Задача курса

Python: Иерархия исключений для банковского счёта

Курс «Python для продвинутых: ООП, типизация и тестирование» · урок «Собственные исключения предметной области»

Условие

Иерархия исключений для банковского счёта

Тебе нужно реализовать иерархию исключений предметной области и класс BankAccount, который их поднимает. Вызывающий код затем перехватывает исключения по конкретному типу и читает их атрибуты.

Что уже дано

Проверяющая система не создаёт никаких переменных или объектов до твоего кода. В редакторе есть незавершённый каркас: заглушки классов исключений и класса BankAccount, а также скрипт демонстрации с try/except-блоками. Весь этот код выполняется в одном процессе.

Что нужно сделать

Определи следующие классы исключений и класс счёта:

Иерархия исключений:

  • BankError(Exception) — корневое исключение домена; принимает только message: str, передаёт его в super().__init__.
  • InsufficientFundsError(BankError) — недостаточно средств. __init__(self, message, required, available) сохраняет self.required и self.available (оба float).
  • NegativeAmountError(BankError) — попытка провести операцию с отрицательной или нулевой суммой. __init__(self, message, amount) сохраняет self.amount (тип float).
  • AccountBlockedError(BankError) — счёт заблокирован. __init__(self, message, account_id) сохраняет self.account_id (тип str).

Класс BankAccount:

  • __init__(self, account_id: str, balance: float) — создаёт счёт. Если balance < 0, поднимает BankError(f"Начальный баланс не может быть отрицательным: {balance}"). Атрибуты: self.account_id, self.balance, self.blocked = False.
  • block(self) — устанавливает self.blocked = True.
  • deposit(self, amount: float) -> None — пополнение счёта. Если amount <= 0, поднимает NegativeAmountError с атрибутом amount. Если счёт заблокирован, поднимает AccountBlockedError с атрибутом account_id. Иначе прибавляет amount к self.balance.
  • withdraw(self, amount: float) -> None — списание. Если amount <= 0, поднимает NegativeAmountError. Если заблокирован — AccountBlockedError. Если amount > self.balance — InsufficientFundsError с required=amount и available=self.balance. Иначе вычитает amount из self.balance.

Вызывающий скрипт (нижняя часть кода):

Напиши блоки try/except, которые:

  1. Пробуют снять 500.0 со счёта с балансом 100.0 и перехватывают InsufficientFundsError as e, сохраняя e.required в переменную caught_required и e.available в caught_available.
  2. Пробуют пополнить счёт на -50.0 и перехватывают NegativeAmountError as e, сохраняя e.amount в переменную caught_bad_amount.
  3. Пробуют снять любую сумму с заблокированного счёта и перехватывают AccountBlockedError as e, сохраняя e.account_id в переменную caught_blocked_id.

Ввод и вывод

stdin не используется. Печатать через print в stdout ничего не нужно.

Проверяющая система выполняет твой код целиком, затем читает верхнеуровневые имена из пространства имён: классы BankError, InsufficientFundsError, NegativeAmountError, AccountBlockedError, BankAccount и переменные caught_required, caught_available, caught_bad_amount, caught_blocked_id.

Пример использования

account = BankAccount("ACC-10", 100.0)
account.deposit(50)
account.withdraw(20)
print(account.balance)

try:
    account.withdraw(500)
except InsufficientFundsError as error:
    print(error.required, error.available)

Результат:

130.0
500 130.0

Попробуйте решить

РешениеPython
Без регистрации · результат не сохраняется