"""
Practice: reading LLM calls like an engineer (Lab 01, scripts 1 and 5).

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


def was_cut(response: dict) -> bool:
    """True when the answer stopped at the output limit instead of finishing.

    `response` is a Chat Completions response as a dict. The first choice's finish_reason is
    "length" when the limit was hit, and "stop" when the model finished on its own.

    TODO 1
    """
    return False


def alike(runs: list[str]) -> float:
    """How alike several runs of the same prompt are.

    For every pair of runs, compare their WORDS (a.split(), b.split()) with
    difflib.SequenceMatcher(None, words_a, words_b).ratio(). Return the average, rounded
    to 2 places. A single run is 1.0.

    TODO 2
    """
    return 0.0


def unfair_cases(cases: list[dict]) -> list[str]:
    """The inputs where exactly one of the two prompts' answers was cut off.

    Each case has "input", "a_cut" and "b_cut". On those inputs the comparison measured the
    output limit, not the prompt.

    TODO 3
    """
    return []


def verdict(a: list[int], b: list[int]) -> str:
    """One question, judged twice: index 0 with A shown first, index 1 with B shown first.

    a = [A's score when shown first, A's score when shown second]
    b = [B's score when A was shown first, B's score when B was shown first]

    Return "A" or "B" if that prompt scored higher in BOTH orders, "flips" if each order
    has a different winner, and "tie" otherwise (equal scores in either order).

    TODO 4
    """
    return "tie"


def compare(cases: list[dict]) -> dict:
    """Tally verdict(c["a"], c["b"]) over every case: {"A": n, "B": n, "flips": n, "tie": n}."""
    out = {"A": 0, "B": 0, "flips": 0, "tie": 0}
    for c in cases:
        out[verdict(c["a"], c["b"])] += 1
    return out


def position_bias(cases: list[dict]) -> tuple[float, float]:
    """(average score of the answer shown FIRST, average score of the answer shown SECOND),
    over every judgment in every case, each rounded to 2 places.

    Shown first: A in order 0 (c["a"][0]) and B in order 1 (c["b"][1]).
    Shown second: A in order 1 and B in order 0.

    TODO 5
    """
    return 0.0, 0.0
