149 lines
6.9 KiB
Python
149 lines
6.9 KiB
Python
"""
|
||
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()
|