【发布时间】:2020-02-08 17:54:45
【问题描述】:
我正在做一个找零计算器 - 一个函数,它会在返回每种硬币的数量之前计算物品的成本和给收银员的金额,以最佳地返回最少的硬币。
我使用地板除法和模函数以非常简单的方式做到了这一点,但我也很想通过以下方法(用于调试的打印语句)扩展我对递归和定义函数的理解:
def change_calc_2(cost, given): # input in full £xx.xx
coin_vals = [200, 100, 50, 20, 10, 5, 2, 1]
coins = [0] * len(coin_vals)
cost = cost * 100 # pence
given = given * 100
left = given - cost
def _calc(left):
for i, c in enumerate(coin_vals):
print("for loop level:", i)
print("Amount left at start of kernel:", left)
print("Coin val in question:", c)
if left == 0:
return coins # early exit routine
elif c > left:
continue
else:
coins[i] += 1
print("coin added:", c)
left -= c
print("Amount left at end of kernel:", left)
_calc(left)
return coins
#_calc(left)
return _calc(left)
#return coins
print(change_calc_2(17, 20))
为 x = 18 和 x = 19 运行 change_calc_2(x, 20) 可以正常工作。结果是 [1 0 0 0 0 0 0 0](一枚 2 英镑硬币)和 [0 1 0 0 0 0 0 0](一枚 1 英镑硬币)。
但是,当我尝试 x = 17 并期望 [1 1 0 0 0 0 0 0] 时,我得到 [1 2 0 0 0 0 0 0]。
打印调试给出以下信息:
for loop level: 0
Amount left at start of kernel: 300
Coin val in question: 200
coin added: 200
Amount left at end of kernel: 100 ##### Completion of one round of for loop, as expected
for loop level: 0
Amount left at start of kernel: 100
Coin val in question: 200 ##### Rejects the 200p coin as too big for the amount left
for loop level: 1
Amount left at start of kernel: 100
Coin val in question: 100
coin added: 100 #### Adds the last coin expected, so 100p + 200p in total
Amount left at end of kernel: 0
for loop level: 0
Amount left at start of kernel: 0 ############ <----- Running as expected until here
Coin val in question: 200 ************** <--- Should break just after this point?
for loop level: 2
Amount left at start of kernel: 0
Coin val in question: 50
for loop level: 1
Amount left at start of kernel: 100 ########### <--- Wtf? How has it added on money?
Coin val in question: 100
coin added: 100
Amount left at end of kernel: 0
for loop level: 0
Amount left at start of kernel: 0
Coin val in question: 200
for loop level: 2
Amount left at start of kernel: 0
Coin val in question: 50
[1 2 0 0 0 0 0 0]
我希望,在上面日志中的标记点,程序有 left=0(它确实如此),然后点击 if left == 0: return coin ,然后退出 _calc() 的实例。我的想法是当它返回到 _calc() 的父实例时,父实例也会点击 left==0,然后返回到它上面的 _calc() 等等。
显然我的想法是错误的 - 非常感谢任何帮助!我有一种感觉,这是由于我对返回函数的误解,和/或误解了变量的“局部性”与“全局性”
【问题讨论】: