Writing Functions

In some of the earlier examples, your scripts used a function named sleep.  This function made the micro:bit wait for a certain amount of time before allowing it to execute the next statement in your script. 

A function is a block of code that your script can call to make it do a certain job.  In the case of sleep, the block of code is tucked away with other functions in the microbit module.  When your script starts with from microbit import *, it gets access to sleep and several other functions.   

Functions aren't only found in places like the microbit module.  You can also write your own functions and call them, all from within the same Python script.  This is especially useful when you have a group of statements that gets used in several different places in your program.  After putting that group of statements into a function and giving it a name, it just takes one statement to call the function at any point.   

Imagine you have ten statements that need to be executed at four different locations in your script.  With a function, you can reduce the extra code from forty lines to fifteen.  That's ten lines of code, one line to define the function's name, and then single-line function calls from the four locations.  

Since functions are such an important tool for keeping your program small and organized, this activity will guide you through adding functions to your Python scripts and calling them.
Objects, Methods, Properties, and Functions

In case you were wondering why sleep(1000) is considered a function call and display.scroll("Hello world") is considered a method call:  When a function belongs to an object, it's called a method.  When you see display.scroll("Message"), the object's name is display, and scroll is the name of one of its methods.  Another method call you might remember is display.show(Image.duck).  The show method is also function code that belongs to the display object.  

Objects can be copied and given unique names.  Also, in addition to methods, objects can contain properties.  For example, the Image object has properties like Image.HEART and Image.HAPPY.  Different object copies storing different properties can even cause their methods to produce different, custom results.  So the name change from function to method implies some extra flexibility that comes with being part of an object. 

 

Define a Function

The following script defines one function. The smile function simply displays a smile on the microbit’s display. It doesn’t take any inputs nor does it return anything.

Function definition: smile

  • Examine the smile function definition script below.
#smile

from microbit import *

def smile():
    display.show(Image.HAPPY)
    sleep(2000)    

Notice that the syntax for defining functions begins with the keyword def. After a space you can then type the name of the function, such as smile, with a pair of parentheses () attached. After the parentheses, you will need to put a colon:. Just like with if… statements, for loops, and while loops, the very next line after a colon will need to be indented. The indented lines that follow are all part of the function. The indented lines are not executed unless the function is called upon.

  • Enter, save, and flash the smile function definition script above to the micro:bit module.

The script doesn’t do anything! We defined a function but we didn’t call upon it.

When you call a function, you must type it exactly like you named it. It is case sensitive. Also, it must be called below the function definition.

  • Add a call to the function at the end of the smile script, and re-flash.
#smile

from microbit import *

def smile():
    display.show(Image.HAPPY)
    sleep(2000)

smile()

Example script: emote

The script smile didn’t have a very complex function. Let’s see what else we can do with functions! For example, we can nest if…else… statements inside functions.

  • Enter, save, and flash the script emote to your micro:bit.
# emote

from microbit import *
 
def emote(feeling):
    if feeling == "happy":
        display.show(Image.HAPPY)
    elif feeling == "sad":
        display.show(Image.SAD)
    else:
        display.scroll("I don't understand that feeling. Try happy or sad.")
    sleep(2000)

emote("happy")

In the emote script, our function now has an input. That input is either the word "happy" or the word "sad". When the function is called, it will use the nested if..elif..else statement to determine if the feeling is happy, sad, or not understandable!

  • Replace the word "happy" with "sad"  and re-flash the script onto the microbit. What do you expect to see on the display?

Example script: adding

While the function in the emote script has an input, or parameter, that we can pass through it, it still doesn’t have anything it returns. The functions in the script adding both have parameters and return values.

  • Enter, save, and flash the script adding to your micro:bit.
# adding

from microbit import *

def add_one(value):
    value = value + 1
    return value
    
def addTogether(value1, value2):
    result = value1 + value2
    return result
    
display.scroll(add_one(5))
display.scroll(addTogether(5,6))

Notice how the add_one function takes one input. It then takes the input and adds one to it. It then returns the new result of that addition.

The addTogether function takes two inputs. It then adds those two inputs together and assigns the result to a new variable called result. It then returns that result.

Since the neither of these functions cause the value to display, we can instead call them inside of the display’s scroll method. This means we can pass functions through methods!

Optional example script: ternary

Not only can we use functions as arguments, we can also write functions that have conditionals as parameters using what is called the ternary operator. The familiar binary operators have 2 inputs. The ternary operator has three inputs: input1 if input2 else input3. Note that input2 is a condition. To see the ternary operator in action, check out the last few lines of the following program

  • Enter, save, and flash the script ternary to your micro:bit.
#ternary

from microbit import *
    
def add_one(value):
    value = value + 1
    return value
    
while True:
    computation = add_one(5 if button_a.is_pressed() else 10)
    display.scroll(computation)
  • Press button A so the function will add one to 5, then release it so it will add one to 10.

The result is stored to the variable called computation, then the value of computation is scrolled on the display.