📋 Формулировка задания
Исходное задание из LMS:
1. Электронное письмо
Реализуйте класс Email, который представляет электронное письмо. Каждое письмо должно содержать:
sender— адрес отправителя;recipient— адрес получателя;subject— тема письма;body— текст письма;date— дата отправки.
Класс должен поддерживать:
- сравнение писем по дате;
- преобразование письма в строку;
- получение длины текста письма;
- проверку на наличие текста в письме или не состоит ли текст только из пробелов.
Пример использования:
e1 = Email("alice@example.com", "bob@example.com",
"Meeting", "Let's meet at 10am", datetime(2024, 6, 10))
e2 = Email("bob@example.com", "alice@example.com",
"Report", "", datetime(2024, 6, 11))
print(e1)
print(e2)
print("Length:", len(e1))
print("Has text:", bool(e1))
print("Is newer:", e2 > e1)
Пример вывода:
From: alice@example.com
To: bob@example.com
Subject: Meeting
- Let's meet at 10am -
From: bob@example.com
To: alice@example.com
Subject: Report
- -
Length: 18
Has text: True
Is newer: True
2. Класс для работы с деньгами
Создайте класс Money, в котором можно:
- складывать и вычитать объекты через операторы
+и-; - выводить объект как строку в виде
$<amount>; - при сложении и вычитании возвращается новый объект;
- если вычитание приводит к отрицательному значению — вернуть
0.
Пример использования:
money1 = Money(100)
money2 = Money(50)
print(money1 + money2)
print(money1 - money2)
print(money2 - money1)
Пример вывода:
$150
$50
$0
🔧 Шаг 0. Подготовка окружения
Перед началом работы над любым заданием курса нужно настроить окружение.
Создайте папку для текущего урока
Внутри учебного репозитория python-fundamentals-practice создайте папку lesson-78.
mkdir -p lesson-78
cd lesson-78
Создайте виртуальное окружение (venv)
# Windows
python -m venv venv
venv\Scripts\activate
# Mac / Linux
python3 -m venv venv
source venv/bin/activate
После активации в начале строки терминала появится (venv).
Создайте ветку для задания
cd ..
git checkout -b lesson/78-magic-methods
Именование веток: lesson/XX-краткое-название.
🛠️ Шаги выполнения задания
Создайте файл homework_78.py
В папке lesson-78 создайте файл homework_78.py.
Реализуйте класс Email
- Сохраните пять полей из условия.
__str__должен формировать вывод из четырёх строк:From:,To:,Subject:и- {body} -.__len__возвращает длинуbody.__bool__возвращаетTrue, еслиbodyне пустое и не состоит из пробелов.- Для сравнения по дате используйте
@total_orderingс__eq__и__lt__.
Реализуйте класс Money
__add__и__sub__возвращают новый объектMoney.- В
__sub__результат не должен быть меньше0. __str__возвращает строку вида$150.- Проверяйте тип
otherчерезisinstance.
Проверьте работу в VS Code
# В терминале с активированным venv
python lesson-78/homework_78.py
Ожидаемый вывод см. в формулировке задания выше.
✅ Полное решение
Ниже приведено полное решение задания. Совет: попробуйте выполнить самостоятельно, прежде чем смотреть ответ.
from __future__ import annotations
from dataclasses import dataclass
from datetime import datetime
from functools import total_ordering
@total_ordering
@dataclass
class Email:
sender: str
recipient: str
subject: str
body: str
date: datetime
def __eq__(self, other: object) -> bool:
if not isinstance(other, Email):
return NotImplemented
return self.date == other.date
def __lt__(self, other: Email) -> bool:
if not isinstance(other, Email):
return NotImplemented
return self.date < other.date
def __len__(self) -> int:
return len(self.body)
def __bool__(self) -> bool:
return bool(self.body.strip())
def __str__(self) -> str:
return (
f"From: {self.sender}\n"
f"To: {self.recipient}\n"
f"Subject: {self.subject}\n"
f"- {self.body} -"
)
@dataclass
class Money:
amount: int
def __add__(self, other: Money) -> Money:
if not isinstance(other, Money):
return NotImplemented
return Money(self.amount + other.amount)
def __sub__(self, other: Money) -> Money:
if not isinstance(other, Money):
return NotImplemented
return Money(max(0, self.amount - other.amount))
def __str__(self) -> str:
return f"${self.amount}"
if __name__ == "__main__":
e1 = Email(
"alice@example.com",
"bob@example.com",
"Meeting",
"Let's meet at 10am",
datetime(2024, 6, 10),
)
e2 = Email(
"bob@example.com",
"alice@example.com",
"Report",
"",
datetime(2024, 6, 11),
)
print(e1)
print()
print(e2)
print("Length:", len(e1))
print("Has text:", bool(e1))
print("Is newer:", e2 > e1)
print()
money1 = Money(100)
money2 = Money(50)
print(money1 + money2)
print(money1 - money2)
print(money2 - money1)
🧪 Как проверить решение
- Активируйте venv:
venv\Scripts\activate(Windows) илиsource venv/bin/activate(Mac/Linux). - Запустите файл:
python lesson-78/homework_78.py. - Убедитесь, что вывод совпадает с примером из LMS.
- Проверьте, что при вычитании большей суммы из меньшей получается
$0.
🐛 Отладка в VS Code
Если что-то не работает:
- Поставьте точку останова (breakpoint) кликом слева от номера строки, например на строке
def __lt__(self, other: Email) -> bool:. - Нажмите F5 или выберите «Run → Start Debugging».
- Используйте панель Debug: проверьте значения полей
dateиbody. - Посмотрите Terminal — Python покажет номер строки с ошибкой и traceback.
💾 Сохранение работы
git add lesson-78/
git commit -m "lesson-78: магические методы — Email и Money"
git push
💡 Советы и типичные ошибки
- В
Money.__sub__используйтеmax(0, ...), чтобы не вернуть отрицательную сумму. Email.__bool__должен смотреть наbody.strip(), а не просто наbody: строка из пробелов считается пустой.- Не забывайте проверять тип
otherв арифметических методах и возвращатьNotImplemented. - Не коммитьте папку
venv/— она указана в.gitignore.
@total_ordering — functools.total_ordering.