Proyecto III (exprés): El Organizador de Archivos
Fig. 13.2: El desorden entra, los estantes salen.
La carpeta de Descargas de cualquier computadora es un almacén sin gerente: facturas junto a memes, instaladores junto a fotos. Este proyecto la ordena: cada archivo a su estante según su extensión. Es el programa de automatización más gratificante que existe, cabe en veinte líneas, y todo lo que usa ya lo tienes.
El Reto
Dada una carpeta, el programa debe:
- Recorrer sus archivos (solo archivos, no subcarpetas).
- Decidir el estante según la extensión:
.pdf→documentos/,.jpg/.png→imagenes/, el resto →otros/. - Crear los estantes si no existen y mover cada archivo al suyo.
El Plano
Un diccionario decide los destinos y pathlib hace el trabajo pesado:
"""Organizador: cada archivo a su estante según la extensión."""
from pathlib import Path
DESTINOS = {
".pdf": "documentos",
".txt": "documentos",
".jpg": "imagenes",
".png": "imagenes",
}
def organizar(carpeta: Path) -> int:
"""Mueve cada archivo a su subcarpeta y devuelve cuántos movió."""
movidos = 0
for archivo in carpeta.iterdir():
if not archivo.is_file():
continue # las subcarpetas no se tocan
estante = DESTINOS.get(archivo.suffix.lower(), "otros")
destino = carpeta / estante
destino.mkdir(exist_ok=True)
archivo.rename(destino / archivo.name)
movidos += 1
return movidos
if __name__ == "__main__":
carpeta = Path("desorden")
total = organizar(carpeta)
print(f"Organización terminada: {total} archivo(s) en su estante.")
Las Piezas, Una a Una
Casi nada aquí es nuevo (solo is_file() y rename(), y ambos se explican aquí mismo); el mérito está en el ensamble:
iterdir()recorre la carpeta (elfordel Capítulo 8 sobre un territorio nuevo), y elcontinuedel patrón de filtrado salta lo que no es archivo.archivo.suffixes la extensión con punto (.pdf); en minúsculas para que.PDFno se escape (el.lower()de siempre).DESTINOS.get(..., "otros")es el.get()con valor por defecto del Capítulo 5: los formatos desconocidos no rompen el programa, van aotros/.mkdir(exist_ok=True)crea el estante solo si hace falta, sin quejarse si ya existe.rename()es el montacargas: mueve el archivo a su destino, pero a diferencia de uno real, no frena si el destino ya está ocupado (ver la advertencia abajo).- Y el guardián
if __name__ == "__main__":que conociste en el ensamblaje del SGI.
Pruébalo Sin Miedo
Mover archivos impone respeto, así que el protocolo de prueba es fabricar un desorden desechable:
En macOS/Linux:
mkdir desorden
cd desorden
touch factura.pdf notas.txt foto.jpg logo.png video.mp4
cd ..
En Windows (PowerShell):
mkdir desorden
cd desorden
ni factura.pdf, notas.txt, foto.jpg, logo.png, video.mp4
cd ..
Antes de correrlo, ¿a qué carpeta crees que va cada archivo? Repasa el diccionario DESTINOS de arriba.
Corre el programa y revisa el resultado: documentos/ con dos archivos, imagenes/ con dos, otros/ con el video. Si algo sale mal, el desorden era de mentira y no perdiste nada.
Cuidado:
rename()no pregunta. Si en el destino ya existe un archivo con el mismo nombre, lo reemplaza sin aviso. Para una carpeta personal real, la primera mejora de abajo deja de ser opcional.
Lleva más Lejos
- Colisiones: antes de mover, revisa con
.exists()si el destino ya tiene ese nombre, y renombra (foto_2.jpg) en vez de pisar. - Reporte: cuenta cuántos archivos fueron a cada estante (el patrón contador, ahora con un diccionario) e imprime el resumen.
- Configuración externa: saca
DESTINOSa undestinos.jsony cárgalo conjson.load: cambiar las reglas dejará de requerir tocar el código.
Resumen del Capítulo
- Ninguno de los dos proyectos introduce conceptos nuevos: ambos aplican herramientas de capítulos anteriores a problemas distintos.
sorted(..., key=lambda par: par[1], reverse=True):keydecide por qué campo ordenar, y unalambdaes una función de una sola línea, sin nombre, para cuando no vale la pena escribir undef.Path.is_file()distingue archivos de subcarpetas al recorrer coniterdir().Path.rename()mueve un archivo a un destino nuevo, pero lo hace sin avisar si ya hay algo ahí.
Con el SGI, el Analizador y el Organizador terminados, ya construiste tres programas completos y distintos con la misma caja de herramientas. El último capítulo cierra el libro con un repaso de todo lo aprendido y un mapa de por dónde seguir.