From: Patrick Cotner Date: 2007-09-04T10:47:07+09:00 Subject: Credit card Calculating I posted a question earlier about hashes. Link: http://www.ruby-forum.com/topic/123502 Stephan answered my question most elegantly. I say this because the code I put together is a bit sloppy. Any how, the end result is a credit card payment calculator. No features, really. It works like this: First the program asks how many sections your card has (purchases, balance transfers, etc) and the related apr for each. It then asks how much you are willing to pay, followed by how many months you intend to pay this amount (0 if you want to pay it off using this amount.) Based on your answer to the previous question, it will either tell you how many months until the card is paid off, including how much your last payment will be, or it will give you the balance on the card after paying the amount of months you've specified. If you've paid it off prior to the amount of months you specified earlier, it tells you this as well. Intended audience I wrote this because I'm up to my eyeballs in debt and want to see how long it will take to get my head above water. How it calculates every month, he program calculates finance charges on every section of the card and adds these to the total owed on those sections. It then subtracts your payment from the section with the lowest apr (how the credit card companies do it). Rinse, repeat. When the low apr section is paid off, any overage is applied to the next lowest apr section, and the low apr section is removed from the equation. Rinse, repeat until the card is paid off or your length of time is specified. Things that would make this a better program: Comments. Cleaning up, proper usage, etc. (I'm a newb, but learning) Ability to add multiple credit cards, including minimum payments, and letting the program recursively figure out the proper order to pay them off in the least time possible. Of course if the credit card companies change your rates, or you use the cards for purchases or balance transefers, this program isn't of much use. here is the code: require 'date' t = Time.now year = t.year month = t.month total_owed = 0.0 sections = Array.new print "how many sections? " num_sections = gets.chomp!.to_i 0.upto num_sections - 1 do |x| print "section type? " type = gets.chomp! print "owed? " owed = gets.chomp!.to_f print "apr? " apr = gets.chomp!.to_f / 100 sections << { :type => type, :owed => owed, :apr => apr } end print "how much are you willing to pay per month? " payment = gets.chomp!.to_f print "how many months are you planning to pay at this rate (enter 0 if you want to pay until its completely paid off)? " months_to_pay = gets.chomp!.to_i sections.sort_by { |section| section[:apr] }.each do |section| total_owed += section[:owed] end if months_to_pay > 0 then total_months = 0 1.upto months_to_pay do |x| sections.each do |section| #calculate day in month for this iteration if month > 12 month = 1 year += 1 end days = Date.civil(year,month,-1).day month += 1 finance_charge = ((section[:apr] / 365) * days) * section[:owed] section[:owed] += finance_charge end overage = 0.0 section = sections.min { |a,b| a[:apr] <=> b[:apr] } section[:owed] -= payment if section[:owed] < 0 overage = section[:owed] end if overage != 0.0 if sections.length > 1 sections.delete(sections.min { |a,b| a[:apr] <=> b[:apr] }) section = sections.min { |a,b| a[:apr] <=> b[:apr] } section[:owed] += overage overage = 0.0 else total_owed = overage overage = 0.0 x = months_to_pay print "you wanted to pay for #{months_to_pay} months, but the card has been paid off after only #{total_months}" break end end total_months += 1 end puts "after #{total_months} months you have left on the card:" section_count = 0 sections.each do |section| puts "section #{section_count + 1}:" puts " #{section[:type]}: #{format("$%.2f",section[:owed])}" section_count += 1 end else total_months = 0 until total_owed < 0 sections.each do |section| #calculate day in month for this iteration if month > 12 month = 1 year += 1 end days = Date.civil(year,month,-1).day month += 1 #calculate finance charges and add to section[:owed] finance_charge = ((section[:apr] / 365) * days) * section[:owed] section[:owed] += finance_charge #puts "Finance charge for #{section[:type]} for month # #{total_months} is #{format("$%.2f",finance_charge)}" end total_months +=1 overage = 0.0 section = sections.min { |a,b| a[:apr] <=> b[:apr] } section[:owed] -= payment if section[:owed] < 0 overage = section[:owed] end if overage != 0.0 if sections.length > 1 sections.delete(sections.min { |a,b| a[:apr] <=> b[:apr] }) section = sections.min { |a,b| a[:apr] <=> b[:apr] } section[:owed] += overage overage = 0.0 else total_owed = overage overage = 0.0 end end end puts "it will take #{total_months} months to pay of the credit card using a payment amount of $#{payment}" puts "your last payment will be in the amount of #{format("$%.2f",total_owed + payment)}" end Please, feel free to modify etc. Let me know how it works for you. If I can figure out the recursion, I'll post it (likewise, I'm sure) -Patrick (my name) at eternaluxe .d.o.t. com -- Posted via http://www.ruby-forum.com/.