On Wed, Mar 11, 2015 at 09:26:38PM +0000, Wibble wrote: [...] > How do I make it show a message to users saying only numbers excepted > and then the loop continues? > > I have tried this but same error is still generated. > > def user_choice(question, low, high, step = 1): > """Define user choice""" > choice = None > while choice not in range(low, high, step): > choice = int(input(question))
Your error occurs at the line above. > if choice == str(input(question)): > print('Numbers only please!') And here you try to detect the error, but it's too late, since it has already happened! > return choice > > Do I need to create another while loop within this loop to handle a > string input? Yes you do, because the user might be stupid, clumsy, obnoxious, or a cat walking on the keyboard, and might repeatedly type non-numbers. Or they might innocently try typing number words like "one", "two", etc. So let's break the question down. You want to give the user the option to enter a number, then you want to check that it is within a range. Let's start by accepting any old number: # Python 3 version! # for Python 2, make sure you use raw_input() not input() def enter_number(prompt): if not prompt.endswith(" "): # Make sure there is at least one space between the prompt # and where the user types. prompt += " " answer = input(prompt) while not answer.isdigit(): print("You must enter a number!") answer = input(prompt) return int(answer) If you try that, you will find a couple of limitations: - it doesn't accept negative numbers; - it doesn't accept floating point numbers like 1.2 or 3e5. Here's another way to write the same function. It's a bit more verbose, but probably a better design: def enter_number(prompt): """Ask the user to enter an integer number. Takes a single argument, the string to use to prompt the user. This repeats until they enter an actual number. """ if not prompt.endswith(" "): # Make sure there is at least one space between the prompt # and where the user types. prompt += " " while True: # Loop forever. answer = input(prompt) # use raw_input in Python 2 try: number = int(answer) except ValueError: print("You must enter a number!") else: return number This loops forever, asking the user for a number, then trying to convert their answer into a number inside a `try` block. If the conversion fails, the `except` block runs, and the loop continues. But if the conversion succeeds, the `else` block runs, which returns the number, thus breaking the infinite loop. Now you can use that as a building block to write the function you want: def user_choice(question, low, high, step = 1): """A better docstring would be appropriate.""" choice = None while choice not in range(low, high, step): choice = enter_number(question) return choice There's a problem with this function too -- if the user enters a number out of range, they don't get any feedback as to why their answer is rejected, instead they just get asked for a number again. Very disheartening! How about this? def user_choice(question, num, high=None): """A better docstring would be appropriate.""" if high is None: start = 1 end = num else: start = num end = high allowed = range(start, end+1) while True: choice = enter_number(question) if choice in allowed: return choice else: print("Out of range! Try again.") -- Steve _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor