1

I'm currently working on recursive function on Think Python, page 44.

It wrote:

"Write a function called do_n that takes a function object and a number, n as arguments,

and that calls the given function n times."

I found a really good answer from this discussion Text

Okay, now I know how to type the code, but how do I actually run it?

def do_n(f, n):
    if n <= 0:
          return
    f(n)
    do_n(f, n-1)

The code like below looks really easy to figure out:

def print_n(s, n):
    if n <= 0:
         return
    print(s)
    print_n(s, n-1)

Just need to type Print("Anita", 2) and the output will be:

Anita
Anita

But the do_n I can't figure out what to type in order to run the code. I guess I am not familiar with do function.

Can anyone explain it?

ggorlen
  • 44,755
  • 7
  • 76
  • 106
JimBigMac
  • 19
  • 6
  • 1
    So what exactly are you stuck on? Is it that you just want to run the funcntion or are you confused about how it should work. – Sherif Jul 21 '21 at 05:05
  • 2
    First of all, this is a poor application of recursion. If you want to call the function more than, say, 1000 times, you'll probably blow the call stack and crash the program. Write a loop and save recursion for sub-linear algorithms like divide and conquer. That said, just pass the function in as a parameter, either a lambda or an already-defined function name (without parentheses). `do_n(lambda: print("Hello"), 5)`. – ggorlen Jul 21 '21 at 15:49
  • 3
    Does this answer your question? [Python - Passing a function into another function](https://stackoverflow.com/questions/1349332/python-passing-a-function-into-another-function) – ggorlen Jul 21 '21 at 15:53
  • By the way, `do_n` should just call `f()`, not `f(n)`. – mkrieger1 Jul 21 '21 at 15:57
  • 3
    You should note that "do" and "print" in `do_n` and `print_n` are just completely arbitrary letters. There is no "do function". The point of `do_n` is that it takes 2 arguments: a function and a number. You get a function by doing (another) `def` somewhere which makes a new function. – Andrew Jaffe Jul 21 '21 at 15:57
  • Thank you guys, @AndrewJaffe the light bot just turn on when you mention it's just a completely "arbitrary letters." Thank you for that. Not understand it was just a arbitrary letter, a concept, is where I stuck on. – JimBigMac Jul 22 '21 at 16:41
  • @ggorlen This does help me observe how others use this method, thanks. – JimBigMac Jul 22 '21 at 16:42
  • @ggorlen I think I have learned lambda yet, just start learning from very beginning, lol. But I have tried to crash the program, lol. `print_n("Anita", 1000)` it doesn't work out. Thank you for the explanation, now I know I should try lambda next time. – JimBigMac Jul 22 '21 at 16:48
  • My example actually won't work because you're passing an argument to `f`, so try `do_n(lambda x: print(x), 5)`. The lambda isn't important, it could be `def foo(x): print(x);` then call it with `do_n(foo, 5)` if you're more comfortable with that. The important thing is that the first argument is a function, not a string. `"Anita"()` is not going to work -- you can't call strings as functions. – ggorlen Jul 22 '21 at 16:51

2 Answers2

0

do_n(f, n)'s first argument is a function, not a string. You can either provide a lambda or normal def function as described in Passing a function into another function:

>>> def do_n(f, n):
...     if n <= 0:
...           return
...     f(n)
...     do_n(f, n-1)
...
>>> do_n(lambda x: print(x), 5)
5
4
3
2
1
>>> def do_stuff(x): print(x)
...
>>> do_n(do_stuff, 3)
3
2
1

As I mentioned in the comments, this is a misapplication of recursion (at least in a non-functional language like Python) -- you can blow the stack if you want to run a function more than ~1000 times (in CPython), creating a security risk for your app. And it's just easier to write the code as a loop:

>>> def do_n(f, n):
...     for i in range(n, 0, -1): f(i)
...
>>> do_n(lambda x: print(x), 5)
5
4
3
2
1
ggorlen
  • 44,755
  • 7
  • 76
  • 106
0

ggorlen's answer is 99% correct, but the question didn't say to pass n into the function and his is a little hard to read for a beginner (required knowledge of lambdas and one-line loops).

Here's my solution:

def do_n(f, n):
  if n > 0:  # stopping condition to prevent looping forever
    f()  # trigger the function
    do_n(f, n-1)  # recourse, decrement n to eventually trigger stopping condition

Here's an example use

def test_f():
  print('test_f triggered')

do_n(test_f, 3)
stoddabr
  • 36
  • 3