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.
5 Answers 5
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.)
Comments
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.
Comments
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":
Comments
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
Comments
This is the simplest solution!
while B not in "YNyn":