Functions
Contents
Functions#
Goals of today’s lecture#
Today we’ll be focusing on functions in Python.
What is a function? What are they good for?
How do you create or define a function?
Key concepts:
def
,return
, and arguments.How do you use or call a function?
More details on functions:
Input
type
.Default argument values.
What is a function?#
A function is a re-usable piece of code that performs some operation (typically on some input), and then typically returns a result (i.e., an output).
Breaking this down:
Input: a variable defined by the user that is passed into a function using the
(input)
syntax.Also called an argument.
Functions can have multiple arguments.
Output: the variable returned by a function after this operation is performed.
If a
return
value is not specified, a function will returnNone
.
A very simple function#
We’ll explore the syntax more in a bit, but this will give you a sense for what we’re talking about.
def square(x):
"""Returns the square of X."""
return x**2
square(1)
1
square(2)
4
Why functions?#
In principle, we could just rewrite the same code each time we want to execute that operation. So why bother defining functions at all?
The answer lies in modular programming.
As operations become more and more complex, it becomes unwieldy (and just inefficient) to copy/paste the same code again and again.
In modular programming, we emphasize building re-usable chunks of code.
Functions (and loops) are ways to re-use chunks of code that solve basic, recurring problems.
Learning to think in a modular way can be hard! But it’s a helpful approach to breaking down a problem into its sub-components.
Functions we’ve encountered#
We’ve already encountered a number of functions in this course.
print
#
Input: something to
print
.Output: technically,
None
.“Side effects”:
print
s out input to designated log (by default, the terminal/Jupyter cell).
print("Hello!")
Hello!
sorted
#
Input: a
list
Output: a sorted
list
.
unsorted = [2, 1, 5]
sorted(unsorted)
[1, 2, 5]
Defining a function#
In Python, a new function can be created or defined using the def
keyword, followed by the name of the function.
See the square
function definition below:
Function name:
square
.Function arguments:
x
.Function
return
:x ** 2
.
def square(x):
"""Returns the square of X."""
return x**2
Executing a function#
To execute a function, we can reference the function name (like a variable), followed by the parentheses ()
and any arguments/input for the function.
## Function name = square
## Input = 2
square(2)
4
## Function name = square
## Input = 4
square(4)
16
What type is a function?#
A function belongs to a special type
in Python, called function
.
type(square)
function
A more complex function#
What if we wanted a function that did the following:
if
the inputx
is even, we square it.if
the inputx
is odd, we justreturn
that number.
def square_if_even(x):
"""Squares x if x is even; otherwise return x."""
if x % 2 == 0: ## check if even
return x ** 2 ## if so, return square
else: ## otherwise..
return x ## just return x
## 2 is even, so square it
square_if_even(2)
4
## 3 is odd, so just return it
square_if_even(3)
3
Another more complex function#
So far, our functions have only had a single argument. But functions can take in many arguments.
Let’s define a function with two inputs, which just adds those inputs together.
def add_two_numbers(num1, num2):
"""Adds num1 to num2."""
return num1 + num2
add_two_numbers(1, 2)
3
add_two_numbers(5, 3)
8
Check-in#
What would the function below produce if the input x
was 25
?
More generally: how would you describe what this function does?
def mystery_func(x):
if x % 5 == 0:
return True
return False
Solution#
mystery_func
can be thought of as a binary “check” for whether a particular number is divisible by 5
.
mystery_func(25)
True
mystery_func(28)
False
Check-in#
Write a function that takes a name
as input and return
s the formatted str
: "My name is {name}."
The code below can get you started:
def hello(name):
### your code here
# Your code here
Solution#
def hello(name):
return "My name is {name}".format(name=name)
hello("Sean")
'My name is Sean'
Interim summary#
What we’ve learned so far:
A function is a re-usable piece of code that does something.
A function can take in some input and
return
some output.In principle, a function can be as complex as you need (can contain
if
statements,for
loops, etc.).Word of caution: a function should be modular.
In principle, a function also take in many different inputs and even produce multiple outputs.
Again: be careful not to make things too complex.
Function arguments: the details#
Beyond the basics, there are several other important things to know about the arguments for a function:
It’s important to be aware of what
type
your function expects as an argument.Arguments can have default values.
Some arguments can be accessed with a keyword, while others are positional arguments.
Argument type
#
Some languages, like Java, require that you specify the type
of an argument (and variable names, etc.).
Python doesn’t require that, but it’s still important to be aware of.
Otherwise, you can run into a
TypeError
.If you’re interested: Python uses something called duck typing.
Example of a TypeError
#
Here, the square
function performs an operation with x
that requires x
to be an int
.
def square(x):
return x ** 2
square("two")
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Input In [22], in <cell line: 3>()
1 def square(x):
2 return x ** 2
----> 3 square("two")
Input In [22], in square(x)
1 def square(x):
----> 2 return x ** 2
TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'int'
How to avoid a TypeError
?#
In practice, the best way to avoid a TypeError
is to document your code.
In the
docstring
under a function, you can write details about what the function expects, e.g., whether the input is anint
, astr
, etc.
def square(x):
"""
Parameters
------
x: int
number to be squared
Returns
-------
int
square of x
"""
return x ** 2
Check-in#
Will the function below result in an error if you called it on the input "test"
? Why or why not?
def mystery_func(x):
return x ** 3
Solution#
As before, Python throws an error, because there’s no way to raise a str
to the power 3
.
mystery_func("test")
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Input In [24], in <cell line: 1>()
----> 1 mystery_func("test")
Input In [23], in mystery_func(x)
1 def mystery_func(x):
----> 2 return x ** 3
TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'int'
Default values#
A default value is the value taken on by an argument by default. If no other value is specified, this is the value assumed by the function.
In the function definition, a default value can be specified by setting: arg_name = default_value
.
In the example below,
name
is required.But
major
has a default value of"COGS"
.
def my_info(name, major = "COGS"):
return "My name is {name}, and my major is {major}.".format(name = name, major = major)
Even if we don’t specify a value for major
, the function will run just fine––it just uses the default value.
my_info("Sean")
'My name is Sean, and my major is COGS.'
Overriding a default value#
A default value can be overridden in the call to the function itself.
Note that this can reference the argument name (
major
), or just occupy the correct position in the series of arguments. (More on this later.)
my_info("Sean", major = "LIGN")
'My name is Sean, and my major is LIGN.'
my_info("Sean", "LIGN")
'My name is Sean, and my major is LIGN.'
Arguments without a default must be referenced!#
If an argument doesn’t have a default, the function will throw an error if you don’t pass in enough arguments.
my_info()
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Input In [29], in <cell line: 1>()
----> 1 my_info()
TypeError: my_info() missing 1 required positional argument: 'name'
Check-in#
Why does the following code not throw an error?
my_info("LIGN")
'My name is LIGN, and my major is COGS.'
Positional vs. keyword arguments#
An argument to a function can be indicated using either:
Its position, i.e., in the list of possible arguments.
A keyword, i.e., the name of that argument.
A positional argument uses the relative position of the arguments to determine which is which.
def exponentiate(num, exp):
return num ** exp
## Raise 2 ^ 3
exponentiate(2, 3)
8
## Raise 3 ^ 2
exponentiate(3, 2)
9
A keyword argument uses the name of the argument to determine which is which.
Even if the positions are swapped, the keyword will take priority.
(Note that the best practice is to keep the order consistent, however.)
## Raise 2 ^ 3
exponentiate(num = 2, exp = 3)
8
## Raise 2 ^ 3
exponentiate(exp = 3, num = 2)
8
Position before keyword#
Once you’ve used a keyword argument, you can’t rely on position for any arguments coming after that keyword. This will throw a
SyntaxError
.However, a positional argument can come before a keyword argument.
## This is incorrect
exponentiate(num = 2, 3)
Input In [36]
exponentiate(num = 2, 3)
^
SyntaxError: positional argument follows keyword argument
## This is fine
exponentiate(2, exp = 3)
8
Conclusion#
This concludes our initial introduction to functions. If there is time, there are also two more challenging practice problems below to work on.
Practice problems#
Problem 1#
Write a function called fizzbuzz
. It should take in a single argument, x
, and follow this behavior:
If
x
is divisible by both3
and5
, return thestr
"fizzbuzz"
.If
x
is divisible by only3
(and not5
), return"fizz"
).If
x
is divisible by only5
(and not3
), return"buzz"
).
Note: this is part of a famous problem in coding interviews!
def fizzbuzz(x):
pass ## Replace this with your code
Problem 2#
Write a function called product, which takes a list
(lst
) as input, and returns the product of every item in the list.
def product(lst):
pass ## Replace this with your code
Practice problems: solutions#
Problem 1#
def fizzbuzz(x):
if x % 5 == 0 and x % 3 == 0:
return "fizzbuzz"
if x % 3 == 0:
return "fizz"
if x % 5 == 0:
return "buzz"
fizzbuzz(15)
'fizzbuzz'
fizzbuzz(25)
'buzz'
Problem 2#
def product(lst):
prod = 1
for i in lst:
prod = prod * i
return prod
product([1, 2, 3])
6
product([9, 10, 0])
0