This code outputs a dictionary containing the number of coins of each type necessary to reach a certain change, while using the least coins possible.
def change(money):
res = {}
coin = 2.0
while coin>=0.01:
parcel = money // coin
res[coin] = int(parcel)
money -= parcel * coin
if coin not in (0.5, 0.05):
coin = coin/2
else:
if coin == 0.5:
coin = 0.2
else:
coin = 0.02
return res
when executing the function for 7.71 it returns the following:
{2.0: 3, 1.0: 1, 0.5: 1, 0.2: 1, 0.1: 0, 0.05: 0, 0.02: 0, 0.01: 0}
how come it uses 0 coins of 0.01?
CodePudding user response:
As others have stated, it's because of floating-point rounding errors.
A standard workaround is to represent monetary amounts as integer numbers of the smallest unit (usually the cent) instead of as a float
number of dollars/euros/pounds/whatever.
Here's an alternative implementation of your function that uses integer arithmetic internally, and only uses float
for the input and final output (dict
keys).
It also specifies the denominations in a list
“constant” instead of in the code. This lets you easily adapt it to other coinage systems, like the US dollar's [100, 25, 10, 5, 1]
. (We technically have a half-dollar in circulation, but it's rarely used.)
# Assuming you're using Euro coins here.
DENOMINATIONS = [200, 100, 50, 20, 10, 5, 2, 1]
def change(money):
res = {}
cents = round(money * 100)
for coin in DENOMINATIONS:
parcel, cents = divmod(cents, coin)
res[coin / 100] = parcel
return res
Sample function call:
>>> change(7.71)
{2.0: 3, 1.0: 1, 0.5: 1, 0.2: 1, 0.1: 0, 0.05: 0, 0.02: 0, 0.01: 1}
CodePudding user response:
The problem is in float rounding. E. g. 0.71 - 0.5 = 0.20999999999999996
.
Use round
function.
def change(money):
res = {}
coin = 2.0
while coin>=0.01:
parcel = money // coin
res[coin] = int(parcel)
print(parcel, money, coin, parcel*coin)
money = round(money - parcel * coin, 2)
if coin not in (0.5, 0.05):
coin = coin/2
else:
if coin == 0.5:
coin = 0.2
else:
coin = 0.02
return res
print(change(7.71))
Result
{2.0: 3, 1.0: 1, 0.5: 1, 0.2: 1, 0.1: 0, 0.05: 0, 0.02: 0, 0.01: 1}