Why am I printing different values? - python

What's different between lines 16 and 17?
#user input
annual_salary = float(input("Enter your annual salary: "))
portion_saved = float(input("Enter the percent of your salary to save, as a decimal: "))
total_cost = float(input("Enter the cost of your dream home: "))
#static vars
portion_down_payment = total_cost*.25
monthly_salary = annual_salary/12
r = .04 #annual rate of return
months_to_save = 0
current_savings = 0
investment_return = current_savings * r / 12
while current_savings < portion_down_payment:
#current_savings += (current_savings * r / 12) + (portion_saved * monthly_salary) # Line 16
current_savings += (investment_return) + (portion_saved*monthly_salary) # Line 17
months_to_save += 1
print("Number of months: ", months_to_save)
I tried running it through pythontutor and the variation happens on step 15 of execution, but I can't quite figure out what's different.

When you use current_savings += investment_return, it adds the same amount of interest to current_savings each time through the loop. That interest is equal to current_savings * r / 12 calculated before you started the loop.
But when you use current_savings += (current_savings * r / 12), you recalculate the interest each time through the loop. So the interest is calculated based on the current value of current_savings, which gets bigger each time the loop runs.
In other words, the first one calculates simple interest, and the second one calculates compound interest.

Related

Trying to find the best savings rate using Bisect search

I am trying to find a savings rate (rate_approx in my code) that will result in a savings (current_savings in code) over 36 months that is within $100 of the down payment (down_payment in code).
I'm running the for loop each time within the while loop to represent the growth of current_savings over the 36 month period. Then once that savings rate is adjusted depending on whether it is too high or too low, I want it to save a new savings_rate and try that on the 36 month period. So I reset current_savings to make sure it's not starting from the current_savings from the prior for loop run and try again.
house_price = float(1000000)
down_payment = float(house_price*0.25)
high = float(1)
low = float(0)
rate_approx = float((low + high)/2)
salary = float(150000)
monthly_salary = float(salary/12)
monthly_contribution = float(monthly_salary*rate_approx)
semi_annual_raise = float(1.07)
APR = float(1.04)
current_savings = 0
while abs(current_savings - down_payment) > 100:
current_savings = 0
for n in range(35):
current_savings = float((current_savings + monthly_contribution) * APR)
if n > 0 and n%6 == 0:
monthly_salary = float(monthly_salary * semi_annual_raise)
monthly_contribution = float(monthly_salary*rate_approx)
if current_savings < down_payment + 100:
current_savings = 0
low = rate_approx
rate_approx = (low + high)/2
print("low")
print("savings rate:",rate_approx)
elif current_savings > down_payment + 100:
current_savings = 0
high = rate_approx
rate_approx = (low + high)/2
print("high")
print("savings rate:",rate_approx)
else:
break
print("savings rate:", float(rate_approx))
print("savings:", float(current_savings))
Why does the program continue outputting smaller and smaller savings rates that are giving larger and larger final current_savings values?

Python: for loop with counter and scheduled increase in increase

Python Learner. Working on a recurring monthly deposit, interest problem. Except I am being asked to build in a raise after every 6th month in this hypothetical. I am reaching the goal amount in fewer months than I'm supposed to.
Currently using the % function along with += function
annual_salary = float(input("What is your expected Income? "))
portion_saved = float(input("What percentage of your income you expect to save? "))
total_cost = float(input("what is the cost of your dream home? "))
semi_annual_raise = float(input("Enter your expected raise, as a decimal "))
monthly_salary = float(annual_salary/12)
monthly_savings = monthly_salary * portion_saved
down_payment= total_cost*.25
savings = 0
for i in range(300):
savings = monthly_savings*(((1+.04/12)**i) - 1)/(.04/12)
if float(savings) >= down_payment:
break
if i % 6 == 0 :
monthly_salary += monthly_salary * .03
monthly_savings = monthly_salary * portion_saved
Thanks for the advice all. My code is getting clearer and I reached correct outputs! The problem was with how and when I was calculating interest. In the case of a static contribution I successfully used the formula for interest on a recurring deposit, here, the simpler move of calculating interest at each month was needed to work with the flow of the loop.
annual_salary = float(input("What is your expected Income? "))
portion_saved = float(input("What percentage of your income you expect to save? "))
total_cost = float(input("what is the cost of your dream home? "))
semi_annual_raise = float(input("Enter your expected raise, as a decimal "))
monthly_salary = float(annual_salary/12)
monthly_savings = monthly_salary * portion_saved
down_payment = total_cost*.25
savings = 0
month = 1
while savings < down_payment :
print(savings)
savings += monthly_savings
savings = savings * (1+(.04/12))
month += 1
if month % 6 == 0 :
monthly_salary += (monthly_salary * semi_annual_raise)
monthly_savings = (monthly_salary * portion_saved)
print("")
print("it will take " + str(month) + " months to meet your savings goal.")
Does something like this work for you? Typically, we want to use while loops over for loops when we don't know how many iterations the loop will ultimately need.
monthly_savings = 1.1 # saving 10% each month
monthly_salary = 5000
down_payment = 2500
interest = .02
savings = 0
months = 0
while savings < goal:
print(savings)
savings = (monthly_salary * monthly_savings) + (savings * interest)
months += 1
if months % 6 == 0 :
monthly_salary += monthly_salary * .03
print("Took " + str(months) + " to save enough")

Python bisection search not running and no error message. MIT edX

The problem is from the MIT edX Python Course 6.00.1 Problem Set 1 Part C. Here are the problems. Scroll to part C. I'm aware that there are countless questions asked about the edX course but none of them have really helped me. Whenever I run my bisection search code, nothing happens. No error message, nothing. Could someone help me find the issue in my code? Sorry if code is horribly inefficient, very new to python and programming.
#Python script for finding optimal saving rate of monthly salary in order to purchase 1M house in 36 months
salary = float(input("Enter salary: "))
total_cost = 1000000
salary_raise = 0.07 #semiannual raise rate
down = 0.25 * total_cost #downpayment
steps = 0
r = 0.04 #annual investments returns
low = 0 #low parameter for bisection search
high = 10000 #high parameter
current_savings = 0
while (current_savings <= (down - 100)) or (current_savings >= (down + 100)):
current_savings = 0
monthly_salary = salary/12
guess_raw = (high + low)/2
guess = guess_raw/10000.0
months = 0
steps += 1
while months < 36: #Finds end amount of money after 36 months based on guess
months += 1
multiple = months%6
monthly_savings = monthly_salary * guess
current_savings = current_savings + monthly_savings + current_savings*r/12
if multiple == 0:
monthly_salary += salary_raise * monthly_salary
if (current_savings >= (down - 100)) and (current_savings <= (down + 100)): #If the guess is close enough, print the rate and number of steps taken
print ("Best savings rate: ",guess)
print ("Steps in bisection search: ",steps)
break
elif current_savings < (down - 100): #If the guess is low, set the low bound to the guess
if guess == 9999:
print ("It is not possible to pay the down payment in three years.")
break
else:
low = guess
elif current_savings > (down + 100): #If the guess is high, set the high bound to the guess
high = guess

Fixed payment is returned as 0. Why? What corrections to make?

Now write a program that calculates the minimum fixed monthly payment needed in order pay off a credit card balance within 12 months. By a fixed monthly payment, we mean a single number which does not change each month, but instead is a constant amount that will be paid each month.
In this problem, we will not be dealing with a minimum monthly payment rate.
The following variables contain values as described below:
balance - the outstanding balance on the credit card
annualInterestRate - annual interest rate as a decimal
The program should print out one line: the lowest monthly payment that will pay off all debt in under 1 year, for example:
Lowest Payment: 180
Assume that the interest is compounded monthly according to the balance at the end of the month (after the payment for that month is made). The monthly payment must be a multiple of $10 and is the same for all months. Notice that it is possible for the balance to become negative using this payment scheme, which is okay. A summary of the required math is found below:
Monthly interest rate = (Annual interest rate) / 12.0
Monthly unpaid balance = (Previous balance) - (Minimum fixed monthly payment)
Updated balance each month = (Monthly unpaid balance) + (Monthly interest rate x Monthly unpaid balance)
Here is my code. I do not know where I'm going wrong:
balance = float(raw_input('enter the outsanding balance on your card'))
annualInterestRate = float(raw_input('enter the anual interest rate as a decimal'))
month = 0
checkBalance = balance
monthlyFixedPayment = 0
while checkBalance <= 0:
checkBalance = balance
monthlyFixedPayment += 10
while month <= 11:
monthlyInterestRate = annualInterestRate/12.0
monthlyUnpaidBalance = checkBalance - monthlyFixedPayment
checkBalance = monthlyUnpaidBalance + (monthlyInterestRate * monthlyUnpaidBalance)
print('lowest payment:' + str(monthlyFixedPayment))
I think this is the program you are looking for:
balance = 500
annualInterestRate = .5
checkBalance = balance
monthlyFixedPayment = 10
count = 0
while checkBalance > 0:
month = 0
while month <= 11 and checkBalance > 0:
count+=1
monthlyInterestRate = annualInterestRate/12.0
monthlyUnpaidBalance = checkBalance - monthlyFixedPayment
checkBalance = monthlyUnpaidBalance - (monthlyInterestRate * monthlyUnpaidBalance)
print "\t"+str(checkBalance)
month+=1
print checkBalance
print "lowest amount: "
print count*monthlyFixedPayment+checkBalance
I have left the print statements, so that you can see what is going on in each iteration.
Some problems i noticed in your code:
1) you were doing a monthlyFixedPayment += 10 that was changing the fixed payemnt. you are not supposed to change the fixed payment according to your problem definition.
2) you were doing a checkBalance = balance in each iteration of outer while loop. This was causing the calculated value to be resetted.
3) I have introduced a count variable to check how many times these decuctions were happening, as month was getting reset in each iteration.
while checkBalance <= 0: to while checkBalance >= 0:
Also, you need to increment month in the while month <= 11: loop.
You are going at it the hard way; there is an analytic solution for fixed_payment:
from math import ceil
def find_fixed_monthly_payment(balance, months, yearly_rate):
i = 1. + yearly_rate / 12.
im = i ** months
return balance * (im * (1. - i)) / (i * (1. - im))
def find_final_balance(balance, months, yearly_rate, fixed_payment):
i = 1. + yearly_rate / 12.
for _ in range(months):
# make payment
balance -= fixed_payment
# add interest
balance *= i
return balance
def get_float(prompt):
while True:
try:
return float(raw_input(prompt))
except ValueError:
# input could not be cast to float; try again
pass
def main():
balance = get_float("Please enter starting balance: ")
annual_rate = get_float("Annual interest rate (in percent): ") / 100.
fixed_payment = find_fixed_monthly_payment(balance, 12, annual_rate)
# round up to the nearest $10
fixed_payment = ceil(fixed_payment / 10.) * 10.
# double-check value of fixed_payment:
assert find_final_balance(balance, 12, annual_rate, fixed_payment ) <= 0., "fixed_payment is too low!"
assert find_final_balance(balance, 12, annual_rate, fixed_payment - 10.) > 0., "fixed_payment is too high!"
print("Lowest payment: ${:0.2f}".format(fixed_payment))
if __name__ == "__main__":
main()

Can't get this while loop right (python)

I am creating a program that will compute the lowest monthly payment to be paid for a credit card, given a certain credit card balance and interest rate. The time frame for the payoff is 12 months and the monthly payment has to be accurate down to the nearest penny, using bisection search.
I was able to get the answer, the problem is that I couldn't get my while loop to quit once the monthly payment was calculated to the nearest cent, so I had to make an infinite while loop that has a elif statement at the bottom of the while loop that quits for me. I was wondering if anyone can figure out what condition to give the while loop so it will quit on its own. Also I just started learning python a week ago, and want some advice on how good/bad my code is. Any ideas?
# random balance
balance = 999999
# random interest rate
annualInterestRate = 0.18
# assign balance to another variable that will undergo the testing
balance_tested = balance
# bounds of bisection search
low = (balance / 12.0)
high = ((balance * (1 + (annualInterestRate/12.0))**12)/12.0)
# start month
month = 1
monthlyPayment = (low + high) / 2.0 #Averages out the bounds to meet in the middle
while abs(balance_tested != 0): #While loop that I can't get right, just made it to run infinitely
balance_tested = balance #Resets balance being tested back to original balance
monthlyPayment = (low + high) / 2.0 #Bisection search recalculates
month = 1 #Month reset back to 1
while month <= 12: #Loops through all 12 months with the payments being made and interested getting added
balance_tested = (balance_tested - monthlyPayment)
balance_tested += (balance_tested * (annualInterestRate/12))
month += 1
print "Balance Remaining: %.20f" % balance_tested
if balance_tested < 0: #If the bisection search guesses to high, decreases the high bound
high = monthlyPayment
elif balance_tested <= 0.01: #Conditional statement that stops the testing if the balance gets paid off to the cent
break
else: #If bisection search guesses to low, increases low bound
low = monthlyPayment
print "Monthly Payment: %.2f" % monthlyPayment
print "Lowest Payment: %.2f" % monthlyPayment
Is there any reason you're using the break statement instead of just putting that as the condition for your while loop?
balance = 999999
annualInterestRate = 0.18
balance_tested = balance
low = (balance / 12.0) #Lower bound of bisection search
high = ((balance * (1 + (annualInterestRate/12.0))**12)/12.0)
month = 1
monthlyPayment = (low + high) / 2.0
while not (balance_tested <= 0.01):
balance_tested = balance
monthlyPayment = (low + high) / 2.0
month = 1
while month <= 12:
balance_tested = (balance_tested - monthlyPayment)
balance_tested += (balance_tested * (annualInterestRate/12))
month += 1
print "Balance Remaining: %.20f" % balance_tested
if balance_tested < 0:
high = monthlyPayment
else:
low = monthlyPayment
print "Monthly Payment: %.2f" % monthlyPayment
print "Lowest Payment: %.2f" % monthlyPayment
You already have the condition, why not put that for the while statement instead?
while not balance_tested <= 0.01:
# etc.
while abs(balance_tested != 0):
will stay in the loop if the balance_tested becomes negative. Make this
while balance_tested >= 0.1:
This will automatically handle the rounding when it drops below a penny.

Categories