[frames] | no frames]

# Source Code for Module osh.command.squish

```  1  # osh
2  # Copyright (C) Jack Orenstein <jao@geophile.com>
3  #
4  # This program is free software; you can redistribute it and/or modify
6  # the Free Software Foundation; either version 2 of the License, or
7  # (at your option) any later version.
8  #
9  # This program is distributed in the hope that it will be useful,
10  # but WITHOUT ANY WARRANTY; without even the implied warranty of
11  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  # GNU General Public License for more details.
13  #
14  # You should have received a copy of the GNU General Public License
15  # along with this program; if not, write to the Free Software
16  # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18  """C{squish [BINARY_FUNCTION ...]}
19
20  Each input sequence is reduced to a single value, using C{BINARY_FUNCTION}
21  to combine the values. C{BINARY_FUNCTION} is a binary function that can be
22  used for reduction, e.g. C{+}, C{*}, C{max}, C{min}, but not C{-} or
23  C{/}.
24
25  B{Example}: If one of the inputs is the list C{[1, 2, 3, 4]}, then::
26
27      squish +
28
29  will generate C{10} (= C{1 + 2 + 3 + 4}).
30
31  The result is exactly equivalent to what would be produced by using
32  the Python function C{map}, e.g.::
33
34      map 'list: squish(lambda a, b: a + b, list)'
35
36  If input sequences contain nested sequences, then multiple C{BINARY_FUNCTION}s
37  can be provided, to do multiple reductions at once. For example, if
38  one input sequence is C{[[10, 20, 30], [1, 100, 1000], [111, 222, 333]]}
39  then::
40
41      squish + max min
42
43  will produce C{[122, 222, 30]}. C{122} is C{10 + 1 + 111}, C{222} is C{max(20, 100, 222)}, and
44  C{30} is C{min(30, 1000, 333)}.
45
46  If no C{BINARY_FUNCTION} is provided, then C{+} is assumed.
47  """
48
49  import types
50
51  import osh.core
52  import osh.function
53
54  create_function = osh.function._create_function
55
56  # CLI
57 -def _squish():
58      return _Squish()
59
60  # API
61 -def squish(*squish_ops):
62      """Each input sequence is reduced to a single value. Elements
63      of the input sequence are combined using a C{squish_op}, a binary function
64      that can be used for reduction, i.e. a binary associative function such as addition,
65      but not subtraction, (because x + y = y + x, but x - y != y - x).
66      If input sequences contain nested sequences, then multiple C{squish_op}s
67      can be provided, to do multiple reductions at once. The squish_op can be a function-valued
68      expression, a string function expression (e.g. C{'x, y: x + y'}), or a string describing
69      a binary associative operator, specifically one of: C{+, *, ^, &, |, and, or}.
70      """
71      return _Squish().process_args(*squish_ops)
72
73 -class _Squish(osh.core.Op):
74
75      _squisher = None
76
77
78      # object interface
79
80 -    def __init__(self):
81          osh.core.Op.__init__(self, '', (0, None))
82
83
84      # BaseOp interface
85
86 -    def doc(self):
87          return __doc__
88
89 -    def setup(self):
90          args = self.args()
91          squish_ops = []
92          while args.has_next():
93              arg = args.next()
94              op = create_function(arg)
95              squish_ops.append(op)
96          if len(squish_ops) == 0:
97              squish_ops.append(create_function(lambda x, y: x + y))
98          if len(squish_ops) == 1:
99              self._squisher = _object_squisher(squish_ops[0])
100          else:
101              self._squisher = _sequence_squisher(squish_ops)
102
104          squished = self._squisher(object)
105          self.send(squished)
106
107 -def _object_squisher(op):
108      return lambda input: reduce(op, input)
109
110 -def _sequence_squisher(ops):
111      def all_ops(x, y):
112          return tuple([ops[i](x[i], y[i]) for i in xrange(len(ops))])
113      return lambda input: reduce(all_ops, input)
114
<!--
expandto(location.href);
// -->

```

 Generated by Epydoc 3.0.1 on Sun Oct 3 15:23:48 2010 http://epydoc.sourceforge.net