0

I'm a beginner in Python, trying to make a simple program combining everything I've learnt so far. In this question the program itself is not the question, but a specific part of it, which I have worked around, but wanted some insight into why this is happening.

def printresults (answer):
    if answer == "y" or "Y":
        print ("Yes")
    else:
        print ("No")

In the case above, I have managed to get this function to run with "N" as the 'answer'. The issue I faced was that it would then run the first if-branch, and in this case print "Yes", despite it not being a "y" or a "Y".

I have since worked around this issue by creating a new variable in the function and using the lower() method to make only one possibility, and then simply asking it to determine if it is "y" or not.

def printresults (answer):
    lwranswer = answer.lower()
    if lwranswer == "y":
        print ("Yes")
    else:
        print ("No")

I therefore suspect the fault lies with me somehow misusing the "or" operator - I just don't know how or why. Any insight would be much appreciated.

Thanks

Note, the program won't simply return a Yes or No, but I made it print these to troubleshoot and see which branch it was taking.

RJK
  • 11
  • 4
  • 3
    Does this answer your question? [How to test multiple variables against a value?](https://stackoverflow.com/questions/15112125/how-to-test-multiple-variables-against-a-value) – Carcigenicate Sep 29 '20 at 13:35

3 Answers3

5

You have two options here, unsing or but this requires the full clause:

if answer == "y" or answer == "Y":

or using in and a collection (sets work best, but tuples and lists are also valid alternatives in this case):

if answer in {"y", "Y"}:
norok2
  • 25,683
  • 4
  • 73
  • 99
Adirio
  • 5,040
  • 1
  • 14
  • 26
  • 1
    Better yet use a `set`, e.g. `answer in {'y', 'Y'}` – norok2 Sep 29 '20 at 14:00
  • sets are not sequences, though. They are just collections. See also [here](https://docs.python.org/3/library/collections.abc.html#collections-abstract-base-classes). – norok2 Sep 30 '20 at 22:15
0

When using the or or and operator. You need to specify the other clause as well.

if answer == "y" or answer == "Y":

Hope this answers your question.

roo1989
  • 86
  • 4
0

Let us quickly analyze why:

answer == 'y' or 'Y'

does not work the way you intended.

The expression is evaluated as following:

(answer == 'y') or 'Y'

because == has higher precedence than or.

The answer == 'y' part behaves as intended, i.e. evaluates to True if answer is 'y' and False otherwise.

Now, x or y operates in such a way that "if x is false, then y, else x". For non-boolean arguments, such as strings, the concept of True/False is extended to Truthy/Falsy.

Therefore, when answer is 'y', it returns True as expected, and when answer is not 'y', it returns 'Y', which is Truthy, no matter if the value of answer is actually 'Y' or not.

Similarly, if you were to evaluate 'y' or 'Y', you would get 'y' again because 'y' is Truthy.

This means that you cannot simply use parenthesis to let the above expression behave the way you expected.

The recommended way to achieve the intended behavior is:

answer in {'y', 'Y'}

For a comprehensive discussion of "how to test a variable against multiple values" please refer to How to test multiple variables against a value? , which, aside from swapping the role of variable and value, is precisely what you would need.

norok2
  • 25,683
  • 4
  • 73
  • 99