python unboundLocalError: local variable 'HighestStockName' referenced before assignment - python

I'm trying to write a program and am having a problem with one of my functions. When I try to run the program I get the following error about unboundLocalError. Can anyone help me with trying to fix this error?
def GetSale(Names, Prices, Exposure):
HighestStock = 0
for Stock in Names:
TotalProfit = ((Prices[Stock][1] - Prices[Stock][0]) - Exposure[Stock][1] *
Prices[Stock][0]) * Exposure[Stock][0]
if (TotalProfit > HighestStock):
HighestStock = TotalProfit
HighestStockName = Stock
print("Highest selling stock is", HighestStockName, "with a ", HighestStock, "profit margin.")

If the argument 'Names' is None or empty, or if the if (TotalProfit > HighestStock) condition is false...
print("Highest selling stock is", HighestStockName, "with a ", HighestStock, "profit margin.")
Will raise the UnboundLocalError because HighestStockName gets assigned within the if block of the for loop.
Perhaps try initializing the value 'HighestStockName' underneath HighestStock = 0 as such...
def GetSale(Names, Prices, Exposure):
HighestStock = 0
HighestStockName = ''
for Stock in Names:
TotalProfit = ((Prices[Stock][1] - Prices[Stock][0]) - Exposure[Stock][1] * Prices[Stock][0]) * Exposure[Stock][0]
if (TotalProfit > HighestStock):
HighestStock = TotalProfit
HighestStockName = Stock
print("Highest selling stock is", HighestStockName, "with a ", HighestStock, "profit margin.")
Or just catch the UnboundLocalError exception and figure out what to do from there...
def GetSale(Names, Prices, Exposure):
HighestStock = 0
for Stock in Names:
TotalProfit = ((Prices[Stock][1] - Prices[Stock][0]) - Exposure[Stock][1] * Prices[Stock][0]) * Exposure[Stock][0]
if (TotalProfit > HighestStock):
HighestStock = TotalProfit
HighestStockName = Stock
try:
print("Highest selling stock is", HighestStockName, "with a ", HighestStock, "profit margin.")
except UnboundLocalError, e:
# Do something after catching the exception

Consider that if all of the calculations of TotalProfit end up being 0 or negative, you never enter the inner if block, and therefore, the HighestStockName is never assigned/defined.

Related

Build a program that will help the company store and analyze sales data

I have to write a program that writes a file for a company and analyzes the sales data.
request_countryname function has to validate the user's input is at least 2 characters long
request_sales function has to accept 2 parameters (product and country), request the user for input on the total sales for each product of that country, and validate that the amount is numeric and non negative
request_data function will iteratively request country names from the user using the above functions and will ask if the user wants to add another country. Once the user is finished, the program will display how many records were added to the file. The program will write a file name (sales_data.txt)
analyze_data function will calculate the average sales per country for each type of product, total amount of sales for each product type, and total amount of sales
I am having trouble with the analyze_data function. I keep getting an error saying some of my variable from the request_data function are undefined. I believe this is happening because these variables (such as software_accumulator) are defined locally, not globally. I tried calling the request_data function at the beginning of my analyze_data function to call the information I wrote in the file, but I am still getting an error. I am also not sure if I correctly used accumulators to calculate the totals for each product type.
How do I fix this?
#Request country name from user
#Country name must be at least 2 characters long
def request_countryname():
character_length = 2
while True:
country = input("Please enter the country's name: ")
if len(country) < character_length or not country.isalpha():
print("Name must be at least 2 characters.")
else:
return country
#Request total sales for each product type for the user's country
#Input must be numeric and non negative
def request_sales(product, country_name):
flag = -1
while flag < 0:
sales = input("Please enter the total sales for " + product + " in " + country_name + ": $ ")
try:
sales = float(sales)
except ValueError:
print("Amount must be numeric")
else:
if sales < 0 :
print("Amount must be numeric and and non-negative. ")
else:
flag = 1
return sales
#Iteratively requests country names from the user and asks for totals
#Once the user finishes inputting countries, program will store data to a file
#Program will display total number of records added
def request_data(sales_data):
sales_data = open(sales_data, "w")
count = 0
software_accumulator = 0
hardware_accumulator = 0
accessories_accumulator = 0
again = "y"
while again == "y" or again == "Y":
country_name = request_countryname()
software = request_sales("software", country_name)
hardware = request_sales("hardware", country_name)
accessories = request_sales("accessories", country_name)
#Write data to file
sales_data.write(country_name + '/n')
sales_data.write(software + '/n')
sales_data.write(hardware + '/n')
sales_data.write(accessories + '/n')
count += 1
software_accumulator += software
hardware_accumulator += hardware
accessories_accumulator += accessories
#Request country names from user
again = input("Do you want to add another country? (Enter y/Y for Yes: ")
#Displays total number of records added
print(count, " record(s) successfully added to file")
sales_data.close()
#Calculates and displays information
def analyze_data(sales_data):
sales_data = open(sales_data, "r")
sales_data = request_data(sales_data)
#Calculates total software of all country inputs
total_software = software_accumulator
#Calculates total hardware of all country inputs
total_hardware = hardware_accumulator
#Calculates total accessories of all country inputs
total_accessories = accessories_accumulator
#Calcuates average software
average_software = total_software / count
#Calcuates average hardware
average_hardware = total_hardware / count
#Calcuates average accessories
average_accessories = total_accessories / count
#Calculates total sales
total_sales = total_software + total_hardware + total_accessories
#Prints and displays calculations
print("----------------------------")
print()
print("Average software sales per country: $ ", format(average_software, ',.2f'))
print("Average hardware sales per country: $ ", format(average_hardware, ',.2f'))
print("Average accessories sales per country: $ ", format(average_accessories, ',.2f'))
print()
print("Total software sales: $ ", format(total_software, ',.2f'))
print("Total hardware sales: $ ", format(total_hardware, ',.2f'))
print("Total accessories sales: $ ", format(total_accessories, ',.2f'))
print()
print("Total sales: $ ", format(total_sales, ',.2f'))
#Defines main function
def main():
request_data("sales_data.txt")
analyze_data("sales_data.txt")
#Calls main function
main()
You are correct in your hunch it has to do with the scope the variable are in, pay attention to where you define your variables, once you exit a function all variables in that functions scope will be gone. Don't use global variables, but return values you need from a function.
I suggest using an IDE to develop in as well, they will tell you when you are accessing a variable that is not in scope (ie not defined) - PyCharm or VSCode are both highly accessible
IDE says function isn't returning value
IDE says variable not defined

Return value doesn't work in Python 3 [duplicate]

This question already has answers here:
How do I get a result (output) from a function? How can I use the result later?
(4 answers)
Alternatives for returning multiple values from a Python function [closed]
(14 answers)
Closed 3 years ago.
It seems like I can't pass a value from a function to another even though I have put a return statement in the 1st function.
This is my code:
price=0
TotalPrice=0
def SumPrice(price,TotalPrice):
if cup_cone=="cup":
price=(price+(mass/10)*0.59)*TotalSet
else:
if cone_size=="small":
price=(price+2)*TotalSet
else:
if cone_size=="medium":
price=(price+3)*TotalSet
else:
price=(price+4)*TotalSet
if Member_Ans=="yes":
TotalPrice=TotalPrice+price*0.90
print(price,TotalPrice)
return (price)
return (TotalPrice)
def PrintDetails(price,TotalPrice,Balance):
SumPrice(price,TotalPrice)
if Member_Ans=="yes":
print("Member ID: ", loginID, " (" , Username, ")")
for element in range (len(UserFlavor)):
print (UserFlavor[element], "--- ", UserFlavorPercentage[element], "%")
print ("Total set = ", TotalSet)
print ("Total price = RM %.2f" % (price))
if Member_Ans=="yes":
print ("Price after 10% discount = RM %.2f" % (TotalPrice))
while True:
Payment=int(input("Please enter your payment: "))
if Payment<TotalPrice:
print("Not enough payment.")
if Payment >= TotalPrice:
break
Balance=Balance+(Payment-TotalPrice)
print(Balance)
PrintDetails(price,TotalPrice,Balance)
When I try to print the price and TotalPrice, it prints 0, why?
You are trying to use return twice, which is not allowed (your function will end as soon as it reaches the 1st return statement, making the other one useless).
You can, however, return both values in one statement:
return (price, TotalPrice)
And then assign the value to a tuple or anything else you would like:
my_tuple = SumPrice(a, b)
or
var1, var2 = SumPrice(a, b)
Your second return statement of first function is not reachable! btw try to not use global variables in your code, instead access return values of your first function.
def SumPrice():
price = 0
TotalPrice = 0
if cup_cone=="cup":
price=(price+(mass/10)*0.59)*TotalSet
else:
if cone_size=="small":
price=(price+2)*TotalSet
else:
if cone_size=="medium":
price=(price+3)*TotalSet
else:
price=(price+4)*TotalSet
if Member_Ans=="yes":
TotalPrice=TotalPrice+price*0.90
return price, TotalPrice
def PrintDetails():
price, TotalPrice = SumPrice()
if Member_Ans=="yes":
print("Member ID: ", loginID, " (" , Username, ")")
for element in range (len(UserFlavor)):
print (UserFlavor[element], "--- ", UserFlavorPercentage[element], "%")
print ("Total set = ", TotalSet)
print ("Total price = RM %.2f" % (price))
if Member_Ans=="yes":
print ("Price after 10%% discount = RM %.2f" % (TotalPrice))
while True:
Payment=int(input("Please enter your payment: "))
if Payment<TotalPrice:
print("Not enough payment.")
if Payment >= TotalPrice:
break
Balance=Balance+(Payment-TotalPrice)
print(Balance)
PrintDetails()

NameError: Global Name not defined

my python code keeps getting nameerror, global variable not defined on ticketSold. I am not sure how to fix this, as I did define it as a global variable. Any help is appreciated.
aLimit=300
bLimit=500
cLimit=100
aPrice=20
bPrice=15
cPrice=10
def Main():
global ticketSold
getTickets(aLimit)
sectionIncome=calcIncome(ticketSold,aPrice)
SectionIncome+=totalIncome
print("The theater generated this much money from section A "+str(sectionIncome))
getTickets(bLimit)
sectionIncome=calcIncome(ticketSold,bPrice)
SectionIncome+=totalIncome
print("The theater generated this much money from section B "+str(sectionIncome))
getTickets(cLimit)
sectionIncome=calcIncome(ticketSold,cPrice)
sectionIncome+=totalIncome
print("The theater generated this much money from section C "+str(sectionIncome))
print("The Theater generated "+str(totalIncome)+" total in ticket sales.")
def getTickets(limit):
ticketSold=int(input("How many tickets were sold? "))
if (ticketsValid(ticketSold,limit)==True):
return ticketSold
else:
getTickets(limit)
def ticketsValid(ticketSold,limit):
while (ticketSold>limit or ticketSold<0):
print ("ERROR: There must be tickets less than "+str(limit)+" and more than 0")
return False
return True
def calcIncome(ticketSold,price):
return ticketSold*price
Saying global varname does not magically create varname for you. You have to declare ticketSold in the global namespace, for example after cPrice=10. global only makes sure that when you say ticketSold, you're using the global variable named ticketSold and not a local variable by that same name.
Here is a version which:
is Python 2 / 3 compatible
does not use any global variables
is easily extended to any number of sections
demonstrates some benefits of OOP (as opposed to a proliferation of named variables: aLimit, bLimit, etc - what will you do when you reach 27 sections?)
And so:
import sys
if sys.hexversion < 0x3000000:
# Python 2.x
inp = raw_input
else:
# Python 3.x
inp = input
def get_int(prompt):
while True:
try:
return int(inp(prompt))
except ValueError: # could not convert to int
pass
class Section:
def __init__(self, name, seats, price, sold):
self.name = name
self.seats = seats
self.price = price
self.sold = sold
def empty_seats(self):
return self.seats - self.sold
def gross_income(self):
return self.sold * self.price
def sell(self, seats):
if 0 <= seats <= self.empty_seats():
self.sold += seats
else:
raise ValueError("Cannot sell {} seats, only {} are available".format(seats, self.empty_seats))
def main():
# create the available sections
sections = [
Section("Loge", 300, 20., 0),
Section("Floor", 500, 15., 0),
Section("Wings", 100, 10., 0)
]
# get section seat sales
for section in sections:
prompt = "\nHow many seats were sold in the {} Section? ".format(section.name)
while True:
# prompt repeatedly until a valid number of seats is sold
try:
section.sell(get_int(prompt))
break
except ValueError as v:
print(v)
# report section earnings
print("The theatre earned ${:0.2f} from the {} Section".format(section.gross_income(), section.name))
# report total earnings
total_earnings = sum(section.gross_income() for section in sections)
print("\nTotal income was ${:0.2f} on ticket sales.".format(total_earnings))
if __name__=="__main__":
main()
which gives us
How many seats were sold in the Loge Section? 300
The theatre earned $6000.00 from the Loge Section
How many seats were sold in the Floor Section? 300
The theatre earned $4500.00 from the Floor Section
How many seats were sold in the Wings Section? 100
The theatre earned $1000.00 from the Wings Section
Total income was $11500.00 on ticket sales.

How do I fix this syntax error? I am confused

Here is all my coding that I did but I keep getting this syntax error. It will be explained more at the bottom.
def main():
ActualValue()
AssessedValue()
printResult()
def ActualValue()
global actual_value
actual_value = float(input("Enter actual value:\t"))
def AssessedValue()
global assessed_value
global property_tax
assessed_value = 0.6 * actual_value
property_tax = assessed_value / 100 * 0.64
def printResult():
print "n\For a property valued at $", actual_value
print "The assessed value is $", assessed_value
print "The property tax is $", property_tax
actual_value = None
assessed_value = None
property_tax = None
main()
That is my code:
It keeps saying that I have a syntax error:
def printResult():
print "n\For a property valued at $", actual_value
print "The assessed value is $", assessed_value
print "The property tax is $", property_tax
You have the \n escape sequence backwards.
Also, you need to make sure all your function definitions have a colon on the end of the line.
Also, print is a function in Python 3.
print is a function in Python 3:
def printResult():
print("\nFor a property valued at $", actual_value)
print("The assessed value is $", assessed_value)
print("The property tax is $", property_tax)
I fixed your \n newline escape code for you as well.
You probably want to use the .format() method to format your output:
def printResult():
print("\nFor a property valued at ${0}".format(actual_value))
print("The assessed value is ${0}".format(assessed_value))
print("The property tax is ${0}".format(property_tax))
Just to clarify what Platinum Azure said.
def main():
actualValue()
assessedValue()
printResult()
def actualValue():
global actual_value
actual_value = float(input("Enter actual value:\t"))
def assessedValue():
global assessed_value
global property_tax
assessed_value = 0.6 * actual_value
property_tax = assessed_value / 100 * 0.64
def printResult():
print "\nFor a property valued at $", actual_value
print "The assessed value is $", assessed_value
print "The property tax is $", property_tax
actual_value = None
assessed_value = None
property_tax = None
main()
This should work

Calculations in module / While Loop / Transferring Variables

I'm very new to python and I'm stuck in some basic problems.
I can't seem to be able to put most of my calculations in a module. If I do, the results are not transferable and they will always show up as 0.0.
Once I'm able to put my calculations in a module, I can put the module inside a loop and ask the user if he wants to repeat the action.
This is my main issue too :: I want to "store" the output (displayResults) of each of the items (item number, price, etc) and print all of them once the loop is cancelled.
Thanks! I'm having a pretty difficult time trying to figure this out.
Here is my code:
#Mateo Marquez
#Oct. 8th, 2012
#P.O.S information system assigment
#
#Define Global Variables
TAX = 0.6
YELLOW_TAG = 0.10
BLUE_TAG = 0.20
RED_TAG = 0.25
GREEN_TAG = 0
#Main Module
def main():
tax_fee = 0.0
total_price = 0.0
introUser()
# I want this to be the mainCalc() function and return results.
productNumber=raw_input("Please enter the Product Number: ")
cost=float(raw_input("Please enter the cost of the selected product: "))
print " "
print "As you might have noticed, our discounts are color coded"
print "Yellow is 10%, Blue is 20% & Red is 25%"
print " "
tagDiscount=raw_input("Please enter the color tag: (yellow, blue, red or none)")
if tagDiscount == 'yellow':
print " "
print "You get a 10% discount"
total_price = (YELLOW_TAG*cost)
if tagDiscount == 'blue':
print " "
print "You get a 20% discount"
total_price = (BLUE_TAG*cost)
if tagDiscount == 'red':
print " "
print "You get a 25% discount"
total_price = (RED_TAG*cost)
if tagDiscount == 'none':
print " "
print "No discount for you!"
total_price = 0
print " "
print "~Remember~ this weekend is Tax Free in most of the country"
print "Green Tags designate if the product is tax free"
tagDiscount=raw_input("Does your product has a Green Tag? (yes or no)")
if tagDiscount == 'yes':
print " "
print "Good! your product is tax free"
tax_fee = 0
if tagDiscount == 'no':
print " "
print "I'm sorry, product", productNumber, "requires regular tax"
tax_fee = (TAX*total_price)
#I want this to be the end of the mainCalc() function
displayResults(total_price, tax_fee, cost, productNumber)
#Introduction function
def introUser():
print "Welcome to Wannabee's"
print "I'll gladly help you with your price question"
print "Let's start"
print " "
#Display results function
def displayResults(total_price, tax_fee, cost, productNumber):
print " "
print "Your Product Number: ", productNumber
print "Listed price of your product: $", cost
print "Your discount: $", total_price
print "Your Tax amount: $", tax_fee
print "Your grand total: $", (cost - total_price - tax_fee)
print " "
print "Your savings: ", ((cost-total_price)/cost*100),"%!"
main()
In order to save values used by related routines, put the variables and the routines that use them in a class. The following code defines a "POS" class and two method routines that share its variables. The "self." notation in the methods indicates a class variable that is saved in the instance "p" that is created when the class is instantiated with p = POS().
The example illustrates how the variables are stored; you'll need to adjust the inputs and print statements as needed (they're in Python 3 here). If you want to store the items as they are input and print them at the end, create an empty list in __init__, add a tuple to the list in mainCalc(), and print out each of the list items in displayResults().
class POS:
def __init__(self):
self.taxrate = 0.06
self.disc = {"": 0.0, "yellow": 0.10, "blue": 0.20, "red": 0.25}
self.total = 0
self.savings = 0
self.tax = 0
def mainCalc(self, item, qty, cost, tag, taxable):
print(qty, "* Item", item, "# ${:.2f}".format(cost),
"= ${:.2f}".format(qty*cost))
discount = cost * self.disc[tag]
if (tag):
print(" You get a", int(100*self.disc[tag]),
"% discount ${:.2f}".format(discount), "for", tag, "tag")
self.total += qty * (cost - discount)
self.savings += discount
if (taxable == "yes"):
tax = qty * cost * self.taxrate
self.tax += tax
print(" tax ${:.2f}".format(tax))
else:
print(" tax free")
def displayResults(self):
print("----------------")
print("Your total: ${:.2f}".format(self.total))
print("Your savings: ${:.2f}".format(self.savings))
print("Your total tax: ${:.2f}".format(self.tax))
print("Grand total: ${:.2f}".format(self.total + self.tax))
return
p = POS()
# Item Qty Price Tag Taxable
items = [(1492, 1, 1.95, "yellow", "yes"),
(1524, 2, 4.50, "blue", "no"),
(2843, 1, 6.95, "blue", "yes"),
(1824, 3, 2.29, "", "yes")]
for i in items:
p.mainCalc(*i)
p.displayResults()
Running the example produces:
1 * Item 1492 # $1.95 = $1.95
You get a 10 % discount $0.20 for yellow tag
tax $0.12
2 * Item 1524 # $4.50 = $9.00
You get a 20 % discount $0.90 for blue tag
tax free
1 * Item 2843 # $6.95 = $6.95
You get a 20 % discount $1.39 for blue tag
tax $0.42
3 * Item 1824 # $2.29 = $6.87
tax $0.41
----------------
Your total: $21.39
Your savings: $2.49
Your total tax: $0.95
Grand total: $22.33
You should consider the following constraints:
A function can only be called after it has been defined by a def statement (your call to displayResults.
Functions cannot access variables that are defined locally in the body of another function definition.
To improve your code, either think about how the program should flow from an overall point of view, or use a class as suggested in Dave's answer.

Categories