How to stop a csv file overwriting - python

this code asks a user to input a barcode, my program then opens a csv file and accesses a database , there are 4 different products, the user eneters how many of the product they want and then asks if they want to keep shopping or press 0 and stop shopping and print a receipt (which is another csv file) , my problem is that my program does not take previous orders into account and only the last one , if that makes sense (if i order 3 tomatoes and then 4 pieces of celery it only takes the amount of celery into account). I want to apoligise for poor english as it is not my primary language. Here is the part of the code which i think is going wrong
def quantity():
fileOne = open('receipt.csv', 'w')
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)))
values = [str(product), str(price), str(order*price)]
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):
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()
Here is the rest of the code if you are curious.
import csv
import locale
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', 'w')
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)))
values = [str(product), str(price), str(order*price)]
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):
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()
I appreciate any help or advice or if you do not understand a part of my code i can try to explain

Related

Python, How to stop my code from showing position of my CSV file (No Panda)

The code I have written gives me the desired output (takes data from csv file) but it shows the position of the function, which is something I do not want.
Here's my code:
# Functions
import sys
from collections import Counter
import csv
def NC(filename: list) -> str:
print("----")
print("Precondition: You must type the FULL name of the genre with the EXACT same capital/lower case lettering.")
print("----")
x = input("Enter the category of the books: ")
category = []
with open('Google_Books_Dataset.csv', 'r') as csv_file:
csv_reader = csv.DictReader(csv_file)
c = Counter(row['generes'] for row in csv_reader)
result = print(c[x])
category.append(result)
return category
def CA(filename: list) -> str:
print("----")
print("Precondition: You must type the author's FULL name with the EXACT same capital/lower case lettering.")
print("----")
x = input("Enter the author's FULL name: ")
author_name = []
with open('Google_Books_Dataset.csv', 'r') as csv_file:
csv_reader = csv.DictReader(csv_file)
for row in csv_reader:
result = {'author': row['author'], 'category': row['generes']}
del result['author']
if (row['author'] in x):
author_name.append(result)
print(list(author_name))
return author_name
def CB(filename: list) -> str:
print("----")
print("Precondition: You must type the book's FULL name with the EXACT same capital/lower case lettering and special symbols (e.g. $ or *).")
print("----")
x = input("Enter the book's FULL name: ")
book_name = []
with open('Google_Books_Dataset.csv', 'r') as csv_file:
csv_reader = csv.DictReader(csv_file)
for row in csv_reader:
result = {'title': row['title'], 'category': row['generes']}
del result['title']
if (row['title'] in x):
book_name.append(result)
print(list(book_name))
return book_name
def Q(x: str) -> str:
x = input("Enter quit: ")
if (x == "quit"):
print("END")
sys.exit()
# Command Line
print("Precondition: ALL commands must be of capital case.")
print("----")
x = input("Enter command: ")
List = ["NC", "CA", "CB", "Q"]
while (x != List):
if x == List[0]:
name = []
NC(name)
print(NC)
if x == List[1]:
name = []
CA(name)
print(CA)
if x == List[2]:
name = []
CB(name)
print(CB)
if x == List[3]:
name = []
Q(name)
print(Q)
else:
x = input("Enter command: ")
All of my functions always give back the function position, I don't know why.
For example, if I run my code and enter a command (Like NC), then my out would be:
Precondition: ALL commands must be of capital case.
----
Enter command: NC
----
Precondition: You must type the FULL name of the genre with the EXACT same capital/lower case lettering.
----
Enter the category of the books: Fiction
39
<function NC at 0x0000018E43A95670>
Enter command: ...
The <function NC at 0x0000018E43A95670> is not wanted. And all my other codes, other than the Quit command yield the position as well. How should I work around this?
You are directly printing function. Just it is printing an address. So kick out print(NC). I believe you are trying to print list of book names. So it is a list of strings you need to print.
If you really need to print book, replace print(NC) with
nc = NC(name)
print(nc)
Definitely it will work. Easy-Peasy ;)

Python only printing last data entered

I have an assignment to create a class that holds the name of an employee, id number, department, and job title. The user should be able to input the information for multiple employees and have all of the information printed out at the end.
The problem I am facing is that only the last employee's information is being printed out.
import pickle
import employee
data = 'data.dat'
def main():
output_file = open(data, 'wb')
end_of_file = False
keep_going = 'Y'
while keep_going == 'Y':
name = str(input('Name of employee: '))
ID_num = int(input('Employee ID number: '))
dep = str(input('Department: '))
job = str(input('Job Title: '))
emp = employee.Employee(name, ID_num)
emp.set_department(dep)
emp.set_job_title(job)
pickle.dump(emp, output_file)
keep_going = input('Enter another employee file? (Use Y / N): ')
input_file = open(data, 'rb')
while not end_of_file:
try:
emp = pickle.load(input_file)
display_data(emp)
except EOFError:
end_of_file = True
input_file.close()
if keep_going == 'N':
print(display_data(emp))
output_file.close()
def display_data(emp):
print('Name','\t','\t','ID Number','\t','Department','\t','\t','Job Title')
print(emp.get_name(), '\t', emp.get_ID_num(),'\t','\t',emp.get_department(),'\t','\t',emp.get_job_title())
main()
If anyone knows why this is happening and has any suggestions on how to fix it I would really appreciate it as I am new to python and don't fully understand all of the concepts
You need to store the employees in memory and then write to the file in the end. Also, I don't understand why you need this bit of code, it doesn't seem to be doing anything :
input_file = open(data, 'rb')
while not end_of_file:
try:
emp = pickle.load(input_file)
display_data(emp)
except EOFError:
end_of_file = True
input_file.close()
So we remove this, and make some other modifications. Your modified code :
import pickle
import employee
data = 'data.dat'
def display_data(emp):
print('Name','\t','\t','ID Number','\t','Department','\t','\t','Job Title')
print(emp.get_name(), '\t', emp.get_ID_num(),'\t','\t',emp.get_department(),'\t','\t',emp.get_job_title())
def main():
output_file = open(data, 'wb')
emp_list = []
keep_going = 'Y'
while keep_going == 'Y':
name = str(input('Name of employee: '))
ID_num = int(input('Employee ID number: '))
dep = str(input('Department: '))
job = str(input('Job Title: '))
emp = employee.Employee(name, ID_num)
emp.set_department(dep)
emp.set_job_title(job)
emp_list.append(emp)
keep_going = input('Enter another employee file? (Use Y / N): ')
pickle.dump(emp_list, output_file)
output_file.close()
if keep_going == 'N':
input_file = open(data, 'rb')
employees = pickle.load(open(data, "rb"))
for emp in employees:
print(display_data(emp))
main()
Also, the printing can be made cleaner :
from tabulate import tabulate
def display_data(employees):
infos = []
for emp in employees:
infos.append([emp.get_name(), emp.get_ID_num(), emp.get_department(), emp.get_job_title()])
print(tabulate(infos, headers=["Name", "ID num", "Department", "Job Title"], tablefmt="fancy_grid"))
So, to print, replace
for emp in employees:
print(display_data(emp))
with
display_data(employees)
HTH.
Every time pickle.dump() is called, it overwrites the existing file. So firstly you need to store all the employees in a list and then write it to file using dump().
While retrieving also you need to load data from file using pickle.load() into a list.

I am not getting the expected output for my code

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!

UnboundLocalError - Python Error

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.

How do I make my program give me the value of a certain cell in a CSV?

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]

Categories