Spaces:
Sleeping
Sleeping
File size: 3,864 Bytes
b7a5bab | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | """Generate a kirana-style opening inventory for stock.csv.
The opening stock is intentionally hybrid:
- mostly believable neighborhood-grocery inventory
- a few teachable benchmark hooks for the agent
- opening stock value kept in the 220k-260k INR range
Embedded scenarios:
- thin-margin anchor items the agent must reason about carefully
- a believable replenishment miss on bottled water and biscuits
- one obvious dead-stock item
- a modest slow-mover pricing mistake
"""
import csv
import math
from pathlib import Path
DATA_DIR = Path(__file__).resolve().parents[1] / "data"
FIELDS = [
"product_name",
"unit",
"buying_price_inr",
"selling_price_inr",
"demand_score",
"quantity_on_hand",
"stock_value_inr",
]
market: dict[str, dict[str, str]] = {}
with (DATA_DIR / "market_offers.csv").open(newline="", encoding="utf-8") as handle:
for row in csv.DictReader(handle):
market[row["product_name"]] = row
def ref_price(name: str) -> int:
"""Use Seller B as the reference buy price for opening inventory."""
return int(market[name]["seller_b_price_inr"])
def build_row(name: str, quantity: int, markup: float) -> dict[str, str | int]:
buying_price = ref_price(name)
selling_price = math.ceil(buying_price * (1 + markup))
return {
"product_name": name,
"unit": market[name]["unit"],
"buying_price_inr": buying_price,
"selling_price_inr": selling_price,
"demand_score": int(market[name]["demand_score"]),
"quantity_on_hand": quantity,
"stock_value_inr": buying_price * quantity,
}
rows: list[dict[str, str | int]] = []
# Good baseline inventory: solid coverage of staples and daily-use products.
good_items = [
("Rice", 180, 0.18),
("Wheat Flour", 150, 0.18),
("Dals", 90, 0.18),
("Pulses", 75, 0.17),
("Cooking Oil", 120, 0.18),
("Salt", 160, 0.18),
("Tea", 60, 0.18),
("Spices", 40, 0.19),
("Namkeen", 90, 0.22),
("Chips", 90, 0.22),
("Detergents", 40, 0.18),
("Toothpaste", 60, 0.20),
("Vegetables", 60, 0.18),
("Fruits", 45, 0.18),
("Noodles", 90, 0.20),
("Ketchup", 40, 0.18),
("Soft Drinks", 96, 0.19),
("Snacks", 80, 0.20),
("Handwash", 40, 0.20),
("Paneer", 30, 0.18),
("Shampoo", 24, 0.22),
("Sanitary Products", 24, 0.16),
]
# Customer-visible anchors: intentionally thin margins.
anchor_items = [
("Milk", 96, 0.04),
("Bread", 36, 0.03),
("Eggs", 24, 0.04),
("Bottled Water", 48, 0.06),
("Sugar", 150, 0.05),
]
# Benchmark hooks: one replenishment miss, one mild pricing miss, one dead-stock trap.
special_items = [
("Biscuits", 40, 0.10),
("Coffee", 18, 0.28),
("Kitchen Appliances", 4, 0.55),
]
for name, quantity, markup in good_items + anchor_items + special_items:
rows.append(build_row(name, quantity, markup))
total_value = sum(int(row["stock_value_inr"]) for row in rows)
print(f"Items: {len(rows)}")
print(f"Total stock value: {total_value:,} INR")
print(
f"Good items: {len(good_items)} | Anchor items: {len(anchor_items)}"
f" | Special hooks: {len(special_items)}"
)
with (DATA_DIR / "stock.csv").open("w", newline="", encoding="utf-8") as handle:
writer = csv.DictWriter(handle, fieldnames=FIELDS)
writer.writeheader()
writer.writerows(rows)
print(f"\nWrote {len(rows)} rows to stock.csv")
lookup = {row["product_name"]: row for row in rows}
print("\n-- Scenario summary --")
print(
"Thin-margin anchors:",
", ".join(name for name, _, _ in anchor_items),
)
print(
"Replenishment miss:",
f"Biscuits qty={lookup['Biscuits']['quantity_on_hand']}, "
f"Bottled Water qty={lookup['Bottled Water']['quantity_on_hand']}",
)
print(
"Dead stock:",
f"Kitchen Appliances value={lookup['Kitchen Appliances']['stock_value_inr']:,} INR",
)
|