Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Bucles While: El Robot Persistente

🧭 Navegación:

¡Bienvenido al centro de monitoreo de tu almacén! Después de conocer al robot especialista (bucle for), es momento de presentarte al robot persistente: el bucle while.

El bucle while es como un robot vigilante en tu almacén que sigue trabajando mientras una condición sea verdadera, sin importar cuánto tiempo tome.

El robot persistente de tu almacén 🤖

Imagínate que contratas a un robot persistente para tu almacén que puede:

  • Trabajar indefinidamente mientras una condición sea verdadera
  • Monitorear sistemas hasta que ocurra un evento específico
  • Procesar datos hasta que se cumplan ciertos criterios
  • Esperar hasta que algo importante suceda
  • Repetir tareas un número variable de veces
# El robot persistente en acción
inventario = 100
umbral_minimo = 20

# El robot monitorea el inventario
while inventario > umbral_minimo:
    print(f"Inventario actual: {inventario} unidades")
    print("Vendiendo 10 unidades...")
    inventario -= 10
    print("---")

print(f"¡Alerta! Inventario bajo: {inventario} unidades")
print("Solicitando reabastecimiento...")

Este robot usa la palabra mágica while para saber cuándo debe seguir trabajando y cuándo debe detenerse.

🔍 Mi perspectiva personal: Siempre pienso en los bucles while como un guardia de seguridad que vigila constantemente una puerta. No sabe cuánto tiempo tendrá que vigilar, pero sabe exactamente qué condición debe cumplirse para terminar su turno. Esta imagen me ayuda a recordar que siempre debe haber una condición clara de salida.

¿Cuándo usar while en lugar de for?

Los bucles for y while tienen propósitos diferentes:

  • Bucle for: Cuando sabes exactamente cuántas iteraciones necesitas o quieres procesar todos los elementos de una secuencia.
  • Bucle while: Cuando no sabes cuántas iteraciones necesitas y dependes de una condición que puede cambiar durante la ejecución.

Ejemplos de situaciones ideales para while:

  • Esperar a que el usuario ingrese una respuesta válida
  • Procesar datos hasta encontrar un valor específico
  • Ejecutar un juego hasta que el jugador pierda
  • Monitorear un sistema hasta que ocurra un evento
  • Implementar algoritmos que requieren un número variable de pasos

Sintaxis básica del bucle while

La estructura básica de un bucle while en Python es:

while condicion:
    # Código que se ejecuta mientras la condición sea True
    hacer_algo()
    # IMPORTANTE: Asegúrate de que la condición cambie eventualmente

Donde:

  • condicion es una expresión que se evalúa como True o False
  • El código indentado se ejecuta repetidamente mientras la condición sea True
  • Es crucial que algo dentro del bucle eventualmente cambie la condición a False, o tendrás un bucle infinito

Ejemplos básicos de bucles while

Contador simple:

# ================================
# CONTADOR DE INVENTARIO
# ================================

print("📦 CONTADOR DE INVENTARIO")
print("=" * 25)

contador = 1
total_productos = 5

# El robot cuenta mientras haya productos
while contador <= total_productos:
    print(f"Contando producto #{contador}")
    print(f"   📋 Registrado en sistema")
    contador += 1  # CRUCIAL: incrementar el contador

print()
print(f"✅ Conteo completado: {total_productos} productos")

Procesamiento hasta una condición:

# ================================
# PROCESADOR DE PEDIDOS
# ================================

print("🛒 PROCESADOR DE PEDIDOS")
print("=" * 25)

pedidos_pendientes = 8
capacidad_diaria = 3
dia = 1

print(f"Pedidos pendientes iniciales: {pedidos_pendientes}")
print(f"Capacidad de procesamiento diaria: {capacidad_diaria}")
print()

# Procesar pedidos hasta que no queden pendientes
while pedidos_pendientes > 0:
    # Determinar cuántos pedidos procesar hoy
    pedidos_hoy = min(capacidad_diaria, pedidos_pendientes)
    pedidos_pendientes -= pedidos_hoy
    
    print(f"Día {dia}:")
    print(f"   📦 Pedidos procesados: {pedidos_hoy}")
    print(f"   📋 Pedidos pendientes: {pedidos_pendientes}")
    print()
    
    dia += 1

print(f"✅ Todos los pedidos han sido procesados en {dia-1} días")

Bucles while con entrada del usuario

Los bucles while son perfectos para interactuar con el usuario hasta que proporcione una entrada válida:

# ================================
# SISTEMA DE AUTENTICACIÓN
# ================================

contraseña_correcta = "python123"
intentos_maximos = 3
intentos_actuales = 0

print("🔐 SISTEMA DE AUTENTICACIÓN")
print("=" * 30)

# En un programa real, usaríamos input() para obtener la contraseña del usuario
# Aquí simularemos diferentes entradas para mostrar el funcionamiento
contraseñas_simuladas = ["clave123", "python", "python123"]

# El robot sigue pidiendo contraseña hasta que sea correcta o se agoten los intentos
while intentos_actuales < intentos_maximos:
    # Simular entrada del usuario
    contraseña_ingresada = contraseñas_simuladas[intentos_actuales]
    intentos_actuales += 1
    
    print(f"Intento #{intentos_actuales}")
    print(f"Contraseña ingresada: {contraseña_ingresada}")
    
    if contraseña_ingresada == contraseña_correcta:
        print("✅ Acceso concedido")
        print("🏠 Bienvenido al sistema")
        break  # Salir del bucle
    else:
        intentos_restantes = intentos_maximos - intentos_actuales
        if intentos_restantes > 0:
            print(f"❌ Contraseña incorrecta")
            print(f"Te quedan {intentos_restantes} intentos")
        else:
            print("🚫 Acceso denegado - Demasiados intentos fallidos")
            print("🔒 Cuenta bloqueada temporalmente")

print("🔚 Proceso de autenticación terminado")

Bucles while con condiciones complejas

Puedes usar operadores lógicos para crear condiciones más complejas:

# ================================
# MONITOR DE RECURSOS DEL SISTEMA
# ================================

print("📊 MONITOR DE RECURSOS DEL SISTEMA")
print("=" * 35)

# Estado inicial del sistema
cpu_usage = 75
memory_usage = 60
disk_space = 50
is_monitoring = True
minutes = 0

print("Iniciando monitoreo del sistema...")
print("Presione Ctrl+C para detener (simulado con límite de 10 minutos)")
print()

# Monitorear mientras el sistema esté en niveles aceptables y el monitoreo esté activo
while (cpu_usage < 90 and memory_usage < 85 and disk_space < 95) and is_monitoring:
    minutes += 1
    
    print(f"Minuto {minutes} - Estado del sistema:")
    print(f"   CPU: {cpu_usage}%")
    print(f"   Memoria: {memory_usage}%")
    print(f"   Disco: {disk_space}%")
    
    # Simular cambios en el sistema
    cpu_usage += 2 if minutes % 2 == 0 else -1
    memory_usage += 3 if minutes % 3 == 0 else 1
    disk_space += 1
    
    # Limitar valores
    cpu_usage = min(100, max(0, cpu_usage))
    memory_usage = min(100, max(0, memory_usage))
    disk_space = min(100, max(0, disk_space))
    
    # Simular detención después de 10 minutos
    if minutes >= 10:
        is_monitoring = False
    
    print()

# Determinar por qué se detuvo el monitoreo
if not is_monitoring:
    print("Monitoreo detenido manualmente")
elif cpu_usage >= 90:
    print("⚠️ ¡Alerta! Uso de CPU crítico")
elif memory_usage >= 85:
    print("⚠️ ¡Alerta! Uso de memoria crítico")
elif disk_space >= 95:
    print("⚠️ ¡Alerta! Espacio en disco crítico")

print("Monitoreo finalizado")

El peligro de los bucles infinitos

Un bucle infinito ocurre cuando la condición del while nunca se vuelve falsa. Esto puede bloquear tu programa:

# ❌ PELIGRO: Bucle infinito
# while True:
#     print("¡Esto nunca terminará!")

Para evitar bucles infinitos:

  1. Asegúrate de que la condición eventualmente se vuelva falsa
  2. Incluye una cláusula de escape (como break)
  3. Verifica que las variables en la condición se actualicen dentro del bucle

Ejemplo de bucle infinito controlado:

# ================================
# SIMULADOR DE SERVICIO CONTINUO
# ================================

print("🔄 SIMULADOR DE SERVICIO CONTINUO")
print("=" * 35)

contador = 0
max_iteraciones = 5  # En un servicio real, esto sería infinito

print("Iniciando servicio...")
print("(Limitado a 5 iteraciones para la demostración)")
print()

# Bucle "infinito" controlado
while True:
    contador += 1
    print(f"Iteración #{contador}")
    print("   ✅ Servicio ejecutándose")
    
    # Cláusula de escape para la demostración
    if contador >= max_iteraciones:
        print("   ⚠️ Límite de demostración alcanzado")
        break
    
    print()

print("Servicio detenido")

Bucles while con else

Al igual que los bucles for, los bucles while pueden tener una cláusula else que se ejecuta cuando la condición se vuelve falsa (pero no si el bucle termina con break):

# ================================
# BUSCADOR DE PRODUCTOS
# ================================

print("🔍 BUSCADOR DE PRODUCTOS")
print("=" * 25)

productos = ["laptop", "mouse", "teclado", "monitor", "auriculares"]
producto_buscado = "impresora"

print(f"Buscando: {producto_buscado}")
print(f"En inventario: {productos}")
print()

# Inicializar variables
encontrado = False
indice = 0

# Buscar mientras haya elementos por revisar
while indice < len(productos):
    print(f"Revisando posición {indice}: {productos[indice]}")
    
    if productos[indice] == producto_buscado:
        encontrado = True
        print(f"✅ ¡Producto encontrado en posición {indice}!")
        break
    
    indice += 1
else:
    # Este bloque se ejecuta si el while termina normalmente (sin break)
    print("❌ Producto no encontrado en el inventario")

print("Búsqueda finalizada")

Ejemplo práctico completo: Simulador de cajero automático

# ================================
# SIMULADOR DE CAJERO AUTOMÁTICO
# ================================

print("🏧 SIMULADOR DE CAJERO AUTOMÁTICO")
print("=" * 35)

# Datos de la cuenta
saldo = 1000
pin_correcto = "1234"
intentos_pin = 3
sesion_activa = False

# Función para mostrar el menú
def mostrar_menu():
    print("\n=== MENÚ PRINCIPAL ===")
    print("1. Consultar saldo")
    print("2. Retirar dinero")
    print("3. Depositar dinero")
    print("4. Salir")
    return input("Seleccione una opción (1-4): ")

# Autenticación
print("Bienvenido a su cajero automático")
while intentos_pin > 0 and not sesion_activa:
    # En un programa real, usaríamos input() para obtener el PIN
    pin_ingresado = "1234"  # Simular entrada correcta
    
    if pin_ingresado == pin_correcto:
        print("✅ PIN correcto")
        sesion_activa = True
    else:
        intentos_pin -= 1
        if intentos_pin > 0:
            print(f"❌ PIN incorrecto. Le quedan {intentos_pin} intentos")
        else:
            print("🚫 Demasiados intentos fallidos. Tarjeta bloqueada")

# Menú principal
if sesion_activa:
    print("\n¡Bienvenido a su cuenta!")
    
    opcion = ""
    while opcion != "4" and sesion_activa:
        opcion = mostrar_menu()
        
        if opcion == "1":
            # Consultar saldo
            print(f"\n💰 Su saldo actual es: ${saldo}")
            
        elif opcion == "2":
            # Retirar dinero
            print("\n=== RETIRO DE DINERO ===")
            # En un programa real, usaríamos input() para obtener la cantidad
            cantidad = 300  # Simular entrada
            
            if cantidad > saldo:
                print("❌ Fondos insuficientes")
            elif cantidad <= 0:
                print("❌ Cantidad inválida")
            else:
                saldo -= cantidad
                print(f"✅ Ha retirado ${cantidad}")
                print(f"💰 Nuevo saldo: ${saldo}")
                
        elif opcion == "3":
            # Depositar dinero
            print("\n=== DEPÓSITO DE DINERO ===")
            # En un programa real, usaríamos input() para obtener la cantidad
            cantidad = 500  # Simular entrada
            
            if cantidad <= 0:
                print("❌ Cantidad inválida")
            else:
                saldo += cantidad
                print(f"✅ Ha depositado ${cantidad}")
                print(f"💰 Nuevo saldo: ${saldo}")
                
        elif opcion == "4":
            # Salir
            print("\n👋 Gracias por usar nuestro cajero automático")
            print("Sesión finalizada")
            sesion_activa = False
            
        else:
            print("\n❌ Opción inválida. Por favor, seleccione una opción válida (1-4)")

print("\n🔚 Programa terminado")

Buenas prácticas para bucles while

1. Asegúrate de que la condición eventualmente se vuelva falsa:

# ❌ PELIGROSO
# contador = 10
# while contador > 0:
#     print(contador)
#     # Olvidamos decrementar el contador

# ✅ SEGURO
contador = 10
while contador > 0:
    print(contador)
    contador -= 1  # Aseguramos que la condición eventualmente sea falsa

2. Usa break para salir del bucle en casos especiales:

while True:
    respuesta = input("¿Continuar? (s/n): ")
    if respuesta.lower() == 'n':
        break  # Salir del bucle cuando el usuario responda 'n'

3. Evita condiciones demasiado complejas:

# ❌ DIFÍCIL DE LEER
while x > 0 and y < 100 and not z or w == 10:
    # Código...

# ✅ MÁS CLARO
condicion1 = x > 0 and y < 100
condicion2 = not z or w == 10
while condicion1 and condicion2:
    # Código...

4. Considera usar for cuando conozcas el número de iteraciones:

# ❌ MENOS PYTHÓNICO
i = 0
while i < 10:
    print(i)
    i += 1

# ✅ MÁS PYTHÓNICO
for i in range(10):
    print(i)

Comprueba tu comprensión 🧠

  1. ¿Cuál es la principal diferencia entre un bucle for y un bucle while?

  2. ¿Qué imprimirá el siguiente código?

    x = 5
    while x > 0:
        print(x, end=" ")
        x -= 1
    
  3. ¿Qué sucede si la condición de un bucle while nunca se vuelve falsa?

  4. Escribe un bucle while que calcule la suma de los números del 1 al 10.

Soluciones

  1. La principal diferencia entre un bucle for y un bucle while es:

    • Un bucle for se utiliza para iterar sobre una secuencia conocida de elementos o un número conocido de veces.
    • Un bucle while se ejecuta mientras una condición sea verdadera, sin importar cuántas iteraciones sean necesarias. En resumen, usamos for cuando sabemos cuántas veces queremos iterar, y while cuando no lo sabemos y dependemos de una condición.
  2. El código imprimirá: 5 4 3 2 1

    Explicación: El bucle comienza con x = 5 y se ejecuta mientras x > 0. En cada iteración, imprime el valor de x y luego lo decrementa en 1. El bucle se detiene cuando x llega a 0.

  3. Si la condición de un bucle while nunca se vuelve falsa, se produce un “bucle infinito”. El programa seguirá ejecutando el código dentro del bucle indefinidamente, lo que puede hacer que el programa se bloquee o consuma recursos excesivamente. En entornos de desarrollo, generalmente necesitarás forzar la terminación del programa (por ejemplo, con Ctrl+C).

  4. Bucle while para calcular la suma de los números del 1 al 10:

    suma = 0
    numero = 1
    
    while numero <= 10:
        suma += numero
        numero += 1
    
    print(f"La suma de los números del 1 al 10 es: {suma}")  # 55
    

Ejercicio práctico: Juego de adivinanza

# ================================
# JUEGO DE ADIVINANZA
# ================================

import random

print("🎮 JUEGO DE ADIVINANZA")
print("=" * 25)

# Configuración del juego
numero_secreto = random.randint(1, 100)
intentos_maximos = 7
intentos_realizados = 0
adivinado = False

print("He pensado un número entre 1 y 100.")
print(f"Tienes {intentos_maximos} intentos para adivinarlo.")
print()

# Bucle principal del juego
while intentos_realizados < intentos_maximos and not adivinado:
    # En un programa real, usaríamos input() para obtener la respuesta
    # Aquí simularemos diferentes respuestas para mostrar el funcionamiento
    if intentos_realizados == 0:
        intento = 50  # Primera suposición: justo en medio
    elif numero_secreto > intento:
        intento += max(1, (100 - intento) // 2)  # Simular que el jugador va más alto
    else:
        intento -= max(1, intento // 2)  # Simular que el jugador va más bajo
    
    intentos_realizados += 1
    
    print(f"Intento #{intentos_realizados}: {intento}")
    
    # Comprobar la respuesta
    if intento == numero_secreto:
        adivinado = True
        print(f"🎉 ¡Correcto! El número era {numero_secreto}")
        print(f"Lo has adivinado en {intentos_realizados} intentos")
    elif intento < numero_secreto:
        print("📈 Demasiado bajo. Intenta un número más alto.")
    else:
        print("📉 Demasiado alto. Intenta un número más bajo.")
    
    print()

# Mensaje final
if not adivinado:
    print(f"❌ Se acabaron los intentos. El número era {numero_secreto}")

print("Gracias por jugar")

¡Ahora tienes el poder de crear bucles que se ejecutan mientras una condición sea verdadera! En el próximo capítulo, aprenderás técnicas avanzadas para controlar el flujo de tus bucles.


🧭 Navegación:

Capítulos de esta sección: