Reputation:
I want to write a program to simulate a vending machine and calculate the change (which has to be returned to you) based on the amount paid. Given the cost, the user should first be prompted to add more money until the cost is met/exceeded by the payment.
Assume that all change is given in coins only and coins come in the following denominations: 1c, 5c, 10c, 25c, $1
Here is my program:
x = eval(input("Enter the cost (in cents):\n"))
b = 0
for i in range(x+500):
if x<5 and x>=b:
b += 1
print("Deposit a coin or note (in cents):")
print(1)
diff = b-x
for i in range(diff):
onecents = diff//1
new_onecents = diff - (onecents*1)
print("Your change is:")
if onecents != 0:
print(onecents,"x 1c")
break
elif x<10 and x>=b:
b += 5
print("Deposit a coin or note (in cents):")
print(5)
diff = b-x
for i in range(diff):
fivecents = diff//5
new_fivecents = diff - (fivecents*5)
onecents = new_fivecents//1
new_onecents = new_fivecents - (onecents*1)
print("Your change is:")
if fivecents != 0:
print(fivecents,"x 5c")
if onecents != 0:
print(onecents,"x 1c")
break
elif x<25 and x>=b:
b += 10
print("Deposit a coin or note (in cents):")
print(10)
diff = b-x
for i in range(diff):
tencents = diff//10
new_tencents = diff - (tencents*10)
fivecents = new_tencents//5
new_fivecents = new_tencents - (fivecents*5)
onecents = new_fivecents//1
new_onecents = new_fivecents - (onecents*1)
print("Your change is:")
if tencents !=0:
print(tencents,"x 10c")
if fivecents != 0:
print(fivecents,"x 5c")
if onecents != 0:
print(onecents,"x 1c")
break
elif x<100 and x>=b:
b += 25
print("Deposit a coin or note (in cents):")
print(25)
diff= b-x
for i in range(diff):
quarters = diff//25
new_quarters = diff - (quarters*25)
tencents = new_quarters//10
new_tencents = new_quarters - (tencents*10)
fivecents = new_tencents//5
new_fivecents = new_tencents - (fivecents*5)
onecents = new_fivecents//1
new_onecents = new_fivecents - (onecents*1)
print("Your change is:")
if quarters !=0:
print(quarters,"x 25c")
if tencents !=0:
print(tencents,"x 10c")
if fivecents != 0:
print(fivecents,"x 5c")
if onecents != 0:
print(onecents,"x 1c")
break
elif x<500 and x>b:
print("Deposit a coin or note (in cents):")
print(100)
b += 100
diff = b-x
for i in range(diff):
quarters = diff//25
new_quarters = diff - (quarters*25)
tencents = new_quarters//10
new_tencents = new_quarters - (tencents*10)
fivecents = new_tencents//5
new_fivecents = new_tencents - (fivecents*5)
onecents = new_fivecents//1
new_onecents = new_fivecents - (onecents*1)
print("Your change is:")
if quarters !=0:
print(quarters,"x 25c")
if tencents !=0:
print(tencents,"x 10c")
if fivecents != 0:
print(fivecents,"x 5c")
if onecents != 0:
print(onecents,"x 1c")
break
elif x<(x+500) and x>=b:
print("Deposit a coin or note (in cents):")
print(500)
b += 500
diff = b-x
for i in range(diff):
onedollars = diff//100
new_onedollars = diff - (onedollars * 100)
quarters = new_onedollars//25
new_quarters = new_onedollars - (quarters*25)
tencents = new_quarters//10
new_tencents = new_quarters - (tencents*10)
fivecents = new_tencents//5
new_fivecents = new_tencents - (fivecents*5)
onecents = new_fivecents//1
new_onecents = new_fivecents - (onecents*1)
print("Your change is:")
if onedollars != 0:
print(onedollars,"x $1")
if quarters !=0:
print(quarters,"x 25c")
if tencents !=0:
print(tencents,"x 10c")
if fivecents != 0:
print(fivecents,"x 5c")
if onecents != 0:
print(onecents,"x 1c")
break
When I run this program and I follow the instructions it should look like this:
Enter the cost (in cents):
1000
Deposit a coin or note (in cents):
500
Deposit a coin or note (in cents):
500
Deposit a coin or note (in cents):
Instead I get:
Enter the cost (in cents):
1000
Deposit a coin or note (in cents):
500
Deposit a coin or note (in cents):
500
Deposit a coin or note (in cents):
500
Your change is:
5 x $1
Also another expected output:
Enter the cost (in cents):
3
Deposit a coin or note (in cents):
1
Deposit a coin or note (in cents):
1
Deposit a coin or note (in cents):
1
However I get:
Enter the cost (in cents):
3
Deposit a coin or note (in cents):
1
Deposit a coin or note (in cents):
1
Deposit a coin or note (in cents):
1
Deposit a coin or note (in cents):
1
Your change is:
1 x 1c
The rest does work out and is correct.
Thanks for all your help guys (especially @jonrsharpe). Here is the solution (in code form):
def vend():
"""Simulate a vending machine, taking user input and returning remainder."""
total = eval(input("Enter the cost (in cents):\n"))
inserted = 0
while inserted < total:
inserted += eval(input("Deposit a coin or note (in cents):\n"))
if inserted > total:
sum = inserted - total
if sum != 0:
print("Your change is:")
dollars = sum//100
if dollars != 0:
print(dollars,'x $1')
quarters = (sum - dollars*100)//25
if quarters != 0:
print(quarters,'x 25c')
ten_cents = (sum - dollars*100 - quarters*25)//10
if ten_cents != 0:
print(ten_cents,'x 10c')
five_cents = (sum - dollars*100 - quarters*25 - ten_cents*10)//5
if five_cents != 0:
print(five_cents,'x 5c')
one_cents = (sum - dollars*100 - quarters*25 - ten_cents*10 - five_cents*5)//1
if one_cents != 0:
print(one_cents,'x 1c')
vend()
Upvotes: 0
Views: 6970
Reputation: 122107
Your specific error stems from the fact that you do not deal correctly with the case where you exactly reach the total - you overshoot, then have to give change. However, your code is very long and complex and it is difficult to figure out exactly what it is doing at each stage.
A few general coding suggestions:
eval
is a bad idea; it is better to use int(input(...))
, which will also make a fuss for you if the user doesn't enter an integer.for
loop should really be a while
loop, rather than guessing a maximum number of iterations (which all run, even after you've made change!)Also, reading your description, specifically:
Given the cost, the user should first be prompted to add more money until the cost is met/exceeded by the payment.
I think you are supposed to be allowing the user to input
coins rather than guessing what they will enter.
Here is one possible implementation:
def vend():
"""Simulate a vending machine, taking user input and returning remainder."""
total = int(input("Enter the cost (in cents): "))
inserted = 0
while inserted < total:
inserted += int(input("Deposit a coin or note (in cents): "))
if inserted > total:
return make_change(inserted - total)
def make_change(remainder):
"""Calculate the coins required to make change equal to amount."""
coins = ["$1", "25c", "10c", "5c", "1c"]
amounts = [int(coin[:-1]) if coin.endswith("c")
else 100 * int(coin[1:])
for coin in coins]
counts = [0 for _ in coins]
for index, amount in enumerate(amounts):
counts[index] = remainder // amount
remainder %= amount
return ", ".join("{0} x {1}".format(count, coin)
for count, coin in zip(counts, coins)
if count)
Note the division of responsibility between the two functions, to make it easier to test each one separately, and the appropriate use of for
and while
loops to minimise repetition. Also, I have made amounts
and paid
in make_change
depend on coins
, so you only have to change in one place to add new coins.
Example usage:
>>> vend()
Enter the cost (in cents): 135
Deposit a coin or note (in cents): 100
Deposit a coin or note (in cents): 50
'1 x 10c, 1 x 5c'
Upvotes: 2