Sistema bancario
Fa parte della sezione Programmazione orientata agli oggetti del percorso GDScript di Coddy. Lezione 63 di 65.
Sfida
DifficileCrea una banca con due tipi di conto. Ogni operazione restituisce un dizionario di risultato {"ok": bool, "message": String}; il codice fornito lo stampa come OK: MESSAGE oppure Failed: MESSAGE. Tutti gli importi sono float e ogni importo in un messaggio ha due cifre decimali dopo un $.
Transaction in transaction.gd: il costruttore accetta kind ("deposit", "withdrawal" oppure "interest") e amount. _to_string() restituisce il tipo con la prima lettera maiuscola, seguito dall’importo: Deposit - $200.00. Una transazione non memorizza il proprio conto.
Account in account.gd è una classe @abstract:
- Il costruttore accetta
account_number,owner_nameeinitial_balance. Il denaro è conservato in_balance, che è privato;balanceè una proprietà di sola lettura il cui getter restituisce_balance._historyè unArray[Transaction]eget_history()lo restituisce. - Due metodi astratti:
account_type() -> Stringewithdrawal_error(amount: float) -> String, che restituisce il motivo per cui un prelievo viene rifiutato, oppure"". deposit(amount): un importo pari a0o inferiore non va a buon fine e restituisceDeposit amount must be positive. Altrimenti aggiunge il denaro, registra una transazionedeposite restituisceDeposited $A. New balance: $B.withdraw(amount): un importo pari a0o inferiore non va a buon fine e restituisceWithdrawal amount must be positive; unwithdrawal_error()non vuoto non va a buon fine e restituisce quel testo. Altrimenti preleva il denaro, registra una transazionewithdrawale restituisceWithdrew $A. New balance: $B, seguito da(Overdraft)quando il saldo è inferiore a0._to_string()restituisceTYPE NUMBER (OWNER): $BALANCE.
SavingsAccount in savings_account.gd estende Account, con le costanti INTEREST_RATE = 0.02 e MIN_BALANCE = 100.0. Il suo tipo è Savings. Un prelievo che lascerebbe un saldo inferiore a MIN_BALANCE viene rifiutato con Cannot withdraw below minimum balance of $100.00. apply_interest() aggiunge balance * INTEREST_RATE, registra una transazione interest e restituisce Applied interest: $I. New balance: $B.
CheckingAccount in checking_account.gd estende Account, con la costante OVERDRAFT_LIMIT = 200.0. Il suo tipo è Checking. Il saldo può scendere fino a -200.00; un prelievo che lo farebbe scendere ulteriormente viene rifiutato con Cannot exceed overdraft limit of $200.00.
Bank in bank.gd conserva i conti in un dizionario privato indicizzato per numero di conto:
- Il costruttore accetta
bank_name. create_account(kind, account_number, owner_name, initial_balance)è una factory:kindpuò esseresavingsoppurechecking, indipendentemente dalle maiuscole e minuscole. Restituisce un errore conAccount number already existsoppureInvalid account type; altrimenti restituisceSavings account created successfully(oppureChecking).get_account(account_number) -> Accountrestituisce il conto oppurenull.transfer(from_number, to_number, amount): restituisce un errore conOne or both accounts not found; preleva dal primo conto e, se l’operazione non va a buon fine, restituisce un errore conTransfer failed:seguito dal messaggio del prelievo. Altrimenti deposita sul secondo conto e restituisceTransferred $A from FROM to TO.total_holdings() -> floatrestituisce la somma di tutti i saldi.
Il codice fornito legge il nome della banca e poi i comandi. Per questo input:
First Bank
open savings|S1|Alice|1000
open checking|C1|Bob|50
withdraw S1|950
transfer S1|C1|300
withdraw C1|400
history C1
totall’output è:
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.00Il tuo codice va inserito in transaction.gd, account.gd, savings_account.gd, checking_account.gd e bank.gd. main.gd contiene il codice fornito per input/output e non può essere modificato.
Provalo tu
extends Node
func _ready():
# Codice di input/output fornito: lascialo così com'è
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"])
Tutte le lezioni di Programmazione orientata agli oggetti
1Fondamenti della programmazione orientata agli oggetti
File esterniIntroduzione alla programmazione orientata agli oggettiClassi e oggetti a confrontoLa parola chiave selfMetodiProprietàCostruttore (_init)Riepilogo - Calcolatrice semplice4Polimorfismo
Ripasso dell'override dei metodiDuck typingClassi e metodi astrattiProgettazione delle interfacceRiepilogo - Calcolatore di forme7Segnali
Che cos'è un segnale?Dichiarare ed emettereCollegarsi ai segnaliSegnali con argomentiRipasso - Sistema della salute10Pattern di progettazione, parte 2
Pattern CommandPattern AdapterPattern DecoratorPattern Template MethodPattern StatePattern Composite2Proprietà delle classi
Variabili di istanza e staticheFunzioni staticheSetter delle proprietàGetter delle proprietàPrivato per convenzioneRiepilogo - Gestore di conti bancari5Incapsulamento
Membri pubblici e privatiValidazione con i setterNascondimento delle informazioniProprietà di sola letturaRiepilogo - Sistema di gestione dei dati degli studenti8Concetti avanzati di OOP
Composizione vs ereditarietàClassi interneNodi come componentiRefCounted vs NodeEnum nelle classi11Progetto: Gestione della biblioteca
Panoramica del progettoClassi Libro e Utente3Ereditarietà
Ereditarietà di baseLa parola chiave superOverride dei metodiCatene di ereditarietàControlli di tipo con isRipasso - Gerarchia dei dipendenti6Metodi speciali
Introduzione ai metodi virtualiIl metodo _to_stringIteratori personalizzatiRiepilogo - Lista personalizzata9Modelli di progettazione, parte 1
Introduzione ai modelli di progettazionePattern SingletonPattern FactoryPattern ObserverPattern Strategy12Sfide finali
Piattaforma di e-learningSistema bancarioSviluppo di un personaggio di giocoServizio di noleggio veicoliEsercitati da solo: Compilatore GDScript online