Writing Functions

Functions are bits of code that do specific things so you don't have to recreate the wheel every time you have to do something complicated. Here we'll program few mathematical functions \[ f(x) = x - 4 \tag{1} \] $$ g(x) = -2x + 1 \tag{2} $$ $$ h(x) = \frac{x^2}{12} \tag{3} $$ and graph them individually and in combination.
Combining functions.
Notes and Code Outcome

Plotting a Math Function

First we graph equation (3) $$ h(x) = \frac{x^2}{12} \tag{3} $$ by creating a loop to generate x values, and then using the equation to calculate the corresponding y values. We'll plot these points as spheres.

              xaxis = curve(pos=[vec(-10,0,0), vec(10,0,0)])
              yaxis = curve(pos=[vec(0,-10,0), vec(0,10,0)])

              for x in range(-10, 10, 1):
                  y = x**2 / 12.0
                  sphere(pos=vec(x,y,0), radius=0.25)

            

Line 4: The for loop that creates values of x between -10 and 10 with a step of 1.

Lines 5: Calculate y using equation (3)

Line 6: Draw the sphere.

Connect the dots

We can draw line segments between the dots by creating a curve and appending points to the curve within the loop.

              # create curve
              line = curve()

              for x in range(-10, 10, 1):
                  y = x**2 / 12
                  sphere(pos=vec(x,y,0), radius=0.25)
                  #append points to curve
                  line.append(pos=vec(x,y,0))
            

Line 2: create curve

Lines 8: Add points to the curve.

Creating a Function

Now, we're going to calculate the y-value for Equation 3 \[ h(x) = \frac{x^2}{12} \tag{3} \] using a function. A function needs input/s and has output/s.

Input: Our equation needs an x value.

Output/s: The function returns a y value

The function is defined on Lines 1-3

Line 1:

  • The def keyword indicates that we're defining a function.
  • the name of the function is h, it can be pretty much anything, but adheres to the naming rules for variables (can't start with a number for example)
  • the input of the function is listed within parentheses. The function recieves the input value and gives it the variable name x_in for use within the function. This variable only exists within this function, making it a local variable, so I could have named it anything. In fact, it would probably have been better to name it simply x but I thought giving it a different name would clarify the difference between the value sent to the function (on line 12) and the variable name in the function.

Line 2:

  • Here we calculate the y value of the function.

Line 3:

  • Here we return the calculated value (s) to the program.
  • NOTE: Functions stand alone. When you run the program, the function definition is stored in memory and saved until the function is called.

Line 12:

  • Calling the function. The function is called by using its name, and passing the input values. The function returns the result to the place in the code where the function is called.


                    def h(x_in):
                        y_out = x_in**2 / 12
                        return y_out

                    xaxis = curve(pos=[vec(-10,0,0), vec(10,0,0)])
                    yaxis = curve(pos=[vec(0,-10,0), vec(0,10,0)])

                    # create curve
                    line = curve()

                    for x in range(-10, 10, 1):
                        y = h(x)
                        sphere(pos=vec(x,y,0), radius=0.25)
                        #append points to curve
                        line.append(pos=vec(x,y,0))

                  

Adding a second function

To demonstrate that you can use the same variable names within a function (so they're local variables) without affecting the variables outside the function, I'll add equation (1)


              def f(x):
                  y = x - 4
                  return y

              def h(x_in):
                  y_out = x_in**2 / 12
                  return y_out

              xaxis = curve(pos=[vec(-10,0,0), vec(10,0,0)])
              yaxis = curve(pos=[vec(0,-10,0), vec(0,10,0)])

              # create curves
              line = curve()
              line1 = curve()

              for x in range(-10, 10, 1):
                  y = h(x)
                  sphere(pos=vec(x,y,0), radius=0.25)
                  #append points to curve
                  line.append(pos=vec(x,y,0))

                  #draw equation 1
                  y = f(x)
                  sphere(pos=vec(x,y,0), radius=.25, color=color.red)
                  line1.append(pos=vec(x,y,0), color=color.red)

            

Now you should be able to add as many functions as you'd like (and reuse the same variable names).

Adding Functions

What happens if we add equations (1) and (3) $$ k(x) = f(x) + h(x) $$
Show Notes ▼

You can add, subtract, multiply, and divide functions in a similar way. And, you can use as many functions as you'd like.

Functions within Functions

What happens if we put equation (1) into equation (3): \[ m(x) = f \circ h \] which can also be written as: \[ m(x) = f(h(x)) \]
Show Notes ▼

A Function to Draw Functions: Passing a function to another function

You will have noticed that in the for loop where we're drawing the spheres and lines, we're repeating the same code for each function.

Whenever you see repetition in code it usually indicates that there's some way to simplify or combine things. So, we'll write a function that takes a mathematical function, and draws it.


                      def f(x):
                          y = x - 4
                          return y

                      def h(x_in):
                          y_out = x_in**2 / 12
                          return y_out

                      def drawFunction(f):
                          c = curve()
                          for x in range(-10,10,1):
                              y = f(x)
                              sphere(pos=vec(x,y,0), radius=0.25)
                              c.append(pos=vec(x,y,0))

                      xaxis = curve(pos=[vec(-10,0,0), vec(10,0,0)])
                      yaxis = curve(pos=[vec(0,-10,0), vec(0,10,0)])

                      # draw the functions:
                      drawFunction(f)
                      drawFunction(h)
                    

Notice how much shorter the code is.

Default Values

Of course the drawFunction function only draws white points and curves. Let's leave that as the default, allow it to be changed. We'll do this by adding another input variable to the drawFunction function, but give it a default value (of white: color.white)


                      def f(x):
                          y = x - 4
                          return y

                      def h(x_in):
                          y_out = x_in**2 / 12
                          return y_out

                      def drawFunction(f, col=color.white):
                          c = curve()
                          for x in range(-10,10,1):
                              y = f(x)
                              sphere(pos=vec(x,y,0), radius=0.25, color=col)
                              c.append(pos=vec(x,y,0), color=col)

                      xaxis = curve(pos=[vec(-10,0,0), vec(10,0,0)])
                      yaxis = curve(pos=[vec(0,-10,0), vec(0,10,0)])

                      # draw the functions:
                      drawFunction(f)
                      drawFunction(h, color.red)
                    

With a default value, we don't break our old code like:


                      drawFunction(f)
                    
But can change any of the other function calls to give it a different color.

                      drawFunction(f, color.red)
                    

Exercise

A. Create a function that graphs:

$$ n(x) = \left| \frac{x^2}{10} - 2 \right| \tag{4} $$

B. Change the drawFunction function so it takes a second, optional variable, that sets the step in the for loop to allow you to plot more points, and make smoother curves.

Exercise

B. Change the drawFunction function so it takes a second, optional variable, that sets the step in the for loop to allow you to plot more points, and make smoother curves.

Use this to graph equation (4): $$ n(x) = \left| \frac{x^2}{10} - 2 \right| \tag{4} $$

Hint: to use non-integer steps, you'll have to use the arange function instead of range in your for loop.