Objektorientiert Programmieren - info-bei

Werbung
Objektorientiert
Programmieren
mit Python 3
Lern- und Übungsheft
Informatik
Jahrgangsstufe 10
Stand vom 5.Oktober 2013
OStR Martin Frenkler
Arnold-Gymnasium Neustadt b.Coburg
Inhaltsverzeichnis
Modellieren und Programmieren .....................................................................................4
1 Programmieren ..............................................................................................................5
1.1 Erste Schritte .................................................................................................................................5
1.2 Die ersten Schritte mit Python .......................................................................................................6
1.2.1 Interpretieren.........................................................................................................................6
1.2.2 Kompilieren..........................................................................................................................6
1.2.3 Installieren............................................................................................................................6
Aufgaben zu Kapitel 1 .......................................................................................................................6
2 Programmieren mit Python ............................................................................................7
2.1 Arbeiten mit der Idle .....................................................................................................................7
2.2 Codierung und „böse“ Zeichen .....................................................................................................7
2.3 Die Ausgabe auf dem Bildschirm ..................................................................................................8
2.3.1 Die print()-Funktion..............................................................................................................8
2.3.2 Datentypen............................................................................................................................8
2.4 Typumwandlung ...........................................................................................................................9
2.5 Die erweiterte Bildschirmausgabe ...............................................................................................10
2.5.1 Noch einmal die print()-Funktion........................................................................................10
2.5.2 Escape- und Steuerzeichen..................................................................................................10
2.5.3 Tastatureingabe...................................................................................................................11
Aufgaben zu Kapitel 2 .....................................................................................................................11
3 Imperatives Programmieren ........................................................................................13
3.1 Die Programm-Datei ...................................................................................................................13
3.1.1 Dateinamen.py....................................................................................................................13
3.1.2 Shebang..............................................................................................................................13
3.1.3 Doppelklick unter Windows................................................................................................13
3.1.4 Der Kommentar..................................................................................................................14
3.2 Sequenz und Pseudo-Code ..........................................................................................................14
3.2.1 Sequentiell – imperativ – prozedural...................................................................................14
3.2.2 Die Anweisungs-Zeile.........................................................................................................15
Aufgaben zu Kapitel 3 .....................................................................................................................15
4 Die einfache Variable ..................................................................................................16
4.1 Die Variable in der Mathematik ..................................................................................................16
4.2 Die Variable in der Informatik ....................................................................................................16
4.2.1 Die Variable als Box...........................................................................................................16
4.2.2 Wertzuweisung...................................................................................................................17
4.2.3 Ringtausch..........................................................................................................................18
Aufgaben zu Kapitel 4 .....................................................................................................................18
5 Die Sammelvariable ....................................................................................................19
5.1 Warum noch ein Variablen-Typ? ................................................................................................19
5.2 Informatiker zählen anders ..........................................................................................................19
5.3 Array, ArrayList und Liste ..........................................................................................................20
5.3.1 Listentypen.........................................................................................................................20
5.3.2 Punkt-Notation....................................................................................................................20
5.3.3 Listenumwandlung..............................................................................................................21
5.4 Der Listendurchlauf ....................................................................................................................21
5.4.1 Anweisung und Anweisungs-Block....................................................................................21
5.4.2 Der Listendurchlauf mit for.................................................................................................22
5.4.3 Der Wiederholung mit fester Anzahl...................................................................................22
5.5 Listen von Listen .........................................................................................................................23
5.6 String und Liste ...........................................................................................................................23
5.6.1 String-Listen in Strings umwandeln....................................................................................23
5.6.2 Buchstaben als Ziffern verwenden......................................................................................23
5.7 Methoden eines Listenobjekts .....................................................................................................24
Aufgaben zu Kapitel 5 .....................................................................................................................25
6 Die Variable im Arbeitsspeicher .................................................................................27
6.1 Die einfache Variable ..................................................................................................................27
6.2 Die Sammelvariable ....................................................................................................................27
6.3 Unterschiedliches Verhalten der Variablentypen .........................................................................28
6.3.1 Call by Value......................................................................................................................28
6.3.2 Call by Reference................................................................................................................28
6.3.3 Deep Copy..........................................................................................................................28
6.4 Identität und Gleichheit von Werten ............................................................................................29
Aufgaben zu Kapitel 6 .....................................................................................................................29
7 Kontrollstrukturen .......................................................................................................30
7.1 Wahrheitswerte (boolsche Werte) ...............................................................................................30
7.2 Die Wiederholung .......................................................................................................................31
7.2.1 Die bedingte Wiederholung................................................................................................31
7.2.2 Wiederholung mit Zähler....................................................................................................32
7.2.3 Die Wiederholung mit fester Anzahl (einfaches for)...........................................................32
7.2.4 Inkrement und Dekrement...................................................................................................32
7.2.5 Erweiterte For-Schleife (foreach)........................................................................................33
7.2.6 Ganzzahl-Teilung und Modulo-Rechnung..........................................................................33
7.2.7 Multiplikation und Divison als Wiederholung....................................................................33
7.3 Die Verzweigung ........................................................................................................................34
7.3.1 Die einfache Verzweigung..................................................................................................34
7.3.2 Die Alternative....................................................................................................................34
7.3.3 Kombination von Wahrheitswerten.....................................................................................34
7.3.4 Mehrfachverzweigung und Kombination von Wahheitswerten...........................................35
7.4 Geschachtelte Kontrollstrukturen ................................................................................................36
Aufgaben zu Kapitel 7 .....................................................................................................................36
8 Einfache Algorithmen ..................................................................................................38
8.1 Algorithmus ................................................................................................................................38
8.2 Beispiele .....................................................................................................................................38
8.2.1 Der größte gemeinsame Teiler (euklidischer Algorithmus).................................................38
8.2.2 Bubble Sort.........................................................................................................................39
Aufgaben zu Kapitel 8 .....................................................................................................................39
9 Strukturiertes Programmieren ......................................................................................40
9.1 Blackbox-Prinzip ........................................................................................................................40
9.2 Funktion ohne Rückgabewert (Prozedur) ....................................................................................41
9.2.1 Die verdeckte Variable........................................................................................................41
9.3 Funktion mit Rückgabewert ........................................................................................................42
9.3.1 Das return-statement...........................................................................................................42
9.3.2 Vergleich zur Tabellenkalkulation......................................................................................42
9.3.3 Ausblick: Funktionen und Methoden..................................................................................43
9.3.4 Benannte Parameter............................................................................................................43
9.3.5 Überladene Parameter.........................................................................................................44
9.3.6 Listen als Parameter............................................................................................................44
9.4 Für Profis: Funktionen der Tabellenkalkulation ..........................................................................45
9.4.1 Einfache Verschlüsselung...................................................................................................45
9.4.2 Uhrzeit, Datum, Geld und Kommazahlen..........................................................................45
9.5 Für Profis: Ausnahmebehandlung ...............................................................................................46
Aufgaben zu Kapitel 9 .....................................................................................................................46
10 Modulares Programmieren ........................................................................................47
10.1 Modul – import ........................................................................................................................47
10.2 Lexikon wichtiger Python-Module ............................................................................................47
10.2.1 Zufallswerte......................................................................................................................47
10.2.2 Zugriff auf das Betriebssystem (platform, os)*.................................................................48
10.2.3 Zugriff auf das Laufzeitsystem (sys)*...............................................................................48
10.2.4 Das Zeitsystem (time)*.....................................................................................................48
Aufgaben zu Kapitel 10 ...................................................................................................................49
11 Klassen und ihre Objekte ...........................................................................................50
11.1 Programmier-Prinzipien ............................................................................................................50
11.1.1 Maschinenabhängig..........................................................................................................50
11.1.2 Problemorientiert..............................................................................................................50
11.1.3 Objektorientiert.................................................................................................................50
11.1.4 Vorteile der Objektorientierung........................................................................................51
11.2 Klassen und Objekte .................................................................................................................51
11.2.1 Reales Objekt und Programm-Objekt................................................................................51
11.2.2 Objekte handeln nach innen und nach außen.....................................................................51
11.3 Mit Objekten arbeiten: Liste und Turtle ....................................................................................52
11.3.1 Listen als Objekte.............................................................................................................52
11.3.2 Die Turtle..........................................................................................................................52
Aufgaben zu Kapitel 11 ...................................................................................................................55
12 Selbst erstellte Klassen und ihre Objekte ..................................................................56
12.1 Die einfache Klasse ...................................................................................................................56
12.1.1 Klasse, Konstruktor und Objekt........................................................................................56
12.1.2 Das Objekt........................................................................................................................57
12.1.3 Methoden und Funktionen................................................................................................57
12.1.4 Methoden geben Werte aus...............................................................................................58
12.1.5 Objekte initialisieren - Attribute........................................................................................58
12.1.6 Geheimnisprinzip..............................................................................................................59
12.1.7 Methoden, die Werte setzen..............................................................................................60
12.1.8 Klassen- und Objektdiagramm..........................................................................................61
12.1.9 Kommunikation von Objekten - Sequenzdiagramm..........................................................61
12.1.10 Zustand und Zustandsübergang.......................................................................................62
12.1.11 has_a-Beziehung.............................................................................................................63
12.2 Vererbung .................................................................................................................................64
12.2.1 Die Flexibilisierung bei der Programmierung...................................................................64
12.2.2 Typ-Prüfung......................................................................................................................64
12.2.3 Spezialisieren....................................................................................................................65
12.2.4 Generalisieren (is_a-Beziehung).......................................................................................66
12.2.5 Polymorphie......................................................................................................................67
12.2.6 Schnittstellen.....................................................................................................................68
Aufgaben zu Kapitel .......................................................................................................................69
13 Probleme objektorientiert lösen .................................................................................70
13.1 Projektplanung ..........................................................................................................................70
13.2 Mögliche Projekte .....................................................................................................................70
13.3 Die Schule, ihre Schüler und Lehrer ..........................................................................................71
Beispiele für eine Hausaufgabe .....................................................................................75
ooP mit Python
Modellieren und Programmieren
Modellieren und Programmieren
Modellierung reduziert Kompexität. Als
informatische Modellierung entwirft sie ein Bild
von der Wirklichkeit, das so auf die notwendigsten Daten reduziert ist, dass deren Bearbeitung automatisiert werden kann.
Ist das Modell gelungen – erfasst es den
richtigen Ausschnitt der Wirklichkeit und
lässt sich mit dem aus dem Modell heraus
entwickelten Informationssystem gut arbeiten, sind die Mühen der Entwicklung
schnell vergessen. Das Ergebnis wirkt wie
die Arbeit eines Künstlers, der scheinbar nur
den überflüssigen Stein wegzuschlagen hatte.
Die
Skulptur
steckt schon längst
im Stein!
Du musst nur
das Überflüssige
wegschlagen
Tatsächlich aber benötigen Künstler wie Informatiker nicht nur ein klares Modell. Sie müssen auch Techniken
beherrschen, um ihr Material angemessen bearbeiten zu können. Denn das Ergebnis des
Gestaltens soll ja auch dem Bild entsprechen, das zu Beginn im Kopf war.
Übertragen auf den Informatik-Unterricht der 10. Jahrgangsstufe benötigen die Schülerinnen und Schüler also nicht nur ein Wissen um die Grundideen der informatischen
Modellierung. Sie müssen auch die sprachlichen Mittel der Programmierung kennen, um
ein Modell zu formulieren, das sie dann in ein Softwareprojekt umsetzen.
Das vorliegende Lern- und Übungsheft bietet einen Lernweg, der sich an der Evolution
des imperativen Programmierens orientiert. Jeder Schritt, angefangen bei der einfachen
Zuweisung über die strukturierte Programmierung bis zum objektorientierten Programmieren, ist so angelegt, dass er nichts voraussetzt, was noch nicht gelernt ist. Dabei finden die Lernenden in jedem Abschnitt bereits bekannte Konzepte im neuen Kontext wieder vor und können so den erweiterten Bedeutungsumfang erfassen. Kontrollstrukturen
führen zu Algorithmen, die dann in Funktionen gekapselt werden und in der objektorientierten Programmierung als funktionale Methoden zur Verfügung stehen. Von hier aus ist
der Weg zum Entwurfsmuster Singleton in der Oberstufe nicht weit. Gleichzeitig wird
deutlich, dass Objektorientierung sich nicht in funktionalen Objekten erschöpft.
Die Programmiersprache Python wurde gewählt, weil sie bei der Codierung viele Fallstricke aus dem Weg räumt, was gerade AnfängerN entgegen kommt. Das Konzept des
Wortschatzes zeigt, dass bestimmte Sprachelemente stets im Kopf und damit griffbereit
sein sollten. Der Rückblick auf die Arbeit mit der Tabellenkalkulation ermöglicht das
Einbinden älteren Wissens und der immer wieder angesetzte Seitenblick nach Java macht
deutlich, dass nicht drill and practice einer bestimmten Programmiersprache im Vordergrund stehen, sondern die Grundkonzepte des Modellierens und Programmierens.
4
ooP mit Python
1
Programmieren
1.1
Erste Schritte
Programmieren
Der älteste kommerziell eingesetzte Computer steht heute im Deutschen Museum in
München. Er wurde von Konrad Zuse während der letzten Jahre des II.Weltkriegs als
mechanischer Rechner für den Flugzeugbau
in Berlin gebaut. Nach dem Krieg wurde der
Rechner zunächst von der ETH Zürich
genutzt. Für Zuses Maschine gab es eine
eigene Programmiersprache, den Plankalkül.
Zuse-Rechner Z4 im Deutschen Museum
ENIAC, der erste US-amerikanische elektronische Computer musste mit Hilfe von
Steckverbindungen programmiert werden.
Was hier die beiden Operator nach Plan
organisieren, leistet heute das Betriebssystem (englisch: Operating System)
Später wurden die Steckverbindungen durch
Lochkarten ersetzt und durch Programme,
die tatsächlich nur aus Nullen und Einsen
bestanden.
Eine erste Vereinfachung kam mit der
Assembler-Programmierung. Jede Maschine
besitzt einen bestimmten Befehlssatz, auf
den mit symbolischen Begriffen zugegriffen
werden kann.
Eniac im Einsatz der US-Army
Die Maus wird dann etwa mit den folgenden
Befehlen angeschaltet:
mov ax, 01h
int 33h
Dass wir heute Programme in Klartext entwickeln können, der dann von einem anderen Programm in Maschinencode übersetzt
wird, haben wir der Computerpionierin
Grace Hopper zu verdanken, die im Jahr
1952 den ersten Compiler schrieb.
5
Grace Hopper
am Univac - einem Röhren-Computer
ooP mit Python
Programmieren
1.2
Die ersten Schritte mit Python
1.2.1
Interpretieren
Python ist eine sehr einfach zu erlernende objektorientierte Programmiersprache. Sie
kann auf allen Betriebssystemen (wie Windows, Linux, Mac) eingesetzt werden. Programme in Python werden lesbar geschrieben und abgespeichert. Auf jedem Rechner, auf
dem Python-Programme laufen sollen, muss die Programmierumgebung Python installiert sein. Phython übersetzt die Programme während sie ablaufen in Maschinensprache,
das heißt das Laufzeitsystem Python interpretiert das Programm. Phyton zählt deshalb zu
den interpretierenden Scriptsprachen. Die Dateiendung .py für Python-Programme weist
Windows daraufhin, dass es die Python-Umgebung einsetzen soll, um diese Datei zu
lesen.
1.2.2
Kompilieren
Programme dagegen, die in C oder C++ geschrieben wurde, müssen vor ihrem Einsatz
für das jeweilige Betriebssystem kompiliert werden. Die Dateiendung .exe weist Windows darauf hin, dass das Programm direkt ausgeführt werden kann.
1.2.3
Installieren
Um mit Python arbeiten zu können muss das Laufzeitsystem installiert werden.
Lexikon: Python installieren
Installion unter Windows
Installationsdatei laden von python.org/download/
x86 oder x68-64 MSI Installer
Ein Doppelklick reicht zum installieren
Installation unter Linux und auf dem Mac
Unter Linuxsysteme wie auf dem Mac wird Python
mit dem jeweiligen Paketmanager installiert
Aufruf von Python Idle3
alle Aufgaben können ab jetzt auf der
Eingabezeile der Pythonkonsole ausgeführt werden
Aufgaben zu Kapitel 1
1
Die ersten Schritte
1) Installiere Python auf deinem Rechner
2) Suche im Internet nach Python-Tutorials
6
Python-Versionen
Python 2.x und Python 3.x
Versionen sind nicht kompatibel.
Wir verwenden Python 3.x, weil
es besser strukturiert ist, Python
2.x läuft auf vielen WebServern,
weil es dazu noch mehr Module
gibt.
ooP mit Python
Programmieren mit Python
2
Programmieren mit Python
2.1
Arbeiten mit der Idle
Programme werden
mit einem Texteditor
geschrieben. Textverarbeitungsprogramme
sind dafür nicht geeignet. Eine Programmierumgebung
wie
etwa Eclipse ist für
Anfänger wieder zu
schwer zu bedienen.
Python liefert statt
dessen einen eigenen
einfachen Editor mit, die Idle. Er beherrscht Syntax-Highlighting, hebt also die verschiedenen Sprachelemente mit unterschiedlichen Farben hervor.
von der Idle-Konsole zum Programmfenster
Wir können den Idle-Editor als Konsole einsetzen, also im interaktiven Modus verwenden. Dann wird jeder eingegebene Befehl sofort ausgeführt (oder bei Programm-Fehlern
mit einer Fehlemeldung verweigert).
Programme können aber auch als Dateien geschrieben und gespeichert werden. Dazu
muss aus der Idle-Konsole heraus ein neues Fenster geöffnet werden. Diese Programmdateien können mit dem Aufruf RunModule bzw. über die Taste F5 getestet werden.
2.2
Codierung und „böse“ Zeichen
Die Urahnen unserer heutigen Computer entstanden in den USA. Sie kannten nur den
amerikanischen Zeichensatz (ASCII-Code), zu dem die europäischen Sonderzeichen wie
ä, ö, ü, ß nicht gehören. Das Leerzeichen wurde als Befehlstrenner verwendet. Auch
wenn die meisten Betriebsysteme mit Umlauten und Leerzeichen in Dateinamen umgehen können, führt deren Verwendung immer wieder zu Fehlern, zum Beispiel beim
Datentausch zwischen den Systemen, etwa über das Internet. Für den ProgrammCode
und für Dateinamen sind Sonderzeichen deshalb tabu. Leerzeichen im Programmtext
werden wie ehedem einzig und allein als Befehlstrenner eingesetzt.
Python lässt in Texten (Strings) auch europäische Umlaute zu, sowie die Schriftzeichen
anderer Sprachen. Diese UTF-Codierung muss aber der Programmier-Umgebung im
Coding-Hinweis mitgeteilt werden. Er steht im Programm vor allen anderen Befehlen.
Lexikon: Codierung
# -*- coding: utf-8 -*-
Coding: Hier gilt die UTF-8-Kodierung
7
ooP mit Python
Programmieren mit Python
2.3
Die Ausgabe auf dem Bildschirm
2.3.1
Die print()-Funktion
Funktionen kennen wir bereits aus der Tabellenkalkulation. Sie werden mit ihrem Funktionsnamen aufgerufen. Die Parameterliste kann leer sein bzw. mit einem oder oder
mehreren Parameterwerten (Argumente) belegt sein. Funktionen geben immer einen Wert
aus.
Der Name der print()-Funktion verrät als sprechender Name, dass sie zum Schreiben da
ist. Konkret gibt sie den zu schreibenden Text auf den Text-Bildschirm aus. Unter Windows ist das die Eingabeaufforderung, unter Linux heißt das Konsole.
Die print()-Funktion erzeugt in der Standardversion immer einen Zeilenumbruch.
Wortschatz: Die print()-Funktion
print()
print('Hallo Welt')
print(1)
2.3.2
leere print()-Funktion
print()-Funktion mit dem Text-Argument 'Hallo Welt'
print()-Funktion mit der Zahl 1 als Argument
Datentypen
Texttypen wie Texte (String) und Zeichen (Character) werden immer zwischen Hochkomma gesetzt. Zahlen, wie die ganzen Zahlen (Integer) und die Kommazahlen (Float)
bleiben unmarkiert.
Datentypen haben unterschiedliche Eigenschaften und Fähigkeiten: So wird der +Operator (sprich 'Plus-Operator') von Text- und Zahlentypen unterschiedlich verwendet:
Rechnen können nur die Zahlen-Datentypen. Bei Texttypen bewirkt der +Operator, dass
die beiden Texte zusammengefügt werden. Vorsicht: Dabei entstehen neue Textobjekte,
die alten Texte bleiben erhalten und müllen den Arbeitsspeicher zu.
Wortschatz: Text-Typen
“Hallo Welt“, 'Hallo Welt'
“Hallo 'Welt'“, 'Hallo “Welt“'
print(“Hallo“ + “Welt“)
print('Hallo'+
'Halloechen!')
'H', “H“
'1', “1“
print(“1“+'1')
String (einfacher Text)
wird mit einfachen Hochkommata oder Anführungszeichen
markiert. Um innerhalb eines Textes einfache Hochkommata
verwenden zu können, muss der ganze Text in Anführungszeichen stehen und umgekehrt
Texte können zusammengefügt werden. Dazu dient der
+Operator
Der Textteil einer print()-Funktion kann auch auf mehrere
Zeilen verteilt werden. Die Ausgabe geschieht trotzdem in
einer Zeile.
Character oder Char (Buchstabe)
einzelne Buchstaben verhalten sich wie Text. Sie können aber
auch in eine Zahl umgewandelt werden.
Auch Zahlen können als Buchstaben geschieben werden, dann
heißen sie Ziffern. Ziffern werden wie Texte zusammengefügt
und nicht berechnet
8
ooP mit Python
Programmieren mit Python
Wortschatz: Zahlen
Integer (ganze Zahlen)
Zahlen brauchen keine Hochkommata oder Anführungszeichen – mit ihnen kann man in Python unmittelbar rechnen
print(1)
print(1+1)
Float (Kommazahlen)
Statt des Komma wird der amerikanische Punkt gesetzt
Kommazahlen können aus ganzen Zahlen erzeugt werden
print(72.0)
print(3/2)
Vorsicht: Die Nachkommastellen bei Floats werden ungenau berechnet, deshalb kann es beim Rechnen mit
Floats zu seltsamen Ergebnissen kommen: 2.15+2.15+2.15=6.449999999999999
Wortschatz: Rechenoperatoren
+ - / *
Potenz: **
Operatoren der Grundrechenarten
Die Potenz wird als doppelte Mutliplikation dargestellt
round(10.6)
#
Ergebnis: 11
round(10.5)
#
Ergebnis: 10
Mathematische Funktionen
round(vorkomma.nachkomma)
- rundet kaufmännisch ab- bzw. auf
round(10.1234,2)
#
Ergebnis: 10.12
- kürzt die Nachkommastellen
Das erste Argument gibt den FloatWert.
Das zweite Argument nach dem Komma bestimmt die die
Zahl der Nachkommastellen
abs(-4)
abs(zahl) erzeugt den absoluten Betrags
2.4
Typumwandlung
Die verschiedenen Datentypen können mit einfachen Funktionen ineinander umgewandelt werden. Als sprechende Funktionen erzeugen die Umwandlungsfunktionen den Wert
für den ihr Name steht. Auf der Konsole können sie auch ohne die print()-Funktion eingesetzt werden.
Wortschatz: Typumwandlung
ord()
print(ord('H'))
Mit Hilfe der ord()-Funktion können Chars in ganze Zahlen
(Integer) umgewandelt werden: ord('H') erzeugt 72
chr()
print(chr(72)+chr(72))
Mit Hilfe der chr()-Funktion werden ganze Zahlen (Integer)
in Zeichen (Character) umgewandelt: chr(72) erzeugt 'H'
str()
print(str(72.0)+str(72.0))
Mit Hilfe der str()-Funktion können beliebige Werte in Text
(String) umgewandelt werden: str(72.0) erzeugt '72.0'
int()
print(int(72.6))
Mit Hilfe der int()-Funktion werden Kommazahlen (Float) in
ganze Zahlen (Integer) umgewandelt. Dabei werden die
Kommawerte abgeschnitten: int(72.6) erzeugt 72
float()
print(float(72))
Mit Hilfe der float()-Funktion werden ganze Zahlen (Integer)
in Kommazahlen (Float) umgewandelt: float(72) erzeugt 72.0
9
ooP mit Python
Programmieren mit Python
2.5
Die erweiterte Bildschirmausgabe
2.5.1
Noch einmal die print()-Funktion
Die print()-Funktion erzeugt standardmäßig eine Bildschirm-Ausgabe und einen darauf
folgenden Zeilenumbruch. Sie kann jedoch sehr flexibel eingesetzt und erweitert werden.
Wortschatz: Die erweiterte print()-Funktion
Standard
Die leere Funktion gibt nur einen Zeilenumbruch aus
Das Argument der Funktion (der Parameterwert) wird auf
der Konsole ausgegeben, dann folgt der Zeilenumbruch
print()
print(1) / print('Text')
Es können auch mehrere Argumente durch Komma getrennt
übergeben werden. Sie werden dann durch Leerzeichen
getrennt ausgegeben. Diese Argumente können auch zu
unterschiedlichen Datentypen gehören.
print("Text"," 'mein' Text",1)
Das Separator-Argument hebt die Standard-Trennung auf.
Statt durch das Leerzeichens werden die Argumente durch
das dem sep-Parameter zugewiesene Zeichen getrennt.
print(1,2,3, sep=“-“)
Das End-Argument ersetzt den Zeilenumbruch, der
standardmäßig vorgesehen ist. Nach der Ausführung der
print()-Funktion wird die Zeile mit den Zeichen beendet, das
dem end-Parameter zugewiesen wurde. Das kann z.B. ein
Leerzeichen ' '' sein oder auch das leere Zeichen '' .
print(''Wert'', end=“ENDE“)
print(''Wert'', end=“ “)
print(''Wert'', end=““)
print(1,2,3, sep=“-“, end=“ENDE“)
2.5.2
Kombination: alle drei Parametertypen lassen sich beliebig
kombinieren
Escape- und Steuerzeichen
Die Textverarbeitung kennt das Konzept der nicht-druckbare Steuerzeichen, wie
TABULATOR oder ENTER. Solche Steuerzeichen gibt es auch in Python. Normale Zeichen werden mit dem Backslash als Ausnahmezeichen (Escape-Zeichen) markiert. Sie
zeigen dann einen anderen Text an.
Lexikon: Escape- und Steuerzeichen
Zeichen und Beispiel
Bedeutung
Ausgabe
\
Der Backslash (escape-Zeichen) markiert einige Zeichen zu
Steuerzeichen um
\n
print('Ein\nUmbruch')
Zeilenumbruch im Text
\t
print('ich\tund\tdu)
erzeugt einen Tabulator
\' bzw. \“
print(“Ein \“Text\“ - “)
erzeugt ein einfaches bzw. eine
doppeltes Hochkomma
Ein “Text“ -
\\
print('/\\')
gibt dem Backslash seine ursprüngliche Bedeutung zurück.
/\
Ein
Umbruch
Ich
10
und
du
ooP mit Python
2.5.3
Programmieren mit Python
Tastatureingabe
Interaktive Programme erwarten immer wieder Eingaben über die Tastatur. Dieser InputBefehl ist in den verschiedenen Programmiersprachen unterschiedlich umgesetzt, wir
sagen: implementiert. In Python übernimmt diese Aufgabe die input()-Funktion.
Wortschatz: Tastatureingabe
Die input()-Funktion
Der Input-Befehl bzw. die input()-Funktion
wartet drauf, dass während des Programmablaufes ein Wert über die Konsole eingegeben
wird. Dieser Wert wird vom Programm immer
als Text gelesen.
print(input('gib einen Wert ein: '))
print(int(input('Ganzzahl: '))+2)
print(float(input('Kommazahl: '))+2)
print(int(float((input('Kommazahl: ')))+2))
Zahlen
Soll eine Zahl eingegeben werden, muss die
eingegebene Zahl mit der int()- oder dem float()Funktion in eine Zahl umgewandelt werden
Aufgaben zu Kapitel 2
1
Bildschirmausgabe
1) Schreibe mit Hilfe mehrerer print()-Funktionen deine vollständige Adresse.
2) Notiere für den Bildschirm deine Adresse und deine Klasse.
Verwende dazu nur eine einzige print()-Funktion.
2
Datentypen
1) Printe auf der Idle-Konsole dein Alter in Jahren, Monaten und Tagen. Kläre, welche Datentypen du dafür am sinnvollsten einsetzt.
2) Rechne dein Alter auf der Idle-Konsole in Tage um. Addiere und multipliziere dabei geschickt
und vergiss die Schaltjahre nicht! Kläre, welche Datentypen du hier einsetzen musst.
3) Berechne den Notendurchschnitt einer Ex, in der 4 mal die 1, 6 mal die 2, 8 mal die 3, 4 mal
die 4, 2 mal die 5 und 1 mal die 6 vorgekommen sind. Setze dabei geschickt Klammern ein!
3
Typumwandlung
1) Finde mit Hilfe der ord()-Funktion heraus, welchen Zahlen die Klein- und Großbuchstaben
des Alphabets zugeordnet sind. Überprüfe auf die gleiche Weise alle Ziffern. Suche z.B. in
Wikipedia die ASCII-Tabelle und erkläre diese Ergebnisse
2) Teste int(3/2) und erkläre mit eigenen Worten, was bei der Verwendung int()-Funktion mit
dem Bruchwert einer Kommazahl geschieht.
3) Teste die chr()-Funktion mit einer beliebigen Kommazahl und notiere die Ausgabe. Kläre, was
sie bedeuten könnte.
4) Teste die folgende Funktion und erkläre ihr Ergebnis: chr(int(ord('z'))+4
11
ooP mit Python
4
Programmieren mit Python
Die Zahl 42
In seinem ScienceFiction-Roman „Per Anhalter ins All“ erzählt der Autor Duglas
Adams, dass die Menschen oder wie man immer auch diese Wesen nennen soll, 'den
Sinn von allem und überhaupt' herausfinden wollten. Dazu wurde 'Deep Thought'
gebaut, der größte Computer aller Zeiten. Nach etlichen Jahrmillionen kam er zu
einem die Auftraggeber höchst enttäuschenden Ergebnis. Die Antwort auf die Frage
nach 'dem Sinn von allem und überhaupt' sei 42! - Die Frage, so Deep Thought, war
leider zu ungenau gestellt.
Prüfe mit Hilfe der ord()-Funktion, welchen Gag der Autor Douglas Adams mit der Zahl 42
erzeugt hat – denke dabei auch an deine Kenntnisse über Datenbankabfragen mit SQL.
5
Die erweiterte Bildschirmausgabe
1) Schreibe mit sechs print()-Funktionen das „Haus des Nikolaus“ auf die Konsole. Nutze dabei die geeigneten Escape- und Steuerzeichen.
2) Erzeuge mit einer einzigen print()-Funktion deinen Stundenplan. Verwende
dazu auch den Tabulator. Als kleine Hilfestellung: In der Idle kann die Zeile
an einem Komma umgebrochen werden!
/\
/ \
---|\/|
|/\|
----
3) Schreibe den folgenden Text in eine print()-Funktion.
'An einem lauen Sommerabend fuhr ein verwegener Bursche mit seinem feuerroten
Rennwagen behäbig auf der ruhigen Landstraße auf die rotglänzend untergehende
Sonne zu.'
Brich dabei den Text durch an geeigneten Stellen innerhalb der print()-Funktion um. Verwende dazu einmal den +Operator und einmal die Trennung mit Komma.
6
Tastatureingabe
1) Schreibe die input()-Anweisung aus dem Wortschatz Tastatureingabe (Kapitel 2.5.3) auf die
Konsole und übergib ihr einen beliebigen Wert. – Erkläre das Ergebnis mit deinem Wissen
über Funktionen aus der 9.Klasse.
2) Teste die Zahlen-Eingaben aus dem Wortschatz Tastatureingabe und notiere im Heft, wie die
Funktionen abgearbeitet werden.
3) Schreibe eine print()-Funktion mit drei input()-Funktionen als Parameter. Sie sollen nach dem
Vornamen, dem Nachnamen und nach der Klasse fragen.
4) Ersetze im folgenden Text die Adjektive durch input()-Funktionen mit jeweils einer geeigneten
Aufforderung zur Texteingabe und führe das Programm aus:
'An einem lauen Sommerabend fuhr ein verwegener Bursche mit seinem feuerroten
Rennwagen behäbig auf der ruhigen Landstraße auf die rotglänzend untergehende
Sonne zu.'
5) Schreibe eine Funktion, in der der Notendurchschnitt einer Arbeit mit beliebig vielen Schülern
berechnet werden kann. Beachte: input() liefert Strings → Umwandlungsfunktion nutzen!
12
ooP mit Python
Imperatives Programmieren
3
Imperatives Programmieren
3.1
Die Programm-Datei
3.1.1
Dateinamen.py
Windows erkennt an der Datei-Endung, mit welchem Programm eine bestimmte Datei
geöffnet werden soll (z.B: .doc → MS WORD). Die Datei-Endung für Python ist py.
Diese Endung signalisert auch dem Idle-Editor, dass er Syntax-Highlighting für Python
verwenden soll.
Dateien sollten immer einen sprechenden Namen bekommen, der verrät, was das Programm tut. Leerzeichen und Sonderzeichen sind dabei zu vermeiden, schließlich ist ja
nicht immer klar, unter welchen Betriebssystemen die Datei eingesetzt werden kann.
Längere Dateinamen können aus mehreren Wörtern zusammengesetzt sein. Dann werden
die Wortteile durch die sogenannte CameCaseSchreibweise unterschieden.
Lexikon: camelCase und .py – die Konvention für Dateinamen
printTest.py
3.1.2
sprechender Namen in camelCaseSchreibweise
Die Dateiendung für Python-Programme ist .py
Shebang
Unter Linux muss eine Scriptdatei in der ersten Programmzeile selbst mitteilen, welche
Konsole für die Bearbeitung des Programmes zuständig ist. Nach dem Rautenzeichen #
(she für sharp) und dem Ausrufezeichen ! (bang), daher der Name Shebang, folgt der
Pfad zum Programm. Im Allgemeinen beginnen Python-Programme deshalb immer mit
dem Shebang. Windows ignoriert ihn. Deshalb können Pythonprogramme unverändert
unter Linux und unter Windows zum Einsatz kommen.
Lexikon: Shebang
#! /usr/bin/env python
3.1.3
Shebang am Anfang eines Programm-Textes
Doppelklick unter Windows
Unter Windows können Python-Programme mit Doppelklick geöffnet werden, dann läuft
das Programm in der Windows-Eingabeaufforderung. Textorientierte Programme schließen das Konsolenfenster aber, sobald das Programm beendet ist und die Ausgabe der
Ergebnisse verschwindet. Das geschieht nicht, wenn wir den leeren input()-Befehl als
Abschluss verwenden.
Lexikon: input()-Abschluss
input()
Hält nach Ablauf des Programms das Fenster der
Eingabeaufforderung offen
13
ooP mit Python
3.1.4
Imperatives Programmieren
Der Kommentar
Kurze Programme können mit einem Blick erfasst werden. Aber schon bei einfachsten
Programmen kommen schnell ein paar hundert Zeilen zusammen, die auf mehrere DINA 4 Seiten passen. Wer diese Programme auch später noch verstehen will, benötigt einen
geeigneten Kommentar, der die wichtigen Elemente erklärt.
Die Technik des Kommentars kann auch beim Testen von Programmen verwendet werden. Teile des Programm-Codes werden auskommentiert und dann beim Programm-Test
übersprungen. Die Idle bietet über das Menu sogar die Möglichkeit, gleich ganze Bereiche auszukommentieren: Format → Comment Out Region.
Wortschatz: Der Kommentar
# Hier folgt der Test
print('Das ist nur eine Testausgabe')
Der Kommentar wird durch das
Rautenzeichen erzeugt
### Hier folgt der Test
##print('Das ist nur eine Testausgabe')
Comment Out / Uncomment
Der ausgewählte Bereich wird mit zwei
zusätzlichen Rautenzeichen versehen.
3.2
Sequenz und Pseudo-Code
3.2.1
Sequentiell – imperativ – prozedural
Beispiel:
Sequenz
Sequenz in Java
System.out.println('erste Zeile');
System.out.println('zweite Zeile');
System.out.println(round(10.2345, 2);
System.out.println(abs(-10));
Sequenz in Python
print('erste Zeile')
print('zweite Zeile')
print(round(10.2345, 2)
print(abs(-10))
Eine Abfolge mehrerer Anweisungen in einem Programm nennen wir Sequenz.
Wir können diese Abfolge als Sequenzdiagramm schreiben. Dazu verwenden wir
Pseudo-Code (scheinbarer Code), also vereinfachtem Klartext, den man in jede Programmiersprache übersetzen kann.
Beispiel:
Pseudo-Code
Sequenz in Pseudo-Code
Programmtext
Bildschirmausgabe: '1+1= '
print('1+1= ')
Berechne und gib auf dem Bildschirm aus
print(1+1)
Das Sequenzdiagramm macht deutlich, dass bei diesem Programm ein Befehl auf den
anderen folgt. Diese Sequenz (Folge) von Befehlen nennt man vom Lateinischen her
imperativ (befehlsorientiert) oder prozedural (fortschreitend).
14
ooP mit Python
3.2.2
Imperatives Programmieren
Die Anweisungs-Zeile
Die Sequenz wird immer als Folge von Programmzeilen geschrieben. Jede Zeile enthält
eine Anweisung oder eine oder mehrere ineinander geschachtelter Funktionen. Jede in
sich geschlossene Anweisung gehört in eine Zeile. In vielen Programmiersprachen muss
jede vollständige Anweisung zusätzlich mit einem Semikolon ';' abgeschlossen werden.
Das ist auch in Python möglich. Der Programm-Code müsste dann nicht für jede Anweisung umgebrochen werden. Das erschwert jedoch das Lesen von Programmen und gilt
deshalb als schlechter Programmierstil.
Beispiel:
Anweisung in Java
System.out.println('Text'); System.out.println('Noch ein Text');
Aufgaben zu Kapitel 3
1
Python-Idle-Editor
1) Übernimm die print()-Funktionen aus dem Wortschatz Text-Typen von Kapitel 2 in eine Programmdatei. Speichere sie unter dem Namen oopmp_3.py und führe das Programm mit
F5 aus. Rufe das Programm dann unter Windows mit Doppelklick auf – beschreibe, das Problem, das dabei auftaucht.
2) Ergänze die Datei oopmp_3.py um die Zusatzinformationen, die im Wortschatz jeweils in
der rechten Spalte stehen. Kommentiere die Zusatzinformationen aus.
3) Schreibe den folgenden Text in eine print()-Funktion.
'An einem lauen Sommerabend fuhr ein verwegener Bursche mit seinem feuerroten
Rennwagen behäbig auf der ruhigen Landstraße auf die rotglänzend untergehende
Sonne zu.'
4) Ersetze die Adjektive durch geeignete input()-Funktionen!
2
Shebang, Coding und input()-Abschluss
1) Ergänze das Programm um Shebang und Coding und um den input()-Abschluss. Rufe das
Programm noch einmal mit F5 und unter Windows mit Doppelklick auf.
2) Sammle mit Hilfe der Sonderzeichentabelle von Windows oder OpenOffice verschiedene
Sonderzeichen, setze sie in eine print()-Funktion und lasse sie auf dem Bildschirm ausgeben.
3) Lasse die print()-Funktion deinen Namen mit griechischen Buchstaben schreiben. Das Alphabet dazu findest du auf der Seite info-bei-frenkler.de.
3
Sequenz und Pseudo-Code
1) Erläutere den Zusammenhang zwischen Sequenzdiagramm und dem Programmtext
2) Schreibe den Pseudo-Code für ein Programm, das nacheinander nach deinem Vor- und
Nachnamen und nach deiner Klasse fragt und das diese drei Werte nacheinander auf dem
Bildschirm ausgibt. Wandle es für in ein Python-Programm um.
15
ooP mit Python
Die einfache Variable
4
Die einfache Variable
4.1
Die Variable in der Mathematik
Das Variablenkonzept der Informatik unterscheidet sich erheblich von dem der Mathematik. In der Mathematik repräsentiert die Variable jeden möglichen Wert, der an dieser
Stelle eingesetzt werden kann. In der Informatik steht die Variable dagegen immer nur
für einen einzigen konkreten Wert.
Lexikon: Die Variable in der Mathematik
a sei eine gerade Zahl zwischen -6 und +6
Welche Werte kann dann a/2 einnehmen?
Ergebnismenge: -3, -2, -1, 1, 2, 3
Für den Fall a = 2
gilt das Ergebnis: 1
In der Mathematik bedeutet die Variable jeden
beliebigen Wert aus eine bestimmten
Definitionsmenge.
Das = steht in der Mathematik für den Vergleich
4.2
Die Variable in der Informatik
4.2.1
Die Variable als Box
Für die Informatik ist die
Variable wie eine Box. Sie
kann bestimmte Werte aufnehmen. Wir sagen, dass wir
der Variable einen Wert
zuweisen.
Die einfache Variable kann
immer nur einen einzigen
Wert enthalten. Weist man
ihr einen neuen Wert zu, verschwindet der alte Wert.
Wie bekommt man eine Giraffe in den
Kühlschrank?
Kühlschrank auf – Giraffe rein – Kühlschrank zu!
Wie bekommt man einen Elefanten in den
Kühlschrank?
Kühlschrank auf – Giraffe raus – Elefant rein –
Kühlschrank zu!
Zuweisung
W ert
Variable
Variable
faktor1
=
10
Lexikon: Die Variable in der Informatik
a = 1 (Zuweisung – kein Vergleich!)
Box
← Wert
a
|____| ←
1
In der Informatik ist die einfache Variable ein Speicher,
der genau einen Wert aufnehmen kann.
Das = ist kein Gleichheitszeichen, sondern ordnet den
Wert auf der rechten Seite dem Variablen-Speicher auf
der linken Seite zu (Pfeilrichtung).
16
ooP mit Python
4.2.2
Die einfache Variable
Wertzuweisung
Bei der Zuweisung eines Wertes zu einer Variablen steht der Wert rechts der Variablen.
Wortschatz: Werte zuweisen und auslesen
faktor1 = 10
_faktor2 = 25
a = input('gib einen Wert ein')
b = 'Text'
so nicht: print = 'schreiben'
mult = faktor1 * _faktor2
print(mult)
Regeln für die Variable
Eine Variable besteht aus beliebigen Namen, der mit
einem Buchstaben oder mit einem Unterstrich beginnt.
Er darf nicht mit einer Zahl beginnen, kein Leerzeichen
enthalten und keinen für die jeweilige Programmiersprache bereits festgelegten Bezeichner.
Die in den Variablen eingelagerten Werte werden
ausgelesen, wenn sie auf der rechten Seite einer
Zuweisung stehen oder wenn sie in einer Funktion als
Parameterwert verwendet werden.
Manchmal möchte man eine Variablen nur anlegen (deklarieren), ohne ihr einen Wert
zuzuweisen, dann setzt man den Wert None („Nichts“) ein. Aber: Taucht der Wert None
unerwartet in einem Programm auf, liegt ein Programmierfehler vor.
Lexikon: Der Nichts-Wert
None
a = None
Geht nicht: print(None+1)
Der Wert 'Nichts'
Der Wert kann auch zugewiesen werden
Er entspricht nicht dem Wert '0' (wie etwa in der
Tabellenkalkulation). Kein Operator kann ihn
verändern. Er muss überschrieben werden.
Lexikon: Die Variable in Python und in Java
a = 'Text'
print(a)
a = 1234
print(a)
a = None
Die Variable in Python (schwach getypt)
Jede Variable kann jeden Wert aufnehmen.
Einer Variablen, die einen Textwert enthält, kann auch
ein Zahlenwert oder der Wert' Nichts' zugewiesen
werden.
String a = 'Text';
system.out.print(a);
Integer b = 1234;
system.out.print(b);
a = null;
Die Variable in Java (Stark getypt)
Eine Variable kann nur Werte eines festgelegten
Wertetyp aufnehmen.
Mehrere Variablen gleichen Namens sind nicht erlaubt
Der Wert 'Nichts' wird NALL ausgesprochen
Lexikon: Variablennamen
camelCaseSchreibweise
varNeu ='Wert'
attrEins = 'Wert'
Leerzeichen sind „böse“ Zeichen.
CamelCaseSchreibweise (wie Kamel-Höcker) lässt alle
Leerzeichen und Umlaute weg. Wortanfänge im Wort werden
groß geschrieben
Diese Schreibweise verwenden wir für Variablen und später
zur Deklaration der Attribute in den Klassen.
17
ooP mit Python
4.2.3
Die einfache Variable
Ringtausch
Ein einarmiger Roboter soll zwei Gegenstände tauschen. Er kann
jedoch immer nur einen dieser Gegenstände halten und jeder Gegenstand darf sich nur an seinem Platz befinden oder am Arm des Roboters. Ohne Ausweichplatz geht das nicht.
Ringtausch
Das Gleiche gilt für zwei Fahrzeuge, die sich auf einer engen Straße,
begegnen. Da muss eines der beiden Fahrzeuge bis zur nächsten Ausweichstelle zurücksetzen, damit beide aneinander vorbei kommen.
Das Gleiche geschieht beim Ringtausch: Von zwei Variablen enthält jede einen eigenen
Wert. Sollen die beiden Werte getauscht werden, wird eine dritte Variable als Ausweichplatz benötigt.
Lexikon: Ringtausch
a =
b =
tmp
a =
b =
'Text'
'anderer Text'
= a
b
tmp
Zum Ringtausch zweier Werte wird eine weitere
Variable benötigt. Hier heißt sie tmp für temporär.
Aufgaben zu Kapitel 4
1
Die Variable in der Mathematik
1) a sei eine beliebige Zahl zwischen -5 und +5: Welche Werte kann dann a 2 einnehmen?
Zeichne den passenden Graph dazu.
2) Für welche Werte ist die folgende Funktion definiert: f(x) = 1/(3-x)?
2
Die Variable anlegen und auslesen
1) Lege für jedes Adjektiv des folgenden Textes eine Variable mit einem sprechenden Namen
an. Schreibe den Text mit einer print() -Funktion auf den Bildschirm. Rufe dabei die Werte
aus den Variablen im Text auf.
'An einem lauen Sommerabend fuhr ein verwegener Bursche mit seinem feuerroten
Rennwagen behäbig auf der ruhigen Landstraße auf die rotglänzend untergehende
Sonne zu.'
2) Versehe die Variablen aus Aufgabe 2a mit passenden input()-Anweisungen.
3) Erfinde einen anderen lustigen Text nach diesem Muster und lasse ihn von deinen MitschülerInnen ausfüllen.
3
Ringtausch
1) Programmiere den Ringtausch mit den Gegenständen 'Adler' auf der Variablen
Platz_Adler und 'Maus' auf der Variablen Platz_Maus.
2) Organisiere den Tausch mit fünf Variablen (a,b,c,d,e) und ihren Werten (1,2,3,4,5).
18
ooP mit Python
Die Sammelvariable
5
Die Sammelvariable
5.1
Warum noch ein Variablen-Typ?
Um mehrere zusammengehörende Werte zu speichern, könnten wir für jeden Wert eine
Variable anlegen. Damit handeln wir uns aber gleiche mehrere Probleme ein: Zum einen
stünde uns nur eine festgelegte Anzahl von Speicherplätzen zur Verfügung. Zum Anderen müssten wir die zusammengehörenden Werte unter verschiedenen Namen aufrufen,
weil jeder Wert in einer anderen Variable steckt. Leichter geht es, wenn wir zusammengehörende Werte in einer Sammelvariablen speichern.
Beispiel:
Eine Sammelvariable statt vieler Variablen anlegen
varA = 1
varV = 2
varC = 3
}
varSammel = [1,2,3]
varSammel[2]= 'wert'
Zuweisung
0
1
2
W ert
varSammel
varSammel
5.2
Informatiker zählen anders
Wollen wir nicht die Liste ausgeben, sondern ein bestimmtes Element aus der Liste, müssen wir die Stelle angeben, an der sich das Element befindet. Dabei ist aber zu beachten,
dass die Informatik mit dem Wert 0 zu zählen beginnt. So kennen wir 10 einstellige
Werte von 0-9, der erste Wert ist die 0, der zehnte Wert ist die 9. Mit zwei Stellen
bekommen wir 100 Werte (0-99) und mit drei Stellen 1000 Werte (0-999).
Die folgende Liste enthält drei Werte, hat also die Länge 3 und besitzt eine nullte, eine
erste und eine zweite Stelle:
Länge
Werte
Stelle
3
'eins'
0 (Stelle Null)
'zwei'
1 (Stelle eins)
'drei'
2 (Stelle zwei)
}
Liste
Wir sagen: Der Wert an der Stelle 0 ist 'eins'.
Wortschatz: Einzelne Werte der Listen auslesen
a = [1,2,3]
b = (1,2,3)
Die Liste auslesen
Informatiker beginnen mit der 0 zu zählen:
print(a[0])
Ergebnis: 1
print(b[1])
Ergebnis: 2
Wir sagen:
'print- a an der Stelle Null'
'print -b an der Stelle Eins'
19
ooP mit Python
Die Sammelvariable
5.3
Array, ArrayList und Liste
5.3.1
Listentypen
In vielen Programmiersprachen heißen diese Sammelvariablen Array oder ArrayList. Das
klassische Array besitzt nur eine begrenzte Anzahl von frei verfügbaren Speicherplätzen.
In Python unterscheiden wir Tupel und Liste. Die Liste entspricht der ArrayList in Java,
sie kann wie das Tupel, beliebig viele Wert aufnehmen. Das Tupel ist nach seiner Erzeugung jedoch unveränderlich. Die Liste kann in jeder Hinsicht verändert werden.
Zum dritten Listentyp, dem Dictionary, das dem Hash in Perl entspricht, finden Profis
unter www.python-kurs.eu/dictionaries.php weitere Informationen.
Lexikon: Array und ArrayList in Java und Python
Java
Python
Gibt es nicht
Integer a = new Integer[4];
c = (1,2,3,4)
print(c)
Das Tupel gibt es nicht
d = 'String'
print(d)
List<int> a
5.3.2
=
new ArrayList<int>();
Array (hier für 4 Werte)
Das Tupel (unveränderlich)
wird erzeugt und nicht verändert
Beachte: Strings sind für Python
ebenfalls Tupel
Die Liste (beliebig viele Werte)
entspricht der ArrayList in Java.
Die Liste in Python ist jedoch
nicht auf einen bestimmten
Wertetyp festgelegt
a = []
Punkt-Notation
Der Punkt klebt zwei Elemente zusammen. Das Listen-Objekt a und die Methode
append() werden also aneinandergehängt. Das bedeutet:
Die Methode append() operiert auf der Liste a und fügt ihr einen Wert ein.
Objekt
.
Methode
.
append('wert')
liste=[]
liste
Lexikon: Punktnotation
Java
a.add(1);
Python
a.append(1)
a.append('Name')
20
Die Funktion append() fügt der
Liste einen Wert hinzu
ooP mit Python
5.3.3
Die Sammelvariable
Listenumwandlung
In Python können Listen problemlos in Tupel verwandelt werden und umgekehrt.
Lexikon: Listen umwandeln
zahlListe = [1,2,3]
zahlTupel = tuple(zahlListe)
xx = tuple([2,3,4])
textListe = list('String')
print(zahlListe,zahlTupel,xx,textListe)
Umwandlungsfunktionen
Listen lassen sich in Tupel umwandeln und
umgekehrt.
In Python sind Strings Tupel. Also lassen auch sie
sich in eine Liste verwandeln.
5.4
Der Listendurchlauf
5.4.1
Anweisung und Anweisungs-Block
Zu einer einzigen Anweisung können mehrere anschließende Anweisungsschritte gehören. Wir sagen: Die Anweisung erzeugt einen Block von Anweisungen. Dem Laufzeitsystem muss dieser Block bekannt gemacht werden. In den meisten Programmiersprachen geschieht das durch geschweifte Klammern. In Python reicht es, einen Doppelpunkt
zu setzen und dann die folgenden Anweisungen um einen Tabulator einzurücken. Die
Idle erzeugt den Block nach dem Doppelpunkt automatisch.
Lexikon: Der Block
Anweisung:
erste Anweisung im Block
zweite Anweisung im Block
Der Block macht deutlich, dass die kommende Folge
von Anweisungen zu einleitenden Anweisung gehört.
Der Listendurchlauf mit for ist eine solche Anweisung, die einen Block erzwingt.
Wortschatz: Listendurchlauf mit for
liste = [1,2,3]
for e in liste:
print(e)
Ausgabe:
1
2
3
for e in (1,2):
print(e, end='x')
Ausgabe
1x2x
Listendurchlauf mit for
Das for-Statement gibt den Auftrag, durch eine Liste
oder einen Tupel zu laufen
Beim ersten Durchlauf wird das erste Element
genommen, vorläufig in der Variablen e gespeichert und
im Block verarbeitet. Beim zweiten Durchlauf ist das
zweite Element dran usw. In diesem Fall wird der Wert
der Variablen e mit der print()-Funktion ausgegeben.
Sind die Folge-Anweisungen für einen Block noch unbekannt, muss in Python der Platz
für den Block durch die leere Anweisung pass reserviert werden.
Lexikon: Das pass-Statement als Block-Reservierer
for e in (1,2,3):
pass
Das leere pass-Statement reserviert den Block
21
ooP mit Python
5.4.2
Die Sammelvariable
Der Listendurchlauf mit for
Um eine Liste zu durchlaufen, verwenden wir die Wiederholung mit for. Das for-Statement (for e in liste:) enthält
•
•
•
•
den Wiederholungsaufruf for (pro)
eine Variable mit beliebigen Namen (e oder Element ...)
(Beim Listendurchlauf ist die Variable element oder e für 'Element der Liste' üblich)
den Zeiger in (aus)
und den Namen der Liste (Liste)
Die Wiederholung holt pro Durchlauf ein Element aus der Liste, speichert dieses Element in der Variablen e und stellt dieses Element aus der Variablen e dem Programmablauf zur Verfügung, der im Block der Wiederholung notiert ist.
5.4.3
Der Wiederholung mit fester Anzahl
Soll ein Programmabschnitt mehrfach durchlaufen werden, wird ein Iterator (Läufer)
verwendet. Die Python-Funktion range(ende) ersetzt die Liste und liefert pro Durchlauf einen um +1 erhöhten Wert. Die Variable nennen wir üblicherweise i (für Iterator).
Ist i als Variable bereits vergeben, nennen wir sie dem Alphabet folgend j, k usw.
Wortschatz: Der Iterator range()
# range(anfang,schranke,schritt)
# range(anfang,schranke)
# range(schranke)
a=[1,2,3,4,5,6]
for i in range(0, 4, 2):
print(a[i])
for i in range(3, 5):
print(a[i])
Die range()-Funktion kann mit einem, zwei oder drei
Parametern aufgerufen werden. Sie wirft für jeden
Listendurchlauf einen von 'anfang ' aufsteigenden Wert
aus. Das Zählen endet unterhalb des als schranke
übergebenen Wertes. Sind anfang und schritt nicht
angegeben, werden die Standardwerte 0 für anfang und
1 für schritt verwendet
for i in range(2):
print(a[i])
Die Variable i nimmt bei jedem Durchlauf den nächsten
Wert vom Iterator range() entgegen
# range(anfang > schranke,-schritt)
for i in range(3,-1,-1):
print(a[i])
Um eine Liste rückwärts einzulesen, muss der
Anfangswert größer sein als die Schranke. Die
Schrittlänge wird als negativer Wert gesetzt.
Die Iterator-Funktion kann auch verwendet werden, um die Werte der Liste und deren
Stelle innerhalb der Liste auszugeben. Dazu wird mit der len()-Funktion die Länge der
Liste ausgelesen und dann dem Iterator übergeben: for i in range(len(liste)).
Lexikon: Länge der Liste
liste = [2,4]
print(len(liste))
Ergebnis: 2
#Die Schranke kann auch durch
#len(liste) erzeugt werden
for i in range(len(a)):
print('- liste['+ i +']:',a[i])
Die len()-Funktion kann die Länge einer Liste einlesen
Sie wird hier für das Auslesen der Liste verwenden.
- liste[0]: 2
- liste[1]: 4
22
ooP mit Python
5.5
Die Sammelvariable
Listen von Listen
Listen können beliebige Werte verwalten und deshalb können sie wiederum Listen oder
Listen-von-Listen enthalten. Solche Listen von Listen nennen wir mehrdimensionale Listen. Mit zweidimensionalen Listen können wir Tabellen darstellen.
Wortschatz: Listen von Listen – innerer Listendurchlauf
kopf = [' ','A','B']
a= ['1','x',2]
b=['2','y',4]
tabelle =[kopf,a,b]
Mehrdimensionale Liste
for e in tabelle:
for i in range(len(e)):
print(e[i], end=' | ')
print()
Listen von Listen verwerten
In den Listendurchlauf durch die Liste 'tabelle' ist ein
innerer Listendurchlauf eingebettet. Er durchläuft
zusätzlich die in der Liste 'tabelle' eingebetteten Listen
'kopf','a' und 'b'
Die Liste 'tabelle' enthält die Listen 'kopf','a' und 'b'
5.6
String und Liste
5.6.1
String-Listen in Strings umwandeln
Strings sind für Python unveränderliche Tupel und können deshalb in veränderliche Listen umgewandelt werden. Der umgekehrte Weg ist etwas schwieriger. Dabei kommt die
Text-Methode 'text'.join(liste) zum Einsatz. Sie klebt jedes Element einer Liste
von Strings an den vorangestellten Text. Besteht der angegebene String aus dem leeren
Text, werden nur die in der Liste vorhandenen Textelemente zusammengefügt.
Lexikon: String und Liste
wortliste = list('String')
textliste = ['ich','1','und',
' ','du']
# 'text'.join(liste)
text = ''.join(textliste)
print(text)
String als Liste
Der String als unveränderliche Liste von Zeichen. kann
in eine veränderliche Liste umgewandelt werden.
Listen können am Komma umgebrochen werden
String- oder Textwerte aus einer Liste können zu einem
neuen String zusammengefügt werden, ohne dabei
Speicherprobleme zu erzeugen
# Ergebnis: 'ich1und du'
5.6.2
Buchstaben als Ziffern verwenden
Für das Dezimalsystem haben wir zehn Ziffernzeichen von 0 bis 9, mit denen alle natürlichen und alle rationalen Zahlen eindeutig beschrieben werden können. In der Informatik verwenden wir aber oft das Hexadezimalsystem, das mit sechzehn Ziffern arbeitet.
Die dezimale 10 wird als A, die dezimale 15 mit dem Buchstaben F dargestellt. Mit diesen Zeichen lässt sich aber schlecht rechnen. Statt dessen packt man die Ziffern '0','1' bis
'E','F' in eine Liste und rechnet mit deren Index-Werten: liste.index('F') → 15.
23
ooP mit Python
5.7
Die Sammelvariable
Methoden eines Listenobjekts
Listen sind Objekte, bei denen wir Werte einfügen, entfernen oder ändern können. Wir
können die Elemente, die in dem Listen-Objekt eingelagert sind, sortieren, durchzählen
oder umkehren. Wir können herausfinden, an welcher Stelle ein bestimmter Wert steckt
oder den Wert an einer bestimmten Stelle ausgeben lassen.
Als Objekte verwenden die Listen bestimmte Methoden. Sie werden mit der Punkt-Notation mit dem Namen der Liste verbunden, auf der sie operieren sollen
Wortschatz: Listenmethoden
Die Funktion ...
… und ihre Aufgabe
a = [1,2,3]
a = []
a = ['x','c','b','x', 1, [1,2,3]]
Legt eine Liste mit drei Werten an
Überschreibt die Liste mit einer leeren Liste
Überschreibt die Liste mit sechs verschiedenen Werten.
Der 6.Wert a[5] ist eine Liste mit drei Werten!
a.append('y')
Hängt einen neuen Wert an das Ende des Liste
# Liste.count(Wert)
print(a.count('x'))
#
Ergebnis: 2
Zählt wie oft der gesuchte Wert in der Liste steckt
# Liste.index(Wert)
print(a.index('x'))
#
Ergebnis: 0
Gibt die Stelle an, an der der gesuchte Wert zum ersten
Mal zu finden ist – hier an der nullten Stelle!
# Liste.reverse()
a.reverse()
print(a)
Kehrt die Reihenfolge der Liste um
#Liste.sort()
a = [3,2,1]
a.sort()
print(a)
# das Folgende gibt eine Fehlermeldung
x = [1,'zwei',3]
x.sort()
Sortiert die Liste vom kleinsten zum größten Wert
Vorsicht: Die alte Reihenfolge geht verloren!
# Liste.remove(Liste['Stelle'])
a.remove(a[3])
a.remove('x')
#oder:
a.remove(a[a.index('x')])
Entfernt das Element an einer bestimmten Stelle
# Liste.insert(Stelle,Wert)
a.insert(0,'z')
print(a)
Fügt in die Liste an der angegebenen Stelle den
angegebenen neuen Wert ein.
# Liste.pop(Stelle)
print(a.pop(3))
#
Ergebnis: 'd'
print(a)
Holt den Wert an einer bestimmten Stelle aus der Liste
und entfernt ihn aus der Liste.
Gemischte Werte werden nicht sortiert!
Soll ein bestimmtes Element entfernt werden, wird
entweder dessen Stelle, dessen Inhalt oder dessen IndexWert genannt.
24
ooP mit Python
Die Sammelvariable
Aufgaben zu Kapitel 5
1
Listen
Teste die Beispiele aus dem Wortschatz Listenmethoden (S.24) mit der Idle
2
Tupel und Liste
1) Speichere deinen Vornamen in einer Variable. Wandle den Vornamen in einen Tupel und in
eine Liste um und speichere den Tupel und die Liste in unterschiedlichen Variablen mit sprechendem Namen.
2) Printe jede der drei Variablen aus Aufgabe 2a mit Hilfe des Listendurchlaufs aus. Dein Vorname soll zuerst dreimal untereinander ausgegeben werden und dann dreimal in einer Zeile
hintereinander.
3) Printe für alle drei Variablen aus Aufgabe 2a nur die ersten und die letzten Buchstaben deines Vornamens aus.
4) Schreibe das Programm mit der input()-Funktion so um, dass ein beliebiger langer Name eingegeben werden kann. Wie greifst du auf den letzten Buchstaben eines Namens zu, wenn du
seine Länge nicht kennst?
3
Listen von Listen
1) Printe alle Elemente der Liste liste1 = [1,2,3,4,5] in einer einzigen Zeile aus.
2) Teste und erkläre, weshalb der gleiche Versuch bei Liste2 ein unbefriedigendes Ergebnis
bringt: liste2 = [1,2,[3,4],5]
3) Printe mit Hilfe eines inneren Listendurchlaufs alle Werte der folgende geschachtelten Liste
einzeln untereinander auf den Bildschirm: liste = [[1,2],[3,4],[5,6]]
4) Teste die folgende geschachtelt Liste
z = ['-','1','2']
a = ['A','x','o']
b = ['B','y','w']
q = [a,b]
print(q[0][0],q[1][0],'\n',
q[0][1],q[1][1],'\n',
q[0][2],q[1][2],sep='')
- A B
1 x y
2 o w
5) Ändere Liste q in q=[z,a,b]. Passe den print()-Aufruf aus der vorhergehenden Aufgabe
so an, dass in der ersten Spalte die Zeilennummern aus Liste z auftauchen.
4
Listenfunktionen
1) Rufe zur Liste a=[1,2,3] die Funktion print(a.remove(a[1])) auf. Rufe danach
zwei Mal die Funktion print(a.pop(0)) auf. Erkläre jeweils die Ausgaben.
2) Berechne mit Hilfe der zahlenliste = ['0','1','2','3','4','5','6',
'7','8','9','A','B','C','D','E','F'] die Zahl 2365.
Erstelle eine Lösung auch mit einer einzigen Wiederholung mit fester Anzahl.
25
ooP mit Python
5
Die Sammelvariable
Ringtausch
Gegeben ist die Liste a=[1,2,3]
1) Tausche die erste mit der letzten Stelle mit Hilfe eines Ringtausches.
2) Erzeuge das gleiche Ergebnis durch eine geschickte Anwendung der Listenmethoden
append(element) und pop(stelle) in einer einzigen Anweisungszeile.
6
Federmäppchen
1) Erstelle eine Liste federmaeppchen, die Bezeichnungen verschiedener Gegenstände
aus deinem Federmäppchen enthält.
2) Lasse mit Hilfe der verschiedenen Möglichkeiten des Listendurchlaufes alle Gegenstände deines Federmäppchens ausgeben. Überlege, wie du alle Gegenstände auf einer Zeile ausgeben kannst.
3) Gib dem Nutzer des Programms den Auftrag, einen Gegenstand aus dem Federmäppchen zu
holen. Das Programm schreibt danach auf die Konsole, welcher Gegenstand entfernt wurde
und an welcher Stelle er sich in der Liste befand.
4) Verändere das Programm so, dass die Gegenstände im Federmäppchen nach dem Listendurchlauf (Aufgabe 6b) und vor dem Nutzerzugriff (Aufgabe 6c) alphabetisch sortiert werden.
Wird dann immer noch der richtige Gegenstand entfernt? - Begründung!
7
Klamotten aufräumen
Beim Aufräumen sortierst du deine Klamotten (Jeans1, braGeuneShorts, KlassenfahrtTShirt,
weißesHemd, blauesHemd, SportShorts, SchulTShirt, JeansGrün, karriertesHemd, FanTShirt) in verschiedene Kisten (T-Shirts, Hemden/Blusen, Hosen, Shorts) und stellst dann alle
Kisten in den Schrank.
1) Programmiere dieses Beispiel als geschachtelte Liste und gib alle Klamotten der Reihe nach
als Bildschirm-Print aus.
2) Anschließend fällt dir auf, dass du die neue Jeans3 vergessen hast. Füge sie in die richtige
Kiste ein.
3) Dann legst du eine Kiste Sportsachen an, nimmst die Sportsachen aus den anderen Kisten,
und legst sie in die neue Kiste.
26
ooP mit Python
Die Variable im Arbeitsspeicher
6
Die Variable im Arbeitsspeicher
6.1
Die einfache Variable
Bei der Deklaration
einer Variable wird im
Arbeitsspeicher Platz
für diese Variable
reserviert
Bei der Wertzuweisung
wird der angegebe Wert
auf dem Speicherplatz
der Variable abgelegt.
Beim Aufruf der Variable wird der Wert von
diesem Speicher ausgelesen.
6.2
Die Sammelvariable
Bei der Deklaration
einer Sammelvariable,
wird ebenfalls ein Platz
reserviert. Dort liegt
jedoch ein Hinweis auf
den Anfang einer Reihe
von Speicherplätzen.
Bei der Wertzuweisung
werden die neuen Werte
in dieser Reihe von
Speicherplätzen abgelegt.
Beim Auslesen folgt das
Programm dem Hinweis
auf die Speicherplätze.
Beachte: Die erste Stelle
in der Sammelvariable
wird als nullte Stelle gezählt!
27
ooP mit Python
Die Variable im Arbeitsspeicher
6.3
Unterschiedliches Verhalten der Variablentypen
6.3.1
Call by Value
Mit varB = 6 wurde
an der Speicherstelle 04 eine neue
Variable angelegt.
Durch varB = varA
bekommt varB den
Wert von varA zugewiesen: Er wird aus
varB
nach varA
kopiert (call by value).
Die beiden Werte existieren also unabhängig
voneinander.
Bekommt varA einen
neuen Wert zugewiesen, ändert sich der
Wert in varB nicht.
6.3.2
Call by Reference
Mit varYY = [6,7,8]wurde eine weitere Variable an der Speicherstelle 07
angelegt. Sie enthält eine Referenz auf die Speicherstelle 15. Mit varXX = vaYY wird
der Variablen varXX der Hinweis auf die Speicherplätze von varYY übergeben (call by
Referenz). Damit gibt es eine „neue Tür“ zu den Werten, die auf den Speicherplätzen 15-17 liegen, währdend die Werte an den Speicherplätzen 10–14 verweist sind.
Ändere ich varXX[0], dann greift auch varYY[0] auf diesen geänderten Wert zu.
Die verweisten Speicherplätze werden durch die Speicherverwaltung zum Überschreiben
freigegeben. Aber Vorsicht: Wie lange diese Werte noch existieren, ist unbekannt! Sie
könnten noch versehentlich ausgelesen werden. Deshalb lässt Python wie viele andere
Programmiersysteme keinen direkten Zugriff auf den Arbeitsspeicher zu.
6.3.3
Deep Copy
Merke: Will ich die Werte aus einer Liste in die andere tatsächlich kopieren, muss ich
eine leere Liste anlegen und die Werte aus der anderen Liste in die neue Liste kopieren.
Für Profis:
Python stellt dafür ein eigenes Modul zur Verfügung (siehe Kap. 10.1 Modul – import):
http://www.python-kurs.eu/deep_copy.php
28
ooP mit Python
6.4
Die Variable im Arbeitsspeicher
Identität und Gleichheit von Werten
Die Berechnung von 2/2 ist für die Mathematik einfach, das Ergebnis ist die natürliche
Zahl 1. Python erzeugt bei Bruchrechnungen jedoch immer Floats, also Kommazahlen,
deshalb ist das Ergebnis von 2/2 in Python 1.0.
Weisen wir das Ergebnis von 2/2 den beiden Variablen a und b zu, so enthalten sie beide
den gleichen Wert. Sie liegen aber nicht an der gleichen Speicherstelle; die Variablen
a und b sind also gleich (Werte), aber nicht identisch (Speicher).
Lexikon: Vergleich auf Gleichheit und Identität
>>> a = 2/2
>>> b = 2/2
>>> a==b
True
>>> a is b
False
Die beiden Variablen enthalten den gleichen Wert
aber sie liegen nicht an der gleichen Speicherstelle
== prüft auf Gleichheit der Werte
is prüft auf die Identität der Speicherstelle
Vorsicht: Python legt einfache Werte wie ganze Zahlen
als Objekt an. Die Variablen mit gleichen ganzen
Zahlen referenzieren dann den gleichen Speicherplatz
Aufgaben zu Kapitel 6
1
Die Variable im Arbeitsspeicher
1) Teste die Wertzuweisung und Wertveränderungen der einfachen Variablen varA und
varB: Lege varA mit dem Wert 10 an, lege varB mit dem Wert 6 an. Weise der Variablen
varA den Wert von varB zu und teste beide Werte durch ausprinten. Ändere den Wert
einer der beiden Variablen und teste das Ergebnis durch erneutes ausprinten.
2) Teste die Wertzuweisungen und Wertveränderungen der Sammelvariablen varXX und
varYY: Lege varXX mit den Werten 3,7,4,2,11 an, weise varXX der Sammelvariablen
varYY zu und prüfe die beiden Sammelvariablen durch ausprinten. Ändere den Wert
varXX[2] auf 5 und printe varYY aus und erkläre das Ergebnis.
3) Lege eine leer Sammelvariable varZZ an und kopiere mit Hilfe des Listendurchlaufes die
Werte aus varXX in varZZ. Teste alle drei Variablen durch ausprinten. Ändere dann die
erste Stelle von varXX und VarZZ. Teste wieder durch ausprinten. Erkläre das Ergebnis.
4) Lege eine Sammelvariable buechertasche für deine Büchertasche an und fülle sie mit
'Gegenständen' (Strings). Erlaube einem Nutzer des Programms, den Inhalt der Büchertasche mit Hilfe der input()-Funktion zu ändern.
5) Ein Raum besitzt zwei Türen, tuere1 und tuere2, anders kann das Zimmer nicht betreten werden. In diesem Zimmer befinden sich ein Tisch, vier Stühle und ein Regal in dem ein
Fernseher und ein DVD-Player stehen (jeweils als String). Programmiere diesen Raum mit
den geeigneten Variablen. Begründe deine Lösung für das Regal mit dem Fernseher und
dem DVD-Player in einem Programm-Kommentar.
29
ooP mit Python
7
Kontrollstrukturen
Kontrollstrukturen
Wenn ein Programm auf verschiedene Eingaben unterschiedlich reagieren soll, benötigen
wir Kontrollstrukturen wie die Wiederholung mit while und mit for oder die Verzweigung mit if, if-else und if-elif-else. Die Verzweigung mit if-else kennen wir schon aus
der Tabellenkalkulation als wenn()-Funktion:
wenn(A1=1;“eins“;“nicht eins“)
if(A1==1): “eins“; else: “nicht eins“
Die aus anderen Programmiersprachen bekannte Vereinfachung der Mehrfachverzweigung mit Switch und Case, die nur mit Zahlen oder Chars arbeitet, ist in Python nicht
implementiert.
7.1
Wahrheitswerte (boolsche Werte)
Wahrheitswerte kennen wir ebenfalls aus der Tabellenkalkulation. Wir benötigen sie, um
bei Verzweigungen und Wiederholungen den richtigen Weg zu finden. Die beiden möglichen Werte Wahr und Falsch können z.B. als 0 bzw. 1 oder als true bzw. false notiert
werden. In Python werden die Wahrheitswerte groß geschrieben: True, False. Für den
Vergleich von Werten stellt Python die üblichen Vergleichsoperatoren zur Verfügung.
Enthält die Wahrheitsprüfung statt eines Vergleich einen leeren Wert oder den Wert 0,
wird False erzeugt; True wird erzeugt, wenn irgend ein Wert ungleich 0 vorhanden ist.
Wortschatz: Vergleichsoperatoren
==
Das einfach Gleichheitszeichen '=' wird für die
Zuweisung verwendet. Verglichen wird durch das
doppelte '=='
is
!=
prüft auf Identät der Objekte
Ungleich
>, >=, <, <=
größer, größer-gleich, kleiner, kleiner-gleich
not('Wert')
not(0)
Die not()-Funktion verwandelt jeden Wahrheitsterm in
sein Gegenteil
True and True
1==1 and 4/2 == 8/4
Die and-Verknüpfung verlangt, dass auf beiden der
Wert True enthalten ist oder erzeugt wird, wenn das
Gesamtergebnis True liefern soll
False or True
1==2 or 4/2 == 8/4
(), [], {}
'irgendeinwert', ("Wert",0)
Bei der or-Verknüpfung reicht es, wenn einer von
beiden Seiten den Wert True enthält oder erzeugt
drei Beispiele für leere Werte (leere Listen!). Sie stehen
den Wert False
zwei Beispiele für beliebige Werte, die für den Wert
True stehen
30
ooP mit Python
Kontrollstrukturen
7.2
Die Wiederholung
7.2.1
Die bedingte Wiederholung
Der Fahrer, der in den Kreisel einfährt, verlässt den Kreisel erst
dann, wenn er das Signal bekommt: 'ausfahren!' Wenn er Pech
hat, kommt das Signal nie und er steckt in einer Endlosschleife!
Wir können diesen Ablauf als Struktogramm schreiben:
solange nicht(ausfahren!)
Wiederholung
fahre im Kreis
Wortschatz: Die bedingte Wiederholung mit while
# 1
while True:
print('findet das kein Ende?')
print('immer noch nicht!')
# 2
while 1 == 2:
print('das liest keiner!')
# 3
while 1:
print('Endlosschleife')
break # und doch nicht
# 4
antwort = 'nein'
while antwort != 'ja':
antwort = input('sag ja! ')
print('machs nochmal, Sam!')
# 5
while input('sag ja: ') != 'ja':
print('machs nochmal, Sam!')
Die Wiederholung mit while fordert eine
Wahheitsprüfung und einen Programmblock. Das
Programm wird solange abgearbeitet, bis die
Wahrheitsprüfung den Wert False erzeugt.
Sind die Wahrheitswerte festgeschraubt, hat man eine
Endlosschleife oder einen Programmabschnitt, der nie
ausgeführt wird
Die Wiederholung mit while sollte deshalb immer so
konstruiert werden, dass sie auch vernünftig
abgearbeitet werden kann
Falls eine Wiederholung auf unendlich gestellt wurde,
kann sie mit dem break-Statement abgebrochen werden
Die beiden Wiederholung # 4 und # 5 bewirken zwar
das Gleiche,
aber die Wiederholung # 5 kommt aber ohne zusätzliche
Variable aus.
Eine bedingte Wiederholung kann alle Programmelemente enthalten, die wir bisher kennen gelernt haben, auch weitere Wiederholungen.
Wortschatz: Die geschachtelte Wiederholung
1 while(input('sag ja') != 'ja'):
2
x = 'x'
3
while(x=='x'):
4
x = input('schreibe kein x')
5
for i in range(5):
6
print(i)
Wiederholung mit internen Wiederholungen
Sooft die äußere Wiederholung (Zeile1) die Eingabe
'ja' belommt, wird zuerst die innere Wiederholung
mit while (Zeilen 2-4) solange durchgeführt, bis kein
'x' eingegeben wird, danach die Wiederholung mit
for (Zeilen 5 und 6).
31
ooP mit Python
7.2.2
Kontrollstrukturen
Wiederholung mit Zähler
Mit einem ordentlich eingerichteten Zähler, kann man die einfache Wiederholung in eine
Zählschleife umwandeln, die im Normalfall sicher endet.
Wortschatz: Die zählende Wiederholung mit while
Die Zählschleife benötigt drei Angaben:
- Initialisierung: Zähler mit Anfangswert
- Endbedingung: Wahheitsprüfung
- Inkrement / Dekrement: Der Anfangswert
wird hochgezählt oder abgesenkt
# aufwärts
a = 0
# Initialisierung des Zählers
while a<10: # Endbedingung
a = a+1 # Zähler = Inkrement
# abwärts
a = 10
# Initialisierung des Zählers
while a>0: # Endbedingung
a = a-1 # Zähler = Dekrement
print('mich gibt’s 10 Mal')
7.2.3
Die Wahrheitsprüfung fragt, ob der
anvisierte Wert schon erreicht wurde;
wenn ja, wird die Schleife abgebrochen
Die Wiederholung mit fester Anzahl (einfaches for)
Das Wiederholung mit Zählen kommt in allen Problemen so häufig vor, dass dafür eine
eigene Wiederholungs-Form entworfen wurde. Sie wird häufig als For-Schleife bezeichnet. In Python wird nur die erweiterte Wiederholung mit for verwendet.
for(Initialisierung,Endbedingung,Hochzähler)
{Block}
Hier ein Beispiel in Java
for(int i = 0;i < 10; i++){
System.out.println('hallo');}
7.2.4
Die zählende Wiederholung mit for
packt die Zählvariable mit der
Endbedingung und der Initialisierung in
eine Klammer. Dann folgt der Block.
Inkrement und Dekrement
Das Java-Beispiel für die Wiederholung mit fester Anzahl verwendet eine in vielen Programmiersprachen vorhandene Kurzschreibweise: x++ ist gleichbedeutend mit x = x+1.
Diese Erhöhung eines Zahlenwertes um den Wert 1 heißt Inkrement. Das Dekrement
(x--) senkt einen Zahlenwert um den Wert 1: x = x-1. Python verwendet statt des
klassische Inkrement und Dekrement die vereinfachte Zuweisung.
Lexikon: Die vereinfachte Zuweisung
Standard
a
a
a
a
=
=
=
=
a
a
a
a
+
/
+
Kurzschreibweise
1
1
2
2
oder
oder
oder
oder
a
a
a
a
+=
-=
/=
*=
++a / a++ // --a / a--
1
1
2
1
Selbstzuweisung einer Variablen
Soll eine Variable erhöht werden, muss sie zuerst auf
der rechten Seite ausgelesen werden. Dann muss ihr ein
passender Wert hinzugefügt werden. Zum Abschluss
ersetzt der neue Wert den eben ausgelesen alten Wert.
In anderen Programmsprachen gibt es das einfache
Inkrement und Dekrement. Steht das Inkrement oder das
Dekrement vor der Variablen, wird der Wert der
Variablen zuerst verändert und dann eingelesen. Sonst
wir die Variable zuerst eingelesen und dann verändert.
32
ooP mit Python
7.2.5
Kontrollstrukturen
Erweiterte For-Schleife (foreach)
Die erweiterte For-Schleife besitzt keinen Zähler, sondern setzt einen Iterator voraus,
etwa eine Liste. Oft wird sie auch foreach-Schleife genannt. Python verwendet die Iterator-Funktion range() als Zähler, um die einfache Wiederholung mit for zu ersetzen.
Beispiel:
Die Zeile
n = int(input('gib eine ganze Zahl ein'))
Viele Zeilen
mit der erweiterten For-Schleife
können viele Zeilen untereinander
erzeugt werden.
for i in range(n):
print('x', end='')
7.2.6
Ganzzahl-Teilung und Modulo-Rechnung
Die normale Division erzeugt in der Mathematik ganzahlige Werte oder Brüche:
15/5 → 3 oder 15/7 → 2,142...
Manchmal interessieren uns aber nur die ganzzahligen Werte. Wenn etwa 15 Bonbons
gleichmäßig auf 5 oder auf 7 Kinder aufgeteilt werden sollen. Der Rest ist unwichtig.
15 Ganzzahlteilung 5 → 5 Rest 0
15 Ganzzahlteilung 7 → 2 Rest 1
In anderen Fällen interressiert uns nur der Rest: Wieviele von 15 Bonbons wanderen bei
5 bzw. bei 7 Kindern zum Schluss in die Resteschachtel?
15 modulo 5 → 5 Rest 0
15 modulo 7 → 2 Rest 1
Lexikon: Ganzzahl-Teilung und Modulo-Rechnung
print(15/5)
print(15/7)
print(15//5)
print(15//7)
print(15%5)
print(15%7)
7.2.7
•
Die einfache Teilung erzeugt in Python immer einen Float-Wert
•
Die Ganzahl-Teilung erzeugt in Python immer einen int-Wert
•
Python verwendet für die Modulo-Rechnung das Prozent-Zeichen
Multiplikation und Divison als Wiederholung
Die Multiplikation und die Division sind eigentlich nichts anderes, als eine wiederholte
Addition bzw. eine wiederholte Subtraktion. Die Addition verwendet den Zähler, um
wiederholt zu addieren. Die Subtraktion verwendet den Zähler, um zu prüfen, wie oft
eine Wert von einem anderen abgezogen werden kann.
Beispiel:
Division
dividend = 11
divisor = 2
ganzzahl = 0
while dividend >= divisor:
dividend = dividend-divisor
ganzzahl = ganzzahl + 1
Die Division ist eine wiederholte Subtraktion.
Vorsicht – es kann überraschende Ergebnisse geben:
Den einen Ausgabetyp nennen wir
Modulo-Rechnung (11%2) ,
den andern Ganzzahl-Teilung (11//2)
33
ooP mit Python
7.3
Die Verzweigung
7.3.1
Die einfache Verzweigung
Kontrollstrukturen
Der Fahrer möchte nach Coburg. Eigentlich ist noch genug Benzin
im Tank. Wenn der Benzinpreis jedoch günstig ist, wird er tanken
– dann, aber nur dann wird er zum Tanken abzweigen.
Beispiel:
Verzweigung
Verzweigung
Die Abzweigung wird nur dann
betreten, wenn die Wahrheitsprüfung wahr ergibt.
Sequenz
if benzinPreis == 'günstig':
tanken()
Sequenz
7.3.2
Die Alternative
Das Ziel ist wieder Coburg. Der Tank des Autos ist fast leer. Der Fahrer muss also tanken. Er weiß jedoch, dass auf der Stecke noch eine weitere Tankstelle folgt, bei der er
zufällig die Preise kennt. Er wird also nur dann zum Tanken abzweigen, wenn er bei der
ersten Tankstelle das Benzin günstiger bekommt, als bei der zweiten.
Beispiel:
Alternative
Eine der beiden Verzweigung wird
auf jeden Fall genommen.
Eine andere Möglichkeit, z.B.
stehen zu bleiben, ist nicht
vorgesehen.
Sequenz
if preisHier < preisDort:
tanken()
else:
weiterfahren()
Sequenz
Wir können die beiden Abläufe auch als Struktogramm schreiben.
Für die einfache Verzweigung wird der Nein-Zweig nicht ausgefüllt.
preisHier < preisDort
Benzin ist billig
ja
ja
tanken()
tanken()
7.3.3
nein
weiterfahren()
Kombination von Wahrheitswerten
Als Fahrradfahrer biegt man natürlich nicht zum Tanken ab und auch dann nicht, wenn
der Tank beim Auto voll ist. Für solche Fälle können Wahheitsprüfungen mit and bzw.
mit or verbunden werden.
Beispiel:
if
and / or
benzinPreis == 'günstig' and fahrzeug != 'Fahrrad':
tanken()
if tankfuellung == 'leer' or benzinPreis == guenstig:
tanken()
34
Beide Bedingungen müssen
erfüllt sein
Eine von beiden Bedingungen
muss erfüllt sein
ooP mit Python
7.3.4
Kontrollstrukturen
Mehrfachverzweigung und Kombination von Wahheitswerten
Ein Autofahrer kommt von Neustadt und möchte nach Neustadt zurückfahren. Im Kreisel
hat er vier Möglichkeiten zur Auswahl
Beispiel:
Mehrfachverzweigung
Sequenz
ziel = 'Neustadt'
if ziel == 'Coburg':
nimmAusfahrt(1)
elif ziel == 'Sonnefeld':
nimmAusfahrt(2)
elif ziel == 'Sonneberg':
nimmAusfahrt(3)
else:
nimmAusfahrt(4)
Sequenz
„Ich will nach Neustadt!“
Falls das gewünschte Ziel bei den
ersten drei Ausfahrten nicht
gefunden wird, muss der
Autofahrer bei der vierten
Abzweigung wieder heimfahren.
nach
nach
nach
Coburg Sonnefeld Sonneberg
1.Ausfahrt
2.Ausfahrt
3.Ausfahrt
sonst
4.Ausfahrt
Ein Problem taucht aber auf, wenn der Fahrer nicht nach
Coburg will, sondern nach Rödental. Auch da muss er die
erste Ausfahrt nehmen. Das geht nur, wenn wir beide Ziele in
der ersten Abfrage angeben und mit or verknüpfen.
Mehrfachverzweigung
Wortschatz: if – elif – else / and / or
if wahrheitsprüfung:
pass
if True:
print('ich bin abgezweigt')
if True:
print('Der Text kommt immer')
else:
print('Der Text kommt nie')
if 1 == 2:
print('Der Text kommt nie')
elif 1 > 2:
print('kommt auch nicht')
elif a <= b:
print('kommt drauf an')
else:
print('Auffangstation')
if ziel=='Rödental' or ziel=='Coburg':
print('nimm die erste Abfahrt')
if ziel=='Rödental' and fahrzeug=='Rad':
print('nimm den Radweg nach Coburg!')
Die Verzweigung wird immer durch den if-Zweig
eröffnet. Die leere Anweisung zeigt den Block an
Diese einfache Verzweigung wird immer betreten
Der Else-Zweig ohne Prüfung ist immer die
Auffangstation. Er kann nicht ohne if-Zweig
existieren.
Der elif-Zweig
- kann beliebig oft eingesetzt werden.
- fordert eine Wahrheitsprüfung
- verlangt den eröffnenden if-Zweig
- und den abschließenden else-Zweig
elif ist in anderen Programmiersprachen der else-if
Bei or reicht es, wenn ein ein einziger Wert wahr ist
Bei and müssen beide Werte wahr sein
35
ooP mit Python
7.4
Kontrollstrukturen
Geschachtelte Kontrollstrukturen
Durch die Kontrollstrukturen kann ein Programm eine dynamische Struktur entwickeln,
kein Programmablauf gleicht mehr dem anderen. Wiederholungen und Verzweigung
können beliebig oft in einander geschachtelt und beliebig oft mit Sequenzen verbunden
werden. Die Möglichkeit mit der Tastatureingabe beliebige Werte einzusetzen, erzeugt
einen völlig frei manipulierbaren Programmablauf.
Beispiel:
Rechteck und Dreieck
n = int(input('gib eine ganze Zahl ein'))
for i in range(n):
for j in range(n):
print('x', end='')
print()
Das Rechteck
wird durch eine Reihe von Reihen erzeugt
Die Variable j benötigen wir, weil die Variable i
schon verwendet wird
n = int(input('gib eine ganze Zahl ein'))
for i in range(n):
for j in range(n-i):
print('x', end='')
print()
Das abfallende Dreieck ist wie ein Rechteck
Ihm wird jedoch pro Durchlauf ein Element
abgezogen . Das erreichen wir, indem wir das von
0 an wachsende i vom Anfangswert n abziehen.
Das steigende Dreieck
addiert den steigenden
zum Anfangswert n
n = int(input('gib eine ganze Zahl ein'))
for i in range(n):
for j in range(1+i):
print('x', end='')
print()
Wert
von
Aufgaben zu Kapitel 7
1
Wiederholung in Java
Übersetze die einfache Wiederholung aus Java (Kapitel 7.2.3) in ein Python-Programm.
2
Einfache Wiederholung
Schreibe ein Ratespiel für Windows. Wenn der Spieler das Programm mit Doppelklick öffnet,
wird er nach einer Zahl gefragt. Nur wenn er die richtige Zahl eingibt, endet das Programm.
3
Wiederholung oder Verzweigung
Schreibe ein Programm mit zahl=int(input('Zahl')), das mit der Wiederholung
while zahl>0 ab dieser Zahl aufsteigend alle Zahlen ausgibt.
1) Kläre: Welcher Bedingung muss erfüllt sein, damit diese Aufgabe kein Problem erzeugt?
2) Ersetze die Wiederholung mit while True und dann durch die Verzweigung mit
if zahl>0: und break. Kläre den Unterschied zu Aufgabe 3a.
3) Kläre, ob die gleichen Effekte auch bei der Wiederholung mit for entstehen können.
36
i
ooP mit Python
Kontrollstrukturen
Die Wiederholung mit Zähler und mit fester Anzahl
1) Baue ein Spiel mit Zahlen oder Wörtern, das nach einer bestimmten Anzahl von Runden
automatisch abgebrochen wird. Es gibt verschiedene Möglichkeiten!
2) Ergänze die Division aus Kapitel Kapitel 7.2.7 Multiplikation und Divison als Wiederholung)
um eine geeignete print()-Funktion und teste sie mit unterschiedlichen Dividenden und Divisoren. Überlege, wie man eine Division mit Nachkommastellen erstellen könnte.
3) Schreibe eine Multiplikation mit Hilfe der Wiederholung mit for, die nur mit der Addition
arbeitet.
4
Verzweigung
Bestimme den Verzweigungstyp der folgenden Aussagen:
1) 'Wenn im Kino ein guter Film läuft, gehe ich ins Kino, sonst gehe ich spazieren'
2) 'Ich ehe spazieren. Wenn der Bäcker offen hat, bringe ich ein Brot mit.'
3) 'Wenn Hans kommt, gehen wir alle miteinander essen, wenn nicht, können wir beide (wenn
du willst) ins Kino gehen oder etwas anderes unternehmen. Sonst bleibe ich zuhause.'
4) Erkläre mit eigenen Worten anhand der Aufgaben 3a-c, weshalb wir die einfache Verzweigung von der Alternative unterscheiden.
5) Erläutere die unterschiedliche Wirkung der beiden Programmfragmente:
e1)
e2)
x = 'Test'
while input('test:')!='test':
print('kein Test')
print(x)
5
x = 'Test'
if input('test: ')!='test':
print('kein Test')
print(x)
Die Mehrfachverzweigung
1) Erweitere das Programm aus Kapitel 7.3.4 Mehrfachverzweigung und Kombination von Wahheitswerten so, dass der Fahrer nach Coburg fahren muss, wenn es am Kreisel kein Schild
'nach Muenchen' gibt.
2) Überlege und begründe: Ist es möglich, dass der Fahrer bei der Mehrfachverzweigung nie
wieder aus dem Kreisel herauskommt?
6
Modulo-Rechnung
1) Überlege, mit welche Berechnung jede Zahl darauf geprüft werden kann, ob sie gerade ist.
Schreibe ein Programm, das jede mit int(input()) eingegebene Zahl auf gerade /
ungerade prüft und je nach Ergebniss 'ist gerade' oder 'ist ungerade' ausgibt.
2) Eine Ampel schaltet von rot auf rot-gelb, auf grün, auf gelb, auf rot. Die vier Möglichkeiten
sind mit 0 bis 3 durchnummeriert. Ein interner Zähler zählt ohne Ende von 0 aufwärts. Mit
welcher Teilung kannst du dafür sorgen, dass er nach dem Wert 3 wieder den Wert 0 ausgibt, egal wie weit er bereits gezählt hat. Schreibe das Programm.
37
ooP mit Python
Einfache Algorithmen
8
Einfache Algorithmen
8.1
Algorithmus
Die Bezeichnung Algorithmus für eine bestimmte
Gruppe von Rechenvorschriften ist von Mohammed alChwarizmi abgeleitet, dem Namen eines iranische Wissenschaftler aus dem 9.Jahrhundert. In der lateinischen
Übersetzung seines Mathematik-Lehrbuchs Rechnen mit
indischen Ziffern wurde sein Name mit Algorismi wiedergegeben. Im Mittelalter glaubte man, er sei ein griechischer Meister der Zahlen (gr. arithmos) gewesen mit
dem Namen Algus. So entstand der Begriff Algorithmus.
Abbildung 1: Denkmal für al-Chwarizmi
in Chiwa (Usbekistan)
Für die Informatik sind die Algorithmen wichtig: Alles, was als Algorithmus beschrieben
werden kann, kann auch als Programm notiert werden und dann (prinzipiell) mit einen
Rechner berechnet werden.
Ein Algorithmus lässt sich mit vier Merkmalen beschreiben:
•
•
•
•
Er ist eine Verarbeitungsvorschrift (ausführbar)
Er ist als Programmtext in sich abgeschlossen (endlich)
Er erreicht sein Ziel in einer endlichen Anzahl von Schritten (terminiert)
Er führt bei gleichen Bedingungen immer zum gleichen Ergebnis (determiniert)
8.2
Beispiele
8.2.1
Der größte gemeinsame Teiler (euklidischer Algorithmus)
In einer Mathematikaufgabe kommen manchmal seltsame Brüche vor, z.B.:
323
247
-
133
95
+
456
152
*
133
56
=?
Sie schauen auf den ersten Blick sehr unangenehm aus - wenn man nur den richtigen
Teiler wüsste! Dafür gibt es einen uralten Algorithmus. Die älteste Beschreibung dafür
stammt von dem griechischen Mathematiker Euklid.
Die folgende Beschreibung lässt sich leicht in ein Programm umwandeln:
Nimm zwei Zahlen. Solange beide Zahlen ungleich sind, ziehe die kleinere von der größeren ab und ersetze die größere durch das Ergebnis. Sind beide Werte gleich, ist der
größte gemeinsame Teiler der beiden Zahlen gefunden.
38
ooP mit Python
Einfache Algorithmen
8.2.2
Bubble Sort
Das Märchen vom Aschenputtel erzählt schon kleinen
Kindern von der eher unangenehmen Aufgaben des
Sortierens. Glücklich, wer fleißige Helfer findet. Zum
Glück brauchen wir keine Tauben, um beliebige Werte
zu sortieren. Es gibt viele Sortier-Algorithmen. Manche arbeiten besonders schnell, andere sind leichter zu
verstehen.
Ein langsamer, aber gut beschreibbarer Sortieralgorithmus ist Bubble Sort. Er lässt die Werte Schritt
Abbildung 2: Aschenputtel ruft die Tauben für Schritt wie Luftblasen im Glas aufsteigen, bis sie in
(Ludwig Richter)
der richtigen Reihenfolge liegen.
1. Nimm den ersten Wert aus eine Reihe von Werten. Vergleiche ihn mit seinem
Nachfolger. Stehen sie nicht in der richtigen Reihenfolge, sollen beide Werte
ihre Plätze tauschen.
2. Mache das Gleiche mit dem zweiten Wert bis zum vorletzten Wert in dieser
Reihe (Beachte: Dabei kann der ständig getauschte erste Wert immer wieder
dabei sein!).
3. Lasse die Schrittfolge 1 bis 2 dann mit dem zweiten, danach mit dem dritten
usw. bis zum vorletzten Wert beginnen.
4. Zum Abschluss stehen alle Werte sicher in der richtigen Reihenfolge
Aufgaben zu Kapitel 8
1
ggt
1) Wandle die Beschreibung des ggt in Pseudocode um und programmiere den Algotithmus mit
Python.
2
Bubble Sort
1) Spiele mit deinen Mitschülern sortieren: nach Alter, Schuhgröße oder was euch gerade einfällt. Kläre, weshalb ihr wesentliche schneller sotieren könnt, als der Bubblesort-Algorithmus.
2) Spiele den Bubblesort-Algorithmus mit verdeckten Karten. Dabei dürfen gleichzeitig nur zwei
nebeneinander liegende Karten aufgedeckt sein. Kläre, weshalb diese Spielweise eher der
Arbeit eines Computers entspricht.
3) Wandle die Beschreibung des Bublbe Sort in Pseudocode um und programmiere ihn mit
Python. Verwende dazu eine veränderliche Liste.
39
ooP mit Python
Strukturiertes Programmieren
9
Strukturiertes Programmieren
9.1
Blackbox-Prinzip
Funktionen haben wir bereits in der Tabellenkalkulation verwendet. Nach dem
Blackbox-Prinzip haben wir ihre interne Arbeit aber nicht betrachtet. Nachdem wir die
Prinzipien des imperativen Programmierens kennen, können wir ab sofort selbst Funktionen schreiben, indem wir einfache Sequenzen oder Algorithmen in Funktionen verwandeln.
Wir geben der Funktion einen Namen und ergänzen ihn um eine Parameterliste. Das ist
der Funktionskopf. Dann fügen wir die Sequenz bzw. den Algorithmus unter dem Funktionskopf als Block ein. Ab sofort kann dieses Programm mit einem einzigen Funktionsaufruf zum Laufen gebracht werden.
def
funktion(beliebige,Menge,an,Parametern):
Funktionskopf
Programm
Block:
Funktionskörper
funktion(pro,Parameter,ein,Wert)
Funktionsaufruf
Funktionen helfen uns, doppelten Code und damit typische Fehlerquellen zu vermeiden.
Die Dreiecke im Beispiel unten (vgl. Kap. 7.4 Geschachtelte Kontrollstrukturen S.36)
können nun beliebig oft mit unterschiedlichen Argumenten aufgerufen werden. Die Programmstruktur ändert sich nicht mehr, wohl aber die Ausgabe.
Im Beispiel-Programm Dreieck ersetzt jeder Aufruf der 11-zeiligen Funktion dreieckschreiben() ein Programm, das aus vier Zeilen besteht. Ein Programm mit vier Funktionsaufrufen benötigt also 15 Code-Zeilen und damit bereits eine Zeile weniger als ein
Programm, das ohne Funktionen das Gleiche erreichen soll
Beispiel:
Dreieck
# Funktion
def dreieckSchreiben(groesse,zeichen,richtung=1):
if richtung >= 0:
for i in range(groesse):
for j in range(groesse-i):
print(zeichen, end='')
print()
else:
for i in range(groesse):
for j in range(1+i):
print(zeichen, end='')
print()
# Aufruf
dreieckSchreiben(3,'z',-1)
dreieckSchreiben(3,'#')
40
Definition der Funktion mit drei Parametern, der dritte Parameter ist
vorbelegt.
Das (auf der Spitze stehende) Dreieck
wird standardmäßig ausgeführt
Das (auf der Basis stehende) Dreieck
wird ausgeführt, wenn das dritte
Argument (richtung) negativ ist.
ooP mit Python
9.2
Strukturiertes Programmieren
Funktion ohne Rückgabewert (Prozedur)
Argument
def potenz(zahl):
x = zahl**zahl
print(x)
Das Argument wird
verarbeitet
potenz(2)
Aufruf der Funktion
Haben wir ein prozedurales Programm oder einen Programmteil in eine Funktion
gepackt, die vereinfacht aufrufen können, sprechen wir auch von einer Prozedur.
9.2.1
Die verdeckte Variable
Eine Prozedur empfängt Werte von außerhalb über die Parameterliste und kann sie verändern. Sobald die Prozedur beendet wird, verschwinden auch die geänderten Werte: Die
Variable innerhalb der Prozedur ist also für den Rest des Programms verschattet.
Außerhalb der Prozedur
varA = 10
def prozedur(varA):
varA = varA+20
print(varA)
prozedur(varA)
print(varA)
Beispiel:
Was innerhalb der Prozedur geschieht,
außerhalb nicht sichtbar und nicht wirksam
ist
Außerhalb der Prozedur
Verschattung
# Färben
← Parameterliste
def faerben(auto):
vor dem Färben: schwarz
print('vor dem Färben',auto)
auto = 'weiss'
print('nach dem Färben', farbe) nach dem Färben: weiss
auto='rot'
print('vor Prozeduraufruf', auto)
faerben(auto)
print('nach Prozeduraufruf', auto)
vor dem Aufruf schwarz
Funktionsaufruf
nach dem Aufruf schwarz
Innerhalb der Prozedur wird
der Wert verändert und neu
aufgerufen.
Außerhalb der Prozedur
bleibt der Wert unverändert
Funktion ohne Rückgabewert (1): Nur der kopierte Wert wird bearbeitet (2 / 3). Danach
wird der Wert vergessen. Das Programm arbeitet mit dem unveränderten Wert weiter (4).
41
ooP mit Python
Strukturiertes Programmieren
9.3
Funktion mit Rückgabewert
9.3.1
Das return-statement
Wollen wir, dass die geänderten Werte auch im weiteren
Programmablauf gelten sollen, müssen wir einen Ausgang
zur Verfügung stellen: das return-Statement. Sobald das
return-Statement erreicht wird, wird die Arbeit der Funktion
abgebrochen. Der Wert, der zum return-Statement gehört,
wird an die aufrufende Stelle zurückgegeben.
Wir können Funktionen also als Werterzeuger verwenden
und deshalb auf der rechten Seite einer Zuweisung einsetzen.
Beispiel:
Funktion
# Färben
def faerben(farbe):
print('vor dem Färben',farbe)
farbe = 'weiß'
print('nach dem Färben', farbe)
return farbe
← Eingang: farbe
vor dem färben
neue Farbe wird zugewiesen
nach dem färben: weiß
Ergebnis ausgeben
vor Modulaufruf: schwarz
farbe = 'schwarz'
print('vor dem Modulaufruf', farbe)
Ergebnis zuweisen
farbe = faerben('weiß')
print('nach dem Modulaufruf', farbe)
nach Modulaufruf: weiß
9.3.2
return-Statement
Der Parameter ist die
Türe, über die Werte
aufgenommen werden
Das return-Statement
schickt den Wert aus tank
an die aufrufende
Funktion
Eine Zuweisung holt den
neu erzeugten Wert der
Farbe in die alte
Variable
Vergleich zur Tabellenkalkulation
Die Funktion mit Rückgabewert entspricht der in der Tabellenkalkulation verwendeten
Funktion. Dort wird die Funktion auf der Eingabeebene eingesetzt. Das '=' markiert in
der Tabellenkalkulation, dass der erzeugte Wert an die Ausgabeebene übergeben wird.
Dieses Verhalten entspricht der einfachen Zuweisung.
Argument
def potenz(zahl):
x = zahl**zahl
return x
Das Argument wird
verarbeitet
}
Der Rückgabewert ersetzt den Aufruf der Funktion
variable = potenz(2)
Aufruf der Funktion
42
ooP mit Python
Beispiel:
Strukturiertes Programmieren
Funktionen ohne Rückgabewert
def testProdzedur1():
print('Prozedur ohne Parameter')
Funktionskopf mit leerer Parameterliste
Der Funktionskörper bzw. Funktionsbblock enthält die
auszuführenden Anweisungen
def nameSchreiben(name, info):
print(info, name)
Funktion mit Parameter, der im Block verwendet wird
# Prozeduraufrufe
testProzedur1()
nameSchreiben('erster','Test')
Der Aufruf der Funktion bzw. Prozedur geschieht durch
den Aufruf des Funktionsnamens
Eine Funktion, die einen Parameter verlangt, muss auch
mit einem Argument versorgt werden.
Wortschatz: Funktionen
Funktion ohne Rückgabewert
man kann auch sagen:
Funktion mit leerem Rückgabewert
def prozedur(parameter):
<Programm-Block>
Ausgabe durch die
Anweisung im
Programm-Block
print(prozedur(meinPar))
Ausgabe: None
def funktion(parameter):
<Programm-Block>
return wert
Ausgabe des
return-Wertes
Funktion mit Rückgabewert
Beachte:
Der return-Wert darf auch eine Liste sein
print(funktion(meinPar))
Ausgabe: wert
Die Funktion mit Rückgabewert ist ein
Wert-Erzeuger. Der von ihr ausgegebene
Wert kann weiterverarbeitet werden.
9.3.3
Ausblick: Funktionen und Methoden
Funktionen ohne Rückgabewert und Funktionen mit Rückgabewert tauchen bei den
Methoden in der objektorientierten Programmierung wieder auf: Methoden ohne Rückgabewert bekommen dann als setMethoden die Aufgabe Werte zu speichern, Methoden
mit Rückgabewert werden dann als getMethode zur Ausgabe von Werten verwendet.
9.3.4
Benannte Parameter
Bei den Parametern handelt es sich um Variablen, die solange gelten, wie die Funktion
arbeitet. Eigentlich müssen sie genau in der Reihenfolge befüllt werden, wie sie in der
Funktion deklariert sind. Werden die Parameter allerdings mit ihrem Namen aufgerufen,
muss die Reihenfolge nicht mehr eingehalten werden
Lexikon: Benannte Parameter
def drucken(text1, text2) :
print(text1,text2)
Die beiden Parameter sind in ihrer Reihenfolge
festgelegt und werden vom print()-Befehl
ausgewertet.
drucken(text2='zweiter Text',
text1='erster Text')
Weil die Parameter benannt sind, kann die
Reihenfolge umgekehrt werden
43
ooP mit Python
9.3.5
Strukturiertes Programmieren
Überladene Parameter
Jedem Parameter einer Funktion muss beim Aufruf der Funktion auch ein Argument
übergeben werden. Wird jedoch ein Paramter mit einem Wert vorbelegt ( par =
'Wert'), dann arbeitet die Funktion mit dem vorgegeben Wert, solange diesem Parameter beim Aufruf der Funktion kein Argument zugewiesen wurde.
Lexikon: Überladene Parameter
def drucken(a, b='nix') :
print(a,b)
Der überladene Parameter muss immer zum Schluss
deklariert werden
drucken('x')
drucken('y','da steht doch was')
Die Funktion drucken kann mit einem oder mit zwei
Parametern aufgerufen werden
9.3.6
Listen als Parameter
Manche Funktionen erwarten Listen als Parameter. Übergibt der Nutzer jedoch nur einen
einfachen Wert, verweigert die Funktion ihren Dienst und zwingt das Programm zum
Abbruch. Um dieses Problem zu umgehen, gibt es für Python eine besondere Form des
Parameters. Sie stellt aus allen Werten, die ihr übergeben werden, eine unveränderliche
Liste zusammen. Diese Form des Parameters wird mit einem Stern markiert.
Wortschatz: Listen als Parameter
def listenFunktion1(listPar):
for e in listPar:
print(e,end=',')
return 'fertig'
# Aufruf:
listenFunktion1([2,3,4,5])
# Ergebnis:
2,3,4,5
Diese Funktion will hier eine Liste abarbeiten.
Problem: Wurde keine Liste, sondern eine Zahl
übergeben, stürzt die Funktion ab.
def listenFunktion2(par,*listPar,pr):
print(par)
print(pr)
return listPar
# Aufruf
print(listenFunktion2(1,2,3,4,5,pr=6))
# Ergebnis:
1
6
(2, 3, 4, 5)
Der Listenparameter wird mit einem * markiert. Ihm
können beliebig viele Werte zugewiesen werden.
def listenFunktion3(*listPar):
listPar = list(listPar)
listPar.reverse()
print(listPar)
# Aufruf
listenFunktion3(2,3,4,5)
# Ergebnis
[5, 4, 3, 2]
Folgt auf den Listenparameter ein weiterer Parameter,
muss er bei der Übergabe der Argumente ausdrücklich
als benannter Parameter aufgerufen werden, sonst kann
ihm kein Wert zugewiesen werden.
Sollen die Werte aus dem Listen-Parameter weiter
bearbeitet werden, muss die unveränderliche Liste mit
Hilfe der list()-Funktion in eine veränderliche Liste
umgewandelt werden.
44
ooP mit Python
Strukturiertes Programmieren
9.4
Für Profis: Funktionen der Tabellenkalkulation
9.4.1
Einfache Verschlüsselung
Die einfache Caesar-Verschlüsselung ersetzt jedes Zeichen des Alphabets durch ein um
einen bestimmten Wert versetztes anderes Zeichen des Alphabets. So wird aus dem A
durch die Funktion caesar(A,3) der Buchstabe D, aus W würde wiederum A. Um dieses
Verschlüsselung zu programmieren, könnten wir die Zeichen des Alphabets in eine Liste
alphabet packen. Auf das Zeichen A würden wir normalerweise mit alphabet[0+Verschiebewert] zugreifen. Um bei dem Zeichen W (also dem Zeichen alphabet[22]) wieder
auf das A (also alphabet[0]) zu kommen, muss man den Verschiebewert mit Modulo 26
(für die 26 Zeichen des Alphabets) teilen. Alternativ könnte man auf die ASCII-Werte
zugreifen: print(chr(ord('A')+3)). Wird jedoch ord(Zeichen)+Verschiebewert größer als
90 (ord(90)=> Z), müsste der Wert 26 abgezogen werden.
Übrigens: In der Tabellenkalkulation ist die Caesar-Verschlüsselung als rot(13) zu finden. Sie rotiert das Alphabet um den Wert 13.
9.4.2
Uhrzeit, Datum, Geld und Kommazahlen
Unsere Uhrzeit richtet sich ja nicht nach dem bei uns gebräuchlichen Dezimalsystem.
Die Sekunden und Minuten erzeugen erst beim Wert 60 den Übergang zur neuen Minute
bzw. zur neuen Stunde. Bei den Stunden geschieht der Übergang zum neuen Tag bereits
beim Wert 24. Der Monatsübergang ist abhängig von der Länge des jeweiligen Monats,
im Februar sogar davon, ob gerade Schaltjahr ist oder nicht.
Eine Funktion neueUhrzeitAusgeben(jetzt,dauer) müsste also bei den Parametern jetzt
und dauer eine Liste mit den Argumenten jahr, monat, tag, stunde, minute, sekunde
erwarten. Die Berechnung beginnt bei den Sekunden. Falls die Addition der Sekunden
der Wert 59 übersteigt, wird der Minutenwert um den Wert 1 gehoben und das Sekundenergebnis um 60 gesenkt. Entsprechend werden dann die Minuten, Stunden, Tage,
Monate und Jahre berechnet und dann als Liste ausgegeben.
Das gleiche Prinzip kann vereinfacht für jede Währung angewendet werden. Bei der
Funktion neueGeldmengeAusgeben(alterWert,aenderung) werden dann die Euro- und
Cent-Beträge getrennt behandelt.
Mit der Funktion ganzzahlUndRestDivision(dividend,divisor) die eine Liste
[ganzzahl,rest] ausgibt, können wir Kommazahlen bis zu eine bestimmten Länge nach
dem Komma berechnen. Ist der Rest größer als 0, wird dieser Rest mit dem Faktor 10
multipliziert und der Funktion wieder übergeben. Das ganzzahlige Ergebnis wird dann
mit 100AnzahlDerVersuche dividiert und zum Gesamtergebnis addiert.
45
ooP mit Python
9.5
Strukturiertes Programmieren
Für Profis: Ausnahmebehandlung
Laufzeitfehler sind nie zu vermeiden, deshalb bietet jede Programmiersprache die Möglichkeit der Fehlerbehandlung an. Wenn ein Python-Programm abstürzt, gibt es eine Fehlermeldung aus. Diese Fehlermeldung kann man abfangen und das Programm so weiterlaufen lassen, als sei kein Fehler aufgetreten. Genaueres finden Interessierte im Netz:
http://www.python-kurs.eu/ausnahmebehandlung.php
Aufgaben zu Kapitel 9
1
Funktionen ohne Rückgabewert
1) Eine Ampel bekommt vier Werte übergeben (rot, rot-gelb, gelb, grün). Sie schaltet danach die
Ampel. - Verwende einmal vier Parameter und einmal einen einzigen Listenparameter.
2) Eine Ampel erwartet einen Zahlenparameter (2 bzw. 4). Danach erzeugt sie eine Fußgängerampel mit den Werten rot und grün bzw. eine Ampel für den Autoverkehr.
3) Lege zwei Funktionen Sommerabend1 und Sommerabend2 an, die den folgenden Text
bearbeiten:
An einem lauen Sommerabend fuhr ein verwegener Bursche mit seinem feuerroten
Rennwagen behäbig auf der ruhigen Landstraße auf die rotglänzend untergehende
Sonne zu.
Die Funktion Sommerabend1 verlangt die Übergabe von sechs Argumenten, die dann als
Adjektiv-Variablen verwendet werden.
Die Funktion Sommerabend2 verlangt die Übergabe einer Liste mit beliebig vielen Adjektiven, die dann als Adjektiv-Variablen verwendet werden.
2
Mit oder ohne Rückgabewert?
1) Entscheide - Welche der folgenden Aufgaben würdest du als Funktion mit Rückgabewert entwerfen, welche als Funktion ohne Rückgabewert? Begründe deine Entscheidung.
Reinigung der Wäsche, Ware ausliefern, eine Nachricht schreiben, Informationen auf dem
Bildschirm ausgeben, telefonieren, Kleidung färben, Einkaufen gehen
2) Schreibe zwei Funktionen einkaufen1 und einkaufen2, die erste mit Rückgabewert,
die zweite ohne Rückgabewert. Übergib beiden Funktionen eine Einkaufsliste. Die Funktionen wählen zufällig viele Produkte aus (Kapitel 10.2.1 Zufallswerte). Das Ergebnis soll auf
den Bildschirm ausgegeben werden.
3
Algorithmus-Funktionen
1) Packe den ggT (Aufgaben zu Kapitel 8) in eine Funktion mit dem Funktionskopf
ggT_berechnen(wert_1,wert_2). Sie schreibt das Ergebnis auf den Bildschirm.
2) Packe den Bubblesort-Algorithmus (Aufgaben zu Kapitel 8) in eine Funktion
bubbleSort(liste). Sie erwartet eine unsortierte Liste als Parameter und gibt eine
sortierte Liste an die aufrufende Stelle zurück.
46
ooP mit Python
Modulares Programmieren
10
Modulares Programmieren
10.1
Modul – import
Die Beispielprogramme, mit denen wir bisher gearbeitet haben, hatten nur ganz wenige
Zeilen an Programm-Code. Die freie Bürosoftware LibreOffice dagegen besteht aus
mehreren Millionen Codezeilen. Um so große Programme pflegen zu können, werden
auf verschiedene Dateien (Module) aufgeteilt. So besteht etwa LibreOffice aus mehreren
tausend Modulen.
Auch in Python können wir unsere Programme in Module zerlegen und als Programmteile anderen Programmen zur Verfügung stellen. Das Modul muss nur noch durch eine
entsprechende Anweisung importiert werden: import modul. Mehrere zu importierende Module trennen wir mit Komma voreinander: import modul1, modul2.
Beispiel:
Programm importieren
Datei: ichLassePrinten.py
Datei: ichPrinte.py
print('Das kommt raus')
import ichLassePrinten
Import
→
Der Aufruf
ichPrinte.py
erzeugt die Ausgabe: Das kommt raus
Wir können unsere eigenen Programme in Module zerlegen. Aber es gibt auch fertige
Module, die wir importieren können. So können wir unsere Python-Programme um interessante Funktionen erweitern. Viele dieser Module sind für Python schon vorbereitet.
Eine vollständige (englische) Informationen zu diesen Modulen ist im Web zu finden:
http://docs.python.org/3/ → Library Referenz
Die Python-IDLE führt über den Menü-Eintrag help → Python Docs (F1) ebenfalls auf
diese Seite.
10.2
Lexikon wichtiger Python-Module
10.2.1
Zufallswerte
import random
Das Modul Zufallszahlen
stellt verschiedene Funktionen zur Verfügung
random.randint(2,11)
random.choice([1,2,3,'a','b','c'])
random.shuffle([1,2,3,'a','b','c'])
random.random()
- erzeugt eine zufällige ganze Zahl von 2 bis 11
- wählt aus einer vorgegebenen Menge eine zufälligen
Wert
- schüttelt die Werte in einer Liste durcheinander
- gibt eine Float zwischen 0.0 und 1.0 aus
47
ooP mit Python
10.2.2
Zugriff auf das Betriebssystem (platform, os)*
import platform
platform.system()
Ergebnis: Linux, Windows oder Darwin
(für den Mac)
import os
os.system('cmd') unter Windows
os.system('clr') unter Windows
os.system('mkdir testOrdner')
os.system('shutdown -r -t 0')
10.2.3
Modulares Programmieren
Das Betriebssystem erkennen
abhängig vom erkannten Betriebssystem können
bestimmte Befehle ausgeführt werden, die nur auf
diesem Betriebssystem zur Verfügung stehen
Die Betriebssystem-Funktionen
- öffnet die Befehlseingabe
- löscht die Einträge auf der Konsole
- legt einen Ordner an
schaltet unter Windows den Rechner aus
-t 0 steht für: nach 0 Sekunden
Zugriff auf das Laufzeitsystem (sys)*
import sys
datei = open('dateiname', 'w')
datei = open('dateiname', 'r')
datei = open('dateiname', 'a')
Das Laufzeitsystem
ist unter anderem für das Anlegen von Dateien
zuständig
legt eine neue Datei unter dem Namen an
öffnet eine Datei nur zum lesen
öffnet eine Datei, um Daten anzuhängen
datei = opend('datei','r')
inhalt= datei.readlines()
datei.close()
eine geöffnete Datei wird zeilenweise ausgelesen und in
der Variablen inhalt als Liste gespeichert
Danach wird die Datei wieder geschlossen
datei = opend('datei','w')
for e in inhalt:
datei.write(str(e))
datei.close()
Eine Datei wird neue angelegt oder überschrieben.
Die Elemente aus der Variablen inhalt werden in einen
String umgewandelt und zeilenweise in die Datei
geschrieben.
10.2.4
Das Zeitsystem (time)*
time.localtime()
Zugriff auf die Systemzeit des Rechners
erzeugt einen Tupel mit Informationen über die
regionale Zeit, die auf dem Rechner eingestellt ist.
print(time.localtime()[0])
Schreibt das Jahr auf den Bildschirm
time.localtime()[1]
Monat
time.localtime()[2]
Tag
time.localtime()[3]
Stunde
time.localtime()[4]
Minute
time.localtime()[5]
Sekunde
time.localtime()[6]
Wochentag
time.localtime()[7]
Tag im Jahr
time.localtime()[8]
ist Sommerzeit (nein → 0, ja ->1) – nur, wenn sie beim
Rechner korrekt eingestellt ist
import time
sec = 1
time.sleep(sec)
Lässt den Prozess warten (hier eine Sekunde)
48
ooP mit Python
Modulares Programmieren
Aufgaben zu Kapitel 10
1
Module verwenden
1) Lege ein Programm mit dem folgenden Text an:
An einem lauen Sommerabend fuhr ein verwegener Bursche mit seinem feuerroten
Rennwagen behäbig auf der ruhigen Landstraße auf die rotglänzend untergehende
Sonne zu.
Lege eine Liste mit Adjektiven an und ersetze die markierten Adjektive im Text durch zufällige
ausgewählte Adjektive aus der Adjektiv-Liste. Rufe das Programm mehrfach auf und erkläre
die Unterschiede.
2) Programmiere ein Spiel, bei dem zufällig erzeugte Zahlen erraten werden sollen.
Ist der Wert erraten, wird der Rechner nach so vielen Sekunden heruntergefahren, wie Versuche nötig waren, um den Wert zu erraten.
3) Erstelle ein Zufallspasswort. Verwende eine Liste für Vokale, eine Liste für Konsonanten und
eine Liste für Ziffern (nicht Zahlen! - warum?). Das Passwort mit 6 Buchstaben wird aus den
Listen zusammengestellt. Sorge dafür, dass auch die Reihenfolge der Buchstaben zufällig ist.
Füge dann die Zeichen aus der Liste zu einem String zusammen.
4) Programmiere: Eine Ampel schaltet von rot auf rot-gelb, auf grün, auf gelb, auf rot. Die vier
Lichtmöglichkeiten sind mit 0 bis 3 durchnummeriert. Ein interner Zähler zählt mit modulo-3
und zeigt nach je einer Sekunde den neuen Ampelwert.
5) Datei-Bombe: Erzeuge eine Endlosschleife, in der du eine Datei immer wieder speicherst. Du
kannst z.B. den Dateinamen als Zähler verwenden.
Aber große Vorsicht: Das darfst du wirklich nur dann tun, wenn du sicher weißt, wie du den
Rechner danach wieder retten kannst!
49
ooP mit Python
Klassen und ihre Objekte
11
Klassen und ihre Objekte
11.1
Programmier-Prinzipien
11.1.1
Maschinenabhängig
Programmieren wird vom Maschinencode aufwärts immer einfacher und zugleich immer
komplexer. Der Assembler vereinfacht den Maschinencode durch halbwegs merkbare
(mnemnonische) Befehle. Programmme in Assembler- und Maschinencode können nur
auf dem Prozessortyp eingesetzt werden, für den sie geschrieben wurden.
11.1.2
Problemorientiert
Imperatives und strukturiertes Programmieren löst das Programm von der Maschine.
Jedes Programm, jede Problemlösung, kann prinzipiell auf allen Rechnern laufen. Das
strukturierte Programmieren vereinfacht die Arbeit, indem Teile des Programmcodes zur
Wiederverwendung in Funktionen ausgelagert werden.
11.1.3
Objektorientiert
Die Objektorientierung setzt auf dem Prinzip des Strukturierens auf, arbeitet aber nicht
problemorientiert; denn mit der Verwendung einer Klasse wird gleich eine ganze Gruppe
gleichartiger Teilprobleme lösbar. Eine komplexe Aufgabe wird durch das Zusammenspiel vieler Objekte bearbeitet.
objektorientiertes Programmieren
Löst in einem Programm eine Klasse von Problemen
Strukturiertes Programmieren
wiederverwenden von Programm-Code
Zuweisungen
Sprünge
Lesbar - Die Sprünge werden zu
Verzweigungen und Wiederholungen
Zuweisungen, Verzweigungen und Wiederholungen werden
ausgelagert in Module und Funktionen
Für jede Teilaufgabe wird ein Objekt mit eigenen Werten (Attribute) erzeugt
Objekte kommunizieren über Methoden miteinander (Funktionen <=> Methoden)
50
System
Maschinencode
Nullen und Einsen
an einen Prozessor
gebunden
Problem
Assembler
halbwegs lesbar
Maschine
Imperatives Programmieren
nicht an einen Prozessor gebunden
ooP mit Python
11.1.4
•
•
•
•
•
Klassen und ihre Objekte
Vorteile der Objektorientierung
Ein Aufgabe wird in viele Teilaufgaben zerlegt. Deshalb können verschiedene
Programmierer unabhängig voneinander an einem Projekt arbeiten – Prinzip des
verteilten Arbeitens.
Schlecht programmierte Klassen können ohne Aufwand durch neu programmierte Klassen ersetzt werden, sofern diese Klassen die klar definierten
Schnittstellen verwenden. Wie eine Klasse intern arbeitet spielt keine Rolle –
Prinzip der Datenkapselung.
Fertige Programme können ohne genauere Kenntnis ihrer Programmierung in
unterschiedlichen Zusammenhängen zu unterschiedlichen Zwecken verwendet
werden – Prinzip der Wiederverwendung (Programm-Bibliothek) .
Allgemeine Aufgaben werden durch allgemein gehaltenen Klassen gelöst. Sie
werden zur Lösung konkreterer Probleme durch Ergänzungsklassen erweitert –
Prinzip der Vererbung.
Die Dynamik der Objekte und die Kommunikation zwischen den Objekten
macht die Simulation komplexer Systeme möglich.
11.2
Klassen und Objekte
11.2.1
Reales Objekt und Programm-Objekt
Wer auf einen VW-Golf mit dem Kennzeichen AB-CD 1234 seinen Führerschein
gemacht hat, kann auch einen VW-Golf mit dem Kennzeichen BA-DC 2143 fahren oder
einen Renault mit dem Kennzeichen CO-DE 526, einen VW-Käfer, einen Mercedes
oder einen Rolls-Royce. Wenn also reale Objekte Strukturen und Abläufe haben, die einander sehr ähnlich sind, fassen wir sie zur einer Klasse zusammen.
In der Informatik betrachten wir die Aufgabe in der umgekehrten Richtung. Die informatische Klasse PKW erzeugt beliebig viele VW-Golf-, Käfer-, Mercedes-, Renault- oder
Rolls-Royce-Objekte und legt sie im Arbeitsspeicher ab. Mit diesen Objekten können
dann unterschiedliche Simulationen durchgeführt werden
11.2.2
Objekte handeln nach innen und nach außen
Objekte können als handelnde Subjekte wie als empfangende Objekte beschrieben werden. Wenn sie von einer Klasse erzeugt und einer Variablen zugewiesen werden, bekommen sie deshalb immer ein Nomen als Variablennamen.
Objekte können mit den Methoden, die ihnen ihre Klasse zur Verfügung stellt, Handlungen durchführen. Grammatikalisch betrachtet sind Methoden also Verben. Deshalb
bekommen Methoden immer eine Verbform als Bezeichner.
Bei den Attributen handelt es sich immer um die Eigenschaften eines Objektes, sie
beschreiben, in welchem Zustand sich ein Objekt gerade befindet. Soll ein Attribut
Objekte speichern, bekommt es als Bezeichner ein Nomen, andernfalls ein Adjektiv oder
ein Adverb oder was sonst gerade passt.
51
ooP mit Python
Klassen und ihre Objekte
11.3
Mit Objekten arbeiten: Liste und Turtle
11.3.1
Listen als Objekte
Listen haben wir bereits als Objekte mit ihren Methoden kennengelernt (Kap. 5.7 Methoden eines Listenobjekts). Allerdings haben wir Listenobjekte nur durch eine Aufzählung
erzeugt, indem wir eine bestimmte Menge an Werten als Liste einer Variablen zugewiesen haben: b = [1,2,3]. Das konnte auch die leere Menge sein: a = [].
Diese Listen können wir objektorientiert erzeugen, indem wir die Klasse list aufrufen
und debei die Werte als Parameter übergeben: a = list([1,2,3] oder a = list().
11.3.2
Die Turtle
Bevor wir selbst Klassen schreiben, können wir eine Gruppe von Klassen verwenden, die
uns von der Python-Bibliothek zur Verfügung gestellt wird, wie etwa die Turtle.
Die Idee der Turtle-Graphik stammt aus der Programmiersprache Logo, die Seymour Papert in den 1960er
Jahren als kindgerechte Anfängersprache entwickelt hat. Die Turtle, also eine Schildkröte, zieht eine Spur
hinter sich her, die auf den Bildschirm gezeichnet wird. Auf diese Weise ist es möglich, mathemathische
Funktionen mit geringem Aufwand graphisch darzustellen. Gregor Lingl hat die Idee für Python umgesetzt
und das Python-Modul Turtle entwickelt. Hilfreiches dazu ist in seinem Buch Python für Kids zu finden.
Wird nur die Standard-Turtle auf der Konsole ausgeführt, können die unten aufgelisteten
Befehle ohne Bezg zu einem Objekt aufgerufen werden. Andernfalls muss ein Objekt
erzeugt und einer Variablen zugewiesen werden.
Beispiel:
Spirale
>>>from turtle import*
Import des Turtle-Moduls
>>>spirale = Turtle()
>>>punkt = Turtle()
Die Variablen spirale und punkt
bekommen je ein neu erzeugtes TurtleObjekt zugewiesen
>>>punkt.shape('circle')
Das Punkt-Objekt wird als Punkt
(circle) gezeichnet
>>>punkt.write('Hi, ich bin da (der punkt)',
font=('Times New Roman',10))
>>>for i in range(52):
spirale.circle(10+i,45)
Erschließe den Rest des Programms!
Schreibe es auf die Konsole und lass es
laufen.
Die folgende Befehlsreferenz hilft dir
zu verstehen, was dabei passiert.
>>>spirale.write('Aber ich bin jetzt hier',
'(die spirale)',font=('Arial',10))
Auf der Konsole kannst, wie in den
letzten beiden Befehlen auch mit einem
nicht-benannten Objekt der StandardTurtle arbeiten.
>>>pencolor('red')
>>>forward(100)
52
ooP mit Python
Beispiel:
Klassen und ihre Objekte
Von der Linie zum Dreieck, Rechteck und Kreis
# Dreieck / Rechteck
# farbiges Rechteck
# zwei Rechtecke
from turtle import*
from turtle import*
from turtle import*
# main-Bereich
# main-Bereich
def
linie = Turtle()
for i in range(3):
linie.forward(100)
linie.left(120)
bildschirm = Screen()
bildschirm.title('Titel')
line = Turtle()
line.begin_fill()
line.color((0,1,0),'red4')
#line.color('green','red4')
#line.pencolor('red1')
line.pensize(4)
for i in range(4):
line.forward(100)
line.right(90)
line.end_fill()
linie.right(90)
linie.up()
linie.forward(50)
linie.down()
for i in range(4):
linie.forward(100)
linie.left(90)
maleRechteck(n,
linienFarbTupel,
fuellFarbTupel,
hoehe,seite) :
n.penup()
n.goto(hoehe,seite)
n.pendown()
begin_fill()
n.color(
linienFarbTupel,
fuellFarbTupel)
n.pensize(4)
for i in range(4):
n.forward(100)
n.right(90)
end_fill()
# main-Bereich
punkt = Turtle()
tester = Turtle()
maleRechteck(punkt,
(1,0,0),(0,0,1),200,150)
maleRechteck(tester,
(0,0,0),
(0,1,1),
20,15)
Lexikon: Die Python-Turtle
Turtle-Aktionen
t = Turtle()
Erzeugt eine Turtle, die in der Variablen t gespeichert ist
t.forward(40)
die Turtle t zeichnet 40 Pixel vorwärts
t.back(30)
die Turtle t bewegt sich zeichnend rückwärts
t.goto(100,200)
t geht eine Linie zeichnend zum Punkt (100|200)
t.penup()
Stift hoch: Die Turtle t bewegt sich ohne zu zeichnen
t.pendown()
Stift ab: Die Turtle t zeichnet wieder
t.pensize(3)
setzt die Linienbreite der Turtle t auf 3 Pixel
t.circle(30)
t zeichnet einen Kreis mit dem Radius 30 Pixel
t.circle(-20,90)
t zeichnet einen rechtsdrehenden Kreis mit einem Radius
von 20 Pixel und einem Winkel von 90°
t.write('Hallo Welt',font=('Arial', 16))
t schreibt in Schriftart Arial und Schriftgröße 16
t.dot(3,'red')
t zeichnet einen Punkt mit dem Durchmesser 3 Pixel und
der Farbe rot an der aktuellen Position
t.right(90)
t die Turtle dreht sich um 90° weiter nach rechts
t.left(60)
die Turtle t dreht sich um 60° weiter nach links
t.setheading(270)
0 → Ost / 90 → Nord / 180 → West
setzt die Richtung der Turtle t auf 270° (Süd), unabhängig
von der vorher eingestellten Richtung
53
ooP mit Python
Klassen und ihre Objekte
Turtle-Farben
t.color('red','yellow')
die Linienfarbe ist rot, die Hintergrundfarbe ist gelb
Die Farben lassen sich auch durch einen Tupel von drei Zahlwerten für rot, grün und blau erzeugen. Gültig
sind die Werte 0 und 1, sowie alle Kommawerte dazwischen: color((1,0,0),(1,1,0)) ist gleichbedeutend zu
color('red','yellow'). Kommawerte führen zu abgetönten Farben
t.fillcolor('blue')
Setzt die Hintergrundfarbe wird auf blau
t.pencolor((0,0,1))
Setzt die Stiftfarbe auf Blau
end_fill()
Beendet die Füll-Aktion
begin_fill()
Leitet bei füllbaren Formen die Füll-Aktion ein
Turtle-Formen
t.shape('turtle')
legt das Aussehen der Turtle fest ('arrow', 'turtle', 'circle',
'square', 'triangle', 'classic')
t.hideturtle()
Turtle wird unsichtbar
t.showturtle()
Turtle wird sichtbar
stempel=[]
stempel.append(t.stamp())
stempelt den Umriss der Turtle an der aktuellen Position
mit stamp() und speichert die Stempelnummer in stempel
t.clearstamp(stempel[0])
Löscht den Stempel an stempel[0]
t.clearstamps()
t.clearstamps(zahl) #positiveZahl
t.clearstamps(zahl) #negativeZahl
lösche alle, die ersten, bzw. die letzten der Stempel. Wenn
die Klammer leer ist, werden alle gelöscht. Wenn zahl
> 0 werden die ersten zahl Stempel, andernfalls die
letzten zahl Stempel gelöscht
Turtle-Positionen
t.position()
gibt die (x|y)-Koordinaten der Turtle zurück
t.xcor()
gibt die x-Koordinate der Turtle als Float zurück
t.ycor()
gibt die y-Koordinate der Turtle als Float zurück
t.heading()
gibt den Winkel der Turtle zurück
t.distance(x,y)
gibt den Abstand der Turtle zum Punkt (x|y) zurück
Grafikbildschirm
f = Screen()
Weist das Grafikfenster der Variablen 'f' zu
f.title("meine Turtle-Graphik")
Titelzeile im Grafikfenster 'f'
f.setup(width=400, height=300,
startx=0, starty=0)
Das Grafikfenster 'f' wird auf die angegebenen Werte
gesetzt
f.bye()
schließt das Grafikfenster 'f'
t.clear()
f.clear()
löscht die Zeichnung der Turtle t
löscht alles, was dem Grafikfenst 'f' gehört
f.clearscreen()
löscht den Grafikbildschirm des Fenster 'f'
f.reset()
Löscht den Bildschirm,setzt die Turtle wieder an den
Anfang und setzt alle Variablen auf die Anfangs-Werte
54
ooP mit Python
Klassen und ihre Objekte
Turtle-Steuerung
t.speed(wert)
Setzt die Geschwindigkeit der Turtle. Mögliche Werte:
0 → Die Turtle springt zum Zielpunkt
1 – 10 (=max) → von langsam bis schnell
tracer(False)
… Befehlsfolge
tracer(True)
Die Aktionen der Befehlsfolge werden unter Verzicht auf
die Turtle-Spur auf den Bildschirm geschrieben.
Standardmäßig steht der Wert auf tracer(True). Wird
tracer(False) gesetzt, muss am Ende der Wert auf
tracer(True) zurückgesetzt werden.
Turtle-Ereignisse
t.onclick(meineFunktion,btn=1)
Bei Klick mit der linken Maustaste wird die angegebene
Funktion ausgeführt. Die mittlere Maustaste hat die
Nummer 2, die rechte Maustaste die Nummer 3.
t.listen()
Setzt den Fokus auf das Graphikfenster
t.onkeypress(meineFunktion,key='e')
Die Funktion meineFunktion wird bei Drücken der Taste
'e' aufgerufen. Diese Funktion setzt voraus, dass zuvor
t.listen() aufgerufen wurde.
mainloop()
Ruft die Ereignisschleife auf. Er muss in einem Programm
mit Ereignisaufrufen immer als letzte Anweisung notiert
werden.
Aufgaben zu Kapitel 11
Die Turtle testen
1) Teste die Beispiele zur Turtle
2) Erzeuge eine Turtle kreis als Kreis und gib seine Koordinaten mit print() aus.
3) Erzeuge eine nicht sichtbare Turtle nix, die trotzdem das Haus des Nikolaus schreibt
4) Erzeuge eine nicht sichtbare Turtle stern, die einen Stern mit sechs gelben Strahlen
schreibt, die im gleichen Winkel auseinander liegen und der in der Mitte einen roten Punkt hat
5) Schreibe die rechtwinkligen Dreiecke a,b,c,d mit unterschiedlichen Linien und Füllfarben
und füge sie mit der Spitze zusammen.
6) Gestalte eine Landschaft mit Bergen, Wiesen, Äckern, Häusern – deiner Fantasie sind keine
Grenzen gesetzt – Mache dir die Aufgabe leichter, indem du für die einzelnen Elemente je
eine Funktion schreibst
7) Erweitere die Landschaft mit Elementen, die sich bewegen. Verwende dazu deine Kenntnisse
über die Kontrollstrukturen
8) Für Matheprofis: Lasse von der Turtle die Regel a 2+b2=c2 zeichnen. Importiere dazu zusätzlich das Modul math, es stellt die Methoden math.sqrt(x), math.sin(x) zur Verfügung; math.hypot(x,y) berechnet die Hypotenuse direkt. Mit
math.degrees(math.asin(sin(x))) bekommst du den passenden Winkel für
die Funktionen left(winkel) und right(winkel)
55
ooP mit Python
Selbst erstellte Klassen und ihre Objekte
12
Selbst erstellte Klassen und ihre Objekte
12.1
Die einfache Klasse
12.1.1
Klasse, Konstruktor und Objekt
Klassen erzeugen Objekte, die jeweils einen Gegenstand, ein Lebewesen oder eine Idee
repräsentieren. Zuständig für das Erzeugen ist der Konstruktor. Er initialisiert die von der
Klasse zu erzeugenden Objekte, das heißt, er belegt ihre Attribute mit Anfangswerten
und weist den Objekten den Speicherplatz zu. Die von der Klasse erzeugten Objekte können wiederum auf die in der Klasse deklarierten Methoden zugreifen.
Die einfachste Klasse ist die leere Klasse ohne Attribute und Methoden. Ihre Objekte
können nichts und enthalten keine Werte, sie reservieren aber Arbeitsspeicher. Sie repräsentieren gewissermaßen einen beliebigen Gegenstand. Dieses scheinbar sinnlose
Gebilde erweist sich später im Rahmen der Vererbung (Kap. 12.2 Vererbung) als durchaus nützlich.
Wortschatz: Klassen deklarieren – Objekte erzeugen
Java
class Test {
Test(){}
}
Python
class Test:
def __init__(self):
pass
Klassenkopf
Konstruktor
hier mit leerem Block
In Java heißt der Konstruktor wie
die Klasse. Als Methode führt er
eine Parameterliste.
In Python heißt er __init__(self)
Im Parameter self steckt der
Speicherplatz des Objektes
Für die leere Klasse braucht man den Konstruktor nicht zu notieren:
class TestLeer{
}
class TestLeer:
pass
leere Klasse
Ein Objekt wird erzeugt, indem man die Klasse (eigentlich den Konstruktor der Klasse) mit einer Parameterliste aufruft. Dabei müssen so viele Argumente übergeben werden, wie es der Konstruktor der Klasse in
seiner Parameterliste verlangt.
Beim Aufruf der leeren Klasse bleibt die Parameterliste leer:
meinTest = Test()
Ein Objekt der Klasse Test wird
erzeugt der Variablen meinTest
zugewiesen.
Java ist stark getypt. Deshalb darf
die Variable meinTest nur Objekte
der Klasse Test() aufnehmen
Test meinTest = new Test();
56
ooP mit Python
12.1.2
Selbst erstellte Klassen und ihre Objekte
Das Objekt
Objekte sind reservierte Bereiche im Arbeitsspeicher. Zugriff auf das Objekt hat nur, wer
dessen Speicherplatz kennt. Dafür gibt es mehrere Möglichkeiten:
a) Das neu erzeugte Objekt wurde einer Variablen zugewiesen. Der Name des
Objektes ist dann der Variablenname; wir verwenden dafür immer ein Nomen
(Subjekt bzw. Objekt im Satz!) Soll das Objekt auch unter einem anderen Namen
bekannt sein, wird die Referenz der Objektvariablen einer anderen Variablen
zugewiesen (zweiterName = objektName).
b) Ein anonymes Objekt wird keiner Variablen zugewiesen, sondern unmittelbar
nach seiner Erzeugung verwendet und dann wieder verworfen. Sobald der Müllsammler (Garbage Collector) auf ein solches Objekt stößt, wirft er es weg – das
heißt: Er markiert dessen Speicherplatz als freigegeben.
c) Jedes Python-Objekt kann mit der Variablen self1 auf seinen eigenen Speicherplatz zugreifen. Diese Variable entspricht dem Pronomen ich bzw. selbst.
Wortschatz: Der Zugriff auf das Objekt
meinTest = Test()
print(meinTest)
Ergebnis: <__main__.Test object at 0xb62b54ac>
Die Variable meinTest weist auf den
Speicherplatz des Objektes. Sie enthält also
eine Referenz auf das gespeicherte Objekt
print(Test())
Ergebnis: <__main__.Test object at 0xb62b56ec>
Die print()-Funktion verarbeitet ein
anonymes Objekt
neuerName = meinTest
Das Objekt meinTest bekommt einen
weiteren Namen
12.1.3
Methoden und Funktionen
Methoden stellen die Handlungsmöglichkeiten der Objekte dar. In ihrem Aufbau und in
ihren Aufgaben ähneln sie den Funktionen der strukturierten Programmierung. Sie besitzen ebenfalls eine Parameterliste und können Werte verarbeiten bzw. Werte ausgeben.
Beispiel:
Klasse mit einfachsten Methoden
class Test2:
def __init__(self):
pass
Eine einfache Klasse
Es besitzt kein Attribut,
denn der Block des Konstruktors ist leer
def getSpeicherplatz(self):
return self
Die erste Methode gibt den Speicherplatz des
Objektes zurück
def speicherplatzAufBildschirm(self):
print(self)
Die zweite Methode schreibt den Speicherplatz auf
den Bildschirm
def schreibWas(self,irgendwas):
print('Ausgabe: ',irgendwas)
Die dritte Methode schreibt das übergebene
Argument auf den Bildschirm
1 In allen anderen objektorientierten Programmiersprache heißt diese Variable this
57
ooP mit Python
12.1.4
Selbst erstellte Klassen und ihre Objekte
Methoden geben Werte aus
Methoden haben die gleiche Struktur wie Funktionen und können auch wie Funktionen
einen bestimmten Algorithmus kapseln und einen entsprechenden Wert zurückgeben. So
gibt es funktionale Objekte, deren Methoden Standardwerte berechnen, Zufallswerte
erzeugen, Sortierfunktionen ausüben oder den ggT zur Verfügung stellen.
In der Hauptsache jedoch bilden Methoden die Schnittstelle eines Objektes nach außen.
Objekte kommunizieren über diese Methoden. Ein Objekt verwendet seine getMethoden
(Methoden mit Rückgabewert), wenn es von einem anderen Objekt gefragt wird, in welchem Zustand es sich Objekt befindet.
Wortschatz: getMethoden geben Auskunft
class Test3:
def __init__(self):
Diese getMethode verlangt die Übergabe eines
pass
def getAnderenSpeicher(self, andObj): Objektes und fragt das andere Objekt nach dessen
Speicherplatz.
return andObj.getSpeicher()
def getSpeicherplatz(self):
return self
Das andere Objekt antwortet, indem es seine eigene
Methode getSpeicherplatz() aufrufen lässt.
def quadrat(zahl):
return zahl*zahl
Diese Methode gibt das Quadrat zu einer Zahl zurück
ta = Test3()
tb = Test3()
print(ta.getAnderenSpeicher(tb))
12.1.5
Der letzte print-Befehl kann so übersetzt werden:
Das Objekt ta gibt den Speicher des Objektes tb aus
print( Subjekt . Prädikat ( Objekt ) )
Objekte initialisieren - Attribute
Ein Objekt speichert in den Attributen Werte. Diese Werte stellen seinen Zustand dar.
Als Werte können Zahlen, Texte, Listenobjekte oder Objekte gespeichert werden. Die
Struktur der Attribute wird in der Klasse festgelegt.
Wortschatz: Objekte initialisieren
Java
Python
In Java muss ein Attribut
deklariert werden, bevor es vom
Konstruktor initialisiert wird
class Test {
String name //Deklaration
Test(String name){
this.name=name;}
}
class Test:
def __init__(self,name):
self.name = name
Test tstr= new Test('Ich')
tstr = Test('Ich')
58
Python erledigt das in einem
Aufwasch im Konstruktor
Sieht der Konstruktor weitere
Parameter vor, müssen beim
Erzeugen des Objekts passende
Argumente übergeben werden.
ooP mit Python
12.1.6
Selbst erstellte Klassen und ihre Objekte
Geheimnisprinzip
Ein weiterer Unterschied der objektorientierten Programmierung zur strukturierten Programmierung ist das durchgehende Geheimnisprinzip. Wir kennen es im Ansatz schon
von den Funktionen he (Kap. 9.2.1 Die verdeckte Variable). Für die Kommunikation von
Objekten wurde dieses Prinzip jedoch erweitert.
Reale wie informatische Objekte besitzen private Eigenschaften auf die kein fremdes
Objekt direkt zugreifen darf. Seltener gibt es öffentliche Eigenschaften, deren Werte von
jedem anderen verändert werden darf. Die meisten objektorientierten Sprachen markieren
diesen Unterschied mit den Modifikatoren private und public. In Python sind alle Attribute standardmäßig auf public eingestellt, privat-Attribute werden mit dem doppelten
Unterstrich markiert.
Beispiel:
Kasse und Geldbeutel
Das Kassen-Objekt bzw. die Kassererin sollte keinen direkten Zugriff auf das Attribut Geldmenge im
Geldbeutel-Objekt des Käufers haben; es wird auf private gesetzt.
Der Geldbeutel stellt der Kasse nur die Methode bezahlen(preis) als Schnittstelle zur Verfügung.
Wie die Klasse Geldbeutel das Bezahlen umsetzt, geht die Kasse nichts an. Für die Kasse ist nur der returnWert der Geldbeutel-Methode bezahlen(preis)wichtig:
Gibt er (passendes) Bargeld heraus, einen Gutschein oder eine Karte?
Genauso darf das Geldbeutel-Objekt bzw. darf der Kunde keinen direkten Zugriff auf das Attribut
bargeldbestand in der Kasse haben; es wird ebenfalls auf private gesetzt.
Auch die Klasse Kasse stellt dafür die Methode bezahlen(preis) zur Verfügung. Wie die Klasse
Kasse intern mit den verschiedenen Bezahlmöglichkeiten umgeht, geht wiederum den Geldbeutel nichts an.
Wortschatz: Die Modifikatoren private und public
Java
public class Test {
private int zahl
public Test(int zahl){
this.zahl=zahl;
}
Python
Java verwendet die
Modifikatoren public
def __init__(self,zahl): und private
class Test:
self.__zahl = zahl
public int getZahl(){
return this.zahl
}
def getZahlself):
return self.__zahl
public void setZahl(int zahl){
this.zahl = zahl
}
def setZahl(self,zahl):
self.__zahl = zahl
Python verwendet den
doppelten Unterstrich
als private-Modifikator
}
# Hauptprogramm
tester = Test(1)
info = tester.getZahl()
59
nur Objekte der gleichen
Klassse dürfen auf das
mit als private gesetzte
Attribut zugreifen.
ooP mit Python
12.1.7
Selbst erstellte Klassen und ihre Objekte
Methoden, die Werte setzen
Die Attributwerte eines Objektes werden beim Erzeugen des Objekte mit den Werten
vorbelegt, die dem Konstruktor bekannt sind. Sei es, dass sie als Argumente übergeben
wurden, sei es, dass sie im Konstruktior fest verankert sind. Nachdem sich aber der
Zustand eines Objektes in den Attributwerten ausdrückt, müssen diese Attributwerte
auch verändert werden können, wenn das Objekt in einen neuen Zustand wechseln soll.
Dazu dienen die setMethoden. Zu jedem Attribut gehört mindestens eine setMethode.
Normalerweise benötigt sie einen Parameter, der den neuen Wert in Empfang nimmt. In
der setMethode kann aber auch ein Algorithmus angelegt sein, der den alten oder den neu
übergebenen Attributwert nach bestimmten Regeln bzw. unter unterschiedlichen Bedingungen unterschiedlich verändert. Eventuell kann der Algorithmus auch mehrere Argumente verlangen, dann bekommt die setMethode entsprechend viele Parameter.
Soll die Methode ein anderes Objekt veranlassen, seinen Zustand zu verändern, muss die
Referenz auf dieses Objekt als Argument übergeben werden. Dann ruft die setMethode
das andere Objekt auf und weist es an, seinerseits eine bestimmte setMethode anzuwenden. Auch dabei können Argumente übergeben werden.
Wortschatz: setMethoden speichern Werte
Class Test:
def __init__(self,zahl):
self.__zahl = zahl
def setZahl(self,neueZahl):
self.__zahl = neueZahl
def andererSetZahl(self,anderer,neueZahl):
anderer.setZahl(neueZahl)
def plusEins(self):
if self.__zahl<10:
self.__zahl += 1
def andererPlusEins(self,anderer):
anderer.plusEins()
# Hauptprogramm
testA = Test(1)
testB = Test(1)
testA.setZahl(3)
testB.plusEins()
testB.andererPlusEins(TestA)
testA.andererSetZahl(TestB,10)
60
ooP mit Python
12.1.8
Selbst erstellte Klassen und ihre Objekte
Klassen- und Objektdiagramm
Das Erzeugen von Objekten durch eine Klasse lässt sich als Diagramm zeichnen.
Im Objektdiagramm werden nur die Attribute notiert, nicht die Methoden der Klasse.
Leuchte
emL: Leuchte
emL = Leuchte()
int licht
licht = 0
anAusSchalten()
Lok
emma: Lok
emma = Lok('EMMA',emL)
str name
int geschwindigkeit
Leuchte leuchte
name = 'EMMA'
geschwindigkeit = 0
leuchte = emL
int fahren(int geschw)
lichtSchalten()
12.1.9
_1414 = Lok('1414')
...
Kommunikation von Objekten - Sequenzdiagramm
Zunächst empfängt Lok _1414 vom Bahnhof mit grünem Signal die Erlaubnis auszufahren. Lok _1414 fährt
daraufhin mit Geschwindigkeit 10 los und verlässt den Bereich des Bahnhofs
Anschließend bekommt Lok Emma vom Bahnhof mit grünem Signal die Erlaubnis einzufahren. Sie tut das
mit Geschwindigkeit 10. Sie fährt bis zum Signal am Ende des Bahnhofs und wartet dort wieder auf ein grü nes Signal. Außerdem gibt sie ihrer Leuchte den Befehl zu schalten, was die Leuchte auch tut und zurückmel det, dass sie aus ist.
Dieser Ablauf lässt sich als Sequenzdiagramm zeichnen. Die breiten senkrechten Linien
stehen für die Aktivitäts- oder Lebenslinie eines Objektes. Die durchgezogenen Pfeile
stehen für eine Methode, die gestrichelten Pfeile für die Rückkehr der Methode. Solange
die Methode nicht zum Ausgangs-Objekt zurückgekehrt ist, ist das andere Objekt aktiv.
nec: Bahnhof
emma: Lok
emL: Leuchte
_1414: Lok
signal(grün)
fahren(10)
signal(grün)
signalFragen()
fahren(10)
rot
fahren(0)
lichtSchalten()
aus
61
anAusSchalten()
ooP mit Python
12.1.10
Selbst erstellte Klassen und ihre Objekte
Zustand und Zustandsübergang
Ändert ein Objekt mit Hilfe einer Methode seinen Zustand, sprechen wir von einem
Zustandsübergang. Für jedes Objekt gibt es eine begrenzte Mengen an Zustandsübergängen. Sie sind durch die in der Klasse deklarierten Methoden beschrieben. Diese
Zustandsübergänge können als Grafik dargestellt werden.
Beispiel:
Zustandsübergänge des Signals und der Lok
Signal
schalten
Signal: rot
stillle
Signal: grün
gen
aus
n
lege
l
l
i
t
s
Lok
Geschwindigkeit: 0
Licht: aus
fahren: 10
fahren: 0
schalten
Geschwindigkeit: 0
Licht: an
Geschwindigkeit:10
Licht: aus
schalten
fahren: 10
fahren: 0
Geschwindigkeit: 10
Licht: an
Das Signal benötigt nur eine einzige Methode schalten() für die Lichtsignaländerung.
Allerdings gelten für jeden Zustandsübergang andere Regeln. Die Regeln sind von dem
Zustand abhängig, in dem sich das Signal gerade befindet. Es gibt genau einen definierten Anfangszustand (schwarzer Punkt), aus dem heraus das Signal in den Zustand rot
geschaltet wird.
Der (etwas künstliche) Zustand aus wird über die Aktion still-legen() erreicht. Damit hört
das Signal endgültig auf zu existieren Diese Aktion ist aus jedem Zustand heraus möglich. Als Endzustand ist er mit einem doppelten Ring versehen. Aus ihm kommt das
Signal nicht mehr in einen aktiven Zustand zurück.
Die Lok besitzt die Methoden fahren(wert) und schalten(). Sie können vier unterschiedliche Zustände erzeugen. Für die Lok ist kein Endzustand definiert. Bei einem geänderten
Modell mit den Methoden einfahren() und ausfahren() könnte sie aus Sicht des Bahnhofs
durch ausfahren() in den Endzustand geraten.
62
ooP mit Python
12.1.11
Selbst erstellte Klassen und ihre Objekte
has_a-Beziehung
Sind Objekte in den Attributen gespeichert, handelt es sich um ein zusammengesetztes
Objekte, wie etwa Emma, die Duplolok. Wir sprechen von einer einer has_a-Beziehung.
So besitzt die Lok Emma als zusammengesetztes Objekt ein Fahrgestell, eine Führerhaus, einen Schlot, einen Kessel und eine Schürze. Das Führerhaus und das Fahrgestell
sind wiederum zusammengesetzte Objekte. Die has_a-Beziehung können wir graphisch
als Aggregat darstellen. Die als Attribut abhängigen Objekte werden mit einer Raute
markiert. Von den abhängigen Objekten können wieder Objekte abhängen.
Beispiel:
Emma, die Duplolok
class Fahrgestell:
def __init__(self,farbe):
self.farbe = farbe
Deklaration der
Klasse Fahrgestell
class Fuehrerhaus:
def __init__(self,farbe):
self.farbe = farbe
...
class Duplolok:
def __init__(self,name):
self.name = name
self.fahrgestell = Fahrgestell("blau")
self.fuehrerhaus = Fuehrerhaus("rot")
emma = Duplolok('Emma')
Deklaration der
Klasse Fuehrerhaus
Deklaration
der
Klasse Duplolok
Das Objekt emma vom Typ Duplolok mit dem
Attribut Namen und dem Attributwert 'Emma',
enthält ein Objekt der Klasse Fahrgestell und
ein Objekt der Klasse Führerhaus.
Das Objekt emma wird initialisiert
Aggregat
Die Duplolok besitzt ein Fahrgestell und ein Führerhaus.
Das Führerhaus besitzt wiederum zwei Elemente.
63
ooP mit Python
Selbst erstellte Klassen und ihre Objekte
12.2
Vererbung
12.2.1
Die Flexibilisierung bei der Programmierung
Bisher haben wir Objekte betrachtet, die genau eine Funktion erfüllen. Damit sind sie
nicht viel leistungsfähiger als Funktionen. Bei der Vererbung dagegen kann die objektorientierte Programmierung ihre volle Stärke ausspielen. Teilaufgaben, die in mehreren
Klassen die gleiche Rolle spielen, können in Schnittstellen-Klassen ausverlagert werden.
Notfalls werden deren Methoden wieder angepasst, dann sprechen wir von Polymorphie.
Einzelnen Klassen können mit Hilfe
der Spezialisierung allgemeinere Aufgaben übernehmen. Manchmal muss
nicht Zusammengehöriges zusammengefasst, also generalisiert werden. In
allen Fällen müssen wir aber in der
Lage sein, festzustellen, zu welcher
Klasse oder zu welcher Klassen-Hierarchie ein bestimmtes Objekt gehört, weil davon wieder unterschiedliche Aktionen
abhängen.
12.2.2
Typ-Prüfung
Manchmal sollen in einem Listen-Attribut nur Objekte einer bestimmten Klasse (eines
bestimmten Typs) eingelagert werden: So ist das Federmäppchen etwa kein Platz für
Messer und Gabel. Die Methode, mit der Dinge ins Federmäppchen aufgenommen werden, muss also erkennen, ob das tatsächlich tatsächlich z.B. ein Stift ist, der ins Federmäppchen darf: Sie muss also den Typ prüfen.
Beispiel:
Typprüfung
Die Methode type() fragt ein Objekt,
zu welcher Klasse es gehört
>>> print(type(blauerKuli))
<class '__main__.Stift'>
>>> class Federmaeppchen:
def __init__(self):
self.inhalt = []
def aufnehmen(self,stift):
if isinstance(stift,type(Stift())):
self.inhalt.append(stift)
else:
print("Das ist kein Stift!")
>>>
>>>
>>>
Das
f = Federmaeppchen()
f.aufnehmen(blauerKuli)
f.aufnehmen ("Textobjekt")
ist keine Stift!
Die Methode isinstance() prüft, ob ein
Objekt zu einer bestimmten Klasse
gehört und gibt dann True bzw. False
aus.
Der Versuch, einen Text einzufügen,
statt eines Stift-Objektes, wird
abgelehnt
64
ooP mit Python
12.2.3
Selbst erstellte Klassen und ihre Objekte
Spezialisieren
Um ein Federmäppchen zu füllen, können wir die Klassen Bleistift und Kugelschreiber
entwerfen oder Buntstifte, Filzstifte, Füller und viele andere Stifttypen. Nun sind Buntstifte aber keine Bleistifte. Sie haben zwar eine fest eingebaute Mine und werden durch
das Spitzen immer kürzer. Allerdings machen sie beim Radieren Probleme.
Sinnvollerweise beschreiben wir deshalb die Buntstifte und Bleistifte als Sonderfall der
Klasse Holzstift. Sie besitzt das Attribut Mine und die Methode spitzen(), die auf das
Attribut Mine kürzend zugreift. Die Klasse Buntstift verwendet (wir sagen: sie erbt) alle
Eigenschaften und Methoden der Klasse Holzstift und ergänzt sie um das Attribut Farbe
und um die entsprechende getMethode. Die Klasse Bleistift, erbt ebenfalls von der
Klasse Holzstift, ergänzt sie aber um das Attribut Haerte und um die besondere Methode
radieren().
Spezialisierung
Spezialisiert
Holzstift
int laenge
int getLaenge()
spitzen()
erbt von
erbt von
Beispiel:
Buntstift(Holzstift)
str farbe
Bleistift(Holzstift)
int haerte
str getFarbe()
int getHaerte()
radieren()
Spezialisieren
class Holzstift:
def __init__(self,laenge):
self.__laenge = laenge
def getLaenge(self):
return self.__laenge
def spitzen(self):
if self.__laenge > 2:
self.__laenge-=1
print("neue Laenge: ",self.__laenge)
else:
print("Der Stift ist am Ende")
class Bleistift(Holzstift):
def __init__(self,laenge,haerte):
Holzstift.__init__(self,laenge)
self.__haerte = haerte
def getHaerte(self):
return self.__hearte
Zur Klasse Holzstift gehören
- das Attribut laenge
- die zur laenge gehörende getMethode
- und die die Methode spitzen().
Die Klasse Bleistift erbt die
Eigenschaften und Fähigkeiten der
Klasse Holzstift und erweitert sie mit
ihren eigenen Attributen und Methoden.
b = Bleistift(10,2)
b.getLaenge()
65
ooP mit Python
12.2.4
Selbst erstellte Klassen und ihre Objekte
Generalisieren (is_a-Beziehung)
Stark getypte Sprachen wie Java machen bei der Organisation eines Schlampermäppchens Probleme. Buntstift- und Bleistift-Objekte können sich kein gemeinsames Sammelattribut teilen, weil sie zu verschiedenen Klasse gehören. Das Gleiche gilt für Spitzer,
Geld, die Brille und was sonst ins Mäppchen passen sollte. Um dieses Problem zu umgehen, erstellen wir eine Klasse Mäppcheninhalt. Alle Stifte-Klassen erweitertern wir um
die Klasse allgemeinere Klasse Stift. Alle Klassen dieser Elemente, die ins Federmäppchen gehören, erweitern wir um die Klasse Mäppcheninhalt. Dies Oberklassen darf dafür
sogar vollkommen leer sein. Sie stellt ja nur eine Rollen dar, mit der z.B. das Recht ver bunden ist, ins Federmäppchen zu dürfen.
Generalisiert
Diesen Trick nennen wir Generalisieren: Viele Klassen werden mit einer Oberklasse
durch Vererbung verbunden. So erben die Stift-, Lineal- und Spitzerklassen von der
Klasse Mäppcheninhalt alle Attribute und Methoden. Wenn die Objekte der erbenden
Klassen bei der Typ-Prüfung gefragt werden, gelten sie als Mäppcheninhalt und dürfen
ins Federmäppchen. Die Generalisierung wird graphisch durch einen Pfeil dargestellt, der
von der erbenden Klasse zur vererbenden Klasse führt.
Beispiel:
Generalisieren
class MaeppchenInhalt:
pass
Die leere Klasse hilft den Stiften und dem Spitzer,
ins Federmäppchen aufgenommen zu werden.
class Spitzer(MaeppchenInhalt):
def __init__(self):
pass
Die vererbende Klasse wird in Klammern an den
Klassenkopf gehängt.
class Stift(MaeppchenInhalt):
def __init__(self,farbe):
self.farbe = farbe
def schreiben(self):
pass
class Bleistift(Stift):
def __init__(self,laenge):
self.laenge=laenge
b = Bleistift(10)
if isinstance(b,type(MaeppchenInhalt())):
print('darf ins Maeppchen')
ab sofort sind Objekte der Klasse Spitzer und Stift
auch Objekte der Klasse MaeppchenInhalt.
Objekte der Klasse Bleistift sind Objekte der Klasse
MaeppchenInhalt und der Klasse Stift. Als Objekte
der Klasse Stift besitzen sie auch die Methode
schreiben
Die Zugehörigkeit zu einer Oberklasse wird durch
die Typ-Prüfung bestätigt
66
ooP mit Python
12.2.5
Selbst erstellte Klassen und ihre Objekte
Polymorphie
Manchmal passt eine geerbte Methode nicht so ganz zu der erbenden Klasse. Solche
Methoden sollte man anpassen können. Deklariert nun eine Unterklasse eine Methode,
der Oberklasse um, sagen wir, die Methode der Oberklasse wird überschrieben. Ein
Zugriff auf die Methode der Oberklasse ist dann nicht mehr unmittelbar möglich und
muss deshalb extra freigegeben werden. Dazu dient der super-Aufruf. Er führt von der
überschreibenden Methode der Unterklasse zur überschriebenen Methode der Oberklasse:
self.methode()
super(NameUnterklasse,self).methode()
Nachdem aber die Unterklasse nicht weiß, in welcher der (möglicherweise vielen) Oberklassen die entsprechende Methode deklariert ist, ruft sie super!; dann gibt sie ihren eigenen Klassen-Namen und den Speicherplatz des Objektes an, von dem aus die Oberklasse
gebeten wird, ihren Beitrag zu leisten. So kann der Super-Aufruf nach einem möglicherweise langen Weg durch die Oberklassen wieder an die richtige Stelle zurückkehren.
Beispiel:
Polymorphie – Mensakasse, Automat und Kassierer
class Mensakasse:
def __init__(self,geld):
self.__geld = geld
def kassieren(self,geld):
self.__geld = self.__geld+geld
class Geldautomat(Mensakasse):
def __init__(self,geld)
Mensakasse.__init__(self,geld)
pass
def scheineKassieren(self,*scheine)
for schein in scheine:
self.kassieren(schein.getGeld())
def muenzeKassieren(self,*muenzen):
for muenze in muenzen:
self.kassieren(muenze.getGeld())
class Kassierer(Mensakasse);
def __init__(self,geld)
Mensakasse.__init__(self,geld)
pass
def kassieren(self,muenzen,scheine)
geld = 0
for muenze in muenzen:
geld = geld+muenze.getgeld()
for schein in scheine:
geld = geld+schein.getgeld()
super(kassierer,self).kassieren(geld)
derKassierer = Kassierer(100)
derKassierer.kassieren((50,20),(100,20,5,10))
67
Zur Klasse Mensakasse gehört das
Attribut self.__geld, in dem die
übergebene Geldmenge als einfache Zahl
(Variable geld) gespeichert ist.
Sie stellt den folgenden Klassen das
Attribut self.__geld und die
Methode kassieren zur Verfügung.
Der Geldautomat hat einen
Eingabeschlitz für Scheine und einen
Eingabeschlitz für Münzen, deshalb
braucht er zwei Methoden.
Die beiden Methoden des
Geldautomaten verwenden die
gemeinsame Methode kassieren
Der Kassierer dagegen kann Münzen
und Scheine intutiv richtig auszählen,
deshalb nimmt er Münzen und Scheine
gemeinsam an.
Die Klasse Kassierer hat die Methode
kassieren mit einer neuen Parameterliste
überschrieben. Deshalb muss sie die
Methode der Oberklasse extra aufrufen.
Das Kassierer-Objekt tut nach außen so,
als gebe es nur eine Methodde kassieren
ooP mit Python
Selbst erstellte Klassen und ihre Objekte
Wortschatz: Vererbung
# type(objekt)
print(type('Text'))
# isinstance(objekt,Klasse)
print(isinstance('Tex',str))
Typprüfung
prüft, zu welcher Klasse ein Objekt gehört
fragt, ob ein bestimmtes Objekt zu einer bestimmten
Klasse oder Klassenhierarchie gehört
gibt True oder False aus
class X:
pass
class Y(x)
pass
Erben
Die Klasse x ist die Oberklasse der Klasse y
Die Klasse y erbt von der Klasse x alle Attribute und
Methoden
class A:
def __init__(self,attr):
self.__attr = attr
Attribute der Oberklasse
Die vererbende Klasse verlangt ein Argument, wenn
sie ein Objekt erzeugen soll,
deshalb
muss an der ersten Stelle im Konstruktor der
Unterklasse der Konstruktor der Oberklasse aufgerufen
werden.
class B(a):
def __init__(self,attr):
a.__init__(self,attr)
pass
class Dora:
def __init__(self):
pass
def methode(self):
print('ich da oben')
class Emil(Dora)
def __init__(self):
pass
def methode(self):
print('ich da unten')
super(Dora,self).methode()
e=Emil()
e.methode()
12.2.6
Der super-Aufruf
Die Oberklasse besitzt eine Methode, die den gleichen
Namen trägt, wie die Methode der Unterklasse (die
Methode der Oberklasse wurde überschrieben)
Sollen die die Methode der Unterklasse und auch die
der Oberklasse aufgerufen werden, muss die
Unterklasse den Super-Aufruf verwenden.
super: gehe zur Oberklasse
(Unterklasse,self): Die Unterklasse und das
Aufrufende Objekt werden genannt
.methode(): jetzt erst wird die Methode gerufen
Schnittstellen
Nicht alle Gegenstände, die wir zum Schreiben verwenden, sind ursprünglich zum
Schreiben gedacht. So kann eine Taschenlampe mit einer zusätzlichen Funktion Schreiben ausgestattet sein oder ein Lineal mit der Funktion Radieren. Eine Spardose kann mit
einem Spitzer verbunden sein, ein Handy mit einem Foto ausgestattet, eine Brille um
Googlefunktionen erweitert werden. Bei solchen Funktionserweiterungen spielt die
objektorientierte Programmierung ihre Stärken aus. Wird so eine Funktion in eine eigene
Klasse ausverlagert, kann sie von beliebig vielen anderen Klassen eingebaut werden. Solche Klassen für ausgelagerte Methoden bezeichnen wir als Schnittstelle. In vielen objektorientierten Sprachen können die Methoden einer Schnittstelle abstrakt formuliert werden, so dass sie beim konkreten Einbau in eine andere Klasse erst noch überschrieben
werden müssen. Die Schnittstelle hat damit die Aufgabe übernommen, dafür zu sorgen,
dass Methoden, die gleiche Funktionalität bieten, in allen Klassen auch die gleichen
Namen tragen. Das erleichtert den Programmierern die Arbeit und den Nutzern die Verwendung der Klassen.
68
ooP mit Python
Selbst erstellte Klassen und ihre Objekte
Aufgaben zu Kapitel 12
1
Geheimnisprinzip
In vielen Städten gibt es öffentliche Bücherschränke: Jeder darf ein Buch für alle Nutzer hineinstellen und jeder darf sich ein Buch entnehmen, wenn er es lesen will.
Universitätsbibliotheken dagegen geben ihre Bücher nur auf Bestellung an der Theke heraus
und nur an angemeldete Nutzer
Erstelle für beide Arten von Bücherverleih eine Klasse mit den geeigneten Attributen.
2
Klassen und Objekte
1) Die Klassen Lok und Leuchte sind in den Klassen- und Objektkarten der Kapitel 12.1.8
(Klassen- und Objektdiagramm) und 12.1.9 (Kommunikation von Objekten - Sequenzdiagramm) schon beschrieben – es fehlt aber noch der Bahnhof: Zeichne die Klassen- und
Objektkarten zum Bahnhof und programmiere das Beispiel.
2) Das Programmbeispiel Emma ist noch nicht fertig. Ergänze die fehlenden Klassen mit den
benötigten Attributen. Außerdem fehlen noch die Methoden, die die Farbe der Objekte verändern können. Ergänze sie und erzeuge mehrere Duplolok-Objekte mit unterschiedlichen
Farbattributen.
3) Erstelle zwei Büchertaschen-Klassen. Die kann ein einziges Schlampermäppchen mit den
Stiften aufnehmen und maximal vier beliebige Bücher. Die andere kann ein Schlampermäppchen und beliebig viele Bücher aufnehmen. Kläre worin sich die beiden Klassen unterscheiden müssen und welche Elemente in beiden Klassen gleich sein können. Notiere
class Array:
deine Idee als Klassendiagramm und prodef __init__(self,arrayMax):
self.arrayMax = arrayMax
grammiere es in Python. Verwende dabei
self.zaehler = -1
die Typprüfung aus Kap. 12.2.2 Typself.liste = []
Prüfung.
def getLen(self):
return zaehler
4) Für Fortgeschrittene: Ergänze die rechts
abgedruckt Klasse Array um die Methoden
der Klasse list. Sie greifen alle auf das
Attribut self.liste zu. Bei fehlerhaften Eingaben (Eingabe < 0 oder Eingabe > zaehler) geben sie eine Fehlermeldung auf der
Konsole aus. Andernfalls setzen sie brav
um, was die Liste zu tun hat.
3
def append(self,inhalt):
if self.zaehler<arrayMax:
self.zaehler+=1
self.liste.append(inhalt)
else:
print('Array ist voll')
def pop(self,stelle):
pass
Generalisieren und Spezialisieren
1) Teste die Beispiele zur Generalisierung und zur Spezialisierung
2) Zur Oberklasse Fahrzeug gehören Wasserfahrzeuge, Autos (mit PKW und LKW), Motorräder,
Traktoren. Überlege, welche Attribute und dazugehörende Methoden in welche der Ebenen
verteilt werden sollten und notiere das Klassendiagramm mit Ober- und Unterklassen.
3) Kläre, ob Flugzeuge auch zu der Klassen Fahrzeuge gehören sollte. Notiere die entsprechenden Argumente pro und contra. Finde eine sinnvolle Lösungsmöglichkeit.
69
ooP mit Python
Probleme objektorientiert lösen
13
Probleme objektorientiert lösen
13.1
Projektplanung
Programme und damit auch Klassen stellen einen abstrahierenden Ausschnitt der Wirklichkeit dar. Bei der Planung ist also zu überlegen, welche Elemente der Wirklichkeit
abgebildet werden sollen und in welchen Klassen und mit welchen Methoden sie modelliert werden sollen. Deshalb benötigen Programmierprojekte immer eine gute Planung.
Dabei werden die benötigten Klassen und Objekte skizziert, sowie deren Kommunikationswege und wie sich die Zustände im System entwickeln sollen oder dürfen.
Gute Projektplanung geschieht also immer zuerst auf dem Papier. Dort werden neben der
Systemskizze auch die Kommunikationsschnittstellen beschrieben, also die Methoden
mit ihren Parametern bzw. mit ihren Rückgabewerten (Methodenkopf!).
Wenn alle diese Voraussetzungen schriftlich festgehalten sind, wird ausgemacht, in welcher Programmiersprache des Projekt umgesetzt wird und welcher Programmierer welchen Ausschnitt entwickelt. Waren die Absprachen gut, müsste das auch das Gesamtprojekt gut laufen, wenn jeder Programmer mit seiner Arbeit fertig ist
13.2
Mögliche Projekte
Die folgenden Aufgaben sind Beispiele. Deshalb könnt ihr euch auch eigene Aufgabe
ausdenken oder die Aufgaben verändern. Als objektorientierte ProgramiererInnen zerlegt
ihr diese Aufgaben dann in Teilaufgaben und bearbeitet sie auf das Team verteilt.
1
Schule, Schüler, Lehrer und Eltern
Entwicklt das Projekt Schule, Schüler, Lehrer (Kapitel 13.3) weiter: Bezieht die Eltern
mit ein und ordnet jedem Schüler auf geeignete Weise Eltern zu. Ergänzt die Klasse
Schulklasse um Schulaufgaben und Stegreifaufgaben und überlegt, wie ihr Noten und
Schülerobjekte zusammenbringen könnt.
2
Hafenmodellierung
Ein Hafen ist mit dem Meer, einem Binnensee, einem Kanal und einem Fluss verbunden.
Auf allen diesen Wasserstraßen können beliebig viele Wasserfahrzeuge unterwegs sein.
Der Hafen besitzt ein Kontrollzentrum, dort werden verschiedene Listen geführt über
Schiffe, die aus den vier Wasserstraßen in den Hafen einfahren wollen und die aus dem
Hafen herausgefahren sind. Es gibt verschiedene Schiffstypen: Containerschiffe, Öltanker, Lastkähne, Kreuzfahrtschiffe, Personenfähren und Autofähren. Güterschiffe docken
am Lastkai an, Passagierschiffe am Personenkai. Öltanker dürfen nur durch den Hafen
zur nächsten Wasserstraße fahren. Die Kais werden als Liste modelliert, weil viele
Schiffe anlegen dürfen. Die Hafendurchfahrt ist immer nur für ein Schiff offen.
70
ooP mit Python
3
Probleme objektorientiert lösen
Ampelanlage
Auf einer Straßenkreuzung fahren auf vier Straßen zufällig viele unterschiedliche Fahrzeuge ein. Sie dürfen nur weiterfahren, wenn ihre Strecke auf Grün gestellt ist. Wenn die
die Warteliste an einer Ampel deutliche länger wird, als die der anderen, beginnen die
PKW-Fahrer zu hupen. Dann wird dort die Ampelphase verkürzt.
Die Kreuzung kann als Turtle-Graphik dargestellt werden.
4
Mastermind
Erkundigt Euch, wie Mastermind gespielt wird und programmiert es selbst. Achtet darauf, dass die Spielsteine unterschiedlichen Rollen haben. Setzt die Turtle ein, um die
Oberfläche zeichnen.
5
Turtle-Graphik erweitern
Erweitert die Turtle mit Spezial-Turtles, die jeweils einen anderen Arbeitsstil haben. Entwickelt daraus ein Spiel für die MitschülerInnen.
13.3
1
Die Schule, ihre Schüler und Lehrer
Die Klasse und ihre Objekte
Klasse Schueler
1 class Schueler:
2
def __init__(self,name):
3
pass
4
def duSchreibstDich(self):
5
print(self)
6
def derAndereSchreibtSich(self,anderer):
7
anderer.duSchreibstDich()
8
9 maier = Schueler()
10 schulz = Schueler()
11
1) Erläutere den Zusammenhang der Zeile 9 mit den Zeilen 1-3. Verwende dabei die korrekten
Fachausdrücke!
2) Schueler maier trägt den Spitznamen grossM. Sorge dafür, dass das Objekt maier auch unter
diesem Namen erreicht wird. Entscheide begründet, welche der freien Zeilen du verwendest.
3) Schueler maier schreibt seinen Speicherplatz auf den Bildschirm und fordert danach den
Schueler schulz auf, das Gleiche zu tun. - Notiere beide Aufrufe mit Hilfe der passenden
Methoden der angegebenen Klasse Schueler!
4) Eine Python-Methode unterscheidet sich deutlich von einer Python-Funktion. - Erkläre daran
die Rolle einer Methode in der objektorientierten Programmierung (ooP).
71
ooP mit Python
2
Probleme objektorientiert lösen
Die Klasse und ihre Attribute
Klasse Schueler mit einem Attribut
1 class Schueler:
2
def __init__(self,name):
3
self.name = name
4
5 maier = Schueler("maier")
1) Erstelle für das Attribut self.name eine Set- und eine GetMethode.
2) Erzeuge ein Schülerobjekt schulz und erfrage den dort gespeicherten Namen.
3) Stelle die Klasse Schueler und das Schülerobjekt schulz als Klassen- und als Objektdiagramm (Kapitel 12.1.8) dar.
4) Erweitere die Klasse Schueler um die Attribute vorname, gebDat und Klasse, sowie den
dazugehörenden Methoden.
5) Ändere den gespeicherten Namen und erfrage ihn erneut. - Kläre , warum es sinnvoller ist,
eine Schüler- oder Klassenliste anzulegen, als für jedes Schülerobjekt eine eigene Variable
zu verwenden.
6) Erstelle eine Methode anrede(), die den Schüler abhängig vom Alter (Grenze 18 Jahre) korrekt anredet: liebe / leber Vorname bzw. liebe / leber Vorname Nachname.
3
Die Klasse und ihre Listenattribute
Klasse Lehrer
Ein Lehrer hat
- einen Vornamen
- einen Namen
- ein Geburtsdatum
- ein Geschlecht (m/w)
- einen Dienstgrad (Ref = Referendar / StR = Studienrat / OStR = Oberstudienrat / StD = Studiendirektor / OStD = Oberstudiendirektor)
+ ein oder mehrere Fächer
1) Erstelle eine Klasse Lehrer, die die passenden Attribute besitzt. Das Attribut Fach soll vom
Typ Liste sein. Überlege, mit welchen Parametern du den Konstruktor ausstatten musst, um
alle (!) Attribute korrekt füllen zu können. Schreibe die Klasse mit ihrem Konstruktor und der
Initialisierung der Variablen.
2) Schreibe zu den Attributen Vorname, Name und Dienstgrad je eine Get- und eine SetMethode
3) Erzeuge zwei Objekte:
Oberstudienrat Christian Schmidt: evangelische Religion, Mathematik (m, 10.12.1970)
Studienrätin Hadice Demirci: Deutsch, Englisch, islamische Religion (w, 3.4.1983)
4) Erstelle eine Methode anrede(), die Geschlecht, Dienstgrad und Name korrekt ausgibt;
also: Herr OStR C.Schmid bzw. Frau StRin H.Demirci.
5) Entwickle für das Attribut Fach eine SetMethode, mit der du ein Fach ergänzen kannst, eine
SetMethode, mit der du ein Fach löschen kannst und eine SetMethode, mit der du ein falsch
eingetragenes Fach ändern kannst
72
ooP mit Python
4
Probleme objektorientiert lösen
Objekte verwalten Objekte (has-a-Beziehung / is-a-Beziehung)
Klasse schulklasse
Die Klasse Schulklasse besitzt nur ein Listen-Attribut schuelerDerKlasse
Das Attribut schuelerDerKlasse nimmt nur Objekte der Klasse Schuler an
(Typprüfung – Kapitel 12.2.2)
Klasse schule
Die Klasse Schule besitzt die Listen-Attribute lehrer und schulklassen
1) Kläre, welches Attribut bei der Klasse Schueler ab sofort entfallen kann.
2) Entwirf die Klasse Schulklasse mit den Methoden setAlleSchueler(*schueler), setEinenSchueler(schueler), getAlleSchueler().
3) Schreibe die Klasse Schule mit den dazugehörenden Attributen und Methoden (setAlleKlassen(*Klasse), setEineKlasse(klasse), getAlleKlassen()).
4) Ergänze eine getMethode , die die Daten eines einzelnen Schülers aus der Klasse 10 erfragen kann, wenn dessen Name bekannt ist.
5) Erzeuge ein Schulobjekt unsereSchule, das im Attribut schulklassen ein Klassenobjekt
klasse10 besitzt. Trage einige Schülerobjekte in die Klasse ein und teste die Ausgaben.
5
Das Geheimnisprinzip
class Offen:
def __init__(self,name):
self.name = name
def setName(self,name):
self.name = name
def getName(self):
print(self.name)
def setAnderenNamen(self,obj,name):
obj.setName(name)
class Geheim:
def __init__(self,name):
self.__name = name
def setName(self,name):
self.__name = name
def getName(self):
print(self.__name)
def setAnderenNamen(self,obj,name):
obj.setName(name)
1) Erzeuge ein Objekt aenderlich = Offen(“Max Änderlich“) und zwei Geheim-Objekte: ichAendere = Geheim(“Klaus Ender“) und werdeGeaendert = Geheim(“Karl Wechsel“).
2) Teste die beiden folgenden Befehle und rufe dann die dazugehörende getMethode auf.
aenderlich.name = "Auch ein Name"
werdeGeaendert.name = "Auch ein Name"
Erkläre die beiden unterschiedlichen Ergebnisse!
3) Teste die beiden folgenden Befehle:
ichAendere.setAnderenNamen(aenderlich,“Kannst Nix“)
ichAendere.setAnderenNamen(werdeGeaendert,“Kannst Nix“)
Kläre, wie solche unerwünschten Veränderungen verhindert werden könnten
4) Stelle den Ablauf von Aufgabe 5c als Zustandsübergangsdiagramm (Kapitel 12.1.10) und als
Sequenzdiagramm (Kapitel 12.1.9) dar.
73
ooP mit Python
6
Probleme objektorientiert lösen
Generalisieren und Erben
1) Vergleiche die Klasse Schueler mit der Klasse Lehrer: Welche Gemeinsamkeiten haben sie
und worin sind diese Gemeinsamkeiten begründet?
2) Schreibe eine Klasse Person, die die Gemeinsamkeiten von Schülern und Lehrern vereinigt
und lasse die Klassen Schüler und Lehrer von der Klasse Person erben. Passe dazu den
Konstruktor und die Methoden an. Stelle die Beziehung als Diagramm dar (Kapitel 12.2).
In einem Rundschreiben sollen Eltern, Schüler und Lehrer informiert werden. Sie
sollen dabei korrekt angesprochen werden: Eltern mit „Herr/Frau Nachname“,
Schüler mit „lieber/liebe Vorname“ und Lehrer mit „Herr/Frau Dienstgrad Nachname“.
3) Ergänze die Klasse Person um das Attribut self.__geschlecht und entwirf eine Schnittstelle
Anrede, die die passende Methode zur Verfügung stellt.
4) Kläre, in welchen Klassen du die Methoden dieser Schnittstelle in welcher Weise überschreiben muss und setze sie für die (neuen) Klassen Eltern, Schüler und Lehrer um.
74
ooP mit Python
Beispiele für eine Hausaufgabe
BEISPIELE FÜR EINE HAUSAUFGABE
Die Hausaufgabe wird mit Python bearbeitet
Für Dateiname gilt immer (!) folgender Aufbau:
oopmp[Kapitel][BerabeiterName][BearbeiterVorname]
(oopmp steht für objektorientiert Programmieren mit Python)
Beispiel für Aufgabe 2a in Kapitel 2:
oomp2.py
#2a
print('Martin Frenkler', ...)
Der Quelltext aus der Programmdatei und die Ausgabe auf der Konsolewerden in die
Textverarbeitung kopiert, zum Korrigieren ausgedruckt und in der nächsten Stunde vorgelegt.
Idle-Programm
Name, Vorname
Hausaufgabe vom [Datum]
oopmp2
Python 3.2.1 (default, Jul 18 2011, 16:24:40) [GCC] on linux2
Type "copyright", "credits" or "license()" for more information.
>>> print("Martin Frenkler", "Bergstr. 10", "95465 Neustadt bei Coburg")
Martin Frenkler Bergstr. 10 95465 Neustadt bei Coburg
>>>
Programm mit Datei und Konsolenausgabe
Name, Vorname
Hausaufgabe vom [Datum]
oopmp2.py
#2a
print("Martin Frenkler", "Bergstr. 10", "95465 Neustadt bei Coburg")
Python 3.2.1 (default, Jul 18 2011, 16:24:40) [GCC] on linux2
Type "copyright", "credits" or "license()" for more information.
>>> ================================ RESTART ================================
>>>
Martin Frenkler Bergstr. 10 95465 Neustadt bei Coburg
>>>
75
Herunterladen