Python

Hier soll es hingehen: Auswertung von Praktikumsversuchen:

Plot

Versuch aus dem Fortgeschrittenen-Praktikum: Lebensdauer kosmischer Myonen

Inhalt

Grundlagen

Eine Programmiersprache wie Python lässt sich nicht an einem Tag lernen.

Hier geben wir einen kurzen Überblick über die wichtigsten Konzepte.

Keine Angst: Zum Erstellen von Plots und für einfache Auswertungen muss man nicht viel Python können!

Die folgenden Beispiele kann man auf der Kommandozeile durch ausführen von

ipython

ausprobieren.

Einfachstes Beispiel

Kommentare

Alles was in Python hinter einem # steht, wird nicht als Code betrachtet und dient als Kommentar.

Kommentare sollten nicht erklären, was der Code tut, sondern warum.

Kommentare, wie jeder andere Code, sollten auf englisch sein.

Variablen

Man kann einem Objekt einen Namen geben:

Variablennamen können auch überschrieben werden:

Datentypen

Einfache Datentypen

Booleans

True und False

Logische Operatoren: and, or, not

None oder leere Objekte verhalten sich wie False, andere wie True

Zahlen

Ganze Zahlen: 42
Kommazahlen: 3.14
Komplexe Zahlen: 3 + 2j

Rechenoperatoren:

Rechenoperationen können geklammert werden

Vergleichsoperatoren geben True oder False zurück

Mehrere Vergleichsoperatoren können in einem Ausdruck stehen:

Strings

Stehen in ' oder ". (Für eins entscheiden)

Strings können mit + konkateniert werden:

Strings können mit * vervielfacht werden

Strings können mit [] indiziert werden

Können beliebige Unicode Symbole enthalten

None

Stellt das Fehlen eines Wertes dar.

Wird häufig für Standardwerte von Funktionen verwendet.

Funktionen, die 'nichts' zurückgeben, geben None zurück:

Sammlungen (Collections)

Speichern mehrere Objekte

Listen

Listen können mit [] indiziert werdern

Man kann Werte an Listen anhängen:

Negative Indizes (beginnend mit -1), indizieren die Liste rückwärts

Man kann auch Teillisten indizieren.
names[Anfang:Ende] liefert eine Teilliste mit den Werten von names[Anfang] bis names[Ende-1]:

Listen werden mit + zusammengeführt:

Listen können mit * vervielfacht werden:

Die Liste kann auch erweitert werden:

Listen sind veränderbar, man kann ihnen Werte zuweisen:

Mit in wird überprüft ob ein Wert in der Liste ist:

Tupel

Können wahlweise auch ohne Klammern geschrieben werden (wenn es eindeutig ist).

Einträge nach Erzeugung unveränderbar:

Dictionaries

Dictionaries sind extrem hilfreich, zum Beispiel um die verschiedene Datensätze der gleichen Messung zusammenzufassen. So wird es einfacher dieselbe Analyse auf die einzelnen Datensätze anzuwenden.

Leere Dictionaries werden z.B. mit der Funktion dict()erstellt

Kontrollstrukturen

Die Zeilen eines Python-Programms werden nacheinander ausgeführt.

Sogennante Kontrollstrukturen erlauben es, den Ablauf zu steuern.

if / elif / else

while

Wiederholen, solange eine Bedingung erfüllt ist.

for

Wiederholen für jedes Elements (z.B. einer Liste)

klassische for-Schleife mit range:

Zwei sehr nützliche Funktionen sind enumerate und zip

Was enumerate() macht:

Was zip() macht:

Iterieren über die Einträge von dict

Übungen 1, 2, und 3 können bearbeitet werden.

Funktionen

Mit Funktionen lässt sich Code leicht wiederverwenden. Eine Funktion nimmt Parameter, verarbeitet sie und gibt Ergebnisse zurück.

Viele Funktionen haben mehrere Parameter, einige können sogar beliebig viele haben:

Viele Funktionen haben optionale Parameter mit eigenem Namen, sogenannte "keyword arguments":

Objekte haben auch Funktionen (diese nennt man Methoden):

In IPython kann man wie folgt auf die Dokumentation einer Funktion zugreifen:

Ansonsten findet man ausführliche Erklärungen in der offiziellen Dokumentation.

Eigene Funktionen definieren mit def

Um mehrfach benötigten Code einfacher zu nutzen, können Funktionen definiert werden.

Vorteile:

Mit dem return Statement wird die Funktion beendet und Ergebnisse zurückgeben.

Es können auch mehrere Werte zurückgeben werden:

Funktionen können sich selbst aufrufen (Rekursion)

Module und import

In Python kann man Code in einzelne Module portionieren.

Es stehen bereits unglaublich viele Module für Python zur Verfügung.

Gerade für das wissenschaftliche Arbeiten ist eigentlich alles da was gebraucht wird und noch viel mehr.

Wird etwas aus einem anderen Modul gebraucht, importiert man es.

Zahlreiche Module sind Teil jeder Python Installation, die sogenannte "standard library": https://docs.python.org/3/library/

Viele weitere Module habt ihr mit Anaconda installiert

Für das Importieren einzelner Funktionen gibt es den Befehl:

Den Modulen können mit as neue Namen gegeben werden

Viele Module haben Konventionen für den Kurznamen, die ihr verwenden solltet

Auslagern in Python-Dateien

Es folgt ein fertiges Python-Programm.

Speichert es als primes.py ab und startet es aus dem Terminal mit python primes.py.

Übung 4, 5 und 6 können bearbeitet werden.

Formatieren von Strings

f-strings

https://docs.python.org/3/reference/lexical_analysis.html#f-strings https://docs.python.org/3/library/string.html#formatspec

Oft will man Werte oder andere Strings in einen String einsetzen.

Seit der Python Version 3.6 gibt es sogenannte f-strings (formatted strings) für String-Formatierung:

Der Ausdruck in den {}-Markierungen wird ausgewertet und das Ergebnis anstelle der geschweiften Klammern gesetzt.
Variablen ersetzt.

f-strings haben viele fortgeschrittene Funktionen.

Beispielsweise kann die gewünschte Genauigkeit für floats angeben werden:

Alle Formateinstellungen werden nach einem Doppelpunkt angegeben.
Für die Genauigkeit sieht die Angabe allgemein so aus: :.Nf
N ist dabei die gewünschte Anzahl an Nachkommastellen.

Sonderzeichen

Mit \ kann man in Strings besondere Anweisungen setzen:

Wenn viele '\' geschrieben werden müssen (z.B. in LaTeX-Code), lohnt es sich diese Funktion mit dem Prefix r auszuschalten:

Will man { oder } im Text stehen haben (für LaTeX benötigt) geht das mit doppelten {{ oder }}.

LaTeX sieht dann leider so aus:

Nur zur Demonstration einmal mit mehr Lücken (funktioniert so nicht in LaTeX wegen den Leerzeichen!):

Comprehensions

Sind nützlich, um Listen oder Dictionaries umzuwandeln oder zu erzeugen:

Übung 7 kann jetzt bearbeitet werden.

Häufig auftretende Fehler

Einige Fehler werden zu Anfang sehr häufig gemacht (und immer mal wieder).
Wenn man die Fehlermeldungen richtig zu lesen weiß, kann einem das viel Arbeit/Frust ersparen.
Das Wichtigste ist: Lest die Fehlermeldung und versucht sie zu verstehen!

Gerade am Anfang beliebt: IndentationError:

Die Fehlermeldung gibt die Zeile an in der Fehler auftritt (hier: line 8)
und den Grund für den Fehler, häufig mit Erklärung (hier: IndentationError: expected an indented block)

Allgemeiner Syntax-Fehler: SyntaxError

Zeile in der der Fehler auftritt: line 6
Grund für den Fehler: SyntaxError: invalid syntax
Hier sogar mit Hinweis auf das fehlerhafte/fehlende Zeichen.

Ein zu Anfang verwirrender Fehler

Die Fehlermeldung ist hier im ersten Moment nicht besonders hilfreich:
Zeile in der der Fehler auftritt: line 11
Grund für den Fehler: SyntaxError: invalid syntax

Stimmt nur zum Teil, denn in Zeile 11 ist alles in Ordnung und der eigentliche Fehler ist in Zeile 10.
In komplexeren Programmen ist das nicht mehr so einfach zu sehen wie hier,
deswegen ist es gut, wenn man dieses Verhalten schon mal gesehen hat.

Auch sehr einfach auszulösen: NameError:

Zeile in der der Fehler auftritt: ----> 7 if a <= n:
Grund für den Fehler: NameError: name 'n' is not defined
Fehlermeldung sieht etwas anders aus, liefert aber immer noch die gleichen Informationen.

Fehler bei Zugriffen auf Listen: IndexError

Zeile in der der Fehler auftritt: ----> 4 names[4]
Grund für den Fehler: IndexError: list index out of range
Fehlermeldung sieht etwas anders aus, liefert aber immer noch die gleichen Informationen.

Fehler bei Zugriffen auf Dictionaries: KeyError

Zeile in der der Fehler auftritt: ----> 4 numbers["five"]
Grund für den Fehler: KeyError: 'five'
Fehlermeldung sieht etwas anders aus, liefert aber immer noch die gleichen Informationen.

Komplexer Fehler mit Traceback:

Wenn an einem Fehler mehrere Funktionen beteiligt sind,
gibt die Fehlermeldung einen Traceback aus.
Dieser Fall ist eher die Regel, vorallem, wenn Module verwendet werden.
Der Traceback zeigt die Reihenfolge aller Funktionsaufrufe, die
am Ende zu dem Fehler geführt haben mit dem letzten Aufruf ganz unten (most recent call last).

Zeilen die zum Auftreten des Fehlers führen:
Funktionsaufruf in Zeile 10:
---> 10 add_one_to_inverse_difference(x,y)
Ergebnis des Funktionsaufrufs ist das return in Zeile 5 mit neuem Funktionsaufruf:
----> 5 return 1 + inverse_difference(a, b)
Ergebnis des 2. Funktionsaufrufs ist das return in Zeile 2:
----> 2 return 1/(a - b)
Hier tritt der Fehler auf, da durch Null geteilt wird, wenn a und b gleich sind!

Grund für den Fehler: ZeroDivisionError: division by zero

Debugging leicht gemacht

Es kann vorkommen, dass man mal überhaupt nicht weiß, warum etwas nicht funktioniert.

In diesem Fall sollte man zunächst mal Ruhe bewahren
und sich dann auf systematische Fehlersuche begeben.
Ein einfacher Ansatz ist das print()-debugging.

Kleiner Trick, um Schuhgröße und Alter einer weiteren Person zu berechnen. Die zweite Person muss folgende Anweisungen befolgen:

1. Multipliziere deine Schuhgröße mit 5         
2. Addiere 50 zum Ergebnis                      
3. Multipliziere das Ergebnis mit 20            
4. Addiere 1020 zum Ergebnis                    
5. Ziehe dein Geburtsjahr vom Ergebnis ab
6. Nenne das Ergebnis

Beispiel:

Mit der Schuhgröße 45 und dem Geburtsjahr 1993, kriege ich die Zahl 4527 raus.
Ich habe (wie erwähnt die Schuhgröße 45) und bin 27 Jahre alt.
Wie funktioniert dieser Trick?!

Die print()-Debugguing Methode:

Die coolere IPython.embed()-Methode:

Das funktioniert auch in normalen Python .py Dateien.
IPython.embed() öffnet ein IPython-Terminalfenster mit allen Variablennamen,
die vorher definiert wurden. Man kann dann interaktiv nach Problemen im Code suchen
oder wie hier herrausfinden wie Code funktioniert.