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.

128 lines
3.1 KiB

  1. # -*- coding: utf-8 -*-
  2. # © 2014-2015 ACSONE SA/NV (<http://acsone.eu>)
  3. # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
  4. """ A trivial immutable array that supports basic arithmetic operations.
  5. >>> a = SimpleArray((1.0, 2.0, 3.0))
  6. >>> b = SimpleArray((4.0, 5.0, 6.0))
  7. >>> t = (4.0, 5.0, 6.0)
  8. >>> +a
  9. SimpleArray((1.0, 2.0, 3.0))
  10. >>> -a
  11. SimpleArray((-1.0, -2.0, -3.0))
  12. >>> a + b
  13. SimpleArray((5.0, 7.0, 9.0))
  14. >>> b + a
  15. SimpleArray((5.0, 7.0, 9.0))
  16. >>> a + t
  17. SimpleArray((5.0, 7.0, 9.0))
  18. >>> t + a
  19. SimpleArray((5.0, 7.0, 9.0))
  20. >>> a - b
  21. SimpleArray((-3.0, -3.0, -3.0))
  22. >>> a - t
  23. SimpleArray((-3.0, -3.0, -3.0))
  24. >>> t - a
  25. SimpleArray((3.0, 3.0, 3.0))
  26. >>> a * b
  27. SimpleArray((4.0, 10.0, 18.0))
  28. >>> b * a
  29. SimpleArray((4.0, 10.0, 18.0))
  30. >>> a * t
  31. SimpleArray((4.0, 10.0, 18.0))
  32. >>> t * a
  33. SimpleArray((4.0, 10.0, 18.0))
  34. >>> a / b
  35. SimpleArray((0.25, 0.4, 0.5))
  36. >>> b / a
  37. SimpleArray((4.0, 2.5, 2.0))
  38. >>> a / t
  39. SimpleArray((0.25, 0.4, 0.5))
  40. >>> t / a
  41. SimpleArray((4.0, 2.5, 2.0))
  42. >>> b / 2
  43. SimpleArray((2.0, 2.5, 3.0))
  44. >>> 2 * b
  45. SimpleArray((8.0, 10.0, 12.0))
  46. >>> b += 2 ; b
  47. SimpleArray((6.0, 7.0, 8.0))
  48. >>> a / ((1.0, 0.0, 1.0))
  49. SimpleArray((1.0, DataError(), 3.0))
  50. >>> a / 0.0
  51. SimpleArray((DataError(), DataError(), DataError()))
  52. """
  53. import operator
  54. import traceback
  55. from .data_error import DataError
  56. __all__ = ['SimpleArray']
  57. class SimpleArray(tuple):
  58. def _op(self, op, other):
  59. def _o2(x, y):
  60. try:
  61. return op(x, y)
  62. except ZeroDivisionError:
  63. return DataError('#DIV/0', traceback.format_exc())
  64. except:
  65. return DataError('#ERR', traceback.format_exc())
  66. if isinstance(other, tuple):
  67. if len(other) != len(self):
  68. raise TypeError("tuples must have same length for %s" % op)
  69. return SimpleArray(map(_o2, self, other))
  70. else:
  71. return SimpleArray(map(lambda z: _o2(z, other), self))
  72. def __add__(self, other):
  73. return self._op(operator.add, other)
  74. __radd__ = __add__
  75. def __pos__(self):
  76. return SimpleArray(map(operator.pos, self))
  77. def __neg__(self):
  78. return SimpleArray(map(operator.neg, self))
  79. def __sub__(self, other):
  80. return self._op(operator.sub, other)
  81. def __rsub__(self, other):
  82. return SimpleArray(other)._op(operator.sub, self)
  83. def __mul__(self, other):
  84. return self._op(operator.mul, other)
  85. __rmul__ = __mul__
  86. def __div__(self, other):
  87. return self._op(operator.div, other)
  88. def __floordiv__(self, other):
  89. return self._op(operator.floordiv, other)
  90. def __truediv__(self, other):
  91. return self._op(operator.truediv, other)
  92. def __rdiv__(self, other):
  93. return SimpleArray(other)._op(operator.div, self)
  94. def __rfloordiv__(self, other):
  95. return SimpleArray(other)._op(operator.floordiv, self)
  96. def __rtruediv__(self, other):
  97. return SimpleArray(other)._op(operator.truediv, self)
  98. def __repr__(self):
  99. return "SimpleArray(%s)" % tuple.__repr__(self)
  100. if __name__ == '__main__':
  101. import doctest
  102. doctest.testmod()