Skip to content

Liibbeerr/Universidad

Repository files navigation

Mi proyecto es una aplicación web hecha con Streamlit que sirve para gestionar reservas en un salón de juegos. El local tiene tres áreas principales: juegos de mesa, consolas y computadoras, y cada una tiene sus propias reglas y recursos. El programa permite a los usuarios registrarse en una reserva eligiendo el tipo de actividad, la fecha, la hora de inicio y fin, y los recursos concretos que quieren usar, como una mesa de dominó, una PlayStation 5 o una computadora de alta gama.

La aplicación no solo guarda la reserva en un archivo JSON, sino que también valida todo antes de confirmar. Por ejemplo, comprueba que el horario esté dentro del rango permitido (de 10 de la mañana a 6 de la tarde), que la duración sea de al menos una hora, que no haya conflictos con otras reservas para el mismo recurso, y que se cumplan las reglas específicas de cada juego, como que el Dungeons & Dragons necesita al menos tres jugadores y un máster concreto, o que los juegos exclusivos de PlayStation no se puedan reservar para una Xbox. También se encarga de que la cantidad de personas no exceda la capacidad de la mesa o el sofá, y que cada persona tenga su propio mando o computadora.

Además de reservar, el programa ofrece un calendario donde se ven todas las reservas guardadas en una tabla, y desde allí se pueden eliminar reservas previa autenticación con la contraseña del usuario y una contraseña maestra del local (1234). En la página de inicio hay una breve explicación de cómo funciona todo y el horario del local.

2. Diseño y decisiones tomadas

Cuando empecé el proyecto, sabía que quería algo modular porque un solo archivo con todo el código se habría vuelto un caos. Por eso dividí el programa en varios módulos: uno para el menú principal, otro para la lógica de reservas, otro para las validaciones, otro para la interfaz de cada tipo de recurso y otro para el calendario. También separé el archivo de eliminación de reservas, aunque al final lo integré en el calendario para que fuera más intuitivo.

Para las validaciones, mi enfoque fue centralizarlas en un archivo llamado Validaciones.py, y dentro de él tener funciones específicas para cada tipo de recurso. Esto me permite modificar las reglas de un tipo sin romper las de los otros. Por ejemplo, en la validación de juegos de mesa tengo condiciones especiales para el D&D, el ajedrez y el dominó, mientras que para consolas valido los exclusivos y la cantidad de mandos.

Una decisión que tomé desde el principio fue pedir siempre la contraseña del usuario y una contraseña del local para eliminar reservas. La contraseña del local la dejé fija como "1234" para pruebas, pero en un entorno real se podría cambiar. Esto da un doble nivel de seguridad, porque evita que cualquiera borre reservas ajenas sin más.

También diseñé las funciones de selección de recursos (Juegos_mesa, Consolas, Computadora) para que devolvieran un diccionario con los datos elegidos, y así la función principal de reservas solo tuviera que recoger ese diccionario y añadirlo al resto de la información. Esto simplifica mucho el código y hace que sea más fácil añadir nuevas categorías en el futuro.

3. Aprendizajes durante el desarrollo

Este proyecto me ha enseñado muchísimo sobre la importancia de validar los datos en varios niveles. Al principio solo comprobaba que los campos no estuvieran vacíos, pero luego me di cuenta de que había que verificar también los conflictos de horarios, las capacidades de las mesas y la compatibilidad entre juegos y hardware. Por ejemplo, me costó bastante implementar la comprobación de que dos reservas no ocupen el mismo recurso a la misma hora, porque tenía que comparar intervalos de tiempo y no solo horas exactas. Al final lo resolví convirtiendo las horas a segundos y usando condiciones que detectaran solapamientos.

Otro aprendizaje importante fue el manejo de excepciones al leer el archivo JSON. Al principio el programa fallaba si el archivo no existía, y tuve que poner try/except para que creara una lista vacía y no se rompiera. Esto me hizo entender que siempre hay que prever que los archivos externos puedan faltar o estar corruptos.

También aprendí a organizar el código en módulos y a usar importaciones relativas, algo que al principio me liaba un poco porque no sabía bien cómo referenciar funciones de otros archivos. Pero una vez que lo entendí, me resultó mucho más ordenado y fácil de depurar.

La experiencia con Streamlit ha sido positiva, aunque tiene sus limitaciones. Por ejemplo, el estado de la aplicación se reinicia con cada interacción, y tuve que usar session_state para mantener las reservas entre recargas. También descubrí que los formularios son la mejor manera de manejar entradas múltiples sin que se disparen validaciones antes de tiempo.

Otro aspecto que he mejorado es la gestión de errores con mensajes claros para el usuario. Antes solo ponía un warning genérico, pero luego fui añadiendo mensajes específicos que indican exactamente qué está mal, como "La mesa de ajedrez solo admite 2 personas" o "No puedes jugar Halo Infinite en PlayStation". Esto hace que la experiencia de usuario sea mucho más amigable.

4. Cómo se usa el programa

Para usar el programa, primero hay que instalar las dependencias con pip install streamlit pandas. Luego se ejecuta el archivo app.py con streamlit run app.py, y se abre una página en el navegador local.

En la barra lateral hay un menú con tres opciones: Inicio, Reservar y Calendario. Al entrar en Inicio, se muestra una explicación general del sistema y el horario. En Reservar, se despliega un formulario donde el usuario debe introducir su nombre, una contraseña, la fecha, la hora de inicio y fin, y el número de personas. Luego debe elegir una de las tres categorías (juegos de mesa, consolas o computadoras), y dependiendo de cuál elija, aparecerán los selectores correspondientes. Por ejemplo, si elige juegos de mesa, tendrá que escoger el juego, la mesa y si quiere instructor. Si elige consolas, deberá seleccionar la consola, los juegos (puede elegir varios), el tipo de asiento y la cantidad de mandos. Si elige computadoras, seleccionará las máquinas que quiere reservar y los juegos que va a instalar.

Una vez relleno todo, al pulsar el botón de reservar se ejecutan todas las validaciones. Si todo es correcto, se guarda la reserva en el archivo JSON y se muestra un mensaje de éxito. Si hay algún problema, se muestra un mensaje de advertencia o error y la reserva no se guarda.

En la página de Calendario, se muestra una tabla con todas las reservas existentes, con columnas como nombre, fecha, hora, recursos, etc. Debajo de la tabla hay un pequeño formulario para eliminar una reserva, donde se pide el nombre del titular, su contraseña y la contraseña del local. Si los datos coinciden, se borra la reserva y se actualiza la tabla.

5. Dificultades y soluciones

La mayor dificultad fue sin duda la validación de conflictos de horarios entre reservas. Al principio comparaba solo las horas de inicio, pero eso no bastaba porque dos reservas podían solaparse aunque empezaran a horas diferentes. Tuve que implementar una lógica que comprobara si el intervalo [hora_inicio, hora_fin] de la nueva reserva se superponía con el de alguna existente para el mismo recurso. Lo resolví convirtiendo las horas a segundos y usando condiciones del tipo: si la hora de inicio de la nueva reserva es menor que la hora de fin de la existente y la hora de fin de la nueva es mayor que la hora de inicio de la existente, entonces hay conflicto. Pero además, para simplificar, en mi código comparo si la reserva existente cubre completamente el horario solicitado, porque en mi modelo no permito reservas parciales.

Otra dificultad fue la actualización de la tabla del calendario después de eliminar una reserva. Al principio, la tabla no se refrescaba automáticamente, pero luego me di cuenta de que al recargar la página, Streamlit volvía a leer el archivo JSON, así que simplemente forzaba la recarga con st.experimental_rerun() después de eliminar. Aunque no es la solución más elegante, funciona.

También me costó un poco manejar los tipos de fecha y hora. El date_input de Streamlit devuelve un objeto date de Python, pero al guardarlo en JSON lo convierto a string. Luego, al leerlo, lo comparo como string, y eso me ha funcionado bien porque el formato es consistente. Sin embargo, para las horas hice algo similar: las guardo como string con formato HH:MM:SS, y las convierto a segundos para las comparaciones. Esto evita problemas de zona horaria y simplifica el código.

Conclusión

Desarrollar este sistema de reservas ha sido una experiencia muy enriquecedora. He aplicado conceptos de programación modular, manejo de archivos, validación de datos, y diseño de interfaces con Streamlit. También he aprendido a pensar en el usuario final, proporcionando mensajes claros y un flujo de trabajo intuitivo. Aunque el programa es sencillo, cubre todas las funcionalidades básicas que se esperan de un gestor de reservas y está preparado para ser extendido con nuevas características en el futuro. Sin duda, este proyecto me ha ayudado a consolidar mis conocimientos y a ganar confianza en el desarrollo de aplicaciones web con Python.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors