Created
February 6, 2026 16:38
-
-
Save epignatelli/82704cb3a445df34e21c5d3e19a32f0e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| """Utilities for working with a tiny in-memory gradebook. | |
| This module defines a small `Gradebook` class that stores scores for named | |
| students and provides summary statistics such as averages. | |
| Examples: | |
| >>> gb = Gradebook() | |
| >>> gb.add_score("alice", 18.0) | |
| >>> gb.add_score("alice", 12.0) | |
| >>> gb.average("alice") | |
| 15.0 | |
| """ | |
| from __future__ import annotations | |
| from typing import Dict, List | |
| class Gradebook: | |
| """A minimal gradebook that stores multiple numeric scores per student. | |
| The gradebook maps a student's name to a list of scores. Names are stored | |
| after stripping whitespace. Scores must be finite floats. | |
| Examples: | |
| >>> gb = Gradebook() | |
| >>> gb.add_score("bob", 10.0) | |
| >>> gb.add_score("bob", 20.0) | |
| >>> gb.scores("bob") | |
| [10.0, 20.0] | |
| >>> gb.average("bob") | |
| 15.0 | |
| """ | |
| def __init__(self) -> None: | |
| """Initialize an empty gradebook. | |
| Examples: | |
| >>> gb = Gradebook() | |
| >>> gb.scores("anyone") | |
| [] | |
| """ | |
| self._scores: Dict[str, List[float]] = {} | |
| def add_score(self, student: str, score: float) -> None: | |
| """Add a score for a student. | |
| Args: | |
| student: Student name (non-empty after stripping whitespace). | |
| score: Numeric score to store. | |
| Raises: | |
| ValueError: If `student` is empty after stripping, or if `score` is | |
| not a finite number. | |
| Examples: | |
| >>> gb = Gradebook() | |
| >>> gb.add_score("alice", 17.5) | |
| >>> gb.scores("alice") | |
| [17.5] | |
| """ | |
| name = student.strip() | |
| if not name: | |
| raise ValueError("student must be a non-empty string") | |
| if score != score or score in (float("inf"), float("-inf")): | |
| raise ValueError("score must be a finite number") | |
| self._scores.setdefault(name, []).append(float(score)) | |
| def scores(self, student: str) -> List[float]: | |
| """Return a copy of the scores for a student. | |
| Args: | |
| student: Student name. | |
| Returns: | |
| A new list containing that student's stored scores. If the student | |
| has no scores, returns an empty list. | |
| Examples: | |
| >>> gb = Gradebook() | |
| >>> gb.add_score("carla", 5.0) | |
| >>> gb.scores("carla") | |
| [5.0] | |
| >>> gb.scores("nobody") | |
| [] | |
| """ | |
| return list(self._scores.get(student.strip(), [])) | |
| def average(self, student: str) -> float: | |
| """Compute the average score for a student. | |
| Args: | |
| student: Student name. | |
| Returns: | |
| The arithmetic mean of the student's scores. | |
| Raises: | |
| ValueError: If the student has no recorded scores. | |
| Examples: | |
| >>> gb = Gradebook() | |
| >>> gb.add_score("bob", 10.0) | |
| >>> gb.add_score("bob", 20.0) | |
| >>> gb.average("bob") | |
| 15.0 | |
| """ | |
| name = student.strip() | |
| values = self._scores.get(name, []) | |
| if not values: | |
| raise ValueError(f"no scores recorded for {name!r}") | |
| return sum(values) / len(values) | |
| def class_average(self) -> float: | |
| """Compute the average across all stored scores. | |
| Returns: | |
| The arithmetic mean across every score in the gradebook. | |
| Raises: | |
| ValueError: If there are no scores in the gradebook. | |
| Examples: | |
| >>> gb = Gradebook() | |
| >>> gb.add_score("a", 10.0) | |
| >>> gb.add_score("b", 20.0) | |
| >>> gb.class_average() | |
| 15.0 | |
| """ | |
| all_scores: List[float] = [] | |
| for values in self._scores.values(): | |
| all_scores.extend(values) | |
| if not all_scores: | |
| raise ValueError("no scores recorded in gradebook") | |
| return sum(all_scores) / len(all_scores) | |
| def main() -> None: | |
| """Run a small demonstration of the `Gradebook` class. | |
| Examples: | |
| $ python main.py | |
| Alice scores: [18.0, 12.0] | |
| Alice average: 15.0 | |
| Class average: 15.0 | |
| """ | |
| gradebook = Gradebook() | |
| gradebook.add_score("alice", 18.0) | |
| gradebook.add_score("alice", 12.0) | |
| gradebook.add_score("bob", 15.0) | |
| print("Alice scores:", gradebook.scores("alice")) | |
| print("Alice average:", gradebook.average("alice")) | |
| print("Class average:", gradebook.class_average()) | |
| if __name__ == "__main__": | |
| main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment