optik404
optik404

Reputation: 31

Python if elif and loops

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)

Upvotes: 0

Views: 232

Answers (3)

GaryMBloom
GaryMBloom

Reputation: 5682

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.

Upvotes: 1

Thomas
Thomas

Reputation: 10065

In addition to Gary02127's solution, I'd like to point out a few other improvements:

  • You should move if num_students < 2 outside 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 with 0 or 1 since you are not using i.

  • Also, if you are not using a variable, you could use _ (throwaway variable) instead. See more about for _ 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() and str.sort(). sorted() creates a new sorted list whereas str.sort() modifies the current list.
  • itemgetter(1) is equals to lambda record: record[1].
  • You can install SortedList with: pip install sortedcontainers.

Upvotes: 2

Random_Pythoneer59
Random_Pythoneer59

Reputation: 728

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]}")

Upvotes: 0

Related Questions