Menu
CoddyTech

银行流水账

本课属于 Coddy R 学习旅程的“面向对象编程”单元。第 57 课,共 57 课。

challenge icon

挑战

困难

用 Reference Classes 在 4 个文件中构建一个小型银行。所有定义都用 suppressMessages() 包裹;每个 stop() 中都使用 call. = FALSE。

  • Account.R:字段为 id、owner、balance(初始值为 0)。当 x 缺失或小于 1 时,deposit(x) 和 withdraw(x) 会以 invalid amount 停止;如果余额会低于 lowest()(值为 0),withdraw() 会以 insufficient funds in 2 停止。month_end() 不执行任何操作;line() 使用 kind() 返回 1 ada checking: -20。
  • Checking.R:类型为 checking;余额最低可以到 -100。
  • Savings.R:类型为 savings;每月最多取款 2 次(withdrawal limit on 2),只统计成功的取款;month_end() 会增加 1% 的利息,向下取整,并重置计数。
  • Bank.R:包含 open_account(kind, id, owner)(account 2 exists)、get_account(id)(no account 9)、transfer(from, to, amount)(取款失败时不做任何更改)、对每个账户执行的 month_end(),以及按 id 排序后包含所有账户信息的 statement()。

提供的代码会读取以下命令:open checking 1 ada、dep 1 100、wd 2 30、tr 1 2 50 或 month,并为每条命令输出 ok 或错误消息,然后输出账户信息。

你的代码写在 Account.R、Checking.R、Savings.R 和 Bank.R 中。main.R 包含提供的输入输出代码,不能编辑。

亲手试试

source("Account.R")
source("Checking.R")
source("Savings.R")
source("Bank.R")

# 提供的输入/输出代码:保持原样
input <- suppressWarnings(readLines(file("stdin")))
bank <- Bank$new()
for (line in input) {
  p <- strsplit(line, " ")[[1]]
  n <- suppressWarnings(as.numeric(p[-1]))
  msg <- tryCatch({
    switch(p[1],
      open = bank$open_account(p[2], as.numeric(p[3]), p[4]),
      dep = bank$get_account(n[1])$deposit(n[2]),
      wd = bank$get_account(n[1])$withdraw(n[2]),
      tr = bank$transfer(n[1], n[2], n[3]),
      month = bank$month_end())
    "ok"
  }, error = function(e) conditionMessage(e))
  cat(line, ": ", msg, "\n", sep = "")
}
for (l in bank$statement()) cat(l, "\n", sep = "")

面向对象编程中的所有课

自己练习: R 在线编译器