import numpy as np


def mean_square_error(y_true: np.ndarray, y_pred: np.ndarray) -> float:
    """
    Calculate MSE loss

    Parameters
    ----------
    y_true: ndarray of shape (n_samples, )
        True response values
    y_pred: ndarray of shape (n_samples, )
        Predicted response values

    Returns
    -------
    MSE of given predictions
    """
    return float(np.mean(((y_true - y_pred) ** 2)))


def misclassification_error(y_true: np.ndarray, y_pred: np.ndarray, normalize: bool = True) -> float:
    """
    Calculate misclassification loss

    Parameters
    ----------
    y_true: ndarray of shape (n_samples, )
        True response values
    y_pred: ndarray of shape (n_samples, )
        Predicted response values
    normalize: bool, default = True
        Normalize by number of samples or not

    Returns
    -------
    Misclassification of given predictions
    """
    # num_of_mistakes, num_of_samples = 0, y_true.shape[0]
    # for i in range(num_of_samples):
    #     if y_true[i] != y_pred[i]:
    #         num_of_mistakes += 1
    # if normalize:
    #     return num_of_mistakes / num_of_samples
    # return num_of_mistakes
    num_of_samples = y_true.shape[0]
    loss = np.sum(np.where(y_true != y_pred, 1, 0))
    if normalize:
        return loss / num_of_samples
    return float(loss)


def accuracy(y_true: np.ndarray, y_pred: np.ndarray) -> float:
    """
    Calculate accuracy of given predictions

    Parameters
    ----------
    y_true: ndarray of shape (n_samples, )
        True response values
    y_pred: ndarray of shape (n_samples, )
        Predicted response values

    Returns
    -------
    Accuracy of given predictions
    """
    # true_predictions, num_of_samples = 0, y_true.shape[0]
    # for i in range(num_of_samples):
    #     if y_pred[i] == y_true[i]:
    #         true_predictions += 1
    # return true_predictions / num_of_samples
    return np.sum(np.where(y_true == y_pred, 1, 0)) / y_true.shape[0]


def cross_entropy(y_true: np.ndarray, y_pred: np.ndarray) -> float:
    """
    Calculate the cross entropy of given predictions

    Parameters
    ----------
    y_true: ndarray of shape (n_samples, )
        True response values
    y_pred: ndarray of shape (n_samples, )
        Predicted response values

    Returns
    -------
    Cross entropy of given predictions
    """
    raise NotImplementedError()
