From 076f943ee617d3eb9319e5e65b46e6b91513e542 Mon Sep 17 00:00:00 2001 From: Jan Kwakkel Date: Sun, 10 Nov 2024 12:28:47 +0100 Subject: [PATCH 01/10] issue a warning if random is none # closes #2477 --- mesa/agent.py | 2 ++ mesa/experimental/cell_space/cell_collection.py | 5 ++++- mesa/experimental/cell_space/discrete_space.py | 3 +++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/mesa/agent.py b/mesa/agent.py index 6b6c3d2e7a3..3c4600856e5 100644 --- a/mesa/agent.py +++ b/mesa/agent.py @@ -120,6 +120,8 @@ def __init__(self, agents: Iterable[Agent], random: Random | None = None): random (Random): the random number generator """ if random is None: + warnings.warn("Random number generator not specified, this can make models non-reproducible. Please pass a random number generator explicitly", + UserWarning, stacklevel=2) random = ( Random() ) # FIXME see issue 1981, how to get the central rng from model diff --git a/mesa/experimental/cell_space/cell_collection.py b/mesa/experimental/cell_space/cell_collection.py index a8c36f5198f..916583b1f6e 100644 --- a/mesa/experimental/cell_space/cell_collection.py +++ b/mesa/experimental/cell_space/cell_collection.py @@ -3,6 +3,7 @@ from __future__ import annotations import itertools +import warnings from collections.abc import Callable, Iterable, Mapping from functools import cached_property from random import Random @@ -45,7 +46,9 @@ def __init__( self._capacity: int = next(iter(self._cells.keys())).capacity if random is None: - random = Random() # FIXME + warnings.warn("Random number generator not specified, this can make models non-reproducible. Please pass a random number generator explicitly", + UserWarning, stacklevel=2) + random = Random() self.random = random def __iter__(self): # noqa diff --git a/mesa/experimental/cell_space/discrete_space.py b/mesa/experimental/cell_space/discrete_space.py index e30d913b23f..b4e77661c86 100644 --- a/mesa/experimental/cell_space/discrete_space.py +++ b/mesa/experimental/cell_space/discrete_space.py @@ -2,6 +2,7 @@ from __future__ import annotations +import warnings from collections.abc import Callable from functools import cached_property from random import Random @@ -44,6 +45,8 @@ def __init__( self.capacity = capacity self._cells: dict[tuple[int, ...], T] = {} if random is None: + warnings.warn("Random number generator not specified, this can make models non-reproducible. Please pass a random number generator explicitly", + UserWarning, stacklevel=2) random = Random() # FIXME should default to default rng from model self.random = random self.cell_klass = cell_klass From fd8e0648c9e96341a49e24f6d93767fc269b225e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 10 Nov 2024 11:30:24 +0000 Subject: [PATCH 02/10] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- mesa/agent.py | 7 +++++-- mesa/experimental/cell_space/cell_collection.py | 7 +++++-- mesa/experimental/cell_space/discrete_space.py | 7 +++++-- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/mesa/agent.py b/mesa/agent.py index 3c4600856e5..43d1ed863ec 100644 --- a/mesa/agent.py +++ b/mesa/agent.py @@ -120,8 +120,11 @@ def __init__(self, agents: Iterable[Agent], random: Random | None = None): random (Random): the random number generator """ if random is None: - warnings.warn("Random number generator not specified, this can make models non-reproducible. Please pass a random number generator explicitly", - UserWarning, stacklevel=2) + warnings.warn( + "Random number generator not specified, this can make models non-reproducible. Please pass a random number generator explicitly", + UserWarning, + stacklevel=2, + ) random = ( Random() ) # FIXME see issue 1981, how to get the central rng from model diff --git a/mesa/experimental/cell_space/cell_collection.py b/mesa/experimental/cell_space/cell_collection.py index 916583b1f6e..3d9829e1226 100644 --- a/mesa/experimental/cell_space/cell_collection.py +++ b/mesa/experimental/cell_space/cell_collection.py @@ -46,8 +46,11 @@ def __init__( self._capacity: int = next(iter(self._cells.keys())).capacity if random is None: - warnings.warn("Random number generator not specified, this can make models non-reproducible. Please pass a random number generator explicitly", - UserWarning, stacklevel=2) + warnings.warn( + "Random number generator not specified, this can make models non-reproducible. Please pass a random number generator explicitly", + UserWarning, + stacklevel=2, + ) random = Random() self.random = random diff --git a/mesa/experimental/cell_space/discrete_space.py b/mesa/experimental/cell_space/discrete_space.py index b4e77661c86..d1020029f1f 100644 --- a/mesa/experimental/cell_space/discrete_space.py +++ b/mesa/experimental/cell_space/discrete_space.py @@ -45,8 +45,11 @@ def __init__( self.capacity = capacity self._cells: dict[tuple[int, ...], T] = {} if random is None: - warnings.warn("Random number generator not specified, this can make models non-reproducible. Please pass a random number generator explicitly", - UserWarning, stacklevel=2) + warnings.warn( + "Random number generator not specified, this can make models non-reproducible. Please pass a random number generator explicitly", + UserWarning, + stacklevel=2, + ) random = Random() # FIXME should default to default rng from model self.random = random self.cell_klass = cell_klass From de7800106d62ac5b95466a9ba417c78b4936f073 Mon Sep 17 00:00:00 2001 From: Jan Kwakkel Date: Sun, 10 Nov 2024 12:35:15 +0100 Subject: [PATCH 03/10] Update mesa/experimental/cell_space/discrete_space.py --- mesa/experimental/cell_space/discrete_space.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mesa/experimental/cell_space/discrete_space.py b/mesa/experimental/cell_space/discrete_space.py index d1020029f1f..f8db5c2e4a0 100644 --- a/mesa/experimental/cell_space/discrete_space.py +++ b/mesa/experimental/cell_space/discrete_space.py @@ -50,7 +50,7 @@ def __init__( UserWarning, stacklevel=2, ) - random = Random() # FIXME should default to default rng from model + random = Random() self.random = random self.cell_klass = cell_klass From e2f0cf6cbf5cfa987702a28bd9bf86a94273fb22 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 10 Nov 2024 11:35:21 +0000 Subject: [PATCH 04/10] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- mesa/experimental/cell_space/discrete_space.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mesa/experimental/cell_space/discrete_space.py b/mesa/experimental/cell_space/discrete_space.py index f8db5c2e4a0..203322def15 100644 --- a/mesa/experimental/cell_space/discrete_space.py +++ b/mesa/experimental/cell_space/discrete_space.py @@ -50,7 +50,7 @@ def __init__( UserWarning, stacklevel=2, ) - random = Random() + random = Random() self.random = random self.cell_klass = cell_klass From 5e5f7e31e3d315c6edb63626af4f933b463f0198 Mon Sep 17 00:00:00 2001 From: Jan Kwakkel Date: Mon, 11 Nov 2024 08:28:28 +0100 Subject: [PATCH 05/10] update examples --- mesa/examples/advanced/pd_grid/model.py | 2 +- mesa/examples/advanced/sugarscape_g1mt/model.py | 2 +- mesa/experimental/cell_space/discrete_space.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mesa/examples/advanced/pd_grid/model.py b/mesa/examples/advanced/pd_grid/model.py index 35327a41ec5..938ea54c107 100644 --- a/mesa/examples/advanced/pd_grid/model.py +++ b/mesa/examples/advanced/pd_grid/model.py @@ -27,7 +27,7 @@ def __init__( """ super().__init__(seed=seed) self.activation_order = activation_order - self.grid = OrthogonalMooreGrid((width, height), torus=True) + self.grid = OrthogonalMooreGrid((width, height), torus=True, random=self.random) if payoffs is not None: self.payoff = payoffs diff --git a/mesa/examples/advanced/sugarscape_g1mt/model.py b/mesa/examples/advanced/sugarscape_g1mt/model.py index c6c5601cac3..4c0d78b587d 100644 --- a/mesa/examples/advanced/sugarscape_g1mt/model.py +++ b/mesa/examples/advanced/sugarscape_g1mt/model.py @@ -70,7 +70,7 @@ def __init__( self.running = True # initiate mesa grid class - self.grid = OrthogonalVonNeumannGrid((self.width, self.height), torus=False) + self.grid = OrthogonalVonNeumannGrid((self.width, self.height), torus=False, random=self.random) # initiate datacollector self.datacollector = mesa.DataCollector( model_reporters={ diff --git a/mesa/experimental/cell_space/discrete_space.py b/mesa/experimental/cell_space/discrete_space.py index 203322def15..9a1c560c0f1 100644 --- a/mesa/experimental/cell_space/discrete_space.py +++ b/mesa/experimental/cell_space/discrete_space.py @@ -73,7 +73,7 @@ def _connect_single_cell(self, cell: T): ... @cached_property def all_cells(self): """Return all cells in space.""" - return CellCollection({cell: cell.agents for cell in self._cells.values()}) + return CellCollection({cell: cell.agents for cell in self._cells.values()}, random=self.random) def __iter__(self): # noqa return iter(self._cells.values()) From 2098b230ffbc1351b645decf61180f4d313962e6 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 11 Nov 2024 07:28:45 +0000 Subject: [PATCH 06/10] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- mesa/examples/advanced/sugarscape_g1mt/model.py | 4 +++- mesa/experimental/cell_space/discrete_space.py | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/mesa/examples/advanced/sugarscape_g1mt/model.py b/mesa/examples/advanced/sugarscape_g1mt/model.py index 4c0d78b587d..055cd6fcae2 100644 --- a/mesa/examples/advanced/sugarscape_g1mt/model.py +++ b/mesa/examples/advanced/sugarscape_g1mt/model.py @@ -70,7 +70,9 @@ def __init__( self.running = True # initiate mesa grid class - self.grid = OrthogonalVonNeumannGrid((self.width, self.height), torus=False, random=self.random) + self.grid = OrthogonalVonNeumannGrid( + (self.width, self.height), torus=False, random=self.random + ) # initiate datacollector self.datacollector = mesa.DataCollector( model_reporters={ diff --git a/mesa/experimental/cell_space/discrete_space.py b/mesa/experimental/cell_space/discrete_space.py index 9a1c560c0f1..28fd3dfce37 100644 --- a/mesa/experimental/cell_space/discrete_space.py +++ b/mesa/experimental/cell_space/discrete_space.py @@ -73,7 +73,9 @@ def _connect_single_cell(self, cell: T): ... @cached_property def all_cells(self): """Return all cells in space.""" - return CellCollection({cell: cell.agents for cell in self._cells.values()}, random=self.random) + return CellCollection( + {cell: cell.agents for cell in self._cells.values()}, random=self.random + ) def __iter__(self): # noqa return iter(self._cells.values()) From a834377afee3ecd2ab1fad48e0015571ebbe08bf Mon Sep 17 00:00:00 2001 From: Jan Kwakkel Date: Mon, 11 Nov 2024 08:30:05 +0100 Subject: [PATCH 07/10] Update cell_collection.py --- mesa/experimental/cell_space/cell_collection.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mesa/experimental/cell_space/cell_collection.py b/mesa/experimental/cell_space/cell_collection.py index 3d9829e1226..fefd5fd74ae 100644 --- a/mesa/experimental/cell_space/cell_collection.py +++ b/mesa/experimental/cell_space/cell_collection.py @@ -121,4 +121,4 @@ def cell_generator(filter_func, at_most): yield cell count += 1 - return CellCollection(cell_generator(filter_func, at_most)) + return CellCollection(cell_generator(filter_func, at_most), random=self.random) From a9e10922681ceed95a34a5f1f278f3d01ce4dbec Mon Sep 17 00:00:00 2001 From: Jan Kwakkel Date: Mon, 11 Nov 2024 08:40:32 +0100 Subject: [PATCH 08/10] Update test_cell_space.py --- tests/test_cell_space.py | 66 ++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/tests/test_cell_space.py b/tests/test_cell_space.py index 13159784c22..31a42271907 100644 --- a/tests/test_cell_space.py +++ b/tests/test_cell_space.py @@ -25,7 +25,7 @@ def test_orthogonal_grid_neumann(): """Test orthogonal grid with von Neumann neighborhood.""" width = 10 height = 10 - grid = OrthogonalVonNeumannGrid((width, height), torus=False, capacity=None) + grid = OrthogonalVonNeumannGrid((width, height), torus=False, capacity=None, random=random.Random(42)) assert len(grid._cells) == width * height @@ -55,7 +55,7 @@ def test_orthogonal_grid_neumann(): assert connection.coordinate in {(4, 5), (5, 4), (5, 6), (6, 5)} # von neumann neighborhood, torus True, top corner - grid = OrthogonalVonNeumannGrid((width, height), torus=True, capacity=None) + grid = OrthogonalVonNeumannGrid((width, height), torus=True, capacity=None, random=random.Random(42)) assert len(grid._cells[(0, 0)].connections.values()) == 4 for connection in grid._cells[(0, 0)].connections.values(): assert connection.coordinate in {(0, 1), (1, 0), (0, 9), (9, 0)} @@ -78,7 +78,7 @@ def test_orthogonal_grid_neumann_3d(): width = 10 height = 10 depth = 10 - grid = OrthogonalVonNeumannGrid((width, height, depth), torus=False, capacity=None) + grid = OrthogonalVonNeumannGrid((width, height, depth), torus=False, capacity=None, random=random.Random(42)) assert len(grid._cells) == width * height * depth @@ -124,7 +124,7 @@ def test_orthogonal_grid_neumann_3d(): } # von neumann neighborhood, torus True, top corner - grid = OrthogonalVonNeumannGrid((width, height, depth), torus=True, capacity=None) + grid = OrthogonalVonNeumannGrid((width, height, depth), torus=True, capacity=None, random=random.Random(42)) assert len(grid._cells[(0, 0, 0)].connections.values()) == 6 for connection in grid._cells[(0, 0, 0)].connections.values(): assert connection.coordinate in { @@ -143,7 +143,7 @@ def test_orthogonal_grid_moore(): height = 10 # Moore neighborhood, torus false, top corner - grid = OrthogonalMooreGrid((width, height), torus=False, capacity=None) + grid = OrthogonalMooreGrid((width, height), torus=False, capacity=None, random=random.Random(42)) assert len(grid._cells[(0, 0)].connections.values()) == 3 for connection in grid._cells[(0, 0)].connections.values(): assert connection.coordinate in {(0, 1), (1, 0), (1, 1)} @@ -158,7 +158,7 @@ def test_orthogonal_grid_moore(): # fmt: on # Moore neighborhood, torus True, top corner - grid = OrthogonalMooreGrid([10, 10], torus=True, capacity=None) + grid = OrthogonalMooreGrid([10, 10], torus=True, capacity=None, random=random.Random(42)) assert len(grid._cells[(0, 0)].connections.values()) == 8 for connection in grid._cells[(0, 0)].connections.values(): # fmt: off @@ -175,7 +175,7 @@ def test_orthogonal_grid_moore_3d(): depth = 10 # Moore neighborhood, torus false, top corner - grid = OrthogonalMooreGrid((width, height, depth), torus=False, capacity=None) + grid = OrthogonalMooreGrid((width, height, depth), torus=False, capacity=None, random=random.Random(42)) assert len(grid._cells[(0, 0, 0)].connections.values()) == 7 for connection in grid._cells[(0, 0, 0)].connections.values(): assert connection.coordinate in { @@ -198,7 +198,7 @@ def test_orthogonal_grid_moore_3d(): # fmt: on # Moore neighborhood, torus True, top corner - grid = OrthogonalMooreGrid((width, height, depth), torus=True, capacity=None) + grid = OrthogonalMooreGrid((width, height, depth), torus=True, capacity=None, random=random.Random(42)) assert len(grid._cells[(0, 0, 0)].connections.values()) == 26 for connection in grid._cells[(0, 0, 0)].connections.values(): # fmt: off @@ -216,7 +216,7 @@ def test_orthogonal_grid_moore_4d(): time = 10 # Moore neighborhood, torus false, top corner - grid = OrthogonalMooreGrid((width, height, depth, time), torus=False, capacity=None) + grid = OrthogonalMooreGrid((width, height, depth, time), torus=False, capacity=None, random=random.Random(42)) assert len(grid._cells[(0, 0, 0, 0)].connections.values()) == 15 for connection in grid._cells[(0, 0, 0, 0)].connections.values(): assert connection.coordinate in { @@ -258,7 +258,7 @@ def test_orthogonal_grid_moore_1d(): width = 10 # Moore neighborhood, torus false, left edge - grid = OrthogonalMooreGrid((width,), torus=False, capacity=None) + grid = OrthogonalMooreGrid((width,), torus=False, capacity=None, random=random.Random(42)) assert len(grid._cells[(0,)].connections.values()) == 1 for connection in grid._cells[(0,)].connections.values(): assert connection.coordinate in {(1,)} @@ -269,7 +269,7 @@ def test_orthogonal_grid_moore_1d(): assert connection.coordinate in {(4,), (6,)} # Moore neighborhood, torus True, left edge - grid = OrthogonalMooreGrid((width,), torus=True, capacity=None) + grid = OrthogonalMooreGrid((width,), torus=True, capacity=None, random=random.Random(42)) assert len(grid._cells[(0,)].connections.values()) == 2 for connection in grid._cells[(0,)].connections.values(): assert connection.coordinate in {(1,), (9,)} @@ -282,7 +282,7 @@ def test_cell_neighborhood(): ## von Neumann width = 10 height = 10 - grid = OrthogonalVonNeumannGrid((width, height), torus=False, capacity=None) + grid = OrthogonalVonNeumannGrid((width, height), torus=False, capacity=None, random=random.Random(42)) for radius, n in zip(range(1, 4), [2, 5, 9]): if radius == 1: neighborhood = grid._cells[(0, 0)].neighborhood @@ -293,7 +293,7 @@ def test_cell_neighborhood(): ## Moore width = 10 height = 10 - grid = OrthogonalMooreGrid((width, height), torus=False, capacity=None) + grid = OrthogonalMooreGrid((width, height), torus=False, capacity=None, random=random.Random(42)) for radius, n in zip(range(1, 4), [3, 8, 15]): if radius == 1: neighborhood = grid._cells[(0, 0)].neighborhood @@ -307,7 +307,7 @@ def test_cell_neighborhood(): # hexgrid width = 10 height = 10 - grid = HexGrid((width, height), torus=False, capacity=None) + grid = HexGrid((width, height), torus=False, capacity=None, random=random.Random(42)) for radius, n in zip(range(1, 4), [2, 6, 11]): if radius == 1: neighborhood = grid._cells[(0, 0)].neighborhood @@ -317,7 +317,7 @@ def test_cell_neighborhood(): width = 10 height = 10 - grid = HexGrid((width, height), torus=False, capacity=None) + grid = HexGrid((width, height), torus=False, capacity=None, random=random.Random(42)) for radius, n in zip(range(1, 4), [5, 10, 17]): if radius == 1: neighborhood = grid._cells[(1, 0)].neighborhood @@ -333,7 +333,7 @@ def test_hexgrid(): width = 10 height = 10 - grid = HexGrid((width, height), torus=False) + grid = HexGrid((width, height), torus=False, random=random.Random(42)) assert len(grid._cells) == width * height # first row @@ -369,7 +369,7 @@ def test_hexgrid(): # fmt: on - grid = HexGrid((width, height), torus=True) + grid = HexGrid((width, height), torus=True, random=random.Random(42)) assert len(grid._cells) == width * height # first row @@ -391,7 +391,7 @@ def test_networkgrid(): m = 20 seed = 42 G = nx.gnm_random_graph(n, m, seed=seed) # noqa: N806 - grid = Network(G) + grid = Network(G, random=random.Random(42)) assert len(grid._cells) == n @@ -404,7 +404,7 @@ def test_voronoigrid(): """Test VoronoiGrid.""" points = [[0, 1], [1, 3], [1.1, 1], [1, 1]] - grid = VoronoiGrid(points) + grid = VoronoiGrid(points, random=random.Random(42)) assert len(grid._cells) == len(points) @@ -414,13 +414,13 @@ def test_voronoigrid(): assert connection.coordinate in [[1, 1], [1, 3]] with pytest.raises(ValueError): - VoronoiGrid(points, capacity="str") + VoronoiGrid(points, capacity="str", random=random.Random(42)) with pytest.raises(ValueError): - VoronoiGrid((1, 1)) + VoronoiGrid((1, 1), random=random.Random(42)) with pytest.raises(ValueError): - VoronoiGrid([[0, 1], [0, 1, 1]]) + VoronoiGrid([[0, 1], [0, 1, 1]], random=random.Random(42)) def test_empties_space(): @@ -431,7 +431,7 @@ def test_empties_space(): m = 20 seed = 42 G = nx.gnm_random_graph(n, m, seed=seed) # noqa: N806 - grid = Network(G) + grid = Network(G, random=random.Random(42)) assert len(grid.empties) == n @@ -448,7 +448,7 @@ def test_agents_property(): m = 20 seed = 42 G = nx.gnm_random_graph(n, m, seed=seed) # noqa: N806 - grid = Network(G) + grid = Network(G, random=random.Random(42)) model = Model() for i in range(8): @@ -554,7 +554,7 @@ def test_cell_collection(): def test_property_layer_integration(): """Test integration of PropertyLayer with DiscrateSpace and Cell.""" width, height = 10, 10 - grid = OrthogonalMooreGrid((width, height), torus=False) + grid = OrthogonalMooreGrid((width, height), torus=False, random=random.Random(42)) # Test adding a PropertyLayer to the grid elevation = PropertyLayer("elevation", width, height, default_value=0) @@ -599,13 +599,13 @@ def test_multiple_property_layers(): temperature = PropertyLayer("temperature", width, height, default_value=20) # Test initialization with a single PropertyLayer - grid1 = OrthogonalMooreGrid((width, height), torus=False) + grid1 = OrthogonalMooreGrid((width, height), torus=False, random=random.Random(42)) grid1.add_property_layer(elevation) assert "elevation" in grid1.property_layers assert len(grid1.property_layers) == 1 # Test initialization with multiple PropertyLayers - grid2 = OrthogonalMooreGrid((width, height), torus=False) + grid2 = OrthogonalMooreGrid((width, height), torus=False, random=random.Random(42)) grid2.add_property_layer(temperature, add_to_cells=False) grid2.add_property_layer(elevation, add_to_cells=True) @@ -627,7 +627,7 @@ def test_multiple_property_layers(): def test_property_layer_errors(): """Test error handling for PropertyLayers.""" width, height = 5, 5 - grid = OrthogonalMooreGrid((width, height), torus=False) + grid = OrthogonalMooreGrid((width, height), torus=False, random=random.Random(42)) elevation = PropertyLayer("elevation", width, height, default_value=0) # Test adding a PropertyLayer with an existing name @@ -674,7 +674,7 @@ def test_cell_agent(): # noqa: D103 def test_grid2DMovingAgent(): # noqa: D103 # we first test on a moore grid because all directions are defined - grid = OrthogonalMooreGrid((10, 10), torus=False) + grid = OrthogonalMooreGrid((10, 10), torus=False, random=random.Random(42)) model = Model() agent = Grid2DMovingAgent(model) @@ -683,7 +683,7 @@ def test_grid2DMovingAgent(): # noqa: D103 agent.move("up") assert agent.cell == grid[3, 4] - grid = OrthogonalVonNeumannGrid((10, 10), torus=False) + grid = OrthogonalVonNeumannGrid((10, 10), torus=False, random=random.Random(42)) model = Model() agent = Grid2DMovingAgent(model) @@ -720,7 +720,7 @@ def test_copying_discrete_spaces(): # noqa: D103 import networkx as nx - grid = OrthogonalMooreGrid((100, 100)) + grid = OrthogonalMooreGrid((100, 100), random=random.Random(42)) grid_copy = copy.deepcopy(grid) c1 = grid[(5, 5)].connections @@ -734,14 +734,14 @@ def test_copying_discrete_spaces(): # noqa: D103 m = 20 seed = 42 G = nx.gnm_random_graph(n, m, seed=seed) # noqa: N806 - grid = Network(G) + grid = Network(G, random=random.Random(42)) grid_copy = copy.deepcopy(grid) for c1, c2 in zip(grid.all_cells, grid_copy.all_cells): for k, v in c1.connections.items(): assert v.coordinate == c2.connections[k].coordinate - grid = HexGrid((100, 100)) + grid = HexGrid((100, 100), random=random.Random(42)) grid_copy = copy.deepcopy(grid) c1 = grid[(5, 5)].connections From 4a868aefd617e48158284ade2d936637653424cb Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 11 Nov 2024 07:40:56 +0000 Subject: [PATCH 09/10] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tests/test_cell_space.py | 63 ++++++++++++++++++++++++++++++---------- 1 file changed, 48 insertions(+), 15 deletions(-) diff --git a/tests/test_cell_space.py b/tests/test_cell_space.py index 31a42271907..add5f6f8ce8 100644 --- a/tests/test_cell_space.py +++ b/tests/test_cell_space.py @@ -25,7 +25,9 @@ def test_orthogonal_grid_neumann(): """Test orthogonal grid with von Neumann neighborhood.""" width = 10 height = 10 - grid = OrthogonalVonNeumannGrid((width, height), torus=False, capacity=None, random=random.Random(42)) + grid = OrthogonalVonNeumannGrid( + (width, height), torus=False, capacity=None, random=random.Random(42) + ) assert len(grid._cells) == width * height @@ -55,7 +57,9 @@ def test_orthogonal_grid_neumann(): assert connection.coordinate in {(4, 5), (5, 4), (5, 6), (6, 5)} # von neumann neighborhood, torus True, top corner - grid = OrthogonalVonNeumannGrid((width, height), torus=True, capacity=None, random=random.Random(42)) + grid = OrthogonalVonNeumannGrid( + (width, height), torus=True, capacity=None, random=random.Random(42) + ) assert len(grid._cells[(0, 0)].connections.values()) == 4 for connection in grid._cells[(0, 0)].connections.values(): assert connection.coordinate in {(0, 1), (1, 0), (0, 9), (9, 0)} @@ -78,7 +82,9 @@ def test_orthogonal_grid_neumann_3d(): width = 10 height = 10 depth = 10 - grid = OrthogonalVonNeumannGrid((width, height, depth), torus=False, capacity=None, random=random.Random(42)) + grid = OrthogonalVonNeumannGrid( + (width, height, depth), torus=False, capacity=None, random=random.Random(42) + ) assert len(grid._cells) == width * height * depth @@ -124,7 +130,9 @@ def test_orthogonal_grid_neumann_3d(): } # von neumann neighborhood, torus True, top corner - grid = OrthogonalVonNeumannGrid((width, height, depth), torus=True, capacity=None, random=random.Random(42)) + grid = OrthogonalVonNeumannGrid( + (width, height, depth), torus=True, capacity=None, random=random.Random(42) + ) assert len(grid._cells[(0, 0, 0)].connections.values()) == 6 for connection in grid._cells[(0, 0, 0)].connections.values(): assert connection.coordinate in { @@ -143,7 +151,9 @@ def test_orthogonal_grid_moore(): height = 10 # Moore neighborhood, torus false, top corner - grid = OrthogonalMooreGrid((width, height), torus=False, capacity=None, random=random.Random(42)) + grid = OrthogonalMooreGrid( + (width, height), torus=False, capacity=None, random=random.Random(42) + ) assert len(grid._cells[(0, 0)].connections.values()) == 3 for connection in grid._cells[(0, 0)].connections.values(): assert connection.coordinate in {(0, 1), (1, 0), (1, 1)} @@ -158,7 +168,9 @@ def test_orthogonal_grid_moore(): # fmt: on # Moore neighborhood, torus True, top corner - grid = OrthogonalMooreGrid([10, 10], torus=True, capacity=None, random=random.Random(42)) + grid = OrthogonalMooreGrid( + [10, 10], torus=True, capacity=None, random=random.Random(42) + ) assert len(grid._cells[(0, 0)].connections.values()) == 8 for connection in grid._cells[(0, 0)].connections.values(): # fmt: off @@ -175,7 +187,9 @@ def test_orthogonal_grid_moore_3d(): depth = 10 # Moore neighborhood, torus false, top corner - grid = OrthogonalMooreGrid((width, height, depth), torus=False, capacity=None, random=random.Random(42)) + grid = OrthogonalMooreGrid( + (width, height, depth), torus=False, capacity=None, random=random.Random(42) + ) assert len(grid._cells[(0, 0, 0)].connections.values()) == 7 for connection in grid._cells[(0, 0, 0)].connections.values(): assert connection.coordinate in { @@ -198,7 +212,9 @@ def test_orthogonal_grid_moore_3d(): # fmt: on # Moore neighborhood, torus True, top corner - grid = OrthogonalMooreGrid((width, height, depth), torus=True, capacity=None, random=random.Random(42)) + grid = OrthogonalMooreGrid( + (width, height, depth), torus=True, capacity=None, random=random.Random(42) + ) assert len(grid._cells[(0, 0, 0)].connections.values()) == 26 for connection in grid._cells[(0, 0, 0)].connections.values(): # fmt: off @@ -216,7 +232,12 @@ def test_orthogonal_grid_moore_4d(): time = 10 # Moore neighborhood, torus false, top corner - grid = OrthogonalMooreGrid((width, height, depth, time), torus=False, capacity=None, random=random.Random(42)) + grid = OrthogonalMooreGrid( + (width, height, depth, time), + torus=False, + capacity=None, + random=random.Random(42), + ) assert len(grid._cells[(0, 0, 0, 0)].connections.values()) == 15 for connection in grid._cells[(0, 0, 0, 0)].connections.values(): assert connection.coordinate in { @@ -258,7 +279,9 @@ def test_orthogonal_grid_moore_1d(): width = 10 # Moore neighborhood, torus false, left edge - grid = OrthogonalMooreGrid((width,), torus=False, capacity=None, random=random.Random(42)) + grid = OrthogonalMooreGrid( + (width,), torus=False, capacity=None, random=random.Random(42) + ) assert len(grid._cells[(0,)].connections.values()) == 1 for connection in grid._cells[(0,)].connections.values(): assert connection.coordinate in {(1,)} @@ -269,7 +292,9 @@ def test_orthogonal_grid_moore_1d(): assert connection.coordinate in {(4,), (6,)} # Moore neighborhood, torus True, left edge - grid = OrthogonalMooreGrid((width,), torus=True, capacity=None, random=random.Random(42)) + grid = OrthogonalMooreGrid( + (width,), torus=True, capacity=None, random=random.Random(42) + ) assert len(grid._cells[(0,)].connections.values()) == 2 for connection in grid._cells[(0,)].connections.values(): assert connection.coordinate in {(1,), (9,)} @@ -282,7 +307,9 @@ def test_cell_neighborhood(): ## von Neumann width = 10 height = 10 - grid = OrthogonalVonNeumannGrid((width, height), torus=False, capacity=None, random=random.Random(42)) + grid = OrthogonalVonNeumannGrid( + (width, height), torus=False, capacity=None, random=random.Random(42) + ) for radius, n in zip(range(1, 4), [2, 5, 9]): if radius == 1: neighborhood = grid._cells[(0, 0)].neighborhood @@ -293,7 +320,9 @@ def test_cell_neighborhood(): ## Moore width = 10 height = 10 - grid = OrthogonalMooreGrid((width, height), torus=False, capacity=None, random=random.Random(42)) + grid = OrthogonalMooreGrid( + (width, height), torus=False, capacity=None, random=random.Random(42) + ) for radius, n in zip(range(1, 4), [3, 8, 15]): if radius == 1: neighborhood = grid._cells[(0, 0)].neighborhood @@ -307,7 +336,9 @@ def test_cell_neighborhood(): # hexgrid width = 10 height = 10 - grid = HexGrid((width, height), torus=False, capacity=None, random=random.Random(42)) + grid = HexGrid( + (width, height), torus=False, capacity=None, random=random.Random(42) + ) for radius, n in zip(range(1, 4), [2, 6, 11]): if radius == 1: neighborhood = grid._cells[(0, 0)].neighborhood @@ -317,7 +348,9 @@ def test_cell_neighborhood(): width = 10 height = 10 - grid = HexGrid((width, height), torus=False, capacity=None, random=random.Random(42)) + grid = HexGrid( + (width, height), torus=False, capacity=None, random=random.Random(42) + ) for radius, n in zip(range(1, 4), [5, 10, 17]): if radius == 1: neighborhood = grid._cells[(1, 0)].neighborhood From fb247b0f892376ff1593b49622b7529982590e98 Mon Sep 17 00:00:00 2001 From: Jan Kwakkel Date: Mon, 11 Nov 2024 10:08:46 +0100 Subject: [PATCH 10/10] add docstrings --- mesa/agent.py | 6 ++++++ mesa/experimental/cell_space/cell_collection.py | 6 ++++++ mesa/experimental/cell_space/discrete_space.py | 6 ++++++ 3 files changed, 18 insertions(+) diff --git a/mesa/agent.py b/mesa/agent.py index 43d1ed863ec..ba94f025ee1 100644 --- a/mesa/agent.py +++ b/mesa/agent.py @@ -110,6 +110,12 @@ class AgentSet(MutableSet, Sequence): without preventing garbage collection. It is associated with a specific model instance, enabling interactions with the model's environment and other agents.The implementation uses a WeakKeyDictionary to store agents, which means that agents not referenced elsewhere in the program may be automatically removed from the AgentSet. + + Notes: + A `UserWarning` is issued if `random=None`. You can resolve this warning by explicitly + passing a random number generator. In most cases, this will be the seeded random number + generator in the model. So, you would do `random=self.random` in a `Model` or `Agent` instance. + """ def __init__(self, agents: Iterable[Agent], random: Random | None = None): diff --git a/mesa/experimental/cell_space/cell_collection.py b/mesa/experimental/cell_space/cell_collection.py index fefd5fd74ae..ead67021532 100644 --- a/mesa/experimental/cell_space/cell_collection.py +++ b/mesa/experimental/cell_space/cell_collection.py @@ -24,6 +24,12 @@ class CellCollection(Generic[T]): agents (List[CellAgent]) : List of agents occupying the cells in this collection random (Random) : The random number generator + Notes: + A `UserWarning` is issued if `random=None`. You can resolve this warning by explicitly + passing a random number generator. In most cases, this will be the seeded random number + generator in the model. So, you would do `random=self.random` in a `Model` or `Agent` instance. + + """ def __init__( diff --git a/mesa/experimental/cell_space/discrete_space.py b/mesa/experimental/cell_space/discrete_space.py index 28fd3dfce37..a017d06bda8 100644 --- a/mesa/experimental/cell_space/discrete_space.py +++ b/mesa/experimental/cell_space/discrete_space.py @@ -26,6 +26,12 @@ class DiscreteSpace(Generic[T]): cell_klass (Type) : the type of cell class empties (CellCollection) : collection of all cells that are empty property_layers (dict[str, PropertyLayer]): the property layers of the discrete space + + Notes: + A `UserWarning` is issued if `random=None`. You can resolve this warning by explicitly + passing a random number generator. In most cases, this will be the seeded random number + generator in the model. So, you would do `random=self.random` in a `Model` or `Agent` instance. + """ def __init__(