我需要编写一个函数,以列表格式打印给定数量所需的英国硬币数量(即列表中的8个值,分别为£2硬币,£1硬币,£0.50,£0.20,£0.10 ,0.05英镑,0.02英镑,0.01英镑)。
到目前为止,我写了以下内容:
def pay_with_coins( amount ):
coins_list = [0, 0, 0, 0, 0, 0, 0, 0]
if amount == 0:
return(coins_list)
else:
while amount > 2.00:
coins_list[0] = (coins_list[0] + 1)
amount = amount - 2.00
while amount >= 1.00 and amount < 2.00:
coins_list[1] = (coins_list[1] + 1)
amount = amount - 1.00
while amount >= 0.50 and amount < 1.00:
coins_list[2] = (coins_list[2] + 1)
amount = amount - 0.50
while amount >= 0.20 and amount < 0.50:
coins_list[3] = (coins_list[3] + 1)
amount = amount - 0.20
while amount >= 0.10 and amount < 0.20:
coins_list[4] = (coins_list[4] + 1)
amount = amount - 0.10
while amount >= 0.05 and amount < 0.10:
coins_list[5] = (coins_list[5] + 1)
amount = amount - 0.05
while amount >= 0.02 and amount < 0.05:
coins_list[6] = (coins_list[6] + 1)
amount = amount - 0.02
while amount >= 0.01 and amount < 0.05:
coins_list[7] = (coins_list[7] + 1)
amount = amount - 0.01
return(coins_list)
我正在通过以下测试功能:
print(pay_with_coins(0.08))
print(pay_with_coins(8.02))
print(pay_with_coins(1.74))
print(pay_with_coins(1001))
这是我应该得到的:
[0,0,0,0,0,1,1,1]
[4,0,0,0,0,0,1,0]
[0,1,1,1,0,0,2,0]
[500,1,0,0,0,0,0,0]
这是我真正得到的:
[0, 0, 0, 0, 0, 1, 1, 0]
[4, 0, 0, 0, 0, 0, 0, 1]
[0, 1, 1, 1, 0, 0, 1, 1]
[500, 1, 0, 0, 0, 0, 0, 0]
如您所见,列表中的最后两个值似乎是混乱的地方,我不太确定问题出在哪里。
我觉得最后两个值搞混了,因为它们分别是0.05和0.01(小数点后两位)。知道如何解决吗?
答案 0 :(得分:2)
啊,我担心这是找出围绕浮点算法的二进制系统局限性的最糟糕的方法之一。
不可能用二进制表示法精确地表示每个十进制数。 https://docs.python.org/3.7/tutorial/floatingpoint.html
为避免出现此问题,在货币方面,请使用美分作为基本单位,并避免完全浮动。
def pay_with_coins( amount_in_cents ):
coins_list = [0, 0, 0, 0, 0, 0, 0, 0]
if amount_in_cents == 0:
return(coins_list)
else:
while amount_in_cents > 200:
coins_list[0] = (coins_list[0] + 1)
amount_in_cents = amount_in_cents - 200
while amount_in_cents >= 100 and amount_in_cents < 200:
coins_list[1] = (coins_list[1] + 1)
amount_in_cents = amount_in_cents - 100
while amount_in_cents >= 50 and amount_in_cents < 100:
coins_list[2] = (coins_list[2] + 1)
amount_in_cents = amount_in_cents - 50
while amount_in_cents >= 20 and amount_in_cents < 50:
coins_list[3] = (coins_list[3] + 1)
amount_in_cents = amount_in_cents - 20
while amount_in_cents >= 10 and amount_in_cents < 20:
coins_list[4] = (coins_list[4] + 1)
amount_in_cents = amount_in_cents - 10
while amount_in_cents >= 5 and amount_in_cents < 10:
coins_list[5] = (coins_list[5] + 1)
amount_in_cents = amount_in_cents - 5
while amount_in_cents >= 2 and amount_in_cents < 5:
coins_list[6] = (coins_list[6] + 1)
amount_in_cents = amount_in_cents - 2
while amount_in_cents >= 1 and amount_in_cents < 2:
coins_list[7] = (coins_list[7] + 1)
amount_in_cents = amount_in_cents - 1
return(coins_list)
答案 1 :(得分:1)
正如@Paritosh Singh在其回答中所述,浮子存在问题。但是,如果您想要一个更具扩展性的解决方案,则可以尝试以下方法,该方法可以节省大量的打字工作。
# Create list of currencies
currencies = [2.00, 1.00, 0.50, 0.20, 0.10, 0.05, 0.02, 0.01]
def pay_with_coins(amount):
# Initialize array
coins = [0 for i in range(len(currencies))]
# Adjust to integers to avoid floating point issues
amount = int(amount * 100)
values = [c * 100 for c in currencies]
# Loop throug values
for currency in values:
i = values.index(currency)
coins[i] = 0
# Dish out coins until you need to move to a smaller value
while amount >= currency:
amount -= currency
coins[i] += 1
return coins
print(pay_with_coins(0.08)) #[0, 0, 0, 0, 0, 1, 1, 1]
print(pay_with_coins(8.02)) #[4, 0, 0, 0, 0, 0, 1, 0]
print(pay_with_coins(1.74)) #[0, 1, 1, 1, 0, 0, 2, 0]
print(pay_with_coins(1001)) #[500, 1, 0, 0, 0, 0, 0, 0]
答案 2 :(得分:1)
您可以使用Python的decimal模块。 它用小数点(以10为底)表示数字,而不是计算机中使用的常规以2为底的数字,因此可以表示像1.1这样的数字。
代码将如下所示:
axes
请注意,该调用现在是使用字符串进行的,但您也可以将其传递给Decimal对象,这样不会生您的气。
答案 3 :(得分:0)
您要寻找的是一种将数字分成越来越小的数字的方法。一种方法是通过divmod
def pay_with_coins(amount):
twoer,rest=divmod(amount, 2) # £2
onner,rest=divmod(rest, 1) # £1
halfer,rest=divmod(rest, 0.5) # £0.50
fifther,rest=divmod(rest, 0.20) # £0.20
tenther,rest=divmod(rest, 0.10) # £0.10
twenthier,rest=divmod(rest, 0.05) # £0.05
fifthier,rest=divmod(rest, 0.02) # £0.02
hundreder,rest=divmod(rest,0.01) # £0.01
coinList = [twoer, onner, halfer, fifther, tenther, twenthier,fifthier, hundreder]
return [i for i in map(int, coinList)]
在上面的代码中,我在同一变量上连续使用divmod
,以将值分成越来越小的面额。
在为此创建“解决方案”之前,我似乎没有完全阅读问题。阅读此问题的其他答案,他们建议在其中使用美分进行计算,以免使用不必要的浮点数,我还对代码进行了修改以遵循以下要求:
def pay_with_coins(amount):
amount *= 100
twoer,rest=divmod(amount,200) # £2
onner,rest=divmod(rest,100) # £1
halfer,rest=divmod(rest,50) # £0.50
fifther,rest=divmod(rest,20) # £0.20
tenther,rest=divmod(rest,10) # £0.10
twenthier,rest=divmod(rest,5) # £0.05
fifthier,rest=divmod(rest,2) # £0.02
hundreder,rest=divmod(rest,1) # £0.01
coinList = [twoer, onner, halfer, fifther, tenther, twenthier,fifthier, hundreder]
return [i for i in map(int, coinList)]
唯一真正的区别是,我将给定的数量乘以100,并对计算进行了相同的操作,因此避免一起使用浮点数。