Python Advanced

[1]:
import sys
sys.version
[1]:
'3.9.2 (default, Feb 20 2021, 00:00:00) \n[GCC 10.2.1 20201125 (Red Hat 10.2.1-9)]'

nameerror bei unbekannten variablen

[2]:
try:
    print(a)
except Exception as e:
    print(e)
name 'a' is not defined
[3]:
lookup_table = {
    1: 'one',
    2: 'two',
}
[4]:
lookup_table
[4]:
{1: 'one', 2: 'two'}
[5]:
type(lookup_table)
[5]:
dict
[6]:
try:
    lookup_table[9]
except Exception as e:
    print(e)
9
[7]:
lookup_table[2]
[7]:
'two'
[8]:
scope = {
    'a': 1,
    'b': 'hallo',
    '12345': 3.12,
    3: 'drei',
}
[9]:
scope
[9]:
{'a': 1, 'b': 'hallo', '12345': 3.12, 3: 'drei'}
[10]:
scope['a']
[10]:
1
[11]:
scope['b']
[11]:
'hallo'
[12]:
scope['12345']
[12]:
3.12
[13]:
scope[3]
[13]:
'drei'
[14]:
globals()['scope']
[14]:
{'a': 1, 'b': 'hallo', '12345': 3.12, 3: 'drei'}
[15]:
del scope['b']
[16]:
globals()['scope']
[16]:
{'a': 1, '12345': 3.12, 3: 'drei'}

now for something completely different

Data Types Recap

Sequential Datatypes

[17]:
liste = [1, 'zwei', 3.0]
[18]:
liste[2]
[18]:
3.0
[19]:
try:
    liste[3]
except Exception as e:
    print(e)
list index out of range
[20]:
noch_eine_liste = ['noch', 'was']
[21]:
gesamte_liste = liste + noch_eine_liste
gesamte_liste
[21]:
[1, 'zwei', 3.0, 'noch', 'was']
[22]:
gesamte_liste.append('das vorläufig letze element')
[23]:
gesamte_liste
[23]:
[1, 'zwei', 3.0, 'noch', 'was', 'das vorläufig letze element']
[24]:
gesamte_liste*2
[24]:
[1,
 'zwei',
 3.0,
 'noch',
 'was',
 'das vorläufig letze element',
 1,
 'zwei',
 3.0,
 'noch',
 'was',
 'das vorläufig letze element']
[25]:
indentation = 2
text = 'blah'
indented_text = 2*' '+text
indented_text
[25]:
'  blah'

Slicing etc.

[26]:
gesamte_liste
[26]:
[1, 'zwei', 3.0, 'noch', 'was', 'das vorläufig letze element']
[27]:
gesamte_liste[2:4]
[27]:
[3.0, 'noch']
[28]:
len(gesamte_liste)
[28]:
6
[29]:
try:
    gesamte_liste[6]
except Exception as e:
    print(e)
list index out of range
[30]:
gesamte_liste[len(gesamte_liste)-1]   # das letzte element der liste
[30]:
'das vorläufig letze element'
[31]:
gesamte_liste[-1]
[31]:
'das vorläufig letze element'
[32]:
gesamte_liste[3:len(gesamte_liste)]
[32]:
['noch', 'was', 'das vorläufig letze element']
[33]:
gesamte_liste[3:]
[33]:
['noch', 'was', 'das vorläufig letze element']
[34]:
gesamte_liste[:3]
[34]:
[1, 'zwei', 3.0]
[35]:
gesamte_liste
[35]:
[1, 'zwei', 3.0, 'noch', 'was', 'das vorläufig letze element']
[36]:
del gesamte_liste[1]
gesamte_liste
[36]:
[1, 3.0, 'noch', 'was', 'das vorläufig letze element']

Mapping Types (Dictionary, und mehr)

[37]:
lookup_table
[37]:
{1: 'one', 2: 'two'}
[38]:
lookup_table[3] = 'three'
[39]:
lookup_table
[39]:
{1: 'one', 2: 'two', 3: 'three'}
[40]:
lookup_table[3]
[40]:
'three'
[41]:
del lookup_table[3]
[42]:
lookup_table    # weg is
[42]:
{1: 'one', 2: 'two'}

nebenbei: Variablen

[43]:
eine_zum_sterben_verurteilte_variable = 666
eine_zum_sterben_verurteilte_variable
[43]:
666
[44]:
del eine_zum_sterben_verurteilte_variable
try:
    eine_zum_sterben_verurteilte_variable
except Exception as e:
    print(e)
name 'eine_zum_sterben_verurteilte_variable' is not defined

Sets

[45]:
ein_set = {'eins', 2, 3}
[46]:
ein_set.add('vier')
ein_set
[46]:
{2, 3, 'eins', 'vier'}
[47]:
ein_set.remove('eins')
[48]:
'eins' in ein_set
[48]:
False
[49]:
2 in ein_set
[49]:
True

Nebenbei: in geht auch in Sequenzen, aber grottenlangsam

[50]:
gesamte_liste
[50]:
[1, 3.0, 'noch', 'was', 'das vorläufig letze element']
[51]:
'was' in gesamte_liste
[51]:
True

for Schleife, ganz kurz

[52]:
for element in gesamte_liste:
    print(element)
1
3.0
noch
was
das vorläufig letze element

Mit while geht das auch, nur sehr potschert:

[53]:
i = 0
while i < len(gesamte_liste):
    print(gesamte_liste[i])
    i += 1
1
3.0
noch
was
das vorläufig letze element

Tuple

[54]:
t = (1,2,3)
[55]:
t[0]
[55]:
1
[56]:
t = (1)
[57]:
try:
    t[0]
except Exception as e:
    print(e)
'int' object is not subscriptable
[58]:
type(t)
[58]:
int
[59]:
True and (False or True)
[59]:
True
[60]:
t = (1,)

Funktionen mit mehreren Returnwerten (bzw. Tuple Unpacking)

[61]:
def multiple_return_values():
    return 1, 'eins'
[62]:
a, b = multiple_return_values()
print(a, b)
1 eins
[63]:
rv = multiple_return_values()
[64]:
type(rv)
[64]:
tuple
[65]:
a, b = rv
[66]:
try:
    a, = rv
except Exception as e:
    print(e)
too many values to unpack (expected 1)

Ist das gleiche wie:

[67]:
def multiple_return_values():
    return (1, 'eins')
[68]:
a, b = [1, 2]

Iteration über Containerdatentypen

Listen

[69]:
l = [1, 2, 3]
for el in l:
    print(el)
1
2
3

Sets

[70]:
s = {1, 2, 3}
for el in s:
    print(el)
1
2
3

Dictionaries

[71]:
d = {'one': 1, 'two': 2}

Iteration über Keys

[72]:
for k in d:
    print(k)
one
two
[73]:
for k in d.keys():
    print(k)
one
two

Iteration über Values

[74]:
for v in d.values():
    print(v)
1
2

Iteration über beides

[75]:
for xyz in d.items():
    print(xyz)
('one', 1)
('two', 2)
[76]:
for k, v in d.items():
    mein_formatierter_string = 'key: '
    mein_formatierter_string += k
    mein_formatierter_string += ', value: '
    mein_formatierter_string += str(v)
    print(mein_formatierter_string)
key: one, value: 1
key: two, value: 2
[77]:
for k, v in d.items():
    print('key:', k, 'value:', v)
key: one value: 1
key: two value: 2
[78]:
for k, v in d.items():
    print('key: {}, value {}'.format(k, v))
key: one, value 1
key: two, value 2

f-Strings

[79]:
for k, v in d.items():
    print(f'key: {k}, value {v}')
key: one, value 1
key: two, value 2

Was heisst “Untypisiert”?

[80]:
def maximum(a, b):
    if a < b:
        return b
    return a
[81]:
maximum(1, 2)
[81]:
2
[82]:
maximum('eins', 'zwei')
[82]:
'zwei'
[83]:
try:
    maximum(1, 'zwei')
except Exception as e:
    print(e)
'<' not supported between instances of 'int' and 'str'

Wir löschen den Integer

[84]:
type(maximum)
[84]:
function
[85]:
a = maximum
[86]:
a(1, 2)
[86]:
2
[87]:
type(int)
[87]:
type
[88]:
int('42')
[88]:
42
[89]:
type(int)
[89]:
type
[90]:
type(int)
[90]:
type
[91]:
int = maximum
[92]:
type(int)
[92]:
function
[93]:
int(1,2)
[93]:
2
[94]:
try:
    int('42')
except Exception as e:
    print(e)
maximum() missing 1 required positional argument: 'b'
[95]:
type(42)
[95]:
int
[96]:
int = type(42)
[97]:
int('42')
[97]:
42
[102]:
int = 17

Iterator Protocol, for Loops

[104]:
r = range(3, 7)
[105]:
for el in r:
    print(el)
3
4
5
6
[106]:
r = range(3, 7)
[107]:
it = iter(r)
[109]:
type(it)
[109]:
range_iterator
[112]:
next(it)
[112]:
5
[113]:
next(it)
[113]:
6
[115]:
try:
    next(it)
except StopIteration as e:
    pass
[122]:
def my_range(start, end):
    retlist = []
    while start < end:
        retlist.append(start)
        start += 1
    return retlist
[125]:
r = my_range(3, 7)
print('zu iterieren:', r)
for el in r:
    print(el)
zu iterieren: [3, 4, 5, 6]
3
4
5
6
[126]:
def my_range(start, end):
    while start < end:
        yield start
        start += 1
[127]:
r = my_range(3, 7)
for el in r:
    print(el)
3
4
5
6

Iterable: Der Begriff

[2]:
liste = [3,4,2,3]
s = set(liste)
len(s)
[2]:
3
[4]:
s
[4]:
{2, 3, 4}
[5]:
zeichenkette = 'hallo joerg'
for elem in zeichenkette:
    print(elem)
h
a
l
l
o

j
o
e
r
g
[6]:
s = set(zeichenkette)
s
[6]:
{' ', 'a', 'e', 'g', 'h', 'j', 'l', 'o', 'r'}

Listen funktionieren ähnlich:

[7]:
l = list(zeichenkette)
l
[7]:
['h', 'a', 'l', 'l', 'o', ' ', 'j', 'o', 'e', 'r', 'g']
[9]:
try:
    list(42)
except Exception as e:
    print(e)
'int' object is not iterable
[11]:
list('x')
[11]:
['x']
[14]:
try:
    for element in 42:
        print(element)
except Exception as e:
    print(e)
'int' object is not iterable
[17]:
try:
    iter(42)
except Exception as e:
    print(e)
'int' object is not iterable
[21]:
r = range(10)
my_liste = []
for elem in r:
    my_liste.append(elem)
print(my_liste)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[22]:
r = range(10)
print(list(r))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Zufall

[23]:
import random
[24]:
random.randrange(10)
[24]:
9
[25]:
random.randrange(10)
[25]:
9
[26]:
random.randrange(10)
[26]:
9
[28]:
random.randrange(10)
[28]:
3
[29]:
random.randrange(10)
[29]:
6

Regular Expressions

[30]:
import re
[32]:
filename = 'AIRMS_ETH.CSV'

Simplizistisches manuelles String-Parsen ist immer blöd

[33]:
phase = filename[0]
if phase in ('A', 'B', 'C'):
    pass # eh ok
i_oder_v = filename[1]
if i_oder_v in ('I', 'V'):
    pass # eh ok
[36]:
match = re.search('^([ABC])([IV])(.*)\\.CSV$', filename)
if match:
    phase = match.group(1)
    i_oder_v = match.group(2)
    anlage = match.group(3)
print(phase, i_oder_v, anlage)
A I RMS_ETH
  • Vorcompilieren der Regex

  • Raw Strings verwenden

  • In der ersten Gruppe 2 Characters

[39]:
filename = 'ACIRMS_ETH.CSV'
my_regex = re.compile(r'^([ABC]{2})([IV])(.*)\.CSV$')
match = my_regex.search(filename)
if match:
    phase = match.group(1)
    i_oder_v = match.group(2)
    anlage = match.group(3)
print(phase, i_oder_v, anlage)
AC I RMS_ETH

enumerate()

[40]:
liste = ['hallo', 'alle', 'und', 'noch', 'was']
for element in liste:
    print(element)
hallo
alle
und
noch
was

Wir wollen aber die Zeilennummer dazuhaben:

[41]:
for element in enumerate(liste):
    print(element)
(0, 'hallo')
(1, 'alle')
(2, 'und')
(3, 'noch')
(4, 'was')
[42]:
for nr, element in enumerate(liste):
    print('position:', nr, ', element:', element)
position: 0 , element: hallo
position: 1 , element: alle
position: 2 , element: und
position: 3 , element: noch
position: 4 , element: was

JSON

[1]:
import json
[6]:
meine_zu_sendenden_daten = ('A', 'I', 'RMS_ETH', 12.345, 220.234)
meine_zu_sendenden_daten_in_string_form = json.dumps(meine_zu_sendenden_daten)
[7]:
meine_zu_sendenden_daten_in_string_form
[7]:
'["A", "I", "RMS_ETH", 12.345, 220.234]'

Diese Daten in String Form werden ueblicherweise uebers Internet verschickt, und auf der anderen Seite im allgemeinen Fall von einem Programm empfangen, das nicht in Python geschrieben ist. Deswegen JSON und nicht einfach str().

Der Empfaenger muss die empfangenen Daten natuerlich wieder zurueckkonvertieren:

[9]:
meine_empfangenen_daten_python_form = json.loads(meine_zu_sendenden_daten_in_string_form)
meine_empfangenen_daten_python_form
[9]:
['A', 'I', 'RMS_ETH', 12.345, 220.234]

Die Information, dass es ein Tupel war, ist verloren gegangen. Aber das ist mir wurscht.