Listing what coins are needed for given amount python
up vote
0
down vote
favorite
I need to write a function that prints the amount of UK coins needed for a given amount, in a list format (i.e. 8 values in the list for £2 coins, £1 coins, £0.50, £0.20, £0.10, £0.05, £0.02, £0.01).
I have so far written the following:
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)
I am testing the function by passing the following:
print(pay_with_coins(0.08))
print(pay_with_coins(8.02))
print(pay_with_coins(1.74))
print(pay_with_coins(1001))
This is what I'm supposed to get:
[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]
And this is what I actually get:
[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]
As you can see, the last two values in the list is where it seems to mess up and I'm not quite sure what the issue is.
I have a feeling that the last two values are messing up because they're 0.05 and 0.01 (2 decimal places). Any idea how to sort that out?
python
add a comment |
up vote
0
down vote
favorite
I need to write a function that prints the amount of UK coins needed for a given amount, in a list format (i.e. 8 values in the list for £2 coins, £1 coins, £0.50, £0.20, £0.10, £0.05, £0.02, £0.01).
I have so far written the following:
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)
I am testing the function by passing the following:
print(pay_with_coins(0.08))
print(pay_with_coins(8.02))
print(pay_with_coins(1.74))
print(pay_with_coins(1001))
This is what I'm supposed to get:
[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]
And this is what I actually get:
[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]
As you can see, the last two values in the list is where it seems to mess up and I'm not quite sure what the issue is.
I have a feeling that the last two values are messing up because they're 0.05 and 0.01 (2 decimal places). Any idea how to sort that out?
python
3
Your last condition is not correct:amount >= 0.01 and amount < 0.01:
– Andrea Nagy
Nov 7 at 20:47
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
I need to write a function that prints the amount of UK coins needed for a given amount, in a list format (i.e. 8 values in the list for £2 coins, £1 coins, £0.50, £0.20, £0.10, £0.05, £0.02, £0.01).
I have so far written the following:
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)
I am testing the function by passing the following:
print(pay_with_coins(0.08))
print(pay_with_coins(8.02))
print(pay_with_coins(1.74))
print(pay_with_coins(1001))
This is what I'm supposed to get:
[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]
And this is what I actually get:
[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]
As you can see, the last two values in the list is where it seems to mess up and I'm not quite sure what the issue is.
I have a feeling that the last two values are messing up because they're 0.05 and 0.01 (2 decimal places). Any idea how to sort that out?
python
I need to write a function that prints the amount of UK coins needed for a given amount, in a list format (i.e. 8 values in the list for £2 coins, £1 coins, £0.50, £0.20, £0.10, £0.05, £0.02, £0.01).
I have so far written the following:
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)
I am testing the function by passing the following:
print(pay_with_coins(0.08))
print(pay_with_coins(8.02))
print(pay_with_coins(1.74))
print(pay_with_coins(1001))
This is what I'm supposed to get:
[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]
And this is what I actually get:
[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]
As you can see, the last two values in the list is where it seems to mess up and I'm not quite sure what the issue is.
I have a feeling that the last two values are messing up because they're 0.05 and 0.01 (2 decimal places). Any idea how to sort that out?
python
python
edited Nov 7 at 21:21
bolov
30k668128
30k668128
asked Nov 7 at 20:44
anon2000
135
135
3
Your last condition is not correct:amount >= 0.01 and amount < 0.01:
– Andrea Nagy
Nov 7 at 20:47
add a comment |
3
Your last condition is not correct:amount >= 0.01 and amount < 0.01:
– Andrea Nagy
Nov 7 at 20:47
3
3
Your last condition is not correct:
amount >= 0.01 and amount < 0.01:
– Andrea Nagy
Nov 7 at 20:47
Your last condition is not correct:
amount >= 0.01 and amount < 0.01:
– Andrea Nagy
Nov 7 at 20:47
add a comment |
4 Answers
4
active
oldest
votes
up vote
1
down vote
accepted
You can use Python's decimal-module for that.
It represents numbers as decimals (base 10) instead of the normal base 2 used in computers and thus it can represent numbers like 1.1.
Code would go something like this:
from decimal import Decimal
def pay_with_coins( amount ):
amount = Decimal(amount)
coins_list = [0, 0, 0, 0, 0, 0, 0, 0]
if amount == 0:
return(coins_list)
else:
while amount > Decimal("2.00"):
coins_list[0] = (coins_list[0] + 1)
amount = amount - Decimal("2.00")
while amount >= Decimal("1.00") and amount < Decimal("2.00"):
coins_list[1] = (coins_list[1] + 1)
amount = amount - Decimal("1.00")
while amount >= Decimal("0.50") and amount < Decimal("1.00"):
coins_list[2] = (coins_list[2] + 1)
amount = amount - Decimal("0.50")
while amount >= Decimal("0.20") and amount < Decimal("0.50"):
coins_list[3] = (coins_list[3] + 1)
amount = amount - Decimal("0.20")
while amount >= Decimal("0.10") and amount < Decimal("0.20"):
coins_list[4] = (coins_list[4] + 1)
amount = amount - Decimal("0.10")
while amount >= Decimal("0.05") and amount < Decimal("0.10"):
coins_list[5] = (coins_list[5] + 1)
amount = amount - Decimal("0.05")
while amount >= Decimal("0.02") and amount < Decimal("0.05"):
coins_list[6] = (coins_list[6] + 1)
amount = amount - Decimal("0.02")
while amount >= Decimal("0.01") and amount < Decimal("0.05"):
coins_list[7] = (coins_list[7] + 1)
amount = amount - Decimal("0.01")
return(coins_list)
print(pay_with_coins("1.74"))
Notice that the call is now made with a string, but you can also pass it a Decimal object and it won't get angry at you.
add a comment |
up vote
2
down vote
Ah, i fear this is one of the worst ways to find out about the limitations of binary systems around floating point arithmetic.
It is not possible to accurately represent every decimal number in binary notation.
https://docs.python.org/3.7/tutorial/floatingpoint.html
To avoid the issue, when it comes to currency, use cents as your base unit and avoid floats completely.
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)
If you would like to see the behaviour for yourself, i would encourage you to look at the values stored in "amount" variable by the end of calculations when you start with an amount like 1.74 in your example.
– Paritosh Singh
Nov 7 at 21:03
When it comes to currency, you should always be able to manipulate the input (ie. multiply amount by 100) or output (divide final answer by 100 to convert cent to dollar/euro) and do all calculations without floats, as each calculation step with floats can introduce more error which creeps up. if you are dealing with something that has to be tackled in decimals though, take a look at Decimals or Fractions @ll17m2r
– Paritosh Singh
Nov 7 at 21:22
add a comment |
up vote
1
down vote
As @Paritosh Singh stated in his answer, there is an issue with floats. But if you'd like a solution that is a bit more expandable, you could try the following approach which will save a lot of typing.
# 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]
add a comment |
up vote
0
down vote
What you're looking for, is a way to divide a number into smaller and smaller numbers. one way do do that is via 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)]
In the above code, i use divmod
continually on the same variable, to separate the values into lower and lower denominations.
It seems like I did not read the question quite fully before creating my "solution" for this. Reading the other answer to this question, where they recommend to do the calculation with cents, so as to not use unnecessary floating-points numbers, I've also edited my code to follow this:
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)]
The only real difference is that I multiply the given amount by 100, and did the same with the calculations so avoid floating-point numbers all together.
add a comment |
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
accepted
You can use Python's decimal-module for that.
It represents numbers as decimals (base 10) instead of the normal base 2 used in computers and thus it can represent numbers like 1.1.
Code would go something like this:
from decimal import Decimal
def pay_with_coins( amount ):
amount = Decimal(amount)
coins_list = [0, 0, 0, 0, 0, 0, 0, 0]
if amount == 0:
return(coins_list)
else:
while amount > Decimal("2.00"):
coins_list[0] = (coins_list[0] + 1)
amount = amount - Decimal("2.00")
while amount >= Decimal("1.00") and amount < Decimal("2.00"):
coins_list[1] = (coins_list[1] + 1)
amount = amount - Decimal("1.00")
while amount >= Decimal("0.50") and amount < Decimal("1.00"):
coins_list[2] = (coins_list[2] + 1)
amount = amount - Decimal("0.50")
while amount >= Decimal("0.20") and amount < Decimal("0.50"):
coins_list[3] = (coins_list[3] + 1)
amount = amount - Decimal("0.20")
while amount >= Decimal("0.10") and amount < Decimal("0.20"):
coins_list[4] = (coins_list[4] + 1)
amount = amount - Decimal("0.10")
while amount >= Decimal("0.05") and amount < Decimal("0.10"):
coins_list[5] = (coins_list[5] + 1)
amount = amount - Decimal("0.05")
while amount >= Decimal("0.02") and amount < Decimal("0.05"):
coins_list[6] = (coins_list[6] + 1)
amount = amount - Decimal("0.02")
while amount >= Decimal("0.01") and amount < Decimal("0.05"):
coins_list[7] = (coins_list[7] + 1)
amount = amount - Decimal("0.01")
return(coins_list)
print(pay_with_coins("1.74"))
Notice that the call is now made with a string, but you can also pass it a Decimal object and it won't get angry at you.
add a comment |
up vote
1
down vote
accepted
You can use Python's decimal-module for that.
It represents numbers as decimals (base 10) instead of the normal base 2 used in computers and thus it can represent numbers like 1.1.
Code would go something like this:
from decimal import Decimal
def pay_with_coins( amount ):
amount = Decimal(amount)
coins_list = [0, 0, 0, 0, 0, 0, 0, 0]
if amount == 0:
return(coins_list)
else:
while amount > Decimal("2.00"):
coins_list[0] = (coins_list[0] + 1)
amount = amount - Decimal("2.00")
while amount >= Decimal("1.00") and amount < Decimal("2.00"):
coins_list[1] = (coins_list[1] + 1)
amount = amount - Decimal("1.00")
while amount >= Decimal("0.50") and amount < Decimal("1.00"):
coins_list[2] = (coins_list[2] + 1)
amount = amount - Decimal("0.50")
while amount >= Decimal("0.20") and amount < Decimal("0.50"):
coins_list[3] = (coins_list[3] + 1)
amount = amount - Decimal("0.20")
while amount >= Decimal("0.10") and amount < Decimal("0.20"):
coins_list[4] = (coins_list[4] + 1)
amount = amount - Decimal("0.10")
while amount >= Decimal("0.05") and amount < Decimal("0.10"):
coins_list[5] = (coins_list[5] + 1)
amount = amount - Decimal("0.05")
while amount >= Decimal("0.02") and amount < Decimal("0.05"):
coins_list[6] = (coins_list[6] + 1)
amount = amount - Decimal("0.02")
while amount >= Decimal("0.01") and amount < Decimal("0.05"):
coins_list[7] = (coins_list[7] + 1)
amount = amount - Decimal("0.01")
return(coins_list)
print(pay_with_coins("1.74"))
Notice that the call is now made with a string, but you can also pass it a Decimal object and it won't get angry at you.
add a comment |
up vote
1
down vote
accepted
up vote
1
down vote
accepted
You can use Python's decimal-module for that.
It represents numbers as decimals (base 10) instead of the normal base 2 used in computers and thus it can represent numbers like 1.1.
Code would go something like this:
from decimal import Decimal
def pay_with_coins( amount ):
amount = Decimal(amount)
coins_list = [0, 0, 0, 0, 0, 0, 0, 0]
if amount == 0:
return(coins_list)
else:
while amount > Decimal("2.00"):
coins_list[0] = (coins_list[0] + 1)
amount = amount - Decimal("2.00")
while amount >= Decimal("1.00") and amount < Decimal("2.00"):
coins_list[1] = (coins_list[1] + 1)
amount = amount - Decimal("1.00")
while amount >= Decimal("0.50") and amount < Decimal("1.00"):
coins_list[2] = (coins_list[2] + 1)
amount = amount - Decimal("0.50")
while amount >= Decimal("0.20") and amount < Decimal("0.50"):
coins_list[3] = (coins_list[3] + 1)
amount = amount - Decimal("0.20")
while amount >= Decimal("0.10") and amount < Decimal("0.20"):
coins_list[4] = (coins_list[4] + 1)
amount = amount - Decimal("0.10")
while amount >= Decimal("0.05") and amount < Decimal("0.10"):
coins_list[5] = (coins_list[5] + 1)
amount = amount - Decimal("0.05")
while amount >= Decimal("0.02") and amount < Decimal("0.05"):
coins_list[6] = (coins_list[6] + 1)
amount = amount - Decimal("0.02")
while amount >= Decimal("0.01") and amount < Decimal("0.05"):
coins_list[7] = (coins_list[7] + 1)
amount = amount - Decimal("0.01")
return(coins_list)
print(pay_with_coins("1.74"))
Notice that the call is now made with a string, but you can also pass it a Decimal object and it won't get angry at you.
You can use Python's decimal-module for that.
It represents numbers as decimals (base 10) instead of the normal base 2 used in computers and thus it can represent numbers like 1.1.
Code would go something like this:
from decimal import Decimal
def pay_with_coins( amount ):
amount = Decimal(amount)
coins_list = [0, 0, 0, 0, 0, 0, 0, 0]
if amount == 0:
return(coins_list)
else:
while amount > Decimal("2.00"):
coins_list[0] = (coins_list[0] + 1)
amount = amount - Decimal("2.00")
while amount >= Decimal("1.00") and amount < Decimal("2.00"):
coins_list[1] = (coins_list[1] + 1)
amount = amount - Decimal("1.00")
while amount >= Decimal("0.50") and amount < Decimal("1.00"):
coins_list[2] = (coins_list[2] + 1)
amount = amount - Decimal("0.50")
while amount >= Decimal("0.20") and amount < Decimal("0.50"):
coins_list[3] = (coins_list[3] + 1)
amount = amount - Decimal("0.20")
while amount >= Decimal("0.10") and amount < Decimal("0.20"):
coins_list[4] = (coins_list[4] + 1)
amount = amount - Decimal("0.10")
while amount >= Decimal("0.05") and amount < Decimal("0.10"):
coins_list[5] = (coins_list[5] + 1)
amount = amount - Decimal("0.05")
while amount >= Decimal("0.02") and amount < Decimal("0.05"):
coins_list[6] = (coins_list[6] + 1)
amount = amount - Decimal("0.02")
while amount >= Decimal("0.01") and amount < Decimal("0.05"):
coins_list[7] = (coins_list[7] + 1)
amount = amount - Decimal("0.01")
return(coins_list)
print(pay_with_coins("1.74"))
Notice that the call is now made with a string, but you can also pass it a Decimal object and it won't get angry at you.
answered Nov 7 at 22:28
Jaakko2000
362
362
add a comment |
add a comment |
up vote
2
down vote
Ah, i fear this is one of the worst ways to find out about the limitations of binary systems around floating point arithmetic.
It is not possible to accurately represent every decimal number in binary notation.
https://docs.python.org/3.7/tutorial/floatingpoint.html
To avoid the issue, when it comes to currency, use cents as your base unit and avoid floats completely.
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)
If you would like to see the behaviour for yourself, i would encourage you to look at the values stored in "amount" variable by the end of calculations when you start with an amount like 1.74 in your example.
– Paritosh Singh
Nov 7 at 21:03
When it comes to currency, you should always be able to manipulate the input (ie. multiply amount by 100) or output (divide final answer by 100 to convert cent to dollar/euro) and do all calculations without floats, as each calculation step with floats can introduce more error which creeps up. if you are dealing with something that has to be tackled in decimals though, take a look at Decimals or Fractions @ll17m2r
– Paritosh Singh
Nov 7 at 21:22
add a comment |
up vote
2
down vote
Ah, i fear this is one of the worst ways to find out about the limitations of binary systems around floating point arithmetic.
It is not possible to accurately represent every decimal number in binary notation.
https://docs.python.org/3.7/tutorial/floatingpoint.html
To avoid the issue, when it comes to currency, use cents as your base unit and avoid floats completely.
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)
If you would like to see the behaviour for yourself, i would encourage you to look at the values stored in "amount" variable by the end of calculations when you start with an amount like 1.74 in your example.
– Paritosh Singh
Nov 7 at 21:03
When it comes to currency, you should always be able to manipulate the input (ie. multiply amount by 100) or output (divide final answer by 100 to convert cent to dollar/euro) and do all calculations without floats, as each calculation step with floats can introduce more error which creeps up. if you are dealing with something that has to be tackled in decimals though, take a look at Decimals or Fractions @ll17m2r
– Paritosh Singh
Nov 7 at 21:22
add a comment |
up vote
2
down vote
up vote
2
down vote
Ah, i fear this is one of the worst ways to find out about the limitations of binary systems around floating point arithmetic.
It is not possible to accurately represent every decimal number in binary notation.
https://docs.python.org/3.7/tutorial/floatingpoint.html
To avoid the issue, when it comes to currency, use cents as your base unit and avoid floats completely.
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)
Ah, i fear this is one of the worst ways to find out about the limitations of binary systems around floating point arithmetic.
It is not possible to accurately represent every decimal number in binary notation.
https://docs.python.org/3.7/tutorial/floatingpoint.html
To avoid the issue, when it comes to currency, use cents as your base unit and avoid floats completely.
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)
answered Nov 7 at 21:01
Paritosh Singh
2706
2706
If you would like to see the behaviour for yourself, i would encourage you to look at the values stored in "amount" variable by the end of calculations when you start with an amount like 1.74 in your example.
– Paritosh Singh
Nov 7 at 21:03
When it comes to currency, you should always be able to manipulate the input (ie. multiply amount by 100) or output (divide final answer by 100 to convert cent to dollar/euro) and do all calculations without floats, as each calculation step with floats can introduce more error which creeps up. if you are dealing with something that has to be tackled in decimals though, take a look at Decimals or Fractions @ll17m2r
– Paritosh Singh
Nov 7 at 21:22
add a comment |
If you would like to see the behaviour for yourself, i would encourage you to look at the values stored in "amount" variable by the end of calculations when you start with an amount like 1.74 in your example.
– Paritosh Singh
Nov 7 at 21:03
When it comes to currency, you should always be able to manipulate the input (ie. multiply amount by 100) or output (divide final answer by 100 to convert cent to dollar/euro) and do all calculations without floats, as each calculation step with floats can introduce more error which creeps up. if you are dealing with something that has to be tackled in decimals though, take a look at Decimals or Fractions @ll17m2r
– Paritosh Singh
Nov 7 at 21:22
If you would like to see the behaviour for yourself, i would encourage you to look at the values stored in "amount" variable by the end of calculations when you start with an amount like 1.74 in your example.
– Paritosh Singh
Nov 7 at 21:03
If you would like to see the behaviour for yourself, i would encourage you to look at the values stored in "amount" variable by the end of calculations when you start with an amount like 1.74 in your example.
– Paritosh Singh
Nov 7 at 21:03
When it comes to currency, you should always be able to manipulate the input (ie. multiply amount by 100) or output (divide final answer by 100 to convert cent to dollar/euro) and do all calculations without floats, as each calculation step with floats can introduce more error which creeps up. if you are dealing with something that has to be tackled in decimals though, take a look at Decimals or Fractions @ll17m2r
– Paritosh Singh
Nov 7 at 21:22
When it comes to currency, you should always be able to manipulate the input (ie. multiply amount by 100) or output (divide final answer by 100 to convert cent to dollar/euro) and do all calculations without floats, as each calculation step with floats can introduce more error which creeps up. if you are dealing with something that has to be tackled in decimals though, take a look at Decimals or Fractions @ll17m2r
– Paritosh Singh
Nov 7 at 21:22
add a comment |
up vote
1
down vote
As @Paritosh Singh stated in his answer, there is an issue with floats. But if you'd like a solution that is a bit more expandable, you could try the following approach which will save a lot of typing.
# 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]
add a comment |
up vote
1
down vote
As @Paritosh Singh stated in his answer, there is an issue with floats. But if you'd like a solution that is a bit more expandable, you could try the following approach which will save a lot of typing.
# 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]
add a comment |
up vote
1
down vote
up vote
1
down vote
As @Paritosh Singh stated in his answer, there is an issue with floats. But if you'd like a solution that is a bit more expandable, you could try the following approach which will save a lot of typing.
# 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]
As @Paritosh Singh stated in his answer, there is an issue with floats. But if you'd like a solution that is a bit more expandable, you could try the following approach which will save a lot of typing.
# 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]
answered Nov 7 at 21:18
Brian Cohan
1,8381821
1,8381821
add a comment |
add a comment |
up vote
0
down vote
What you're looking for, is a way to divide a number into smaller and smaller numbers. one way do do that is via 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)]
In the above code, i use divmod
continually on the same variable, to separate the values into lower and lower denominations.
It seems like I did not read the question quite fully before creating my "solution" for this. Reading the other answer to this question, where they recommend to do the calculation with cents, so as to not use unnecessary floating-points numbers, I've also edited my code to follow this:
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)]
The only real difference is that I multiply the given amount by 100, and did the same with the calculations so avoid floating-point numbers all together.
add a comment |
up vote
0
down vote
What you're looking for, is a way to divide a number into smaller and smaller numbers. one way do do that is via 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)]
In the above code, i use divmod
continually on the same variable, to separate the values into lower and lower denominations.
It seems like I did not read the question quite fully before creating my "solution" for this. Reading the other answer to this question, where they recommend to do the calculation with cents, so as to not use unnecessary floating-points numbers, I've also edited my code to follow this:
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)]
The only real difference is that I multiply the given amount by 100, and did the same with the calculations so avoid floating-point numbers all together.
add a comment |
up vote
0
down vote
up vote
0
down vote
What you're looking for, is a way to divide a number into smaller and smaller numbers. one way do do that is via 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)]
In the above code, i use divmod
continually on the same variable, to separate the values into lower and lower denominations.
It seems like I did not read the question quite fully before creating my "solution" for this. Reading the other answer to this question, where they recommend to do the calculation with cents, so as to not use unnecessary floating-points numbers, I've also edited my code to follow this:
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)]
The only real difference is that I multiply the given amount by 100, and did the same with the calculations so avoid floating-point numbers all together.
What you're looking for, is a way to divide a number into smaller and smaller numbers. one way do do that is via 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)]
In the above code, i use divmod
continually on the same variable, to separate the values into lower and lower denominations.
It seems like I did not read the question quite fully before creating my "solution" for this. Reading the other answer to this question, where they recommend to do the calculation with cents, so as to not use unnecessary floating-points numbers, I've also edited my code to follow this:
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)]
The only real difference is that I multiply the given amount by 100, and did the same with the calculations so avoid floating-point numbers all together.
edited Nov 7 at 21:27
answered Nov 7 at 20:59
Hampus Larsson
655
655
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53197530%2flisting-what-coins-are-needed-for-given-amount-python%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
3
Your last condition is not correct:
amount >= 0.01 and amount < 0.01:
– Andrea Nagy
Nov 7 at 20:47