0

I am trying to write a function that calls another function repeatedly. This is what I have so far:

def function1(n, function_object):
    if n > 0:
        function_object
        function1(n-1, function_object)

def function2(x, word):
    for i in range(x):
        print word

y = 'pluto'

function1(3, function2(3, y))

This is what I get when I try to run it:

>>> 
pluto
pluto
pluto
>>> 

I thought it would print 'pluto' nine times, but it seems that function2 is only executing once. How can I get it to execute repeatedly inside function1?

aih
  • 3
  • 1

4 Answers4

1
  • missed () after function_object.
  • Call to function1 is passing the return value of function2, you should pass function object. I replaced it with lambda in the following code. (to make a anonymous function that call function2 instead of calling function2 before calling function1)

def function1(n, function_object):
    if n > 0:
        function_object() # <---- Added ()
        function1(n-1, function_object)

def function2(x, word):
    for i in range(x):
        print word

y = 'pluto'

function1(3, lambda: function2(3, y)) # <---
falsetru
  • 357,413
  • 63
  • 732
  • 636
  • 1
    I think you missed the point of what he was trying to do -- pass an arbitrary function to function1, which function1 would then call. – jdhildeb Feb 01 '14 at 02:53
  • @jdhildeb, I don't think OP is asking about abitrary argument. – falsetru Feb 01 '14 at 03:01
  • This seems to be the right solution, but adding the lambda is likely a huge leap from the OP's current level of understanding, and so it needs more explanation than "this different-looking thing happens to work". – lvc Feb 01 '14 at 03:11
  • 1
    @falsetru: it seems to me that OP is trying to pass function2 as an argument to function1, and that function1 should then invoke function2 repeatedly. His mistake is to invoke function2 in the last line instead of passing it. So I think your lambda kind of wallpapers over what he was trying to do. – jdhildeb Feb 01 '14 at 03:39
  • @jdhildeb, Yes, I agree that OP's mistake is calling `function2` instead of passing it. Sorry, but I don't understand what `lambda kind of wallpapers over ..` mean. – falsetru Feb 01 '14 at 03:45
0

In your code, function1 was calling itself AND another function. It doesn't need to be that complicated.

Also, in the last line you were passing function2(3, y) as a parameter - because you have parens () there, that calls function2 and gets the result, then passes the result to function1. I don't think that's what you meant to do.

So I've modified it. As you requested, here is a function (function1) which calls another (arbitrary) function N times, passing the current value of N along with arbitrary arguments.

def function1(n, function_object, *args):
    while n > 0:
        function_object(n, *args)
        n -= 1

def function2(n, x, word):
    for i in range(x):
        print "%s, %d, %d" % (word, n, i)

y = 'pluto'

function1(3, function2, 3, y)

Output:

pluto, 3, 0
pluto, 3, 1
pluto, 3, 2
pluto, 2, 0
pluto, 2, 1
pluto, 2, 2
pluto, 1, 0
pluto, 1, 1
pluto, 1, 2
jdhildeb
  • 3,322
  • 3
  • 17
  • 25
  • The title explicitly mention `recursion`. – falsetru Feb 01 '14 at 03:53
  • True, but the goal at the top of the post is "I am trying to write a function that calls another function repeatedly." Implementing this using recursion is not necessary, that's why I said "it doesn't have to be that complicated." I'm trying to simplify the solution because simpler code is better. – jdhildeb Feb 01 '14 at 17:31
0

When you do this:

function2(3, y)

that function is run immediately, and its return value (which is None in this case) is passed into function1 as the function_object argument. In function1, you try to call it like this:

function_object

but that doesn't actually call it. So, function2 will end up being called a total of once - before function1 is ever called.

If you replace that with function_object(), it does call it - but then you get an error, since function_object is None, which isn't callable. To pass function2 in instead of None, just don't call it outside yet - instead you need to do this:

function1(3, function2)

This will get you an error saying that function2 needs to take two arguments, but you're not giving it any. So the next step is to work out how to pass those arguments to it - which needs to happen at the time it is called. But function1 expects a function with no arguments.. you can fix that problem by writing another function that takes no arguments, and calls function2 with the two arguments you want, and pass that into function1. So it looks like this:

def function1(n, function_object):
    if n > 0:
        function_object()
        function1(n-1, function_object)

def function2(x, word):
    for i in range(x):
        print word

y = 'pluto'

def function3():
    function2(3, y)

function1(3, function3)

If you're only using this function3 once, and there isn't a sensible name you can give it, you can use a lambda to create an anonymous function that does the same job:

def function1(n, function_object):
    if n > 0:
        function_object()
        function1(n-1, function_object)

def function2(x, word):
    for i in range(x):
        print word

y = 'pluto'
function1(3, lambda: function2(3, y))
lvc
  • 34,233
  • 10
  • 73
  • 98
-1

Lambdas are a great option in this case, otherwise you could have a look to this post where they explain another 2 ways of making it: Passing functions with arguments to another function in Python?

Community
  • 1
  • 1
Diegomanas
  • 162
  • 8