Best way to handle user input matching multiple possibilities: "Y"/ "y"/ "yes" - python

If you ask someone a yes/no question then the answer is one of these two options. In programming what if the response was "Y" or "y" or "yes" or whatever?
I had to create a compound condition repeating my statement while its actually the same one. I'm not an expert but I can see that it can be improved.
def note_maker(note):
case_note = open("case_note.txt", "a+")
update = case_note.write("\n" + note)
multiple_inputs = input("Do you want to enter more details? Y/N")
while multiple_inputs == "yes" or multiple_inputs == "YES" or multiple_inputs == "Yes" or multiple_inputs == "Y" or multiple_inputs == "y":
update_again = case_note.write("\n" + input("Enter your additional information"))
multiple_inputs = input("Do you want to enter more details?")
case_note.close()
Is there a way to control the user input into what I expect?

You can shorten the user input and make it lowercase which should help.
Eg: user_input = input("Something? y/n: ")[0].lower()
This way, if they enter "Y", "Yes", "yes", or "yep" it will end up being "y".

Try refactoring input check into a new function:
def is_affirmative(input: str) -> bool:
return input.strip().lower() in ['y', 'yes']
def note_maker(note):
case_note = open("case_note.txt", "a+")
update = case_note.write("\n" + note)
multiple_inputs = input("Do you want to enter more details? Y/N")
while not is_affirmative(multiple_inputs):
update_again = case_note.write("\n" + input("Enter your additional information"))
multiple_inputs = input("Do you want to enter more details?")
case_note.close()

You could have a set of valid yes responses and no responses:
yes_responses, no_responses = {'y', 'yes'}, {'n', 'no'}
user_response = None
while user_response not in yes_responses and user_response not in no_responses:
user_response = input("Do you want to enter more details? (Y/N): ").lower()
if user_response in yes_responses:
print("The user responded yes.")
else:
print("The user responded no.")
Example Usage:
Do you want to enter more details? (Y/N): zxc
Do you want to enter more details? (Y/N): YesNo
Do you want to enter more details? (Y/N): yEs
The user responded yes.
Note: The advantage of using a set over a list or a tuple is that is the in operation is O(1) rather than O(N).

Related

Can't get string user input working (Python)

I've searched the web and this site and been messing around all day, trying 100 ways to get this simple little program working. I'm practicing endless While loops and string user inputs. Can anyone explain what I'm doing wrong? Thank you!
while True:
print("This is the start.")
answer = input("Would you like to continue? (Y/N) ")
answer = answer.islower()
if answer == "n":
print("Ok thank you and goodbye.")
break
elif answer == "y":
print("Ok, let's start again.")
else:
print("You need to input a 'y' or an 'n'.")
your code has one thing wrong answer.islower() will return boolean values True or False but you want to convert it into lower values so correct method will be answer.lower()
while True:
print("This is the start.")
answer = input("Would you like to continue? (Y/N) ")
answer = answer.lower() # change from islower() to lower()
if answer == "n":
print("Ok thank you and goodbye.")
break
elif answer == "y":
print("Ok, let's start again.")
else:
print("You need to input a 'y' or an 'n'.")
You just need one amendment to this line:
Instead of
answer = answer.islower()
Change to
answer = answer.lower()

Can you assign multiple strings to the same variable on the same line?

I'm having trouble writing a program that asks for your birthday and then the user can confirm if their inputted birthday is true or false (yes or no), however, I want to be able to accept an answer of "yes" if it was spelt with an accidental capital visa Veras for "no"
For example if I were to input "Yes" instead of "yes" as an answer to whether or not the correct birthday is being displayed in the console, the computer would still accept that as an answer as the word is still spelt correctly.
So in that case, I am trying to understand if I can assign multiple ways of spelling "yes" to one variable so I don't have to type all the ways you can write the word "yes" and assign it too different variables.
Here is what I have tried for my code:
answer_YES = 'Yes' or "yes"
answer_NO = 'No'
Name = input("What's your name? ")
Last_Name = input("What's your last name? ")
print("\nHello,", Name, Last_Name + "!")
num1 = float(input("Give me one number: "))
num2 = float(input("Give me a better number: "))
print("\nHere is your Summary:")
print(int(num1), '+', int(num2), '=', int(num1 + num2))
BD = input("\nOK, now give me your birthday m/d/y: ")
print("Is this your birthday?", '"' + BD + '"' "\n\nCorrect? (Yes) Incorrect? (No)\n")
answer = input("Answer: ")
#Using Boolean Expressions
if answer == answer_YES:
print("Awesome! Thank you", Name)
if it is all about the yes spelling (Yes or YEs or YES ...)
you can have
anser_YES = 'yes'
then in the validation you do something like
if answer.lower() == answer_YES
otherway if you want make multilang input accept you can use list of accepted answers, so
instead of
answer_YES = 'yes'
do
answer_YES = ['yes', 'oui', 'Yeeeeeessss']
then to test the true response do
if answer in answer_YES:
i wish this was helpful for you
You can use the in keyword
answer_YES = ("Yes", "yes")
if answer in answer_YES:
do_something()
or use
if answer.lower() == "yes":
You are not able to assign multiple values to a variable.
If you just want a simple check, I would use the lower() function to make the strings match without worrying about capitalization. An alternative would be to search for it in a set.
answer_YES = "yes"
...
if answer.lower() == answer_YES:
print("Awesome! Thank you", Name)
or
answer_YES = {"Yes", "yes"}
...
if answer in answer_YES:
print("Awesome! Thank you", Name)

Flowchart getting complicated with while loops in Python

I would appreciate some help with this:
I try to make a form-program of the "Then why worry" philosophy:
I wrote this code, but I can't understand how do I make the while loop repeat itself every time the user doesn't enter "yes" or "no" in both questions.
problem = str(input("Do you have a problem in life? "))
problem = problem.replace(" ", "").lower() #nevermind caps or spaces
while problem:
if problem not in ("yes","no"):
print("Please enter YES or NO")
if problem == "no":
break
if problem == "yes":
something = str(input("Do you have something to do about it? "))
something = something.replace(" ","").lower()
while something:
if something not in ("yes","no"):
print("Please enter YES or NO")
elif:
break
print("Then why worry?")
Your algorithm is linear, there is no loops in there. So, the only place you need a loop is when you try to get correct response from the user. So, I'd propose you to move that into a function and then your example turns into this:
def get_user_input(prompt):
while True:
reply = input(prompt).replace(" ", "").lower()
if reply in ['yes', 'no']:
return reply
print("Please enter YES or NO")
problem_exists = get_user_input("Do you have a problem in life? ")
if problem_exists == 'yes':
action_possible = get_user_input("Do you have something to do about it? ")
print("Then why worry?")
I'd suggest to use while True loops, so you can put the input code once, then with the correct condition and break you're ok
while True:
problem = input("Do you have a problem in life? ").lower().strip()
if problem not in ("yes", "no"):
print("Please enter YES or NO")
continue
if problem == "no":
break
while True:
something = input("Do you have something to do about it? ").lower().strip()
if something not in ("yes", "no"):
print("Please enter YES or NO")
continue
break
break
print("Then why worry?")
Using walrus operator (py>=3.8) that could be done easier
while (problem := input("Do you have a problem in life? ").lower().strip()) not in ("yes", "no"):
pass
if problem == "yes":
while (something := input("Do you have something to do about it? ").lower().strip()) not in ("yes", "no"):
pass
print("Then why worry?")

Python: Depending on IF statement output, execute different code outside of itself

If my_input == "n" I want to my program to loop again, which works fine.
But if my else statement is True I dont want it to run the whole program again and just "start" at the my_input variable.
How can I achieve this?
def name_user_validation():
while True:
full_name = input("What is your name? ")
print(f"Hello {full_name}, nice to meet you.")
full_name.split()
print(f"If I understood correctly, your first name is {full_name[0]} and your last name is {full_name[-1]}.")
my_input = input("Is that right? (y/n) ")
if (my_input == "y"):
print("Great!")
break
elif my_input == "n":
print("Oh no :(")
else:
print("Invalid input, try again.")
name_user_validation()
I misunderstood your question, I would probably restructure your code a bit, so you get rid of your while loops and use recursive function calling to go back when you need to,
something like the below
def name_user_validation():
full_name = input("What is your name? ")
print(f"Hello {full_name}, nice to meet you.")
full_name.split() # This line actually doesn't do anything
print(f"If I understood correctly, your first name is {full_name[0]} and your last name is {full_name[-1]}.")
if not accept_input():
name_user_validation()
def accept_input():
my_input = input("Is that right? (y/n) ")
if my_input == "y":
print("Great!")
return True
elif my_input == "n":
print("Oh no :(")
return False
else:
print("Invalid input, try again.")
accept_input()
name_user_validation()
Add another loop that doesn't terminate until user enters acceptable input.
def name_user_validation():
while True:
full_name = input("What is your name? ")
print(f"Hello {full_name}, nice to meet you.")
full_name.split()
print(f"If I understood correctly, your first name is {full_name[0]} and your last name is {full_name[-1]}.")
while True:
my_input = input("Is that right? (y/n) ")
if (my_input == "y"):
print("Great!")
break
elif my_input == "n":
print("Oh no :(")
break
else:
print("Invalid input, try again.")
if my_input == 'y':
break
name_user_validation()
Edit: The program terminates only when my_input = y.

How can I get my function to go back to a certain point in code after elif statement?

I'm trying to get user input for adding persons details to a dictionary, after they go through the first while loop. It asks them if they would like to add another entry, if the user enters anything other than "y" or "n" I want it to say ivalid entry, and ask them again, if they then enter "y" or "n" I would like it to go back to the start of the while loop again.
Tried changing the code, the loops and the if, elif and else statements but can't figure it out.
import pprint
everyone = {}
def people_database():
yesno = "y"
while yesno == "y":
name = input("What is the name you would like to add?: ")
age = input("What is the age you would like to add?: ")
residence = input("What is the residence you would like to add?: ")
everyone["people"] = {"Name": name,
"Age": age,
"Residence": residence}
yesno = input("Would you like to add another? Enter y or n: ")
if yesno == "y" or yesno == "Y":
continue
elif yesno == "n" or yesno == "N":
break
else:
while yesno != "y" or yesno != "Y" or yesno != "n" or yesno != "N":
print("Not a valid input.")
yesno = input("Would you like to add another? Enter y or n: ")
if yesno == "y" or yesno == "Y":
continue
elif yesno == "n" or yesno == "N":
break
people_database()
If after entering wrong entry they then input correct entry the function should start again.
I think it would be very beneficial to construct a function for recieving the yes / no input. But in my opinion it need not be recursive in contrast to liamhawkins' answer. A simple while loop would suffice. And no need to print any error statement, as it is pretty obvious to the user that something went wrong if the question is posed again with clear instructions how to answer.
def get_decision(question: str='y/n: '):
ans = ''
while ans not in ['y', 'n']:
ans = input(question)
return ans
everyone = {}
def people_database():
while True:
name = input("What is the name you would like to add?: ")
age = input("What is the age you would like to add?: ")
residence = input("What is the residence you would like to add?: ")
everyone["people"] = {"Name": name,
"Age": age,
"Residence": residence}
if get_decision('Would you like to add another? Enter y or n: ') == 'n':
break
people_database()
You can of course extend the list of accepted answers and make the decision condition more complex accordingly, but this is a minimal example. In my opinion accepting only one symbol for a particular action is clearer than guessing what the user ment, although in this case it is pretty unambiguous.
Side note, I don't know the full story behind your case, but it seems that overriding the people key in the dictionary is not useful in the loop. You'd probably want an incrementing ID to mimic a "database":
people = {}
def people_database():
person_id = 0
while True:
name = input('Name?: ')
age = input('Age?: ')
residence = input('Residence?: ')
people[person_id] = {
'Name': name,
'Age': age,
'Residence': residence
}
if get_decision('Would you like to add another? Enter y or n: ') == 'n':
break
person_id += 1
if __name__ == '__main__':
people_database()
Your second while loop is testing whether yesno is not y or not Y or not n or not N. It will always run, because it can't be all of these cases at the same time. Change your ors to ands
Also, your first while loop should also check for uppercase Y.

Categories