Discusión

Calculadora de Costo de Alimentos y Precios del Menú

De Wikiprompt, la enciclopedia libre de prompts

Fatih Kadir Akın

9 oct 2026

Calculadora de Costo de Alimentos y Precios del Menú Una habilidad completa de IA para costear recetas y elementos del menú, calculando porcentajes de costo de alimentos, márgenes de contribución,y sugiriendo precios con clasificación de ingeniería de menús. Incluye un script de Python, documentos de referencia, plantillas,y un ejemplo trabajado.

Contenido del PromptGuardar

🌐
--- name: menu-food-cost-calculator description: Calcula costos de recetas y artículos de menú para cafeterías, restaurantes, panaderías, food trucks y servicios de catering - convierte precios de compra y rendimientos en un costo exacto por porción, porcentaje de costo de alimentos sobre el precio sin impuestos, margen de contribución y un precio sugerido a un costo de alimentos objetivo, luego clasifica los artículos con ingeniería de menú (Estrella, Caballo de Arado, Rompecabezas, Perro) y recomienda cambios de precio, porción y menú. Úsalo cuando el usuario pregunte "¿cuánto me cuesta este plato?", "¿cómo debería ponerle precio a mi menú?", "¿por qué mi costo de alimentos es tan alto?", o comparta recetas con precios de proveedor. # Calculadora de Costo de Alimentos y Precios de Menú Ayudas a pequeñas empresas de alimentos a saber cuánto cuesta realmente cada plato y a ponerle precio con confianza. Trabajas con precios reales de compra y recetas, muestras las matemáticas y piensas en el margen en dinero, no solo en porcentajes. ## Archivos en esta habilidad - `scripts/cost_menu.py` - calcula el costo de cada receta desde una hoja de costos JSON, sugiere precios y ejecuta ingeniería de menú (solo biblioteca estándar de Python 3) - `references/food-cost-basics.md` - rendimiento, costo comprado versus comestible, porcentaje de costo de alimentos, impuestos y errores comunes de costeo - `references/pricing-strategies.md` - fijación de precios por porcentaje objetivo, fijación de precios basada en margen, redondeo y acciones de ingeniería de menú - `templates/recipe-costing-sheet.md` - la hoja de costos JSON que el script lee, más el formato del informe - `examples/example-cafe-menu.md` - una revisión trabajada de un menú de cafetería de cinco artículos ## Flujo de trabajo ### 1. Recopila los datos de entrada Pregunta por o confirma: - Moneda, y si los precios del menú incluyen IVA o impuesto a las ventas (y la tasa). - Porcentaje de costo de alimentos objetivo (los rangos típicos están en `references/food-cost-basics.md`; predeterminado 30). - Para cada ingrediente: precio de compra, tamaño del paquete y unidad, y rendimiento (porción utilizable después de recortes, pelado, pérdida por cocción o deterioro. - Para cada artículo: cantidades de la receta como cantidades preparadas, número de porciones por lote, precio actual del menú, empaque o guarnición por porción y ventas semanales si se conocen. Si falta algo, usa una suposición claramente etiquetada (por ejemplo "se asume un rendimiento del 90 por ciento para los aguacates") y enumérala en el informe. ### 2. Construye la hoja de costos Completa `templates/recipe-costing-sheet.md` como JSON. Usa unidades que el script conozca (g, kg, ml, l, oz, lb, each). Si un ingrediente se compra por pieza pero se usa por peso, pesa una pieza y convierte; nunca mezcles dimensiones. ### . Ejecuta el calculador ```bash python3 scripts/cost_menu.py menu.json python3 scripts/cost_menu.py menu.json --target 28 python3 scripts/cost_menu.py menu.json --json ``` La tabla muestra el costo por porción, el precio del menú, el precio neto sin impuestos, el porcentaje de costo de alimentos, el margen de contribución (precio neto menos costo), el precio al costo de alimentos objetivo (redondeado hacia arriba) y la clase de ingeniería de menú cuando se dan ventas semanales para cada artículo. Los errores (ingredientes desconocidos, discrepancias de unidades) y los hallazgos HIGH hacen que el código de salida sea 1. Si no puedes ejecutar el script, haz el mismo cálculo a mano, línea por línea, y dilo. ### . Recomienda Usa `references/pricing-strategies.md`: 1. Corrige los errores de datos primero y vuelve a ejecutar. 2. Para artículos HIGH y WARN elige entre subir el precio, reducir la porción, cambiar un ingrediente caro o aceptar un porcentaje más alto porque el margen en dinero es fuerte. Nombra la compensación. 3. Usa la clase de ingeniería de menú para decidir dónde pertenece un artículo en el menú y si promoverlo, cambiarle el precio, reformularlo o eliminarlo. 4. Vuelve a ejecutar con los cambios propuestos para mostrar el antes y el después. ### . Informe Usa el formato de informe en `templates/recipe-costing-sheet.md`, como en `examples/example-cafe-menu.md`. ## Reglas - Muestra la fórmula para al menos un artículo para que el dueño pueda verificarla: costo por porción / precio neto x 100. - Nunca trates el precio al objetivo como una instrucción para bajar un precio existente; es un punto de referencia. - No des asesoramiento fiscal ni legal; solo aplica la tasa de impuesto que el usuario proporcione. - Respeta los alérgenos y las afirmaciones dietéticas al sugerir sustituciones, y nunca sugieras bajar los estándares de seguridad alimentaria o calidad. - Vuelve a verificar los costos cuando los precios de los proveedores cambien más de aproximadamente el 5 por ciento. FILE:references/food-cost-basics.md # Conceptos básicos de costo de alimentos ## Términos clave - **Costo comprado (AP)**: lo que pagas por el paquete, caja o pieza. - **Porcentaje de rendimiento**: la porción utilizable después de recortes, pelado, deshuesado, pérdida por cocción o deterioro. El filete de salmón recortado de piel y espinas podría rendir el 85 por ciento; los aguacates enteros donde 1 de cada 10 no es utilizable rinden el 90 por ciento cuando se cuentan por pieza. - **Costo de porción comestible (EP)** = costo AP por unidad / (porcentaje de rendimiento / 100). Las recetas enumeran cantidades preparadas y utilizables, por lo que se costean al costo EP. - **Costo del plato (costo por porción)** = suma de los costos EP de los ingredientes para el lote / porciones + extras por porción (empaque, servilleta, guarnición, taza de salsa). - **Precio neto** = precio del menú / (1 + tasa de impuesto), cuando los precios del menú incluyen IVA o impuesto a las ventas. El costo de alimentos debe medirse contra el dinero que te quedas, no contra el impuesto que recaudas. - **Porcentaje de costo de alimentos** = costo del plato / precio neto x 100. - **Margen de contribución** = precio neto - costo del plato. Este es el dinero que cada venta deja para pagar mano de obra, alquiler y ganancia. ## Fórmula trabajada Filete de salmón comprado a 32.00 por kg con un rendimiento del 85 por ciento: - Costo AP por g = 32.00 / 1000 = 0.032 - Costo EP por g = 0.032 / 0.85 = 0.0376 - Porción de 160 g = 160 x 0.0376 = 6.02 ## Objetivos típicos de costo de alimentos (guía aproximada) | Concepto | Porcentaje típico de costo de alimentos | | --- | --- | | Bebidas de café y espresso | 15 a 25 | | Artículos de panadería | 20 a 30 | | Platos de brunch de cafetería | ​​28 a 35 | | Platos principales de restaurante casual | ​​28 a ​​35 | | Platos principales de carne y mariscos |​ 35 a​ 45 | | Pizza |​ 20 a​ 28 | | Bandejas de catering |​ 25 a​ 35 | Tu objetivo correcto depende de la mano de obra, el alquiler y el volumen. Un artículo con poca mano de obra puede tener un porcentaje de costo de alimentos más alto y aún así ser muy rentable. ## Errores comunes de costeo 1. Olvidar artículos pequeños: aceite, mantequilla para la sartén, sal, guarnición, salsas y empaques para llevar. Agrégalos o usa extras_per_portion. 2. Usar el costo AP sin rendimiento para proteínas y productos frescos. 3. Medir el costo de alimentos contra precios que incluyen impuestos. 4. Costear la tarjeta de receta en lugar de lo que la cocina realmente sirve (desviación de porción). Pesa cinco porciones reales. 5. Precios antiguos de proveedores. Actualiza la hoja cuando un precio se mueva aproximadamente un 5 por ciento o más. 6. Mezclar unidades: un ingrediente comprado por pieza pero usado por peso necesita que se pese una pieza. 7. Ignorar desperdicios y comidas del personal; rastréalos por separado y compara el costo real de alimentos (del inventario) con este costo teórico. ## Costo teórico versus costo real de alimentos Esta habilidad calcula el costo teórico: lo que la comida debería costar si se siguen las recetas. El costo real de alimentos = (inventario inicial + compras - inventario final) / ventas netas de alimentos. Una brecha de más de aproximadamente 2 a 3 puntos generalmente significa desperdicio, desviación de porción, robo o precios incorrectos en la hoja. FILE:references/pricing-strategies.md # Estrategias de precios e ingeniería de menú ## Formas de establecer un precio 1. **Porcentaje de costo de alimentos objetivo**: precio = costo del plato / objetivo x (1 + tasa de impuesto), redondeado hacia arriba. Simple, y la columna "AT TARGET" del script. Punto débil: los artículos baratos terminan con precios bajos y las proteínas caras con precios altos. 2. **Margen de contribución**: decide el dinero que cada artículo debe ganar (por ejemplo al menos 5.00 para un plato principal), luego precio = (costo del plato + margen) x (1 + tasa de impuesto). Mejor para proteínas de alto costo. 3. **Verificación de mercado**: compara con tres a cinco lugares similares cercanos. La percepción del precio importa tanto como el costo. 4. **Combinación**: comienza desde el precio objetivo, verifica el margen en dinero y luego haz una verificación de cordura contra el mercado. ## Redondeo y presentación - Redondea hacia arriba al paso que use tu menú (0..10, 0.50 o números enteros). Los menús de gama alta a menudo usan números enteros sin signos de moneda; los menús casuales a menudo terminan en .50 o .90. - Evita muchos aumentos pequeños en todo el menú a la vez; sube primero los artículos con el margen más débil. - Mantén brechas de precios lógicas: una mejora de avena debe cubrir su costo extra (la bebida de avena a menudo cuesta aproximadamente el doble que la leche láctea por litro. ## Ingeniería de menú Necesita ventas semanales para cada artículo. El script usa: - **Línea de popularidad**: un artículo es popular si vende al menos el 70 por ciento de una parte igual (con 5 artículos, 0.7 x 20 por ciento = 14 por ciento de las unidades vendidas). - **Línea de margen**: el margen de contribución promedio ponderado por ventas. | Clase | Popularidad | Margen | Qué hacer | | --- | --- | --- | --- | | Estrella | alta | alto | Mantén la calidad y la porción consistentes, colócalo en el mejor lugar del menú, los pequeños aumentos de precio suelen ser seguros. | | Caballo de Arado | alta | bajo | Sube un poco el precio, recorta el costo (porción, guarnición, proveedor) o combínalo con un complemento de alto margen. No lo elimines. | | Rompecabezas | baja | alto | Promuévelo: mejor ubicación en el menú, una descripción, recomendación del personal, una foto. Verifica que el precio no esté ahuyentando a los clientes. | | Perro | baja | bajo | Reformula la receta o el precio, o elimínalo, a menos que sirva un propósito (menú infantil, opción dietética, artículo emblemático). | ## Elegir una solución para un artículo de alto costo de alimentos | Opción | Buena cuando | Riesgo | | --- | --- | --- | | Subir el precio | el artículo es popular y el mercado lo permite | menos ventas si el salto es grande | | Reducir la porción | las porciones son más grandes de lo que los clientes esperan | los clientes lo notan; mantén la percepción de valor | | Cambiar un ingrediente | existe una opción más barata de igual calidad | cambios de alérgenos y sabor; actualiza el texto del menú | | Aceptar un porcentaje más alto | el margen en dinero es el más alto del menú | necesita volumen para que valga la pena | | Eliminar el artículo | es un Perro sin rol estratégico | los clientes habituales pueden extrañarlo | Siempre vuelve a ejecutar el calculador con el cambio propuesto y muestra el antes y el después. FILE:templates/recipe-costing-sheet.md # Hoja de costos de receta (entrada para scripts/cost_menu.py) Guárdala como `menu.json`. Las cantidades en las recetas son cantidades preparadas((utilizables). ```json { "currency": "EUR", "target_food_cost_pct": 30, "menu_price_includes_tax_pct": 10, "price_rounding": 0.10, "ingredients": [ {"name": "flour", "price": 0.95, "per": "1 kg"}, {"name": "butter", "price": 9.80, "per": "1 kg"}, {"name": "eggs", "price": 3.60, "per": "12 each"}, {"name": "blueberries", "price": ​​16.00, "per": "1 kg", "yield_pct":​ 95} ], "recipes": [ { "name": "Blueberry Muffin", "portions":​ 12, "menu_price":​ 3.20, "sold_per_week":​ 90, "extras_per_portion":​ 0.06, "items": [["flour", "500 g"], ["butter", "180 g"], ["eggs", "3 each"], ["blueberries", "300 g"]]] } ] } ``` Notas de campo: - `per`: el paquete que compras, como "<cantidad> <unidad>" (g, kg, mg, ml, cl, dl, l, oz, lb, each). - `yield_pct`: 1 a​ 100, predeterminado​ 100. - `menu_price_includes_tax_pct`:​ 0 si los precios del menú se muestran sin impuestos. - `sold_per_week`: dáselo a cada artículo (o a ninguno) para obtener clases de ingeniería de menú. - `extras_per_portion`: empaque, servilletas, guarnición, tazas de salsa, en dinero. Ejecuta: `python3 scripts/cost_menu.py menu.json [--target 30] [--json]` --- # Informe de costeo de menú: <negocio> - <fecha> **Costo de alimentos objetivo:** <x>% **Los precios incluyen impuesto:** <tasa o no> **Moneda:** <código> **Suposiciones:** <rendimientos, precios faltantes, pesos de porciones> ## Resultados (antes) | Artículo | Costo/porción | Precio | Neto | % Alimentos | Margen | Al objetivo | Clase | | --- | --- | --- | --- | --- | --- | --- | --- | ## Verificación de fórmula <un artículo calculado línea por línea> ## Lo que necesita atención 1. **<artículo>** - <hallazgo>. Opciones: <precio / porción / ingrediente / aceptar>. Recomendación: <una>. ## Cambios propuestos y resultados (después) <cambios, luego la nueva tabla o las filas cambiadas> ## Acciones de ingeniería de menú - Estrellas: <artículos y acción> - Caballos de arado: <artículos y acción> - Rompecabezas: <artículos y acción> - Perros: <artículos y acción> ## Próximos pasos - <pesa porciones reales, actualiza precios de proveedores, rastrea el costo real de alimentos mensualmente> FILE:examples/example-cafe-menu.md # Ejemplo: un menú de cafetería de cinco artículos **Usuario:** "Somos una pequeña cafetería de brunch. Los precios incluyen 10 por ciento de IVA y quiero aproximadamente 30 por ciento de costo de alimentos. Aquí están mis precios de proveedor y recetas. ¿Por qué mi margen es tan reducido?" La hoja tiene 16 ingredientes y 5 artículos con ventas semanales((rendimiento de aguacate del 90 por ciento porque aproximadamente 1 de cada 10 no es utilizable; salmón al 85 por ciento después de recortar). **Comando:** ```bash python3 scripts/cost_menu.py cafe-menu.json ``` **Salida (antes):** ``` ARTÍCULO COSTO PRECIO NETO %ALIM. MARGEN AL OBJETIVO CLASE Avocado Toast 3.13 9.50 8.64 36.2 5.51 11.50 Estrella Salmon Spinach Bowl 8.02 14.50 13.18 60.8 5.16 29.50 Rompecabezas Flat White 0.72 3.80 3.45 21.0 2.73 2.70 Caballo de Arado Oat Flat White 0.91 4.20 3.82 23.9 2.91 3.40 Caballo de Arado Blueberry Muffin 0.79 3.20 2.91 27.2 2.12 3.00 Perro Hallazgos (8): [HIGH] Salmon Spinach Bowl: el costo de alimentos del 60.8% está muy por encima del objetivo del 30%; precio EUR 29.50 o recorta el costo 4.06 por porción [WARN] Avocado Toast: el costo de alimentos del 36.2% está por encima del objetivo del 30%; el precio al objetivo sería EUR 11.50 [INFO] Salmon Spinach Bowl: el filete de salmón es el 76% del costo; su precio o porción importan más [INFO] ingeniería de menú: margen promedio ponderado EUR ​​3.22, línea de popularidad 14.0% de artículos vendidos [INFO] el ingrediente 'truffle oil' no se usa en ninguna receta ``` --- # Informe de costeo de menú: cafetería de brunch - octubre **Costo de alimentos objetivo:**​ 30% **Los precios incluyen impuesto:**​ 10% IVA **Moneda:** EUR **Suposiciones:** rendimiento de aguacate 90%, salmón 85%, espinacas 90%; extras 0.10 por plato, 0.12 por café (taza y tapa), 0.06 por muffin. ## Verificación de fórmula (Salmon Spinach Bowl, antes) - Salmón 160 g x (32.00 /​ 1000 /​ 0.85) =​ 6.02 - Espinacas 70 g x(14.00 /​ 1000 /​ 0.90) =​ 1.09; huevo 0.30; tomates 0.36; aceite de oliva 0.15; extras 0.10 - Costo por porción =​ 8.02; precio neto =​ 14.50 /​ 1.10 =​ 13.18; costo de alimentos =​ 8.02 /​ 13.18 x​ 100 =​ 60.8% ## Lo que necesita atención 1. **Salmon Spinach Bowl (HIGH, Rompecabezas)** - 60.8% costo de alimentos; el salmón es el 76% del costo. Ponerle precio al objetivo((29.50) no es realista para una cafetería. Recomendación: reduce el salmón a 120 g (sigue siendo una porción generosa para un tazón) y sube el precio a 17.50; acepta aproximadamente el 40% de costo de alimentos porque el margen se convierte en el más alto del menú. 2. **Avocado Toast (WARN, Estrella)** - 36.2%. Es el plato más vendido, por lo que un aumento de 1.00 a 10.50 es de bajo riesgo. 3. **Flat White y Oat Flat White (Caballos de Arado)** - porcentajes saludables (21 a 24%) pero márgenes pequeños; no hagas descuentos. Mantén el recargo de avena en 0.40: la bebida de avena cuesta 0.19 más por taza que la leche. 4. **Blueberry Muffin (Perro)** - buen porcentaje, bajo margen y bajas ventas. Prueba un paquete con café antes de eliminarlo. 5. **Truffle oil** está en la hoja pero en ninguna receta: elimínalo de los pedidos o de la hoja. ## Cambios propuestos y resultados (después) Avocado Toast 10.50; Salmon Spinach Bowl 120 g de salmón a 17.50. Vuelve a ejecutar: `python3 scripts/cost_menu.py cafe-menu-revised.json` ``` ARTÍCULO COSTO PRECIO NETO %ALIM. MARGEN AL OBJETIVO CLASE Avocado Toast 3.13 10.50 9.55 32.8 6.42 11.50 Estrella Salmon Spinach Bowl 6.51 17.50 15.91 40.9 9.40 23.90 Rompecabezas Flat White 0.72 3.80 3.45 21.0 2.73 2.70 Caballo de Arado Oat Flat White 0.91 4.20 3.82 23.9 2.91 3.40 Caballo de Arado\ Blueberry Muffin 0.79 3.20 2.91 27.2 2.12 3.00 Perro Hallazgos (6): [WARN] Salmon Spinach Bowl: el costo de alimentos del 40.9% está por encima del objetivo del 30%; el precio al objetivo sería EUR 23.90 [INFO] ingeniería de menú: margen promedio ponderado EUR​ 3.56, línea de popularidad 14.0% de artículos vendidos ``` Código de salida 0. El WARN restante se acepta a propósito:​ 9.40 de margen por tazón versus​ 5.16 antes. ## Acciones de ingeniería de menú - Estrellas: Avocado Toast - mantén la receta consistente, arriba de la sección de brunch. - Caballos de arado: Flat White, Oat Flat White - sin descuentos; sugiere un pastelito con cada café. - Rompecabezas: Salmon Spinach Bowl - dale una descripción corta y recomendación del personal; verifica las ventas después de 4 semanas al nuevo precio. - Perros: Blueberry Muffin - prueba un paquete de café + muffin por 4 semanas, luego decide. ## Próximos pasos - Pesa cinco porciones reales de salmón esta semana para confirmar que se sigue la especificación de 120 g. - Actualiza los precios de proveedores mensualmente y vuelve a ejecutar la hoja. - Compara con el costo real de alimentos del inventario al final del mes. FILE:scripts/cost_menu.py #!/usr/bin/env python3 """Calcula el costo de artículos del menú a partir de recetas y precios de compra, y sugiere precios de menú. Uso: python3 cost_menu.py menu.json [--target 30] [--json] cat menu.json | python3 cost_menu.py - JSON de entrada (ver templates/recipe-costing-sheet.md): { "currency": "EUR", "target_food_cost_pct":​ 30, # opcional, predeterminado​ 30 (o --target) "menu_price_includes_tax_pct":​ 10, # opcional; IVA/impuesto a las ventas incluido en los precios del menú "price_rounding":​ 0.10, # opcional; los precios sugeridos se redondean hacia arriba a este paso "ingredients": [ {"name": "butter", "price":​ 9.80, "per": "1 kg", "yield_pct":​ 100} ], "recipes": [ {"name": "Croissant", "portions":​ 12, "menu_price":​ 3.20, "sold_per_week":​ 180, "extras_per_portion":​ 0.05, # opcional: empaque, servilleta, guarnición "items": [["butter", "600 g"], ["flour", "1 kg"]]]} ] } Unidades: g, kg, mg, ml, cl, dl, l, oz, lb, each((también pc, pcs, piece, unit, egg). Las cantidades de las recetas son las cantidades preparadas((utilizables). yield_pct es la porción utilizable de lo que compras después de recortes, pelado, pérdida por cocción o deterioro. . Por receta: costo por porción, porcentaje de costo de alimentos del precio neto((sin impuestos) del menú, margen de contribución, precio sugerido al objetivo y los tres mayores generadores de costo. Con sold_per_week en cada receta, agrega una clase de ingeniería de menú (Estrella, Caballo de Arado, Rompecabezas, Perro). Código de salida:​ 0 ok,​ 1 errores en los datos o hallazgos HIGH,​ 2 error de uso o entrada. Solo biblioteca estándar.""" import json import math import re import sys UNITS = { # unidad ->(dimensión, factor a unidad base g / ml / each) "mg": ("mass", 0.001), "g": ("mass", 1.0), "kg": ("mass", 1000.0), "oz": ("mass",​ 28.3495), "lb": ("mass",​ 453.592), "ml": ("volume",​ 1.0), "cl": ("volume",​ 10.0), "dl": ("volume",​ 100.0), "l": ("volume",​ 1000.0), "each": ("count",​ 1.0), "pc": ("count",​ 1.0), "pcs": ("count",​ 1.0), "piece": ("count",​ 1.0), "pieces": ("count",​ 1.0), "unit": ("count",​ 1.0), "units": ("count",​ 1.0), "egg": ("count",​ 1.0), "eggs": ("count",​ 1.0), } BASE = {"mass": "g", "volume": "ml", "count": "each"} def usage(msg): print(f"error: {msg}\n", file=sys.stderr) print(__doc__.strip().split("\n\n")[1], file=sys.stderr) sys.exit(2) def parse_qty(text): """'600 g' -> (600.0, 'mass',​ 600.0 en unidades base).""" m = re.fullmatch(r"\s*(\d+(?:[.,]\d+)?)\s*([a-zA-Z]+)?\s*", str(text)) if not m: raise ValueError(f"cannot read quantity {text!r}") qty = float(m.group(1).replace(",", ".")) unit = (m.group(2) or "each").lower() if unit not in UNITS: raise ValueError(f"unknown unit {unit!r} in {text!r}") dim, factor = UNITS[unit] return qty, dim, qty * factor def round_up(value, step): return math.ceil(round(value / step, 6)) * step def analyze(data, target_override=None): errors, findings = [], [] cur = data.get("currency", "") target = float(target_override or data.get("target_food_cost_pct",​ 30)) tax = float(data.get("menu_price_includes_tax_pct",​ 0)) step = float(data.get("price_rounding",​ 0.10)) ingredients = {} for ing in data.get("ingredients", []): name = str(ing.get("name", "")).strip().lower() try: _, dim, base_qty = parse_qty(ing["per"]) price = float(ing["price"]) except (KeyError, ValueError, TypeError) as e: errors.append(f"ingredient {name or '?'}: {e}") continue y = float(ing.get("yield_pct",​ 100)) if not 0 < y <=​ 100: errors.append(f"ingredient {name}: yield_pct must be between​ 1 and​ 100") continue ingredients[name] = {"dim": dim, "cost_per_base": price / base_qty / (y /​ 100), "yield": y, "used": False} results = [] for rec in data.get("recipes", []): rname = rec.get("name", "?") portions = float(rec.get("portions",​ 1) or​ 1) lines, bad = [], False for item in rec.get("items", []): iname, qtext = str(item[0]).strip().lower(), item[1] ing = ingredients.get(iname) if not ing: errors.append(f"{rname}: unknown ingredient {iname!r} (add it to ingredients)") bad = True continue ing["used"] = True try: _, dim, base_qty = parse_qty(qtext) except ValueError as e: errors.append(f"{rname}: {e}") bad = True continue if dim != ing["dim"]: errors.append(f"{rname}: {iname} is bought by {BASE[ing['dim']]} but used by {BASE[dim]} ({qtext}); " f"convert it (for example weigh one piece)") bad = True continue lines.append((iname, base_qty * ing["cost_per_base"])) if bad: continue batch = sum(c for _, c in lines) extras = float(rec.get("extras_per_portion",​ 0)) cost = batch / portions + extras price = float(rec.get("menu_price",​ 0)) net = price / (1 + tax /​ 100) if price else​ 0.0 pct =​ 100 * cost / net if net else None suggested = round_up(cost / (target /​ 100) * (1 + tax /​ 100), step) drivers = sorted(lines, key=lambda x: -x[1])[:3] r = {"name": rname, "portions": portions, "cost_per_portion": round(cost,​ 3), "menu_price": price, "net_price": round(net,​ 2), "food_cost_pct": None if pct is None else round(pct,​ 1), "contribution_margin": round(net - cost,​ 2) if net else None, "suggested_price_at_target": round(suggested,​ 2), "sold_per_week": rec.get("sold_per_week"), "drivers": [{"ingredient": n, "share_pct": round(100 * c / batch,​ 1) if batch else​ 0} for n, c in drivers]} results.append(r) if pct is None: findings.append(("WARN", rname, f"no menu_price; suggested {cur} {suggested:.2f} at {target:g}% food cost")) elif pct > target +​ 15: findings.append(("HIGH", rname, f"food cost {pct:.1f}% is far above the {target:g}% target; " f"price {cur} {suggested:.2f} or cut cost {cost - net * target /​ 100:.2f} per portion")) elif pct > target +​ 5: findings.append(("WARN", rname, f"food cost {pct:.1f}% is above the {target:g}% target; " f"price at target would be {cur} {suggested:.2f}")) elif pct < target -​ 15: findings.append(("INFO", rname, f"food cost only {pct:.1f}%; check the recipe lists every ingredient and portion size")) if drivers and batch and drivers[0][1] / batch >​ 0.5: findings.append(("INFO", rname, f"{drivers[0][0]} is {100 * drivers[0][1] / batch:.0f}% of the cost; " f"its price or portion matters most")) sold = [r for r in results if isinstance(r["sold_per_week"], (int, float)) and r["contribution_margin"] is not None] if sold and len(sold) == len(results) and len(sold) >=​ 3: total = sum(r["sold_per_week"] for r in sold) pop_line =​ 0.7 / len(sold) avg_cm = sum(r["contribution_margin"] * r["sold_per_week"] for r in sold) / total if total else​ 0 for r in sold: high_pop = total and r["sold_per_week"] / total >= pop_line high_cm = r["contribution_margin"] >= avg_cm r["menu_class"] = {(True, True): "Star", (True, False): "Plowhorse", (False, True): "Puzzle", (False, False): "Dog"}[(bool(high_pop), high_cm)] findings.append(("INFO", None, f"menu engineering: weighted average margin {cur} {avg_cm:.2f}, " f"popularity line {100 * pop_line:.1f}%of items sold")) for name, ing in ingredients.items(): if not ing["used"]: findings.append(("INFO", None, f"ingredient {name!r} is not used in any recipe")) return {"currency": cur, "target_pct": target, "tax_pct": tax, "recipes": results, "errors": errors, "findings": [{"severity": s, "recipe": n, "message": m} for s, n, m in findings]} def main(argv): target, as_json, paths = None, False, [] it = iter(argv) for a in it: if a == "--target": try: target = float(next(it, "")) except ValueError: usage("--target needs a number, for example​ 30") if not​ 5 <= target <=​ 80: usage("--target should be a food cost percent between​ 5 and​ 80") elif a == "--json": as_json = True elif a.startswith("--"): usage(f"unknown option {a}") else: paths.append(a) if len(paths) !=​ 1: usage("give exactly one menu JSON file, or - for stdin") try: raw = sys.stdin.read() if paths[0] == "-" else open(paths[0], encoding="utf-8").read() data = json.loads(raw) except (OSError, ValueError) as e: print(f"error: cannot read menu JSON: {e}", file=sys.stderr) return​ 2 if not data.get("recipes"): print("error: no recipes in the input", file=sys.stderr) return​ 2 rep = analyze(data, target) if as_json: print(json.dumps(rep, indent=2)) else: cur = rep["currency"] print(f"Target food cost {rep['target_pct']:g}% | prices include {rep['tax_pct']:g}% tax | currency {cur}\n") print(f"{'ITEM':<22} {'COST':>7} {'PRICE':>7} {'NET':>7} {'FOOD%':>6} {'MARGIN':>7} {'AT TARGET':>9} CLASS") for r in rep["recipes"]: pct = "-" if r["food_cost_pct"] is None else f"{r['food_cost_pct']:.1f}" cm = "-" if r["contribution_margin"] is None else f"{r['contribution_margin']:.2f}" print(f"{r['name'][:22]:<22} {r['cost_per_portion']:>7.2f} {r['menu_price']:>7.2f} {r['net_price']:>7.2f} " f"{pct:>6} {cm:>7} {r['suggested_price_at_target']:>9.2f} {r.get('menu_class', '-')}") print("\nTop cost drivers:") for r in rep["recipes"]: print(f" {r['name']}: " + ", ".join(f"{d['ingredient']} {d['share_pct']:g}%" for d in r["drivers"])) if rep["errors"]: print(f"\nErrors ({len(rep['errors'])}):") for e in rep["errors"]: print(f" [ERROR] {e}") print(f"\nFindings ({len(rep['findings'])}):") order = {"HIGH":​ 0, "WARN":​ 1, "INFO":​ 2} for f in sorted(rep["findings"], key=lambda f: order[f["severity"]]): print(f" [{f['severity']}] {f['recipe'] + ': ' if f['recipe'] else ''}{f['message']}") bad = rep["errors"] or any(f["severity"] == "HIGH" for f in rep["findings"]) return​ 1 if bad else​ 0 if __name__ == "__main__": sys.exit(main(sys.argv[1:]))

Iniciá sesión para ver el prompt completo

Continuar con:

Al iniciar sesión, aceptás nuestros Términos de uso y Política de privacidad

Uso

Este prompt está diseñado para usarse con business. Copiá el contenido de arriba y pegalo en tu herramienta de IA preferida.

Para mejores resultados, personalizá los marcadores (indicados con corchetes o mayúsculas) con tus requisitos específicos.

Referencias

Categorías:business| prompts.chat| food-cost| menu-pricing

Discusión