diff --git a/CHANGELOG.md b/CHANGELOG.md index 4801cad..f19fe51 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,24 @@ All notable changes to this project will be documented in this file. +## [0.2.3] - 2024-12-05 + +### ๐Ÿš€ Features + +- Add `central` to shortname columns + +### ๐Ÿ› Bug Fixes + +- `&` and `|` with `None` return original `Q`. Previously, `Q(...) | None` would return a query that evaluated to `True` everywhere. + +### ๐Ÿ“š Documentation + +- List defined operators on `Q` (`&`, `|`, `~`, `==`) in the docstring of `CombineQMixin`. + +### ๐Ÿงช Testing + +- ensure that `&` and `|` with `None` return original `Q`. + ## [0.2.2] - 2024-12-03 ### ๐Ÿš€ Features @@ -202,6 +220,7 @@ Initial implementation of the lyDATA library. +[0.2.3]: https://github.com/rmnldwg/lydata/compare/0.2.2..0.2.3 [0.2.2]: https://github.com/rmnldwg/lydata/compare/0.2.1..0.2.2 [0.2.1]: https://github.com/rmnldwg/lydata/compare/0.2.0..0.2.1 [0.2.0]: https://github.com/rmnldwg/lydata/compare/0.1.2..0.2.0 diff --git a/lydata/accessor.py b/lydata/accessor.py index d41bd0a..4efbf84 100644 --- a/lydata/accessor.py +++ b/lydata/accessor.py @@ -55,17 +55,34 @@ def _get_all_true(df: pd.DataFrame) -> pd.Series: class CombineQMixin: - """Mixin class for combining queries.""" + """Mixin class for combining queries. + + Four operators are defined for combining queries: + + 1. ``&`` for logical AND operations. + The returned object is an :py:class:`AndQ` instance and - when executed - + returns a boolean mask where both queries are satisfied. When the right-hand + side is ``None``, the left-hand side query object is returned unchanged. + 2. ``|`` for logical OR operations. + The returned object is an :py:class:`OrQ` instance and - when executed - + returns a boolean mask where either query is satisfied. When the right-hand + side is ``None``, the left-hand side query object is returned unchanged. + 3. ``~`` for inverting a query. + The returned object is a :py:class:`NotQ` instance and - when executed - + returns a boolean mask where the query is not satisfied. + 4. ``==`` for checking if two queries are equal. + Two queries are equal if their column names, operators, and values are equal. + Note that this does not check if the queries are semantically equal, i.e., if + they would return the same result when executed. + """ def __and__(self, other: QTypes | None) -> AndQ: """Combine two queries with a logical AND.""" - other = other or NoneQ() - return AndQ(self, other) + return self if other is None else AndQ(self, other) def __or__(self, other: QTypes | None) -> OrQ: """Combine two queries with a logical OR.""" - other = other or NoneQ() - return OrQ(self, other) + return self if other is None else OrQ(self, other) def __invert__(self) -> NotQ: """Negate the query.""" @@ -166,6 +183,8 @@ class AndQ(CombineQMixin): 1 True 2 False dtype: bool + >>> all((q1 & None).execute(df) == q1.execute(df)) + True """ def __init__(self, q1: QTypes, q2: QTypes) -> None: @@ -198,6 +217,8 @@ class OrQ(CombineQMixin): 1 False 2 True Name: col1, dtype: bool + >>> all((q1 | None).execute(df) == q1.execute(df)) + True """ def __init__(self, q1: QTypes, q2: QTypes) -> None: @@ -257,6 +278,7 @@ def execute(self, df: pd.DataFrame) -> pd.Series: QTypes = Q | AndQ | OrQ | NotQ | None +"""Type for a query object or a combination of query objects.""" class C: diff --git a/lydata/utils.py b/lydata/utils.py index 5b2cdb0..fcb4528 100644 --- a/lydata/utils.py +++ b/lydata/utils.py @@ -120,6 +120,7 @@ def get_default_column_map() -> _ColumnMap: _ColumnSpec("midext", ("tumor", "1", "extension")), _ColumnSpec("subsite", ("tumor", "1", "subsite")), _ColumnSpec("volume", ("tumor", "1", "volume")), + _ColumnSpec("central", ("tumor", "1", "central")), ] )