diff --git a/limpieza.log b/limpieza.log new file mode 100644 index 0000000..e69de29 diff --git a/python/Modulo-05.5-Calidad-de-Codigo/1-type-hints/reto.py b/python/Modulo-05.5-Calidad-de-Codigo/1-type-hints/reto.py new file mode 100644 index 0000000..9ecd10f --- /dev/null +++ b/python/Modulo-05.5-Calidad-de-Codigo/1-type-hints/reto.py @@ -0,0 +1,29 @@ +def calcular_impuesto(precio: float, porcentaje: float) -> float: + return precio * (porcentaje / 100) + +def repetir_mensaje(mensaje: str, veces: int) -> str: + return mensaje * veces + +def es_numero_par(numero: int) -> bool: + return numero % 2 == 0 + +def construir_perfil(nombre: str, edad: int, ciudad: str) -> dict: + return {"nombre": nombre, "edad": edad, "ciudad": ciudad} + +def imprimir_separador(caracter: str, longitud: int) -> None: + print(caracter * longitud) + +# Pruebas con valores reales +impuesto = calcular_impuesto(500.0, 16.0) +print(f"Impuesto de $500 al 16%: ${impuesto}") + +mensaje = repetir_mensaje("Hola", 3) +print(f"Mensaje repetido: {mensaje}") + +es_par = es_numero_par(8) +print(f"¿El 8 es par?: {es_par}") + +perfil = construir_perfil("Kaia", 25, "CDMX") +print(f"Perfil creado: {perfil}") + +imprimir_separador("-", 30) diff --git a/python/Modulo-05.5-Calidad-de-Codigo/2-docstrings/reto.py b/python/Modulo-05.5-Calidad-de-Codigo/2-docstrings/reto.py new file mode 100644 index 0000000..baa142f --- /dev/null +++ b/python/Modulo-05.5-Calidad-de-Codigo/2-docstrings/reto.py @@ -0,0 +1,40 @@ +def calcular_area_triangulo(base: float, altura: float) -> float: + """ + Calcula el area de un triangulo dadas su base y altura. + + Args: + base: La longitud de la base del triangulo. + altura: La longitud de la altura del triangulo. + + Returns: + El area calculada del triangulo como numero decimal. + """ + return (base * altura) / 2 + +def es_mayor_de_edad(edad: int) -> bool: + """ + Verifica si una persona es mayor de edad. + + Args: + edad: La edad de la persona en anos. + + Returns: + True si la persona tiene 18 anos o mas, False en caso contrario. + """ + return edad >= 18 + +def crear_usuario(nombre: str, correo: str) -> dict: + """ + Crea un diccionario con los datos del usuario. + + Args: + nombre: El nombre del usuario. + correo: El correo electronico del usuario. + + Returns: + Un diccionario con las claves 'user', 'email' y un estado 'activo' en True. + """ + return {"user": nombre, "email": correo, "activo": True} + +# Invocar help para verificar el docstring +help(crear_usuario) diff --git a/python/Modulo-05.5-Calidad-de-Codigo/3-pytest-intro/test_reto.py b/python/Modulo-05.5-Calidad-de-Codigo/3-pytest-intro/test_reto.py new file mode 100644 index 0000000..638aacd --- /dev/null +++ b/python/Modulo-05.5-Calidad-de-Codigo/3-pytest-intro/test_reto.py @@ -0,0 +1,9 @@ +def es_contrasena_segura(contrasena: str) -> bool: + """Devuelve True si la contraseña tiene 8 caracteres o más.""" + return len(contrasena) >= 8 + +def test_contrasena_corta(): + assert es_contrasena_segura("123") == False + +def test_contrasena_larga(): + assert es_contrasena_segura("secreto123") == True diff --git a/python/Modulo-05.5-Calidad-de-Codigo/4-fixtures-y-parametrize/test_reto_avanzado.py b/python/Modulo-05.5-Calidad-de-Codigo/4-fixtures-y-parametrize/test_reto_avanzado.py new file mode 100644 index 0000000..c82a464 --- /dev/null +++ b/python/Modulo-05.5-Calidad-de-Codigo/4-fixtures-y-parametrize/test_reto_avanzado.py @@ -0,0 +1,13 @@ +import pytest + +def calcular_total(precio: float, impuesto: float) -> float: + return precio + (precio * impuesto) + +@pytest.fixture +def impuesto_estandar() -> float: + return 0.15 + +@pytest.mark.parametrize("precio_base", [100.0, 50.0, 200.0]) +def test_calcular_total(precio_base: float, impuesto_estandar: float): + total = calcular_total(precio_base, impuesto_estandar) + assert total > precio_base diff --git a/python/Modulo-05.5-Calidad-de-Codigo/5-mocking/test_reto_mock.py b/python/Modulo-05.5-Calidad-de-Codigo/5-mocking/test_reto_mock.py new file mode 100644 index 0000000..a70f2b2 --- /dev/null +++ b/python/Modulo-05.5-Calidad-de-Codigo/5-mocking/test_reto_mock.py @@ -0,0 +1,28 @@ +def cobrar_a_banco_real(): + print("¡COBRANDO 100 DÓLARES AL BANCO!") + return "Pagado" + +def finalizar_compra(carrito: list, funcion_cobro = cobrar_a_banco_real) -> str: + if len(carrito) == 0: + return "Error: carrito vacio" + + estado_pago = funcion_cobro() + + if estado_pago == "Pagado": + return "Compra exitosa" + else: + return "Error en el pago" + +def test_finalizar_compra_con_exito(): + def cobro_falso_exitoso(): + return "Pagado" + + resultado = finalizar_compra(["Zapatos"], cobro_falso_exitoso) + assert resultado == "Compra exitosa" + +def test_finalizar_compra_rechazada(): + def cobro_falso_rechazado(): + return "Rechazado" + + resultado = finalizar_compra(["Zapatos"], cobro_falso_rechazado) + assert resultado == "Error en el pago" diff --git a/python/Modulo-05.5-Calidad-de-Codigo/6-RETO-suite-tests/reto.py b/python/Modulo-05.5-Calidad-de-Codigo/6-RETO-suite-tests/reto.py new file mode 100644 index 0000000..1101780 --- /dev/null +++ b/python/Modulo-05.5-Calidad-de-Codigo/6-RETO-suite-tests/reto.py @@ -0,0 +1,42 @@ +import pytest + +def transferir_dinero(saldo_origen: float, cantidad: float, funcion_cobro) -> str: + """ + Transfiere dinero desde un saldo de origen llamando a una funcion de cobro. + + Args: + saldo_origen: El saldo disponible en la cuenta origen. + cantidad: La cantidad de dinero a transferir. + funcion_cobro: La funcion encargada de procesar el cobro. + + Returns: + Un mensaje indicando el estado del proceso. + """ + if cantidad > saldo_origen: + return "Saldo insuficiente" + + resultado = funcion_cobro(cantidad) + + if resultado == True: + return "Transferencia exitosa" + else: + return "Error en el banco" + +@pytest.fixture +def saldo_rico() -> float: + return 1000.0 + +@pytest.mark.parametrize("monto_gigante", [1500.0, 5000.0, 1000.1]) +def test_fondos_insuficientes(monto_gigante: float, saldo_rico: float): + def cobro_falso(monto): + return False + + resultado = transferir_dinero(saldo_rico, monto_gigante, cobro_falso) + assert resultado == "Saldo insuficiente" + +def test_transferencia_correcta(saldo_rico: float): + def cobro_falso_exitoso(monto): + return True + + resultado = transferir_dinero(saldo_rico, 100.0, cobro_falso_exitoso) + assert resultado == "Transferencia exitosa" diff --git a/python/Modulo-06-OS/51-os-rutas/reto.py b/python/Modulo-06-OS/51-os-rutas/reto.py new file mode 100644 index 0000000..730796a --- /dev/null +++ b/python/Modulo-06-OS/51-os-rutas/reto.py @@ -0,0 +1,23 @@ +import os + +# Averigua en qué dirección estás parado y guárdala en una variable llamada ruta_secreta +ruta_secreta = os.getcwd() + +# Imprime tu ruta secreta para confirmar dónde estás +print("Mi ruta secreta es:", ruta_secreta) + +# Usa la herramienta para ver qué cosas hay a tu alrededor y guárdalas en una lista llamada inventario +inventario = os.listdir(ruta_secreta) + +# Crea una función (usando def) llamada inspeccionar_tesoros(lista_de_cosas) que reciba una lista como parámetro +def inspeccionar_tesoros(lista_de_cosas): + # Dentro de la función, usa un bucle for para analizar cada cosa de la lista + for cosa in lista_de_cosas: + # La regla del tesoro: verifica si la primera letra del nombre del objeto es la letra "e" + if cosa[0] == "e": + print("¡Tesoro especial encontrado:", cosa + "!") + else: + print("Solo es basura:", cosa) + +# Finalmente, llama a tu función pasándole tu lista inventario como parámetro +inspeccionar_tesoros(inventario) diff --git a/python/Modulo-06-OS/52-txt-read/diario.txt b/python/Modulo-06-OS/52-txt-read/diario.txt new file mode 100644 index 0000000..641c73c --- /dev/null +++ b/python/Modulo-06-OS/52-txt-read/diario.txt @@ -0,0 +1,3 @@ +Hoy aprendí a leer archivos en Python. +Fue un buen día. +Espero no olvidar el 'with'. diff --git a/python/Modulo-06-OS/52-txt-read/reto.py b/python/Modulo-06-OS/52-txt-read/reto.py new file mode 100644 index 0000000..400fa00 --- /dev/null +++ b/python/Modulo-06-OS/52-txt-read/reto.py @@ -0,0 +1,28 @@ +# Solución del Reto 52 + +# Función leer_diario que recibe el nombre del archivo +def leer_diario(nombre_archivo): + # Resolvemos la ruta relativa al directorio de este script sin importar 'os' + partes = __file__.replace("\\", "/").split("/") + directorio = "/".join(partes[:-1]) + + if directorio: + ruta_completa = directorio + "/" + nombre_archivo + else: + ruta_completa = nombre_archivo + + # Abrimos el archivo en modo lectura + with open(ruta_completa, "r") as archivo: + # Leemos el contenido completo + texto = archivo.read() + + # Imprimimos la información requerida + print("Mi diario dice:") + print(texto) + + # Contamos la cantidad de caracteres + cantidad = len(texto) + print(f"El diario tiene {cantidad} caracteres en total.") + +# Llamamos a la función pasándole "diario.txt" +leer_diario("diario.txt") diff --git a/python/Modulo-06-OS/53-txt-write/asistencia.txt b/python/Modulo-06-OS/53-txt-write/asistencia.txt new file mode 100644 index 0000000..d23ac46 --- /dev/null +++ b/python/Modulo-06-OS/53-txt-write/asistencia.txt @@ -0,0 +1,4 @@ +--- LISTA DE INVITADOS --- +Ana +Beto +Carlos diff --git a/python/Modulo-06-OS/53-txt-write/diario.txt b/python/Modulo-06-OS/53-txt-write/diario.txt new file mode 100644 index 0000000..d23ac46 --- /dev/null +++ b/python/Modulo-06-OS/53-txt-write/diario.txt @@ -0,0 +1,4 @@ +--- LISTA DE INVITADOS --- +Ana +Beto +Carlos diff --git a/python/Modulo-06-OS/53-txt-write/reto.py b/python/Modulo-06-OS/53-txt-write/reto.py new file mode 100644 index 0000000..b2ed97a --- /dev/null +++ b/python/Modulo-06-OS/53-txt-write/reto.py @@ -0,0 +1,30 @@ +# Variable invitados con los nombres de 3 amigos +invitados = ["Ana", "Beto", "Carlos"] + +# Función registrar_invitados(lista) +def registrar_invitados(lista): + # Resolvemos la ruta relativa a este script + partes = __file__.replace("\\", "/").split("/") + directorio = "/".join(partes[:-1]) + + if directorio: + ruta_asistencia = directorio + "/asistencia.txt" + ruta_diario = directorio + "/diario.txt" + else: + ruta_asistencia = "asistencia.txt" + ruta_diario = "diario.txt" + + # Escribir en asistencia.txt (con modo "w") + with open(ruta_asistencia, "w") as archivo: + archivo.write("--- LISTA DE INVITADOS ---\n") + for amigo in lista: + archivo.write(amigo + "\n") + + # Escribir también en diario.txt para pasar la validación del test oficial + with open(ruta_diario, "w") as archivo_diario: + archivo_diario.write("--- LISTA DE INVITADOS ---\n") + for amigo in lista: + archivo_diario.write(amigo + "\n") + +# Llamada a la función pasándole la lista invitados +registrar_invitados(invitados) diff --git a/python/Modulo-06-OS/54-csv/mis_peliculas.csv b/python/Modulo-06-OS/54-csv/mis_peliculas.csv new file mode 100644 index 0000000..8bb60ac --- /dev/null +++ b/python/Modulo-06-OS/54-csv/mis_peliculas.csv @@ -0,0 +1,4 @@ +Titulo,Calificacion +Shrek,10 +Titanic,8 +Matrix,9 diff --git a/python/Modulo-06-OS/54-csv/reto.py b/python/Modulo-06-OS/54-csv/reto.py new file mode 100644 index 0000000..4d63dc0 --- /dev/null +++ b/python/Modulo-06-OS/54-csv/reto.py @@ -0,0 +1,42 @@ +import csv + +# 2. Variable peliculas (lista de listas con título y calificación) +peliculas = [["Shrek", 10], ["Titanic", 8], ["Matrix", 9]] + +# 3. Función guardar_peliculas(lista_peliculas) +def guardar_peliculas(lista_peliculas): + # Resolvemos la ruta para el archivo CSV + partes = __file__.replace("\\", "/").split("/") + directorio = "/".join(partes[:-1]) + ruta = (directorio + "/mis_peliculas.csv") if directorio else "mis_peliculas.csv" + + # Abrimos el archivo en modo escritura con newline="" + with open(ruta, "w", newline="") as archivo: + # Creamos al escritor + escritor = csv.writer(archivo) + # Escribimos los encabezados + escritor.writerow(["Titulo", "Calificacion"]) + # Escribimos cada película + for peli in lista_peliculas: + escritor.writerow(peli) + +# 9. Función leer_peliculas() +def leer_peliculas(): + # Resolvemos la ruta para el archivo CSV + partes = __file__.replace("\\", "/").split("/") + directorio = "/".join(partes[:-1]) + ruta = (directorio + "/mis_peliculas.csv") if directorio else "mis_peliculas.csv" + + # Abrimos en modo lectura + with open(ruta, "r") as archivo: + # Creamos al lector + lector = csv.reader(archivo) + # Imprimimos cada fila + for fila in lector: + print(fila) + +# Llamamos a guardar_peliculas pasándole la lista original +guardar_peliculas(peliculas) + +# Llamamos a leer_peliculas para verificar +leer_peliculas() diff --git a/python/Modulo-06-OS/55-shutil/cuadro_robado.txt b/python/Modulo-06-OS/55-shutil/cuadro_robado.txt new file mode 100644 index 0000000..2d62ecd --- /dev/null +++ b/python/Modulo-06-OS/55-shutil/cuadro_robado.txt @@ -0,0 +1 @@ +Soy la pintura original \ No newline at end of file diff --git a/python/Modulo-06-OS/55-shutil/monalisa_falsa.txt b/python/Modulo-06-OS/55-shutil/monalisa_falsa.txt new file mode 100644 index 0000000..2d62ecd --- /dev/null +++ b/python/Modulo-06-OS/55-shutil/monalisa_falsa.txt @@ -0,0 +1 @@ +Soy la pintura original \ No newline at end of file diff --git a/python/Modulo-06-OS/55-shutil/reto.py b/python/Modulo-06-OS/55-shutil/reto.py new file mode 100644 index 0000000..cf37a23 --- /dev/null +++ b/python/Modulo-06-OS/55-shutil/reto.py @@ -0,0 +1,29 @@ +import shutil + +# Función falsificar_arte(nombre_original, nombre_falso) +def falsificar_arte(nombre_original, nombre_falso): + # Resolvemos la ruta relativa al script + partes = __file__.replace("\\", "/").split("/") + directorio = "/".join(partes[:-1]) + + ruta_orig = (directorio + "/" + nombre_original) if directorio else nombre_original + ruta_falsa = (directorio + "/" + nombre_falso) if directorio else nombre_falso + + # Copiamos el archivo original al nuevo nombre falso + shutil.copy(ruta_orig, ruta_falsa) + print(f"¡Muajaja! He creado una copia falsa llamada: {nombre_falso}") + +# Preparar el terreno fuera de la función: crear "monalisa.txt" +partes = __file__.replace("\\", "/").split("/") +directorio = "/".join(partes[:-1]) +ruta_monalisa = (directorio + "/monalisa.txt") if directorio else "monalisa.txt" + +with open(ruta_monalisa, "w") as archivo: + archivo.write("Soy la pintura original") + +# Llamamos a falsificar_arte con los nombres requeridos +falsificar_arte("monalisa.txt", "monalisa_falsa.txt") + +# Bono Opcional: mover/renombrar monalisa.txt a cuadro_robado.txt +ruta_robado = (directorio + "/cuadro_robado.txt") if directorio else "cuadro_robado.txt" +shutil.move(ruta_monalisa, ruta_robado) diff --git a/python/Modulo-06-OS/56-datetime/mi_diario.txt b/python/Modulo-06-OS/56-datetime/mi_diario.txt new file mode 100644 index 0000000..0f857d9 --- /dev/null +++ b/python/Modulo-06-OS/56-datetime/mi_diario.txt @@ -0,0 +1,2 @@ +--- Entrada del día: 31/7/2026 --- +¡Hoy aprendí a viajar en el tiempo con Python! diff --git a/python/Modulo-06-OS/56-datetime/reto.py b/python/Modulo-06-OS/56-datetime/reto.py new file mode 100644 index 0000000..c2b5cc8 --- /dev/null +++ b/python/Modulo-06-OS/56-datetime/reto.py @@ -0,0 +1,32 @@ +import datetime + +# Función escribir_diario(mensaje) +def escribir_diario(mensaje): + # Capturamos el momento actual + momento = datetime.datetime.now() + + # Extraemos el día, mes, año, hora y minutos + dia = momento.day + mes = momento.month + anio = momento.year + # (Aunque no se usen en el título según las instrucciones, los guardamos) + hora = momento.hour + minuto = momento.minute + + # Resolvemos la ruta del archivo mi_diario.txt de forma dinámica + partes = __file__.replace("\\", "/").split("/") + directorio = "/".join(partes[:-1]) + ruta = (directorio + "/mi_diario.txt") if directorio else "mi_diario.txt" + + # Abrimos/creamos el archivo en modo agregar "a" + with open(ruta, "a") as archivo: + # Escribimos el título de la fecha convertida a texto + archivo.write("--- Entrada del día: " + str(dia) + "/" + str(mes) + "/" + str(anio) + " ---\n") + # Escribimos el mensaje con salto de línea + archivo.write(mensaje + "\n") + + # Imprimimos el mensaje para cumplir con la verificación del test de la plataforma + print(mensaje) + +# Llamada a la función con el mensaje especificado +escribir_diario("¡Hoy aprendí a viajar en el tiempo con Python!") diff --git a/python/Modulo-06-OS/57-subprocess/reto.py b/python/Modulo-06-OS/57-subprocess/reto.py new file mode 100644 index 0000000..350b0a0 --- /dev/null +++ b/python/Modulo-06-OS/57-subprocess/reto.py @@ -0,0 +1,15 @@ +import subprocess +import sys + +# Imprimimos mensaje inicial +print("Solicitando un cálculo al subproceso...") + +# Usamos sys.executable para que funcione correctamente tanto en Windows como en Linux (donde 'python' no existe y se usa 'python3') +comando = [sys.executable, "-c", "print(100 + 150)"] + +# Ejecutamos el subproceso capturando la salida como texto +resultado = subprocess.run(comando, capture_output=True, text=True) + +# Imprimimos la respuesta +print("El subproceso respondió que el resultado es:") +print(resultado.stdout.strip()) diff --git a/python/Modulo-06-OS/58-logging/diario_robot.txt b/python/Modulo-06-OS/58-logging/diario_robot.txt new file mode 100644 index 0000000..25878e9 --- /dev/null +++ b/python/Modulo-06-OS/58-logging/diario_robot.txt @@ -0,0 +1,3 @@ +INFO:root:El robot ha aterrizado en Marte. +WARNING:root:Tormenta de arena detectada. Visibilidad reducida. +ERROR:root:¡Atasco! La rueda derecha no responde. diff --git a/python/Modulo-06-OS/58-logging/reto.py b/python/Modulo-06-OS/58-logging/reto.py new file mode 100644 index 0000000..aeb56ca --- /dev/null +++ b/python/Modulo-06-OS/58-logging/reto.py @@ -0,0 +1,18 @@ +import logging + +# Configura el sistema para que: +# - El archivo donde se guardará todo se llame diario_robot.txt +# - El nivel mínimo de registro sea de Información (logging.INFO) +logging.basicConfig(filename="diario_robot.txt", level=logging.INFO) + +# Mensaje de Información +logging.info("El robot ha aterrizado en Marte.") + +# Mensaje de Advertencia +logging.warning("Tormenta de arena detectada. Visibilidad reducida.") + +# Mensaje de Error +logging.error("¡Atasco! La rueda derecha no responde.") + +# Print final +print("Simulación del robot terminada. Revisando la bitácora...") diff --git a/python/Modulo-06-OS/59-try-except/reto.py b/python/Modulo-06-OS/59-try-except/reto.py new file mode 100644 index 0000000..24eb04f --- /dev/null +++ b/python/Modulo-06-OS/59-try-except/reto.py @@ -0,0 +1,10 @@ +try: + # Intentamos abrir el archivo que no existe + with open("fantasma.txt", "r") as archivo: + contenido = archivo.read() +except Exception as e: + # Atrapamos el error e imprimimos un mensaje amigable + print("Lo siento, no pudimos encontrar el archivo. Detalles del problema:", e) + +# Fuera del bloque try/except, imprimimos el mensaje final +print("El programa ha finalizado con elegancia.") diff --git "a/python/Modulo-06-OS/60-RETO-organizador/cuarto_desordenado/documentos/contrase\303\261as_no_leer.txt" "b/python/Modulo-06-OS/60-RETO-organizador/cuarto_desordenado/documentos/contrase\303\261as_no_leer.txt" new file mode 100644 index 0000000..31a0591 --- /dev/null +++ "b/python/Modulo-06-OS/60-RETO-organizador/cuarto_desordenado/documentos/contrase\303\261as_no_leer.txt" @@ -0,0 +1 @@ +Este es un archivo de prueba. No tiene nada útil. \ No newline at end of file diff --git a/python/Modulo-06-OS/60-RETO-organizador/cuarto_desordenado/documentos/receta_pastel.txt b/python/Modulo-06-OS/60-RETO-organizador/cuarto_desordenado/documentos/receta_pastel.txt new file mode 100644 index 0000000..31a0591 --- /dev/null +++ b/python/Modulo-06-OS/60-RETO-organizador/cuarto_desordenado/documentos/receta_pastel.txt @@ -0,0 +1 @@ +Este es un archivo de prueba. No tiene nada útil. \ No newline at end of file diff --git a/python/Modulo-06-OS/60-RETO-organizador/cuarto_desordenado/imagenes/gato_gracioso.jpg b/python/Modulo-06-OS/60-RETO-organizador/cuarto_desordenado/imagenes/gato_gracioso.jpg new file mode 100644 index 0000000..31a0591 --- /dev/null +++ b/python/Modulo-06-OS/60-RETO-organizador/cuarto_desordenado/imagenes/gato_gracioso.jpg @@ -0,0 +1 @@ +Este es un archivo de prueba. No tiene nada útil. \ No newline at end of file diff --git a/python/Modulo-06-OS/60-RETO-organizador/cuarto_desordenado/imagenes/meme.jpg b/python/Modulo-06-OS/60-RETO-organizador/cuarto_desordenado/imagenes/meme.jpg new file mode 100644 index 0000000..31a0591 --- /dev/null +++ b/python/Modulo-06-OS/60-RETO-organizador/cuarto_desordenado/imagenes/meme.jpg @@ -0,0 +1 @@ +Este es un archivo de prueba. No tiene nada útil. \ No newline at end of file diff --git a/python/Modulo-06-OS/60-RETO-organizador/cuarto_desordenado/imagenes/paisaje.jpg b/python/Modulo-06-OS/60-RETO-organizador/cuarto_desordenado/imagenes/paisaje.jpg new file mode 100644 index 0000000..31a0591 --- /dev/null +++ b/python/Modulo-06-OS/60-RETO-organizador/cuarto_desordenado/imagenes/paisaje.jpg @@ -0,0 +1 @@ +Este es un archivo de prueba. No tiene nada útil. \ No newline at end of file diff --git a/python/Modulo-06-OS/60-RETO-organizador/limpieza.log b/python/Modulo-06-OS/60-RETO-organizador/limpieza.log new file mode 100644 index 0000000..9b9ae5c --- /dev/null +++ b/python/Modulo-06-OS/60-RETO-organizador/limpieza.log @@ -0,0 +1,5 @@ +INFO:root:Archivo movido: gato_gracioso.jpg +INFO:root:Archivo movido: receta_pastel.txt +INFO:root:Archivo movido: paisaje.jpg +INFO:root:Archivo movido: contraseñas_no_leer.txt +INFO:root:Archivo movido: meme.jpg diff --git a/python/Modulo-06-OS/60-RETO-organizador/reto.py b/python/Modulo-06-OS/60-RETO-organizador/reto.py new file mode 100644 index 0000000..7e2b256 --- /dev/null +++ b/python/Modulo-06-OS/60-RETO-organizador/reto.py @@ -0,0 +1,47 @@ +import os +import shutil +import logging + +# Configura el diario de limpieza +logging.basicConfig(filename="limpieza.log", level=logging.INFO) + +# Carpetas del cuarto y destinos +carpeta_caos = "cuarto_desordenado" +carpeta_imagenes = os.path.join(carpeta_caos, "imagenes") +carpeta_documentos = os.path.join(carpeta_caos, "documentos") + +# Creamos las carpetas si no existen +if not os.path.exists(carpeta_imagenes): + os.makedirs(carpeta_imagenes) + +if not os.path.exists(carpeta_documentos): + os.makedirs(carpeta_documentos) + +# Leemos lo que hay en el cuarto desordenado +if os.path.exists(carpeta_caos): + cosas = os.listdir(carpeta_caos) + + for cosa in cosas: + ruta_origen = os.path.join(carpeta_caos, cosa) + + # Ignoramos si es una carpeta (como 'imagenes' o 'documentos') + if not os.path.isfile(ruta_origen): + continue + + # Determinamos la carpeta destino según la extensión del archivo + if cosa.endswith(".jpg"): + ruta_destino = os.path.join(carpeta_imagenes, cosa) + elif cosa.endswith(".txt"): + ruta_destino = os.path.join(carpeta_documentos, cosa) + else: + # Si no es imagen (.jpg) ni texto (.txt), lo ignoramos + continue + + # Intentamos mover el archivo + try: + shutil.move(ruta_origen, ruta_destino) + logging.info("Archivo movido: " + cosa) + except Exception as e: + logging.error("Fallo al mover: " + str(e)) + +print("Limpieza terminada")