Sunday 15 March 2015

python - Asking the user for input until they give a valid response -



python - Asking the user for input until they give a valid response -

i writing programme must take input user.

#note: python 2.7 users should utilize `raw_input`, equivalent of 3.x's `input` age = int(input("please come in age: ")) if age >= 18: print("you able vote in united states!") else: print("you not able vote in united states.")

this works expected if user enters sensible data.

class="lang-none prettyprint-override">c:\python\projects> canyouvote.py please come in age: 23 able vote in united states!

but if create mistake, crashes:

class="lang-none prettyprint-override">c:\python\projects> canyouvote.py please come in age: dickety 6 traceback (most recent phone call last): file "canyouvote.py", line 1, in <module> age = int(input("please come in age: ")) valueerror: invalid literal int() base of operations 10: 'dickety six'

instead of crashing, seek getting input again. this:

class="lang-none prettyprint-override">c:\python\projects> canyouvote.py please come in age: dickety 6 sorry, didn't understand that. please come in age: 26 able vote in united states!

how can accomplish this? if wanted reject values -1, valid int, nonsensical in context?

the simplest way accomplish set input method in while loop. utilize continue when bad input, , break out of loop when you're satisfied.

when input might raise exception

use try , catch observe when user enters info can't parsed.

while true: try: # note: python 2.x users should utilize raw_input, equivalent of 3.x's input age = int(input("please come in age: ")) except valueerror: print("sorry, didn't understand that.") #better seek again... homecoming start of loop go on else: #age parsed! #we're ready exit loop. break if age >= 18: print("you able vote in united states!") else: print("you not able vote in united states.") implementing own validation rules

if want reject values python can parse, can add together own validation logic.

while true: info = input("please come in loud message (must caps): ") if not data.isupper(): print("sorry, response not loud enough.") go on else: #we're happy value given. #we're ready exit loop. break while true: info = input("pick reply d:") if data.lower() not in ('a', 'b', 'c', 'd'): print("not appropriate choice.") else: break combining exception handling , custom validation

both of above techniques can combined 1 loop.

while true: try: age = int(input("please come in age: ")) except valueerror: print("sorry, didn't understand that.") go on if age < 0: print("sorry, response must not negative.") go on else: #age parsed, , we're happy value. #we're ready exit loop. break if age >= 18: print("you able vote in united states!") else: print("you not able vote in united states.") encapsulating in function

if need inquire user lot of different values, might useful set code in function, don't have retype every time.

def get_non_negative_int(prompt): while true: try: value = int(input(prompt)) except valueerror: print("sorry, didn't understand that.") go on if value < 0: print("sorry, response must not negative.") go on else: break homecoming value age = get_non_negative_int("please come in age: ") kids = get_non_negative_int("please come in number of children have: ") salary = get_non_negative_int("please come in yearly earnings, in dollars: ") putting together

you can extend thought create generic input function:

def sanitised_input(prompt, type_=none, min_=none, max_=none, range_=none): if min_ not none , max_ not none , max_ < min_: raise valueerror("min_ must less or equal max_.") while true: ui = input(prompt) if type_ not none: try: ui = type_(ui) except valueerror: print("input type must {0}.".format(type_.__name__)) go on if max_ not none , ui > max_: print("input must less or equal {0}.".format(max_)) elif min_ not none , ui < min_: print("input must greater or equal {0}.".format(min_)) elif range_ not none , ui not in range_: if isinstance(range_, range): template = "input must between {0.start} , {0.stop}." print(template.format(range_)) else: template = "input must {0}." if len(range_) == 1: print(template.format(*range_)) else: print(template.format(" or ".join((", ".join(map(str, range_[:-1])), str(range_[-1]))))) else: homecoming ui

with usage such as:

age = sanitised_input("enter age: ", int, 1, 101) reply = sanitised_input("enter answer", str.lower, range_=('a', 'b', 'c', 'd')) common pitfalls, , why should avoid them the redundant utilize of redundant input statements

this method works considered poor style:

data = input("please come in loud message (must caps): ") while not data.isupper(): print("sorry, response not loud enough.") info = input("please come in loud message (must caps): ")

it might attractive because it's shorter while true method, violates don't repeat yourself principle of software development. increases likelihood of bugs in system. if want backport 2.7 changing input raw_input, accidentally alter first input above? it's syntaxerror waiting happen.

recursion blow stack

if you've learned recursion, might tempted utilize in get_non_negative_int can dispose of while loop.

def get_non_negative_int(prompt): try: value = int(input(prompt)) except valueerror: print("sorry, didn't understand that.") homecoming get_non_negative_int(prompt) if value < 0: print("sorry, response must not negative.") homecoming get_non_negative_int(prompt) else: homecoming value

this appears work fine of time, if user enters invalid info plenty times, script terminate runtimeerror: maximum recursion depth exceeded. may think "no fool create 1000 mistakes in row", you're underestimating ingenuity of fools!

python validation loops python-3.x user-input

No comments:

Post a Comment