Learn how to create your own functions in python

I wrote a guide that showed how to use the builtin functions in python.

However, there comes a time when programming that a builtin function may not already exists and it will be in your best interest to craft one yourself. This guide provides an introduction on how to create your own functions in python, and even provide instructions on how to rewrite some of the popular functions in the python library to further hone your programming skills.

Learn the Syntax for Creating Functions

The following outlines how to create functions in python:

def function_name(a, b, c, … n):
    function code
    return value  
  • The def keyword is a reserved keyword in python. It denotes the start of a function.
  • The function_name indicates the name of the function, it’s proceeded by open parentheses.
  • The colon is used to indicate the end of the function header.
  • The body of the code goes after the function declaration.
  • The program can return a value using the builtin return keyword.
  • The letters a, b, c, and n are known as parameters. It represents data the function uses.

When you call or invoke a function, and pass in values these are known as arguments. Therefore, when you’re in the action of executing a function and passing in values it’s known as passing in arguments. Below are some some examples of functions in python. Note, you can include details about what your function does by including docstrings which are triple quotes that go inside the module, class, and function/method declarations.

def f(x):
    """ simple function that returns a value"""
    return x * 5


def g(x):
    """ function doesn't return anything """
    print(x * x * x)

>>> f(10)
50

>>> g(10)
1000

>>> def h(x):
...     return f(5)

>>> h(5)
25

>>> def h(x):
...     return x * f(5)

>>> h(10)
250

>> def i(x):
...     x * g(10)
... 
>>> i(5)
1000

To execute or call or invoke a function in python simply use the function name followed by the arguments as shown in the above examples. If you want your function to reuse a value then it must return it. A benefit to this is that value can be used in other aspects of your program. If you don’t want your function to return anything then you can exclude the return statement. A quick way to illustrate the difference between these two is as follows:

>>> def f(x):
...     return x * 10
... 
>>> f(10)
100

>>> def g(x):
...     y = x * x
... 
>>> g(10)

The above doesn’t show anything because it doesn’t return a value. If you don’t want to return something but still want to display output then you can simply print the value as shown in the updated code snippet:

>>> def g(x):
...     y = x * x
...     print(y)
... 
>>> g(10)
100

The Difference Between Functions and Methods

The main difference is that a function is not binded to a class the way a method is as shown in the following code snippet:

>>> class formulas:
...     """ simple class to test math formulas """
...     def arithmetic(self, x, y, z):
...         return (x + y ) * z
... 
>>> a = formulas()
>>> a.arithmetic(5, 10, 15)
225


>>> def arithmetic(x, y, z):
...     """ this is a function, different from a method """
...     return (x +y ) * z
... 
>>> arithmetic(10, 15, 20)
500

How to rewrite some of the functions in the python docs

Let’s get better at writing functions by rewriting some of the builtin python functions.

Before we write a function we should generally have an idea of the accepted inputs and the expected outputs. Some of the functions we’ll take a stab at are:

  • sum()
  • abs()
  • min()
  • max()
  • round()

Rewriting the sum function

The sum function is straightforward to understand. You pass in a sequence of numbers and then the sum is then computed. The logic for this can be detailed as follow:

  • a) Pass in an arbitrary number of elements into the function.
  • b) Add each subsequent number.
  • c) Return the sum of those numbers.

To enable a function to receive an arbitrary number of elements you can use the asterisk operator to make it look something like the following:

>>> def arbitrary(*args):
...     for x in args:
...         print(x)
... 
>>> arbitrary(5, 6, 8, 19, 10, 20, 50, 100)
5
6
8
19
10
20
50
100

Below is one solution to rewriting the builtin sum() function in python:

def compute_sum(*args):
    """ a replacement function to the builtin sum()
    function in the python api """
    sum = 0
    for x in args:
        sum += x
    return sum
print('a output:')

a1 = compute_sum(1, 2, 5)
a2 = compute_sum(1, 2, 3, 4, 5, 6, 7, 8)
a3 = compute_sum(1.282, 98, 68.29, 0.0292, .172, 87.928, 2772.228)
print(a1)
print(a2)
print(a3)
a output:
8
36
3027.9292 

Rewriting the abs() function

Let’s first think about what the abs() function does. It takes the absolute value of a number or it’s positive counterpart. Therefore, the logic behind it is straightforward as listed below:

  • a) Determine if the input is negative or positive.
  • b) If it’s positive do nothing.
  • c) If it’s negative then make it positive.

Let’s assume that the input or argument for the function is args:

  • We can translate the logic of a into python code by using a simple if statement like if
    args < 0
    .
  • We can translate the logic of b by simply returning args.
  • We can translate the logic of c into args * -1 since a negative multiplied by another negative is a positive.

Below is the transcribed python function:

def compute_abs(args):
    """ computes the absolute value of any number """
    if args < 0:
        args *= -1
        return args
    else:
        return args

print('b output:')
b1 = compute_abs(-10)
b2 = compute_abs(100)
b3 = compute_abs(-7.282)
b4 = compute_abs(.292020202)
b5 = compute_abs(-.029202029)

b output:
10
100
7.282
0.292020202
0.029202029 

Rewriting the min() function

The min() function should return the smallest number in a sequence. One simple but inefficient way to calculate this is as follows:

  • a) Iterate through the list of numbers.
  • b) Compare each subsequent number to an initial variable.
  • c) If the next number is smaller, swap it with the initial value.
  • d) Otherwise keep iterating.

Here’s the above steps translated into python code:

def compute_min(*args):
    """ find the smallest number entered """
    min = args[0]
    for x in args:
        if x < min:
            min = x
    return min

print('c output:')
c1 = compute_min(0, 5, 2, 9)
c2 = compute_min(10, 20, 50, 100)
c3 = compute_min(5, 10, 100)
c4 = compute_min(.20302, 1.292029, .292002, .00000289292)
c5 = compute_min(.00292020, 67.28282, 928, 16, 93922)

print(c1)
print(c2)
print(c3)
print(c4)
c output:
0
10
5
2.89292e-06
0.0029202

The max() function is in essence the same function except with a slight modification of the condition. The max() function is shown below:

def compute_max(*args):
    """ find the maximum number"""
    max = args[0]
    for x in args:
        if x > max:
            max = x
    return max

print('d output:')
d1 = compute_max(0, 5, 2, 9)
d2 = compute_max(10, 20, 50, 100)
d3 = compute_max(5, 10, 100)
d4 = compute_max(.20302, 1.292029, .292002, .00000289292)
d5 = compute_max(.00292020, 67.28282, 928, 16, 93922)

print(d1)
print(d2)
print(d3)
print(d4)
print(d5)

Rewriting the round() function in python

Python has a builtin function that allows us to round a number. On paper this might seem like an easy function to write it gets a little tricky as there’s a couple of things that you need to think about. For example, we need to know when to round up and when to round down. This is an interesting dilemma because it really depends on the length of the number. For example, here’s some same input/output of the builtin function in the python class:

>>> round(3628.283922)
3628
>>> round(.2)
0
>>> round(.5)
0
>>> round(.6)
1
>>> round(.05)
0
>>> round(29.23)
29
>>> round(53.5)
54

By analyzing the output we can deduce that if there’s no number in the whole number part of the floating point, and if the number to the right of the decimal (fractional part) is less than or equal to 5 then round down to 0, else round up to one. However, that rule changes when the number we’re working with numbers that have more than one number to the left of the decimal point.

In this case if the number to the right of the decimal point is greater than or equal to five, then we round this number up to the nearest integer. What makes implementing a function in this technique a little interesting is that we can’t just take the length of an integer, we have to convert it to another type like a string in order to find out it's length. Below is an example on how to convert a number to a string in python:

>>> num = .5
>>> str(num)
'0.5'
>>> num = .5
>>> num = str(num)
>>> num
'0.5'
>>> len(num)
3

Also, since we can’t compare strings to numbers we need a way to work around this. We could save the stings in a list and then get the appropriate index of the string as a number by passing the index into the int() function. Therefore, having a sound understanding of how the builtin round() function works in python along with an understanding of python’s data types, data structures, and how they relate to each other is important or less it will be a difficult to rewrite the round() function using the technique I’m proposing. Below is my rewrite of the round() function:

def compute_round(args):
    """ rounds a given number: emulates round() """
    convert, rounded_num, count = [], [], 0
    whole = 0
    num_to_string = str(args)
    for x in num_to_string:
        convert.append(x)
    if len(convert) == 3 and int(convert[2]) > 5:
        return 1.0
    elif len(convert) == 3 and int(convert[2]) < 5:
        return 0.0
    if len(convert) > 3:
        rounded_num = num_to_string.split('.')
        a, b = ''.join(rounded_num[0]), ''.join(rounded_num[1])
        if int(b[0]) >= 5:
            a = int(a)
            return a
        else:
            a = int(a)
        return a

print('g output:')
g1 = compute_round(0.4)
g2 = compute_round(1.23)
g3 = compute_round(.3392020)
g4 = compute_round(19.2882)
g5 = compute_round(159.28)
g6 = compute_round(159.58)
g7 = compute_round(-.3922)
g8 = compute_round(3232.3802832902)

print(g1)
print(g2)
print(g3)
print(g4)
print(g5)
print(g6)
print(g7)
print(g8)
g output:
0.0
1
0
19
159
159
0
3232
============================================================================ Want to learn how to use Python's most popular IDE Pycharm? In the free pdf guide "Getting the Hang of PyCharm" you'll learn all of the amazing features in PyCharm along with how to get started with data science. Subscribe to the Purcell Consult newsletter and get started A.S.A.P.