Newbie (but improving) - Passing a function name with parameters as a parameter

M

mosscliffe

I am trying to time a function's execution, but I get 'TypeError:
'bool' object is not callable' when I try to run it.

I suspect it is my calling of 'timeloop' with the function name
'lookup' and its associated variables or it could just be some stupid
error on my part.

function 'lookups' was working OK

Any help will be appreciated.

Thanks - Richard

===The offending Code =====


#!/usr/bin/python

def timeloop(dofunction,iters=10):
import datetime
print "->-> Start of test", "LOOPS=", iters,
datetime.datetime.now().ctime()
for x in xrange(iters):
print x
dofunction()
print "<-<- End of test", "LOOPS=", iters,
datetime.datetime.now().ctime()



def lookup(recs,patterns):
matchcount = 0
pattcount = 0
for patt in patterns:
if matchcount < pattcount:
break
pattcount += 1
for rec in recs:
# print "PATT:", patt, " REC:", rec, " PATTCOUNT=", pattcount
if patt in rec:
matchcount +=1
break
# print"MATCHCOUNT=",matchcount, "PATTCOUNT=", pattcount
if matchcount == pattcount:
return True
else:
return False



myrecs = ['This is a title for Brian', 'this is detail one for brian',
'this is detail two for brian', 'this is another detail one for
brian']

test1 = ['one', 'nomatch']
test2 = ['one', 'two']
test3 = ['title', 'two', 'nomatcheither']

mypatts = test1

timeloop(lookup(myrecs,mypatts), 10)
 
A

Asun Friere

Try again ...

Just looking over your code quickly ... the function 'lookup' returns
either True or False (a boolean) depending on whether matchcount ==
pattcount. Then in the declaration of the function 'timeloop' this
return value gets bound to 'dofunction.' The subsequent call
'dofunction()' fails, because a boolean is not callable.

Asun
 
A

Ant

As Stephan said, you can investigate the timeit module. If you want to
test it your way, wrap up your function call in another function:

def timeloop(dofunction,iters=10): ....

def lookup(recs,patterns): ....

myrecs = ...
def test1():
lookup(myrecs, ['one', 'nomatch'])

def test2():
lookup(myrecs, ['one', 'two'])
timeloop(test1, 10)

Using timeit:

t = timeit.Timer("lookup(myrecs, ['one', 'nomatch'])", "from __main__
import *")
print t.timeit(10)
 
M

mosscliffe

Many thanks. I think I see what you mean.

I will try 'timeit' as well.

Aren't examples wonderful ?

As Stephan said, you can investigate the timeit module. If you want to
test it your way, wrap up your function call in another function:

...> def timeloop(dofunction,iters=10):
...
def lookup(recs,patterns):
...

myrecs = ...

def test1():
lookup(myrecs, ['one', 'nomatch'])

def test2():
lookup(myrecs, ['one', 'two'])
timeloop(test1, 10)

Using timeit:

t = timeit.Timer("lookup(myrecs, ['one', 'nomatch'])", "from __main__
import *")
print t.timeit(10)
 
T

Terry Reedy

Asun Friere pointed out the central flaw in your program. Since passing
functions as arguments is an important concept, here, for any newbies who
did not understand, is a restatement of the problem and the fix.

| timeloop(lookup(myrecs,mypatts), 10)

This does not pass the lookup function to timeloop. Rather it calls lookup
and passes the boolean result. The attempt to 'call' that boolean gives

|I am trying to time a function's execution, but I get 'TypeError:
| 'bool' object is not callable' when I try to run it.

| I suspect it is my calling of 'timeloop' with the function name
| 'lookup' and its associated variables

Yes. Make the following changes and all should be well.

| def timeloop(dofunction,iters=10):

def timeloop(func, args, iters=10)

| import datetime
| print "->-> Start of test", "LOOPS=", iters,
| datetime.datetime.now().ctime()
| for x in xrange(iters):
| print x
| dofunction()

func(*args)

| print "<-<- End of test", "LOOPS=", iters,
| datetime.datetime.now().ctime()
|
| def lookup(recs,patterns):
| matchcount = 0
| pattcount = 0
| for patt in patterns:
| if matchcount < pattcount:
| break
| pattcount += 1
| for rec in recs:
| # print "PATT:", patt, " REC:", rec, " PATTCOUNT=", pattcount
| if patt in rec:
| matchcount +=1
| break
| # print"MATCHCOUNT=",matchcount, "PATTCOUNT=", pattcount
| if matchcount == pattcount:
| return True
| else:
| return False
|
|
|
| myrecs = ['This is a title for Brian', 'this is detail one for brian',
| 'this is detail two for brian', 'this is another detail one for
| brian']
|
| test1 = ['one', 'nomatch']
| test2 = ['one', 'two']
| test3 = ['title', 'two', 'nomatcheither']
|
| mypatts = test1
|
| timeloop(lookup(myrecs,mypatts), 10)

timeloop(lookup, (myrecs, mypaths), 10)

Terry Jan Reedy
 
M

MRAB

Asun Friere pointed out the central flaw in your program. Since passing
functions as arguments is an important concept, here, for any newbies who
did not understand, is a restatement of the problem and the fix.

| timeloop(lookup(myrecs,mypatts), 10)

This does not pass the lookup function to timeloop. Rather it calls lookup
and passes the boolean result. The attempt to 'call' that boolean gives

|I am trying to time a function's execution, but I get 'TypeError:
| 'bool' object is not callable' when I try to run it.

| I suspect it is my calling of 'timeloop' with the function name
| 'lookup' and its associated variables

Yes. Make the following changes and all should be well.

| def timeloop(dofunction,iters=10):

def timeloop(func, args, iters=10)

| import datetime
| print "->-> Start of test", "LOOPS=", iters,
| datetime.datetime.now().ctime()
| for x in xrange(iters):
| print x
| dofunction()

func(*args)

| print "<-<- End of test", "LOOPS=", iters,
| datetime.datetime.now().ctime()
|
| def lookup(recs,patterns):
| matchcount = 0
| pattcount = 0
| for patt in patterns:
| if matchcount < pattcount:
| break
| pattcount += 1
| for rec in recs:
| # print "PATT:", patt, " REC:", rec, " PATTCOUNT=", pattcount
| if patt in rec:
| matchcount +=1
| break
| # print"MATCHCOUNT=",matchcount, "PATTCOUNT=", pattcount
| if matchcount == pattcount:
| return True
| else:
| return False
|
|
|
| myrecs = ['This is a title for Brian', 'this is detail one for brian',
| 'this is detail two for brian', 'this is another detail one for
| brian']
|
| test1 = ['one', 'nomatch']
| test2 = ['one', 'two']
| test3 = ['title', 'two', 'nomatcheither']
|
| mypatts = test1
|
| timeloop(lookup(myrecs,mypatts), 10)

timeloop(lookup, (myrecs, mypaths), 10)
A smaller change would be:

timeloop(lambda: lookup(myrecs,mypatts), 10)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top