def for_value(prompt_text, convert=(lambda x: x), is_legal=(lambda x: True), default=None, error_message='reenter'): """ Prompt for value using the specified prompt_text (with default in brackets appended if it is non-None) followed by ': '; convert the entered value (or use the default if the user just presses enter), ensure is_legal returns True when called on it, and return that value. Display error_messages for all possible failures See the comments in the code for more details See the calls to for_value below, for examples of how it is called. """ while True: try: # display answer (and default, if supplied) and ': '; read str that is user's answer response = input(prompt_text + ('[' + str(default) + ']' if default != None else '') + ': ') # if there is no answer, and no default, print error message and reprompt # kludge: so the user cannot enter an empty string unless the empty string is a default! if len(response) == 0 and default == None: print( leading(prompt_text, extra=2) + 'Must enter a value: there is no default') continue # set answer to either be the default (if there is no answer) or convert the user's answer # see except clause, in case conversion fails: e.g., int('abc') throws an exception answer = default if len( response) == 0 and default != None else convert(response) # if the answer (default or user's) is legal, return it, other print the error message if is_legal(answer): return answer else: print( leading(prompt_text, extra=2) + 'Entry Error:', "'" + str(answer) + "'; ", error_message) # if conversion raises an exception, print an error message and reprompt except Exception as x: print(leading(prompt_text, extra=2) + 'Exception:', x) print(leading(prompt_text, extra=2) + 'Possible error: cannot convert str \'', response, '\' to specified type of value', sep='')
def for_int_between(prompt_text, low, high, default=None, error_message=''): lead = leading(prompt_text, extra=2) return for_value( prompt_text + '(' + str(low) + '..' + str(high) + ')', int, (lambda x: type(x) is int and low <= x <= high), default, error_message + '\n' + lead + 'Please enter a value in the range [' + str(low) + ',' + str(high) + ']') """
def for_char( prompt_text, default=None, legal=None, error_message='Please enter one char in the range (if specified)'): lead = leading(prompt_text, extra=2) return for_value( prompt_text + ('(' + legal + ')' if legal != None else ''), (lambda x: x[0]), (lambda x: x in legal) if legal != None else (lambda x: True), default, error_message + ('\n' + lead + 'Please enter one of ' + legal if legal != None else '')) """
def for_float(prompt_text, default=None, is_legal=(lambda x: True), error_message='not a legal value'): """ Prompt for a float; use the specified prompt_text (with default in brackets appended if it is non-None) followed by ': '; verify that the entered value (using default if the user just presses enter) is a float and is_legal returns True when called on it (and if not display the error_message) See the call to for_value below, and the documentation and code for for_value above. """ lead = leading(prompt_text, extra=2) return for_value( prompt_text, float, (lambda x: type(x) is float and is_legal(x)), default, error_message + ':\n' + lead + 'Please enter a legal value')
def for_string(prompt_text, default=None, is_legal=(lambda x: True), error_message=''): """ Prompt for a string; use the specified prompt_text (with default in brackets appended if it is non-None) followed by ': '; verify that the entered value (using default if the user just presses enter) returns True when is_legal is called on it (and if not display the error_message) See the call to for_value below, and the documentation and code for for_value above. """ lead = leading(prompt_text, extra=2) return for_value( prompt_text, (lambda x: x), is_legal, default, error_message + '\n' + lead + 'Please enter a legal String')