So I am attempting to implement a bisection search algorithm in Python that returns an "optimal" savings rate.
I've tried creating several different functions, and I don't understand why the program gets caught in an infinite loop. I do know that the abs(current_savings - down_payment) is what causes the recursive infinite loop but I do not know why.
First things first, this doesn't really explain why my program doesn't work but here goes:
At the end of each month I earn interest on current savings, which is
applied first, and then I receive my monthly salary, which is just
1/12 of my annual salary.
I am attempting to find the best rate to apply to my monthly salary, to then add to my current savings.
My first function simply checks to see if one's salary is high enough to ever save for the 250K down payment. If their salary is not high enough, it prints that it is not adequate and returns False.
My second function attempts to find the best rate ("portion saved"), or the best rate to save of monthly salary in order to fall within 100 dollars of the down_payment. In addition, I must record the number of "steps" my bisection search function takes to find the optimal rate.
Here is the code:
#Givens
annual_salary = 150000
initial_salary = annual_salary
interest_rate = float(0.04/12.0)
down_payment = float(250000.0)
semi_annual_raise = 0.07
#Bisect-search
low = float(0.0)
high = float(10000.0)
portion_saved = float((low+high)/2)
current_savings = 0
months = 0
steps = 0
def isPossible(annual_salary):
count = 0
current_savings = 0
while count < 36:
current_savings += (current_savings*interest_rate) + (annual_salary/12)
count += 1
if count % 6 == 0:
annual_salary += (annual_salary*semi_annual_raise)
if current_savings < down_payment:
print("It is not possible to pay the down payment in three years.")
return False
else:
return True
def bisearch(initial_salary,interest_rate,down_payment,semi_annual_raise,low,high,portion_saved,steps):
current_savings = 0
months = 0
while abs(current_savings - down_payment) > 100.0:
months = 0
current_savings = 0
while months < 36:
current_savings = current_savings + (initial_salary*interest_rate)
current_savings = current_savings + (initial_salary/12*portion_saved/10000.0)
months += 1
if months % 6 == 0:
initial_salary += (initial_salary*semi_annual_raise)
steps += 1
if current_savings > down_payment:
high = portion_saved
else:
low = portion_saved
portion_saved = ((low+high)/2.0)
print("Best saving rate: ", (portion_saved/10000.0))
print("Steps in bisection search: ", steps)
if isPossible(annual_salary) == True:
bisearch(initial_salary,interest_rate,down_payment,semi_annual_raise,low,high,portion_saved,steps)
And the test cases:
Note: the number of bisection search steps doesn't have to be the same, but the rate should be the same
Test Case 1
Enter the starting salary: 150000
Best savings rate: 0.4411
Steps in bisection search: 12
Test Case 2
Enter the starting salary: 300000
Best savings rate: 0.2206
Steps in bisection search: 9
If anyone could help me out I would greatly appreciate it, been at this for hours trying to come up with a fix.
I was confused in the same problem and finally found a solution. Try resetting initial_salary back to annual_salary inside the first while loop within your bisection function, else that would just keep on increasing every time you hit six months on the inner loop. Does that work?
Related
The exercise program is from MIT OpenCourseWare. It asks me to calculate how many months can a down payment is fulfilled, with three portion:1. investment. 2. Part of the salary. 3. The salary gains a semi-year raise: this should only happen after the 6th, 12th, 18th month, and so on.
Here is my work:
current_saving = 0
annual_salary = int(input("Enter your annual salary:"))
portion_saved = float(
input("Enter the percent of your salary to save, as a decimal:"))
total_cost = int(input("Enter the cost of your dream home:"))
semi_annual_raise = float(input("Enter the semi- annual raise, as a decimal:"))
portion_down_payment = total_cost * 0.25
months = 0
while current_saving <= portion_down_payment:
if months % 6 !=1:
current_saving = current_saving * 0.04 /12 + annual_salary/12 * portion_saved + current_saving
months +=1
else:
annual_salary = annual_salary*(1+semi_annual_raise)
current_saving = current_saving * 0.04 /12 + annual_salary/12 * portion_saved + current_saving
months +=1
print(months)
This is my own run and sample test provided by an official document by MIT OpenCourseWare.
My own run
Please help me, thank you! I will get to interact as soon as possible.
Your issue is in the computation of every 6 month with the modulo. What you are doing is that you increase the salary everytime the month is in the form 6n + 1. Which means you increase the salary on month 1, 7, 13 etc. (as your index starts at zero, you are increasing the salary after the first month).
So you have a raise too early and the other ones too late.
Note: You have the same code in you if and else part, put it outside for easier to read and maintain code.
while current_saving <= portion_down_payment:
# Apply the raise every time the month is a multiple of 6 (as you start from 0, you need the +1 here)
if (months + 1) % 6 == 0:
annual_salary = annual_salary*(1+semi_annual_raise)
current_saving = current_saving * 0.04 /12 + annual_salary/12 * portion_saved + current_saving
months +=1
I am trying to calculate the end balance earned in one year based on $1000 monthly contributions and $0 starting balance on a 5% annual return.
So each year I should be contributing $12,000 and the interest that I earn should have equaled $322.58 making the end balance $12,322.58.
Here is my code so far but the end balance that I am getting is only 12050.
count = 0
current_savings = 0
r = 0.05
while count < 12:
current_savings += 1000
Monthly_interest = (current_savings*r)/12
Final_amount = current_savings + Monthly_interest
count += 1
print(Final_amount)
Note that most banks will compute the interest BEFORE adding the new deposit. You'll have to decide what order is right for you.
current_savings = 0
r = 0.05
for _ in range(12):
current_savings += 1000
Monthly_interest = (current_savings*r)/12
current_savings += Monthly_interest
print(current_savings)
I am new to programming and I am stuck with one of my programming assignments. please evaluate the given code and let me know the mistakes I have made. the code is expected to output the number of months required to save up to buy a new house...
total_cost = float(input("cost of house:"))
portion_down_payment= 0.25
current_savings = 0.0
r = .04
annual_salary = float(input("your annual salary is:"))
portion_saved = float(input("portion of income saved:"))
months = 0
while current_savings <= portion_down_payment*total_cost:
current_savings = current_savings*r/12 + portion_saved*annual_salary/12
months = months+1
print("To buy your dream house you gotta wait for",months, "months")
You likely want to add to your savings, not overwrite them:
current_savings = current_savings*r/12 + portion_saved*annual_salary/12
should be:
current_savings = current_savings + current_savings*r/12 + portion_saved*annual_salary/12
I'm new to programming, so any experienced programmer will probably be able to answer this question easily.
I am trying to write a Python function which will tell me what percentage compound interest is necessary to end up with a specific sum. For example, if I deposited $100, and after 17 years of compound interest I have $155, the function will tell me what percentage interest was I receiving. I wrote the following function, with 'start' being the original sum deposited, 'finish' the sum I ended up with, and 'years' the number of years it accrued interest. I designed it to give a result in decimal points, for example for 1.5% it will show 0.015.
Here's the code I wrote:
def calculate(start, finish, years):
num = start
percentage = 0
while num < finish:
percentage += 0.000001
for year in range(years):
num += num * percentage
return percentage
print(calculate(12000, 55000, 100))
It's giving an output of 0.00017499999999999962 (i.e. 0.017499999999999962%), which is totally wrong.
I can't understand where I've gone wrong.
You need to reset the num=start after every time you guess a percentage.
def calculate(start, finish, years):
num = start
percentage = 0
while num < finish:
num = start
percentage += 0.000001
for year in range(years):
num += num * percentage
return percentage
print(calculate(12000, 55000, 100))
However, you'd probably be better off solving this problem by simply re-arranging the compound interest formula:
A=P*(1+r/n)^(nt)
(where A = Final balance, P = Initial balance, r = Interest rate, n = number of times interest applied per time period, and t = number of time periods elapsed.)
The rearrangement gives:
r=n((A/P)^(1/nt)-1)
and putting this into python gives us:
def calculate(start, finish, years):
num = ((finish / start)**(1/years))-1
return num
print(calculate(12000.0, 55000.0, 100.0))
which gives the expected results.
You can do a one-liner if you understand how compound interest works
def calculate(start, finish, years):
return (finish/start)**(1/years) - 1
print(calculate(12000, 55000, 100) * 100, '%')
I'm attempting to take a starting balance and increase the value by 5% each month. I then want to feed this new balance back into the equation for the next month. I've attempted to do this using a while loop but it doesn't seem to be feeding the new balance back in.
I'm using 60 months (5 years) for the equation but this can be altered
counter = 1
balance = 1000
balance_interest = balance * .05
while counter <= 60:
new_monthly_balance = (balance + balance_interest)*(counter/counter)
print(new_monthly_balance)
balance = new_monthly_balance
counter += 1
You never change balance_interest in the loop.
What do you intend to do with *(counter/counter)? This merely multiplies by 1.0, which is a no-op.
while counter <= 60:
balance *= 1.05
print(balance)
counter += 1
Better yet, since you know how many times you want to iterate, use a for:
for month in range(60):
balance *= 1.05
print(balance)
BTW, just what sort of finance has a constant 5% monthly increase???