Last active
June 17, 2022 10:47
-
-
Save izebit/078541449dfa018cf91b5a8a8743cbae to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import datetime as dt | |
class Record: | |
def __init__(self, amount, comment, date=''): | |
self.amount = amount | |
# подобное присваивание читается сложнее, чем аналогичное с использованием конструкции вида | |
# if (...): | |
# self.date = | |
# else : | |
# self.date = | |
self.date = ( | |
dt.datetime.now().date() if | |
not | |
date else dt.datetime.strptime(date, '%d.%m.%Y').date()) | |
self.comment = comment | |
class Calculator: | |
def __init__(self, limit): | |
self.limit = limit | |
self.records = [] | |
def add_record(self, record): | |
self.records.append(record) | |
def get_today_stats(self): | |
today_stats = 0 | |
# объявление переменных начинается с маленькой буквы | |
for Record in self.records: | |
# eсли указывать <Название класса>.<название переменной> то обращение происходит | |
# к переменной класса, а не к переменной объекта этого класса. | |
# вынесение dt.datetime.now().date() из цикла в отдельную переменную, | |
# позволит избежать создание объекта на каждой итерации. | |
if Record.date == dt.datetime.now().date(): | |
today_stats = today_stats + Record.amount | |
return today_stats | |
def get_week_stats(self): | |
week_stats = 0 | |
today = dt.datetime.now().date() | |
# методы get_today_stats и get_week_stats очень похожи - итерация по записям, фильтрация и суммировании | |
# вынесение этой логики в отдельный метод позволила бы избежать дублирования и ошибок. | |
for record in self.records: | |
if ( | |
(today - record.date).days < 7 and | |
(today - record.date).days >= 0 | |
): | |
week_stats += record.amount | |
return week_stats | |
class CaloriesCalculator(Calculator): | |
def get_calories_remained(self): # Получает остаток калорий на сегодня | |
x = self.limit - self.get_today_stats() | |
if x > 0: | |
# бэкслеши для переносов не должны применяться | |
return f'Сегодня можно съесть что-нибудь' \ | |
f' ещё, но с общей калорийностью не более {x} кКал' | |
else: | |
return('Хватит есть!') | |
class CashCalculator(Calculator): | |
# использование float не обязательно, достаточно было бы простого присвоения | |
# например, USD_RATE = 60.0 | |
# если есть набор констант, то принято их группировать в enum | |
# подробнее https://docs.python.org/ja/3/howto/enum.html | |
USD_RATE = float(60) # Курс доллар США. | |
EURO_RATE = float(70) # Курс Евро. | |
def get_today_cash_remained(self, currency, | |
# не очевидно, зачем передавать эти значения в качестве параметров метода | |
USD_RATE=USD_RATE, EURO_RATE=EURO_RATE): | |
currency_type = currency | |
cash_remained = self.limit - self.get_today_stats() | |
# слишком большое ветвление, в данном случае предпочтительнее использовать case match. | |
# https://nuancesprog.ru/p/12097/ | |
# возможно, следует эту часть вынести в отдельный метод, | |
# тогда улучшилась бы читабельность метода | |
if currency == 'usd': | |
cash_remained /= USD_RATE | |
currency_type = 'USD' | |
elif currency_type == 'eur': | |
cash_remained /= EURO_RATE | |
currency_type = 'Euro' | |
elif currency_type == 'rub': | |
# перетирается значение cash_remained | |
cash_remained == 1.00 | |
currency_type = 'руб' | |
if cash_remained > 0: | |
return ( | |
# использование функций в f строках не рекомендуется | |
f'На сегодня осталось {round(cash_remained, 2)} ' | |
f'{currency_type}' | |
) | |
# проверку остатка можно осуществить в ранее, | |
# тем самым избежав выполнения ряда операций | |
elif cash_remained == 0: | |
return 'Денег нет, держись' | |
# это условие не обязательно объявлять, | |
# так как оно является взаимоисключающим, то достаточно else: | |
elif cash_remained < 0: | |
return 'Денег нет, держись:' \ | |
' твой долг - {0:.2f} {1}'.format(-cash_remained, | |
currency_type) | |
# не обязательно объявлять метод который просто делегирует вызов родительскому классу. | |
# без него так же будет работать | |
def get_week_stats(self): | |
super().get_week_stats() | |
# общение замечания | |
# 1. отсутствует объявление if __name__ == '__main__' | |
# 2. отсутствует документация для методов в формате Docstrings |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment