From fa961971fc7eccb50125e6090d23b1c9caa99baf Mon Sep 17 00:00:00 2001 From: Marks Mac Date: Wed, 17 Apr 2024 22:55:50 -0400 Subject: [PATCH 1/9] added amortization_table --- financial/amortization_table.py | 87 +++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 financial/amortization_table.py diff --git a/financial/amortization_table.py b/financial/amortization_table.py new file mode 100644 index 000000000000..9fa3ad63b5a1 --- /dev/null +++ b/financial/amortization_table.py @@ -0,0 +1,87 @@ +import pandas as pd + +def payment(principal: float, interest_rate: float, payments: int) -> float: + """ + Calculate the monthly payment for a loan. + + Parameters + ---------- + principal : float + The amount of the loan. + interest_rate : float + The annual interest rate for the loan. + years : int + The term of the loan in years. + + Returns + ------- + float + The monthly payment for the loan. + + Examples + -------- + >>> payment(1000, 0.1, 1) + 1099.9999999999995 + """ + payment = principal * interest_rate / (1 - (1 + interest_rate) ** -payments) + + return payment + +def amortization_table(principal: float, interest_rate: float, years: int) -> pd.DataFrame: + """ + Create an amortization table for a loan. + + Parameters + ---------- + principal : float + The amount of the loan. + interest_rate : float + The annual interest rate for the loan. + years : int + The term of the loan in years. + + Returns + ------- + pd.DataFrame + The amortization table for the loan. + + Examples + -------- + >>> amortization_table(1000, 0.1, 1) + Payment Principal Interest Remaining + 0 0.00 0.00 0.00 1000.00 + 1 87.92 79.58 8.33 920.42 + 2 87.92 80.25 7.67 840.17 + 3 87.92 80.91 7.00 759.26 + 4 87.92 81.59 6.33 677.67 + 5 87.92 82.27 5.65 595.40 + 6 87.92 82.95 4.96 512.45 + 7 87.92 83.65 4.27 428.80 + 8 87.92 84.34 3.57 344.46 + 9 87.92 85.05 2.87 259.41 + 10 87.92 85.75 2.16 173.66 + 11 87.92 86.47 1.45 87.19 + 12 87.92 87.19 0.73 0.00 + """ + payments = years * 12 + interest_rate /= 12 + payment_amount = payment(principal, interest_rate, payments) + df = pd.DataFrame(index=range(0, payments + 1), columns=["Payment", "Principal", "Interest", "Remaining"], dtype="float", data=0) + + df["Payment"][1:] = payment_amount + df["Remaining"][0] = principal + for i in range(1, payments + 1): + df["Interest"][i] = df["Remaining"][i - 1] * interest_rate + df["Principal"][i] = df["Payment"][i] - df["Interest"][i] + df["Remaining"][i] = df["Remaining"][i - 1] - df["Principal"][i] + df = df.round(2) + df = df.abs() + + return df + + + +if __name__ == "__main__": + import doctest + + doctest.testmod() \ No newline at end of file From 3fb6f0fe5a29005860fe459f57f767cddbec5502 Mon Sep 17 00:00:00 2001 From: Marks Mac Date: Wed, 17 Apr 2024 22:59:44 -0400 Subject: [PATCH 2/9] added wiki --- financial/amortization_table.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/financial/amortization_table.py b/financial/amortization_table.py index 9fa3ad63b5a1..77a01f8b2dae 100644 --- a/financial/amortization_table.py +++ b/financial/amortization_table.py @@ -1,3 +1,12 @@ +""" +Program creates an amortization table for a loan, given +- Principal borrowed +- Rate of interest per annum +- Years to repay the loan + +Wikipedia Reference: https://www.investopedia.com/terms/a/amortization.asp +""" + import pandas as pd def payment(principal: float, interest_rate: float, payments: int) -> float: From b82e1e2ad39f155e775e241e522f1beb10066104 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 18 Apr 2024 03:02:25 +0000 Subject: [PATCH 3/9] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- financial/amortization_table.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/financial/amortization_table.py b/financial/amortization_table.py index 77a01f8b2dae..883169d4734d 100644 --- a/financial/amortization_table.py +++ b/financial/amortization_table.py @@ -9,6 +9,7 @@ import pandas as pd + def payment(principal: float, interest_rate: float, payments: int) -> float: """ Calculate the monthly payment for a loan. @@ -36,7 +37,10 @@ def payment(principal: float, interest_rate: float, payments: int) -> float: return payment -def amortization_table(principal: float, interest_rate: float, years: int) -> pd.DataFrame: + +def amortization_table( + principal: float, interest_rate: float, years: int +) -> pd.DataFrame: """ Create an amortization table for a loan. @@ -75,7 +79,12 @@ def amortization_table(principal: float, interest_rate: float, years: int) -> pd payments = years * 12 interest_rate /= 12 payment_amount = payment(principal, interest_rate, payments) - df = pd.DataFrame(index=range(0, payments + 1), columns=["Payment", "Principal", "Interest", "Remaining"], dtype="float", data=0) + df = pd.DataFrame( + index=range(0, payments + 1), + columns=["Payment", "Principal", "Interest", "Remaining"], + dtype="float", + data=0, + ) df["Payment"][1:] = payment_amount df["Remaining"][0] = principal @@ -89,8 +98,7 @@ def amortization_table(principal: float, interest_rate: float, years: int) -> pd return df - if __name__ == "__main__": import doctest - doctest.testmod() \ No newline at end of file + doctest.testmod() From 36a863291566b209e070582ffc4da68f4f541c19 Mon Sep 17 00:00:00 2001 From: Marks Mac Date: Wed, 17 Apr 2024 23:07:05 -0400 Subject: [PATCH 4/9] ran ruff --- financial/amortization_table.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/financial/amortization_table.py b/financial/amortization_table.py index 77a01f8b2dae..a155d0a6289d 100644 --- a/financial/amortization_table.py +++ b/financial/amortization_table.py @@ -9,6 +9,7 @@ import pandas as pd + def payment(principal: float, interest_rate: float, payments: int) -> float: """ Calculate the monthly payment for a loan. @@ -75,22 +76,22 @@ def amortization_table(principal: float, interest_rate: float, years: int) -> pd payments = years * 12 interest_rate /= 12 payment_amount = payment(principal, interest_rate, payments) - df = pd.DataFrame(index=range(0, payments + 1), columns=["Payment", "Principal", "Interest", "Remaining"], dtype="float", data=0) + amor_table = pd.DataFrame(index=range(0, payments + 1), columns=["Payment", "Principal", "Interest", "Remaining"], dtype="float", data=0) - df["Payment"][1:] = payment_amount - df["Remaining"][0] = principal + amor_table["Payment"][1:] = payment_amount + amor_table["Remaining"][0] = principal for i in range(1, payments + 1): - df["Interest"][i] = df["Remaining"][i - 1] * interest_rate - df["Principal"][i] = df["Payment"][i] - df["Interest"][i] - df["Remaining"][i] = df["Remaining"][i - 1] - df["Principal"][i] - df = df.round(2) - df = df.abs() + amor_table["Interest"][i] = amor_table["Remaining"][i - 1] * interest_rate + amor_table["Principal"][i] = amor_table["Payment"][i] - amor_table["Interest"][i] + amor_table["Remaining"][i] = amor_table["Remaining"][i - 1] - amor_table["Principal"][i] + amor_table = amor_table.round(2) + amor_table = amor_table.abs() - return df + return amor_table if __name__ == "__main__": import doctest - doctest.testmod() \ No newline at end of file + doctest.testmod() From 02979c45ee9b415d006976dfe401ffd4f5b4b8cb Mon Sep 17 00:00:00 2001 From: Marks Mac Date: Wed, 17 Apr 2024 23:08:42 -0400 Subject: [PATCH 5/9] fixed miss type in the code --- financial/amortization_table.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/financial/amortization_table.py b/financial/amortization_table.py index 3ecb07fe9d41..a56343f62b2d 100644 --- a/financial/amortization_table.py +++ b/financial/amortization_table.py @@ -79,7 +79,7 @@ def amortization_table( payments = years * 12 interest_rate /= 12 payment_amount = payment(principal, interest_rate, payments) - df = pd.DataFrame(index=range(0, payments + 1), columns=["Payment", "Principal", "Interest", "Remaining"], dtype="float", data=0) + amor_table = pd.DataFrame(index=range(0, payments + 1), columns=["Payment", "Principal", "Interest", "Remaining"], dtype="float", data=0) amor_table["Payment"][1:] = payment_amount amor_table["Remaining"][0] = principal From 9e776e1a438fac278a3eb561cdce5332de4c66cb Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 18 Apr 2024 03:08:46 +0000 Subject: [PATCH 6/9] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- financial/amortization_table.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/financial/amortization_table.py b/financial/amortization_table.py index 3ecb07fe9d41..825269fe8cb4 100644 --- a/financial/amortization_table.py +++ b/financial/amortization_table.py @@ -79,14 +79,23 @@ def amortization_table( payments = years * 12 interest_rate /= 12 payment_amount = payment(principal, interest_rate, payments) - df = pd.DataFrame(index=range(0, payments + 1), columns=["Payment", "Principal", "Interest", "Remaining"], dtype="float", data=0) + df = pd.DataFrame( + index=range(0, payments + 1), + columns=["Payment", "Principal", "Interest", "Remaining"], + dtype="float", + data=0, + ) amor_table["Payment"][1:] = payment_amount amor_table["Remaining"][0] = principal for i in range(1, payments + 1): amor_table["Interest"][i] = amor_table["Remaining"][i - 1] * interest_rate - amor_table["Principal"][i] = amor_table["Payment"][i] - amor_table["Interest"][i] - amor_table["Remaining"][i] = amor_table["Remaining"][i - 1] - amor_table["Principal"][i] + amor_table["Principal"][i] = ( + amor_table["Payment"][i] - amor_table["Interest"][i] + ) + amor_table["Remaining"][i] = ( + amor_table["Remaining"][i - 1] - amor_table["Principal"][i] + ) amor_table = amor_table.round(2) amor_table = amor_table.abs() From b79ab36a484a358855af2e5f27ef3a75c8304721 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 18 Apr 2024 03:10:53 +0000 Subject: [PATCH 7/9] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- financial/amortization_table.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/financial/amortization_table.py b/financial/amortization_table.py index de2984b1780d..a5e7f55debe8 100644 --- a/financial/amortization_table.py +++ b/financial/amortization_table.py @@ -79,7 +79,12 @@ def amortization_table( payments = years * 12 interest_rate /= 12 payment_amount = payment(principal, interest_rate, payments) - amor_table = pd.DataFrame(index=range(0, payments + 1), columns=["Payment", "Principal", "Interest", "Remaining"], dtype="float", data=0) + amor_table = pd.DataFrame( + index=range(0, payments + 1), + columns=["Payment", "Principal", "Interest", "Remaining"], + dtype="float", + data=0, + ) amor_table["Payment"][1:] = payment_amount amor_table["Remaining"][0] = principal From af207aed87063f4d6a9c2e10f834ab1fa7bc9045 Mon Sep 17 00:00:00 2001 From: Marks Mac Date: Wed, 17 Apr 2024 23:13:11 -0400 Subject: [PATCH 8/9] fixed ruff errors --- financial/amortization_table.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/financial/amortization_table.py b/financial/amortization_table.py index de2984b1780d..600e64fdfea3 100644 --- a/financial/amortization_table.py +++ b/financial/amortization_table.py @@ -79,7 +79,8 @@ def amortization_table( payments = years * 12 interest_rate /= 12 payment_amount = payment(principal, interest_rate, payments) - amor_table = pd.DataFrame(index=range(0, payments + 1), columns=["Payment", "Principal", "Interest", "Remaining"], dtype="float", data=0) + amor_table = pd.DataFrame(index=range(payments + 1), + columns=["Payment", "Principal", "Interest", "Remaining"], dtype="float", data=0) amor_table["Payment"][1:] = payment_amount amor_table["Remaining"][0] = principal From dad5fd5a42e8a902aa1bf2fe4bcfd80eb5a5ff1c Mon Sep 17 00:00:00 2001 From: Marks Mac Date: Wed, 17 Apr 2024 23:19:14 -0400 Subject: [PATCH 9/9] fixed ruff error PIE808 Unnecessary `start` argument in `range` --- financial/amortization_table.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/financial/amortization_table.py b/financial/amortization_table.py index a5e7f55debe8..a23f757698f1 100644 --- a/financial/amortization_table.py +++ b/financial/amortization_table.py @@ -80,7 +80,7 @@ def amortization_table( interest_rate /= 12 payment_amount = payment(principal, interest_rate, payments) amor_table = pd.DataFrame( - index=range(0, payments + 1), + index=range(payments + 1), columns=["Payment", "Principal", "Interest", "Remaining"], dtype="float", data=0,