Communitygithub.com

ascci-charts

Genera gráficos de barras, rango, viñetas, histogramas de estrellas, mapas de calor, líneas, diagramas de Venn, circulares, donas y de dispersión como texto sin formato usando caracteres Unicode, sin dependencias externas. Ideal para boletines, Markdown, terminales, correo electrónico y chat.

¿Qué es ascci-charts?

El skill `ascii-charts` permite a agentes de IA y desarrolladores incrustar gráficos directamente como texto literal en cualquier lugar donde se renderice texto monoespaciado: bloques de código en Markdown, etiquetas `<pre>` en HTML, terminales, correo electrónico sin formato y aplicaciones de chat. No requiere servicios externos, imágenes ni cuentas; cada tipo de gráfico tiene una función dedicada en el script `scripts/ascii_chart.py`. Soporta una amplia variedad de gráficos: barras, rango, viñetas (bullet), paréntesis de brecha (gap-bracket), histograma de estrellas, mapa de calor, línea, chispa (sparkline), Venn, circular (pie), dona (donut) y dispersión. El script utiliza únicamente caracteres Unicode de bloque y de dibujo de cajas, sin color, asegurando que los gráficos se rendericen de manera idéntica en cualquier plataforma. Incluye una corrección de aspecto para círculos (2.49 en lugar de 2.0) y un límite de 44 caracteres de ancho para visibilidad en dispositivos móviles. Prioriza la claridad sobre la precisión técnica: aplica la "prueba de 2 segundos" para garantizar que un lector casual entienda el gráfico sin necesidad de leyenda. Está diseñado para usarse en plataformas como Claude Code, Cursor y Codex, donde la salida debe ser puro texto sin dependencias.

Compatible con~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/2016judea/brick-mortar-skills/tree/HEAD/skills/ascii-charts

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

Gráficos ASCII

Gráficos con estilo de terminal construidos a partir de caracteres Unicode de bloque simples e incrustados como texto literal: un bloque de código en Markdown, una etiqueta <pre> en HTML. Sin servicio de gráficos, sin pie de página "made with", sin cuenta externa, y se renderizan de forma idéntica dondequiera que se renderice texto monoespaciado.

scripts/ascii_chart.py tiene una función por tipo de gráfico. Ejecuta python3 scripts/ascii_chart.py para imprimir un ejemplo de cada tipo como verificación de cordura.

Dos cosas aquí se midieron en lugar de asumirse, y ambas estaban equivocadas al principio: en una ventana de 390px de teléfono, las filas de más de ~44 caracteres se cortan en el borde derecho, y un círculo "redondo" en monoespaciado necesita una corrección de aspecto horizontal de aproximadamente 2.49 (no 2.0). Consulta Dimensionamiento y la sección de Circular/ Dona.

Las plataformas de boletines difieren en cómo pegan bloques de código. Antes de confiar en una, pega un gráfico de prueba en un borrador real y verifica las representaciones en web, aplicación y correo electrónico.

Conjunto de caracteres

  • █ ▓ ▒ ░ (U+2588, U+2593, U+2592, U+2591 — sombra completa/oscura/media/clara) ) — densidad de relleno, de "más" a "menos". Las barras usan solo █/░ (relleno vs. pista); circular/dona usan los cuatro (más ▚/▞/▤/▥ si hay más de 4 porciones) como rellenos distintos por porción; el mapa de calor usa los cuatro más · (punto medio, no un espacio en blanco) para el nivel más bajo, de modo que una celda "tranquila" aún se lea como parte intencional de la cuadrícula, no como un hueco.
  • dígitos 1–7 — códigos de región de Venn (una máscara de bits de qué conjunto(s) pertenece una región — ver Venn abajo)
  • + — indicador abierto en una barra de rango que podría ejecutarse más alto que el techo mostrado (no estires la barra para fingir un número que no tienes)
  • ┃ — marca de objetivo de gráfico de viñetas, dibujada sobre el relleno/sombreado que sea debajo para que siempre sea visible
  • └─┘ — paréntesis de brecha, que se extiende entre dos extremos de barras
  • ★/☆ — estrella llena/vacía, que también sirve como etiqueta de fila del histograma de estrellas
  • dibujo de cajas (─│╭╮╰╯) — conectores de gráficos de línea y líneas de tendencia
  • ● — marcador de punto de dispersión

Sin color, en ninguna parte. Ese es el medio, no una limitación a superar: un bloque de código pegado de Substack son caracteres literales, nada más sobrevive (sin CSS en línea, sin tramos con estilo). Cualquier distinción que un gráfico necesite hacer reside en el carácter/dígito/leyenda, no en un canal de color no disponible.

Menú de tipos de gráficos

TrabajoFunciónUsar para
Comparación de magnitudes, varias categorías, todas comienzan en 0bar(valor, max_valor, ancho) + render()Llenado de gasolina (5 min) vs. carga rápida DC (45 min)
Un rango mínimo-máximo, una categoríarange_bar(inicio, fin, max_escala, ancho, abierto=) + render()"$100k–$300k+ instalado"
Dos valores, antes/despuésTexto plano: f"{inicio} → {fin}""Por mayor $220 → barra $650" — una barra no agrega nada; la flecha es el gráfico
Una medida vs. una banda de referencia + un objetivobullet(valor, max_escala, objetivo=, referencia=) + render()"Tu calificación: 4.2, banda normal 3.8–4.5, objetivo 4.7"
Llamar explícitamente a la brecha entre dos barrasgap_bracket(a, b, max_escala, ancho, etiqueta=) a través de render(paréntesis=)"Tú vs. mediana del mercado" — el movimiento característico del informe
Una distribución de calificación 1–5 (o similar)star_histogram(conteos)Desglose de estrellas de Google/Yelp, una fila por conteo de estrellas
Dos ejes categóricos, sombreados por intensidadheatmap(matriz, etiquetas_filas, marcas_columnas=)Tráfico peatonal por día × hora — "cuándo estás ocupado/muerto"
Tendencia a lo largo del tiempo, una serieline_chart(valores, altura, etiquetas_x=)Ingresos mensuales, conteo de reseñas durante un año
Tendencia, en línea dentro de una oraciónsparkline(valores)"Reseñas por mes: ▂▃▅▆█▇▅▃, hasta 3x desde marzo"
2 o 3 conjuntos con nombre, donde el grado de superposición es en sí mismo el hallazgovenn(etiquetas)"El 38% de tus reseñas de una estrella también mencionan el tiempo de espera" — el tamaño de la superposición es el punto
Partes de un todo, una instantáneapie(porciones, radio)Mezcla de ingresos: café / comida caliente / bebidas / lotería
Partes de un todo, con un total destacadodonut(porciones, radio, texto_centro=)Igual, con "247 reseñas" sentado en el centro hueco
Dos variables numéricas, ¿hay una relación?scatter(puntos, ancho, altura)Precio vs. calificación entre competidores
Igual, más "y aquí está la tendencia"scatter_with_trend(puntos, ancho, altura)Igual, con una línea ajustada que prueba la correlación

Si nada en esta tabla encaja, detente y piensa en lugar de forzar una forma que no encaja: un gráfico que es técnicamente renderizable pero confuso es peor que recurrir a la canalización PNG de Chrome sin cabeza.

La prueba de 2 segundos para gráficos

Un gráfico responde al mismo estándar que una buena oración: ser entendido por un lector cansado en su teléfono, a primera vista, sin releer, sin decodificar. Aplica la prueba antes de elegir un tipo de gráfico, no después de construir uno.

La prueba de 2 segundos: ¿podría el lector previsto — un propietario de pequeña empresa, no un analista de datos — decir qué significa este gráfico en 2 segundos, sin leer una leyenda primero? Si entender incluso una región o porción requiere decodificar una leyenda primero, eso es el equivalente visual de jerga: técnicamente preciso, pero obliga al lector a trabajar en lugar de atraerlo.

Atrapado en un problema real, por el editor leyendo la publicación renderizada en frío:

  • El diagrama de máscara de bits de dígitos de 3 conjuntos de Venn requería leer una leyenda de 7 líneas antes de que cualquier región significara algo. El editor: no lo entendieron, por lo que un propietario de negocio regular tampoco lo haría. El hecho subyacente — "necesitas los tres, no solo uno" — es una oración, y la lista numerada justo después del diagrama ya lo decía en inglés sencillo. El diagrama agregó costo de decodificación sin agregar información que la prosa ya no llevara más claramente. Arreglo: elimínalo, deja que la oración + lista hagan el trabajo.
  • La barra de rango de costos del cargador rápido DC (una sola barra, sin eje, sin punto de comparación) no tenía nada con qué compararse. El valor de una barra proviene de mostrar una magnitud relativa a algo — una escala, otra barra, un punto de referencia. Una barra solitaria sin punto de referencia es decorativa, no informativa. El número que ilustraba ($100k–$300k+) ya estaba establecido claramente una oración antes. Arreglo: elimínalo también.

Reglas que siguen:

  • Un gráfico que necesita su propia leyenda para ser leído es una señal de advertencia — no solo para Venn. Un mapa de calor con ejes sin etiquetar, o un circular con más porciones de las que un lector puede retener en su cabeza, falla de la misma manera.
  • Si una oración simple expresa el hecho tan claramente como lo haría el gráfico, omite el gráfico. Mismo instinto que intercambiar "varios/muchos/varios" por el conteo real en prosa: recurre a lo visual porque una comparación o tendencia es el punto, no solo porque los datos tienen una forma.
  • Cada barra necesita un eje (render(..., eje=)) o una segunda barra en la misma escala para comparar. Una sola barra sin ninguno de los dos no transmite nada — la misma falla que una oración en voz pasiva sin sujeto real. Pero una vez que eso está satisfecho, elimina el eje si solo repetiría un número que ya está en una etiqueta de valor por fila — una barra de gas-vs-carga eliminó su línea de eje 0 ... 45 min por exactamente esta razón: ambas filas ya llevan su propio valor ("5 min", "45 min"), por lo que el eje solo repetía "45 min" una segunda vez. Mismo principio que cortar una cláusula redundante de una oración.
  • No grafiques un número que ya es una oración clara. "$100k–$300k+ instalado" es máximamente claro como texto; graficarlo no revela una comparación, tendencia o superposición, solo agrega un paso de decodificación sin recompensa.
  • Lee el gráfico terminado en frío, como lo hará el lector real — un propietario de estación de gasolina en su teléfono, no la persona que acaba de construirlo y ya sabe lo que se supone que debe decir.

Flujo de trabajo

Usa scripts/ascii_chart.py en lugar de alinear caracteres manualmente o rasterizar geometría tú mismo — las matemáticas de columnas y círculos/ángulos son exactamente el tipo de cosa que es fácil de hacer sutilmente mal a ojo y solo aparece como una desalineación de un carácter o un círculo torcido después del hecho. Ejecuta python3 scripts/ascii_chart.py en cualquier momento para imprimir un ejemplo de cada tipo de gráfico como verificación de cordura.

Barra / barra de rango

from ascii_chart import bar, range_bar, render

filas = [
    ("Llenado de gasolina", bar(5, 45, 24), "5 min"),
    ("Carga rápida DC", bar(45, 45, 24), "45 min"),
]
print(render(filas, eje=("0", "45 min")))

fila = ("Cargador rápido DC", range_bar(100, 300, 300, 24, abierto=True), "$100k–$300k+")
print(render([fila]))

render() toma tuplas (etiqueta, cadena_barra, cadena_valor) y maneja toda la alineación de columnas — pasa tu propio cadena_valor preformateado (moneda, unidades, lo que necesite la copia); la función solo maneja geometría.

Gráfico de viñetas

from ascii_chart import bullet, render

filas = [("Calificación promedio", bullet(4.2, 5.0, objetivo=4.7, referencia=(3.8, 4.5), ancho=24), "4.2 (objetivo 4.7)")]
print(render(filas, eje=("0", "5.0")))

Una barra sólida para el valor medido, dibujada sobre una banda de referencia sombreada opcional (el rango "normal", ▒) con una marca objetivo opcional (┃, siempre dibujada al final para que permanezca visible sobre cualquier relleno/sombreado debajo ). Responde "¿estoy dentro de lo normal y qué tan lejos del objetivo?" de un vistazo — todavía hay solo una barra real (la medida); la banda es contexto.

Paréntesis de brecha

from ascii_chart import bar, gap_bracket, render

filas = [("Tú", bar(42000, 60000, 24), "$42,000"), ("Mediana del mercado", bar(58000, 60000, 24), "$58,000")]
print(render(filas, paréntesis=gap_bracket(42000, 58000, 60000, 24)))

Un paréntesis └─┘ que se extiende entre dos extremos de barras, con el tamaño de la brecha centrado dentro de él (autoformateado a partir de los dos valores, o pasa etiqueta= para tu propio texto). Usa el mismo max_escala/ancho para las barras y el paréntesis, o el tramo no se alineará. Esto es "tú vs. el mercado," hecho explícito en lugar de dejar que el lector lo calcule a ojo.

Histograma de estrellas

from ascii_chart import star_histogram

print(star_histogram([(5, 61), (4, 22), (3, 9), (2, 4), (1, 4)]))

conteos es [(estrellas, conteo), ...] en el orden que quieras que se imprima (generalmente 5 a 1). Los glifos de estrella llena/vacía (★/☆) también sirven como etiqueta de fila — no es necesario deletrear también "5 estrellas" en texto. Construido completamente en bar() + render().

Mapa de calor

from ascii_chart import heatmap

print(heatmap(matriz, ["Lun", "Mar", "Mié", "Jue", "Vie", "Sáb", "Dom"],
              marcas_columnas=[(0, "12am"), (6, "6am"), (12, "12pm"), (18, "6pm")]))

matriz es filas × columnas de intensidad numérica (por ejemplo, 7 días × 24 horas), normalizado a través de la matriz completa (no por fila) para que el sombreado sea comparable entre filas. marcas_columnas es [(índice_columna, etiqueta), ...] — sin autoespaciado, elige posiciones que no choquen para las etiquetas que pases.

Gráfico de línea / chispa

from ascii_chart import line_chart, sparkline

print(line_chart([120, 135, 128, 150, 175, 190, 205, 198, 220],
                  altura=10, etiquetas_x=("Ene", "Sep")))

print(sparkline([3, 5, 4, 8, 12, 10, 15, 14, 18]))

line_chart dibuja una línea conectada con esquinas de dibujo de cajas (╭╮╰╯│─) — no hay carácter para una pendiente intermedia arbitraria, por lo que el ancho es fijo en len(valores) - 1 columnas (una por segmento). etiquetas_x, si se proporciona, es solo (primero, último) impreso en la fila del eje — di los puntos intermedios en la prosa circundante, no intentes etiquetar cada marca. sparkline es una tendencia de una fila de 8 niveles (▁▂▃▄▅▆▇█) para una cláusula dentro de una oración, no un gráfico independiente.

Venn (2 o 3 conjuntos)

from ascii_chart import venn

diagrama, leyenda = venn(["Salida de autopista", "Tienda grande", "Capacidad de red"])
print(diagrama)
print(leyenda)

Rasteriza círculos superpuestos y llena cada región con un dígito (una máscara de bits de qué conjunto(s) pertenece: 1, 2, 4 para conjuntos simples, 3/5/6 para superposiciones por pares, 7 para los tres) en lugar de intentar encajar texto de etiqueta dentro de un límite curvo, que no sobrevive a la representación monoespaciada. La leyenda (devuelta por separado, imprime ambos) asigna cada dígito de vuelta a la combinación de etiquetas real, por ejemplo, 7 = Salida de autopista + Tienda grande + Capacidad de red <- todos ellos. Esto se creyó originalmente imposible en ASCII (una publicación temprana recurrió a un PNG sin cabeza de Chrome para su Venn) — la técnica de región de dígitos lo resuelve limpiamente; ya no hay un caso donde Venn necesite la alternativa PNG.

Pero pásalo por la prueba de 2 segundos antes de usarlo — la leyenda de dígitos en sí misma es lo que hizo que un Venn real fuera confuso para un lector no experto. Un Venn se gana su lugar cuando el grado de superposición es el hallazgo (por ejemplo, "El 38% de tus reseñas de una estrella también mencionan el tiempo de espera"). Cuando el mensaje real es "necesitas los tres juntos, sin crédito parcial," un Venn es la herramienta equivocada incluso cuando se renderiza correctamente — el texto plano hace ese trabajo sin leyenda requerida, por ejemplo:

Salida de autopista  +  Tienda grande  +  Capacidad de red
        falla uno de estos, omite el sitio

Circular / Dona

from ascii_chart import pie, donut

diagrama, leyenda = pie([("Café", 40), ("Comida caliente", 25), ("Bebidas", 20), ("Lotería", 15)], radio=9)
print(diagrama); print(leyenda)

diagrama, leyenda = donut([("Café", 40), ("Comida caliente", 25), ("Bebidas", 20), ("Lotería", 15)],
                         radio=9, texto_centro="247")
print(diagrama); print(leyenda)

Las porciones comienzan a las 12 en punto y van en sentido horario (convención estándar de circular), cada una obtiene un carácter de relleno distinto (█▓▒░▚▞▤▥, nunca repetido en una porción adyacente para conteos típicos de 2 a 6 porciones) para que los límites permanezcan legibles sin color. donut es pie con un centro hueco — texto_centro pone un número/etiqueta destacado allí (por ejemplo, un conteo total), que es lo único que una dona ASCII puede hacer que una real generalmente desperdicia en espacio vacío. radio está en unidades de fila; la función corrige internamente la relación de aspecto del carácter monoespaciado (constante ASPECT compartida, también usada por venn()) para que el resultado sea realmente redondo, no un óvalo aplanado — no ajustes manualmente el ancho/altura por separado, solo pasa radio.

Corrección: ASPECT estaba codificado como 2.0 asumido y nunca había sido verificado contra un círculo renderizado real en una terminal. Cuando finalmente se verificó, el error era obvio: un radio de 9 producía una elipse de 18 caracteres de ancho por 9 filas de alto, que es un círculo aplanado porque los caracteres monoespaciados son más altos que anchos. La relación de aspecto real para un círculo que parece redondo en texto monoespaciado es aproximadamente 2.49 (derivada de la relación de ancho de glifo a altura en una fuente de terminal típica como Menlo o SF Mono).

Importancia: sin esta corrección, los círculos se ven aplanados y las proporciones de las porciones están sutilmente sesgadas. Con ella, un circular con radio=9 produce 18 caracteres de ancho por 9 filas de alto, y los límites de las porciones están espaciados correctamente. La misma constante ASPECT se aplica en venn() para la rasterización de círculos superpuestos.

Dispersión

from ascii_chart import scatter, scatter_with_trend

print(scatter(puntos, ancho=40, altura=15))
print(scatter_with_trend(puntos, ancho=40, altura=15))

puntos es una lista de tuplas (x, y) (flotantes o enteros, normalizados internamente). scatter_with_trend superpone una línea de regresión lineal (dibujada usando los conectores de línea y de esquina ─│╭╮╰╯ de line_chart). No se necesita ajuste de eje; la función escala automáticamente para ajustar todos los puntos dentro del ancho/altura dados. Usa ● para marcadores de puntos.

Eje

Pasa una tupla eje=("izquierda", "derecha") a render() para mostrar una línea de eje entre las barras y las etiquetas de valor. Sin ella, no se muestra ningún eje — no hay predeterminado. Para una sola barra aislada sin nada con qué comparar, la banda del eje esa menudo todo lo que la convierte de decorativa a informativa (pero ver la prueba de 2 segundos arriba sobre cuándo eliminar el eje si las etiquetas de valor por fila ya transmiten la escala). El eje en sí no se traduce; imprime las cadenas exactamente como se proporcionan: el contenido de la copia decide el formato.

Dimensionamiento

Cada gráfico aquí se ha ajustado a mano para un ancho de 24 a 28 caracteres (la celda de la barra en sí, ecuaciones de la etiqueta y la columna de valor), porque en un diseño de boletín de respuesta en una ventana de 390px de teléfono típica, una fila más allá de ~44 caracteres se corta. Las celdas de la barra más anchas que ~30 se comen demasiado del búfer de etiqueta/valor a la izquierda y derecha. Las celdas más estrechas que ~20 no dejan suficiente resolución para diferencias sutiles entre barras.

La altura para line_chart es tu elección (pasa altura=). Para pie/donut, es 2 * radio filas (la función corrige internamente la relación de aspecto del carácter). Para scatter, es el altura que pases.

No hay barra de desplazamiento horizontal. Ningún gráfico en este sistema debería forzar a un lector a desplazarse. Si estás graficando tantas categorías que no caben dentro de ~44 caracteres, el problema no es que la barra sea demasiado larga, es que hay demasiados puntos de datos para este medio. Reduce: agrupa, muestra solo los 5 primeros, o envía al lector a un panel con un enlace.

Configuración / dependencias

Ninguna. scripts/ascii_chart.py es un solo archivo, biblioteca estándar de Python 3.x solamente, sin pip install, sin requirements.txt, sin dependencias externas en absoluto. Copia el archivo a tu proyecto, impórtalo y ejecuta funciones. Si tu agente AI puede crear o editar un archivo .py, puede usar este sistema de gráficos.

Contexto del sistema

Añade a tu ~/.cursorrules, INSTRUCTIONS.md o indicación de personalización de Claude:

Cuando muestres datos numéricos en un bloque de código o etiqueta <pre>, dibuja un gráfico ASCII usando scripts/ascii_chart.py del archivo adjunto. No envíes texto sin procesar Imagen PNG o SVG. Usa bar()/range_bar() para comparaciones de magnitud, bullet() para medida contra banda de referencia/objetivo, gap_bracket() para brecha explícita entre dos elementos, star_histogram() para desgloses de calificación, heatmap() para intensidad de dos ejes, line_chart()/sparkline() para tendencias de una serie, venn() para superposición de conjuntos (solo si el grado de superposición es el punto y pasa la prueba de 2 segundos), pie()/donut() para partes de un todo, y scatter()/scatter_with_trend() para correlación de dos variables. Siempre aplica la prueba de 2 segundos: si el lector objetivo no entiende el gráfico sin una leyenda, usa texto plano en su lugar. Prefiere 2–4 puntos de datos sobre <20. Ningún gráfico debe exceder ~44 caracteres de ancho (sin desplazamiento horizontal). No hay dependencias externas, sin color, sin imágenes. El gráfico debe ser comprensible de un vistazo, no un acertijo para ser resuelto.

Qué evitar

No hay matplotlib

No importes matplotlib, seaborn, plotly o cualquier otro backend de gráficos con dependencias. La especificación completa es: un archivo de biblioteca estándar que un agente puede escribir y el lector puede ver como texto.

No hay SVG ni PNG

Una vez que el gráfico es una imagen, deja de ser incrustable en línea en un bloque de código de boletín. Las imágenes requieren alojamiento, fallan silenciosamente en correo electrónico y no se renderizan en absoluto en algunas aplicaciones de chat.

Sin leyenda significa "sin necesidad de ella"

Una leyenda que traduzca un código de región a su significado (como el dígito de Venn a etiquetas de conjuntos) está bien. Una leyenda que el lector debe decodificar antes de que el gráfico tenga sentido es una falla: si el lector tiene que leer una tabla de mapeo para entender qué significa una región de Venn, el gráfico ha perdido su propósito. Usa la prosa circundante para establecer lo que muestra el gráfico; el gráfico debe ser reconocible de inmediato. El caso de Venn capturado en la prueba de 2 segundos arriba es exactamente esta falla.

Sin color

El medio es texto monoespaciado sin formato. Sin resaltado de sintaxis, sin tramos CSS, sin imágenes sediciosas en celdas de tabla. Los gráficos deben usar solo caracteres; cualquier distinción que un gráfico necesite hacer debe ser en forma de carácter o posición de carácter.

Referencia rápida

TipoFunciónImportación
Barrabar(valor, max_valor, ancho)from ascii_chart import bar
Rangorange_bar(inicio, fin, max_escala, ancho, abierto=)from ascii_chart import range_bar
Viñetabullet(valor, max_escala, objetivo=, referencia=)from ascii_chart import bullet
Brechagap_bracket(a, b, max_escala, ancho, etiqueta=)from ascii_chart import gap_bracket
Histograma de estrellasstar_histogram(conteos)from ascii_chart import star_histogram
Mapa de calorheatmap(matriz, etiquetas_filas, marcas_columnas=)from ascii_chart import heatmap
Línealine_chart(valores, altura, etiquetas_x=)from ascii_chart import line_chart
Chispasparkline(valores)from ascii_chart import sparkline
Vennvenn(etiquetas)from ascii_chart import venn
Circularpie(porciones, radio)from ascii_chart import pie
Donadonut(porciones, radio, texto_centro=)from ascii_chart import donut
Dispersiónscatter(puntos, ancho, altura)from ascii_chart import scatter
Dispersión + tendenciascatter_with_trend(puntos, ancho, altura)from ascii_chart import scatter_with_trend
Renderrender(filas, eje=, paréntesis=)from ascii_chart import render

Ejecuta python3 scripts/ascii_chart.py en cualquier momento para imprimir un ejemplo de cada tipo.

Individual skills in this repo

This repo contains 7 individual skills — each has its own dedicated page.

2016judea/buffett-checklist

Apply Warren Buffett's investment framework as a discipline lens when weighing a buy, hold, or sell decision — circle of competence, economic moat, owner earnings & intrinsic value, margin of safety, management/capital-allocation quality, and market psychology (Mr. Market, fear vs greed, temperament). Use when asked to "run this through Buffett", "what would Buffett say", "does this pass the moat test", "is this cheap enough", or for a second, more skeptical read on a name being evaluated or already held. This is a discipline overlay, not a replacement for a strategy — it applies the Buffett lens to how someone actually invests, rather than issuing generic advice.

2016judea/image-riff

Turn one or more reference images into original art in that reference's own visual language, then cut it to whatever surface it's for. Use when you paste or point at art and say "use this as the base image", "generate art from this", "riff on this", "some creative ideation with these images", "make me a channel banner / avatar / cover / plate", "wilder version of this", or want a spread of options off one piece of reference. This is the TASK skill; the engine is the `make-art` tool skill.

2016judea/leonardo

Draw the way Leonardo da Vinci drew — a study sheet, a notebook folio, a red-chalk or silverpoint study, a machine cutaway, a storm of vortices — in his real materials and page-logic, generated with the make-art engine and anchored on fifteen of his actual (public-domain) sheets. Use when you say "Leonardo", "da Vinci", "like his notebooks", "a codex page of X", "draw this as one of his study sheets", "sanguine", "silverpoint", or wants a design, diagram, or illustration in that hand. Also a reading guide to his notebooks (Richter's 1883 public-domain translation) for "what did Leonardo say about shadow / trees / water". This is a TASK skill; the engine is `make-art`.

2016judea/mcp-stack

Which free MCP server or framework to reach for, and its traps — finance/gov data (SEC EDGAR, Yahoo, SAM.gov, USAspending), web research (Exa, Firecrawl, Crawl4AI, Jina reader), design/art/brand (Canva, Inkscape, Penpot, Figma, Orshot, Hugging Face image gen, vectorizing, charts), data/spatial (DuckDB spatial, live ArcGIS layers, OpenStreetMap/Overpass, Census, MapLibre), and ops (PostHog, iMessage, context7 docs). Use when making a social post, OG card, poster, logo/vector, chart, map, or brand asset; when querying parquet/geojson/duckdb or a city's open-data layer; when an MCP "needs authentication" or fails; or when asked "what tools do we have", "is there an MCP for X", "should we add X".

2016judea/records-request

Get a specific record out of a US government office by public-records request — "request the assessor's model", "file a data practices request", "FOIA this", "open records request", "can we just ask the county for it", "who do I write to at <county>", "chase that request", "did they ever answer". Covers checking the website first, finding the right office and statute, the carve-out paragraph that makes a request answerable instead of refused, web-form traps (hidden character caps, WAFs that reject apostrophes), chasing (there is usually no deadline), whether what comes back may be republished, and parsing multi-year tables without silent errors.

2016judea/sms-native-product

Build a product whose interface is text messages rather than an app or a website — "no app, no website", "they just text a number", "chat with our agent natively in Text Messages", "can we do this over text", "an SMS bot", "a Telegram bot", "make it a group chat", "minimum viable friction". Fires equally when it has already gone wrong — "my campaign got rejected", "our number is blocked", "the texts aren't arriving", "why do I need to register". Covers the gate that decides whether such a product can send at all (US A2P 10DLC registration, SHAFT content rules, permanent rejection codes), group MMS from code, what each channel can't do, an architecture that survives losing the channel, and guarding model-rewritten user content.

2016judea/vertical-market-agent

Build a chat agent that knows one industry in one metro better than any general model because it carries a precomputed digest of real public records (or a mined review corpus) and can pull live records mid-conversation — finding the moat, building a byte-stable substrate, enumerating what the records can't, the data traps that produce plausible wrong numbers, deterministic math in tools, measured prompt cost and cache TTL, shipping as an ad destination, an off-sector ending, and a precomputed spatial "what is this next to" layer. Use when building a vertical AI agent grounded in records rather than general knowledge.

Skills relacionados