Intro to Programming with Python – #4

This is a small series of programming tutorials which will eventually transition into a bigger series encompassing Deep Learning/Machine Learning. Till now we have gone through major concepts of programming.

  • In the first post, we went through the installation of Python and understood basic units of a programming language, a.k.a. Tokens.
  • In the second post, we went through basic structure of a program, data types generally used in Python and a powerful construct of programming world, the if-else-if ladder.
  • In the third post, we brought out the artillery with loops and discussed why they are a necessity. We also went through usage of some of the iterable data types which were introduced in second post.

Now that we have learnt the basic moving parts of a programming language, we can move on to heavy lifters which make our life easy. One such main concept is functions. We will be going over the program we made in third post and understand why it isn’t comes under good coding practices and how we can improve it. In the process, we will learn how we can leverage functions to make it a nicely coded program.

But before moving ahead, find assignment solutions for last post here.

FUNCTIONS IN PYTHON

So what is a function? Remember when in second post we discussed the basic structure of a program? A short summary of the structure we discussed: every program takes an input, do some processing over the input and deliver the processed result.

Consider a function to be a small dedicated program that can be used over and over again to process certain type of data without needing to write the same code repeatedly. What does this mean? Consider having to cut some salad using a knife. Do you buy a new knife whenever you want to cut salad. No, yeah I guess so. That’s what functions are for; just take a bunch of repetitive code that have one work to do and convert them into a function and get a fully functional knife from which you can cut salad for a long long time.

Let’s have a look at general structure of a python function.

def <function-name>(<argument-list>):
    <do-something with arguments>
    <do-something more with arguments>
    ...
    return <result>

What is that hell of a thing? Let’s just calm ourselves down and go over things one step at a time!

  • What is def? If you remember tokens from first post, you might remember that in programming languages we have something called a keyword. A keyword always have a fix meaning! And our keyword here tells python to remember that we are going to define a function now which we will be using ahead.
  • What is <function-name>? Well, as the name suggests, we substitute it with some name (some identifier, remember it from first post?). For example, our function can have name sum, max or magic etc. So whenever we call a function (using a function is generally referred to as calling it), we use this name for the sake of simplicity.
  • What is <argument-list>? Remember that function is a program that requires input. Most of the input in a function goes from here. Here we are defining a list of identifiers that a function takes in and works on!
  • Now I think <do-something …> will be well explanatory now. We process arguments here!
  • And lastly, return! Finally when function has done its processing it has to return something (give some output) to the caller (the place where it has been called).

EXAMPLE OF A PYTHON FUNCTION

We have already discussed in the last post that sum() is a built-in function that takes in a list and returns sum of all the values in it. Let’s make a function that takes a list and returns the sum of all the values in that list. How will it operate? We will make use of following steps to define our function!!

  1. Think of a super cool function name. Say, sum_list
  2. Take a list, say input_list. This is our argument that we will pass in the function.
  3. Define a variable, total = 0. Why total = 0? Because any number a + 0 = a.
  4. Iterate over the list using for loop and add each element to total.
  5. Most important step! Get out of for loop by left indentation.
  6. Finally, return total (sum of all the elements in the list).

Launch up a file in your favorite text editor and name it func_demo.py. Now, let’s add our function to the file and save it.

def sum_list(input_list):
    total = 0
    for ele in input_list:
        total = total + ele
    return total

Go to your terminal and try to run the file using command python func_demo.py. (Make sure you are in right directory). Did something happen? Did your program print something? I bet it didn’t. This is because till now we have just defined a function but didn’t use it. In programming words, we didn’t call the function!! So let’s add some calling statements in our func_demo.py file. Remember to left indent to come out of your `sum_list` function as shown below.

def sum_list(input_list):
    total = 0
    for ele in input_list:
        total = total + ele
    return total

my_list = [10, 20, 30, 40, 50]
print("Sum of", my_list, "=", sum_list(my_list))

my_list2 = [1.5, 2.7, 3.9, 4.1, 5.3]
print("Sum of", my_list2, "=", sum_list(my_list2))

my_list3 = ['This', 'is', 'a', 'list', 'of', 'strings', '.']
print("Sum of", my_list3, "=", sum_list(my_list3))		

Now try to run it using command python func_demo.py. Output will be something like this:

I think the first two lines will be clear and we got the result as expected. But what happened when we used strings? Why did python sprout some nonsense? Well, it wasn’t python. Let’s go back to our sum_list() function and try to read its second line where we say total = 0. So what about it? Let’s take a deep breath and think about asking ourselves – Can we add ‘This’, a string, and an integer 0? or for that matter can we add a string to any other type? The answer is of course a big NO. And python, being a good friend it is, justifies everything very clearly. It does so by stating that the operand(s), things on which we are applying `+` operator, are unsupported for `+` operator. So, it states that int and str cannot be added in its own pythonic way!

So can you correct it such that we can apply concatenate on a list of strings using sum_list() function while maintaining its current functionality? Try it yourself as this is an assignment for this post along with others below. If you don’t get it, don’t worry, we always have solutions attached in next posts.

WHY AN ITCH TO HAVE FUNCTIONS?

To understand this, let us have a look at the complete code from previous post. If you remember it correctly, we were asked to take marks of 5 subjects as input and produce the grade report for the student.

Doesn’t the code feels like too much for such a small task. Let’s particularly have a look at the if-elif ladder used for grade calculation. Isn’t the same if-elif ladder used twice? And each time we used it we have to use 10 extra lines of our program. Such a waste of time and lines! Let’s rectify this! Let’s make a function that takes marks as input and outputs the grade of the student. Make sure you try it yourself before looking at my code!

def get_grade(marks):
    if marks >= 80:
        grade = 'A'
    elif marks >= 65:
        grade = 'B'
    elif marks >= 50:
        grade = 'C'
    elif marks >= 35:
        grade = 'D'
    else:
        grade = 'E'
    return grade

Can we shorten the above function further? Yes, we can. Remember that whenever we call return to send back the value we terminate the function. So let’s throw away the grade variable and return grade directly. Also, remember that the else statement will run if none of the other cases match. In which case we will always have to return ‘E’ as grade. This means we really don’t need else there.

def get_grade(marks):
    if marks >= 80:
        return 'A'
    elif marks >= 65:
        return 'B'
    elif marks >= 50:
        return 'C'
    elif marks >= 35:
        return 'D'
    return 'E'

Finally, let’s add this function to our new code to see how it fits in.

We just now reduced 9 lines from our code by creating a small function. Consider having a code base of 1000s of lines. If we encounter an error in code, we can target a function rather than fiddling through all of the lines. Not only that, if we didn’t have functions we might have got millions of lines of code rather than thousands.

Some examples of Functions in Python

Finally, here are some useful examples of functions in python!

Our example here had only one argument (input). This might cause confusion to some that how we can send multiple values to a function. So I curated this example – a function that returns a list which is addition of two lists of same size!

def add_lists(list1, list2):
new_list = []
for i in range(len(list1)):
new_list.append(list1[i] + list2[i])
return new_list

Sometimes you might want functions that require nothing as input. Let’s see how we can define them.

def get_key():
return 'This is some important key for a crypted data!!'

Sometimes you might want a function that returns nothing but does something for you. Let’s see how we can define them.

def display_grading_system():
print('\n' + '-' * 10 + 'GRADING CRITERIA' + '-' * 10)
print('|{:10s}|{:^23s}|'.format('A', '>=80%'))
print('|{:10s}|{:^23s}|'.format('B', '>=65% and < 80%'))
print('|{:10s}|{:^23s}|'.format('C', '>=50% and < 65%'))
print('|{:10s}|{:^23s}|'.format('D', '>=35% and < 50%'))
print('|{:10s}|{:^23s}|'.format('E', '<35%'))
print('-' * 36)

Remember that a function that returns nothing, or a function without a return statement, by default returns a special type of data called None.

Sometimes you might need to return multiple values from a function. Let’s try it out. Here I made a function that returns maximum and minimum value of a list.

def get_min_max_vals(my_list):
return min(my_list), max(my_list)

But how does this works? Behind the scenes python converts returning entities into a tuple and thus it is returning a tuple not two different entities (this is known as packing). Let’s see how we will get these values.

min_val, max_val = get_min_max_vals([10, -100, 99, -1000, 999, 123, 54])

Here, python sees that a tuple is coming back and realizes tuple has two values and we are asking two values from the function call. Thus, the tuple is decoupled (unpacking in pythonic terms) into two different values.

There is one other way of using arguments in function which allows us to give default values to arguments. This means if no value is passed at time of calling, functions will take default value for those arguments. But that is topic for another time with a fresh mind.

This brings us to the end of this tutorial. This blog post is complex for beginners and might be overwhelming at places. Use comment sections to discuss, ask and interact with me as well as others to clear your doubts. 🙂

Before going ahead dirty your hands and broader your mind using following assignments:

  1. Armstrong numbers are those in which sum of cubes of digits is equal to the number itself. For example, 371 is an Armstrong number as 3^3 + 7^3 + 1^3 = 371. Write a function that takes a number a returns whether the number is Armstrong (True) or not (False).
  2. Try to rectify sum_list() function so that it maintains current behavior while making sure it can concatenate a list of strings.
  3. Write a function that takes a list and return the maximum value present in the list along with the index at which it is present in the list.

Links to Some Useful Python Books

  1. Learn Python 3 The Hard Way
  2. Automate the Boring Stuff with Python
  3. Python Crash Course

This Post Has 2 Comments

Leave a Reply

Close Menu

SUBSCRIBE FOR WEEKLY POST UPDATES <3