0

I'm attempting to read values from a file and then sort them, and then rewriting the values back to the file. The file contains the following syntax for the value: NAME, SCORE/10. Each new value begins on a new line e.g:

TEST, 5/10
TEST2, 2/10

Currently, I have the sorting of A - Z working. However, I am having difficulty sorting via the values. Could anybody help me with sorting from Highest Num - Lowest Num? (10 - 0)

The code I have currently to read the Values is this:

def splitList(alist):
    a = []
    i = 0
    for i in range(alist.count("\n")):
        a = a.append(alist[:])
        i =+ 1
    return a

And this is what I have to sort from Highest to Lowest:

def sortFile(filePath, mode = "ABC"):
    if mode == "321":
        try:
            f = open(filePath, "r")
            try:
                lines = f.readlines()
                print(lines)
                lines = lines.sort(key=lambda x: x[2], reverse=True)
                print(lines)
                f.close()
                f = open(filePath, "w")
                f.writelines(lines)
            finally:
                f.close()
        except IOError:
            pass
        return True
artman41
  • 402
  • 2
  • 5
  • 15
  • But what is you 'difficulty'? Does the program sort anything, but results are incorrect? Does it drop some data or duplicates it? Does it run at all? – CiaPan Oct 21 '14 at 10:37
  • @CiaPan the problem is this (High - Low) `f.writelines(lines) TypeError: 'NoneType' object is not iterable` – artman41 Oct 21 '14 at 10:39
  • So the problem is the `lines` object returned from `sort()` is not proper. But didn't `print()` complain about it earlier? Could you add example - what data you try to sort, what was the printout of the data before and after `sort()`? – CiaPan Oct 21 '14 at 10:44
  • @CiaPan It returns all the lines of the text file as a list seperated by the commas but, after the sort, it then returns `none` – artman41 Oct 21 '14 at 10:49
  • ...and now you can ask the right question: "what's wrong with my call to `sort()` and how can I correct it". – CiaPan Oct 21 '14 at 11:01

2 Answers2

0

Define sorting criteria however you like:

def key_az_reverse_numeric(line):
    alpha, sep, score10 = line.partition(',')
    score10 = score10.strip()
    if sep and score10.endswith('/10'): 
       try:
           return alpha.strip(), -int(score10[:-len('/10')])
       except ValueError:
           pass
    return '', float('-inf') # default

And use it to sort the file:

def sort_file(filename):
    with open(filename) as file:
        lines = file.readlines() # assume the last line has newline
    lines.sort(key=key_az_reverse_numeric)
    with open(filename, 'w') as file:
        file.writelines(lines)

To sort a large file that do not fit in memory, you could sort the file in small batches and merge the sorted results.

To find out what line.partition(',') means you could search google using keywords: python partition. The first result points to the Python docs for str.partition method. line is a string so it looks like what we need. Click the link.

Community
  • 1
  • 1
jfs
  • 399,953
  • 195
  • 994
  • 1,670
  • Could you please explain what the line `alpha, sep, score10 = line.partition(',')` means please? I understand that you're splitting the string, but why do you need 3 variables to carry this value? – artman41 Oct 21 '14 at 10:46
  • @artman41: I've added instructions how to find out what is `line.partition()`. – jfs Oct 21 '14 at 10:50
  • ah, makes a lot more sense now - need 3 variables, one for each part of the tuple – artman41 Oct 21 '14 at 10:52
0

Pseudocode, do not attempt to copy paste. Write a function that strips the string values for sorting functions inside the sorting method, then return which one is superior.

def sort(line1, line2) {
  //strip the lines for their values, then compare and return value
  returns 1 if line1 > line2, -1 if line1 < line2, 0 if line1 == line2
}

for(int i = 0; i < arraylength, i++) {
 line1 = array[i];
 line2 = array[i+1];
 placeholderline = null;
 int ordering = sort(line1, line2);
 if(ordering = 1) {
  placeholderline = line2;
  array[i+1] = line1;
  array[i] = line2;
 }     

//ordering is already ok if they are equal or 1 is smaller than 2 depending on ascending/descending

Does this help? I am not a python expert so it's hard for me to provide python specific answers but the principle is the same.

G_V
  • 2,396
  • 29
  • 44