Writing User-defined Functions in Python

At this point, it is but obvious for you all to know what functions are! You have encountered several inbuilt functions already in the tutorials before. Although, due to all those functions being built-in, all we had to do was to use them directly by calling them and providing the required arguments if required.

Functions defined explicitly(by a user) in a program also helps to divide the whole program into sub-parts thereby making it more readable, easy to revise the code and to fix any errors or bugs.

It's time to learn how we can create our own functions in python, which are also called as user-defined functions.

As we have already seen in previous tutorials, to use any built-in function, we have to import the module in which the function is defined, in our program. For example, in the below program we have imported the math module to use the floor() built-in function.

import math

a = 2.3
print ("The floor of 2.3 is : "+ math.floor(a))

If you open the module file, which is a python file only, you will be able to see the definitions of various functions, just like you would do very soon, when you will start defining your own user-defined functions.


Structure of function definition

Let's see how a simple function can be created. The syntax would go like,

def functionName(parameter1, parameter2, ...):
    logic/algorithm statements
    ...
    return someData

The very first point here, indentation is very important, the definition of the function should be indented by a tabspace after the def functionName(parameter1, parameter2):

Now let's try to understand each line one by one. The first line is called function header starts with the keyword def which actually means define, since this is the starting point from where start defining a function. Next, comes the function's name, where you give the function a name which can be, for example, say add, multiply, swap or anything which signifies what actually the function will do.

Next, inside the circular braces, comes the parameters. These are some required values, which user can input, and are used inside the function during the operation. As you might remember, how we used to put several numbers while calling math's functions for example, sin(3.14), here 3.14 is the parameter value. We know that without a value like 3.14, the sin() function will have no value to perform the sine operations on. Similarly, you can also specify, that your user-defined function expects some parameter for successful execution, while defining the function.

Coming to the second line, we have the logic/algorithm statements. Here, we will be utilising all the parameters(if, any) to achieve what the function is supposed to do. We can have various operations, loops, conditional statements, etc. here to accomplish it. Taking the example of the add() function, where in simple addition is performed - a + b and the result is stored into some variable, let's say c, hence inside the add() function, we have an expression, c = a + b, a and b are the input values.

Finally, comes the return statement. Now the first thing to know about the return statement is that it is not mandatory to have it in a function. If your function is supposed to return a value after any operation, then you must use the return statement to output that value, else your function does not need it. Hence, you must always know when to have a return statement. The data returned can be anything - a number, string, a Boolean value, a list or anything else.

In case of the function add(), do we expect it to give us some (data) value? Yes. And What is it? The result of addition of the two numbers that are passed as parameters. So, add() function should have a return statement. To return any value, we just have to mention the value which we want to return, next to the return keyword.

def add(a, b):
    c = (a+b)
    return c

Alternatively, you could have simply returned (a+b) directly, without storing it to some other variable too.

def add(a, b):
    return (a+b)

Once a function is defined, we can use it by simply calling it as we do for the built-in function i.e., if we want to add 5 and 9, then,

>>> print add(5, 9)

14

In fact, you can even pass a function as a parameter! For example:

>>> print add(5, add(7, 6))

18

Confused? Don't worry, let us explain. First, add(7, 6) will be evaluated and its result, i.e., 13 will be passed inside the second add() function as a parameter, to be added with 5. Therefore, the final result will be the output of, add(5, 13), which is 18.


Return Type of a function

Every function has a return-type, which is nothing but the type of value it returns. It's very simple to decide what is the return-type of any function. In add() function, if a and b are integer, then add() function will return an integer value, which will be it's return-type. Similarly, if the function is returning a list, then it's return-type will be a list. For built-in functions, you can find the return-type of every function specified in the official documentation.

But how can every function have a return-type, because we mentioned earlier, that having a return statement is completely optional and it totally depends on whether you need it or not in the function. Hence, the question arises, that what will be the return type of the functions which doesn't return anything? The answer is, void, which is pretty much synonymous to empty or nothing, stating that if there is no return statement then the function will have void return type.

Let's see where we can use the functions with return-type void.

Hint: As they do not return anything, these can be used to break your program into smaller units.

Suppose there is a simple program, wherein, you take a positive number as input from the user and print all the even numbers and double of all the odd numbers, starting from 1 to that number. A program without any function will look like following:

n = input()
for i in xrange(1, n+1):
	if i%2 == 0:
		print i
	else:
		print 2*i

Now let's try to achieve this with a function. We will start by defining the function on the top. Although, it doesn't matter where you define the function because that has no effect on the flow of execution. Only calling a function will begin the execution of the function. But it's a good practice to define all the functions at the starting of your program because that's where all the programmers look for all the user-defined functions when they are reviewing any code.

def check(k):
	if (k%2==0):
		print k
	else:
		print 2*k

n = input()
for i in xrange(1, i+1):
	check(i)

As you can see we just picked up the logic of checking whether the number is even or not and defined it inside the check() function. And then we call it in the for loop, passing a new value to it in every iteration. This actually cleaned up the for loop a bit and made it look tidier.

The above program is a simple program, but when you will write programs with 100s of lines of code, then divinding the program into functions is a very good practice.

One advantage of using a function is that you can re-use that function anytime, by simply calling it. In the example above, if we want to print a number if it's even, or print the double of it, if it's odd, then all we have to do is simply call the function, and pass that number as the argument, and it's done. check(9), Handy, right?


Default Arguments

Default arguments are used when you need to pre-set the value for the parameters. That is, if in the future we don't pass any variable as an argument while calling the function, then the function will assume the default value to execute its statements.

Now, how to define the default arguments? Let's take the example of add() function. What should happen if we do this:

>>> print add()

Without any default parameter, python will throw an error straight away. So let's set the default arguments for the add() function, so that it works, even without argument values. We think the defulat values should be zero. With this, the returned value will be 0 + 0, i.e. 0, which makes sense too since we haven't passed any parameter/argument value.

The updated add() function will be,

def add(a=0, b=0):
    return (a+b)

And it's done.

>>> print add(10, 6)
>>> print add()

16 0


Aliasing function names

Python has a special feature where you can create an alias of any function, i.e. if you think a function name is too long and not worth typing every time, you can decide a new name for it, without altering the original function. Taking the example of add() function, suppose we want a shorter or different name for this function, but without editing the original function, we can do so by using the function aliasing feature. Suppose we want to rename add() to a(), then,

>>> a = add

And done. After this line, add() and a() would call the same function, thus, obviously, the parameters need to be same too. Hence now the following will work just like add() function,

>>> print a(9, 8)

17