You have already used built-in functions when you have done such things as str(x)
, which converts a number to a string. You have also used display.scroll()
. scroll
is a special kind of function that belongs to the display
object. Such functions are called methods. The scroll
method will “call” other methods and functions to turn LEDs on and off and make the
display do what it does. In addition to all the built-in functions and methods in
Python, you can write your own functions. This helps to keep your code neat and easy
to follow.
You can think of functions as commands that you can use in your programs, such as
str
(convert something to a string) or sleep
(wait a while). These might be built-in functions, or they might be functions that
you have written yourself. Writing your own functions allows you to have your program
in small chunks of code so that it’s easier to understand how the program works and
to fix things when they don’t work. It also means that you can use the function over
and over again without having to repeat chunks of code.
These chunks of code (functions) are given a name when you make them, and the name
has the same rules as when you create a variable. That is, the name must start with
a letter and not contain any spaces. Words are connected by an underscore, so typical
function names might be sleep
, print
, or, for a home-made function that you will see in a moment, display_mins
. Whereas the names of variables are normally nouns (e.g., message
and mins
), the names of functions are often verbs (e.g., sleep
, print
, and display_mins
).
Functions can be built to have parameters. For example, the built-in function sleep
has a parameter that is the number of milliseconds for the program to sleep. The
function sleep
expects to receive this parameter whenever sleep
is called. In the case of sleep
, it expects this parameter to be a number. For example:
If you were to pass
a string to sleep
as its parameter, you would get an error. When calling a function, the parameter
always comes after the method name and is enclosed in parentheses. If a function has
more than one parameter, the parameters are separated by commas.
The time has come for you to write your own function in our timer example. So load
the example ch04_timer_02.py
. The revised program is shown in Figure 4-1.
Figure 4-1 Function definition and calling.
Flash the program onto your micro:bit, and notice that now it displays either min
or mins
after the number of minutes to which the timer is set. The next thing to notice about the code is that now there is a block of code that starts with def
after the mins
variable. The word def
marks the start of a method definition
. This is where our custom function called display_mins
is defined.
And here is a really important point: although the function is defined here, it will
not actually do anything until it is called. This calling of the function only happens right at the end of the while
loop in the last line of the program.
In the same way as if
, else
, and while
, all the lines that belong to the function definition must be indented.
After the word def
is the name of the function and then its parameters between parentheses. In this
case, there is just the one parameter called m
. m
is short for mins
, and we could have called m
by the name mins
like the variable. But I have used a different name here to make it clearer how functions
work and the relationship between m
inside the function and mins
outside it.
In addition to being a parameter, m
is also a special type of variable called a local variable. It is local in the sense that it can only be used within the function of which it
is a parameter (in this case, display_mins
). The value of m
is set when the function is called, so jumping for a moment to the end of the program,
we have:
This line of code calls (runs) the function display_mins
, specifying that it will supply mins
as the parameter to the function. Python will take whatever value is in mins
and assign it to m
within display_mins
. The lines of code inside display_mins
will then be run in turn until the end of the function is reached, at which point
Python will continue with any lines that come after the call to the function. In this
case, there is no line of code after the call. It’s the last line, but because it
is inside the loop, the first line inside the loop will run again.
Returning for a moment to the lines of code in the function (called the function’s
body), you can see that the variable message
is defined inside the function and is given a value of m
converted into a string. This variable m
, although not a parameter like m
, is still a local variable. That is, the variable message
will only exist inside the function while the function is actually running. So a
new message
is created each time that the display_mins
function is called and is then automatically destroyed after the function finishes
running. This may seem inefficient, but actually microprocessors are designed to be
able to do this kind of thing really quickly.
The if
on line 7 checks to see if the number of minutes m
is 1
, and if it is, it adds the string "min"
to message
. Note the use of +=
, which adds the string "min"
onto the end of message
. If m
isn’t 1
, then "mins"
(plural) is added to the message. Finally, display.scroll
is called to display the message.
Earlier I described m
and message
as local variables. The variable mins
sits at the top of the program and is accessible from anywhere within the code. This
type of variable is called a global variable. The discussion about just how bad it is to use global variables takes on almost
religious overtones. There is no doubt that overuse of global variables does lead
to unmanageable code, but if you are writing a few dozen lines of Python for a micro:bit,
it’s really not the same problem as the thousands or millions of lines of code in
a large program.
If you wanted to, you could just use the global variable mins
throughout the program. You might like to load up ch04_timer_02_globals.py
and verify that it does work the same as the previous version.
The differences between this and the previous version are highlighted in bold. First,
the parameter m
has been removed, so display_mins
no longer has any parameters. Now display_mins
uses the global variable mins
directly rather than having mins
passed to it.
This version works just fine in this simple example, but it does mean that you can
now only use display_mins
to display the value in the global variable mins
. So if we had another global variable called something else, we couldn’t use display_mins
to display it. By giving it a parameter, we make it more flexible.
The display_mins
function does a task rather than calculate a value. It’s not like the built-in function
str
, which takes a number as a parameter and converts it into a string. Functions like
str
are said to return a value. This allows you to write things like this:
which gives the variable message
the value returned by str
(in this case, the string "123"
).
You can write your own functions that return a value using the word return
. For example, we can modify our timer example so that the code to add min
or mins
to the end of the number of minutes is contained in its own function. You can find
this modified version in ch04_timer_03.py
.
Most of the code is the same, but display_mins
has been changed, and a new function, pluralize
, has been added. Let’s look at pluralize
first.
This function has two parameters: word
, which is a text string, and x
, which is an integer. If x
is 1
, then the function returns the parameter word
unchanged. However, if x
is not 1
, then the value of word
plus an "s"
is returned. Once the word return
is encountered, nothing further happens in the function. So in addition to returning
a value, return
also ends the function, continuing with the main program.
We can now use the pluralize
function in the display_mins
function by changing display_mins
to:
The body of display_mins
is now just a single line that contains two calls to other functions. First, it calls
the built-in function str
to convert the number into a string, and then it calls pluralize
to add an s
if necessary. The results of these two function calls are combined into a single
string using a plus sign, and the result is scrolled across the display.
One neat feature of Python is the ability to use optional parameters with default values. This allows you to hide away rarely used parameters while retaining the flexibility of the function. For example, the following function increases the number supplied as an argument. By default, it will increase it by just one.
Functions are a great way to break down your programs into more manageable chunks, and functions can also often be reused, so you can take a function that you wrote for one project and use it in another. You will meet methods, which are a special type of function, in Chapter 7. We are now going to park the timer example for a while and return to it in Chapter 6, where we will make it a whole lot more complex and finish the project.