Merv Merzoug
Merv Merzoug

Reputation: 1237

Seeking Feedback, Infinite loop

I'm practicing some newly acquired skills and wanted to tap the community for some feedback on the code below.

The goal: create a simple program to help an imaginary cashier return the right change by deconstructing the components of the change (dollars, quaters etc). The best way I could think of doing this is by using an if statement with a nested while loop.

2 questions:

1). The while loop isnt terminating at the end of the script despite the condition runningTotal != change no longer being satisfied. Why is that exactly? Isn't the while supposed to run until that condition is met, and the be terminated? I must be missing something...Is there something obvious that I'm missing that you guys/gals see?

2). I'm still a beginner (as you could probably tell). What feedback do you have for me on the script below. Things I did well, poorly or just general thoughts. I'm really trying to get better so your comments are much appreciated. Thanks!

The Script:

def changeCalc(cost,pmt):
    change = float(pmt - cost)
    print("Total Change: " + str(change))
    runningTotal = 0 #used to count up the change paid in the while loop below

    #make sure they paid enough
    if (pmt - cost) < 0:
        print("The customer needs to pay " + str(abs(change)) + " more.")
    else:
        #check to see if any change is due
        while runningTotal != change:
            #how many DOLLAR bills to return
            dollarBills = int(change - runningTotal)
            print("Number of Dollar Bills: " + str(dollarBills))

            #add to runningTotal
            runningTotal = float(runningTotal + dollarBills)
            print runningTotal

            #how many QUARTERS to return
            numOFqtrs = int((change - runningTotal)/(.25))
            print("Number of Quarters: " + str(numOFqtrs))

            #add to running total
            runningTotal = float(runningTotal + (numOFqtrs * (.25)))
            print runningTotal

            #how many DIMES
            numOFdimes = int((change - runningTotal)/(.10))
            print("Number of Dimes: " + str(numOFdimes))
            runningTotal = float(runningTotal + (numOFdimes * (.10)))

            #how many NICKELS
            print runningTotal
            numOFnickels = int((change - runningTotal)/(.05))
            print("Number of nickels: " + str(numOFnickels))
            runningTotal = float(runningTotal + (numOFnickels * (.05)))
            print runningTotal

            #how many PENNIES
            numOFpennies = int((change - runningTotal)/(.01))
            print("Number of Pennies: " + str(numOFpennies))
            runningTotal = float(runningTotal + (numOFpennies * (.01)))

            print runningTotal
            print change
            #####WHY DOES THE LOOP NOT END HERE??????????##########

            break

running changeCalc(87.63,103.86) results in an infinite loop with the following output.

Total Change: 16.23
Number of Dollar Bills: 16
16.0
Number of Quarters: 0
16.0
Number of Dimes: 2
16.2
Number of nickels: 0
16.2
Number of Pennies: 3
16.23
16.23

Upvotes: 1

Views: 138

Answers (2)

tobias_k
tobias_k

Reputation: 82889

As others have noted, the problem with your while loop is with floating point precision: runningTotal is very close, but just not quite the same as change. You can solve this by using some small epsilon for comparison, or using integers or similar.

However, it seems you do not need the while loop at all, do you? Also, note that the code for the different types of coins is all the same, so you could instead use a loop to iterate over all the different types of coins:

COINS = (("Dollars", 1.), 
         ("Quarters", .25), 
         ("Dimes",    .10), 
         ("Nickels",  .05), 
         ("Pennies",  .01))

def changeCalc(cost, pmt):
    change = pmt - cost
    print("Total Change: %.2f" % change)
    if (pmt - cost) < 0:
        print("The customer needs to pay %.2f more." % abs(change))
    else:
        runningTotal = 0
        for (name, value) in COINS:
            number = int((change - runningTotal) / value)
            if number > 0:
                print("Number of %s: %d" % (name, number))
                runningTotal += number * value
        print runningTotal, change, (runningTotal - change)

Upvotes: 1

Shv
Shv

Reputation: 53

Try printing change-runningTotal and you will see that it is of the order of 10e-15 . This is probabaly due to the use of floats. You can change the condition of the loop to:
"while runningTotal - change <-0.001 or runningTotal - change >0.001:"
for the program to work.

Upvotes: 0

Related Questions