Python Concepts/Functions

Objective

edit
  • Discuss the purpose of functions.
  • Learn how to create a simple function.
  • Understand the use of parameters.
  • Work with "default parameter values".
  • Work with positional arguments.
  • Work with keyword arguments.
  • Use the return statement within a function.
  • Understand the location and abstraction of a function.

Lesson

edit

Functions

edit

A function is a way of reusing a block of code so that it can be used more than once. Functions give the programmer the ability to reduce code redundancy and eliminate hours of wasted work. Each function allows the code to be centralized, where one change to the function will affect everything that depends on it. Functions can be used to divide and conquer tasks that would seem otherwise impossible to accomplish!

Creating A Function

edit

To create a function, use the def keyword, followed by the function's name, with an empty pair of parentheses, ending with a colon. Functions make up a code block, so you'll need to indent any code that's within the function. Don't forget to indent, otherwise you'll get the pesky "IndentationError".

def hello():
    print("Hello, world!")

The code above assigns and creates the function called hello. It acts much like the the command x=1; both the given examples create a new variable, hello and x respectively.

Now that you've created the function nothing should visibly happen. To actually invoke or call the function, you'll need to use the function's name followed by the parentheses as shown in the script below.

def hello():
    print("Hello, world!")

hello()

The output should be:

Hello, world!

Adding the command hello() again will result in the words Hello, world! being displayed twice. This demonstrates a small fraction of the function's uses and abilities.

Function Parameters

edit

At this point, you might be wondering why we need to have those pointless parentheses when we call the function. Wouldn't hello be a lot easier than hello(). Believe it or not, but we can pass arguments to the function when we include them within the parentheses. This allows us to create functions that do things based on their given arguments. First, the arguments need to be declared when the function is first defined and then we need to call it with the correct number of arguments.

def square(x):
    print(x**2)

square(2)
square(3)
square(4)

The following output should be:

4
9
16

x now acts like a variable within the function square. You should note that x will only exist within the function. Trying something like the example below will definitely cause a NameError.

def square(x):
    print(x**2)

square(2)
square(3)
square(4)
print(x) # x doesn't exist outside of square!

A function can take multiple arguments with any two adjacent arguments separated by a comma if more than one exists as demonstrated in the next example.

def somemath(x, y):
    print((x**2)+y)

somemath(2, 3)
somemath(3, 2)

The following output should be:

7
11

Default Parameters

edit

Having parameters is great, but it can be repetitive to continue to use them over and over, again. We can define a default value for a parameter by setting its value when you define the parameter. Take the script below for example.

def woof(x=0):
    print(x)

woof(1)
woof()
woof(23)

The output should be:

1
0
23

Did you see the second time we called woof? We didn't give an argument, yet it still printed out 0. If no argument is given, a default is automatically assigned.

Positional Arguments

edit


A positional argument is an argument that is not a keyword argument. In an argument list it occupies a position that corresponds to a parameter in the function definition.

def f3 (arg1, arg2=None, arg3=None) :
    # This function expects at least one argument and a maximum of three.
    print ('arg1 =', arg1, '. arg2 =', arg2, '. arg3 =', arg3,'.')

f3 (1, *(2,3))
f3 (1, *[2,3])
f3 (1, *{2,3})
f3 (1, 2,3)

In all four function calls above numbers 1, 2, 3 are positional arguments. Number 1 occupies the position that corresponds to arg1 in the function definition; number 2 occupies the position that corresponds to arg2 in the function definition; number 3 occupies the position that corresponds to arg3 in the function definition. All four of the above function calls produce the same output:

arg1 = 1 . arg2 = 2 . arg3 = 3 .

The following syntax accepts a variable number of arguments:

def f3 (*args) :                                    
    print ('Length = {}, args = {}, isinstance(args,tuple): {}'
            .format(len(args), args, isinstance(args,tuple)))

f3()
f3(1)
f3(1,2)
f3(1,2,3)
f3('0', 1, {'one':1, 'two':2}, [1,2,3])
Length = 0, args = (), isinstance(args,tuple): True
Length = 1, args = (1,), isinstance(args,tuple): True
Length = 2, args = (1, 2), isinstance(args,tuple): True
Length = 3, args = (1, 2, 3), isinstance(args,tuple): True
Length = 4, args = ('0', 1, {'one': 1, 'two': 2}, [1, 2, 3]), isinstance(args,tuple): True

Python's syntax accepts required and optional arguments and a variable number of arguments:

def f5 (arg1, arg2=None, *arg3) :
    print ('arg1 =', arg1, '. arg2 =', arg2, '. arg3 =', arg3)

f5(1)
f5(1,2)
f5(1,2,3)
f5(1,2,3,4)
arg1 = 1 . arg2 = None . arg3 = ()
arg1 = 1 . arg2 = 2 . arg3 = ()
arg1 = 1 . arg2 = 2 . arg3 = (3,)
arg1 = 1 . arg2 = 2 . arg3 = (3, 4)

Parameters are part of the function definition. When the function is invoked, arguments are passed to the function and each argument passed must correspond to a parameter in the definition of the function.

Keyword Arguments

edit


Keyword arguments are arguments that are supplied to a dictionary within the function. They may be supplied as the sole list of arguments or they may follow other arguments:

def f2 (**kwargs) :

or

def f2 (arg1, arg2, arg..., **kwargs) :

We saw keyword arguments used in Dictionaries:Other operations on dictionaries This lesson shows by examples how they may be passed and received.

def f2 (**kwargs) :
    print ('\nf2: isinstance(kwargs, dict):', isinstance(kwargs, dict))
    for arg in kwargs :
        print ('    arg =', arg, ', isinstance(arg,str):', isinstance(arg,str))
      	break
    for arg in kwargs :                      
        print ('    kwargs[{}] = {}.'.format(arg, kwargs[arg]))
                                                                  
f2(**{'one':1, 'two':2, 'three':3})

f2(one=1,two=2,three=3)

The result is:

f2: isinstance(kwargs, dict): True
    arg = one , isinstance(arg,str): True
    kwargs[one] = 1.
    kwargs[two] = 2.
    kwargs[three] = 3.

f2: isinstance(kwargs, dict): True
    arg = one , isinstance(arg,str): True
    kwargs[one] = 1.
    kwargs[two] = 2.
    kwargs[three] = 3.

The following example shows how (optional) positional arguments and (optional) keyword arguments may be passed to a given function upon invocation.

def f6 (arg1, arg2=None, *var, **kwargs) :
    print ( 'arg1 = {}. arg2 = {}. var = {}. kwargs = {}.\n'
            .format (arg1, arg2, var, kwargs)
           )

f6(0) # At least one argument is required for f6().
f6(0, one=1, two=2)
f6(0,1, one=1, two=2)
f6(0,1,2, one=1, two=2)
f6(0,1,2,3, one=1, two=2)
f6(0,1,2,3,4, one=1, two=2)
f6(0,[1,2],3,4, one=1, two=2) # arg2 is passed as list.
f6(0,*[1,2],3,4, one=1, two=2) # arg2 is unpacked.
arg1 = 0. arg2 = None. var = (). kwargs = {}.

arg1 = 0. arg2 = None. var = (). kwargs = {'one': 1, 'two': 2}.

arg1 = 0. arg2 = 1. var = (). kwargs = {'one': 1, 'two': 2}.

arg1 = 0. arg2 = 1. var = (2,). kwargs = {'one': 1, 'two': 2}.

arg1 = 0. arg2 = 1. var = (2, 3). kwargs = {'one': 1, 'two': 2}.

arg1 = 0. arg2 = 1. var = (2, 3, 4). kwargs = {'one': 1, 'two': 2}.

arg1 = 0. arg2 = [1, 2]. var = (3, 4). kwargs = {'one': 1, 'two': 2}.

arg1 = 0. arg2 = 1. var = (2, 3, 4). kwargs = {'one': 1, 'two': 2}.

Returning A Value

edit

If we wanted to use the value that the square function gives us, we would rewrite it to use the return command.

>>> def square(x):
... 	return x**2
...

Which can then be used to do such fun things as:

>>> print(square(3))
9

or

>>> print(square(square(3)))
81

or even in statements such as:

>>> 10 + square(2)
14

and

>>> y = square(10)
>>> y
100

If the function is to return a value, the return statement is required. Without it the function returns None.

Assignments

edit

Completion status: About halfway there. You may help to clarify and expand it.

References

edit

1. Python's documentation:

"4.6. Defining Functions", "4.7. More on Defining Functions", "4.7.2. Keyword Arguments", "function", "parameter", "argument", "6.3.4. Calls", "8.6. Function definitions", "What is the difference between arguments and parameters?", "Functional Programming HOWTO"


2. Python's methods:


3. Python's built-in functions:

"2. Built-in Functions"