Mesa 1.1.0__py3-none-any.whl → 1.2.0__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-1.1.0.dist-info → Mesa-1.2.0.dist-info}/LICENSE +1 -1
  2. {Mesa-1.1.0.dist-info → Mesa-1.2.0.dist-info}/METADATA +15 -14
  3. {Mesa-1.1.0.dist-info → Mesa-1.2.0.dist-info}/RECORD +41 -41
  4. {Mesa-1.1.0.dist-info → Mesa-1.2.0.dist-info}/WHEEL +1 -1
  5. mesa/__init__.py +8 -9
  6. mesa/agent.py +2 -3
  7. mesa/batchrunner.py +19 -28
  8. mesa/datacollection.py +15 -28
  9. mesa/main.py +4 -4
  10. mesa/model.py +2 -6
  11. mesa/space.py +379 -286
  12. mesa/time.py +21 -22
  13. mesa/visualization/ModularVisualization.py +11 -9
  14. mesa/visualization/TextVisualization.py +0 -3
  15. mesa/visualization/UserParam.py +8 -11
  16. mesa/visualization/__init__.py +0 -1
  17. mesa/visualization/modules/BarChartVisualization.py +7 -8
  18. mesa/visualization/modules/CanvasGridVisualization.py +1 -3
  19. mesa/visualization/modules/ChartVisualization.py +2 -3
  20. mesa/visualization/modules/HexGridVisualization.py +1 -3
  21. mesa/visualization/modules/NetworkVisualization.py +1 -2
  22. mesa/visualization/modules/PieChartVisualization.py +2 -6
  23. mesa/visualization/templates/js/GridDraw.js +6 -10
  24. mesa/visualization/templates/js/HexDraw.js +5 -9
  25. mesa/visualization/templates/js/InteractionHandler.js +0 -2
  26. tests/test_batchrunner.py +3 -4
  27. tests/test_batchrunnerMP.py +4 -4
  28. tests/test_datacollector.py +2 -2
  29. tests/test_examples.py +8 -5
  30. tests/test_grid.py +104 -37
  31. tests/test_import_namespace.py +0 -1
  32. tests/test_lifespan.py +4 -3
  33. tests/test_main.py +5 -1
  34. tests/test_scaffold.py +2 -1
  35. tests/test_space.py +13 -20
  36. tests/test_time.py +44 -14
  37. tests/test_tornado.py +4 -2
  38. tests/test_usersettableparam.py +4 -3
  39. tests/test_visualization.py +4 -8
  40. {Mesa-1.1.0.dist-info → Mesa-1.2.0.dist-info}/entry_points.txt +0 -0
  41. {Mesa-1.1.0.dist-info → Mesa-1.2.0.dist-info}/top_level.txt +0 -0
tests/test_examples.py CHANGED
@@ -1,14 +1,17 @@
1
- import sys
2
- import os.path
3
- import unittest
4
1
  import contextlib
5
2
  import importlib
3
+ import os.path
4
+ import sys
5
+ import unittest
6
6
 
7
7
 
8
8
  def classcase(name):
9
9
  return "".join(x.capitalize() for x in name.replace("-", "_").split("_"))
10
10
 
11
11
 
12
+ @unittest.skip(
13
+ "Skipping TextExamples, because examples folder was moved. More discussion needed."
14
+ )
12
15
  class TestExamples(unittest.TestCase):
13
16
  """
14
17
  Test examples' models. This creates a model object and iterates it through
@@ -59,7 +62,7 @@ class TestExamples(unittest.TestCase):
59
62
  f"{example.replace('-', '_')}.server"
60
63
  )
61
64
  server.server.render_model()
62
- Model = getattr(mod, classcase(example))
63
- model = Model()
65
+ model_class = getattr(mod, classcase(example))
66
+ model = model_class()
64
67
  for _ in range(10):
65
68
  model.step()
tests/test_grid.py CHANGED
@@ -3,7 +3,9 @@ Test the Grid objects.
3
3
  """
4
4
  import random
5
5
  import unittest
6
- from mesa.space import Grid, SingleGrid, MultiGrid, HexGrid
6
+ from unittest.mock import Mock, patch
7
+
8
+ from mesa.space import HexGrid, MultiGrid, SingleGrid
7
9
 
8
10
  # Initial agent positions for testing
9
11
  #
@@ -14,7 +16,7 @@ from mesa.space import Grid, SingleGrid, MultiGrid, HexGrid
14
16
  # 1 0 1
15
17
  # 0 0 1
16
18
  # -------------------
17
- TEST_GRID = [[0, 1, 0, 1, 0], [0, 0, 1, 1, 0], [1, 1, 0, 0, 0]]
19
+ TEST_GRID = [[0, 1, 0, 1, 0, 0], [0, 0, 1, 1, 0, 1], [1, 1, 0, 0, 0, 1]]
18
20
 
19
21
 
20
22
  class MockAgent:
@@ -28,9 +30,9 @@ class MockAgent:
28
30
  self.pos = pos
29
31
 
30
32
 
31
- class TestBaseGrid(unittest.TestCase):
33
+ class TestSingleGrid(unittest.TestCase):
32
34
  """
33
- Testing a non-toroidal grid.
35
+ Testing a non-toroidal singlegrid.
34
36
  """
35
37
 
36
38
  torus = False
@@ -39,9 +41,10 @@ class TestBaseGrid(unittest.TestCase):
39
41
  """
40
42
  Create a test non-toroidal grid and populate it with Mock Agents
41
43
  """
44
+ # The height needs to be even to test the edge case described in PR #1517
45
+ height = 6 # height of grid
42
46
  width = 3 # width of grid
43
- height = 5 # height of grid
44
- self.grid = Grid(width, height, self.torus)
47
+ self.grid = SingleGrid(width, height, self.torus)
45
48
  self.agents = []
46
49
  counter = 0
47
50
  for x in range(width):
@@ -108,10 +111,10 @@ class TestBaseGrid(unittest.TestCase):
108
111
  assert len(neighborhood) == 8
109
112
 
110
113
  neighborhood = self.grid.get_neighborhood((1, 4), moore=False)
111
- assert len(neighborhood) == 3
114
+ assert len(neighborhood) == 4
112
115
 
113
116
  neighborhood = self.grid.get_neighborhood((1, 4), moore=True)
114
- assert len(neighborhood) == 5
117
+ assert len(neighborhood) == 8
115
118
 
116
119
  neighborhood = self.grid.get_neighborhood((0, 0), moore=False)
117
120
  assert len(neighborhood) == 2
@@ -126,7 +129,7 @@ class TestBaseGrid(unittest.TestCase):
126
129
  assert len(neighbors) == 3
127
130
 
128
131
  neighbors = self.grid.get_neighbors((1, 3), moore=False, radius=2)
129
- assert len(neighbors) == 2
132
+ assert len(neighbors) == 3
130
133
 
131
134
  def test_coord_iter(self):
132
135
  ci = self.grid.coord_iter()
@@ -147,8 +150,8 @@ class TestBaseGrid(unittest.TestCase):
147
150
  def test_agent_move(self):
148
151
  # get the agent at [0, 1]
149
152
  agent = self.agents[0]
150
- self.grid.move_agent(agent, (1, 1))
151
- assert agent.pos == (1, 1)
153
+ self.grid.move_agent(agent, (1, 0))
154
+ assert agent.pos == (1, 0)
152
155
  # move it off the torus and check for the exception
153
156
  if not self.torus:
154
157
  with self.assertRaises(Exception):
@@ -156,22 +159,51 @@ class TestBaseGrid(unittest.TestCase):
156
159
  with self.assertRaises(Exception):
157
160
  self.grid.move_agent(agent, [1, self.grid.height + 1])
158
161
  else:
159
- self.grid.move_agent(agent, [-1, 1])
160
- assert agent.pos == (self.grid.width - 1, 1)
161
- self.grid.move_agent(agent, [1, self.grid.height + 1])
162
- assert agent.pos == (1, 1)
162
+ self.grid.move_agent(agent, [0, -1])
163
+ assert agent.pos == (0, self.grid.height - 1)
164
+ self.grid.move_agent(agent, [1, self.grid.height])
165
+ assert agent.pos == (1, 0)
163
166
 
164
167
  def test_agent_remove(self):
165
168
  agent = self.agents[0]
166
169
  x, y = agent.pos
167
170
  self.grid.remove_agent(agent)
168
171
  assert agent.pos is None
169
- assert self.grid.grid[x][y] is None
172
+ assert self.grid[x][y] is None
173
+
174
+ def test_swap_pos(self):
175
+ # Swap agents positions
176
+ agent_a, agent_b = list(filter(None, self.grid))[:2]
177
+ pos_a = agent_a.pos
178
+ pos_b = agent_b.pos
179
+
180
+ self.grid.swap_pos(agent_a, agent_b)
181
+
182
+ assert agent_a.pos == pos_b
183
+ assert agent_b.pos == pos_a
184
+ assert self.grid[pos_a] == agent_b
185
+ assert self.grid[pos_b] == agent_a
186
+
187
+ # Swap the same agents
188
+ self.grid.swap_pos(agent_a, agent_a)
189
+
190
+ assert agent_a.pos == pos_b
191
+ assert self.grid[pos_b] == agent_a
192
+
193
+ # Raise for agents not on the grid
194
+ self.grid.remove_agent(agent_a)
195
+ self.grid.remove_agent(agent_b)
170
196
 
197
+ id_a = agent_a.unique_id
198
+ id_b = agent_b.unique_id
199
+ e_message = f"<Agent id: {id_a}>, <Agent id: {id_b}> - not on the grid"
200
+ with self.assertRaisesRegex(Exception, e_message):
201
+ self.grid.swap_pos(agent_a, agent_b)
171
202
 
172
- class TestBaseGridTorus(TestBaseGrid):
203
+
204
+ class TestSingleGridTorus(TestSingleGrid):
173
205
  """
174
- Testing the toroidal base grid.
206
+ Testing the toroidal singlegrid.
175
207
  """
176
208
 
177
209
  torus = True
@@ -190,25 +222,30 @@ class TestBaseGridTorus(TestBaseGrid):
190
222
  neighborhood = self.grid.get_neighborhood((0, 0), moore=False)
191
223
  assert len(neighborhood) == 4
192
224
 
225
+ # here we test the edge case described in PR #1517 using a radius
226
+ # measuring half of the grid height
227
+ neighborhood = self.grid.get_neighborhood((0, 0), moore=True, radius=3)
228
+ assert len(neighborhood) == 17
229
+
230
+ neighborhood = self.grid.get_neighborhood((1, 1), moore=False, radius=3)
231
+ assert len(neighborhood) == 15
232
+
193
233
  neighbors = self.grid.get_neighbors((1, 4), moore=False)
194
- assert len(neighbors) == 1
234
+ assert len(neighbors) == 2
195
235
 
196
236
  neighbors = self.grid.get_neighbors((1, 4), moore=True)
197
- assert len(neighbors) == 3
237
+ assert len(neighbors) == 4
198
238
 
199
239
  neighbors = self.grid.get_neighbors((1, 1), moore=False, include_center=True)
200
240
  assert len(neighbors) == 3
201
241
 
202
242
  neighbors = self.grid.get_neighbors((1, 3), moore=False, radius=2)
203
- assert len(neighbors) == 2
243
+ assert len(neighbors) == 3
204
244
 
205
245
 
206
- class TestSingleGrid(unittest.TestCase):
246
+ class TestSingleGridEnforcement(unittest.TestCase):
207
247
  """
208
- Test the SingleGrid object.
209
-
210
- Since it inherits from Grid, all the functionality tested above should
211
- work here too. Instead, this tests the enforcement.
248
+ Test the enforcement in SingleGrid.
212
249
  """
213
250
 
214
251
  def setUp(self):
@@ -231,7 +268,27 @@ class TestSingleGrid(unittest.TestCase):
231
268
  self.grid.place_agent(a, (x, y))
232
269
  self.num_agents = len(self.agents)
233
270
 
234
- def test_enforcement(self):
271
+ @patch.object(MockAgent, "model", create=True)
272
+ def test_position_agent(self, mock_model):
273
+ a = MockAgent(100, None)
274
+ with self.assertRaises(Exception) as exc_info:
275
+ self.grid.position_agent(a, (1, 1))
276
+ expected = (
277
+ "x must be an integer or a string 'random'."
278
+ " Actual type: <class 'tuple'>. Actual value: (1, 1)."
279
+ )
280
+ assert str(exc_info.exception) == expected
281
+ with self.assertRaises(Exception) as exc_info:
282
+ self.grid.position_agent(a, "(1, 1)")
283
+ expected = (
284
+ "x must be an integer or a string 'random'."
285
+ " Actual type: <class 'str'>. Actual value: (1, 1)."
286
+ )
287
+ assert str(exc_info.exception) == expected
288
+ self.grid.position_agent(a, "random")
289
+
290
+ @patch.object(MockAgent, "model", create=True)
291
+ def test_enforcement(self, mock_model):
235
292
  """
236
293
  Test the SingleGrid empty count and enforcement.
237
294
  """
@@ -239,17 +296,16 @@ class TestSingleGrid(unittest.TestCase):
239
296
  assert len(self.grid.empties) == 9
240
297
  a = MockAgent(100, None)
241
298
  with self.assertRaises(Exception):
242
- self.grid._place_agent(a, (0, 1))
299
+ self.grid.place_agent(a, (0, 1))
243
300
 
244
301
  # Place the agent in an empty cell
302
+ mock_model.schedule.get_agent_count = Mock(side_effect=lambda: len(self.agents))
245
303
  self.grid.position_agent(a)
246
304
  self.num_agents += 1
247
305
  # Test whether after placing, the empty cells are reduced by 1
248
306
  assert a.pos not in self.grid.empties
249
307
  assert len(self.grid.empties) == 8
250
- for i in range(10):
251
- # Since the agents and the grid are not associated with a model, we
252
- # must explicitly tell move_to_empty the number of agents.
308
+ for _i in range(10):
253
309
  self.grid.move_to_empty(a, num_agents=self.num_agents)
254
310
  assert len(self.grid.empties) == 8
255
311
 
@@ -299,7 +355,7 @@ class TestMultiGrid(unittest.TestCase):
299
355
  counter = 0
300
356
  for x in range(width):
301
357
  for y in range(height):
302
- for i in range(TEST_MULTIGRID[x][y]):
358
+ for _i in range(TEST_MULTIGRID[x][y]):
303
359
  counter += 1
304
360
  # Create and place the mock agent
305
361
  a = MockAgent(counter, None)
@@ -343,7 +399,7 @@ class TestMultiGrid(unittest.TestCase):
343
399
 
344
400
  class TestHexGrid(unittest.TestCase):
345
401
  """
346
- Testing a hexagonal grid.
402
+ Testing a hexagonal singlegrid.
347
403
  """
348
404
 
349
405
  def setUp(self):
@@ -391,10 +447,14 @@ class TestHexGrid(unittest.TestCase):
391
447
  neighborhood = self.grid.get_neighborhood((1, 1), include_center=True)
392
448
  assert len(neighborhood) == 7
393
449
 
450
+ neighborhood = self.grid.get_neighborhood((0, 0), radius=4)
451
+ assert len(neighborhood) == 13
452
+ assert sum(x + y for x, y in neighborhood) == 39
394
453
 
395
- class TestHexGridTorus(TestBaseGrid):
454
+
455
+ class TestHexGridTorus(TestSingleGrid):
396
456
  """
397
- Testing a hexagonal toroidal grid.
457
+ Testing a hexagonal toroidal singlegrid.
398
458
  """
399
459
 
400
460
  torus = True
@@ -435,12 +495,19 @@ class TestHexGridTorus(TestBaseGrid):
435
495
  neighborhood = self.grid.get_neighborhood((2, 4))
436
496
  assert len(neighborhood) == 6
437
497
 
498
+ neighborhood = self.grid.get_neighborhood((1, 1), include_center=True, radius=2)
499
+ assert len(neighborhood) == 13
500
+
501
+ neighborhood = self.grid.get_neighborhood((0, 0), radius=4)
502
+ assert len(neighborhood) == 14
503
+ assert sum(x + y for x, y in neighborhood) == 45
504
+
438
505
 
439
506
  class TestIndexing:
440
507
  # Create a grid where the content of each coordinate is a tuple of its coordinates
441
- grid = Grid(3, 5, True)
508
+ grid = SingleGrid(3, 5, True)
442
509
  for _, x, y in grid.coord_iter():
443
- grid.grid[x][y] = (x, y)
510
+ grid._grid[x][y] = (x, y)
444
511
 
445
512
  def test_int(self):
446
513
  assert self.grid[0][0] == (0, 0)
@@ -3,7 +3,6 @@ def test_import():
3
3
  # https://github.com/projectmesa/mesa/pull/1294.
4
4
  import mesa
5
5
  import mesa.flat as mf
6
-
7
6
  from mesa.time import RandomActivation
8
7
 
9
8
  mesa.time.RandomActivation
tests/test_lifespan.py CHANGED
@@ -1,10 +1,11 @@
1
1
  import unittest
2
2
 
3
- from mesa.time import RandomActivation
4
- from mesa.datacollection import DataCollector
5
- from mesa import Model, Agent
6
3
  import numpy as np
7
4
 
5
+ from mesa import Agent, Model
6
+ from mesa.datacollection import DataCollector
7
+ from mesa.time import RandomActivation
8
+
8
9
 
9
10
  class LifeTimeModel(Model):
10
11
  """Simple model for running models with a finite life"""
tests/test_main.py CHANGED
@@ -2,6 +2,7 @@ import os
2
2
  import sys
3
3
  import unittest
4
4
  from unittest.mock import patch
5
+
5
6
  from click.testing import CliRunner
6
7
 
7
8
  from mesa.main import cli
@@ -19,8 +20,11 @@ class TestCli(unittest.TestCase):
19
20
  def tearDown(self):
20
21
  sys.path[:] = self.old_sys_path
21
22
 
23
+ @unittest.skip(
24
+ "Skipping test_run, because examples folder was moved. More discussion needed."
25
+ )
22
26
  def test_run(self):
23
- with patch("mesa.visualization.ModularServer") as ModularServer:
27
+ with patch("mesa.visualization.ModularServer") as ModularServer: # noqa: N806
24
28
  example_dir = os.path.abspath(
25
29
  os.path.join(os.path.dirname(__file__), "../examples/wolf_sheep")
26
30
  )
tests/test_scaffold.py CHANGED
@@ -1,5 +1,6 @@
1
- import unittest
2
1
  import os
2
+ import unittest
3
+
3
4
  from click.testing import CliRunner
4
5
 
5
6
  from mesa.main import cli
tests/test_space.py CHANGED
@@ -4,12 +4,9 @@ import networkx as nx
4
4
  import numpy as np
5
5
  import pytest
6
6
 
7
- from mesa.space import ContinuousSpace
8
- from mesa.space import SingleGrid
9
- from mesa.space import NetworkGrid
7
+ from mesa.space import ContinuousSpace, NetworkGrid, SingleGrid
10
8
  from tests.test_grid import MockAgent
11
9
 
12
-
13
10
  TEST_AGENTS = [(-20, -20), (-20, -20.05), (65, 18)]
14
11
  TEST_AGENTS_GRID = [(1, 1), (10, 0), (10, 10)]
15
12
  TEST_AGENTS_NETWORK_SINGLE = [0, 1, 5]
@@ -302,10 +299,10 @@ class TestSingleGrid(unittest.TestCase):
302
299
  for i, pos in enumerate(TEST_AGENTS_GRID):
303
300
  a = self.agents[i]
304
301
  assert a.pos == pos
305
- assert self.space.grid[pos[0]][pos[1]] == a
302
+ assert self.space[pos[0]][pos[1]] == a
306
303
  self.space.remove_agent(a)
307
304
  assert a.pos is None
308
- assert self.space.grid[pos[0]][pos[1]] is None
305
+ assert self.space[pos[0]][pos[1]] is None
309
306
 
310
307
  def test_empty_cells(self):
311
308
  if self.space.exists_empty_cells():
@@ -325,12 +322,12 @@ class TestSingleGrid(unittest.TestCase):
325
322
  _agent = self.agents[agent_number]
326
323
 
327
324
  assert _agent.pos == initial_pos
328
- assert self.space.grid[initial_pos[0]][initial_pos[1]] == _agent
329
- assert self.space.grid[final_pos[0]][final_pos[1]] is None
325
+ assert self.space[initial_pos[0]][initial_pos[1]] == _agent
326
+ assert self.space[final_pos[0]][final_pos[1]] is None
330
327
  self.space.move_agent(_agent, final_pos)
331
328
  assert _agent.pos == final_pos
332
- assert self.space.grid[initial_pos[0]][initial_pos[1]] is None
333
- assert self.space.grid[final_pos[0]][final_pos[1]] == _agent
329
+ assert self.space[initial_pos[0]][initial_pos[1]] is None
330
+ assert self.space[final_pos[0]][final_pos[1]] == _agent
334
331
 
335
332
 
336
333
  class TestSingleNetworkGrid(unittest.TestCase):
@@ -340,7 +337,7 @@ class TestSingleNetworkGrid(unittest.TestCase):
340
337
  """
341
338
  Create a test network grid and populate with Mock Agents.
342
339
  """
343
- G = nx.complete_graph(TestSingleNetworkGrid.GRAPH_SIZE)
340
+ G = nx.cycle_graph(TestSingleNetworkGrid.GRAPH_SIZE) # noqa: N806
344
341
  self.space = NetworkGrid(G)
345
342
  self.agents = []
346
343
  for i, pos in enumerate(TEST_AGENTS_NETWORK_SINGLE):
@@ -357,14 +354,10 @@ class TestSingleNetworkGrid(unittest.TestCase):
357
354
  assert a.pos == pos
358
355
 
359
356
  def test_get_neighbors(self):
360
- assert (
361
- len(self.space.get_neighbors(0, include_center=True))
362
- == TestSingleNetworkGrid.GRAPH_SIZE
363
- )
364
- assert (
365
- len(self.space.get_neighbors(0, include_center=False))
366
- == TestSingleNetworkGrid.GRAPH_SIZE - 1
367
- )
357
+ assert len(self.space.get_neighbors(0, include_center=True)) == 3
358
+ assert len(self.space.get_neighbors(0, include_center=False)) == 2
359
+ assert len(self.space.get_neighbors(2, include_center=True, radius=3)) == 7
360
+ assert len(self.space.get_neighbors(2, include_center=False, radius=3)) == 6
368
361
 
369
362
  def test_move_agent(self):
370
363
  initial_pos = 1
@@ -415,7 +408,7 @@ class TestMultipleNetworkGrid(unittest.TestCase):
415
408
  """
416
409
  Create a test network grid and populate with Mock Agents.
417
410
  """
418
- G = nx.complete_graph(TestMultipleNetworkGrid.GRAPH_SIZE)
411
+ G = nx.complete_graph(TestMultipleNetworkGrid.GRAPH_SIZE) # noqa: N806
419
412
  self.space = NetworkGrid(G)
420
413
  self.agents = []
421
414
  for i, pos in enumerate(TEST_AGENTS_NETWORK_MULTIPLE):
tests/test_time.py CHANGED
@@ -4,13 +4,14 @@ Test the advanced schedulers.
4
4
 
5
5
  import unittest
6
6
  from unittest import TestCase, mock
7
- from mesa import Model, Agent
7
+
8
+ from mesa import Agent, Model
8
9
  from mesa.time import (
9
10
  BaseScheduler,
10
- StagedActivation,
11
11
  RandomActivation,
12
- SimultaneousActivation,
13
12
  RandomActivationByType,
13
+ SimultaneousActivation,
14
+ StagedActivation,
14
15
  )
15
16
 
16
17
  RANDOM = "random"
@@ -29,7 +30,15 @@ class MockAgent(Agent):
29
30
  self.steps = 0
30
31
  self.advances = 0
31
32
 
33
+ def kill_other_agent(self):
34
+ for agent in self.model.schedule.agents:
35
+ if agent is not self:
36
+ self.model.schedule.remove(agent)
37
+ break
38
+
32
39
  def stage_one(self):
40
+ if self.model.enable_kill_other_agent:
41
+ self.kill_other_agent()
33
42
  self.model.log.append(self.unique_id + "_1")
34
43
 
35
44
  def stage_two(self):
@@ -39,11 +48,14 @@ class MockAgent(Agent):
39
48
  self.advances += 1
40
49
 
41
50
  def step(self):
51
+ if self.model.enable_kill_other_agent:
52
+ self.kill_other_agent()
42
53
  self.steps += 1
54
+ self.model.log.append(self.unique_id)
43
55
 
44
56
 
45
57
  class MockModel(Model):
46
- def __init__(self, shuffle=False, activation=STAGED):
58
+ def __init__(self, shuffle=False, activation=STAGED, enable_kill_other_agent=False):
47
59
  """
48
60
  Creates a Model instance with a schedule
49
61
 
@@ -59,6 +71,7 @@ class MockModel(Model):
59
71
  The default scheduler is a BaseScheduler.
60
72
  """
61
73
  self.log = []
74
+ self.enable_kill_other_agent = enable_kill_other_agent
62
75
 
63
76
  # Make scheduler
64
77
  if activation == STAGED:
@@ -91,7 +104,7 @@ class TestStagedActivation(TestCase):
91
104
 
92
105
  def test_no_shuffle(self):
93
106
  """
94
- Testing staged activation without shuffling.
107
+ Testing the staged activation without shuffling.
95
108
  """
96
109
  model = MockModel(shuffle=False)
97
110
  model.step()
@@ -100,7 +113,7 @@ class TestStagedActivation(TestCase):
100
113
 
101
114
  def test_shuffle(self):
102
115
  """
103
- Test staged activation with shuffling
116
+ Test the staged activation with shuffling
104
117
  """
105
118
  model = MockModel(shuffle=True)
106
119
  model.step()
@@ -118,7 +131,7 @@ class TestStagedActivation(TestCase):
118
131
 
119
132
  def test_remove(self):
120
133
  """
121
- Test staged activation can remove an agent
134
+ Test the staged activation can remove an agent
122
135
  """
123
136
  model = MockModel(shuffle=True)
124
137
  agent_keys = list(model.schedule._agents.keys())
@@ -126,6 +139,15 @@ class TestStagedActivation(TestCase):
126
139
  model.schedule.remove(agent)
127
140
  assert agent not in model.schedule.agents
128
141
 
142
+ def test_intrastep_remove(self):
143
+ """
144
+ Test the staged activation can remove an agent in a
145
+ step of another agent so that the one removed doesn't step.
146
+ """
147
+ model = MockModel(shuffle=True, enable_kill_other_agent=True)
148
+ model.step()
149
+ assert len(model.log) == 2
150
+
129
151
  def test_add_existing_agent(self):
130
152
  model = MockModel()
131
153
  agent = model.schedule.agents[0]
@@ -162,12 +184,20 @@ class TestRandomActivation(TestCase):
162
184
  """
163
185
  Test the random activation step causes each agent to step
164
186
  """
165
-
166
187
  model = MockModel(activation=RANDOM)
167
188
  model.step()
168
189
  agent_steps = [i.steps for i in model.schedule.agents]
169
190
  # one step for each of 2 agents
170
- assert all(map(lambda x: x == 1, agent_steps))
191
+ assert all(x == 1 for x in agent_steps)
192
+
193
+ def test_intrastep_remove(self):
194
+ """
195
+ Test the random activation can remove an agent in a
196
+ step of another agent so that the one removed doesn't step.
197
+ """
198
+ model = MockModel(activation=RANDOM, enable_kill_other_agent=True)
199
+ model.step()
200
+ assert len(model.log) == 1
171
201
 
172
202
 
173
203
  class TestSimultaneousActivation(TestCase):
@@ -184,8 +214,8 @@ class TestSimultaneousActivation(TestCase):
184
214
  # one step for each of 2 agents
185
215
  agent_steps = [i.steps for i in model.schedule.agents]
186
216
  agent_advances = [i.advances for i in model.schedule.agents]
187
- assert all(map(lambda x: x == 1, agent_steps))
188
- assert all(map(lambda x: x == 1, agent_advances))
217
+ assert all(x == 1 for x in agent_steps)
218
+ assert all(x == 1 for x in agent_advances)
189
219
 
190
220
 
191
221
  class TestRandomActivationByType(TestCase):
@@ -224,7 +254,7 @@ class TestRandomActivationByType(TestCase):
224
254
  model.step()
225
255
  agent_steps = [i.steps for i in model.schedule.agents]
226
256
  # one step for each of 2 agents
227
- assert all(map(lambda x: x == 1, agent_steps))
257
+ assert all(x == 1 for x in agent_steps)
228
258
 
229
259
  def test_add_non_unique_ids(self):
230
260
  """
@@ -233,8 +263,8 @@ class TestRandomActivationByType(TestCase):
233
263
  RandomActivationByType.
234
264
  """
235
265
  model = MockModel(activation=RANDOM_BY_TYPE)
236
- a = MockAgent(0, None)
237
- b = MockAgent(0, None)
266
+ a = MockAgent(0, model)
267
+ b = MockAgent(0, model)
238
268
  model.schedule.add(a)
239
269
  with self.assertRaises(Exception):
240
270
  model.schedule.add(b)
tests/test_tornado.py CHANGED
@@ -1,8 +1,10 @@
1
- from tornado.testing import AsyncHTTPTestCase
1
+ import json
2
+
2
3
  import tornado
4
+ from tornado.testing import AsyncHTTPTestCase
5
+
3
6
  from mesa import Model
4
7
  from mesa.visualization.ModularVisualization import ModularServer
5
- import json
6
8
 
7
9
 
8
10
  class TestServer(AsyncHTTPTestCase):
@@ -1,11 +1,12 @@
1
1
  from unittest import TestCase
2
+
2
3
  from mesa.visualization.UserParam import (
3
- UserSettableParameter,
4
- Slider,
5
4
  Checkbox,
6
5
  Choice,
7
- StaticText,
8
6
  NumberInput,
7
+ Slider,
8
+ StaticText,
9
+ UserSettableParameter,
9
10
  )
10
11
 
11
12
 
@@ -1,13 +1,12 @@
1
- from unittest import TestCase
2
1
  from collections import defaultdict
2
+ from unittest import TestCase
3
3
 
4
4
  from mesa.model import Model
5
- from mesa.space import Grid
5
+ from mesa.space import MultiGrid
6
6
  from mesa.time import SimultaneousActivation
7
7
  from mesa.visualization.ModularVisualization import ModularServer
8
8
  from mesa.visualization.modules import CanvasGrid, TextElement
9
9
  from mesa.visualization.UserParam import UserSettableParameter
10
-
11
10
  from tests.test_batchrunner import MockAgent
12
11
 
13
12
 
@@ -15,15 +14,14 @@ class MockModel(Model):
15
14
  """Test model for testing"""
16
15
 
17
16
  def __init__(self, width, height, key1=103, key2=104):
18
-
19
17
  self.width = width
20
18
  self.height = height
21
19
  self.key1 = (key1,)
22
20
  self.key2 = key2
23
21
  self.schedule = SimultaneousActivation(self)
24
- self.grid = Grid(width, height, torus=True)
22
+ self.grid = MultiGrid(width, height, torus=True)
25
23
 
26
- for (c, x, y) in self.grid.coord_iter():
24
+ for _c, x, y in self.grid.coord_iter():
27
25
  a = MockAgent(x + y * 100, self, x * y * 3)
28
26
  self.grid.place_agent(a, (x, y))
29
27
  self.schedule.add(a)
@@ -48,7 +46,6 @@ class TestModularServer(TestCase):
48
46
  }
49
47
 
50
48
  def setUp(self):
51
-
52
49
  self.user_params = {
53
50
  "width": 1,
54
51
  "height": 1,
@@ -68,7 +65,6 @@ class TestModularServer(TestCase):
68
65
  )
69
66
 
70
67
  def test_canvas_render_model_state(self):
71
-
72
68
  test_portrayal = self.portrayal(None)
73
69
  test_grid_state = defaultdict(list)
74
70
  test_grid_state[test_portrayal["Layer"]].append(test_portrayal)