tools/chain.py: add --consumers to list what eats a material

Reverse of the existing make-vs-buy tree: given a ticker, find every
recipe that consumes it as an input, with each output's live market
depth. Answers "is there a deeper downstream product worth chaining
into" without an ad-hoc fio.recipes() scan each time (did this by hand
for BOR, BSE and BBH this session).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-10-08 10:42:16 +02:00
co-authored by Claude Sonnet 5
parent 264fbf164b
commit 84a873f3bc
+20
View File
@@ -3,6 +3,7 @@
Cost to make = inputs at min(buy, make) per output unit; wages/capex excluded unless --wages. Cost to make = inputs at min(buy, make) per output unit; wages/capex excluded unless --wages.
tools/chain.py DEC # AI1 tools/chain.py DEC # AI1
tools/chain.py BHP --depth 3 --qty 13 tools/chain.py BHP --depth 3 --qty 13
tools/chain.py BOR --consumers # what recipes EAT this ticker as an input, with the output's market depth
""" """
import argparse, sys import argparse, sys
from pathlib import Path from pathlib import Path
@@ -18,6 +19,7 @@ def main():
ap.add_argument("--qty", type=float, default=1.0, help="units/day you would make (sourcing check)") ap.add_argument("--qty", type=float, default=1.0, help="units/day you would make (sourcing check)")
ap.add_argument("--wages", action="store_true", help="add wage cost per output unit (both luxuries at ask)") ap.add_argument("--wages", action="store_true", help="add wage cost per output unit (both luxuries at ask)")
ap.add_argument("--cogc") ap.add_argument("--cogc")
ap.add_argument("--consumers", action="store_true", help="list recipes that consume this ticker as an input, with the output's market depth, instead of the make-vs-buy tree")
a = ap.parse_args() a = ap.parse_args()
snap = market.snapshot() snap = market.snapshot()
@@ -28,6 +30,24 @@ def main():
for o in r["Outputs"]: for o in r["Outputs"]:
by_out.setdefault(o["Ticker"], []).append(r) by_out.setdefault(o["Ticker"], []).append(r)
if a.consumers:
tk = a.ticker.upper()
found = False
for r in fio.recipes():
if not any(i["Ticker"] == tk for i in r["Inputs"]):
continue
found = True
ins = " ".join(f"{i['Amount']}{i['Ticker']}" for i in r["Inputs"])
outs = " ".join(f"{o['Amount']}{o['Ticker']}" for o in r["Outputs"])
print(f"{r['BuildingTicker']:4} {ins} -> {outs}")
for o in r["Outputs"]:
q = Q(o["Ticker"])
mk = f"ask {q.ask:.0f} bid {q.bid:.0f} sup {q.supply:.0f} dem {q.demand:.0f} flow {sat.tref(q.traded7, q.traded30):.1f}/d" if q and q.ask and q.bid else "no market"
print(f" {o['Ticker']:5} {mk}")
if not found:
print(f"nothing consumes {tk} as an input")
return
def wage_per_day(b): def wage_per_day(b):
tot = 0.0 tot = 0.0
for t in econ.TIERS: for t in econ.TIERS: