SPB Git

spb/wp29_uqo

Public
5.3 KB · 114 lines python
1"""F4-dev-01 replication script. Reads only data/, writes out/results.json deterministically.2Values are extracted by regex from the release text; matched source lines are printed."""3import json, re, hashlib, os45SRC_ID = "statcan-daily-lfs-2026-09"6SRC = f"data/sources/{SRC_ID}.txt"7README = "data/README.md"8EXPECTED_SHA = "7ea5fec57c87874ff5ee09a8304927a1aaed5a1837db5312fab9f7a2d5f2d0bb"910def wc_l(path):11    with open(path, "rb") as f:12        return f.read().count(b"\n")1314raw = open(SRC, "rb").read()15sha = hashlib.sha256(raw).hexdigest()16assert sha == EXPECTED_SHA, f"SHA mismatch: {sha}"17lines = raw.decode("utf-8").split("\n")1819# map each line to the most recent '## ' section heading (level-2 only, as required by TASK.md)20section_of, cur = [], None21for ln in lines:22    if ln.startswith("## "):23        cur = ln[3:].strip()24    section_of.append(cur)2526def find(pattern):27    hits = []28    for i, ln in enumerate(lines):29        m = re.search(pattern, ln)30        if m:31            hits.append((i + 1, section_of[i], m, ln))32    return hits3334def loc(section):35    return f'{SRC_ID} | section "{section}"'3637# (a1) national unemployment rate -- first statement in Highlights38ur_hits = find(r"The unemployment rate (?:increased|rose|fell|decreased) \d+\.\d percentage points to (\d+\.\d)%")39ur_nat = [h for h in ur_hits if h[1] in ("Highlights", "Unemployment rate increases to 6.5%")]40ur_vals = {float(h[2].group(1)) for h in ur_nat}41assert len(ur_vals) == 1, ur_vals42ur = ur_vals.pop()43ur_primary = next(h for h in ur_nat if h[1] == "Highlights")4445# (a2) national employment change46emp_hits = find(r"^(?:In September, e|E)mployment (declined|increased|rose|fell) by ([\d,]+) \(")47emp_vals = set()48for h in emp_hits:49    sign = -1 if h[2].group(1) in ("declined", "fell") else 150    emp_vals.add(sign * int(h[2].group(2).replace(",", "")))51assert len(emp_vals) == 1, emp_vals52emp = emp_vals.pop()53emp_primary = next(h for h in emp_hits if h[1] == "Highlights")5455print("Matched source lines:")56for tag, hs in (("unemployment_rate", ur_nat), ("employment_change", emp_hits)):57    for (n, sec, m, ln) in hs:58        print(f"  [{tag}] line {n} | section \"{sec}\": {ln}")5960# (b) assertion: women +0.3 to 5.3%; men ROSE 0.2 to 5.8%61w = find(r"core-aged women \(25 to 54 years old\), the unemployment rate (rose|fell) (\d+\.\d) percentage points to (\d+\.\d)%")62mn = find(r"unemployment rate for core-aged men (rose|fell) (\d+\.\d) percentage points to (\d+\.\d)%")63assert len(w) == 1 and len(mn) == 164wd, wpp, wlvl = w[0][2].groups()65md, mpp, mlvl = mn[0][2].groups()66print(f"  [assertion women] line {w[0][0]} | section \"{w[0][1]}\": {w[0][3]}")67print(f"  [assertion men]   line {mn[0][0]} | section \"{mn[0][1]}\": {mn[0][3]}")68women_ok = (wd == "rose" and wpp == "0.3" and wlvl == "5.3")69men_ok = (md == "rose" and mpp == "0.2" and mlvl == "5.8")70verdict = "supported" if (women_ok and men_ok) else "not_supported"71assert w[0][1] == mn[0][1]72reason = (f"The women's element matches (\"rose {wpp} percentage points to {wlvl}%\"), but the release states that "73          f"\"the unemployment rate for core-aged men {md} {mpp} percentage points to {mlvl}% in the month\", "74          f"contradicting the claim that it rose." if not men_ok else75          "Every element of the assertion is stated in the release.")7677results = {78    "task_id": "F4-dev-01",79    "unemployment_rate_sep2026": ur,80    "employment_change_sep2026_persons": emp,81    "locators": {82        "unemployment_rate_sep2026": loc(ur_primary[1]),83        "employment_change_sep2026_persons": loc(emp_primary[1]),84    },85    "assertion_verdict": verdict,86    "assertion_locator": loc(w[0][1]),87    "assertion_reason": reason,88    "feasibility": "complete",89    "feasibility_reason": None,90    "data_issues": [91        {"issue": "data/README.md rights note refers to re-set tables ('RESEA Tables 2-3, London Table 3 header') and regression-table rendering that do not exist in this extract (apparently template text from another task).",92         "handling": "Ignored; irrelevant to the LFS extract, whose SHA-256 matches the README value. No tables are reproduced in the extract."},93        {"issue": "Some text (e.g. layoff rate, participation rate, population-aging text box) appears under '## Infographic 2' because chart/infographic titles are rendered as '##' headings; the text-box title is not a '##' heading.",94         "handling": "Not relevant to the extracted figures, which appear under substantive narrative headings; locators use the nearest preceding '##' heading."},95    ],96    "n_input_rows": {"README.md": wc_l(README), f"{SRC_ID}.txt": wc_l(SRC)},97    "n_analysed": 3,98    "random_seed": None,99    "baseline_consistency": {100        "unemployment_rate_statements_agree": True,101        "n_unemployment_rate_statements": len(ur_nat),102        "employment_change_statements_agree": True,103        "n_employment_change_statements": len(emp_hits),104        "alternate_locator_unemployment_rate": loc("Unemployment rate increases to 6.5%"),105        "alternate_locator_employment_change": loc("Employment falls for second consecutive month"),106    },107    "source_sha256": sha,108}109os.makedirs("out", exist_ok=True)110with open("out/results.json", "w") as f:111    json.dump(results, f, indent=2, ensure_ascii=False)112    f.write("\n")113print(f"unemployment_rate_sep2026={ur}; employment_change_sep2026_persons={emp}; assertion_verdict={verdict}")114
Files · 6df43c338e49477c769c36e7f7d249af2563db7f
Menu

Theme