From 01a4c355b29bb3774d3b90523270539bd42707d5 Mon Sep 17 00:00:00 2001 From: Roman Ludwig <48687784+rmnldwg@users.noreply.github.com> Date: Thu, 5 Dec 2024 16:00:11 +0100 Subject: [PATCH 1/5] fix: `&` and `|` with `None` return original `Q` Previously, combingn `Q(...) | None` would return a query that always evaluates to an all-true query. Now, the original `Q(...)` is returned. --- lydata/accessor.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lydata/accessor.py b/lydata/accessor.py index d41bd0a..8e9c886 100644 --- a/lydata/accessor.py +++ b/lydata/accessor.py @@ -59,13 +59,11 @@ class CombineQMixin: 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.""" From c422767c129bd1d3cf457437686dddcb92dba616 Mon Sep 17 00:00:00 2001 From: Roman Ludwig <48687784+rmnldwg@users.noreply.github.com> Date: Thu, 5 Dec 2024 16:05:52 +0100 Subject: [PATCH 2/5] test: `&` and `|` with `None` return original `Q` These test check whether the combination of `Q` object with `None` - e.g. `Q(...) | None` surely return the same query as only the original `Q(...)` object. --- lydata/accessor.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lydata/accessor.py b/lydata/accessor.py index 8e9c886..6be988c 100644 --- a/lydata/accessor.py +++ b/lydata/accessor.py @@ -164,6 +164,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: @@ -196,6 +198,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: From 99ba3244ebe8d22ca21cde45f426ce50dd6ec5fe Mon Sep 17 00:00:00 2001 From: Roman Ludwig <48687784+rmnldwg@users.noreply.github.com> Date: Thu, 5 Dec 2024 16:06:18 +0100 Subject: [PATCH 3/5] docs: list defined operators on `Q` --- lydata/accessor.py | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/lydata/accessor.py b/lydata/accessor.py index 6be988c..4efbf84 100644 --- a/lydata/accessor.py +++ b/lydata/accessor.py @@ -55,7 +55,26 @@ 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.""" @@ -259,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: From 5efe21882e9775970774f131711f178c87618b9c Mon Sep 17 00:00:00 2001 From: Roman Ludwig <48687784+rmnldwg@users.noreply.github.com> Date: Thu, 5 Dec 2024 16:07:50 +0100 Subject: [PATCH 4/5] feat: add `central` to shortname columns --- lydata/utils.py | 1 + 1 file changed, 1 insertion(+) 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")), ] ) From 0aca73e817254a81ebb60f05ace97fc620377171 Mon Sep 17 00:00:00 2001 From: Roman Ludwig <48687784+rmnldwg@users.noreply.github.com> Date: Thu, 5 Dec 2024 16:12:32 +0100 Subject: [PATCH 5/5] chore: update changelog --- CHANGELOG.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) 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