Write list to CSV file in Python - python

I have created a quiz for students to take part to test their arithmetic skills. I wish to write the list of students and their scores to a csv file. I am struggling to write to file and although I have managed to, the excel file contains no data. It says "Score for [] : []". Very sorry for the inefficient code, but any help will do on how to solve this.
I created 2 empty lists and a variable.
Student = []
Score = []
QuizTaken = 0
This defines when to append the scores to the list.
def QuizTaken(): #the amount of quizzes taken by student
while QuizTaken <= 3:
userName, ClassName = Introduction() #used to input name and class using raw_input
score = Quiz()
Student.append(userName) #student's inputted name is appended to list
Score.append(score) #student's final score is appended to list
QuizTaken()
This code writes the list to file in the form of a string, however I think my problem lies here somewhere, however I can't locate it.
def WriteToFile():
userName, ClassName = Introduction()
score = Quiz()
print ""
if ClassName == "10x1":
print "Creating a text file for your teacher..."
fileWrite = open("10x1 Class Score.csv", "a+")
fileWrite.write("Score for ")
fileWrite.write(str(Student))
fileWrite.write(" : ")
fileWrite.write(str(Score))
fileWrite.write("\n")
fileWrite.close()
The code should write the names and scores appended into the empty list into a csv file, with the data available for me to view, but it shouldn't be overwritten.

There are a few problems with your code: you have QuizTaken as both function and variable name. You also don't increment your counter (QuizTaken) in the body of your loop. You can use pandas (http://pandas.pydata.org/) to store your data in dataframe and then use pandas.DataFrame.to_csv() to write it to a file.

Related

Displaying the first name alphabetically and last name alphabetically after being given a list of names from the user in python

Design a program that asks the user for a series of names (in no particular order). After the final person's name has been entered, the program should display the name that is first alphabetically and the name that is last alphabetically. For example, if the user enters the names Kristin, Joel, Adam, Beth, Zeb, and Chris, the program would display Adam and Zeb.
Note: A condition-controlled loop must be used. The user will enter a sentinel value of DONE to indicate that there are no more names to be input.
We really haven't gone over this in class and I've tried looking it up online to see if I can understand anything but most of the people are asking about it in java or C++.
My Code:
# Prompt user to enter names
names = input("Enter the names: ")
# breakdown the names into a list
words = names.split()
# sort the names
words.sort()
# display the sorted names
print("The sorted names are:")
for word in words:
print(word)
Best way to learn is to try it yourself. Most import things is (imho) to read the assignment carefully and then break it down in smaller, but easier to solve problems:
# init names list
names = []
# get input
while True:
name = input("Enter a name:")
# end while loop, when name = 'DONE'
if name == "DONE":
break;
else:
# else add it to 'names' list
names.append(name)
# Do some sorting of the list
names.sort()
# Print the first item of a list
print(names[0])
# Print the last item of a list
print(names[-1])
Here is a code that will solve your problem:
print("Keep entering names by typing space bar after every name. Once done, press Enter")
final_list = list(map(str, input().rstrip().split()))
final_list.sort()
print("The first name is {}. The last name is {}".format(final_list[0],final_list[-1]))

Writing to textfile in a specific way using a list in python

I am trying to write to a textfile in python where the the output in the file.
I have a Class called phonebook which has a list containing objects of the phonebook class.
My constructor looks like this:
def __init__(self,name,number):
self.name = name
self.number = number
When i add a new object to the list looks like this:
def add(self):
name = input()
number = input()
p = Phonebook(name,number)
list.append(p)
When I'm writing my list to the textfile the function looks like this:
def save():
f = open("textfile.txt","w")
for x in list:
f.write(x.number+";"+x.name+";")
f.close()
And its writes out:
12345;david;12345;dave;12345;davey;09876;cathryn;09876;cathy; and so on..
should look like this:
12345;david,dave,davey
09876;cathryn,cathy,
78887;peter,pete,petr,petemon
My question is then.. How do I implement this save function so it will only write out one unique number and all its names connected to that number?
Feels like its impossible to do with only a list containing names and numbers.. Maybe im wrong..
Dictionaries in Python give you fast access to items based on their key. So a good solution to your problem would be to index the Phonebook objects using the Phonebook.number as the key to store a list of Phonebooks as the values. Then at the end just handle the printing based on however you want each line to appear.
This example should work in your case:
phone_dict = dict() # Used to store Phonebook objects intead of list
def add(self):
name = input()
number = input()
p = Phonebook(name,number)
if p.number in phone_dict:
phone_dict[p.number].append(p) # Append p to list of Phonebooks for same number
else:
phone_dict[p.number] = [p] # Create list for new phone number key
def save():
f = open("textfile.txt","w")
# Loop through all keys in dict
for number in phone_dict:
f.write(x.number + ";") # Write out number
phone_books = phone_dict[number]
# Loop through all phone_books associated with number
for i, pb in enumerate(phone_books):
f.write(pb.name)
# Only append comma if not last value
if i < len(phone_books) - 1:
f.write(",")
f.write("\n") # Go to next line for next number
f.close()
so how would the load function look?
I have tried doing one, and it loads everything into the dictionary but the program doesnt function with my other functions like it did before i saved it and reload it to the program again..
def load(self,filename):
self.dictList = {}
f = open(filename,"r")
for readLine in f:
readLine = readLine.split(";")
number = readLine[0]
nameLength = len(readLine[1:])
name = readLine[1:nameLength]
p = phonebook(name)
self.dictList[number] = [p]
print(self.dictList)
f.close()

Dynamically generated Class instances

I want to store values that I plan to later use for sorting pdfs on my computer using PyPDF2.
I thought that if I created a class and stored identifying info for each type of file (such as a descriptor, a string that is unique to the file and can be found by PyPDF2 later such as an account number, and the path where the file should be moved to) that would work. Something like this:
class File_Sort(object):
def __init__(self, identifier, file_text, file_path):
self.identifier = identifier
self.file_text = file_text
self.file_path = file_path
so an example input from me would be:
filetype0001 = File_Sort("Phone Bill", "123456", "/Users/Me/PhoneBills/")
I would like to be able to have users generate new file types via a series of raw_input questions, but I can't figure how to generate the variable to create a new instance, so that I can get:
filetype000[automatically incrementing number] = File_Sort(UserResponse1, UserResponse3, UserResponse3).
Creating the "filetype000[automatically incrementing number]" text itself seems easy enough with:
file_number += 1
file_name = "filetype" + str(file_number).zfill(4)
but how do you turn the generated file_name string into a variable and populate it?
It sounds like you're wanting to dynamically create variables. That's almost always a foolish thing to do. Instead, you should be using a data structure like a list or dictionary, indexed by the parts of the variable name you wanted to generate dynamically.
So instead of creating a list named filetype000, start with a list named filetypes, and append an inner list, so you can do filetypes[0] to get at it. Or if string names make more sense for your specific application, let filetypes be a dictionary, and access the inner lists with something like filetypes['pdf'].
I'm being a little vague here because I don't really understand all of your pseudocode. It's not at all obvious what the purpose of the [automatically incrementing number] parts of your example are, so I'm more or less ignoring those bits. You probably just want to start with an empty list and append values to it, rather than somehow initializing it to a specific size and magically indexing it.
so fyi this is what I ended up using:
file_descriptor = []
file_string = []
file_location = []
filetype_new = len(file_descriptor)
input_descriptor = raw_input("What is the description of the new file type? ")
file_descriptor.append(input_descriptor)
input_filestring = raw_input("What is unique string to search for in this file type? ")
file_string.append(input_filestring)
input_filelocation = raw_input("where should we put this file type? ")
file_location.append(input_filelocation)
print("file%s: %s, \t%s, \t%s" % (str(filetype_new+1).zfill(4), file_descriptor[filetype_new], file_string[filetype_new], file_location[filetype_new]))
review = raw_input("\nWould you like to review the current files? y/n ").lower()
while review not in "yn":
review = raw_input("Sorry, I don't understand. Would you like to review your file types? y/n ").lower()
print("There are currently sort instructions for %s filetypes: " % (len(file_descriptor)))
file_increment = 0
while file_increment in range(0, len(file_descriptor)):
print("file%s: %s, \t%s, \t%s" % (
str(file_increment + 1).zfill(4), file_descriptor[file_increment], file_string[file_increment],
file_location[file_increment]))
file_increment += 1
thanks for your advice.

When i add to the list in my dictionary, it doesn't actually add to the list? python

So, I made a dictionary, called groupA, that i want to hold names and multiple scores. The scores come from a variable called count, which is dependent on a quiz from another part of my code. My code adds multiple values to one key, but i want them all in one list, which isn't happening for whatever reason. This is my code:
name = input("What is your name? ")
while name.isdigit():
print ("That's not a name.")
name = input("What is your name? ")
group = input("Which group are you in; A, B or C: ")
if group == "A":
if name in groupA:
groupA = pickle.load(open("groupA.p", "rb"))
score = [count]
groupA[name].append(score)
numberofvalues = len(score)
if numberofvalues > 3:
print("Deleting oldest score.")
score.pop(1)
print(score)
pickle.dump(groupA, open("groupA.p", "wb"))
else:
score = [count]
groupA[name] = [score]
pickle.dump(groupA, open("groupA.p", "wb"))
i want this part of the code to either add to the values in the list, and if there are more than three values in the list, delete the first, then if there isn't an entry for the dictionary with that name; create an entry, but it's not doing this. can someone please help? thank you!
What you are currently doing is equivalent to:
groupA[name].append([count]) # this appends a list to the list
Do it this way
groupA[name].append(count) # count must be single value
And in the else part
groupA[name] = [count] # creating new single-element list
Also, len(scores) will always be 1. Replace it with this:
numberofvalues = len(groupA[name])

Sorting and displaying a list in a basic record-jar format that is stored in a text file based on additional data stored within the same list

I'm attempting to write a script that makes a sorted list out of items stored in this format:
&&
TASK:
PROJECT:
CONTEXT:
DUE_DATE:
COMPLETION_DATE:
PRIORITY:
%%
I have a pretty good idea of the logic behind what I'm trying to do, but I'm very new to Python so I'm struggling with the implementation. Here's what I have so far:
import sys
import getopt
#add function
if sys.argv[1] == 'add':
try:
f = open("todo.txt", "added")
try:
f.write("TASK:" + sys.argv[2] + "\n")
project = raw_input("Please enter the project: ")
f.write("PROJECT:" + project + "\n")
context = raw_input("Please enter the context: ")
f.write("CONTEXT:" + context + "\n")
duedate = raw_input("Please enter the due date: ")
f.write("DUE_DATE:" + duedate + "\n")
completiondate = raw_input("Please enter the completion date: ")
f.write("COMPLETEION_DATE:" + completiondate + "\n")
priority = raw_input("Please enter the priority level")
f.write("PRIORITY:" + priority + "\n")
finally:
f.close()
except IOError:
pass
#list function
if sys.argv[1] == 'list':
listnum = 1
try:
with open("todo.txt", "r") as f:
searchlines = f.readlines()
for i, line in enumerate(searchlines):
if "TASK:" in line:
for l in searchlines[i:i+3]:
print listnum, l[5:],
listnum += listnum
except IOError:
pass
#complete function
if sys.argv[1] == 'complete':
listName.pop(args[0]-1);#this pops it out and deletes it. need to sort into order and from that list. delete that item
#by popping and it will be the -1 of the one from the list.
Now, my add function works fine. I understand that argeparse(sp?) would let me add all of the meta data with a single line, but I figured I'd keep it as simple as possible. My list function at the moment simply lists all of the items based on their order within the file, but it doesn't have any sort of filter functionality. It also doesn't display the meta data below TASK: lines.
What I want to do with my list function is to have the default action sort all items in the text file based on priority. I'd like to accept additional search "tags" in the same line, and have the list function generate a list of TASKS: who have any number of meta data that match any of the search tags, and I want the filtered list to also be sorted based on priority.
What I'm thinking is to use letter tags for priority (A, B, etc...) and traversing to each entry in the file. I would then compare the task name and all of the meta data to each filter tag. If a match occurs, I would check the priority, and display the entry if the priority is "A". If the priority is not "A", but a match occurs, I would make some sort of bool flag turn to 1 to let me know the program needs to traverse the list again while looking for the next level of priority.
The things I don't know how to do:
Traverse the list and look for match, then look at the priority.
Display the filtered or unfiltered list with the TASK: lines enumerated and all other lines indented and NOT enumerated.
How to have the program stop traversing the list once all valid list candidates for the particular filter have been displayed
Not let previously displayed entries trigger the bool that causes the program to keep looking for more entries.
If possible, I'd like complete to look for a given task name, and if found, delete the task name and the next 6 lines in the text file.
Thank you for any help you can provide!

Categories

Resources