Quoting Kevin Reeder <[EMAIL PROTECTED]>:
> The second module is timings.py.
>
> import time, makezeros
>
> def do_timing(num_times, *funcs):
> totals = {}
> for func in funcs: totals[func] = 0.0
> for x in range(num_times):
> for func in funcs:
> starttime = time.time()
> apply(func)
> stoptime = time.time()
> elapsed = stoptime-starttime
> totals[func] = totals[func] + elapsed
> for func in funcs:
> print "Running %s %d times took %.3f seconds" %
> (func.__name__, num_times, totals[func])
>
> do_timing(100, (makezeros.lots_of_appends, makezeros.one_multiply))
Hi Kevin,
I have two comments. First, a simple one:
Using "apply" is no longer necessary in python. It is better to just call the
function directly. (ie: replace 'apply(func)' with 'func()')
Now, to your problem:
You have (possibly) slightly misunderstood the "star" notation.
Consider:
>>> def printArgs(*args):
... print args
...
>>> printArgs(1, 2, 'foo', 'bar')
(1, 2, 'foo', 'bar')
Basically, all the arguments to printArgs get collected into a tuple, which gets
the name 'args' in this example.
Here's another example:
>>> def printArgs2(x, y, *args):
... print 'x:', x
... print 'y:', y
... print 'remaining:', args
...
>>> printArgs2(1, 'foo', 3, 'hello world', 99)
x: 1
y: foo
remaining: (3, 'hello world', 99)
In this case, x and y consumed the first two arguments to printArgs2, and the
remainder went into the catch-all args.
Now, lets look at the relevant bits of your code:
----
def do_timing(num_times, *funcs):
...
----
This says: "Call the first argument 'num_times', and put any other arguments
into a tuple called 'funcs'."
You then do this:
----
do_timing(100, (makezeros.lots_of_appends, makezeros.one_multiply))
----
Here, you are calling do_timing with _two_ arguments.
First argument: 100
Second argument: (makezeros.lots_of_appends, makezeros.one_multiply)
Your second argument is a tuple with two elements. funcs in your function will
be set to a tuple containing all remaining arguments --- ie:
((makezeros.lots_of_appends, makezeros.one_multiply),) (which is a tuple with
one element, whose element is a tuple with two elements).
You can correct this in two ways:
- Change the function definition to:
def do_timing(num_times, funcs):
Now, funcs is just an ordinary positional argument, and it will take whatever
you give it. If you give it a tuple of functions, then you can iterate over it
the way you expect.
or:
- Change the function call to:
do_timing(100, makezeros.lots_of_appends, makezeros.one_multiply)
*funcs will consume the two function arguments, giving you the same result as
in the first option.
My personal preference would be for the first option, which I think is clearer..
(it better expresses the idea that you have written a function which will take
a
list of functions and time them)
HTH!
--
John.
_______________________________________________
Tutor maillist - [email protected]
http://mail.python.org/mailman/listinfo/tutor