Search code examples
pythonpython-3.xrecursionfactorial

Error in Factorial Program in Python


When I execute the below code in Python 3, it's gives me below error. Could some one explain me what is wrong in the below code.

I know how to write a Factorial Program using simple function. But I would like to understand what is wrong in the below code.

class Factorial:
    def __init__(self):
        self.n=1
    def fact(self,n):    
        if self.n >= 1:
            return ((self.n) * (self.fact(n - 1)))
        else:
            return 1
a=Factorial()
print("4! =", a.fact(4))

Error:

RecursionError: maximum recursion depth exceeded in comparison

Solution

  • You never alter self.n, so it'll always be greater or equal to 1. You created an endless loop. It's set to 1 in __init__ so self.n >= 1 is true each time you test.

    You should not use a local variable and a parameter to track the current state of the factorial function. Pick one or the other.

    Without a parameter:

    class Factorial:
        def __init__(self, n):
            self.n = n
        def fact(self):
            n = self.n
            if n >= 1:
                self.n -= 1
                return n * self.fact()
            else:
                return 1
    

    Note that you now pass the initial value of n to the class, to create an instance:

    >>> f = Factorial(4)
    >>> f.fact()
    24
    >>> f.n
    0
    

    This isn't all that useful, because now the instance has n set to 0. Unless you assign something different to that attribute, calling f.fact() again will only produce 1 now.

    This is not really a problem that needs to be solved with a class. If you pass the initial value of n is as a pramater, you don't need an instance to track the state and you can just use a normal function:

    def fact(n):
        if n >= 1:
            return n * fact(n - 1)
        else:
            return 1
    

    The fact() function can be called as often as needed, with different values for n:

    >>> fact(4)
    24
    >>> fact(8)
    40320