Reputation: 1237
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
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
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