SPB Git

spb/wp44_uqo

Public
2.9 KB · 48 lines python
1#!/usr/bin/env python32"""WP44 — generate manuscript/tables/numbers.tex: every number quoted in the prose is a LaTeX macro produced here from3result files (never typed by hand). Macro names use letters only (no digits: `\\nCoreEligible`, not `\\n2026`).4Sources: data/metadata/prisma_counts.json, linkage_report.json, results/bibliometrics/*.csv, results/econometrics/*.json,5taxonomy/validation/metrics.json, results/emerging/metrics_h12.json (each optional: missing → macro undefined → compile error,6which is intended: the prose cannot cite a number that does not exist)."""7import json, os, sys, csv, re8R = sys.argv[1] if len(sys.argv) > 1 else os.path.dirname(os.path.dirname(os.path.abspath(__file__)))9out = []10WORDS = {"0": "Zero", "1": "One", "2": "Two", "3": "Three", "4": "Four", "5": "Five", "6": "Six", "7": "Seven", "8": "Eight", "9": "Nine"}11def name(s):12    s = re.sub(r"[^A-Za-z0-9]+", " ", s).title().replace(" ", "")13    return "".join(WORDS[ch] if ch.isdigit() else ch for ch in s)14def fmt(v):15    if isinstance(v, bool): return str(v)16    if isinstance(v, int): return f"{v:,}".replace(",", "{,}")17    if isinstance(v, float):18        return f"{v:,.3f}".replace(",", "{,}") if abs(v) < 100 else f"{v:,.1f}".replace(",", "{,}")19    return str(v).replace("%", "\\%").replace("_", "\\_")20def emit(k, v):21    out.append(f"\\newcommand{{\\{name(k)}}}{{{fmt(v)}}}")22def walk(prefix, obj):23    if isinstance(obj, dict):24        for k, v in obj.items(): walk(f"{prefix} {k}", v)25    elif isinstance(obj, (int, float, str, bool)) and obj is not None:26        emit(prefix, obj)27p = os.path.join(R, "data/metadata/prisma_counts.json")28if os.path.exists(p): walk("prisma", json.load(open(p)))29p = os.path.join(R, "data/metadata/linkage_report.json")30if os.path.exists(p): walk("link", json.load(open(p)))31for f in ["volume_yearly", "citation_windows_yearly", "international_collab_yearly", "industry_share_yearly", "venue_hhi_yearly"]:32    p = os.path.join(R, "results/bibliometrics", f + ".csv")33    if os.path.exists(p):34        for row in csv.DictReader(open(p)):35            y = row.get("year") or row.get("publication_year")36            for k, v in row.items():37                if k in ("year", "publication_year") or v in ("", None): continue38                try: v = int(v) if re.fullmatch(r"-?\d+", v) else float(v)39                except ValueError: pass40                emit(f"{f} {y} {k}", v)41for f, key in [("results/econometrics/its_results.json", "its"), ("taxonomy/validation/metrics.json", "val"), ("results/emerging/metrics_h12.json", "emerg"), ("results/emerging/metrics_h24.json", "emergTwoFour")]:42    p = os.path.join(R, f)43    if os.path.exists(p):44        d = json.load(open(p))45        walk(key, {k: v for k, v in d.items() if not isinstance(v, (list,))})46open(os.path.join(R, "manuscript/tables/numbers.tex"), "w").write("% machine-generated by tables/make_numbers.py — do not edit\n" + "\n".join(out) + "\n")47print(len(out), "macros")48
Files · a549246b6e6d148c37f1b3b1d15a674cd2828d88
Menu

Theme