3

I've looked over the internet for information on using the .csv module; there are a few other people who have highlighted this issue but I haven't yet found a concrete solution.

Currently, the sorting / writing / outputting code works to the extent that it outputs the correct data to the file, but leaves the data with blank rows inbetween the correct rows of data.

Just to give a bit of background to the following code; i must output only the last 3 scores of each person to the file, and I will be using the 'Name,Class' pair as a primary key for the database i.e. it is what I will identify users of the database with. The Variables 'totalscore' , 'difficulty' , 'username' and 'Class' have already been defined in earlier code (There's a lot, and it isn't entirely relevant, so I haven't included it)

savescore = 0
savescore = totalscore * (difficulty + 2) #Multiplies their score out of 10 by difficulty + 2
print("You got " + str(totalscore) + " Out of ten and scored " + str(savescore) + " points" ) 

with open("Scoredatabase.csv","r") as f:
    f=csv.reader(f)
    NameClassScoreList = []
    for line in f:
        NameClassScoreList.append(line[0:5]) # Creates a list of all of the entries in the .csv file (List of lists) in the order Name,Class,Score,Score,Score
NameClassList = []

for n in NameClassScoreList: 
    NameClassList.append([n[0], n[1]]) #Appends a  list of pairs of (Name,Class) for all the records in the .csv file
print(NameClassList)
print(NameClassScoreList)
userNameClass=[]
userNameClass=[username,Class] #Creates a variable storing the pair (Name,Class) for the user currently using the program, can later be used to compare with ones in the database

if userNameClass not in NameClassList: #Tests if a user with that username and class already exists (It should append it to the end before sorting)
    NameClassScoreList.append([username,Class,str(savescore),'0','0'])

for entry in NameClassScoreList: #Iterates through all of the entries within the NameClassScoreList (Which includes a list of entries in the .csv file)
    if entry[0:2] == [username,Class]: #Checks if the username,Class matches
        entry[4]=entry[3] #If it does, it moves all of the scores forwards, deleting the the 3rd last and then replaces it with the savescore
        entry[3]=entry[2]
        entry[2]=str(savescore)

NameClassScoreList = sorted(NameClassScoreList, key=itemgetter(1,0)) #Sorts the NameClassScoreList by Class, then Name alphabetically. 

with open("Scoredatabase.csv","w") as f:
    writer=csv.writer(f) #should be for n in NameClassScoreList
    for entryrow in NameClassScoreList:
        writer.writerow((entryrow[0],entryrow[1],entryrow[2],entryrow[3],entryrow[4]))

I would like to either make it so that the problem is rectified as the data is outputted to the file, or a way of fixing it after it is outputted incorrectly (I.e just move the rows up depending on where they are in the file)

If you need any clarification about the problem just comment and I'll reply as soon as possible, thanks.

Cubbs
  • 133
  • 1
  • 6
  • See the answer on this thread: https://stackoverflow.com/questions/3348460/csv-file-written-with-python-has-blank-lines-between-each-row/#53577233 – Febin Mathew Dec 02 '18 at 03:59

1 Answers1

6

I had the same problem, you have to overwrite the line terminator, e.g.:

csv.writer(f, lineterminator='\n')

The behavior of line terminators might be system specific though. *nix and DOS/Windows behave differently.

I have a windows machine, the normal line terminator on windows is '\r\n'. If I use the above code I get a file with '\r\n' as line terminators: Single carriage return

If I use '\r\n' as line terminator I get '\r\r\n': Double carriage return

I guess the csv writer replaces the 'nix line terminator ('\n') with the windows line terminator ('\r\n') automatically, therefore you get one carriage return too many on Windows machines.

EDIT: I found out that there is a flag that should be used on Windows machines, I missed that in the documentation the first time around:

If csvfile is a file object, it must be opened with the ‘b’ flag on platforms where that makes a difference.

It's not worded in a way that seems at all important, so I hope you can forgive me on that one.

CodeMonkey
  • 4,067
  • 1
  • 31
  • 43