- a return value (fruitful function) or without (void function)
- a return value (fruitful function) or without (void function)
- parameters that have default values
- parameters that have default values
- Write a function knowing the difference in outcomes of print and return statements
- Write a function knowing the difference in outcomes of print and return statements
- Explain how positional, keyword, and default arguments are copied into parameters
- Explain how positional, keyword, and default arguments are copied into parameters
- Make function calls using positional, keyword, and default arguments and determine the result.
- Make function calls using positional, keyword, and default arguments and determine the result.
- Use the debugger to trace function invocations to determine control flow
- Use the debugger to trace function invocations to determine control flow
%% Cell type:markdown id: tags:
%% Cell type:markdown id: tags:
## Functions
## Functions
A function definition has two parts:
A function definition has two parts:
-**head** or **header** - the line that begins a function definition. It must be of the form:
-**head** or **header** - the line that begins a function definition. It must be of the form:
`def <func_name>(parameters):`
`def <func_name>(parameters):`
`parameters` may be empty or it may be a comma-separated list of variables. The values these variables will refer to will be passed in when the function call occurs.
`parameters` may be empty or it may be a comma-separated list of variables. The values these variables will refer to will be passed in when the function call occurs.
`<func_name>` must follow the same naming rules as variables. Typically, <u>function names are verbs</u> while <u>variable names are nouns</u>.
`<func_name>` must follow the same naming rules as variables. Typically, <u>function names are verbs</u> while <u>variable names are nouns</u>.
-**body** - the rest of the function definition, consisting of lines of code. These lines must be indented.
-**body** - the rest of the function definition, consisting of lines of code. These lines must be indented.
The full function definition has the form:
The full function definition has the form:
```
```
def <func_name>(parameters):
def <func_name>(parameters):
body_line1
body_line1
body_line2
body_line2
...
...
```
```
%% Cell type:code id: tags:
%% Cell type:code id: tags:
``` python
``` python
# TODO: Write a function named cube that takes one number input and cubes and return that value
# TODO: Write a function named cube that takes one number input and cubes and return that value
# The first line is called the function header
# The first line is called the function header
# Notice that all the other lines are indented the same amount (4 spaces)
# Notice that all the other lines are indented the same amount (4 spaces)
# The best practice in a Jupyter Notebook is to press tab
# The best practice in a Jupyter Notebook is to press tab
# If you don't run the cell, Jupyter Notebook won't know about the function
# If you don't run the cell, Jupyter Notebook won't know about the function
# Open the debugger and notice what is created in the kernel state when this cell runs
# Open the debugger and notice what is created in the kernel state when this cell runs
# Look under the "function variables" section
# Look under the "function variables" section
```
```
%% Cell type:code id: tags:
%% Cell type:code id: tags:
``` python
``` python
# Now we call or invoke the cube function! Run the code below:
# Now we call or invoke the cube function! Run the code below:
print(cube(5))
print(cube(5))
print(cube(4)+cube(-3))
print(cube(4)+cube(-3))
print(cube(cube(2)))
print(cube(cube(2)))
```
```
%% Cell type:code id: tags:
%% Cell type:code id: tags:
``` python
``` python
# In the bad_cube function definition in this cell the parameter is cubed and printed rather than returned
# In the bad_cube function definition in this cell the parameter is cubed and printed rather than returned
# this is bad practice.
# this is bad practice.
defbad_cube(num):
defbad_cube(num):
print(num**3)
print(num**3)
```
```
%% Cell type:code id: tags:
%% Cell type:code id: tags:
``` python
``` python
# Explain what goes wrong in these function calls.
# Explain what goes wrong in these function calls.
x=bad_cube(5)#bad_cube does not return anything (it prints a value, but doesn't return a value)
x=bad_cube(5)#bad_cube does not return anything (it prints a value, but doesn't return a value)
print(x)#since nothing is returned, x contains the value None and that is what is printed
print(x)#since nothing is returned, x contains the value None and that is what is printed
```
```
%% Cell type:markdown id: tags:
%% Cell type:markdown id: tags:
## `return` vs `print`
## `return` vs `print`
-`return` enables us to send output from a function to the calling place
-`return` enables us to send output from a function to the calling place
- default `return` value is `None`
- default `return` value is `None`
- that means, when you don't have a `return` statement, `None` will be returned
- that means, when you don't have a `return` statement, `None` will be returned
-`print` function simply displays / prints something
-`print` function simply displays / prints something
- it cannot enable you to produce output from a function
- it cannot enable you to produce output from a function
%% Cell type:code id: tags:
%% Cell type:code id: tags:
``` python
``` python
# TODO: Write a function that determines if one number is strictly between two other numbers
# TODO: Write a function that determines if one number is strictly between two other numbers
# return a boolean ... True or False
# return a boolean ... True or False
# delete the "pass" line of code and put your own code there
# delete the "pass" line of code and put your own code there
defis_between(lower,num,upper):
defis_between(lower,num,upper):
pass
pass
# you can call a function in the same cell that you defined it
# you can call a function in the same cell that you defined it
print(is_between(5,8,13))
print(is_between(5,8,13))
print(is_between(5,5,13))
print(is_between(5,5,13))
print(is_between(100,cube(5),200))
print(is_between(100,cube(5),200))
```
```
%% Cell type:code id: tags:
%% Cell type:code id: tags:
``` python
``` python
# Example 3: write a function get_grid that works like this:
# Example 3: write a function get_grid that works like this:
# get_grid(5, 3, "@") returns the string
# get_grid(5, 3, "@") returns the string
# @@@@@
# @@@@@
# @@@@@
# @@@@@
# @@@@@
# @@@@@
# Let's practice Incremental Coding
# Let's practice Incremental Coding
# first, try to do this with string operators and literals
# first, try to do this with string operators and literals
print((("#"*5)+'\n')*3)
print((("#"*5)+'\n')*3)
```
```
%% Cell type:code id: tags:
%% Cell type:code id: tags:
``` python
``` python
# then, try to do this with variables
# then, try to do this with variables
width=5
width=5
height=3
height=3
symbol='#'
symbol='#'
print(((symbol*width)+'\n')*height)
print(((symbol*width)+'\n')*height)
```
```
%% Cell type:code id: tags:
%% Cell type:code id: tags:
``` python
``` python
# now, try to write a function
# now, try to write a function
# think about what would be good names for the parameters
# think about what would be good names for the parameters
defget_grid(width,height,symb):
defget_grid(width,height,symb):
return (((symb*width)+'\n')*height)
return (((symb*width)+'\n')*height)
my_grid=get_grid(5,3,"*");
my_grid=get_grid(5,3,"*");
# do some code
# do some code
2**1000000000
2**1000000000
# ...
# ...
print(my_grid)
print(my_grid)
```
```
%% Cell type:code id: tags:
%% Cell type:code id: tags:
``` python
``` python
# Finally, add in a parameter for a title that appears above the grid
# Finally, add in a parameter for a title that appears above the grid
2. Add a breakpoint to your code. Do this by clicking on the line number of a line of code within the cell. A red dot should appear next to that line of code. Now, when you run the code in the cell when that line is reached the debugger will stop executing your code.
2. Add a breakpoint to your code. Do this by clicking on the line number of a line of code within the cell. A red dot should appear next to that line of code. Now, when you run the code in the cell when that line is reached the debugger will stop executing your code.
3. Click the run button (or press shift-enter) to start running the code in the cell. The code will run up to the line where you added a breakpoint and will then stop.
3. Click the run button (or press shift-enter) to start running the code in the cell. The code will run up to the line where you added a breakpoint and will then stop.
4. Use the buttons in the bebugger sidepanel next to the "callstack" section in the side panel to control the continued execution of the code:
4. Use the buttons in the bebugger sidepanel next to the "callstack" section in the side panel to control the continued execution of the code:
- (**next**) - Run the next line of code.
- (**next**) - Run the next line of code.
- (**step-into**) - If a line of code calls a function, go into that function stop on the first line of code within the function.
- (**step-into**) - If a line of code calls a function, go into that function stop on the first line of code within the function.
- (**step-out**) - Execute all lines of code of the function you are currently in and stop at the first line of code outside of the function.
- (**step-out**) - Execute all lines of code of the function you are currently in and stop at the first line of code outside of the function.
- (**continue**) - Run the code until you reach the next breakpoint
- (**continue**) - Run the code until you reach the next breakpoint
- (**terminate**) - stop running the code.
- (**terminate**) - stop running the code.
Be aware if the buttons are greyed out or not. This is another way you can tell if the kernel is still busy trying to execute the code in the cell. Even after every line of code in the cell has finished executing, you will still need to continue stepping until the kernel is free (or you can click the stop button).
Be aware if the buttons are greyed out or not. This is another way you can tell if the kernel is still busy trying to execute the code in the cell. Even after every line of code in the cell has finished executing, you will still need to continue stepping until the kernel is free (or you can click the stop button).
(kernel is still busy with the code in the cell)
(kernel is still busy with the code in the cell)
(kernel has finished executing the code in the cell)
(kernel has finished executing the code in the cell)
Follow along as we use the debugger on the code cell below.
Follow along as we use the debugger on the code cell below.
%% Cell type:code id: tags:
%% Cell type:code id: tags:
``` python
``` python
deffunc_c():
deffunc_c():
print("C")
print("C")
deffunc_b():
deffunc_b():
print("B1")
print("B1")
func_c()
func_c()
print("B2")
print("B2")
deffunc_a():
deffunc_a():
print("A1")
print("A1")
func_b()
func_b()
print("A2")
print("A2")
func_a()
func_a()
```
```
%% Cell type:markdown id: tags:
%% Cell type:markdown id: tags:
## You Try It
## You Try It
For the code cells below, can you think through what will be printed, and in what order? Use the debugger to set a breakpoint and step through the lines of code and see if it is executed and the output is printed in the order that you thought.
For the code cells below, can you think through what will be printed, and in what order? Use the debugger to set a breakpoint and step through the lines of code and see if it is executed and the output is printed in the order that you thought.
%% Cell type:code id: tags:
%% Cell type:code id: tags:
``` python
``` python
print("A")
print("A")
deffoo():
deffoo():
print("B")
print("B")
print("C")
print("C")
foo()
foo()
print("D")
print("D")
foo()
foo()
```
```
%% Cell type:code id: tags:
%% Cell type:code id: tags:
``` python
``` python
#Almost the same as the last cell but the print("C") has been indented
#Almost the same as the last cell but the print("C") has been indented
print("A")
print("A")
deffoo():
deffoo():
print("B")
print("B")
print("C")
print("C")
foo()
foo()
print("D")
print("D")
foo()
foo()
```
```
%% Cell type:code id: tags:
%% Cell type:code id: tags:
``` python
``` python
deff():
deff():
print("A")
print("A")
return"B"
return"B"
print("C")
print("C")
print("D")
print("D")
x=f()
x=f()
print("E")
print("E")
print(x)
print(x)
```
```
%% Cell type:markdown id: tags:
%% Cell type:markdown id: tags:
## Summary
## Summary
You have learned how to **define a function** and what the different portions of the definition are called (header, body, parameters, default value, return). You know how to **pass values by position, keyword, or use the default value**. You know the difference between and **fruitful function and a void function** and the difference between using a print statement and a return statement. You have practiced **using the debugger to step through execution** of Python code.
You have learned how to **define a function** and what the different portions of the definition are called (header, body, parameters, default value, return). You know how to **pass values by position, keyword, or use the default value**. You know the difference between and **fruitful function and a void function** and the difference between using a print statement and a return statement. You have practiced **using the debugger to step through execution** of Python code.