74 lines
2.1 KiB
Python
74 lines
2.1 KiB
Python
#!/usr/bin/env python3
|
|
# Import-free verifier for top-python-repos-2026-10-26.
|
|
# Exit code 0 = artifact correct, nonzero = wrong.
|
|
import csv
|
|
import json
|
|
import sys
|
|
|
|
BASE = "/root/troupe-standup/wizard-work/ledger"
|
|
CSV_PATH = BASE + "/top-python-repos-2026-10-26.csv"
|
|
JSON_PATH = BASE + "/top-python-repos-2026-10-26.json"
|
|
HEADER = ["rank", "name", "owner", "description", "stars", "forks", "html_url", "language"]
|
|
|
|
|
|
def fail(msg):
|
|
print("CHECK FAIL: " + msg)
|
|
sys.exit(1)
|
|
|
|
|
|
try:
|
|
with open(JSON_PATH) as f:
|
|
payload = json.load(f)
|
|
except Exception as e:
|
|
fail("cannot read json: %r" % e)
|
|
|
|
items = payload.get("items")
|
|
if not items:
|
|
fail("json has no items")
|
|
|
|
# Expected order: stars desc, name asc
|
|
expected = sorted(items, key=lambda r: (-int(r.get("stargazers_count") or 0), r.get("name", "")))
|
|
expected_rows = []
|
|
for i, r in enumerate(expected, 1):
|
|
owner = r.get("owner") or {}
|
|
expected_rows.append({
|
|
"rank": str(i),
|
|
"name": r.get("name", ""),
|
|
"owner": owner.get("login", "") if isinstance(owner, dict) else "",
|
|
"description": r.get("description") or "",
|
|
"stars": str(int(r.get("stargazers_count") or 0)),
|
|
"forks": str(int(r.get("forks_count") or 0)),
|
|
"html_url": r.get("html_url", ""),
|
|
"language": r.get("language") or "",
|
|
})
|
|
|
|
try:
|
|
with open(CSV_PATH, newline="") as f:
|
|
rows = list(csv.DictReader(f))
|
|
except Exception as e:
|
|
fail("cannot read csv: %r" % e)
|
|
|
|
if not rows:
|
|
fail("csv is empty")
|
|
|
|
if list(rows[0].keys()) != HEADER:
|
|
fail("header mismatch: %r" % list(rows[0].keys()))
|
|
|
|
if len(rows) != 50:
|
|
fail("row count %d != 50" % len(rows))
|
|
|
|
for i, (act, exp) in enumerate(zip(rows, expected_rows), 1):
|
|
if act != exp:
|
|
fail("row %d mismatch: %r != %r" % (i, act, exp))
|
|
|
|
stars = [int(r["stars"]) for r in rows]
|
|
if any(a < b for a, b in zip(stars, stars[1:])):
|
|
fail("stars not non-increasing")
|
|
|
|
ranks = [int(r["rank"]) for r in rows]
|
|
if ranks != list(range(1, 51)):
|
|
fail("ranks not 1..50")
|
|
|
|
print("CHECK PASS: %d rows | top=%s/%s stars=%s" % (
|
|
len(rows), rows[0]["owner"], rows[0]["name"], rows[0]["stars"]))
|