You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Proyecto I] Centro de Investigación Científica #322
Aplicación desarrollada en Python con interfaz gráfica (Tkinter) para gestionar experimentos científicos en un laboratorio ficticio. Permite registrar científicos, planificar experimentos, asignar recursos y aplicar restricciones de seguridad y acceso automáticamente. Los datos persisten entre sesiones mediante archivos JSON.
Construiste un planificador de experimentos de laboratorio con interfaz gráfica en Tkinter: registro y login de científicos, creación de experimentos con selección de recursos, y un motor de restricciones de seguridad que valida automáticamente nivel de acceso, exclusiones entre equipos, co-requisitos de materiales radioactivos y el horario de apertura del centro. Lo más valioso: cuando hay un conflicto de horario, el sistema busca y sugiere fechas alternativas. Y todo persiste en JSON entre sesiones.
Ejecución
Compilé los 10 módulos (todos sin errores de sintaxis) y ejecuté directamente la lógica de negocio con tus datos reales, probando más de una docena de escenarios válidos e inválidos. La GUI no arrancó en mi entorno Linux por una sola línea: self.state("zoomed") (gui.py:36) usa un estado de ventana que solo existe en Windows — en tu máquina arranca perfectamente, no es un bug de tu lógica. Cambiando esa línea por self.geometry(...), la ventana y todos los widgets se construyen bien. Por eso el foco de la revisión fue tu motor de restricciones, que es donde está la sustancia.
Lo que está bien
Arquitectura ejemplar para primer año. Separaste la lógica de negocio (Planner, tus clases Cientifico/Recurso/Experimento, y los sistema_*) de la GUI de forma tan limpia que pude ejecutar y verificar todo el núcleo sin abrir la ventana. Eso es exactamente lo que hace testeable un programa.
Todas las restricciones funcionan verificadas en ejecución real: nivel insuficiente → rechazado; láser + vibración → rechazado; radioactivos sin sala blindada/dosímetro → rechazado (y con ambos → aceptado); domingo → rechazado; fuera de horario → rechazado; conflicto de recurso+horario → rechazado. Todas con su mensaje correcto.
Persistencia bien pensada. Guardas el email del científico y los IDs de recursos en lugar de duplicar objetos, y al cargar resuelves las referencias. Es el patrón correcto (como claves foráneas) y evita datos inconsistentes.
Búsqueda de huecos correcta. Verifiqué que buscar_varios_huecos devuelve fechas válidas respetando horario y conflictos (ej. desde un recurso ocupado a las 09:00 me ofreció 11:00 / 11:30 / 12:00).
Código limpio y legible, con comentarios que explican el porqué. Por encima de la media del curso.
Qué mejorar
Bug de caso límite: experimentos que cruzan la medianoche. Un experimento que empieza lunes 18:00 y dura 10h (termina martes 04:00) tu sistema lo acepta, aunque corre toda la noche con el centro cerrado. La causa está en planner.py:68: comparas fin.time() > time(hora_cierre), pero cuando el fin pasa de medianoche, fin.time() es 04:00, que es menor que 20:00, así que la validación no lo pilla. Solución: compara el datetime completo del fin contra la hora de cierre del día de inicio (o rechaza si fin.date() != inicio.date()). Fíjate que tu se_solapa_con sí usa datetime completos — es solo el chequeo de horario el que se quedó mirando solo la hora.
IDs de experimento no estables al recargar. Asignas el id en el constructor desde un contador de clase (experimento.py:13), así que cada vez que se re-instancian los experimentos el contador sube y los IDs cambian. En tu GUI no molesta porque cargas los datos una sola vez al arrancar, pero es frágil: ya guardas el id en el JSON (sistema_experimentos.py:69), así que sería más robusto leerlo al cargar en vez de regenerarlo.
Detalle defensivo: tu constructor de Cientifico avisa si el nivel no es 1/2/3 pero no lo rechaza; y textos_nivel[nivel] (gui.py:436) daría IndexError con un nivel fuera de rango. En la práctica estás a salvo porque el nivel siempre viene de los radio buttons, pero conviene tenerlo presente.
Sobre el informe
El informe es honesto y preciso — describe exactamente lo que hace el código, sin inventar features. La afirmación de que comparas el objeto time completo para no aceptar un experimento que termina a las 20:30 es cierta para el caso normal (lo confirmé); solo se le escapó el caso del cruce de medianoche que menciono arriba. El único pero es formal: tiene 878 palabras y la asignatura pide un mínimo de 2000. Te recomiendo ampliarlo — tienes material de sobra (podrías desarrollar decisiones de diseño, el patrón de persistencia por referencias, y ejemplos concretos de cada restricción).
Muy buen trabajo, Sabrina. El diseño que lograste es el tipo de estructura que hace que un programa sea fácil de mantener y probar. Corrige el caso de medianoche y amplía el informe, y queda redondo. 👏
Activity
[-]Centro de Investigación Científica[/-][+][Proyecto I] Centro de Investigación Científica[/+]apiad commentedon Jul 6, 2026
🔧 Título corregido al formato
[Proyecto I]para disparar la verificación automática./revisar
github-actions commentedon Jul 6, 2026
Verificación Automática — Proyecto I 🤖
Repositorio analizado:
https://github.com/SabrinaSocarras/centro-investigacion-planner1. Repositorio
✅ El repositorio es accesible y fue clonado correctamente.
2. Informe (
report.md)src/report.mdencontrado pero con solo 878 palabras (mínimo: 2,000).3. Proyecto Python
pyproject.toml.requirements.txt.Archivos Python (10, 1,481 líneas en total):
src/cientifico.pysrc/sistema_cientifico.pysrc/run_app.pysrc/experimento.pysrc/sistema_recursos.pysrc/planner.pysrc/recursos_iniciales.pysrc/recurso.pysrc/gui.pysrc/sistema_experimentos.py4. Punto de Entrada
main.py,app.py, etc.).5. Ejecución
Resumen
2/6 verificaciones pasadas.
Verificación automática — los resultados son orientativos. El profesor revisará en detalle.
apiad commentedon Jul 15, 2026
🔍 Revisión de Código — Claude Code
Qué hace tu proyecto
Construiste un planificador de experimentos de laboratorio con interfaz gráfica en Tkinter: registro y login de científicos, creación de experimentos con selección de recursos, y un motor de restricciones de seguridad que valida automáticamente nivel de acceso, exclusiones entre equipos, co-requisitos de materiales radioactivos y el horario de apertura del centro. Lo más valioso: cuando hay un conflicto de horario, el sistema busca y sugiere fechas alternativas. Y todo persiste en JSON entre sesiones.
Ejecución
Compilé los 10 módulos (todos sin errores de sintaxis) y ejecuté directamente la lógica de negocio con tus datos reales, probando más de una docena de escenarios válidos e inválidos. La GUI no arrancó en mi entorno Linux por una sola línea:
self.state("zoomed")(gui.py:36) usa un estado de ventana que solo existe en Windows — en tu máquina arranca perfectamente, no es un bug de tu lógica. Cambiando esa línea porself.geometry(...), la ventana y todos los widgets se construyen bien. Por eso el foco de la revisión fue tu motor de restricciones, que es donde está la sustancia.Lo que está bien
Planner, tus clasesCientifico/Recurso/Experimento, y lossistema_*) de la GUI de forma tan limpia que pude ejecutar y verificar todo el núcleo sin abrir la ventana. Eso es exactamente lo que hace testeable un programa.buscar_varios_huecosdevuelve fechas válidas respetando horario y conflictos (ej. desde un recurso ocupado a las 09:00 me ofreció 11:00 / 11:30 / 12:00).Qué mejorar
planner.py:68: comparasfin.time() > time(hora_cierre), pero cuando el fin pasa de medianoche,fin.time()es 04:00, que es menor que 20:00, así que la validación no lo pilla. Solución: compara eldatetimecompleto del fin contra la hora de cierre del día de inicio (o rechaza sifin.date() != inicio.date()). Fíjate que tuse_solapa_consí usadatetimecompletos — es solo el chequeo de horario el que se quedó mirando solo la hora.iden el constructor desde un contador de clase (experimento.py:13), así que cada vez que se re-instancian los experimentos el contador sube y los IDs cambian. En tu GUI no molesta porque cargas los datos una sola vez al arrancar, pero es frágil: ya guardas eliden el JSON (sistema_experimentos.py:69), así que sería más robusto leerlo al cargar en vez de regenerarlo.Cientificoavisa si el nivel no es 1/2/3 pero no lo rechaza; ytextos_nivel[nivel](gui.py:436) daríaIndexErrorcon un nivel fuera de rango. En la práctica estás a salvo porque el nivel siempre viene de los radio buttons, pero conviene tenerlo presente.Sobre el informe
El informe es honesto y preciso — describe exactamente lo que hace el código, sin inventar features. La afirmación de que comparas el objeto
timecompleto para no aceptar un experimento que termina a las 20:30 es cierta para el caso normal (lo confirmé); solo se le escapó el caso del cruce de medianoche que menciono arriba. El único pero es formal: tiene 878 palabras y la asignatura pide un mínimo de 2000. Te recomiendo ampliarlo — tienes material de sobra (podrías desarrollar decisiones de diseño, el patrón de persistencia por referencias, y ejemplos concretos de cada restricción).Muy buen trabajo, Sabrina. El diseño que lograste es el tipo de estructura que hace que un programa sea fácil de mantener y probar. Corrige el caso de medianoche y amplía el informe, y queda redondo. 👏