Skip to content

Commit 7d18880

Browse files
committed
Merge remote-tracking branch 'upstream/main'
2 parents fe3d655 + 725143f commit 7d18880

File tree

28 files changed

+1044
-208
lines changed

28 files changed

+1044
-208
lines changed

.github/ISSUE_TEMPLATE/asking-help.md

Lines changed: 0 additions & 9 deletions
This file was deleted.

.github/ISSUE_TEMPLATE/bug-report.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ about: Let us know if something is broken on Mesa
1111
<!-- A clear and concise description of what you expected to happen -->
1212

1313
**To Reproduce**
14-
<!-- Steps to reproduce the bug, or a link to a project where the bug is visible -->
14+
<!-- Steps to reproduce the bug, or a link to a project where the bug is visible
15+
Include a Minimal reproducible example: https://stackoverflow.com/help/minimal-reproducible-example -->
1516

1617
**Additional context**
1718
<!--

.github/ISSUE_TEMPLATE/config.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
blank_issues_enabled: true
2+
contact_links:
3+
- name: Questions, ideas, showcases and more
4+
url: https://github.com/projectmesa/mesa/discussions
5+
about: Discuss Mesa, ask questions, share ideas, and showcase your projects

benchmarks/BoltzmannWealth/boltzmann_wealth.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ def __init__(self, seed=None, n=100, width=10, height=10):
2727
model_reporters={"Gini": compute_gini}, agent_reporters={"Wealth": "wealth"}
2828
)
2929
# Create agents
30-
for i in range(self.num_agents):
31-
a = MoneyAgent(i, self)
30+
for _ in range(self.num_agents):
31+
a = MoneyAgent(self)
3232
# Add the agent to a random grid cell
3333
x = self.random.randrange(self.grid.width)
3434
y = self.random.randrange(self.grid.height)
@@ -50,8 +50,8 @@ def run_model(self, n):
5050
class MoneyAgent(mesa.Agent):
5151
"""An agent with fixed initial wealth."""
5252

53-
def __init__(self, unique_id, model):
54-
super().__init__(unique_id, model)
53+
def __init__(self, model):
54+
super().__init__(model)
5555
self.wealth = 1
5656

5757
def move(self):

benchmarks/Flocking/flocking.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ class Boid(mesa.Agent):
2727

2828
def __init__(
2929
self,
30-
unique_id,
3130
model,
3231
speed,
3332
direction,
@@ -41,7 +40,6 @@ def __init__(
4140
Create a new Boid flocker agent.
4241
4342
Args:
44-
unique_id: Unique agent identifier.
4543
speed: Distance to move per step.
4644
direction: numpy vector for the Boid's direction of movement.
4745
vision: Radius to look around for nearby Boids.
@@ -51,7 +49,7 @@ def __init__(
5149
match: the relative importance of matching neighbors' directions
5250
5351
"""
54-
super().__init__(unique_id, model)
52+
super().__init__(model)
5553
self.speed = speed
5654
self.direction = direction
5755
self.vision = vision
@@ -131,13 +129,12 @@ def __init__(
131129
"match": match,
132130
}
133131

134-
for i in range(self.population):
132+
for _ in range(self.population):
135133
x = self.random.random() * self.space.x_max
136134
y = self.random.random() * self.space.y_max
137135
pos = np.array((x, y))
138136
direction = np.random.random(2) * 2 - 1
139137
boid = Boid(
140-
unique_id=i,
141138
model=self,
142139
speed=speed,
143140
direction=direction,

benchmarks/Schelling/schelling.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,14 @@ class SchellingAgent(CellAgent):
88
Schelling segregation agent
99
"""
1010

11-
def __init__(self, unique_id, model, agent_type, radius, homophily):
11+
def __init__(self, model, agent_type, radius, homophily):
1212
"""
1313
Create a new Schelling agent.
1414
Args:
15-
unique_id: Unique identifier for the agent.
1615
x, y: Agent initial location.
1716
agent_type: Indicator for the agent's type (minority=1, majority=0)
1817
"""
19-
super().__init__(unique_id, model)
18+
super().__init__(model)
2019
self.type = agent_type
2120
self.radius = radius
2221
self.homophily = homophily
@@ -81,9 +80,7 @@ def __init__(
8180
for cell in self.grid:
8281
if self.random.random() < density:
8382
agent_type = 1 if self.random.random() < self.minority_pc else 0
84-
agent = SchellingAgent(
85-
self.next_id(), self, agent_type, radius, homophily
86-
)
83+
agent = SchellingAgent(self, agent_type, radius, homophily)
8784
agent.move_to(cell)
8885
self.schedule.add(agent)
8986

benchmarks/WolfSheep/wolf_sheep.py

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717

1818

1919
class Animal(CellAgent):
20-
def __init__(self, unique_id, model, energy, p_reproduce, energy_from_food):
21-
super().__init__(unique_id, model)
20+
def __init__(self, model, energy, p_reproduce, energy_from_food):
21+
super().__init__(model)
2222
self.energy = energy
2323
self.p_reproduce = p_reproduce
2424
self.energy_from_food = energy_from_food
@@ -29,7 +29,6 @@ def random_move(self):
2929
def spawn_offspring(self):
3030
self.energy /= 2
3131
offspring = self.__class__(
32-
self.model.next_id(),
3332
self.model,
3433
self.energy,
3534
self.p_reproduce,
@@ -107,7 +106,7 @@ def fully_grown(self, value: bool) -> None:
107106
function_args=[self, "fully_grown", True],
108107
)
109108

110-
def __init__(self, unique_id, model, fully_grown, countdown, grass_regrowth_time):
109+
def __init__(self, model, fully_grown, countdown, grass_regrowth_time):
111110
"""
112111
TODO:: fully grown can just be an int --> so one less param (i.e. countdown)
113112
@@ -119,7 +118,7 @@ def __init__(self, unique_id, model, fully_grown, countdown, grass_regrowth_time
119118
grass_regrowth_time : time to fully regrow grass
120119
countdown : Time for the patch of grass to be fully regrown if fully grown is False
121120
"""
122-
super().__init__(unique_id, model)
121+
super().__init__(model)
123122
self._fully_grown = fully_grown
124123
self.grass_regrowth_time = grass_regrowth_time
125124

@@ -189,7 +188,6 @@ def __init__(
189188
)
190189
energy = self.random.randrange(2 * sheep_gain_from_food)
191190
sheep = Sheep(
192-
self.next_id(),
193191
self,
194192
energy,
195193
sheep_reproduce,
@@ -205,7 +203,6 @@ def __init__(
205203
)
206204
energy = self.random.randrange(2 * wolf_gain_from_food)
207205
wolf = Wolf(
208-
self.next_id(),
209206
self,
210207
energy,
211208
wolf_reproduce,
@@ -221,9 +218,7 @@ def __init__(
221218
countdown = grass_regrowth_time
222219
else:
223220
countdown = self.random.randrange(grass_regrowth_time)
224-
patch = GrassPatch(
225-
self.next_id(), self, fully_grown, countdown, grass_regrowth_time
226-
)
221+
patch = GrassPatch(self, fully_grown, countdown, grass_regrowth_time)
227222
patch.move_to(cell)
228223

229224
def step(self):

docs/conf.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@
113113

114114
nb_execution_timeout = 60
115115
nb_execution_mode = "cache"
116+
nb_execution_allow_errors = False
117+
nb_execution_raise_on_error = True
116118

117119
# -- Options for HTML output ----------------------------------------------
118120

docs/tutorials/MoneyModel.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ def compute_gini(model):
1515
class MoneyAgent(mesa.Agent):
1616
"""An agent with fixed initial wealth."""
1717

18-
def __init__(self, unique_id, model):
19-
super().__init__(unique_id, model)
18+
def __init__(self, model):
19+
super().__init__(model)
2020
self.wealth = 1
2121

2222
def move(self):

mesa/agent.py

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
import contextlib
1212
import copy
13+
import functools
14+
import itertools
1315
import operator
1416
import warnings
1517
import weakref
@@ -32,21 +34,49 @@ class Agent:
3234
Base class for a model agent in Mesa.
3335
3436
Attributes:
35-
unique_id (int): A unique identifier for this agent.
3637
model (Model): A reference to the model instance.
37-
self.pos: Position | None = None
38+
unique_id (int): A unique identifier for this agent.
39+
pos (Position): A reference to the position where this agent is located.
40+
41+
Notes:
42+
unique_id is unique relative to a model instance and starts from 1
43+
3844
"""
3945

40-
def __init__(self, unique_id: int, model: Model) -> None:
46+
# this is a class level attribute
47+
# it is a dictionary, indexed by model instance
48+
# so, unique_id is unique relative to a model, and counting starts from 1
49+
_ids = defaultdict(functools.partial(itertools.count, 1))
50+
51+
def __init__(self, *args, **kwargs) -> None:
4152
"""
4253
Create a new agent.
4354
4455
Args:
45-
unique_id (int): A unique identifier for this agent.
4656
model (Model): The model instance in which the agent exists.
4757
"""
48-
self.unique_id = unique_id
49-
self.model = model
58+
# TODO: Cleanup in future Mesa version (3.1+)
59+
match args:
60+
# Case 1: Only the model is provided. The new correct behavior.
61+
case [model]:
62+
self.model = model
63+
self.unique_id = next(self._ids[model])
64+
# Case 2: Both unique_id and model are provided, deprecated
65+
case [_, model]:
66+
warnings.warn(
67+
"unique ids are assigned automatically to Agents in Mesa 3. The use of custom unique_id is "
68+
"deprecated. Only input a model when calling `super()__init__(model)`. The unique_id inputted is not used.",
69+
DeprecationWarning,
70+
stacklevel=2,
71+
)
72+
self.model = model
73+
self.unique_id = next(self._ids[model])
74+
# Case 3: Anything else, raise an error
75+
case _:
76+
raise ValueError(
77+
"Invalid arguments provided to initialize the Agent. Only input a model: `super()__init__(model)`."
78+
)
79+
5080
self.pos: Position | None = None
5181

5282
self.model.register_agent(self)

0 commit comments

Comments
 (0)