Банковская система
Часть раздела Объектно-ориентированное программирование путешествия по GDScript на Coddy. Урок 63 из 65.
Задание
СложноСоздай банк с двумя видами счетов. Каждая операция возвращает словарь результата {"ok": bool, "message": String}; предоставленный код выводит его как OK: MESSAGE или Failed: MESSAGE. Все суммы имеют тип float, а каждая сумма в сообщении указывается с двумя знаками после десятичной точки и символом $.
Transaction в transaction.gd: конструктор принимает kind ("deposit", "withdrawal" или "interest") и amount. _to_string() возвращает вид операции с заглавной первой буквой, а затем сумму: Deposit - $200.00. Транзакция не хранит информацию о своём счёте.
Account в account.gd — класс @abstract:
- Конструктор принимает
account_number,owner_nameиinitial_balance. Деньги хранятся в закрытом поле_balance;balance— свойство только для чтения, геттер которого возвращает_balance._history— этоArray[Transaction], аget_history()возвращает его. - Два абстрактных метода:
account_type() -> Stringиwithdrawal_error(amount: float) -> String, который возвращает причину отказа в снятии средств или"". deposit(amount): если сумма равна0или меньше, операция завершается ошибкой с сообщениемDeposit amount must be positive. В противном случае метод добавляет деньги, записывает транзакциюdepositи возвращаетDeposited $A. New balance: $B.withdraw(amount): если сумма равна0или меньше, операция завершается ошибкой с сообщениемWithdrawal amount must be positive; непустой результатwithdrawal_error()также приводит к ошибке, и её текст возвращается. В противном случае метод снимает деньги, записывает транзакциюwithdrawalи возвращаетWithdrew $A. New balance: $B, а если баланс теперь ниже0, добавляет в конце(Overdraft)._to_string()возвращаетTYPE NUMBER (OWNER): $BALANCE.
SavingsAccount в savings_account.gd наследуется от Account и содержит константы INTEREST_RATE = 0.02 и MIN_BALANCE = 100.0. Тип счёта — Savings. В снятии средств, после которого останется сумма меньше MIN_BALANCE, отказывают с сообщением Cannot withdraw below minimum balance of $100.00. apply_interest() добавляет balance * INTEREST_RATE, записывает транзакцию interest и возвращает Applied interest: $I. New balance: $B.
CheckingAccount в checking_account.gd наследуется от Account и содержит константу OVERDRAFT_LIMIT = 200.0. Тип счёта — Checking. Баланс может опуститься до -200.00; в снятии средств, после которого он станет ещё меньше, отказывают с сообщением Cannot exceed overdraft limit of $200.00.
Bank в bank.gd хранит счета в закрытом словаре, где ключом является номер счёта:
- Конструктор принимает
bank_name. create_account(kind, account_number, owner_name, initial_balance)— фабричный метод:kind— этоsavingsилиchecking, регистр букв может быть любым. Метод завершается ошибкой с сообщениемAccount number already existsилиInvalid account type; в противном случае возвращаетSavings account created successfully(илиChecking).get_account(account_number) -> Accountвозвращает счёт илиnull.transfer(from_number, to_number, amount): метод завершается ошибкой с сообщениемOne or both accounts not found; снимает деньги с первого счёта и, если эта операция завершается ошибкой, возвращаетTransfer failed:вместе с сообщением об ошибке снятия. В противном случае метод вносит деньги на второй счёт и возвращаетTransferred $A from FROM to TO.total_holdings() -> floatвозвращает сумму всех балансов.
Предоставленный код считывает название банка, а затем команды. Для этого ввода:
First Bank
open savings|S1|Alice|1000
open checking|C1|Bob|50
withdraw S1|950
transfer S1|C1|300
withdraw C1|400
history C1
totalвывод будет таким:
OK: Savings account created successfully
OK: Checking account created successfully
Failed: Cannot withdraw below minimum balance of $100.00
OK: Transferred $300.00 from S1 to C1
OK: Withdrew $400.00. New balance: $-50.00 (Overdraft)
History of C1:
1. Deposit - $300.00
2. Withdrawal - $400.00
Total held by First Bank: $650.00Твой код нужно поместить в transaction.gd, account.gd, savings_account.gd, checking_account.gd и bank.gd. В main.gd находится предоставленный код ввода/вывода, его нельзя редактировать.
Попробуйте сами
extends Node
func _ready():
# Предоставленный код ввода-вывода: оставьте его без изменений
var bank := Bank.new(OS.read_string_from_stdin())
var line := OS.read_string_from_stdin()
while line != "":
var parts := line.split(" ", true, 1)
var f: PackedStringArray = parts[1].split("|") if parts.size() > 1 else PackedStringArray()
match parts[0]:
"open":
show_result(bank.create_account(f[0], f[1], f[2], float(f[3])))
"deposit":
show_result(bank.get_account(f[0]).deposit(float(f[1])))
"withdraw":
show_result(bank.get_account(f[0]).withdraw(float(f[1])))
"interest":
var account: Account = bank.get_account(f[0])
if account is SavingsAccount:
var savings := account as SavingsAccount
show_result(savings.apply_interest())
else:
print("Failed: ", f[0], " is not a savings account")
"transfer":
show_result(bank.transfer(f[0], f[1], float(f[2])))
"history":
var history: Array = bank.get_account(f[0]).get_history()
print("History of ", f[0], ":")
for i in history.size():
print(i + 1, ". ", history[i])
"account":
print(bank.get_account(f[0]))
"total":
print("Total held by %s: $%.2f" % [bank.bank_name, bank.total_holdings()])
line = OS.read_string_from_stdin()
func show_result(result: Dictionary) -> void:
print(("OK: " if result["ok"] else "Failed: ") + result["message"])
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыВведение в ООПКлассы и объектыКлючевое слово selfМетодыСвойстваКонструктор (_init)Повторение: простой калькулятор4Полиморфизм
Переопределение методов: повторениеУтиная типизацияАбстрактные классы и методыПроектирование интерфейсовПовторение — калькулятор фигур7Сигналы
Что такое сигнал?Объявление и отправкаПодключение к сигналамСигналы с аргументамиПовторение — система здоровья10Паттерны проектирования. Часть 2
Паттерн «Команда»Паттерн «Адаптер»Паттерн «Декоратор»Паттерн «Шаблонный метод»Паттерн «Состояние»Паттерн «Компоновщик»2Свойства классов
Переменные экземпляра и классаСтатические функцииСеттеры свойствГеттеры свойствПриватность по соглашениюПовторение — менеджер банковского счёта5Инкапсуляция
Открытые и закрытые членыПроверка данных с помощью сеттеровСокрытие информацииСвойства только для чтенияПовторение — система учета студентов8Продвинутые концепции ООП
Композиция и наследованиеВнутренние классыУзлы как компонентыRefCounted и NodeПеречисления в классах11Проект: Управление библиотекой
Обзор проектаКлассы книг и пользователей3Наследование
Основы наследованияКлючевое слово superПереопределение методовЦепочки наследованияПроверка типов с помощью isПовторение — иерархия сотрудников6Специальные методы
Введение в виртуальные методыМетод _to_stringПользовательские итераторыПовторение: пользовательский список9Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн «Одиночка»Паттерн «Фабрика»Паттерн «Наблюдатель»Паттерн «Стратегия»12Итоговые задания
Платформа электронного обученияБанковская системаРазработка игрового персонажаСервис аренды автомобилейПотренируйтесь самостоятельно: Онлайн-компилятор GDScript