import json


def get_best_hyperparams(hyperparams_dict, fit_params_dict, best, file_name=None):
    """
    Helper function to extract the numerical values of best hyperparameters from hyperopt into a more easily usable format.
    :param hyperparams_dict: Dictionary of hyperparameter values
    :param fit_params_dict: Dictionary of fit parameter values
    :param best: The best hyperparameters as returned by hyperopt
    :param file_name: Directory plus name of the file you want to save the best parameters to.  File name must end in .json as this is the expected output format
    :return: Parameter dictionary. Contains both model hyperparameters and epochs parameter for model fit.
    """
    # Extract hyperparameters for the model
    best_params = {}
    for key, val in best.items():
        if key in hyperparams_dict:
            input_ = hyperparams_dict[key]
            if input_[0] == 'choice':
                best_params[key] = input_[1][val]
            else:
                best_params[key] = val

    # The only other parameter I need to get out is the number of epochs to train for.
    # I'll put it all into the best_params dictionary, but I'll need to pop it out before defining the model
    best_params['num_epochs'] = fit_params_dict['num_epochs'][1][best['num_epochs']]

    if file_name is not None:
        json_out =json.dumps(best_params)
        f = open(file_name, "w")
        f.write(json_out)
        f.close()

    return best_params