#!/usr/bin/env python3
"""FlashMemory teaching example: threshold evaluation on an untouched synthetic holdout.

No model is trained or threshold optimized here. Scores are fictional and labels
are retrospective teaching annotations, not real fab failure measurements.
Python 3 standard library only. Run beside holdout-events.csv.
"""
import csv
import json
from pathlib import Path

path = Path(__file__).with_name("holdout-events.csv")
with path.open(encoding="utf-8", newline="") as f:
    rows = list(csv.DictReader(f))
assert len(rows) == 24
ids = [r["event_id"] for r in rows]
assert len(ids) == len(set(ids))
assert [int(r["time_order"]) for r in rows] == list(range(1, 25))
scores = [float(row["model_score"]) for row in rows]
labels = [int(row["reviewed_label"]) for row in rows]
assert all(0 <= x <= 1 for x in scores)
assert set(labels) == {0, 1}
assert sum(labels) == 6

def evaluate(threshold):
    predictions = [int(score >= threshold) for score in scores]
    tp = sum(p == 1 and y == 1 for p,y in zip(predictions,labels))
    fp = sum(p == 1 and y == 0 for p,y in zip(predictions,labels))
    tn = sum(p == 0 and y == 0 for p,y in zip(predictions,labels))
    fn = sum(p == 0 and y == 1 for p,y in zip(predictions,labels))
    precision = tp / (tp + fp) if (tp+fp) else None
    recall = tp / (tp+fn) if (tp+fn) else None
    false_positive_rate = fp / (fp+tn) if (fp+tn) else None
    return {
        "threshold":threshold, "TP":tp, "FP":fp, "TN":tn, "FN":fn,
        "alerts":tp+fp,
        "precision":round(precision,4) if precision is not None else None,
        "recall":round(recall,4) if recall is not None else None,
        "false_positive_rate":round(false_positive_rate,4) if false_positive_rate is not None else None,
    }
low = evaluate(0.60)
high = evaluate(0.80)
assert (low["TP"],low["FP"],low["TN"],low["FN"]) == (5,5,13,1)
assert (high["TP"],high["FP"],high["TN"],high["FN"]) == (3,1,17,3)
print(json.dumps({
    "dataset":"SYNTHETIC_TRAINING_ONLY",
    "warning":"Descriptive evaluation of pre-fixed thresholds on fictional retrospectively reviewed events, not a measured production ML model. Do not pick a winning threshold using this final holdout.",
    "events":len(rows), "reviewed_positive":sum(labels),
    "predefined_thresholds":[low,high],
},ensure_ascii=False,indent=2))
