Reglas de implementación para proyecto académico de SO usando Tkinter (nivel fácil)
Este skill contiene las reglas arquitectónicas y principios de desarrollo para el proyecto académico de Simulador de Sistemas Operativos usando Tkinter (nivel fácil).
Principio fundamental:
core/ NO DEBE importar Tkinter (lógica pura de SO)gui/ contiene solo presentaciónValidación: Si no puede ejecutarse python core/test_scheduler.py sin Tkinter, la regla se ha violado.
Orden obligatorio:
Prohibición crítica: NO diseñar la UI completa antes de tener la lógica funcional.
Métrica: Dedicar 50% del tiempo total a la Fase 1 (algoritmos en consola).
after()Obligatorio:
root.after(ms, callback) para actualizaciones periódicasProhibiciones absolutas:
time.sleep() en callbacks de Tkinter (bloquea toda la UI)while True en el hilo principalafter() recursivo)psutil.cpu_percent(interval=1.0) en callbacks directosPatrón correcto:
def update_dashboard(self):
# Actualizar widgets
cpu = psutil.cpu_percent(interval=0.1)
self.cpu_label.config(text=f"CPU: {cpu}%")
# Programar próxima actualización (recursivo)
self.after_id = self.after(1000, self.update_dashboard)
Requisitos:
open(), os.remove(), o cualquier operación real de discojson.dump() al cerrar la aplicaciónPeligro crítico: Tocar el FS real del sistema host puede causar pérdida de datos.
ProySistemasOperativos/
├── main.py # Punto de entrada
├── requirements.txt # Solo psutil==5.9.8
├── README.md
├── core/
│ ├── __init__.py
│ ├── process.py # Clase Process
│ ├── scheduler.py # Scheduler + FIFO/SJF/RoundRobin
│ ├── file_system.py # Directory y File simulados
│ ├── system_monitor.py # Funciones con psutil
│ ├── test_scheduler.py # Pruebas consola
│ ├── test_monitor.py # Pruebas monitoreo
│ └── test_file_system.py # Pruebas FS
└── gui/
├── __init__.py
└── app.py # Clase App(tk.Tk) - toda la interfaz
Notas:
monitor/ separada (simplicidad)controllers/ (un solo archivo app.py en nivel fácil)resources/ (no se usa Qt Designer)Clases requeridas:
Scheduler (clase base con interfaz común)FIFOScheduler → listas simples o queue.QueueSJFScheduler → sorted() por burst_timeRoundRobinScheduler → listas con quantum configurable (default=2.0)Interfaz obligatoria:
add_process(process: Process) -> None
run() -> List[Dict] # Timeline: [{"pid": 1, "start": 0, "end": 5, "state": "running"}, ...]
get_statistics() -> Dict # {"waiting_time_avg": ..., "turnaround_time_avg": ...}
Scripts de prueba mínimos:
core/test_scheduler.py → validar los 3 algoritmos en consolacore/test_monitor.py → imprimir CPU/RAM cada 2 segundoscore/test_file_system.py → probar crear/listar archivos y carpetasChecklist de hitos evaluables:
ttk.Notebook y 3 pestañas vacíasProgressbar actualizándose sin bloquear UICanvas funcionalVentana principal (tk.Tk):
Menu superior (tk.Menu):
Notebook con pestañas (ttk.Notebook):
Label + ttk.Progressbar para uso de CPULabel + ttk.Progressbar para uso de RAMttk.Treeview para mostrar particionesttk.Combobox para seleccionar algoritmo (FIFO, SJF, Round Robin)ttk.Entry para quantum (visible solo si Round Robin)ttk.Treeview para lista de procesos pendientesCanvas para timeline de Gantt (rectángulos coloreados por PID)Label para estadísticasttk.Treeview para estructura de directoriosError: Usar time.sleep() dentro de callbacks o while True en hilo principal
Solución: Siempre usar root.after(ms, callback) para actualizaciones periódicas
Error: Crear threading.Thread para monitoreo y actualizar widgets directamente
Solución: En nivel fácil, evitar threading. Usar after() con intervalos cortos (1000ms)
Error: Llamar after() sin condición de parada al cerrar ventana
Solución: En método de cierre, cancelar con after_cancel(id)
Error: Dibujar timeline con coordenadas fijas que se salen del Canvas
Solución: Calcular escala dinámica: pixels_por_segundo = ancho_canvas / duracion_total
Error: Escribir algoritmos de planificación dentro de métodos de la clase App
Solución: Mantener core/scheduler.py 100% independiente. App solo llama a scheduler.run() y muestra resultados
core/scheduler.pyttk.Notebook con 3 pestañas vacíasLabel que diga "CPU: 0%"psutil.cpu_percent() con after(1000, ...)Progressbar junto al Labelcreate_rectangle()Nunca intentar dibujar el timeline completo en el primer intento
Proyecto aprobatorio:
Proyecto reprobatorio:
Pasos obligatorios:
python --version (debe ser 3.11.x)python -m venv venvvenv\Scripts\activate (Windows)pip install -r requirements.txtgit initAdvertencia: Saltar esta configuración causa problemas de dependencias.
Primera llamada a psutil:
# Inicialización (hacer una vez al inicio)
psutil.cpu_percent(interval=0.1)
# Luego en actualizaciones:
cpu = psutil.cpu_percent(interval=None) # No bloquea
Patrón after recursivo:
def update(self):
# Actualizar widgets aquí
self.after_id = self.after(1000, self.update)
def on_close(self):
if hasattr(self, 'after_id'):
self.after_cancel(self.after_id)
self.destroy()
Timeline en Canvas:
# Escala dinámica
pixels_per_second = canvas_width / total_duration
# Dibujar proceso
x1 = start_time * pixels_per_second
x2 = end_time * pixels_per_second
canvas.create_rectangle(x1, y, x2, y+30, fill=color_by_pid[pid])
canvas.create_text((x1+x2)//2, y+15, text=f"P{pid}")
Este plan es realista para 8 semanas con 8-10 horas semanales. La simplicidad de Tkinter permite enfocarse en los conceptos de Sistemas Operativos sin perder tiempo en complejidades de frameworks GUI.
Prioriza corrección lógica sobre apariencia visual.