The Qualification round in Google code jam taught me a new thing about python.
Imagine following program for getting asleep:
# asleep.py import sys, time sheep = int(sys.argv[1:].pop()) print "Counting sheep up to", sheep for i in xrange(sheep): time.sleep(1) if i > 4: break print i+1, print "Fell asleep"
and you run it:
$ python asleep.py 1111111 Counting sheep up to 1111111 1 2 3 4 5 Fell asleep
It looks fine because xrange
does not create the whole list [0, 1, ..., 1111110]
but instead works as “generator” that requests the next value on demand.
But what happens if we raise the sheep count?
$ python asleep.py 11111111111 Counting sheep up to 11111111111 Traceback (most recent call last): File "asleep.py", line 7, in <module> for i in xrange(sheep): OverflowError: Python int too large to convert to C long
That’s interesting. It turns out that when you run the line
### sheep = int(sys.argv[1:].pop()) ###
the type of sheep
variable may vary:
### sheep = int(sys.argv[1:].pop()) print sheep.__class__ ###
$ python asleep.py 1111111 <type 'int'>
$ python asleep.py 11111111111 <type 'long'>
Basically, Python checks the input value and if it’s inside the range [-sys.maxint - 1, sys.maxint]
it returns int
, otherwise converts it to long
. Same thing happens if you run a code like:
a = sys.maxint print a.__class__ # <type 'int'> a += 1 print a.__class__ # <type 'long'>
So simply use a while loop and you’re safe:
import sys, time sheep = int(sys.argv[1:].pop()) print "Counting sheep up to", sheep i = 0 while i < sheep: time.sleep(1) if i > 4: break print i+1, i+=1 print "Fell asleep"