3.14 Libraries HW — Season Stats Report

Lesson: https://pages.opencodingsociety.com/python/libraries/2027

Core rule: don’t rewrite tested code — import a library, read its API docs, call its procedures. AAP-3.D.

Popcorn Hack 1 — read the API, then use it

Change: jersey range 1-99 → 1-55. Prediction: any integer 1–55 (I predicted ~41); math.ceil(avg) still rounds the same average up.

Code Runner Challenge

Popcorn 1 - box score math with math + random

View IPYNB Source
# CODE_RUNNER: Popcorn 1 - box score math with math + random
import math
import random

# Read the API before calling (name, params, return value)
print("random.randint:", random.randint.__doc__)
print("math.ceil:", math.ceil.__doc__)

points_per_game = [24, 18, 31, 27, 22]

# Changed jersey range to 1-55 per task (was 1-99); prediction: jersey in 1..55, e.g. 41
print("Random game to review:", random.choice(points_per_game), "points")
jersey = random.randint(1, 55)
print("Random jersey number (1-55):", jersey)

side = math.sqrt(144)
print("Square court side:", side, "feet")

average = sum(points_per_game) / len(points_per_game)
rounded_up = math.ceil(average)
print("Points per game:", average, "-> rounded up:", rounded_up)

Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

Popcorn Hack 2 — Flask route

Change: custom roster names + extra /coach route (procedure with a web address). jsonify turns the dict into JSON.

Code Runner Challenge

Popcorn 2 - Flask scoreboard routes

View IPYNB Source
# CODE_RUNNER: Popcorn 2 - Flask scoreboard routes
from flask import Flask, jsonify

app = Flask(__name__)

# My roster (changed per task)
@app.route("/score")
def score():
    return jsonify({"home": 58, "away": 52, "quarter": 3})

@app.route("/roster")
def roster():
    return jsonify({"players": ["Samarth", "Ryden", "Aarav"]})

# My extra route (pattern copied): coach of the season stats app
@app.route("/coach")
def coach():
    return jsonify({"coach": "Coach Hande", "season": "2026-27"})

client = app.test_client()
print("/score says:", client.get("/score").get_json())
print("/roster says:", client.get("/roster").get_json())
print("/coach says:", client.get("/coach").get_json())

Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

Homework Hack — Season Stats Report (soccer)

Uses 5 stdlib modules: json, datetime, statistics, random, math. summarize_season has a full API docstring. Own sport (soccer goals), own games, next game 2027-03-01. requirements.txt lists only externals (pandas, Flask); stdlib is never listed.

Code Runner Challenge

Homework - Season Stats Report (soccer)

View IPYNB Source
# CODE_RUNNER: Homework - Season Stats Report (soccer)
import json
import math
import random
import statistics
from datetime import date

games = [
    {"date": "2026-09-14", "opponent": "Lincoln", "goals": 2, "minutes": 80},
    {"date": "2026-09-15", "opponent": "Madison", "goals": 1, "minutes": 70},
    {"date": "2026-09-16", "opponent": "Lincoln", "goals": 3, "minutes": 85},
    {"date": "2026-09-18", "opponent": "Roosevelt", "goals": 0, "minutes": 60},
]

def summarize_season(season):
    """Summarize a list of soccer games.

    Parameters:
        season: list of dictionaries, each with "date", "opponent", "goals", and "minutes"
    Returns:
        dictionary with total_points, average_points, best_game,
        and points_by_opponent (goals work as points here)
    """
    points = [game["goals"] for game in season]
    points_by_opponent = {}
    for game in season:
        opponent = game["opponent"]
        points_by_opponent[opponent] = points_by_opponent.get(opponent, 0) + game["goals"]
    return {
        "total_points": sum(points),
        "average_points": round(statistics.mean(points), 1),
        "best_game": max(points),
        "points_by_opponent": points_by_opponent,
    }

report = summarize_season(games)

# datetime: days until my next game; math: round a save-percentage stat; random: pick a MOTM
next_game = date(2027, 3, 1)
report["days_until_next_game"] = (next_game - date.today()).days
report["save_pct_rounded_up"] = math.ceil(87.2)
report["motm_pick"] = random.choice([g["opponent"] for g in games])

print(json.dumps(report, indent=2))

# requirements.txt lists only external packages. json, datetime, statistics,
# math, and random come with Python, so they are never listed.
requirements_txt = """pandas  # season table
Flask  # scoreboard web routes
"""
print()
print("requirements.txt:")
print(requirements_txt)

Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...
Lesson: CSP 3.14 Libraries
Popcorn 1: what I changed = jersey range 1-99 -> 1-55
Popcorn 2: my extra route = /coach
Homework: libraries used = json, datetime, statistics, random, math
Homework: days until my next game = 151 (2027-03-01)