From f6a5e62e6f24e00134dc8d376d00c9599fcfdc9b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 4 Apr 2026 00:29:44 +0000 Subject: [PATCH 1/3] Initial plan From 9f93f50b6956e12c3afcae64b5026e5f7cfd6196 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 4 Apr 2026 00:35:08 +0000 Subject: [PATCH 2/3] Add Python exercises organized by complexity level (basico, intermedio, avanzado, algoritmos) Agent-Logs-Url: https://github.com/BrandonCabra/ejercicios_python/sessions/7ceb4281-0576-4193-94c3-45c8ede397b0 Co-authored-by: BrandonCabra <173741999+BrandonCabra@users.noreply.github.com> --- README.md | 51 +++- algoritmos/01_ordenamiento.py | 147 ++++++++++++ algoritmos/02_busqueda.py | 121 ++++++++++ algoritmos/03_recursion.py | 139 +++++++++++ algoritmos/04_estructuras_datos.py | 223 ++++++++++++++++++ .../01_ordenamiento.cpython-312.pyc | Bin 0 -> 1316 bytes .../__pycache__/02_busqueda.cpython-312.pyc | Bin 0 -> 1445 bytes .../__pycache__/03_recursion.cpython-312.pyc | Bin 0 -> 1649 bytes .../04_estructuras_datos.cpython-312.pyc | Bin 0 -> 5559 bytes avanzado/01_poo_clases.py | 170 +++++++++++++ avanzado/02_decoradores.py | 138 +++++++++++ avanzado/03_generadores.py | 114 +++++++++ .../__pycache__/01_poo_clases.cpython-312.pyc | Bin 0 -> 3982 bytes .../02_decoradores.cpython-312.pyc | Bin 0 -> 2559 bytes .../03_generadores.cpython-312.pyc | Bin 0 -> 1853 bytes basico/01_variables_y_tipos.py | 54 +++++ basico/02_condicionales.py | 76 ++++++ basico/03_bucles.py | 82 +++++++ basico/04_funciones.py | 94 ++++++++ basico/05_listas.py | 89 +++++++ .../01_variables_y_tipos.cpython-312.pyc | Bin 0 -> 654 bytes .../02_condicionales.cpython-312.pyc | Bin 0 -> 453 bytes basico/__pycache__/03_bucles.cpython-312.pyc | Bin 0 -> 255 bytes .../__pycache__/04_funciones.cpython-312.pyc | Bin 0 -> 1194 bytes basico/__pycache__/05_listas.cpython-312.pyc | Bin 0 -> 750 bytes intermedio/01_diccionarios_y_conjuntos.py | 87 +++++++ intermedio/02_funciones_orden_superior.py | 86 +++++++ intermedio/03_comprensiones.py | 80 +++++++ intermedio/04_archivos_y_excepciones.py | 105 +++++++++ ...1_diccionarios_y_conjuntos.cpython-312.pyc | Bin 0 -> 683 bytes ...2_funciones_orden_superior.cpython-312.pyc | Bin 0 -> 1147 bytes .../03_comprensiones.cpython-312.pyc | Bin 0 -> 611 bytes .../04_archivos_y_excepciones.cpython-312.pyc | Bin 0 -> 1243 bytes 33 files changed, 1854 insertions(+), 2 deletions(-) create mode 100644 algoritmos/01_ordenamiento.py create mode 100644 algoritmos/02_busqueda.py create mode 100644 algoritmos/03_recursion.py create mode 100644 algoritmos/04_estructuras_datos.py create mode 100644 algoritmos/__pycache__/01_ordenamiento.cpython-312.pyc create mode 100644 algoritmos/__pycache__/02_busqueda.cpython-312.pyc create mode 100644 algoritmos/__pycache__/03_recursion.cpython-312.pyc create mode 100644 algoritmos/__pycache__/04_estructuras_datos.cpython-312.pyc create mode 100644 avanzado/01_poo_clases.py create mode 100644 avanzado/02_decoradores.py create mode 100644 avanzado/03_generadores.py create mode 100644 avanzado/__pycache__/01_poo_clases.cpython-312.pyc create mode 100644 avanzado/__pycache__/02_decoradores.cpython-312.pyc create mode 100644 avanzado/__pycache__/03_generadores.cpython-312.pyc create mode 100644 basico/01_variables_y_tipos.py create mode 100644 basico/02_condicionales.py create mode 100644 basico/03_bucles.py create mode 100644 basico/04_funciones.py create mode 100644 basico/05_listas.py create mode 100644 basico/__pycache__/01_variables_y_tipos.cpython-312.pyc create mode 100644 basico/__pycache__/02_condicionales.cpython-312.pyc create mode 100644 basico/__pycache__/03_bucles.cpython-312.pyc create mode 100644 basico/__pycache__/04_funciones.cpython-312.pyc create mode 100644 basico/__pycache__/05_listas.cpython-312.pyc create mode 100644 intermedio/01_diccionarios_y_conjuntos.py create mode 100644 intermedio/02_funciones_orden_superior.py create mode 100644 intermedio/03_comprensiones.py create mode 100644 intermedio/04_archivos_y_excepciones.py create mode 100644 intermedio/__pycache__/01_diccionarios_y_conjuntos.cpython-312.pyc create mode 100644 intermedio/__pycache__/02_funciones_orden_superior.cpython-312.pyc create mode 100644 intermedio/__pycache__/03_comprensiones.cpython-312.pyc create mode 100644 intermedio/__pycache__/04_archivos_y_excepciones.cpython-312.pyc diff --git a/README.md b/README.md index ca69ccf..e9339d3 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,49 @@ -# ejercicios_python -ejercicios de lógica y entrenamiento de python +# Ejercicios Python + +Repositorio de ejercicios de Python para el entrenamiento de conceptos, lógica de programación y algoritmos, organizados por nivel de complejidad. + +## Estructura del repositorio + +``` +ejercicios_python/ +├── basico/ # Nivel 1 – Conceptos fundamentales +├── intermedio/ # Nivel 2 – Estructuras de datos y funciones avanzadas +├── avanzado/ # Nivel 3 – POO, decoradores, generadores +└── algoritmos/ # Algoritmos clásicos y estructuras de datos +``` + +## Niveles + +### 🟢 Básico +Ejercicios orientados a quienes están dando sus primeros pasos en Python. +Temas: variables, tipos de datos, condicionales, bucles y funciones simples. + +### 🟡 Intermedio +Ejercicios para quienes ya conocen lo básico y quieren profundizar. +Temas: listas avanzadas, diccionarios, funciones de orden superior, manejo de archivos y excepciones. + +### 🔴 Avanzado +Ejercicios que exploran características más potentes del lenguaje. +Temas: programación orientada a objetos, decoradores, generadores y comprensiones. + +### ⚙️ Algoritmos +Implementaciones de algoritmos y estructuras de datos clásicas. +Temas: ordenamiento, búsqueda, recursión y estructuras lineales/no lineales. + +## Cómo usar este repositorio + +1. Clona el repositorio: + ```bash + git clone https://github.com/BrandonCabra/ejercicios_python.git + ``` +2. Navega al nivel que te corresponda y abre el archivo `.py` que quieras practicar. +3. Lee el enunciado incluido como comentario al inicio de cada archivo. +4. Escribe tu solución y ejecútala con: + ```bash + python nombre_del_archivo.py + ``` + +## Requisitos + +- Python 3.8 o superior. +- No se requieren librerías externas; todos los ejercicios usan la biblioteca estándar. diff --git a/algoritmos/01_ordenamiento.py b/algoritmos/01_ordenamiento.py new file mode 100644 index 0000000..f28c14b --- /dev/null +++ b/algoritmos/01_ordenamiento.py @@ -0,0 +1,147 @@ +# ============================================================= +# Ejercicio: Algoritmos de ordenamiento +# Nivel: Algoritmos +# ============================================================= +# Descripción: +# Implementa los algoritmos de ordenamiento más conocidos +# y compara su comportamiento. +# ============================================================= + +# ------ Tarea 1: Bubble Sort ------ +# Implementa el algoritmo Bubble Sort. +# Idea: compara pares adyacentes e intercambia si están +# en el orden incorrecto; repite hasta que no haya cambios. +def bubble_sort(lista): + arr = lista[:] # No modificar la lista original + # Tu código aquí: + return arr + +datos = [64, 25, 12, 22, 11] +print("Bubble Sort:", bubble_sort(datos)) +# Esperado: [11, 12, 22, 25, 64] + + +# ------ Tarea 2: Selection Sort ------ +# Implementa Selection Sort. +# Idea: busca el mínimo del subarreglo no ordenado y lo +# coloca al inicio en cada iteración. +def selection_sort(lista): + arr = lista[:] + # Tu código aquí: + return arr + +print("Selection Sort:", selection_sort(datos)) +# Esperado: [11, 12, 22, 25, 64] + + +# ------ Tarea 3: Insertion Sort ------ +# Implementa Insertion Sort. +# Idea: toma un elemento y lo inserta en su posición correcta +# dentro del subarreglo ya ordenado. +def insertion_sort(lista): + arr = lista[:] + # Tu código aquí: + return arr + +print("Insertion Sort:", insertion_sort(datos)) +# Esperado: [11, 12, 22, 25, 64] + + +# ------ Tarea 4: Merge Sort ------ +# Implementa Merge Sort de forma recursiva. +# Idea: divide la lista en mitades, ordena cada mitad y combina. +def merge_sort(lista): + if len(lista) <= 1: + return lista + # Tu código aquí: + pass + +print("Merge Sort:", merge_sort(datos)) +# Esperado: [11, 12, 22, 25, 64] + + +# ------ Tarea 5: Quick Sort ------ +# Implementa Quick Sort de forma recursiva. +# Idea: elige un pivote, separa los menores y mayores, y ordena recursivamente. +def quick_sort(lista): + if len(lista) <= 1: + return lista + # Tu código aquí (elige el primer elemento como pivote): + pass + +print("Quick Sort:", quick_sort(datos)) +# Esperado: [11, 12, 22, 25, 64] + + +# ------ Tarea 6: Comparación de rendimiento ------ +# Usando el módulo timeit, mide cuánto tarda cada algoritmo +# en ordenar una lista de 1000 elementos aleatorios. +import timeit +import random + +grande = random.sample(range(10000), 1000) + +# Tu código aquí: mide y compara tiempos + + +# ============================================================= +# Ejemplos de solución +# ============================================================= +# --- Tarea 1 --- +# def bubble_sort(lista): +# arr = lista[:] +# n = len(arr) +# for i in range(n): +# for j in range(0, n - i - 1): +# if arr[j] > arr[j + 1]: +# arr[j], arr[j + 1] = arr[j + 1], arr[j] +# return arr + +# --- Tarea 2 --- +# def selection_sort(lista): +# arr = lista[:] +# n = len(arr) +# for i in range(n): +# idx_min = i +# for j in range(i + 1, n): +# if arr[j] < arr[idx_min]: +# idx_min = j +# arr[i], arr[idx_min] = arr[idx_min], arr[i] +# return arr + +# --- Tarea 3 --- +# def insertion_sort(lista): +# arr = lista[:] +# for i in range(1, len(arr)): +# clave = arr[i] +# j = i - 1 +# while j >= 0 and arr[j] > clave: +# arr[j + 1] = arr[j] +# j -= 1 +# arr[j + 1] = clave +# return arr + +# --- Tarea 4 --- +# def merge_sort(lista): +# if len(lista) <= 1: +# return lista +# mid = len(lista) // 2 +# izq = merge_sort(lista[:mid]) +# der = merge_sort(lista[mid:]) +# resultado = [] +# i = j = 0 +# while i < len(izq) and j < len(der): +# if izq[i] <= der[j]: +# resultado.append(izq[i]); i += 1 +# else: +# resultado.append(der[j]); j += 1 +# return resultado + izq[i:] + der[j:] + +# --- Tarea 5 --- +# def quick_sort(lista): +# if len(lista) <= 1: +# return lista +# pivote = lista[0] +# menores = [x for x in lista[1:] if x <= pivote] +# mayores = [x for x in lista[1:] if x > pivote] +# return quick_sort(menores) + [pivote] + quick_sort(mayores) diff --git a/algoritmos/02_busqueda.py b/algoritmos/02_busqueda.py new file mode 100644 index 0000000..8c7f3c5 --- /dev/null +++ b/algoritmos/02_busqueda.py @@ -0,0 +1,121 @@ +# ============================================================= +# Ejercicio: Algoritmos de búsqueda +# Nivel: Algoritmos +# ============================================================= +# Descripción: +# Implementa los algoritmos de búsqueda más comunes y +# analiza su complejidad temporal. +# ============================================================= + +# ------ Tarea 1: Búsqueda lineal ------ +# Implementa la búsqueda lineal: recorre la lista elemento +# a elemento hasta encontrar el objetivo. +# Retorna el índice si lo encuentra, o -1 si no existe. +def busqueda_lineal(lista, objetivo): + # Tu código aquí: + pass + +numeros = [5, 3, 8, 1, 9, 2, 7, 4, 6] +print(busqueda_lineal(numeros, 9)) # 4 +print(busqueda_lineal(numeros, 10)) # -1 + + +# ------ Tarea 2: Búsqueda binaria (iterativa) ------ +# La lista DEBE estar ordenada. Divide el espacio de búsqueda +# a la mitad en cada paso. +# Complejidad: O(log n) +def busqueda_binaria(lista, objetivo): + izquierda, derecha = 0, len(lista) - 1 + # Tu código aquí: + pass + +ordenada = sorted(numeros) +print("Lista ordenada:", ordenada) +print(busqueda_binaria(ordenada, 7)) # índice de 7 en la lista ordenada +print(busqueda_binaria(ordenada, 10)) # -1 + + +# ------ Tarea 3: Búsqueda binaria (recursiva) ------ +def busqueda_binaria_recursiva(lista, objetivo, izquierda=None, derecha=None): + if izquierda is None: + izquierda = 0 + if derecha is None: + derecha = len(lista) - 1 + # Tu código aquí: + pass + +print(busqueda_binaria_recursiva(ordenada, 7)) +print(busqueda_binaria_recursiva(ordenada, 10)) + + +# ------ Tarea 4: Búsqueda en matriz ------ +# Dada una matriz n×m de números enteros ordenados de forma +# que cada fila está ordenada de izquierda a derecha y la +# primera celda de cada fila es mayor que la última de la +# fila anterior, determina si un objetivo existe en la matriz. +def buscar_en_matriz(matriz, objetivo): + # Tu código aquí (pista: aplica búsqueda binaria): + pass + +matriz = [ + [1, 3, 5, 7], + [10, 11, 16, 20], + [23, 30, 34, 60], +] +print(buscar_en_matriz(matriz, 3)) # True +print(buscar_en_matriz(matriz, 13)) # False + + +# ============================================================= +# Ejemplos de solución +# ============================================================= +# --- Tarea 1 --- +# def busqueda_lineal(lista, objetivo): +# for i, valor in enumerate(lista): +# if valor == objetivo: +# return i +# return -1 + +# --- Tarea 2 --- +# def busqueda_binaria(lista, objetivo): +# izquierda, derecha = 0, len(lista) - 1 +# while izquierda <= derecha: +# medio = (izquierda + derecha) // 2 +# if lista[medio] == objetivo: +# return medio +# elif lista[medio] < objetivo: +# izquierda = medio + 1 +# else: +# derecha = medio - 1 +# return -1 + +# --- Tarea 3 --- +# def busqueda_binaria_recursiva(lista, objetivo, izquierda=None, derecha=None): +# if izquierda is None: izquierda = 0 +# if derecha is None: derecha = len(lista) - 1 +# if izquierda > derecha: +# return -1 +# medio = (izquierda + derecha) // 2 +# if lista[medio] == objetivo: +# return medio +# elif lista[medio] < objetivo: +# return busqueda_binaria_recursiva(lista, objetivo, medio + 1, derecha) +# else: +# return busqueda_binaria_recursiva(lista, objetivo, izquierda, medio - 1) + +# --- Tarea 4 --- +# def buscar_en_matriz(matriz, objetivo): +# if not matriz: +# return False +# filas, cols = len(matriz), len(matriz[0]) +# izq, der = 0, filas * cols - 1 +# while izq <= der: +# mid = (izq + der) // 2 +# valor = matriz[mid // cols][mid % cols] +# if valor == objetivo: +# return True +# elif valor < objetivo: +# izq = mid + 1 +# else: +# der = mid - 1 +# return False diff --git a/algoritmos/03_recursion.py b/algoritmos/03_recursion.py new file mode 100644 index 0000000..3f81236 --- /dev/null +++ b/algoritmos/03_recursion.py @@ -0,0 +1,139 @@ +# ============================================================= +# Ejercicio: Recursión +# Nivel: Algoritmos +# ============================================================= +# Descripción: +# La recursión es una técnica donde una función se llama a sí +# misma para resolver subproblemas más pequeños. +# Regla de oro: siempre define un caso base para detener la recursión. +# ============================================================= + +import sys +sys.setrecursionlimit(10000) + +# ------ Tarea 1: Factorial recursivo ------ +def factorial(n): + # Caso base: + # Tu código aquí: + pass + +print(factorial(5)) # 120 +print(factorial(0)) # 1 +print(factorial(10)) # 3628800 + + +# ------ Tarea 2: Fibonacci recursivo ------ +# Implementa la función de Fibonacci de forma recursiva. +# Nota: esta versión naive es O(2^n); observa cómo se ralentiza +# para valores grandes. +def fibonacci(n): + # Tu código aquí: + pass + +print([fibonacci(i) for i in range(10)]) +# Esperado: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34] + + +# ------ Tarea 3: Fibonacci con memoización ------ +# Mejora la versión anterior usando un diccionario de caché +# para evitar recálculos (memoización manual o @functools.lru_cache). +from functools import lru_cache + +@lru_cache(maxsize=None) +def fibonacci_memo(n): + # Tu código aquí: + pass + +print(fibonacci_memo(50)) # 12586269025 (instantáneo) + + +# ------ Tarea 4: Torres de Hanói ------ +# Imprime los movimientos necesarios para mover n discos +# del poste origen al destino, usando un poste auxiliar. +def hanoi(n, origen="A", destino="C", auxiliar="B"): + # Tu código aquí: + pass + +hanoi(3) +# Esperado (7 movimientos): +# Mover disco 1 de A a C +# Mover disco 2 de A a B +# Mover disco 1 de C a B +# Mover disco 3 de A a C +# Mover disco 1 de B a A +# Mover disco 2 de B a C +# Mover disco 1 de A a C + + +# ------ Tarea 5: Potencia recursiva ------ +# Calcula x^n de forma recursiva eficiente usando la propiedad: +# x^n = (x^(n//2))^2 si n es par +# x^n = x * x^(n-1) si n es impar +def potencia(x, n): + # Tu código aquí: + pass + +print(potencia(2, 10)) # 1024 +print(potencia(3, 5)) # 243 +print(potencia(5, 0)) # 1 + + +# ------ Tarea 6: Suma de dígitos ------ +# Dado un número entero, calcula la suma de sus dígitos +# de forma recursiva. Ejemplo: suma_digitos(123) = 6 +def suma_digitos(n): + n = abs(n) + # Tu código aquí: + pass + +print(suma_digitos(123)) # 6 +print(suma_digitos(9999)) # 36 +print(suma_digitos(0)) # 0 + + +# ============================================================= +# Ejemplos de solución +# ============================================================= +# --- Tarea 1 --- +# def factorial(n): +# if n == 0: +# return 1 +# return n * factorial(n - 1) + +# --- Tarea 2 --- +# def fibonacci(n): +# if n <= 1: +# return n +# return fibonacci(n - 1) + fibonacci(n - 2) + +# --- Tarea 3 --- +# @lru_cache(maxsize=None) +# def fibonacci_memo(n): +# if n <= 1: +# return n +# return fibonacci_memo(n - 1) + fibonacci_memo(n - 2) + +# --- Tarea 4 --- +# def hanoi(n, origen="A", destino="C", auxiliar="B"): +# if n == 1: +# print(f"Mover disco 1 de {origen} a {destino}") +# return +# hanoi(n - 1, origen, auxiliar, destino) +# print(f"Mover disco {n} de {origen} a {destino}") +# hanoi(n - 1, auxiliar, destino, origen) + +# --- Tarea 5 --- +# def potencia(x, n): +# if n == 0: +# return 1 +# if n % 2 == 0: +# mitad = potencia(x, n // 2) +# return mitad * mitad +# return x * potencia(x, n - 1) + +# --- Tarea 6 --- +# def suma_digitos(n): +# n = abs(n) +# if n < 10: +# return n +# return n % 10 + suma_digitos(n // 10) diff --git a/algoritmos/04_estructuras_datos.py b/algoritmos/04_estructuras_datos.py new file mode 100644 index 0000000..787f3c4 --- /dev/null +++ b/algoritmos/04_estructuras_datos.py @@ -0,0 +1,223 @@ +# ============================================================= +# Ejercicio: Estructuras de datos lineales +# Nivel: Algoritmos +# ============================================================= +# Descripción: +# Implementa las estructuras de datos más importantes desde +# cero usando clases de Python: Pila, Cola y Lista enlazada. +# ============================================================= + +# ============================================================= +# Parte 1: Pila (Stack) – LIFO (Last In, First Out) +# ============================================================= +# Operaciones requeridas: +# push(dato) – añade un elemento en la cima +# pop() – elimina y retorna el elemento de la cima +# peek() – retorna el elemento de la cima sin eliminarlo +# is_empty() – True si la pila está vacía +# __len__() – número de elementos en la pila +class Pila: + def __init__(self): + self._datos = [] + + def push(self, dato): + # Tu código aquí: + pass + + def pop(self): + # Tu código aquí (lanza IndexError si está vacía): + pass + + def peek(self): + # Tu código aquí: + pass + + def is_empty(self): + # Tu código aquí: + pass + + def __len__(self): + return len(self._datos) + + def __repr__(self): + return f"Pila({self._datos})" + + +# Pruebas de Pila +pila = Pila() +pila.push(1) +pila.push(2) +pila.push(3) +print(pila) # Pila([1, 2, 3]) +print(pila.peek()) # 3 +print(pila.pop()) # 3 +print(len(pila)) # 2 +print(pila.is_empty()) # False + + +# ============================================================= +# Parte 2: Cola (Queue) – FIFO (First In, First Out) +# ============================================================= +from collections import deque + +class Cola: + def __init__(self): + self._datos = deque() + + def enqueue(self, dato): + # Tu código aquí: + pass + + def dequeue(self): + # Tu código aquí (lanza IndexError si está vacía): + pass + + def frente(self): + # Tu código aquí: + pass + + def is_empty(self): + return len(self._datos) == 0 + + def __len__(self): + return len(self._datos) + + def __repr__(self): + return f"Cola({list(self._datos)})" + + +# Pruebas de Cola +cola = Cola() +cola.enqueue("a") +cola.enqueue("b") +cola.enqueue("c") +print(cola) # Cola(['a', 'b', 'c']) +print(cola.frente()) # 'a' +print(cola.dequeue()) # 'a' +print(len(cola)) # 2 + + +# ============================================================= +# Parte 3: Lista enlazada simple +# ============================================================= +class Nodo: + def __init__(self, dato): + self.dato = dato + self.siguiente = None + + +class ListaEnlazada: + def __init__(self): + self.cabeza = None + + def agregar_al_final(self, dato): + # Tu código aquí: + pass + + def agregar_al_inicio(self, dato): + # Tu código aquí: + pass + + def eliminar(self, dato): + # Elimina la primera aparición del dato. + # Tu código aquí: + pass + + def buscar(self, dato): + # Retorna True si el dato está en la lista. + # Tu código aquí: + pass + + def __len__(self): + cuenta = 0 + actual = self.cabeza + while actual: + cuenta += 1 + actual = actual.siguiente + return cuenta + + def __repr__(self): + elementos = [] + actual = self.cabeza + while actual: + elementos.append(str(actual.dato)) + actual = actual.siguiente + return " -> ".join(elementos) + " -> None" + + +# Pruebas de Lista enlazada +lista = ListaEnlazada() +lista.agregar_al_final(1) +lista.agregar_al_final(2) +lista.agregar_al_final(3) +lista.agregar_al_inicio(0) +print(lista) # 0 -> 1 -> 2 -> 3 -> None +print(len(lista)) # 4 +print(lista.buscar(2)) # True +print(lista.buscar(9)) # False +lista.eliminar(2) +print(lista) # 0 -> 1 -> 3 -> None + + +# ============================================================= +# Ejemplos de solución +# ============================================================= +# --- Pila --- +# def push(self, dato): +# self._datos.append(dato) +# def pop(self): +# if self.is_empty(): +# raise IndexError("La pila está vacía") +# return self._datos.pop() +# def peek(self): +# if self.is_empty(): +# raise IndexError("La pila está vacía") +# return self._datos[-1] +# def is_empty(self): +# return len(self._datos) == 0 + +# --- Cola --- +# def enqueue(self, dato): +# self._datos.append(dato) +# def dequeue(self): +# if self.is_empty(): +# raise IndexError("La cola está vacía") +# return self._datos.popleft() +# def frente(self): +# return self._datos[0] + +# --- Lista enlazada --- +# def agregar_al_final(self, dato): +# nuevo = Nodo(dato) +# if not self.cabeza: +# self.cabeza = nuevo +# return +# actual = self.cabeza +# while actual.siguiente: +# actual = actual.siguiente +# actual.siguiente = nuevo + +# def agregar_al_inicio(self, dato): +# nuevo = Nodo(dato) +# nuevo.siguiente = self.cabeza +# self.cabeza = nuevo + +# def eliminar(self, dato): +# if not self.cabeza: +# return +# if self.cabeza.dato == dato: +# self.cabeza = self.cabeza.siguiente +# return +# actual = self.cabeza +# while actual.siguiente and actual.siguiente.dato != dato: +# actual = actual.siguiente +# if actual.siguiente: +# actual.siguiente = actual.siguiente.siguiente + +# def buscar(self, dato): +# actual = self.cabeza +# while actual: +# if actual.dato == dato: +# return True +# actual = actual.siguiente +# return False diff --git a/algoritmos/__pycache__/01_ordenamiento.cpython-312.pyc b/algoritmos/__pycache__/01_ordenamiento.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9c0eb03a1d04c66cb265e8d13a6f134250d0beea GIT binary patch literal 1316 zcmb_bJ8#oa6h7CEoy2)ns139iEk$+OVFMFva5^=dj}8;?gwG{)x%xEKd7>R|$ zN!+C~r%|6Eoy9o{7u|)2$h7P)5(HNNqFutMgg=BE& zd_^yNj_WJy!mvF-Dhryppgsk~^i|KWxZ(M#DBHSY`KnvC)=lm!_+8cW==;~{3wa+y45W0DDAOJ`!L-dYVDU*}%sn$_+5 PZ)-dE+VRWJ)IhW!!A%Il literal 0 HcmV?d00001 diff --git a/algoritmos/__pycache__/02_busqueda.cpython-312.pyc b/algoritmos/__pycache__/02_busqueda.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..316dd18c37bbce92d68e3df4f253398f4003e7c3 GIT binary patch literal 1445 zcmaJ{xluw4*%Ko6gsJ-rqU*eD3N>1D=NuHr(6Y06$1b z4sTy}3k+Zd1iXMEOoL$WS&?ZVHT*y_p?%a^o*&VV4ugGG{iszKm`O(;L$V~MXi|(Y zrJ4Bu&Z0|G@I;&VAF%$dMz^qEup)0W;s4D+*1zRQAx{fCPQPb}9Wizy>P5Sq*OIpA z`X@KCW{z6tt$cQ>J+s!t5Ow@^4TKe#hjmt1hrAY=W!JAdq3umRl2v!k^C>Eq+dJWu zr#Ue3g=Firoa7G``huw)#D!Ucwl$DJk8A@&<1n}Lkcku%GR78r1>PF-f z(d$Ji0;&>O1VkvJMNqgM5Ye(6U{3a!`3PQcM_9GJ0|1MVyp_-vFmOp<(y%kV5TPq5 zqO{IJy(}y1h9WA8>VzqGVYcQbSsW>9d#PjC-L+9 z5dzpcG5GGzn)&wLhn_cui>{$`@h3@+_&zz@(tT@8Cp?XkTn4E=iF5_hd z7PUYVY)McU%ID-`mn zcp*cpQk#*=^F#Boax2yN2}ACCswxHUd;5Xn(I`r#&Jj>YF|D|PJ$qut6ScCusm9Pi zo9BN**wz_iJEt_3+OeVILSTIb^SM`_UY%|5b4?gZMAhI!O&H$E=q&X!4V}I9i!W~l zHkvp1@zsHr=O*v3KV9o-@Zlzmps6MIHuy*r&hOeBL$kp6CeN)6e7M%&SDG*yyOBKJ o;G<0#+sP7_G?;y%LBDOwNNWMdniSYypWDZ*B@?wTFdX;#3nQy0TmS$7 literal 0 HcmV?d00001 diff --git a/algoritmos/__pycache__/03_recursion.cpython-312.pyc b/algoritmos/__pycache__/03_recursion.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..74c3ef56c9d025d29f28c935e12918ef46f37b41 GIT binary patch literal 1649 zcmbVM&2JM&6o0e3UavpmB;=z3Q53iYBk>v96RMQb11AoM9%@lV%g*8q+K(`^7I8}? zM^2?kMXGyBt6q9V@K12&(!#cd6$emHz6D#Y)SUWe?O8h@dgw?qZ|1$<{NBgB-6sf2D$5UJzTsG%%M z63H^Kfzl~CX3Hs^lE`c#voXA#qZ#5e_zoPcj`K^*XjAeV_cHG9wfkiQZJU_}nSka! z)6duPsmDAek1XYf7PjHxAQ`AxLvI!>D!Y=%a)_3;Nv(jG0xgf}Cos<9@Me)#Fw$Yo zMwrZ6#tOaPYEXFBN+*%OG-N2zDaEQ}R>cyXRyrleY*{@jP$oBki$6Q9hC77GI47_vMyy%AA3O6GFacm0shqLWiNxlAN=*}Z@} zM+QAU4%Bj#Qq|zHE{Tc7s=Gmwr>=-t5GI!0*kB&BxsXhYI0h-_*6bi;{0J&P!pW!P zA~Wqu56;`)?fcwn3E4Pi-vEnQdVbCDEJ8^x{g!euL>XWrB&Kl`POW$sMqX%je0hTy;{{1 zvXYR?3Hh{IPIS=}$+U2ztO-5lvncJoB)8645Ty;0t#G=y3R{qggkFZ}ey@8;4EWUJYk{^s6Ob18*YpmXh+xe&wQep%^S_O{hKrcPUHJ9j!K+F=ay zG7Nb--VS1zJ9z4qv#7n!@-y>;7#1YL>s%c04-V(s;cqbiPp?5Be^SWr^6|{%<&Uj@ E0aE2Ob^rhX literal 0 HcmV?d00001 diff --git a/algoritmos/__pycache__/04_estructuras_datos.cpython-312.pyc b/algoritmos/__pycache__/04_estructuras_datos.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..85945a232024bb26d57247af11a6494386cc3355 GIT binary patch literal 5559 zcmb_g-ESMm5#K%DosJ?UimFK2mMt@hjZ%FQ>`>zloEh3PsL?`P+r%wgvO$MGB z188T>aoe%e@bf=zW1H6%g@`5gTSJ!}? z*g@pzk}jJ{A)ED$*K$O5Ik*o8*7=!1 z&7Nh!z4;Rd<>fx~b@j@Dc#48A#(ZDIc#Mt1vzY&E0`^aMR%GHvJU>6Exi7|sbM(g8 zaE_iB11;YlqDAVp9-=Vbzvd_PpY^{3iRmE{eX9<{J>hYAzmQS!{F(jaV$Ahhx)M)M zW_!1|*-5(Z!P6FGbcX6ABj|LUWJ0k`lrT?VS?5X+hHijof7;`N-V zWj$FaA5j93gLEf>w8#=!B`VCEu|l5E#V6F3Rb8u;ESQOwVcxP(KYBxk{mA zz5ByUs$o@FHCw4N&2re!mse~>RddB$MOABKsQSFOoB|0JqCuT(C66@4KSa8yGV6jC z&iUY`i7;)E6~Yj>o{%R3!=1LsjlvzN6hnlx#d6iUT?=zfIGu)vUEEYB|52hW3bVe$ z!`eA~p9VG#kC_6*IjAE$R4$ckiX*yI#w29uvNsbdmJMUsGZ>~P4@az$vs9x{uB^CT z_m=PMEgl`soqZN2EmHAgWR>KDmjWDKY~OG%MX*DrQDh^iAn3UfRfTsD0#P>v_zF|E z8wXM+|Bg*=Txz}l@cn18lWpbXpi6z@-Uj{_6gMymX2J0nC}UrSZjf|nu_mFe)30cn z$-p*X6T~Gm%B&|Yo#hXJ*-8L`xQr(^Dy_Q@?`{+xUuehX+sZt*Y%x8GVO`V;hN{}5 zs#+-NRTJk?RlQTyOy>=Ypk6#6!(eAnxCuLgmEDZhrEPs4qGd9;&=JrYT?}S6c z?ZSj}Z`OsPU!wWg91R+P;le$12_}d&yD_{!6!xJH-o|N$aGn-y(ab?@9EOb?2K?}L zAm~@H$-?@=A?VMQM<4&~+85WJO`mQj(_h8gu`_Mu3^yBqh`j}T40DaWgM?$wIh?(V zeh1)&W6oJ_0N-a*&89bPn$3a$e|S0WwiW&D%8HN< z+2UeJFZI=XOi1qe6iixV6;OV+716OV@uc=3#{}@&VJo*(&0!v}U~0Png35dVxea?P z+z1|?g68A%@Yc~2fFk3rTg9Pn4S@AeU_V2$gwpVG*GX3pq*=!`_-43A-l%~a`xHV+ z`+3pSYMQ=pC&wKIMmWQ5o}d`WS?#7#(*}|kL#LMP6Yo2$2=DxE?bspU?S!_(j3te! znyKE(6*aRq+pjtJ{tj5s1I6DN=;J+tp)t+oO0|=FYIYc^hoo9D%v=G^%7R|@p09wS zE(TJad@Gai7!Rbr41sq}h9F4!9kJ6!1OwleZ&s}=Xq)OkpY!y0Ab?#(GSC$JX}HLh z==9zm?bbbERbW%AR2OPvgaDT?tW)G%^mE|jjhRzE=0G%*{SVQA4{#oGT6#HKg)G)= zS%VJ=&9o2>Qf`sveN!#be;OCh*MQGj0D_n~*_5~9iPp@+nWp^B_|#T(azp#f2qOW0s-$eU*U}2T!kvlLdD1{I33-+La z;dRj7FD1Z-6*Vwi|1Ib=k0}}$tN#C3;1=MW)BK95bC**!1?gg`XryKCY4B>fY!r1n z1l5Qk{&C;iV!o6sdN&X@OrrpIP_o#kz|nsLDR>f$UaygUfZW%CAgCsr;r=T~JdYmV zj2{2%jmOD<%=~@k*@<(V==q@+^2fWM-F@`qXR-OOMmJ*@+sZ{3l!w>4pMgU5F_J4t zK0&f)e|;I>A}PRMPpzBjt#u*jv`0CSrDS(PmKGd9$9>!Q-MN@f@@5;pHsKS4clfqc zX1QX;>G65D&%Y0`^4gJX$ux~@C08n1PM?d_))wKh#(1gbRhrjpUQ!#VsP<4>!Wix7MS> zr{55%uCGV<&;48@x3=6Nlg{dPzwNi&9{}&~6_N6#Y z&%Pi?-s{mCZA6 0: +# self._saldo += cantidad +# def retirar(self, cantidad): +# if cantidad > self._saldo: +# print("Fondos insuficientes") +# elif cantidad > 0: +# self._saldo -= cantidad diff --git a/avanzado/02_decoradores.py b/avanzado/02_decoradores.py new file mode 100644 index 0000000..27ff53e --- /dev/null +++ b/avanzado/02_decoradores.py @@ -0,0 +1,138 @@ +# ============================================================= +# Ejercicio: Decoradores +# Nivel: Avanzado +# ============================================================= +# Descripción: +# Los decoradores son funciones que envuelven a otras funciones +# para añadir o modificar su comportamiento sin cambiar su código. +# Sintaxis: @mi_decorador +# ============================================================= + +import time +import functools + +# ------ Tarea 1 ------ +# Crea un decorador 'cronometrar' que imprima el tiempo que +# tarda en ejecutarse la función decorada. +def cronometrar(func): + @functools.wraps(func) + def envoltura(*args, **kwargs): + # Tu código aquí: + pass + return envoltura + +@cronometrar +def operacion_lenta(): + time.sleep(0.1) + return "Listo" + +print(operacion_lenta()) +# Esperado: "operacion_lenta tardó X.XXs" y "Listo" + + +# ------ Tarea 2 ------ +# Crea un decorador 'registrar' que imprima el nombre de la +# función y los argumentos con que fue llamada, antes de ejecutarla. +def registrar(func): + @functools.wraps(func) + def envoltura(*args, **kwargs): + # Tu código aquí: + pass + return envoltura + +@registrar +def sumar(a, b): + return a + b + +print(sumar(3, 7)) +# Esperado: +# Llamando a: sumar con args=(3, 7), kwargs={} +# 10 + + +# ------ Tarea 3 ------ +# Crea un decorador 'reintentar' que vuelva a ejecutar la función +# hasta 3 veces si lanza una excepción, y la propague al tercer fallo. +def reintentar(func): + @functools.wraps(func) + def envoltura(*args, **kwargs): + # Tu código aquí: + pass + return envoltura + +contador_llamadas = 0 + +@reintentar +def puede_fallar(): + global contador_llamadas + contador_llamadas += 1 + if contador_llamadas < 3: + raise ValueError("Error temporal") + return "Éxito en el intento 3" + +print(puede_fallar()) # Debe funcionar al tercer intento + + +# ------ Tarea 4 ------ +# Crea un decorador de fábrica 'repetir(n)' que ejecute la +# función n veces. +def repetir(n): + def decorador(func): + @functools.wraps(func) + def envoltura(*args, **kwargs): + # Tu código aquí: + pass + return envoltura + return decorador + +@repetir(3) +def saludar(nombre): + print(f"¡Hola, {nombre}!") + +saludar("Brandon") +# Esperado: imprime el saludo 3 veces + + +# ============================================================= +# Ejemplos de solución +# ============================================================= +# --- Tarea 1 --- +# def cronometrar(func): +# @functools.wraps(func) +# def envoltura(*args, **kwargs): +# inicio = time.time() +# resultado = func(*args, **kwargs) +# fin = time.time() +# print(f"{func.__name__} tardó {fin - inicio:.4f}s") +# return resultado +# return envoltura + +# --- Tarea 2 --- +# def registrar(func): +# @functools.wraps(func) +# def envoltura(*args, **kwargs): +# print(f"Llamando a: {func.__name__} con args={args}, kwargs={kwargs}") +# return func(*args, **kwargs) +# return envoltura + +# --- Tarea 3 --- +# def reintentar(func): +# @functools.wraps(func) +# def envoltura(*args, **kwargs): +# for intento in range(3): +# try: +# return func(*args, **kwargs) +# except Exception as e: +# print(f"Intento {intento + 1} fallido: {e}") +# raise +# return envoltura + +# --- Tarea 4 --- +# def repetir(n): +# def decorador(func): +# @functools.wraps(func) +# def envoltura(*args, **kwargs): +# for _ in range(n): +# func(*args, **kwargs) +# return envoltura +# return decorador diff --git a/avanzado/03_generadores.py b/avanzado/03_generadores.py new file mode 100644 index 0000000..596bbfa --- /dev/null +++ b/avanzado/03_generadores.py @@ -0,0 +1,114 @@ +# ============================================================= +# Ejercicio: Generadores e iteradores +# Nivel: Avanzado +# ============================================================= +# Descripción: +# Los generadores producen valores de forma perezosa (lazy), +# ahorrando memoria. Se crean con la palabra clave 'yield'. +# ============================================================= + +# ------ Tarea 1 ------ +# Crea un generador 'contar_hasta' que produzca números del 1 +# hasta n (incluido). +def contar_hasta(n): + # Tu código aquí (usa yield): + pass + +for num in contar_hasta(5): + print(num, end=" ") +# Esperado: 1 2 3 4 5 +print() + + +# ------ Tarea 2 ------ +# Crea un generador 'fibonacci' que produzca la secuencia de +# Fibonacci indefinidamente (sin límite). Usa islice para +# obtener los primeros 10 términos. +from itertools import islice + +def fibonacci(): + # Tu código aquí: + pass + +print(list(islice(fibonacci(), 10))) +# Esperado: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34] + + +# ------ Tarea 3 ------ +# Crea un generador 'lineas_archivo' que lea un archivo línea +# a línea sin cargarlo todo en memoria (modo lazy). +# Para la prueba, escribe primero el archivo y luego léelo. +import os + +def lineas_archivo(ruta): + # Tu código aquí: + pass + +# Crear archivo de prueba +with open("/tmp/prueba.txt", "w") as f: + f.writelines(f"Línea {i}\n" for i in range(1, 6)) + +for linea in lineas_archivo("/tmp/prueba.txt"): + print(linea, end="") +# Esperado: Línea 1 a Línea 5 + + +# ------ Tarea 4 ------ +# Convierte el siguiente generador en una expresión generadora +# (generator expression) equivalente y compara el uso de memoria. + +def cuadrados_gen(n): + for x in range(1, n + 1): + yield x ** 2 + +# Escribe la expresión generadora equivalente: +# cuadrados_expr = (... for ... in ...) +cuadrados_expr = None # Reemplaza None con tu expresión generadora + +print(list(cuadrados_gen(5))) # [1, 4, 9, 16, 25] +# print(list(cuadrados_expr)) # Debe dar el mismo resultado + + +# ------ Tarea 5 ------ +# Encadena dos generadores con 'yield from': crea un generador +# que produzca primero los números del 1 al 5 y luego del 6 al 10. +def rango_completo(): + # Tu código aquí (usa yield from): + pass + +print(list(rango_completo())) +# Esperado: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + +# Limpieza +if os.path.exists("/tmp/prueba.txt"): + os.remove("/tmp/prueba.txt") + + +# ============================================================= +# Ejemplos de solución +# ============================================================= +# --- Tarea 1 --- +# def contar_hasta(n): +# for i in range(1, n + 1): +# yield i + +# --- Tarea 2 --- +# def fibonacci(): +# a, b = 0, 1 +# while True: +# yield a +# a, b = b, a + b + +# --- Tarea 3 --- +# def lineas_archivo(ruta): +# with open(ruta, "r", encoding="utf-8") as f: +# for linea in f: +# yield linea + +# --- Tarea 4 --- +# cuadrados_expr = (x ** 2 for x in range(1, 6)) + +# --- Tarea 5 --- +# def rango_completo(): +# yield from range(1, 6) +# yield from range(6, 11) diff --git a/avanzado/__pycache__/01_poo_clases.cpython-312.pyc b/avanzado/__pycache__/01_poo_clases.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0beb2813275526fc9f18b730a0efe8ebce22a2c8 GIT binary patch literal 3982 zcmb^zU1(cX_}tu|+@wjGHd))Pon}nY=1z<@SZENVtx zw@j;lY{FJGEmz2uG_8`T3+(rh?I;K%XOjG*Mrtr2hIbiU;Am2YAu&?`EC>vf)I#zU z!zutuF;lO!H^@Om0=8Tk_tglC!g8xJ80yz3Av9*P+^AV%#Y(b4jF0UCdIoifY)?#3 z)2tE$n{_q_adA7FL}b!IG;u*6H8sr+Yuad$mh(7|XxeyL&pSJ;4Nt`ppgGtM1ZYLB zC$}C$J97|&iG??rCJzDuIr=~q04M-z2%IBGT}5Y9`3xo`lMdM8;PD|lrk@A(b)y89 z8Yxl(H@)GOUQ*i!n0lz1A_l8hHnS3}A#DA%JRznfTRD-tPzJtRjF49E@%vZW947r3 z8n1&6EP`M=QNc}GiMxFLSlHjhJd;)!kB)9c_aNAfpzf0vcf5$Z2wsD~^(ugAa$ioY z2ha~9QIcyoTT@_G$MKotAUxV+dCzLK7htDu`OQUQLQ2baa45$NtPP&S;1D0^Zof9v z(=i?3>1fMLr@5kqr&3N@^4P1yU4DM*zX=r2!S-msO2lK1PCbH*x1EEIQ#(AyzE|IF z;+|R9tJcO*Dlamv5 z*1nrhH1W?c%)i!x$*Tu~W4M_{fMtXss@w@+Xz4c3q0}3xr72MQXsROi9~>@Yf!&w- z*knt$c`rGds-j7&*m28A0HDy)x4bpik5;kURWYxc!oo|>+5y;U$Z7@hTF8o~)LcjT zGeF_bfFL{rf_7}EY!*uTacJv0gv_(1d(_hNw1_R<$m#jbY2V$<-Vcq>LEG(zhAngP zm1K()j-|~aJVODNk0+$Tf?LN_LobwaRHu!1vP0AyD_Xgd&MG}EGX0$qVBZj$Ta?Q% zS(;=8nOVv)kkr*8$;Dr4l9NdbtQRn8wYAN(0oGQ>SP_D|G{N4*V}l5I4q@OqVT(^F z_Lc`Um{>0Zm?kxR1gxn|MM{@?5e7!xl<*aF}<0i|c4B29I0kCj3s1xy~c?9p^oC zjGYFSSVFBc0M|r85FYkLgy=d!&`0F0Js`qkm7;VUE4?at!T)TJw< zt0c)+(`qeFgvj4y?}iiaMwg zn}@F-zHwxJXs-WO?7Q(FF5kKQ{g?O7E+772Svk2%POU3Mj?L(^9kYY8<8z=>pL?`# z?)1%b*U#Pfbl#ZD-0HvE@pJEwy+7@~XDuH&wXA%&NplO85RdyY3F&9bXw3Tn-8iXK*Bw9;!3D*Qn^o*KS}&|5})mKZ#sN6 dKb2o43D~(Bn~Ke_RnmzTXvJH9kOU8*{{UA8)Y||6 literal 0 HcmV?d00001 diff --git a/avanzado/__pycache__/02_decoradores.cpython-312.pyc b/avanzado/__pycache__/02_decoradores.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dc9ddd9b92ff53b3b0c7a4f7288b2404d26b774c GIT binary patch literal 2559 zcmc&#O>7%Q6rNdo*IxfMcH%S%A#tG~93T{`3J_6HkdUIPNxijb_WXIh!8ciq`_ zOROL{BvPFdxg~%&aEu~x=L$zIhNM!pM5q#6a2-ebYtCq;;|=afyZ2$*u=o3`vBC zVT5`!yR>VfgoObwbD7BjyyD>%rm)Da)WrtYL}5*Y5iQCiObx74y>;p-eqyjD2KE?J zdONXrU~L?1ahB-WC|RcYvOt7 zZ;-sSPz+*GpM=o~gV-X=WQQ*7kR8bhYvPXOC`Rph zjiPOuy5-3Cg;udJ44e~j0C+J7ED|Rk@E`_ZCJm$W0*E>}kW&u|tA)*v_T;g)B+1E6 zh$zprPy=^~Y%@G0l7KvM5B>#DgXOFXX0&&~kT5A9TDbG|SNQz!t|MP7S+<#n!0l3* zJF=y7UJ+QnuFr1t=gbNhTCrpr1)UqVCPu+N0>c^rQ73JfgBS(b*#UIz}&ori~4sBU;g8l*epyz zKllblYmgW%I3q1VW<=b^HSWVgz5e)uE{F5-!XZ|#xB#M-dS3`r1W_k{DMTLLPX7`fYlgE2k&*4!e~pYEq(+*f`MuOsGdlGs{`@~X4dV`!9P(+O zN72}O5QIGR^a=XRLU~p23b#uE=JlESl*0KCg0_4zPNx5}RsD@>WB=~t1KiQ0Vm0&S z{9qIZ*g2di61oH2R?u~e!#3is?N9#Edb#f%h z@@Oj&B=lfHkht8;JqJpV&>3AJ-w-B!>lZ1IH~|u`MgjTbck`yMy^=eo7xL7RD+0<9 z6a{`~x8O&I9&%k0k62KM3<~WE%zX^Q!u%t7tBv{1o1637bIsVq!|h+&9`#ACm45?r%48+)4ld literal 0 HcmV?d00001 diff --git a/avanzado/__pycache__/03_generadores.cpython-312.pyc b/avanzado/__pycache__/03_generadores.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..33e1950721f24ec15f9667f0d10163df102251c8 GIT binary patch literal 1853 zcmaJ?&1)M+6o0c{TFKH{QRBq%2T>xsRG8Y4L#;zy7vhv+Vhl-75e;UeS;sPxR?M#a zg;V5WaDsbKXsHFIkgIV6`4>u#y*QN{+@*(>Uh11aC}~BZeY4V9vI`kAvv1z~=Dpwh z82N`#C;&JnKHbUu+XnDE-*`i92*>{rfK8yV1}PB007|w|!^cgy7X(NV)CvZn!gu1f zP(LB?g(h*duw7RG0V+{BE9Rt>gtCIxWPXlQ!71UCJuLNkc05ns*R`T%eJLOHqXiXj z`DuW*dHDAr6)*yG7aLAnJ~X(-`2=Z*Y99I~cph8qs}%n{1mSm78t~2=5rt-dO~&jkwC$UF z`%M@EOX`vug9KP)K_GA!tA!Q(Y*D-m3nU&%H|l+2LqzFV!etYdV2ey`L7X@wZ*g3- z)}_zu`DLA&L)WfPKQQtJLzx-YU}4D#rp>&qv*}sg!jBK}A#O{?r3Al9>M;ti&$l%a zMWdpTr~6!ovXZf~nY5AS+tzW44dXk;xz!gxmlRwa|4in-nb*_l3=8AFmmlyZXB@K6 zAHvj|18tf{G7>A=dOhH}c`cjC8@e^Ev-E6c-el*|-~cy&;$yje$j%jp3an_{*9YxI z+aU|5JaX1CoX79ratlka2`g|9nLQ*FR>(K_^u86pCYuC{6O>>{cqU?b#3E1Qw$jz?rqYcD4r&ujz_Mcg+c?7d9Vcv}O``VO{@@RM72NM==)Bpyepc$eHuT8Rj*0 zG-uLc))-^MXp|Stx`69}NC-LV5{Um$gWBa+ft^5i<&&y>R{^#U*VtZgWJhCf|yha~M^r7|a^t@XQ4RR8fN*{3&{pCBaq)txa(osYp z9S1>(TqtS3fsEcisGO^|byt<1UFbd1T4;@(s1H<-l=b9la(!%dY$p=i75nz2Q0d0{ p#OlP3cKIhMdLV+-|N3LhMAD^Mv+zG1eBTir9~NH>%j56+{sSOeZ@B;f literal 0 HcmV?d00001 diff --git a/basico/01_variables_y_tipos.py b/basico/01_variables_y_tipos.py new file mode 100644 index 0000000..1e45130 --- /dev/null +++ b/basico/01_variables_y_tipos.py @@ -0,0 +1,54 @@ +# ============================================================= +# Ejercicio: Variables y tipos de datos +# Nivel: Básico +# ============================================================= +# Descripción: +# Practica la declaración de variables con los tipos de datos +# más comunes en Python: int, float, str y bool. +# Cada bloque propone una tarea concreta; reemplaza los "..." +# por tu código. +# ============================================================= + +# ------ Tarea 1 ------ +# Declara una variable entera con tu edad y muéstrala en pantalla. +edad = ... +print("Mi edad es:", edad) + +# ------ Tarea 2 ------ +# Declara una variable de punto flotante con tu estatura (en metros). +estatura = ... +print("Mi estatura es:", estatura, "m") + +# ------ Tarea 3 ------ +# Declara una variable de texto con tu nombre completo. +nombre = ... +print("Mi nombre es:", nombre) + +# ------ Tarea 4 ------ +# Declara una variable booleana que indique si te gusta Python. +gusta_python = ... +print("¿Me gusta Python?", gusta_python) + +# ------ Tarea 5 ------ +# Usa la función type() para mostrar el tipo de cada variable. +print(type(edad), type(estatura), type(nombre), type(gusta_python)) + +# ------ Tarea 6 ------ +# Convierte la variable 'edad' a float y 'estatura' a int. +# Muestra los resultados. +edad_float = ... +estatura_int = ... +print("Edad como float:", edad_float) +print("Estatura como int:", estatura_int) + + +# ============================================================= +# Ejemplo de solución (descomenta para ver el resultado) +# ============================================================= +# edad = 25 +# estatura = 1.75 +# nombre = "Ana García" +# gusta_python = True +# print(type(edad), type(estatura), type(nombre), type(gusta_python)) +# edad_float = float(edad) +# estatura_int = int(estatura) diff --git a/basico/02_condicionales.py b/basico/02_condicionales.py new file mode 100644 index 0000000..eb1e7b5 --- /dev/null +++ b/basico/02_condicionales.py @@ -0,0 +1,76 @@ +# ============================================================= +# Ejercicio: Condicionales +# Nivel: Básico +# ============================================================= +# Descripción: +# Practica el uso de if / elif / else para tomar decisiones +# en tu programa. +# ============================================================= + +# ------ Tarea 1 ------ +# Escribe un programa que lea un número e indique si es +# positivo, negativo o cero. +numero = int(input("Ingresa un número: ")) + +# Tu código aquí: + + +# ------ Tarea 2 ------ +# Escribe un programa que determine si un número es par o impar. +numero2 = int(input("Ingresa otro número: ")) + +# Tu código aquí (pista: usa el operador %): + + +# ------ Tarea 3 ------ +# Escribe un programa que clasifique una nota (0-100) en: +# - Sobresaliente: 90-100 +# - Notable: 70-89 +# - Aprobado: 50-69 +# - Reprobado: 0-49 +nota = float(input("Ingresa tu nota (0-100): ")) + +# Tu código aquí: + + +# ------ Tarea 4 ------ +# Escribe un programa que determine si un año es bisiesto. +# Un año es bisiesto si es divisible entre 4, excepto los +# siglos, que deben ser divisibles entre 400. +anio = int(input("Ingresa un año: ")) + +# Tu código aquí: + + +# ============================================================= +# Ejemplos de solución +# ============================================================= +# --- Tarea 1 --- +# if numero > 0: +# print("Positivo") +# elif numero < 0: +# print("Negativo") +# else: +# print("Cero") + +# --- Tarea 2 --- +# if numero2 % 2 == 0: +# print("Par") +# else: +# print("Impar") + +# --- Tarea 3 --- +# if nota >= 90: +# print("Sobresaliente") +# elif nota >= 70: +# print("Notable") +# elif nota >= 50: +# print("Aprobado") +# else: +# print("Reprobado") + +# --- Tarea 4 --- +# if (anio % 4 == 0 and anio % 100 != 0) or (anio % 400 == 0): +# print(f"{anio} es bisiesto") +# else: +# print(f"{anio} no es bisiesto") diff --git a/basico/03_bucles.py b/basico/03_bucles.py new file mode 100644 index 0000000..a868c07 --- /dev/null +++ b/basico/03_bucles.py @@ -0,0 +1,82 @@ +# ============================================================= +# Ejercicio: Bucles +# Nivel: Básico +# ============================================================= +# Descripción: +# Practica los bucles for y while para repetir instrucciones. +# ============================================================= + +# ------ Tarea 1 ------ +# Imprime los números del 1 al 20 usando un bucle for. + +# Tu código aquí: + + +# ------ Tarea 2 ------ +# Imprime la tabla de multiplicar de un número dado por el usuario. +n = int(input("¿De qué número quieres la tabla de multiplicar? ")) + +# Tu código aquí: + + +# ------ Tarea 3 ------ +# Suma todos los números del 1 al 100 usando un bucle while. +# Al final muestra el resultado. + +# Tu código aquí: + + +# ------ Tarea 4 ------ +# Pide al usuario que adivine un número secreto (por ejemplo 42). +# El programa debe seguir pidiendo números hasta que el usuario +# acierte, indicando en cada intento si el número es mayor o menor. + +secreto = 42 +# Tu código aquí: + + +# ------ Tarea 5 ------ +# Imprime el triángulo de asteriscos de altura 5: +# * +# ** +# *** +# **** +# ***** + +# Tu código aquí: + + +# ============================================================= +# Ejemplos de solución +# ============================================================= +# --- Tarea 1 --- +# for i in range(1, 21): +# print(i) + +# --- Tarea 2 --- +# for i in range(1, 11): +# print(f"{n} x {i} = {n * i}") + +# --- Tarea 3 --- +# total = 0 +# i = 1 +# while i <= 100: +# total += i +# i += 1 +# print("Suma:", total) # Esperado: 5050 + +# --- Tarea 4 --- +# intento = 0 +# while True: +# intento = int(input("Adivina el número: ")) +# if intento < secreto: +# print("Más alto") +# elif intento > secreto: +# print("Más bajo") +# else: +# print("¡Correcto!") +# break + +# --- Tarea 5 --- +# for i in range(1, 6): +# print("*" * i) diff --git a/basico/04_funciones.py b/basico/04_funciones.py new file mode 100644 index 0000000..f75cb66 --- /dev/null +++ b/basico/04_funciones.py @@ -0,0 +1,94 @@ +# ============================================================= +# Ejercicio: Funciones +# Nivel: Básico +# ============================================================= +# Descripción: +# Practica la definición y el uso de funciones para modularizar +# tu código y reutilizar lógica. +# ============================================================= + +# ------ Tarea 1 ------ +# Define una función que reciba dos números y retorne su suma. +def suma(a, b): + # Tu código aquí: + pass + +print(suma(3, 5)) # Esperado: 8 +print(suma(10, -4)) # Esperado: 6 + + +# ------ Tarea 2 ------ +# Define una función que reciba un número y retorne +# True si es primo, False en caso contrario. +def es_primo(n): + # Tu código aquí: + pass + +print(es_primo(7)) # True +print(es_primo(10)) # False +print(es_primo(2)) # True + + +# ------ Tarea 3 ------ +# Define una función que calcule el factorial de n de forma iterativa. +def factorial(n): + # Tu código aquí: + pass + +print(factorial(5)) # 120 +print(factorial(0)) # 1 +print(factorial(10)) # 3628800 + + +# ------ Tarea 4 ------ +# Define una función con parámetro por defecto que salude a una +# persona. Si no se pasa nombre, debe saludar con "Mundo". +def saludar(nombre="Mundo"): + # Tu código aquí: + pass + +saludar() # "¡Hola, Mundo!" +saludar("Brandon") # "¡Hola, Brandon!" + + +# ------ Tarea 5 ------ +# Define una función que reciba un número variable de argumentos +# y retorne su promedio. +def promedio(*numeros): + # Tu código aquí: + pass + +print(promedio(10, 20, 30)) # 20.0 +print(promedio(5, 5, 5, 5, 5)) # 5.0 + + +# ============================================================= +# Ejemplos de solución +# ============================================================= +# --- Tarea 1 --- +# def suma(a, b): +# return a + b + +# --- Tarea 2 --- +# def es_primo(n): +# if n < 2: +# return False +# for i in range(2, int(n**0.5) + 1): +# if n % i == 0: +# return False +# return True + +# --- Tarea 3 --- +# def factorial(n): +# resultado = 1 +# for i in range(2, n + 1): +# resultado *= i +# return resultado + +# --- Tarea 4 --- +# def saludar(nombre="Mundo"): +# print(f"¡Hola, {nombre}!") + +# --- Tarea 5 --- +# def promedio(*numeros): +# return sum(numeros) / len(numeros) diff --git a/basico/05_listas.py b/basico/05_listas.py new file mode 100644 index 0000000..80cb7df --- /dev/null +++ b/basico/05_listas.py @@ -0,0 +1,89 @@ +# ============================================================= +# Ejercicio: Listas +# Nivel: Básico +# ============================================================= +# Descripción: +# Practica la creación, acceso y manipulación de listas. +# ============================================================= + +# ------ Tarea 1 ------ +# Crea una lista con los nombres de 5 frutas y muéstrala. +frutas = [...] +print(frutas) + +# Accede e imprime la primera y la última fruta. +primera = ... +ultima = ... +print(primera, ultima) + + +# ------ Tarea 2 ------ +# Dado el siguiente listado de números, agrega el número 99 al +# final, inserta el número 0 al inicio y elimina el número 5. +numeros = [1, 2, 3, 4, 5, 6, 7, 8] + +# Tu código aquí: + +print(numeros) # [0, 1, 2, 3, 4, 6, 7, 8, 99] + + +# ------ Tarea 3 ------ +# Sin usar la función sorted(), ordena la siguiente lista de menor +# a mayor usando el método .sort() y luego inviértela. +desordenada = [34, 7, 23, 32, 5, 62] + +# Tu código aquí: + +print(desordenada) # Ordenada ascendente +# luego invertida + + +# ------ Tarea 4 ------ +# Dada la lista, calcula y muestra: máximo, mínimo y promedio. +valores = [10, 45, 3, 78, 22, 56, 14] + +maximo = ... +minimo = ... +promedio = ... +print(f"Máx: {maximo}, Mín: {minimo}, Promedio: {promedio:.2f}") + + +# ------ Tarea 5 ------ +# Crea una nueva lista que contenga solo los números pares +# de la siguiente lista, usando un bucle for. +todos = list(range(1, 21)) +pares = [] + +# Tu código aquí: + +print(pares) # [2, 4, 6, 8, 10, 12, 14, 16, 18, 20] + + +# ============================================================= +# Ejemplos de solución +# ============================================================= +# --- Tarea 1 --- +# frutas = ["manzana", "banana", "cereza", "durazno", "uva"] +# primera = frutas[0] +# ultima = frutas[-1] + +# --- Tarea 2 --- +# numeros.append(99) +# numeros.insert(0, 0) +# numeros.remove(5) + +# --- Tarea 3 --- +# desordenada.sort() +# print(desordenada) +# desordenada.reverse() +# print(desordenada) + +# --- Tarea 4 --- +# maximo = max(valores) +# minimo = min(valores) +# promedio = sum(valores) / len(valores) + +# --- Tarea 5 --- +# for n in todos: +# if n % 2 == 0: +# pares.append(n) diff --git a/basico/__pycache__/01_variables_y_tipos.cpython-312.pyc b/basico/__pycache__/01_variables_y_tipos.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7c1d245e965da1858523248783988eb07168cf8f GIT binary patch literal 654 zcmY+Av2W8r7{$M{FV59?k=_3oOIT`pTGCs**|JE6T~`uJ@Jhyz+WlK zMJ^BL6LI(o9=rk#DDn`6u{L{$B-IqvsOITo{TkO5$5fx2#)?)bzM_(dT@krx=2uFa zQ~I33r5fXFjfS{QRplGhn9ujBw0cES(p+d|i@Ux}J=e2o+|KG!#EF~qBUb{Bf~+Q3 zj|H8GO44tLstIF}!OvDR^8e~&%bc<2n=$agzk z8at_z_#um1VR}Ix2h8ht=~lEP#^vvghvG5S5kk}3Ko)cS2P%0md|ANilz>&wi2xJh z)@bE$vw*vTnYG-ILu@!GU`>GKo4KWiR!2JpH2)Dm#z*h-qfZ|W)`$CFT1V@LgKzgw l@yVN?8&3;(HZ@`CMsEJDH!giEqk9G1DIHOlM$XNCjcW6o%D|5E&R9#RQjQgo(lE zC}yA>3s@f$ObkXxvBLE+!^B{86k8>WCTpn(&?e8k^rF<_M1|5kg}lSNa#M@)trSYd zkRr-Uu|yPm}!?b7o%2E!NDu zg3^*(Y^YapOQj7HpDt~d<7esU}^XXpZ(raMBSN}4*K?BQ2AqEcaPSXp5Dwnxc NFSDyPvJ`=04*)&da#8>Q literal 0 HcmV?d00001 diff --git a/basico/__pycache__/03_bucles.cpython-312.pyc b/basico/__pycache__/03_bucles.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2d18b69c604a2316932ce80d412e03d1d87dff7f GIT binary patch literal 255 zcmX@j%ge<81XrRjWX7>GFgylvV1O0M_^bkCOlM$XNCjcW6o%D|5E&R9#gxJr#azjx z$y{m-lsUBDB~_uY^zcfByu-V4Q;YI}oXpgs)MAC4M1_*XBp{iRs*qcnQ<7PblbM`Y zWUug23#iXeljRn3W?soH*37(u(vn+@dAHb$QPO4oI$S)wb70UsM56p~=j31R4SUEabFYq~E=5V>p;@ZIY PL5YEzw~@Vw1E>T5n2(%a~j%x&NrrRl3qA2O4r~xI5fRa&RF z$7&8=pvt^Li*Ky|jp^QLuDQj%7IFZbX{OklsGAA#T?pbTyM6V*mt9+ z&z>J1C86s_p%?FTx~Uc?fx|2W)i?*2`vBiHYla)hIB&*d8UG8i-}Cw0Ep86|+?KQ% z_ZUCPh@>QpIk>@0oKwq-4?D~cBDRk1JsgbxKuj=mM8=PLQ+l?F;3~a+a(Y-(_((s9=Uk z;ISyKN?08h1s?SywvBZ!a8x?jKsV#@eXQ2sB&gRk#KWaJUTb(Ju2u9djwm?9ONbj5 zZ*XnB3?iDey;tlBGV#ZWKjHLKC4@}xE5!a~0Wm((!S2B6olIcu3Uu`L2CUbfz};!B zgd7h}d+#T(&H=|oI^XB<=}HOpheTBK^zvTm1rykqNmi?GUx7KWk#QypmYUKi$8^hy8eJriWJmyix)4eAgS+dHn>Ta{4A}f94f2` zvNsDw{JBXHdi36-AO-iZ<|KHEr>(v9?mgws8>)|OI`g> zmr-Z9O~cSJ4DxVAXuH5wp(8S3aBWw4$Ij-^Q^hd3&W-u$^KRR6p>3BZ*>g>Tt!mS3 zHT8miqM-X0GJ!&%5-&ixRU? zCHvaJ$IX>SN{f~nYX@I~mBtHesqruheZjpDncTYFiOMT2plQ8X%ULH%6DQ8qe&hv7 zu3_>;vC7$o(T96_S?AMCdd*}XB`KeE8EUp*S#8g0CO@ 4] + +# --- Tarea 3 --- +# cuadrados_dict = {n: n ** 2 for n in range(1, 6)} + +# --- Tarea 4 --- +# letras = {c for c in frase if c != ' '} + +# --- Tarea 5 --- +# plana = [num for fila in matriz for num in fila] + +# --- Tarea 6 --- +# pares = [(x, y) for x in range(4) for y in range(4) if x != y] diff --git a/intermedio/04_archivos_y_excepciones.py b/intermedio/04_archivos_y_excepciones.py new file mode 100644 index 0000000..6c0038b --- /dev/null +++ b/intermedio/04_archivos_y_excepciones.py @@ -0,0 +1,105 @@ +# ============================================================= +# Ejercicio: Manejo de archivos y excepciones +# Nivel: Intermedio +# ============================================================= +# Descripción: +# Practica la lectura/escritura de archivos con open() y +# el manejo de errores con try/except/finally. +# ============================================================= + +import os + +# ------ Tarea 1 ------ +# Escribe una función que cree un archivo llamado "notas.txt" +# con tres líneas de texto (las que tú quieras). +def crear_archivo(nombre_archivo): + # Tu código aquí (usa 'with open(...)'): + pass + +crear_archivo("notas.txt") + + +# ------ Tarea 2 ------ +# Escribe una función que lea el contenido del archivo +# y lo imprima línea a línea con su número de línea. +def leer_archivo(nombre_archivo): + # Tu código aquí: + pass + +leer_archivo("notas.txt") + + +# ------ Tarea 3 ------ +# Escribe una función que añada (sin sobreescribir) una nueva +# línea al final del archivo. +def agregar_linea(nombre_archivo, linea): + # Tu código aquí (usa modo 'a'): + pass + +agregar_linea("notas.txt", "Línea agregada al final") +leer_archivo("notas.txt") + + +# ------ Tarea 4 ------ +# Escribe una función que intente abrir un archivo y maneje +# el error FileNotFoundError mostrando un mensaje amigable. +def abrir_seguro(nombre_archivo): + # Tu código aquí: + pass + +abrir_seguro("archivo_inexistente.txt") +abrir_seguro("notas.txt") + + +# ------ Tarea 5 ------ +# Escribe una función que convierta un string a entero de forma +# segura, retornando None si la conversión falla. +def convertir_a_entero(valor): + # Tu código aquí: + pass + +print(convertir_a_entero("42")) # 42 +print(convertir_a_entero("hola")) # None +print(convertir_a_entero("3.14")) # None (no es entero directo) + + +# Limpieza del archivo de prueba +if os.path.exists("notas.txt"): + os.remove("notas.txt") + + +# ============================================================= +# Ejemplos de solución +# ============================================================= +# --- Tarea 1 --- +# def crear_archivo(nombre_archivo): +# with open(nombre_archivo, "w", encoding="utf-8") as f: +# f.write("Primera nota\n") +# f.write("Segunda nota\n") +# f.write("Tercera nota\n") + +# --- Tarea 2 --- +# def leer_archivo(nombre_archivo): +# with open(nombre_archivo, "r", encoding="utf-8") as f: +# for i, linea in enumerate(f, start=1): +# print(f"{i}: {linea}", end="") + +# --- Tarea 3 --- +# def agregar_linea(nombre_archivo, linea): +# with open(nombre_archivo, "a", encoding="utf-8") as f: +# f.write(linea + "\n") + +# --- Tarea 4 --- +# def abrir_seguro(nombre_archivo): +# try: +# with open(nombre_archivo, "r", encoding="utf-8") as f: +# print(f.read()) +# except FileNotFoundError: +# print(f"Error: el archivo '{nombre_archivo}' no existe.") + +# --- Tarea 5 --- +# def convertir_a_entero(valor): +# try: +# return int(valor) +# except (ValueError, TypeError): +# return None diff --git a/intermedio/__pycache__/01_diccionarios_y_conjuntos.cpython-312.pyc b/intermedio/__pycache__/01_diccionarios_y_conjuntos.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0f3051e3ef1ea895d9b8bd1a0a63875ebb080c6c GIT binary patch literal 683 zcmYjNy>HV%6o3A@v)!a=k@$)ViYf-Y6lhn}KY)ROF$|XDJ5oo9&pO+PWU>$gBMYKK zhl&Z5e}Mmig-At$n<_DROR2=riFYAsIqCi0?|r{}Uz<%I@cnuIEqU(&{L;qiIZJYW zgyaJx&;=8?!C`9rix^9r!EJPKV20LHa}{MKvzW~sMvm;Rxu`X-Y8mZX*wbG4?JIvD znETP_I;cI=g!x^H;-YwqT*_VUO|8|G@mkPOBo(8cBGQCj_L{7pV0|YrRKp zYtZ+q2|_@m9w#?6Y-%sn;A+4l!_L#dS3b{+k|j}EaOGq&Nee|Y$>Rjqati*c5Xygn zcFEH?i4+|sc@c$|q^D>sMrF!#<>g{1LY`vqlJ-8sIZlF$02_0;ILU*Dk3yEjI3bNB zjtR$MEYd-l79!ut#ux76kznPJ@5^nh)IZE$Bg`$sFy?J@-K_jG0tTrDC$PC>?{3XV z`|!!}WVW??0(2%(KA=)_us6~+u-e0&S|stf0N%Euy&`S%HOK! cso$*Vk4CHV7Vs0Cs{eL;7<`9&vV&{<1pubE2><{9 literal 0 HcmV?d00001 diff --git a/intermedio/__pycache__/02_funciones_orden_superior.cpython-312.pyc b/intermedio/__pycache__/02_funciones_orden_superior.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bef0bb3e5beff5e8991c3f97c3f68b6672a17ad0 GIT binary patch literal 1147 zcmZvay>HV%6u{rbv12FBM=4+8LnbWGtV`V+sPgCJ4n;0>u52AKGYcu=)#G# znbGDyG~*hcl;2{**mWzTtPzEF9WyE7en}L$_QCkW+8Jw)SYGHty^OnMZg!~#>#xX_ zjINAm)CaZU3UfwTth<&)s*NIbY^U6(mN-lqQt-AXoMNBwKJ~1xk;s$K zNf;ywBuo-`EzqZ1nsIbVlq54**JV6qGE!O5xo<95?idf>+`HztpXi6h5vwuEd5?uWN-&n^++ zhfNVLg_4WrQrwP&^g}rlbyUHP0^f6`Jcq8cIAh8yf$w?q5EtML+D2=9Apltt^!7I3 z1wOgwh%aIu3&&-TqXE-r&tmeMkY`aInGXWDvCQ3hc@fonIAdy90=+9eck@~T@;s_e z{>1iCz5O#N7Mw9<8En zRqz{;D@Cl#NQQXLtq_T9!-zxK5?onXgUC1Qhthet90;XLx49yeg}&{eg=R^0W?2s_ zY+%4Z%*&f-pwi=yD1K^;v0tZwT|Ov6=|)o6vuo?)Ym2?l*25QUGDNK3BdrFFXmLD0<^k^o(c{Dkfi0tAf7*a9R{pya_p1`P?&vB=Wh zTic(KB}0dVYbS3;vSsR#ZefSR)A4(c#}n_etPi-d)BEBk0r=xK|5x;{c>amScMvck zIRqeygkNOs5tx7=3z7%k4ZRy~Tme&(N1jGoG{~uUn0MI5!EWJ#phjLPYMA$Y@7QPK zP1e)I(_};EY}7j#F&j;F$t|sBN@&aKc{|n02C}hiB2~dl8&387^21nHwUMeRw35x9 zRD0{>C|tTfTn0`;6a?-$medJbgPyBnC-`#kWz@HHJUiEorL`$kYvY=i{M>N7v*c!i z-@$msh2cUsXQCLlmR_JM(Uz@`RlGIDC7v(2!r^OfWb*@_u{*r%VoPZ%DGGgf^y%!? z;0N{mCH`D#F)QV<*~Pe>)|F+Tww&Yi?4rg9H2pSiYX2 literal 0 HcmV?d00001 diff --git a/intermedio/__pycache__/04_archivos_y_excepciones.cpython-312.pyc b/intermedio/__pycache__/04_archivos_y_excepciones.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e69172ed27678907546c0e668e3c33d4a2973221 GIT binary patch literal 1243 zcmbVK&1(}u6o0c{P10=CTD7g%Mg&U`;#ai@r3Y^X=^s#qu-zS#Z8y8&?It8SwIH-d zZ}nd&Meu*{=%vyX?4ATq-ePkQdh*RCn-2;F9hjN-e((3@_h#OF(e(__n0s?<|Ct2% zDV$`eeWSa=01m(ci#f0Xmh=ubm;{_z@)1SEU|=bPN`y*ds7k0zsBFoWb|fY23%m*9 zDTFFkYItVsk7}fer4p*qRIN!>~kjd&Qv>ZSS4%zx4Em6+(s+-752AUPS;rSvdf4*qD z0mmx0Z13Ttr9rUND)FYtYo_hF+%MKzk!~V4Fd<-?vabjk(ajzBp`^NGKs)Vvf#DZ} zW^j2`D9S^Tj2bPyYA{7+lyx{C3h4yR3Yz#(NPh{;e!I!+jj`(v4=zYJL4-(kY?m9p z$jaw?61q`FUZ(5BA-qbVdo+g{^%-(sef~&^`5xCI!^yw3UBmhRn;DyEW69^`I(jHN zTpUwv-|9D~L=`t}Kj74ye|gISi`0hUcsTl=Q>N!OI0mF_l*EaoeS>sgjA=*G(vwK3 zc#hFlo)#Z36*7_J`Ej37^dNquxaK%HQfo+GCsJxgP>Hm-T0hc|S3S~-`zm@BKlgcR zrRrIAhp*xt!owwKI)vGQOVQ)o&q8>9 z3fb|9eyraQVeta4ebr_@OrL1;AuODND!iK~T0Vrk<6b8Pinh1ByS%r$yZZh?D9?Xa X^qrS`YrAXv+uxMAjtt5|{QLd_@~ZHU literal 0 HcmV?d00001 From 518781fe2273481b13792645e0be520e46d2bf57 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 4 Apr 2026 00:35:27 +0000 Subject: [PATCH 3/3] Add .gitignore to exclude __pycache__ and build artifacts Agent-Logs-Url: https://github.com/BrandonCabra/ejercicios_python/sessions/7ceb4281-0576-4193-94c3-45c8ede397b0 Co-authored-by: BrandonCabra <173741999+BrandonCabra@users.noreply.github.com> --- .gitignore | 23 ++++++++++++++++++ .../01_ordenamiento.cpython-312.pyc | Bin 1316 -> 0 bytes .../__pycache__/02_busqueda.cpython-312.pyc | Bin 1445 -> 0 bytes .../__pycache__/03_recursion.cpython-312.pyc | Bin 1649 -> 0 bytes .../04_estructuras_datos.cpython-312.pyc | Bin 5559 -> 0 bytes .../__pycache__/01_poo_clases.cpython-312.pyc | Bin 3982 -> 0 bytes .../02_decoradores.cpython-312.pyc | Bin 2559 -> 0 bytes .../03_generadores.cpython-312.pyc | Bin 1853 -> 0 bytes .../01_variables_y_tipos.cpython-312.pyc | Bin 654 -> 0 bytes .../02_condicionales.cpython-312.pyc | Bin 453 -> 0 bytes basico/__pycache__/03_bucles.cpython-312.pyc | Bin 255 -> 0 bytes .../__pycache__/04_funciones.cpython-312.pyc | Bin 1194 -> 0 bytes basico/__pycache__/05_listas.cpython-312.pyc | Bin 750 -> 0 bytes ...1_diccionarios_y_conjuntos.cpython-312.pyc | Bin 683 -> 0 bytes ...2_funciones_orden_superior.cpython-312.pyc | Bin 1147 -> 0 bytes .../03_comprensiones.cpython-312.pyc | Bin 611 -> 0 bytes .../04_archivos_y_excepciones.cpython-312.pyc | Bin 1243 -> 0 bytes 17 files changed, 23 insertions(+) create mode 100644 .gitignore delete mode 100644 algoritmos/__pycache__/01_ordenamiento.cpython-312.pyc delete mode 100644 algoritmos/__pycache__/02_busqueda.cpython-312.pyc delete mode 100644 algoritmos/__pycache__/03_recursion.cpython-312.pyc delete mode 100644 algoritmos/__pycache__/04_estructuras_datos.cpython-312.pyc delete mode 100644 avanzado/__pycache__/01_poo_clases.cpython-312.pyc delete mode 100644 avanzado/__pycache__/02_decoradores.cpython-312.pyc delete mode 100644 avanzado/__pycache__/03_generadores.cpython-312.pyc delete mode 100644 basico/__pycache__/01_variables_y_tipos.cpython-312.pyc delete mode 100644 basico/__pycache__/02_condicionales.cpython-312.pyc delete mode 100644 basico/__pycache__/03_bucles.cpython-312.pyc delete mode 100644 basico/__pycache__/04_funciones.cpython-312.pyc delete mode 100644 basico/__pycache__/05_listas.cpython-312.pyc delete mode 100644 intermedio/__pycache__/01_diccionarios_y_conjuntos.cpython-312.pyc delete mode 100644 intermedio/__pycache__/02_funciones_orden_superior.cpython-312.pyc delete mode 100644 intermedio/__pycache__/03_comprensiones.cpython-312.pyc delete mode 100644 intermedio/__pycache__/04_archivos_y_excepciones.cpython-312.pyc diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3485325 --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# Distribution / packaging +*.egg-info/ +dist/ +build/ + +# Virtual environments +.venv/ +venv/ +env/ + +# IDE files +.idea/ +.vscode/ +*.code-workspace + +# OS files +.DS_Store +Thumbs.db diff --git a/algoritmos/__pycache__/01_ordenamiento.cpython-312.pyc b/algoritmos/__pycache__/01_ordenamiento.cpython-312.pyc deleted file mode 100644 index 9c0eb03a1d04c66cb265e8d13a6f134250d0beea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1316 zcmb_bJ8#oa6h7CEoy2)ns139iEk$+OVFMFva5^=dj}8;?gwG{)x%xEKd7>R|$ zN!+C~r%|6Eoy9o{7u|)2$h7P)5(HNNqFutMgg=BE& zd_^yNj_WJy!mvF-Dhryppgsk~^i|KWxZ(M#DBHSY`KnvC)=lm!_+8cW==;~{3wa+y45W0DDAOJ`!L-dYVDU*}%sn$_+5 PZ)-dE+VRWJ)IhW!!A%Il diff --git a/algoritmos/__pycache__/02_busqueda.cpython-312.pyc b/algoritmos/__pycache__/02_busqueda.cpython-312.pyc deleted file mode 100644 index 316dd18c37bbce92d68e3df4f253398f4003e7c3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1445 zcmaJ{xluw4*%Ko6gsJ-rqU*eD3N>1D=NuHr(6Y06$1b z4sTy}3k+Zd1iXMEOoL$WS&?ZVHT*y_p?%a^o*&VV4ugGG{iszKm`O(;L$V~MXi|(Y zrJ4Bu&Z0|G@I;&VAF%$dMz^qEup)0W;s4D+*1zRQAx{fCPQPb}9Wizy>P5Sq*OIpA z`X@KCW{z6tt$cQ>J+s!t5Ow@^4TKe#hjmt1hrAY=W!JAdq3umRl2v!k^C>Eq+dJWu zr#Ue3g=Firoa7G``huw)#D!Ucwl$DJk8A@&<1n}Lkcku%GR78r1>PF-f z(d$Ji0;&>O1VkvJMNqgM5Ye(6U{3a!`3PQcM_9GJ0|1MVyp_-vFmOp<(y%kV5TPq5 zqO{IJy(}y1h9WA8>VzqGVYcQbSsW>9d#PjC-L+9 z5dzpcG5GGzn)&wLhn_cui>{$`@h3@+_&zz@(tT@8Cp?XkTn4E=iF5_hd z7PUYVY)McU%ID-`mn zcp*cpQk#*=^F#Boax2yN2}ACCswxHUd;5Xn(I`r#&Jj>YF|D|PJ$qut6ScCusm9Pi zo9BN**wz_iJEt_3+OeVILSTIb^SM`_UY%|5b4?gZMAhI!O&H$E=q&X!4V}I9i!W~l zHkvp1@zsHr=O*v3KV9o-@Zlzmps6MIHuy*r&hOeBL$kp6CeN)6e7M%&SDG*yyOBKJ o;G<0#+sP7_G?;y%LBDOwNNWMdniSYypWDZ*B@?wTFdX;#3nQy0TmS$7 diff --git a/algoritmos/__pycache__/03_recursion.cpython-312.pyc b/algoritmos/__pycache__/03_recursion.cpython-312.pyc deleted file mode 100644 index 74c3ef56c9d025d29f28c935e12918ef46f37b41..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1649 zcmbVM&2JM&6o0e3UavpmB;=z3Q53iYBk>v96RMQb11AoM9%@lV%g*8q+K(`^7I8}? zM^2?kMXGyBt6q9V@K12&(!#cd6$emHz6D#Y)SUWe?O8h@dgw?qZ|1$<{NBgB-6sf2D$5UJzTsG%%M z63H^Kfzl~CX3Hs^lE`c#voXA#qZ#5e_zoPcj`K^*XjAeV_cHG9wfkiQZJU_}nSka! z)6duPsmDAek1XYf7PjHxAQ`AxLvI!>D!Y=%a)_3;Nv(jG0xgf}Cos<9@Me)#Fw$Yo zMwrZ6#tOaPYEXFBN+*%OG-N2zDaEQ}R>cyXRyrleY*{@jP$oBki$6Q9hC77GI47_vMyy%AA3O6GFacm0shqLWiNxlAN=*}Z@} zM+QAU4%Bj#Qq|zHE{Tc7s=Gmwr>=-t5GI!0*kB&BxsXhYI0h-_*6bi;{0J&P!pW!P zA~Wqu56;`)?fcwn3E4Pi-vEnQdVbCDEJ8^x{g!euL>XWrB&Kl`POW$sMqX%je0hTy;{{1 zvXYR?3Hh{IPIS=}$+U2ztO-5lvncJoB)8645Ty;0t#G=y3R{qggkFZ}ey@8;4EWUJYk{^s6Ob18*YpmXh+xe&wQep%^S_O{hKrcPUHJ9j!K+F=ay zG7Nb--VS1zJ9z4qv#7n!@-y>;7#1YL>s%c04-V(s;cqbiPp?5Be^SWr^6|{%<&Uj@ E0aE2Ob^rhX diff --git a/algoritmos/__pycache__/04_estructuras_datos.cpython-312.pyc b/algoritmos/__pycache__/04_estructuras_datos.cpython-312.pyc deleted file mode 100644 index 85945a232024bb26d57247af11a6494386cc3355..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5559 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 diff --git a/avanzado/__pycache__/02_decoradores.cpython-312.pyc b/avanzado/__pycache__/02_decoradores.cpython-312.pyc deleted file mode 100644 index dc9ddd9b92ff53b3b0c7a4f7288b2404d26b774c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2559 zcmc&#O>7%Q6rNdo*IxfMcH%S%A#tG~93T{`3J_6HkdUIPNxijb_WXIh!8ciq`_ zOROL{BvPFdxg~%&aEu~x=L$zIhNM!pM5q#6a2-ebYtCq;;|=afyZ2$*u=o3`vBC zVT5`!yR>VfgoObwbD7BjyyD>%rm)Da)WrtYL}5*Y5iQCiObx74y>;p-eqyjD2KE?J zdONXrU~L?1ahB-WC|RcYvOt7 zZ;-sSPz+*GpM=o~gV-X=WQQ*7kR8bhYvPXOC`Rph zjiPOuy5-3Cg;udJ44e~j0C+J7ED|Rk@E`_ZCJm$W0*E>}kW&u|tA)*v_T;g)B+1E6 zh$zprPy=^~Y%@G0l7KvM5B>#DgXOFXX0&&~kT5A9TDbG|SNQz!t|MP7S+<#n!0l3* zJF=y7UJ+QnuFr1t=gbNhTCrpr1)UqVCPu+N0>c^rQ73JfgBS(b*#UIz}&ori~4sBU;g8l*epyz zKllblYmgW%I3q1VW<=b^HSWVgz5e)uE{F5-!XZ|#xB#M-dS3`r1W_k{DMTLLPX7`fYlgE2k&*4!e~pYEq(+*f`MuOsGdlGs{`@~X4dV`!9P(+O zN72}O5QIGR^a=XRLU~p23b#uE=JlESl*0KCg0_4zPNx5}RsD@>WB=~t1KiQ0Vm0&S z{9qIZ*g2di61oH2R?u~e!#3is?N9#Edb#f%h z@@Oj&B=lfHkht8;JqJpV&>3AJ-w-B!>lZ1IH~|u`MgjTbck`yMy^=eo7xL7RD+0<9 z6a{`~x8O&I9&%k0k62KM3<~WE%zX^Q!u%t7tBv{1o1637bIsVq!|h+&9`#ACm45?r%48+)4ld diff --git a/avanzado/__pycache__/03_generadores.cpython-312.pyc b/avanzado/__pycache__/03_generadores.cpython-312.pyc deleted file mode 100644 index 33e1950721f24ec15f9667f0d10163df102251c8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1853 zcmaJ?&1)M+6o0c{TFKH{QRBq%2T>xsRG8Y4L#;zy7vhv+Vhl-75e;UeS;sPxR?M#a zg;V5WaDsbKXsHFIkgIV6`4>u#y*QN{+@*(>Uh11aC}~BZeY4V9vI`kAvv1z~=Dpwh z82N`#C;&JnKHbUu+XnDE-*`i92*>{rfK8yV1}PB007|w|!^cgy7X(NV)CvZn!gu1f zP(LB?g(h*duw7RG0V+{BE9Rt>gtCIxWPXlQ!71UCJuLNkc05ns*R`T%eJLOHqXiXj z`DuW*dHDAr6)*yG7aLAnJ~X(-`2=Z*Y99I~cph8qs}%n{1mSm78t~2=5rt-dO~&jkwC$UF z`%M@EOX`vug9KP)K_GA!tA!Q(Y*D-m3nU&%H|l+2LqzFV!etYdV2ey`L7X@wZ*g3- z)}_zu`DLA&L)WfPKQQtJLzx-YU}4D#rp>&qv*}sg!jBK}A#O{?r3Al9>M;ti&$l%a zMWdpTr~6!ovXZf~nY5AS+tzW44dXk;xz!gxmlRwa|4in-nb*_l3=8AFmmlyZXB@K6 zAHvj|18tf{G7>A=dOhH}c`cjC8@e^Ev-E6c-el*|-~cy&;$yje$j%jp3an_{*9YxI z+aU|5JaX1CoX79ratlka2`g|9nLQ*FR>(K_^u86pCYuC{6O>>{cqU?b#3E1Qw$jz?rqYcD4r&ujz_Mcg+c?7d9Vcv}O``VO{@@RM72NM==)Bpyepc$eHuT8Rj*0 zG-uLc))-^MXp|Stx`69}NC-LV5{Um$gWBa+ft^5i<&&y>R{^#U*VtZgWJhCf|yha~M^r7|a^t@XQ4RR8fN*{3&{pCBaq)txa(osYp z9S1>(TqtS3fsEcisGO^|byt<1UFbd1T4;@(s1H<-l=b9la(!%dY$p=i75nz2Q0d0{ p#OlP3cKIhMdLV+-|N3LhMAD^Mv+zG1eBTir9~NH>%j56+{sSOeZ@B;f diff --git a/basico/__pycache__/01_variables_y_tipos.cpython-312.pyc b/basico/__pycache__/01_variables_y_tipos.cpython-312.pyc deleted file mode 100644 index 7c1d245e965da1858523248783988eb07168cf8f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 654 zcmY+Av2W8r7{$M{FV59?k=_3oOIT`pTGCs**|JE6T~`uJ@Jhyz+WlK zMJ^BL6LI(o9=rk#DDn`6u{L{$B-IqvsOITo{TkO5$5fx2#)?)bzM_(dT@krx=2uFa zQ~I33r5fXFjfS{QRplGhn9ujBw0cES(p+d|i@Ux}J=e2o+|KG!#EF~qBUb{Bf~+Q3 zj|H8GO44tLstIF}!OvDR^8e~&%bc<2n=$agzk z8at_z_#um1VR}Ix2h8ht=~lEP#^vvghvG5S5kk}3Ko)cS2P%0md|ANilz>&wi2xJh z)@bE$vw*vTnYG-ILu@!GU`>GKo4KWiR!2JpH2)Dm#z*h-qfZ|W)`$CFT1V@LgKzgw l@yVN?8&3;(HZ@`CMsEJDH!giEqk9G1DIHOlM$XNCjcW6o%D|5E&R9#RQjQgo(lE zC}yA>3s@f$ObkXxvBLE+!^B{86k8>WCTpn(&?e8k^rF<_M1|5kg}lSNa#M@)trSYd zkRr-Uu|yPm}!?b7o%2E!NDu zg3^*(Y^YapOQj7HpDt~d<7esU}^XXpZ(raMBSN}4*K?BQ2AqEcaPSXp5Dwnxc NFSDyPvJ`=04*)&da#8>Q diff --git a/basico/__pycache__/03_bucles.cpython-312.pyc b/basico/__pycache__/03_bucles.cpython-312.pyc deleted file mode 100644 index 2d18b69c604a2316932ce80d412e03d1d87dff7f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 255 zcmX@j%ge<81XrRjWX7>GFgylvV1O0M_^bkCOlM$XNCjcW6o%D|5E&R9#gxJr#azjx z$y{m-lsUBDB~_uY^zcfByu-V4Q;YI}oXpgs)MAC4M1_*XBp{iRs*qcnQ<7PblbM`Y zWUug23#iXeljRn3W?soH*37(u(vn+@dAHb$QPO4oI$S)wb70UsM56p~=j31R4SUEabFYq~E=5V>p;@ZIY PL5YEzw~@Vw1E>T5n2(%a~j%x&NrrRl3qA2O4r~xI5fRa&RF z$7&8=pvt^Li*Ky|jp^QLuDQj%7IFZbX{OklsGAA#T?pbTyM6V*mt9+ z&z>J1C86s_p%?FTx~Uc?fx|2W)i?*2`vBiHYla)hIB&*d8UG8i-}Cw0Ep86|+?KQ% z_ZUCPh@>QpIk>@0oKwq-4?D~cBDRk1JsgbxKuj=mM8=PLQ+l?F;3~a+a(Y-(_((s9=Uk z;ISyKN?08h1s?SywvBZ!a8x?jKsV#@eXQ2sB&gRk#KWaJUTb(Ju2u9djwm?9ONbj5 zZ*XnB3?iDey;tlBGV#ZWKjHLKC4@}xE5!a~0Wm((!S2B6olIcu3Uu`L2CUbfz};!B zgd7h}d+#T(&H=|oI^XB<=}HOpheTBK^zvTm1rykqNmi?GUx7KWk#QypmYUKi$8^hy8eJriWJmyix)4eAgS+dHn>Ta{4A}f94f2` zvNsDw{JBXHdi36-AO-iZ<|KHEr>(v9?mgws8>)|OI`g> zmr-Z9O~cSJ4DxVAXuH5wp(8S3aBWw4$Ij-^Q^hd3&W-u$^KRR6p>3BZ*>g>Tt!mS3 zHT8miqM-X0GJ!&%5-&ixRU? zCHvaJ$IX>SN{f~nYX@I~mBtHesqruheZjpDncTYFiOMT2plQ8X%ULH%6DQ8qe&hv7 zu3_>;vC7$o(T96_S?AMCdd*}XB`KeE8EUp*S#8g0CO@HV%6o3A@v)!a=k@$)ViYf-Y6lhn}KY)ROF$|XDJ5oo9&pO+PWU>$gBMYKK zhl&Z5e}Mmig-At$n<_DROR2=riFYAsIqCi0?|r{}Uz<%I@cnuIEqU(&{L;qiIZJYW zgyaJx&;=8?!C`9rix^9r!EJPKV20LHa}{MKvzW~sMvm;Rxu`X-Y8mZX*wbG4?JIvD znETP_I;cI=g!x^H;-YwqT*_VUO|8|G@mkPOBo(8cBGQCj_L{7pV0|YrRKp zYtZ+q2|_@m9w#?6Y-%sn;A+4l!_L#dS3b{+k|j}EaOGq&Nee|Y$>Rjqati*c5Xygn zcFEH?i4+|sc@c$|q^D>sMrF!#<>g{1LY`vqlJ-8sIZlF$02_0;ILU*Dk3yEjI3bNB zjtR$MEYd-l79!ut#ux76kznPJ@5^nh)IZE$Bg`$sFy?J@-K_jG0tTrDC$PC>?{3XV z`|!!}WVW??0(2%(KA=)_us6~+u-e0&S|stf0N%Euy&`S%HOK! cso$*Vk4CHV7Vs0Cs{eL;7<`9&vV&{<1pubE2><{9 diff --git a/intermedio/__pycache__/02_funciones_orden_superior.cpython-312.pyc b/intermedio/__pycache__/02_funciones_orden_superior.cpython-312.pyc deleted file mode 100644 index bef0bb3e5beff5e8991c3f97c3f68b6672a17ad0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1147 zcmZvay>HV%6u{rbv12FBM=4+8LnbWGtV`V+sPgCJ4n;0>u52AKGYcu=)#G# znbGDyG~*hcl;2{**mWzTtPzEF9WyE7en}L$_QCkW+8Jw)SYGHty^OnMZg!~#>#xX_ zjINAm)CaZU3UfwTth<&)s*NIbY^U6(mN-lqQt-AXoMNBwKJ~1xk;s$K zNf;ywBuo-`EzqZ1nsIbVlq54**JV6qGE!O5xo<95?idf>+`HztpXi6h5vwuEd5?uWN-&n^++ zhfNVLg_4WrQrwP&^g}rlbyUHP0^f6`Jcq8cIAh8yf$w?q5EtML+D2=9Apltt^!7I3 z1wOgwh%aIu3&&-TqXE-r&tmeMkY`aInGXWDvCQ3hc@fonIAdy90=+9eck@~T@;s_e z{>1iCz5O#N7Mw9<8En zRqz{;D@Cl#NQQXLtq_T9!-zxK5?onXgUC1Qhthet90;XLx49yeg}&{eg=R^0W?2s_ zY+%4Z%*&f-pwi=yD1K^;v0tZwT|Ov6=|)o6vuo?)Ym2?l*25QUGDNK3BdrFFXmLD0<^k^o(c{Dkfi0tAf7*a9R{pya_p1`P?&vB=Wh zTic(KB}0dVYbS3;vSsR#ZefSR)A4(c#}n_etPi-d)BEBk0r=xK|5x;{c>amScMvck zIRqeygkNOs5tx7=3z7%k4ZRy~Tme&(N1jGoG{~uUn0MI5!EWJ#phjLPYMA$Y@7QPK zP1e)I(_};EY}7j#F&j;F$t|sBN@&aKc{|n02C}hiB2~dl8&387^21nHwUMeRw35x9 zRD0{>C|tTfTn0`;6a?-$medJbgPyBnC-`#kWz@HHJUiEorL`$kYvY=i{M>N7v*c!i z-@$msh2cUsXQCLlmR_JM(Uz@`RlGIDC7v(2!r^OfWb*@_u{*r%VoPZ%DGGgf^y%!? z;0N{mCH`D#F)QV<*~Pe>)|F+Tww&Yi?4rg9H2pSiYX2 diff --git a/intermedio/__pycache__/04_archivos_y_excepciones.cpython-312.pyc b/intermedio/__pycache__/04_archivos_y_excepciones.cpython-312.pyc deleted file mode 100644 index e69172ed27678907546c0e668e3c33d4a2973221..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1243 zcmbVK&1(}u6o0c{P10=CTD7g%Mg&U`;#ai@r3Y^X=^s#qu-zS#Z8y8&?It8SwIH-d zZ}nd&Meu*{=%vyX?4ATq-ePkQdh*RCn-2;F9hjN-e((3@_h#OF(e(__n0s?<|Ct2% zDV$`eeWSa=01m(ci#f0Xmh=ubm;{_z@)1SEU|=bPN`y*ds7k0zsBFoWb|fY23%m*9 zDTFFkYItVsk7}fer4p*qRIN!>~kjd&Qv>ZSS4%zx4Em6+(s+-752AUPS;rSvdf4*qD z0mmx0Z13Ttr9rUND)FYtYo_hF+%MKzk!~V4Fd<-?vabjk(ajzBp`^NGKs)Vvf#DZ} zW^j2`D9S^Tj2bPyYA{7+lyx{C3h4yR3Yz#(NPh{;e!I!+jj`(v4=zYJL4-(kY?m9p z$jaw?61q`FUZ(5BA-qbVdo+g{^%-(sef~&^`5xCI!^yw3UBmhRn;DyEW69^`I(jHN zTpUwv-|9D~L=`t}Kj74ye|gISi`0hUcsTl=Q>N!OI0mF_l*EaoeS>sgjA=*G(vwK3 zc#hFlo)#Z36*7_J`Ej37^dNquxaK%HQfo+GCsJxgP>Hm-T0hc|S3S~-`zm@BKlgcR zrRrIAhp*xt!owwKI)vGQOVQ)o&q8>9 z3fb|9eyraQVeta4ebr_@OrL1;AuODND!iK~T0Vrk<6b8Pinh1ByS%r$yZZh?D9?Xa X^qrS`YrAXv+uxMAjtt5|{QLd_@~ZHU