-
-
Save garrettdreyfus/8153571 to your computer and use it in GitHub Desktop.
def yes_or_no(question): | |
reply = str(raw_input(question+' (y/n): ')).lower().strip() | |
if reply[0] == 'y': | |
return True | |
if reply[0] == 'n': | |
return False | |
else: | |
return yes_or_no("Uhhhh... please enter ") |
Correct me if I am wrong but this might be OK with the Assigment Expressions (PEP 572) in Python 3.8
while res:= input("Do you want to save? (Enter y/n)").lower() not in {"y", "n"}: pass
And if you don't like hitting ENTER for whatever reason, something like this might work:
def getch():
"""Read single character from standard input without echo."""
import sys, tty, termios
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(sys.stdin.fileno())
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch
def yes_or_no(question):
c = ""
print(question + " (Y/N): ", end = "", flush = True)
while c not in ("y", "n"):
c = getch().lower()
return c == 'y'
if __name__ == "__main__":
if not yes_or_no("Continue?"):
print("NO") # ...or echo nothing and just provide newline
os._exit(0)
else:
print("YES")
Granted, this is very far from "dead simple", but its an alternative nevertheless. (Looking at robertour's suggestion, I wish Debian 10 would have gone with 3.8 instead of 3.7...)
What about using strtobool
?
def query_yes_no(question, default='no'):
if default is None:
prompt = " [y/n] "
elif default == 'yes':
prompt = " [Y/n] "
elif default == 'no':
prompt = " [y/N] "
else:
raise ValueError(f"Unknown setting '{default}' for default.")
while True:
try:
resp = input(question + prompt).strip().lower()
if default is not None and resp == '':
return default == 'yes'
else:
return distutils.util.strtobool(resp)
except ValueError:
print("Please respond with 'yes' or 'no' (or 'y' or 'n').\n")
adapted from this SO question.
I propose renaming it to whats_it_gonna_be_boy
.
Lots of great answers here, but prompted for something a little simpler and recursive.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Simple yes/no function demo."""
def yesno(question):
"""Simple Yes/No Function."""
prompt = f'{question} ? (y/n): '
ans = input(prompt).strip().lower()
if ans not in ['y', 'n']:
print(f'{ans} is invalid, please try again...')
return yesno(question)
if ans == 'y':
return True
return False
def main():
"""Run main function."""
ans = yesno("What'll it be")
print(f'you answer was: {ans}')
if __name__ == '__main__':
main()
Version without recursion:
def single_yes_or_no_question(question, default_no=True):
choices = ' [y/N]: ' if default_no else ' [Y/n]: '
default_answer = 'n' if default_no else 'y'
reply = str(input(question + choices)).lower().strip() or default_answer
if reply[0] == 'y':
return True
if reply[0] == 'n':
return False
else:
return False if default_no else True
Correct me if I am wrong but this might be OK with the Assigment Expressions (PEP 572) in Python 3.8
while res:= input("Do you want to save? (Enter y/n)").lower() not in {"y", "n"}: pass
Great idea. A couple more brackets are needed here:
while ( res:=input("Do you want to save? (Enter y/n)").lower() ) not in {"y", "n"}: pass
and then ...
if res=='y':
... do something ...
Lots of great answers here, but prompted for something a little simpler and recursive.
#!/usr/bin/env python3 # -*- coding: utf-8 -*- """Simple yes/no function demo.""" def yesno(question): """Simple Yes/No Function.""" prompt = f'{question} ? (y/n): ' ans = input(prompt).strip().lower() if ans not in ['y', 'n']: print(f'{ans} is invalid, please try again...') return yesno(question) if ans == 'y': return True return False def main(): """Run main function.""" ans = yesno("What'll it be") print(f'you answer was: {ans}') if __name__ == '__main__': main()
Thank you so much mate, I didn't know that we can return a function that I was manipulating the code in quite different ways. It changed my many lines of stuck code to refactoring.
#!/usr/bin/python3
def confirm_prompt(question: str) -> bool:
reply = None
while reply not in ("y", "n"):
reply = input(f"{question} (y/n): ").lower()
return (reply == "y")
reply = confirm_prompt("Are you sure?")
print(reply)
Edit: added keyword argument to set either yes or no by default
#!/usr/bin/python3
def prompt(question: str, default=None) -> bool:
choices = ("", "y", "n") if default in ("yes", "no") else ("y", "n")
hint = "Y/n" if default == "yes" else "y/n"
hint = "y/N" if default == "no" else hint
reply = None
while reply not in choices:
reply = input(f"{question} ({hint}): ").lower()
return (reply == "y") if default != "yes" else (reply in ("", "y"))
reply = prompt("Are you sure?")
print(reply, "\n")
reply = prompt("Are you sure?", default="yes")
print(reply, "\n")
reply = prompt("Are you sure?", default="no")
print(reply, "\n")
@gyoza necrothreading this just to kudos you on the fact that you quoted Meatloaf
Stop using raw_input, that's Python 2.
How would I add an --yes or -y parser arg to @icamys solution?
first
parser.add_argument("--yes", "-y", help="Always accept")
and then what? :D sorry I am really new to python
maybe something like:
def confirm(question, default_no=True):
choices = ' [y/N]: ' if default_no else ' [Y/n]: '
default_answer = 'n' if default_no else 'y'
reply = str(input(question + choices)).lower().strip() or default_answer
if reply[0] == 'y':
return True
if reply[0] == 'n':
return False
if args.yes:
default_answer='y'
else:
return False if default_no else True
but that doesnt work
@willbelr, Thank you for this beautiful & elegant solution! I modified with casefold (in Python3) but am otherwise using as-is in a few scripts, and it works great!
def confirm_prompt(question: str) -> bool:
reply = None
while reply not in ("y", "n"):
reply = input(f"{question} (y/n): ").casefold()
return (reply == "y")
reply = confirm_prompt("Are you sure?")
print(reply)
My version using simple recursion:
def user_confirm(question: str) -> bool:
reply = str(input(question + ' (y/n): ')).lower().strip()
if reply[0] == 'y':
return True
elif reply[0] == 'n':
return False
else:
new_question = question
if "Please try again - " not in question:
new_question = f"Please try again - {question}"
return user_confirm(new_question)
if __name__ == "__main__":
print(user_confirm("Do you love me?"))
I prefer this approach:
def yes_or_no_prompt(question:str,default_yes=True)->bool:
inputMapping={
'y':'y',
"υ":'y',
"Υ":'y',
'n':'n',
'ν':'n',
'N':'n'
}
question = question.strip()
if question == "":
raise ValueError(f"Question is an empty string")
default ='n'
prompt_choice="(y/N)"
if default_yes:
default='y'
prompt_choice="(Y/n)"
reply = str(input(f"{question} {prompt_choice}: ")).lower().strip()
reply = reply[0] or default
reply = inputMapping[reply]
if reply not in ['y','n']:
raise ValueError(f'Invalid input for reply given {reply} instead of Y or N')
return reply=='y'
# Usage Example
if __name__ == "__main__":
while True:
try:
if yes_or_no_prompt("Are roses red?"):
print("Correct")
else:
print("Nope")
exit(0)
except ValueError:
print("I made a Boo Boo mommy")
The reason why is because I split whether I'll re-ask the question into another point whereas the value sanitization and checking is performed upon the function itself. Furthermore I set the default value as well. Furthermore I map any Greek Input given from user intop its respective English one in case keyboard layout is a non-English one.
I like @jkbbwr solution's which I modified for a simple script where I want to confirm the user wants to overwrite an existing file.
if not input("Are you sure? (y/n): ").lower().strip()[:1] == "y": sys.exit(1)
I also took the [:1] from @vincenta which will handle an empty response and default to no.
Note: This doesn't handle other responses that start with y and it won't keep prompting. Also, for python 2, use raw_input instead of input