---
jupyter:
  jupytext:
    metadata_filter:
      notebook:
        additional: all
        excluded:
        - language_info
    text_representation:
      extension: .Rmd
      format_name: rmarkdown
      format_version: '1.0'
      jupytext_version: 0.8.6
  kernelspec:
    display_name: Python 3
    language: python
    name: python3
  jupyterbook:
    run: false
---

# Exercises on functions

For background, please read the [functions](../functions-conditionals/functions) introduction.


This function is not properly defined, and will give a `SyntaxError`.  Fix it, then run the call below to confirm it is working.

```{python tags=c("raises-exception")}
function subtract(p, q):
    r = p - q
    return r
```

```{python tags=c("raises-exception")}
subtract(5, 10)
```

This function also gives a `SyntaxError`. Fix and run.

```{python tags=c("raises-exception")}
def add(first_value, second_value)
    return first_value + second_value
```

```{python tags=c("raises-exception")}
add(2, 3)
```

Here is another error.  Fix and run.

```{python tags=c("raises-exception")}
def cube(a_variable):
return a_variable ** 2
```

```{python tags=c("raises-exception")}
cube(3)
```

Why does the second cell below give you an error?

```{python}
def add_then_multiply(a, b):
    added = a + b
    return added * b
```

```{python tags=c("raises-exception")}
result = add_then_multiply(10, 4)
result + added
```

Write a function called "increase" that

* accepts two arguments
* the body multiplies the first argument by 2 and the second by 3, adds the two resulting numbers, and returns the result.

If your function is right, the cell below should return 13.

```{python}
# Your function here
```

```{python tags=c("raises-exception")}
increase(2, 3)
```

This function will run, but it probably doesn't give you the result you expect.  Fix to give the result you expect and run.

```{python}
def divide(p, q):
    # Give result of dividing p by q
    result = p / q
```

```{python}
divide(10, 2)
```

Remember that, in function world, the function can see the variables
at the top level, but it cannot change what value the top-level
variables point to.

Read the code the below, but do not run it.

Predict what you will see.  Will it be an error?  If not, what value will you see?  

Run it to see if you're right.

```{python}
a = 12

def my_function(b):
    return a * b

my_function(4)
```

This is now going into deeper water.

We know that, in function world, the function can see the variables at the top level, but it cannot change what value the top-level variables point to.

Read the code the below, but do not run it.

Predict what you will see.  Will it be an error?  If not, what value will you see?

Run it to see if you're right.  See if you can explain why you are right.  Call your instructor over to check your explanation.

```{python}
a = 12

def function_two(b):
    a = b
    return a * b

function_two(4)
```
