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!
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]
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:
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.
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.