2024-04-13 11:57:17 +00:00
|
|
|
|
"""
|
2024-04-13 12:14:48 +00:00
|
|
|
|
https://stepik.org/lesson/701990/step/5?unit=702091
|
2024-04-13 11:57:17 +00:00
|
|
|
|
|
|
|
|
|
Объявите класс Track (маршрут), объекты которого создаются командой:
|
|
|
|
|
track = Track(start_x, start_y)
|
|
|
|
|
где start_x, start_y - координаты начала маршрута (целые или вещественные числа).
|
|
|
|
|
>>> track = Track(0, 0)
|
|
|
|
|
|
|
|
|
|
Каждый линейный сегмент маршрута определяется классом TrackLine, объекты которого создаются командой:
|
|
|
|
|
line = TrackLine(to_x, to_y, max_speed)
|
|
|
|
|
где to_x, to_y - координаты следующей точки маршрута (целые или вещественные числа); max_speed - максимальная скорость на данном участке (целое число).
|
|
|
|
|
|
|
|
|
|
>>> line = TrackLine(1, 2, 3)
|
|
|
|
|
|
|
|
|
|
Для формирования и работы с маршрутом в классе Track должны быть объявлены следующие методы:
|
|
|
|
|
add_track(self, tr) - добавление линейного сегмента маршрута (следующей точки);
|
|
|
|
|
get_tracks(self) - получение кортежа из объектов класса TrackLine.
|
|
|
|
|
|
|
|
|
|
>>> {m in dir(Track) for m in "add_track get_tracks".split()}
|
|
|
|
|
{True}
|
|
|
|
|
|
|
|
|
|
Также для объектов класса Track должны быть реализованные следующие операции сравнения:
|
|
|
|
|
track1 == track2 # маршруты равны, если равны их длины
|
|
|
|
|
track1 != track2 # маршруты не равны, если не равны их длины
|
|
|
|
|
track1 > track2 # True, если длина пути для track1 больше, чем для track2
|
|
|
|
|
track1 < track2 # True, если длина пути для track1 меньше, чем для track2
|
|
|
|
|
|
|
|
|
|
>>> track11 = Track(0, 0)
|
|
|
|
|
>>> track12 = Track(0, 0, [TrackLine(2, 2, 3)])
|
|
|
|
|
>>> track13 = Track(1, 1, [TrackLine(1, 1, 4)])
|
|
|
|
|
>>> track11 == track12
|
|
|
|
|
False
|
|
|
|
|
>>> track13 != track12
|
|
|
|
|
True
|
|
|
|
|
>>> track11 == track13
|
|
|
|
|
True
|
|
|
|
|
>>> track11 < track12
|
|
|
|
|
True
|
|
|
|
|
>>> track12 > track13
|
|
|
|
|
True
|
|
|
|
|
|
|
|
|
|
И функция:
|
|
|
|
|
n = len(track) # возвращает целочисленную длину маршрута (привести к типу int) для объекта track
|
|
|
|
|
Создайте два маршрута track1 и track2 с координатами:
|
|
|
|
|
|
|
|
|
|
>>> len(track11)
|
|
|
|
|
0
|
|
|
|
|
>>> len(track12)
|
|
|
|
|
2
|
|
|
|
|
|
|
|
|
|
1-й маршрут: (0; 0), (2; 4), (5; -4) и max_speed = 100
|
|
|
|
|
2-й маршрут: (0; 1), (3; 2), (10; 8) и max_speed = 90
|
|
|
|
|
Сравните их между собой на равенство. Результат сравнения сохраните в переменной res_eq.
|
|
|
|
|
|
|
|
|
|
>>> len(track1)
|
|
|
|
|
13
|
|
|
|
|
>>> len(track2)
|
|
|
|
|
12
|
|
|
|
|
>>> res_eq
|
|
|
|
|
False
|
|
|
|
|
|
|
|
|
|
P.S. На экран в программе ничего выводить не нужно.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
from functools import total_ordering
|
|
|
|
|
from math import hypot
|
|
|
|
|
from operator import sub
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TrackLine:
|
|
|
|
|
def __init__(self, to_x, to_y, max_speed):
|
|
|
|
|
self.to_x, self.to_y, self.max_speed = to_x, to_y, max_speed
|
|
|
|
|
|
|
|
|
|
def __repr__(self):
|
|
|
|
|
return f"{self.__class__.__name__}{(self.to_x, self.to_y, self.max_speed)!r}"
|
|
|
|
|
|
|
|
|
|
def __rsub__(self, other):
|
|
|
|
|
return self - other
|
|
|
|
|
|
|
|
|
|
def __sub__(self, other):
|
|
|
|
|
if isinstance(other, self.__class__):
|
|
|
|
|
return self - (other.to_x, other.to_y)
|
|
|
|
|
if isinstance(other, tuple):
|
|
|
|
|
a, b, c, d = (self.to_x, self.to_y, *other)
|
|
|
|
|
return hypot(c - a, d - b)
|
|
|
|
|
return NotImplemented
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@total_ordering
|
|
|
|
|
class Track:
|
|
|
|
|
def __init__(self, start_x, start_y, lines=None):
|
|
|
|
|
self.start_x, self.start_y, self.lines = start_x, start_y, lines or []
|
|
|
|
|
|
|
|
|
|
def __repr__(self):
|
|
|
|
|
return f"{self.__class__.__name__}{(self.start_x, self.start_y, self.lines)!r}"
|
|
|
|
|
|
|
|
|
|
def __len__(self):
|
|
|
|
|
left = [(self.start_x, self.start_y), *self.lines[:-1]]
|
|
|
|
|
return int(sum(map(sub, left, self.lines)))
|
|
|
|
|
|
|
|
|
|
def __eq__(self, other):
|
|
|
|
|
if isinstance(other, self.__class__):
|
|
|
|
|
return len(self) == len(other)
|
|
|
|
|
return NotImplemented
|
|
|
|
|
|
|
|
|
|
def __lt__(self, other):
|
|
|
|
|
if isinstance(other, self.__class__):
|
|
|
|
|
return len(self) < len(other)
|
|
|
|
|
return NotImplemented
|
|
|
|
|
|
|
|
|
|
def add_track(self, tr):
|
|
|
|
|
self.lines.append(tr)
|
|
|
|
|
|
|
|
|
|
def get_tracks(self):
|
|
|
|
|
return tuple(self.lines)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ma, mb = 100, 90
|
|
|
|
|
track1 = Track(0, 0, [TrackLine(2, 4, ma), TrackLine(5, -4, ma)])
|
|
|
|
|
track2 = Track(0, 1, [TrackLine(3, 2, mb), TrackLine(10, 8, mb)])
|
|
|
|
|
res_eq = track1 == track2
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def tests():
|
|
|
|
|
...
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
import doctest
|
|
|
|
|
|
|
|
|
|
doctest.testmod()
|
|
|
|
|
tests()
|