I am getting the following error with my code:
UnboundLocalError: local variable 'row' referenced before assignment
I have tried many things, but nothing has worked. I suspect it is something to do around the 'quantityQuestion' subprogram. According to the scripter, the problem is at line 97.
import csv
import sys
global totalPrice
totalPrice = 0
addItem = ""
gtinNum = ""
quantity = 0
restart = ""
global receipt
receipt = open("receipt.txt", "w+")
global restockTxt
restockTxt = open("restock.txt", "w+")
global price
price = 0
global file2
file2 = open("ChocolateCSV2.csv", "r")
global file2w
file2w = open("ChocolateCSV2.csv", "w", newline="")
def restart():
restart = input("Would you like to restart? Y/N")
if restart.lower() == "y":
actionQ()
else:
print("Exiting program.")
file2.close()
sys.exit()
def priceSub(): #Defining the restart subprogram
priceQ = input("Would you like to add an item? Y/N") #Asks the user if they would like to add an item.
global totalPrice #Declaring totalPrice and making it global.
totalPrice = int(price) + totalPrice #Setting totalPrice to add the variable price to itself.
if priceQ.lower() == "y": #If statement that checks to see if the user has entered a "y".
gtinQuestion() #If it is true, it will start the gtinQuestion subprogram.
else: #Anything other than a "y" will do the following commands.
global receiptCont #Declaring the receipt content as a global variable.
receiptCont = receipt.read() #Reads the receipt.
receipt.close() #Closes the file.
print(receiptCont) #Prints the content of the receipt.
print("Total Price: " + "%.2f" % round(totalPrice, 2)) #Prints the totalPrice variable rounded to two decimal places.
restart()
def quantityQuestion(): #Defining the subprogram for the quantity.
quantity = input("How much would you like?") #Asks the user how much of the item they would like.
if quantity.isdigit() == False: #If statement to check whether or not the user has entered an integer or not.
quantityQuestion() #If they have not entered an integer, it will ask the question again.
global price #Declaring the variable price as a global variable.
price = "" #Setting price to an empty string.
reader = csv.reader(file2, delimiter = ",")
csvList = list(reader)
for row in csvList: #Loop that seperates each row in the CSV
if str(gtinNum) in row: #If statement to check if the GTIN given by the user is in the CSV.
receipt.write(str(row) + "\n") #If it is in one of the CSV rows, it will write the row to the text file.
receipt.write(str("- Quantity: " + quantity + "\n")) #It also writes the quantity given by the user.
price = float(row[2]) * int(quantity) #The price is the price given by the CSV file multiplied by the quantity.
receipt.write("- Price: " + str("%.2f" % round(price, 2)) + "\n") #The final price (after the multiplication) is written to the text file also.
row[2] = row[2] - quantity
writeCSV = csv.writer(file2w)
writeCSV.writerow(row)
file2w.close()
priceSub() #Starts the restart subprogram.
break #Breaks the loop.
else:
print("The code entered could not be found - Please re-enter") #If it is not in the CSV it will print this error message.
gtinQuestion() #Starts the gtinQuestion subprogram.
def gtinQuestion(): #Defining the gtinQuestion subprogram.
global gtinNum #Declaring the gtinNum variable as global.
gtinNum = input("Please enter the GTIN-8 Code of the product you would like to order:") #Setting that variable to the initial question.
if gtinNum.isdigit() == False or len(gtinNum) != 8: #If the code given is not an integer or is not 8 digits long...
print("Please re-enter your GTIN-8 code - Reason: Invalid Code") #It will print this error message and ask the question again.
gtinQuestion()
elif gtinNum.isdigit() == True and len(gtinNum) == 8: #If it is an integer and is 8 digits long...
quantityQuestion() #It will start the quantityQuestion subprogram.
def restockAction():
reader = csv.reader(file2, delimiter = ",")
csvList = list(reader)
for row in csvList:
stDiff = float(row[5]) - float(row[3])
if float(row[3]) <= float(row[4]):
restockTxt.write(row[0]+" | "+row[1]+" | "+"Stock Replenished: "+(str(stDiff)+"\n"))
restockTxt.close()
row[3] = row[5]
writeCSV = csv.writer(file2w)
writeCSV.writerows(csvList)
file2w.close()
else:
if float(row[3]) >= float(row[4]):
restockTxt.write("No (other) stock needs to be replenished.")
restockTxt.close()
restockRead = open("restock.txt", "r")
print(restockRead.read())
restart()
def actionQ():
restock = input("What action would you like to perform?:\n Restock (Enter 1)\n Order (Enter 2)")
if restock == "1" or restock == "restock":
print("Restock Action Requested...")
restockAction()
elif restock == "2" or restock == "order":
print("Ordering action Requested...")
gtinQuestion()
else:
actionQ()
actionQ()
Any help is appreciated,
Thanks.
The problem is in restockAction():
for row in csvList:
# some code
else:
if float(row[3]) >= float(row[4]):
# ^
If there are no rows in csvList, row will not have any value, since the for will not be executed, but the else block will be executed.
So row in the else block of the for has yet to defined.
Did you intend to attach the else to the if, not the for:
for row in csvList:
stDiff = float(row[5]) - float(row[3])
if float(row[3]) <= float(row[4]):
# ...
else:
# ...
You have to verify you have that you have any rows before checking whether row[index] has a value:
else:
if row and float(row[3]) >= float(row[4]):
restockTxt.write("No (other) stock needs to be replenished.")
restockTxt.close()
restockRead = open("restock.txt", "r")
print(restockRead.read())
restart()
if row and ... acts as a vanguard, protecting the interpreter from executing row[index]. If row is None, if row == False and it returns immediately without evaluating the rest of the statement.
Related
I will try to simplify this is as much as possible , My code is designed for a user to enter multiple products from a data base using a barcode , resulting in my program outputting in the name of the products they ordered and the total price of the products.
However my expected output of the code when it is first run is
GTIN = int(input("input your gtin-8 number: "))
return GTIN # Breaks the loop and returns the value
except:
print ("Oops! That was not a valid number. Try again")
However this code is first run at the end of the code as the starting line for some reason.
continue_shopping=int(input("press 0 to stop shopping and print your reciept or press 1 to continue shopping"))
if continue_shopping != 0 and continue_shopping != 1:
print("make sure you enter a valid number")
I would appreciate any helpful input or criticism for my code.
If you are interested here is the code as an entity on its own. Thank you for any help
import csv
import locale
from decimal import *
total_price = []
locale.setlocale( locale.LC_ALL, '' )
def read_csv_file():
global total_price
""" reads csv data and appends each row to list """
csv_data = []
with open("task2.csv") as csvfile:
spamreader = csv.reader(csvfile, delimiter=",", quotechar="|")
for row in spamreader:
csv_data.append(row)
return csv_data
def get_user_input():
global total_price
""" get input from user """
while True:
try:
GTIN = int(input("input your gtin-8 number: "))
return GTIN # Breaks the loop and returns the value
except:
print ("Oops! That was not a valid number. Try again")
def search_user_input(product_data):
global total_price
repeat=""
# Pass the csv data as an argument
""" search csv data for string """
keep_searching = True
while keep_searching:
gtin = get_user_input()
for row in product_data:
if row[0] == str(gtin):
product = row[1]
price = round(float(row[2]),2)
return(product, price)
while True:
try:
repeat = input("not in there? search again? If so (y), else press enter to continue")
break
except:
print("please make sure you enter a valid string")
if repeat != 'y':
keep_searching = False
return None
def quantity():
fileOne = open('receipt.csv', 'a')
writer = csv.writer(fileOne)
global total_price
product_data = read_csv_file()
matches = search_user_input(product_data)
if matches: # Will not be True if search_user_input returned None
print("apple")
product, price = matches[0], matches[1]
order = int(input("How much of {} do you want?".format(product)))
TWOPLACES = Decimal(10) ** -2
subt = order * pricea
subtotal = Decimal(subt).quantize(TWOPLACES)
values = [str(product), str(price), str(subtotal)]
print('values are ',values)
writer.writerows((values,))
total_price.append(order * price)
continue_shopping=int(input("press 0 to stop shopping and print your reciept or press 1 to continue shopping"))
if continue_shopping != 0 and continue_shopping != 1:
print("make sure you enter a valid number")
if (continue_shopping == 0):
fileOne.close()
fileTwo = open("receipt.csv" , "r")
reader = csv.reader(fileTwo)
for row in reader:
if row != None:
print(row)
elif continue_shopping==1:
quantity()
quantity()
when you create a function (that's what def does), it won't do anything until you instantiate the function. so, for instance, if you want to run the read_csv_file() function before you do ask whether the person is done shopping, you have to do this. (or something similar)
#all your functions are above this snippet.
read_csv_file()
continue_shopping=int(input("press 0 to stop shopping and print your reciept or press 1 to continue shopping"))
I hope this helps!
I have a variable in my code (named totalPrice) which will set itself to a price given and then when the user adds a product to their list it will add that price to totalPrice. However, when running it, it resets the variable to 0. I believe it has something to do with the placement of it as I have placed it inside a subprogram. I do not know what to do with it as I can't seem to find a place for it.
My code is as follows:
import csv
import sys
import re
import os
addItem = ""
gtinNum = ""
quantity = 0
restart = ""
f = open("ChocolateCSV.csv", "rt")
global receipt
receipt = open("receipt.txt", "w+")
def restart():
restart = input("Would you like to restart? Y/N")
if restart.lower() == "y":
gtinQuestion()
else:
global receiptCont
receiptCont = receipt.read()
receipt.close()
print(receiptCont)
print("Total Price: " + "%.2f" % round(totalPrice, 2))
sys.exit()
def quantityQuestion():
quantity = input("How much would you like?")
if quantity.isdigit() == False:
quantityQuestion()
global price
price = ""
global totalPrice
totalPrice = 0
with open("ChocolateCSV.csv", 'r') as file2:
for row in csv.reader(file2):
if str(gtinNum) in row:
receipt.write(str(row) + "\n")
receipt.write(str("- Quantity: " + quantity + "\n"))
price = float(row[2]) * int(quantity)
totalPrice += price
receipt.write("- Price: " + str("%.2f" % round(price, 2)) + "\n")
restart()
break
def gtinQuestion():
global gtinNum
gtinNum = input("Please enter the GTIN-8 Code of the product you would like to order:")
if gtinNum.isdigit() == False or len(gtinNum) != 8:
gtinQuestion()
elif gtinNum.isdigit() == True and len(gtinNum) == 8:
quantityQuestion()
gtinQuestion()
totalPrice is not global within restart().
also think of re-designing your code, there's a lot of dangerous recursion and global variables. E.g. if quantity.isdigit() == False: within quantityQuestion calls quantityQuestion and continues despite the error with the computation.
The whole point of having functions is to hide computation and variables inside. Use function parameters etc and learn clean python (try import this within a python console).
I am working with a CSV file for a program I am writing but I seem to be getting this error:
Traceback (most recent call last):
File "C:\Users\Jordan\Documents\Year 10\Computing\CA and Coursework\A453 Material 2\Task 3\Task 3.py", line 115, in <module>
actionQ()
File "C:\Users\Jordan\Documents\Year 10\Computing\CA and Coursework\A453`Material 2\Task 3\Task 3.py", line 111, in actionQ
gtinQuestion()
File "C:\Users\Jordan\Documents\Year 10\Computing\CA and Coursework\A453 Material 2\Task 3\Task 3.py", line 80, in gtinQuestion
quantityQuestion() #It will start the quantityQuestion subprogram.
File "C:\Users\Jordan\Documents\Year 10\Computing\CA and Coursework\A453 Material 2\Task 3\Task 3.py", line 52, in quantityQuestion
if float(row[3]) >= float(quantity):
IndexError: list index out of range`
I'm not quite sure how to approach it but I have never had this problem before. Initially, quantityQuestion was its own program but I have decided to place it with this other code for accessibility.
As a side note - I am unable to overwrite the third row so that the new stock can be updated in the CSV. (Any help on this is also appreciated).
Code:
import csv
import sys
global totalPrice
totalPrice = 0
addItem = ""
gtinNum = ""
quantity = 0
restart = ""
price = 0
receipt = open("receipt.txt", "w+")
restockTxt = open("restock.txt", "w+")
file = open("ChocolateCSV2.csv", "r")
def restart():
restart = input("Would you like to restart? Y/N")
if restart.lower() == "y":
actionQ()
else:
file.close()
print("Exiting program.")
sys.exit()
def priceSub(): #Defining the restart subprogram
priceQ = input("Would you like to add an item? Y/N") #Asks the user if they would like to add an item.
global totalPrice #Declaring totalPrice and making it global.
totalPrice = int(price) + totalPrice #Setting totalPrice to add the variable price to itself.
if priceQ.lower() == "y": #If statement that checks to see if the user has entered a "y".
gtinQuestion() #If it is true, it will start the gtinQuestion subprogram.
else: #Anything other than a "y" will do the following commands.
global receiptCont #Declaring the receipt content as a global variable.
receiptCont = receipt.read() #Reads the receipt.
receipt.close() #Closes the file.
print(receiptCont) #Prints the content of the receipt.
print("Total Price: " + "%.2f" % round(totalPrice, 2)) #Prints the totalPrice variable rounded to two decimal places.
restart()
def quantityQuestion(): #Defining the subprogram for the quantity.
quantity = input("How much would you like?") #Asks the user how much of the item they would like.
if quantity.isdigit() == False: #If statement to check whether or not the user has entered an integer or not.
quantityQuestion() #If they have not entered an integer, it will ask the question again.
global price #Declaring the variable price as a global variable.
price = "" #Setting price to an empty string.
with open("ChocolateCSV.csv", 'r') as file2:
for row in csv.reader(file2): #Loop that seperates each row in the CSV
if str(gtinNum) in row[0]: #If statement to check if the GTIN given by the user is in the CSV.
if float(row[3]) >= float(quantity):
receipt.write(str(row) + "\n") #If it is in one of the CSV rows, it will write the row to the text file.
receipt.write(str("- Quantity: " + quantity + "\n")) #It also writes the quantity given by the user.
price = float(row[2]) * int(quantity) #The price is the price given by the CSV file multiplied by the quantity.
receipt.write("- Price: " + str("%.2f" % round(price, 2)) + "\n") #The final price (after the multiplication) is written to the text file also.
updateStk = str(float(row[3]) - float(quantity))
row[3] = updateStk
file2w = open("ChocolateCSV2.csv", "w", newline = "")
writeCSV = csv.writer(file2w)
writeCSV.writerows(csvList)
file2w.close()
priceSub() #Starts the restart subprogram.
break #Breaks the loop.
elif float(row[3]) <= float(quantity):
print("There is not enough stock to allow you to purchase this item - Try again u nerd.")
gtinQuestion()
else:
print("The code entered could not be found - Please re-enter") #If it is not in the CSV it will print this error message.
gtinQuestion() #Starts the gtinQuestion subprogram.
def gtinQuestion(): #Defining the gtinQuestion subprogram.
global gtinNum #Declaring the gtinNum variable as global.
gtinNum = input("Please enter the GTIN-8 Code of the product you would like to order:") #Setting that variable to the initial question.
if gtinNum.isdigit() == False or len(gtinNum) != 8: #If the code given is not an integer or is not 8 digits long...
print("Please re-enter your GTIN-8 code - Reason: Invalid Code") #It will print this error message and ask the question again.
gtinQuestion()
elif gtinNum.isdigit() == True and len(gtinNum) == 8: #If it is an integer and is 8 digits long...
quantityQuestion() #It will start the quantityQuestion subprogram.
def restockAction():
reader = csv.reader(file, delimiter = ",")
csvList = list(reader)
for row in csvList:
stDiff = float(row[5]) - float(row[3])
if float(row[3]) <= float(row[4]):
restockTxt.write(row[0]+" | "+row[1]+" | "+"Stock Replenished: "+(str(stDiff)+"\n"))
row[3] = row[5]
file2w = open("ChocolateCSV2.csv", "w", newline = "")
writeCSV = csv.writer(file2w)
writeCSV.writerows(csvList)
file2w.close()
else:
restockTxt.write("No (other) stock needs to be replenished.")
restockTxt.close()
restockRead = open("restock.txt", "r") print(restockRead.read())
restart()
def actionQ():
restock = input("What action would you like to perform?:\n Restock (Enter 1)\n Order (Enter 2)")
if restock == "1" or restock == "restock":
print("Restock Action Requested...")
restockAction()
elif restock == "2" or restock == "order":
print("Ordering action Requested...")
gtinQuestion()
else:
actionQ()
actionQ()
CSV File:
12312313 Item 1 0.5 100 25 100
12345670 Item 2 0.2 100 25 100
76543210 Item 3 0.3 100 25 100
34563670 Item 4 0.4 100 25 100
I am having problems with trying to make my program find a certain cell in a CSV file. My program will ask you for a 8 digit number. If it is in the CSV file, the row should be written to a text file. It then should proceed to ask the user how much of the product they want to buy. This quantity will then be multiplied to give a final price. The price will be written to a variable named totalPrice.
My initial problem is with the quantity since I cannot retrieve it from the third column of the row of the entered GTIN-8 number in my CSV file.
My code is:
import csv
import sys
import re
import os
addItem = ""
gtinNum = ""
quantity = 0
totalPrice = 0
restart = ""
f = open("ChocolateCSV.csv", "rt")
def restart():
restart = input("Would you like to restart? Y/N")
if restart.lower() == "y":
gtinQuestion()
else:
print(receiptCont)
sys.exit()
def quantityQuestion():
quantity = input("How much would you like?")
def scanGTIN():
global rows
rows = re.split('\n', f.read())
global receiptCont
receiptCont = receipt.read()
for index, row in enumerate(rows):
global cells
cells = row.split(',')
if gtinNum in cells:
receipt.write(receiptCont)
receipt.close()
quantityQuestion()
def gtinQuestion():
global gtinNum
global receipt
receipt = open("receipt.txt", "r+")
gtinNum = input("Please enter the GTIN-8 Code of the product you would like to order:")
if gtinNum.isdigit() == False or len(gtinNum) != 8:
gtinQuestion()
elif gtinNum.isdigit() == True and len(gtinNum) == 8:
scanGTIN()
gtinQuestion()
You could just iterate through the lines of the csv file and return a particular column of the row that contains the 8 digit number:
import csv
def get_row(filename, number, column):
with open(filename, 'r') as f:
for row in csv.reader(f):
if str(number) in row:
return row[column+1]
I have below code where I have two functions print_menu() and pStockName()
def print_menu():
print ("\t\t\t\t 1. Get Stock Series ")
print ("\t\t\t\t 2. Invoke Stocks.")
print ("\t\t\t\t 3. Generate DC Stock List . ")
print ("\t\t\t\t 4. QUIT")
def pStockName():
global StockList, fStockList
pStockList = []
fStockList = []
StockList = str(raw_input('Enter pipe separated list of StockS : ')).upper().strip()
items = StockList.split("|")
count = len(items)
print 'Total Distint Stock Count : ', count
items = list(set(StockList.split("|")))
# pipelst = StockList.split('|')
# pipelst = [i.split('-mc')[0] for i in StockList.split('|')]
# pipelst = [i.replace('-mc','').replace('-MC','').replace('$','').replace('^','') for i in StockList.split('|')]
pipelst = [i.replace('-mc', '').replace('-MC', '').replace('$', '').replace('^', '') for i in items]
# pipelst = [Stock.rsplit('-mc',1)[0] for Stock in pipelst]
filepath = '/location/Stock_data.txt'
f = open(filepath, 'r')
for lns in f:
split_pipe = lns.split(':', 1)
if split_pipe[0] in pipelst:
index = pipelst.index(split_pipe[0])
pStockList = split_pipe[0] + "|"
fStockList.append(pStockList)
del pipelst[index]
# f.close()
for lns in pipelst:
print bcolors.red + lns, ' is wrong Stock Name' + bcolors.ENDC
if lns:
uResp = str(raw_input('Do You Want To Continue with option 0 [YES|Y|NO|N] : ')).upper().strip()
if uResp == "NO" or uResp == "N":
os.system("tput clear")
print bcolors.FAIL + "\n PLEASE USE OPTION 0 TO ENTER THE Stock NAMES BEFORE PROCEEDING." + bcolors.ENDC
# StockList = None
print_menu()
else:
pStockName()
f.close()
In above code you must be seeing in 4th last line I am calling print_menu() function. But it is just printing the content of print_menu() function not doing any operation and going to pStockName() function. Follow operation I want to execute from print_menu() function when I am calling it:
while choice >= 1 and choice < 4:
if choice == 4:
os.system("tput clear")
if StockList:
uResp = str(raw_input(
bcolors.FAIL + 'Do you need to move : ' + StockList + ' ? Press Y To Go Back to Main Menu and N to Quit [YES|Y|NO|N] : ')).upper()
if uResp == "NO" or uResp == "N":
print bcolors.HEADER + "GoodBye." + bcolors.ENDC
break
I mean to say when I am calling print_menu() function in pStockName() function in 4th last line from pStockName() function it should print the content of print_menu() function and when I press 4 it should perform the operation quit. But when I pressing any of the option from 1 to 4 it going to pStockName() function only.
Please help me what I am doing wrong here.
I'm a bit new here, but I do not see where you assign the keyboard input into variable "choice". Therefore, the program will not recognize what the end user input is. My suggestion is to assign "choice" into raw_input Like so:
choice = raw_input()
if choice == "4": # alternatively, perform int(choice) == 4
print ("yes")
I hope this helps!