Scientific Computing with Python

This is a course about applying computer programming to problems of modeling physical systems and analysing data related to those systems. We'll be using a programming language called "Python 3". The first project is a "getting started" experience where you start to use the programming environment, become familiar with the basic elements of the language and, more or less, "learn your way around." Let's get started!

Notebook UI + Help

Before we get too far, first click on the "Help" menu and choose "User Interface Tour" and then "Keyboard Shortcuts". Look over these and remember where they are if you get stuck. You'll also see that under the "Help" menu there are links to module specific help sites for all the major python packages we'll be using this semester.

Built in types

First things first. Python comes with many "built in" types. These are things like integers, floating point numbers, srings, tuples, lists and dictionaries. Let's go over those one at a time.

Integers and floats are easy:


In [1]:
#
# When the cursor is in this cell hit "shift enter" to execute the python code here
#

x=3     # x is assigned an integer value of 3
y=2.4   # y is assigned a floating point value of 2.4
print("x and y are:", x, 'and',y)


x and y are: 3 and 2.4

Like most programming languages you can operate on these values using unary and binary operators, like so:


In [2]:
z=x+y
print("The value of z is:", z)


The value of z is: 5.4

Tuples and Lists

These guys are used to track collections of things. For example you can have a list of integers like so:


In [3]:
aList = [1,2,9,4,7]
print("We have a list:", aList, "with a length of:", len(aList))

aTuple = (1,2,9,4,7)
print("We have a tuple:", aTuple, "with a length of:", len(aTuple))


We have a list: [1, 2, 9, 4, 7] with a length of: 5
We have a tuple: (1, 2, 9, 4, 7) with a length of: 5

The difference between these guys is that a list is 'mutable' and a tuple is not. In other words you can change a list by inserting, appending and deleting elements of the list, but a tuple, once born, cannot be modified.


In [4]:
aList.append(17)
print("We now have a modified list:", aList, "with a length of ", len(aList))


We now have a modified list: [1, 2, 9, 4, 7, 17] with a length of  6

In [5]:
aTuple.append(12) # this will fail! You can't append to a tuple.


---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-5-4fe31d469fca> in <module>()
----> 1 aTuple.append(12) # this will fail! You can't append to a tuple.

AttributeError: 'tuple' object has no attribute 'append'

Items within Tuples and lists can be accessed using their "index". Note that index values start at "0":


In [6]:
print("element 3 of the list is", aList[3])


element 3 of the list is 4

In [7]:
print("element 27 of the tuple is", aTuple[27]) # this will fail! There is no such element.


---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-7-9aa3d7cc188c> in <module>()
----> 1 print("element 27 of the tuple is", aTuple[27]) # this will fail! There is no such element.

IndexError: tuple index out of range

Note: When you "multiply" a list or a tuple by an integer you get copies of the original:


In [8]:
print(aList*3)
print(aTuple*4)


[1, 2, 9, 4, 7, 17, 1, 2, 9, 4, 7, 17, 1, 2, 9, 4, 7, 17]
(1, 2, 9, 4, 7, 1, 2, 9, 4, 7, 1, 2, 9, 4, 7, 1, 2, 9, 4, 7)

Strings

A string is a collection of characters, which like a list can be indexed, but has extra methods that only make sense for strings. We use string to manage textual data.


In [9]:
aString = "hello there world!"
print("We have a string:", aString, "whose length is:", len(aString))

print("the 9th element of aString is", aString[9])


We have a string: hello there world! whose length is: 18
the 9th element of aString is r

String methods

You can manipulate strings by using built-in methods of string objects like so:


In [10]:
print(aString.split()) # split a string on spaces, convert to a list


['hello', 'there', 'world!']

In [11]:
bString="""1,2,3,4
5,6,7,8
9,10,11,12
"""

print("Here's what bString looks like:", repr(bString))
print("Let's split the lines:", bString.splitlines())


Here's what bString looks like: '1,2,3,4\n5,6,7,8\n9,10,11,12\n'
Let's split the lines: ['1,2,3,4', '5,6,7,8', '9,10,11,12']

In [12]:
print(aString.upper())


HELLO THERE WORLD!

Dictionaries

A dictionary is a structured type, similar a list in that it can be indexed, but not ordered like a list:


In [13]:
aDict = {'a':1, 'b':"sam", 'joe':3.1415927}
print("We have a dictionary with keys:", aDict.keys())
print("It as values:", aDict.values())
print("And items:", aDict.items())
print("You can index it like an array:", aDict['joe'])


We have a dictionary with keys: dict_keys(['a', 'b', 'joe'])
It as values: dict_values([1, 'sam', 3.1415927])
And items: dict_items([('a', 1), ('b', 'sam'), ('joe', 3.1415927)])
You can index it like an array: 3.1415927

import this

While you can do a lot with built-in python types, for many things we have to do in scientific computing it makes sense to import additional functionality using an "import" statement. Let's import the Pandas libaray using the python import statment:


In [14]:
# tell the plotting system that we want plots inside the notebook
%matplotlib inline   
import pandas as pd  # we're renaming pandas as 'pd' here to save typing

The most important object defined in pandas is the DataFrame. Here's one way to create a DataFrame with pandas using a dictionary:


In [15]:
myDF = pd.DataFrame({'x':[1,2,3,4,5], 'y':[9,8,7,6,5]})

This creates a DataFrame with two "Columns" x and y. You can fetch the columns individually:


In [16]:
print("Here is x:", myDF.x.values)
print("Here is y:", myDF.y.values)


Here is x: [1 2 3 4 5]
Here is y: [9 8 7 6 5]

In [17]:
#
# It is possible to plot directly from the DataFrame
#

myDF.plot('x','y')


Out[17]:
<matplotlib.axes._subplots.AxesSubplot at 0x109dd9898>

Logic and Loops

It's hard to do much without loops sooner or later! There are two basic types of loops in python "for" and "while". The while loop executes the statements within it's scope until a logical expression becomes False. A for loop executes the statements within it's scope for every element of a sequence (e.g., a list, tuple, or any other sequence type). Basically if you have a sequence you need to iterate over, use a for loop. On the other hand, if you want to iterate until some condition is met, then use a while.

Here's an example:


In [18]:
print("Starting with:", repr(bString)) # show the raw string
for s in bString.splitlines():
    print("Breaking down the string:", s)
    for n in s.split(','):
        print("Found the item:", n)


Starting with: '1,2,3,4\n5,6,7,8\n9,10,11,12\n'
Breaking down the string: 1,2,3,4
Found the item: 1
Found the item: 2
Found the item: 3
Found the item: 4
Breaking down the string: 5,6,7,8
Found the item: 5
Found the item: 6
Found the item: 7
Found the item: 8
Breaking down the string: 9,10,11,12
Found the item: 9
Found the item: 10
Found the item: 11
Found the item: 12

In [19]:
#
# another way with the while loop
#

cList=bString.splitlines()
while len(cList)>0:
    s=cList.pop(0) # pop off the zeroth element of the list
    for n in s.split(','):
        print("Found item:", n)


Found item: 1
Found item: 2
Found item: 3
Found item: 4
Found item: 5
Found item: 6
Found item: 7
Found item: 8
Found item: 9
Found item: 10
Found item: 11
Found item: 12

Functions

We often need to encapsulate code so that it can be easily re-used. This is a part of breaking down problems into smaller parts that are more manageable. Functions are easy to define in python, the basic syntax is:


In [20]:
def myFunction(x):        # function to compute 1.0/(x**2 + 1.0)
    aLocalVar = x*x+1.0   # this is x**2 + 1.0
    return 1.0/aLocalVar  # finally 1.0/(x**2 + 1.0)

for i in range(10):
    print("i=",i,"myFunction(i):", myFunction(i))


i= 0 myFunction(i): 1.0
i= 1 myFunction(i): 0.5
i= 2 myFunction(i): 0.2
i= 3 myFunction(i): 0.1
i= 4 myFunction(i): 0.058823529411764705
i= 5 myFunction(i): 0.038461538461538464
i= 6 myFunction(i): 0.02702702702702703
i= 7 myFunction(i): 0.02
i= 8 myFunction(i): 0.015384615384615385
i= 9 myFunction(i): 0.012195121951219513

Odds and Ends

Numpy Arrays

Another package we'll need to finish our "quick tour" of python tools is numpy. This library provides very fast homogeneous arrays.

Matplotlib Graphing

We'll be using matplotlib to make more sophisticated graphs

Sympy

For symbolic computations we'll be using sympy.


In [ ]: