Maker.io main logo

Intro to Python for Makers (Part 5) - Custom Functions

2021-06-02 | By Maker.io Staff

A preceding article in this series introduced you to function calls and demonstrated how to use Python’s built-in functions to perform several tasks. This article goes a step further and teaches you how to build custom functions that you can call in your code. Doing so helps to keep your code organized and clean, as you can implement some functionality once and then use it in many spots throughout your program

Writing Custom Functions in Python

Take a look at the following example. It might look overwhelming at first, but we’ll break it down, step by step, below:

Copy Code
def printLengthOfList(list, printElements=False):
    
	print("The list has " + str(len(list)) + " elements!")
    
	if printElements:
    	    for i in range(0, len(list)):
            	print(list[i])
       	 
	return True
    
fruits = ["Apple", "Banana", "Kiwi", "Papaya", "Watermelon"]
ok = printLengthOfList(fruits) # The printElements parameter is optional
ok = printLengthOfList(fruits, True) # You can, however, supply it

This snippet defines a new custom function called "printLengthOfList". Note how the definition starts with the def keyword, followed by the function name, followed by the expected arguments in parentheses. This function has a single mandatory argument called list and an optional one named printElements. If you call the method and don’t supply a value for the printElements argument, it defaults to False. The line then ends with a colon. From then on, all indented lines are part of the function, analogously to if-blocks and loops.

The first line of the custom method prints the length of the supplied list. The line that follows it checks whether the user passed "True" as the optional argument. If the user did, the for-loop goes over every element of the list and prints it.

The last line of this function returns "True". Note that this is an optional line, and we only added it as an example. In Python, you don’t have to specify what your function returns. It may also not return anything.

Below the function definition, you can see the fruits list and two calls to the printLengthOfList function. One of the function calls omits the optional parameter while the other one supplies a value for it.

Magic Methods in Python

Part two of this series mentioned a common problem when you try to apply one of the basic binary operators, such as the arithmetic subtraction, with complex data types. All these basic operations work for numbers, and some of them might even work for other data types, such as strings. One example is the addition operator for strings, which concatenates two strings.

However, some operations, such as subtraction, are not implemented for various complex data types, like strings. And it’s easy to understand why when you think about what the string subtraction might look like. The same problem arises when you define custom data types, as the following article will discuss in more detail. How could Python, or any other programming language for that matter, know how to add two complex objects (like complex numbers)?

Many programming languages require you to write custom functions for that case. Python, however, allows the programmer to re-define the meaning of many standard operations, similar to C++. In Python, programmers can override so-called magic methods, which themselves override how the interpreter applies binary operators to complex variables such as custom objects:

Copy Code
class Complex:
	real = 0
	imag = 0
    
	def __init__(self, r, i):
            	self.real = r
            	self.imag = i
    
	# Classic method that adds two complex numbers
	def addition(self, other):
            	r = self.real + other.real
            	i = self.imag + other.imag
            	return Complex(r, i)
   	 
	# Python's magic method for addition
	def __add__(self, other):
            	r = self.real + other.real
            	i = self.imag + other.imag
            	return Complex(r, i)
   	 
	# This magic method represents a complex object
	# as a string. This is useful when you want to
	# output an object's values with the print
	# function
	def __str__(self):
            	return "r = " + str(self.real) + ", i = " + str(self.imag)

Take a look at the three methods present in class. The addition() function is a custom Python method that adds two complex numbers and returns a new one. The __add__ and __str__ functions are magic methods. These override some of the standard behavior of Python. The __add__ method, for example, overrides what happens when you try to add two Complex objects using the binary addition operator. By default, this operation is undefined for custom objects. The __str__ magic method defines what happens if the programmer requests a string representation of an object of the Complex class, for example, when calling the built-in print() function:

Copy Code
# Create two complex number objects
c1 = Complex(10, 5)
c2 = Complex(2, 2)

# Use the binary addition operator to add the two numbers
# This only works because the Complex class, seen above,
# contains the __add__ magic method. Because it also
# overrides the __str__ method, we can just call print to
# display the resulting number's r and i components.
print(c1 + c2)

As you can see in the second code snippet, you can use the arithmetic addition operator to add the values of two instances of the Complex class (c1 and c2 in this example). And because Complex contains the __str__ magic method, you can use the print command just like you would with a primitive data type.

You can also employ the conventional addition method to demonstrate why magic methods are advantageous:

Copy Code
# If we didn't have the magic method, you'd have to add the
# numbers like this:
print(c1.addition(c2))

The addition operator, demonstrated in the second code snippet, is much more natural to read and easier to understand compared to the nested function calls in the last example.

Recommended Reading

Summary

Methods allow you to encapsulate custom behavior in a reusable block. Doing so results in code that is easier to read, understand, and maintain. In Python, you define functions using the def keyword, followed by the method name. If a method takes parameters, you supply the list of expected parameters within a set of parentheses. Python supports optional parameters, but they have to be at the end of the parameter list. Functions may return a value. A method, however, doesn’t have to return anything. Besides conventional methods, Python also supports the use of so-called magic methods. These allow you to define how several standard operators should behave when applied to custom objects.

We have covered quite a bit in this series, and the final upcoming article will explore classes and objects as the capstone concept for this introductory Python blog series. Once we’ve covered that concept, we’ll be able to expand these concepts out to additional how-to’s and projects!

TechForum

Have questions or comments? Continue the conversation on TechForum, DigiKey's online community and technical resource.

Visit TechForum