Open sentyaev opened 6 years ago
def debt(self): return sum([r.debt for r in self.rooms])
Мне не обязательно считать суммарный долг по всей квартире. Дальше оно используется в ConsumptionReport.full_cost(), что в общем мне тоже не нужно.
class Room: debt = 0
Зачем тут "debt=0"?
class ConsumptionReport: def __init__(self, apartment, tariff, month): ... self.month = month
А тут атрибут "month"?
@property
Вот это клевый чит!)) Только почему ты его не используешь для методов в классах квартир и комнат, а только здесь? Это же декоратор, превращающий метод класса в аргумент, или я его не правильно понял?
report = ConsoleConsumptionReport(apartment, tariff, month=5)
Название класса здесь, полагаю, просто опечатка?
Круто и лаконично! Мне до этого еще учиться и учиться. Основная мысль, что я вынес из твоего примера, это то, что все вводимые данные ты загнал в соответствующие классы. Точнее, вообще почти все данные)
В последней правке своей программулины назрел вопрос: можно ли написать тест для функции с циклом (особенно, если их там сразу несколько сплетено), чтобы выдавал ошибку, если процесс зависает в бесконечном повторении?
Твои замечания про dept & month
правильные. Я просто по быстрому это накидал и скорее всего что-то забыл, что-то зря добавил.
Про @property
- это называется "свойство". Удобно помечать им методы которые как-бы не методы, а свойства.
Обычно легко понять свойство это или метод так: метод - это глагол, свойство - существительное.
Т.е вес, рост, цвет глаз человека
это свойства,
а ходить, говорить, плавать
- методы.
Тут нет опечатки ConsoleConsumptionReport
.
ConsumptionReport
- базовый класс, у него пустой метод print
.
ConsoleConsumptionReport
- его наследник, в нем уже определен метод print
и он печатает в консоль.
Можно сделать еще одного наследника, например FileConsumptionReport
и его метод print
определить так, чтобы он печатал в файл.
Можно было сделать еще круче, но я уже не стал, но можно сделать так:
# Отчет
class ConsumptionReport:
def __init__(self, apartment, tariff, month):
self.apartment = apartment
self.tarif = tariff
self.month = month
@property
def rooms_cost(self):
return [(r.consumption() * self.tarif) + r.debt for r in
self.apartment.rooms]
@property
def rooms_communal_cost(self):
people = self.apartment.number_of_people()
return [((self.apartment.consumption() / people) * r.number_of_people) * self.tarif
for r in self.apartment.rooms]
@property
def communal_cost(self):
apartment_consumption = self.apartment.consumption()
return apartment_consumption * self.tarif
@property
def full_cost(self):
full_consumption = self.apartment.consumption() + self.apartment.rooms_consumption()
return (full_consumption * self.tarif) + self.apartment.debt()
def print(self, writer):
writer.print(self)
class ConsoleWriter:
def print(self, report):
print(report.full_cost)
print(report.another_stuff)
class FileWriter:
def print(self, report):
# store report to file
pass
# А использовать можно так
report = ConsumptionReport(apartment, tariff, month=5)
report.print(writer=ConsoleWriter())
report.print(writer=FileWriter())
Такое разделение полезно, т.к. не изменяя класс ConsumptionReport
ты можешь добавить сколько угодно новых Writer's
.
Я накидал пример как бы я решал задачу.
Ну а вот пример использования: