Question 2: Defining Vectors (7 points)
Define class Vector for n-dimensional vectors as follows:
Vector(l): Creates a new vector with dimension len(l) from list l of numbers; raises TypeError if l is not a list or not all of its elements are of type int or float.
v.dim(): Returns the dimension (length) of the vector.
v. __getitem__(i): Returns the i-th component of the vector, where components are indexed starting from 1; raises IndexError if i is less than 1 or greater than the dimension of the vector.
v. __setitem__(i, x): Sets the i-th component of vector v to x, where components are indexed starting from 1; raises IndexError if i is less than 1 or greater than the dimension of the vector.
v.__str__(): Returns a string with a readable representation of the vector, see the example below.
v. __add__(other): Returns a new vector that is the component-wise sum of v and other; raises ValueError if other is not of type Vector or if other is of a different dimension.
v.__mul__(other): If other is of type int or float, returns a new vector resulting from the scalar multiplication of v with other, , i.e. with each component of v multiplied by scalar. If other is of type Vector, returns the dot product of v and other, which is the sum of the products of the corresponding components; raises ValueError if other is of different dimension in this case. If the type of other is none of Vector, int, float, raises AssertionError.
v.__rmul__(other): Defined exactly like v.__mul__(other)
Python uses following equivalent notations:
v[i] = v.__getitem__(i)
v[i] = x = v.__setitem__(i, x)
str(v) = v.__str__()
v + other = v.__add__(other)
v * other = v.__mul__(other)
other * v = v.__rmul__(other) if other.__mul__(v) is not defined