0

So currently this code is returning an infinite loop. The assignment is to calculate a fixed monthly payment. My biggest pain is with epsilon and trying to get my newly calculated balance within it's range. The code takes the balance and calculates the theoretical most and least amount we can pay monthly and be at 0 new_balance. MonthlyIR is monthly interest rate

def bisection(balance,annualinterestRate):
    monthlyIR = annualinterestRate/12.0
    new_balance = balance
    monthly_lower = balance/12
    monthly_upper = (balance * (1 + monthlyIR)**12)/12.0
    epsilon = 0.01
    print(monthly_lower,monthly_upper)


    while abs(new_balance) >=  epsilon:
        new_balance = balance
        print(monthly_lower,monthly_upper)
        payment = (monthly_upper + monthly_lower)/2
        for i in range(12):
            new_balance -= payment
            new_balance *= monthlyIR
        if new_balance > 0:
            monthly_lower = payment
        else: 
            monthly_upper = payment

    return round(payment,2)

So pretty much when I go through the monthly payments, and the new balance is still bigger than epsilon then set either the max or the min = to payments. However when It runs the max or min don't update and I can't figure out why. I would like someone to solve that particular issue and I would like insight on a cleaner way to do this. Whether it's more specialization of functions or a different approach other than iterative.

1
  • Please give sample input values for balance and annualinterestRate with the desired result. Commented Feb 18, 2019 at 14:44

2 Answers 2

1

Ran 2 tests

annualinterestRate >= 12 No infinite loop, and returns results

annualinterestRate < 12 : Infinite loop

Good luck :)

Sign up to request clarification or add additional context in comments.

Comments

1

First, the monthly interest is incorrectly calculated. On one hand the algorithm treats it as non-compound interest:

   monthlyIR = annualinterestRate/12.0

but earlier:

   monthly_lower = balance/12

and later, in the loop:

   new_balance *= monthlyIR

which implies that it is a compound interest. But the code does not converge for another reasons. You are calculating the impact of interest on the debt incorrectly. It should be:

   new_balance *= monthlyIR + 1

The problem is that new_balance should be increased by monthly interest rate. For example, if the monthly IR is 0.005, then the original code lowers the balance to 0.005 of its previous size. Unfortunately for us, borrowers, our debt does not shrinks to 1/200 of its original value every month, but rather it increases by extra 1/200 of the original debt. A debt of 1000$ becomes 1005$, i.e., the debt should be multiplied by 1.005 instead of 0.005.

The original code will converge (incorrectly) only with annual interest rates of 12 and above (1200%), since it makes monthly IR >= 1 (100%). This way, the multiplication does not lower the debt in the original code.

The full code is:

def bisection(balance,annualinterestRate):
    # This is most likely an incorrect monthly IR
    # I suspect it should be:
    # monthlyIR = pow(1+annualinterestRate, 1/12.0) - 1
    monthlyIR = annualinterestRate/12.0
    new_balance = balance
    monthly_lower = balance/12
    monthly_upper = (balance * (1 + monthlyIR)**12)/12.0
    epsilon = 0.01
    print(monthly_lower,monthly_upper)

    while abs(new_balance) >=  epsilon:
        new_balance = balance
        print(monthly_lower,monthly_upper)
        payment = (monthly_upper + monthly_lower)/2
        for i in range(12):
            new_balance -= payment
            new_balance *= monthlyIR + 1
        if new_balance > 0:
            monthly_lower = payment
        else: 
            monthly_upper = payment

    return round(payment,2)

Besides, there is a trivial formula to calculate this in one line, instead of using bisection. Look it up, or derive it.

For example, read here

3 Comments

Thank you! I'm not sure how I missed that. I guess in changing it so many times I forgot to add the + 1 again haha
Also the class asked for a bisection search solution. Simply to get some much needed practice in. Thanks for your help and support. How would I put the derivative into a program? Would it just the formula entered in?
@Jk128711 do you mean derivative such as in calculus, or as an incremental progression of the given code? It sounds like there should be a separate question for that, since it might require much more than a short comment

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.