Publications: 75 | Followers: 1

## Functions

Publish on Category: Birds 0

CS 115 Lecture
FunctionsTaken from notes by Dr. Neil Moore
The idea behind functions
Sometimes we have to repeat the same combination of control structures and steps in several different places.Functionslet you write the codeonce… And then use it inmultipleplacesIt’s like defining a new verb in the languageWe’ve already seen several built-in and library functionsprint, input, rangemath.sin,random.randrangeConstructors:Graphwin, RectangleMethods:setText,getMouse
The idea behind functions
And we know how to call them:If it doesn’t return a value:func(arguments)If it does return a value:result =func(arguments)We’ve even written one of our own!def main():defines a function namedmain
Calling a function: syntax
To call (“invoke”) a function, you write its name, followed by itsargumentsin parentheses.The name of the function is an identifierSame rules as for variable namesLetters, digits, underscore, cannot start with digitThe arguments are a list of expressions, separated by commasArguments are “inputs” that the calling statement sends to the functionEach function specifies how many arguments it takesSome like random() take no argumentsBut they still need parentheses even if they’re empty!
Calling a function: semantics
When you call a function:The interpreter pauses execution of the code that made the function callBut it remembers where it wasThe interpreter runs the code of the called functionIt makes the arguments available to the function by copying them into the parametersThe function finishes orreturnsThe interpreter picks up where it left offThe value of the function call Is whatever value the function returned (or None if it does not explicitly return anything)
Structured programming guarantees
When a subprogram (function) finishes, control returns to where the function was called fromA function should have ONE return statement as the last line of the function definition (One entrance, one exit guarantee) or NO return statement, in which case all the statements in the definition are executed, then control returns to where it was called from
Defining a function
Todefinea function, you need to specify three things:Thenameof the functionWhatparametersthe function takesWith a name for each parameterThis is called the parameter listWhat the functiondoeswhen calledThecodeorbodyof the functionAs usual, the body is an indented block
Defining functions
defname (parameters):bodyDefines a function called “name”Goes at thetop levelof the fileUnindented(at the left margin)Not insidemainor other function definitions!Parameters are a comma-separated list of identifiersThe function receives one argument for each parameter it has
Defining functions
When Python sees the definition, it does NOT run the body!Instead it remembers its definition and its nameThe body runs when youcallthe functionThat’s why we needmain()at the end of our fileIf you don’t call a function, it will not run!It does NOT run just because it is defined in the fileSomething to check for when debugging
A simple function definition
def triangle (): #no parametersprint(“*”)print(“**”)print(“***”)Now when you calltriangle(), it prints those 3 lines.
A simple function definition
Function definitions can contain any control structure you like.def triangle():for i in range(1, 3 + 1):print(“*” * i)This function does the same thing as the previous version.“Multiplying” a string by an integer repeats the string that many times“*” * 3evaluates to“***”
Function arguments
Most functions don’t do exactly the same thing every time.Instead, they takeargumentsthat control the details of what happensprint: what value to printinput: what prompt to displayrandrange: what range to choose the random number fromWe use arguments to send informationintoa functionThey are the function’s “inputs”(not the same as user input from the keyboard!)
Parameters and arguments
In a function definition, we create placeholders for arguments, calledparameters.Inside the function, parameters work like variablesWhen you call the function, each argument’s value is stored in the corresponding parameterIt is a run-time error if you give more or fewer arguments than the number of parameters
Parameters and arguments
Call by value: the parameter holds the argument’svaluebut isn’t the same place in memory as the argumentIf you assign a value to the parameter, it does NOT change the argument!We’ll see later that the situation is more complicated when you have mutable arguments like lists or graphics objects.
A function with a parameter
Let’s change our triangle function to take one argument, the height of the triangle (number of lines)def triangle(size):for i in range(1, size + 1):print(“*” * i)Nowtriangle(3)will print the three-line-high triangle.
A function with a parameter
When triangle is called, the 3 is copied into the parametersize,beforeexecuting the bodyRemember the terminology!sizeis the parameter3 is the argument (the value we give the parameter this time)Note thatsizeisonlyaccessible inside the function (its scope)And you set (give a value to)sizeby calling the function with an argument
Multiple parameters
Functions can have more than one parameterdef triangle(size, letter):for i in range(1, size+1):print(letter * i)triangle(2, “+”)+++
Multiple parameters
When calling the function, you must supply the same number of arguments as parameterstriangle(3) # ERRORtriangle(3, “+”, “-”) # ERRORIf arguments are out oforder, or …if arguments are the wrongtype, the function will eventually give an error
Parameters out of order
defsum_sub(a, b):return (a + 10) – bIf you call this function assum_sub(1, 3)you get a return value of 8If you call this function assum_sub(3, 1)you get a return value of 12Is this an error? It’s not a syntax error, it MAY be a semantics error depending on the context of the program
Parameters of the wrong type
defmy_print(a, b):print(a * 2, b)If you call this asmy_print(3, 4)it displays6 4If you call it asmy_print(“abc”, “def”)it displaysabcabcdefIs this an error? Not a syntax error, it may be a semantics error depending on what the function was supposed to do.
Parameters of wrong type
On the other hand, using the last version of triangle, If you call it astriangle(“+”, 3), you WILL get an error when the “+” argument is used as the ending point for the range – which must have integers.So Python does NOT check anytypeswhen the arguments are passed in. If one of them is the wrong type for how it is USED in the function, then you get the error when that statement is executed.
Returning a value
A function can send a value (or values) back to the caller byreturningit (or them)Syntax:returnexpressionor just plain:returnSemantics:First evaluate the expressionThen end the function’s execution and erase all the local variables created in the functionSend back to the calling statement the value of the expression, or the special valueNoneif there was no return statement at all
Multiple return values
You can write functions in Python which return more than one thing at the same timedef funsum_and_diff(a, b):return (a+b, a-b)How do you call it? Thesimplest way is:x, y =sum_and_diff(9, 5)x gets the first value returned, y gets the secondcan also be written as (x,y) =sum_and_diff(9,5)
Returning a value
The expression is the “result of” the functionRemember the structured programming guaranteesEach control structure hasone exit.So a function should haveone returnat the endIf the function doesn’t need to return a value, you can either put a plainreturnat the end or no return at all. This gives the same result, the function returns to where it was called from.
Parameters/return values vs. input/output
Parameterstake “input” from thestatement that calls the functionReturn valuessend “output” to thestatement that called the functioninput()takes input fromthe keyboard (the user)print()sends output tothe screen (the user)Good functions usually use parameters and return values, notinputandprintThen you can use them not only with user input…… but also with graphical programs, files, computed data…When should a function useinputorprint?When the function’s sole purpose is to interact with the user
A function that returns a value
deftriangular_number(num):sum = 0for i in range(1,num+ 1):sum += Ireturn sumWhen we call the function, run it and see what it returns:print(triangular_number(5))The function returns15The interpreter plugs that value into the expression:print(15)15
Local variables
All the variables defined in a function arelocalto that functionFor example,iin our triangle functionThe locals only exist while the function is runningLifetimeorextent:the time during which a variable takes up memoryVariable is “born” when it is initialized…… and “dies” when the function it is in returns
Local variables
Other functions cannot see local variables at all!Thescopeof any variable is which part of the code can see itThe scope of a local variable is the body of the function it is in, starting from its initialization to the end of the definitionScope doesn’t care about what else the function calls!This means your functioncannotrefer directly to variables in other functions.
Local variables
If you need access to information from another functionUse a parameter and argument to send information into a functionUse the return value to get information back outAglobal variableis defined outside any functionTheir scope is from the definition all the way to the end of theFILEAvoid these! (they are NOT allowed in this class at all)They make it hard to understand what a function doesThey can be changed by ANY function at ANY time!They causeside effects –things that a function does which are not evident in the header or call
Where to put function definitions
Functions (at least in this class) should be defined at thetop levelof your source fileNot indentedSo NOT inside another function’s definitionFunctions must be defined before the code that calls them executesSo if function main calls function triangle:def trianglemust come before the call tomain()But it’s ok if it comes afterdef mainIn general, put the call tomainat the end of the file and you’ll be fine
A complete program with functions
defmain():number = int(input(“Enter a number: “))limit =square(number)print(“Counting up to”, limit)countto(limit)defsquare(x):return x ** 2defcountto(number):for i in range(1, number):print(I, end= “, “)print(number)main()Let’s try rearranging the functions
Documenting functions
Functions are “subprograms”, so they should be documented like programsWrite aheader commentfor each functionThree parts:purpose, preconditions,postconditionsYou should still have the usual design comments in the function’s codePurpose: Describes what the function is supposed to do,in terms of the parametersNotwhere it is used:sqrt’sdocumentation does not say “used in calculation of distance”# Purpose: Compute thesqreof the number x# Purpose: Print a triangle of stars with size rows
Documenting functions
Preconditions: What has to be true before the function is called?What should the type of each parameter be?Are there any other restrictions on the parameter values?# Preconditions: x is an integer or a float# Preconditions: size is a positive integer
Documenting functions
Postconditions: what will be true after the function finishes?What type will be returned, if any?Any other promises we can make about the return value?What user input/output will the function have done?# Postconditions: returns a positive number# of the same type as x# Postconditions: Prints size lines to# standard output
Documenting functions
Preconditions andpostconditionsare like a legal contract“If you give me this (pre), I promise to give you that (post)”Helps to identify where a bug could be. If a function does the wrong thing:If the preconditions are all satisfied, it’s a bug in the functionIf they are not, it’s a bug in thecaller
Where to put function documentation
In most languages, the 3 P’s (purpose, preconditions,postconditions) are in a comment just before the function definitionPython has another way to do it: documentation strings or “docstrings”These go inside the function definition, as the very first thingSo it must be indented!It starts with ‘’’ (three single quotes)Continues across multiple lines until another‘’’Cannot have blank lines before or after it
Where to put function documentation
Docstringsare not really commentsThey still don’t do anything, but the interpreter is aware of themThehelpfunction in the Python shell displays a function’sdocstringhelp(square) # just the function name, no ()You must execute the program first so the definition has been loaded into memoryExample: countsquare-doc.py
Unit testing
Functions can be tested in the same way as whole programsUnit testing:Testing individual functions in isolationYou can verify that the function keeps its promisesThree columns in the test plan:Description of the test case, e.g. “Normal case, positive integer.”Inputs: all the arguments you will send to the functionThe preconditionsAlso list whatever user input is given while it is runningExpected output: what the function should return and any outputs to screens or filesThe return value(s)Distinguish the return value from any printed output
Driver functions
Once the test plan is written, doing the whole program tests is easy.Just run the program, type the input and verify the outputBut how do we do that with separate functions?One way: call the function from the shell windowThe interpreter will print the return value of the function if you type in a function callYou must run the program at least once as a whole before you can do this – get the functions loaded in memory first!
Driver functions
Another way: write adriverfunctionA function likemain(maybe namedtesterfor example)But instead of following your design, it just calls the function with the inputs from the unit testYou can check whether the function returned the correct thing!This is one place where it’s okay to hard-code values, especially for argumentsWhen you want to run unit tests, just changemain()totester()An example: countsquare-test.py
They avoid repeated codeThey allow you to re-use code in a later programThey provide more structure to programsThe details of complicated procedures are hidden awayYou can choose to look at the details or at the big pictureEach piece of code deals with one topicMakes it easier to focus on one part at a timeAnd for different programmers to work on different parts of the same program at the same time
They are easier to test and debugYou can focus on testing one piece at a timeThen put those well-tested pieces together into larger unitsTesting at each stage of development means less time spent debugging!
Functions make the program run slightly slower than just embedding the code.Arguments have to be copied to parameters, etc.Some languages (especially compiled ones) avoid thisEvery function takes a bit of memory while it is runningParameters, local variables, “where was I?”If functions call functions hundreds of calls deep, it could add up to a good piece of memoryUsually only comes up with recursion (a function calls itself)More lines of code if you only call it onceTwo or three extra lines: def, return, and calling the functionIf you call it more than a few times, usually it saves lines!Usually the benefits are much higher than the costs!
Single-stepping with functions
Remember the three kinds of stepping in the debugger. They have much to do with functions.Step into: Pause at the next line (maybe at the top of another function)Step over: Pause at the next line ofthisfunction.Step out: Pause when this function returnsLet’s see those in action while watching the call stack
Tracing functions
What if you need to trace a program that has functions?Our traces have a column for the line numberWe’ll put the function name on the table tooHow do we show variables for each function?Could have columns forallof them …… but that could be a lot!And wouldn’t work with recursive functionsWe’ll indicate when we call a function or return from oneEach function has its own table, which disappears when it returns
Tracing with functions: example
Let’s trace this program:def triangular (num):sum = 0for i in range(1,num+ 1):sum += Ireturn sumdef pyramidal (n):sum = 0for i in range(1, n + 1):sum += triangular(i)return sumdef main():pyr= pyramidal(2)print(pyr)main()
Trace of functions
Trace, continued
Trace, concluded
Debugging functions: the call stack
What happens if we set a breakpoint in triangular?How did we get there?Called by pyramidalSo we’ll go back there when triangular returnsHow did we get to pyramidal?Called by mainSo we’ll go back here when pyramidal returnsWhen functions return, execution goes back to the calling codeSo the interpreter has to keep track of all the callingWho called the current function, who called them, who called them…
The call stack
The interpreter tracks all this info with a data structure called thecall stackEach item on the call stack is a function call in progressThe local variables for that function are also kept on the stackCalling causes a new item to be put on top of the stackReturning removes the item that is on top of the stackThe debugger shows it to you butupside down!Both WingIDE and IDLE show it in such a way that main() is at the top of the call stack window, new functions are added as you go downComputer scientists consider the start of any stack as the bottom and add things to the top

0

Embed

Share