Python Mystery Theatre -- Episode 3: Extend this

Harvey Thomas hst at empolis.co.uk
Tue Jul 22 05:49:41 EDT 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 ---------------------
> s = 'abracadabra'
> 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 = []
> 
>     def add(self, item):
>         self.numitems += 1
>         self.contents += [item]
> 
> laundry = Bin()
> groceries = Bin()
> 
> laundry.add('shirt')
> groceries.add('bananas')
> groceries.add('nuts')
> laundry.add('socks')
> groceries.add('pretzels')
> 
> 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
> print "Workload;", swaps
> 
>
 
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.





More information about the Python-list mailing list