Jonah Rivers S
Jonah Rivers S

Reputation: 33

Python if/else defers to wrong branch

I'm writing an Interactive Fiction game for a school project, and for some reason, when I try to use an if/else statement with input (or raw_input), the if else statement defers to the wrong branch regardless of what I input. Here is the code in question:

print( """ 
    You enter the room to the south. 
    Upon entering you mark that it is pitch black, 
    and if you were in the famous text adventure Zork, 
    you would be likely to be eaten by a grue. Thank 
    the programmer for small favors. Unlike in that game, 
    you have a candle, a single stick of 100-year-old 
    dynamite, and that matchbook from earlier. 
    You just knew that would be useful! The candle and 
    the dynamite have the same shape, size, and weight.""") 

choice1 = True 

while choice1 == True: 
    choice2 = input("Will you strike a match? ") 

    if choice2 == "Yes" or "yes" or "y": 
        print("""
            It flickers for a second. You can kind of make 
            out which is which, but alas! They are both 
            covered in red paper! You are beginning to sweat 
            from the nervousness.""") 

        choice1 = False 

    elif choice2 == "No" or "no" or "n": 
        print(""" 
            Okay. I can wait, you aren’t leaving this room until 
            you light a match. You will eventually light a match, 
            but I can wait until you do.""") 
        choice1 = True 
    else: choice1 = True

The if/else statement is treating anything that I type as though I typed yes. Can anyone help me with this error?

Upvotes: 0

Views: 269

Answers (3)

DW42
DW42

Reputation: 101

I believe your problem is in the if statements' conditionals, such as if choice2 == "Yes" or "yes" or "y". This looks like it would check whether choice2 is "Yes" or choice2 is "yes" or choice2 is "y", but it doesn't. The problem is the or statement. The if statement in your code could be written as if (choice2 == "Yes") or ("yes") or ("y") and have the same meaning. This makes it easier to see that, even if choice2 does not equal Yes, the expression will be true because the string "yes" is non-empty and as thus is converted to True in an if statement. This is because the or operator in python is a boolean OR, so if either side of the operator, converted to a boolean, is true, then the expression is. The easiest (i.e. least code refactoring) way to fix this is a series of =='s:

if choice2 == "Yes" or choice2 == "yes" or choice2 == "y": #...

There are others, but this should do the trick for a simple-is program like yours. If you need to do more and more complex matching, you should look into string operators. FOr example, your expression could be rewritten as if "yes".startswith(choice2.lower()): #..., but don't use this without understanding it. For a program of the size of yours, the chained =='s will do just fine. Hope this helps!

Upvotes: 1

Peter Gerber
Peter Gerber

Reputation: 1017

Your if statements are wrong, they should look like this:

if choice in ["Yes", "yes", "y"]:
    …

or like this:

if choice == "Yes" or choice == "yes" or choice == "y":
    …

Python treats an non-empty string as true, e.g. "Yes" is considered true. So if you write choice == "yes" or "Yes", the expression is always true because if even if choice == "yes" isn't true, "Yes" will be considered true.

Upvotes: 3

Leon Z.
Leon Z.

Reputation: 572

The line if choice2 == "Yes" or "yes" or "y" doesn't work like you think it does. After the first statement choice2 == "Yes" it is like asking if "yes" or if "y". The if statement on a string will always return true, unless it is an empty string. To fix this you'll need either

if choice2 == "Yes" or choice2 == "yes" or choice2 == "y":

or this more pythonic approach:

if choice2 in ["Yes", "yes", "y"]:

which will check if the string is in that array. Of course the same thing applies to elif choice2 == "No" or "no" or "n":, which in its current form will also always return true.

Upvotes: 1

Related Questions