Código Python: ponto de pedido e lote econômico de compra (EOQ)

Código Python: ponto de pedido e lote econômico de compra (EOQ)
Comprar atrasado esvazia a prateleira e a venda vai para o concorrente; comprar demais deixa o dinheiro dormindo no depósito, pagando aluguel, seguro e quebra de mercadoria que ninguém toca. Entre esses dois extremos ficam dois números que todo negócio com estoque deveria ter à mão: o ponto de pedido, que responde «quando eu compro de novo?», e o lote econômico de compra (EOQ), que responde «quanto eu compro em cada pedido?». Este pacote traz um programa de Python que calcula os dois, mais o estoque de segurança e a tabela de sensibilidade que mostra quanto o sistema encarece quando a gente se afasta do ótimo.
Não é preciso ser programador: basta descompactar o ZIP, rodar o programa e ler a tabela. Ele foi feito para o dono de uma loja de material de construção ou de um depósito de bairro, para o contador que monta o orçamento de compras e para o estoquista que sofre a cada pedido que atrasa.
⬇ Baixar o código (ZIP)O que vem no ZIP
| Arquivo | Para que serve |
|---|---|
punto_reorden_eoq.py | O programa completo, comentado linha por linha em português. |
datos/consumo.csv | Quatro produtos de exemplo com demanda anual, custo do pedido, custo unitário, percentual de manutenção, prazo de entrega e desvio diário. |
salida_ejemplo.txt | A saída real do programa, para comparar com a sua. |
LEIAME.md | As instruções do pacote: como abrir e como trocar os dados. |
O que o programa faz
- Lê os produtos de
datos/consumo.csve para se encontrar demanda ou custo de manter igual a zero, em vez de continuar com um número inventado. - Calcula o custo de manter (H): o custo unitário vezes o percentual de manutenção, dividido por cem. É o que custa guardar uma unidade por um ano: aluguel, dinheiro parado, seguro e quebra.
- Calcula o EOQ com a raiz de dois vezes a demanda anual vezes o custo do pedido, dividido por H.
- Arredonda para cima com o teto matemático, porque ninguém compra fração de parafuso nem de galão.
- Conta os pedidos por ano e o custo anual de tocar o item, que não é o valor da mercadoria comprada.
- Espalha a demanda num ano comercial de 360 dias para chegar à demanda diária.
- Calcula o estoque de segurança: 1,65 vezes o desvio diário vezes a raiz do prazo de entrega. O 1,65 corresponde a um nível de serviço de noventa e cinco por cento.
- Calcula o ponto de pedido: o que se consome durante o prazo de entrega mais o colchão de segurança.
- Monta a tabela de sensibilidade com seis tamanhos de pedido em volta do EOQ, da metade ao dobro.
- Salva dois CSV,
salida/reorden_eoq.csvesalida/sensibilidade.csv, prontos para abrir no Excel.
Como rodar
Você precisa do Python 3.11 ou superior. Se não tiver, baixe em python.org e instale com as opções padrão. Descompacte o ZIP numa pasta, abra o terminal nessa pasta e digite:
python punto_reorden_eoq.py
No Windows dá para abrir o terminal na pasta digitando cmd na barra de endereços do Explorador de Arquivos. Não há nada mais para instalar: o programa usa apenas csv, math, decimal e pathlib, que já vêm com o Python. Não precisa de internet nem de banco de dados. Ao terminar você vê as tabelas na tela e aparece uma pasta salida com os dois CSV dentro.
O código, explicado
O programa tem cerca de duzentas e sessenta linhas e está dividido em funções curtas: ler, calcular, imprimir e salvar. Estes são os quatro trechos que vale a pena entender, copiados exatamente como vêm no arquivo que está dentro do ZIP.
As ferramentas e as constantes
import csv # # csv: para ler o arquivo de entrada
import math # # math: para o teto das unidades (ceil) e nada mais
from decimal import Decimal, ROUND_HALF_UP # # Decimal: dinheiro não se calcula com decimais binários (float)
from pathlib import Path # # pathlib: caminhos que funcionam no Windows, Linux e Mac
O programa começa importando quatro módulos da biblioteca padrão. csv lê o arquivo de produtos e math serve só para o teto das unidades. Decimal é a decisão mais importante do programa: dinheiro não se calcula com decimais binários, porque o valor 0,1 não existe de forma exata em binário e os centavos começam a tremer depois de milhares de operações. pathlib monta caminhos que funcionam igual no Windows, no Linux e no Mac, e a pasta base é deduzida do próprio arquivo, então o programa roda de qualquer lugar.
O coração do 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"Dado inválido no arquivo (demanda ou custo de manter em zero): {producto['produto']}")
# 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))
Aqui está o modelo inteiro. H é o custo de manter uma unidade guardada por um ano. O EOQ nasce de colocar as duas curvas de custo uma contra a outra: o custo de fazer os pedidos se espalha por mais unidades quando o pedido é grande, e o custo de manter cresce com o tamanho do pedido. Onde as duas curvas se cruzam a soma é mínima, e desse cruzamento sai um EOQ igual à raiz de dois vezes a demanda vezes o custo do pedido, dividido por H. Depois o programa arredonda para cima, conta os pedidos por ano, espalha a demanda em 360 dias e monta o colchão de segurança com o desvio diário e o prazo de entrega.
A tabela de sensibilidade
def sensibilidad(datos: dict) -> list[dict]:
"""Testa seis tamanhos de pedido em volta do EOQ para mostrar onde está o custo 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 função é a que ensina de verdade: ela testa seis tamanhos em volta do EOQ —da metade ao dobro— e refaz para cada um o custo de pedir, o custo de manter e a soma dos dois. Perto do EOQ a curva é bem plana, e isso é uma boa notícia para quem compra em caixas, paletes ou lotes fechados: arredondar o pedido para a embalagem que o fornecedor vende quase não mexe no custo total.
A conferência final
minimo = min(filas, key=lambda fila: fila["total"])
cuadra = minimo["factor"] == Decimal("1")
print()
print(f" Conferência (o custo mais baixo cai no EOQ, fator 1): {'FECHA' if cuadra else 'REVISAR'}")
A última função procura a linha de menor custo total e confere se é a do fator 1, ou seja, a do EOQ. É uma verificação que o programa faz em si mesmo: se algum número saísse do lugar, a tela mostraria a palavra REVISAR em vez de FECHA. Esse tipo de checagem interna é barato de escrever e evita sustos quando alguém mexe nas constantes do modelo.
O que você vai ver na tela
Com os quatro produtos de exemplo, a primeira coisa que aparece é o cabeçalho e quantos produtos foram lidos:
=================================================================================================================== PONTO DE PEDIDO E EOQ Código Python didático · Kardex Tauro · kardex-tauro.muisca.co =================================================================================================================== Produtos lidos: 4 O EOQ é a quantidade que equilibra o custo de pedir com o custo de manter.
Depois vem a tabela de parâmetros de reposição, uma linha por produto. Veja a linha do cimento: o pedido econômico são 573,00 unidades, ele é comprado umas quinze vezes por ano, tocar esses pedidos custa 2.517.144,50 e o colchão de segurança é de 45,00 unidades, então o ponto de pedido fica em 545,00 unidades.
PARÂMETROS DE REPOSIÇÃO POR PRODUTO ------------------------------------------------------------------------------------------------------------------- Produto EOQ un. Pedidos/ano Custo anual Dem. diária Estoque seg. P. de pedido ------------------------------------------------------------------------------------------------------------------- Cimento cinza 50 kg 573,00 15,71 2.517.144,50 25,00 45,00 545,00 Cabo THHN 12 AWG 100 m 425,00 14,12 1.272.794,12 16,67 32,00 282,00 Parafuso aut. 1 pol x100 837,00 5,02 200.798,42 11,67 8,00 67,00 Tinta anticorrosiva 1 gal 156,00 9,62 673.498,46 4,17 73,00 198,00 -------------------------------------------------------------------------------------------------------------------
E esta é a tabela que mais ensina, a sensibilidade do primeiro produto:
SENSIBILIDADE DO PEDIDO: Cimento cinza 50 kg -------------------------------------------------------------------------- Fator Quantidade Custo de pedir Custo de manter Custo 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 -------------------------------------------------------------------------- Custo total mais baixo: 1x (2.517.144,50)
A linha do fator 1 é o EOQ: 573,00 unidades com custo total de 2.517.144,50. Se o negócio comprasse a metade, 287,00 unidades, o custo subiria para 3.140.110,80; se comprasse o dobro, 1.146,00 unidades, subiria para 3.149.472,25. Sair do ótimo custa mais ou menos um quarto a mais, enquanto errar um quarto para cima ou para baixo quase não se percebe. É essa a lição: o EOQ não precisa ser seguido ao último decimal, mas a ordem de grandeza tem de ser respeitada.
Cimento cinza 50 kg
Pedir : 573,00 unidades
A cada : 22,92 dias entre pedidos
Ponto de pedido : 545,00 unidades
Custo total anual: 2.517.144,50
Conferência (o custo mais baixo cai no EOQ, fator 1): FECHA
E no fim vem o resumo em palavras com os dois números de todo dia —de quanto em quanto tempo comprar e em que saldo disparar o pedido— mais a conferência do próprio programa:
Erros comuns e dicas
- Confundir o custo anual com o valor da mercadoria. A coluna de custo anual é o custo de fazer os pedidos e manter o estoque, não o que se paga ao fornecedor.
- Ignorar o separador decimal do arquivo de dados. Em
datos/consumo.csvos números usam ponto decimal e nenhum separador de milhar. Se você colar de uma planilha que usa vírgulas, o programa para com um aviso de dado inválido. - Deixar o CSV aberto no Excel. No Windows, um arquivo aberto no Excel fica travado e o programa não consegue ler. Feche a planilha e rode de novo.
- Trocar a constante 1,65 sem trocar o nível de serviço. Esse valor pertence a noventa e cinco por cento; com um nível menor a constante cai (mais ou menos 1,28 para noventa por cento) e o colchão encolhe.
- Informar o prazo de entrega em meses. O campo espera dias: se o fornecedor demora três semanas, digite 21.
- Esquecer o ano comercial. O programa usa 360 dias; se o seu negócio vende todos os dias do ano, aumente essa constante e a demanda diária cai um pouco.
- Achar que o EOQ é uma camisa de força. É uma referência: arredonde para a embalagem que o fornecedor vende, porque a tabela de sensibilidade mostra que um quarto a mais ou a menos quase não muda o custo.
Quando isso não basta
Este programa serve para decidir quanto e quando comprar enquanto o catálogo é curto e os dados cabem numa planilha: algumas centenas de itens, um único depósito e entregas que chegam completas. Ele fica curto quando existem vários depósitos, quando o preço unitário muda conforme a quantidade comprada, quando os pedidos chegam em partes e, principalmente, quando é preciso saber quem mexeu em quê e quando.
Para isso existe o Kardex Tauro, um programa gratuito para organizar o estoque de um negócio pequeno: entradas, saídas, saldo por produto e relatórios, sem pagar licença. A recomendação honesta é esta: use este script enquanto a sua operação couber numa planilha e, quando o volume, os depósitos ou o controle interno pedirem mais, passe para um software que mantenha a ficha de estoque completa.
⬇ Baixar o código (ZIP)Baixe o pacote, troque os quatro produtos de exemplo pelos seus e em uma tarde você terá a sua própria tabela de reposição. Na próxima vez que o fornecedor perguntar quanto você vai comprar, a resposta vai estar num arquivo e não na memória.