def linear_function(a, b):
    return lambda x: a * x + b

f = linear_function(2, 3)
for x in [0, 1, 2]:
    print("f(%s) = %s" % (x, f(x)))

def degree_two_polynomial(a, b, c):
    def evaluate(x):
        return a * x**2 + b * x + c

    return evaluate

p = degree_two_polynomial(1, 2, 3)

for x in [0, 1, 2]:
    print("p(%s) = %s" % (x, p(x)))

def polynomial(coefficients):
    return lambda x: sum([c * x**p for p, c in enumerate(coefficients)])

print("polynomial([3, 2, 1])(2) =", polynomial([3, 2, 1])(2))

def combine(f, g):
    def evaluate(*args, **kwargs):
        return f(g(*args, **kwargs))

    return evaluate

h = combine(abs, lambda x, y: x - y)

print("h(3, 5) =", h(3, 5))
