Python Forum
Another infinite loop
Thread Rating:
  • 2 Vote(s) - 3 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Another infinite loop
#1
The given problem: use bisectional search to find the minimum monthly payment to pay off debt after 12 payments (slight.
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).

annualInterestRate=.1 # i used these numbers soley as placeholders to test the program
balance=100 # i used these numbers soley as placeholders to test the program
monthlyInterestrate=annualInterestRate/12
balance_initial=balance
lowerbound=(1/12)*balance # the upperbound and lowerbound were defined in the given problem for us.
upperbound=balance*(1+monthlyInterestrate)**(12)/12 
monthlyPayment=(upperbound+lowerbound)/2
while balance!=0:
    for i in range(12):
        balance=balance-monthlyPayment + (balance-monthlyPayment)*monthlyInterestrate
    if balance>0:
            monthlyPayment=(upperbound+monthlyPayment)/2
    if balance<0:
            monthlyPayment=(lowerbound+monthlyPayment)/2
    balance=balance_initial
print('Lowest Payment: ' + str(round(monthlyPayment, 2)))
Is there something wrong with my bisectional search? I've been looking at it for some time and I don't see how this could give me an infinite look; if the monthlyPyament is too large it is lowered, and if it is too small it is raised until the minimum balance is found.
Reply
#2
Line 15 is resetting balance to 100 at the end of every loop, so it can never reach 0.

Edit: I ran a test without that and you are still going to have problems. Balance passes zero and goes way down, never reaching 0 exactly. You might want to test if the balance is close enough (like less than a penny from 0). Also, in a bisectional search you are changing the upper or lower bound and picking the middle repeatedly. You're not changing the bounds, just the monthly payment. And once the balance gets to zero, line 14 continually increase the monthly payment.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#3
I edited my code to
annualInterestRate=.1
balance=100
monthlyInterestrate=annualInterestRate/12
balance_initial=balance
lowerbound=(1/12)*balance
upperbound=balance*(1+monthlyInterestrate)**(12)/12
monthlyPayment=(upperbound+lowerbound)/2
while balance>-.00001 and balance<.00001:
    for i in range(12):
        balance=balance-monthlyPayment + (balance-monthlyPayment)*monthlyInterestrate
    if balance>0:
            monthlyPayment=(upperbound+monthlyPayment)/2
    if balance<0:
            monthlyPayment=(lowerbound+monthlyPayment)/2
    
print('Lowest Payment: ' + str(round(monthlyPayment, 2)))
but now everything is off by a small amount.
For instance, a balance of 320000 and an annualInterestRate of .2 should yield "Lowest Payment: 29157.09" but I'm getting 29591.88

I'm quite confused as to why this still isn't working.
Reply
#4
You never execute the while loop - check what conditions you have. While loop will be executed if balance is between -0.00001 and 0.00001.Is it the case with starting balance of 320 000?
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#5
Buran is right. You need what is often called an until loop. While it is not explicitly supported in Python, you can do one this way:

while True:
    # do stuff
    if condition:
        break
That is, check the condition at the end of the loop, rather than use a standard while that will check it at the beginning of the loop.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#6
or use just one condition, e.g.
while balance > 10**-10: # very very very small number
Another point to be strict - working with money requires 2 decimal points precision (i.e. in real life you cannot substract 150.1234321 from your balance, you will substract 150.12). you may want to check decimal module for this purpose.
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#7
I guess it is late enough to be early.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#8
Fixed it, thanks for all your help. In the end I used this.
monthlyInterestrate=annualInterestRate/12
balance_initial=balance
lowerbound=(1/12)*balance
upperbound=balance*(1+monthlyInterestrate)**(12)/12
while balance >.0001 or balance<-.0001:
    balance=balance_initial
    monthlyPayment=(upperbound+lowerbound)/2
    for i in range(12):
        balance=balance-monthlyPayment + (balance-monthlyPayment)*monthlyInterestrate
    if balance>0:
            lowerbound=monthlyPayment
    if balance<0:
            upperbound=monthlyPayment
     
print('Lowest Payment: ' + str(round(monthlyPayment, 2)))
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Infinite loop Danado 4 2,324 Aug-16-2021, 05:56 PM
Last Post: deanhystad
  Help with while loop creating an infinite loop. FWendeburg 3 2,994 Jan-30-2019, 08:28 PM
Last Post: FWendeburg
  Infinite loop/ only half working anclark686 5 4,675 Sep-09-2018, 07:31 AM
Last Post: buran
  Why is this giving me an infinite loop? wlsa 4 3,835 Jul-25-2018, 10:11 PM
Last Post: cyberpatje
  How to stop an infinite loop in spyder if it's currently running? wlsa 3 24,599 Jun-30-2018, 03:27 AM
Last Post: ichabod801
  Infinite loop Truman 9 9,004 Jan-19-2018, 11:25 PM
Last Post: j.crater

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020