## 1.8 Our Own Functions

Python allows us to create our own functions. This is a very powerful feature as it allows us to: reuse/share code, make our code more readable and make changes easier to manage.

There two ways to define our own functions: named definitions and anonymous (or lambda) definitions.

### 1.8.1 Named Functions (Basic definition)

Here is a simple way to define a function.

def pow_wow(x,y):
'''
Takes two arguments x and y and returns x raised to the power y.
'''
return x**y
• Not the keyword def
• (x,y) specifies the function inputs (also called arguments)
• : is where the declaration starts.
• The scope (i.e. where the function starts and ends) is defined by the indentation!
• return specifies the output.
• '''$$\ldots$$''' is the docstring.

#### Useage Example 1

Lets use this function

z = pow_wow(2,3)          # Specifying arguments by position
print(z)
# 8

#### Useage Example 2

z = pow_wow(3,2)          # Specifying arguments by position
print(z)
# 9

#### Useage Example 3

z = pow_wow(y = 3,x = 2)  # Specifying arguments by name
print(z)
# 8

#### Useage Example 4

help(pow_wow)             # Accessing the docstring
# Help on function pow_wow in module __main__:
#
# pow_wow(x, y)
#     Takes two arguments x and y and returns x raised to the power y.

### 1.8.2 Named Functioons (with Default Arguments)

You also have the option of specifying a default value.

def pow_wow_too(x,y = 5):
'''
Takes two arguments x and y and returns x raised to the power y.
y defaults to 5
'''
return x**y

#### Useage Example 1

print(pow_wow_too(2,3))   # Specifying arguments by position
# 8

#### Useage Example 2

print(pow_wow_too(2))   # Specifying arguments by position
# We are now using the default value of y
# 32

### 1.8.3 Named Functions (Some cool features)

import numpy as np
X = np.array([1,2,3])                 # Create a numpy array

#### Useage Example 1

print(pow_wow_too(x = X,y = 2))       # x is not same as X :)
# [1 4 9]

#### Useage Example 2

print(pow_wow_too(X,2))               # Same as above. By position
# [1 4 9]

#### Useage Example 3

print(pow_wow_too(X))                 # Using the default value
# [  1  32 243]

#### Useage Example 4

print(pow_wow_too(X,[1,2,3]))         # Cool right?
# [ 1  4 27]

#### Useage Example 5

print(pow_wow_too(x = 2, y = X))      # Coolness continues
# [2 4 8]