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 it also makes 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.
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, Input
s and Output
s. Each of those types
has it's own special functions that they can use, and we'll discuss this more later.
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...
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 and 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...
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:
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.
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.
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.
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.