# [Tutor] Ingenious script (IMO)

Dick Moores rdm at rcblue.com
Mon Aug 6 16:31:57 CEST 2007

```At 06:49 AM 8/6/2007, Kent Johnson wrote:
>Dick Moores wrote:
>>http://www.rcblue.com/Python/changeMaker_revised_for_US_denominations.py
>>I'm still working at Python--been at it a while--and thought the
>>script was ingenious. Do the Tutors agree? Or is it just
>>run-of-the-mill programming? Could it have been more simply written?
>
>I don't find it either ingenious or well-written. The algorithm is
>the same one you would use to count out an amount by hand so it
>doesn't seem so unusual. IMO the code relies too much on indices. If
>you rewrite it using a dict (or, even better, defaultdict(int)) for
>coinCount, there is no need for indices at all. Even with coinCount
>as a list, it could be better written.
>
>coinCount = []
>for d in denominations:
>     coinCount.append(0)
>
>=>
>
>coinCount = [0] * ndenominations
>
>
>The main loop could be
>for deno in range(ndenominations):
>   if not remaining:
>     break
>
>or
>for i, deno in enumerate(denominations):
># i is now the index, deno is the actual denomination
>
>
>but I would write it this way and avoid the use of the index completely:
>
>from collections import defaultdict
>coinCount = defaultdict(int)
>remaining = change
>
>#   Loop until either we have given all the change or we have
>#   run out of coin denominations to check.
>for deno in denominations:
>     if not remaining:
>         break
>
>     #   For one denomination, count out coins of that denomination
>     #   as long as the remaining amount is greater than the denomination
>     #   amount.
>
>     while remaining >= deno:
>         coinCount[deno] += 1
>         print "remaining =", remaining
>         remaining -= deno
>
>#   Report the results.
>print "Your change is \$%.02f"% (float(change) / CPD)
>for deno in denominations:
>     if coinCount[deno] > 0:
>         if deno >= 100:
>             print "\$%d bills:\t" % (deno / CPD), coinCount[deno]
>         else:
>             print "%d-cent coins:\t" % (deno), coinCount[deno]
>
>
>Kent

Thanks Kent!

Here's what I have after incorporating your suggestions:

=================================
#!/usr/bin/env python
#coding=utf-8
from collections import defaultdict

CPD = 100
cost = int(CPD * float(raw_input("Enter the cost: ")))
tend = int(CPD * float(raw_input("Enter the tendered amount: ")))

#   Calculate the change.
change = tend - cost

coinCount = defaultdict(int)
print coinCount
remaining = change
denominations = (2000, 1000, 500, 100, 50, 25, 10, 5, 1)

#   Loop until either we have given all the change or we have
#   run out of coin denominations to check.
for deno in denominations:
if not remaining:
break

#   For one denomination, count out coins of that denomination
#   as long as the remaining amount is greater than the denomination
#   amount.

while remaining >= deno:
coinCount[deno] += 1
remaining -= deno

#   Report the results.
print "Your change is \$%.02f"% (float(change) / CPD)
for deno in denominations:
if coinCount[deno] > 0:
if deno >= 100:
print "\$%d bills:\t" % (deno / CPD), coinCount[deno]
else:
print "%d-cent coins:\t" % (deno), coinCount[deno]
========================================

Gotta say though, I still don't understand how the defaultdict works here.

Dick

```