{"id":"recursion-return-values","slug":"return-values","title":"Recursion that returns a value","text":"A recursive function can return a value, and that's where recursion gets useful. The classic example is the **factorial**. The factorial of 5, written 5!, is 5 * 4 * 3 * 2 * 1 = 120. Look closer and 5! is 5 * 4!, and 4! is 4 * 3!, and so on down to 1!, which is 1 (and 0! is 1 too). A definition that uses a smaller version of itself is exactly what a recursive function needs:\n\n```python\ndef factorial(n):\n    if n <= 1:\n        return 1\n    return n * factorial(n - 1)\n\n\nfor i in range(1, 6):\n    print(f\"{i}! = {factorial(i)}\")\n```\n\n```output\n1! = 1\n2! = 2\n3! = 6\n4! = 24\n5! = 120\n```\n\n`factorial(4)` can't finish before it knows `factorial(3)`, which waits for `factorial(2)`, which waits for `factorial(1)`. That one is the base case and returns 1 right away. Then the answers travel back the way they came:\n\n```text\nfactorial(4) = 4 * factorial(3)\n             = 4 * 3 * factorial(2)\n             = 4 * 3 * 2 * factorial(1)\n             = 4 * 3 * 2 * 1\n             = 24\n```\n\n### Watching the calls\n\nA `print` when a call starts and another before it returns show the order of events. This function adds up the digits of a number: the last digit is `n % 10`, and the number without it is `n // 10`. A number below 10 is a single digit, the base case:\n\n```python\ndef digit_sum(n):\n    print(\"start\", n)\n    if n < 10:\n        result = n\n    else:\n        result = n % 10 + digit_sum(n // 10)\n    print(\"return\", result, \"for\", n)\n    return result\n\n\nprint(digit_sum(472))\n```\n\n```output\nstart 472\nstart 47\nstart 4\nreturn 4 for 4\nreturn 11 for 47\nreturn 13 for 472\n13\n```\n\nThe call for 472 started first and finished last. Python keeps the unfinished calls waiting on the **call stack**, the newest on top. When the call on top returns, the one below it carries on from where it stopped, with the value it was waiting for.\n\n### The missing return\n\nA common mistake is to work out the result of the recursive call but forget to return it. A function that ends without `return` returns `None`, and the call waiting for an answer gets `None`:\n\n```python\ndef factorial(n):\n    if n <= 1:\n        return 1\n    n * factorial(n - 1)\n\n\nprint(factorial(3))\n```\n\n```crash\nTraceback (most recent call last):\n  File \"main.py\", line 7, in <module>\n    print(factorial(3))\n          ~~~~~~~~~^^^\n  File \"main.py\", line 4, in factorial\n    n * factorial(n - 1)\n    ~~^~~~~~~~~~~~~~~~~~\nTypeError: unsupported operand type(s) for *: 'int' and 'NoneType'\n```\n\n`factorial(2)` worked out 2 * 1 but threw the result away and returned `None`, so `factorial(3)` tried to calculate 3 * `None`. The fix is `return n * factorial(n - 1)`.\n","task":"2 to the power of 5 is 2 * 2 * 2 * 2 * 2, which is 2 times 2 to the power of 4. Fill in the blank so the function calculates powers recursively. The program should print:\n\n```\n32\n27\n1\n```\n","kind":"fill","seed":"def power(base, exponent):\n    if exponent == 0:\n        return 1\n    return base * power(base, [[exponent - 1]])\n\n\nprint(power(2, 5))\nprint(power(3, 3))\nprint(power(7, 0))\n","solution":"def power(base, exponent):\n    if exponent == 0:\n        return 1\n    return base * power(base, exponent - 1)\n\n\nprint(power(2, 5))\nprint(power(3, 3))\nprint(power(7, 0))\n","hints":["The recursive call should work on a smaller problem, one that is closer to the base case `exponent == 0`.","The power one smaller is `power(base, exponent - 1)`."],"tests":[{"name":"Output","stdin":"","expect":"32\n27\n1","hidden":false}],"require":[],"forbid":[],"more":[{"task":"What does this program print? Type each line it prints.\n","kind":"predict","seed":"def total(n):\n    if n == 0:\n        return 0\n    result = n + total(n - 1)\n    print(n, result)\n    return result\n\n\nprint(total(3))\n","solution":"def total(n):\n    if n == 0:\n        return 0\n    result = n + total(n - 1)\n    print(n, result)\n    return result\n\n\nprint(total(3))\n","hints":["The `print` inside the function comes after the recursive call, so a call prints only after the calls it made have returned.","`total(1)` is the first to print: it gets 0 from `total(0)` and prints `1 1`.","Then `total(2)` and `total(3)` print, and last the main program prints what `total(3)` returned."],"tests":[{"name":"Output","stdin":"","expect":"1 1\n2 3\n3 6\n6","hidden":false}],"require":[],"forbid":[],"lines":["1 1","2 3","3 6","6"]},{"task":"Multiplying is adding the same number many times: 6 * 4 is 6 + 6 + 6 + 6, which is 6 + (6 * 3). Write a recursive function `multiply(a, b)` that returns `a` times `b` using only addition and recursion. `b` is never negative.\n\nFor example, this call:\n\n```python\nprint(multiply(6, 4))\n```\n\nprints:\n\n```\n24\n```\n","kind":"code","seed":"def multiply(a, b):\n    pass\n\n\nif __name__ == \"__main__\":\n    print(multiply(6, 4))\n","solution":"def multiply(a, b):\n    if b == 0:\n        return 0\n    return a + multiply(a, b - 1)\n\n\nif __name__ == \"__main__\":\n    print(multiply(6, 4))\n","hints":["Start with the base case: anything times 0 is 0.","Otherwise, `a` times `b` is `a` plus `a` times `b - 1`.","Don't forget the `return` in front of `a + multiply(a, b - 1)`."],"tests":[{"name":"print(multiply(6, 4))","stdin":"","call":"print(multiply(6, 4))\n","expect":"24","hidden":false},{"name":"multiply(5, 0)","stdin":"","call":"multiply(5, 0)\n","expect":"0","hidden":true,"returns":true},{"name":"multiply(-3, 5)","stdin":"","call":"multiply(-3, 5)\n","expect":"-15","hidden":true,"returns":true},{"name":"multiply(12, 1)","stdin":"","call":"multiply(12, 1)\n","expect":"12","hidden":true,"returns":true}],"require":[{"pattern":"def multiply\\b[^\\n]*\\n(?:[ \\t]*\\n|[ \\t]+[^\\n]*\\n)*?[ \\t]+[^\\n]*\\bmultiply\\s*\\(","message":"Make `multiply` call itself inside its own body."}],"forbid":[{"pattern":"\\*","message":"Multiply with addition and recursion, without `*`."},{"pattern":"\\b(?:while|for)\\b","message":"Use recursion instead of a loop."}]}]}