Conversation
|
Performance benchmarks:
|
|
Performance benchmarks:
|
|
I'm concerned we're accumulating some API bloat. This PR adds self.recorder = DataRecorder(self)
self.data_registry.track_agents(self.agents, "agent_data", "wealth").record(self.recorder)
self.data_registry.track_model(self, "model_data", "gini").record(
self.recorder,
configuration=DatasetConfig(start_time=4, interval=2)
)In our recent discussion I thought we were moving towards an API like this: # No explicit recorder construction - handled internally by model.data
self.data.track_agents(Wolf, "wolf_energy", "energy").record()
self.data.track_model(self, "gini", "gini").record(Schedule(interval=5, start=100))With as main difference that With this PR, users now need to understand:
Do you see options to decomplicate both the mental model for users and the API? I think sensible defaults also would help to go a long way. |
Users might use different recorders depending on the backend. So, the dataset needs to know the recorder that is to be used. Also, at the moment, we don't have a default recorder field on the model, nor a configuration via I agree about the end goal of having a clean API. This PR is just a small step to getting there. And I would argue it already simplifies it quite a bit because there is no longer the need to pass a complex configuration dict to the recorder. Instead, we tie the configuration directly to the dataset via the new A next step, in my view, is to see if we can simplify |
|
Thanks for the context, sounds good.
We might create a
|
|
It's a bit different. The two share |
|
Basically Schedule is a data storage object. It can have some fields that are useful/valid for recurring event scheduling, some that are useful for data recording, and some that are useful for both. |
Which is why a basic protocol with start, end, and interval might make sense, but a full hierarchy of classes is probably overkill. |
This PR adds a new
recordmethod toDataSet. Building on #3145 and #3156, and the discussion on data collection, this makes for quite an elegant API:Implementation details
I kept this PR as focused as possible. At its core, it adds a new method
DataSet.record(recorder, configuration). Internally, I added aBaseDataRecorder. add_dataset(dataset:DataSet, configuration:DataConfig|None=None). I updated the__init__ofBaseDataRecorderto allow forconfig=Noneand I removed the behavior where a recorder automatically records all datasets. This last change is not needed for this PR, but a key design principle is that we want to separate datasets at a given instant from their recording over time. Automatically recording datasets defeats this purpose.I deliberately left out other ideas from the discussion because there is no consensus on those yet.