Good morning, It's been a long time since I've played around with python and I seem to have forgotten a fair bit.
I'm trying to make a repayment credit card repayment calculator, I've got it to work but I'm trying to improve it. currently It works if I fill in a payment amount and that will tell me how long it will take to pay, However I would like to fill in number of payments instead and then it tell me how much I need to pay. This is my code, can someone please point me in the right direction
original_amount = amount = 500
repayment = 1
interest = 30.34
total_interest = 0
number_of_payments = 8
def calculate_interest(old_balance):
global interest
global monthly_interest
global total_interest
monthly_interest_percent = interest / 100 / 12
monthly_interest = old_balance * monthly_interest_percent
new_balance = old_balance + monthly_interest
total_interest += monthly_interest
return new_balance
count = 0
while amount > 0:
card_value = calculate_interest(amount)
amount = card_value - repayment
count += 1
if count > number_of_payments:
repayment += 1
I think your problem is this:
if count > number_of_payments:
repayment += 1
repayment is the amount you are repaying but I don't think that's what you want to increment here, you probably want to increment the number_of_payments.
Related
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
First of all, I feel sorry. This is my first time to use this website so I don't know the rules.
I try to show my attempt but I don't know how to do this. I just rewrite the code directly day by day and don't have the saved drafts. I use many methods to work out, but I am fresh to coding and as you know, I keep on going the MIT CS introduction course.
For this problem, I would like to paste the original link but you need to sign in the website first. So I google it and find a Github page which contained the problem. enter link description here The problem set has three problems and I have solved first two of them.
It's about how to calculate credit cards latest monthly payment, and must use bisection search.
I have worked out once. However, I can only do one bisection search and then minus 0.01 step to step to approach the result. I show you my code before, here is the only old version which I saved.
balance = 999999
annualInterestRate = 0.18
monthly_interest_rate = annualInterestRate /12.0
lower_bound = balance / 12.0
upper_bound = (balance * (1 + monthly_interest_rate)**12) / 12.0
def calculate_balance(balance, fixed):
month = 0
while month < 12:
balance = (balance - fixed) * (monthly_interest_rate + 1)
month += 1
return balance
while True:
if calculate_balance(balance, lower_bound) > 0:
lower_bound = (lower_bound + upper_bound) / 2
else:
skipped_answer = lower_bound
break
#print(skipped_answer)
while True:
#print(balance, skipped_answer)
if calculate_balance(balance, skipped_answer) < 0:
skipped_answer -= 0.01
else:
break
print(round(skipped_answer+0.01, 2))
Anyway, this code works fine but the grader of edx says my code takes too much time.
So I think out of dual-directed bisection search and it takes me hours again. But this is the limit of my ability. I have no ideas. Here's the code below.
balance = 999999
annualInterestRate = 0.18
monthly_interest_rate = annualInterestRate /12.0
lower_bound = balance / 12.0
upper_bound = (balance * (1 + monthly_interest_rate)**12) / 12.0
def calculate_balance(balance, fixed):
month = 0
while month < 12:
balance = (balance - fixed) * (monthly_interest_rate + 1)
month += 1
balance
return balance
while True:
if abs(calculate_balance(balance, lower_bound) - balance) > 0.01:
if calculate_balance(balance, lower_bound) > 0:
mark = lower_bound
lower_bound = (lower_bound + upper_bound) / 2
elif calculate_balance(balance, lower_bound) < 0:
upper_bound = lower_bound
lower_bound = mark
else:
break
print(lower_bound)
I don't know why it will be an infinite loop. And how to solve it? What's wrong?
Thinking this for hours. I have tried all the methods that I know.
I worked out all of the exercises by myself and takes me too much time. This time, I know I must get help of experienced people. There must be something I don't know.
I don't knew is it now of any interest to see my code that works very fast. It is little
bit different then yours:
balance = 999999
annualInterestRate = 0.18
payment = 0
lower = balance/12.0
upper = (balance*(1+annualInterestRate/12)**12)/12.0
lbalance = 0
while payment < balance :
oldbalance = lbalance
lbalance = balance
payment = round((lower + upper)/2,3)
for i in range(0,12):
unpaidBalance = lbalance - payment
interest = unpaidBalance * annualInterestRate / 12.0
lbalance = unpaidBalance + interest
if round(lbalance,2) == 0 or oldbalance == lbalance:
print('Lowest Payment: ' + str(payment))
break
elif lbalance > 0 :
lower = payment
else:
upper = payment
Why both of your codes in some cases use bisection and in some don't? This is the main problem.
All the best to all of you
Have a nice day
Below I have a piece of code which calculates credit card balance, but it doesn't work when balance has an extreme value (such as balance=9999999999below). It throws the code through an infinite loop. I have a couple of theories as to how to fix this flaw, but don't know how to move forward with them. Here's my code:
balance = 9999999999
annualInterestRate = 0.2
monthlyPayment = 0
monthlyInterestRate = annualInterestRate /12
newbalance = balance
month = 0
while newbalance > 0:
monthlyPayment += .1
newbalance = balance
for month in range(1,13):
newbalance -= monthlyPayment
newbalance += monthlyInterestRate * newbalance
month += 1
print("Lowest Payment:" + str(round(monthlyPayment,2)))
My theory is that
while newbalance > 0
is causing the infinite loop, because newbalance is always larger than 0.
How can I change this while loop so that it doesn't cause my code to run infinitely?
By the way:
With moderate numbers, the program runs for a long time and finally gives an answer. For the larger numbers, the program just keeps on going.
This loop is not infinite, but will take a long time to resolve. For very large values of balance, monthlyPayment will have to get very large in order to drop it past zero.
The bisection method will execute much quicker if you're allowed to use it in your assignment. Will not help you though, if you're required to increment the monthly payment by .01.
static_balance = balance
interest = (annualInterestRate/12)
epsilon = 0.01
lo = balance/12
hi = balance
while abs(balance) > epsilon:
balance = static_balance
min_pmt = (hi+lo)/2
for i in range(12):
balance -= min_pmt
balance *= 1+interest
if balance > 0:
lo = min_pmt
else:
hi = min_pmt
print("Lowest payment: ", round(min_pmt, 2))
I'm having trouble solving problem 2 from this page
Here
Here's my code:
#Problem set 1 b
out_bal = float(raw_input("Enter the outstanding balance on your credit card: "))
ann_interest = float(raw_input("Enter the annual interest rate as a decimal: "))
min_pmnt = 10
months = 1
prev_bal = out_bal
month_interest = ann_interest / 12.0
updated_bal = prev_bal * (1 + month_interest) - min_pmnt
while out_bal > 0:
for i in range(1,13):
out_bal = updated_bal
prev_bal = out_bal
months += 1
if out_bal <= 0:
break
else:
min_pmnt = min_pmnt + 10
months = 0
print out_bal
print "RESULT"
print "Monthly payment to pay off debt in 1 year: $", min_pmnt
print "Number of months needed: ", months
print "Balance: ", round(out_bal, 2)
I want to take 1200 and .18 for the first two inputs, respectively. However when I do this the program gets caught in my while loop and keeps printing 1208.00.
When I read the code to myself it seems like it should be working. But I think I'm not using the prev_bal variable correctly.
Also, it's performing the math the way I expect it to the first time it goes through the loop but then it seems like it's not adding 10 to min_pmnt and going through the loop again. It seems like it's just using 10 over and over.
How can I write this so it does actually add 10 and perform the loop again?
Thanks!
Your problem is that updated_bal isn't changing, yet you are setting out_bal to it each time you iterate, and then conditioning the loop on out_bal becoming reduced in value.
It looks to me like you are thinking that updated_bal changes on each loop iteration, based on its component parts. In order for that to work, you would need to instead use a function that calculates an updated balance each time around.
I have to create a code to find the exact payment, to the cent, needed to pay off a loan in 12 months using bisection. The code I created for this works but it overshoots it's target. The loan will be payed off within the 12 months but after making 12 payments the final balance should be around 0. However it is a way bigger negative number.
The code I am using is:
StartBalance = float(raw_input('Credit Balance in $: '))
AnnualRate = float(raw_input('Annual interest rate in decimals: '))
MonthlyRate = AnnualRate / 12.0
MinPaymentLow = StartBalance / 12.0
MinPaymentHigh = (StartBalance*(1+MonthlyRate)**12.0)/12.0
cent = 0.01
Payment = (MinPaymentHigh+MinPaymentLow)/2.0
while (Payment*12-StartBalance) >= cent:
for month in range(0, 12):
Balance = (StartBalance-Payment)/10*(1+MonthlyRate)
if Balance < 0:
MinPaymentLow = Payment
elif Balance > 0:
MinPaymentHigh = Payment
Payment = (MinPaymentHigh + MinPaymentLow)/ 2.0
print 'RESULT'
print 'Number of months needed: 12'
print 'Montly pay: $', round(Balance,2)
It looks like these lines:
for month in range(0, 12):
Balance = (StartBalance-Payment)/10*(1+MonthlyRate)
Should be:
Balance = StartBalance
for month in range(0, 12):
Balance = (Balance-Payment) * (1 + MonthlyRate)
Or something similar, depending on how you want to calculate interest, and whether you consider payments occurring at the start or end of the month.
Your code seemed to work fine for me, but if you're getting results that are "way off" it's probably because you're using the float datatype. Float is untrustable, because it rounds on every operation. Given enough iterations and you've rounded off a lot of money. Try using decimal instead. This module keeps track of decimals as indexed integer values.