How do I represent this object unambiguously?

Viewed 62

I have written a class MyPoint:

import math

class MyPoint:
    def __init__(self,x=0,y=0):
        self.x,self.y = x,y

    def __str__(self,x=0,y=0):
        return "{}".format((self.x,self.y))

    def move(self, dx, dy):
        self.x += dx
        self.y += dy

    def move_to(self, new_x, new_y):
        self.x = new_x
        self.y = new_y

    def get_distance(self, other_point):
        distance = math.sqrt(((other_point.x - self.x)**2)+((other_point.y - self.y)**2))
        return distance

    def is_near_by(self, other_point):
        distance = MyPoint.get_distance(self, other_point)
        if distance < 5.0:
            return True
        else:
            return False

Now I need to write the MyLine class.

Define a class named MyLine by using the MyPoint class. A line is composed of two points. The MyLine class contains the following:

  • A data field named start_point of type MyPoint that defines the start point.

  • A data field named end_point of type MyPoint that defines the end point.

  • A constructor/initializer which takes 4 integers as parameters (start_x, start_y, end_x, end_y) and creates a line with two MyPoint objects or creates a line with the default values. The default value for each coordinate is 0.

This is the code I have written to use the __repr__(self) method to represent it as follows:

c1 = MyLine(10, 20, 20, 30)
print(repr(c1))

produces

MyLine(10, 20, 20, 30)

My code:

class MyLine:
    def __init__(self,start_x=0, start_y=0, end_x=0, end_y=0):
        self.start_x, self.start_y, self.end_x, self.end_y = start_x, start_y, end_x, end_y

        start_point = MyPoint(start_x, start_y)
        self.start_point = start_point

        end_point = MyPoint(end_x, end_y)
        self.end_point = end_point

    def __str__(self):
        return "{} to {}".format(self.start_point, self.end_point)

    def __repr__(self):
        return "MyLine({}, {}, {}, {})".format(self.start_x, self.start_y, self.end_x, self.end_y)

My issue is in the __repr(self)__.

Test1:

line1 = MyLine(10, 20, 20, 30)
print(repr(line1))
line2 = MyLine()
print(repr(line2))
print(type(line1.start_point))

Expected Output1:

MyLine(10, 20, 20, 30)
MyLine(0, 0, 0, 0)
<class '__main__.MyPoint'>

Received Output1:

MyLine(10, 20, 20, 30)
MyLine(0, 0, 0, 0)
<class '__main__.MyPoint'>

Test2:

line1 = MyLine()
line1.start_point = MyPoint(100, 200)
line1.end_point = MyPoint(-100, 40)
print(repr(line1))

Expected Output2:

MyLine(100, 200, -100, 40)

Received Output2:

MyLine(0, 0, 0, 0)

Where am I going wrong? I know there is an issue with what I'm doing in the .format() part but not sure what's the issue.

1 Answers

There are 2 ways. First is to change

def __repr__(self):
    return "MyLine({}, {}, {}, {})".format(self.start_point.x, self.start_point.y, self.end_point.x, self.end_point.y)

2nd, is to use attribute getters and setters.

class MyLine:
    def __init__(self,start_x=0, start_y=0, end_x=0, end_y=0):
        self.start_x, self.start_y, self.end_x, self.end_y = start_x, start_y, end_x, end_y

        start_point = MyPoint(start_x, start_y)
        self._start_point = start_point

        end_point = MyPoint(end_x, end_y)
        self._end_point = end_point

    def __str__(self):
        return "{} to {}".format(self._start_point, self._end_point)

    @property
    def start_point(self):
        return self._start_point

    @start_point.setter
    def start_point(self, point):
        self._start_point = point
        self.start_x = point.x
        self.start_y = point.y

    @property
    def end_point(self):
        return self._end_point

    @end_point.setter
    def end_point(self, point):
        self._end_point = point
        self.end_x = point.x
        self.end_y = point.y

    def __repr__(self):
        return "MyLine({}, {}, {}, {})".format(self.start_x, self.start_y, self.end_x, self.end_y)
Related