# Python Mystery Theatre -- Episode 3: Extend this

Harvey Thomas hst at empolis.co.uk
Tue Jul 22 11:49:41 CEST 2003

```Raymond Hettinger wrote:
>
> Here are few more mini-mysteries for your amusement
> and edification.
>
> Again in this episode, the program output is not shown.
> Your goal is to predict the output and, if anything
> mysterious occurs, then explain what happened
> (in blindingly obvious terms).
>
> This time, the extra credit is for picking-out the three
> that surfaced as errors in my own, real code over
> the past few years (the example context below may be
> different, but the type of error occurred in real code).
>
> Try to solve these without looking at the other posts.
> Let me know if you learned something new along the way.
>
>
> Enjoy,
>
>
> Raymond Hettinger
>
>
> ACT I ---------------------
> def real(z):
>     return hasattr(z, 'real') and z.real or z
> def imag(z):
>     return hasattr(z, 'imag') and z.imag or 0
> for z in 3+4j, 5, 0+6j, 7.0, 8+0j, 9L:
>     print real(z), imag(z)
>
I guess this was a real error.
print real(z), imag(z)  will give
6j, 6
as z.real is 0, therefore the result of the first expression is z which is 6j

> ACT II ---------------------
> uniq = {}
> for k in (10, 'ten', 10+0j, u'ten', 'Ten', 't'+'en', 10.0):
>     uniq(k) = 1
> print len(uniq)
>
Assuming it should read uniq[k] = 1, the answer is three as there are only three unique keys - 10, 'Ten' and 'ten'

> ACT III ---------------------
> for i in [3, 2, 1, 0]:
>         print s[i:], s[-i:]
>
as -0 is the same as 0, I presume the trap is that s[-i:] when s == 0 gives 'abracadabra', whereas the three preceding values are 'bra', 'ra' and 'a'

> ACT IV ---------------------
> pets = list('cat ')
> pets += 'dog '
> pets.extend('fish ')
> print pets + 'python'
>
I guess this was a real error as I've done it myself.
pets is a list of characters, initially ['c', 'a', 't'], which is then extended by += 'dog ' and .extend('fish')
The print statement is trying to concatenate a string to a list, which isn't allowed. I suppose this is why some people don't like augmented assignment as the results are sometimes unexpected.

> INTERMISSION (with output included, oh yeah! ------------
> >>> import operator
> >>> 1 - reduce(operator.add, [1e-7]* 10**7)
> 2.4983004554002264e-010

Is this just the rounding error on a particular machine in evaluating 1e-7* 10**7?
>
> ACT V ---------------------
> class Bin:
>     numitems = 0
>     contents = []
>
>         self.numitems += 1
>         self.contents += [item]
>
> laundry = Bin()
> groceries = Bin()
>
>
> print laundry.numitems, laundry.contents
> print groceries.numitems, groceries.contents

I guess this was a real error due to the unintended use of class variables. the two print statements yield identical results with 5 items in each.
>
>
> ACT VI -----------------------------------------
> print "What is the technical name for this algorithm or
> transformation?"
> a = range(0, 100, 10)
> import random
> random.shuffle(a)
> print "Input:", a
> swaps = 0
> for i in range(len(a)):
>     for j in range(i+1, len(a)):
>     if a[i] > a[j]:
>         i, j, a[i], a[j], swaps = j, i, a[j], a[i], swaps+1
> print "Output:", a
>
>

It's a quick and dirty bubble sort. Not sure what's wrong without running the code, but it looks wrong to mess around with the loop indices. Perhaps the swapping line should read
a[i], a[j], swaps = a[j], a[i], swaps+1. BTW isn't there an indentation error in the code?
>

Interesting set of puzzles.

_____________________________________________________________________
This message has been checked for all known viruses by the MessageLabs Virus Scanning Service.

```