import math

def fit(values):
    if not values or not all(math.isfinite(x) for x in values):
        raise ValueError('finite nonempty training data required')
    mean = math.fsum(values)/len(values)
    variance = math.fsum((x-mean)**2 for x in values)/len(values)
    scale = math.sqrt(variance) or 1.0
    return mean, scale

def transform(values, state):
    if not all(math.isfinite(x) for x in values):
        raise ValueError('finite values required')
    mean, scale = state
    return [(x-mean)/scale for x in values]

train, test = [2.0, 4.0, 6.0], [8.0, 100.0]
state = fit(train)
print('training mean/scale', state)
print('training z', transform(train, state))
print('test z with training state', transform(test, state))
print('wrong all-data mean/scale', fit(train+test))
assert state[0] == 4.0
assert abs(transform([8.0], state)[0]-math.sqrt(6)) < 1e-12
assert fit(train+test)[0] == 24.0
assert transform([5.0, 6.0], fit([5.0, 5.0])) == [0.0, 1.0]
