#!/usr/bin/env python3 """Reproduce the published clearance arithmetic from its companion CSVs. Python 3.9+, standard library only. No network, external packages, or personal data. Run from any directory: python reproduce-headroom-v1.0.py Accepts CSVs beside this file or in its data/ subdirectory. This checks arithmetic and file consistency, not physical fit or source freshness. """ from __future__ import annotations import ast import csv import io import json import re import sys from collections import Counter from fractions import Fraction from pathlib import Path BASE = Path(__file__).resolve().parent DATA = BASE / 'data' if (BASE / 'data').is_dir() else BASE CHECKS = 0 def check(condition: bool, message: str) -> None: global CHECKS CHECKS += 1 if not condition: raise ValueError(message) def read(name: str) -> list[dict[str, str]]: with (DATA / name).open(encoding='utf-8-sig', newline='') as handle: result = list(csv.DictReader(handle)) check(all(None not in row for row in result), f'{name}: malformed CSV row') return result def number(value: str) -> Fraction: if value == '': raise ValueError('An empty value is unknown, not zero.') return Fraction(value) def close(actual: Fraction, expected: str, name: str) -> None: check(abs(float(actual) - float(expected)) < 1e-8, f'{name}: computed {actual}, file gives {expected}') def evaluate(expression: str) -> Fraction: """Evaluate only numeric +, -, *, / and parentheses; never use eval().""" if len(expression) > 200: raise ValueError('Arithmetic expression exceeds supported length') def visit(node: ast.AST) -> Fraction: if isinstance(node, ast.Expression): return visit(node.body) if isinstance(node, ast.Constant) and type(node.value) in (int, float): return Fraction(str(node.value)) if isinstance(node, ast.UnaryOp) and isinstance(node.op, (ast.UAdd, ast.USub)): return visit(node.operand) * (-1 if isinstance(node.op, ast.USub) else 1) if isinstance(node, ast.BinOp): a, b = visit(node.left), visit(node.right) if isinstance(node.op, ast.Add): return a + b if isinstance(node.op, ast.Sub): return a - b if isinstance(node.op, ast.Mult): return a * b if isinstance(node.op, ast.Div): return a / b raise ValueError(f'Unsupported arithmetic: {expression}') return visit(ast.parse(expression, mode='eval')) def offset(row: dict[str, str]) -> Fraction: """Use only an explicit height + constant formula, not a missing fragment.""" match = re.fullmatch(r'(?:door|opening) height \+ (\d+(?:\.\d+)?)', row['formula']) if not match: raise ValueError(f"{row['row_id']}: not an explicit height-plus-constant formula") return Fraction(match.group(1)) def scalar_or_offset(row: dict[str, str]) -> Fraction: return number(row['min_in']) if row['min_in'] else offset(row) def main() -> None: records = read('commercial-door-headroom-clearance-ledger-v1.0.csv') rows = {r['row_id']: r for r in records} spreads = read('headroom-spread-by-setup-v1.0.csv') pairs = read('front-vs-rear-low-headroom-v1.0.csv') calculations = read('calculations-v1.0.csv') calcs = {r['calc_id']: r for r in calculations} sources = read('source-register-v1.0.csv') supplements = read('supplemental-document-checks-v1.0.csv') claims = read('numbers-checked-v1.0.csv') check(len(records) == len(rows) == 181, 'Expected 181 unique source IDs') check(len(spreads) == 8 and len(pairs) == 13, 'Comparison row counts differ') check(len(calcs) == len(calculations) == 123, 'Calculation count or duplicate ID') check(len(supplements) == 11 and len(claims) == 6, 'Supplement/claim counts differ') source_ids = {s['source_id'] for s in sources} for r in records: check(r['source_id'] in source_ids, f"Unknown source: {r['row_id']}") check(bool(r['source_url']) and r['checked'] == '2026-09-29', f"Provenance: {r['row_id']}") if r['min_in'] and r['max_in']: check(number(r['min_in']) <= number(r['max_in']), f"Range order: {r['row_id']}") for c in calculations: check(bool(c['source_urls']), f"Missing primary evidence: {c['calc_id']}") for rid in c['input_rows'].split(';'): check(rid in rows, f"{c['calc_id']}: unknown input {rid}") # Reproduce all eight category spreads directly from the main ledger. spread_values = [] for index, group in enumerate(spreads, 1): relevant = [rows[rid] for rid in group['row_ids'].split(';')] vertical = group['metric'] != 'headroom_inches' points = [offset(r) if vertical else number(r['min_in']) for r in relevant if vertical or r['value_kind'] == 'fixed'] lo, hi = min(points), max(points) close(lo, group['lowest_in'], f'T3-{index} minimum') close(hi, group['highest_in'], f'T3-{index} maximum') close(hi - lo, group['spread_in'], f'T3-{index} spread') close(hi-lo, calcs[f'T3-{index:02}']['result_numeric'], f'T3-{index} calculation') if not vertical: check(group['ratio'] == f'{float(hi/lo):.2f}', f'T3-{index} rounded ratio') close(hi/lo, calcs[f'T3-{index:02}-RATIO']['result_numeric'], f'T3-{index} ratio') else: check(group['ratio'] == '', 'Vertical additions must not imply headroom ratio') spread_values.append(hi-lo) check(min(spread_values) == Fraction(3,2), 'Smallest selected spread') check(sum(v >= 3 for v in spread_values) == 6, 'Six of eight >=3 inches') headline = [number(rows[rid]['min_in']) for rid in ['GAR-05','AMR-07','OHD-13','HOL-06','IDL-06']] check(min(headline) == 4 and max(headline) == 8 and max(headline)/min(headline) == 2, 'Headline 4–8, 2:1') # All 13 front/rear comparisons, including overlapping OHD height scopes. differences, depth_pairs = [], 0 for i, pair in enumerate(pairs, 1): front, rear = rows[pair['front_row']], rows[pair['rear_row']] a, b = number(front['min_in']), number(rear['min_in']) close(a, pair['front_headroom_in'], f'Pair {i} front') close(b, pair['rear_headroom_in'], f'Pair {i} rear') close(a-b, pair['headroom_saved_in'], f'Pair {i} change') close(a-b, calcs[f'T5-{i:02}']['result_numeric'], f'Pair {i} calculation') differences.append(a-b) if pair['backroom_source_rows']: first, second = [rows[rid] for rid in pair['backroom_source_rows'].split(';')] delta = offset(second)-offset(first) close(delta, pair['extra_backroom_in'], f'Pair {i} depth') close(delta, calcs[f'T5-{i:02}-DEPTH']['result_numeric'], f'Pair {i} depth calculation') depth_pairs += 1 check(len(differences) == 13 and min(differences) == 2 and max(differences) == Fraction(37,4), 'Front/rear extent') check(depth_pairs == 4, 'Exactly four source-backed depth comparisons') check(any(p['front_row']=='OHD-11' and p['rear_row']=='OHD-15' for p in pairs), 'Missing added OHD pair') # Sister-brand headroom differences and all matching side/backroom entries. sister_differences = [] for i in range(1,12): delta = scalar_or_offset(rows[f'IDL-{i:02}'])-scalar_or_offset(rows[f'HOL-{i:02}']) close(delta, calcs[f'T4-{i:02}']['result_numeric'], f'Sister comparison {i}') sister_differences.append(delta) check(sum(d != 0 for d in sister_differences) == 8, 'Eight of eleven headroom entries differ') for i in range(12,34): a,b=rows[f'HOL-{i:02}'],rows[f'IDL-{i:02}'] check((a['min_in'],a['max_in'],a['formula']) == (b['min_in'],b['max_in'],b['formula']), f'Side/back equality {i}') check(calcs[f'HMATCH-{i:02}']['result_numeric']=='1', f'Side/back match flag {i}') # Table 8's 24 cells and Table 10's eight values are computed from source formulas. table8_count = 0 for c in calculations: cid=c['calc_id']; ids=c['input_rows'].split(';') if cid.startswith('T8-'): _,hi,col=cid.split('-'); height=[120,144,168,192][int(hi)-1] vals=[Fraction(height)+offset(rows[rid]) for rid in ids] check(len(set(vals))==1, cid+' source formulas disagree') close(vals[0], c['result_numeric'], cid) close(evaluate(c['formula']), c['result_numeric'], cid+' printed expression') table8_count+=1 elif cid.startswith('T10-'): vals=[Fraction(120)+offset(rows[rid]) for rid in ids] check(len(set(vals))==1, cid+' source formulas disagree') value=vals[0]+(120 if cid.endswith('TOTAL') else 0) close(value,c['result_numeric'],cid) close(evaluate(c['formula']),c['result_numeric'],cid+' printed expression') check(table8_count==24,'24 backroom example cells') for cid in ['RADIUS','FAQ-96-LOW','FAQ-96-HIGH','FAQ-120-LOW','FAQ-120-HIGH','WEIGHT-DIFFERENCE','WD12-MANUAL','WD12-MOTOR']: c=calcs[cid];close(evaluate(c['formula']),c['result_numeric'],cid) check(offset(rows['WD-22'])-offset(rows['WD-21'])==48,'WD +48-inch depth') check(number(rows['OHD-04']['min_in'])-number(rows['OHD-03']['min_in'])==Fraction(7,2),'OHD 3.5-inch change') check(number(rows['OHD-02']['min_in'])-number(rows['OHD-01']['min_in'])==Fraction(3,2),'OHD 1.5-inch change') check(number(rows['IDL-02']['min_in'])-number(rows['IDL-01']['min_in'])==3,'IDEAL radius headroom difference') check(number(rows['COR-01']['min_in'])-4==Fraction(13,2),'Selected-guide comparison') check(number(rows['GARA-01']['min_in'])-number(rows['GAR-04']['min_in'])==1,'Garaga one-inch source difference') check(Fraction(rows['HOL-37']['weight_limit_lb'])-Fraction(rows['HOL-38']['weight_limit_lb'])==400,'Printed weight-limit difference') # Unknowns and conditional values must remain non-executable. for rid in ['WD-25','GARA-03','AMR-11','AMR-12']: check(rows[rid]['formula']=='' and rows[rid]['min_in']=='' and rows[rid]['max_in']=='',rid+' unresolved value was normalized') for rid in ['HOL-39','IDL-39']: check(rows[rid]['min_in']=='' and rows[rid]['max_in']=='4',rid+' invented lower bound') check(rows[rid]['value_kind']=='possible_allowance_up_to',rid+' allowance type') check(rows['COR-14']['value_kind']=='as_little_as' and rows['COR-14']['max_in']=='','Visionaire qualifier') check(rows['OHD-20']['min_in']=='' and rows['OHD-20']['max_in']=='','Unknown drawbar allowance') check(all('opening height' not in r['size_scope'] for r in records if r['source_id']=='OHD'),'OHD bands must use door height') check(all(rows[rid]['source_locator'].startswith('PDF p. 1') for rid in ['OHD-20','OHD-21']),'OHD operator footnote page') check(all('7–20' in rows['AMR-14']['size_scope'] for _ in [0]),'Amarr vertical size scope') check('No complete cross-brand' in calcs['K12']['result'],'Unsupported total powered range') # The main Markdown is optional when users download only the data and script. page=BASE/'commercial-garage-door-headroom-chart.md' if page.exists(): text=page.read_text(encoding='utf-8') for name,embedded in re.findall(r'```DATASET\nFILE: ([^\n ]+)[^\n]*\n(.*?)\n```',text,re.S): actual=list(csv.DictReader(io.StringIO(embedded))) check(actual==read(name),f'Embedded dataset differs: {name}') public=re.sub(r'^---\n.*?\n---\n','',text,count=1,flags=re.S) public=re.sub(r'```(?:BUILD SPEC|CHART SPEC|DATASET)\n.*?\n```','',public,flags=re.S) anchors=re.findall(r'id="([^"]+)"',public) check(len(anchors)==len(set(anchors)),'Duplicate public anchor') for rid in rows:check('row-'+rid in anchors,f'Missing source-row anchor {rid}') for frag in re.findall(r'\]\(#([^)]*)\)',public):check(frag in anchors,f'Broken local anchor #{frag}') for asset in set(re.findall(r'/research/downloads/([^\s)\]\"<>]+)',public)): check(any((folder/asset).is_file() for folder in [BASE,DATA,BASE/'charts']),f'Missing asset {asset}') print(json.dumps({'status':'passed','checks':CHECKS,'source_records':181, 'front_rear_comparisons':13,'category_comparisons':8,'calculation_records':123, 'backroom_example_cells':24,'headline_inches':[4,8],'headline_ratio':2, 'depth_comparisons_with_seven_extra_inches':4, 'limits':'Arithmetic and local-file consistency only; not installation approval, a deployed lookup test, or a fresh web check.'},indent=2)) if __name__=='__main__': try: main() except (OSError, ValueError, KeyError, ZeroDivisionError, SyntaxError) as exc: print(f'VALIDATION FAILED: {exc}',file=sys.stderr) sys.exit(1)