Files
troupe-standup/wizard-work/ledger/check_gdp_nominal.py
T

83 lines
2.7 KiB
Python

#!/usr/bin/env python3
"""Real cross-check: re-fetches the World Bank GDP nominal-2023 API and compares the
committed gdp_nominal_usd_2023.csv (next to this script) against a fresh computation.
Exit code: 0 = artifact matches the live source of truth; 1 = mismatch.
"""
import csv
import json
import os
import sys
import urllib.request
HERE = os.path.dirname(os.path.abspath(__file__))
CSV_PATH = os.path.join(HERE, "gdp_nominal_usd_2023.csv")
ISO3_PATH = os.path.join(HERE, "iso3_codes.txt")
API_URL = ("https://api.worldbank.org/v2/country/all/indicator/NY.GDP.MKTP.CD"
"?format=json&date=2023:2023&per_page=1000")
TOLERANCE_USD = 1_000_000 # 1e6 USD == 0.001B (artifact rounds to 3 decimals)
def fetch_json(url):
req = urllib.request.Request(url, headers={"User-Agent": "ledger/extract/1.0"})
with urllib.request.urlopen(req, timeout=40) as r:
return json.loads(r.read().decode("utf-8"))
def main():
with open(ISO3_PATH, encoding="utf-8") as f:
iso3 = {ln.strip() for ln in f if ln.strip()}
payload = fetch_json(API_URL)
records = payload[1] if isinstance(payload, list) and payload else []
api = []
for rec in records:
iso = rec.get("countryiso3code")
val = rec.get("value")
if iso in iso3 and val is not None:
api.append((rec["country"]["value"], iso, float(val)))
api.sort(key=lambda x: -x[2])
top20 = api[:20]
with open(CSV_PATH, encoding="utf-8") as f:
rows = [r for r in csv.reader(f) if r]
if not rows:
print("FAIL: artifact CSV is empty")
sys.exit(1)
data = rows[1:]
if len(data) != 20:
print(f"FAIL: artifact has {len(data)} data rows, expected 20")
sys.exit(1)
ok = True
for i, (cname, ciso, cval) in enumerate(top20):
row = data[i]
try:
artifact_usd = float(row[3]) * 1e9
except (ValueError, IndexError):
artifact_usd = None
good = (row[1] == cname) and (row[2] == ciso) and (artifact_usd is not None
and abs(artifact_usd - cval) < TOLERANCE_USD)
if not good:
ok = False
print(f"MISMATCH rank {i+1}: source={cname} {ciso} {cval:.3f}B; "
f"artifact={row}")
values = [float(r[3]) for r in data]
if values != sorted(values, reverse=True):
ok = False
print("FAIL: artifact rows are not in descending GDP order")
if ok:
print(f"CHECK OK: {len(top20)} countries match the live World Bank API "
f"(US={top20[0][1]}, China={top20[1][1]}).")
sys.exit(0)
print("CHECK FAIL")
sys.exit(1)
if __name__ == "__main__":
main()