Q and A for Section 5.2 CS 106 Victor Norman
Function definition, call syntax def ( ): Note: is a comma-separated list of identifiers, called parameters, that will refer to the values passed in Function call: (, ) result = (,, …) are called arguments.
Metaphor: Bank Teller A bank teller does work for you. You hand him some information (money or a paycheck or a request for money). – input parameters He does some work for you using your inputs. – code in the function He hands back some results to you (money or a receipt or both). – return value or values. You don’t really know exactly what he is doing, but that’s ok.
Why create functions? A function can be called a sub-program. – It takes inputs, does some computation using those inputs, and produces outputs. A function can be given a really nice name. def filterOutNonExcelFiles(fileList): excelFiles = filterOutNonExcelFiles(allFiles) – This makes the main code much easier to understand – i.e., more hospitable.
Why create functions? Thus, a function is an abstraction of code. – we don’t know how math.sin() works, but we can use it anyway. A function, once debugged, can be reused many times without worrying about whether the code is correct or not. – Code reuse. – Should help with debugging large programs. A function operates in its own little world. – Variables you create in the function are not accessible from outside – they have local scope.
Function definition vs. call You have to define a function before you can use it. def isOdd(num): “““Return True if num is an odd number, False if it is even.””” if num % 2 == 1: return True return False Function call: x = int(raw_input(“Enter a number: “)) if isOdd(x): print x, “is an odd number.”
Multiple returns in a function defn Q: Is it possible to use the return statement multiple times in the body of a function? A: Yes! If there are different places where you have determined what to return, just call return there.
Let’s define some functions! incr(x) isPositive(aNum) half(val) abs(y) area(w, h) max(val1, val2) min(val1, val2, val3) Functions on lists: incrAll(nums) listAbs(nums) removeNegs(nums) concatAll(listOfStr)
Where to define functions? Q: Where do you define functions? In the same file? In another place? A: Either in the same file or in another file. You can build up a file with some useful functions that you will use in multiple projects. You would have to import the file to use the functions. Or you can define functions in the same file, for use only in that file.
File organization # Comments about what this code does. # Author information, perhaps. # imports import sys from math import sin, cos # CONSTANT definitions WORLD_SIZE = 500 HOUSE_SIZE = 20 # Function definitions def isOdd(x): “””blah””” # main code num_houses = int(raw_input(“Enter how many houses to draw: “)) … etc …
What does this function do? Q: What does this function do? def unknown(val1, val2): tmp = val1 ** val2 return tmp A: It is the power function. Note: tmp is a local variable – only defined and accessible within the function.
Function call example Q: Write code to call unknown() and print the results. A: print "An unknown result: ", unknown(2.5, 3.5) What if unknown() had printed a result instead of returning it?...
Multiple function calls Q: Suppose I have written a function drawFigure(x, y) that draws a stick figure at location x, y. Write code to draw 2 stick figures, one at (100, 200) and the other at (300, 400). A: drawFigure(100, 200) drawFigure(300, 400)
return statement Q: What does return someVal do? A: It returns the value someVal to the caller, and, ends execution of code in the function. Q: How is this different than printing a value in a function? A: Printing sends out characters to the screen, but does not give a value back to the caller.
return vs. break Q: Is return similar to break in that it gets you out of a loop? A: Yes! Very observant of you. A return is another way to get out of an “infinite loop”, but, of course, it can only be used in a function.
Example def isPrime(n): “””return True if n is prime, False otherwise””” res = True # assume n is prime # try every division of n up to n / 2. for div in range(n / 2 + 1): if n % div == 0: # We found a divisor that divides n # perfectly. Therefore, we know n is # not prime. So return immediately res = False break # We’ve tried every divisor and not found any # that divides n perfectly. Therefore, n must # be prime. return res
Example def isPrime(n): “””return True if n is prime, False otherwise””” # try every division of n up to n / 2. for div in range(n / 2 + 1): if n % div == 0: # We found a divisor that divides n # perfectly. Therefore, we know n is # not prime. So return immediately return False # We’ve tried every divisor and not found any # that divides n perfectly. Therefore, n must # be prime. return True
What is the output? Q: What is the output from this code: def f(x): x += 3 print x z = 10 f(z) print z A: Output is 13 on one line, then 10 on the next. Why?
What is the result? Q: What does z hold at the end of this code?: def add3(x): x += 3 print x y = 7 z = add3(y) A: z holds the value None, because the function f() does not return anything. NOTE: printing a value is NOT the same as returning a value!
Scope Q: If you define a variable inside a function, can you access that variable from outside the function? Explain. A: No, you cannot access it. Once the code stops running the function, the local variables cease to exist.
Activation Records When a function is called, an activation record for that function is defined and pushed on the “stack”. – The parameters refer to the values passed in as arguments. – Local variables are created in the activation record. When the function returns, the activation record is deleted. If a function calls another function, another activation record for that function is added.
Local vs. Global Scope A local variable defined in a function definition has local scope. – It cannot be accessed from outside. – Same for parameters of the function definition. A global variable can be accessed within a function: – If the variable is not found already defined in the function, then the code looks in the global scope for the definition. – A global variable cannot be set from within a function.
Whiteboard: draw this def abc(x, y): t = x * 3 + y return t def dfg(z): res = abc(z, z + 1) return res x = dfg(3) print x
Syntax errors Q: Fix the syntax errors below: def average(x y) z = (x + y) / 2.0 return z print avrage(3, 77) A: need comma between x and y; need colon at end of line 1; return z is mis-indented; call to average is misspelled.
Mistakes students make (1) (Sung to the tune “Mistakes lovers make”) def area(w, h): w = 10 h = 30 return w * h Ignores the input parameters.
Mistakes students make (2) def area(w, h): print w * h theArea = area(10, 100) Print instead of return the computed value
Mistakes students make (3) def volume(w, h, 10): return w * h * 10 Function definition problems – not using identifiers only in the param list.
Mistakes students make (4) def volume(w, h, d): w * h * d Forgetting to return a value. def volume(w, h, d): return w * h * d volume(30, 77.2, 33) Forgetting to save the returned value.
Mistakes students make (5) def searchForString(aList, aStr): index = searchForString(listOfQuotes, aQuote) Thinking that the name of the parameter must match the name of the argument.
OK? Or not? Q: Will this work? def average(x, y): return (x + y) / 2.0 z = 10 q = average(z, z) A: Yes. Why not?!
Formal/actual parameters Q: In this code, identify the formal parameters and the actual parameters. def average(x, y): return (x + y) / 2.0 z = 10 q = average(z, z) A: x, y are the formal parameters. z and z are the actual parameters.
Global/local names Q: Is this legal? def average(x, y): return (x + y) / 2.0 y = 10 x = 20 print average(y, x) A: Yes. The value of y is assigned to x in average(). The value in x is assigned to y in average().
Creating global variables from inside a function? Q: Is there any way to set variables withint he body of a function that the uer could use later, or are they all local scope? A: You can do this, but please don’t, if at all possible. You can use the keyword global : def a(x, y): global z z = x + y print z # error a(3, 4) print z # prints 7
Number of parameters Q: Does a function need to know how many variables it is taking in? So, can you write a function that takes in an undetermined amount of variables? A: (Q should use the term “parameters”, not variables.) A function has to know how many parameters it has coming in. It is basing its output on its input parameters.
Undetermined # of params? Q: Can you write a function that takes in an undetermined number of parameters? A: You can… but you don’t want to… in this class… e.g., it is nice to have a function max() that takes any number of parameters: max(1, 7, 22, -33) max(-33, -1000, math.pi) max(1, 2, 3, 4, 5, 6, 7, 8, 8, 10, 11, 12, 13, 14, 15, 176)
Fruitless function? Q: When might you write and use a function that doesn't return anything? A: Perhaps the function prints out some stuff. Or this: def add1(x): x.append(1) lst = [ 7 ] add1(lst) # what is lst now?
Legal? Q: Is this legal? def average(x, y): return (x + y + z) / 3.0 z = print average(0, 1) A: It is legal. A function can access a variable in the global scope. This is often not very desirable, however.
Functions calling other functions Q: Can a function call another function? Can a function call itself? A: Of course! And, yes! A function that calls itself is called a recursive function. Don’t try this at home…
Interface vs. Implementation Q: Does a person have to know how a function does something in order to use it? A: No! A function defines what it does, and the caller doesn't care how it does it.
Knowing what a function does Q: How does a person know what a function can do for you? A: The writer of the function gives the function a nice descriptive name, with good formal parameter names, and a docstring (or comments) to describe what the function does.
Flow of Control Flow of control is how the thread of execution jumps around the code. I.e., what lines are being executed, when. Starts in the main code. Each time a function is called, execution “flows” to that function definition. Control flows back to the caller when the function returns.
Flow of control example 1 def khvr(a): 2 a *= return a 4 def se(x): 5 y = khvr(x + 1) 6 return y – 1 7 def rvd(p): 8 return se(p ** 2) 9 # main code 10 print rvd(2) Control flow 1 function defn 4 function defn 7 function defn 10 rvd called 8 se called 5 khvr called 2 khvr body 3 return from khvr to se 6 return from se to rvd 8 return from rvd to main 10 print result
Optional Parameters With “normal” function definitions, each parameter has to be given a value when the function is called. def aFunc(x, y, z): # 3 parameters aFunc(3, 4, “Hi, Isaac!”) # 3 values
Optional Parameters (2) With optional parameters, you can specify in the function definition the default value for parameters when the caller provides no value. def countdown(start = 10): “””print a countdown, starting at the given start value (10 by default).””” for i in range(start, 0, -1): print i countdown() # no value given, so start is 10 countdown(20) # use 20 for start
Optional Parameters (3) Notice that the code in the function is not “special” – uses start normally. Optional parameters (with default values) must be specified after non-optional (“required”) parameters.
Using optional params Q: If you are given this function, show two ways you could call it, with different numbers of arguments: def plot_points(x_list, y_list, symbol='ro') A: plot_points(xs, ys) plot_points(xs, ys, 'g-')
draw() signature Q: Write the signature of a function draw() that takes x, y, and radius as 3 required parameters, and takes canvas and width as optional parameters, with the default value for canvas being canv and the default value for width being 2. A: draw(x, y, radius, canvas=canv, width=2)
Q20 Q: For the previous draw() function, could a caller provide a width value without specifying (or overriding) the canvas value? A: Actually, yes. You have to use keyword arguments: draw(3, 10, 14, width=7) or, e.g., draw(x=3, y=10, radius=14, width=7) or, draw(width=10, y=1, radius=7, x=1000)
Checking input parameters Q: What are the reasons for checking input parameters to functions? A: Sometimes functions cannot operate if sent the wrong kinds of parameters – wrong values or wrong types. Checking input parameters gives better feedback to the programmer than just a SyntaxError or DivideByZero error.