Function that calculates change - python

I want to write a function that calculates the change a machine has to give a customer. The function receives the cost of the product, the sum of money the customer gave and a dictionary that has the money the machine has in it.
The function should give the smallest set of coins and bills and take into account the money available.
It should also avoid running out of any one kind of money; for example, if it has 2 of 10€ and 8 of 5€ it should not use the 2 of 10€ in the same change.
This is my dictionary:
d = {0.01: 10,
0.02: 5,
0.05: 2,
0.1: 10,
0.2: 5,
0.5: 2,
1: 5,
2: 5,
5: 2,
10: 4,
20: 5,
50: 1,
100: 0,
200: 0,
500: 0,
}
and this is my code so far:
def change(cost, given, d):
last_change = 0
change = given - cost #calculates how much we own the customer
if change == 0: #if we don't own the customer anything
return change
else:
if change in d and d[change] != 0: #if change is in the dictionary and its value is not 0 we can give it to the customer
return change
else:
euro = int(change)
cent = change - euro #calculates if we have to give any cents
if cent == 0: #if we only have to give bills
for item in d:
if item > last_change and item < change and d[item] != 0: #biggest bill we can give the customer
last_change = item
I don't know what to do next.

from math import *
dict1 = {0.01: 10,
0.02: 5,
0.05: 2,
0.1: 10,
0.2: 5,
0.5: 2,
1: 5,
2: 5,
5: 2,
10: 4,
20: 5,
50: 1,
100: 0,
200: 0,
500: 0,
}
def change(cost, given, dict1):
last_change = 0
change = given - cost
if change == 0:
print change
else:
if change in dict1 and dict1[change] != 0:
print change
else:
if change >= 500 and dict1[change] != 0:
a = floor( change / 500 )
print a, " --500 's"
change = change - ( a * 500 )
if change >= 200 and dict1[change] != 0:
b = floor( change / 200 )
print b, " --200 's"
change = change - ( b * 200 )
if change >= 100 and dict1[change] != 0:
c = floor( change / 100 )
print c, " --100 's"
change = change - ( c * 100 )
if change >= 50 and dict1[change] != 0:
d = floor( change / 50 )
print d, " --50 's"
change = change - ( d * 50 )
if change >= 20 and dict1[change] != 0:
e = floor( change / 20 )
print e, " --20 's"
change = change - ( e * 20 )
if change >= 10 and dict1[change] != 0:
f = floor( change / 10 )
print f, " --10 's"
change = change - ( f * 20 )
if change >= 5 and dict1[change] != 0:
g = floor( change / 5 )
print g, " --5 's"
change = change - ( g * 5 )
if change >= 2 and dict1[change] != 0:
h = floor( change / 2 )
print h, " --2 's"
change = change - ( h * 2 )
if change >= 1 and dict1[change] != 0:
i = floor( change / 1 )
print i, " --1 's"
change = change - ( i * 1 )
if change >= 0.5 and dict1[change] != 0:
j = floor( change / 0.5 )
print j, " --0.5 's"
change = change - ( j * 0.5 )
if change >= 0.2 and dict1[change] != 0:
k = floor( change / 0.2 )
print k, " --0.2 's"
change = change - ( k * 0.2 )
---------------------------
---------------------------
---------------------------
---------------------------
implement similar steps for 0.1,0.05,0.02,0.01
Output will be like this:
1 - 500 's
2 - 200 's
2 - 100 's
1 - 20 's

Here is some pseudo-code - there are some details you have to fill in:
amount = ... the input amount ...
change = {}
for denomination in [500, 200, 100, 50, ...]:
if amount == 0:
break
n = ... number of coins of this denomination to use
change[denomination] = n # store it
amount = amount - n*denomination # subtract from amount
# the dictionary change contains how to make the change

Related

calculate Output Change in the least amount of coins/notes for change using Python

The code provided below is not giving the output for "calculate Output Change in the least amount of coins/notes for change". I am new with Phyton and trying to learn, so anyone can help me spotting out and correcting what I have done wrong?. This application must- take inputs: Time in, Time Out; Output Cost, then ask for Payment in and the calculate Output Change in the least amount of coins/notes for change. The code is asking for inputs but not giving an output of calculating output change in least amount of coins/notes for change.
def print_euros(money, val):
while money <= val:
print("£" + str(val), end=", ")
money -= val
return money
def print_p(money, val):
while money <= val:
print(str(val), end="p,")
money -= val
return money
in_hour, in_min = map(int, input().split(':'))
out_hour, out_min = map(int, input().split(':'))
payment_in = input().split(',')
money_in = []
for i in payment_in:
money_in.append(int(i[1:]))
tot_money = sum(money_in)
tot_hours = 0
if out_hour <= in_hour:
tot_hours = 24 - in_hour + out_hour
else:
tot_hours = abs(out_hour - in_hour)
tot_mins = 0
if out_min <= in_min:
tot_mins = 60 - in_min + out_min
else:
tot_mins = abs(out_min - in_min)
if tot_mins == 60:
tot_hours += 1
tot_mins = 0
output_cost = tot_hours * 3
print("Output cost : £" + str(output_cost) + "." + str(tot_mins))
rem_change = 0
if tot_mins > 0:
rem_change = 100 - tot_mins
tot_money = tot_money - output_cost - 1
else:
tot_money -= output_cost
print("output change : ", end="")
tot_money = print_euros(tot_money, 20)
tot_money = print_euros(tot_money, 10)
tot_money = print_euros(tot_money, 5)
tot_money = print_euros(tot_money, 1)
rem_change = print_p(rem_change, 50)
rem_change = print_p(rem_change, 20)
rem_change = print_p(rem_change, 10)
rem_change = print_p(rem_change, 5)
rem_change = print_p(rem_change, 2)
rem_change = print_p(rem_change, 1)

Python Help - with “local variable referenced before assignment”

I have had problems with the shell saying local variable referenced before assignment and don't feel any previous answers have helped. Can I have some specific advice to this code:
Error : TotalExcessCharge = ExcessOneCharge + ExcessTwoCharge + ExcessThreeCharge + ExcessFourCharge + ExcessFiveCharge + ExcessPlusLimitCharge
UnboundLocalError: local variable 'ExcessThreeCharge' referenced before assignment
def BillingSystem(CustomerName,CustomerType,TotalGBUsed):
StandardCustomer = 1500
StandardQuota = 25
PremiumCustomer = 2500
PremiumQuota = 50
if (CustomerType == "Standard") or (CustomerType == "standard"):
if (TotalGBUsed > StandardQuota):
ExcessGB = TotalGBUsed - StandardQuota
for a in range(0, ExcessGB):
if (a <= 10):
ExcessOne = 250
ExcessOneCharge = a * ExcessOne
for b in range(0, ExcessGB):
if (b > 10) and (b <= 20):
ExcessTwo = 500
ExcessTwoCharge = b * ExcessTwo
for c in range(0, ExcessGB):
if (c > 20) and (c <= 30):
ExcessThree = 750
ExcessThreeCharge = c * ExcessThree
for d in range(0, ExcessGB):
if (d > 30) and (d <= 40):
ExcessFour = 1000
ExcessFourCharge = d * ExcessFour
for e in range(0, ExcessGB):
if (e > 40) and (e <= 50):
ExcessFive = 1250
ExcessFiveCharge = e * ExcessFive
for explus in range(0, ExcessGB):
if (explus > 50):
ExcessPlusLimit = 1500
ExcessPlusLimitCharge = explus * ExcessPlusLimit
TotalExcessCharge = ExcessOneCharge + ExcessTwoCharge + ExcessThreeCharge + ExcessFourCharge + ExcessFiveCharge + ExcessPlusLimitCharge
TotalCharge = StandardCustomer + TotalExcessCharge
print ("Total Excess Charge : " + str(TotalExcessCharge))
print ("Total Charge for this month : " + str(TotalCharge))
else:
print ("Total Excess Charge : 0")
print ("Total Charge for this month : " + str(StandardCustomer))
CName = input("[!] Customer Name : ")
CType = input("[!] Customer Type : ")
TotGB = int(input("[!] Total GB Usage : "))
BillingSystem(CName,CType,TotGB)
Obviously, at this point:
TotalExcessCharge = ExcessOneCharge + ExcessTwoCharge + ExcessThreeCharge + ExcessFourCharge + ExcessFiveCharge + ExcessPlusLimitCharge
your ExcessThreeCharge variable have not yet been assigned to, and that's because you assign to it under conditional:
for c in range(0, ExcessGB):
if (c > 20) and (c <= 30):
ExcessThree = 750
ExcessThreeCharge = c * ExcessThree
which might never be satisfied if ExcessDB is <= 20.
I'll not advise you how to fix it because, frankly, I do not understand the underlying logic of this code - it seems completely nonsensical to me.
The problem here is when your code doesn't go into the if conditions, your variables never get initiated but you have referred them at the end...So the error clearly tells you that you are calling the variable that you have never created or assigned. Always ensure that you refer the assigned variables!
And also you can make your code more easier to read like
using Excess# values directly inside the if conditions without assigning it to a variable.
using upper function on the input string and compare the value in one go..
def BillingSystem(CustomerName,CustomerType,TotalGBUsed):
StandardCustomer = 1500
StandardQuota = 25
PremiumCustomer = 2500
PremiumQuota = 50
ExcessOneCharge=0
ExcessTwoCharge=0
ExcessThreeCharge=0
ExcessFourCharge=0
ExcessFiveCharge=0
ExcessPlusLimitCharge=0
if (CustomerType.upper() == "STANDARD"):
if (TotalGBUsed > StandardQuota):
ExcessGB = TotalGBUsed - StandardQuota
for a in range(0, ExcessGB):
if (a <= 10):
ExcessOneCharge = a * 250
elif (a > 10) and (a <= 20):
ExcessTwoCharge = (a - 10) * 500
elif (a > 20) and (a <= 30):
ExcessThreeCharge = (a - 20) * 750
elif (a > 30) and (a <= 40):
ExcessFourCharge = (a - 30) * 1000
elif (a > 40) and (a <= 50):
ExcessFiveCharge = (a - 40) * 1250
elif (a > 50):
ExcessPlusLimitCharge = (a - 50) * 1500
TotalExcessCharge = ExcessOneCharge +
ExcessTwoCharge +
ExcessThreeCharge +
ExcessFourCharge +
ExcessFiveCharge +
ExcessPlusLimitCharge
TotalCharge = StandardCustomer + TotalExcessCharge
print ("Total Excess Charge : ", TotalExcessCharge)
print ("Total Charge for this month : ", TotalCharge)
else:
print ("Total Excess Charge : 0")
print ("Total Charge for this month : ", StandardCustomer)
CName = input("[!] Customer Name : ")
CType = input("[!] Customer Type : ")
TotGB = int(input("[!] Total GB Usage : "))
BillingSystem(CName,CType,TotGB)
And also instead of creating ExcessOneCharge, ExcessTwoCharge variables etc... You can do something like :
TotalExcessCharge = 0 #don't forget to initiate the variable at the beginning of the function
#then inside the if conditions
TotalExcessCharge += a*Excess#
This is just an example of how to write a cleaner code...logics you can apply as per your requirements!
Note : I'm typing everything in mobile, so pls ignore typos...
Because your definition of each of the "Excess#Charge" variables are within if statements, they seem not to be running for some reason. To fix this, I recommend defining all of the variables as 0 at the start so that if there is no excess value, it will simply be defined as 0. For example, at this at the top of the class:
ExcessOneCharge = 0
ExcessTwoCharge = 0
ExcessThreeCharge = 0
ExcessFourCharge = 0
ExcessFiveCharge = 0
ExcessPlusLimitCharge = 0

PYTHON 3.0 Negative numbers aren't working as inputs

I'm trying to make a factoring program, but it doesn't seem to work with negative number a-, b- and c-inputs.
from fractions import gcd
factor = -1
opp = 0
number = 1
success = 0
a = int(input("a-value: "))
b = int(input("b-value: "))
c = int(input("c-value: "))
factors = []
d = 0
e = 0
while number <= abs(a*c):
#Checking for multiples
if abs(a*c) % number == 0:
factor += 1
factors.append(number)
number += 1
while (factor-opp) >= 0:
#Checking for actual factors
d = int(factors[factor])
e = int(factors[opp])
if (abs(d+e) or abs(d-e)) == abs(b):
success += 1
break
else:
factor -= 1
opp += 1
if success > 0:
if (d+e) == b:
e = e
elif (d-e) == b:
e -= 2*e
elif (e-d) == b:
d -= 2*d
elif (-d-e) == b:
d -= 2*d
e -= 2*e
#Figuring out the equation
if d % a == 0:
d /= a
f = 1
else:
f = a/gcd(d,a)
d /= gcd(d,a)
if e % a == 0:
e /= a
g = 1
else:
g = a/gcd(e,a)
e /= gcd(e,a)
#Displaying the answer
if d >= 0:
d = str("+" + str(int(d)))
if e >= 0:
e = str("+" + str(int(e)))
elif e < 0:
e = str(int(e))
else:
d = str(int(d))
if e >= 0:
e = str("+" + str(int(e)))
elif e < 0:
e = str(int(e))
if f == 1:
if g == 1:
print ("(x" + d + ")(x" + e + ")")
else:
g = str(int(g))
print ("(x" + d + ")(" + g + "x" + e + ")")
elif g == 1:
f = str(int(f))
print ("(" + f + "x" + d + ")(x" + e + ")")
else:
f = str(int(f))
g = str(int(g))
print ("(" + f + "x" + d + ")(" + g + "x" + e + ")")
else:
print("This equation cannot be factored into integers.")
More specifically, the problem is somewhere within this block, I think. I've tested it out with print statements:
while (factor-opp) >= 0:
#Checking for actual factors
d = int(factors[factor])
e = int(factors[opp])
if (abs(d+e) or abs(d-e)) == abs(b):
success += 1
break
else:
factor -= 1
opp += 1
I've searched everywhere: my programming textbook, online searches about inputting negatives, everything. What am I doing wrong here?
Ok I am able to reproduce your issue for a simple testcase like - a=1 , b=0, c=-4 .
The issue is in the line -
if (abs(d+e) or abs(d-e)) == abs(b):
This does not check whether abs(b) is equal to abs(d+e) or abs(d-e) , instead it first evaluates the result of (abs(d+e) or abs(d-e)) , which would return the first non-zero result , and then compare that against abs(b) , so for negative numbers this does not evaluate the result correctly. Change that condition to -
if abs(d+e) == abs(b) or abs(d-e) == abs(b):
or you can also use a set -
if abs(b) in {abs(d+e), abs(d-e)}: #Though I doubt if using set would give any performance improvement because of the overhead of creating a set.
Demo after changes -
a-value: 1
b-value: 0
c-value: -4
(x+2)(x-2)
a-value: 1
b-value: -1
c-value: -6
(x-3)(x+2)
One more thing, there is something you have not considered , when a=-1 , b=-4 , c=-4 , the result should come to -(x+2)(x+2) , but the current program results in (x+2)(x+2) .

print values after each 1000 step

I want to print value after every certain interval (1000) on last line of code than every single value.
DARTS=200000
hits = 0
throws = 0
rangen = RanGenerator()
pi = 0
avg = 0
mu = 0
var = 0
dev = 1
for i in range (1, DARTS):
throws += 1
x = rangen.rand()
y = rangen.rand()
z = rangen.rand()
tt = x**2 + y**2 + z**2
dist = sqrt(tt)
if dist <= 1.0:
hits = hits + 1.0
pi = 6 * (hits / throws)
avg = avg + pi
mu = avg/throws
var = (var+(mu-pi)**2)/throws
dev = sqrt(var)
print("%d: %s" % (i,dev))
This is easy with the modulo operator - it will print the values only when i is divisible by 1000:
if i % 1000 == 0:
print("%d: %s" % (i,dev))

How do I properly use a Callback in this code? (Kivy)

Why does this code not work? I think it's something to do with x1 being already defined because I get the error "UnboundLocalError: local variable 'x1' referenced before assignment" whenever I click b1. Please I've searched the entire Internet with no luck.... Sorry I'm relatively new to Python and programming.
import calendar
import datetime
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
now = datetime.datetime.now()
h = now.hour
m = now.minute
s = now.second
year = now.year
month = now.month
day = now.day
home = 'home.'
weekday1 = calendar.weekday(year, month, day)
if len(str(m)) == 1:
zero = '0'
else:
zero = ''
if len(str(s)) == 1:
zero1 = '0'
else:
zero1 = ''
if weekday1 == 0:
day = 'Monday'
time = '''Period 1/2/3/4 = History
Period 5/6 = Japanese'''
if h == 8 and m >= 40:
current = 'Homeroom.'
elif h == 9 or (h == 10 and m <= 40):
current = 'History.'
elif h == 10 and m > 40:
current = 'recess.'
elif h == 11 or (h == 12 and m <= 40):
current = 'History.'
elif (h == 12 and m > 40) or (h == 13 and m <= 20):
current = 'lunch.'
elif (h == 13 and m > 20) or h == 14:
current = 'Japanese.'
else:
current = home
elif weekday1 == 1:
day = 'Tuesday'
time = '''Period 1 = English
Period 2 = Maths
Period 3/4 = English
Period 5/6 = ICT'''
if h == 8 and m>= 40:
current = 'Homeroom.'
elif h == 9 and m <= 50:
current = 'English.'
elif (h == 9 and m > 50) or (h == 10 and m <= 40):
current = 'Maths.'
elif h == 10 and m > 40:
current = 'recess.'
elif h == 11 or (h == 12 and m <= 40):
current = 'English.'
elif (h == 12 and m > 40) or (h == 13 and m <= 20):
current = 'lunch.'
elif (h == 13 and m > 20) or h == 14:
current = 'ICT.'
else:
current = home
elif weekday1 == 2:
day = 'Wednesday'
time = '''Period 1/2 = Science Extended
Period 3 = English
Period 4 = Maths
Period 5/6 = Science'''
if h == 8 and m >= 40:
current = 'Homeroom.'
elif h == 9 or (h == 10 and m <= 40):
current = 'Science Extended.'
elif h == 10 and m > 40:
current = 'recess.'
elif h == 11 and m <= 50:
current = 'English.'
elif (h== 11 and m > 50) or (h == 12 and m <= 40):
current = 'Maths.'
elif (h == 12 and m > 40) or (h == 13 and m <= 20):
current = 'lunch.'
elif (h == 13 and m > 20) or h == 14:
current = 'Science.'
else:
current = home
elif weekday1 == 3:
day = 'Thursday'
time = '''Period 1/2 = Art
Period 3 = Science
Period 4 = Wellbeing
Period 5 = English
Period 6 = Maths'''
if h == 8 and m >= 40:
current = 'Homeroom.'
elif (h == 10 and m <= 40) or h == 9:
current = 'Art.'
elif h == 10 and m > 40:
current = 'recess.'
elif h == 11 and m <= 50:
current = 'Science.'
elif (h == 11 and m > 50) or (h == 12 and m <= 40):
current = 'Wellbeing.'
elif (h == 12 and m > 40) or (h == 13 and m < 20):
current = 'lunch.'
elif (h == 13 and m >= 20) or (h == 14 and m <= 10):
current = 'English.'
elif h == 14 and m > 10:
current = 'Maths.'
else:
current = home
elif weekday1 == 4:
day = 'Friday'
time = '''Period 1/2 = PE
Period 3 = English
Period 4 = Maths
Period 5/6 = Music'''
if h == 8 and m >= 40:
current = 'Homeroom.'
elif h == 9 or (h == 10 and m <= 40):
current = 'PE.'
elif h == 10 and m > 40:
current = 'recess.'
elif h == 11 and m <= 50:
current = 'English.'
elif (h == 11 and m > 50) or (h == 12 and m <= 40):
current = 'Maths.'
elif (h == 12 and m > 40) or (h == 13 and m < 20):
current = 'lunch.'
elif (h == 13 and m >= 20) or h == 14:
current = 'Music.'
else:
current = home
else:
day = 'a weekend'
time = 'You have none.'
if day == 'a weekend':
a = "You don't have to be anywhere."
else:
a = ('You should be at ' + current)
a1 = ('Today is ' + day + '.')
a2 = ('''Today your timetable is:
''' + time)
a3 = ('The current time is ' + str(h) + ':' + zero + str(m) + ':' + zero1 + str(s) + '.')
t1 = 'What is the day today?'
t2 = 'What is the current time?'
t3 = 'What is my timetable today?'
t4 = 'Where should I be?'
x1, x2, x3, x4 = '', '', '', ''
def callback1(object):
del x1
x1 = a1
def callback2(object):
x2 = a3
def callback3(object):
x3 = a2
def callback4(object):
x4 = a
b1 = Button(text = t1)
b1.bind(on_press = callback1)
layout = GridLayout(cols = 2)
layout.add_widget(b1)
layout.add_widget(Label(text = x1))
layout.add_widget(Button(text = t2))
layout.add_widget(Label(text = x2))
layout.add_widget(Button(text = t3))
layout.add_widget(Label(text = x3))
layout.add_widget(Button(text = t4))
layout.add_widget(Label(text = x4))
class TimeTable(App):
def build(self):
return layout
if __name__ == '__main__':
TimeTable().run()
Your error is because you try to delete a global variable (x1) in a local context (callback1), without declaring it as global before.
You could do:
global x1
del x1
But there is a more general issue with what you are trying to accomplish, when you say text = x1, it just passes the current value of x1 to the text property of the Label you create, and changing the value of x1 later has no effect on this, what you want is to change widget.text to the new value (and you should rename object to widget in these callbacks, object is the name of the base class in python, so you shouldn't use it as a parameter or anything).
Also, the way you structure your code won't work well in the long term, you should do more things in methods of your class (most of what you do before could be done in build).

Categories