diff --git a/mis_builder/models/simple_array.py b/mis_builder/models/simple_array.py new file mode 100644 index 00000000..e05702d3 --- /dev/null +++ b/mis_builder/models/simple_array.py @@ -0,0 +1,103 @@ +""" A trivial immutable array that supports basic arithmetic operations. + +>>> a = SimpleArray((1.0, 2.0, 3.0)) +>>> b = SimpleArray((4.0, 5.0, 6.0)) +>>> t = (4.0, 5.0, 6.0) +>>> +a +SimpleArray((1.0, 2.0, 3.0)) +>>> -a +SimpleArray((-1.0, -2.0, -3.0)) +>>> a + b +SimpleArray((5.0, 7.0, 9.0)) +>>> b + a +SimpleArray((5.0, 7.0, 9.0)) +>>> a + t +SimpleArray((5.0, 7.0, 9.0)) +>>> t + a +SimpleArray((5.0, 7.0, 9.0)) +>>> a - b +SimpleArray((-3.0, -3.0, -3.0)) +>>> a - t +SimpleArray((-3.0, -3.0, -3.0)) +>>> t - a +SimpleArray((3.0, 3.0, 3.0)) +>>> a * b +SimpleArray((4.0, 10.0, 18.0)) +>>> b * a +SimpleArray((4.0, 10.0, 18.0)) +>>> a * t +SimpleArray((4.0, 10.0, 18.0)) +>>> t * a +SimpleArray((4.0, 10.0, 18.0)) +>>> a / b +SimpleArray((0.25, 0.4, 0.5)) +>>> b / a +SimpleArray((4.0, 2.5, 2.0)) +>>> a / t +SimpleArray((0.25, 0.4, 0.5)) +>>> t / a +SimpleArray((4.0, 2.5, 2.0)) +""" + +import operator + + +__all__ = ['SimpleArray'] + + +class SimpleArray(tuple): + + def _op(self, op, other): + if isinstance(other, tuple): + if len(other) != len(self): + raise TypeError("tuples must have same length for %s" % op) + return SimpleArray(map(op, self, other)) + return NotImplemented + + def __add__(self, other): + return self._op(operator.add, other) + + __radd__ = __add__ + + def __pos__(self): + return SimpleArray(map(operator.pos, self)) + + def __neg__(self): + return SimpleArray(map(operator.neg, self)) + + def __sub__(self, other): + return self._op(operator.sub, other) + + def __rsub__(self, other): + return SimpleArray(other)._op(operator.sub, self) + + def __mul__(self, other): + return self._op(operator.mul, other) + + __rmul__ = __mul__ + + def __div__(self, other): + return self._op(operator.div, other) + + def __floordiv__(self, other): + return self._op(operator.floordiv, other) + + def __truediv__(self, other): + return self._op(operator.truediv, other) + + def __rdiv__(self, other): + return SimpleArray(other)._op(operator.div, self) + + def __rfloordiv__(self, other): + return SimpleArray(other)._op(operator.floordiv, self) + + def __rtruediv__(self, other): + return SimpleArray(other)._op(operator.truediv, self) + + def __repr__(self): + return "SimpleArray(%s)" % tuple.__repr__(self) + + +if __name__ == '__main__': + import doctest + doctest.testmod()