Я пытаюсь научиться писать программу, которая может «вносить изменения».

Он должен принимать два числа в качестве входных данных, одно из которых представляет собой начисленную денежную сумму, а другое - заданную денежную сумму. Затем он должен вернуть количество каждого вида банкнот и монет для возврата в качестве сдачи на разницу между выданной суммой и взимаемой суммой. Стоимость купюр и монет может быть основана на денежной системе любого действующего или бывшего правительства. Постарайтесь разработать свою программу так, чтобы она возвращала как можно меньше купюр и монет.

Вот код.

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}

Я не могу понять заявление if amount, что это означает? Кроме того, первый вывод divmod (425,100) равен (4,25) ,, и он возвращает change {100: 4} , второй вывод divmod (425,20) , он возвращает (21,5) ,, поэтому результат должно быть {100: 4, 20:21}, однако реальный результат будет {100: 4, 20: 1, 5: 1}. Кто-нибудь может мне помочь, пожалуйста?

1
Xiangyuan Li 9 Июл 2021 в 05:18

5 ответов

Лучший ответ

if amount - это ярлык для if amount != 0 здесь.

Python пытается вычислить "логическое значение" любого выражения, переданного if . В случае целых чисел логическое значение 0 равно False, все остальное - True. Необходимо указать, что лучше быть явным и иметь условие if, записанное как if amount > 0

Первый вывод divmod(425, 100) действительно (4, 25), который назначен amount, residual. в соответствии

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

Это еще один трюк с Python, позволяющий присвоить несколько значений нескольким именам переменных, называемый распаковкой кортежа

После первого цикла значение остатка изменяется на 25, поэтому второй цикл вызывается с amount, residual = divmod(25, 20)

0
wjandrea 9 Июл 2021 в 02:46

if amount: - это хитрый способ проверить, не равно ли amount 0. Возможно, лучше явно изменить его на if amount > 0:

Что касается вашего вопроса о выходе, divmod () возвращает кортеж (частное, остаток). Вы были правы, говоря, что divmod (425, 20) = (21, 5), потому что 425 можно разделить на 20 двадцать один раз. Однако вам все равно придется учитывать оставшуюся часть 5. divmod (5, 5) = (1, 0), что означает, что 5 можно разделить на 5 один раз без остатка. Поскольку нет остатка, это окончательный ответ. Таким образом, {100: 4, 20: 1, 5: 1}

-1
Matt Spataro 9 Июл 2021 в 02:34

Программа работает так, как вы описываете, для чего она предназначена.

Если необходимое изменение - 425, то его следует разделить на 4 100, 1 20 и 1 5, как это делает программа. В сумме получится 425 (4*100 + 1*20 + 1*5).

4 100 и 21 20 будут 820 сдачей, что больше чем 1000 - 575.

0
wjandrea 9 Июл 2021 в 02:41

Оператор if amount проверяет значение amount: если amount != 0, то вы добавляете новый элемент в свой словарь, иначе (amount == 0) ничего не делает.

0
wjandrea 9 Июл 2021 в 02:39

Второй расчет - это не divmod(425, 20), это divmod(25, 20), потому что residual = 25 из-за предыдущего цикла.

>>> residual = 425
>>> denomination = 100
>>> amount, residual = divmod(residual, denomination)
>>> amount
4
>>> residual
25
0
wjandrea 9 Июл 2021 в 02:31