-1

I'm fairly new to Python. Here, I'm creating a class to represent a blob-like structure. However, my code yields the following error:

TypeError: add() takes 3 positional arguments but 4 were given

class Blob:
    mass = 0
    xvals = []
    yvals = []
    correlationVal = 0

    def __init__(self):
        Blob.mass = 0
        Blob.correlationVal = 0

    def add(x, y, newCorrel):
        Blob.correlationVal = computeCorrelation(newCorrel)
        Blob.mass += 1
        Blob.xvals.append(x)
        Blob.yvals.append(y)

    def computeCorrelation(newCorrel):
        prevCorrel = Blob.correlationVal*Blob.mass
        updatedCorrel = (prevCorrel + newCorrel)/(Blob.mass + 1)
        return updatedCorrel

if __name__ == "__main__":

    test1 = Blob()
    print(test1.mass)
    test1.add(0, 0, 12)
    print(test1.mass)
    print(test1.correlationVal)
    test1.add(0, 1, 10)
    print(test1.mass)
    print(test1.correlationVal)
    test1.add(1, 1, 11)
    print(test1.mass)
    print(test1.correlationVal)
    print(test1.xvals)
    print(test1.yvals)

What am I doing wrong here, and how am I giving 4 inputs, when I supply 3?

Note: The error results from the "test1.add(0, 0, 12)" line.

depperm
  • 10,606
  • 4
  • 43
  • 67
  • 6
    your methods should accept self as the first parameter.. ie def add(self, x, y, newCorrel): – Alan Kavanagh Jul 19 '16 at 14:42
  • Possible duplicate of [What is the purpose of self in Python?](http://stackoverflow.com/questions/2709821/what-is-the-purpose-of-self-in-python) – Łukasz Rogalski Jul 19 '16 at 14:51
  • You should spend some time reading the [Classes section in the Tutorial](https://docs.python.org/3/tutorial/classes.html#classes) - you may have to revisit it a number of times: 9.1) Names and Objects and 9.2) Scopes and Namespaces subsections are pretty important to understand. If an attribute is intended to be an *instance* attribute ```self``` is typically used for the name of the instance and it is always the first argument passed to an instance method. – wwii Jul 19 '16 at 14:55

3 Answers3

4

Your instance methods are missing the self reference:

def computeCorrelation(self, newCorrel)
#                       ^

def add(self, x, y, newCorrel)
#        ^

The first parameter passed by an instance method is a reference to that instance of the class. So your add method should take 4 arguments but you will only be required to pass 3 when the method is called from an instance of the class. Python passes the reference to that instance for you.


More so, you are referencing your attributes from the class itself as Blob.some_attribute, you should instead use self:

def __init__(self):
    self.mass = 0
    self.correlationVal = 0

This modifies those attributes only on that instance of the class which is what you intend with __init__. The same should apply to the other methods.

Moses Koledoye
  • 77,341
  • 8
  • 133
  • 139
  • Additionally, the methods should refer to the instance `self` rather than the class `Blob`. The first line of `__init__(self)` would then look like: `self.mass = 0` – Aaron Jul 19 '16 at 14:45
  • I see. Thanks everyone for the feedback! –  Jul 19 '16 at 14:51
1

in a class, the first argument of a function is self. When in your main, you call test1.add(0, 0, 12), python call test1.add(test1,0, 0, 12), so now he has 4 argument.

class Blob:
    mass = 0
    xvals = []
    yvals = []
    correlationVal = 0

def __init__(self):
    self.mass = 0
    self.correlationVal = 0

def add(self,x, y, newCorrel):
    self.correlationVal = computeCorrelation(self,newCorrel)
    self.mass += 1
    self.xvals.append(x)
    self.yvals.append(y)
pwnsauce
  • 416
  • 4
  • 14
0

The first argument to a Python class method needs to be self i.e. def add(self, x, y, newCorrel): instead of def add(x, y, newCorrel):.

Self is implicitly passed to class instance methods when they are called, hence why 4 arguments are being passed instead of just the 3 you explicitly pass.

N.B. Non-instance methods (static methods) don't require self as their first parameter. See here for more details.

Mark
  • 768
  • 3
  • 7
  • 23