Searching a .CSV file - python

I've been trying to create a program in python whereby you can access, search and input(append) the data in a CSV file. I am able to append and print the file, however I am having trouble searching the external file.
This is what my code looks like so far:
def a():
# knows to use the file (getting something that's made)
import csv
myfile = open("student01.csv", "a")
student_num = input("Enter the student number: ")
name = input("Enter student's name: ")
tutor_group = input("Enter the tutor group: ")
gender = input("Enter M or F: ")
new_record =student_num+","+name+","+tutor_group+","+gender
myfile.write(str(new_record))
myfile.write("\n")
myfile.close()
def d():
# knows to use the file (getting something that's made)
import csv
myfile = open("student01.csv", "rb")
reader = csv.reader(myfile)
for row in myfile:
print(row)
myfile.close()
def menu():
print("Welcome to Student.csv\nWhat would you like to do?")
print()
print("1. Add to the file")
print("2. Display all the data from the file")
print("3. Search for particular data")
enter = input("Enter 1, 2 or 3: ")
enter = enter.upper()
if enter == "1":
a()
elif enter == "2":
d()
else:
s()
menu()
I'm just not sure what to do now for my def s(): so that I am able to search for a student in the file by their name, number or tutor group.
Does anyone have any ideas?
Lotz

import csv
def create_record(number_of_students):
while number_of_students:
student_num = raw_input("Enter the student number: ")
name = raw_input("Enter student's name: ")
tutor_group = raw_input("Enter the tutor group: ")
gender = raw_input("Enter M or F: ")
if student_num and name and tutor_group and gender:
record_list = [student_num, name, tutor_group, gender]
with open("student_record.csv", "ab") as wf:
writer = csv.writer(wf)
writer.writerow(record_list)
number_of_students -= 1
def display_record(option):
with open("student_record.csv", "r") as rf:
reader = csv.reader(rf)
if option == 2:
for row in reader:
print " ".join(row)
elif option == 3:
search_feild = raw_input("Search by student name, number, tutor_group, gender :")
for row in reader:
if search_feild in row:
print " ".join(row)
def main():
print("1. Add to the file")
print("2. Display all the data from the file")
print("3. Search for particular data")
print("0. To Exit")
choice = True
while choice:
your_choice = input("Enter your choice:")
if your_choice == 1:
number_of_students = input("Enter number of records you want to enter:")
create_record(number_of_students)
if your_choice == 2:
display_record(2)
if your_choice == 3:
display_record(3)
if your_choice == 0:
choice = False
if __name__ == "__main__":
main()
Output:
1. Add to the file
2. Display all the data from the file
3. Search for particular data
0. To Exit
Enter your choice:1
Enter number of records you want to enter:3
Enter the student number: 1
Enter student's name: Jhon
Enter the tutor group: Python
Enter M or F: M
Enter the student number: 2
Enter student's name: Lina
Enter the tutor group: Django
Enter M or F: F
Enter the student number: 3
Enter student's name: Max
Enter the tutor group: Python
Enter M or F: M
Enter your choice:2
1 Jhon Python M
2 Lina Django F
3 Max Python M
Enter your choice:3
Search by student name, number, tutor_group, gender :Python
1 Jhon Python M
3 Max Python M
Enter your choice:3
Search by student name, number, tutor_group, gender :F
2 Lina Django F
Enter your choice:0
You should even write your data in csv file using csv writer method.
Searching is easy as while reading a csv it gives a list in which we can search any element by using in keyword.

There is a DictReader in the csv module, perfect for what you want to do (assuming some fields are unique, like student_num probably)
just for info I see some problems in your code
don't import module in function if not necessary, and don't repeat yourself(DRY), just put one import statement at the top outside any function, and if you import something, make use of it ;)
use function's parameters instead of harcoding literals constant inside the body for file name
this : student_num+","+name+","+tutor_group+","+gender should be removed, use ', '.join(your_iterable) instead
when you want to open a file and do work on it before close it, use a context manager : `with open('myfile.txt') as flux:', it defines a block where the file is opened, the file will be closed automatically, even if a problem occurs and an exception is raised

Searching through a set of records is not a trivial problem. I hope this won't make your like super complicated but you'll need a couple of things:
Indices for each field you would like to search on (a data structure that copies information for fast lookup)
A clever way of guessing whether the user is entering a name, tutor group or number (or just asking them what they want to search by)
You can make your own stuff here: maybe start by compiling the users' input into a regular expression and search subsets of the CSV file (like the name column) by doing binary comparisons between the entry and your user's query.
You can also make an index: just pick a data type (or make your own of course) and make sure it's super efficient for checking through itself in a reasonable amount of time for the number of records you have (as low a time complexity as possible).
Then again, a lot of people have been working on this problem for a long time and have TONS of code out there to help you. Check out Information Retrieval and get a feel for the type of problem you are looking at.
You can use something like Xapian for search but there are a lot of alternatives.
Here are some SO questions that might help you: the one without a chosen answer, the one that uses the anyfunction, and the one about getting the right look at columns

Related

How to print list with proper indentation in a file?

so i have this project that I should make a program to add identify or delete data from an inventory.txt file
but when I ever try to print the inputs in the file I get messy text, what I'm looking for is a table-like structure printed inputs in the .txt file, I've tried to remove and readjust the place of \n and \t but still, I get stuff like this in the file
Samsung ide445 2154SS rams 120.0 14
Logetech Specture lid224 G502 230.0 8
here's my code for a closer look:
#This function is to get the parts information from the user
def input_parts():
#Taking the parts input from the user
try:
make = input("Enter the make: ")
model = input("Enter the model: ")
part_id = input("Enter part_id: ")
part_name = input("Enter part name: ")
price = float(input("Enter price:QR "))
quantity = int(input("Enter quantity: "))
except ValueError:
print("BOTH PRICE AND QUANTITY CAN NOT BE LETTERS, PLEASE RE-ENTER THE RIGHT DATA")
else:
#transferring both price and quantitiy to strings
price = str(price)
quantity = str(quantity)
list = ['\n'+make,model,part_id,part_name,price,quantity]
return list
#This function is to save the parts information to a file
def add_parts():
#Assignning this sentinal to make the loop repeat if the user didn't want to save
sentinal = True
while sentinal is True:
#Assigning the values of the inputs function to a variable
parts = input_parts()
#Validating user's unput
try:
#Asking the user if he wants to save the information to the file
save = input("Save? (Y/N) or Q to quit ")
except TypeError:
print("YOU CANNOT SAVE WRONG DATA IN THE FILE PLEASE RE-ENTER YOUR DATA")
else:
pass
#A boleen function to export the data to the file if the boleen is true
if save.lower() == 'y':
outfile = open('inventory.txt',"a")
#Validating user's input
try:
#Using a for loop to print the information in the file
for i in parts:
outfile.write(i+'\t')
except TypeError:
print("YOU CAN NOT SAVE WRONG DATA FILES!!!")
break
else:
pass
outfile.close
print("....Record saved.")
sentinal = False
#Using an elif statment to enable the user to re input his data
elif save.lower() == 'n':
sentinal = True
#Using an elif statment to quit if the user wants to
elif save.lower() == 'q':
break
#Using else statment to tell the user no input a valid choice
else:
print("PLEASE ENTER (Y/N) IF YOU WANT TO SAVE!!!!")
print("YOUR DATA HAS NOT BEEN SAVED")
print("PLEASE RE-ENTER YOUR DATA AND TRY AGAIN.")
sentinal = True
add_parts()
You can import tabulate module and use it as below example:
from tabulate import tabulate
print(tabulate([['Saeed', 26], ['You', 24]], headers=['Name', 'Age']))
Result:
Name Age
------ -----
Saeed 26
You 24
You may use this module to reach what you want.

Python input loops based on user selections for event scoring [duplicate]

This question already has answers here:
Simple while loop until break in Python
(3 answers)
Closed 3 years ago.
The idea of the program is as follows;
1) Users are asked to select either 1 or 2
2) If one is selected, the user is prompted to enter the score. If 2 is selected the user should be able to view the scores.
3) After the user has entered or viewed a score they should be able to add another score or view scores. Typing Y should bring them back to the beginning of the program. N Should say they can close the program, or close it.
At the moment, the number selections work for the score entry but I'm not sure how to make it so that the program restarts is the user wishes to add or view more scores.
Here's the program in its current state;
print ("Type 1 to a add a score.")
print ("Type 2 to view scores.")
action = input("Please type a number: ")
if action == "1":
print ("Enter a score?")
eventscore = int(input ("Please type their score: ")
score = eventscore
f = open("scores.txt", "a")
f.write(eventscore)
f.write("\n")
f.close()
print("The score for" , score, "has been saved.")
elif action == "2":
print ("Type 1 to view all scores.")
print ("Type 2 to view scores for a specific team.")
scorecheck = input("Please type a number: ")
if scorecheck == "1":
f = open("scores.txt", "r")
for line in f:
allscores = f.readlines()
print(allscores)
f.close
elif scorecheck == "2":
teamcheck= input ("Please enter the team name: ")
while True:
while True:
answer = input('Want to add a new score or view existing scores? (Y/N): ')
if answer in ('Y', 'N'):
break
print ("Please enter 'Y' or 'N'.")
if answer == 'y':
continue
else:
print ("You can now close the program.")
break
Currently the program is able to start, ask the user to pick if they want to add or view scores and then ask if they want to add/view more or close the program. If the user enters 'Y' the program should completely restart, but it still needs to have the loops for adding/viewing. If they type N the program should close.
Any help would be greatly appreciated as I don't know how to get a loop on the overall program when it already contains multiple loops.
while True:
ans = input("Enter option (y, Y):")
if ans == "":
print("finished - exit program")
break
if ans in ['y', 'Y']:
askQuestion()
def askQuestion():
...top bit of your code
On my mobile so just peudocode provided. There's likley a better way than this. As said in chess if you find a good move look for a better one.
Also its canonical to write opening a file inside a with context managerlike so:
with open('filename.txt', 'a') as f:
f.write..etc

Building a .csv based on user input

I need to add to a .csv file based on user input. Other portions of the code add to the file but I can't figure out how to have it add user input. I'm new to python and coding in general.
I have other portions of the code that can merge or draw the data from a .csv database and write it to the separate file, but can't figure how to get it to take multiple user inputs to write or append to the outgoing file.
def manualentry():
stock = input("Enter Stock #: ") #Generate data for each column to fill in to the output file.
VIN = input("Enter Full VIN: ") #Each line asks the user to add data do the line.
make = input("Enter Make: ")
model = input("Enter Model: ")
year = input("Enter Year: ")
l8v = input("Enter L8V: ")
print(stock, VIN, make, model, year, l8v) #Prints the line of user data
input4 = input("Append to inventory list? Y/N") #Asks user to append the data to the output file.
if input4 == "Y" or input4 == "y":
with open('INV.csv','a', newline='') as outfile: #Pull up a seperate csv to write to, an output for collected data
w = csv.writer(outfile) #Need to write the user input to the .csv file.
w.writerow([stock, VIN, make, model, year, l8v]) #<-This is the portion that seems to fall apart.
print("INVENTORY UPDATED")
starter() #Restarts whole program from begining.
if input4 == "N" or input4 == "n":
print("SKIPPING. RESTARTING....")
starter() #Reset
else:
print("Invalid entry restarting program.")
starter() #Reset
starter() #R E S E T !
Just need the user inputs to be applied to the .csv and saved there. Earlier portions of the code function perfectly except this to add to the .csv file. It's to fill in missing data that would otherwise not be listed in a separate database.
Some improvement in the code.
You can use a looping condition like while or for instead of recursion
You can open your csv file at the start of the code instead of doing it everytime
You can come up with a word say stop to stop the loop, close the file and exit
You can use str.lower() == 'y' to cover for both y and Y, upper and lower case
The code will then look like
import csv
def manualentry():
#Open csv file at start
outfile = open('INV.csv', 'a', newline='')
w = csv.writer(outfile) # Need to write the user input to the .csv file.
#Everything wrapped in a while True loop, you can change to any loop accordingly
while True:
stock = input("Enter Stock #: ") # Generate data for each column to fill in to the output file.
VIN = input("Enter Full VIN: ") # Each line asks the user to add data do the line.
make = input("Enter Make: ")
model = input("Enter Model: ")
year = input("Enter Year: ")
l8v = input("Enter L8V: ")
print(stock, VIN, make, model, year, l8v) # Prints the line of user data
input4 = input("Append to inventory list? Y/N") # Asks user to append the data to the output file.
if input4.lower() == "y":
w.writerow([stock, VIN, make, model, year, l8v]) # <-This is the portion that seems to fall apart.
print("INVENTORY UPDATED")
if input4.lower() == "n":
print("SKIPPING. RESTARTING....")
#If you see stop, stop writing, close the file and exit
if input4.lower() == 'stop':
print('Not writing anymore! Stopping')
outfile.close()
exit()
else:
print("Invalid entry restarting program.")
#Call manualentry
manualentry()
You can simply use user input controlled while loop to recursively get user input and then you can exit depending on the user choice
user_input = 'Y'
while user_input.lower() == 'y':
# Run your code here
user_input = input('Do you want to add one more entry: Enter [Y/N]')
Try this
import csv
def boo():
stock = input("Enter Stock #: ") # Generate data for each column to fill in to the output file.
VIN = input("Enter Full VIN: ") # Each line asks the user to add data do the line.
make = input("Enter Make: ")
model = input("Enter Model: ")
year = input("Enter Year: ")
l8v = input("Enter L8V: ")
print(stock, VIN, make, model, year, l8v) # Prints the line of user data
input4 = input(
"Append to inventory list? Y/N || anything else to exit") # Asks user to append the data to the output file.
if input4 == "Y" or input4 == "y":
with open('INV.csv', 'a',
newline='') as outfile: # Pull up a separate csv to write to, an output for collected data
w = csv.writer(outfile)
w.writerow([stock, VIN, make, model, year,
l8v]) # Need to write the previously pulled up line to new csv
print("INVENTORY UPDATED")
user_input = input('Do you want to add one more entry: Enter [Y/N]')
if user_input.lower() == 'y':
boo()
else:
exit()
boo()

How do I overwrite a specific line in a CSV file with Python

I'm making a program that lets you input data into a CSV file and then let you search for specific customers, and delete specific customers from the system. I've done the viewing part but I can't figure out how to overwrite a specific line in the csv file. This is what I have so far:
choice = str(input("What would you like to do?"))
if choice.lower() == "delete":
Type = str(input("Type in 'Phone' to delete by Phone number and 'Name' to delete by Surnames: "))
if Type.lower() == "phone":
view = str(input("Enter the phone number of the customer you want to delete: "))
check = csv.reader(open('D:\Programming\School Work\Johns Decorating company program\Customers.csv', "rt"), delimiter=",")
for line in check:
if view in line:
print(line)
confirm = str(input("Type 'Yes' to delete all of the quotes above. Type 'No' to restart or to select in a different way"))
if confirm.lower() == "yes":
#!THIS IS WHERE I'M CONFUSED!
elif confirm.lower() == "no":
print("Restarting search")
existing()
You can transform csv to a list and write:
for i in range(len(check)):
if check[i][column_index] == phone_number: # column_index is index
# of a column where the phone numbers are stored
del csv_list[i]
I hope this helps you.

Saving Raw_input to a list when used in a While Loop

I have already posted a question today and it had 2 problems on it. One of which was solved perfectly, then it got a little complicated. So forgive me but I am posting the other question separately as it confused some peeps:
I am new to python so apologies in advance. Any help is much appreciated. I have been stuck on this code for 2weeks now and I have tunnel vision and cannot work it out:
Basically our assignment was to get to grips with Object-Oriented Programming. We unfortunately have to use "get" and "set" which I've learnt a lot of people dislike, however, as per our tutor we have to do it like that. We were told tp create a program whereby the user is presented with a screen with 3 options. 1. adding a student. 2. viewing a student and 3. removing a student.. within my AddStudent function I have to ask the user to enter fname Lname age degree studying id number (these are the easy bits) and also module name and grade for each module, I have managed to create a loop whereby it will ask the user over and over to enter modules and corresponding grades and will break from said loop when the user enters -1 into the modulname field. However, when trying saving it to a list named students[] ... (which is at the very top of my code above all functions, to apparently make it global) it saves all input from the user re: age name etc but when it comes to saving module names and grades it only saves the last input and not the multiple inputs I need it to. I am unsure if it is within my AddStudent function where it isn't saving or within my ViewStudent function: Both are below (remember I HAVE to use the GET and SET malarky) ;)
students[] # Global List
def addStudent():
print
print "Adding student..."
student = Student()
firstName = raw_input("Please enter the student's first name: ")
lastName = raw_input("Please enter the student's last name: ")
degree = raw_input("Please enter the name of the degree the student is studying: ")
studentid = raw_input("Please enter the students ID number: ")
age = raw_input("Please enter the students Age: ")
while True:
moduleName = raw_input("Please enter module name: ")
if moduleName == "-1":
break
grade = raw_input ("Please enter students grade for " + moduleName+": ")
student.setFirstName(firstName) # Set this student's first name
student.setLastName(lastName)
student.setDegree(degree)# Set this student's last name
student.setGrade(grade)
student.setModuleName(moduleName)
student.setStudentID(studentid)
student.setAge(age)
students.append(student)
print "The student",firstName+' '+lastName,"ID number",studentid,"has been added to the system."
........................
def viewStudent():
print "Printing all students in database : "
for person in students:
print "Printing details for: " + person.getFirstName()+" "+ person.getLastName()
print "Age: " + person.getAge()
print "Student ID: " + person.getStudentID()
print "Degree: " + person.getDegree()
print "Module: " + person.getModuleName()
print "Grades: " + person.getGrade()
your problem is that the module is a single variable you keep changing. instead, make it a list.
while True:
moduleName = raw_input("Please enter module name: ")
if moduleName == "-1":
break
grade = raw_input ("Please enter students grade for " + moduleName+": ")
should be something like
modules = []
while True:
moduleName = raw_input("Please enter module name: ")
if moduleName == "-1":
break
grade = raw_input ("Please enter students grade for " + moduleName+": ")
modules.append((moduleName, grade))
add a new variable to student which is "Modules" and is a list.
and then modules will be a list of tuples which are (moduleName, grade) and to display them, change the line in viewstudent from:
print "Module: " + person.getModuleName()
print "Grades: " + person.getGrade()
to:
for module, grade in person.getModules():
print "Module: " + module
print "Grades: " + grade
It seems you need something like this:
modules = {}
while True:
module_name = raw_input("Please enter module name: ")
if module_name:
grade = raw_input ("Please enter students grade for " + module_name +": ")
modules[module_name] = grade
Modules is a dictionary ("hash map" in other languages), each mod name is key and grades are values, or you could also do it with tuples, wherever floats your boat.
Instead of checking for -1 as a stop condition you check if is true, in python anything empty is evaluated to false.

Categories