"""
Practice: RAG over scans and screenshots, measured. Lab 08 Script 4's checks: did search put the
right page in the top k, is an answer right (the lab's is_right), which cards name something you
don't know, and what each way of answering costs.

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

PRICE = (0.20, 1.25)  # gpt-5.4-nano, USD per 1M tokens (input, output): the lab's list prices


def found(ranks: list, k: int) -> int:
    """How many questions had their right page in the top k.

    ranks[i] is where search put question i's right page (1 = first)."""
    # TODO
    return -1


def is_right(answer: str, correct: float) -> bool:
    """The lab's check: True if any number in the answer equals the right one.

    Remove commas first, so "$5,742.00" reads as 5742.00. "NOT FOUND" has no number, so it's never right."""
    # TODO: find every number with re.findall(r"\\d+(?:\\.\\d+)?", ...) and compare within 0.005
    return None


def names_on(card: str, kind: str) -> list:
    """The names a card mentions, the way each kind of page writes them.

    memo:      every word after "Project "        ("Project Heron is..." -> "Heron")
    dashboard: every word before "-service"       ("checkout-service" -> "checkout")
    invoice:   the card's first line, stripped     (the vendor's name)"""
    # TODO
    return []


def unknown_names(card: str, kind: str, known: list) -> list:
    """The names on a card that aren't in the known list (case-sensitive), each once, in order.

    A card with no name at all counts as unknown: return ["(no name)"]."""
    # TODO: use names_on
    return []


def cost_per_1000(input_tokens: int, output_tokens: int, calls: int, price=PRICE) -> float:
    """Dollars per 1,000 calls, from the total tokens over `calls` calls."""
    # TODO
    return 0.0
