Thuta Learning
ProjectsData & Databasesintermediate

Student Score Project - Part 3: Final Report

Relax. We'll talk through this in plain words — no textbook voice.

What you'll walk away with

  • Apply Student Score Project - Part 3: Final Report in a hands-on project
  • Write and run the code yourself
  • Build out an entire project step by step

Take a moment to think about this

In this final step, we'll take Part 2's curved_scores as the base and compute a weighted final score using subject weights (giving Math more weight) via np.dot() matrix multiplication. Then we'll use np.random.seed() to generate a reproducible random bonus quiz score and add it to the final score. Finally, we'll use np.argsort() to rank students from highest to lowest score and print a formatted final report table, wrapping up the project. This step pulls together everything you've learned throughout the tutorial — array creation, indexing, aggregation, broadcasting, linear algebra, and the random module — all in one place.

Let's build it

Create a weight array (Math 0.3, Myanmar 0.2, English 0.2, Science 0.3) and use np.dot(curved_scores, weights) to compute each student's weighted final score. Set a seed with np.random.seed(42), then use np.random.randint(0, 10, size=5) to generate a random bonus quiz score for each of the 5 students. Compute final_score = weighted_score + bonus, then use np.argsort(final_score)[::-1] to find the rank order (highest first). Use a for loop to print each student's name and final score, ranked, in a formatted string to finish the final report.

Example Code

python
import numpy as np

students = ["Aye", "Bo", "Cho", "Dan", "Eaint"]

curved_scores = np.array([
    [80, 90, 90, 75],
    [66, 75, 58, 83],
    [97, 93, 92, 94],
    [52, 65, 55, 51],
    [84, 84, 84, 91]
])

weights = np.array([0.3, 0.2, 0.2, 0.3])
weighted_score = np.dot(curved_scores, weights)

np.random.seed(42)
bonus = np.random.randint(0, 10, size=5)

final_score = weighted_score + bonus

# rank: highest final_score first
rank_order = np.argsort(final_score)[::-1]

print("=== Final Report ===")
for rank, idx in enumerate(rank_order, start=1):
    print(f"{rank}. {students[idx]:<6} weighted={weighted_score[idx]:.1f} bonus={bonus[idx]} final={final_score[idx]:.1f}")
You should see
Under the === Final Report === label, you'll see 5 formatted lines listing the 5 students ranked from rank 1 to 5 by highest final_score, along with their weighted, bonus, and final score values.

Try it in 5 minutes

Change the weight array to [0.2, 0.2, 0.2, 0.4], giving Science more weight, and check whether the rank order changes (5 minutes).

A quick word of caution

For np.dot(matrix, vector), the vector's length has to match the matrix's column count — whenever the subject count changes, don't forget to update the weights array's length too.

Easy traps

  • Writing a weights vector for np.dot() whose length doesn't match the scores column count (subject count), triggering a shape mismatch error
  • Not setting np.random.seed(), so the bonus value changes every run and the report isn't reproducible

Try it yourself

Change the weight array to [0.2, 0.2, 0.2, 0.4], giving Science more weight, and check whether the rank order changes (5 minutes).

You'll know it worked when: Under the === Final Report === label, you'll see 5 formatted lines listing the 5 students ranked from rank 1 to 5 by highest final_score, along with their weighted, bonus, and final score values.

Student Score Project - Part 3: Final Report | Thuta Learning