Recursive Factorial Calculator RecursionError - python

This recursive factorial calculator runs fine all the way up to an input of 994 when I recieve this error: "RecursionError: maximum recursion depth exceeded in comparison". Can someone please explain what is meant by this? How can there be a maximum amount of recursions? Thanks in advance.
def factorial(x):
if( x == 0):
return 1
else:
return x * factorial(x - 1)
while True:
u_input = input("")
print(factorial(int(u_input)))
def calc_factorial(num):
num-=1
fact_total = 1
while num > 0:
fact_total *= num
num-=1
return(fact_total)
EDIT:
I understand that recursion is re-using a function from within that function as a loop but I do not understand what recursion depth is and would like that explained. I could not tell from the answers to the other question. Apologies for the confusion.

Recursive calls are just like any other function calls, and function calls use memory to keep track of the state inside each function. You will notice that you get a very long traceback showing all the nested function calls that are on the stack. Since memory is finite, recursion depth (the number of nested function calls) is inherently limited even without python's enforced limit.

The error means what it says: Python limits the depth of how many recursive calls you can make. The default is 1000, which was chosen as a number that means you most likely have infinite recursion somewhere. Since no computer can keep track of an infinite amount of recursive calls (and such a program would never finish anyway), halting with this error message is seen as preferable to recurring as deeply as the computer can handle, which eventually results in a stack overflow.
You can change this limit if you wish with sys.setrecursionlimit, but the best way to avoid this issue is to change your program to work iteratively instead of recursively. Fortunately, this is easy for a factorial calculation:
def factorial(x):
result = 1
for num in range(1, x+1):
result *= num
return result

There are built in Function with Math library, It is improved algorithm to get the value of factorial quickly, So when we are writing the recursive algorithm to get the value for factorial, there will be a recursive limit. So If we use the built in library, then we can escape from that problem.
import math
math.factorial(5)
Answer : 120

Related

Why maximum recursion depth exceeded is not (always) happening in python list comprehension?

I noticed that "maximum recursion depth exceeded" does not happen when a basic recursive function is used inside a list-comprehension, while it does when used outside of it. I would like to understand why, to get a better understanding of how list-comprehension works and then use it efficiently.
I tried it with a basic fibonacci function applied on a range.
from functools import lru_cache
#lru_cache(maxsize = 2048)
def fib(n): return n if n<2 else fib(n-1)+fib(n-2)
# The following will be calculated (and 5000 can be replaced by much bigger integer)
fb = [fib(n)for n in range(5000)]
print(fb[-1])
# but next line:
print(fib(500))
# will cause a RecursionError: maximum recursion depth exceeded
# And will need this to be enabled:
import sys
sys.setrecursionlimit(1024)
print(fib(500))
Every time the comprehension evaluates fib(n), it saves that result in the cache. By the time it gets to fib(500), fib(499) and fib(498) are already cached, so they don’t run again. The stack goes 1 call of fib deep.
When you run fib(500) immediately, the first thing it evaluates is fib(499), which isn’t cached and evaluates fib(498), which isn’t cached and evaluates fib(497)… all the way down to fib(1). The stack goes 499 calls of fib deep.
You should be able to see the same thing by running:
print(fib(250))
print(fib(500))

When Is Recursion Useful? [duplicate]

This question already has answers here:
Recursion or Iteration?
(31 answers)
Closed 5 years ago.
I am relatively new to python and have recently learned about recursion. When tasked to find the factorial of a number, I used this:
def factorial(n):
product = 1
for z in xrange(1,n+1):
product *= z
return product
if __name__ == "__main__":
n = int(raw_input().strip())
result = factorial(n)
print result
Then, because the task was to use recursion, I created a solution that used recursion:
def factorial(n):
if n == 1:
current = 1
else:
current = n*(factorial(n-1))
return current
if __name__ == "__main__":
n = int(raw_input().strip())
result = factorial(n)
print result
Both seem to produce the same result. My question is why would I ever use recursion, if I could use a for loop instead? Are there situations where I cannot just create for loops instead of using recursion?
For every solution that you found with recursion there are a solution iterative, because you can for example simulate the recursion using an stack.
The example of Factorial use a type of recursion named Tail Recursion an this cases have an easy way to implement iterative, but in this case recursion solution is more similar to the mathematical definition. However there are other problems that found an iterative solution is difficult and is more powerful and more expressive use recursive solution. For example the problem of Tower of Hanoi see this question for more informationTower of Hanoi: Recursive Algorithm, the solution of this problem iterative is very tedious and finally have to simulate a recursion.
There are problems like Fibonacci sequence that the definition is recursive an is easy to generate a solution recursive
def fibonacci(n):
if ((n==1) or (n==2)):
return 1
else (n>2):
return fibonacci(n-2) + fibonacci(n-1)
This solution is straight forward, but calculate many times unnecessarily the fibonacci of n-2 see the image bellow to better understanding the fibonacci(7)
So you can see the recursion like syntactic sugar some time, but depends of what you want, you need to decide if use or no. When you program in Low-level programming language the recursion is not used, when you program a microprocessor is a big error, but on others case is better use a recursive solutions for better understanding of your code.
hope this help, but you need go deep reading books.

Is it possible to code this formula using recursion

I am trying to code the following formula using recursion.
I was thinking of doing it in different ways, but since the expression is recursive, in my opinion recursion is the way to go.
I know how to apply recursion to simple problems, but in this particular case my understanding seems to be wrong. I tried to code it in python, but the code failed with the message
RuntimeError: maximum recursion depth exceeded
Therefore, I would like to ask what is the best way to code this expression and whether recursion is possible at all.
The python code I tried is:
def coeff(l,m,m0,m1):
if l==0 and m==0:
return 1.
elif l==1 and m==0:
return -(m1+m0)/(m1-m0)
elif l==1 and m==1 :
return 1./(m1-m0)
elif m<0 or m>l:
return 0.
else:
return -((l+1.)*(m1-m0))/((2.*l+1.)*(m1+m0))* \
((2.*l+1.)*(m+1.)/((l+1.)*(2.*m+3.)*(m1-m0))*coeff(l,m+1,m0,m1) +\
(2.*l+1.)*m/((l+1.)*(2.*m-1.)*(m1-m0))*coeff(l,m-1,m0,m1) -\
l/(l+1.)*coeff(l-1,m,m0,m1))
where x=m1-m0 and y=m1+m0. In my code I tried to express the a(l,m) coefficient as a function of the others and code the recursion on the basis of it.
A naive recursive implementation here, obviously recalculates the same things over and over. It probably pays to store things previously calculated. This can be done either by explicitly filling out a table, or implicitly by memoization (I therefore don't really agree with the comments taking about "recursion vs. dynamic programming").
E.g., using this decorator,
class memoize(dict):
def __init__(self, func):
self.func = func
def __call__(self, *args):
return self[args]
def __missing__(self, key):
result = self[key] = self.func(*key)
return result
You could write it as
#memoize
def calc_a(l, m, x, y):
if l == 0 and m == 0:
return 1
# Rest of formula goes here.
Note that the same link contains a version that caches between invocations.
There are a number of tradeoffs between (memoized) recursion and explicit table building:
Recursion is typically more limited in the number of invocations (which might or might not be an issue in your case - you seem to have an infinite recursion problem in your original code).
Memoized recursion is (arguably) simpler to implement than explicit table building with a loop.

My heap is working too slow

So here is my code for min-heap. It's a part of my homework:
def heapify(i):
global end,a
l=2*i+1
if l>end:
return None
r=2*i+2
minarg=i
if a[i]>a[l]:
minarg=l
if r<=end:
if a[minarg]>a[r]: minarg=r
if a[i]==a[minarg]:
return None
else:
a[i],a[minarg]=a[minarg], a[i]
heapify(minarg)
def buildHeap(start):
global end,a
if start*2+1>end:
return None
buildHeap(start*2+1)
buildHeap(start*2+2)
heapify(start)
It should be working, but I get time limit exceeded for large testcases. Am I doing something wrong?
Function calls in Python take time, recursion takes space.
To save the time of a recursion one usually transforms it into a loop. This usually requires to use a specialized "memory management" of the date to work on to safe space. You did that already (with... ehem... global variables) using an array/list.
If that is your homework, go ahead -- doable, but non-trivial.

Fibonacci numbers not getting printed beyond F(996)

I wrote this small snippet to calculate Fibonacci numbers. It works well for numbers up to 996 and from 997 a trace back is being printed. I can't figure out what the problem is. Does it has something to do with maximum_recursion_count?
def fib(n):
if n==0:
return 0
elif n==1:
return 1
else:
return fib(n-1)+n
Probably. Take a look at sys.getrecursionlimit(). The default value is 1000, which sounds like it just might be causing the problem you're seeing: once there are 1000 frames on the stack (i.e. slightly less than 1000 recursive function calls), you'll get an error on the next function call.
You can set the recursion limit to a larger value using sys.setrecursionlimit, but there is a maximum value which is platform-dependent (which means you might have to figure out what it is by trial and error).
There is a wonderful Fibonnaci function implementation here that doesn't use recursion.
Your code may come up against stack call limits.
You say "It works well for numbers up to 996" ... No, it doesn't, it generates the wrong results. The last line should be:
return fib(n - 1) + fib(n - 2)
You have reached the maxmimum recursion depth limit. As far as I know its default value is about 1000. You can change it sys.setrecursionlimit() and see it using sys.getrecursionlimit()

Categories