Welcome, guest | Sign In | My Account | Store | Cart

Improvement over Recipe 577058 and cie.

easy_input() function extends the built-in input() function. A question is prompted as well as some expected answers.

The user input can be incomplete (ie. y or ye instead of yes)

  • If no list of expected answer is provided, default will be "yes/no".
  • If no default answer is provided, default will be the first expected answer.

Try and see.

Disclaimer: written in python3, meant for *nix shell, indented with tabs

Avoided caveat: If some expected answer have the same beginning, the user can not enter too few letters. Ex: answer = ['continue', 'test', 'testicle'], user can not input t, te or tes because it will be ambiguous. User can however input test, which is not.

Python, 55 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#!/usr/bin/env python3

def easy_input(question, answer=None, default=None):
	"""Ask a question, return an answer.
	
	<question> is a string that is presented to the user.
	<answer> is a list of strings presented as a choice. User may type only first letters
	<default> is the presumed answer if the user just hits <Enter>.

	"""
	
	if answer is None :
		answer = ['yes', 'no']
	else : 
		answer = [i.lower() for i in answer]
	
	# if <default> is None or <default> is not an expected answers
	# <default> will be the first of the expected answers
	if default is None or default not in answer :
		default = answer[0]
		
	prompt = '/'.join([
		"\x1b[1;1m{0}\x1b[1;m".format(i.capitalize()) if i == default else i
		for i in answer
	])
	
	while True :
		choice = input("{0} [{1}]: ".format(question, prompt)).lower()

		if default is not None and choice == '':
			return default
		if choice in answer :
			return choice	
			
		valid_answer = { i[:len(choice)] : i for i in answer }
		
		if len(valid_answer) < len(answer) :
			print(" -- Ambiguous, please use a more detailed answer.")
		elif choice in valid_answer :
			return valid_answer[choice]
		else:
			print(" -- Please answer only with {0} or {1}.".format(", ".join(answer[:-1]), answer[-1]))
			
if __name__ == '__main__' :
	u = easy_input("vous habitez chez vos parents ?")
	print("\nanswer was : {0}\n".format(u))
	
	u = easy_input("ajouter au gloubiboulga ?", ['carotte', 'rutabaga', 'pomepeche'])
	print("\nanswer was : {0}\n".format(u))
	
	u = easy_input("alors, on dance ?", ['non', 'nui'], 'oui')
	print("\nanswer was : {0}\n".format(u))
	
	u = easy_input("question piège ?", ['continue', 'testicle', 'test', ])
	print("\nanswer was : {0}\n".format(u))	
	

1 comment

yota (author) 9 years, 2 months ago  # | flag

would down-voters mind to let a useful remark ?

Created by yota on Fri, 7 Jun 2013 (GPL3)
Python recipes (4591)
yota's recipes (13)

Required Modules

  • (none specified)

Other Information and Tasks

  • Licensed under the GPL 3
  • Viewed 11915 times
  • Revision 7 (updated 10 years ago)