from functools import reduce
import torch


def compute_accuracy(pred, data):
    """Computes the accuracy of predicted sequences.

    Args:
        pred(torch.Tensor): predictions produces by a model in index form, can be both a vector of last words
            and a matrix containing a batch of predicted sequences.
        data(torch.Tensor): the gold standard to compare the predictions against.

    Returns:
        float: the fraction of correct predictions.
    """
    # Handle different cases, 1 vs all outputs
    denom = reduce(lambda x, y: x * y, pred.shape)

    if len(data) == 1:
        target = data[0][:, 1:]
    else:
        # Here we have to ignore padding from the computation
        target = data[0][:, 1:]
        pred[data[2][:, 1:] == 0] = -1
        denom = denom - torch.sum(1.0 - data[2])

    return float(torch.eq(target, pred).sum()) / denom