# Python Notes - Function parameters, return, locals

We have seen functions used with global variables. But ideally we want to minimise the use of globals, to make each function more independent. We can use parameters/arguments, and the the return instruction. (NB - arguments are known as parameters in other languages, and this is perhaps more meaningful.

Here is an analogy of parameters. We have a TV set with a scart socket in the back. We can connect a DVD player to it:

```
_                                                                    _
|                                                                      |

+----------------------------+
+----------+                     |                            |
| Sony DVD |------------------>   Scart                       |
+----------+                     | Socket                     |
+------------>  |                 TV         |
|               |                            |
+---------+      |               |                            |
| JVC DVD |------+               |                            |
+---------+                      +----------------------------+

|_                                                                    _|

```
The label on the back of the TV says Scart Socket. It can accept the input from ANY DVD. The company who built the TV decided on this label. (This is a 'formal parameter').

Later, a user of the TV can connect any DVD to it. THis is an 'actual parameter' or 'argument'.

Here is a python method that displays a doubled value on the screen, in the form:

```The doubled value of 23 is 46

```
Here is the code:
```
#double a parameter
def doubled(theNumber):
print "The doubled value of", theNumber,"is", theNumber * 2
#end Def

#some calls
doubled(23)
n = 4
doubled(n+1)
doubled(input("Type a number"))

```
The output is:
```The doubled value of 23 is 46
The doubled value of 5 is 10
Type a number: 44                                  (44 entered by user)
The doubled value of 44 is 88
```
Look at the code. Note:
• the def line has a variable name in (). We invent this name. It is a formal parameter.
• it is treated like a local variable in the def.
• when we call the function, we supply an actual parameter in () This should be the correct type of item (e.g not a string in this case)
• the actual parameter need not be a name or a number - it can be anything that results in a number.
• behind the scenes, actual parameters are copied into formal parameters.
• if we alter e.g theNumber inside doubled, the local value is changed, but the changed value is not sent back to the calling code.

# Example - box drawing

Here we create a box of stars, in the form:
```****
****
****
```
We wish to control the height and width, so use 2 parameters. Here is the code:
```
#box drawing with function parameters
# e.g width is 4, height is 3, gives:
# ****
# ****
# ****

def main():
width = input("How wide? ")
height = input("How high? ")
box(width, height)
# now a 10 by 10
box(10, 10)
#end def

def box(theWidth, theHeight):
#build up  a string of *, e.g   *****
stars = ""
for star in range(1, theWidth+1):
stars = stars + "*"

# do the lines
for lineCount in range(1, theHeight+1):
print stars
#end def

main()  #execution begins here
```

Note:

• we chose theWidth, theHeight as formal parameter names. Commas are used to separate them.
• the stars and star variables are local. Noglobal is needed. Locals are covered in more detail below.
• when we call the box function, we supply 2 actual parameters
• the function can be re-used. (e.g by pasting it into another program)
• if we used global, as in:
```def box():
global theWidth, theHeight
etc...
```
then the function is not packaged up as neatly as before. We force the caller to use the names theWidth, theHeight. This would be inflexible.

Problem: add a 3rd parameter to box, so that we can specify an offset:
```
*****                 (offset of 6 spaces)
*****
*****
```
(add spaces to the stars variable)

## Using Built-in functions

Here are some common built-in functions, which often calculate a result, and send it back to us to use:
```
import math
x = len("abcd")    # length of a string or list  (4 here)
x= math.sqrt(16)   # square root(i.e. 4)  Put:  import math    at top of code
x = max( 8, 5)     # biggest   (8 here)
x = float("12.34") # convert(e.g) a string to  a float number
x = float(3.6)     # convert integer to float
x = int("1233")    # convert a string to an integer
n = str(12.3)      # convert number to string
```
We can use these in a variety of ways, as long as we use their result:
```x = 3+max(6,8)*4
x = max(max(x, y, z))   # biggest of 3
#but not
max(8,9)    # not using result

```
Next, we look at writing our own functions which return a result.

## Using return

Parameters can only be used for input to a function (with the exception of lists - see later). To send back a value, we use the return instruction.

Example - square a number:

```
#square - shows return

def squareIt(n):
squared = n * n
return squared
#end def

#calls
x = squareIt(6)
n=2
y = squareIt(n+1)
z= squareIt(squareIt(2))
print x, y, z         # prints 36  9  16
print squareIt(5)

```
Note:
• we supply a numeric parameter
• return sends back a value to the caller, who must use it in some way. (Such as assigning it, or printing it.)
• a call such as:
```squareIt(3)
```
is probably not what you meant to do, because the 9 is not used.
• we can return expressions, as the the shorter:
```def squareIt(n):
return n*n
```
If we need to return several results, we can put them in a 'tuple', and return it. Tuples are considered later, but briefly, here is a def and a call:
```def someCalc(x)
return 2*x, 3*x     #return 2 values.  The ( ) are needed!

a, b = someCalc(4)      #A call.   a becomes 8, b 12
```

IMPORTANT: return and parameters are much better than the use of globals.

The area program below shows how you can return more than one result, using a 'tuple'

### Local Variables

If a function is complicated, it may need variables for its own calculations, and local variables are better than globals, because they have no impact on other areas of the program. Here is a function which returns the average of 3 numbers:
```def calcAverage(a, b, c)
return (a+b+c) / 3
```
This is fine, but if it were more complicated, we might need extra variables. We will not go further with the complexity here, but what if the programmer recoded it:
```def calcAverage(a, b, c)
aver =  (a+b+c) / 3   # a local variable
return aver
```
aver is local, only known about inside the function. If another function (e.g. written by another programmer) also uses this name, there is still no confusion. 2 variables with 2 different values will be created and used.

Finally, here is the area program, rewritten to use parameters, locals, return. Work through it, trying to spot these 3 things. Note that there are no globals.

 ```1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 ``` ```#area - functions - v1 #area - with locals and parameters def main(): width, height = getSize() # returns 2 values #nb width, height are local to main area = calcArea(width, height) showResults(area) #end def def getSize(): w = input("Type the width: ") h = input("Type the height: ") return (w, h) #brackets needed - a 'tuple' #end def def calcArea(w, h): answer = h * w #answer is local to calcArea return answer #end def def showResults(a): print "Area is ", a, "Sq Metres" print "---------------------------" #end def main() ```