def eval_distances(self, X_test):
        distances = Distances(X_test, self.X_train)

        distances_manhattan_two_loops = distances.manhattan_two_loops()
        distances_manhattan_one_loop = distances.manhattan_one_loop()
        distances_manhattan_no_loop = distances.manhattan_no_loop()
        difference = distances.eval_distances(distances_manhattan_two_loops, distances_manhattan_one_loop)
        difference = distances.eval_distances(distances_manhattan_two_loops, distances_manhattan_no_loop)

        distances_euclidean_two_loops = distances.euclidean_two_loops()
        distances_euclidean_one_loop = distances.euclidean_one_loop()
        distances_euclidean_no_loop = distances.euclidean_no_loop()
        difference = distances.eval_distances(distances_euclidean_two_loops, distances_euclidean_one_loop)
        difference = distances.eval_distances(distances_euclidean_two_loops, distances_euclidean_no_loop)
    def predict(self, X_test, k=1, distance_type='euclidean_no_loop'):
        distances = Distances(X_test, self.X_train)
        if distance_type == 'manhattan_two_loops':
            this_distances = distances.manhattan_two_loops()
        elif distance_type == 'manhattan_one_loop':
            this_distances = distances.manhattan_one_loop()
        elif distance_type == 'manhattan_no_loop':
            this_distances = distances.manhattan_no_loop()
        elif distance_type == 'euclidean_two_loops':
            this_distances = distances.euclidean_two_loops()
        elif distance_type == 'euclidean_one_loop':
            this_distances = distances.euclidean_one_loop()
        elif distance_type == 'euclidean_no_loop':
            this_distances = distances.euclidean_no_loop()
        else:
            raise ValueError("Invalid type %s for distance_type" % distance_type)

        return self._select_labels(this_distances, k=k)