Basic Python

Quentin CAUDRON
Ecology and Evolutionary Biology
qcaudron@princeton.edu
@QuentinCAUDRON

This section moves quickly. I'm assuming that everyone speaks at least one programming language, and so this chapter gives a lightning intro to syntax in Python. The sections are subheaded, but they really overlap quite a lot, so they're there more as a page reference...

Variables and Arithmetic


In [1]:
print("He said, 'what ?' \n")


He said, 'what ?' 

In standard programming language tradition, we begin with a "Hello world" equivalent. We can immediately see a few things :

  1. Standard in / out ( writing to screen, for instance ) is available without invoking any libraries. That is, the Python Standard Library comes with some useful things - w00t.

  2. Strings are delimited by "", but can also use ''. This is useful because you can now use one set of quotes inside another, and it'll still be one big string.

  3. The print function seems to be happy with and without brackets. This is only true in Py2. Py3 requires brackets, and because print is a function that takes arguments like any other, we'll try keep the brackets as good practice - but I usually fail here...


In [2]:
s = "This is a string."
print(s)
print(type(s))


This is a string.
<type 'str'>

In [1]:
s = 42
print(s)
print(type(s))


42
<type 'int'>

Variables don't need to be given a type, as Python is dynamically-typed. That means if I wanted to reuse s as an integer, Python would have no issue with that.


In [2]:
print(s * 2) # Multiplication
print(s + 7) # This one's really hard


84
49

Single-line comments use #. Arithmetic uses the standard operators : +, -, *, /. You can take powers using **. Python also allows C-like += syntax :


In [3]:
s += 2**3 # s is being incremented by 2^3
print "Same as s = s + 2**3"
print s


Same as s = s + 2**3
50

Note that, two cells up, we called s*2 and s+7, but never used =, so we never changed s. In the last cell, however, we used +=.

That statement is equivalent to saying s = s + 2**3, it's just shorthand. Also works with -=, *=, /=, **=


In [4]:
print(s == 42)
print(s == 50)
print(s > 10)


False
True
True

The == operator is the comparison operator. Here, we also see Python's syntax for logical statements : True and False. As with any programming syntax, capitalisation is important. In Python, 1 is also True, and 0 is also False.


In [5]:
x = "Blah"
print(x + x)
print(len(x))


BlahBlah
4

Lists

Strings can be concatenated using the + operator. The len() function returns the length of a string. This also works for lists :


In [10]:
mylist = [1, 2.41341]
mylist.append("We can mix types !")

print(mylist)
print("Length is " + str(len(mylist))) # note how we TYPECAST an integer ( returned by len() ) into a string
print(type(mylist))


[1, 2.41341, 'We can mix types !']
Length is 3
<type 'list'>

In [11]:
mylist


Out[11]:
[1, 2.41341, 'We can mix types !']

Here, we typecast the integer len(mylist) into a string by simply calling str on it. We can typecast to any valid Python type : float, int, str, complex, ... It's worth noting that this is not the best practice for writing variables into text strings. We'll get to the better method in a while.

Python accesses elements in lists from 0, not from 1 as in Matlab or R. This will be familiar to C users.


In [12]:
print(mylist[0])
print(mylist[1])
print(mylist[2])


1
2.41341
We can mix types !

Control Structures

For loops in Python are really cool. Python objects like lists are iterables. That is, we can directly iterate over them :


In [13]:
for i in mylist :
    print i
    print "Hello"
print "Finished"


1
Hello
2.41341
Hello
We can mix types !
Hello
Finished

Note the indentation - this is really important. Loops in Python don't get delimited by brackets like in C or R. Each block gets its own indentation. Typically, people use tabs, but you can use any amount of whitespace you want as long as you are consistent. To end the loop, simply unindent. We'll see that in a few lines.

Here, the keyword in individually returns members of mylist. It can also be used to check whether something is in a container :


In [15]:
print (1 in mylist)
print (2 in mylist)


True
False

If you wanted to loop by indexing the list, we can use range(), which, in its simplest ( single-argument ) form, returns a list from 0 to that element minus 1.


In [16]:
for i in range(len(mylist)) :
    print i, mylist[i]


0 1
1 2.41341
2 We can mix types !

A quick way to do this is the enumerate function :


In [17]:
for index, value in enumerate(mylist) :
    print("Element number " + str(index) + " in the list has the value " + str(value))


Element number 0 in the list has the value 1
Element number 1 in the list has the value 2.41341
Element number 2 in the list has the value We can mix types !

Great. What about while loops and if statements ?


In [18]:
if True :
    print "Hello"


Hello

Notice how the contents of the while loop are indented, and then code that is outside the loop continues unindented below. Here's a nested loop to clarify :


In [19]:
for i in range(1, 5) :
    blah = 0
    
    for j in range(i) :
        blah += 2
        print "Inner blah loop " + str(j), str(blah)
        
    print "i = " + str(i)
print "I'm done here."


Inner blah loop 0 2
i = 1
Inner blah loop 0 2
Inner blah loop 1 4
i = 2
Inner blah loop 0 2
Inner blah loop 1 4
Inner blah loop 2 6
i = 3
Inner blah loop 0 2
Inner blah loop 1 4
Inner blah loop 2 6
Inner blah loop 3 8
i = 4
I'm done here.

Here, we used range() with two arguments. It generates a list from the first argument to the second argument minus 1. Also, note that we can feed the print statement several things to print, separated by a comma. Again, we can use brackets if we want for print.

Interacting Between Different Variable Types

Beware of integer division. Python uptypes cross-type operations. Unlike R, Python doesn't assume that everything is a float unless explicitly told; it recognises that 2 is an integer, and this can be good and bad.


In [20]:
myint = 2
myfloat = 3.14
print type(myint), type(myfloat)


<type 'int'> <type 'float'>

In [21]:
# Multiplying an int with a float gives a float, we've UPTYPED
print myint * myfloat
print type(myint * myfloat)


6.28
<type 'float'>

In [22]:
# But operations between SAME type gives the same type :
print 7 / 3
print type(7/3) # uh oh


2
<type 'int'>

In [23]:
# Quick hack with ints to floats - there's no need to typecast, just give it a float 
print float(7) / 3
print 7 / 3.0


2.33333333333
2.33333333333

More Lists : Accessing Elements

Let's go back to lists. They're a type of generic, ordered container; their elements can be access in several ways.


In [24]:
# Create a list of integers 0, 1, 2, 3, 4
A = range(5)
print A


[0, 1, 2, 3, 4]

In [25]:
# Let's replace the middle element
A[2] = "Naaaaah"
print A


[0, 1, 'Naaaaah', 3, 4]

In [26]:
# What are the middle three elements ? Let's use the : operator
# Like range(), it creates a list of integers
# 1:4 will give us 1, 2, 3 because we stop at n-1, like with range()
print A[1:4]


[1, 'Naaaaah', 3]

In [27]:
# So what's the point of both range() and the : operator ?
# We don't need to give it a start or an end with :
print A[:2]
print A[2:]


[0, 1]
['Naaaaah', 3, 4]

In [28]:
# Can we access the last element ? What about the last two ?
print A[len(A)-2:]
print A[-2:]


[3, 4]
[3, 4]

In [29]:
# Earlier, we saw that range() can take two arguments : range(start, finish) 
# It can actually take a third : range(start, finish, stride)
print range(0, 5, 2)


[0, 2, 4]

In [30]:
# Similarly, the : operator can also do this
print A[0:5:2]
# Here, it will give us elements 0, 2, 4.


[0, 'Naaaaah', 4]

In [31]:
# Again, what if I don't want to explicitly remember the size of the list ?
print A[::2]
# This will simply go from start to finish with a stride of 2


[0, 'Naaaaah', 4]

In [32]:
# And this one, from the second element to finish, with a stride of 2
print A[1::2]


[1, 3]

In [33]:
# So, uh... Reverse ?
print A[::-1]


[4, 3, 'Naaaaah', 1, 0]

In [34]:
# List arithmetic is fun, but don't get too attached : you may not be using many lists in the future...
print A + A
print A * 4


[0, 1, 'Naaaaah', 3, 4, 0, 1, 'Naaaaah', 3, 4]
[0, 1, 'Naaaaah', 3, 4, 0, 1, 'Naaaaah', 3, 4, 0, 1, 'Naaaaah', 3, 4, 0, 1, 'Naaaaah', 3, 4]

Dictionaries

Let's take a very brief look at dictionaries. These are unordered containers that you can use to pair elements in, similar to a std::map if you're a C++ coder.


In [35]:
pythonSkillz = { "Quentin" : 1. / 3, "Paul" : 42 }
print pythonSkillz


{'Paul': 42, 'Quentin': 0.3333333333333333}

In [36]:
# Dictionaries associate keys with values
print pythonSkillz.keys()
print pythonSkillz.values()


['Paul', 'Quentin']
[42, 0.3333333333333333]

In [37]:
# You can access them through their keys
print pythonSkillz["Paul"] * 2


84

There are a couple of other built-in containers, like tuples and sets. I won't go into them here, plainly because I have to use them so rarely that it's not worth the time during the session. If you want to read up : http://docs.python.org/2/tutorial/datastructures.html

List Comprehension and Inlines

A couple of cool final tricks :


In [38]:
# Let's build a list of elements 1^2, 2^2, 3^2, ..., 10^2
x = range(1, 11)
y = [i**2 for i in x]
print y[3:5]


[16, 25]

In [39]:
# We can inline if statements too
print "Trust me, I know what I'm doing." if pythonSkillz["Paul"] > 0 else "Whaaaaaaa"


Trust me, I know what I'm doing.

Functions


In [40]:
# Fibonacci numbers
# OH NO RECURSION

def fib(n) :
    if n == 0 :
        return 0
    elif n == 1 :
        return 1
    else :
        return fib(n-1) + fib(n-2)
    
print "Done defining"


Done defining

In [48]:
# Testing :
for i in range(1, 10) :
    print fib(i)


1
1
2
3
5
8
13
21
34

Looks good. We've just defined a function that takes one argument, n, and returns something based on what n is. The Fibonacci function is quite particular because it calls itself ( recursion ), but it's a small, fun example, so why not.

Better Printing

Earlier, I used the + operator to concatenate a number into a string. To do that, I had to typecast it. Not great. This is the better way to do it :


In [44]:
def printFib(i) :
    print "The %dth number of the Fibonnaci sequence is %d." % (i, fib(i))

In [45]:
printFib(20)


The 20th number of the Fibonnaci sequence is 6765.

Here, %d is a format code for integer. %f is for floating point numbers ( floats ), and %s is for strings. The sneaky one to know is %r, which just takes any type.

Note how, to pass more than one thing in, we had to put it into round brackets. This is a tuple, we mentioned it briefly in the last notebook. It's basically just an immutable list. String formatting like this takes tuples.


In [49]:
# I stole this one from Learn Python The Hard Way ( highly recommended ) :
formatstring = "Start %r %r %r %r"
print formatstring % (formatstring, formatstring, formatstring, formatstring)


Start 'Start %r %r %r %r' 'Start %r %r %r %r' 'Start %r %r %r %r' 'Start %r %r %r %r'

Also worth knowing are \n and \t : the newline and tab characters, respectively.


In [50]:
# Written on-the-fly, because I got mad skills
print "This is a haiku\n\tI'm awful at poetry\nWait, this really worked"


This is a haiku
	I'm awful at poetry
Wait, this really worked

File IO

A very, very quick look at file IO, because there are packages that can do a better job.


In [51]:
myfile = open("README.MD", "r")
for line in myfile :
    print line
    
# There are other options instead of looping over each line. You can instead use myfile.read().
# Writing : you can dump a variable using myfile.write() after having opened it in "w" mode.

# There are many other ways to read and write files, including ways to read and write CSV directly.


Python-Workshop

===============



PrincetonPy's one-day workshop, **Introduction to Python for Scientific Computing**.



The material comes as a series of IPython Notebooks :



- 0. **Introduction and Setup** - a brief introduction to what Python is about, and some recommendations for 

what to install.

- 1. **Basic Python** - very quick intro to variables, control structure, lists, dictionaries, functions, IO; 

to 

get you on your feet.

- 2. **Numpy, Scipy, Matplotlib** - the *Scipy Stack* which forms the basis of scientific coding in Python.

- 3. **Demos** - lmfit, scikit-learn, scikit-image, pandas, pickle, pymc; some packages I use for cool 

scientific work.

- 4. **Exercises** - a Notebook helping you through some real data analysis, using real data collected during 

my PhD.

OK, with that - onto the Scientific Python Stack.