Wrong number of arguments when a calling function from class in Python - python

I'm trying to write an implementation of a genetic algorithm in python. It says there I am calling it with two arguments when only one is allowed, but I'm sure I'm not.
Here is the relevant code:
class GA:
def __init__(self, best, pops=100, mchance=.07, ps=-1):
import random as r
self.pop = [[] for _ in range(pops)]
if ps == -1:
ps = len(best)
for x in range(len(self.pop)): #Creates array of random characters
for a in range(ps):
self.pop[x].append(str(unichr(r.randint(65,122))))
def mutate(array):
if r.random() <= mchance:
if r.randint(0,1) == 0:
self.pop[r.randint(0, pops)][r.randint(0, ps)] +=1
else:
self.pop[r.randint(0, pops)][r.randint(0, ps)] -=1
This is the code when I initialize and call from the class:
a = GA("Hello",10,5)
a.mutate(a.pop)
which returns the following error from IDLE:
TypeError: mutate() takes exactly 1 argument (2 given)
How can I fix this?

Methods of a class are automatically passed the instance of the class as their first argument (it's named self by convention):
def mutate(self, array):

Related

How can I ensure that a function is "defined" in Python?

Trying to learn python as a java programmer. I would really appreciate some insight into why my program is telling me that my "isPrime" function isn't defined, especially with the use of 'self.'
import math
class Problem10:
def sumOfPrimesX(self, number):
sum = 0
for i in range(0, number):
if isPrime(i):
sum += i
return sum
def isPrime(self, x):
for n in range(0, math.floor(x/2)):
if x % n == 0:
return False
return True
print(sumOfPrimesX(input()))
all functions need it as their first parameter in a python program
No, only the instance methods, the methods related to a specific instance of a class. A simple function can need to parameter.
And you won't see the parameter self filled with the classic way of calling it, if you call the method on a instance it'll be filled by it
p = Problem10()
p.sumOfPrimesX(int(input("Give a value"))) # call on instance, one paramater given
# same as
Problem10.sumOfPrimesX(Problem10(), int(input("Give a value")))
# call on class itself, need to pass an instance as first to fill 'self
Also you need to wrap the input in an int, also start the loop at 2
p = Problem10()
print(p.sumOfPrimesX(int(input("Give a value"))))
class Problem10:
def isPrime(self, x):
for n in range(2, math.floor(x / 2)):
if x % n == 0:
return False
return True
The issue is both isPrime and sumofPrimesX are methods of the class Problem10.
Try the following:
import math
class Problem10:
def sumOfPrimesX(self, number):
sum = 0
for i in range(0, number):
if self.isPrime(i):
sum += i
return sum
def isPrime(self, x):
for n in range(0, math.floor(x/2)):
if x % n == 0:
return False
return True
pv = Problem10()
print(pv.sumOfPrimesX(input()))

How to run a class function

I was trying to write some code that would take in the number of sides of a polygon and a user can just randomly input the length of each side
I wanted to make a separate class polygon and the following was my code:
#numSides=int(input(Number of sides))
class polygon(object):
def __init__(self,x): #useless code
self.x=x #useless code
self.x=[] #useless code
def __inputSides__(self):
#counter=0
#for i in range(x):
# counter=counter+1
numSides=int(input("number of sides"))
list_=[]
for i in range(numSides):
length=float(input("length"))
list_.append(length)
return list_
def __dispSides__(self,list_):
for i in list_:
print("side length",i)
stone= polygon()
stone.__dispSides__(4)
but then in the second to last line i was getting an error that said :
Traceback (most recent call last):
File "python", line 23, in <module>
TypeError: __init__() missing 1 required positional argument: 'x'
I was wondering how can i fix this and why I am getting this error?
thanks!
A proper class wouldn't prompt the user for the side lengths; the code that creates a Polygon should be responsible for the I/O and simply pass the values as arguments to Polygon.__init__.
class Polygon(object):
def __init__(self, sides):
self.sides = sides
def display_sides(self):
for s in self.sides:
print("side length", s)
numSides = int(input("number of sides"))
sides = []
for i in range(numSides):
length = float(input("length"))
sides.append(length)
s = Polygon(sides)
s.display_sides()
This is a quite straight-forward question.
Whenever you call your polygon class its __init__ function is run automatically. You've set this initiation function to require 2 arguments: self & x. Whenever you initiate your class you will thus have to provide your class with an x argument.
Meaning instead of declaring stone = polygon(), you should declare something like stone = polygon(x).
Furthermore, your reason for passing and initiating the x argument is unclear since no matter what value x is given, it is never passed along to any method within your class. This is because after declaring self.x = x, it is immediately overwritten to be an empty list by your self.x=[] declaration (leaving the actual x-argument unused).
In same code, I applied two fixes.Hope you wanted the same result.
class polygon(object):
def __init__(self,x=[]): #useless code
self.x=x
# force user to input numSide and length
numSides=int(input("number of sides"))
list_=[]
for i in range(numSides):
length=float(input("length"))
list_.append(length)
#finally list_ argument is a declaration so you have to define it(assign value)
def __dispSides__(self,list_=list_):
for i in list_:
print("side length",i)
stone= polygon()
stone.__dispSides__()
fix 1: __init__(self,x=[]): define x with declaration to set a default value
fix 2:
def __dispSides__(self,list_=list_):
here you declared a variabe list_ but actually you wanted to pass previous list_ value here(as it seems ) so do pass it a value.
Avoid Error: stone.__dispSides__(4)# passing a non-iterable will raise an error

How to repeat string without a function

I found a task where I am asked to implement some object that repeats a string n times but condition is that this something must not be a function. I have tried the following:
class str_repeat:
def __init__(self,x,y):
self.s = x * y
def __repr__(self):
return self.s
but this did not work.Some Hints would help a lot
Humm! str_repeat must be a callable.
What do you think of:
str_repeat = str.__mul__

Error while defining the class

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!
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.
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:
the instance (by default)
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])

Object Oriented example in Python

I know its dumb question but i am trying to grasp the concepts of OOP in Python. Suppose i want to write the program for factorial in Procedural form, i would do something like this
def factorial(n):
num = 1
while n >= 1:
num = num * n
n = n - 1
return num
f = factorial(3)
print f # 6
Now i want to rewrite the same factorial program in OO way. i am not getting how to write this same function using objects and classes.
class Factorial():
def fact(n):
num = 1
while n >= 1:
num = num * n
n = n - 1
return num
f = Factorial()
a = f.fact(3)
print a # TypeError: fact() takes exactly 1 argument (2 given)
I know this can be done more precisely in Functional way by using lambdas and other things, but i am learning the concepts of OOP. What i am doing wrong ?
When you are calling an instance method, by default the current object is passed as the first parameter to the function. In your case,
def fact(n):
when you call it like this
a = f.fact(3)
it will be actually treated like this
a = fact(f, 3)
The reason why the current object is passed is, to let the instance method make changes to the object. (Remember Python doesn't have any other keyword like this, like in some other languages).
But your function's signature doesn't match this (it expects only one parameter). That's why it is throwing
# TypeError: fact() takes exactly 1 argument (2 given)
To fix this, you have to change the signature to something like this
def fact(self, n):
Now, the self parameter will receive the current object being passed.
You forgot the self parameter:
class Factorial():
def fact(self,n): #Forgot the self parameter huh?
num = 1
while n >= 1:
num = num * n
n = n - 1
return num
I recommend you read these too:
explaining the self variable to a beginner
Python 'self' explained
Dive into Python - defining Classes
I would also recommend these article for reading:
An Introduction to Object-Oriented Concepts in Python, Part 1
Unfortunately I cannot put more that 2 links But I'm sure you'll find other 4 parts of these.

Categories