Mesa 3.0.0a4__py3-none-any.whl → 3.0.0a5__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 (40) hide show
  1. mesa/__init__.py +2 -3
  2. mesa/agent.py +106 -61
  3. mesa/batchrunner.py +15 -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 +7 -0
  10. mesa/experimental/cell_space/cell.py +61 -20
  11. mesa/experimental/cell_space/cell_agent.py +10 -5
  12. mesa/experimental/cell_space/cell_collection.py +54 -17
  13. mesa/experimental/cell_space/discrete_space.py +16 -5
  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 +38 -34
  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 +43 -45
  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 +6 -4
  33. mesa/visualization/solara_viz.py +157 -83
  34. mesa/visualization/utils.py +3 -1
  35. {mesa-3.0.0a4.dist-info → mesa-3.0.0a5.dist-info}/METADATA +1 -1
  36. mesa-3.0.0a5.dist-info/RECORD +44 -0
  37. mesa-3.0.0a4.dist-info/RECORD +0 -44
  38. {mesa-3.0.0a4.dist-info → mesa-3.0.0a5.dist-info}/WHEEL +0 -0
  39. {mesa-3.0.0a4.dist-info → mesa-3.0.0a5.dist-info}/entry_points.txt +0 -0
  40. {mesa-3.0.0a4.dist-info → mesa-3.0.0a5.dist-info}/licenses/LICENSE +0 -0
@@ -1,3 +1,5 @@
1
+ """Epstein civil violence example using ABMSimulator."""
2
+
1
3
  import enum
2
4
  import math
3
5
 
@@ -7,21 +9,32 @@ from mesa.space import SingleGrid
7
9
 
8
10
 
9
11
  class EpsteinAgent(Agent):
12
+ """Epstein Agent."""
13
+
10
14
  def __init__(self, model, vision, movement):
15
+ """Initialize the agent.
16
+
17
+ Args:
18
+ model: a model instance
19
+ vision: size of neighborhood
20
+ movement: boolean whether agent can move or not
21
+ """
11
22
  super().__init__(model)
12
23
  self.vision = vision
13
24
  self.movement = movement
14
25
 
15
26
 
16
27
  class AgentState(enum.IntEnum):
28
+ """Agent states."""
29
+
17
30
  QUIESCENT = enum.auto()
18
31
  ARRESTED = enum.auto()
19
32
  ACTIVE = enum.auto()
20
33
 
21
34
 
22
35
  class Citizen(EpsteinAgent):
23
- """
24
- A member of the general population, may or may not be in active rebellion.
36
+ """A member of the general population, may or may not be in active rebellion.
37
+
25
38
  Summary of rule: If grievance - risk > threshold, rebel.
26
39
 
27
40
  Attributes:
@@ -55,10 +68,13 @@ class Citizen(EpsteinAgent):
55
68
  threshold,
56
69
  arrest_prob_constant,
57
70
  ):
58
- """
59
- Create a new Citizen.
71
+ """Create a new Citizen.
72
+
60
73
  Args:
61
74
  model : model instance
75
+ vision: number of cells in each direction (N, S, E and W) that
76
+ agent can inspect. Exogenous.
77
+ movement: whether agent can move or not
62
78
  hardship: Agent's 'perceived hardship (i.e., physical or economic
63
79
  privation).' Exogenous, drawn from U(0,1).
64
80
  regime_legitimacy: Agent's perception of regime legitimacy, equal
@@ -66,8 +82,8 @@ class Citizen(EpsteinAgent):
66
82
  risk_aversion: Exogenous, drawn from U(0,1).
67
83
  threshold: if (grievance - (risk_aversion * arrest_probability)) >
68
84
  threshold, go/remain Active
69
- vision: number of cells in each direction (N, S, E and W) that
70
- agent can inspect. Exogenous.
85
+ arrest_prob_constant : agent's assessment of arrest probability
86
+
71
87
  """
72
88
  super().__init__(model, vision, movement)
73
89
  self.hardship = hardship
@@ -80,9 +96,7 @@ class Citizen(EpsteinAgent):
80
96
  self.arrest_prob_constant = arrest_prob_constant
81
97
 
82
98
  def step(self):
83
- """
84
- Decide whether to activate, then move if applicable.
85
- """
99
+ """Decide whether to activate, then move if applicable."""
86
100
  self.update_neighbors()
87
101
  self.update_estimated_arrest_probability()
88
102
  net_risk = self.risk_aversion * self.arrest_probability
@@ -95,9 +109,7 @@ class Citizen(EpsteinAgent):
95
109
  self.model.grid.move_agent(self, new_pos)
96
110
 
97
111
  def update_neighbors(self):
98
- """
99
- Look around and see who my neighbors are
100
- """
112
+ """Look around and see who my neighbors are."""
101
113
  self.neighborhood = self.model.grid.get_neighborhood(
102
114
  self.pos, moore=True, radius=self.vision
103
115
  )
@@ -107,10 +119,7 @@ class Citizen(EpsteinAgent):
107
119
  ]
108
120
 
109
121
  def update_estimated_arrest_probability(self):
110
- """
111
- Based on the ratio of cops to actives in my neighborhood, estimate the
112
- p(Arrest | I go active).
113
- """
122
+ """Based on the ratio of cops to actives in my neighborhood, estimate the p(Arrest | I go active)."""
114
123
  cops_in_vision = len([c for c in self.neighbors if isinstance(c, Cop)])
115
124
  actives_in_vision = 1.0 # citizen counts herself
116
125
  for c in self.neighbors:
@@ -121,18 +130,25 @@ class Citizen(EpsteinAgent):
121
130
  )
122
131
 
123
132
  def sent_to_jail(self, value):
133
+ """Sent agent to jail.
134
+
135
+ Args:
136
+ value: duration of jail sentence
137
+
138
+ """
124
139
  self.model.active_agents.remove(self)
125
140
  self.condition = AgentState.ARRESTED
126
141
  self.model.simulator.schedule_event_relative(self.release_from_jail, value)
127
142
 
128
143
  def release_from_jail(self):
144
+ """Release agent from jail."""
129
145
  self.model.active_agents.add(self)
130
146
  self.condition = AgentState.QUIESCENT
131
147
 
132
148
 
133
149
  class Cop(EpsteinAgent):
134
- """
135
- A cop for life. No defection.
150
+ """A cop for life. No defection.
151
+
136
152
  Summary of rule: Inspect local vision and arrest a random active agent.
137
153
 
138
154
  Attributes:
@@ -143,14 +159,19 @@ class Cop(EpsteinAgent):
143
159
  """
144
160
 
145
161
  def __init__(self, model, vision, movement, max_jail_term):
162
+ """Initialize a Cop agent.
163
+
164
+ Args:
165
+ model: a model instance
166
+ vision: size of neighborhood
167
+ movement: whether agent can move or not
168
+ max_jail_term: maximum jail sentence
169
+ """
146
170
  super().__init__(model, vision, movement)
147
171
  self.max_jail_term = max_jail_term
148
172
 
149
173
  def step(self):
150
- """
151
- Inspect local vision and arrest a random active agent. Move if
152
- applicable.
153
- """
174
+ """Inspect local vision and arrest a random active agent. Move if applicable."""
154
175
  self.update_neighbors()
155
176
  active_neighbors = []
156
177
  for agent in self.neighbors:
@@ -164,9 +185,7 @@ class Cop(EpsteinAgent):
164
185
  self.model.grid.move_agent(self, new_pos)
165
186
 
166
187
  def update_neighbors(self):
167
- """
168
- Look around and see who my neighbors are.
169
- """
188
+ """Look around and see who my neighbors are."""
170
189
  self.neighborhood = self.model.grid.get_neighborhood(
171
190
  self.pos, moore=True, radius=self.vision
172
191
  )
@@ -177,9 +196,8 @@ class Cop(EpsteinAgent):
177
196
 
178
197
 
179
198
  class EpsteinCivilViolence(Model):
180
- """
181
- Model 1 from "Modeling civil violence: An agent-based computational
182
- approach," by Joshua Epstein.
199
+ """Model 1 from "Modeling civil violence: An agent-based computational approach," by Joshua Epstein.
200
+
183
201
  http://www.pnas.org/content/99/suppl_3/7243.full
184
202
  Attributes:
185
203
  height: grid height
@@ -218,6 +236,23 @@ class EpsteinCivilViolence(Model):
218
236
  max_iters=1000,
219
237
  seed=None,
220
238
  ):
239
+ """Initialize the Eppstein civil violence model.
240
+
241
+ Args:
242
+ width: the width of the grid
243
+ height: the height of the grid
244
+ citizen_density: density of citizens
245
+ cop_density: density of cops
246
+ citizen_vision: size of citizen vision
247
+ cop_vision: size of cop vision
248
+ legitimacy: perceived legitimacy
249
+ max_jail_term: maximum jail term
250
+ active_threshold: threshold for citizen to become active
251
+ arrest_prob_constant: arrest probability
252
+ movement: allow agent movement or not
253
+ max_iters: number of iterations
254
+ seed: seed for random number generator
255
+ """
221
256
  super().__init__(seed)
222
257
  if cop_density + citizen_density > 1:
223
258
  raise ValueError("Cop density + citizen density must be less than 1")
@@ -257,7 +292,8 @@ class EpsteinCivilViolence(Model):
257
292
  self.active_agents = self.agents
258
293
 
259
294
  def step(self):
260
- self.active_agents.shuffle(inplace=True).do("step")
295
+ """Run one step of the model."""
296
+ self.active_agents.shuffle_do("step")
261
297
 
262
298
 
263
299
  if __name__ == "__main__":
@@ -1,20 +1,22 @@
1
- """
2
- Wolf-Sheep Predation Model
3
- ================================
4
-
5
- Replication of the model found in NetLogo:
6
- Wilensky, U. (1997). NetLogo Wolf Sheep Predation model.
7
- http://ccl.northwestern.edu/netlogo/models/WolfSheepPredation.
8
- Center for Connected Learning and Computer-Based Modeling,
9
- Northwestern University, Evanston, IL.
10
- """
1
+ """Example of using ABM simulator for Wolf-Sheep Predation Model."""
11
2
 
12
3
  import mesa
13
4
  from mesa.experimental.devs.simulator import ABMSimulator
14
5
 
15
6
 
16
7
  class Animal(mesa.Agent):
8
+ """Base Animal class."""
9
+
17
10
  def __init__(self, model, moore, energy, p_reproduce, energy_from_food):
11
+ """Initialize Animal instance.
12
+
13
+ Args:
14
+ model: a model instance
15
+ moore: using moore grid or not
16
+ energy: initial energy
17
+ p_reproduce: probability of reproduction
18
+ energy_from_food: energy gained from 1 unit of food
19
+ """
18
20
  super().__init__(model)
19
21
  self.energy = energy
20
22
  self.p_reproduce = p_reproduce
@@ -22,12 +24,14 @@ class Animal(mesa.Agent):
22
24
  self.moore = moore
23
25
 
24
26
  def random_move(self):
27
+ """Move to random neighboring cell."""
25
28
  next_moves = self.model.grid.get_neighborhood(self.pos, self.moore, True)
26
29
  next_move = self.random.choice(next_moves)
27
30
  # Now move:
28
31
  self.model.grid.move_agent(self, next_move)
29
32
 
30
33
  def spawn_offspring(self):
34
+ """Create offspring."""
31
35
  self.energy /= 2
32
36
  offspring = self.__class__(
33
37
  self.model,
@@ -38,13 +42,15 @@ class Animal(mesa.Agent):
38
42
  )
39
43
  self.model.grid.place_agent(offspring, self.pos)
40
44
 
41
- def feed(self): ...
45
+ def feed(self): ... # noqa: D102
42
46
 
43
47
  def die(self):
48
+ """Die."""
44
49
  self.model.grid.remove_agent(self)
45
50
  self.remove()
46
51
 
47
52
  def step(self):
53
+ """Execute one step of the agent."""
48
54
  self.random_move()
49
55
  self.energy -= 1
50
56
 
@@ -57,13 +63,10 @@ class Animal(mesa.Agent):
57
63
 
58
64
 
59
65
  class Sheep(Animal):
60
- """
61
- A sheep that walks around, reproduces (asexually) and gets eaten.
62
-
63
- The init is the same as the RandomWalker.
64
- """
66
+ """A sheep that walks around, reproduces (asexually) and gets eaten."""
65
67
 
66
68
  def feed(self):
69
+ """Eat grass and gain energy."""
67
70
  # If there is grass available, eat it
68
71
  agents = self.model.grid.get_cell_list_contents(self.pos)
69
72
  grass_patch = next(obj for obj in agents if isinstance(obj, GrassPatch))
@@ -73,11 +76,10 @@ class Sheep(Animal):
73
76
 
74
77
 
75
78
  class Wolf(Animal):
76
- """
77
- A wolf that walks around, reproduces (asexually) and eats sheep.
78
- """
79
+ """A wolf that walks around, reproduces (asexually) and eats sheep."""
79
80
 
80
81
  def feed(self):
82
+ """Eat wolf and gain energy."""
81
83
  agents = self.model.grid.get_cell_list_contents(self.pos)
82
84
  sheep = [obj for obj in agents if isinstance(obj, Sheep)]
83
85
  if len(sheep) > 0:
@@ -89,12 +91,10 @@ class Wolf(Animal):
89
91
 
90
92
 
91
93
  class GrassPatch(mesa.Agent):
92
- """
93
- A patch of grass that grows at a fixed rate and it is eaten by sheep
94
- """
94
+ """A patch of grass that grows at a fixed rate and it is eaten by sheep."""
95
95
 
96
96
  @property
97
- def fully_grown(self) -> bool:
97
+ def fully_grown(self) -> bool: # noqa: D102
98
98
  return self._fully_grown
99
99
 
100
100
  @fully_grown.setter
@@ -109,12 +109,13 @@ class GrassPatch(mesa.Agent):
109
109
  )
110
110
 
111
111
  def __init__(self, model, fully_grown, countdown, grass_regrowth_time):
112
- """
113
- Creates a new patch of grass
112
+ """Creates a new patch of grass.
114
113
 
115
114
  Args:
116
- grown: (boolean) Whether the patch of grass is fully grown or not
115
+ model: a model instance
116
+ fully_grown: (boolean) Whether the patch of grass is fully grown or not
117
117
  countdown: Time for the patch of grass to be fully grown again
118
+ grass_regrowth_time: regrowth time for the grass
118
119
  """
119
120
  super().__init__(model)
120
121
  self._fully_grown = fully_grown
@@ -125,13 +126,12 @@ class GrassPatch(mesa.Agent):
125
126
  setattr, countdown, function_args=[self, "fully_grown", True]
126
127
  )
127
128
 
128
- def set_fully_grown(self):
129
+ def set_fully_grown(self): # noqa
129
130
  self.fully_grown = True
130
131
 
131
132
 
132
133
  class WolfSheep(mesa.Model):
133
- """
134
- Wolf-Sheep Predation Model
134
+ """Wolf-Sheep Predation Model.
135
135
 
136
136
  A model for simulating wolf and sheep (predator-prey) ecosystem modelling.
137
137
  """
@@ -151,10 +151,11 @@ class WolfSheep(mesa.Model):
151
151
  simulator=None,
152
152
  seed=None,
153
153
  ):
154
- """
155
- Create a new Wolf-Sheep model with the given parameters.
154
+ """Create a new Wolf-Sheep model with the given parameters.
156
155
 
157
156
  Args:
157
+ height: height of the grid
158
+ width: width of the grid
158
159
  initial_sheep: Number of sheep to start with
159
160
  initial_wolves: Number of wolves to start with
160
161
  sheep_reproduce: Probability of each sheep reproducing each step
@@ -164,7 +165,9 @@ class WolfSheep(mesa.Model):
164
165
  grass_regrowth_time: How long it takes for a grass patch to regrow
165
166
  once it is eaten
166
167
  sheep_gain_from_food: Energy sheep gain from grass, if enabled.
167
- moore:
168
+ moore: whether to use moore or von Neumann grid
169
+ simulator: Simulator to use for simulating wolf and sheep
170
+ seed: Random seed
168
171
  """
169
172
  super().__init__(seed=seed)
170
173
  # Set parameters
@@ -226,8 +229,9 @@ class WolfSheep(mesa.Model):
226
229
  self.grid.place_agent(patch, pos)
227
230
 
228
231
  def step(self):
229
- self.agents_by_type[Sheep].shuffle(inplace=True).do("step")
230
- self.agents_by_type[Wolf].shuffle(inplace=True).do("step")
232
+ """Perform one step of the model."""
233
+ self.agents_by_type[Sheep].shuffle_do("step")
234
+ self.agents_by_type[Wolf].shuffle_do("step")
231
235
 
232
236
 
233
237
  if __name__ == "__main__":
@@ -1,3 +1,10 @@
1
+ """Provides several simulator classes.
2
+
3
+ A Simulator is responsible for executing a simulation model. It controls time advancement and enables event scheduling.
4
+
5
+
6
+ """
7
+
1
8
  from __future__ import annotations
2
9
 
3
10
  import numbers
@@ -27,6 +34,12 @@ class Simulator:
27
34
  # TODO: add experimentation support
28
35
 
29
36
  def __init__(self, time_unit: type, start_time: int | float):
37
+ """Initialize a Simulator instance.
38
+
39
+ Args:
40
+ time_unit: type of the smulaiton time
41
+ start_time: the starttime of the simulator
42
+ """
30
43
  # should model run in a separate thread,
31
44
  # and we can then interact with start, stop, run_until, and step?
32
45
  self.event_list = EventList()
@@ -36,10 +49,10 @@ class Simulator:
36
49
  self.time = self.start_time
37
50
  self.model = None
38
51
 
39
- def check_time_unit(self, time: int | float) -> bool: ...
52
+ def check_time_unit(self, time: int | float) -> bool: ... # noqa: D102
40
53
 
41
54
  def setup(self, model: Model) -> None:
42
- """Set up the simulator with the model to simulate
55
+ """Set up the simulator with the model to simulate.
43
56
 
44
57
  Args:
45
58
  model (Model): The model to simulate
@@ -49,12 +62,13 @@ class Simulator:
49
62
  self.model = model
50
63
 
51
64
  def reset(self):
52
- """Reset the simulator by clearing the event list and removing the model to simulate"""
65
+ """Reset the simulator by clearing the event list and removing the model to simulate."""
53
66
  self.event_list.clear()
54
67
  self.model = None
55
68
  self.time = self.start_time
56
69
 
57
70
  def run_until(self, end_time: int | float) -> None:
71
+ """Run the simulator until the end time."""
58
72
  while True:
59
73
  try:
60
74
  event = self.event_list.pop_event()
@@ -71,7 +85,7 @@ class Simulator:
71
85
  break
72
86
 
73
87
  def run_for(self, time_delta: int | float):
74
- """run the simulator for the specified time delta
88
+ """Run the simulator for the specified time delta.
75
89
 
76
90
  Args:
77
91
  time_delta (float| int): The time delta. The simulator is run from the current time to the current time
@@ -88,7 +102,7 @@ class Simulator:
88
102
  function_args: list[Any] | None = None,
89
103
  function_kwargs: dict[str, Any] | None = None,
90
104
  ) -> SimulationEvent:
91
- """Schedule event for the current time instant
105
+ """Schedule event for the current time instant.
92
106
 
93
107
  Args:
94
108
  function (Callable): The callable to execute for this event
@@ -116,7 +130,7 @@ class Simulator:
116
130
  function_args: list[Any] | None = None,
117
131
  function_kwargs: dict[str, Any] | None = None,
118
132
  ) -> SimulationEvent:
119
- """Schedule event for the specified time instant
133
+ """Schedule event for the specified time instant.
120
134
 
121
135
  Args:
122
136
  function (Callable): The callable to execute for this event
@@ -150,7 +164,7 @@ class Simulator:
150
164
  function_args: list[Any] | None = None,
151
165
  function_kwargs: dict[str, Any] | None = None,
152
166
  ) -> SimulationEvent:
153
- """Schedule event for the current time plus the time delta
167
+ """Schedule event for the current time plus the time delta.
154
168
 
155
169
  Args:
156
170
  function (Callable): The callable to execute for this event
@@ -174,13 +188,12 @@ class Simulator:
174
188
  return event
175
189
 
176
190
  def cancel_event(self, event: SimulationEvent) -> None:
177
- """remove the event from the event list
191
+ """Remove the event from the event list.
178
192
 
179
193
  Args:
180
194
  event (SimulationEvent): The simulation event to remove
181
195
 
182
196
  """
183
-
184
197
  self.event_list.remove(event)
185
198
 
186
199
  def _schedule_event(self, event: SimulationEvent):
@@ -204,13 +217,29 @@ class ABMSimulator(Simulator):
204
217
  """
205
218
 
206
219
  def __init__(self):
220
+ """Initialize a ABM simulator."""
207
221
  super().__init__(int, 0)
208
222
 
209
223
  def setup(self, model):
224
+ """Set up the simulator with the model to simulate.
225
+
226
+ Args:
227
+ model (Model): The model to simulate
228
+
229
+ """
210
230
  super().setup(model)
211
231
  self.schedule_event_now(self.model.step, priority=Priority.HIGH)
212
232
 
213
233
  def check_time_unit(self, time) -> bool:
234
+ """Check whether the time is of the correct unit.
235
+
236
+ Args:
237
+ time (int | float): the time
238
+
239
+ Returns:
240
+ bool: whether the time is of the correct unit
241
+
242
+ """
214
243
  if isinstance(time, int):
215
244
  return True
216
245
  if isinstance(time, float):
@@ -225,9 +254,9 @@ class ABMSimulator(Simulator):
225
254
  function_args: list[Any] | None = None,
226
255
  function_kwargs: dict[str, Any] | None = None,
227
256
  ) -> SimulationEvent:
228
- """Schedule a SimulationEvent for the next tick
257
+ """Schedule a SimulationEvent for the next tick.
229
258
 
230
- Args
259
+ Args:
231
260
  function (Callable): the callable to execute
232
261
  priority (Priority): the priority of the event
233
262
  function_args (List[Any]): List of arguments to pass to the callable
@@ -243,7 +272,7 @@ class ABMSimulator(Simulator):
243
272
  )
244
273
 
245
274
  def run_until(self, end_time: int) -> None:
246
- """run the simulator up to and included the specified end time
275
+ """Run the simulator up to and included the specified end time.
247
276
 
248
277
  Args:
249
278
  end_time (float| int): The end_time delta. The simulator is until the specified end time
@@ -270,7 +299,7 @@ class ABMSimulator(Simulator):
270
299
  break
271
300
 
272
301
  def run_for(self, time_delta: int):
273
- """run the simulator for the specified time delta
302
+ """Run the simulator for the specified time delta.
274
303
 
275
304
  Args:
276
305
  time_delta (float| int): The time delta. The simulator is run from the current time to the current time
@@ -282,13 +311,24 @@ class ABMSimulator(Simulator):
282
311
 
283
312
 
284
313
  class DEVSimulator(Simulator):
285
- """A simulator where the unit of time is a float. Can be used for full-blown discrete event simulating using
286
- event scheduling.
314
+ """A simulator where the unit of time is a float.
315
+
316
+ Can be used for full-blown discrete event simulating using event scheduling.
287
317
 
288
318
  """
289
319
 
290
320
  def __init__(self):
321
+ """Initialize a DEVS simulator."""
291
322
  super().__init__(float, 0.0)
292
323
 
293
324
  def check_time_unit(self, time) -> bool:
325
+ """Check whether the time is of the correct unit.
326
+
327
+ Args:
328
+ time (float): the time
329
+
330
+ Returns:
331
+ bool: whether the time is of the correct unit
332
+
333
+ """
294
334
  return isinstance(time, numbers.Number)
@@ -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.
@@ -39,8 +38,7 @@ from mesa.experimental.UserParam import Slider
39
38
  def Card(
40
39
  model, measures, agent_portrayal, space_drawer, dependencies, color, layout_type
41
40
  ):
42
- """
43
- Create a card component for visualizing model space or measures.
41
+ """Create a card component for visualizing model space or measures.
44
42
 
45
43
  Args:
46
44
  model: The Mesa model instance
@@ -95,8 +93,7 @@ def SolaraViz(
95
93
  play_interval=150,
96
94
  seed=None,
97
95
  ):
98
- """
99
- Initialize a component to visualize a model.
96
+ """Initialize a component to visualize a model.
100
97
 
101
98
  Args:
102
99
  model_class: Class of the model to instantiate
@@ -212,8 +209,7 @@ JupyterViz = SolaraViz
212
209
 
213
210
  @solara.component
214
211
  def ModelController(model, play_interval, current_step, reset_counter):
215
- """
216
- Create controls for model execution (step, play, pause, reset).
212
+ """Create controls for model execution (step, play, pause, reset).
217
213
 
218
214
  Args:
219
215
  model: The model being visualized
@@ -315,8 +311,7 @@ def ModelController(model, play_interval, current_step, reset_counter):
315
311
 
316
312
 
317
313
  def split_model_params(model_params):
318
- """
319
- Split model parameters into user-adjustable and fixed parameters.
314
+ """Split model parameters into user-adjustable and fixed parameters.
320
315
 
321
316
  Args:
322
317
  model_params: Dictionary of all model parameters
@@ -335,8 +330,7 @@ def split_model_params(model_params):
335
330
 
336
331
 
337
332
  def check_param_is_fixed(param):
338
- """
339
- Check if a parameter is fixed (not user-adjustable).
333
+ """Check if a parameter is fixed (not user-adjustable).
340
334
 
341
335
  Args:
342
336
  param: Parameter to check
@@ -354,8 +348,8 @@ def check_param_is_fixed(param):
354
348
 
355
349
  @solara.component
356
350
  def UserInputs(user_params, on_change=None):
357
- """
358
- Initialize user inputs for configurable model parameters.
351
+ """Initialize user inputs for configurable model parameters.
352
+
359
353
  Currently supports :class:`solara.SliderInt`, :class:`solara.SliderFloat`,
360
354
  :class:`solara.Select`, and :class:`solara.Checkbox`.
361
355
 
@@ -364,7 +358,6 @@ def UserInputs(user_params, on_change=None):
364
358
  min and max values, and other fields specific to the input type.
365
359
  on_change: Function to be called with (name, value) when the value of an input changes.
366
360
  """
367
-
368
361
  for name, options in user_params.items():
369
362
 
370
363
  def change_handler(value, name=name):
@@ -423,8 +416,7 @@ def UserInputs(user_params, on_change=None):
423
416
 
424
417
 
425
418
  def make_text(renderer):
426
- """
427
- Create a function that renders text using Markdown.
419
+ """Create a function that renders text using Markdown.
428
420
 
429
421
  Args:
430
422
  renderer: Function that takes a model and returns a string
@@ -440,8 +432,7 @@ def make_text(renderer):
440
432
 
441
433
 
442
434
  def make_initial_grid_layout(layout_types):
443
- """
444
- Create an initial grid layout for visualization components.
435
+ """Create an initial grid layout for visualization components.
445
436
 
446
437
  Args:
447
438
  layout_types: List of layout types (Space or Measure)