1. An Overview of Python Essentials
Chapter 1. An Overview of Python Essentials
Devops, the combination of software development with information technology operations, has been a hot field during the last decade.
Traditional boundaries between software development, deployment, maintenance, and quality assurance are broken, enabling more integrated
teams. Python has been a popular language both in traditional IT operations and in the DevOps due to its combination of flexibility, power, and
ease of use. The Python programming language was created in the early 1990s for use in system administration. It has been a great success in
this area and gained wide adoption. It is a general-purpose programming language used in just about every domain. Visual effects and the film
world is another prominent Python success story. More recently, it has become the defacto language in data science and machine learning. It has
been used across industries from avian to bioinformatics. Modern Python has an extensive arsenal of tools to cover the wide-ranging needs of its
users. Learning the whole Python Standard Library (the capabilities that come with any Python installation), would be a daunting task. If you
add to it learning all of the third party packages ( that enliven the Python ecosystem, it would be an immense undertaking. The good news is that
you don’t need to. You can become a powerful DevOps practitioner with only a small subset of Python.
In this chapter, we draw on our decades of Python DevOps experience to teach only the elements of the language that you need. These are the
parts of Python you use daily. They form the essential toolbox to get things done. Once you have these core concepts down, you can add more
complicated tools, and indeed this is touched in more advanced features in later chapters.
Installing and Running Python
If you want to try the code in this overview, you need version Python 3.7 or later installed (the latest release is 3.7.3 as of this writing), and
access to a shell. In Os X, Windows and most Linux distributions, you can open the terminal application to access a shell. To check the version
of Python you are using, open a shell and type python --version.
$ python --version
Python 3.7.3
Python installers can be downloaded directly from the Python.org website. Alternatively, you can use a package manager such as Apt, RPM,
MacPorts, Homebrew, Chocolatey, or many others.
The Python Shell
The simplest way to run Python is to use the built-in interactive interpreter. Just type python in a shell. You can then interactively run Python
statements. Type exit() to exit the shell.
$ python
Python 3.7.0 (default, Sep 23 2018, 09:47:03)
[Clang 9.0.0 (clang-900.0.38)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 1 + 2
3
>>> exit()
Python scripts
Python code runs from a file with the py extension.
# This is my first Python script
print("Hello world!")
To invoke the script, in a shell run python followed by the file name.
$ python hello.py
Hello world!
Python scripts are the way most production Python code runs.
IPython
Besides the built-in interactive shell, several third-party interactive shells run Python code. One of the most popular is IPython. IPython offers
introspection (the ability to dynamically get information about objects), syntax highlighting, special magic commands (which we touch on later
in this chapter), and many more features making it a pleasure to use for exploring Python. To install IPython, use the Python package manager,
1
1. An Overview of Python Essentials
pip, which is installed by the Python installer:
$ pip install ipython
Running is similar to running the built-in an interactive shell of the previous section:
$ ipython
Python 3.7.0 (default, Sep 23 2018, 09:47:03)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.5.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: print("Hello")
Hello
In [2]: exit()
Jupyter Notebooks
A spin-off from the iPython project, the Jupyter project allows documents containing text, code, and visualizations. These documents are a
powerful tool for combining running code, output, and formatted text. Jupyter enables the delivery of documentation along with the code. It has
achieved widespread popularity, especially in the data science world. To install and run Jupyter notebooks:
$ pip install jupyter
$ jupyter notebook
This command opens a web browser tab showing the current working directory. From here, you can open existing notebooks in the current
project or create new ones.
Procedural Programming
If you’ve been around programming at all, you’ve probably heard terms like Object Oriented Programming (OOPS) and Functional
Programming. These are different approaches to organizing programs. One of the most basic styles, Procedural Programming, is an excellent
place to start. Procedural programming is the issuing instructions to a computer in an ordered sequence:
>>> i = 3
>>> j = i +1
>>> i + j
7
We can see in this example, there are three statements, which execute in order from the first line to the last. Each statement uses the state
produced by the previous ones. In this case, the first statement assigns the value 3 to a variable named i. In the second statement, this variable’s
value is used to assign a value to a variable named j, and in the third statement, the values from both variables add together. Don’t worry about
the details of these statements yet, notice that they are executed in order and rely on the state left by the previous statements.
Variables
Variables are a name which points to some value. In the previous example, these variables are i and j . Variables in Python can assign to new
values:
>>> dog_name = 'spot'
>>> dog_name
'spot'
>>> dog_name = 'rex'
>>> dog_name
'rex'
>>> dog_name = 't-' + dog_name
>>> dog_name
't-rex'
>>>
Python variables use dynamic typing. In practice, this means reassigned to values of different types or classes:
>>> big = 'large'
2
1. An Overview of Python Essentials
>>> big
'large'
>>> big = 1000*1000
>>> big
1000000
>>> big = {}
>>> big
{}
>>>
Here the same variable is set to a string, a number, and a dictionary. Be aware that there is no restriction on the type of a variable’s value.
Basic Math
Basic math operations such as addition, subtraction, multiplication, and division can all be performed using built-in math operators:
>>> 1 + 1
2
>>> 3 - 4
–1
>>> 2*5
10
>>> 2/3
0.6666666666666666
Note that a // symbol is for integer division. The symbol ** creates an exponent, and % is the modulo operator:
>>> 5/2
2.5
>>> 5//2
2
>>> 3**2
9
>>> 5%2
1
Comments
Comments are text ignored by the Python interpreter. They are useful for documentation of code and can be mined by some services to provide
standalone documentation. Single line comments are delineated by prepending with #. A single line comment can start at the beginning of a line,
or any point following. Everything after the # is part of the comment until a new line break.
# This is a comment
1 + 1 # This comment follows a statement
Multi-line comments enclose themselves in blocks beginning and ending with either """ or '''.
"""
This statement is a block comment.
It can run for multiple lines
"""
'''
This statement is also a block comment
'''
Built-in Functions
Functions are statements grouped to be called as a unit. Generally, you give functions a name. You invoke a function by calling the function
name followed by parentheses. If the function takes arguments, the arguments appear within the parenthesis. Python has many built-in
functions. Two of the most widely used build-in functions are print and range.
3
1. An Overview of Python Essentials
Print
The print function produces output that a user of a program can view. It is less relevant in interactive environments but is a fundamental tool
when writing Python scripts. In the previous example, the argument to the print function is written as output when the script runs:
# This is my first Python script
print("Hello world!")
$ python hello.py
Hello world!
print can be used to see the value of a variable or to give feedback as to the state of a program. print generally outputs to standard out and
is visible as program output in a shell.
Range
Though range is a built-in function, it is technically not a function at all. It is a type representing a sequence of numbers. When calling the
range() constructor, an object representing a sequence of numbers is returned. Range objects count through a sequence of numbers. The
range function takes up to three integer arguments. If only one argument appears, then the sequence is represented by the numbers from zero
up to, but not including that number. If a second argument appears, it represents the starting point, rather than the default of starting from 0. The
third argument can be used to specify the step distance, and it defaults to 1.
>>> range(10)
range(0, 10)
>>> list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list(range(5, 10))
[5, 6, 7, 8, 9]
>>> list(range(5, 10, 3))
[5, 8]
>>>
range maintains a small memory footprint, even over extended sequences as it only stores the start, stop, and step values. The range function
can iterate through long sequences of numbers without performance constraints.
Execution Control
Python has many constructs to control the flow of statement execution. You can group statements you wish to run together as a block of code.
These blocks can be run multiple times using for and while loops, or only run under certain conditions using if statements, while loops, or
try-except blocks. Using these constructs is the first step to taking advantage of the power of programming. Different languages demarcate
blocks of code using different conventions. Many languages with syntax similar to the C language (a very influential language used in writing
Unix) use curly brackets around a group of statements to define a block. In Python, indentation is used to indicate a block. Statements that have
the same indentation are run together as a block.
Note
The Python interpreter does not care if you use tabs or spaces to indent, as long as you are consistent. The Python style guide, PEP-8, however,
recommends using four whitespaces for each level of indentation.
if/elif/else
if/elif/else statements are a common way to branch between decisions in code. A block directly after an if statement runs if that
statement evaluates to True:
>>> i = 45
>>> if i == 45:
... print("i is 45")
...
...
i is 45
4
1. An Overview of Python Essentials
>>>
Here we used the == operator which returns True if items are equal and False if not. This block can optionally follow an elif or else
statement with an accompanying block. In the case of an elif statement, this block only executes if the elif evaluated to True.
>>> i = 35
>>> if i == 45:
... print("i is 45")
... elif i == 35:
... print("i is 35")
...
...
i is 35
>>>
Multiple elif loops can append together. If you are familiar with switch statements in other languages, this simulates that same behavior of
choosing from multiple choices. Adding an else statement at the end runs a block if none of the other conditions evaluate as True:
>>> i = 0
>>> if i == 45:
... print("i is 45")
... elif i == 35:
... print("i is 35")
... elif i > 10:
... print("i is greater than 10")
... elif i%3 == 0:
... print("i is a multiple of 3")
... else:
... print("I don't know much about i...")
...
...
i is a multiple of 3
>>>
You can nest if statements, creating blocks containing if statements only execute if an outer if statement is True.
>>> cat = 'spot'
>>> if 's' in cat:
... print("Found an 's' in a cat")
... if cat == 'Sheba':
... print("I found Sheba")
... else:
... print("Some other cat")
... else:
... print(" a cat without 's'")
...
...
Found an 's' in a cat
Some other cat
>>>
For Loops
for loops allow you to repeat a block of statements (a code block) once for each member of a Sequence (ordered groups of items). As you
iterate through the sequence, the current item can be accessed by the code block. One of most common uses of for loops is to iterate through a
range object to do a task a set number of times.
>>> for i in range(10):
... x = i*2
... print(x)
...
...
0
2
5
1. An Overview of Python Essentials
4
6
8
10
12
14
16
18
>>>
In this example, our block of code is as follows:
... x = i*2
... print(x)
We repeat this code 10 times, each time assigning the variable i the next number in the sequence of integers 0-9. for loops can be used to
iterate through any of the Python Sequence types. You will see these later in this chapter.
continue
The continue statement skips a step in a loop, jumping to the next item in the sequence.
>>> for i in range(6):
... if i == 3:
... continue
... print(i)
...
...
0
1
2
4
5
>>>
While Loops
while loops repeat a block as long as a condition evaluates to True.
>>> count = 0
>>> while count < 3:
... print(f"The count is {count}")
... count += 1
...
...
The count is 0
The count is 1
The count is 2
>>>
It is essential to define a way for your loop to end. Otherwise, you will be stuck in the loop until your program crashes. One way to handle this is
to define your conditional statement such that it eventually evaluates to False. An alternative pattern uses the break statement to exit a loop
using a nested conditional.
>>> count = 0
>>> while True:
... print(f"The count is {count}")
... if count > 5:
... break
... count += 1
...
...
The count is 0
6
The count is 1
The count is 2
The count is 3
The count is 4
The count is 5
The count is 6
>>>
1. An Overview of Python Essentials
Handling Exceptions
Exceptions are a type of error causing your program to crash if not handled (caught). Catching them with a try-except block allows the
program to continue. These blocks are created by indenting the block in which the exception might be raised and putting a try statement before
it and an except statement after, followed by a code block which should run when the error occurs:
>>> thinkers = ['Plato', 'PlayDo', 'Gumby']
>>> while True:
... try:
... thinker = thinkers.pop()
... print(thinker)
... except IndexError as e:
... print("We tried to pop too many thinkers")
... print(e)
... break
...
...
...
Gumby
PlayDo
Plato
We tried to pop too many thinkers
pop from empty list
>>>
There are many built-in exceptions, such as IOError, KeyError, and ImportError. Many third-party packages also define their own
exception classes. They indicate that something has gone very wrong, so it pays only to catch them if you are confident that the problem should
not be fatal to your software. Ideally, you should catch the exact exception type (in our example this was the exception IndexError).
Built in Objects
In this overview, we will not be covering Object Oriented programming. The Python language, however, comes with quite a few built-in classes.
What is an object
In object-oriented programming (OOP), data or state and functionality appear together. The essential concepts to understand when working with
objects are class instantiation (creating objects from classes) and dot syntax (the syntax for accessing an object’s attributes and methods). A
class defines attributes and methods shared by its objects. Think of it as the technical drawing describing a car model. The class can then be
instantiated to create an instance. The instance, or object, is a single car built based on those drawings.
>>> class FancyCar():
... pass
...
>>> type(FancyCar)
>>> my_car = FancyCar()
>>> type(my_car)
You don’t need to worry about creating your own classes, understand that each object is an instantiation of a class.
Object Methods and Attributes
7
1. An Overview of Python Essentials
Objects store data in attributes. These attributes are variables attached to the object or object class. Objects define functionality in object
methods (methods defined for all objects in a class) and class methods (methods attached to a class, and shared by all objects in the class), which
are functions attached to the object.
Note
Functions and methods are technically the same thing. There is a convention, however, in Python circles to refer to functions attached to
Objects and classes as methods and refer to unattached methods as functions.
These functions have access to the object’s attributes and can modify and use the object’s data. To call an objects method or access one of its
attributes, we use dot syntax:
>>> class FancyCar():
... wheels = 4
... def driveFast(self):
... print("Driving so fast")
...
...
...
>>> my_car = FancyCar()
>>> my_car.wheels
4
>>> my_car.driveFast()
Driving so fast
>>>
So here our FancyCar class defines a method called driveFast and an attribute wheels. When you instantiate an instance name my_car,
you can access the attribute and invoke the method using the dot syntax.
Sequences
Sequences are a family of built-in types including the list, tuple, range, string, and binary types. Sequences represent ordered and finite
collections of items.
Sequence Operations
There are many operations which work across all of the types of sequences. We cover some of the most commonly used here.
You can use the in and not in operators to test if an item exists in a sequence:
>>> 2 in [1,2,3]
True
>>> 'a' not in 'cat'
False
>>> 10 in range(12)
True
>>> 10 not in range(2, 4)
True
You can use these to form conditional statements:
>>>
>>> name = 'spot'
>>> registered_names = ['jim', 'bill', 'mary', 'sue']
>>> if name not in registered_names:
... print(f"We must register {name}")
... registered_names.append(name)
...
...
You must register spot
>>>
You can reference the contents of a sequence by using its index number. To access the item at some index, use square brackets with the index
8