Compound interest with deposits in Python - python

I am working on an assignment for a comp sci class. I feel like I am really close but I cant quite get to the answer. Basically the assignment is a compound interest calculator, what I am trying to do that makes it more complicated is adding deposits to the initial investment and allowing for someone to stop paying into it at one point, but collect it at a different point. The example is ", a user may already have
saved $10,000 in their account when they start their retirement calculation. They intend to save
another $1000 per year for the next 10 years at which point they will stop making any additional
deposits into their account. However, they may be 20 years away from retirement. Your program
should be able to account for these varying inputs and calculate the correct future value of their
account at retirement"
Here is my code so far:
def main():
print("Welcome to Letmeretire.com's financial retirement calculator!")
import random
num = random.randrange(10000)
principal = int(input("How much are you starting with for your retirement savings?"))
deposit = int(input("How much money do you plan to deposit each year?"))
interest = int(input("How much interest will your account accrue annually"))
time = int(input("Please enter the number of years that you plan to deposit money for."))
time_till_retirement = int(input("How long until you plan on retiring? (Please enter this amount in years)"))
t = time + 1
APR = interest/100
R = ((1+APR/12)**12)-1
DR = deposit/R
DRT = deposit/(R*(1+R)**time)
PV = principal+(DR-DRT)
future_value = PV*((1+APR/12)**12*time)
if time < time_till_retirement:
time1 = (time_till_retirement-time)
future = future_value*((1+APR/12)**12*time1)
else:
future = future_value
for i in range(1, t):
print("After " + str(i) + " years you will have "+ str(future) + " saved!")
main()
I would like the output to look like this:
Enter annual deposit: 1000
Enter interest rate: 12
Enter number of years until retirement: 10
What's the current balance of your account: 5000
How many years will you make your annual deposit? 5
After 1 year, you have: $ 6720.0
After 2 years, you have: $ 8646.4
After 3 years, you have: $ 10803.97
After 4 years, you have: $ 13220.44
After 5 years, you have: $ 15926.9
After 6 years, you have: $ 17838.13
After 7 years, you have: $ 19978.7
After 8 years, you have: $ 22376.14
After 9 years, you have: $ 25061.28
After 10 years, you have: $ 28068.64
But what Im getting is this:
Welcome to Letmeretire.com's financial retirement calculator!
How much are you starting with for your retirement savings?5000
How much money do you plan to deposit each year?1000
How much interest will your account accrue annually12
Please enter the number of years that you plan to deposit money for.5
How long until you plan on retiring? (Please enter this amount in years)10
After 1 years you will have 271235.9643776919 saved!
After 2 years you will have 271235.9643776919 saved!
After 3 years you will have 271235.9643776919 saved!
After 4 years you will have 271235.9643776919 saved!
After 5 years you will have 271235.9643776919 saved!

I think you need to ensure the formula is correct:
FV(t) = 5000 * (1.12 ** t) + 1000 * (1.12 ** t) + 1000 * (1.12 **
(t-1)) + ... + 1000 * 1.12
= 5000 * (1.12 ** t) + 1000 * (1.12 ** t - 1) * 1.12 / 0.12
Then we can define a function:
def fv(t, initial, annual, interest_rate):
return initial * (1+interest_rate) ** t + \
annual * (1+interest_rate) * ((1+interest_rate) ** t - 1) / interest_rate
Test:
print fv(1, 5000, 1000, 0.12)
print fv(3, 5000, 1000, 0.12)
print fv(5, 5000, 1000, 0.12)
Yields:
6720.0
10803.968
15926.8974592
Till now the main work is done, I think you can handle the rest.

In most cases, I would prefer Ray's analytic solution - plug the values into a formula, get the final answer, instead of iterating year by year.
However, in this case, you want the values for each year, so you may as well iterate after all:
import sys
# Python 2/3 compatibility shim
if sys.hexversion < 0x3000000:
rng = xrange
inp = raw_input
else:
rng = range
inp = input
def getter_fn(datatype):
if datatype == str:
return inp
else:
def fn(prompt=''):
while True:
try:
return datatype(inp(prompt))
except ValueError:
pass
return fn
get_float = getter_fn(float)
get_int = getter_fn(int)
def main():
print("Welcome to Letmeretire.com's financial retirement calculator!")
principal = get_float("Initial investment amount? ")
periods = get_int ("How many years will you make an annual deposit? ")
deposit = get_float("Annual deposit amount? ")
apr = get_float("Annual interest rate (in percent)? ") / 100
retirement = get_int ("Years until retirement? ")
deposits = [deposit] * periods
no_deposits = [0.] * (retirement - periods)
amount = principal
for yr, d in enumerate(deposits + no_deposits, 1):
amount = (amount + d) * (1. + apr)
print('After {:>2d} year{} you have: $ {:>10.2f}'.format(yr, 's,' if yr > 1 else ', ', amount))
if __name__ == '__main__':
main()
which results in
Welcome to the Letmeretire.com financial retirement calculator!
Initial investment amount? 5000
How many years will you make an annual deposit? 5
Annual deposit amount? 1000
Annual interest rate (in percent)? 12
Years until retirement? 10
After 1 year, you have: $ 6720.00
After 2 years, you have: $ 8646.40
After 3 years, you have: $ 10803.97
After 4 years, you have: $ 13220.44
After 5 years, you have: $ 15926.90
After 6 years, you have: $ 17838.13
After 7 years, you have: $ 19978.70
After 8 years, you have: $ 22376.14
After 9 years, you have: $ 25061.28
After 10 years, you have: $ 28068.64

FV(t) = 5000 * (1.12 ** t) + 1000 * (1.12 ** t) + 1000 * (1.12 ** (t-1)) + ... + 1000 * 1.12 = 5000 * (1.12 ** t) + 1000 * (1.12 ** t - 1) * 1.12 / 0.12
I have a similar problem like the one mentioned above but I do not get why the second part of the equation(formula) after the second equal sign?
Also is there not another way of doing this more concise without having to code "FV(t) = 5000 * (1.12 ** t) + 1000 * (1.12 ** t) + 1000 * (1.12 ** (t-1))" this part several times?

Related

This should calculate how long it takes for an investment to double. Return values are way too long. I am required to use a while loop

This program is meant to get input from the user, initial investment and apy and is meant to return the number of years it takes for the investment to double. I've been testing 100 for the principal and .05 for the apy but the result I'm getting is over 14,000 years. This value should calculate to a little over 15 years. I can seem to find the issue and could use some pointers.
def main():
print("This program calculates the amount of time it takes for an investment to double")
principal = eval(input("What is the initial investment amount? "))
apy = eval(input("What is the annual interest rate? "))
years = 0
while principal < (2 * principal):
principal = principal * (1 + apy)
years = years + 1
print("It will take", years, "years for your investment to double." )
main()
when you increase the pricipal in every loop you also increase 2 times principal
as x+1 < (x+1)* 2
And you have your infinite loop in at least theory
But python stops at ∞ < 2 * ∞ and that is correct as 2 * ∞ Is ∞ and makes the equation false and ends the loop
Add another variable.
def main():
print("This program calculates the amount of time it takes for an investment to double")
principal = eval(input("What is the initial investment amount? "))
apy = eval(input("What is the annual interest rate? "))
years = 0
resultinv = principal
while resultinv < (2 * principal):
resultinv = resultinv * (1 + apy)
years = years + 1
print("It will take", years, "years for your investment to double." )
main()

Yearly Interest on house and deposit

Suppose you currently have $50,000 deposited into a bank account and the account pays you a constant interest rate of 3.5% per year on your deposit. You are planning to buy a house with the current price of $300,000. The price will increase by 1.5% per year. It still requires a minimum down payment of 20% of the house price.
Write a while loop to calculate how many (integer) years you need to wait until you can afford the down payment to buy the house.
m = 50000 #money you have
i = 0.035 #interest rate
h = 300000 #house price
f = 0.015 #amount house will increase by per year
d= 0.2 #percent of down payment on house
y = 0 #number of years
x = 0 #money for the down payment
mn = h*d #amount of down payment
while m <= mn:
m = (m+(m*i)) #money you have plus money you have times interest
y = y + 1 #year plus one
mn = mn +(h*f*y)
print(int(y))
The answer you should get is 10.
I keep getting the wrong answer, but I am not sure what is incorrect.
You can simplify the code by using the compound interest formula.
def compound_interest(amount, rate, years):
return amount * (rate + 1) ** years
while compound_interest(m, i, y) < d * compound_interest(h, f, y):
y += 1
If you are allowed to do without the while loop, you can resolve the inequality after the years y.
So you get this code snippet:
import math
base = (i + 1) / (f + 1)
arg = (d * h) / m
y = math.ceil(math.log(arg, base))

CS1301xl Computing in Python I practice exam mortgage problem’s formula may be somehow incorrect?

I’d like to know whether this is the formula problem or my problem.
I’ve looked up various formulas online. This is edx’s formula
Cost * Number of Months * Monthly Rate / 1 - ((1 + Monthly Rate) ** Number of Months)
cost = 150000
rate = 0.0415
years = 15
rate = rate / 12
years = years * 12
house_value = cost * years * rate
house_value2 = (1 + rate) ** years
house_value = house_value / house_value2
house_value = round(house_value, 2)
print("The total cost of the house will be $" + str(house_value))
It should print “The total cost of the house will be $201751.36” but it prints “The total cost of the house will be $50158.98”
Going off your answer with the correct formula, you can simplify the code quite a bit and add more readability by doing the following:
# This is a function that lets you calculate the real mortgage cost over
# and over again given different inputs.
def calculate_mortgage_cost(cost, rate, years):
# converts the yearly rate to a monthly rate
monthly_rate = rate / 12
# converts the years to months
months = years * 12
# creates the numerator to the equation
numerator = cost * months * monthly_rate
# creates the denominator to the equation
denominator = 1 - (1 + monthly_rate) ** -months
#returns the calculated amount
return numerator / denominator
# sets the calculated amount
house_value = calculate_mortgage_cost(150000, 0.0415, 15)
# This print statement utilizes f strings, which let you format the code
# directly in the print statement and make rounding and conversion
# unnecessary. You have the variable inside the curly braces {}, and then
# after the colon : the comma , adds the comma to the number and the .2f
# ensures only two places after the decimal get printed.
print(f"The total cost of the house will be ${house_value:,.2f}")
I have now solved this. This is the edit.
cost = 150000
rate = 0.0415
years = 15
house_value = cost * (years * 12) * (rate / 12)
house_value2 = 1 - (1 + (rate / 12)) ** -years
house_value = house_value / house_value2
house_value = round(house_value, 2)
print("The total cost of the house will be $" + str(house_value))
I have added a negative sign to the years.

How to loop through a percentage investment?

I'm working on this simple task where a financial advisor suggests to invest in a stock fund that is guaranteed to increase by 3 percent over the next five years.
Here's my code:
while True:
investment = float(input('Enter your initial investment: '))
if 1000 <= investment <= 100000:
break
else:
print("Investment must be between $1,000 and $100,000")
#Annual interest rate
apr = 3 / 100
amount = investment
for yr in range(5):
amount = (amount) * (1. + apr)
print('After {:>2d} year{} you have: $ {:>10.2f}'.format(yr, 's,' if yr > 1 else ', ', amount))
You got it. The only problem is that apr is runing integer math. Use floating point numbers instead, so apr does not round to zero:
apr = 3.0 / 100.0
By changing that line your program will probably work
This is the whole code changes (as requested in comments):
while True:
investment = float(input('Enter your initial investment: '))
if 1000 <= investment <= 100000:
break
else:
print("Investment must be between $1,000 and $100,000")
#Annual interest rate
apr = 3.0 / 100.0
amount = investment
for yr in range(5):
amount = (amount) * (1. + apr)
print('After {:>2d} year{} you have: $ {:>10.2f}'.format(yr, 's,' if yr > 1 else ', ', amount))
The output I get is:
Enter your initial investment: 1002
After 0 year, you have: $ 1032.06
After 1 year, you have: $ 1063.02
After 2 years, you have: $ 1094.91
After 3 years, you have: $ 1127.76
After 4 years, you have: $ 1161.59
new_a=1000
yi = .03
for yr in range(1,6):
new_a = new_a+new_a*yi
print('After {:>2d} year{} you have: $ {}'.format(yr, 's,' , new_a))

Python: smarter way to calculate loan payments

How to calculate the monthly fee on a loan?
Given is:
a: an amount to loan.
b: the loan period (number of months).
c: the interest rate p.a. (interests is calculated and added every month, 1/12 of the interest is added. So if the interest is on 12%, 1% interest is added every month).
d: the amount of money owed after the end of the period.
This problem is a bit different than the usual since, the goal is not to have the loan payed after the loan period has ended, but to still owe an amount that is given. I have been able to find an algorithm so solve the problem if I wanted to pay the entire amount, but it will of course not work for this problem where the goal is to end up owing a given amount rather than not owing anything.
I managed to make a solution to this problem by starting with an guess and then keep on improving that guess until it was close enough. I wondered however, if there is a better way to simply calculate this, rather than just guessing.
Edit: Here's how I'm doing it now.
def find_payment(start, end, months, interest):
difference = start
guess = int(start / months * interest)
while True:
total = start
for month in range(1, months + 1):
ascribe = total * interest / 12
total = total + ascribe - guess
difference = total - end
# See if the guess was good enough.
if abs(difference) > start * 0.001:
if difference < 0:
if abs(difference) < guess:
print "payment is %s" % guess
return evolution(start, guess, interest, months)
else:
mod = int(abs(difference) / start * guess)
if mod == 0:
mod = 1
guess -= mod
else:
mod = int(difference / start * guess)
if mod == 0:
mod = 1
guess += mod
else:
print "payment is %s" % guess
return evolution(start, guess, interest, months)
evolution is just a function that displays how the loan would look like payment for payment and interest for interest, summing up total amount of interest paid etc.
An example would be if I wanted to find out the monthly payments for a loan starting with $100k and ending at $50k with an interest of 8% and a duration of 70 months, calling
>>> find_payment(100000, 50000, 70, 0.08)
payment is 1363
In the above case I would end up owing 49935, and I went through the loop 5 times. The amount of times needed to go through the loop depends on how close I want to get to the amount and it varies a bit.
This is a basically a mortgage repayment calculation.
Assuming that start is greater than end, and that interest is between 0 and 1 (i.e. 0.1 for 10% interest)
First consider the part of the payment you want to pay off.
Principal = start - end
The monthly payment is given by:
pay_a = (interest / 12) / (1 - (1+interest/12) ^ (-months))) * Principal
You then need to consider the extra interest. Which is just equal to the remaining principal times the monthly interest
pay_b = interest / 12 * end
So the total payment is
payment = (interest / 12) * (1 / (1 - (1+interest/12) ^ (-months))) * Principal + end)
On the example you gave of
Start: 100000
End: 50000
Months: 70
Interest: 8%
pay_a = 896.20
pay_b = 333.33
Payment = 1229.54
When I tested these values in Excel, after 70 payments the remaing loan was 50,000. This is assuming you pay the interest on the notional before the payment is made each month.
Perhaps the easiest way to think about this is to split the loan in two parts, one part which is to be repaid in full and another part where you don't pay off anything. You have already computed the monthly fee for the first part.
You can keep paying the interest of every month; then, you will alway owe the same amont.
Owe_1 = a
Int_2 = Owe_1*(InterestRate/12)
Pay_2 = Int_2
Owe_2 = Owe_1 + Int_2 - Pay_2 # ==> Owe_1 + Int_2 - Int_2 = Owe_1
Int_3 = Owe_2*(InterestRate/12)
Pay_3 = Int_3
Owe_3 = Owe_2 + Int_3 - Pay_3 # ==> Owe_2 + Int_3 - Int_3 = Owe_2 = Owe_1
python code to calculate emi
class EMI_CALCULATOR(object):
# Data attributes
# Helps to calculate EMI
Loan_amount = None # assigning none values
Month_Payment = None # assigning none values
Interest_rate = None #assigning none values
Payment_period = None #assigning none values
def get_loan_amount(self):
#get the value of loan amount
self.Loan_amount = input("Enter The Loan amount(in rupees) :")
pass
def get_interest_rate(self):
# get the value of interest rate
self.Interest_rate = input("Enter The Interest rate(in percentage(%)) : ")
pass
def get_payment_period(self):
# get the payment period"
self.Payment_period = input("Enter The Payment period (in month): ")
pass
def calc_interest_rate(self):
# To calculate the interest rate"
self.get_interest_rate()
if self.Interest_rate > 1:
self.Interest_rate = (self.Interest_rate /100.0)
else:
print "You have not entered The interest rate correctly ,please try again "
pass
def calc_emi(self):
# To calculate the EMI"
try:
self.get_loan_amount() #input loan amount
self.get_payment_period() #input payment period
self.calc_interest_rate() #input interest rate and calculate the interest rate
except NameError:
print "You have not entered Loan amount (OR) payment period (OR) interest rate correctly,Please enter and try again. "
try:
self.Month_Payment = (self.Loan_amount*pow((self.Interest_rate/12)+1,
(self.Payment_period))*self.Interest_rate/12)/(pow(self.Interest_rate/12+1,
(self.Payment_period)) - 1)
except ZeroDivisionError:
print "ERROR!! ZERO DIVISION ERROR , Please enter The Interest rate correctly and Try again."
else:
print "Monthly Payment is : %r"%self.Month_Payment
pass
if __name__ == '__main__':# main method
Init = EMI_CALCULATOR() # creating instances
Init.calc_emi() #to calculate EMI
for more info visit : https://emilgeorgejames.wordpress.com/2015/07/29/python-emi-equated-monthly-installment-calculator/
This rather a detailed way but will give the whole payment as well
# Mortgage Loan that gives the balance and total payment per year
# Function that gives the monthly payment
def f1 (principle,annual_interest_rate,duration):
r = annual_interest_rate/1200
n = duration*12
a=principle*r*((1+r)**n)
b= (((1+r)**n)- 1)
if r > 0 :
MonthlyPayment = (a/b)
else :
MonthlyPayment = principle/n
return MonthlyPayment
# Function that gives the balance
def f2 (principle,annual_interest_rate,duration,number_of_payments):
r = annual_interest_rate/1200
n = duration*12
a= ((1+r)**n)
b= ((1+r)**number_of_payments)
c= (((1+r)**n)-1)
if r > 0 :
RemainingLoanBalance = principle*((a-b)/c)
else :
RemainingLoanBalance = principle*(1-(number_of_payments/n))
return RemainingLoanBalance
# Entering the required values
principle=float(input("Enter loan amount: "))
annual_interest_rate=float(input("Enter annual interest rate (percent): "))
duration=int(input("Enter loan duration in years: "))
# Output that returns all useful data needed
print ("LOAN AMOUNT:",principle,"INTEREST RATE (PERCENT):",annual_interest_rate)
print ("DURATION (YEARS):",duration,"MONTHLY PAYMENT:",int(f1(principle,annual_interest_rate,duration)))
k=duration+1
BALANCE=principle
total=0
for i in range (1,k):
TOTALPAYMENT= f1(BALANCE,annual_interest_rate,k-i)*12
total+= TOTALPAYMENT
BALANCE= f2(principle,annual_interest_rate,duration,12*i)
print("YEAR:",i,"BALANCE:",int(BALANCE),"TOTAL PAYMENT",int(total))
How about this?
def EMI_calc(principle, rate, time, frequency):
return (principle / ((1-((1+(rate/frequency))**(-1*(time*frequency))))/(rate/frequency)))
print("""
----- Welcome to EMI programe for Python -----
""")
print("\n You have chosen to know the EMI for Loan.\n")
input('\nTo Continue Press ENTER --- to ABORT Press ctrl+c > \n')
print("\nPlease Enter amount of Loan to be taken: >\n")
principle = int(input())
print("\nEnter rate of interst (%): >\n")
rate = float(input())/100
print("\nEnter Term (Years): >\n")
time = float(input())
print("\nPlease enter the frequency of installments) : >\n")
frequency = int(input())
EMI = round(EMI_calc(principle, rate, time, frequency),0)
print("""
---------------------------------------------------------------------
""")
print(f"""
The EMI for Loan of Rs.{principle};
at interest rate of {rate*100} % for {time} years;
would be: Rs.""", EMI)
print("""
---------------------------------------------------------------------
""")
Here is a code snippet using numpy functions. This shows you the payment, principal, interest, instalment and total_amount each month. Run it and see the output. You can also check the syntax for Excel "IPMT()" and "PPMT()" functions for more explanation of the arguments.
https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.pmt.html#numpy.pmt
import math
import numpy as np
rate = 0.08
start_amount = 100000.0
end_amount = 50000.0
diff_amount = start_amount - end_amount
# nr_years = 4
payment_frequency = int (12)
nr_months = 70 # = nr_years * payment_frequency
per_np = np.arange (nr_months) + 1 # +1 because index starts with 1 here
pay_b = rate / payment_frequency * end_amount
ipmt_np = np.ipmt (rate / payment_frequency, per_np, nr_months, diff_amount) - pay_b
ppmt_np = np.ppmt (rate / payment_frequency, per_np, nr_months, diff_amount)
for payment in per_np:
idx = payment - 1
principal = math.fabs (ppmt_np [idx])
start_amount = start_amount - principal
interest = math.fabs (ipmt_np [idx])
instalment = principal + interest
print payment, "\t", principal, "\t", interest, "\t\t", instalment, "\t\t", start_amount
print np.sum (ipmt_np)

Categories

Resources