temperaturas()

 Vamos a hacer el código en Python de una manera sencilla, ideal para un principiante, cubriendo todos los requisitos del PDF.

Para poder usar reduce(), necesitamos importarlo primero.

Python
from functools import reduce

1. Generador de Datos (Función Generadora) ⚙️

Una función generadora (yield) es eficiente en memoria porque produce valores uno a uno, solo cuando se le pide, en lugar de crear toda una lista de golpe.

Código para leer_temperaturas()

Python
def leer_temperaturas():
    # Simulamos la lista de datos de ejemplo
    datos = [
        ("CDMX", 26),
        ("Monterrey", 34),
        ("Toluca", 19),
        ("Cancún", 38),
        ("Guadalajara", 31),
        ("Puebla", 24),
        ("Mérida", 35)
    ]

    # Devolvemos cada tupla una a una usando yield
    for ciudad, temperatura in datos:
        yield (ciudad, temperatura)  # [cite: 41, 42, 44]

# ```

---

## 2. Decorador Personalizado 🛡️

Un **decorador** es una función que envuelve a otra función para extender su comportamiento sin modificarla permanentemente.

### Código para `@auditar_funcion`

Vamos a crear un decorador que cuenta cuántas veces se llama a la función y muestra su nombre.

```python
# Un diccionario para almacenar el conteo de llamadas de cada función
conteo_llamadas = {}

def auditar_funcion(func):
    """
    Decorador que imprime el nombre de la función y cuenta sus llamadas. [cite: 59, 60]
    """
    # Inicializa el contador para la función
    if func.__name__ not in conteo_llamadas:
        conteo_llamadas[func.__name__] = 0

    def wrapper(*args, **kwargs):
        # 1. Imprime el nombre de la función [cite: 59]
        print(f"--- Ejecutando función: {func.__name__} ---")

        # 2. Cuenta y actualiza las llamadas [cite: 60]
        conteo_llamadas[func.__name__] += 1
        print(f"Llamadas totales a {func.__name__}: {conteo_llamadas[func.__name__]}")

        # Ejecuta la función original
        resultado = func(*args, **kwargs)
        
        return resultado
    return wrapper

3. Procesamiento de Datos (Lambda y Funciones de Orden Superior) 🚀

Las funciones de orden superior (filter, map, sorted, reduce) toman otras funciones (como las lambda) como argumentos. Una función lambda es una pequeña función anónima (sin nombre) de una sola línea, perfecta para operaciones sencillas.

3.1. Filtro con filter() y lambda

Filtramos los datos del generador para obtener solo las temperaturas mayores o iguales a $30^{\circ}C$1.

Python
@auditar_funcion
def filtrar_alertas(temperaturas_generador):
    # La función lambda toma una tupla (ciudad, temp) y devuelve True si temp >= 30
    alertas_filtradas = filter(lambda item: item[1] >= 30, temperaturas_generador)
    return list(alertas_filtradas)

# Obtenemos los datos del generador
temperaturas_data = leer_temperaturas()

# Aplicamos el filtro
alertas_filtradas_list = filtrar_alertas(temperaturas_data)
print(f"Alertas filtradas (Temperaturas >= 30°C): {alertas_filtradas_list}\n")

3.2. Ordenamiento con sorted() y key=lambda

Ordenamos la lista filtrada de mayor a menor temperatura2.

Python
@auditar_funcion
def ordenar_alertas(alertas):
    # La función lambda key le dice a sorted que use el segundo elemento (la temperatura, índice 1)
    # para ordenar, y 'reverse=True' es para orden descendente.
    alertas_ordenadas = sorted(alertas, key=lambda item: item[1], reverse=True)
    return alertas_ordenadas

# Aplicamos el ordenamiento
alertas_ordenadas_list = ordenar_alertas(alertas_filtradas_list)
print(f"Alertas ordenadas por temperatura (Descendente): {alertas_ordenadas_list}\n")

3.3. Transformación con map() y lambda

Convertimos cada tupla ordenada en un string de alerta con el formato específico3.

Python
@auditar_funcion
def transformar_a_string(alertas_ordenadas):
    # La función lambda toma la tupla (ciudad, temp) y la formatea en el string requerido
    alertas_string = map(
        lambda item: f"Alerta de calor en {item[0]}: {item[1]}°C", 
        alertas_ordenadas
    )
    return list(alertas_string)

# Aplicamos la transformación
alertas_finales = transformar_a_string(alertas_ordenadas_list)

3.4. Resumen con reduce()

Calculamos el promedio de las temperaturas filtradas4. Para calcular el promedio, necesitamos sumar todas las temperaturas y luego dividir por la cantidad de temperaturas.

Python
@auditar_funcion
def calcular_promedio(alertas):
    # 1. Suma con reduce(): [cite: 52]
    # El acumulador (acc) empieza en 0. A cada tupla (ciudad, temp), le sumamos la temperatura (item[1]).
    suma_temperaturas = reduce(
        lambda acc, item: acc + item[1], 
        alertas, 
        0
    )

    # 2. Conteo
    cantidad_alertas = len(alertas)
    
    # 3. Cálculo del promedio
    if cantidad_alertas > 0:
        promedio = suma_temperaturas / cantidad_alertas
    else:
        promedio = 0.0

    return promedio

# Aplicamos el cálculo
promedio_temperaturas = calcular_promedio(alertas_filtradas_list)

4. Salida Final Esperada 🎯

Mostramos los resultados como lo pide el ejercicio5.

Resultados de las Alertas

Python
## Lista Ordenada de Alertas
print("\n" + "="*50)
print("📢 LISTA ORDENADA DE ALERTAS DE TEMPERATURA 📢")
print("="*50)
for alerta in alertas_finales:
    print(alerta)

Resultado del Promedio

Python
## Promedio de Temperaturas
print("\n" + "="*50)
print("🌡️ RESUMEN DEL PROMEDIO DE TEMPERATURAS 🌡️")
print("="*50)
# Formato solicitado: "Temperatura promedio de alertas: 33.5°C" [cite: 65]
print(f"Temperatura promedio de alertas: {promedio_temperaturas:.1f}°C") 

¡Felicidades, has completado el ejercicio! Cubrimos el generador, el decorador, y todas las funciones de orden superior con lambdas.

Comentarios

Entradas populares de este blog

¿Qué es un Closure?

4 tipos de colecciones de datos más

Funciones en Python: con y sin paréntesis