C. Классная точка 5.0

Согласитесь, что использовать операторы куда удобнее, чем обыкновенные методы. Давайте вспомним о реализованном нами методе move(x, y) и напишем ему альтернативу в виде операторов + и +=.

При выполнении кода point + (x, y), создаётся новая точка, которая отличается от изначальной на заданное кортежем расстояние по осям x и y.
При выполнении кода point += (x, y) производится перемещение изначальной точки.

Напомним, что сейчас мы модернизируем только класс PatchedPoint.

Примечание

Ваше решение должно содержать только классы и функции.
В решении не должно быть вызовов инициализации требуемых классов.

Пример

Ввод

point = PatchedPoint()
print(point)
new_point = point + (2, -3)
print(point, new_point, point is new_point)

Вывод

(0, 0)
(0, 0) (2, -3) False

Ввод

first_point = second_point = PatchedPoint((2, -7))
first_point += (7, 3)
print(first_point, second_point, first_point is second_point)

Вывод

(9, -4) (9, -4) True

Решение

Настала очередь попробовать волшебные методы __add__ и __iadd__. Первый реализует операцию +, второй – +=. И как и в прошлой задаче эти методы имеют определенную разницу не только с точки зрения нотации, но и с точки зрения того, что мы получаем в результате. Важное отличие в том, что __add__ должен ввернуть новый объект, никак не связанный ни с первым, ни вторым, в то время как __iadd__ модифицирует первый объект. И этот нюанс иногда вызывает сложность, если модификация объекта не представляет никаких проблем, мы это уже делали несколько раз в прошлых задачах, то порождение нового, не всегда очевидная задача для начинающих программистов просто в силу ловушки нашего привычного хода мыслей. В то же время это элементарное действие – для порождения нового объекта достаточно его инициализировать нужными значениями и вернуть в качестве результата.

Посмотреть код

Решение

Python
class Point:
    def __init__(self, x, y) -> None:
        self.x = x
        self.y = y

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

    def length(self, point):
        result = ((point.x - self.x) ** 2 + (point.y - self.y) ** 2) ** 0.5
        return round(result, 2)


class PatchedPoint(Point):
    def __init__(self, *args) -> None:
        match len(args):
            case 0:
                self.x = 0
                self.y = 0
            case 1:
                self.x, self.y = args[0]
            case 2:
                self.x, self.y = args

    def __add__(self, other):
        return PatchedPoint(self.x + other[0], self.y + other[1])

    def __iadd__(self, other):
        self.move(other[0], other[1])
        return self

    def __str__(self) -> str:
        string = f'({self.x}, {self.y})'
        return string

    def __repr__(self) -> str:
        string = f'PatchedPoint({self.x}, {self.y})'
        return string

Решение

Python
class Point:
    def __init__(self, x, y) -> None:
        self.x = x
        self.y = y

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

    def length(self, point):
        result = ((point.x - self.x) ** 2 + (point.y - self.y) ** 2) ** 0.5
        return round(result, 2)


class PatchedPoint(Point):
    def __init__(self, *args) -> None:
        match len(args):
            case 0:
                super().__init__(0, 0)
            case 1:
                super().__init__(*args[0])
            case 2:
                super().__init__(*args)

    def __add__(self, other):
        return PatchedPoint(self.x + other[0], self.y + other[1])

    def __iadd__(self, other):
        self.move(other[0], other[1])
        return self

    def __str__(self) -> str:
        string = f'({self.x}, {self.y})'
        return string

    def __repr__(self) -> str:
        string = f'PatchedPoint({self.x}, {self.y})'
        return string
Подписаться
Уведомить о
guest
5 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии