<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def predict(self, X):
 """Predict the class labels for the provided data Parameters X : array-like, shape (n_query, n_features). Test samples. Returns ------- y : array of shape [n_samples] Class labels for each data sample. """

        # TODO: Make classification of multiple samples a bit more effective...
        if X.ndim > 1 and X.shape[1] != 1:
            out = []
            for x in X:
                out += self.predict(x)
            return out
        X = X.flatten()

        if self.metric == 'minkowski':
            dists = np.sum(np.abs(self._data - X) ** self.p, axis=1)
        else:
            # TODO: Implement other metrics.
            raise ValueError("Only Minkowski distance metric implemented...")

        argument = np.argsort(dists)
        labels = self._labels[argument[:self.n_neighbors]]

        if self.weights == 'distance':
            weights = 1 / dists[argument[:self.n_neighbors]]
            out = np.zeros((len(self._classes), ), 'float')
            for i, c in enumerate(self._classes):
               out[i] = np.sum(weights[labels == c])
            out /= np.sum(out)
            y_pred = self._labels[np.argmax(out)]
        else:
            y_pred, _ = mode(labels)

        return y_pred.tolist()