Reputation: 35
EDIT: The suggested duplicate is incredibly helpful in regards to basic input validation. While it does cover a lot, my specific problem (failing to assign int(evaluation)
to a variable) is only explicitly addressed here. I'm marking this separately in case anyone else has made a similarly silly mistake :)
I've spent the last few weeks playing with Python 2.7 and having a lot of fun. To learn more about while
loops, I've created a small script which asks the user for an integer between 1 and 10.
My goal is to then be able to respond to cases in which the user responds with unexpected input, like a non-integer, or an integer outside the specified range. I've been able to fix a lot of my issues with help from other StackOverflow threads, but now I'm stumped.
First, I created a variable, idiocy
, to keep track of exceptions. (The script is supposed to be sassy, but until I get it working, I'm the one it's making fun of.)
idiocy = 0
while 1:
evaluation = raw_input("> ")
try:
int(evaluation)
if evaluation < 1 or evaluation > 10:
raise AssertionError
except ValueError:
idiocy += 1
print "\nEnter an INTEGER, dirtbag.\n"
except AssertionError:
idiocy += 1
print "\nI said between 1 and 10, moron.\n"
else:
if idiocy == 0:
print "\nOkay, processing..."
else:
print "\nDid we finally figure out how to follow instructions?"
print "Okay, processing..."
break
As you can see, I'm trying to handle two different errors -- a ValueError
for the input type, and an AssertionError
for the integer range -- and keep track of how many times they're raised. (Really, I only care about knowing whether or not they've been raised at least once; that's all I need to insult the user.)
Anyways, when I run the script in its current form, the error response works just fine ('dirtbag' for non-integers, 'moron' for out-of-range). The problem is that even when I input a valid integer, I still get an out-of-range AssertionError
.
I suspect that my issue has to do with my while
logic, but I'm not sure what to do. I've added a break
here or there but that doesn't seem to help. Any suggestions or blatant errors? Again, total Python beginner here, so I'm half winging it.
//If anyone has simpler, cleaner, or prettier ways to do this, feel free to let me know too. I'm here to learn!
Upvotes: 2
Views: 117
Reputation: 516
In your code:
int(evaluation)
is not typecasting evaluation variable to int type. The output is:
> 2
<type 'str'>
I said between 1 and 10, moron.
Try this:
idiocy = 0
while 1:
try:
evaluation = int(raw_input("> "))
if evaluation < 1 or evaluation > 10:
raise AssertionError
except ValueError:
idiocy += 1
print "\nEnter an INTEGER, dirtbag.\n"
except AssertionError:
idiocy += 1
print "\nI said between 1 and 10, moron.\n"
else:
if idiocy == 0:
print "\nOkay, processing..."
else:
print "\nDid we finally figure out how to follow instructions?"
print "Okay, processing..."
break
By the way you can use tuple to store all your exceptions. Example:
idiocy = 0
all_exceptions = (ValueError, AssertionError)
while 1:
try:
evaluation = int(raw_input("> "))
if evaluation < 1 or evaluation > 10:
raise AssertionError("\nI said between 1 and 10, moron.\n")
except all_exceptions as e:
idiocy += 1
print str(e)
else:
if idiocy == 0:
print "\nOkay, processing..."
else:
print "\nDid we finally figure out how to follow instructions?"
print "Okay, processing..."
break
Hope it helps.
Upvotes: 0
Reputation: 23753
Your range test can be refactored as
assert 1 <= evaluation <= 10
You could keep your insults in a dictionary
insults = {AssertionError : "\nI said between 1 and 10, moron.\n",
ValueError : "\nEnter an INTEGER, dirtbag.\n"
}
And write the try/except like this
try:
...
except (AssertionError, ValueError) as e:
print(insults[type(e)])
When you change the user input to an int, you need to assign it to something
evaluation = int(evaluation)
assert was meant for debugging - you are using it incorrectly.
Upvotes: 0
Reputation: 5193
Your problem is you're not saving the int
version of evaluation
to evaluation
like this:
idiocy = 0
while 1:
evaluation = raw_input("> ")
try:
evaluation = int(evaluation) <--- here
if evaluation < 1 or evaluation > 10:
raise AssertionError
except ValueError:
idiocy += 1
print "\nEnter an INTEGER, dirtbag.\n"
except AssertionError:
idiocy += 1
print "\nI said between 1 and 10, moron.\n"
else:
if idiocy == 0:
print "\nDid we finally figure out how to follow instructions?"
print "Okay, processing..."
else:
print "\nOkay, processing..."
If you wanted to track the types of exceptions raised, you could use collections.Counter
for idiocy
and change the code like this:
from collections import Counter
idiocy = Counter()
while 1:
evaluation = raw_input("> ")
try:
evaluation = int(evaluation)
if evaluation < 1 or evaluation > 10:
raise AssertionError
except ValueError as e:
idiocy[e.__class__] += 1
print "\nEnter an INTEGER, dirtbag.\n"
except AssertionError as e:
idiocy[e.__class__] += 1
print "\nI said between 1 and 10, moron.\n"
else:
if idiocy == 0:
print "\nDid we finally figure out how to follow instructions?"
print "Okay, processing..."
else:
print "\nOkay, processing..."
>>> idiocy
Counter({AssertionError: 2, ValueError: 3})
And you can access the error counts by key like idiocy[AssertionError]
Upvotes: 2
Reputation: 303
You have int(evalutation)
, but you're not assigning it to anything.
Try
try:
evaluation = int(evaluation)
assert 0 < evaluation < 10
except ValueError:
...
except AssertionError:
Upvotes: 1