def test_random_appendargs(self): """`general.appendargs`: Randomized Validator. Tests the behavior of `appendargs` by feeding it randomly generated arguments. Raises: AssertionError: If `appendargs` needs debugging. """ concat = lambda s1, s2: s1 + s2 """callable: Appends one string to the other.""" # appendargs with no arguments should return `None`. self.assertIsNone(appendargs(None)) for i in range(self.n_tests): c_arg = compose(str, _np.random.uniform)(0.0, 100.0, size=self.n) """list of float: Argument to be appended.""" arg = compose(str, _np.random.uniform)(0.0, 100.0, size=self.n) """list of float: Test argument.""" target = arg + c_arg """float: Expected output from appendargsd function.""" adder = appendargs(concat, c_arg) """callable: Test input.""" # Adder should be a function. self.assertIsInstance(adder, type(compose)) result = adder(arg) """str: Adder output.""" # Programatic adder result should match manual sum. self.assertEqual(result, target)
def test_edge_cases_appendargs(self): """`general.appendargs`: Edge Case Validator. Tests the behavior of `appendargs` with edge cases. Raises: Exception: If at least one `Exception` raised is not of the expected kind. """ with self.assertRaises(AttributeError): # No arguments to append. appendargs(sum)([2])
def test_random_factors(self): """`linalg.factors`: Randomized Validator. Tests the behavior of `factors` by feeding it randomly generated arguments. Raises: AssertionError: If `factors` needs debugging. """ for i in range(self.n_tests): n = _np.random.randint(1, self.max_val) """int: Random input.""" f = factors(n) """list of int: Test input.""" # Factors should be a list of integers. self.assertIsInstance(f, list) map(appendargs(self.assertIsInstance, int), f)
def test_invalid_args_appendargs(self): """`general.appendargs`: Argument Validator. Tests the behavior of `appendargs` with invalid argument counts and values. Raises: Exception: If at least one `Exception` raised is not of the expected kind. """ with self.assertRaises(TypeError): # No arguments. appendargs()([2]) with self.assertRaises(TypeError): # Non-function argument. appendargs(None, 2)([2]) with self.assertRaises(TypeError): # With **kwargs. appendargs(sum, 2, key="value")([2])
def batches(X, Y, k): """K-Batch Creator. Partitions the given sets of features and observations into batches of at least `k` elements. The number of data points does not differ by more than one data point from one batch to the other. Args: X (np.matrix): Feature set. Shape: n x d. Y (np.matrix): Observation set. Shape: n x 1. k (int): Minimum number of data points per batch. Raises: AttributeError: If `X` is not a valid matrix. ValueError: If `X` or `Y` are empty matrices or if `k` is not a natural number. TypeError: If `X` or `Y` are not valid matrices or if `k` is not an int. Returns: list of np.matrix: Partitions of at least `k` elements per batch. """ validate_datasets(X, Y) if type(k) != int: raise TypeError("Expected an 'int' for `k`, saw '%s' instead." % type(k).__name__) if k <= 0: raise ValueError("Value of `k` not greater than 0: %d." % k) n, d = X.shape """(int, int): Number of data points and number of features.""" indices = [i for i in range(n)] """list of int: Shuffled indiced of data points.""" shuffle(indices) batches = [] """list of np.matrix: All batches.""" n_training_points = compose(int, np.floor)(float(n) / compose(float, min)(n, k)) """int: Number of data points destined for training.""" i = None """int: Current data point index.""" for q in range(n_training_points): tot = compose(appendargs(min, k), len)(indices) """int: Number of data points to add to current batch.""" batch = np.zeros((tot, d + 1)) """int: Current batch.""" for j in range(tot): i = indices.pop() batch[j, :] = np.concatenate((X[i, :], Y[i, :]), 1) compose(batches.append, np.matrix)(batch) if len(batches) == 1: n_left = len(indices) if n_left == 0: raise ValueError("Unable to partition %d data points into length " "%d batches." % (n, k)) batch = np.zeros((n_left, d + 1)) """int: Current batch.""" batch = np.concatenate( [np.concatenate((X[i, :], Y[i, :]), 1) for i in indices], 0) compose(batches.append, np.matrix)(batch) else: j = 0 """int: Current batch offset.""" while len(indices) > 0: i = indices.pop() datapoint = compose(np.matrix, np.concatenate)((X[i, :], Y[i, :]), 1) """np.matrix: Remaining data point.""" m = j % len(batches) """int: Current batch index.""" batches[m] = compose(np.matrix, np.concatenate)((batches[m], datapoint)) j += 1 return batches