import torch


def test(model, test_loader, loss_func, device):
    """Function to evaluate model's perfomance on a test dataset

        Args:
            model (torch model): a pytorch model
            test_loader (torch dataloader): a pytorch dataloader object
            loss_func (torch loss function): a pytorch loss function
            device (str): to specify whether cpu or gpu is to be used

        Returns:
            loss (float): loss evaluated according to the loss function for the given model and test data
            accuracy (float): accuracy of the model on test data
    """

    running_loss = 0.0
    correct_preds = 0
    model.eval()
    with torch.no_grad():
        for batch_idx, (features, labels) in enumerate(test_loader):
            features, labels = features.to(device), labels.to(device)
            outputs = model(features)
            predictions = torch.argmax(outputs, dim=1)
            correct_preds += torch.sum(predictions==labels).item()
            running_loss += loss_func(outputs, labels).item()
    num_of_batches = int(len(test_loader.dataset)/test_loader.batch_size)
    loss = running_loss / num_of_batches
    accuracy = 100.0 * correct_preds / len(test_loader.dataset)
    return loss, accuracy