Rod
Rod

Reputation: 15477

what's wrong with exception handling

When I enter a letter for one of the numbers I get an error:

    Traceback (most recent call last):
      File "/Users/rodchar/Documents/Hello World Katie/testing.py", line 7, in <module>
        x = input("What is your first number?")
      File "<string>", line 1, in <module>
    NameError: name 's' is not defined



x = 0
y = 0

isValid = False

while isValid == False:
    x = input("What is your first number?")

    try:
        float(x)
        isValid = True
    except:
        isValid = False

    y = input("What is your second number?")

    try:
        float(y)
        isValid = True
    except:
        isValid = False


print "The answer is: %s" % (x+y)

Upvotes: 0

Views: 238

Answers (3)

jamylak
jamylak

Reputation: 133764

input() tries to evaluate its input as a python expression... So it tries to evaluate s and looks for a variable s.

In this case you could set x to a string:

x = raw_input("What is your first number?")

then do the conversion to float in a try block

Note: This only applies to python 2 as python 3 changes the input() function to take input as a string.

Upvotes: 3

senderle
senderle

Reputation: 151207

When you use input, eval is called on the text the user passes. In this case, the result of eval('s') is the value of the variable s, which isn't defined. So you get a name error. If you want to pass a string, you have to enter it as a string, with ' marks around it. In other words, not s but 's'.

Quoting the docs:

This function does not catch user errors. If the input is not syntactically valid, a SyntaxError will be raised.

This is changed in Python 3, which I didn't initially mention because I figured it would be best not to complicate things, and you're obviously using Python 2. But input in Python 3 is equivalent to raw_input in Python 2.

Upvotes: 1

Li-aung Yip
Li-aung Yip

Reputation: 12486

Firstly, at least in Python 2.7, input() is not what you want for getting user input. You actually want raw_input(). (This is, indeed, confusing, and has been fixed in Python 3.)

Secondly, as @jamylak said, the statement giving the exception is not inside a try/catch block.

Thirdly, when you catch exceptions using except:, you should really be catching a specific type of exception (except ValueError:) instead of any and all exceptions. Catching all exceptions is bad because it masks bugs that raise exceptions you didn't anticipate.


A better way to write this would be:

  • Apply the "Don't Repeat Yourself" principle (DRY) - the code for getting x and getting y from the user is very similar. Instead of writing the same thing twice, write it once and reuse it.
  • Wrap the "get a float from the user" functionality up in a named function.
  • Catch only the specific type of exception that you are prepared to handle.

Tested on Python 2.7:

def get_float_from_user (prompt):
    while True:
        try:
            user_input = float(raw_input(prompt))
            return user_input
        except ValueError:
            print ("Not a floating point number. Please try again.")

x = get_float_from_user("Enter x.")
y = get_float_from_user("Enter y.")

print (x+y)

Upvotes: 3

Related Questions