diff --git a/src/pop2net/__init__.py b/src/pop2net/__init__.py index ca3493f..3e02923 100644 --- a/src/pop2net/__init__.py +++ b/src/pop2net/__init__.py @@ -7,8 +7,8 @@ from .exceptions import Pop2netException from .inspector import NetworkInspector from .location import Location -from .location import MagicLocation -from .location import MeltLocation +from .location_designer import LocationDesigner +from .location_designer import MeltLocationDesigner from .model import Model from .sequences import LocationList @@ -17,8 +17,8 @@ "Agent", "Pop2netException", "Location", - "MagicLocation", - "MeltLocation", + "LocationDesigner", + "MeltLocationDesigner", "NetworkInspector", "Model", "LocationList", diff --git a/src/pop2net/agent.py b/src/pop2net/agent.py index 0e5df6b..c379b77 100644 --- a/src/pop2net/agent.py +++ b/src/pop2net/agent.py @@ -44,25 +44,25 @@ def setup(self) -> None: This is executed on the instantiation of each agent. """ - def neighbors(self, location_classes: list | None = None) -> ap.AgentList: + def neighbors(self, location_labels: list[str] | None = None) -> ap.AgentList: """Return all neighbors of an agent. Convenience method that returns all neighbors over all locations this agent is currently - located in. The locations to be considered can be defined with location_classes. + located in. The locations to be considered can be defined with location_labels. Args: - location_classes: A list of location_classes. + location_labels: A list of location_labels. Returns: All agents co-located with this agent over all locations. """ - return self.model.neighbors_of_agent(self, location_classes=location_classes) + return self.model.neighbors_of_agent(self, location_labels=location_labels) - def shared_locations(self, agent, location_classes: list | None = None): + def shared_locations(self, agent, location_labels: list[str] | None = None): return self.model.locations_between_agents( agent1=self, agent2=agent, - location_classes=location_classes, + location_labels=location_labels, ) def add_location(self, location: _location.Location, weight: float | None = None) -> None: @@ -112,21 +112,21 @@ def locations(self) -> _sequences.LocationList: """ return self.model.locations_of_agent(self) - def get_agent_weight(self, agent: Agent, location_classes: list | None = None) -> float: + def get_agent_weight(self, agent: Agent, location_labels: list | None = None) -> float: """Return the edge weight between this agent and a given other agent. This is summed over all shared locations. Args: agent: The other agent. - location_classes (list): A list of location classes to specify the type of locations + location_labels (list): A list of location classes to specify the type of locations which are considered. Returns: A weight of the contact between the two agents. """ weight = 0 - for location in self.shared_locations(agent=agent, location_classes=location_classes): + for location in self.shared_locations(agent=agent, location_labels=location_labels): weight += location.project_weights(agent1=self, agent2=agent) return weight @@ -155,7 +155,7 @@ def connect(self, agent: Agent, location_cls: type, weight: float | None = None) def disconnect( self, neighbor: Agent, - location_classes: list | None = None, + location_labels: list | None = None, remove_self=True, remove_neighbor=True, remove_locations: bool = False, @@ -169,7 +169,7 @@ def disconnect( Args: neighbor (Agent): An agent to disconnect from. - location_classes (list | None, optional): A list of location types to specify which + location_labels (list | None, optional): A list of location types to specify which shared locations are considered. Defaults to None. remove_self (bool): Should the agent be removed from the shared locations? Defaults to True. @@ -180,7 +180,7 @@ def disconnect( """ shared_locations = self.shared_locations( agent=neighbor, - location_classes=location_classes, + location_labels=location_labels, ) for location in shared_locations: diff --git a/src/pop2net/creator.py b/src/pop2net/creator.py index 3ee8d9e..8321a21 100644 --- a/src/pop2net/creator.py +++ b/src/pop2net/creator.py @@ -2,6 +2,7 @@ from __future__ import annotations +import itertools import math import random import warnings @@ -34,8 +35,17 @@ def __init__( self._dummy_model = p2n.Model(parameters=self.model.p) self._temp_agent_attrs = ["_P2NTEMP_split_values", "_P2NTEMP_melt_location_weight"] - def _create_dummy_location(self, location_cls) -> p2n.Location: - location = location_cls(model=self._dummy_model) + def _create_dummy_location(self, designer) -> p2n.Location: + lc = designer.location_class + cls = type( + "Location" if lc is None else utils._get_cls_as_str(designer.location_class), + (designer,) if lc is None else (designer, designer.location_class), + {}, # TODO: warum funktioniert das hier nicht?: {"label": designer.label}, + ) + location = cls(model=self._dummy_model) + location.label = ( + designer.label if designer.label is not None else utils._get_cls_as_str(designer) + ) location.setup() return location @@ -172,7 +182,7 @@ def create_agents( return agents def _get_affiliated_agents(self, agents, dummy_location) -> list: - temp_filter_attr = "_P2NTEMP_filter_" + dummy_location.type + temp_filter_attr = "_P2NTEMP_filter_" + dummy_location.label affiliated_agents = [] for agent in agents: @@ -193,7 +203,7 @@ def _get_mother_group_id(self, agent, dummy_location) -> str: # search for mother location assigned to this agent n_mother_locations_found = 0 for location in agent.locations: - if isinstance(location, dummy_location.nest()): + if location.label == dummy_location.nest(): mother_location = location n_mother_locations_found += 1 @@ -226,7 +236,7 @@ def _get_split_values( for i, value in enumerate(agent_values): mother_group_id = self._get_mother_group_id(agent, dummy_location) agent_values[i] = "-".join([mother_group_id, str(value)]) - temp_attr = f"_P2NTEMP_{dummy_location.type}_mother_group_id" + temp_attr = f"_P2NTEMP_{dummy_location.label}_mother_group_id" setattr(agent, temp_attr, mother_group_id) self._temp_agent_attrs.append(temp_attr) @@ -247,10 +257,10 @@ def _get_stick_value(self, agent, dummy_location): else: return stick_value - def _get_groups(self, agents, location_cls) -> list[list]: + def _get_groups(self, agents, designer) -> list[list]: overcrowding_i = 0 - dummy_location = self._create_dummy_location(location_cls) + dummy_location = self._create_dummy_location(designer) n_location_groups_is_fixed = False @@ -278,7 +288,7 @@ def _get_groups(self, agents, location_cls) -> list[list]: elif dummy_location.n_locations is not None and dummy_location.n_agents is None: n_location_groups = dummy_location.n_locations - location_cls.n_agents = max( + designer.n_agents = max( math.floor(len(agents) / n_location_groups), 1, ) @@ -295,7 +305,7 @@ def _get_groups(self, agents, location_cls) -> list[list]: stick_values = {self._get_stick_value(agent, dummy_location) for agent in agents} - # dummy_location = self._create_dummy_location(location_cls) + # dummy_location = self._create_dummy_location(designer) # for each group of sticky agents for stick_value in stick_values: @@ -326,7 +336,7 @@ def _get_groups(self, agents, location_cls) -> list[list]: if not assigned: if len(groups) < n_location_groups: new_group = [] - dummy_location = self._create_dummy_location(location_cls) + dummy_location = self._create_dummy_location(designer) # assign agents for agent in sticky_agents: new_group.append(agent) @@ -356,8 +366,8 @@ def _get_split_value_affiliated_agents( return group_affiliated_agents - def _get_melted_groups(self, agents: list, location_cls) -> list[list]: - dummy_location = self._create_dummy_location(location_cls) + def _get_melted_groups(self, agents: list, designer) -> list[list]: + dummy_location = self._create_dummy_location(designer) # get all mother locations the agents are nested in all_mother_group_ids = { @@ -381,11 +391,11 @@ def _get_melted_groups(self, agents: list, location_cls) -> list[list]: groups_to_melt_by_location: list[list[list]] = [] # for each location that shall be melted - for melt_location_cls in dummy_location.melt(): + for melt_designer in dummy_location.melt(): # create dummy location - melt_dummy_location = self._create_dummy_location(melt_location_cls) - if melt_location_cls.n_locations is None: - melt_location_cls.n_locations = location_cls.n_locations + melt_dummy_location = self._create_dummy_location(melt_designer) + if melt_designer.n_locations is None: + melt_designer.n_locations = designer.n_locations # get all agents that should be assigned to this location # filter by melt_location @@ -419,7 +429,7 @@ def _get_melted_groups(self, agents: list, location_cls) -> list[list]: location_groups_to_melt.extend( self._get_groups( agents=melt_split_value_affiliated_agents, - location_cls=melt_location_cls, + designer=melt_designer, ), ) @@ -448,18 +458,59 @@ def _get_melted_groups(self, agents: list, location_cls) -> list[list]: return all_melted_groups + def _create_designer_mutations(self, location_designers: list) -> list: + # for each location designer class + for designer in location_designers: + # create a dummy location to use the location's methods + dummy_location = self._create_dummy_location(designer) + + # if the user defined mutations + if dummy_location.mutate() is not None: + mutations = [] + + # create all possible combinations of the mutation values + # {key: [1, 2, 3], key2: [4, 5]} -> [{key: 1, key2: 4}, {key: 1, key2: 5}, ...] + combinations = [ + dict(zip(dummy_location.mutate().keys(), values)) + for values in itertools.product(*dummy_location.mutate().values()) + ] + + # create a new location designer class for each combination + for i, combo in enumerate(combinations): + mutation = type( + dummy_location.type, + (designer,), + { + **combo, + "label": f"{dummy_location.label}{i}", + }, + ) + mutations.append(mutation) + + # store the mutations in the designer class + designer._P2NTEMP_mutations = mutations + + # replace the original location designer classes with the mutations + location_designers_with_mutations = [] + for location_designer in location_designers: + if hasattr(location_designer, "_P2NTEMP_mutations"): + location_designers_with_mutations.extend(location_designer._P2NTEMP_mutations) + else: + location_designers_with_mutations.append(location_designer) + + return location_designers_with_mutations + def create_locations( self, - location_classes: list, + location_designers: list, agents: list | p2n.AgentList | None = None, clear: bool = False, - # TODO: delete_magic_location_attributes: bool = True, delete_magic_agent_attributes: bool = True, ) -> p2n.LocationList: """Creates location instances and connects them with the given agent population. Args: - location_classes (list): A list of location classes. + location_designers (list): A list of LocationDesigner classes. agents (list | p2n.AgentList): A list of agents. clear (bool): Should the locations already included in the model be removed? delete_magic_location_attributes (bool): If True, all magic location attributes will be @@ -470,12 +521,31 @@ def create_locations( Returns: p2n.LocationList: A list of locations. """ + # Create designer mutations + location_designers = self._create_designer_mutations(location_designers) + + # Check if all location classes have a unique label + labels = [] + for designer in location_designers: + dummy_location = self._create_dummy_location(designer) + if dummy_location.label is None: + msg = ( + f"LocationDesigner class {designer} has no label. Please define a unique label." + ) + raise Pop2netException(msg) + elif dummy_location.label in labels: + msg = f"""LocationDesigner class {designer} has a duplicate label. + Please define a unique label.""" + raise Pop2netException(msg) + else: + labels.append(dummy_location.label) + + # Remove all locations if clear is True if clear: - # Remove all locations self.model.remove_locations(self.model.locations) + # Use the existing agents in the model if no agents are given if agents is None: if agents is None: - # Use the existing agents in the model if no agents are given agents = self.model.agents # Create a list containing the names of all special location attributes @@ -485,39 +555,41 @@ def create_locations( # Add the agents to the dummy model self._dummy_model.add_agents(agents) - for location_cls in location_classes: - dummy_location = self._create_dummy_location(location_cls) - str_location_cls = dummy_location.type + # Create magic agent attributes for each location designer class + for designer in location_designers: + dummy_location = self._create_dummy_location(designer) + label = dummy_location.label for agent in agents: - setattr(agent, str_location_cls, None) - magic_agent_attributes.append(str_location_cls) + setattr(agent, label, None) + magic_agent_attributes.append(label) - setattr(agent, str_location_cls + "_assigned", False) - magic_agent_attributes.append(str_location_cls + "_assigned") + setattr(agent, label + "_assigned", False) + magic_agent_attributes.append(label + "_assigned") - setattr(agent, str_location_cls + "_id", None) - magic_agent_attributes.append(str_location_cls + "_id") + setattr(agent, label + "_id", None) + magic_agent_attributes.append(label + "_id") - setattr(agent, str_location_cls + "_position", None) - magic_agent_attributes.append(str_location_cls + "_position") + setattr(agent, label + "_position", None) + magic_agent_attributes.append(label + "_position") - setattr(agent, str_location_cls + "_head", None) - magic_agent_attributes.append(str_location_cls + "_head") + setattr(agent, label + "_head", None) + magic_agent_attributes.append(label + "_head") - setattr(agent, str_location_cls + "_tail", None) - magic_agent_attributes.append(str_location_cls + "_tail") + setattr(agent, label + "_tail", None) + magic_agent_attributes.append(label + "_tail") + # The list of all created location instances locations = [] - # for each location class - for location_cls in location_classes: + # For each designer: start of creation procedure + for designer in location_designers: + # Set temporary location weight of MeltLocations to None for agent in agents: agent._P2NTEMP_melt_location_weight = None # create location dummy in order to use the location's methods - dummy_location = self._create_dummy_location(location_cls) - - str_location_cls = dummy_location.type + dummy_location = self._create_dummy_location(designer) + label = dummy_location.label # If nxgraph is used do some checks if dummy_location.nxgraph is not None: @@ -525,16 +597,27 @@ def create_locations( msg = """You cannot define location.n_agents if location.nxgraph is used. It will be set to the number of nodes in location.nxgraph automatically.""" warnings.warn(msg) - location_cls.n_agents = len(list(dummy_location.nxgraph.nodes)) + designer.n_agents = len(list(dummy_location.nxgraph.nodes)) dummy_location.n_agents = len(list(dummy_location.nxgraph.nodes)) if dummy_location.overcrowding is True and self.model.enable_p2n_warnings: msg = """You cannot define location.overcrowding if location.nxgraph is used. It will be set to `False` automatically.""" warnings.warn(msg) - location_cls.overcrowding = False + designer.overcrowding = False dummy_location.overcrowding = False + # check if n_locations and split is used at the same time + if ( + not all(dummy_location.split(agent) is None for agent in agents) + and dummy_location.n_locations is not None + ): + msg = f"""You cannot use {label}.n_locations and {label}.split() at the same time. + {label}.n_locations is ignored and set to None.""" + warnings.warn(msg) + designer.n_locations = None + dummy_location.n_locations = None + # bridge if not dummy_location.melt(): bridge_values = { @@ -549,8 +632,8 @@ def create_locations( pass elif len(bridge_values) == 1 and self.model.enable_p2n_warnings: - msg = f"""{str_location_cls}.bridge() returned only one unique value. - {str_location_cls}.bridge() must return at least two unique values in order + msg = f"""{dummy_location.label}.bridge() returned only one unique value. + {dummy_location.label}.bridge() must return at least two unique values in order to create locations that bring together agents with different values on the same attribute. """ @@ -558,8 +641,8 @@ def create_locations( elif len(bridge_values) > 1 and self.model.enable_p2n_warnings: if dummy_location.n_agents is not None: - msg = f"""You cannot use {str_location_cls}.n_agents and - {str_location_cls}.bridge() at the same time. {str_location_cls}.n_agents + msg = f"""You cannot use {label}.n_agents and + {label}.bridge() at the same time. {label}.n_agents is ignored.""" warnings.warn(msg) @@ -573,7 +656,7 @@ def filter(self, agent): dummy_melt_class = type( f"dummy_meltlocation{str(bridge_value)}", - (p2n.MeltLocation,), + (p2n.MeltLocationDesigner,), { "filter": filter, "n_agents": 1, @@ -587,8 +670,8 @@ def filter(self, agent): def melt(self): return melt_list - location_cls.melt = melt - dummy_location = self._create_dummy_location(location_cls) + designer.melt = melt + dummy_location = self._create_dummy_location(designer) if not dummy_location.melt(): # get all agents that could be assigned to locations of this class @@ -600,8 +683,8 @@ def melt(self): else: affiliated_agents = [] - for melt_location_cls in dummy_location.melt(): - melt_dummy_location = self._create_dummy_location(melt_location_cls) + for melt_designer in dummy_location.melt(): + melt_dummy_location = self._create_dummy_location(melt_designer) affiliated_agents.extend( self._get_affiliated_agents( agents=agents, @@ -635,23 +718,20 @@ def melt(self): if not dummy_location.melt(): group_lists: list[list] = self._get_groups( agents=split_value_affiliated_agents, - location_cls=location_cls, + designer=designer, ) else: group_lists = self._get_melted_groups( agents=split_value_affiliated_agents, - location_cls=location_cls, + designer=designer, ) # for each group of agents for i, group_list in enumerate(group_lists): group_count += 1 - dummy_location = self._create_dummy_location(location_cls) + dummy_location = self._create_dummy_location(designer) dummy_location.agents_ = group_list - # dummy_location.add_agents(agents) - - # dummy_location.group_agents = group_list # get all subgroub values subsplit_values = { @@ -675,8 +755,33 @@ def melt(self): if subsplit_value in agent_subsplit_value: subsplit_affiliated_agents.append(agent) + # inspect the defined magic location class get all methods/attributes + # that are not part of magic location class + keep_attrs = {} + for attr in dir(designer): + if attr not in p2n.LocationDesigner.__dict__: + keep_attrs[attr] = getattr(designer, attr) + # Build the final location - location = location_cls(model=self.model) + if designer.location_class is None: + location = type( + "Location", + (p2n.Location,), + keep_attrs, + )(model=self.model) + + else: + location = type( + utils._get_cls_as_str(designer.location_class), + (designer.location_class,), + keep_attrs, + )(model=self.model) + + location.label = ( + designer.label + if designer.label is not None + else utils._get_cls_as_str(designer) + ) location.setup() location.split_value = split_value location.subsplit_value = subsplit_value @@ -701,18 +806,18 @@ def melt(self): ) group_info_str = f"gv={location.split_value},gid={location.group_id}" - setattr(agent, str_location_cls, group_info_str) - setattr(agent, str_location_cls + "_assigned", True) - setattr(agent, str_location_cls + "_id", group_count - 1) - setattr(agent, str_location_cls + "_position", group_list.index(agent)) + setattr(agent, label, group_info_str) + setattr(agent, label + "_assigned", True) + setattr(agent, label + "_id", group_count - 1) + setattr(agent, label + "_position", group_list.index(agent)) setattr( agent, - str_location_cls + "_head", + label + "_head", True if group_list.index(agent) == 0 else False, ) setattr( agent, - str_location_cls + "_tail", + label + "_tail", True if group_list.index(agent) == (len(group_list) - 1) else False, ) @@ -726,7 +831,7 @@ def melt(self): for _ in range( int(dummy_location.n_locations - len(split_value_locations)) ): - location = location_cls(model=self.model) + location = designer(model=self.model) location.setup() location.split_value = split_value location.subsplit_value = None @@ -737,39 +842,16 @@ def melt(self): locations = p2n.LocationList(model=self.model, objs=locations) - # execute an action after all locations have been created - for location in locations: - location.refine() - # delete temporary agent attributes for agent in self._dummy_model.agents: for attr in self._temp_agent_attrs: if hasattr(agent, attr): delattr(agent, attr) - # delete magic location attributes - magic_location_attributes = [ - "filter", - "setup", - "bridge", - "split", - "weight", - "stick_together", - "nest", - "melt", - "refine", - ] - # TODO: delete magic location attributes - if False: # delete_magic_location_attributes: - for cls in location_classes: - del cls.stick_together - del cls.setup - magic_agent_attributes = set(magic_agent_attributes) if delete_magic_agent_attributes: for attr in magic_agent_attributes: for agent in agents: - # if hasattr(agent, attr): delattr(agent, attr) return locations @@ -777,7 +859,7 @@ def melt(self): def create( self, df: pd.DataFrame, - location_classes: list, + location_designers: list, agent_class: type[p2n.Agent] = p2n.Agent, agent_class_attr: None | str = None, agent_class_dict: None | dict = None, @@ -797,7 +879,7 @@ def create( the creation of agents. Each row is (potentially) translated into one agent. Each column is translated into one agent attribute. agent_class (type[p2n.Agent]): The class from which the agent instances are created. - location_classes (list): A list of classes from which the location instances are + location_designers (list): A list of classes from which the location instances are created. n_agents (Optional[int], optional): The number of agents that will be created. If `n_agents` is set to None, each row of `df` is translated into exactly one agent. @@ -842,7 +924,7 @@ def create( # create locations locations = self.create_locations( agents=agents, - location_classes=location_classes, + location_designers=location_designers, clear=clear, delete_magic_agent_attributes=delete_magic_agent_attributes, ) diff --git a/src/pop2net/location.py b/src/pop2net/location.py index 447bb99..db83edd 100644 --- a/src/pop2net/location.py +++ b/src/pop2net/location.py @@ -4,9 +4,6 @@ from agentpy.objects import Object from agentpy.sequences import AgentList -import networkx as nx - -import pop2net.utils as utils from . import agent as _agent from . import model as _model @@ -15,6 +12,8 @@ class Location(Object): """Base class for location objects.""" + label: str | None = None + def __init__(self, model: _model.Model) -> None: """Location constructor. @@ -24,6 +23,7 @@ def __init__(self, model: _model.Model) -> None: super().__init__(model) self.model = model self.model.add_location(self) + self.label = self.__class__.__name__ if self.label is None else self.label @property def agents(self) -> AgentList: @@ -146,199 +146,3 @@ def project_weights(self, agent1: _agent.Agent, agent2: _agent.Agent) -> float: Combined edge weight. """ return min([self.get_weight(agent1), self.get_weight(agent2)]) - - -class MagicLocation(Location): - """Helper class to create locations from inside the Creator.""" - - n_agents: int | None = None - overcrowding: bool = None - only_exact_n_agents: bool = False - n_locations: int | None = None - static_weight: bool = False - recycle: bool = True - nxgraph: nx.Graph | None = None - - def __init__(self, model: _model.Model) -> None: - """Create a helper class to create locations. - - Args: - model (_model.Model): The model. - """ - super().__init__(model) - self.group_id: int | None = None - self.subgroup_id: int | None = None - self.group_value: int | str | None = None - self.subgroup_value: int | str | None = None - - def setup(self) -> None: - """Use this method to set instance attributes, for instance. - - This method is called automatically by the creator after creating an instance. - """ - - def filter(self, agent: _agent.Agent) -> bool: # noqa: ARG002 - """Check whether the agent is meant to join this type of location. - - This is a boilerplate implementation of this method which always returns True; i.e. all - agents will always be allowed at this location. Override this method in your own - implementations as you seem fit. - - Args: - agent: The agent that is currently processed by the Creator. - - Returns: - True if the agent is allowed to join the location, False otherwise. - """ - return True - - def bridge(self, agent: _agent.Agent) -> float | str | list | None: # noqa: ARG002 - """Create locations with one agent for each unique value returned. - - Cannot be used in combination with melt(). - - Args: - agent (_agent.Agent): The agent that is currently processed by the Creator. - - Returns: - float | str | list | None: - The value which is used to assign agents to location instances. - """ - return None - - def split(self, agent: _agent.Agent) -> float | str | list | None: # noqa: ARG002 - """Creates seperate location instances for each unique returned value. - - Args: - agent: The agent that is currently processed by the Creator. - - Returns: - float | str | list | None: - The value(s) that determine(s) to which location instance the agent is assigned. - """ - return None - - def stick_together(self, agent: _agent.Agent) -> float | str: - """Assigns agents with a shared value on an attribute to the same location instance. - - Args: - agent (_agent.Agent): The agent that is currently processed by the Creator. - - Returns: - float | str: A value that defines the groups of agents. - """ - return agent.id - - def nest(self) -> type[Location] | None: - """Nests this location class into another location class. - - Ensures that the agents assigned to the same instance of this location class - are also assigned to the same instance of the returned location class. - - Returns: - type[Location] | None: The location class in which this location class should be nested. - """ - return None - - def melt(self) -> list[Location] | tuple[Location]: - """Allows to assign agents with different attribute values to the same location. - - Merges the agents assigned to the instances of the returned location classes - into one instance of this location class. - - Returns: - None | list | tuple: A list or tuple of location classes. - """ - return [] - - def refine(self): - """An action that is performed after all location instances have been created.""" - pass - - def _subsplit(self, agent: _agent.Agent) -> str | float | list | None: # noqa: ARG002 - """Splits a location instance into sub-instances to create a certain network structure. - - Args: - agent (_agent.Agent): The agent that is currently processed by the Creator. - - Returns: - str | float | None: A value or a list of values that represent specific sub-instances. - """ - if self.nxgraph is None: - return None - else: - node_indices = list(self.nxgraph.nodes) - agent_pos = self.agents_.index(agent) - - if agent_pos <= len(node_indices) - 1: - node_index = node_indices[agent_pos] - - return [ - utils._join_positions(pos1=node_index, pos2=neighbor) - for neighbor in self.nxgraph.neighbors(node_index) - ] - - else: - return None - - -class MeltLocation(Location): - """Helper class to melt locations.""" - - n_agents: int | None = None - overcrowding: bool | None = None - only_exact_n_agents: bool = False - n_locations: int | None = None - - def filter(self, agent: _agent.Agent) -> bool: # noqa: ARG002 - """Check whether the agent is meant to join this type of location. - - This is a boilerplate implementation of this method which always returns True; i.e. all - agents will always be allowed at this location. Override this method in your own - implementations as you seem fit. - - Args: - agent: The agent that is currently processed by the Creator. - - Returns: - True if the agent is allowed to join the location, False otherwise. - """ - return True - - def stick_together(self, agent: _agent.Agent) -> float | str: - """Assigns agents with a shared value on an attribute to the same location instance. - - Args: - agent (_agent.Agent): The agent that is currently processed by the Creator. - - Returns: - float | str: A value that defines the groups of agents. - """ - return agent.id - - def split(self, agent: _agent.Agent) -> float | str | list | None: # noqa: ARG002 - """Creates seperate location instances for each unique returned value. - - Args: - agent: The agent that is currently processed by the Creator. - - Returns: - float | str | list | None: The value(s) that determine(s) to which location instance - the agent is assigned. - """ - return None - - def weight(self, agent: _agent.Agent) -> float | None: # noqa: ARG002 - """Defines the edge weight between the agent and the location instance. - - Defines how the edge weight between an agent and the location is determined. - This is a boilerplate implementation of this method which always returns 1; i.e. all - edge weights will be 1. Override this method in your own implementations as you seem fit. - - Args: - agent: The agent that is currently processed by the Creator. - - Returns: - The edge weight. - """ - return None diff --git a/src/pop2net/location_designer.py b/src/pop2net/location_designer.py new file mode 100644 index 0000000..543a08e --- /dev/null +++ b/src/pop2net/location_designer.py @@ -0,0 +1,221 @@ +from __future__ import annotations + +import networkx as nx + +from pop2net.location import Location +import pop2net.utils as utils + +from . import agent as _agent +from . import model as _model + + +class LocationDesigner(Location): + """Helper class to create locations from inside the Creator.""" + + label: str | None = None + location_class: type | None = None + location_name: str | None = None + + n_agents: int | None = None + overcrowding: bool = None + only_exact_n_agents: bool = False + n_locations: int | None = None + static_weight: bool = False + recycle: bool = True + nxgraph: nx.Graph | None = None + + def __init__(self, model: _model.Model) -> None: + """Create a helper class to create locations. + + Args: + model (_model.Model): The model. + """ + super().__init__(model) + self.group_id: int | None = None + self.subgroup_id: int | None = None + self.group_value: int | str | None = None + self.subgroup_value: int | str | None = None + + def setup(self) -> None: + """Use this method to set instance attributes, for instance. + + This method is called automatically by the creator after creating an instance. + """ + + def filter(self, agent: _agent.Agent) -> bool: # noqa: ARG002 + """Check whether the agent is meant to join this type of location. + + This is a boilerplate implementation of this method which always returns True; i.e. all + agents will always be allowed at this location. Override this method in your own + implementations as you seem fit. + + Args: + agent: The agent that is currently processed by the Creator. + + Returns: + True if the agent is allowed to join the location, False otherwise. + """ + return True + + def bridge(self, agent: _agent.Agent) -> float | str | list | None: # noqa: ARG002 + """Create locations with one agent for each unique value returned. + + Cannot be used in combination with melt(). + + Args: + agent (_agent.Agent): The agent that is currently processed by the Creator. + + Returns: + float | str | list | None: + The value which is used to assign agents to location instances. + """ + return None + + def split(self, agent: _agent.Agent) -> float | str | list | None: # noqa: ARG002 + """Creates seperate location instances for each unique returned value. + + Args: + agent: The agent that is currently processed by the Creator. + + Returns: + float | str | list | None: + The value(s) that determine(s) to which location instance the agent is assigned. + """ + return None + + def stick_together(self, agent: _agent.Agent) -> float | str: + """Assigns agents with a shared value on an attribute to the same location instance. + + Args: + agent (_agent.Agent): The agent that is currently processed by the Creator. + + Returns: + float | str: A value that defines the groups of agents. + """ + return agent.id + + def nest(self) -> type[Location] | None: + """Nests this location class into another location class. + + Ensures that the agents assigned to the same instance of this location class + are also assigned to the same instance of the returned location class. + + Returns: + type[Location] | None: The location class in which this location class should be nested. + """ + return None + + def melt(self) -> list[Location] | tuple[Location]: + """Allows to assign agents with different attribute values to the same location. + + Merges the agents assigned to the instances of the returned location classes + into one instance of this location class. + + Returns: + None | list | tuple: A list or tuple of location classes. + """ + return [] + + def refine(self): + """An action that is performed after all location instances have been created.""" + pass + + def _subsplit(self, agent: _agent.Agent) -> str | float | list | None: # noqa: ARG002 + """Splits a location instance into sub-instances to create a certain network structure. + + Args: + agent (_agent.Agent): The agent that is currently processed by the Creator. + + Returns: + str | float | None: A value or a list of values that represent specific sub-instances. + """ + if self.nxgraph is None: + return None + else: + node_indices = list(self.nxgraph.nodes) + agent_pos = self.agents_.index(agent) + + if agent_pos <= len(node_indices) - 1: + node_index = node_indices[agent_pos] + + return [ + utils._join_positions(pos1=node_index, pos2=neighbor) + for neighbor in self.nxgraph.neighbors(node_index) + ] + + else: + return None + + def mutate(self) -> None | dict[str:list]: + """Creates new versions of this location designer with different attributes. + + Returns: + dict: A dictionary that specifies the values for each mutation. + """ + return None + + +class MeltLocationDesigner(Location): + """Helper class to melt locations.""" + + label: str | None = None + + location_class: type | None = None + location_name: str | None = None + n_agents: int | None = None + overcrowding: bool | None = None + only_exact_n_agents: bool = False + n_locations: int | None = None + + def filter(self, agent: _agent.Agent) -> bool: # noqa: ARG002 + """Check whether the agent is meant to join this type of location. + + This is a boilerplate implementation of this method which always returns True; i.e. all + agents will always be allowed at this location. Override this method in your own + implementations as you seem fit. + + Args: + agent: The agent that is currently processed by the Creator. + + Returns: + True if the agent is allowed to join the location, False otherwise. + """ + return True + + def stick_together(self, agent: _agent.Agent) -> float | str: + """Assigns agents with a shared value on an attribute to the same location instance. + + Args: + agent (_agent.Agent): The agent that is currently processed by the Creator. + + Returns: + float | str: A value that defines the groups of agents. + """ + return agent.id + + def split(self, agent: _agent.Agent) -> float | str | list | None: # noqa: ARG002 + """Creates seperate location instances for each unique returned value. + + Args: + agent: The agent that is currently processed by the Creator. + + Returns: + float | str | list | None: The value(s) that determine(s) to which location instance + the agent is assigned. + """ + return None + + def weight(self, agent: _agent.Agent) -> float | None: # noqa: ARG002 + """Defines the edge weight between the agent and the location instance. + + Defines how the edge weight between an agent and the location is determined. + This is a boilerplate implementation of this method which always returns 1; i.e. all + edge weights will be 1. Override this method in your own implementations as you seem fit. + + Args: + agent: The agent that is currently processed by the Creator. + + Returns: + The edge weight. + """ + return None diff --git a/src/pop2net/model.py b/src/pop2net/model.py index 6e15192..5fc4407 100644 --- a/src/pop2net/model.py +++ b/src/pop2net/model.py @@ -15,7 +15,6 @@ from . import location as _location from pop2net.sequences import LocationList -import pop2net.utils as utils class Model(ap.Model): @@ -261,30 +260,25 @@ def locations_of_agent(self, agent: _agent.Agent) -> LocationList: def neighbors_of_agent( self, agent: _agent.Agent, - location_classes: list | None = None, + location_labels: list | None = None, ) -> AgentList: """Return a list of neighboring agents for a specific agent. - The locations to be considered can be defined with location_classes. + The locations to be considered can be defined with location_labels. Args: agent: Agent of whom the neighbors are to be returned. - location_classes: A list of location_classes. + location_labels: A list of location_labels. Returns: The list of neighbors for the specified agent. """ - if location_classes: - location_classes = [ - (utils._get_cls_as_str(cls) if not isinstance(cls, str) else cls) - for cls in location_classes - ] - + if location_labels: locations = ( node for node in self.g.neighbors(agent.id) if self.g.nodes[node]["bipartite"] == 1 - and self.g.nodes[node]["_obj"].type in location_classes + and self.g.nodes[node]["_obj"].label in location_labels ) else: locations = ( @@ -306,8 +300,7 @@ def neighbors_of_agent( ), ) - # TODO: evlt. filtern nach Klasse oder Key einbauen - def _objects_between_objects(self, object1, object2, object_classes: list | None = None): + def _objects_between_objects(self, object1, object2) -> list: paths = list( nx.all_simple_paths( G=self.g, @@ -316,57 +309,52 @@ def _objects_between_objects(self, object1, object2, object_classes: list | None cutoff=2, ), ) + return [self.g.nodes[path[1]]["_obj"] for path in paths] - objects_between = [self.g.nodes[path[1]]["_obj"] for path in paths] - - if object_classes is not None: - if len(object_classes) < 1: - # TODO - raise Exception - - object_classes = [ - (utils._get_cls_as_str(cls) if not isinstance(cls, str) else cls) - for cls in object_classes - ] - filtered_objects_between = [o for o in objects_between if o.type in object_classes] - return filtered_objects_between - else: - return objects_between - - def locations_between_agents(self, agent1, agent2, location_classes: list | None = None): + def locations_between_agents(self, agent1, agent2, location_labels: list[str] | None = None): """Return all locations the connect two agents. Args: agent1 (Agent): Agent 1. agent2 (Agent): Agent 2. - location_classes (tuple, optional): Constrain the locations to the following types. - Defaults to (). + location_labels (tuple, optional): Constrain the locations to the following types. + Defaults to None. Returns: LocationList: A list of locations. """ - return LocationList( + locations = LocationList( model=self.model, - objs=self._objects_between_objects(agent1, agent2, location_classes), + objs=self._objects_between_objects(object1=agent1, object2=agent2), ) - def agents_between_locations(self, location1, location2, agent_classes: list | None = None): + if location_labels is not None: + locations = [location for location in locations if location.label in location_labels] + + return locations + + def agents_between_locations(self, location1, location2, agent_types: list[str] | None = None): """Return all agents between two locations. Args: location1 (Location): Location 1. location2 (Location): Location 2. - agent_classes (tuple, optional): Constrain the agents to the following types. - Defaults to (). + agent_types (tuple, optional): Constrain the agents to the following types. + Defaults to None. Returns: AgentList: A list of agents. """ - return AgentList( + agents = AgentList( model=self.model, - objs=self._objects_between_objects(location1, location2, agent_classes), + objs=self._objects_between_objects(location1, location2), ) + if agent_types is not None: + agents = [agent for agent in agents if agent.type in agent_types] + + return agents + def set_weight(self, agent, location, weight: float | None = None) -> None: """Set the weight of an agent at a location. @@ -408,7 +396,7 @@ def connect_agents(self, agents: list, location_cls: type, weight: float | None def disconnect_agents( self, agents: list, - location_classes: list | None = None, + location_labels: list | None = None, remove_locations: bool = False, ): """Disconnects agents by removing them from shared locations. @@ -423,7 +411,7 @@ def disconnect_agents( Args: agents (list): A list of agents. - location_classes (list | None, optional): A list of location types to specify which + location_labels (list | None, optional): A list of location types to specify which shared locations are considered. Defaults to None. remove_locations (bool, optional): A bool that determines whether the shared locations shall be removed from the model. Defaults to False. @@ -437,7 +425,7 @@ def disconnect_agents( self.locations_between_agents( agent1=agent1, agent2=agent2, - location_classes=location_classes, + location_labels=location_labels, ) ) @@ -524,21 +512,21 @@ def export_agent_network( return graph - def update_weights(self, location_classes: list | None = None) -> None: + def update_weights(self, location_labels: list | None = None) -> None: """Updates the edge weights between agents and locations. If you only want to update the weights of specific types of locations - specify those types in location_classes. + specify those types in location_labels. Args: - location_classes (list | None, optional): A list of location classes that specifiy for + location_labels (list | None, optional): A list of location classes that specifiy for which location types the weights should be updated. - If location_classes is None all locations are considered. Defaults to None. + If location_labels is None all locations are considered. Defaults to None. """ for location in ( self.locations - if location_classes is None - else [location for location in self.locations if type(location) in location_classes] + if location_labels is None + else [location for location in self.locations if location.label in location_labels] ): for agent in location.agents: location.set_weight(agent=agent, weight=location.weight(agent=agent)) diff --git a/src/pop2net/utils.py b/src/pop2net/utils.py index c4878c0..ff3c7de 100644 --- a/src/pop2net/utils.py +++ b/src/pop2net/utils.py @@ -79,6 +79,9 @@ def _to_list(x: object) -> list: def _get_cls_as_str(cls_): + # if isinstance(cls_, str): + # # if cls_ is a string + # return cls_ if inspect.isclass(cls_): # if cls_ is a class return cls_.__name__ diff --git a/tests/test_agent/test_agent.py b/tests/test_agent/test_agent.py index cf19d28..7c5bfb4 100644 --- a/tests/test_agent/test_agent.py +++ b/tests/test_agent/test_agent.py @@ -156,7 +156,7 @@ def end(self): def test_chef_agents(): - class Town(p2n.MagicLocation): + class Town(p2n.LocationDesigner): n_agents = 4 def stick_together(self, agent): @@ -165,7 +165,7 @@ def stick_together(self, agent): def assert_(self): assert len(self.agents) == 4 - class Home(p2n.MagicLocation): + class Home(p2n.LocationDesigner): def split(self, agent): return agent.couple @@ -175,7 +175,7 @@ def weight(self, agent): def assert_(self): assert len({a.couple for a in self.agents}) == 1 - class Restaurant(p2n.MagicLocation): + class Restaurant(p2n.LocationDesigner): def setup(self): chef = Chef(self.model) self.add_agent(chef) @@ -188,16 +188,16 @@ def split(self, agent): return agent.food def nest(self): - return Town + return "Town" def assert_(self): # assert that affiliated agents are affiliated with the same Town assert ( len( { - agent.locations.select(agent.locations.type == "Town")[0] + agent.locations.select(agent.locations.label == "Town")[0] for agent in self.agents - if isinstance(agent, MyAgent) # Chef-agents are not affiliated with Towns + if agent.type == "MyAgent" # Chef-agents are not affiliated with Towns }, ) == 1 @@ -206,7 +206,7 @@ def assert_(self): class Chef(p2n.Agent): def assert_(self): assert len(self.locations) == 1 - assert self.locations[0].type == "Restaurant" + assert self.locations[0].label == "Restaurant" assert self.get_location_weight(self.locations[0]) == 8 assert ( len([1 for a in self.locations[0].neighbors(self) if self.get_agent_weight(a) != 2]) @@ -221,14 +221,30 @@ def assert_(self): if agent.couple == self.couple and agent is not self ][0] - assert self.neighbors(location_classes=[Home])[0] is couple_agent + assert self.neighbors(location_labels=["Home"])[0] is couple_agent assert self.get_agent_weight(couple_agent) == 12 + 1 - assert ( - self.locations.select(self.locations.type == "Town")[0] - is self.shared_locations(couple_agent, location_classes=[Town])[0] - ) + print(self.locations) + for location in self.locations: + print(location.label) + + print(self.shared_locations(couple_agent)) + for l in self.shared_locations(couple_agent): + print(l.label) + + print([location for location in self.locations if location.label == "Town"]) + print(self.shared_locations(couple_agent, location_labels=["Town"])) + + for location in self.locations: + print(location.label, location.id) + + for location in couple_agent.locations: + print(location.label, location.id) + + assert [location for location in self.locations if location.label == "Town"][ + 0 + ] is self.shared_locations(couple_agent, location_labels=["Town"])[0] df = pd.DataFrame( { @@ -245,7 +261,7 @@ def assert_(self): creator.create_agents(df=df, agent_class=MyAgent) creator.create_locations( - location_classes=[ + location_designers=[ Town, Home, Restaurant, @@ -279,11 +295,11 @@ def test_table_agents(): creator.create_agents(df=df) - class Table(p2n.MagicLocation): + class Table(p2n.LocationDesigner): recycle = True def melt(self): - class PizzaGroup(p2n.MagicLocation): + class PizzaGroup(p2n.LocationDesigner): n_agents = 3 only_exact_n_agents = False @@ -296,7 +312,7 @@ def filter(self, agent): def weight(self, agent): return 10 - class PastaGroup(p2n.MagicLocation): + class PastaGroup(p2n.LocationDesigner): n_agents = 2 only_exact_n_agents = False @@ -306,12 +322,12 @@ def filter(self, agent): return PizzaGroup, PastaGroup def nest(self): - return Restaurant + return "Restaurant" def weight(self, agent): return 5 - class Restaurant(p2n.MagicLocation): + class Restaurant(p2n.LocationDesigner): n_agents = 10 # def stick_together(self, agent): @@ -321,7 +337,7 @@ class Restaurant(p2n.MagicLocation): # return agent.Table creator.create_locations( - location_classes=[ + location_designers=[ Restaurant, Table, ], diff --git a/tests/test_agent/test_agent_connect_and_disconnect.py b/tests/test_agent/test_agent_connect_and_disconnect.py index 7c79748..1c8de39 100644 --- a/tests/test_agent/test_agent_connect_and_disconnect.py +++ b/tests/test_agent/test_agent_connect_and_disconnect.py @@ -39,7 +39,7 @@ class School(p2n.Location): agent1.disconnect( agent2, - location_classes=None, + location_labels=None, remove_locations=False, remove_neighbor=True, remove_self=True, @@ -70,7 +70,7 @@ class School(p2n.Location): agent1.disconnect( agent2, - location_classes=None, + location_labels=None, remove_locations=False, remove_neighbor=True, remove_self=True, @@ -92,7 +92,7 @@ class School(p2n.Location): agent2.disconnect( agent3, - location_classes=None, + location_labels=None, remove_locations=False, remove_neighbor=True, remove_self=False, @@ -137,7 +137,7 @@ class School(p2n.Location): agent1.disconnect( agent2, - location_classes=[Home], + location_labels=["Home"], remove_locations=True, remove_neighbor=True, remove_self=True, @@ -155,7 +155,7 @@ class School(p2n.Location): agent1.disconnect( agent2, - location_classes=[School], + location_labels=["School"], remove_locations=False, remove_neighbor=False, remove_self=True, diff --git a/tests/test_agent/test_agent_neighbors.py b/tests/test_agent/test_agent_neighbors.py index fac97ee..35564e9 100644 --- a/tests/test_agent/test_agent_neighbors.py +++ b/tests/test_agent/test_agent_neighbors.py @@ -29,7 +29,7 @@ class Marius(p2n.Agent): class Lukas(p2n.Agent): pass - class WebexMeeting(p2n.MagicLocation): + class WebexMeeting(p2n.LocationDesigner): pass model = p2n.Model() @@ -66,13 +66,13 @@ class Marius(p2n.Agent): class Lukas(p2n.Agent): pass - class WebexMeeting(p2n.MagicLocation): + class WebexMeeting(p2n.LocationDesigner): pass _max = creator.create_agents(agent_class=Max, n=1)[0] _marius = creator.create_agents(agent_class=Marius, n=1)[0] _lukas = creator.create_agents(agent_class=Lukas, n=1)[0] - creator.create_locations(location_classes=[WebexMeeting]) + creator.create_locations(location_designers=[WebexMeeting]) assert len(model.locations) == 1 assert len(model.agents) == 3 @@ -97,10 +97,10 @@ class Marius(p2n.Agent): class Lukas(p2n.Agent): pass - class Meeting1(p2n.MagicLocation): + class Meeting1(p2n.Location): pass - class Meeting2(p2n.MagicLocation): + class Meeting2(p2n.Location): pass model = p2n.Model() @@ -115,12 +115,12 @@ class Meeting2(p2n.MagicLocation): assert len(model.locations) == 2 assert len(model.agents) == 3 - assert agent_max.neighbors(location_classes=[Meeting1])[0].type == "Marius" + assert agent_max.neighbors(location_labels=["Meeting1"])[0].type == "Marius" - assert agent_marius.neighbors(location_classes=[Meeting1])[0].type == "Max" - assert agent_marius.neighbors(location_classes=[Meeting2])[0].type == "Lukas" + assert agent_marius.neighbors(location_labels=["Meeting1"])[0].type == "Max" + assert agent_marius.neighbors(location_labels=["Meeting2"])[0].type == "Lukas" - assert agent_lukas.neighbors(location_classes=[Meeting2])[0].type == "Marius" + assert agent_lukas.neighbors(location_labels=["Meeting2"])[0].type == "Marius" # two Locations @@ -137,25 +137,29 @@ class Marius(p2n.Agent): class Lukas(p2n.Agent): pass - class Meeting1(p2n.MagicLocation): + class Meeting1(p2n.LocationDesigner): + location_name = "Meeting1" + def filter(self, agent): return agent.type in ["Max", "Marius"] - class Meeting2(p2n.MagicLocation): + class Meeting2(p2n.LocationDesigner): + location_name = "Meeting2" + def filter(self, agent): return agent.type in ["Marius", "Lukas"] _max = creator.create_agents(agent_class=Max, n=1) _marius = creator.create_agents(agent_class=Marius, n=1) _lukas = creator.create_agents(agent_class=Lukas, n=1) - creator.create_locations(location_classes=[Meeting1, Meeting2]) + creator.create_locations(location_designers=[Meeting1, Meeting2]) assert len(model.locations) == 2 assert len(model.agents) == 3 - assert _max.neighbors(location_classes=[Meeting1])[0][0].type == "Marius" + assert _max.neighbors(location_labels=["Meeting1"])[0][0].type == "Marius" - assert _marius.neighbors(location_classes=[Meeting1])[0][0].type == "Max" - assert _marius.neighbors(location_classes=[Meeting2])[0][0].type == "Lukas" + assert _marius.neighbors(location_labels=["Meeting1"])[0][0].type == "Max" + assert _marius.neighbors(location_labels=["Meeting2"])[0][0].type == "Lukas" - assert _lukas.neighbors(location_classes=[Meeting2])[0][0].type == "Marius" + assert _lukas.neighbors(location_labels=["Meeting2"])[0][0].type == "Marius" diff --git a/tests/test_agent/test_agent_shared_locations.py b/tests/test_agent/test_agent_shared_locations.py index 9ce09cd..327ba79 100644 --- a/tests/test_agent/test_agent_shared_locations.py +++ b/tests/test_agent/test_agent_shared_locations.py @@ -11,10 +11,10 @@ class Marius(p2n.Agent): class Lukas(p2n.Agent): pass - class Meeting1(p2n.MagicLocation): + class Meeting1(p2n.LocationDesigner): pass - class Meeting2(p2n.MagicLocation): + class Meeting2(p2n.LocationDesigner): pass model = p2n.Model() @@ -29,13 +29,13 @@ class Meeting2(p2n.MagicLocation): assert len(model.locations) == 2 assert len(model.agents) == 3 - assert agent_max.shared_locations(agent=agent_marius)[0].type == "Meeting1" + assert agent_max.shared_locations(agent=agent_marius)[0].label == "Meeting1" assert not bool(agent_max.shared_locations(agent=agent_lukas)) - assert agent_marius.shared_locations(agent=agent_max)[0].type == "Meeting1" - assert agent_marius.shared_locations(agent=agent_lukas)[0].type == "Meeting2" + assert agent_marius.shared_locations(agent=agent_max)[0].label == "Meeting1" + assert agent_marius.shared_locations(agent=agent_lukas)[0].label == "Meeting2" - assert agent_lukas.shared_locations(agent=agent_marius)[0].type == "Meeting2" + assert agent_lukas.shared_locations(agent=agent_marius)[0].label == "Meeting2" assert not bool(agent_lukas.shared_locations(agent=agent_max)) @@ -52,27 +52,27 @@ class Marius(p2n.Agent): class Lukas(p2n.Agent): pass - class Meeting1(p2n.MagicLocation): + class Meeting1(p2n.LocationDesigner): def filter(self, agent): return agent.type in ["Max", "Marius"] - class Meeting2(p2n.MagicLocation): + class Meeting2(p2n.LocationDesigner): def filter(self, agent): return agent.type in ["Marius", "Lukas"] _max = creator.create_agents(agent_class=Max, n=1)[0] _marius = creator.create_agents(agent_class=Marius, n=1)[0] _lukas = creator.create_agents(agent_class=Lukas, n=1)[0] - creator.create_locations(location_classes=[Meeting1, Meeting2]) + creator.create_locations(location_designers=[Meeting1, Meeting2]) assert len(model.locations) == 2 assert len(model.agents) == 3 - assert _max.shared_locations(agent=_marius)[0].type == "Meeting1" + assert _max.shared_locations(agent=_marius)[0].label == "Meeting1" assert not bool(_max.shared_locations(agent=_lukas)) - assert _marius.shared_locations(agent=_max)[0].type == "Meeting1" - assert _marius.shared_locations(agent=_lukas)[0].type == "Meeting2" + assert _marius.shared_locations(agent=_max)[0].label == "Meeting1" + assert _marius.shared_locations(agent=_lukas)[0].label == "Meeting2" - assert _lukas.shared_locations(agent=_marius)[0].type == "Meeting2" + assert _lukas.shared_locations(agent=_marius)[0].label == "Meeting2" assert not bool(_lukas.shared_locations(agent=_max)) diff --git a/tests/test_creator/test_creator_create_clear.py b/tests/test_creator/test_creator_create_clear.py index d316b02..a224d50 100644 --- a/tests/test_creator/test_creator_create_clear.py +++ b/tests/test_creator/test_creator_create_clear.py @@ -24,21 +24,22 @@ def test_create_locations(): model = p2n.Model() creator = p2n.Creator(model=model) - class MyLocation(p2n.MagicLocation): + class MyLocationDesigner(p2n.LocationDesigner): + label = "MyLocation" n_locations = 5 creator.create_agents(n=10) - creator.create_locations(location_classes=[MyLocation], clear=False) + creator.create_locations(location_designers=[MyLocationDesigner], clear=False) assert len(model.agents) == 10 assert len(model.locations) == 5 - creator.create_locations(location_classes=[MyLocation], clear=False) + creator.create_locations(location_designers=[MyLocationDesigner], clear=False) assert len(model.agents) == 10 assert len(model.locations) == 10 - creator.create_locations(location_classes=[MyLocation], clear=True) + creator.create_locations(location_designers=[MyLocationDesigner], clear=True) assert len(model.agents) == 10 assert len(model.locations) == 5 @@ -50,13 +51,14 @@ def test_create(): model = p2n.Model() creator = p2n.Creator(model=model) - class MyLocation(p2n.MagicLocation): + class MyLocationDesigner(p2n.LocationDesigner): + label = "MyLocation" n_locations = 5 creator.create( n_agents=10, df=df, - location_classes=[MyLocation], + location_designers=[MyLocationDesigner], clear=False, ) @@ -66,7 +68,7 @@ class MyLocation(p2n.MagicLocation): creator.create( n_agents=10, df=df, - location_classes=[MyLocation], + location_designers=[MyLocationDesigner], clear=False, ) @@ -76,7 +78,7 @@ class MyLocation(p2n.MagicLocation): creator.create( n_agents=10, df=df, - location_classes=[MyLocation], + location_designers=[MyLocationDesigner], clear=True, ) diff --git a/tests/test_creator/test_creator_delete_magic_attrs.py b/tests/test_creator/test_creator_delete_magic_attrs.py index fa14d6c..65164db 100644 --- a/tests/test_creator/test_creator_delete_magic_attrs.py +++ b/tests/test_creator/test_creator_delete_magic_attrs.py @@ -17,16 +17,16 @@ def test_del_magic_agent_attrs1(magic_agent_attributes): model = p2n.Model() creator = p2n.Creator(model=model) - class Location1(p2n.MagicLocation): + class Location1(p2n.LocationDesigner): pass - class Location2(p2n.MagicLocation): + class Location2(p2n.LocationDesigner): pass # First test: Do NOT delete magic agent attributes creator.create_agents(n=10) creator.create_locations( - location_classes=[Location1, Location2], + location_designers=[Location1, Location2], delete_magic_agent_attributes=False, ) @@ -37,7 +37,7 @@ class Location2(p2n.MagicLocation): # Second test: DELETE magic agent attributes creator.create_agents(n=10, clear=True) creator.create_locations( - location_classes=[Location1, Location2], + location_designers=[Location1, Location2], delete_magic_agent_attributes=True, clear=True, ) @@ -53,17 +53,17 @@ def test_del_magic_agent_attrs2(magic_agent_attributes): model = p2n.Model() creator = p2n.Creator(model=model) - class Location1(p2n.MagicLocation): + class Location1(p2n.LocationDesigner): pass - class Location2(p2n.MagicLocation): + class Location2(p2n.LocationDesigner): pass # First test: Do NOT delete magic agent attributes creator.create( df=df, n_agents=10, - location_classes=[Location1, Location2], + location_designers=[Location1, Location2], delete_magic_agent_attributes=False, ) @@ -75,7 +75,7 @@ class Location2(p2n.MagicLocation): creator.create( df=df, n_agents=10, - location_classes=[Location1, Location2], + location_designers=[Location1, Location2], delete_magic_agent_attributes=True, clear=True, ) diff --git a/tests/test_creator/test_creator_get_affiliated_agents.py b/tests/test_creator/test_creator_get_affiliated_agents.py index 2fb51a5..1283006 100644 --- a/tests/test_creator/test_creator_get_affiliated_agents.py +++ b/tests/test_creator/test_creator_get_affiliated_agents.py @@ -13,7 +13,7 @@ def test_0(): agent = p2n.Agent(model=model) agent.gender = "m" - class School(p2n.MagicLocation): + class School(p2n.LocationDesigner): pass school = School(model=model) @@ -34,7 +34,7 @@ class School(p2n.MagicLocation): agent = p2n.Agent(model=model) agent.gender = "m" - class School(p2n.MagicLocation): + class School(p2n.LocationDesigner): def filter(self, agent): return agent.gender == "w" diff --git a/tests/test_creator/test_parameter_transfer.py b/tests/test_creator/test_parameter_transfer.py index 907a8fc..917b9e2 100644 --- a/tests/test_creator/test_parameter_transfer.py +++ b/tests/test_creator/test_parameter_transfer.py @@ -7,7 +7,7 @@ def test_p_transfer(): """Tests whether a MagicLocation can access the parameters p of the model when the Creator is working.""" - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): def __init__(self, model: p2n.Model) -> None: super().__init__(model) self.nxgraph = nx.cycle_graph(n=self.p["n_agents"]) @@ -16,7 +16,7 @@ class TestModel(p2n.Model): def setup(self): self.creator = p2n.Creator(model=self) self.creator.create_agents(n=self.p["n_agents"]) - self.creator.create_locations(location_classes=[TestLocation]) + self.creator.create_locations(location_designers=[TestLocation]) params = {"n_agents": 100} diff --git a/tests/test_creator/test_pop_maker.py b/tests/test_creator/test_pop_maker.py index c4f57c0..a53160d 100644 --- a/tests/test_creator/test_pop_maker.py +++ b/tests/test_creator/test_pop_maker.py @@ -69,7 +69,7 @@ def test_create_locations(): for agent in agents: model.env.add_agent(agent) - locations = creator.create_locations(agents=agents, location_classes=[Home, School]) + locations = creator.create_locations(agents=agents, location_designers=[Home, School]) for location in locations: model.env.add_location(location) @@ -79,7 +79,3 @@ def test_create_locations(): for location in locations: for agent in location.agents: assert location.group(agent) == location.group_id - - -if __name__ == "__main__": - test_create_locations() diff --git a/tests/test_creator/test_seperation_of_location_classes.py b/tests/test_creator/test_seperation_of_location_classes.py new file mode 100644 index 0000000..84eea6b --- /dev/null +++ b/tests/test_creator/test_seperation_of_location_classes.py @@ -0,0 +1,226 @@ +import pytest + +import pop2net as p2n + + +@pytest.fixture +def base_attrs(): + return [ + "add_agent", + "add_agents", + "agents", + "get_weight", + "id", + "log", + "model", + "neighbors", + "p", + "project_weights", + "record", + "remove_agent", + "remove_agents", + "set_weight", + "setup", + "type", + "vars", + "weight", + ] + + +@pytest.fixture +def magic_attrs(): + return [ + "split", + "nest", + "bridge", + "filter", + "location_class", + "melt", + "n_agents", + "n_locations", + "nxgraph", + "only_exact_n_agents", + "overcrowding", + "recycle", + "refine", + "static_weight", + "stick_together", + "_subsplit", + ] + + +def test_1(base_attrs, magic_attrs): + """Testcase: location_class == None & label == None.""" + + class MyLocation(p2n.LocationDesigner): + def custom_method1(self): + pass + + model = p2n.Model() + creator = p2n.Creator(model) + creator.create_agents(n=10) + creator.create_locations(location_designers=[MyLocation]) + location = model.locations[0] + + # check number of locations + assert len(model.locations) == 1 + + # test if the types are correct + assert location.type == "Location" + assert location.label == "MyLocation" + assert isinstance(location, p2n.Location) + assert not isinstance(location, MyLocation) + + # test if magic attributes are deleted + for attr in magic_attrs: + assert not hasattr(location, attr) + + # test if base attributes are still there + for attr in base_attrs: + assert hasattr(location, attr) + + # test if custom methods are still there + assert hasattr(location, "custom_method1") + + +def test_2(base_attrs, magic_attrs): + """Testcase: location_class == None & label != None.""" + + class MyLocation(p2n.LocationDesigner): + label = "MyLocationYo" + + def custom_method1(self): + pass + + model = p2n.Model() + creator = p2n.Creator(model) + creator.create_agents(n=10) + creator.create_locations(location_designers=[MyLocation]) + location = model.locations[0] + + # check number of locations + assert len(model.locations) == 1 + + # test if the types are correct + assert location.type == "Location" + assert location.label == "MyLocationYo" + assert isinstance(location, p2n.Location) + assert not isinstance(location, MyLocation) + + # test if magic attributes are deleted + for attr in magic_attrs: + assert not hasattr(location, attr) + + # test if base attributes are still there + for attr in base_attrs: + assert hasattr(location, attr) + + # test if custom methods are still there + assert hasattr(location, "custom_method1") + + +def test_3(base_attrs, magic_attrs): + """Testcase: location_class != None & label == None.""" + + class MyLocation(p2n.Location): + def custom_method2(self): + pass + + def weight(self, agent): + return "MyLocation" + + class MyLocationDesigner(p2n.LocationDesigner): + location_class = MyLocation + + def custom_method1(self): + pass + + def weight(self, agent): + return "MyLocationDesigner" + + model = p2n.Model() + creator = p2n.Creator(model) + creator.create_agents(n=10) + creator.create_locations(location_designers=[MyLocationDesigner]) + location = model.locations[0] + + # check number of locations + assert len(model.locations) == 1 + + # test if the types are correct + assert location.type == "MyLocation" + assert location.label == "MyLocationDesigner" + assert isinstance(location, p2n.Location) + assert isinstance(location, MyLocation) + assert not isinstance(location, p2n.LocationDesigner) + + # test if magic attributes are deleted + for attr in magic_attrs: + assert not hasattr(location, attr) + + # test if base attributes are still there + for attr in base_attrs: + assert hasattr(location, attr) + + # test if custom methods defined in MyLocationDesigner are still there + assert hasattr(location, "custom_method1") + + # test if custom methods defined in MyLocation are still there + assert hasattr(location, "custom_method2") + + # test if the baselocation weight method is overwritten by the magiclocation weight method + assert location.weight(None) == "MyLocationDesigner" + + +def test_4(base_attrs, magic_attrs): + """Testcase: location_class != None & label != None.""" + + class MyLocation(p2n.Location): + def custom_method2(self): + pass + + def weight(self, agent): + return "MyLocation" + + class MyLocationDesigner(p2n.LocationDesigner): + location_class = MyLocation + label = "BlaBla" + + def custom_method1(self): + pass + + def weight(self, agent): + return "MyLocationDesigner" + + model = p2n.Model() + creator = p2n.Creator(model) + creator.create_agents(n=10) + creator.create_locations(location_designers=[MyLocationDesigner]) + location = model.locations[0] + + # check number of locations + assert len(model.locations) == 1 + + # test if the types are correct + assert location.type == "MyLocation" + assert location.label == "BlaBla" + assert isinstance(location, p2n.Location) + assert isinstance(location, MyLocation) + assert not isinstance(location, p2n.LocationDesigner) + + # test if magic attributes are deleted + for attr in magic_attrs: + assert not hasattr(location, attr) + + # test if base attributes are still there + for attr in base_attrs: + assert hasattr(location, attr) + + # test if custom methods defined in MyLocationDesigner are still there + assert hasattr(location, "custom_method1") + + # test if custom methods defined in MyLocation are still there + assert hasattr(location, "custom_method2") + + # test if the baselocation weight method is overwritten by the magiclocation weight method + assert location.weight(None) == "MyLocationDesigner" diff --git a/tests/test_location/test_combinations/test_n_locations_split.py b/tests/test_location/test_combinations/test_n_locations_split.py deleted file mode 100644 index 639768b..0000000 --- a/tests/test_location/test_combinations/test_n_locations_split.py +++ /dev/null @@ -1,43 +0,0 @@ -import pandas as pd - -import pop2net as p2n - - -# TODO ist das so gewollt? n_locations macht drei leere Location-Objecte und dann -# generiert split die Locations mit den Agenten, aber auch nicht richtig: -# !Komisch ist, dass jeder Agent eine eigene Location zugewiesen bekommt! -def test_1(): - df = pd.DataFrame( - { - "status": ["A", "B", "B", "A", "B", "C"], - }, - ) - - model = p2n.Model() - creator = p2n.Creator(model) - - class TestLocation(p2n.MagicLocation): - n_locations = 3 - - def split(self, agent): - return agent.status - - creator.create_agents(df=df) - creator.create_locations(location_classes=[TestLocation]) - - inspector = p2n.NetworkInspector(model=model) - inspector.plot_bipartite_network() - inspector.plot_agent_network(agent_attrs=["status"]) - - # assert len(model.locations) == 3 - # assert len(model.agents) == 6 - # for location in model.locations: - # if location.agents[0].status == "A": - # assert len(location.agents) == 2 - # assert all(agent.status == "A" for agent in location.agents) - # if location.agents[0].status == "B": - # assert len(location.agents) == 3 - # assert all(agent.status == "B" for agent in location.agents) - # if location.agents[0].status == "C": - # assert len(location.agents) == 1 - # assert all(agent.status == "C" for agent in location.agents) diff --git a/tests/test_location/test_location.py b/tests/test_location/test_location.py index b04383f..c4fff45 100644 --- a/tests/test_location/test_location.py +++ b/tests/test_location/test_location.py @@ -65,11 +65,11 @@ def test_location_size(): # only_exact_n_agents_pizza_group, # only_exact_n_agents_pasta_group, # ): -# class Table(p2n.MagicLocation): +# class Table(p2n.LocationDesigner): # recycle = recycle_ # def melt(self): -# class PizzaGroup(p2n.MagicLocation): +# class PizzaGroup(p2n.LocationDesigner): # n_agents = size_pizza_group # only_exact_n_agents = only_exact_n_agents_pizza_group @@ -82,7 +82,7 @@ def test_location_size(): # def weight(self, agent): # return 10 -# class PastaGroup(p2n.MagicLocation): +# class PastaGroup(p2n.LocationDesigner): # n_agents = size_pasta_group # only_exact_n_agents = only_exact_n_agents_pasta_group diff --git a/tests/test_location/test_combinations/test_exact_n__agents_refine.py b/tests/test_location_designer/test_combinations/test_exact_n__agents_refine.py similarity index 94% rename from tests/test_location/test_combinations/test_exact_n__agents_refine.py rename to tests/test_location_designer/test_combinations/test_exact_n__agents_refine.py index f583093..81dbe67 100644 --- a/tests/test_location/test_combinations/test_exact_n__agents_refine.py +++ b/tests/test_location_designer/test_combinations/test_exact_n__agents_refine.py @@ -1,10 +1,10 @@ -# %% import pandas as pd +import pytest import pop2net as p2n -# %% +@pytest.mark.skip def test_1(): df = pd.DataFrame( { @@ -12,7 +12,7 @@ def test_1(): }, ) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_agents = 2 only_exact_n_agents = True diff --git a/tests/test_location/test_combinations/test_exact_n_agents_filter.py b/tests/test_location_designer/test_combinations/test_exact_n_agents_filter.py similarity index 71% rename from tests/test_location/test_combinations/test_exact_n_agents_filter.py rename to tests/test_location_designer/test_combinations/test_exact_n_agents_filter.py index 8b29f74..4324a54 100644 --- a/tests/test_location/test_combinations/test_exact_n_agents_filter.py +++ b/tests/test_location_designer/test_combinations/test_exact_n_agents_filter.py @@ -13,17 +13,14 @@ def test_1(): model = p2n.Model() creator = p2n.Creator(model=model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): only_exact_n_agents = False n_agents = 2 def filter(self, agent): return agent.status == "A" - creator.create(df=df, location_classes=[TestLocation]) - inspector = p2n.NetworkInspector(model=model) - inspector.plot_bipartite_network() - inspector.plot_agent_network(agent_attrs=["status"]) + creator.create(df=df, location_designers=[TestLocation]) assert len(model.agents) == 4 assert len(model.locations) == 2 @@ -36,17 +33,14 @@ def filter(self, agent): model = p2n.Model() creator = p2n.Creator(model=model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): only_exact_n_agents = True n_agents = 2 def filter(self, agent): return agent.status == "A" - creator.create(df=df, location_classes=[TestLocation]) - inspector = p2n.NetworkInspector(model=model) - inspector.plot_bipartite_network() - inspector.plot_agent_network(agent_attrs=["status"]) + creator.create(df=df, location_designers=[TestLocation]) assert len(model.agents) == 4 assert len(model.locations) == 1 diff --git a/tests/test_location/test_combinations/test_exact_n_agents_nest.py b/tests/test_location_designer/test_combinations/test_exact_n_agents_nest.py similarity index 80% rename from tests/test_location/test_combinations/test_exact_n_agents_nest.py rename to tests/test_location_designer/test_combinations/test_exact_n_agents_nest.py index c433795..7dc20e5 100644 --- a/tests/test_location/test_combinations/test_exact_n_agents_nest.py +++ b/tests/test_location_designer/test_combinations/test_exact_n_agents_nest.py @@ -8,17 +8,17 @@ def test_1(): model = p2n.Model() creator = p2n.Creator(model=model) - class Classroom(p2n.MagicLocation): + class Classroom(p2n.LocationDesigner): n_agents = 3 only_exact_n_agents = False def nest(self): return School - class School(p2n.MagicLocation): + class School(p2n.LocationDesigner): pass - creator.create(df=df, location_classes=[Classroom, School]) + creator.create(df=df, location_designers=[Classroom, School]) assert len(model.agents) == 5 assert len(model.locations) == 3 @@ -30,17 +30,17 @@ class School(p2n.MagicLocation): model = p2n.Model() creator = p2n.Creator(model=model) - class Classroom(p2n.MagicLocation): + class Classroom(p2n.LocationDesigner): n_agents = 3 only_exact_n_agents = True def nest(self): return School - class School(p2n.MagicLocation): + class School(p2n.LocationDesigner): pass - creator.create(df=df, location_classes=[Classroom, School]) + creator.create(df=df, location_designers=[Classroom, School]) inspector = p2n.NetworkInspector(model=model) inspector.plot_bipartite_network() inspector.plot_agent_network(agent_attrs=["status"]) @@ -56,18 +56,18 @@ def test_2(): model = p2n.Model() creator = p2n.Creator(model=model) - class Classroom(p2n.MagicLocation): + class Classroom(p2n.LocationDesigner): n_agents = 2 only_exact_n_agents = True def nest(self): return School - class School(p2n.MagicLocation): + class School(p2n.LocationDesigner): n_agents = 4 only_exact_n_agents = True - creator.create(df=df, location_classes=[Classroom, School]) + creator.create(df=df, location_designers=[Classroom, School]) inspector = p2n.NetworkInspector(model=model) inspector.plot_bipartite_network() inspector.plot_agent_network(agent_attrs=["status", "id"]) diff --git a/tests/test_location/test_combinations/test_exact_n_agents_split.py b/tests/test_location_designer/test_combinations/test_exact_n_agents_split.py similarity index 76% rename from tests/test_location/test_combinations/test_exact_n_agents_split.py rename to tests/test_location_designer/test_combinations/test_exact_n_agents_split.py index 1baa97a..e8caa16 100644 --- a/tests/test_location/test_combinations/test_exact_n_agents_split.py +++ b/tests/test_location_designer/test_combinations/test_exact_n_agents_split.py @@ -12,17 +12,14 @@ def test_1(): model = p2n.Model() creator = p2n.Creator(model=model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): only_exact_n_agents = False n_agents = 2 def split(self, agent): return agent.status - creator.create(df=df, location_classes=[TestLocation]) - inspector = p2n.NetworkInspector(model=model) - inspector.plot_bipartite_network() - inspector.plot_agent_network(agent_attrs=["status"]) + creator.create(df=df, location_designers=[TestLocation]) assert len(model.agents) == 6 assert len(model.locations) == 4 @@ -38,17 +35,14 @@ def split(self, agent): model = p2n.Model() creator = p2n.Creator(model=model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): only_exact_n_agents = True n_agents = 2 def split(self, agent): return agent.status - creator.create(df=df, location_classes=[TestLocation]) - inspector = p2n.NetworkInspector(model=model) - inspector.plot_bipartite_network() - inspector.plot_agent_network(agent_attrs=["status"]) + creator.create(df=df, location_designers=[TestLocation]) assert len(model.agents) == 6 assert len(model.locations) == 2 diff --git a/tests/test_location/test_combinations/test_exact_n_agents_weight.py b/tests/test_location_designer/test_combinations/test_exact_n_agents_weight.py similarity index 85% rename from tests/test_location/test_combinations/test_exact_n_agents_weight.py rename to tests/test_location_designer/test_combinations/test_exact_n_agents_weight.py index 48de8fd..2018708 100644 --- a/tests/test_location/test_combinations/test_exact_n_agents_weight.py +++ b/tests/test_location_designer/test_combinations/test_exact_n_agents_weight.py @@ -13,7 +13,7 @@ def test_1(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_agents = 2 only_exact_n_agents = True @@ -21,7 +21,7 @@ def weight(self, agent): return 1 creator.create_agents(df=df) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) assert len(model.locations) == 1 assert len(model.agents) == 3 diff --git a/tests/test_location/test_combinations/test_exct_n_agents_melt.py b/tests/test_location_designer/test_combinations/test_exct_n_agents_melt.py similarity index 82% rename from tests/test_location/test_combinations/test_exct_n_agents_melt.py rename to tests/test_location_designer/test_combinations/test_exct_n_agents_melt.py index c4cba2c..d541937 100644 --- a/tests/test_location/test_combinations/test_exct_n_agents_melt.py +++ b/tests/test_location_designer/test_combinations/test_exct_n_agents_melt.py @@ -17,29 +17,26 @@ def test_1(): model = p2n.Model() creator = p2n.Creator(model) - class LocA(p2n.MeltLocation): + class LocA(p2n.MeltLocationDesigner): n_agents = 2 only_exact_n_agents = False def filter(self, agent): return agent.status == "A" - class LocB(p2n.MeltLocation): + class LocB(p2n.MeltLocationDesigner): n_agents = 2 only_exact_n_agents = False def filter(self, agent): return agent.status == "B" - class LocAB(p2n.MagicLocation): + class LocAB(p2n.LocationDesigner): def melt(self): return LocA, LocB creator.create_agents(df=df) - creator.create_locations(location_classes=[LocAB]) - inspector = p2n.NetworkInspector(model) - inspector.plot_bipartite_network() - inspector.plot_agent_network(agent_attrs=["status"]) + creator.create_locations(location_designers=[LocAB]) assert len(model.agents) == 6 assert len(model.locations) == 2 @@ -52,21 +49,21 @@ def melt(self): model = p2n.Model() creator = p2n.Creator(model) - class LocA(p2n.MeltLocation): + class LocA(p2n.MeltLocationDesigner): n_agents = 2 only_exact_n_agents = True def filter(self, agent): return agent.status == "A" - class LocB(p2n.MeltLocation): + class LocB(p2n.MeltLocationDesigner): n_agents = 2 only_exact_n_agents = True def filter(self, agent): return agent.status == "B" - class LocAB(p2n.MagicLocation): + class LocAB(p2n.LocationDesigner): n_agents = 4 only_exact_n_agents = True @@ -74,7 +71,7 @@ def melt(self): return LocA, LocB creator.create_agents(df=df) - creator.create_locations(location_classes=[LocAB]) + creator.create_locations(location_designers=[LocAB]) inspector = p2n.NetworkInspector(model) inspector.plot_bipartite_network() inspector.plot_agent_network(agent_attrs=["status"]) diff --git a/tests/test_location/test_combinations/test_filter_melt.py b/tests/test_location_designer/test_combinations/test_filter_melt.py similarity index 80% rename from tests/test_location/test_combinations/test_filter_melt.py rename to tests/test_location_designer/test_combinations/test_filter_melt.py index f6cfffe..976bc2d 100644 --- a/tests/test_location/test_combinations/test_filter_melt.py +++ b/tests/test_location_designer/test_combinations/test_filter_melt.py @@ -12,20 +12,20 @@ def test_1(): } ) - class PupilHelper(p2n.MagicLocation): + class PupilHelper(p2n.MeltLocationDesigner): def filter(self, agent): return agent.status == "pupil" - class TeacherHelper(p2n.MagicLocation): + class TeacherHelper(p2n.MeltLocationDesigner): def filter(self, agent): return agent.status == "teacher" - class ClassRoom(p2n.MagicLocation): + class ClassRoom(p2n.LocationDesigner): def melt(self): return PupilHelper, TeacherHelper creator.create_agents(df=df) - creator.create_locations(location_classes=[ClassRoom]) + creator.create_locations(location_designers=[ClassRoom]) assert len(model.agents) == 5 assert len(model.locations) == 1 @@ -43,15 +43,15 @@ def test_2(): } ) - class PupilHelper(p2n.MagicLocation): + class PupilHelper(p2n.MeltLocationDesigner): def filter(self, agent): return agent.status == "pupil" - class TeacherHelper(p2n.MagicLocation): + class TeacherHelper(p2n.MeltLocationDesigner): def filter(self, agent): return agent.status == "teacher" - class ClassRoom(p2n.MagicLocation): + class ClassRoom(p2n.LocationDesigner): def filter(self, agent): return agent.classroom_id == 1 @@ -59,7 +59,7 @@ def melt(self): return PupilHelper, TeacherHelper creator.create_agents(df=df) - creator.create_locations(location_classes=[ClassRoom]) + creator.create_locations(location_designers=[ClassRoom]) assert len(model.agents) == 6 assert len(model.locations) == 1 diff --git a/tests/test_location/test_combinations/test_filter_nest.py b/tests/test_location_designer/test_combinations/test_filter_nest.py similarity index 76% rename from tests/test_location/test_combinations/test_filter_nest.py rename to tests/test_location_designer/test_combinations/test_filter_nest.py index e6c401c..e400c1e 100644 --- a/tests/test_location/test_combinations/test_filter_nest.py +++ b/tests/test_location_designer/test_combinations/test_filter_nest.py @@ -23,28 +23,25 @@ def test_1(): model = p2n.Model() creator = p2n.Creator(model=model) - class Classroom1(p2n.MagicLocation): + class Classroom1(p2n.LocationDesigner): def filter(self, agent): return agent.class_id == 1 def nest(self): return School - class Classroom2(p2n.MagicLocation): + class Classroom2(p2n.LocationDesigner): def filter(self, agent): return agent.class_id == 2 def nest(self): return School - class School(p2n.MagicLocation): + class School(p2n.LocationDesigner): def filter(self, agent): return agent.class_id == 1 or agent.class_id == 2 - creator.create(df=df, location_classes=[Classroom1, Classroom2, School]) - inspector = p2n.NetworkInspector(model=model) - inspector.plot_bipartite_network() - inspector.plot_agent_network(agent_attrs=["status", "class_id"]) + creator.create(df=df, location_designers=[Classroom1, Classroom2, School]) assert len(model.agents) == 9 assert len(model.locations) == 3 @@ -54,7 +51,6 @@ def filter(self, agent): assert all(not agent.locations for agent in model.agents if agent.class_id == 3) -# %% def test_2(): df = pd.DataFrame( { @@ -75,33 +71,29 @@ def test_2(): model = p2n.Model() creator = p2n.Creator(model=model) - class Classroom1(p2n.MagicLocation): + class Classroom1(p2n.LocationDesigner): def filter(self, agent): return agent.school_id == 1 def nest(self): return School1 - class Classroom2(p2n.MagicLocation): + class Classroom2(p2n.LocationDesigner): def filter(self, agent): return agent.school_id == 2 def nest(self): return School2 - class School1(p2n.MagicLocation): + class School1(p2n.LocationDesigner): def filter(self, agent): return agent.school_id == 1 - class School2(p2n.MagicLocation): + class School2(p2n.LocationDesigner): def filter(self, agent): return agent.school_id == 2 - creator.create(df=df, location_classes=[Classroom1, Classroom2, School1, School2]) - inspector = p2n.NetworkInspector(model=model) - inspector.plot_bipartite_network() - inspector.plot_agent_network(agent_attrs=["status", "school_id"]) - print(model.locations[3]) + creator.create(df=df, location_designers=[Classroom1, Classroom2, School1, School2]) assert len(model.agents) == 9 assert len(model.locations) == 4 diff --git a/tests/test_location/test_combinations/test_filter_refine.py b/tests/test_location_designer/test_combinations/test_filter_refine.py similarity index 91% rename from tests/test_location/test_combinations/test_filter_refine.py rename to tests/test_location_designer/test_combinations/test_filter_refine.py index 6d4c7e8..4379bd3 100644 --- a/tests/test_location/test_combinations/test_filter_refine.py +++ b/tests/test_location_designer/test_combinations/test_filter_refine.py @@ -1,8 +1,10 @@ import pandas as pd +import pytest import pop2net as p2n +@pytest.mark.skip def test_1(): df = pd.DataFrame( { @@ -14,7 +16,7 @@ def test_1(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): def filter(self, agent): return agent.status == "A" diff --git a/tests/test_location/test_combinations/test_filter_split.py b/tests/test_location_designer/test_combinations/test_filter_split.py similarity index 88% rename from tests/test_location/test_combinations/test_filter_split.py rename to tests/test_location_designer/test_combinations/test_filter_split.py index 169d9db..36e38e4 100644 --- a/tests/test_location/test_combinations/test_filter_split.py +++ b/tests/test_location_designer/test_combinations/test_filter_split.py @@ -14,14 +14,14 @@ def test_1(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocationA(p2n.MagicLocation): + class TestLocationA(p2n.LocationDesigner): def filter(self, agent): return agent.status == "A" def split(self, agent): return agent.sex - class TestLocationB(p2n.MagicLocation): + class TestLocationB(p2n.LocationDesigner): def filter(self, agent): return agent.status == "B" @@ -29,7 +29,7 @@ def split(self, agent): return agent.sex creator.create_agents(df=df) - creator.create_locations(location_classes=[TestLocationA, TestLocationB]) + creator.create_locations(location_designers=[TestLocationA, TestLocationB]) assert len(model.locations) == 4 assert len(model.agents) == 5 diff --git a/tests/test_location/test_combinations/test_filter_stick_together.py b/tests/test_location_designer/test_combinations/test_filter_stick_together.py similarity index 78% rename from tests/test_location/test_combinations/test_filter_stick_together.py rename to tests/test_location_designer/test_combinations/test_filter_stick_together.py index 78e7ef5..01c074b 100644 --- a/tests/test_location/test_combinations/test_filter_stick_together.py +++ b/tests/test_location_designer/test_combinations/test_filter_stick_together.py @@ -11,7 +11,7 @@ def test_1(): {"friend_group": [1, 2, 2, 3, 1, 3, 2], "filter_group": [1, 1, 2, 2, 1, 1, 2]} ) - class TestLocationA(p2n.MagicLocation): + class TestLocationA(p2n.LocationDesigner): n_agents = 2 def filter(self, agent): @@ -20,7 +20,7 @@ def filter(self, agent): def stick_together(self, agent): return agent.friend_group - class TestLocationB(p2n.MagicLocation): + class TestLocationB(p2n.LocationDesigner): n_agents = 2 def filter(self, agent): @@ -30,15 +30,12 @@ def stick_together(self, agent): return agent.friend_group creator.create_agents(df=df) - creator.create_locations(location_classes=[TestLocationA, TestLocationB]) - inspector = p2n.NetworkInspector(model=model) - inspector.plot_bipartite_network() - inspector.plot_agent_network(agent_attrs=["friend_group", "filter_group"]) + creator.create_locations(location_designers=[TestLocationA, TestLocationB]) assert len(model.locations) == 4 assert len(model.agents) == 7 - assert len([location for location in model.locations if location.type == "TestLocationA"]) == 2 - assert len([location for location in model.locations if location.type == "TestLocationB"]) == 2 + assert len([location for location in model.locations if location.label == "TestLocationA"]) == 2 + assert len([location for location in model.locations if location.label == "TestLocationB"]) == 2 assert len(model.locations[0].agents) == 2 assert all(agent.friend_group == 1 for agent in model.locations[0].agents) diff --git a/tests/test_location/test_combinations/test_filter_weight.py b/tests/test_location_designer/test_combinations/test_filter_weight.py similarity index 77% rename from tests/test_location/test_combinations/test_filter_weight.py rename to tests/test_location_designer/test_combinations/test_filter_weight.py index b2a3cab..8b1639b 100644 --- a/tests/test_location/test_combinations/test_filter_weight.py +++ b/tests/test_location_designer/test_combinations/test_filter_weight.py @@ -6,14 +6,14 @@ def test_1(): model = p2n.Model() creator = p2n.Creator(model=model) - inspector = p2n.NetworkInspector(model=model) + df = pd.DataFrame( { "status": ["A", "B", "A", "B", "A"], } ) - class ClassRoom(p2n.MagicLocation): + class ClassRoom(p2n.LocationDesigner): def filter(self, agent): return agent.status == "A" @@ -24,9 +24,7 @@ def weight(self, agent): return 1 creator.create_agents(df=df) - creator.create_locations(location_classes=[ClassRoom]) - inspector.plot_bipartite_network() - inspector.plot_agent_network(agent_attrs=["status"]) + creator.create_locations(location_designers=[ClassRoom]) assert len(model.locations) == 1 assert len(model.agents) == 5 diff --git a/tests/test_location/test_combinations/test_n_agents_filter.py b/tests/test_location_designer/test_combinations/test_n_agents_filter.py similarity index 85% rename from tests/test_location/test_combinations/test_n_agents_filter.py rename to tests/test_location_designer/test_combinations/test_n_agents_filter.py index 5c67e05..e7da0fc 100644 --- a/tests/test_location/test_combinations/test_n_agents_filter.py +++ b/tests/test_location_designer/test_combinations/test_n_agents_filter.py @@ -13,20 +13,20 @@ def test_1(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocationA(p2n.MagicLocation): + class TestLocationA(p2n.LocationDesigner): n_agents = 2 def filter(self, agent): return agent.status == "A" - class TestLocationB(p2n.MagicLocation): + class TestLocationB(p2n.LocationDesigner): n_agents = 2 def filter(self, agent): return agent.status == "B" creator.create_agents(df=df) - creator.create_locations(location_classes=[TestLocationA, TestLocationB]) + creator.create_locations(location_designers=[TestLocationA, TestLocationB]) assert len(model.locations) == 4 assert len(model.agents) == 7 diff --git a/tests/test_location/test_combinations/test_n_agents_melt.py b/tests/test_location_designer/test_combinations/test_n_agents_melt.py similarity index 74% rename from tests/test_location/test_combinations/test_n_agents_melt.py rename to tests/test_location_designer/test_combinations/test_n_agents_melt.py index 6ef14ad..3ce2dc3 100644 --- a/tests/test_location/test_combinations/test_n_agents_melt.py +++ b/tests/test_location_designer/test_combinations/test_n_agents_melt.py @@ -10,28 +10,26 @@ def test_1(): }, ) - class Teacher(p2n.MeltLocation): + class Teacher(p2n.MeltLocationDesigner): n_agents = 1 def filter(self, agent): return agent.status == "teacher" - class Pupils(p2n.MeltLocation): + class Pupils(p2n.MeltLocationDesigner): n_agents = 1 def filter(self, agent): return agent.status == "pupil" - class Classroom(p2n.MagicLocation): + class Classroom(p2n.LocationDesigner): def melt(self): return Teacher, Pupils model = p2n.Model() creator = p2n.Creator(model) creator.create_agents(df=df) - creator.create_locations(location_classes=[Classroom]) - inspector = p2n.NetworkInspector(model) - inspector.plot_bipartite_network() + creator.create_locations(location_designers=[Classroom]) assert len(model.agents) == 5 assert len(model.locations) == 3 @@ -48,19 +46,19 @@ def test_2(): }, ) - class Teacher(p2n.MeltLocation): + class Teacher(p2n.MeltLocationDesigner): n_agents = 1 def filter(self, agent): return agent.status == "teacher" - class Pupils(p2n.MeltLocation): + class Pupils(p2n.MeltLocationDesigner): n_agents = 2 def filter(self, agent): return agent.status == "pupil" - class Classroom(p2n.MagicLocation): + class Classroom(p2n.LocationDesigner): n_agents = 2 def melt(self): @@ -69,9 +67,8 @@ def melt(self): model = p2n.Model() creator = p2n.Creator(model) creator.create_agents(df=df) - creator.create_locations(location_classes=[Classroom]) - inspector = p2n.NetworkInspector(model) - inspector.plot_bipartite_network() + creator.create_locations(location_designers=[Classroom]) + assert len(model.agents) == 5 assert len(model.locations) == 2 diff --git a/tests/test_location/test_combinations/test_n_agents_nest.py b/tests/test_location_designer/test_combinations/test_n_agents_nest.py similarity index 70% rename from tests/test_location/test_combinations/test_n_agents_nest.py rename to tests/test_location_designer/test_combinations/test_n_agents_nest.py index 7ce350a..c6a3ffe 100644 --- a/tests/test_location/test_combinations/test_n_agents_nest.py +++ b/tests/test_location_designer/test_combinations/test_n_agents_nest.py @@ -12,10 +12,10 @@ def test_1(): } ) - class School(p2n.MagicLocation): + class School(p2n.LocationDesigner): n_agents = 2 - class Classroom(p2n.MagicLocation): + class Classroom(p2n.LocationDesigner): n_agents = 2 def nest(self): @@ -23,21 +23,21 @@ def nest(self): model = p2n.Model() creator = p2n.Creator(model=model) - creator.create(df=df, location_classes=[School, Classroom]) + creator.create(df=df, location_designers=[School, Classroom]) assert len(model.agents) == 4 assert len(model.locations) == 4 for location in model.locations: - if location.type == "School": + if location.label == "School": assert len(location.agents) == 2 - if location.type == "Classroom": + if location.label == "Classroom": assert len(location.agents) == 2 for agent in model.agents: assert ( - agent.neighbors(location_classes=[Classroom])[0] - is agent.neighbors(location_classes=[School])[0] + agent.neighbors(location_labels=["Classroom"])[0] + is agent.neighbors(location_labels=["School"])[0] ) inspector = p2n.NetworkInspector(model) @@ -53,10 +53,10 @@ def test_2(): } ) - class School(p2n.MagicLocation): + class School(p2n.LocationDesigner): n_agents = 4 - class Classroom(p2n.MagicLocation): + class Classroom(p2n.LocationDesigner): n_agents = 2 def split(self, agent): @@ -66,7 +66,7 @@ def split(self, agent): creator = p2n.Creator(model=model) creator.create( df=df, - location_classes=[School, Classroom], + location_designers=[School, Classroom], delete_magic_agent_attributes=False, ) @@ -74,7 +74,7 @@ def split(self, agent): assert len(model.locations) == 6 for location in model.locations: - if location.type == "School": + if location.label == "School": assert len(location.agents) == 4 counter = Counter([agent.group for agent in location.agents]) assert counter[1] == 2 @@ -83,30 +83,26 @@ def split(self, agent): assert not all( location.agents[0].School == location.agents[1].School for location in model.locations - if location.type == "Classroom" + if location.label == "Classroom" ) - inspector = p2n.NetworkInspector(model) - inspector.plot_bipartite_network() - inspector.plot_agent_network(agent_attrs=df.columns, agent_color="id") - - class School(p2n.MagicLocation): + class School(p2n.LocationDesigner): n_agents = 4 - class Classroom(p2n.MagicLocation): + class Classroom(p2n.LocationDesigner): n_agents = 2 def split(self, agent): return agent.group def nest(self): - return School + return "School" model = p2n.Model() creator = p2n.Creator(model=model) creator.create( df=df, - location_classes=[School, Classroom], + location_designers=[School, Classroom], delete_magic_agent_attributes=False, ) @@ -115,43 +111,39 @@ def nest(self): assert all( location.agents[0].School == location.agents[1].School for location in model.locations - if location.type == "Classroom" + if location.label == "Classroom" ) - inspector = p2n.NetworkInspector(model) - inspector.plot_bipartite_network() - inspector.plot_agent_network(agent_attrs=df.columns, agent_color="group") - for location in model.locations: - if location.type == "School": + if location.label == "School": assert len(location.agents) == 4 - if location.type == "Classroom": + if location.label == "Classroom": assert len(location.agents) == 2 for location in model.locations: - if location.type == "School": + if location.label == "School": assert len(location.agents) == 4 counter = Counter([agent.group for agent in location.agents]) assert counter[1] == 2 assert counter[2] == 2 assert any( - agent.neighbors(location_classes=[Classroom]) - not in agent.neighbors(location_classes=[School]) + agent.neighbors(location_labels=[Classroom]) + not in agent.neighbors(location_labels=[School]) for agent in model.agents ) for location in model.locations: - if location.type == "School": + if location.label == "School": for agent in location.agents: assert all(agent.School == nghbr.School for nghbr in agent.neighbors()) def test_3(): - class City(p2n.MagicLocation): + class City(p2n.LocationDesigner): n_agents = 4 - class Group(p2n.MagicLocation): + class Group(p2n.LocationDesigner): n_agents = 2 def split(self, agent): @@ -165,17 +157,17 @@ def split(self, agent): agent.group = i % 2 creator.create_locations( - location_classes=[City, Group], + location_designers=[City, Group], delete_magic_agent_attributes=False, ) - for location in model.locations.select(model.locations.type == "City"): + for location in model.locations.select(model.locations.label == "City"): assert int(location.agents[0].group) == 0 assert int(location.agents[1].group) == 1 assert int(location.agents[2].group) == 0 assert int(location.agents[3].group) == 1 - for location in model.locations.select(model.locations.type == "Group"): + for location in model.locations.select(model.locations.label == "Group"): assert location.agents[0].group == location.agents[1].group # not all members of the same group are also in the same city (which is not desired) @@ -190,17 +182,17 @@ def nest(self): model = p2n.Model() creator = p2n.Creator(model=model) creator.create_locations( - location_classes=[City, GroupNestedInCity], + location_designers=[City, GroupNestedInCity], delete_magic_agent_attributes=False, ) - for location in model.locations.select(model.locations.type == "City"): + for location in model.locations.select(model.locations.label == "City"): assert int(location.agents[0].group) == 0 assert int(location.agents[1].group) == 1 assert int(location.agents[2].group) == 0 assert int(location.agents[3].group) == 1 - for location in model.locations.select(model.locations.type == "Group"): + for location in model.locations.select(model.locations.label == "Group"): assert location.agents[0].group == location.agents[1].group # all members of a group are in the same city diff --git a/tests/test_location/test_combinations/test_n_agents_refine.py b/tests/test_location_designer/test_combinations/test_n_agents_refine.py similarity index 75% rename from tests/test_location/test_combinations/test_n_agents_refine.py rename to tests/test_location_designer/test_combinations/test_n_agents_refine.py index 149f582..9f69f78 100644 --- a/tests/test_location/test_combinations/test_n_agents_refine.py +++ b/tests/test_location_designer/test_combinations/test_n_agents_refine.py @@ -1,35 +1,16 @@ -# %% import pandas as pd +import pytest import pop2net as p2n -# %% -# TODO interessantes Case gefunden: -# Man kann also theoretisch keine leeren Locations damit erzeugen- gewollt? -# Error: "ZeroDivisionError: division by zero" -def n_agents_zero(): - df = pd.DataFrame({"_id": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}) - model = p2n.Model() - creator = p2n.Creator(model=model) - - class TestLocation(p2n.MagicLocation): - # TODO geht das? - n_agents = 0 - - creator.create(df=df, location_classes=[TestLocation]) - - -# n_agents_zero() - - -# %% +@pytest.mark.skip(reason="TODO") def test_1(): df = pd.DataFrame({"_id": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}) model = p2n.Model() creator = p2n.Creator(model=model) - class TestLocationRemoveAgent(p2n.MagicLocation): + class TestLocationRemoveAgent(p2n.LocationDesigner): n_agents = 2 def refine(self): @@ -38,7 +19,7 @@ def refine(self): print("Test refine 1") self.remove_agent(agent) - class TestLocationAddAgents(p2n.MagicLocation): + class TestLocationAddAgents(p2n.LocationDesigner): # workaround: no agents in this location at start def filter(self, agent): return agent._id == 0 @@ -63,7 +44,7 @@ def refine(self): if agent.locations: self.add_agent(agent) - creator.create(df=df, location_classes=[TestLocationRemoveAgent, TestLocationAddAgents]) + creator.create(df=df, location_designers=[TestLocationRemoveAgent, TestLocationAddAgents]) # inspector = p2n.NetworkInspector(model=model) # inspector.plot_bipartite_network() diff --git a/tests/test_location/test_combinations/test_n_agents_split.py b/tests/test_location_designer/test_combinations/test_n_agents_split.py similarity index 77% rename from tests/test_location/test_combinations/test_n_agents_split.py rename to tests/test_location_designer/test_combinations/test_n_agents_split.py index 62ff527..1545778 100644 --- a/tests/test_location/test_combinations/test_n_agents_split.py +++ b/tests/test_location_designer/test_combinations/test_n_agents_split.py @@ -13,14 +13,14 @@ def test_1(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_agents = 2 def split(self, agent): return agent.status creator.create_agents(df=df) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) assert len(model.locations) == 5 assert len(model.agents) == 10 @@ -33,9 +33,6 @@ def split(self, agent): assert all(agent.status == "B" for agent in location.agents) -# %% - - def test_2(): df = pd.DataFrame( { @@ -47,18 +44,15 @@ def test_2(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_agents = 1 def split(self, agent): return [agent.status, agent.sex] creator.create_agents(df=df) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) - inspector = p2n.NetworkInspector(model=model) - inspector.plot_bipartite_network() - inspector.plot_agent_network(agent_attrs=["status", "sex"]) assert len(model.locations) == 8 assert len(model.agents) == 4 assert len(model.locations[0].agents) == 1 @@ -71,9 +65,6 @@ def split(self, agent): assert len(model.locations[7].agents) == 1 -# %% - - def test_3(): df = pd.DataFrame( { @@ -85,24 +76,18 @@ def test_3(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_agents = 1 def split(self, agent): return str(agent.status) + str(agent.sex) creator.create_agents(df=df) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) - inspector = p2n.NetworkInspector(model=model) - inspector.plot_bipartite_network() - inspector.plot_agent_network(agent_attrs=["status", "sex"]) assert len(model.locations) == 4 assert len(model.agents) == 4 assert len(model.locations[0].agents) == 1 assert len(model.locations[1].agents) == 1 assert len(model.locations[2].agents) == 1 assert len(model.locations[3].agents) == 1 - - -# %% diff --git a/tests/test_location/test_combinations/test_n_agents_stick_together.py b/tests/test_location_designer/test_combinations/test_n_agents_stick_together.py similarity index 84% rename from tests/test_location/test_combinations/test_n_agents_stick_together.py rename to tests/test_location_designer/test_combinations/test_n_agents_stick_together.py index 95f6d7a..14d2cac 100644 --- a/tests/test_location/test_combinations/test_n_agents_stick_together.py +++ b/tests/test_location_designer/test_combinations/test_n_agents_stick_together.py @@ -6,7 +6,7 @@ def test_1(): df = pd.DataFrame({"status": ["pupil", "pupil", "pupil", "pupil"], "class_id": [1, 2, 1, 2]}) - class Classroom(p2n.MagicLocation): + class Classroom(p2n.LocationDesigner): n_agents = 2 def stick_together(self, agent): @@ -14,7 +14,7 @@ def stick_together(self, agent): model = p2n.Model() creator = p2n.Creator(model=model) - creator.create(df=df, location_classes=[Classroom]) + creator.create(df=df, location_designers=[Classroom]) assert len(model.agents) == 4 assert len(model.locations) == 2 @@ -23,7 +23,7 @@ def stick_together(self, agent): assert len(location.agents) == 2 for agent in model.agents: - assert agent.neighbors(location_classes=[Classroom])[0].class_id == agent.class_id + assert agent.neighbors(location_labels=["Classroom"])[0].class_id == agent.class_id inspector = p2n.NetworkInspector(model) inspector.plot_bipartite_network() @@ -33,7 +33,7 @@ def stick_together(self, agent): def test_2(): df = pd.DataFrame({"status": ["pupil", "pupil", "pupil", "pupil"], "class_id": [1, 1, 1, 1]}) - class Classroom(p2n.MagicLocation): + class Classroom(p2n.LocationDesigner): n_agents = 1 def stick_together(self, agent): @@ -42,7 +42,7 @@ def stick_together(self, agent): model = p2n.Model() creator = p2n.Creator(model=model) - creator.create(df=df, location_classes=[Classroom]) + creator.create(df=df, location_designers=[Classroom]) inspector = p2n.NetworkInspector(model) inspector.plot_bipartite_network() @@ -60,7 +60,7 @@ def test_3(): } ) - class Classroom(p2n.MagicLocation): + class Classroom(p2n.LocationDesigner): n_agents = 1 def stick_together(self, agent): @@ -69,7 +69,7 @@ def stick_together(self, agent): model = p2n.Model() creator = p2n.Creator(model=model) - creator.create(df=df, location_classes=[Classroom]) + creator.create(df=df, location_designers=[Classroom]) inspector = p2n.NetworkInspector(model) inspector.plot_bipartite_network() diff --git a/tests/test_location/test_combinations/test_n_agents_weight.py b/tests/test_location_designer/test_combinations/test_n_agents_weight.py similarity index 88% rename from tests/test_location/test_combinations/test_n_agents_weight.py rename to tests/test_location_designer/test_combinations/test_n_agents_weight.py index 425ff9e..7d4bb3a 100644 --- a/tests/test_location/test_combinations/test_n_agents_weight.py +++ b/tests/test_location_designer/test_combinations/test_n_agents_weight.py @@ -15,14 +15,14 @@ def test_1(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_agents = 2 def weight(self, agent): return 1 creator.create_agents(df=df) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) assert len(model.locations) == 3 assert len(model.agents) == 6 @@ -43,7 +43,7 @@ def test_2(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_agents = 2 def weight(self, agent): @@ -55,7 +55,7 @@ def weight(self, agent): return 3 creator.create_agents(df=df) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) assert len(model.locations) == 3 assert len(model.agents) == 6 diff --git a/tests/test_location/test_combinations/test_n_location_refine.py b/tests/test_location_designer/test_combinations/test_n_location_refine.py similarity index 94% rename from tests/test_location/test_combinations/test_n_location_refine.py rename to tests/test_location_designer/test_combinations/test_n_location_refine.py index 637628d..01ecfb1 100644 --- a/tests/test_location/test_combinations/test_n_location_refine.py +++ b/tests/test_location_designer/test_combinations/test_n_location_refine.py @@ -1,16 +1,19 @@ import pandas as pd +import pytest import pop2net as p2n - # TODO Gefundener Nebeneffekt: # Die Aufteilung der Agenten ist anders als Erwartet # Hätte erwartet loc 1 mit 3x "pupil" und loc 2 mit 2x "teacher" # Ist es faslch diese Aufteilung zu erwarten? + + +@pytest.mark.skip def test_1(): df = pd.DataFrame({"status": ["pupil", "pupil", "pupil", "teacher", "teacher"]}) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_locations = 2 def refine(self): diff --git a/tests/test_location/test_combinations/test_n_locations_filter.py b/tests/test_location_designer/test_combinations/test_n_locations_filter.py similarity index 84% rename from tests/test_location/test_combinations/test_n_locations_filter.py rename to tests/test_location_designer/test_combinations/test_n_locations_filter.py index 38e9c15..b334aa1 100644 --- a/tests/test_location/test_combinations/test_n_locations_filter.py +++ b/tests/test_location_designer/test_combinations/test_n_locations_filter.py @@ -13,20 +13,20 @@ def test_1(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocationA(p2n.MagicLocation): + class TestLocationA(p2n.LocationDesigner): n_locations = 2 def filter(self, agent): return agent.status == "A" - class TestLocationB(p2n.MagicLocation): + class TestLocationB(p2n.LocationDesigner): n_locations = 1 def filter(self, agent): return agent.status == "B" creator.create_agents(df=df) - creator.create_locations(location_classes=[TestLocationA, TestLocationB]) + creator.create_locations(location_designers=[TestLocationA, TestLocationB]) inspector = p2n.NetworkInspector(model=model) inspector.plot_bipartite_network() inspector.plot_agent_network(agent_attrs=["status"]) diff --git a/tests/test_location/test_combinations/test_n_locations_nest.py b/tests/test_location_designer/test_combinations/test_n_locations_nest.py similarity index 79% rename from tests/test_location/test_combinations/test_n_locations_nest.py rename to tests/test_location_designer/test_combinations/test_n_locations_nest.py index 73be26f..e8202cb 100644 --- a/tests/test_location/test_combinations/test_n_locations_nest.py +++ b/tests/test_location_designer/test_combinations/test_n_locations_nest.py @@ -13,10 +13,10 @@ def test_1(): } ) - class School(p2n.MagicLocation): + class School(p2n.LocationDesigner): n_locations = 1 - class Classroom(p2n.MagicLocation): + class Classroom(p2n.LocationDesigner): n_locations = 2 def nest(self): @@ -24,7 +24,7 @@ def nest(self): model = p2n.Model() creator = p2n.Creator(model=model) - creator.create(df=df, location_classes=[School, Classroom]) + creator.create(df=df, location_designers=[School, Classroom]) inspector = p2n.NetworkInspector(model) inspector.plot_bipartite_network() @@ -38,8 +38,8 @@ def nest(self): assert len(location.agents) == 2 for agent in model.agents: - assert agent.neighbors(location_classes=[Classroom])[0] in agent.neighbors( - location_classes=[School] + assert agent.neighbors(location_labels=["Classroom"])[0] in agent.neighbors( + location_labels=["School"] ) @@ -54,10 +54,10 @@ def test_2(): } ) - class School(p2n.MagicLocation): + class School(p2n.LocationDesigner): n_locations = 2 - class Classroom(p2n.MagicLocation): + class Classroom(p2n.LocationDesigner): n_locations = 1 def nest(self): @@ -65,7 +65,7 @@ def nest(self): model = p2n.Model() creator = p2n.Creator(model=model) - creator.create(df=df, location_classes=[School, Classroom]) + creator.create(df=df, location_designers=[School, Classroom]) inspector = p2n.NetworkInspector(model) inspector.plot_bipartite_network() print(len(model.locations)) diff --git a/tests/test_location_designer/test_combinations/test_n_locations_split.py b/tests/test_location_designer/test_combinations/test_n_locations_split.py new file mode 100644 index 0000000..d63df66 --- /dev/null +++ b/tests/test_location_designer/test_combinations/test_n_locations_split.py @@ -0,0 +1,53 @@ +import pandas as pd + +import pop2net as p2n + + +def test_1(): + df = pd.DataFrame( + { + "status": ["A", "B", "B", "A", "B", "C"], + }, + ) + + model = p2n.Model() + creator = p2n.Creator(model) + + class TestLocation(p2n.LocationDesigner): + n_locations = None + + def split(self, agent): + return agent.status + + creator.create_agents(df=df) + creator.create_locations(location_designers=[TestLocation]) + + assert len(model.locations) == 3 + assert len(model.agents) == 6 + assert TestLocation.n_locations is None + + +def test_2(): + df = pd.DataFrame( + { + "status": ["A", "B", "B", "A", "B", "C"], + }, + ) + + model = p2n.Model() + creator = p2n.Creator(model) + + class TestLocation(p2n.LocationDesigner): + n_locations = 3 + + def split(self, agent): + return agent.status + + creator.create_agents(df=df) + creator.create_locations(location_designers=[TestLocation]) + + assert len(model.locations) == 3 + assert len(model.agents) == 6 + + # check if the n_locations attribute is overwritten with None + assert TestLocation.n_locations is None diff --git a/tests/test_location/test_combinations/test_n_locations_stick_together.py b/tests/test_location_designer/test_combinations/test_n_locations_stick_together.py similarity index 56% rename from tests/test_location/test_combinations/test_n_locations_stick_together.py rename to tests/test_location_designer/test_combinations/test_n_locations_stick_together.py index 53ee67d..b1d0348 100644 --- a/tests/test_location/test_combinations/test_n_locations_stick_together.py +++ b/tests/test_location_designer/test_combinations/test_n_locations_stick_together.py @@ -9,7 +9,7 @@ def test_1(): df = pd.DataFrame({"status": ["pupil", "pupil", "pupil", "pupil"], "class_id": [1, 2, 1, 2]}) - class Classroom(p2n.MagicLocation): + class Classroom(p2n.LocationDesigner): n_locations = 4 def stick_together(self, agent): @@ -17,15 +17,7 @@ def stick_together(self, agent): model = p2n.Model() creator = p2n.Creator(model=model) - creator.create(df=df, location_classes=[Classroom]) - - inspector = p2n.NetworkInspector(model) - inspector.plot_bipartite_network() - inspector.plot_agent_network(agent_attrs=df.columns, agent_color="class_id") - - for location in model.locations[0:3]: - print(location) - print(location.agents) + creator.create(df=df, location_designers=[Classroom]) assert len(model.agents) == 4 assert len(model.locations) == 4 @@ -34,5 +26,5 @@ def stick_together(self, agent): assert len(location.agents) == 2 for agent in model.agents: - assert agent.neighbors(location_classes=[Classroom])[0].class_id == agent.class_id + assert agent.neighbors(location_labels=["Classroom"])[0].class_id == agent.class_id assert all(not location.agents for location in model.locations[2:]) diff --git a/tests/test_location/test_combinations/test_overcrowding_exact_size_only.py b/tests/test_location_designer/test_combinations/test_overcrowding_exact_size_only.py similarity index 58% rename from tests/test_location/test_combinations/test_overcrowding_exact_size_only.py rename to tests/test_location_designer/test_combinations/test_overcrowding_exact_size_only.py index eb01ea3..c2e8963 100644 --- a/tests/test_location/test_combinations/test_overcrowding_exact_size_only.py +++ b/tests/test_location_designer/test_combinations/test_overcrowding_exact_size_only.py @@ -1,4 +1,3 @@ -# Hier muss man die Hierarchie berücksichtgigen und testen exact size only überschreibt das Verhalten von overcrrowd import pandas as pd import pop2net as p2n @@ -11,44 +10,41 @@ def test_1(): }, ) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): overcrowding = None n_agents = 5 only_exact_n_agents = False - class TestLocation2(p2n.MagicLocation): + class TestLocation2(p2n.LocationDesigner): overcrowding = True n_agents = 5 only_exact_n_agents = False - class TestLocation3(p2n.MagicLocation): + class TestLocation3(p2n.LocationDesigner): overcrowding = False n_agents = 5 only_exact_n_agents = False model = p2n.Model() creator = p2n.Creator(model) - creator.create(df=df, location_classes=[TestLocation]) - inspector = p2n.NetworkInspector(model) - inspector.plot_agent_network(agent_attrs=df.columns, agent_color="status") + creator.create(df=df, location_designers=[TestLocation]) + assert len(model.agents) == 7 assert len(model.locations) == 1 assert len(model.locations[0].agents) == 7 model = p2n.Model() creator = p2n.Creator(model) - creator.create(df=df, location_classes=[TestLocation2]) - inspector = p2n.NetworkInspector(model) - inspector.plot_agent_network(agent_attrs=df.columns, agent_color="status") + creator.create(df=df, location_designers=[TestLocation2]) + assert len(model.agents) == 7 assert len(model.locations) == 1 assert len(model.locations[0].agents) == 7 model = p2n.Model() creator = p2n.Creator(model) - creator.create(df=df, location_classes=[TestLocation3]) - inspector = p2n.NetworkInspector(model) - inspector.plot_agent_network(agent_attrs=df.columns, agent_color="status") + creator.create(df=df, location_designers=[TestLocation3]) + assert len(model.agents) == 7 assert len(model.locations) == 2 assert len(model.locations[0].agents) == 5 @@ -62,26 +58,25 @@ def test_1(): }, ) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): overcrowding = None n_agents = 5 only_exact_n_agents = True - class TestLocation2(p2n.MagicLocation): + class TestLocation2(p2n.LocationDesigner): overcrowding = True n_agents = 5 only_exact_n_agents = True - class TestLocation3(p2n.MagicLocation): + class TestLocation3(p2n.LocationDesigner): overcrowding = False n_agents = 5 only_exact_n_agents = True model = p2n.Model() creator = p2n.Creator(model) - creator.create(df=df, location_classes=[TestLocation]) - inspector = p2n.NetworkInspector(model) - inspector.plot_agent_network(agent_attrs=df.columns, agent_color="status") + creator.create(df=df, location_designers=[TestLocation]) + assert len(model.agents) == 7 assert len(model.locations) == 1 assert len(model.locations[0].agents) == 5 @@ -89,9 +84,8 @@ class TestLocation3(p2n.MagicLocation): model = p2n.Model() creator = p2n.Creator(model) - creator.create(df=df, location_classes=[TestLocation2]) - inspector = p2n.NetworkInspector(model) - inspector.plot_agent_network(agent_attrs=df.columns, agent_color="status") + creator.create(df=df, location_designers=[TestLocation2]) + assert len(model.agents) == 7 assert len(model.locations) == 1 assert len(model.locations[0].agents) == 5 @@ -99,9 +93,8 @@ class TestLocation3(p2n.MagicLocation): model = p2n.Model() creator = p2n.Creator(model) - creator.create(df=df, location_classes=[TestLocation3]) - inspector = p2n.NetworkInspector(model) - inspector.plot_agent_network(agent_attrs=df.columns, agent_color="status") + creator.create(df=df, location_designers=[TestLocation3]) + assert len(model.agents) == 7 assert len(model.locations) == 1 assert len(model.locations[0].agents) == 5 diff --git a/tests/test_location/test_combinations/test_overcrowding_filter.py b/tests/test_location_designer/test_combinations/test_overcrowding_filter.py similarity index 74% rename from tests/test_location/test_combinations/test_overcrowding_filter.py rename to tests/test_location_designer/test_combinations/test_overcrowding_filter.py index e1099df..a11666f 100644 --- a/tests/test_location/test_combinations/test_overcrowding_filter.py +++ b/tests/test_location_designer/test_combinations/test_overcrowding_filter.py @@ -10,42 +10,42 @@ def test_1(): }, ) - class TestLocationA1(p2n.MagicLocation): + class TestLocationA1(p2n.LocationDesigner): overcrowding = None n_agents = 5 def filter(self, agent): return agent.status == "A" - class TestLocationA2(p2n.MagicLocation): + class TestLocationA2(p2n.LocationDesigner): overcrowding = True n_agents = 5 def filter(self, agent): return agent.status == "A" - class TestLocationA3(p2n.MagicLocation): + class TestLocationA3(p2n.LocationDesigner): overcrowding = False n_agents = 5 def filter(self, agent): return agent.status == "A" - class TestLocationB1(p2n.MagicLocation): + class TestLocationB1(p2n.LocationDesigner): overcrowding = None n_agents = 5 def filter(self, agent): return agent.status == "B" - class TestLocationB2(p2n.MagicLocation): + class TestLocationB2(p2n.LocationDesigner): overcrowding = True n_agents = 5 def filter(self, agent): return agent.status == "B" - class TestLocationB3(p2n.MagicLocation): + class TestLocationB3(p2n.LocationDesigner): overcrowding = False n_agents = 5 @@ -54,7 +54,7 @@ def filter(self, agent): model = p2n.Model() creator = p2n.Creator(model) - creator.create(df=df, location_classes=[TestLocationA1, TestLocationB1]) + creator.create(df=df, location_designers=[TestLocationA1, TestLocationB1]) assert len(model.agents) == 14 assert len(model.locations) == 2 assert len(model.locations[0].agents) == 7 @@ -64,10 +64,7 @@ def filter(self, agent): model = p2n.Model() creator = p2n.Creator(model) - creator.create(df=df, location_classes=[TestLocationA2, TestLocationB2]) - inspector = p2n.NetworkInspector(model) - inspector.plot_bipartite_network() - inspector.plot_agent_network(agent_attrs=df.columns, agent_color="status") + creator.create(df=df, location_designers=[TestLocationA2, TestLocationB2]) assert len(model.agents) == 14 assert len(model.locations) == 2 assert len(model.locations[0].agents) == 7 @@ -77,9 +74,7 @@ def filter(self, agent): model = p2n.Model() creator = p2n.Creator(model) - creator.create(df=df, location_classes=[TestLocationA3, TestLocationB3]) - inspector = p2n.NetworkInspector(model) - inspector.plot_agent_network(agent_attrs=df.columns, agent_color="status") + creator.create(df=df, location_designers=[TestLocationA3, TestLocationB3]) assert len(model.agents) == 14 assert len(model.locations) == 4 assert len(model.locations[0].agents) == 5 diff --git a/tests/test_location/test_combinations/test_overcrowding_nest.py b/tests/test_location_designer/test_combinations/test_overcrowding_nest.py similarity index 78% rename from tests/test_location/test_combinations/test_overcrowding_nest.py rename to tests/test_location_designer/test_combinations/test_overcrowding_nest.py index cb96b1b..1fe3ca5 100644 --- a/tests/test_location/test_combinations/test_overcrowding_nest.py +++ b/tests/test_location_designer/test_combinations/test_overcrowding_nest.py @@ -14,11 +14,11 @@ def test_1(): } ) - class School(p2n.MagicLocation): + class School(p2n.LocationDesigner): overcrowding = False n_agents = 5 - class Classroom(p2n.MagicLocation): + class Classroom(p2n.LocationDesigner): overcrowding = False n_agents = 5 @@ -27,7 +27,7 @@ def nest(self): model = p2n.Model() creator = p2n.Creator(model=model) - creator.create(df=df, location_classes=[School, Classroom]) + creator.create(df=df, location_designers=[School, Classroom]) inspector = p2n.NetworkInspector(model) inspector.plot_bipartite_network() inspector.plot_agent_network(agent_attrs=df) @@ -53,10 +53,10 @@ def test_2(): } ) - class School(p2n.MagicLocation): + class School(p2n.LocationDesigner): n_agents = 4 - class Classroom(p2n.MagicLocation): + class Classroom(p2n.LocationDesigner): n_agents = 2 def split(self, agent): @@ -66,7 +66,7 @@ def split(self, agent): creator = p2n.Creator(model=model) creator.create( df=df, - location_classes=[School, Classroom], + location_designers=[School, Classroom], delete_magic_agent_attributes=False, ) @@ -74,7 +74,7 @@ def split(self, agent): assert len(model.locations) == 6 for location in model.locations: - if location.type == "School": + if location.label == "School": assert len(location.agents) == 4 counter = Counter([agent.group for agent in location.agents]) assert counter[1] == 2 @@ -83,30 +83,30 @@ def split(self, agent): assert not all( location.agents[0].School == location.agents[1].School for location in model.locations - if location.type == "Classroom" + if location.label == "Classroom" ) inspector = p2n.NetworkInspector(model) inspector.plot_bipartite_network() inspector.plot_agent_network(agent_attrs=df.columns, agent_color="id") - class School(p2n.MagicLocation): + class School(p2n.LocationDesigner): n_agents = 4 - class Classroom(p2n.MagicLocation): + class Classroom(p2n.LocationDesigner): n_agents = 2 def split(self, agent): return agent.group def nest(self): - return School + return "School" model = p2n.Model() creator = p2n.Creator(model=model) creator.create( df=df, - location_classes=[School, Classroom], + location_designers=[School, Classroom], delete_magic_agent_attributes=False, ) @@ -115,7 +115,7 @@ def nest(self): assert all( location.agents[0].School == location.agents[1].School for location in model.locations - if location.type == "Classroom" + if location.label == "Classroom" ) inspector = p2n.NetworkInspector(model) @@ -123,35 +123,35 @@ def nest(self): inspector.plot_agent_network(agent_attrs=df.columns, agent_color="group") for location in model.locations: - if location.type == "School": + if location.label == "School": assert len(location.agents) == 4 - if location.type == "Classroom": + if location.label == "Classroom": assert len(location.agents) == 2 for location in model.locations: - if location.type == "School": + if location.label == "School": assert len(location.agents) == 4 counter = Counter([agent.group for agent in location.agents]) assert counter[1] == 2 assert counter[2] == 2 assert any( - agent.neighbors(location_classes=[Classroom]) - not in agent.neighbors(location_classes=[School]) + agent.neighbors(location_labels=[Classroom]) + not in agent.neighbors(location_labels=[School]) for agent in model.agents ) for location in model.locations: - if location.type == "School": + if location.label == "School": for agent in location.agents: assert all(agent.School == nghbr.School for nghbr in agent.neighbors()) def test_3(): - class City(p2n.MagicLocation): + class City(p2n.LocationDesigner): n_agents = 4 - class Group(p2n.MagicLocation): + class Group(p2n.LocationDesigner): n_agents = 2 def split(self, agent): @@ -165,17 +165,17 @@ def split(self, agent): agent.group = i % 2 creator.create_locations( - location_classes=[City, Group], + location_designers=[City, Group], delete_magic_agent_attributes=False, ) - for location in model.locations.select(model.locations.type == "City"): + for location in model.locations.select(model.locations.label == "City"): assert int(location.agents[0].group) == 0 assert int(location.agents[1].group) == 1 assert int(location.agents[2].group) == 0 assert int(location.agents[3].group) == 1 - for location in model.locations.select(model.locations.type == "Group"): + for location in model.locations.select(model.locations.label == "Group"): assert location.agents[0].group == location.agents[1].group # not all members of the same group are also in the same city (which is not desired) @@ -190,17 +190,17 @@ def nest(self): model = p2n.Model() creator = p2n.Creator(model=model) creator.create_locations( - location_classes=[City, GroupNestedInCity], + location_designers=[City, GroupNestedInCity], delete_magic_agent_attributes=False, ) - for location in model.locations.select(model.locations.type == "City"): + for location in model.locations.select(model.locations.label == "City"): assert int(location.agents[0].group) == 0 assert int(location.agents[1].group) == 1 assert int(location.agents[2].group) == 0 assert int(location.agents[3].group) == 1 - for location in model.locations.select(model.locations.type == "Group"): + for location in model.locations.select(model.locations.label == "Group"): assert location.agents[0].group == location.agents[1].group # all members of a group are in the same city diff --git a/tests/test_location/test_combinations/test_overcrowding_split.py b/tests/test_location_designer/test_combinations/test_overcrowding_split.py similarity index 85% rename from tests/test_location/test_combinations/test_overcrowding_split.py rename to tests/test_location_designer/test_combinations/test_overcrowding_split.py index 4312925..107a029 100644 --- a/tests/test_location/test_combinations/test_overcrowding_split.py +++ b/tests/test_location_designer/test_combinations/test_overcrowding_split.py @@ -1,10 +1,8 @@ -# %% import pandas as pd import pop2net as p2n -# %% def test_1(): df = pd.DataFrame( { @@ -12,21 +10,21 @@ def test_1(): }, ) - class TestLocation1(p2n.MagicLocation): + class TestLocation1(p2n.LocationDesigner): overcrowding = None n_agents = 5 def split(self, agent): return agent.status - class TestLocation2(p2n.MagicLocation): + class TestLocation2(p2n.LocationDesigner): overcrowding = True n_agents = 5 def split(self, agent): return agent.status - class TestLocation3(p2n.MagicLocation): + class TestLocation3(p2n.LocationDesigner): overcrowding = False n_agents = 5 @@ -35,7 +33,7 @@ def split(self, agent): model = p2n.Model() creator = p2n.Creator(model) - creator.create(df=df, location_classes=[TestLocation1]) + creator.create(df=df, location_designers=[TestLocation1]) assert len(model.agents) == 14 assert len(model.locations) == 2 assert len(model.locations[0].agents) == 7 @@ -45,7 +43,7 @@ def split(self, agent): model = p2n.Model() creator = p2n.Creator(model) - creator.create(df=df, location_classes=[TestLocation2]) + creator.create(df=df, location_designers=[TestLocation2]) assert len(model.agents) == 14 assert len(model.locations) == 2 assert len(model.locations[0].agents) == 7 @@ -55,7 +53,7 @@ def split(self, agent): model = p2n.Model() creator = p2n.Creator(model) - creator.create(df=df, location_classes=[TestLocation3]) + creator.create(df=df, location_designers=[TestLocation3]) assert len(model.agents) == 14 assert len(model.locations) == 4 assert len(model.locations[0].agents) == 5 @@ -66,6 +64,3 @@ def split(self, agent): assert all(agent.status == "A" for agent in model.locations[1].agents) assert all(agent.status == "B" for agent in model.locations[2].agents) assert all(agent.status == "B" for agent in model.locations[3].agents) - - -# %% diff --git a/tests/test_location/test_combinations/test_split_melt.py b/tests/test_location_designer/test_combinations/test_split_melt.py similarity index 79% rename from tests/test_location/test_combinations/test_split_melt.py rename to tests/test_location_designer/test_combinations/test_split_melt.py index 8cadb79..371d202 100644 --- a/tests/test_location/test_combinations/test_split_melt.py +++ b/tests/test_location_designer/test_combinations/test_split_melt.py @@ -1,10 +1,8 @@ -# %% import pandas as pd import pop2net as p2n -# %% def test_1(): model = p2n.Model() creator = p2n.Creator(model=model) @@ -25,26 +23,26 @@ def test_1(): } ) - class PupilHelper(p2n.MagicLocation): + class PupilHelper(p2n.LocationDesigner): def filter(self, agent): return agent.status == "pupil" def split(self, agent): return agent.class_id - class TeacherHelper(p2n.MagicLocation): + class TeacherHelper(p2n.LocationDesigner): def filter(self, agent): return agent.status == "teacher" def split(self, agent): return agent.class_id - class ClassRoom(p2n.MagicLocation): + class ClassRoom(p2n.LocationDesigner): def melt(self): return PupilHelper, TeacherHelper creator.create_agents(df=df) - creator.create_locations(location_classes=[ClassRoom]) + creator.create_locations(location_designers=[ClassRoom]) assert len(model.agents) == 9 assert len(model.locations) == 3 @@ -54,10 +52,6 @@ def melt(self): assert all(location.agents[0].class_id == agent.class_id for agent in location.agents) -# %% -# TODO Anwendungsbeispiel passt eher zu nest? aber zum testen von multi melt... -# ...nicht schlecht? -# 2-layer melts def test_2(): model = p2n.Model() creator = p2n.Creator(model=model) @@ -79,40 +73,40 @@ def test_2(): } ) - class PupilHelper(p2n.MeltLocation): + class PupilHelper(p2n.MeltLocationDesigner): def filter(self, agent): return agent.status == "pupil" def split(self, agent): return agent.class_id - class TeacherHelper(p2n.MeltLocation): + class TeacherHelper(p2n.MeltLocationDesigner): def filter(self, agent): return agent.status == "teacher" def split(self, agent): return agent.class_id - class ClassRoom(p2n.MagicLocation): + class ClassRoom(p2n.LocationDesigner): def melt(self): return PupilHelper, TeacherHelper - class SchoolHelper(p2n.MeltLocation): + class SchoolHelper(p2n.MeltLocationDesigner): def filter(self, agent): return agent.status == "principal" - class School(p2n.MagicLocation): + class School(p2n.LocationDesigner): def melt(self): return ClassRoom, SchoolHelper creator.create_agents(df=df) - creator.create_locations(location_classes=[ClassRoom, School]) + creator.create_locations(location_designers=[ClassRoom, School]) assert len(model.agents) == 10 assert len(model.locations) == 4 for location in model.locations: - if location.type == "ClassRoom": + if location.label == "ClassRoom": assert len(location.agents) == 3 assert all(location.agents[0].class_id == agent.class_id for agent in location.agents) else: diff --git a/tests/test_location/test_combinations/test_split_nest.py b/tests/test_location_designer/test_combinations/test_split_nest.py similarity index 75% rename from tests/test_location/test_combinations/test_split_nest.py rename to tests/test_location_designer/test_combinations/test_split_nest.py index e7548a2..b464b20 100644 --- a/tests/test_location/test_combinations/test_split_nest.py +++ b/tests/test_location_designer/test_combinations/test_split_nest.py @@ -16,10 +16,10 @@ def test_1(): } ) - class School(p2n.MagicLocation): + class School(p2n.LocationDesigner): n_agents = 4 - class Classroom(p2n.MagicLocation): + class Classroom(p2n.LocationDesigner): n_agents = 2 def split(self, agent): @@ -29,7 +29,7 @@ def split(self, agent): creator = p2n.Creator(model=model) creator.create( df=df, - location_classes=[School, Classroom], + location_designers=[School, Classroom], delete_magic_agent_attributes=False, ) @@ -37,7 +37,7 @@ def split(self, agent): assert len(model.locations) == 6 for location in model.locations: - if location.type == "School": + if location.label == "School": assert len(location.agents) == 4 counter = Counter([agent.group for agent in location.agents]) assert counter[1] == 2 @@ -46,26 +46,26 @@ def split(self, agent): assert not all( location.agents[0].School == location.agents[1].School for location in model.locations - if location.type == "Classroom" + if location.label == "Classroom" ) - class School(p2n.MagicLocation): + class School(p2n.LocationDesigner): n_agents = 4 - class Classroom(p2n.MagicLocation): + class Classroom(p2n.LocationDesigner): n_agents = 2 def split(self, agent): return agent.group def nest(self): - return School + return "School" model = p2n.Model() creator = p2n.Creator(model=model) creator.create( df=df, - location_classes=[School, Classroom], + location_designers=[School, Classroom], delete_magic_agent_attributes=False, ) @@ -74,29 +74,29 @@ def nest(self): assert all( location.agents[0].School == location.agents[1].School for location in model.locations - if location.type == "Classroom" + if location.label == "Classroom" ) for location in model.locations: - if location.type == "School": + if location.label == "School": assert len(location.agents) == 4 - if location.type == "Classroom": + if location.label == "Classroom": assert len(location.agents) == 2 for location in model.locations: - if location.type == "School": + if location.label == "School": assert len(location.agents) == 4 counter = Counter([agent.group for agent in location.agents]) assert counter[1] == 2 assert counter[2] == 2 assert any( - agent.neighbors(location_classes=[Classroom]) - not in agent.neighbors(location_classes=[School]) + agent.neighbors(location_labels=["Classroom"]) + not in agent.neighbors(location_labels=["School"]) for agent in model.agents ) for location in model.locations: - if location.type == "School": + if location.label == "School": for agent in location.agents: assert all(agent.School == nghbr.School for nghbr in agent.neighbors()) diff --git a/tests/test_location/test_combinations/test_split_refine.py b/tests/test_location_designer/test_combinations/test_split_refine.py similarity index 90% rename from tests/test_location/test_combinations/test_split_refine.py rename to tests/test_location_designer/test_combinations/test_split_refine.py index 535fb72..1285052 100644 --- a/tests/test_location/test_combinations/test_split_refine.py +++ b/tests/test_location_designer/test_combinations/test_split_refine.py @@ -1,11 +1,13 @@ # %% import pandas as pd +import pytest import pop2net as p2n # %% +@pytest.mark.skip def test_1(): model = p2n.Model() creator = p2n.Creator(model=model) @@ -16,7 +18,7 @@ def test_1(): }, ) - class ClassRoom(p2n.MagicLocation): + class ClassRoom(p2n.LocationDesigner): def split(self, agent): return agent.status diff --git a/tests/test_location/test_combinations/test_split_stick_together.py b/tests/test_location_designer/test_combinations/test_split_stick_together.py similarity index 94% rename from tests/test_location/test_combinations/test_split_stick_together.py rename to tests/test_location_designer/test_combinations/test_split_stick_together.py index 851c582..7079282 100644 --- a/tests/test_location/test_combinations/test_split_stick_together.py +++ b/tests/test_location_designer/test_combinations/test_split_stick_together.py @@ -15,7 +15,7 @@ def test_1(): } ) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_agents = 4 def split(self, agent): @@ -25,7 +25,7 @@ def stick_together(self, agent): return agent.friend_group creator.create_agents(df=df) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) for i, location in enumerate(model.locations): print(f"Location;{i}") diff --git a/tests/test_location/test_combinations/test_split_weight.py b/tests/test_location_designer/test_combinations/test_split_weight.py similarity index 78% rename from tests/test_location/test_combinations/test_split_weight.py rename to tests/test_location_designer/test_combinations/test_split_weight.py index 2576006..30c14a8 100644 --- a/tests/test_location/test_combinations/test_split_weight.py +++ b/tests/test_location_designer/test_combinations/test_split_weight.py @@ -6,10 +6,10 @@ def test_1(): model = p2n.Model() creator = p2n.Creator(model=model) - inspector = p2n.NetworkInspector(model=model) + df = pd.DataFrame({"status": ["A", "B", "B", "A", "A"]}) - class ClassRoom(p2n.MagicLocation): + class ClassRoom(p2n.LocationDesigner): def split(self, agent): return agent.status @@ -17,9 +17,7 @@ def weight(self, agent): return 5 creator.create_agents(df=df) - creator.create_locations(location_classes=[ClassRoom]) - inspector.plot_bipartite_network() - inspector.plot_agent_network() + creator.create_locations(location_designers=[ClassRoom]) assert len(model.locations) == 2 assert len(model.agents) == 5 @@ -28,12 +26,7 @@ def weight(self, agent): assert all(agent.status == "A" for agent in model.locations[0].agents) assert all(agent.status == "B" for agent in model.locations[1].agents) - # TODO Warum triggered das nicht assert? - # assert all([[location.get_weight(agent) == 4 for agent in location.agents] for location in model.locations]) - - # TODO - # keine Ahnung wie ich das effizienter ermitteln könnte - # List comprehension geschachtelt geht bei mir nicht siehe oben + # locations_weights = [] # model sum weight for location in model.locations: @@ -48,14 +41,14 @@ def weight(self, agent): def test_2(): model = p2n.Model() creator = p2n.Creator(model=model) - inspector = p2n.NetworkInspector(model=model) + df = pd.DataFrame( { "status": ["A", "B", "A", "B", "A"], } ) - class ClassRoom(p2n.MagicLocation): + class ClassRoom(p2n.LocationDesigner): def split(self, agent): return agent.status @@ -66,9 +59,7 @@ def weight(self, agent): return 4 creator.create_agents(df=df) - creator.create_locations(location_classes=[ClassRoom]) - inspector.plot_bipartite_network() - inspector.plot_agent_network(agent_attrs=["status"]) + creator.create_locations(location_designers=[ClassRoom]) assert len(model.locations) == 2 assert len(model.agents) == 5 @@ -94,7 +85,7 @@ def test_3(): creator = p2n.Creator(model=model) df = pd.DataFrame({"status": ["A", "B", "A", "B"], "attention_span": [1, 3, 2.5, 4]}) - class ClassRoom(p2n.MagicLocation): + class ClassRoom(p2n.LocationDesigner): def split(self, agent): return agent.status @@ -102,7 +93,7 @@ def weight(self, agent): return agent.attention_span creator.create_agents(df=df) - creator.create_locations(location_classes=[ClassRoom]) + creator.create_locations(location_designers=[ClassRoom]) assert len(model.locations) == 2 assert len(model.agents) == 4 diff --git a/tests/test_location/test_exact_n_agents_stick_together.py b/tests/test_location_designer/test_exact_n_agents_stick_together.py similarity index 76% rename from tests/test_location/test_exact_n_agents_stick_together.py rename to tests/test_location_designer/test_exact_n_agents_stick_together.py index 9cbc660..b233b49 100644 --- a/tests/test_location/test_exact_n_agents_stick_together.py +++ b/tests/test_location_designer/test_exact_n_agents_stick_together.py @@ -8,7 +8,7 @@ def test_1(): {"status": ["pupil", "pupil", "pupil", "pupil", "pupil"], "class_id": [1, 2, 1, 2, 1]} ) - class Classroom(p2n.MagicLocation): + class Classroom(p2n.LocationDesigner): n_agents = 2 only_exact_n_agents = False @@ -17,7 +17,7 @@ def stick_together(self, agent): model = p2n.Model() creator = p2n.Creator(model=model) - creator.create(df=df, location_classes=[Classroom]) + creator.create(df=df, location_designers=[Classroom]) assert len(model.agents) == 5 assert len(model.locations) == 2 @@ -25,10 +25,10 @@ def stick_together(self, agent): assert len(model.locations[1].agents) == 3 for agent in model.agents: - assert agent.neighbors(location_classes=[Classroom])[0].class_id == agent.class_id + assert agent.neighbors(location_labels=["Classroom"])[0].class_id == agent.class_id # with exact agent set to True - class Classroom(p2n.MagicLocation): + class Classroom(p2n.LocationDesigner): n_agents = 2 only_exact_n_agents = True @@ -37,7 +37,7 @@ def stick_together(self, agent): model = p2n.Model() creator = p2n.Creator(model=model) - creator.create(df=df, location_classes=[Classroom]) + creator.create(df=df, location_designers=[Classroom]) inspector = p2n.NetworkInspector(model) inspector.plot_bipartite_network() @@ -49,5 +49,5 @@ def stick_together(self, agent): for agent in model.agents: if agent.locations: - assert agent.neighbors(location_classes=[Classroom])[0].class_id == agent.class_id + assert agent.neighbors(location_labels=["Classroom"])[0].class_id == agent.class_id assert all(not agent.locations for agent in model.agents if agent.class_id == 1) diff --git a/tests/test_location/test_location_bridge.py b/tests/test_location_designer/test_location_bridge.py similarity index 88% rename from tests/test_location/test_location_bridge.py rename to tests/test_location_designer/test_location_bridge.py index dfa11a7..d6195f0 100644 --- a/tests/test_location/test_location_bridge.py +++ b/tests/test_location_designer/test_location_bridge.py @@ -15,13 +15,13 @@ def test_1(): agent = p2n.Agent(model) agent.gender = "m" - class HeteroRelationship(p2n.MagicLocation): + class HeteroRelationship(p2n.LocationDesigner): recycle = False def bridge(self, agent): return agent.gender - creator.create_locations(location_classes=[HeteroRelationship]) + creator.create_locations(location_designers=[HeteroRelationship]) assert len(model.locations) == 2 assert len(model.agents) == 5 @@ -52,14 +52,14 @@ def test_2(): agent = p2n.Agent(model) agent.gender = "m" - class HeteroRelationship(p2n.MagicLocation): + class HeteroRelationship(p2n.LocationDesigner): recycle = False n_locations = 1 def bridge(self, agent): return agent.gender - creator.create_locations(location_classes=[HeteroRelationship]) + creator.create_locations(location_designers=[HeteroRelationship]) assert len(model.locations) == 1 assert len(model.agents) == 5 @@ -90,13 +90,13 @@ def test_3(): agent = p2n.Agent(model) agent.gender = "m" - class HeteroRelationship(p2n.MagicLocation): + class HeteroRelationship(p2n.LocationDesigner): recycle = True def bridge(self, agent): return agent.gender - creator.create_locations(location_classes=[HeteroRelationship]) + creator.create_locations(location_designers=[HeteroRelationship]) assert len(model.locations) == 3 assert len(model.agents) == 5 @@ -127,14 +127,14 @@ def test_4(): agent = p2n.Agent(model) agent.gender = "m" - class HeteroRelationship(p2n.MagicLocation): + class HeteroRelationship(p2n.LocationDesigner): recycle = True n_locations = 1 def bridge(self, agent): return agent.gender - creator.create_locations(location_classes=[HeteroRelationship]) + creator.create_locations(location_designers=[HeteroRelationship]) assert len(model.locations) == 1 assert len(model.agents) == 5 diff --git a/tests/test_location/test_location_filter.py b/tests/test_location_designer/test_location_filter.py similarity index 81% rename from tests/test_location/test_location_filter.py rename to tests/test_location_designer/test_location_filter.py index 0f783f4..14e9082 100644 --- a/tests/test_location/test_location_filter.py +++ b/tests/test_location_designer/test_location_filter.py @@ -14,16 +14,16 @@ def test_1(): model = p2n.Model() creator = Creator(model) - class TestLocationA(p2n.MagicLocation): + class TestLocationA(p2n.LocationDesigner): def filter(self, agent): return agent.status == "A" - class TestLocationB(p2n.MagicLocation): + class TestLocationB(p2n.LocationDesigner): def filter(self, agent): return agent.status == "B" creator.create_agents(df=df) - creator.create_locations(location_classes=[TestLocationA, TestLocationB]) + creator.create_locations(location_designers=[TestLocationA, TestLocationB]) assert len(model.locations) == 2 assert len(model.agents) == 5 @@ -44,16 +44,16 @@ def test_2(): model = p2n.Model() creator = Creator(model) - class TestLocationA(p2n.MagicLocation): + class TestLocationA(p2n.LocationDesigner): def filter(self, agent): return agent.status == "A" and agent.sex == "w" - class TestLocationB(p2n.MagicLocation): + class TestLocationB(p2n.LocationDesigner): def filter(self, agent): return agent.status == "B" and agent.sex == "w" creator.create_agents(df=df) - creator.create_locations(location_classes=[TestLocationA, TestLocationB]) + creator.create_locations(location_designers=[TestLocationA, TestLocationB]) assert len(model.locations) == 2 assert len(model.agents) == 5 diff --git a/tests/test_location_designer/test_location_label.py b/tests/test_location_designer/test_location_label.py new file mode 100644 index 0000000..85fa24b --- /dev/null +++ b/tests/test_location_designer/test_location_label.py @@ -0,0 +1,66 @@ +import pop2net as p2n + + +def test_location_label(): + model = p2n.Model() + + # Test 1: Default label (label is class name) + location = p2n.Location(model) + assert location.label == "Location" + + # Test 2: Label is custom class name + class MyLocation(p2n.Location): + pass + + location = MyLocation(model) + assert location.label == "MyLocation" + + # Test 3: Label is custom string + class MyLocation(p2n.Location): + label = "MyLocationYo" + + location = MyLocation(model) + assert location.label == "MyLocationYo" + + +def test_location_designer_label(): + model = p2n.Model() + creator = p2n.Creator(model) + + # Test 1: Default label (label is designer class name) + class School(p2n.LocationDesigner): + n_locations = 1 + + location = creator.create_locations(location_designers=[School])[0] + assert location.label == "School" + + # Test 2: Label is custom string + class School(p2n.LocationDesigner): + label = "SchoolYo" + n_locations = 1 + + location = creator.create_locations(location_designers=[School])[0] + assert location.label == "SchoolYo" + + # Test 3: Label is sthe designer class name even if a custom location class is used + class School(p2n.Location): + pass + + class SchoolDesigner(p2n.LocationDesigner): + n_locations = 1 + location_class = School + + location = creator.create_locations(location_designers=[SchoolDesigner])[0] + assert location.label == "SchoolDesigner" + + # Test 4: Label is the label defined in the designer class even if a location class is used + class School(p2n.Location): + label = "Schoooooool" + + class SchoolDesigner(p2n.LocationDesigner): + label = "SchoolYOOO" + n_locations = 1 + location_class = School + + location = creator.create_locations(location_designers=[SchoolDesigner])[0] + assert location.label == "SchoolYOOO" diff --git a/tests/test_location/test_location_melt.py b/tests/test_location_designer/test_location_melt.py similarity index 77% rename from tests/test_location/test_location_melt.py rename to tests/test_location_designer/test_location_melt.py index 4625654..cae4bdc 100644 --- a/tests/test_location/test_location_melt.py +++ b/tests/test_location_designer/test_location_melt.py @@ -10,19 +10,22 @@ def test_recycle_1(): - class Teacher(p2n.MeltLocation): + class Teacher(p2n.MeltLocationDesigner): + label = "Teacher" n_agents = 1 def filter(self, agent): return agent.status == "teacher" - class Pupils(p2n.MeltLocation): + class Pupils(p2n.MeltLocationDesigner): + label = "Pupil" n_agents = 1 def filter(self, agent): return agent.status == "pupil" - class Classroom(p2n.MagicLocation): + class Classroom(p2n.LocationDesigner): + label = "Classroom" recycle = True def melt(self): @@ -31,7 +34,7 @@ def melt(self): model = p2n.Model() creator = p2n.Creator(model) creator.create_agents(df=df) - creator.create_locations(location_classes=[Classroom]) + creator.create_locations(location_designers=[Classroom]) inspector = p2n.NetworkInspector(model) inspector.plot_bipartite_network() @@ -44,19 +47,19 @@ def melt(self): def test_recycle_2(): - class Teacher(p2n.MeltLocation): + class Teacher(p2n.MeltLocationDesigner): n_agents = 1 def filter(self, agent): return agent.status == "teacher" - class Pupils(p2n.MeltLocation): + class Pupils(p2n.MeltLocationDesigner): n_agents = 1 def filter(self, agent): return agent.status == "pupil" - class Classroom(p2n.MagicLocation): + class Classroom(p2n.LocationDesigner): recycle = False def melt(self): @@ -65,7 +68,7 @@ def melt(self): model = p2n.Model() creator = p2n.Creator(model) creator.create_agents(df=df) - creator.create_locations(location_classes=[Classroom]) + creator.create_locations(location_designers=[Classroom]) inspector = p2n.NetworkInspector(model) inspector.plot_bipartite_network() diff --git a/tests/test_location/test_location_n_locations.py b/tests/test_location_designer/test_location_n_locations.py similarity index 57% rename from tests/test_location/test_location_n_locations.py rename to tests/test_location_designer/test_location_n_locations.py index 7d858ae..6343429 100644 --- a/tests/test_location/test_location_n_locations.py +++ b/tests/test_location_designer/test_location_n_locations.py @@ -1,5 +1,3 @@ -# %% - import pop2net as p2n @@ -7,48 +5,32 @@ def test_1(): model = p2n.Model() creator = p2n.Creator(model=model) - class ClassRoom(p2n.MagicLocation): + class ClassRoom(p2n.LocationDesigner): n_locations = 4 n_agents = None only_exact_n_agents = False - creator.create_locations(location_classes=[ClassRoom]) - - inspector = p2n.NetworkInspector(model=model) - inspector.plot_bipartite_network() - + creator.create_locations(location_designers=[ClassRoom]) assert len(model.locations) == 4 -# %% - - def test_2(): model = p2n.Model() creator = p2n.Creator(model=model) - class ClassRoom(p2n.MagicLocation): + class ClassRoom(p2n.LocationDesigner): n_locations = 4 n_agents = 2 - creator.create_locations(location_classes=[ClassRoom]) - - inspector = p2n.NetworkInspector(model=model) - inspector.plot_bipartite_network() - + creator.create_locations(location_designers=[ClassRoom]) assert len(model.locations) == 4 -test_2() - -# %% - - def test_3(): model = p2n.Model() creator = p2n.Creator(model=model) - class ClassRoom(p2n.MagicLocation): + class ClassRoom(p2n.LocationDesigner): n_locations = 4 n_agents = 2 only_exact_n_agents = False @@ -56,10 +38,7 @@ class ClassRoom(p2n.MagicLocation): for _ in range(10): p2n.Agent(model=model) - creator.create_locations(location_classes=[ClassRoom]) - - inspector = p2n.NetworkInspector(model=model) - inspector.plot_bipartite_network() + creator.create_locations(location_designers=[ClassRoom]) assert len(model.locations) == 4 assert len(model.agents) == 10 @@ -68,16 +47,11 @@ class ClassRoom(p2n.MagicLocation): assert len(location.agents) == 2 -test_3() - -# %% - - def test_4(): model = p2n.Model() creator = p2n.Creator(model=model) - class ClassRoom(p2n.MagicLocation): + class ClassRoom(p2n.LocationDesigner): n_locations = 4 n_agents = 3 only_exact_n_agents = True @@ -85,16 +59,10 @@ class ClassRoom(p2n.MagicLocation): for _ in range(10): p2n.Agent(model=model) - creator.create_locations(location_classes=[ClassRoom]) - - inspector = p2n.NetworkInspector(model=model) - inspector.plot_bipartite_network() + creator.create_locations(location_designers=[ClassRoom]) assert len(model.locations) == 3 assert len(model.agents) == 10 for location in model.locations: assert len(location.agents) == 3 - - -test_4() diff --git a/tests/test_location/test_location_nest.py b/tests/test_location_designer/test_location_nest.py similarity index 64% rename from tests/test_location/test_location_nest.py rename to tests/test_location_designer/test_location_nest.py index 6574fe1..6c33f29 100644 --- a/tests/test_location/test_location_nest.py +++ b/tests/test_location_designer/test_location_nest.py @@ -12,37 +12,36 @@ def test_1(): } ) - class School(p2n.MagicLocation): + class SchoolDesigner(p2n.LocationDesigner): + label = "School" n_agents = 2 - class Classroom(p2n.MagicLocation): + class ClassroomDesigner(p2n.LocationDesigner): + label = "Classroom" n_agents = 2 def nest(self): - return School + return "School" model = p2n.Model() creator = p2n.Creator(model=model) - creator.create(df=df, location_classes=[School, Classroom]) + creator.create(df=df, location_designers=[SchoolDesigner, ClassroomDesigner]) assert len(model.agents) == 4 assert len(model.locations) == 4 for location in model.locations: - if location.type == "School": + if location.label == "School": assert len(location.agents) == 2 - if location.type == "Classroom": + if location.label == "Classroom": assert len(location.agents) == 2 for agent in model.agents: assert ( - agent.neighbors(location_classes=[Classroom])[0] - is agent.neighbors(location_classes=[School])[0] + agent.neighbors(location_labels=["Classroom"])[0] + is agent.neighbors(location_labels=["School"])[0] ) - inspector = p2n.NetworkInspector(model) - inspector.plot_bipartite_network() - def test_2(): df = pd.DataFrame( @@ -53,10 +52,12 @@ def test_2(): } ) - class School(p2n.MagicLocation): + class SchoolDesigner(p2n.LocationDesigner): + label = "School" n_agents = 4 - class Classroom(p2n.MagicLocation): + class ClassroomDesigner(p2n.LocationDesigner): + label = "Classroom" n_agents = 2 def split(self, agent): @@ -66,7 +67,7 @@ def split(self, agent): creator = p2n.Creator(model=model) creator.create( df=df, - location_classes=[School, Classroom], + location_designers=[SchoolDesigner, ClassroomDesigner], delete_magic_agent_attributes=False, ) @@ -74,7 +75,7 @@ def split(self, agent): assert len(model.locations) == 6 for location in model.locations: - if location.type == "School": + if location.label == "School": assert len(location.agents) == 4 counter = Counter([agent.group for agent in location.agents]) assert counter[1] == 2 @@ -83,30 +84,28 @@ def split(self, agent): assert not all( location.agents[0].School == location.agents[1].School for location in model.locations - if location.type == "Classroom" + if location.label == "Classroom" ) - inspector = p2n.NetworkInspector(model) - inspector.plot_bipartite_network() - inspector.plot_agent_network(agent_attrs=df.columns, agent_color="id") - - class School(p2n.MagicLocation): + class SchoolDesigner(p2n.LocationDesigner): + label = "School" n_agents = 4 - class Classroom(p2n.MagicLocation): + class ClassroomDesigner(p2n.LocationDesigner): + label = "Classroom" n_agents = 2 def split(self, agent): return agent.group def nest(self): - return School + return "School" model = p2n.Model() creator = p2n.Creator(model=model) creator.create( df=df, - location_classes=[School, Classroom], + location_designers=[SchoolDesigner, ClassroomDesigner], delete_magic_agent_attributes=False, ) @@ -115,33 +114,29 @@ def nest(self): assert all( location.agents[0].School == location.agents[1].School for location in model.locations - if location.type == "Classroom" + if location.label == "Classroom" ) - inspector = p2n.NetworkInspector(model) - inspector.plot_bipartite_network() - inspector.plot_agent_network(agent_attrs=df.columns, agent_color="group") - for location in model.locations: - if location.type == "School": + if location.label == "School": assert len(location.agents) == 4 - if location.type == "Classroom": + if location.label == "Classroom": assert len(location.agents) == 2 for location in model.locations: - if location.type == "School": + if location.label == "School": assert len(location.agents) == 4 counter = Counter([agent.group for agent in location.agents]) assert counter[1] == 2 assert counter[2] == 2 assert any( - agent.neighbors(location_classes=[Classroom]) - not in agent.neighbors(location_classes=[School]) + agent.neighbors(location_labels=["Classroom"]) + not in agent.neighbors(location_labels=["School"]) for agent in model.agents ) for location in model.locations: - if location.type == "School": + if location.label == "School": for agent in location.agents: assert all(agent.School == nghbr.School for nghbr in agent.neighbors()) diff --git a/tests/test_location/test_location_nest_marius.py b/tests/test_location_designer/test_location_nest_marius.py similarity index 66% rename from tests/test_location/test_location_nest_marius.py rename to tests/test_location_designer/test_location_nest_marius.py index ffa90e3..acab5df 100644 --- a/tests/test_location/test_location_nest_marius.py +++ b/tests/test_location_designer/test_location_nest_marius.py @@ -2,10 +2,12 @@ def test_1(): - class City(p2n.MagicLocation): + class CityDesigner(p2n.LocationDesigner): + label = "City" n_agents = 4 - class Group(p2n.MagicLocation): + class GroupDesigner(p2n.LocationDesigner): + label = "Group" n_agents = 2 def split(self, agent): @@ -19,17 +21,20 @@ def split(self, agent): agent.group = i % 2 creator.create_locations( - location_classes=[City, Group], + location_designers=[CityDesigner, GroupDesigner], delete_magic_agent_attributes=False, ) - for location in model.locations.select(model.locations.type == "City"): + for agent in model.agents: + print(vars(agent)) + + for location in model.locations.select(model.locations.label == "City"): assert int(location.agents[0].group) == 0 assert int(location.agents[1].group) == 1 assert int(location.agents[2].group) == 0 assert int(location.agents[3].group) == 1 - for location in model.locations.select(model.locations.type == "Group"): + for location in model.locations.select(model.locations.label == "Group"): assert location.agents[0].group == location.agents[1].group # not all members of the same group are also in the same city (which is not desired) @@ -37,24 +42,24 @@ def split(self, agent): location.agents[0].City == location.agents[1].City for location in model.locations ) - class GroupNestedInCity(Group): + class GroupNestedInCityDesigner(GroupDesigner): def nest(self): - return City + return "City" model = p2n.Model() creator = p2n.Creator(model=model) creator.create_locations( - location_classes=[City, GroupNestedInCity], + location_designers=[CityDesigner, GroupNestedInCityDesigner], delete_magic_agent_attributes=False, ) - for location in model.locations.select(model.locations.type == "City"): + for location in model.locations.select(model.locations.label == "City"): assert int(location.agents[0].group) == 0 assert int(location.agents[1].group) == 1 assert int(location.agents[2].group) == 0 assert int(location.agents[3].group) == 1 - for location in model.locations.select(model.locations.type == "Group"): + for location in model.locations.select(model.locations.label == "Group"): assert location.agents[0].group == location.agents[1].group # all members of a group are in the same city diff --git a/tests/test_location/test_location_nx_graph.py b/tests/test_location_designer/test_location_nx_graph.py similarity index 85% rename from tests/test_location/test_location_nx_graph.py rename to tests/test_location_designer/test_location_nx_graph.py index 2eddc40..30bb547 100644 --- a/tests/test_location/test_location_nx_graph.py +++ b/tests/test_location_designer/test_location_nx_graph.py @@ -7,7 +7,8 @@ def test_line_1(): model = p2n.Model() creator = p2n.Creator(model) - class LineLocation(p2n.MagicLocation): + class LineLocationDesigner(p2n.LocationDesigner): + label = "LineLocation" nxgraph = nx.path_graph(10) n_agents = None n_locations = None @@ -16,7 +17,7 @@ class LineLocation(p2n.MagicLocation): creator.create_agents(n=10) creator.create_locations( - location_classes=[LineLocation], + location_designers=[LineLocationDesigner], delete_magic_agent_attributes=False, ) @@ -38,7 +39,8 @@ def test_line_2(): model = p2n.Model() creator = p2n.Creator(model) - class LineLocation(p2n.MagicLocation): + class LineLocationDesigner(p2n.LocationDesigner): + label = "LineLocation" nxgraph = nx.path_graph(10) n_agents = None n_locations = None @@ -46,7 +48,7 @@ class LineLocation(p2n.MagicLocation): creator.create_agents(n=20) creator.create_locations( - location_classes=[LineLocation], + location_designers=[LineLocationDesigner], delete_magic_agent_attributes=False, ) @@ -80,7 +82,8 @@ def test_line_3(): model = p2n.Model() creator = p2n.Creator(model) - class LineLocation(p2n.MagicLocation): + class LineLocationDesigner(p2n.LocationDesigner): + label = "LineLocation" nxgraph = nx.path_graph(10) n_agents = 15 n_locations = None @@ -89,7 +92,7 @@ class LineLocation(p2n.MagicLocation): creator.create_agents(n=20) creator.create_locations( - location_classes=[LineLocation], + location_designers=[LineLocationDesigner], delete_magic_agent_attributes=False, ) @@ -123,7 +126,8 @@ def test_line_4(): model = p2n.Model() creator = p2n.Creator(model) - class LineLocation(p2n.MagicLocation): + class LineLocationDesigner(p2n.LocationDesigner): + label = "LineLocation" nxgraph = nx.path_graph(10) n_agents = 15 n_locations = None @@ -132,7 +136,7 @@ class LineLocation(p2n.MagicLocation): creator.create_agents(n=20) creator.create_locations( - location_classes=[LineLocation], + location_designers=[LineLocationDesigner], delete_magic_agent_attributes=False, ) @@ -166,7 +170,8 @@ def test_line_5(): model = p2n.Model() creator = p2n.Creator(model) - class LineLocation(p2n.MagicLocation): + class LineLocationDesigner(p2n.LocationDesigner): + label = "LineLocation" nxgraph = nx.path_graph(10) n_agents = 15 n_locations = None @@ -175,7 +180,7 @@ class LineLocation(p2n.MagicLocation): creator.create_agents(n=5) creator.create_locations( - location_classes=[LineLocation], + location_designers=[LineLocationDesigner], delete_magic_agent_attributes=False, ) @@ -198,12 +203,13 @@ def test_line_6(): model = p2n.Model() creator = p2n.Creator(model) - class LineLocation(p2n.MagicLocation): + class LineLocationDesigner(p2n.LocationDesigner): + label = "LineLocation" nxgraph = nx.path_graph(10) only_exact_n_agents = True creator.create_agents(n=5) - creator.create_locations(location_classes=[LineLocation]) + creator.create_locations(location_designers=[LineLocationDesigner]) assert len(model.agents) == 5 assert len(model.locations) == 0 diff --git a/tests/test_location/test_location_refine.py b/tests/test_location_designer/test_location_refine.py similarity index 86% rename from tests/test_location/test_location_refine.py rename to tests/test_location_designer/test_location_refine.py index 32d8fdb..084bf4c 100644 --- a/tests/test_location/test_location_refine.py +++ b/tests/test_location_designer/test_location_refine.py @@ -1,11 +1,14 @@ +import pytest + import pop2net as p2n +@pytest.mark.skip def test_1(): model = p2n.Model() creator = p2n.Creator(model=model) - class ClassRoom(p2n.MagicLocation): + class ClassRoom(p2n.LocationDesigner): n_locations = 3 def refine(self): @@ -21,6 +24,7 @@ def refine(self): assert len(location.agents) == 1 +@pytest.mark.skip def test_2(): model = p2n.Model() creator = p2n.Creator(model=model) @@ -28,7 +32,7 @@ def test_2(): for _ in range(10): p2n.Agent(model=model) - class ClassRoom(p2n.MagicLocation): + class ClassRoom(p2n.LocationDesigner): n_locations = 2 def refine(self): diff --git a/tests/test_location/test_location_size.py b/tests/test_location_designer/test_location_size.py similarity index 77% rename from tests/test_location/test_location_size.py rename to tests/test_location_designer/test_location_size.py index 08d571e..5c9ab81 100644 --- a/tests/test_location/test_location_size.py +++ b/tests/test_location_designer/test_location_size.py @@ -1,4 +1,5 @@ import pandas as pd +import pytest import pop2net as p2n @@ -7,11 +8,11 @@ def test_1(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): pass creator.create_agents(n=10) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) assert len(model.locations) == 1 assert len(model.locations[0].agents) == 10 @@ -21,14 +22,14 @@ def test_2(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_agents = 5 n_locations = None overcrowding = None only_exact_n_agents = False creator.create_agents(n=10) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) assert len(model.locations) == 2 assert len(model.locations[0].agents) == 5 @@ -39,14 +40,14 @@ def test_3(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_agents = 4 n_locations = None overcrowding = None only_exact_n_agents = False creator.create_agents(n=10) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) assert len(model.locations) == 2 assert len(model.locations[0].agents) == 5 @@ -57,14 +58,14 @@ def test_4(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_agents = 4 n_locations = None overcrowding = True only_exact_n_agents = False creator.create_agents(n=10) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) assert len(model.locations) == 2 assert len(model.locations[0].agents) == 5 @@ -75,14 +76,14 @@ def test_5_1(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_agents = 4 n_locations = None overcrowding = False only_exact_n_agents = False creator.create_agents(n=10) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) assert len(model.locations) == 3 assert len(model.locations[0].agents) == 4 @@ -94,14 +95,14 @@ def test_5_2(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_agents = 4 n_locations = None overcrowding = False only_exact_n_agents = True creator.create_agents(n=10) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) assert len(model.locations) == 2 assert len(model.locations[0].agents) == 4 @@ -112,14 +113,14 @@ def test_6(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_agents = 4 n_locations = None overcrowding = None only_exact_n_agents = True creator.create_agents(n=10) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) assert len(model.locations) == 2 assert len(model.locations[0].agents) == 4 @@ -130,14 +131,14 @@ def test_7(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_agents = None n_locations = 2 overcrowding = None only_exact_n_agents = False creator.create_agents(n=10) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) assert len(model.locations) == 2 assert len(model.locations[0].agents) == 5 @@ -148,14 +149,14 @@ def test_8_1(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_agents = None n_locations = 3 overcrowding = None only_exact_n_agents = False creator.create_agents(n=10) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) assert len(model.locations) == 3 assert len(model.locations[0].agents) == 4 @@ -167,14 +168,14 @@ def test_8_2(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_agents = None n_locations = 3 overcrowding = None only_exact_n_agents = False creator.create_agents(n=10) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) assert len(model.locations) == 3 assert len(model.locations[0].agents) == 4 @@ -186,14 +187,14 @@ def test_8_3(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_agents = None n_locations = 3 overcrowding = None only_exact_n_agents = False creator.create_agents(n=10) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) assert len(model.locations) == 3 assert len(model.locations[0].agents) == 4 @@ -205,14 +206,14 @@ def test_9(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_agents = 1 n_locations = 3 overcrowding = None only_exact_n_agents = False creator.create_agents(n=10) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) assert len(model.locations) == 3 assert len(model.locations[0].agents) == 1 @@ -224,14 +225,14 @@ def test_10(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_agents = 2 n_locations = 4 overcrowding = None only_exact_n_agents = False creator.create_agents(n=10) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) assert len(model.locations) == 4 assert len(model.locations[0].agents) == 2 @@ -244,14 +245,14 @@ def test_11(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_agents = 5 n_locations = 2 overcrowding = None only_exact_n_agents = False creator.create_agents(n=10) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) assert len(model.locations) == 2 assert len(model.locations[0].agents) == 5 @@ -262,14 +263,14 @@ def test_12(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_agents = 7 n_locations = 1 overcrowding = None only_exact_n_agents = False creator.create_agents(n=10) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) assert len(model.locations) == 1 assert len(model.locations[0].agents) == 7 @@ -279,14 +280,14 @@ def test_13(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_agents = 7 n_locations = 2 overcrowding = None only_exact_n_agents = False creator.create_agents(n=10) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) assert len(model.locations) == 2 assert len(model.locations[0].agents) == 7 @@ -297,14 +298,14 @@ def test_14(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_agents = 7 n_locations = 2 overcrowding = None only_exact_n_agents = True creator.create_agents(n=10) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) assert len(model.locations) == 1 assert len(model.locations[0].agents) == 7 @@ -314,14 +315,14 @@ def test_15(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_agents = 7 n_locations = 3 overcrowding = None only_exact_n_agents = False creator.create_agents(n=10) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) assert len(model.locations) == 3 assert len(model.locations[0].agents) == 7 @@ -333,14 +334,14 @@ def test_16(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_agents = 20 n_locations = 3 overcrowding = None only_exact_n_agents = False creator.create_agents(n=10) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) assert len(model.locations) == 3 assert len(model.locations[0].agents) == 10 @@ -352,14 +353,14 @@ def test_17(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_agents = None n_locations = 3 overcrowding = None only_exact_n_agents = False creator.create_agents(n=10) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) assert len(model.locations) == 3 assert len(model.locations[0].agents) == 4 @@ -371,14 +372,14 @@ def test_18(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_agents = None n_locations = 3 overcrowding = None only_exact_n_agents = False creator.create_agents(n=10) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) assert len(model.locations) == 3 assert len(model.locations[0].agents) == 4 @@ -390,14 +391,14 @@ def test_19(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_agents = None n_locations = 3 overcrowding = None only_exact_n_agents = True creator.create_agents(n=10) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) assert len(model.locations) == 3 assert len(model.locations[0].agents) == 3 @@ -409,14 +410,14 @@ def test_20(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_agents = None n_locations = 6 overcrowding = None only_exact_n_agents = True creator.create_agents(n=10) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) assert len(model.locations) == 6 assert len(model.locations[0].agents) == 1 @@ -431,14 +432,14 @@ def test_21(): creator = p2n.Creator(model) inspector = p2n.NetworkInspector(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_agents = None n_locations = 6 overcrowding = None only_exact_n_agents = False creator.create_agents(n=10) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) inspector.plot_bipartite_network() @@ -456,7 +457,7 @@ def test_split_1(): creator = p2n.Creator(model) inspector = p2n.NetworkInspector(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_agents = None n_locations = None overcrowding = None @@ -472,7 +473,7 @@ def split(self, agent): ) creator.create_agents(df=df) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) inspector.plot_bipartite_network() @@ -489,7 +490,7 @@ def test_split_2(): creator = p2n.Creator(model) inspector = p2n.NetworkInspector(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_agents = 2 n_locations = None overcrowding = None @@ -505,7 +506,7 @@ def split(self, agent): ) creator.create_agents(df=df) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) inspector.plot_bipartite_network() @@ -517,12 +518,13 @@ def split(self, agent): assert len(model.locations[4].agents) == 2 +# TODO: Maybe bring back the compatibility of n_locations and split in the future +@pytest.mark.skip(reason="n_locations and split are not compatible any more") def test_split_3(): model = p2n.Model() creator = p2n.Creator(model) - inspector = p2n.NetworkInspector(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_agents = 2 n_locations = 1 overcrowding = None @@ -538,9 +540,7 @@ def split(self, agent): ) creator.create_agents(df=df) - creator.create_locations(location_classes=[TestLocation]) - - inspector.plot_bipartite_network() + creator.create_locations(location_designers=[TestLocation]) assert len(model.locations) == 3 assert len(model.locations[0].agents) == 2 @@ -552,12 +552,12 @@ def test_overcrowding_1(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_agents = 4 overcrowding = True creator.create_agents(n=10) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) assert len(model.locations) == 2 assert len(model.locations[0].agents) == 5 @@ -568,12 +568,12 @@ def test_overcrowding_2(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_agents = 4 overcrowding = False creator.create_agents(n=10) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) assert len(model.locations) == 3 assert len(model.locations[0].agents) == 4 @@ -585,12 +585,12 @@ def test_overcrowding_3(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_agents = 4 overcrowding = None creator.create_agents(n=10) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) assert len(model.locations) == 2 assert len(model.locations[0].agents) == 5 @@ -601,15 +601,15 @@ def test_melt_1(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): def melt(self): - class TestMeltLocation0(p2n.MeltLocation): + class TestMeltLocation0(p2n.MeltLocationDesigner): n_agents = 1 def filter(self, agent): return agent.opinion == 0 - class TestMeltLocation1(p2n.MeltLocation): + class TestMeltLocation1(p2n.MeltLocationDesigner): n_agents = 1 def filter(self, agent): @@ -625,7 +625,7 @@ def filter(self, agent): agent = p2n.Agent(model) agent.opinion = 1 - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) assert len(model.locations) == 5 assert len(model.locations[0].agents) == 2 @@ -639,16 +639,16 @@ def test_melt_2(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): def melt(self): - class TestMeltLocation0(p2n.MeltLocation): + class TestMeltLocation0(p2n.MeltLocationDesigner): n_agents = 1 n_locations = 3 def filter(self, agent): return agent.opinion == 0 - class TestMeltLocation1(p2n.MeltLocation): + class TestMeltLocation1(p2n.MeltLocationDesigner): n_agents = 1 n_locations = 3 @@ -665,7 +665,7 @@ def filter(self, agent): agent = p2n.Agent(model) agent.opinion = 1 - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) assert len(model.locations) == 3 assert len(model.locations[0].agents) == 2 @@ -677,17 +677,17 @@ def test_melt_3(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_locations = 4 def melt(self): - class TestMeltLocation0(p2n.MeltLocation): + class TestMeltLocation0(p2n.MeltLocationDesigner): n_agents = 1 def filter(self, agent): return agent.opinion == 0 - class TestMeltLocation1(p2n.MeltLocation): + class TestMeltLocation1(p2n.MeltLocationDesigner): n_agents = 1 def filter(self, agent): @@ -703,7 +703,7 @@ def filter(self, agent): agent = p2n.Agent(model) agent.opinion = 1 - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) assert len(model.locations) == 4 assert len(model.locations[0].agents) == 2 diff --git a/tests/test_location/test_location_split.py b/tests/test_location_designer/test_location_split.py similarity index 94% rename from tests/test_location/test_location_split.py rename to tests/test_location_designer/test_location_split.py index c8aca4c..cd95ad5 100644 --- a/tests/test_location/test_location_split.py +++ b/tests/test_location_designer/test_location_split.py @@ -15,12 +15,12 @@ def test_1(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): def split(self, agent): return agent.status creator.create_agents(df=df) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) assert len(model.locations) == 3 assert len(model.agents) == 6 @@ -47,12 +47,12 @@ def test_2(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): def split(self, agent): return [agent.status, agent.sex] creator.create_agents(df=df) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) assert len(model.locations) == 5 assert len(model.agents) == 6 @@ -165,7 +165,7 @@ def test_3(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): def split(self, agent): if agent.relevance == 1: return agent.status @@ -173,7 +173,7 @@ def split(self, agent): return agent.sex creator.create_agents(df=df) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) assert len(model.locations) == 5 assert len(model.agents) == 6 diff --git a/tests/test_location/test_location_stick_together.py b/tests/test_location_designer/test_location_stick_together.py similarity index 87% rename from tests/test_location/test_location_stick_together.py rename to tests/test_location_designer/test_location_stick_together.py index be711a3..0391703 100644 --- a/tests/test_location/test_location_stick_together.py +++ b/tests/test_location_designer/test_location_stick_together.py @@ -6,7 +6,7 @@ def test_1(): df = pd.DataFrame({"status": ["pupil", "pupil", "pupil", "pupil"], "class_id": [1, 2, 1, 2]}) - class Classroom(p2n.MagicLocation): + class Classroom(p2n.LocationDesigner): n_agents = 2 def stick_together(self, agent): @@ -14,7 +14,7 @@ def stick_together(self, agent): model = p2n.Model() creator = p2n.Creator(model=model) - creator.create(df=df, location_classes=[Classroom]) + creator.create(df=df, location_designers=[Classroom]) assert len(model.agents) == 4 assert len(model.locations) == 2 @@ -23,7 +23,7 @@ def stick_together(self, agent): assert len(location.agents) == 2 for agent in model.agents: - assert agent.neighbors(location_classes=[Classroom])[0].class_id == agent.class_id + assert agent.neighbors(location_labels=["Classroom"])[0].class_id == agent.class_id inspector = p2n.NetworkInspector(model) inspector.plot_bipartite_network() @@ -36,7 +36,7 @@ def test_2(): {"status": ["pupil", "pupil", "pupil", "pupil", "pupil"], "class_id": [1, 2, 1, 2, 1]} ) - class Classroom(p2n.MagicLocation): + class Classroom(p2n.LocationDesigner): n_agents = 2 def stick_together(self, agent): @@ -44,7 +44,7 @@ def stick_together(self, agent): model = p2n.Model() creator = p2n.Creator(model=model) - creator.create(df=df, location_classes=[Classroom]) + creator.create(df=df, location_designers=[Classroom]) inspector = p2n.NetworkInspector(model) inspector.plot_bipartite_network() inspector.plot_agent_network(agent_attrs=df.columns, agent_color="class_id") @@ -71,7 +71,7 @@ def test_3(): } ) - class Classroom(p2n.MagicLocation): + class Classroom(p2n.LocationDesigner): n_agents = 2 def split(self, agent): @@ -82,7 +82,7 @@ def stick_together(self, agent): model = p2n.Model() creator = p2n.Creator(model=model) - creator.create(df=df, location_classes=[Classroom]) + creator.create(df=df, location_designers=[Classroom]) inspector = p2n.NetworkInspector(model) inspector.plot_bipartite_network() inspector.plot_agent_network(agent_attrs=df.columns, agent_color="class_id") @@ -110,12 +110,12 @@ def test_4(): ) # location without stick_together() - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_locations = 5 creator.create_agents(df=df) creator.create_locations( - location_classes=[TestLocation], + location_designers=[TestLocation], delete_magic_agent_attributes=False, ) @@ -135,7 +135,7 @@ class TestLocation(p2n.MagicLocation): inspector = p2n.NetworkInspector(model=model) # location with stick_together() - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): n_locations = 5 def stick_together(self, agent): @@ -143,7 +143,7 @@ def stick_together(self, agent): creator.create_agents(df=df) creator.create_locations( - location_classes=[TestLocation], + location_designers=[TestLocation], delete_magic_agent_attributes=False, ) diff --git a/tests/test_location/test_location_weight.py b/tests/test_location_designer/test_location_weight.py similarity index 88% rename from tests/test_location/test_location_weight.py rename to tests/test_location_designer/test_location_weight.py index 0b4716b..9372093 100644 --- a/tests/test_location/test_location_weight.py +++ b/tests/test_location_designer/test_location_weight.py @@ -13,12 +13,12 @@ def test_1(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): def weight(self, agent): return 1 creator.create_agents(df=df) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) assert len(model.locations) == 1 assert len(model.agents) == 5 @@ -44,7 +44,7 @@ def test_2(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): def weight(self, agent): if agent.status == "A": return 1 @@ -52,7 +52,7 @@ def weight(self, agent): return 5 creator.create_agents(df=df) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) assert len(model.locations) == 1 assert len(model.agents) == 5 @@ -81,12 +81,12 @@ def test_3(): model = p2n.Model() creator = p2n.Creator(model) - class TestLocation(p2n.MagicLocation): + class TestLocation(p2n.LocationDesigner): def weight(self, agent): return agent.status creator.create_agents(df=df) - creator.create_locations(location_classes=[TestLocation]) + creator.create_locations(location_designers=[TestLocation]) assert len(model.locations) == 1 assert len(model.agents) == 5 diff --git a/tests/test_location_designer/test_mutate.py b/tests/test_location_designer/test_mutate.py new file mode 100644 index 0000000..ebfd397 --- /dev/null +++ b/tests/test_location_designer/test_mutate.py @@ -0,0 +1,52 @@ +import pytest + +import pop2net as p2n + + +@pytest.fixture +def model(): + model = p2n.Model() + creator = p2n.Creator(model) + + class NormalLocation(p2n.LocationDesigner): + pass + + class NormalLocation2(p2n.LocationDesigner): + pass + + class MutationLocation(p2n.LocationDesigner): + def mutate(self): + return {"mutated1": [1, 2, 3], "mutated2": ["x", "y", "z"]} + + creator.create_agents(n=10) + creator.create_locations( + location_designers=[ + NormalLocation, + MutationLocation, + NormalLocation2, + ] + ) + return model + + +def test_n_locations(model): + assert len(model.locations) == 11 + + +def test_positions_and_labels(model): + assert model.locations[0].label == "NormalLocation" + assert model.locations[1].label == "MutationLocation0" + assert model.locations[5].label == "MutationLocation4" + assert model.locations[9].label == "MutationLocation8" + assert model.locations[10].label == "NormalLocation2" + + +def test_mutated_values(model): + assert model.locations[1].mutated1 == 1 + assert model.locations[1].mutated2 == "x" + + assert model.locations[5].mutated1 == 2 + assert model.locations[5].mutated2 == "y" + + assert model.locations[9].mutated1 == 3 + assert model.locations[9].mutated2 == "z" diff --git a/tests/test_model/test_model_connect_and_disconnect.py b/tests/test_model/test_model_connect_and_disconnect.py index 7f1a6e4..635c0c7 100644 --- a/tests/test_model/test_model_connect_and_disconnect.py +++ b/tests/test_model/test_model_connect_and_disconnect.py @@ -79,7 +79,7 @@ class School(p2n.Location): location_cls=School, ) - model.disconnect_agents(agents, location_classes=[Home], remove_locations=False) + model.disconnect_agents(agents, location_labels=["Home"], remove_locations=False) assert len(model.agents) == 3 @@ -94,7 +94,7 @@ class School(p2n.Location): assert len(agent2.locations) == 1 assert len(agent3.locations) == 0 - model.disconnect_agents(agents, location_classes=[School], remove_locations=False) + model.disconnect_agents(agents, location_labels=["School"], remove_locations=False) assert len(model.agents) == 3 @@ -110,7 +110,7 @@ class School(p2n.Location): assert len(agent3.locations) == 0 model.connect_agents(agents=agents, location_cls=School) - model.disconnect_agents(agents=[agent1, agent2], location_classes=[School]) + model.disconnect_agents(agents=[agent1, agent2], location_labels=["School"]) assert len(model.agents) == 3 @@ -151,7 +151,7 @@ class School(p2n.Location): location_cls=School, ) - model.disconnect_agents(agents, location_classes=[School], remove_locations=True) + model.disconnect_agents(agents, location_labels=["School"], remove_locations=True) assert len(model.agents) == 3 @@ -164,7 +164,7 @@ class School(p2n.Location): assert len(agent2.locations) == 1 assert len(agent3.locations) == 1 - model.disconnect_agents(agents, location_classes=[Home], remove_locations=True) + model.disconnect_agents(agents, location_labels=["Home"], remove_locations=True) assert len(model.agents) == 3 @@ -222,8 +222,8 @@ class School(p2n.Location): pass assert len(agent1.shared_locations(agent2)) == 0 - assert len(agent1.shared_locations(agent=agent2, location_classes=[Home])) == 0 - assert len(agent1.shared_locations(agent=agent2, location_classes=[School])) == 0 + assert len(agent1.shared_locations(agent=agent2, location_labels=["Home"])) == 0 + assert len(agent1.shared_locations(agent=agent2, location_labels=["School"])) == 0 model.connect_agents( agents=[agent1, agent2], @@ -231,8 +231,8 @@ class School(p2n.Location): ) assert len(agent1.shared_locations(agent=agent2)) == 1 - assert len(agent1.shared_locations(agent=agent2, location_classes=[Home])) == 1 - assert len(agent1.shared_locations(agent=agent2, location_classes=[School])) == 0 + assert len(agent1.shared_locations(agent=agent2, location_labels=["Home"])) == 1 + assert len(agent1.shared_locations(agent=agent2, location_labels=["School"])) == 0 model.connect_agents( agents=[agent1, agent2], @@ -240,11 +240,11 @@ class School(p2n.Location): ) assert len(agent1.shared_locations(agent=agent2)) == 2 - assert len(agent1.shared_locations(agent=agent2, location_classes=[Home])) == 1 - assert len(agent1.shared_locations(agent=agent2, location_classes=[School])) == 1 + assert len(agent1.shared_locations(agent=agent2, location_labels=["Home"])) == 1 + assert len(agent1.shared_locations(agent=agent2, location_labels=["School"])) == 1 model.disconnect_agents(agents=[agent1, agent2], remove_locations=True) assert len(agent1.shared_locations(agent=agent2)) == 0 - assert len(agent1.shared_locations(agent=agent2, location_classes=[Home])) == 0 - assert len(agent1.shared_locations(agent=agent2, location_classes=[School])) == 0 + assert len(agent1.shared_locations(agent=agent2, location_labels=["Home"])) == 0 + assert len(agent1.shared_locations(agent=agent2, location_labels=["School"])) == 0 diff --git a/tests/test_model/test_model_enable_warnings.py b/tests/test_model/test_model_enable_warnings.py index ba37f08..d4cfac6 100644 --- a/tests/test_model/test_model_enable_warnings.py +++ b/tests/test_model/test_model_enable_warnings.py @@ -10,7 +10,7 @@ def test_enable_warnings_true(): model = p2n.Model(enable_p2n_warnings=True) creator = p2n.Creator(model) - class LineLocation(p2n.MagicLocation): + class LineLocation(p2n.LocationDesigner): nxgraph = nx.path_graph(10) n_agents = 10 @@ -18,7 +18,7 @@ class LineLocation(p2n.MagicLocation): with pytest.warns(UserWarning) as record: creator.create_locations( - location_classes=[LineLocation], + location_designers=[LineLocation], delete_magic_agent_attributes=False, ) assert len(record) > 0, "Expected a warning but none were raised." @@ -28,7 +28,7 @@ def test_enable_warnings_false(): model = p2n.Model(enable_p2n_warnings=False) creator = p2n.Creator(model) - class LineLocation(p2n.MagicLocation): + class LineLocation(p2n.LocationDesigner): nxgraph = nx.path_graph(10) n_agents = 10 @@ -37,7 +37,7 @@ class LineLocation(p2n.MagicLocation): with warnings.catch_warnings(record=True) as record: warnings.simplefilter("always") creator.create_locations( - location_classes=[LineLocation], + location_designers=[LineLocation], delete_magic_agent_attributes=False, ) assert len(record) == 0, "Expected no warnings but warnings were raised." diff --git a/tests/test_utils/test_utils.py b/tests/test_utils/test_utils.py index b23aed3..9f268c3 100644 --- a/tests/test_utils/test_utils.py +++ b/tests/test_utils/test_utils.py @@ -126,7 +126,7 @@ def test_to_list(): def test_get_cls_as_str(): - class MyLocation(p2n.MagicLocation): + class MyLocation(p2n.LocationDesigner): pass assert utils._get_cls_as_str(MyLocation) == "MyLocation" diff --git a/tests/test_weighting.py b/tests/test_weighting/test_weighting.py similarity index 100% rename from tests/test_weighting.py rename to tests/test_weighting/test_weighting.py diff --git a/tests/test_weighting_during_sim.py b/tests/test_weighting/test_weighting_during_sim.py similarity index 97% rename from tests/test_weighting_during_sim.py rename to tests/test_weighting/test_weighting_during_sim.py index c296b66..5e7dc61 100644 --- a/tests/test_weighting_during_sim.py +++ b/tests/test_weighting/test_weighting_during_sim.py @@ -131,6 +131,8 @@ def update(self): def test_weighting_during_sim7(): class WeightedLocation(p2n.Location): + label = "WeightedLocation" + def weight(self, agent): return self.model.t @@ -143,7 +145,7 @@ def setup(self): self.location2.add_agent(agent=self.agent, weight=10) def step(self): - self.update_weights(location_classes=[WeightedLocation]) + self.update_weights(location_labels=["WeightedLocation"]) def update(self): assert self.location.get_weight(agent=self.agent) == self.t