Desarrollo de un Sistema de Gestión de Restaurantes en Python
Enviado por Chuletator online y clasificado en Informática y Telecomunicaciones
Escrito el en
con un tamaño de 21,4 KB
Este documento detalla la implementación de un sistema básico de gestión para un restaurante, desarrollado en Python. El sistema permite a los usuarios interactuar con diversas funcionalidades, como la visualización del estado de las mesas, la realización de reservas, la gestión de pedidos de la carta y el procesamiento de pagos, incluyendo la aplicación de descuentos y el cálculo de impuestos. Se utilizan estructuras de datos simples y funciones para modularizar las diferentes funcionalidades, ofreciendo una solución práctica para la administración de un establecimiento.
Estructura del Código y Variables Globales
El programa inicia con la importación de las librerías necesarias y la definición de las estructuras de datos globales que almacenarán la información del restaurante y las reservas activas.
Importaciones y Configuración Inicial
Las siguientes librerías son esenciales para el funcionamiento del sistema:
import os
import time
import numpyos: Se utiliza para interactuar con el sistema operativo, permitiendo, por ejemplo, limpiar la consola (os.system('clear')) para una mejor experiencia de usuario.time: Proporciona funciones para pausar la ejecución del programa por un tiempo determinado (time.sleep()), lo que es útil para mostrar mensajes al usuario antes de continuar.numpy: Empleada para crear y manipular una matriz que representa el estado de las mesas del restaurante, facilitando la gestión de su disponibilidad.
Representación del Restaurante y Listas de Datos
La disposición de las mesas se modela eficientemente con una matriz de NumPy, y la información de las reservas se gestiona mediante listas paralelas para mantener la coherencia de los datos.
restaurant = numpy.zeros((3, 3), int)Esta línea inicializa una matriz de 3x3 con valores enteros. Cada celda de la matriz representa una mesa: un valor de 0 indica que la mesa está disponible, mientras que 1 significa que está reservada.
Listas para la Gestión de Reservas
Se utilizan las siguientes listas globales para almacenar de forma organizada la información detallada de cada reserva:
lista_ruts: Almacena los R.U.T. (Rol Único Tributario) de los clientes que han realizado una reserva.lista_nombres: Guarda los nombres completos de los clientes.lista_correos: Contiene las direcciones de correo electrónico de los clientes.lista_filas: Registra el índice de la fila de la mesa que ha sido reservada.lista_columnas: Registra el índice de la columna de la mesa que ha sido reservada.lista_totales: Almacena el total acumulado de los pedidos realizados para cada reserva, inicializado en 0.
lista_ruts = []
lista_nombres = []
lista_correos = []
lista_filas = []
lista_columnas = []
lista_totales = []Funciones Principales del Sistema
El sistema se estructura en torno a un conjunto de funciones que manejan la interacción con el usuario, la validación de entradas y la lógica de negocio del restaurante.
mostrar_menu(): Presentación del Menú Principal
Esta función es responsable de limpiar la consola y mostrar las opciones principales disponibles para el usuario, facilitando la navegación por el sistema.
def mostrar_menu():
os.system('clear')
print("""MENÚ PRINCIPAL
1. Ver restaurante
2. Reservar
3. Ver carta
4. Pagar
5. Cancelar reserva
6. Salir""")validar_opcion(): Validación de la Entrada del Menú Principal
Asegura que el usuario ingrese una opción numérica válida y dentro del rango permitido para el menú principal, manejando posibles errores de entrada.
def validar_opcion():
while True:
try:
opc = int(input("Ingrese opción: "))
if opc in (1, 2, 3, 4, 5, 6):
return opc
else:
print("Error: Opción incorrecta. Por favor, ingrese un número entre 1 y 6.")
except ValueError:
print("Error: Debe ingresar un número entero.")ver_restaurant(): Visualización del Estado de las Mesas
Esta función limpia la consola y presenta visualmente el estado actual de las mesas del restaurante. Indica la capacidad de cada fila de mesas y si cada mesa individual está disponible (0) o reservada (1).
def ver_restaurant():
os.system('clear')
print("\tVER RESTAURANTE\n")
contador = 1
for x in range(3):
print(f"Mesas para {(x+1)*2} personas: ", end=" ")
for y in range(3):
print(f"Mesa {contador}: {restaurant[x][y]} ", end=" ")
contador += 1
print("\n")
time.sleep(3)Funciones de Validación de Datos del Cliente
Estas funciones son cruciales para solicitar y validar la información personal del cliente durante el proceso de reserva, garantizando la integridad de los datos.
validar_rut(): Validación del R.U.T.
Solicita el R.U.T. del cliente y verifica que sea un número entero dentro de un rango válido, sin puntos ni dígito verificador.
def validar_rut():
while True:
try:
rut = int(input("Ingrese RUT (sin puntos ni dígito verificador): "))
if 1000000 <= rut <= 99999999:
return rut
else:
print("Error: El RUT debe estar entre 1.000.000 y 99.999.999.")
except ValueError:
print("Error: Debe ingresar un número entero.")validar_nombre(): Validación del Nombre del Cliente
Pide el nombre del cliente y comprueba que tenga al menos 3 letras. Se permite el uso de espacios, pero la validación de caracteres alfabéticos se realiza sobre el nombre sin espacios.
def validar_nombre():
while True:
nombre = input("Ingrese nombre: ")
if len(nombre.strip()) >= 3 and nombre.replace(' ', '').isalpha():
return nombre
else:
print("Error: El nombre debe tener al menos 3 letras y contener solo caracteres alfabéticos (se permiten espacios).")validar_correo(): Validación del Correo Electrónico
Solicita la dirección de correo electrónico y verifica que contenga el símbolo '@', un requisito básico para un formato de correo válido.
def validar_correo():
while True:
correo = input("Ingrese correo: ")
if "@" in correo:
return correo
else:
print("Error: Correo electrónico incorrecto. Debe contener '@'.")validar_cantidad(): Validación de la Cantidad de Personas
Asegura que la cantidad de personas para la reserva esté dentro del rango de 1 a 6, acorde a las capacidades de las mesas.
def validar_cantidad():
while True:
try:
cantidad = int(input("Ingrese cantidad de personas (1-6): "))
if 1 <= cantidad <= 6:
return cantidad
else:
print("Error: La cantidad de personas debe estar entre 1 y 6.")
except ValueError:
print("Error: Debe ingresar un número entero.")mesas_disponibles(p_cantidad): Búsqueda de Mesas Adecuadas
Esta función identifica y retorna una lista de mesas disponibles que son adecuadas para la cantidad de personas especificada. La lógica de asignación de mesas es la siguiente:
- Grupos de 1-2 personas pueden ocupar cualquier mesa disponible (de 2, 4 o 6 personas).
- Grupos de 3-4 personas pueden ocupar mesas disponibles en las filas 1 o 2 (mesas de 4 o 6 personas).
- Grupos de 5-6 personas solo pueden ocupar mesas disponibles en la fila 2 (mesas de 6 personas).
def mesas_disponibles(p_cantidad):
contador = 1
lista_mesas = []
for x in range(3): # Itera sobre las filas (0, 1, 2)
for y in range(3): # Itera sobre las columnas (0, 1, 2)
if restaurant[x][y] == 0: # Si la mesa está disponible
if p_cantidad <= 2: # Para 1 o 2 personas, cualquier mesa disponible es válida
lista_mesas.append(contador)
elif 3 <= p_cantidad <= 4 and x in (1, 2): # Para 3 o 4 personas, mesas de la fila 1 o 2
lista_mesas.append(contador)
elif 5 <= p_cantidad <= 6 and x == 2: # Para 5 o 6 personas, solo mesas de la fila 2
lista_mesas.append(contador)
contador += 1
return lista_mesasvalidar_mesa(p_mesas): Validación de la Selección de Mesa
Asegura que el usuario seleccione un número de mesa válido de la lista de mesas previamente identificadas como disponibles.
def validar_mesa(p_mesas):
while True:
try:
mesa = int(input("Ingrese número de mesa: "))
if mesa in p_mesas:
return mesa
else:
print("Error: Número de mesa no disponible o inválido. Por favor, elija una de las opciones mostradas.")
except ValueError:
print("Error: Debe ingresar un número entero.")reservar(): Proceso de Reserva de Mesa
Esta función coordina todo el proceso de reserva, desde la recopilación y validación de los datos del cliente hasta la asignación final de una mesa y el registro de la reserva en las listas globales.
def reservar():
os.system('clear')
print("RESERVAR MESA\n")
rut = validar_rut()
if rut in lista_ruts:
print("Advertencia: Ya existe una reserva activa para el RUT indicado.")
time.sleep(3)
return
nombre = validar_nombre()
correo = validar_correo()
ver_restaurant()
cant_personas = validar_cantidad()
lista_mesas = mesas_disponibles(cant_personas)
if len(lista_mesas) == 0:
print("Información: No existen mesas disponibles para la cantidad de personas solicitada en este momento.")
time.sleep(3)
return
print("Mesas disponibles:", lista_mesas)
mesa = validar_mesa(lista_mesas)
contador = 1
for x in range(3):
for y in range(3):
if contador == mesa:
restaurant[x][y] = 1 # Marca la mesa como reservada en la matriz
lista_ruts.append(rut)
lista_nombres.append(nombre)
lista_correos.append(correo)
lista_filas.append(x)
lista_columnas.append(y)
lista_totales.append(0) # Inicializa el total de la cuenta para esta reserva en 0
print("Mesa reservada con éxito.")
time.sleep(3)
return # Sale de la función después de completar la reserva
contador += 1Funciones para la Gestión de la Carta y Pedidos
Estas funciones permiten a los clientes con reserva explorar la carta del restaurante, seleccionar productos y acumular el total de su pedido.
validar_opcion_menu(): Validación de Opciones del Menú de Carta
Similar a la función validar_opcion(), pero adaptada para las opciones específicas del menú de la carta (categorías de productos y acciones de pedido/cancelación).
def validar_opcion_menu():
while True:
try:
opc = int(input("Ingrese opción: "))
if opc in (1, 2, 3, 4, 5):
return opc
else:
print("Error: Opción incorrecta. Por favor, ingrese un número entre 1 y 5.")
except ValueError:
print("Error: Debe ingresar un número entero.")validar_opciones_carta(): Validación de Opciones de Productos
Valida la selección de un producto específico dentro de una categoría de la carta (bebestibles, platos de fondo, postres), asegurando que la opción sea numérica y esté dentro del rango permitido.
def validar_opciones_carta():
while True:
try:
opc = int(input("Ingrese opción: "))
if opc in (1, 2, 3):
return opc
else:
print("Error: Opción incorrecta. Por favor, ingrese un número entre 1 y 3.")
except ValueError:
print("Error: Debe ingresar un número entero.")validar_cantidad_prod(): Validación de la Cantidad de Productos
Asegura que la cantidad de productos a pedir sea un número entero no negativo, evitando entradas inválidas.
def validar_cantidad_prod():
while True:
try:
cantidad = int(input("Ingrese cantidad: "))
if cantidad >= 0:
return cantidad
else:
print("Error: La cantidad debe ser 0 o un valor positivo.")
except ValueError:
print("Error: Debe ingresar un número entero.")ver_carta(): Interfaz para Realizar Pedidos
Esta función permite a un cliente con una reserva activa ver la carta del restaurante, seleccionar productos de diferentes categorías (bebestibles, platos de fondo, postres) y acumular el total de su pedido. El cliente puede añadir múltiples productos antes de confirmar o cancelar el pedido.
def ver_carta():
os.system('clear')
rut = validar_rut()
if rut not in lista_ruts:
print("Información: No existe reserva para el RUT indicado. Por favor, realice una reserva primero.")
time.sleep(3)
return
posicion = lista_ruts.index(rut)
acumulador = 0
while True:
os.system('clear')
print("""CARTA DEL RESTAURANTE
1. BEBESTIBLES
2. PLATOS DE FONDO
3. POSTRES
4. PEDIR
5. CANCELAR""")
opcion = validar_opcion_menu()
if opcion == 1:
print("""\nBEBESTIBLES
1. Limonada $2.500
2. Bebida $1.500
3. Jugo $2.000""")
opcion_bebestible = validar_opciones_carta()
cantidad = validar_cantidad_prod()
if opcion_bebestible == 1:
acumulador += 2500 * cantidad
elif opcion_bebestible == 2:
acumulador += 1500 * cantidad
else:
acumulador += 2000 * cantidad
elif opcion == 2:
print("""\nPLATOS DE FONDO
1. Consomé $3.000
2. Pollo con Papas Fritas $4.500
3. Ensalada $2.000""")
opcion_plato = validar_opciones_carta()
cantidad = validar_cantidad_prod()
if opcion_plato == 1:
acumulador += 3000 * cantidad
elif opcion_plato == 2:
acumulador += 4500 * cantidad
else:
acumulador += 2000 * cantidad
elif opcion == 3:
print("""\nPOSTRES
1. Helado $2.000
2. Tiramisú $2.500
3. Jalea $1.000""")
opcion_postre = validar_opciones_carta()
cantidad = validar_cantidad_prod()
if opcion_postre == 1:
acumulador += 2000 * cantidad
elif opcion_postre == 2:
acumulador += 2500 * cantidad
else:
acumulador += 1000 * cantidad
elif opcion == 4:
lista_totales[posicion] += acumulador
print("Pedido realizado con éxito. El total se ha añadido a su cuenta.")
break
else:
print("Pedido cancelado de la carta. No se han añadido productos a su cuenta.")
break
time.sleep(3)Funciones de Pago y Cancelación de Reservas
Estas funciones gestionan el cierre de la cuenta del cliente y la liberación de las mesas, completando el ciclo de vida de una reserva.
validar_descuento(): Validación del Descuento
Solicita un valor de descuento a aplicar y asegura que sea un número entero no negativo, evitando entradas erróneas.
def validar_descuento():
while True:
try:
desc = int(input("Ingrese descuento (valor entero): "))
if desc >= 0:
return desc
else:
print("Error: El descuento debe ser 0 o un valor positivo.")
except ValueError:
print("Error: Debe ingresar un número entero.")pagar(): Procesamiento del Pago de la Cuenta
Permite a un cliente con reserva pagar su cuenta. La función calcula el subtotal, el IVA, el total antes del descuento y el total final, presentando una boleta detallada. Posteriormente, libera la mesa y elimina todos los datos asociados a la reserva.
def pagar():
os.system('clear')
print("PAGAR CUENTA\n")
rut = validar_rut()
if rut in lista_ruts:
posicion = lista_ruts.index(rut)
descuento = validar_descuento()
subtotal = lista_totales[posicion]
iva = round(0.19 * subtotal)
total_sin_descuento = round(1.19 * subtotal)
total_final = total_sin_descuento - descuento
print(f"""BOLETA
-----------------------------------
SUBTOTAL: ${subtotal:,.0f}
IVA (19%): ${iva:,.0f}
TOTAL: ${total_sin_descuento:,.0f}
DESCUENTO: ${descuento:,.0f}
-----------------------------------
TOTAL FINAL: ${total_final:,.0f}""")
fila = lista_filas[posicion]
columna = lista_columnas[posicion]
restaurant[fila][columna] = 0 # Libera la mesa en la matriz
# Elimina la reserva de todas las listas paralelas
lista_ruts.pop(posicion)
lista_nombres.pop(posicion)
lista_correos.pop(posicion)
lista_filas.pop(posicion)
lista_columnas.pop(posicion)
lista_totales.pop(posicion)
print("\nPago realizado con éxito. ¡Gracias por su visita!")
else:
print("Información: El RUT indicado no tiene reserva activa para procesar el pago.")
time.sleep(5)cancelar_reserva(): Anulación de una Reserva Existente
Permite a un cliente cancelar su reserva. La función libera la mesa correspondiente en la matriz del restaurante y elimina todos los datos asociados a la reserva de las listas globales.
def cancelar_reserva():
os.system('clear')
print("CANCELAR RESERVA\n")
rut = validar_rut()
if rut in lista_ruts:
posicion = lista_ruts.index(rut)
fila = lista_filas[posicion]
columna = lista_columnas[posicion]
restaurant[fila][columna] = 0 # Libera la mesa en la matriz
# Elimina la reserva de todas las listas paralelas
lista_ruts.pop(posicion)
lista_nombres.pop(posicion)
lista_correos.pop(posicion)
lista_filas.pop(posicion)
lista_columnas.pop(posicion)
lista_totales.pop(posicion)
print("\nReserva cancelada con éxito.")
else:
print("Información: El RUT indicado no tiene reserva activa para cancelar.")
time.sleep(5)Consideraciones Adicionales y Mejoras Potenciales
Este sistema proporciona una base sólida para la gestión de un restaurante. Para futuras mejoras y una mayor robustez, se podrían considerar las siguientes extensiones:
- Persistencia de Datos: Implementar mecanismos para guardar y cargar los datos de reservas y el estado de las mesas en archivos (por ejemplo, CSV, JSON) o una base de datos, para que la información no se pierda al cerrar el programa.
- Interfaz Gráfica de Usuario (GUI): Desarrollar una interfaz más intuitiva y amigable utilizando librerías como Tkinter, PyQt o Kivy, mejorando significativamente la experiencia del usuario.
- Gestión de Errores Mejorada: Implementar un manejo de excepciones más granular y específico, proporcionando mensajes de error más descriptivos y acciones de recuperación.
- Optimización de Búsquedas: Para escenarios con un gran volumen de datos, considerar el uso de estructuras de datos más eficientes que las listas paralelas (como diccionarios o clases de objetos) para mejorar el rendimiento de las búsquedas y manipulaciones.
- Detalle de Pedidos: Almacenar los detalles específicos de cada pedido (qué productos y en qué cantidad) en lugar de solo el total acumulado, lo que permitiría generar facturas más detalladas.
- Autenticación de Usuarios: Añadir un sistema de autenticación para el personal del restaurante, con diferentes niveles de acceso según el rol (e.g., mesero, administrador).
- Validación de RUT Completa: Implementar la validación del dígito verificador del RUT para una verificación más exhaustiva de la identidad del cliente.