Python Forum
Creating a change table - £0.01-£0.50?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Creating a change table - £0.01-£0.50?
#1
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.

Attached Files

Thumbnail(s)
   
Reply
#2
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.
Sig:
>>> import this

The UNIX philosophy: "Do one thing, and do it well."

"The danger of computers becoming like humans is not as great as the danger of humans becoming like computers." :~ Konrad Zuse

"Everything should be made as simple as possible, but not simpler." :~ Albert Einstein
Reply
#3
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?
Reply
#4
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.
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy

Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Reply
#5
(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)}")
Sig:
>>> import this

The UNIX philosophy: "Do one thing, and do it well."

"The danger of computers becoming like humans is not as great as the danger of humans becoming like computers." :~ Konrad Zuse

"Everything should be made as simple as possible, but not simpler." :~ Albert Einstein
Reply
#6
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.
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy

Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Reply
#7
(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.
Reply
#8
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})
Yoriz write Oct-22-2022, 07:48 AM:
https://python-forum.io/misc.php?action=help&hid=52 Wrote:Homework and No Effort Questions

This forum is focused on education. It exists to help people learn Python. We don’t exist to solve others’ problems, although that tends to be a happy byproduct of education. You should keep this in mind when writing replies.

It is highly advised that you do not post the full solution, even if the asker is putting in the effort. It is better to use hints with natural language rather than code if at all possible. Only after the author has something complete you may go all out.
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#9
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
It is more important to do the right thing, than to do the thing right.(P.Drucker)
Better is the enemy of good. (Montesquieu) = French version for 'kiss'.
Reply
#10
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
Yoriz write Oct-22-2022, 07:51 AM:
(Oct-21-2022, 09:04 AM)DPaul Wrote: I'm in two minds, because this is homework, and we are not supposed to ...

https://python-forum.io/misc.php?action=help&hid=52 Wrote:Homework and No Effort Questions

This forum is focused on education. It exists to help people learn Python. We don’t exist to solve others’ problems, although that tends to be a happy byproduct of education. You should keep this in mind when writing replies.

It is highly advised that you do not post the full solution, even if the asker is putting in the effort. It is better to use hints with natural language rather than code if at all possible. Only after the author has something complete you may go all out.
It is more important to do the right thing, than to do the thing right.(P.Drucker)
Better is the enemy of good. (Montesquieu) = French version for 'kiss'.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  creating a 3x3 multiplication table aditvaddi 1 3,634 Jun-18-2018, 06:05 AM
Last Post: volcano63
  Tricky estimating three models and creating a table: regression HellinPython 1 2,816 Oct-18-2017, 02:46 PM
Last Post: sparkz_alot

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020