Código Python: punto de reorden y lote económico de pedido (EOQ)

Código Python: punto de reorden y lote económico de pedido (EOQ)
Comprar tarde deja el estante vacío y la venta se va para la competencia; comprar de más deja el capital dormido en bodega, pagando arriendo, seguros y mermas por mercancía que nadie toca. Entre esos dos extremos hay dos números que cualquier negocio con inventario debería tener a mano: el punto de reorden, que responde «¿cuándo vuelvo a pedir?», y el lote económico de pedido (EOQ), que responde «¿cuánto pido cada vez?». Este paquete trae un programa de Python que calcula los dos, más el stock de seguridad y la tabla de sensibilidad que muestra cuánto se encarece el sistema cuando uno se aleja del óptimo.
No hay que ser programador: se descomprime el ZIP, se ejecuta el programa y se lee la tabla. Está pensado para el dueño de una ferretería o un depósito de barrio, para el contador que arma el presupuesto de compras y para el almacenista que sufre cada pedido que llega tarde.
⬇ Descargar el código (ZIP)Qué trae el ZIP
| Archivo | Para qué sirve |
|---|---|
punto_reorden_eoq.py | El programa completo, comentado línea por línea en español. |
datos/consumo.csv | Cuatro productos de ejemplo con demanda anual, costo de pedido, costo unitario, porcentaje de mantener, plazo de entrega y desviación diaria. |
salida_ejemplo.txt | La salida real del programa, para compararla con la tuya. |
LEEME.md | Las instrucciones del paquete: cómo abrirlo y cómo cambiar los datos. |
Qué hace el programa
- Lee los productos de
datos/consumo.csvy se detiene si encuentra la demanda o el costo de mantener en cero, en vez de seguir con un número inventado. - Calcula el costo de mantener (H): el costo unitario por el porcentaje de mantener, dividido en cien. Es lo que cuesta tener una unidad guardada un año: arriendo, dinero inmovilizado, seguros y mermas.
- Calcula el EOQ con la raíz de dos por la demanda anual por el costo de pedido, dividido entre H.
- Redondea hacia arriba con el techo matemático, porque no se piden fracciones de tornillo ni de galón.
- Cuenta los pedidos al año y el costo anual de gestionar el producto, que no es el valor de la mercancía comprada.
- Reparte la demanda en un año comercial de 360 días para sacar la demanda diaria.
- Calcula el stock de seguridad: 1,65 por la desviación diaria por la raíz del plazo de entrega. El 1,65 corresponde a un nivel de servicio del noventa y cinco por ciento.
- Calcula el punto de reorden: lo que se consume durante el plazo de entrega más el colchón de seguridad.
- Arma la tabla de sensibilidad con seis cantidades alrededor del EOQ, de la mitad al doble.
- Guarda dos CSV,
salida/reorden_eoq.csvysalida/sensibilidad.csv, listos para abrir en Excel.
Cómo ejecutarlo
Necesitas Python 3.11 o superior. Si no lo tienes, descárgalo de python.org e instálalo con las opciones por defecto. Descomprime el ZIP en una carpeta, abre la terminal en esa carpeta y escribe:
python punto_reorden_eoq.py
En Windows puedes abrir la terminal en la carpeta escribiendo cmd en la barra de direcciones del explorador de archivos. No hay que instalar nada más: el programa solo usa csv, math, decimal y pathlib, que ya vienen con Python. No necesita internet ni base de datos. Al terminar verás las tablas en pantalla y aparecerá una carpeta salida con los dos CSV.
El código, explicado
El programa tiene unas doscientas sesenta líneas y está partido en funciones cortas: leer, calcular, imprimir y guardar. Estos son los cuatro pedazos que conviene entender, copiados tal cual del archivo que viene en el ZIP.
Las herramientas y las constantes
import csv # # csv: para leer el archivo de entrada
import math # # math: para el techo de las unidades (ceil) y nada más
from decimal import Decimal, ROUND_HALF_UP # # Decimal: el dinero no se calcula con decimales binarios (float)
from pathlib import Path # # pathlib: rutas que funcionan en Windows, Linux y Mac
El programa empieza importando cuatro módulos de la biblioteca estándar. csv lee el archivo de productos y math se usa solo para el techo de las unidades. Decimal es la decisión más importante del programa: el dinero no se calcula con decimales binarios, porque 0,1 no existe de forma exacta en binario y los centavos terminan bailando cuando se suman miles de operaciones. pathlib arma rutas que funcionan igual en Windows, Linux y Mac, y la carpeta base se deduce del propio archivo, así el programa corre sin importar desde dónde lo llames.
El corazón del cálculo
# H: lo que cuesta tener una unidad guardada un año (arriendo, dinero, mermas).
h = unitario * mantener / 100
if h <= 0 or demanda <= 0:
raise ValueError(f"Dato inválido en el archivo (demanda o costo de mantener en cero): {producto['producto']}")
# Lote económico de pedido: el que hace mínimo el costo de pedir + el de mantener.
# Sale de igualar las dos curvas: D*K/Q = Q*H/2 -> EOQ = raíz(2*D*K/H).
eoq = raiz(Decimal(2) * demanda * costo_pedido / h)
cantidad = entero(eoq)
# Pedidos al año y costo anual total (NO es el valor de la mercancía comprada).
pedidos = demanda / Decimal(cantidad)
costo_total = pedidos * costo_pedido + (Decimal(cantidad) / 2) * h
# Demanda diaria con el año comercial de 360 días.
diaria = demanda / DIAS_ANO
# Stock de seguridad: 1,65 * desviación diaria * raíz del plazo de entrega.
seguridad = entero(Z_SERVICIO * desviacion * raiz(plazo))
# Punto de reorden: lo que se alcanza a consumir mientras llega el pedido + colchón.
reorden = entero(diaria * plazo + Decimal(seguridad))
Aquí está la fórmula del modelo. H es el costo de mantener una unidad guardada un año. El EOQ sale de igualar las dos curvas de costo: lo que cuesta tramitar los pedidos se reparte entre más unidades cuando el pedido es grande, y lo que cuesta mantener crece con el tamaño del pedido. Donde las dos curvas se cruzan la suma es mínima, y de ese cruce sale el EOQ igual a la raíz de dos por la demanda por el costo de pedido, dividido entre H. Después el programa redondea hacia arriba, cuenta los pedidos al año, calcula la demanda diaria sobre 360 días y arma el colchón de seguridad con la desviación y el plazo.
La tabla de sensibilidad
def sensibilidad(datos: dict) -> list[dict]:
"""Prueba seis cantidades de pedido alrededor del EOQ para ver dónde está el costo mínimo."""
filas = []
for factor, etiqueta in FACTORES:
cantidad = entero(factor * Decimal(datos["cantidad"]))
pedir = (datos["demanda"] / Decimal(cantidad)) * datos["costo_pedido"]
guardar = (Decimal(cantidad) / 2) * datos["h"]
filas.append({
"factor": factor, "etiqueta": etiqueta, "cantidad": cantidad,
"pedir": pedir, "mantener": guardar, "total": pedir + guardar,
})
return filas
Esta función es la que enseña de verdad: prueba seis cantidades alrededor del EOQ —de la mitad al doble— y para cada una recalcula el costo de pedir, el de mantener y la suma de los dos. Al lado del EOQ la curva es muy plana, y eso es una buena noticia para quien compra en cajas, paletas o lotes completos: redondear el pedido al empaque que vende el proveedor casi no mueve el costo total.
La comprobación final
minimo = min(filas, key=lambda fila: fila["total"])
cuadra = minimo["factor"] == Decimal("1")
print()
print(f" Comprobación (el costo más bajo cae en el EOQ, factor 1): {'CUADRA' if cuadra else 'REVISAR'}")
La última función busca el renglón de menor costo total y comprueba que sea el del factor 1, es decir el del EOQ. Es una verificación que el programa se hace a sí mismo: si algún número quedara mal, en pantalla aparecería la palabra REVISAR en vez de CUADRA. Este chequeo interno es barato de escribir y ahorra sustos cuando alguien toca las constantes del modelo.
Qué vas a ver en pantalla
Con los cuatro productos de ejemplo, lo primero que sale es el encabezado y cuántos productos se leyeron:
=================================================================================================================== PUNTO DE REORDEN Y EOQ Código Python didáctico · Kardex Tauro · kardex-tauro.muisca.co =================================================================================================================== Productos leídos: 4 El EOQ es la cantidad que equilibra el costo de pedir con el costo de mantener.
Después viene la tabla de parámetros de reposición, una fila por producto. Mira la del cemento: el pedido económico son 573,00 unidades, se piden unas quince veces al año, gestionar esos pedidos cuesta 2.517.144,50 y el colchón de seguridad es de 45,00 unidades, así que el punto de reorden queda en 545,00 unidades.
PARÁMETROS DE REPOSICIÓN POR PRODUCTO ------------------------------------------------------------------------------------------------------------------- Producto EOQ unid. Pedidos/año Costo anual Dem. diaria Stock seg. P. reorden ------------------------------------------------------------------------------------------------------------------- Cemento gris 50 kg 573,00 15,71 2.517.144,50 25,00 45,00 545,00 Cable THHN 12 AWG 100 m 425,00 14,12 1.272.794,12 16,67 32,00 282,00 Tornillo aut. 1 pulg x100 837,00 5,02 200.798,42 11,67 8,00 67,00 Pintura anticorrosiva 1 gal 156,00 9,62 673.498,46 4,17 73,00 198,00 -------------------------------------------------------------------------------------------------------------------
Y esta es la tabla que más enseña, la sensibilidad del primer producto:
SENSIBILIDAD DEL PEDIDO: Cemento gris 50 kg -------------------------------------------------------------------------- Factor Cantidad Costo de pedir Costo de mantener Costo total -------------------------------------------------------------------------- 0,5x 287,00 2.508.710,80 631.400,00 3.140.110,80 0,75x 430,00 1.674.418,60 946.000,00 2.620.418,60 1x 573,00 1.256.544,50 1.260.600,00 2.517.144,50 1,25x 717,00 1.004.184,10 1.577.400,00 2.581.584,10 1,5x 860,00 837.209,30 1.892.000,00 2.729.209,30 2x 1.146,00 628.272,25 2.521.200,00 3.149.472,25 -------------------------------------------------------------------------- Costo total más bajo: 1x (2.517.144,50)
El renglón del factor 1 es el EOQ: 573,00 unidades con un costo total de 2.517.144,50. Si el negocio pidiera la mitad, 287,00 unidades, el costo subiría a 3.140.110,80; si pidiera el doble, 1.146,00 unidades, subiría a 3.149.472,25. Alejarse del óptimo cuesta alrededor de una cuarta parte más, mientras que equivocarse un cuarto arriba o abajo casi no se nota. Esa es la lección: el EOQ no hay que clavarlo al decimal, pero sí respetar su orden de magnitud.
Cemento gris 50 kg
Pedir : 573,00 unidades
Cada : 22,92 días entre pedidos
Punto de reorden : 545,00 unidades
Costo total anual: 2.517.144,50
Comprobación (el costo más bajo cae en el EOQ, factor 1): CUADRA
Y al final, el resumen en palabras con los dos datos de todos los días —cada cuánto pedir y en qué saldo disparar la orden— más la comprobación del programa:
Errores comunes y consejos
- Confundir el costo anual con el valor de la mercancía. La columna de costo anual es lo que cuesta tramitar los pedidos y mantener el inventario, no lo que se le paga al proveedor.
- No respetar el separador decimal del archivo de datos. En
datos/consumo.csvlos números van con punto decimal y sin separador de miles. Si los pegas desde una hoja con comas, el programa se detiene con un aviso de dato inválido. - Dejar el CSV abierto en Excel. En Windows, un archivo abierto en Excel queda bloqueado y el programa no puede leerlo. Cierra la hoja y vuelve a ejecutar.
- Cambiar la constante 1,65 sin cambiar el nivel de servicio. Ese valor corresponde al noventa y cinco por ciento; con un nivel menor la constante baja (alrededor de 1,28 para el noventa por ciento) y el colchón se encoge.
- Poner el plazo de entrega en meses. El campo espera días: si el proveedor tarda tres semanas, escribe 21.
- Olvidar el año comercial. El programa usa 360 días; si tu negocio vende todos los días del año, sube esa constante y la demanda diaria baja un poco.
- Creer que el EOQ es una camisa de fuerza. Es una referencia: redondea al empaque que te venda el proveedor, porque la tabla de sensibilidad muestra que un cuarto arriba o abajo casi no cambia el costo.
Cuándo esto no alcanza
Este programa sirve para decidir cuánto y cuándo pedir cuando el catálogo es corto y los datos viven en una hoja de cálculo: unos pocos cientos de referencias, una sola bodega y compras que llegan completas. Se queda corto cuando hay varias bodegas, cuando el precio unitario cambia según la cantidad pedida, cuando los pedidos llegan por partes y, sobre todo, cuando hace falta saber quién movió qué y cuándo.
Para eso existe Kardex Tauro, un programa gratuito para ordenar el inventario de un negocio pequeño: entradas, salidas, saldo por producto y reportes, sin pagar licencia. La recomendación honesta es esta: usa este script mientras tu operación quepa en una tabla, y cuando el volumen, las bodegas o el control interno lo pidan, pasa a un software que lleve el kardex completo.
⬇ Descargar el código (ZIP)Descarga el paquete, cambia los cuatro productos de ejemplo por los tuyos y en una tarde tendrás tu propia tabla de reposición. La próxima vez que el proveedor pregunte cuánto vas a pedir, la respuesta va a estar en un archivo y no en la memoria.