Python for Water Resources Engineering

Jon Herman, University of California, Davis

1. Python language basics - variables, loops, lists, and dicts

Even without the scientific packages, Python provides readable, easy-to-use variables and data structures. There are already very good tutorials on these topics from a computer science perspective, such as Learn Python the Hard Way. This will be a quick overview of the basics before moving on to engineering applications.

Defining variables (no type declaration):

In [6]:
a = 5 # this is a comment
b = 10.0
c = 'this is a string'
print "Output = " + str(a) + ", " + str(b)
Output = 5, 10.0

Lists and loops:

In [7]:
L = [10.0, 3.0, 'some words', 2]
for item in L:
    print(item)
10.0
3.0
some words
2

If statements: As with for loops, these require : characters at the end of the line. Other lines in Python do not require line ending characters. Use and and or keywords to connect multiple logical statements.

In [11]:
if a==5:
    print("a is 5")
elif a==3:
    print("a is 3")
else:
    print("a is neither 5 nor 3")
a is 5

Whitespace: As you see in the previous examples, whitespace matters in Python. There are no brackets {} to denote code blocks. Use either spaces or tabs to indent for loops and if statements.

Ranges and slicing: The range() function returns a sequence of integers in a list. Its arguments are (start, stop, step), and the stop value is not included in the range. Only stop is required; default values for start and step are 0 and 1, respectively.

In [15]:
L = range(1,10,2)
print(L)

count = 0
for i in range(10):
    count += i
print(count)
[1, 3, 5, 7, 9]
45

Slicing (retrieving values from a list) follows a similar syntax: start:stop:step. Any of these can be omitted with the same default values as above. This is important, because later we'll use NumPy arrays and matrices with the same syntax for indexing.

In [16]:
L = range(10)
print L[0] # get a single value (Python indices start at 0)
print L[5:] # values 5-end
print L[:5] # values start-5
print L[3:9:2] # values 3-9 in steps of 2
print L[::-1] # whole list with step=-1 (reverse order)
0
[5, 6, 7, 8, 9]
[0, 1, 2, 3, 4]
[3, 5, 7]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

Lists may look like vectors, but in general they are too slow to use for scientific computing applications, especially if you append new values to the end of the list. In the next tutorial, NumPy will solve that issue for us.

Dictionaries: A set of key-value pairs, which you can think of as a lookup table. Unlike lists, the values in a dictionary are not ordered, and they are indexed with strings instead of integers. Lookups are very fast because you don't have to search for items.

In [18]:
person = {'name': 'Terry', 'age': 42, 'weight': 160}

print('This person is named ' + person['name'] + ' and they are ' + str(person['age']) + ' years old')
This person is named Terry and they are 42 years old

Combining lists and dicts: Both data structures are flexible enough to accept values of any type. This means you can have a list of dictionaries, a dictionary of lists, and any number of nested combinations you can think of! Dictionaries are a good way to handle data in your program, even more complicated objects like matrices, because the items are easy to access.

In [19]:
person_2 = {'name': 'Chris', 'age': 31, 'weight': 155}
people = [person, person_2]
company = {'workers': people, 'num_workers': len(people)}

for p in company['workers']:
    print p['name']
Terry
Chris

Functions: A function accepts one or more arguments and returns a value. We've already seen the range() function, for example, but we can define our own too. The arguments and return values can be any type, including lists and dicts.

In [20]:
def square(x):
    return x**2

def square_list(L):
    return [square(x) for x in L] # this is called a "list comprehension" -- makes things easy

print(square(5))
print(square_list(range(10)))
25
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Keyword arguments: Functions can accept either positional or keyword arguments. Positional arguments are identified by their order, while keyword arguments are explicitly named and may be given a default value in the function definition.

In [23]:
def square(x, a=0):
    return (x+a)**2

print(square(5))
print(square(5,2))
25
49

Again, this is only an overview of the Python language. Whenever you see syntax you don't recognize, you should check whether it comes from Python itself or from a particular scientific package. Spend some time with Learn Python the Hard Way for a much more detailed tutorial of the language.

On to engineering! Part 2: NumPy and Matplotlib