algo/applications/collatz/collatz_k_scripts/collatz_document_base_states.py
Nicolas Cantu 14ed1de36b Pipeline Collatz aligné sur commandes.md et reprise après interruption
**Motivations:**
- Implémenter le workflow complet de démonstration Collatz (commandes.md)
- Permettre la reprise après interruption au palier D20

**Evolutions:**
- Scripts 01-12 et run-full-workflow alignés sur commandes.md sections 1-10
- collatz_recover_noyau.py : recréation de noyau_post_D20 à partir du CSV candidats
- Option --resume-from D20 dans collatz_k_pipeline pour reprendre sans recalculer D18-D19-F15
- Détection automatique : si candidats_D20 existe sans noyau_post_D20, récupération puis poursuite
- Filtres --cible=critique et --modulo dans collatz_fusion_pipeline
- ROOT par défaut = collatz_k_scripts (plus data/source vide)

**Pages affectées:**
- .gitignore (__pycache__, out/)
- applications/collatz/collatz_k_scripts/*.py
- applications/collatz/scripts/*.sh
- applications/collatz/scripts/README.md
2026-03-02 02:49:23 +01:00

81 lines
2.3 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
collatz_document_base_states.py
If JSON has state info (e.g. per-palier state), document each state.
Outputs MD describing each state.
Usage: python collatz_document_base_states.py --base-projective JSON --output MD
"""
from __future__ import annotations
import argparse
import json
from pathlib import Path
from typing import Any
def load_json(path: str) -> dict[str, Any]:
"""Load JSON file."""
p = Path(path)
if not p.exists():
raise FileNotFoundError(f"File not found: {path}")
return json.loads(p.read_text(encoding="utf-8"))
def is_state_info(obj: Any) -> bool:
"""Check if object looks like a state (has m, mod, etc.)."""
if not isinstance(obj, dict):
return False
return "m" in obj or "mod" in obj
def document_states(data: dict[str, Any]) -> list[str]:
"""Extract and document each state from JSON."""
lines: list[str] = ["# Base states documentation", ""]
for key, val in sorted(data.items()):
if not is_state_info(val):
continue
val = val if isinstance(val, dict) else {}
lines.append(f"## State {key}")
lines.append("")
for k, v in sorted(val.items()):
if isinstance(v, list) and len(v) > 10:
lines.append(f"- **{k}**: {len(v)} items")
else:
lines.append(f"- **{k}**: {v}")
lines.append("")
if len(lines) <= 2:
lines.append("No state information found in JSON.")
return lines
def run(base_path: str, output_path: str) -> None:
"""Run and write output."""
try:
data = load_json(base_path)
lines = document_states(data)
except FileNotFoundError as e:
lines = ["# Base states documentation", "", str(e)]
except json.JSONDecodeError as e:
lines = ["# Base states documentation", "", f"Invalid JSON: {e}"]
Path(output_path).write_text("\n".join(lines) + "\n", encoding="utf-8")
def main() -> None:
parser = argparse.ArgumentParser(description="Document base states from JSON")
parser.add_argument("--base-projective", required=True, help="Path to base-projective JSON")
parser.add_argument("--output", required=True, help="Path to output MD file")
args = parser.parse_args()
run(args.base_projective, args.output)
if __name__ == "__main__":
main()