Tutorial to learn how to create programs in the Python programming language
Python tutorial
What is Python?
How to run Python?
Let’s get coding
Python’s origin
I Guido Van Rossum (Netherlands)
I Created in 1991
I Named after Monty Python’s flying circus
Python is a programming language
simple, powerful, fun
Python is mature yet in active development
Python Enhancement Proposals (PEP)
Python is mature yet in active development
Python Enhancement Proposals (PEP)
Python is a scripting language
I Dynamic typing
I Object oriented
I Interactive
Python is mature yet in active development
Python Enhancement Proposals (PEP)
Python is a scripting language
I Dynamic typing
I Object oriented
I Interactive
Python is cross-platform
Linux, Windows, Mac, android phones, . . .
Python is glue
Easily interacts with
I filesystem, operating system
I command line tools
I compiled libraries (C, C++, Fortran)
Python is glue
Easily interacts with
I filesystem, operating system
I command line tools
I compiled libraries (C, C++, Fortran)
Python is a universe
I Batteries included
I Thousands of high-standard packages out there
I Open-source effort
Python is versatile
I Web Programming
I GUI Development
I Scientific and Numeric
I Software Development
I System Administration
Python happens to be suitable for science
I The “Scientific and Numeric” has been booming for 5 years
I Toolstack bundled as ’scipy’
I Theano, numexpr, numba (Python math compilers)
I Numpy (linear algebra)
I Sympy (computer algebra system)
I Pandas (data analysis)
I Fenics, Fipy (Python for PDEs)
I Vistrails (Python scientific workflow, data exploration and visualization)
I matplotlib, chaco (2D plotting)
I Mayavi (3D visualization)
I Pyomo, cvxpy (Python optimization)
Python is a free and open-source ecosystem
I Tutorials, documentation
I Rapid bug-fixing
I Nightly testing (Continuous integration)
I Survival of the fittest
Python is popular
I Lingua Franca
I A huge user-base to ask/answer questions
I For every nail you want to hit, there might be 5 hammers out there
IEEE Spectrum’s 2014 Ranking
Table of Contents
What is Python?
How to run Python?
Let’s get coding
Option A: as command line argument $ python -c "print ’hello world’"
Option B: editor + command line invocation
Notepad++ (Windows)
.
Option B: editor + command line invocation
Scite (Windows, Linux, Mac)
.
Option B: editor + command line invocation
Gedit (Linux)
.
Option B: editor + command line invocation
Emacs (Windows, Linux, Mac)
.
Option B: editor + command line invocation
Vim (Windows, Linux, Mac)
.
Option B: editor + command line invocation
$ python
What you get
I Syntax highlighting
IPython (Windows, Linux, Mac)
IPython (Windows, Linux, Mac)
IPython (Web)
Option C: interactive
What you get
I Tab completion
I Command history
To paste in IPython, type %paste
Option D: integrated development environment (IDE)
Eclipse (Windows, Linux, Mac)
Option D: integrated development environment (IDE)
Spyder (Windows, Linux, Mac)
Option D: integrated development environment (IDE)
What you get
I Syntax highlighting
I Tab completion
I Command history
I Debugging tools
I Static code analysis
Table of Contents
What is Python?
How to run Python?
Let’s get coding
Syntax: assignment
variable = object
Properties
I Every piece of data is an object
I A variable is a reference to an object
I The object stays alive as long as some variable points to it
(reference counted)
a = 3
Properties
I Immutable
a = 3
Properties
I Immutable
a = a + 1 a += 1
a = 3
Properties
I Immutable
a = a + 1 a += 1
Datatypes: bool
a = True a = False
Properties
I Immutable
Datatypes: float
a = 2.0 a = 2e-3
Datatypes: float
a = 2.0 a = 2e-3
Properties
I Immutable
print a <= 0, a+1
False, 1.002
Datatypes: str
a = "spam" a = 'spam' a = "hello\nworld"
Properties
I Immutable
Datatypes: str
a = "spam" a = 'spam' a = "hello\nworld"
Properties
I Immutable
print a print "world" in a, "spam" + "eggs", "spam" * 3
hello world
True, spameggs, spamspamspam
Datatypes: set
a = {} # empty set
a = {"spam",3} a = {3} a = {1,2,3}
Properties
I Unordered
I No duplicates
I Mutable
Datatypes: set
a = {} # empty set
a = {"spam",3} a = {3} a = {1,2,3}
Properties
I Unordered
I No duplicates
I Mutable
print 2 in a, 5 in a print a.union({2,5})
True, False set([1, 2, 3, 5])
Datatypes: list
a = ["spam",3] a = [] # empty list a = [1,2,3]
Properties
I Ordered
I Duplicates allowed
I Mutable
Datatypes: list
a = ["spam",3] a = [] # empty list a = [1,2,3]
Properties
I Ordered
I Duplicates allowed
I Mutable
print a[0], 2 in a, a.index(2)
1, True, 1
Datatypes: tuple
a = (1,2,3) a = ("spam",3) a = (3,) # note trailing comma a = () # empty tuple
Properties
I Ordered
I Duplicates allowed
I Immutable
Datatypes: dict
a = {"spam": 3, "eggs": 1} a = {3 : "spam", (1,2): "eggs"} a = dict() # empty dictionary a = dict(spam=3,eggs=1)
Properties
I Unordered
I No duplicate keys allowed
I Immutable
Keys must be of immutable type
Datatypes: dict
a = dict(spam=3,eggs=1)
print "spam" in a, "eggs" in a, "foo" in a print "spam" in a.keys() print 3 in a, 3 in a.values()
True True False
True
False True
Syntax: assignment (2)
Recall
I Every piece of data is an object
I A variable is a reference to an object
I The object stays alive as long as some variable points to it (reference counting)
a = {"spam": 3, "eggs": 1} a = 6
Syntax: assignment (2)
Recall
I Every piece of data is an object
I A variable is a reference to an object
I The object stays alive as long as some variable points to it (reference counting)
a = [1,2,3] b = a b[0] = 7 print a
[7, 2, 3]
Observation
I Everything is an object . . .
I . . . so everything has methods and attributes
Observation
I Everything is an object . . .
I . . . so everything has methods
I . . . and everything has documentation
Observation
I Everything is an object . . .
I . . . so everything has methods
I . . . and everything has documentation
I . . . everything has a type
Functions
def spam():
return "eggs"
print spam()
eggs
Indentation determines scope
def spam(a,b,c):
return a+b+c
print spam(1,2,3)
6 def spam(*args): print args return sum(args)
print spam(1,2,3) print spam(1,2,3,4)
(1,2,3)
(1,2,3,4)
def spam(a,b,c="everybody"): print "Greetings to %s! -- %d" % (c,a+b)
spam(1,2) spam(3,4,c="you")
Greetings to everybody! -- 3
Greetings to you! -- 7
def spam(*args,**kwargs): print "Thanks for these arguments:" print " args:", args print " kwargs:", kwargs
spam("eggs",3,boilingtime=12,salt=True)
Thanks for these arguments:
args: (’eggs’, 3) kwargs: {’boilingtime’: 12, ’salt’: True}
Arguments are always passed by reference
def spam(eggs):
eggs.append(2)
my_eggs = [] spam(my_eggs)
print my_eggs
[2]
def factorial(n):
if n==0:
return 1
else: return n*factorial(n-1)
print factorial(5)
24
def factorial(n,partials=[]):
partials.append(n) print partials if n==0:
return 1
else: return n*factorial(n-1,partials=partials)
print factorial(4)
[4]
[4, 3]
[4, 3, 2]
[4, 3, 2, 1]
[4, 3, 2, 1, 0]
print factorial(4)
[4, 3, 2, 1, 0, 4]
[4, 3, 2, 1, 0, 4, 3]
[4, 3, 2, 1, 0, 4, 3, 2]
[4, 3, 2, 1, 0, 4, 3, 2, 1]
[4, 3, 2, 1, 0, 4, 3, 2, 1, 0]
def factorial(n,partials=None):
if partials is None: partials = []
partials.append(n) print partials if n==0:
return 1
else: return n*factorial(n-1,partials=partials)
print factorial(4) print factorial(4)
[4]
[4, 3]
[4, 3, 2]
[4, 3, 2, 1]
[4, 3, 2, 1, 0]
24
[4]
teachers = ["moritz","joel","greg","joris"]
for p in teachers:
print p.capitalize()
Moritz
Joel
Greg
Joris
for i in range(4):
print i
teachers = ["moritz","joel","greg","joris"]
for i in range(len(teachers)):
print i, teachers[i]
0 moritz
1 joel
2 greg
3 joris
teachers = ["moritz","joel","greg","joris"]
for i in range(len(teachers)):
print i, teachers[i]
0 moritz
1 joel
2 greg
3 joris
teachers = ["moritz","joel","greg","joris"]
for i, p in enumerate(teachers):
print i, p
0 moritz
1 joel
2 greg
3 joris
This is pythonic
List comprehension
teachers = "moritz joel greg joris".split(" ")
namelengths = [] for p in teachers:
namelengths.append(len(p))
print namelengths
[6, 4, 4, 5]
This is unpythonic
List comprehension
teachers = "moritz joel greg joris".split(" ")
namelengths = [len(p) for p in teachers]
print namelengths
[6, 4, 4, 5]
This is pythonic
teachers = ["moritz","joel","greg","joris"] homes = ["Freiburg","Barcelona","Freiburg","Leuven"]
for i in range(len(teachers)): print "%s lives in %s" % (teachers[i],homes[i])
moritz lives in Freiburg joel lives in Barcelona greg lives in Freiburg joris lives in Leuven
This is unpythonic
teachers = ["moritz","joel","greg","joris"] homes = ["Freiburg","Barcelona","Freiburg","Leuven"]
for t, p in zip(teachers,homes):
print "%s lives in %s" % (t.capitalize(),p)
Moritz lives in Freiburg
Joel lives in Barcelona
Greg lives in Freiburg
Joris lives in Leuven
This is pythonic
teachers = ["moritz","joel","greg","joris"] homes = ["Freiburg","Barcelona","Freiburg","Leuven"]
print zip(teachers,homes)
[(’moritz’, ’Freiburg’), (’joel’, ’Barcelona’),
(’greg’, ’Freiburg’), (’joris’, ’Leuven’)]
[(’moritz’, ’Freiburg’), (’joel’, ’Barcelona’),
(’greg’, ’Freiburg’), (’joris’, ’Leuven’)]
for t, p in zip(teachers,homes):
code
[(’moritz’, ’Freiburg’), (’joel’, ’Barcelona’), (’greg’, ’Freiburg’), (’joris’, ’Leuven’)]
for t, p in zip(teachers,homes):
code
t, p = ('moritz', 'Freiburg') code t, p = ('joel', 'Barcelona') code
d = dict()
for t, p in zip(teachers,homes): d[t] = p
print d
{’joris’: ’Leuven’, ’joel’: ’Barcelona’,
’greg’: ’Freiburg’, ’moritz’: ’Freiburg’} d = dict(zip(teachers,homes))
print d
{’joris’: ’Leuven’, ’joel’: ’Barcelona’,
’greg’: ’Freiburg’, ’moritz’: ’Freiburg’}
More pythonic
for t, p in d.items():
print "%s lives in %s" % (t.capitalize(),p)
Moritz lives in Freiburg
Joel lives in Barcelona
Greg lives in Freiburg
Joris lives in Leuven
More pythonic
The creative cycle in Python
1. Imagine it (ascii art)
2. Google it (pyfiglet)
3. Install it (pip install pyfiglet – Windows, Linux, Mac)
4. Import it
teachers = ["moritz","joel","greg","joris"]
for t in teachers:
print pyfiglet.figlet_format(t,font="starwars")
teachers = ["moritz","joel","greg","joris"]
for t in teachers: print pyfiglet.figlet_format(t,font="starwars")
from pyfiglet import figlet_format
teachers = ["moritz","joel","greg","joris"]
for t in teachers:
print figlet_format(t,font="starwars")
Slicing
teachers = ["moritz","joel","greg","joris"]
print teachers[0] print teachers[-1] print teachers[:2] print teachers[1:] print teachers[::2] print teachers[1::2]
moritz joris
[’moritz’, ’joel’]
[’joel’, ’greg’, ’joris’]
[’moritz’, ’greg’]
[’joel’, ’joris’]
Iterators
def fibonacci(a,b):
yield a yield b n2, n1 = a, b while True: yield n1+n2 n2, n1 = n1, n1+n2
for i in fibonacci(1,1):
print i if i > 20: break
def simulate(a):
return a**2
print simulate(3)
cache = {12: 144}
def simulate(a):
if a in cache:
return cache[a]
else:
print "working hard" return a**2
print simulate(3) print simulate(12)
working hard 9
cache = {}
def simulate(a):
if a in cache:
return cache[a]
else:
print "working hard" cache[a] = result = a**2 return result
print simulate(3) print simulate(3) cache = {} print simulate(3)
working hard 9 9 working hard
cache = {}
def simulate(a,clear=False):
if clear:
cache = {}
if a in cache:
return cache[a]
else:
print "working hard" cache[a] = result = a**2 return result
print simulate(3) print simulate(3) print simulate(3,clear=True)
4 if clear:
5 cache = {}
----> 6 if a in cache: 7 return cache[a] 8 else:
UnboundLocalError: local variable ’cache’ referenced bef
cache = {}
def simulate(a,clear=False):
global cache if clear:
cache = {}
if a in cache:
return cache[a]
else:
print "working hard" cache[a] = result = a**2 return result
print simulate(3) print simulate(3) print simulate(3,clear=True)
working hard 9 9 working hard
def simulate(a,clear=False,cache={}):
if clear:
cache = {}
if a in cache:
return cache[a]
else:
print "working hard" cache[a] = result = a**2 return result
print simulate(3) print simulate(3) print simulate(3,clear=True)
working hard 9 9 working hard
Functions are objects too
def speaker(message):
def temp(receiver):
print "Hey", receiver, "!", message
return temp
python_promoter = speaker("Time to learn Python")
python_promoter("Moritz") python_promoter("audience")
Hey Moritz ! Time to learn Python
Hey audience ! Time to learn Python
Functions are objects too
def speaker(message):
return lambda r: "Hey " + r + " ! " + message
python_promoter = speaker("Time to learn Python")
print python_promoter("Moritz") print python_promoter("audience")
Hey Moritz ! Time to learn Python
Hey audience ! Time to learn Python
class Model(object):
""" Represents a model """
def __init__(self,labels): self.labels = labels
pendulum = Model(["theta","omega"])
print pendulum
type(pendulum)
__main__.Model
type(pendulum)
__main__.Model
pendulum?
Type: Model
String form:
Docstring: Represents a model
class Model(object):
""" Represents a model """
def __init__(self,labels): self.labels = labels
def __repr__(self): return "Model(" + str(self.labels)+ ")"
pendulum = Model(["theta","omega"])
print pendulum
Model([’theta’, ’omega’]) pendulum?
Type: Model
String form: Model([’theta’, ’omega’])
Docstring: Represents a model
class Pendulum(Model):
def __init__(self,length=1.0):
Model.__init__(self,["theta","omega"]) self.length = length
def describe(self):
print "pendulum with length %d" % self.length
pendulum = Pendulum(2)
print pendulum
Model([’theta’, ’omega’])
print pendulum
Model([’theta’, ’omega’])
print pendulum.length
print pendulum
Model([’theta’, ’omega’])
print pendulum.length
pendulum.length = 4
pendulum.describe()
pendulum with length 4
class Pendulum(Model):
def __init__(self,length=1.0):
Model.__init__(self,["theta","omega"]) self._length = length
def getLength(self):
return self._length
def setLength(self, value): self._length = value
pendulum = Pendulum(2)
pendulum.
pendulum.getLength pendulum.labels pendulum.setLength pendulum.setLength(5) print pendulum.getLength()
5 pendulum.setLength("spam") print pendulum.getLength()
spam
class Pendulum(Model):
def __init__(self,length=1.0):
Model.__init__(self,["theta","omega"]) self._length = length
def getLength(self):
return self._length
def setLength(self, value):
if isinstance(value,int):
self._length = value
else:
raise Exception("Expected number")
pendulum = Pendulum(2) pendulum.setLength("spam")
Exception: Expected number
def setLength(self, value):
if isinstance(value,int):
self._length = value
else:
raise Exception("Expected number")
This is unpythonic
def setLength(self, value): try: self._length = int(value)
except:
raise Exception("Expected number")
This is pythonic
pendulum.setLength(5)
pendulum.setLength(5)
pendulum.setLength('5')
pendulum.setLength(5)
pendulum.setLength('5')
pendulum.setLength('spam')
Exception: Expected number
class Pendulum(Model):
def __init__(self,length=1.0):
Model.__init__(self,["theta","omega"]) self.length = length
@property def length(self):
return self._length
@length.setter def length(self, value):
try: self._length = int(value)
except: raise Exception("Expected number")
pendulum = Pendulum(2)
pendulum.
pendulum.labels
pendulum.length
pendulum.pendulum.labels
pendulum.length
pendulum.length = "5" print pendulum.length
pendulum.
pendulum.labels
pendulum.length
pendulum.length = "5" print pendulum.length
pendulum.length = "spam"
Exception: Expected number
Code reuse
Code Listing 1:
class Model(object): """ Represents a model """
class Pendulum(Model):
from models import Pendulum
pendulum = Pendulum(3)
Code reuse
Code Listing 3:
class Model(object): """ Represents a model """
class Pendulum(Model):
if __name__ == "__main__":
p = Pendulum() p.describe()
Code reuse
$ python
pendulum with length 1
Pickling
import pickle
teachers = ["moritz","joel","greg","joris"] namelengths = [len(p) for p in teachers]
results = (teachers,namelengths) (results,file('','w'))
Pickling
import pickle
teachers = ["moritz","joel","greg","joris"] namelengths = [len(p) for p in teachers]
results = (teachers,namelengths) (results,file('','w'))
import pickle
teachers,namelengths =
(file('','r'))
print teachers, namelengths
[’moritz’, ’joel’, ’greg’, ’joris’] [6, 4, 4, 5]
Code Listing 4:
import numpy as np import sys
N = int([1]) items = [2:]
for i in range(N): n = len(items) print items[np.random.randint(n)]
Code Listing 5:
import numpy as np import sys
N = int([1]) items = [2:]
for i in range(N): n = len(items) print items[np.random.randint(n)]
$ python 3 spam eggs
eggs spam spam
$ python spam eggs 3
ValueError Traceback
C:\Users\jg\ in ()
2 import sys
----> 4 N = int([1])
5 items = [2:]
ValueError: invalid literal for int() with base 10: ’spa
Code Listing 6:
try:
N = int([1]) except:
raise Exception("""Oops. Expecting a number but you supplied me with '%s'.
""" % [1])
Exception: Oops. Expecting a number but you supplied me with ’spam’.
Code Listing 7:
from argparse import * import numpy as np
p = ArgumentParser( description="Simulate drawing from a collection"
p.add_argument('--N', type=int, default=10, help="The number of draws")
p.add_argument('items', type=str, nargs='+', metavar='item', help='the items to draw from')
p.add_argument('--special', action='store_true')
args = p.parse_args()
for i in range(args.N): n = len(args.items) print args.items[np.random.randint(n)]
)
$ python
usage: [-h] [--N N] [--special] item [item ] : error: too few arguments
$ python -h
usage: [-h] [--N N] [--special] item [item ] Simulate drawing from a collection
positional arguments:
item the items to draw from
optional arguments:
-h, --help show this help message and exit
--N N The number of draws
--special
$ python --N 3 spamm eggs
spamm eggs eggs
Interacting with the shell
import subprocess
items = ["spam", "eggs"]
N = 3
p = subprocess.Popen(
["python","","--N", "%d" % N] + items, , )
stdout, stderr = p.communicate() print stdout
eggs spam eggs
Interacting with the shell
Conclusion
This should be enough background to explore the Python universe
Happy coding!