1

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 
2
  • 2
    It's generally bad to check for equality with floats, particularly for 1/10ths which can't be represented exactly. Maybe consider using integers for cents rather than floats for dollars. Commented Jan 17, 2014 at 10:57
  • 1
    Or you could use Decimal docs.python.org/2/library/decimal.html Commented Jan 17, 2014 at 11:06

2 Answers 2

1

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) 
Sign up to request clarification or add additional context in comments.

Comments

0

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.