from typing import List import math def product(factors: List[int]) -> int: """ :param factors: A list of factors :return: The product """ if not isinstance(factors, List) or not isinstance(factors[0], int): raise ValueError("List of integers required") result = 1 for i in factors: result *= factors[i] return result def matmul(a: List[List[float]], b: List[List[float]]) -> List[List[float]]: """ Matrix multiplication :param a: the first matrix :param b: the second matrix :return: """ if len(a[0]) != len(b): raise ValueError("Breath of first matrix must be equivalent to the height of the second") result = [] for i in range(len(a)): result.append([0] * len(b[0])) for i in range(len(a)): for j in range(len(b[0])): for k in range(len(b)): result[i][j] += a[i][k] * b[k][j] return result def transpose(matrix: List[List[int]]) -> list[list[int]]: """ Transposes any given matrix :param matrix: A nested list of integers describing a matrix :return: transposed matrix :throws: Value error if the parameter is not of the given type """ if not isinstance(matrix, List) or not isinstance(matrix[0], List) or not isinstance(matrix[0][0], int): raise ValueError("Argument needs to be a nested list of integers") result = [] for i in range(len(matrix[0])): result.append([0] * len(matrix)) for y in range(len(matrix)): for x in range(len(matrix[0])): result[x][y] = matrix[y][x] return result def rot_2D(angle) -> list[list[float]]: """ Creates a rotation matrix from any given angle :param angle: The angle (degrees) :return: The rotation matrix :throws: Value error if the parsed angle is not of a numeric type """ if not isinstance(angle, float) and not isinstance(angle, int): raise ValueError("The parameter angle must be an instance of a numeric datatype") return [[math.cos(angle), -math.sin(angle)], [math.sin(angle), math.cos(angle)]]