require 'ordered_hash' class BalanceSheet < ActiveSupport::OrderedHash attr_accessor :assets, :liabilities, :MAX, :RESERVE_REQUIREMENT, :name, :DEBUG def initialize(name = 'Balance Sheet', *args) super(name) @MAX = 40 @name = name @headers = [] args.each { |header| @headers.push(header) } @assets = Array.new @liabilities = Array.new @RESERVE_REQUIREMENT = 0.2 @asset_total = 0.0 @liability_total = 0.0 @DEBUG = 0 #@DEBUG = 1 #@outstanding_loans = 0.0 self['assets'] = @assets self['liabilities'] = @liabilities end def draw(maxstring = 16) puts;puts max = getLongestString(); max += 3 if maxstring > max then max = maxstring end if max > @MAX then max = @MAX end #puts "max==#{max}" total = 2*max+3 puts @name.center(total) @headers.each { |header| puts header.center(total) } printf("%-#{max}s | %#{max}s", "assets","liabilities") puts total.times { print '-' }; puts total_assets = 0; total_liabilities = 0 self['assets'].each_with_index { |element, index| begin if element =~ /\$(\d+[.,]?\d*)(.*)/ asset_value = $1.to_f; rest = $2.to_s total_assets += asset_value formatted_element = sprintf("$%.2f%s", asset_value, rest) if formatted_element == "$0.00" then formatted_element = ' ' end else; formatted_element = element; end rescue; end begin if self['liabilities'][index] =~ /\$(\d+[.,]?\d*)(.*)/ liability_value = $1.to_f total_liabilities += liability_value formatted_liability = sprintf("$%.2f%s", liability_value, $2.to_s) if formatted_liability == "$0.00" then formatted_liability = ' ' end else; formatted_liability = self['liabilities'][index]; end rescue; end #TODO: nicely wrap entries that are longer than @MAX #printf("%-#{max}s | %#{max}s", element, self['liabilities'][index]) printf("%-#{max}s | %#{max}s", formatted_element, formatted_liability) puts #printf("%-#{max}s | %#{max}s", ' ', ' '); puts # insert blank line #printf("%-#{max}s | %#{max}s", ' ', ' '); puts # insert blank line } printf("%-#{max}s | %#{max}s", ' ', ' '); puts # insert blank line formatted_total_assets = sprintf("%.2f", total_assets) formatted_total_liabilities = sprintf("%.2f", total_liabilities) printf("%-#{max}s | %#{max}s", "Total: $#{formatted_total_assets}", "Total: $#{formatted_total_liabilities}") puts;puts @asset_total = total_assets; @liability_total = total_liabilities return end def getLongestString() if @assets.length == 0 @assets.push(' ') end while @assets.length > @liabilities.length @liabilities.push(' ') end while @assets.length < @liabilities.length @assets.push(' ') end #puts @assets, @liabilities max = @assets.max{ |c1, c2| c1.length <=> c2.length } max2 = @liabilities.max{ |c1, c2| c1.length <=> c2.length } return max.length unless max2.length > max.length max2.length end def lend_long(loan_to = "loan") # calculate reserve and outstanding loan totals reserves = 0.0 outstanding_loans = 0.0 @assets.each { |asset| puts "asset: #{asset}" unless @DEBUG == 0 if asset =~ /\$(\d+[.,]?\d*) reserves/ begin reserves += $1.to_f puts "reserves 1: #{reserves}" unless @DEBUG == 0 rescue; end next end if asset =~ /\$(\d+[,.]?\d*) loan/ begin value = $1.to_f outstanding_loans = value rescue; end end } new_reserves = @liability_total * @RESERVE_REQUIREMENT #new_reserves = (new_reserves*100).round / 100.0 puts "new_reserves: #{new_reserves}" unless @DEBUG == 0 puts "reserves: #{reserves}" unless @DEBUG == 0 puts "outstanding_loans: #{outstanding_loans}" unless @DEBUG == 0 amount_to_lend_long = reserves - new_reserves #- outstanding_loans #amount_to_lend_long = outstanding_loans + (reserves - new_reserves) puts "amount_to_lend_long: #{amount_to_lend_long}" unless @DEBUG == 0 # now, reset reserves, and lend long #@assets.each { |asset| # if asset =~ /$(\d+[.,]?\d*) reserves/ # asset = "$#{new_reserves} reserves" # end #} @assets.map! { |asset| asset =~ /\$(\d+[.,]?\d*) reserves/ ? "$#{new_reserves} reserves" : asset } @assets.uniq! @assets.push("$#{amount_to_lend_long} #{loan_to}") return amount_to_lend_long end end