CS51A - Fall 2019 - Class 21

Example code in this lecture

   oo_calculator.py
   higher_order_functions.py
   montecarlo.py

Lecture notes

admin
   - 54/62 and the major
   - meet with CS faculty if you have more questions

higher order functions
   - have you ever typed a function into the shell, but forgot the parentheses?
      def my_function(x):
         return x+1

      >>> my_function(2)
      3
      >>> my_function
      <function my_function at 0x108e962f0>
      >>> abs
      <built-in function abs>

      - Notice that it does NOT give an error
      - Instead, it echoes the value, just like any other expression, in this case, the value is a function!

      >>> type(my_function)
      <type 'function'>

   - functions in python are values, just like everything else!
      >>> y = my_function
      >>> y
      <function my_function at 0x108e962f0>
      >>> y(2)
      3
      >>> my_abs = abs
      >>> my_abs(-10)
      10

      - we can pass them as parameters
      - we can return them from functions
      - we can even create them on the fly!

   - Motivating example: oo_calculator.py code
      - Look at oo_calculator.py's use of a dictionary of operators
      - The objects seem a little redundant to the functions inside
      - It's annoying to make a new class every time we need a new operator
      - We can make this nicer with higher order functions:
      def add(a,b):
         return a+b
      def sub(a,b):
         return a-b
      def hamburger(a,b):
         return a**b / 7
      operators = {
         "+": add,
         "-": sub,
      }
      # ...
      operators["🍔"] = hamburger
      a, op, b = "5 🍔 7".split(" ")
      print(operators[op](a,b))
   - what do the first four function in higher_order_functions.py code do?
      - take two arguments and do standard mathematical calculations

   - what does apply_function do in higher_order_functions.py code?
      - takes three arguments
         - the first is a function!
      - applies the function passed as the first argument to the second and third argument and returns the result

   - We can call our apply_function function:
      >>> apply_function(add, 2, 3)
      5
      >>> apply_function(subtract, 2, 3)
      -1

      - to pass a function as a parameter you just give the name of the function as the argument

   - def
      - what the keyword def actually does is
         1) create a new function
         2) assign that function to a variable with the name of the function

map
   - what does the apply_function_to_list function do in higher_order_functions.py code?
      - takes a function and a list as parameters
         - you can tell that the parameter "function" is a function because we apply it in the line with the append in it
      - iterates through each value in the list
         - applies the function
         - appends the result of the function to a list that is then returned
         - You have written this function so many times, just changing the function you call
            - Sorry! You can use this from now on.
      - High-level: applies the function to each element in the list and returns a new list containing the result from each of those applications
      - For example:
         >>> apply_function_to_list(double, [1, 2, 3, 4])
         [2, 4, 6, 8]

filter
   - what does the filter_list function do in higher_order_functions.py code?
      - also takes a function and a list as parameters

      - are there any expectations on what the function should do/return?
         - it's used in an if statement
         - it should return a bool, i.e. True or False
      - The filter function is like map in that it applies the function to every element in the list
         - BUT, it only keeps those where the function returns True for that element

      - For example,
         >>> map(is_even, [1, 2, 3, 4])
         [False, True, False, True]
         >>> filter_list(is_even, [1, 2, 3, 4])
         [2, 4]
      - You have written this function so many times, just changing the function you call
         - Sorry! You can use this from now on.

monte carlo sampling (we'll do this on Tuesday maybe)
   - monte carlo methods are a way of determining the answer to numerical problems via random sampling
   - general idea:
      - generate random samples
      - look at the outcome of those random samples
      - use the answer to the outcomes to estimate the answer
   - An example: calculating the area
      - we want to calculate the area of a shape, specifically, if I draw an arbitrary shape within a 1 by 1 box, can you tell me the area?
         - kind of hard!
      - what if I put a bunch of points uniformly in the box and could tell how many were inside the shape?
         - e.g., if I put 1000 points in the box with a triangle shape, how many would you expect in the triangle?
            - about 500
            - what would be the area of the triangle?
               - 500/1000 = 0.5
      - key idea: use the proportion of points that fall inside the shape to estimate the area
   - what are the areas of these two shapes:
      - triangle
      - quarter circle

   - look at in_circle and in_triangle functions in montecarlo.py code
      - what do these functions do?

   - write a function monte_carlo that takes two parameters: number of trials and a shape function
      - generate "trials" random points (x, y points between 0 and 1)
      - count how many are "inside" the shape
      - return the proportion, i.e., count/trials
      - Hint:
         import random
         random.random() # returns random value between 0 and 1

   - look at monte_carlo function in montecarlo.py code

   - We can use this to estimate the area of different shapes:
      >>> monte_carlo(1000, in_triangle)
      0.484
      >>> monte_carlo(10000, in_triangle)
      0.5005
      >>> monte_carlo(100000, in_triangle)
      0.49756
      >>> monte_carlo(100000, in_circle)
      0.7854
      >>> monte_carlo(100000, in_circle)*4
      3.14896
      >>> monte_carlo(1000000, in_circle)*4
      3.141972
      >>> monte_carlo(10000000, in_circle)*4
      3.141894