מערכת בנקאית
חלק מהיחידה תכנות מונחה עצמים במסלול ה-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הוא מאפיין לקריאה בלבד, שה-getter שלו מחזיר את_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, ואחריו(Overdraft)כאשר היתרה כעת נמוכה מ-0._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)היא פונקציית factory: הערך של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יסודות התכנות מונחה העצמים
קבצים חיצונייםמבוא ל-OOPמחלקות לעומת אובייקטיםמילת המפתח selfמתודותמאפייניםבנאי (_init)חזרה – מחשבון פשוט2מאפייני מחלקה
משתני מופע לעומת משתנים סטטייםפונקציות סטטיותקובעי מאפייניםמאחזרי מאפייניםפרטיים לפי מוסכמהסיכום – מנהל חשבון בנק5כימוס
איברים ציבוריים ופרטייםאימות באמצעות Settersהסתרת מידעמאפיינים לקריאה בלבדסיכום – מערכת לניהול רשומות תלמידיםתרגלו בעצמכם: קומפיילר GDScript אונליין