Issue when trying to add user validation [duplicate] - python

This question already has answers here:
not equals operator(!=) not working in python string comparison
(2 answers)
Closed 1 year ago.
Trying to add validation to user input.
So the code is:
print ('Does this service require an SFP Module? (y/n): ')
while True:
sfpreq = input()
if sfpreq != 'y' or 'n':
print("You must enter either y or n")
continue
else:
break
So even when the user enters 'n' it returns the "print("You must enter either y or n")" and continues the loop.
I have tried setting the variabl manually to and also tried another convention I found on realpython and also removed the if statement from the while loop:
sfpreq = "n"
if sfpreq != 'y' or sfpreq != 'n':
print("You must enter either y or n")
else:
print("Test")
Again it just returns:
admin#MacBook-Pro Learning Folder % python3 test22.py
You must enter either y or n
Am I just missing something very fundamental here?

Problem with the logic
sfpreq = "n"
if sfpreq != 'y' or sfpreq != 'n':
print("You must enter either y or n")
else:
print("Test")
Here, when you enter the if loop,
sfpreq != 'y' is validated as True and sfpreq != 'n' is validated as False.
Now True OR False statement in boolean algebra equates to True.
So, the if loop gets executed and You must enter either y or n is printed.
See, more about boolean algebra here
A better solution
sfpreq = "n"
if sfpreq not in {"y","n"}:
print("You must enter either y or n")
else:
print("Test")
So, here we are checking if y or n is not there in the set {"y","n"}. As in this case, sfpreq is there in that set so,the else statement gets executed.

Related

(Python) Trouble making the user input promt another quiz question or break the loop

I'm pretty new to programming, so please pardon me!
***EDIT 2: Ok so this is the full thing. Everything is working fine except when I try to break out of the while enthusiasm is True: loop, I just keep getting more and more questions (the loop keeps running)
I'm building a Python trivia quiz, and I managed all the answer input loop to work (doesn't allow invalid input, breaks the loop succesfully)
I want the program to ask the user "Would you like another question? (y/n)" and stop the program if 'n'.
The problem is no matter what I tried, I keep getting more trivia questions!
Thanks in advance
import requests
import pprint
import json
import html
print("Welcome to the ultimate test of knowledge and valour, The Internet Quiz!")
print("You will be given an array of multiple choice questions in general knowledge")
input("Press Enter to start!")
y_n = ["y", "n"]
import random
q_num = 1
score = 0
enthusiasm = True
while enthusiasm is True:
r = requests.get("https://opentdb.com/api.php?amount=1&category=9&type=multiple")
question = json.loads(r.text)
first = question['results'][0]['correct_answer']
second = question['results'][0]['incorrect_answers'][0]
third = question['results'][0]['incorrect_answers'][1]
fourth = question['results'][0]['incorrect_answers'][2]
print("--------------------------------------------------------")
print("Question number " + str(q_num)+ ":")
print(html.unescape(question['results'][0]['question']))
options = [first,second,third,fourth]
random.shuffle(options)
for X in options:
print(html.unescape(X))
legend = (
(options[0], 1),
(options[1], 2),
(options[2], 3),
(options[3], 4)
)
error = False
while error is False:
guess = input("Please enter the number of your answer(1-4):")
try:
guess = int(guess)
except:
print("Your answer must be a number between 1-4.")
continue
if guess <1 or guess > 4:
print("Your answer must be a number between 1-4.")
continue
else:
error = True
if (first, guess) in legend:
score += 1
q_num += 1
print("Correct! \nCurrent score: " +str(score))
acid = True
while acid is True:
yesno=input("Would you like another question? (y/n)")
try:
yesno = str(yesno.lower())
except:
print("Invalid input. Please enter y/n.")
continue
if yesno.lower() != "y" and yesno.lower() != "n":
print("Invalid input. Please enter y/n.")
continue
elif yesno.lower() == "y":
break
else:
acid=False
error=True
continue
else:
print("Incorrect! Better hit the books, buddy! \nCurrent score: " +str(score))
q_num += 1
acid = True
while acid is True:
yesno=input("Would you like another question? (y/n)")
try:
yesno = str(yesno.lower())
except:
print("Invalid input. Please enter y/n.")
continue
if yesno.lower() != "y" and yesno.lower() != "n":
print("Invalid input. Please enter y/n.")
continue
elif yesno.lower() == "y":
break
else:
acid=False
error=True
continue
You have two while loops:
while enthusiasm is True:
and
while error is False
Let's look at what happens when you ask if the user wants another question (simplified a little):
yesno=input("Would you like another question? (y/n)")
if yesno.lower() == "y":
break
else:
error=True
You set error to True, but you do not set enthusiasm to False, so the loop starts again at the top. Looking further, enthusiasm never gets set to False, so that condition will always start over. Simply writing
else:
error = True
enthusiasm = False
would be fine. I also would recommend thinking about if you want two loops, and what the purpose of the enthusiasm variable is.
There's a lot of other refactoring that can be done here, but not that you probably should write
while not error:
instead of explicitely checking if error "is" False. Similarly,
while enthusiasm:
is a good check on a boolean
Similarly,
yesno=input("Would you like another question? (y/n)")
try:
yesno = str(yesno.lower())
except:
print("Invalid input. Please enter y/n.")
continue
if yesno.lower() != "y" and yesno.lower() != "n":
can be improved. You don't need to cast yesno to a string, becuase that's what happens when it comes from input. You don't need the try/except either (you may have taken this from an int cast, elsewhere). Since you've already converted yesno to lower once, you don't need to keep doing that every time you compare it to a y or n.
Possible to stop the program with:
import sys
sys.exit()

While loop with functions and if/break statement?

I’m just starting to learn functions and I am practicing on implementing some into my code. Just a simple example... how can I code this to loop properly and break out when the user wants?
def profit(i,c):
gain = c - i
print('Your profit is:' + '' + str(gain))
def beginning():
x = float(input("What was your initial investment?"))
y = float(input("What is your investment worth now?"))
profit(x,y)
beginning()
ans = 'y'
while ans == 'y' or ans == 'Y':
ans = str(input('Would you like to calculate another investment? (Y/N)'))
beginning()
if ans != 'y' or ans != 'Y':
break
There are two ways to break out of a while loop. The first way is obviously the break statement, kind of like you have done. For it to work correctly, you need to change the condition:
if ans != 'y' or ans != 'Y':
break
This will always be true, since ans cannot be "y" and "Y" at the same time. You should change it into:
if ans not in ["y", "Y"]:
Or
if ans.upper() != "Y":
In your case however, you don't need it at all. Since in both the if statement and the while condition you are checking ans, you can get rid of the if and just rely on this.
while ans.upper() == "Y":
This will end the loop automatically when ans becomes anything other than "Y" or "y".
The only reason you would use a break here is if you wanted to exit the loop immediately, and not complete the current iteration. For example:
while ans.upper() == "Y":
ans = input("Enter selection: ")
if ans == "I want to stop right now!":
break
print("Do other things, even if ans is not Y")
In this example, "Do other things" will always be printed regardless of ans, unless ans is "I want to stop", in which case it won't get printed.
One thing you can do is ans = ans.capitalize() after you get the user input. Then remove the ans != 'y' since that's causing your loop to break.

Python multiple nested while True continue/end looping error [duplicate]

This question already has answers here:
How can I break out of multiple loops?
(39 answers)
Closed 5 years ago.
Here's a piece of code from my project software:
def fun_1(self, i):
print("")
print("Welcome to Option 1: View Passwords")
while True:
print("")
which_o1 = input("1: Input a New Account details \n2: Exit \nPlease Input the option number: ")
if which_o1 == str(1):
with open(str(i)+'.txt', 'a+') as file:
while True:
print("")
web_n = input("Please Input Website name: ")
print("")
e_u = input("Please input email/username: ")
print("")
pass_w = input("Please input password: ")
while True:
print("")
sure = input("Website- " +web_n+"\nEmail/Username- "+e_u+"\nPassword- "+pass_w+"\nAre You sure about these details? Yes/No: ")
if (sure.lower()[0]) != 'y' and (sure.lower()[0]) != 'n':
print("")
print("Please input a valid response Yes/No!")
continue
elif (sure.lower()[0]) == 'y' and (sure.lower()[0]) != 'n':
list_log = [web_n, e_u, pass_w]
file.write(str(list_log) + '\n')
break
break
continue
elif (sure.lower()[0]) == 'n' and (sure.lower()[0]) != 'y':
break
continue
elif which_o1 == str(2):
return (i)
else:
print("")
print("Please Enter a Valid Response!")
continue
So has you can see that it has 3 while True loop. The problem is occurring while breaking and looping the loop. If you see the latest While True under "pass_w" in the middle elif, where it says elif (sure.lower()[0]) == 'y' and (sure.lower()[0]) != 'n':, in it I have 2 break and 1 continue because what I wanted to do is that when that elif executes it just break middle 3rd while true, 2nd while true and continue means loop the first while true at the start of the code, but it just keep looping 3rd While True in the middle of the code instead of breaking it.
Is there a way I can make it possible?
Firstly, understand that no lines can be executed after a break statement inside of a while loop. So putting multiple breaks and a continue won't work. You need to restructure your code. Personally, I would recommend either implementing try except statements, or putting some of the code inside of functions so that you can return when you want to stop looping and pass variables as indications to the outer loops where the function was called.
Another option could be instead of using breaks and continues, use a variable or set of variables that your while loops check for to decide if they should continue. So inside your ifs and elifs you could set exitfirstloop = True, etc. and in the while loops you check while not exitfirstloop

I need to figure out how to make my program repeat. (Python coding class)

I am a beginner student in a python coding class. I have the majority of the done and the program itself works, however I need to figure out a way to make the program ask if wants a subtraction or an adding problem, and if the user would like another question. I asked my teacher for assistance and he hasn't gotten back to me, so I'm simply trying to figure out and understand what exactly I need to do.
import random
x = int(input("Please enter an integer: "))
if x < 0:
x = 0
print('Negative changed to zero')
elif x == 0:
print('Zero')
elif x == 1:
print('Single')
else:
print('More')
maximum = 10 ** x;
maximum += 1
firstnum = random.randrange(1,maximum) # return an int from 1 to 100
secondnum = random.randrange(1, maximum)
compsum = firstnum + secondnum # adds the 2 random numbers together
# print (compsum) # print for troubleshooting
print("What is the sum of", firstnum, " +", secondnum, "?") # presents problem to user
added = int(input("Your answer is: ")) # gets user input
if added == compsum: # compares user input to real answer
print("You are correct!!!")
else:
print ("Sorry, you are incorrect")
You'll want to do something like this:
def foo():
print("Doing good work...")
while True:
foo()
if input("Want to do more good work? [y/n] ").strip().lower() == 'n':
break
I've seen this construct (i.e., using a break) used more often than using a sentinel in Python, but either will work. The sentinel version looks like this:
do_good_work = True
while do_good_work:
foo()
do_good_work = input("Want to do more good work? [y/n] ").strip().lower() != 'n'
You'll want to do more error checking than me in your code, too.
Asking users for input is straightforward, you just need to use the python built-in input() function. You then compare the stored answer to some possible outcomes. In your case this would work fine:
print('Would you like to test your adding or subtracting skills?')
user_choice = input('Answer A for adding or S for subtracting: ')
if user_choice.upper() == 'A':
# ask adding question
elif user_choice.upper() == 'S':
# ask substracting question
else:
print('Sorry I did not understand your choice')
For repeating the code While loops are your choice, they will repeatedly execute a statement in them while the starting condition is true.
while True: # Condition is always satisfied code will run forever
# put your program logic here
if input('Would you like another test? [Y/N]').upper() == 'N':
break # Break statement exits the loop
The result of using input() function is always a string. We use a .upper() method on it which converts it to UPPERCASE. If you write it like this, it doesn't matter whether someone will answer N or n the loop will still terminate.
If you want the possibility to have another question asked use a while loop and ask the user for an input. If you want the user to input whether (s)he want an addition or substraction you already used the tools to ask for such an input. Just ask the user for a string.

Python will not accept user inputs [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 7 years ago.
I managed to get this code to work before, but I've changed something accidentally and can't figure out what.
The code that will not work is:
while True:
answer = input ("Would you like to play this game? Type yes if you would like to. Type no to end the program")
if answer == 'no' or 'n' or 'No' or 'N':
sys.exit()
elif answer == 'yes' or 'y' or 'Yes' or 'Y':
code = input("Input a three digit code. Must be more than 001 and less than 100.")
When I run the code and put in one of the answers, the program will not run the next part and gives no error message.
In case it is necessary, I have put the code for the entire program below:
import random
import sys
while True:
answer = input ("Would you like to play this game? Type yes if you would like to. Type no to end the program")
if answer == 'no' or 'n' or 'No' or 'N':
sys.exit()
elif answer == 'yes' or 'y' or 'Yes' or 'Y':
code = input("Input a three digit code. Must be more than 001 and less than 100.")
try:
value = int(code)
except:
print ("Invalid code")
continue
if 1 <= value <= 100:
print (code)
print ("Valid code")
print ("I will now try to guess your number")
number = random.randint(1, 100)
while number > int(code) or number < int(code):
print ("Failed attempt. Number guessed is")
number = random.randint(1, 100)
print (number)
else:
if number == int(code):
print ("Your code is")
print (code)
else:
print ("Invalid code")
EDIT: Thank you so much, the yes option is working now, but the program will still not exit when selecting any of the no options, as it did before. The edited code is:
if answer in ('no', 'n', 'No', 'N'):
sys.exit()
elif answer in ('yes', 'y', 'Yes', 'Y'):
I checked by printing the answer value, and i believe it is registering the no input but not executing the command that follows for some reason.
EDIT: I'm still a bit fuzzy on the logic, but changing it to exit() fixed the problem. It asks for confirmation when closing now, when it didn't before, but otherwise sorted.
Problem causing silent exit:
if answer == 'no' or 'n' or 'No' or 'N':
sys.exit()
That test is testing answer == 'no' as one test, then 'n' as a separate test, and so on. or chains return when any test returns a "truthy" value (or the last evaluated value if none are truthy), so the test always ends up evaluating as "truthy" because a non-empty string like 'n' is truthy. If you're trying to test for any one of those values, you'd do an "is contained in" test to see if answer is one of a recognized group of values, e.g.:
if answer in ('no', 'n', 'No', 'N'):
The reason is due to this expression:
if answer == 'no' or 'n' or 'No' or 'N':
In python, the above is exactly the same as this:
if (answer == 'no') or ('n' != '') or ('No' != '') or ('N' != ''):
Since all but the first expression evaluates to true, the whole expression is true.
The simplest solution is to convert your input to lowercase and trim off any extra space, then check if the answer is in a list of allowable answers so that you can easily compare for "n", "N", "no", "NO", "No", "nO".
if answer.strip().lower() in ("n", "no"):

Categories