I have a text file set out in this layout:
Greg,Computer Science,Hard,5
Alex,Computer Science,Medium,2
Fiona,Maths,Easy,0
Cassie,Maths,Medium,5
Alex,Maths,Medium,1
In my program I want the user to be able to choose a certain name and see their results. My code for this looks like this:
name = input("Enter name: ")
for each in file:
each = each.split(",")
realName = each[0]
subject = each[1]
difficulty = each[2]
score = each[3]
if name == realName:
print(subject, difficulty, score)
break
else:
print()
print("Invalid name.")
name = input("Re-enter your name: ")
A few things are wrong with it though and I can't figure out what to do:
If the user entered "Alex", only one of his results will be displayed.
If a wrong name is inputted once, every other name inputted will return as "Invalid".
If the correct name is inputted and the results are displayed, the program will continue to ask for a name.
Does anybody have any solutions to these problems?
If you're going to query your file repeatedly, I'd recommend pre-loading your data once into a dictionary, and printing data as and when needed. Something like this:
data = {}
with open('file.txt', 'r') as file:
for line in file:
realName, subject, difficulty, score = each.split(',')
data.setdefault(realName, []).append((subject, difficulty, score))
while True:
name = input('>>> ')
data.get(name, 'Invalid Name')
This solves problems one and two. If you just want to break after the first valid name is input, you can query the return value of dict.get:
while True:
name = input('>>> ')
result = data.get(name)
if result:
print(result)
break
print('Invalid name')
This solves problem three.
You're better off using the csv module since your file syntax is simple CSV.
Then you can loop through the rows (each row will be an array of values).
import csv
def parse_csv_file(csv_file, operation, value, index):
with open(csv_file, newline='') as file:
reader = csv.reader(file, delimiter=',',
quotechar='|')
return operation(reader,
value, index)
def find_first_row(csv_reader, value, index):
for row in csv_reader:
if row[index] == value:
return row
return None
def main():
query = input('Enter a name: ')
result = parse_csv_file('file.csv',
find_first_row,
query, 0)
if result:
print(result)
else:
print('Nothing found!')
main()
Related
This code is trying to open a txt document read the names print them then ask to input a name and search for the name but the search doesn't work with text only with set names if anyone can help. I think its using data a a search request so don't know how to make the names it
def liner_search():
with open ("example.txt", "r") as myfile:
data = myfile.read().splitlines()
print (data)
numberList = [data]
searchRequest = input("enter name:")
print(searchRequest)
found = False
i=0
while found == False and i != len(numberList):
if numberList[i] == searchRequest:
print ("found")
found = True
else:
print("next")
i = i+1
liner_search()
this is the result
I propose a more pythonic approach:
def name_finder():
with open('example.txt', 'r') as my_file:
data = my_file.read().splitlines()
name = input("enter name:")
if name in data:
print("Name is in the list")
else:
print("Name is not in the list")
name_finder()
I am storing the records in form of a list.
Write a menu driven program to append, display and delete student
details [id, name, percentage] in a binary file. Deletion should be
done on the basis of student id.
So I wrote this:
#Code to append display and delete student details
import pickle
def append():
f = open("student.bin","ab")
x = int(input("Enter number of students to be appended: "))
for i in range(x):
y = eval(input("Enter details in the form [id, name, percentage]: "))
pickle.dump(y,f)
f.close()
def display():
f = open("student.bin","rb")
while True:
try:
x = pickle.load(f)
print(x)
except EOFError:
break
f.close()
def delete():
f = open("student.bin","ab+")
x = input("Enter id to be deleted: ")
y = pickle.load(f)
for i in y:
if str(i[0]) == str(x):
In the end, I was matching the user input to the matching IDs but I don't know how I should go about deleting the list entirely from the binary file.
Here is one way: reads all the student records from file, remove the one we want to delete, then write the whole list back into file.
def delete():
student_id = int(input("Enter id to be deleted: "))
records = []
with open("student.bin", "rb") as stream:
while True:
try:
record = pickle.load(stream)
if record[0] != student_id:
records.append(record)
except EOFError:
break
# records now contains all students, except for the one we want to delete
with open("student.bin", "wb") as stream:
for record in records:
pickle.dump(record, stream)
Another way is to open the file for read/write and load each record and write it back. It is harder to understand.
I don't expect any coding answers, more just guidance. For my project I have to date-mine apple stock prices from a csv-file and implement it in my code. I provided a sample output below.
https://imgur.com/rPOPN1I
Right now, I am not getting any error messages but my code is not posting the columns requested from the csv.file. Are my definitions at fault or am I missing something else?
# Project No.: 5
# Author: burntchickennuget
# Description: making definitions, reading from a .csv file, validating input, data-mining,
f_list = list()
file_object = ()
my_tot = dict()
new_list = list()
def get_input_descriptor():
while True:
filename = input("Enter a file name: ")
if filename == 'table.csv':
with open(filename, "r") as infile:
infile.readlines()[1:]
# for line in lines:
# print(line.rstrip())
break
else:
print("Bad file name, try again")
return filename
def get_data_list(file_object, column_number):
dict = {}
for val in file_object:
date = val.split(",")[0]
data = float(val.split(",")[column_number])
dict[date] = data
return dict.items()
def average_data(new_list):
for date, price in new_list:
my_tot[date] = my_tot.get(date, 0) + float(price)
my_times[date] = my_times.get(date, 0) + 1
for key in my_tot:
f_list.append((float(my_tot[key] / my_times[key]), key))
def main():
get_input_descriptor()
column_number = int(input("Which column: "))
date_list = get_data_list(file_object, column_number)
final_list = average_data(date_list)
x = sorted(f_list)
print('Lowest 6:')
for tup in x[:6]:
print
tup[0], tup[1]
print('Highest 6:')
x = sorted(f_list, reverse=True)
for tup in x[:6]:
print
tup[0], tup[1]
while 1:
flag = input("do you want to continue? ")
if flag == '' or not flag[0].lower() in ['y', 'n']:
print("Please answer with a yes or no")
else:
break
if flag[0].lower() == 'y':
column = input("Which column: ")
print(column)
if flag[0].lower() == 'n':
print("Bye!")
if __name__ == "__main__":
main()
What can I try next?
Take a look around your get_input_descriptor method.
What are you returning from the method?
Where is the returned information being stored in the main method (is it being stored at all?)
What are you doing with the lines that you read from the file?
What is the file_object you are passing into get_data_list
My main advice would be to add print everywhere for debugging. See what it stored in your variables at different points in the program and see where a variable doesn't contain what you think it should
I want to create a python lookup function for students. I have a tab delimited file with ID and students name. I want to create a lookup program such that entering either a student's name or ID will return name of the student and student ID if a match has been found.
So far I have imported the data successfully. Snippet of data is shared. Having trouble defining a function. I am sharing my code below:
infile = open("D:/work/student_id.txt", "r")
def lookup():
word =raw_input("code to lookup: ")
print ("\n")
n = elements.index(word)
x = elements[n][0]
y = elements[n][0]
if word == x:
print x, ":", y, "\n"
else:
print("That code does not exist")
lookup()
I searched online(stackoverflow-found post by Erik and Alexander, I tried to model my code like theirs but still no help; O'riley books on Python) for help regarding creation of lookup function but they all involved writing the data out. But I found no guidance on creating a lookup function for an imported tab delimited file. I hope this will help others as well. Any advice?
What version of Python are you using?
Python 3 uses input(), not raw_input().
As your file is tab-separated you can use the csv function.
import csv
students = {}
search = input()
found = None
with open('student_id.txt', newline='') as csvfile:
reader = csv.reader(csvfile, delimiter='\t')
for row in reader:
students[row[0]] = row[1]
print(students)
for i in students.keys():
if search == i:
found = search + " " + students[i]
else:
if search == students[i]:
found = i + " " + students[i]
if found == None:
print("Not found")
else:
print(found)
I am new to python, and trying to create a program which opens a csv file. The user is supposed to enter a barcode , then the program finds that product and the cost of the product. However I got an error which is the title of my thread. Here is my code.
import csv # imports should go at the top of the file
def read_csv_file():
""" 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():
""" get input from user """
while True:
try:
GTIN = int(input("input your gtin-8 number: "))
break
except:
print ("Oops! That was not a valid number. Try again")
def search_user_input():
""" search csv data for string """
search_user_input
gtin = get_user_input()
for row in PRODUCT_DATA:
#print(row) #debug print
if row[0] == str(gtin):
product = row[1]
price = round(float(row[2]),2)
print(product, price)
return(product, price)
repeat = input("not in there? search again? If so (y), else press enter to continue")
if repeat == 'y':
search_user_input() # calls function again in order to create a loop
def quantity():
gtin = 0
product = 0
price = 0.0
product_data = read_csv_file()
product,price = search_user_input()
product, price = search_user_input(str(gtin), product_price)
order = int(input("How much of " + product + " do you want?"))
price = round(price * order, 2)
print(quantity,price)
def order_making():
print("Apples")
PRODUCT_DATA = read_csv_file() # call function to read csv
quantity() # call the main function
I have cleaned the flow up a bit for search_user_input and quantity. In some cases you were calling search_user_input with multiple arguments (it doesn't accept them) and you made it recursive. I have added some comments in the code below. In fact, that function was returning None in your setup, which leads to the TypeError: 'NoneType' object is not iterable error.
The if __name__ == '__main__:' is not necessary in your code, I've included it more as a heads-up for later on when you'll want to start importing your own modules. See this for more info on this topic.
import csv
def read_csv_file():
""" 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():
""" 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): # 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)
repeat = input("not in there? search again? If so (y), else press enter to continue")
if repeat != 'y':
keep_searching = False
return None # This is done implicitly, I'm just making it obvious
def quantity():
product_data = read_csv_file()
matches = search_user_input(product_data)
if matches: # Will not be True if search_user_input returned None
product, price = matches[0], matches[1]
order = int(input("How much of {} do you want?".format(product)))
price = round(price * order, 2)
print("That costs {}".format(price))
if __name__ == '__main__': # You'll need this in future for importing modules
# There was no need to read the csv_data here and make it global
quantity() # call the main function