""" The `+` operator produces a `Vector` result. >>> v1 = Vector(2, 4) >>> v2 = Vector(2, 1) >>> v1 + v2 Vector(4, 5) We can also implemement the `*` operator to perform scalar multiplication or elementwise multiplication. >>> v = Vector(3, 4) >>> abs(v) 5.0 >>> v * 3 Vector(9, 12) >>> abs(v * 3) 15.0 >>> v25 = Vector(2, 5) >>> v71 = Vector(7, 1) >>> v71 * v25 Vector(14, 5) A vector can be used in a boolean context, where it will be considered _falsy_ if it has magnitude zero, otherwise it is _truthy_:: >>> bool(v) True >>> bool(Vector(0, 0)) False Vectors can have n-dimensions:: >>> v3 = Vector(1, 2, 3) >>> len(v3) 3 >>> v3 Vector(1, 2, 3) >>> abs(v3) # doctest:+ELLIPSIS 3.74165738... >>> v3 + Vector(4, 5, 6) Vector(5, 7, 9) >>> v3 * 5 Vector(5, 10, 15) >>> v2 + v3 Traceback (most recent call last): ... ValueError: Addition applies only to vectors of equal dimensions. The `repr` of a Vector is produced with the help of the `reprlib.repr` function, limiting the size of the output string: >>> Vector(*range(100)) Vector(0, 1, 2, 3, 4, 5, ...) """ # BEGIN VECTOR_ITER import math import numbers import reprlib EQ_DIMENSIONS_MSG = '%s applies only to vectors of equal dimensions.' class Vector: """An n-dimensional vector""" def __init__(self, *components): # <1> self._components = tuple(components) # <2> def __repr__(self): return 'Vector' + (reprlib.repr(self._components)) # <3> def __iter__(self): return iter(self._components) # <4> def __abs__(self): return math.sqrt(sum(comp*comp for comp in self)) # <5> def __len__(self): return len(self._components) # <6> def __add__(self, other): if len(self) != len(other): raise ValueError(EQ_DIMENSIONS_MSG % 'Addition') return Vector(*(a+b for a, b in zip(self, other))) # <7> def __mul__(self, other): if isinstance(other, numbers.Number): return Vector(*(comp*other for comp in self)) # <8> else: return self.elementwise_mul(other) # <9> def elementwise_mul(self, other): if len(self) != len(other): raise ValueError(EQ_DIMENSIONS_MSG % 'Elementwise multiplication') return Vector(*(a*b for a, b in zip(self, other))) # <10> def __bool__(self): return any(self) # <11> # END VECTOR_ITER