Created
March 31, 2026 11:36
-
-
Save DJWOMS/3ce2c640c98e6493c06adc0df883a51a to your computer and use it in GitHub Desktop.
Ревью кода студента, калькулятор калорий и денег
This file contains hidden or 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: | |
| # Лучше использовать date=None вместо date=''. | |
| # None явно означает "не передано", пустая строка это конкретное значение. | |
| # Ниже проверка `not date` сработает одинаково для '' и None, | |
| # но с None код читается понятнее. | |
| def __init__(self, amount, comment, date=None): | |
| self.amount = amount | |
| # Форматирование тернарного оператора затрудняет чтение. | |
| # if not и date разбиты на разные строки без причины. | |
| # Лучше писать в одну строку или разбить на обычный if/else. | |
| # Например: | |
| # if date is None: | |
| # self.date = dt.datetime.now().date() | |
| # else: | |
| # self.date = dt.datetime.strptime(date, '%d.%m.%Y').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 | |
| # Переменная цикла названа Record с большой буквы это перекрывает | |
| # имя класса Record в текущей области видимости. | |
| # Используй строчную букву: for record in self.records. | |
| for Record in self.records: | |
| # dt.datetime.now().date() вызывается на каждой итерации цикла. | |
| # Лучше вычислить один раз до цикла и сохранить в переменную, | |
| # как это сделано в get_week_stats. | |
| if Record.date == dt.datetime.now().date(): | |
| # Используй оператор += для единообразия с get_week_stats. | |
| # today_stats += Record.amount | |
| today_stats = today_stats + Record.amount | |
| return today_stats | |
| def get_week_stats(self): | |
| week_stats = 0 | |
| today = dt.datetime.now().date() | |
| for record in self.records: | |
| if ( | |
| # (today - record.date).days вычисляется дважды. | |
| # Сохрани в переменную: days_ago = (today - record.date).days | |
| # и используй её в условии. | |
| # Также можно записать условие короче: | |
| # 0 <= (today - record.date).days < 7 | |
| (today - record.date).days < 7 and | |
| (today - record.date).days >= 0 | |
| ): | |
| week_stats += record.amount | |
| return week_stats | |
| class CaloriesCalculator(Calculator): | |
| # Комментарий должен быть оформлен как docstring, а не строчный комментарий. | |
| # Например: | |
| # def get_calories_remained(self): | |
| # """Возвращает количество калорий, доступных сегодня к употреблению.""" | |
| def get_calories_remained(self): # Получает остаток калорий на сегодня | |
| # Название переменной x не описывает её смысл. | |
| # Используй что-то понятное calories_remained или remained. | |
| x = self.limit - self.get_today_stats() | |
| if x > 0: | |
| # Для переноса строк не используй бэкслеш это нарушение требований. | |
| # Оберни строку в скобки: | |
| # return ( | |
| # f'Сегодня можно съесть что-нибудь ещё, ' | |
| # f'но с общей калорийностью не более {x} кКал' | |
| # ) | |
| return f'Сегодня можно съесть что-нибудь' \ | |
| f' ещё, но с общей калорийностью не более {x} кКал' | |
| # Ветка else здесь лишняя, if выше заканчивается return, | |
| # значит всё что ниже выполнится только если условие ложно. | |
| # Убери else и оставь просто return. | |
| else: | |
| # Лишние скобки в return, return не функция. | |
| # Пиши return 'Хватит есть!' | |
| return('Хватит есть!') | |
| class CashCalculator(Calculator): | |
| # float(60) избыточно. Пиши просто 60.0 или 60. | |
| # Комментарии к константам лучше оформить как строки с точкой в конце | |
| # или убрать совсем, имена USD_RATE и EURO_RATE говорят сами за себя. | |
| USD_RATE = float(60) # Курс доллар США. | |
| EURO_RATE = float(70) # Курс Евро. | |
| # USD_RATE и EURO_RATE передавать как параметры со значениями по умолчанию | |
| # не нужно, они уже доступны как атрибуты класса через self.USD_RATE | |
| # и self.EURO_RATE. Такая сигнатура создаёт путаницу и позволяет | |
| # случайно переопределить курс при вызове метода. | |
| def get_today_cash_remained(self, currency, | |
| USD_RATE=USD_RATE, EURO_RATE=EURO_RATE): | |
| # currency_type = currency это лишнее присвоение, если всё равно | |
| # переопределяешь значение в каждой ветке if/elif. | |
| currency_type = currency | |
| cash_remained = self.limit - self.get_today_stats() | |
| # Первое условие проверяет currency, остальные currency_type. | |
| # Это непоследовательно, хотя в данном случае значения совпадают. | |
| # Используй одну переменную везде. | |
| 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 ( | |
| # Вызов round() внутри f-строки нарушает требования: | |
| # "в f-строках нет вызовов функций". | |
| # Вычисли значение до f-строки: | |
| # rounded = round(cash_remained, 2) | |
| # и используй {rounded} в строке. | |
| f'На сегодня осталось {round(cash_remained, 2)} ' | |
| f'{currency_type}' | |
| ) | |
| elif cash_remained == 0: | |
| return 'Денег нет, держись' | |
| # Последний elif можно заменить на else, так как других вариантов нет. | |
| elif cash_remained < 0: | |
| # Два нарушения сразу: бэкслеш для переноса и смешивание | |
| # f-строк с .format() в одном методе это непоследовательно. | |
| # Используй f-строку и скобки для переноса | |
| # return ( | |
| # f'Денег нет, держись: ' | |
| # f'твой долг - {-cash_remained:.2f} {currency_type}' | |
| # ) | |
| return 'Денег нет, держись:' \ | |
| ' твой долг - {0:.2f} {1}'.format(-cash_remained, | |
| currency_type) | |
| # Этот метод не нужен, он вызывает родительский get_week_stats, | |
| # но не возвращает результат, нет return. | |
| # Если цель просто использовать родительскую реализацию, | |
| # достаточно убрать этот метод целиком и он будет унаследован автоматически. | |
| def get_week_stats(self): | |
| super().get_week_stats() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment