Functions

In this tutorial, we're going to learn about functions and modules. A function is one of the most basic concepts in programming and also one of the most important. It often takes a lot of code to get a computer to do even a simple task, and if you want the computer to do the same task over and over again, that could mean having to write lots of the same code over and over again.

That doesn't sound very efficient, does it?

It's not, which is why, instead of writing the same code many times, we have the ability to just write the code once in a special format, and then we can use that code over and over again, as many times as we want. The special format that allows us to re-use the code over and over again is called a function.

One of the nice things about functions is that they also make it easy for you to use code that other people have written, without having to retype all the code yourself into your software. In fact, while you may not have realized it, you've already used several functions that other people have written. Some of those functions are included in the Python programming language that everyone (at least everyone who uses Python) has access to. You can often recognize functions because they contain () after them (many times with information between the parentheses), and when we use a function in our code, we generally say we are calling the function.

For example, when you use the command print(), you are actually calling a function named "print" that comes standard with the Python language. You may think that using print() to print something to the screen requires just a single line of code, but what you don't see behind-the-scenes is that the print() function actually utilizes thousands of lines of code. You read that correctly — every time you use print(), Python is running thousands of lines of code to print your message to the screen. But, because Python provides this command as a function, you can print to the screen using just a single programming line.

In addition to having access to the thousands of functions that are provided as part of Python programming language, you also have access to all the Ready Set STEM functions — a set of functions that we (the Ready Set STEM team) have written to make building with and using the Ready Set STEM CREATOR Kit easier and more functional.

For example, you might see the following in one of our projects:

Both of the lines of code above are calling Ready Set STEM functions that we have written to make using the kit easier and more powerful. While you only needed to write two lines of code to setup the GPIO as an output and turn on the LED, behind the scenes, there were over 300 lines of code that the Ready Set STEM team has written to carry out those tasks. Not to mention, within those 300+ lines of code, we were calling functions that other people had written — many thousands of more lines of code!

And again, you were able to utilize all that code by calling a couple functions. Even the best programmers in the world rarely write a piece of code that doesn't rely on code that others have written. This is one of the powerful concepts of programming — in addition to your own code, you get to benefit from code that others have written as well.

Why the Dot?

Throughout our projects (and out in the real world), you're going to see code that looks like:

my_led.on()

In the above, the period between my_led and on() is called the dot operator. The part on the right of the dot (in this case on()) is associated with the variable on the left (in this case my_led). You can only use functions that are supported by the type of the variable on the left. In this case, when we defined the my_led variable in the line above it, we defined it as an Output. By doing that, we gave the my_led variable the ability to call several special functions, like on() and off().

There are many other types of variables you'll use, like numbers, lists, strings, Inputs and Outputs. Each of those types has it's own special functions that they can use, and we'll discuss this more later.

Modules

In Python, a module is an group of functions (and perhaps other things, like variables). Typically, the collection of things in a module are all related to one another — perhaps they all are focused on the same types of tasks or we're all created by the same person.

For example, you probably noticed that our Projects Guide is broken up into sections, with each section focused on a particular topic and set of electronic components. Well, in most cases, we also organize the functions needed for each section into their own module. We have a gpio module that contains all of the functions you'll use in this section. We have a sound module that contains all of the functions you'll use to generate sounds (in the next section and beyond). And so on...

Learning About Available Modules & Functions?

As you might imagine, different functions are used in different ways. Some functions can be run by just using the function name followed by () (like the on() function we discussed above). Other functions require a bunch of information to be placed between the () to tell the function exactly what to do (like putting the information we want printed between the () in our print() statements.

But, how do we know what information a function needs/expects and how do we know about the special functions available through a dot operator to certain functions and variables?

In most cases, functions will have documentation — that is, a place where you can look up all the information about the function. For example, if you want to see all the modules that were written and provided by the Ready Set STEM team, you can click on the API icon at the top of this page. API stands for "Application Programming Interface" and is a fancy name for functions and modules that are used for a specific purpose — in this case, the Ready Set STEM API is used specifically to provide functionality to the CREATOR Kit.

If you click on the API icon at the top of the RDE, you'll see more detailed information on the Ready Set STEM API functions...

Importing Functions & Modules

Before you can use a function in your code, the computer needs to know about it. Specifically, there are the two types of functions you'll encounter:

  1. Built-In Commands: Some functions can be called anytime, anywhere in your code without having to do anything other than calling the function. These are referred to as "built-in" functions, and the print() function is a good example. We can use the print() function anywhere in our code without having to do anything other than calling the print() function.

  2. Imported Functions: For functions that we want to use that aren't built-in (including all the Ready Set STEM functions we provide), we need to tell the computer about those functions before we can use them. We do this by importing the function (or the whole module that it's part of) into our code.

For functions that need to be imported, there are two ways to do it — importing the individual functions we need or importing the entire module that holds that function.

Importing Individual Functions from a Module

In the cases where we only need access to one or two functions within a module, it's often convenient to import only the functions we need, directly by name. We do this using the from ... import command, with the following syntax:

from [module] import [function]

Here's an example of importing the sleep() function — a function that is used to put our program to sleep for a period of time:

As you can see, the sleep() function is part of the time module, and by importing the way we did above, we can use the sleep function simply by calling it (along with the number of seconds we want to sleep). Here's an example of what the code might look like:

The code above isn't very exciting — all it does is wait for 10 seconds and then the program ends. But, this should give you an idea of how functions can be imported and used one at a time.

Importing an Entire Module

If you're going to be using several functions within the same module, it's generally easiest to just import the whole module into your code. Doing this gives you access to any of the functions in that module any time you need them. We do this using the import command by itself.

As an example, let's give ourselves access to the same sleep() function we used again by importing the entire time module:

In addition to sleep(), the module time contains functions for telling time, formatting time strings, working with time zones, etc. By importing the entire module, we now have access to all those functions within that module.

By importing the entire module, we now have access to the sleep() function by calling:

Notice that to call the sleep() function in this example, we had to prepend the function call with the module name and the dot operator. This is one of the drawbacks to importing an entire function at a time — in order to use any functions within that module, we need to call the function using the module name and the dot operator.