|
| 1 | +""" |
| 2 | +Program to calculate the amortization amount per month, given |
| 3 | +- Principal borrowed |
| 4 | +- Rate of interest per annum |
| 5 | +- Years to repay the loan |
| 6 | +
|
| 7 | +Wikipedia Reference: https://en.wikipedia.org/wiki/Equated_monthly_installment |
| 8 | +""" |
| 9 | + |
| 10 | + |
| 11 | +def equated_monthly_installments( |
| 12 | + principal: float, rate_per_annum: float, years_to_repay: int |
| 13 | +) -> float: |
| 14 | + """ |
| 15 | + Formula for amortization amount per month: |
| 16 | + A = p * r * (1 + r)^n / ((1 + r)^n - 1) |
| 17 | + where p is the principal, r is the rate of interest per month |
| 18 | + and n is the number of payments |
| 19 | +
|
| 20 | + >>> equated_monthly_installments(25000, 0.12, 3) |
| 21 | + 830.3577453212793 |
| 22 | + >>> equated_monthly_installments(25000, 0.12, 10) |
| 23 | + 358.67737100646826 |
| 24 | + >>> equated_monthly_installments(0, 0.12, 3) |
| 25 | + Traceback (most recent call last): |
| 26 | + ... |
| 27 | + Exception: Principal borrowed must be > 0 |
| 28 | + >>> equated_monthly_installments(25000, -1, 3) |
| 29 | + Traceback (most recent call last): |
| 30 | + ... |
| 31 | + Exception: Rate of interest must be >= 0 |
| 32 | + >>> equated_monthly_installments(25000, 0.12, 0) |
| 33 | + Traceback (most recent call last): |
| 34 | + ... |
| 35 | + Exception: Years to repay must be an integer > 0 |
| 36 | + """ |
| 37 | + if principal <= 0: |
| 38 | + raise Exception("Principal borrowed must be > 0") |
| 39 | + if rate_per_annum < 0: |
| 40 | + raise Exception("Rate of interest must be >= 0") |
| 41 | + if years_to_repay <= 0 or not isinstance(years_to_repay, int): |
| 42 | + raise Exception("Years to repay must be an integer > 0") |
| 43 | + |
| 44 | + # Yearly rate is divided by 12 to get monthly rate |
| 45 | + rate_per_month = rate_per_annum / 12 |
| 46 | + |
| 47 | + # Years to repay is multiplied by 12 to get number of payments as payment is monthly |
| 48 | + number_of_payments = years_to_repay * 12 |
| 49 | + |
| 50 | + return ( |
| 51 | + principal |
| 52 | + * rate_per_month |
| 53 | + * (1 + rate_per_month) ** number_of_payments |
| 54 | + / ((1 + rate_per_month) ** number_of_payments - 1) |
| 55 | + ) |
| 56 | + |
| 57 | + |
| 58 | +if __name__ == "__main__": |
| 59 | + import doctest |
| 60 | + |
| 61 | + doctest.testmod() |
0 commit comments