"""
Practice: what shrinking a model buys and costs, measured. Lab 12's arithmetic for running a model
yourself (07_local_speed.py, 08_quantization.py): the decode-speed ceiling, the size of a model
stored in fewer bits, how many answers changed (not just the score), and the long-pile recall test.

Fill in the TODOs, then run the tests:
    pytest test_quant_practice.py        (locally)
or press "Run tests" on the chapter page.
"""


def ceiling(bandwidth_gbs, weights_gb):
    """The rough decode-speed ceiling, in tokens per second. Writing each token reads every weight
    once, so a model of `weights_gb` can't decode faster than bandwidth / weights."""
    # TODO
    return 0.0


def weights_gb(params_billion, bits, group=64):
    """Size of the weights in GB (1e9 bytes).
    - 16 bits: 2 bytes per number.
    - Fewer bits (MLX's quantize, as in script 08): `bits` per number, plus, for every `group`
      numbers, a 16-bit scale and a 16-bit offset (the group's own ruler)."""
    # TODO
    return 0.0


def compare(gold, ref, new):
    """Compare a shrunk model's answers (`new`) with the full-size model's (`ref`) on the same
    questions; `gold` holds the right answers. Return a dict:
    - "ref_right", "new_right": how many each got right,
    - "same": the share of questions where new gave exactly ref's answer, right or wrong (0..1),
    - "changed": how many answers differ from ref's,
    - "r2w": right -> wrong, "w2r": wrong -> right, "w2w": wrong -> a different wrong answer."""
    # TODO
    return {"ref_right": 0, "new_right": 0, "same": 0.0, "changed": 0, "r2w": 0, "w2r": 0, "w2w": 0}


def recall(answers, expected):
    """The long-pile test, graded as script 08 does: a reply counts if, with spaces and then full
    stops trimmed from both ends, it equals the expected name, ignoring case. Return the count."""
    # TODO
    return 0
