Python object creation failed - python

I am newbie in python so it may sound a stupid question.
Scenario:
I have a cluster class, while creating its instance i am supplying it with two default value which are nothing but coordinates for the centroid which will be of ty
from checkbox.lib.text import split
class point:
x=0
y=0
def toString(self):
return (self.x+ ':'+self.y)
def __init__(self,a,b):
self.x=a
self.y=b
class cluster:
points=[]
centroid= point
def __init__(self,a,b):
centroid= point(a,b)
def kMeans(lis,k):
length=len(lis)
clusters=[]
for i in range(k):
clusters.append(cluster(2*i,2*i))
print clusters[i].centroid.toString()
for pt in lis:
min=10
centroidNum=0
for i in range(k):
dist=(abs(int(pt.x)- int(clusters[i].centroid.x))) +abs((int(pt.y) - int(clusters[i].centroid.y)))
if dist<min:
min=dist
centroidNum=i
clusters[centroidNum].points.append(pt)
for cl in clusters:
print "Clusters"
for pt in cl.points:
print pt.toString()
def readValues():
try:
fileHandler = open('/home/sean/input/k_means.txt', 'r')
for line in fileHandler:
tokens=split(line,",")
if len(tokens) == 2:
tempObj=point(tokens[0].strip(),tokens[1].strip())
list.append(tempObj)
except IOError:
print "File doesn't exist"
if __name__ == '__main__':
list=[]
readValues();
kMeans(list,3)
I am tring to assign value to centroid thus passing in constructor. But i am getting below error:
unbound method toString() must be called with point instance as first argument (got nothing instead)
I want the centroid to be a point so that i can access in rest of the program.
Please help me how to assign value to centroid
input file has points in form
1,2
3,5
4,3

You are not giving us the full code for your problem.
Couple of general Python syntax issues first:
Class names should be CamelCase (class Point and class Cluster)
Function names should be lower case (to_string(self): )
You've also got some random semicolons around there from Java(script) syntax I'm guessing.
It looks like the line
centroid = Point
is creating an unbound instance of Point (should be centroid = Point() but you'd also need to pass 2 arguments as a and b).
Try removing this line so the Point() instance is created in the __init__ function of Cluster.
Edit 1:
Here's your problem;
In your __init__ of Cluster you are setting a variable centroid but not applying it to the instance (self). As a result, it is trying to use centroid = Point you are setting within the instance, which is unbound.
Try this setup:
class cluster:
points=[]
def __init__(self,a,b):
self.centroid = point(a,b)
I've got rid of the unnecessary (and wrong) initialisation of centroid= point and am now setting centroid as an attribute to the class in the __init__ method.

The error
unbound method toString() must be called with point instance as first
argument
usually occurs when you call an instance method of class on the class directly and instead of an instance of the object.
Example:
class foo(object):
def bar(self):
print 'bar'
print foo.bar()
Traceback (most recent call last):
File "out", line 6, in <module>
print foo.bar()
TypeError: unbound method bar() must be called with foo instance as first argument (got nothing instead)
So you have to call
foo().bar()

Related

TypeError: __init__() missing 1 required positional argument: 'lists'

I created a class, something like below -
class child:
def __init__(self,lists):
self.myList = lists
def find_mean(self):
mean=np.mean(self.myList)
return mean
and when I create an onject something like below -
obj=child()
it gives the error -
TypeError: __init__() missing 1 required positional argument: 'lists'
if I create object like below then it works well -
obj=child([44,22,55)
or If I create the class like below -
class child:
def find_mean(self,myList):
mean=np.mean(myList)
return mean
and then I create the object like below -
obj=child()
then also it works well, however I need to make it in the way I explained in the very begining. Can you please help me understand this context?
In the first example, the __init__ method expects two parameters:
self is automatically filled in by Python.
lists is a parameter which you must give it. It will try to assign this value to a new variable called self.myList, and it won't know what value it is supposed to use if you don't give it one.
In the second example, you have not written an __init__ method. This means that Python creates its own default __init__ function which will not require any parameters. However, the find_mean method now requires you to give it a parameter instead.
When you say you want to create it in the way you explained at the beginning, this is actually impossible: the class requires a value, and you are not giving it one.
Therefore, it is hard for me to tell what you really want to do. However, one option might be that you want to create the class earlier, and then add a list to it later on. In this case, the code would look like this:
import numpy as np
class Child:
def __init__(self, lists=None):
self.myList = lists
def find_mean(self):
if self.myList is None:
return np.nan
mean = np.mean(self.myList)
return mean
This code allows you to create the object earlier, and add a list to it later. If you try to call find_mean without giving it a list, it will simply return nan:
child = Child()
print(child.find_mean()) # Returns `nan`
child.myList = [1, 2, 3]
print(child.find_mean()) # Returns `2`
the code you have at the top of your question defines a class called child, which has one attribute, lists, which is assigned at the time of instance creation in the __init__ method. This means that you must supply a list when creating an instance of child.
class child:
def __init__(self, lists):
self.myList = lists
def find_mean(self):
mean=np.mean(self.myList)
return mean
# works because a list is provided
obj = child([44,22,55])
# does not work because no list is given
obj = child() # TypeError
If you create the class like in your second example, __init__ is no longer being explicitly specified, and as such, the object has no attributes that must be assigned at instance creation:
class child:
def find_mean(self, myList):
mean=np.mean(myList)
return mean
# does not work because `child()` does not take any arguments
obj = child([44,22,55]) # TypeError
# works because no list is needed
obj = child()
The only way to both have the myList attribute, and not need to specify it at creation would be to assign a default value to it:
class child:
def find_mean(self,myList=None):
mean=np.mean(myList)
return mean
# now this will work
obj = child()
# as will this
obj = child([24, 35, 27])

'object' is not subscriptable in 2d python list

Message='SodokuGame' object is not subscriptable
Source=C:\Users\PC\Desktop\python\Soduku\Soduku\Soduku.py
StackTrace: File
"C:\Users\PC\Desktop\python\Soduku\Soduku\Soduku.py", line 31, in
fillArray
if currentArray[x][y].value == 0:
File "C:\Users\PC\Desktop\python\Soduku\Soduku\Soduku.py", line 110,
in init
game.fillArray(game.matrix, 0, 0, game.newPool) File "C:\Users\PC\Desktop\python\Soduku\Soduku\Soduku.py", line 113, in
Run()
I am trying my own project and ran into an issue. To begin I have my cell class. My goal is to test the data in the Cell and run code dependent on the results but on runtime I run into the error above.
class Cell:
value = 0
def __getitem__(self):
return self.value
def __setitem__(newVal, self):
self.value = newVal
This is how I defined and tried to add my list
class SodokuGame:
matrix = []
for i in range(9):
arr = []
for j in range(9):
arr.append(Cell())
matrix.append(arr)
def fillArray(currentArray, x, y, pool, self):
if currentArray[x][y].value == 0:
print("fillArray loop") #unimportant context code from here on
poolNum = randint(0, pool.length)
if testNumber(pool[poolNum]):
currentArray[x][y]= pool.pop(pool[poolNum])
print(poolNum)
My first assumption was that the array was being filled incorrectly to fail the if statement but that is not the issue. I believe the issue is during the
if currentArray[x][y].value == 0:
somehow even when I instantiated all nodes at an (x,y) it is still giving me an error as if I'm comparing a SodukuGame object to 0.
How it is called originally:
class Run:
def __init__(self):
print("Run")
game = SodokuGame()
game.printGrid()
game.fillArray(game.matrix, 0, 0, game.newPool)
game.printGrid()
Run()
Notes: I don't think it's relevant to the question but this function's intention is to check to see if the current cell is empty(=0), and if not, it will attempt to fill the cell and recursively run the function again moving over one cell until the structure is full.
I've tried implementing methods in the Cell class to workaround this, including adding a __getitem__ function, a native getInfo function, and even tried to use a isZero boolean function but all of these result in the same error. This is not for homework.
Welcome Justin. There are a few problems here, but the first one is that you aren't starting your instance methods with self. Python is still treating those variables like self, which is why you're getting the error "SodokuGame is not subscriptable". It's not subscripting the matrix you're passing in; it's subscripting the instantiated object of the SodokuGame class itself.
This is what the SodokuGame class's fillArray method should look like
class SodokuGame:
def fillArray(self, currentArray, x, y, pool):
if currentArray[x][y].value == 0:
# do stuff
You'll notice I put self up front in the argument list, which you'll always need to do. Python doesn't listen to where you put self, because you can technically name it whatever you want (you shouldn't, but you can). It's just always the first argument in an instance method.
After this you'll run into problems with Cell. You're implementing __getitem__, but Cell doesn't have an array to subscript. If you really want to subscript it, but always return the same value for some reason, you need to implement the method correctly (same goes for __setitem__):
class Cell:
value = 0
def __getitem__(self, item):
return self.value
def __setitem__(self, item, value):
self.value = value
if you don't actually want to subscript Cell, i.e. you don't want to do
c = Cell()
c[247321] = 2
# 247321 can literally be anything; 'turkey', 12, 32.1, etc.
# that is what item is in the __getitem__ and __setitem__ methods, and
# you're not using that argument in the implementations
you should probably not utilize __getitem__, but rather do something like:
class Cell:
def get_value(self):
return self.value
def set_value(self, value):
self.value = value
but your method of accessing the property directly with .value also works.

Why `__iter__` does not work when defined as an instance variable?

If I define the __iter__ method as follows, it won't work:
class A:
def __init__(self):
self.__iter__ = lambda: iter('text')
for i in A().__iter__():
print(i)
iter(A())
Result:
t
e
x
t
Traceback (most recent call last):
File "...\mytest.py", line 10, in <module>
iter(A())
TypeError: 'A' object is not iterable
As you can see, calling A().__iter__() works, but A() is not iterable.
However if I define __iter__ for the class, then it will work:
class A:
def __init__(self):
self.__class__.__iter__ = staticmethod(lambda: iter('text'))
# or:
# self.__class__.__iter__ = lambda s: iter('text')
for i in A():
print(i)
iter(A())
# will print:
# t
# e
# x
# t
Does anyone know why python has been designed like this? i.e. why __iter__ as instance variable does not work? Don't you find it unintuitive?
It is done by design. You can find the thorough description here: https://docs.python.org/3/reference/datamodel.html#special-method-lookup
Short answer: the special method must be set on the class object itself in order to be consistently invoked by the interpreter.
Long answer: the idea behind this is to speed up well-known constructions. In your example:
class A:
def __init__(self):
self.__iter__ = lambda: iter('text')
How often are you going to write a code like this in real life? So, what Python does - it skips a dictionary lookup of the instance, i.e. iter(A()) simply does not "see" that self.__iter__, which is actually self.__dict__['__iter__'] in this case.
It also skips all the __getattribute__ instance and metaclass lookup gaining a significant speedup.

Two-parter: Why doesn't this code call the function I want, and can I do this without making a separate function for it?

This is a part of a larger program, what's supposed to happen is the Score.print_points() line calls the print_points() function in class Score, then print the self.points variable.
class Score(object):
def __init__(self, points):
self.points = points
def set_score(self):
self.points = 100
# This is going to be used for something else
def change_score(self, amount):
self.points += amount
def print_points(self):
print self.points
Score.print_points()
When I run it, though, I get this error:
Traceback (most recent call last):
File "sandbox.py", line 15, in <module>
Score.print_points()
TypeError: unbound method print_points() must be called with Score instance as first argument (got nothing instead)
I'm really unfamiliar with lingo, but I thought that I was calling with the Score instance as my first argument?
As for the second part: Is there a way of making printing self.points without making a separate function within the Score class to do so?
The problem is you're calling print_points on the class itself, not an instance of that class.
Try
>>> score = Score(0)
>>> score.print_points()
0
For your second question:
As for the second part: Is there a way of making printing self.points without making a separate function within the Score class to do so?
You could just do
>>> print score.points

What is the difference for these 2 approachs to new a python class instance

I a new learner for python program, and I confuse with creating class instance as following, what are they different?
Class declaration:
class TestClass:
def __init__(self, one=10, two=20, three=30):
self.one = one
self.two = two
self.three = three
1st. (worng)
x = TestClass
print x
print x(50)
print x.one, x.two
output:
__main__.TestClass
<__main__.TestClass instance at 0x0000000002445208>
Traceback (most recent call last):
File "D:\workspace-QATool_vNext\testStudyCode\test\StudyCode.py", line 27, in <module>
print x.one, x.two
AttributeError: class TestClass has no attribute 'one'
2nd. (correct)
y = TestClass()
print y
print y.one, y.two
output:
<__main__.TestClass instance at 0x00000000023B5208>
10 20
The first one gives you a pointer to a class object (yes, these are also objects), the second one an instance to a object.
__init__ is only called when you create a new instance of an object. This is what the () after the class do: create a new instance.
You could make your first example work by doing it like this:
x = TestClass #'x' points to class object
print x
z = x(50) #'x' still points to class object but 'z' points to new instance
print z
print z.one, z.two #and 'z' is now usable as a new instance
print x.one #where 'x' still points to the class object that does not know 'one' since it hasn't run '__init__'
The problem was that x still pointed to the class object intead of the newly created instance.
The Function init is the constructor for the class and it is not called untill you use following syntex:
y = TestClass()
With that the object of TestClass (i.e. y) has all attributes.
In your first example, you are simply copying the class onto x. You are not creating an instance at all, and thus, the __init__ constructor does not run. print x(50) is what is making an instance of the class, because you are actually calling the class. But you have not stored it anywhere, so it is pointless.
In the second one, you are creating an instance (note the paretheses after TestClass), and thus accessing the variables work as you have discovered
There is a very subtle difference between your two attempts to create and use a TestClass-object.
x = TestClass
This copies the class TestClass to x.
y = TestClass()
This creates an instance of testclass and assigns it to y.
y = x()
By copying the testclass to x, x contains the exact same class and can therefore also be used to initiate objects of the class testclass.

Categories