Source document

scripts/analysis/inspect_sqr.py

Served verbatim from the project repository. Internal working document conventions apply: documents may reference file paths, branch names, and findings-ledger anchors from the repo.

#!/usr/bin/env python
"""Verify what comparison-group data NYC publishes in the School Quality Report
(SQR) 'Citywide Results' Excel files. Downloads a few years of EMS/HS files and
reports: which sheet holds the metrics, the per-metric column family
(Metric Value / N Count / Comparison Group / Metric Rating), a sample row, and
school-level coverage. Read-only; writes nothing back. Files are public.

Run: scripts/analysis/.venv/bin/python scripts/analysis/inspect_sqr.py
(needs openpyxl + requests in the venv)
"""
import io
import re
import openpyxl
import urllib.request

BASE = "https://infohub.nyced.org/docs/default-source/default-document-library"
FILES = {
    "2024-25 EMS": "202425-ems-sqr-results.xlsx",
    "2023-24 EMS": "202324-ems-sqr-results.xlsx",
    "2024-25 HS": "202425-hs-sqr-results.xlsx",
    "2023-24 HS": "202324-hs-sqr-results.xlsx",
    "2018-19 EMS": "201819-ems-sqr-results.xlsx",  # older format, for comparison
}

def header_row(ws, maxr=6):
    rows = [list(r) for r in ws.iter_rows(min_row=1, max_row=maxr, values_only=True)]
    i = max(range(len(rows)), key=lambda i: sum(1 for c in rows[i] if isinstance(c, str)))
    return i, [(str(c).replace("\n", " ").strip() if c is not None else None) for c in rows[i]]

for label, fname in FILES.items():
    raw = urllib.request.urlopen(f"{BASE}/{fname}", timeout=120).read()
    wb = openpyxl.load_workbook(io.BytesIO(raw), read_only=True, data_only=True)
    ms = next((s for s in ("Instruction and Performance", "Student Achievement") if s in wb.sheetnames),
              wb.sheetnames[1])
    ws = wb[ms]
    hi, hdr = header_row(ws)
    mv = [c for c in hdr if c and c.startswith("Metric Value")]
    cg = [c for c in hdr if c and c.startswith("Comparison Group")]
    mr = [c for c in hdr if c and c.startswith("Metric Rating")]
    print(f"\n{label}: sheets={wb.sheetnames}")
    print(f"  metric sheet='{ms}'  Metric Value cols={len(mv)}  "
          f"Comparison Group cols={len(cg)}  Metric Rating cols={len(mr)}")
    wb.close()

print("""
Finding: each metric X is published as a family — 'Metric Value - X' (the school),
'N Count - X', 'Comparison Group - X' (the peer pool's benchmark VALUE, not a
within-group percentile), and 'Metric Rating - X'. No peer-school roster is
published. Sheet names and metric sets change across years (2018-19 differs from
2023-24), so ingestion needs a per-year-format mapping.""")