def exponential_smoothing(series, alpha):
    """
    :define: Exponential smoothing weights all of the observations, while exponentially decreasing the weights as we move further back in time.
    :define2: Exponentiality is hidden in the resuriveness of the function: y-hat = a * y-not + (1-a) * (previous y-not)
    :param series: dataframe with time stamps
    :param alpha: float [0.0, 1.0], smoothing parameter. The smaller alpha is, the more influence the previous observations have, and the smoother the series is
    :return: exponentially smoothed dataframe, predicts one observation in the future
    """
    result = [series[0]]  # first value is same as series
    for n in range(1, len(series)):
        result.append(alpha * series[n] + (1 - alpha) * result[n - 1])
    return result