Bucles en Python — 3 programas que por fin tienen sentido
Los bucles en Python práctica real es lo que toca ahora. En el artículo anterior vimos la teoría de for y while. Ahora construimos tres programas desde cero en VS Code: un validador de contraseña con intentos limitados, una calculadora de factorial y una cuenta atrás. Además comparamos cómo el mismo problema se resuelve con for y con while para que quede claro cuándo usar cada uno.
Practicar los bucles en Python con programas reales es la forma más efectiva de entender cuándo usar for y cuándo usar while.
Crea una carpeta llamada practica_bucles y un archivo separado para cada programa. Si quieres ir más allá, usa pythontutor.com y ejecuta el código paso por paso
Tabla de Contenidos
Bucles en Python práctica — Programa 1: Validador de contraseña con intentos limitados
Este programa usa while porque no sabemos cuántos intentos necesitará el usuario. Crea el archivo validador_contrasena.py.
Versión simple:
# Validador de contraseña — versión simple
CONTRASENA_CORRECTA = "Python2024"
MAX_INTENTOS = 3
intentos = 0
while intentos < MAX_INTENTOS:
contrasena = input("Introduce la contraseña: ")
intentos += 1
if contrasena == CONTRASENA_CORRECTA:
print("✓ Acceso concedido")
break
else:
restantes = MAX_INTENTOS - intentos
if restantes > 0:
print(f"✗ Contraseña incorrecta — {restantes} intento/s restante/s")
else:
print("✗ Cuenta bloqueada — demasiados intentos fallidos")
```
Resultado con contraseña incorrecta tres veces:
```
Introduce la contraseña: python
✗ Contraseña incorrecta — 2 intento/s restante/s
Introduce la contraseña: Python
✗ Contraseña incorrecta — 1 intento/s restante/s
Introduce la contraseña: PYTHON2024
✗ Cuenta bloqueada — demasiados intentos fallidos
Versión mejorada con tiempo de espera simulado y feedback de seguridad:
# Validador de contraseña — versión mejorada
import time
CONTRASENA_CORRECTA = "Python2024"
MAX_INTENTOS = 3
intentos = 0
bloqueado = False
print("=== SISTEMA DE ACCESO ===\n")
while intentos < MAX_INTENTOS and not bloqueado:
contrasena = input(f"Contraseña (intento {intentos + 1}/{MAX_INTENTOS}): ")
intentos += 1
if contrasena == CONTRASENA_CORRECTA:
print(f"\n✓ Acceso concedido en el intento {intentos}")
print("Bienvenido al sistema.")
break
else:
restantes = MAX_INTENTOS - intentos
if restantes > 0:
print(f"✗ Incorrecta — {restantes} intento/s restante/s\n")
time.sleep(1) # simula tiempo de espera entre intentos
else:
bloqueado = True
print("\n🔒 Cuenta bloqueada por seguridad")
print("Contacta con el administrador para recuperar el acceso")
if bloqueado:
print(f"\nRegistro: {intentos} intentos fallidos")
Fíjate en el while con dos condiciones combinadas: intentos < MAX_INTENTOS and not bloqueado. Si cualquiera de las dos falla el bucle termina. Esto es mucho más limpio que tener un if dentro para comprobar el bloqueo.
Bucles en Python práctica — Programa 2: Calculadora de factorial
El factorial de un número n (escrito n!) es el producto de todos los números del 1 al n. Por ejemplo 5! = 5 × 4 × 3 × 2 × 1 = 120. Crea el archivo factorial.py.
Este programa es perfecto para comparar for vs while:
# Factorial — comparativa for vs while
numero = int(input("Introduce un número entero positivo: "))
if numero < 0:
print("Error: el factorial no existe para números negativos")
elif numero == 0:
print("0! = 1 (por definición matemática)")
else:
# CON FOR — sabemos exactamente cuántas veces repetir
factorial_for = 1
for i in range(1, numero + 1):
factorial_for *= i
# CON WHILE — misma lógica, diferente estructura
factorial_while = 1
i = 1
while i <= numero:
factorial_while *= i
i += 1
print(f"\n{numero}! calculado con for: {factorial_for}")
print(f"{numero}! calculado con while: {factorial_while}")
print(f"\n¿Son iguales?: {factorial_for == factorial_while}")
# Mostramos el proceso paso a paso
print(f"\nProceso: ", end="")
acumulado = 1
for i in range(1, numero + 1):
acumulado *= i
if i < numero:
print(f"{i}×", end="")
else:
print(f"{i} = {acumulado}")
```
Resultado con número 5:
```
5! calculado con for: 120
5! calculado con while: 120
¿Son iguales?: True
Proceso: 1×2×3×4×5 = 120
Esta comparativa directa deja muy claro por qué para el factorial usamos for, sabemos exactamente que vamos del 1 al n, así que el for con range() es la opción natural. El while funciona igual pero necesita más código para hacer lo mismo.
Bucles en Python práctica — Programa 3: Cuenta atrás con pausa
Crea el archivo cuenta_atras.py. Este programa usa for con range() en orden inverso, un uso de range() que no siempre se explica en clase:
# Cuenta atrás
import time
print("=== CUENTA ATRÁS ===\n")
segundos = int(input("¿Desde cuántos segundos? "))
if segundos <= 0:
print("Error: introduce un número mayor que 0")
else:
print()
# range con paso negativo — cuenta hacia atrás
for i in range(segundos, 0, -1):
print(f"{i}...")
time.sleep(1) # espera 1 segundo real
print("🚀 ¡Despegue!")
# Bonus — versión con while para comparar
print("\n--- Misma cuenta atrás con while ---\n")
i = segundos
while i > 0:
print(f"{i}...")
time.sleep(1)
i -= 1
print("🚀 ¡Despegue!")
```
Resultado con 3 segundos:
```
=== CUENTA ATRÁS ===
¿Desde cuántos segundos? 3
3...
2...
1...
🚀 ¡Despegue!
--- Misma cuenta atrás con while ---
3...
2...
1...
🚀 ¡Despegue!
El range(segundos, 0, -1) es clave, empieza en segundos, va hasta 1 (el 0 no se incluye) y va de uno en uno hacia abajo. El paso negativo -1 es lo que hace la cuenta regresiva.
De nuevo la comparativa es reveladora, aquí tanto for como while son igual de naturales porque sabemos el número de segundos de antemano. En estos casos usa for, es más limpio y pythónico.
El patrón del acumulador en los tres programas
Los tres programas usan el mismo patrón fundamental que vimos en teoría:
# Patrón acumulador — aparece en los tres programas
acumulador = valor_inicial # antes del bucle
for/while ...:
acumulador = acumulador operacion elemento # dentro del bucle
usar(acumulador) # después del bucle
# En el validador: intentos = 0 → intentos += 1
# En el factorial: factorial = 1 → factorial *= i
# En la cuenta atrás: i = segundos → i -= 1
Cuando veas un ejercicio de bucles en FP1 y no sepas por dónde empezar, pregúntate: ¿qué variable necesito acumular? Eso te da el punto de partida.
Resumen y siguiente paso
En este artículo de bucles en Python práctica construiste tres programas reales usando for y while en situaciones concretas. Viste while para intentos limitados con condición compuesta, for con range() normal e inverso, la comparativa directa for vs while en factorial y cuenta atrás, y el patrón del acumulador en los tres casos.
En el siguiente artículo encontrarás ejercicios propuestos para practicar por tu cuenta, con solución comentada al final.
Python loops — 3 programs that finally make sense
In the previous article we covered Python loops theory. Now let’s build three programs from scratch: a password validator with limited attempts, a factorial calculator, and a countdown. We’ll also compare how the same problem looks with for vs while.
Create a folder called loops_practice and a separate file for each program.
Program 1 — Password validator with limited attempts
Uses while, we don’t know how many attempts the user needs.
# Password validator — simple version
CORRECT_PASSWORD = "Python2024"
MAX_ATTEMPTS = 3
attempts = 0
while attempts < MAX_ATTEMPTS:
password = input("Enter password: ")
attempts += 1
if password == CORRECT_PASSWORD:
print("✓ Access granted")
break
else:
remaining = MAX_ATTEMPTS - attempts
if remaining > 0:
print(f"✗ Wrong password — {remaining} attempt(s) left")
else:
print("✗ Account locked — too many failed attempts")
Improved version with simulated wait time:
python
import time
CORRECT_PASSWORD = "Python2024"
MAX_ATTEMPTS = 3
attempts = 0
locked = False
print("=== ACCESS SYSTEM ===\n")
while attempts < MAX_ATTEMPTS and not locked:
password = input(f"Password (attempt {attempts + 1}/{MAX_ATTEMPTS}): ")
attempts += 1
if password == CORRECT_PASSWORD:
print(f"\n✓ Access granted on attempt {attempts}")
break
else:
remaining = MAX_ATTEMPTS - attempts
if remaining > 0:
print(f"✗ Wrong — {remaining} attempt(s) left\n")
time.sleep(1)
else:
locked = True
print("\n🔒 Account locked for security")
print("Contact admin to recover access")
Note the while with two combined conditions: attempts < MAX_ATTEMPTS and not locked. If either fails, the loop ends.
Program 2 — Factorial calculator
The factorial of n (written n!) is the product of all numbers from 1 to n. Example: 5! = 120.
# Factorial — for vs while comparison
number = int(input("Enter a positive integer: "))
if number < 0:
print("Error: factorial doesn't exist for negative numbers")
elif number == 0:
print("0! = 1 (by mathematical definition)")
else:
# WITH FOR — we know exactly how many times to repeat
factorial_for = 1
for i in range(1, number + 1):
factorial_for *= i
# WITH WHILE — same logic, different structure
factorial_while = 1
i = 1
while i <= number:
factorial_while *= i
i += 1
print(f"\n{number}! with for: {factorial_for}")
print(f"{number}! with while: {factorial_while}")
print(f"\nSame result?: {factorial_for == factorial_while}")
print(f"\nProcess: ", end="")
running = 1
for i in range(1, number + 1):
running *= i
if i < number:
print(f"{i}×", end="")
else:
print(f"{i} = {running}")
The comparison makes it clear: for factorial use for, we know we go from 1 to n, so range() is the natural choice. while works but needs more code for the same result.
Program 3 — Countdown with pause
import time
print("=== COUNTDOWN ===\n")
seconds = int(input("Count down from how many seconds? "))
if seconds <= 0:
print("Error: enter a number greater than 0")
else:
print()
# range with negative step — counts backwards
for i in range(seconds, 0, -1):
print(f"{i}...")
time.sleep(1)
print("🚀 Liftoff!")
# Same with while — for comparison
print("\n--- Same countdown with while ---\n")
i = seconds
while i > 0:
print(f"{i}...")
time.sleep(1)
i -= 1
print("🚀 Liftoff!")
range(seconds, 0, -1) starts at seconds, goes down to 1 (0 not included), step -1. The negative step is what makes it count down.
The accumulator pattern in all three programs
# Accumulator pattern
accumulator = initial_value # before the loop
for/while ...:
accumulator = accumulator op element # inside the loop
use(accumulator) # after the loop
# Validator: attempts = 0 → attempts += 1
# Factorial: factorial = 1 → factorial *= i
# Countdown: i = seconds → i -= 1
When stuck on a loop exercise: ask yourself what variable needs to accumulate. That’s your starting point.
Un comentario