I've been trying to write an elegant [y/n] prompt for scripts that I'll be running over command line. I came across this:
http://mattoc.com/python-yes-no-prompt-cli.html
This is the program I wrote up to test it (it really just involved changing raw_input to input as I'm using Python3):
import sys
from distutils import strtobool
def prompt(query):
sys.stdout.write("%s [y/n]: " % query)
val = input()
try:
ret = strtobool(val)
except ValueError:
sys.stdout.write("Please answer with y/n")
return prompt(query)
return ret
while True:
if prompt("Would you like to close the program?") == True:
break
else:
continue
However, whenever I try to run the code I get the following error:
ImportError: cannot import name strtobool
Changing "from distutils import strtobool" to "import distutils" doesn't help, as a NameError is raised:
Would you like to close the program? [y/n]: y
Traceback (most recent call last):
File "yes_no.py", line 15, in <module>
if prompt("Would you like to close the program?") == True:
File "yes_no.py", line 6, in prompt
val = input()
File "<string>", line 1, in <module>
NameError: name 'y' is not defined
How do I go about solving this problem?
The first error message:
ImportError: cannot import name strtobool
is telling you that there's no publically visible strtobool
function in the distutils
module you've imported.
This is because it's moved in python3: use from distutils.util import strtobool
instead.
https://docs.python.org/3/distutils/apiref.html#distutils.util.strtobool
The second error message deeply confuses me -- it seems to imply that the y
you input is trying to be interpreted as code (and therefore complains that it doesn't know about any y
variable. I can't quite see how that'd happen!
... two years pass ...
Ahh, I get it now... input
in Python 3 is "get a string from the keyboard", but input
in Python 2 is "get a string from the keyboard, and eval
it". Assuming you don't want to eval
the input, use raw_input
on Python 2 instead.
The distutils
package has been deprecated in Python 3.10 and will be removed from Python 3.12. Fortunately, the strtobool
function is pretty small, so you can just copy its code to your module:
def strtobool(val):
"""Convert a string representation of truth to true (1) or false (0).
True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values
are 'n', 'no', 'f', 'false', 'off', and '0'. Raises ValueError if
'val' is anything else.
"""
val = val.lower()
if val in ('y', 'yes', 't', 'true', 'on', '1'):
return 1
elif val in ('n', 'no', 'f', 'false', 'off', '0'):
return 0
else:
raise ValueError("invalid truth value %r" % (val,))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With