⚠️ Рекомендация: попробуйте решить задания самостоятельно.
Решение задачи 1. Система чеков
# practice18_receipts.py
class Receipt:
def __init__(self, receipt_id: int, amount: float) -> None:
self.id = receipt_id
self.amount = amount
def __str__(self) -> str:
return f"{self.__class__.__name__} {self.id}: {self.amount}"
class SaleReceipt(Receipt):
def __init__(self, receipt_id: int, amount: float) -> None:
if amount <= 0:
raise ValueError("SaleReceipt amount must be positive.")
super().__init__(receipt_id, amount)
def __str__(self) -> str:
return f"{self.__class__.__name__} {self.id}: +{self.amount}"
class ReturnReceipt(Receipt):
def __init__(self, receipt_id: int, amount: float) -> None:
if amount >= 0:
raise ValueError("ReturnReceipt amount must be negative.")
super().__init__(receipt_id, amount)
def __str__(self) -> str:
return f"{self.__class__.__name__} {self.id}: {self.amount}"
class Shift:
_id_counter = 1
def __init__(self) -> None:
self.id = Shift._id_counter
Shift._id_counter += 1
self.receipts: list[Receipt] = []
self.closed = False
def is_closed(self) -> bool:
return self.closed
def close(self) -> None:
self.closed = True
def add_receipt(self, amount: float) -> None:
if self.closed:
raise ValueError("Cannot add receipt to closed shift.")
receipt_id = len(self.receipts) + 1
self.receipts.append(SaleReceipt(receipt_id, amount))
def add_return(self, source_shift: "Shift", original_id: int, return_amount: float) -> None:
if not (0 < original_id <= len(source_shift.receipts)):
raise ValueError("Original receipt not found.")
original = source_shift.receipts[original_id - 1]
if return_amount > original.amount:
raise ValueError("Return amount exceeds original.")
receipt_id = len(self.receipts) + 1
self.receipts.append(ReturnReceipt(receipt_id, -return_amount))
def list_receipts(self, receipt_type: str | None = None) -> None:
for receipt in self.receipts:
if receipt_type is None:
print(receipt)
elif receipt_type == "sale" and isinstance(receipt, SaleReceipt):
print(receipt)
elif receipt_type == "return" and isinstance(receipt, ReturnReceipt):
print(receipt)
def get_total(self, receipt_type: str | None = None) -> float:
if receipt_type is None:
return sum(r.amount for r in self.receipts)
cls = SaleReceipt if receipt_type == "sale" else ReturnReceipt
return sum(r.amount for r in self.receipts if isinstance(r, cls))
# --- проверка ---
shift1 = Shift()
shift1.add_receipt(100)
shift1.add_receipt(200)
shift2 = Shift()
shift2.add_return(shift1, 1, 50)
shift1.list_receipts()
shift2.list_receipts()
print("Total sales:", shift2.get_total("sale"))
print("Total returns:", shift2.get_total("return"))
print("Total:", shift2.get_total())
try:
shift2.add_return(shift1, 1, 500)
except ValueError as e:
print("Error:", e)
Решение задачи 2. Уведомления
# practice18_notifications.py
class EmailNotifyMixin:
def email_notify(self, message: str) -> None:
if not hasattr(self, "email"):
raise AttributeError("Missing 'email'")
print(f"Email to {self.email}: {message}")
class SmsNotifyMixin:
def sms_notify(self, message: str) -> None:
if not hasattr(self, "phone"):
raise AttributeError("Missing 'phone'")
print(f"SMS to {self.phone}: {message}")
class PushNotifyMixin:
def push_notify(self, message: str) -> None:
print(f"Push notification: {message}")
class User:
def __init__(self, name: str) -> None:
self.name = name
class Courier(User, EmailNotifyMixin, SmsNotifyMixin):
def __init__(self, name: str, email: str, phone: str) -> None:
super().__init__(name)
self.email = email
self.phone = phone
def notify(self, message: str) -> None:
self.email_notify(message)
self.sms_notify(message)
class Admin(User, PushNotifyMixin):
def notify(self, message: str) -> None:
self.push_notify(message)
courier = Courier("Alice", "alice@example.com", "+123456789")
courier.notify("Package delivered.")
admin = Admin("Bob")
admin.notify("New report available.")