Fundamentos de Programación

Ejercicios Unidad 05

EJERCICIO 1

Implemente la función analizar_frecuencia_acciones(registros) que recibe una lista de cadenas con el formato "NIVEL|USUARIO|ACCION". Debe contar la frecuencia de cada ACCION realizada únicamente por usuarios con nivel ADMIN (insensible a mayúsculas/minúsculas). Las acciones del diccionario de salida deben estar en mayúsculas.

RESOLUCIÓN

# Construye un diccionario de frecuencias de ACCION solo para nivel ADMIN (case-insensitive).
def analizar_frecuencia_acciones(registros):
    freq = {}
    for linea in registros:
        partes = linea.split("|")
        if len(partes) != 3:
            continue
        nivel, usuario, accion = partes
        if nivel.strip().lower() == "admin":
            clave = accion.strip().upper()
            freq[clave] = freq.get(clave, 0) + 1
    return freq

# Ejemplo de uso (produce la salida esperada del enunciado).
logs = [
    "USER|juan.perez|LOGIN",
    "ADMIN|ana.gomez|CREATE_USER",
    "GUEST|invitado|VIEW_PAGE",
    "admin|maria.lopez|DELETE_USER",
    "ADMIN|ana.gomez|CREATE_USER",
    "USER|pedro.ramirez|LOGOUT",
    "ADMIN|ana.gomez|UPDATE_CONFIG"
]
print(analizar_frecuencia_acciones(logs))  # {'CREATE_USER': 2, 'DELETE_USER': 1, 'UPDATE_CONFIG': 1}

EJERCICIO 2

Implemente la función consolidar_calificaciones(dict_parcial, dict_final). Debe retornar un diccionario donde cada clave es el estudiante y el valor es una lista [nota_parcial, nota_final, promedio]. Si falta una nota, se registra como 0. El promedio es (parcial + final)/2.

RESOLUCIÓN

# Crea un diccionario consolidado: [parcial, final, promedio]. Si falta una nota, usa 0.
def consolidar_calificaciones(dict_parcial, dict_final):
    estudiantes = sorted(set(dict_parcial.keys()) | set(dict_final.keys()))
    consolidado = {}
    for nombre in estudiantes:
        p = dict_parcial.get(nombre, 0)
        f = dict_final.get(nombre, 0)
        promedio = (p + f) / 2
        consolidado[nombre] = [p, f, promedio]
    return consolidado

# Ejemplo de uso (produce la salida del enunciado).
parcial = {"Ana": 85, "Luis": 91, "Marta": 76}
final = {"Ana": 95, "Luis": 88, "Pedro": 92}
print(consolidar_calificaciones(parcial, final))
# {'Ana': [85, 95, 90.0], 'Luis': [91, 88, 89.5], 'Marta': [76, 0, 38.0], 'Pedro': [0, 92, 46.0]}

EJERCICIO 3

Implemente la función mapear_proyectos_por_empleado(asignaciones) que invierte un diccionario {proyecto: [empleados...]} a {empleado: [proyectos...]}, agrupando correctamente cuando un empleado participa en varios proyectos.

RESOLUCIÓN

# Invierte {proyecto: [empleados]} en {empleado: [proyectos]} manejando colisiones por acumulación.
def mapear_proyectos_por_empleado(asignaciones):
    invertido = {}
    for proyecto, lista_empleados in asignaciones.items():
        for emp in lista_empleados:
            invertido.setdefault(emp, []).append(proyecto)
    return invertido

# Ejemplo de uso (produce la salida esperada).
proyectos = {
    "Proyecto Alpha": ["Elena", "Carlos"],
    "Proyecto Beta": ["David", "Elena", "Sofia"],
    "Proyecto Gamma": ["Carlos"]
}
print(mapear_proyectos_por_empleado(proyectos))
# {'Elena': ['Proyecto Alpha', 'Proyecto Beta'], 'Carlos': ['Proyecto Alpha', 'Proyecto Gamma'], 'David': ['Proyecto Beta'], 'Sofia': ['Proyecto Beta']}

EJERCICIO 4

Implemente la función generar_resumen_inventario(items_bodega) que recibe una lista de cadenas en el formato "CODIGO;PRODUCTO;CANTIDAD" y retorna un diccionario {CODIGO: [NombreDelProducto, CantidadTotal]}. Si un código se repite, conserve el primer nombre y sume las cantidades (enteras).

RESOLUCIÓN

# Resume el inventario acumulando cantidades por código; conserva el primer nombre visto.
def generar_resumen_inventario(items_bodega):
    resumen = {}
    for linea in items_bodega:
        partes = linea.split(";")
        if len(partes) != 3:
            continue
        codigo, producto, cantidad = partes
        codigo = codigo.strip()
        producto = producto.strip()
        try:
            cantidad = int(cantidad.strip())
        except ValueError:
            continue
        if codigo in resumen:
            resumen[codigo][1] += cantidad
        else:
            resumen[codigo] = [producto, cantidad]
    return resumen

# Ejemplo de uso (produce la salida del enunciado).
items = [
    "HW-001;Teclado Mecanico;50",
    "SW-001;Licencia OS;100",
    "HW-002;Mouse Gamer;75",
    "HW-001;Teclado Mecanico;25",
    "HW-001;Teclado Inalambrico;10"
]
print(generar_resumen_inventario(items))
# {'HW-001': ['Teclado Mecanico', 85], 'SW-001': ['Licencia OS', 100], 'HW-002': ['Mouse Gamer', 75]}