Este ejercicio consta de una recreación de una caja registradora totalmente funcional con una gran variedad de funcionalidades que la hacen asemejarse a una real.
Entre las funcionalidades de este programa encontramos las siguientes:
- Gestión de empleados por parte de un archivo externo (a modo de pequeña base de datos).
- Inserción de 100 productos reales con sus datos asociados (nombre, precio, identificador) en un archivo externo (a modo de pequeña base de datos).
- Funcionalidades relacionadas a la naturaleza de la aplicación: insertar productos, añadir múltiples productos simultáneamente, añadir productos con descuento, retirar productos, añadir descuentos al total...
- Además, el programa permite generar un ticket de compra en formato .txt en el que se muestran los productos adquiridos.
El código es:
import random
import datetime
import csv
# Cargar productos desde archivo CSV
productos = {}
trabajadores = {}
with open('productos.csv', mode='r') as archivo:
leerfilas = csv.DictReader(archivo)
for fila in leerfilas:
productos[fila['id']] = {'nombre': fila['nombre'], 'precio': float(fila['precio'])}
with open('trabajadores.csv', mode='r') as archivo:
leerfilas = csv.DictReader(archivo)
for fila in leerfilas:
trabajadores[fila["id"]] = {"nombre": fila["nombre"], "pw": fila["pw"]}
# Función para generar el ticket en un archivo de texto
def generar_ticket(lista, listap, listan, total, pedido, nombre, mediopago, haycupon, cupon, descuento_nom, hayeliminados, listae, haygratis, listag):
with open(f"ticket{pedido}.txt", "w") as f:
f.write("Ticket de compra\n")
f.write("==============================\n")
for i in range(0, len(lista)):
f.write(f" - {listan[i]} ({lista[i]}): {listap[i]}€\n")
f.write("")
if hayeliminados == True:
for j in range(len(listae)):
f.write(f" - {listae[j]}€\n")
if haygratis == True:
for j in range(len(listag)):
f.write(f" - {listag[j]}€\n")
f.write("______________________________\n")
a = float(round((total + cupon), 2))
f.write(f" -> Subtotal: {a:.2f}€\n")
if haycupon:
f.write(f" · Cupón de descuento: {cupon}€ ({descuento_nom}%)\n")
f.write(f" -> Total: {total:.2f}€\n")
else:
f.write(f" (No se han aplicado cupones de descuento)\n")
f.write(f" -> Total: {total:.2f}€\n")
f.write("______________________________\n")
f.write(f"Medio de pago: {mediopago}.\n")
f.write("")
fechayhora = datetime.datetime.now()
fecha = fechayhora.date()
hora = fechayhora.hour
minuto = str(fechayhora.minute).zfill(2)
f.write(f"Fecha: {fecha} - {hora}:{minuto}\n")
f.write("==============================\n")
f.write(f"Le atendió: {nombreT}\n")
f.write("Gracias por confiar en nosotros\n")
f.write("==============================\n")
print(f"Ticket generado: ticket{pedido}.txt")
def verificar_trabajador(IDTrabajador, seguir):
# Verificamos si el IDTrabajador existe en el diccionario trabajadores. Si existe, comprobamos la contraseña introducieda. Todo con sus correspondientes errores asociados.
while seguir == False:
if IDTrabajador in trabajadores:
pwTrab = trabajadores[IDTrabajador]["pw"]
pwIntrod = input("Introduzca su contraseña personal -> ")
if pwTrab == pwIntrod:
global nombreT
nombreT = trabajadores[IDTrabajador]["nombre"]
seguir = True
else:
print("Contraseña incorrecta. Pruebe de nuevo.")
seguir = False
else:
IDTrabajador = input("No se ha podido verificar su ID. Introdúzcalo de nuevo -> ")
seguir = False
while not IDTrabajador:
IDTrabajador = input("No se ha podido obtener su ID. Introdúzcalo de nuevo -> ")
pedido = 0
descuento_nom = 0
repetirBucle = True
seguir = False
nombre = ""
IDTrabajador = str(input("Introduzca su ID de trabajador: "))
verificar_trabajador(IDTrabajador, seguir)
print(f"Te has identificado correctamente como {nombreT}")
# Bucle principal para gestionar múltiples pedidos
while repetirBucle == True:
total = 0
hayeliminados = False
haygratis = False
lista = [] #ids de los productos
listap = [] #precios de los productos
listan = [] #nombres de los productos
listae = [] #productos eliminados
listag = [] #productos gratis
pedido += 1
if pedido > 1:
cambio = input("¿Cambio de trabajador? (s/n) ")
if cambio == "s":
IDTrabajador = str(input("Introduzca su ID de trabajador: "))
verificar_trabajador(IDTrabajador, seguir)
print(f"Te has identificado correctamente como {nombreT}")
else:
print(f"De acuerdo, {nombreT}\n")
auto = input("¿Desea recibir una lista de productos aleatoria? (s/n) -> ")
if auto == "s":
cantidad_prod = random.randint(5, 15)
lista_ids = list(productos.keys())
print("Lista de productos: \n")
for i in range(cantidad_prod): # Itera sobre un rango de enteros
id_random = random.choice(lista_ids) # No es necesario convertir a float
print(f"{id_random}, ")
else:
print("De acuerdo, introducirá los artículos manualmente.\n")
print("Introduzca los artículos\n(escriba 'd' para descuento, 'a' para entrada múltiple, 'r' para retirar un artículo o 's' para finalizar):")
# Bucle interno para gestionar los artículos de un pedido
#Va con la misma variable pues si se sale de la de dentro, de la de fuera tambien, pero si solo hay una comprueba todos los if y vuelve a donde el trabajador
while repetirBucle == True:
entrada = str(input("-> ")).zfill(4) #esto es para rellenar 4 digitos (25 -> 0025)
if entrada.isnumeric() and entrada in productos:
total += productos[entrada]["precio"]
print(f"Producto {productos[entrada]['nombre']} (ID:{entrada}): {productos[entrada]['precio']:.2f}€")
print(f"Total hasta ahora: {total:.2f}€")
lista.insert(0, entrada)
listap.insert(0, f"{productos[entrada]['precio']:.2f}")
listan.insert(0, f"{productos[entrada]['nombre']}")
elif entrada.lower() == "000d": #el entrada.lower() hace que todas las letras en dicha variable pasen a minusculas
print("Introduzca el descuento:")
desc = float(input("Descuento (%): "))
while desc > 100:
desc = float(input("El descuento no puede superar el 100%. Introdúzcalo de nuevo -> "))
print("Introduzca el artículo:")
art = str(input("ID artículo: ")).zfill(4)
if art in productos:
if desc == 100:
precio = productos[art]["precio"]
print(f"Producto {productos[art]['nombre']} (ID:{art}): 0.00€ -> 100% descuento (GRATIS)")
listag.append(f"{productos[art]['nombre']} -> GRATIS (PVP: {precio:.2f}) - 0.00")
haygratis = True
else:
precio_descuento = productos[art]['precio'] * (1 - desc / 100)
listap.insert(0, f"{precio_descuento:.2f}")
total += precio_descuento
print(f"Producto {productos[art]['nombre']} (ID:{art}): {productos[art]['precio']} -> {precio_descuento:.2f}€ ({desc}% desc)")
listan.insert(0, f"{productos[art]['nombre']}")
lista.insert(0, art)
#el listap (precios) está arriba en cada condicion del if, ya que si el descuento es del 100, es gratis
print(f"Total hasta ahora: {total:.2f}€")
else:
print("Código de artículo no válido.")
elif entrada.lower() == "000a":
cantidad = int(input("Cantidad: "))
art = str(input("ID artículo: ")).zfill(4)
if art in productos:
precio = productos[art]['precio'] * cantidad
total += precio
print(f"Has añadido {cantidad} productos {productos[art]['nombre']} (ID:{art}) -> {cantidad} x {productos[art]['precio']} = {precio:.2f}€")
print(f"Total hasta ahora: {total:.2f}€")
for i in range(cantidad):
lista.insert(0, art)
listap.insert(0, f"{productos[art]['precio']:.2f}")
listan.insert(0, f"{productos[art]['nombre']}")
else:
print("Código de artículo no válido.")
elif entrada.lower() == "000r":
art = str(input("ID artículo a QUITAR: ")).zfill(4)
if art in lista:
indice = lista.index(art)
precio = float(listap[indice])
total = total - precio
print(f"Has eliminado {art} (ID:{art}) -> Bajado el importe total en {precio:.2f}€")
print(f"Total hasta ahora: {total:.2f}€")
lista.pop(indice) # estos dos serian para eliminar el producto a quitar de la lista, pero prefiero que aparezcan
listap.pop(indice)
listan.pop(indice)
listae.append(f"{productos[art]['nombre']} -> Eliminado: -{precio:.2f}")
hayeliminados = True
else:
print("Código de artículo no válido o no en el carrito.")
elif entrada.lower() == "0000":
nomart = input("Introduzca el nombre del artículo -> ")
precioart = round((float(input("Introduzca el precio del artículo -> "))), 2)
total = total + precioart
print(f"Producto {nomart} (ID:{entrada:4}): {precioart}€")
print(f"Total hasta ahora: {total:.2f}€")
lista.insert(0, "-No ID asociado-")
listap.insert(0, f"{precioart:.2f}")
listan.insert(0, f"{nomart}")
elif entrada.lower() == "000s":
a = input("¿Hay un cupón de descuento? (s/n) -> ")
if a == "s":
haycupon = True
cupon = float(input("Introduzca el % de descuento sobre el total -> "))
print(f"Descuento del {cupon:.2f}% aplicado.")
descuento_nom = cupon
cupon = round((total - (total * (1 - cupon / 100))), 2)
total = total - cupon
print(f"Descuento total: {cupon}€")
else:
print("- Sin cupón -")
haycupon = False
cupon = 0
print(f"Total final: {total:.2f}€")
pago = input("¿Efectivo o tarjeta? (e/t) -> ")
while pago not in ["e", "t"]:
pago = input("No se ha podido obtener. Introduzca medio de pago -> ")
if pago == "e":
continuar = False
while not continuar:
entregado = float(input("¿Cuánto ha entregado? -> "))
if entregado > total or entregado == total:
devolver = entregado - total
print(f"Devolver {devolver:.2f}€")
mediopago = "Efectivo"
continuar = True
else:
print("No puede haber entregado menos. Revise la cantidad")
elif pago == "t":
continuar = False
while not continuar:
terminal = float(input("Introduzca cantidad para terminal de pago -> "))
print(f"Pago de {terminal:.2f}€ introducido correctamente")
if terminal == float(f"{total:.2f}"):
mediopago = "Tarjeta"
continuar = True
else:
print("Cantidad incorrecta")
print(f"Objetos comprados: {lista}")
siono = input("¿Quiere ticket? (s/n) -> ")
if siono.lower() == "s":
generar_ticket(lista, listap, listan, total, pedido, nombre, mediopago, haycupon, cupon, descuento_nom, hayeliminados, listae, haygratis, listag)
seguirpreg = input("¿Desea seguir? (s/n) -> ")
if seguirpreg.lower() == "n":
repetirBucle = False
break
else:
print("Código no válido. Introduzca otro artículo o 's' para finalizar.")
print("Gracias, ¡Hasta pronto!")
No hay comentarios:
Publicar un comentario