"""
Practice: text or page image, measured. Lab 08's grading of document answers (02_documents_as_images.py:
is_right and classify), what a column-by-column table does to extracted text, the token bill, and picking a scan
resolution.

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


def is_right(answer: str, correct, kind: str) -> bool:
    """The lab's grader. Three kinds of question:
    - "word": strip everything but letters from the answer, lowercase it, and compare with correct.lower()
      ("No." is right for "No"; "Yes" is not).
    - "text": right if str(correct), lowercased, appears anywhere in the lowercased answer
      ("room 4.12" is right for "4.12").
    - "number": remove commas, find every number in the answer (digits with an optional decimal part), and it's
      right if any of them is within 0.005 of correct ("$4,317.30" is right for 4317.3).
    """
    # TODO
    raise NotImplementedError


def outcome(answer: str, right: bool) -> str:
    """"right" if right; otherwise "not found" if the answer contains "not found" (any case); otherwise "wrong".
    "Not found" is the safe failure: you know you don't know. "Wrong" looks just like a right answer."""
    # TODO
    raise NotImplementedError


def split_columns(text: str, headers: list[str]) -> dict[str, list[str]]:
    """Extracted text from a table written one column at a time: each header line is followed by that column's
    cells, one per line, until the next header. Lines before the first header (titles, notes) are ignored.
    Return {header: [cells]} in order. A blank cell writes nothing, so its column comes out short."""
    # TODO
    raise NotImplementedError


def pair_in_order(columns: dict[str, list[str]], key: str, value: str) -> dict[str, str | None]:
    """Pair the key column with the value column by position: the 1st key gets the 1st value, and so on.
    Keys left without a value get None. This is what reading the text "in order" does."""
    # TODO
    raise NotImplementedError


def short_columns(columns: dict[str, list[str]]) -> list[str]:
    """The headers whose column has fewer cells than the longest column. A cheap check that would have flagged
    the price list before anyone trusted a pairing."""
    # TODO
    raise NotImplementedError


def cost_per_1000(input_tokens: int, output_tokens: int, n: int, price_in: float, price_out: float) -> float:
    """Dollars per 1,000 questions. input_tokens and output_tokens are totals over n questions; prices are USD per
    1M tokens. Don't round."""
    # TODO
    raise NotImplementedError


def lowest_good_dpi(results: dict[int, tuple[int, int]], need: float) -> int | None:
    """results maps scan DPI -> (right, asked). Return the lowest DPI whose share right is at least `need`, or
    None if no setting gets there. The cheapest setting that still reads your smallest print."""
    # TODO
    raise NotImplementedError
