© The Author(s), under exclusive license to APress Media, LLC, part of Springer Nature 2021
A. SuberoProgramming Microcontrollers with Pythonhttps://doi.org/10.1007/978-1-4842-7058-5_4

4. Python Programming

Armstrong Subero1  
(1)
Basse Terre, Moruga, Trinidad and Tobago
 

Python is a large and complex language that I cannot hope to cover in one chapter. There are simply too many functions and structures and programming constructs that need to be detailed to make you into a decent Python user. What I will try to do however is apply the 80/20 rule here, also called the Pareto principle. Since we are learning Python for the purpose of programming microcontrollers with CircuitPython, I can omit a lot of things and still have you understand just enough to follow along with this book.

For that reason, we will learn the 20% of the language that you will need to know to work with 80% of the tasks you are likely to do with CircuitPython. This chapter will thus present a subset of the core language, covering in brief the most important aspects of the language. If you have experience programming with Python, you may think I should have added one or the other. The subset I cover here though is enough so that anyone coming from an Arduino or C background, for instance, will be able to pick up easily.

Writing Python Programs

Python programs are usually written in text files that carry a “.py” extension. Python comes in two versions which are Python 2, the legacy version of Python, and Python 3 which is current and well supported. For most purposes, we will focus on Python 3 since this is the version used in CircuitPython. Should at any point you feel the need to run any programs that are present in this chapter, you can use the Mu editor.

To do this, simply click the mode button as shown in Figure 4-1.
../images/511128_1_En_4_Chapter/511128_1_En_4_Fig1_HTML.jpg
Figure 4-1

Mode Button

After you have clicked this button, a window should appear; from the dialog, select the “Python 3” option pictured in Figure 4-2 to start a new Python program.
../images/511128_1_En_4_Chapter/511128_1_En_4_Fig2_HTML.jpg
Figure 4-2

Python 3 Option

Once it is selected, a window opens; we type our program into the text area and press the run button depicted in Figure 4-3.
../images/511128_1_En_4_Chapter/511128_1_En_4_Fig3_HTML.jpg
Figure 4-3

The Run Button

Our program will be run and look for the output in the console window located at the bottom of the IDE. After our program has finished, we can click the stop button as shown in Figure 4-4.
../images/511128_1_En_4_Chapter/511128_1_En_4_Fig4_HTML.jpg
Figure 4-4

The Stop Button

Now that you know how to run Python programs, we can look at using the Python language.

It is important to begin our discussion on Python programming by first looking at the typical structure of a Python program. Listing 4-1 shows an example of a basic Python program we will be using through this book. We use the import statement to bring modules in our programs so that we can use methods contained within them. We will also have a main loop called a super loop that runs indefinitely. The words after the hash symbol “#” are called comments. These are ignored by the Python interpreter but allow us to explain to ourselves and other programmers what our code is doing.
# import math modules
import math
# main super loop
while(True):
    # call method from our imported module
    print (math.sqrt(4))
Listing 4-1

Basic Python Program

In Python, we access methods which are blocks of code that only run when they are called by something called the dot notation. Our math module has a method called square root we would like to use, so we call the “math.sqrt” method. There is also a print statement. The print statement is used to output things to our display that we can use to get information from our program. This basic structure will be maintained for all Python programs, as you will see in later chapters going forward.

Whitespace

Something that should be addressed is that of whitespace in your Python programs. When we talk about whitespace, what we are really talking about are invisible characters such as tabs, blank space, newline characters, and the like.

Whitespace is ignored by some programming languages, but in Python whitespace plays a special role. Whitespace is used to structure your Python programs. While many programming languages use curly braces to indicate where blocks of code start and end, in Python whitespace is used to indicate blocks in the program. Pay attention to whitespace as it is particularly important in your Python code. The programs in this book are fairly short and don’t have much levels of indentation; however, you should still pay attention to the whitespace in your programs.

Comments

The comment is the text within your Python program that is there for the benefit of the programmer, as they are ignored by the interpreter. Good programming practice dictates that you include enough comments so that other programmers reading your code will be aware of what the program does. Comments will also remind you what your code did as you may have to update or maintain your code sometime in the future.

Though comments are necessary, it is important not to abuse comments and put too much. As in everything in life, it is important to have balance, so use comments, but don’t overuse them.

There are two ways we can write comments in Python. There is the single-line comment that occupies one line and is done by utilizing a hash symbol. Anything put after this symbol is ignored by the interpreter. This is done in Listing 4-2.
# a single line comment
Listing 4-2

Single-Line Comment

There are also comments that span multiple lines and are used for comment blocks. These use the comment contained within two sets of triple quotes. Listing 4-3 shows us what these multiline comments look like.
"""
a multiline block comment
That spans multiple lines
"""
Listing 4-3

Multiline Comment

Each comment type has their uses, and it is dependent on the code base you are maintaining or the team you are working with that will determine which comment style you will use.

Variables and Constants

When writing programs, we need some way to store information and retrieve it later. The way we do this is with variables. Variables allow us to assign a name to a memory location, store data at that location, and then retrieve it later. The names we assign to variables in Python must meet certain parameters. Python variables to be valid can be a combination of numbers and characters, also collectively called alphanumeric characters. What this means is that you can only use letters, numbers, and underscores when creating Python programs. Listing 4-4 shows examples of valid Python variable names.
Foo
dove
_topshot
RickyTicky99
Listing 4-4

Example Valid Python Variable Names

While it is valid to use numbers in a variable name, you cannot begin a variable name with a number. You also cannot have spaces in variable names, and you cannot use keywords (words reserved as part of the language) in variable names. Listing 4-5 shows us some invalid variable names.
20Foo
dove bird
$upermaniac
for
Listing 4-5

Example Invalid Python Variable Names

To ensure that you do not use any of the reserved keywords as variable names, Table 4-1 shows us which variable names we must not use, sorted in alphabetical order.
Table 4-1

Reserved Keywords in Python

and

elif

if

or

yield

as

else

import

pass

 

assert

except

in

raise

 

break

finally

is

return

 

class

False

lambda

true

 

continue

for

nonlocal

try

 

def

from

None

with

 

del

global

not

while

 

When variables cannot be changed during program execution, we call these variables constants. In Python, we usually declare variables by writing them in capital letters and placing them in a constants.py file.

Before we can use a variable in a program, we must declare it. Listing 4-6 shows us how to declare a variable.
# declaring a variable
myVar = None
Listing 4-6

Declaring a Variable

After we declare a variable, we can assign a value to it. The process of assigning a value to a variable is called initialization of the variable. Listing 4-7 demonstrates how we can initialize a variable.
# initializing a variable
myVar = 10
Listing 4-7

Initializing a Variable

As Listing 4-8 shows us, we can both declare and initialize a variable at the same time.
# declaring and initializing a variable
anotherVar = 10
Listing 4-8

Declaring and Initializing a Variable

Data Types

Variables can belong to one of several data types within the Python language. The type of a variable determines what type of data can be stored within the variable and how much memory it occupies. We don’t need to tell Python if a variable is an integer (a number) or a string (like words) as Python automatically handles these assignments. The four data types we use in our programs most often and their use are given in Table 4-2.
Table 4-2

Common Data Types

Data Type

Description

int (Int)

This is an integer or a number such as 10, 20, 100, 4000

float (Float)

This is a floating-point number or numbers with a decimal point, for example, 4.5, 60.9, 300.03, 1000.908

str (String)

A string is a set of characters between quotation marks (double or single), for example, “Andy” or ‘Maggie’

bool (Boolean)

A data type that can represent True or False

To see the type of your variable, simply use “type(variableName)” and you will see the type of your keyword.

Operators

Python provides facilities to perform many logical and mathematical operations. To accomplish this, Python has a lot of operators it can use. These operators may be arithmetic, relational, logical, bitwise, and assignment operators. Table 4-3 lists some common operators and provides an example of their usage. This table is by no means exhaustive, but it does give you a taste of what is available.
Table 4-3

Common Python Operators

Operator

Type

Description

Usage

+

Arithmetic

Adds two operands

X + Y

-

Arithmetic

Subtracts the second operand from the first

X - Y

*

Arithmetic

Multiplies both operands

X * Y

/

Arithmetic

Divides the numerator by the denominator

X / Y

%

Arithmetic

The modulo operator gives the remainder of a division operation

X % Y

**

Arithmetic

This is the exponent operator and performs power calculations

X**Y

==

Comparison

If the two operands are equal, then Python will evaluate the condition as true

A==B

!=

Comparison

If the two operands are not equal, then Python will evaluate the condition as true

A != B

>

Comparison

If the operand on the left is greater than the operand on the right, then the condition is true

A > B

<

Comparison

If the operand on the left is less than the operand on the right, then the condition is true

A < B

Lists

An important component of any programming language is the type of data structures it supports. Lists are one data structure that are fundamental to the Python programming language. Lists store a collection of items that are ordered, and the list can be changed. Listing 4-9 shows us a list in Python.
# python list
myList = ["boy", 15, 1.2]
Listing 4-9

Example List in Python

Items in a list in Python are assigned an index which starts at 0. We can get the index of a list by using the code in Listing 4-10.
# get index of list item
myList = ["red", "orange", "green"]
print(thislist[1])
Listing 4-10

Get Index of List Item

Keep this in mind that the elements in a list start at zero as we move forward.

Tuples

A list as we learned in the previous section can store a collection of data types. However, sometimes you need another way to structure your data. For such a scenario, we can use the tuple.

In Python, a tuple structure can be thought of as a list; however, we cannot change the elements contained within the tuple. Listing 4-11 shows us how we use tuples.
# tuple example
myTuple=("red", "orange", "green")
print(myTuple)
Listing 4-11

Python Tuple

We can access the index of items in a tuple just as we did with a list. Listing 4-12 shows how we can do this.
# access tuple item index
myTuple = ("red", "orange", "green")
print(myTuple[0])
Listing 4-12

Access Items of Tuple

If Statement

The if statement is used to make decisions in your program (see Listing 4-13). To do this, the statement checks a Boolean expression for truth. If the expression is true, the statement will execute.
if (x > y):
    doSomething()
Listing 4-13

if Statement

else Statement

The else statement is used to complement the if statement and create a decision block. The else statement executes when the Boolean statement within the if statement evaluates as false. Listing 4-14 shows us how the else statement would operate.
if (x > y):
   doSomething()
else:
  doSomethingElse()
Listing 4-14

else Statement

elif Statement

Many times, in our program, we may need to test more than just two conditionals in our decision block. For testing several conditionals, we must use the elif statement to test these multiple conditions. Listing 4-15 gives us an example of the else if statement.
if (x > y):
   doSomething()
elif (x == y):
  doSomethingElse()
else:
   doTheOtherThing()
Listing 4-15

else if Statement

short if

Sometimes, you can put your if statement code on one line if it is short enough and you only have one statement to execute as is shown in Listing 4-16.
# single line if statement
if x == y: print("its equal")
Listing 4-16

One-Line if

for Loop

Sometimes, we need to execute a block of code for a specified number of times. To aid with this, we use a for loop combined with a range function. Listing 4-17 gives an example of a for loop with a range function in action.
# print 0 to 9
for x in range(10):
  print(x)
Listing 4-17

for Loop

Remember that Python counts from 0, so when the preceding statement is run, it will print numbers from 0 to 9 in the console, not 10.

while Loop

While the for loop with a range function lets us run a block of code for a set number of times, sometimes we are not sure how many times we need to execute a block of code. In such a case, we use a while loop which executes providing the condition specified for the loop’s execution remains True this is the basis of many of the programs in this book. Listing 4-18 shows us what the while loop looks like.
while (True):
   runForever()
Listing 4-18

while Loop

The while loop is used in many embedded applications to keep a program running indefinitely, and when it does so, we call it a super loop.

Functions

Sometimes, within your Python programs, you may find yourself having to run the same block of code over and over. Instead of typing the same block of code multiple times, there is a feature in Python called a function that lets you call a block of code you have written and returns a value. These functions can take arguments on the input and then do something with them. If you need to return a value from a function, you would use the return statement.

For example, let's write a function that will take two variables and raise one to the power of the other and then call it three times to demonstrate how this works as shown in Listing 4-19.
def addVar(a, b):
     print (a**b)
addVar(3, 6)
addVar(2, 8)
addVar(1, 9)
Listing 4-19

Functions

Lambda Functions

Sometimes, within our programs, we can create what is known as a lambda function. Lambda functions allow us to write small functions that we don’t have to name. Listing 4-20 shows us how we can replace the preceding function with a small lambda function.
x = lambda a, b : a**b
print (x(2, 5))
Listing 4-20

Lambda Functions

Exception Handling

Sometimes, parts of our code do not work as intended, and though it may follow all the syntax rules of the program, the statement may still be invalid for execution by the Python interpreter. For example, if we try to print a variable that does not exist, though it is syntactically correct to try to print a variable with the print function, since the variable does not yet exist, we get an error. Instead of crashing the program when we “try” to execute the statement and it fails, we can do something else by placing the block of code under the except statement. Listing 4-21 shows us how exception handling works.
 try:
  print(undefVar)
except:
  print("Causes Exception")
Listing 4-21

Exception Handling

Object-Oriented Programming

Python is what is known as an object-oriented programming language. What this means is that we can create special bits of code that act as a blueprint by which we can create other code. We call this special blueprint code a class. The formal name for this blueprint is an object constructor, and we use it to create instances of the class. We can also have functions that can exist within a class, and when we do, they are called methods.

Within Python, there exists a special method within the class that is called every time we use it to create an object called the __init__() method. In Python, we can modify instances of the class before it has been called with “self”; using self, we can access attributes and methods of the Python class that will be done to the object once it is initialized.

An object is an instance of the class from which it gets its properties and is meant to model real-world things. Think about a car; two cars may have the same make and model but different colors. They are functionally the same except that the color attribute of them is different. In Python, it is the same way – sometimes, we need objects that are identical but need to modify one a little differently than the other; in such a case, we would create a class, then two instances of that class we can modify separately. Listing 4-22 shows us what a class in Python is like.
# create the car class
class AwesomeCar:
    # our special method that lets us
    # initialize attributes of the class
    def __init__(self, color):
        # these remain the same
        self.make = "Tayaba"
        self.model = "Nimbus"
        # the colors change
        self.color = color
# create instance of our car class
Car1 = AwesomeCar("Red")
# create another instance of our car class
Car2 = AwesomeCar("Blue")
# print car attributes
# prints {'make': 'Tayaba', 'model': 'Nimbus', 'color': 'Red'}
print(Car1.__dict__)
# print car attributes
# prints {'make': 'Tayaba', 'model': 'Nimbus', 'color': 'Blue'}
print(Car2.__dict__)
Listing 4-22

Python Class

We can print all the attributes of the class with the (__dict__) which is itself an attribute that objects have which contain all attributes defined for the object itself.

In Python, we will use many classes and their methods throughout this book; this little crash section in objects will be enough to take you through the rest of the book.

Random and Time

Sometimes, we need to generate random numbers, and for that reason, Python provides mechanisms for doing that with a module called the random module. We also have a module called the sleep module that allows our code to wait a certain amount of time. Listing 4-23 demonstrates how we can use these two modules together.
# our random module
import random
# the time module
import time
# super loop
while (True):
    # create a random number between 1 and 10
    x = random.randint(1, 10)
    # print the number
    print(x)
    # once per second
    time.sleep(1)
Listing 4-23

Using Random and Time

Python vs. CircuitPython

The most widely used distribution of Python is a variety we know as CPython. CPython is the “gold standard” implementation of the Python programming language because it is known as the reference implementation of the language. CircuitPython aims to be compliant with CPython; however, due to obvious reasons of lack of memory on the microcontrollers and for ease of use, some libraries that are available in CPython may not be available in CircuitPython. Most things from the core language do work however, and code written in CircuitPython will be valid in CPython but not necessarily the other way around. The core language however is there, and you can write a lot of amazing programs with CircuitPython.

How Does My Python Program Run?

If you are not familiar with microcontrollers and programming, you may be wondering how a Python program goes from your editor such as Mu into the microcontroller to be executed. So, in this section, I give a high-level overview of what happens when you run your Python program.

Python is what is known as an interpreted language, so what this means is that it takes each statement that is present in our source code and converts it into machine language our microcontroller can understand when the program is run. This is contrasted with a compiler that transforms code written into machine code before the program is run.

Python programs are run in three states which are
  • Initialization

  • Compilation

  • Execution

Before we begin looking at how our Python program is run, we must remember that the Python interpreter is written in C, and as such it is merely a program that is run in our C code. In the initial stage, when we write our program and load it into the C program, the program looks for the Py_main program which is the main high-level function within the main program. Other supporting functions that handle program initialization and the like are then called.

After this stage, we enter the compilation stage where things known as parse tree generation and abstract syntax tree (AST ) generation take place to help generate the bytecode. These bytecode instructions aren’t machine code; rather they are independent of the platform we are using. The bytecode is then optimized, and we get the object code we need to run. In CircuitPython, we have the option to make our code into bytecode before the program is run, and such files are given a “.mpy” extension. These files can be imported like regular files and are more compact, leading to more efficient memory usage.

Finally, our program is executed within the Python Virtual Machine (PVM). The virtual machine is a function within the interpreter program that runs these bytecode instructions. It’s just one big super loop that reads our bytecode instructions one by one and executes them.

Conclusion

In this chapter, we briefly looked at Python and some of the features of the language. Once you read this chapter, you should have a basic understanding of the Python programming language. Programming is something though that you learn over time, and as such it is important that we write code. Only by writing code will you learn the language you are using, and for that reason, in the next chapter, we will look at how we can use Python to control our microcontroller hardware.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.141.27.244