I have defined a class called Point which defines a point in the x, y coordinate system. The definition and methods are shown below. I created my own version of the str method to return the created point in a printable form (required). However, when I try to pass the returned point to another method to determine the distance between two points (p1 and p2), using the call p.DistanceTo(p2), I get the following error from the attempt to parse the string (p2) passed into the method:
AttributeError: Point instance has no attribute 'find'
When I pass in a string defined as p2 should be it works just fine. Any help would be greatly appreciated. Thank you.
Here is the code:
class Point:
""" Define a Point
"""
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def __str__(self):
return "(" + str(self.x) + "," + str(self.y) + ")"
def __getitem__(self,i):
return i
def __find__(self,j):
return j
def DistanceTo(self,p2):
idx1 = p2.find("(")
idx2 = p2.find(",")
idx3 = p2.find(")")
x2 = int(p2[idx1+1:idx2])
y2 = int(p2[idx2+1:idx3])
dist = math.sqrt(math.pow((x2-self.x),2)+math.pow((y2-self.y),2))
return dist
p1=Point()
p2=Point(3,4)
print p1.DistanceTo(p2)
3 Answers 3
You named the method __find__. Remove the double underscores:
def find(self, j):
return j
You should really only use __...__ "dunder" (double underscore) method names for the Special method names to avoid confusion and future name clashes.
However, you are passing in a Point instance, so just access the attributes directly:
def DistanceTo(self,p2):
x2 = p2.x
y2 = p2.y
dist = math.sqrt(math.pow((x2-self.x),2)+math.pow((y2-self.y),2))
return dist
or, further simplified, using the underscore_name style most often used in Python for methods:
def distance_to(self, p2):
return math.sqrt(math.pow((p2.x - self.x), 2) + math.pow((p2.y - self.y), 2))
You can then remove the __find__ and __getitem__ methods, those look like attempts at making the .DistanceTo() method work.
The full class then becomes:
class Point(object):
"""Define a Point"""
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def __str__(self):
return "({0.x}, {0.y})".format(self)
def distance_to(self, p2):
return math.sqrt(math.pow((p2.x - self.x), 2) + math.pow((p2.y - self.y), 2))
using a little more Python idiom for the class (inheriting from object) and the __str__ method (using string formatting).
Now the class behaves as expected:
>>> p1 = Point()
>>> p2 = Point(3,4)
>>> print p1
(0, 0)
>>> print p2
(3, 4)
>>> print p1.distance_to(p2)
5.0
Class instances are not strings, and although they can be converted to strings (when printed for example), you don't need to treat them as strings. Just access their attributes directly.
4 Comments
find just return the argument? So, p2.find('(') would return ( instead of the intended value - the index of ( in the str return value.p2 is not a string, nor does it need to act like one.The method find is not declared in your object, you have to change the find method declaration like this:
...
def find(self,j):
return j
...
The double underscores are reserved for class operator methods like str, cmp, eq etc... You can get more info about python class here
3 Comments
If you intended to have private or semi-private methods in your class rename your function.
If your find method will only be used inside the Point class, rename it to __find. Otherwise you can rename it to _find which tells other developers that this method is intended to be private but they can still use it even though they should not.