Bank Ledger
Part of the Object Oriented Programming section of Coddy's Ruby journey. Lesson 57 of 57.
Challenge
HardBuild a small bank. BankError < StandardError is the parent of InvalidAmount, InsufficientFunds, LimitReached and NoAccount, which carry the messages invalid amount, insufficient funds in 2, withdrawal limit on 2 and no account 9. Account.new(id, owner) has readers for id, owner and balance, with a private setter for the balance. deposit(amount) and withdraw(amount) raise InvalidAmount below 1; withdraw raises InsufficientFunds when the balance would fall below lowest_balance, a hook that returns 0. month_end does nothing and kind returns the account type. Checking allows an overdraft down to -100. Savings allows at most 2 withdrawals per month (LimitReached), and its month_end adds 1% interest, rounded down, and resets the count. to_s returns 1 ada checking: -20. Bank#open(kind, id, owner) creates a Checking or Savings, account(id) raises NoAccount, transfer(from, to, amount) looks both accounts up before it withdraws and deposits, month_end calls it on every account, and Bank includes Enumerable with each yielding the accounts by id.
The supplied code reads commands open checking 1 ada, dep 1 100, wd 2 30, tr 1 2 50 or month, prints ok or the error message for each, and finally every account.
Your code goes in bank_error.rb, invalid_amount.rb, insufficient_funds.rb, limit_reached.rb, no_account.rb, account.rb, checking.rb, savings.rb and bank.rb. main.rb holds the supplied input/output code and cannot be edited.
Try it yourself
require_relative 'bank_error'
require_relative 'invalid_amount'
require_relative 'insufficient_funds'
require_relative 'limit_reached'
require_relative 'no_account'
require_relative 'account'
require_relative 'checking'
require_relative 'savings'
require_relative 'bank'
# Supplied input/output code: keep it as it is
input = []
while (line = gets)
input << line.chomp
end
bank = Bank.new
input.each do |cmd|
parts = cmd.split
begin
case parts[0]
when "open" then bank.open(parts[1], parts[2].to_i, parts[3])
when "dep" then bank.account(parts[1].to_i).deposit(parts[2].to_i)
when "wd" then bank.account(parts[1].to_i).withdraw(parts[2].to_i)
when "tr" then bank.transfer(parts[1].to_i, parts[2].to_i, parts[3].to_i)
else bank.month_end
end
puts "ok"
rescue BankError => e
puts e.message
end
end
bank.each { |account| puts account }
All lessons in Object Oriented Programming
1Classes and Objects
Working With FilesDefining ClassesInstance VariablesMethods and selfto_s and inspectRecap - Library Card7Polymorphism and Duck Typing
PolymorphismDuck TypingAbstract Methodscase and ClassesRecap - Payment Methods2Accessors and Self
Readers and WritersCustom Settersself in MethodsIdentity and EqualityRecap - Contact List8Special Methods
Equality and hashOperator MethodsIndexing and AppendingCustom CollectionsRecap - Fractions11Project: Library Management
Books and MembersBorrowing Books3Class Methods and Variables
Class MethodsClass Instance VariablesConstantsFactory MethodsRecap - Coupon CodesPractice on your own: Online Ruby compiler