You may be wondering about the choice of parameters for thedrawBarfunction. Obviously, the year for which a bar is being drawn and the height of the bar are the changeable parts in the drawing of a bar. But, why iswindowalso a parameter to this function? After all, we will be drawing all of the bars in the same window; it doesn’t seem to change.
The reason for makingwindowa parameter has to do with the scope of variables in function definitions. Scope refers to the places in a program where a given variable may be referenced. Remember each function is its own little subprogram. The variables used inside of one function are local to that function, even if they happen to have the same name as variables that appear inside of another function.
The only way for a function to see a variable from another function is for that variable to be passed as a parameter. Since theGraphWin(in the variablewin) is created inside ofmain, it is not directly accessible
indrawBar. However, thewindowparameter indrawBargets assigned the value ofwinfrommain
whendrawBaris called. To see how this happens, we need to take a more detailed look at the function invocation process.
A function definition looks like this.
def <name>(<formal-parameters>): <body>
Thenameof the function must be an identifier, andformal-parameters is a (possibly empty) list of variable names (also identifiers). The formal parameters, like all variables used in the function, are only accessible in thebodyof the function. Variables with identical names elswhere in the program are distinct from the formal parameters and variables inside of the functionbody.
A function is called by using its name followed by a list of actual parameters or arguments.
When Python comes to a function call, it initiates a four-step process. 1. The calling program suspends at the point of the call.
2. The formal parameters of the function get assigned the values supplied by the actual parameters in the call.
3. The body of the function is executed.
4. Control returns to the point just after where the function was called.
Returning to the Happy Birthday example, let’s trace through the singing of two verses. Here is part of the body frommain.
sing("Fred") print
sing("Lucy") ...
When Python gets tosing("Fred"), execution ofmainis temporarily suspended. At this point, Python looks up the definition ofsingand sees that it has a single formal parameter,person. The formal parameter is assigned the value of the actual, so it is as if we had executed this statement:
person = "Fred"
A snapshot of this situation is shown in Figure 6.1. Notice the variablepersoninside ofsinghas just been initialized.
sing("Fred") print sing("Lucy")
def main(): def sing(person):
happy() happy()
print "Happy birthday, dear", person + "." happy()
person = "Fred"
person: "Fred"
Figure 6.1: Illustration of control transferring tosing.
At this point, Python begins executing the body ofsing. The first statement is another function call, this one tohappy. Python suspends execution ofsingand transfers control to the called function. The body of
happyconsists of a singleprint. This statement is executed, and then control returns to where it left off insing. Figure 6.2 shows a snapshot of the execution so far.
sing("Fred") print sing("Lucy")
def main(): def sing(person): happy() happy()
print "Happy birthday, dear", person + "." happy()
def happy():
print "Happy Birthday to you!" person = "Fred"
person: "Fred"
Figure 6.2: Snaphot of completed call tohappy.
Execution continues in this manner with Python making two more side trips back tohappyto complete the execution ofsing. When Python get to the end ofsing, control then returns tomainand continues immediately after the function call. Figure 6.3 shows where we are at that point. Notice that theperson
sing("Fred") print sing("Lucy")
def main(): def sing(person):
happy() happy()
print "Happy birthday, dear", person + "." happy()
person = "Fred"
Figure 6.3: Snaphot of completed call tosing.
variable insinghas disappeared. The memory occupied by local function variables is reclaimed when the function finishes. Local variables do not retain any values from one function execution to the next.
The next statement to execute is the bareprintstatement inmain. This produces a blank line in the output. Then Python encounters another call tosing. As before, control transfers to the function definition. This time the formal parameter is"Lucy". Figure 6.4 shows the situation assingbegins to execute for the second time.
sing("Fred") print sing("Lucy")
def main(): def sing(person):
happy() happy()
print "Happy birthday, dear", person + "." happy()
person = "Lucy"
person: "Lucy"
Figure 6.4: Snaphot of second call tosing.
Now we’ll fast forward to the end. The function body ofsingis executed for Lucy (with three side trips throughhappy) and control returns tomainjust after the point of the function call. Now we have reached the bottom of our code fragment, as illustrated by Figure 6.5. These three statements inmainhave caused
singto execute twice andhappyto execute six times. Overall, nine total lines of output were generated.
sing("Fred") print sing("Lucy")
def main(): def sing(person):
happy() happy()
print "Happy birthday, dear", person + "." happy()
person = "Lucy"
Figure 6.5: Completion of second call tosing.
Hopefully you’re getting the hang of how function calls actually work. One point that this example did not address is the use of multiple parameters. When a function definition has several parameters, the actual parameters are matched up with the formal parameters by position. The first actual parameter is assigned to the first formal paramter, the second actual is assigned to the second formal, etc.
As an example, look again at the use of thedrawBarfunction from the future value program. Here is the call to draw the initial bar.
drawBar(win, 0, principal)
When Python transfers control todrawBar, these parameters are matched up to the formal parameters in the function heading.
The net effect is as if the function body had been prefaced with three assignment statements.
window = win year = 0
height = principal
You must always be careful when calling a function that you get the actual parameters in the correct order to match the function definition.