import math
def smooth(values,alpha):
    if not values or not 0<alpha<=1 or not all(math.isfinite(v) for v in values):
        raise ValueError('finite nonempty values and 0<alpha<=1 required')
    level=values[0]
    levels=[level]
    forecasts=[None]
    for value in values[1:]:
        forecasts.append(level)  # prediction before seeing this observation
        level=alpha*value+(1-alpha)*level
        levels.append(level)
    return forecasts,levels
values=[10.0,14.0,12.0,20.0]
for alpha in [0.5,0.2]:
    forecasts,levels=smooth(values,alpha)
    print(alpha,'one-step forecasts',forecasts,'levels',[round(z,6) for z in levels],
          'next forecast',round(levels[-1],6))
f,l=smooth(values,0.5)
assert f==[None,10.0,12.0,12.0] and l==[10.0,12.0,12.0,16.0]
assert abs(smooth(values,0.2)[1][-1]-12.832)<1e-12
assert smooth(values,1.0)[0][1:]==values[:-1]
