summaryrefslogtreecommitdiffstats
path: root/utils.py
diff options
context:
space:
mode:
authorJan Pokorný <jpokorny@redhat.com>2014-02-13 20:42:18 +0100
committerJan Pokorný <jpokorny@redhat.com>2014-02-13 20:42:18 +0100
commitd9e87ec9e575669899129665df0a3be3b6780fcf (patch)
tree05a9a01d7f4cd1b2459605bb9d73a57a29b76a93 /utils.py
parentc40ec3b0f74e380c2a1e054473f2878d6c10a7ec (diff)
downloadclufter-d9e87ec9e575669899129665df0a3be3b6780fcf.tar.gz
clufter-d9e87ec9e575669899129665df0a3be3b6780fcf.tar.xz
clufter-d9e87ec9e575669899129665df0a3be3b6780fcf.zip
command: make this top-layer work as per the design, yay
Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
Diffstat (limited to 'utils.py')
-rw-r--r--utils.py27
1 files changed, 27 insertions, 0 deletions
diff --git a/utils.py b/utils.py
index becef9b..045f434 100644
--- a/utils.py
+++ b/utils.py
@@ -71,6 +71,33 @@ apply_intercalate = apply_aggregation_preserving_depth(
i, [])
)
+bifilter = \
+ lambda fnc, seq: \
+ reduce(lambda acc, x: acc[int(not fnc(x))].append(x) or acc,
+ seq, ([], []))
+
+# Given the partitioning function, do the recursive refinement in a way
+# the parts reaching the bottom line in more steps are continually "shaked"
+# towards the end (with stable the relative order, though).
+# Default partitioning function just distinguishes between tuples/lists
+# and other values (presumably scalars) so when passed a tuple/list encoding
+# a graph (tree/forest) in a DFS manner using unrestricted nesting, it will
+# return serialized BFS walk of the same.
+# NOTE if there are scalars already at the start-level depth, use
+# `tail_shake_safe` (not that it provides much more guarantee :-p)
+tailshake = \
+ lambda src, partitioner=(lambda x: not tuplist(x)): \
+ reduce(lambda a, b: a + (tailshake(b, partitioner) if b else b),
+ reduce(lambda a, b: (a[0] + b[0], a[1] + b[1]),
+ tuple(bifilter(partitioner, i) if tuplist(i) else (i, [])
+ for i in src), ([], [])))
+
+tailshake_safe = \
+ lambda src, partitioner=(lambda x: not tuplist(x)): \
+ tailshake(src if all(tuplist(i) for i in src) else (src, ),
+ partitioner)
+
+
zipped_outlier = type('zipped_outlier', (tuple, ), {})
zip_empty = type('zip_filler', (str, ), {})("EMPTY")
loose_zip = lambda a, b: zip(