0

The task is to write a function to make change for an amount using a given denomination of coins (coins = [200, 100, 50, 20, 10, 5, 2, 1]), given the coins in 'pocket' e.g a pocket of [1,0,1,0,5,0,3,0] would represent 1x£2, 1x£0.50, 5x£0.10 and 3x£0.02. If there are several ways to pay, the one using the most coins should be used. If it is not possible to pay the exact amount, the mimum amount possible should be paid and the change noted. The output should list the coins to be paid in the same format as pocket, with a 9th element, change.

Problem: the function currently changes 'pocket' to output the original pocket minus what has been paid, which is close to the desired answer (it should state what coins should be given). So I created a variable, original_pocket to store the initial values of 'pocket', before I edit them, so from there the difference between original_pocket and pocket is the desired output. I cannot understand why original_pocket is changing, given the for loop should only be modifying 'pocket'?

def pay_with_coins(amount, pocket):
    amount = amount*100 #puts amount in pennies
    original_pocket = pocket
    coins = [200, 100, 50, 20, 10, 5, 2, 1]
    def value(list):
        value = 0
        for i in range(8):
        value += list[i]*coins[i]
        return value
    pocket_val = value(pocket)
    if pocket_val < amount:
        return False
    else: pass
    for i in range(7,-1,-1):
        take = min(amount//coins[i], pocket[i])  #how many of each coin type can be taken
        amount = amount - coins[i]*take #set a new amount
        pocket[i]= pocket[i]-take#take those coins out of pocket
    print(pocket, "this is the pocket")
    print(original_pocket, "original pocket")
    output = [0 for i in range (9)]
    for i in range(7):
        output[i]= original_pocket[i]-pocket[i]
    print (output) #I still need to account for change as output[8]

currently, using the test:

    pay_with_coins(0.05,[0,0,0,0,0,5,3,6])

the output is:

    [0.0, 0.0, 0.0, 0.0, 0.0, 5.0, 3.0, 1.0] this is the pocket
    [0.0, 0.0, 0.0, 0.0, 0.0, 5.0, 3.0, 1.0] original pocket
    [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0, 0]

while the expected/desired output should be:

    [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 5.0, 0, 0]

1 Answers1

1

This is because original_pocket = pocket makes original_pocket a reference to pocket, not a copy. So operations on both pocket and original_pocket affect the same list.

To get a new copy of the list, either use:

original_pocket = pocket.copy() (Python 3.3+)

or

original_pocket = pocket[:]

or

original_pocket = list(pocket)

jfowkes
  • 1,495
  • 9
  • 17
  • Beware, all those solutions will only make a shallow copy, so if the the list's contents are mutable and you mutate one in the orginal, it will ALSO mutate the one in the copy. For a true deep copy, you want the `deepcopy` function of the `copy` module. – bruno desthuilliers Oct 24 '18 at 09:48