import torch


def evaluate_dataloader(model, dataloader, metrics):
    """
    Return the average metric values for the given dataloader and model.
    
    Parameters
    ----------
    model : pytorch model
        The pytorch model to predict with.
    dataloader : pytorch dataloader
        Dataloader returning batches of inputs.
    metrics : dict
        Dictionary where keys are metric names (str), and values are metric 
        function (callable, taking (predictions, targets) as inputs).
    
    Returns
    -------
    values : dict
        Dictionary where keys are metric names (str), and values are metric 
        average values.
    """
    values = {}
    for key in metrics.keys():
        values[key] = 0
    
    model_device = next(model.parameters()).device
    model.eval()
    with torch.no_grad():
        for batch in dataloader:
            inputs = batch[0].to(model_device)
            targets = batch[1].to(model_device)
            
            preds = model(inputs)

            for key, metric in metrics.items():
                values[key] += metric(preds, targets).item() * inputs.shape[0]
            
    for key in values.keys():
        values[key] /= len(dataloader.dataset)
    return values