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

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).

Related

Python and vs or in while loop

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.

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

Checking input against a list in python - why does one way work while the other doesn't?

Started learning python a few days ago and was doing a task with simple yes/no inputs and doing different things with the while loop depending no whether the user wants to continue using the program or not.
The whole program is fairly small so hope it's alright to post the entirety of its code here. This is what worked for me:
import random
print("=====================================")
print("I Add Numbers and Tell You the Sum v2")
print("=====================================")
while True:
rand1 = random.randint(1, 100)
rand2 = random.randint(1, 100)
result = rand1 + rand2
print(f"I'm adding {rand1} and {rand2}. If you add them together,the result would be {result}")
print()
again_input = input("Would you like to try again? (Y/N) ")
again = again_input.lower().strip()
validyes = ["yes", "y"]
validno = ["no", "n"]
if again in validyes:
print("Sure thing!")
print()
elif again in validno:
print("Okay. See you!")
break
else:
print("That's not a valid response. The program will now exit.")
break
While the relevant code that didn't work as expected was this, to do with checking the user input against the valid list:
valid = ["yes", "y", "no", "n"]
if valid == "yes" or "y":
print("Sure thing")
elif valid == "no" or "n":
print("Okay bye")
break
else:
print("That's not a valid response. The program will now exit")
break
The former would run just fine, while the latter will print "Sure thing" regardless of what the user inputs. Why is that the case?
On that front, I'm happy to hear any other tips you guys might have with regards to making the rest of the code better. Eager to hear from and take part in this community!
You have to show what all the string what they are comparing to
if again == "yes" or again == "y":
print("Sure thing")
elif again == "no" or again == "n":
print("Okay bye")
break
else:
print("That's not a valid response. The program will now exit")
break
Also a tip is to use "\n" for a new line. The \n will not be shown
Old:
print(f"I'm adding {rand1} and {rand2}. If you add them together,the result would be {result}")
print()
New:
print(f"I'm adding {rand1} and {rand2}. If you add them together,the result would be {result}\n")
Last is that for the lower and strip function u can use it in the same line were u get your input
Old:
again_input = input("Would you like to try again? (Y/N) ")
again = again_input.lower().strip()
New:
again = input("Would you like to try again? (Y/N) ").lower().strip()
In the second case you're using the OR operand wrong and that's why it is always printing Sure thing. Here you can take a look and understand it better.
To make the code better, i would suggest keeping the valid list with all valid inputs, and checking for yes or no using the if again in valid method, but playing with what is and isn't valid inputs.
This is how or works
operation: x or y result: if x is false, then y, else x
Explanation:
valid == "yes" will be false for obvious reason because you are comparing a list to a string. When the first condition is false operator or goes to evaluate next condition which is just "y" and will always be true(you can confirm it using bool("y")) so that's why it's always printing "Sure thing".
You use this:
if valid == "yes" or "y":
print("Sure thing")
elif valid == "no" or "n":
print("Okay bye")
break
So in the first condition you check if (valid == "yes") or ("y"), but not if valid == ("yes" or "y"). Non-empty string is always True, when you use it as bool, so the first condition is always True. If you want to do somwthing like this, you can use tuples (it's like lists, but you cant edit it): if valid in ("yes", "y")
valid is a list, so valid will never equal to "yes", so it just goes to "y", which will always equal true. You need to check if "yes" or "y" is in valid:
if "yes" in valid or "y" in valid:
print("Sure thing")
elif "no" in valid or "n" in valid:
print("Okay bye")
break
Of course, with this code it will always print "Sure thing" because valid includes all the options.

If Statement doesn't read input [duplicate]

This question already has answers here:
How to test multiple variables for equality against a single value?
(31 answers)
Closed 5 years ago.
Just learning how to code, and wanted to make a small program to see what I know.
n = int(input("Pick a number any Number: "))
if n > 100:
print ("No... Not that Number")
else:
answer = input("Would you like to know your number?")
if answer == "Y" or "Yes" or "y" or "yes":
print ("Your number is %s" % (n))
elif answer == "N" or "No" or "n" or "no" or "NO":
print ("Oh, well that's a shame then.")
else:
print ("Please type Yes or No")
input("Press Enter/Return to Exit")
Everything works, except for the second if statement, which doesn't follow any of the data entered into input. Any reason why it does this?
Python isn't human, it doesn't understand
if answer == "Y" or "Yes"
The way you mean it to. You should do
if answer == 'Y' or answer == 'Yes'
Or even better
if answer in ('Yes', 'Y', 'yes', 'y')
Or even shorter
if answer.lower() in ('yes', 'y')
== has a higher precedence than or. So, in the if condition your're checking whether answer == 'Y' and then oring this boolean expression with "Yes", which is a non-None string, so it evaluates as True. Instead, you should use the in operator to check if answer is one of the values you're interested in:
if answer in ("Y", "Yes", "y", "yes"):
print ("Your number is %s" % (n))
elif answer in ("N", "No", "n", "no", "NO"):
print ("Oh, well that's a shame then.")
else:
print ("Please type Yes or No")

Python Input Function

I was wondering if somebody could tell me what is wrong with this code, when I run the code it shows nothing but if I take out the "elif" it does work.\
first=input("What is your first name? ");
middle=input("What is your middle name? ");
last=input("What is your last name? ");
test = [first, middle, last];
print ("");
print ("Firstname: " + test[0]);
print ("Middlename: " + test[1]);
print ("Lastname: " + test[2]);
print ("");
correct=input("This is the information you input, correct? ");
if (correct == "Yes" or "yes"):
print ("Good!")
elif (correct == "no" or "No"):
print ("Sorry about that there must be some error!");
Here's the problem:
if (correct == "Yes" or "yes"):
# ...
elif (correct == "no" or "No"):
# ...
It should be:
if correct in ("Yes", "yes"):
# ...
elif correct in ("No", "no"):
# ...
Notice that the right way to make a comparison involving several conditions is like this:
correct == "Yes" or correct == "yes"
But usually it gets written like this, which is shorter:
correct in ("Yes", "yes")
You need to use the in keyword:
if correct in ("Yes", "yes"):
print ("Good!")
elif correct in ("no", "No"):
print ("Sorry about that there must be some error!")
or convert the entire input to the same case:
# I use the lower method of a string here to make the input all lowercase
correct=input("This is the information you input, correct? ").lower()
if correct == "yes":
print ("Good!")
elif correct == "no":
print ("Sorry about that there must be some error!")
Personally, I think the lower solution is the cleanest and best. Note however that it will make your script accept inputs such as "YeS", "yEs", etc. If this is a problem, go with the first solution.
You'e checking correct incorrectly
if (correct == "Yes" or "yes"):
means (correct == "Yes") or ("yes"), and non-empty string evaluates to True in python, so first condition will always be True.If you want to check multiple strings, you can do:
if (correct in ("Yes", "yes")):
But this one doesn't takes 'yEs' or 'yES' into account. If you want case-insensitive comparison, then I think correct.lower() == "yes" would be preferred method.

Categories

Resources