Skip to content

Commit 023e8ce

Browse files
authoredApr 7, 2020
Merge branch 'master' into ADD-pre-commit
2 parents 69afa97 + bb56278 commit 023e8ce

File tree

11 files changed

+209
-128
lines changed

11 files changed

+209
-128
lines changed
 

‎README.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ You can also use `pip` to install the github version:
4848

4949
.. code-block:: bash
5050
51-
$ pip install -e git+https://github.com/projectmesa/mesa
51+
$ pip install -e git+https://github.com/projectmesa/mesa#egg=mesa
5252
5353
Take a look at the `examples <https://github.com/projectmesa/mesa/tree/master/examples>`_ folder for sample models demonstrating Mesa features.
5454

‎docs/tutorials/adv_tutorial.ipynb

+9-12
Original file line numberDiff line numberDiff line change
@@ -257,9 +257,9 @@
257257
" // Create the tag:\n",
258258
" var canvas_tag = \"<canvas width='\" + canvas_width + \"' height='\" + canvas_height + \"' \";\n",
259259
" canvas_tag += \"style='border:1px dotted'></canvas>\";\n",
260-
" // Append it to body:\n",
260+
" // Append it to #elements:\n",
261261
" var canvas = $(canvas_tag)[0];\n",
262-
" $(\"body\").append(canvas);\n",
262+
" $(\"#elements\").append(canvas);\n",
263263
" // Create the context and the drawing controller:\n",
264264
" var context = canvas.getContext(\"2d\");\n",
265265
"};\n",
@@ -269,14 +269,12 @@
269269
"\n",
270270
"```javascript\n",
271271
"var HistogramModule = function(bins, canvas_width, canvas_height) {\n",
272-
" // Create the elements\n",
273-
"\n",
274272
" // Create the tag:\n",
275273
" var canvas_tag = \"<canvas width='\" + canvas_width + \"' height='\" + canvas_height + \"' \";\n",
276274
" canvas_tag += \"style='border:1px dotted'></canvas>\";\n",
277-
" // Append it to body:\n",
275+
" // Append it to #elements:\n",
278276
" var canvas = $(canvas_tag)[0];\n",
279-
" $(\"body\").append(canvas);\n",
277+
" $(\"#elements\").append(canvas);\n",
280278
" // Create the context and the drawing controller:\n",
281279
" var context = canvas.getContext(\"2d\");\n",
282280
"\n",
@@ -304,7 +302,7 @@
304302
" };\n",
305303
"\n",
306304
" // Create the chart object\n",
307-
" var chart = new Chart(context).Bar(data, options);\n",
305+
" var chart = new Chart(context, {type: 'bar', data: data, options: options});\n",
308306
"\n",
309307
" // Now what?\n",
310308
"};\n",
@@ -322,14 +320,13 @@
322320
"var HistogramModule = function(bins, canvas_width, canvas_height) {\n",
323321
" // ...Everything from above...\n",
324322
" this.render = function(data) {\n",
325-
" for (var i in data)\n",
326-
" chart.datasets[0].bars[i].value = data[i];\n",
323+
" datasets[0].data = data;\n",
327324
" chart.update();\n",
328325
" };\n",
329326
"\n",
330327
" this.reset = function() {\n",
331328
" chart.destroy();\n",
332-
" chart = new Chart(context).Bar(data, options);\n",
329+
" chart = new Chart(context, {type: 'bar', data: data, options: options});\n",
333330
" };\n",
334331
"};\n",
335332
"```\n",
@@ -431,9 +428,9 @@
431428
"name": "python",
432429
"nbconvert_exporter": "python",
433430
"pygments_lexer": "ipython3",
434-
"version": "3.5.1"
431+
"version": "3.7.4"
435432
}
436433
},
437434
"nbformat": 4,
438-
"nbformat_minor": 0
435+
"nbformat_minor": 1
439436
}

‎docs/tutorials/adv_tutorial.rst

+7-10
Original file line numberDiff line numberDiff line change
@@ -310,9 +310,9 @@ context, which is required for doing anything with it.
310310
// Create the tag:
311311
var canvas_tag = "<canvas width='" + canvas_width + "' height='" + canvas_height + "' ";
312312
canvas_tag += "style='border:1px dotted'></canvas>";
313-
// Append it to body:
313+
// Append it to #elements:
314314
var canvas = $(canvas_tag)[0];
315-
$("body").append(canvas);
315+
$("#elements").append(canvas);
316316
// Create the context and the drawing controller:
317317
var context = canvas.getContext("2d");
318318
};
@@ -330,14 +330,12 @@ created, we can create the chart object.
330330
.. code:: javascript
331331
332332
var HistogramModule = function(bins, canvas_width, canvas_height) {
333-
// Create the elements
334-
335333
// Create the tag:
336334
var canvas_tag = "<canvas width='" + canvas_width + "' height='" + canvas_height + "' ";
337335
canvas_tag += "style='border:1px dotted'></canvas>";
338-
// Append it to body:
336+
// Append it to #elements:
339337
var canvas = $(canvas_tag)[0];
340-
$("body").append(canvas);
338+
$("#elements").append(canvas);
341339
// Create the context and the drawing controller:
342340
var context = canvas.getContext("2d");
343341
@@ -365,7 +363,7 @@ created, we can create the chart object.
365363
};
366364
367365
// Create the chart object
368-
var chart = new Chart(context).Bar(data, options);
366+
var chart = new Chart(context, {type: 'bar', data: data, options: options});
369367
370368
// Now what?
371369
};
@@ -389,14 +387,13 @@ With that in mind, we can add these two methods to the class:
389387
var HistogramModule = function(bins, canvas_width, canvas_height) {
390388
// ...Everything from above...
391389
this.render = function(data) {
392-
for (var i in data)
393-
chart.datasets[0].bars[i].value = data[i];
390+
datasets[0].data = data;
394391
chart.update();
395392
};
396393
397394
this.reset = function() {
398395
chart.destroy();
399-
chart = new Chart(context).Bar(data, options);
396+
chart = new Chart(context, {type: 'bar', data: data, options: options});
400397
};
401398
};
402399

‎examples/hex_snowflake/Readme.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Conway's Game Of "Life"
1+
# Conway's Game Of "Life" on a hexagonal grid
22

33
## Summary
44

‎mesa/agent.py

+10-3
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,27 @@
55
Core Objects: Agent
66
77
"""
8+
# mypy
9+
from .model import Model
10+
from random import Random
811

912

1013
class Agent:
1114
""" Base class for a model agent. """
1215

13-
def __init__(self, unique_id, model):
16+
def __init__(self, unique_id: int, model: Model) -> None:
1417
""" Create a new agent. """
1518
self.unique_id = unique_id
1619
self.model = model
20+
self.pos = None
1721

18-
def step(self):
22+
def step(self) -> None:
1923
""" A single step of the agent. """
2024
pass
2125

26+
def advance(self) -> None:
27+
pass
28+
2229
@property
23-
def random(self):
30+
def random(self) -> Random:
2431
return self.model.random

‎mesa/datacollection.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ def get_agent_vars_dataframe(self):
216216
rep_names = [rep_name for rep_name in self.agent_reporters]
217217

218218
df = pd.DataFrame.from_records(
219-
data=all_records, columns=["Step", "AgentID"] + rep_names
219+
data=all_records, columns=["Step", "AgentID"] + rep_names,
220220
)
221221
df = df.set_index(["Step", "AgentID"])
222222
return df

‎mesa/model.py

+12-14
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,22 @@
55
Core Objects: Model
66
77
"""
8-
import time
98
import random
109

10+
# mypy
11+
from typing import Any, Optional
12+
1113

1214
class Model:
1315
""" Base class for models. """
1416

15-
def __new__(cls, *args, **kwargs):
17+
def __new__(cls, *args: Any, **kwargs: Any) -> Any:
1618
"""Create a new model object and instantiate its RNG automatically."""
19+
cls._seed = kwargs.get("seed", None)
20+
cls.random = random.Random(cls._seed)
21+
return object.__new__(cls)
1722

18-
model = object.__new__(cls) # This only works in Python 3.3 and above
19-
model._seed = time.time()
20-
if "seed" in kwargs and kwargs["seed"] is not None:
21-
model._seed = kwargs["seed"]
22-
model.random = random.Random(model._seed)
23-
return model
24-
25-
def __init__(self, *args, **kwargs):
23+
def __init__(self, *args: Any, **kwargs: Any) -> None:
2624
""" Create a new model. Overload this method with the actual code to
2725
start the model.
2826
@@ -36,24 +34,24 @@ def __init__(self, *args, **kwargs):
3634
self.schedule = None
3735
self.current_id = 0
3836

39-
def run_model(self):
37+
def run_model(self) -> None:
4038
""" Run the model until the end condition is reached. Overload as
4139
needed.
4240
4341
"""
4442
while self.running:
4543
self.step()
4644

47-
def step(self):
45+
def step(self) -> None:
4846
""" A single step. Fill in here. """
4947
pass
5048

51-
def next_id(self):
49+
def next_id(self) -> int:
5250
""" Return the next unique ID for agents, increment current_id"""
5351
self.current_id += 1
5452
return self.current_id
5553

56-
def reset_randomizer(self, seed=None):
54+
def reset_randomizer(self, seed: Optional[int] = None) -> None:
5755
"""Reset the model random number generator.
5856
5957
Args:

‎mesa/space.py

+129-66
Large diffs are not rendered by default.

‎mesa/time.py

+28-14
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,16 @@
2424

2525
from collections import OrderedDict
2626

27+
# mypy
28+
from typing import Dict, Iterator, List, Optional, Union
29+
from .agent import Agent
30+
from .model import Model
31+
32+
33+
# BaseScheduler has a self.time of int, while
34+
# StagedActivation has a self.time of float
35+
TimeT = Union[float, int]
36+
2737

2838
class BaseScheduler:
2939
""" Simplest scheduler; activates agents one at a time, in the order
@@ -35,14 +45,14 @@ class BaseScheduler:
3545
3646
"""
3747

38-
def __init__(self, model):
48+
def __init__(self, model: Model) -> None:
3949
""" Create a new, empty BaseScheduler. """
4050
self.model = model
4151
self.steps = 0
42-
self.time = 0
43-
self._agents = OrderedDict()
52+
self.time = 0 # type: TimeT
53+
self._agents = OrderedDict() # type: Dict[int, Agent]
4454

45-
def add(self, agent):
55+
def add(self, agent: Agent) -> None:
4656
""" Add an Agent object to the schedule.
4757
4858
Args:
@@ -52,7 +62,7 @@ def add(self, agent):
5262
"""
5363
self._agents[agent.unique_id] = agent
5464

55-
def remove(self, agent):
65+
def remove(self, agent: Agent) -> None:
5666
""" Remove all instances of a given agent from the schedule.
5767
5868
Args:
@@ -61,22 +71,22 @@ def remove(self, agent):
6171
"""
6272
del self._agents[agent.unique_id]
6373

64-
def step(self):
74+
def step(self) -> None:
6575
""" Execute the step of all the agents, one at a time. """
6676
for agent in self.agent_buffer(shuffled=False):
6777
agent.step()
6878
self.steps += 1
6979
self.time += 1
7080

71-
def get_agent_count(self):
81+
def get_agent_count(self) -> int:
7282
""" Returns the current number of agents in the queue. """
7383
return len(self._agents.keys())
7484

7585
@property
76-
def agents(self):
86+
def agents(self) -> List[Agent]:
7787
return list(self._agents.values())
7888

79-
def agent_buffer(self, shuffled=False):
89+
def agent_buffer(self, shuffled: bool = False) -> Iterator[Agent]:
8090
""" Simple generator that yields the agents while letting the user
8191
remove and/or add agents during stepping.
8292
@@ -101,7 +111,7 @@ class RandomActivation(BaseScheduler):
101111
102112
"""
103113

104-
def step(self):
114+
def step(self) -> None:
105115
""" Executes the step of all agents, one at a time, in
106116
random order.
107117
@@ -121,7 +131,7 @@ class SimultaneousActivation(BaseScheduler):
121131
122132
"""
123133

124-
def step(self):
134+
def step(self) -> None:
125135
""" Step all agents, then advance them. """
126136
agent_keys = list(self._agents.keys())
127137
for agent_key in agent_keys:
@@ -146,8 +156,12 @@ class StagedActivation(BaseScheduler):
146156
"""
147157

148158
def __init__(
149-
self, model, stage_list=None, shuffle=False, shuffle_between_stages=False
150-
):
159+
self,
160+
model: Model,
161+
stage_list: Optional[List[str]] = None,
162+
shuffle: bool = False,
163+
shuffle_between_stages: bool = False,
164+
) -> None:
151165
""" Create an empty Staged Activation schedule.
152166
153167
Args:
@@ -166,7 +180,7 @@ def __init__(
166180
self.shuffle_between_stages = shuffle_between_stages
167181
self.stage_time = 1 / len(self.stage_list)
168182

169-
def step(self):
183+
def step(self) -> None:
170184
""" Executes all the stages for all agents. """
171185
agent_keys = list(self._agents.keys())
172186
if self.shuffle:

‎mesa/visualization/ModularVisualization.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -321,13 +321,14 @@ def render_model(self):
321321
visualization_state.append(element_state)
322322
return visualization_state
323323

324-
def launch(self, port=None):
324+
def launch(self, port=None, open_browser=True):
325325
""" Run the app. """
326326
if port is not None:
327327
self.port = port
328328
url = "http://127.0.0.1:{PORT}".format(PORT=self.port)
329329
print("Interface starting at {url}".format(url=url))
330330
self.listen(self.port)
331-
webbrowser.open(url)
331+
if open_browser:
332+
webbrowser.open(url)
332333
tornado.autoreload.start()
333334
tornado.ioloop.IOLoop.current().start()

‎mesa/visualization/modules/CanvasGridVisualization.py

+8-4
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,21 @@ class CanvasGrid(VisualizationElement):
2222
2323
A portrayal as a dictionary with the following structure:
2424
"x", "y": Coordinates for the cell in which the object is placed.
25-
"Shape": Can be either "circle", "rect" or "arrowHead"
25+
"Shape": Can be either "circle", "rect", "arrowHead" or a custom image.
2626
For Circles:
2727
"r": The radius, defined as a fraction of cell size. r=1 will
2828
fill the entire cell.
2929
For Rectangles:
3030
"w", "h": The width and height of the rectangle, which are in
3131
fractions of cell width and height.
3232
For arrowHead:
33-
"scale": Proportion scaling as a fraction of cell size.
34-
"heading_x": represents x direction unit vector.
35-
"heading_y": represents y direction unit vector.
33+
"scale": Proportion scaling as a fraction of cell size.
34+
"heading_x": represents x direction unit vector.
35+
"heading_y": represents y direction unit vector.
36+
For an image:
37+
The image must be placed in the same directory from which the
38+
server is launched. An image has the attributes "x", "y",
39+
"scale", "text" and "text_color".
3640
"Color": The color to draw the shape in; needs to be a valid HTML
3741
color, e.g."Red" or "#AA08F8"
3842
"Filled": either "true" or "false", and determines whether the shape is

0 commit comments

Comments
 (0)
Please sign in to comment.