CS 2120: Topic 3¶
Video for this week:¶
Yikes, what happened to your voice?
Sorry for my voice in videos 2 and 3 for this week.. I’ve caught a bit of a cold, and it happened to show up between recording parts 1 and 2.
Functions¶
Say you want to be able to do a certain thing (i.e. find the area of a circle)
You may want to do it multiple times.. ideally you’d want a cleaner way to do this than to copy and paste it X times in your editor..
In Python, we can use a function:
def my_function(parameter): result = parameter * 2 print(result)
Once you’ve defined a function, you can call it exactly the same way you’d call a built-in function like
print
.- Let’s call our function:
>>> my_function(2) 4 >>> my_function(7) 14
When we call
my_function
, the Python interpreter executes the statements that make up the function, in order.
Function Parameters¶
Imagine an
add_print(a,b)
function that adds two numbers and prints the result. You want it to add any two numbers, not just two specific numbers. A functionadd_print(3,5)
that can only add 3 to 5 wouldn’t be very useful. It would only ever print8
. So we introduce parameters.Parameters are like variables. When you call the function, the parameter values get filled with whatever you set them to in the call.
Let’s create an
add_print
function:def add_print(a,b): print(a+b)
Now that the function is defined, we can call it. Like this:
>>> add_print(5,2) 7
The call
add_print(5,2)
gets handled like this:The interpreter checks to see if it knows about a function named
add_print
We just defined
add_print
, so it does.When we defined it, we told the interpreter it should have two parameters:
a
andb
.The interpreter now takes the values in the call (in this case,
5
and2
) and assigns those values to the function parametersa
andb
.In other words, the first thing the interpreter does in this case is set
a = 5
andb = 2
Then the interpreter executes the body of the function, with the parameters having their new values.
Abstraction¶
What is abstraction?
Abstraction: reduce complexity by hiding unnecessary information
When you press a button to make coffee, you probably don’t care about what the machine is doing, and you don’t need to.
Why is abstraction important?
Try this…
Write down a sequence of instructions (i.e. a “program”) for boiling an egg. You can use the functions locate(pot)
, setup(egg_in_water_in_pot)
, and boil(egg)
.
Now try this…
Write down a sequence of instructions (i.e. a “program”) for boiling an egg. You cannot use any functions.
You’ve now written two programs at two levels of abstraction. Which was easier?
- Functions allow us to add on layers of abstraction.
A low level function might worry about how to set the individual pixels of the display to show the letter
A
.Would you want to cut-and-paste that code every time you needed to print
A
?Instead, we have a function called
print
that hides all those messy details from us.We call
print
,print
calls other functions, which call other functions, which call other functions…
Without organizing things into levels of abstraction, writing complex software would be impossibly difficult.
A note on indentation¶
The general format for defining a function is:
def function_name(p1,p2,p3,p4, ... ): statement 1 statement 2 ... statement m
statement 1, statement 2, ... , statement m
make up the body of the functionYou tell Python which statements make up the body of the function by using indentation (i.e. hitting the
tab
key).without indenting, you will get a syntax error (more specifically an IndentationError)
make sure to be consistent in your indentation (whether you use a
tab
,4 spaces
, …).
Execution Flow¶
To make sense of programs, we need to know which instruction gets executed when
Execution begins at the first
statement
of the program. Statements are executed from top to bottom, one line at a time.- However, when the interpreter reaches a function, it processes the
def
statement only.. it does not go into the body of the function. it “skips over” those lines and executes the first line outside of the function.
- However, when the interpreter reaches a function, it processes the
The statements in the body of the function are not executed until we call the function.
Let’s trace through this program:
1 2 3 4 5 6 7 8 9
def dostuff(a,b): c = b*2 d = (a+4)*2 c = d + c return c x = 2 y = 3 print(dostuff(x,y))
Test yourself
In what order are these lines of code above processed by Python? (i.e. 1,2,3,5,9,etc.)
Function values¶
Notice how
dostuff
ended with areturn
statement.The
return
statement tells Python: “return this value to whoever called this function”With
return
, functions evaluate into values.- Consider:
>>> print(dostuff(2,2)) 16 >>> print(dostuff(4,4)) 24 >>> print(dostuff(2,2) + dostuff(4,4)) 40
When the interpreter hits a
dostuff
function call, it executes the function, which results in a returned value.So, when execution flow comes back to the calling program, the call to
dostuff
gets replaced with whatever value gotreturn
ed.
Composition¶
Python functions can be composed just like mathematical functions.
We’ve already seen
print
composed withdostuff
- We can nest functions, too:
>>> dostuff(dostuff(2,2),dostuff(2,2)) 72
- If you get confused tracing nested functions, try the following:
Find a function call you can evaluate. Evaluate it.
Replace the function call with the value it returns
Keep doing this until you’re down to one value.
Variable scope¶
If you set a variable inside a function, it is local to that function.
No other function can see a function’s local variables. They are local. Consider this code:
def domore(a,b): c = 2*a + b return c
- What happens if I do this::
>>> print(domore(4,4)) 12 >>> print(c) NameError: name 'c' is not defined
Error! But
c
is defined indomore
! Why did we get an error?Variables have scope. We will come back to this later in the course.
Optional parameters for functions¶
Sometimes you want a function to have an optional parameter, with a pre-specified default value.
This is done very easily:
def my_function(a,b,c=3): do_stuff()
When you call
my_function(5,12)
,a
will have value5
,b
value12
andc
value3
.Because we specified a default value for
c
, we don’t have to provide one when we call the function.If we want to override the default though, we can:
my_function(4,3,2)
.
Import¶
Sometimes you want to make a big library of functions. Maybe they’re related to analysis data from your research.
You’d like to access some of those functions from another program that you’re writing.
- If you put your functions in a file called ‘myfuncs.py’, you can import them into another program like this:
>>> from myfuncs import *
(The
*
here means “everything)- You could also use:
>>> import myfuncs
- BUT, after importing in this way, to access a function called
dostuff
in the filemyfunc
you’d have to type: >>> myfuncs.dostuff(...)
- BUT, after importing in this way, to access a function called