Upload
lamkhanh
View
218
Download
0
Embed Size (px)
Citation preview
Allen B. Downey, Programmieren lernen mit Python, O´Reilly, ISBN 97839556180639783955618063
D3kjd3Di38lk323nnm
Inhalt
Vorwort. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . XIII
1 Programme entwickeln . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1Die Programmiersprache Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Was ist ein Programm? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Was ist Debugging? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
Syntaxfehler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
Laufzeitfehler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
Semantische Fehler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Experimentelles Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Formale und natürliche Sprachen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Das erste Programm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Glossar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Übungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2 Variablen, Ausdrucke und Anweisungen . . . . . . . . . . . . . . . . . . . . . . . . . . . 13Werte und Typen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Variablen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Variablennamen und Schlüsselwörter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Operatoren und Operanden . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Ausdrücke und Anweisungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Interaktiver Modus und Skriptmodus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Rangfolge von Operatoren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
String-Operationen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Kommentare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
| V
Glossar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Übungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
3 Funktionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25Funktionsaufrufe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Funktionen zur Typkonvertierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Mathematische Funktionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
Komposition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Neue Funktionen erstellen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Definition und Verwendung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Programmablauf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
Parameter und Argumente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
Variablen und Parameter sind lokal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
Stapeldiagramme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
Funktionen mit und ohne Rückgabewert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
Warum Funktionen? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
Import mit from . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
Glossar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Übungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
4 Fallstudie: Gestaltung von Schnittstellen . . . . . . . . . . . . . . . . . . . . . . . . . . 41TurtleWorld . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Einfache Wiederholung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
Übungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Datenkapselung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
Generalisierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Gestaltung von Schnittstellen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Refactoring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
Entwicklungsplan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
Docstring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
Glossar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
Übungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
5 Bedingungen und Rekursion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53Modulos-Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
Boolesche Ausdrücke . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
Logische Operatoren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
VI | Inhalt
Allen B. Downey, Programmieren lernen mit Python, O´Reilly, ISBN 97839556180639783955618063
Bedingte Ausführung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
Alternativer Programmablauf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
Verkettete Bedingungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
Verschachtelte Bedingungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
Rekursion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
Stapeldiagramme für rekursive Funktionen . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
Endlose Rekursion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
Tastatureingaben . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Glossar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Übungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
6 Funktionen mit Ruckgabewert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65Rückgabewerte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
Inkrementelle Entwicklung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
Funktionskomposition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
Boolesche Funktionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
Mehr Rekursion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
Vertrauensvorschuss . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
Noch ein Beispiel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
Typprüfung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
Glossar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
Übungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
7 Iteration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79Mehrfache Zuweisungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
Variablen aktualisieren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
Die while-Anweisung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
break . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
Quadratwurzeln . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
Algorithmen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
Glossar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
Übungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
8 Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89Ein String ist eine Folge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
len . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
Inhalt | VII
Traversierung mit einer Schleife . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
String-Teile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
Strings sind unveränderbar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
Suchen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
Schleifen und Zähler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
String-Methoden . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
Der in-Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
String-Vergleich . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
Unicode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
Glossar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
Übungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
9 Fallstudie: Wortspiele . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105Wortlisten einlesen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
Übungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
Suchen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
Schleifen mit Indizes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
Glossar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
Übungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
10 Listen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113Eine Liste ist eine Sequenz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
Listen können geändert werden . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
Listen durchlaufen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
Operationen mit Listen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
Listen-Slices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
Methoden für Listen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
Map, Filter und Reduktion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
Listen-Abstraktionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
Elemente löschen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
Listen und Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
Objekte und Werte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
Aliasing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
Listen als Argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
Mengen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
VIII | Inhalt
Allen B. Downey, Programmieren lernen mit Python, O´Reilly, ISBN 97839556180639783955618063
Glossar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
Übungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
11 Dictionaries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133Dictionary als Menge von Zählern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
Schleifen und Dictionaries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
Inverse Suche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
Dictionaries und Listen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
Dictionary-Abstraktionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
Memos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
Globale Variablen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
Long Integer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
Glossar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
Übungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
12 Tupel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149Tupel sind unveränderbar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
Tupel-Zuweisung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
Tupel als Rückgabewerte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
Argument-Tupel mit variabler Länge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
Listen und Tupel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
Dictionaries und Tupel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
Tupel vergleichen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
Sequenzen mit Sequenzen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
Glossar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
Übungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
13 Fallstudie: Die Wahl der richtigen Datenstruktur . . . . . . . . . . . . . . . . . . . . 161Häufigkeitsanalyse für Wörter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
Zufallszahlen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
Worthistogramm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
Die häufigsten Wörter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
Optionale Parameter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
Dictionary-Subtraktion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166
Zufallswörter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
Markov-Analyse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
Datenstrukturen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
Inhalt | IX
Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
Glossar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172
Übungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172
14 Dateien . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175Persistenz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175
Lesen und schreiben . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175
Formatoperator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176
format-Methode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
Dateinamen und Pfade . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178
Ausnahmen abfangen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
Datenbanken . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
Pickling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
Pipes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182
Module schreiben . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
Glossar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
Übungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
15 Klassen und Objekte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189Benutzerdefinierte Typen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
Attribute . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
Rechtecke . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
Instanzen als Rückgabewerte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
Objekte sind veränderbar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
Kopieren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
Glossar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
Übungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
16 Klassen und Funktionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199Zeit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
Reine Funktionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200
Modifizierende Funktionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
Prototyping kontra Planung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204
Glossar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205
Übungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205
X | Inhalt
Allen B. Downey, Programmieren lernen mit Python, O´Reilly, ISBN 97839556180639783955618063
17 Klassen und Methoden . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207Objektorientierte Programmierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
Objekte ausgeben . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208
Noch ein Beispiel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209
Ein komplizierteres Beispiel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
init-Methode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211
Methode __str__ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211
Operator-Überladung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212
Dynamische Bindung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213
Polymorphismus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214
Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215
Schnittstelle und Implementierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
Glossar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
Übungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
18 Vererbung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221Karten-Objekte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221
Klassenattribute . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222
Karten vergleichen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224
Stapel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225
Kartenstapel ausgeben . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225
Hinzufügen, entfernen, mischen und sortieren . . . . . . . . . . . . . . . . . . . . . . . . . 226
Vererbung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227
Klassendiagramme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229
Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230
Datenkapselung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231
Glossar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232
Übungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
19 Fallstudie: Tkinter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237GUI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237
Buttons und Callbacks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238
Canvas-Widgets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
Koordinatensequenzen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240
Weitere Widgets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241
Widgets packen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242
Menüs und Callables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245
Bindung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246
Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
Inhalt | XI
Glossar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249
Übungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250
Syntaxfehler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253
Laufzeitfehler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255
Semantische Fehler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
Wachstumsordnung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264
Analyse grundlegender Python-Operationen . . . . . . . . . . . . . . . . . . . . . . . . . . 266
Analyse von Suchalgorithmen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268
Hashtabellen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269
Zustandsdiagramm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
Stapeldiagramm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277
Objektdiagramme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278
Funktions- und Klassenobjekte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280
Klassendiagramme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281
Anhang A: Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253
Anhang B: Algorithmenanalyse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263
Anhang C: Lumpy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
Index. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285
XII | Inhalt
Allen B. Downey, Programmieren lernen mit Python, O´Reilly, ISBN 97839556180639783955618063
KAPITEL 4
Fallstudie: Gestaltung von Schnittstellen
TurtleWorldBegleitend zu diesem Buch habe ich ein Paket mit dem Namen Swampy geschrieben. Dieentsprechende Datei aus den Codebeispielen heißt http://thinkpython.com/swampy. Be-folgen Sie einfach die Anweisungen, um Swampy auf Ihrem System zu installieren.
Ein Paket ist eine Sammlung von Modulen. Eines der Module in Swampy ist TurtleWorld.Dieses Modul stellt eine Reihe von Funktionen zur Verfügung, mit denen Sie Linienzeichnen können, indem Sie Schildkröten über den Bildschirm bewegen.
Sobald Swampy als Paket auf Ihrem System installiert ist, können Sie TurtleWorldfolgendermaßen importieren:
from swampy.TurtleWorld import *
Wenn Sie die Swampy-Module heruntergeladen, aber nicht als Paket installiert haben,können Sie entweder in dem entsprechenden Verzeichnis mit den Swampy-Dateienarbeiten oder dieses Verzeichnis dem Suchpfad von Python hinzufügen. Anschließendkönnen Sie TurtleWorld so importieren:
from TurtleWorld import *
Die Einzelheiten des Installationsvorgangs sowie die Details zum Festlegen des Suchpfadsvon Python hängen von Ihrem System ab. Anstatt dazu Näheres an dieser Stelle zuerläutern, werde ich versuchen, die Informationen für verschiedene Systeme unter http://thinkpython.com/swampy aktuell zu halten.
Erstellen Sie eine Datei mit dem Namen meinpolygon.py, und tippen Sie den folgendenCode ein:
from swampy.TurtleWorld import *
welt = TurtleWorld()tim = Turtle()print(tim)
wait_for_user()
| 41
In der ersten Zeile wird alles aus dem Modul TurtleWorld des Pakets swampy importiert.
In den folgenden Zeilen wird eine TurtleWorld erstellt und der Variablen welt zugewie-sen. Außerdem weisen wir der Variablen tim eine neue Schildkröte zu. Wenn Sie timausgeben, erhalten Sie in etwa Folgendes:
<TurtleWorld.Turtle instance at 0xb7bfbf4c>
Das bedeutet, dass sich tim auf eine Instanz einer Schildkröte (»Turtle«) in TurtleWorldbezieht. In diesem Kontext bedeutet »Instanz«, dass es sich um das Mitglied einer Gruppehandelt. Diese Turtle ist eine der möglichen Turtles.
wait_for_user weist TurtleWorld an, darauf zu warten, dass der Benutzer etwas macht. Indiesem Fall kann der Benutzer allerdings nicht mehr tun, als das Fenster zu schließen.
TurtleWorld bietet mehrere Funktionen zum Steuern der Schildkröte: fd und bk fürvorwärts und rückwärts sowie lt und rt für links und rechts. Außerdem hält jedeSchildkröte einen Stift, der sich entweder oben oder unten befindet. Wenn sich der Stiftunten befindet, zeichnet die Schildkröte eine Spur, wenn sie sich bewegt. Die Funktionenpu und pd stehen für »pen up« (Stift nach oben) und »pen down« (Stift nach unten).
Fügen Sie diese Zeilen in das Programm ein, um einen rechten Winkel zu zeichnen(nachdem Sie tim erstellt haben und bevor Sie wait_for_user aufrufen):
fd(tim, 100)lt(tim)fd(tim, 100)
Die erste Zeile weist tim an, 100 Schritte vorwärts zu machen. Die zweite Zeile lässt ihnlinks abbiegen.
Wenn Sie dieses Programm ausführen, müsste sich tim zuerst nach Osten und dann nachNorden bewegen und dabei zwei Linienabschnitte zurücklassen.
Ändern Sie nun das Programm so, dass es ein Quadrat zeichnet. Lassen Sie nicht locker,bis es funktioniert!
Einfache WiederholungHöchstwahrscheinlich haben Sie ungefähr Folgendes geschrieben (mit Ausnahme desCodes, der die TurtleWorld erstellt und auf den Benutzer wartet):
fd(tim, 100)lt(tim)
fd(tim, 100)lt(tim)
fd(tim, 100)lt(tim)
fd(tim, 100)
42 | Kapitel 4: Fallstudie: Gestaltung von Schnittstellen
Allen B. Downey, Programmieren lernen mit Python, O´Reilly, ISBN 97839556180639783955618063
Prägnanter können wir dasselbe mit einer for-Anweisung erreichen. Fügen Sie diefolgenden Zeilen in meinpolygon.py ein, und führen Sie das Skript erneut aus:
for i in range(4):print('Hallo!')
Nun sollten Sie in etwa Folgendes sehen:
Hallo!Hallo!Hallo!Hallo!
Das ist die einfachste Einsatzmöglichkeit einer for-Anweisung. Mehr dazu erfahren Siespäter. Das sollte aber bereits ausreichen, damit Sie Ihr Programm zum Zeichnen desQuadrats neu schreiben können. Bleiben Sie so lange dran, bis es funktioniert!
Hier sehen Sie eine for-Anweisung, die ein Quadrat zeichnet:
for i in range(4):fd(tim, 100)lt(tim)
Die Syntax einer for-Anweisung ist einer Funktionsdefinition recht ähnlich. Sie hat einenHeader, der mit einem Doppelpunkt endet, sowie einen eingerückten Body. Auch hierkann der Body wieder eine beliebige Anzahl von Anweisungen enthalten.
Eine for-Anweisung wird manchmal auch als Schleife bezeichnet, weil das Programm denBody in einer Schleife durchläuft. In diesem Fall wird der Body viermal ausgeführt.
Diese Version unterscheidet sich genau genommen ein klein wenig von dem bisherigenCode, weil sich die Schildkröte nach der letzten Seite des Quadrats noch einmal zusätzlichdreht. Diese Drehung braucht ein wenig mehr Zeit, vereinfacht aber den Code, wenn wirbei jedem Durchlauf durch die Schleife immer dasselbe tun. Außerdem landet die Schild-kröte so auch wieder in der ursprünglichen Position und zeigt in die Ausgangsrichtung.
UbungenEs folgt eine Reihe von Übungen mit TurtleWorld. Sie sollen natürlich Spaß machen,haben aber auch einen Sinn. Denken Sie darüber nach, welcher Sinn das jeweils seinkönnte, während Sie an den Übungen arbeiten.
Die folgenden Abschnitte enthalten auch Lösungen für die Übungen. Blättern Sie abernicht vor, bevor Sie damit fertig sind (oder es wenigstens versucht haben).
1. Schreiben Sie eine Funktion mit dem Namen quadrat, die eine Schildkröte als Para-meter t erwartet. Die Funktion soll diese Schildkröte verwenden, um ein Quadrat zuzeichnen.
Schreiben Sie eine Funktion, die tim als Argument an quadrat übergibt, und führenSie das Programm erneut aus.
Ubungen | 43
2. Fügen Sie einen zusätzlichen Parameter mit dem Namen laenge in quadrat ein.Ändern Sie den Body so, dass die Kantenlänge durch laenge bestimmt wird, undändern Sie den Funktionsaufruf so, dass ein zweites Argument übergeben wird.Führen Sie das Programm erneut aus. Testen Sie es mit verschiedenen Werten fürlaenge.
3. Die Funktionen lt und rt biegen jeweils in einem Winkel von 90 Grad ab. Sie könnenaber auch ein zweites Argument übergeben, das den Winkel in Grad angibt. Bei-spielsweise lässt lt(tim, 45) unseren tim im 45-Grad-Winkel nach links drehen.
Machen Sie eine Kopie von quadrat, und ändern Sie den Namen in polygon. Fügen Sieeinen zusätzlichen Parameter n ein, und ändern Sie den Body so, dass ein gleichsei-tiges Polygon mit n Seiten gezeichnet wird. Tipp: Die Außenwinkel eines gleichseiti-gen n-seitigen Polygons betragen 360/n Grad.
4. Schreiben Sie eine Funktion mit dem Namen kreis, die eine Schildkröte t und einenRadius r als Parameter erwartet und einen ungefähren Kreis zeichnet, indem siepolygon mit einer entsprechenden Länge und Anzahl von Seiten aufruft. Testen Siedie Funktion mit mehreren Werten für r.
Tipp: Ermitteln Sie den Umfang des Kreises, und vergewissern Sie sich, dass laenge * n= umfang.
Noch ein Tipp: Wenn tim Ihnen zu langsam ist, können Sie das ändern, indem Sietim.delay anpassen. Dadurch legen Sie die Zeit zwischen den einzelnen Bewegungenin Sekunden fest. Mit tim.delay = 0.01 wird er die Beine in die Hand nehmen müssen.
5. Schreiben Sie eine allgemeinere Version von kreis mit dem Namen bogen, die einenzusätzlichen Parameter winkel erwartet, mit dem Sie festlegen können, welcher Teileines Kreises gezeichnet werden soll. winkel wird in Grad angegeben, so dass beiwinkel=360 ein vollständiger Kreis gezeichnet wird.
DatenkapselungIn der ersten Übung sollten Sie den Code zum Zeichnen des Quadrats in eine Funktions-definition schreiben und anschließend die Funktion aufrufen, wobei Sie die Schildkröteals Parameter übergeben. Hier eine mögliche Lösung:
def quadrat(t):for i in range(4):
fd(t, 100)lt(t)
quadrat(tim)
Die Anweisungen ganz innen – fd und lt – wurden zweimal eingerückt, um zu kenn-zeichnen, dass sie innerhalb der for-Schleife stehen, die sich wiederum innerhalb derFunktionsdefinition befindet. Die nächste Zeile, quadrat(tim), ist wieder linksbündig,wodurch sowohl das Ende der for-Schleife als auch der Funktionsdefinition gekenn-zeichnet wird.
44 | Kapitel 4: Fallstudie: Gestaltung von Schnittstellen
Allen B. Downey, Programmieren lernen mit Python, O´Reilly, ISBN 97839556180639783955618063
Innerhalb der Funktion bezieht sich t auf dieselbe Schildkröte wie tim, entsprechend hatlt(t) denselben Effekt wie lt(tim). Aber warum rufen wir dann nicht den Parameter timauf?
Weil t auf diese Weise eine beliebige Schildkröte sein kann, nicht nur tim. So können Sieauch eine zweite Schildkröte erstellen und als Argument an quadrat übergeben:
rudi = Turtle()quadrat(rudi)
Wenn Sie eine Codezeile in eine Funktion auslagern, nennt man das Datenkapselung.Einer der Vorteile der Datenkapselung besteht darin, dass der entsprechende Codeteileinen Namen erhält, was gleichzeitig auch der Dokumentation des Codes dient. Undwenn Sie einen bestimmten Code mehrmals verwenden möchten, ist es wesentlicheinfacher, eine Funktion mehrfach aufzurufen, als deren Body mehrmals zu kopierenund einzufügen.
GeneralisierungDer nächste Schritt besteht darin, quadrat um den Parameter laenge zu erweitern. Hiereine mögliche Lösung:
def quadrat(t, laenge):for i in range(4):
fd(t, laenge)lt(t)
quadrat(tim, 100)
Die Erweiterung einer Funktion um einen Parameter nennt man Generalisierung, weildadurch die Funktion verallgemeinert wird. In der vorherigen Version hatte das Quadratimmer dieselbe Größe. In dieser Version kann es eine beliebige Größe haben.
Der nächste Schritt ist ebenfalls eine Generalisierung. Anstatt Quadrate zu zeichnen, kannpolygon regelmäßige Polygone mit einer beliebigen Anzahl von Seiten zeichnen. Hier einemögliche Lösung:
def polygon(t, n, laenge):winkel = 360.0 / nfor i in range(n):
fd(t, laenge)lt(t, winkel)
polygon(tim, 7, 70)
Dadurch wird ein siebenseitiges Polygon mit einer Seitenlänge von 70 gezeichnet. WennSie mehr als ein numerisches Argument übergeben, kann es leicht passieren, dass Sievergessen, was die einzelnen Argumente bedeuten und in welcher Reihenfolge Sie sieangeben müssen.
Generalisierung | 45
Es ist daher zulässig – und manchmal auch durchaus hilfreich –, die Namen der Parameterin der Argumentenliste mit anzugeben:
polygon(tim, n=7, laenge=70)
Solche Argumente bezeichnet man als Schlüsselwortargumente, weil sie die Parameter-namen als »Schlüsselwörter« mit angeben (nicht zu verwechseln mit Python-Schlüssel-wörtern wie while und def).
Durch diese Syntax ist das Programm besser lesbar. Außerdem veranschaulicht diesesBeispiel, wie Argumente und Parameter funktionieren: Wenn Sie eine Funktion aufrufen,werden die übergebenen Argumente den entsprechenden Parametern zugewiesen.
Gestaltung von SchnittstellenIm nächsten Schritt zeichnen Sie einen kreis mit dem Radius r als Parameter. Hier sehenSie eine einfache Lösung, die mit polygon ein fünfzigseitiges Polygon zeichnet:
def kreis(t, r):umfang = 2 * math.pi * rn = 50laenge = umfang / npolygon(t, n, laenge)
In der ersten Zeile wird der Umfang des Kreises mit Radius r über die Formel 2πr be-rechnet. Da wir math.pi verwenden, müssen wir math importieren. Der Konvention nachmüssen import-Anweisungen am Anfang des Skripts stehen.
n ist die Anzahl der Liniensegmente für die Annäherung an den Kreis. laenge ist die Längeder einzelnen Linien. Entsprechend zeichnet polygon ein fünfzigseitiges Polygon alsAnnäherung an einen Kreis mit Radius r.
Eine Begrenzung dieser Lösung liegt darin, dass n eine Konstante ist. Für sehr große Kreisesind die Liniensegmente zu lang, und bei sehr kleinen Kreisen verschwenden wir Zeit,indem wir sehr kleine Kreissegmente zeichnen. Eine mögliche Lösung besteht darin, dieFunktion zu generalisieren und n als Parameter entgegenzunehmen. Dadurch hätten dieBenutzer (wer auch immer kreis aufruft) mehr Kontrolle, aber die Schnittstelle wäredadurch weniger übersichtlich.
Die Schnittstelle einer Funktion fasst zusammen, wie sie verwendet wird: Wie heißen dieParameter? Was macht die Funktion? Und was ist der Rückgabewert? Eine Schnittstelle istdann übersichtlich, wenn sie »so einfach wie möglich, aber nicht einfacher ist« (Einstein).
In diesem Beispiel gehört r zur Schnittstelle, weil es den zu zeichnenden Kreis bestimmt. nist dagegen nicht ganz zutreffend, weil es sich mehr auf die Einzelheiten dazu bezieht, wieder Kreis gezeichnet werden soll.
Anstatt die Schnittstelle unübersichtlicher zu machen, wählen wir für n besser einen Wert,der vom umfang abhängt:
46 | Kapitel 4: Fallstudie: Gestaltung von Schnittstellen
Allen B. Downey, Programmieren lernen mit Python, O´Reilly, ISBN 97839556180639783955618063
def kreis(t, r):umfang = 2 * math.pi * rn = int(umfang / 3) + 1laenge = umfang / npolygon(t, n, laenge)
Nun entspricht die Anzahl der Segmente (ungefähr) umfang / 3, wodurch die Länge jedesSegments (ungefähr) 3 beträgt. Das ist klein genug, damit der Kreis hübsch aussieht, undgroß genug, um Kreise beliebiger Größe effizient und angemessen zu zeichnen.
RefactoringAls ich kreis geschrieben habe, konnte ich polygon wiederverwenden, weil ein Polygonmit beliebig vielen Seiten eine gute Annäherung an einen Kreis ist. Aber bogen ist nichtganz so kooperativ. Wir können weder polygon noch kreis verwenden, um einen Bogen zuzeichnen.
Eine Alternative besteht darin, mit einer Kopie von polygon zu beginnen und sie in einenbogen umzuwandeln. Das Ergebnis könnte folgendermaßen aussehen:
def bogen(t, r, winkel):bogen_laenge = 2 * math.pi * r * winkel / 360n = int(bogen_laenge / 3) + 1schritt_laenge = bogen_laenge / nschritt_winkel = float(winkel) / n
for i in range(n):fd(t, schritt_laenge)lt(t, schritt_winkel)
Die zweite Hälfte dieser Funktion sieht wie polygon aus, aber wir können polygon nichtverwenden, ohne die Schnittstelle zu ändern. Wir könnten zwar polygon so verallgemei-nern, dass die Funktion einen Winkel als drittes Argument erwartet. Aber dann wärepolygon kein passender Name mehr! Verwenden wir lieber die allgemeinere Funktionpolylinie:
def polylinie(t, n, laenge, winkel):for i in range(n):
fd(t, laenge)lt(t, winkel)
Nun können wir polygon und bogen so umschreiben, dass sie polylinie verwenden:
def polygon(t, n, laenge):winkel = 360.0 / npolylinie(t, n, laenge, winkel)
def bogen(t, r, winkel):bogen_laenge = 2 * math.pi * r * winkel / 360n = int(bogen_laenge / 3) + 1schritt_laenge = bogen_laenge / nschritt_winkel = float(winkel) / npolylinie(t, n, schritt_laenge, schritt_winkel)
Refactoring | 47
Zum Abschluss können wir kreis noch so umschreiben, dass die Funktion bogenverwendet wird:
def kreis(t, r):bogen(t, r, 360)
Den Vorgang, ein Programm neu zu arrangieren, um Funktionsschnittstellen zu verbes-sern und die Wiederverwendung von Code zu erleichtern, nennt man Refactoring. Indiesem Fall haben wir festgestellt, dass bogen und polygon ähnlichen Code enthaltenhaben, deshalb haben wir ihn in die Funktion polylinie »ausgeklammert«.
Wenn wir entsprechend vorausgeplant hätten, hätten wir vielleicht zuerst polyliniegeschrieben und uns das Refactoring gespart. Aber oft wissen Sie am Anfang einesProjekts nicht genug, um alle Schnittstellen entsprechend zu entwerfen. Sobald Sie mitdem Code angefangen haben, verstehen Sie die Probleme besser. Manchmal ist Refacto-ring ein Zeichen dafür, dass Sie etwas gelernt haben.
EntwicklungsplanEin Entwicklungsplan ist ein Verfahren zum Schreiben von Programmen. Die beidenAnsätze, die wir in dieser Fallstudie herangezogen haben, waren »Datenkapselung« und»Generalisierung«. Die Schritte dieses Verfahrens lauten:
1. Beginnen Sie mit einem kleinen Programm ohne Funktionsdefinitionen.
2. Sobald das Programm funktioniert, kapseln Sie es in eine Funktion und geben ihreinen Namen.
3. Generalisieren Sie die Funktion durch entsprechende Parameter.
4. Wiederholen Sie die Schritte 1 bis 3, bis Sie eine Reihe entsprechender Funktionenhaben. Kopieren Sie den funktionierenden Code, und fügen Sie ihn ein, um sich daserneute Tippen (und das erneute Debugging) zu ersparen.
5. Suchen Sie nach Möglichkeiten, das Programm durch Refactoring zu verbessern.Wenn Sie beispielsweise an mehreren Stellen ähnlichen Code verwenden, sollten Siedarüber nachdenken, diesen in eine entsprechende allgemeinere Funktion auszula-gern.
Dieses Verfahren hat auch Nachteile (Alternativen dazu sehen wir uns später an), kannaber sehr nützlich sein, wenn Sie nicht von vornherein wissen, wie Sie das Programm inFunktionen aufteilen können. Bei diesem Ansatz gestalten Sie das Programm immerwieder um, während Sie daran arbeiten.
DocstringEin Docstring ist ein String am Anfang einer Funktion, der die Schnittstelle erklärt (»doc«steht dabei für Dokumentation). Hier ein Beispiel:
48 | Kapitel 4: Fallstudie: Gestaltung von Schnittstellen
Allen B. Downey, Programmieren lernen mit Python, O´Reilly, ISBN 97839556180639783955618063
def polylinie(t, n, laenge, winkel):"""Zeichnet n Liniensegmente.t: Turtle-Objektn: Anzahl der Liniensegmentelaenge: Lange der einzelnen Segmentewinkel: Winkel zwischen den Segmenten in Grad"""for i in range(n):
fd(t, laenge)lt(t, winkel)
Dieser Docstring steht in drei Anführungszeichen hintereinander. So etwas bezeichnetman auch als mehrzeiligen String, weil er mehr als eine Zeile umfassen kann.
Das ist kurz und knapp, enthält aber die wesentlichen Informationen für jemanden, derdiese Funktion verwenden möchte. Der Docstring erklärt exakt, was die Funktion macht(ohne auf Einzelheiten einzugehen), welche Auswirkungen die jeweiligen Parameter aufdas Verhalten der Funktion haben und welcher Typ jeweils erwartet wird (falls das nichtoffensichtlich ist).
Diese Art der Dokumentation ist ein wichtiger Teil der Gestaltung von Schnittstellen. Einegut durchdachte Schnittstelle sollte einfach zu erklären sein. Sollten Sie Schwierigkeitenhaben, eine Ihrer Funktionen zu beschreiben, könnte das ein Hinweis darauf sein, dass dieSchnittstelle verbesserungsbedürftig ist.
DebuggingEine Schnittstelle ist wie ein Vertrag zwischen einer Funktion und dem Aufrufenden. DerAufrufende stimmt zu, bestimmte Parameter zur Verfügung zu stellen, und die Funktionwilligt ein, eine bestimmte Aufgabe zu erfüllen.
polylinie benötigt beispielsweise vier Argumente: t muss eine Turtle sein, n ist die Anzahlder Liniensegmente und muss daher ein Integer sein. laenge muss eine positive Zahl sein,und winkel muss eine Zahl sein, die sich in Grad auswerten lässt.
Diese Anforderungen nennt man Vorbedingungen, weil sie erfüllt sein müssen, bevor dieFunktion mit der Ausführung beginnen kann.
Die Bedingungen gegen Ende der Funktion heißen entsprechend Nachbedingungen. Zuden Nachbedingungen gehören der gewünschte Effekt der Funktion (beispielsweise dasZeichnen von Liniensegmenten) sowie jegliche Nebeneffekte (Bewegungen der Schild-kröte oder andere Änderungen in der jeweiligen Welt).
Vorbedingungen unterliegen der Verantwortung des Aufrufenden. Falls der Aufrufendeeine (korrekt dokumentierte!) Vorbedingung nicht erfüllt und deshalb die Funktion nichtkorrekt arbeitet, liegt der Fehler beim Aufrufenden, nicht bei der Funktion.
Debugging | 49
GlossarInstanz:
Mitglied einer Gruppe. Die TurtleWorld in diesem Kapitel ist Mitglied einer Gruppevon TurtleWorlds.
Schleife:Teil eines Programms, der wiederholt ausgeführt wird
Datenkapselung:Vorgang, bei dem eine Folge von Anweisungen in eine Funktionsdefinition umge-wandelt wird
Generalisierung:Verfahren, um etwas unnötig Spezifisches (etwa eine Zahl) durch etwas Allgemeine-res (etwa eine Variable oder einen Parameter) zu ersetzen
Schlüsselwortargument:Argument, das den Namen des Parameters als »Schlüsselwort« enthält
Schnittstelle:Beschreibung, wie eine Funktion zu verwenden ist, einschließlich der Namen undBeschreibungen der Argumente sowie des Rückgabewerts
Refactoring:Vorgang, um die Funktionsschnittstellen und andere Qualitäten eines Programms zuverbessern
Entwicklungsplan:Verfahren zum Schreiben von Programmen
Docstring:String in einer Funktionsdefinition, der die Schnittstelle der Funktion dokumentiert
Vorbedingung:Bedingung, die vom Aufrufenden erfüllt werden muss, bevor eine Funktion aus-geführt werden kann
Nachbedingung:Anforderung, die von einer Funktion erfüllt werden muss, bevor sie beendet wird
Ubungen
Ubung 4-1:
Den Code für dieses Kapitel finden Sie in der Beispieldatei polygon.py.
1. Schreiben Sie entsprechende Docstrings für polygon, bogen und kreis.
50 | Kapitel 4: Fallstudie: Gestaltung von Schnittstellen
Allen B. Downey, Programmieren lernen mit Python, O´Reilly, ISBN 97839556180639783955618063
2. Zeichnen Sie ein Stapeldiagramm, das den Zustand des Programms bei der Aus-führung von kreis(tim, radius) darstellt. Die Berechnungen können Sie entwedervon Hand durchführen oder Sie können entsprechende print-Aufrufe in den Codeeinfügen.
3. Die Version von bogen im Abschnitt »Refactoring« auf Seite 47 ist nicht allzu genau,weil die lineare Annäherung an einen Kreis niemals einen echten Kreis ergibt. AlsKonsequenz davon landet die Schildkröte einige Einheiten von der korrekten Positionentfernt. Meine Lösung zeigt eine Möglichkeit, den Effekt dieser Abweichung zureduzieren. Lesen Sie den Code, und schauen Sie, ob er für Sie Sinn ergibt. Wenn Sieein Diagramm zeichnen, finden Sie vielleicht heraus, wie er funktioniert.
Ubung 4-2:
Schreiben Sie eine halbwegs allgemeine Sammlung von Funktionen, die Blumen wie die inAbbildung 4-1 zeichnen können.
Abbildung 4-1: Turtle-Blumen
Lösung: blumen.py, benötigt polygon.py
Ubung 4-3:
Schreiben Sie eine angemessen allgemeine Sammlung von Funktionen, die Formen wie diein Abbildung 4-2 zeichnen kann.
Abbildung 4-2: Turtle-Kuchen
Lösung: kuchen.py
Ubungen | 51
Ubung 4-4:
Die Buchstaben des Alphabets können aus einer überschaubaren Anzahl grundlegenderElemente aufgebaut werden, wie etwa vertikalen und horizontalen Linien sowie einigenKurven. Gestalten Sie eine Schrift, die mit einer minimalen Anzahl grundlegender Ele-mente gezeichnet werden kann, und schreiben Sie die Funktionen, die die Buchstaben desAlphabets zeichnen.
Schreiben Sie jeweils eine Funktion für jeden Buchstaben mit den Namen zeichne_a,zeichne_b usw., und legen Sie die Funktionen in einer Datei mit dem Namen buch-staben.py ab. Die Datei schreibmaschine.py enthält eine »Schildkrötenschreibmaschine«,mit der Sie Ihre Funktionen testen können.
Lösung: buchstaben.py, benötigt außerdem polygon.py
Ubung 4-5:
Informieren Sie sich über Spiralen unter http://de.wikipedia.org/wiki/Spirale. Schreiben Siedann ein Programm, das eine archimedische Spirale zeichnet (oder einen der anderenTypen).
Lösung: spirale.py
52 | Kapitel 4: Fallstudie: Gestaltung von Schnittstellen
Allen B. Downey, Programmieren lernen mit Python, O´Reilly, ISBN 97839556180639783955618063