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 español 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 numpy
os
: 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_mesas
validar_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 += 1
Funciones 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.