user3501324
user3501324

Reputation:

Vending Machine Program (Calculate the amount that has to inserted,etc.)

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

Answers (1)

jonrsharpe
jonrsharpe

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:

  1. 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.
  2. Your outer 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!)
  3. You have a lot of repeated code and hard-coded values; whenever you write similar things repeatedly consider splitting them out into a function with arguments, or some kind of loop.

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

Related Questions