Python Mystery Theatre -- Episode 3: Extend this

Florian Schulze florian.proff.schulze at gmx.net
Tue Jul 22 13:13:29 CEST 2003


On Tue, 22 Jul 2003 07:27:21 GMT, Raymond Hettinger <vze4rx4y at verizon.net> 
wrote:

> 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)

Duh, I had to look at the output, but after that it was obvious:
For 0+6j, hasattr(z, 'real') is true, but t.real is false so z is printed.
For imag it's no problem, as it's 0 either way.

> ACT II ---------------------
> uniq = {}
> for k in (10, 'ten', 10+0j, u'ten', 'Ten', 't'+'en', 10.0):
> uniq(k) = 1
> print len(uniq)

My prediction is between 5 and 7 depending on the hash values for numbers.
Uhh, 3 !?! So numbers and strings generate a hash just by their value. And 
the unicode string has the same hash as a normal string if just ascii is 
used. Should have been obvious.
ps: it should be uniq[k] = 1 or the output would have been a traceback, 
maybe this was intended ;)

> ACT III ---------------------
> s = 'abracadabra'
> for i in [3, 2, 1, 0]:
> print s[i:], s[-i:]

Prediction:
acadabra bra
racadabra ra
bracadabra a
abracadabra abracadabra

Result:
acadabra bra
racadabra ra
bracadabra a
abracadabra abracadabra

Yep! s[-0:] is the same as s[0:].

> ACT IV ---------------------
> pets = list('cat ')
> pets += 'dog '
> pets.extend('fish ')
> print pets + 'python'

I would say this raises a TypeError.
But it's at the print not at pets += 'dog ', so the string is used as a 
sequence here.

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

Uh! Binary representation of floating point strikes again.

> 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

Prediction:
2 ['shirt','bananas','nuts','socks','pretzels']
3 ['shirt','bananas','nuts','socks','pretzels']

Result:
2 ['shirt','bananas','nuts','socks','pretzels']
3 ['shirt','bananas','nuts','socks','pretzels']

Contents is a class variable and not unique to an instance.

> 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

I would say it's bubble sort, but it doesn't work and I don't yet 
understand why.
Oh, wait, i and j are assigned first and then a[i] is the a[j] from before 
and the other way around. But after testing I found out that i and j should 
never be swapped, as this disturbs the inner loop, because i is wrong then.

My guess for the real bugs:
ACT I
ACT III
ACT V

Florian Schulze




More information about the Python-list mailing list