If just want to handle "quit"
or a float, that’s easy:
total = 0.0
while True:
value = raw_input("enter a number or quit to finish"))
if value == "quit":
break
total += float(value)
print total
But if the user types, say, qiut
or 2..137
, the program will bail out with a ValueError
. How do you protect against that, without a try
?
Or, what if you want to prevent the user from entering, say, inf
or -inf
or nan
, or something that will (at least on some platforms) overflow to one of those (e.g., try 1e309
on most systems)?
Well, you need some way to verify that the float
call is going to work in advance.
First, you have to parse Python 2.7’s floating point literal syntax. At least you’re not dealing with Python 3.x, where, e.g., float('١٠٣')
is perfectly valid and means 103.0
. The language is easily translatable to a regular language, meaning re
or plain string methods should be enough, or you can implement the grammar with something like PyParsing
or a hand-rolled recursive descent parser instead of translating.
Next, you need to evaluate the value to make sure it’s not going to give an error when evaluated as a float. sys.float_info
should have all the information you need… except that Python 2.7 doesn’t actually define what is and isn’t an error. In general, overflow automatically turns into inf
or -inf
, and underflow to 0
, but you may need a bit of trial and error to see what it does for all the edge cases (or, alternatively, look over your interpreter’s source code).
You can probably optimize this part by first ruling in and out everything that’s clearly illegal/safe (e.g., if there’s no exponent and the length is short enough, it can’t possibly overflow), but there will be some range you will have to check in detail.
Or, while you’re evaluating the number, you might as well skip the float
anyway, and just use the number you evaluated. That even allows you to use different rules from Python 2.7 if you want (e.g., handle Persian numerals, or forms like 1.2x10^3
instead of just 1.2e3
, or allow thousands separators, or…).
I won’t write the code for you, because this would all be an insane thing to do. It will take a lot of design, coding, testing, and debugging, and in the end it will run a few orders of magnitude slower than just letting Python try
the float
for you.
solved Python I want a different way of doing this while loop [closed]