You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
131 lines
3.2 KiB
131 lines
3.2 KiB
# -*- coding: utf-8 -*-
|
|
# © 2014-2015 ACSONE SA/NV (<http://acsone.eu>)
|
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
|
""" 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))
|
|
>>> b / 2
|
|
SimpleArray((2.0, 2.5, 3.0))
|
|
>>> 2 * b
|
|
SimpleArray((8.0, 10.0, 12.0))
|
|
>>> b += 2 ; b
|
|
SimpleArray((6.0, 7.0, 8.0))
|
|
>>> a / ((1.0, 0.0, 1.0))
|
|
SimpleArray((1.0, DataError(), 3.0))
|
|
>>> a / 0.0
|
|
SimpleArray((DataError(), DataError(), DataError()))
|
|
"""
|
|
|
|
import operator
|
|
import traceback
|
|
|
|
from .data_error import DataError
|
|
|
|
|
|
__all__ = ['SimpleArray']
|
|
|
|
|
|
# TODO named tuple-like behaviour, so expressions can work on subkpis
|
|
|
|
|
|
class SimpleArray(tuple):
|
|
|
|
def _op(self, op, other):
|
|
def _o2(x, y):
|
|
try:
|
|
return op(x, y)
|
|
except ZeroDivisionError:
|
|
return DataError('#DIV/0', traceback.format_exc())
|
|
except:
|
|
return DataError('#ERR', traceback.format_exc())
|
|
|
|
if isinstance(other, tuple):
|
|
if len(other) != len(self):
|
|
raise TypeError("tuples must have same length for %s" % op)
|
|
return SimpleArray(map(_o2, self, other))
|
|
else:
|
|
return SimpleArray(map(lambda z: _o2(z, other), self))
|
|
|
|
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()
|