Skip to content

Commit

Permalink
ENH: add 'like_with_tols' search operator
Browse files Browse the repository at this point in the history
This operator is converted in Client.search, but is provided as
a way for the UI to pass user-provided tolerances into the search
function
  • Loading branch information
shilorigins committed Sep 13, 2024
1 parent df79b38 commit 55459a9
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 6 deletions.
5 changes: 1 addition & 4 deletions superscore/backends/filestore.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,10 +339,7 @@ def compare(op: str, data, target) -> bool:
elif op == "like":
if isinstance(data, str):
return re.search(target, data)
elif isinstance(data, (int, float)):
return data < 1.05 * target and data > .95 * target
else:
return NotImplemented
return NotImplemented

@contextlib.contextmanager
def _load_and_store_context(self) -> Generator[Dict[UUID, Any], None, None]:
Expand Down
16 changes: 14 additions & 2 deletions superscore/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from uuid import UUID

from superscore.backends import get_backend
from superscore.backends.core import _Backend
from superscore.backends.core import SearchTerm, _Backend
from superscore.control_layers import ControlLayer, EpicsData
from superscore.control_layers.status import TaskStatus
from superscore.errors import CommunicationError
Expand Down Expand Up @@ -151,8 +151,20 @@ def search(self, *post) -> Generator[Entry, None, None]:
"""
Search backend for entries matching all SearchTerms in ``post``. Can search by any
field, plus some special keywords. Backends support operators listed in _Backend.search.
Some operators are supported in the UI / client and must be converted before being
passed to the backend.
"""
return self.backend.search(*post)
new_search_terms = []
for search_term in post:
if search_term.operator == 'like_with_tols':
target, rel_tol, abs_tol = search_term.value
lower = target - target * rel_tol - abs_tol
upper = target + target * rel_tol + abs_tol
new_search_terms.append(SearchTerm(search_term.attr, 'gt', lower))
new_search_terms.append(SearchTerm(search_term.attr, 'lt', upper))
else:
new_search_terms.append(search_term)
return self.backend.search(*new_search_terms)

def save(self, entry: Entry):
"""Save information in ``entry`` to database"""
Expand Down
13 changes: 13 additions & 0 deletions superscore/tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import pytest

from superscore.backends.core import SearchTerm
from superscore.backends.filestore import FilestoreBackend
from superscore.client import Client
from superscore.control_layers import EpicsData
Expand Down Expand Up @@ -136,3 +137,15 @@ def test_find_config(sscore_cfg: str):
# explicit SUPERSCORE_CFG env var supercedes XDG_CONFIG_HOME
os.environ['SUPERSCORE_CFG'] = 'other/cfg'
assert 'other/cfg' == Client.find_config()


def test_search(sample_client):
results = list(sample_client.search(
SearchTerm('data', 'like_with_tols', (4, 0, 0))
))
assert len(results) == 0

results = list(sample_client.search(
SearchTerm('data', 'like_with_tols', (4, .5, 1))
))
assert len(results) == 4

0 comments on commit 55459a9

Please sign in to comment.