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.
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.
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