I am trying to figure out how to use a bisect search to find:
Monthly payment made to clear loan amount
Monthly interest rate = (Annual interest rate) / 12
Monthly payment lower bound = Balance / 12
Monthly payment upper bound = (Balance x (1 + Monthly interest rate)12) / 12
At the moment I have:
balance = 6758
annualInterestRate = 0.20
monthlyRate = annualInterestRate/12
numGuesses = 0
lo = balance/12
hi = (balance)*((1+monthlyRate)**12)/12
monthPay = (hi + lo)/2.0
NuBalance = balance
while abs((NuBalance)*(1+monthlyRate))-(monthPay) >= 0.01:
print('low = ' + str(lo) + ' high = ' + str(hi) + ' MonthPay = ' + str(monthPay))
numGuesses += 1
if ((NuBalance)*(1+monthlyRate))-(monthPay) <= 0.01:
print('Month Pay LO = ' + str(monthPay))
lo = monthPay
else:
print('Month Pay HI = ' + str(monthPay))
hi = monthPay
monthPay = (hi + lo)/2.0
print('numGuesses = ' + str(numGuesses))
print('Month Pay = ' + str(monthPay))
Any help to where I'm going wrong would be appreciated.
It should be:
while abs((NuBalance)*(1+monthlyRate)-(monthPay)) >= 0.01:
^ ^
and always exists
(hi + lo)/2.0 < (NuBalance)*(1+monthlyRate)
is True because hi and lo both smaller than (NuBalance)*(1+monthlyRate)
In [9]: print 'lo:', lo
lo: 563
In [10]: print 'hi:', hi
hi: 686.720412649
In [11]: print 'monthPay:', monthPay
monthPay: 624.860206325
In [12]: print '(NuBalance)*(1+monthlyRate):', (NuBalance)*(1+monthlyRate)
(NuBalance)*(1+monthlyRate): 6870.63333333
Related
I am writing a program for my business that will require some division. For one of the user inputs, it is possible that 0 is a variable but it will then be required to be divided. If opps == 0 then sales and addon are irrelevant, but total might still have a variable assigned to it by the user. Line 9 contains my solution, but it requires the entering of false information. Is there any better way to handle this?
ans = 'y'
opps = []
sales = []
addon = []
total = []
while ans in ['y', 'Y', 'yes', 'Yes', 'YES']:
opps.append(int(input("Number of opportunities: ")))
while opps[-1] == 0:
opps.append(int(input("Number of opportunities can not equal 0, input at least 1: ")))
sales.append(int(input("Quantity of of sales: ")))
addon.append(float(input("Addon $ amount: ")))
total.append(float(input("Sales dollar amount: ")))
cra = (sales[-1] / opps[-1]) * 100
addonp = (addon[-1] / total[-1]) * 100
print("\nResults: " + "\nAddon %: " + "%.2f" % addonp + "%\n" "CRA %: " + "%.2f" % cra + "%\n")
ans = str(input("Continue? (Y/N)"))
if ans not in ['y', 'Y', 'yes', 'Yes', 'YES']:
oppst = sum(opps)
salest = sum(sales)
addont = sum(addon)
cratp = (salest / oppst) * 100
tsales = sum(total)
addontp = (addont / tsales) * 100
print("\nYour totals are: \n" +
"\n" +
"Opportunities: " + str(int(oppst)) + "\n" +
"\n" +
"# of Sales: " + str(int(salest)) + "\n" +
"\n" +
"Addon $ amount: " + "$" + "%.2f" % addont + "\n" +
"\n" +
"Addon %: " + "%.2f" % addontp + "%\n" +
"\n" +
"CRA %: " + "%.2f" % cratp + "%\n" +
"\n" +
"Total Sales: " + "$" + "%.2f" % tsales
)
input("\nPress any key to close...")
The function does what I want it to, but when it's done it just sits there rather than continuing from where I called it and I can't figure out why. The code is:
x = 9
y = 9
n = 10
ty = 1
tx = 1
while ty <= y:
while tx <= x:
vars()["p" + str(ty) + str(tx)] = 0
tx += 1
ty += 1
tx = 1
tn = 1
while tn <= n:
vars()["m" + str(tn)] = tn
tn += 1
t = x * y
tm = n
def recursion(z):
global tm
if z < n:
for x in range(n):
recursion(z + 1)
else:
if tm > 0:
tv = "m" + str(tm)
otm = eval(tv)
while eval(tv) < t - n + tm:
vars()[tv] = eval(tv) + 1
print(tv + " = " + str(eval(tv)))
vars()[tv] = otm + 1
print(tv + " = " + str(eval(tv)))
if tm > 1:
vars()["m" + str(tm - 1)] = eval("m" + str(tm - 1)) + 1
print(str("m" + str(tm - 1) + " = " + str(eval("m" + str(tm -1)))))
tm -= 1
recursion(1)
print("done")
I've put the return in where I would expect it to end but as far as I know it shouldn't actually need it.
Can anyone see what I've done to cause it to get stuck?
Thanks
Note for people not going through the change history: This is based on the comments on other answers. UPDATE: Better version.
import itertools
def permutations(on, total):
all_indices = range(total)
for indices in itertools.combinations(all_indices, on):
board = ['0'] * total
for index in indices:
board[index] = '1'
yield ''.join(board)
If anyone is interested in what the original code did, I rearranged the conditionals to prune the tree of function calls:
x = 9
y = 9
n = 10
ty = 1
tx = 1
while ty <= y:
while tx <= x:
vars()["p" + str(ty) + str(tx)] = 0
tx += 1
ty += 1
tx = 1
tn = 1
while tn <= n:
vars()["m" + str(tn)] = tn
tn += 1
t = x * y
tm = n
def recursion(z):
global tm
if tm > 0:
if z < n:
for x in range(n):
recursion(z + 1)
else:
tv = "m" + str(tm)
otm = eval(tv)
while eval(tv) < t - n + tm:
vars()[tv] = eval(tv) + 1
print(tv + " = " + str(eval(tv)))
vars()[tv] = otm + 1
print(tv + " = " + str(eval(tv)))
if tm > 1:
vars()["m" + str(tm - 1)] = eval("m" + str(tm - 1)) + 1
print(str("m" + str(tm - 1) + " = " + str(eval("m" + str(tm -1)))))
tm -= 1
recursion(1)
print("done")
This could be made much clearer through the use of lists and range objects, but that takes effort.
I wasn't able to work out what was happening (turns out if I left it for a few minutes it would actually finish though), instead, I realised that I didn't need to use recursion to achieve what I wanted (and I also realised the function didn't actually do what I want to do).
For anyone interested, I simplified and rewrote it to be a few while loops instead:
x = 9
y = 9
t = x * y
n = 10
tt = 1
while tt <= t:
vars()["p" + str(tt)] = 0
tt += 1
tn = 1
while tn <= n:
vars()["m" + str(tn)] = tn
vars()["p" + str(tn)] = 1
tn += 1
def cl():
w = ""
tt = 1
while tt <= t:
w = w + str(eval("p" + str(tt)))
tt += 1
p.append(w)
tm = n
tv = "m" + str(tm)
p = []
while m1 < t - n + tm - 1:
cl()
while tm == n and eval(tv) < t - n + tm:
vars()["p" + str(eval(tv))] = 0
vars()[tv] = eval(tv) + 1
vars()["p" + str(eval(tv))] = 1
cl()
tm -= 1
tv = "m" + str(tm)
while tm < n and tm > 0:
if eval(tv) < t - n + tm:
vars()["p" + str(eval(tv))] = 0
vars()[tv] = eval(tv) + 1
vars()["p" + str(eval(tv))] = 1
while tm < n:
tm += 1
ptv = tv
tv = "m" + str(tm)
vars()["p" + str(eval(tv))] = 0
vars()[tv] = eval(ptv) + 1
vars()["p" + str(eval(tv))] = 1
else:
tm -= 1
tv = "m" + str(tm)
I am trying to solve an online question using binary search (bisection search?) and I am uncertain where my code is wrong, my answers vary from the expected answer by a bit more than comfortable for me. I would really appreciate to know where I am off-course, as well as pointers for the future.
I am given an annual interest rate and an initial balance. I am also expected to select a small enough step so I can increment to the cent.
My code is like this:
startbalance = input('Balance: ')
annualInterestRate = input('annualInterestRate: ')
monthlyInterestRate = annualInterestRate / 12.0
balance = startbalance
step = 0.01
lowbound = balance / 12.0
highbound = (balance * (1 + monthlyInterestRate)**12) / 12.0
monthlyPayment = (lowbound + highbound) / 2.0
while (monthlyPayment - balance) >= step:
for month in range(0, 12):
balance -= monthlyPayment
balance = balance + ((1 + monthlyInterestRate) * balance)
if balance < 0:
highbound = monthlyPayment
balance = startbalance
elif balance > 0:
lowbound = monthlyPayment
balance = startbalance
print 'Lowest Payment: ', round(monthlyPayment, 2)
Testing my code with the values provided in cases, I have the following:
With an annual interest rate of 0.2
and a balance of 320000,
My result: 29591.88 (incorrect, the answer should be 29157.09)
With an annual interest rate of 0.18
and a balance of 999999,
My result: 91484.0 (incorrect, the answer should be 90325.03)
I think I am just a little bit off and I would really appreciate some setting-straight.
Thanks!
Fixed it (thanks, z0k!):
startbalance = input('Balance: ')
annualInterestRate = input('annualInterestRate: ')
monthlyInterestRate = annualInterestRate / 12.0
monthlyInterestRate = annualInterestRate / 12.0
startbalance = balance
step = 0.01
lowbound = startbalance / 12.0
highbound = (startbalance * (1 + monthlyInterestRate)**12) / 12.0
monthlyPayment = (lowbound + highbound) / 2.0
while (abs(startbalance)) >= step:
startbalance = balance
for month in range(0, 12):
startbalance -= monthlyPayment
startbalance = startbalance + ((monthlyInterestRate) * startbalance)
if startbalance < 0:
highbound = monthlyPayment
if startbalance > 0:
lowbound = monthlyPayment
monthlyPayment = (lowbound + highbound) / 2.0
print 'Lowest Payment: ', round(monthlyPayment, 2)
month = 1
while month < 13:
monthly_interest_rate = annualInterestRate/12.0
min_monthlypayment = monthlyPaymentRate * balance
monthlyUnpaidBalance = balance - min_monthlypayment
updated_balance = monthlyUnpaidBalance + (monthly_interest_rate * monthlyUnpaidBalance)
print "Month: " + str(month)
print "Minimum monthly payment : " + str(round(min_monthlypayment, 2))
print "Remaining balance: " + str(round(updated_balance, 2))
balance = updated_balance
month = month + 1
print "Total paid : " + round(sum(min_monthlypayment), 2)
print "Remaining balance: " + round(updated_balance, 2)
I don't know why I'm getting this error if not using any iteration.
You are iterating when you are trying to take the sum. My suggestion would be to keep your code and store the variable in an array and then take the sum at the end so:
import numpy as np
sum_arr = np.zeros(12)
a = 0
under min_monthlypayment put: sum_arr[a] = min_monthlypayment
under month = month + 1 put: a = a+1
then to get the sum use np.sum(sum_arr)
How do I continue the following loop until I find mmp = 310? So far, with my code the furthest I can go is mmp = 240. Do you think I should have one more if statement?
balance = 4213
annualInterestRate = 0.2
mir = annualInterestRate/12
monthlyPaymentRate = 0.04
rb = balance
mmp = 0
Month = 1
while Month <= 12:
print('Month:' + str(Month))
mmp = mmp + 10
print('Minimum monthly payment:' + str(mmp))
ub = rb - mmp
rb = round(ub + (annualInterestRate/12 * ub), 2)
Month = Month + 1
print('Remaining balance:' + str(rb))
if rb > 0:
rb = balance
Month = 1
while Month <= 12:
print('Month:' + str(Month))
mmp = mmp + 10
print('Minimum monthly payment:' + str(mmp))
ub = rb - mmp
rb = round(ub + (annualInterestRate/12 * ub), 2)
Month = Month + 1
print('Remaining balance:' + str(rb))
else:
print('Lowest Payment:' + str(mmp)
Instead of while Month <= 12:, you could use while mmp < 310: if you just want to reach that number. Or while rb > 0: if you want to continue looping until everything is paid.
If looping over the months is a requirement (btw, it's generally appreciated here if you mention that your question is homework), you could add an outer loop for years:
year = 1
while rb > 0:
month = 1
while month <= 12:
# do stuff
month = month + 1
year = year + 1