Salchem
Salchem

Reputation: 128

Simple but too many positional arguments for method call

  1. Would anyone explain why the TypeError is

    fib() takes 1 positional argument but 2 were given`

    when I'm only giving it ONE argument => self.fib(self.n - 1) !

  2. Also, while keeping the instantiation of the class, can you suggest your solution to fix this?

  3. I feel the "self" is being used too much, especially with the more methods I add. Can that be improved?

Just trying to wrap my head around some basics! All feedback is appreciated.

class math_func:
    def __init__(self, n: "int" = 6, output: "list" = []):
        self.n = n
        self.output = output

    def fib(self):
        print("Current output is:", self.output)
        if self.n == 0:
            return self.output
        else:
            if len(self.output) < 2:
                self.output.append(1)
                self.fib(self.n - 1)
            else:
                last = self.output[-1]
                second_last = self.output[-2]
                self.output.append(last + second_last)
                self.fib(self.n - 1)
            return self.output

first_func = math_func(n=9)
print(first_func.fib())

Upvotes: 3

Views: 33397

Answers (5)

user15566711
user15566711

Reputation: 11

A type error can mean many things. In this case it means that you have passed too many arguments into a function. It looks like you are calling self.fib with a parameter. You have defined it only with self as a parameter. From the way you have written your code, it seems that you think that you need to pass self as an argument. The truth is that it is an invisible parameter that is already passed when you call the function.

Do something like this:

class math_func:
        def __init__(self, '''...'''):
            #...
        def fib(self):
            #...
            self.n = self.n - 1
            self.fib()

or

class math_func:
        def __init__(self, '''...'''):
            #...
        def fib(self):
            #...
            self.fib2(self.n -1)
        def fib2(self, n: int):
            #...
            #same thing as fib with slight changes

or

class math_func:
    def __init__(self, '''...'''):
        #...
    def fib(self, n: int):
        #...
        self.fib(self.n - 1)
    def getN(self):
        return self.n

fib = math_func('''...''')
print(fib.fib(fib.getN())

Upvotes: 1

chenchuk
chenchuk

Reputation: 5742

When u first call fib() in

print(first_func.fib())

you pass no args except the implicit self. in the next call you pass 1 arg which makes it 2 (including the implicit self)

self.fib(self.n - 1)

This provides the TypeError: fib() takes 1 positional argument but 2 were given

about the Fibonacci, a simpler implementation :

def fib(n):
    if n==0 or n==1:
        return 1
    else:
        return (fib(n-1) + fib(n-2))

Upvotes: 1

P&#233;ter Le&#233;h
P&#233;ter Le&#233;h

Reputation: 2119

You need to include n as fib's agrument

def fib(self, n):
...

Also a little addition: If you define recursive functions you should consider using lru_cache decorator for performance improvement.

from functools import lru_cache

...

@lru_cache(500) # 500 is the cache size
def fib(self, n):
...

Upvotes: 0

Scott Hunter
Scott Hunter

Reputation: 49883

The first argument of a method is self, which refers to the object the method is being called on. If, as it appears, you wish to pass an argument (n, it looks like), you need to include that in the method's signature.

Upvotes: 3

ForceBru
ForceBru

Reputation: 44878

This function takes one argument self, but this line: self.fib(self.n - 1) attempts to pass 2: self and self.n - 1.

Upvotes: 1

Related Questions