Updates
This commit is contained in:
BIN
OCTO/octo_1.xlsx
Normal file
BIN
OCTO/octo_1.xlsx
Normal file
Binary file not shown.
BIN
OCTO/octo_2.xlsx
Normal file
BIN
OCTO/octo_2.xlsx
Normal file
Binary file not shown.
BIN
OCTO/octo_3.xlsx
Normal file
BIN
OCTO/octo_3.xlsx
Normal file
Binary file not shown.
BIN
OUTPUT/bom_parts_1_of_3.xlsx
Normal file
BIN
OUTPUT/bom_parts_1_of_3.xlsx
Normal file
Binary file not shown.
BIN
OUTPUT/bom_parts_2_of_3.xlsx
Normal file
BIN
OUTPUT/bom_parts_2_of_3.xlsx
Normal file
Binary file not shown.
BIN
OUTPUT/bom_parts_3_of_3.xlsx
Normal file
BIN
OUTPUT/bom_parts_3_of_3.xlsx
Normal file
Binary file not shown.
45
octo_fill.py
45
octo_fill.py
@@ -40,7 +40,7 @@ _SFP.__init__ = _sfp_patched
|
||||
# ──────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
BOM_DIR = Path("BoM")
|
||||
OCTO_FILE = Path("OCTO/octo.xlsx")
|
||||
OCTO_DIR = Path("OCTO")
|
||||
COST_HEADER = "Unit Cost EUR @1000"
|
||||
|
||||
SKIP_MPNS = {
|
||||
@@ -59,26 +59,18 @@ log = logging.getLogger(__name__)
|
||||
|
||||
# ── Load Octopart data ─────────────────────────────────────────────────────────
|
||||
|
||||
def load_octo(path: Path) -> tuple[dict[tuple[str,str], float], dict[str, float]]:
|
||||
"""
|
||||
Returns:
|
||||
exact_map – (manufacturer_lower, mpn_lower) → lowest unit price
|
||||
mpn_map – mpn_lower → lowest unit price (fallback)
|
||||
"""
|
||||
log.info(f"Reading Octopart data from {path}")
|
||||
def _load_single(path: Path, exact_map: dict, mpn_map: dict) -> int:
|
||||
"""Load one Octopart xlsx into the shared maps. Returns number of entries added."""
|
||||
wb = openpyxl.load_workbook(path, data_only=True, read_only=True)
|
||||
|
||||
exact_map: dict[tuple[str, str], float] = {}
|
||||
mpn_map: dict[str, float] = {}
|
||||
added = 0
|
||||
|
||||
for sheet_name in wb.sheetnames:
|
||||
ws = wb[sheet_name]
|
||||
headers: Optional[dict[str, int]] = None # col_name → 0-based index
|
||||
headers: Optional[dict[str, int]] = None
|
||||
|
||||
for row in ws.iter_rows(values_only=True):
|
||||
row = list(row)
|
||||
if headers is None:
|
||||
# Find header row
|
||||
row_lower = [str(v).strip().lower() if v is not None else "" for v in row]
|
||||
if "original part" in row_lower and "original manufacturer" in row_lower:
|
||||
headers = {str(row[i]).strip(): i for i in range(len(row)) if row[i] is not None}
|
||||
@@ -112,14 +104,35 @@ def load_octo(path: Path) -> tuple[dict[tuple[str,str], float], dict[str, float]
|
||||
key = (mfr.lower(), mpn.lower())
|
||||
if key not in exact_map or price < exact_map[key]:
|
||||
exact_map[key] = price
|
||||
added += 1
|
||||
|
||||
mpn_k = mpn.lower()
|
||||
if mpn_k not in mpn_map or price < mpn_map[mpn_k]:
|
||||
mpn_map[mpn_k] = price
|
||||
|
||||
wb.close()
|
||||
return added
|
||||
|
||||
log.info(f" Loaded {len(exact_map)} unique (manufacturer, part) entries from Octopart")
|
||||
|
||||
def load_octo(octo_dir: Path) -> tuple[dict[tuple[str, str], float], dict[str, float]]:
|
||||
"""
|
||||
Reads every .xlsx file in octo_dir into shared lookup maps.
|
||||
exact_map – (manufacturer_lower, mpn_lower) → lowest unit price
|
||||
mpn_map – mpn_lower → lowest unit price (fallback)
|
||||
"""
|
||||
files = sorted(octo_dir.glob("*.xlsx"))
|
||||
if not files:
|
||||
log.error(f"No .xlsx files found in {octo_dir}/")
|
||||
sys.exit(1)
|
||||
|
||||
exact_map: dict[tuple[str, str], float] = {}
|
||||
mpn_map: dict[str, float] = {}
|
||||
|
||||
for f in files:
|
||||
added = _load_single(f, exact_map, mpn_map)
|
||||
log.info(f" {f.name}: {added} entries loaded")
|
||||
|
||||
log.info(f"Octopart total: {len(exact_map)} unique (manufacturer, part) entries")
|
||||
return exact_map, mpn_map
|
||||
|
||||
|
||||
@@ -311,10 +324,10 @@ def fill_boms(
|
||||
# ── Main ───────────────────────────────────────────────────────────────────────
|
||||
|
||||
if __name__ == "__main__":
|
||||
for p in (BOM_DIR, OCTO_FILE):
|
||||
for p in (BOM_DIR, OCTO_DIR):
|
||||
if not p.exists():
|
||||
log.error(f"Not found: {p}")
|
||||
sys.exit(1)
|
||||
|
||||
exact_map, mpn_map = load_octo(OCTO_FILE)
|
||||
exact_map, mpn_map = load_octo(OCTO_DIR)
|
||||
fill_boms(BOM_DIR, exact_map, mpn_map)
|
||||
|
||||
Reference in New Issue
Block a user