Python Functions
By: Alejandro Colocho
Tags: Programming, Python Programming, Python, Object Oriented, Data Science

Photo by: Glen Carrie

When I was in kindergarten, I hated color pencil pouches. It was extremely messy. You just dump all your color pencils there, pencils, scissors, rulers, etc. It would take forever to find the right pencil. When you write a program, you are basically dumping code into a big pouch to hold it all. It can get extremely messy. Thankfully, we have functions to make our job easier. Today, we are going to go through just that in python, so open up your favorite editor, open your mind, and get ready to have some fun.

Functions

Functions are a handy tool to recycle and group code. It can perform any task, return values, and accept arguments. Let’s go through a basic function.

def example_function():

print('Hello World!')

In order to build a function, we need to use the keyword def, then we name the function and place parenthesis right after, we use the colon to let python know we are going to start writing the function code, we indent the code, and we are done! In order to use our function, we just write the name of it and use parenthesis. Python will perform the code inside the function after we do that. In our example we just print the string “Hello World!”. However, let’s say that we wanted to print a custom message if a name is passed.

def example_function(name=None):

if name == None:

print('Hello World!')

else:

print("Hello {}.".format(name))

Now, we added logic to check if there is a name, so it can print a custom message. However, if there is no name, then it will default to “Hello World!”. As you can see, we can set a default value to our parameter. The default value can be anything. However, let’s say that we didn’t know how many people we need to greet. We can do the following for that situation.

def example_function(*args):

if len(args) == 0:

print('Hello World!')

else:

for i in args:

print('Hello {}'.format(i))

We use the *args parameter to tell our function that we can have 0, or we can have 0 < arguments passed. The key here is the *. We can name our arbitrary argument anything as long as the * is passed. Python will package all arbitrary arguments passed in a tuple. Now, let’s assume we wanted to print a greeting depending on the season.

def example_function(season,*args):

if len(args) == 0:

print('Hello World! Happy {}.'.format(season))

else:

for i in args:

print('Hello {}. Happy {}.'.format(i,season))

It is important to remember that because we have the *args keyword, we cannot set our parameters equal to our arguments such as season = ‘Summer’ because you will get a syntax error. Let’s continue. Now, let’s assume that our requirements change. Now, we do not want to print the string just return the values, and each name will have a different season. We can do something like the following.

def example_function(**kwargs):

if len(kwargs.items()) == 0:

return 'Hello World!'

else:

return ['Hello {}. Happy {}.'.format(name,season) for name, season in zip(kwargs.keys(),kwargs.values())]

There is a bit to go through. First, we use the **kwargs to tell python that our function will receive named arguments. For example, Alex=”Winter” or Jose=”Summer”. Then, we check the length of items to see if we need to trigger the default message. Keep in mind that we have to use the .items() because python will pack kwargs in a dictionary. Last, we iterate through our dictionary to generate our custom message. We do this by packing both keys and values using zip(), then we use list comprehension to iterate over our zip values. Once we generate the message, we use the return keyword to tell python to return the values for external use.

Annotations

In python there are some cool tricks to annotate your functions to give other developers more information. This helps you too! That way you wont come back later on and wonder “What does this code do?”. Let’s review annotations.

#Function that adds 2 to an integer def add_two(num:int) -> int: """

Arguements:

num: Can be any integer.

Returns:

An integer that has been increased by 2. Function that adds 2 to any integer. """

return num + 2

This function looks a little different than our previous functions. Let’s examine this code from top to bottom. First, we have a # above our function. If you are experienced with python you know what this is, but if you are new, then this is a comment. ALWAYS comment your code. This comment will be extremely helpful when you have to go back to this section, or if someone else has to go back to this section. Next, the line that defines our function looks extremely different, but let’s examine why this helps. Our argument is followed by a colon which is followed by the data type of what the argument should be. Outside of our parenthesis, we have an arrow that points to the data type that our function will return. Keep in mind that these aren’t rules, so python will not enforce the data types. For example, if you pass the function a float, then python will perform the operation and return a float. They are just annotations. The last thing thats different is the comment inside our function. This is called a docstring, and they are used to give information to the developer using the function. This is faster than going back looking for the file, then the function, then figuring out what it does. The docstring typically list the arguements and what they take, what the function returns, and a brief explanation. They can be as long as you like, but this does not mean they should be long.

Bonus

Python functions cannot be empty, but there is a cool trick to be able to have an empty function.

def bonus():

pass

The pass keyword literally tells python to skip over. This way you can have an empty function, but you can use the keyword in a variety of ways. For example, debugging and testing.

KEEP IN MIND it’s generally not very good practice to leave empty functions in your code.

Wrap Up

Functions are literally the most useful thing in programming. Why? Because it leads to writing less code since you are reusing it, it leads to less time debugging since you can isolate issues faster, and it leads to better code maintenance since you can update a couple lines of code in a central place. This is also known as object oriented programming or OOP for short.