Reputation: 673
I am learning Python and I am reading the "Think Python" and doing some simple exercises included in the book.
I am asked "Define a new function called do_four that takes a function object and a value and calls the function four times, passing the value as a parameter."
I am trying to compose this function with one statement by calling a function already defined called do_twice() and test it with a function called print_double(). Here is the code:
def do_twice(f, x):
f(x)
f(x)
def do_four(f, v):
do_twice(do_twice(f, v), v)
def print_twice(s):
print s
print s
s = 'abc'
do_four(print_twice, s)
This code produces an error:
abc
abc
abc
abc
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-41-95b513e5e0ee> in <module>()
----> 1 do_four(print_twice, s)
<ipython-input-40-100f8587f50a> in do_four(f, v)
1 def do_four(f, v):
----> 2 do_twice(do_twice(f, v), v)
<ipython-input-38-7143620502ce> in do_twice(f, x)
1 def do_twice(f, x):
----> 2 f(x)
3 f(x)
TypeError: 'NoneType' object is not callable
In trying to understand what is happening I tried to construct a Stack Diagram as described in the book. Here it is:
Could you explain the error message and comment on the Stack Diagram?
Your advice will be appreciated.
Upvotes: 2
Views: 280
Reputation: 13510
do_twice
gets a function on the first argument, and doesn't return anything. So there is no reason to pass do_twice
the result of do_twice
. You need to pass it a function
.
This would do what you meant:
def do_four(f, v):
do_twice(f, v)
do_twice(f, v)
Very similar to how you defined do_twice
by f
Upvotes: 2
Reputation: 522110
do_twice(do_twice(f, v), v) ^^^^^^^^^^^^^^
Slightly rewritten:
result = do_twice(f, v)
do_twice(result, v)
You're passing the return value of do_twice(...)
as the first parameter to do_twice(...)
. That parameter is supposed to be a function object. do_twice
does not return anything, so result
is None
, which you're passing instead of the expected function object.
There's no point in nesting the two do_twice
in any way here.
Upvotes: 1