Este es el primero de una serie de ejemplos. Comenzamos con un escenario sencillo que consolida los conceptos básicos antes de avanzar hacia proyectos más complejos en temas posteriores.
Necesitamos un simulador pequeño para una sucursal que atiende clientes en orden de llegada. La cola debe registrar el número de ticket y un nombre breve. El objetivo es permitir tres operaciones desde consola:
Este ejemplo se centra en una cola circular de tamaño fijo implementada en Python, ideal para comenzar porque garantiza O(1) y evita gestiones manuales de memoria.
La estructura circular reutiliza casilleros liberados y mantiene el orden de llegada de cada ticket.
Usaremos una lista con capacidad fija y un índice circular para apuntar al frente y al final, además de un contador para detectar estados vacío/lleno.
CAP_TURNOS = 16
MAX_NOMBRE = 32
class Cliente:
def __init__(self, ticket=0, nombre=""):
self.ticket = ticket
self.nombre = nombre
class ColaTurnos:
def __init__(self, capacidad=CAP_TURNOS):
self.capacidad = capacidad
self.datos = [None] * capacidad
self.frente = 0
self.final = 0
self.cantidad = 0
self.siguiente_ticket = 1
Los métodos agregar_cliente, llamar_cliente y mostrar_cola encapsulan el flujo. Cada uno valida estados para informar éxito o error (cola llena/vacía).
class ColaTurnos:
...
def agregar_cliente(self, nombre):
if self.cantidad == self.capacidad:
return 0
slot = Cliente(self.siguiente_ticket, nombre[:MAX_NOMBRE])
self.datos[self.final] = slot
self.siguiente_ticket += 1
self.final = (self.final + 1) % self.capacidad
self.cantidad += 1
return slot.ticket
def llamar_cliente(self):
if self.cantidad == 0:
return None
cliente = self.datos[self.frente]
self.frente = (self.frente + 1) % self.capacidad
self.cantidad -= 1
return cliente
def mostrar_cola(self):
print(f"Turnos pendientes ({self.cantidad}):")
idx = self.frente
for _ in range(self.cantidad):
slot = self.datos[idx]
print(f" #{slot.ticket} - {slot.nombre}")
idx = (idx + 1) % self.capacidad
El programa principal muestra un pequeño menú y ejecuta las operaciones según la entrada del usuario. Las entradas se validan para evitar desbordes.
def main():
cola = ColaTurnos()
while True:
print("\n1) Agregar cliente")
print("2) Llamar siguiente")
print("3) Mostrar cola")
print("0) Salir")
opcion = input("Opcion: ")
opcion = opcion.strip()
if opcion == "1":
nombre = input("Nombre: ")
nombre = nombre.strip()
ticket = cola.agregar_cliente(nombre)
if ticket == 0:
print("Cola llena, intenta mas tarde.")
else:
print(f"Ticket asignado: #{ticket}")
elif opcion == "2":
cliente = cola.llamar_cliente()
if cliente:
print(f"Atendiendo #{cliente.ticket} - {cliente.nombre}")
else:
print("No hay clientes esperando.")
elif opcion == "3":
cola.mostrar_cola()
elif opcion == "0":
print("Hasta luego")
break
else:
print("Opcion no valida")
if __name__ == "__main__":
main()
Ejecuta el siguiente archivo con python simulador_turnos.py:
CAP_TURNOS = 16
MAX_NOMBRE = 32
class Cliente:
def __init__(self, ticket=0, nombre=""):
self.ticket = ticket
self.nombre = nombre
class ColaTurnos:
def __init__(self, capacidad=CAP_TURNOS):
self.capacidad = capacidad
self.datos = [None] * capacidad
self.frente = 0
self.final = 0
self.cantidad = 0
self.siguiente_ticket = 1
def agregar_cliente(self, nombre):
if self.cantidad == self.capacidad:
return 0
slot = Cliente(self.siguiente_ticket, nombre[:MAX_NOMBRE])
self.datos[self.final] = slot
self.siguiente_ticket += 1
self.final = (self.final + 1) % self.capacidad
self.cantidad += 1
return slot.ticket
def llamar_cliente(self):
if self.cantidad == 0:
return None
cliente = self.datos[self.frente]
self.frente = (self.frente + 1) % self.capacidad
self.cantidad -= 1
return cliente
def mostrar_cola(self):
print(f"Turnos pendientes ({self.cantidad}):")
idx = self.frente
for _ in range(self.cantidad):
slot = self.datos[idx]
print(f" #{slot.ticket} - {slot.nombre}")
idx = (idx + 1) % self.capacidad
def main():
cola = ColaTurnos()
while True:
print("1) Agregar cliente")
print("2) Llamar siguiente")
print("3) Mostrar cola")
print("0) Salir")
opcion = input("Opcion: ").strip()
if opcion == "1":
nombre = input("Nombre: ").strip()
ticket = cola.agregar_cliente(nombre)
if ticket == 0:
print("Cola llena, intenta mas tarde.")
else:
print(f"Ticket asignado: #{ticket}")
elif opcion == "2":
cliente = cola.llamar_cliente()
if cliente:
print(f"Atendiendo #{cliente.ticket} - {cliente.nombre}")
else:
print("No hay clientes esperando.")
elif opcion == "3":
cola.mostrar_cola()
elif opcion == "0":
print("Hasta luego")
break
else:
print("Opcion no valida")
if __name__ == "__main__":
main()
La cola circular facilita mantener los tickets en orden incluso cuando la cantidad de clientes alcanza el límite.
El programa es autocontenible y puede usarse como plantilla para futuros ejemplos con mayor complejidad.
En los siguientes ejemplos prácticos aumentaremos la complejidad incorporando hilos, prioridades y almacenamiento persistente.