2. Kurzeinführung in Python#

Lernziel ist es grundlegende Elemente von Python kennenzulernen:

  • Syntax

  • Datentypen

  • Datenstrukturen: Tupel, Listen, Dictionaries

  • Kontrollstrukturen: if, for, while

  • Funktionen

Es geht explizit nicht darum einen umfassenden Überblick über Python zu gewinnen, z.B. wird Objektorientierung größtenteils ausgelassen. Wir betrachten Python vor allem als Werkzeug, um Bibliotheken für Data Analytics wie numpy, pandas, scikit, tensorflow zu nutzen. Wir gehen davon aus, dass die Leser bereits Kenntnisse in einer Programmiersprache haben und die Nutzung von Python on-the-job erlernen. Die datengetriebenen Programmierstile der genannten Bibliotheken korrekt zu nutzen ist häufig konzeptionell schwieriger als die reine Adaption von Code in konventionellen Programmiermodellen z.B. von Java nach Python. Beispielsweise ist die Nutzung einer Schleife in Zusammenhang mit numpy oder pandas ein Warnsignal - man sollte noch mal prüfen, ob es nicht einen eleganteren Weg gibt.

Für umfangreichere Einführungen in Python siehe:

Referenzen:

2.1. Programmierumgebung#

Python ist eine interpretierte Programmiersprache - es ist kein Compile-Vorgang notwendig. Wir können direkt eine Quellcode-Datei ausführen, z.B. können wir in der Datei helloworld.py den folgenden Quelltext speichern:

Nun können wir diesen Direkt ausführen:

Einer der Treiber für die Beliebtheit von Python ist sicher die interaktive Ausführung von Python mit ipython und vor allem die Integration in eine bequeme Weboberfläche mit Support für integrierte Graphiken und Markdown-Textabschnitte in Jupyter Notebook.

Die Installation von Jupyter Notebook ist einfach:

  • per pip: pip install notebook

  • per conda: conda install -c conda-forge notebook Danach können Sie aus der Kommandozeile mit jupyter notebook die Umgebung starten - der Webbrowser wird automatisch geöffnet.

Für eine Kurzeinführung siehe: http://bit.ly/jupyter-tour

Cheat Sheet zu Jupyter Notebook: https://www.edureka.co/blog/wp-content/uploads/2018/10/Jupyter_Notebook_CheatSheet_Edureka.pdf

Beachten Sie insbesondere den Menüeintrag Help, der Ihnen im weiteren Verlauf sehr gute Dienste leisten kann.

Ebenso extrem hilfreich sind die Tastenkombinationen (siehe Help -> Keyboard shortcuts) und dabei insbesondere:

  • <TAB> für die Autovervollständigung von Variablennamen, Funktionsnamen, Methoden von Objekten usw.

  • <SHIFT>-<TAB> für Hilfe innerhalb der Klammern eines Funktionsaufrufs

Hilfe ist ebenso mit dem ? Operator möglich - das können Sie ausprobieren, wenn Sie z.B. den folgenden Code ausführen:

?print

2.2. Syntax#

Wir haben bereits kennengelernt:

  • Funktionsaufrüfe mit function_name(parameter)

  • Strings mit "Inhalt" Das führt uns zu:

print("Hello World")
Hello World

Strings können auch in einfachen Anführungszeichen stehen 'Hello World' und mehrere Strings mit + zusammengefügt werden.

'Hello ' + " World"
'Hello  World'

+ und andere Operationen funktionieren wie gewohnt für Zahlen, um Ausdrücke zu bilden, z.B.:

Operator

Beispiel

Ergebnis

-

5-2

3

+

5+2

7

/

22/8

2.75

*

3*5

15

**

2**3

8

Ein weiterer Erfolgsfaktor von Python ist die Lesbarkeit des Quellcodes. Dennoch ist nicht jeder Code selbsterklärend und der Leser des Codes - das ist man oft genug selber - freut sich über Kommentare, die mit # eingeleitet werden

# Das ist ein Kommentar

2.3. Datentypen#

Python ist dynamisch typisiert. Dies erlaubt uns Variablen ohne Typangaben zu erstellen und zu nutzen - ABER: es gibt Typen in Python und diese werden im Normalfall nicht automatisch konvertiert. Z.B.:

'3' + 3
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/tmp/ipykernel_2610/1841419283.py in <module>
----> 1 '3' + 3

TypeError: can only concatenate str (not "int") to str
3 + '3'
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-17-4ab8cd832a54> in <module>
----> 1 3 + '3'

TypeError: unsupported operand type(s) for +: 'int' and 'str'

Weder wird ein String automatisch in eine Zahl konvertiert noch andersrum. Zwei Ausnahmen in einer Zeile:

print(2/3)
0.6666666666666666

Hier werden Ganzzahlen automatisch in Fließkommazahlen umgewandelt und die Zahl für print automatisch in einen String. Ansonsten ist Vorsicht angebracht:

'2' + '3'
'23'
'2' * 3
'222'

Oder explizite Konvertierungen sind angesagt:

int('2') * str(3)
'33'

Boolean#

Es ist existieren die 2 Konstanten True und False, ansonsten sind standardmäßig alle Objekte (das beinhaltet in Python auch Zahlen) true außer:

  • Numerische Typen mit dem Wert Null, z.B. 0, 0.0

  • Leere Sequenzen und Collections inklusive dem leeren String, z.B. ‘’, (), [], {}

  • Die Konstanten None und False

Die booleschen Operatoren sind or, and and not.

0 == 1
False
not 0 == 1
True

and and or liefern den letzten evaluierten Operanden zurück:

() or '' or [] or {}
{}
() and '' and [] and {}
()
1 or 0
1
True and False
False

2.4. Variablen#

Varablen können jederzeit ohne vorherige Deklaration durch die Zuweisung per = definiert werden:

a = 1
b = 2
c = a + b

Eine Zuweisung liefert keinen Wert zurück - das sehen wir in Jupyer Notebook (mit dem dieser Teil des Skripts entwickelt wurde) daran, dass es kein Out[ ] gibt. Wenn wir den Wert einer Variablen nach Zuweisung anzeigen wollen, müssen wir print verwenden:

print(c)
3

Oder wir erstellen einen Ausdruck, der einfach nur die Variable auswertet:

c
3

Variablen können fast beliebige Namen haben - die Groß-/Kleinschreibung wird berücksichtigt. Es gibt Ausnahmen:

  • Reservierte Wörter: and, as, assert, break, class, continue, def, del, elif, else, except, False, finally, for, from, global, if, import, in, is, lambda, None, nonlocal, not, or, pass, raise, return, True, try, with, while and yield.

not = 1
  File "<ipython-input-36-b2ac4f479726>", line 1
    not = 1
        ^
SyntaxError: invalid syntax
  • Namen, die mit einer Zahl anfangen:

123abc = "Hallo"
  File "<ipython-input-37-572ffeaeb2a7>", line 1
    123abc = "Hallo"
       ^
SyntaxError: invalid syntax
  • Namen mit Leerzeichen, stattdessen einfach einen Underscore _ verwenden:

echt langer Variablenname = 4
  File "<ipython-input-38-6e16b34befd2>", line 1
    echt langer Variablenname = 4
         ^
SyntaxError: invalid syntax
echt_langer_Variablenmame = 4
  • Nicht verboten aber nicht empfehlenswert: gemischte Kapitalisierung

variable_1 = 4
Variable_1 += 1
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-40-2d2cdd4870de> in <module>
      1 variable_1 = 4
----> 2 Variable_1 += 1

NameError: name 'Variable_1' is not defined
  • Ebenso erlaubt aber besser lassen: Sonderzeichen

# DON'T DO IT!
übung = 1

Nutzung von Variablen in Strings#

Mit f'' können so genannte Format-Strings verwendet werden. In diesen Strings können innerhalb von geschweiften Klammern Ausdrücke stehen, die im String durch den ausgewerteten und zum String umgewandelten Ausdruck ersetzt werden. Optional kann in den geschweiften Klammern mit : noch ein Format für den Ausdruck eingefügt werden.

Beispiele:

world = 'Welt'
f'Hallo {world}'
'Hallo Welt'
a = 2.0
print(f'a = {a}')
print(f'2 * a = {2 * a}')
a = 2.0
2 * a = 4.0
b = 100.0
print(f'{a}\n{b}')
2.0
100.0
c = 1000
print(f'{a:8,.2f}\n{b:8,.2f}\n{c:8,.2f}')
    2.00
  100.00
1,000.00

2.5. Datenstrukturen#

Listen#

Listen können beliebige Werten in einer bestimmten Reihenfolge abspeichern. Die Werte in einer Liste können verschiedene Typen haben - üblich sind aber Listen von einem einzelnen Typ. Listen können verändert werden. Sie können direkt mit Hilfe von eckigen Klammern und durch Kommas separierte Werte im Code erstellt werden:

a = [1, 2, 3]
print(a)
[1, 2, 3]

Auf einzelne Werte wird mit [index] zugegriffen - sowohl lesend als auch schreibend. Es wird bei 0 angefangen zu zählen.

print(a[0])
a[0] = a[0] + 1
print(a[0])
1
2

Es kann auch vom Ende der Liste aus zugegriffen werden indem man einen negativen Index verwendet - hier fängt man bei -1 an zu zählen. Man kann auch auf einen Unterabschnitt der Liste zugriffen - auf ein sogenanntes slice. Dazu wird [start_index:end_index] verwendet. start_index ist inklusive mit Default-Wert 0; end_index ist exklusive mit Default-Wert entsprechend der Länge der Liste.

a[-1]
3
a[0:2] = [1,2]
a[0:3]
[1, 2, 3]
a[-2:]
[2, 3]

Mit + können Listen aneinander gehängt werden - das Ergebnis ist eine neue Liste. Mit der append()-Methode können neue Werte ans Ende der Liste angehängt werden. Die Funktion len() gibt die Länge der Liste aus. Sie funktioniert übrigens auch für Strings.

b = a + [4, 5, 6]
print(b)
[1, 2, 3, 4, 5, 6]
a.append(4)
print(a)
[1, 2, 3, 4]
len(a)
4
len("Hallo")
5

Tupel#

Tupel sind ebenso wie Listen ein Sequenz-Typ. Im Gegensatz zu Listen sind Tupel unveränderbar und werden häufig mit gemischten Datentypen verwendet, z.B. um zusammengehörende Daten zu strukturieren. Tupel werden als eine Reihe von kommaseparierten Werten angelegt. Klammern sind dabei optional.

# Create tuples with content Firstname, Lastname, Year of birth, Favorite foods
joe = ('Joe', 'Doe', 1984, ['Steak', 'Fish', 'Vegetables'])
jane = 'Jane', 'Doe', 1998, ['Fish', 'Eggs']

jane
('Jane', 'Doe', 1998, ['Fish', 'Eggs'])
first, last, yob, foods = joe

print(first)
print(foods)
Joe
['Steak', 'Fish', 'Vegetables']

Ranges#

Ranges sind ein weiterer Sequenz-Typ, der per Konstruktor angelegt wird und eine gleichförmige Integer-Reihe darstellen. Der Vorteil gegenüber einer Liste ist der geringe Speicherverbrauch, da die Elemente einer Range berechnet werden können und nicht vollständig im Hauptspeicher materialisiert werden muss. Mit list() kann aber genau diese Materialisierung in eine Liste vorgenommen werden. Es gibt zwei Varianten von range:

  • range(stop): Liefert die Integer-Reihe von 0 bis stop - 1

r = range(5)
r
range(0, 5)
list(r)
[0, 1, 2, 3, 4]
r[0]
0
r[-3:]
range(2, 5)
  • range(start, stop[, step]): Liefert die Integer-Reihe von start bis stop mit einer Schrittweite step

list(range(1,10,2))
[1, 3, 5, 7, 9]
list(range(0,51,5))
[0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50]
list(range(-1, -11, -1))
[-1, -2, -3, -4, -5, -6, -7, -8, -9, -10]

Dictionaries#

Ein Dictionary ist eine Datenstruktur, die key-value-Paare, so abspeichert, dass mit Hilfe des keys effizient auf den value zugegriffen werden kann. Diese Datenstruktur ist in anderen Programmiersprachen u.a. auch als Hashmap, Hashtable oder Assoziativspeicher bekannt. keys müssen einen unveränderbaren Typ haben, z.B. Strings oder Zahlen.

Ein leeres Dictionary wird mit {} angelegt, optional können in den geschweiften Klammern direkt key: value Paare per Komma separiert angelegt werden. Der Zugriff auf values erfolgt über den Key in geschweiften Klammern nach dem Dictionary.

d1 = {}
d1['Joe'] = 'Doe'
d1['Jane'] = 'Doe'
d1
{'Joe': 'Doe', 'Jane': 'Doe'}
d2 = {'Doe': ['Jane', 'Joe']}
d2['Doe'][0]
'Jane'
# Prüfen, ob ein key vorhanden ist:
'Jack' in d1
False
# Entfernen eines key-value Paars:
del d1['Joe']
d1
{'Jane': 'Doe'}

2.6. Kontrollstrukturen#

Bevor wir auf Kontrollstrukturen eingehen, müssen wir einen wichtigen Aspekt der Python-Syntax betrachten: Whitespaces sind wichtig. Statt Code-Blöcke mit { und } abzugrenzen, wie es in vielen Programmiersprachen üblich ist, werden Code-Blöcke in Python über die Einrückung bestimmt. Dabei ist es gängige Leerzeichen statt Tabs zu verweden. Ein Block wird eingeleitet mit einem : und enthält alle nachfolgenden Zeilen, die weiter eingerückt sind als die einleitende Zeile.

Ein Beispiel mit if:

if True:
    print('Hallo True')
    
if False:
    print('Hallo False')

print('Hallo zusammen')
Hallo True
Hallo zusammen

Blöcke können geschachtelt werden:

if 1 + 1 > 1:
    print('Die erste Bedingung ist wahr')
    if 1 != 2:
        if not False:
            print('Alle Bedingungen sind wahr')
Die erste Bedingung ist wahr
Alle Bedingungen sind wahr

Bedingungen#

Neben if und else können noch weitere Bedingungen mit elif eingefügt werden:

number = 10
if number < 10:
    print('Kleine Zahl')
elif number < 100:
    print('Mittlere Zahl')
else:
    print('Große Zahl')
Mittlere Zahl

while-Schleifen#

while-Schleifen bestehen aus dem Schlüsselwort while gefolgt von der Bedingung und danach ein Block, der so lange ausgeführt wird wie die Bedingung als Wahr ausgewertet wird.

i = 0
while i < 3:
    print(f'Durchgang mit i = {i}')
    i += 1
Durchgang mit i = 0
Durchgang mit i = 1
Durchgang mit i = 2

for-Schleifen#

for-Schleifen in Python folgen immer der Form for variable(n) in sequence - also dem was in anderen Programmiersprachen typischerweise als for-each-loop bekannt ist.

for i in ['Hallo', 'Welt']:
    print(i)
Hallo
Welt
for i in 'Hallo':
    print(i)
H
a
l
l
o

Die “klassische” for-Schleife, z.B. aus Java for(int i=0; i<10; i++) kann wie folgt ausgedrückt werden:

for i in range(10):
    print(i)
0
1
2
3
4
5
6
7
8
9

2.7. Funktionen#

Funktionen werden mit def definiert. Es folgt der Funktionsname und dann in Klammern die Parameter. Der Code der Funktion folgt dann in einem Code-Block. Parameter können optional sein, wenn ein Default-Wert angegeben wird. Beispiel:

def begruessung(name, grusswort='Hallo'):
    print(f'{grusswort} {name}')

Aufgerufen werden Funktionen über ihren Namen gefolgt von den Parametern in Klammern:

begruessung('Joe')
Hallo Joe
begruessung('Jane', 'Hello')
Hello Jane

Bei Verwendung der Parameternamen, kann die Reihenfolge beim Funktionsaufruf geändert werden, z.B.:

begruessung(grusswort='Hello', name='World')
Hello World

Funktionen können auch anonym mit dem Schlüsselwort lambda erstellt werden und diese wiederum in Variablen gespeichert werden.

f = lambda a, b: a + b
g = lambda x: x * 2
f(1,2)
3
g(f(1,2))
6
list(map(lambda x: x * 2, [1, 2, 3]))
[2, 4, 6]
list(map(g, [1, 2, 3]))
[2, 4, 6]

2.8. Klassen, Objekte und Methoden#

Wir gehen nicht darauf ein, wie man in Python objektorientiert programmiert und eigene Klassen erstellt. Wir werden aber häufig Klassen und Objekte verwenden. Sowohl Klassen als auch Objekte (also Instanzen einer Klassen) können Attribute haben - das können entweder Variablen sein in denen Daten gespeichert werden oder Funktionen, die man im Kontext der Klasse oder des Objekts aufruft. Diese Funktionen entsprechen dann den bekannten Klassen- oder Instanzmethoden. Der Name des Attributes wird per Punkt an die Klasse oder das Objekt gehängt. Zu beachten im Vergleich z.B. zu Java:

  • In Python ist es üblich direkt Datenvariablen zu verwenden anstatt Getter und Setter zu implementieren

  • Methoden sind Attribute und daher wird ein Funktionsobjekt zurückgeliefert, wenn die Klammern (und ggfs. Parameter) nicht angegeben werden

a = "hallo"
# Ein String ist ein Objekt
# a.<TAB> liefert die Attribute, z.B. die capitalize-Methode
a.capitalize()
'Hallo'
# Ohne die Klammern bekommt man die Funktion geliefert
a.capitalize
<function str.capitalize()>

2.9. Bibliotheken#

Wir nutzen Python hauptsächlich als Schnittstelle, um auf mächtige Bibliotheken wie z.B. numpy zuzugreifen. Neben den bereits in der Standard-Library enthaltenen Bibliotheken können auf der Kommandozeile per pip3 install PAKETNAME oder in Jupyter-Notebook mit %pip install PAKETNAME weitere Pakete installiert werden. Mit from BIBNAME import ELEMENT können bestimmte Elemente aus einer Bibliothek in den lokalen Namespace importiert werden.

from datetime import  datetime

dt = datetime.now()
dt
datetime.datetime(2021, 7, 8, 12, 37, 29, 862138)
# Attribut von datetime.datetime-Objekten:
dt.year
2021
dt.strftime('%Y-%m-%d %H:%M:%S')
'2021-07-07 14:45:55'

Es ist auch möglich ganze Bibliotheken zu importieren mit import BIBNAME. Dann muss vor Elementen aus der Bibliothek immer BIBNAME. vorangestellt werden. Häufig wird dazu mit as ein kürzerer Alias vergeben, z.B.:

import numpy as np
np.array([1,2,3])
array([1, 2, 3])

2.10. Abschluss#

Dies war ein Kurzüberblick über die Grundlagen von Python, die es uns erlauben mächtige Bibliotheken zu nutzen. Weitere Aspekte werden wir bei Bedarf einführen, bzw. können eigenständig in der Python Dokumentation nachgeschlagen werden: https://docs.python.org/3/