Fundamentos del Control de Flujo

Fundamentos del Control de Flujo

  • El control de flujo es el conjunto de estructuras que determinan el orden en que se ejecutan las instrucciones de un programa.
  • Por defecto, Python ejecuta las declaraciones secuencialmente, una tras otra, desde la primera hasta la última línea del código.
# Ejecución secuencial
x = 5
y = 3
resultado = x + y
print(resultado)
## 8

Fundamentos del Control de Flujo

No obstante, la mayoría de los programas necesitan:

  • Tomar decisiones según los datos que procesan.
  • Repetir ciertas acciones varias veces.
  • Alterar o interrumpir el curso normal de ejecución.

Principales estructuras de control de flujo

En Python, las estructuras de control permiten modificar ese orden lineal de tres formas esenciales:

  • Condicionales: seleccionar qué bloque de código ejecutar dependiendo de si una condición se cumple o no.
  • Bucles (iteración): ejecutar un mismo bloque de código múltiples veces, ya sea un número definido de repeticiones o mientras se mantenga cierta condición.
  • Transferencia de control: cambiar el flujo dentro de un bucle, ya sea para detenerlo antes de tiempo o para saltar a la siguiente iteración.

Valores Logicos

# Los dos valores lógicos fundamentales
verdadero = True
falso = False

# Verificar su clase
print(type(True))   # <class 'bool'>
## <class 'bool'>
print(type(False))   # <class 'bool'>
## <class 'bool'>
# En Python no hay T ni F, solo se usa True y False
tambien_verdadero = True
tambien_falso = False

Operadores de Comparacion

Igualdad y Desigualdad

# Operador de igualdad (==)
print(5 == 5)   # True
## True
print(5 == 3)   # False
## False
print("hola" == "hola")   # True
## True
print("Hola" == "hola")   # False
## False
# Operador de desigualdad (!=)
print(5 != 3)   # True
## True
print(5 != 5)   # False
## False
print("gato" != "perro")   # True
## True

Operadores de Comparacion

# Mayor que (>)
print(10 > 5)   # True
## True
print(3 > 8)    # False
## False
# Menor que (<)
print(2 < 7)    # True
## True
print(9 < 4)    # False
## False
# Mayor o igual que (>=)
print(5 >= 5)   # True
## True
print(5 >= 3)   # True
## True
print(2 >= 6)   # False
## False
# Menor o igual que (<=)
print(4 <= 4)   # True
## True
print(3 <= 7)   # True
## True
print(8 <= 2)   # False
## False

Operadores de comparacion

edad = 25
limite = 18

# Comparaciones con variables
print(edad > limite)    # True
## True
print(edad == limite)   # False
## False
print(edad >= limite)   # True
## True
precio = 150.00
descuento_minimo = 100.00
print(precio >= descuento_minimo)   # True
## True

Operadores Logicos

El operador AND(and)

El operador and devuelve True solo si ambas condiciones son verdaderas

# Tabla de verdad del operador and
print(True and True)    # True
## True
print(True and False)   # False
## False
print(False and True)   # False
## False
print(False and False)  # False
## False
# Ejemplo práctico
edad = 25
tiene_licencia = True

# ¿Puede alquilar un auto? (debe ser mayor de 21 Y tener licencia)
puede_alquilar = (edad >= 21) and tiene_licencia
print(puede_alquilar)   # True
## True

Valores logicos

El operador OR(or)

El operador or devuelve True si al menos una de las condiciones es verdadera

# Tabla de verdad del operador or
print(True or True)     # True
## True
print(True or False)    # True
## True
print(False or True)    # True
## True
print(False or False)   # False
## False
# Ejemplo práctico
es_estudiante = False
es_senior = True

# ¿Tiene descuento? (si es estudiante O es senior)
tiene_descuento = es_estudiante or es_senior
print(tiene_descuento)   # True
## True

Operadores logicos

Operador NOT(not)

El operador not invierte el valor lógico

# El operador NOT
print(not True)   # False
## False
print(not False)  # True
## True
# Ejemplo práctico
esta_lloviendo = False
salir_sin_paraguas = not esta_lloviendo
print(salir_sin_paraguas)   # True
## True

Operadores logicos

Combinaciones complejas

# Múltiples condiciones combinadas
temperatura = 22
esta_soleado = True
es_fin_de_semana = True

# ¿Es buen día para un fútbol?
buen_dia_futbol = (temperatura >= 20) and esta_soleado and es_fin_de_semana
print(buen_dia_futbol)   # True
## True
# Usando paréntesis para claridad
nota1 = 85
nota2 = 78
asistencia = 95

aprobado = ((nota1 >= 70) and (nota2 >= 70)) and (asistencia >= 80)
print(aprobado)   # True
## True

Estructuras Condicionales

Estructura condicionales

La declaracion if

Estructura Gneral

# if condicion:
    # código a ejecutar si la condición es True

Ejemplo

temperatura = 30

if temperatura > 25:
    print("Hace calor hoy")
## Hace calor hoy

Verificación edad

edad = 18

if edad >= 18:
    print("Puedes votar en las elecciones")
    print("También puedes obtener una licencia de conducir")
## Puedes votar en las elecciones
## También puedes obtener una licencia de conducir

Control de inventario

stock = 25
stock_minimo = 10

if stock < stock_minimo:
    print("¡ALERTA! Stock bajo - necesita reabastecimiento")
    urgente = True

Validacion de datos

salario = 50000

if salario > 0:
    print("Salario válido registrado")
    salario_mensual = salario / 12
    print("Salario mensual:", round(salario_mensual, 2))
## Salario válido registrado
## Salario mensual: 4166.67

Forma compacta

temperatura = 35

# Con indentación (equivalente a "con llaves" en R)
if temperatura > 30:
    print("Día muy caluroso")
## Día muy caluroso
# En una sola línea (equivalente a "sin llaves" en R, pero poco usado)
if temperatura > 30: print("Día muy caluroso")
## Día muy caluroso

Nota importante:

es_viernes = True

if es_viernes:
    print("¡Por fin viernes!")
    preparar_fin_de_semana = True
    revisar_agenda_lunes = True
## ¡Por fin viernes!
es_viernes = True

# INCORRECTO: solo la primera línea depende del if
if es_viernes:
    print("¡Por fin viernes!")
## ¡Por fin viernes!
preparar_fin_de_semana = True   # Esta línea SIEMPRE se ejecuta

Casos de Uso

nivel_bateria = 15

if nivel_bateria <= 20:
    print("ADVERTENCIA: Batería baja")
    if nivel_bateria <= 10:
        print("CRÍTICO: Conectar cargador inmediatamente")
        modo_ahorro_energia = True
## ADVERTENCIA: Batería baja

Procesamiento Condicional de Datos

import numpy as np

datos_usuario = np.array([23, 45, 67, np.nan, 89, 12])

if np.any(np.isnan(datos_usuario)):
    print("Detectados valores faltantes en los datos")
    
    # Contar valores faltantes
    valores_na = np.sum(np.isnan(datos_usuario))
    print("Número de valores NA:", valores_na)
    
    # Crear versión limpia de los datos (sin NA)
    datos_limpios = datos_usuario[~np.isnan(datos_usuario)]
    print("Datos limpios:", ", ".join(map(str, datos_limpios.astype(int))))
## Detectados valores faltantes en los datos
## Número de valores NA: 1
## Datos limpios: 23, 45, 67, 89, 12

Validacion de Entrada de Usuario

entrada = "25"

# Verificar si la entrada es una cadena
if isinstance(entrada, str):
    try:
        # Intentar convertir a número
        numero = float(entrada)
        print("Conversión exitosa:", numero)

        # Si es positivo, calcular raíz cuadrada
        if numero >= 0:
            print("Número válido y positivo")
            resultado = numero ** 0.5
            print("Raíz cuadrada:", round(resultado, 2))
    except ValueError:
        # Si no se puede convertir a número
        pass
## Conversión exitosa: 25.0
## Número válido y positivo
## Raíz cuadrada: 5.0

Declaraciones else

Declaraciones else

Estructura General

# if condicion:
    # código si la condición es True
# else:
    # código si la condición es False

Ejemplo

edad = 16

if edad >= 18:
    print("Eres mayor de edad")
    print("Puedes votar")
else:
    print("Eres menor de edad")
    print("Aún no puedes votar")
## Eres menor de edad
## Aún no puedes votar

if-else para Asignar Valores

Método 1: Asignacion Dentro de Cada Bloque

nota = 75

if nota >= 70:
    resultado = "Aprobado"
    mensaje = "¡Felicitaciones!"
else:
    resultado = "Reprobado"
    mensaje = "Necesitas estudiar más"

print(resultado)
## Aprobado
print(mensaje)
## ¡Felicitaciones!

Método 2: Asignacion del Resultado Completo

nota = 65
estado = "Aprobado" if nota >= 70 else "Reprobado"
print(estado)  # "Reprobado"
## Reprobado
# También funciona con cálculos más complejos
precio_base = 100
es_miembro = True

precio_final = precio_base * 0.9 if es_miembro else precio_base
print(precio_final)  # 90
## 90.0

Sistema de Calificacion de Crédito

puntaje_credito = 650

if puntaje_credito >= 700:
    categoria = "Excelente"
    tasa_interes = 3.5
    limite_credito = 50000
    aprobacion_automatica = True
else:
    categoria = "Regular"
    tasa_interes = 8.5
    limite_credito = 15000
    aprobacion_automatica = False

print("Categoría:", categoria)  
## Categoría: Regular
print("Tasa de interés:", tasa_interes, "%")  
## Tasa de interés: 8.5 %
print("Límite de crédito: $", limite_credito)  
## Límite de crédito: $ 15000
print("Aprobación automática:", aprobacion_automatica)  
## Aprobación automática: False

Calculadora de Descuentos

monto_compra = 150
descuento_aplicado = 0

if monto_compra >= 100:
    descuento_aplicado = monto_compra * 0.15  # 15% de descuento
    tipo_descuento = "Compra Mayor"
    puntos_ganados = monto_compra * 2  # Doble puntos
else:
    descuento_aplicado = 0
    tipo_descuento = "Sin descuento"
    puntos_ganados = monto_compra  # Puntos normales

monto_final = monto_compra - descuento_aplicado

print("Monto original: $", monto_compra)
## Monto original: $ 150
print("Descuento aplicado: $", descuento_aplicado)
## Descuento aplicado: $ 22.5
print("Tipo de descuento:", tipo_descuento)
## Tipo de descuento: Compra Mayor
print("Puntos ganados:", puntos_ganados)
## Puntos ganados: 300
print("Monto final: $", monto_final)
## Monto final: $ 127.5

Sistema de Recomenación de Ropa

temperatura = 18
precipitacion = 0  # mm de lluvia

if temperatura >= 25:
    ropa_recomendada = "Camiseta y pantalón corto"
    accesorios = ["gorra", "lentes de sol"]
    calzado = "sandalias o tenis ligeros"
else:
    ropa_recomendada = "Suéter y pantalón largo"
    accesorios = ["bufanda", "guantes"]
    calzado = "zapatos cerrados"

# Verificar lluvia independientemente de la temperatura
if precipitacion > 0:
    accesorios.extend(["paraguas", "impermeable"])
    calzado = "botas impermeables"

print("Ropa recomendada:", ropa_recomendada)
## Ropa recomendada: Suéter y pantalón largo
print("Accesorios:", ", ".join(accesorios))
## Accesorios: bufanda, guantes
print("Calzado:", calzado)
## Calzado: zapatos cerrados

Validación y Manejo de Errores

dividendo = 10
divisor = 3

if divisor != 0:
    resultado = dividendo / divisor
    print("El resultado de", dividendo, "÷", divisor, "es:", round(resultado, 2))
else:
    print("Error: No se puede dividir por cero")
    resultado = None  # En Python se usa None en lugar de NA
## El resultado de 10 ÷ 3 es: 3.33

Validacion de Tipos de Datos

entrada_usuario = "123"

# Verificar si el objeto es numérico (int o float)
if isinstance(entrada_usuario, (int, float)):
    print("Entrada válida: es un número")
    numero_procesado = entrada_usuario * 2
    print("Resultado:", numero_procesado)
else:
    print("Entrada inválida: no es un número")
    try:
      # Intentar convertir
        numero_convertido = float(entrada_usuario)  
        print("Conversión exitosa")
        numero_procesado = numero_convertido * 2
        print("Resultado:", int(numero_procesado))
    except ValueError:
        print("No se pudo convertir a número")
        numero_procesado = 0
## Entrada inválida: no es un número
## Conversión exitosa
## Resultado: 246

Sistema de Autenticación Básico

from datetime import datetime

usuario_ingresado = "admin"
password_ingresado = "12345"

# Credenciales correctas (en un sistema real, estarían encriptadas)
usuario_correcto = "admin"
password_correcto = "admin123"

if usuario_ingresado == usuario_correcto and password_ingresado == password_correcto:
    print("Acceso concedido")
    sesion_activa = True
    tiempo_sesion = datetime.now()
    permisos = ["leer", "escribir", "administrar"]

    print("Bienvenido,", usuario_correcto)
    print("Hora de inicio de sesión:", tiempo_sesion)

else:
    print("Acceso denegado: credenciales incorrectas")
    sesion_activa = False
    intentos_fallidos = 1  # En un sistema real, incrementarías un contador

    # Determinar qué falló
    if usuario_ingresado != usuario_correcto:
        print("Usuario incorrecto")

    if password_ingresado != password_correcto:
        print("Contraseña incorrecta")
## Acceso denegado: credenciales incorrectas
## Contraseña incorrecta

Múltiples Condiciones con if-else if-else

La función if-else if

Estructura General

# if primera_condicion:
#     # código para primera condición
# elif segunda_condicion:
#     # código para segunda condición
# elif tercera_condicion:
#     # código para tercera condición
# else:
#     # código para cuando ninguna condición anterior es verdadera

Ejemplo

nota = 85

if nota >= 90:
    calificacion = "A"
    comentario = "Excelente trabajo"
elif nota >= 80:  # Solo se evalúa si nota < 90
    calificacion = "B"
    comentario = "Muy buen trabajo"
elif nota >= 70:  # Solo se evalúa si nota < 80
    calificacion = "C"
    comentario = "Trabajo satisfactorio"
elif nota >= 60:  # Solo se evalúa si nota < 70
    calificacion = "D"
    comentario = "Necesita mejorar"
else:  # Solo se ejecuta si nota < 60
    calificacion = "F"
    comentario = "Debe repetir el curso"

print("Calificación:", calificacion)
## Calificación: B
print(comentario)
## Muy buen trabajo

La Importancia del Orden

numero = 75

# CORRECTO: de mayor a menor
if numero >= 90:
    categoria = "Muy alto"
elif numero >= 70:  # 75 >= 70 es True, se ejecuta aquí
    categoria = "Alto"  # Resultado correcto
elif numero >= 50:
    categoria = "Medio"  # Ya no se evalúa
else:
    categoria = "Bajo"

print(categoria)  # "Alto"
## Alto
# NCORRECTO: de menor a mayor
if numero >= 50:  # 75 >= 50 es True, se ejecuta aquí
    categoria_mala = "Medio"  # Resultado incorrecto
elif numero >= 70:
    categoria_mala = "Alto"  # Nunca se ejecuta
elif numero >= 90:
    categoria_mala = "Muy alto"  # Nunca se ejecuta

print(categoria_mala)  # "Medio"
## Medio

Sistema de Clasificación de IMC

# Datos
peso = 70  # kg
altura = 1.75  # metros

# Cálculo de IMC
imc = peso / (altura ** 2)

# Clasificación con condicionales
if imc < 18.5:
    categoria = "Bajo peso"
    recomendacion = "Consulte con un nutricionista para ganar peso saludablemente"
    color_alerta = "azul"
elif imc < 25:
    categoria = "Peso normal"
    recomendacion = "Mantenga su estilo de vida saludable"
    color_alerta = "verde"
elif imc < 30:
    categoria = "Sobrepeso"
    recomendacion = "Considere aumentar la actividad física y mejorar la dieta"
    color_alerta = "amarillo"
elif imc < 35:
    categoria = "Obesidad clase I"
    recomendacion = "Consulte con un médico para un plan de pérdida de peso"
    color_alerta = "naranja"
elif imc < 40:
    categoria = "Obesidad clase II"
    recomendacion = "Es importante consultar con un médico especialista"
    color_alerta = "rojo"
else:
    categoria = "Obesidad clase III (mórbida)"
    recomendacion = "Consulte urgentemente con un médico especialista"
    color_alerta = "rojo_intenso"

# Mostrar resultados
print(f"IMC: {imc:.2f}")
## IMC: 22.86
print(f"Categoría: {categoria}")
## Categoría: Peso normal
print(f"Recomendación: {recomendacion}")
## Recomendación: Mantenga su estilo de vida saludable
print(f"Nivel de alerta: {color_alerta}")
## Nivel de alerta: verde

Sistema de Tarifas Progresivas

# Consumo en kWh
consumo_kwh = 250  # kilowatts-hora consumidos

# Cálculo del costo según la tarifa progresiva
if consumo_kwh <= 100:
    # Tarifa básica: primeros 100 kWh
    tarifa = 0.12
    costo = consumo_kwh * tarifa
    tipo_usuario = "Básico"

elif consumo_kwh <= 200:
    # Tarifa intermedia: de 101 a 200 kWh
    costo_basico = 100 * 0.12
    consumo_intermedio = consumo_kwh - 100
    costo_intermedio = consumo_intermedio * 0.18
    costo = costo_basico + costo_intermedio
    tipo_usuario = "Intermedio"

elif consumo_kwh <= 300:
    # Tarifa alta: de 201 a 300 kWh
    costo_basico = 100 * 0.12
    costo_intermedio = 100 * 0.18
    consumo_alto = consumo_kwh - 200
    costo_alto = consumo_alto * 0.25
    costo = costo_basico + costo_intermedio + costo_alto
    tipo_usuario = "Alto"

else:
    # Tarifa muy alta: más de 300 kWh
    costo_basico = 100 * 0.12
    costo_intermedio = 100 * 0.18
    costo_alto = 100 * 0.25
    consumo_muy_alto = consumo_kwh - 300
    costo_muy_alto = consumo_muy_alto * 0.32
    costo = costo_basico + costo_intermedio + costo_alto + costo_muy_alto
    tipo_usuario = "Muy Alto"

# Resultados
print(f"Consumo: {consumo_kwh} kWh")
## Consumo: 250 kWh
print(f"Tipo de usuario: {tipo_usuario}")
## Tipo de usuario: Alto
print(f"Costo total: ${costo:.2f}")
## Costo total: $42.50
print(f"Precio promedio por kWh: ${costo/consumo_kwh:.4f}")
## Precio promedio por kWh: $0.1700

Sistema de Evaluacion Academica Complejo

# Datos del estudiante
nota_examenes = 85
nota_tareas = 78
asistencia = 95
participacion = 88
proyecto_final = 92

# Cálculo de nota ponderada
nota_final = (nota_examenes * 0.4) + (nota_tareas * 0.25) + \
             (asistencia * 0.1) + (participacion * 0.1) + \
             (proyecto_final * 0.15)

# Determinar calificación
if nota_final >= 95:
    letra = "A+"
    puntos = 4.0
    descripcion = "Excelencia sobresaliente"
    mencion = "Suma Cum Laude"
elif nota_final >= 90:
    letra = "A"
    puntos = 4.0
    descripcion = "Excelente desempeño"
    mencion = "Magna Cum Laude"
elif nota_final >= 87:
    letra = "A-"
    puntos = 3.7
    descripcion = "Muy buen desempeño"
    mencion = "Cum Laude"
elif nota_final >= 83:
    letra = "B+"
    puntos = 3.3
    descripcion = "Buen desempeño superior"
    mencion = "Sin mención especial"
elif nota_final >= 80:
    letra = "B"
    puntos = 3.0
    descripcion = "Buen desempeño"
    mencion = "Sin mención especial"
elif nota_final >= 77:
    letra = "B-"
    puntos = 2.7
    descripcion = "Desempeño satisfactorio superior"
    mencion = "Sin mención especial"
elif nota_final >= 73:
    letra = "C+"
    puntos = 2.3
    descripcion = "Desempeño satisfactorio"
    mencion = "Sin mención especial"
elif nota_final >= 70:
    letra = "C"
    puntos = 2.0
    descripcion = "Desempeño mínimo aceptable"
    mencion = "Sin mención especial"
elif nota_final >= 65:
    letra = "D"
    puntos = 1.0
    descripcion = "Desempeño deficiente"
    mencion = "Requiere recuperación"
else:
    letra = "F"
    puntos = 0.0
    descripcion = "Desempeño insuficiente"
    mencion = "Debe repetir el curso"

# Modificadores por asistencia
if asistencia < 75:
    mencion = f"{mencion} - BAJA ASISTENCIA"
    if puntos > 0:
        puntos -= 0.5  # Penalización

# Reporte académico
print("=== REPORTE ACADÉMICO ===")
## === REPORTE ACADÉMICO ===
print(f"Nota final: {round(nota_final, 2)}")
## Nota final: 85.6
print(f"Calificación: {letra}")
## Calificación: B+
print(f"Puntos GPA: {puntos}")
## Puntos GPA: 3.3
print(f"Descripción: {descripcion}")
## Descripción: Buen desempeño superior
print(f"Mención: {mencion}")
## Mención: Sin mención especial
print("========================")
## ========================

Sistema de Clasificación Meteorológica

# Datos climáticos
temperatura = 22
humedad = 65
velocidad_viento = 15  # km/h
precipitacion = 2      # mm

# Clasificación principal por temperatura
if temperatura < -10:
    clima_base = "Extremadamente frío"
    actividades = "Permanecer en interiores"
elif temperatura < 0:
    clima_base = "Muy frío"
    actividades = "Deportes de invierno, ropa térmica"
elif temperatura < 10:
    clima_base = "Frío"
    actividades = "Caminatas con abrigo, actividades interiores"
elif temperatura < 20:
    clima_base = "Fresco"
    actividades = "Senderismo, actividades al aire libre con chaqueta"
elif temperatura < 25:
    clima_base = "Templado"
    actividades = "Ideal para todas las actividades al aire libre"
elif temperatura < 30:
    clima_base = "Cálido"
    actividades = "Playa, piscina, deportes acuáticos"
elif temperatura < 35:
    clima_base = "Caluroso"
    actividades = "Actividades acuáticas, evitar ejercicio intenso"
else:
    clima_base = "Extremadamente caluroso"
    actividades = "Permanecer en interiores con aire acondicionado"

# Mostrar resultados
print("=== CLIMA Y ACTIVIDADES ===")
## === CLIMA Y ACTIVIDADES ===
print(f"Temperatura: {temperatura}°C")
## Temperatura: 22°C
print(f"Humedad: {humedad}%")
## Humedad: 65%
print(f"Viento: {velocidad_viento} km/h")
## Viento: 15 km/h
print(f"Precipitación: {precipitacion} mm")
## Precipitación: 2 mm
print(f"Clima base: {clima_base}")
## Clima base: Templado
print(f"Actividades recomendadas: {actividades}")
## Actividades recomendadas: Ideal para todas las actividades al aire libre

Istalacion de librerias de Python necesarias

library(reticulate)
## Warning: package 'reticulate' was built under R version 4.5.1
# Añadir numpy y pandas al entorno actual
py_require(c("numpy", "pandas"))

ifelse en Python

En R, ifelse() es una función que permite aplicar una condición a cada elemento de un vector.

En Python, no existe directamente ifelse(), pero tenemos dos maneras principales de hacerlo:

import pandas as pd

# Vector de números
numeros = [-3, -1, 0, 2, 5, -7, 8]

# Usando comprensión de listas
signos = ["No negativo" if n >= 0 else "Negativo" for n in numeros]

resultado = pd.DataFrame({"numero": numeros, "signo": signos})
print("Resultado usando comprensión de listas:")
## Resultado usando comprensión de listas:
print(resultado)
##    numero        signo
## 0      -3     Negativo
## 1      -1     Negativo
## 2       0  No negativo
## 3       2  No negativo
## 4       5  No negativo
## 5      -7     Negativo
## 6       8  No negativo
import numpy as np
import pandas as pd

# Vector de números
numeros = np.array([-3, -1, 0, 2, 5, -7, 8])

# Usando numpy.where (igual a ifelse en R)
signos = np.where(numeros >= 0, "No negativo", "Negativo")

resultado = pd.DataFrame({"numero": numeros, "signo": signos})
print("\nResultado usando numpy.where:")
## 
## Resultado usando numpy.where:
print(resultado)
##    numero        signo
## 0      -3     Negativo
## 1      -1     Negativo
## 2       0  No negativo
## 3       2  No negativo
## 4       5  No negativo
## 5      -7     Negativo
## 6       8  No negativo

Comparación con Métodos Alternativos

# Método con bucle
numeros = [-3, -1, 0, 2, 5, -7, 8]
signos_bucle = [""] * len(numeros)

for i in range(len(numeros)):
    if numeros[i] >= 0:
        signos_bucle[i] = "No negativo"
    else:
        signos_bucle[i] = "Negativo"

# Método con comprensión de listas
signos = ["No negativo" if n >= 0 else "Negativo" for n in numeros]

# Comparación como en R
print(signos == signos_bucle)  
## True

Método vectorizado con np.where (más rápido)

import numpy as np

# Vector de números
numeros = np.array([-3, -1, 0, 2, 5, -7, 8])

# Método vectorizado similar a ifelse
signos_ifelse = np.where(numeros >= 0, "No negativo", "Negativo")

# Comparación con el método con bucle (suponiendo que ya existe 'signos_bucle')
# signos_bucle = [...]  # tu lista creada con bucle
print(np.array_equal(signos_bucle, signos_ifelse))  # True si son iguales
## True

Clasificacion de Estudiantes

# Clasificación de Estudiantes

import numpy as np
import pandas as pd

# Datos de estudiantes
estudiantes = ["Ana", "Pedro", "Luis", "María", "Carlos", "Sofia", "Diego", "Laura"]
notas = [95, 67, 82, 88, 45, 91, 73, 79]

# Clasificación simple: Aprobado/Reprobado
estado = np.where(np.array(notas) >= 70, "Aprobado", "Reprobado")

# Crear DataFrame con resultados
reporte_estudiantes = pd.DataFrame({
    "nombre": estudiantes,
    "nota": notas,
    "estado": estado
})

print(reporte_estudiantes)
##    nombre  nota     estado
## 0     Ana    95   Aprobado
## 1   Pedro    67  Reprobado
## 2    Luis    82   Aprobado
## 3   María    88   Aprobado
## 4  Carlos    45  Reprobado
## 5   Sofia    91   Aprobado
## 6   Diego    73   Aprobado
## 7   Laura    79   Aprobado
# Agregar información adicional
reporte_estudiantes["necesita_recuperacion"] = np.where(reporte_estudiantes["nota"] < 70, "Sí", "No")
reporte_estudiantes["excelencia"] = np.where(reporte_estudiantes["nota"] >= 90, "Excelente", "Regular")

print(reporte_estudiantes)
##    nombre  nota     estado necesita_recuperacion excelencia
## 0     Ana    95   Aprobado                    No  Excelente
## 1   Pedro    67  Reprobado                    Sí    Regular
## 2    Luis    82   Aprobado                    No    Regular
## 3   María    88   Aprobado                    No    Regular
## 4  Carlos    45  Reprobado                    Sí    Regular
## 5   Sofia    91   Aprobado                    No  Excelente
## 6   Diego    73   Aprobado                    No    Regular
## 7   Laura    79   Aprobado                    No    Regular

Condicionales anidados con np.where para múltiples categorías

import numpy as np
import pandas as pd

# Datos de ejemplo
edades = np.array([5, 12, 15, 18, 25, 35, 45, 55, 65, 75, 85])

# Clasificación de edades con np.where anidado
categorias = np.where(edades < 13, "Niño",
             np.where(edades < 18, "Adolescente",
             np.where(edades < 25, "Joven adulto",
             np.where(edades < 65, "Adulto", "Adulto mayor"))))

# Crear DataFrame con resultados
clasificacion_edades = pd.DataFrame({
    "edad": edades,
    "categoria": categorias
})

print(clasificacion_edades)
##     edad     categoria
## 0      5          Niño
## 1     12          Niño
## 2     15   Adolescente
## 3     18  Joven adulto
## 4     25        Adulto
## 5     35        Adulto
## 6     45        Adulto
## 7     55        Adulto
## 8     65  Adulto mayor
## 9     75  Adulto mayor
## 10    85  Adulto mayor
# Agregar recomendaciones especificas
recomendaciones = np.where(edades < 13, "Educación primaria y juegos",
                  np.where(edades < 18, "Educación secundaria",
                  np.where(edades < 25, "Educación superior o trabajo",
                  np.where(edades < 65, "Vida laboral activa", "Jubilación y cuidados"))))
  
clasificacion_edades["recomendacion"] = recomendaciones
print(clasificacion_edades)
##     edad     categoria                 recomendacion
## 0      5          Niño   Educación primaria y juegos
## 1     12          Niño   Educación primaria y juegos
## 2     15   Adolescente          Educación secundaria
## 3     18  Joven adulto  Educación superior o trabajo
## 4     25        Adulto           Vida laboral activa
## 5     35        Adulto           Vida laboral activa
## 6     45        Adulto           Vida laboral activa
## 7     55        Adulto           Vida laboral activa
## 8     65  Adulto mayor         Jubilación y cuidados
## 9     75  Adulto mayor         Jubilación y cuidados
## 10    85  Adulto mayor         Jubilación y cuidados

Sistema de Calificación Académica

# Sistema de Calificación Académica
import numpy as np
import pandas as pd

# Datos de calificaciones
materias = ["Matemáticas", "Ciencias", "Historia", "Literatura", "Arte", "Deportes"]
puntuaciones = np.array([95, 78, 85, 92, 68, 88])

# Sistema de calificación con letras
calificaciones_letra = np.where(puntuaciones >= 95, "A+",
                     np.where(puntuaciones >= 90, "A",
                     np.where(puntuaciones >= 85, "B+",
                     np.where(puntuaciones >= 80, "B",
                     np.where(puntuaciones >= 75, "C+",
                     np.where(puntuaciones >= 70, "C", "F"))))))

# Determinar estado
estado_materia = np.where(puntuaciones >= 70, "Aprobada", "Reprobada")

# Calcular puntos GPA
puntos_gpa = np.where(puntuaciones >= 95, 4.0,
             np.where(puntuaciones >= 90, 4.0,
             np.where(puntuaciones >= 85, 3.5,
             np.where(puntuaciones >= 80, 3.0,
             np.where(puntuaciones >= 75, 2.5,
             np.where(puntuaciones >= 70, 2.0, 0.0))))))

# Crear reporte completo
reporte_academico = pd.DataFrame({
    "materia": materias,
    "puntuacion": puntuaciones,
    "letra": calificaciones_letra,
    "estado": estado_materia,
    "gpa": puntos_gpa
})

print(reporte_academico)
##        materia  puntuacion letra     estado  gpa
## 0  Matemáticas          95    A+   Aprobada  4.0
## 1     Ciencias          78    C+   Aprobada  2.5
## 2     Historia          85    B+   Aprobada  3.5
## 3   Literatura          92     A   Aprobada  4.0
## 4         Arte          68     F  Reprobada  0.0
## 5     Deportes          88    B+   Aprobada  3.5
# Calcular estadísticas generales
promedio_general = np.mean(puntuaciones)
gpa_general = np.mean(puntos_gpa)
materias_aprobadas = np.sum(puntuaciones >= 70)
materias_reprobadas = np.sum(puntuaciones < 70)

print(f"Promedio general: {promedio_general:.2f}")
## Promedio general: 84.33
print(f"GPA general: {gpa_general:.2f}")
## GPA general: 2.92
print(f"Materias aprobadas: {materias_aprobadas}")
## Materias aprobadas: 5
print(f"Materias reprobadas: {materias_reprobadas}")
## Materias reprobadas: 1

Análisis de Ventas por Trimestre

import numpy as np
import pandas as pd

# Datos de ventas mensuales
meses = ["Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio",
         "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"]
ventas = np.array([45000, 52000, 48000, 55000, 62000, 58000,
                   71000, 68000, 59000, 63000, 75000, 82000])

# Meta mensual
meta_mensual = 60000

# Evaluación de rendimiento
rendimiento = np.where(ventas >= meta_mensual * 1.2, "Excepcional",
                np.where(ventas >= meta_mensual, "Cumplió meta",
                np.where(ventas >= meta_mensual * 0.8, "Cerca de meta", "Bajo rendimiento")))

# Bonificación
bonificacion = np.where(ventas >= meta_mensual * 1.2, ventas * 0.05,
                np.where(ventas >= meta_mensual, ventas * 0.03, 0))

# Trimestres
trimestre = np.where(np.isin(meses, ["Enero", "Febrero", "Marzo"]), "Q1",
             np.where(np.isin(meses, ["Abril", "Mayo", "Junio"]), "Q2",
             np.where(np.isin(meses, ["Julio", "Agosto", "Septiembre"]), "Q3", "Q4")))

# Crear reporte de ventas
reporte_ventas = pd.DataFrame({
    "mes": meses,
    "trimestre": trimestre,
    "ventas": ventas,
    "meta": meta_mensual,
    "rendimiento": rendimiento,
    "bonificacion": bonificacion
})

print(reporte_ventas)
##            mes trimestre  ventas   meta       rendimiento  bonificacion
## 0        Enero        Q1   45000  60000  Bajo rendimiento           0.0
## 1      Febrero        Q1   52000  60000     Cerca de meta           0.0
## 2        Marzo        Q1   48000  60000     Cerca de meta           0.0
## 3        Abril        Q2   55000  60000     Cerca de meta           0.0
## 4         Mayo        Q2   62000  60000      Cumplió meta        1860.0
## 5        Junio        Q2   58000  60000     Cerca de meta           0.0
## 6        Julio        Q3   71000  60000      Cumplió meta        2130.0
## 7       Agosto        Q3   68000  60000      Cumplió meta        2040.0
## 8   Septiembre        Q3   59000  60000     Cerca de meta           0.0
## 9      Octubre        Q4   63000  60000      Cumplió meta        1890.0
## 10   Noviembre        Q4   75000  60000       Excepcional        3750.0
## 11   Diciembre        Q4   82000  60000       Excepcional        4100.0
# Análisis por trimestre

# Sumar ventas por trimestre
ventas_q1 = reporte_ventas.loc[reporte_ventas["trimestre"] == "Q1", "ventas"].sum()
ventas_q2 = reporte_ventas.loc[reporte_ventas["trimestre"] == "Q2", "ventas"].sum()
ventas_q3 = reporte_ventas.loc[reporte_ventas["trimestre"] == "Q3", "ventas"].sum()
ventas_q4 = reporte_ventas.loc[reporte_ventas["trimestre"] == "Q4", "ventas"].sum()

# Imprimir resultados
print(f"Ventas Q1: {ventas_q1}")
## Ventas Q1: 145000
print(f"Ventas Q2: {ventas_q2}")
## Ventas Q2: 175000
print(f"Ventas Q3: {ventas_q3}")
## Ventas Q3: 198000
print(f"Ventas Q4: {ventas_q4}")
## Ventas Q4: 220000

Manejo de Valores Faltantes

# Manejo de valores faltantes en temperaturas
import numpy as np
import pandas as pd

# Datos con valores faltantes
temperaturas = np.array([22, 25, np.nan, 18, 30, np.nan, 15, 28, 24, np.nan])
ciudades = ["Madrid", "Barcelona", "Valencia", "Sevilla", "Bilbao",
            "Málaga", "Zaragoza", "Murcia", "Palma", "Córdoba"]

# Clasificación que maneja valores faltantes
clasificacion_temp = np.where(np.isnan(temperaturas), "Sin datos",
                     np.where(temperaturas >= 25, "Caluroso",
                     np.where(temperaturas >= 20, "Templado", "Frío")))

# Recomendación de ropa
ropa_recomendada = np.where(np.isnan(temperaturas), "Consultar pronóstico",
                     np.where(temperaturas >= 25, "Ropa ligera",
                     np.where(temperaturas >= 20, "Ropa normal", "Abrigo")))

# Crear reporte meteorológico
reporte_clima = pd.DataFrame({
    "ciudad": ciudades,
    "temperatura": temperaturas,
    "clasificacion": clasificacion_temp,
    "ropa": ropa_recomendada
})

print(reporte_clima)
##       ciudad  temperatura clasificacion                  ropa
## 0     Madrid         22.0      Templado           Ropa normal
## 1  Barcelona         25.0      Caluroso           Ropa ligera
## 2   Valencia          NaN     Sin datos  Consultar pronóstico
## 3    Sevilla         18.0          Frío                Abrigo
## 4     Bilbao         30.0      Caluroso           Ropa ligera
## 5     Málaga          NaN     Sin datos  Consultar pronóstico
## 6   Zaragoza         15.0          Frío                Abrigo
## 7     Murcia         28.0      Caluroso           Ropa ligera
## 8      Palma         24.0      Templado           Ropa normal
## 9    Córdoba          NaN     Sin datos  Consultar pronóstico
# Estadísticas excluyendo NaN
temp_validas = temperaturas[~np.isnan(temperaturas)]
print(f"Temperatura promedio: {temp_validas.mean():.1f} °C")
## Temperatura promedio: 23.1 °C
print(f"Ciudades con datos: {np.sum(~np.isnan(temperaturas))}")
## Ciudades con datos: 7
print(f"Ciudades sin datos: {np.sum(np.isnan(temperaturas))}")
## Ciudades sin datos: 3

Uso de match-case en Python (equivalente a la función switch en R)

En Python, no existe la función switch como en R, pero a partir de la versión 3.10 se introdujo la estructura match-case, que cumple el mismo propósito: comparar una variable contra múltiples valores y ejecutar acciones diferentes según el caso. Además, case _ funciona como el valor por defecto. ## Estructura General

# Con nombres (más común)
# match expresion:
#     case "opcion1":
#         resultado = valor1
#     case "opcion2":
#         resultado = valor2
#     case "opcion3":
#         resultado = valor3
#     case _:
#         resultado = valor_por_defecto

# Con posiciones numéricas
# match numero:
#     case 1:
#         resultado = valor1   # posición 1
#     case 2:
#         resultado = valor2   # posición 2
#     case 3:
#         resultado = valor3   # posición 3
#     case _:
#         resultado = valor_por_defecto

Ejemplo

# Determinar el número de días en un mes
mes = "febrero"
año = 2024  # Año bisiesto

match mes:
    case "enero":
        dias_en_mes = 31
    case "febrero":
        # Verificamos si es año bisiesto
        if (año % 4 == 0 and (año % 100 != 0 or año % 400 == 0)):
            dias_en_mes = 29
        else:
            dias_en_mes = 28
    case "marzo":
        dias_en_mes = 31
    case "abril":
        dias_en_mes = 30
    case "mayo":
        dias_en_mes = 31
    case "junio":
        dias_en_mes = 30
    case "julio":
        dias_en_mes = 31
    case "agosto":
        dias_en_mes = 31
    case "septiembre":
        dias_en_mes = 30
    case "octubre":
        dias_en_mes = 31
    case "noviembre":
        dias_en_mes = 30
    case "diciembre":
        dias_en_mes = 31
    case _:
        dias_en_mes = None  # Valor por defecto si el mes no es válido

print(f"{mes} de {año} tiene {dias_en_mes} días")
## febrero de 2024 tiene 29 días
# febrero de 2024 tiene 29 días

Sistema de Días de la Semana

# Sistema de Días de la Semana
# Función para obtener información del día
def obtener_info_dia(dia):
    dia = dia.lower()  # para que sea insensible a mayúsculas/minúsculas
    match dia:
        case "lunes":
            info = {
                "nombre": "Lunes",
                "tipo": "Laboral",
                "actividad": "Comenzar la semana con energía",
                "estado_animo": "Motivado",
                "color": "Azul"
            }
        case "martes":
            info = {
                "nombre": "Martes",
                "tipo": "Laboral",
                "actividad": "Continuar con el ritmo de trabajo",
                "estado_animo": "Concentrado",
                "color": "Verde"
            }
        case "miercoles":
            info = {
                "nombre": "Miércoles",
                "tipo": "Laboral",
                "actividad": "Punto medio de la semana",
                "estado_animo": "Equilibrado",
                "color": "Amarillo"
            }
        case "jueves":
            info = {
                "nombre": "Jueves",
                "tipo": "Laboral",
                "actividad": "Prepararse para el final de semana",
                "estado_animo": "Expectante",
                "color": "Naranja"
            }
        case "viernes":
            info = {
                "nombre": "Viernes",
                "tipo": "Laboral",
                "actividad": "Finalizar tareas y planificar el fin de semana",
                "estado_animo": "Alegre",
                "color": "Rosa"
            }
        case "sabado":
            info = {
                "nombre": "Sábado",
                "tipo": "Fin de semana",
                "actividad": "Relajarse y disfrutar tiempo libre",
                "estado_animo": "Relajado",
                "color": "Púrpura"
            }
        case "domingo":
            info = {
                "nombre": "Domingo",
                "tipo": "Fin de semana",
                "actividad": "Descansar y prepararse para la nueva semana",
                "estado_animo": "Tranquilo",
                "color": "Rojo"
            }
        case _:
            info = {
                "nombre": "Desconocido",
                "tipo": "Inválido",
                "actividad": "Verificar el día ingresado",
                "estado_animo": "Confundido",
                "color": "Gris"
            }
    return info


# Ejemplo de uso
dia_actual = "viernes"
info_dia = obtener_info_dia(dia_actual)
print(f"Día: {info_dia['nombre']}")
## Día: Viernes
print(f"Tipo: {info_dia['tipo']}")
## Tipo: Laboral
print(f"Actividad: {info_dia['actividad']}")
## Actividad: Finalizar tareas y planificar el fin de semana
print(f"Estado de ánimo: {info_dia['estado_animo']}")
## Estado de ánimo: Alegre
print(f"Color asociado: {info_dia['color']}")
## Color asociado: Rosa

Calculadora con match-case

En Python, el match-case funciona de forma similar al switch de R, permitiendo evaluar una expresión contra múltiples casos. Es útil para seleccionar operaciones según el valor de una variable, haciendo el código más limpio que una cadena de if-elif-else.

# Calculadora usando match-case en Python
def calculadora(operacion, a, b):
    # Validar que los operandos sean numéricos
    if not (isinstance(a, (int, float)) and isinstance(b, (int, float))):
        return {"resultado": None, "error": "Los operandos deben ser numéricos"}
    
    match operacion:
        case "suma" | "+":
            resultado = a + b
        case "resta" | "-":
            resultado = a - b
        case "multiplicacion" | "*":
            resultado = a * b
        case "division" | "/":
            if b == 0:
                return {"resultado": None, "error": "División por cero"}
            resultado = a / b
        case "potencia" | "^":
            resultado = a ** b
        case "modulo" | "%":
            resultado = a % b
        case _:
            return {"resultado": None, "error": "Operación no reconocida"}
    
    return {"resultado": resultado, "error": None}


# Ejemplos de uso
print(calculadora("suma", 10, 5))
## {'resultado': 15, 'error': None}
print(calculadora("+", 10, 5))
## {'resultado': 15, 'error': None}
print(calculadora("division", 10, 0))
## {'resultado': None, 'error': 'División por cero'}
print(calculadora("/", 15, 3))
## {'resultado': 5.0, 'error': None}
print(calculadora("potencia", 2, 8))
## {'resultado': 256, 'error': None}
print(calculadora("xyz", 5, 3))  # Operación inválida
## {'resultado': None, 'error': 'Operación no reconocida'}

Sistema de Conversión de Unidades

# Conversor de unidades en Python
def convertir_unidad(valor, de_unidad, a_unidad):
    # Normalizar a minúsculas
    de = de_unidad.lower()
    a = a_unidad.lower()

    # Factores de conversión a metros (unidad base)
    factor_a_metros = {
        "mm": 0.001,
        "cm": 0.01,
        "m": 1,
        "km": 1000,
        "in": 0.0254,
        "ft": 0.3048,
        "yd": 0.9144,
        "mi": 1609.344
    }

    # Factores de conversión desde metros a otra unidad
    factor_de_metros = {
        "mm": 1000,
        "cm": 100,
        "m": 1,
        "km": 0.001,
        "in": 39.3701,
        "ft": 3.28084,
        "yd": 1.09361,
        "mi": 0.000621371
    }

    # Validar unidades
    if de not in factor_a_metros or a not in factor_de_metros:
        return {
            "resultado": None,
            "error": "Unidad no reconocida",
            "unidades_validas": list(factor_a_metros.keys())
        }

    # Conversión a metros
    metros = valor * factor_a_metros[de]

    # Conversión final
    resultado_final = metros * factor_de_metros[a]

    return {
        "valor_original": valor,
        "unidad_original": de_unidad,
        "valor_convertido": round(resultado_final, 6),
        "unidad_final": a_unidad,
        "formula": f"{valor} {de_unidad} = {round(resultado_final, 6)} {a_unidad}"
    }


# Ejemplos de conversión
print(convertir_unidad(100, "cm", "m"))
## {'valor_original': 100, 'unidad_original': 'cm', 'valor_convertido': 1.0, 'unidad_final': 'm', 'formula': '100 cm = 1.0 m'}
print(convertir_unidad(5, "ft", "m"))
## {'valor_original': 5, 'unidad_original': 'ft', 'valor_convertido': 1.524, 'unidad_final': 'm', 'formula': '5 ft = 1.524 m'}
print(convertir_unidad(10, "km", "mi"))
## {'valor_original': 10, 'unidad_original': 'km', 'valor_convertido': 6.21371, 'unidad_final': 'mi', 'formula': '10 km = 6.21371 mi'}
print(convertir_unidad(1, "xyz", "m"))  # Unidad inválida
## {'resultado': None, 'error': 'Unidad no reconocida', 'unidades_validas': ['mm', 'cm', 'm', 'km', 'in', 'ft', 'yd', 'mi']}

Estrucutras Iterativas

Bucles

Los bucles en Python son estructuras que permiten ejecutar un mismo bloque de código varias veces sin necesidad de escribirlo repetidamente. Son muy útiles para automatizar tareas repetitivas, recorrer listas, procesar datos o realizar cálculos múltiples de manera sencilla. Imagina que necesitas saludar a 100 personas. En lugar de escribir print() cien veces, puedes usar un bucle que lo haga por ti.

# Sin bucles (ineficiente e impráctico)
print("Hola persona 1")
## Hola persona 1
print("Hola persona 2")
## Hola persona 2
print("Hola persona 3")
## Hola persona 3
# ... y así hasta la persona 100 

Tipos de Bucles en Python

Python proporciona dos tipos principales de bucles:

  • for: Se usa cuando quieres recorrer una secuencia (lista, cadena, rango, etc.) o sabes exactamente cuántas veces quieres repetir algo.

  • while: Se utiliza cuando quieres repetir mientras una condición sea verdadera.

  • Bucle while True (simulación de repeat): Python no tiene repeat, pero se puede recrear con un while True: y salir manualmente con break.

Conceptos Fundamentales

  • Iteración: Cada vez que el bloque de código se ejecuta dentro del bucle.

  • Variable de Control: Es la variable que cambia en cada iteración y que nos da acceso al valor actual de la secuencia o controla cuándo termina el bucle.

  • Cuerpo del Bucle: El bloque de código que se ejecuta en cada iteración.

Bucles for en Python

Bucles for

Los bucles for son una de las estructuras de control más fundamentales y usadas en programación. * Propósito principal: Automatizar la repetición de tareas de forma controlada y eficiente.

  • Definición: Un bucle for permite iterar (recorrer) sobre una secuencia de elementos. En cada iteración, el bloque de código accede a un elemento distinto de la secuencia.

Características fundamentales:

  • Predictibilidad: Sabemos cuántas iteraciones habrá (si recorremos un range o una lista definida).

  • Control automático: Python avanza automáticamente al siguiente elemento de la secuencia.

  • Flexibilidad: Puede iterar sobre listas, cadenas, rangos, diccionarios, tuplas, etc.

  • Eficiencia: Evita la repetición manual de código y hace el programa más claro y mantenible.

# for variable_iteracion in secuencia:
     # Cuerpo del bucle: código que se ejecuta en cada iteración
     # La variable_iteracion toma el valor de cada elemento de la secuencia

Componentes clave:

  • for → Palabra clave que inicia el bucle.

  • variable_iteracion → Variable que almacena el valor actual en cada iteración.

  • in → Operador que conecta la variable con la secuencia.

  • secuencia → Conjunto de elementos sobre los que se itera (listas, tuplas, cadenas, rangos, etc.).

  • Indentación (sangría) → En lugar de {}, Python usa indentación (espacios o tabulaciones) para definir el cuerpo del bucle. ## Proceso de Ejecución

# Ejemplo en Python: seguimiento paso a paso
numeros = [10, 20, 30]

for numero in numeros:
    resultado = numero * 2
    print(f"Número: {numero} - Doble: {resultado}")
## Número: 10 - Doble: 20
## Número: 20 - Doble: 40
## Número: 30 - Doble: 60
# Proceso interno:
# Iteración 1: numero = 10, resultado = 20, imprime "Número: 10 - Doble: 20"
# Iteración 2: numero = 20, resultado = 40, imprime "Número: 20 - Doble: 40"
# Iteración 3: numero = 30, resultado = 60, imprime "Número: 30 - Doble: 60"
# Fin del bucle

Tipos de Secuencias para Iterar

1. Secuencias Numéricas

# Usando el operador : para crear secuencias
print("=== SECUENCIAS NUMÉRICAS BÁSICAS ===\n")
## === SECUENCIAS NUMÉRICAS BÁSICAS ===
# === SECUENCIAS NUMÉRICAS BÁSICAS ===

# Secuencia ascendente
print("Conteo del 1 al 5:\n")
## Conteo del 1 al 5:
# Conteo del 1 al 5:
for i in range(1, 6):  # range(1,6) genera 1,2,3,4,5
    print(f"Número: {i}")
## Número: 1
## Número: 2
## Número: 3
## Número: 4
## Número: 5
# Número: 1
# Número: 2
# Número: 3
# Número: 4
# Número: 5

# Secuencia descendente
print("\nConteo descendente del 5 al 1:\n")
## 
## Conteo descendente del 5 al 1:
#
# Conteo descendente del 5 al 1:
for i in range(5, 0, -1):  # range(5,0,-1) genera 5,4,3,2,1
    print(f"Número: {i}")
## Número: 5
## Número: 4
## Número: 3
## Número: 2
## Número: 1
# Número: 5
# Número: 4
# Número: 3
# Número: 2
# Número: 1

# Usando step en range() para mayor control
print("\nNúmeros pares del 2 al 10:\n")
## 
## Números pares del 2 al 10:
#
# Números pares del 2 al 10:
for i in range(2, 11, 2):  # desde 2 hasta 10 de 2 en 2
    print(f"Número par: {i}")
## Número par: 2
## Número par: 4
## Número par: 6
## Número par: 8
## Número par: 10
# Número par: 2
# Número par: 4
# Número par: 6
# Número par: 8
# Número par: 10

# Secuencia con decimales
print("\nSecuencia decimal:\n")
## 
## Secuencia decimal:
#
# Secuencia decimal:
for valor in [0.5, 1.0, 1.5, 2.0, 2.5]:
    print(f"Valor: {valor:.1f}")
## Valor: 0.5
## Valor: 1.0
## Valor: 1.5
## Valor: 2.0
## Valor: 2.5
# Valor: 0.5
# Valor: 1.0
# Valor: 1.5
# Valor: 2.0
# Valor: 2.5

2. Vectores de Caracteres

# Iterando sobre texto
print("\n=== PROCESAMIENTO DE TEXTO ===\n")
## 
## === PROCESAMIENTO DE TEXTO ===
#
# === PROCESAMIENTO DE TEXTO ===

# Lista de nombres
estudiantes = ["Ana María", "Pedro José", "Lucía Carmen", "Miguel Ángel"]
print("Lista de estudiantes:\n")
## Lista de estudiantes:
# Lista de estudiantes:
for nombre in estudiantes:
    # Procesar cada nombre
    num_palabras = len(nombre.split(" "))   # divide en palabras por espacio
    num_caracteres = len(nombre)            # cuenta caracteres (incluye espacio)
    print(f"- {nombre}: {num_palabras} palabras, {num_caracteres} caracteres")
## - Ana María: 2 palabras, 9 caracteres
## - Pedro José: 2 palabras, 10 caracteres
## - Lucía Carmen: 2 palabras, 12 caracteres
## - Miguel Ángel: 2 palabras, 12 caracteres
# Días de la semana con información
dias_semana = ["Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado", "Domingo"]
tipos_dia = ["Laboral", "Laboral", "Laboral", "Laboral", "Laboral", "Fin de semana", "Fin de semana"]

print("\nCalendario semanal:\n")
## 
## Calendario semanal:
#
# Calendario semanal:
for i in range(len(dias_semana)):
    dia = dias_semana[i]
    tipo = tipos_dia[i]
    simbolo = "maletin" if tipo == "Laboral" else "fiesta"
    print(f"{simbolo} {dia} - {tipo}")
## maletin Lunes - Laboral
## maletin Martes - Laboral
## maletin Miércoles - Laboral
## maletin Jueves - Laboral
## maletin Viernes - Laboral
## fiesta Sábado - Fin de semana
## fiesta Domingo - Fin de semana

3. Listas Complejas

# Trabajando con estructuras de datos complejas
print("\n=== PROCESAMIENTO DE LISTAS ===\n")
## 
## === PROCESAMIENTO DE LISTAS ===
#
# === PROCESAMIENTO DE LISTAS ===

# Lista de información de empleados
empleados = [
    {
        "nombre": "Carlos Mendoza",
        "departamento": "Ventas",
        "salario": 45000,
        "años_experiencia": 3,
        "certificaciones": ["Ventas Avanzadas", "CRM"]
    },
    {
        "nombre": "María González",
        "departamento": "IT",
        "salario": 65000,
        "años_experiencia": 7,
        "certificaciones": ["Java", "Python", "Scrum Master"]
    },
    {
        "nombre": "Roberto Silva",
        "departamento": "Marketing",
        "salario": 50000,
        "años_experiencia": 5,
        "certificaciones": ["Google Ads", "Analytics", "SEO"]
    }
]

print("=== REPORTE DE EMPLEADOS ===")
## === REPORTE DE EMPLEADOS ===
# === REPORTE DE EMPLEADOS ===

for i, emp in enumerate(empleados, start=1):
    # Calcular información derivada
    salario_mensual = emp["salario"] / 12
    if emp["años_experiencia"] >= 5:
        nivel_experiencia = "Senior"
    elif emp["años_experiencia"] >= 2:
        nivel_experiencia = "Intermedio"
    else:
        nivel_experiencia = "Junior"

    print(f"\n--- EMPLEADO {i} ---")
    print(f"Nombre: {emp['nombre']}")
    print(f"Departamento: {emp['departamento']}")
    print(f"Salario anual: ${emp['salario']:,}")
    print(f"Salario mensual: ${round(salario_mensual):,}")
    print(f"Experiencia: {emp['años_experiencia']} años ({nivel_experiencia})")
    print(f"Certificaciones ({len(emp['certificaciones'])}):")
    for cert in emp["certificaciones"]:
        print(f" • {cert}")
## 
## --- EMPLEADO 1 ---
## Nombre: Carlos Mendoza
## Departamento: Ventas
## Salario anual: $45,000
## Salario mensual: $3,750
## Experiencia: 3 años (Intermedio)
## Certificaciones (2):
##  • Ventas Avanzadas
##  • CRM
## 
## --- EMPLEADO 2 ---
## Nombre: María González
## Departamento: IT
## Salario anual: $65,000
## Salario mensual: $5,417
## Experiencia: 7 años (Senior)
## Certificaciones (3):
##  • Java
##  • Python
##  • Scrum Master
## 
## --- EMPLEADO 3 ---
## Nombre: Roberto Silva
## Departamento: Marketing
## Salario anual: $50,000
## Salario mensual: $4,167
## Experiencia: 5 años (Senior)
## Certificaciones (3):
##  • Google Ads
##  • Analytics
##  • SEO

Procesamiento de Datos Financieros

# Sistema de análisis financiero
print("\n=== ANÁLISIS FINANCIERO TRIMESTRAL ===\n")
## 
## === ANÁLISIS FINANCIERO TRIMESTRAL ===
#
# === ANÁLISIS FINANCIERO TRIMESTRAL ===

# Datos de ventas por trimestre
meses = [
    "Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio",
    "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"
]
ventas_2024 = [125000, 138000, 142000, 156000, 149000, 163000,
               178000, 171000, 165000, 183000, 195000, 210000]
# Metas mensuales progresivas
metas = [120000, 125000, 130000, 135000, 140000, 145000,
         150000, 155000, 160000, 165000, 170000, 175000]

# Variables de análisis
total_ventas = 0
total_metas = 0
meses_exitosos = 0
mejor_mes = ""
mejor_rendimiento = 0

print("REPORTE MENSUAL DETALLADO:")
## REPORTE MENSUAL DETALLADO:
# Encabezado
print(f"{'Mes':<12} {'Ventas':>12} {'Meta':>12} {'Diferencia':>12} {'% Meta':>9} Estado")
## Mes                Ventas         Meta   Diferencia    % Meta Estado
print("-" * 80)
## --------------------------------------------------------------------------------
# Análisis mes a mes
for i in range(len(meses)):
    mes = meses[i]
    venta = ventas_2024[i]
    meta = metas[i]
    diferencia = venta - meta
    porcentaje_meta = (venta / meta) * 100

    # Actualizar totales
    total_ventas += venta
    total_metas += meta

    # Determinar estado
    if venta >= meta:
        meses_exitosos += 1
        estado = "ÉXITO"
    else:
        estado = "Bajo"

    # Buscar mejor rendimiento
    if porcentaje_meta > mejor_rendimiento:
        mejor_rendimiento = porcentaje_meta
        mejor_mes = mes

    # Mostrar resultados
    print(f"{mes:<12} ${venta:>10,} ${meta:>10,} {diferencia:+10,} {porcentaje_meta:9.1f}% {estado}")
## Enero        $   125,000 $   120,000     +5,000     104.2% ÉXITO
## Febrero      $   138,000 $   125,000    +13,000     110.4% ÉXITO
## Marzo        $   142,000 $   130,000    +12,000     109.2% ÉXITO
## Abril        $   156,000 $   135,000    +21,000     115.6% ÉXITO
## Mayo         $   149,000 $   140,000     +9,000     106.4% ÉXITO
## Junio        $   163,000 $   145,000    +18,000     112.4% ÉXITO
## Julio        $   178,000 $   150,000    +28,000     118.7% ÉXITO
## Agosto       $   171,000 $   155,000    +16,000     110.3% ÉXITO
## Septiembre   $   165,000 $   160,000     +5,000     103.1% ÉXITO
## Octubre      $   183,000 $   165,000    +18,000     110.9% ÉXITO
## Noviembre    $   195,000 $   170,000    +25,000     114.7% ÉXITO
## Diciembre    $   210,000 $   175,000    +35,000     120.0% ÉXITO
# Resumen anual
print("-" * 80)
## --------------------------------------------------------------------------------
porcentaje_anual = (total_ventas / total_metas) * 100
superavit_total = total_ventas - total_metas
print(f"{'TOTAL AÑO':<12} ${total_ventas:>10,} ${total_metas:>10,} {superavit_total:+10,} {porcentaje_anual:9.1f}%")
## TOTAL AÑO    $ 1,975,000 $ 1,770,000   +205,000     111.6%
# Resumen ejecutivo
print("\n=== RESUMEN EJECUTIVO ===\n")
## 
## === RESUMEN EJECUTIVO ===
print(f" Total vendido: ${total_ventas:,}")
##  Total vendido: $1,975,000
print(f" Total de metas: ${total_metas:,}")
##  Total de metas: $1,770,000
print(f" Rendimiento anual: {porcentaje_anual:.1f}%")
##  Rendimiento anual: 111.6%
print(f" Meses exitosos: {meses_exitosos} de {len(meses)}")
##  Meses exitosos: 12 de 12
print(f" Mejor mes: {mejor_mes} ({mejor_rendimiento:.1f}% de la meta)")
##  Mejor mes: Diciembre (120.0% de la meta)
if porcentaje_anual >= 100:
    print(" ¡Felicitaciones! Se superaron las metas anuales")
else:
    deficit = total_metas - total_ventas
    print(f" Área de mejora: ${deficit:,} por debajo de la meta")
##  ¡Felicitaciones! Se superaron las metas anuales

Sistema de Gestión Académica

# Procesamiento de calificaciones estudiantiles
print("\n=== SISTEMA DE GESTIÓN ACADÉMICA ===")
## 
## === SISTEMA DE GESTIÓN ACADÉMICA ===
## === SISTEMA DE GESTIÓN ACADÉMICA ===

# Base de datos de estudiantes (usando diccionarios y listas)
estudiantes_db = [
    {
        "nombre": "Ana Rodríguez",
        "id": "EST001",
        "materias": {
            "Matemáticas": {"parcial1": 85, "parcial2": 88, "final": 92, "asistencia": 95},
            "Física": {"parcial1": 78, "parcial2": 82, "final": 85, "asistencia": 90},
            "Química": {"parcial1": 90, "parcial2": 87, "final": 94, "asistencia": 98}
        }
    },
    {
        "nombre": "Pedro Martínez",
        "id": "EST002",
        "materias": {
            "Matemáticas": {"parcial1": 75, "parcial2": 79, "final": 82, "asistencia": 88},
            "Física": {"parcial1": 82, "parcial2": 85, "final": 88, "asistencia": 92},
            "Química": {"parcial1": 77, "parcial2": 80, "final": 83, "asistencia": 85}
        }
    },
    {
        "nombre": "Lucía Fernández",
        "id": "EST003",
        "materias": {
            "Matemáticas": {"parcial1": 92, "parcial2": 94, "final": 96, "asistencia": 100},
            "Física": {"parcial1": 88, "parcial2": 91, "final": 93, "asistencia": 95},
            "Química": {"parcial1": 95, "parcial2": 92, "final": 97, "asistencia": 98}
        }
    }
]

# Función para calcular la nota final
def calcular_nota_final(parcial1, parcial2, final, asistencia):
    # 25% cada parcial, 40% examen final, 10% asistencia
    nota = (parcial1 * 0.25) + (parcial2 * 0.25) + (final * 0.40) + (asistencia * 0.10)
    return round(nota, 2)

# Función para determinar letra, estado y puntos
def obtener_calificacion(nota):
    if nota >= 90:
        return {"letra": "A", "estado": "Excelente", "puntos": 4.0}
    elif nota >= 80:
        return {"letra": "B", "estado": "Bueno", "puntos": 3.0}
    elif nota >= 70:
        return {"letra": "C", "estado": "Satisfactorio", "puntos": 2.0}
    elif nota >= 60:
        return {"letra": "D", "estado": "Mínimo", "puntos": 1.0}
    else:
        return {"letra": "F", "estado": "Reprobado", "puntos": 0.0}

# Procesar todos los estudiantes
print("REPORTE ACADÉMICO DETALLADO")
## REPORTE ACADÉMICO DETALLADO
print("=" * 60)
## ============================================================
for estudiante in estudiantes_db:
    print(f"\n ESTUDIANTE: {estudiante['nombre']} (ID: {estudiante['id']})")
    print("-" * 50)

    total_puntos = 0
    materias_cursadas = 0
    materias_aprobadas = 0

    # Procesar cada materia
    for materia_nombre, materia_data in estudiante["materias"].items():
        # Calcular nota final
        nota_final = calcular_nota_final(
            materia_data["parcial1"],
            materia_data["parcial2"],
            materia_data["final"],
            materia_data["asistencia"]
        )

        # Obtener calificación en letra
        calificacion = obtener_calificacion(nota_final)

        # Actualizar contadores
        materias_cursadas += 1
        total_puntos += calificacion["puntos"]
        if calificacion["puntos"] > 0:
            materias_aprobadas += 1

        # Mostrar detalles
        print(f" {materia_nombre}:")
        print(f"  Parcial 1: {materia_data['parcial1']} | Parcial 2: {materia_data['parcial2']} | "
              f"Final: {materia_data['final']} | Asistencia: {materia_data['asistencia']}%")
        print(f"  → Nota final: {nota_final:.2f} ({calificacion['letra']}) - {calificacion['estado']}")

        # Identificar áreas de mejora
        if nota_final < 80:
            if materia_data["asistencia"] < 90:
                print("   Recomendación: Mejorar asistencia")
            if materia_data["final"] < materia_data["parcial1"] or materia_data["final"] < materia_data["parcial2"]:
                print("   Recomendación: Prepararse mejor para exámenes finales")
        print()

    # Calcular GPA
    gpa = round(total_puntos / materias_cursadas, 2) if materias_cursadas > 0 else 0

    # Determinar estado académico
    if gpa >= 3.5:
        estado_academico = "Lista de Honor"
    elif gpa >= 3.0:
        estado_academico = "Buen Rendimiento"
    elif gpa >= 2.0:
        estado_academico = "Rendimiento Satisfactorio"
    else:
        estado_academico = "Necesita Mejora"

    # Resumen del estudiante
    print(" RESUMEN ACADÉMICO:")
    print(f"  GPA: {gpa:.2f}/4.0")
    print(f"  Materias cursadas: {materias_cursadas}")
    print(f"  Materias aprobadas: {materias_aprobadas}")
    print(f"  Tasa de aprobación: {(materias_aprobadas/materias_cursadas)*100:.1f}%")
    print(f"  Estado académico: {estado_academico}")
    print("=" * 60)
## 
##  ESTUDIANTE: Ana Rodríguez (ID: EST001)
## --------------------------------------------------
##  Matemáticas:
##   Parcial 1: 85 | Parcial 2: 88 | Final: 92 | Asistencia: 95%
##   → Nota final: 89.55 (B) - Bueno
## 
##  Física:
##   Parcial 1: 78 | Parcial 2: 82 | Final: 85 | Asistencia: 90%
##   → Nota final: 83.00 (B) - Bueno
## 
##  Química:
##   Parcial 1: 90 | Parcial 2: 87 | Final: 94 | Asistencia: 98%
##   → Nota final: 91.65 (A) - Excelente
## 
##  RESUMEN ACADÉMICO:
##   GPA: 3.33/4.0
##   Materias cursadas: 3
##   Materias aprobadas: 3
##   Tasa de aprobación: 100.0%
##   Estado académico: Buen Rendimiento
## ============================================================
## 
##  ESTUDIANTE: Pedro Martínez (ID: EST002)
## --------------------------------------------------
##  Matemáticas:
##   Parcial 1: 75 | Parcial 2: 79 | Final: 82 | Asistencia: 88%
##   → Nota final: 80.10 (B) - Bueno
## 
##  Física:
##   Parcial 1: 82 | Parcial 2: 85 | Final: 88 | Asistencia: 92%
##   → Nota final: 86.15 (B) - Bueno
## 
##  Química:
##   Parcial 1: 77 | Parcial 2: 80 | Final: 83 | Asistencia: 85%
##   → Nota final: 80.95 (B) - Bueno
## 
##  RESUMEN ACADÉMICO:
##   GPA: 3.00/4.0
##   Materias cursadas: 3
##   Materias aprobadas: 3
##   Tasa de aprobación: 100.0%
##   Estado académico: Buen Rendimiento
## ============================================================
## 
##  ESTUDIANTE: Lucía Fernández (ID: EST003)
## --------------------------------------------------
##  Matemáticas:
##   Parcial 1: 92 | Parcial 2: 94 | Final: 96 | Asistencia: 100%
##   → Nota final: 94.90 (A) - Excelente
## 
##  Física:
##   Parcial 1: 88 | Parcial 2: 91 | Final: 93 | Asistencia: 95%
##   → Nota final: 91.45 (A) - Excelente
## 
##  Química:
##   Parcial 1: 95 | Parcial 2: 92 | Final: 97 | Asistencia: 98%
##   → Nota final: 95.35 (A) - Excelente
## 
##  RESUMEN ACADÉMICO:
##   GPA: 4.00/4.0
##   Materias cursadas: 3
##   Materias aprobadas: 3
##   Tasa de aprobación: 100.0%
##   Estado académico: Lista de Honor
## ============================================================

Simulación y Modelado

# Simulación de crecimiento poblacional
print("\n=== SIMULACIÓN DE CRECIMIENTO POBLACIONAL ===\n")
## 
## === SIMULACIÓN DE CRECIMIENTO POBLACIONAL ===
# Parámetros de simulación
poblacion_inicial = 10000
tasa_natalidad = 0.025     # 2.5% anual
tasa_mortalidad = 0.015    # 1.5% anual
tasa_migracion = 0.008     # 0.8% anual (inmigración neta)
años_simulacion = 20

# Variables de tracking
poblacion_actual = poblacion_inicial
historial_poblacion = [0] * (años_simulacion + 1)
historial_poblacion[0] = poblacion_inicial

print("SIMULACIÓN A 20 AÑOS:\n")
## SIMULACIÓN A 20 AÑOS:
print(f"Población inicial: {poblacion_inicial:,} habitantes")
## Población inicial: 10,000 habitantes
print(f"Tasa de natalidad: {tasa_natalidad*100:.1f}% anual")
## Tasa de natalidad: 2.5% anual
print(f"Tasa de mortalidad: {tasa_mortalidad*100:.1f}% anual")
## Tasa de mortalidad: 1.5% anual
print(f"Migración neta: {tasa_migracion*100:.1f}% anual\n")
## Migración neta: 0.8% anual
print(f"{'Año':<6} {'Población':>12} {'Nacim.':>8} "
      f"{'Muertes':>8} {'Migrac.':>8} {'Crecimiento':>12}")
## Año       Población   Nacim.  Muertes  Migrac.  Crecimiento
print("-" * 65)
## -----------------------------------------------------------------
# Bucle principal
for año in range(1, años_simulacion + 1):
    # Calcular cambios
    nacimientos = round(poblacion_actual * tasa_natalidad)
    muertes = round(poblacion_actual * tasa_mortalidad)
    migracion = round(poblacion_actual * tasa_migracion)

    # Aplicar cambios
    poblacion_anterior = poblacion_actual
    poblacion_actual = (poblacion_actual + nacimientos
                        - muertes + migracion)
    crecimiento_neto = poblacion_actual - poblacion_anterior

    # Guardar historial
    historial_poblacion[año] = poblacion_actual

    # Mostrar resultados
    print(f"{año:<6} {poblacion_actual:>12,} {nacimientos:>8,} "
          f"{muertes:>8,} {migracion:>8,} {crecimiento_neto:>+12,}")

    # Análisis cada 5 años
    if año % 5 == 0:
        crecimiento_periodo = (poblacion_actual
                               - historial_poblacion[año - 5])
        tasa_crecimiento_periodo = (
            (poblacion_actual / historial_poblacion[año - 5]) ** (1/5) - 1
        ) * 100
        print(f" Crecimiento últimos 5 años: {crecimiento_periodo:,} "
              f"({tasa_crecimiento_periodo:.2f}% anual promedio)")
## 1            10,180      250      150       80         +180
## 2            10,362      254      153       81         +182
## 3            10,549      259      155       83         +187
## 4            10,739      264      158       84         +190
## 5            10,932      268      161       86         +193
##  Crecimiento últimos 5 años: 932 (1.80% anual promedio)
## 6            11,128      273      164       87         +196
## 7            11,328      278      167       89         +200
## 8            11,532      283      170       91         +204
## 9            11,739      288      173       92         +207
## 10           11,950      293      176       94         +211
##  Crecimiento últimos 5 años: 1,018 (1.80% anual promedio)
## 11           12,166      299      179       96         +216
## 12           12,385      304      182       97         +219
## 13           12,608      310      186       99         +223
## 14           12,835      315      189      101         +227
## 15           13,066      321      193      103         +231
##  Crecimiento últimos 5 años: 1,116 (1.80% anual promedio)
## 16           13,302      327      196      105         +236
## 17           13,541      333      200      106         +239
## 18           13,785      339      203      108         +244
## 19           14,033      345      207      110         +248
## 20           14,286      351      210      112         +253
##  Crecimiento últimos 5 años: 1,220 (1.80% anual promedio)
# Análisis final
crecimiento_total = poblacion_actual - poblacion_inicial
tasa_crecimiento_anual_promedio = (
    (poblacion_actual / poblacion_inicial) ** (1 / años_simulacion) - 1
) * 100
import math
duplicacion_años = math.log(2) / math.log(1 + tasa_crecimiento_anual_promedio/100)

print("-" * 65)
## -----------------------------------------------------------------
print("\nANÁLISIS FINAL DE LA SIMULACIÓN:\n")
## 
## ANÁLISIS FINAL DE LA SIMULACIÓN:
print(f"Población final: {poblacion_actual:,} habitantes")
## Población final: 14,286 habitantes
print(f"Crecimiento total: {crecimiento_total:,} habitantes "
      f"({(crecimiento_total/poblacion_inicial)*100:.1f}%)")
## Crecimiento total: 4,286 habitantes (42.9%)
print(f"Tasa de crecimiento anual promedio: "
      f"{tasa_crecimiento_anual_promedio:.2f}%")
## Tasa de crecimiento anual promedio: 1.80%
print(f"Tiempo estimado para duplicar población: {duplicacion_años:.1f} años")
## Tiempo estimado para duplicar población: 38.9 años
# Proyección a 50 años
if tasa_crecimiento_anual_promedio > 0:
    poblacion_en_50 = poblacion_inicial * (
        (1 + tasa_crecimiento_anual_promedio/100) ** 50
    )
    print(f"Proyección a 50 años: {round(poblacion_en_50):,} habitantes")
## Proyección a 50 años: 24,394 habitantes

Procesamiento Secuencial Dependiente

# Cálculos que dependen de iteraciones anteriores
print("\n=== ANÁLISIS DE SERIES TEMPORALES ===")
## 
## === ANÁLISIS DE SERIES TEMPORALES ===
## === ANÁLISIS DE SERIES TEMPORALES ===

# Datos de ventas mensuales
ventas_mensuales = [100000, 108000, 95000, 112000, 125000, 118000,
                    135000, 142000, 128000, 155000, 168000, 175000]
meses_nombres = ["Ene", "Feb", "Mar", "Abr", "May", "Jun",
                 "Jul", "Ago", "Sep", "Oct", "Nov", "Dic"]

# Variables para cálculos acumulativos
ventas_acumuladas = [0] * len(ventas_mensuales)
variacion_mensual = [0] * len(ventas_mensuales)
promedio_movil_3 = [None] * len(ventas_mensuales)

print("ANÁLISIS DE TENDENCIAS DE VENTAS:\n")
## ANÁLISIS DE TENDENCIAS DE VENTAS:
## ANÁLISIS DE TENDENCIAS DE VENTAS:
print(f"{'Mes':<4}{'Ventas':>12}{'Acumulado':>12}{'Variación':>12}{'Prom.Móvil':>12}{'Tendencia':>12}")
## Mes       Ventas   Acumulado   Variación  Prom.Móvil   Tendencia
print("-" * 75)
## ---------------------------------------------------------------------------
for i in range(len(ventas_mensuales)):
    mes = meses_nombres[i]
    venta_actual = ventas_mensuales[i]

    # Ventas acumuladas
    if i == 0:
        ventas_acumuladas[i] = venta_actual
        variacion_mensual[i] = 0  # No hay mes anterior
    else:
        ventas_acumuladas[i] = ventas_acumuladas[i-1] + venta_actual
        variacion_mensual[i] = ((venta_actual - ventas_mensuales[i-1]) / ventas_mensuales[i-1]) * 100

    # Promedio móvil de 3 meses
    if i >= 2:
        promedio_movil_3[i] = sum(ventas_mensuales[i-2:i+1]) / 3
    else:
        promedio_movil_3[i] = None

    # Determinar tendencia
    if i == 0:
        tendencia = "Inicio"
    elif variacion_mensual[i] > 5:
        tendencia = "Alza fuerte"
    elif variacion_mensual[i] > 0:
        tendencia = "Crecimiento"
    elif variacion_mensual[i] > -5:
        tendencia = "Leve baja"
    else:
        tendencia = "Baja fuerte"

    # Formato de impresión
    variacion_str = " -" if i == 0 else f"{variacion_mensual[i]:+.1f}%"
    promedio_str = " -" if promedio_movil_3[i] is None else f"{promedio_movil_3[i]:8.0f}"

    print(f"{mes:<4}{venta_actual:>12,}{ventas_acumuladas[i]:>12,}{variacion_str:>12}{promedio_str:>12}{tendencia:>12}")
## Ene      100,000     100,000           -           -      Inicio
## Feb      108,000     208,000       +8.0%           - Alza fuerte
## Mar       95,000     303,000      -12.0%      101000 Baja fuerte
## Abr      112,000     415,000      +17.9%      105000 Alza fuerte
## May      125,000     540,000      +11.6%      110667 Alza fuerte
## Jun      118,000     658,000       -5.6%      118333 Baja fuerte
## Jul      135,000     793,000      +14.4%      126000 Alza fuerte
## Ago      142,000     935,000       +5.2%      131667 Alza fuerte
## Sep      128,000   1,063,000       -9.9%      135000 Baja fuerte
## Oct      155,000   1,218,000      +21.1%      141667 Alza fuerte
## Nov      168,000   1,386,000       +8.4%      150333 Alza fuerte
## Dic      175,000   1,561,000       +4.2%      166000 Crecimiento
# Análisis de resultados
print("-" * 75)
## ---------------------------------------------------------------------------
crecimiento_anual = ((ventas_mensuales[-1] - ventas_mensuales[0]) / ventas_mensuales[0]) * 100
promedio_mensual = sum(ventas_mensuales) / len(ventas_mensuales)
mejor_mes_idx = ventas_mensuales.index(max(ventas_mensuales))
peor_mes_idx = ventas_mensuales.index(min(ventas_mensuales))

print("\nRESUMEN ANUAL:\n")
## 
## RESUMEN ANUAL:
print(f"Ventas totales: ${sum(ventas_mensuales):,}")
## Ventas totales: $1,561,000
print(f"Promedio mensual: ${round(promedio_mensual):,}")
## Promedio mensual: $130,083
print(f"Crecimiento anual: {crecimiento_anual:.1f}%")
## Crecimiento anual: 75.0%
print(f"Mejor mes: {meses_nombres[mejor_mes_idx]} (${ventas_mensuales[mejor_mes_idx]:,})")
## Mejor mes: Dic ($175,000)
print(f"Peor mes: {meses_nombres[peor_mes_idx]} (${ventas_mensuales[peor_mes_idx]:,})")
## Peor mes: Mar ($95,000)

Bucles while

Bucles while

Un bucle while evalúa una condición antes de cada iteración.

  • Si la condición es True, ejecuta el bloque de código.

  • Si la condición es False, el bucle termina y el programa continúa.

Características fundamentales:

  • Evaluación previa: La condición se verifica antes de cada iteración.

  • Flexibilidad: El número de iteraciones depende de los datos.

  • Control dinámico: La condición puede cambiar durante la ejecución.

  • Riesgo de bucles infinitos: Si la condición nunca se vuelve False.

# Estructura básica
# while condicion:
    # Cuerpo del bucle
    # Código que se ejecuta mientras la condición sea True
    # IMPORTANTE: Incluir algo que eventualmente cambie la condición

Componentes esenciales:

Proceso de Ejecución

# Ejemplo paso a paso (versión Python)
contador = 1
while contador <= 3:
    print(f"Iteración: {contador}")
    contador += 1  # CRÍTICO: actualizar la variable de control
## Iteración: 1
## Iteración: 2
## Iteración: 3

# Proceso interno:
# Evaluación 1: contador (1) <= 3 -> True  -> ejecutar cuerpo -> contador = 2
# Evaluación 2: contador (2) <= 3 -> True  -> ejecutar cuerpo -> contador = 3
# Evaluación 3: contador (3) <= 3 -> True  -> ejecutar cuerpo -> contador = 4
# Evaluación 4: contador (4) <= 3 -> False -> terminar bucle

Contadores y Acumuladores

# === CONTADOR BÁSICO ===
print("=== CONTADOR BÁSICO ===")
## === CONTADOR BÁSICO ===
numero = 1
suma_total = 0

print("Sumando números del 1 al 5:")
## Sumando números del 1 al 5:
while numero <= 5:
    suma_total += numero
    print(f"Sumando {numero}: total = {suma_total}")
    numero += 1
## Sumando 1: total = 1
## Sumando 2: total = 3
## Sumando 3: total = 6
## Sumando 4: total = 10
## Sumando 5: total = 15
print(f"Suma final: {suma_total}")
## Suma final: 15
# === SUMA HASTA LÍMITE ===
print("\n=== SUMA HASTA LÍMITE ===")
## 
## === SUMA HASTA LÍMITE ===
suma = 0
contador = 1
limite = 100

print(f"Sumando números hasta que la suma supere {limite}:")
## Sumando números hasta que la suma supere 100:
while suma <= limite:
    suma += contador
    print(f"Suma = {suma} (agregando {contador})")
    contador += 1
## Suma = 1 (agregando 1)
## Suma = 3 (agregando 2)
## Suma = 6 (agregando 3)
## Suma = 10 (agregando 4)
## Suma = 15 (agregando 5)
## Suma = 21 (agregando 6)
## Suma = 28 (agregando 7)
## Suma = 36 (agregando 8)
## Suma = 45 (agregando 9)
## Suma = 55 (agregando 10)
## Suma = 66 (agregando 11)
## Suma = 78 (agregando 12)
## Suma = 91 (agregando 13)
## Suma = 105 (agregando 14)
print(f"Se necesitaron {contador - 1} números para superar {limite}")
## Se necesitaron 14 números para superar 100

Búsqueda y Validación

# === BÚSQUEDA EN LISTA ===
print("\n=== BÚSQUEDA EN LISTA ===")
## 
## === BÚSQUEDA EN LISTA ===
productos = ["Laptop", "Mouse", "Teclado", "Monitor", "Auriculares"]
producto_buscado = "Monitor"
indice = 0  # En Python los índices empiezan en 0
encontrado = False

print(f"Buscando '{producto_buscado}' en la lista:")
## Buscando 'Monitor' en la lista:
while indice < len(productos) and not encontrado:
    producto_actual = productos[indice]
    print(f"Revisando posición {indice + 1}: {producto_actual}")
    if producto_actual == producto_buscado:
        encontrado = True
        print(f"¡Encontrado! '{producto_buscado}' está en la posición {indice + 1}")
    else:
        indice += 1
## Revisando posición 1: Laptop
## Revisando posición 2: Mouse
## Revisando posición 3: Teclado
## Revisando posición 4: Monitor
## ¡Encontrado! 'Monitor' está en la posición 4
if not encontrado:
    print(f"'{producto_buscado}' no se encontró en la lista")


# === VALIDACIÓN DE ENTRADA ===
print("\n=== VALIDACIÓN DE ENTRADA ===")
## 
## === VALIDACIÓN DE ENTRADA ===
# Simulación de validación de edad
entradas_simuladas = ["abc", "-5", "150", "25"]  # Entradas simuladas
indice_entrada = 0
edad_valida = False
edad = None

print("Solicitando edad válida (18-100 años):")
## Solicitando edad válida (18-100 años):
while not edad_valida and indice_entrada < len(entradas_simuladas):
    entrada = entradas_simuladas[indice_entrada]
    print(f"Entrada del usuario: '{entrada}'")

    try:
        edad_convertida = int(entrada)
        if edad_convertida < 18:
            print("Error: Debe ser mayor de 18 años")
        elif edad_convertida > 100:
            print("Error: Edad no puede ser mayor a 100 años")
        else:
            edad = edad_convertida
            edad_valida = True
            print(f"Edad válida aceptada: {edad} años")
    except ValueError:
        print("Error: Debe ingresar un número válido")

    indice_entrada += 1
## Entrada del usuario: 'abc'
## Error: Debe ingresar un número válido
## Entrada del usuario: '-5'
## Error: Debe ser mayor de 18 años
## Entrada del usuario: '150'
## Error: Edad no puede ser mayor a 100 años
## Entrada del usuario: '25'
## Edad válida aceptada: 25 años

if not edad_valida:
    print("No se pudo obtener una edad válida después de varios intentos")

Bucles repeat (simulados con while True en Python)

While True

Un bucle tipo repeat en R se puede simular en Python usando while True. Este bucle ejecuta su bloque de código de manera infinita hasta que se cumpla una condición explícita de salida con break. Por lo tanto:

  • Ejecuta al menos una vez: Siempre se entra al bucle inicialmente.

  • Terminación manual: Requiere una condición de salida con break.

  • Flexibilidad: Permite manejar múltiples condiciones de salida o interrupciones según la lógica del programa.

Estructura Básica

# while True:
    # código a ejecutar
#    if condicion_de_salida:
#        break

Características Clave

  • Ejecución garantizada: El bucle se ejecuta al menos una vez porque la condición True siempre permite entrar.

  • Terminación manual: Es necesario usar break explícitamente para salir del bucle.

  • Flexibilidad: Se pueden implementar múltiples condiciones de salida o interrupciones dentro del bucle según la lógica del programa.

Ejemplo

# Ejemplo paso a paso (versión Python)
contador = 1
while True:
    print(f"Iteración: {contador}")
    contador += 1
    if contador > 3:
        break
## Iteración: 1
## Iteración: 2
## Iteración: 3

Menús Interactivos

# Menú interactivo simulado (versión Python)
while True:
    print("1. Opción A\n2. Opción B\n3. Salir")
    # opcion = input("Seleccione: ")
    opcion = "3"  # Simulación de entrada
    
    if opcion == "1":
        print("Ejecutando opción A")
    elif opcion == "2":
        print("Ejecutando opción B")
    elif opcion == "3":
        print("Saliendo...")
        break
    else:
        print("Opción inválida")
## 1. Opción A
## 2. Opción B
## 3. Salir
## Saliendo...

Procesamiento Hasta Condición

import random

suma = 0
while True:  # equivalente a repeat en R
    numero = random.randint(1, 10)  # número aleatorio entre 1 y 10
    suma += numero
    # Imprimir estilo R
    print(f' "Sumando: {numero} Total: {suma}"')
    
    if suma >= 20:
        print(' "Meta alcanzada"')
        break
##  "Sumando: 10 Total: 10"
##  "Sumando: 4 Total: 14"
##  "Sumando: 7 Total: 21"
##  "Meta alcanzada"

Control de bucles

Declaraciones de Control

break- Terminar bucle

  • Función: Termina inmediatamente el bucle más interno en el que se encuentra.

  • Comportamiento: Al ejecutarse, el bucle deja de iterar, y el flujo del programa continúa con la instrucción inmediatamente posterior al bucle.

# Buscar primer número par mayor que 10
for i in range(1, 21):
    if i > 10 and i % 2 == 0:
        print(f"Primer par mayor que 10: {i}")
        break
## Primer par mayor que 10: 12

continue - Saltar iteración

  • Función: Salta el resto de la iteración actual del bucle y continúa con la siguiente iteración.

  • Comportamiento: No termina el bucle; simplemente omite el código que queda por ejecutar en esa vuelta.

# Procesar solo números impares
for i in range(1, 11):
    if i % 2 == 0:
        continue  # Saltar números pares
    print(f"Número impar: {i}")
## Número impar: 1
## Número impar: 3
## Número impar: 5
## Número impar: 7
## Número impar: 9

Bucles Anidados con Control en Python

# Matriz: salir de bucle interno vs externo

for i in range(1, 4):  # Fila 1 a 3
    print(f"Fila {i}")
    for j in range(1, 4):  # Columna 1 a 3
        if i == 2 and j == 2:
            print("Saltando elemento (2,2)")
            continue  # Solo salta esta iteración del bucle interno
        print(f" Columna {j}")
## Fila 1
##  Columna 1
##  Columna 2
##  Columna 3
## Fila 2
##  Columna 1
## Saltando elemento (2,2)
##  Columna 3
## Fila 3
##  Columna 1
##  Columna 2
##  Columna 3