Reputation: 17
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)
Upvotes: 0
Views: 740
Reputation: 152
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.
Upvotes: 0
Reputation: 1121366
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.
Upvotes: 3
Reputation: 2340
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
Upvotes: 1