Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

Python Python Basics All Together Now Branch and Loop

My IF statement always returns true with using OR.

Hi! I'm trying to use OR in my IF statement to try to make it more user friendly. For some reason it always comes back true, no matter what I write. What I mean is that my IF statement always runs no matter what I write with this code. Whats the problem?

This is the code I'm trying.

proceed = input("{}, would you like to proceed in this purchase?\nY/N ".format(user_name))

if proceed.lower() == "y" or "yes": print("Thank you for your purchase {}".format(user_name)) tickets_remaining -= how_many_tickets

else: print("Thanks {}, have a nice day!".format(user_name))

4 Answers

Jonathan Grieve
MOD
Jonathan Grieve
Treehouse Moderator 90,683 Points

I don't think there's a lot materially wrong with the code.

Maybe try making sure your indentations are correctly aligned. That is to say 4 spaces every time indentation is required. Python can be strict about it and can cause disruption to program flow.

Jeff Muday
MOD
Jeff Muday
Treehouse Moderator 26,972 Points

One of the things I love about programming is that there many correct ways to write a program. Python is very forgiving in the way you can construct expressions, but there are always hidden "gotchas" along the way.

Let's evaluate what comes back from your if expression. You will note your expression will always result in 'yes' rather than the expected 'True' or 'False' which is what you intended.

>>> proceed='Yes'
>>> proceed.lower()=="y" or "yes"
'yes'
>>> proceed='No'
>>> proceed.lower()=="y" or "yes"
'yes'

To fix that, you can separate the expression logical tests.

>>> proceed='Yes'
>>> proceed.lower()=='y' or proceed.lower()=='yes'
>>> True
>>> proceed='No'
>>> proceed.lower()=='y' or proceed.lower()=='yes'
>>> False

Even better yet, which matches your intention to test the proceed response against several strings.

You could use a list of responses and the in operation.

>>> proceed='Yes'
>>> proceed.lower() in ['y','yes']
True
>>> proceed='NO'
>>> proceed.lower() in ['y','yes']
False

The resulting code is this.

proceed = input("{}, would you like to proceed in this purchase?\nY/N ".format(user_name))

if proceed.lower() in ["y", "yes"]:
    print("Thank you for your purchase {}".format(user_name))
    tickets_remaining -= how_many_tickets

else:
    print("Thanks {}, have a nice day!".format(user_name))

Great answer Jeff Munday! Thank you! I understand now why the IF expression did what it did, and how to fix it. But there is 2 things I still don't understand that you might be able to explain to me.

Why did it return 'Yes' instead of True or False?

And why did the IF expression run on a 'Yes'? Is that equal to a True?

Sorry that I might seem confused but still a very novice at this ;).

Thanks again for the answers everyone!

Jeff Muday
MOD
Jeff Muday
Treehouse Moderator 26,972 Points

Q: Why did it return 'Yes' instead of True or False?

Great question to ask! I totally encourage you to do experiments with the Python REPL when you are in doubt about how operations work.

The overarching reason we see these strings returned as values comes from the design concept "operator overloading" and "operator short-circuit". Python (mostly but not always) allows mixing of types and operators (operator overloading). This includes Boolean operators. The idea of "short-circuit" is that the Python interpreter will evaluate the order of operations of a logical equation and it won't go on to evaluate anything else unless it needs to (this saves time). For example "or" short-circuits when the LEFT side evaluates to True. And "and" short-circuits if the LEFT side evaluates to False.

The other oddity of Python is something Kenneth calls "truthiness". Any non-zero number is considered "truthy" or True. Any string that has one or more characters in it is called "truthy" or basically equivalent to True. An integer 0, empty string, or None value are considered to be "falsey" or False in terms of logical flow.

Python will let you get away with using strings and numbers with logical operators e.g. and, or, not -- these are syntactically correct and there are some programming tricks you can do with these, though I don't necessarily recommend. I will demonstrate below.

Consider the following.

>>> # the "or" operator short-circuits since LEFT side is truthy
>>> # since "yes" is truthy, return the LEFT string!
>>> "yes" or "no"
'yes'
>>> # note that this works with 'no' too.
>>> "no" or "yes"
'no'
>>> True or "I am Truthy too, but short-circuit gives LEFT expression"
True
>>> # since there is not a short-circuit, return RIGHT truthy expression
>>> False or "I can say I am False, but I am truthy"
'I can say I am False, but I am truthy'
>>> # the "and" operator doesn't short circuit because
>>> # the LEFT side is truthy, so it evaluates the RIGHT
>>> # and this is also truthy, so returns the truthy string.
>>> "yes" and "no"
'no'
>>> # this also returns the RIGHT truthy expression
>>> "no" and "yes"
'yes'
>>> # the "not" operator short-circuits since "yes" is truthy
>>> # and returns False
>>> not "yes"
False
>>> # "no" is truthy so will also return False
>>> not "no"
False
>>> # note the "falsey" empty string and None
>>> # will return True
>>> not ""
True
>>> not None
True
>>> not 0
True

I hope this helps!