aboutsummaryrefslogtreecommitdiffstats
path: root/tagit/utils
diff options
context:
space:
mode:
authorMatthias Baumgartner <dev@igsor.net>2023-02-03 17:24:40 +0100
committerMatthias Baumgartner <dev@igsor.net>2023-02-03 17:24:40 +0100
commite4b98fb261c83588ca1151a1c3f8891965051b2f (patch)
tree23fc90186db6acab73c1b91dc2c21b044bd5628e /tagit/utils
parent7bb4c0f40c8666ef94a4dcf7fdf03a9058b64a8e (diff)
downloadtagit-e4b98fb261c83588ca1151a1c3f8891965051b2f.tar.gz
tagit-e4b98fb261c83588ca1151a1c3f8891965051b2f.tar.bz2
tagit-e4b98fb261c83588ca1151a1c3f8891965051b2f.zip
previews in browser
Diffstat (limited to 'tagit/utils')
-rw-r--r--tagit/utils/__init__.py1
-rw-r--r--tagit/utils/namespaces.py4
-rw-r--r--tagit/utils/rmatcher.py53
3 files changed, 57 insertions, 1 deletions
diff --git a/tagit/utils/__init__.py b/tagit/utils/__init__.py
index 16dcd4d..daa9eab 100644
--- a/tagit/utils/__init__.py
+++ b/tagit/utils/__init__.py
@@ -10,6 +10,7 @@ import typing
# inner-module imports
from . import bsfs
from . import namespaces as ns
+from . import rmatcher
from . import time as ttime
from .frame import Frame
from .shared import * # FIXME: port properly
diff --git a/tagit/utils/namespaces.py b/tagit/utils/namespaces.py
index 5446922..dbdb853 100644
--- a/tagit/utils/namespaces.py
+++ b/tagit/utils/namespaces.py
@@ -19,8 +19,9 @@ bsm = _bsfs.Namespace('http://bsfs.ai/schema/Meta')
# auxiliary bsfs namespaces
bse = _bsfs.Namespace('http://bsfs.ai/schema/Entity')
-bst = _bsfs.Namespace('http://bsfs.ai/schema/Tag')
bsg = _bsfs.Namespace('http://bsfs.ai/schema/Group')
+bsp = _bsfs.Namespace('http://bsfs.ai/schema/Preview')
+bst = _bsfs.Namespace('http://bsfs.ai/schema/Tag')
# export
__all__: typing.Sequence[str] = (
@@ -28,6 +29,7 @@ __all__: typing.Sequence[str] = (
'bsfs',
'bsg',
'bsm',
+ 'bsp',
'bst',
'xsd',
)
diff --git a/tagit/utils/rmatcher.py b/tagit/utils/rmatcher.py
new file mode 100644
index 0000000..b5bb802
--- /dev/null
+++ b/tagit/utils/rmatcher.py
@@ -0,0 +1,53 @@
+"""
+
+Part of the tagit module.
+A copy of the license is provided with the project.
+Author: Matthias Baumgartner, 2022
+"""
+# exports
+__all__ = (
+ 'by_area',
+ 'by_area_min',
+ )
+
+
+## code ##
+
+def by_area(target, candidates):
+ """Pick the item from *candidates* whose area is most similar to *target*."""
+ target_area = target[0] * target[1]
+ scores = [
+ (key, abs(target_area - res[0] * res[1]))
+ for key, res in candidates
+ ]
+ best_key, best_score = min(scores, key=lambda key_score: key_score[1])
+ return best_key
+
+
+def by_area_min(target, candidates):
+ """Pick the item from *candidates* whose area is at least that of *target*."""
+ # rank the candidates by area difference
+ # a positive score means that the candidate is larger than the target.
+ target_area = target[0] * target[1]
+ scores = [(key, res[0] * res[1] - target_area) for key, res in candidates]
+
+ # identify the two items with
+ # a) the smallest positive score (kmin), or
+ # b) the largest negative score (kmax)
+ kmin, kmax = None, None
+ cmin, cmax = float('inf'), float('-inf')
+ for key, score in scores:
+ if score >= 0 and score < cmin:
+ kmin, cmin = key, score
+ elif score < 0 and score > cmax:
+ kmax, cmax = key, score
+
+ # prefer positive over negative scores
+ if cmin < float('inf'):
+ return kmin
+ if cmax > float('-inf'):
+ return kmax
+ # no viable resolution found
+ raise IndexError('list contains no valid element')
+
+## EOF ##