En programación, el boilerplate code o simplemente boilerplate son esas secciones de código que deben incluirse en muchos lugares con poca o ninguna alteración.
Cuando se utilizan lenguajes que se consideran verbosos, el programador debe escribir mucho código para lograr una mínima funcionalidad. Dicho código se llama boilerplate.
Los tres lenguajes tienen for, pero cada uno lo entiende a su manera. Java tiene dos formas, Go usa una sola palabra para todos los bucles, y en Python el for siempre recorre algo. Los comparamos con ejemplos ejecutados en los tres.
public class CicloFor {
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
System.out.println("valor de i: " + i);
}
String[] lenguajes = {"Java", "Go", "Python"};
for (String l : lenguajes) {
System.out.println(l);
}
for (int i = 0, j = 10; i < j; i += 3, j -= 3) {
System.out.println(i + " " + j);
}
}
}
java CicloFor.javavalor de i: 0
valor de i: 1
valor de i: 2
Java
Go
Python
0 10
3 7
El primero es el for heredado de C: una inicialización, una condición que se comprueba antes de cada vuelta y un incremento que se ejecuta al final de cada una. El segundo, el «for mejorado», recorre un arreglo o cualquier colección sin índice. El tercero recuerda que cada una de las tres partes puede tener varias expresiones separadas por comas.
Go: una sola palabra para todos los bucles
package main
import "fmt"
func main() {
for i := 0; i < 3; i++ {
fmt.Println("valor de i: ", i)
}
for i := range 3 {
fmt.Println("range:", i)
}
lenguajes := []string{"Java", "Go", "Python"}
for i, l := range lenguajes {
fmt.Println(i, l)
}
n := 1
for n < 100 {
n *= 3
}
fmt.Println("primera potencia de 3 mayor que 100:", n)
for {
fmt.Println("una vez y fuera")
break
}
}
go run .valor de i: 0
valor de i: 1
valor de i: 2
range: 0
range: 1
range: 2
0 Java
1 Go
2 Python
primera potencia de 3 mayor que 100: 243
una vez y fuera
Go no tiene while ni do: todo se escribe con for. Con tres partes es el clásico, sin paréntesis. Con solo la condición, hace de while. Sin nada es un bucle infinito, del que se sale con break. Y con range recorre colecciones devolviendo el índice y el valor. Desde Go 1.22, range también acepta un número: for i := range 3 da 0, 1 y 2.
Fíjate en los dos espacios de valor de i: 0. fmt.Println pone un espacio entre cada argumento, y el texto ya terminaba en espacio. En Go se escribe fmt.Println("valor de i:", i), sin el espacio final.
Python: siempre recorre algo
for i in range(3):
print("valor de i: ", i)
for i in range(3):
print("valor de i:", i)
lenguajes = ["Java", "Go", "Python"]
for i, l in enumerate(lenguajes):
print(i, l)
for i in range(10, 0, -3):
print(i, end=" ")
print()
for l in lenguajes:
if l == "Rust":
break
else:
print("no había Rust")
python ciclo.pyvalor de i: 0
valor de i: 1
valor de i: 2
valor de i: 0
valor de i: 1
valor de i: 2
0 Java
1 Go
2 Python
10 7 4 1
no había Rust
En Python no hay for con contador: se recorre una secuencia, y range genera los números. range(10, 0, -3) cuenta hacia atrás de tres en tres, y enumerate da el índice junto a cada elemento. El primer print tiene el mismo doble espacio que Go, por el mismo motivo: print separa sus argumentos con un espacio.
Lo exclusivo de Python es el else del for: se ejecuta solo si el bucle terminó sin break. Sirve para búsquedas como esta, donde llegar al final significa que no se encontró nada.
Lado a lado
Java
Go
Python
Contar de 0 a 9
for (int i = 0; i < 10; i++)
for i := 0; i < 10; i++ o for i := range 10
for i in range(10):
Recorrer una colección
for (String l : lista)
for _, l := range lista
for l in lista:
Con índice
el for clásico
for i, l := range lista
for i, l in enumerate(lista):
Mientras se cumpla algo
while (cond)
for cond
while cond:
Infinito
while (true)
for
while True:
Bloque
llaves
llaves, obligatorias
sangría
Lo que cambia por debajo
La versión anterior de esta entrada decía que Java es un lenguaje interpretado, como Python. No es exacto, y la diferencia explica buena parte de la diferencia de velocidad. Java se compila a bytecode, y la máquina virtual compila a código máquina, mientras el programa se ejecuta, las partes que más se usan. Go se compila directamente a un ejecutable nativo. Python, en su implementación habitual, también compila a bytecode, pero lo interpreta instrucción a instrucción, y por eso un bucle con mucho cálculo suele ir bastante más despacio. Para medirlo bien, mira medir el rendimiento en Java.
Entrada publicada en 2020 y revisada en octubre de 2026. Cada ejemplo se ejecutó en un contenedor limpio con Java 25 LTS, Go 1.25 y Python 3.14; las salidas están copiadas de esa ejecución.
Katherine Louise Bouman es una científica y profesora asistente de ciencias de la computación en el Instituto de Tecnología de California. Hace tres años, Bouman lideró la creación de un algoritmo que eventualmente ayudó a formar esta imagen única en su clase: un agujero negro supermasivo y su sombra en el centro de una galaxia conocida como M87.Ella era entonces una estudiante graduada en ciencias de la computación e inteligencia artificial en el Instituto de Tecnología de Massachusetts.
Puedes ver una interesante charla de Bouman y su propuesta para la detección de agujeros negros en TED de hace tres años.
Años más tarde puedes ver que su investigación es un total éxito.
Ella y su equipo tomaron los «datos escasos y ruidosos» que generaron diversos radiotelescopios alrededor del mundo e intentaron crear una imagen.Durante los últimos años, Bouman dirigió la verificación de imágenes y la selección de parámetros para crearla. Mas de 5 petabytes fueron necesarios para recabar la información de todos los centros de investigación que participaron.
La imagen obtenida, revela la cara sombría de un agujero negro supermasivo de 6.500 millones de masas solares en el centro de Messier 87 (M87), una gran galaxia a unos 55 millones de años luz de la Tierra en el cúmulo de galaxias de Virgo.Tales objetos son la comprobación (una vez más) de la teoría de la relatividad general de Einstein que predice la deformación del espacio-tiempo por objetos súper massivos.
Python trae mucho de serie, pero buena parte de lo que se hace con él a diario se apoya en librerías externas. Estas son las que más se usan, agrupadas por tarea y cada una con un ejemplo corto que puedes copiar y ejecutar.
Ten en cuenta que el nombre del paquete no siempre coincide con el del import: se instala pillow y se importa PIL, se instala beautifulsoup4 y se importa bs4.
Para…
Librería
Versión probada
Peticiones HTTP
requests
2.34.2
Barras de progreso
tqdm
4.70.1
Imágenes
Pillow
12.3.0
Cálculo numérico
NumPy
2.5.3
Tablas de datos
pandas
3.0.6
Gráficas
Matplotlib
3.11.2
Extraer datos de HTML
Beautiful Soup
4.15.0
Bases de datos
SQLAlchemy
2.1.4
APIs web
FastAPI
0.143.0
Pruebas
pytest
9.1.1
requests: peticiones HTTP
import requests
r = requests.get("https://httpbin.org/get", params={"lenguaje": "python"}, timeout=10)
print(r.status_code, r.headers["Content-Type"])
print(r.json()["args"])
r = requests.post("https://httpbin.org/post", json={"sitio": "decodigo.com"}, timeout=10)
print(r.json()["json"])
Con params se arma la cadena de consulta, con json= se envía un cuerpo JSON con su cabecera, y r.json() decodifica la respuesta. Pon siempre un timeout: sin él, una petición a un servidor que no responde puede quedarse esperando indefinidamente. Si solo necesitas algo puntual y no quieres dependencias, la biblioteca estándar también lo hace; lo vemos en peticiones HTTP sin dependencias.
tqdm: barras de progreso
from time import sleep
from tqdm import tqdm
total = 0
for n in tqdm(range(50), desc="Procesando", ncols=70):
total += n
sleep(0.02)
print("suma:", total)
salida, última línea de la barraProcesando: 100%|█████████████████████| 50/50 [00:01<00:00, 49.11it/s]
suma: 1225
Basta con envolver el iterable en tqdm(). La barra se va redibujando en la misma línea y muestra el avance, la velocidad y el tiempo que falta. Es muy útil en procesos largos, porque deja ver enseguida si el trabajo avanza o se ha atascado.
thumbnail reduce la imagen para que quepa en la caja que le das (200×200), pero conserva la proporción: por eso queda en 200×100 y no se deforma. Pillow abre y guarda los formatos habituales (PNG, JPEG, WebP, GIF…) y sirve para recortar, rotar, dibujar o cambiar el formato por lotes.
salidamedia: 21.14 máxima: 24.3
[65.3 69.8 75.74 67.64 71.78]
count sum mean
lenguaje
Python 3 400 133.333333
Java 2 175 87.500000
Go 1 40 40.000000
NumPy opera sobre arreglos completos de una vez: temps * 9 / 5 + 32 convierte las cinco temperaturas sin escribir ningún bucle, y además mucho más rápido que un bucle en Python. pandas se apoya en NumPy para trabajar con tablas: aquí agrupa por lenguaje y calcula el número de filas, la suma y la media de cada grupo en una sola línea. Si trabajas con archivos muy grandes, merece la pena mirar también Polars, una alternativa más reciente y muy rápida.
La gráfica que genera el ejemplo, tal cual. Los datos son inventados.
matplotlib.use("Agg") hace que dibuje directamente a un archivo, sin abrir ninguna ventana; así funciona también en un servidor o en un contenedor. En tu ordenador puedes quitarlo y llamar a plt.show() para ver la gráfica en pantalla.
Beautiful Soup: extraer datos de HTML
from bs4 import BeautifulSoup
html = """
<ul id="lenguajes">
<li class="activo"><a href="/python">Python</a></li>
<li><a href="/java">Java</a></li>
<li class="activo"><a href="/rust">Rust</a></li>
</ul>
"""
soup = BeautifulSoup(html, "html.parser")
for a in soup.select("#lenguajes li.activo a"):
print(a.text, "->", a["href"])
salidaPython -> /python
Rust -> /rust
select acepta selectores CSS, los mismos que se usan en las hojas de estilo, así que #lenguajes li.activo a se lee igual que en CSS. Para descargar la página se combina con requests. Si lo que necesitas es recorrer un sitio entero siguiendo enlaces, la herramienta adecuada es Scrapy. Y antes de extraer datos de un sitio, revisa sus condiciones de uso y su robots.txt.
SQLAlchemy: bases de datos
from sqlalchemy import create_engine, select, String
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session
class Base(DeclarativeBase):
pass
class Articulo(Base):
__tablename__ = "articulos"
id: Mapped[int] = mapped_column(primary_key=True)
titulo: Mapped[str] = mapped_column(String(100))
visitas: Mapped[int]
engine = create_engine("sqlite:///:memory:")
Base.metadata.create_all(engine)
with Session(engine) as s:
s.add_all([Articulo(titulo="Hola mundo", visitas=10),
Articulo(titulo="Leer CSV", visitas=42),
Articulo(titulo="Peticiones HTTP", visitas=27)])
s.commit()
consulta = select(Articulo).where(Articulo.visitas > 20).order_by(Articulo.visitas.desc())
for a in s.scalars(consulta):
print(a.titulo, a.visitas)
salidaLeer CSV 42
Peticiones HTTP 27
Cada tabla se define como una clase, y las consultas se escriben en Python en lugar de en SQL. Es el estilo de SQLAlchemy 2, con anotaciones de tipo (Mapped[int]). El mismo código funciona con SQLite, PostgreSQL o MySQL cambiando solo la cadena de conexión. Para SQLite sin ninguna librería externa, mira SQLite con Python.
FastAPI: APIs web
from fastapi import FastAPI
from fastapi.testclient import TestClient
from pydantic import BaseModel
app = FastAPI()
class Articulo(BaseModel):
titulo: str
visitas: int = 0
@app.get("/saludo/{nombre}")
def saludo(nombre: str):
return {"mensaje": f"Hola, {nombre}"}
@app.post("/articulos")
def crear(articulo: Articulo):
return {"creado": articulo.titulo, "visitas": articulo.visitas}
cliente = TestClient(app)
print(cliente.get("/saludo/Ana").json())
print(cliente.post("/articulos", json={"titulo": "FastAPI"}).json())
r = cliente.post("/articulos", json={"visitas": "muchas"})
print(r.status_code, [e["loc"][-1] + ": " + e["type"] for e in r.json()["detail"]])
FastAPI usa las anotaciones de tipo para validar lo que llega: en la última petición falta el título y visitas no es un número, así que responde con un error 422 que explica cada fallo, sin que hayas escrito ninguna validación. Aquí se prueba con TestClient, que llama a la API sin levantar un servidor; en producción se ejecuta con uvicorn.
Con las versiones actuales, TestClient avisa de que usar httpx está obsoleto y pide instalar httpx2. Por eso aparece en el pip install de arriba; con él, el aviso desaparece y el ejemplo funciona igual.
Si buscas un framework completo, con panel de administración, usuarios y plantillas incluidos, la referencia es Django. Para algo pequeño y sin estructura impuesta, Flask.
Las pruebas son funciones que empiezan por test_ y usan un assert normal. parametrize ejecuta la misma prueba con varios casos, y cada uno aparece por separado en el informe; pytest.raises comprueba que se lanza la excepción esperada.
Interfaces gráficas multiplataforma, también para móviles
La versión de 2019 de esta entrada incluía Twisted, un framework de red basado en eventos. Sigue existiendo, pero hoy, para la mayoría de los programas concurrentes, se usa asyncio, que viene con Python, o librerías construidas sobre él.
Entrada publicada en 2019 y revisada en octubre de 2026. Todo el código se ejecutó con Python 3.14.8 en un contenedor limpio, con las versiones de la tabla; las salidas están copiadas de esa ejecución.
¿Cuánto es 9999999999999999.0 - 9999999999999998.0? Debería ser 1, pero en la mayoría de los lenguajes el resultado es 2. Geo Carncross hizo la prueba en una veintena de ellos, y la tabla de arriba resume lo que obtuvo. Aquí lo comprobamos en Java y vemos por qué pasa.
double a = 9999999999999999.0;
double b = 9999999999999998.0;
IO.println("a: " + a);
IO.println("b: " + b);
IO.println("a - b: " + (a - b));
IO.println("a exacto: " + new BigDecimal(a));
IO.println("b exacto: " + new BigDecimal(b));
IO.println("separación entre doubles cerca de a: " + Math.ulp(a));
IO.println("2^53 = " + (long) Math.pow(2, 53));
salidaa: 1.0E16
b: 9.999999999999998E15
a - b: 2.0
a exacto: 10000000000000000
b exacto: 9999999999999998
separación entre doubles cerca de a: 2.0
2^53 = 9007199254740992
La segunda línea de la salida ya da la pista: a se imprime como 1.0E16, es decir, 10000000000000000. El número que escribimos no es el que se guardó.new BigDecimal(a) muestra el valor exacto que hay en memoria, y la resta, con esos valores, sí está bien hecha: 10000000000000000 − 9999999999999998 = 2.
Por qué no cabe
Un double ocupa 64 bits: 1 para el signo, 11 para el exponente y 52 para la mantisa, que con un bit implícito dan 53 bits de precisión. Con 53 bits se pueden representar exactamente todos los enteros hasta 253 = 9,007,199,254,740,992. Nuestros números son mayores.
Por encima de ese límite, los double ya no están en todos los enteros: entre 253 y 254 van de dos en dos, que es lo que dice Math.ulp(a). 9999999999999998 es par y cae justo en uno. 9999999999999999 es impar, queda exactamente a medio camino entre 9999999999999998 y 10000000000000000, y la regla de redondeo de IEEE 754 (al vecino «par») lo lleva a 10000000000000000.
No es un fallo de Java: es el formato que usan casi todos los lenguajes y los procesadores. Por eso la mayoría de la tabla dice 2.
El caso de todos los días: 0.1 + 0.2
No hace falta irse a números tan grandes. Con decimales pequeños pasa algo parecido, porque la mayoría no tienen representación exacta en binario, igual que 1/3 no la tiene en decimal:
El 0.1 que se guarda es un poquito mayor que 0.1, y al sumar se acumulan esos errores. De ahí la regla: nunca compares double con ==. Compara la diferencia con un margen de tolerancia adecuado a tu problema.
Cuando hace falta exactitud
IO.println("new BigDecimal(\"0.1\").add(new BigDecimal(\"0.2\")) = " + new BigDecimal("0.1").add(new BigDecimal("0.2")));
IO.println("new BigDecimal(0.1).add(new BigDecimal(0.2)) = " + new BigDecimal(0.1).add(new BigDecimal(0.2)));
IO.println("9999999999999999L - 9999999999999998L = " + (9999999999999999L - 9999999999999998L));
double suma = 0;
for (int i = 0; i < 10; i++) suma += 0.1;
IO.println("0.1 sumado diez veces = " + suma);
Dos detalles importantes. BigDecimal se crea a partir de una cadena: new BigDecimal(0.1) recibe el double ya redondeado y conserva el error con todos sus decimales. Y la resta original, hecha con long, da 1, porque un long guarda enteros exactos hasta unos 9.2 trillones.
Para…
Usa
Por qué
Medidas, física, gráficos, estadística
double
Rápido, y un error en el decimal 16 no importa
Dinero
BigDecimal creado desde texto, o long en céntimos
Los céntimos tienen que cuadrar siempre
Contadores e identificadores grandes
long
Exacto hasta 9,223,372,036,854,775,807
Comparar dos double
Math.abs(x - y) < tolerancia
== falla con resultados de operaciones
La tabla de la imagen está tomada del experimento de Geo Carncross, que sigue en línea con algunos lenguajes más.
Entrada publicada en 2019 y revisada en octubre de 2026. Todo el código se compiló y se ejecutó con Java 25 LTS en un contenedor limpio; las salidas están copiadas de esa ejecución.
Es sabido que no debes enfocarte en una sola tecnología o lenguaje de programación. Pero el sentido de este consejo no es sólo que escojas una tecnología que te permita ganar más dinero (que también es una buena idea), sino que además de eso te permita experimentar y hacer cosas diferentes. Por ejemplo, si siempre has estado enfocado a aplicaciones WEB, puedes comenzar a experimentar con el control de motores eléctricos o para obtener datos desde sensores o hardware que no hayas usado anteriormente, o probar también con aplicaciones para móviles, tendrás una perspectiva más amplia de lo que es el desarrollo de software.
Ten un «Pet Project»
Todos tenemos ideas para una aplicación o desarrollo que nos gustaría programar. Sin embargo pocas veces las materializamos. Esto no sólo es malo porque pierdes la oportunidad de llevar a cabo una buena idea, sino que también es posible que nunca sepas si esa idea es mala o que en realidad no sea tan útil, o peor aún, que ya exista algo parecido porque no habías investigado demasiado y te enfoques mejor en otra cosa. Adquiere el hábito de tener al menos un proyecto y ve agregando características poco a poco pero de forma constante.
Relaciónate con personas que hagan cosas diferentes
No sólo se trata de encontrar gente que use otras tecnologías, sino otras formas de hacer negocios y de ganar dinero. Es posible que encuentres oportunidades donde otros no las han visto, tan sólo porque no ha llegado nadie para propornerlas. No te enfoques sólo a entender los problemas de los clientes de la empresa donde trabajes.
Haz que tu trabajo se vea elegante
Son muchos los desarrolladores que descuidan el aspecto visual de su trabajo y sólo se preocupan porque funcione correctamente. Sin embargo una apariencia visual o usabilidad deficientes, pueden hacer que el usuario tenga una impresión equivocada sobre como funcionan tus desarrollos y llegue a pensar que tiene errores aún cuando esto no sea verdad, recuerda que haces desarrollo para facilitarle la vida a personas que no siempre tienen un conocimiento técnico silimar al tuyo.
No inventes cosas que ya están bien hechas
Lenguajes como Java o C# no son los más ampliamente usados por su sintaxis o su facilidad de uso, sino por la inmensa variedad de librerías o herramientas que existen y que puedes usar libremente, con la seguridad de que van a funcionar correctamente. No gastes tu tiempo tratndo de hacer algo que ya existe si no lo vas a superar.
Comparte y acepta críticas a tu código
Es universal. Ocurre en todas las profesiones. A nadie le gusta que le digan como hacer cosas que uno supone hace bien. Pero compartir ideas y tomar en cuenta las recomendaciones de otros es casi tan útil como Google para aprender cosas nuevas. Además mejoras tu ambiente laboral.
Crea librerías de ejemplos o soluciones
No es que tengas que desarrollar librerías nuevas, se trata más bien de esos ejemplos, como conectarte a bases de datos, nombres de drivers, herramientas, comandos, funciones o técnicas de desarrollo que quizá aplicarás en tus proyectos más de una vez. En cualquier momento puedes usar el buscador y encontrar prácticamente todo lo que necesites, pero tener cosas ya probadas previamente por tí, es muy útil.
Descansa lejos de la computadora
Esto debes hacerlo por puro amor propio y no sólo es descansar, ejercítate. Algunos problemas de espalda y ojos derivados de pasar horas sentados frente a la computadora pueden agravarse y son difíciles de tratar. Cuida tu cuerpo.
El empleado de Google Jason Mayes, ingeniero creativo senior, ha publicado unas de las mejores presentaciones sobre Machine Learning. El trabajo es el resultado de dos años de experiencia, es gratuito y se puede descargar o visualizar en línea. Los únicos requisitos según su creador son los siguientes:
Dos horas de estudio y atención continuas.
Cerrar clientes de correo y aplicaciones de mensajería.
Buscar un lugar adecuado para su estudio, porque no por nada se trata del estudio de «deep learning».
Linus Torvalds transformó la tecnología dos veces: primero con el núcleo de Linux, que es uno de los soportes fundamentales de Internet, y lo hizo nuevamente con Git, el sistema de administración de código fuente utilizado por desarrolladores de todo el mundo. En una rara entrevista con el Curador de TED, Chris Anderson, Torvalds discute con gran apertura los rasgos de personalidad que impulsaron su filosofía de trabajo, su ingeniería y su vida.
Existe una amplia variedad de tipos de redes neuronales y a veces es necesario un mapa para navegar entre muchas arquitecturas y enfoques emergentes. Fjodor Van Veen del instituto Asimov compiló una maravillosa variedad de topologías de redes neuronales.