Syntax etc.

Comments vs. Documentation

[1]:
# das ist ein voellig sinnloser kommentar, weil der
# code sollte ja wohl selbsterklaerend sein
i = 0
while i < 10:
    print('das ist eine zahl zwischen 0 und 9 (inklusive):', i)
    i = i + 1
das ist eine zahl zwischen 0 und 9 (inklusive): 0
das ist eine zahl zwischen 0 und 9 (inklusive): 1
das ist eine zahl zwischen 0 und 9 (inklusive): 2
das ist eine zahl zwischen 0 und 9 (inklusive): 3
das ist eine zahl zwischen 0 und 9 (inklusive): 4
das ist eine zahl zwischen 0 und 9 (inklusive): 5
das ist eine zahl zwischen 0 und 9 (inklusive): 6
das ist eine zahl zwischen 0 und 9 (inklusive): 7
das ist eine zahl zwischen 0 und 9 (inklusive): 8
das ist eine zahl zwischen 0 und 9 (inklusive): 9

Comment, zum Unterschied von Docstrings

[2]:
def f(a):
    'das ist eine funktion mit einem parameter a. der sollte int typ haben. diese funktion printet den parameter auf stdout'
    print(a)
f(666)
666
[3]:
f.__doc__
[3]:
'das ist eine funktion mit einem parameter a. der sollte int typ haben. diese funktion printet den parameter auf stdout'
[4]:
help(f)
Help on function f in module __main__:

f(a)
    das ist eine funktion mit einem parameter a. der sollte int typ haben. diese funktion printet den parameter auf stdout

[5]:
class X:
    'das ist eine depperte klasse'
    def __init__(self, param):
        self.param = param

help(X)
Help on class X in module __main__:

class X(builtins.object)
 |  X(param)
 |
 |  das ist eine depperte klasse
 |
 |  Methods defined here:
 |
 |  __init__(self, param)
 |      Initialize self.  See help(type(self)) for accurate signature.
 |
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |
 |  __dict__
 |      dictionary for instance variables (if defined)
 |
 |  __weakref__
 |      list of weak references to the object (if defined)

Variables

[6]:
a = 42
[7]:
type(a)
[7]:
int
[8]:
a = 3.14
[9]:
type(a)
[9]:
float
[10]:
a = [42, 'blah']
print(type(a))
<class 'list'>
[11]:
_abc = 2
_1 = 5
_ = 5
a123 = 5

Assignment Fun

[12]:
a = 42
b = 666
[13]:
print(a, b)
42 666
[14]:
a, b = 42, 666
[15]:
print(a, b)
42 666

Vertauschen von zwei Variablen

[16]:
tmp = a
a = b
b = tmp
print(a, b)
666 42
[17]:
a, b = 42, 666

Pythonic Swap:

[18]:
a, b = b, a
print(a, b)
666 42

Assignment Details

Variable vernichten zur Laufzeit

[19]:
del a
del b
[20]:
a = 42
id(a)
[20]:
140032702361168
[21]:
b = a
id(b)
[21]:
140032702361168
[22]:
del b
[23]:
del a

Refcount von 42 ist auf 0 -> automatic Memory management by refcounting

Datatypes

Numbers

Dezimal …

[24]:
1234
[24]:
1234
[25]:
1*10**3 + 2*10**2 + 3*10**1 + 4*10**0
[25]:
1234

Oktal …

[26]:
0o755
[26]:
493
[27]:
7*(8**2) + 5*(8**1) + 5*(8**0)
[27]:
493

Binär …

[28]:
0b11
[28]:
3
[29]:
1*2**1 + 1*2**0
[29]:
3

Small int und Big int? (Aus SQL-Datenbanken)

[30]:
i = 0
[31]:
0b11111111
[31]:
255
[32]:
2**64-1
[32]:
18446744073709551615
[33]:
2**64
[33]:
18446744073709551616
[34]:
2**1000
[34]:
10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069376

Operators

[2]:
if 1 < 2:
    print('die welt ist noch in ordnung')
die welt ist noch in ordnung
[3]:
uhrzeit = 10
# ist das zwischen 8 und 12?
if 8 <= uhrzeit <= 12:
    print('es ist vormittag')
es ist vormittag

Integer Arithmetic

[35]:
2/3
[35]:
0.6666666666666666

Floor Division: Division ohne Rest

[36]:
2//3
[36]:
0

Modulo: Rest der Division

[37]:
6%4
[37]:
2
[38]:
15%4
[38]:
3

Strings

[39]:
'hallo'
[39]:
'hallo'
[40]:
"hallo"
[40]:
'hallo'
[41]:
'abc\'def'
[41]:
"abc'def"
[42]:
"abc'def"
[42]:
"abc'def"
[43]:
print('\'hello\'')
'hello'
[44]:
print("'hello'")
'hello'
[45]:
"""Das ist die erste Zeile
Das ist die zweite Zeile"""
[45]:
'Das ist die erste Zeile\nDas ist die zweite Zeile'

Raw Strings …

[46]:
python_dir = "C:\\Users\\Jan\\..."
print(python_dir)
C:\Users\Jan\...
[47]:
python_dir = r"C:\Users\Jan\..."
print(python_dir)
C:\Users\Jan\...

String Methods

[9]:
s = 'HALLO'
s.lower()
[9]:
'hallo'
[10]:
s
[10]:
'HALLO'

Wie lowercased man einen String in-place?

[11]:
s = s.lower()
s
[11]:
'hallo'

Datatype Conversions

[48]:
s = '42'
i = int(s)
i
[48]:
42
[49]:
s = '10'
i = int(s, 16)
i
[49]:
16
[50]:
i = 42
s = str(i)
s
[50]:
'42'
[51]:
float('42.666')
[51]:
42.666
[52]:
int(42.666)
[52]:
42

Strings können alles!

[53]:
s = 'hallo'
s.upper()
[53]:
'HALLO'
[54]:
s.lower()
[54]:
'hallo'
[55]:
s.capitalize()
[55]:
'Hallo'
[56]:
s.find('ll')
[56]:
2
[57]:
'mississippi'.count('ss')
[57]:
2
[58]:
'abc;def;666'.split(';')
[58]:
['abc', 'def', '666']

Complex Datatypes

List (mutable)

[59]:
l = []   # leere Liste
len(l)
[59]:
0
[60]:
l = list()  # leere liste
len(l)
[60]:
0
[61]:
l = list('abc')
l
[61]:
['a', 'b', 'c']
[62]:
for c in 'abc':
    print(c)
a
b
c
[63]:
l = list()
[64]:
l = [42, 'blah']
len(l)
[64]:
2
[65]:
id(l)
[65]:
140032636418048
[66]:
l[0]
[66]:
42
[67]:
l[1]
[67]:
'blah'
[68]:
try:
    l[2]
except Exception as e:
    print(e)
list index out of range
[69]:
l.append(666)
l
[69]:
[42, 'blah', 666]
[70]:
id(l)
[70]:
140032636418048

extend()? Iterable?

Was ist ein Iterable? Etwas, über das man iterieren kann:

[71]:
ein_iterierbares_ding = [1, 'zwei', 3.0]
for element in ein_iterierbares_ding:
    print(element)
1
zwei
3.0

extend() nimmt Iterable als Parameter:

[72]:
l.extend(ein_iterierbares_ding)
l
[72]:
[42, 'blah', 666, 1, 'zwei', 3.0]
[73]:
try:
    l.extend(1)
except Exception as e:
    print(e)
'int' object is not iterable
[74]:
t = (1, 'zwei', 3.0)
for element in t:
    print(element)
1
zwei
3.0
[75]:
s = 'abcd'
for element in s:
    print(element)
a
b
c
d
[76]:
l.extend(s)
l
[76]:
[42, 'blah', 666, 1, 'zwei', 3.0, 'a', 'b', 'c', 'd']
[77]:
id(l)
[77]:
140032636418048
[78]:
l1 = [1,2,3]
l2 = [4,5,6]
[79]:
l = l1 + l2
l
[79]:
[1, 2, 3, 4, 5, 6]
[80]:
l1
[80]:
[1, 2, 3]
[81]:
l2
[81]:
[4, 5, 6]
[82]:
[1,2,3] * 2
[82]:
[1, 2, 3, 1, 2, 3]
[83]:
l = [1, 2, 3, 4]
[84]:
l[2]
[84]:
3
[85]:
del l[2]
[86]:
l[2]
[86]:
4

Tuple (wie Liste, nur immutable)

[87]:
t = ()  # leeres tuple
len(t)
[87]:
0
[88]:
t = (42, 'blah')
len(t)
[88]:
2

Immutable:

[89]:
try:
    t.append(666)
except Exception as e:
    print(e)
'tuple' object has no attribute 'append'

Syntaktisches Extrawürschtl: Tuple mit nur einem Element

[90]:
(666)
[90]:
666
[91]:
(1+2)*3
[91]:
9
[92]:
(666,)
[92]:
(666,)
[93]:
(666)
[93]:
666
[94]:
print((666))
666
[95]:
(42, 666)
[95]:
(42, 666)

print() mit einem Parameter

[96]:
print((42, 666))
(42, 666)

print() mit zwei Parametern

[97]:
print(42, 666)
42 666

in Operator

[4]:
sex = 'd'
if sex != 'm' and sex != 'f':
    print('divers not implemented')
divers not implemented
[5]:
if sex not in ('m', 'f'):
    print('divers not implemented')
divers not implemented

Dictionary

Leeres Dictionary …

[52]:
d = {}
type(d)
[52]:
dict
[53]:
len(d)
[53]:
0
[54]:
d = dict()
type(d)
[54]:
dict

Nicht-leeres Dictionary …

[98]:
translation_table = {
    'one': 1,
    'zero': 0,
    'two': 2,
}
[99]:
translation_table['one']
[99]:
1
[100]:
translation_table['bullshit'] = [666, 42, 'hallo']
[101]:
translation_table['bullshit']
[101]:
[666, 42, 'hallo']
[102]:
translation_table = {
    'one': [1, 2, 3],
    'zero': 0,
    'two': 2,
}
[103]:
translation_table['one']
[103]:
[1, 2, 3]
[104]:
for k in translation_table.keys():
    print(k)
one
zero
two
[105]:
translation_table['bullshit'] = (1, 2, 3)
[106]:
for k in translation_table.keys():
    print(k)
one
zero
two
bullshit
[107]:
if 'bullshit' in translation_table:
    print('jo, is eh drin')
jo, is eh drin
[108]:
'xyz' in translation_table
[108]:
False
[109]:
del translation_table['bullshit']
[110]:
'bullshit' in translation_table
[110]:
False

Sets

Leeres Set …

[56]:
s = {}   # ATTENTION!!
type(s)
[56]:
dict
[58]:
s = set()
type(s)
[58]:
set
[59]:
len(s)
[59]:
0

Nicht-leeres set …

[111]:
bag = {'red', 'green', 'blue'}
len(bag)
[111]:
3
[112]:
bag
[112]:
{'blue', 'green', 'red'}
[113]:
'red' in bag
[113]:
True
[114]:
bag.add('black')
[115]:
bag
[115]:
{'black', 'blue', 'green', 'red'}
[116]:
bag.add(666)
[117]:
bag
[117]:
{666, 'black', 'blue', 'green', 'red'}

Mengenoperationen …

[121]:
set1 = {1, 2, 3, 4}
set2 = {3, 4, 2, 5}
[122]:
union = set1 | set2
union
[122]:
{1, 2, 3, 4, 5}
[123]:
diff = set1 - set2
diff
[123]:
{1}
[124]:
intersection = set1 & set2
intersection
[124]:
{2, 3, 4}
[125]:
symm_diff = set1 ^ set2
symm_diff
[125]:
{1, 5}
[126]:
s = {}    # leeres set? nein!
type(s)
[126]:
dict
[127]:
s = set()
type(s)
[127]:
set
[128]:
d = dict()
type(d)
[128]:
dict

Iteration über Daten: mittels for

While gibts auch

[13]:
i = 0
while i < 10:
    print(i)
    i += 1
0
1
2
3
4
5
6
7
8
9
[14]:
for i in range(0, 10):
    print(i)
0
1
2
3
4
5
6
7
8
9
[16]:
for i in range(10):
    print(i)
0
1
2
3
4
5
6
7
8
9
[18]:
for i in range(0, 10, 2):
    print(i)
0
2
4
6
8

List iteration

[20]:
l = ['Lisa', 'Eugenie', 'Jan', 'Okan', 'Joerg']
for element in l:
    print(element)
Lisa
Eugenie
Jan
Okan
Joerg

Set iteration

[24]:
s = {'Lisa', 'Eugenie', 'Jan', 'Okan', 'Joerg'}
for element in s:
    print(element)
Okan
Joerg
Lisa
Eugenie
Jan
[26]:
d = {'Lisa': 'McGuire',
    'Eugenie': 'Sinner'
    }
d['Lisa']
[26]:
'McGuire'

Dictionary iteration

[29]:
for element in d:    # implicitly meaning: iteration over keys
    print(element)
Lisa
Eugenie
[32]:
for k in d.keys():
    print(k)
Lisa
Eugenie
[33]:
for v in d.values():
    print(v)
McGuire
Sinner
[34]:
for element in d.items():
    print(element)
('Lisa', 'McGuire')
('Eugenie', 'Sinner')
[37]:
for element in d.items():
    vorname = element[0]
    nachname = element[1]
    print('Vorname:', vorname)
    print('Nachname:', nachname)
Vorname: Lisa
Nachname: McGuire
Vorname: Eugenie
Nachname: Sinner

Tuple unpacking

[38]:
for vorname, nachname in d.items():
    print('Vorname:', vorname)
    print('Nachname:', nachname)
Vorname: Lisa
Nachname: McGuire
Vorname: Eugenie
Nachname: Sinner
[39]:
l = [(1, 'Eugenie', 'Sinner', 'eugenie@sinner.com'),
     (2, 'Lisa', 'McGuire', 'lisa@mcguire.com')
    ]
for persnr, vorname, nachname, email in l:
    print('PersonalNummer:', persnr)
    print('Email:', email)
PersonalNummer: 1
Email: eugenie@sinner.com
PersonalNummer: 2
Email: lisa@mcguire.com

enumerate(), sum(), map(), und so weiter

enumerate()

[2]:
l = ['Lisa', 'Eugenie', 'Jan', 'Okan', 'Joerg']
l[0]
[2]:
'Lisa'
[3]:
l[4]
[3]:
'Joerg'

Problem:

[4]:
for person in l:
    print(person)
Lisa
Eugenie
Jan
Okan
Joerg
[5]:
position = 0
for person in l:
    print(person, 'ist an position', position)
    position += 1
Lisa ist an position 0
Eugenie ist an position 1
Jan ist an position 2
Okan ist an position 3
Joerg ist an position 4

Lösung: verwende doch enumerate()

[6]:
for element in enumerate(l):
    print(element)
(0, 'Lisa')
(1, 'Eugenie')
(2, 'Jan')
(3, 'Okan')
(4, 'Joerg')
[7]:
for position, person in enumerate(l):
    print(person, 'ist an position', position)
Lisa ist an position 0
Eugenie ist an position 1
Jan ist an position 2
Okan ist an position 3
Joerg ist an position 4

sum()

[10]:
l = [5000, 4000, 3000, 2000, 1000]
sum(l)
[10]:
15000
[15]:
l = [1, 1.55]
sum(l)
[15]:
2.55

map()

[16]:
l = ['Lisa', 'Eugenie', 'Jan', 'Okan', 'Joerg']
for element in l:
    print(len(element))
4
7
3
4
5
[17]:
lengths = []
for element in l:
    lengths.append(len(element))
lengths
[17]:
[4, 7, 3, 4, 5]
[18]:
len(l[0])
[18]:
4
[19]:
for element in map(len, l):
    print(element)
4
7
3
4
5

Transformation in uppercase Liste …

[20]:
def upper(s):
    return s.upper()
for element in map(upper, l):
    print(element)
LISA
EUGENIE
JAN
OKAN
JOERG

list() function

[8]:
s = 'abcd'
for element in s:
    print(element)
a
b
c
d
[9]:
l = list(s)
l
[9]:
['a', 'b', 'c', 'd']

Functions

[23]:
def maximum(a, b):
    if a < b:
        return b
    else:
        return a
max = maximum(42, 666)
max
[23]:
666
[24]:
type(maximum)
[24]:
function
[26]:
a = maximum
a(1,2)
[26]:
2
[28]:
maximum(1,2)
[28]:
2

Frage: sind a und b nun auch verfuegbar im restlichen Programm?

[34]:
def summe(l):
    x = 0
    for element in l:
        x += element
    return x

gehaelter = [5000, 4000, 3000, 2000, 1000]
budget = summe(gehaelter)
[35]:
budget
[35]:
15000

x in summe() ist eine lokale Variable:

[38]:
try:
    x
except Exception as e:
    print(e)
name 'x' is not defined

Performance: in Operator, und list und set

[41]:
l = [42, 1, 42, 666, 1, 5, 666]
[42]:
42 in l
[42]:
True

ein Vergleich

[43]:
5 in l
[43]:
True

sechs Vergleiche

[44]:
53 in l
[44]:
False

sieben Vergleiche

Lineare Laufzeit

Zum Unterschied von set

[49]:
s = {1,56,42,666,1,5,53}
s
[49]:
{1, 5, 42, 53, 56, 666}
[50]:
s.add(56)
s
[50]:
{1, 5, 42, 53, 56, 666}
[51]:
53 in s
[51]:
True

Konstante Laufzeit -> optimiert für Suche (Hash Table)

Dynamische Evaluierung: eval()

[60]:
eval('[1,2,3]')
[60]:
[1, 2, 3]
[62]:
try:
    eval('[1,2,')
except Exception as e:
    print(e)
unexpected EOF while parsing (<string>, line 1)
[64]:
eval('666')
[64]:
666
[65]:
eval('print("hallo joerg")')
hallo joerg