Introduction to Python and Jupyter

  • KEYWORDS: introduction

Python

I will use Python exclusively in class, every day. Python is free, and better than anything else for what we will do in this class. I have used it in research for more than a decade, and it is one of the most popular programming languages around today.

I assume most of you have not used Python before. We will start small, and continuously build up skills in using it. You will see it a lot, and you should practice using it. It is an opportunity to learn something new!

For a lot of examples of using Python for scientific computing, see http://kitchingroup.cheme.cmu.edu/pycse/.

Jupyter notebook introduction

Jupyter notebooks are an interactive, browser-based tool for running Python. We will use them exclusively in this class. We will quickly build up the skills required to solve engineering problems. We will not learn everything about programming, mathematical modeling or engineering processes. My goal is to get you thinking about a very general computational way of thinking about these problems, and to learn how to use computation as a way to augment your analytical skills.

I will lecture from the notebooks, and show you how I use them. The notes will be available to you during class for you to work along with me.

print('Hello World! Welcome to the pycse course!')
# Type C-Enter to run this cell
# Type shift-Enter to run this cell and got to the next one or create a new one.
Hello World! Welcome to the pycse course!

What is the value of \(a\) that satisfies the equation \(a + 4 = 5\)?

We can document our solution here, e.g. we find \(x\) by algebra. If we subtract 4 from each side of the equation, \(a\) will be isolated, and equal to the value of the right hand side of the equation.

You can double-click on any text block to see what the Markdown is that generates it. Type C-Enter to re-render the cell.

You can add text if you want, and re-execute the cell with C-enter

Here is the code that implements that explanation:

a = 5 - 4
print(f'The solution is {a}')
The solution is 1

numpy

numpy is a Python library for arrays. We have to import this library to access the functionality in it. The conventional way to import this library is:

Remember this cell. You will use it almost every time.
import numpy as np

To see help on the numpy library, run this cell:

Now, we can access functions in the numpy module using “dot notation”. For example, let us start by creating an array of linearly spaced points using the linspace function.

np.pi is a constant for the number $\pi$
x = np.linspace(0, 2 * np.pi, 40)
x
array([0.        , 0.16110732, 0.32221463, 0.48332195, 0.64442926,
       0.80553658, 0.96664389, 1.12775121, 1.28885852, 1.44996584,
       1.61107316, 1.77218047, 1.93328779, 2.0943951 , 2.25550242,
       2.41660973, 2.57771705, 2.73882436, 2.89993168, 3.061039  ,
       3.22214631, 3.38325363, 3.54436094, 3.70546826, 3.86657557,
       4.02768289, 4.1887902 , 4.34989752, 4.51100484, 4.67211215,
       4.83321947, 4.99432678, 5.1554341 , 5.31654141, 5.47764873,
       5.63875604, 5.79986336, 5.96097068, 6.12207799, 6.28318531])

Most mathematical operations are element-wise on arrays.

x * x
array([0.00000000e+00, 2.59555671e-02, 1.03822269e-01, 2.33600104e-01,
       4.15289074e-01, 6.48889178e-01, 9.34400417e-01, 1.27182279e+00,
       1.66115630e+00, 2.10240094e+00, 2.59555671e+00, 3.14062362e+00,
       3.73760167e+00, 4.38649084e+00, 5.08729116e+00, 5.84000260e+00,
       6.64462519e+00, 7.50115890e+00, 8.40960375e+00, 9.36995973e+00,
       1.03822269e+01, 1.14464051e+01, 1.25624945e+01, 1.37304950e+01,
       1.49504067e+01, 1.62222295e+01, 1.75459634e+01, 1.89216084e+01,
       2.03491646e+01, 2.18286320e+01, 2.33600104e+01, 2.49433000e+01,
       2.65785007e+01, 2.82656126e+01, 3.00046356e+01, 3.17955697e+01,
       3.36384150e+01, 3.55331714e+01, 3.74798389e+01, 3.94784176e+01])

We can define new variables

y1 = np.sin(x)
y2 = np.cos(x)
y2.shape
(40,)
a = [ 0, 1, 2]
print(a) 
print(np.array([0, 1, 2]))
[0, 1, 2]
[0 1 2]
2 * a
2 + np.array(a)
array([2, 3, 4])
np.sin([0, 1, 2]), np.sin(a)
(array([0.        , 0.84147098, 0.90929743]),
 array([0.        , 0.84147098, 0.90929743]))

plotting

We can make plots using matplotlib. First we need this line. This line imports the plotting library.

Remember this cell. You will use it almost every time you make a plot.
import matplotlib.pyplot as plt

You call functions in the plt library to create plots. These are automatically saved in the notebook.

plt.plot(y1, y2, 'g-.')
plt.xlabel('y1')
plt.ylabel('y2')
plt.legend(['y1', 'y2'])
plt.axis('equal');
# Always include axis labels and legends when appropriate
../_images/00-intro_26_0.png

scipy

scipy contains numerous libraries for a broad range of scientific computing needs.

Suppose we want to perform the following integral: \(I = \int_0^{4.5} J_{2.5}(x) dx\). The function \(J_{2.5}\) is a special function known as a Bessel function. scipy provides both the integration function, and an implementation of the special function we can use.

from scipy.integrate import quad
from scipy.special import jv

To evaluate this integral, we have to define a function for the integrand, and use the quad function to compute the integral. The quad function returns two values, the value of the integral, and an estimate of the maximum error in the integral.

# This is how we define a function. There is a function name, and arguments
# The function returns the output of the jv function.
def integrand(x):
    return jv(2.5, x)

integrand([0, 0.5])

x1 = np.linspace(0, 4.5)
plt.plot(x1, integrand(x1));
../_images/00-intro_31_0.png
I, err, info = quad(integrand, 0, 4.5, full_output=1)

info
{'neval': 63,
 'last': 2,
 'iord': array([          1,           2,           0,           0,   218176832,
           50334979,     4328707, -1610151165, -2130509563,   168558857,
          134618112,   269356036,   196103132,   229657428, -1185391788,
        -1057027072,  1020549432,   288550084,   788541753,  -331557660,
          809046578,   123229003,   130614288,  1506346256,   708837666,
            2752523,     5832776,     7798889,   369557642,   637545217,
          906177281,  1325485569,  1443712780,  1963025921, -2063369727,
            6098177,   553716061,   856765187,   588325653,    53813521,
           16973318,  -704760322,  1593690581,  -470014715,   872205571,
           27328168,       50016,        9764,   973145089,    11166562],
       dtype=int32),
 'alist': array([0.00000000e+00, 2.25000000e+00, 7.67216743e-04, 2.10783652e-03,
        4.30872995e-03, 7.48622952e-03, 1.17307690e-02, 1.71108947e-02,
        2.36754402e-02, 3.14548611e-02, 4.04621596e-02, 5.06936098e-02,
        6.21293999e-02, 7.47342567e-02, 8.84580927e-02, 1.03236700e-01,
        1.18992502e-01, 1.35635383e-01, 1.53063574e-01, 1.71164629e-01,
        1.89816457e-01, 2.08888426e-01, 2.28242527e-01, 2.47734592e-01,
        2.67215554e-01, 2.86532742e-01, 3.05531217e-01, 3.24055105e-01,
        3.41948956e-01, 3.59059092e-01, 3.75234941e-01, 3.90330352e-01,
        4.04204875e-01, 4.16724997e-01, 4.27765321e-01, 4.37209691e-01,
        4.44952235e-01, 4.50898336e-01, 4.54965507e-01, 4.57084178e-01,
        4.57198376e-01, 4.55266300e-01, 4.51260786e-01, 4.45169648e-01,
        4.36995911e-01, 4.26757911e-01, 4.14489286e-01, 4.00238834e-01,
        3.84070253e-01, 3.66061764e-01]),
 'blist': array([ 2.25000000e+000,  4.50000000e+000,  6.91892332e-310,
         6.91892119e-310,  6.20311750e+059,  6.91892139e-310,
         6.91892204e-310, -1.30894292e+005,  6.91892204e-310,
         6.91892099e-310,  1.41366147e-064,  6.91892204e-310,
         6.91892099e-310,  3.69431696e-138,  6.91892099e-310,
         6.91892099e-310, -1.15345234e+032,  6.91892119e-310,
         6.91892205e-310, -4.06777619e-170,  6.91892328e-310,
         6.91892205e-310,  2.36650989e-077,  6.91892119e-310,
         6.91892099e-310,  1.18068449e-081,  6.91892331e-310,
         6.91892099e-310, -3.93063548e-302,  6.91892100e-310,
         6.91892099e-310, -4.33318176e+001,  6.91892308e-310,
         6.91892100e-310, -3.69784623e+178,  6.91892329e-310,
         6.91892100e-310, -7.81343914e-094,  6.91892182e-310,
         6.91892100e-310, -3.12302610e-251,  6.91892329e-310,
         6.91892100e-310, -4.43162428e-138,  6.91892283e-310,
         6.91892096e-310, -9.14058561e+239,  6.91892243e-310,
         6.91892096e-310,  6.91892116e-310]),
 'rlist': array([2.05718868e-001, 9.12099070e-001, 1.80944544e+223, 4.37322830e-308,
        1.44764293e+166, 6.51256002e+175, 6.92131999e+218, 2.57378228e+151,
        3.40062557e-309, 1.33360290e+241, 2.95806213e-311, 8.31833568e-273,
        1.79209176e-313, 1.45259949e-308, 1.33360294e+241, 4.31571504e-310,
        1.43229092e+089, 3.27748881e-313, 2.05210913e-307, 1.33360332e+241,
        1.49568806e+243, 1.14197836e+243, 5.23920761e-310, 3.00384344e-273,
        1.24805375e+243, 7.66637482e+199, 5.45658405e-310, 8.83636824e-090,
        9.64347618e-313, 1.68400738e-019, 1.28310547e-225, 2.89544668e-312,
        1.09385187e-303, 1.36727173e-303, 2.78138476e-309, 2.78681707e-309,
        2.78138476e-309, 2.78138476e-309, 2.78138476e-309, 2.78681707e-309,
        2.78138476e-309, 5.98224249e-299, 2.18723328e-284, 1.73394944e-255,
        3.33846309e-289, 2.43977751e-260, 9.11749059e-304, 2.01878821e-284,
        2.52282277e-284, 0.00000000e+000]),
 'elist': array([7.86630709e-009, 1.01263339e-014, 9.97338022e-313, 2.48273508e-312,
        2.33419537e-312, 2.41907520e-312, 2.52517499e-312, 2.41907520e-312,
        9.97338022e-313, 2.56761491e-312, 2.44029516e-312, 9.97338022e-313,
        2.56761491e-312, 2.44029516e-312, 9.97338022e-313, 2.56761491e-312,
        2.44029516e-312, 9.54898106e-313, 2.07955588e-312, 2.37663529e-312,
        2.10077583e-312, 2.14321575e-312, 2.01589600e-312, 2.37663529e-312,
        2.46151512e-312, 2.35541533e-312, 2.01589600e-312, 2.35541533e-312,
        2.37663529e-312, 2.46151512e-312, 2.46151512e-312, 2.35541533e-312,
        2.44029516e-312, 2.22809558e-312, 2.01589600e-312, 2.10077583e-312,
        2.14321575e-312, 2.10077583e-312, 2.01589600e-312, 2.33419537e-312,
        2.01589600e-312, 2.33419537e-312, 2.22809558e-312, 2.14321575e-312,
        2.41907520e-312, 2.33419537e-312, 9.97338022e-313, 2.35541533e-312,
        2.27053550e-312, 6.91876728e-310])}
x1 = np.linspace(0, 4.5, 150)
(np.trapz(integrand(x1), x1) - I) / I
-1.3991438186509969e-05

Summary

Today we introduced several ideas about using Jupyter notebooks to run Python computations. The main points are:

  1. Code is run in code cells

  2. You have to import some functions from libraries

  3. numpy, scipy and matplotlib are three of the main scientific programming libraries we will use a lot.

  4. We saw some ways to get help on functions

Next time we will dig into defining functions more deeply, and how to print formatted strings containing results.