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:
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:
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:
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¶
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.
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.
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.