Programming Raspberry Pi with Python-Next Steps - Software Foundations - Hacking Raspberry Pi (2014)

Hacking Raspberry Pi (2014)

Part II. Software Foundations

Chapter 11. Programming Raspberry Pi with Python-Next Steps

By the time you’ve had the chance to study the material in Chapter 10, “Programming Raspberry Pi with Python—Beginnings,” you should have (at the least) the following Python skills under your belt:

Image You understand a bit of the purpose behind the Python programming language and why the Raspberry Pi Foundation wanted it to serve as the fundamental development environment on the Pi.

Image You know how to get in and out of the Python 3 interpreter and get online help for command syntax.

Image You know how to run .py Python script files.

My learning goals for you in this chapter are as follows:

Image To understand how to use the IDLE environment

Image To have a basic understanding of Python command syntax

Image To know where to go to learn Python formally, from “soup to nuts”

Image To understand what modules are and how to import them into Python 3

The skills you pick up in this chapter are especially important because when you start building Raspberry Pi projects, you need to understand how to manage Python modules and scripts as well as understand how the code flow works.

I finish this chapter by giving you some pointers for additional resources you can turn to if you’re inspired to deep-dive into Python. Let’s get to work!

Getting Comfortable with IDLE

Fire up Raspbian and double-click the IDLE3 icon on the LXDE desktop. You’ll see the Python Shell open onscreen, as shown in Figure 11.1. The Python Shell is essentially the Python 3 interpreter with a bunch of integrated development environment (IDE) stuff like debugging tools built-in. Interestingly, IDLE is itself a Python application!

FIGURE 11.1 IDLE, also called the Python Shell. You can open the IDLE Preferences dialog by clicking Options, Configure IDLE.


Note: Why Python 2?

You’ve doubtless noticed that Raspbian includes both Python 2 and Python 3 and that a separate version of IDLE exists for each language version. In my opinion, Python 2 is included in Raspbian primarily for backward compatibility with older Python scripts. In fact, the sample games that are included in the Raspbian image are themselves Python 2 scripts.


Let me briefly explain the purpose of each menu in the IDLE Python Shell:

Image File: Used to create and manage .py Python script files.

Image Edit: Enables you perform typical word-processing functions (Python scripts are plain text files, after all).

Image Shell: Allows you to restart the Python Shell if something goes wrong (akin to rebooting a frozen computer).

Image Debug: Enables you access tools for troubleshooting your Python scripts.

Image Options: Enables you customize the IDLE environment to suit your tastes.

Image Windows: Lets you switch among several open script files and the Python Shell.

Image Help: Gives you access to the IDLE and Python documentation.

We’re going to get right into Python development, here. Try issuing the following statements directly into IDLE at the chevron (>>>) prompt. Remember to press Enter after typing each statement:

25*5

The asterisk represents multiplication. Try division (/), addition (+), and subtraction (-) as well.

len("python")

The len function reports on how many characters a given string consists of.

x = input("What is your name? ")

You are storing user input in a new variable named x. I added a space intentionally after the question mark to put some space between the prompt and the user response.

x

You can persist the value of a variable in the current Python Shell session. If you restart the shell, then the variable is destroyed.

print("I’m gonna add a new line underneath this text. \n")

This command uses the newline escape character (\n) to add an extra line—this makes your programs easier to read.

#This is a comment

Single-line comments are preceded with the octothorpe or pound sign (#) character.

mylist = ["item one" , 2, 3.14]

Lists are a great way to pack multiple pieces of data into a single variable.

print(mylist)

You can retrieve individual items from a list as well.

type(x)

The type function tells you what data type is associated with a particular variable.

In preparation for your second real Python script (you wrote your first one in Chapter 10), let’s create a new file and save it to your home directory.


Task: Creating a New Python Script File

You already know that “the journey of a thousand miles starts with the first step.” Likewise, before you can author the code in a Python script file, you need to create said script file in the first place. Let’s get this party started!

1. In Python Shell, click File, New Window.

2. In the Untitled window that appears, click File, Save.

3. In the Save As dialog box, note that the default save location is your home directory. Name the new file guessing_game and click Save.

4. As a test, click File, Open in the editor window. Verify that guessing_game.py exists in your home directory.

You now know how to open script files in the Python Shell!


Writing a Simple Game

Next we are going to write a simple number-guessing game that gives you the opportunity to practice with some common Python code constructions and perhaps have a bit of fun in the process.

Start with the guessing_game.py file you created in the preceding section. Take a look at the following code sample (don’t include the line numbers) and then follow that up by studying my annotations for each line of code.

For reference, check out Figure 11.2 to see what the completed script looks like on my Raspberry Pi.

1. /usr/bin/env python
2. #Number guessing game adapted from
#inventwithpython.com
3. import random
4. guesscount = 0
5. number = random.randint(1, 10)
6. print("I thought of a number between 1 and 10. Can you guess it in three
tries?\n")
7. while guesscount < 3:
8. guess = input()
9. guess = int(guess)
10. guesscount = guesscount + 1
11. if guess < number:
print("Too low.")
12. if guess > number:
print("Too high.")
13 if guess == number:
break
14. if guess == number:
15. guesscount = str(guesscount)
16. print("Congratulations! You guessed the correct number in " +
guesscount+ " guesses!")
17. if guess != number:
number = str(number)
print("Sorry. The number I thought of was " + number + ".")

FIGURE 11.2 The number guessing game source code

On to the purpose of each line in the program:

1. This is the “shebang” line that points Raspbian to the location of the Python interpreter.

2. These are two single-line comments that give credit to the developer on whose code this example is based on. Incidentally, multiline comments in Python are done using the triple quote (""") punctuation before and after the comment.

3. Use the import function to bring in external code modules into the Python environment. Modules are discussed in greater detail later in the chapter. For now, understand that random is a module that ships with Python and gives you access to functions related to (what else?) random number generation.

4. Create a variable to store the running count of user guesses and initialize the value of the variable to zero.

5. Define a variable to hold the randomly selected number. Specifically, you call the randint function inside of the random module and ask the Python interpreter to generate an integer (whole number) between 1 and 10, inclusive.

6. This print statement explains the game to the player and inserts a new line between this prompt and the user’s first guess.

7. The while statement is an example of looping logic. It says “keep repeating whatever code is indented underneath until the guesscount variable reaches 3.”

8. Populate the guess variable with the user’s typed response.

9. Use the int function to ensure that the user’s input is typed as an integer. This is an example of type casting, in which you can convert data from one type to another.

10. Increment the guesscount variable by one each time you loop through the indented while code.

11. The if statement is probably the most common looping function in Python. Here it tests the guess variable against the computer’s generated number. If the user’s guess is below the number, it tells the user.

12. This if block does the same thing as 11, but here it tests if the user’s guess is above the correct value.

13. If the user’s guess matches the computer’s randomly selected number, then you break out of the while loop and continue with whatever code comes next in the script.

14. This if statement (and the next one) are necessary because if you break out of the while loop with a correct response, you want to end the game. This line of code also uses concatenation to combine static text and variable data. More on that later.

15. Convert the guesscount variable, which was created as an integer, to a string value. It’s common practice to cast numbers to strings when you want to print output for the user.

16. Concatenate, or combine, static text and variable data using the plus (+) operator. This can get confusing because you can also use the plus sign to perform arithmetic addition.

17. The purpose of this block is to handle the situation in which you leave the while loop because the user’s guess count exceeds three tries. Here you verify that the user’s guess does not match the computer’s number (!= is the programmatic equivalent of “not equal to”), convert the number to a string, and then inform the user.

Delving into a Bit More Detail

You can close your Python script file; let’s work directly in the Python Shell. First, I want to discuss three Python programming features in a bit more detail:

Image variables

Image type casting

Image concatenation

I’m calling out these three programming tools because they are so fundamental not only to Python, but to any programming language. For instance, most computer programs take data and perform some sort of processing and evaluation on it. How and where do you store that data? What if you need to convert data from one form to another—how is that done in Python? Finally, how do you combine multiple pieces of dynamic data?

Read on, friend...read on.

Variables

As previously discussed, a variable is a named placeholder for data. Variable naming in Python 3 is flexible, but there are a few rules that you need to keep in mind:

Image Python key words cannot be used as a variable name (naming a variable print is not allowed, for instance).

Image Variable names cannot contain spaces (underscores are okay, though).

Image Uppercase and lowercase characters are distinct (Var1 and var1 are considered two separate variables).

Image The first character of a variable name must be a letter a through z, A through Z, or an underscore character (no numbers to start variable names because this confuses the Python interpreter).

Image After the first character, you can use the digits 0 through 9 and underscores in variable names.

The equal sign (=) is used to assign value to a variable. This is in stark contrast to the double equals (==) that are used to test equality between two values. For instance:

Image var1 = 2 : This statement says, “The value of the variable named var2 is 2.”

Image var1 == 2 : This asks the question, “Does the value of the variable named var1 equal 2?”

Type Casting

In programming, a variable needs to be associated with a data type. The data type constrains, or limits, the kind of data stored by the variable. For instance, does the variable x below store a number or a string of characters? How about the variable y? How do you think Python computes the result of the variable z in the third code example?

x = "234"
y = 432
z = x + y

In some programming languages, the variable x in the previous example would be assumed to be a string because of the quotation marks. Therefore, the expression x+ y would fail because you can’t add a string and a number together.

Strictly typed programming languages like C require that you declare not only a variable’s name, but also the type of data that it can hold. Python isn’t like that; it’s much more lax.

Yes indeed—Python is pretty forgiving, data type-wise. You can use the type function to check the data type that Python associated with a variable. Try the following:

type(x)

Python 3 supports the following native data types:

Image Boolean: Possible values are True or False.

Image Numbers: Integers (whole numbers); Floats (decimal or fractional numbers), or complex numbers.

Image Strings: Character sequences.

Image Bytes: Binary data such as images or other media files.

Image Lists: Ordered value sequences.

Image Tuples: Ordered values that are different from lists inasmuch as lists can change their values (mutable), but tuples cannot (immutable).

Image Sets: Unordered value sequences.

Image Dictionaries: Unordered key-value pairs.

You can use type-casting functions to manually convert data from one data type to another. This is useful when you want to ensure that Python receives variable data in a particular format.

For instance, try this:

vara = "100"
type(vara)

The result of the above code is that Python sees “100” as a string rather than as an integer. Does that result surprise you? It shouldn’t. When the Python interpreter saw data contained within quotes, it assumed you wanted to use the str (string) data type instead of int (integer). You can fix it, though, by converting the string you assigned to the variable to an integer:

varb = int(vara)
type(varb)

In other words, Python infers a data type based upon how you type. If you use quotes, then dollars to donuts Python assumes you’re talking about a string value. If you supply a number without quotes, then Python selects one of the numeric data types depending upon the number.

For instance, a variable value of 100 is an integer, and 100.1 is a float. Understand?

Concatenation

In Python, string concatenation enables you to patch together bits of code. To do this, simply use the plus sign (+). Consider the following examples, all of which you can try out in the Python Shell:

Image str1, str2 = "abc", "def": Two things—you can create and initialize more than one variable in one shot, and you can use single or double quotes to contain string data.

Image str1 + str2: Note that when you concatenate strings, no extra space is included. The result of this operation is abcdef.

Image str1 + " " + str2: You can pad spaces by passing in the space character(s) as a separate string literal. In this example, the result is “abc def”. Pretty cool, huh?

Image print("The combined string value is: " + str1 + str2): You can concatenate string literal data with variable data to provide the user with customized output.

Modules

In Python, modules are .py script files that contain one or more related code blocks. What is so cool about modules is that they make programming much more modular. Think of it: Would you rather write (or copy/paste) a bunch of functions you created that pertain to several different Python programs you’re working on, or would you rather have those functions stored in a module that you can load and unload at your convenience?

Earlier in this chapter I briefly introduced the random module that ships with the so-called reference version of Python 3. As you can see in Figure 11.3, the contents of the module are stored in plain text and can be viewed and analyzed by anyone.

FIGURE 11.3 Python modules are note encrypted, but boy, are they useful! Here you can see the code behind the randint function used earlier in the chapter.


Note: Where Are Modules Located?

You can run help(“modules”) to get a list of all currently available modules in your current Python 3 installation. After you get the name of your desired module, type help(“module_name”) to get the file location. For instance, in Raspbian, the random module is located by default in /usr/lib/python3.2/random.py.


Assuming a module is present on your system (see the note “Where Are Modules Located?” for more info), you can use the import statement to bring a module into the current Python environment. Note that an import statement lasts only for the duration of the current script file.

When you perform an import, all of the code contained in the module becomes available to you in Python. For instance, to import all code from the math module, you can issue any of the following statements:

import math
from math import *
import math, random (we can import more than one module at a time; just use a
comma separator)

After you’ve imported a module, run dir(module_name) to get a list of all the names (the Python term for code components) that are contained inside the module. To illustrate, run the following three statements in the Python Shell:

import math
content = dir(math)
content

Now let’s drill into the math module, and you’ll see how to take advantage of a module’s inner content. As an example, let’s work with the sqrt function from the math module:

import math
math.sqrt(25)

With respect to Python programming, a fully qualified function name takes the form of module.function. Thus, after importing the math module, you issue math.sqrt() when you want to run the sqrt() function that is contained in the math module.

Even though you imported the math module, the Python interpreter would get confused and issue an error if you used just sqrt() in your code without qualifying its location.


Note: Where to Find Cool Modules?

I’ve found that you can learn about any Python 3 module directly from the Python website. Check out the Python Module Index (http://is.gd/yr7n0A) to learn about the built-in module library. For third-party modules, see the Useful Modules list (http://is.gd/OvwCJm) at the Python Wiki. Finally, I cover Raspberry Pi-specific modules as we move through the remainder of this book.


As I said earlier, many Raspberry Pi projects require that you obtain and install additional modules. You can use the Linux apt-get command in many cases.

One word of warning: You need to be mindful of the fact that you’re working with Python 3 and not Python 2. Many online tutorials show you how to do stuff with Python on the Pi, and the module and code references the older version of Python.

Let’s make sure you have the most recent version of the GPIO module in your Python 3 installation. This module is important later because, you’ll recall, the GPIO headers are the principal way that you connect the Raspberry Pi to external hardware.

I’ve found that the case-sensitivity in Linux has caused Raspberry Pi users to conclude that their Python 3 installation is missing certain modules when, in point of fact, they are present. Try the following procedure.


Task: Loading and then Updating the GPIO Module in Python 3

Many of the projects that I cover in the latter part of this book involve taking control of the Raspberry Pi’s General Purpose Input/Output (GPIO) header pins. Accordingly, it is crucial that you ensure that your Python installation has access to the GPIO modules.

1. From LXTerminal, type python3 to start an interactive Python 3 session.

2. Import the GPIO module included in Raspbian so you can begin the process of interacting with the Pi’s GPIO headers:

import RPI.GPIO

3. Did that work? No? Well, something you should know is that GPIO is a function library inside of the RPi module. Notice the mixed case. Try this:

import RPi.GPIO as GPIO

The as keyword is used to provide an alias to an imported module. This means you can call GPIO functions by using GPIO instead of RPi.GPIO. You had some more problems though, correct? It turns out you also need to run Python as root. Sheesh!

4. Run exit() to leave the interpreter and then issue sudo python3 to enter the interpreter as root. One more time with feeling!

import RPi.GPIO as GPIO
dir(GPIO)

Now we’re cooking! The output is displayed in Figure 11.4.

FIGURE 11.4 Working with modules in Python 3 can be...interesting.

5. Exit the interpreter one final time. Let’s update the module to make sure you have the latest and greatest version:

sudo apt-get update
sudo apt-get dist-upgrade
sudo apt-get install python3-rpi.gpio


Where Do You Go from Here?

If nothing else, I hope your work in Chapters 10 and 11 has fired your imagination and inspired you to learn more about Python programming. My challenge as your guide has been to pack as much Python instruction as possible in just a few pages in a Raspberry Pi book.

However, for those interested readers, I want to share with you what I think are the very best Python learning resources available. I know different people have different learning styles, so following is a collection of various types of references for your studying pleasure.

Image Textbooks: For my money, you simply cannot go wrong with Tony Gaddis’ Starting Out with Python, 2nd Edition (http://is.gd/CZy0QN).

Another Python text I enthusiastically recommend is Mark Lutz’ Learning Python (http://is.gd/0oueEV). I’m not sure why the book gets mixed reviews on Amazon because it really is a landmark text.

Image Computer-based Training: At the risk of coming across as a self-promoter, I recorded a computer-based training course on Python Programming for CBT Nuggets (http://is.gd/A5XQei) that I fully stand behind. What’s cool about computer-based training is that you can see the concepts in action immediately on your computer screen.

A second computer-based training course I had a hand in developing and recommend is Wesley Chun’s Python Fundamentals LiveLessons (http://is.gd/V56Ekl).

Image Online Resources: As I’ve stated before, the Python website is perhaps the best reference source on the Internet for learning Python. Check out The Python Tutorial at http://is.gd/KyCom5.

Another awesome online resource, and it is completely free, is Dive into Python 3 by Mark Pilgrim (http://is.gd/QeW7OH). This is essentially the full text of the associated textbook by Apress. However, it’s really nice to have direct access to the source code and examples.