Pasaré los códigos de r a python
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 instruc ciones de un programa. 

• Por defecto, R 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

Sin embargo, la mayoría de los programas requieren: 

• Tomar decisiones basadas en datos. 

• Repetir operaciones múltiples veces. 

• Saltar o interrumpir el flujo normal. 

Las estructuras de control de flujo

Las estructuras de control de flujo nos permiten alterar este orden secuencial de tres maneras fundamentales: 

• Selección condicional: ejecutar diferentes bloques de código según se cumplan ciertas condiciones • Iteración: repetir bloques de código un número determinado de veces o mientras se cumplan ciertas condiciones 

• Transferencia de control: saltar a diferentes partes del código. 

1

Importancia del Control de Flujo

• Automatización: Permite procesar grandes cantidades de datos sin intervención manual. • Eficiencia: Evita la repetición innecesaria de código. 

• Flexibilidad: Los programas pueden responder a diferentes situaciones. 

• Escalabilidad: Facilita el manejo de problemas complejos. 

• Interactividad: Permite crear programas que respondan dinámicamente. 

Valores lógicos

En el corazón de toda decisión computacional están los valores lógicos: TRUE y FALSE

Estos valores representan la verdad o falsedad de una proposición y son el fundamento sobre el cual se construyen todas las estructuras de control. 

En R, estos valores lógicos (también llamados booleanos, en honor al matemático George Boole) son objetos de clase logical. 

Los valores lógicos son el resultado de todas las operaciones de comparación y forman la base de las decisiones que puede tomar un programa. 

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

# Verificar su tipo
print(type(verdadero))
## <class 'bool'>
# <class 'bool'>
print(type(falso))
## <class 'bool'>
# <class 'bool'>

Operadores de comparación

Los operadores de comparación evalúan la relación entre dos valores y devuelven un resultado lógico: 

Igualdad y Desigualdad 

# Operador de igualdad (==)
print(5 == 5)
## True
# True
print(5 == 3)
## False
# False
print("hola" == "hola")
## True
# True

# Python también distingue entre mayúsculas y minúsculas
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 comparación

Los operadores de comparación evalúan la relación entre dos valores y devuelven un resultado lógico: ### Comparaciones Numéricas # Mayor que (>)

# 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 Comparación en Python con Variables

En Python, el funcionamiento es el mismo. Los operadores de comparación evalúan la relación entre dos variables y devuelven un valor booleano (True o False).

# Trabajando con Variables
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

el operador lógico para “y” es la palabra clave and. Funciona igual que el & en R: devuelve True solo si ambas condiciones que compara 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

Operadores Lógicos

El Operador OR (|)
el operador lógico para “o” es la palabra clave or . Funciona igual que el | en R: 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_miembro_vip = True
tiene_codigo_secreto = False

# ¿Puede acceder a la sala de tesoros? (si es miembro VIP O tiene un código secreto)
puede_entrar = es_miembro_vip or tiene_codigo_secreto
print(f"¿Puede acceder a la sala de tesoros? {puede_entrar}")
## ¿Puede acceder a la sala de tesoros? True
# True

Operadores Lógicos

El Operador NOT (!)

El operador ! invierte el valor lógico:

# El operador not
print(not True)
## False
# False
print(not False)
## True
# True

# Ejemplo práctico
tiene_llave_maestra = False

# ¿Se puede entrar en la bóveda sin forzar la puerta?
# Esto solo es posible si NO se tiene una llave maestra.
entrar_sin_forzar = not tiene_llave_maestra
print(f"¿Se puede entrar sin forzar? {entrar_sin_forzar}")
## ¿Se puede entrar sin forzar? True
# True

 Operadores Lógicos

Combinaciones Complejas

En Python, la lógica es la misma. Puedes usar paréntesis para asegurarte de que el código se entienda bien y que las operaciones se ejecuten en el orden correcto.

# Variables
temperatura = 22
esta_soleado = True
es_fin_de_semana = True

# Es buen dia para un futbol
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

Estructuras Condicionales

El control condicional es la base de todo algoritmo. Permite que un programa “tome decisiones” según el valor de expresiones lógicas 

La Declaración if

La lógica es la misma que en R: si una condición es verdadera, el programa ejecuta un bloque de código. En Python, usamos dos puntos (:) en lugar de llaves {} para definir el bloque, y la indentación (la sangría) es obligatoria.

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

Si la condición es False, el código dentro del if se ignora por completo.

temperatura = 30

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

# 1. Python evalúa si 30 > 25.
# 2. Como la expresión es True, ejecuta la línea con print().
# 3. El resultado en la consola es: "Hace calor hoy".

# Si cambias 'temperatura' a 20, la condición (20 > 25) sería False,
# y el programa no imprimiría nada.
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

# Si la edad es 18, la condición (18 >= 18) es True.
# Entonces, las dos líneas con print() se ejecutan.
# Si la edad fuera 16, la condición sería False y no se imprimiría nada.
stock = 25
stock_minimo = 10
urgente = False

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

# En este caso, como 25 no es menor que 10, la condición es False
# y el mensaje no se imprimirá.

Validación de Datos

salario = 50000

if salario > 0:
    print("Salario válido registrado")
    salario_mensual = salario / 12
    print(f"Salario mensual: {salario_mensual:.2f}")
## Salario válido registrado
## Salario mensual: 4166.67

# El f-string f"..." te permite poner variables entre llaves {}
# y el :.2f le dice a Python que lo formatee con 2 decimales.

Forma Compacta 
En Python, puedes anidar un if dentro de otro. La clave para que funcione es la indentación: cada if anidado necesita una sangría adicional para mostrar que está dentro del bloque del if superior.

nivel_bateria = 15
modo_ahorro_energia = True

# Si el nivel de la batería es bajo...
if nivel_bateria <= 20:
    print("ADVERTENCIA: Batería baja")
    
    # ...y si es extremadamente bajo, haz esto.
    if nivel_bateria <= 10:
        print("CRÍTICO: Conectar cargador inmediatamente")
## ADVERTENCIA: Batería baja

# En este caso, como nivel_bateria es 15, solo se ejecuta el primer 'if'.
# El mensaje de "ADVERTENCIA" se imprime, pero el de "CRÍTICO" se ignora.

Procesamiento Condicional de Datos

El manejo de datos suele hacerse con la libreríapandas

import pandas as pd
import numpy as np

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

# Detectar si hay valores faltantes (NaN)
if datos_usuario.isnull().values.any():
    print("Detectados valores faltantes en los datos")

    # Contar valores faltantes
    valores_na = datos_usuario.isnull().sum()
    print(f"Número de valores NA: {valores_na}")

    # Crear versión limpia de los datos
    datos_limpios = datos_usuario.dropna()
    print(f"Datos limpios: {', '.join(map(str, datos_limpios))}")
## Detectados valores faltantes en los datos
## Número de valores NA: 1
## Datos limpios: 23.0, 45.0, 67.0, 89.0, 12.0

# NOTA: En Python, los valores faltantes se representan con 'NaN'

Validación de Entrada de Usuario

Para validar la entrada del usuario en Python es similar a R,pero la forma de verificar el tipo de dato y manejar los errores es diferente. Usaremos un bloque try-except.

# Simulando entrada de usuario
entrada = "25"

# Intentar convertir a número usando un bloque try-except
try:
    numero = float(entrada)

    # Si la conversión es exitosa, se ejecuta este código
    if numero >= 0:
        print(f"Conversión exitosa: {numero}")
        print("Número válido y positivo")
        resultado = numero ** 0.5  # La raíz cuadrada se hace con ** 0.5
        print(f"Raíz cuadrada: {resultado:.2f}")

except ValueError:
    # Si la conversión falla (por ejemplo, si entrada es "hola"), se ejecuta este código
    print("Error: Entrada no es un número válido.")
## Conversión exitosa: 25.0
## Número válido y positivo
## Raíz cuadrada: 5.00

Declaraciones else

La estructura if nos permite hacer algo cuando una condición es verdadera, pero ¿qué pasa cuando queremos hacer algo diferente cuando la condición es falsa? Ahí es donde entra else. 

• La estructura if-else nos permite elegir entre dos caminos mutuamente excluyentes: si la condición es verdadera, se ejecuta una acción; si es falsa, se ejecuta otra acción diferente.

if condicion:

código si la condición es True

else:

código si la condición es False

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

# Como edad = 16, la condición (edad >= 18) es falsa,
# por lo tanto, se ejecuta el bloque 'else'.

f-else para Asignar Valores

Una técnica muy poderosa es usar if-else para asignar diferentes valores a una variable:

nota = 75

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

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

if-else para Asignar Valores:

Asignación Condicional en una Línea

Método 2: la forma compacta de asignar un valor a una variable basada en una condición se llama expresión condicional o operador ternario

nota = 65

# La sintaxis en Python es: valor_si_es_verdadero if condicion else valor_si_es_falso
estado = "Aprobado" if nota >= 70 else "Reprobado"
print(estado)
## 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.0

Sistema de Calificación de Crédito

se asignan múltiples variables dependiendo de la condición. Para la impresión final, se usan los f-strings

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(f"Categoría: {categoria}")
## Categoría: Regular
print(f"Tasa de interés: {tasa_interes} %")
## Tasa de interés: 8.5 %
print(f"Límite de crédito: ${limite_credito}")
## Límite de crédito: $15000
print(f"Aprobación automática: {aprobacion_automatica}")
## Aprobación automática: False

Calculadora de Descuentos

monto_compra = 150
descuento_aplicado = 0
tipo_descuento = "" # Se define la variable para evitar errores
puntos_ganados = 0

if monto_compra >= 100:
    descuento_aplicado = monto_compra * 0.15
    tipo_descuento = "Compra Mayor"
    puntos_ganados = monto_compra * 2
else:
    descuento_aplicado = 0
    tipo_descuento = "Sin descuento"
    puntos_ganados = monto_compra

monto_final = monto_compra - descuento_aplicado

print(f"Monto original: ${monto_compra}")
## Monto original: $150
print(f"Descuento: ${descuento_aplicado:.2f}")
## Descuento: $22.50
print(f"Monto final: ${monto_final:.2f}")
## Monto final: $127.50
print(f"Tipo: {tipo_descuento}")
## Tipo: Compra Mayor
print(f"Puntos ganados: {puntos_ganados}")
## Puntos ganados: 300

Sistema de Recomendación de Ropa

temperatura = 18
precipitacion = 0

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.append("paraguas")
    accesorios.append("impermeable")
    calzado = "botas impermeables"

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

Validación y Manejo de Errores

dividendo = 10
divisor = 3

if divisor != 0:
    resultado = dividendo / divisor
    print(f"El resultado de {dividendo} ÷ {divisor} es: {resultado:.2f}")
else:
    print("Error: No se puede dividir por cero")
## El resultado de 10 ÷ 3 es: 3.33

# El resultado no se asigna a NA en Python como en R

Validación de Tipos de Datos

En python se usa try-except

entrada_usuario = "123"

try:
    # Intentamos convertir la entrada a un número
    numero_procesado = float(entrada_usuario) * 2
    print("Entrada válida: es un número")
    print(f"Resultado: {numero_procesado}")

except ValueError:
    # Si la conversión falla, se ejecuta este código
    print("Entrada inválida: no es un número")

    # Intentamos una segunda conversión para el mensaje de éxito
    try:
        numero_procesado = float(entrada_usuario) * 2
        print("Conversión exitosa")
        print(f"Resultado: {numero_procesado}")
    except ValueError:
        print("No se pudo convertir a número")
## Entrada válida: es un número
## Resultado: 246.0

Sistema de Autenticación Básico

Usamos el operador lógico and para combinar las condiciones

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.datetime.now()
    permisos = ["leer", "escribir", "administrar"]
    print(f"Bienvenido, {usuario_correcto}")
    print(f"Hora de inicio de sesión: {tiempo_sesion}")
else:
    print("Acceso denegado: credenciales incorrectas")
    sesion_activa = False
    intentos_fallidos = 1

    # 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-elif-else

En lugar de else if, Python usa la palabra clave elif

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 si ninguna condición anterior fue verdadera

nota = 85

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

print(f"Calificación: {calificacion}")
## Calificación: B
print(comentario)
## Muy buen trabajo

La Importancia del Orden

El orden de las condiciones es crucial. Siempre ordena de más específico a menos específico, o de mayor a menor (o viceversa):

numero = 75

# CORRECTO: de mayor a menor
if numero >= 90:
    categoria = "Muy alto"
elif numero >= 70:  # 75 >= 70 es True, se ejecuta este bloque
    categoria = "Alto"
elif numero >= 50:
    categoria = "Medio"
else:
    categoria = "Bajo"

print(categoria)
## Alto
# INCORRECTO: de menor a mayor
if numero >= 50:  # 75 >= 50 es True, se ejecuta este bloque
    categoria_mala = "Medio"
elif numero >= 70:
    categoria_mala = "Alto"  # Nunca se ejecuta
elif numero >= 90:
    categoria_mala = "Muy alto"  # Nunca se ejecuta

print(categoria_mala)
## Medio

Sistema de Clasificación de IMC

peso = 70  # kg
altura = 1.75  # metros
imc = peso / (altura**2)

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"

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_kwh = 250

if consumo_kwh <= 100:
    tarifa = 0.12
    costo = consumo_kwh * tarifa
    tipo_usuario = "Básico"
elif consumo_kwh <= 200:
    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:
    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:
    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"

precio_promedio = costo / consumo_kwh

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: ${precio_promedio:.4f}")
## Precio promedio por kWh: $0.1700

Sistema de Evaluación Académica 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)

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

print("=== REPORTE ACADÉMICO ===")
## === REPORTE ACADÉMICO ===
print(f"Nota final: {nota_final:.2f}")
## Nota final: 85.60
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

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"

print(f"Clima base: {clima_base}")
## Clima base: Templado
print(f"Actividades recomendadas: {actividades}")
## Actividades recomendadas: Ideal para todas las actividades al aire libre

ifelse, no hay en python pero usamos otros métodos :

Método 1: Usando numpy.where() usando libreríasEs el equivalente directo de ifelse

import numpy as np
import pandas as pd

numeros = np.array([-3, -1, 0, 2, 5, -7, 8])

# numpy.where(condición, valor_si_verdadero, valor_si_falso)
signos = np.where(numeros >= 0, "No negativo", "Negativo")

# Crear un DataFrame para mostrar el resultado, como en R
resultado = pd.DataFrame({
    'numero': numeros,
    'signo': signos
})
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

Método 2: Usando List Comprehension

numeros = [-3, -1, 0, 2, 5, -7, 8]

# [valor_si_verdadero if condición else valor_si_falso for elemento in lista]
signos = ["No negativo" if num >= 0 else "Negativo" for num in numeros]

# Si quieres mostrarlo como una tabla, puedes usar pandas
import pandas as pd
resultado = pd.DataFrame({
    'numero': numeros,
    'signo': signos
})
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: usando for

# Método con bucle (más lento)
numeros = [-3, -1, 0, 2, 5, -7, 8]
signos_bucle = []  # Se crea una lista vacía para guardar los resultados

for num in numeros:
    if num >= 0:
        signos_bucle.append("No negativo")
    else:
        signos_bucle.append("Negativo")

# Para comparar con el método de list comprehension del ejercicio anterior
signos_comprension = ["No negativo" if num >= 0 else "Negativo" for num in numeros]

# Imprimir si son idénticos
print(signos_bucle == signos_comprension)  # True (mismo resultado)
## True

Usando la Expresión Condicional (Método Eficiente): list comprehension.

numeros = [-3, -1, 0, 2, 5, -7, 8]

# Versión con bucle (del ejercicio anterior)
signos_bucle = []
for num in numeros:
    if num >= 0:
        signos_bucle.append("No negativo")
    else:
        signos_bucle.append("Negativo")

# Versión con list comprehension (la más rápida)
signos_condicional = ["No negativo" if num >= 0 else "Negativo" for num in numeros]

# Ambos métodos dan el mismo resultado, pero la list comprehension
# es mucho más eficiente
print(signos_bucle == signos_condicional)
## True

Clasificación de Estudiantes

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]

# Crear un DataFrame (equivalente al data.frame de R)
reporte_estudiantes = pd.DataFrame({
    'nombre': estudiantes,
    'nota': notas
})

# Clasificación simple: Aprobado/Reprobado
# Se usa una list comprehension para crear la columna 'estado'
estado = ["Aprobado" if nota >= 70 else "Reprobado" for nota in notas]
reporte_estudiantes['estado'] = estado

print("--- Clasificación inicial ---")
## --- Clasificación inicial ---
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'] = ["Sí" if nota < 70 else "No" for nota in notas]
reporte_estudiantes['excelencia'] = ["Excelente" if nota >= 90 else "Regular" for nota in notas]

print("\n--- Reporte completo ---")
## 
## --- Reporte completo ---
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

bucle for que contiene una cadena de decisiones if-elif-else.

import pandas as pd

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

# Se crean listas vacías para guardar los resultados
categorias = []
recomendaciones = []

# Se usa un bucle for para procesar cada edad
for edad in edades:
    if edad < 13:
        categorias.append("Niño")
        recomendaciones.append("Educación primaria y juegos")
    elif edad < 18:
        categorias.append("Adolescente")
        recomendaciones.append("Educación secundaria")
    elif edad < 25:
        categorias.append("Joven adulto")
        recomendaciones.append("Educación superior o trabajo")
    elif edad < 65:
        categorias.append("Adulto")
        recomendaciones.append("Vida laboral activa")
    else:
        categorias.append("Adulto mayor")
        recomendaciones.append("Jubilación y cuidados")

# Se crea un DataFrame con los resultados
clasificacion_edades = pd.DataFrame({
    'edad': edades,
    'categoria': categorias,
    '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

import pandas as pd

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

# Se crean listas vacías para guardar los resultados de cada clasificación
calificaciones_letra = []
estado_materia = []
puntos_gpa = []

# Se usa un bucle for para procesar cada puntuación
for puntaje in puntuaciones:
    # Clasificación con letras y puntos GPA
    if puntaje >= 95:
        calificaciones_letra.append("A+")
        puntos_gpa.append(4.0)
    elif puntaje >= 90:
        calificaciones_letra.append("A")
        puntos_gpa.append(4.0)
    elif puntaje >= 85:
        calificaciones_letra.append("B+")
        puntos_gpa.append(3.5)
    elif puntaje >= 80:
        calificaciones_letra.append("B")
        puntos_gpa.append(3.0)
    elif puntaje >= 75:
        calificaciones_letra.append("C+")
        puntos_gpa.append(2.5)
    elif puntaje >= 70:
        calificaciones_letra.append("C")
        puntos_gpa.append(2.0)
    else:
        calificaciones_letra.append("F")
        puntos_gpa.append(0.0)

    # Determinamos el estado (Aprobada/Reprobada)
    if puntaje >= 70:
        estado_materia.append("Aprobada")
    else:
        estado_materia.append("Reprobada")

# Crear el DataFrame (equivalente a data.frame) con todos los resultados
reporte_academico = pd.DataFrame({
    'materia': materias,
    'puntuacion': puntuaciones,
    'letra': calificaciones_letra,
    'estado': estado_materia,
    'gpa': puntos_gpa
})

print("=== REPORTE ACADÉMICO ===")
## === REPORTE ACADÉMICO ===
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 = reporte_academico['puntuacion'].mean()
gpa_general = reporte_academico['gpa'].mean()
materias_aprobadas = reporte_academico[reporte_academico['estado'] == 'Aprobada'].shape[0]
materias_reprobadas = reporte_academico[reporte_academico['estado'] == 'Reprobada'].shape[0]

print(f"\nPromedio 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 pandas as pd

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

# Meta mensual
meta_mensual = 60000

# Usamos list comprehensions con if-else anidado para las clasificaciones
rendimiento = ["Excepcional" if v >= meta_mensual * 1.2
               else "Cumplió meta" if v >= meta_mensual
               else "Cerca de meta" if v >= meta_mensual * 0.8
               else "Bajo rendimiento" for v in ventas]

bonificacion = [v * 0.05 if v >= meta_mensual * 1.2
                else v * 0.03 if v >= meta_mensual
                else 0 for v in ventas]

# Para el trimestre, usamos una función y una list comprehension
def obtener_trimestre(mes):
    if mes in ["Enero", "Febrero", "Marzo"]:
        return "Q1"
    elif mes in ["Abril", "Mayo", "Junio"]:
        return "Q2"
    elif mes in ["Julio", "Agosto", "Septiembre"]:
        return "Q3"
    else:
        return "Q4"

trimestre = [obtener_trimestre(m) for m in meses]

# Crear el reporte de ventas usando un DataFrame de Pandas
reporte_ventas = pd.DataFrame({
    'mes': meses,
    'trimestre': trimestre,
    'ventas': ventas,
    'meta': meta_mensual,
    'rendimiento': rendimiento,
    'bonificacion': bonificacion
})

print("--- REPORTE DE VENTAS ---")
## --- REPORTE DE VENTAS ---
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
ventas_por_trimestre = reporte_ventas.groupby('trimestre')['ventas'].sum()

print("\n--- ANÁLISIS POR TRIMESTRE ---")
## 
## --- ANÁLISIS POR TRIMESTRE ---
print(f"Ventas Q1: {ventas_por_trimestre['Q1']}")
## Ventas Q1: 145000
print(f"Ventas Q2: {ventas_por_trimestre['Q2']}")
## Ventas Q2: 175000
print(f"Ventas Q3: {ventas_por_trimestre['Q3']}")
## Ventas Q3: 198000
print(f"Ventas Q4: {ventas_por_trimestre['Q4']}")
## Ventas Q4: 220000

Manejo de Valores Faltantes

import pandas as pd
import numpy as np

# Datos con valores faltantes (usamos np.nan para representar los NA)
temperaturas = [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"]

# Listas vacías para los resultados
clasificacion_temp = []
ropa_recomendada = []

# Se usa un bucle para procesar cada dato
for temp in temperaturas:
    # La primera condición es verificar si el dato es un valor faltante
    if pd.isna(temp):  # pd.isna() es la forma de verificar si es NaN
        clasificacion_temp.append("Sin datos")
        ropa_recomendada.append("Consultar pronóstico")
    elif temp >= 25:
        clasificacion_temp.append("Caluroso")
        ropa_recomendada.append("Ropa ligera")
    elif temp >= 20:
        clasificacion_temp.append("Templado")
        ropa_recomendada.append("Ropa normal")
    else:
        clasificacion_temp.append("Frío")
        ropa_recomendada.append("Abrigo")

# Crear el reporte meteorológico en un DataFrame de Pandas
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 los valores faltantes
temp_validas = reporte_clima['temperatura'].dropna()  # .dropna() elimina los NaN

print(f"\nTemperatura promedio: {temp_validas.mean():.1f} °C")
## 
## Temperatura promedio: 23.1 °C
print(f"Ciudades con datos: {temp_validas.count()}")
## Ciudades con datos: 7
print(f"Ciudades sin datos: {reporte_clima['temperatura'].isna().sum()}")
## Ciudades sin datos: 3

La función switch

En python no hay esta funcion, asi que la equivalente seria diccionario (dictionary)

Se crea un diccionario que asocia los valores con los resultados

= { ‘valor1’: ‘resultado1’, ‘valor2’: ‘resultado2’, ‘valor3’: ‘resultado3’ }

# Se usa el método .get() para obtener el resultado. # Si el valor no se encuentra, devuelve el valor por defecto que tú definas. variable_a_comparar = ‘valor2’ resultado = opciones.get(variable_a_comparar, ‘resultado_por_defecto’) # resultado ahora es ’resultado2

mes = "febrero"
año = 2024  # Año bisiesto

# Se crea un diccionario que asocia el nombre del mes con el número de días
dias_en_mes_dic = {
    "enero": 31,
    "febrero": 29 if (año % 4 == 0 and (año % 100 != 0 or año % 400 == 0)) else 28,
    "marzo": 31,
    "abril": 30,
    "mayo": 31,
    "junio": 30,
    "julio": 31,
    "agosto": 31,
    "septiembre": 30,
    "octubre": 31,
    "noviembre": 30,
    "diciembre": 31
}

# Usamos .get() para obtener el valor del diccionario.
# Si el mes no existe, devuelve None (el equivalente a NA en Python)
dias_en_mes = dias_en_mes_dic.get(mes, None)

if dias_en_mes is not None:
    print(f"{mes} de {año} tiene {dias_en_mes} días")
else:
    print("Mes inválido")
## febrero de 2024 tiene 29 días

Sistema de Días de la Semana

# Función para obtener información del día
def obtener_info_dia(dia):
    # Usamos un diccionario que mapea el día a un diccionario con su info
    info_dias = {
        "lunes": {
            "nombre": "Lunes",
            "tipo": "Laboral",
            "actividad": "Comenzar la semana con energía",
            "estado_animo": "Motivado",
            "color": "Azul"
        },
        "martes": {
            "nombre": "Martes",
            "tipo": "Laboral",
            "actividad": "Continuar con el ritmo de trabajo",
            "estado_animo": "Concentrado",
            "color": "Verde"
        },
        "miercoles": {
            "nombre": "Miércoles",
            "tipo": "Laboral",
            "actividad": "Punto medio de la semana",
            "estado_animo": "Equilibrado",
            "color": "Amarillo"
        },
        "jueves": {
            "nombre": "Jueves",
            "tipo": "Laboral",
            "actividad": "Prepararse para el final de semana",
            "estado_animo": "Expectante",
            "color": "Naranja"
        },
        "viernes": {
            "nombre": "Viernes",
            "tipo": "Laboral",
            "actividad": "Finalizar tareas y planificar el fin de semana",
            "estado_animo": "Alegre",
            "color": "Rosa"
        },
        "sabado": {
            "nombre": "Sábado",
            "tipo": "Fin de semana",
            "actividad": "Relajarse y disfrutar tiempo libre",
            "estado_animo": "Relajado",
            "color": "Púrpura"
        },
        "domingo": {
            "nombre": "Domingo",
            "tipo": "Fin de semana",
            "actividad": "Descansar y prepararse para la nueva semana",
            "estado_animo": "Tranquilo",
            "color": "Rojo"
        }
    }

    # Definimos el diccionario por defecto para el caso de un día no válido
    default_info = {
        "nombre": "Desconocido",
        "tipo": "Inválido",
        "actividad": "Verificar el día ingresado",
        "estado_animo": "Confundido",
        "color": "Gris"
    }

    # Usamos el método .get() para obtener la información.
    # El método .lower() hace que la entrada no sea sensible a mayúsculas.
    info = info_dias.get(dia.lower(), default_info)
    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 switch

def calculadora(operacion, a, b):
    # 1. Validar que los operandos sean numéricos
    if not isinstance(a, (int, float)) or not isinstance(b, (int, float)):
        return {"resultado": None, "error": "Los operandos deben ser numéricos"}
        
    # 2. Definir las operaciones en un diccionario.
    #    Cada valor es una función que toma a y b y devuelve un diccionario.
    operaciones = {
        "suma": lambda x, y: {"resultado": x + y, "error": None},
        "+": lambda x, y: {"resultado": x + y, "error": None},
        "resta": lambda x, y: {"resultado": x - y, "error": None},
        "-": lambda x, y: {"resultado": x - y, "error": None},
        "multiplicacion": lambda x, y: {"resultado": x * y, "error": None},
        "*": lambda x, y: {"resultado": x * y, "error": None},
        "division": lambda x, y: (
            {"resultado": x / y, "error": None} if y != 0 else {"resultado": None, "error": "División por cero"}
        ),
        "/": lambda x, y: (
            {"resultado": x / y, "error": None} if y != 0 else {"resultado": None, "error": "División por cero"}
        ),
        "potencia": lambda x, y: {"resultado": x ** y, "error": None},
        "**": lambda x, y: {"resultado": x ** y, "error": None},
        "modulo": lambda x, y: {"resultado": x % y, "error": None},
        "%": lambda x, y: {"resultado": x % y, "error": None},
    }
    
    # 3. Obtener la función del diccionario y ejecutarla.
    #    Si la operación no existe, devolvemos un error por defecto.
    funcion_a_ejecutar = operaciones.get(operacion.lower())
    
    if funcion_a_ejecutar:
        return funcion_a_ejecutar(a, b)
    else:
        return {"resultado": None, "error": "Operación no reconocida"}

# 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))
## {'resultado': None, 'error': 'Operación no reconocida'}

Sistema de Conversión de Unidades

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

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

    # 3. Validar si las unidades existen en el diccionario
    if de not in factores_a_metros or a not in factores_a_metros:
        unidades_validas = list(factores_a_metros.keys())
        return {
            "resultado": None,
            "error": "Unidad no reconocida",
            "unidades_validas": unidades_validas
        }

    # 4. Realizar la conversión
    metros = valor * factores_a_metros[de]
    resultado_final = metros / factores_a_metros[a]
    
    # 5. Formatear la fórmula
    formula = f"{valor} {de_unidad} = {resultado_final:.6f} {a_unidad}"

    # 6. Devolver un diccionario con los resultados
    return {
        "valor_original": valor,
        "unidad_original": de_unidad,
        "valor_convertido": resultado_final,
        "unidad_final": a_unidad,
        "formula": formula
    }

# 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.000000 m'}
print(convertir_unidad(5, "ft", "m"))
## {'valor_original': 5, 'unidad_original': 'ft', 'valor_convertido': 1.524, 'unidad_final': 'm', 'formula': '5 ft = 1.524000 m'}
print(convertir_unidad(10, "km", "mi"))
## {'valor_original': 10, 'unidad_original': 'km', 'valor_convertido': 6.2137119223733395, 'unidad_final': 'mi', 'formula': '10 km = 6.213712 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']}

Estructuras Iterativas

Bucles

Los bucles son estructuras que permiten ejecutar el mismo bloque de código múltiples veces sin tener que escribirlo repetidamente. Son fundamentales para automatizar tareas repetitivas y procesar conjuntos de datos. 

Python tiene dos tipos principales de bucles, que se corresponden directamente con dos de los tipos que mencionas en R:

  • for: Lo usas cuando sabes exactamente por dónde vas a pasar. Es para recorrer listas, como el for de R.

  • While: Lo usas cuando quieres que algo se repita mientras una condición sea verdad. Cuidado, que si no la cambias, el bucle no para.

  • repeat (en R): En Python no existe así, pero lo resuelves con un while true y le metes un break cuando quieres que se detenga.

    Conceptos Fundamentales

  • Iteración: Es cada vez que el código se repite.

  • Variable de Control: La variable que se va actualizando en cada vuelta del bucle.

  • Cuerpo del Bucle: Es el código que va con sangría (indentado) y que se repite una y otra vez.

El Bucle for en Python

El bucle for en Python es la forma más común de automatizar tareas repetitivas. Es muy similar al de R, pero con una sintaxis más limpia.

Características Fundamentales

El bucle for de Python comparte las mismas características principales que el de R:

  • Predictibilidad: Sabes de antemano cuántas iteraciones se van a realizar, ya que el bucle se detendrá cuando recorra toda la secuencia.

  • Control automático: Python maneja por sí mismo el avance a través de la secuencia. No necesitas un contador o un índice.

  • Flexibilidad: Puede iterar sobre casi cualquier cosa: listas, tuplas, cadenas de texto, diccionarios y rangos de números.

  • Eficiencia: Te permite escribir código conciso y eficiente, evitando la repetición manual.

Anatomía y Componentes Clave

La estructura de un bucle for en Python es muy sencilla y se basa en la indentación.

for es varibales_interaccion in secuencias

#Cuerpo del bucle

# Este es el codigo que se repite en cada interacion

  • for: Es la palabra clave que inicia el bucle.

  • variable_iteracion: Es la variable temporal que almacena el valor de cada elemento de la secuencia en cada vuelta del bucle.

  • in: El operador que le indica al bucle sobre qué secuencia debe iterar.

  • secuencia: El conjunto de elementos que vas a recorrer (por ejemplo, una lista de números, una cadena de texto, etc.).

  • : (dos puntos): Marcan el final de la línea del for y el inicio del cuerpo del bucle.

  • Indentación (sangría): En Python, la sangría es obligatoria. El código que tiene la misma sangría se considera parte del mismo bloque, lo que reemplaza a las llaves ({}) de R.

Proceso de ejecución:

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

Tipos de Secuencias para Iterar

1)Secuencias Numéricas

En lugar del operador : o la función seq () , Python usa la función range() para crear secuencias de números.

import numpy as np

# === SECUENCIAS NUMÉRICAS BÁSICAS ===
print("=== SECUENCIAS NUMÉRICAS BÁSICAS ===")
## === SECUENCIAS NUMÉRICAS BÁSICAS ===
# Secuencia ascendente (conteo del 1 al 5)
print("\nConteo del 1 al 5:")
## 
## Conteo del 1 al 5:
for i in range(1, 6): # range(inicio, fin + 1)
    print(f"Número: {i}")
## Número: 1
## Número: 2
## Número: 3
## Número: 4
## Número: 5
# Secuencia descendente (conteo del 5 al 1)
print("\nConteo descendente del 5 al 1:")
## 
## Conteo descendente del 5 al 1:
for i in range(5, 0, -1): # range(inicio, fin - 1, paso)
    print(f"Número: {i}")
## Número: 5
## Número: 4
## Número: 3
## Número: 2
## Número: 1
# Usando range() para mayor control (números pares)
print("\nNúmeros pares del 2 al 10:")
## 
## Números pares del 2 al 10:
for i in range(2, 11, 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
# Secuencia con decimales (usamos numpy para esto)
print("\nSecuencia decimal:")
## 
## Secuencia decimal:
for valor in np.arange(0.5, 3.0, 0.5): # np.arange(inicio, fin + paso, paso)
    print(f"Valor: {valor:.1f}")
## Valor: 0.5
## Valor: 1.0
## Valor: 1.5
## Valor: 2.0
## Valor: 2.5

2. Vectores de Caracteres

Iterar sobre listas de texto en Python es muy intuitivo, ya que el bucle for recorre directamente cada elemento.

# === PROCESAMIENTO DE TEXTO ===
print("\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:")
## Lista de estudiantes:
for nombre in estudiantes:
    # Procesar cada nombre
    num_palabras = len(nombre.split())
    num_caracteres = len(nombre)
    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:")
## 
## Calendario semanal:
# Usamos zip() para iterar sobre dos listas al mismo tiempo
for dia, tipo in zip(dias_semana, tipos_dia):
    emoji = "maletin" if tipo == "Laboral" else "fiesta"
    print(f"{emoji} {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

Python maneja estructuras de datos anidadas (listas de diccionarios) de forma muy natural.

# === PROCESAMIENTO DE LISTAS ===
print("\n=== PROCESAMIENTO DE LISTAS ===")
## 
## === PROCESAMIENTO DE LISTAS ===
# Lista de información de empleados (una lista de diccionarios)
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 ===
for i, emp in enumerate(empleados): # enumerate() da el índice y el elemento
    # 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 + 1} ---")
    print(f"Nombre: {emp['nombre']}")
    print(f"Departamento: {emp['departamento']}")
    print(f"Salario anual: ${emp['salario']:,}") # Con formato para comas
    print(f"Salario mensual: ${salario_mensual:,.0f}") # Con formato para comas y sin decimales
    print(f"Experiencia: {emp['años_experiencia']} años ({nivel_experiencia})")
    print(f"Certificaciones ({len(emp['certificaciones'])}):")
    
    # Bucle anidado para las 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

Usar la función zip (), que te permite iterar sobre múltiples listas al mismo tiempo

# === ANÁLISIS FINANCIERO TRIMESTRAL ===
print("\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]

# Análisis detallado por mes
total_ventas = 0
total_metas = 0
meses_exitosos = 0
mejor_mes = ""
mejor_rendimiento = 0

print("REPORTE MENSUAL DETALLADO:")
## REPORTE MENSUAL DETALLADO:
# Usamos f-strings para el formato, con símbolos de alineación (<, >, ^)
print(f"{'Mes':<12} {'Ventas':>12} {'Meta':>12} {'Diferencia':>12} {'% Meta':>10} {'Estado':>10}")
## Mes                Ventas         Meta   Diferencia     % Meta     Estado
print("-" * 80)
## --------------------------------------------------------------------------------
# Usamos zip() para iterar sobre los 3 sets de datos a la vez
for mes, venta, meta in zip(meses, ventas_2024, metas):
    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
    
    # Formatear y mostrar resultados
    print(f"{mes:<12} ${venta:10,} ${meta:10,} {diferencia:10,} {porcentaje_meta:9.1f}% {estado:>8}")
## 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%
print("\n=== RESUMEN EJECUTIVO ===")
## 
## === 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

Usar una lista de diccionarios anidados, para la estructura , usaremos bucles for anidado con el métodos items()

# === SISTEMA DE GESTIÓN ACADÉMICA ===
print("\n=== SISTEMA DE GESTIÓN ACADÉMICA ===")
## 
## === SISTEMA DE GESTIÓN ACADÉMICA ===
# Base de datos de estudiantes (lista de diccionarios)
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 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 y estado
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 (el método .items() nos da la clave y el valor)
    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
        calificacion = obtener_calificacion(nota_final)
        
        # Actualizar contadores
        materias_cursadas += 1
        total_puntos += calificacion['puntos']
        if calificacion['puntos'] > 0:
            materias_aprobadas += 1
            
        # Mostrar detalles de la materia
        print(f" {materia_nombre}:")
        print(f" Parcial 1: {materia_data['parcial1']} | Parcial 2: {materia_data['parcial2']} | 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("\n")
    
    # 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
    tasa_aprobacion = (materias_aprobadas / materias_cursadas) * 100
    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: {tasa_aprobacion:.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 de Crecimiento Poblacional

usaremso un bucle for para la simulación y el formato avanzado con f-strings, para las operaciones matematicas complejas usaremos math la librería

import math

# === SIMULACIÓN DE CRECIMIENTO POBLACIONAL ===
print("\n=== SIMULACIÓN DE CRECIMIENTO POBLACIONAL ===")
## 
## === 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 para tracking
poblacion_actual = poblacion_inicial
historial_poblacion = [poblacion_inicial]

print("SIMULACIÓN A 20 AÑOS:")
## 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} {'Muertes':>8} {'Migrac.':>8} {'Crecimiento':>12}")
## Año       Población   Nacim.  Muertes  Migrac.  Crecimiento
print("-" * 65)
## -----------------------------------------------------------------
for año in range(1, años_simulacion + 1):
    # Calcular cambios poblacionales
    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 en historial
    historial_poblacion.append(poblacion_actual)
    
    # Mostrar resultados del año
    print(f"{año:<6} {poblacion_actual:12,} {nacimientos:8,} {muertes:8,} {migracion:8,} {crecimiento_neto:+12,}")
    
    # Análisis de tendencias cada 5 años
    if año % 5 == 0:
        poblacion_hace_5_años = historial_poblacion[año - 5]
        crecimiento_periodo = poblacion_actual - poblacion_hace_5_años
        tasa_crecimiento_periodo = ((poblacion_actual / poblacion_hace_5_años)**(1/5) - 1) * 100
        print(f" Crecimiento últimos 5 años: {crecimiento_periodo:,} ({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
print("-" * 65)
## -----------------------------------------------------------------
print("\n ANÁLISIS FINAL DE LA SIMULACIÓN:")
## 
##  ANÁLISIS FINAL DE LA SIMULACIÓN:
crecimiento_total = poblacion_actual - poblacion_inicial
tasa_crecimiento_anual_promedio = ((poblacion_actual / poblacion_inicial)**(1/años_simulacion) - 1) * 100
duplicacion_años = math.log(2) / math.log(1 + (tasa_crecimiento_anual_promedio / 100))

print(f"Población final: {poblacion_actual:,} habitantes")
## Población final: 14,286 habitantes
print(f"Crecimiento total: {crecimiento_total:,} habitantes ({crecimiento_total/poblacion_inicial * 100:.1f}%)")
## Crecimiento total: 4,286 habitantes (42.9%)
print(f"Tasa de crecimiento anual promedio: {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
# Proyecciones adicionales
if tasa_crecimiento_anual_promedio > 0:
    poblacion_en_50_años = poblacion_inicial * (1 + tasa_crecimiento_anual_promedio / 100)**50
    print(f"Proyección a 50 años: {round(poblacion_en_50_años):,} habitantes")
## Proyección a 50 años: 24,394 habitantes

Procesamiento Secuencial Dependiente

import numpy as np

# === ANÁLISIS DE SERIES TEMPORALES ===
print("\n=== 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
variacion_mensual = 0
promedio_movil_3 = 0
ventas_acumuladas_lista = []

print("ANÁLISIS DE TENDENCIAS DE VENTAS:")
## ANÁLISIS DE TENDENCIAS DE VENTAS:
print(f"{'Mes':<4} {'Ventas':>10} {'Acumulado':>12} {'Variación':>10} {'Prom.Móvil':>12} {'Tendencia':>10}")
## Mes      Ventas    Acumulado  Variación   Prom.Móvil  Tendencia
print("-" * 75)
## ---------------------------------------------------------------------------
# Usamos enumerate para obtener el índice (i) y el valor (venta_actual)
for i, venta_actual in enumerate(ventas_mensuales):
    # Ventas acumuladas
    ventas_acumuladas += venta_actual
    ventas_acumuladas_lista.append(ventas_acumuladas)

    # Variación mensual
    if i == 0:
        variacion_str = " - "
        tendencia = "Inicio"
    else:
        variacion = ((venta_actual - ventas_mensuales[i-1]) / ventas_mensuales[i-1]) * 100
        variacion_str = f"{variacion:+.1f}%"
        
        # Determinar tendencia
        if variacion > 5:
            tendencia = "Alza fuerte"
        elif variacion > 0:
            tendencia = "Crecimiento"
        elif variacion > -5:
            tendencia = "Leve baja"
        else:
            tendencia = "Baja fuerte"

    # Promedio móvil de 3 meses
    if i >= 2:
        # Usamos una "slice" para obtener los últimos 3 meses
        promedio = np.mean(ventas_mensuales[i-2:i+1])
        promedio_str = f"{int(promedio):,}"
    else:
        promedio_str = " - "
    
    # Mostrar resultados
    print(f"{meses_nombres[i]:<4} {venta_actual:10,} {ventas_acumuladas:12,} {variacion_str:>10} {promedio_str:>12} {tendencia:10}")
## Ene     100,000      100,000         -            -  Inicio    
## Feb     108,000      208,000      +8.0%           -  Alza fuerte
## Mar      95,000      303,000     -12.0%      101,000 Baja fuerte
## Abr     112,000      415,000     +17.9%      105,000 Alza fuerte
## May     125,000      540,000     +11.6%      110,666 Alza fuerte
## Jun     118,000      658,000      -5.6%      118,333 Baja fuerte
## Jul     135,000      793,000     +14.4%      126,000 Alza fuerte
## Ago     142,000      935,000      +5.2%      131,666 Alza fuerte
## Sep     128,000    1,063,000      -9.9%      135,000 Baja fuerte
## Oct     155,000    1,218,000     +21.1%      141,666 Alza fuerte
## Nov     168,000    1,386,000      +8.4%      150,333 Alza fuerte
## Dic     175,000    1,561,000      +4.2%      166,000 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("\n RESUMEN ANUAL:")
## 
##  RESUMEN ANUAL:
print(f"Ventas totales: ${sum(ventas_mensuales):,}")
## Ventas totales: $1,561,000
print(f"Promedio mensual: ${promedio_mensual:,.0f}")
## 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

Evalúa una condición antes de cada iteración. Si la condición es verdadera, el código dentro del bucle se ejecuta. Si es falsa, el bucle termina

Características Fundamentales

Las características que mencionas se aplican perfectamente a Python:

  • Evaluación previa: La condición siempre se verifica antes de que comience cada repetición.

  • Flexibilidad: El número de repeticiones es dinámico; el bucle continúa hasta que la condición se cumpla, sin importar cuántas veces sea necesario.

  • Control dinámico: Puedes cambiar la condición en cualquier momento dentro del bucle.

  • Riesgo de bucles infinitos: Si el código no incluye algo que eventualmente haga que la condición sea falsa, el bucle nunca terminará. Esto es algo que debes tener en cuenta.

Anatomía de un Bucle while

samos los dos puntos (:) y la sangría en lugar de los paréntesis y las llaves.

while condicion: # Cuerpo del bucle # Código que se ejecuta mientras la condición sea True

# IMPORTANTE: Aquí debe haber código que eventualmente cambie la condición

Componentes esenciales:

  • While: La palabra clave que inicia el bucle.

  • condicion :La expresión lógica que el bucle evalúa antes de cada repetición.

  • cuerpo del bucle:: El código que tiene sangría y se ejecuta en cada iteración.

  • Actualizacion:El código dentro del bucle que modifica las variables de la condicion para que, en algún momento, se vuelva falsa.

Componentes esenciales:

• while: Palabra clave que inicia el bucle 

• condición: Expresión lógica que se evalúa en cada iteración • Cuerpo del bucle: Código que se ejecuta cuando la condición es verdadera • Actualización: Modificación de variables que afectan la condición 

Proceso de Ejecución

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

# Salida esperada:
# Iteración: 1
# Iteración: 2
# Iteración: 3

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 Secuencial

# === 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
encontrado = False

print(f"Buscando '{producto_buscado}' en la lista:")
## Buscando 'Monitor' en la lista:
# Usamos 'and not' en la condición del bucle
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}")
    
    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

usar un bloque try-except para manejar errores de formato de forma segura.

# === 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"]
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:
        # Intentar convertir a número
        edad_convertida = int(entrada)
        
        # Validar el rango
        if 18 <= edad_convertida <= 100:
            edad = edad_convertida
            edad_valida = True
            print(f"Edad válida aceptada: {edad} años")
        elif edad_convertida < 18:
            print("Error: Debe ser mayor de 18 años")
        else:
            print("Error: Edad no puede ser mayor a 100 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 en python no existe pero,para crear un bucle que se ejecute indefinidamente y que podamos decidir cuándo termine, se usa la expresión while True

Características Clave

  • Ejecución garantizada: Con while True, el código se ejecuta al menos una vez, ya que la condición de salida se evalúa dentro del bucle.

  • Terminación manual: La única forma de salir de este bucle es usando la palabra clave break. Si no la usas, el bucle será infinito.

  • Flexibilidad: Puedes colocar el break en cualquier lugar del bucle y usar múltiples condiciones if para salir.

Estructura Básica

# Estructura básica while True: # Código que se ejecuta en cada iteración

if condicion_de_salida: break # Detiene el bucle
Ejemplo:

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

usamos input () para tener la entrada del usuario, y while true para asegurar que se muestre la entrada

# Menú Interactivo para RMarkdown

# Lista de opciones que el programa 'simulará' que escribes.
opciones_a_probar = ["1", "2", "4", "3"]

for opcion in opciones_a_probar:
    print("1. Opción A")
    print("2. Opción B")
    print("3. Salir")
    
    # Imprime la opción que se está probando
    print(f"Seleccionaste: {opcion}")
    
    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")
    
    print("-" * 20) # Separador para que el resultado sea más claro
## 1. Opción A
## 2. Opción B
## 3. Salir
## Seleccionaste: 1
## Ejecutando opción A
## --------------------
## 1. Opción A
## 2. Opción B
## 3. Salir
## Seleccionaste: 2
## Ejecutando opción B
## --------------------
## 1. Opción A
## 2. Opción B
## 3. Salir
## Seleccionaste: 4
## Opción inválida
## --------------------
## 1. Opción A
## 2. Opción B
## 3. Salir
## Seleccionaste: 3
## Saliendo...

Nota: En un entorno de Python normal se usaría input(), pero en RMarkdown

simulamos la entrada del usuario para evitar que la ejecución se detenga.

Procesamiento Hasta Condición

usamos la librería random

import random

suma = 0
while True:
    numero = random.randint(1, 10)  # Genera un número aleatorio entre 1 y 10
    suma += numero
    print(f"Sumando: {numero} Total: {suma}")

    if suma >= 20:
        print("Meta alcanzada")
        break
## Sumando: 8 Total: 8
## Sumando: 5 Total: 13
## Sumando: 8 Total: 21
## Meta alcanzada

Declaraciones de Control :

Breack

Para terminar bucle

# Buscar el 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  # Termina el bucle
## Primer par mayor que 10: 12

Continue

saltar interacion

# Procesar solo números impares
for i in range(1, 11):
    if i % 2 == 0:
        continue  # Saltar los 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

# Matriz: saltar en el bucle interno
for i in range(1, 4):
    print(f"Fila {i}")
    for j in range(1, 4):
        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

Funciones en Python

Las funciones son bloques de código reutilizable que realizan tareas específicas. Permiten organizar el código, evitar repetición y crear programas modulares.

¿Por qué Usar Funciones?

Las razones que mencionas aplican perfectamente a Python. Usar funciones te ayuda a:

  • Reutilizar el código: Define una tarea una sola vez y úsala en cualquier parte de tu programa.

  • Organizar tu código: Divide un problema complejo en pequeñas piezas lógicas y fáciles de entender.

  • Facilitar el mantenimiento: Si necesitas cambiar algo, lo haces en un solo lugar.

  • Mejorar la legibilidad: Un programa dividido en funciones es más fácil de leer y entender para ti y para otros.

    Estructura Básica

    En Python, una función se define con la palabra clave def . Al igual que en R, el cuerpo de la función se define después de la línea de declaración, pero en Python, se usa una sangría en lugar de las llaves {}.

    def nombre_funcion(parametros):
        # cuerpo de la función
        # cálculos y operaciones
    
        return resultado  # opcional

Ejemplo

# Función simple
def saludar(nombre):
    mensaje = f"Hola, {nombre}"
    return mensaje

# Uso de la función
resultado = saludar("Ana")
print(resultado)
## Hola, Ana

# Salida esperada:
# Hola, Ana