[Tutor] More problems with Learning Python example

Danny Yoo dyoo at hkn.eecs.berkeley.edu
Fri Aug 12 04:00:59 CEST 2005


> Traceback (most recent call last):
>    File "timings.py", line 16, in ?
>      do_timing(100, makezeros.lots_of_appends, makezeros.one_multiply)
>    File "timings.py", line 12, in do_timing
>      totals[func] = totals[func] + elapsed
> KeyError: <function one_multiply at 0x403eaf0c>

> help(KeyError) tells me Mapping key not found. Have I stumbled on
> another error in the book? I don't know how to proceed in tracking this
> down. any suggestions?

Hi Terry,

This looks a little unusual, for code in the book to be so bad.  *grin*


The logic error is that 'func' is being reused in a way that isn't clear.
There's several nested loops that look a bit unusual.  Let me cut out the
particularly funky section:

>      for func in funcs:
>          totals[func] = 0.0
>          starttime = time.clock()        # record starting time
>          for x in range(num_times):
>              for func in funcs:
>                  apply(func)


Note that the innermost loop here reuses the same 'func' variable, which
breaks the assumption of the rest of the code:

The code logic suggests that the innermost loop really shouldn't be
there.  From a high-level point of view, the program is doing this:

#######
def do_timing(...):
    for each function to be timed:
        record start time
        do some time trials
        record end time
    ...
#######

And, at least from the high level view, 'do some time trials" should not
touch 'funcs' at all: it should only concentrate on the particular
function that's being exercised.


The fact that the innermost loop in:

>      for func in funcs:
>          totals[func] = 0.0
>          starttime = time.clock()        # record starting time
>          for x in range(num_times):
>              for func in funcs:
>                  apply(func)

is touching data that is irrelevant to what it should be doing is the
clue: it strongly suggests that a logic bug is there.


Developing this further, it might be a good thing to explicitely write a
helper to run a function n times.  If we imagine that we have something
like this:

######
def time_trial(func, num_times):
    """Applies a function func num_times."""
    ... # fill me in
######


then the logic of the block in do_timing() reduces to:

####
for func in funcs:
    totals[func] = 0.0
    time_trial(func, num_times)
####


I'm still a little shocked that Learning Python would have such code,
though.  Can anyone double check this?  We should be sending errata
reports if there are serious bugs like this in the book..


If you have any questions on this, please ask questions.  Good luck!




More information about the Tutor mailing list