Search code examples
pythonpython-3.xcode-inspection

Function that sorts multiple arguments


I need to write a function sort_gradebook(gradebook), which has next arguments: [first_name, last_name, grade_1, grade_2, ..., grade_n, final_grade]. Function must sort by:

  • Final grade
  • If final grades are equal - by first grade
  • If first grades are equal - by second grade, etc
  • If all grades are equal - by second name
  • If second names are equal - by name.

Everything I could do:

from operator import itemgetter

def sort_gradebook(*gradebook):
    length = len([str(i) for i in gradebook[0]])
    a = [i for i in range(length)]
    for i in a:
        s = sorted(gradebook, key = itemgetter(i))

    return s

For test:

from itertools import permutations

def test_sort(inp, outp):
    for i in permutations(inp):
        assert sort_gradebook(list(i)) == outp

test_sort([['Alice', 'Smith', 2, 3, 4],
    ['John', 'Smith', 2, 3, 5]], [['John', 'Smith', 2, 3, 5],
    ['Alice', 'Smith', 2, 3, 4]
])

Solution

  • Sorting

    • you want to sort on multiple parameters, that are the different indices. You can use itemgetter(0,1,2), and in your case itemgetter(4,3,2,1,0) which need to be built dynamically regarding the size

    • add reverse=True to get John, who has higher final grade, before Alice

    def sort_gradebooks(*gradebooks):
        nb_attributes = len(gradebooks[0])
        s = itemgetter(*[i for i in range(nb_attributes - 1, -1, -1)]) # itemgetter(4,3,2,1,0)
        return sorted(gradebooks, key=s, reverse=True)
    

    Call it

    You need to call the sort with *i and i to pass the flatten the parameters and not pass one list, but rather multiple items

    def test_sort(inp, outp):
        for i in permutations(inp):
            print(sort_gradebooks(*i) == outp)
    

    print(sort_gradebooks(*[['Alice', 'Smith', 2, 3, 4], ['John', 'Smith', 2, 3, 5]])) # John / Alice because final grade
    print(sort_gradebooks(*[['Alice', 'Smith', 2, 3, 5], ['John', 'Smith', 2, 3, 5]])) # John / Alice because name
    print(sort_gradebooks(*[['Alice', 'Smith', 2, 5, 5], ['John', 'Smith', 2, 3, 5]])) # Alice / John because 2ng grade