Skip to content

Commit

Permalink
Merge branch 'master' into black
Browse files Browse the repository at this point in the history
  • Loading branch information
dmasad authored Apr 5, 2020
2 parents 1604c1e + 0932032 commit 7abb0ec
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 53 deletions.
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ You can also use `pip` to install the github version:

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

Expand Down
14 changes: 6 additions & 8 deletions docs/tutorials/adv_tutorial.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -257,9 +257,9 @@
" // Create the tag:\n",
" var canvas_tag = \"<canvas width='\" + canvas_width + \"' height='\" + canvas_height + \"' \";\n",
" canvas_tag += \"style='border:1px dotted'></canvas>\";\n",
" // Append it to body:\n",
" // Append it to #elements:\n",
" var canvas = $(canvas_tag)[0];\n",
" $(\"body\").append(canvas);\n",
" $(\"#elements\").append(canvas);\n",
" // Create the context and the drawing controller:\n",
" var context = canvas.getContext(\"2d\");\n",
"};\n",
Expand All @@ -269,14 +269,12 @@
"\n",
"```javascript\n",
"var HistogramModule = function(bins, canvas_width, canvas_height) {\n",
" // Create the elements\n",
"\n",
" // Create the tag:\n",
" var canvas_tag = \"<canvas width='\" + canvas_width + \"' height='\" + canvas_height + \"' \";\n",
" canvas_tag += \"style='border:1px dotted'></canvas>\";\n",
" // Append it to body:\n",
" // Append it to #elements:\n",
" var canvas = $(canvas_tag)[0];\n",
" $(\"body\").append(canvas);\n",
" $(\"#elements\").append(canvas);\n",
" // Create the context and the drawing controller:\n",
" var context = canvas.getContext(\"2d\");\n",
"\n",
Expand Down Expand Up @@ -430,9 +428,9 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.5.1"
"version": "3.7.4"
}
},
"nbformat": 4,
"nbformat_minor": 0
"nbformat_minor": 1
}
10 changes: 4 additions & 6 deletions docs/tutorials/adv_tutorial.rst
Original file line number Diff line number Diff line change
Expand Up @@ -310,9 +310,9 @@ context, which is required for doing anything with it.
// Create the tag:
var canvas_tag = "<canvas width='" + canvas_width + "' height='" + canvas_height + "' ";
canvas_tag += "style='border:1px dotted'></canvas>";
// Append it to body:
// Append it to #elements:
var canvas = $(canvas_tag)[0];
$("body").append(canvas);
$("#elements").append(canvas);
// Create the context and the drawing controller:
var context = canvas.getContext("2d");
};
Expand All @@ -330,14 +330,12 @@ created, we can create the chart object.
.. code:: javascript
var HistogramModule = function(bins, canvas_width, canvas_height) {
// Create the elements
// Create the tag:
var canvas_tag = "<canvas width='" + canvas_width + "' height='" + canvas_height + "' ";
canvas_tag += "style='border:1px dotted'></canvas>";
// Append it to body:
// Append it to #elements:
var canvas = $(canvas_tag)[0];
$("body").append(canvas);
$("#elements").append(canvas);
// Create the context and the drawing controller:
var context = canvas.getContext("2d");
Expand Down
79 changes: 41 additions & 38 deletions mesa/space.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@

import numpy as np

from typing import Iterable, Iterator, List, Optional, Set, Tuple, Union
from typing import Any, Dict, Iterable, Iterator, List, Optional, Set, Tuple, Union
from .agent import Agent

Coordinate = Tuple[int, int]
GridContent = Union[Optional[Agent], Set[Agent]]
# used in ContinuousSpace
FloatCoordinate = Union[Tuple[float, float], np.ndarray]


def accept_tuple_argument(wrapped_function):
Expand All @@ -32,7 +34,7 @@ def accept_tuple_argument(wrapped_function):
"""

def wrapper(*args):
def wrapper(*args: Any):
if isinstance(args[1], tuple) and len(args[1]) == 2:
return wrapped_function(args[0], [args[1]])
else:
Expand Down Expand Up @@ -412,7 +414,7 @@ def __init__(self, width: int, height: int, torus: bool) -> None:
"""
super().__init__(width, height, torus)

def position_agent(self, agent, x="random", y="random"):
def position_agent(self, agent: Agent, x: Union[int, str] = "random", y: Union[int, str] = "random") -> None:
""" Position an agent on the grid.
This is used when first placing agents! Use 'move_to_empty()'
when you want agents to jump to an empty cell.
Expand Down Expand Up @@ -459,7 +461,7 @@ class MultiGrid(Grid):
"""

@staticmethod
def default_val():
def default_val() -> Set[Agent]:
""" Default value for new cell elements. """
return set()

Expand All @@ -477,7 +479,7 @@ def _remove_agent(self, pos: Coordinate, agent: Agent) -> None:
self.empties.add(pos)

@accept_tuple_argument
def iter_cell_list_contents(self, cell_list):
def iter_cell_list_contents(self, cell_list: Iterable[Coordinate]) -> Iterator[GridContent]:
"""
Args:
cell_list: Array-like of (x, y) tuples, or single tuple.
Expand Down Expand Up @@ -510,7 +512,9 @@ class HexGrid(Grid):
"""

def iter_neighborhood(self, pos, include_center=False, radius=1):

def iter_neighborhood(self, pos: Coordinate,
include_center: bool = False, radius: int = 1) -> Iterator[Coordinate]:
""" Return an iterator over cell coordinates that are in the
neighborhood of a certain point.
Expand All @@ -528,12 +532,12 @@ def iter_neighborhood(self, pos, include_center=False, radius=1):
"""

def torus_adj_2d(pos):
def torus_adj_2d(pos: Coordinate) -> Coordinate:
return (pos[0] % self.width, pos[1] % self.height)

coordinates = set()

def find_neighbors(pos, radius):
def find_neighbors(pos: Coordinate, radius: int) -> None:
x, y = pos

"""
Expand Down Expand Up @@ -572,7 +576,7 @@ def find_neighbors(pos, radius):
for i in coordinates:
yield i

def neighbor_iter(self, pos):
def neighbor_iter(self, pos: Coordinate) -> Iterator[GridContent]:
""" Iterate over position neighbors.
Args:
Expand All @@ -582,7 +586,8 @@ def neighbor_iter(self, pos):
neighborhood = self.iter_neighborhood(pos)
return self.iter_cell_list_contents(neighborhood)

def get_neighborhood(self, pos, include_center=False, radius=1):
def get_neighborhood(self, pos: Coordinate,
include_center: bool = False, radius: int = 1) -> List[Coordinate]:
""" Return a list of cells that are in the neighborhood of a
certain point.
Expand All @@ -599,7 +604,8 @@ def get_neighborhood(self, pos, include_center=False, radius=1):
"""
return list(self.iter_neighborhood(pos, include_center, radius))

def iter_neighbors(self, pos, include_center=False, radius=1):
def iter_neighbors(self, pos: Coordinate,
include_center: bool = False, radius: int = 1) -> Iterator[GridContent]:
""" Return an iterator over neighbors to a certain point.
Args:
Expand All @@ -616,7 +622,8 @@ def iter_neighbors(self, pos, include_center=False, radius=1):
neighborhood = self.iter_neighborhood(pos, include_center, radius)
return self.iter_cell_list_contents(neighborhood)

def get_neighbors(self, pos, include_center=False, radius=1):
def get_neighbors(self, pos: Coordinate,
include_center: bool = False, radius: int = 1) -> List[Coordinate]:
""" Return a list of neighbors to a certain point.
Args:
Expand Down Expand Up @@ -644,7 +651,7 @@ class ContinuousSpace:

_grid = None

def __init__(self, x_max, y_max, torus, x_min=0, y_min=0):
def __init__(self, x_max: float, y_max: float, torus: bool, x_min: float = 0, y_min: float = 0) -> None:
""" Create a new continuous space.
Args:
Expand All @@ -666,10 +673,10 @@ def __init__(self, x_max, y_max, torus, x_min=0, y_min=0):
self.torus = torus

self._agent_points = None
self._index_to_agent = {}
self._agent_to_index = {}
self._index_to_agent = {} # type: Dict[int, Agent]
self._agent_to_index = {} # type: Dict[Agent, int]

def place_agent(self, agent, pos):
def place_agent(self, agent: Agent, pos: FloatCoordinate) -> None:
""" Place a new agent in the space.
Args:
Expand All @@ -686,7 +693,7 @@ def place_agent(self, agent, pos):
self._agent_to_index[agent] = self._agent_points.shape[0] - 1
agent.pos = pos

def move_agent(self, agent, pos):
def move_agent(self, agent: Agent, pos: FloatCoordinate) -> None:
""" Move an agent from its current position to a new position.
Args:
Expand All @@ -700,7 +707,7 @@ def move_agent(self, agent, pos):
self._agent_points[idx, 1] = pos[1]
agent.pos = pos

def remove_agent(self, agent):
def remove_agent(self, agent: Agent) -> None:
""" Remove an agent from the simulation.
Args:
Expand All @@ -721,7 +728,7 @@ def remove_agent(self, agent):
del self._index_to_agent[max_idx]
agent.pos = None

def get_neighbors(self, pos, radius, include_center=True):
def get_neighbors(self, pos: FloatCoordinate, radius: float, include_center: bool = True) -> List[GridContent]:
""" Get all objects within a certain radius.
Args:
Expand All @@ -744,7 +751,7 @@ def get_neighbors(self, pos, radius, include_center=True):
]
return neighbors

def get_heading(self, pos_1, pos_2):
def get_heading(self, pos_1: FloatCoordinate, pos_2: FloatCoordinate) -> FloatCoordinate:
""" Get the heading angle between two points, accounting for toroidal space.
Args:
Expand All @@ -760,7 +767,7 @@ def get_heading(self, pos_1, pos_2):
heading = tuple(heading)
return heading

def get_distance(self, pos_1, pos_2):
def get_distance(self, pos_1: FloatCoordinate, pos_2: FloatCoordinate) -> float:
""" Get the distance between two point, accounting for toroidal space.
Args:
Expand All @@ -777,7 +784,7 @@ def get_distance(self, pos_1, pos_2):
dy = min(dy, self.height - dy)
return np.sqrt(dx * dx + dy * dy)

def torus_adj(self, pos):
def torus_adj(self, pos: FloatCoordinate) -> FloatCoordinate:
""" Adjust coordinates to handle torus looping.
If the coordinate is out-of-bounds and the space is toroidal, return
Expand All @@ -800,7 +807,7 @@ def torus_adj(self, pos):
else:
return np.array((x, y))

def out_of_bounds(self, pos):
def out_of_bounds(self, pos: FloatCoordinate) -> bool:
""" Check if a point is out of bounds. """
x, y = pos
return x < self.x_min or x >= self.x_max or y < self.y_min or y >= self.y_max
Expand All @@ -809,18 +816,18 @@ def out_of_bounds(self, pos):
class NetworkGrid:
""" Network Grid where each node contains zero or more agents. """

def __init__(self, G):
def __init__(self, G: Any) -> None:
self.G = G
for node_id in self.G.nodes:
G.nodes[node_id]["agent"] = list()

def place_agent(self, agent, node_id):
def place_agent(self, agent: Agent, node_id: int) -> None:
""" Place a agent in a node. """

self._place_agent(agent, node_id)
agent.pos = node_id

def get_neighbors(self, node_id, include_center=False):
def get_neighbors(self, node_id: int, include_center: bool = False) -> List[int]:
""" Get all adjacent nodes """

neighbors = list(self.G.neighbors(node_id))
Expand All @@ -829,37 +836,33 @@ def get_neighbors(self, node_id, include_center=False):

return neighbors

def move_agent(self, agent, node_id):
def move_agent(self, agent: Agent, node_id: int) -> None:
""" Move an agent from its current node to a new node. """

self._remove_agent(agent, agent.pos)
self._place_agent(agent, node_id)
agent.pos = node_id

def _place_agent(self, agent, node_id):
def _place_agent(self, agent: Agent, node_id: int) -> None:
""" Place the agent at the correct node. """

self.G.nodes[node_id]["agent"].append(agent)

def _remove_agent(self, agent, node_id):
def _remove_agent(self, agent: Agent, node_id: int) -> None:
""" Remove an agent from a node. """

self.G.nodes[node_id]["agent"].remove(agent)

def is_cell_empty(self, node_id):
def is_cell_empty(self, node_id: int) -> bool:
""" Returns a bool of the contents of a cell. """
return not self.G.nodes[node_id]["agent"]

def get_cell_list_contents(self, cell_list):
def get_cell_list_contents(self, cell_list: List[int]) -> List[GridContent]:
return list(self.iter_cell_list_contents(cell_list))

def get_all_cell_contents(self):
def get_all_cell_contents(self) -> List[GridContent]:
return list(self.iter_cell_list_contents(self.G))

def iter_cell_list_contents(self, cell_list):
list_of_lists = [
self.G.nodes[node_id]["agent"]
for node_id in cell_list
if not self.is_cell_empty(node_id)
]
def iter_cell_list_contents(self, cell_list: List[int]) -> List[GridContent]:
list_of_lists = [self.G.nodes[node_id]['agent'] for node_id in cell_list if not self.is_cell_empty(node_id)]
return [item for sublist in list_of_lists for item in sublist]

0 comments on commit 7abb0ec

Please sign in to comment.