Skip to content

S3Q1 · Student Score Operations

⚡ Quick Reference

Function: process_records(records, operation, subject=None)

def process_records(records, operation, subject=None):
    if operation == "count_records":
        return len(records)

    if operation not in ("average_by_subject", "top_student_by_subject", "pass_count"):
        return {}

    if subject is None:
        return {}

    filtered = [r for r in records if r[2] == subject]
    if not filtered:
        return {}

    if operation == "average_by_subject":
        return sum(r[1] for r in filtered) / len(filtered)
    if operation == "top_student_by_subject":
        return max(filtered, key=lambda r: r[1])[0]
    if operation == "pass_count":
        return sum(1 for r in filtered if r[1] >= 60)

Key rules: - count_records needs no subject - return len(records) - Other operations: return {} if subject=None or no matching records - Invalid operation → return {} - top_student_by_subject tie → first appearance (max preserves first on tie)


Problem Statement

Problem

Write a function process_records(records, operation, subject=None) that performs one of four operations on a list of (student_id, score, subject) tuples.

Sample data:

records = [
    ("S1", 85, "Math"),
    ("S2", 72, "Math"),
    ("S3", 91, "Science"),
    ("S4", 55, "Math"),
    ("S5", 65, "Science"),
]


Operation 1 - count_records

Simply return the total number of records - no subject needed:

if operation == "count_records":
    return len(records)

From sample: process_records(records, "count_records")5


Operation 2 - average_by_subject

Filter by subject, compute mean:

filtered = [r for r in records if r[2] == subject]
return sum(r[1] for r in filtered) / len(filtered)

From sample: Math scores = [85, 72, 55] → average = 70.67


Operation 3 - top_student_by_subject

Filter by subject, return student_id with highest score. Ties → first in list:

return max(filtered, key=lambda r: r[1])[0]

max() scans left to right and only updates on strictly greater values - ties naturally return the first occurrence.

From sample: Math students → ("S1",85), ("S2",72), ("S4",55) → top = "S1"


Operation 4 - pass_count

Count records with score >= 60 for the given subject:

return sum(1 for r in filtered if r[1] >= 60)

From sample: Math pass (≥60) = S1(85), S2(72) → 2. S4(55) fails.


Complete solution approaches

def process_records(records, operation, subject=None):
    if operation == "count_records":
        return len(records)

    if operation not in ("average_by_subject", "top_student_by_subject", "pass_count"):
        return {}

    if subject is None:
        return {}

    filtered = [r for r in records if r[2] == subject]
    if not filtered:
        return {}

    if operation == "average_by_subject":
        return sum(r[1] for r in filtered) / len(filtered)
    if operation == "top_student_by_subject":
        return max(filtered, key=lambda r: r[1])[0]
    if operation == "pass_count":
        return sum(1 for r in filtered if r[1] >= 60)
def process_records(records, operation, subject=None):
    if operation == "count_records":
        return len(records)

    elif operation == "average_by_subject":
        if subject is None:
            return {}
        filtered = [r for r in records if r[2] == subject]
        if not filtered:
            return {}
        return sum(r[1] for r in filtered) / len(filtered)

    elif operation == "top_student_by_subject":
        if subject is None:
            return {}
        filtered = [r for r in records if r[2] == subject]
        if not filtered:
            return {}
        best = filtered[0]
        for r in filtered[1:]:
            if r[1] > best[1]:
                best = r
        return best[0]

    elif operation == "pass_count":
        if subject is None:
            return {}
        filtered = [r for r in records if r[2] == subject]
        if not filtered:
            return {}
        return sum(1 for r in filtered if r[1] >= 60)

    else:
        return {}
def process_records(records, operation, subject=None):
    if operation == "count_records":
        return len(records)

    if subject is None:
        return {}

    filtered = [r for r in records if r[2] == subject]
    if not filtered:
        return {}

    ops = {
        "average_by_subject":    lambda f: sum(r[1] for r in f) / len(f),
        "top_student_by_subject": lambda f: max(f, key=lambda r: r[1])[0],
        "pass_count":            lambda f: sum(1 for r in f if r[1] >= 60),
    }
    return ops.get(operation, lambda _: {})(filtered)

Each operation is stored as a lambda in a dict. ops.get(operation, lambda _: {}) returns {} for unknown operations. Clean and extensible.


Key takeaways

01

Filter once, reuse the filtered list

Compute filtered = [r for r in records if r[2] == subject] once before the operation-specific logic. All subject-dependent operations use the same filtered list.

02

max(key=lambda) preserves first on tie

max() scans left to right and only updates on strictly greater values. When scores are tied, the first student in the list stays as the best - no extra tie-breaking logic needed.

03

Return {} for all invalid/missing cases

Three distinct cases all return {}: invalid operation, missing subject, and no matching records. Checking them in order with early returns keeps the function flat and readable.