def loss(w):
    return (w-3.0)**2

def run(rate, steps=3):
    w = 0.0
    rows = [(0, w, loss(w))]
    for step in range(1, steps+1):
        gradient = 2*(w-3.0)
        w = w-rate*gradient
        rows.append((step, w, loss(w)))
    return rows

normal = run(0.1)
for step, w, value in normal:
    print(step, round(w, 6), round(value, 6))
print('rate=1', [w for _, w, _ in run(1.0)])
print('rate=1.1', [round(w, 6) for _, w, _ in run(1.1)])
assert abs(normal[-1][1]-1.464) < 1e-12
assert abs(normal[-1][2]-2.359296) < 1e-12
assert all(normal[j+1][2] < normal[j][2] for j in range(3))
assert [w for _, w, _ in run(1.0)] == [0.0, 6.0, 0.0, 6.0]
assert run(1.1)[-1][2] > run(1.1)[0][2]
