0

I'm new to "class" in python. I created a following class in python. The objective of this class is, if pass a list of numbers, if the sum of 2 numbers is 50, it will return me the position of those number in the list.

from itertools import  combinations
class numList(object):

    def findComb(self):
        a = []
        b = []
        for comb in combinations(self, 2):
            a.append(comb)
        for i in range(1, len(a)):
            if sum(a[i]) == 50:
                b.append(a[i])
        return b

c = numList()
c.findComb([10,20,10,40,50,60,70])

But I'm getting the following error, when I'm trying to execute it:

TypeError: findComb() takes 1 positional argument but 2 were given

Please let me know where I'm making the mistake.

Thank you!

Beta
  • 1,638
  • 5
  • 33
  • 67
  • 1
    what is `combinations` ? – Ankush Rathi Jul 20 '17 at 12:34
  • @AnkushRathi: yes..it combination. I update the code. – Beta Jul 20 '17 at 12:39
  • Possible duplicate of [TypeError: method() takes 1 positional argument but 2 were given](https://stackoverflow.com/questions/23944657/typeerror-method-takes-1-positional-argument-but-2-were-given) –  Jul 20 '17 at 12:41

2 Answers2

1

By design, the first argument of every class function is always a reference to the current instance of the class (always named self).

You are calling findComb with an additional argument when you defined it to only take one (self).

def findComb(self):
    ...

should be

def findComb(self, myList):
    ...

All your references to self in your function implementation will need to be updated accordingly to use myList.

ILostMySpoon
  • 2,399
  • 2
  • 19
  • 25
  • 1
    I would say this is not by convention but by design. The fact that it is called `self` is a convention. –  Jul 20 '17 at 12:37
  • @IListMySpoon: I got it now. Thanks! But if I'm adding a new variable within the method of a class, do I've to start with "self"? E.g. here "self.myList". If not, why not? – Beta Jul 20 '17 at 12:42
  • 1
    That depends on whether you plan on using that new variable throughout the rest of the class or just within the scope of the method. If the latter, then no. If the former, yes. – ILostMySpoon Jul 20 '17 at 12:48
  • perfect...Now things are completely clear! Thanks a lot ILostMySpoon! – Beta Jul 20 '17 at 12:51
1

Each method within a class takes as positional input the instance of the class itself, unless you add the @staticmethod decorator.

So you are receiving the error because the function findComb receives as input:

  1. the instance (by default)
  2. the list you passed

This should clarify the error you are receiving.

You can fix it in two ways:

Assigning the input list to an attribute of the class and then use the attribute in the function:

class numList(object):

    def __init__(self, inp_list):
        self.input = inp_list

    def findComb(self):
        a = []
        b = []
        for comb in combinations(self.input, 2):
            a.append(comb)
        for i in range(1, len(a)):
            if sum(a[i]) == 50:
                b.append(a[i])
        return b

c = numList([10,20,10,40,50,60,70])
c.findComb()

Define findComb as a staticmethod, so that it would only use the argument you are passing (without using the instance as first argument):

class numList(object):

    @staticmethod
    def findComb(inp_list):
        a = []
        b = []
        for comb in combinations(inp_list, 2):
            a.append(comb)
        for i in range(1, len(a)):
            if sum(a[i]) == 50:
                b.append(a[i])
        return b

c = numList()
c.findComb([10,20,10,40,50,60,70])
FLab
  • 7,136
  • 5
  • 36
  • 69
  • I would say that, although this makes the error go away, it doesn't address the lack in understanding that the OP seems to have about the `self` argument. –  Jul 20 '17 at 12:39
  • @FLab: Thanks for your answer. But the issue here is there's not much difference between plain function and creating a class. I believe class makes more sense if we start with "self" (or any other variant name). Please let me know if I'm wrong. – Beta Jul 20 '17 at 12:45
  • Yes I agree that if this is all you plan to do with the class, probably a function is all you need. If instead you want to define multiple attributes and methods if a self-contained namespace, than the class is what you are looking for – FLab Jul 20 '17 at 12:55