Files
fn_registry/python/functions/datascience/render_automatic_eda_pptx.md
T
egutierrez 9cdde4a341 feat(eda): núcleo AutomaticEDA — documento por capítulos + renderers PDF/PPTX anti-corte
Introduce la capa intermedia entre el contenido de un EDA y su formato de
salida. Un documento es una lista de capítulos versionados; cada capítulo es
un conjunto ordenado de bloques (heading, markdown, kv_table, data_table,
figure, image, caption, note) independientes del formato.

Núcleo (paquete de soporte python/functions/datascience/automatic_eda/):
- model.py: dataclasses de bloques + Chapter, normalizadores defensivos
  (aceptan dataclass o dict, nunca lanzan), ENGINE_VERSION y el manifiesto
  por capítulo (automatic_eda_manifest.json).
- text_layout.py: medición/wrapping por rejilla de caracteres compartida.
- chapters_registry.py: CHAPTER_ORDER pre-declarado + build_document con
  auto-discovery de capítulos por convención (permite añadir capítulos en
  paralelo sin editar el registro).
- render_pdf_impl.py: paginador A5 retrato móvil que MIDE cada bloque y nunca
  corta: texto a líneas completas, tablas largas partidas por filas repitiendo
  cabecera, figuras/imágenes escaladas para caber enteras. Pie versionado por
  capítulo.
- render_pptx_impl.py: mismo principio sobre slides 16:9 (continúa en slide
  "(cont.)"; tablas repiten cabecera; figuras exportadas a PNG escaladas).
- chapters/portada.py y chapters/overview.py: capítulos de referencia. Portada
  con nombre, rótulo Automatic-EDA, fuente, almacenamiento (inferido de
  source), fecha europea, filas×cols, descripción, granularidad y calidad con
  criterios. Overview con df.head (placeholder honesto si falta head_rows),
  diccionario de columnas (tipo/nulos/ejemplos) y describe numérico.

Funciones públicas del registry (grupo eda, dict-no-throw):
- render_automatic_eda_pdf / render_automatic_eda_pptx: aceptan capítulos o un
  TableProfile (construyen los capítulos con build_document) y escriben el
  manifiesto. Aditivas — no reemplazan render_eda_pdf.

Tests self-contained (sin DuckDB) para ambos renderers: golden (portada +
overview), partición de tablas largas repitiendo cabecera, no-corte de celdas
y markdown largos, profile None/{} válido de 1 página/slide, y error path en
directorio no escribible. 23 tests verdes (incluye los previos de
render_eda_pdf, intactos).

Dependencia nueva python-pptx>=1.0.2 declarada en python/pyproject.toml.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 14:30:31 +02:00

5.8 KiB

name, kind, lang, domain, version, purity, signature, description, tags, uses_functions, uses_types, returns, returns_optional, error_type, imports, params, output, tested, tests, test_file_path, file_path
name kind lang domain version purity signature description tags uses_functions uses_types returns returns_optional error_type imports params output tested tests test_file_path file_path
render_automatic_eda_pptx function py datascience 1.0.0 impure def render_automatic_eda_pptx(chapters_or_profile, out_path: str, meta: dict = None) -> dict Renderiza un documento AutomaticEDA por CAPÍTULOS (modelo de bloques independiente del formato) en una presentación PPTX 16:9 pensada para COMPARTIR. Acepta una lista de capítulos del modelo o directamente un TableProfile del grupo eda (construye los capítulos canónicos con build_document). Mismo principio anti-corte que el renderer PDF: cada bloque se mide y, si no cabe en la slide, continúa en una slide '<Capítulo> (cont.)'; las tablas largas se parten por filas REPITIENDO la cabecera; las figuras matplotlib se exportan a PNG e insertan escaladas para caber enteras. Cada slide lleva pie 'Capítulo · vX.Y.Z' y se escribe automatic_eda_manifest.json junto a la salida. dict-no-throw: nunca lanza, devuelve {path, n_slides, chapters, manifest_path, note}. Motor python-pptx (dependencia declarada en python/pyproject.toml).
eda
pptx
render
report
share
automatic-eda
chapters
versioned
no-cut
slides
python-pptx
datascience
python
false error_go_core
os
python-pptx
datascience.automatic_eda
name desc
chapters_or_profile una lista de capítulos del modelo AutomaticEDA (dataclasses Chapter o dicts {id,title,version,blocks}) O un TableProfile dict del grupo eda. Si es un TableProfile, los capítulos canónicos se construyen con build_document(profile, meta['ctx']). Bloques soportados: heading, markdown, kv_table, data_table, figure, image, caption, note. Lectura defensiva: lo no reconocido se degrada a Note, nunca lanza.
name desc
out_path ruta del archivo PPTX de salida. Los directorios padre se crean si faltan. Directorio no escribible → {path:None, note:<causa>} sin lanzar.
name desc
meta dict opcional. Claves: title (título), ctx (contexto de presentación para los builders de capítulo cuando se da un profile), manifest_path (override; por defecto automatic_eda_manifest.json junto a out_path), write_manifest (False para no escribirlo), generated_at.
dict (nunca lanza): {path: str|None, n_slides: int, chapters: list[{id,version,n_slides}], manifest_path: str|None, note: str}. En error fatal (incluida python-pptx no instalada) path es None y note explica la causa. true
test_golden_profile_genera_pptx_portada_y_overview
test_edge_tabla_larga_parte_repitiendo_cabecera_sin_cortar
test_edge_profile_none_y_vacio_un_slide
test_error_path_directorio_no_escribible_no_revienta
python/functions/datascience/render_automatic_eda_pptx_test.py python/functions/datascience/render_automatic_eda_pptx.py

Ejemplo

from datascience import render_automatic_eda_pptx

# Desde un TableProfile del grupo eda (mismo modelo que el renderer PDF).
profile = {
    "table": "ventas", "source": "/data/ventas.csv",
    "n_rows": 1000, "n_cols": 2, "quality_score": 92.5,
    "columns": [
        {"name": "precio", "inferred_type": "numeric", "null_pct": 0.01,
         "numeric": {"mean": 42.5, "median": 40.0, "min": 1.0, "max": 100.0,
                     "std": 12.3}},
        {"name": "categoria", "inferred_type": "categorical", "null_pct": 0.0,
         "categorical": {"top": [{"value": "neumaticos", "count": 500}]}},
    ],
}
res = render_automatic_eda_pptx(
    profile, "reports/ventas_aeda.pptx",
    {"title": "EDA — ventas",
     "ctx": {"dataset_name": "Ventas", "source_origin": "ERP export"}})
print(res["n_slides"], res["chapters"], res["manifest_path"])
# -> 3 [{'id':'portada','version':'1.0.0','n_slides':1},
#       {'id':'overview','version':'1.0.0','n_slides':2}] reports/automatic_eda_manifest.json

Cuando usarla

Cuando quieras compartir el EDA como una presentación (no para móvil sino para enseñar a alguien): mismo documento por capítulos que el PDF, emitido como PPTX 16:9. Úsala junto a render_automatic_eda_pdf para que cada EDA tenga sus dos salidas (PDF móvil + PPTX para compartir) desde el mismo modelo de capítulos. Garantiza no-corte: ningún texto, tabla ni imagen se recorta — lo que no cabe en una slide continúa en otra (cont.) con la cabecera repetida en las tablas. Para añadir capítulos nuevos al documento, ver docs/capabilities/automatic_eda.md.

Gotchas

  • Impura: escribe el PPTX en out_path y, salvo meta['write_manifest']=False, el manifiesto automatic_eda_manifest.json junto a la salida.
  • Dependencia python-pptx: declarada en python/pyproject.toml (python-pptx>=1.0.2). Si no está instalada, devuelve {path: None, note: 'python-pptx no disponible: ...'} sin lanzar. Instalar: uv pip install --python python/.venv/bin/python3 python-pptx.
  • Nunca lanza (dict-no-throw): un bloque que falle se omite y se anota en note; el deck se genera igual. Un profile None/{} produce un deck de 1 slide válido.
  • No corta nada: cada bloque se mide; si no cabe en la slide actual, abre una slide (cont.). Las tablas largas se parten por filas repitiendo la cabecera (las filas restantes pasan a la siguiente slide). Las figuras matplotlib se exportan a PNG en memoria y se insertan escaladas para caber enteras (nunca recortadas).
  • Figuras: un bloque figure puede traer una matplotlib.figure.Figure ya construida o un callable make (se construye perezosamente). Se cierra tras rasterizar. Las imágenes (image) por ruta se escalan manteniendo el aspecto.
  • Tablas anchas: con muchas columnas el ancho por columna se reduce y el texto se envuelve dentro de la celda (sigue sin perderse). El reparto por grupos de columnas para tablas muy anchas es mejora pendiente.