Convención: formato de salida en scripts de comprobación

Fecha: 2026-08-04 Archivo: helpers_output.py

Qué resuelve

Estandariza cómo los scripts de validación muestran resultados en terminal, para que sean legibles de forma consistente sin que cada script reinvente su propio formato de tabla.

Decisión

rich.Console() sin ancho fijo (auto-detecta el ancho real de la terminal del usuario — confirmado 138 columnas en surface-ehas).

Se probaron 4 variantes en la misma sesión:

  • Console(width=160) fijo — descartado: con tablas de 8+ columnas rompe en bloques verticales ilegibles si el ancho fijo no coincide con la terminal real.
  • Console() sin width — elegido: se adapta al ancho real, tablas anchas se leen en una sola pasada horizontal.
  • pandas.to_string() plano sin rich — descartado, sin ventaja clara sobre la opción elegida.
  • Vista vertical (1 fila = 1 bloque campo/valor) — útil para drill-downs de un solo folio, no para tablas de muchas filas/comparaciones.

Uso

from helpers_output import console, mostrar_tabla, resumen
 
resumen(folios=1425, cuadran=1425, pct="100.0%")
mostrar_tabla(df, titulo="Resumen por ORIGEN")

mostrar_tabla() trunca a 30 filas por default (max_filas=) y avisa si el dataframe tiene más, para no saturar la salida con tablas de cientos de filas.

Salida hacia Claude (aparte de esta convención de terminal)

Para pegar resultados en la conversación con Claude, preferir CSV plano (df.to_csv(index=False)) sobre las tablas rich con bordes — más compacto en tokens, sin ambigüedad de columnas truncadas. Las tablas rich de este helper son para legibilidad humana en pantalla; el CSV es lo que se pega al LLM cuando se necesita que procese el resultado.

Pendiente

Retrofit de scripts existentes (v3_cxp_completo, v5_impuestos_layout, etc.) para usar este helper en vez de su Console()/Table() propio — no urgente, aplicar de aquí en adelante a scripts nuevos primero.

Actualización 2026-08-05: separación de stream para pipe a Claude

Problema: python3 script.py | cb capturaba TODO stdout, mezclando las tablas rich (humanas) con los bloques CSV destinados a pegar en la conversación con Claude — obligaba a copiar manualmente solo la parte CSV. Decisión: las tablas rich (humanas) van a stderr; los bloques CSV_PARA_CLAUDE van a stdout (print() normal). Ambos streams se ven igual en pantalla (comparten la tty), pero | cb solo engancha stdout — así python3 script.py | cb deja en el clipboard solo los CSV, sin tocar el script ni acordarse de flags.

Uso

from helpers_output import console_err, mostrar_tabla_err, resumen_err
 
mostrar_tabla_err(df, titulo="Resumen por ORIGEN")   # rich -> stderr, humano
resumen_err(folios=1425, cuadran=1425, pct="100.0%") # rich -> stderr, humano
 
print("--- CSV_PARA_CLAUDE: nombre_bloque ---")
print(df.to_csv(index=False))                        # -> stdout, para Claude

Regla: cualquier script nuevo de validación usa console_err/ mostrar_tabla_err/resumen_err para la parte de pantalla, y bloques print("--- CSV_PARA_CLAUDE: <nombre> ---") + print(df.to_csv(index=False)) para lo que se necesite pegar a Claude. El helper original (console, mostrar_tabla, resumen, stdout puro) queda para scripts que se corren sin intención de pipe (ej. exploración interactiva rápida sin | cb).