Dictionary or Else

Let's keep adding tools that we can use to make this lamp really awesome. Non-blocking waiting is going to be helpful. Another useful concept we'll lean on later is using python dictionaries.

You will often find yourself writing code that seems repetitive. You may have a number of lines of code that are a series of similar elements using if and elif statements. Let's take a look at an example.

from adafruit_circuitplayground.express import cpx

while True:
    if cpx.touch_A1:
        cpx.pixels.fill((255, 0, 0))  # red
    elif cpx.touch_A2:
        cpx.pixels.fill((255, 40, 0))  # orange
    elif cpx.touch_A3:
        cpx.pixels.fill((255, 150, 0))  # yellow
    elif cpx.touch_A4:
        cpx.pixels.fill((0, 255, 0))  # green
    elif cpx.touch_A5:
        cpx.pixels.fill((0, 0, 255))  # blue
    elif cpx.touch_A6:
        cpx.pixels.fill((180, 0, 255))  # purple
    elif cpx.touch_A7:
        cpx.pixels.fill((0, 0, 0))  # off

In this example, we are changing the colors of the NeoPixels using the capacitive touch pads. Each touch pad changes it to a different color, and the last touch pad turns them off.

This code seems really repetitive though. The difference between the if and elif statements is which touch pad, and the difference between the color statements is the color. Is there another way to do this? Yes! We're going to use a dictionary.

The CircuitPython Dictionary

A dictionary maps a set of objects, called keys, to another set of objects, called values. These are expressed in key: value pairs. Within a single dictionary, each key must be unique. A dictionary can contain all different types of information. Dictionaries have a name and the information is contained within {} brackets.

For our dictionary, we're going to pair a string with a tuple. Our string will be the names of the different touch pads, and the tuple will be the associated (r, g, b) color value.  Let's take a look what our code looks like with a dictionary for our data.

from adafruit_circuitplayground.express import cpx

touchpad_to_color = {
    "touch_A1": (255, 0, 0),  # red
    "touch_A2": (255, 40, 0),  # orange
    "touch_A3": (255, 150, 0),  # yellow
    "touch_A4": (0, 255, 0),  # green
    "touch_A5": (0, 0, 255),  # blue
    "touch_A6": (180, 0, 255),  # purple
    "touch_A7": (0, 0, 0),  # off
}

while True:
    for touchpad in touchpad_to_color:
        if getattr(cpx, touchpad):
            cpx.pixels.fill(touchpad_to_color[touchpad])

We've named our dictionary touchpad_to_color. Our keys are strings with the touch pad names. Our values are the colors we chose to associate with each touch pad. For example, the first key: value pair is "touch_A1": (255, 0, 0). Note that the "touch_A1" including the quotation marks is the string, and as a whole is the key. Now that we have our dictionary, we can use it in our code.

Our loop starts with for touchpad in touchpad_to_color:. This line ensures that the code only applies if the key is found within the dictionary. Otherwise, you'll get a KeyError if you try to apply a key that isn't found! This check avoids that. The key thing to know is that for key in dictionary steps over all the keys. So not only does it ensure the key is found, it ensures the entire dictionary is utilised. Then with our if statement we say, if a key touch pad has been touched, use the paired value to fill the NeoPixels the associated color.

We went from seven if and elif statements to one if statement. We add some data but we save a lot of code in our loop. Data is easier to manipulate than code. So, in the event we wanted to add more touch pads to our dictionary, we add only one line of data into our dictionary for every two lines of code we would have had to add without it!

This guide was first published on Feb 20, 2018. It was last updated on Sep 20, 2018. This page (Dictionary or Else) was last updated on Feb 19, 2018.