DEV Community

Cover image for Create and Use Functions in Python
Sahil
Sahil

Posted on

Create and Use Functions in Python

What is a function? What does a function do? As the name suggests function does a specific task. This task can be used repeatedly or once as per the use case. The main purpose of a function is to separate the logic into different blocks. We can create our functions or use any of the available in-built functions in python.

Syntax:

def function_name(parameters):
    """docstring"""
    statement(s)
    return expression 
Enter fullscreen mode Exit fullscreen mode

We can see in the syntax that to create a function we need to use the def keyword following the function name. Parameter(s)/ Argument(s) is the only way through which we can pass data to the function. We can add a docstring to explain the use of function and its parameter(s). A function can return a value if desire. It is not compulsory to return something.

Once we define the function, to use it we need to call that function. Let's assume I have created a function named odd_or_even. To call this function, I can write like odd_or_even(). And if this function is expecting some argument(s), I can write it like odd_or_even(2).

Sum of Two Numbers

If we want to just print the sum of two numbers or just to see the sum of two numbers, we do not need to return anything. And if we try to assign it to a variable we get None as the value.

def sum_num(num1, num2):
    total = num1 + num2
    print(total)

sum_num(5,10)

# OUTPUT: 15
Enter fullscreen mode Exit fullscreen mode
def sum_num(num1, num2):
    total = num1 + num2
    print(total)

temp = sum_num(5,10)
print(temp)

"""
OUTPUT: 

15
None
"""
Enter fullscreen mode Exit fullscreen mode

Now, if we want to return the sum then we can do using following code.

def sum_num(num1, num2):
    total = num1 + num2
    return total

temp = sum_num(5,10)
print(temp)

# OUTPUT: 15
Enter fullscreen mode Exit fullscreen mode

Keyword arguments

In general, we need to pass arguments in a specific order to a function. But, using keyword arguments we can pass arguments in any order. Let's understand it by an example of division. In the example below, if we want 3/2 then we will write divide(3,2).

def divide(num1, num2):
    return num1/num2

ans = divide(3,2)
print(ans)

# OUTPUT: 1.5
Enter fullscreen mode Exit fullscreen mode

But now, by mistake, we wrote divide(2,3). This error can make the whole logic wrong.

def divide(num1, num2):
    return num1/num2

ans = divide(2,3)
print(ans)

# OUTPUT: 0.6666666666666666
Enter fullscreen mode Exit fullscreen mode

To save yourself from this kind of mistake we can use keyword arguments. This is just a normal argument passing, but instead of passing only value, we will pass the variable name as well.

def divide(num1, num2):
  return num1/num2

ans = divide(num1=3, num2=2)
print(ans)

# OUTPUT: 1.5
Enter fullscreen mode Exit fullscreen mode

So, now we can pass data in any order and this way logic will be intact.

def divide(num1, num2):
  return num1/num2

ans = divide(num2=2, num1=3)
print(ans)

# OUTPUT: 1.5
Enter fullscreen mode Exit fullscreen mode

This is one of the best practices for function in python.

Variable Length Arguments

In some cases, we don't know the number of arguments we will receive in function. Or we do not want to restrict the function with a specific number of arguments. In this kind of situation, we can use variable-length arguments. There are two types of variable-length arguments:

  1. *args (Non-Keyword Arguments)
  2. **kwargs (Keyword Arguments)

1. *args (Non-Keyword Arguments)

In non-keyword arguments, we just pass n number of data to the function. *args is not the fixed name of non-keyword arguments. We can use any name. It is just a standard to use **args.*

Let's assume, we are asking users to enter the fruits they have. Noe, every user might have a different number of fruits. To save or to operate on all fruits entered by users, we can use non-keyword arguments.

def fruit_list_operation(*fruits):
  for fruit in fruits:
    print(fruit, end=",")

fruit_list_operation("apple", "banana")

print()

fruit_list_operation("apple", "banana", "grape", "mango")

""" OUTPUT:
apple,banana,
apple,banana,grape,mango,
"""
Enter fullscreen mode Exit fullscreen mode

Here, we have used for loop as *args will create a sequence data. As you see, when we pass 2 fruits loop runs for 2 times and 4 times in the second case.

The print(fruit, end=",") function is used to notify the interpreter that does not end the statement with a new line. Instead, use comma(,) to end the statement. And when we used the print(), it just wrote a new line and moved on.

2. **kwargs (Keyword Arguments)

The variable-length keyword argument is almost the same as the variable-length non-keyword arguments. The only difference we use this variable-length keyword argument function when we do not know how many keyword arguments we will be getting.

def my_project(**kwargs):
  for key, value in kwargs.items():
        print("%s == %s" % (key, value))

my_project(frontend = "Angular", backend = "Python", database="MongoDB")

""" OUTPUT: 
frontend == Angular
backend == Python
database == mongodb
"""
Enter fullscreen mode Exit fullscreen mode

Default Parameter Value

When we want to use some default value if the argument is not passed to a function, we can use the default parameter. We can use any number and any datatype as the default parameter. There is just one condition we have to use the default value argument as the last parameter of the function.

def division(num1, num2=2):
  print(num1/num2)

division(16,4)
division(16)

""" OUTPUT:
4.0
8.0
"""
Enter fullscreen mode Exit fullscreen mode

Let's see what happens if we keep the first argument as the default argument.

def division(num1=2, num2):
  print(num1*num2)

division(16,4)
division(16)

""" OUTPUT: 
File "functions.py", line 1
    def division(num1=2, num2):
                         ^^^^
SyntaxError: non-default argument follows default argument
"""
Enter fullscreen mode Exit fullscreen mode

Docstring

As we have seen in the syntax, the first commented statement in any function is considered as the docstring. Docstring is nothing but some commented statements explaining the use of the function, its arguments and the return expression. To print or to get the docstring we can use the following syntax: *function_name*.__doc__. Let's see an example to understand the concept of the docstring.

def is_odd(num1):
  """Function to check if the number is odd or not.

      Parameters:
        num1 (float): number to be checked

      Returns:
        is_odd (boolean): true if number is odd 

  """
  is_odd = num1 % 2 != 0
  print(is_odd)
  return is_odd 

is_odd(16)
is_odd(1)
print("-"*15)
print(is_odd.__doc__)

""" OUTPUT:
False
True
---------------
Function to check if the number is odd or not.

      Parameters:
        num1 (float): number to be checked

      Returns:
        is_odd (boolean): true if number is odd
"""
Enter fullscreen mode Exit fullscreen mode

When we use a third-party library or even some python in-built library we can use docstring to understand the use of a specific function.

print(range.__doc__)

""" OUTPUT:
Return an object that produces a sequence of integers from start (inclusive)
to stop (exclusive) by step.  range(i, j) produces i, i+1, i+2, ..., j-1.
start defaults to 0, and stop is omitted!  range(4) produces 0, 1, 2, 3.
These are exactly the valid indices for a list of 4 elements.
When step is given, it specifies the increment (or decrement).
"""
Enter fullscreen mode Exit fullscreen mode

That was it. Thank you for reading.

I hope, you were able to absorb some knowledge. If you have any questions or doubt mention them in the comment section or reach out to me on Twitter, LinkedIn or Instagram.

If you want me to explain any specific topic, mention that in the comment section below 👇

Discussion (0)