Python and vs or in while loop - python

choice = input('Enjoying the course? (y/n)')
while choice != "y" or choice != "n":
choice = input("Sorry, I didn't catch that. Enter again: ")
im trying to understand why the code above doesnt exit the while loop if i input 'y' or 'n', but if i change the or to and and input 'y' or 'n' the while loop exits? To my understanding it should have worked both.
In or case its read as
while choice is not 'y' or choice is not 'n' -> exit
just like and
while choice is not 'y' and choice is not 'n' -> exit

You should use and instead of or:
while choice != "y" and choice != "n":
choice = input("Sorry, I didn't catch that. Enter again: ")
choice != "y" or choice != "n" always evaluates to True since choice cannot be y and n at the same time.

while choice != "y" or choice != "n":
choice = input("Sorry, I didn't catch that. Enter again: ")
You want the while loop to repeat
until choice equals "y" or choice equals "n"
So you want it to last
while choice doesn't equal "y" and choice doesn't equal "n"
So the correct code in your case would be
while choice != "y" and choice != "n":
Note
In Python a better practice would be writing this
while choice not in ("y", "n"): # Easier to understand, right?

Look at it this way:
if you enter "y" on or operator below happens
while "y" != "y" or "y" != "n":
which translates to below
while False or True:
and its or operator so (True or False) will always be True
if you enter "y" on and operator below happens
while "y" != "y" and "y" != "n":
which translates to below
while False and True:
and as its and operator so (True and False) will always be False
hence you should use and if you want to leave the loop

There are exactly 3 cases:
source is 'x'
source is 'y'
source is something else. Not one of {'x', 'y'}.
In all of these 3 states the OR condition holds, and therefore the loop continues.
In other words, the condition is always True, because choice can be only one of the two values. And therefore it is always not one of them, at least. Hence, the OR condition always holds, and the loop continues.

Related

Why is my if-elif-else statement always returning the same answer? [duplicate]

This question already has answers here:
How to test multiple variables for equality against a single value?
(31 answers)
Closed 1 year ago.
Background:
I'm experimenting with while loops and I just made a simple program nested in a while loop.
Code:
while True:
userinput = input("Is nem jeff? ")
if userinput == "y" or "yes" or "Y" or "Yes":
print ("YAY!")
elif userinput == "n" or "no" or "N" or "No":
print ("das sad :(")
else:
print ("wrong input")
break
Problem:
My program should be looping until the user types in an invalid input, but instead, it always returns the value nested in the if statement, no matter what I type in. What am I doing wrong?
Your conditionals aren't doing what you think they are.
In Python, a non-zero-length string evaluates to True in a boolean
context. The or operator performs a boolean or operation between
the lefthand operand and the righthand operand.
So when you write this:
if userinput == "y" or "yes" or "Y" or "Yes":
What you are saying is this:
if (userinput == "y") or True or True or True:
Which will always evaluate to True. You want to write instead:
if userinput == "y" or userinput == "yes" or userinput == "Y" or userinput == "Yes":
Or more simply:
if userinput.lower() in ['y', 'yes']:
The reason false down to truthsy or falsy in if conditions.
based on your initial code block
print('y'=='yes'or'y')
[output] y
print('n'=='yes'or'y')
[output] y
based on the above you can see that regardless of you input, your first if statement would be evaluated as True.
rather than doing that, try doing this instead.
while True:
userinput = input("Is nem jeff? ").lower()
if userinput in ['yes','y']:
print ("YAY!")
elif userinput in ['no','n']:
print ("das sad :(")
else:
print ("wrong input")
break

Python, How do I use a string in a while loop and then an if statement?

I cannot figure out why this won't work, I have gone as far as to apply integer variables, I would prefer to keep it purely to strings. I'm new, what am I doing wrong?
x = int(2)
y = int(1)
while userinput != (1,2):
userinput = input("Do you wish to continue, to start from scratch?")
if input == 1:
print("y")
if input == 2:
print ("n")
else:
print("Try y or n, they mean yes or no respectively.")
I presume you want to check directly on the "y" and "n" characters, note that, among the other things, in your code you are checking the wrong input, you should check the variable userinput that you assign in the loop with the user input.
Here is a working example, note that i convert to lowercase in order to accept both "y\n" and "Y\N" with a single if statement.
userinput = ""
while (userinput !="y" and userinput !="n"):
userinput = input("Do you wish to continue, to start from scratch?").lower()
if userinput == "y":
print("y")
elif userinput == "n":
print ("n")
else:
print("Try y or n, they mean yes or no respectively.")
EDIT: if statement fixed as suggested by #Kumar

While loop with if/elif/else statement

I have just started learning Python and I have some issues with the while loop.
instruction_yes_no = ""
while instruction_yes_no.lower() != "y" or "n":
instruction_yes_no = input("Do you want to see the instruction? Please write 'Y' or 'N'\n")
if instruction_yes_no.lower() == "y":
print("You are gonna lose even if you read the instructions...")
print("\n")
time.sleep(1)
instruction()
elif instruction_yes_no.lower() == "n":
print("Do you think you are better than me? I will beat you faster since you have not read the instructions")
time.sleep(1)
else:
print("You mortal...you have not chosen a valid input. Type or 'Y' or 'N'")
time.sleep(1)
break
Basically I would like to obtain the following:
1) If the user inputs 'y', the instruction() function is called (THIS WORKS)
2) If the user inputs 'n', it prints ""Do you think you are better than me?..." (THIS WORKS)
3) If the user does not type either 'y' or 'n', I would like to keep looping until the user insert or 'y' or 'n'.
HOWEVER this is not working.
I am not understanding why. This is how I think it should work:
At the beginning the variable instruction_yes_no is set to ""
It enter the loop because instruction_yes_no != than 'y' or 'n'
Now, instruction_yes_no assumes the value that the user inputs
If the user does not input either 'y' or 'n' it should keep looping, but is does not.
If the user does not input either 'y' or 'n' it should keep looping, but is does not
Because you have the break after the if-elif-else. So it will break in any case.
Move that break inside the if block (when instruction_yes_no.lower() == "y").
Oh, this is a classic common error:
while instruction_yes_no.lower() != "y" or "n":
It's the same as
while (instruction_yes_no.lower() != "y") or True:
You want this instead:
while instruction_yes_no.lower() != "y" and instruction_yes_no.lower() != "n":
Or maybe this, it's shorter :)
while instruction_yes_no.lower() not in ["y", "n"]:

Python while loop condition check for string

In Codeacademy, I ran this simple python program:
choice = raw_input('Enjoying the course? (y/n)')
while choice != 'y' or choice != 'Y' or choice != 'N' or choice != 'n': # Fill in the condition (before the colon)
choice = raw_input("Sorry, I didn't catch that. Enter again: ")
I entered y at the console but the loop never exited
So I did it in a different way
choice = raw_input('Enjoying the course? (y/n)')
while True: # Fill in the condition (before the colon)
if choice == 'y' or choice == 'Y' or choice == 'N' or choice == 'n':
break
choice = raw_input("Sorry, I didn't catch that. Enter again: ")
and this seems to work. No clue as to why
You have your logic inverted. Use and instead:
while choice != 'y' and choice != 'Y' and choice != 'N' and choice != 'n':
By using or, typing in Y means choice != 'y' is true, so the other or options no longer matter. or means one of the options must be true, and for any given value of choice, there is always at least one of your != tests that is going to be true.
You could save yourself some typing work by using choice.lower() and test only against y and n, and then use membership testing:
while choice.lower() not in {'n', 'y'}:

If-branch for x == "N" or "No" always runs [duplicate]

This question already has answers here:
Why does "a == x or y or z" always evaluate to True? How can I compare "a" to all of those?
(8 answers)
Closed 6 months ago.
When I run this in my program, the question goes through, however no matter the answer, the "No" option always runs. If I switch the option order, the "Y" option will only run and it will always go straight to start. I'm sure I'm missing something simple, I just don't know what.
infoconf = raw_input("Is this information correct? Y/N: ")
if infoconf == "N" or "No":
print "Please try again."
elif infoconf == "Y" or "Yes":
start()
else:
print "That is not a yes or no answer, please try again."
Supposed to be
infoconf = raw_input("Is this information correct? Y/N: ")
#you wrote: infoconf == "N" or "No" but should be:
if infoconf == "N" or infoconf == "No":
print "Please try again."
#you wrote: infoconf == "Y" or "Yes" but should be
elif infoconf == "Y" or infoconf == "Yes":
start()
else:
print "That is not a yes or no answer, please try again."
Short explanation:
when value of x = 'N'
x == 'N' or 'No' will return True
when value of x = 'Y'
x == 'N' or 'No' will return 'No' i believe this is not what you want
at the other side
when value of x = 'N'
x == 'N' or x == 'No' will return True
when value of x = 'Y'
x == 'N' or x == 'No' will return False i believe this is what you want
Python will interpret infoconf == "N" or "No" differently than you thought. This is somewhat a case of "operator precedence" where your condition is parsed as (infoconf == "N") or ("No").
Now, infoconf == "N" may or may not be true, but "No" is "something" and when treated as a logical evaluates as true. In effect, your condition infoconf == "N" or true will always be true.
As many others suggested, comparing infoconf to "No" in your second logical term will do the trick.
Personally I'd do something like this:
infoconf = raw_input("Is this information correct? Y/N: ")
if infoconf.lower().startswith('n'):
# No
elif infoconf.lower().startswith('y'):
# Yes
else:
# Invalid
This means that the user could reply "Y/y/yes/yeah" for yes, and "N/n/no/nah" for no.
In Python, it's a bit easier to do this as:
infoconf = raw_input("Is this information correct? Y/N: ")
if infoconf in ["N", "No"]:
print "Please try again."
elif infoconf in ["Y", "Yes"]:
start()
else:
print "That is not a yes or no answer, please try again."
As others have said, if infoconf == "N" or "No" is equivilent to if (infoconf == "N") or "No", and since "No" (as a non-empty string) evaluates to True, the statement will always be true.
Also, to be a little less picky on the input, you might want to do infoconf = infoconf.strip().lower() before you do the tests (and then compare to the lower case versions).

Categories

Resources