py_stepik/mod_oop/2.3_13_tvprogram.py
2024-04-09 17:32:49 +03:00

149 lines
6.9 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
https://stepik.org/lesson/701985/step/13?unit=702086
Необходимо написать программу для представления и управления расписанием телевизионного вещания. Для этого нужно объявить класс TVProgram, объекты которого создаются командой:
>>> repr(TVProgram("название канала"))
"TVProgram('название канала')"
где название канала - это строка с названием телеканала.
В каждом объекте класса TVProgram должен формироваться локальный атрибут:
items - список из телепередач (изначально список пуст).
>>> TVProgram("название канала").items
[]
В самом классе TVProgram должны быть реализованы следующие методы:
add_telecast(self, tl) - добавление новой телепередачи в список items;
remove_telecast(self, indx) - удаление телепередачи по ее порядковому номеру (атрибуту __id, см. далее).
>>> {hasattr(TVProgram, m) for m in "add_telecast remove_telecast".split()}
{True}
Каждая телепередача должна описываться классом Telecast, объекты которого создаются командой:
>>> repr(Telecast(1, "название", 1111))
"Telecast(1, 'название', 1111)"
где 1 - порядковый номер - номер телепередачи в сетке вещания (от 1 и далее); "название" - наименование телепередачи; 1111 - длительность - время телепередачи (в секундах - целое число).
Соответственно, в каждом объекте класса Telecast должны формироваться локальные приватные атрибуты:
__id - порядковый номер (целое число);
__name - наименование телепередачи (строка);
__duration - длительность телепередачи в секундах (целое число).
>>> {hasattr(obj, a) for obj in (Telecast(1, "название", 1111),) for a in "__id __name __duration".split()}
{True}
Для работы с этими приватными атрибутами в классе Telecast должны быть объявлены соответствующие объекты-свойства (property):
uid - для записи и считывания из локального атрибута __id;
name - для записи и считывания из локального атрибута __name;
duration - для записи и считывания из локального атрибута __duration.
>>> {hasattr(obj, a) for obj in (Telecast(1, "название", 1111),) for a in "uid name duration".split()}
{True}
Пример использования классов (эти строчки в программе писать не нужно):
>>> def test():
... pr = TVProgram("Первый канал")
... pr.add_telecast(Telecast(1, "Доброе утро", 10000))
... pr.add_telecast(Telecast(2, "Новости", 2000))
... pr.add_telecast(Telecast(3, "Интервью с Балакиревым", 20))
... return [*map(lambda t: f"{t.name}: {t.duration}", pr.items)]
>>> test()
['Доброе утро: 10000', 'Новости: 2000', 'Интервью с Балакиревым: 20']
"""
from typing import List
def make_properties(names: List[str]):
def decorator(cls):
def prop(private_name: str):
def getter(self):
return getattr(self, private_name)
def setter(self, value):
return setattr(self, private_name, value)
return getter, setter
for name in names:
private_name = "__id" if name == "uid" else f"__{name}"
setattr(cls, name, property(*prop(private_name)))
return cls
return decorator
@make_properties("uid name duration".split())
class Telecast:
def __init__(self, uid: int, name: str, duration: int):
self.uid, self.name, self.duration = uid, name, duration
def __repr__(self):
return f"{self.__class__.__name__}{(self.uid, self.name, self.duration)!r}"
class TVProgram:
def __init__(self, name: str):
self.name = name
self.items: List[Telecast] = []
def __repr__(self) -> str:
return f"{self.__class__.__name__}('{self.name}')"
def add_telecast(self, telecast: Telecast):
self.items.append(telecast)
def remove_telecast(self, indx: int):
self.items = [item for item in self.items if item.uid != indx]
def tests():
assert hasattr(TVProgram, "add_telecast") and hasattr(
TVProgram, "remove_telecast"
), "в классе TVProgram должны быть методы add_telecast и remove_telecast"
pr = TVProgram("Первый канал")
pr.add_telecast(Telecast(1, "Доброе утро", 10000))
pr.add_telecast(Telecast(3, "Новости", 2000))
t = Telecast(2, "Интервью с Балакиревым", 20)
pr.add_telecast(t)
pr.remove_telecast(3)
assert (
len(pr.items) == 2
), "неверное число телеперач, возможно, некорректно работает метод remove_telecast"
assert (
pr.items[-1] == t
), "удалена неверная телепередача (возможно, вы удаляете не по __id, а по порядковому индексу в списке items)"
assert (
type(Telecast.uid) == property
and type(Telecast.name) == property
and type(Telecast.duration) == property
), "в классе Telecast должны быть объекты-свойства uid, name и duration"
for x in pr.items:
assert hasattr(x, "uid") and hasattr(x, "name") and hasattr(x, "duration")
assert (
pr.items[0].name == "Доброе утро"
), "объект-свойство name вернуло неверное значение"
assert (
pr.items[0].duration == 10000
), "объект-свойство duration вернуло неверное значение"
t = Telecast(1, "Доброе утро", 10000)
t.uid = 2
t.name = "hello"
t.duration = 10
if __name__ == "__main__":
import doctest
doctest.testmod()
tests()