Interesting float/int casting in Python
25th of April 2006
Casting is when you convert a variable value from one type to another. This is, in Python, done with functions such as int() or float() or str(). A very common pattern is that you convert a number, currently as a string into a proper number.
Let me exemplify:
>>> y = '-90'
>>> print x + y
100-90
>>> print int(x) + int(y)
10
That was the int() function. There's also another very common one which is float() which does basically the same thing:
10.0
Today I had to fix a bug might come as a surprise. Allow me to demonstrate:
>>> print float(x)
100.0
>>> print int(float(x))
100
>>> print int(x)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ValueError: invalid literal for int(): 100.0
As you can see, the int() function can convert floating point numbers to integers just fine but it can't do that and decode it from a string in one statement. A flaw in the design? No, I don't think so. It's just another design decision that you just have to learn. But, is it to explicit? Would it be that bad if the int() function could do both actions in one builtin sweep?
The bug I found was related to a human height input validator that looked something like this:
try:
cm = int(cm)
return 100 <= cm <= 250
except ValueError:
return False
>>> validHeight(190)
True
>>> validHeight('190')
True
>>> validHeight('')
False
>>> validHeight('190.0')
False # WHAT?!
You see, our system saves all values like this in the database as REAL (floating point decimal values) and when you return to the Height form it prints "190.0" as the default prefilled value in the input box. In the database it's a valid and correct value. The validHeight() function had to be rewritten to this:
try:
cm = float(cm)
return 100 <= cm <= 250
except ValueError:
return False
>>> validHeight(190)
True
>>> validHeight('190')
True
>>> validHeight('')
False
>>> validHeight('190.0')
True
Geez! What a long boring story this became. Just remember, float() is sometimes better than int(). In some cases you might have to use both.