-1

The above code works but the second code shows typerror: print(a.factorial(a, 5))TypeError: factorial() takes 2 positional arguments but 3 were given:

class Factorial:
def factorial(self, num):
     if num == 0:
        return 1
     if num ==1:
        return 1
     else:
        return num * self.factorial(self, num-1)

def main():
a = Factorial()
print(Factorial.factorial(Factorial, 5))
main()

The second code is as follows:

class Factorial:
def factorial(self, num):
     if num == 0:
        return 1
     if num ==1:
        return 1
     else:
        return num * self.factorial(self, num-1)

def main():
a = Factorial()
print(a.factorial(a, 5))
main()
azim
  • 1

2 Answers2

0

self argument is the same as the object on which you call the function. You don't need to provide it again as the first explicit argument - a.factorial(5) will work.

matszwecja
  • 6,357
  • 2
  • 10
  • 17
0

When you call a method on an instance (rather than on the class), the instance is automatically passed as the self argument. You don't pass it yourself.

So this:

Factorial.factorial(a, 5)

is the same as this:

a.factorial(5)

and this:

a.factorial(a, 5)

is the same as this:

Factorial.factorial(a, a, 5)  # too many arguments!

Note that your function definition is also confused about the difference between instances and classes. Given that this is an instance method, it should expect self to be an instance of Factorial, not the Factorial class itself:

def factorial(self, num):
     if num == 0:
        return 1
     if num ==1:
        return 1
     else:
        return num * self.factorial(num-1)  # no extra "self" arg

Once you make this fix, calling this method as Factorial.factorial(Factorial, 5) will not work, because that's not a valid way to call an instance method (it "works" in your current code because of that self bug that prevents it from working as an actual instance method).

To define it as a class method (where the first argument is the class, not an instance), you'd do:

@classmethod
def factorial(cls, num):
     if num == 0:
        return 1
     if num ==1:
        return 1
     else:
        return num * cls.factorial(num-1)

and then would call it as Factorial.factorial(5).

Samwise
  • 68,105
  • 3
  • 30
  • 44
  • But when I use a.factorial(5). Why does it show this error: TypeError: factorial() takes 2 positional arguments but 3 were given? – azim Mar 10 '22 at 15:37
  • I assume that's happening in the recursive call, due to the `self.factorial(self, num-1)` bug. Remove the extra `self` from that call and it'll work (and then your `Factorial.factorial(Factorial, 5)` one will break, but that one should never have worked). – Samwise Mar 10 '22 at 15:41