Structure of the Code file
Code files end with ".py
":
myprogram.py
Every line is a Python statement (or part thereof).
* comment line start with `#`
Run Python Program from command line
Execute with python interpreter
$ python myprogram.py
Direct use on UNIX systems
define the path to the interpreter on the first line of the program as comment
#!/usr/bin/env python
- If setting the executable flag of the file, we can run the program directly in the shell:
$ myprogram.py
a-z
, A-Z
, 0-9
_
. __
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
The assignment operator in Python is =
.
The type is determined dynamically on assignment. No explicit definition
In [ ]:
# variable assignments
myInt = 1
myFloat = 12.2
myString = "Hallo"
myBoolean = True
The type is derived form the value it was assigned (duck-typing)
In [ ]:
type(myFloat)
If we assign a new value to a variable, its type can change.
In [ ]:
myFloat = 1
type(myFloat)
If we try to use a variable that has not yet been defined we get an NameError
:
In [ ]:
print(myChar)
In [ ]:
# integers
x = 1
type(x)
In [ ]:
# float
x = 1.0
type(x)
In [ ]:
# boolean
b1 = True
b2 = False
type(b1)
We can also use the isinstance
method for testing types of variables:
In [ ]:
isinstance(x, float)
Python provides a large set of fast, easy to use data structures. In particular
Built-in data structures are implemented in C.
Strings are the variable type that is used for storing text messages as array of characters/bytes.
In [ ]:
characters = "Complex Systems Engineering"
type(characters)
In [ ]:
char = "C"
type(char)
In [ ]:
# length of the string: the number of characters
len(char)
In [ ]:
s = "Hello world"
In [ ]:
# replace a substring in a string with somethign else
s2 = s.replace( "world", "test")
print(s2)
We can index a character in a string using []
:
Note: Indexing start at 0!
In [ ]:
s[0]
In [ ]:
s[0:5]
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:
In [ ]:
s[:5]
In [ ]:
s[6:]
In [ ]:
s[:]
In [ ]:
x = "80"
y = "20"
print(x, type(x), y, type(y))
In [ ]:
u = x + y
print(u, type(u))
In [ ]:
u = int(x) + int(y)
print(u, type(u))
In [ ]:
x = "80.0"
x = int(x)
Most operators and comparisons in Python work as one would expect. We will briefly outline the following operators
+
, -
, *
, /
, //
(integer division), '**' power
In [ ]:
1 + 2, 1 - 2, 1 * 2, 1 / 2
In [ ]:
1.0 + 2.0, 1.0 - 2.0, 1.0 * 2.0, 1.0 / 2.0
In [ ]:
# Integer division of float numbers
3.0 // 2.0
In [ ]:
# Note! The power operators in python isn't ^, but **
2 ** 2
and
, not
, or
.
In [ ]:
True and False
In [ ]:
not False
In [ ]:
True or False
>
, <
, >=
(greater or equal), <=
(less or equal), ==
equality, is
identical.
In [ ]:
2 > 1, 2 < 1
In [ ]:
2 > 2, 2 < 2
In [ ]:
2 >= 2, 2 <= 2
In [ ]:
# equality
[1,2] == [1,2]
In [ ]:
# objects identical?
l1 = l2 = [1,2]
l1 is l2
In [ ]:
[1,2] is [1,2]
In [ ]:
print("str1", "str2", "str3") # The print statement concatenates strings with a space
In [ ]:
print("str1", 1.0, False, -1j) # The print statements converts all arguments to strings
In [ ]:
print("str1" + "str2" + "str3") # strings added with + are concatenated without space
In [ ]:
a = 5
print ("Hallo" + a)
Lists are very similar to strings, except that each element can be of any type.
The syntax for creating lists in Python is [...]
:
In [ ]:
l = [1,2,3,4]
print(type(l))
print(l)
See help(list)
for more details, or read the online documentation
In [ ]:
print(l)
print(l[1:3])
print(l[::2])
Noe: Indexing starts at 0!
In [ ]:
l[0]
In [ ]:
l = [1, 'a', 1.0, 1-1j]
print(l)
Python lists can be inhomogeneous and arbitrarily nested:
In [ ]:
nested_list = [1, [2, [3, [4, [5]]]]]
nested_list
In [ ]:
start = 10
stop = 30
step = 2
range(start, stop, step)
In [ ]:
# in python 3 range generates an iterator, which can be converted to a list using 'list(...)'. It has no effect in python 2
list(range(start, stop, step))
In [ ]:
list(range(-10, 10))
In [ ]:
s = "some string"
In [ ]:
# convert a string to a list by type casting:
s2 = list(s)
s2
In [ ]:
# sorting lists
s2.sort()
print(s2)
In [ ]:
# create a new empty list
l = []
# add an elements using `append`
l.append("A")
l.append("d")
l.append("d")
print(l)
We can modify lists by assigning new values to elements in the list. In technical jargon, lists are mutable.
In [ ]:
l[1] = "p"
l[2] = "p"
print(l)
In [ ]:
l[1:] = ["d", "d"]
print(l)
In [ ]:
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)
In [ ]:
l.remove("d")
print(l)
Remove an element at a specific location using del
:
In [ ]:
del l[7]
del l[6]
print(l)
In [ ]:
#Write your solution here
Execute the next cell to see a sample solution
In [ ]:
print("""print(len([9,5,1,2])""")
Check if 3 belong to this list [6,9,5,3]
In [ ]:
#Write your solution here
Execute the next cell to see a sample solution
In [ ]:
print(""" 3 in [6,9,5,3]
The result of this instruct is boolean """)
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 ..., ...
:
In [ ]:
point = (10, 20)
print(point, type(point))
In [ ]:
point = 10, "Olaf"
print(point, type(point))
In [ ]:
a = (1,)
print(a)
a + (2,3)
In [ ]:
x, y = point
print("x =", x)
print("y =", y)
In [ ]:
point[0] = 20
Dictionaries are also like lists, except that each element is a key-value pair. The syntax for dictionaries is {key1 : value1, ...}
:
In [ ]:
params = {"key1" : 1.0,
"key2" : 2.0,
"key3" : 3.0,}
print(type(params))
print(params.keys())
print(params.values())
print(params)
In [ ]:
print("key1 = " + str(params["key1"]))
print("key3 = " + str(params["key3"]))
In [ ]:
params["key1"] = "A"
params["key2"] = "B"
# add a new entry
params["key4"] = "D"
print("key1 = " + str(params["key1"]))
print("key2 = " + str(params["key2"]))
print("key3 = " + str(params["key3"]))
print("key4 = " + str(params["key4"]))
The Python Syntax for conditional execution of code use the keywords if
, elif
(else if), else
:
In [ ]:
statement1 = True
statement2 = False
if statement1:
print("statement1 is True")
elif statement2:
print("statement2 is True")
else:
print("statement1 and statement2 are False")
For the first time, here we encounted a peculiar and unusual aspect of the Python programming language: Program blocks are defined by their indentation level.
Compare to the equivalent JAVA code:
if (statement1)
{
System.out.println("statement1 is True\n");
}
else if (statement2)
{
System.out.println("statement2 is True\n");
}
else
{
System.out.println("statement1 and statement2 are False\n");
}
In C blocks are defined by the enclosing curly brakets {
and }
. And the level of indentation (white space before the code statements) does not matter (completely optional).
But 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.
In [ ]:
statement1 = statement2 = True
if statement1:
if statement2:
print("both statement1 and statement2 are True")
In [ ]:
# Bad indentation!
if statement1:
if statement2:
print("both statement1 and statement2 are True") # this line is not properly indented
In [ ]:
statement1 = True
if statement1:
print("printed if statement1 is True")
print("still inside the if block")
In [ ]:
if statement1:
print("printed if statement1 is True")
print("now outside the if block")
In [ ]:
for x in range(6): # by default range start at 0
print(x)
In [ ]:
for x in range(-3,3):
print(x)
In [ ]:
myList = [1,2,3]
for i in range(len(myList)):
print(myList[i])
In [ ]:
for item in myList:
print(item)
In [ ]:
strList = ["complex", "systems", "engineering"]
for word in strList:
print(word)
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:
In [ ]:
for index, word in enumerate(strList):
print(index, word)
Note: range(4)
does not include 4 !
In [ ]:
for key, value in params.items():
print(key + " = " + str(value))
#for key in params.keys():
# print(key + " = " + str(params[key]))
In [ ]:
l1 = [x**2 for x in range(0,5)]
print(l1)
List comprehensions can be conditional (and hence very powerful especially when working with data structures!)
In [ ]:
allCars = [("mercedes", 10000), ("bmw", 20000), ("toyota", 8000), ("vw", 6000)]
myCars = [car for car in allCars if car[1] <= 8000]
print(myCars)
In [ ]:
# find the prices of all cars, that have a "w" in their brand
In [ ]:
i = 0
while i < 5:
print(i)
i = i + 1
#i += 1
print("done")
Note that the print("done")
statement is not part of the while
loop body because of the difference in indentation.
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.
In [ ]:
def func0():
print("Without Parameter")
def func1(someString):
print(someString)
Because Python has a dynamic type system, func0 does not need to specify the type of the return values nor the parameters.
In [ ]:
func0()
func1("with parameter")
Optionally, but highly recommended, we can define a so called "docstring", which is a description of the functions purpose and behaivor. The docstring should follow directly after the function definition, before the code in the function body.
In [ ]:
def func1(s):
"""
Print a string 's' and tell how many characters it has
"""
print(s + " has " + str(len(s)) + " characters")
In [ ]:
help(func1)
In [ ]:
func1("test")
In [ ]:
func1(5)
Python has a dynamic and strong type system
Functions that returns a value use the return
keyword to return any object or function:
In [ ]:
def square(x):
"""
Return the square of x.
"""
return x ** 2
In [ ]:
square(4)
In [ ]:
def powers(x):
"""
Return a few powers of x.
"""
return x ** 2, x ** 3, x ** 4
In [ ]:
resultOfPowers = powers(3)
print(type(resultOfPowers))
print(resultOfPowers)
print(resultOfPowers[0])
In [ ]:
x2, x3, x4 = powers(3)
print(x3)
In a definition of a function, we can give default values to the arguments the function takes:
In [ ]:
def myfunc(x, p=2, debug=False):
if debug:
print("evaluating myfunc for x = " + str(x) + " using exponent p = " + str(p))
return x**p
If we don't provide a value of the debug
argument when calling the the function myfunc
it defaults to the value provided in the function definition:
In [ ]:
myfunc(5)
In [ ]:
myfunc(5, 3, True)
In [ ]:
myfunc(p=3, debug=True, x=7)
In Python we can also create unnamed functions, using the lambda
keyword:
In [ ]:
f1 = lambda x: x**2
# is equivalent to
def f2(x):
return x**2
In [ ]:
f1(2), f2(2)
In [ ]:
def s_length(string):
#write your code here
Execute the next cell to test your solution
In [ ]:
import sys
import traceback
try:
assert s_length("python") == 6
print("success")
except AssertionError:
print('try again')
solution ="""def s_length(string):
c = 0
for char in string:
c += 1
return c"""
Execute the next cell to see the solution
In [ ]:
print(solution)
In [ ]:
def char_mix(a, b):
#write your code here
Execute the next cell to test your solution
In [ ]:
import sys
import traceback
try:
assert char_mix("abc","jhg") == "jbc ahg"
print("success")
except AssertionError:
print('try again')
sol ="""def char_mix(a, b):
mix_a = b[:1] + a[1:]
mix_b = a[:1] + b[1:]
return mix_a + ' ' + mix_b"""
Execute the next cell to see the solution
In [ ]:
print(sol)
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.
A class can contain attributes (variables) and methods (functions).
A class is defined using the class
keyword plus a number of class method definitions (a function in a class).
Each class method should have an argurment 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.
In [ ]:
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:
In [ ]:
p1 = Point(0, 0) # this will invoke the __init__ method in the Point class
print(p1) # this will invode the __str__ method
To invoke a class method in the class instance p
:
In [ ]:
p2 = Point(1, 1)
p1.translate(0.25, 1.5)
print(p1)
print(p2)
Note that calling class methods can modifiy the state of that particular class instance, but does not effect other class instances or any global variables.
That is one of the nice things about object-oriented design: code such as functions and related variables are grouped in separate and independent entities.
import
statementmodule.function
The Python Standard Library is a large collection of modules that provides cross-platform implementations of common facilities such as access to the operating system, file I/O, string management, network communication, and much more.
In [ ]:
import math
Imports the whole module and makes it available under the moduls namespace. For example, we can do:
In [ ]:
x = math.cos(2 * math.pi)
print(x)
In [ ]:
from math import cos, pi
x = cos(2 * pi)
print(x)
In [ ]:
from math import *
x = cos(2 * pi)
print(x)
In [ ]:
from math import cos as c
from math import pi as p
import math as m
x = c(2 * p)
y = m.cos(2 * m.pi)
print (x,y)
Caveat: Readability may suffer.
In [ ]:
import math
print(dir(math))
In [ ]:
help(math.log)
In [ ]:
log(10)
In [ ]:
log(10, 2)
Use help
function directly on modules:
help(math)
Some very useful modules form the Python standard library are
os
sys
math
shutil
re
subprocess
multiprocessing
threading
. A complete lists of standard modules for Python 2 and Python 3 are available at http://docs.python.org/2/library/ and http://docs.python.org/3/library/, respectively.
In [ ]:
import matplotlib.pyplot as plt
plt.plot([0,1,2,3,4])
plt.ylabel('some numbers')
plt.show()
In [ ]:
a = [0,1,2,3,4]
squared = [x**2 for x in a]
plt.plot(a, squared, 'ro')
plt.ylabel('some numbers')
plt.show()
In [ ]:
import math
def sigmoid(x):
a = []
for item in x:
a.append(1/(1+math.exp(-item)))
return a
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(-10, 10, 0.2)
sig = sigmoid(x)
plt.plot(x,sig)
plt.axhline(0, color='black')
plt.axvline(0, color='black')
plt.grid(True)
plt.show()
NumPy enriches the programming language Python with powerful data structures for efficient computation of multi- dimensional arrays and matrices. The implementation is even aiming at huge matrices and arrays. Besides that the module supplies a large library of high-level mathematical functions to operate on these matrices and arrays.
In [ ]:
import numpy as np
Task1
Try to complete the following tasks:
In [ ]:
# create a one-dimensional python list containing 15 integers from 0 to 14
In [ ]:
# create a new numpy array containing the values of the python list
In [ ]:
# reshape the numpy array into a 2-Dimensional matrix with 3 rows and 5 coloumns
In [ ]:
# print the dimensions of the array
In [ ]:
# divide the entire array by 2
In [ ]:
# add another 2 columns to the matrix with the values 0,1,2
In [ ]:
# create two numpy arrays of length 1000, one initialised with only 1's and one with only 0's
In [ ]:
# add random values to each value inside the 0-array
In [ ]:
import sys
import IPython
In [ ]:
print("This notebook was evaluated with: Python %s and IPython %s." % (sys.version, IPython.__version__))
by Michael Granitzer (michael.granitzer@uni-passau.de)
based on the following sources
License
This work is licensed under a Creative Commons Attribution 3.0 Unported License