1

I am trying to learn how to write a program that can "make change".

It should take two numbers as input, one that is a monetary amount charged and the other that is a monetary amount given. It should then return the number of each kind of bill and coin to give back as change for the difference between the amount given and the amount charged. The values assigned to the bills and coins can be based on the monetary system of any current or former government. Try to design your program so that it returns as few bills and coins as possible.

Here is the code.

def make_change(given, charged, denominations = [100, 20, 10, 5, 2, 1, 0.25, 0.10, 0.05, 0.01]):
    assert given >= charged, 'The customer has not given enough!'
    change = {}
    residual = given-charged
    for denomination in denominations:
        amount, residual = divmod(residual, denomination)
        if amount: 
            change[denomination] = int(amount) 
    return change

print(make_change(1000, 575))
print(make_change(1000.84, 575))
{100: 4, 20: 1, 5: 1}
{100: 4, 20: 1, 5: 1, 0.25: 3, 0.05: 1, 0.01: 4}

I can't understand the if amount statement, what does that mean? In addition, the first output of divmod(425,100) is (4,25),and it returns change{100:4},the second output of divmod(425,20),it returns (21,5),so the result should be {100:4, 20:21}, however, the real result is {100: 4, 20: 1, 5: 1}. Can somebody help me, please?

  • 1
    At a first glance, `if amount` ~ `if amound != 0` – Tuan Chau Jul 09 '21 at 02:28
  • 1
    Welcome to Stack Overflow! Please take the [tour] and read [ask]. Please ask only one question at a time. Your secondary question has already been asked here, indirectly: [What is Truthy and Falsy?](https://stackoverflow.com/q/39983695/4518341) – wjandrea Jul 09 '21 at 02:29

5 Answers5

0

The if amount statement is testing the value of amount: if amount != 0, then you add the new item to your dictionary, else (amount == 0) do nothing.

wjandrea
  • 28,235
  • 9
  • 60
  • 81
0

The second calculation is not divmod(425, 20), it's divmod(25, 20), because residual = 25 due to the previous loop.

>>> residual = 425
>>> denomination = 100
>>> amount, residual = divmod(residual, denomination)
>>> amount
4
>>> residual
25
wjandrea
  • 28,235
  • 9
  • 60
  • 81
0

if amount is a shortcut for if amount != 0 here.

Python tries to figure out the "boolean value" of any expression given to if . In case of integers, the boolean value of 0 is False, everything else is True. There is a case to be made that it's better to be explicit and have the if statment written as if amount > 0

the first output of divmod(425, 100) is indeed (4, 25) which is assigned to amount, residual. in the line

amount, residual = divmod(residual, denomination)
#  ^        ^                ^
# new_amt, new_residual     current_residual, 

That's another python trick where you can assign multiple values to multiple variable names called tuple unpacking

after the first loop, the value of residual changes to 25, hence the second loop gets called with amount, residual = divmod(25, 20)

wjandrea
  • 28,235
  • 9
  • 60
  • 81
srj
  • 9,591
  • 2
  • 23
  • 27
0

The program works as you describe it is intended to.

If the needed change is 425, then that should be split into 4 100s, 1 20, and 1 5, like the program does. This will add up to 425 (4*100 + 1*20 + 1*5).

4 100s and 21 20s would be 820 change, which is more than 1000 - 575.

wjandrea
  • 28,235
  • 9
  • 60
  • 81
Blubywaff
  • 26
  • 4
-1

if amount: is a tricky way to check if amount is not 0. It would probably better to explicitly change it to if amount > 0:

As far as your question about the output, divmod() returns a tuple of (quotient, remainder). You were correct in saying that divmod(425, 20) = (21, 5) because 425 can be divided by 20 twenty-one times. However you still have to account for the remainder of 5. divmod(5, 5) = (1, 0), meaning that 5 can be divided by 5 one time, with no remainder. Because there is no remainder that's the final answer. Thus, {100: 4, 20: 1, 5: 1}

Matt Spataro
  • 224
  • 3
  • 8
  • `divmod(425, 20)` is a red herring. It's never actually calculated by OP's program, they're just confused. – wjandrea Jul 09 '21 at 02:43