Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix some bugs and make all notebook docs update-to-date #106

Merged
merged 8 commits into from
Feb 16, 2025
6 changes: 3 additions & 3 deletions .github/workflows/gh-page.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ jobs:
virtualenvs-in-project: true
- name: Install dependencies
run: |
poetry config http-basic.mkdocs-material-insiders username "${{ secrets.MKDOCS_INSIDER }}"
poetry install
poetry run pip install --upgrade pip
poetry run pip install git+https://x-access-token:${{ secrets.MKDOCS_INSIDER }}@github.com/squidfunk/mkdocs-material-insiders.git
set -e
poetry run pip install git+https://${{ secrets.GH_TOKEN }}@github.com/squidfunk/mkdocs-material-insiders.git
poetry install
- name: Deploy documentation
run: poetry run mkdocs gh-deploy --force
env:
Expand Down
5 changes: 0 additions & 5 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
repos:
- repo: https://github.com/PyCQA/flake8
rev: '7.1.1'
hooks:
- id: flake8
args: ['--max-line-length=88', '--extend-ignore=E203,E501,W503', '--exclude=.venv']
- repo: https://github.com/PyCQA/isort
rev: '6.0.0'
hooks:
Expand Down
8 changes: 5 additions & 3 deletions abses/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
"BaseNature",
"PatchModule",
"Actor",
"Decision",
"ActorsList",
"PatchCell",
"perception",
Expand All @@ -30,10 +29,13 @@
"Experiment",
"load_data",
]
__version__ = "v0.7.0"

from importlib.metadata import version

__version__ = f"v{version('abses')}"


from .actor import Actor, alive_required, perception
from .decision import Decision
from .experiment import Experiment
from .human import BaseHuman
from .main import MainModel
Expand Down
41 changes: 7 additions & 34 deletions abses/actor.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,7 @@

from abses._bases.errors import ABSESpyError
from abses._bases.objects import _BaseObj
from abses.decision import _DecisionFactory
from abses.links import TargetName, _LinkNodeActor, _LinkNodeCell
from abses.tools.func import make_list
from abses.links import TargetName, _LinkNodeActor

if TYPE_CHECKING:
from abses.cells import PatchCell, Pos
Expand Down Expand Up @@ -66,7 +64,9 @@ def alive_required(method):

@wraps(method)
def wrapper(self, *args, **kwargs) -> Any:
return method(self, *args, **kwargs) if self.alive else None
actor = self if isinstance(self, Actor) else getattr(self, "actor")
alive = actor.alive
return method(self, *args, **kwargs) if alive else None

return wrapper

Expand Down Expand Up @@ -94,9 +94,7 @@ def perception_result(name, result, nodata: Any = 0.0) -> Any:


def perception(
decorated_func: Optional[Callable[..., Any]] = None,
*,
nodata: Optional[Any] = None,
decorated_func: Optional[Callable[..., Any]] = None, *, nodata: Optional[Any] = None
) -> Callable[..., Any]:
"""
Change the decorated function into a perception attribute.
Expand Down Expand Up @@ -148,34 +146,22 @@ class Actor(mg.GeoAgent, _BaseObj, _LinkNodeActor):
Kills the actor.
"""

# when checking the rules
__decisions__ = None

def __init__(
self,
model: MainModel[Any, Any],
observer: bool = True,
**kwargs,
self, model: MainModel[Any, Any], observer: bool = True, **kwargs
) -> None:
_BaseObj.__init__(self, model, observer=observer)
crs = kwargs.pop("crs", model.nature.crs)
geometry = kwargs.pop("geometry", None)
mg.GeoAgent.__init__(self, model=model, geometry=geometry, crs=crs)
_LinkNodeActor.__init__(self)
self._cell: Optional[PatchCell] = None
self._decisions: _DecisionFactory = self._setup_decisions()
self._alive: bool = True
self._birth_tick: int = self.time.tick
self._setup()

def __repr__(self) -> str:
return f"<{self.breed} [{self.unique_id}]>"

def _setup_decisions(self) -> _DecisionFactory:
"""Decisions that this actor makes."""
decisions = make_list(getattr(self, "__decisions__", None))
return _DecisionFactory(self, decisions)

@property
def geo_type(self) -> Optional[GeoType]:
"""The type of the geo info."""
Expand Down Expand Up @@ -203,14 +189,6 @@ def alive(self) -> bool:
"""Whether the actor is alive."""
return self._alive

@property
def decisions(self) -> _DecisionFactory:
"""The decisions that this actor makes."""
return self._decisions

# alias of decisions
d = decisions

@property
def layer(self) -> Optional[PatchModule]:
"""Get the layer where the actor is located."""
Expand All @@ -229,8 +207,6 @@ def at(self) -> PatchCell | None:
@at.setter
def at(self, cell: PatchCell) -> None:
"""Set the cell where the actor is located."""
if not isinstance(cell, _LinkNodeCell):
raise TypeError(f"{cell} is not a cell.")
if self not in cell.agents:
raise ABSESpyError(
"Cannot set location directly because the actor is not added to the cell."
Expand Down Expand Up @@ -281,10 +257,7 @@ def age(self) -> int:

@alive_required
def get(
self,
attr: str,
target: Optional[TargetName] = None,
default: Any = ...,
self, attr: str, target: Optional[TargetName] = None, default: Any = ...
) -> Any:
"""
Gets attribute value from target.
Expand Down
40 changes: 13 additions & 27 deletions abses/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,17 +61,21 @@
class _AgentsContainer:
"""AgentsContainer for the main model."""

def __init__(
self,
model: MainModel[Any, Any],
max_len: None | int = None,
):
def __init__(self, model: MainModel[Any, Any], max_len: None | int = None):
if not isinstance(model, Model):
raise TypeError(f"{model} is not a Mesa Model.")
self._model: MainModel = model
self._agents = model._all_agents
self._max_length = max_len

def __getattr__(self, name: str) -> Any:
"""Get an attribute from the container."""
if not name.startswith("_") and hasattr(self._agents, name):
return getattr(self._agents, name)
raise AttributeError(
f"'{self.__class__.__name__}' object has no attribute '{name}'"
)

def __len__(self) -> int:
return len(self._agents)

Expand Down Expand Up @@ -118,14 +122,6 @@ def __getitem__(self, breeds: Optional[Breeds]) -> ActorsList[Actor]:
except KeyError:
return ActorsList(model=self.model, objs=[])

def __getattr__(self, name: str) -> Any:
"""Get an attribute from the container."""
if not name.startswith("_") and hasattr(self._agents, name):
return getattr(self._agents, name)
raise AttributeError(
f"'{self.__class__.__name__}' object has no attribute '{name}'"
)

@property
def crs(self) -> pyproj.CRS:
"""Returns the current CRS."""
Expand Down Expand Up @@ -189,10 +185,7 @@ def _new_one(
raise TypeError(f"{agent_cls} is not a subclass of Actor.")
self._check_full()
agent = agent_cls(
model=self.model,
geometry=geometry,
crs=self.model.nature.crs,
**kwargs,
model=self.model, geometry=geometry, crs=self.model.nature.crs, **kwargs
)
self._add_one(agent)
return agent
Expand Down Expand Up @@ -372,7 +365,7 @@ def new_from_graph(
mapping = {}
for node, attr in graph.nodes(data=True):
unique_id = get_node_unique_id(node=node)
actor = self._new_one(unique_id, agent_cls=actor_cls, **attr)
actor = self._new_one(unique_id=unique_id, agent_cls=actor_cls, **attr)
actors.append(actor)
mapping[unique_id] = actor
self.model.human.add_links_from_graph(
Expand Down Expand Up @@ -417,11 +410,7 @@ def new_from_gdf(
agents = []
for _, row in gdf.iterrows():
geometry = row[geo_col]
new_agent = self._new_one(
geometry=geometry,
agent_cls=agent_cls,
**kwargs,
)
new_agent = self._new_one(geometry=geometry, agent_cls=agent_cls, **kwargs)
new_agent.crs = self.crs

for col, name in set_attributes.items():
Expand All @@ -435,10 +424,7 @@ class _CellAgentsContainer(_AgentsContainer):
"""Container for agents located at cells."""

def __init__(
self,
model: MainModel[Any, Any],
cell: PatchCell,
max_len: int | None = None,
self, model: MainModel[Any, Any], cell: PatchCell, max_len: int | None = None
):
super().__init__(model, max_len)
self._agents = AgentSet([], random=model.random)
Expand Down
Loading
Loading