user2278537
user2278537

Reputation: 17

Python find method in class

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

Answers (3)

Nylo Andy
Nylo Andy

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

Martijn Pieters
Martijn Pieters

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

jvallver
jvallver

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

Related Questions