¿Superaste la Parte 1 sin problemas? Entonces es hora de subir la dificultad. En los exámenes finales de programación no solo basta con saber hacer un bucle; necesitas dominar la búsqueda eficiente, el manejo de errores y la Programación Orientada a Objetos (POO).
Aquí tienes otros 10 enunciados clásicos que tocan temas como Búsqueda Binaria, Ficheros, Herencia y Estructuras de Datos optimizadas.
11. Búsqueda Binaria (Binary Search)
El Enunciado: Dada una lista ordenada, encontrar la posición de un número objetivo. Si no existe, devolver -1. Debes hacerlo con una complejidad O(log n), no lineal.
def busqueda_binaria(lista, objetivo):
izquierda = 0
derecha = len(lista) - 1
while izquierda <= derecha:
medio = (izquierda + derecha) // 2
if lista[medio] == objetivo:
return medio # Encontrado
elif lista[medio] < objetivo:
izquierda = medio + 1
else:
derecha = medio - 1
return -1 # No encontrado
numeros = [1, 3, 5, 7, 9, 11, 15]
print(busqueda_binaria(numeros, 9)) # Salida: 4 (índice)
12. Lectura de Archivos y Conteo de Líneas
El Enunciado: Escribe una función que lea un archivo de texto (ej. "datos.txt") y cuente cuántas líneas tiene. Debes manejar la posibilidad de que el archivo no exista.
def contar_lineas(nombre_archivo):
try:
with open(nombre_archivo, 'r') as archivo:
lineas = archivo.readlines()
return len(lineas)
except FileNotFoundError:
return "Error: El archivo no existe."
# Nota: Necesitas crear un archivo 'notas.txt' para probarlo
# print(contar_lineas("notas.txt"))
13. Herencia en Clases (POO)
El Enunciado: Crea una clase Persona y una clase hija Empleado. El empleado debe heredar el nombre de la persona y añadir un atributo salario.
class Persona:
def __init__(self, nombre, edad):
self.nombre = nombre
self.edad = edad
class Empleado(Persona):
def __init__(self, nombre, edad, salario):
# Llamamos al constructor de la clase padre
super().__init__(nombre, edad)
self.salario = salario
def mostrar_datos(self):
return f"Emp: {self.nombre}, Salario: ${self.salario}"
admin = Empleado("Ana", 30, 2500)
print(admin.mostrar_datos())
14. Eliminar duplicados de una lista
El Enunciado: Dada una lista con elementos repetidos, devolver una nueva lista con los elementos únicos (sin usar bucles anidados excesivos).
def eliminar_duplicados(lista):
# Convertir a set elimina duplicados automáticamente
# Luego volvemos a convertir a lista
return list(set(lista))
items = [1, 2, 2, 3, 4, 4, 4, 5]
print(eliminar_duplicados(items))
# Salida: [1, 2, 3, 4, 5] (El orden puede variar)
15. Anagramas
El Enunciado: Determinar si dos cadenas de texto son anagramas (contienen exactamente las mismas letras en diferente orden).
def son_anagramas(palabra1, palabra2):
# Ordenamos las letras y comparamos
return sorted(palabra1.lower()) == sorted(palabra2.lower())
print(son_anagramas("Roma", "Amor")) # True
print(son_anagramas("Casa", "Caza")) # False
16. Comprensión de Listas con Condicionales
El Enunciado: Dada una lista de números, crear una nueva lista que contenga solo los números pares elevados al cuadrado, utilizando una sola línea de código.
numeros = [1, 2, 3, 4, 5, 6]
# Sintaxis: [expresion for item in lista if condicion]
cuadrados_pares = [x**2 for x in numeros if x % 2 == 0]
print(cuadrados_pares)
# Salida: [4, 16, 36] (2^2, 4^2, 6^2)
17. Diccionario de Listas (Agrupación)
El Enunciado: Tienes una lista de tuplas (alumno, materia). Crea un diccionario donde la clave sea la materia y el valor sea una lista de alumnos inscritos en ella.
datos = [("Juan", "Mate"), ("Ana", "Física"), ("Luis", "Mate")]
def agrupar_por_materia(datos):
grupo = {}
for alumno, materia in datos:
if materia not in grupo:
grupo[materia] = []
grupo[materia].append(alumno)
return grupo
print(agrupar_por_materia(datos))
# Salida: {'Mate': ['Juan', 'Luis'], 'Física': ['Ana']}
18. La Suma de Dos (Two Sum)
El Enunciado: Dada una lista de números y un valor objetivo, encuentra los índices de los dos números que suman ese valor.
def two_sum(nums, target):
vistos = {} # Valor: Índice
for i, num in enumerate(nums):
complemento = target - num
if complemento in vistos:
return [vistos[complemento], i]
vistos[num] = i
print(two_sum([2, 7, 11, 15], 9))
# Salida: [0, 1] (porque 2 + 7 = 9)
19. Generadores (Yield)
El Enunciado: Escribe una función generadora que produzca una secuencia de números pares hasta un límite dado, para ahorrar memoria.
def generar_pares(limite):
num = 0
while num < limite:
yield num
num += 2
# Uso del generador
for par in generar_pares(10):
print(par, end=" ")
# Salida: 0 2 4 6 8
20. Manejo de Excepciones: División Segura
El Enunciado: Crea una función que divida dos números. Debe controlar si el usuario introduce texto en lugar de números o si intenta dividir por cero.
def division_segura(a, b):
try:
resultado = float(a) / float(b)
return resultado
except ZeroDivisionError:
return "Error: No puedes dividir por 0"
except ValueError:
return "Error: Debes introducir números"
print(division_segura(10, 0)) # Error controlado
print(division_segura(10, "dos")) # Error controlado
Conclusión Parte 2
Si eres capaz de resolver estos ejercicios sin mirar la solución, ¡felicidades! Estás muy por encima de la media. Estos conceptos (especialmente diccionarios, manejo de errores y clases) son el pan de cada día en el mundo profesional.
¿Quieres seguir avanzando? Lo próximo sería entrar en estructuras de datos avanzadas como Árboles Binarios o algoritmos de grafos. ¡Dímelo en los comentarios si quieres una Parte 3!
No hay comentarios:
Publicar un comentario