-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Accept Scenario as class or instance in Model init #3435
Copy link
Copy link
Closed
Labels
Description
Problem
The current pattern for wiring Scenarios into Models creates boilerplate in every model:
class PdGrid(mesa.Model):
def __init__(self, scenario=None):
if scenario is None:
scenario = PrisonersDilemmaScenario()
super().__init__(scenario=scenario)The call site is verbose for the default case:
model = PdGrid(scenario=PrisonersDilemmaScenario(rng=42))Proposal
Allow scenario to accept either a class (instantiated automatically with defaults) or an instance (used directly). The class serves as the default in the signature:
class PdGrid(mesa.Model):
def __init__(self, scenario=PrisonersDilemmaScenario, rng=None):
super().__init__(scenario=scenario, rng=rng)
self.grid = OrthogonalMooreGrid(
(self.scenario.width, self.scenario.height), ...
)Call sites
# Defaults
model = PdGrid()
model = PdGrid(rng=42)
# Custom parameters
model = PdGrid(scenario=PrisonersDilemmaScenario(width=100, rng=42))
# Batch runs
scenarios = [PrisonersDilemmaScenario(width=w, rng=r) for w in [50, 100] for r in seeds]
models = [PdGrid(scenario=s) for s in scenarios]Implementation
The change is in Model.__init__:
if isinstance(scenario, type) and issubclass(scenario, Scenario):
scenario = scenario(rng=rng)
elif scenario is None:
scenario = Scenario(rng=rng)
# else: already an instance, use directlyBenefits
- No
if scenario is Noneboilerplate in every model - The default argument documents which Scenario type the model expects
- IDE autocomplete and
help()work (no**kwargspassing) - Simple models that don’t need a custom Scenario just omit the parameter entirely
- SolaraViz can inspect the default to discover parameter names for sliders
batch_runcan inspect the default to construct Scenarios from parameter dicts
Reactions are currently unavailable