Lecturer:José Pedro Silva1 - silva_at_math.uni-wuppertal.de
This notebook is based on the one provided by rjohansson
import antigravity
import this
Python code is usually stored in text files with the file ending ".py
":
myprogram.py
Every line in a Python program file is assumed to be a Python statement.
#
(optionally preceded by an arbitrary number of white-space characters, i.e., tabs or spaces). Comment lines are usually ignored by the Python interpreter.To run our Python program from the command line we use:
$ python myprogram.py
On UNIX systems it is common to define the path to the interpreter on the first line of the program (note that this is a comment line as far as the Python interpreter is concerned):
#!/usr/bin/env python
If we do, and if we additionally set the file script to be executable, we can run the program like this:
$ myprogram.py
script_dir = '../scripts/'
ls $script_dir"hello-world"*.py
../scripts/hello-world-in-portuguese.py ../scripts/hello-world.py
cat $script_dir"hello-world.py"
#!/usr/bin/env python print("Instituto Superior de Economia e Gestao!")
!python $script_dir"hello-world.py"
Instituto Superior de Economia e Gestao!
The standard character encoding is ASCII, but we can use any other encoding, for example UTF-8. To specify that UTF-8 is used we include the special line
# -*- coding: UTF-8 -*-
at the top of the file.
!ls $script_dir
hello-world-in-german.py~ hello-world-in-portuguese.py hello-world.py hello-world.py~
cat $script_dir"hello-world-in-portuguese.py"
#!/usr/bin/env python # -*- coding: UTF-8 -*- print("Instituto Superior de Economia e Gestão!")
!python $script_dir"hello-world-in-portuguese.py"
Instituto Superior de Economia e Gestão!
Other than these two optional lines in the beginning of a Python code file, no additional code is required for initializing a program.
Most of the functionality in Python is provided by modules.
To use a module in a Python program it first has to be imported. A module can be imported using the import
statement. For example, to import the module math
, which contains many standard mathematical functions, we can do:
import math
This includes the whole module and makes it available for use later in the program. For example, we can do:
import math
x = math.cos(2 * math.pi)
print(x)
1.0
Alternatively, we can chose to import all symbols (functions and variables) in a module to the current namespace (so that we don't need to use the prefix "math.
" every time we use something from the math
module:
from math import *
x = cos(2 * pi)
print(x)
1.0
As a third alternative, we can chose to import only a few selected symbols from a module by explicitly listing which ones we want to import instead of using the wildcard character *
:
from math import cos, pi
x = cos(2 * pi)
print(x)
1.0
Although not a very good practice, we can rename the symbols for ease of comprehension
from numpy.linalg import inv
from scipy.sparse.linalg import inv as sparseinv
Once a module is imported, we can list the symbols it provides using the dir
function:
import math
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']
And using the function help
we can get a description of each function (almost .. not all functions have docstrings, as they are technically called, but the vast majority of functions are documented this way).
help(math.log)
Help on built-in function log in module math: log(...) log(x[, base]) Return the logarithm of x to the given base. If the base not specified, returns the natural logarithm (base e) of x.
log(10)
2.302585092994046
We can also specify the base
log(10, 2)
3.3219280948873626
We can also use the help
function directly on modules: Try
help(math)
help(math)
Help on module math: NAME math FILE /home/jpsilva/anaconda/lib/python2.7/lib-dynload/math.so MODULE DOCS http://docs.python.org/library/math DESCRIPTION This module is always available. It provides access to the mathematical functions defined by the C standard. FUNCTIONS acos(...) acos(x) Return the arc cosine (measured in radians) of x. acosh(...) acosh(x) Return the hyperbolic arc cosine (measured in radians) of x. asin(...) asin(x) Return the arc sine (measured in radians) of x. asinh(...) asinh(x) Return the hyperbolic arc sine (measured in radians) of x. atan(...) atan(x) Return the arc tangent (measured in radians) of x. atan2(...) atan2(y, x) Return the arc tangent (measured in radians) of y/x. Unlike atan(y/x), the signs of both x and y are considered. atanh(...) atanh(x) Return the hyperbolic arc tangent (measured in radians) of x. ceil(...) ceil(x) Return the ceiling of x as a float. This is the smallest integral value >= x. copysign(...) copysign(x, y) Return x with the sign of y. cos(...) cos(x) Return the cosine of x (measured in radians). cosh(...) cosh(x) Return the hyperbolic cosine of x. degrees(...) degrees(x) Convert angle x from radians to degrees. erf(...) erf(x) Error function at x. erfc(...) erfc(x) Complementary error function at x. exp(...) exp(x) Return e raised to the power of x. expm1(...) expm1(x) Return exp(x)-1. This function avoids the loss of precision involved in the direct evaluation of exp(x)-1 for small x. fabs(...) fabs(x) Return the absolute value of the float x. factorial(...) factorial(x) -> Integral Find x!. Raise a ValueError if x is negative or non-integral. floor(...) floor(x) Return the floor of x as a float. This is the largest integral value <= x. fmod(...) fmod(x, y) Return fmod(x, y), according to platform C. x % y may differ. frexp(...) frexp(x) Return the mantissa and exponent of x, as pair (m, e). m is a float and e is an int, such that x = m * 2.**e. If x is 0, m and e are both 0. Else 0.5 <= abs(m) < 1.0. fsum(...) fsum(iterable) Return an accurate floating point sum of values in the iterable. Assumes IEEE-754 floating point arithmetic. gamma(...) gamma(x) Gamma function at x. hypot(...) hypot(x, y) Return the Euclidean distance, sqrt(x*x + y*y). isinf(...) isinf(x) -> bool Check if float x is infinite (positive or negative). isnan(...) isnan(x) -> bool Check if float x is not a number (NaN). ldexp(...) ldexp(x, i) Return x * (2**i). lgamma(...) lgamma(x) Natural logarithm of absolute value of Gamma function at x. log(...) log(x[, base]) Return the logarithm of x to the given base. If the base not specified, returns the natural logarithm (base e) of x. log10(...) log10(x) Return the base 10 logarithm of x. log1p(...) log1p(x) Return the natural logarithm of 1+x (base e). The result is computed in a way which is accurate for x near zero. modf(...) modf(x) Return the fractional and integer parts of x. Both results carry the sign of x and are floats. pow(...) pow(x, y) Return x**y (x to the power of y). radians(...) radians(x) Convert angle x from degrees to radians. sin(...) sin(x) Return the sine of x (measured in radians). sinh(...) sinh(x) Return the hyperbolic sine of x. sqrt(...) sqrt(x) Return the square root of x. tan(...) tan(x) Return the tangent of x (measured in radians). tanh(...) tanh(x) Return the hyperbolic tangent of x. trunc(...) trunc(x:Real) -> Integral Truncates x to the nearest Integral toward 0. Uses the __trunc__ magic method. DATA e = 2.718281828459045 pi = 3.141592653589793
Variable names in Python can contain alphanumerical characters a-z
, A-Z
, 0-9
and some special characters such as _
. Normal variable names must start with a letter.
By convension, variable names start with a lower-case letter, and Class names start with a capital letter.
In addition, there are a number of Python keywords that cannot be used as variable names. These keywords are:
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
Note: Be aware of the keyword lambda
, which could easily be a natural variable name in a scientific program. But being a keyword, it cannot be used as a variable name.
The assignment operator in Python is =
. Python is a dynamically typed language, so we do not need to specify the type of a variable when we create one.
Assigning a value to a new variable creates the variable:
import sys
import keyword
print sys.version
print ''
print(keyword.kwlist)
2.7.8 |Anaconda 2.1.0 (64-bit)| (default, Aug 21 2014, 18:22:21) [GCC 4.4.7 20120313 (Red Hat 4.4.7-1)] ['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']
# variable assignments
x = 1.0
my_variable = 12.2
Although not explicitly specified, a variable do have a type associated with it. The type is derived from the value it was assigned.
type(x)
float
If we assign a new value to a variable, its type can change.
x = 1
type(x)
int
If we try to use a variable that has not yet been defined we get an NameError
:
print(y)
--------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-41-36b2093251cd> in <module>() ----> 1 print(y) NameError: name 'y' is not defined
# integers
x = 1
type(x)
int
# float
x = 1.0
type(x)
float
# boolean
b1 = True
b2 = False
type(b1)
bool
# complex numbers: note the use of `j` to specify the imaginary part
x = 1.0 - 1.0j
type(x)
complex
print(x)
(1-1j)
print(x.real, x.imag)
(1.0, -1.0)
import types
# print all types defined in the `types` module
print(dir(types))
['BooleanType', 'BufferType', 'BuiltinFunctionType', 'BuiltinMethodType', 'ClassType', 'CodeType', 'ComplexType', 'DictProxyType', 'DictType', 'DictionaryType', 'EllipsisType', 'FileType', 'FloatType', 'FrameType', 'FunctionType', 'GeneratorType', 'GetSetDescriptorType', 'InstanceType', 'IntType', 'LambdaType', 'ListType', 'LongType', 'MemberDescriptorType', 'MethodType', 'ModuleType', 'NoneType', 'NotImplementedType', 'ObjectType', 'SliceType', 'StringType', 'StringTypes', 'TracebackType', 'TupleType', 'TypeType', 'UnboundMethodType', 'UnicodeType', 'XRangeType', '__builtins__', '__doc__', '__file__', '__name__', '__package__']
x = 1.0
# check if the variable x is a float
type(x) is float
True
# check if the variable x is an int
type(x) is int
False
We can also use the isinstance
method for testing types of variables:
isinstance(x, float)
True
x = 1.5
print(x, type(x))
(1.5, <type 'float'>)
x = int(x)
print(x, type(x))
(1, <type 'int'>)
z = complex(x)
print(z, type(z))
((1+0j), <type 'complex'>)
x = float(z)
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-55-e719cc7b3e96> in <module>() ----> 1 x = float(z) TypeError: can't convert complex to float
Complex variables cannot be cast to floats or integers. We need to use z.real
or z.imag
to extract the part of the complex number we want:
y = bool(z.real)
print(z.real, " -> ", y, type(y))
y = bool(z.imag)
print(z.imag, " -> ", y, type(y))
(1.0, ' -> ', True, <type 'bool'>) (0.0, ' -> ', False, <type 'bool'>)
Most operators and comparisons in Python work as one would expect:
+
, -
, *
, /
, //
(integer division), '**' power1 + 2, 1 - 2, 1 * 2, 1 / 2
(3, -1, 2, 0)
1.0 + 2.0, 1.0 - 2.0, 1.0 * 2.0, 1.0 / 2.0
(3.0, -1.0, 2.0, 0.5)
3.0 // 2.0
1.0
2 ** 2
4
and
, not
, or
.True and False
False
not False
True
True or False
True
>
, <
, >=
(greater or equal), <=
(less or equal), ==
equality, is
identical.2 > 1, 2 < 1
(True, False)
2 > 2, 2 < 2
(False, False)
2 >= 2, 2 <= 2
(True, True)
# equality
[1,2] == [1,2]
True
# objects identical?
l1 = l2 = [1,2]
l1 is l2
True
s = "Hello world"
type(s)
str
# length of the string: the number of characters
len(s)
11
# replace a substring in a string with somethign else
s2 = s.replace("world", "test")
print(s2)
Hello test
We can index a character in a string using []
:
s[0]
'H'
We can extract a part of a string using the syntax [start:stop]
, which extracts characters between index start
and stop
:
s[0:5]
'Hello'
If we omit either (or both) of start
or stop
from [start:stop]
, the default is the beginning and the end of the string, respectively:
s[:5]
'Hello'
s[6:]
'world'
s[:]
'Hello world'
We can also define the step size using the syntax [start:end:step]
(the default value for step
is 1, as we saw above):
s[::1]
'Hello world'
s[::2]
'Hlowrd'
print("str1" + "str2" + "str3") # strings added with + are concatenated without space
str1str2str3
print("value = %f" % 1.0)
value = 1.000000
s2 = "value1 = %.2f value2 = %d" % (3.1415, 1.5)
print(s2)
value1 = 3.14 value2 = 1
s3 = 'value1 = {0}, value2 = {1}'.format(3.1415, 1.5)
print(s3)
value1 = 3.1415, value2 = 1.5
Lists are very similar to strings, except that each element can be of any type.
The syntax for creating lists in Python is [...]
:
l = [1,2,3,4]
print(type(l))
print(l)
<type 'list'> [1, 2, 3, 4]
print(l)
print(l[1:3])
print(l[::2])
[1, 2, 3, 4] [2, 3] [1, 3]
l[0]
1
l = [1, 'a', 1.0, 1-1j]
print(l)
[1, 'a', 1.0, (1-1j)]
start = 10
stop = 30
step = 2
range(start, stop, step)
[10, 12, 14, 16, 18, 20, 22, 24, 26, 28]
list(range(-10, 10))
[-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
s
'Hello world'
# convert a string to a list:
s2 = list(s)
s2
['H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']
# sorting lists
s2.sort()
print(s2)
[' ', 'H', 'd', 'e', 'l', 'l', 'l', 'o', 'o', 'r', 'w']
# create a new empty list
l = []
# add an elements using `append`
l.append("A")
l.append("d")
l.append("d")
print(l)
['A', 'd', 'd']
l[1] = "p"
l[2] = "p"
print(l)
['A', 'p', 'p']
l[1:3] = ["d", "d"]
print(l)
['A', 'd', 'd']
l.insert(0, "i")
l.insert(1, "n")
l.insert(2, "s")
l.insert(3, "e")
l.insert(4, "r")
l.insert(5, "t")
print(l)
['i', 'n', 's', 'e', 'r', 't', 'A', 'd', 'd']
l.remove("A")
print(l)
['i', 'n', 's', 'e', 'r', 't', 'd', 'd']
del l[7]
del l[6]
print(l)
['i', 'n', 's', 'e', 'r', 't']
Tuples are like lists, except that they cannot be modified once created, that is they are immutable.
In Python, tuples are created using the syntax (..., ..., ...)
, or even ..., ...
:
point = (10, 20)
print(point, type(point))
((10, 20), <type 'tuple'>)
point = 10, 20
print(point, type(point))
((10, 20), <type 'tuple'>)
We can unpack a tuple by assigning it to a comma-separated list of variables:
x, y = point
print("x =", x)
print("y =", y)
('x =', 10) ('y =', 20)
If we try to assign a new value to an element in a tuple we get an error:
point[0] = 20
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-103-ac1c641a5dca> in <module>() ----> 1 point[0] = 20 TypeError: 'tuple' object does not support item assignment
Dictionaries are also like lists, except that each element is a key-value pair. The syntax for dictionaries is {key1 : value1, ...}
:
params = {"parameter1" : 1.0,
"parameter2" : 2.0,
"parameter3" : 3.0,}
print(type(params))
print(params)
<type 'dict'> {'parameter1': 1.0, 'parameter3': 3.0, 'parameter2': 2.0}
print("parameter1 = " + str(params["parameter1"]))
print("parameter2 = " + str(params["parameter2"]))
print("parameter3 = " + str(params["parameter3"]))
parameter1 = 1.0 parameter2 = 2.0 parameter3 = 3.0
params["parameter1"] = "A"
params["parameter2"] = "B"
# add a new entry
params["parameter4"] = "D"
print("parameter1 = " + str(params["parameter1"]))
print("parameter2 = " + str(params["parameter2"]))
print("parameter3 = " + str(params["parameter3"]))
print("parameter4 = " + str(params["parameter4"]))
parameter1 = A parameter2 = B parameter3 = 3.0 parameter4 = D
The Python syntax for conditional execution of code use the keywords if
, elif
(else if), else
:
statement1 = False
statement2 = False
if statement1:
print("statement1 is True")
elif statement2:
print("statement2 is True")
else:
print("statement1 and statement2 are False")
statement1 and statement2 are False
In Python, the extent of a code block is defined by the indentation level (usually a tab or say four white spaces). This means that we have to be careful to indent our code correctly, or else we will get syntax errors.
Examples:
statement1 = statement2 = True
if statement1:
if statement2:
print("both statement1 and statement2 are True")
both statement1 and statement2 are True
# Bad indentation!
if statement1:
if statement2:
print("both statement1 and statement2 are True") # this line is not properly indented
both statement1 and statement2 are True
statement1 = False
if statement1:
print("printed if statement1 is True")
print("still inside the if block")
if statement1:
print("printed if statement1 is True")
print("now outside the if block")
now outside the if block
In Python, loops can be programmed in a number of different ways. The most common is the for
loop, which is used together with iterable objects, such as lists. The basic syntax is:
for
loops:
for x in [1,2,3]:
print(x)
1 2 3
The for
loop iterates over the elements of the supplied list, and executes the containing block once for each element. Any kind of list can be used in the for
loop. For example:
for x in range(4): # by default range start at 0
print(x)
0 1 2 3
Note: range(4)
does not include 4 !
for x in range(-3,3):
print(x)
-3 -2 -1 0 1 2
for word in ["scientific", "computing", "with", "python"]:
print(word)
scientific computing with python
To iterate over key-value pairs of a dictionary:
for key, value in params.items():
print(key + " = " + str(value))
parameter4 = D parameter1 = A parameter3 = 3.0 parameter2 = B
Sometimes it is useful to have access to the indices of the values when iterating over a list. We can use the enumerate
function for this:
for idx, x in enumerate(range(-3,3)):
print(idx, x)
(0, -3) (1, -2) (2, -1) (3, 0) (4, 1) (5, 2)
List comprehensions: Creating lists using for
loops:
l1 = [x**2 for x in range(0,5)]
print(l1)
[0, 1, 4, 9, 16]
while
loops:
i = 0
while i < 5:
print(i)
i = i + 1
print("done")
0 1 2 3 4 done
A function in Python is defined using the keyword def
, followed by a function name, a signature within parenthises ()
, and a colon :
. The following code, with one additional level of indentation, is the function body.
def func0():
print("test")
func0()
test
Optionally, but highly recommended, we can define a so called "docstring", which is a description of the functions purpose and behavior. The docstring should be located after the function definition and before the code in the function body.
def func1(s):
"""
Print a string 's' and tell how many characters it has
"""
print(s + " has " + str(len(s)) + " characters")
help(func1)
Help on function func1 in module __main__: func1(s) Print a string 's' and tell how many characters it has
func1("test")
test has 4 characters
Functions that returns a value use the return
keyword:
def square(x):
"""
Return the square of x.
"""
return x ** 2
square(4)
16
We can return multiple values from a function using tuples (see above):
def powers(x):
"""
Return a few powers of x.
"""
return x ** 2, x ** 3, x ** 4
powers(3)
(9, 27, 81)
x2, x3, x4 = powers(3)
print(x3)
27
def myfunc(x, p=2, debug=False):
if debug:
print("evaluating myfunc for x = " + str(x) + " using exponent p = " + str(p))
return x**p
myfunc(5)
25
myfunc(5, debug=True)
evaluating myfunc for x = 5 using exponent p = 2
25
myfunc(p=3, debug=True, x=7)
evaluating myfunc for x = 7 using exponent p = 3
343
In Python we can also create unnamed functions, using the lambda
keyword:
f1 = lambda x: x**2
# is equivalent to
def f2(x):
return x**2
f1(2), f2(2)
(4, 4)
This technique is useful for exmample when we want to pass a simple function as an argument to another function, like this:
# map is a built-in python function
map(lambda x: x**2, range(-3,4))
[9, 4, 1, 0, 1, 4, 9]
Classes are the key features of object-oriented programming. A class is a structure for representing an object and the operations that can be performed on the object.
In Python a class can contain attributes (variables) and methods (functions).
In python a class is defined almost like a function, but using the class
keyword, and the class definition usually contains a number of class method definitions (a function in a class).
Each class method should have an argument self
as it first argument. This object is a self-reference.
Some class method names have special meaning, for example:
__init__
: The name of the method that is invoked when the object is first created.
__str__
: A method that is invoked when a simple string representation of the class is needed, as for example when printed.
class Point:
"""
Simple class for representing a point in a Cartesian coordinate system.
"""
def __init__(self, x, y):
"""
Create a new Point at x, y.
"""
self.x = x
self.y = y
def translate(self, dx, dy):
"""
Translate the point by dx and dy in the x and y direction.
"""
self.x += dx
self.y += dy
def __str__(self):
return("Point at [%f, %f]" % (self.x, self.y))
To create a new instance of a class:
p1 = Point(0, 0) # this will invoke the __init__ method in the Point class
print(p1) # this will invoke the __str__ method
Point at [0.000000, 0.000000]
p2 = Point(1, 1)
p1.translate(0.25, 1.5)
print(p1)
print(p2)
Point at [0.250000, 1.500000] Point at [1.000000, 1.000000]
One of the most important concepts in good programming is to reuse code and avoid repetitions.
Consider the following example: the file mymodule.py
contains simple example implementations of a variable, function and a class:
%%file mymodule.py
"""
Example of a python module. Contains a variable called my_variable,
a function called my_function, and a class called MyClass.
"""
my_variable = 0
def my_function():
"""
Example function
"""
return my_variable
class MyClass:
"""
Example class.
"""
def __init__(self):
self.variable = my_variable
def set_variable(self, new_value):
"""
Set self.variable to a new value
"""
self.variable = new_value
def get_variable(self):
return self.variable
Writing mymodule.py
We can import the module mymodule
into our Python program using import
:
import mymodule
Use help(module)
to get a summary of what the module provides:
help(mymodule)
Help on module mymodule: NAME mymodule FILE /home/jpsilva/Lisbon1214/notebooks/mymodule.py DESCRIPTION Example of a python module. Contains a variable called my_variable, a function called my_function, and a class called MyClass. CLASSES MyClass class MyClass | Example class. | | Methods defined here: | | __init__(self) | | get_variable(self) | | set_variable(self, new_value) | Set self.variable to a new value FUNCTIONS my_function() Example function DATA my_variable = 0
mymodule.my_variable
0
mymodule.my_function()
0
my_class = mymodule.MyClass()
my_class.set_variable(10)
my_class.get_variable()
10
If we make changes to the code in mymodule.py
, we need to reload it using reload
:
reload(mymodule)
<module 'mymodule' from 'mymodule.pyc'>
%reload_ext version_information
%version_information math
Software | Version |
---|---|
Python | 2.7.8 |Anaconda 2.1.0 (64-bit)| (default, Aug 21 2014, 18:22:21) [GCC 4.4.7 20120313 (Red Hat 4.4.7-1)] |
IPython | 2.3.0 |
OS | posix [linux2] |
math | 'module' object has no attribute '__version__' |
Fri Dec 05 09:59:20 2014 CET |
%who
HTML Point acos acosh asin asinh atan atan2 atanh b1 b2 ceil copysign cos cosh css_styling degrees e erf erfc exp expm1 f1 f2 fabs factorial floor fmod frexp fsum func0 func1 gamma hypot i idx inv isinf isnan key keyword l l1 l2 ldexp lgamma log log10 log1p math modf my_class my_variable myfunc mymodule p1 p2 params pi point pow powers radians s s2 s3 script_dir sin sinh sparseinv sqrt square start statement1 statement2 step stop sys tan tanh trunc types value word x x2 x3 x4 y z
We can find more information about IPython capabilities in IPython example notebooks
from IPython.core.display import HTML
def css_styling():
styles = open("./styles/custom.css", "r").read()
return HTML(styles)
css_styling()