Mesa 3.0.0a4__py3-none-any.whl → 3.0.0b0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of Mesa might be problematic. Click here for more details.

Files changed (41) hide show
  1. mesa/__init__.py +2 -3
  2. mesa/agent.py +116 -85
  3. mesa/batchrunner.py +22 -23
  4. mesa/cookiecutter-mesa/hooks/post_gen_project.py +2 -0
  5. mesa/cookiecutter-mesa/{{cookiecutter.snake}}/{{cookiecutter.snake}}/__init__.py +1 -0
  6. mesa/datacollection.py +138 -27
  7. mesa/experimental/UserParam.py +17 -6
  8. mesa/experimental/__init__.py +2 -0
  9. mesa/experimental/cell_space/__init__.py +14 -1
  10. mesa/experimental/cell_space/cell.py +84 -23
  11. mesa/experimental/cell_space/cell_agent.py +117 -21
  12. mesa/experimental/cell_space/cell_collection.py +54 -17
  13. mesa/experimental/cell_space/discrete_space.py +79 -7
  14. mesa/experimental/cell_space/grid.py +19 -8
  15. mesa/experimental/cell_space/network.py +9 -7
  16. mesa/experimental/cell_space/voronoi.py +26 -33
  17. mesa/experimental/components/altair.py +10 -0
  18. mesa/experimental/components/matplotlib.py +18 -0
  19. mesa/experimental/devs/__init__.py +2 -0
  20. mesa/experimental/devs/eventlist.py +36 -15
  21. mesa/experimental/devs/examples/epstein_civil_violence.py +65 -29
  22. mesa/experimental/devs/examples/wolf_sheep.py +40 -35
  23. mesa/experimental/devs/simulator.py +55 -15
  24. mesa/experimental/solara_viz.py +10 -19
  25. mesa/main.py +6 -4
  26. mesa/model.py +51 -54
  27. mesa/space.py +145 -120
  28. mesa/time.py +57 -67
  29. mesa/visualization/UserParam.py +19 -6
  30. mesa/visualization/__init__.py +3 -2
  31. mesa/visualization/components/altair.py +4 -2
  32. mesa/visualization/components/matplotlib.py +176 -85
  33. mesa/visualization/solara_viz.py +167 -84
  34. mesa/visualization/utils.py +3 -1
  35. {mesa-3.0.0a4.dist-info → mesa-3.0.0b0.dist-info}/METADATA +55 -13
  36. mesa-3.0.0b0.dist-info/RECORD +45 -0
  37. mesa-3.0.0b0.dist-info/licenses/LICENSE +202 -0
  38. mesa-3.0.0a4.dist-info/licenses/LICENSE → mesa-3.0.0b0.dist-info/licenses/NOTICE +2 -2
  39. mesa-3.0.0a4.dist-info/RECORD +0 -44
  40. {mesa-3.0.0a4.dist-info → mesa-3.0.0b0.dist-info}/WHEEL +0 -0
  41. {mesa-3.0.0a4.dist-info → mesa-3.0.0b0.dist-info}/entry_points.txt +0 -0
@@ -1,5 +1,4 @@
1
- """
2
- Mesa visualization module for creating interactive model visualizations.
1
+ """Mesa visualization module for creating interactive model visualizations.
3
2
 
4
3
  This module provides components to create browser- and Jupyter notebook-based visualizations of
5
4
  Mesa models, allowing users to watch models run step-by-step and interact with model parameters.
@@ -8,7 +7,6 @@ Key features:
8
7
  - SolaraViz: Main component for creating visualizations, supporting grid displays and plots
9
8
  - ModelController: Handles model execution controls (step, play, pause, reset)
10
9
  - UserInputs: Generates UI elements for adjusting model parameters
11
- - Card: Renders individual visualization elements (space, measures)
12
10
 
13
11
  The module uses Solara for rendering in Jupyter notebooks or as standalone web applications.
14
12
  It supports various types of visualizations including matplotlib plots, agent grids, and
@@ -23,10 +21,14 @@ Usage:
23
21
  See the Visualization Tutorial and example models for more details.
24
22
  """
25
23
 
24
+ from __future__ import annotations
25
+
26
+ import asyncio
26
27
  import copy
27
- import time
28
+ from collections.abc import Callable
28
29
  from typing import TYPE_CHECKING, Literal
29
30
 
31
+ import reacton.core
30
32
  import solara
31
33
  from solara.alias import rv
32
34
 
@@ -44,8 +46,7 @@ if TYPE_CHECKING:
44
46
  def Card(
45
47
  model, measures, agent_portrayal, space_drawer, dependencies, color, layout_type
46
48
  ):
47
- """
48
- Create a card component for visualizing model space or measures.
49
+ """Create a card component for visualizing model space or measures.
49
50
 
50
51
  Args:
51
52
  model: The Mesa model instance
@@ -91,21 +92,57 @@ def Card(
91
92
 
92
93
  @solara.component
93
94
  def SolaraViz(
94
- model: "Model" | solara.Reactive["Model"],
95
- components: list[solara.component] | Literal["default"] = "default",
96
- *args,
97
- play_interval=100,
95
+ model: Model | solara.Reactive[Model],
96
+ components: list[reacton.core.Component]
97
+ | list[Callable[[Model], reacton.core.Component]]
98
+ | Literal["default"] = "default",
99
+ play_interval: int = 100,
98
100
  model_params=None,
99
- seed=0,
101
+ seed: float = 0,
100
102
  name: str | None = None,
101
103
  ):
102
- update_counter.get()
104
+ """Solara visualization component.
105
+
106
+ This component provides a visualization interface for a given model using Solara.
107
+ It supports various visualization components and allows for interactive model
108
+ stepping and parameter adjustments.
109
+
110
+ Args:
111
+ model (Model | solara.Reactive[Model]): A Model instance or a reactive Model.
112
+ This is the main model to be visualized. If a non-reactive model is provided,
113
+ it will be converted to a reactive model.
114
+ components (list[solara.component] | Literal["default"], optional): List of solara
115
+ components or functions that return a solara component.
116
+ These components are used to render different parts of the model visualization.
117
+ Defaults to "default", which uses the default Altair space visualization.
118
+ play_interval (int, optional): Interval for playing the model steps in milliseconds.
119
+ This controls the speed of the model's automatic stepping. Defaults to 100 ms.
120
+ model_params (dict, optional): Parameters for (re-)instantiating a model.
121
+ Can include user-adjustable parameters and fixed parameters. Defaults to None.
122
+ seed (int, optional): Seed for the random number generator. This ensures reproducibility
123
+ of the model's behavior. Defaults to 0.
124
+ name (str | None, optional): Name of the visualization. Defaults to the models class name.
125
+
126
+ Returns:
127
+ solara.component: A Solara component that renders the visualization interface for the model.
128
+
129
+ Example:
130
+ >>> model = MyModel()
131
+ >>> page = SolaraViz(model)
132
+ >>> page
133
+
134
+ Notes:
135
+ - The `model` argument can be either a direct model instance or a reactive model. If a direct
136
+ model instance is provided, it will be converted to a reactive model using `solara.use_reactive`.
137
+ - The `play_interval` argument controls the speed of the model's automatic stepping. A lower
138
+ value results in faster stepping, while a higher value results in slower stepping.
139
+ """
103
140
  if components == "default":
104
141
  components = [components_altair.make_space_altair()]
105
142
 
106
143
  # Convert model to reactive
107
144
  if not isinstance(model, solara.Reactive):
108
- model = solara.use_reactive(model)
145
+ model = solara.use_reactive(model) # noqa: SH102, RUF100
109
146
 
110
147
  def connect_to_model():
111
148
  # Patch the step function to force updates
@@ -125,41 +162,70 @@ def SolaraViz(
125
162
  with solara.AppBar():
126
163
  solara.AppBarTitle(name if name else model.value.__class__.__name__)
127
164
 
128
- with solara.Sidebar():
129
- with solara.Card("Controls", margin=1, elevation=2):
130
- if model_params is not None:
165
+ with solara.Sidebar(), solara.Column():
166
+ with solara.Card("Controls"):
167
+ ModelController(model, play_interval)
168
+
169
+ if model_params is not None:
170
+ with solara.Card("Model Parameters"):
131
171
  ModelCreator(
132
172
  model,
133
173
  model_params,
134
174
  seed=seed,
135
175
  )
136
- ModelController(model, play_interval)
137
- with solara.Card("Information", margin=1, elevation=2):
176
+ with solara.Card("Information"):
138
177
  ShowSteps(model.value)
139
178
 
140
- solara.Column(
141
- [
142
- *(component(model.value) for component in components),
143
- ]
144
- )
179
+ ComponentsView(components, model.value)
145
180
 
146
181
 
147
- JupyterViz = SolaraViz
182
+ def _wrap_component(
183
+ component: reacton.core.Component | Callable[[Model], reacton.core.Component],
184
+ ) -> reacton.core.Component:
185
+ """Wrap a component in an auto-updated Solara component if needed."""
186
+ if isinstance(component, reacton.core.Component):
187
+ return component
188
+
189
+ @solara.component
190
+ def WrappedComponent(model):
191
+ update_counter.get()
192
+ return component(model)
193
+
194
+ return WrappedComponent
148
195
 
149
196
 
150
197
  @solara.component
151
- def ModelController(model: solara.Reactive["Model"], play_interval=100):
152
- """
153
- Create controls for model execution (step, play, pause, reset).
198
+ def ComponentsView(
199
+ components: list[reacton.core.Component]
200
+ | list[Callable[[Model], reacton.core.Component]],
201
+ model: Model,
202
+ ):
203
+ """Display a list of components.
154
204
 
155
205
  Args:
156
- model: The reactive model being visualized
157
- play_interval: Interval between steps during play
206
+ components: List of components to display
207
+ model: Model instance to pass to each component
158
208
  """
159
- if not isinstance(model, solara.Reactive):
160
- model = solara.use_reactive(model)
209
+ wrapped_components = [_wrap_component(component) for component in components]
210
+
211
+ with solara.Column():
212
+ for component in wrapped_components:
213
+ component(model)
214
+
215
+
216
+ JupyterViz = SolaraViz
161
217
 
218
+
219
+ @solara.component
220
+ def ModelController(model: solara.Reactive[Model], play_interval=100):
221
+ """Create controls for model execution (step, play, pause, reset).
222
+
223
+ Args:
224
+ model (solara.Reactive[Model]): Reactive model instance
225
+ play_interval (int, optional): Interval for playing the model steps in milliseconds.
226
+ """
162
227
  playing = solara.use_reactive(False)
228
+ running = solara.use_reactive(True)
163
229
  original_model = solara.use_reactive(None)
164
230
 
165
231
  def save_initial_model():
@@ -170,40 +236,48 @@ def ModelController(model: solara.Reactive["Model"], play_interval=100):
170
236
 
171
237
  solara.use_effect(save_initial_model, [model.value])
172
238
 
173
- def step():
174
- while playing.value:
175
- time.sleep(play_interval / 1000)
239
+ async def step():
240
+ while playing.value and running.value:
241
+ await asyncio.sleep(play_interval / 1000)
176
242
  do_step()
177
243
 
178
- solara.use_thread(step, [playing.value])
244
+ solara.lab.use_task(
245
+ step, dependencies=[playing.value, running.value], prefer_threaded=False
246
+ )
179
247
 
180
248
  def do_step():
181
249
  """Advance the model by one step."""
182
250
  model.value.step()
183
-
184
- def do_play():
185
- """Run the model continuously."""
186
- playing.value = True
187
-
188
- def do_pause():
189
- """Pause the model execution."""
190
- playing.value = False
251
+ running.value = model.value.running
191
252
 
192
253
  def do_reset():
193
254
  """Reset the model to its initial state."""
194
255
  playing.value = False
256
+ running.value = True
195
257
  model.value = copy.deepcopy(original_model.value)
196
258
 
259
+ def do_play_pause():
260
+ """Toggle play/pause."""
261
+ playing.value = not playing.value
262
+
197
263
  with solara.Row(justify="space-between"):
198
264
  solara.Button(label="Reset", color="primary", on_click=do_reset)
199
- solara.Button(label="Step", color="primary", on_click=do_step)
200
- solara.Button(label="▶", color="primary", on_click=do_play)
201
- solara.Button(label="⏸︎", color="primary", on_click=do_pause)
265
+ solara.Button(
266
+ label="▶" if not playing.value else "❚❚",
267
+ color="primary",
268
+ on_click=do_play_pause,
269
+ disabled=not running.value,
270
+ )
271
+ solara.Button(
272
+ label="Step",
273
+ color="primary",
274
+ on_click=do_step,
275
+ disabled=playing.value or not running.value,
276
+ )
202
277
 
203
278
 
204
279
  def split_model_params(model_params):
205
- """
206
- Split model parameters into user-adjustable and fixed parameters.
280
+ """Split model parameters into user-adjustable and fixed parameters.
207
281
 
208
282
  Args:
209
283
  model_params: Dictionary of all model parameters
@@ -222,8 +296,7 @@ def split_model_params(model_params):
222
296
 
223
297
 
224
298
  def check_param_is_fixed(param):
225
- """
226
- Check if a parameter is fixed (not user-adjustable).
299
+ """Check if a parameter is fixed (not user-adjustable).
227
300
 
228
301
  Args:
229
302
  param: Parameter to check
@@ -241,6 +314,36 @@ def check_param_is_fixed(param):
241
314
 
242
315
  @solara.component
243
316
  def ModelCreator(model, model_params, seed=1):
317
+ """Solara component for creating and managing a model instance with user-defined parameters.
318
+
319
+ This component allows users to create a model instance with specified parameters and seed.
320
+ It provides an interface for adjusting model parameters and reseeding the model's random
321
+ number generator.
322
+
323
+ Args:
324
+ model (solara.Reactive[Model]): A reactive model instance. This is the main model to be created and managed.
325
+ model_params (dict): Dictionary of model parameters. This includes both user-adjustable parameters and fixed parameters.
326
+ seed (int, optional): Initial seed for the random number generator. Defaults to 1.
327
+
328
+ Returns:
329
+ solara.component: A Solara component that renders the model creation and management interface.
330
+
331
+ Example:
332
+ >>> model = solara.reactive(MyModel())
333
+ >>> model_params = {
334
+ >>> "param1": {"type": "slider", "value": 10, "min": 0, "max": 100},
335
+ >>> "param2": {"type": "slider", "value": 5, "min": 1, "max": 10},
336
+ >>> }
337
+ >>> creator = ModelCreator(model, model_params)
338
+ >>> creator
339
+
340
+ Notes:
341
+ - The `model_params` argument should be a dictionary where keys are parameter names and values either fixed values
342
+ or are dictionaries containing parameter details such as type, value, min, and max.
343
+ - The `seed` argument ensures reproducibility by setting the initial seed for the model's random number generator.
344
+ - The component provides an interface for adjusting user-defined parameters and reseeding the model.
345
+
346
+ """
244
347
  user_params, fixed_params = split_model_params(model_params)
245
348
 
246
349
  reactive_seed = solara.use_reactive(seed)
@@ -260,37 +363,34 @@ def ModelCreator(model, model_params, seed=1):
260
363
  set_model_parameters({**model_parameters, name: value})
261
364
 
262
365
  def create_model():
263
- model.value = model.value.__class__.__new__(
264
- model.value.__class__, **model_parameters, seed=reactive_seed.value
265
- )
266
- model.value.__init__(**model_parameters)
366
+ model.value = model.value.__class__(**model_parameters)
367
+ model.value._seed = reactive_seed.value
267
368
 
268
369
  solara.use_effect(create_model, [model_parameters, reactive_seed.value])
269
370
 
270
- solara.InputText(
271
- label="Seed",
272
- value=reactive_seed,
273
- continuous_update=True,
274
- )
371
+ with solara.Row(justify="space-between"):
372
+ solara.InputText(
373
+ label="Seed",
374
+ value=reactive_seed,
375
+ continuous_update=True,
376
+ )
275
377
 
276
- solara.Button(label="Reseed", color="primary", on_click=do_reseed)
378
+ solara.Button(label="Reseed", color="primary", on_click=do_reseed)
277
379
 
278
380
  UserInputs(user_params, on_change=on_change)
279
381
 
280
382
 
281
383
  @solara.component
282
384
  def UserInputs(user_params, on_change=None):
283
- """
284
- Initialize user inputs for configurable model parameters.
385
+ """Initialize user inputs for configurable model parameters.
386
+
285
387
  Currently supports :class:`solara.SliderInt`, :class:`solara.SliderFloat`,
286
388
  :class:`solara.Select`, and :class:`solara.Checkbox`.
287
389
 
288
390
  Args:
289
- user_params: Dictionary with options for the input, including label,
290
- min and max values, and other fields specific to the input type.
391
+ user_params: Dictionary with options for the input, including label, min and max values, and other fields specific to the input type.
291
392
  on_change: Function to be called with (name, value) when the value of an input changes.
292
393
  """
293
-
294
394
  for name, options in user_params.items():
295
395
 
296
396
  def change_handler(value, name=name):
@@ -348,26 +448,8 @@ def UserInputs(user_params, on_change=None):
348
448
  raise ValueError(f"{input_type} is not a supported input type")
349
449
 
350
450
 
351
- def make_text(renderer):
352
- """
353
- Create a function that renders text using Markdown.
354
-
355
- Args:
356
- renderer: Function that takes a model and returns a string
357
-
358
- Returns:
359
- function: A function that renders the text as Markdown
360
- """
361
-
362
- def function(model):
363
- solara.Markdown(renderer(model))
364
-
365
- return function
366
-
367
-
368
451
  def make_initial_grid_layout(layout_types):
369
- """
370
- Create an initial grid layout for visualization components.
452
+ """Create an initial grid layout for visualization components.
371
453
 
372
454
  Args:
373
455
  layout_types: List of layout types (Space or Measure)
@@ -390,5 +472,6 @@ def make_initial_grid_layout(layout_types):
390
472
 
391
473
  @solara.component
392
474
  def ShowSteps(model):
475
+ """Display the current step of the model."""
393
476
  update_counter.get()
394
477
  return solara.Text(f"Step: {model.steps}")
@@ -1,7 +1,9 @@
1
+ """Solara related utils."""
2
+
1
3
  import solara
2
4
 
3
5
  update_counter = solara.reactive(0)
4
6
 
5
7
 
6
- def force_update():
8
+ def force_update(): # noqa: D103
7
9
  update_counter.value += 1
@@ -1,12 +1,13 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: Mesa
3
- Version: 3.0.0a4
3
+ Version: 3.0.0b0
4
4
  Summary: Agent-based modeling (ABM) in Python
5
5
  Project-URL: homepage, https://github.com/projectmesa/mesa
6
6
  Project-URL: repository, https://github.com/projectmesa/mesa
7
7
  Author-email: Project Mesa Team <projectmesa@googlegroups.com>
8
8
  License: Apache 2.0
9
9
  License-File: LICENSE
10
+ License-File: NOTICE
10
11
  Keywords: ABM,agent,based,model,modeling,multi-agent,simulation
11
12
  Classifier: Development Status :: 3 - Alpha
12
13
  Classifier: Intended Audience :: Science/Research
@@ -22,30 +23,60 @@ Classifier: Topic :: Scientific/Engineering
22
23
  Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
23
24
  Classifier: Topic :: Scientific/Engineering :: Artificial Life
24
25
  Requires-Python: >=3.10
25
- Requires-Dist: click
26
- Requires-Dist: cookiecutter
27
- Requires-Dist: matplotlib
28
- Requires-Dist: networkx
29
26
  Requires-Dist: numpy
30
27
  Requires-Dist: pandas
31
- Requires-Dist: solara
32
28
  Requires-Dist: tqdm
29
+ Provides-Extra: all
30
+ Requires-Dist: cookiecutter; extra == 'all'
31
+ Requires-Dist: ipython; extra == 'all'
32
+ Requires-Dist: matplotlib; extra == 'all'
33
+ Requires-Dist: myst-nb; extra == 'all'
34
+ Requires-Dist: myst-parser; extra == 'all'
35
+ Requires-Dist: networkx; extra == 'all'
36
+ Requires-Dist: pydata-sphinx-theme; extra == 'all'
37
+ Requires-Dist: pytest; extra == 'all'
38
+ Requires-Dist: pytest-cov; extra == 'all'
39
+ Requires-Dist: pytest-mock; extra == 'all'
40
+ Requires-Dist: ruff; extra == 'all'
41
+ Requires-Dist: scipy; extra == 'all'
42
+ Requires-Dist: seaborn; extra == 'all'
43
+ Requires-Dist: solara; extra == 'all'
44
+ Requires-Dist: sphinx; extra == 'all'
33
45
  Provides-Extra: dev
46
+ Requires-Dist: cookiecutter; extra == 'dev'
47
+ Requires-Dist: matplotlib; extra == 'dev'
48
+ Requires-Dist: networkx; extra == 'dev'
49
+ Requires-Dist: pytest; extra == 'dev'
34
50
  Requires-Dist: pytest-cov; extra == 'dev'
35
51
  Requires-Dist: pytest-mock; extra == 'dev'
36
- Requires-Dist: pytest>=4.6; extra == 'dev'
37
- Requires-Dist: ruff~=0.1.1; extra == 'dev'
52
+ Requires-Dist: ruff; extra == 'dev'
53
+ Requires-Dist: solara; extra == 'dev'
38
54
  Requires-Dist: sphinx; extra == 'dev'
39
55
  Provides-Extra: docs
40
56
  Requires-Dist: ipython; extra == 'docs'
57
+ Requires-Dist: matplotlib; extra == 'docs'
41
58
  Requires-Dist: myst-nb; extra == 'docs'
42
59
  Requires-Dist: myst-parser; extra == 'docs'
60
+ Requires-Dist: networkx; extra == 'docs'
43
61
  Requires-Dist: pydata-sphinx-theme; extra == 'docs'
44
62
  Requires-Dist: seaborn; extra == 'docs'
63
+ Requires-Dist: solara; extra == 'docs'
45
64
  Requires-Dist: sphinx; extra == 'docs'
46
65
  Provides-Extra: examples
47
- Requires-Dist: pytest>=4.6; extra == 'examples'
66
+ Requires-Dist: matplotlib; extra == 'examples'
67
+ Requires-Dist: networkx; extra == 'examples'
68
+ Requires-Dist: pytest; extra == 'examples'
48
69
  Requires-Dist: scipy; extra == 'examples'
70
+ Requires-Dist: solara; extra == 'examples'
71
+ Provides-Extra: network
72
+ Requires-Dist: networkx; extra == 'network'
73
+ Provides-Extra: rec
74
+ Requires-Dist: matplotlib; extra == 'rec'
75
+ Requires-Dist: networkx; extra == 'rec'
76
+ Requires-Dist: solara; extra == 'rec'
77
+ Provides-Extra: viz
78
+ Requires-Dist: matplotlib; extra == 'viz'
79
+ Requires-Dist: solara; extra == 'viz'
49
80
  Description-Content-Type: text/markdown
50
81
 
51
82
  # Mesa: Agent-based modeling in Python
@@ -78,7 +109,7 @@ can be displayed in browser windows or Jupyter.*
78
109
 
79
110
  ## Using Mesa
80
111
 
81
- To install our latest stable release (2.3.x), run:
112
+ To install our latest stable release (2.4.x), run:
82
113
 
83
114
  ``` bash
84
115
  pip install -U mesa
@@ -89,6 +120,17 @@ To install our latest pre-release (3.0.0 alpha), run:
89
120
  ``` bash
90
121
  pip install -U --pre mesa
91
122
  ```
123
+ With Mesa 3.0, we don't install all our dependencies anymore by default.
124
+ ```bash
125
+ # You can customize the additional dependencies you need, if you want. Available are:
126
+ pip install -U --pre mesa[network,viz]
127
+
128
+ # This is equivalent to our recommended dependencies:
129
+ pip install -U --pre mesa[rec]
130
+
131
+ # To install all, including developer, dependencies:
132
+ pip install -U --pre mesa[all]
133
+ ```
92
134
 
93
135
  You can also use `pip` to install the latest GitHub version:
94
136
 
@@ -107,13 +149,13 @@ For resources or help on using Mesa, check out the following:
107
149
 
108
150
  - [Intro to Mesa Tutorial](http://mesa.readthedocs.org/en/stable/tutorials/intro_tutorial.html) (An introductory model, the Boltzmann
109
151
  Wealth Model, for beginners or those new to Mesa.)
110
- - [Visualization Tutorial](https://mesa.readthedocs.io/en/stable/tutorials/visualization_tutorial.html) (An introduction into our Solara visualization)
152
+ - [Visualization Tutorial](https://mesa.readthedocs.io/stable/tutorials/visualization_tutorial.html) (An introduction into our Solara visualization)
111
153
  - [Complexity Explorer Tutorial](https://www.complexityexplorer.org/courses/172-agent-based-models-with-python-an-introduction-to-mesa) (An advanced-beginner model,
112
154
  SugarScape with Traders, with instructional videos)
113
- - [Mesa Examples](https://github.com/projectmesa/mesa-examples/tree/main/examples) (A repository of seminal ABMs using Mesa and
155
+ - [Mesa Examples](https://github.com/projectmesa/mesa-examples) (A repository of seminal ABMs using Mesa and
114
156
  examples of employing specific Mesa Features)
115
157
  - [Docs](http://mesa.readthedocs.org/) (Mesa's documentation, API and useful snippets)
116
- - [Development version docs](https://mesa.readthedocs.io/en/latest/) (the latest version docs if you're using a pre-release Mesa version)
158
+ - [Development version docs](https://mesa.readthedocs.io/latest/) (the latest version docs if you're using a pre-release Mesa version)
117
159
  - [Discussions](https://github.com/projectmesa/mesa/discussions) (GitHub threaded discussions about Mesa)
118
160
  - [Matrix Chat](https://matrix.to/#/#project-mesa:matrix.org) (Chat Forum via Matrix to talk about Mesa)
119
161
 
@@ -0,0 +1,45 @@
1
+ mesa/__init__.py,sha256=GM836SFDxNMX8ePHbGQt5Yi4G3jiYLyOb3f-AUDLmaQ,618
2
+ mesa/agent.py,sha256=XeBMwbq7Ruhbt6xj9PPEDuDMtO185Bff9dOFagUxiq8,24254
3
+ mesa/batchrunner.py,sha256=0AqTcvjWNPp1aqn7zuUKSovx6Rnkk4M-KouCZ4Guqy0,6419
4
+ mesa/datacollection.py,sha256=xyb07aBpd-HSDh5bk-XcVqGiDu5bfaLlxj5eDlGIwqY,16138
5
+ mesa/main.py,sha256=_KgeVGbi0znzezjjoM09vhGdyaqcuDEwb9M7vH2c_O4,1668
6
+ mesa/model.py,sha256=zMs5_ZlLity7hYcrwhz1BY1ysK3y3aQa9hf1KIoxryM,7845
7
+ mesa/space.py,sha256=1sVl78o5lYP6aEg32QIb9-tcv3V3UeFdC7A_h_8CgO8,62838
8
+ mesa/time.py,sha256=FaVqRwWWdFH6iagfXrdmCN7YSvRpDmikyzfz6GJ8yU4,14977
9
+ mesa/cookiecutter-mesa/cookiecutter.json,sha256=tBSWli39fOWUXGfiDCTKd92M7uKaBIswXbkOdbUufYY,337
10
+ mesa/cookiecutter-mesa/hooks/post_gen_project.py,sha256=UKz12l6mKc7fILK0MvV5djsTKwkmD4DlH8LYjFO8ehI,316
11
+ mesa/cookiecutter-mesa/{{cookiecutter.snake}}/README.md,sha256=Yji4lGY-NtQSnW-oBj0_Jhs-XhCfZA8R1mBBM_IllGs,80
12
+ mesa/cookiecutter-mesa/{{cookiecutter.snake}}/app.pytemplate,sha256=36f9k9CH6TK6VrXsPvTFXGUfCKzCLwgYTeK-Gt27GNg,584
13
+ mesa/cookiecutter-mesa/{{cookiecutter.snake}}/setup.pytemplate,sha256=UtRpLM_CkeUZRec-Ef_LiO_x7SKaWN11fOiH9T1UmTw,214
14
+ mesa/cookiecutter-mesa/{{cookiecutter.snake}}/{{cookiecutter.snake}}/__init__.py,sha256=WgJccMfsAlD_mA3zTBPJVHadF3FtO8xgi8SPKORzyMs,22
15
+ mesa/cookiecutter-mesa/{{cookiecutter.snake}}/{{cookiecutter.snake}}/model.pytemplate,sha256=Aml4Z6E1yj7E7DtHNSUqnKNRUdkxG9WWtJyW8fkxCng,1870
16
+ mesa/experimental/UserParam.py,sha256=f32nmFjroe76HpxU75ZCEOqFW2nAsDfmqIf8kQ1zt-E,2086
17
+ mesa/experimental/__init__.py,sha256=1hxkjcZvdJhhQx4iLlTTUAPs_SqRyN-us4qR8U6JKkw,209
18
+ mesa/experimental/solara_viz.py,sha256=uWrNQAX3oEWSftmyjNorN839dBCUp86hnhpL704dyGQ,15212
19
+ mesa/experimental/cell_space/__init__.py,sha256=-NtSCT7mA-aszLSAdqbICGqeFe2vBdb-GrcW562legY,999
20
+ mesa/experimental/cell_space/cell.py,sha256=lR1lz9hMlfKsDoRzSPCqb0XTk2VIEFqxIiN_zwUaUUo,6738
21
+ mesa/experimental/cell_space/cell_agent.py,sha256=jvYOV9OIaBaqAsAG0YLV64X_f3BJe_wP7qfos_RXi0Y,3759
22
+ mesa/experimental/cell_space/cell_collection.py,sha256=ZcyuPEevCZEXW7jFnX6StjBMw4UBDQvUspZRcFi2dFg,3426
23
+ mesa/experimental/cell_space/discrete_space.py,sha256=bl8jmYnOLFaF5_0Wh7BFQetXr53cS-SNLzHTjtkOnVY,4845
24
+ mesa/experimental/cell_space/grid.py,sha256=WT9AtQCgPzV8VonX0oSPRXgZNXoOR_mVgEAEOp5I4YA,7319
25
+ mesa/experimental/cell_space/network.py,sha256=hzhxGipRyM1PWOQFlPz--tc3pA_RRBT8Xq4pXHx5sD8,1252
26
+ mesa/experimental/cell_space/voronoi.py,sha256=lSY8zQhELvOy0RfDyZIek09UMwY9_20UY9SPqFWsNoM,10014
27
+ mesa/experimental/components/altair.py,sha256=49OHgrm1JncfrKqDfw_5ifPtsbMKdgVYCacL9SMwucc,2624
28
+ mesa/experimental/components/matplotlib.py,sha256=j477UBk_7yW5vzT3rjhnuTixpA7PedDNghoK9TLgHVY,8043
29
+ mesa/experimental/devs/__init__.py,sha256=EByaC66ikUIu9G9p1geLm6ESEMWZOPTO9r9627S83j0,211
30
+ mesa/experimental/devs/eventlist.py,sha256=Trvc5S-NG5B792uuk_cY8Q_5Rw99zioUYDQXcXWVuCo,5972
31
+ mesa/experimental/devs/simulator.py,sha256=wvqkLIDgbJNaem9nwMacyEYRp0W3ai5Oxptw3-QmbSw,10595
32
+ mesa/experimental/devs/examples/epstein_civil_violence.py,sha256=E8YSV3O5ihKsntGtnltHM-4IyS8eg2DSRUqmIiw_1iU,10916
33
+ mesa/experimental/devs/examples/wolf_sheep.py,sha256=1eb1CfYNQoprqSJat-LPYPvwWH1ENQdj39viEqwSk0s,8103
34
+ mesa/visualization/UserParam.py,sha256=Dl2WOwLYLf0pfLpabCZtIdFRyKZrK6Qtc3utZx5GPYg,2139
35
+ mesa/visualization/__init__.py,sha256=sa8lqeLcDtte19SMzFiKP6K4CrVLxAPwrhDu_AsDWTs,395
36
+ mesa/visualization/solara_viz.py,sha256=6Gq4r4-XFt9AG6G-v2Gvz_W-ykTC4gP0OQnqtYIhAxw,16717
37
+ mesa/visualization/utils.py,sha256=lJHgRKF5BHLf72Tw3YpwyiWuRoIimaTKQ7xBCw_Rx3A,146
38
+ mesa/visualization/components/altair.py,sha256=E-iblqpWhx72qrjkNz4Ie9c66Hh1OFpLVjuDIg9m2sA,2804
39
+ mesa/visualization/components/matplotlib.py,sha256=6ttFOxfNj3YdNu7c1NB0YP6-F7Chy0Qq0kkMe02TF8c,11697
40
+ mesa-3.0.0b0.dist-info/METADATA,sha256=iqC2Ea-eu6tKAs5lwnnHS7Zoimp6ifPO8cJBb4o65UQ,9937
41
+ mesa-3.0.0b0.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
42
+ mesa-3.0.0b0.dist-info/entry_points.txt,sha256=IOcQtetGF8l4wHpOs_hGb19Rz-FS__BMXOJR10IBPsA,39
43
+ mesa-3.0.0b0.dist-info/licenses/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
44
+ mesa-3.0.0b0.dist-info/licenses/NOTICE,sha256=GbsWoK0QWv1JyZ_xer2s-jNilv0RtWl-0UrtlJANHPg,578
45
+ mesa-3.0.0b0.dist-info/RECORD,,