diff --git a/mod_oop/3.5_05_track.py b/mod_oop/3.5_05_track.py new file mode 100644 index 0000000..6ccaf5d --- /dev/null +++ b/mod_oop/3.5_05_track.py @@ -0,0 +1,132 @@ +""" + https://stepik.org/lesson/701989/step/11?unit=702090 + +Объявите класс 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()