2
\$\begingroup\$

I am learning python by solving python module from HackerRank. This problem is Find the Percentage.

You have a record of N students. Each record contains the student's name, and their percent marks in Maths, Physics and Chemistry. The marks can be floating values. The user enters some N integer followed by the names and marks for N students. You are required to save the record in a dictionary data type. The user then enters a student's name. Output the average percentage marks obtained by that student, correct to two decimal places.

Sample Input 0

3
Krishna 67 68 69 
Arjun 70 98 63 
Malika 52 56 60 
Malika

Sample Output 0

56.00

I need to improve this code by using better functions available in python.

def percentage(name):
    """
    Find percentage of marks of the student
    """

    marks = student_marks[name]
    total_marks = 0
    for mark in marks:
        total_marks += mark

    return format(total_marks/len(marks), '.2f')


if __name__ == '__main__':
    n = int(input())
    student_marks = {}
    for _ in range(n):
        name, *line = input().split()
        scores = list(map(float, line))
        student_marks[name] = scores
    query_name = input()
    print(percentage(query_name))
\$\endgroup\$
3
  • 1
    \$\begingroup\$ What do you need to improve about the code and why? Did you write this code? Please clarify. \$\endgroup\$
    – Mast
    Mar 31 '20 at 10:02
  • \$\begingroup\$ Yes, I wrote this and I am beginner in Python. I want to learn about other modules and functions which will help me to solve this problem. \$\endgroup\$
    – coder
    Mar 31 '20 at 10:25
  • \$\begingroup\$ (To the flagger: What gave rise to flag not implemented or not working as intended?) \$\endgroup\$
    – greybeard
    Apr 1 '20 at 5:50
5
\$\begingroup\$

For a beginner this is some good code. I would make some additional adjustments.

  • One-line docstrings should be on one line, not over 3. And should end with a period.
  • You should only pass the marks to percentage and not rely on a global student_marks.
  • You can use sum to compute total_marks.
  • I'm not a fan of having format in the percentage function.
  • You should move all the main code into a main function, if __name__ == '__main__': should really only call this.
  • It's more idiomatic to use comprehensions than map, even more so when you have list(map(...)).
  • It's pretty rude to call a student a query. You can just use name.
def percentage(marks):
    """Find percentage of marks of the student."""
    return sum(marks) / len(marks)


def main():
    """Main code."""
    n = int(input())
    student_marks = {}
    for _ in range(n):
        name, *scores = input().split()
        student_marks[name] = [float(score) for score in scores]
    name = input()
    result = percentage(student_marks[name])
    print(format(result, '.2f'))


if __name__ == '__main__':
    main()
  • You can use statistics.mean rather than a custom made percentage.
  • You can change the for loop into two comprehensions, a generator and dictionary comprehension.

    Note: I don't think comprehensions are better here, but are an 'as good' alternate.

import statistics


def main():
    """Main code."""
    _marks = (input().split() for _ in range(int(input())))
    student_marks = {
        name: [float(score) for score in scores]
        for name, *scores in _marks
    }
    result = statistics.mean(student_marks[input()])
    print(format(result, '.2f'))


if __name__ == '__main__':
    main()
\$\endgroup\$
1
  • \$\begingroup\$ You can use statistics.mean during input and have that average the value kept in the dict - as per problem statements, the individual scores are as important as the subjects they have been credited for. \$\endgroup\$
    – greybeard
    Apr 1 '20 at 7:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.