Problem Solving With Python Compress
Problem Solving With Python Compress
3.6 Edition
2
Preface 9
Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Supporting Materials . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Formatting Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Errata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1 Orientation 13
1.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
1.2 Why Python? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
1.3 The Anaconda Distribution of Python . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
1.4 Installing Anaconda on Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
1.5 Installing Anaconda on MacOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
1.6 Installing Anaconda on Linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
1.7 Installing Python from Python.org . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
1.8 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
1.9 Review Questions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
3
4 CONTENTS
4 Jupyter Notebooks 69
4.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
4.2 What is a Jupyter Notebook? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
4.3 Why Jupyter Notebooks? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
4.4 Installing Juypter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
4.5 Opening a Jupyter Notebook . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
4.6 The Jupyter Notebook Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
4.7 Magic Cells . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
4.8 Getting Help in a Jupyter Notebook . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
4.9 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
4.10 Review Questions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
8 Loops 211
8.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211
8.2 For Loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212
8.3 While Loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215
8.4 Break and Continue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
8.5 Flowcharts Describing Loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
6 CONTENTS
12 MicroPython 283
12.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283
CONTENTS 7
13 Appendix 313
13.1 Contents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313
13.2 Reserved and Keywords in Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314
13.3 ASCII Character Codes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315
13.4 Virtual Environments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317
13.5 NumPy Math Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320
13.6 Git and GitHub . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321
13.7 LaTeX Math . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323
13.8 Problem Solving with Python Book Construction . . . . . . . . . . . . . . . . . . . . . 324
13.9 Contributions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325
13.10Cover Artwork . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325
13.11About the Author . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326
8 CONTENTS
Preface
Motivation
The motivation for writing this book is that many undergraduate engineering students have to take
a programming course based on MATLAB. MATLAB is a great piece of software, but it currently
costs $49.00 for a student license and requires a site license to be used on school computers. Sub-
sequently, it is costly for a student to use MATLAB and it is costly for a college to support a course
that uses MATLAB. In addition, this site license expires eventually and students need to purchase
another copy often before they finish their degree.
The Python programming language, on the other hand, is open source and free. To download and
use Python, the cost to both the student and the college is zero (minus time spent). By moving
an undergraduate engineering programming class to Python, students will save money and have
greater access to the software they use in class. Further in their engineering education, students
can continue to use Python for free.
Acknowledgments
The creation of this book and supporting material would not be possible without the gracious
support of my wife and family. Students at Portland Community College continue to give me hope
that the next generation of engineers will be a diverse group of team problem solvers.
The Python Data Science Handbook and Machine Learning in Python as well as Reiman Equations in
Python served as inspiration and examples of using Jupyter notebooks to construct a book. The
bookbook repository on GitHub provided a starting point for the tooling used to convert this book
from Jupyter notebooks into a website and into LaTeX for printing.
Supporting Materials
Supporting materials for this text can be found on the textbook website:
https://problemsolvingwithpython.com
The textbook website contains all of the text in web format. Code examples and Jupyter notebooks
for the text can be found in the GitHub repository for the book:
9
10 CONTENTS
https:github.com/ProfessorKazarinoff/Problem-Solving-with-Python
Live notebooks, where code examples found in the text can be run without installing any software,
are available at:
https://mybinder.org/v2/gh/ProfessorKazarinoff/Problem-Solving-with-Python/
master
If you are an instructor and using this book in a course with students- please send me an email
using your school email address. In the email, include the course you are teaching and the term,
approximate enrollment, and a link to the course listing on your school website.
peter.kazarinoff@problemsolvingwithpython.com
I am happy to reply with a solution key for the end of chapter review problems as well as quiz and
exam question banks.
Formatting Conventions
This book and supporting materials use the following formatting conventions:
Web Address
Web address will be shown as:
https://github.com/professorkazarinoff/Problem-Solving-with-Python
There is a difference between local variables and global variables in Python code.
File Names
File Names are shown in bold and italic text
After completing the code, save the file as hello.py in the current directory.
NumPy and Matplotlib are two useful packages for problem solvers.
CONTENTS 11
Inline code
Inline code, including variable names, is shown in monospace font
To compare a variable use var == 'string' and make sure to include ==, the double
equals sign.
Terminal Commands
Commands typed into the MacOS or Linux terminal appear in separate sections which contain the
dollar symbol $ before each line. Note the dollar symbol $ should not be typed. The dollar symbol
is included to indicate a terminal prompt, not a character for the user to enter.
$ pip install pint
$ cd pint_srcipts
In [1]: A = 2
B = 3
C = A + B
print(C)
In order to delete a line use the [Backspace] key. To exit the shell type [shift]+[c]
Errata
Errata including any typos, code errors and formatting inconsistencies can be submitted to:
errata@problemsolvingwithpython.com
Please include the chapter number and section number in your email. Thank-you in advance for
helping improve this text for future readers.
Chapter 1
Orientation
1.1 Introduction
Welcome to the world of problem solving with Python! This first Orientation chapter will help you
get started by guiding you through the process of installing Python on your computer.
By the end of this chapter, you will be able to:
13
14 CHAPTER 1. ORIENTATION
You might be wondering “Why should I solve problems with Python?” There are other program-
ming languages in the world such as MATLAB, LabView, C++ and Java. What makes Python useful
for solving problems?
Python defines the types of objects you build into your code. Unlike some other languages such as
C, you do not need to declare the object type. The object type is also mutable, you can change the
type of object easily and on the fly. There is a wide array of object types built into Python. Objects
can change in size. Python objects can also contain mixed data types. Strings and floating point
numbers can be part of the same list.
Python has an extensive Standard Library. A huge number of object types, functions and methods
are available for use without importing any external modules. These include math functions, list
methods, and calls to a computer’s system. There is a lot that can be done with the Python Standard
Library. The first couple of chapters of this book will just use the standard library. It can do a lot.
Python has over 100,000 external packages available for download and use. They are easy to install
off of the Python Package Index, commonly called PyPI (“pie pee eye”). There is a Python package
for just about everything. There are packages which can help you: interact with the web, make
complex computations, calculate unit conversions, plot data, work with .csv, .xls, and .pdf files,
manipulate images and video, read data from sensors and test equipment, train machine learning
algorithms, design web apps, work with GIS data, work with astronautical data. There are and
many more Python packages added to PyPI every day. In this book, we will use some of the more
useful Python packages for problem solvers such as NumPy, Matplotlib, and SymPy.
One way Problem solvers code solutions faster in Python faster than coding solutions in other
programming languages is that Python is easy to learn and use. Python programs tend to be shorter
and quicker to write than a program which completes a similar function in another languages. In
the rapid design, prototype, test, iterate cycle programming solutions in Python can be written
and tested quickly. Python is also an easy language for fellow problem solvers on your team to
learn. Python’s language syntax is also quite human readable. While programmers can become
preoccupied with a program’s runtime, it is development time that takes the longest.
Python is transportable
Python can be installed and run on each of the three major operating systems: Windows, Mac and
Linux. On Mac and Linux Python comes installed out of the box. Just open up a terminal in on
a MacOS or Linux machine and type python. That’s it, you are now using Python. On Windows,
I recommend downloading and installing the Anaconda distribution of Python. The Anaconda
distribution of Python is free and can be installed on all three major operating systems.
1.3. THE ANACONDA DISTRIBUTION OF PYTHON 15
Python is free
Some computer languages used for problem solving such as MATLAB and LabView cost money to
download and install. Python is free to download and use. Python is also open source and indi-
viduals are free to modify, contribute to, and propose improvements to Python. All of the packages
available on the Python Package Index are free to download and install. Many more packages,
scripts and utilities can be found in open source code repositories on GitHub and BitBucket.
Python is growing
Python is growing in popularity. Python is particularly growing in the data sciences and in use
with GIS systems, physical modeling, machine learning and computer vision. These are growing
team problem-solving areas for engineers.
The Anaconda distribution of Python is advantageous because it includes Python as well as about
600 additional Python packages. These additional packages are all free to install. The packages that
come with Anaconda includes many of the most common Python packages use to solve problems.
16 CHAPTER 1. ORIENTATION
If you download Anaconda, you get Python including the Python Standard Library plus about 600
extra packages. If you download Python from Python.org, you just get Python and The Standard
Library but no additional modules. You could install the extra modules that come with Anaconda
(that don’t come with plain old Python), but why not save a step (or about 600 steps) and just install
Anaconda instead of installing about 600 different modules?
Even if you don’t have the ability to install programs on a computer, like a computer in a school
computer lab, you can still download and use Anaconda. The Anaconda distribution of Python
will also allow you to install additional modules from the Python package index (PyPI.org) and
conda-forge (conda-forge.org), the conda package index.
If you use MacOS, you probably already have Python installed on your computer. Most MacOS
installations come with Python included. The problem is that the version of Python that comes
with MacOS is old (usually legacy Python, Python 2) and the version of Python that comes with
MacOS is locked up behind a set of administrator privileges. Because the pre-installed version
of Python included with MacOS can require administrator privileges, you can have trouble with
installation and run-time problems. Some things will seem to work fine, and then other things
won’t run at all, or you will keep getting asked for an administrator password over and over.
Downloading and installing Anaconda (separate from the version of Python that came with Ma-
cOS) prevents most of the problems on MacOS caused by using the pre-installed version of Python.
Another advantage of Anaconda is that package management and virtual environments are a lot
easier when you have Anaconda. Virtual environments and package handling might not seem to
make a huge difference right now. If you just downloaded Anaconda for the first time, you are
probably not dealing with package management and virtual environments yet. (It’s OK if you
don’t even know what those two things are yet). After you write a couple of Python programs
and start downloading a couple of extra modules from PyPI or conda-forge, dealing with package
management and virtual environments becomes more critical.
For problem solvers, I recommend installing and using the Anaconda distribution of Python.
This section details the installation of the Anaconda distribution of Python on Windows 10. I think
the Anaconda distribution of Python is the best option for problem solvers who want to use Python.
Anaconda is free (although the download is large which can take time) and can be installed on
school or work computers where you don’t have administrator access or the ability to install new
programs. Anaconda comes bundled with about 600 packages pre-installed including NumPy,
Matplotlib and SymPy. These three packages are very useful for problem solvers and will be
discussed in subsequent chapters.
1.4. INSTALLING ANACONDA ON WINDOWS 17
Follow the steps below to install the Anaconda distribution of Python on Windows.
Steps:
1. Visit Anaconda.com/downloads
2. Select Windows
2. Select Windows
Figure 1.3. Anaconda downloads page. Select Python 3.6 version or higher. Python 2 is legacy
Python.
Figure 1.4. Part of Anaconda installation. You don’t have to enter your work email to proceed.
3. Download
Download the most recent Python 3 release. At the time of writing, the most recent release was the
Python 3.6 Version. Python 2.7 is legacy Python. For problem solvers, select the Python 3.6 version.
If you are unsure if your computer is running a 64-bit or 32-bit version of Windows, select 64-bit as
64-bit Windows is most common.
You may be prompted to enter your email. You can still download Anaconda if you click
[No Thanks] and don’t enter your Work Email address.
The download is quite large (over 500 MB) so it may take a while to for Anaconda to download.
Figure 1.5. Anaconda downloading.Note the file size and amount of time remaining
1.4. INSTALLING ANACONDA ON WINDOWS 19
Figure 1.6. Once the download is complete, open the .exe file
Figure 1.7. Welcome to Anaconda3 installation screen. Click next to proceed with the installation.
Once the download completes, open and run the .exe installer
At the beginning of the install, you need to click Next to confirm the installation.
Then agree to the license.
At the Advanced Installation Options screen, I recommend that you do not check “Add Anaconda
to my PATH environment variable”
After the installation of Anaconda is complete, you can go to the Windows start menu and select
the Anaconda Prompt.
This opens the Anaconda Prompt. Anaconda is the Python distribution and the Anaconda Prompt
20 CHAPTER 1. ORIENTATION
Figure 1.8. Anaconda End User License Agreement. Click I Agree to proceed
Figure 1.9. Anaconda installation options. When installing Anaconda on Windows, do not check
Add Anaconda to my PATH environment variable
1.4. INSTALLING ANACONDA ON WINDOWS 21
Figure 1.11. The Anaconda Prompt: What you see when you open the Anaconda Prompt. Note the
word “python” was typed at the > prompt
Figure 1.12. The Anaconda Prompt: The result of typing python is the Python REPL opens. Note
the >>> prompt which denotes the Python interpreter is running
is a command line shell (a program where you type in commands instead of using a mouse). The
black screen and text that makes up the Anaconda Prompt doesn’t look like much, but it is really
helpful for problem solvers using Python.
At the Anaconda prompt, type python and hit [Enter]. The python command starts the Python
interpreter, also called the Python REPL (for Read Evaluate Print Loop).
> python
Note the Python version. You should see something like Python 3.6.1. With the interpreter run-
ning, you will see a set of greater-than symbols >>> before the cursor.
Now you can type Python commands. Try typing import this. You should see the Zen of Python
by Tim Peters
To close the Python interpreter, type exit() at the prompt >>>. Note the double parenthesis at the
end of the exit() command. The () is needed to stop the Python interpreter and get back out to
the Anaconda Prompt.
To close the Anaconda Prompt, you can either close the window with the mouse, or type exit, no
parenthesis necessary.
When you want to use the Python interpreter again, just click the Windows Start button and select
the Anaconda Prompt and type python.
This section details the installation of the Anaconda Distribution of Python on MacOS. Most ver-
sions of MacOS come pre-installed with legacy Python (Version 2.7). You can confirm the legacy
version of Python is installed on MacOS by opening and running a command at the MacOS termi-
nal. To open the MacOS terminal use [command]+[Space Bar] and type terminal in the Spotlight
Search bar.
In the MacOS Terminal type (note: the dollar sign $ is used to indicate the terminal prompt. The
dollar sign $ does not need to be typed):
$ python
1.5. INSTALLING ANACONDA ON MACOS 23
Figure 1.13. Anaconda Prompt: Results of entering import this is The Zen of Python, by Tim Peters
You will most likely see Python version 2.7 is installed. An issue for MacOS users is that the in-
stalled system version of Python has a set of permissions that may always allow Python to run and
may not allow users to install external packages. Therefore, I recommend the Anaconda distribu-
tion of Python is installed alongside the system version of Python that comes pre-installed with
MacOS. You will be able to run Python code using the Anaconda distribution of Python, and you
will be able to install external packages using the Anaconda distribution of Python.
Follow the steps below to install the Anaconda distribution of Python on MacOS.
Steps:
1. Visit Anaconda.com/downloads
In the operating systems box, select [MacOS]. Then download the most recent Python 3 distribution
(at the time of this writing the most recent version is Python 3.6) graphical installer by clicking the
24 CHAPTER 1. ORIENTATION
Figure 1.14. Anaconda distribution of Python downloads page. Notice the macOS operating sys-
tem is selection. Download Python 3.6 verion or higher
Download link. Python 2.7 is legacy Python. For problem solvers, select the most recent Python 3
version.
You may be prompted to enter your email. You can still download Anaconda if you click
[No Thanks] or [x] and don’t enter your Work Email address.
Navigate to the Downloads folder and double-click the .pkg installer file you just downloaded. It
may be helpful to order the contents of the Downloads folder by date to find the .pkg file.
Follow the installation instructions. It is advised that you install Anaconda for the current user and
that Anaconda is added to your PATH.
Once Anaconda is installed, you need to load the changes to your PATH environment variable in the
current terminal session.
Open the MacOS Terminal and type:
$ cd ~
$ source . bashrc
Figure 1.15. Anaconda downloads page. You do not have to enter your Work Email
$ python
If you see the Zen of Python, the installation was successful. Exit out of the Python REPL using the
command exit(). Make sure to include the double parenthesis () after the exit command.
>>> exit ()
You will most likely see Python Version 2.7 is installed. If you enter:
$ python3
You will most likely see Python Version 3.6 is also installed. You can use the 3.6 Version of Python,
but each time a new package needs to be downloaded, the $ pip3 install command must be
used.
26 CHAPTER 1. ORIENTATION
Figure 1.16. Anaconda downloads page operating systems option. Notice Linux is selected
Install the Anaconda distribution of Python to follow the examples in the book without the need to
install additional third-party packages.
Steps:
1. Visit Anaconda.com/downloads
2. Select Linux
2. Select Linux
In the Python 3.6 Version* box, right-click on the [64-Bit(x86) Installer] link. Select [copy link
address].
Now that the bash installer (.sh file) link is stored on the clipboard, use wget to download the
installer script. In a terminal, cd into the home directory and make a new directory called tmp. cd
into tmp and use wget to download the installer. Although the installer is a bash script, it is still
quite large and the download will not be immediate (Note the link below includes <release>. the
specific release depends on when you download the installer).
1.6. INSTALLING ANACONDA ON LINUX 27
Figure 1.17. Anaconda installation on Linux, Copy the download link address.
$ cd ~
$ mkdir tmp
$ cd tmp
$ https :// repo . continuum . io / archive / Anaconda3 < release >. sh
Accept the Licence Agreement and allow Anaconda to be added to your PATH. By adding Anaconda
to your PATH, the Anaconda distribution of Python will be called when you type $ python in a
terminal.
Now that Anaconda3 is installed and Anaconda3 is added to our PATH, source the .bashrc file to
load the new PATH environment variable into the current terminal session. Note the .bashrc file is
in the home directory. You can see it with $ ls -a.
$ cd ~
$ source . bashrc
28 CHAPTER 1. ORIENTATION
Figure 1.18. Python.org downloads page showing download for Windows button
To verify the installation is complete, open Python from the command line:
$ python
If you see Python 3.6 from Anaconda listed, your installation is complete. To exit the Python REPL,
type:
>>> exit ()
Below is the recommended way to install a new version of Python from Python.org on each of the
three major operating systems: Windows, MacOS and Linux.
This book is based on Python version 3.6. Some of the examples in the book may not work properly
on legacy Python (version 2.7). I recommend installing the Anaconda Distribution of Python on
Windows and MacOSX. The installation of Anaconda on these operating systems was detailed in
previous sections.
Figure 1.19. Python.org downloads page showing download for MacOS link button
Open a terminal and enter $ python to see if a version of Python is already installed on the system.
$ python
Python 2.7.12 ( default , Dec 4 2017 , 14:50:18)
[ GCC 5.4.0 20160609] on linux2
Type " help " , " copyright " , " credits " or " license " for more information .
>>> exit ()
In the code block above, the version of Python is Python 2.7.12. If the Python version is 2.7 or
below, try the command $ python3.
$ python3
Python 3.6.7 ( default , Oct 22 2018 , 11:32:17)
[ GCC 8.2.0] on linux
Type " help " , " copyright " , " credits " or " license " for more information .
>>> exit ()
If no version of Python is shown, you can download a release of Python 3.6 from the deadsnakes
package repository.
$ sudo add - apt - repository ppa : deadsnakes / ppa
[ Enter ]
$ sudo apt - get update
$ sudo apt - get install python3 .6
30 CHAPTER 1. ORIENTATION
After installation, you may need to append your PATH environment variable to ensure the newly
installed Python 3.6 version is the version of Python called when using the terminal. The com-
mands below will add /usr/bin to your PATH, and add an alias in .bashrc so that the command
$ python3.6 produces the Python 3.6 REPL. Take care to ensure the double chevron >> is used, as
a single chevron > will overwrite the .bashrc file.
$ cd ~
$ echo " PATH =/ usr / bin : $PATH " >> ~/. bashrc
$ echo " alias python3 .6= '/ usr / bin / python3 .6 '" >> ~/. bashrc
$ source . bashrc
$ python3 .6
Python 3.6.6 ( default , Jun 28 2018 , 04:42:43)
[ GCC 5.4.0 20160609] on linux
Type " help " , " copyright " , " credits " or " license " for more information .
>>> exit ()
1.8. SUMMARY 31
1.8 Summary
In this chapter, you learned about the Anaconda distribution of Python and how the Anaconda
distribution of Python compares the version of Python at Python.org. The Anaconda distribu-
tion of Python comes with about 600 packages pre-installed as well as Jupyter notebooks and the
Anaconda Prompt. Jupyter notebooks and some of the pre-installed packages that come with Ana-
conda will be used later chapters. This text recommends that problem solvers install the Anaconda
distribution of Python.
This chapter showed how to install the Anaconda distribution of Python on Windows, MacOS, and
Linux.
At the end of the chapter, a description of how to download and install Python from Python.org
was shown.
Q01.01 What is Python? How is the Python language different than the Python Interpreter?
Q01.02 What is the difference between the version of Python at python.org and the version of
Python at Anaconda.com?
Q01.03 What are the advantages and disadvantages of using the Anaconda distribution of Python
compared to using the version of Python at python.org?
Q01.04 There are many different applications to edit Python code. Some examples include: Jupyter-
Lab, Sublime Text, Visual Studio Code, and PyCharm. Pick two Python code editors and explain a
feature of each code editor.
Q01.05 What are some advantages of Python compared to other computer programming lan-
guages?
Q01.06 What is PyPI? How many packages are currently available for download on PyPI?
Q01.07 Find three modules that are part of the Python Standard Library. Write a short description
of what each of the modules you choose is used for.
Q01.08 Which computer operating systems can Python be installed on?
Q01.09 How much does Python cost to download and install?
Q01.10 What are three subject areas that have seen a growth in the use of Python.
32 CHAPTER 1. ORIENTATION
Q01.11 Besides PyPI where else can problem solvers go to find Python packages, scripts, and utili-
ties?
Q01.12 Name three packages that come pre-installed with the Anaconda distribution of Python
Q01.13 How much does the Anaconda distribution of Python cost to download and install?
Q01.14 Which operating systems can the Anaconda distribution of Python be installed on?
Q01.15 What type of program is the Anaconda Prompt?
Q01.16 What is another name for the Python interpreter?
Q01.17 How can you bring up the Python interpreter (the Python REPL) using the Anaconda
Prompt?
Q01.18 What prompt is shown in the Python interpreter (the Python REPL)?
Q01.19 What command do you type to close the Python interpreter (the Python REPL)?
Q01.20 What are the first three lines in The Zen of Python by Tim Peters?
Q01.21 How do you open the Anaconda Prompt?
Q01.30 What web address do you go to download the Anaconda distribution of Python for MacOS?
Q01.31 What file extension does the installer for MacOS of the Anaconda distribution of Python
use?
Q01.32 When you install the Anaconda distribution of Python on MacOS, what is advised to do for
the installation options?
Q01.33 Why do you need to source the .bashrc file after you install the Anaconda distribution of
Python for MacOS?
Q01.34 How can you bring up the Python interpreter (the Python REPL) using the MacOS terminal?
Q01.35 Which version of Python is it advisable to download and install on MacOS?
Q01.36 Python can be installed on MacOS using a terminal program called Homebrew. What
command is issued to the MacOS terminal to install Python using Homebrew?
Q01.37 What version of Python comes pre-installed on MacOS?
Q01.45 How can you bring up the Python interpreter (the Python REPL) using a Linux terminal?
Q01.46 Which version of Python is it advisable to download and install on Linux?
Q01.47 What is a disadvantage of using the version of Python that comes pre-installed on Linux,
compared to using the Anaconda distribution of Python on Linux?
Q01.48 Before you install the Anaconda distribution of Python on Linux, what version of Python
are you most likely to see when you enter the command $ python in a Linux terminal?
Q01.49 Before you install the Anaconda distribution of Python on Linux, what version of Python
are you most likely to see when you enter the command $ python3 in a Linux terminal?
For each of the problems below, run the line of code. Copy the output, then suggest and run a line
of code that fixes the error.
Q01.91 Open the Python Interpreter (the Python REPL). Try to close the Python Interpreter with
the command:
>>> exit
Q02.92 Open the Python Interpreter (the Python REPL). Try to view The Zen of Python by Tim Peters
with the command:
>>> Zen of Python
Q01.93 Open the Anaconda Prompt. Try to open the Python Interpreter (the Python REPL) with
the command:
> python3
Q01.94 Open the Anaconda Prompt. Try to open the Python Interpreter (the Python REPL) with
the command:
> Python
Q02.95 Open the Python Interpreter (the Python REPL). Try to view The Zen of Python by Tim Peters
with the command:
>>> import this ()
34 CHAPTER 1. ORIENTATION
Chapter 2
2.1 Introduction
Welcome to the world of problem solving with Python! This first Orientation Chapter will help you
get started by guiding you through the process of installing Python on your computer.
By the end of this chapter, you will be able to:
35
36 CHAPTER 2. THE PYTHON REPL
Python can be used as a calculator to compute arithmetic operations like addition, subtraction,
multiplication and division. Python can also be used for trigonometric calculations and statistical
calculations.
Arithmetic
Python can be used as a calculator to make simple arithmetic calculations.
Simple arithmetic calculations can be completed at the Python Prompt, also called the Python REPL.
REPL stands for Read Evaluate Print Loop. The Python REPL shows three arrow symbols >>>
followed by a blinking cursor. Programmers type commands at the >>> prompt then hit [ENTER]
to see the results.
Commands typed into the Python REPL are read by the interpreter, results of running the com-
mands are evaluated, then printed to the command window. After the output is printed, the >>>
prompt appears on a new line. This process repeats over and over again in a continuous loop.
Try the following commands at the Python REPL:
Suppose the mass of a battery is 5 kg and the mass of the battery cables is 3 kg. What is the mass of
the battery cable assembly?
>>> 5 + 3
8
Suppose one of the cables above is removed and it has a mass of 1.5 kg. What is the mass of the
leftover assembly?
>>> 8 - 1.5
6.5
If the battery has a mass of 5000 g and a volume of 2500 cm3 What is the density of the battery? The
formula for density is below, where D is density, m is mass and v is volume.
m
D=
v
What is the total mass if we have 2 batteries, and each battery weighs 5 kg?
>>> 5 * 2
2.0
The length, width, and height of each battery is 3 cm. What is the area of the base of the battery?
To complete this problem, use the double asterisk symbol ** to raise a number to a power.
2.2. PYTHON AS A CALCULATOR 37
>>> 3 ** 2
9
What is the volume of the battery if each the length, width, and height of the battery are all 3 cm?
>>> 3 ** 3
27
Section Summary
This error results because we have not told Python to include the sin function. The sin function
is part of the Python Standard Library. The Python Standard Library comes with every Python
38 CHAPTER 2. THE PYTHON REPL
installation and includes many functions, but not all of these functions are available to us when we
start a new Python REPL session. To use Python’s sin function, first import the sin function from
the math module which is part of the Python Standard Library.
Importing modules and functions is easy. Use the following syntax:
from module import function
Success! Multiple modules can be imported at the same time. Say we want to use a bunch of
different trig functions to solve the following problem.
An angle has a value of π/6 radians. What is the sine, cos, and tangent of the angle?
To solve this problem we need to import the sin(), cos(), and tan() functions. It is also useful to
have the value of π, rather than having to write 3.14.... We can import all of these functions at
the same time using the syntax:
from module import function1 , function2 , function3
Section Summary
• log
• log10
• exp
• e
• pow(x,y)
• sqrt
A right triangle has side lengths 3 and 4. What is the length of the hypotenuse?
>>> sqrt (3**2 + 4**2)
5.0
The power function pow() works like the ** operator to raise a number to a power.
>>> 5**2
25
Section Summary
The following exponent and logarithm functions are part of Python’s math module:
Statistics
To round out this section, we will look at a couple of statistics functions. These functions are
part of the Python Standard Library, but not part of the math module. To access Python’s
statistics functions, we need to import them from the statistics module using the statement
from statistics import mean, median, mode, stdev. Then the functions mean, median, mode
and stdev(standard deviation) can be used.
>>> from statistics import mean , median , mode , stdev
Alternatively, we can import the entire statistics module using the statement import statistics.
Then to use the functions, we need to use the names statistics.mean, statistics.median,
statistics.mode, and statistics.stdev. See below:
>>> import statistics
Section Summary
2.3 Variables
Variables are assigned in Python using the = equals sign also called the assignment operator. The
statement:
a = 2
Note the assignment operator =(equals), is different from the logical comparison operator == (equiv-
alent to).
>>> a == 2
True
SQUARES = 4
3 newVariables = [1 , 2 , 3]
& sum = 4 + 4
Let’s solve the problem below at the Python REPL using variables.
42 CHAPTER 2. THE PYTHON REPL
Problem
n = nv e−Qv /( RT )
In Python, some operations we can do on strings include concatenation (combining strings), logical
comparisons (comparing strings) and indexing (pulling specific characters out of strings).
String Concatenation
Strings can be concatenated or combined using the + operator.
>>> word = " Solution "
>>> another_word = " another solution "
>>> third_word = " 3 rd solution ! "
>>> all_words = word + another_word + third_word
>>> all_words
' Solutionanother solution3rd solution ! '
To include spaces in the concatenated string, add a string which just contains one space " " in
between each string you combine.
>>> word = " Solution "
>>> another_word = " another solution "
>>> third_word = " 3 rd solution ! "
2.4. STRING OPERATIONS 43
String Comparison
Strings can be compared using the comparison operator; the double equals sign ==. Note the com-
parison operator (double equals ==) is not the same as the assignment operator, a single equals sign
=.
>>> name1 = ' Gabby '
>>> name2 = ' Gabby '
>>> name1 == name2
True
Capital letters and lower case letters are different characters in Python. A string with the same
letters, but different capitalization are not equivalent.
>>> name1 = ' Gabby '
>>> name2 = ' gabby '
>>> name1 == name2
False
String Indexing
String indexing is the process of pulling out specific characters from a string in a particular order.
In Python, strings are indexed using square brackets [ ]. An important point to remember: Python
counting starts at 0 and ends at n-1.
Consider the word below.
Solution
The letter S is at the zero index, the letter o is at the first index. The last letter of the word Solution
is n. n is in the seventh index. Even though the word Solution has eight letters, the last letter is in
the seventh index. This is because Python indexing at 0 and ends at n-1.
>>> word = ' Solution '
>>> word [0]
'S '
Negative Indexing
Placing a negative number inside of the square brackets pulls a character out of a string starting
from the end of the string.
>>> word [ -1]
'n '
String Slicing
A colon on the inside of the square brackets between two numbers indicates through. If the index
[0:3] is called, the characters at positions 0 through 3 are returned. Remember Python counting
starts at 0 and ends at n-1. So [0:3] indicates the first through third letters, which are indexes 0 to
2.
>>> word [0:3]
' Sol '
When three numbers are separated by two colons inside of square brackets, the numbers represent
start : stop : step. But remember that Python counting starts at 0 and ends at n-1.
>>> word [0:7:2] # start : stop : step
' Slto '
When two colons are used inside of square brackets, and less than three numbers are specified, the
missing numbers are set to their “defaults”. The default start is 0, the default stop is n-1, and the
default step is 1.
The two code lines below produce the same output since 0 is the default start and 7 (n-1) is the
default stop. Both lines of code use a step of 2.
>>> word [0:7:2]
' Slto '
The characters that make up a string can be reversed by using the default start and stop values and
specifying a step of -1.
>>> word [:: -1]
' noituloS '
Remember that strings must be enclosed by quotation marks. The following command produces
an error.
>>> print ( Gabby )
This error is corrected by surrounding the string Gabby with quotation marks.
>>> print ( " Gabby " )
Gabby
46 CHAPTER 2. THE PYTHON REPL
Expressions passed to the print() function are evaluated before they are printed out. For instance,
the sum of two numbers can be shown with the print() function.
>>> print (1+2)
3
If you want to see the text 1+2, you need to define "1+2" as a string and print out the string "1+2"
instead.
>>> print ( " 1+2 " )
1+2
The print() function also prints out individual expressions one after another with a space in be-
tween when the expressions are placed inside the print() function and separated by a comma.
>>> print ( " Name : " ," Gabby " ," Age " , 3+5)
Name : Gabby Age 8
2.6. SUMMARY 47
2.6 Summary
In this chapter, you learned how to use the Python REPL, also called the Python prompt, to solve
calculation problems. You learned how to do arithmetic, powers and logarithms, trigonometry
and save values to variables. Operations on strings were introduced including concatenation, com-
parison, indexing, and slicing. In the last section of the chapter, Python’s print() function was
introduced. As shown multiple times through this chapter, remember Python counting starts at 0
and ends at n-1.
Arithmetic
Trigonometry
Statistics
Arithmetic
1
Q02.01 2 + 2
Q02.02 4 × 2 + 2
4
Q02.03 5
2 ×3+4
Q02.04 42 +3
√
Q02.05 16
Q02.06 34 − 5
1+3+5
Q02.07 2+4+6
2.7. REVIEW QUESTIONS 49
Q02.08 1 − 2 + 9
6 −3+5
Q02.09 (3 + 5 − 2)2/3
5+3
Q02.10 2×5
√
Q02.11 62 + 4
Q02.12 1 + 9 × 8
42
+ 13−4 × 1
2.5
String Indexing
Q02.15 Write two lines of code that pulls out the first three letters of the word “Problem”
Q02.16 Write two lines of code that pulls out the last four letters of the word “Problem”
Q02.17 Write two lines of code that pulls out every other letter of the word “Problem” starting with
the letter “P”.
Q02.18 Write two lines of code that rewrites the word “Problem” backwards
Trigonometry
h = d tan(θ )
If a Forest Service ranger is 20 feet away from the base of a douglas fir tree and looks up at a 63
degree angle relative to straight ahead to see the top of the tree, what is the height of the douglas
fir tree?
Q02.35 The tangent of an angle is equal to the sine of the angle divided by the cosine of the angle.
Make two calculations, one for the tangent of -29 degrees and another calculation for the sine of -29
degrees divided by the cosine of -29 degrees. Do you observe the output of both calculations to be
the same?
Q02.36 A simple model of water level based on tides (assuming high tide is at midnight) is:
Where h is the water height and t is the number of hours since midnight. Using this model, calculate
the water level h at 6am (t = 6 hours since midnight).
Q02.37 The x-component of a force Fx is equal to the magnitude of the force |⃗F | multiplied by the
cosine of the angle θ of the force relative to the positive x-axis.
50 CHAPTER 2. THE PYTHON REPL
Fx = |⃗F | cos(θ )
If the magnitude of a force |⃗F | = 12.4 and the force acts at θ = 110 degrees relative to the positive
x-axis, what is the x-component of the force Fx ?
Q02.37 The distance d a free-thrown projectile travels is dependent on the projectile’s initial velocity
v0 , the acceleration due to gravity g = 9.81m/s2 and the angle θ at which the project is launched
according to:
v0 2
d= sin(2θ )
g
If a projectile is launched at a 12 degree angle with an initial velocity of 150 m/s, how far will the
projectile travel?
Q02.41 Show that the natural log of Euler’s number, ln(e), is equal to one.
Q02.42 Logarithms turn multiplication into addition. Complete both of the calculations below to
see if the expressions are equal to each other:
Q02.43 Logarithms turn exponents into multiplication. Complete both of the calculations below to
see if the expressions are equal.
log(6.02 × 1023 )
(23) log(6.02)
Q02.44 Python’s math module has the natural log (ln) function math.log() and the log (base 10)
function math.log10(). If you want to find the log with an arbitrary base, b, of a number n, you
can use a ratio of natural logarithms (log base e) according to:
ln(n)
logb (n) =
ln(b)
Q02.45 The magnitude of a vector |⃗v| is equal to the square root of the sum of the squares of the
vector’s components v x , vy , and vz according to:
2.7. REVIEW QUESTIONS 51
√
|⃗v| = v x 2 + vy 2 + vz 2
What is the magnitude of a vector ⃗v that has components v x = 76.3, vy = 70.9, vz = 93.6 ?
Q02.46 Moore’s Law, a relationship that states the number of transistors that fit on a microchip
doubles every two years can be modeled as:
Pn = P0 × 2n
Where P0 is the original number of transistors on a microchip and Pn is the number of transistors
on a microchip after n number of years since the original microchip. If the original microchip has
1000 transistors, how many transistors were projected to be on a microchip 40 years later?
Variables in Calculations
Q02.71 a = 2, b = 3, calculate 54 ( a2 − b3 )
Q02.72 The area of a circle, a, is dependent on the circle’s radius, r, according to a = πr2 . What is
the area of a circle with radius r = 4?
Q02.73 The area of a circle, a, is dependent on the circle’s diameter, d, according to a = π ( 2d )2 . What
is the area of a circle with diameter d = 6?
Q02.74 The volume of a sphere, v, is dependent on the sphere’s radius, r, according to v = ( 34 )πr3 .
What is the volume of a sphere with radius r = 1.5?
Q02.75 The volume of a cylinder, v, is dependent on the cylinder’s radius, r, and height, h, accord-
ing to v = πr2 h. What is the volume of a cylinder with radius r = 5 and height h = 10 ?
Q02.76 The surface area of a sphere, as is related to the sphere’s radius, r, according to as = 4πr2 .
What is the surface area as of a sphere with radius r = 2.5?
Q02.77 The general equation for the distance, d, that a free falling body travels (neglecting air
resistance) is d = 21 gt2 , where g is the acceleration due to gravity and t is the fall time. Assume the
acceleration due to gravity g = 9.81. How far (what distance) will a ball fall in time t = 12?
Q02.78 The general equation for the fall√ time, t, that a free falling body takes (neglecting air re-
d
sistance) to cover a distance, d is t = 0.5g , where g is the acceleration due to gravity. Assume
the acceleration due to gravity g = 9.81. How long (what time) will it take a base jumper to fall
distance d = 2000?
Q02.79 The value of an investment v compounded annually at an interest rate of r% after n years is
dependent on the original investment P according to:
v = P(1 + r/100)n
If P = 1000 dollars at a rate of r = 7%, what will the value v be after n = 20 years?
Q02.80 The original principal P needed to produce a total savings of value v at a rate of r% over n
years is calculated by:
v
P=
(1 + r/100)n
52 CHAPTER 2. THE PYTHON REPL
What is the principal P needed to save one million dollars at a rate r = 10% over n = 40 years?
Q02.81 Electrical power P is related to current I and resistance R according to P = I 2 R. An electrical
load with a resistance R = 10, 000 running at a current I = 0.200 draws how much power P ?
For each of the problems below, run the line of code. Then explain the error in your words. Give
an explanation more specific than invalid syntax. Then suggest and run a line of code that fixes
the error.
Q02.91
>>> 9 x 10
Q02.92
>>> 1 1/2 + 2 2/3
Q02.93
>>> 3 cos (35)
Q02.94
>>> 8.31 x 10^9
Q02.95
>>> (2+3)**(2 -3 e (4)
Q02.96
>>> 7% + 8% + 9%
Q02.97
>>> ( -)54.2 + 9.2
Q02.98
>>> '5 ' / '4 '
Q02.99
>>> ln ( e ) - log (10)
Chapter 3
3.1 Introduction
53
54 CHAPTER 3. DATA TYPES AND VARIABLES
Python has many built-in data types. These include integers, floats, booleans, strings, and lists.
By the end of this chapter you will be able to:
Python has many useful built-in data types. Python variables can store different types of data. A
variable’s data type is created dynamically, without the need to explicitly define a data type when
the variable is created.
It is useful for problem solvers to understand a couple of Python’s core data types in order to write
well-constructed code.
Remember from the previous chapter that variables in Python are defined with the assignment
operator, the equals sign =. Recall that to define a variable in Python, the variable name is written
first, then the assignment operator = followed by a value or expression.
The general syntax to assign a value to variable name is below:
variable_name = value
Integers
Integers are one of the Python data types. An integer is a whole number, negative, positive or
zero. In Python, integer variables are defined by simply assigning a whole number to a variable.
Python’s type() function can be used to determine the data type of a variable.
>>> a = 5
>>> type ( a )
< class ' int ' >
The output <class 'int'> indicates the variable a is an integer. Integers can be negative or zero.
>>> b = -2
>>> type ( b )
< class ' int ' >
>>> z = 0
>>> type ( z )
< class ' int ' >
56 CHAPTER 3. DATA TYPES AND VARIABLES
To define a variable as a float instead of an integer, even if the variable is assigned a whole number,
a trailing decimal point . is used. Note the difference when a decimal point . comes after a whole
number:
>>> g = 5
>>> type ( g )
< class ' int ' >
>>> g = 5.
>>> type ( g )
< class ' float ' >
Complex Numbers
Another useful numeric data type for problem solvers is the complex number data type. A complex
number is defined in Python using a real component + an imaginary component j. The letter j
must be used to denote the imaginary component. Using the letter i to define a complex number
in Python returns an error. Note how imaginary numbers add to integers and floats.
>>> comp = 4 + 2 j
>>> type ( comp )
< class ' complex ' >
>>> comp2 = 4 + 2 i
^
SyntaxError : invalid syntax
>>> intgr = 3
>>> type ( intgr )
< class ' int ' >
>>> b = False
>>> type ( b )
< class ' bool ' >
The output <class 'bool'> indicates the variable is a boolean data type.
Note that True and False must have an Upper Case first letter. Using a lowercase true returns an
error.
>>> c = true
Traceback ( most recent call last ):
File " < input > " , line 1 , in < module >
NameError : name ' true ' is not defined
>>> d = false
Traceback ( most recent call last ):
File " < input > " , line 1 , in < module >
NameError : name ' false ' is not defined
>>> pos_int = 1
>>> bool ( pos_int )
True
58 CHAPTER 3. DATA TYPES AND VARIABLES
Boolean Arithmetic
Boolean arithmetic is the arithmetic of true and false logic. A boolean or logical value can either be
True or False. Boolean values can be manipulated and combined with boolean operators. Boolean
operators include and, or, and not.
The common boolean operators in Python are below:
• or
• and
• not
• == (equivalent)
• != (not equivalent)
In the code section below, two variables are assigned the boolean values True and False. Then
these boolean values are combined and manipulated with boolean operators.
>>> A = True
>>> B = False
>>> A or B
True
>>> A and B
False
>>> not A
False
>>> not B
True
>>> A == B
False
>>> A != B
True
Boolean operators such as and, or, and not can be combined with parenthesis to make compound
boolean expressions.
>>> C = False
>>> A or ( C and B )
True
>>> ( A and B ) or C
False
A summary of boolean arithmetic and boolean operators is shown in the table below:
3.4. STRINGS 59
3.4 Strings
Another built-in Python data type is strings. Strings are sequences of letters, numbers, symbols,
and spaces. In Python, strings can be almost any length and can contain spaces. String variables
are assigned in Python using quotation marks ' ' or " ". In Python, strings can be defined by
single quotation marks ' ' or double quotation marks " ".
Python strings can contain blank spaces. A blank space is a valid character in Python string.
>>> string = 'z '
>>>> type ( string )
< class ' str ' >
Numbers as Strings
Numbers and decimals can be defined as strings too. If a decimal number is defined using quotes
' ', the number is saved as a string rather than as a float. Integers defined using quotes will
become strings as well if surrounded by quotes.
>>> num = ' 5.2 '
>>> type ( num )
< class ' str ' >
Note that a string which contains just one space (" ") is not empty. It contains the space character.
Therefore a string made up of just one space converts to True.
>>> space = " "
>>> bool ( space )
True
3.5 Lists
A list is a data structure in Python that can contain multiple elements of any of the other data type.
A list is defined with square brackets [ ] and commas , between elements.
>>> lst = [ 1 , 2 , 3 ]
>>> type ( lst )
list
Indexing Lists
Individual elements of a list can be accessed or indexed using bracket [ ] notation. Note that Python
lists start with the index zero, not the index 1. For example:
>>> lst = [ ' statics ' , ' strengths ' , ' dynamics ']
>>> lst [0]
' statics '
Remember! Python lists start indexing at [0] not at [1]. To call the elements in a list with 3 values
use: lst[0], lst[1], lst[2].
Colons : are used inside the square brackets to denote all
>>> lst = [2 , 4 , 6]
>>> lst [:]
[2 , 4 , 6]
Negative numbers can be used as indexes to call the last number of elements in the list
3.6. DICTIONARIES AND TUPLES 61
>>> lst = [2 , 4 , 6]
>>> lst [ -1]
6
The colon operator can also be used to denote all upto and from thru end.
>>> lst = [2 , 4 , 6]
>>> lst [:2]
[2 , 4]
lst = [2 , 4 , 6]
lst [2:]
[6]
The colon operator can also be used to denote start : end + 1. Note that the indexing here in not
inclusive. lst[1:3] will return the 2nd element, and 3rd element but not the fourth even though 3
is used in the index.
Remember! Python indexing is not inclusive. The last element called in an index will not be re-
turned.
Dictionaries
Dictionaries are made up of key: value pairs. In Python, lists are organized and accessed based on
position. Dictionaries in Python are organized and accessed using keys and values. The location of
a pair of keys and values stored in a Python dictionary is irrelevant.
Dictionaries are defined in Python with curly braces { }. Commas separate the key-value pairs
that make up the dictionary. Each key-value pair is related by a colon :.
Let’s store the ages of two people in a dictionary. The two people are Gabby and Maelle. Gabby is 8
and Maelle is 5. Note the name Gabby is a string and the age 8 is an integer.
>>> age_dict = { " Gabby " : 8 , " Maelle " : 5}
>>> type ( age_dict )
dict
The values stored in a dictionary are called and assigned using the following syntax:
dict_name [ key ] = value
We can add a new person to our age_dict with the following command:
>>> age_dict = { " Gabby " : 8 , " Maelle " : 5}
Dictionaries can be converted to lists by calling the .items(), .keys(), and .values() methods.
>>> age_dict = { " Gabby " : 8 , " Maelle " : 5}
Tuples
Tuples are immutable lists. Elements of a list can be modified, but elements in a tuple can only be
accessed, not modified. The name tuple does not mean that only two values can be stored in this
data structure.
Tuples are defined in Python by enclosing elements in parenthesis ( ) and separating elements
with commas. The command below creates a tuple containing the numbers 3, 4, and 5.
>>> t_var = (1 ,2 ,3)
>>> t_var
(1 , 2 , 3)
The elements of a tuple can not be modified. If you try to assign a new value to one of the elements
in a tuple, an error is returned.
>>> t_var = (3 ,4 ,5) # a tuple
>>> t_var [0]= 8
>>> t_var
TypeError : ' tuple ' object does not support item assignment
3.6. DICTIONARIES AND TUPLES 63
To create a tuple that just contains one numerical value, the number must be followed by a comma.
Without a comma, the variable is defined as a number.
>>> num = (5)
>>> type ( num )
int
When a comma is included after the number, the variable is defined as a tuple.
>>> t_var = (5 ,)
>>> type ( t_var )
tuple
64 CHAPTER 3. DATA TYPES AND VARIABLES
3.7 Summary
In this chapter, we reviewed a couple of different data types built-in to Python. These data types
include the numeric data types: integers, floats, and complex numbers. The string data type is
composed of letters, numbers, spaces, and punctuation. Python also has container data types which
can store many values. These container data types are lists, tuples, and dictionaries.
Python Functions
Function Description
type() outputs a variable or objects data type
len() return the length of a string
str() converts a float or int into a str (string)
int() converts a float or str into an int (integer)
float() converts an int or str into an float (floating point number)
3.8. REVIEW QUESTIONS 65
Booleans
Q03.20 Predict the output if the lines n=5 and (n<3) and (n<7) are run. Then run the the two lines
of code.
Q03.21 Predict the output if the lines ans='Yes' and ans=='Yes' or ans='No'are run. Then run
the the two lines of code.
66 CHAPTER 3. DATA TYPES AND VARIABLES
Q03.22 Pick a number n to make the following statement True: (2<n) or (n==2+n)Then run the
code to show your number works.
Q03.23 Pick a number n to make the following statement False: not (n<6) and (n<4) Then run
the code to show your number works.
Q03.24 Create the floating point number 0.001 × 10− 0.2 and assign it to the variable b.
Q03.25 Show that (n>5) and (n<=10) is equivalent to 5 < n <= 10 using the two different num-
bers for n.
Q03.26 Show that (n<5) or (n>=10) is equivalent to not(5 =< n < 10) using the two different
numbers for n.
Strings
Q03.30
Lists
Q03.40 Create a list that contains the numbers 1, 2.9 × 108 , and the word game.
Q03.41 Create a list that contains the words problem, solving, with, python.
Q03.42 Create a list with one value, the number 6. Convert the list to a boolean with the bool()
function.
Q03.43 Create an empty list. Convert the empty list to a boolean with the bool() function.
Q03.44 Create a list with the letters C, D, and R. Pull the letters C and D out of your list with
indexing.
Q03.45 Create a list with the numbers 1 to 10 (counting by ones). Use slicing to pull out the number
5 from the list.
Q03.46 Create a list with the numbers 1 to 10 (counting by ones). Use slicing to pull out all of the
numbers 5 or less using list slicing.
Q03.47 Create a list with the numbers 1 to 10 (counting by ones). Use slicing to pull out all of the
numbers 5 and greater using list slicing.
Q03.48 Create a list with the numbers 1 to 10 (counting by ones). Use slicing to pull out all of the
even numbers from the list.
Q03.49 Create a list with the numbers 1 to 10 (counting by ones). Use slicing to pull out every odd
number from the list.
Q03.50 Create a list with the numbers 1 to 10 (counting by ones). Use slicing to return the list in
reverse order (the returned list starts with 10 and ends with 1),
Dictionaries
Q03.60 Create a dictionary called capitals that contains the states and state capitals. Include
Washington, capital Olympia and Oregon, capital Salem.
Q03.61 Create a dictionary called capitals that contains the states and state capitals. Include
Washington, capital Olympia and Oregon, capital Salem. In the line after the dictionary is created
3.8. REVIEW QUESTIONS 67
Tuples
Use Python’s type() function to find the object type of each variable.
Q03.75 Create a tuple that returns True when converted to a boolean. Use the bool() function to
demonstrate your tuple converts to True.
Q03.76 Create a tuple that returns False when converted to a boolean. Use the bool() function to
demonstrate your tuple converts to False.
Q03.80 Run the following lines of code and explain the error in your own words, then write the
lines of code to run without an error:
n = 503
n [3]
68 CHAPTER 3. DATA TYPES AND VARIABLES
Q03.81 Run the following lines of code and explain the error in your own words, then write the
lines of code to run without an error:
a = 321
b = ' go ! '
c = a + b
Q03.82 Run the following lines of code and explain the error in your own words, then write the
lines of code to run without an error:
d = { one :1 , two :2 , three :3}
d [ one ]
Q03.83 Run the following lines of code and explain the error in your own words, then write the
lines of code to run without an error:
f = false
not f
Q03.84 Run the following lines of code and explain the error in your own words, then write the
lines of code to run without an error:
comp = 0.1 - 4.3 i
comp + 5
Q03.84 Run the following lines of code and explain the error in your own words, then write the
lines of code to run without an error:
empty = ' '
bool ( empty )
Q03.84 Run the following lines of code and explain the error in your own words, then write the
lines of code to run without an error:
lst = [1 ,3 ,5]
lst [1:3:2]
Q03.85 Run the following lines of code and explain the error in your own words, then write the
lines of code to run without an error:
dict = [ ' key ': 8 , ' pair ': 9]
dict [ ' key ']
Chapter 4
Jupyter Notebooks
4.1 Introduction
By the end of this chapter you will be able to:
69
70 CHAPTER 4. JUPYTER NOTEBOOKS
A Jupyter notebook is neither a simple text editor nor a full-featured IDE. Jupyter notebooks pro-
vide a quick and streamlined way for problem-solvers to prototype code and quickly share code.
Jupyter notebooks also provide a way for problem-solvers to share programming solutions with
team members, supervisors, and customers.
In a way, Jupyter notebooks strike a balance between simple text editors, which are fast to start
4.4. INSTALLING JUYPTER 71
and simple and easy to manipulate, and IDE’s which tend to start slower and be feature-rich and
complex. Simple text editors typically can only edit code, and cannot run the code. A full IDE can
edit code, run the code, debug code, provide syntax highlighting and context help.
In the context of problem-solving, Jupyter notebooks can be quite handy. Jupyter notebooks are
quick to open and quick to produce output. Data exploration, data cleaning, and plot building are
accomplished in Jupyter notebooks easier and quicker than in a text editor or an IDE.
In the context of sharing solutions to problems, Jupyter notebooks are also useful. Markdown cells
render text in different sizes, bold and italic. Tables and images, plots and code can all be shown
together in the same Jupyter notebook. Notebooks can be exported to a variety of formats including
.html and .pdf .
The simplest way to install Jupyter notebooks is to download and install the Anaconda distribution
of Python. The Anaconda distribution of Python comes with Jupyter notebook included and no
further installation steps are necessary.
Below are additional methods to install Jupyter notebooks if you are not using the Anaconda dis-
tribution of Python.
Type y for yes when prompted. Once Jupyter is installed, type the command below into the Ana-
conda Prompt to open the Jupyter notebook file browser and start using Jupyter notebooks.
> jupyter notebook
After homebrew installs a non-system version of Python, pip can be used to install Jupyter.
$ pip install jupyter
Figure 4.2. Windows 10 Start Menu showing the Jupyter Notebook application
• Anaconda Prompt
• Anaconda Navigator
Figure 4.3. Jupyter Notebook file browser. Notice a new Python 3 notebook is selected
Then click the run button in the middle of the menu at the top of the notebook.
This command starts the Jupyter notebook server. The output in the Anaconda Prompt will look
something like the output shown below:
Copy / paste this URL into your browser when you connect ...
A web browser should open, and you should be able to see the Jupyter file browser. If a web
browser doesn’t open automatically, you can copy the web address from the Anaconda Prompt
and paste it into a web browser’s address bar.
4.5. OPENING A JUPYTER NOTEBOOK 75
Figure 4.6. Windows 10 Start Menu showing the Anaconda Prompt application
Figure 4.8. Jupyter Notebook file browser: create new Python 3 notebook
One additional way to open a Jupyter notebook is to use Anaconda Navigator. Anaconda Nav-
igator comes with the Anaconda distribution of Python. Open Anaconda Navigator using the
Windows start menu and select [Anaconda3(64-bit)] –> [Anaconda Navigator].
An Anaconda Navigator window will open. In the middle of the page, in the Jupyter notebook
tile, click [Launch]
A Jupyter file browser will open in a web browser tab.
In the upper right select [New] –> [Python 3]
A new notebook will open as a new tab in your web browser.
When a new Jupyter notebook opens, you will see the Jupyter notebook interface. Across the top
of the notebook you see the Jupyter icon and the Notebook name. You can click on the notebook
name field and change the name of the notebook. Note that the file extension .ipynb is not printed
in the file name field, but if you look in the Home tab, you will see that the notebook is saved with
the .ipynb extension.
A Jupyter notebook is comprised of a bunch of cells which are arrayed one after another in boxes
below the menu items and buttons. There are three main types of cells: code cells, output cells, and
markdown cells.
78 CHAPTER 4. JUPYTER NOTEBOOKS
Code Cells
In code cells, you can write Python code, then execute the Python code and see the resulting output.
An example of a code cell is shown below.
You can tell you are typing in a code cell because In [ ]: is shown to the left of the cell and the
cell-type drop-down menu shows Code.
To run the Python code in a code cell push the [Run] button or type [Shift]+[Enter]. Hitting [Enter]
when the cursor is inside a code cell brings the cursor down to a new line.
Output Cells
After a code cell is run, an output cell can be produced below the code cell. The output cell contains
the output from the code cell above it. Not all code produces output, so not all code cells produce
output cells. The results in output cells can’t be edited. If a code cell produces plots, charts or
images, these outputs are shown in output cells.
You can clear all the output cells and re-run code cells by selecting [Kernal] –> [Restart Kernal and
Clear Output].
Markdown Cells
Markdown cells don’t contain Python code. Markdown cells contain text written in Markdown
format. Text in markdown cells can be formatted to show bold or italic text. Tables, images, and
lists can also be included in markdown cells.
Markdown cells are used for documentation and explaining your code. The text in a markdown
4.6. THE JUPYTER NOTEBOOK INTERFACE 79
Figure 4.10. Windows 10 Start Menu showing the Anaconda Navigator application
Figure 4.12. Jupyter Notebook file browser - create new Python 3 notebook
cell is not executed. Markdown cells can be formatted with a few special characters.
Markdown cells are run like code cells. The difference is that when markdown cells are run, the
text is formatted (when code cells run, code is executed). Markdown cells are run by clicking the
[Run] button or by pressing [Shift] + [Enter]
Text in markdown cells can be formatted using markdown syntax. An example of markdown syntax
is putting an underscore before and after a word to cause the word to be formatted in italics.
Headings
Headings are created in markdown cells using the hash symbol #. One # is the largest heading.
Four hashes #### is the smallest heading.
# H1 Heading
## H2 Heading
### H3 Heading
#### H4 Heading
Code Blocks
Code blocks can be inserted in Jupyter notebook markdown cells. For inline code blocks use the ‘
left quote character, the character to the left of the number [1]``` and above ```[Tab] on most
keyboards.
This is inline code: ‘ ‘ ‘ Inline code block ‘ ‘ ‘ within a paragraph
For a separated code block use three ‘ left quote characters on one line, followed by the code block
on separate lines. Terminate the separate code block with a line of three ‘ left quote characters.
“‘
Separated code block
4.6. THE JUPYTER NOTEBOOK INTERFACE 83
“‘
Bold and italic font is displayed by surrounding text with a double asterisk for **bold** and a
single underscore for _italics_
**bold** produces bold
_italics_ produces italics
**_bold and italic_** produces bold and italic
Tables
Tables are displayed using the pipe | character, which is [Shift]+[\] on most keyboards. Columns
are separated by pipes | and rows are separated by lines. After the header row, a row of pipes and
dashes --- are needed to define the table.
| header1 | header 2 | header 3 |
| --- | --- | --- |
| col 1 | col 2 | col 3 |
| col 1 | col 2 | col 3 |
produces:
produces
• item 1
• item 2
Numbered lists are produced using sequential numbers followed by a dot. Indent sub-items with
two spaces.
1. First item
2. Second item
3. Third item
1. sub item
84 CHAPTER 4. JUPYTER NOTEBOOKS
2. sub item
1. sub - sub item
2. sub - sub item
produces
1. First item
2. Second item
3. Third item
4. sub item
5. sub item
1. sub-sub item
2. sub-sub item
Horizontal Rule
***
produces
Links
Hyperlinks are specified using a set of square brackets [ ] followed by a pair of parenthesis ( )
The text inside the square brackets will be the link, the link address goes in the parenthesis.
produces
Python.org
Images
Images are embedded in Jupyter Notebook markdown using the exclamation point and square
brackets ![ ], followed by the image file path in parenthesis ( ). If the image can not be displayed,
the text in square brackets will be shown. The image can be in the same directory as the notebook,
or a relative path can be specified. In this case, the image engineering.png is stored in the images
directory, which is a subdirectory of the directory the notebook is saved in.
produces
4.6. THE JUPYTER NOTEBOOK INTERFACE 85
LaTeX Math
LaTeX Math equations and symbols are rendered by markdown cells. A more extensive list of
LaTeX commands can be found in the appendix.
$$ \ int_ { a }^{ b } \ frac {1}{ x ^2} dx $$
produces
∫ b
1
dx
a x2
html
Because Jupyter notebooks are rendered by web browsers, just about any HTML tag can be in-
cluded in the markdown portion of a notebook. An example of an HTML tag is the <sup> </sup>
tags that surround superscript text.
x < sup >2 </ sup >
produces
x2
Text can be colored using html <font> </font> tags
< font color = red > Red Text </ font >
produces
86 CHAPTER 4. JUPYTER NOTEBOOKS
Red Text
warning boxes
bootstrap style warning boxes can be included in Jupyter notebook markdown using <div> tags
< div class =" alert alert - danger " role =" alert " >
< strong > Warning ! </ strong > Python lists start at 0
</ div >
produces
Warning! Python lists start at 0
When a Notebook is saved as a .py file, all text in markdown cells is converted to comments, and
any code cells stay intact as Python code.
%matplotlib inline
%matplotlib inline
One of the most popular magic commands is:
% matplotlib inline
Entering the %matplotlib inline command at the top of a Jupyter notebook renders Matplotlib
plots in cells of the notebook. Without %matplotlib inline, plots may jump out as external win-
dows. A typical start to a Jupyter notebook using Matplotlib might start as:
4.7. MAGIC CELLS 91
import numpy as np
import pandas as pd
import matplotlib . pyplot as plt
% matplotlib inline
%load
The %load command loads a Python module, webpage or file into a Jupyter notebook. If there is a
file called hello.py in the same directory as the notebook with some Python code written in it, we
can load that same code into a Jupyter notebook code cell with the %load command.
Within a Jupyter notebook code cell type the command:
% load hello . py
The result is the code from the file hello.py is copied into the current notebook.
%run
If the %run magic command followed by the name of a valid Python file, the Python file runs as a
script. Suppose the file hello.py is created in the same directory as the running Jupyter notebook.
The directory structure will look something like this:
| folder
- - -| notebook . ipynb
- - -| hello . py
print ( ' This code was run from a separate Python file ')
print ( ' Hello from the file hello . py ')
Within our Jupyter notebook, if we %run this file, we get the output of the hello.py script in a Jupyter
notebook output cell.
You can list all of the available magic commands by typing and running %lsmagic in a Jupyter
notebook code cell:
% lsmagic
The output shows all the available line magic commands that begin with the percent sign %.
Available line magics :
% alias % alias_magic % autocall % automagic % autosave ...
% dhist % dirs % doctest_mode % ed % edit % env % gui ...
dir % more % mv % notebook % page % pastebin % pdb % pdef ...
...
Out[1]: ['__all__',
'__builtins__',
'__cached__',
'__doc__',
'__file__',
4.8. GETTING HELP IN A JUPYTER NOTEBOOK 93
'__loader__',
'__name__',
'__package__',
'__spec__',
'_glob0',
'_glob1',
'_glob2',
'_iglob',
'_ishidden',
'_isrecursive',
'_iterdir',
'_rlistdir',
'escape',
'fnmatch',
'glob',
'glob0',
'glob1',
'has_magic',
'iglob',
'magic_check',
'magic_check_bytes',
'os',
're']
sin(...)
sin(x)
94 CHAPTER 4. JUPYTER NOTEBOOKS
After importing a module, you can view help on the imported module by typing the module name
followed by a question mark ?
You can view the source code where a particular function is defined using a double question mark
??
Help online
Help is also available online at in the offical Jupyter documentation:
http://jupyter.readthedocs.io/en/latest/
You can always try to find help by typing something into Google. The site Stack Overflow is
devoted to programming questions and answers. The highest rated answers on Stack Overflow
are at the top of each question page.
96 CHAPTER 4. JUPYTER NOTEBOOKS
4.9 Summary
In this chapter, you learned about Jupyter notebooks. You learned what a Jupyter notebook is and
why Jupyter notebooks are useful for problem solvers. This chapter showed how to install Jupyter
notebooks on Windows, MacOS, and Linux. Some specific operations with Jupiter notebooks were
introduced:
You also learned about special “magic” commands that can be used in a Jupyter notebook. The final
section of the chapter detailed a couple of ways to get help when working with Jupyter notebooks.
Command Description
%matplotlib inline Display plots in output cells
%run file.py Runs file.py and displays output
%pwd Prints the working directory file path
%ls List contents of the current working directory
%precision sets float point precision for pretty printing
%whos lists variables and types in the running kernel session
function? Display help on a function
function?? Display source code of a function
4.10. REVIEW QUESTIONS 97
Q04.01 Run the following code in two different Jupyter notebook cells. Run one cell as a code cell.
Run the other cell as a Markdown cell. Why is the output different?
# Problem Solving with Python
Q04.02 Run the following code in two different Jupyter notebook cells. Run one cell as a code cell.
Run the other cell as a Markdown cell. Why is the output different?
print ( ' Problem Solving with Python ')
Markdown cells
Q04.10 Recreate the following headings in one Jupyter notebook markdown cell:
# BIG heading
## Big heading
Q04.11 Recreate the following table in one Jupyter notebook markdown cell:
Q04.12 Recreate the following code block in one Jupyter notebook markdown cell:
import numpy as np
import matplotlib . pyplot as plt
% matplotlib inline
Q04.12 Recreate the following bullet points in one Jupyter notebook markdown cell:
Q04.13 Recreate the following list in one Jupyter notebook markdown cell:
2. Write code
3. Restart Kernel & run all
4. Download notebook
Q04.14 Recreate two horizontal rules in a Jupyter notebook markdown cell. In between the hori-
zontal rules write the text In between the lines like below:
LaTeX Math
Q04.20 Write the Pythagorean Theorem in a Jupyter notebook markdown cell using LaTeX math.
a2 + b2 = c2
Q04.20 Write the formula for the area of a circle in a Jupyter notebook markdown cell using LaTeX
math.
A = πr2
Q04.20 Write the formula below in a Jupyter notebook Markdown cell using LaTeX math.
∫ 1
1
dy
0 y3
Code cells
Q04.34 Run the following in a Jupyter notebook code cell. Move the slider back and forth:
from ipywidgets import interact
import ipywidgets as widgets
def func ( x ):
return x
Cell Magic
Q04.50 Create a file called hello.py in the same directory as your Jupyter notebook. Inside the file
hello.py write the code below:
# hello . py
Use the Jupyter notebook magic command %load to load the code from hello.py into your Jupyter
notebook.
Q04.51 Create a file called hello.py in the same directory as your Jupyter notebook. Inside the file
hello.py write the code below:
# hello . py
Use the Jupyter notebook magic command %run to run the code from hello.py into your Jupyter
notebook.
Q04.52 Run the code below in a Jupyter notebook code cell:
import os
% pwd
Getting Help
Q04.60 Use Python’s dir() function in a Jupyter notebook code cell to find all the functions avail-
able in Python’s math module. Remember to import math at the start of the code cell.
Q04.61 In a Jupyter notebook code cell, import math and run math.sqrt?. Copy the contents of
the help you receive in a Jupyter notebook markdown cell.
Q04.61 In a Jupyter notebook code cell, import statistics and run statistics.mode?. Copy the
examples from the help you receive in a Jupyter notebook code cell. Run the code cell.
100 CHAPTER 4. JUPYTER NOTEBOOKS
Chapter 5
5.1 Introduction
By the end of this chapter you will be able to:
101
102 CHAPTER 5. FUNCTIONS AND MODULES
Every function has a name. The function name is used when the function is called in a program.
Calling a function means running a function.
Functions can receive input from the program. The input provided to a function is called input
arguments or just arguments. Arguments are the code passed to a function as input.
Functions can produce output. We say a function returns output to the program. The output of a
function can be assigned to a variable for use in a program.
Below is an example of calling the pow() a function in Python:
In the function call above, the function name is pow. pow is the power function. The pow function
raises a number to a power. The input arguments are the numbers 3 and 2. The function output
is assigned to the variable out. In this example, the function returns the value 9 (3 raised to the 2
power, 32 = 9).
The keyword def needs to be the start of the line that declares the function. Def stands for definition
and indicates to the Python interpreter that a function definition will follow.
function_name
5.3. FIRST FUNCTION 103
Each function needs a name. The function name should start with a letter and is typically all
lowercase (in Python names that start with Uppercase are usually used to define Classes). Function
names need to start with a letter and can only contain letters, numbers and the underscore character.
Just about any name will do, but it is best to avoid using any Python keywords such as def, class,
if, else, for. A complete list of reserved Python keywords is in the index.
( argument ):
Function names are followed by a set of parenthesis ( ). Many functions have code, called argu-
ments in between the parenthesis. The name used for the function argument(s) should be used in
the body of the function. After the function name, parenthesis, and arguments comes a : colon. In
Python, a colon is required to end the first line of all functions.
A colon : is required at the end of the first line of every function. If the : is not present the code will
not run.
< code >
The body of the function contains the code that will run when the function is called. Any variables
declared by the function arguments can be used in the body of the function. Any variables used
in the body of the function are local variables. Local variables cannot be called or accessed by other
scripts.
return
The return keyword is often the last line of a function. return indicates that whatever expression
that follows will be the output of the function. The return keyword is not a function or a method,
and parenthesis are not used after return, just a space.
output
Whatever expression is included after return will be returned by the function. The output expres-
sion after return can be a single variable, value or be a complex expression that includes multiple
variables.
Let’s write a simple function which adds two to any number. We will call our function plustwo.
Our function has one input argument, a number. The function will return that number plus 2.
Let’s apply this description to our four criteria:
The code section above includes the keyword def, a space and then the function name plustwo.
The input argument, n, is enclosed in parenthesis ( ) after the function name. After the set of
parenthesis is a colon :. The body of the function includes the code out = n + 2. The last line of
the function includes the keyword return followed by a space and the variable out.
Let’s run our plustwo() function and see the output.
In [2]: plustwo(3)
Out[2]: 5
Out[3]: 12
A function that calculates the area of a triangle given the base and height of the triangle would
accept two arguments base and height. The formula for the area A of a triangle given base b and
height h is below.
1
A= b×h
2
5.5. FUNCTIONS WITH DEFAULT ARGUMENTS 105
Let’s name our function triarea and accept base and height as input arguments. The triarea
function will return a number, the area of a triangle.
We can test our triarea() function with a couple of sets of input arguments.
In [2]: triarea(10,5)
Out[2]: 25.0
In [3]: A = triarea(1,4)
A
Out[3]: 2.0
Note that if only one input argument is supplied to the triarea() function, an error is returned:
In [4]: triarea(2)
------------------------------------------------------------------------
<ipython-input-4-ddd55ccdd949> in <module>
----> 1 triarea(2)
An example a function with default arguments is a function that calculates the distance an object
falls based on time. The general formula for fall distance d based on fall time t can be modeled as:
106 CHAPTER 5. FUNCTIONS AND MODULES
1 2
d= gt
2
Where g is the acceleration due to gravity. On earth the value of g = 9.81m/s2 . But on the moon,
g = 1.625m/s2 . Our falldist() function will include the default value for earth’s gravity and give
programmers the option of specifying a different value for g if they choose.
On earth, the distance a ball that falls for three seconds is calculated by falldist(3). In the func-
tion call falldist(3), no value is specified for g, so the default value 9.81 is used.
In [2]: falldist(3)
Out[2]: 44.145
Out[4]: 7.3125
def plustwo ( n ):
out = n + 2
return out
5.6. CALLING FUNCTIONS FROM OTHER FILES 107
This file, myfunctions.py can be imported into another script (another .py file), or Jupyter Note-
book.
Remember the file that contains the function definitions and the file calling the functions must
be in the same directory.
To use the functions written in one file inside another file include the import line,
from filename import function_name. Note that although the file name must contain a .py ex-
tension, .py is not used as part of the filename during import.
The general syntax to import and call a function from a separate file is below:
from function_file import function_name
function_name ( arguments )
An example using this syntax with the myfunctions.py file and the functions plustwo() and
falldist() is below:
plustwo(3)
Out[1]: 5
Multiple functions can be imported from the same file by separating the imported functions with
commas. The general syntax to import and call multiple functions from the same file is below:
from function_file import function_name1 , function_name2
function_name1 ( arguments )
function_name2 ( arguments )
An example using this syntax with the myfunctions.py file and the functions plustwo() and
falldist() is below:
out1 = falldist(3)
out2 = plustwo(3)
print(out1, out2)
44.145 5
108 CHAPTER 5. FUNCTIONS AND MODULES
Another way to import and use the functions from myfunctions.py into another script or Jupyter
notebook is to import the entire myfunctions.py file with import myfunctions, then call the func-
tions with the syntax below.
import function_file
function_file . function_name ()
myfunctions.plustwo(3)
Out[3]: 5
myfunctions.falldist(3)
Out[4]: 44.145
"""
< code >
return output
Doc strings are what you see when the help() function is called. As an example, running the
help() function on the built-in function sum brings up:
5.7. DOCSTRINGS IN FUNCTIONS 109
In [1]: help(sum)
sum(iterable, start=0, /)
Return the sum of a 'start' value (default: 0) plus an iterable of numbers
We can produce the same type of output when a user types types help() by adding docstrings to a
function.
Let’s create a new function that converts grams (g) to kilograms (kg). Let’s call our function g2kg.
The first thing to do is make sure that the name g2kg is not assigned to another function and is not
a keyword by Python. We can check quick using Python’s built-in type() function. We know that
sum() is a Python function, how about g2kg()?
In [2]: print(type(sum))
print(type(g2kg))
<class 'builtin_function_or_method'>
---------------------------------------------------------------------------
<ipython-input-2-487fcfc6eb43> in <module>()
1 print(type(sum))
----> 2 print(type(g2kg))
Since g2kg is not already defined in Python, we can use g2kg as the name of a new user-defined
function. Remember the parenthesis, colon, and return statement.
return kg
Now let’s try and use our function. How many kilograms is 1300 grams? We expect the output to
be 1.3 kilograms.
110 CHAPTER 5. FUNCTIONS AND MODULES
In [4]: g2kg(1300)
Out[4]: 1.3
If we call help() on our g2kg() function, nothing is returned. help(g2kg) does not return any
output because our new g2kg() function does not contain a docstring yet.
In [5]: help(g2kg)
g2kg(g)
If we insert a docstring into the function definition, help(g2kg) will return whatever text we in-
cluded in the docstring.
The standard components of docstrings included in function definitions include:
The docstring is included right below the def line and is enclosed in triple quotes """ """. The
triple quotes are typically included on their own lines. The syntax to add a docstring in a function
definition is below.
def function_name ( arguments ):
"""
"""
return output
Example:
>>> g2kg(1300)
1.3
"""
kg = g/1000
return kg
Now let’s ask for help() on our g2kg() function and see the docstring we wrote in the g2kg()
function definition printed back to us.
In [7]: help(g2kg)
g2kg(g)
Function g2kg converts between g and kg
Example:
>>> g2kg(1300)
1.3
Positional Arguments
An argument is a variable, value or object passed to a function or method. Positional arguments are
arguments that need to be included when a function is called in the proper position or order.
The first positional argument always needs to be listed first. The second positional argument needs
to be listed second and the third positional argument listed third, etc.
An example of positional arguments can be seen in Python’s complex() function. This function
returns a complex number with a real term and an imaginary term. The order that numbers are
112 CHAPTER 5. FUNCTIONS AND MODULES
passed to the complex function determines which number is the real term and which number is the
imaginary term.
If the complex number 3 + 5j is created, the two positional arguments are the numbers 3 and 5.
As positional arguments, 3 must be listed first, and 5 must be listed second.
In [1]: complex(3, 5)
Out[1]: (3+5j)
On the other hand, if the complex number 5 + 3j needs to be created, the 5 needs to be listed first
and the 3 listed second. Writing the same arguments in a different order produces a different result.
In [2]: complex(5, 3)
Out[2]: (5+3j)
Positional arguments can also be passed to functions using an iterable object. Examples of iterable
objects in Python include lists and tuples. The general syntax to use is:
function (* iterable )
Where function is the name of the function and iterable is the name of the iterable preceded by
the ampersand * character.
An example of using a list to pass positional arguments to the complex() function is below. Note
the ampersand * character is included before the term_list argument.
Out[3]: (3+5j)
Keyword Arguments
A keyword argument is an argument passed to a function or method which is preceded by a keyword
and an equals sign. The general form is:
function ( keyword = value )
Where function is the function name, keyword is the keyword argument and value is the value or
object passed as that keyword. Python’s complex function can also accept two keyword arguments.
The two keyword arguments are real= and imag=. To create the complex number 3 + 5j the 3 and
5 can be passed to the function as the values assigned to the keyword arguments real= and imag=.
Out[4]: (3+5j)
5.8. POSITIONAL AND KEYWORD ARGUMENTS 113
Keyword arguments are passed to functions after any required positional arguments. But the order
of one keyword argument compared to another keyword argument does not matter. Note how
both sections of code below produce the same output.
Out[5]: (3+5j)
Out[6]: (3+5j)
Keyword arguments can also be passed to functions using a Python dictionary. The dictionary
must contain the keywords as keys in the dictionary and the values as values in the dictionary. The
general form is:
keyword_dict = { ' keyword1 ': value1 , ' keyword2 ': value2 }
function (** keyword_dict )
Where function is the name of the function and keyword_dict is the name of the dictionary con-
taining keywords and values preceded by the double ampersand ** character. Note that the key-
words assigned as keys in a dictionary must be surrounded by quotes ' '. An example of using a
dictionary to pass keyword arguments to the complex() function is below:
Out[7]: (3+5j)
114 CHAPTER 5. FUNCTIONS AND MODULES
5.9 Summary
This chapter introduced user-defined functions. Functions are useful because functions are
reusable pieces of code. All functions have names. Some functions take input arguments and
produce output. Functions in Python are defined with the keyword def. You learned how to create
functions with default arguments. You also learned the difference between positional arguments
and keyword arguments. Positional arguments must be included in the proper order. Keyword
arguments must include the keyword name and an equals sign. You learned how to call functions
which are contained in a different file than the file that calls the function. One section of the chapter
reviewed how docstrings work in Python functions and the results of calling Python’s help() on a
function that contains a docstring.
Python Commands
Command Description
def define a function
return define the expression or value a function outputs
import import a module or .py file
from import a function or class from a module or .py file
as name an alias for a function, method or class
""" """ define a doc string
User-defined functions
Q05.01 Write a function called ft_to_in() which converts feet to inches. Note the conversion factor
is 1 foot = 12 inches. Convert 6 feet into inches using your function.
Q05.02 Write a function called m_to_ft() which converts meters to feet. Note the conversion factor
is 1 meter = 3.28084 feet. Convert 5,000 meters into feet using your function.
Q05.03 Use the functions in questions Q05.01 and Q05.02 to convert 2 meters into inches.
5.10. REVIEW QUESTIONS 115
Q05.04 Write a function that calculates the area of a circle based on a circle’s radius. The formula
for the area of a circle is A = πr2 where A is area and r is radius. Use your function to calculate the
area of circle with a radius of 5.
Q05.05 Write a function that converts degrees Celcius (C) to degrees Fahrenheit (F). The formula to
convert between the two temperature scales is F = 95 C × +32
Q05.06 Write a function that converts Kelvin temperature (K) to degrees Celcius (C). The formula
to convert between the two temperature scales is C = K − 273.15.
Q05.07 Use the functions in questions Q05.05 and Q05.06 to convert to convert the temperature at
Standard Temperature and Pressure (STP) of 273.15K into degrees Fahrenheit.
Q05.08 Use the functions in questions Q05.05 and Q05.06 to convert to convert the temperature at
absolute zero, 0K into degrees Celcius and degrees Fahrenheit.
Q05.09 Write a function called hp_to_kw() which converts horse power (hp) into kilowatts (kW).
Note the conversion factor is 1hp = 0.7457kW. Convert the horsepower of the average horse,
14.9hp, into kilowatts (kW).
Q05.20 Write a function called cyl_v() that calculates the volume V of a cylinder based on cylinder
height h and cylinder radius r. The formula for the volume of a cylinder is below:
V = πr2 h
Use your function cyl_v() to calculate the volume of a cylinder with height = 2.7 and radius = 0.73.
Q05.21 The universal gas law states that the pressure P, and temperature T of volume V of gas with
number of particles n is related by the equation below, where R is the universal gas constant.
PV = nRT
Write a function called gas_v() to calculate the volume V of a gas based on pressure P, temperature
T, number of particles n and universal gas constant R. Use your function to find the volume of gas
with the following parameters:
T = 273.15
n = 6.02 × 1023
R = 8.314
P = 101, 325
Q05.22 Most professional bakers weight their ingredients, while many home bakers use measure-
ments like cups and tablespoons to measure out ingredients. Create a function that takes two
arguments: ingredient and cups. The function will output the number of grams of the specified
ingredient. For example, a skeleton outline of your function might look like:
116 CHAPTER 5. FUNCTIONS AND MODULES
Your function needs to accept the following ingredients: 'flour' and 'sugar'. The conversion
factor for flour is 1 cup flour = 128 grams flour. The conversion factor for sugar is 1 cup sugar = 200
grams sugar.
Q05.23 The gravitational force between two celestial bodies (planets, moons, stars etc) is calculated
according to:
GMm
Fg =
r2
where Fg is the gravitational force, M is the mass of one of the celestial bodies, m is the mass of the
other the celestial bodies, r is the distance between the two celestial bodies and G is the universal
gravitational constant. G = 6.667408 × 10−11 m3 kg−1 s−2 .
(a) Write a function called grav_force() that accepts the mass of two celestial bodies and out-
puts the gravitational force produced.
(b) Use your function grav_force() and the table above to calculate the gravitational force be-
tween the earth and the sun.
(c) Use your function grav_force() and the table above to calculate the gravitational force be-
tween the mars and the sun.
Q05.30 (a) Rewrite the function in problem Q05.20 called gas_v() with the default values n =
6.02 × 1023 , R = 8.314 and P = 101, 325.
(a) Use your modified function gas_v() to calculate the volume of a gas at T = 500K using the
default arguments.
(b) Use your modified function gas_v() to calculate the volume of a gas at T = 500K, under half
the pressure p = 101, 325/2.
Q05.32 In engineering mechanics, the tensile stress σ applied to a solid cylinder is equal to the
tensile force on the cylinder F divided by the cylinder’s cross sectional area A according to the
formula below:
F
σ=
A
5.10. REVIEW QUESTIONS 117
The standard diameter d of a cylinder pulled in tension in a tensile test using the ASTM D8 standard
is d = 0.506 inches.
A = π (d/2)2
Use the formula for stress σ and area A above to write a function called stress() that calculates
stress σ based on force F and diameter d. Use d = 0.506 as the default diameter, but allow the user
to specify a different diameter if they want.
Use your stress() function to calculate the tensile stress σ in a cylinder with the default diameter
and a tensile force F = 12, 000.
Q05.31 One way to calculate how much an investment will be worth is to use the Future Value
formula:
FV = I0 (1 + r )n
Where FV is the future value, I0 is the initial investment, r is the yearly rate of return, and n is the
number of years you plan to invest.
(a) Write a function called future_value() which accepts an initial investment I0 and a number
of years n and calculates the future value FV. Include r = 0.05 as the default yearly rate of
return.
(b) Use your future_value() function to calculate the future value of an initial investment of
2000 dollars over 30 years with the default yearly rate of return
(c) Use your future_value() function to calculate the future value of the same initial investment
of 2000 dollars over 30 years, but a rate of return of 8% (0.08).
(d) Use your future_value() function to determine when 2000 dollars is invested over 30 years,
how much more do you make if the rate of return is 10% (0.10) instead of 5% (0.05).
Nested Functions
Q05.31 In mechanical engineering, there are a couple different units of stress. Units of stress include:
Pascals (Pa), Mega Pascals (MPa), pounds per square inch (psi) and kilopounds per square inch
(ksi).
(a) Write a function called pa_to_mpa to convert between Pascals (Pa) and Mega Pascals (MPa).
The conversion factor is 1MPa = 106 Pa
(b) Write a function called mpa_to_ksi to convert between Mega Pascals (MPa) and kilopounds
per square inch (ksi). The conversion factor is 1ksi = 6.89476MPa
(c) Write a function called ksi_to_psi to convert between kilopounds per square inch (ksi) and
pounds per square inch (psi). The conversion factor is 1000psi = 1ksi
(d) Combine the three functions pa_to_mpa, mpa_to_ksi, ksi_to_psi into a single function
pa_to_psi. Do this with calling the other functions as part of the pa_to_psi function, not
by rewriting the same code you wrote in parts (a), (b), and (c).
(e) Convert 2,500 Pa into psi using your pa_to_psi function.
118 CHAPTER 5. FUNCTIONS AND MODULES
Q05.40 Create a separate file .py file called greetings.py. Inside of greetings.py include the code:
def hi ():
print ( " Hi ! " )
Import you newly created greatings.py file and run the function hi().
Q05.41 Create a separate file .py file called greetings.py. Inside of greetings.py include the code:
def hello ( name ):
print ( " Hello " + name )
Import you newly created greatings.py file and run the function hello() with your name as an
input argument.
Q05.42 Create a separate file .py file called areas.py. Inside of areas.py include the code:
def triangle ( base , height ):
area = 0.5* base * height
print ( " Triangle Area : " , area )
Import you newly created areas.py file and run the functions triangle() and rectangle() with
the same two input arguments: 2 and 3.
For the sections of code below, run the lines of code. Then explain the error in your own words.
Below your error explanation, rewrite and run an improved section of code that fixes the error.
Q05.80 Run the code below and explain the error. Write the code and run it error free.
def add_me ( num )
return num + 2
add_me (1)
Q05.81 Run the code below and explain the error. Re-write the code and run it error free.
def add_you [ num ]:
return num + 2
add_you (2)
Q05.82 Run the code below and explain the error. Re-write the code and run it error free.
def my_func ():
print ( ' yup ')
Q05.83 Run the code below and explain the error. Rewrite the code and run it error free.
nothing ()
Q05.84 Run the code below and explain the error. Rewrite the code and run it error free.
nothing ()
Q05.85 Run the code below and explain the error. Rewrite the code and run it error free.
def first_a ( a ):
return a [0]
first_a (1)
120 CHAPTER 5. FUNCTIONS AND MODULES
Chapter 6
6.1 Introduction
By the end of this chapter you will be able to:
121
122 CHAPTER 6. PLOTTING WITH MATPLOTLIB
This command will install Matplotlib in the current working Python environment.
To verify that Matplotlib is installed try to invoke Matplotlib’s version at the Python REPL using
the .__version__ attribute common to most Python packages.
Out[1]: '3.0.2'
Line plots can be created with Python using Matplotlib’s pyplot library.
To build a line plot, first import Matplotlib. It is a standard convention to import Matplotlib’s
pyplot library as plt. The plt alias will be familiar to other Python programmers.
If using a Jupyter notebook include the line %matplotlib inline after the imports.
%matplotlib inline is a Jupyter notebook magic command which causes Matplotlib plots to dis-
play directly inside Jupyter notebook output cells.
We will also use NumPy, a numerical computing library for Python, to build the plot. NumPy is
typically imported with the alias np.
To create a line plot, pass an array of numbers as an argument to Matplotlib’s plt.plot() function.
The command plt.show() is needed at the end to show the plot. Make sure to include the double
parenthesis () in plt.show().
In [3]: plt.plot(x, y)
plt.show()
124 CHAPTER 6. PLOTTING WITH MATPLOTLIB
Line Color, Line Width, Line Style, Line Opacity and Marker Options
The color, width and style of line in a plot can be specificed. Line color, line width and line style
are included as extra arguments in the plt.plot() function call.
plt . plot ( <x - data > , <y - data > ,
linewideth = < float or int > ,
linestyle = ' < linestyle abbreviation > ' ,
color = ' < color abbreviation > ' ,
marker = ' < marker abbreviation > ')
An example plt.plot() line including line color, line width and line style options is:
plt . plot (x , y ,
linewidth =2.0 ,
linestyle = '+ ' ,
color = 'b ' ,
alpha =0.5 ,
marker = 'o ')
6.4. LINE PLOTS 125
Below is a list of color abbreviations. Note 'b' is used for blue and 'k' is used for black.
Below is a list of alpha (opacity) values (any alpha value between 0.0 and 1.0 is possible)
Colors can also be specified in hexadecimal form surrounded by quotation marks like '#FF69B4'
or in RGBA (red,green,blue,opacity) color surrounded by parenthesis like (255,182,193,0.5).
In addition to marker='<marker style>', the color of the marker edge, the color of the marker face
and the size of the marker can be specificed with:
plt . plot ( ....
Title
The plot title will be shown above the plot. The plt.title() command accepts a string as an
argument.
plt . title ( ' My Title ')
x-axis label
The x-axis label is shown below the x-axis. The plt.xlabel() command accepts a string as an
argument.
plt . xlabel ( ' My x - axis label ')
y-axis label
The y-axis label is shown to the left of the y-axis. The plt.ylabel() command accepts a string as
an argument.
6.4. LINE PLOTS 127
Legend
You can use the plt.legend() command to insert a legend on a plot. The legend will appear within
the plot area, in the upper right corner by default. The plt.legend() command accepts a list of
strings and optionally accepts a loc= argument to position the legend in a different location
plt . legend ([ ' entry1 ' , ' entry2 '] , loc = 0)
The following are the location codes for the legend location. These numbers need to be placed after
loc= in the plt.legend() call.
Grid
A grid can be shown on the plot using the plt.grid() command. By defaut, the grid is turned off.
To turn on the grid use:
plt . grid ( True )
The only valid options are plt.grid(True) and plt.grid(False). Note that True and False are
capitalized and are not enclosed in quotations.
1. Imports
2. Define data
3. Plot Data including options
4. Add plot details
5. Show the plot
1. Imports
Import matplot.pyplot as plt, as well as any other modules needed to work with the data such
as NumPy or Pandas. If using a Jupyter notebook include the line %matplotlib inline in the
import section.
2. Define data
Your plot needs to contain something. This is defined after the imports. Typically data for plots is
contained in Python lists, NumPy arrays or Pandas dataframes.
Use plt.plot() to plot the data defined you defined. Note the plt.plot() line needs to be called
before any other plot details are specified. Otherwise the details have no plot to apply to.
Besides the data, arguments in plt.plot() call can include:
Add details such as a title, axis labels, legend and a grid. Plot details to add include:
• plt.title('<title string>')
• plt.xlabel('<x-axis label string>')
• plt.ylabel('<y-axis label string>')
• plt.legend(['list','of','strings'])
• ptl.grid(<True or False>)
• plt.xticks([tick locations, floats or ints],[tick labels, strings]
• plt.yticks([tick locations, floats or ints],[tick labels, strings]
Use the plt.show() command to show the plot. plt.show() causes the plot to display in a Jupyter
notebook or pop out as a new window if the plot is constructed in a separate .py file. Note that
plt.show() needs to be called after all of the plot specifications.
A section of code following this outline and the resulting plot is shown below:
In [8]: # Imports
import numpy as np
6.4. LINE PLOTS 129
# Define data
x = np.arange(0, 4 * np.pi, 0.2)
y = np.sin(x)
Matplotlib plots can be saved with the plt.savefig() function. The plt.savefig() function needs
to be called right above the plt.show() line. All the features of the plot must be specified before
the plot is saved as an image file. If the figure is saved after the plt.show() command, the figure
will not be saved until the plot window is closed. Calling plt.savefig() after calling plt.show()
can be problematic when building plots in a Jupyter notebook with %matplotlib inline enabled.
A standard savefig() command is:
plt . savefig ( ' plot . png ' , dpi =300 , bbox_inches = ' tight ')
Where 'plot.png' is the name of the saved image file. Matplotlib will infer the image file format
(.png, .jpg, etc) based on the extension specified as part of the filename.
The keyword argument dpi= specifies how many dots per inch (image resolution) are in the saved
image. dpi=72 is fine for web images. dpi=300 is probably better for an image designed to go in a
written report or **_.pdf** document.
The keyword argument bbox_inches='tight' is optional. If the axis labels in the plot are cut off
in the saved image, set bbox_inches='tight'.
The following code section constructs a line plot and saves the plot to the image file plot.png.
6.6. MULTI LINE PLOTS 131
x = [0, 2, 4, 6]
y = [1, 3, 4, 8]
plt.plot(x,y)
plt.xlabel('x values')
plt.ylabel('y values')
plt.title('plotted x and y values')
plt.legend(['line 1'])
plt.show()
plotlib’s object-oriented approach to building plots. The object-oriented approach to building plots
will be used in the rest of this chapter.
• Figure Objects: The bottom layer. Think of the figure layer as the figure window which
contains the minimize, maximize, close buttons. A figure can include one plot or multiple
plots
• Plot Objects: A plot builds on the Figure layer. If there are multiple plots, each plot is called a
subplot.
• Axis Objects: An axis is added to a Plot layer. Axis can be thought of as sets of x and y axis
that lines and bars are drawn on. An Axis contains daughter attributes like axis labels, tick
labels, and line thickness.
• Data Objects: data points, lines, shapes are plotted on an axis
• Figure Objects: The bottom layer. Think of the figure layer as the figure window which
contains the minimize, maximize, close buttons. A figure can include one plot or multiple
plots
• Plot Objects: A plot builds on the Figure layer. If there are multiple plots, each plot is called a
subplot.
• Axis Objects: An axis is added to a Plot layer. Axis can be thought of as sets of x and y axis
that lines and bars are drawn on. An Axis contains daughter attributes like axis labels, tick
labels, and line thickness.
• Data Objects: data points, lines, shapes are plotted on an axis
To build a figure object, Matplotlib’s plt.subplot() function is used. The plt.subplot() function
creates both a figure object and an axis object. We say the plt.subplot() function instantiates a
figure object and instantiates an axis object. For now, we’ll leave the subplot() arguments blank. By
default, the subplot() function creates a single figure object and a single axis object. We’ll call the
figure object fig and the axis object ax. Note these two outputs of the plt.subplots() function
are separated by a comma.
6.6. MULTI LINE PLOTS 133
We have a figure object and axis object, but both of these objects are without attributes. We add
elements to the axis object to build a plot. Let’s create three NumPy arrays to add the three arrays
to our axis object.
The NumPy arrays x, y, and z can be added to axis object ax. We add a plot attribute (a line) to
our axis object ax using the object-oriented structure <object>.<attribute>. In this case, ax is the
object and plot is the attribute. The plt.show() line shows the plot on the screen.
The next code section demonstrates how to build a multi-line plot with Matplotlib’s object-oriented
interface.
x = np.arange(0,4*np.pi,0.1)
y = np.sin(x)
z = np.cos(x)
fig, ax = plt.subplots()
ax.plot(x,y)
ax.plot(x,z)
plt.show()
134 CHAPTER 6. PLOTTING WITH MATPLOTLIB
The ax object has many methods and attributes. In Python a method is sort of like a function, but
methods typically modify the object they are associated with, while functions modify their input
arguments. Two methods we can run on the ax object include ax.set_title() and ax.legend().
A couple daughter objects include ax.xaxis and ax.yaxis. These daughter objects in turn have
methods such as ax.xaxis.set_label_text() and ax.yaxis.set_label_text().
The code section below demonstrates using objects, attributes, and methods to build a multi-line
plot.
x = np.arange(0,4*np.pi,0.1)
y = np.sin(x)
z = np.cos(x)
fig, ax = plt.subplots()
ax.plot(x,y)
ax.plot(x,z)
plt.show()
6.7. BAR CHARTS AND PIE CHARTS 135
Bar charts and pie charts can be created with Matplotlib’s pyplot library.
Bar Charts
To construct a bar plot using Matplotlib, first import Matplotlib’s pyplot library. The alias plt
is commonly used to substitute matplotlib.pyplot. If using a Jupiter notebook, include the line
%matplotlib inline. In the next example, NumPy will also be used so it must be included in the
imports as well.
We need some data to plot to create a bar chart. In this case, the data is from a set of coefficient of ther-
mal expansion lab measurements. The coefficient of thermal expansion (CTE) is a material property
that describes how much a material will change in length as a result of a change in temperature.
Different materials have different CTE’s and we can use the lab data to determine which material
136 CHAPTER 6. PLOTTING WITH MATPLOTLIB
will expand the most if all three materials are heated up to the same temperature (assuming all
three materials start at the same temperature).
First, we need to input the lab measurement data as NumPy arrays:
In [2]: # Data
aluminum = np.array([
6.4e-5, 3.01e-5, 2.36e-5, 3.0e-5, 7.0e-5, 4.5e-5, 3.8e-5, 4.2e-5, 2.62e-5,
3.6e-5
])
copper = np.array([
4.5e-5, 1.97e-5, 1.6e-5, 1.97e-5, 4.0e-5, 2.4e-5, 1.9e-5, 2.41e-5, 1.85e-5,
3.3e-5
])
steel = np.array([
3.3e-5, 1.2e-5, 0.9e-5, 1.2e-5, 1.3e-5, 1.6e-5, 1.4e-5, 1.58e-5, 1.32e-5,
2.1e-5
])
Next, calculate the average or mean of each data set using NumPy’s np.mean() function.
Then build a list of materials and CTE’s. Note the list of materials is a list of strings, the list of x-
postions x_pos is an array of numbers and the list CTEs is a list of three numbers from the np.mean()
calculation above.
After the materials, x_pos, and CTEs (the labels below the bars) are defined, the bar chart is created
using the ax.bar() method.
Mathplotlib’s ax.bar() method requires two positional arguments, a list of bar positions and a list
of bar heights. In this bar chart, x_pos is the list of bar positions and CTEs is the list of bar heights.
The list of materials is passed to the ax.set_xticklabels() method.
ax.yaxis.grid(True)
Pie Charts
Pie charts can be constructed with Matplotlib’s ax.pie() method. The one required positional
argument supplied to the ax.pie() method is a list of pie piece sizes. Optional keyword arguments
include a list of pie piece labels (label=) and if the percentages will be auto-calculated and in what
format (autopct=).
The data we will plot is from the number of students that choose different engineering majors at
colleges in the US each year.
The following table lists the approximate numbers of engineering graduates in different engineer-
ing disciplines:
In [6]: # Pie chart, where the slices will be ordered and plotted counter-clockwise:
labels = ['Civil', 'Electrical', 'Mechanical', 'Chemical']
sizes = [15, 50, 45, 10]
fig, ax = plt.subplots()
ax.pie(sizes, labels=labels, autopct='%1.1f%%')
ax.axis('equal') # Equal aspect ratio ensures the "pie" is drawn as a circle
ax.set_title('Engineering Diciplines')
plt.show()
Pie pieces can be highlighted by “exploding” them out. Exploded pie pieces is applied to the pie
chart by using the explode= keyword argument. shadow=True and startangle= are two additional
keyword arguments that can be passed to the ax.pie() method.
In [7]: # Pie chart, where the slices will be ordered and plotted counter-clockwise
labels = ['Civil', 'Electrical', 'Mechanical', 'Chemical']
sizes = [15, 30, 45, 10]
explode = (
6.8. ERROR BARS 139
fig, ax = plt.subplots()
ax.pie(sizes,
explode=explode,
labels=labels,
autopct='%1.1f%%',
shadow=True,
startangle=90)
ax.axis('equal') # Equal aspect ratio ensures that pie is drawn as a circle.
ax.set_title('Engineering Diciplines')
plt.show()
Error bars can be created with Matplotlib and applied to both line plots and bar plots.
140 CHAPTER 6. PLOTTING WITH MATPLOTLIB
We’ll apply error bars to the Coefficient of Thermal Expansion data used in a previous section.
First the data we’ll store the data in three NumPy arrays. Then the mean or average of each array
is computed. The mean of each array will be the height of the bars. Next the standard deviation
of each array is calculated. The standard deviation will be the height of the error bars. Finally a
couple lists are created that correspond to the bar labels (labels), the bar positions (x_pos), the bar
heights (CTEs) and the error bar heights (error).
In [2]: # Data
aluminum = np.array([6.4e-5 , 3.01e-5 , 2.36e-5, 3.0e-5, 7.0e-5, 4.5e-5, 3.8e-5,
4.2e-5, 2.62e-5, 3.6e-5])
copper = np.array([4.5e-5 , 1.97e-5 , 1.6e-5, 1.97e-5, 4.0e-5, 2.4e-5, 1.9e-5,
2.41e-5 , 1.85e-5, 3.3e-5 ])
steel = np.array([3.3e-5 , 1.2e-5 , 0.9e-5, 1.2e-5, 1.3e-5, 1.6e-5, 1.4e-5,
1.58e-5, 1.32e-5 , 2.1e-5])
In [4]: x = np.linspace(0,5.5,10)
y = 10*np.exp(-x)
xerr = np.random.random_sample((10))
yerr = np.random.random_sample((10))
ax.set_xlabel('x-axis')
ax.set_ylabel('y-axis')
ax.set_title('Line plot with error bars')
plt.show()
6.9 Histograms
Historgram plots can be created with Matplotlib.
To create a histogram, first import Matplotlib. If using a Jupyter notebook, include the line
%matplotlib inline
We’ll use Numpy’s np.random.normal() function to create an array of random numbers with a
normal distribution. The three arguments passed to the np.random.normal() function are mu (the
mean), sigma (the standard deviation) and size= (the size of the array).
6.9. HISTOGRAMS 143
Matplotlib’s ax.hist() method is used to build the histogram. The first argument passed to
ax.hist() corresponds to the array of values to plot (x). The second argument corresponds to
the number of bins, or number of bars on the histogram. In our plot, we’ll specify 20 bins (20 bars).
The line plt.style.use('fivethirtyeight') is included to style the plot to look like plots on
fivethirtyeight.com. Matplotlib styles are addressed in a subsequent section of this chapter.
mu = 80
sigma = 7
x = np.random.normal(mu, sigma, size=200)
fig, ax = plt.subplots()
ax.hist(x, 20)
ax.set_title('Historgram')
ax.set_xlabel('bin range')
ax.set_ylabel('frequency')
fig.tight_layout()
plt.show()
144 CHAPTER 6. PLOTTING WITH MATPLOTLIB
In addition to histograms, a couple other useful statistical plots are box plots and violin plots.
Box Plots
To create a box plot with Matplotlib, the ax.boxplot() method is used. The general syntax is:
ax . boxplot ( data )
The data passed to the ax.boxplot() method can be a list, NumPy array. To create multiple box
plots side by side, pass in a list of lists or a 2D array.
The code section below creates a box plot with four elements.
fig, ax = plt.subplots()
Violin Plots
Violin plots are a type of statistical plot. A violin plot is similar to a box plot, but it shows some
additional information. The sides of the “violins” in a violin plot corresponds to a kernel density
estimation (kind of like a histogram) flipped vertically.
The next code section shows how to build a scatter plot with Matplotlib.
First, 100 random, but semi-focused, x and y-values are created using NumPy’s
np.random.randn() function. The x and y-values are plotted on a scatter plot using Mat-
plotlib’s ax.scatter() method. Note the number of x-values is the same as the number of
y-values. The size of the two lists or two arrays passed to plt.scatter() must be equal.
6.11. SCATTER PLOTS 147
x1 = 1.5 * np.random.randn(150) + 10
y1 = 1.5 * np.random.randn(150) + 10
x2 = 1.5 * np.random.randn(150) + 4
y2 = 1.5 * np.random.randn(150) + 4
x = np.append(x1,x2)
y = np.append(y1,y2)
fig, ax = plt.subplots()
ax.scatter(x,y)
plt.show()
Matplotlib scatter plots can be customized by including keyword arguments in the ax.scatter()
method call. Note the keyword arguments used in ax.scatter() are a little different from the
keyword arguments in other Matplotlib plot types.
Each of these keyword arguments can be assigned an individual value which applies to the whole
scatter plot. The ax.scatter() keyword arguments can also be assigned to lists or arrays. Supply-
ing a list or array controls the properties of each marker in the scatter plot.
N = 100
x1 = 1.5 * np.random.randn(N) + 10
y1 = 1.5 * np.random.randn(N) + 10
x2 = 1.5 * np.random.randn(N) + 4
y2 = 1.5 * np.random.randn(N) + 4
x = np.append(x1,x2)
y = np.append(y1,y2)
colors = np.random.rand(N*2)
area = np.pi * (8 * np.random.rand(N*2))**2
fig, ax = plt.subplots()
The code section below builds a simple line plot and applies three annotations (three arrows with
text) on the plot. The ax.annotate() method produces the annotations. There are a bunch of
keyword arguments that can be passed to ax.annotate().
The keyword argument to pay attention to in the code section below is xycoords=. Each of the
three annotations has a different xycoords= keyword argument.
In the first annotation, xycoords='data'. This means the annotation is placed relative to the data.
Since xy=(0, 0), the annotation arrow points to the 0,0 data point.
150 CHAPTER 6. PLOTTING WITH MATPLOTLIB
In the second annotation, xycoords='axes fraction'. This means the second annotation is placed
relative to the axis. Since xy=(0, 0.5), the annotation arrow points all the way to the left edge of
the x-axis and half way up the y-axis.
In the third annotation, xycoords='figure pixels'. This means the third annotation is placed
relative to the figure window. Since xy=(20, 75), the third annotation arrow points 20 pixels to
the right and 75 pixels up from the bottom left corner of the figure window.
x = np.arange(-5, 5, 0.01)
y = x**2
ax.set_xlim(-5,5)
6.13. SUBPLOTS 151
ax.set_ylim(-1,10)
ax.set_title('Parabolic Function with Text Notation')
plt.show()
6.13 Subplots
Sometimes it is useful for problem solvers to include a couple plots side by side. This can be
done in Matplotlib using subplots. Matplotlib’s plt.subplot() function can include two positional
arguments for the number of rows of plots in the figure and the number of columns of plots in the
figure. The general format is:
fig , < ax objects > = plt . subplots ( rows , cols )
Where rows and cols denote how the subplots are laid out. The <ax objects> needs to have
dimensions that correspond to rows and cols.
If a 2 row by 2 column array of plots is created, the <ax object> must to be arrayed as shown
below:
fig , ( ( ax1 , ax2 ) , ( ax3 , ax4 ) ) = plt . subplots (2 ,2)
If a 2 row by 3 column array of plots is created, the <ax objects> must be arrayed to correspond
to these dimensions:
152 CHAPTER 6. PLOTTING WITH MATPLOTLIB
The code section below builds a 2 row by 2 column array of subplots in one figure. The axes of each
subplt is scaled in a different way.
# log y axis
ax2.semilogy(t, np.exp(-t / 5.0))
ax2.set(title='semilogy')
ax2.grid()
# log x axis
ax3.semilogx(t, np.exp(-t / 5.0))
ax3.set(title='semilogx')
ax3.grid()
fig.tight_layout()
plt.show()
6.14. PLOT STYLES 153
x = np.linspace(0, 10)
fig, ax = plt.subplots()
plt.style.use('fivethirtyeight')
154 CHAPTER 6. PLOTTING WITH MATPLOTLIB
for n in range(-20,30,10):
ax.plot(x, np.cos(x) + np.random.randn(50) + n)
ax.set_title("'fivethirtyeight' style")
plt.show()
There are many different styles available. You can list the available styles with the command:
seaborn-talk
seaborn-bright
seaborn-muted
seaborn-dark
seaborn-darkgrid
seaborn-paper
seaborn-white
seaborn-pastel
seaborn-colorblind
Solarize_Light2
seaborn
fast
6.14. PLOT STYLES 155
seaborn-dark-palette
tableau-colorblind10
seaborn-notebook
classic
seaborn-poster
bmh
seaborn-whitegrid
seaborn-deep
dark_background
_classic_test
fivethirtyeight
ggplot
seaborn-ticks
grayscale
The code section below displays a couple of Matplotlib’s available plot styles including the
'default', 'seaborn' and the older Matplotlib 'classic' style.
def his(ax):
x = np.random.randn(50)
ax.hist(x)
def lb(ax,s):
ax.text(0.2,0.5,s, fontsize=14)
ax.xaxis.set_ticklabels([],[])
ax.yaxis.set_ticklabels([],[])
def make_fig(st):
with plt.style.context(st):
fig,[ax1,ax2,ax3]=plt.subplots(1,3,figsize=(9,1.5))
lb(ax1,st)
his(ax2)
pl(ax3,st)
s = ['default','fivethirtyeight','seaborn','ggplot','Solarize_Light2','classic']
for st in s:
make_fig(st)
plt.show()
156 CHAPTER 6. PLOTTING WITH MATPLOTLIB
6.15. CONTOUR PLOTS 157
Where X and Y are 2D arrays of the x and y points, and Z is a 2D array of points that determines
the “height” of the contour, which is represented by color in a 2D plot. The np.meshgrid function
is useful to create two 2D arrays from two 1D arrays.
X, Y = np.meshgrid(x, y)
Z = np.sin(X)*np.cos(Y)
fig, ax = plt.subplots(figsize=(6,6))
158 CHAPTER 6. PLOTTING WITH MATPLOTLIB
ax.contour(X,Y,Z)
plt.show()
Where X and Y are 2D arrays of the x and y points, and Z is a 2D array of points that determines the
color of the areas on the 2D plot.
6.15. CONTOUR PLOTS 159
X, Y = np.meshgrid(x, y)
Z = np.sin(X)*np.cos(Y)
fig, ax = plt.subplots(figsize=(6,6))
ax.contourf(X,Y,Z)
plt.show()
160 CHAPTER 6. PLOTTING WITH MATPLOTLIB
Because colors represent a third dimension (like “hight”) on a 2D plot, it is useful to have a scale to
what each color means. A color scale is typically represented besides a plot. Color bars are added
to Matplotlib contour plots using the fig.colorbar() method. Since the color bar is not part of
the contour plot, the color bar needs to be applied to the figure object, often called fig. A contour
plot needs to be passed into the fig.colorbar() method. Therefore, when you add a color bar to a
figure, a plot object needs to be available. A plot object is the output of the ax.contour() method.
Previously, the output of the ax.contour() method was not assigned to a variable. But to include
a color bar on a contour plot, the plot object needs to be saved to a variable so that it can be passed
to the fig.colorbar() method.
cf = ax1 . contourf (X ,Y , Z )
fig . colorbar ( cf , ax = ax1 )
Where cf is the plot object created by ax1.contourf(X, Y, Z). The axis object that contains the
contour plot, ax1 is passed to the fig.colorbar() method along with the cf plot object.
%matplotlib inline
X, Y = np.meshgrid(x, y)
Z = np.sin(X)*np.cos(Y)
ax1.set_aspect('equal')
cf = ax1.contourf(X,Y,Z)
fig.colorbar(cf, ax=ax1)
plt.show()
6.15. CONTOUR PLOTS 161
The code section below produces two filled contour plots, each with a different color map.
%matplotlib inline
X, Y = np.meshgrid(x, y)
Z = np.sin(X)*np.cos(Y)
mycmap1 = plt.get_cmap('gist_earth')
ax1.set_aspect('equal')
ax1.set_title('Colormap: gist_earth')
cf1 = ax1.contourf(X,Y,Z, cmap=mycmap1)
fig.colorbar(cf1, ax=ax1)
mycmap2 = plt.get_cmap('gnuplot2')
ax2.set_aspect('equal')
ax2.set_title('Colormap: gnuplot2')
cf2 = ax2.contourf(X,Y,Z, cmap=mycmap2)
fig.colorbar(cf2, ax=ax2)
plt.show()
6.16. QUIVER AND STREAM PLOTS 163
In this section, you will learn how to build quiver and stream plots using Matplotlib.
Quiver Plots
A quiver plot is a type of 2D plot that shows vector lines as arrows. Quiver plots are useful in
electrical engineering to visualize electrical potential and useful in mechanical engineering to show
stress gradients.
To build a quiver plot, first import Matplotlib. Again, by convention the alias plt is used. If using a
Jupyter notebook include the line %matplotlib inline. For some of the quiver plots in this section,
NumPy is needed as well.
Let’s buid a simple quiver plot that contains one arrow to see how matplotlib’s ax.quiver()
method works. The ax.quiver() method takes four positional arguments:
Where x_pos and y_pos are the arrow starting positions and x_direct, y_direct are the arrow
directions.
Let’s build our first plot which contains one quiver arrow at the starting point x_pos = 0,
y_pos = 0. We’ll define the quiver arrow’s direction as pointing up and to the right x_direct = 1,
y_direct = 1.
x_pos = 0
y_pos = 0
x_direct = 1
y_direct = 1
ax.quiver(x_pos,y_pos,x_direct,y_direct)
plt.show()
164 CHAPTER 6. PLOTTING WITH MATPLOTLIB
Now let’s add a second arrow to the quiver plot by passing in two starting points and two arrow
directions.
We’ll keep our original arrow starting position at the origin 0,0 and pointing up and to the right (in
the 1,1 direction). We’ll define a second arrow with a starting position of -0.5,0.5 which points
straight down (in the 0,-1 direction).
An additional keyword argument to add the the ax.quiver() method is scale=5. Including
scale=5 scales the arrow lengths so the arrows look longer and show up better on the quiver plot.
To see the start and end of both arrows, we’ll set the axis limits between -1.5 and 1.5 using the
ax.axis() method and pass in a list of axis limits in the form [xmin, xmax, ymin, ymax].
We can see two arrows. One arrow points to the upper right and the other arrow points straight
down.
x_pos = [0, 0]
y_pos = [0, 0]
x_direct = [1, 0]
y_direct = [1, -1]
6.16. QUIVER AND STREAM PLOTS 165
ax.quiver(x_pos,y_pos,x_direct,y_direct,
scale=5)
ax.axis([-1.5, 1.5, -1.5, 1.5])
plt.show()
Two arrows is great, but to create a whole 2D surface worth of arrows, we’ll utilize NumPy’s
meshgrid() function.
We need to build a set of arrays that denote the x and y starting positions of each quiver arrow on
the plot. We will call our quiver arrow starting position arrays X and Y.
We can use the x,y arrow starting positions to define the x and y components of each quiver arrow
direction. We will call the quiver arrow direction arrays u and v. On this quiver plot, we will define
the quiver arrow direction based upon the quiver arrow starting point using:
In [4]: x = np.arange(0,2.2,0.2)
y = np.arange(0,2.2,0.2)
166 CHAPTER 6. PLOTTING WITH MATPLOTLIB
X, Y = np.meshgrid(x, y)
u = np.cos(X)*Y
v = np.sin(y)*Y
Now we will build the quiver plot using Matplotlib’s ax.quiver() method. Again, the method call
takes four positional arguments:
This time x_pos and y_pos are 2D arrays which contain the starting positions of the arrows and
x_direct, y_direct are 2D arrays which contain the arrow directions.
The commands ax.xaxis.set_ticks([]) and ax.yaxis.set_ticks([]) removes the tick marks
from the axis and ax.set_aspect('equal') sets the aspect ratio of the plot to 1:1.
ax.xaxis.set_ticks([])
ax.yaxis.set_ticks([])
ax.axis([-0.2, 2.3, -0.2, 2.3])
ax.set_aspect('equal')
plt.show()
6.16. QUIVER AND STREAM PLOTS 167
Now let’s build another quiver plot with the î and ĵ components of the arrows, ⃗F are dependant
upon the arrow starting point x, y according to the function:
⃗F = x î − y ĵ
5 5
Again we can use NumPy’s np.meshgrid() function to build the arrow starting position arrays,
then apply our function ⃗F to the x and y arrow starting point arrays.
In [6]: x = np.arange(-1,1,0.1)
y = np.arange(-1,1,0.1)
X, Y = np.meshgrid(x, y)
u = np.cos(X)*Y
168 CHAPTER 6. PLOTTING WITH MATPLOTLIB
v = np.sin(y)*Y
X,Y = np.meshgrid(x,y)
u = X/5
v = -Y/5
fig, ax = plt.subplots(figsize=(9,9))
ax.quiver(X,Y,u,v)
ax.xaxis.set_ticks([])
ax.yaxis.set_ticks([])
ax.set_aspect('equal')
plt.show()
6.16. QUIVER AND STREAM PLOTS 169
Next let’s build another quiver plot using the gradient function. The gradient function will have
the form:
z = xe− x
2 − y2
We can use NumPy’s np.gradient() function to apply the gradient function to every arrow’s x,y
starting position.
In [7]: x = np.arange(-2,2.2,0.2)
y = np.arange(-2,2.2,0.2)
X, Y = np.meshgrid(x, y)
z = X*np.exp(-X**2 -Y**2)
dx, dy = np.gradient(z)
fig, ax = plt.subplots(figsize=(9,9))
ax.quiver(X,Y,dx,dy)
ax.xaxis.set_ticks([])
ax.yaxis.set_ticks([])
ax.set_aspect('equal')
plt.show()
170 CHAPTER 6. PLOTTING WITH MATPLOTLIB
Now let’s build a quiver plot that contains four vortices. The function ⃗F which describes the 2D
field is:
Again we can build these arrays using NumPy and plot the arrays with Matplotlib.
In [8]: x = np.arange(0,2*np.pi+2*np.pi/20,2*np.pi/20)
y = np.arange(0,2*np.pi+2*np.pi/20,2*np.pi/20)
6.16. QUIVER AND STREAM PLOTS 171
X,Y = np.meshgrid(x,y)
u = np.sin(X)*np.cos(Y)
v = -np.cos(X)*np.sin(Y)
fig, ax = plt.subplots(figsize=(9,9))
ax.quiver(X,Y,u,v)
ax.xaxis.set_ticks([])
ax.yaxis.set_ticks([])
ax.axis([0,2*np.pi,0,2*np.pi])
ax.set_aspect('equal')
plt.show()
172 CHAPTER 6. PLOTTING WITH MATPLOTLIB
Now let’s add some color to the quiver plots. The ax.quiver() method has an optional fifth po-
sitional argument that specifies the quiver arrow color. The quiver arrow color argument needs to
have the same dimensions as the position and direction arrays.
Using Matplotlib subplots, we can build a figure which contains 3 quiver plots each in color
# first subplot
x = np.arange(0,2.2,0.2)
y = np.arange(0,2.2,0.2)
X, Y = np.meshgrid(x, y)
u = np.cos(X)*Y
v = np.sin(y)*Y
n = -2
R = np.sqrt(((v-n)/2)**2 + ((u-n)/2)**2)
ax1.quiver(X,Y,u,v,R, alpha=0.8)
ax1.xaxis.set_ticks([])
ax1.yaxis.set_ticks([])
ax1.axis([-0.2, 2.3, -0.2, 2.3])
ax1.set_aspect('equal')
# second subplot
x = np.arange(-2,2.2,0.2)
y = np.arange(-2,2.2,0.2)
X, Y = np.meshgrid(x, y)
z = X*np.exp(-X**2 -Y**2)
dx, dy = np.gradient(z)
n = -2
R = np.sqrt(((dx-n)/2)**2 + ((dy-n)/2)**2)
ax2.quiver(X,Y,dx,dy,R)
ax2.xaxis.set_ticks([])
ax2.yaxis.set_ticks([])
ax2.set_aspect('equal')
# third subplot
6.16. QUIVER AND STREAM PLOTS 173
x = np.arange(0,2*np.pi+2*np.pi/20,2*np.pi/20)
y = np.arange(0,2*np.pi+2*np.pi/20,2*np.pi/20)
X,Y = np.meshgrid(x,y)
u = np.sin(X)*np.cos(Y)
v = -np.cos(X)*np.sin(Y)
n = -1
R = np.sqrt(((dx-n)/2)**2 + ((dy-n)/2)**2)
ax3.quiver(X,Y,u,v,R)
ax3.xaxis.set_ticks([])
ax3.yaxis.set_ticks([])
ax3.axis([0,2*np.pi,0,2*np.pi])
ax3.set_aspect('equal')
plt.show()
Stream Plots
A stream plot is a type of plot used to show fluid flow and 2D field gradiants.
The basic method to build a stream plot in Matplotlib is:
Where x_grid and y_grid are arrays of x,y points. The arrays x_vec and y_vec denote the stream
velocity at each point on the grid. The keyword argument density=spacing specifies how close
together to draw the stream lines.
174 CHAPTER 6. PLOTTING WITH MATPLOTLIB
Let’s build a simple plot of stream lines on a 10 x 10 grid where all the stream lines are parallel and
point to the right.
In [11]: x = np.arange(0,10)
y = np.arange(0,10)
X, Y = np.meshgrid(x,y)
u = np.ones((10,10))
v = np.zeros((10,10))
fig, ax = plt.subplots()
plt.show()
We can build a stream plot which shows field lines based on a defined 2D vector field.
In [12]: x = np.arange(0,2.2,0.1)
y = np.arange(0,2.2,0.1)
X, Y = np.meshgrid(x, y)
u = np.cos(X)*Y
v = np.sin(y)*Y
fig, ax = plt.subplots()
ax.streamplot(X,Y,u,v, density = 1)
ax.axis([0.5,2.1,0,2])
ax.xaxis.set_ticks([])
ax.yaxis.set_ticks([])
ax.set_title('Stream Plot')
plt.show()
176 CHAPTER 6. PLOTTING WITH MATPLOTLIB
We can build a stream plot to demonstrate the electric field due to two point charges. The electric
field at any point depends on the position and distance relative to the two point charges.
x = np.arange(-4,4,0.2)
y = np.arange(-4,4,0.2)
X,Y = np.meshgrid(x,y)
Ex = (X + 1)/((X+1)**2 + Y**2) - (X - 1)/((X-1)**2 + Y**2)
Ey = Y/((X+1)**2 + Y**2) - Y/((X-1)**2 + Y**2)
fig, ax = plt.subplots(figsize=(6,6))
ax.streamplot(X,Y,Ex,Ey)
ax.set_aspect('equal')
ax.plot(-1,0,'-or')
ax.plot(1,0,'-ob')
Surface Plots
Surface plots are created with Matplotlib’s ax.plot_surface() method. By default surface plots
are a single color. The general method call is:
178 CHAPTER 6. PLOTTING WITH MATPLOTLIB
ax . plot_surface (X , Y , Z )
x = np.arange(-5,5,0.1)
y = np.arange(-5,5,0.1)
X,Y = np.meshgrid(x,y)
Z = X*np.exp(-X**2 - Y**2)
fig = plt.figure(figsize=(6,6))
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(X, Y, Z, )
plt.show()
6.17. 3D SURFACE PLOTS 179
Where X and Y are 2D array of x and y points and Z is a 2D array of heights. The keyword arguments
rstride= and cstride= are the row step size and the column step size. These keyword arguments
control how close together the “wires” in the wireplot are drawn.
fig = plt.figure(figsize=(12,6))
180 CHAPTER 6. PLOTTING WITH MATPLOTLIB
x = np.arange(-5,5,0.1)
y = np.arange(-5,5,0.1)
X,Y = np.meshgrid(x,y)
Z = X*np.exp(-X**2 - Y**2)
plt.show()
Where the keyword argument cmap=<color map> assigns the colors to the surface. There is a huge
array of color map options in Matplotlib. Options include 'coolwarm', 'gist_earth', and ocean.
6.17. 3D SURFACE PLOTS 181
fig = plt.figure(figsize=(10,6))
ax1 = fig.add_subplot(111, projection='3d')
x = np.arange(-5,5,0.1)
y = np.arange(-5,5,0.1)
X,Y = np.meshgrid(x,y)
Z = X*np.exp(-X**2 - Y**2)
mycmap = plt.get_cmap('gist_earth')
ax1.set_title('gnuplot color map')
surf1 = ax1.plot_surface(X, Y, Z, cmap=mycmap)
fig.colorbar(surf1, ax=ax1, shrink=0.5, aspect=5)
plt.show()
182 CHAPTER 6. PLOTTING WITH MATPLOTLIB
3D Surface Plots can be projected onto 2D surfaces. Below is sample code and the plot produced.
fig = plt.figure(figsize=(12,6))
ax = fig.add_subplot(111, projection='3d')
x = np.arange(-5,5,0.1)
y = np.arange(-5,5,0.1)
X,Y = np.meshgrid(x,y)
Z = X*np.exp(-X**2 - Y**2)
ax.set_xlabel('X')
ax.set_xlim(-5, 5)
ax.set_ylabel('Y')
ax.set_ylim(-5, 5)
ax.set_zlabel('Z')
ax.set_zlim(np.min(Z),np.max(Z))
ax.set_title('3D surface with 2D contour plot projections')
plt.show()
6.17. 3D SURFACE PLOTS 183
184 CHAPTER 6. PLOTTING WITH MATPLOTLIB
6.18 Summary
In this chapter, you learned how to create plots using Python and Matplotlib. You learned what
Matplotlib is and why problem solvers should learn how to use Matplotlib. How to install Mat-
plotlib on your computer was shown at the start of the chapter. You learned how to customize
Matplotlib plots and save plots as images. You learned how to include axis label, titles, and leg-
ends on your plots. You also learned how to add annotations to plots.
Types of charts detailed in this chapter: * line plots * multiline plots * bar graphs * pie charts * bar
and line graphs with error bars * scatter plots * histograms * box plots and violin plots * contour
plots * quiver plots * stream plots * 3D surface plots * 3D wire frame plots * 3D surface plots with
projections
Additional Resources
Matplotlib official documentation: https://matplotlib.org/contents.html
Matplotlib summary notebook on Kaggle: https://www.kaggle.com/grroverpr/
matplotlib-plotting-guide/notebook
Python Plotting With Matplotlib (Guide) on Real Python: https://realpython.com/
python-matplotlib-guide/#why-can-matplotlib-be-confusing
Python For Data Science: Matplotlib Cheat Sheet from DataCamp: https://s3.amazonaws.com/
assets.datacamp.com/blog_assets/Python_Matplotlib_Cheat_Sheet.pdf
Line plots
Q06.04 Create a plot of the function y = mx + b, where m = −1 and b = −4. Limit the plot to
values of x = −5 to 5.
Q06.05 Create a plot of the function y = ax2 + bx + c, where a = 1/2, b = −1/3 and c = 4. Limit
the plot to values of x = −10 to x = 10
Q06.06 Create a plot of the function y = x3 + 3 from x = −3 to x = 3.
Q06.07 Create a plot of the function y = 2x3 − 9x2 + 7x + 6 from x = −3 to x = 4.
Q06.08 Plot the data set below with a line plot. Use Matplotlib’s default index system, or create a
set of x values from x = 0 to x = 4.
y = [−1, 2, −3, 1, 0]
Q06.09 Plot the following three functions on the same set of axis. Use a different color line for each
function.
x = cos(t)
y = cos(t/2)
√
z = cos( (t))
x = cos(r/10)
y = sin(r/4)
z = atan(r )
Q06.30 According to the University of Waterloo, world energy consumption in 2006 from the 5 top
energy resources were:
Hydro = 6%
186 CHAPTER 6. PLOTTING WITH MATPLOTLIB
Nuclear = 6%
Oil = 36%
Coal = 28%
Build a pie chart of distribution of world energy consumption based on the data above.
Q06.31 According to the 2017 Python Developer’s Survey. The computer operating system used by
Python Developers breaks down as follows
Windows = 49%
Linux = 19%
MacOS = 15%
Other = 17%
Build a pie chart of the computer operating system used by Python Developers in 2017.
Q06.32 According to the 2017 Python Developer’s Survey. The commercial cloud providers used
by Python Developers breaks down as follows:
AmazonWebServices = 67%
GoogleCloud = 29%
Heroku = 26%
DigitalOcean = 23%
Other = 13%
Build a pie chart of the commercial cloud providers used by Python Developers in 2017.
√
Q06.33 Create a plot of the function y = 2x from x = 1 to 10
Q06.35 A list of grades in a college engineering course and the corresponding number of students
who earned each grade is shown below:
6.19. REVIEW QUESTIONS 187
grades = [ 'A ' , 'B ' , 'C ' , 'D ' , 'F ']
number_ of _s tu de nt s =[3 , 5 , 8 , 1 , 2]
Build a bar plot of the grade distribution from the college engineering class.
Q06.36 The proof strength of four different grades of bolts is shown below:
Build a bar chart of the proof strength of the four types of bolts. Include labels on the x-axis and
y-axis. Include a title.
Q06.37 According to the 2017 Python Developer’s Survey, the IDE (Integrated Development Envi-
ronment) used by Scientific Python Developers breaks down as follows:
PyCharm CE = 17%
Sublime Text = 9%
Vim = 8%
IDLE = 7%
Atom = 7%
VS Code = 6%
Notepad + + = 6%
Eclipse = 3%
Emacs = 3%
Build a bar plot of tensile strength vs. heat treatment using the data above.
Q06.50 Plot a histogram of normal distribution of 100 random numbers. Use NumPy’s
np.random.normal() function to create the array of numbers. Set a mean µ of 20 and a standard
deviation σ of 7.
Q06.51 NumPy’s np.random.randint() function creates an array of random numbers. NumPy’s
np.random.randn() function creates an array of normally-distributed random numbers. Use both
each of these functions to create a set of 200 random numbers. Plot both sets of numbers as his-
tograms with Matplotlib’s ax.hist() method. After you construct both histograms, explain how
the two NumPy functions np.random.randint() and np.random.randn() functions compare.
Q06.52 Create a box plot with three elements (three “boxes”). Use NumPy’s np.random.randn()
function to create three arrays of 50 elements. Plot each array as a separate element on the box plot.
Q06.53 Create a violin plot with five elements (three “violins”). Use NumPy’s np.random.randn()
function to create five arrays of 50 elements. Plot each array as a separate element on the violin
plot.
Q06.54 Use Matplotlib’s plt.subplots() command to create a figure with three subplots. In the
first subplot, build a historgram. In the second subplot build a box plot. In the third subplot build a
violin plot. Plot the same set of 100 normally-distributed random numbers in each subplot. Include
a title above each subplot that shows the plot type.
Scatter Plots
Q06.60 Create a scatter plot with the following lists of x points and y points.
x = [1 ,2 ,3 ,4 ,5]
y = [8 ,12 ,4 ,2 ,6]
Q06.60 Create a scatter plot with the following arrays of x pints and y points generated with
NumPy’s np.random.randin() function.
x = np . random . randint (20)
y = np . random . randint (20)
Q06.62 Use the code below to create two arrays of semi-focused random points.
6.19. REVIEW QUESTIONS 189
Plot the arrays x and y on a scatter plot. Make the color of the marker’s on the scatter plot red and
set the marker opacity to 0.5.
Subplots
Q06.70 Create a figure that has four subplots all in one row. In each of the subplots plot the function:
y = ex
Use the same values of x and y in each subplot. Set the values of x with NumPy’s arange()
function with the line x = np.arange(0.01, 20.0, 0.01`) In the first subplot, use Matplotlibs’s
ax.plot() method. In the second subplot use Matplotlib’s ax.semilogy() method. In the thrid
subplot use Matplotlib’s ax.semilogx method. In the four subplot use Matplotlib’s ax.loglog()
method. Label each subplot with a title that shows the plot type.
190 CHAPTER 6. PLOTTING WITH MATPLOTLIB
Chapter 7
7.1 Introduction
By the end of this chapter you will be able to:
191
192 CHAPTER 7. IF ELSE TRY EXCEPT
Where var is the variable that stores the user’s input and 'message' is the message the user sees at
the prompt. A string enclosed in quotes, like 'message' needs to be passed as an input argument
to the input() function. Let’s ask a user for their age:
Since the user’s input is assigned to a variable, further operations can be run on it. Now, let’s print
the user’s age back to them. This can be accomplished with an f-string. Note the f' ' inserted
before the string. A set of curly braces { } surrounds the variable’s value that is printed back to
the user.
Let’s try another example. We will we ask for the base and height of a triangle and print back the
area of the triangle to back to the user.
There is a problem with the approach below. The code block does not run becuase a common error
is present.
base of triangle: 5
height of triangle: 2
---------------------------------------------------------------------------
<ipython-input-3-c9cb8f02e604> in <module>()
1 b = input('base of triangle: ')
2 h = input('height of triangle: ')
----> 3 A = (1/2)*b*h
4 print(f'The area of the triangle is: {A}')
The previous section of code returns an error because of the data type of the variables b and h. To
investigate the data type, we can use Python’s type() function.
base of triangle: 5
height of triangle: 2
b and h are of type: <class 'str'>, <class 'str'>
Notice that both b and h are strings, even though the numbers 5 and 2 were entered as input. The
output of the input() function is always a string, even if the user enters a number.
To complete the area calculation, b and h first need to be converted to floats using Python’s float()
function, then the mathematical operation will run without error:
base of triangle: 5
height of triangle: 2
The area of the triangle is: 5.0
7.3 If statements
The if-statement is one of the basic selection structures in Python. The syntax for a section of code
that contains an if statement is below:
if < logical_condition >:
< code to run >
194 CHAPTER 7. IF ELSE TRY EXCEPT
The keyword if begins the statement. Following if, a logical condition must to be included. A
logical condition is an variable or expression that can be evaluated as True or False. An example
of a logical condition is a<5. The logical condition a<5 returns True if a is less than 5. Otherwise,
if a is 5 or greater a<5 returns False. Following the logical condition, a colon : is required. After
the if-statement, a section of code to run when the condition is True is included. The section of
<code to run> must be indented and every line in this section of code must be indented the same
number of spaces. By convention, indentation is four spaces in Python. Most Python code editors,
including Jupyter notebooks, indent code after if-statements automatically.
The section of code below demonstrates an if-statement in Python:
In [1]: a = 2
if a<5:
print('less than five')
In the first line of code in the example above, the variable a is assigned the value 2. The sec-
ond line of code is the if-statement. The if-statement starts with the keyword if and is followed
by the logical condition a<5 and a colon :. The logical condition a<5 will return either True or
False depending on the value of a. Since a=2, the logical condition a<5 evaluates as True. The
line print('less than five') is indented after the if-statement. The line of code including the
print() statement will run if the if-statement is True. Since the if-statement is True, the indented
line print('less than five') runs. As a result of running these three lines of code, the user sees
the text less than five.
Multiple if statements
If-statements can be chained together one after another to create a programmatic flow. For example,
the following code block utilizes three different if-statements, each if-statement is followed by an
indented code block.
In [2]: a = 2
if a<0:
print('is negative')
if a == 0:
print('is zero')
if a>0:
print('is positive')
is positive
Note how each if-statement is followed by a logical condition and a colon :. Also, note how the
code below each if-statement is indented. With the code left-justified (not indented), all three code
lines will run, and the output will be different. The pass keyword is used as the code will not run
unless at least one line of code is indented after the if-statement. pass is a line of code that does
nothing in Python.
7.4. SELECTION STATEMENTS 195
In [3]: a = 2
if a<0:
pass
print('a is negative')
if a == 0:
pass
print('a is zero')
if a>0:
pass
print('a is positive')
a is negative
a is zero
a is positive
• if
• else
• elif
• try
• except
So far in this text, all of the Python code has either been strictly linear or linear and include func-
tions. A strictly linear program is a program that runs top to bottom. Every line of code in a linear
program runs. In a linear program with functions, the program still runs head to base, but the
program takes side excursions to execute functions on the way down.
If this next couple chapters, you learn to write programs non-linearly. Non-linear programs do not
run every line of code top to bottom. In non-linear programs, sections of code may not run based
on selection statements like if and try. Non-linear programs can include loops. Inside loops are
sections of code that run multiple times. Loops are defined by repetition structures like for loops
and while loops.
To start our discussion of non-linear programs, we will begin with if statements.
The else keyword needs to be on its own line and be at the same indentation level as the if
keyword that the else corresponds to. The keyword else needs to be followed by a colon :. Any
code that is included as part of the else statement must be indented the same amount.
A sample if/else code section is below:
In [2]: a = 5
if a>10:
print('a is greater than 10')
else:
print('a is less than 10')
a is less than 10
Since a=5 assigns a value to a that is less than 10, a>10 is False and the code under the if statement
does not run. Therefore, the code under the else statement does run, and a is less than 10 is
printed.
If the value of a is modified so that a is greater than 10, a>10 returns Truethe code under the if
statement will run, and the code under the else keyword will not.
In [3]: a = 20
if a>10:
print('a is greater than 10')
else:
print('a is less than 10')
a is greater than 10
elif
The else if statement can be added to an if statement to run different sections of code depending on
which one of many conditions are True. The basic syntax of an else if section of code is:
if < logical_condition >:
< code block 1 >
elif < logical_condition >:
< code block 2 >
else :
< code block 3 >
The keyword elif must be followed by a logical condition that evaluates as True or False followed
by a colon :. The <code block> runs if the elif condition is True and is skipped if the elif
condition is False.
An example section of code using if, elif and else is below:
7.6. TRY-EXCEPT STATEMENTS 197
If we modify the code to assign the string 'orange' to the variable color, the code under the if is
not run, and the code under the elif is not run either. Only the code under the else is executed.
Syntax Errors
A syntax error is a type of error in Python that occur when the syntax in a line of code is not valid
Python code. Syntax errors include quotes that are not closed and variable names that do not start
with a letter.
The line of code below contains a syntax error. The string "problem solving is missing a quotation
mark ".
When you encounter syntax errors in Python, the Python interpreter displays SyntaxError and
often a cryptic message.
Even if a line of code does not run when a program is executed, syntax errors in Python are not
allowed. For instance, a line of code indented after the if-statement if 'a' == 'b:' will not be
executed. But if the indented line of code contains a syntax error, the Python interpreter still flags
the error as a syntax error and does not complete the program.
Exception Errors
Syntax errors are lines of code that are not valid Python. Another type of error in Python is an
exception error. Exception errors result when a valid line of Python code cannot run. Lines of code
with exception errors contain valid Python code, but the line of code still cannot run.
For example, the statement f = open('file.txt','r') is valid Python code. But if the file file.txt
does not exist, Python throws an exception error because f = open('file.txt','r') code cannot
be executed.
In [3]: f = open('file.txt','r')
---------------------------------------------------------------------------
<ipython-input-3-b0ee218ebbfc> in <module>()
----> 1 f = open('file.txt','r')
Another valid line of Python code is print(a[0]), but if a is defined as an integer, a can not be
indexed and an exception error is shown.
In [4]: a = 1
print(a[5])
---------------------------------------------------------------------------
<ipython-input-4-df093d7733e3> in <module>()
1 a = 1
----> 2 print(a[5])
Try except statements can be used to try run sections of Python code that may return an exception
error. The general syntax of a try except statement is below:
try :
< code to try >
except :
< code to run instead >
For instance, if the file file.txt does not exist, a line of code that tries to open file.txt can be included
in a try statement.
In [5]: try:
f=open('file.txt','r')
except:
print('file does not exist')
Similarly, we can wrap the code a = 5 and print(a[0]) in a try block and attempt to run it. If the
line a = 5 and print(a[0]) throws an exception error, the code below except runs.
In [6]: try:
a = 5
print(a[0])
except:
print('variable a is not a list')
When the Python code in a try block does run and does not throw an exception error, the code in
the except does not run.
In [7]: try:
a = 'Solution'
print(a[0])
except:
print('variable a is not a list')
7.7 Flowcharts
Flowcharts graphically represent the flow of a program. There are four basic shapes used in a flow
chart. Each shape has a specific use:
Arrows connect the basic shapes in a flowchart. The shapes and arrows of a flowchart describe the
flow of a program from start to end. Flowcharts typically flow from the top to the bottom or flow
from the left to the right.
Below is the description of a simple program:
The program starts. Then the program prints out “Output!”. Finally, the program ends.
The program starts. Next, the program asks a user for a number. Two is added to the
number. Next, the resulting sum is printed. Finally, the program ends.
Figure 7.1. Four basic flow chart shapes: oval, parallelogram, rectangle and diamond
202 CHAPTER 7. IF ELSE TRY EXCEPT
Figure 7.3. Flowchart of a program that includes input, output, and a calculation
204 CHAPTER 7. IF ELSE TRY EXCEPT
The program starts. Next the program asks a user for a number. If the number is greater
than zero, the program prints “Greater than 0”, then the program ends.
The program starts. Next, the program asks a user for a number. If the number is
greater than zero, the program prints “Greater than 0”. If the number is less than zero,
the program prints “Less than 0”. Then the program prints “Done” and the program
ends.
Figure 7.4. Flow chart of a program that contains user input and a selection structure
206 CHAPTER 7. IF ELSE TRY EXCEPT
Figure 7.5. Flowchart of a program that contains user input and two if-statements
7.8. SUMMARY 207
7.8 Summary
Selection structures in Python include if, elif, else, try and except. These selection structures
allow certain blocks of code to run or not run based on logical conditions. Logical conditions are
expressions or variables that can be evaluated as True or False. You learned that Python uses
indentation segment code after if, elif, and else statements. The standard indentation in Python
is four spaces.
The difference between syntax errors and exception errors was demonstrated in this chapter.
try/except blocks only check for exception errors.
At the end of the chapter, you learned how to use flowcharts to describe the flow of a program with
four basic shapes and arrows.
Q07.04 Create a program that asks a user for two numbers, x and y. If the x is greater than y, print
back to the user “x>y”. If x is less than y, print back to the user “x<y”. If x is equal to y, print back
to the user “x=y”.
Q07.05 Create a program that asks a user for one of three trig functions: sine, cosine or tangent.
Calculate the sine, cosine or tangent of π/4 depending on the user’s input and print the result of
208 CHAPTER 7. IF ELSE TRY EXCEPT
fruit color
banana yellow
apple red
lemon yellow
lime green
orange orange
Create a program that asks a user to choose from a list of fruit. Print pack to the user the color of
the fruit they chose.
Q07.08 The average size of a US congressional district is about 700,000 people. Ask the user for
a state population and print back to the user the number of congress members in the state. For
example a state with 1.4 million people is represented by 2 members of congress. Each state has at
least one member of congress by default. If the user enters a population less than 700,000, tell the
user their state only has 1 member of congress.
Q07.08 In a college engineering class, final grades are related to percentages as follows:
Build a program that asks a user for a final score (in percent) and prints back to the user their letter
grade.
Run the following code snippets. Explain the error in your own words. Rewrite the code snippet
to solve the error.
Q07.80
a = 1
if a = 0:
print ( ' zero ')
else if a = 1:
print ( ' one ')
Q07.81
7.9. REVIEW QUESTIONS 209
a = 1
if a == 0:
print ( ' zero ')
Q07.82
n = input ( ' Enter a number ')
if n > 0:
print ( ' positive ')
210 CHAPTER 7. IF ELSE TRY EXCEPT
Chapter 8
Loops
8.1 Introduction
By the end of this chapter you will be able to:
211
212 CHAPTER 8. LOOPS
One way to accomplish this task is by coding three print statements in a row:
Another way to accomplish the same task is to use a for loop. The basic structure of a for loop in
Python is below:
for <var > in range ( < num >):
< code >
Where <var> can be any variable, range(<num>) is the number of times the for loop runs and
<code> are the lines of code that execute each time the for loop runs. Note the for loop starts with
the keyword for and includes a colon :. Both for and the colon : are required. Also, note <code> is
indented. Each line of code that runs as part of the for loop needs to be indented the same number
of spaces. Standard indentation in Python is four spaces.
The example above can be rewritten using a for loop:
range() function
Python’s range() function returns an iterable list of values starting at zero and ending at n-1. For
example, when range(3) is called, the values 0, 1, 2 are returned. Note 3 is not part of the output,
8.2. FOR LOOPS 213
even though the function input was range(3). We can be confirm the behavior of range() with a
for loop:
0
1
2
Customizing range()
Python’s range() function can be customized by supplying up to three arguments. The general
format of the range function is below:
range ( start , stop , step )
A code section that uses a for loop and range() with three arguments is below:
5
6
7
8
Where <var> is a variable name assigned to the item in the list and <list> is the list object. Re-
member to include a colon : after the list. <code> is the programming code that runs for each item
in the list.
An example of a list in a for loop is below:
electrical
civil
mechanical
The loop ran three times because there are three items in the list. Each time through the loop, the
variable item is set to one of the items in the list.
Where <char> is one of the characters in the string <string>. Just like for loops with range() and
for loops with lists, make sure to include a colon : after the list. <code> is the programming code
that runs for each character in the string. <code> needs to be indented
An example of a string in a for loop is below:
The keyword while must be included, as well as a <logical_condition> which can be evaluated
as True or False. The <code> after the while statement must be indented. Each line of code runs
in the while loop needs to be indented the same number of spaces. (Many code editors, including
Jupyter notebooks, auto-indent after a while loop statement) If you add indentation manually, four
space spaces is the Python standard.
An example of a while loop is below:
In [1]: i = 0
while i<4:
print(i)
i = i+1
0
1
2
3
The first line i=0 creates the variable i and assigns it the value 0. The next line declares the logical
condition needed to keep the loop running. The statement i<4 is True or False depending on the
variable i. Since i=0, the statement i<4 is True and the while loop starts to run. The code inside
while the loop prints the value of i then increases i by 1. When i=4, the statement i<4 is False
and the while loop ends.
In [2]: num_input = -1
while num_input < 0:
str_input = input('Enter a positive number: ')
num_input = float(str_input)
In the section of code above, it is important to initialize the variable num_input with a value that
causes the statement num_input < 0 to evaluate as True. num_input = -1 causes the statement
num_input < 0 to evaluate as True. Besides num_input = -1, any other negative number would
have worked. If the while statement can’t be evaluated as True or False, Python throws an error.
Therefore, it is necessary to convert the user’s input from a string to a float. The statement '5' < 0
does not evaluate to True or False, because the string '5' can’t be compared to the number 0.
Break
In Python, the keyword break causes the program to exit a loop early. break causes the program to
jump out of for loops even if the for loop hasn’t run the specified number of times.break causes the
program to jump out of while loops even if the logical condition that defines the loop is still True.
An example using break in a for loop is below.
0
1
2
3
Loop exited
When the loop hits i=3, break is encountered and the program exits the loop.
An example using break in a while loop is below.
Continue
In Python, the keyword continue causes the program to stop running code in a loop and start back
at the top of the loop. Remember the keyword break cause the program to exit a loop. continue is
similar, but continue causes the program to stop the current iteration of the loop and start the next
iteration at the top of the loop.
A code section that uses continue in a for loop is below.
0
1
3
When the code section is run, the number 2 is not printed. This is because when i=2 the program
hits the continue statement. Therefore, the line print(i) isn’t run when i=2. Then the program
starts back up to the start of the loop with the next number i=3.
Flowcharts show the flow of a program graphically. Flow charts were introduced in the previous
chapter to describe how a programs that include if statements are illustrated graphically.
This chapter is about loops. Flowcharts can also be used to describe programs which contain for
loops and while loops.
The basic shapes in a flowchart are connected by arrows. The shapes and arrows in a flowchart
represent the flow of a program from start to end.
Figure 8.1. Four the four flowchart shapes: oval, parallelogram, rectangle, and diamond
8.5. FLOWCHARTS DESCRIBING LOOPS 219
The program starts. The program prints the word “looping” 10 times. Finally, the pro-
gram ends.
# start
for i in range (10):
print ( " looping " )
# end
220 CHAPTER 8. LOOPS
The program starts. The program asks the user for a positive number. If the number the
user enters is negative, the program asks the user for a positive number again. If the
number the user enters is positive, the program prints “positive”. Finally, the program
ends.
8.6 Summary
Repetition structures allow the same piece of code to run multiple times.
In this chapter, you learned how to write for loops and while loops in Python. You learned how
to use Python’s range() function in a for loops and how to use a list or string in a for loop. For
loops run a block of code a definite number of times. A while loop runs a block of code as long as a
logical condition is true. The keywords break and continue cause for and while loops to exit early.
At the end of the chapter, you learned how to build flowcharts that describe programs with for
loops and while loops.
For Loops
(b) Use a for loop to print out all the numbers 1 to 30, but leave out any number which is divisible
by 3, such as 3,6 and 9.
(c) Use a for loop to print out all the numbers 1 to 30, but leave out any number which is divisible
by 5, such as 5,10 and 15.
(d) Use a for loop to print out all the numbers 1 to 30, but insert the word fizz for any number
that is divisible by 3, insert the word buzz for any number that is divisible by 5 and insert the
word fizz buzz for any numbers that are both divisible by 3 and 5, like 15.
Q 08.07 Imagine you can see the future of investing and over the next five years, the interest rate
of return on investments is going to be 0.05, 0.07, 0.1, 0.3. Prompt the user for an initial investment
and use the formula below to calculate how much the investment is worth each year.
new balance = old balance + old balance × interest rate
8.7. REVIEW QUESTIONS 223
Q 08.07 Imagine you can see the future of investing and over the next four years, the interest rate of
return on investments is going to be 0.02, 0.03, 0.015, 0.1. Prompt the user for an initial investment
with Python’s input(_) function and use the formula below to calculate how much the investment
will be worth after four years.
new balance = old balance + old balance × interest rate
Note the first “old balance” is the person’s initial investment.
Q 08.08 A geometric series is a series that has a common ratio between the terms. The sum of the
geometric series that starts at 12 and has a common ratio of 12 approaches the value 1.
The formula that shows the sum of a geometric series which approaches 1 is below.
1 1 1 1
1= + + + + ...
2 4 8 16
Use the geometric series above to approximate the value of 1 after 10 terms are added. Print out
how far off the geometric series approximation is to 1.
Q 08.09 A Taylor Series is an infinite series of mathematical terms that when summed together
approximate a mathematical function. A Taylor Series can be used to approximate e x , sine, and
cosine.
Taylor Series expansion for the function e x is below:
∞
xn x2 x3 x4
ex = ∑ n!
= 1+x+
2!
+
3!
+
4!
+ ...
n =0
Write a program that asks a user for a number x, then calculates e x using the Taylor Series expan-
sion. Calculate 20 terms.
While Loops
Q08.40 Use a for loop to sum the elements in the list [1,3,5,8,12]. Print the sum to the user.
Q08.41 Use a while loop to print out the numbers between 1 and 100 that have whole number
square roots.
Q08.42 Create a program that prompts a user for test scores. Continue to prompt the user for
additional test scores until the user types 'q'. When the user types 'q', the program stops asking
the user for test scores and prints out the following statistics about the test scores the user entered:
• mean
• median
• standard deviation
Q08.43 Use while loop to validate user input. Ask the user to enter a value between 0 and 1. Print
back to the user “Try again” if the user’s input is invalid. Print “Your number works!” when the
user enters valid input.
Q08.44 Use a while loop to validate user input. Ask the user to enter a day of the week. Keep
asking the user for a day of the week until they enter one. When the user enters a day of the week,
print back to the “Yup, it’s <day of the week>”.
224 CHAPTER 8. LOOPS
Q08.45 Write a program to play the game higher/lower. Tell the user you have picked a random
integer between 1 and 20.
The code below creates a random integer n between 1 and 20:
from random import randint
n = ( randint (1 , 20))
(a) Ask the user to enter a number (one time) and tell the user if the number random is higher or
lower. Print higher if the random number is higher than the user’s guess, print lower if the
random number is lower than the user’s guess. Print You guessed it:“‘ if the user guesses
the random number.
(b) Modify your program so that the program keeps printing higher or lower after each guess
until the user guesses the random number. When the user guesses the random number print
You guessed it:“‘.
(c) Extend your higher/lower game to record the number of guesses the user enters to guess the
random number. Then the user guesses the random number print You guessed:tries.
Q 08.46 A Taylor Series is an infinite series of mathematical terms that when summed together
approximate a mathematical function. A Taylor Series can be used to approximate e x , sine, and
cosine.
Taylor Series expansion for the function e x is below:
∞
xn x2 x3 x4
ex = ∑ n!
= 1+x+
2!
+
3!
+
4!
+ ...
n =0
Write a program that asks a user for a number x, then calculates e x using the Taylor Series expan-
sion. Continue to add terms to the Taylor Series until the result from the Taylor series is less than
0.001 off the value of e x calculated with Python’s math.exp() function.
Run the following code snippets. Explain the error in your own words. Rewrite the code snippet
to solve the error.
Q08.80
n = [1 2 3]
for n [1] == 2:
n = n + 1
end
Q08.81
while x in [1 , 2 , 3]:
print ( x )
Q08.82
8.7. REVIEW QUESTIONS 225
n = 1
while 1 == n
print ( ' valid ')
n = n +1
Q08.83
for i in range (3):
print ( i )
226 CHAPTER 8. LOOPS
Chapter 9
9.1 Introduction
By the end of this chapter you will be able to:
227
228 CHAPTER 9. MATRICIES AND ARRAYS
Out[1]: '1.14.3'
9.3 NumPy
NumPy is a Python package used for numerical calculations, working with arrays of homogeneous
values, and scientific computing. This section introduces NumPy and arrays then explains the
difference between Python lists and NumPy arrays.
9.3. NUMPY 229
The Python list above contains four different data types: 1 is an integer, -0.038 is a float, 'gear' is
a string, and 'True' is a boolean.
The code below prints the data type of each value store in python_list.
<class 'int'>
<class 'float'>
<class 'str'>
<class 'bool'>
The values stored in a NumPy array must all share the same data type. Consider the NumPy array
below:
np . array ([1.0 , 3.1 , 5e -04 , 0.007])
All four values stored in the NumPy array above share the same data type: 1.0, 3.1, 5e-04, and
0.007 are all floats.
The code below prints the data type of each value stored in the NumPy array above.
<class 'numpy.float64'>
<class 'numpy.float64'>
<class 'numpy.float64'>
<class 'numpy.float64'>
If the same four elements stored in the previous Python list are stored in a NumPy array, NumPy
forces all of the four items in the list to conform to the same data type.
In the next code section, all four items are converted to type '<U32', which is a string data type in
NumPy (the U refers Unicode strings; all strings in Python are Unicode by default).
230 CHAPTER 9. MATRICIES AND ARRAYS
Out[4]: [1, 2, 3, 4, 1, 2, 3, 4]
To multiply each element of a Python list by the scalar number 2, a loop can be used:
Out[5]: [2, 4, 6, 8]
The method above is relatively cumbersome and is also quite computationally expensive. An opera-
tion that is computationally expensive is an operation that takes a lot of processing time or storage
resources like RAM or CPU bandwidth.
Another way of completing the same action as the loop above is to use a NumPy array.
An entire NumPy array can be multiplied by a scalar in one step. The scalar multiplication opera-
tion below produces an array with each element multiplied by the scalar 2.
If we have a very long list of numbers, we can compare the amount of time it takes each of the
two computation methods above to complete the same operation. We’ll compare the Python list
calculation to the NumPy array calculation.
Jupyter notebooks have a nice built-in way to time how a line of code takes to execute. In a Jupyter
notebook, when a line starts with %timeit followed by code, the notebook runs the line of code
multiple times and outputs an average of the time spent to execute the line of code.
We can use %timit to compare a mathematical operation on a Python list using a for loop to the
same mathematical operation on a NumPy array.
9.4. ARRAY CREATION 231
4.47 ms ś 1.41 ms per loop (mean ś std. dev. of 7 runs, 1000 loops each)
11.9 ţs ś 155 ns per loop (mean ś std. dev. of 7 runs, 100000 loops each)
With 10,000 integers, the Python list and for loop takes an average of single milliseconds, while the
NumPy array completes the same operation in tens of microseconds. This is a speed increase of
over 100x by using the NumPy array (1 millisecond = 1000 microseconds).
For larger lists of numbers, the speed increase using NumPy is considerable.
The data type can be passed into the np.array() function as a second optional positional argu-
ments. Available data types include 'int64', 'float', 'complex' and '>U32' (string data type).
The data type store in a NumPy array can be determined using the .dtype method. For instance,
an array of floats returns float64.
Out[3]: dtype('float64')
232 CHAPTER 9. MATRICIES AND ARRAYS
np.arange()
NumPy’s np.arange() function creates a NumPy array according the arguments start, stop,step.
my_array = np . arange ( start , stop , step )
The np.arange() function is useful for creating an array of regularly spaced numbers where you
know the step size.
Consider creating a NumPy array of even numbers between 0 and 10. Note that just like counting
in Python, counting in NumPy starts at 0 and ends at n-1.
In [4]: np.arange(0,10+2,2)
np.linspace()
NumPy’s np.linspace() function creates a NumPy array according the arguments start,
stop,number of elements.
my_array = np . linspace ( start , stop , number of elements )
The np.linspace() function is useful for creating an array of regularly spaced numbers where the
spacing is not known, but the number of values is. Consider creating a NumPy array of 10 numbers
between 0 and 2pi.
In [5]: np.linspace(0,2*np.pi,10)
np.logspace()
NumPy’s np.logspace() function creates a NumPy array according the arguments start,
stop,number of elements, but unlike np.linspace(), np.logspace() produces a logarithmically
spaced array.
my_array = np . logspace ( start , stop , number of elements , base = < num >)
This function is useful for creating an array of logarithmically spaced numbers where the spacing
interval is not known but the number of values is. Consider creating a NumPy array of 4 loga-
rithmically spaced numbers between 10 and 100. The function call is np.logspace(1, 2, 4). The
start is 101 = 10 and the stop is 102 = 100. Be careful about putting large numbers in for stop
because the argument is the power of 10, not the stop value.
9.4. ARRAY CREATION 233
In [6]: np.logspace(1, 2, 4)
np.zeros()
NumPy’s np.zeros() function creates a NumPy array containing all zeros of a specific size.
np.zeros() is useful when the size of an array is known, but the values that will go into the array
have not been created yet.
my_array = np . zeros (( rows , cols ))
In [7]: np.zeros((5,5))
np.ones()
NumPy’s np.ones() function creates a NumPy array containing all 1’s of a specific size. Like
np.zeros(), np.ones() is useful when the size of an array is known, but the values that will go
into the array have not been created yet.
my_array = np . ones (( rows , cols ))
In [8]: np.ones((3,5))
Arrays of random integers can be created with NumPy’s np.random.randint() function. The gen-
eral syntax is:
np . random . randint ( lower limit , upper limit , number of values )
To create an array of 5 different random numbers, each random number between 1 and 10:
234 CHAPTER 9. MATRICIES AND ARRAYS
In [9]: np.random.randint(0,10,5)
Array dimensions can be provided as the third argument. A 5 × 5 array of random numbers
between 1 and 10:
In [10]: np.random.randint(0,10,[5,5])
Arrays of random floating point numbers can be created with NumPy’s np.random.rand() func-
tion. The general syntax is:
np . random . rand ( number of values )
In [11]: np.random.rand(5)
In [13]: np.random.randn(10)
9.4. ARRAY CREATION 235
To specify a mean mu and a standard deviation sigma, the function can be wrapped with:
In [14]: mu = 70
sigma = 6.6
sigma * np.random.randn(10) + mu
Matplotlib’s plt.hist() function can be used to quickly plot a normal distribution created with
NumPy’s np.random.randn() function.
mu = 70
sigma = 6.6
2-D Arrays
np.meshgrid()
NumPy’s np.meshgrid() function takes in two positional arguments which are 1D NumPy arrays.
The two input arrays do not have to contain the same number of elements. The outputs of the
np.meshgrid() function are two 2D arrays. One of the 2D arrays has the same values in each row;
the other 2D array has the same values in each column.
np . meshgrid ( array1 , array2 )
In [16]: x = np.arange(0,6)
y = np.arange(0,11,2)
X, Y = np.meshgrid(x,y)
print(X)
print(Y)
[[0 1 2 3 4 5]
[0 1 2 3 4 5]
[0 1 2 3 4 5]
[0 1 2 3 4 5]
[0 1 2 3 4 5]
[0 1 2 3 4 5]]
[[ 0 0 0 0 0 0]
[ 2 2 2 2 2 2]
[ 4 4 4 4 4 4]
[ 6 6 6 6 6 6]
[ 8 8 8 8 8 8]
[10 10 10 10 10 10]]
np.mgrid[]
NumPy’s np.mgrid[] function is similar to np.meshgrid(), but has a “MATLAB-like” syntax and
behavior.
Use square brackets [ ] after the np.mgrid function name. Separate the two “lists” passed as input
arguments with a comma and use the start:stop:step indexing method. The outputs of the
np.mgrid[] function are two 2D arrays. The first 2D array have the same values in each row; the
second 2D array has the same values in each column.
np . mgrid [ start : stop : step , start : stop : step ]
In [17]: X, Y = np.mgrid[0:5,0:11:2]
print(X)
print(Y)
9.5. ARRAY INDEXING 237
[[0 0 0 0 0 0]
[1 1 1 1 1 1]
[2 2 2 2 2 2]
[3 3 3 3 3 3]
[4 4 4 4 4 4]]
[[ 0 2 4 6 8 10]
[ 0 2 4 6 8 10]
[ 0 2 4 6 8 10]
[ 0 2 4 6 8 10]
[ 0 2 4 6 8 10]]
Section Summary
Below is a list of NumPy function descriptions used in this section.
Function Description
np.array([list,of,numbers]) Array from a list
np.arange(start,stop,step) Array with know step
np.linspace(start, stop, num) Array with known num
np.logspace(start,stop,num) Logorithmically spaced array
np.zeros((rows,cols)) Array of zeros
np.ones((rows,cols)) Array of ones
np.random.randint(start, stop, num) Random integers
np.random.rand(num) Random float 0 to 1
np.random.choice(list,num) Randome choice from a list
np.random.randn(num) Random normal distribution
np.meshgrid(array1,array2) Two 2D arrays from two 1D arrays
np.mgrid[start:stop:step, start:stop:step] MATLAB meshgrid
a = np.array([2,4,6])
The array above contains three values: 2, 4 and 6. Each of these values has a different index.
Remember counting in Python starts at 0 and ends at n-1.
The value 2 has an index of 0. 2 is in the 0 location of the array. The value 4 has an index of 1 and
the value 6 has an index of 2. The table below shows the index of each value in the array.
238 CHAPTER 9. MATRICIES AND ARRAYS
Where <value> is the value stored in the array, <array> is the array object name and [index]
specifies the index or location of that value.
In the array above, the value 6 is stored at index 2.
a = np.array([2,4,6])
value = a[2]
print(value)
a = np.array([[2,3,4],[6,7,8]])
print(a)
[[2 3 4]
[6 7 8]]
Values in a 2-D array can be accessed using the general notation below:
< value > = < array >[ row , col ]
Where <value> is the value pulled out of the 2-D array and [row,col] specifies the row and column
index of the value. Remember Python counting starts at 0, so the first row is row zero and the first
column is column zero.
We can access the value 8 in the array above by calling the row and column index [1,2] for the 2nd
row (remember row 0 is the first row) and the 3rd column (remember column 0 is the first column).
9.5. ARRAY INDEXING 239
a = np.array([[2,3,4],[6,7,8]])
value = a[1,2]
print(value)
Where <value> is the new value going into the array and [index] is the location the new value
will occupy.
The code below puts the value 10 into the second index or location of the array a.
[ 2 4 10]
Values can also be assigned to a particular location in a 2-D arrays using the form:
< array >[ row , col ] = < value >
The code example below shows the value 20 assigned to the 2nd column and 3rd row of the array.
a = np.array([[2,3,4],[6,7,8]])
print(a)
a[1,2]=20
print(a)
[[2 3 4]
[6 7 8]]
[[ 2 3 4]
[ 6 7 20]]
240 CHAPTER 9. MATRICIES AND ARRAYS
Multiple values stored within an array can be accessed simultaneously with array slicing. To pull
out a section or slice of an array, the colon operator : is used when calling the index. The general
form is:
< slice > = < array >[ start : stop ]
Where <slice> is the slice or section of the array object <array>. The index of the slice is specified
in [start:stop]. Remember Python counting starts at 0 and ends at n-1. The index [0:2] pulls
the first two values out of an array. The index [1:3] pulls the second and third values out of an
array.
An example of array slicing the first two elements out of an array is below.
a = np.array([2, 4, 6])
b = a[0:2]
print(b)
[2 4]
A blank stands in for the last index. The slicing operation [1:] pulls out the 2nd through the last
values of an array.
a = np.array([2, 4, 6, 8])
b = a[1:]
print(b)
[4 6 8]
A blank also stands in for the first index. The slicing operation [:3] pulls out the first through third
values of an array.
a = np.array([2, 4, 6, 8])
b = a[:3]
print(b)
[2 4 6]
9.7. ARRAY OPERATIONS 241
Slicing 2D Arrays
2D NumPy arrays can be sliced with the general form:
< slice > = < array >[ start_row : end_row , start_col : end_col ]
The code section below creates a two row by four column array and indexes out the first two rows
and the first three columns.
[[ 2 4 6]
[10 20 30]]
Again, a blank represents the first index or the last index. The colon operator also represents “all”.
The code section below slices out the first two rows and all columns from array a.
[[ 2 4 6 8]
[10 20 30 40]]
Scalar Addition
Scalars can be added and subtracted from arrays and arrays can be added and subtracted from
each other:
a = np.array([1, 2, 3])
b = a + 2
print(b)
242 CHAPTER 9. MATRICIES AND ARRAYS
[3 4 5]
[3 6 9]
Scalar Multiplication
NumPy arrays can be multiplied and divided by scalar integers and floats:
In [3]: a = np.array([1,2,3])
b = 3*a
print(b)
[3 6 9]
In [4]: a = np.array([10,20,30])
b = a/2
print(b)
[ 5. 10. 15.]
Array Multiplication
NumPy array can be multiplied by each other using matrix multiplication. These matrix multipli-
cation methods include element-wise multiplication, the dot product, and the cross product.
Element-wise Multiplication
Dot Product
Out[6]: 32
Cross Product
np.exp()
Logarithms
In [9]: np.log(np.e)
Out[9]: 1.0
In [10]: np.log2(16)
Out[10]: 4.0
In [11]: np.log10(1000)
Out[11]: 3.0
244 CHAPTER 9. MATRICIES AND ARRAYS
Trigonometry
NumPy also contains all of the standard trigonometry functions which operate on arrays.
• np.sin() - sin
• np.cos() - cosine
• np.tan() - tangent
• np.asin() - arc sine
• np.acos() - arc cosine
• np.atan() - arc tangent
• np.hypot() - given sides of a triangle, returns hypotenuse
NumPy contains functions to convert arrays of angles between degrees and radians.
In [13]: a = np.array([np.pi,2*np.pi])
np.rad2deg(a)
8x + 3y − 2z = 9
−4x + 7y + 5z = 15
3x + 4y − 12z = 35
NumPy’s np.linalg.solve() function can be used to solve this system of equations for the vari-
ables x, y and z.
The steps to solve the system of linear equations with np.linalg.solve() are below:
The resulting array has three entries. One entry for each variable.
We can plug the valuse of x, y and z back into one of the equations to check the answer.
x is the first entry of the array, y is the second entry of the array, and z is the third entry of the array.
x = x[0]
y = x[1]
z = x[2]
When these values are plugged into the equation from above:
8x + 3y − 2z = 9
Out[2]: 9.0
246 CHAPTER 9. MATRICIES AND ARRAYS
9.9 Summary
In this chapter, you learned how to work with NumPy arrays. NumPy is a Python package used
for numerical calculations and arrays. An array is a data structure only contains objects that share
the same data type. Arrays are faster than lists in large-scale numerical calculations.
You learned how to create arrays in a variety of ways:
You learned how to index and slice arrays. Slicing NumPy arrays share the same syntax used to
slice Python lists and strings.
At the end of the chapter, you learned how to run mathematical operations on arrays. NumPy’s
mathematical functions operate on arrays like Python’s math functions operate on integers and
floats. NumPy has additional functions like np.dot() and np.cross() that cannot be applied to
scalars. NumPy’s np.linalg.solve() function can be used to solve systems of linear equations.
Array Creation
Meshgrids
Q09.40 Create two 2D arrays from the two 1D arrays below using NumPy’s np.meshgrid() func-
tion.
y = [0 , 2 , 4 , 6]
x = [1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10]
y = [1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10]
Use element-wise multiplication to multiple each element in one of the resulting 2D arrays with
the other resulting 2D array to build a multiplication table.
Array Operations
Q09.50 Create the two arrays below and perform each calculation.
a = [2 4 6]
b = [-1 0 1]
(a) a + b
(b) 1.5a − 2b
(c) 0.5ab
b2
(d) a
Q09.52 Create the two arrays below and then perform the following operations.
F1 = [-1, 0, 2]
F2 = [5, -2, 0]
Linear Algebra
Q09.70 Use the system of linear equations below to calculate the values of x and y.
4x − 2y = −42
−6x + y = 31
Q09.70 Use the system of linear equations below to calculate the values of x, y and z.
x
+ 2y − z = 5
2
x + 3y − 4z = −1
− x − 3y + 2z = −5
Chapter 10
Symbolic Math
10.1 Introduction
By the end of this chapter you will be able to:
249
250 CHAPTER 10. SYMBOLIC MATH
10.2 SymPy
SymPy http://www.sympy.org is a Python library for symbolic math.
In symbolic math, symbols are used to represent mathematical expressions. An example of a sym-
bolic math expression is below.
x 2 + y2 = z
x = a+b
( a + b )2 + y2 = z
a2 + 2ab + b2 + y2 = z
In the symbolic math substitution above, symbolic math variables were rearranged, grouped and
inserted. None of the variables were equal to a specific number, like 5 or 0.001, but you can still
solve for one variable in terms on the other variables.
If we have numerical values for z, a and b, we can use Python to calculate the value of y.
But if we don’t have numerical values for z, a and b, Python and the SymPy package can be used
to rearrange terms and solve for one variable in terms of the other.
Working with mathematical symbols in a programmatic way instead of working with numerical
values in a programmatic way is called symbolic math.
To work with symbolic math in Python, the SymPy library needs to be installed. SymPy comes pre-
installed with the Anaconda distribution of Python. If you are not using the Anaconda distribution
of Python, SymPy can be installed with the Anaconda Prompt. Use the command:
> conda install sympy
To define symbolic math variables with SymPy, first import the symbols() function from the SymPy
module:
Symbolic math symbols are declared using SymPy’s symbols() function. A string is passed to the
symbols() function as an input argument and the output is assigned to a SymPy symbols object
(not a string).
In [2]: x = symbols('x')
y = symbols('y')
SymPy’s symbol() function can define multiple symbols in the same line of code. Note the input ar-
guments passed to the symbols() function is a string, entries separated by a space (no comma) and
surrounded by quotes. The output of the symbols() function are SymPy symbol objects. Commas
separate these output objects (no quotation marks).
Expressions
A symbolic math expression is a combination of symbolic math variables with numbers and math-
ematical operators (such as +,-,/ and *. The standard Python rules for calculating numbers apply
in SymPy symbolic math expressions.
After the symbols x and y are created, a symbolic math expression using x and y can be created.
x, y = symbols('x y')
expr = 2*x + y
Substitution
Use SymPy’s .subs() method to insert a numerical value into a symbolic math expression. The
first argument of the .subs() method is the variable and the second argument is the numerical
value. In the expression above:
2x + y
If we substitute
252 CHAPTER 10. SYMBOLIC MATH
x=2
2(2) + y
4+y
In [2]: expr.subs(x, 2)
Out[2]: y + 4
The .subs() method does not replace variables in place, it only completes a one-time substitution.
If expr is called after the .subs() method is applied, the original expr expression is returned.
In [3]: expr
Out[3]: 2*x + y
To make the substitution permanent, a new expression object needs to be assigned to the output of
the .subs() method.
Out[4]: y + 4
SymPy variables can also be substituted into SymPy expressions. In the code section below, the
symbol z is substituted for the symbol x (z replaces x).
Out[5]: y + 2*z
Expressions can also be substituted into other expressions. Consider the following:
2x + y
substitute in
y = 2x2 + z−3
results in
2x + 2x2 + z−3
10.4. EXPRESSIONS AND SUBSTITUTIONS 253
A practical example involving symbolic math variables, expressions and substitutions could in-
clude a large equation and several replacements.
n0 e−Qv /RT
n0 = 3.48 × 10−6
Qv = 12, 700
R = 8.31
T = 1000 + 273
Multiply SymPy subs() methods can be chained together to substitute multiple variables in one
line of code.
Out[8]: 3.48e-6*exp(-12700/10223463)
In [10]: expr2.evalf()
Out[10]: 3.47567968697765e-6
254 CHAPTER 10. SYMBOLIC MATH
10.5 Equations
You can define equations using SymPy using symbolic math variables. Equations in SymPy are
different than expressions. An expression does not have equality. An expression is a collection of
symbols and operators, but expressions are not equal to anything. Equations have equality. An
equation can be thought of as an expression equal to something else.
A code section that defines the equation 4x + 2 = 0 is below. Note all equations defined in SymPy
are assumed to equal zero.
x = symbols('x')
eq1 = Eq(4*x+2)
If you want to define the equation 2y − x = 5, which is not equal to zero, you just have to subtract
the right hand side of the equation from the left hand side of the equation first.
2y − x = 5
2y − x − 5 = 0
eq2 = 2*y - x -5
Substitutions in Equations
Symbols and expressions can be substituted into equations. In the code section below, the variable
z is substituted in for the variable x (z replaces x).
eq2 = 2*y - x -5
eq3 = eq2.subs(x,z)
eq3
Out[3]: 2*y - z - 5
SymPy’s solve() function can be used to solve equations and expressions that contain symbolic
math variables.
10.6. SOLVING EQUATIONS 255
x = symbols('x')
expr = x-4-2
sol = solve(expr)
sol
Out[1]: [6]
To pull the value out of the list, regular list indexing can be used.
num
Out[2]: 6
The code section below demonstrates SymPy’s solve() function when an equation is defined with
symbolic math variables.
y = symbols('y')
eq1 = Eq(y + 3 + 8)
sol = solve(eq1)
sol
Out[3]: [-11]
Quadratic equations, like x2 − 5x + 6 = 0, have two solutions. SymPy’s solve() function can be
used to solve an equation with two solutions. When an equation has two solutions, SymPy outputs
a list. The elements in the list are the two solutions.
The code section below shows how SymPy’s solve() function solves an equation with two solu-
tions.
256 CHAPTER 10. SYMBOLIC MATH
y = symbols('x')
eq1 = Eq(x**2 -5*x + 6)
sol = solve(eq1)
sol
Out[4]: [2, 3]
If you specify the keyword argument dict=True to SymPy’s solve() function, the output is still a
list, but inside the list is a dictionary that shows which variable was solved for.
y = symbols('x')
eq1 = Eq(x**2 -5*x + 6)
In [6]: sol[0]
Out[6]: {x: 2}
In [7]: sol[1]
Out[7]: {x: 3}
x+y−5 = 0
x−y+3 = 0
To solve this system of two equations for the two unknowns, x and y, first import the SymPy
package. From the SymPy package, the functions symbols, Eq and solve are needed.
Next, create two SymPy symbols objects, x and y. As shown in a previous section, the string passed
as an input argument to the symbols() function, 'x y', does not have any commas. The outputs
of the symbols() function are the two symbol objects x and y. These outputs must be separated by
a comma and are not surrounded by quotes.
We can use SymPy’s solve() function to compute the value of x and y. The first argument passed
to the solve() function is a tuple of the two equations (eq1, eq2). The second argument passed
to the solve() function is a tuple of the variables we want to solve for (x, y).
Out[4]: {x: 1, y: 4}
The solution is in the form of a Python dictionary. The dictionary keys are the variables and the
dictionary values are the numerical solutions.
We can access the solution out of the solution dictionary using regular dictionary indexing.
x = 1
y = 4
GIVEN:
A weight of 22 lbs is hung from a ring. The ring is supported by two cords. The first cord, cord CE,
is 30 degrees above the horizontal and to the right. The second cord, cord BD, is 45 degrees to the
left and above the horizontal.
w = 22 lb
TCE @ +30 degrees CCW relative to +x-axis
TBD @ +45 degress CW relative to -x-axis
258 CHAPTER 10. SYMBOLIC MATH
FIND:
SOLUTION:
To solve for the magnitude of TCE and TBD , you need to solve to two equations for two unknowns.
To accomplish this with SymPy, first import NumPy and SymPy. The SymPy functions symbols, Eq
and solve are needed.
Next, define the symbolic math variables. Multiple symbolic math variables can be defined at the
same time. Remember the argument names (on the right-hand side of the assignment operator =)
need to be enclosed in quotes' ' and separated by spaces, no commas. The object names (on the
left-hand side of the assignment operator =) are separated with commas, no quotes.
Σ⃗F = 0
ΣFx = 0
ΣFy = 0
⃗ = 0î − 22 ĵ
w
The first equation, based on the sum of the forces in the x-direction (the î terms) is:
This equation can be represented as a SymPy equation object. Note the right-hand side of the equa-
tion is 0. SymPy equation objects are instantiated with expressions equal to zero. If the expression
was not equal to zero, simply subtract both sides by the term on the right-hand side of the equals
sign and use the resulting expression (equal to zero) to create the SymPy equation object.
Eq(-0.707106781186548*Tbd + 0.866025403784439*Tce, 0)
The second equation, based on the sum of the forces in the y-direction is:
Now solve the two equations for Tce and Tbd with SymPy’s solve() method. The first argument
passed to the solve() method is a tuple of equations to solve, the argument passed to the solve()
method is a tuple of the variables to solve for.
The solution is saved in a Python dictionary. The dictionary keys are the variable names and the
dictionary values are the numerical solutions.
The numerical solutions can be pulled out of the dictionary using regular Python dictionary access.
Note Tce and Tbd are SymPy symbols objects, not strings.
260 CHAPTER 10. SYMBOLIC MATH
Tce = 16.1051177665153
Tce = 19.7246603876972
The same problem can be solved again, but with w kept as a variable.
eq1=Eq(Tce*np.cos(np.radians(30)) - Tbd*np.cos(np.radians(45)))
eq2=Eq(Tce*np.sin(np.radians(30)) + Tbd*np.sin(np.radians(45))-w)
solve((eq1,eq2),(Tce,Tbd))
10.8 Summary
In this chapter, you learned about symbolic math and how to complete symbolic math calculations
with the SymPy package. Symbolic math treats variables as mathematical symbols rather than
defining variables as defined numbers.
You learned how to create symbolic math variables with SymPy’s symbols() function.
Symbolic math variables can be combined into symbolic math expressions and symbolic math
equations. You learned how to substitute variables and numbers into symbolic math expressions
and equations.
At the end of the chapter, you learned how to solve linear and quadratic equations with SymPy.
The final example in the chapter was a multi-variable statics problem where two variables were
solved for two unknowns.
Solving Equations
−3x − 2y + 7 = 0
5x − 3y − 6 = 0
Q10.04 Use SymPy to solve the system of non-linear equations below for the variables x and y:
17
3x2 + 2y3 = −
4
− x3 127
− 8y2 + =0
2 2
262 CHAPTER 10. SYMBOLIC MATH
Chapter 11
11.1 Introduction
By the end of this chapter you will be able to:
263
264 CHAPTER 11. PYTHON AND EXTERNAL HARDWARE
11.2 PySerial
PySerial is a Python package that facilitates serial communication. A computer running Python
with the PySerial package installed can communicate with external hardware. PySerial is a useful
package for problem solvers because it allows us to exchange data between computers and pieces
of external hardware such as voltmeters, oscilloscopes, strain gauges, flow meters, actuators, and
lights.
PySerial provides an interface to communicate over the serial communication protocol. Serial com-
munication is one of the oldest computer communication protocols. Serial communication protocol
predates the USB specification used by computers and other pieces of hardware like mice, key-
boards, and webcams. USB stands for Universal Serial Bus. USB and is built upon and extends the
original serial communication interface.
Installing PySerial
To use the PySerial package with Python, PySerial first needs to be installed. If you installed the full
Anaconda distribution of Python, PySerial comes pre-installed. If you do have the full Anaconda
distribution of Python installed, PySerial can be installed using the Anaconda Prompt.
> conda install pyserial
After PySerial is installed, the installation can be confirmed at the Python REPL:
3.4
NOTE: Even though the command to install PySerial was > conda install pyserial, the Py-
Serial module is imported with the line import serial.
Unicode Strings
In Python, the syntax to define a new string is:
11.3. BYTES AND UNICODE STRINGS 265
Use Python’s built-in type() function to determine the data type of the ustring variable:
In [2]: print(type(ustring))
<class 'str'>
When the Python interpreter declares the variable ustring is of <class 'str'>, it indicates
ustring is a Unicode string.
In Python 3, all strings are Unicode strings by defaut.
Unicode strings are useful because there are many letters and letter-like characters that are not part of
the set of letters, numbers, and symbols on a regular computer keyboard. For example in Spanish,
the accent character is used over certain vowels. Letters with accents cannot be represented by the
letters on a standard English keyboard. However, letters with accents are part of a set of letters,
numbers, and symbols in unicode strings.
Byte Strings
Another way that characters such as letters, numbers, and punctuation can be stored is as bytes. A
byte is a unit of computer information that has a fixed width (one byte long). Because of this fixed
width, one byte only has a small number of unique combinations. This limits byte strings to only
the letters, numbers and punctuation marks on a computer keyboard (plus a couple extra). This
limited set of characters is called the ASCII (pronounced ask-ee two) character set. A table of ASCII
character codes is in the appendix. For instance, the ASCII character code 49 corresponds to the
number one 1.
Machines speak bytes.
However, external hardware such as Arduinos, oscilloscopes, and voltmeters speak byte strings by
default. Almost all machines speak byte strings by default, including the servers that bring Netflix
to your laptop.
To define a byte string in Python, the letter b is placed before the quotation marks b' ' when a
string is created.
We can view the data type of the bstring variable using the type() function.
In [4]: print(type(bstring))
<class 'bytes'>
266 CHAPTER 11. PYTHON AND EXTERNAL HARDWARE
Out[5]: bytes
Out[6]: str
When a command from a Python program (a Unicode string) is sent to a piece of external hardware
(that reads bytes):
The .encode() method is applied to the Unicode string (to convert the Unicode string to a byte
string) before the command is sent to the piece of external hardware.
When a chunk of data comes in from a piece of external hardware (a byte string) and is read by a
Python script (which speaks Unicode by the default):
The .decode() method is applied to the byte string (to convert the byte string to a Unicode string)
before it is processed further by Python program.
You will also need to download the Arduino IDE (Integrated Development Environment). Down-
load the Arduino IDE using the following link:
https://www.arduino.cc/en/Main/Software
If you are working on a computer that you don’t have administrator privileges to install software
on, be sure to select: [Windows ZIP for non-admin install].
void setup () {
// initialize serial communication :
Serial . begin (9600);
// initialize the LED pin as an output :
pinMode ( ledPin , OUTPUT );
}
void loop () {
// see if there ' s incoming serial data :
if ( Serial . available () > 0) {
// read the oldest byte in the serial buffer :
incomingByte = Serial . read ();
// if it ' s a capital H ( ASCII 72) , turn on the LED :
if ( incomingByte == 'H ') {
digitalWrite ( ledPin , HIGH );
}
// if it ' s an L ( ASCII 76) turn off the LED :
if ( incomingByte == 'L ') {
digitalWrite ( ledPin , LOW );
}
}
}
• Make sure the Port is selected properly in the Arduino IDE under Tools –> Port.
• Make sure the Board is selected in the Arduino IDE under Tools –> Board –> Arduino/Gen-
uino Uno
In the Arduino IDE, click the [checkmark] to verify and the [arrow] to upload. If the sketch does
not upload, check which COM port is selected in Tools –> Port.
270 CHAPTER 11. PYTHON AND EXTERNAL HARDWARE
Turn the LED on and off with the Arduino Serial Monitor
Open the Arduino Serial Monitor using Tools –> Serial Monitor. In the Serial Monitor type L or H
and click [Send]. Observe the LED turn on and off. Send H to turn the LED on. Send L to turn the
LED off.
Use the Python REPL to turn the Arduino LED on and off
Next, use the Python REPL to turn the Arduino on and off. (You can open the Python REPL by
typing > python at the Anaconda Prompt) At the Python REPL, type the following commands. If
a REPL prompt >>> precedes the command, type the command into the REPL. If the line does not
start with a REPL prompt, the line represents expected output.
When you type the command: ser = serial.Serial('COM4', 9800, timeout=1), ensure the
'COM#' corresponds to the port that worked with the Arduino IDE in Tools –> Port.
>>> import serial
>>> import time
>>> ser = serial . Serial ( ' COM4 ' , 9600) # open serial port
>>> time . sleep (2) # wait 2 seconds
>>> ser . name ()
' COM4 '
Ensure the command ser.close() is issued before exiting the Python REPL.
import serial
import time
In the next part of the Python script, connect to the Arduino over the serial port. In the line
ser = serial.Serial('COM4', 9800, timeout=1), ensure the 'COM#' corresponds to the port
that worked with the Arduino IDE. Then create a loop that blinks the Arduino LED on and off
for about 5 seconds. Notice the byte string b'H' is sent to the Arduino, not the Unicode string 'H'.
The Unicode string 'H' is prepended with the letter b in the line ser.writelines(b'H'). This line
of code turns the Unicode string into a byte string before it is sent to the Arduino.
ser = serial . Serial ( ' COM4 ' , 9800 , timeout =1)
time . sleep (2)
ser . close ()
Run the entire Python script and watch the Arduino LED blink ten times. A common problem
is the serial port was not closed before the script starts. Make sure the Arduino Serial Monitor is
closed and try running >>> ser.close() at the Python REPL.
Write a Python script to allow a user to turn the LED on and off
Once the LED blinks on and off successfully using a for loop in a Python script, you can write a
new Python script that allows a user to turn the LED on and off. At the top of the new Python
272 CHAPTER 11. PYTHON AND EXTERNAL HARDWARE
Next, give the user instructions. If the user types H, the LED turns on. If the user types L the LED
turns off. If the user types q, the program terminates.
print ( ' This program allows a user to control an LED ')
print ( ' type H to turn the LED on ')
print ( ' type L to turn the LED off ')
print ( ' type q to quit ')
Finally, the script needs a while loop to ask the user to enter the letter H, L or q. Once the user enters
the letter, the letter is converted to a byte string. Next, the byte string is sent over the serial line to
the Arduino. A delay is added so that the Arduino can process the command before reading with
the next one.
ser = serial . Serial ( ' COM4 ' , 9800 , timeout =1)
time . sleep (2)
Run the Python script. Type H and L and observe the LED turn on and off. Type q to end the
program.
You will also need to download the Arduino IDE (the Arduino Integrated Development Environ-
ment) using the following link as shown in the previous section:
https://www.arduino.cc/en/Main/Software
11.5. READING A SENSOR WITH PYTHON 273
Connect the Arduino to the computer with a USB cable. In the Arduino IDE select Tools –> Board
–> Arduino/Genuino Uno. Upload the sketch to the Arduino. In the Arduino IDE, click the [check
mark] to verify and the [arrow] to upload. If the sketch does not upload, check which COM port is
selected in the Arduino IDE under Tools –> Ports.
11.5. READING A SENSOR WITH PYTHON 275
Figure 11.10. Select the Arduino Serial Monitor from the Tools Menus
To verify the Arduino sketch is working correctly, the sensor signal can be checked in three ways:
The LED should turn on and off as the potentiometer is rotated. If the LED does not turn on and off
when the potentiometer is rotated, make sure the potentiometer is turned back and forth through
it’s full range of rotation. Also, ensure the USB cable is plugged into both the Arduino and the
computer.
Access the Arduino Serial Monitor using Tools –> Serial Monitor.
If the Arduino sketch is working correctly, a running list of numbers is shown in the Arduino
Serial Monitor. When the potentiometer is dialed back and forth, the numbers streaming down
the Serial Monitor should change. The output in the Serial Monitor should be a running list of
numbers between 0 and 1024.
If a running list of numbers can’t be seen in the Arduino Serial Monitor, ensure [Auto Scroll], [Both
NL & CR] and [9600 baud] are selected. Also, make sure the Port is set correctly in the Arduino
IDE under Tools –> Port.
276 CHAPTER 11. PYTHON AND EXTERNAL HARDWARE
To access the Arduino Serial Plotter, select Tools –> Serial Monitor in the Arduino IDE. Note the
Arduino Serial Monitor needs to be closed before the Arduino Serial Plotter can be opened. If the
sketch is working correctly, potentiometer rotation produces a moving line on the Arduino Serial
Plotter.
The output of the Arduino Serial Plotter should be a running line graph. The height of the line on
the graph should change as the potentiometer is dialed back and forth. If the Arduino Serial Plotter
is blank, make sure [9600 baud] is selected in the lower right corner of the Serial Plotter. Also, make
sure the Port has been set correctly in the Arduino IDE in Tools –> Port.
Type " help " , " copyright " , " credits " or " license "
>>> import serial
>>> import time
>>> ser = serial . Serial ( ' COM4 ' ,9600)
>>> time . sleep (2)
>>> b = ser . readline ()
>>> b
b ' 409\ r \ n '
>>> type ( b )
< class ' bytes ' >
>>> str_rn = b . decode ()
>>> str_rn
11.5. READING A SENSOR WITH PYTHON 277
Next, set up the serial communication line with the Arduino. Ensure the port specified in the
command ser = serial.Serial('COM4', 9600) is the same COM# that was used in the Arduino
IDE.
# set up the serial line
ser = serial . Serial ( ' COM4 ' , 9600)
time . sleep (2)
Next, code a loop runs for about 5 seconds while data is collected from the sensor. If it seems like
the loop is stuck, press [Ctrl] + [c].
# Read and record the data
data =[] # empty list to store the data
for i in range (50):
b = ser . readline () # read a byte string
string_n = b . decode () # decode byte string into Unicode
string = string_n . rstrip () # remove \ n and \ r
flt = float ( string ) # convert string to float
print ( flt )
data . append ( flt ) # add to the end of data list
time . sleep (0.1) # wait ( sleep ) 0.1 seconds
ser . close ()
11.5. READING A SENSOR WITH PYTHON 279
Figure 11.14. Matplotlib plot of potentiometer readings recorded with an Arduino and PySerial
After the data is collected, the data can be displayed with the Python’s print() function and a for
loop. The output looks like the numbers in the Arduino Serial Monitor.
# show the data
The data can also be plotted with Matplotlib. The resulting plot looks like the line plot in the
Arduino Serial Plotter.
import matplotlib . pyplot as plt
# if using a Jupyter notebook include
% matplotlib inline
Run the entire script and twist the potentiometer. You should see the potentiometer values running
by in the Python REPL command window.
After all the data is collected, you will see a plot like the one below.
280 CHAPTER 11. PYTHON AND EXTERNAL HARDWARE
11.6 Summary
In this chapter, you learned how to use Python to interact with external hardware. In particular,
you learned how to use Python and the PySerial package to communicate with an Arduino.
The chapter began with a discussion of Unicode strings and byte strings. In Python, all strings
are Unicode by default, but machines speak in bytes. To create a byte string in Python, prepend a
string with the letter b as in b'my string'. Python’s .encode() and .decode() methods convert
between Unicode strings and byte strings.
In the first project of the chapter, you learned how to use Python and the PySerial package to control
an LED attached to an Arduino. The general steps were:
The second project of the chapter involved reading a sensor connected to an Arduino with Python
and PySerial. To complete this project, the general steps were:
Additional Resources
The official documentation for the PySerial Package is found here: https://docs.pyserial.com
The Arduino project has a great set of tutorials found here:https://Arduino.com/tutorials
SparkFun has a great overview of wiring an LED to an Arduino here: and a great overview of
writing a potentiometer to an Arduino here:
11.7. PROJECT IDEAS 281
MicroPython
12.1 Introduction
By the end of this chapter you will be able to:
283
284 CHAPTER 12. MICROPYTHON
What is MicroPython?
MicroPython is a port, or version of Python designed to run on small, inexpensive, low-power
microcontrollers. Examples of microcontrollers that Micropython can run on includes the pyboard,
the WiPy and ESP8266-based boards like the Adafruit Feather Huzzah and ESP8266 NodeMCU.
Traditionally, Python runs on desktop or laptop computers and cloud servers. Compared to a
desktop or laptop, microcontrollers are much smaller, cheaper and less powerful. A “regular” ver-
sion of Python can’t run on small, cheap microcontrollers because Python is too resource intensive.
Regular Python takes up too much hard disk space, runs on too much RAM and requires a more
powerful processor than microcontrollers have.
It is pretty amazing that a version of Python (MicroPython) runs on these small, cheap microcon-
trollers like the ESP8266. To get MicroPython to run at all on these little low-cost boards, MicroPy-
thon only contains a subset of all the Standard Library modules included with “regular” Python.
Some of the libraries that are included with MicroPython don’t have the full set of functions and
classes that come with the full version of Python. By not including the full functionality of “regu-
lar” Python, MicroPython is compact (around 600 kB for the ESP8266 port), and MicroPython only
uses a small amount of RAM (down to 16k according to the Micropython main page.)
You can try using MicroPython online with a browser-based MicroPython online emulator. The
emulator allows you to run commands at a MicroPython Prompt and see the result on a virtual
pyboard.
solvers understand how programming works. Seeing and controlling a motor whirl is a differ-
ent kind of feedback and excitement compared to seeing text on a screen that shows how fast a
motor spins. Seeing an array of LED’s light up produces a different kind of wonder compared to
seeing a 2-D plot on a computer screen. Plus MicroPython is fun! It’s as easy to program MicroPy-
thon as it is to program regular Python. The little projects you can do with MicroPython running
on a small, low-cost board are almost unlimited. We could send MicroPython to space in a micro-
satellite, or bury MicroPython underground in a boring machine, or launch MicroPython into the
sky on a weather balloon.
Hardware Purpose
A laptop or desktop computer install MicroPython on the microcontroller
Adafruit Feather Huzzah ESP8266 microcontroller running MicroPython
micro USB cable connect the microcontroller to computer
Software Purpose
Anaconda distribution of Python run esptool that installs MicroPython
Anaconda Prompt Install esptool package with pip
esptool A pip installable package used to install MicroPython
firmware .bin file Version of MicroPython run on the microcontroller
Summary of Steps:
If you don’t have the Anaconda distribution of Python installed already, go to Ana-
conda.com/download to download and install the latest version.
Before we connect the ESP8266-based microcontroller such as an Adafruit Feather Huzzah ESP8266
or ESP8266 NodeMCU to the computer, a specific driver needs to be installed. For Windows 10
laptop to see the board, the CP210x USB to UART Bridge VCP driver needs to be downloaded
from SiLabs and installed. The driver download and installation is quick and easy but does require
administrator privileges.
12.3. INSTALLING MICROPYTHON 287
Before uploading the .bin firmware file to the ESP8266-based microcontoller, it is best practice to
first erase the flash memory on the board using the command esptool erase_flash. Make sure
to specify the --port. The argument after --port is the COM port assigned to the ESP8266 board
shown in the Windows Device Manager. This port often comes up as COM4.
( micropython ) > esptool -- port COM4 erase_flash
Now you can finally write the .bin firmware file to the flash memory on the microcontroller using
the esptool write_flash command. Make sure to use the exact firmware file name you see sitting
in the micropython directory. The port needs to be set corresponding to the port you found in the
Windows Device Manager. ---baud is the baud rate or upload speed. I found that --baud 460800
12.3. INSTALLING MICROPYTHON 289
worked, but you could also specify --baud 115200 which is slower. The upload time was a matter
of seconds with either baud rate. The 0 after --flash_size=dectect means the firmware is written
at the start of the flash memory (the 0th position) on the board. Again, make sure the .bin firmware
file name is correct. The long file name is easy to mistype.
( micropython ) > esptool -- port COM4 -- baud 115200 write_flash \
-- flash_size = detect 0 esp8266 -20171101 - v1 .9.3. bin
Sometimes, you may need to type [Enter] or Ctrl-D to bring up the >>> REPL prompt. If the >>>
REPL prompt is not displayed in your PuTTY window, try to close PuTTY, unplug then replug the
board and open PuTTY again. Most ESP8266-based microcontrollers also have a tiny little black
RESET button that can be pressed to restart the board.
At the >>> MicroPython REPL prompt try the following commands:
>>> print ( ' Problem Solving with MicroPython ! ')
Problem Solving with MicroPython !
The last section detailed the installation of MicroPython on an ESP8266-based microcontroller using
Python and a package called esptool. In this section, you will learn how to write commands to the
MicroPython REPL (the Micropython prompt) to turn an LED on and off.
Before you can use the MicroPython REPL (the MicroPython prompt) running on a microcontroller,
MicroPython needs to be installed on the board. A serial communication tool, like PuTTY, also
needs to be installed on your computer to communicate with the microcontroller over a serial line.
The previous section detailed how to install MicroPython on an ESP8266-based microcontroller and
how to install PuTTY on Windows.
Summary of Steps
Use a microUSB cable to connect the microcontroller to the computer. Make sure that the microUSB
cable is a full USB data cable and not just a simple power cable. Cables that are just used to charge
phones may only be power cables and may not be capable of transmitting data.
Determine which COM port the microcontroller is connected to using the Win-
dows Device Manager
Use the Windows Device Manager to determine which serial port the microcontroller is connected
to. On Windows, the microcontroller usually comes up as COM4. You can find the serial port by
looking in the Ports (COM & LPT) category of the Windows Device Manager. Look for something
12.4. THE MICROPYTHON REPL 295
like Silicon Labs CP210x USB to UART Bridge (COM4) in the Ports (COM & LPT) menu. It is the
COM# that’s needed to connect to the board.
Ensure the microcontroller is connected to your computer with a USB cable. Then initialize serial
communication between the microcontroller and your computer with PuTTY. In PuTTY set the
proper serial port (COM#) and 115200 baud. Remember to use the [Serial[ radio button under
[Connection Type:] to select serial communication or PuTTY will attempt to communicate with
the microcontroller over SSH which won’t work.
In PuTTY, click [Open] to bring up the MicroPython REPL prompt >>>. If you can’t see the >>>
prompt, try typing [Enter], [Ctrl]-[D], pushing the RESET button on the microcontroller or unplug-
ging then replugging the USB cable.
296 CHAPTER 12. MICROPYTHON
If you import the sys module, you can see the MicroPython implementation and platform.
>>> import sys
>>> sys . implementation
( name = ' micropython ' , version =(1 , 9 , 3))
>>> sys . platform
' esp8266 '
If you see similar output, that means MicroPython is working on the ESP8266-based microcon-
troller. You can also view the flash memory size of your microcontroller and the size of the Mi-
croPython firmware you installed. Try the command below at the MicroPython prompt:
>>> import port_diag
In the results above, you can see the flash memory size is 4 MB. Below the label
Firmware checksum: you can see a line for size: 600872. size: 600872 means the size of the
Micropythpon installation is about 600 KB or about 0.6 MB. Just over half a megabyte on the mi-
crocontroller and you are running a working version of Python!
Now try a simple for loop. When you initiate a loop, the MicroPython REPL automatically indents
the next line. A tab is not needed on code lines below a loop statement. To run the loop, type
12.4. THE MICROPYTHON REPL 297
Figure 12.18. Results of running sys commands at the MicroPython REPL prompt
12.5. BLINKING A LED 299
Figure 12.19. Results of running import port_diag at the MicroPython REPL prompt
backspace on an empty line (to backspace away from an indented line) and hit [Enter].
>>> for i in range (5):
... print (" Problem Solving with MicroPython !")
...
In this section, you will learn how to blink the built-in LED on ESP8266-based microcontroller using
the MicroPython REPL.
Before the LED on the ESP8266-based microcontroller can be blinked, MicroPython needs to be in-
stalled on the microcontroller and PuTTY needs to be installed on your computer. PuTTY facilitates
interaction between a computer and the microcontroller using the serial communication protocol.
An alternative to PuTTY is a MacOS or Linux terminal and the screen utility. The screen utility can
also be used for serial communication.
Most ESP8266-based microcontrollers (such as the Adafruit Feather Huzzah ESP8266) have a built-
in LED mounted on the board. On many boards, the built-in LED is connected to Pin 0. You can
control the board’s built-in LED with MicroPython’s machine module.
300 CHAPTER 12. MICROPYTHON
Connect the ESP8266-based microcontroller to the computer with a microUSB cable. Ensure the
microUSB cable is a USB data cable, not just a charging cable. Open PuTTY and connect to the
microcontroller using the proper serial port (COM#) and 115200 baud. (Remember to use the Serial
radio button under Connection Type:)
Clicking [Open] will bring up the MicroPython REPL prompt >>>. If you can’t see the >>> prompt,
try typing [Enter] or [Ctrl]+[D] or push the RESET button on the microcontroller. If none of these
methods work, try closing PuTTY and unplugging then replugging in the microUSB cable that
connects the board to the computer.
Use the MicroPython REPL to turn the microcontroller’s LED on and off
Test to see if the MicroPython REPL is functioning correctly with a basic Hello World program. Type
the following into the PuTTY window:
12.5. BLINKING A LED 301
Next, try to turn the microcontroller’s built-in LED on and off. Most ESP8266-based microcon-
trollers (such as the Adafruit Feather Huzzah ESP8266) have a built-in LED connected to Pin 0. If
you control the voltage going to Pin 0, you control if the built-in LED on the microcontroller is on
or off. To control a Pin on a microcontroller with MicroPython, you first need to import the ma-
chine module. The machine module is built into MicroPython, but absent from “regular” Python.
Next, a Pin object needs to be created. The integer passed into machine.Pin() determines the pin
number assigned to the Pin object.
>>> import machine
>>> pin = machine . Pin (0)
The value of Pin0 (on or off) is determined with the command below.
>>> pin . value
1
In or assign a value to Pin 0, the Pin object must be assigned as an output pin. An output pin is a
pin where a program or user determines the pin output. An input pin is a pin set up to read input,
like the input from a sensor. In this case, you want to assign Pin 0 as an output pin.
>>> pin = machine . Pin (0 , machine . Pin . OUT )
Now let’s make the microcontroller’s built-in LED blink. Blinking the LED can be accomplished
with a simple for loop. At the MicroPython REPL, initiating a loop automatically indents the next
line, so a tab is not needed before the pin.on() statement. To run the loop, type backspace on an
empty line (to backspace from an indented line) and hit [Enter].
The microcontroller’s built-in LED turns on and off for a total of about 10 seconds.
In this section, you will learn how to connect a temperature sensor to an ESP8266-based microcon-
troller and use the MicroPython REPL to read the temperature. This section includes specifics for
the Adafruit Feather Huzzah ESP8266 microcontroller and the MCP9808 temperature sensor. Other
ESP8266-based microcontrollers and temperature sensors could be used instead, but the specifics
of the procedure may be different from what’s shown in this section.
Before you can use MicroPython to read a temperature sensor, MicroPython needs to be installed
on the board, and PuTTY needs to be installed on your computer (on MacOS and Linux, use a
terminal and screen) to communicate with the board over serial.
Summary of Steps
1. Connect the MCP9808 temperature sensor to the Adafruit Feather Huzzah ESP8266 micro-
controller
2. Connect the Adafruit Feather Huzzah ESP8266 microcontroller to the computer with a USB
cable and bring up the MicroPython REPL with PuTTY
3. Run code at the MicroPython REPL to measure the temperature
12.6. READING A SENSOR 303
Figure 12.22. MCP9808 temperature sensor connected to an Adafruit Feather Huzzah ESP8266
Connect the Adafruit Feather Huzzah ESP8266 to the computer with a microUSB cable. Ensure the
cable is a USB data cable, not just a power cable. Open PuTTY and connect to the Feather Huzzah
using the proper serial port (COM#) and 115200 baud. (Remember to use the Serial radio button
under Connection Type:)
Clicking [Open] will bring up the MicroPython REPL prompt >>>. If you can’t see the >>> prompt,
try typing [Enter] or [Ctrl]+[D] or push the RESET button on the Feather Huzzah. If none of these
methods work, try closing PuTTY and unplugging then replugging in the USB cable then reopen
PuTTY.
304 CHAPTER 12. MICROPYTHON
At the MicroPython REPL, import the machine module and then create an instance of
the machine.I2C class. Set the scl and sda parameters as scl=machine.Pin(5) and
sda=machine.Pin(4). Next, create an empty bytearray to store the data coming in from the
MCP9808 temperature sensor. As strings in Micropython are UTF-8 encoded by default (like in
Python 3), a bytearray needs to be used to read the raw output from the MCP9808 chip registers. The
command i2c.readfrom_mem_into() reads the data from the sensor and saves it to the byte_data
variable. The arguments inside the i2c.readfrom_mem_into() method 24 and 5 correspond to the
I2C memory address and registry address of the temperature data stored in the MCP9808 temper-
ature sensor.
In this section, you will learn how to upload code to an ESP8266-based microcontroller with a tool
called ampy. The code in this section was written to turn the ESP8266-based microcontroller in
a scrolling thermometer. The same upload method shown in this section can be used to upload
MicroPython code you write to a ESP8266-based microcontroller.
Before MicroPython code is uploaded on the ESP8266-based microcontroller, MicroPython needs
to be installed on the board. PuTTY also needs to be installed on you computer in order for the
computer to communicate with the microcontroller over a serial connection.
A previous section in this chapter detailed how to install MicroPython on an ESP9266 microcon-
troller and how to install PuTTY on a Windows. The procedures in this section are specific to the
Adafruit Feather Huzzah ESP8266 microcontroller and the MCP9808 temperature sensor, both of
which were used in a previous section. Other ESP8266-based microcontrollers and I2C sensors
could be used instead, but the specifics of the procedure may be different from what’s shown in
this section.
Summary of Steps
1. Install ampy with pip
2. Write MicroPython code
3. Upload the MicroPython on code on the microcontroller with ampy
4. Unplug and then power up the Feather Huzzah and watch the temperature scroll by
The first MCP9808.py file includes one function called readtemp(). The readtemp() function reads
temperature recorded by the MCP9808 temperature sensor. The readtemp() function parses out
the temperature data from the I2C bus on the MCP9808 temperature sensor and outputs the tem-
perature in degrees C as a float.
At the top of MCP9808.py we need to import the machine module to use the I2C bus. The machine
module provides a class to create a new I2C object.
When the I2C object is instantiated, the scl and sda pins that the MCP9808 temperature sensor is
connected to need to be specified. scl is the I2C clock line and sda is the I2C data line. scl and sda
are pin 5 and pin 4 on the Adafruit Feather Huzzah ESP8266.
The next part of the readtemp() function creates a byte array. Data from the MCP9808 temperature
sensor will be stored in the byte array.
The next part of the readtemp() function in the MCP9808.py file uses the
i2c.readfrom_mem_into() method to read the temperature off the sensor. The first argu-
ment passed to the i2c.readfrom_mem_into() method is the I2C bus address of the sensor. On
the MCP9808 temperature sensor, the I2C bus address is 24(if you type the line >>> i2c.scan()
into the MicroPython REPL, the I2C bus address is returned). The next parameter passed to the
i2c.readfrom_mem_into() method is the register on the MCP9808 temperature sensor where the
measured temperature is stored. On the MCP9808, the temperature is stored in register 5. The
third parameter passed to the i2c.readfrom_mem_into() method is the variable we want to store
the temperature data in. The i2c.readfrom_mem_into() method changes the variable passed into
the method as the third argument. Most Python methods modify the object the method operates
on, but MicroPython’s i2c.readfrom_mem_into() method changes the third variable passed to it,
in our case the variable byte_data. That’s why we created the byte_data variable before we called
the i2c.readfrom_mem_into() method.
The last part of the readtemp() function includes post-processing needed to convert the byte array
into a temperature in degrees C. The final temperature in degrees C is a float
The entire contents of the MCP9808.py file are below:
# MCP9808 . py
Now construct a MicroPython script called main.py which will use the function readtemp() stored
in MCP9808.py.
The main.py script will import the MCP9808.py module and use the readtemp() function to read
308 CHAPTER 12. MICROPYTHON
import MCP9808
import time
Unplug and then power up the Feather Huzzah and watch the temperature scroll
by
The Feather Huzzah needs to be restarted to run the main.py file uploaded with ampy.
To restart the board, unplug and then replug in the board’s power (the USB cable). Once power
is restored, the board will run through the boot.py script then start the main.py script. When the
board runs the main.py script, the board will read the temperature from the MCP9808 temperature
sensor then print the temperature out to the terminal. After two minutes the program should end.
The output below demonstrates the results shown in a terminal window.
12.7. UPLOADING CODE 309
...
25.6875
25.75
25.6875
25.6875
25.75
25.6875
25.75
25.75
25.75
25.75
25.75
25.8125
25.8125
25.8125
25.75
25.75
25.8125
>>>
310 CHAPTER 12. MICROPYTHON
12.8 Summary
In this chapter, you learned about MicroPython. MicroPython is a small slimed down port of the
Python programming language designed to run on small cheap microcontrollers. The first part of
the chapter introduced MicroPython. “Regular” Python consumes to much hard disk space and
RAM to be run installed on a microcontroller. But MicroPython is very small for a programming
language. It only takes up less than 1MB on a microcontroller.
The next section of the chapter involved how to install MicroPython on a microcontroller. To install
MicroPython on a microcontroller, use a package called esptool and upload a .bin firmware file to
the board.
The rest of the chapter involved two projects. Blinking an LED with MicroPython and reading a
sensor with MicroPython.
To blink an LED on a microcontroller, you need to connect to the microcontroller with a program
called PuTTY. Through a PuTTY terminal, you can use MicroPython’s machine module to write
high and low values to the pins on the microcontroller.
An MCP9808 temperature sensor was read using MicroPython in the second project. The sensor
first needed to be wired up to the microcontroller, and then the MicroPython’s ic2 class was used
to read data off the sensor. At the end of the project, a Python package called ampy was used to
upload a .py file to the microcontroller.
Appendix
13.1 Contents
The following is detailed in the appendix:
• Contributions
• Cover Artwork
• About the author
313
314 CHAPTER 13. APPENDIX
Logical Keywords
if break finally
else continue raise
elif pass return
for try yield
while except
Module Keywords
13.3. ASCII CHARACTER CODES 315
import as
from with
The conda create command builds the new virtual environment. The --name env_name flag gives
the new virtual environment the name env_name. Including python=3.6 ensures the virtual envi-
ronment has a current version of Python.
The following output or something similar results:
The following NEW packages will be INSTALLED :
ca - certificates : 2018.03.07 -0
certifi : 2018.11.29 - py36_0
libedit : 3.1.20170329 - h6b74fdf_2
libffi : 3.2.1 - hd88cf55_4
libgcc - ng : 8.2.0 - hdf63c60_1
libstdcxx - ng : 8.2.0 - hdf63c60_1
ncurses : 6.1 - he6710b0_1
openssl : 1.1.1 a - h7b6447c_0
pip : 18.1 - py36_0
python : 3.6.8 - h0371630_0
readline : 7.0 - h7b6447c_5
setuptools : 40.6.3 - py36_0
sqlite : 3.26.0 - h7b6447c_0
tk : 8.6.8 - hbc83047_0
wheel : 0.32.3 - py36_0
318 CHAPTER 13. APPENDIX
xz : 5.2.4 - h14c3975_4
zlib : 1.2.11 - h7b6447c_3
Proceed ([ y ]/ n )?
The virtual environment is active when you see (env_name) > in parenthesis at the start of the
prompt:
( env_name ) >
When a new virtual environment is created, no packages are installed by default. If you use the
Anaconda distribution of Python, the base environment contains about 600 packages that come
with Anaconda. But a fresh new virtual environment will just have Python installed, no other
packages.
To install a package into the virtual environment (env_name), first, make sure the environ-
ment is active ((env_name) before the prompt). Package installation is accomplished with the
conda install command followed by the package name. To install Matplotlib into the virtual
environment type:
Multiple packages can be installed with the same command. To install both NumPy and Jupyter
use:
When the virtual environment is deactivated, the prompt looks normal >, with no environment
name in parenthesis before it.
13.4. VIRTUAL ENVIRONMENTS 319
# conda environments :
#
base / home / tribilium / anaconda3
env_name * / home / tribilium / anaconda3 / envs / env_name
matplotlib / home / tribilium / anaconda3 / envs / matplotlib
Notice the * asterisk on the line with env_name. The virtual environment with the * is currently
active.
To exit the virtual environment, use the command conda deactivate.
( env_name ) > conda deactive
If you run conda env list again, there is no * in front of env_name. That’s because the env_name
virtual environment is no longer active.
> conda env list
# conda environments :
#
base * / home / tribilium / anaconda3
env_name / home / tribilium / anaconda3 / envs / env_name
matplotlib / home / tribilium / anaconda3 / envs / matplotlib
# conda environments :
#
base * / home / tribilium / anaconda3
env_name / home / tribilium / anaconda3 / envs / env_name
matplotlib / home / tribilium / anaconda3 / envs / matplotlib
Proceed ([ y ]/ n )?
320 CHAPTER 13. APPENDIX
Type [y] to remove the environment. View a list of your virtual environments again. Note that
env_nameis no longer in the list.
> conda env list
# conda environments :
#
base * / home / tribilium / anaconda3
matplotlib / home / tribilium / anaconda3 / envs / matplotlib
np . pi np . arcsinh np . radians
np . sin np . arccosh np . sinc
np . cos np . arctanh np . sinh
np . tan np . arctan2 np . tanh
np . arcsin np . radians np . angle
np . arccos np . rad2deg
np . arctan np . deg2rad
13.6. GIT AND GITHUB 321
• git - a command line program used to track file changes and collaborate on code with others.
• repo - short name for “repository”. A repo is a directory and its contents.
• local repo - a directory and its contents on your computer that git knows about.
• remote repo - a directory and its contents stored in the cloud that git knows about.
• git add . add all files and changes to the local repo
• git commit -m "commit message" commit the changes in the local repo with the message
"commit message"
• git push origin master push local changes up to the remote repo
• git pull origin master pull down the version in the remote repo into the local repo
Cloning a repo
One common operation to complete with git is to clone a repo from GitHub.com and save it lo-
cally. This means you copy all the files stored in the remote repo on GitHub.com onto your local
computer. Cloning a repo from Github.com is accomplished with:
322 CHAPTER 13. APPENDIX
This command copies the repo named repo from the user named user to a local computer. To clone
the repo for MicroPython, use:
Another common task to complete with git is to synch a remote repo on GitHub.com with a local
repo on your local computer. This is useful when you want to keep the files in a particular project
synched across multiple computers. Synched remote and local repos are also useful for a group of
problem solvers working on the same project. Each team member has access to the same remote
repo on GitHub.com and each team member has the same local repo on their computer.
First, go to GitHub.com/join and create a new account. Log in and create a new repo. It is a good
idea to include a license and a .gitignore file. For a Python project, the .gitignore file for Python is
a good start. Two common licenses for open source projects (projects you are willing to share with
others) are the GNU General Public License v3.0 and the MIT License.
Make a new local repo and link the local repo to the remote repo on GitHub.com
Second, create a local directory and cd into it. Initialize a git repo locally in that directory. Then
synch the local folder with the remote repo on GitHub.com.
$ mkdir newproject
$ cd newproject
$ git init
$ git remote add origin https :// github . com / user / repo . git
$ git pull origin master
Third, work on the project locally. For example, you could edit one of the files in the directory
newproject or create a new file in the directory newproject.
Finally, save your work and commit the changes you made with git. Push those changes up to the
remote repo on GitHub.com
$ git add .
$ git commit -m " commit message "
$ git push origin master
13.7. LATEX MATH 323
Pull the most recent version from GitHub.com before each work session
If using git and GitHub.com, remember to pull the most recent version of the repo down from
GitHub.com before you make any changes locally. If changes are made locally before the version
of the repo on GitHub.com is synched, the local repo and remote repo will be out of synch.
$ git pull origin master
After local changes are made, save the changes and push to GitHub.com
$ git add .
$ git commit -m " commit message "
$ git push orign master
Jupyter Notebooks
This book was constructed using Jupyter notebooks. The GitHub.com repo for the book can be
found at:
https://github.com/ProfessorKazarinoff/Problem-Solving-with-Python
The directory structure of the GitHub repo contains all the Jupyter notebooks used the write the
book. The repo also contains a set of custom conversion scripts and templates which convert the
Jupyuter notebooks into .html and .tex files.
Problem - Solving - with - Python /
| - - conversion_tools /
| - - notebooks /
| - - LICENSE
| - - notebooks /
| - - pdf /
| - - README . md
| - - website /
The notebooks directory contains a directory for each chapter of the book:
notebooks /
| - - 00 - Preface /
| - - 01 - Orientation /
| - - 02 - The - Python - REPL /
| - - 03 - Data - Types - and - Variables /
| - - 04 - Jupyter - Notebooks /
| - - 05 - Functions - and - Modules /
| - - 06 - Plotting - with - Matplotlib /
| - - 07 - If - Else - Try - Except /
| - - 08 - Loops /
| - - 09 - Matrices - and - Arrays /
| - - 10 - Symbolic - Math /
| - - 11 - Python - and - External - Hardware /
| - - 12 - MicroPython /
| - - 99 - Appendix /
| - - figures /
`-- TOC . ipynb
There is a Jupyter notebook for each section of the book within each chapter directory. Each chapter
directory contains an images directory for any images used in the markdown cells of the notebooks.
01 - Orientation /
| - - 01.00 - Welcome . ipynb
| - - 01.01 - Why - Python . ipynb
| - - 01.02 - The - Anaconda - Distribution - of - Python . ipynb
| - - 01.03 - Installing - Anaconda - on - Windows . ipynb
13.9. CONTRIBUTIONS 325
Website
The website for this book was constructed using mkdocs and the Material for MkDocs theme.
Jupyter noteboks were exported to .html files with markdown cells unformatted using a custom
script and nbconvert.
Hardcopy
The hard copy of the book was constructed using LaTeX, nbconvert and a set of custom scripts
and templates. One conversion script combined all of the notebooks into one BIG notebook. The
BIG notebook was then converted into LaTeX using nbconvert and a custom template. Outside
of the Python ecosystem, a separate installation of TeXworks compiled the LaTeX .tex file to a .pdf
document.
13.9 Contributions
Any corrections, typos or suggestions to improve the text can be emailed to:
errata@problemsolvingwithpython.com
Please include the chapter number and section number in your email. Include in your email if you
would like to remain anonymous or have your name recognized in the contributor list. Thank-you
in advance for improving the text for others.
Contributor List
•
•
•