Lostsoulaside
Lostsoulaside

Reputation: 63

Print the students with the top marks

Q: Print all the students with the top marks. If multiple students have the same mark, print both students.

Sample Output:

Best student(s): Micheal Murphy, Dan Smith
Best mark: 89 

My code:

import sys

def procfile(filename):
    try:
        with open(filename, 'r') as f:
            bestMark = -1
            for line in f:
                mark, name = line.strip().split(maxsplit=1)
                mark = int(mark)
                if mark > bestMark:
                   bestMark, bestStudent = mark, name
            print(f'Best student(s): {bestStudent}')
            print(f'Best mark: {bestMark}')

    except FileNotFoundError:
        print(f'The file {filename} cannot be opened')

procfile(sys.argv[1])

My output that I am getting:

Best student(s): Michael Murphy
Best mark: 89

My problem:

How do I make it so that it prints multiple students that achieved the top mark? I want my output to be

Best student(s): Micheal Murphy, Dan Smith
Best mark: 89 

Upvotes: 1

Views: 301

Answers (1)

Patrick Artner
Patrick Artner

Reputation: 51673

Use a list to store the student names:

def procfile(filename): 
    try:
        with open(filename, 'r') as f:
            bestMark = -1
            for line in f:
                mark, name = line.strip().split(maxsplit=1)
                mark = int(mark)
                # better mark: create new list
                if mark > bestMark:
                   bestMark, bestStudents = mark, [name]

                # same mark again: add to the list
                elif mark == bestMark:
                   bestStudents.append(name)
                   
            print(f'Best student(s): {", ".join(bestStudents)}')
            print(f'Best mark: {bestMark}')

    except FileNotFoundError:
        print(f'The file {filename} cannot be opened')

with open("t.txt", "w") as f:
  f.write("20 John\n30 Bill\n20 Lisa\n30 Nobody")
procfile("t.txt")

Output:

Best student(s): Bill, Nobody
Best mark: 30

You can also do all students:

def procfile(filename):
    students = {}
    try:
        with open(filename, 'r') as f:
            bestMark = -1
            for line in f:
                mark, name = line.strip().split(maxsplit=1)
                mark = int(mark)
                students.setdefault(mark,[]).append(name)
                  
            print(f'All student(s):')
            for key in sorted(students, reverse=True):
                print(key, "by", ', '.join(students[key]))
          
    except FileNotFoundError:
        print(f'The file {filename} cannot be opened')

with open("t.txt", "w") as f:
  f.write("20 John\n30 Bill\n20 Lisa\n30 Nobody")
procfile("t.txt")

Output:

All student(s):
30 by Bill, Nobody
20 by John, Lisa

Computationally its not much worse, you just need some more memory to store the dictionary. You can speed the progam up if you do thousands of students by using a collections.defaultdict instead of a normal dict using dict.setdefault.

Upvotes: 1

Related Questions