Python Help - with “local variable referenced before assignment” - python

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

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)

Stray new line after user input

Whilst attempting CS50's PSET6, I was trying to create a double-half pyramid of a size specified by the user.
The pyramid is fine but there's a random new line after the user input and before the pyramid starts. How can I fix it? Any help is appreciated :D
The code is as follows
def main():
hashHeight = height()
create(hashHeight)
# get height
def height():
h = int(input("Height: "))
if h >= 1 and h <= 8:
return h
else:
height()
#print hash
def create(x):
for i in range(x + 1):
print(" " * (x - i) + "#" * i + " " + "#" * i)
main()
def main():
hashHeight = height()
create(hashHeight)
# get height
def height():
h = int(input("Height: "))
if h >= 1 and h <= 8:
return h
else:
height()
#print hash
def create(x):
for i in range(1, x + 1):
print(" " * (x - i) + "#" * i + " " + "#" * i)
main()

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))

Function that calculates change

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

string index out of range list iteration

I am fairly new to python, I am not sure on how to fix a index string out of range. it happens right after the while loop when I want to send mylist[i][0] to formatting function. Any pointer on my code in general would be awesome!
def formatting(str1):
if str1 == '?':
return True
else:
return False
while(i <= len(mylist)):
val = formatting(mylist[i][0])
if val == True:
str1 = mylist[i]
str2 = mylist[i+1]
i = i + 2
format_set(str1, str2)
else:
if format == True:
if (margin + count + len(mylist[i])) <= width:
if (i == (len(mylist)-1)):
list2.append(mylist[i])
print(" " * margin + " ".join(list2))
break
list2.append(mylist[i])
count += len(mylist[i])
i += 1
else:
print(" " * margin + " ".join(list2))
list2 = []
count = 0
else:
temp_margin = margin
temp_width = width
width = 60
margin = 0
if (margin + count + len(mylist[i])) <= width:
if (i == (len(mylist)-1)):
list2.append(mylist[i])
print(" " * margin + " ".join(list2))
margin = temp_margin
width = temp_width
break
list2.append(mylist[i])
count += len(mylist[i])
i += 1
else:
print(" " * margin + " ".join(list2))
list2 = []
count = 0
change
i <= len(mylist)
to
i < len(mylist)
In the last iteration of the while loop, i is referring to the last value. Hence,
str2 = mylist[i+1]
is trying to reference a string outside the allowed range and you get an error.
EDIT: Also, as Wcrousse mentioned, the while (i <= len(...)) should be changed to i < len(...) because indexes go from 0 - (length-1).

Categories