Задача курса
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, которые:
- Пробуют снять 500.0 со счёта с балансом 100.0 и перехватывают
InsufficientFundsError as e, сохраняяe.requiredв переменнуюcaught_requiredиe.availableвcaught_available. - Пробуют пополнить счёт на
-50.0и перехватываютNegativeAmountError as e, сохраняяe.amountв переменнуюcaught_bad_amount. - Пробуют снять любую сумму с заблокированного счёта и перехватывают
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
