I am learning python, and I am stuck in an infinite while loop in the following code.
A = input("Hello what is your name? ")
D = input("What is today's date? ")
B = input("Did you have a good day [y/N]")
while B != "y" or B != "Y" or B != "N" or B != "n":
B = input("Did you have a good day [y/N]")
else:
if B == "Y" or B == "y":
print(A + ", ")
C = input("Tell me about your day ")
with open("Start.txt", "a") as infile:
infile.write("\n")
infile.write(A)
infile.write(" ran Start.py and said he had a good day on ")
infile.write(D)
infile.write(".")
infile.write("\n He reports today:\n ")
infile.write(C)
elif B == "N" or "n":
print(A + ", ")
C = input("Tell me about your day ")
with open("Start.txt", "a") as infile:
infile.write("\n")
infile.write(A)
infile.write(" ran Start.py and said he had a bad day on ")
infile.write(D)
infile.write(".")
infile.write("\n He reports today:\n ")
infile.write(C)
The problem happens when B is compared to see if it is equal to Y, y, N, or n
but it still no matter what input I give it for B sticks me into the while statement and keeps me there.
The problem is here:
while B != "y" or B != "Y" or B != "N" or B != "n":
B is always not equal to one of those. If it's "y" it is not equal to the other three, and so on. And since you are using or to combine these conditions, the loop continues if any one is true, which, as we've seen, is always the case.
Rewrite using and:
while B != "y" and B != "Y" and B != "N" and B != "n":
Or apply DeMorgan's law (factor the not out of the expression and swap and/or):
while not (B == "y" or B == "Y" or B == "N" or B == "n"):
Or best of all, write it the Python way:
while B.lower() not in "yn":
(This also accepts an empty answer, which according to your prompt is equivalent to "N". To handle this, just convert your elif to a plain else, without a condition.)
Lets use a simplified version of your while loop.
while B != "Y" or B != "y":
# ...
There is no way that this will ever evaluate to False.
If B was set to Y then B != "Y" would be False, but B != "y" would be True.
I think, in this case, it might be cleaner to do something like
while B not in ["y", "Y", "n", "N"]:
# ...
Which will then repeat until the input is one of the characters in your list.
EDIT: Some other answers have suggested using while B not in "yYnN" or equivalents. This works here because all of your expected responses are one character. If you decide later to accept "yes" as a response, then you will have to use a list like I have shown above.
The issue is that you are doing while B != "y" or B != "Y" or B != "N" or B != "n":
With or it returns true if either of its options are true. So if B="N"
b!="N" or b!=n" is true because b still isn't "n"
You can solve this by replacing all the ors with ands to get this
while B != "y" and B != "Y" and B != "N" and B != "n":
This line
elif B == "N" or "n":
Should be
elif B == "N" or B == "n":
You should use condition, simply "n" (non empty string) means true
This is the simplest solution!
while B not in "YNyn":
Related
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.
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
I want to break out of the loop if y or n is set. In my head this is the way to do it, but it seems to get stuck in the while loop even when 'str1' is set to both n and y.
I have also tried to do: while str1 != "y" or str1 != "n": without luck.
str1 = ""
while not str1 == "y" or not str1 == "n":
str1 = input('setting [y/n] => ')
str1 = str1.lower()
Your condition while str1 != "y" or str1 != "n" is always True, if you enter n it'll be different of y and vice-versa.
You want to stop if both condition aren't met
while str1 != "y" and str1 != "n"
Or easier
while str1 not in "yn":
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 8 years ago.
This script does not progress passed the first if expression!
If the user enters DD, or F, the script acts as like the if state was true.
choice = raw_input("Cup size for bra: D, DD, or F: ")
if choice == "D" or "d":
band_length = raw_input("Please enter the bra band length for your D size breasts: ")
D_Statistics(band_length)
elif choice == "DD" or "dd":
band_length = raw_input("Please enter the bra band length for your DD size breasts: ")
DD_statistics(band_length)
elif choice == "F" or "f":
band_length = raw_input("Please enter the bra band length for your F size breasts: ")
F_statistics(band_length)
Your if statements will always evaluate to True currently.
if choice == "D" or "d" evaluates to True on either the value of choice equaling "D", or the value of literal "d" being True; and the second part is thus always True.
Instead, use
if choice in ("D", "d"):
...
elif choice in ("DD", "dd"):
...
if choice in ("F", "f"):
...
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).