When you are working with functions it is really important to know the order
in which statements are executed. This is called the flow of
execution and we’ve already talked about it a number of times in this
chapter.

Execution always begins at the first statement of the program. Statements are
executed one at a time, in order, from top to bottom.
Function definitions do not alter the flow of execution of the program, but
remember that statements inside the function are not executed until the
function is called.
Function calls are like a detour in the flow of execution. Instead of going to
the next statement, the flow jumps to the first line of the called function,
executes all the statements there, and then comes back to pick up where it left
off.

That sounds simple enough, until you remember that one function can call
another. While in the middle of one function, the program might have to execute
the statements in another function. But while executing that new function, the
program might have to execute yet another function!

Fortunately, Python is adept at keeping track of where it is, so each time a
function completes, the program picks up where it left off in the function that
called it. When it gets to the end of the program, it terminates.

What’s the moral of this sordid tale? When you read a program, don’t read from
top to bottom. Instead, follow the flow of execution. This means that you will read the def statements as you
are scanning from top to bottom, but you should skip the body of the function
until you reach a point where that function is called.

Check your understanding

func-6-1: Consider the following Python code. Note that line numbers are included on the left.

Which of the following best reflects the order in which these lines of code are processed in Python?

(A) 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11

Although Python typically processes lines in order from top to bottom, function definitions and calls are an exception to this rule.

(B) 1, 2, 3, 5, 6, 7, 9, 10, 11

Although Python typically processes lines in order from top to bottom, function definitions and calls are an exception to this rule. Although this order skips blank lines, it still lists the lines of code in order.

(C) 9, 10, 11, 1, 2, 3, 5, 6, 7

This is close, in that Python will not execute the functions until after they are called, but there are two problems here. First, Python does not know which lines are function definitions until it processes them, so it must at least process the function headers before skipping over the functions. Section, notice that line 10 involves a function call. Python must execute the function square before moving on to line 11.

(D) 9, 10, 5, 6, 1, 2, 3, 6, 7, 10, 11

This is close, in that Python will not execute the functions until after they are called, but there is one problem here. Python does not know which lines are function definitions until it processes them, so it must at least process the function headers before skipping over the functions.

(E) 1, 5, 9, 10, 5, 6, 1, 2, 3, 6, 7, 10, 11

Python starts at line 1, notices that it is a function definition and skips over all of the lines in the function definition until it finds a line that it no longer included in the function (line 5). It then notices line 5 is also a function definition and again skips over the function body to line 9. On line 10 it notices it has a function to execute, so it goes back and executes that function. Notice that that function includes another function call. It returns from the function call and completes the assignment in line 6. Then it returns the result of line 7 and completes the assignment in line 10. Finally, it will go to line 11 after the function square and the assignment are complete.

func-6-2: Consider the following Python code. Note that line numbers are included on the left.