Forums

OT: Friday Python Puzzler #3

I almost forgot again this week... But not quite! (Cue groans)

Just a couple of short ones to have a go at - I guess these aren't really puzzlers so much as oddities that you may not have come across. Firstly, what will this function return and what will it print?

def func():
    try:
        print "one"
        return 1
    except:
        print "two"
        return 2
    else:
        print "three"
        return 3
    finally:
        print "four"
        return 4

Secondly, can you explain this somewhat random looking behaviour?

>>> 1+2 is 3
True
>>> 5+10 is 15
True
>>> 200 + 60 is 260
False
>>> 200 + 55 is 255
True
>>> 200 + 56 is 256
True
>>> 200 + 57 is 257
False

Ah well, time for the answer I guess... Assuming anybody cares. (^_^)

The first one is pretty straightforward - the function prints one and four and returns 4. It's logical if you think about it - finally blocks are guaranteed to execute last, and this includes after a return statement, but it might seem a little odd to some people that putting a return in a finally block can "override" the return value of a function.

As an aside, the else clause would have normally executed (unless an exception was thrown), but the return statement in the body of the try block prevented that - the finally block is the only one guaranteed to run. This behaviour is mentioned in the penultimate paragraph of the Python reference docs for the try statement. For bonus fun, guess what this function returns:

def func():
    for i in xrange(5):
        try:
            return i
        finally:
            break

The second example is a little quirkier. Those moderately familiar with Python will know that the is operator differs from == in that it checks for referential equality as opposed to value equality (i.e. whether the two arguments refer to the same object as opposed to whether the objects hold equivalent values). So it seems a little odd that any two integers would ever return True for an is check.

As it turns out, however, Python has a quirky little optimisation where "small" integers are in fact singletons, much as None is (all references to None refer to the same global singleton object, which is why you can use the is operator to compare it - indeed, that's considered best practice). I assume this is done to speed up common cases such as loops, which would tend to use small values, but I'm not sure. Of course, this is a CPython implementation issue and should never be relied upon. Indeed, the threshold of what counts as "small" has changed in different Python versions.

Hope that was at least slightly interesting!

Cartroo wrote:
Hope that was at least slightly interesting!

It is / was and I care...☺

I hadn't posted any answers so I wouldn't spoil the fun for anyone else. Is that how these are meant to be handled? I haven't read your first two, because I was too busy when you posted them.

Either way I suppose I should go back and look at the first two!

Ah, there's no "supposed to" about it, really, they're mostly for interest, but thanks for confirming that someone's reading them!

I did just re-read my post above an it did sound a little self-pitying, didn't it? One of those cases where it didn't come across as lightly as it was meant - curse you, lack of verbal cues.

The first two were a little more involved, but you might still find them interesting. You can always just read my initial post and no further and see if you can figure them out before reading down.

Yes, reading only the beginning can work for the disciplined. Of course in the event you accidentally scroll a line or two too far...you could see something critical that you weren't supposed to. Not sure that there is a resolution unless you intentionally add some dead space to the bottom of the initial post to allow for such accidents. You could use the space to include a nice ASCII art warning about spoilers if you go past this point. Just a thought...☺

Or for that matter people posting answers could do that very thing, thus allowing people to freely read until they encounter a spoiler alert. Even better would be post folding...does this site support that? I just did a search for fold in the docs and got: hits is None...☺

Well, I think SO uses the >! syntax for spoiler tags, which only appear when you mouse over them - I'm not sure if that's standard Markdown, however.

! Doesn't look like it.

@PAStaff...any hints on spoiler tags would be much appreciated.

Oh, and anyone else is invited, but of course the staff has the advantage of reviewing the source...☺