From af59039f8815c7d6086ec2887fcb808430a5bccf Mon Sep 17 00:00:00 2001 From: Jan Kwakkel Date: Sun, 27 Oct 2024 10:20:04 +0100 Subject: [PATCH 1/7] rework of epstein * shift to von neuman grid * update of perceived risk with round operator * introduction of enum for state * cleanup of statistics gathering to use enum * update of visualization code to be consistent with what is currently supported when drawing new_style discrete grids --- .../advanced/epstein_civil_violence/agents.py | 69 +++++++++------- .../advanced/epstein_civil_violence/app.py | 40 ++++----- .../advanced/epstein_civil_violence/model.py | 81 +++++++------------ 3 files changed, 87 insertions(+), 103 deletions(-) diff --git a/mesa/examples/advanced/epstein_civil_violence/agents.py b/mesa/examples/advanced/epstein_civil_violence/agents.py index edd1d1ebabf..6bb7612b645 100644 --- a/mesa/examples/advanced/epstein_civil_violence/agents.py +++ b/mesa/examples/advanced/epstein_civil_violence/agents.py @@ -1,15 +1,21 @@ import math +from enum import Enum import mesa +class CitizenState(Enum): + ACTIVE = 1 + QUIET = 2 + ARRESTED = 3 + + class EpsteinAgent(mesa.experimental.cell_space.CellAgent): def update_neighbors(self): """ Look around and see who my neighbors are """ self.neighborhood = self.cell.get_neighborhood(radius=self.vision) - self.neighbors = self.neighborhood.agents self.empty_neighbors = [c for c in self.neighborhood if c.is_empty] @@ -38,13 +44,14 @@ class Citizen(EpsteinAgent): """ def __init__( - self, - model, - hardship, - regime_legitimacy, - risk_aversion, - threshold, - vision, + self, + model, + hardship, + regime_legitimacy, + risk_aversion, + threshold, + vision, + arrest_prob_constant ): """ Create a new Citizen. @@ -66,12 +73,17 @@ def __init__( self.regime_legitimacy = regime_legitimacy self.risk_aversion = risk_aversion self.threshold = threshold - self.condition = "Quiescent" + self.state = CitizenState.QUIET self.vision = vision self.jail_sentence = 0 self.grievance = self.hardship * (1 - self.regime_legitimacy) + self.arrest_prob_constant = arrest_prob_constant self.arrest_probability = None + self.neighborhood = [] + self.neighbors = [] + self.empty_neighbors = [] + def step(self): """ Decide whether to activate, then move if applicable. @@ -81,11 +93,12 @@ def step(self): return # no other changes or movements if agent is in jail. self.update_neighbors() self.update_estimated_arrest_probability() + net_risk = self.risk_aversion * self.arrest_probability if self.grievance - net_risk > self.threshold: - self.condition = "Active" + self.state = CitizenState.ACTIVE else: - self.condition = "Quiescent" + self.state = CitizenState.QUIET if self.model.movement and self.empty_neighbors: new_cell = self.random.choice(self.empty_neighbors) @@ -96,17 +109,19 @@ def update_estimated_arrest_probability(self): Based on the ratio of cops to actives in my neighborhood, estimate the p(Arrest | I go active). """ - cops_in_vision = len([c for c in self.neighbors if isinstance(c, Cop)]) - actives_in_vision = 1.0 # citizen counts herself - for c in self.neighbors: - if ( - isinstance(c, Citizen) - and c.condition == "Active" - and c.jail_sentence == 0 - ): + cops_in_vision = 0 + actives_in_vision = 1 # citizen counts herself + for neighbor in self.neighbors: + if isinstance(neighbor, Cop): + cops_in_vision += 1 + elif neighbor.state == CitizenState: actives_in_vision += 1 + + # there is a body of literature on this equation + # the round is not in the pnas paper but without it, its impossible to replicate + # the dynamics shown there. self.arrest_probability = 1 - math.exp( - -1 * self.model.arrest_prob_constant * (cops_in_vision / actives_in_vision) + -1 * self.arrest_prob_constant * round(cops_in_vision / actives_in_vision) ) @@ -122,7 +137,7 @@ class Cop(EpsteinAgent): able to inspect """ - def __init__(self, model, vision): + def __init__(self, model, vision, max_jail_term): """ Create a new Cop. Args: @@ -133,6 +148,7 @@ def __init__(self, model, vision): """ super().__init__(model) self.vision = vision + self.max_jail_term = max_jail_term def step(self): """ @@ -143,16 +159,15 @@ def step(self): active_neighbors = [] for agent in self.neighbors: if ( - isinstance(agent, Citizen) - and agent.condition == "Active" - and agent.jail_sentence == 0 + isinstance(agent, Citizen) + and agent.state == CitizenState.ACTIVE ): active_neighbors.append(agent) if active_neighbors: arrestee = self.random.choice(active_neighbors) - sentence = self.random.randint(0, self.model.max_jail_term) - arrestee.jail_sentence = sentence - arrestee.condition = "Quiescent" + arrestee.jail_sentence = self.random.randint(0, self.max_jail_term) + arrestee.state = CitizenState.ARRESTED + if self.model.movement and self.empty_neighbors: new_pos = self.random.choice(self.empty_neighbors) self.move_to(new_pos) diff --git a/mesa/examples/advanced/epstein_civil_violence/app.py b/mesa/examples/advanced/epstein_civil_violence/app.py index 870e931c51d..08511b662d1 100644 --- a/mesa/examples/advanced/epstein_civil_violence/app.py +++ b/mesa/examples/advanced/epstein_civil_violence/app.py @@ -1,4 +1,9 @@ -from mesa.examples.advanced.epstein_civil_violence.agents import Citizen, Cop +import sys +import os.path +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../../'))) + + +from mesa.examples.advanced.epstein_civil_violence.agents import Citizen, Cop, CitizenState from mesa.examples.advanced.epstein_civil_violence.model import EpsteinCivilViolence from mesa.visualization import ( Slider, @@ -8,10 +13,9 @@ ) COP_COLOR = "#000000" -AGENT_QUIET_COLOR = "#648FFF" -AGENT_REBEL_COLOR = "#FE6100" -JAIL_COLOR = "#808080" -JAIL_SHAPE = "rect" +QUIET_COLOR = "#648FFF" +ACTIVE_COLOR = "#FE6100" +ARRESTED_COLOR = "#808080" def citizen_cop_portrayal(agent): @@ -20,29 +24,19 @@ def citizen_cop_portrayal(agent): portrayal = { "size": 25, - "shape": "s", # square marker } if isinstance(agent, Citizen): - color = ( - AGENT_QUIET_COLOR if agent.condition == "Quiescent" else AGENT_REBEL_COLOR - ) - color = JAIL_COLOR if agent.jail_sentence else color - shape = JAIL_SHAPE if agent.jail_sentence else "circle" + match agent.state: + case CitizenState.ACTIVE: + color = ACTIVE_COLOR + case CitizenState.QUIET: + color = QUIET_COLOR + case CitizenState.ARRESTED: + color = ARRESTED_COLOR portrayal["color"] = color - portrayal["shape"] = shape - if shape == "s": - portrayal["w"] = 0.9 - portrayal["h"] = 0.9 - else: - portrayal["r"] = 0.5 - portrayal["filled"] = False - portrayal["layer"] = 0 - elif isinstance(agent, Cop): portrayal["color"] = COP_COLOR - portrayal["r"] = 0.9 - portrayal["layer"] = 1 return portrayal @@ -59,7 +53,7 @@ def citizen_cop_portrayal(agent): } space_component = make_space_matplotlib(citizen_cop_portrayal) -chart_component = make_plot_measure(["Quiescent", "Active", "Jailed"]) +chart_component = make_plot_measure([state.name.lower() for state in CitizenState]) epstein_model = EpsteinCivilViolence() diff --git a/mesa/examples/advanced/epstein_civil_violence/model.py b/mesa/examples/advanced/epstein_civil_violence/model.py index 3d3708e1241..2cd94c7f0b3 100644 --- a/mesa/examples/advanced/epstein_civil_violence/model.py +++ b/mesa/examples/advanced/epstein_civil_violence/model.py @@ -1,5 +1,5 @@ import mesa -from mesa.examples.advanced.epstein_civil_violence.agents import Citizen, Cop +from mesa.examples.advanced.epstein_civil_violence.agents import Citizen, Cop, CitizenState class EpsteinCivilViolence(mesa.Model): @@ -7,7 +7,8 @@ class EpsteinCivilViolence(mesa.Model): Model 1 from "Modeling civil violence: An agent-based computational approach," by Joshua Epstein. http://www.pnas.org/content/99/suppl_3/7243.full - Attributes: + + Args: height: grid height width: grid width citizen_density: approximate % of cells occupied by citizens. @@ -45,61 +46,53 @@ def __init__( seed=None, ): super().__init__(seed=seed) - self.width = width - self.height = height - self.citizen_density = citizen_density - self.cop_density = cop_density - self.citizen_vision = citizen_vision - self.cop_vision = cop_vision - self.legitimacy = legitimacy - self.max_jail_term = max_jail_term - self.active_threshold = active_threshold - self.arrest_prob_constant = arrest_prob_constant self.movement = movement self.max_iters = max_iters - self.iteration = 0 - self.grid = mesa.experimental.cell_space.OrthogonalMooreGrid( + self.grid = mesa.experimental.cell_space.OrthogonalVonNeumannGrid( (width, height), capacity=1, torus=True, random=self.random ) model_reporters = { - "Quiescent": lambda m: self.count_type_citizens(m, "Quiescent"), - "Active": lambda m: self.count_type_citizens(m, "Active"), - "Jailed": self.count_jailed, - "Cops": self.count_cops, + 'active': CitizenState.ACTIVE.name, + 'quiet': CitizenState.QUIET.name, + 'arrested': CitizenState.ARRESTED.name, + "Cops": self.count_cops } agent_reporters = { "x": lambda a: a.cell.coordinate[0], "y": lambda a: a.cell.coordinate[1], - "breed": lambda a: type(a).__name__, "jail_sentence": lambda a: getattr(a, "jail_sentence", None), - "condition": lambda a: getattr(a, "condition", None), "arrest_probability": lambda a: getattr(a, "arrest_probability", None), } self.datacollector = mesa.DataCollector( model_reporters=model_reporters, agent_reporters=agent_reporters ) - if self.cop_density + self.citizen_density > 1: + if cop_density + citizen_density > 1: raise ValueError("Cop density + citizen density must be less than 1") for cell in self.grid.all_cells: - if self.random.random() < self.cop_density: - cop = Cop(self, vision=self.cop_vision) - cop.move_to(cell) + klass = self.random.choices([Citizen, Cop, None], + cum_weights=[citizen_density, + citizen_density+cop_density, 1])[0] - elif self.random.random() < (self.cop_density + self.citizen_density): + if klass == Cop: + cop = Cop(self, vision=cop_vision, max_jail_term=max_jail_term) + cop.move_to(cell) + elif klass == Citizen: citizen = Citizen( self, hardship=self.random.random(), - regime_legitimacy=self.legitimacy, + regime_legitimacy=legitimacy, risk_aversion=self.random.random(), - threshold=self.active_threshold, - vision=self.citizen_vision, + threshold=active_threshold, + vision=citizen_vision, + arrest_prob_constant=arrest_prob_constant ) citizen.move_to(cell) self.running = True + self._update_counts() self.datacollector.collect(self) def step(self): @@ -107,36 +100,18 @@ def step(self): Advance the model by one step and collect data. """ self.agents.shuffle_do("step") - # collect data + self._update_counts() self.datacollector.collect(self) - self.iteration += 1 - if self.iteration > self.max_iters: + + if self.steps > self.max_iters: self.running = False - @staticmethod - def count_type_citizens(model, condition, exclude_jailed=True): - """ - Helper method to count agents by Quiescent/Active. - """ - citizens = model.agents_by_type[Citizen] + def _update_counts(self): + counts = self.agents_by_type[Citizen].groupby("state").count() - if exclude_jailed: - return len( - [ - c - for c in citizens - if (c.condition == condition) and (c.jail_sentence == 0) - ] - ) - else: - return len([c for c in citizens if c.condition == condition]) + for state in CitizenState: + setattr(self, state.name, counts.get(state, 0)) - @staticmethod - def count_jailed(model): - """ - Helper method to count jailed agents. - """ - return len([a for a in model.agents_by_type[Citizen] if a.jail_sentence > 0]) @staticmethod def count_cops(model): From a5075bbda9c6678ba815252375c9b5772b994476 Mon Sep 17 00:00:00 2001 From: Jan Kwakkel Date: Sun, 27 Oct 2024 10:36:17 +0100 Subject: [PATCH 2/7] further cleaning --- .../advanced/epstein_civil_violence/agents.py | 24 +++++++++---------- .../advanced/epstein_civil_violence/model.py | 14 +---------- 2 files changed, 13 insertions(+), 25 deletions(-) diff --git a/mesa/examples/advanced/epstein_civil_violence/agents.py b/mesa/examples/advanced/epstein_civil_violence/agents.py index 6bb7612b645..2bc305c405c 100644 --- a/mesa/examples/advanced/epstein_civil_violence/agents.py +++ b/mesa/examples/advanced/epstein_civil_violence/agents.py @@ -19,6 +19,12 @@ def update_neighbors(self): self.neighbors = self.neighborhood.agents self.empty_neighbors = [c for c in self.neighborhood if c.is_empty] + def move(self): + if self.model.movement and self.empty_neighbors: + new_pos = self.random.choice(self.empty_neighbors) + self.move_to(new_pos) + + class Citizen(EpsteinAgent): """ @@ -46,9 +52,7 @@ class Citizen(EpsteinAgent): def __init__( self, model, - hardship, regime_legitimacy, - risk_aversion, threshold, vision, arrest_prob_constant @@ -69,9 +73,9 @@ def __init__( model: model instance """ super().__init__(model) - self.hardship = hardship + self.hardship = self.random.random() + self.risk_aversion = self.random.random() self.regime_legitimacy = regime_legitimacy - self.risk_aversion = risk_aversion self.threshold = threshold self.state = CitizenState.QUIET self.vision = vision @@ -95,14 +99,12 @@ def step(self): self.update_estimated_arrest_probability() net_risk = self.risk_aversion * self.arrest_probability - if self.grievance - net_risk > self.threshold: + if (self.grievance - net_risk) > self.threshold: self.state = CitizenState.ACTIVE else: self.state = CitizenState.QUIET - if self.model.movement and self.empty_neighbors: - new_cell = self.random.choice(self.empty_neighbors) - self.move_to(new_cell) + self.move() def update_estimated_arrest_probability(self): """ @@ -114,7 +116,7 @@ def update_estimated_arrest_probability(self): for neighbor in self.neighbors: if isinstance(neighbor, Cop): cops_in_vision += 1 - elif neighbor.state == CitizenState: + elif neighbor.state == CitizenState.ACTIVE: actives_in_vision += 1 # there is a body of literature on this equation @@ -168,6 +170,4 @@ def step(self): arrestee.jail_sentence = self.random.randint(0, self.max_jail_term) arrestee.state = CitizenState.ARRESTED - if self.model.movement and self.empty_neighbors: - new_pos = self.random.choice(self.empty_neighbors) - self.move_to(new_pos) + self.move() \ No newline at end of file diff --git a/mesa/examples/advanced/epstein_civil_violence/model.py b/mesa/examples/advanced/epstein_civil_violence/model.py index 2cd94c7f0b3..949a034539d 100644 --- a/mesa/examples/advanced/epstein_civil_violence/model.py +++ b/mesa/examples/advanced/epstein_civil_violence/model.py @@ -57,11 +57,8 @@ def __init__( 'active': CitizenState.ACTIVE.name, 'quiet': CitizenState.QUIET.name, 'arrested': CitizenState.ARRESTED.name, - "Cops": self.count_cops } agent_reporters = { - "x": lambda a: a.cell.coordinate[0], - "y": lambda a: a.cell.coordinate[1], "jail_sentence": lambda a: getattr(a, "jail_sentence", None), "arrest_probability": lambda a: getattr(a, "arrest_probability", None), } @@ -82,9 +79,7 @@ def __init__( elif klass == Citizen: citizen = Citizen( self, - hardship=self.random.random(), regime_legitimacy=legitimacy, - risk_aversion=self.random.random(), threshold=active_threshold, vision=citizen_vision, arrest_prob_constant=arrest_prob_constant @@ -107,15 +102,8 @@ def step(self): self.running = False def _update_counts(self): + """Helper function for counting nr. of citizens in given state.""" counts = self.agents_by_type[Citizen].groupby("state").count() for state in CitizenState: setattr(self, state.name, counts.get(state, 0)) - - - @staticmethod - def count_cops(model): - """ - Helper method to count jailed agents. - """ - return len(model.agents_by_type[Cop]) From efc744ec39b5840421dc2570fc250819d8544f2a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 27 Oct 2024 09:40:10 +0000 Subject: [PATCH 3/7] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .../advanced/epstein_civil_violence/agents.py | 15 +++---------- .../advanced/epstein_civil_violence/app.py | 13 +++++++++--- .../advanced/epstein_civil_violence/model.py | 21 ++++++++++++------- 3 files changed, 26 insertions(+), 23 deletions(-) diff --git a/mesa/examples/advanced/epstein_civil_violence/agents.py b/mesa/examples/advanced/epstein_civil_violence/agents.py index 2bc305c405c..026ec342e22 100644 --- a/mesa/examples/advanced/epstein_civil_violence/agents.py +++ b/mesa/examples/advanced/epstein_civil_violence/agents.py @@ -25,7 +25,6 @@ def move(self): self.move_to(new_pos) - class Citizen(EpsteinAgent): """ A member of the general population, may or may not be in active rebellion. @@ -50,12 +49,7 @@ class Citizen(EpsteinAgent): """ def __init__( - self, - model, - regime_legitimacy, - threshold, - vision, - arrest_prob_constant + self, model, regime_legitimacy, threshold, vision, arrest_prob_constant ): """ Create a new Citizen. @@ -160,14 +154,11 @@ def step(self): self.update_neighbors() active_neighbors = [] for agent in self.neighbors: - if ( - isinstance(agent, Citizen) - and agent.state == CitizenState.ACTIVE - ): + if isinstance(agent, Citizen) and agent.state == CitizenState.ACTIVE: active_neighbors.append(agent) if active_neighbors: arrestee = self.random.choice(active_neighbors) arrestee.jail_sentence = self.random.randint(0, self.max_jail_term) arrestee.state = CitizenState.ARRESTED - self.move() \ No newline at end of file + self.move() diff --git a/mesa/examples/advanced/epstein_civil_violence/app.py b/mesa/examples/advanced/epstein_civil_violence/app.py index 08511b662d1..ade5ab8577f 100644 --- a/mesa/examples/advanced/epstein_civil_violence/app.py +++ b/mesa/examples/advanced/epstein_civil_violence/app.py @@ -1,9 +1,16 @@ -import sys import os.path -sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../../'))) +import sys +sys.path.insert( + 0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../../../../")) +) -from mesa.examples.advanced.epstein_civil_violence.agents import Citizen, Cop, CitizenState + +from mesa.examples.advanced.epstein_civil_violence.agents import ( + Citizen, + CitizenState, + Cop, +) from mesa.examples.advanced.epstein_civil_violence.model import EpsteinCivilViolence from mesa.visualization import ( Slider, diff --git a/mesa/examples/advanced/epstein_civil_violence/model.py b/mesa/examples/advanced/epstein_civil_violence/model.py index 949a034539d..3e632b65e77 100644 --- a/mesa/examples/advanced/epstein_civil_violence/model.py +++ b/mesa/examples/advanced/epstein_civil_violence/model.py @@ -1,5 +1,9 @@ import mesa -from mesa.examples.advanced.epstein_civil_violence.agents import Citizen, Cop, CitizenState +from mesa.examples.advanced.epstein_civil_violence.agents import ( + Citizen, + CitizenState, + Cop, +) class EpsteinCivilViolence(mesa.Model): @@ -54,9 +58,9 @@ def __init__( ) model_reporters = { - 'active': CitizenState.ACTIVE.name, - 'quiet': CitizenState.QUIET.name, - 'arrested': CitizenState.ARRESTED.name, + "active": CitizenState.ACTIVE.name, + "quiet": CitizenState.QUIET.name, + "arrested": CitizenState.ARRESTED.name, } agent_reporters = { "jail_sentence": lambda a: getattr(a, "jail_sentence", None), @@ -69,9 +73,10 @@ def __init__( raise ValueError("Cop density + citizen density must be less than 1") for cell in self.grid.all_cells: - klass = self.random.choices([Citizen, Cop, None], - cum_weights=[citizen_density, - citizen_density+cop_density, 1])[0] + klass = self.random.choices( + [Citizen, Cop, None], + cum_weights=[citizen_density, citizen_density + cop_density, 1], + )[0] if klass == Cop: cop = Cop(self, vision=cop_vision, max_jail_term=max_jail_term) @@ -82,7 +87,7 @@ def __init__( regime_legitimacy=legitimacy, threshold=active_threshold, vision=citizen_vision, - arrest_prob_constant=arrest_prob_constant + arrest_prob_constant=arrest_prob_constant, ) citizen.move_to(cell) From a876d77eae2ce2c08474efcadf6bfd76efad6cb1 Mon Sep 17 00:00:00 2001 From: Jan Kwakkel Date: Sun, 27 Oct 2024 10:41:50 +0100 Subject: [PATCH 4/7] cleanup --- .../advanced/epstein_civil_violence/app.py | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/mesa/examples/advanced/epstein_civil_violence/app.py b/mesa/examples/advanced/epstein_civil_violence/app.py index ade5ab8577f..81e59f4b271 100644 --- a/mesa/examples/advanced/epstein_civil_violence/app.py +++ b/mesa/examples/advanced/epstein_civil_violence/app.py @@ -1,16 +1,4 @@ -import os.path -import sys - -sys.path.insert( - 0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../../../../")) -) - - -from mesa.examples.advanced.epstein_civil_violence.agents import ( - Citizen, - CitizenState, - Cop, -) +from mesa.examples.advanced.epstein_civil_violence.agents import Citizen, Cop, CitizenState from mesa.examples.advanced.epstein_civil_violence.model import EpsteinCivilViolence from mesa.visualization import ( Slider, From 195703b981879f493474a01e10450c7a4fa4f930 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 27 Oct 2024 09:42:31 +0000 Subject: [PATCH 5/7] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- mesa/examples/advanced/epstein_civil_violence/app.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/mesa/examples/advanced/epstein_civil_violence/app.py b/mesa/examples/advanced/epstein_civil_violence/app.py index 81e59f4b271..bdd7df1b036 100644 --- a/mesa/examples/advanced/epstein_civil_violence/app.py +++ b/mesa/examples/advanced/epstein_civil_violence/app.py @@ -1,4 +1,8 @@ -from mesa.examples.advanced.epstein_civil_violence.agents import Citizen, Cop, CitizenState +from mesa.examples.advanced.epstein_civil_violence.agents import ( + Citizen, + CitizenState, + Cop, +) from mesa.examples.advanced.epstein_civil_violence.model import EpsteinCivilViolence from mesa.visualization import ( Slider, From a7fa4766444eceb61b4fd20755a0de213ad2c41b Mon Sep 17 00:00:00 2001 From: Jan Kwakkel Date: Sun, 27 Oct 2024 15:43:04 +0100 Subject: [PATCH 6/7] shift to dict for colors --- .../advanced/epstein_civil_violence/app.py | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/mesa/examples/advanced/epstein_civil_violence/app.py b/mesa/examples/advanced/epstein_civil_violence/app.py index bdd7df1b036..338cda8f714 100644 --- a/mesa/examples/advanced/epstein_civil_violence/app.py +++ b/mesa/examples/advanced/epstein_civil_violence/app.py @@ -12,10 +12,12 @@ ) COP_COLOR = "#000000" -QUIET_COLOR = "#648FFF" -ACTIVE_COLOR = "#FE6100" -ARRESTED_COLOR = "#808080" +agent_colors = { + CitizenState.ACTIVE: "#FE6100", + CitizenState.QUIET: "#648FFF", + CitizenState.ARRESTED: "#808080" +} def citizen_cop_portrayal(agent): if agent is None: @@ -26,14 +28,7 @@ def citizen_cop_portrayal(agent): } if isinstance(agent, Citizen): - match agent.state: - case CitizenState.ACTIVE: - color = ACTIVE_COLOR - case CitizenState.QUIET: - color = QUIET_COLOR - case CitizenState.ARRESTED: - color = ARRESTED_COLOR - portrayal["color"] = color + portrayal["color"] = agent_colors[agent.state] elif isinstance(agent, Cop): portrayal["color"] = COP_COLOR From df4b3c1d5806daa89d702b59ce47884e328126fc Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 27 Oct 2024 14:44:37 +0000 Subject: [PATCH 7/7] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- mesa/examples/advanced/epstein_civil_violence/app.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mesa/examples/advanced/epstein_civil_violence/app.py b/mesa/examples/advanced/epstein_civil_violence/app.py index 338cda8f714..862ca6220d8 100644 --- a/mesa/examples/advanced/epstein_civil_violence/app.py +++ b/mesa/examples/advanced/epstein_civil_violence/app.py @@ -16,9 +16,10 @@ agent_colors = { CitizenState.ACTIVE: "#FE6100", CitizenState.QUIET: "#648FFF", - CitizenState.ARRESTED: "#808080" + CitizenState.ARRESTED: "#808080", } + def citizen_cop_portrayal(agent): if agent is None: return