def eval_metrics(model_type, params, dtrain, dtest, metrics):
    """Evaluates model with given parameters on train dataset,

    evaluates on test dataset and calculates given metrics

    Args:
        model_type (type, subclass of modelgym.models.Model): class of model
            (e.g modelgym.models.XGBClassifier)
        params (dict of str: obj): model parameters
        dtrain (modelgym.utils.XYCDataset): train dataset
        dtest (modelgym.utils.XYCDataset): test dataset
        metrics (list of modelgym.metrics.Metric): metrics to evaluate
    Returns:
        dict of str: obj: Mapping from metric name to metric result
    """

    model = model_type(params=params)
    model.fit(dtrain)
    y_pred_proba = None
    y_pred = None

    if any(map(lambda metric: metric.requires_proba, metrics)):
        y_pred_proba = model.predict_proba(dtest)
    if not all(map(lambda metric: metric.requires_proba, metrics)):
        y_pred = model.predict(dtest)

    metrics_results = {}
    for metric in metrics:
        pred = y_pred_proba if metric.requires_proba else y_pred
        metrics_results[metric.name] = metric.calculate(dtest.y, pred)

    return metrics_results