AppleScript C Perl Shell Xcode Other

Calculating combined interest on your credit card acount

Post Reply
coding / perl     Views: 26343Prev .. Next
Calculating combined interest on your credit card acountPosted: Thursday, December 9, 2010 [21:36:50] - 1
rootPosted by:rootMember Since:
June 16 2010
Posts: 357
We were just sitting around and thinking on how to lower monthly bills arguing about interest rate credit cards charging nowdays.
Turned-out that 24% APR gonna cost an arm and leg if one is not careful...
We did not found anything Googling and wrote a small Perl program to do the math and help us understand the issue.

Use it at your own risk. Program made to be run in Terminal

View Code#!/usr/bin/perl
unless($total) {print "Enter borrowed amount: ";$total = <STDIN>;chomp $total;}
$total = sprintf("%0.2f",$total);
if($total < .1) {print "No borrowed amount entered - exiting\n";exit(0);}
print "You have borrowed: \$$total\nPlease enter an interest rate: ";$interest = <STDIN>;
chomp $interest;
$interest = sprintf("%0.2f",$interest);
print "Interest Rate: $interest\% APR\nEnter the date you have borrowed money (Month DD YYYY): ";
$dateborrowed = <STDIN>;chomp $dateborrowed;
%allMonths = ('Jan','January','Feb','February','Mar','March','Apr','April','May','May','Jun','June',
'Jul','July','Aug','August','Sep','September','Oct','October','Nov','November','Dec','December');
%revMonths = ('January','Jan','February','Feb','March','Mar','April','Apr','May','May','June','Jun',
'July','Jul','August','Aug','September','Sep','October','Oct','November','Nov','December','Dec');
($rmo,$rda,$rye) = split(/ /,$dateborrowed);$rda =~ s/\D//g;$rye =~ s/\D//g;
$rmo =~ tr/A-Z/a-z/;$rmo =~ s/\b\w/\u$&/;
if(($allMonths{$rmo} || $revMonths{$rmo}) && length($rye) == 4 && (length($rda) == 2 || length($rda) == 1)) {$paydate=&getdateun;}
else {print "Borrowing date can not be determined - please try this program again\n";exit(0);}
print "Borrowed: \$$total\nInterest rate: $interest\%\nBorrowed on: $rmo $rda $rye\n";
print "\nPlease enter the date of your payment. When done - just hit Enter key\n";

while(1) {
print "Payment date (Month DD YYYY): ";$payment = <STDIN>;chomp $payment;
unless($payment) {last;}
($rmo,$rda,$rye) = split(/ /,$payment);$rda =~ s/\D//g;$rye =~ s/\D//g;
$rmo =~ tr/A-Z/a-z/;$rmo =~ s/\b\w/\u$&/;
if(($allMonths{$rmo} || $revMonths{$rmo}) && length($rye) == 4 && (length($rda) == 2 || length($rda) == 1)) {$payunix=&getdateun;
if($payunix) {print "Amount paid: ";$amount = <STDIN>;chomp $amount;$amount = sprintf("%0.2f",$amount);
$rmo = $allMonths{$rmo};$paids{$payunix}{$amount} = "$rmo $rda $rye";
print "Paid: \$$amount on $rmo $rda $rye\n";
} ## END IF UNIX DATE PRESENT
}
} ## WHILE END

$perday = $interest / 365;
$principal = $total;
foreach $payment (sort num keys(%paids)) {
$lapsed = $payment - $paydate;$lapsed /= 86400;$days = sprintf("%0.0f",$lapsed);
$lapsed *= $perday;
$percent = $lapsed * $principal;$percent /= 100;
$totpercent += $percent;$principal += $percent;
$percent1 = sprintf("%0.2f",$percent);
foreach $amount1 (keys %{$paids{$payment}}) {
$principal -= $amount1;
my $finaltime = localtime($payment);$finaltime =~ tr/ //s;($wdT,$moT,$daT,$tiT,$yeT) = split(/\s/,$finaltime);
$moT = $allMonths{$moT};
$principal1=$principal;$principal1 = sprintf("%0.2f",$principal1);
print "\nOn $moT $daT, $yeT your Principal was: \$$principal1 after paying \$$amount1 - interest: \$$percent1 for $days days\n";
$remainingamount = "$principal1 on $moT $daT, $yeT";
} ## FOREACH AMOUNT END
$paydate=$payment;
} ## FOREACH PAYMENT DATE END
$totpercent = sprintf("%0.2f",$totpercent);
print "Interest up to last payment: \$$totpercent\n";
sub num {$a $b;}

sub getdateun { ########
## WE KNOW IT'S NOT THE MOST EFFICIENT WAY - BUT IT WORKS FOR OUR PURPOSE
if($revMonths{$rmo}) {$rmo=$revMonths{$rmo};}$rda++;$rda--;
$tdate=time;
while(1) {
my $finaltime = localtime($tdate);$finaltime =~ tr/ //s;($wdT,$moT,$daT,$tiT,$yeT) = split(/\s/,$finaltime);
if($rda == $daT && $yeT == $rye && $moT eq $rmo) {$unixtime=$tdate;last;}
$tdate -= 86400;
} ## WHILE END
return($unixtime);
} ## END GET UNIX DATE #

as simple as thatThere's no place like ~
RE: Calculating combined interest on your credit card acountPosted: Friday, December 10, 2010 [19:15:52] - 2
rootPosted by:rootMember Since:
June 16 2010
Posts: 357
Come to think of it -- this program could be ported to anything besides being a simple Terminal program.
Also multiple purchases could be easily added. It could feed off CSV or any database files to get purchases and payments. Based on this input it could calculate the interest and total amounts.
Let me see if I'll have time to do this...
cheersThere's no place like ~
RE: Calculating combined interest on your credit card acountPosted: Monday, January 3, 2011 [13:29:04] - 3
Posted by:HugmeirPosts: 1
I took the liberty of reviewing your code a bit, though I'd recommend running this through perltidy (http://search.cpan.org/dist/Perl-Tidy/lib/Perl/Tidy.pm or simply perl -MCPAN -e 'install Perl::Tidy') before trying to read it, as these code tags are ruining my indentation. I tried to keep things faithful to the original, plus a couple of sanity checks and best practices - Though I'll admit that I gave up on some parts and scarcely even touched them, and some parts from me are scarcely the best, or even a practice!

As you said, it should be trivial to add CSV support (using Text::CSV from CPAN, or some other related module), or command-line argument passing (using Getopt::Long).

Also, please, always, no matter what you intend to do, use strict and warnings! Otherwise all the cool Perl kids will point and laugh.

View Code#!/usr/bin/perl
use strict;
use warnings;
use 5.010;

print "Enter borrowed amount: ";
chomp( my $total = sprintf "%0.2f", scalar <STDIN> );
die "No borrowed amount entered - exiting\n" if ( $total < .1 );
say "You have borrowed: \$$total";

print("Please enter an interest rate: ");
chomp( my $interest = sprintf "%0.2f", scalar <STDIN> );
say "Interest Rate: $interest% APR";

my @month_names = (
'January', 'February', 'March',
'April', 'May', 'June',
'July', 'August', 'September',
'October', 'November', 'December',
);
my %all_months = map { (substr($_, 0, 3), $_) } @month_names;
my %rev_months = reverse %all_months;

print "Enter the date you have borrowed money (Month-or-MM DD YYYY): ";
chomp( my $date_borrowed = <STDIN> );
my %date = %{ parse_date($date_borrowed) };
my $paydate = getdateun(\%date);

say <<"END_TEXT";

Borrowed: \$$total
Interest rate: $interest%
Borrowed on: $date{month} $date{day} $date{year}

Please enter the date of your payment. When done, just leave blank and hit the enter key.
END_TEXT

my %paids;

while ( my $payment_date = get_date() ) {
chomp $payment_date;
my %date = %{ parse_date($payment_date) } or (say "Bad date" and next);

my $payunix = getdateun(\%date);
if ($payunix) {
print "Amount paid: ";
chomp( my $amount = <STDIN>);
$amount = sprintf( "%0.2f", $amount );
$paids{$payunix}{$amount} = join ' ', $all_months{$date{month}}, $date{day}, $date{year};
print "Paid: \$$amount on $date{month} $date{day} $date{year}\n";
}
}

my $perday = $interest / 365;
my $principal = $total;
my $totpercent = 0;

for my $payment ( sort { $a <=> $b } keys(%paids) ) {
my $lapsed = ( ($payment - $paydate) / 86400 ) * $perday;
my $percent = ($lapsed * $principal) / 100;
$totpercent += $percent;
$principal += $percent;

for my $amount_paid ( keys %{ $paids{$payment} } ) {
$principal -= $amount_paid;
my $finaltime = localtime($payment);
my ( $wdT, $moT, $daT, $tiT, $yeT ) = split( /\s/, $finaltime );
$moT = $all_months{$moT};
say <<"END_SUM";

On $moT $daT, $yeT your Principal was: \$@{[sprintf( "%0.2f", $principal )]} after paying \$$amount_paid.
Interest: \$@{[sprintf "%0.2f", $percent ]} for @{[sprintf "%0.0f", $lapsed ]} days.
END_SUM
}
$paydate = $payment;
}

say <<"END";

Interest up to last payment: \$@{[sprintf "%0.2f", $totpercent]}
Remaining amount: \$@{[sprintf "%.2f", $principal ]}

END

sub parse_date {
my ($date_to_parse) = @_;
my %date;
@date{qw( month day year )} = split(/ /, $date_to_parse );
die "Bad date format" unless (grep defined, values %date) == 3;

$date{day} =~ s/[^0-9]//g; #Changing \D to [^0-9] because \D sometimes becomes retarded with locales.
$date{year} =~ s/[^0-9]//g;
$date{month} =~ s/\W//g;
$date{month} =~ s/^([0-9]+)$/$month_names[$1 - 1]/;
$date{month} =~ "\u\L$date{month}";

die "Bad date format" unless (grep defined, values %date) == 3 or (
( $all_months{$date{month}} or $rev_months{$date{month}} )
and length($date{year}) == 4
and length($date{day}) ~~ [1,2]
);

return \%date;
}

sub get_date {
print("Payment date (Month DD YYYY): ");
chomp( my $payment_date = <STDIN> );
return $payment_date;
}

sub getdateun { ########
## WE KNOW IT'S NOT THE MOST EFFICIENT WAY - BUT IT WORKS FOR OUR PURPOSE
my ($date) = @_;
if ( $rev_months{$date->{month}} ) { $date->{month} = $rev_months{$date->{month}}; }
my $tdate = time;

while (1) {
my $finaltime = localtime($tdate);
$finaltime =~ tr/ //s;
my ( $wdT, $moT, $daT, $tiT, $yeT ) = split( /\s/, $finaltime );
if ( $date->{day} == $daT && $yeT == $date->{year} && $moT eq $date->{month} ) {
last;
}
$tdate -= 86400;
}
return ($tdate);
}
coding / perlPrev .. Next
 
Post Reply
Home - Coding: AppleScript C Perl Shell Xcode Other
Our Telegram Group