1   
  2   
  3   
  4   
  5   
  6   
  7   
  8   
  9   
 10   
 11   
 12   
 13   
 14   
 15   
 16   
 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   
 59   
 60   
 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   
 74   
 75      _squisher = None 
 76   
 77   
 78       
 79   
 82   
 83   
 84       
 85       
 88   
 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   
108      return lambda input: reduce(op, input) 
 109   
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