Apariencia
📙 Clase 22 — Librería estándar: datetime, pathlib, random
Fase 4 · Archivos y el mundo exterior ⬅️ Volver al índice de clases
🎯 Qué aprendí
datetime: fechas y horas — crear, formatear, sumar/restar, parsear.pathlib: rutas de archivos modernas (adiós a pegar strings con/).random: azar controlado. Python trae "pilas incluidas": revisa antes de instalar.
📖 PARTE TEÓRICA
📅 1. datetime: fechas y horas
python
from datetime import datetime, timedelta
ahora = datetime.now() # fecha+hora actuales
d = datetime(2026, 7, 11, 20, 30) # una fecha concreta
print(d.year, d.month, d.day) # 2026 7 11Formatear (fecha → texto) con strftime y parsear (texto → fecha) con strptime:
python
print(d.strftime("%d/%m/%Y %H:%M")) # 11/07/2026 20:30
f = datetime.strptime("25/12/2026", "%d/%m/%Y")
print(f.date()) # 2026-12-25| Código | Significa | Ejemplo |
|---|---|---|
%d / %m / %Y | día / mes / año (4 cifras) | 11 07 2026 |
%H / %M / %S | hora / minuto / segundo | 20 30 00 |
🧪 Tip de entrevista: "¿
strftimevsstrptime?" → f = format (fecha → texto); p = parse (texto → fecha). Los códigos%d/%m/%Yson los mismos en ambas.
Aritmética con timedelta (sumar/restar tiempo) y restas entre fechas:
python
manana = d + timedelta(days=1) # 12/07/2026
dif = datetime(2026, 12, 25) - d
print(dif.days) # 166 días hasta navidad📁 2. pathlib: rutas como objetos
Path reemplaza el pegado manual de strings para rutas — y funciona igual en macOS/Windows/Linux:
python
from pathlib import Path
p = Path("tareas.json")
print(p.name, p.suffix, p.exists()) # tareas.json .json True
carpeta = Path("datos_app")
carpeta.mkdir(exist_ok=True) # crear carpeta (sin error si ya existe)
archivo = carpeta / "config.json" # el operador / UNE rutas 🤯
archivo.write_text('{"tema": "oscuro"}', encoding="utf-8") # escribir en 1 línea
print(archivo.read_text(encoding="utf-8")) # leer en 1 línea| Utilidad | Con pathlib |
|---|---|
| Carpeta del usuario | Path.home() → /Users/styp |
| ¿Existe? | p.exists() |
| Unir rutas | Path("a") / "b" / "c.txt" |
Listar .md de una carpeta | p.glob("*.md") |
| Crear carpetas | p.mkdir(parents=True, exist_ok=True) |
🎲 3. random: azar
python
import random
random.randint(1, 6) # dado: entero entre 1 y 6 (incluidos)
random.choice(["Ana", "Luis", "Marta"]) # uno al azar
random.shuffle(lista) # mezcla la lista EN el sitio
random.sample(lista, 2) # 2 distintos, sin tocar la original📌
random.seed(42)fija la semilla: misma secuencia "aleatoria" en cada corrida — clave para reproducir bugs y tests. (Y no usesrandompara seguridad: existesecrets.)
💡 Filosofía batteries included: antes de
pip install algo, busca en la librería estándar:datetime,pathlib,csv,json,sqlite3,zipfile,smtplib… ya vienen con Python.
🖥️ EN TU APP DE ESCRITORIO
Los tres módulos aparecen juntos en cualquier app real:
python
from datetime import datetime
from pathlib import Path
import json
class App(ctk.CTk):
# pathlib: guardar los datos DONDE corresponde (no junto al .py)
CARPETA = Path.home() / ".mi_todo" # ~/.mi_todo/
ARCHIVO = CARPETA / "tareas.json"
def __init__(self):
super().__init__()
self.CARPETA.mkdir(exist_ok=True) # asegurar la carpeta
def _agregar(self):
# datetime: sellar cuándo se creó cada tarea
self._tareas.append({
"texto": self.entry.get(),
"hecha": False,
"creada": datetime.now().strftime("%d/%m/%Y %H:%M"),
})
self._guardar()| Módulo | En tu app sirve para |
|---|---|
datetime | timestamp de creación, fechas de vencimiento, "hace 3 días" |
pathlib | carpeta de datos del usuario (Path.home()), rutas portables |
random | datos de prueba, sorteos, orden aleatorio de un quiz |
⚠️ Guardar datos "junto al .py" falla cuando empaquetes la app (Fase 6, PyInstaller): el ejecutable vive en otro lado.
Path.home() / ".mi_app"es el patrón correcto desde ya.
🗄️ CON BASE DE DATOS (caso de uso)
Las fechas se guardan como texto ISO (YYYY-MM-DD HH:MM:SS) — SQLite las ordena y filtra correctamente en ese formato:
python
con.execute("INSERT INTO tareas (texto, creada) VALUES (?, ?)",
("Comprar pan", datetime.now().isoformat()))
# ¿Tareas de los últimos 7 días? La fecha ISO se compara como texto:
desde = (datetime.now() - timedelta(days=7)).isoformat()
filas = con.execute("SELECT * FROM tareas WHERE creada >= ?", (desde,)).fetchall()🏋️ EJERCICIOS CON SOLUCIÓN
Ejercicio 1 — ¿Cuántos días faltan?
Calcula cuántos días faltan de hoy al próximo 31 de diciembre.
Ver solución
python
from datetime import datetime
hoy = datetime.now()
fin = datetime(hoy.year, 12, 31)
print((fin - hoy).days) # p. ej. 173 (depende del día que lo corras)Ejercicio 2 — Carpeta de datos
Crea (si no existe) la carpeta ~/.mi_app y dentro un log.txt con la fecha-hora actual.
Ver solución
python
from pathlib import Path
from datetime import datetime
carpeta = Path.home() / ".mi_app"
carpeta.mkdir(exist_ok=True)
(carpeta / "log.txt").write_text(
datetime.now().strftime("%d/%m/%Y %H:%M"), encoding="utf-8")Ejercicio 3 — Quiz aleatorio
De preguntas = ["p1", "p2", "p3", "p4"], elige 2 al azar sin repetir y sin modificar la lista.
Ver solución
python
import random
preguntas = ["p1", "p2", "p3", "p4"]
elegidas = random.sample(preguntas, 2) # sample: sin repetición, no muta
print(elegidas, preguntas) # la original queda intacta❓ Preguntas y respuestas (autoevaluación)
1. ¿Cómo conviertes datetime → "11/07/2026" y al revés?
d.strftime("%d/%m/%Y")(a texto) ydatetime.strptime(texto, "%d/%m/%Y")(a fecha).
2. ¿Cómo sumas 7 días a una fecha?
fecha + timedelta(days=7).
3. ¿Qué hace Path.home() / ".mi_app" / "datos.json"?
Une rutas con
/de forma portable:~/.mi_app/datos.jsonen cualquier sistema operativo.
4. ¿random.shuffle vs random.sample?
shufflemezcla la lista en el sitio (muta);sample(lista, k)devuelvekelementos al azar sin repetir y sin tocar la original.
📎 Apuntes relacionados
- Dónde persisten estos datos → Clase 20 · JSON
- Mutar vs no mutar (shuffle/sample ≈ sort/sorted) → Clase 01
➡️ Siguiente
Clase 23 · requests y APIs — tu app sale a internet.