From 31d0b43b977c90e28aa470d5dca259bd63261b14 Mon Sep 17 00:00:00 2001 From: Jan Kwakkel Date: Sat, 21 Sep 2024 10:42:32 +0200 Subject: [PATCH 1/9] have a dedicated neighborhood property and a get method --- mesa/experimental/cell_space/cell.py | 27 +++++++++++++++++++++++++-- tests/test_cell_space.py | 22 +++++++++++++++++----- 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/mesa/experimental/cell_space/cell.py b/mesa/experimental/cell_space/cell.py index 381d0f6cccb..864282b487f 100644 --- a/mesa/experimental/cell_space/cell.py +++ b/mesa/experimental/cell_space/cell.py @@ -131,10 +131,33 @@ def is_full(self) -> bool: def __repr__(self): # noqa return f"Cell({self.coordinate}, {self.agents})" + + @property + @cache + def neighborhood(self) -> CellCollection: + """Returns the direct neigborhood of the cell + + This is equivalent to cell.get_neighborhood(radius=1) + + """ + return self.get_neighborhood(radius=1) + # FIXME: Revisit caching strategy on methods @cache # noqa: B019 - def neighborhood(self, radius: int = 1, include_center: bool = False): - """Returns a list of all neighboring cells.""" + def get_neighborhood(self, radius: int = 1, include_center: bool = False) -> CellCollection: + """Returns a list of all neighboring cells for the given radius + + For getting the direct neighborhood (i.e., radius=1) you can also use + the `neighborhood` property. + + Args: + radius (int): the radius of the neighborhood + include_center (bool): include the center of the neighborhood + + Returns + a list of all neighboring cells + + """ return CellCollection[Cell]( self._neighborhood(radius=radius, include_center=include_center), random=self.random, diff --git a/tests/test_cell_space.py b/tests/test_cell_space.py index 5ef4c44e21d..e9993b4198a 100644 --- a/tests/test_cell_space.py +++ b/tests/test_cell_space.py @@ -280,7 +280,10 @@ def test_cell_neighborhood(): height = 10 grid = OrthogonalVonNeumannGrid((width, height), torus=False, capacity=None) for radius, n in zip(range(1, 4), [2, 5, 9]): - neighborhood = grid._cells[(0, 0)].neighborhood(radius=radius) + if radius == 1: + neighborhood = grid._cells[(0, 0)].neighborhood + else: + neighborhood = grid._cells[(0, 0)].get_neighborhood(radius=radius) assert len(neighborhood) == n ## Moore @@ -288,25 +291,34 @@ def test_cell_neighborhood(): height = 10 grid = OrthogonalMooreGrid((width, height), torus=False, capacity=None) for radius, n in zip(range(1, 4), [3, 8, 15]): - neighborhood = grid._cells[(0, 0)].neighborhood(radius=radius) + if radius == 1: + neighborhood = grid._cells[(0, 0)].neighborhood + else: + neighborhood = grid._cells[(0, 0)].get_neighborhood(radius=radius) assert len(neighborhood) == n with pytest.raises(ValueError): - grid._cells[(0, 0)].neighborhood(radius=0) + grid._cells[(0, 0)].get_neighborhood(radius=0) # hexgrid width = 10 height = 10 grid = HexGrid((width, height), torus=False, capacity=None) for radius, n in zip(range(1, 4), [2, 6, 11]): - neighborhood = grid._cells[(0, 0)].neighborhood(radius=radius) + if radius == 1: + neighborhood = grid._cells[(0, 0)].neighborhood + else: + neighborhood = grid._cells[(0, 0)].get_neighborhood(radius=radius) assert len(neighborhood) == n width = 10 height = 10 grid = HexGrid((width, height), torus=False, capacity=None) for radius, n in zip(range(1, 4), [5, 10, 17]): - neighborhood = grid._cells[(1, 0)].neighborhood(radius=radius) + if radius == 1: + neighborhood = grid._cells[(1, 0)].neighborhood + else: + neighborhood = grid._cells[(1, 0)].get_neighborhood(radius=radius) assert len(neighborhood) == n # networkgrid From 887d7ce3252ae3fcf7312c0f463b15339ab2f5f3 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 21 Sep 2024 08:45:43 +0000 Subject: [PATCH 2/9] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- mesa/experimental/cell_space/cell.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mesa/experimental/cell_space/cell.py b/mesa/experimental/cell_space/cell.py index 864282b487f..144f8195007 100644 --- a/mesa/experimental/cell_space/cell.py +++ b/mesa/experimental/cell_space/cell.py @@ -131,7 +131,6 @@ def is_full(self) -> bool: def __repr__(self): # noqa return f"Cell({self.coordinate}, {self.agents})" - @property @cache def neighborhood(self) -> CellCollection: @@ -144,7 +143,9 @@ def neighborhood(self) -> CellCollection: # FIXME: Revisit caching strategy on methods @cache # noqa: B019 - def get_neighborhood(self, radius: int = 1, include_center: bool = False) -> CellCollection: + def get_neighborhood( + self, radius: int = 1, include_center: bool = False + ) -> CellCollection: """Returns a list of all neighboring cells for the given radius For getting the direct neighborhood (i.e., radius=1) you can also use @@ -154,7 +155,7 @@ def get_neighborhood(self, radius: int = 1, include_center: bool = False) -> Cel radius (int): the radius of the neighborhood include_center (bool): include the center of the neighborhood - Returns + Returns: a list of all neighboring cells """ From e61d4e8f77967eec185e5bf87b23ba239f48bade Mon Sep 17 00:00:00 2001 From: Jan Kwakkel Date: Sat, 21 Sep 2024 10:49:52 +0200 Subject: [PATCH 3/9] Update mesa/experimental/cell_space/cell.py Co-authored-by: Ewout ter Hoeven --- mesa/experimental/cell_space/cell.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mesa/experimental/cell_space/cell.py b/mesa/experimental/cell_space/cell.py index 144f8195007..a2ccc1c2b2a 100644 --- a/mesa/experimental/cell_space/cell.py +++ b/mesa/experimental/cell_space/cell.py @@ -139,7 +139,7 @@ def neighborhood(self) -> CellCollection: This is equivalent to cell.get_neighborhood(radius=1) """ - return self.get_neighborhood(radius=1) + return self.get_neighborhood() # FIXME: Revisit caching strategy on methods @cache # noqa: B019 From 54ffc094255f2a1ffa5fbd6ed92573a5d3befc22 Mon Sep 17 00:00:00 2001 From: Jan Kwakkel Date: Sat, 21 Sep 2024 10:53:22 +0200 Subject: [PATCH 4/9] fix benchmark models --- benchmarks/Schelling/schelling.py | 2 +- benchmarks/WolfSheep/wolf_sheep.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/benchmarks/Schelling/schelling.py b/benchmarks/Schelling/schelling.py index 47bf521e057..cc2b9d4cf46 100644 --- a/benchmarks/Schelling/schelling.py +++ b/benchmarks/Schelling/schelling.py @@ -25,7 +25,7 @@ def __init__(self, model, agent_type, radius, homophily): def step(self): """Run one step of the agent.""" similar = 0 - neighborhood = self.cell.neighborhood(radius=self.radius) + neighborhood = self.cell.get_neighborhood(radius=self.radius) for neighbor in neighborhood.agents: if neighbor.type == self.type: similar += 1 diff --git a/benchmarks/WolfSheep/wolf_sheep.py b/benchmarks/WolfSheep/wolf_sheep.py index 16c01e000c1..903c18665b9 100644 --- a/benchmarks/WolfSheep/wolf_sheep.py +++ b/benchmarks/WolfSheep/wolf_sheep.py @@ -33,7 +33,7 @@ def __init__(self, model, energy, p_reproduce, energy_from_food): def random_move(self): """Move to a random neighboring cell.""" - self.move_to(self.cell.neighborhood().select_random_cell()) + self.move_to(self.cell.get_neighborhood().select_random_cell()) def spawn_offspring(self): """Create offspring.""" From 1538310bb21aea2bf9f4236bc88f65817b858696 Mon Sep 17 00:00:00 2001 From: Jan Kwakkel Date: Sat, 21 Sep 2024 10:53:56 +0200 Subject: [PATCH 5/9] even cleaner --- benchmarks/WolfSheep/wolf_sheep.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/benchmarks/WolfSheep/wolf_sheep.py b/benchmarks/WolfSheep/wolf_sheep.py index 903c18665b9..aaeed13536c 100644 --- a/benchmarks/WolfSheep/wolf_sheep.py +++ b/benchmarks/WolfSheep/wolf_sheep.py @@ -33,7 +33,7 @@ def __init__(self, model, energy, p_reproduce, energy_from_food): def random_move(self): """Move to a random neighboring cell.""" - self.move_to(self.cell.get_neighborhood().select_random_cell()) + self.move_to(self.cell.neighborhood.select_random_cell()) def spawn_offspring(self): """Create offspring.""" From 66cc965f4a8cf98ea082e0623486fae1f0b40808 Mon Sep 17 00:00:00 2001 From: Jan Kwakkel Date: Sat, 21 Sep 2024 14:40:40 +0200 Subject: [PATCH 6/9] switch to cached_property --- mesa/experimental/cell_space/cell.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/mesa/experimental/cell_space/cell.py b/mesa/experimental/cell_space/cell.py index a2ccc1c2b2a..981ca438d67 100644 --- a/mesa/experimental/cell_space/cell.py +++ b/mesa/experimental/cell_space/cell.py @@ -2,7 +2,7 @@ from __future__ import annotations -from functools import cache +from functools import cache, cached_property from random import Random from typing import TYPE_CHECKING @@ -131,8 +131,7 @@ def is_full(self) -> bool: def __repr__(self): # noqa return f"Cell({self.coordinate}, {self.agents})" - @property - @cache + @cached_property def neighborhood(self) -> CellCollection: """Returns the direct neigborhood of the cell From 417a011dc25547fbed8eb4b65fe7b8bbd064abf3 Mon Sep 17 00:00:00 2001 From: Jan Kwakkel Date: Sat, 21 Sep 2024 16:40:11 +0200 Subject: [PATCH 7/9] fix for failing tests --- mesa/experimental/cell_space/cell.py | 1 + 1 file changed, 1 insertion(+) diff --git a/mesa/experimental/cell_space/cell.py b/mesa/experimental/cell_space/cell.py index 981ca438d67..7073520aa0b 100644 --- a/mesa/experimental/cell_space/cell.py +++ b/mesa/experimental/cell_space/cell.py @@ -34,6 +34,7 @@ class Cell: "capacity", "properties", "random", + "__dict__" ] # def __new__(cls, From be9e30f83bd279b2a4f7b21ea0e415d8fd1abe0b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 21 Sep 2024 14:40:20 +0000 Subject: [PATCH 8/9] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- mesa/experimental/cell_space/cell.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mesa/experimental/cell_space/cell.py b/mesa/experimental/cell_space/cell.py index 7073520aa0b..2fc17390b49 100644 --- a/mesa/experimental/cell_space/cell.py +++ b/mesa/experimental/cell_space/cell.py @@ -34,7 +34,7 @@ class Cell: "capacity", "properties", "random", - "__dict__" + "__dict__", ] # def __new__(cls, From 4fb59dda80a93d937d0d09af2f2ae96c0d190110 Mon Sep 17 00:00:00 2001 From: Ewout ter Hoeven Date: Sat, 21 Sep 2024 16:48:23 +0200 Subject: [PATCH 9/9] Fix ruff: It wants a point after the first docs sentence. --- mesa/experimental/cell_space/cell.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mesa/experimental/cell_space/cell.py b/mesa/experimental/cell_space/cell.py index 2fc17390b49..8eef711cc7d 100644 --- a/mesa/experimental/cell_space/cell.py +++ b/mesa/experimental/cell_space/cell.py @@ -134,7 +134,7 @@ def __repr__(self): # noqa @cached_property def neighborhood(self) -> CellCollection: - """Returns the direct neigborhood of the cell + """Returns the direct neigborhood of the cell. This is equivalent to cell.get_neighborhood(radius=1) @@ -146,7 +146,7 @@ def neighborhood(self) -> CellCollection: def get_neighborhood( self, radius: int = 1, include_center: bool = False ) -> CellCollection: - """Returns a list of all neighboring cells for the given radius + """Returns a list of all neighboring cells for the given radius. For getting the direct neighborhood (i.e., radius=1) you can also use the `neighborhood` property.