# 5.5. Fruitful functions¶

## 5.5.1. Adding new functions¶

In one of the previous sections, you made the program for calculating the slope factor (s.py). It should be similar to the version for s.py given in the table below.

import math # program to calculate the s factor in the USLE slope = input("Enter the slope in degrees ") print("The slope you entered is", slope, "degrees.") slopeFloat=float(slope) # slope in radians slopeRadians = (slopeFloat/360) * 2.0 * math.pi print("This corresponds to a slope of ", slopeRadians, "in radians.") # slope in m/m slopeFraction = math.tan(slopeRadians) print("This corresponds to a slope of ", slopeFraction, "(m/m)") # slope factor S = 0.065 + 0.045 * slopeFraction + 0.0065 * slopeFraction**2.0 print("The slope factor is", S)

In many cases it is convenient to define functions for often used calculations in a program. For instance, the statement

```
slopeRadians = (slopeFloat / 360.0) * 2.0 * math.pi
```

Can be replaced by,

```
slopeRadians=degreesToRadians(slopeFloat)
```

while providing a definition of the function `degreesToRadians`

:

```
def degreesToRadians(angleInDegrees):
angleInRadians = (angleInDegrees / 360.0) * 2.0 * math.pi
return angleInRadians
```

The word `def`

indicates a function definition. Note the `:`

at the end of the first line of the function definition. Here, the function has an ‘input’, which is called the argument of the function. It is `angleInDegrees`

. Everything below the first line of the function definition is called the body of the function, indented from the left margin by one or two spaces. The statements in the body define what the function does. The last statement, a return statement, defines the return value of the function. In our example, the return value of the function will be assigned to `slopeRadians`

. The function body in this example contains only two statements, but you may use more (not too many as this will make the code hard to read). For instance, an alternative way of defining the function would be:

```
def degreesToRadians(angleInDegrees):
angleInDegreesDivided = angleInDegrees / 360.0
angleInRadians = angleInDegreesDivided * 2.0 * math.pi
return angleInRadians
```

Now it will be clear why we use a return statement: `angleInRadians`

needs to be returned. Not `angleInDegreesDivided`

!

Open `s.py`

(either your own version or the one in the table below) and save it as `s_function.py`

. Make the changes suggested above. Put the function definition at the top of the script, one line below `import math`

. Save the script and execute it to check it. It should generate the same result as the original one!

Now, let’s do a test: save `s_function.py`

as `test.py`

and move the function definition to the bottom of the script. Save `test.py`

and execute it. Why do you think it doesn’t work?

The next step is to make a function calculating the slope factor. Open `s_function.py`

and save it as `s_twofu.py`

. Modify the script by defining a second function (define it below the `degreesToRadians`

function definition) named `sFactor`

having one argument, the slope in degrees given as a float, with the slope factor as the return value. You could use this as the first line of the function definition:

```
def sFactor(slopeInDegrees):
```

Note that most statements which were in the `s_function.py`

script need to be moved to the body of the `sFactor`

function. Calculate *S* now by calling (at the bottom of the script) the function `sFactor`

. Be sure the script runs before answering the next question.

**Question** Where should the `sFactor`

function definition be provided?

Certainly below the definition of the

`degreesToRadians`

function.Certainly above the definition of the

`degreesToRadians`

function.Certainly inside the definition of the

`degreesToRadians`

function.Either above or below the definition of the

`degreesToRadians`

function.

*Correct answers:* d.

*Feedback:*
As long as all the function definitions needed to execute a line are above that line, it makes no difference in what order they are given. In general, function definitions are not given inside other function definitions.

import math # program to enter the slope in degrees def degreesToRadians(angleInDegrees): angleInRadians = (angleInDegrees / 360.0) * 2.0 * math.pi return angleInRadians def sFactor(slopeInDegrees): # slope in radians slopeRadians = degreesToRadians(slopeInDegrees) print("This corresponds to a slope of", slopeRadians, "in radians.") # slope in m/m slopeFraction = math.tan(slopeRadians) print("This corresponds to a slope of", slopeFraction, "(m/m)") # slope factor S = 0.065 + 0.045 * slopeFraction + 0.0065 * slopeFraction**2.0 return S slope = input("Enter the slope in degrees ") print("The slope you entered is", slope, "degrees.") # slope factor S = sFactor(float(slope)) print("The slope factor is", S)

Imagine field data are collected of the topographical slope to estimate soil erosion for individual arable fields. On each arable field, slope is measured two times, at randomly chosen locations on the arable field. It is assumed that the average slope factor of an individual field (*S* _{f}) can be estimated by:

*S* _{f} = (*S* _{1} + *S* _{2}) / 2.0

with *S* _{1}, *S* _{2}, the slope factors calculated from the first and second slope measurements on the field, respectively. Open `s_twofu.py`

and save it as `s_two_in.py`

. Using the equation given above, modify the script such that it can be used to calculate the average slope factor (Sf) of a field:

asks the user to enter the first slope of the field

asks the user to enter the second slope of the field

prints Sf

You will find that you can use the same function sFactor twice. Test the script before answering the next question.

**Question** On a field, the slope is measured two times, resulting in a slope of 11.0 and 13.0 degrees. What is the average slope factor?

0.013

0.091

0.075

0.021

*Correct answers:* c.

*Feedback:*

import math # program to enter two slopes in degrees and calculate average slope # factor def degreesToRadians(angleInDegrees): angleInRadians = (angleInDegrees / 360.0) * 2.0 * math.pi return angleInRadians def sFactor(slopeInDegrees): # slope in radians slopeRadians=degreesToRadians(slopeInDegrees) # slope in m/m slopeFraction=math.tan(slopeRadians) # slope factor S = 0.065 + 0.045 * slopeFraction + 0.0065 * slopeFraction**2.0 return S slopeOne = input("Enter the first slope in degrees ") print("The first slope you entered is", slopeOne, "degrees.") slopeTwo = input ("Enter the second slope in degrees ") print("The second slope you entered is", slopeTwo, "degrees.") # average slope factor of the field Sf = (sFactor(float(slopeOne)) + sFactor(float(slopeTwo))) / 2.0 print("The average slope factor of the field is", Sf)