home
·
contact
·
privacy
projects
/
bricksplom
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (parent:
2fceffe
)
For matching on numerical values, allow "<" and ">" comparisons.
master
author
Plom Heller
<plom@plomlompom.com>
Fri, 14 Aug 2026 23:42:26 +0000
(
01:42
+0200)
committer
Plom Heller
<plom@plomlompom.com>
Fri, 14 Aug 2026 23:42:26 +0000
(
01:42
+0200)
src/bricksplom/misc.py
patch
|
blob
|
history
diff --git
a/src/bricksplom/misc.py
b/src/bricksplom/misc.py
index e7d276de68210f60a74ddf3cc7582790d6d32635..7cce3cf0d632d4ed79fccd4cced628d4efdd36cd 100644
(file)
--- a/
src/bricksplom/misc.py
+++ b/
src/bricksplom/misc.py
@@
-13,6
+13,8
@@
CHAR_SEP_TOKEN = ' '
CHAR_COMMENT = '#'
CHAR_DESIGN_ALT = '='
CHAR_ATTR_EQ = '='
CHAR_COMMENT = '#'
CHAR_DESIGN_ALT = '='
CHAR_ATTR_EQ = '='
+CHAR_ATTR_LESS = '<'
+CHAR_ATTR_MORE = '>'
CHAR_TEXTCONTAINS = ':'
SEP_DESIGN_DESC = '#'
CHAR_COLL_INDENT = ' '
CHAR_TEXTCONTAINS = ':'
SEP_DESIGN_DESC = '#'
CHAR_COLL_INDENT = ' '
@@
-28,7
+30,12
@@
BOX_PREFIX = 'box:'
ARG_QMARK = '?'
PARAM_Q_ID = f'id{CHAR_ATTR_EQ}'
ARG_QMARK = '?'
PARAM_Q_ID = f'id{CHAR_ATTR_EQ}'
-PARAM_Q_DELIMITERS = {CHAR_ATTR_EQ, CHAR_TEXTCONTAINS}
+MATCH_OPERATORS = {
+ CHAR_ATTR_EQ,
+ CHAR_TEXTCONTAINS,
+ CHAR_ATTR_LESS,
+ CHAR_ATTR_MORE
+ }
TOK_SORT_BOX = 'box'
TOK_SORT_ID = 'id'
TOK_SORT_BOX = 'box'
TOK_SORT_ID = 'id'
@@
-154,24
+161,31
@@
class Lookupable:
@classmethod
def matchers(
cls
@classmethod
def matchers(
cls
- ) -> dict[str, tuple[str,
Callable[[Self, str], bool
]]]:
+ ) -> dict[str, tuple[str,
dict[str, Callable[[Self, str], bool]
]]]:
'Available lookup matchers.'
return {
'Available lookup matchers.'
return {
- PARAM_Q_ID: (
- 'by ID of individual item',
- lambda item, q_body: item.id_ == q_body),
- f'text{CHAR_TEXTCONTAINS}': (
+ TOK_SORT_ID: (
+ 'ID of individual item',
+ {CHAR_ATTR_EQ: (
+ lambda item, val: item.id_ == val)}
+ ),
+ 'text': (
'text contained in item description',
'text contained in item description',
- lambda item, q_body: q_body.upper() in item.show().upper())
+ {CHAR_TEXTCONTAINS: (
+ lambda item, val: val.upper() in item.show().upper())}
+ ),
}
def match(
self,
}
def match(
self,
- query_char: str,
- query_body: str
+ target: str,
+ operator: str,
+ val: str
) -> bool:
'Return if self matches query.'
) -> bool:
'Return if self matches query.'
- return self.matchers()[query_char][1](self, query_body)
+ target_matchers = self.matchers()[target][1]
+ assert operator in target_matchers, (target, operator)
+ return target_matchers[operator](self, val)
@classmethod
def _by_box_sorter(
@classmethod
def _by_box_sorter(
@@
-426,19
+440,22
@@
class BrickDesign(Textfiled, WithDb, Lookupable):
@classmethod
def matchers(
cls
@classmethod
def matchers(
cls
- ) -> dict[str, tuple[str,
Callable[[Self, str], bool
]]]:
+ ) -> dict[str, tuple[str,
dict[str, Callable[[Self, str], bool]
]]]:
def attr_matcher(
attr_name: str
def attr_matcher(
attr_name: str
- ) -> tuple[str,
Callable[[Self, str], bool
]]:
- def
match
(
+ ) -> tuple[str,
dict[str, Callable[[Self, str], bool]
]]:
+ def
cmp
(
item: Self,
q_body: str
item: Self,
q_body: str
- ) ->
bool
:
+ ) ->
float
:
assert q_body.isdigit()
assert q_body.isdigit()
- return getattr(item, attr_name) == int(q_body)
- return 'by ' + BrickDesignData.usage(attr_name), match
+ return int(q_body) - float(getattr(item, attr_name))
+ return 'by ' + BrickDesignData.usage(attr_name), {
+ CHAR_ATTR_EQ: lambda item, v: 0 == cmp(item, v),
+ CHAR_ATTR_LESS: lambda item, v: 0 < cmp(item, v),
+ CHAR_ATTR_MORE: lambda item, v: 0 > cmp(item, v)}
return super().matchers() | {
return super().matchers() | {
- f'{attr_name}
{CHAR_ATTR_EQ}
': attr_matcher(attr_name)
+ f'{attr_name}': attr_matcher(attr_name)
for attr_name, attr_type in BrickDesignData.sortables().items()
if attr_type in {int, float}}
for attr_name, attr_type in BrickDesignData.sortables().items()
if attr_type in {int, float}}
@@
-922,18
+939,19
@@
class BricksDb:
) -> str:
'Return formatted result of inquiry on table of table_name.'
assert table_name in self.lookupables
) -> str:
'Return formatted result of inquiry on table of table_name.'
assert table_name in self.lookupables
- match
_keys_val
s = []
+ match
er
s = []
for instruction in match_by:
for instruction in match_by:
- match_key = match_val = ''
+ match_key = match_val =
match_operator =
''
for idx, c in enumerate(instruction):
for idx, c in enumerate(instruction):
- match_key += c
- if c in PARAM_Q_DELIMITERS:
+ if c in MATCH_OPERATORS:
+ match_operator = c
match_val = instruction[idx+1:]
break
match_val = instruction[idx+1:]
break
- match_keys_vals += [(match_key, match_val)]
+ match_key += c
+ matchers += [(match_key, match_operator, match_val)]
cls = self.lookupables[table_name]
for arg_keys, x_ers in [
cls = self.lookupables[table_name]
for arg_keys, x_ers in [
- (arg, m()) for arg, m in ((tuple(t[0] for t in match
_keys_val
s),
+ (arg, m()) for arg, m in ((tuple(t[0] for t in match
er
s),
cls.matchers),
(sort_by, cls.sorters),
((formatter, ), cls.formatters))]:
cls.matchers),
(sort_by, cls.sorters),
((formatter, ), cls.formatters))]:
@@
-944,9
+962,8
@@
class BricksDb:
for arg_key in arg_keys:
assert (not arg_key) or arg_key in keys, (arg_key, keys)
if (items := tuple(getattr(self, table_name).values())):
for arg_key in arg_keys:
assert (not arg_key) or arg_key in keys, (arg_key, keys)
if (items := tuple(getattr(self, table_name).values())):
- for match_key, match_val in match_keys_vals:
- items = tuple(x for x in items
- if x.match(match_key, match_val))
+ for key, operator, val in matchers:
+ items = tuple(x for x in items if x.match(key, operator, val))
for sorter in sort_by:
items = cls.sorters()[sorter][1](self, items)
return CHAR_NEWLINE.join([cls.formatters()[formatter][1](item)
for sorter in sort_by:
items = cls.sorters()[sorter][1](self, items)
return CHAR_NEWLINE.join([cls.formatters()[formatter][1](item)