8.8. Function Composition (functions calling functions)

It is important to understand that each of the functions we write can be used and called from other functions we write. This is one of the most important ways that computer programmers take a large problem and break it down into a group of smaller problems. This process of breaking a problem into smaller subproblems is called functional decomposition.

Here’s a simple example of functional decomposition using two functions. The first function called square simply computes the square of a given number. The second function called sum_of_squares makes use of square to compute the sum of three numbers that have been squared.

Activity: CodeLens 8.8.1 (clens8_8_1)

Even though this is a pretty simple idea, in practice this example illustrates many very important Python concepts, including local and global variables along with parameter passing. Note that the body of square is not executed until it is called from inside the sum_of_squares function for the first time on line 6.

Also notice that when square is called (at Step 8, for example), there are two groups of local variables, one for square and one for sum_of_squares. Each group of local variables is called a stack frame. The variables x, and y are local variables in both functions. These are completely different variables, even though they have the same name. Each function invocation creates a new frame, and variables are looked up in that frame. Notice that at step 9, y has the value 25 in one frame and 2 in the other.

What happens when you to refer to variable y on line 3? Python looks up the value of y in the stack frame for the square function. If it didn’t find it there, it would go look in the global frame.

In the example below, we create a turtle drawing program that uses function composition.

The turtle example above has 5 different functions. Two of them are helper functions that move a turtle to a random location and set a turtle to draw in a random color. The other three are drawing functions that cause the turtle to draw things. The global part of the code (lines 47-53) create the window and the turtle and sets the turtle speed to 10 so the turtle draws quickly. Then there is a for loop that iterates 10 times. Each time through the loop a new random size is generated and then the draw_design() function is called with the random size. The draw_design function calls the other four functions, ane even calls the draw_triangle function twice.

Check your Understanding

System Message: ERROR/3 (/home/bmiller/Runestone/books/FOPP-PIE/_sources/FunctionsParametersScope/FunctionComposition.rst, line 127)

Duplicate ID – see FunctionsParametersScope/FunctionComposition, line 69

.. activecode:: ac8_8_1
   :language: python
   :autograde: unittest
   :practice: T

   **1.** Write two functions, one called ``addit`` and one called ``mult``. ``addit`` takes one number as an input and adds 5. ``mult`` takes one number as an input, and multiplies that input by whatever is returned by ``addit``, and then returns the result.
   ~~~~

   =====

   from unittest.gui import TestCaseGui

   class myTests(TestCaseGui):

      def testOne(self):
         self.assertEqual(mult(1), 6,"Testing the function mult with input 1 (should be 6)")
         self.assertEqual(mult(-2), -6, "Testing the function mult with input -2 (should be -6)")
         self.assertEqual(mult(0), 0, "Testing the function mult with input 0 (should be 0)")

      def testTwo(self):
         self.assertEqual(addit(1), 6, "Testing the function addit with input 1 (should be 6)")
         self.assertEqual(addit(-2), 3, "Testing the function addit with input -2 (should be 3)")
         self.assertEqual(addit(0), 5, "Testing the function addit with input 0 (should be 5)")

   myTests().main()
You have attempted of activities on this page