Captn Buzz
Captn Buzz

Reputation: 329

Python loop restarting even though there is a try: except:

Here is the code for a small program I just wrote to test some new things I learned.

while 1:
    try:
        a = input("How old are you? ")
    except:
        print "Your answer must be a number!"
        continue

    years_100 = 100 - a
    years_100 = str(years_100)
    a = str(a)
    print "You said you were "+a+", so that means you still have "+years_100+" years"
    print "to go until you are 100!"
    break
while 2:
    try:
        b = str(raw_input('Do you want to do it again? If yes enter "yes", otherwise type "no" to stop the script.'))
    except:
        print 'Please try again. Enter "yes" to do it again, or "no" to stop.'
        continue

    if b == "yes":
            print 'You entered "yes". Script will now restart... '
    elif b == "no":
            print 'You entered "no". Script will now stop.' 
            break

It works fine for the for loop. If you type something other than a number, it will tell you only numbers are allowed.

However, in the 2nd loop, it asks you to enter yes or no, but if you enter in something different, it just restarts the loop instead of printing the message after

except:

What did I do wrong and how do I fix it so it displays the message I told it to?

Upvotes: 2

Views: 5854

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1121992

You do not get an exception, because you are always enter a string when using raw_input(). Thus str() on the return value of raw_input() will never fail.

Instead, add an else statement to your yes or no tests:

if b == "yes":
        print 'You entered "yes". Script will now restart... '
elif b == "no":
        print 'You entered "no". Script will now stop.' 
        break
else:
    print 'Please try again. Enter "yes" to do it again, or "no" to stop.'
    continue

Note that you should never use a blanket except statement; catch specific exceptions. Otherwise, you'll mask unrelated problems, making it harder for you to find those problems.

Your first except handler should only catch NameError, EOFError and SyntaxError for example:

try:
    a = input("How old are you? ")
except (NameError, SyntaxError, EOFError):
    print "Your answer must be a number!"
    continue

as that's what input() would throw.

Also note that input() takes any python expression. If I enter "Hello program" (with the quotes), no exception would be raised, but it is not a number either. Use int(raw_input()) instead, and then catch ValueError (what would be thrown if you entered anything that's not an integer) and EOFError for raw_input:

try:
    a = int(raw_input("How old are you? "))
except (ValueError, EOFError):
    print "Your answer must be a number!"
    continue

To use the second loop to control the first, make it a function that returns True or False:

def yes_or_no():
    while True:
        try:
            cont = raw_input('Do you want to do it again? If yes enter "yes", otherwise type "no" to stop the script.'))
        except EOFError:
            cont = ''  # not yes and not no, so it'll loop again.
        cont = cont.strip().lower()  # remove whitespace and make it lowercase
        if cont == 'yes':
            print 'You entered "yes". Script will now restart... '
            return True
        if cont == 'no':
            print 'You entered "no". Script will now stop.' 
            return False
        print 'Please try again. Enter "yes" to do it again, or "no" to stop.'

and in the other loop:

while True:
    # ask for a number, etc.

    if not yes_or_no():
        break  # False was returned from yes_or_no
    # True was returned, we continue the loop

Upvotes: 4

Related Questions