Skip to content

Commit

Permalink
Merge pull request #83 from ABSESpy/dev
Browse files Browse the repository at this point in the history
Version 0.6.5: Fixed two bugs.
  • Loading branch information
SongshGeo authored May 17, 2024
2 parents a4e61f1 + 3e4f33a commit 71960c2
Show file tree
Hide file tree
Showing 10 changed files with 433 additions and 834 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@

<a id='changelog-0.6.5'></a>
# 0.6.5 — 2024-05-17

## Fixed bugs

- [x] #bug🐛 solving situation when entities with prob are not enough for expected size in random choose
- [x] #bug🐛 Fixed shape `(1, x)` natural patch squeezed bug

<a id='changelog-0.6.4'></a>
# 0.6.4 — 2024-05-16

Expand Down
2 changes: 1 addition & 1 deletion abses/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"load_data",
"logger",
]
__version__ = "v0.6.4"
__version__ = "v0.6.5"

from ._bases.logging import logger
from .actor import Actor, alive_required, perception
Expand Down
7 changes: 4 additions & 3 deletions abses/patch.py
Original file line number Diff line number Diff line change
Expand Up @@ -614,12 +614,13 @@ def _add_attribute(
flipud: bool = False,
apply_mask: bool = False,
) -> None:
data = np.squeeze(data)
if data.shape != self.shape2d:
try:
data = data.reshape(self.shape2d)
except ValueError as e:
raise ValueError(
f"Data shape does not match raster shape. "
f"Expected {self.shape2d}, received {data.shape}."
)
) from e
if apply_mask:
set_null_values(data, ~self.mask)
if attr_name is None:
Expand Down
32 changes: 31 additions & 1 deletion abses/random.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
# GitHub : https://github.com/SongshGeo
# Website: https://cv.songshgeo.com/

"""在列表中随机操作主体
"""

from __future__ import annotations

from itertools import combinations
Expand Down Expand Up @@ -89,7 +92,8 @@ def clean_p(self, prob: Union[np.ndarray, str]) -> np.ndarray:
"""
if isinstance(prob, str):
prob = self.actors.array(attr=prob)
prob = np.array(make_list(prob))
else:
prob = np.array(make_list(prob))
length = len(prob)
prob = np.nan_to_num(prob)
prob[prob < 0] = 0.0
Expand All @@ -115,6 +119,7 @@ def choice(
replace: bool = False,
as_list: bool = False,
when_empty: WHEN_EMPTY = "raise exception",
double_check: bool = False,
) -> Optional[Actor | ActorsList[Actor]]:
"""Randomly choose one or more actors from the current self object.
Expand Down Expand Up @@ -154,8 +159,14 @@ def choice(
raise ABSESpyError(
f"Trying to choose {size} actors from {self.actors}."
)
# 有概率的时候,先清理概率
if prob is not None:
prob = self.clean_p(prob=prob)
valid_prob = prob.astype(bool)
# 特别处理有概率的主体数量不足预期的情况
if valid_prob.sum() < size and not replace:
return self._when_p_not_enough(double_check, valid_prob, size)
# 其他情况就正常随机选择
chosen = self.generator.choice(
self.actors, size=size, replace=replace, p=prob
)
Expand All @@ -165,6 +176,25 @@ def choice(
else self._to_actors_list(chosen)
)

def _when_p_not_enough(self, double_check, valid_prob, size):
if not double_check:
raise ABSESpyError(
f"Only {valid_prob.sum()} entities have possibility, "
f"but {size} entities are expected. "
"Please check the probability settings.\n"
"If you want to choose with replacement, set `replace=True`.\n"
"If you want to choose with equal probability, set `prob=None`.\n"
"If you want to choose the valid entities firstly, "
"and then choose others equally, set `double_check=True'`."
)
first_chosen = self.actors.select(valid_prob)
others = self.actors.select(~valid_prob)
remain_size = size - len(first_chosen)
second_chosen = self.generator.choice(
others, remain_size, replace=False
)
return self._to_actors_list([*first_chosen, *second_chosen])

def new(
self,
actor_cls: Type[Actor],
Expand Down
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ description: "Agent-Based Social-ecological systems Modelling Framework in Pytho

<!-- Language: [English Readme](#) | [简体中文](README_ch) -->

**Date**: January. 11, 2024, **Version**: 0.6.4
**Date**: January. 11, 2024, **Version**: 0.6.5

**Useful links**: [Install](home/Installation.md) | [Source Repository](https://github.com/ABSESpy/ABSESpy) | [Issues & Ideas](https://github.com/ABSESpy/ABSESpy/issues) | [Q&A Support](https://github.com/ABSESpy/ABSESpy/discussions)

Expand Down
554 changes: 59 additions & 495 deletions docs/tutorial/advanced/geodata.ipynb

Large diffs are not rendered by default.

622 changes: 305 additions & 317 deletions poetry.lock

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ line_length = 79

[tool.poetry]
name = "abses"
version = "0.6.4"
version = "0.6.5"
description = "ABSESpy makes it easier to build artificial Social-ecological systems with real GeoSpatial datasets and fully incorporate human behaviour."
authors = ["Shuang Song <[email protected]>"]
license = "Apache 2.0 License"
Expand All @@ -51,15 +51,15 @@ abses = "hydra_plugins.abses_searchpath_plugin:ABSESpySearchPathPlugin"
python = ">=3.9,<3.12"
netcdf4 = ">=1.6"
hydra-core = "~1.3"
mesa-geo = "~0.7"
xarray = "~2024"
mesa-geo = ">=0.6"
xarray = ">=2023"
fiona = ">1.8"
loguru = "~0.7"
loguru = ">=0.7"
rioxarray = ">=0.13"
pendulum = "~2"
geopandas = "~0"
typing-extensions = "~4"
fontawesome = "~5"
fontawesome = ">=5"
seaborn = ">=0.13"

[tool.poetry.group.dev.dependencies]
Expand Down
18 changes: 9 additions & 9 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ loguru==0.7.2 ; python_version >= "3.9" and python_version < "3.12"
markdown-it-py==3.0.0 ; python_version >= "3.9" and python_version < "3.12"
markupsafe==2.1.5 ; python_version >= "3.9" and python_version < "3.12"
matplotlib-inline==0.1.7 ; python_version >= "3.9" and python_version < "3.12"
matplotlib==3.8.4 ; python_version >= "3.9" and python_version < "3.12"
matplotlib==3.9.0 ; python_version >= "3.9" and python_version < "3.12"
mdurl==0.1.2 ; python_version >= "3.9" and python_version < "3.12"
mesa-geo==0.7.1 ; python_version >= "3.9" and python_version < "3.12"
mesa-viz-tornado==0.1.3 ; python_version >= "3.9" and python_version < "3.12"
Expand All @@ -73,7 +73,7 @@ parso==0.8.4 ; python_version >= "3.9" and python_version < "3.12"
pendulum==2.1.2 ; python_version >= "3.9" and python_version < "3.12"
pexpect==4.9.0 ; python_version >= "3.9" and python_version < "3.12" and sys_platform != "win32"
pillow==10.3.0 ; python_version >= "3.9" and python_version < "3.12"
platformdirs==4.2.1 ; python_version >= "3.9" and python_version < "3.12"
platformdirs==4.2.2 ; python_version >= "3.9" and python_version < "3.12"
prompt-toolkit==3.0.43 ; python_version >= "3.9" and python_version < "3.12"
psutil==5.9.8 ; python_version >= "3.9" and python_version < "3.12"
ptyprocess==0.7.0 ; python_version >= "3.9" and python_version < "3.12" and sys_platform != "win32"
Expand All @@ -93,7 +93,7 @@ rasterio==1.3.10 ; python_version >= "3.9" and python_version < "3.12"
reacton==1.8.3 ; python_version >= "3.9" and python_version < "3.12"
referencing==0.35.1 ; python_version >= "3.9" and python_version < "3.12"
requests==2.31.0 ; python_version >= "3.9" and python_version < "3.12"
rich-click==1.8.1 ; python_version >= "3.9" and python_version < "3.12"
rich-click==1.8.2 ; python_version >= "3.9" and python_version < "3.12"
rich==13.7.1 ; python_version >= "3.9" and python_version < "3.12"
rioxarray==0.15.0 ; python_version >= "3.9" and python_version < "3.12"
rpds-py==0.18.1 ; python_version >= "3.9" and python_version < "3.12"
Expand All @@ -105,10 +105,10 @@ shapely==2.0.4 ; python_version >= "3.9" and python_version < "3.12"
six==1.16.0 ; python_version >= "3.9" and python_version < "3.12"
sniffio==1.3.1 ; python_version >= "3.9" and python_version < "3.12"
snuggs==1.4.7 ; python_version >= "3.9" and python_version < "3.12"
solara-server[dev,starlette]==1.32.1 ; python_version >= "3.9" and python_version < "3.12"
solara-ui==1.32.1 ; python_version >= "3.9" and python_version < "3.12"
solara-ui[all]==1.32.1 ; python_version >= "3.9" and python_version < "3.12"
solara==1.32.1 ; python_version >= "3.9" and python_version < "3.12"
solara-server[dev,starlette]==1.32.2 ; python_version >= "3.9" and python_version < "3.12"
solara-ui==1.32.2 ; python_version >= "3.9" and python_version < "3.12"
solara-ui[all]==1.32.2 ; python_version >= "3.9" and python_version < "3.12"
solara==1.32.2 ; python_version >= "3.9" and python_version < "3.12"
soupsieve==2.5 ; python_version >= "3.9" and python_version < "3.12"
stack-data==0.6.3 ; python_version >= "3.9" and python_version < "3.12"
starlette==0.37.2 ; python_version >= "3.9" and python_version < "3.12"
Expand All @@ -127,6 +127,6 @@ wcwidth==0.2.13 ; python_version >= "3.9" and python_version < "3.12"
websockets==12.0 ; python_version >= "3.9" and python_version < "3.12"
widgetsnbextension==4.0.10 ; python_version >= "3.9" and python_version < "3.12"
win32-setctime==1.1.0 ; python_version >= "3.9" and python_version < "3.12" and sys_platform == "win32"
xarray==2024.3.0 ; python_version >= "3.9" and python_version < "3.12"
xarray==2024.5.0 ; python_version >= "3.9" and python_version < "3.12"
xyzservices==2024.4.0 ; python_version >= "3.9" and python_version < "3.12"
zipp==3.18.1 ; python_version >= "3.9" and python_version < "3.10"
zipp==3.18.2 ; python_version >= "3.9" and python_version < "3.10"
12 changes: 10 additions & 2 deletions tests/api/test_random.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from abses import Actor, MainModel
from abses._bases.errors import ABSESpyError
from abses.sequences import ActorsList


class TestRandomActorsList:
Expand Down Expand Up @@ -67,6 +68,7 @@ def test_clean_p(self, main: MainModel, actors_num, p, expected_p):

# assert
assert np.allclose(possibilities, expected_p)
assert np.sum(possibilities) == 1

@pytest.mark.parametrize(
"num, size, replace",
Expand All @@ -89,21 +91,27 @@ def test_bad_choose(self, main: MainModel, num, size, replace):
(2, [0.1, 0.4], False, [0, 1]),
(2, [np.nan, 1], True, [1, 1]),
(1, [np.nan, 1], False, [1]),
(2, [0, 1], False, [0, 1]),
],
ids=[
"choose all two",
"expected two, but only one to choose",
"only one to choose",
"double_check choosing",
],
)
def test_random_choose(self, main: MainModel, size, p, replace, expected):
"""测试从列表中随机抽取"""
# arrange
agents = main.agents.new(Actor, num=2)
agents: ActorsList = main.agents.new(Actor, num=2)

# act
chosen = agents.random.choice(
size=size, prob=p, as_list=True, replace=replace
size=size,
prob=p,
as_list=True,
replace=replace,
double_check=True,
)

# assert
Expand Down

0 comments on commit 71960c2

Please sign in to comment.