I wrote this for my beginner class and I don't know how to get the NAME of the SECOND STUDENT with the 2nd highest score. After testing it, I believe the code works for the first student.
I think what I need is to store the highest score in to variable high_score and then the next highest in to second_score and then compare the third score to both the highest and second score. But I am confused on how to get the name of the second highest scoring student.
num_students = int(input("enter number of students: "))
high_score = 0
high_name = ""
second_name = ""
second_score = 0
for i in range(1,num_students + 1):
if num_students < 2:
break
if num_students >= 2:
name = input("enter student name: ")
score = int(input("enter student score: "))
if score > second_score:
if score > high_score:
second_score = high_score
high_score = score
high_name = name
elif score < high_score:
second_score = score
second_name = name
print()
print("Top Two Students")
print()
print(high_name,"'s score is", high_score)
print(second_name,"'s score is", second_score)
-
1You can use a list of two tuples for storing student information. You can sort the list based on scores DESC and then get the first two elements.gst– gst2021年10月17日 15:54:41 +00:00Commented Oct 17, 2021 at 15:54
-
1A few things... After your "if num_students < 2: break" you don't need the next "if num_students >= 2:" . Also, when you determine that the current score is bumping the high score and you update the second_score = high_score, you should add a line to update the second_name at the same time. Other than that, without running your code, it looks like it should work. Also, your last "elif score < high_score:" could just be an "else:"GaryMBloom– GaryMBloom2021年10月17日 16:07:09 +00:00Commented Oct 17, 2021 at 16:07
3 Answers 3
In addition to Gary02127's solution, I'd like to point out a few other improvements:
You should move
if num_students < 2outside of your loop. It would be enough to check the condition once after the user inputted the number of students.You could also write
for i in range(num_students). It doesn't matter if the range starts with0or1since you are not usingi.Also, if you are not using a variable, you could use
_(throwaway variable) instead. See more aboutfor _ in range(num_students)here: What is the purpose of the single underscore "_" variable in Python?.
Instead of:
if score > second_score:
if score > high_score:
# ...
else:
# ...
You could also write:
if high_score < score:
# ...
elif second_score < score:
# ...
Here is a verbose solution considering suggested improvements:
num_students = int(input("Enter number of students: "))
if num_students < 2:
exit()
highest_name = None
highest_grade = 0
second_highest_name = None
second_highest_grade = 0
for _ in range(num_students):
name = input("Enter student's name: ")
grade = int(input("Enter student's score: "))
if highest_grade < grade:
second_highest_name = highest_name
second_highest_grade = highest_grade
highest_name = name
highest_grade = grade
elif second_highest_grade < grade:
second_highest_name = name
second_highest_grade = grade
print(highest_name, highest_grade) # highest grade
print(second_highest_name, second_highest_grade) # second highest grade
You could also use a list and sorted() (built-in function):
from operator import itemgetter
num_students = int(input("Enter number of students: "))
if num_students < 2:
exit()
grades = []
for _ in range(num_students):
name = input("Enter student's name: ")
grade = int(input("Enter student's score: "))
grades.append((name, grade))
grades = sorted(grades, key=itemgetter(1), reverse=True)
print(grades[0]) # highest grade
print(grades[1]) # second highest grade
You could also use a specialized list such as SortedList (requires external package):
from sortedcontainers import SortedList
num_students = int(input("Enter number of students: "))
if num_students < 2:
exit()
grades = SortedList(key=lambda record: -record[1])
for _ in range(num_students):
name = input("Enter student's name: ")
grade = int(input("Enter student's score: "))
grades.add((name, grade))
print(grades[0]) # highest grade
print(grades[1]) # second highest grade
Notes:
- Difference between
sorted()andstr.sort().sorted()creates a new sortedlistwhereasstr.sort()modifies the currentlist. itemgetter(1)is equals tolambda record: record[1].- You can install SortedList with:
pip install sortedcontainers.
Comments
Here's a solution based on my previous comments to your original post.
num_students = int(input("enter number of students: "))
high_score = 0
high_name = ""
second_name = ""
second_score = 0
for i in range(1,num_students + 1):
if num_students < 2:
break
# if num_students >= 2: # don't need this "if" after previous "break"
name = input("enter student name: ")
score = int(input("enter student score: "))
if score > second_score:
if score > high_score:
second_score = high_score
second_name = high_name # NEW
high_score = score
high_name = name
else: # simplified to just a plain "else:"
second_score = score
second_name = name
print()
print("Top Two Students")
print()
print(high_name,"'s score is", high_score)
print(second_name,"'s score is", second_score)
Notice that simplifying that last "elif ...:" to a simple "else:" also solves a simple bug where entering the current high score again can be ignored and not captured. If you were to run your code as is and use input values "100 80 100", you would find the 2nd high score set to 80 instead of 100.
3 Comments
You can simply store the details in a list. And use list.sort() to sort the values according to the score.
Here is the working code:
num_students = int(input("Enter number of students: "))
scores = []
if num_students < 2:
print('Number of students less than 2')
exit()
for i in range(num_students):
name = input("Enter student's name: ")
score = int(input("Enter student's score: "))
scores.append([name, score])
scores.sort(key=lambda details: details[1], reverse=True)
print("Top Two Students")
print()
print(f"{scores[0][0]}'s score is {scores[0][1]}")
print(f"{scores[1][0]}'s score is {scores[1][1]}")