diff options
author | Jan Pokorný <jpokorny@redhat.com> | 2014-04-01 14:10:14 +0200 |
---|---|---|
committer | Jan Pokorný <jpokorny@redhat.com> | 2014-04-01 14:10:14 +0200 |
commit | d560abca52d05b78c4cf1def0b92652b0e931769 (patch) | |
tree | 909109af03abc94bad70bf3810c9508388b8646f | |
parent | ccba7aaeaa7f3f60e987811f9972af77b20c683a (diff) | |
download | clufter-d560abca52d05b78c4cf1def0b92652b0e931769.tar.gz clufter-d560abca52d05b78c4cf1def0b92652b0e931769.tar.xz clufter-d560abca52d05b78c4cf1def0b92652b0e931769.zip |
Refactor: move functional-paradigm helpers utils -> utils_func
Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
-rw-r--r-- | command.py | 14 | ||||
-rw-r--r-- | command_manager.py | 10 | ||||
-rw-r--r-- | completion.py | 3 | ||||
-rw-r--r-- | filter_manager.py | 10 | ||||
-rw-r--r-- | formats/simpleconfig.py | 3 | ||||
-rw-r--r-- | tests/command.py | 5 | ||||
-rw-r--r-- | utils.py | 76 | ||||
-rw-r--r-- | utils_func.py | 86 |
8 files changed, 109 insertions, 98 deletions
@@ -18,19 +18,19 @@ from .plugin_registry import PluginRegistry from .utils import any2iter, \ args2sgpl, \ args2tuple, \ - apply_aggregation_preserving_depth, \ - apply_intercalate, \ - apply_loose_zip_preserving_depth, \ - bifilter, \ cli_decor, \ func_defaults_varnames, \ head_tail, \ hybridproperty, \ longopt_letters_reprio, \ selfaware, \ - tuplist, \ - tailshake, \ - zip_empty + tuplist +from .utils_func import apply_aggregation_preserving_depth, \ + apply_intercalate, \ + apply_loose_zip_preserving_depth, \ + bifilter, \ + tailshake, \ + zip_empty log = logging.getLogger(__name__) diff --git a/command_manager.py b/command_manager.py index 368e053..0055e86 100644 --- a/command_manager.py +++ b/command_manager.py @@ -12,11 +12,11 @@ from .command import commands, CommandAlias from .error import ClufterError, ClufterPlainError, \ EC from .plugin_registry import PluginManager -from .utils import apply_preserving_depth, \ - apply_aggregation_preserving_depth, \ - apply_intercalate, \ - bifilter, \ - make_options +from .utils import make_options +from .utils_func import apply_preserving_depth, \ + apply_aggregation_preserving_depth, \ + apply_intercalate, \ + bifilter log = logging.getLogger(__name__) diff --git a/completion.py b/completion.py index d5336f4..1ffa59b 100644 --- a/completion.py +++ b/completion.py @@ -7,7 +7,8 @@ __author__ = "Jan Pokorný <jpokorny @at@ Red Hat .dot. com>" from os.path import basename -from .utils import args2sgpl, bifilter, cli_undecor +from .utils import args2sgpl, cli_undecor +from .utils_func import bifilter class Completion(object): diff --git a/filter_manager.py b/filter_manager.py index 9e73f29..da974a8 100644 --- a/filter_manager.py +++ b/filter_manager.py @@ -9,12 +9,12 @@ import logging from .error import ClufterError from .filter import filters -from .format import CompositeFormat, Format +from .format import CompositeFormat from .plugin_registry import PluginManager -from .utils import apply_preserving_depth, \ - apply_aggregation_preserving_depth, \ - apply_intercalate, \ - tuplist +from .utils import tuplist +from .utils_func import apply_preserving_depth, \ + apply_aggregation_preserving_depth, \ + apply_intercalate log = logging.getLogger(__name__) diff --git a/formats/simpleconfig.py b/formats/simpleconfig.py index 6b40d95..e65b0cb 100644 --- a/formats/simpleconfig.py +++ b/formats/simpleconfig.py @@ -6,7 +6,8 @@ __author__ = "Jan Pokorný <jpokorny @at@ Red Hat .dot. com>" from ..format import SimpleFormat -from ..utils import apply_aggregation_preserving_depth, tuplist +from ..utils import tuplist +from ..utils_func import apply_aggregation_preserving_depth class simpleconfig(SimpleFormat): diff --git a/tests/command.py b/tests/command.py index 009ec00..329a7cd 100644 --- a/tests/command.py +++ b/tests/command.py @@ -22,9 +22,8 @@ from clufter.formats.ccs import ccs, ccsflat from clufter.formats.coro import coroxml from clufter.formats.pcs import pcs -from clufter.utils import apply_preserving_depth, \ - apply_aggregation_preserving_depth, \ - head_tail +from clufter.utils_func import apply_preserving_depth, \ + apply_aggregation_preserving_depth class ChainResolve(unittest.TestCase): @@ -47,82 +47,6 @@ filtervarsdef = \ lambda src, which: dict((x, src[x]) for x in which if src.get(x, None)) filtervarspop = \ lambda src, which: dict((x, src.pop(x)) for x in which if x in src) -apply_preserving_depth = \ - lambda action: \ - lambda item: \ - type(item)(apply_preserving_depth(action)(i) for i in item) \ - if tuplist(item) else action(item) -apply_aggregation_preserving_depth = \ - lambda agg_fn: \ - lambda item: \ - agg_fn(type(item)(apply_aggregation_preserving_depth(agg_fn)(i) - for i in item)) \ - if tuplist(item) else item -apply_aggregation_preserving_passing_depth = \ - lambda agg_fn, d=0: \ - lambda item: \ - agg_fn(type(item)( - apply_aggregation_preserving_passing_depth(agg_fn, d+1)(i) - for i in item), - d+1 - ) \ - if tuplist(item) else item -# name comes from Haskell -# note: always returns list even for input tuple -# note: when returning from recursion, should always observe scalar or list(?) -apply_intercalate = apply_aggregation_preserving_depth( - lambda i: - reduce(lambda a, b: a + (b if isinstance(b, list) else [b]), - 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( - list(a) + (max(len(a), len(b)) - len(a)) * [zip_empty], - list(b) + (max(len(a), len(b)) - len(b)) * [zip_empty] -) -apply_loose_zip_preserving_depth = \ - lambda a, b: \ - (type(a) if type(a) == type(b) else type(a))( - [apply_loose_zip_preserving_depth(*p) for p in loose_zip(a, b)] - ) if tuplist(a) == tuplist(b) == True else zipped_outlier([a, b]) -# as previous, but with length checking of some sort -# NOTE: automatically shortens the longer counterpart in the pair -# to the length of the bigger one -apply_strict_zip_preserving_depth = \ - lambda a, b: \ - (type(a) if type(a) == type(b) else type(a))( - [apply_strict_zip_preserving_depth(*p) for p in zip(a, b)] - ) if tuplist(a) == tuplist(b) == True and len(a) == len(b) \ - else zipped_outlier([a, b]) def which(name, *where): diff --git a/utils_func.py b/utils_func.py new file mode 100644 index 0000000..eac0305 --- /dev/null +++ b/utils_func.py @@ -0,0 +1,86 @@ +# -*- coding: UTF-8 -*- +# Copyright 2014 Red Hat, Inc. +# Part of clufter project +# Licensed under GPLv2 (a copy included | http://gnu.org/licenses/gpl-2.0.txt) +"""Various functional-paradigm helpers""" +__author__ = "Jan Pokorný <jpokorny @at@ Red Hat .dot. com>" + +from .utils import tuplist + + +apply_preserving_depth = \ + lambda action: \ + lambda item: \ + type(item)(apply_preserving_depth(action)(i) for i in item) \ + if tuplist(item) else action(item) +apply_aggregation_preserving_depth = \ + lambda agg_fn: \ + lambda item: \ + agg_fn(type(item)(apply_aggregation_preserving_depth(agg_fn)(i) + for i in item)) \ + if tuplist(item) else item +apply_aggregation_preserving_passing_depth = \ + lambda agg_fn, d=0: \ + lambda item: \ + agg_fn(type(item)( + apply_aggregation_preserving_passing_depth(agg_fn, d+1)(i) + for i in item), + d+1 + ) \ + if tuplist(item) else item +# name comes from Haskell +# note: always returns list even for input tuple +# note: when returning from recursion, should always observe scalar or list(?) +apply_intercalate = apply_aggregation_preserving_depth( + lambda i: + reduce(lambda a, b: a + (b if isinstance(b, list) else [b]), + 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( + list(a) + (max(len(a), len(b)) - len(a)) * [zip_empty], + list(b) + (max(len(a), len(b)) - len(b)) * [zip_empty] +) +apply_loose_zip_preserving_depth = \ + lambda a, b: \ + (type(a) if type(a) == type(b) else type(a))( + [apply_loose_zip_preserving_depth(*p) for p in loose_zip(a, b)] + ) if tuplist(a) == tuplist(b) == True else zipped_outlier([a, b]) +# as previous, but with length checking of some sort +# NOTE: automatically shortens the longer counterpart in the pair +# to the length of the bigger one +apply_strict_zip_preserving_depth = \ + lambda a, b: \ + (type(a) if type(a) == type(b) else type(a))( + [apply_strict_zip_preserving_depth(*p) for p in zip(a, b)] + ) if tuplist(a) == tuplist(b) == True and len(a) == len(b) \ + else zipped_outlier([a, b]) |