Introduction to Python

Timomthy Brown
Research Computing
CU Boulder

This introduction was written by Monte Lunacek.

Let us change our traditional attitude to the construction of programs: Instead of imagining that our main task is to instruct a computer what to do, let us concentrate rather on explaining to humans what we want the computer to do.

Donald E. Knuth, Literate Programming, 1984

What is Python?

Python is a general-purpose programming language that blends procedural, functional, and object-oriented paradigms

Mark Lutz, Learning Python

  • Simple, clean syntax
  • Easy to learn
  • Interpreted
  • Strong, dynamically typed
  • Runs everywhere: Linux, Mac, and Windows
  • Free, as in beer and speach
  • Expressive: do more with fewer lines of code
  • Lean: modules
  • Options: Procedural, object-oriented, and functional.

Why Python?

  • Scripting lanugage
    • os support
    • glue existing applications
  • Scientific abstraction
    • Use highly optimized C and Fortran libraies
    • Intel MKL, HDF5, Blas, Lapack, MPI, Cuda, SVM
  • Data Analysis
  • Visualization
  • Scrape websites
  • Build websites
  • Anything!

Performance

CPU time is cheap, my time is expensive

  • Expressive: minimal time required to develop code.
  • Rapid protoytping.
  • Interpreted and dynamically typed means it's slower.
  • Implementing the built-in Python modules would require some advanced programming skills in other languages

Python environments

Interative coding

The Basics

Python Files

  • Extension: files end in .py
    • Not strictly required
    • e.g. script.py
  • Execution:
    • CANOPY: play button
    • IPython: run script.py
    • Python terminal: python script.py

The import Statement

  • Python is made up of several modules.
  • Before you can use a module, you must import it.
In [1]:
import math

Gives access to all functions and objects in the math module.

In [2]:
print math.pi
3.14159265359

In [3]:
print math.cos(10)
-0.839071529076

The prefix is helpful in avoiding name collision.

Alternative imports

Import all symbols so we no longer need the math prefix

In [6]:
from math import *

print pi
3.14159265359

Import select symbols

In [7]:
from math import pi, cos

myvar = 1.4
print cos(myvar)
0.1699671429

What is available?

In [8]:
print dir(math)
['__doc__', '__file__', '__name__', '__package__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'hypot', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc']

In [9]:
help(math.pow)
Help on built-in function pow in module math:

pow(...)
    pow(x, y)
    
    Return x**y (x to the power of y).


Common imports:

In [10]:
import os, sys, math, shutil, re, subprocess

Comments

Every line of text in your file is considered python code uless it is preceeded by a # sign

In [11]:
# This is a comment
# It's ignored by the python interpreter

print(cos(pi)) # this is also ignored
-1.0

Variables

  • Variable names in Python can contain:
    • alphanumerical characters a-z, A-Z, 0-9
    • Undescore _
  • Cannot be a keyword

    and, as, assert, break, class, continue, def, del, elif, else, except, 
    exec, finally, for, from, global, if, import, in, is, lambda, not, or,
    pass, print, raise, return, try, while, with, yield
  • Convension: names start with
    • lowercase for variables
    • Uppercase for objects
  • The = character is assignment

In [12]:
x87_ = 10
print x87_
10

Data types

In a dynamically typed language, the type is determined at assigment.

In [13]:
a = 2
b = 1e9
c = False
d = "A string"
In [14]:
print type(a)
print type(b)
print type(c)
print type(d)
<type 'int'>
<type 'float'>
<type 'bool'>
<type 'str'>

Type casting

In [15]:
print a,b,c,d
2 1000000000.0 False A string

In [16]:
print float(a)
print int(2.6)
print str(c)
2.0
2
False

In [17]:
print d, float(d)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-17-e54c9bdba762> in <module>()
----> 1 print d, float(d)

ValueError: could not convert string to float: A string
A string
In [18]:
print float("24")
 24.0

None

This is the null value type in Python.

In [19]:
value = None
print value
None

Example: Scientific Hello World

In [24]:
import math
r = float("4.2")
s = math.sin(r)
print "hello world! The sin(" +  str(r) + ") =", s
hello world! The sin(4.2) = -0.871575772414

  • cast "4.2" to a float
  • String concatentation +

Data Structures

  • String
  • Lists
  • Tuples
  • Dictionaries

Strings

  • A string is a container of characters.
  • Python strings are immutable, meaning they cannot change once assigned.
In [19]:
s = "Hello world, world"
print type(s)
<type 'str'>

Length

In [20]:
print len(s)
18

In [21]:
s[0] = 'h'
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-21-855719672658> in <module>()
----> 1 s[0] = 'h'

TypeError: 'str' object does not support item assignment

Find and replace (notice the immutability).

In [22]:
s2 = s.replace("world", "python")
s3 = s2.replace("Hello","monty")
print s
print s2
print s3
Hello world, world
Hello python, python
monty python, python

Slicing, more on this later

In [26]:
print s
print s[6:11]
Hello world, world
world

In [27]:
print s[6:]
world, world

In [28]:
print s[-2:]
ld

Concatenation

In [30]:
print s
print s3
Hello world, world
monty python, python

In [31]:
s4 = s + ' ' + s3
print s4
Hello world, world monty python, python

Find

In [7]:
print s4.find('world')
6

In [32]:
print s4.find('monty')
19

Formatting

In [33]:
print 'A string with value {0} and {1}'.format(10,20.3)
A string with value 10 and 20.3

More string help...

In [34]:
#help(str)

Lists

  • A list is a container of objects.
  • They do not need to be the same
  • Mutable
In [36]:
values = ['1',2,3.0,False]
print len(values)
print values
4
['1', 2, 3.0, False]

In [37]:
print type(values)
<type 'list'>

Slicing

In [38]:
print values
print values[1]
['1', 2, 3.0, False]
2

In [39]:
print values[:3]
['1', 2, 3.0]

In [40]:
print values[2:]
[3.0, False]

Append and remove

  • Note: mutability
In [41]:
l = []
l.append(8)
l.append(10)
l.append(10)
l.append(12)
In [42]:
print l
[8, 10, 10, 12]

In [43]:
l.remove(10)
print l
[8, 10, 12]

In [44]:
l.remove(l[0]) # Can also say del
print l
[10, 12]

Generating lists

Create a list using the function range(start,stop,step).

In [52]:
l = range(0,10,2)
print l
[0, 2, 4, 6, 8]

In [53]:
l = range(-5,5)
print l
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4]

In [54]:
line = "This is a    \t list -      \t of strings"
print len(line.split('\t'))
print line.split('\t')
3
['This is a    ', ' list -      ', ' of strings']

Sorting

Notice this is modifying the list.

In [70]:
l = range(-5,5)
print l

l.sort(reverse=True)
print l
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4]
[4, 3, 2, 1, 0, -1, -2, -3, -4, -5]

Tuples

  • Sequence of objects, like lists.
  • But they are immutable
In [61]:
t = (10,40.0,"A")
In [12]:
print type(t), len(t)
<type 'tuple'> 3

In [13]:
t[1] = 'B'
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-13-97fa05af13f0> in <module>()
----> 1 t[1] = 'B'

TypeError: 'tuple' object does not support item assignment

Unpacking

A Python favorite!

Unpack the tuple

In [14]:
print t
x,y,z = t #Unpacking
print z
(10, 40.0, 'A')
A

Unpack the list.

In [15]:
print l
A, B = l[:2]
print B
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4]
-4

Dictionaries

  • A flexible collection of {key: value} pairs.
  • Also called associative arrays or hash maps in other languages.
Another Python favorite!
In [86]:
data = {}

data['k1'] = True
data['x2'] = 2
data[100] = 3.0
In [87]:
print data
{'x2': 2, 'k1': True, 100: 3.0}

In [88]:
print len(data), type(data)
3 <type 'dict'>

Add a new entry

In [89]:
data['k4'] = 100

Example

In [106]:
data = {'number': 10, 1:'string'}
data['c'] = [1,2,3,4]
In [93]:
print data
{1: 'string', 'c': [1, 2, 3, 4], 'number': 10}

In [94]:
print data[1]
string

In [95]:
print data['c'][3]
4

In [96]:
print data['number']
10

Default values

In [107]:
print data.get('number',0)
10

In [108]:
print data.get('B',0) # The key `B` does not exist
0

In [109]:
data['B'] = data.get('B',0) + 100
print data.get('B',0) 
100

Control Flow

  • Indention
  • if, elif, and else
  • for loops
  • while loops
  • exception handling

Indention

There are no braces ({,}) around blocks of code in Python.

  • Instead, python uses whitespace
  • Example if statement in C++
if( value < 0){
    std::cout << value << std::endl;
}
std::cout << "done" << std::endl;

  • In python, a colon (:) denotes the start of a block.
if value < 0:
    print value
print done

if, elif, and else

In [2]:
cash = .9
if car < cash:
    print 'Enjoy your car ride'
elif bus < cash:
    print 'Another one rides the bus'
elif cash < 1.00:
    print 'stay home'
else:
    print 'Walking..'
stay home

If nothing else, walking.

The ternary expression

In [3]:
action = 'car' if car < cash else 'walking' #one-liner

print action
walking

The for loop

In [4]:
numbers = [1,2,3,4,5]
for i in numbers:
    print i
1
2
3
4
5

In [5]:
for i in range(10,20):
    print i,
10 11 12 13 14 15 16 17 18 19

In [6]:
names = ['pat','jonh']
for name in names:
    print name
pat
jonh

continue

You can skip part of the remaining block.

In [9]:
for i in xrange(10):
    print i,
    if i % 2 == 0:
        print 'even'
        continue
    print "---"
0 even
1 ---
2 even
3 ---
4 even
5 ---
6 even
7 ---
8 even
9 ---

break

Stop executing the entire loop.

In [10]:
for i in xrange(10):
    if i == 5:
        break
    print i
0
1
2
3
4

The while loop

In [21]:
count = 0
while (count < 10):
   print count,
   count += 1
0 1 2 3 4 5 6 7 8 9

When would you prefer a while loop to a for loop?

Exceptions

Gracefully handling errors.

In [12]:
num = '123.4d'
print float(num)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-12-320d5b550040> in <module>()
      1 num = '123.4d'
----> 2 print float(num)

ValueError: invalid literal for float(): 123.4d
In [13]:
try:
    print float(num)
except ValueError, e:
    print e
    print 'This is called Duck Typing'
invalid literal for float(): 123.4d
This is called Duck Typing

Multiple exceptions

In [21]:
def example(values):
    try:
        print float(values)
    except ValueError, e:
        print e
    except TypeError, e:
        print e
        
example(['3','4'])
example('A string?')
float() argument must be a string or a number
could not convert string to float: A string?

enumerate

Sometimes you want the index of a collection and the value. For example:

In [42]:
names = ['Deborah','Carla','Mary','Susan']
In [35]:
index = 0
for name in names:
    print index, names[index], name
    index += 1
0 Deborah Deborah
1 Carla Carla
2 Mary Mary
3 Susan Susan

In [36]:
for i, name in enumerate(names):
    print i, name
0 Deborah
1 Carla
2 Mary
3 Susan

sorted

  • Different than the list method sort.
  • A copy of a stored list.
In [15]:
print sorted(names)
['Carla', 'Deborah', 'Mary', 'Susan']

In [38]:
for name in sorted(names):
    print name,
Carla Deborah Mary Susan

reversed

  • A reverse iterator (e.g. not a list)
In [39]:
for i in reversed(names):
    print i,
Susan Mary Carla Deborah

In [40]:
print list(reversed(names))
['Susan', 'Mary', 'Carla', 'Deborah']

In [41]:
print names
['Deborah', 'Carla', 'Mary', 'Susan']

zip

In [43]:
last = ['Smith','Mason','Carter','Dee']
print last
print names
['Smith', 'Mason', 'Carter', 'Dee']
['Deborah', 'Carla', 'Mary', 'Susan']

In [44]:
together = zip(names, last)
print together
[('Deborah', 'Smith'), ('Carla', 'Mason'), ('Mary', 'Carter'), ('Susan', 'Dee')]

In [45]:
for index, pair in  enumerate(zip(names,last)):
    print index, pair[0], pair[1]
0 Deborah Smith
1 Carla Mason
2 Mary Carter
3 Susan Dee

Comprehension

The Python consise expression.

In [47]:
names.append("Dan")
print names
['Deborah', 'Carla', 'Mary', 'Susan', 'Dan']

Create a list of just names that start with d

In [48]:
dnames = []
for name in names:
    if name.startswith('D'):
        dnames.append(name.lower())
print dnames
['deborah', 'dan']

List Comprehension: the "Python way"

In [49]:
dnames = None
dnames = [name.lower() for name in names if name.startswith('D')]
In [50]:
print dnames
['deborah', 'dan']

Dictonary items()

In [22]:
d = {'a': 10, 'b': 20, 'c': 30}
In [23]:
for i in d.keys():
    print i, d[i]
a 10
c 30
b 20

In [24]:
for k, v in d.items():
    print k, v
a 10
c 30
b 20

The Procedural Python

  • Imperative programming
  • Organization steps
  • Avoid cut-paste!

Outline:

  • Definition
  • Arguments
  • Return types

Definition

In [4]:
def my_function():
    names = ['joe','nate']
    for k in names:
        print k
In [5]:
my_function()
joe
nate

  • The pass keyword is the Python "do nothing" command.
  • Very common for defining, but not implementing, functions.

Arguments

These are positional arguments

In [6]:
def my_function(a,b,c):
    print a,b,c

my_function(2,7,6)
2 7 6

In this example, the variables are named arguments.

In [9]:
def my_function(a,b,c=100):
    print a,b,c
    
my_function(c=2,b=4,a=50)
50 4 2

In [10]:
my_function(a=2,b=4)
2 4 100

Why not pass a dictionary as inputs? **kwargs

  • source: stackoverflow
  • kwargs is a dict of the keyword args passed to the function
In [11]:
def print_keyword_args(**kwargs):
    for key, value in kwargs.iteritems():
        print key, value
In [12]:
print_keyword_args(a=20,b=30)
a 20
b 30

In [13]:
print_keyword_args(a=20,b=30,c=100)
a 20
c 100
b 30

*args

Passing an arbitrary number of arguments to your function

In [15]:
def print_args(*args):
    for index, value in enumerate(args):
        print index, value
In [16]:
print_args(10,20,40)
0 10
1 20
2 40

In [17]:
print_args(10,20)
0 10
1 20

Combination

In [19]:
def print_all(pos, *args, **kwargs):
    print "pos", pos
    
    for index, value in enumerate(args):
        print 'args', index, value
        
    for key, value in kwargs.iteritems():
        print 'kwargs', key, value
In [20]:
print_all("positional",10,20,30,a=40,b=50)
pos positional
args 0 10
args 1 20
args 2 30
kwargs a 40
kwargs b 50

Returning values

In [21]:
def my_function(a,b,c=100):
    if c  == 100:
        return a+b+c
    else:
        return a+b
In [22]:
value = my_function(10,10)
print value
120

In [23]:
value = my_function(1,1,10)
print value
2

Using a tuple

In [27]:
def my_function():
    a = 10
    b = 20.0
    c = "string"
    return a, b, c

Results as a tuple.

In [30]:
print my_function()
(10, 20.0, 'string')

Results as individual variables

In [31]:
x,y,z = my_function()
print x,y,z
10 20.0 string

Multiple values with a dictionary

In [32]:
def my_function():
    a = 10
    b = 20.0
    c = "string"
    return {'a': a, 'b': b, 'c': c}
In [33]:
values = my_function()
print values['a']
10