CMU 15-112: Fundamentals of Programming and Computer Science
Class Notes: Functions Redux (part 2)


  1. Keyword args (**kwargs)
  2. Functions inside functions
  3. Closures + Non-local variables
  4. Non-local variables fail on setting (use nonlocal)
  5. Functions that return functions
  6. Function decorators

  1. Keyword args (**kwargs)
    def f(x=1, y=2): return (x,y) print(f()) # (1, 2) print(f(3)) # (3, 2) print(f(y=3)) # (1, 3) [here is where we use a keyword arg] def f(x, **kwargs): return (x, kwargs) print(f(1)) # (1, { }) print(f(2, y=3, z=4)) # (2, {'z': 4, 'y': 3})

  2. Functions inside functions
    def f(L): def squared(x): return x**2 return [squared(x) for x in L] print(f(range(5))) try: print(squared(5)) except: print("squared is not defined outside f")

  3. Closures + Non-local variables
    def f(L): myMap = dict() def squared(x): result = x**2 myMap[x] = result return result squaredList = [squared(x) for x in L] return myMap print(f(range(5)))

  4. Non-local variables fail on setting (use nonlocal)
    def brokenF(L): lastX = 0 def squared(x): result = x**2 lastX = x return result squaredList = [squared(x) for x in L] return lastX print(brokenF(range(5))) def fixedF(L): lastX = 0 def squared(x): nonlocal lastX result = x**2 lastX = x return result squaredList = [squared(x) for x in L] return lastX print(fixedF(range(5)))

  5. Functions that return functions
    def derivativeFn(f): def g(x): h = 10**-5 return (f(x+h) - f(x))/h return g def f(x): return 5*x**3 + 10 fprime1 = derivativeFn(f) fprime2 = derivativeFn(fprime1) print(f(3)) # 145, 5*x**3 + 10 evaluated at x == 3 print(fprime1(3)) # about 135, 15*x**2 evaluated at x == 3 print(fprime2(3)) # about 90, 30*x evaluated at x == 3

  6. Function decorators
    @derivativeFn def h(x): return 5*x**3 + 10 print(h(3)) # 135, matches fprime1 from above.