Python Forum
Creating a change table - £0.01-£0.50? - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: Homework (https://python-forum.io/forum-9.html)
+--- Thread: Creating a change table - £0.01-£0.50? (/thread-38482.html)



Creating a change table - £0.01-£0.50? - MrKnd94 - Oct-19-2022

Hello,

I'm trying to complete my workbook for university, but I'm stuck on this question: Write a program that determines how many of each coin ( from 1p to 50p) a vending machine should dispense for different amounts of change. You should print a row for each value of change between 0 and 99 and columns for the change required.

For example, the start of the table should look like the following:

[Image: kqgQbV5] (Attached as well).

The table should go up to 99p.

All I have is this code:

num1=0.01
num2=0.50
num3=float(input('Enter a number:  '))
I've made a multiplication table, but this seems different, and much more difficult.

If I can have help, then I'd be grateful. Try and explain please. I'm just four weeks in this course and I don't know much about Python as a whole. I'm starting fresh I guess you can say.

Thanks in advance.


RE: Creating a change table - £0.01-£0.50? - rob101 - Oct-19-2022

I'm a little confused.

What is said vending machine dispensing?

If it's a machine that is simply providing a cash changing service, then you don't need a floating point number. £1 could be 2x 50p, or 10x 10p, or whatever. You simply multiply the input (say, £1) by 100 to get the pennies and then divide that up: 100/50 = 2 or 100/10 = 10 and so on.

If it's a machine that is providing food or beverage, then you'll need two inputs: one for the cost of said and one for the money inserted. Then, granted, you'll need floating point numbers for the inputs.

So, start with some code that clears up the above point and we'll move this forward.

Edit to add:
I see a floor in the above: you will need a floating point number for the input, if one has 50p to convert, to smaller change.


RE: Creating a change table - £0.01-£0.50? - Pedroski55 - Oct-19-2022

Well, I thought the Brits had done away with 1p, but the Internet says:

Quote:The following coins are legal tender in the UK: All regular circulation coins: 1p, 2p, 5p, 10p, 20p, 50p, £1 and £2 pieces;

Looks like a job for modulo! Find the biggest coin that dispenses the maximum amount of change, then work on the rest.

Someone sticks in a £5 note, but only spends £3.01, how to allocate the change?

And if some coins are already gone?


RE: Creating a change table - £0.01-£0.50? - perfringo - Oct-19-2022

In these kind of situations divmod is your friend:

>>> help(divmod)
Help on built-in function divmod in module builtins:

divmod(x, y, /)
    Return the tuple (x//y, x%y).  Invariant: div*y + mod == x.
What kind of friend?

>>> divmod(0, 50)      
(0, 0)
>>> divmod(1, 50)
(0, 1)
>>> divmod(1, 20)
(0, 1)
>>> divmod(1, 1)
(1, 0)
This gives you first number as quantity and second number as reminder. You could put it into loop and break out of it when reminder is 0.


RE: Creating a change table - £0.01-£0.50? - rob101 - Oct-19-2022

(Oct-19-2022, 01:59 PM)Pedroski55 Wrote: Looks like a job for modulo! Find the biggest coin that dispenses the maximum amount of change, then work on the rest.

I was thinking along the lines of 'floor division'

As a working example (which will need some added logic to produce the bases for a solution):

amount = float(input("£ ")) * 100  # convert to pennies

fiftyP = amount // 50
twentyP = amount // 20
tenP = amount // 10
fiveP = amount // 5
twoP = amount // 2
oneP = amount // 1

print(f"50p x {int(fiftyP)}")
print(f"20p x {int(twentyP)}")
print(f"10p x {int(tenP)}")
print(f"5p  x {int(fiveP)}")
print(f"2p  x {int(twoP)}")
print(f"1p  x {int(oneP)}")



RE: Creating a change table - £0.01-£0.50? - perfringo - Oct-19-2022

As I understand the objective one should iterate over values 0...99 and print row for every of them indicating from which coins and their quantities it can be derived.

As it is homework there are some options. First - to be smartass. There is no condition (at least presented here) that it should be presented as minimum amount of coins. So 1 penny * 0...99 and you get correct answer. Second option would be going against Zen of Python which states:

Quote:In the face of ambiguity, refuse the temptation to guess.


and start guessing what is the real objective of this homework. In this case divmod suggestion could be handy.


RE: Creating a change table - £0.01-£0.50? - MrKnd94 - Oct-20-2022

(Oct-19-2022, 04:29 PM)perfringo Wrote: As I understand the objective one should iterate over values 0...99 and print row for every of them indicating from which coins and their quantities it can be derived.

As it is homework there are some options. First - to be smartass. There is no condition (at least presented here) that it should be presented as minimum amount of coins. So 1 penny * 0...99 and you get correct answer. Second option would be going against Zen of Python which states:

Quote:In the face of ambiguity, refuse the temptation to guess.

and start guessing what is the real objective of this homework. In this case divmod suggestion could be handy.


Thank you for all your help. I appreciate it. We were looking at Control Structures. I'm going to try to use what you said in your example in my Multiplication Table and see how it goes. I'm unsure if it will work or not.

If it doesn't, can I get back to you?

Thanks.


RE: Creating a change table - £0.01-£0.50? - DeaD_EyE - Oct-21-2022

I like the divmod solution.

def change(value: int, coins: list[int] | None = None):
    if coins is None:
        coins = [1, 2, 5, 10, 20, 50]

    result = []
    for coin in sorted(coins, reverse=True):
        amount, value = divmod(value, coin)
        result.extend([coin] * amount)

    return result
If the input is a float, convert it to an int.

my_float = float("1.23") # <- input data was a str
my_int = round(my_float * 100)
The problem here is, that round is scientific rounding and in financial rounding is required.
A better approach to convert the fraction right, is the use of Decimal.


from decimal import Decimal

user_input = input("Please enter a float: ")
# user_input is a str

value = Decimal(user_input)
# currency -> cent
value *= 100

# value is still a Decimal
# converting the value to an int
value = int(value)

print(value)
Then you can call change(value).

Output:
>>> change(1242) [50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 20, 20, 2]
The output is a bit long. It could be shorter with a dict. For example, you could use collections.Counter to count the amount of unique objects in the iterable (list).


Output:
>>> from collections import Counter >>> Counter(change(1242)) Counter({50: 24, 20: 2, 2: 1})



RE: Creating a change table - £0.01-£0.50? - DPaul - Oct-21-2022

I'm in two minds, because this is homework, and we are not supposed to ...
I first thought of modulo or the exotic divmod.
But the kiss fan in me decided that none of these is necessary if you
use a nested while in a for loop (only 4 lines of actual code).
Paul


RE: Creating a change table - £0.01-£0.50? - DPaul - Oct-22-2022

Without modulo or divmod:
cost = 51
paid = 100
coins = [50,20,10,5,2,1]
change = []
for coin in coins:
    while (paid - cost) / coin >= 1:
        change.append(coin)
        paid -= coin

print(change)
print(sum(change))
Output:
[20, 20, 5, 2, 2] 49