Skip to content

Instantly share code, notes, and snippets.

@ihincks
Last active October 24, 2018 19:44
Show Gist options
  • Save ihincks/5d0ed6934860a1e06e50f35d4c2a03bd to your computer and use it in GitHub Desktop.
Save ihincks/5d0ed6934860a1e06e50f35d4c2a03bd to your computer and use it in GitHub Desktop.
Some functions to query users at the command prompt.
def general_query(question, validator, default=None):
"""
Asks the given question, returning the (possibly modified) result if validator
allows it, and keeps asking until a valid answer is given.
:param str question: The question to ask.
:param validator: A function that acts on user response strings, and returns
`(success, modified_response, message)`. The loop ends if `success` is `True`,
in which case `modified_response` is returned. `message` is printed in
any case.
:param default: The implied response when the user provides a zero-length
response (just presses Enter).
"""
if default is not None and not validator(default)[0]:
raise ValueError("Default value not valid...")
while True:
print(question)
response = input()
response = default if default is not None and response == "" else response
success, value, msg = validator(response)
if len(msg) > 0:
print(msg)
if success:
return value
def folder_query(question, default_folder=None):
"""
Queries the user for a valid folder.
:param str question: The question to ask, where the `format` is invoked with
`default_folder` as the argument.
:param str default_folder: The default folder to use. If `None`, the current
working directory is used.
:return: The folder.
:rtype: `str`
"""
def validator(folder):
success = os.path.isdir(folder)
msg = "" if success else "Specified folder does not exist."
return success, folder, msg
if default_folder is None:
default_folder = os.path.realpath(os.getcwd())
question = question.format(default_folder)
return general_query(question, validator, default=default_folder)
def query_yes_no(question, default=None):
"""
Queries the user for a yes/no response.
:param str question: The question to ask.
:param default: The default user response, 'y', 'n', or `None` for no default.
:return: `True` if 'yes', `False` if `no`
:rtype: `bool`
"""
valid = {"yes": True, "y": True, "ye": True, "no": False, "n": False}
prompt = (
" [y/n] " if default is None else " [Y/n] " if valid[default] else " [y/N] "
)
def validator(response):
success = response.lower() in valid
result = valid[response] if success else None
msg = "" if success else "Please respond with 'yes' or 'no' (or 'y' or 'n')"
return success, result, msg
return general_query("{} {} ".format(question, prompt), validator, default)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment