Deutsch / Englisch

Die Programmiersprache Python

Einführung

Vorbemerkung

Warum gerade Python?

Python ... Ein bedeutender Grund für die Beliebtheit von Python ist die große Zahl frei verfügbarer Materialien wie zum Beispiel Einführungen (Englisch: Tutorials), Gratis-Bücher, Beispielprogramme, Erweiterungen, etc. Vieles davon ist auf Englisch einiges aber auch auf Deutsch.
Eine wichtige Anlaufstelle für Python ist die Seite der Python Software Foundation.

Rechengeschwindigkeit (Performance)

Python entstand zuerst als Lehrsprache im akademischen Bereich. Deshalb war Geschwindigkeit (Performance) nicht das wichtigste Ziel. Python ist in der Ausführung wesentlich langsamer als C und deutlich langsamer als Java. Das ist aber weniger eine Eigenschaft der Sprache selbst als der konkreten Implementierung.

Abhilfe

Die wichtigsten Eigenschaften von Python

In Python wird zwischen Groß- und Kleinschreibung unterschieden (Auf Englisch sagt man die Sprache ist "case sensitive"). Das gilt sowohl für die reservierten Wörter als auch für Variablennamen. Für diejenigen, die schon eine andere Programmiersprache kennen, ist die folgende Liste interessant:

Python wird interpretiert

Vereinfacht dargestellt gibt es 2 Arten von Programmiersprachen: Compiler und Interpreter. Python gehört zur 2. Gruppe. Das hat den Vorteil, dass ein Programm nicht nach jeder Änderung in Maschinensprache übersetzt (=kompiliert) werden muss. Andererseits bedeutet es aber, dass Python auf jedem Computer installiert sein muss, auf dem ein Pythonprogramm lauffähig sein soll. Für die meisten dieser Einschränkungen gibt es aber Abhilfen (zum Beispiel http://www.py2exe.org/).

Wie wird Python installiert?

Python wird (für Einsteiger recht verwirrend) in 2 Versionen angeboten: Version 2 und Version 3
Wann wählt man welche Version?
Von Version 2 auf Version 3 wurden einige Verbesserungen vorgenommen die nicht abwärtskompatibel zur Version 2 sind, das heisst Python 3 Programme, die diese neuen Merkmale verwenden, laufen unter Python 2 nicht.
Deshalb gilt:
Schreibt man ein Programm ganz neu ohne fremde Bibliotheken (=Libraries) zu verwenden, dann greift man zu Python 3. Ist man auf die Verwendung von solchen Bibliotheken angewiesen und diese existieren nur in der Python 2 Version, dann greift man zu Python 2. Im Zweifelsfall installiertst du zuerst Python 3.
Die Installation ist denkbar einfach.

Windows

Eine Google Suche mit den Wörtern "Python herunterladen" oder "Download Python" liefert meist die richtige Adresse als erstes Suchergebnis:
https://www.python.org/downloads/
Nach dem Herunterladen befindet sich die Datei python-x.y.z.exe im Downloads-Ordner, wobei x, y, z Ziffern sind, die die Versionsnummer angeben. Die Ziffer z ändert sich in jeder neuen Version, die Ziffer y nur bei größeren Änderungen und die Ziffer x zeigt an das es einige umfangreiche Änderungen in der neuen Version gibt, aber keine Angst, üblicherweise können für ältere Versionen geschriebene Programme so wie sie sind weiterverwendet werden.
Klicke die heruntergeladene Datei mit einem Doppelklick an, ann öffnet sich folgendes Fenster:

install

Dort setzt man folgendes Häkchen:

install path

Dadurch kann Python systemweit von überall aufgerufen werden.
Dann klickt man auf "Install Now". Nach kurzer Zeit sollte dann ein Fenster mit dem Text "Setup was successful" erscheinen.
Wann würde man dieses Häkchen nicht setzen?
Wenn man auf einem Rechner mehrere verschiedene Python-Versionen parallel laufen lassen möchte. Zum Beispiel wenn man eine Anwendung hat die eine bestimmte Version von Python benötigt.
Standardmässig wird Windows-Benutzern die 32-bit Version angeboten. Diese Version kann man getrost auch auf 64-bit Windows-Versionen installieren. Für Python gibt es auch eine 64-bit Version. Die ist für den Anfang aber nicht notwendig.

Linux

Auf vielen Linuxsystemen ist Python schon vorinstalliert. Eventuell muss man aber bei der Konfiguration etwas nachhelfen.

Raspberry Pi

Nicht nur ist Python hier bereits installiert, das "Pi" in Raspberry Pi steht für Python und zeigt das Bekenntnis des Mini-Computers zu dieser Programmiersprache.

MacOS

Python sollte bereits installiert und lauffähig sein, eventuell aber nicht in der letzten Version. Die neueste Version findest du unter folgendem Link:
https://www.python.org/downloads/mac-osx/

Python verwenden

Endlich ist es so weit. Python ist am Computer installiert. Wie kann ich es starten?
Fahre mit der Maus über das Windows-Start-Symbol in der linken unteren Ecke, klicke 1 mal und beginne auf der Tastatur "pyth..." zu tippen. Während du tippst erscheint das Menü wie im Bild unten:

start python

Dir werden 2 Möglichkeiten angeboten Python zu starten:
Für die erste Möglichkeit brauchst du nicht unbedingt den hier gezeigten Link, die Python-Shell funktioniert in jeder Windows-Eingabeaufforderung.

Die Windows-Eingabeaufforderung

Fahre wieder mit der Maus über das Windows-Start-Symbol in der linken unteren Ecke, klicke 1 mal und beginne auf der Tastatur "cmd" zu tippen. Es erscheint dann folgendes Menü:

start command

Klicke auf Eingabeaufforderung dann öffnet sich folgendes Fenster:

command
Schneller geht es mit: Fenster+r, tippe dann cmd und dann Enter.

Es öffnet sich die Windows-Eingabeaufforderung. Ein Cursor steht in der ersten Zeile und wartet auf Deine Eingabe.

Was ist die Windows-Eingabeaufforderung?

Die Windows-Eingabeaufforderung wird auch manchmal Kommandozeile oder Shell genannt, ist gleichsam ein zusätzlicher, leistungsstarker Zugang zum Betriebssystem Deines Computers. Die Windows-Eingabeaufforderung ist sehr mächtig und gerade deshalb absichtlich etwas versteckt. Hier sollen nur Benutzer arbeiten, die wissen was sie tun.
In der Eingabeaufforderung kann man Textbefehle eingeben und damit etwas bewirken oder auch nur Informationen erlangen. Gibst du hier zum Beispiel "dir" (=directory) ein gefolgt von der Eingabetaste. Dann bekommst Du den Inhalt des aktuellen Verzeichnisses aufgelistet. Probier das ruhig einmal aus. Mit "cd" kannst Du in eines der aufgelisteten Verzeichnisse wechseln und mit "cd .." kannst du wieder um eine Ebene zurück.

Die Python Shell

Gib nun in der Eingabeaufforderung "python" ein:

shell

Python meldet sich mit ">>>". Das heisst die Installation hat funktioniert und Python wurde auf dem System gefunden. Die ">>>" nennt man auch den Prompt. Damit meldet sich Python und sagt: "Ich bin bereit für Deine Eingaben".
Führt die Eingabe von "python" hier zur Fehlermeldung:
Der Befehl "python" ist entweder falsch geschrieben oder konnte nicht gefunden werden.
Dann gibt es 2 Möglichkeiten:
  • Python wurde nicht richtig installiert
  • Python ist installiert wurde aber nicht gefunden
Versuch im ersteren Fall die Installation noch einmal und wenn es wieder nicht klappt, bitte jemand um Unterstützung. Im zweiten Fall hat während der Installation das Setzen des Systempfads nicht geklappt. Vielleicht war während der Installation das betreffende Häkchen nicht gesetzt? Entweder versuchst du eine Deinstallation und Neuinstallation diesmal mit dem Häkchen, alternativ kann man diese Konfiguration auch manuell vornehmen:

Gib zuerst in der Windows Eingabeaufforderung "where python" ein und drücke die Eingabetaste:
C:\Users\administrator>where python

Windows meldet dann den Pfad von python.exe der könnte etwas so lauten (xy steht für die Versionsnummer):
C:\Pythonxy\python.exe

oder so:
C:\Users\administrator\AppData\Local\Programs\Python\Pythonxy-z\python.exe


Öffne dann:
Start > System > Erweiterte Systemeinstellungen > Umgebungsvariablen
Selektiere in der Rubrik "Systemvariablen" die Variable "Pfad" und drücke "Bearbeiten".
Füge dann den entsprechenden Python-Pfad ans Ende der Variablen hinzu, der alte und der neue Inhalt werden mit ";" getrennt. Das Ergebnis wäre dann zum Beispiel (xyz sind die Versionsnummern, sie müssen mit deiner Version übereinstimmen):
C:\Windows;C:\Windows\System32;C:\Pythonxy
oder
C:\Windows;C:\Windows\System32;C:\Users\administrator\AppData\Local\Programs\Python\Pythonxy-z\

Alternative

Alternativ zur lokalen Installation gibt es auch online-Varianten, zum Beispiel die hier gezeigte:
https://repl.it/languages/python3

Eine lokale Installation ist aber für unseren Zweck zu bevorzugen.

Wenn alles geklappt hat, haben wir jetzt eine Python Shell zur Verfügung eine sehr gute Möglichkeit erste Erfahrungen mit Python zu sammeln. Die Shell nennt man auch den "interaktiven Modus" denn auf jede Eingabe reagiert Python sofort mit einem Ergebnis. Python "antwortet" sozusagen auf unsere Eingaben.
Hier zeigt sich die Stärke eines Interpreters. Die eingegebenen Programmstücke müssen eben im Gegensatz zu einem Compiler nicht zuerst übersetzt werden.

Hello World (Vorgriff)

Traditionell das erste Programm, das man in jeder Programmiersprache lernt:
print("hello world!")

Ausdrücke (Expressions)

Was ist ein Ausdruck? Ausdrücke sind wichtige Bausteine von Programmen. Ein Ausdruck besteht aus einer Kombination von Werten und Operatoren. Ausdrücke werden ausgewertet und liefern dann wieder einen Wert.

Folgende Beispiele sind uns aus der Schule bekannt:
Man kann Ausdrücke mit oder ohne Leerzeichen schreiben, je nach Geschmack.
(3+5)*2 ist äquivalent (3 + 5) * 2

Wohlgeformtheit von Ausdrücken

Der Aufbau von Ausdrücken ist bestimmten Regeln unterworfen. Kennst du Beispiele? Erfüllt ein Ausdruck diese Regeln, dann nennt man ihn "wohlgeformt". Andererseits kann er nicht ausgewertet werden und der Versuch liefert einen Fehler. Einen Regelverstoß in diesem Zusammenhang heisst "syntaktischer Fehler". (Später werden wir sehen, dass es noch andere Arten von syntaktischen Fehlern gibt)

Die Python-Shell ist ein ideales Werkzeug um Ausdrücke zu testen. Während der Entwicklung eines Programms lohnt es sich immer eine Shell offen zu haben wo schnell Ausdrücke getestet werden können.

Operatoren

Die folgende Tabelle zeigt einige wichtige Python-Operatoren.
Die Reihung erfolgt in absteigender "Operatorrangfolge" (Priorität):
  
**Potenz
*, /, //, %Multiplikation, Division, ganzzahlige Division, Modulo
+, -Addition, Subtraktion
in, not inElement von, nicht Element von
<, <=, >, >=, !=, ==Vergleich
notlogisches "nicht"
andlogisches "und"
orlogisches "oder"

Operatoren in der gleichen Zeile haben gleiche Priorität. Wenn man einen Ausdruck anhand dieser Tabelle auswertet beginnt man immer mit dem Operator der am weitesten oben in der Tabelle steht. Stehen zwei Operatoren in der gleichen Zeile, dann wertet man den Ausdruck von links nach rechts aus. Wenn keine Klammern vorhanden sind, wird zum Beispiel * vor + ausgewertet, da * in der Liste vor + steht. Ebenso wird "and" vor "or" ausgewertet, da "and" in der Liste vor "or" steht. Durch Klammern kann man eine andere Auswertungsreihenfolge bewirken aber Klammern können einen Ausdruck auch lesbarer machen.
Jetzt lässt sich unsere Liste von Ausdrücken noch weiter ausbauen:

Bemerkung

Die Verwechslung von "=" und "==" ist einer der häufigsten Programmierfehler und passiert auch geübten Programmierern.
Ein großer Vorteil in Python ist, dass "a = 1" keine gültige Bedingung ist, so dass "if a = 1:" einen Fehler liefert.

"Überladen" von Operatoren (operator overloading)

Achtung!: "Überladen" von Operatoren kann für Anfänger sehr verwirrend sein. Um einen Ausdruck auszuwerten muss man zuerst sicher sein, welchen Datentypen man vor sich hat.
Welche Ausgabe erzeugt folgende Anweisung. Erkläre das Ergebnis:
print("*"*3)
Welche Ausgabe erzeugt folgende Anweisung. Erkläre das Ergebnis:
print("a"<"b")

Datentypen

Man unterscheidet grundlegende und höhere Datentypen. Zunächst werden wir uns mit den Grundlegenen Datentypen beschäftigen.

Integer (Ganzzahl)

Enthält eine ganze Zahl jeder Größe, positiv oder negativ, wie 1 oder 3 oder 9999999 oder -712 oder 0.
Im Unterschied zu vielen anderen Sprachen sind Integers "unbounded", können also beliebig groß sein. Das spart viel Aufwand, macht die Programme sicherer (Überlauf) und funktioniert weil Python selbst für jede Zahl so viel Speicher reserviert wie notwendig.

Gleitkommazahl (Float)

Enthält eine Dezimalzahl wie 11.456 oder -71.3 oder 29.0 (Achtung! "." statt ",")

Gleitkommazahlen sind auf den ersten Blick der umfassendere Datentyp. Haben aber entscheidende Nachteile. Zum Beispiel ist ein Vergleich nicht so einfach wie bei ganzen Zahlen:
2.00000001
2.00000000
Sind die Zahlen gleich oder nicht?

Gleitkommazahlen werden auch verwendet, um sehr große oder sehr kleine Zahlen in wissenschaftlicher Notation darzustellen. So bedeutet zum Beispiel 5.0e30 eine 5 gefolgt von 30 Nullen. 1.7e-6 ist 0.000017, was bedeutet 1,7 dividiert durch 1 gefolgt von 6 Nullen.

Zeichenkette (String)

Enthält eine Zeichenkette (Engl.: string) also einen Text, zum Beispiel den Namen einer Person, wie Max Mustermann. Die hier demnächst verwendete input-Funktion liefert eine Zeichenkette.

Boolean (logischer Wert)

Enthält entweder wahr (True) oder falsch (False). Der Datentyp Boolean kann nur einen dieser zwei Zustände annehmen. Boolesche Werte entstehen auch durch Vergleiche.
Die Auswertung des Ausdrucks 3 < 4 ergibt zum Beispiel den booleschen Wert True (wahr).

Mittels der type-Funktion kann abgefragt werden, welcher Datentyp vorliegt.
Mit den Umwandlungsfunktionen kann zwischen den Datentypen konvertiert werden: Im folgenden Beispiel sieht man, wie die type-Funktion und Umwandlungsfunktionen verwendet werden können:
>>> type(bool("true")) <class 'bool'> >>> bool(0) False >>> bool(1) True >>> type(3) <class 'int'> >>> type(3.0) <class 'float'> >>> type(1/2) <class 'float'> >>>
Was fällt dir beim letzten Aufruf auf?

Literale

Variable

Variablen sind wie Behälter für einen Wert. Um Variablen voneinander zu unterscheiden haben sie Bezeichner. Über diese Bezeichner wird auf die Werte zugegriffen.
x=2 y=x*2 print("x:", x) print("y:", y)

gültige Variablennamen

Variablennamen unterliegen gewissen Regeln.
Das gilt auch für andere Bezeichner in Python (Funktionsnamen, Klassennamen, ...).
Erlaubte Zeichen sind:
Verboten sind: Gute Variablennamen drücken die Bedeutung/Verwendung des Werts aus, den sie enthalten. Zum Beispiel: anzahl, summe, laenge, vorname, nachname, alter, temperatur_12_uhr, ... strecke, winkel, entfernung, x, y, z (für Koordinaten)

Python-Konvention (PEP 8)

Variablennamen und Funktionsnamen werden klein, Klassen groß geschrieben.
Beides ist leider unter Umständen sehr schwer zu finden.

Zuweisung

x=2 vorname="max" pi=3.14 ist_groesser_als = True ist_nicht_groesser_als = not ist_groesser_als        # Code ist wie Text

Achtung!: eine Zuweisung ist keine Gleichung.
x=x+1 ist eine gültige Zuweisung aber als Gleichung wäre es sinnlos.

Anweisungen

Manchmal entsprechen Anweisungen den Zeilen im Programm, eine Anweisung kann sich aber auch über mehrere Zeilen erstrecken.
name = input("Bitte geben sie ihren Namen ein: ") print("Hallo", name)

Anweisungsfolgen

Einfache Programme bestehen manchmal lediglich aus Anweisungsfolgen.
x=2 x=x*2 print("x:",x)
Anweisungsfolgen werden streng in der Reihenfolge abgearbeitet.

Kommentare

Man unterscheidet einzeilige "#" und mehrzeilige Kommentare: """
Zweck: Für denjenigen bestimmt, der den Code liest, also unter Umständen auch für den Autor selbst.

Solche Kommentare nicht notwendig. Selbsterklärend.
x=3     # Der Variablen x wird der Wert 3 zugewiesen

""" Mit dem dreifachen Hochkomma kann man einfach mehrere Zeilen auskommentieren """
Die obige Methode kann auch dazu dienen ganze Programmteile auszukommentieren und damit inaktiv zu schalten.

Zunächst vielleicht etwas verwirrend:
Auch mehrzeiligen Text im Programm schreibt man mit dreifachem Hochkomma.
>>> str = """hallo ... du!""" >>> str 'hallo\ndu!' >>> print(str) hallo du! >>>

IDLE

Python ist eine textorientierte Sprache. Python-Programme kann man mit jedem Texteditor schreiben.
Eine integrierte Entwicklungs Umgebung oder IDE unterstützt beim Programmieren. Bei der Python-Standardinstallation ist eine einfache aber gute IDE namens "IDLE" schon vorinstalliert.

Wichtigste Merkmale von IDLE.
Öffnet und startet man ein Pythonprogramm dann sind 3 Fenster vorhanden
  1. der Quellcode
  2. das Anwendungsfenster: hier läuft das Programm ab
  3. eine Python-Shell, wo alle print()-Ausgaben und eventuelle Fehlermeldungen angezeigt werden
Mit Alt+tab wechselt man zwischen den Fenstern. Schließen kann man sie unter Windows mit Alt+F4 oder mit dem "x" rechts oben..
(Für andere Betriebssysteme gibt es gleichbedeutende Shortcuts)

Achtung! Python-Programme dürfen nicht die gleichen Namen erhalten wie verwendete Python-Module.
Zum Beispiel führt eine selbst erstellte Programmdatei "turtle.py" zu einem Fehlerhalten.
Leider erhält man in dem Fall keine Fehlermeldung.

Die if-Anweisung

Einfache Programme bestehen manchmal nur aus Anweisungsfolgen aber diese können weder auf äußere Bedingungen noch auf innere Zustände reagieren. Der Programmablauf hat keine Varianten und ist streng linear.
if <bedingung>:     <anweisungsblock>
Bei folgendem Beispiel kommt die input-Funktion zum Einsatz, die bisher nicht erklärt wurde.
Die input-Funktion erwartet eine durch Enter abgeschlossene Benutzereingabe. Man kann der input-Funktion einen Text übergeben der ausgegeben wird. Die Benutzereingabe wird als Text zurückgeliefert (auch wenn der Benutzer eine Zahl eingibt).
>>> str = input("Tippe etwas ein: ") Tippe etwas ein: Test >>> str 'Test' >>>

temp = int(input("Wie kalt ist es heute?: ")) if temp < 0:     print("Vorsicht Glatteis!")
Man beachte hier, dass das Programm scheitert, wenn der Benutzer keine ganze Zahl eingibt.

Einrückungen in Python

Die Verwendung von Einrückungen zur Bildung von Blöcken ist eine Besonderheit von Python.
Dieses Merkmal wirkt auf Umsteiger von anderen Sprachen zunächst gewöhnungsbedürftig ist aber sehr praktisch.

else

Häufig braucht man auch Entscheidungen der folgenden Form:
temp = int(input("Wie kalt ist es heute?: ")) if temp < 0:     print("Vorsicht Glatteis!") else:     print("Vermutlich heute kein Glatteis.")

elif (else if)

Mit dem elif Zweig ist das if-Konstrukt komplett:
temp = int(input("Wie kalt ist es heute?: ")) if temp < 0:     print("Vorsicht Glatteis!") elif temp > 0:     print("Heute sicher kein Glatteis.") else:        # temp == 0 (alles rechts von "#" ist nur ein Kommentar)     print("Es hat genau Null Grad.")
Der elif-Zweig darf als einziger mehrfach vorkommen.

Aufgabe:
Schreibe ein Programm, das den Benutzer auffordert sein Alter einzugeben. Das Programm soll feststellen ob der Benutzer unter 13, ein Teenager (13-19) oder ob er älter ist. Das Programm soll dann eine entsprechende Ausgabe machen.
Verwende dazu die input-Funktion.

Schleifen

In Python gibt es 2 Arten von Schleifen.

for-Schleifen

Vor allem praktisch wenn man vorab weiß, wie oft man die Schleife durchlaufen will
Oft - aber nicht immer - kommt hier die range-Funktion zum Einsatz.
Versuch einmal folgendes in der Shell einzugeben:
print(list(range(10)))
for i in range(10):     print(i)

Spezialfall:
for char in "abcdef":     print(char)

Analog bei Listen

while-Schleifen

Diese sind vor allem praktisch wenn man die Anzahl der Durchläufe nicht genau weiß aber eine Schleifenbedingung leicht angeben kann.
i = 0 while i < 10:       # "i < 10": Schleifenbedingung     print(i)     i=i+1       # Diese Zeile sehr wichtig wegen Abbruchbedingung!
Der Programmierer ist selbst verantwortlich, dass die Abbruchbedingungen tatsächlich erreicht wird. Oft kommt es unbeabsichtigt zu einer Endlosschleife.

Aber manchmal will man ganz bewusst eine Endlosschleife (zb für die Implementierung eines Dienstes):
while True:     print(".", end="") print("Auf Wiedersehen")   # Diese Zeile wird niemals erreicht: "toter Code"

break

Die break-Anweisung beendet die Schleife vorzeitig, das Programm wird aber weiter ausgeführt.
Nun sehen wir, dass eine "while True:"-Schleife nur dann eine Endlosschleife ist, wenn sie kein erreichbares "break" enthält.
In dem Zusammenhang ist eine "while True:"-Konstruktion eine durchaus sinnvolle Möglichkeit.

Aufgabe:
Schreibe ein Programm, das den Benutzer auffordert ganze Zahlen einzugeben. Durch die Eingabe von "q" soll das Programm beendet werden. Vorher soll aber die Summe der eingegebenen Zahlen ausgegeben werden.

Listen

Listen gehören zu den höheren Datentypen. Höhere Datentypen sind im Gegensatz zu grundlegenden Datentypen nicht atomar. Mit ihnen können Serien von Werten (zum Beispiel eine Messwertreihe) oder Kompositionen (zum Beispiel ein Personendatensatz bestehend aus Vorname, Nachname, Geburtsdatum, ...) dargestellt werden.

Auf folgende Weise kann eine Liste in Python erstellt werden:
haustiere = ["Katze","Hund","Hamster","Goldfisch","Hase"]

Die Namen der Haustiere sind hier die Elemente. Auf Elemente kann dann über ihren sogenannten Index zugegriffen werden, indem zuerst der Name der Liste oder des Tupels und dann die Position des Elements in eckigen Klammern angegeben wird.

Achtung!:
Nicht nur in Python, sondern auch in fast allen anderen Programmiersprachen beginnt man aber bei der Zählung nicht mit 1 sondern mit 0!

Die Eingabe von haustiere[3] liefert also nicht, wie man vielleicht vermuten würde 'Hamster', sondern: 'Goldfisch'!
Das ist ein fundamentaler Unterschied, eine mögliche Fehlerquelle und jeder Programmieranfänger braucht mehr oder weniger Zeit, sich daran zu gewöhnen.
haustiere [0] liefert also demnach 'Katze' und Eingabe von haustiere alleine liefert die ganze Liste.
Hier auch noch ein kleiner Trick: haustiere[-1] liefert das letzte Element der Liste also "Hase".

Beispiel:
>>> haustiere = ["Katze","Hund","Hamster","Goldfisch","Hase"] >>> haustiere[3] 'Goldfisch' >>> haustiere[0] 'Katze' >>> haustiere ['Katze', 'Hund', 'Hamster', 'Goldfisch', 'Hase'] >>>

Der folgende Befehl sortiert die Liste namens haustiere:
haustiere.sort()

Beispiel:
Namen = ["David", "Anna", "Peter", "Paul", "Luise"] print("Die Namen sind:", Namen) Namen.sort() print("Die Namen in sortierter Reihenfolge sind:") print(Namen)

Bei Ausführung ergibt das:
>>> Die Namen sind: ['David', 'Anna', 'Peter', 'Paul', 'Luise'] Die Namen in sortierter Reihenfolge sind: ['Anna', 'David', 'Luise', 'Paul', 'Peter'] >>>

Schnitt-Operator (slice operator) für Listen

Dieser liefert Teile von Listen zurück:

Liste[n:m] liefert eine Liste zurück mit Elementen der Liste beginnend beim Element mit dem Index n inklusive bis zum Element mit dem Index m exklusive.

Der untere (n) und obere Index (m) können aber auch entfallen, also sind auch folgende Varianten erlaubt:
Hier ein paar Beispiele zur Verdeutlichung:
>>> Namen = ["Sarah", "David", "Ann", "Peter", "Mary", "Paul"] >>> Namen[0:1] ['Sarah'] >>> Namen[1:4] ['David', 'Ann', 'Peter'] >>> Namen[3:] ['Peter', 'Mary', 'Paul'] >>> Namen[:4] ['Sarah', 'David', 'Ann', 'Peter']

Durchlaufen von Listen

Zum Durchlaufen von Listen wird die for-Schleife wie folgt verwendet:
haustiere = ["Katze","Hund","Hamster","Goldfisch","Hase"] for element in haustiere:     print(element)

Gemischte Listen

In Python sind gemischte Listen erlaubt, das heisst die Elemente müssen nicht alle den gleichen Datentyp haben.
(Das ist gar nicht so selbstverständlich)
Also ist folgendes erlaubt:
Mix_List = ["abc", 1, 3.5, False]

Listen von Listen

werden später behandelt

Eingebaute Methoden für Listen

Mit dem dir-Befehl (funktioniert mit jedem Objekt) werden diese angezeigt. Methoden mit "__" können vorerst ignoriert werden (zum Beispiel __add__ entspricht dem "+"-Operator):
>>> dir(list) ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort'] >>>
Hier findet man alle grundlegenden nützlichen Funktionen zu Listen wie zum Beispiel Hinzufügen, Entfernen, ...
Achtung!: was liefert list.count()?

Versuche auch:
help(list)

oder:
help(list.insert)

In diesem Sinne können wir herausfinden, dass list.count nicht die Anzahl der Elemente einer Liste liefert, denn dazu bräuchte die Methode keinen zusätzlichen Parameter.
Die count-Methode liefert die Anzahl der Elemente eines bestimmten (übergebenen) Werts. Für die Gesamtzahl der Elemente genügt "len()" (eingebaute Funktionen).
Anmerkung: wann verwendet man objektorientierte Schreibweise "Objekt.Methode()" wann verwendet man klassische Schreibweise "Funktion(Parameter)"?

Verwenden wir diese Information zur Demonstration einer möglichen Arbeitsweise mit Listen:
list_1 = [] list_1.append("a") list_1.append("b") list_1.append("c") print(list_1) list_1.insert(1,"d") print(list_1) list_1.remove("d") print(list_1)

dir()/help()

dir() und help() funktionieren auch mit eingebauten Objekten:
int (integer), float, bool, str (strings), dict (dictionaries), list, tuple, set, ...
Und auch mit importierten Objekten:
>>> import math >>> dir(math) ['__doc__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'trunc'] >>> help(math.sin) Help on built-in function sin in module math: sin(...) sin(x) Return the sine of x (measured in radians). >>>

Tupel

Für sie gilt alles was für Listen gesagt wurde, mit der Ausnahmen, dass einmal erstellte Tupel nicht mehr verändert werden können.
haustiere = ("Katze","Hund","Hamster","Goldfisch","Hase") for element in haustiere:     print(element) print(haustiere[3]) haustiere.insert(2, "Goldfisch")

Liefert:
>>> Katze Hund Hamster Goldfisch Hase Traceback (most recent call last):   File "C:/Python34/haustiere.py", line 4, in <module>     haustiere.insert(2, "Goldfisch") AttributeError: 'tuple' object has no attribute 'insert' >>>

Funktionen

Eine Funktion ist ein Stück Programmcode, das von verschiedenen Stellen des Programms aufgerufen werden kann. Funktionen kennst du bereits, denn Python verfügt über viele nützliche eingebaute Funktionen ohne die fast kein Programm auskommt. input() und print() sind Beispiele für solche Funktionen:

Liste "eingebauter Funktionen" (built-in functions)

Ein gelegentliche Durchsicht dieser Liste ist jedenfalls empfehlenswert, weil sich hier nützliche Bausteine finden, auf die eigene Werke aufbauen können. Manche eingbaute Funktionen verwendet man häufig, manche nur sehr selten:

https://docs.python.org/3/library/functions.html

Neben der Möglichkeit der Verwendung von eingebauten Funktionen ist aber gerade die Möglichkeit, selbst Funktionen erstellen zu können, eine der wichtigsten grundlegenden Methoden einer Programmiersprache.
In Python wird das Schlüsselwort def (kurz für englisch "define") zur Definition einer Funktion verwendet. Eine Funktion kann von jedem Ort im des Programms aufgerufen werden, indem sein Name angegeben wird. Der Programmcode in der Funktion wird dann abgearbeitet und nach Fertigstellung wird das aufrufende Programm weiter ausgeführt und zwar ab der Stelle des Aufrufs. Der Programmfluss springt sozusagen an die Stelle des Aufrufs zurück.
Es gibt Funktionen, die etwas tun ("do_...") und Funktionen die etwas liefern ("get_...") und Kombinationen daraus.

ohne Parameter

Es werden trotzdem die "()" verwendet, um von einer Variablen unterscheiden zu können.

Betrachten wir folgende Funktion:
def Sterne(): print("*****") print("Vor dem Aufruf der Funktion Sterne()") Sterne() print("Nach dem Aufruf der Funktion Sterne()")

>>> ============= RESTART: C:/.../sterne.py ============= Vor dem Aufruf der Funktion Sterne() ***** Nach dem Aufruf der Funktion Sterne() >>>

Das ist die einfachste Art einer Funktion aber sie ist nicht sehr flexibel. Es werden immer 5 Sterne ausgegeben.

mit einem/mehreren Parameter(n)

Die folgende Funktion ist eine verbesserte Variante der Funktion oben. Ein Parameter wird übergeben, der steuert wieviele Sterne ausgegeben werden.
def Sterne_laut_Anzahl(Anzahl_Sterne): print("*" * Anzahl_Sterne) Sterne_laut_Anzahl(5)

Ruft man sie mit dem Parameter 5 auf ist das Ergebnis das gleiche wie bei der Funktion oben.
>>> ==== RESTART: .../Sterne_laut_Anzahl.py ==== ***** >>>

So eine Funktion kann natürlich vielseitiger eingesetzt werden:
def Sterne_laut_Anzahl(Anzahl_Sterne): print("*" * Anzahl_Sterne) Sterne_laut_Anzahl(1) Sterne_laut_Anzahl(2) Sterne_laut_Anzahl(3)

Das obige Programm liefert:
>>> ==== RESTART: .../Sterne_laut_Anzahl.py ==== * ** *** >>>

mit oder ohne Rückgabewert

Die bisher erstellten Funktionen lieferten keinen Wert zurück: Funktion ohne Rückgabewert. Die gut bekannte print()-Funktion ist ein Beispiel für diese Gruppe.
Funktionen ohne Rückgabewert nennt man in anderen Programmiersprachen auch Prozedur.

Eine Funktion kann auch eine Berechnung ausführen und dem aufrufenden Programm einen Wert zurückliefern: Funktion mit Rückgabewert. Die uns bereits gut bekannte input()-Funktion ist ein Beispiel für diese Gruppe.
#T(°C) = (T(°F) - 32) / 1.8 def Fahrenheit_nach_Celsius(Temperatur_in_Fahrenheit): return int((Temperatur_in_Fahrenheit - 32) / 1.8) print("-100 Fahrenheit sind in Celsius: ", Fahrenheit_nach_Celsius(-100)) print("0 Fahrenheit sind in Celsius: ", Fahrenheit_nach_Celsius(0)) print("100 Fahrenheit sind in Celsius: ", Fahrenheit_nach_Celsius(100))

Zentraler Punkt dabei ist die für uns neue return-Anweisung, gebildet aus dem "return"-Schlüsselwort und gefolgt vom Rückgabewert. Die return-Anweisung beendet die Ausführung der Funktion und liefert den Rückgabewert zurück. Eventueller Programmcode nach einer return-Anweisung wird nicht mehr ausgeführt ("toter" Code). Über einen Aufruf:
if <Bedingung>: return
kann das aber nicht pauschal gesagt werden. Der return Befehl muss also nicht die letzte Anweisung in der Funktion sein.

Im aufrufenden Programm wird dann der Funktionsaufruf durch den Rückgabewert ersetzt. Aus:
print("-100 Fahrenheit sind in Celsius: ", Fahrenheit_nach_Celsius(-100))

wird nach der Ausführung der Funktion und Einsetzen des Rückgabewerts:
print("-100 Fahrenheit sind in Celsius: ", -73)

Eine Ausführung des Programms liefert demnach:
>>> RESTART: .../Fahrenheit_nach_Celsius.py -100 Fahrenheit sind in Celsius: -73 0 Fahrenheit sind in Celsius: -17 100 Fahrenheit sind in Celsius: 37 >>>

Im dem kleinen Programm oben haben wir den Rückgabewert in int umgewandelt weil sich durch die Division lange Kommazahlen ergeben würden. Stattdessen hätten wir auch eine Rundung vornehmen können um die Werte genauer ausgeben zu können. Python stellt dafür die eingebaute Funktion "round()" zur Verfügung, mit der man zum Beispiel auf 2 Nachkommastellen runden kann. Ändere die Zeile:
return int((Temperatur_in_Fahrenheit - 32) / 1.8)

in
return round((Temperatur_in_Fahrenheit - 32) / 1.8,2)

Auch die eingebaute Funktion "round()" ist eine Funktion mit Rückgabewert. Man übergibt ihr 2 Übergabeparameter: die zu rundende Zahl und die Anzahl der Stellen auf die gerundet werden soll. Gehe auch bei den folgenden 2 Zeilen so vor und starte das Programm. Achtung! Ein häufiger und sehr nachvollziehbarer Anfängerfehler bezüglich Funktionen mit Rückgabewert kann mit folgendem Beispiel-Programm gezeigt werden:
def double(Zahl): return Zahl * 2 double(10)

Betrachte das Programm und versuche vorherzusagen, was beim Aufruf passieren wird. Ist das Programm fehlerfei? Wird es funktionieren wie gewünscht? Probiere das Programm aus. Schlage Lösungen vor.

Auflösung:
Das Programm ist syntaktisch korrekt (es enthält keine syntaktischen Fehler). Allerdings enthält das Programm einen semantischen Fehler, welcher schwieriger zu finden ist, als ein syntaktischer Fehler. Die Funktion ist richtig definiert und sinnvoll benannt. Der Aufruf ist in Ordnung, aber das Problem ist, dass mit dem von der Funktion zurückgelieferten Rückgabewert nichts geschieht. Der Wert wird weder ausgegeben, noch sonstwie weiterverwendet. Nach dem Start terminiert das Programm nach kurzer Rechenzeit, aber es passiert nichts. Eine mögliche Behebung wäre die Zeile:
double(10)

zu ändern in:
print("Das Ergebnis ist:", double(10))

Boolesche Funktionen

Das sind Funktionen die als Ergebnis nur True oder False liefern können.
Diese können als Bedingung (zum Beispiel in if, while) verwendet werden.
Es muss nicht
if f()==True:     ...

geschrieben werden.
if f():     ...

genügt vollkommen.
Dasselbe gilt auch für boolsche Variablen.

Funktionen sind auch eine wichtige Möglichkeit ein Programm zu strukturieren.

Dictionaries   +! erweiterter Inhalt

Ein weiterer wichtiger Datentyp in Python. Ähnlich einer Liste aber die Elemente werden nicht über einen Index angesprochen sondern über einen "Schlüssel". Man sagt auch, dass Dictionaries Listen von Schlüssel/Wert-Paaren sind.
>>> dict = {"eins":"one", "zwei":"two", "drei":"three", "vier":"four"} >>> dict["eins"] 'one' >>> print(dict) {'vier': 'four', 'zwei': 'two', 'drei': 'three', 'eins': 'one'} >>>

Die Reihenfolge im Dictionary ist nicht garantiert.
dict = {"eins":"one", "zwei":"two", "drei":"three", "vier":"four"} for key in dict: print ("key:", key, "dict[key]:", dict[key])

Das obige Programm liefert:
>>> key: eins dict[key]: one key: drei dict[key]: three key: vier dict[key]: four key: zwei dict[key]: two >>>

Verschachtelte Dictionaries (nested dictionaries)

...

Importieren von Modulen

Mittels Import von Modulen kann man die Funktionalität von Python erweitern.
Es gibt mehrere Arten diesen Import durchzuführen.
import random Obst = ["Apfel", "Birne", "Banane", "Orange"] print(random.choice(Obst)) for i in range(10): print(random.randint(1,6)) for i in range(10): print(random.randrange(1,7))

from time import strftime, gmtime, localtime # http://strftime.org/, https://docs.python.org/2/library/datetime.html print("aktuelle Zeit:", strftime("%d.%m.%Y %H:%M", gmtime())) print("aktuelle Zeit:", strftime("%d.%m.%Y %H:%M", localtime())) print("aktuelle Zeit:", strftime("%d.%m.%Y %I:%M", localtime())) print("aktuelle Zeit:", strftime("%d.%m.%Y %I:%M %p", localtime())) """ Example output: aktuelle Zeit: 03.05.2018 12:35 aktuelle Zeit: 03.05.2018 14:35 aktuelle Zeit: 03.05.2018 02:35 aktuelle Zeit: 22.11.2018 02:35 PM """

"strftime" steht wahrscheinlich für "string from time". Mehr Informationen zur Formatierung von Datum und Zeit finden Sie:
http://strftime.org/
https://docs.python.org/2/library/datetime.html

from math import * print(sqrt(9)) print(pi)

Importiert werden: Objekte, Funktionen, Konstante

Turtle-Grafik

In Python gibt es eine großartige Möglichkeit, auf einfache Art mit Grafikprogrammierung zu beginnen. Traditionell wird dieses Modul Turtle-Grafik genannt, weil es um eine gedachte Schildkröte geht, die, während man sie mit Befehlen steuert, einen farbigen Strich zieht, wo immer man sie hinschickt. Die Farbe und Stärke des Stifts steuert man auch über Befehle und man kann den Stift heben und senken.
Nachdem man mittels "from turtle import *" die Turtle-Bibliothek importiert hat, kann man auf alle Turtle-Befehle zugreifen. Ein Teil dieser Befehle ist hier aufgelistet, bei vielen Befehlen gibt es eine Lang- und eine Kurzform (zum Beispiel forward und fd) - es spielt keine Rolle, welche der beiden man verwendet.

Turtle-Befehle:
fd(Strecke) (forward)Die Schildkröte bewegt sich um "Strecke" nach vorne.
bk(Strecke) (back)Die Schildkröte bewegt sich um "Strecke" rückwärts.
lt(Winkel) (left)Die Schildkröte dreht sich um "Winkel" nach links.
rt(Winkel) (right)Die Schildkröte dreht sich um "Winkel" nach rechts.
pu() (pen up)Die Schildkröte hebt den Zeichenstift an (und schreibt nicht mehr).
pd() (pen down)Die Schildkröte senkt den Zeichenstift (und schreibt wieder).
pensize(Breite)setzt die Stiftdicke auf "Breite".
pencolor(Farbe)setzt die Stiftfarbe auf "Farbe".
shape(Form)setzt die Form der Schildkröte (‘arrow’,‘classic’,‘turtle’,‘circle’).
home()Schildkröte kehrt nach (0,0) zurück (Mitte des Zeichenblatts).
clear()Löschen der Zeichnung, Schildkröte ändert Zustand nicht.
reset()Löschen der Zeichnung, Schildkröte geht in Ausgangszustand.
setup(Breite, Hoehe)Fenster mit "Breite", "Hoehe" erzeugen.
heading()In welche Richtung schaut die Schildkröte? (3-Uhr-Position = 0)
setheading(Winkel)Drehe die Schildkröte in Richtung "Winkel" (3-Uhr-Position=0).
goto(x, y)Bewege die Turtle zur Position x, y.
(Falls pen=down wird auch gezeichnet. Ändert die Orientierung nicht.)
dot(size, color)Zeichnet einen Kreis der Größe "size" und der Farbe "color" an der aktuellen Position.
towards(x, y)Liefert den Winkel, den sich die Schildkröte drehen müsste um auf x, y zu zeigen.

Mit Turtle-Grafik kann man auf einfache Art tolle Grafiken erstellen und auf anschauliche Art viel über Programmierung lernen, weil man sozusagen den Programmen bei der Arbeit zusehen kann.
Und hier zur Demonstration ein Beispielprogramm:
from turtle import * setup(400,400) # Legt ein Fenster dieser Größe an shape('turtle') # Zeigt die Schildkröte fd(50) # 50 Einheiten nach vorn lt(90) # Dreht um 90 Grad nach links pencolor('red') # Stiftfarbe ist ab jetzt "rot" fd(70) lt(90) fd(110) pencolor('blue') # Stiftfarbe ist ab jetzt "blau" rt(90) # Dreht um 90 Grad nach rechts bk(100) # Fährt 100 Einheiten zurück pu() # pen up: Hebt den Stift ab lt(45) bk(50) pd() # pen down: Senkt den Stift ab pensize(5) # Ändert Stiftgröße auf 5 bk(70) pensize(1) home() # Geht zum Ursprung

Hier das Ergebnis beim Aufruf des Programms:

turtle

Und hier noch ein fortgeschrittenes Beispiel:
import turtle, colorsys turtle.setup(350,350) turtle.pensize(10) turtle.color("#ff0000") turtle.fd(10) turtle.color("#00ff00") turtle.fd(10) turtle.color("#0000ff") turtle.fd(10) hue=0.0 i = 0 while True: turtle.fd(1) turtle.lt(1) turtle.color(colorsys.hsv_to_rgb(hue, 1, 1)) hue+=0.01 i = i + 1 if i > 315: break

Ausgabe des Programms:

circle

Ereignisorientierte Programmierung

In der Programmierung gibt es verschiedene fundamentale Ansätze. Mehrere davon kennst du schon, denn sie sind fester Bestandteil der traditionellen Programmierung: In diesem Kapitel wird ein weiterer Ansatz vorgestellt. Auch dieser ist Bestandteil der traditionellen Programmierung, er ist aber nicht ganz so universell anzutreffen wie die drei oben erwähnten Ansätze. Im Zusammenhang mit der Programmierung von graphischen Benutzerschnittstellen (Graphical User Interfaces = GUIs) kommt dieser Ansatz verstärkt um Einsatz.
Bei der ereignisorientierten Programmierung (englisch Event-driven programming oder auch Event-based programming) spielen Ereignisse eine zentrale Rolle in der Programmlogik. Jede Aktion des Benutzers, zum Beispiel Mausbewegungen, Klicks, Drücken von Tasten, löst Ereignisse aus. Aber auch Mechanismen innerhalb des Programms können Ereignisse auslösen, wie etwa der Ablauf einer festgelegten Zeitspanne, das Eintreffen von Daten oder das Beenden einer vorher gestarteten Aufgabe. Auch vom Rechner selbst können Ereignisse ausgelöst werden, zum Beispiel ein Notebook, dessen Akkustand unter eine gewisse Schwelle sinkt, könnte ein speziell dafür vorherbestimmtes Ereignis auslösen.

Ereignisbehandlungsroutinen (Event handler)

Tastendruck-Ereignisse

Ereignisse sind speziellen Ereignisbehandlungsroutinen (Funktionen) zugeordnet, die aufgerufen werden, sobald die Ereignisse eintreten. Zum Beispiel können den Pfeiltasten auf der Tastatur (nach oben, nach unten, links, rechts) solche Ereignisbehandlungsroutinen zugewiesen werden. Je nachdem, welcher Event auftritt (nach oben, nach unten, links, rechts), führt das Programm die passende Ereignisbehandlungsroutine aus, die dann die richtige Bewegung der Schildkröte ausführt.
Um diese ereignisorienierte Programmierung praktisch vorzustellen, eignet sich die oben vorgestellte Turtle-Bibliothek ideal.
import turtle turtle.setup(400,500) # Fenstergröße wn = turtle.Screen() # wn repräsentiert das Fenster wn.title("Tastendruck-Ereignisse") # Fenster Titel wn.bgcolor("lightgray") # Hintergrundfarbe schildkroete = turtle.Turtle() # Schildkröte anlegen # Event-Handler: def h1(): schildkroete.forward(30) def h2(): schildkroete.left(15) def h3(): schildkroete.right(15) def h4(): wn.bye() # Fenster schließen # Verknüpfung herstellen zwischen Tastenereignissen und Handlern wn.onkey(h1, "Up") wn.onkey(h2, "Left") wn.onkey(h3, "Right") wn.onkey(h4, "q") # Mit "listen" fängt die Anwendung an nach Ereignissen zu "horchen". # Ein richtiger Tastendruck löst den zugehörigen Eventhandler aus. wn.listen() wn.mainloop()

keypress

Mausklick-Ereignisse

Ich kann aber auch auf Mausklick-Ereignisse reagieren. Ich füge nun folgenden Handler in das obige Programm ein:
... def h5(x, y): schildkroete.penup() schildkroete.goto(x, y) schildkroete.pendown() ...

und mit folgender Zeile verknüpfe ich den Handler mit dem Ereignis:
... wn.onclick(h5) # "onclick" reagiert auf Mausklick ...

Also zusammen:
import turtle turtle.setup(400,500) # Fenstergröße wn = turtle.Screen() # wn repräsentiert das Fenster wn.title("Tastendruck-Ereignisse") # Fenster Titel wn.bgcolor("lightgray") # Hintergrundfarbe schildkroete = turtle.Turtle() # Schildkröte anlegen # Event-Handler: def h1(): schildkroete.forward(30) def h2(): schildkroete.left(15) def h3(): schildkroete.right(15) def h4(): wn.bye() # Fenster schließen #------------------- neu ------------------------ def h5(x, y): schildkroete.penup() schildkroete.goto(x, y) schildkroete.pendown() #------------------------------------------------ # Verknüpfung herstellen zwischen Tastenereignissen und Handlern wn.onkey(h1, "Up") wn.onkey(h2, "Left") wn.onkey(h3, "Right") wn.onkey(h4, "q") #------------------- neu ------------------------ wn.onclick(h5) # "onclick" reagiert auf Mausklick #------------------------------------------------ # Mit "listen" fängt die Anwendung an nach Ereignissen zu "horchen". # Ein richtiger Tastendruck löst den zugehörigen Eventhandler aus. wn.listen() wn.mainloop()

Folgende Abbildung zeigt dann eine mögliche Ausführung wenn ich während der Ausführung auf verschiedene Punkte des Fensters klicke:
mouse click

Rest des Kapitels+! erweiterter Inhalt

Timer

Sehen wir uns folgendes Beispiel an:
import turtle turtle.setup(400,500) wn = turtle.Screen() wn.title("Using a timer") wn.bgcolor("lightgray") schildkroete = turtle.Turtle() schildkroete.color("purple") schildkroete.pensize(3) def h1(): schildkroete.forward(100) schildkroete.left(56) wn.ontimer(h1, 2000) wn.mainloop()

Mittels der ontimer-Funktion wird festgelegt, dass die Funktion h1 nach 2 Sekunden aufgerufen wird.
Ergebnis:
timer
Für manche Anwendungszwecke reicht das aus aber wenn eine Timer-Funktion regelmässig aufgerufen werden soll dann muss man so vorgehen wir unten gezeigt:
import turtle turtle.setup(400,500) wn = turtle.Screen() wn.title("Using a timer") wn.bgcolor("lightgray") schildkroete = turtle.Turtle() schildkroete.color("purple") schildkroete.pensize(3) def h1(): schildkroete.forward(100) schildkroete.left(56) wn.ontimer(h1, 2000) h1() wn.mainloop()
Ergebnis:
timer 2

Bauen wir nun diese Timer-Funktionalität in unser Beispiel ein:
import turtle turtle.setup(400,500) # Fenstergröße wn = turtle.Screen() # wn repräsentiert das Fenster wn.title("Tastendruck-Ereignisse") # Fenster Titel wn.bgcolor("lightgray") # Hintergrundfarbe schildkroete = turtle.Turtle() # Schildkröte anlegen # Event-Handler: def h1(): schildkroete.forward(30) def h2(): schildkroete.left(15) def h3(): schildkroete.right(15) def h4(): wn.bye() # Fenster schließen def h5(x, y): schildkroete.penup() schildkroete.goto(x, y) schildkroete.pendown() #------------------- neu ------------------------ def h6(): if schildkroete.pensize() == 1: schildkroete.pensize(10) else: schildkroete.pensize(1) wn.ontimer(h6, 700) #------------------------------------------------ # Verknüpfung herstellen zwischen Tastenereignissen und Handlern wn.onkey(h1, "Up") wn.onkey(h2, "Left") wn.onkey(h3, "Right") wn.onkey(h4, "q") wn.onclick(h5) # "onclick" reagiert auf Mausklick # Mit "listen" fängt die Anwendung an nach Ereignissen zu "horchen". # Ein richtiger Tastendruck löst den zugehörigen Eventhandler aus. wn.listen() #------------------- neu ------------------------ h6() #------------------------------------------------ wn.mainloop()

Und hier wieder ein Beispiel für eine Durchführung:
timer

Rekursion

Aus der Schule erinnern wir uns an die Definition der Faktoriellen:

n! = n * (n-1)! (für alle n > 1))
n! = 1 (für n:0,1)

Betrachten wir folgende Funktion.
from turtle import * setup(800, 800) def zeichne_rekursiv(wie_oft_noch): if wie_oft_noch < 1: # Abbruch der Rekursion return fd(wie_oft_noch) lt(15) # Rekursionsaufruf mit verringerter Größe: zeichne_rekursiv(wie_oft_noch - 1) zeichne_rekursiv(50)

Das Programm erzeugt folgendes Bild:
rekursion

Rekursion kann anfänglich recht verwirrend wirken, denn eine Definition, die sich selbst enthält erinnert auf den ersten Blick an einen fehlerhaften Zirkelbezug. Zum Beispiel wie im folgenden Dialog:

"Kennst du Max?"
"Ja, das ist der Nachbar von Tom"
"Wer ist Tom?"
"Das ist der Nachbar von Max"

Tatsächlich handelt es sich aber bei unserer Funktion um keinen Zirkelbezug, weil bei einem Funktionsaufruf immer auch der Übergabeparameter eine Rolle spielt.
Erweitern wir die Funktion noch etwas:
from turtle import * setup(800, 800) def dreieck(groesse): # Zeichnet ein Dreieck in der angegebenen Größe # Nach dem Zeichnen ist die Schildkröte wieder # in der ursprünglichen Position und hat den # ursprünglichen Winkel fd(groesse) lt(120) fd(groesse) lt(120) fd(groesse) lt(120) # Ergänzt auf 360 Grad def zeichne_rekursiv(wie_oft_noch): if wie_oft_noch < 1: # Abbruch der Rekursion return fd(wie_oft_noch) lt(15) dreieck(wie_oft_noch) # Rekursionsaufruf mit verringerter Größe: zeichne_rekursiv(wie_oft_noch - 1) zeichne_rekursiv(50)

Das Programm erzeugt folgendes Bild:
rekursion 2

Rekursive Funktionen sind mächtige Werkzeuge und werden in der Informatik häufig verwendet. Ideal eigenen sich rekursive Funktionen auch zur Abarbeitung von rekursiven Datenstrukturen.
Rekursive Funktionen sind nicht auf grafische Anwendungen beschränkt es gibt zum Beispiel rekursive Suchverfahren.




Inhalte ab hier gehen über das Computing Modul hinaus

Textverarbeitung (Stringverarbeitung)

Erinnern wir und an das Beispiel des Durchlaufens einer Zeichenkette:
for char in "abcdef":     print(char)

Aber auch in anderen Fällen können Zeichenketten behandelt werden wie Listen:
>>> str_list = "abcdef" >>> str_list[3] 'd'

Ansonsten ist die Suche einer Zeichenkette innerhalb einer anderen eine der grundlegendsten Operationen.
Dazu kann "in" verwendet werden. dieser Operator arbeitet grundsätzlich "case-sensitive".
Zur Vermeidung, muss man die lower-Methode einsetzen.
Braucht man die Position des gefunden Strings, verwendet man die find-Methode.
str = "eins zwei drei" print("zwei" in str) # True print("zwEi" in str) # False print("zwEi".lower() in str) # True print(str.find("zwei")) # 5 print(str.find("zwEi")) # -1 print(str.lower().find("zwEi".lower())) # 5 print(str.lower()) # "eins zwei drei" print("zwEi".lower()) # "zwei"

Dateioperationen   +! erweiterter Inhalt

Lesen

Zeilenweise:
with open("filename") as fileobj: for line in fileobj: print(line)

Einzelne Zeichen:
with open("filename") as fileobj: for line in fileobj: for ch in line: print(ch)

Was ist, wenn es keine Zeilen gibt?:
with open(filename) as fileobj: while True: c = fileobj.read(1) if not c: print("End of file") break print("Read a character:", c)

pi_digits.txt

romeo_und_julia.txt

Wenden wir das nun an:
""" with open("romeo_und_julia.txt") as fileobj: for line in fileobj: #print(line) print(line, end="") """ fileobj = open("romeo_und_julia.txt") for line in fileobj: print(line.rstrip()) #print(line, end="") # alternativ fileobj.close()

Das führt zu einer sehr langen Ausgabe:
... Denn nie verdarben Liebende noch so Wie diese: Julia und ihr Romeo. (Alle ab.) Ende dieses Projekt Gutenberg Etextes Romeo und Julia, von William Shakespeare (Uebersetzt von August Wilhelm von Schlegel)

Jetzt wollen wir aber nur die gefundenen Zeilen anzeigen:
search = "gift" fileobj = open("romeo_und_julia.txt") for line in fileobj: if (search in line.lower()): print(line.rstrip()) fileobj.close()

Das klappt schon besser. Das läuft wesentlich schneller. Warum eigentlich?:
Voll Pflanzen giftger Art und diensam zum Genesen. Die kleine Blume hier beherbergt giftge Saefte Und sagt du "Ja", vergiftet dieser Laut ...
Die Bildschirmausgaben verbrauchen oft erheblich mehr Zeit ale alle anderen Berechungen und Aufgaben: Flaschenhals.

Jetzt wollen wir aber auch die Zeilennummmern:
search = "gift" # gift, tod, liebe, verona, nachtigall line_num = 1 num = 0 fileobj = open("romeo_und_julia.txt") for line in fileobj: if (search in line.lower()): print(line_num, line.rstrip()) num += 1 line_num += 1 print() print(num) # print("\n" + str(num)) # alternativ fileobj.close()

Das ist wesentlich Aussagekräftiger:
1730 Voll Pflanzen giftger Art und diensam zum Genesen. 1745 Die kleine Blume hier beherbergt giftge Saefte 2905 Und sagt du "Ja", vergiftet dieser Laut 3116 So hattest du kein Gift gemischt, kein Messer 3483 Ach, faendet Ihr nur jemand, der ein Gift 3825 Wie? Waer es Gift, das mir mit schlauer Kunst 3836 Des giftger Mund nie reine Luefte einhaucht, 4239 Beduerfte jemand Gift hier, des Verkauf 4481 In meines Trauten Hand?--Gift, seh ich, war 4486 Haengt noch ein wenig Gift daran und laesst mich 4708 Ihm Gift verkauft, womit er gehen wolle 11

Schreiben

Wir wollen nun in einer Log-Datei über alle Aufrufe Buch führen:
search = "liebe" # gift, tod, liebe, verona, nachtigall line_num = 1 num = 0 fileobj = open("romeo_und_julia.txt") fileobj_append = open("log.txt", "a") # "a" für append. Fehlt die Datei dann wird sie erzeugt. for line in fileobj: if (search in line.lower()): print(line_num, line.rstrip()) num += 1 line_num += 1 print() print(num) # print("\n" + str(num)) # alternativ fileobj_append.write(search + " " + str(num) + "\n") fileobj.close() fileobj_append.close()

In log.txt steht dann:
gift 11 tod 61 liebe 95 verona 11 nachtigall 2

Zuletzt möchte ich noch die Fundstellen hervorheben lassen:
search = "gift" # gift, tod, liebe, verona, nachtigall line_num = 1 num = 0 fileobj = open("romeo_und_julia.txt") for line in fileobj: pos = line.lower().find(search) if (pos > -1): print(line_num, line.rstrip()) print(" "*len(str(line_num)) + " " + " "*pos + "="*len(search)) num += 1 line_num += 1 print() print(num) # print("\n" + str(num)) # alternativ fileobj.close() """ markiert wird nur ein auftreten pro zeile. markieren aller auftreten wäre etwas komplizierter. """

Das erzeugt dann:
1730 Voll Pflanzen giftger Art und diensam zum Genesen. ==== 1745 Die kleine Blume hier beherbergt giftge Saefte ==== 2905 Und sagt du "Ja", vergiftet dieser Laut ==== ...

Schreiben einer Liste als csv-Datei   +! erweiterter Inhalt

Folgendes Programm schreibt den Inhalt der Liste in eine Datei:
fileobj = open("export_list.csv", "w") # "w" für write also Schreiben. # Eine eventuell vorhandene Datei wird überschrieben list_1 = [ [3,1,True,5.7,"Demo"], [9,1,False,15.27,"Test"], [1,1,True,2.2,"Xyz"], [4,1,True,4.8,"Muster"], [8,1,False,9.7,"Abc"] ] for record in list_1: separator = "" for element in record: fileobj.write(separator + str(element)) separator = ";" fileobj.write("\n") fileobj.close() print("Die Datei wurde exportiert.")

Obiges Programm schreibt folgende Datei:
3;1;True;5.7;Demo 9;1;False;15.27;Test 1;1;True;2.2;Xyz 4;1;True;4.8;Muster 8;1;False;9.7;Abc

Try-Except   +! erweiterter Inhalt

Das "Abfangen" von Ausnahmen (Exceptions) mittel try-except.

Erinnern wir uns an das vorige Beispiel.
Reduzieren wir das auf den reinen Lesevorgang.
from datetime import * fileobj_read = open("demo.txt") for line in fileobj_read: print(line.rstrip()) fileobj_read.close()

Dateioperationen (Lesen, Schreiben, Anfügen) können scheitern.
Beispiele?
Diese Ausnahmen kann man auf diese Weise abfangen:
try: fileobj_read = open("demo.txt") for line in fileobj_read: print(line.rstrip()) fileobj_read.close() except: print("Die Datei wurde nicht gefunden.") # Alternativ: Fortsetzung möglich?

Ergebnis:
Die Datei wurde nicht gefunden. >>>

Es geht auch folgendes:
try: fileobj_read = open("demo.txt") for line in fileobj_read: print(line.rstrip()) fileobj_read.close() except Exception as e: print(e)

Ergebnis:
[Errno 2] No such file or directory: 'demo.txt' >>>

Speichern einer Liste als JSON   +! erweiterter Inhalt

Speichern der Liste:
import json friends = ["Tina",["Peter",3],"Paul"] friends_json = json.dumps(friends) with open('data.txt', 'w') as outfile: json.dump(friends_json, outfile)

Laden der Liste:
import json with open('data.txt') as json_file: data_str = json.load(json_file) print(type(data_str)) data = json.loads(data_str) print(type(data)) print(data)

Erzeugte Ausgabe:
<class 'str'> <class 'list'> ['Tina', ['Peter', 3], 'Paul']

Datenbanken   +! erweiterter Inhalt

Datenbanken sind ein wichtiges Werkzeug um Daten in strukturierter Weise auf Dauer zu speichern, sie zu bearbeiten und darauf effizient zuzugreifen.
In folgendem Beispiel kommt eine SQLite Datenbank zum Einsatz.

"SQLite ist eine Bibliothek, die eine in sich geschlossene, serverlose, konfigurationsfreie, transaktionale SQL-Datenbank-Engine implementiert. Der Code für SQLite ist gemeinfrei und kann daher zu jedem gewerblichen oder privaten Zweck verwendet werden. SQLite ist die am häufigsten eingesetzte Datenbank der Welt, darunter mehrere hochkarätige Projekte."

Mit eventuellen kleinen Anpassungen funktionieren diese Programme aber auch mit anderen Datenbanken.

Die Daten einer SQLite Datenbank werden in einer ".db" Datei abgespeichert.

Das folgende Programm legt eine Tabelle an und entfernt vorher eventuell schon existierende Versionen. Falls die Datei employee.db nicht existiert wird sie automatisch angelegt.
import sqlite3 connection = sqlite3.connect("employee.db") cursor = connection.cursor() # Tabelle löschen: cursor.execute("DROP TABLE IF EXISTS tbl_employee;") sql_command = """ CREATE TABLE tbl_employee ( staff_number INTEGER PRIMARY KEY, firstname VARCHAR(20), lastname VARCHAR(30), gender CHAR(1), joining DATE, birth_date DATE);""" cursor.execute(sql_command) print("Die Tabelle wurde neu angelegt.")

Das folgende Programm zeigt, wie Datensätze in die Tabelle eingetragen werden.
import sqlite3 connection = sqlite3.connect("employee.db") cursor = connection.cursor() people = [ #firstname, lastname, gender, joining, birth_date ["Max","Muster","m","2016-04-07","2000-01-12"], ["Maria","Muster","f","2016-04-07","2001-11-02"], ["Tom","Taler","m","2017-03-23","1990-05-09"], ["Peter","Maier","m","2011-01-08","2001-01-05"], ["Karin","Müller","w","2017-02-17","2002-06-01"] ] for element in people: cursor.execute("""INSERT INTO tbl_employee (firstname, lastname, gender, joining, birth_date) VALUES ('""" + element[0] + "','" + element[1] + "','" + element[2] + "','" + element[3] + "','" + element[4] + "');") print("Die Sätze wurde eingefügt.") connection.commit() connection.close()

Alternativ dazu hier ein Programm zur manuellen Eingabe von Datensätzen.
Das wäre aber umständlich wenn es um mehr als einzelne Sätze geht.
import sqlite3 connection = sqlite3.connect("employee.db") # Felder: firstname lastname gender joining birth_date cursor = connection.cursor() while True: firstname = input("Bitte den Vornamen und 'Return' drücken (q=ende): ") if firstname == "q": break lastname = input("Bitte den Nachnamen und 'Return' drücken: ") gender = input("Bitte das Geschlecht (m oder f) und 'Return' drücken: ") joining = input("Bitte das Eintrittsdatum und 'Return' drücken (JJJJ-MM-TT): ") birth_date = input("Bitte das Geburtsdatum und 'Return' drücken (JJJJ-MM-TT): ") sql_command = "INSERT INTO tbl_employee (firstname, lastname, gender, joining, birth_date) VALUES ('"+firstname+"','"+lastname+"','"+gender+"','"+joining+"','"+birth_date+"');" cursor.execute(sql_command) print("Auf Wiedersehen") connection.commit() connection.close()

Die Ausgabe aller Datensätze kann durch folgendes Programm erzielt werden:
import sqlite3 connection = sqlite3.connect("employee.db") cursor = connection.cursor() print("----------------") cursor.execute("SELECT * FROM tbl_employee") result = cursor.fetchall() for record in result: print(record) print("----------------") connection.close()

Folgendes Programm löscht alle Datensätze aus der Tabelle:
import sqlite3 # Alle Datensätze löschen connection = sqlite3.connect("employee.db") cursor = connection.cursor() cursor.execute("delete FROM tbl_employee") connection.close() print("Alle Datensätze wurden gelöscht.")

Folgendes Programm importiert Datensätze aus der csv-Datei import.csv und schreibt sie in die Tabelle:
import csv import sqlite3 with open("import.csv", "r") as file: import_list = csv.reader(file, delimiter = ";") # Lesen der Daten von Datei connection = sqlite3.connect("employee.db") cursor = connection.cursor() for element in import_list: print(element) sql = """INSERT INTO tbl_employee (firstname, lastname, gender, joining, birth_date) VALUES ('""" + element[0] + "','" + element[1] + "','" + element[2] + "','" + element[3] + "','" + element[4] + "');" print(sql) cursor.execute(sql) # Einfügen von Satz in Datenbank print("Die Sätze wurde eingefügt.") connection.commit() connection.close()

Beispiel für eine dabei eingesetzte csv-Datei.
Peter;Berger;m;2017-04-01;2002-03-02 Lisa;Müller;w;2020-02-01;2001-09-17 Thomas;Bauer;m;2020-04-07;2005-04-11 Paula;Adler;w;2019-08-04;2001-02-19 Karl;Kummer;m;2018-10-30;1990-11-10 Berta;Auer;w;2017-12-31;2000-01-27 Horst;Maier;m;2019-06-17;2003-02-15

Beispiel für einen csv-Export aus der Datenbank:
import sqlite3 fileobj = open("export.csv", "w") connection = sqlite3.connect("employee.db") cursor = connection.cursor() cursor.execute("SELECT * FROM tbl_employee") result = cursor.fetchall() for record in result: fileobj.write(str(record[0])+";"+record[1]+";"+record[2]+";\ "+record[3]+";"+record[4]+";"+record[5]+"\n") fileobj.close() connection.close() print("Die Datei wurde exporti-+ert.")
Beachte, dass das "\"-Zeichen verwendet wurde um die Zeile umzubrechen.
Python liest dann automatisch in der nächsten Zeile weiter und der Umbruch hat für die logische Struktur des Programms keine Bedeutung.

Das ist ein Beispiel für die so erzeugte Datei export.csv:
1;Max;Muster;m;2016-04-07;2000-01-12 2;Maria;Muster;f;2016-04-07;2001-11-02 3;Tom;Taler;m;2017-03-23;1990-05-09 4;Peter;Maier;m;2011-01-08;2001-01-05 5;Karin;Müller;w;2017-02-17;2002-06-01 6;Peter;Berger;m;2017-04-01;2002-03-02 7;Lisa;Müller;w;2020-02-01;2001-09-17

Natürlich kann man auch alle Programmteile in eine Datei zusammenführen und hat dann bereits das Grundgerüst für eine vollständige Anwendung.

SQLite kann man auch mit Hilfe einer grafischen Oberfläche verwalten:
Ergänzen müsste man noch:
Die oben gezeigt sqlite-Datenbank ist eine tolle Möglichkeit für kleine Projekte oder um schnell loszustarten aber wenn sqlite an seine Grenzen stößt, sollte man auf eine echte Serverdatenbank umstellen. Unten wird gezeigt, wie man zu einer mySQL oder zu einer MariaDB Datenbank verbindet.
Passe die Verbindungsdaten entsprechend an: user, password, host, database).
Im Fall unten erfolgt die Verbindung zum sogenannten localhost (127.0.0.1). Das beudeutet die Datenbank läuft am selben Rechner wie Python. Das muss natürlich nicht so sein.
Damit das funktioniert, muss der verwendete Benutzer (in unserem Fall connnect_user) die Berechtigung haben, sich zu verbinden. Möchte man sich nicht vom selben Rechner (localhost) sondern von einem entfernten Rechner (remote) verbinden muss eine eigene zusätzliche Berechtigung bei diesem Benutzer vorhanden sein.
Achtung! Um wie unten gezeigt, das mysql-Modul zu importieren, musst du vorher das Modul installieren.

Öffne dazu eine Windows-Kommandozeile aber im Administratormodus:
Kommandozeile Admin

Gib dann im Fenster folgendes ein:
C:\Users\python_fan>pip install mysql

Fenster-Taste > cmd > rechte Maustaste auf dem Kommandozeilensymbol
              > Als Administrator ausführen
              > pip install mysql

Die Installation könnte scheitern, wenn du nicht im Administratormodus bist.

import mysql.connector connection = mysql.connector.connect(user='connnect_user', password='!dE3rZ?%', host='127.0.0.1', database='mydb') cursor = connection.cursor() # Tabelle löschen: cursor.execute("DROP TABLE IF EXISTS tbl_employee;") sql_command = """ CREATE TABLE tbl_employee ( staff_number INTEGER PRIMARY KEY, firstname VARCHAR(20), lastname VARCHAR(30), gender CHAR(1), joining DATE, birth_date DATE);""" cursor.execute(sql_command) print("Die Tabelle wurde neu angelegt.") connection.close()

Folgendes Beispiel zeigt die Verbindung zu einer Microsoft Access Datenbank. Die Datei mydb.accdb muss an dem angegebenen Pfad vorhanden sein.
import pyodbc conn = pyodbc.connect(r'Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=C:\python\db\mydb.accdb;') cursor = conn.cursor() cursor.execute('select * from tbl_employee') for row in cursor.fetchall(): print (row) conn.close()
Installiere vor der Ausführung wie oben gezeigt mittels "pip install pyodbc" das pyodbc-Modul.
Verwende wieder eine Windows-Kommandozeile im Administrator-Modus.

In der Access-Datenbank kannst du vorher mittels folgendem SQL-Skript die Tabelle anlegen und dann befüllen:
CREATE TABLE tbl_employee ( staff_number INTEGER PRIMARY KEY, firstname VARCHAR(20), lastname VARCHAR(30), gender CHAR(1), joining DATE, birth_date DATE);

Im obigen Fall wurde die Verbindung über eine ODBC (Open Database Connectivity) Schnittstelle hergestellt. Dafür müssen, zusätzlich zu Installation und Import des pyodcb Moduls, 2 Voraussetzungen erfüllt sein:

Webservices mit Python   +! erweiterter Inhalt

...

Klassen   +! erweiterter Inhalt

Im Gegenteil zu Java muss man in Python nicht immer objektorientiert programmieren. Aber natürlich unterstützt Python als moderne Sprache auch das objektorientierte Paradigma.

Begriffsklärung

Klassen sind Baupläne für Objekte. Mithilfe eines "Konstruktors" (eine spezielle Funktion, die auch Parameter haben kann) wird zur Laufzeit eine sogenannte Objektinstanz erstellt. Die Konstruktor-Funktion ist namensgleich mit der Klasse (siehe zum Beispiel die Funktion Person() im Beispiel unten). Von einer Klasse kann es zu einem Zeitpunkt viele Instanzen geben. Klassen sind maßgeblich zur Design-Zeit, Objekte zur Laufzeit.
Was ist ein Objekt?
Ein Objekt besteht aus Attributen und Methoden. Die Attribute beinhalten die Daten des Objekts. Die Methoden können lesend oder schreibend auf diese Daten zugreifen und diese direkt oder daraus abgeleitete Ergebnbisse zurückgeben.
Eine wichtige Eigenschaft von Objekten ist, dass ein Objekt einen Teil seines inneren Aufbaus und Zustands nach außen verbergen kann. Es kann sogenannte private Attribute oder Methoden geben, welche von außen (von außerhalb des Objekts) nicht oder nicht direkt zugänglich sind.
Praktisch ist bei Klassen, dass man meist die genaue Implementierung einer Methode nicht kennen muss. Es genügt, wenn man versteht, was die Methode macht.

Motivation

In Python stehen hinter allen Datentypen Klassen. Deshalb kann man auch bei der Liste "haustiere" mit dem Aufruf "haustiere.sort()" auf der Objektinstanz die dazugehörige Methode aufrufen. Diese Schreibweise ist uns also durch ihre Verwendung durchaus schon bekannt. Eine einfache Erklärung für objektorierte Programmierung ist also zu sagen, dass man mit Klassen selbstdefinierte Datentypen erstellen kann.

Sehen wir uns zum Beispiel folgendes Programm an:
import datetime class Person: def __init__(self, name, birth_year, birth_month, birth_day): self.name = name self.birth_year = birth_year self.birth_month = birth_month self.birth_day = birth_day def get_age(self): today = datetime.date.today() birthday = datetime.date(self.birth_year,self.birth_month,self.birth_day) current_birthday = datetime.date(today.year, birthday.month, birthday.day) if today < current_birthday: return today.year - birthday.year - 1 else: return today.year - birthday.year p1 = Person("John", 2000, 1, 1) print(p1.get_age())

Erklärung:
Die Definition einer Klasse wird mit dem "class"-Schlüsselwort eingeleitet. Die "__init__"-Methode dient der Initialisierung.
name, birth_year, birth_month, birth_day sind in dieser Klasse die Attribute. Sie enthalten die Daten des Objekts. get_age ist eine Methode des Objekts.

Achtung!:
Der Parameter "self" hat eine spezielle Bedeutung. Mit ihm kann man auf die aktuelle Objektinstanz zugreifen. Diesen Parameter muss jede Klassenemethode (also auch init) haben und per Konvention wird meist der Name "self" verwendet, das ist aber nicht verpflichtend.
In der init-Methode bezieht sich "self" also auf das neu erstellte Objekt. In anderen Klassenmethoden bezieht es sich auf die Instanz, deren Methode aufgerufen wurde.

In unserem Fall hat init aber noch weitere Parameter, nämlich Namen und Geburtsdaten. Mithilfe der "self"-Variablen werden die übergebenen Werte dem Objekt zugewiesen.
Die get_age-Methode verwendet diese Werte um das Alter der Person zu ermitteln.
Im Hauptprogramm wird schließlich mithilfe des Konstruktors "Person()" eine Objektinstanz (oder kurz ein Objekt) der Klasse erstellt. Bei Erstellung des Objekts wird automatisch die init-Methode aufgerufe und die Parameter des Konstruktors werden an sie übergeben. Danach wird die get_age-Methode aufgerufen um das Alter der Person zu ermitteln und auszugeben.

Abstrakte Datentypen   +! erweiterter Inhalt

Ein Abstrakter Datentyp ist ein Verbund von Daten zusammen mit der Definition aller zulässigen Operationen, die auf sie zugreifen. Es fällt auf, dass die Definition von Abstraktem Datentyp eine starke Verwandschaft zur objektorientierten Programmierung aufweist. Tatsächlich sind Abstrakte Datentypen eine starke Motivation zur Verwendung von Klassen und können damit sehr gut umgesetzt werden. Das ist aber nicht unbedingt so und Abstrakte Datentypen gibt es auch in der klassischen (nicht objekt-orientierten) Programmierung.
Als Beispiele sollen hier Stack und Queue vorgestellt werden.

Stack / Stapelspeicher

Ein Stack oder Stapelspeicher wird auch als LIFO (Last-In-First-Out) Datenstruktur bezeichnet. Das letzte eingetragene Element ist das erste ausgegebene.

Im folgenden Programm wird ein Stack verwendet, um einen Klammernausdruck zu analysieren. Wenn eine öffende Klammer erkannt wird, dann wird diese im Stack gespeichert. Wenn eine schließende Klammer erkannt wird, muss sich eine entsprechende öffnende ganz oben im Stack befinden.
Enthält der Ausdruck nur eine Art von Klammer, bräuchte man die Vorgangsweise mit dem Stack nicht unbedingt, sondern ein Zähler würde genügen, in dem festgehalten wird, wie viele Klammern geöffnet sind. Der hier gewählte Weg hat den Vorteil, dass das Verfahren erweiterbar ist auf kompliziertere Ausdrücke und verschiedene Klammernarten ("()","[]","{}").
import sys class Stack: def __init__(self): self.items = [] def isEmpty(self): return self.items == [] def push(self, item): self.items.append(item) def pop(self): return self.items.pop() def peek(self): return self.items[len(self.items)-1] def size(self): return len(self.items) stack = Stack() expression = input("Bitte gib einen Klammernausdruck ein (zb '(((())))()(())'): ") for ch in expression: if ch == "(": stack.push(ch) elif ch == ")": if stack.isEmpty(): print("Kein gültiger Klammernausdruck.") sys.exit() elif stack.pop() != "(": print("Kein gültiger Klammernausdruck.") sys.exit() if stack.size() == 0: print("Gültiger Klammernausdruck.") else: print("Kein gültiger Klammernausdruck.")

Queue / Warteschlange

Eine Queue oder Warteschlange wird auch als FIFO (First-In-First-Out) Datenstruktur bezeichnet. Das erste eingetragene Element ist das erste ausgegebene.

Das folgende kleine Programm simuliert einen typischen Anwendungsfall einer Queue: das Wartezimmer einer Arztpraxis. Jeder neu ankommende Patient wird in die Warteschlange eingetragen. Die Patienten werden in der Reihenfolge ihres Eintreffens behandelt.
class Queue: def __init__(self): self.items = [] def isEmpty(self): return self.items == [] def enqueue(self, item): self.items.insert(0,item) def dequeue(self): return self.items.pop() def size(self): return len(self.items) def show(self): print(self.items) def neuer_patient_trifft_ein(name): wartezimmer.enqueue(name) anzahl = wartezimmer.size() if anzahl > 10: nachricht = "Tut mir leid " nachricht += name nachricht += " die Wartezeit beträgt mindestens " nachricht += str(anzahl * 10) + " min." print(nachricht) def naechster_patient_ist_dran(): if wartezimmer.size() == 0: print("Das Wartezimmer ist leer.") else: print(wartezimmer.dequeue() + " bitte ins Behandlungszimmer eintreten.") wartezimmer = Queue() while True: print("1: neuer Patient eingetroffen 2: nächster Patient ist dran") print("3: Zeige Wartezimmer q: Ende") befehl = input("Bitte wähle eine Option: ") if befehl == "1": name = input("Name des eintreffenden Patienten?: ") neuer_patient_trifft_ein(name) elif befehl == "2": naechster_patient_ist_dran() elif befehl == "3": wartezimmer.show() elif befehl == "q": print("Danke, dass Du MediSoft Wartezimmer-Software verwendet hast.") break else: print("Bitte nur 1, 2, 3 oder 'q' eingeben.")

Fehlerarten

Lexikalische Fehler

Beispiele: Programmcode mit einem lexikalischen Fehler ist nicht lauffähig.

Syntaktische Fehler

So ein Fehler liegt vor, wenn zwar alle Wörter richtig geschrieben wurden, aber ein Fehler im Programmaufbau vorhanden ist. Beispiele:

Sprachvergleich

Syntaktische Fehler sind vergleichbar mit Grammatikfehlern. Alle Wörter sind zwar richtig geschrieben doch der Satzbau ist nicht richtig.
"Mach deinen Buch zu."
Dieser Fall kann durch eine nur wortbezogene Rechtschreibprüfung nicht gefunden werden aber durch eine grammatikalische Prüfung des Satzes Auch bei Programmen kann eine Syntaxprüfung durchgeführt werden.

Programmcode mit einem syntaktischen Fehler ist nicht lauffähig.

Semantische Fehler

Alle Wörter sind richtig geschrieben und der Programmaufbau ist korrekt. Ein Programmkonstrukt wurde aber falsch und nicht gemäß seiner tatsächlichen Bedeutung verwendet. Im Programmcode wird zum Beispiel auf falsche Variablen zugegriffen, es werden falsche Operationen verwendet, Übergabeparameter werden in der falschen Reihenfolge übergeben. Weitere mögliche Gründe sind:

Sprachvergleich

Wörter sind richtig geschrieben. Sätze sind richtig aufgebaut aber werden nicht in ihrer wirklichen Bedeutung verwendet. Der Satz ergibt keinen Sinn.
"Die Uhrzeit ist grün."
"Der Hammer isst Gras."
Semantische Fehler sind schwieriger zu finden als syntaktische Fehler. Ein Compiler oder Interpreter kann aber sehr wohl eine semantische Prüfung enthalten. Programmcode mit einem semantischen Fehler ist lauffähig. Das Programm verhält sich aber nicht wie gewünscht. Es treten Fehler auf. Eventuell terminiert das Programm ungewollt mit einer Fehlermeldung oder es kommt zu einem Programmabsturz. Eventuell liefert das Programm falsche, sinnlose Ergebnisse.

Logische Fehler

Ein Programm, das so einen Fehler enthält ist vom Aufbau korrekt. Auch der Programmablauf erfolgt ungestört und es treten keine Fehler auf. Einziges Problem bei logischen Fehlern ist, dass sie nicht die richtigen Ergebnisse liefern oder dass der Programmablauf anders ist als gewünscht. Die abweichenden Resultate sind aber nicht sinnlose Werte, wie bei semantischen Fehlern, sie liefern sinnvolle Ergebnisse aber nicht die gewünschten, weil der Programmierer eine falsche Formel verwendet hat oder diese falsch befüllt zum Beispiel, weil er sich bei der Rangfolge der Operatoren irrt.

Logische Fehler sind Irrtümer des Programmierers.
def mittelwert(a, b): return a + b / 2 # richtig wäre (a + b) / 2 print(mittelwert(2.0,4.0)) # gewünscht wäre: 3.0 ausgegeben wird: 4.0 print(mittelwert(1.0,4.0)) # gewünscht wäre: 2.5 ausgegeben wird: 3.0

Bei obigem Beispiel sollte der Mittelwert zweier Übergabeparameter berechnet werden, was auch die sinnvolle Benennung andeutet. Durch einen Fehler des Programmierers wird aber das falsche Ergebnis geliefert.

Sprachvergleich

Wörter sind richtig geschrieben. Sätze sind richtig aufgebaut und alle Begriffe werden in einem sinnvollen Zusammenhang verwendet aber nicht in dem gewünschten. In folgendem Fall sagt ein englischer Tourist:
"Auf dem Weg hierher habe ich eine Ambulanz gesehen"
und meint dabei einen Rettungswagen (englisch: ambulance), der Zuhörer denkt aber an eine Klinik für medizinische Notfälle. Logische Fehler können sehr subtil sein und sind dann noch schwieriger zu finden als semantische Fehler.

Programme mit logischen Fehlern sind lauffähig und sie erzeugen keinerlei Fehlermeldungen liefern sinnvolle Ergebnisse aber nicht die gewünschten.
In der folgenden Grafik werden alle Fehlerarten nochmals dargestellt.

Fehlerarten

Auswirkungen von Fehlern

Oben haben wir die Fehler streng aus Sicht der Programmierung klassifiziert. Jetzt kategorisieren wir sie nach ihren Auswirkungen:

Syntaxfehler

Diese verhindern die Codeausführung.
Egal ob in der Python-Shell oder im IDLE, bei dem Versuch ein Pythonprogramm mit Syntaxfehler zu starten öffnet sich ein Fenster mit einer entsprechenden Meldung und die beanstandete Stelle im Programm wird hervorgehoben.

Laufzeitfehler

Diese werden auch "Bugs" genannt so wie das Insekt. Sie treten während eines Programmlaufs auf. Laufzeitfehler werden oft aber nicht ausschließlich durch semantische Fehler verursacht. Laufzeitfehler können folgende unerwünschte Auswirkungen haben:

Ausnahmen (Exceptions)

Eine Ausnahme wird vom System zur Laufzeit gemeldet und sie kann durch einen Laufzeitfehler (=Bug) verursacht werden. Folgende Ausnahme wird durch eine Division durch 0 verursacht:
>>> Traceback (most recent call last): File "C:\Python34\error.py", line 10, in x = 1/0 ZeroDivisionError: division by zero >>>

Aber Achtung!
Eine Ausnahme kann auch durch eine sogenannte erwartbare Ausnahmesituation verursacht werden. Was ist das? Nehmen wir folgende Ausnahme als Beispiel. Sie wurde verursacht, weil eine Datei namens "workfile" aus irgendeinem Grund nicht geöffnet werden konnte:
>>> Traceback (most recent call last): File "C:/Python34/file_open.py", line 1, in f = open('workfile', 'r') FileNotFoundError: [Errno 2] No such file or directory: 'workfile' >>>

Das kann aber verschiedene Ursachen haben. Eine falsche Pfadangabe des Programmierers wäre ein Bug. Falls aber zum Beispiel jemand diese Datei unbeabsichtigt entfernt hat oder vielleicht von dem Speichermedium nicht gelesen werden kann, dann ist das kein Bug, sondern die oben erwähnte erwartbare Ausnahmesituation.

Erwartbare Ausnahmen kann man aber auch "abfangen". Dabei kann man eine Ausnahmebehandlung durchführen, zum Beispiel kann man den Benutzer darüber informieren, was nicht funktioniert hat und kann dann kontrolliert terminieren oder man fordert den Benutzer auf für Abhilfe zu sorgen und versucht dann nochmals die problematische Stelle auszuführen.

Fehlerhafte Resultate

Das Programm scheint zu funktionieren, liefert auch Resultate aber diese entsprechen nicht den Werten in der Spezifikation. Das könnte an einem logischen Fehler im Programm liegen.

Der Programmablauf erfolgt nicht wie gewünscht

Das Programm erzeugt keine Fehler und liefert keine falschen Ergebnisse aber das beobachtbare Programmverhalten weicht von den Vorgaben ab. Zum Beispiel erzeugt das Programm Ausgaben wo keine erfolgen sollen und wo sie erfolgen sollten unterbleiben sie.

Debugging

Eliza in Python Demo

Alle Programme als zip-Datei zip icon
Weitere Programmezip icon

Ressourcen

Beispiele und Lösungen

ecdl_computing_loesungen.zip

Freie Bücher

Think Python
Byte of Python

"Cheat Sheets":

Beginners Python Cheat Sheet
http://learnpython.org/

Links

CheckiO is expanding the world’s code literacy through game play:
https://checkio.org/

Beginner Python exercises:
http://www.practicepython.org/

thenewboston

CodingBat is a free site of live coding problems to build coding skill in Java and Python:
http://codingbat.com/python

BUILD AND DEPLOY IN SECONDS, Instant Serverless Computing Platform:
https://repl.it/

Codesters Python Coding Platform:
https://www.codesters.com/coding-platform/

Solo Learn, Everyone Can Code:
https://www.sololearn.com/Codes?ordering=Trending&language=py

Google's Python Class:
https://developers.google.com/edu/python/

Think Python:
http://greenteapress.com/wp/think-python/

Python-programming-exercises

Python Fiddle:
http://pythonfiddle.com/

PyFiddle is a free lightweight Python IDE to run and share Python scripts:
https://pyfiddle.io/

We host a growing number of Open Source, interactive textbooks you can use in a course.
Written by award winning authors. Used by some of the best schools:
http://interactivepython.org/

Put Interactive Python Anywhere on the Web:
https://trinket.io/python

fiddle