def kde_pdf(data, kernel_func, bandwidth):
    """
    Calculate a kernel density estimate using the
    given kernel function. Kernel density estimation is a way
    to estimate the probability density function of a random
    variable in a non-parametric way.

    Parameters
    ----------
    data : arrays of floats

    kernel_func: function
        kernel function that applies to
        the fixed window and put more weight on points
        closer to the point being evaluated.

    bandwidth: float
        estimator bandwidth calculated by plugging in
        or from cross validation method.

    Return
    -------
    evaluate : function that evaluates x using given kernel
    """
    kernels = dict()
    n = len(data)
    for d in data:
        kernels[d] = kernel_func(d, bandwidth)

    def evaluate(x):
        """Evaluate `x` using kernels above."""
        pdfs = list()
        for d in data:
            pdfs.append(kernels[d](x))
        return sum(pdfs) / n

    return evaluate