Last active
March 9, 2021 14:45
-
-
Save jlinoff/1b9957e313be8fad70b5eb99b814c950 to your computer and use it in GitHub Desktop.
Simple PMI calculator that accepts the loan amount, interest and term in years.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python2.7 | |
''' | |
Simple PMI calculator for monthly payments. | |
Enter the loan amount, the annual interest rate and the number | |
of years. | |
''' | |
import sys | |
def pmi(amt, interest, term, ppyr=12): | |
''' | |
Create an amortization schedule based on the term | |
of the loan. | |
@param amt The total amount of the loan. | |
@param interest The interest rate. | |
@param term Term of the loan. | |
''' | |
# CITATION: https://www.mtgprofessor.com/formulas.htm | |
# CITATION: https://en.wikipedia.org/wiki/Amortization_calculator | |
# pylint: disable=too-many-locals | |
famt = float(amt) | |
fint = float(interest) | |
term = int(term) | |
pir = fint / float(ppyr) # periodic interest rate | |
pay = famt * (pir + (pir / (((1. + pir) ** term) - 1.))) | |
total_paid = pay * term | |
interest_paid = total_paid - famt | |
fmt = ' {:>2} {:>4} {:>12} {:>12} {:>12} {:>12} {:>12}' | |
def currency(val): | |
''' | |
Convert to currency. | |
''' | |
return '${:,.2f}'.format(val) | |
# pylint: disable=superfluous-parens | |
print('') | |
print('Amount: {:>12}'.format(currency(famt))) | |
print('Interest: {:12,.2f} {:.2f}%'.format(fint, 100. * fint)) | |
print('Term: {:12,}'.format(term)) | |
print('PerInt: {:12,.4f} {:.2f}%'.format(pir, 100. * pir)) | |
print('Payment: {:>12}'.format(currency(pay))) | |
print('Total: {:>12}'.format(currency(total_paid))) | |
print('TotalInt: {:>12}'.format(currency(interest_paid))) | |
print('') | |
print(fmt.format('Yr', | |
'Per', | |
'Principal', | |
'Payment', | |
'PrincPaid', | |
'IntPaid', | |
'AccTotal')) | |
# pylint: enable=superfluous-parens | |
prev_total_paid_off = 0 | |
acc_payments = pay | |
for i in range(1, term+1): | |
num = ((1. + pir) ** i) - 1 | |
div = ((1. + pir) ** term) - 1 | |
pri = famt * (1. - (num / div)) # principal remaining | |
total_paid_off = famt - pri | |
paid_off_this_period = total_paid_off - prev_total_paid_off | |
interest_paid = pay - paid_off_this_period | |
# pylint: disable=superfluous-parens | |
print(fmt.format(((i+11)//12), | |
i, | |
currency(pri), | |
currency(pay), | |
currency(paid_off_this_period), | |
currency(interest_paid), | |
currency(acc_payments))) | |
# pylint: enable=superfluous-parens | |
prev_total_paid_off = total_paid_off | |
acc_payments += pay | |
# pylint: enable=too-many-locals | |
def main(): | |
''' | |
Main | |
''' | |
def get_val(prompt, i): | |
''' | |
Get a value. | |
''' | |
if len(sys.argv) > i: | |
return sys.argv[i] | |
val = raw_input(prompt) | |
try: | |
float(val) | |
except ValueError: | |
sys.stderr.write('ERROR: Not a valid number for "{}".\n'.format(prompt)) | |
sys.exit(1) | |
amount = get_val('Loan amount? ', 1) | |
interest = get_val('Interest rate? ', 2) | |
term = int(get_val('Number of years? ', 3)) | |
pmi(amount, interest, term*12) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Updated to work with python-3.