From ff07ffdaca8bcd5e0973978b81c331551506604b Mon Sep 17 00:00:00 2001 From: jackiekazil Date: Thu, 20 May 2021 23:56:35 -0500 Subject: [PATCH 1/5] v0.8.9 Oro Valley --- HISTORY.rst | 29 +++++++++++++++++++++++++++-- mesa/__init__.py | 2 +- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index c0039c3f395..aa1d1836fd7 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -3,12 +3,37 @@ Release History --------------- - -0.8.9 (TBD) Oro Valley +0.8.9 (2020-05-20) Oro Valley +++++++++++++++++++++++++++++++++++++++++++ *Note: Master branch was renamed to Main on 03/13/2021* +**Improvements** + +* Master to Main change: + * Docs/examples: Update links to use main instead of master as branch #1012 + * CI: Run on pushed to main and release branches #1011 +* Github Actions + * GitHub Actions: run black only on ubuntu 3.8 #996 + * GA: Only run CI when pushed to master #974 + * GA: Add pypy3 #972 + * rename github action to "build", remove redundant flake8 check #971 + * GA: Run on Windows and macOS #970 + * Add GitHub Action for continuous integration testing #966 +*[PERF] Add neighborhood cache to grids and improve iter_cell_list_contents #823 +* forest_fire: Remove unnecessary code #981 +* Migrate away from type comments #984 +* Update License #985 +* Public remove_agent function for NetworkGrid #1001 +* Date update to release #962 +* Advanced indexing of grid #820 + +**Fixes** + +* Correct spelling #999 +* Update Pipfile.lock #983 +* Fix order of variable_params in model and agent vars data frames #979 +* Fix asyncio on windows with python 3.6 #973 0.8.8 (2020-11-27) Nogales diff --git a/mesa/__init__.py b/mesa/__init__.py index 9769c2c127e..71fb67980a9 100644 --- a/mesa/__init__.py +++ b/mesa/__init__.py @@ -14,6 +14,6 @@ __all__ = ["Model", "Agent"] __title__ = "mesa" -__version__ = "0.8.8.1" +__version__ = "0.8.9" __license__ = "Apache 2.0" __copyright__ = "Copyright %s Project Mesa Team" % datetime.date.today().year From 73d752b456a11dbfb35fa3f73ef8c08375e11cfd Mon Sep 17 00:00:00 2001 From: Jackie Kazil Date: Fri, 21 May 2021 00:12:31 -0500 Subject: [PATCH 2/5] fixing release formatting --- HISTORY.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HISTORY.rst b/HISTORY.rst index aa1d1836fd7..4ee04ad1e58 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -20,7 +20,7 @@ Release History * rename github action to "build", remove redundant flake8 check #971 * GA: Run on Windows and macOS #970 * Add GitHub Action for continuous integration testing #966 -*[PERF] Add neighborhood cache to grids and improve iter_cell_list_contents #823 +* [PERF] Add neighborhood cache to grids and improve iter_cell_list_contents #823 * forest_fire: Remove unnecessary code #981 * Migrate away from type comments #984 * Update License #985 From c27dcc12fcb885a3b06db18af0ef18e35e31559f Mon Sep 17 00:00:00 2001 From: jackiekazil Date: Sat, 22 May 2021 23:25:11 -0500 Subject: [PATCH 3/5] Updating release date. --- HISTORY.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HISTORY.rst b/HISTORY.rst index 4ee04ad1e58..0b63ef454d6 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -3,7 +3,7 @@ Release History --------------- -0.8.9 (2020-05-20) Oro Valley +0.8.9 (2020-05-22) Oro Valley +++++++++++++++++++++++++++++++++++++++++++ *Note: Master branch was renamed to Main on 03/13/2021* From 17315ad5f2b7d9edc6b5f04c47e374b3254b285b Mon Sep 17 00:00:00 2001 From: jackiekazil Date: Sat, 22 May 2021 23:40:43 -0500 Subject: [PATCH 4/5] Black clean up on examples. --- examples/bank_reserves/bank_reserves/model.py | 2 +- .../boltzmann_wealth_model/boltzmann_wealth_model/model.py | 2 +- .../boltzmann_wealth_model_network/model.py | 2 +- examples/charts/charts/model.py | 2 +- examples/pd_grid/pd_grid/agent.py | 4 ++-- examples/pd_grid/pd_grid/model.py | 4 ++-- examples/schelling/model.py | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/examples/bank_reserves/bank_reserves/model.py b/examples/bank_reserves/bank_reserves/model.py index 92be1c419b1..ec24db49979 100644 --- a/examples/bank_reserves/bank_reserves/model.py +++ b/examples/bank_reserves/bank_reserves/model.py @@ -26,7 +26,7 @@ def get_num_rich_agents(model): - """ return number of rich agents""" + """return number of rich agents""" rich_agents = [a for a in model.schedule.agents if a.savings > model.rich_threshold] return len(rich_agents) diff --git a/examples/boltzmann_wealth_model/boltzmann_wealth_model/model.py b/examples/boltzmann_wealth_model/boltzmann_wealth_model/model.py index f8eeec1ef6b..d7ad78324ea 100644 --- a/examples/boltzmann_wealth_model/boltzmann_wealth_model/model.py +++ b/examples/boltzmann_wealth_model/boltzmann_wealth_model/model.py @@ -50,7 +50,7 @@ def run_model(self, n): class MoneyAgent(Agent): - """ An agent with fixed initial wealth.""" + """An agent with fixed initial wealth.""" def __init__(self, unique_id, model): super().__init__(unique_id, model) diff --git a/examples/boltzmann_wealth_model_network/boltzmann_wealth_model_network/model.py b/examples/boltzmann_wealth_model_network/boltzmann_wealth_model_network/model.py index 7737ad5034f..0d996ca4dbd 100644 --- a/examples/boltzmann_wealth_model_network/boltzmann_wealth_model_network/model.py +++ b/examples/boltzmann_wealth_model_network/boltzmann_wealth_model_network/model.py @@ -52,7 +52,7 @@ def run_model(self, n): class MoneyAgent(Agent): - """ An agent with fixed initial wealth.""" + """An agent with fixed initial wealth.""" def __init__(self, unique_id, model): super().__init__(unique_id, model) diff --git a/examples/charts/charts/model.py b/examples/charts/charts/model.py index e325af499a1..394e18205eb 100644 --- a/examples/charts/charts/model.py +++ b/examples/charts/charts/model.py @@ -26,7 +26,7 @@ def get_num_rich_agents(model): - """ return number of rich agents""" + """return number of rich agents""" rich_agents = [a for a in model.schedule.agents if a.savings > model.rich_threshold] return len(rich_agents) diff --git a/examples/pd_grid/pd_grid/agent.py b/examples/pd_grid/pd_grid/agent.py index c923d3fc4b1..a8985b2a78a 100644 --- a/examples/pd_grid/pd_grid/agent.py +++ b/examples/pd_grid/pd_grid/agent.py @@ -2,7 +2,7 @@ class PDAgent(Agent): - """ Agent member of the iterated, spatial prisoner's dilemma model. """ + """Agent member of the iterated, spatial prisoner's dilemma model.""" def __init__(self, pos, model, starting_move=None): """ @@ -28,7 +28,7 @@ def isCooroperating(self): return self.move == "C" def step(self): - """ Get the neighbors' moves, and change own move accordingly. """ + """Get the neighbors' moves, and change own move accordingly.""" neighbors = self.model.grid.get_neighbors(self.pos, True, include_center=True) best_neighbor = max(neighbors, key=lambda a: a.score) self.next_move = best_neighbor.move diff --git a/examples/pd_grid/pd_grid/model.py b/examples/pd_grid/pd_grid/model.py index 01f02b9772d..9bba389867e 100644 --- a/examples/pd_grid/pd_grid/model.py +++ b/examples/pd_grid/pd_grid/model.py @@ -7,7 +7,7 @@ class PdGrid(Model): - """ Model class for iterated, spatial prisoner's dilemma model. """ + """Model class for iterated, spatial prisoner's dilemma model.""" schedule_types = { "Sequential": BaseScheduler, @@ -60,6 +60,6 @@ def step(self): self.datacollector.collect(self) def run(self, n): - """ Run the model for n steps. """ + """Run the model for n steps.""" for _ in range(n): self.step() diff --git a/examples/schelling/model.py b/examples/schelling/model.py index bcb7f5c4ad1..a2ca410bb6f 100644 --- a/examples/schelling/model.py +++ b/examples/schelling/model.py @@ -41,7 +41,7 @@ class Schelling(Model): """ def __init__(self, height=20, width=20, density=0.8, minority_pc=0.2, homophily=3): - """""" + """ """ self.height = height self.width = width From 3aee0b7f9a142f312fec62c114265bc87cdf2fd4 Mon Sep 17 00:00:00 2001 From: jackiekazil Date: Sun, 23 May 2021 00:02:43 -0500 Subject: [PATCH 5/5] Black clean up on mesa and tests. --- mesa/agent.py | 6 +-- mesa/batchrunner.py | 8 ++-- mesa/datacollection.py | 6 +-- mesa/model.py | 6 +-- mesa/space.py | 48 +++++++++++----------- mesa/time.py | 10 ++--- mesa/visualization/ModularVisualization.py | 12 +++--- mesa/visualization/TextVisualization.py | 14 +++---- tests/test_visualization.py | 4 +- 9 files changed, 57 insertions(+), 57 deletions(-) diff --git a/mesa/agent.py b/mesa/agent.py index 51dabd566b4..0f43141ff1e 100644 --- a/mesa/agent.py +++ b/mesa/agent.py @@ -10,16 +10,16 @@ class Agent: - """ Base class for a model agent. """ + """Base class for a model agent.""" def __init__(self, unique_id: int, model: Model) -> None: - """ Create a new agent. """ + """Create a new agent.""" self.unique_id = unique_id self.model = model self.pos = None def step(self) -> None: - """ A single step of the agent. """ + """A single step of the agent.""" pass def advance(self) -> None: diff --git a/mesa/batchrunner.py b/mesa/batchrunner.py index 07811eb7f15..e38e1e30afb 100644 --- a/mesa/batchrunner.py +++ b/mesa/batchrunner.py @@ -150,7 +150,7 @@ def _make_model_args(self): return total_iterations, all_kwargs, all_param_values def run_all(self): - """ Run the model at all parameter combinations and store results. """ + """Run the model at all parameter combinations and store results.""" run_count = count() total_iterations, all_kwargs, all_param_values = self._make_model_args() @@ -210,7 +210,7 @@ def run_model(self, model): return None def collect_model_vars(self, model): - """ Run reporters and collect model-level variables. """ + """Run reporters and collect model-level variables.""" model_vars = OrderedDict() for var, reporter in self.model_reporters.items(): model_vars[var] = reporter(model) @@ -218,7 +218,7 @@ def collect_model_vars(self, model): return model_vars def collect_agent_vars(self, model): - """ Run reporters and collect agent-level variables. """ + """Run reporters and collect agent-level variables.""" agent_vars = OrderedDict() for agent in model.schedule._agents.values(): agent_record = OrderedDict() @@ -412,7 +412,7 @@ def __init__( class BatchRunnerMP(BatchRunner): - """ Child class of BatchRunner, extended with multiprocessing support. """ + """Child class of BatchRunner, extended with multiprocessing support.""" def __init__(self, model_cls, nr_processes=None, **kwargs): """Create a new BatchRunnerMP for a given model with the given diff --git a/mesa/datacollection.py b/mesa/datacollection.py index 727c16f4871..469c67f383f 100644 --- a/mesa/datacollection.py +++ b/mesa/datacollection.py @@ -154,7 +154,7 @@ def _new_table(self, table_name, table_columns): self.tables[table_name] = new_table def _record_agents(self, model): - """ Record agents data in a mapping of functions and agents. """ + """Record agents data in a mapping of functions and agents.""" rep_funcs = self.agent_reporters.values() if all([hasattr(rep, "attribute_name") for rep in rep_funcs]): prefix = ["model.schedule.steps", "unique_id"] @@ -174,7 +174,7 @@ def _reporter_decorator(self, reporter): return reporter() def collect(self, model): - """ Collect all the data for the given model object. """ + """Collect all the data for the given model object.""" if self.model_reporters: for var, reporter in self.model_reporters.items(): @@ -217,7 +217,7 @@ def add_table_row(self, table_name, row, ignore_missing=False): @staticmethod def _getattr(name, _object): - """ Turn around arguments of getattr to make it partially callable.""" + """Turn around arguments of getattr to make it partially callable.""" return getattr(_object, name, None) def get_model_vars_dataframe(self): diff --git a/mesa/model.py b/mesa/model.py index a148f012637..fddf68ea13f 100644 --- a/mesa/model.py +++ b/mesa/model.py @@ -11,7 +11,7 @@ class Model: - """ Base class for models. """ + """Base class for models.""" def __new__(cls, *args: Any, **kwargs: Any) -> Any: """Create a new model object and instantiate its RNG automatically.""" @@ -42,11 +42,11 @@ def run_model(self) -> None: self.step() def step(self) -> None: - """ A single step. Fill in here. """ + """A single step. Fill in here.""" pass def next_id(self) -> int: - """ Return the next unique ID for agents, increment current_id""" + """Return the next unique ID for agents, increment current_id""" self.current_id += 1 return self.current_id diff --git a/mesa/space.py b/mesa/space.py index a9750820faf..2ad29bff1a5 100644 --- a/mesa/space.py +++ b/mesa/space.py @@ -118,7 +118,7 @@ def __init__(self, width: int, height: int, torus: bool) -> None: @staticmethod def default_val() -> None: - """ Default value for new cell elements. """ + """Default value for new cell elements.""" return None @overload @@ -195,7 +195,7 @@ def __iter__(self) -> Iterator[GridContent]: return itertools.chain(*self.grid) def coord_iter(self) -> Iterator[Tuple[GridContent, int, int]]: - """ An iterator that returns coordinates as well as cell contents. """ + """An iterator that returns coordinates as well as cell contents.""" for row in range(self.width): for col in range(self.height): yield self.grid[row][col], row, col # agent, x, y @@ -356,7 +356,7 @@ def get_neighbors( return list(self.iter_neighbors(pos, moore, include_center, radius)) def torus_adj(self, pos: Coordinate) -> Coordinate: - """ Convert coordinate, handling torus looping. """ + """Convert coordinate, handling torus looping.""" if not self.out_of_bounds(pos): return pos elif not self.torus: @@ -416,35 +416,35 @@ def move_agent(self, agent: Agent, pos: Coordinate) -> None: agent.pos = pos def place_agent(self, agent: Agent, pos: Coordinate) -> None: - """ Position an agent on the grid, and set its pos variable. """ + """Position an agent on the grid, and set its pos variable.""" self._place_agent(pos, agent) agent.pos = pos def _place_agent(self, pos: Coordinate, agent: Agent) -> None: - """ Place the agent at the correct location. """ + """Place the agent at the correct location.""" x, y = pos self.grid[x][y] = agent self.empties.discard(pos) def remove_agent(self, agent: Agent) -> None: - """ Remove the agent from the grid and set its pos variable to None. """ + """Remove the agent from the grid and set its pos variable to None.""" pos = agent.pos self._remove_agent(pos, agent) agent.pos = None def _remove_agent(self, pos: Coordinate, agent: Agent) -> None: - """ Remove the agent from the given location. """ + """Remove the agent from the given location.""" x, y = pos self.grid[x][y] = None self.empties.add(pos) def is_cell_empty(self, pos: Coordinate) -> bool: - """ Returns a bool of the contents of a cell. """ + """Returns a bool of the contents of a cell.""" x, y = pos return self.grid[x][y] == self.default_val() def move_to_empty(self, agent: Agent) -> None: - """ Moves agent to a random empty cell, vacating agent's old cell. """ + """Moves agent to a random empty cell, vacating agent's old cell.""" pos = agent.pos if len(self.empties) == 0: raise Exception("ERROR: No empty cells") @@ -454,7 +454,7 @@ def move_to_empty(self, agent: Agent) -> None: self._remove_agent(pos, agent) def find_empty(self) -> Optional[Coordinate]: - """ Pick a random empty cell. """ + """Pick a random empty cell.""" from warnings import warn import random @@ -475,12 +475,12 @@ def find_empty(self) -> Optional[Coordinate]: return None def exists_empty_cells(self) -> bool: - """ Return True if any cells empty else False. """ + """Return True if any cells empty else False.""" return len(self.empties) > 0 class SingleGrid(Grid): - """ Grid where each cell contains exactly at most one object. """ + """Grid where each cell contains exactly at most one object.""" empties: Set[Coordinate] = set() @@ -544,18 +544,18 @@ class MultiGrid(Grid): @staticmethod def default_val() -> Set[Agent]: - """ Default value for new cell elements. """ + """Default value for new cell elements.""" return [] def _place_agent(self, pos: Coordinate, agent: Agent) -> None: - """ Place the agent at the correct location. """ + """Place the agent at the correct location.""" x, y = pos if agent not in self.grid[x][y]: self.grid[x][y].append(agent) self.empties.discard(pos) def _remove_agent(self, pos: Coordinate, agent: Agent) -> None: - """ Remove the agent from the given location. """ + """Remove the agent from the given location.""" x, y = pos self.grid[x][y].remove(agent) if self.is_cell_empty(pos): @@ -907,13 +907,13 @@ def torus_adj(self, pos: FloatCoordinate) -> FloatCoordinate: return np.array((x, y)) def out_of_bounds(self, pos: FloatCoordinate) -> bool: - """ Check if a point is out of bounds. """ + """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 class NetworkGrid: - """ Network Grid where each node contains zero or more agents. """ + """Network Grid where each node contains zero or more agents.""" def __init__(self, G: Any) -> None: self.G = G @@ -921,13 +921,13 @@ def __init__(self, G: Any) -> None: G.nodes[node_id]["agent"] = list() def place_agent(self, agent: Agent, node_id: int) -> None: - """ Place a agent in a node. """ + """Place a agent in a node.""" self._place_agent(agent, node_id) agent.pos = node_id def get_neighbors(self, node_id: int, include_center: bool = False) -> List[int]: - """ Get all adjacent nodes """ + """Get all adjacent nodes""" neighbors = list(self.G.neighbors(node_id)) if include_center: @@ -936,30 +936,30 @@ def get_neighbors(self, node_id: int, include_center: bool = False) -> List[int] return neighbors def move_agent(self, agent: Agent, node_id: int) -> None: - """ Move an agent from its current node to a new node. """ + """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: Agent, node_id: int) -> None: - """ Place the agent at the correct node. """ + """Place the agent at the correct node.""" self.G.nodes[node_id]["agent"].append(agent) def _remove_agent(self, agent: Agent, node_id: int) -> None: - """ Remove an agent from a node. """ + """Remove an agent from a node.""" self.G.nodes[node_id]["agent"].remove(agent) def remove_agent(self, agent: Agent) -> None: - """ Remove the agent from the network and set its pos variable to None. """ + """Remove the agent from the network and set its pos variable to None.""" pos = agent.pos self._remove_agent(agent, pos) agent.pos = None def is_cell_empty(self, node_id: int) -> bool: - """ Returns a bool of the contents of a cell. """ + """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: List[int]) -> List[GridContent]: diff --git a/mesa/time.py b/mesa/time.py index 4458de50109..dde633f095d 100644 --- a/mesa/time.py +++ b/mesa/time.py @@ -45,7 +45,7 @@ class BaseScheduler: """ def __init__(self, model: Model) -> None: - """ Create a new, empty BaseScheduler. """ + """Create a new, empty BaseScheduler.""" self.model = model self.steps = 0 self.time: TimeT = 0 @@ -79,14 +79,14 @@ def remove(self, agent: Agent) -> None: del self._agents[agent.unique_id] def step(self) -> None: - """ Execute the step of all the agents, one at a time. """ + """Execute the step of all the agents, one at a time.""" for agent in self.agent_buffer(shuffled=False): agent.step() self.steps += 1 self.time += 1 def get_agent_count(self) -> int: - """ Returns the current number of agents in the queue. """ + """Returns the current number of agents in the queue.""" return len(self._agents.keys()) @property @@ -139,7 +139,7 @@ class SimultaneousActivation(BaseScheduler): """ def step(self) -> None: - """ Step all agents, then advance them. """ + """Step all agents, then advance them.""" agent_keys = list(self._agents.keys()) for agent_key in agent_keys: self._agents[agent_key].step() @@ -188,7 +188,7 @@ def __init__( self.stage_time = 1 / len(self.stage_list) def step(self) -> None: - """ Executes all the stages for all agents. """ + """Executes all the stages for all agents.""" agent_keys = list(self._agents.keys()) if self.shuffle: self.model.random.shuffle(agent_keys) diff --git a/mesa/visualization/ModularVisualization.py b/mesa/visualization/ModularVisualization.py index 1cb5d87d99e..5200176c587 100644 --- a/mesa/visualization/ModularVisualization.py +++ b/mesa/visualization/ModularVisualization.py @@ -160,7 +160,7 @@ def render(self, model): class PageHandler(tornado.web.RequestHandler): - """ Handler for the HTML template which holds the visualization. """ + """Handler for the HTML template which holds the visualization.""" def get(self): elements = self.application.visualization_elements @@ -178,7 +178,7 @@ def get(self): class SocketHandler(tornado.websocket.WebSocketHandler): - """ Handler for websocket. """ + """Handler for websocket.""" def open(self): if self.application.verbose: @@ -230,7 +230,7 @@ def on_message(self, message): class ModularServer(tornado.web.Application): - """ Main visualization application. """ + """Main visualization application.""" verbose = True @@ -260,7 +260,7 @@ class ModularServer(tornado.web.Application): def __init__( self, model_cls, visualization_elements, name="Mesa Model", model_params={} ): - """ Create a new visualization server with the given elements. """ + """Create a new visualization server with the given elements.""" # Prep visualization elements: self.visualization_elements = visualization_elements self.package_includes = set() @@ -298,7 +298,7 @@ def user_params(self): return result def reset_model(self): - """ Reinstantiate the model object, using the current parameters. """ + """Reinstantiate the model object, using the current parameters.""" model_params = {} for key, val in self.model_kwargs.items(): @@ -325,7 +325,7 @@ def render_model(self): return visualization_state def launch(self, port=None, open_browser=True): - """ Run the app. """ + """Run the app.""" if port is not None: self.port = port url = "http://127.0.0.1:{PORT}".format(PORT=self.port) diff --git a/mesa/visualization/TextVisualization.py b/mesa/visualization/TextVisualization.py index d80cfa3b9d7..980a925a3df 100644 --- a/mesa/visualization/TextVisualization.py +++ b/mesa/visualization/TextVisualization.py @@ -42,17 +42,17 @@ class TextVisualization: """ def __init__(self, model): - """ Create a new Text Visualization object. """ + """Create a new Text Visualization object.""" self.model = model self.elements = [] def render(self): - """ Render all the text elements, in order. """ + """Render all the text elements, in order.""" for element in self.elements: print(element) def step(self): - """ Advance the model by a step and print the results. """ + """Advance the model by a step and print the results.""" self.model.step() self.render() @@ -69,7 +69,7 @@ def __init__(self): pass def render(self): - """ Render the element as text. """ + """Render the element as text.""" return "Placeholder!" def __str__(self): @@ -77,10 +77,10 @@ def __str__(self): class TextData(TextElement): - """ Prints the value of one particular variable from the base model. """ + """Prints the value of one particular variable from the base model.""" def __init__(self, model, var_name): - """ Create a new data renderer. """ + """Create a new data renderer.""" self.model = model self.var_name = var_name @@ -115,7 +115,7 @@ def __init__(self, grid, converter): self.converter = converter def render(self): - """ What to show when printed. """ + """What to show when printed.""" viz = "" for y in range(self.grid.height): for x in range(self.grid.width): diff --git a/tests/test_visualization.py b/tests/test_visualization.py index 2e84e71082c..3f33bee92fe 100644 --- a/tests/test_visualization.py +++ b/tests/test_visualization.py @@ -12,7 +12,7 @@ class MockModel(Model): - """ Test model for testing """ + """Test model for testing""" def __init__(self, width, height, key1=103, key2=104): @@ -33,7 +33,7 @@ def step(self): class TestModularServer(TestCase): - """ Test server for testing """ + """Test server for testing""" def portrayal(self, cell): return {