100% fanden dieses Dokument nützlich (1 Abstimmung)
34 Ansichten400 Seiten

Einstieg in Python 3

Deutsch für Informatiker

Hochgeladen von

Olga Pavlova
Copyright
© All Rights Reserved
Wir nehmen die Rechte an Inhalten ernst. Wenn Sie vermuten, dass dies Ihr Inhalt ist, beanspruchen Sie ihn hier.
Verfügbare Formate
Als PDF, TXT herunterladen oder online auf Scribd lesen
100% fanden dieses Dokument nützlich (1 Abstimmung)
34 Ansichten400 Seiten

Einstieg in Python 3

Deutsch für Informatiker

Hochgeladen von

Olga Pavlova
Copyright
© All Rights Reserved
Wir nehmen die Rechte an Inhalten ernst. Wenn Sie vermuten, dass dies Ihr Inhalt ist, beanspruchen Sie ihn hier.
Verfügbare Formate
Als PDF, TXT herunterladen oder online auf Scribd lesen

Thomas Theis

Einstieg in Python 3

• Für Programmieranfänger und Umsteiger


♦ Mit vielen Beispielen und Übungsaufgaben
• Inkl. objektorientierter Programmierung, Datenbanken,
Internet u>v,m. ____________________

2. Auflage
Galileo Computing
Thomas Theis

Einstieg in Python 3

e·A
.,. • e
Gal ileo Press
Liebe Leserin, lieber Leser,

mit der Programmiersprache Python haben Sie eine gute Wahl getroffen: Sie ist
nicht nur leicht zu lernen, sie bietet Ihnen später auch das Potenzial für anspruchs-
vollere Projekte.

Dieses Buch wird Sie dabei auf Ihrem Weg von Anfang an begleiten. Schritt für
Schritt und jederzeit verständlich erlernen Sie zunächst anhand vieler kleiner Bei-
spiele die Grundlagen der Programmierung. Sie werden daher im Handumdrehen
in der Lage sein, Ihre ersten eigenen Python-Programme zu schreiben, selbst wenn
Sie vorher noch nie programmiert haben sollten. Im weiteren Verlauf des Buchs
macht Sie unser Autor Thomas Theis dann nach und nach natürlich auch mit den
fortgeschritteneren Themen der Python-Programmierung vertraut - selbstverständ-
lich alles aktuell zur neuen Version Python 3.

Im Vordergrund steht dabei stets die Praxis, denn auch mit dem besten Buch ler-
nen Sie Python nur, indem Sie selbst damit programmieren. Aus diesem Grund bie-
tet Ihnen das Buch nicht nur eine Vielzahl spielerischer Beispiele, sondern auch
zahlreiche Übungen, mit denen Sie Ihr neu gewonnenes Wissen direkt austesten
können. Alles, was Sie dafür benötigen, finden Sie auf der beiliegenden CD, so dass
Sie sofort loslegen können.

Dieses Buch wurde mit großer Sorgfalt geschrieben, geprüft und produziert. Sollte
dennoch einmal etwas nicht so funktionieren, wie Sie es erwarten, freue ich mich,
wenn Sie sich mit mir in Verbindung setzen. Ihre Kritik und konstruktiven Anre-
gungen, aber natürl ich auch I hr Lob sind uns jederzeit herzl ich will kommen!

Viel Spaß mit Python wünscht Ihnen nun

Ihre Christine Siedle


Lektorat Galileo Computing

ch ristine .siedle@[Link]
[Link]
Galileo Press· Rheinwerkallee 4·53227 Bonn
Auf einen Blick

1 Einführung ............................................................................ 13

2 Erste Sch ritte ........................................................................ 17

3 Programmierkurs ................................................................... 31

4 Datentypen ........................................................................... 77

5 Weiterführende Programmierung .......................................... 131

6 Objektorientierte Programmierung ........................................ 179

7 Neues in Python 3 ................................................................ 195

8 Verschiedene Module ........................................................... 199

9 Dateien................................................................................. 225

10 Internet ................................................................................ 257

11 Datenbanken ........................................................................ 291

12 Benutzeroberflächen 309

13 Lösungen .............................................................................. 379

3
Der Name Galileo Press geht auf den italienischen Mathematiker und Philosophen Galileo
Galilei (1564-1642) zurück. Er gilt als Gründungsfigur der neuzeitlichen Wissenschaft und
wurde berühmt als Verfechter des modernen, heliozentrischen Weltbilds. Legendär ist sein
Ausspruch Eppur se muove (Und sie bewegt sich doch). Das Emblem von Galileo Press ist der
Jupiter, umkreist von den vier Galileischen Monden. Galilei entdeckte die nach ihm benannten
Monde 1610.

Gerne stehen wir Ihnen mit Rat und Tat zur Seite:
[Link]@[Link] bei Fragen und Anmerkungen zum Inhalt des Buches
service@[Link] für versandkostenfreie Bestellungen und Reklamationen
[Link]@[Link] für Rezensions- und Schulungsexemplare

Lektorat Judith Stevens-Lemoine, Christine Siedle


Fachgutachten Carsten Reimer
I<orrektorat Bettina Mosbach
Cover Barbara Thoben, Köln
Titelbild Barbara Thoben, Köln
Typografie und Layout Vera Brauner
Herstellung Julia Bach
Satz Typographie & Computer, Krefeld
Druck und Bindung Bercker Graphischer Betrieb, Kevelaer

Dieses Buch wurde gesetzt aus der Linotype Syntax Serif (9,25/13,25 pt) in FrameMaker.
Gedruckt wurde es auf chlorfrei gebleichtem Offsetpapier.

Bibliografische Information der Deutschen Bibliothek


Die Deutsche Bibliothek verzeichnet diese Publikation in der Deutschen Nationalbibliografie;
detaillierte bibliografische Daten sind im Internet über [Link] abrufbar.

ISBN 978-3-8362-1406-3

© Galileo Press, Bonn 2009


2., aktualisierte Auflage

Das vorliegende Werk ist in all seinen Teilen urheberrechtlieh geschützt. Alle Rechte vorbehalten, insbesondere das Recht
der Übersetzung, des Vortrags, der Reproduktion, der Vervielfältigung auf fotomechanischem oder anderen Wegen und der
Speicherung in elektronischen Medien. Ungeachtet der Sorgfalt, die auf die Erstellung von Text, Abbildungen und Program-
men verwendet wurde, können weder Verlag noch Autor, Herausgeber oder Übersetzer für mögliche Fehler und deren Fol-
gen eine juristische Verantwortung oder irgendeine Haftung übernehmen. Die in diesem Werk wiedergegebenen Gebrauchs-
namen, Handelsnamen, Warenbezeichnungen usw. können auch ohne besondere Kennzeichnung Marken sein und als
solche den gesetzlichen Bestimmungen unterliegen.
Inhalt

1 Einführung ................................................................................ 13
1.1 Vorteile von Python ..................................................................... 13
1.2 Verbreitung von Python ............................................................... 14
1.3 Aufbau des Buchs ........................................................................ 14
1.4 Übungen ..................................................................................... 15
1.5 Installation von Python ................................................................ 16

2 Erste Schritte ........................................................................... 17


2.1 Python als Taschenrechner ........................................................... 17
2.1.1 Eingabe von Berechnungen ............................................. 17
2.1.2 Addition, Subtraktion und Multiplikation ........................ 18
2.1.3 Division, Ganzzahldivision und Modulo ........................... 18
2.1.4 Rangfolge und Klammern ................................................ 19
2.1.5 Variablen und Zuweisung ................................................ 20
2.2 Erstes Programm .......................................................................... 21
2.2.1 Hallo Welt ...................................................................... 21
2.2.2 Eingabe eines Programms ................................................ 22
2.3 Speichern und Ausführen ............................................................. 22
2.3.1 Speichern ........................................................................ 22
2.3.2 Ausführen unter Windows .............................................. 23
2.3.3 Ausführen unter Linux ..................................................... 27
2.3.4 Kommentare................................................................... 27
2.3.5 Verkettung von Ausgaben ............................................... 28
2.3.6 Lange Ausgaben .............................................................. 28

3 Programmierkurs ...................................................................... 31
3.1 Ein Spiel programmieren .............................................................. 31
3.1.1 Das fertige Spiel .............................................................. 31
3.1.2 Der Weg zum fertigen Spiel............................................. 31
3.1.3 Mögliche Erweiterungen ................................................. 32
3.2 Variablen und Operatoren ........................................................... 32
3.2.1 Berechnung und Zuweisung ............................................ 32
3.2.2 Eingabe einer Zeichen kette ............................................. 33
3.2.3 Eingabe einer Zahl........................................................... 33
3.2.4 Spiel, Version mit Eingabe ............................................... 35
3.2.5 Zufallszahlen ................................................................... 36

5
Inhalt

3.3 Verzweigungen ............................................................................ 37


3.3.1 Vergleichsoperatoren ...................................................... 38
3.3.2 Einfache Verzweigung ..................................................... 38
3.3.3 Spiel, Version mit Bewertung der Eingabe ....................... 39
3.3.4 Mehrfache Verzweigung .................................................. 40
3.3.5 Logische Operatoren ....................................................... 42
3.3.6 Mehrere Vergleichsoperatoren ........................................ 44
3.3.7 Spiel, Version mit genauer Bewertung der Eingabe .......... 45
3.3.8 Rangfolge der Operatoren .............................. ................. 46
3.4 Schleifen...................................................................................... 47
3.4.1 for-Schleife ..................................................................... 47
3.4.2 Schleifenabbruch mit break ............................................. 48
3.4.3 Geschachtelte I<ontrollstrukturen .................................... 48
3.4.4 Spiel, Version mit for-Schleife und Abbruch .................... 50
3.4.5 for-Schleife mit rangeO .................................................... 51
3.4.6 Spiel, Version mit rangeO ................................................ 54
3.4.7 while-Schleife ................................................................. 56
3.4.8 Spiel, Version mit while-Schleife und Zähler .................... 57
3.5 Fehler und Ausnahmen ................................................................ 58
3.5.1 Basisprogramm ................................................................ 58
3.5.2 Programmabbruch vermeiden ......................................... 59
3.5.3 Fehler abfangen .............................................................. 61
3.5.4 Exkurs: Schleifenfortsetzung mit continue ....................... 62
3.5.5 Spiel, Version mit Ausnahmebehandlung ........................ 63
3.6 Funktionen und Module .............................................................. 65
3.6.1 Einfache Funktionen ........................................................ 66
3.6.2 Funktionen mit einem Parameter .................................... 68
3.6.3 Funktionen mit mehreren Parametern ............................. 69
3.6.4 Funktionen mit Rückgabewert ......................................... 70
3.6.5 Spiel, Version mit Funktionen ......................................... 71
3.7 Das fertige Spiel........................................................................... 72

4 Datentypen .............................................................................. 77
4.1 Zahlen 77
4.1.1 Ganze Zahlen ................................................................. . 77
4.1.2 Zahlen mit Nachkommastelien ...................................... .. 79
4.1.3 Operatoren..................................................................... 80
4.1.4 Rundung und I<onvertierung ........................................... 80
4.1.5 Modul math .................................................................... 82
4.1.6 Brüche............................................................................ 83

6
Inhalt

4.2 Zeichenketten .............................................................................. 86


4.2.1 Eigenschaften.................................................................. 86
4.2.2 Operatoren ..................................................................... 87
4.2.3 Operationen ................................................................... 89
4.2.4 Funktionen..................................................................... 91
4.2.5 Umwandlung von Zeichenkette in Zahl........................... 94
4.2.6 Umwandlung von Zahl in Zeichenkette ........................... 96
4.2.7 Datentyp bytes................................................................ 97
4.3 Listen 98
4.3.1 Eigenschaften.................................................................. 98
4.3.2 Operatoren..................................................................... 100
4.3.3 Funktionen und Operationen .......................................... 101
4.4 Tupel 104
4.4.1 Eigenschaften .................................................................. 104
4.4.2 Operationen................................................................... 104
4.4.3 Tupel entpacken ............................................................. 106
4.5 Dictionarys .................................................................................. 109
4.5.1 Eigenschaften .................................................................. 109
4.5.2 Funktionen ..................................................................... 110
4.5.3 Views .............................................................................. 111
4.5.4 Vergleiche ....................................................................... 113
4.6 Mengen, Sets ............................................................................... 114
4.6.1 Eigenschaften .................................................................. 114
4.6.2 Funktionen ..................................................................... 115
4.6.3 Operatoren ..................................................................... 116
4.6.4 Frozenset ........................................................................ 119
4.7 Wahrheitswerte und Nichts ......................................................... 120
4.7.1 Wahrheitswerte True und False ....................................... 120
4.7.2 Nichts, None ................................................................... 123
4.8 Referenz, Identität und Kopie ...................................................... 125
4.8.1 Referenz und Identität .................................................... 125
4.8.2 Ressourcen sparen .......................................................... 127
4.8.3 Objekte kopieren ............................................................ 128

5 Weiterführende Programmierung ............................................ 131


5.1 Allgemeines ................................................................................. 131
5.1.1 Kombinierte Zuweisungsoperatoren ................................ 131
5.1.2 Anweisung in mehreren Zeilen ........................................ 133
5.1.3 Eingabe mit Hilfestellung ................................................ 134

7
Inhalt

5.1.4 Anweisung pass .............................................................. 135


5.1.5 Funktionen evalO und execO ........................................... 137
5.2 Ausgabe und Formatierung .......................................................... 138
5.2.1 Funktion printO ............................................................... 138
5.2.2 Formatierte Ausgabe ....................................................... 140
5.3 Conditional Expression ................................................................ 144
5.4 Iterierbare Objekte ...................................................................... 145
5.4.1 Funktion zipO .................................................................. 146
5.4.2 Funktion mapO ............................................................... 146
5.4.3 Funktion filterO ............................................................... 148
5.5 List Comprehension ..................................................................... 149
5.6 Fehler und Ausnahmen ................................................................ 151
5.6.1 Allgemeines .................................................................... 151
5.6.2 Syntaxfehler .................................................................... 152
5.6.3 Laufzeitfehler .................................................................. 153
5.6.4 Logische Fehler und Debugging ...................................... 154
5.6.5 Fehler erzeugen .............................................................. 158
5.6.6 Unterscheidung von Ausnahmen ..................................... 159
5.7 Funktionen .................................................................................. 161
5.7.1 Variable Anzahl von Parametern ...................................... 161
5.7.2 Benannte Parameter ........................................................ 162
5.7.3 Voreinstellung von Parametern ....................................... 163
5.7.4 Mehrere Rückgabewerte ................................................. 164
5.7.5 Übergabe von I<opien und Referenzen ............................ 165
5.7.6 Lokal, global ................................................................... 168
5.7.7 Lambda-Funktion ............................................................ 169
5.8 Eingebaute Funktionen ................................................................ 170
5.8.1 Übersicht ........................................................................ 170
5.8.2 Funktionen maxO, minO und sumO ................................. 171
5.8.3 Funktionen chrO und ordO .............................................. 172
5.8.4 Funktionen reversedO und sortedO ................................. 173
5.9 Eigene Module ............................................................................ 174
5.9.1 Eigene Module erzeugen ................................................. 174
5.9.2 Eigene Module verwenden .............................................. 175
5.10 Parameter der I<ommandozeile .................................................... 176
5.10.1 Übergabe von Zeichenketten ........................................... 176
5.10.2 Übergabe von Zahlen ...................................................... 177
5.10.3 Beliebige Anzahl von Parametern .................................... 177

8
Inhalt

6 Objektorientierte Program m ieru ng ......................................... 179


6.1 Was ist OOP? .............................................................................. 179
6.2 I<lassen, Objekte und eigene Methoden ....................................... 180
6.3 I<onstruktor und Destruktor ......................................................... 182
6.4 Besondere Methoden .................................................................. 184
6.5 Operatormethoden ...................................................................... 185
6.6 Referenz, Identität und I<opie ...................................................... 187
6.7 Vererbung ................................................................................... 189
6.8 Mehrfachvererbung ..................................................................... 192

7 Neues in python 3 .................................................................... 195


7.1 Neue und geänderte Eigenschaften .............................................. 195
7.1.1 Auffällige Änderungen ..................................................... 195
7.1.2 Weitere Änderungen ....................................................... 196
7.2 I<onvertierung von Python 2 zu Python 3 ..................................... 197

8 Verschiedene Module ............................................................... 199


8.1 Datum und Zeit ........................................................................... 199
8.1.1 Spielen mit Zeitangabe .................................................... 199
8.1.2 Aktuelle Zeit ausgeben .................................................... 199
8.1.3 Zeitangabe erzeugen ....................................................... 203
8.1.4 Mit Zeitangaben rechnen ................................................ 204
8.1.5 Programm anhalten ......................................................... 206
8.1.6 Spiel, Version mit Zeitmessung ........................................ 208
8.2 Modul collections ........................................................................ 209
8.3 Multithreading ............................................................................ 212
8.3.1 Wozu dient Multithreading? ........................................... 212
8.3.2 Erzeugung eines Threads ................................................. 212
8.3.3 Identifizierung eines Threads ........................................... 213
8.3.4 Gemeinsame Objekte ...................................................... 215
8.3.5 Threads und Exceptions .................................................. 216
8.4 Reguläre Ausdrücke ..................................................................... 218
8.4.1 Suchen von Teiltexten ..................................................... 218
8.4.2 Ersetzen von Teiltexten ................................................... 222

9 Dateien ..................................................................................... 225


9.1 Dateitypen ................................................................................... 225
9.2 Öffnen und Schließen einer Datei ................................................ 226

9
Inhalt

9.3 Sequenzielle Dateien ................................................................... 227


9.3.1 Sequenzielles Schrei ben .................................................. 227
9.3.2 Sequenzielles Lesen ......................................................... 229
9.3.3 CSV-Datei schreiben ....................................................... 234
9.3.4 CSV- Datei lesen .............................................................. 236
9.4 Dateien mit festgelegter Struktur ................................................. 237
9.4.1 Formatiertes Schreiben .................................................... 238
9.4.2 Lesen an bel iebiger Stelle ................................................ 239
9.4.3 Schreiben an beliebiger Stelle .......................................... 241
9.5 Modul pickle ............................................................................... 242
9.5.1 Objekte in Datei schreiben .............................................. 242
9.5.2 Objekte aus Datei lesen .................................................. 244
9.6 Bearbeitung mehrerer Dateien ..................................................... 246
9.7 Informationen über Dateien ......................................................... 247
9.8 Dateien und Verzeichnisse verwalten ........................................... 248
9.9 Spiel, Version mit Highscore-Datei ............................................... 249
9.9.1 Eingabebeispiel ............................................................... 250
9.9.2 Aufbau des Programms ................................................... 250
9.9.3 Code des Programms ...................................................... 251

10 Internet .................................................................................... 257


10.1 Laden und Senden von Internetdaten .......................................... 257
10.1.1 Lokaler Webserver ....................................................... 257
10.1.2 Daten lesen .................................................................. 258
10.1.3 Daten kopieren ............................................................ 261
10.1.4 Daten senden per GET ................................................. 261
10.1.5 Daten senden per POST ............................................... 264
10.2 Webserver-Programmierung ........................................................ 267
10.2.1 Erstes Programm .......................................................... 267
10.2.2 Beantworten einer Benutzereingabe ............................. 268
10.2.3 Formularelemente mit mehreren Werten ..................... 272
10.2.4 Typen von Formularelementen ..................................... 274
10.3 Browser aufrufen ......................................................................... 280
10.4 Spiel, Version für das Internet ...................................................... 281
10.4.1 Eingabebeispiel ............................................................ 281
10.4.2 Aufbau des Programms ................................................ 283
10.4.3 Code des Programms ................................................... 284

10
Inhalt

11 Datenbanken ............................................................................ 291


11.1 Aufbau von Daten banken ............................................................ 291
11.2 SQ Lite ......................................................................................... 292
11.2.1 Datenbank, Tabelle und Datensätze ............................. 292
11.2.2 Daten anzeigen ............................................................ 295
11.2.3 Daten auswählen, Operatoren ..................................... 296
11.2.4 Operator I ike ............................................................... 298
11.2.5 Sortierung der Ausgabe................................................ 300
11.2.6 Auswahl nach Eingabe ................................................. 301
11.2.7 Datensätze ändern ....................................................... 303
11.2.8 Datensätze läschen ...................................................... 305
11.3 SQ Lite auf dem Webserver .......................................................... 306

12 Benutzeroberflächen ................................................................ 309


12.1 Einführung ................................................................................... 309
12.1.1 Eine erste GUI-Anwendung .......................................... 310
12.1.2 Ändern von Eigenschaften ............................................ 311
12.2 Widget-Typen .............................................................................. 313
12.2.1 Anzeigefeld, Label ........................................................ 313
12.2.2 Einzeilige Textbox, Entry .............................................. 316
12.2.3 Versteckte Eingabe ...................................................... 318
12.2.4 Mehrzeilige Textbox, Text ............................................ 320
12.2.5 Scrollende Textbox, ScrolledText .................................. 322
12.2.6 Listbox mit einfacher Auswahl ...................................... 323
12.2.7 Listbox mit mehrfacher Auswahl .................................. 325
12.2.8 Scrollbar, scrollende Widgets ....................................... 327
12.2.9 Radio-Buttons zur Auswahl, Widget-Variablen ............. 329
12.2.10 Radio-Buttons zur Auswahl und Ausführung ................ 331
12.2.11 Check-Buttons zur mehrfachen Auswahl ...................... 333
12.2.12 Schieberegler, Scale ..................................................... 335
12.2.13 Mausereignisse ............................................................ 338
12.2.14 Tastaturereignisse ........................................................ 341
12.3 Geometrische Anordnung von Widgets ........................................ 343
12.3.1 Frame-Widget, Methode packO ................................... 343
12.3.2 Ein einfacher Taschenrechner ....................................... 346
12.3.3 Methode gridO ............................................................ 351
12.3.4 Methode placeO, absolute Koordinaten ....................... 353

11
Inhalt

12.3.5 Methode placeO, relative I<oord inaten ......................... 355


12.3.6 Absolute Veränderung von I<oordinaten ...................... 357
12.3.7 Relative Veränderung von I<oord inaten ........................ 359
12.4 Menüs und MessageBoxes ........................................................... 363
12.4.1 Menüleisten ................................................................. 363
12.4.2 I<ontextmenüs ............................................................. 368
12.4.3 Message Boxes.............................................................. 372

13 Lösungen .................................................................................. 379

Index ............................................................................................................ 387

12
I
1 Einführung

In diesem Kapitel wird Ihnen Python kurz vorgestellt. Sie lernen die Vor-
teile von Python kennen und erfahren, wie die Programmierumgebung
unter Windows installiert wird.

1.1 Vorteile von Python

Python ist eine sehr einfach zu erlernende Programmiersprache und für Leicht zu lernen
den Einstieg in die Welt der Programmierung ideal geeignet. Trotz ihrer
Einfachheit bietet diese Sprache auch die Möglichkeit, komplexe Pro-
gramme für vielfältige Anwendungsgebiete zu schreiben.
Python eignet sich besonders zur schnellen Entwicklung umfangreicher
Anwendungen. Diese Technik ist unter dem Stichwort RAD (= Rapid
Application Development) bekannt geworden. Python vereint zu diesem
Zweck folgende Vorteile:

~ Eine einfache, eindeutige Syntax: Python ist eine ideale Programmier- Einfach
sprache für Einsteiger. Sie beschränkt sich auf einfache, klare Anwei-
sungen. In anderen Programmiersprachen werden vielfältige Lösungs-
wege für das gleiche Problem angeboten, sodass der Entwickler
weniger geleitet als verunsichert wird. Python beschränkt sich dagegen
häufig auf einen einzigen möglichen Lösungsweg. Dieser prägt sich
schnell ein und wird dem Entwickler vertraut.
~ Klare Strukturen: Python zwingt den Entwickler, in einer gut lesbaren Klar
Struktur zu schreiben. Die Anordnung der Programmzeilen ergibt
gleichzeitig die logische Struktur des Programms.
~ Wiederverwendung von Code: Die Modularisierung, also die Zerle- Wiederver-
gung eines Problems in Teilprobleme und die anschließende Zusam- wendbar

menführung der Teillösungen zu einer Gesamtlösung, wird in Python


sehr leicht gemacht. Die vorhandenen Teillösungen können unkom-
pliziert für weitere Aufgabenstellungen genutzt werden, sodass Sie als
Entwickler bald über einen umfangreichen Pool an Modulen verfügen.

13
1 I Einführung

Einheitliche ~ Objektbearbeitung: In Python werden alle Daten als Objekte gespei-


Objekte chert. Dies führt zu einer einheitlichen Datenbehandlung für Objekte
unterschiedlichen Typs. Andererseits wird die physikalische Speiche-
rung der Objekte von Python automatisch, ohne Eingriff des Entwick-
lers vorgenommen. Der Entwickler muss sich nicht um die Reservie-
rung und Freigabe geeigneter Speicherbereiche kümmern.
Interpretiert ~ Interpreter / Compiler: Python-Programme werden unmittelbar inter-
pretiert. Sie müssen nicht erst kompiliert und gebunden werden. Dies
ermöglicht einen häufigen, schnellen Wechsel zwischen Codierungs-
und Testphase.
Unabhängig ~ Unabhängigkeit vom Betriebssystem: Sowohl Programme, die von
der Kommandozeile aus bedient werden, als auch Programme mit
grafischen Benutzeroberflächen können auf unterschiedlichen
Betriebssystemen (Windows, Unix/Linux, Mac OS) ohne Neuentwick-
lung und Anpassung eingesetzt werden.

1.2 Verbreitung von Python

Innerhalb des Projekts 100-Dollar-Laptop, das der Schulausbildung von


Kindern in aller Welt dient, wird Python für die Benutzeroberfläche ver-
wendet. Es wird in zahlreichen weiteren Unternehmen eingesetzt:
~ Google: Python ist eine der drei offiziellen Programmiersprachen.
(Guido van Rossum, der Entwickler von Python, arbeitet für Google.)
~ YouTube: Wurde zum großen Teil mit Hilfe von Python entwickelt.
~ NASA: Nutzt Python zur Softwareentwicklung im Zusammenhang mit
den Space-Shuttle-Missionen.
~ Industrial Light and Magic (Filmproduktion)
~ Honeywell (Hardware- und Softwareentwicklung)

1.3 Aufbau des Buchs

Aktiv lernen Das vorliegende Buch soll Sie in die Programmiersprache Python einfüh-
ren. Es wird besonderer Wert darauf gelegt, dass Sie selbst praktisch mit
Python arbeiten. Daher möchte ich Sie von Anfang an dazu auffordern,
dem logischen Faden von Erklärungen und Beispielen zu folgen.
Erste Zusammenhänge werden in Kapitel 2, »Erste Schritte«, anhand von
einfachen Berechnungen vermittelt. Außerdem lernen Sie, ein Pro-

14
Übungen I 1·4 I
gramm einzugeben, zu speichern und es unter den verschiedenen Umge-
bungen auszuführen.
Sie sollen die Sprache spielerisch kennenlernen. Daher wird Sie ein selbst Spielerisch lernen
programmiertes Spiel durch das Buch begleiten. Dieses Spiel wird mit dem
»Programmierkurs« in Kapitel 3 eingeführt und im weiteren verlauf des
Buchs kontinuierlich erweitert und verbessert.
Nach der Vorstellung der verschiedenen Datentypen mit ihren jeweili-
gen Eigenschaften und Vorteilen in Kapitel 4, »Datentypen«, werden die
Programmierkenntnisse in Kapitel 5, »Weiterführende Programmie-
rung«, vertieft.
Kapitel 6, »Objektorientierte Programmierung«, widmet sich der objekt- Objektorientiert
orientierten Programmierung mit Python.

Python hat mit der Version 3.0 große Änderungen erfahren. Diese Ände- Python 3.0
rungen sind in alle Kapitel und Programme dieses Buchs integriert. Kapi-
tel 7, »Neues in Python 3«, fasst die Neuerungen, die besonders für Ein-
steiger interessant sind, noch einmal übersichtlich zusammen.

Einige nützliche Module zur Ergänzung der Programme werden im Kapi-


tel 8, »Verschiedene Module«, vorgestellt.

In den Kapiteln 9, »Dateien«, und 11, »Datenbanken«, lernen Sie, Daten


dauerhaft in Dateien oder Datenbanken zu speichern. Python wird
zudem in der Internetprogrammierung eingesetzt. Die Zusammenhänge
zwischen Python und dem Internet vermittelt Kapitel 10, »Internet«.

Sowohl Windows als auch Linux bieten komfortable grafische Benutzero- Grafische
berflächen. Kapitel 12, »Benutzeroberflächen«, beschäftigt sich daher mit Oberflächen

der Erzeugung von Benutzeroberflächen mithilfe des Moduls tkinter.


Dieses stellt eine Schnittstelle zwischen dem grafischen Toolkit Tk und
Python dar.

Für die Hilfe bei der Erstellung dieses Buchs bedanke ich mich bei Bettina
Mosbach, Carsten Reimer und dem ganzen Team von Galileo Press, ganz
besonders bei Christine Siedle.

1.4 Übungen

In Kapitel 3, »Programmierkurs«, und in weiteren Kapiteln werden


Übungsaufgaben gestellt, die unmittelbar gelöst werden sollten. Auf
diese Weise können Sie Ihre Kenntnisse prüfen, bevor Sie zum nächsten

15
1 I Einführung

Thema übergehen. Die Lösungen der Übungsaufgaben finden Sie in


Kapitel 13 am Ende des Buchs. Dabei ist Folgendes zu beachten:

Viele Lösungen ~ Es gibt für jedes Problem viele richtige Lösungen. Sie sollten sich also
nicht davon beunruhigen lassen, dass Ihre Lösung eventuell nicht
genau so aussieht wie die angegebene. Betrachten Sie die angegebene
Lösung vielmehr als Anregung, was man anders und gegebenenfalls
besser machen kann.
~ Bei der eigenen Lösung der Aufgaben wird sicherlich der eine oder
andere Fehler auftreten - lassen Sie sich dadurch nicht entmutigen ...
Aus Fehlern lernen ~ ... denn nur aus Fehlern kann man lernen. Auf die vorgeschlagene Art
und Weise werden Sie Python wirklich erlernen - nicht allein durch
das Lesen von Programmierregeln.

1.5 Installation von Python

Software auf CD Python ist eine frei verfügbare Programmiersprache, die auf verschiede-
nen Betriebssystemplattformen eingesetzt werden kann. Auf der CD zu
diesem Buch findet sich die Version 3.0 für Windows. Die jeweils neu-
este Version kann man sich von der offiziellen Python-Website
[Link] aus dem Internet laden.

Installation Rufen Sie zur Installation unter Windows die ausführbare Datei python-
3. O. msi auf. Die Voreinstellungen des Installationsvorganges können
unverändert übernommen werden. Dabei wird Python im Verzeichnis
c:\python30 installiert. Anschließend verfügt man im Startmenü über
einen Eintrag PYTHON 3.0 mit folgendem Inhalt:

o IDLE (Python GUI)


o Module Docs
~, Python (command line)

~ Python Manuals
6 Uninstall Python

Abbildung 1.1 Startmenü, Python

16
2 Erste Schritte I
In diesem Kapitel werden Sie Python zum ersten Mal einsetzen -
zunächst als Taschenrechner. Außerdem lernen Sie, ein Programm einzu-
geben, zu speichern und auszuführen.

2.1 Python als Taschenrechner

Sie können Python zunächst wie einen einfachen Taschenrechner benut-


zen. Dies erleichtert Ihnen den Einstieg in Python.

2.1.1 Eingabe von Berechnungen


Rufen Sie (unter Windows Vista oder XP) über START· (ALLE) PROGRAMME Python Shell
• PYTHON 3.0 • IDLE (PYTHON GU!) die nachfolgend dargestellte Entwick-
lungsumgebung IDLE für Python auf. Sie wird auch PYTHON SHELL
genannt und kann sowohl als Editor zur Eingabe der Programme als auch
als einfacher Taschenrechner genutzt werden.

Python Shell
Fi le Edit Shell Debug Options Windows Help
Python 3 . 0 (r30:67507 , Dec 3 2008, 20:14:27)
32
Type "copyright ,r , r' cred i ts" 01:" pr l icense () pr for

Persona l firewal l software may warn about


makes co its subprocess using chis computE
interface . Th is connection i::l not visib l e
int e rface and no data i3 sent to 0[" rec e i

ID LE 3 . 0
>>> I

Abbildung 2.1 Python-Entwicklungsumgebung IDLE

Zur Durchführung kleinerer Berechnungen müssen keine vollständigen Kleinere


Programme geschrieben und gestartet werden. Man kann die gewünsch- Berechnungen
ten Rechenoperationen direkt an der Eingabestelle, erkennbar an den
Zeichen >>>, eingeben. Eine abschließende Betätigung der Taste [EJ
führt zur unmittelbaren Berechnung und Ausgabe des Ergebnisses.

17
2 I Erste Schritte

Die dabei angewendeten Rechenregeln finden auch bei der Erstellung


von Python-Programmen Verwendung. Es lohnt sich also eine genauere
Betrachtung.

2.1.2 Addition, Subtraktion und Multiplikation


Im Folgenden werden Eingabe, Verarbeitung und Ausgabe einiger einfa-
cher Berechnungen dargestellt:
»>41+7.5
48.5
»> 12 18
-6
»> 7 * 3
21

Zur Erläuterung:
Operatoren +, -, * ~ Der Reihe nach werden die Operatoren + (Addition), - (Subtraktion)
und * (Multiplikation) eingesetzt. Wenn Sie die Taste [EJ betätigen,
erscheint das Ergebnis jeweils in der Zeile darunter.
~ Als Dezimalzeichen gilt der Punkt, wie bei der ersten Berechnung (41
+ 7. 5 ~ 48.5) erkennbar.

2.1.3 Division, Ganzzahldivision und Modulo


Es folgen zwei Divisionsaufgaben:
»> 22 / 8
2.75
»> 22 / -8
-2.75

Zur Erläuterung:

Operator / ~ Der Operator / dient zur normalen Division.

Seltener genutzt werden die beiden Operatoren für die Ganzzahldivision


und die Modulo-Berechnung.

Zunächst zwei Beispiele zur Ganzzahldivision:


»> 22 /I 8
2
»> 22 /I -8
-3

18
Python als Taschenrechner I 2.1

Zur Erläuterung:

~ Der Operator / / dient zur Ganzzahldivision. Operator //


I
~ Bei einer Ganzzahldivision wird das Ergebnis berechnet, indem
~ zunächst das exakte Ergebnis inklusive etwaiger Nachkommastel-
Ien ermittelt wird und
~ anschließend die nächstkleinere ganze Zahl ermittelt wird.

Ein Beispiel zum Operator % (Modulo): Operator %

22 % 8
6

Zur Erläuterung:
~ Mit dem Operator % wird der Rest einer Ganzzahldivision berechnet.
~ Die Ganzzahldivision »22 durch 8« ergibt »2 Rest 6«. Der Modulo-
Operator liefert also den Rest 6.

2.1.4 Rangfolge und 1<lammern


Es gilt, wie in der Mathematik, Punkt- vor Strich rechnung. Multiplika- Rangfolge
tion und Division haben also Vorrang vor Addition und Subtral<tion. Das
Setzen von Klammern führt dazu, dass die Ausdrücke innerhalb der
Klammern zuerst berechnet werden. Die folgenden Beispiele verdeutli-
chen die Rangfolge der Operatoren:
»> 7 + 2 * 3
13
»> (7 + 2) * 3
27

Listing 2.1 Rangfolge der Operatoren

Zur Erläuterung: Bei der ersten Rechnung werden zunächst 2 und 3 mul-
tipliziert, anschließend wird 7 addiert. Bei der zweiten Rechnung werden
zunächst 7 und 2 addiert, anschließend wird mit 3 multipliziert.

Übung U0201
Es wird vorausgesetzt, dass Python wie angegeben installiert wurde. Rufen Sie
die Entwicklungsumgebung IDLE auf. Ermitteln Sie die Ergebnisse der folgen-
den vier Aufgaben:

19
2 I Erste Schritte

12
~ 13-5·2+-
6

~
7 -
5
2 4

~
12 - 5·2
4

Die Lösungen aller Übungsaufgaben finden Sie im Anhang dieses Buchs.

2.1.5 Variablen und Zuweisung


Variablen Bisher wurde nur mit Zahlen gerechnet. Python kann, wie jede andere
zuweisen Programmiersprache auch, Zahlen in Variablen speichern, falls sie im
verlauf einer Berechnung mehrmals benötigt werden.

Dezimalpunkt Dies soll bei der Umrechnung einer Entfernungsangabe von englischen
Meilen in Kilometer gezeigt werden. Für die Umrechnung gilt: 1 Meile =
1609,344 Meter = 1,609344 Kilometer. Beachten Sie, dass Nachkomma-
stelIen mit einem Dezimalpunkt abgetrennt werden.
»> mi ~ 1.609344
»> 2 * mi
3.2186880000000002
»> 5 * mi
8.0467200000000005
»> 22.5 * mi
36.210239999999999
»> 2.35 * mi
3.7819584000000006

Zur Erläuterung:

Variable ~ Der Umrechnungsfaktor wird zunächst in der Variablen mi gespei-


chert. Auf diese Weise können mehrere Umrechnungen einfacher
nacheinander durchgeführt werden. Anschließend werden die ent-
sprechenden Kilometerwerte für 2 Meilen, 5 Meilen, 22,5 Meilen
und für 2,35 Meilen berechnet und ausgegeben.
Zuweisung ~ Die Speicherung des Umrechnungsfaktors geschieht mit einer Zuwei-
sung (mi ~ 1.609344). Folglich erhält die Variable mi den Wert, der
rechts vom Gleichheitszeichen steht (1.609344).

20
Erstes Programm I 2.2

Zwei Hinweise
1. In Python-Variablen können ganze Zahlen, Zahlen mit Nachkommastellen,
Zeichenketten (also Texte) und andere Objekte eines Programms mithilfe
Runden
I
von Zuweisungen gespeichert werden.
2. Es ist üblich, den Wert in Kilometer so auszugeben, dass auf drei Stellen
hinter dem Komma gerundet wird, also auf den Meter genau. Auf eine sol-
che formatierte Ausgabe wird später noch eingegangen.

Der Name einer Variablen kann unter Befolgung der folgenden Regeln Variablennamen
weitgehend frei gewählt werden:
~ Er kann aus den Buchstaben abis z, Abis Z, Ziffern oder dem Zeichen
_ (= Unterstrich) bestehen.
~ Er darf nicht mit einer Ziffer beginnen.
~ Er darf keinem reservierten Wort der Programmiersprache Python
entsprechen. Eine Liste der reservierten Wörter finden Sie auf der
vorderen Außenklappe.
~ Die Groß- und Kleinschreibung ist zu beachten: Namen und Anwei- Case sensitive
sungen müssen stets exakt wie vorgegeben geschrieben werden. Die
Namen mi und Mi bezeichnen also verschiedene Variablen.

Übung U0202
Für das englische Längenmaß Inch gilt folgende Umrechnung: 1 Inch ent-
spricht 2,54 Zentimetern. Berechnen Sie für die folgenden Angaben den Wert
in Zentimeter: 5 Inch, 20 Inch und 92,7 Inch. Vereinfachen Sie Ihre Berech-
nungen, indem Sie den Umrechnungsfaktor zunächst in einer Variablen spei-
chern.

2.2 Erstes Programm

Es soll ein erstes Python-Programm eingegeben, abgespeichert und auf- Eingabe, Verar-
gerufen werden. Dieser Vorgang wird im Folgenden ausführlich erklärt. beitung, Ausgabe

Die einzelnen Schritte sind später analog bei jedem Python-Programm


auszuführen.

2.2.1 Hallo Welt


Die Ausgabe Ihres ersten Python-Programms soll lauten:
Hallo Welt

21
2 I Erste Schritte

Hallo Welt Das Programm soll also den Text »Hallo Welt« auf dem Bildschirm anzei-
gen. Dies ist häufig das erste Programm, das man in einer beliebigen Pro-
grammiersprache schreibt.

2.2.2 Eingabe eines Programms


Neues Programm- Zur Eingabe des Programms wird in der Entwicklungsumgebung IDLE
fenster im Menü FILE zunächst der Menübefehl NEW WINDOW aufgerufen. Es
öffnet sich ein neues Fenster mit dem Titel UNTITLED. Das Hauptfenster
mit dem Titel PYTHON SHELL rückt in den Hintergrund. In dem neuen
Fenster wird das Programm wie in Abbildung 2.3 dargestellt eingegeben:

' Untitled '


File Edi t Forma t Run Options Wind o",s Help
print ( P'Hallo Welt" )

Abbildung 2.2 Eingabe des Programms in neuem Fenster

Zur Erläuterung:
~ Die eingebaute Funktion pr i nt ( ) gibt Text oder Werte von Variablen
auf dem Bildschirm aus.

2.3 Speichern und Ausführen

Damit man das Ergebnis des Programms sehen kann, muss es zunächst in
einer Datei gespeichert und anschließend ausgeführt werden.

2.3.1 Speichern
Speichern Zur Speicherung des Programms wird im aktuellen Fenster im Menü FILE
der Menübefehl SAVE aufgerufen. Das Programm wird in der Datei mit
dem Namen [Link] gespeichert (siehe Abbildung 2.4).

Dateiendung .py Nach Betätigung des Buttons SPEICHERN ist die Speicherung vollzogen.
Der Name der Datei (hier hallo) kann frei gewählt werden. Die Datei-
endung .py ist für Python-Programme allerdings zwingend vorgeschrieben.

22
Speichern und Ausführen I 2.3

Speichern untel

Speichern in : IB P~thon 30
[1JLEl I
IDl OLLs
IDl Ooc
Zuletzt lDl indude
verwendete 0 ...
IDl Lib
IDl libs
IDl td
Desktop
IDl Tools
[I LICENSE .txt
[I [Link]
[I REAOME.t xt
Eigene Dateien

Arbeitsplatz

Netzwerkumgeb
ung
Dateiname : Imn Speichern

Dateit~p : IP~thon and text file s ( ' . p~ : . p~w:. txt) Abbrechen

Abbildung 2.3 Speichern des Python-Programms

Das Fenster mit dem Programm sieht nun aus wie in Abbildung 2.5. dar-
gestellt. In der Titelzeile ist der Dateiname beziehungsweise der vollstän-
dige pfadname erkennbar.

[Link] - C:/Python30/[Link]
File Edit Format Run Options Windows Help
print ( "Hallo \Je lt" )

Abbildung 2.4 Dateiname und Pfad in Titelzeile

2·3·2 Ausführen unter Windows


Sie können das Programm unter Windows auf drei verschiedene Arten Aufrufen
aufrufen:
~ innerhalb der Entwicklungsumgebung IDLE (diese Methode nutzen
wir bei den meisten Programmen dieses Buchs)
~ von der Kommandozeile aus
~ per Doppelklick im Windows Explorer

23
2 I Erste Schritte

Innerhalb der Entwicklungsumgebung IDlE


Aufruf in IDLE Betrachten wir im Folgenden zunächst den Aufruf innerhalb der Ent-
wicklungsumgebung IDLE. Dazu wird im Menü RUN der Menübefehl
RUN MODULE ausgeführt (Taste [NJ). Das Hauptfenster der Entwick-
lungsumgebung (die Python-Shell) rückt in den Vordergrund, und der
Ausgabetext erscheint.
.~

~ py - C:\Python30\[Link]. Python Shell


File Edlt Format Run Options Wlndo' File Edit 5hell Debug Options
print ( "Hallo Welt" ) Python 3.0 (r30:67507,
32
Type "copyright", P' e re

Personal firewall
roakes to its subpr
interface. This c
interface and no d

IDLE 3.0
» > ~~~~~~~~~~~~~~~~~~

» >
Hallo Welt
>>> I

Abbildung 2.5 Aufruf in IDLE

über die Taskleiste kann man anschließend das Programmfenster wieder


in den Vordergrund rücken.

Kommandozeile Von der I<ommandozeile aus


Das Programm in der Datei [Link] ist ein Kommandozeilenprogramm.
Es erzeugt also eine einfache Ausgabe auf dem Bildschirm, ohne eine
eigene Benutzeroberfläche zu erzeugen. In Kapitel 12, »Benutzeroberflä-
chen«, lernen Sie, wie Sie mithilfe von Python Programme mit grafischen
Benutzeroberflächen erzeugen können.

Wechsel zur Für einen Aufruf des Programms aus der Kommandozeile muss unter
Kommandozeile Windows zunächst auf die Kommandozeilenebene gewechselt werden.
Dazu gehen Sie (unter Windows Vista oder XP) wie folgt vor:

~ Rufen Sie den Menüpunkt START· (ZUBEHÖR) • AUSFÜHREN auf.


~ Geben Sie im nun erscheinenden Eingabefenster die Anweisung emd
ein und drücken Sie den Button üK (siehe Abbildung 2.7).

24
Speichern und Ausführen I 2.3

Ausführen

=J:!!:.'J Ge ben Sie den Namen ei nes P r o gr am m s~ Ord ners)


[1](8) I
-:t!E!J Dokume nt s oder ein er Interne tr esso urce an.

Öffnen: I_ v I

OK : : : J [ Abbrechen I [Dur chsuchen " ,

Abbildung 2.6 Aufruf des Kommandozeilenfensters

Es erscheint das Kommandozeilenfenster:

Abbildung 2.7 Kommandozeilenfenster, nächste Eingabe

Mit Eingabe des Befehls cd \ Pyt hon3 0 wechseln Sie in das Verzeichnis Verzeichnis
C\Python30, in dem das Programm [Link] abgelegt wurde. Anschlie- wechseln

ßend veranlassen Sie die Ausführung des Programms mit der Anweisung
python ha 110. py. Es erscheint die in Abbildung 2.9 gezeigte Ausgabe.

Abbildung 2.8 Aufruf im Kommandozeilenfenster

Dieses Kommandozeilenfenster kann man für spätere Aufrufe von exit


Python-Programmen geöffnet lassen oder mit Eingabe des Befehls ex i t
wieder schließen.

25
2 I Erste Schritte

Per Doppelklick im Windows Explorer


Per Doppelklick Python-Programme können auch mit einem einfachen Doppelklick auf
den Dateinamen im Windows Explorer gestartet werden. Es öffnet sich
automatisch ein Kommandozeilenfenster, das sich allerdings nach der
Ausgabe sofort wieder schließt, sodass die Ausgabe nicht zu sehen ist.

Dieses verhalten können Sie ändern, indem Sie den Programmcode wie
folgt modifizieren:
print("Hallo Welt")
input ()

Listing 2.2 Datei [Link]

Zur Erläuterung:
inputO ~ Die eingebaute Funktion input ( ) wartet auf eine Eingabe des Benut-
zers. Diese Funktion werden wir später häufig benutzen, um Eingabe-
daten vom Anwender zu erhalten. Hier wird sie nur dazu benutzt, das
Programm anzuhalten, damit das Kommandozeilenfenster sichtbar
bleibt.

Nach erfolgter Änderung und erneuter Speicherung des Programms kann


es nun per Doppelklick aus dem Windows Explorer gestartet werden.
Die Ausgabe erscheint in einem Kommandozeilenfenster.

Dateiordne r
Dateio rdne r
Dat ei or dne r
Dateior dn er

Abbildung 2.9 Aufruf im Windows Explorer

Erst nach Betätigung der Taste CE] wird das Programm beendet. Das
Kommandozeilenfenster schließt sich wieder automatisch.

26
Speichern und Ausführen I 2.3

2.3.3 Ausführen unter Linux


Auch unter Linux können Sie Python-Programme von der Kommando- Neue erste Zeile
I
zeile aus aufrufen. Die meisten Linux-Installationen enthalten Python,
allerdings teilweise noch in einer Version 2.x. Als Ergänzung muss eine
neue erste Zeile in der Datei eingefügt werden, wie nachfolgend darge-
stellt:
#!/usr/bin/python
print("Hallo Welt")

Listing 2.3 Datei [Link]

Anschließend kann das Programm mit python [Link] unter Linux


gestartet werden.

- \ -:1. 1. _ I ~ I ' t· r 1 ' I tl 1 ~ .,

f-l i ~ 1 ;: 1 '
I .,1. . "00' I

Abbildung 2.10 Aufruf unter Linux

Zur Erläuterung:
~ Die erste Zeile mit dem Text lf!/usr/bin/python ist eigentlich eine
Kommentarzeile (siehe nächster Abschnitt). Kommentarzeilen wer-
den unter Windows ignoriert.
~ Unter Linux werden Kommentarzeilen normalerweise auch ignoriert.
Diese spezielle Kommentarzeile führt jedoch dazu, dass das Python-
Programm unter Linux ausgeführt wird.

2.3.4 I<ommentare
Bei umfangreicheren Programmen erweist es sich als sehr nützlich, Kom- Kommentar mit #
mentare zur Erläuterung in den Programmtext einzufügen. Kommentare
werden durch das Raute-Zeichen lf eingeleitet und reichen bis zum Zei-
lenende. Sie werden vom System nicht als Programmschritte betrachtet
und folglich nicht ausgeführt.

Im folgenden Listing wurde das erste Programm durch einen Kommentar


ergänzt:
# Mein erstes Programm
print("Hallo Welt")

Listing 2.4 Datei [Link]

27
2 I Erste Schritte

2.3.5 Verkettung von Ausgaben


Mithilfe der Funktion pr i nt ( ) können auch mehrere Ausgaben in einer
Zeile ausgegeben werden. Entsprechend wurde das Programm weiter
verändert:
# Mein erstes Programm
print("Hallo", "Welt")

Listing 2.5 Datei [Link]

Zur Erläuterung:
Kommata ~ Die einzelnen Teile der Ausgabe werden durch Kommata voneinan-
der getrennt.
~ Nach jedem Teil der Ausgabe wird automatisch ein Leerzeichen ein-
gesetzt. Dieses Verhalten kann man als Programmierer beeinflussen,
dazu später mehr.

2.3.6 Lange Ausgaben


Zeichenketten, die mithilfe der Funktion print() ausgegeben werden,
können sehr lang werden, eventuell sogar über den rechten Rand inner-
halb des Editors hinausgehen. Damit wird der Programmcode allerdings
etwas unübersichtlich. Sie können solche Zeichenketten aber auch auf
mehrere Zeilen verteilen - dieses Vorgehen wird auch im vorliegenden
Buch aufgrund der begrenzten Druckbreite häufig angewendet.

Übersichtlicher Wenngleich es für dieses kurze Programm eigentlich nicht notwendig ist,
wird die Verteilung des Codes auf mehrere Zeilen hier zur Verdeutli-
chung vorgenommen:
# Mein erstes Programm
print( "Hallo",
"Welt" )
print( "Hallo"
"Welt" )

Listing 2.6 Datei [Link]

Zur Erläuterung:
~ Es bietet sich an, den Zeilenumbruch nach einem Komma durchzu-
führen, wie bei der ersten Ausgabe von» Hallo Welt«. Dabei wird, wie
bereits ausgeführt, automatisch ein Leerzeichen gesetzt.

28
Speichern und Ausführen I 2.3

~ Einzelne lange Texte können in Teiltexte zerlegt werden, wie bei der
zweiten Ausgabe von »Hallo Welt«. Teiltexte müssen nicht durch
Kommata voneinander getrennt werden. Sie sind allerdings jeweils
Teiltexte
I
mit Anführungsstrichen zu begrenzen. Das trennende Leerzeichen
zwischen »Hallo« und »Welt« muss nun von Hand gesetzt werden.

Hinweis
In Abschnitt 5.1.2, »Anweisung in mehreren Zeilen«, wird erläutert, wie man
allgemein lange Programmzeilen aufteilen kann.

29
3 Programmierl<urs

I
Der folgende Programmierkurs mit ausführlichen Erläuterungen führt
Sie schrittweise in die Programmierung mit Python ein. Begleitet wird
der Kurs von einem Programmierprojekt, das die vielen Teilaspekte zu
einem Ganzen verknüpft.

3.1 Ein Spiel programmieren

Damit Sie die Programmiersprache Python auf unterhaltsame Weise ken-


nenlernen, sollen Sie im Folgenden selbst ein Spiel programmieren. Im
weiteren verlauf des Buchs wird dieses Spiel dann kontinuierlich erwei-
tert und verbessert.

3.1.1 Das fertige Spiel


Das Spiel läuft wie folgt ab: Dem Anwender wird nach Aufruf des Pro- Kopfrechnen
gramms eine Kopfrechenaufgabe gestellt. Er gibt das von ihm ermittelte
Ergebnis ein, und das Programm bewertet seine Eingabe.
Die Aufgabe: 9 + 26
Bitte eine Zahl eingeben:
34
34 ist falsch
Bitte eine Zahl eingeben:
35
35 ist richtig
Ergebnis: 35
Anzahl Versuche: 2

3.1.2 Der Weg zum fertigen Spiel


Das Spiel wird in mehreren Einzelschritten erstellt. Zunächst entsteht Das Spiel wächst.
eine ganz einfache Version. Mit wachsender Programmierkenntnis ent-
wickeln Sie dann immer komplexere Versionen. Die im jeweiligen
Abschnitt erlernten Programmierfähigkeiten setzen Sie unmittelbar zur
Verbesserung des Spielablaufs ein.

31
3 I Programmierkurs

3.1.3 Mögliche Erweiterungen


Versionen In späteren Abschnitten entstehen weitere Versionen des Spiels. Das
Spiel begleitet Sie so durch das gesamte Buch. Es wird unter anderem um
folgende Möglichkeiten erweitert:

~ mehrere Aufgaben nacheinander oder gleichzeitig stellen


~ Messung der benötigten Zeit
~ Speicherung der Spiel daten in einer Datei
~ Aktualisierung und Darstellung einer Highscore-Liste
~ Spielen im Internet

3.2 Variablen und Operatoren

Zur Speicherung von Werten werden Variablen benötigt. Operatoren


dienen zur Ausführung von Berechnungen.

3.2.1 Berechnung und Zuweisung


Im folgenden Programm wird eine einfache Berechnung mithilfe eines
Operators durchgeführt. Das Ergebnis der Berechnung wird mit dem
Gleichheitszeichen einer Variablen zugewiesen. Es erfolgt eine Ausgabe.
Diese Schritte kennen Sie bereits aus Abschnitt 2.1.5.
lf Werte
a 5
b ~ 3

lf Berechnung
c ~ a + b

lf Ausgabe
print("Die Aufgabe:", a, "+", b)
print("Das Ergebnis:", c)

Listing 3.1 Datei [Link]

Die Ausgabe des Programms lautet:


Die Aufgabe: 5 + 3
Das Ergebnis: 8

32
Variablen und Operatoren I 3.2

Zur Erläuterung:

~
In den beiden Variablen a und b wird jeweils ein Wert gespeichert.
Die Werte der beiden Variablen werden addiert, das Ergebnis wird
der Variablen c zugewiesen.
Eingangsdaten

Verarbeitung I
~ Die Aufgabenstellung wird ausgegeben. Anschließend wird das Ausgabe
Ergebnis ausgegeben.
~ Noch hat der Benutzer des Programms keine Möglichkeit, in den
Ablauf einzugreifen.

3.2.2 Eingabe einer Zeichen kette


Die Funktion input ( ) wurde bereits benutzt, um das Programm anzuhal-
ten. Dies war für die Ausführung des Programms per Doppelklick aus
dem Windows Explorer notwendig.

In diesem Abschnitt soll die Funktion input () zu ihrem eigentlichen inputO


Zweck genutzt werden: zur Eingabe einer Zeichenkette durch den Benut-
zer. Ein kleines Beispiel:
# Eingabe einer Zeichenkette
print("Bitte einen Text eingeben")
x~input()

print("Ihre Eingabe:", x)
Listing 3.2 Datei [Link]

Die Ausgabe könnte wie folgt aussehen:


Bitte einen Text eingeben
Python ist toll
Ihre Eingabe: Python ist toll
Zur Erläuterung:

~ Der Benutzer gibt einen kleinen Satz ein. Dieser Satz wird in der Vari-
ablen x gespeichert und anschließend ausgegeben.

3·2·3 Eingabe einer Zahl


Im weiteren verlauf des Spiels ist es notwendig, die Eingabe des Benut- Umwandlung
zers als zahl weiter zu verwenden. Dazu muss die Zeichenkette, die die
Funktion input ( ) liefert, in eine Zahl umgewandelt werden.

33
3 I Programmierkurs

Zur Umwandlung gibt es unter anderem die folgenden Funktionen:

intO ~ Die eingebaute Funktion i nt () wandelt eine Zeichenkette in eine


ganze Zahl um; eventuell vorhandene Nachkommastellen werden
abgeschnitten.
floatO ~ Die eingebaute Funktion fl oa t ( ) wandelt eine Zeichenkette in eine
Zahl mit Nachkommastellen um.

Ein Beispiel:
# Eingabe einer Zahl
print("Bitte eine ganze Zahl eingeben")
x~input()

print("Ihre Eingabe:", x)

# Umwandlung in ganze Zahl


xganz ~ int(x)
print("Als ganze Zahl:", xganz)

# Mit Berechnung
xdoppel ~ xganz * 2
print("Das Doppelte:", xdoppel)

Listing 3.3 Datei [Link]

Die Ausgabe könnte wie folgt aussehen:


Bitte eine ganze Zahl eingeben
6
Ihre Eingabe: 6
Al s ganze Zahl: 6
Das Doppelte: 12

Zur Erläuterung:
~ Der Benutzer gibt eine Zeichenkette ein.
~ Diese Zeichenkette wird mithilfe der eingebauten Funktion i nt ( ) in
eine ganze Zahl umgewandelt.
~ Die Zahl und das Doppelte der Zahl werden ausgegeben.

EVA In diesem Programm wird auch das EVA-Prinzip der klassischen Pro-
grammierung verdeutlicht:
~ E = Eingabe (der Anwender gibt Daten über die Tastatur ein)
~ V = Verarbeitung (das Programm verarbeitet diese und andere Daten)

34
Variablen und Operatoren I 3·2

~ A = Ausgabe (das Programm gibt das Ergebnis der Verarbeitung auf

I
dem Bildschirm aus)

3.2.4 Spiel, Version mit Eingabe


Das Spielprogramm wird mit einer Eingabe versehen. Es wird wie folgt
geändert:

# Werte und Berechnung


a 5
b 3
c a + b

print("Die Aufgabe:", a, "+" b)

lf Ei ngabe
print("Bitte eine Zahl eingeben:")
z~input()

lf Ei ngabe in Zahl umwandel n


zahl ~ int(z)

lf Ausgabe
print("Ihre Eingabe:", z)
print("Das Ergebnis:", c)

Listing 3.4 Datei [Link]

Eine mögliche Ausgabe des Programms:

Die Aufgabe: 5 + 3
Bitte eine Zahl eingeben:
9
Ihre Eingabe: 9
Das Ergebnis: 8

Zur Erläuterung:

~ DasProgrammgibtdieAufforderungBitte eine Zahl eingeben: aus


und hält an.
~ Die Eingabe des Benutzers wird in der Variablen z gespeichert.

~ Die Zeichenkette z wird mithilfe der Funktion i nt () in eine ganze intO


zahl verwandelt.

35
3 I Programmierkurs

Inch in Zentimeter Übung U0301


Schreiben Sie ein Programm zur Eingabe und Umrechnung von beliebigen
Inch-Werten in Zentimeter. Speichern Sie das Programm in der Datei
[Link]. Rufen Sie das Programm auf und testen Sie es.
Die Ausgabe sollte zum Beispiel wie folgt aussehen:
Bitte geben Sie den Inch Wert ein:
3.5
3.5 inch sind 8.89 cm

Steuer berechnen Übung U0302


Schreiben Sie ein Programm zur Berechnung des monatlich zu zahlenden Steu-
erbetrags. Der Anwender soll zunächst dazu aufgefordert werden, sein monat-
liches Bruttogehalt einzugeben. Anschließend werden (hier sehr vereinfacht)
18% dieses Betrags berechnet und ausgegeben. Speichern Sie das Programm
in der Datei [Link].
Die Ausgabe sollte zum Beispiel wie folgt aussehen:
Geben Sie Ihr Bruttogehalt in Euro ein:
2500
Es ergibt sich ein Steuerbetrag von 450.0 Euro

3.2.5 Zufallszah len


Natürlich soll nicht immer die gleiche Kopfrechenaufgabe gestellt wer-
den. In Python steht ein Zufallszahlengenerator zur Verfügung. Dieser
kann zufällige Zahlen generieren, die zur Bildung der Aufgabenstellung
genutzt werden sollen.
Modul Die Funktionen des Zufallszahlengenerators befinden sich in einem
importieren zusätzlichen Modul. das zunächst importiert werden muss. Das Pro-
gramm wird wie folgt verändert:
Ir Modul random importieren
import random

# Zufallsgenerator initialisieren
[Link]( )

# Zufallswerte und Berechnung


a [Link](l,lO)
b [Link](l,lO)
c a + b

print("Die Aufgabe:", a, "+" b)


Verzweigungen I 3·3

IrEi ngabe

I
print("Bitte eine Zahl eingeben:")
z~input()

zahl ~ int(z)

IrAusgabe
print("Ihre Eingabe:", z)
print("Das Ergebnis:", c)

Listing 3.5 Datei [Link]

Eine mögliche Ausgabe des Programms, abhängig von den gelieferten


zufälligen Werten, sieht wie folgt aus:
Die Aufgabe: 8 + 3
Bitte eine Zahl eingeben:
7
Ihre Eingabe: 7
Das Ergebnis: 11

Zur Erläuterung:
~ Zusätzliche Module können mithilfe der Anweisung i mpo rt in das import
Programm eingebunden werden.
~ Die Funktionen dieser Module können anschließend in der Schreib-
weise [Link] aufgerufen werden.
~ Der Aufruf der Funktion seed() des Moduls random führt dazu, dass seedO
der Zufallszahlengenerator mit der aktuellen Systemzeit initialisiert
wird. Anderenfalls könnte es passieren, dass anstelle einer zufälligen
Auswahl immer wieder dieselben Zahlen geliefert würden.
~ Die Funktion rand i nt ( ) des Moduls ra ndom liefert eine ganze Zufalls- randintO
zahl im angegebenen Bereich. Im vorliegenden Fall ist dies also eine
zufällige Zahl von 1 bis 10.

3.3 Verzweigungen

In den bisherigen Programmen wurden alle Anweisungen der Reihe Programmablauf


nach ausgeführt. Zur Steuerung eines Programmablaufs werden aller- steuern

dings häufig Verzweigungen benötigt. Innerhalb des Programms wird


dann aufgrund einer Bedingung entschieden, welcher Zweig des Pro-
gramms ausgeführt werden soll.

37
3 I Programmierkurs

3.3.1 Vergleichsoperatoren
Kleiner, größer, Bedingungen werden mithilfe von Vergleichsoperatoren formuliert. Die
gleich folgende Tabelle listet die Vergleichsoperatoren mit ihrer Bedeutung auf:

Bedeutung
größer als
kleiner als
>~ größer als oder gleich
<~ kleiner als oder gleich
gleich
!~ ungleich

Tabelle 3.1 Vergleichsoperatoren

3.3.2 Einfache Verzweigung


if-else Im folgenden Beispiel wird untersucht, ob eine Zahl positiv ist. Ist dies der
Fall, so wird Diese Zahl ist positiv ausgegeben, anderenfalls lautet
die Ausgabe Diese Zahl ist 0 oder negativ. Es wird also nur eine der
beiden Anweisungen ausgeführt.
x ~ 12

print("x:", x)

if x > 0:
print("Diese Zahl ist positiv")
else:
print("Diese Zahl ist 0 oder negativ")

Listing 3.6 Datei [Link]

Die Ausgabe des Programms lautet:


x: 12
Diese Zahl ist positiv

Zur Erläuterung:
~ In der ersten Zeile bekommt die Variable x den Wert 12 zugewiesen.
Doppelpunkt ~ In der zweiten Zeile wird mithilfe der Anweisung i f eine Verzwei-
gung eingeleitet. Danach wird eine Bedingung formuliert (hier x > 0),
die entweder wahr oder falsch ergibt. Anschließend folgt das Doppel-
punkt-Zeichen (:).
Verzweigungen I 3·3

~ Es folgen eine oder mehrere Anweisungen, die nur ausgeführt wer- Einrücken

I
den, wenn die Bedingung wahr ergibt. Die Anweisungen müssen
innerhalb des sogenannten i f-Zweigs mithilfe der I'~I I-Taste einge-
rückt werden, damit Python die Zugehörigkeit zur Verzweigung
erkennen kann. Gleichzeitig macht die Einrückung das Programm
übersichtlicher.
~ In der vierten Zeile wird mithilfe der Anweisung e 1se der alternative else
Teil der Verzweigung eingeleitet. Es folgt wiederum ein Doppelpunkt.
~ Es folgen eine oder mehrere Anweisungen, die nur ausgeführt wer-
den, falls die Bedingungfalsch ergibt. Auch diese Anweisungen müs-
sen eingerückt werden.

3·3·3 Spiel, Version mit Bewertung der Eingabe


Nun soll die Eingabe des Benutzers bewertet werden. Mithilfe einer ein- Eingabe prüfen
fachen Verzweigung wird untersucht, ob die Eingabe richtig oder falsch
war. Das Programm wird wie folgt verändert:
# Zufallsgenerator
import random
ra ndom. seed ( )

# Werte und Berechnung


a [Link](l,lO)
b [Link](l,lO)
c a + b

print("Die Aufgabe:", a, "+" b)

i! Ei ngabe
print("Bitte eine Zahl eingeben:")
z~input()

zahl ~ int(z)

i! Verzwei gung
if zahl ~~ c:

print(zahl, "ist richtig")


else:
print(zahl. "ist falsch")
print( "Ergebnis: ", c)
Listing 3.7 Datei [Link]

39
3 I Programmierkurs

Eine mögliche Ausgabe des Programms wäre:


Die Aufgabe: 2 + 8
Bitte eine Zahl eingeben:
11
11 ist falsch
Ergebnis: 10

Zur Erläuterung:

~ Die Eingabe wird in eine zahl umgewandelt.


Richtig ~ Entspricht diese zahl dem Ergebnis der Rechnung, so wird ist r i c ht i g
ausgegeben.
Falsch ~ Entspricht die Zahl nicht dem Ergebnis, so wird ist fa 1s eh ausgegeben,
und das korrekte Ergebnis wird genannt.

Übung U0303
Das Programm zur Berechnung des monatlich zu zahlenden Steuerbetrags soll
verändert werden. Der Anwender soll zunächst dazu aufgefordert werden, sein
monatliches Bruttogehalt einzugeben. Liegt das Gehalt über 2.500 Euro, so
sind 22% Steuer zu zahlen, ansonsten 18% Steuer. Speichern Sie das Pro-
gramm in der Datei [Link].
Programm Zur Erläuterung: Es ist nur eine Eingabe erforderlich. Innerhalb des Programms
entscheidet wird aufgrund des Gehalts entschieden, welcher Steuersatz zur Anwendung
kommt.
Die Ausgabe sollte zum Beispiel wie folgt aussehen:
Geben Sie Ihr Bruttogehalt in Euro ein:
3000
Es ergibt sich ein Steuerbetrag von 660.0 Euro
oder
Geben Sie Ihr Bruttogehalt in Euro ein:
2000
Es ergibt sich ein Steuerbetrag von 360.0 Euro

3.3.4 Mehrfache Verzweigung


Mehrere In vielen Anwendungsfällen gibt es mehr als zwei Möglichkeiten, zwischen
Möglichkeiten denen zu entscheiden ist. Dazu wird eine mehrfache Verzweigung benötigt.

if-elif-else Im folgenden Beispiel wird untersucht, ob eine Zahl positiv, negativ oder
gleich 0 ist. Es wird eine entsprechende Meldung ausgegeben:
x ~ -5
print("x:", x)

40
Verzweigungen I 3·3

if x > 0:
print("x ist positiv")
el if x < 0:

else:
print("x ist negativ")

print("x ist gleich 0" )


I
Listing 3.8 Datei [Link]

Die Ausgabe des Programms:


x: - 5
x ist negativ
Zur Erläuterung:

~ Mit der Anweisung i f wird die Verzweigung eingeleitet. Falls x posi- if


tiv ist, werden die nachfolgenden, eingerückten Anweisungen ausge-
führt.
~ Nach der Anweisung e 1 if wird eine weitere Bedingung formuliert. elif
Diese wird nur untersucht, wenn die erste Bedingung (nach dem i f)
nicht zutraf. Falls x negativ ist, werden die nachfolgenden, eingerück-
ten Anweisungen ausgeführt.
~ Die Anweisungen nach der Zeile mit der e 1se-Anweisung werden nur else
durchgeführt, falls keine der beiden vorherigen Bedingungen zutraf
(nach dem i f und nach dem e 1 i f). In diesem Fall bedeutet das, dass
x gleich 0 ist, da es nicht positiv und nicht negativ ist.

Innerhalb einer Verzweigung können mehrere e 1 if-Anweisungen vor- Mehrere elif-


kommen. Diese werden der Reihe nach untersucht, bis das Programm zu Anweisungen

der Bedingung kommt, die zutrifft. Die weiteren e 1 i f-Anweisungen


oder eine else-Anweisung werden dann nicht mehr beachtet.

Eine el se-Anweisung ist weder bei einer einfachen Verzweigung noch else muss nicht
bei einer mehrfachen Verzweigung zwingend notwendig. vorkommen.

Übung U0304
Das Programm zur Berechnung des monatlich zu zahlenden Steuerbetrags soll
weiter verändert werden (Datei [Link]). Der Anwender soll zunächst dazu
aufgefordert werden, sein monatliches Bruttogehalt einzugeben. Anschließend
soll das Gehalt nach der folgenden Steuertabelle berechnet werden:

41
3 I Programmierkurs

~
mehr als 4.000 Euro 26%
2.500 bis 4.000 Euro 22%
weniger als 2.500 Euro 18%

Tabelle 3.2 Steuertabelle für Übung U0304

3.3.5 Logische Operatoren


Logische Mithilfe der logischen Operatoren and, or und not können mehrere
Verknüpfung Bedingungen miteinander verknüpft werden.
and ~ Eine Bedingung, die aus einer oder mehreren Einzelbedingungen
besteht, die jeweils mit dem Operator a nd (= und) verknüpft sind,
ergibt wahr, wenn jede der Einzelbedingungen wahr ergibt.
or ~ Eine Bedingung, die aus einer oder mehreren Einzelbedingungen
besteht, die mit dem Operator 0 r (= oder) verknüpft sind, ergibt
wahr, wenn mindestens eine der Einzelbedingungen wahr ergibt.
not ~ Der Operator not (= nicht) kehrt den Wahrheitswert einer Bedingung
um, das heißt eine falsche Bedingung wird wahr, eine wahre Bedin-
gung wird falsch.
Wahrheitswerte Der gleiche Zusammenhang wird in der folgenden Wahrheitswerttabelle
dargestellt:

Bedingung 1 Bedingung 2 gesamte Bedingung


wahr and wahr wahr
wahr and falsch falsch
falsch and wahr falsch
falsch and falsch falsch
wahr or wahr wahr
wahr or falsch wahr
falsch or wahr wahr
falsch or falsch falsch
not wahr falsch
not falsch wahr

Tabelle 3.3 Einsatz von logischen Operatoren

42
Verzweigungen I 3·3

Ein Beispiel:
x
y
z
12
15
20
I
print( "x:", x)
print( "y:", y)
print("z:", z)

IrBed i ngung
if x<y and x<z:
print("x ist die kleinste Zahl ")

IrBed i ngung 2
if y>x or y>z:
print("y ist nicht die kleinste Zahl")

IrBed i ngung 3
if not y<x:
print("y ist nicht kleiner als x")

Listing 3.9 Datei [Link]

Die Ausgabe des Programms:


x: 12
y: 15
z: 20
x ist die kleinste Za h 1
y ist nicht die kleinste Zah 1
y ist nicht kleiner als x

Zur Erläuterung:

~ Die Bedingung 1 ergibt wahr, wenn x kleiner als y und kleiner als z and
ist. Dies trifft bei den gegebenen Anfangswerten zu.
~ Die Bedingung 2 ergibt wahr, wenn y größer als x oder y größer als z or
ist. Die erste Bedingung trifft zu, also ist die gesamte Bedingung wahr:
y ist nicht die kleinste der drei Zahlen.

~ Die Bedingung 3 ist wahr, wenn y nicht kleiner als x ist. Dies trifft hier not
zu.
~ Zu allen Verzweigungen kann es natürlich auch noch einen e 1 s e-
Zweig geben.

43
3 I Programmierkurs

Mehrere Übung U0305


Entscheidungen
Das Programm zur Berechnung des monatlich zu zahlenden Steuerbetrags soll
wiederum verändert werden (Datei [Link]). Die Steuertabelle sieht nun wie
folgt aus:

~ l:rmrnl . •
> 4.000 Euro ledig 26%
> 4.000 Euro verheiratet 22%
s 4.000 Euro ledig 22%
s 4.000 Euro verheiratet 18%

Tabelle 3.4 Steuertabelle für Übung U0305

Der Anwender soll neben seinem Gehalt auch seinen Familienstand nennen.
Beispielsweise soll der Familienstand ledig mit 1 und der Familienstand verhei-
ratet mit 2 angegeben werden. Verwenden Sie logische Operatoren.

3.3.6 Mehrere Vergleichsoperatoren


1 < 2< 3 Bedingungen können auch mehrere Vergleichsoperatoren enthalten.
Manche Verzweigungen sind mithilfe von mehreren Vergleichsoperato-
ren an Stelle von mehreren, verknüpften Bedingungen verständlicher. Es
folgt ein Beispiel:
x 12
y 15
z 20

print("x:", x)
print("y:", y)
print("z:", z)

lfBed i ngung
ifx<y<z:
print("y liegt z wischen x und z")

Listing 3.10 Datei [Link]

Die Ausgabe des Programms:


x: 12
y: 15
z: 20
y liegt zwischen x und z

44
Verzweigungen I 3·3

Zur Erläuterung:

~ Die Bedingung x < y < z entspricht dem Ausdruck x


In der Kurzform ist sie allerdings besser lesbar.
<y a nd y < z. Kurzform

I
3.3.7 Spiel, Version mit genauer Bewertung der Eingabe
Nun kann die Eingabe des Benutzers genauer bewertet werden:
~ mithilfe einer mehrfachen Verzweigung
~ anhand logischer Operatoren
~ anhand von Bedingungen mit mehreren Vergleichsoperatoren
Das Programm wird wie folgt verändert:
# Zufallsgenerator
import random
ra ndom. seed ( )

# Werte und Berechnung


a [Link](l,10)
b [Link](l,10)
c a + b

print("Die Aufgabe:", a, "+" b)

Ir Ei ngabe
print("Bitte eine Zahl eingeben:")
z~input()

zahl ~ int(z)

# Mehrfache Verzweigung, logische Operatoren


# Bedingungen mit mehreren Vergleichsoperatoren
if zahl c:
~~

print(zahl, "ist richtig")


el if zahl < 0 or zahl> 100:
print(zahl, "ist ganz falsch")
e 1 if c - 1 <~ z a h1 <~ c+ 1 :
print(zahl, "ist ganz nahe dran")
else:
print(zahl. "ist falsch")

Ir Ende
print("Ergebnis:" c)
Listing 3.11 Datei [Link]

45
3 I Programmierkurs

Eine mögliche Ausgabe des Programms wäre:


Die Aufgabe: 2 + 1
Bitte eine Zahl eingeben:
4
4 ist ganz nahe dran
Ergebnis: 3

Zur Erläuterung:

~ Insgesamt werden jetzt über i f, zweimal e 1 i fund e 1se vier Möglich-


keiten geboten.
or ~ Ist die Eingabe kleiner als 0 oder größer als 100, so ist sie ganz falsch.
Dies wird mithilfe des logischen Operators 0 r gelöst.
Mehrere ~ Unterscheidet sich die zahl vom richtigen Ergebnis nur um den Wert
Vergleichs- 1, so ist sie ganz nahe dran. Dies wird mit einer Bedingung gelöst, die
operatoren
mehrere Vergleichsoperatoren beinhaltet.

3.3.8 Rangfolge der Operatoren


In vielen Ausdrücken treten mehrere Operatoren auf. Bisher sind dies
Rechenoperatoren, Vergleichsoperatoren und logische Operatoren. Damit
Python weiß, in welcher Reihenfolge die einzelnen Teilschritte bearbeitet
werden sollen, gilt eine feste Rangfolge der Operatoren. Die Teilschritte, bei
denen höherrangige Operatoren beteiligt sind, werden zuerst ausgeführt.

Höchster Tabelle 3.5 gibt die Rangfolge der bisher verwendeten Operatoren in
Rang oben Python an, beginnend mit den Operatoren, die den höchsten Rang
haben. Gleichrangige Operatoren stehen jeweils in einer Zeile. Teil-
schritte, in denen mehrere Operatoren gleichen Ranges stehen, werden
von links nach rechts ausgeführt.

operator Bedeutung
+ positives Vorzeichen einer Zahl, negatives Vorzeichen einer
Zahl
* / % // Multiplikation, Division, Modulo, Ganzzahldivision
+ Addition, Subtraktion
< <~ > >~ ~~ !~ kleiner, kleiner oder gleich, größer, größer oder gleich,
gleich, ungleich
not logische Verneinung
a nd logisches Und
o r l o g i s c h e s Oder

Tabelle 3.5 Rangfolge der bisher genutzten Operatoren


Schleifen I 3·4

3.4 Schleifen
Neben der Verzweigung gibt es noch eine weitere wichtige Struktur zur
Steuerung von Programmen: die Schleife. Mithilfe einer Schleife kann
I
man die wiederholte Ausführung eines Programmschritts ermöglichen.
Es muss zwischen zwei Typen von Schleifen unterschieden werden, der Wiederholung
fo r-Schleife und der whi 1 e-Schleife. Der jeweilige Anwendungsbereich
der beiden Typen wird durch folgende Merkmale definiert:

~ Eine f 0 r-Schleife wird verwendet, wenn ein Programmschritt für eine for
regelmäßige, zum Zeitpunkt der Anwendung bekannte Folge von
Werten wiederholt ausgeführt werden soll.
~ Eine whi 1 e-Schleife wird verwendet, wenn sich erst durch Eingaben while
des Anwenders ergibt, ob ein Programmschritt ausgeführt werden
soll und wie oft er wiederholt wird.
Eine fo r-Schleife wird auch als Zählschleife bezeichnet, eine wh i 1 e-
Schleife als bedingungsgesteuerte Schleife.

3.4.1 for-Schleife
Die Anwendung der f 0 r-Schleife verdeutlicht das folgende Beispiel:
for i in 2, 7.5, -22:
print("Zahl:", i, " Quadrat:", i*i)
Listing 3.12 Datei [Link]

Folgende Ausgabe wird erzeugt:


Zahl: 2 , Quadrat: 4
Zahl: 7.5 , Quadrat: 56.25
Zahl: -22 , Quadrat: 484
Zur Erläuterung:
~ Die erste Zeile ist wie folgt zu lesen: Führe die nachfolgenden einge- Abfolge von
rückten Anweisungen für jede Zahl inder Abfolge 2, 7.5 und - 22 aus. Zahlen

Nenne diese Zahl in diesen Anweisungen i.


~ Nach der Zahlenfolge muss, ebenso wie bei if-el se, ein Doppel-
punkt notiert werden.
~ Anstelle von i kann natürlich auch eine andere Variable als Schleifen-
variable genutzt werden.
~ Die Zahlen werden zusammen mit einem kurzen Informationstext
ausgegeben beziehungsweise quadriert und ausgegeben.

47
3 I Programmierkurs

Iterable Hinweis
1. Eine solche Abfolge von Objekten, die zum Beispiel in einer f 0 r-Schleife
durchlaufen werden kann, nennt man auch iterierbares Objekt oder kurz
Iterable. Diese Iterables werden uns in Python noch häufig begegnen.
2. Den Vorgang des Durchlaufens nennt man auch Iterieren.

3.4.2 Schleifenabbruch mit break


break Die Anweisung b rea k bietet eine weitere Möglichkeit zur Steuerung von
Schleifen. Sie führt zu einem unmittelbaren Abbruch einer Schleife. Sie
wird sinnvollerweise mit einer Bedingung verbunden und häufig bei
Sonderfällen eingesetzt. Ein Beispiel:
for i in 12. -4. 20. 7:
if i*i > 200:
break
print("Zahl :". i. Quadrat:". i*i)
print( "Ende")

Listing 3.13 Datei p0313 .py

Es wird die Ausgabe erzeugt:


Zahl: 12 Quadrat: 144
Za h1: - 4 Quadrat: 16
Ende

Zur Erläuterung:

Schleife verlassen ~ Die Schleife wird unmittelbar verlassen, falls das Quadrat der aktuel-
len Zahl größer als 200 ist.
~ Die Ausgabe innerhalb der Schleife erfolgt auch nicht mehr.
~ Das Programm wird nach der Schleife fortgesetzt.

3.4.3 Geschachtelte I<ontrollstru ktu ren


Wie das vorherige Programm verdeutlicht, können Kontrollstrukturen
(also Verzweigungen und Schleifen) auch geschachtelt werden. Dies
bedeutet, dass eine Kontrollstruktur eine weitere Kontrollstruktur bein-
haltet. Diese kann ihrerseits wiederum eine Kontrollstruktur beinhalten
usw. Ein weiteres Beispiel:
for x in -2. -1. O. 1. 2:
ifx>O:
Schleifen I 3·4

print(x. "positiv")
else:
ifx<O:
print(x. "negativ")
else:
print(x. "gleich 0")
I
Listing 3.14 Datei [Link]

Es wird die Ausgabe erzeugt:


-2 negativ
-1 negativ
o gleich 0
positiv
2 positiv

Zur Erläuterung:

~ Die äußerste Kontrollstruktur ist eine f 0 r-Schleife. Alle einfach einge- Äußeres for
rückten Anweisungen werden - gemäß der Schleifensteuerung -
mehrmals ausgeführt.
~ Mit der äußeren i f-Anweisung wird die erste Verzweigung eingelei- Äußeres if
tet. Ist x größer 0, wird die nachfolgende, zweifach eingerückte
Anweisung ausgeführt.
~ Trifft die Bedingung zur äußeren i f-Anweisung nicht zu, so wird die Inneres if
innere i f-Anweisung hinter der äußeren else-Anweisung untersucht.
~ Trifft diese Bedingung zu, so werden die nachfolgenden, dreifach ein-
gerückten Anweisungen ausgeführt.
~ Trifft die innere i f-Anweisung nicht zu, so werden die dreifach ein-
gerückten Anweisungen ausgeführt, die der inneren else-Anweisung
folgen.

Zu beachten sind besonders die mehrfachen Einrückungen, damit die Mehrfach


Tiefe der Kontrollstruktur von Python richtig erkannt werden kann. einrücken

Nach einem Doppelpunkt hinter dem Kopf einer Kontrollstruktur wird in


der Entwicklungsumgebung IDLE automatisch mit einem Tabulatorsprung
eingerückt. Dieser Sprung erzeugt standardmäßig vier Leerzeichen,
dadurch werden die Kontrollstrukturen für den Entwickler klar erkennbar.

Falls Sie mit einem anderen Editor arbeiten, müssen Sie darauf achten, Mindestens ein
dass um mindestens ein Leerzeichen eingerückt wird, damit Python die Leerzeichen

Kontrollstruktur erkennt. Sinnvoller ist eine Einrückung um zwei oder

49
3 I Programmierkurs

mehr Leerzeichen, damit die Struktur auch für den Entwickler gut
erkennbar ist.

3.4.4 Spiel, Version mit for-Schleife und Abbruch


Vier Versuche Die f 0 r-Schleife wird nun dazu genutzt, die Eingabe und die Bewertung
insgesamt viermal zu wiederholen. Der Benutzer hat also vier Versuche,
das richtige Ergebnis zu ermitteln.

Die Anweisung b rea k dient zum Abbruch der Schleife, sobald der Benut-
zer das richtige Ergebnis eingegeben hat.

# Zufallsgenerator
import random
[Link]( )

# Werte und Berechnung


a [Link]([Link])
b [Link]([Link])
c a + b

print("Die Aufgabe:". a. "+" b)

# Schleife mit for


for i in 1. 2. 3. 4:
lf Eingabe
print("Bitte eine Zahl eingeben:")
z~input()

zahl ~ int(z)

lf Verzwei gung
if zahl ~~ c:

print(zahl. "ist richtig")


# Abbruch der Schleife
break
else:
print(zahl. "ist falsch")

lf Ende
print("Ergebnis:" c)

Listing 3.15 Datei [Link]


Schleifen I 3·4

Folgende Ausgabe wird erzeugt:


Die Aufgabe: 7 + 9
Bitte eine Zahl
12
12 ist fal sch
eingeben:
I
Bitte eine Zahl eingeben:
16
16 ist richtig
Ergebnis: 16

Zur Erläuterung:
~ Die Aufgabe wird einmal ermittelt und gestellt.
~ Der Benutzer wird maximal viermal dazu aufgefordert, ein Ergebnis
einzugeben. Jede seiner Eingaben wird bewertet.
~ Wird bereits bei einem der ersten drei Versuche das richtige Ergebnis Vorzeitiger
eingegeben, so wird die Schleife vorzeitig abgebrochen. Abbruch

3.4.5 for-Schleife mit rangeO


Meist werden Schleifen für regelmäßige Abfolgen von Zahlen genutzt. rangeO
Dabei erweist sich der Einsatz der Funktion range() als sehr nützlich.
Ein Beispiel:
for i in range(3,II,2):
print("Zahl:", i, "Quadrat:", i*i)

Listing 3.16 Datei [Link]

Es wird die Ausgabe erzeugt:


Za h 1 : 3 Quadrat: 9
Za h 1 : 5 Quadrat: 25
Za h 1 : 7 Quadrat: 49
Za h 1 : 9 Quadrat: 81

Der englische Begriff range bedeutet »Bereich«. Innerhalb der Klammern


hinter ra nge können bis zu drei ganze Zahlen, durch Kommata getrennt,
eingetragen werden:

~ Die erste ganze Zahl (hier 3) gibt den Beginn des Bereichs an, für den Beginn
die nachfolgenden Anweisungen ausgeführt werden sollen.
~ Die zweite ganze Zahl (hier 11) kennzeichnet das Ende des Bereichs. Ende
Es ist die erste Zahl, für die die Anweisungen nicht mehr ausgeführt
werden.

51
3 I Programmierkurs

Schrittweite ~ Die dritte ganze Zahl (hier 2) gibt die Schrittweite für die Schleife an.
Die Zahlen, für die die Anweisungen ausgeführt werden, stehen
zueinander also jeweils im Abstand von +2.
Der Aufruf der Funktion range() mit den Zahlen 3, 11 und 2 ergibt
somit die Abfolge: 3,5,7,9.

Schrittweite 1 Wird die Funktion range ( ) nur mit zwei Zahlen aufgerufen, so wird eine
Schrittweite von 1 angenommen. Ein Beispiel:
for i in range(5,9):
print("Zahl :", i)

Listing 3.17 Datei [Link]

Es wird folgende Ausgabe erzeugt:


Za h1: 5
Za h 1: 6
Za h 1: 7
Za h1: 8

Beginn bei 0 Wird die Funktion range ( ) sogar nur mit einer zahl aufgerufen, so wird
diese zahl einfach als die obere Grenze angesehen. Als untere Grenze
wird 0 gesetzt. Außerdem wird wiederum eine Schrittweite von 1 ange-
nommen. Ein Beispiel:
for i in range(3):
print("Zahl :", i)

Listing 3.18 Datei [Link]

Die Ausgabe:
Za h 1: 0
Za h1 :
Za h1: 2

Nicht sinnvoll Hinweise


1. Bei der Funktion range() können eine oder mehrere der drei Zahlen auch
negativ sein. Achten Sie aber auf die Eingabe sinnvoller Zahlenkombinatio-
nen.
2. Die Angabe range (3, -11 ,2) ist nicht sinnvoll, da man von der Zahl +3 in
Schritten von +2 nicht zur Zahl -11 gelangt. Python fängt solche Schleifen
ab und lässt sie nicht ausführen. Dasselbe gilt für die Zahlenkombination
range(3, 11, -2).

52
Schleifen I 3·4

Soll ein regelmäßiger Ablauf von Zahlen mit NachkommastelIen erzeugt Keine ganze Zahl

I
werden, so muss die Schleifenvariable entsprechend umgerechnet wer-
den. Ein Beispiel:
i! 1. Version
for x in range(18.22):
print(x/lO)
pr i nt ( )

i! 2. Version
x ~ 1.8
for i in range(4):
print(x)
x~x+0.1

Listing 3.19 Datei [Link]

Die Ausgabe lautet:


1.8
1.9
2.0
2.1

1.8
1.9
2.0
2.1

Zur Erläuterung:
~ Es sollen jeweils die zahlen von 1,8 bis 2,1 in Schritten von 0,1
erzeugt werden.
~ In der ersten Version werden dazu die ganzen Zahlen von 18 bis 21 Version 1
erzeugt und durch 10 geteilt.
~ In der zweiten Version wird mit dem ersten Wert begonnen und Version 2
innerhalb der Schleife jeweils um 0,1 erhöht. Vorher ist zu errechnen,
wie häufig die Schleife durchlaufen werden muss.
~ Beide Versionen haben Vor- und Nachteile für den Entwickler. In der
ersten Version kann man Anfang und Ende der Schleife gut erkennen,
nicht aber die Schrittweite. In der zweiten Version ist es umgekehrt.

53
3 I Programmierkurs

Schleife erkennen Übung U0306


Ermitteln Sie durch Überlegen (nicht durch einen einfachen Aufruf) die Aus-
gabe des folgenden Programms (Datei [Link]).
print("Schleife 1")
for i in 2. 3. 6.5. -7:
p ri nt ( i )

print("Schleife 2")
for i in range(3.11.3):
p ri nt ( i )

print("Schleife 3")
for i in range(-3.14.4):
p ri nt ( i )

print("Schleife 4")
for i in range(3.-11.-3):
p ri nt ( i )
Datei u0306. py

Übung U0307
Schreiben Sie ein Programm, das die folgende Ausgabe erzeugt (Datei
[Link]). Beachten Sie, dass für dieses Programm keine Eingabe durch den
Anwender notwendig ist. Es handelt sich um eine regelmäßige Liste von Inch-
Werten, für die der jeweilige Zentimeter-Wert durch Umrechnung mit dem
Faktor 2,54 ermittelt werden soll.
15 inch 38.1 cm
20 inch 50.8 cm
25 inch 63.5 cm
30 inch 76.2 cm
35 inch 88.9 cm
40 inch 101. 6 cm

3.4.6 Spiel, Version mit rangeO


Mit Zähler Die Schleife zur Wiederholung der Eingabe wird nun mithilfe von
range () gebildet. Gleichzeitig hat man damit einen Zähler, der die lau-
fende Nummer des Versuchs beinhaltet. Diesen Zähler kann man ver-
wenden, um dem Benutzer am Ende mitzuteilen, wie viele Versuche er
benötigt hat.
# Zufallsgenerator
import random
[Link]( )

54
Schleifen I 3·4

# Werte und Berechnung

I
a [Link](I,10)
b [Link](I,10)
c a + b

print("Die Aufgabe:", a, "+" b)

# Schleife mit range


for versuch in range(I,10):
Ir Ei ng abe
print("Bitte eine Zahl eingeben:")
z~input()

zahl ~ int(z)

Ir Verzwei gung
if zahl ~~ c:
print(zahl. "ist richtig")
# Abbruch der Schleife
break
else:
print(zahl, "ist falsch")

IrAnzahl ausgeben
print("Ergebnis: ", c)
print( "Anzahl Versuche:", versuch)

Listing 3.20 Datei [Link]

Die Ausgabe lautet:


Die Aufgabe: 10 + 5
Bitte eine Zahl eingeben:
13
13 ist falsch
Bitte eine Zahl eingeben:
15
15 ist richtig
Ergebnis: 15
Anzahl Versuche: 2

Zur Erläuterung:
~ Der Benutzer hat maximal neun Versuche: ranger 1,10).
~ Die Variable versuch dient als Zähler für die Versuche. Zähler

~ Nach Eingabe der richtigen Lösung (oder nach vollständigem Durchlauf


der Schleife) wird dem Benutzer die Anzahl der Versuche mitgeteilt.

55
3 I Programmierkurs

3.4.7 while-Schleife
Bedingte Schleife Die whi 1 e-Schleife dient zur bedingungsgesteuerten Wiederholung einer
Schleife. Mithilfe des folgenden Programms sollen zufällige Zahlen
addiert und ausgegeben werden. Solange die Summe der Zahlen kleiner
als 30 ist, wird der Vorgang wiederholt. Ist die Summe gleich oder grö-
ßer 30, wird das Programm beendet.

# Zufallsgenerator
import random
[Link]( )

lf Initialisierung
summe ~ 0

# while Schleife
while summe< 30:
zzahl ~ [Link](1,8)
summe ~ summe + zzahl
print("Zahl:", zzahl. "Zwischensumme:", summe)

print( "Ende")

Listing 3.21 Datei [Link]

Eine mögliche Ausgabe des Programms sähe wie folgt aus:

Za h1 : 3 Zwischensumme: 3
Za h1 : 8 Zwischensumme: 11
Za h1 : 5 Zwischensumme: 16
Za h1 : 6 Zwischensumme: 22
Za h1 : 7 Zwischensumme: 29
Za h1 : 4 Zwischensumme: 33
Ende

Zur Erläuterung:

~ Zunächst wird die Variable für die Summe der Zahlen auf °gesetzt.
Einrücken ~ Die wh i 1 e-Anweisung leitet die Schleife ein. Die wörtliche überset-
zung der Zeile lautet: solange die Summe kleiner als 30 ist. Dies bezieht
sich auf die folgenden, eingerückten Anweisungen.
Doppelpunkt ~ Hinter dem Wort wh i 1 e steht (wie bei einer if-Anweisung) eine
Bedingung, die mithilfe von Vergleichsoperatoren erstellt wird. Auch
hier darf der: (Doppelpunkt) am Ende der Zeile (wie bei i f - e 1 se und
fo r) nicht vergessen werden.
Schleifen I 3·4

~ Es wird eine zufällige zahl ermittelt und zur bisherigen Summe hin-

I
zuaddiert. Die neue Summe errechnet sich also aus der alten Summe
plus der eingegebenen zahl. Die neue Summe wird ausgegeben.
~ Die Anweisung zur Ausgabe des Texts »Ende« wird erst erreicht, Ende der Schleife
wenn die Summe den Wert 30 erreicht oder überschritten hat.

3.4.8 Spiel, Version mit while-Schleife und Zähler


Die wh i 1 e-Schleife wird nun zur Wiederholung der Eingabe genutzt. Der Solange Eingabe
Benutzer hat unendlich viele Versuche, die Aufgabe zu lösen. Die Vari- falsch

able versuch als Zähler für die Versuche muss separat gesteuert werden.
Sie ergibt sich nicht mehr automatisch als Schleifenvariable.

# Zufallsgenerator
import random
ra ndom. seed ( )

# Werte und Berechnung


a [Link](l,lO)
b [Link](l,lO)
c a + b

print("Die Aufgabe:", a, "+", b)

# Schleife initialisieren
zahl ~ c +

lf Anzahl initialisieren
versuch ~ 0

# Schleife mit while


while zahl !~ c:
lf Anzahl Versuche
versuch ~ versuch + 1

# Eingabe mit Umwandlung


print("Bitte eine Zahl eingeben:")
z~input()

zahl ~ int(z)

# Verzweigung
if zahl ~~ c:

print(zahl. "ist richtig")


else:
print(zahl, "ist falsch")

57
3 I Programmierkurs

Ir Anzahl ausgeben
print("Ergebnis: ", c)
print( "Anzahl Versuche:", versuch)
Listing 3.22 Datei p0322 .py

Die Ausgabe hat sich nicht geändert.

Zur Erläuterung:
~ Der Benutzer hat unendlich viele Versuche. Die whi 1e-Schleife läuft,
solange die richtige Lösung nicht ermittelt wurde.
Schleife starten ~ Die Variable za h1 wird mit einem Wert vorbesetzt, der dafür sorgt,
dass die wh i 1 e-Schleife mindestens einmal läuft.
~ Die Variable ve rs uch wird mit 0 vorbesetzt und dient als laufende
Nummer.
Anzahl Versuche ~ Nach Eingabe der richtigen Lösung wird dem Benutzer die Anzahl der
Versuche mitgeteilt.

Ende mit 0 Übung U0308


Schreiben Sie ein Programm (Datei [Link]) , das den Anwender wiederholt
dazu auffordert, einen Wert in Inch einzugeben. Der eingegebene Wert soll
anschließend in Zentimeter umgerechnet und ausgegeben werden. Das Pro-
gramm soll beendet werden, falls der Anwender den Wert 0 eingibt.
Hinweis: Bei einer whi 1e-Schleife wird immer angegeben, unter welcher Be-
dingung wiederholt werden soll, und nicht, unter welcher Bedingung beendet
werden soll. Daher ist für dieses Programm die umgekehrte Bedingung zu for-
mulieren: solange die Eingabe ungleich 0 ist.

3.5 Fehler und Ausnahmen

Fehler Macht der Anwender nach einer Eingabeaufforderung eine falsche Ein-
gabe (zum Beispiel keine Zahl, sondern einen Text), so wird das Pro-
gramm mit einer Fehlermeldung beendet. Bisher wurde vereinfacht
davon ausgegangen, dass der Anwender korrekte Eingaben vornimmt. In
diesem Abschnitt wird beschrieben, wie Fehler vermieden beziehungs-
weise abgefangen werden können.

3.5.1 Basisprogramm
Abbruch möglich Durch das Abfangen von falschen Eingaben wird die Benutzung eines
Programms für den Anwender deutlich komfortabler. Im folgenden Pro-
Fehler und Ausnahmen I 3.5

gramm soll eine Zahl eingegeben werden. Da der Benutzer dieses Pro-

I
gramm durch die Eingabe von Text oder Sonderzeichen zum Abbruch
bringen kann, wird es im weiteren verlauf des Abschnitts verbessert.
lf Ei ngabe
print("Bitte geben Sie eine Zahl ein")
z~input()

lf Umwandl ung
zahl ~ int(z)

lf Ausgabe
print("Sie haben die Zahl", zahl. "richtig eingegeben")
print("Ende des Programms")

Listing 3.23 Datei p0323 .py

Gibt der Anwender eine zahl (zum Beispiel 12) ein, so läuft das Pro- Richtige Eingabe
gramm fehlerfrei bis zum Ende und erzeugt die folgende Ausgabe:
Bitte geben Sie eine Zahl ein
12
Sie haben die Zahl 12 richtig eingegeben
Ende des Programms

Macht der Anwender jedoch eine falsche Eingabe (zum Beispiel da«), so Falsche Eingabe
bricht das Programm vorzeitig ab und erzeugt die folgende Ausgabe:
Bitte geben Sie eine Zahl ein
3a
Traceback (most recent call last):
File "C:\Python30\Kap03\[Link]", line 6, in <module>
zahl ~ int(z)
ValueError: invalid literal for int() with base 10: '3a'

Diese Informationen weisen auf die Stelle im Programm hin, an der der FehlersteIle
Fehler bemerkt wurde (Datei [Link], Zeile 6). Außerdem wird die Art
des Fehlers mitgeteilt (Va 1 ueE r ro r).

3·5·2 Programmabbruch vermeiden


Der Fehler soll zunächst abgefangen werden, um einen Abbruch des Pro- Verbessern
gramms zu vermeiden. Zu diesem Zweck müssen Sie die Stelle herausfin-
den, an welcher der Fehler auftrat. An dieser Stelle muss das Programm
verbessert werden.

59
3 I Programmierkurs

Fehler abfangen Das Programm soll zukünftig an dieser Stelle alle Arten von Fehlern
abfangen, die Python automatisch erkennen kann. Dies erreichen Sie in
einem ersten Schritt durch die folgende Änderung:
lf Ei ngabe
print("Bitte geben Sie eine Zahl ein")
z~input()

# Versuch der Umwandlung


try:
zahl ~ int(z)
print( "Sie haben die Zahl". zahl.
"richtig eingegeben")
lf Fehl er bei Umwandl ung
except:
print("Sie haben die Zahl nicht"
" richtig eingegeben")

print("Ende des Programms")


Listing 3.24 Datei [Link]

Kein Abbruch Wenn der Anwender eine richtige Zahl eingibt, läuft das Programm wie
mehr bisher. Bei einer falschen Eingabe erscheint nun eine entsprechende
Meldung. Das Programm bricht jedoch nicht ab, sondern läuft bis zum
Ende.
Bitte geben Sie eine Zahl ein
3a
Sie haben die Zahl nicht richtig eingegeben
Ende des Programms

Zur Erläuterung:

try ~ Die Anweisung t r y leitet eine Ausnahmebehandlung ein. Ähnlich wie


bei der i f-Anweisung gibt es verschiedene Zweige, die das Programm
durchlaufen kann. Das Programm versucht (englisch: try), die Anwei-
sungen durchzuführen, die eingerückt hinter t r y stehen.
~ Falls die Eingabe erfolgreich ist, wird der except-Zweig nicht ausge-
führt, ähnlich wie beim e 1se-Zweig der i f-Anweisung.
except ~ Ist die Eingabe dagegen nicht erfolgreich und handelt es sich um
einen Fehler, so wird der Fehler oder die Ausnahme (englisch: excep-
tion) mit der Anweisung except abgefangen. Es werden dann alle ein-
gerückten Anweisungen in diesem Zweig durchgeführt.

60
Fehler und Ausnahmen I 3.5

~ Anschließend läuft das Programm ohne Abbruch zu Ende, da der Feh-

I
ler zwar auftrat, aber abgefangen wurde.
~ Nach t ry und except muss jeweils ein Doppelpunkt gesetzt werden,
wie bei if-else, for oderwhile.

Hinweise

1. Nur die kritische Zeile wurde in die Ausnahmebehandlung eingebettet. Der Kritische Stelle
Programmierer muss sich also Gedanken darüber machen, welche Stellen
sei nes Programms feh lerträchtig si nd.
2. Eine Eingabeaufforderung ist solch eine kritische Stelle. Andere Fehlermög- Fehlermöglich-
lichkeiten sind zum Beispiel die Bearbeitung einer Datei (die möglicher- keiten
weise nicht existiert) oder die Ausgabe auf einen Drucker (der vielleicht
nicht eingeschaltet ist).

3.5.3 Fehler abfangen


In einem zweiten Schritt soll dafür gesorgt werden, dass der Anwender Erneute Eingabe
nach einer falschen Eingabe eine neue Eingabe machen kann. Der
gesamte Eingabevorgang einschließlich der Ausnahmebehandlung wird
so lange wiederholt, bis er erfolgreich war. Betrachten Sie dazu das fol-
gende Programm:
# Initialisierung der while-Schleife
fehler ~ 1

# Schleife bei falscher Eingabe


while fehler ~~ 1:
Ir Eingabe
print("Bitte geben Sie eine Zahl ein")
z~input()

# Versuch der Um wandlung


try:
zahl ~ int(z)
print( "Sie haben die Zahl". zahl.
"richtig eingegeben")
fehler ~ 0
# Fehler bei Umwandlung
except:
print("Sie haben die Zahl nicht"
" richtig eingegeben")

print("Ende des Programms")


Listing 3.25 Datei [Link]

61
3 I Programmierkurs

Test Nachfolgend wird eine mögliche Eingabe gezeigt - zunächst mit einem
Fehler, anschließend fehlerfrei:
Bitte geben Sie eine Zahl ein
3a
Sie haben die Zahl nicht richtig eingegeben
Bitte geben Sie eine Zahl ein
12
Sie haben die Zahl 12 richtig eingegeben
Ende des Programms

Zur Erläuterung:
~ Die Variable feh 1 er wird zunächst auf den Wert 1 gesetzt. Diese Vari-
able ist notwendig, um die Eingabe gegebenenfalls wiederholen zu
können.
Eingabewieder- ~ Mit der wh i 1e-Anweisung wird eine Schleife formuliert, in welcher
holung der Eingabevorgang einschließlich der Ausnahmebehandlung einge-
bettet ist. Die Schleife wird wiederholt, solange die Variable fehl er
den Wert 1 hat.
Richtige Eingabe ~ Ist die Eingabe erfolgreich, so wird die Variable fehl er auf 0 gesetzt.
Dies führt dazu, dass die Schleife beendet wird und das Programm
regulär fortfahren kann.
Falsche Eingabe ~ Ist die Eingabe nicht erfolgreich, so hat feh 1 er nach wie vor den Wert
1. Dies führt dazu, dass der Eingabevorgang wiederholt wird.

Hinweis
Beachten Sie die doppelte Einrückung: einmal nach whi 1 e und noch einmal
nach try / except.

Übung U0309
Verbessern Sie das Programm zur Eingabe und Umrechnung eines beliebigen
Inch-Wertes in Zentimeter. Eingabefehler des Anwenders sollen abgefangen
werden. Das Programm soll den Anwender so lange zur Eingabe auffordern, bis
sie erfolgreich war (Datei [Link]).

3.5.4 Exkurs: Schleifenfortsetzung mit continue


break An dieser Stelle möchte ich auf ein Thema zurückkommen, das bereits in
Abschnitt 3.4, »Schleifen«, behandelt wurde. Sie kennen aus diesem
Abschnitt die Anweisung b rea k, die zum unmittelbaren Abbruch einer
Schleife führt.

62
Fehler und Ausnahmen I 3.5

Die Anweisung co nt i nue dient zum unmittelbaren Abbruch des aktuel- continue

I
len Durchlaufs einer Schleife. Die Schleife wird anschließend mit dem
nächsten Durchlauf fortgesetzt. Betrachten Sie hierzu das folgende Pro-
gramm:
for i in range (1,7):
print("Zahl :", i)
if 3 <~ i <~ 5:
continue
print("Quadrat:", i*i)
Listing 3.26 Datei [Link]

Die Ausgabe dieses Programms wäre:


Za h1 : 1
Quadrat:
Za h1 : 2
Quadrat: 4
Za h1 : 3
Za h1 : 4
Za h1 : 5
Za h1 : 6
Quadrat: 36

Zur Erläuterung:
~ Die Schleife durchläuft alle Zahlen von 1 bis 6. Die Zahlen werden
auch alle ausgegeben.
~ Liegt die al<tuelle Zahl zwischen 3 und 5, so wird der Rest der Schleife Rest übergehen
übergangen und unmittelbar der nächste Schleifendurchlauf begon-
nen. Anderenfalls wird das Quadrat der Zahl ausgegeben.

3.5.5 Spiel, Version mit Ausnahmebehandlung


Die Ausnahmebehandlung und die Anweisung cont i nue werden im fol- Fehler abfangen
genden Programm dazu eingesetzt, einen Eingabefehler abzufangen und
das Programm regulär fortzusetzen.
# Zufallsgenerator
import random
ra ndom. seed ( )

# Werte und Berechnung


a ~ [Link](I,10)
3 I Programmierkurs

b [Link](l,10)
c a + b

print("Die Aufgabe:", a, "+", b)

lf Schleife und Anzahl initialisieren


zahl ~ c +
versuch ~ 0

# Schleife mit while


while zahl !~ c:
lf Anzahl Versuche
versuch ~ versuch + 1

lf Eingabe
print("Bitte eine Zahl eingeben:")
z~input()

# Versuch einer Umwandlung


try:
zahl ~ int(z)
except:
# Falls Umwandlung nicht erfolgreich
print("Sie haben keine Zahl eingegeben")
# Schleife unmittelbar fortsetzen
continue

lf Verzwei gung
if zahl ~~ c:
print(zahl, "ist richtig")
else:
print(zahl, "ist falsch")

lf Anzahl Versuche
print("Ergebnis: ", c)
print( "Anzahl Versuche:", versuch)

Listing 3.27 Datei [Link]

Es wird folgende Ausgabe erzeugt:


Die Aufgabe: 8 + 3
Bitte eine Zahl eingeben:
12
12 ist falsch
Funktionen und Module I 3.6

Bitte eine Zahl eingeben:

I
11a
Sie haben keine Zahl eingegeben
Bitte eine Zahl eingeben:
11
11 ist richtig
Ergebnis: 11
Anzahl Versuche: 3
Zur Erläuterung:

~ Die Umwandlung der Eingabe steht in einem t ry except-Block.


~ Falls die Umwandlung aufgrund einer falschen Eingabe nicht gelingt, Falsche Eingabe
erscheint eine entsprechende Meldung.
~ Der Rest der Schleife wird übergangen, und die nächste Eingabe wird
unmittelbar angefordert.

3.6 Funktionen und Module

Die Modularisierung, also die Zerlegung eines Programms in selbst Modularisierung


geschriebene Funktionen, bietet besonders bei größeren Programmen
unübersehbare Vorteile:

~ Programmteile, die mehrmals benötigt werden, müssen nur einmal Mehrfach


definiert werden. verwenden

~ Nützliche Programmteile können in mehreren Programmen verwen-


det werden.
~ Umfangreiche Programme können in übersichtliche Teile zerlegt wer- Übersichtlicher
den.
~ Pflege und Wartung von Programmen wird erleichtert.
~ Der Programmcode ist für den Programmierer selbst (zu einem späte- Verständlicher
ren Zeitpunkt) und für andere Programmierer leichter zu verstehen.
Neben den selbst geschriebenen Funktionen gibt es in Python, wie bei Vordefinierte
jeder anderen Programmiersprache auch, zahlreiche vordefinierte Funk- Funktionen

tionen, die dem Entwickler viel Arbeit abnehmen können. Diese Funkti-
onen sind entweder fest eingebaut oder über die Einbindung spezieller
Module verfügbar.

Als Beispiel für eine fest eingebaute Funktion wurde bereits input ( ) ein- Aufgabe einer
gesetzt. Jede Funktion hat eine spezielle Aufgabe. So hält beispielsweise die Funktion

Funktion input ( ) das Programm an und nimmt eine Eingabe entgegen.


3 I Programmierkurs

Rückgabewert Wie viele (aber nicht alle) Funktionen hat input () einen sogenannten
Rückgabewert, liefert also ein Ergebnis an die Stelle des Programms
zurück, von der sie aufgerufen wurde: die eingegebene Zeichenkette.

Die Entwicklung selbst geschriebener Funktionen erläutert der folgende


Abschnitt.

3·6.1 Einfache Funktionen


Immer gleich Einfache Funktionen führen bei Aufruf stets dieselbe Aktion aus. Im fol-
genden Beispiel führt jeder Aufruf der Funktion s t ern ( ) dazu, dass eine
optische Trennung auf dem Bildschirm ausgegeben wird:
# Definition der Funktion
def stern():
pr i nt ( "- - - - - - - - - - - - - - - - -" )
print("*** Trennung ****")
pr i nt ( "- - - - - - - - - - - - - - - - -" )

lf Haupt- Programm
x ~ 12
Y ~ 5
stern() lf 1. Aufruf
print( "x x, y y)
stern() lf 2. Aufruf
print( "x + y x + y)
stern() lf 3. Aufruf
print( "x y x y)
stern() lf 4. Aufruf
Listing 3.28 Datei [Link]

Folgende Ausgabe wird erzeugt:

*** Trennung ****

x ~
12 Y ~
5

*** Trennung ****

x + y ~
17

*** Trennung ****

66
Funktionen und Module I 3.6

x y ~ 7

*** Trennung

Zur Erläuterung:
****

Definition
I
Im oberen Teil des Programms wird die Funktion stern() definiert:

~ Nach der Anweisung def folgt der Name der Funktion (hier stern), def
anschließend runde Klammern und der bereits bekannte Doppel-
punkt. Innerhalb der Klammern könnten Werte an die Funktion über-
geben werden. Hierzu erfahren Sie mehr in den folgenden Abschnit-
ten 3.6.2, »Funktionen mit einem Parameter«, und 3.6.3, »Funktionen
mit mehreren Parametern«.
~ Die nachfolgenden, eingerückten Anweisungen werden jedes Mal
durchgeführt, wenn die Funktion aufgerufen wird.
~ Die eingebaute Funktion pr i nt ( ) zur Erzeugung einer optischen Tren-
nung wird dreimal aufgerufen.
Eine Funktion wird zunächst nur definiert und nicht durchgeführt. Sie Bereitstellung
steht sozusagen zum späteren Gebrauch bereit. Im unteren Teil beginnt
das eigentliche Programm:
~ Es werden verschiedene Rechenoperationen mit zwei Variablen
durchgeführt.
~ Die Ausgabezeilen werden mithilfe der Funktion s te rn () optisch
voneinander getrennt.
~ Die Funktion ste rn ( ) wird insgesamt viermal aufgerufen. Aufruf

~ Nach Bearbeitung der Funktion stern() fährt das Programm jedes Nach Funktion
Mal mit der Anweisung fort, die dem Aufruf der Funktion folgt. weiter

Eine Funktion wird aufgerufen, indem ihr Name, gefolgt von den runden Klammern
Klammern, notiert wird. Sollen Informationen an die Funktion geliefert
werden, so werden diese innerhalb der runden Klammern angegeben
(dazu später mehr).
Der Name einer Funktion kann weitgehend frei gewählt werden - es gel- Name
ten die gleichen Regeln wie bei den Namen von Variablen:
~ Der Name kann aus den Buchstaben abis z, Abis Z, aus Ziffern und
dem Zeichen _ (= Unterstrich) bestehen.
3 I Programmierkurs

~ Der Name darf nicht mit einer Ziffer beginnen.


~ Er darf keinem reservierten Wort der Programmiersprache Python
entsprechen.

3.6.2 Funktionen mit einem Parameter


Parameter Bei einem Aufruf können auch Informationen an Funktionen übermittelt
werden, sogenannte Parameter. Dies führt dazu, dass diese Informatio-
nen innerhalb der Funktion ausgewertet werden können und bei jedem
Aufruf zu unterschiedlichen Ergebnissen führen. Ein Beispiel:
# Definition der Funktion
def quadrat(x):
q ~ x*x
print("Zahl:", x, "Quadrat:", q)

lf Hauptprogramm
quadrat(4.5)
a ~ 3
quadrat(a)
quadrat(2*a)

Listing 3.29 Datei [Link]

Die Ausgabe lautet:


Zahl: 4.5 Quadrat: 20.25
Zahl: 3 Quadrat: 9
Zahl: 6 Quadrat: 36

Zur Erläuterung:
Wertübermittlung Die Definition der Funktion qua d ra t ( ) beinhaltet in den Klammern eine
Variable. Dies bedeutet, dass beim Aufruf der Funktion ein Wert über-
mittelt und dieser Variablen zugewiesen wird. Im vorliegenden Pro-
gramm werden der Funktion die folgenden Werte geliefert:
1. Die Zahl 4.5 - die Variable x erhält in der Funktion den Wert 4.5.
2. Die Variable a - die Variable x erhält in der Funktion den aktuellen
Wert von a, nämlich 3.
3. Das Ergebnis einer Berechnung - die Variable x erhält in der Funktion
den aktuellen Wert von 2 mal a, also 6.

68
Funktionen und Module I 3.6

Hinweis Anzahl Werte

I
Die Funktion erwartet genau einen Wert. Sie darf also nicht ohne einen Wert
oder mit mehr als einem Wert aufgerufen werden. Falls dies dennoch getan
wird, bricht das Programm mit einer Fehlermeldung ab.

Übung U0310
Es soll für verschiedene Bruttogehälter der Steuerbetrag berechnet werden
(Datei u0310py). Liegt das Gehalt über 2.500 Euro, so sind 22% Steuer zu
zahlen, ansonsten 18%. Die Berechnung und die Ausgabe des Steuerbetrags
sollen innerhalb einer Funktion mit dem Namen steuer() stattfinden. Die
Funktion soll für die folgenden Gehälter aufgerufen werden: 1.800 Euro, 2.200
Euro, 2.500 Euro, 2.900 Euro.

3.6.3 Funktionen mit mehreren Parametern


Eine Funktion kann noch vielseitiger werden, falls man ihr mehrere Para- Anzahl,
meter übermittelt. Dabei ist auf die übereinstimmende Anzahl und die Reihenfolge

richtige Reihenfolge der Parameter zu achten. Ein Beispiel:


# Definition der Funktion
def berechnung(x,y,z):
ergebnis ~ (x+y) * Z
print("Ergebnis:", ergebnis)

Ir Hauptprogramm
berechnung(2,3,5)
berechnung(5,2,3)

Listing 3.30 Datei [Link]

Die Ausgabe lautet:


Ergebni s: 25
Ergebnis: 21
Zur Erläuterung:
Es werden genau drei Parameter erwartet, bei beiden Aufrufen werden Reihenfolge
auch drei Werte übermittelt. Wie Sie am Ergebnis erkennenkännen, ist
die Reihenfolge der Parameter wichtig.
~ Beim ersten Aufruf erhält x den Wert 2, y den Wert 3 und Z den Wert
5. Dies ergibt die Rechnung: (2 + 3) x 5 = 25.
~ Beim zweiten Aufruf werden zwar die gleichen Zahlen übergeben,
aber in anderer Reihenfolge. Es ergibt sich die Rechnung:
(5 + 2) x 3 = 21

69
3 I Programmierkurs

3.6.4 Funktionen mit Rückgabewert


Ergebnis Funktionen werden häufig zur Berechnung von Ergebnissen eingesetzt.
Zu diesem Zweck können Funktionen ihre Ergebnisse als sogenannte
Rückgabewerte zurückliefern.
Rückgabewert Im Unterschied zu vielen anderen Programmiersprachen können Funkti-
onen in Python mehr als einen Rückgabewert liefern. In diesem
Abschnitt sollen allerdings zunächst nur Funktionen betrachtet werden,
die genau einen Rückgabewert zur Verfügung stellen.
Im folgenden Beispiel wird eine Funktion, die einen Rückgabewert lie-
fert, auf zwei verschiedene Arten im Hauptprogramm eingesetzt und auf-
gerufen.
# Definition der Funktion
def mittelwert(x,y):
ergebnis ~ (x+y) / 2
return ergebnis

lf Hauptprogramm
c ~ mittelwert(3, 9)
print("Mittelwert:", c)

x ~ 5
print("Mittelwert:", mittelwert(x,4))
Listing 3.31 Datei [Link]

Es wird die Ausgabe erzeugt:


Mittelwert: 6.0
Mittelwert: 4.5

Zur Erläuterung:

return ~ Innerhalb der Funktion wird das Ergebnis zunächst berechnet.


Anschließend wird es mithilfe der Anweisung retu rn an die aufru-
fende Stelle zurückgeliefert. Die Anweisung return beendet außer-
dem unmittelbar den Ablauf der Funktion.
Rückgabe ~ Beim ersten Aufruf wird der Rückgabewert in der Variablen c zwi-
speichern schengespeichert. Er kann im weiteren verlauf des Programms an
beliebiger Stelle verwendet werden.
Rückgabe ~ Beim zweiten Aufruf geschehen zwei Dinge gleichzeitig: Die Funktion
ausgeben mi t te 1we rt ( ) wird aufgerufen und liefert ein Ergebnis. Dieses Ergeb-
nis wird unmittelbar ausgegeben.

70
Funktionen und Module I 3.6

3.6.5 Spiel, Version mit Funktionen


Das Programm beinhaltet nun zwei Funktionen: Die erste Funktion dient
zur Ermittlung der Aufgabe, die zweite zur Bewertung der Eingabe:
lf Aufgabe
Mit Funktionen

I
def aufgabe():
a ~ [Link](l,lO)
b ~ [Link](l,lO)
erg ~ a + b
print("Die Aufgabe:", a, "+" b)
return erg

lf Komment ar
def kommentar(eingabezahl, ergebnis):
if eingabezahl ~~ ergebnis:
print(eingabezahl, "ist richtig")
else:
print(eingabezahl. "ist falsch")

# Zufallsgenerator
import random
[Link]()

lf Aufgabe
c ~ aufgabe()

# Schleife und Anzahl initialisieren


zahl ~ c + 1
versuch ~ 0

# Schleife mit while


while zahl !~ c:
lf Anzahl Versuche
versuch ~ versuch + 1

lf Ei ng abe
print("Bitte eine Zahl eingeben:")
z~input()

# Versuch einer Umwandlung


try:
zahl ~ int(z)
except:
# Falls Umwandlung nicht erfolgreich

71
3 I Programmierkurs

print("Sie haben keine Zahl eingegeben")


# Schleife unmittelbar fortsetzen
continue

Ir Kommenta r
kommenta r( zahl, c)

IrAnzahl Versuche
print("Ergebnis: ", c)
print( "Anzahl Versuche:", versuch)

Listing 3.32 Datei [Link]

Die Ausgabe hat sich nicht geändert.


Zur Erläuterung:
aufgabeO ~ In der Funktion auf gabe ( ) werden die beiden Zufallszahlen ermittelt
und die Aufgabe wird auf dem Bildschirm ausgegeben. Außerdem
wird das Ergebnis der Aufgabe als Rückgabewert an das Hauptpro-
gramm zurückgeliefert.
kommentarO ~ Der Funktion kommenta r () werden zwei Zahlen als Parameter über-
mittelt: die Lösung des Anwenders und das richtige Ergebnis. Inner-
halb der Funktion wird die eingegebene Lösung untersucht und ein
entsprechender Kommentar wird ausgegeben. Die Funktion hat kei-
nen Rückgabewert.

Übung U0311
Das Programm aus Übung U0310 soll umgeschrieben werden. Innerhalb der
Funktion steuer() soll der Steuerbetrag nur berechnet und an das Hauptpro-
gramm zurückgeliefert werden. Die Ausgabe des ermittelten Werts soll im
Hauptprogramm stattfinden.

3.7 Das fertige Spiel

Anzahl bestimmen Zum Abschluss des Programmierkurses wird das Spiel noch ein wenig
erweitert - dabei nutzen Sie die Programmiermittel, die Ihnen inzwi-
schen zur Verfügung stehen. Bei der erweiterten Version des Spiels sol-
len bis zu 10 Aufgaben nacheinander gestellt werden. Der Benutzer kann
dabei die Anzahl selber bestimmen.

72
Das fertige Spiel I 3.7

~ Zusätzlich zur Addition kommen nun auch die anderen drei Grundre- Alle Grund-
rechenarten

I
chenarten zum Einsatz: Subtraktion, Multiplikation und Division.
~ Die Bereiche, aus denen die zufälligen Zahlen gewählt werden, hän- Zahlenbereiche
gen von der Rechenart ab. Bei der Multiplikation wird zum Beispiel
mit kleineren Zahlen gerechnet als bei der Addition.
~ Der Benutzer hat maximal drei Versuche pro Aufgabe.
~ Die Anzahl der richtig gelösten Aufgaben wird gezählt.
Die einzelnen Abschnitte des Programms sind nummeriert. Diese Num-
mern finden sich in der Erläuterung wieder.
In späteren Kapiteln kommen noch weitere Ergänzungen hinzu. Das Pro-
gramm sieht nun wie folgt aus:
# 1: Zufallsgenerator
import random
ra ndom. seed ( )

lf 2: Anzahl Aufgaben
anzahl ~ -1
while anzahl<O or anzahl>10:
try:
print("Wieviele Aufgaben (1 bis 10):")
anzahl ~ int(input())
except:
continue

lf 3: Anzahl ri chti ge Ergebni sse


richtig ~ 0

# 4: Schleife mit 5 Aufgaben


for aufgabe in range([Link]+l):
# 5: Operatorauswahl
opzahl ~ [Link](I.4)

# 6: Operandenaus wahl
if (opz a h1 ~~ 1):
a ~ [Link](-10.30)
b ~ [Link](-10.30)
op ~ "+"
c ~ a + b
el if(opzahl ~~ 2):
a [Link](I.30)
b ~ [Link](I.30)

73
3 I Programmierkurs

op ~ "-"
c ~ a b
e 1 i f (opz a h1 ~~ 3):
a ~ [Link](I,10)
b ~ [Link](I,10)
op ~ "*"
c ~ a * b
lf 7: Sonderfall Division
e 1 i f (opz a h1 ~~ 4):
c ~ [Link](I,10)
b ~ [Link](I,10)
op ~ "j"
a ~ c * b

# 8: Aufgabenstellung
print( "Aufgabe", aufgabe, "von",
anzahl, ":", a, op, b)

# 9: Schleife mit 3 Versuchen


for versuch in range(I,4):
lf 10: Eingabe
try:
print("Bitte eine Zahl eingeben:")
zahl ~ int(input())
except:
# Falls Umwandlung nicht erfolgreich
print("Sie haben keine Zahl eingegeben")
# Schleife unmittelbar fortsetzen
continue

lf 11: Kommenta r
i f zahl~~ c:

print(zahl. "ist richtig")


richtig ~ richtig + 1
break
else:
print(zahl, "ist falsch")

# 12: Richtiges Ergebnis der Aufgabe


print("Ergebnis: ", c)

# 13: Anzahl richtige Ergebnisse


print("Richtig:", richtig, "von", anzahl)

Listing 3.33 Datei [Link]

74
Das fertige Spiel I 3.7

Es wird die folgende Ausgabe erzeugt:


Wie v iele Aufgaben (1 bis 10):
2
Aufgabe 1 von 2
Bitte eine Zahl
26 + 18
eingeben:
I
44
44 ist richtig
Ergebnis: 44
Aufgabe 2 von 2 : 27 2
Bitte eine Zahl eingeben:
24
24 ist falsch
Bitte eine Zahl eingeben:
23
23 ist falsch
Bitte eine Zahl eingeben:
22
22 ist falsch
Ergebnis: 25
Richtig: 1 von 2

Zur Erläuterung:

~ Nach der Initialisierung des Zufallsgenerators (1) wird die gewünschte Fehler abfangen
Anzahl der Aufgaben eingelesen (2). Da der Benutzer einen Fehler bei
der Eingabe machen könnte, findet eine Ausnahmebehandlung statt.
~ Der Rückgabewert der Funktion input ( ) wird unmittelbar als Para- Eingabe,
meter der Funktion i nt ( ) genutzt. So können zwei Schritte auf ein- Umwandlung

mal erledigt werden.


~ Der Zähler für die Anzahl der richtig gelösten Aufgaben (r i cht i g) wird
auf 0 gestellt (3).
~ Es wird eine äußere fo r-Schleife mit der gewünschten Anzahl gestar-
tet (4).
~ Der Operator wird per Zufallsgenerator ermittelt (5). Zufälliger
Operator
~ Für jeden Operator gibt es andere Bereiche, aus denen die Zahlen aus-
gewählt werden (6). Der Operator selbst und das Ergebnis werden
gespeichert.
~ Eine Besonderheit ist bei der Division zu beachten (7). Es sollen nur Nur ganze Zahlen
ganze Zahlen vorkommen. Die beiden zufälligen Operanden (a und b)
werden daher aus dem Ergebnis einer Multiplikation ermittelt.

75
3 I Programmierkurs

~ Die Aufgabe wird gestellt (8). Dabei werden zur besseren Orientie-
rung des Benutzers auch die laufende Nummer und die Gesamtanzahl
der Aufgaben ausgegeben.
~ Es wird eine innere f 0 r-Schleife für maximal drei Versuche gestartet (9).
Maximal drei ~ Die Eingaben des Benutzers (10) werden kommentiert (11). Nach
Versuche maximal drei Versuchen wird das richtige Ergebnis ausgegeben (12).

Endergebnis ~ Als Endergebnis wird die Anzahl der richtig gelösten Aufgaben ausge-
geben (13).
4 Datentypen

Dieses Kapitel beschäftigt sich mit den Eigenschaften und Vorteilen der
I
verschiedenen Objekttypen. Es werden Operationen, Funktionen und
Operatoren für die jeweiligen Datentypen vorgestellt. Ein eigener
Abschnitt über Objektreferenzen und Objektidentität vervollständigt die
Objektbetrachtung.

Alle Daten werden in Python als Objekte gespeichert. Man kann dabei Alles ist ein Objekt.
zwei Arten von Objekttypen unterscheiden, nämlich zum einen die,
~ die einzelne Objekte beinhalten, wie zum Beispiel zahlen oder Zei-
chen und zum anderen die,
~ die eine zusammengehörige Gruppe von Objekten beinhalten wie zum
Beispiel Strings (= Zeichenketten), Listen, Tupe!, Dictionarys und Sets.
In diesem Kapitel geht es zunächst um zahlen. Später folgen die anderen
Objekttypen. Dabei werden auch die Gemeinsamkeiten und Unterschiede
der Objekttypen vorgestellt.

4.1 Zahlen

Ganze Zahlen, Zahlen mit Nachkommastellen, Brüche und Operationen


mit zahlen sind Thema dieses Abschnitts.

4.1.1 Ganze Zahlen


Es gibt in Python 3 einen Objekttyp für ganze zahlen: den Typ i nt (von Typ int
engl. integer für ganzzahlig). Zahlen dieses Typs sind unendlich genau.
zahlen des Typs i nt können mithilfe von vier verschiedenen Zahlensys- Zahlensysteme
ternen direkt verarbeitet werden. Üblicherweise wird das dezimale Zah-
lensystem mit der Basis 10 benutzt. Außerdem stehen in Python die fol-
genden Zahlensysteme zur Verfügung:
~ das duale Zahlensystem (mit der Basis 2)
~ das oktale Zahlensystem (mit der Basis 8)
~ das hexadezimale Zahlensystem (mit der Basis 16)

77
4 I Datentypen

Ein Beispiel:
a ~ 27
print("Dezimal:", a)
print("Hexadezimal :", hex(a))
print("Oktal:",oct(a))
print("Dual:", bin(a))

b ~ Ox1a + 12 + Ob101 + 0067


print("Summe:", b)

Listing 4.1 Datei [Link]

Folgende Ausgabe wird erzeugt:


Dezimal: 27
Hexadezimal : Ox1b
Okta 1: 0033
Dual: Ob11011
Summe: 98

Zur Erläuterung:
~ Die dezimale zahl 27 wird in die drei anderen Zahlensysteme umge-
rechnet und ausgegeben.
hexO ~ Die Funktion hex() dient zur Umrechnung und Ausgabe der Zahl in
das hexadezimale System. Dieses System hat neben den Ziffern 0 bis
9 noch die Ziffern abis f für die Werte von 10 bis 15. Die Zahl Ox1 b
entspricht dem Wert (in Worten) 1 mal 16 hoch 1 + b (= 11) mal 16
hoch O.
odO ~ Zur Umrechnung und Ausgabe der Zahl in das oktale System dient die
Funktion 0 ct ( ). Das oktale System hat nur die Ziffern 0 bis 7. Die
Zahl 0033 entspricht dem Wert (in Worten) 3 mal 8 hoch 1 + 3 mal 8
hoch O.
binO ~ Die Funktion bin ( ) dient zur Umrechnung und Ausgabe der Zahl in
das duale System. Dieses System hat nur die Ziffern 0 und 1. Die zahl
Ob11011 entspricht dem Wert (in Worten) 1 mal 2 hoch 4 + 1 mal 2
hoch 3 + 0 mal 2 hoch 2 + 1 mal 2 hoch 1 + 1 mal 2 hoch o.
Man kann auch direkt mit zahlen in anderen Zahlensystemen rechnen.
Die Berechnung der Variablen b ergibt:

Ox1a + 12 + Ob101 + 0067 =


(1 mal 16 hoch 1 + a (= 10) mal 16 hoch 0) +
Zahlen I 4·1

(1 mal 10 hoch 1 + 2 mal 10 hoch 0) +


(1 mal 2 hoch 2 + 0 mal 2 hoch 1 + 1 mal 2 hoch 0) +
(6 mal 8 hoch 1 + 7 mal 8 hoch 0) =
(16+10) + 10+2) + (4+0+1) + (48+7) = 98

4.1.2 Zahlen mit Nachkommastellen


Der Datentyp für Zahlen mit Nachkommastellen heißt fl oa t. Diese soge- Typ float
I
nannten Fließkommazahlen werden mithilfe des Dezimalpunkts und
gegebenenfalls der Exponentialschreibweise angegeben. Dazu ein klei-
nes Beispiel:
a 7.5
b 2e2
c 3.5 E3
d 4.2e 3

print(a. b. c. d)

Listing 4.2 Datei [Link]

Die Ausgabe lautet:


7.5 200.0 3500.0 0.0042

Zur Erläuterung:
~ Die Variable a erhält den Wert 7.5. Beachten Sie, dass Nachkomma- Dezimalpunkt
stellen mit einem Dezimalpunkt abgetrennt werden. Dies gilt auch für
die Eingabe einer zahl mit Nachkommastellen mithilfe der Funktion
input ().
~ Die Variable b erhält den Wert 200 (= 2 mal 10 hoch 2 = 2 mal 100).
~ Die Variable c erhält den Wert 3500 (= 3,5 mal 10 hoch 3 = 3,5 mal
1000).
~ Die Variable d erhält den Wert 0,0042 (= 4,2 mal 10 hoch -3 = 4,2 mal
0,001).

Bei der Zuweisung in Exponentialschreibweise wird mithilfe des e (oder Exponential-


E) ausgedrückt, um wie viele Stellen und in welcher Richtung der Dezi- schreibweise

malpunkt innerhalb der zahl verschoben wird. Diese Schreibweise eig-


net sich zum Beispiel für sehr große oder sehr kleine Zahlen, da sie die
Eingabe vieler Nullen erspart.

79
4 I Datentypen

4.1.3 Operatoren
Operator** Neben den bereits behandelten Rechenoperatoren + (Addition), - (Sub-
traktion), * (Multiplikation), / (Division) und % (Modulo, Rest einer
Ganzzahldivision) wird noch der Operator ** (Potenz) eingesetzt:

Ein Beispiel:
z ~ 5 ** 3
print("5 hoch 3 z)
z ~ 5.2 ** 3
print("5.2 hoch 3 ~", z)
z ~ -5.2 ** 3
print("-5.2 hoch 3 ~", z)
z ~ 5.2 ** 3.8
print("5.2 hoch 3.8 ~", z)

Listing 4.3 Datei [Link]

Es wird die Ausgabe erzeugt:


5 hoch 3 ~ 125
5.2 hoch 3 ~ 140.608
-5.2 hoch 3 ~ -140.608
5.2 hoch 3.8 ~ 525.79046467

Zur Erläuterung:
~ Der Variablen z wird nacheinander das Ergebnis verschiedener Expo-
nentialrechnungen zugewiesen. Anschließend wird der jeweils aktu-
elle Wert von z mit Kommentar ausgegeben.

4.1.4 Rundung und I<onvertierung


Es gibt eine Reihe fest eingebauter Funktionen für Zahlen. Eine Liste mit
vielen fest eingebauten Funktionen inklusive einer kurzen Beschreibung
finden Sie in Abschnitt 5.8, »Eingebaute Funktionen«.

roundO Als Anwendungsbeispiel für die fest eingebauten Funktionen soll die
Funktionen round () zur Rundung einer zahl dienen - im Unterschied zu
der bereits bekannten Funktion i nt () zur Konvertierung (= Umwand-
lung) in eine ganze zahl.

Das Programm:
lf Positive Zahl
x ~ 12/7
print("x:", x)

80
Zahlen I 4·1

# Rundung und Konvertierung


rx ~ round(x.3)
print("x gerundet auf drei Stellen: " rx)
rx ~ round(x)

I
print("x gerundet auf null Stellen: " rx)
ix ~ int(x)
print("int(x):". ix)
pr i nt ( )

Ir Negat i ve Zahl
x ~ -12/7
print ("x:". x)

# Rundung und Konvertierung


rx ~ round(x.3)
print("x gerundet auf drei Stellen: " rx)
rx ~ round(x)
print("x gerundet auf null Stellen: " rx)
ix ~ int(x)
print("int(x):". ix)
Listing 4.4 Datei [Link]

Es wird folgende Ausgabe erzeugt:


x: 1.71428571429
x gerundet auf drei Stellen: 1.714
x gerundet auf null Stellen: 2
i nt (x): 1

x: -1.71428571429
x gerundet auf drei Stellen: -1.714
x gerundet auf null Stellen: -2
i nt (x): -1

Zur Erläuterung:
~ Es wird die Division 12/7 ausgeführt. Das Rechenergebnis wird
anschließend auf drei verschiedene Arten umgewandelt:
~ Mithilfe der eingebauten Funktion round() wird das Ergebnis auf Runden auf drei
drei Stellen nach dem Komma gerundet. Stellen

~ Mit der gleichen Funktion wird das Ergebnis auf die nächsthöhere Runden ohne
oder nächstniedrigere ganze Zahl gerundet. KommasteIlen

81
4 I Datentypen

Stellen ~ Mithilfe der eingebauten Funktion i nt ( ) wird das Ergebnis in eine


abschneiden ganze Zahl umgewandelt. Dabei werden - im Unterschied zum
Runden - die Stellen nach dem Komma einfach abgeschnitten.
~ Die gleichen Operationen werden mit einer negativen Zahl mit Nach-
kommastellen durchgeführt.

4.1.5 Modul math


Mathematische Das Modul math enthält eine Reihe von mathematischen Funktionen für
Funktionen Zahlen.

sinO, cosO, tanO Als Beispiel für eine dieser Funktionen dienen im Folgenden die trigono-
metrischen Funktionen si n ( ), co s ( ) und ta n ( ). Das Modul ma t h beinhal-
tet außerdem die mathematischen Konstanten pi und e (Euler'sche Zahl).

Das Programm lautet:


Ir Modul math
import math

# Trigonom. Funktionen und Konstanten


x ~ 30
xbm ~ x / 180.0 * [Link]
print("Sinus x, "Grad:", [Link](xbm))
print("Cosinus", x, "Grad:", [Link](xbm))
print("Tangens", x, "Grad:", [Link](xbm))

Listing 4.5 Datei [Link]

Es wird die Ausgabe erzeugt:


Sinus 30 Grad: 0.5
Cosinus 30 Grad: 0.866025403784
Tangens 30 Grad: 0.57735026919

Zur Erläuterung:
~ Das Modul math wird importiert.
~ Sinus, Cosinus und Tangens des Winkels 30 Grad werden berechnet.
Bogenmaß, pi ~ Alle Funktionen beziehen sich auf eine Angabe des Winkels im
Bogenmaß, daher wird der Winkel mithilfe der Konstanten math. pi
in das Bogenmaß umgewandelt.
~ Die drei Funktionen werden angewendet, das Ergebnis wird ausgege-
ben.

82
Zahlen I 4·1

Es ist häufig nützlich zu wissen, ob es sich bei einer zahl um eine ganze typeO
zahl (Datentyp i nt) oder eine Fließkommazahl (Datentyp fl oa t) han-
delt. Die Funktion type ( ) gibt den Typ eines Objekts aus. Hierzu ein Pro-
grammbeispiel:
a ~ 2
print("Typ:", type(a))

b ~ 12/6
I
print("Typ:", type(b))
print("Modulo liefert:", 12%6~~O)

Listing 4.6 Datei [Link]

Das Programm erzeugt die Ausgabe:


Typ: <class 'int')
Typ: <class 'float')
Modulo liefert: True

Zur Erläuterung:

~ Die Variable a beinhaltet den Wert 2 und ist vom Typ i nt.
~ Die Variable b beinhaltet den gleichen Wert, allerdings als Ergebnis
von 12/6. Es handelt sich um ein Objekt vom Typ fl oat.
~ Die Information, dass ein Ergebnis ganzzahlig ist, erhält man mithilfe Operator %
des Modulo-Operators (%).

4.1.6 Brüche
Python kann auch mit Brüchen rechnen beziehungsweise Informationen fractions
über Brüche zur Verfügung stellen. Dazu wird das Modul fractions
(deutsch: Brüche) genutzt. Ein Beispiel:
# Import des Moduls
import fractions

Ir Bruch
z ~ 12
n ~ 28
print("Bruch:", z, "I", n)

Ir als Fraction
b1 ~ [Link](z, n)
print("Fraction:", b1)
4 I Datentypen

print("Z, N:", [Link], [Link])


wert ~ [Link] 1 [Link]
print("Wert:", wert)
pr i nt ( )

lf Umrechnen
x ~ "2.375"
print("Zahl:", x)
b2 ~ [Link](x)
print("Fraction:", b2)
pr i nt ( )

# ggT: größter gemeinsamer Teiler


print("Bruch:", z, "I", n)
print("ggT:", [Link](z,n))

Listing 4.7 Datei [Link]

Die Ausgabe lautet:


Bruch: 12 1 28
Fraction: 3/7
Z. N: 3 7
Wert: 0.428571428571

Zahl: 2.375
Fract i on: 19/8

Bruch: 12 1 28
ggT: 4

Zur Erläuterung:

Zähler, Nenner ~ Zunächst wird ein Beispiel-Bruch in der bekannten Form dargestellt.
Er wird gebildet aus zwei Zahlen: Zähler und Nenner.
FractionO ~ Die Funktion Fra ct ion ( ) aus dem Modul fra ct ion s bietet verschie-
dene Möglichkeiten, einen Bruch zu erzeugen. Genauer gesagt handelt
es sich bei Fract i on() um den Konstruktor der Klasse Fracti on. Damit
wird eine Instanz (ein Objekt) der Klasse erzeugt und eine Referenz
auf dieses Objekt zurückgeliefert. Klassen, Instanzen, Konstruktoren
und andere Aspekte der objektorientierten Programmierung werden
in Kapitel 6, »Objektorientierte Programmierung«, genauer erläutert.
Bruch kürzen ~ Der Bruch bl, der aus 12/28 gebildet wurde, wird bei der Erzeugung
automatisch auf 3/7 gekürzt.
Zahlen I 4·1

~ Zähler und Nenner des Bruchs stehen in den Eigenschaften nume ra to r numerator,
und denomi na to r einzeln zur Verfügung. Der Wert eines Bruchs läßt denominator

sich über diese beiden Eigenschaften berechnen: 3/7 = 0,428 ...


~ Umgekehrt kann auch eine zahl mit Nachkommastellen in einen Float-Zahl
Bruch umgerechnet werden. Dazu muss die Zahl in Anführungsstri-
chen verpackt der Konstruktormethode Fraction() übergeben wer-
den: Aus 2.375 wird 19/8.
I
~ Die Methode gcd ( ) berechnet den größten gemeinsamen Teiler (ggT; gcdO
engl. greatest common divisor) zweier ganzer zahlen. Dies ist die
größte Zahl. durch die sich die beiden ganzen Zahlen ohne Rest teilen
lassen. Für die zahlen 12 und 28 ist dies die Zahl 4. Mit dem größten
gemeinsamen Teiler kann ein Bruch gekürzt werden: Aus 12/28 wird
3/7.
Brüche können auch dazu dienen, eine zahl mit Nachkommastellen zu limit_
approximieren, also anzunähern. Dazu dient die Methode 1 im i Ldenomi - denominatorO
nator(). Ein Beispiel:

# Import des Moduls


import fractions

# untersuchte Zahl
x ~ "1.84953"
print("Zahl:", x)

i! als Bru c h
b3 ~ [Link](x)
print("Fraction:", b3)

i! approximiert
b4 ~ [Link](100)
print("Approximiert auf Nenner max. 100:", b4)

i! Genaui gkeit
wert ~ [Link] 1 [Link]
print("Wert:", wert)
print("rel. Fehler:", abs((float(x)-wert)/float(x)))
Listing 4.8 Datei [Link]

Die Ausgabe:
Zahl: 1.84953
Fraction: 184953/100000
Approximiert auf Nenner max. 100: 172/93
4 I Datentypen

Wert: 1.84946236559
rel. Fehl er: 3. 6568430142ge 05

Zur Erläuterung:
~ Es soll die zahl 1,84953 untersucht werden. Diese entspricht dem
Bruch 184953/100000.
Nenner begrenzen ~ Mit der Methode 1 i mit denomi nato r ( ) wird der Nenner auf die Zahl
100 begrenzt. Es wird dann der Bruch gesucht, der
~ einen Nenner mit dem maximalen Wert 100 hat und
~ der Zahl 1,84953 am nächsten kommt.
~ Im vorliegenden Fall ist der gesuchte Bruch 172/93.
~ Dieser Bruch hat den Wert 1,84946236559 und kommt der ursprüng-
lichen Zahl recht nahe.
Relativer Fehler ~ Der relative Fehler zwischen diesem Wert und der untersuchten Zahl
beträgt 3,65684301429 * 10 hoch -5.
Betrag, absO ~ Der relative Fehler wird mithilfe der eingebauten Funktion zur
Berechnung des Betrags ermittelt (abs (). Der Betrag ist bekanntlich
der Absolutwert einer Zahl, also die Zahl ohne das Vorzeichen.

4.2 Zeichen ketten

Sequenzen Zeichenketten sind Sequenzen von einzelnen Zeichen - also Texte. Auch
andere Objekttypen gehören zu den Sequenzen. Anhand von Zeichen-
ketten wird im Folgenden eine Einführung in die Sequenzen geboten.

4.2.1 Eigenschaften
Typ str Zeichenketten (Strings) sind Objekte des Datentyps s t r. Strings bestehen
aus mehreren Zeichen oder Worten. Sie werden gekennzeichnet, indem
man sie in einfache, doppelte oder dreimal doppelte Hochkommata setzt.
Ein Beispiel:
t1 "Hallo Welt"
t2 'Auch das ist eine Zeichenkette'
t3 """Diese Zeichenkette
geht über
mehrere Zeilen"""
t4 ~ 'Hier sind "doppelte Hochkommata" gespeichert'
print("Bitte geben Sie einen Text ein")
t5 ~ input()

86
Zeichen ketten I 4·2

print( "tl:", tl)


print("t2:", t2)
print("t3:", t3)
print("t4:", t4)

I
print("t5:", t5)

print("Typ:", type(tl))

Listing 4.9 Datei [Link]

Es wird die Ausgabe erzeugt:


Bitte geben Sie einen Text ein
Das ist meine Eingabe
tl: Hallo Welt
t2: Auch das ist eine Zeichenkette
t3: Diese Zeichenkette
geht über
mehrere Zeilen
t4: Hier sind "doppelte Hochkommata" gespeichert
t5: Das ist meine Eingabe
Typ: <class 'str')

Zur Erläuterung:

~ Die Zeichenkette tl ist in doppelten Hochkommata gespeichert.


~ Die Zeichenkette t2 ist in einfachen Hochkommata gespeichert.
~ Die Zeichenkette t3 ist in dreifachen Hochkommata gespeichert, sie Dreifache
darf sich deshalb über mehrere Zeilen erstrecken und wird auch in Hochkommata
mehreren Zeilen ausgegeben.
~ Die Zeichenkette t4 verdeutlicht den Vorteil, den das Vorhandensein
mehrerer Alternativen bietet: Die doppelten Hochkommata sind hier
Bestandteil des Texts und werden auch ausgegeben.
~ Die eingebaute Funktion input () ist bereits bekannt. Sie dient zur Zeichenkette
Eingabe von Zeichenketten. Sie liefert als Ergebnis den eingegebenen zuweisen

Text zurück. Er wird hier in der Variablen t5 gespeichert.


~ Mithilfe der Funktion type ( ) wird für die Zeichenkette tl der Objekt-
typ (s t r) ausgegeben.

4.2.2 Operatoren
Die Operatoren + und * dienen zur Verkettung mehrerer Sequenzen Operatoren +, *, in
beziehungsweise zur Vervielfachung einer Sequenz. Mithilfe des Opera-
4 I Datentypen

tors in kann man feststellen, ob ein bestimmtes Element in einer


Sequenz enthalten ist. Betrachten Sie das folgende Beispiel für diese Ope-
ratoren, angewendet für Strings:
# Operatoren + und *
t1 ~ "Teil 1"
t2 ~ "Teil 2"
tgesamt ~ tl +" "+ t2

t3 ~ "-0000-"
t4 ~ "***"
tlinie ~ t4 + t3 * 3 + t4

print(tgesamt)
print(tl inie)

lf Operator in
tname ~ "Robinson Crusoe"
print("Text:", tname)

i f "b" in tname:
print("b: ist enthalten")

if "p" not in tname:


print("p: ist nicht enthalten")
Listing 4.10 Datei [Link]

Die Ausgabe lautet:


Teil 1. Teil 2
***-0000--0000--0000-***
Text: Robinson Crusoe
b: ist enthalten
p: ist nicht enthalten

Zur Erläuterung:
Verkettung ~ Die Zeichenkette tgesamt wird mithilfe des Verkettungsoperators +
aus drei Teilen zusammengesetzt: den beiden Zeichenketten t1 und
t2 und dem Text mit Komma und Leerzeichen.
Vervielfachung ~ Die Zeichenkette tl i ni e wird mithilfe des Verkettungsoperators +
und des Vervielfachungsoperators * zusammengesetzt. Dabei wird
die Zeichenkette "- 0000 -" dreimal hintereinander in tl in i e gespei-
chert.

88
Zeichen ketten I 4·2

~ Mithilfe des Operators in wird festgestellt ob das Element »b« in der Operator in
Sequenz enthalten ist.
~ Der logische Operator not dient (zusammen mit in) zur Feststellung, Operator not
ob das Element »p« nicht enthalten ist.

4.2.3 Operationen
Teilbereiche von Sequenzen werden als Slices bezeichnet. Am Beispiel Teilbereiche von
I
von Strings soll der Einsatz von Slices verdeutlicht werden. Auf die hier Sequenzen
beschriebene Art und Weise sind Slices auch auf andere Sequenzen
anwendbar.

Als Beispiel für eine Sequenz wird wiederum die Zeichenkette »Robinson
Crusoe« in der Variablen tn ame gespeichert. Die folgende Tabelle 4.1 stellt
die einzelnen Elemente von tname mit dem zugehörigen Index dar. Die
Nummerierung beginnt bei 0; alternativ können Sie auch eine negative
Nummerierung nutzen, die mit -1 endet (siehe unterste Zeile der Tabelle) .

Index . . . . . . . . . . .1111111l1li111
Element R o b n o n c u o e
negativer Index -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1

Tabelle 4.1 Sequenz mit Index

Ein Slice wird durch die Angabe eines Bereichs in eckigen Klammern ([ J) Index
hinter der sequenziellen Variablen erzeugt. Er beginnt mit einem Startin-
dex, gefolgt von einem Doppelpunkt und einem Endindex. Ein Slice, der
nur aus einem einzelnen Zeichen besteht, wird durch die Eingabe eines
einzelnen Index erzeugt.

Die eingebaute Funktion 1 en () ermittelt die Anzahl der Elemente einer lenO
Sequenz. Im Fall eines Strings spricht man hierbei auch von der Länge
der Zeichenkette.
lf Bei spi el -Sequenz, hi er Zei chenkette
tname ~ "Robinson Crusoe"
print("Text:", tname)

# Lange der Sequenz


19 ~ len(tname)
print("Lange:", 19)
lf Teilbereiche, Elemente
ts ~ tname[5:8J
print("[5:8J:", ts)

89
4 I Datentypen

ts ~ tname[:8J
print("[:8J:", ts)
ts ~ tname[9:J
print("[9:J:", ts)
ts ~ tname[9J
print("[9J:", ts)
ts ~ tname[9:-3J
print("[9:-3J:", ts)

Listing 4.11 Datei p0412 .py

Es wird die folgende Ausgabe erzeugt:


Text: Robinson Crusoe
Länge: 15
[5:8J: son
[: 8J: Robi nson
[9:J: Crusoe
[9 J: C
[9:-3J: Cru

Zur Erläuterung:

~ Die Länge der Sequenz, also die Anzahl der Zeichen in der Zeichen-
kette, wird mithilfe der Funktion 1en() ermittelt.
Slice von ... bis ~ Slice [5:8]: Der Bereich erstreckt sich von dem Element, das durch den
Startindex gekennzeichnet wird, bis vor das Element, das durch den
Endindex gekennzeichnet wird (Ergebnis: son).
Slice bis ~ Slice [:8]: Wenn der Startindex weggelassen wird, beginnt der Bereich
bei 0 (Ergebnis: Rob ins on).
Slice von ~ Slice [9:]: Wenn der Endindex weggelassen wird, endet der Bereich
am Ende der Zeichenkette (Ergebnis: Crusoe).
Element ~ Slice [9]: Wird nur ein Index angegeben, so besteht der Bereich nur
aus einem einzelnen Element (Ergebnis: C).
~ Slice [9:-3]: Wird ein Index mit einer negativen Zahl angegeben, so
wird vom Ende aus gemessen, beginnend bei -1 (Ergebnis: Cr u).

Unveränderbar Strings sind nicht veränderbar. Es können keine einzelnen Zeichen oder
Bereiche aus Strings durch andere Zeichen oder Slices ersetzt werden.

Ein Beispiel:
tname ~ "Robinson Crusoe"


Zeichen ketten I 4·2

try:
tname[3J ~ "e"
except:
print("Fehler")

try:
tname[3: 5J ~ "el"
except:
print("Fehler")
I
Listing 4.12 Datei p0413 .py

Die Ausgabe lautet:


Fehler
Fehler

Zur Erläuterung:

~ Die einzige Möglichkeit zur Veränderung eines Strings ist die Erzeu-
gung eines neuen Objekts.

4.2.4 Funktionen
Neben der eingebauten Funktion 1en () gibt es für Objekte des Daten-
typs s t r noch eine Reihe von nützlichen Funktionen zur Bearbeitung
und Analyse von Zeichenketten.

An folgendem Beispiel sollen einige Funktionen zum Suchen von Teiltex-


ten verdeutlicht werden:
Ir Bei spi el
test ~ "Das ist ein Beispielsatz"
print("Text:", test)

# Suchtexte zahlen
such ~ "ei"
anz ~ [Link](such)
print( "count: Der String", such, "kommt", anz, "mal vor")

# Erste Position des Suchtextes


anfpos ~ [Link](such)
print("find 1: Zum ersten Mal an Position", anfpos)
# Nachste Position des Suchtextes
nextpos ~ [Link](such, anfpos+1)
print("find 2: Das nachste Mal an Position", nextpos)
# Letzte Position des Suchtextes

91
4 I Datentypen

endpos ~ [Link](such)
print("rfind: Zum letzten Mal an Position", endpos)

# Suchtext nicht gefunden


such ~ "am"
pos ~ [Link](such)
if pos~~-l:
print("find 3'" such, "wurde nicht gefunden")
else:
print("find 3'" such, "an Position", pos, "gefunden")

# Ersetzen von Text


test ~ [Link]("ist","war")
print("replace:", test)
Listing 4.13 Datei [Link]

Folgende Ausgabe wird erzeugt:


Text: Das ist ein Beispielsatz
count: Der String ei kommt 2 mal vor
find 1: Zum ersten Mal an Position 8
find 2: Das nächste Mal an Position 13
rfind: Zum letzten Mal an Position 13
find 3: am wurde nicht gefunden
replace: Das war ein Beispielsatz

Zur Erläuterung:

countO ~ Die Funktion co u n t () ergibt die Anzahl der Vorkommen eines


Suchtexts (hier in der Variablen s u c h) innerhalb des analysierten Textes.
findO ~ Die Funktion find () ergibt die Position, an der ein Suchtext inner-
halb eines analysierten Texts vorkommt. Zur Erinnerung: Das erste
Element einer Sequenz hat die Position O.
Startpunkt für ~ Bei der Funktion f in d ( ) kann optional ein zweiter Parameter angege-
Suche ben werden. Dieser Parameter bestimmt die Position, ab der gesucht
wird. Im vorliegenden Fall ist dies die Position des Zeichens hinter
der ersten Fundstelle. Diese Technik wird häufig verwendet, um mit-
hilfe einer Schleife alle Vorkommen eines Suchtexts zu finden.
rfindO ~ Die Funktion rfind() ergibt die Position des letzten Vorkommens
des Suchtexts innerhalb des analysierten Textes.
~ Falls der gesuchte Text nicht vorkommt, liefern find() beziehungs-
weise rfi nd ( ) den Wert -1 zurück.

92
Zeichen ketten I 4·2

~ Die Funktion repl ace() ersetzt einen gesuchten Teiltext durch einen replaceO
anderen und liefert den geänderten Text zurück.

Das folgende Beispiel zeigt hauptsächlich Funktionen zum Zerlegen von


Texten in Teiltexte:

IrBei spi el
test ~ "Das ist ein Beispielsatz"
print("Text:", test)
I
IrBeginn, Ende
if [Link]("Das"):
print("Text beginnt mit Das")
if not [Link]("Das"):
print("Text endet nicht mit Das")

IrZerl egung
teile ~ [Link]("ei")
print("vor der 1. Teilung:", teile[O])
print("hinter der 1. Teilung:", teile[2])

teile ~ [Link]("ei")
print("vor der 2. Teilung:", teile[O])
print("hinter der 2. Teilung:", teile[2])

# Zerlegung in Liste
wliste ~ [Link]()
for i in range(O, 3):
print("Element:", i, wliste[i])

Listing 4.14 Datei [Link]

Die Ausgabe lautet:

Text: Das ist ein Beispielsatz


Text beginnt mit Das
Text endet nicht mit Das
vor der 1. Teilung: Das ist
hinter der 1. Teilung: n Beispielsatz
vor der 2. Teilung: Das ist ein B
hinter der 2. Teilung: spielsatz
El ement: 0 Das
El ement: ist
El ement: 2 ei n

93
4 I Datentypen

Zur Erläuterung:
startswithO, ~ Mithilfe der Funktionen startswith() und ends with() kann man
endswithO untersuchen, ob eine Zeichenkette mit einem bestimmten Text
beginnt oder endet. Beide Funktionen liefern einen Wahrheitswert
(T rue oder Fa 1 se), daher kann der Rückgabewert direkt als Bedingung
genutzt werden.
partitionO, ~ Die Funktionen pa rt i ti on () und rpa rt i t i on () zerlegen eine Zei-
rpartitionO chenkette in drei Teile anhand eines Teilungstexts. Diese drei Teile
werden in einem Tupel geliefert.
~ Das erste Element des Tupels (Element 0) beinhaltet den Text bis
zum Teilungstext, das dritte Element (Element 2) beinhaltet den
Text hinter dem Teilungstext.
~ Die Funktion pa rt i ti on ( ) sucht den Teilungstext ausgehend vom
Beginn der Zeichenkette , die Funktion r par t it ion () sucht ihn
ausgehend vom Ende der Zeichenkette.
~ Falls der Teilungstext nicht gefunden wird, steht die gesamte Zei-
chenkette im ersten Element des Tupels; das dritte Element ist leer.
~ Weitere Informationen zu den Tupeln erhalten Sie in Abschnitt
4.4, »Tupe!«.
splitO ~ Die Funktion s pli t ( ) zerlegt einen Text in einzelne Teile, die in einer
Liste gespeichert werden. Das Leerzeichen wird dabei als Trennzei-
chen angesehen. Zur Verdeutlichung werden im vorliegenden Bei-
spiel die drei ersten Elemente der Liste, zusammen mit der laufenden
Nummer innerhalb der Liste, ausgegeben (für weitere Informationen
zu Listen siehe Abschnitt 4.3, »Listen«).
~ Falls bei der Funktion s p 1 it () ein anderes Trennzeichen verwendet
werden soll, wie zum Beispiel das Semikolon oder das Rautezeichen,
dann muss dieses Zeichen als Parameter an die Funktion übergeben
werden, zum Beispiel: s pli t ( " ; " )

4.2.5 Umwandlung von Zeichenkette in Zahl


Beinhaltet eine Zeichenkette eine Zahl, etwa eine vom Benutzer eingege-
bene Zeichenkette oder einen Kommandozeilenparameter (siehe Ab-
schnitt 5.10), so kann diese Zeichenkette konvertiert werden. Dazu dienen
die bereits bekannten Funktionen i nt () und fl oat ( ) zur Umwandlung
in eine ganze zahl oder in eine Zahl mit Nachkommastellen. Anschließend
kann mit dieser Zahl gerechnet werden.

94
Zeichen ketten I 4·2

Das folgende Beispiel soll den Unterschied in der Behandlung von Zahlen
und Strings verdeutlichen:
# Erste Zeichenkette
x ~ "15.3"

ergebnis ~ x * 2
print(ergebnis)
I
x ~ float(x)
ergebnis ~ x * 2
print(ergebnis)

# Zweite Zeichenkette
x ~ "17"

ergebnis ~ x * 2
print(ergebnis)

x ~ int(x)
ergebnis ~ x * 2
print(ergebnis)

Listing 4.15 Datei [Link]

Die Ausgabe des Programms ist:


15.315.3
30.6
1717
34

Zur Erläuterung:

~ In der ersten Zeichenkette steht »15.3«. Wird diese Zeichenkette mit 2 floatO
»multipliziert«, so ergibt sich die Zeichenkette »15.315.3«. Wird die Zei-
chenkette mithilfe der Funktion f 10 a t () hingegen in eine zahl mit
Nachkommastellen verwandelt, so kann mit ihr gerechnet werden. Eine
Multiplikation mit 2 ergibt mathematisch korrekt die Ausgabe 30.6.
~ Ähnlich sieht es bei der Umwandlung einer ganzen Zahl aus. In der intO
zweiten Zeichenkette steht »17«. Wenn diese Zeichenkette mit 2
»multipliziert« wird, ergibt sich die Zeichenkette »1717«. Wird die
Zeichenkette mithilfe der Funktion i nt ( ) in eine ganze Zahl verwan-
delt, so kann mit ihr gerechnet werden. Eine Multiplikation mit 2
ergibt in diesem Fall mathematisch korrekt 34.

95
4 I Datentypen

Versucht man, eine Zeichenkette, die keine gültige Zahl beinhaltet, in


eine zahl umzuwandeln, so tritt eine Ausnahme auf. Daher sollte die
Umwandlung von Benutzereingaben oder Kommandozeilenparametern
in eine Ausnahmebehandlung eingebettet werden:
# Fehler abfangen
x ~ "15.3p"

try:
x ~ float(x)
print(x*2)
except:
print("Zeichenkette konnte nicht umgewandelt werden")

Listing 4.16 Datei [Link]

Die Ausgabe des Programms lautet:


Zei chenkette konnte ni cht umgewandel t werden

Zur Erläuterung:
~ In der Zeichenkette steht ein nicht gültiges Zeichen (hier das p). Bei
der Umwandlung tritt eine Ausnahme auf, und es erscheint eine Feh-
lermeldung.

4.2.6 Umwandlung von Zahl in Zeichen kette


strO Muss eine Zahl in eine Zeichenkette umgewandelt werden, etwa zur Aus-
gabe der Zahl in eine Datei (siehe Abschnitt 9.3.1, »Sequenzielles Schrei-
ben«), so kann die Funktion str() verwendet werden.

Ein Beispiel:
a 23
b 7.5
c a + b

lf 1. Ausgabe
print(a. "+". b. c)

lf 2. Ausgabe
print(str(a) + "+" + str(b) + +str(c))

Listing 4.17 Datei [Link]

96
Zeichen ketten I 4·2

Die Ausgabe lautet:


23 + 7.5 ~ 30.5
23+7.5~30.5

Zur Erläuterung:

~ Die erste Ausgabe erfolgt wie gewohnt. Sie setzt sich aus den einzel-
nen Variablen und den verbindenden Texten zusammen. Nachjedem
I
Teil der Ausgabe wird automatisch ein Leerzeichen eingefügt.
~ Für die zweite Ausgabe werden die Zahlen zunächst mithilfe der Operator +
Funktion s t r () in Zeichenketten umgewandelt. Abschließend wer-
den die verschiedenen Zeichenketten mit dem Verkettungsoperator +
verbunden. In der Ausgabe kommen keine Leerzeichen mehr vor.
~ Eine weitere Möglichkeit zur Gestaltung von Ausgaben wird in
Abschnitt 5.2.2, »Formatierte Ausgabe«, gezeigt.

4.2.7 Datentyp bytes


Zeichenketten des Datentyps bytes werden mithilfe von Byte-Literalen ASCII-Zeichen
gebildet und repräsentieren Binärdaten. Byte-Literale können mit ASCII-
Zeichen dargestellt werden, die mit einem Byte (also 8 Bit) gebildet wer-
den. Dies umfasst nur die Zahlen von 0 bis 255.

Byte-Literale beginnen mit einem »b« oder einem »B«. Objekte des Escape-Sequenzen
Datentyps bytes mit einem Zahlenwert über 127 werden durch Escape-
Sequenzen ausgedrückt (siehe Tabelle 4.2).

Escape-Sequenz Erläuterung
\r Carriage Return (Wagenrücklauf)
\n Une Feed (Zeilenvorschub)
\xe4 Umlaut ä, hex. E4 = dez. 228
\xf6 Umlaut ö, hex. F6 = dez. 246
\xfe Umlaut Ü, hex. FC = dez. 252
\xe4 Umlaut Ä, hex. C4 = dez. 196
\xd6 Umlaut Ö, hex. D6 = dez. 214
\xde Umlaut Ü, hex. DC = dez. 220
\xdf scharfes s, hex. DF = dez. 223

Tabelle 4.2 Einige Escape-Sequenzen

So werden beispielsweise die Zeichenketten »Öffnen« und »Schließen« als


Byte-Literale wie folgt ausgedrückt: b" \xd6ffnen" und b" Seh 1 i e \xd fen".

97
4 I Datentypen

4.3 listen
Eine Liste ist eine Sequenz von Objekten in ihrer allgemeinsten Form. Sie
kann Elemente unterschiedlichen Objekttyps beinhalten. Eine Liste bie-
tet vielfältige Möglichkeiten, unter anderem die Funktionalität von ein-
und mehrdimensionalen Feldern (Arrays), wie man sie aus anderen Pro-
grammiersprachen kennt.

4·3·1 Eigenschaften
Veränderbar Eine Liste ist im Gegensatz zu einem String veränderbar. Von diesem
Unterschied abgesehen ist ein String, vereinfacht gesagt, nur eine spezia-
lisierte Form einer Liste zur Speicherung von einzelnen Zeichen.
Einige Beispiele für Listen:
# Liste von Zahlen
z ~ [3. 6. 12.5. -8. 5.5J

print(zl # gesamte Liste


print(z[OJl # ein Element
print(z[O :3J l lf 51 iee

# Liste von Zeiehenketten


s ~ ["Hamburg". "Augsburg". "Berlin"J
print(sl

# Lange einer Liste


print( "Anzahl:". 1 en(s l l

Listing 4.18 Datei [Link]

Es wird die Ausgabe erzeugt:


[3. 6. 12.5. -8. 5.5J
3
[3. 6. 12.5J
[' Hamburg'. 'Augsburg'. 'Berl in' J
Anzahl: 3

Zur Erläuterung:

Eckige Klammern ~ Listen werden innerhalb von eckigen Klammern angegeben.


Kommata ~ Innerhalb dieser Klammern werden die einzelnen Elemente, durch
Kommata getrennt, aufgelistet.
~ Die Variable z beinhaltet eine Liste von Zahlen, mit und ohne Nach-
kommastellen.

98
Listen I 4·3

~ Wie bei Strings kann man ein einzelnes Element einer Liste durch Index
Angabe eines Index ermitteln (hier: z [0 J).
~ Ein Teilbereich einer Liste kann mithilfe eines Slice ermittelt werden Slice
(hier: z[O :3J).
~

~
Die Variable s beinhaltet eine Liste von Zeichenketten.
Die Länge einer Sequenz, also auch einer Liste, kann mit der Funktion
1en ( ) ermittelt werden.
lenO I
Eine Liste kann Elemente unterschiedlicher Objekttypen beinhalten. Mehrdimen-
Diese Elemente können wiederum Listen sein. Auf diese Weise werden sionale Listen
mehrdimensionale Listen erzeugt. Ein Beispiel:
# mehrdimensionale Liste, unterschiedliche Objekte
x ~ [["Paris","Fr",3500000J,["Rom","lt",4200000JJ
print(x)

lf Te i 11 ist e
print(x[OJ)

# einzelne Elemente
print(x[OJ[OJ, "hat", x[OJ[2J, "Ein wohner")
print(x[lJ[OJ, "hat", x[lJ[2J, "Einwohner")

# Teile von Elementen


print(x[OJ[lJ[:lJ)

Listing 4.19 Datei [Link]

Die Ausgabe lautet:


[['Paris', 'Fr', 3500000J, ['Rom', 'It', 4200000JJ
['Paris', 'Fr', 3500000J
Paris hat 3500000 Einwohner
Rom hat 4200000 Einwohner
F

Zur Erläuterung:

~ Die Variable x beinhaltet zwei Listen. Innerhalb jeder Teilliste (oder ein- Eingebettete Liste
gebetteten Liste) sind zwei Zeichenketten und eine zahl gespeichert.
~ Eingebettete Listen können durch Angabe eines einzelnen Index oder
eines Slices ermittelt werden (hier: x [0 J).
~ Einzelne Elemente von eingebetteten Listen können durch Angabe Mehrere Indizes
mehrerer Indizes oder Slices angesprochen werden (hier zum Bei-

99
4 I Datentypen

spiel: x [0 J [2 J). Die erste Angabe in eckigen Klammern kennzeichnet


hier die eingebettete Liste mit dem Index 0, die zweite Angabe in ecki-
gen Klammern kennzeichnet das Element mit dem Index 2 innerhalb
dieser eingebetteten Liste.
~ Einzelne Elemente der Liste sind wiederum Sequenzen, falls es sich
um Zeichenketten handelt. Daher kann man das erste Zeichen des Ele-
ments x [ 0 J [ 1 J mithilfe von x [ 0 J [1 J [ : 1 J ermitteln.

4.3.2 Operatoren
Operatoren +, *, in Die Operatoren + und * können bei Sequenzen, also auch bei Listen, zur
Verkettung oder Vervielfachung eingesetzt werden. Außerdem werden
Listen, zusammen mit dem Operator in, häufig zur Erstellung einer f 0 r-
Schleife genutzt. Ein gemeinsames Beispiel für die beiden genannten Fälle:
lf zwei Listen
fr [ " Par i s " , " Ly 0 n" , "M ars eil 1 e" J
it ~ ["Rom","Pisa"J

# Listen zusammensetzen
stadtliste ~ fr + it * 2
print(stadtl iste)

# Liste teilweise durchlaufen


for stadt in stadtl i ste[3 :6J:
print(stadt)
Listing 4.20 Datei [Link]

Es wird die folgende Ausgabe erzeugt:


['Paris', 'Lyon', 'Marseille', 'Rom', 'Pisa', 'Rom', 'Pisa'J
Rom
Pisa
Rom
Zur Erläuterung:
~ In den beiden Listen fr und i t werden jeweils einige Zeichenketten
gespeichert.
~ Die Liste stadtl iste ist eine neue Liste. Sie beinhaltet die Elemente
der Liste fr und zweimal nacheinander die Elemente der Liste i t .
~ Die Liste stad t 1 i s te wird als vollständige Liste ausgegeben.
for-Schleife ~ Mithilfe einer fo r-Schleife und eines Slices wird ein Teil der Liste Ele-
ment für Element ausgegeben.

100
Listen I 4·3

4.3.3 Funktionen und Operationen


Listen können, im Gegensatz zu Strings, verändert werden. Es können Veränderlich
also nicht nur einzelne Elemente oder Teilbereiche ausgewählt werden,
sondern es können außerdem

~
zusätzliche Elemente oder Teilbereiche am Ende oder am Anfang hin-
zugefügt,
vorhandene Elemente oder Teilbereiche verändert,
Liste ändern
I
~ Elemente oder Teilbereiche innerhalb der Liste eingefügt und
~ Elemente oder Teilbereiche gelöscht werden.

Man sollte allerdings beachten, dass man nicht aus Versehen ein einzel-
nes Element durch einen Teilbereich ersetzt. Dadurch würde statt des
Austauschs eines Elements eine ganze Liste als eingebettete Liste erzeugt
werden.

Im Folgenden werden zunächst einige Listenoperationen mit Elementen, dei


Teilbereichen und der Anweisung de 1 zum Löschen von Elementen auf-
geführt:
lf Originalliste
fr ~ ["Paris","Lyon","Marseille","Bordeaux"]
print("Original :")
print(fr)

# Ersetzen eines Elementes durch ein Element


fr[2] ~ "Lens"
print("Element ersetzt:")
print(fr)

# Ersetzen eines Teilbereiches durch eine Liste


fr[1:3] ~ ["Nancy","Metz","Gap"]
print("Teil ersetzt:")
print(fr)

# Entnehmen eines Teilbereiches


del fr[3:]
print("Teil entnommen:")
print(fr)

# Ersetzen eines Elementes durch eine Liste


fr[O] ~ ["Paris-Nord","Paris-Sud"]

101
4 I Datentypen

print("Element durch Liste ersetzt:")


print(fr)

Listing 4.21 Datei p0422 .py

Die Ausgabe der Liste in den verschiedenen Zuständen:


Original:
['Paris', 'Lyon', 'Marseille', 'Bordeaux']
Element ersetzt:
['Paris', 'Lyon', 'Lens', 'Bordeaux']
Tei 1 ersetzt:
['Paris', 'Nancy', 'Metz', 'Gap', 'Bordeaux']
Teil entnommen:
['Paris', 'Nancy', 'Metz']
Element durch Liste ersetzt:
[['Paris-Nord', 'Paris-Sud'], 'Nancy', 'Metz']

Zur Erläuterung:

~ Die o riginalliste , bestehend aus vier Zeichenketten, wird erstellt.


Ersetzen ~ Ein einzelnes Element wird durch eine andere Zeichenkette ersetzt.
~ Ein Teilbereich wird durch eine Liste ersetzt.
Löschen ~ Ein Teilbereich wird mithilfe von del aus der Liste gelöscht.
~ Ein Element wird durch eine Liste ersetzt, dadurch wird eine einge-
bettete Liste erzeugt.

Es gibt eine Reihe von weiteren Funktionen zur Analyse und Bearbeitung
von Listen. Einige dieser Funktionen werden im folgenden Programm
verdeutlich t:
lf Originallste
f r ~ [" Par i s " , " Ly 0 n" , "M ars eil 1 e" ]

print("Original :")
print(fr)

# Einsetzen eines Elements


[Link](O,"Nantes")
print("Nach Einsetzen:")
print(fr)

# Sortieren der Elemente


[Link]()
print("Nach Sortieren:")
print(fr)

102
Listen I 4·3

# Umdrehen der Liste


[Link]()
print("Nach Umdrehen:")
print(fr)

# Entfernen eines Elements


[Link]("Nantes")
print("Nach Entfernen:")
print(fr)
I
# Ein Element am Ende hinzu
[Link]("Paris")
print("Ein Element hinzu:")
print(fr)

i! Anzahl bestimmter El emente


print("Anzahl Elemente Paris:", [Link]("Paris"))

# Suchen bestimmter Elemente


print("Erste Position Paris:", [Link]("Paris"))
Listing 4.22 Datei p0423 .py

Die Ausgabe der Liste in den verschiedenen Zuständen:


Original:
[ , Par i s " 'Ly 0 n " 'M ars eil 1e ' ]
Nach Einsetzen:
[ , Na n t es', 'P a r i s " 'Ly 0 n " 'M ars eil 1e ' ]
Nach Sortieren:
[ , Ly 0 n " 'M ars eil 1 e', 'N a n t es', 'P a r i s ' ]
Nach Umdrehen:
['Paris', 'Nantes', 'Marseille', 'Lyon']
Nach Entfernen:
['Paris', 'Marseille', 'Lyon']
Ein Element hinzu:
['Paris', 'Marseille', 'Lyon', 'Paris']
Anzahl Elemente Paris: 2
Erste Position Paris: 0

Zur Erläuterung:
~ Die Originalliste, bestehend aus drei Zeichenketten, wird erstellt.
~ Ein Element wird mit der Funktion ins er t ( ) an der Position 0 einge- insertO
fügt, also zu Beginn der Liste.

1°3
4 I Datentypen

sortO ~ Die Liste wird mit der Funktion sort() intern sortiert. Falls es sich
um eine Liste von Zeichenketten handelt, wird alphabetisch sortiert.
Eine Liste von zahlen wird nach Größe sortiert. Bei anderen Listen-
elementen oder bei gemischten Listen ist der Einsatz der Funktion
so r t ( ) nur bedingt sinnvoll.

reverseO ~ Die Liste wird mit der Funktion reverse( ) intern umgedreht.
removeO ~ Ein bestimmtes Element (hier: Nantes) wird innerhalb der Liste
gesucht. Falls es vorhanden ist, wird das erste Vorkommen dieses Ele-
ments mit der Funktion remove( ) gelöscht. Falls es nicht vorhanden
ist, wird eine Ausnahme ausgelöst.
appendO ~ Ein Element wird am Ende der Liste mit der Funktion a ppend ( ) angefügt.
countO ~ Die Anzahl der Vorkommen eines bestimmten Elements (hier: Pa r i s)
wird mit der Funktion count() ermittelt.
indexO ~ Die Position des ersten Vorkommens eines bestimmten Elements
(hier: Par i s) wird mit der Funktion index ( ) ermittelt. Ist das Element
nicht vorhanden, wird eine Ausnahme ausgelöst.

4.4 lupel
In diesem Abschnitt werden Tupel und ihre besonderen Eigenschaften
sowie Operationen mit Tupeln erläutert.

Eigenschaften
Unveränderlich Ein Tupel unterscheidet sich von einer Liste im Wesentlichen durch eine
einzige Eigenschaft: Ein Tupel kann nicht verändert werden. Ansonsten
gelten die gleichen Regeln und es können die gleichen Operationen und
Funktionen auf Tupel wie auf Listen angewendet werden, sofern sie
keine Veränderung des Tupels hervorrufen.

4.4.2 Operationen
Einige Beispiele und Besonderheiten:
lf Tupel mi t und ohne Kl ammer
z ~ (3, 6, -8, 5.5)
print("Tupel 1:", z)

Z ~ 6, 8, -3
print("Tupel 2:", z)

104
Tupel I 4·4

# mehrdimensionales Tupel. unterschiedliche Objekte


x ~ (( .. Paris ..... Fr ... 3500000). [ .. Rom ..... Jt ... 4200000J)
print( "mehrdim. Tupel:")
print(x)

i!Ersetzen
try:
x [ 0 J [ 0 J ~ .. Ly 0 n .. i! n ich t e r 1 a u b t. we i 1 Tu p e 1
except:
I
print("Fehler")
x[IJ[OJ ~ "Pisa" i! erlaubt. weil Liste
print("Listenelement ersetzt: ... x[IJ)

i!Tupel bei for-5chl eife


for i in 4. 5. 12:
pr i nt ( .. i : ". i)

# Zuweisung mit Tupel


X.y 2.18~

print("x:". x. "y:". y)

Listing 4.23 Datei [Link]

Es wird die Ausgabe erzeugt:


Tupel 1: (3.6. -8. 5.5)
Tupel 2: (6. 8. -3)
mehrdim. Tupel:
(( 'Paris'. 'Fr'. 3500000). ['Rom'. 'It'. 4200000J)
Listenelement ersetzt: ['Pisa'. 'Jt'. 4200000J
i: 4
i: 5
i: 12
x: 2 y: 18

Zur Erläuterung:
~ Tupel können mit runden Klammern (statt eckiger Klammern bei Lis- Runde Klammern
ten) oder ganz ohne Klammern erzeugt werden. Sie können gleichzei-
tig Zahlen, Zeichenketten und andere Objekte beinhalten.
~ Durch Einbettung können mehrdimensionale Tupel erzeugt werden. Mehrdimen-
Hier ist dies das Tupel x, bestehend wiederum aus einem Tupel und sionale Tupel
einer Liste.
~ Die versuchte Veränderung des inneren Tupels erzeugt eine Aus-
nahme. Erlaubt ist dagegen die Veränderung der inneren Liste, die in
einem Tupel eingebettet ist (hier für x [ 1 J [ 0 J).

1°5
4 I Datentypen

Mehrfache ~ Mithilfe eines Tupels kann die Zuweisung von mehreren Werten
Zuweisung gleichzeitig realisiert werden. Im vorliegenden Beispiel werden die
Werte 2 bzw. 18 den Einzelvariablen x und y zugewiesen. Mehr zu
diesem Thema erfahren Sie im nächsten Abschnitt.

4.4.3 Tupel entpacken


Innerhalb eines Tupels sind mehrere, unveränderliche Werte gespei-
chert. Mithilfe eines Tupels kann eine mehrfache Zuweisung durchge-
führt werden. Dabei werden in einer Anweisung gleichzeitig mehreren
Variablen Werte zugewiesen.

Schreibabkürzung Dieses Vorgehen kann Ihnen Schreibarbeit ersparen. Allerdings müssen


Sie dabei einige Besonderheiten beachten, die das folgende Programm
verdeutlich t.
# 1: Mehrfache Zuweisung
x, y, z ~ 3, 5.2, "hallo"
print("Mehrf. Zuweisung:", x, y, z)

# 2: Auswirkungen erst danach


a 12
b ~ 15
c ~ 22
a, b, c ~ c, a, a+b
print("Auswirkung:", a, b, c)

# 3: Verpacken eines Tupels


p ~ 3, 4
print("Verpackt:", p)

lf 4: Entpacken ei nes Tupel s


m, n ~ p
print("Entpackt: m:", m, "n:", n)

lf 5: Falsche Zuweisung eines Tupels


try:
s, t ~ 3, 4, 12
print(s, t)
except:
print("Fehler")

lf 6: Rest in Liste
pr i nt ( )

106
Tupel I 4·4

x, *y, z 3, 5.2, "hallo", 7.3, 2.9


print(x)
print(y)
print(z)

Ir kein Rest, Liste leer


pr i nt ( )
x, *y, z
print(x)
~ 3, 5.2
I
print(y)
print(z)

Listing 4.24 Datei [Link]

Die Ausgabe sieht wie folgt aus:


Mehrf. Zuweisung: 3 5.2 hallo
Auswirkung: 22 12 27
Verpackt: (3, 4)
Entpackt: m: 3 n: 4
Fehler

3
[5.2000000000000002, 'hallo', 7.2999999999999998J
2.9

3
[J
5.2

Zur Erläuterung der mehrfachen Zuweisung (1):

~ Die Variable x bekommt den Wert 3, die Variable y den Wert 5.2 und Mehrfache
die Variable z den Wert »hallo« zugewiesen. Zuweisung

~ Die nachfolgenden Anweisungen bewirken dasselbe, beanspruchen


aber drei Programmzeilen statt einer.
x 3
y 5.2
z "hallo"

Zur Erläuterung der Auswirkungen (2):

~ Man kann erkennen, dass die Änderung eines Variablenwerts keine


Auswirkungen innerhalb der gleichen Mehrfachzuweisung hat:
~ Die Variable a erhält den alten (und neuen) Wert von c (= 22).

107
4 I Datentypen

~ Die Variable b erhält den alten Wert von a (= 12).


~ Die Variable c erhält den alten Wert von a, erhöht um den alten
Wert von b (= 27).
Auswirkung später ~ Die Änderung der Variablen wirkt sich erst in der nächsten Anwei-
sung aus.
~ Die nachfolgenden Anweisungen hätten zu ganz anderen Ergebnissen
geführt, sie sind nicht (!) gleichzusetzen mit der Anweisung: a, b, c ~
c, a, a+b:
a C
b a
c a+b

Zur Erläuterung der Verpackung (3):

Verpacken ~ Steht auf der linken Seite der Zuweisung nur eine Variable (im Bei-
spiel: p), während auf der rechten Seite mehrere Werte oder Ausdrü-
cke stehen (im Beispiel: 3 und 4), so handelt es sich um die Erzeugung
(Verpackung) eines Tupels.

Zur Erläuterung der Entpackung (4):

Entpacken ~ Ein Tupel kann wieder entpackt werden. Dabei sollte die Anzahl der
Variablen auf der linken Seite der Zuweisung (im Beispiel: die beiden
Variablen mund n) der Anzahl der Elemente des Tupels (im Beispiel:
p) auf der rechten Seite entsprechen.

Zur Erläuterung der falschen Zuweisung (5):

Anzahl passt nicht. ~ Es werden mehrere Werte zugewiesen, aber es steht nicht die gleiche
Anzahl an Variablen oder nur eine einzelne Variable zur Verfügung.
Es resultiert eine Ausnahme, da die Werte weder einem Tupel noch
einer einzelnen Variablen eindeutig zugeordnet werden können.
Zur Erläuterung der Zuweisung an die gesternte Variable (6):

Variable mit * ~ Falls die Anzahl der Tupel-Werte nicht mit der Anzahl der Variablen
übereinstimmt, kann man einer der Variablen einen Stern voranstel-
len. In dieser gesternten (englisch: starred) Variablen wird der Rest des
Tupels gespeichert, der nicht einer einzelnen Variablen zugewiesen
werden konnte. Im Programmbeispiel werden der erste und der letzte
Wert einer einzelnen Variablen zugewiesen. Die mittleren Werte lan-
den als Liste in der mittleren Variablen.

108
Dictionarys I 4·5

4.5 Dictionarys

Ein Dictionary ist mit einem Wörterbuch zu vergleichen. In einem Wör- Wörterbuch
terbuch kann man unter einem Schlüsselbegriff die zugeordnete Infor-
mation finden. So findet man etwa in einem englisch-deutschen Wörter-
buch unter dem Eintrag hause den zugeordneten deutschen Begriff Haus.
I
4.5.1 Eigenschaften
In Python stellen Dictionarys veränderliche Objekte dar und bestehen Schlüssel, Wert
aus mehreren Paaren. Jedes Paar besteht aus einem eindeutigen schlüssel
und einem zugeordneten Wert. über den schlüssel kann auf den Wert
zugegriffen werden. Als schlüssel werden meistens Strings verwendet, es
können aber auch andere unveränderliche Objekte (Zahlen, Tupel) ver-
wendet werden. Die schlüssel sind ungeordnet, ihre Reihenfolge ist
nicht festgelegt.
Im folgenden Beispiel sollen mehrere Personen und ihre Altersangaben
in einem Dictionary erfasst und bearbeitet werden. Der Name der jewei-
ligen Person dient als schlüssel. über den Namen kann auf das Alter der
Person (auf den Wert des Schlüssels) zugegriffen werden.
# Erzeugung eines Dictionarys
alter ~ {"Peter":31. "Julia":28. "Werner":35}
print(alter)

# Ersetzen eines Werts


alter["Julia"J 27
print(alter)

# Ein Element hinzu


alter["Moritz"J ~ 22
print(alter)

lf Ausgabe
print("Julia:". alter["Julia"J)

Listing 4.25 Datei [Link]

Folgende Ausgabe wird erzeugt:


{'Peter': 31. 'Julia': 28. 'Werner': 35)
{'Peter': 31. 'Julia': 27. 'Werner': 35)
{'Moritz': 22. 'Peter': 31. 'Julia': 27. 'Werner': 35)
Julia: 27

1°9
4 I Datentypen

Zur Erläuterung:

Geschweifte ~ Es wird das Dictionary alt e r mit drei Informationspaaren erzeugt und
Klammern ausgegeben. Dictionarys werden mithilfe von geschweiften Klammern
({ }) erzeugt. Die Paare werden durch Kommata voneinander getrennt,
ein Paar wird in der folgenden Form notiert: schlüssel: Wert.
Eckige Klammern ~ Auf ein Element kann über die Angabe des schlüssels in eckigen
Klammern zugegriffen werden. Dies wird im vorliegenden Beispiel
für Zuweisung und Ausgabe genutzt.
Veränderlich ~ Elemente sind veränderlich. Hier wird die Altersangabe von "J u1 i a "
verändert.
Hinzufügen ~ Elemente können hinzugefügt werden. Hier wird dem Dictionary das
Paar "Mo r i tz" : 2 2 hinzugefügt, da kein Element mit dem schlüssel
"Mo ritz" gefunden wurde.

4.5.2 Funktionen
Es gibt eine Reihe von Funktionen zur Bearbeitung von Dictionarys.
Einige werden im folgenden Programm verdeutlicht:
lf Erzeugung
alter ~ {"Peter":31. "Julia":28. "Werner":35}
print(alter)

# Element enthalten?
i f "Julia" in alter:
pr i nt (a 1 te r [ "J u 1 i a "J )

# Löschen eines Elementes


del alter["Julia"J

# Element enthalten?
i f "Julia" not in alter:
print("Julia ist nicht enthalten")

lf Anzahl El emente
print("Anzahl: ". len(alter))

# Aktualisierung mit zweitem Dictionary


ualter ~ {'Moritz': 18. 'Werner': 29)
[Link](ualter)
print(alter)

Listing 4.26 Datei [Link]

110
Dictionarys I 4·5

Das Programm erzeugt die Ausgabe:


{'Peter': 31. 'Julia': 28, 'Werner': 35)
28
Julia ist nicht enthalten
Anzahl: 2
{'Moritz': 18,

Zur Erläuterung:
'Peter': 31. 'Werner': 29)
I
~ Ein einzelnes Element wird mithilfe der Anweisung d e 1 aus der Liste dei
gelöscht.
~ Die Existenz eines Elements kann mithilfe des Operators in geprüft Operator in
werden.
~ Die Anzahl der Elemente wird mithilfe der Funktion 1 en ( ) ermittelt. lenO

~ Ein Dictionary kann mithilfe der Funktion update() mit einem ande- updateO
ren Dictionary aktualisiert werden. Dabei erhalten vorhandene Ele-
mente gegebenenfalls einen neuen Wert, neue Elemente werden
angehängt. Die beiden Dictionarys werden also zusammengeführt.

4.5.3 Views
Die Funktionen keys(), items() und val ues() erzeugen sogenannte Unmittelbare
Views eines Dictionarys. Diese Views verändern sich unmittelbar, falls Änderung
sich das zugeordnete Dictionary verändert. Ein Beispiel:
IrErzeugung
alter ~ {"Peter":31, "Julia":28, "Werner":35}

Ir Werte
w ~[Link]()
print("Anzahl Werte:", len(w))
fo r x in w:
print(x)
if 31 in w:
print("31 ist enthalten")
alter["Peter"J ~ 41
if 31 not in w:
print("31 ist nicht enthalten")
pr i nt ( )

Ir Keys
k ~ [Link]()
print("Anzahl Keys:", len(k))

111
4 I Datentypen

forxink:
print(x)
if "Werner" in k:
print("Werner ist enthalten")
del alter["Werner"]
if "Werner" not in k:
print("Werner ist nicht enthalten")
pr i nt ( )

lf Items
i ~ [Link]()
alter["Franz"] ~ 35
print("Anzahl Items:", len(i))
forxini:
print(x)
if ("Julia", 28) in i:
print("Julia, 28 ist enthalten")
Listing 4.27 Datei [Link]

Folgende Ausgaben werden durch den ersten Teil des Programms erzeugt:

Anzahl Werte: 3
31
28
35
31 ist enthalten
31 ist nicht enthalten
Zur Erläuterung des Werte-Views:

Werte-View ~ Mithilfe der Funktion val ues() wurde ein dynamischer View (w) der
Werte des Dictionarys erzeugt.
~ Der Inhalt des Views kann mithilfe einer fo r-Schleife und des Opera-
tors in ausgegeben werden. Man kann, wiederum mithilfe des Ope-
rators in, prüfen, ob ein bestimmter Wert im View existiert.
Änderung ~ Der Wert eines Dictionary-Elements wird verändert. Dies hat auch
unmittelbar Auswirkungen auf den zugehörigen View. Dieser muss also nicht
mehr neu erzeugt werden. Der ursprüngliche Wert wird nach der
Änderung nicht mehr gefunden.

Folgende Ausgaben werden durch den zweiten Teil des Programms


erzeugt:
Anzahl Keys: 3
Peter

112
Dictionarys I 4·5

Jul i a
Werner
Werner ist enthalten
Werner ist nicht enthalten
Zur Erläuterung des schlüssel-Views:

~ Mithilfe der Funktion keys () wurde ein dynamischer View (k) der
Keys des Dictionarys erzeugt.
Schlüssel-View I
~ Der Inhalt des Views kann mithilfe einer f 0 r-Schleife und des Opera-
tors in ausgegeben werden. Man kann, wiederum mithilfe des Ope-
rators in, prüfen, ob ein bestimmter Key im View existiert.
~ Ein Dictionary-Element wird gelöscht. Dies hat auch Auswirkungen Löschung
auf den zugehörigen View. Das ursprünglich vorhandene Dictionary- unmittelbar

Element wird nach dem Löschen nicht mehr gefunden.

Folgende Ausgaben werden durch den dritten und letzten Teil des Pro-
gramms erzeugt:

Anzahl Items: 3
('Franz'. 35)
('Peter' . 41)
( 'Jul i a ' . 28)
Jul i a . 28 ist enthalten
Zur Erläuterung des Elemente-Views:

~ Mithilfe der Funktion items ( ) wurde ein dynamischer View (i) der Elemente-View
Elemente des Dictionarys erzeugt.
~ Der Inhalt des Views kann mithilfe einer fo r-Schleife und in ausgege-
ben werden. Man kann, wiederum mit in, prüfen, ob ein bestimmtes
Element, also eine Schlüssel-Wert-Kombination, im View existiert.

4.5.4 Vergleiche
Dictionarys können miteinander verglichen werden. Mithilfe des Opera- Alle Elemente
tors ~~ kann festgestellt werden, ob alle Elemente, also alle schlüssel-Wert- gleich

Kombinationen, übereinstimmen. Allerdings kann nicht festgestellt wer-


den, ob ein Dictionary kleiner oder größer als ein anderes Dictionary ist.

Ein Beispiel:
# Zwei Dictionarys
alterl {"Julia":28. "Peter":30}
alter2 ~ {"Peter":30. "Julia":28}

113
4 I Datentypen

lf Vergl ei ch
if alterl ~~ alter2:
print("Gleich")
try:
if alterl < alter2:
print("1 < 2")
except:
print("Fehler")

Listing 4.28 Datei [Link]

Die Ausgabe lautet:


Gleich
Fehler

Zur Erläuterung:
Operator == ~ Die beiden Dictionarys werden, in unterschiedlicher Reihenfolge,
erstellt. Mithilfe von ~~ wird festgestellt, dass sie dennoch den glei-
chen Inhalt haben.
~ Der Vergleich mithilfe von < (oder» ist nicht möglich; er führt zu
einem Fehler.

4.6 Mengen, Sets


Einmalig, Mengen (englisch: sets) unterscheiden sich von Listen und Tupeln
ungeordnet dadurch, dass jedes Element nur einmal existiert. Außerdem sind Men-
gen ungeordnet, einzelne Elemente können also nicht anhand eines sli-
ces bestimmt werden. Allerdings können mit Mengen einige Operatio-
nen durchgeführt werden, die aus der Mengenlehre bekannt sind.

4.6.1 Eigenschaften
Zunächst werden ein Set und eine Liste (zum Vergleich) erzeugt und
einige Eigenschaften betrachtet:
lf Liste
li ~ [8. 2. 5. 5. 5J
print("Liste:". li)

lf Set
sI ~ set([8. 2. 5. 5. 5J)
print("Set:". s1)
print( "Anzahl:". 1en(sl))

114
Mengen, Sets I 4.6

Ir El emente
for x in sI:
print("Element:". x)
if5insl:

I
print("5 ist enthalten")
Listing 4.29 Datei [Link]

Die Ausgabe lautet:


Liste: [8. 2. 5. 5. 5J
Set: {8. 2. 5)
Anzahl: 3
El ement: 8
El ement: 2
El ement: 5
5 ist enthalten
Zur Erläuterung:

~ Eine Menge kann mithilfe der Funktion set () erzeugt werden. Als setO
einziger Parameter wird der Funktion set ( ) eine Liste (wie hier) oder
ein anderes Objekt übergeben, das durchlaufen werden kann.
~ Man erkennt den Unterschied zur Liste: In der Liste kann ein Objekt Einmalig
mehrmals vertreten sein, in der Menge nur einmal.
~ Die Funktion 1 en ( ) ergibt erwartungsgemäß die Anzahl der Elemente lenO
der Menge.
~ Mithilfe einer f 0 r-Schleife und des Operators in kann die Menge for, in
durchlaufen werden. Wiederum mit in kann geprüft werden, ob ein
bestimmtes Element in der Menge enthalten ist.

4.6.2 Funktionen
Es werden einige Funktionen betrachtet, die auf Mengen angewendet
werden können:
~ Kopieren einer Menge mit copy()
~ Hinzufügen von Elementen mit a dd ( )
~ Entfernen von Elementen mit dis c ar d ( )
~ Leeren einer Menge mit cl e a r ( )
Ein Beispiel:
Ir Set
sI ~ set([8. 15. "x"J)

115
4 I Datentypen

print("Original:", sI)

lf Kop i e
s2 ~ [Link]()
pr i nt ( " Ko pie: ", s 2 )

lf Element hinzu
[Link]( "abc")
print("Element hinzu:", s1)

# Element entnehmen
[Link] scard( "x")
print("Element entnommen:", sI)

lf Lee ren
[Link]()
print("geleert:", sI)

Listing 4.30 Datei [Link]

Es wird die Ausgabe erzeugt:


Original: {8, 'x', 15}
Kopie: {8, 'x', 15}
Element hinzu: {8, 'x', 'abc', 15}
Element entnommen: {8, 'abc', 15}
geleert: set()

Zur Erläuterung:

copyO ~ Die Funktion copy() erzeugt eine neue Menge, als Kopie der alten
Menge.
addO ~ Mithilfe der Funktion add ( ) kann man ein Element hinzufügen.
discardO ~ Die Funktion dis ca rd ( ) dient zum Löschen eines Elements.
clearO ~ Die Funktion cl ea r ( ) leert die Menge von allen Elementen.

4.6.3 Operatoren
< <= >= > Mit den vier Operatoren <, <~, > und >~ kann man feststellen, ob eine
Menge eine Teilmenge oder eine echte Teilmenge einer anderen Menge
ist. Ein Beispiel:
lf Sets
sI set([8, 2, 5J)
s2 ~ set( [2, 8J)

116
Mengen, Sets I 4.6

s3 ~
set([2, 5, 8J)

print("sl:", sI)
print("s2:", s2)

I
print("s3:", s3)

lf Teilmenge, echte Teilmenge


if s2 < sI:
print("s2 ist echte Teilmenge von sI")
if s3 <~ sI:

print("s3 ist Teilmenge von sI" )

Listing 4.31 Datei [Link]

Folgende Ausgabe wird erzeugt:


sI: {8, 2, 5 }
s2: {8, 2 }
s3: {8, 2, 5 }
s2 ist echte Teilmenge von sI
s3 ist Teilmenge von sI

Zur Erläuterung:

~ Die Menge s 2 ist eine echte Teilmenge der Menge sI, denn alle Ele- Echte Teilmenge
mente von s 2 sind in sI enthalten, und s 2 hat weniger Elemente als
sI.
~ Die Menge s3 ist nur eine normale Teilmenge der Menge sI, denn alle Teilmenge
Elemente von s3 sind in sI enthalten, aber s3 hat ebenso viele Ele-
mente wie sI.
~ Die Reihenfolge der Elemente bei der Erzeugung ist unerheblich.

Mithilfe der Operatoren I (oder) , & (und) , - (minus) und (hoch) kann
A I& _A
man einige Mengenoperationen durchführen. Ein Beispiel:
lf Sets
sI set([8, 15, "x"J)
s2 ~ set([4, "x", "abc", 15J)

print("sl:", sI)
print("s2:", s2)

# Vereinigungsmenge
s3 ~ sI I s2
print("Vereinigungsmenge:", s3)

117
4 I Datentypen

lf Schni ttmenge
s4 ~ sI & s2
print("Schnittmenge:", s4)

# Differenzmengen
s5~sl s2
print("Differenzmenge sl-s2:", s5)
s6 ~ s2 sI
print("Differenzmenge s2 sI:", s6)

s7 ~ s2 A sI
print("symm. Differenzmenge:", s7)

Listing 4.32 Datei [Link]

Die Ausgabe lautet:


sI: {B, 'x', 15}
s2: {'x', 'abc', 4, 15}
Vereinigungsmenge: {'abc', 4, B, 'x', 15}
Schnittmenge: {'x', 15}
Differenzmenge sl-s2: {B}
Differenzmenge s2-s1: {'abc', 4}
symm. Differenzmenge: {B, 'abc', 4}

Zur Erläuterung:

Vereinigungs- ~ Der Operator I (oder) dient zur Vereinigung zweier Mengen. Die ent-
menge stehende Menge enthält alle Elemente, die in der ersten oder in der
zweiten Menge enthalten sind. Auch in der neuen Menge ist jedes
Element nach wie vor nur einmal enthalten.
Schnittmenge ~ Alle Elemente, die in der ersten und in der zweiten Menge enthalten
sind, bilden die Schnittmenge. Dies gelingt mithilfe des Operators &
(und).
Differenzmenge ~ Bei einer Differenzmenge ist es wichtig zu betrachten, welche Menge
von welcher anderen Menge abgezogen wird. Mithilfe des Operators
(minus) werden zwei verschiedene Differenzmengen erstellt. Die
Operation sI - s 2 zieht von der Menge sI alle Elemente ab, die auch
in s 2 enthalten sind. Bei der Operation s 2 - s 1 verhält es sich umge-
kehrt.
Symmetrische ~ Bei der symmetrischen Differenzmenge werden mithilfe des Opera-
Differenzmenge tors (hoch) die Elemente ermittelt, die nur in einer der beiden Men-
A

gen enthalten sind.

118
Mengen, Sets I 4.6

4.6.4 Frozenset
Ein sonderfall eines Sets ist ein Frozenset. Ein Frozenset ist im Unter- Unveränderlich
schied zum Set eingefroren (englisch: jrozen) , also unveränderlich. Ein
Beispiel:

Ir Set
s ~ set([8, 15, "x", 8J)
print("Set:", s)
I
Ir Frozenset
fs ~ frozenset([8, 15, "x", 8J)
print("Frozenset:", fs)
for x in fs:
print(x)
try:
[Link]("x")
except:
print("Fehler")
Listing 4.33 Datei [Link]

~ Die Ausgabe sieht wie folgt aus:


Set: {8, 'x', 15}
Frozenset: frozenset({8, 'x', 15})
8
x
15
Fehler
Zur Erläuterung:

~ Bei der Erzeugung des Frozensets mithilfe der Funktion frozenset() frozensetO
wird (wie beim Set) darauf geachtet, dass jedes Element nur einmal
vorkommt.
~ Bei der Ausgabe wird das Frozenset besonders gekennzeichnet, durch frozenset
den Begriff frozenset und zusätzliche Klammern.
~ Die einzelnen Elemente können mithilfe von f 0 rund in wie gewohnt
ausgegeben werden.
~ Allerdings führt der Versuch, einen Frozenset zu verändern, zu einem
Fehler.

119
4 I Datentypen

4.7 Wahrheitswerte und Nichts

Objekte und Ausdrücke können wahr oder falsch sein, außerdem gibt es
auch das Nichts-Objekt. Der folgende Abschnitt erläutert die Zusammen-
hänge.

4.7.1 Wahrheitswerte True und False


Bedingung Besonders im Zusammenhang mit Bedingungsprüfungen (i f, wh i 1 e)
wird der Wahrheitswert eines Ausdruckes benötigt.

Beispiel: Wenn eine Zahl größer als 10 ist, sollen bestimmte Anweisun-
gen ausgeführt werden. Der dabei benötigte Ausdruck x > 10 ist wahr,
wenn x einen Zahlenwert größer als 10 hat. Er ist falsch, wenn x einen
Zahlenwert kleiner oder gleich 10 hat.

Typ bool Die Ausdrücke liefern eines der beiden schlüsselworte T rue (wahr) oder
Fa 1 se (falsch). Dies sind die einzigen Objekte des Datentyps boo 1.

boolO Es gibt außerdem die Funktion boo 1 ( ), die den Wahrheitswert eines
Ausdrucks oder eines Objekts zurückgibt.

Neben diesen Ausdrücken haben in Python auch Objekte einen Wahr-


heitswert:

Wahre Objekte ~ Folgende Objekte sind wahr (liefern True):

~ eine Zahl ungleich 0, also größer als 0 oder kleiner als 0


~ eine nicht leere Sequenz (String, Liste, Tupel)
~ ein nicht leeres Dictional}'
~ eine nicht leere Menge
Falsche Objekte ~ Folgende Objekte sind falsch (liefern Fa 1 se):

~ eine Zahl, die den Wert 0 hat


~ eine leere Sequenz (String: "", Liste [J, Tupel ( )
~ ein leeres Dictional}': {}
~ eine leere Menge: set(), frozenset()

~ die Konstante None (siehe Abschnitt 4.7.2, »Nichts, None«)

Endlosschleife Endlosschleifen, die nur mit einem b rea k verlassen werden können,
werden gerne mit whi 1 e( 1) konstruiert. Diese Bedingung ist immer
wahr. Man kann natürlich auch wh i 1 e (T r ue) schreiben.

120
Wahrheitswerte und Nichts I 4.7

Gilt für eine Objektsammlung 1 en (x) ~~ 0, so ist das Objekt x falsch. Im Länge gleich 0
folgenden Programm wird der Wahrheitswert der genannten Objekte an
Beispielen dargestellt, überprüft und ausgegeben.

# True und False

I
True, False
W ~ True
print("Wahrheitswert:", W)
W ~ False
print("Wahrheitswert:", W)

W ~ 5>3
print("5>3:", W)
W ~ 5<3
print("5<3:", W)
pr i nt ( )

lf Datentyp
W ~ 5>3
print("Typ von 5>3: " type(W))
pr i nt ( )

lf wahre Zahl Zahl


Z ~ 5 + 0.001 5
print("Zahl:", Z)
if Z:
print("Zahl ist", bool(Z))

# nicht wahre Zahl


Z ~ 5.75 5.75
print("Zahl:", Z)
if not Z:
print("Zahl ist", bool(Z))
pr i nt ( )

lf String Zeichen kette


S ~ "Kurt"
print("String:", S)
if S:
print("String ist nicht leer, also", bool(S))
pr i nt ( )

lf Liste Liste
L ~ [3,4J
print("Liste vorher:", L)
del L[O:2J

121
4 I Datentypen

print("Liste nachher:", L)
i f not L:
print("Liste ist leer, also", bool(L))
pr i nt ( )

Tupel lf Tupel
T ~ (5,8,2)
print("Tupel:", Tl
i f T:
print("Tupel ist nicht leer, also", bool(T))
pr i nt ( )

Dictionary lf Oi ct i ona ry
o~ {"Julia":28, "Werner":32}
print("Oictionary vorher:", 0)
del O["Julia"]
del O[ "Werner"]
print("Oictionary nachher:", 0)
i f not 0:
print("Oictionary ist leer, also", bool(O))
pr i nt ( )

Set lf Set
S ~ set([5, 7.5, "abc"])
print("Set vorher:", S)
[Link]()
print("Set nachher:", S)
i f not S:
print("Set ist leer, also", bool(S))
pr i nt ( )

Listing 4.34 Datei [Link]

Das Programm erzeugt die Ausgabe:


Wahrheitswert: True
Wahrheitswert: False
5>3: True
5<3: False

Typ von 5>3: <class 'bool'>

Zahl: 0.001
Zahl ist True
Zahl: 0.0
Zahl ist Fal se

122
Wahrheitswerte und Nichts I 4.7

String: Kurt
String ist nicht leer. also True

Liste vorher: [3. 4J

I
Li ste nachher: [J
Liste ist leer. also False

Tupel: (5. 8. 2)
Tupel ist nicht leer. also True

Dictionary vorher: {' Werner': 32. 'Jul ia': 28}


Dictionary nachher: {}
Dictionary ist leer. also False

Set vorher: {l.5. 'abc'. 5}


Set nachher: set()
Set ist leer. also False

Zur Erläuterung:

~ Der Variablen W werden Wahrheitswerte beziehungsweise die Ergeb- Typ bool


nisse von Vergleichsausdrücken, also auch Wahrheitswerte zugewie-
sen. Der Datentyp der Wahrheitswerte ist bo 0 1 .
~ Sobald das Ergebnis einer Berechnung von 0 abweicht, ergibt sich der
Wahrheitswert True.
~ String, Liste, Tupel, Dictionary und Set ergeben False, falls sie leer Leere Objekte
sind, und T rue, falls sie nicht leer sind. Dies kann man zur Prüfung der
betreffenden Objekte nutzen.

Nichts, None
Das schlüsselwort None bezeichnet das Nichts-Objekt. None ist das ein- NoneType
zige Objekt des Datentyps NoneType.

Funktionen ohne Rückgabewert liefern None zurück. Dies kann ein Hin- Rückgabewert
weis darauf sein,

~ dass man eine Funktion falsch eingesetzt hat, bei der man einen Rück-
gabewert erwartet hat, oder
~ dass eine Funktion kein Ergebnis geliefert hat, obwohl dies erwartet
wurde.

123
4 I Datentypen

Ein Beispiel:

lf Funktion
def quotient(a, b):
try:
c ~ alb
return c
except:
print("Funktion meldet Fehler")

# liefert Ergebnis
erg ~ quotient(7,4)
i f erg:
print("Ergebnis:", erg)
pr i nt ( )

# liefert Fehler
erg ~ quotient(7,O)
i f not erg:
print("Programm meldet Fehler")
print("Ergebnis:", erg)
print("Typ des Ergebnisses:", type(erg))
pr i nt ( )

lf Konstante None
Z ~ None
print("Z:", Z)
i f Z is None:
print("Objekt ist das Nichts, also", bool(Z))

Listing 4.35 Datei [Link]

Die Ausgabe lautet:

Ergebnis: 1.75

Funktion meldet Fehler


Programm meldet Fehler
Ergebni s: None
Typ des Ergebnisses: <class 'NoneType')

Z: None
Objekt ist das Nichts, also False

124
Referenz, Identität und Kopie I 4.8

Zur Erläuterung:
~ Zunächst wird die Funktion quot i ent () definiert. Diese berechnet
den Quotient aus zwei zahlen. Sie kann nicht den Wert 0 als Ergebnis

I
liefern.
~ Wenn der Quotient regulär berechnet werden kann, wird das Ergeb-
nis mithilfe von return zurückgeliefert. Dies ist beim ersten Aufruf
der Funktion der Fall.
~ Tritt ein Fehler auf, so wird nichts zurückgeliefert. Die Variable erg Funktion liefert
erhält also den Wert None. Dies kann man abfragen und damit feststel- None

len, dass die Funktion kein nutzbares Ergebnis geliefert hat.


~ Das Nichts-Objekt hat den Wahrheitswert Fal se.

4.8 Referenz, Identität und I<opie

In diesem Abschnitt wird der Zusammenhang zwischen Objekten und


Referenzen erläutert. Es wird die Identität von Objekten untersucht und
es werden Kopien von Objekten erzeugt.

4.8.1 Referenz und Identität


Der Name eines Objekts ist im Grunde nur eine Referenz auf ein Objekt. Referenz

Die Zuweisung dieser Referenz an einen anderen Namen erzeugt eine Operator is
zweite Referenz auf das gleiche Objekt. Mithilfe des Identitätsoperators
i s kann man feststellen, dass die beiden Referenzen auf das gleiche
Objekt verweisen.

Wird das Objekt über die zweite Referenz geändert, so zeigt sich eines
der beiden folgenden verhalten:

~ Im Fall eines einfachen Objekts wie Zahl oder String wird ein zweites Zweites Objekt
Objekt erzeugt, in dem der neue Wert gespeichert wird. Die beiden
Referenzen verweisen dann auf zwei verschiedene Objekte
~ Im Fall eines nicht einfachen Objekts wie Liste, Dictionary usw. wird Zweite Referenz
das Originalobjekt geändert. Es gibt nach wie vor ein Objekt mit zwei
verschiedenen Referenzen.
Mithilfe des Operators ~~ kann man feststellen, ob zwei Objekte den
gleichen Inhalt haben, ob also zum Beispiel zwei Listen die gleichen Ele-
mente beinhalten.

125
4 I Datentypen

Operatoren is, == Im folgenden Beispiel werden nacheinander eine Zahl. ein String und
eine Liste erzeugt und zweimal referenziert. Anschließend wird der zwei-
ten Referenz jeweils ein neuer Inhalt zugewiesen. Identität und Inhalt
werden anhand der beiden Operatoren i s und ~~ festgestellt.
# Kopie einer Zahl
print( "Zahl:")
x ~ 12.5
Y~ x
print("gleiches Objekt:", x is y)
y ~ 15.8
print("gleiches Objekt:", x is y)
pr i nt (" 9 1 ei c her In h alt: ", x ~~ y)
pr i nt ( )

# Kopie eines Strings


print( "String:")
x ~ "Robinson"
y ~ x
print("gleiches Objekt:", x is y)
y ~ "Freitag"
print("gleiches Objekt:", x is y)
pr i nt (" 9 1 ei c her In h alt: ", x ~~ y)
pr i nt ( )

# Zweite Referenz auf eine Liste


print("Liste:")
x ~ [23," ha 1 10" , - 7 . 5 J
y ~

x
print("gleiches Objekt:", x i s y)
y[1J ~
"welt"
print("gleiches Objekt:", x i s y)

Listing 4.36 Datei [Link]

Es wird die folgende Ausgabe erzeugt:


Za h1 :
gleiches Objekt: True
gleiches Objekt: False
gleicher Inhalt: False

String:
gleiches Objekt: True
gleiches Objekt: False
gleicher Inhalt: False

126
Referenz, Identität und Kopie I 4.8

Liste:
gleiches Objekt: True
gleiches Objekt: True

Zur Erläuterung:

~
Die Ausgabe zeigt, dass die Objekte zunächst jeweils identisch sind.
Nach der Zuweisung eines neuen Werts zeigt sich, dass im Fall von
zahl und String ein zweites Objekt erzeugt wird. Da die beiden neuen
Zweites Objekt
I
Objekte durch Zuweisung eines anderen Werts entstanden sind, sind
natürlich auch die Inhalte unterschiedlich.
~ Die Liste (hier stellvertretend auch für andere Objekte) existiert ins ge- Zweite Referenz
samt nur einmal. auch wenn einzelne Elemente der Liste verändert
wurden. Man kann über beide Referenzen auf die Liste zugreifen.

4.8.2 Ressourcen sparen


Python spart gerne Ressourcen. Dies kann zu einem ungewöhnlichen Ver- Speicherplatz
halten führen: Wenn einem Objekt über eine Referenz ein Wert zugewiesen sparen
wird und auf denselben Wert bereits von einer anderen Referenz verwiesen
wird, so kann es geschehen, dass die beiden Referenzen anschließend auf
dasselbe Objekt verweisen. Python spart also Speicherplatz.

Die Anweisung de 1 dient zur Löschung von nicht mehr benötigten Refe- Referenz löschen
renzen. Ein Objekt, auf das zwei Referenzen verweisen, wird durch das
Löschen der ersten Referenz nicht gelöscht.

Ein Beispiel:
i! Ein Objekt, zwei Referenzen
x 42
~

y 42
~

print("x:", x, "y:", y, "identisch:", x is y)

# Zweites Objekt
y ~ 56
print("x:", x, "y:", y, "identisch:", x is y)

# Ressourcen sparen
y ~ 42
print("x:", x, "y:", y, "identisch:", x is y)
# Entfernen, Schritt 1
del y
print( "x:", x)

127
4 I Datentypen

# Entfernen, Schritt 2
del x
try:
print("x:", x)
except:
print("Fehler")

Listing 4.37 Datei [Link]

Es wird die folgende Ausgabe erzeugt:


x: 42 y: 42 identisch: True
x: 42 y: 56 identisch: False
x: 42 y: 42 identisch: True
x: 42
Fehler

Zur Erläuterung:

Ein Objekt ~ Zunächst erhalten die beiden Referenzen x und y den gleichen Wert.
Man stellt fest: Es handelt sich nur um ein Objekt mit zwei Referen-
zen.
Zwei Objekte ~ Der Wert von y wird geändert. Damit gibt es nun zwei Referenzen auf
zwei verschiedene Objekte.
Ein Objekt ~ Der Wert von y wird wieder auf den früheren Wert zurückgesetzt.
Nun gibt es wieder nur noch ein Objekt.
~ Die Referenz y wird gelöscht. Das Objekt existiert weiterhin und kann
über die Referenz x erreicht werden.
~ Die Referenz x wird gelöscht. Nun führt die Ausgabe über diese Refe-
renz zu einem Fehler, da der Name nicht mehr existiert.

4.8.3 Objekte kopieren


[Link] Echte Kopien von nicht einfachen Objekten können durch Erzeugen
eines leeren Objekts und Anhängen beziehungsweise Hinzufügen der
einzelnen Elemente erzeugt werden. Für umfangreiche Objekte, die wie-
derum andere Objekte enthalten, kann man sich auch der Funktion
deepcopy() aus dem Modul copy bedienen. Beide Vorgehensweisen
zeigt das folgende Programm.
lf Modul copy
import copy

128
Referenz, Identität und Kopie I 4.8

Ir Kopie einer Liste, Methode


x [ 23 , " ha 11 0" , - 7 . 5 J
y [J
fo r i in x: # Elemente einzeln kopieren

I
[Link](i)
print ("gleiches Objekt:", x is y)
print ("gleicher Inhalt:", x y)
pr i nt ( )

Ir Kopie einer Liste, Methode 2


x ~ [23,["Berlin","Hamburg"J,-7.5,12,67J
y ~ [Link](x) # Funktion fOr Tiefenkopie
print("gleiches Objekt:", x is y)
pr i nt (" g 1 ei c her I n h alt: ", x ~~ y)

Listing 4.38 Datei [Link]

Das Programm erzeugt die Ausgabe:


gleiches Objekt: False
gleicher Inhalt: True

gleiches Objekt: False


gleicher Inhalt: True

Zur Erläuterung:

~ Die Ausgabe zeigt, dass in beiden Fällen jeweils ein neues Objekt
erzeugt wurde. Die Inhalte der beiden Objekte sind allerdings gleich.

129
5 Weiterführende Programmierung

In diesem Kapitel werden die Kenntnisse aus dem Programmierkurs im


Zusammenhang mit den verschiedenen Objekttypen durch nützliche
Praxistipps erweitert. I
5.1 Allgemeines

Im ersten Teil des Kapitels werden einige nützliche Techniken erläutert,


die keinem bestimmten Thema zuzuordnen sind.

5.1.1 I<ombinierte Zuweisungsoperatoren


Neben der einfachen Zuweisung eines Werts zu einer Variablen gibt es Kürzere
auch die kombinierten Zuweisungsoperatoren. Diese verbinden die nor- Schreibweise

malen Operatoren für Zahlen oder Zeichenketten mit der Zuweisung


eines Wertes. Die betreffende Variable wird also unmittelbar um den
genannten Wert verändert. Dies ist besonders bei umfangreichen Aus-
drücken oder bei längeren Variablennamen sinnvoll.
Ein Beispiel: Der Ausdruck Tempe rat u r I nCe 1si us +~ 5 ist überschaubarer
als der Ausdruck: Temperatur I nCe 1si us ~ Tempera tur I nCe 1si us + 5. Beide
Ausdrücke erhöhen den Wert der Variablen Tempe ra tur I nCe 1si us um 5.
Es folgt ein Beispiel, in dem kombinierte Zuweisungsoperatoren für Zah-
len und für Zeichenketten eingesetzt werden.
# Kombinierte Zuweisungsoperatoren fOr Zahlen
x ~ 12
print(x)

x +~ 3 lf Erhoehen von x
print(x)

x -~ 9 # Vermindern von x
print(x)

x **~ 2 # Quadrieren von x


print(x)

131
5 I Weiterführende Programmierung

x *~ 3 # Verdreifachen von x
print(x)

x //~ 7 # ganzzahliges Teilen von x


print(x)

x /~ 4 lf Teilen von x
print(x)

x %~ 2 # Dividieren. Rest berechnen


print(x)

# Kombinierte Zuweisungsoperatoren fOr Zeichenketten


t ~ " hallo"
print(t)

t +~ " python" # Anhaengen an t


print(t)

t *~ 3 # Verdreifachen von t
print(t)
Listing 5.1 Datei [Link]

Die Ausgabe:
12
15
6
36
108
15
3.75
1. 75
ha 110
ha 110 python
ha 110 python ha 110 python hallo python

Zur Erläuterung:
~ Die Variable x erhält zunächst den Wert 12. Durch die anschließen-
den Anweisungen wird der Wert von xjedes Mal verändert.
+= -= **= *= ~ Die Variable x wird um 3 erhöht (= 15), anschließend um 9 vermindert
(= 6), dann hoch 2 gerechnet (= 36) und mit 3 multipliziert (= 108).
//= /= %= ~ Es folgt eine Ganzzahldivision: 108 / 7 ~ 15.428 ... Die Nachkomma-
stellen werden dabei abgeschnitten. Die verbleibende Zahl (15) wird

132
Allgemeines I 5·1

durch 4 geteilt (= 3,75). Zuletzt wird der Rest der Division durch 2
berechnet (= 1,75).
~ Die Variable t erhält zunächst den Wert »hallo«.
~ Sie wird anschließend verlängert und vervielfacht. += *=

Bei all diesen Operationen ist darauf zu achten, dass die betreffende Vari-
able vorher bereits einen Wert hat, sonst tritt ein Fehler auf.

5.1.2 Anweisung in mehreren Zeilen


In Abschnitt 2.3 .6, »Lange Ausgaben«, wurde bereits erläutert, wie eine lange Zeichen \
I
Zeichenkette bei Einsatz der Funktion pr i nt ( ) über mehrere Zeilen verteilt
werden kann. In diesem Abschnitt wird gezeigt, wie man lange Anweisun-
gen generell zerlegen kann, unter anderem mithilfe des Zeichens \.

Ein Beispiel:
print("Umrechnung von Celsius in Fahrenheit")

# Trennung einer Zeichenkette


print("Bitte geben Sie eine"
" Temperatur in Celsius ein: ")
TemperaturlnCelsius ~ float(input())

# Trennung eines Ausdrucks


TemperaturlnFahrenheit ~ TemperaturlnCelsius \
* 9 / 5 + 32

# Trennung nach einem Komma


print(TemperaturlnCelsius, "Grad Celsius entsprechen",
TemperaturlnFahrenheit, "Grad Fahrenheit")
Listing 5.2 Datei [Link]

Die Ausgabe lautet:


Umrechnung von Celsius in Fahrenheit
Bitte geben Sie eine Temperatur in Celsius ein:
5.2
5.2 Grad Celsius entsprechen 41.36 Grad Fahrenheit
Zur Erläuterung:
~ Zunächst wird eine Zeichenkette in gewohnter Weise zerlegt und in
zwei Zeilen geschrieben. Jeder Teil der Zeichenkette wird in Anfüh-
rungszeichen gesetzt. Ein trennendes Leerzeichen zwischen den bei-
den Teilen muss von Hand eingegeben werden.

133
5 I Weiterführende Programmierung

Zeichen \ ~ Ein längerer Ausdruck mit einer Berechnung wird mithilfe des Zei-
chens \ zerlegt. Dieses Zeichen zeigt an, dass der Ausdruck in der
nächsten Zeile fortgesetzt wird.
Nach Komma ~ Einfacher ist die Zerlegung des Ausdruck, wenn in der Zeile Kommata
trennen auftreten, wie zum Beispiel beim Aufruf einer Funktion mit mehreren
Parametern oder bei der Zuweisung einer Liste. Hier kann einfach
nach einem Komma getrennt werden.

5·1·3 Eingabe mit Hilfestellung


inputO Die eingebaute Funktion input () zur Eingabe von Zeichenketten hat
einen optionalen Parameter. Dabei handelt es sich um eine Zeichenkette,
die eine hilfreiche Information für die Eingabe beinhalten sollte. Dies
spart eine Zeile mit der Funktion pr in t ( ).
Im folgenden Beispiel wird zunächst die Summe aus drei eingegebenen
Zahlen berechnet. Anschließend wird der Benutzer aufgefordert, den
jeweiligen Namen der Hauptstadt eines von insgesamt drei Ländern ein-
zugeben.
# Berechnung einer Summe
summe ~ 0
for i in range (1.4):
fehler ~ True
while fehler:
zahl ~ input(str(i) + ". Zahl eingeben: ")
try:
summe +~ float(zahl)
fehler ~ False
except:
print("Das war keine Zahl")
fehler ~ True

print("Summe:", summe)
pr i nt ( )

# Geografiespiel
hauptstadt ~ {"Italien":"Rom", "Spanien":"Madrid",
"Portugal":"Lissabon"}
hs ~ [Link]()

for land, stadt in hs:


eingabe ~ input("Bitte die Hauptstadt von"
+ land + " eingeben: ")

134
Allgemeines I 5·1

if eingabe~~stadt:

print("Richtig")
else:
print("Falsch. richtig ist:". stadt)

Listing 5.3 Datei [Link]

Die Ausgabe lautet:


l. Za h1 eingeben: 4
2. Za h1 eingeben: 6.7
Das war keine Za h1
I
2. Za h1 eingeben: 6.7
3. Zahl ei ngeben: 2
Summe: 12.7

Bitte die Hauptstadt von Spanien eingeben: Madrid


Richtig
Bitte die Hauptstadt von Italien eingeben: Neapel
Falsch. richtig ist: Rom
Bitte die Hauptstadt von Portugal eingeben: Lissabon
Richtig

Zur Erläuterung:
~ Bei der Eingabe zur Berechnung einer Summe wird als Hilfestellung
die laufende Nummer der einzugebenden Zahl ausgegeben. Es ist zu
beachten, dass diese Nummer in eine Zeichenkette umgewandelt und
mit dem restlichen Kommentar verkettet werden muss.
~ Aufgrund der Ausnahmebehandlung muss eine fehlerhafte Eingabe
wiederholt werden. In diesem Fall wird wieder die gleiche laufende
Nummer als Hilfestellung ausgegeben.
~ Bei der Zeichenketteneingabe wird das erste Element des jeweiligen
Tupel-Elements, also das Land, mit ausgegeben. Der Benutzer gibt die
Hauptstadt ein und erhält eine Rückmeldung, ob seine Eingabe richtig
oder falsch ist.

5.1.4 Anweisung pass


Die Anweisung pass bewirkt, dass nichts ausgeführt wird. Wozu existiert Nichts ausführen
sie dann? Einige mögliche Einsatzzwecke sind:
~ Man entwickelt ein Programm, in dem unter anderem eine Funktion Funktions-
aufgerufen wird. In der ersten Entwicklungsphase soll das Hauptpro- Dummy

gramm geschrieben werden. Der Funktionsaufruf soll bereits an der

135
5 I Weiterführende Programmierung

richtigen Stelle platziert werden, aber noch keine Auswirkungen


haben. Die Funktionsdefinition beinhaltet in diesem Fall nur die
Anweisung pass.
~ Das Programm beinhaltet eine einfache oder mehrfache Verzwei-
gung, bei der in einem bestimmten Zweig nichts ausgeführt werden
soll. Dieser Zweig soll aber trotzdem erscheinen, um den Programm-
ab lauf klarer zu machen.

Ein Programm mit Beispielen zu diesen Fällen sähe wie folgt aus:
# Funktions-Dummy
def OuadraturDesKreises():
pass

# Funktionsaufruf
OuadraturDesKreises()

# Nur else Zweig interessant


a -12
b 6
c 6.2

if a >~ 0 and b >~ 0 and c >~ 0:

pass
else:
print("Eine der Zahlen ist negativ")

# Ein Zweig nicht interessant


ifa~~I:

print("Fall 1")
elif a ~~ 2:
print("Fall 2")
elifa<O:
pass
else:
print("Ansonsten")

Listing 5.4 Datei [Link]

Die Ausgabe lautet:


Eine der Zahlen ist negativ
Allgemeines I 5·1

Zur Erläuterung:
~ Die Funktion QuadraturDesKreises() dient vorerst nur als Dummy
und wird erst zu einem späteren Zeitpunkt mit Inhalten gefüllt. Sie ist
aber bereits im Programm eingebaut und kann aufgerufen werden.
~ Bei der einfachen Verzweigung soll nur im e 1se-Zweig eine Ausgabe
erfolgen.
~ Bei der mehrfachen Verzweigung soll nur eine der drei möglichen Aus-
gaben erfolgen, falls der untersuchte Wert größer oder gleich 0 ist. I
5·1·5 Funktionen eval() und exec()
Die Funktionen eval () und exec() dienen zum Zusammensetzen von
Python-Code. Mit diesen Funktionen lassen sich Anweisungen dyna-
misch aus Zeichenketten bilden.

~ Die Funktion eva 1 () evaluiert den zusammengesetzten Ausdruck, Auswerten


ermittelt also den Wert (englisch: value) des Ausdrucks.
~ Die Funktion exec( ) führt eine zusammengesetzte Anweisung aus. Ausführen

Ein Beispiel:
import math

lf Zwei Funktionen
def mwl(a,b):
c ~ (a+b)/2
return c

def mw2(a,b):
c ~ [Link](a*b)
return c

lf eva 1
for i in 1.2:
t ~ "mw" + str(i) + "(3,4)"
c ~ eval(t)
print(c)
pr i nt ( )

lf exec
for i in 1.2:
t ~ "print(m w" + str(i) + "(3,4))"
exec(t)
Listing 5.5 Datei [Link]

137
5 I Weiterführende Programmierung

Folgende Ausgabe wird erzeugt:


3.5
3.46410161514

3.5
3.46410161514

Zur Erläuterung:
~ Es werden zunächst die Funktionen mw1 ( ) zur Ermittlung des arith-
metischen Mittelwerts und die Funktion mw2 () zur Ermittlung des
geometrischen Mittelwerts zweier Zahlen definiert.
~ Die Namen der beiden Funktionen, mw1 und mw2, unterscheiden sich
nur geringfügig.
Ausdruck zusam- ~ Für den Aufruf von eva 1 ( ) werden zwei Ausdrücke in Zeichenketten
mensetzen zusammengesetzt: "mw1 (3.4)" und "mw2 (3.4)". Mithilfe dieser
Zusammensetzung können die beiden Aufrufe erfolgen: c ~ mw1 (3.4)
und c ~ mw2 (3.4). Der Rückgabewert wird jeweils in der Variablen c
gespeichert, die anschließend ausgegeben wird.
Anweisung ~ Für den Aufrufvon exec( ) werden zwei Anweisungen in Zeichenket-
zusammensetzen ten zusammengesetzt: "pri nt (mw1 (3.4))" und "pri nt( mw2 (3.4))".
Diese beiden Anweisungen werden ausgeführt. Der Rückgabewert
wird direkt ausgegeben.

5.2 Ausgabe und Formatierung

In diesem Abschnitt werden weitere Möglichkeiten zur Ausgabe mithilfe


der Funktion pr i nt ( ) und zur Formatierung von Ausgaben erläutert.

5.2.1 Funktion print()


Die Funktion pr i nt ( ) wurde bereits mehrfach eingesetzt. Sie bietet noch
weitere Möglichkeiten:

Separator ~ Der Separator, der die ausgegebenen Objekte voneinander trennt,


kann verändert werden. Er wird mit sep bezeichnet. Normalerweise
wird ein Leerzeichen zur Trennung ausgegeben.
Zeilenende ~ Das Zeilenende, das normalerweise nach einer Ausgabe folgt, kann
verändert werden. Es wird mit end bezeichnet.
Ausgabe und Formatierung I 5.2

Ein Beispiel:
Ir Berechnung
a 23
b 7.5
c a + b

# normale Ausgabe
print("Ergebnis:", a, "+", b,

# Ausgabe ohne Zeilenende und Leerzeichen


print("Ergebnis: ", end~"")
c)

I
print(a, "+", b, "~", c, sep~"")

Ir Neue Zei 1 e
pr i nt ( )

Ir Liste
stadt ~ ["Hamburg", "Berl in", "Augsburg"]
for x in stadt:
print(x)
for x in stadt:
print("Stadt", x, sep~"~>", end~" # ")

Listing 5.6 Datei [Link]

Die Ausgabe sieht wie folgt aus:


Ergebnis: 23 + 7.5 ~ 30.5
Ergebnis: 23+7.5~30.5

Hamburg
Be rl in
Augsburg
Stadt~>Hamburg # Stadt~>Berlin # Stadt~>Augsburg #
Zur Erläuterung:

~ Zunächst wird die normale Ausgabe einer Berechnung erzeugt, mit


Leerzeichen zwischen den einzelnen Elementen.
~ Es folgen zwei Anweisungen, jeweils mit der Funktion pr i nt ( ). Bis-
her führte dies dazu, dass zwei Ausgabezeilen erzeugt wurden.
~ Weist man allerdings dem Parameter end eine leere Zeichenkette end
zu, so wird am Ende der Zeile nichts ausgegeben. Die nächste Aus-
gabe erfolgt dann in der gleichen Zeile.

139
5 I Weiterführende Programmierung

sep ~ Bei der nächsten Ausgabe wurde dem Parameter sep eine leere Zei-
chenkette zugewiesen. Dies führt dazu, dass die Ausgaben ohne
Leerzeichen direkt hintereinander stehen.
~ Es folgt die Ausgabe der Elemente einer Liste, zunächst in gewohnter
Form. In der zweiten Version werden sowohl der Separator als auch
das Zeilenende verändert.

5·2.2 Formatierte Ausgabe


Schleifen unterstützen unter anderem die Durchführung von Berechnun-
gen für eine Liste von Werten. Bei der Ausgabe steht man häufig vor dem
Problem, diese Werte übersichtlich in Tabellenform, anzuordnen.

formatO Die eingebaute Funktion fo rma t ( ) bietet Möglichkeiten für eine einheit-
liche, formatierte Ausgabe von zahlen und Zeichenketten. Man kann
unter anderem:

Breite, Anzahl ~ die Mindestausgabebreite der zahlen bestimmen


Stellen
~ die Anzahl der Nachkommastellen bestimmen

zunächst sollen zwei Zahlen mit Nachkommastellen auf verschiedene


Arten ausgegeben werden:
Ir 1: Zahl mi t Nachkommastell en
x ~ 100/7
Y ~ 2/7
print("Zahlen:")
print(x, y)
pr i nt ( )

Ir2: Format f
print("Format f")
print("{O:f} {O:f} (1:f}".format(x,y))
pr i nt ( " { 0 : 15 . 1 0 f} {1:. 25 f} " . form at ( x ,y) )
pr i nt ( )

Ir3: Format e
print("Format eH)
print("{O:e}" .format(x))
pr i nt ( " { 0 : 12 .3 e } " . form at ( x) )
print(" {O: .3e}". format(x))
pr i nt ( )

140
Ausgabe und Formatierung I 5.2

Ir 4: Format %
print("Format %")
pr i nt ( " { 0 : %} " • form a t (y) )
print(" {O: 12 .3%)". format(y))
pr i nt ( " { 0 : .3%) " . form a t (y) )

Listing 5.7 Datei [Link]

Folgende Ausgabe wird erzeugt:


Zahlen:
14.2857142857 0.285714285714
I
Format f
14.285714 14.285714 0.285714
14.2857142857 0.2857142857142857000000000

Format e
1.428571e+01
1.42ge+01
1.42ge+01

Format %
28.571429%
28.571%
28.571%

Zur Erläuterung:

~ Zu Block 1: Die Variablen x und y erhalten den Wert von 100/7 bezie-
hungsweise von 2/7. Sie werden zunächst unformatiert ausgegeben.
Dies führt zu einer Ausgabe in einer Gesamtbreite von 13 Stellen. Die
Anzahl der Nachkommastellen richtet sich nach der Größe der zahl.
~ Zu Block 2: Es wird eine Ausgabezeichenkette gebildet, in der die
gewünschten Formate stehen. Diese Ausgabezeichenkette ist ein
Objekt. Für dieses Objekt wird die Methode format() aufgerufen.
Parameter der Methode f 0 rma t ( ) sind die auszugebenden Variablen
beziehungsweise Werte.
~ Die auszugebenden Variablen beziehungsweise Werte werden intern Laufende Nummer
nummeriert, beginnend bei o. Diese Nummer wird in der Ausgabe-
zeichenkette benötigt.
~ Die Ausgabezeichenkette beinhaltet normalen Text und Ausdrücke in Geschweifte
geschweiften Klammern. Diese Ausdrücke in geschweiften Klammern Klammern

bestehen wiederum aus

141
5 I Weiterführende Programmierung

~ den oben genannten laufenden Nummern der Variablen bezie-


hungsweise des Werts,
~ einem Doppelpunkt und
~ einer Formatierungsangabe.
Formatf ~ Die erste Formatierungsangabe in Block 2 ist ein einzelnes f. Es steht
für: Ausgabe als Zahl mit sechs Nachkommastellen. Die Variable x
(laufende Nummer 0) wird zweimal in dieser Form ausgegeben, die
Variable y (laufende Nummer 1) einmal.
~ Die zweite Formatierungsangabe in Block 2 enthält die folgenden
Angaben:
~ Variable x (laufende Nummer 0) in 15.10 f: Breite der Ausgabe ins-
gesamt 15 Stellen, Zahl rechtsbündig, 10 Stellen nach dem Komma
~ Variable y (laufende Nummer 1) in .25f: Breite der Ausgabe
gesamt ist unbestimmt, 25 Stellen nach dem Komma
Format e ~ Das Format e in Block 3 steht für das Exponentialformat.
~ Ein einfaches e bedeutet: Ausgabe mit einer Stelle vor dem
Komma, sechs Stellen nach dem Komma, mit Exponent
~ Die Angabe 12 .3 e bedeutet: Breite der Ausgabe insgesamt 12 Stel-
len inklusive Exponent, Zahl rechtsbündig, 1 Stelle vor dem
Komma, 3 Stellen nach dem Komma, mit Exponent
~ Die Angabe .3e bedeutet: Breite der Ausgabe gesamt ist unbe-
stimmt, drei Stellen nach dem Komma, mit Exponent
Format % ~ Das Format %in Block 4 steht für das Prozentformat. Die Zahl wird für
die Ausgabe mit 100 multipliziert, intern bleibt die Zahl unverändert.
~ Ein einfaches % bedeutet: Ausgabe mit sechs Stellen nach dem
Komma, gefolgt von einem Prozentzeichen
~ Die Angabe 12.3 %bedeutet: Breite der Ausgabe insgesamt 12 Stel-
len inklusive Prozentzeichen, zahl rechtsbündig, 3 Stellen nach
dem Komma, Prozentzeichen
~ Die Angabe .3% bedeutet: Breite der Ausgabe insgesamt ist unbe-
stimmt, drei Stellen nach dem Komma, mit Prozentzeichen

Es folgt ein Beispiel für die Ausgabe von ganzen zahlen und Zeichenketten:
# Formatierung von Zeichenketten
pr i nt ( " {0 : >4 }{ 1 : >9 }{ 2 : >4 }{3 : >4 }" . form a t ( "d ez" ,
"dual ","okt","hex"))

142
Ausgabe und Formatierung I 5.2

# Formatierung ganzer Zahlen


for z in range(59.69):
pr i nt ( .. { 0 : 4 d ) { 0 : 9 b }{ 0 : 40) { 0 : 4x ) ... f 0 rma t ( z ) )
pr i nt ( )

# Tabelle mit verschiedenen Objekten


fm ~ "{0:04d){1:>12){2:4d){3:8.2f) Euro{4:8.2f) Euro"

I
artname ~ {23:"Apfel". 8:"Banane". 42:"Pfirsich")
anzahl {23:1. 8:3. 42:5)
epreis ~ {23:2.95. 8:1.45. 42:3.05)

pr i nt ( .. { 0 : >4 ) {1 : >12) { 2 : >4 ) {3 : >13) {4 : >13) ... form a t


( .. Nr ..... Name ..... Anz ..... EP ..... GP .. ))
for x in 23. 8. 42:
print([Link](x. artname[xJ. anzahl[x]'
epreis[x]. anzahl[x] * epreis[x]))

Listing 5.8 Datei [Link]

Die Ausgabe sieht wie folgt aus:

dez dua 1 o kt hex


59 111011 73 3b
60 111100 74 3c
61 111101 75 3d
62 111110 76 3e
63 111111 77 3f
64 1000000 100 40
65 1000001 101 41
66 1000010 102 42
67 1000011 103 43
68 1000100 104 44

Nr Name Anz EP GP
0023 Apfel 2.95 Euro 2.95 Euro
0008 Banane 3 1. 45 Euro 4.35 Euro
0042 Pfirsich 5 3.05 Euro 15.25 Euro

Zur Erläuterung:

~ Zeichenketten werden standardmäßig linksbündig ausgegeben. zah-


len werden standardmäßig rechtsbündig ausgegeben.
~ Als Erstes werden im Programm vier Zeichenketten formatiert ausge- Rechtsbündig >
geben. Nach der laufenden Nummer (0 bis 3) folgt das Zeichen> für
rechtsbündig und die Gesamtbreite der Ausgabe (4 beziehungsweise
9). Das Zeichen< würde für linksbündig stehen.

143
5 I Weiterführende Programmierung

Formate d, b, 0, x ~ Es folgt eine einheitlich formatierte Zahlentabelle. Die Zahlen von 59


bis 68 werden nacheinander ausgegeben als:
~ Dezimalzahl (Zeichen d, hier in Gesamtbreite 4)
~ Binärzahl beziehungsweise Dualzahl (Zeichen b, hier in Gesamt-
breite 9)
~ Oktalzahl (Zeichen 0, hier in Gesamtbreite 4)
~ Hexadezimalzahl (Zeichen x, hier in Gesamtbreite 4)
Mehrmals ~ Zum Abschluss folgt noch eine kleine Artikeltabelle. Die Formatierung-
verwenden sangabe wird einheitlich festegelegt und als Zeichenkette gespeichert.
Dies hat den Vorteil, dass sie mehrmals im Programm verwendet wer-
den kann. Die Zeichenkette beinhaltet Formate für ganze Zahlen, Zah-
len mit Nachkommastellen und Zeichenketten, sowie Text.
~ Es werden drei Dictionarys angelegt, für Artikelname, Anzahl und
Einzelpreis. Alle Elemente der Dictionarys werden einheitlich ausge-
geben, zusammen mit dem ermittelten Gesamtpreis.
Führende Nullen ~ Steht vor der Angabe der Gesamtbreite eine Null, so wird die Zahl mit
führenden Nullen bis zur angegebenen Gesamtbreite aufgefüllt. Dies
ist bei der ersten Spalte der Fall.

Übung U0501
Schreiben Sie das Programm aus der Übung U0307 so um, dass die nachfol-
gende Ausgabe (mit Überschrift) erzeugt wird. Die Beträge für inch und cm sol-
len jeweils mit zwei Nachkommastelien angezeigt und rechtsbündig ausgerich-
tet werden.
inch cm
15.0 38.1
20.0 50.8
25.0 63.5
30.0 76.2
35.0 88.9
40.0 101.6

5.3 Conditional Expression

Kürzere Eine Conditional Expression (d. h. ein bedingter Ausdruck) kann als
Schreibweise Schreibabkürzung für eine einfache Verzweigung dienen. Sie ist aller-
dings etwas schwerer lesbar.

144
Iterierbare Objekte I 5·4

Ein Programm mit zwei Beispielen:


x -12
y 15

# Ausdruck zur Zuweisung


max ~ x if x>y else y
print(max)

# Ausdruck zur Ausgabe


print("positi v" if x>O else "negati v oder 0")
I
Listing 5.9 Datei [Link]

Das Programm erzeugt die Ausgabe:

15
negativ oder 0

Zur Erläuterung:

~ Die erste Anweisung mit dem bedingten Ausdruck liest sich wie folgt:
Die Variable max erhält den Wert von x, falls x größer als y ist; ande-
renfalls erhält die Variable max den Wert von y.
~ Die zweite Anweisung mit dem bedingten Ausdruck liest sich wie
folgt: Gib die Zeichenkette pos i ti v aus, falls x größer als 0 ist, ansons-
tengib negativ oder 0 aus.

5.4 Iterierbare Objekte

Eine Abfolge von Objekten, die zum Beispiel in einer f 0 r-Schleife durch- Iterable
laufen werden kann, nennt man auch iterierbares Objekt oder kurz
Iterable. Listen, Zeichenketten, Tupe!, Dictionarys und andere Objekte
sind iterierbar. Man kann iterierbare Objekte unter anderem in fo r-
Schleifen benutzen.

Es gibt eine Reihe von Funktionen, die mit iterierbaren Objekten arbeiten
und die dem Entwickler viel Arbeit abnehmen können. Beispielhaft wer-
den im Folgenden die Funktionen z i p ( ), ma p ( ) und f i 1 te r ( ) erläutert.

145
5 I Weiterführende Programmierung

Funktion zipO
Iterables Die Funktion z i p ( ) verbindet Elemente aus verschiedenen iterierbaren
verbinden Objekten. Sie liefert wiederum einen Iterator, der aus den verbundenen
Objekten besteht. Ein Beispiel:

# Mehrere iterierbare Objekte


plz ~ [49808, 78224, 55411J
stadt ~ ["Lingen", "Singen", "Bingen"J
bundesland ~ ["NS", "BW", "RP"J

lf Verbi nden
kombi ~ zip(plz, stadt, bundesland)

lf Ausgabe
for element in kombi:
print(element)

Listing 5.10 Datei [Link]

Die Ausgabe lautet:


(49808, 'L ingen', 'NS')
(78224, 'Singen', 'BW')
(55411. 'Bingen', 'RP')

Zur Erläuterung:

~ Zunächst werden verschiedene iterierbare Objekte erzeugt - in die-


sem Fall drei Listen, die die Postleitzahlen, Namen und die entspre-
chenden Bundesländer dreier Städte beinhalten.
~ Die Funktion z i p ( ) erhält drei Parameter: die drei iterierbaren Objekte.
In der Funktion werden diese Parameter miteinander verbunden.
~ Es wird das Objekt kombi zurückgeliefert. Die Elemente des Objekts
kombi sind (thematisch zusammengehörige) Tupel.
~ Diese Tupel werden mithilfe einer fo r-Schleife ausgegeben.

5.4.2 Funktion map()


Funktionsaufrufe Mithilfe der Funktion ma p () können Funktionen mit einer Reihe von
Werten aufgerufen werden. Die Funktion liefert einen Iterator, der aus
den Funktionsergebnissen besteht. Ein Programm mit zwei Beispielen:

# Funktion mit einem Parameter


def quad(x):
Iterierbare Objekte I 5·4

erg ~ x * x
return erg

# Funktion mit mehr als einem Parameter


def summe(a,b,c):
erg ~ a + b + C
return erg

# Funktion mit einem Parameter mehrmals aufrufen


z ~ map(quad, [4, 2.5, -1.5J) I
# Jedes Ergebnis ausgeben
print("Quadrat:")
for element in z:
print(element)
pr i nt ( )

# Funktion mit mehr als einem Parameter mehrmals aufrufen


z ~ ma p ( summe, [3, 1. 2, 2 J. [4.8, 2 J. [5, 0.1. 9 J )

# Jedes Ergebnis ausgeben


print("Summe:")
for element in z:
print(element)

Listing 5.11 Datei [Link]

Die Ausgabe lautet:


Quadrat:
16
6.25
2.25

Summe:
12.8
3.3

Zur Erläuterung:
~ Zunächst werden zwei Funktionen definiert:
~ Die Funktion qua d ( ) hat einen Parameter und liefert das Quadrat
dieses Werts zurück.
~ Die Funktion summe ( ) hat drei Parameter und liefert die Summe
dieser drei Werte zurück.

147
5 I Weiterführende Programmierung

Zwei Parameter ~ Im ersten Beispiel wird die Funktion ma p ( ) mit zwei Parametern auf-
gerufen:
~ Der erste Parameter ist der Name der Funktion, die für die ver-
schiedenen Werte aufgerufen werden soll.
~ Der zweite Parameter ist ein iterierbares Objekt, in dem die Werte
stehen, für die die Funktion aufgerufen werden soll.
~ Es wird das Objekt z zurückgeliefert. Die Elemente des Objekts z
sind die Funktionsergebnisse, also die Rückgabewerte der Funk-
tion für die verschiedenen Aufrufe.
~ Diese Ergebnisse werden mithilfe einer f 0 r-Schleife ausgegeben.
Mehr als zwei ~ Im zweiten Beispiel wird die Funktion ma p ( ) mit mehr als zwei Para-
Parameter metern aufgerufen:
~ Der erste Parameter ist nach wie vor der Name der Funktion, die
für die verschiedenen Werte aufgerufen werden soll.
~ Der zweite und alle folgenden Parameter sind jeweils iterierbare
Objekte, in denen die Werte stehen, für die die Funktion aufgeru-
fen werden soll.
~ Für die Bildung der ersten Summe wird aus jedem iterierbaren
Objekt das erste Element (hier: 3, 4.8 und 5) verwendet. Für die
Bildung der zweiten Summe wird aus jedem iterierbaren Objekt
das zweite Element (hier: 1.2, 2 und 0.1) verwendet usw.
~ Das kürzeste iterierbare Objekt (hier: [4.8, 2 J) bestimmt die
Anzahl der Aufrufe. Die Funktion wird also niemals mit zu weni-
gen Parametern aufgerufen.
~ Es wird das Objekt z zurückgeliefert. Die Elemente des Objekts z
sind die Funktionsergebnisse, also die Rückgabewerte der Funk-
tion für die verschiedenen Aufrufe.
~ Diese Ergebnisse werden mithilfe einer f 0 r-Schleife ausgegeben.

5.4.3 Funktion filterO


Iterable filtern Die Funktion fi 1 te r ( ) untersucht Elemente eines iterierbaren Objekts
mithilfe einer Funktion. Sie liefert diejenigen Elemente, für die die Funk-
tion den Wahrheitswert True zurückliefert. Ein Beispiel:
# Funktion. die True oder False liefert
def test(a):
if a>3:
return True
List Comprehension I 5·5

else:
return False

# Funktion mehrmals aufrufen


z ~ filter(test. [5. 6. -2. O. 12.3. -5J)

# Ausgabe der Werte. die True ergeben


for element in z:
print("True:". element)
Listing 5.12 Datei [Link]
I
Es wird die Ausgabe erzeugt:
T r ue: 5
True: 6
True: 12

Zur Erläuterung:

~ Der erste Parameter der Funktion fi 1 te r () ist der Name der Funk-
tion, die für einen untersuchten Wert Tr ue oder Fa 1se liefert.
~ Der zweite Parameter ist das iterierbare Objekt, in diesem Fall eine
Liste.
~ Es wird das iterierbare Objekt z zurückgeliefert. In dieser Liste stehen
nur noch die Elemente, für die die Funktion True ergibt.

5.5 list Comprehension

Mithilfe von List Comprehensions kann man auf einfache Art und Weise Liste aus Liste
eine Liste aus einer anderen Liste erzeugen. Dabei können die Elemente
der ersten Liste gefiltert und verändert werden.

In insgesamt drei Beispielen wird die herkömmliche Technik der Technik


der List Comprehension gegenübergestellt:
i! Zwei Beispiellisten
xliste ~ [3.6. 8. 9. 15J
print(xliste)
yliste ~ [2. 13.4.8. 4J
print(yliste)
pr i nt ( )

149
5 I Weiterführende Programmierung

# Beispiel 1: Version ohne List Comprehension


aliste ~ [J
for item in xliste:
al i ste. append( item+l)
print(aliste)

# Beispiel 1: Version mit List Comprehension


aliste ~ [item + 1 for item in xlisteJ
print(aliste)
pr i nt ( )

# Beispiel 2: Version ohne List Comprehension


bliste ~ [J
for item in xliste:
if( item > 7):
[Link](item + 1)
print(bl i ste)

# Beispiel 2: Version mit List Comprehension


bliste ~ [item + 1 for item in xliste if item > 7]
print(bl i ste)
pr i nt ( )

# Beispiel 3: Version ohne List Comprehension


cliste ~ [J
for i in range(len(xliste)):
if xliste[iJ < 10 and yliste[iJ < 10:
[Link](xliste[iJ*10 + yliste[iJ)
print(cliste)

# Beispiel 3: Version mit List Comprehension


cliste [xliste[iJ*10 + yliste[iJ
~

for i in range(len(xliste))
if xliste[iJ < 10 and yliste[iJ < 10J
print(cliste)

Listing 5.13 Datei p0513 .py

Die Ausgabe lautet:

[3. 6. 8. 9. 15J
[2. 13. 4. 8. 4J

[4. 7. 9. 10. 16J


[4. 7. 9. 10. 16J

15°
Fehler und Ausnahmen I 5.6

[9. 10. 16J


[9. 10. 16J

[32. 84. 98 J
[32. 84. 98 J

Zur Erläuterung:

~
Zunächst werden zwei Beispiellisten gebildet. Für die Nutzung inner-
halb des dritten Beispiels ist es wichtig, dass sie gleich groß sind.
In Beispiel 1 wird zunächst ohne List Comprehension gearbeitet. Es
I
wird eine leere Liste erstellt. Innerhalb einer f 0 r-Schleife, die über
jedes Element iteriert, wird die Ergebnisliste mithilfe der Funktion
append() gefüllt.
~ Das Gleiche erreicht man auch in einem einzigen Schritt. Der Aus- Alle Elemente
druck al ist e ~ [it em + 1 f 0 r it em in xli s t e J bedeutet: Liefere den
Wert von (item+l) für jedes einzelne Element in xl i ste, dabei ist
»item« der Name eines einzelnen Elements.
~ In Beispiel 2 sieht man, dass eine Liste auch gefiltert werden kann. Es Elemente filtern
werden nur die Elemente übernommen, deren Wert größer als 7 ist. Der
Ausdruckbl i ste~ [item+ 1 for item in xl i ste i f item > 7] bedeutet:
Liefere den Wert von (i tem+ 1) für jedes einzelne Element in xli ste,
aber nur, wenn der Wert des einzelnen Elements größer als 7 ist.
~ Beispiel 3 zeigt, dass man natürlich auch eine fo r-Schleife mit ra nge Mit Index
verwenden kann. Die einzelnen Listenelemente werden über einen
Index angesprochen. Im Beispiel wird eine Liste aus zwei anderen,
gleich langen Listen gebildet. Dabei wird eine Filterungvorgenommen.

5.6 Fehler und Ausnahmen

Dieser Abschnitt bietet weitergehende Erläuterungen und Programmier-


techniken im Zusammenhang mit Fehlern und Ausnahmen.

5.6.1 Allgemeines
Während man ein Programm entwickelt und testet, treten oft noch Feh- Fehler sind normal
ler auf. Das ist völlig normal, und häufig kann man aus diesen Fehlern
hinzulernen. Fehler lassen sich in drei Gruppen untergliedern: Syntax-
fehler, Laufzeitfehler und logische Fehler.

151
5 I Weiterführende Programmierung

Abbruch Syntaxfehler werden spätestens dann bemerkt, wenn man ein Programm
vermeiden startet. Laufzeitfehler, also Fehler zur Laufzeit des Programms, die einen
Programmabsturz zur Folge haben, können mit einem try-except-Block
behandelt werden.

Logische Fehler Logische Fehler treten auf, wenn das Programm richtig arbeitet, aber
nicht die erwarteten Ergebnisse liefert. Hier hat der Entwickler den
Ablauf nicht richtig durchdacht. Diese Fehler sind erfahrungsgemäß am
schwersten zu finden. Hier bietet das Debugging eine gute Hilfestellung.

5.6.2 Syntaxfehler
Falscher Code Syntaxfehler treten zur Entwicklungszeit des Programms auf und haben
ihre Ursache in falsch oder unvollständig geschriebenem Programmcode.
Spätestens beim Starten eines Programms macht Python auf Syntaxfehler
aufmerksam. Der Programmierer erhält eine Meldung und einen Hin-
weis auf die Fehlerstelle. Das Programm wird nicht weiter ausgeführt.
Ein Beispiel für einen fehlerhaften Code:
x 12

if x > 10
print(x
Listing 5.14 Datei [Link]

FehlersteIle Nach dem Start des Programms erscheint die Fehlermeldung invalid syn-
markiert tax. Im Code wird die 12 markiert, da an dieser Stelle das Gleichheitszei-
chen erwartet wird. Das Programm läuft nicht weiter.
~

p0514. py - C:\Python30IKap05\[Link]
File Edit Format Run Options Window< Help
x
Syntax[rror [8J
if x > 10
print lx
invalid syntax

Abbildung 5.1 Anzeige des ersten Fehlers

152
Fehler und Ausnahmen I 5.6

Nach der Verbesserung des Programms wird es erneut gestartet. Es


erscheint die gleiche Fehlermeldung. Der Bereich nach x > 10 wird mar-
kiert, da an dieser Stelle der Doppelpunkt erwartet wird.

I
Abbildung 5.2 Anzeige des zweiten Fehlers

Nach erneuter Verbesserung des Programms wird es wieder gestartet. Es


erscheint noch einmal die gleiche Fehlermeldung. Die Zeile mit pr i nt (x
wird markiert, da die schließende Klammer erwartet wird.

Abbildung 5.3 Anzeige des dritten Fehlers

Erst nachdem auch der letzte Fehler beseitigt wurde, läuft das Programm
fehlerfrei bis zum Ende.

5.6.3 Laufzeitfehler
Ein try-except-Block dient zum Abfangen von Laufzeitfehlern, wie try-except
bereits in Abschnitt 3.5, »Fehler und Ausnahmen«, angesprochen. Lauf-
zeitfehler treten auf, wenn das Programm versucht, eine unzulässige
Operation durchzuführen, beispielsweise eine Division durch 0 oder das
öffnen einer nicht vorhandenen Datei.

153
5 I Weiterführende Programmierung

Nicht vermeidbar Natürlich wäre es besser, Laufzeitfehler von Anfang an zu unterbinden.


Dies ist allerdings unmöglich, da es Vorgänge gibt, auf die der Entwickler
keinen Einfluss hat, etwa die fehlerhafte Eingabe eines Benutzers oder
ein beim Druckvorgang ausgeschalteter Drucker.
Weitere Möglichkeiten zum Abfangen von Laufzeitfehlern werden in
Abschnitt 5.6.6, »Unterscheidung von Ausnahmen«, erläutert.

5.6.4 Logische Fehler und Debugging


Logische Fehler treten auf, wenn eine Anwendung zwar ohne Syntaxfeh-
ler übersetzt und ohne Laufzeitfehler ausgeführt wird, aber nicht das
geplante Ergebnis liefert. Ursache hierfür ist ein fehlerhafter Aufbau der
Programmlogik.

Debugging Die Ursache logischer Fehler zu finden, ist oft schwierig und erfordert
intensives Testen und Analysieren der Abläufe und Ergebnisse. Die Ent-
wicklungsumgebung IDLE stellt zu diesem Zweck einen einfachen
Debugger zur Verfügung.

EinzelschriUverfahren
Einzelne Schritte Sie können ein Programm im Einzelschrittverfahren ablaufen lassen, um
sich dann beijedem einzelnen Schritt die aktuellen Inhalte von Variablen
anzuschauen. Als Beispiel dient ein einfaches Programm mit einer
Schleife und einer Funktion:
def summe(a,b):
c ~ a + b
return c

for i in range(5):
erg ~ summe(lO,i)
print(erg)

Listing 5.15 Datei [Link]

Dieses Programm schreibt nacheinander die Zahlen von 10 bis 14 auf


den Bildschirm.

Debugger starten Sie starten den Debugger, indem Sie in der PYTHON SHELL im Menü
DEBUG den Menüpunkt DEBUGGER aufrufen. Es erscheint das Dialogfeld
DEBUG CONTROL und in der PYTHON SHELL die Meldung [DEBUG ONJ.

154
Fehler und Ausnahmen I 5.6

»>
[DEBUG ON]
»>

Abbildung 5.4 Dialogfeld Debug Control und Meldung

Starten Sie nun das Programm wie gewohnt über den Menüpfad RUN·
I
RUN MODULE, also über die Taste [NJ. Im Dialogfeld DEBUG (ONTROL
wird auf die erste Zeile des Programms hingewiesen.

Abbildung 5.5 Nach dem Start des Programms

Jetzt können auch die Buttons im Dialogfeld DEBUG (ONTROL betätigt Buttons bedienen
werden. Mit dem Button STEP gehen Sie schrittweise durch das Pro-
gramm. Mit dem nächsten Schritt gelangen Sie direkt hinter die Funk-
tionsdefinition, da die Funktion nur beim Aufruf durchlaufen wird.

Abbildung 5.6 Erste ausgeführte Programmzeile

Durch wiederholtes Drücken des Buttons STEP können Sie nun die Aktuelle Werte
Schleife mehrmals durchlaufen. Bei jedem Durchlauf wird auch die
Funktion summe () durchlaufen. Im unteren Bereich des Dialogfelds

155
5 I Weiterführende Programmierung

DEBUG CONTROL sehen Sie die jeweils gültigen Variablen und ihre sich
ständig verändernden Werte.
Befinden Sie sich im Hauptprogramm in der Schleife, so sehen Sie die
Werte von i und erg:

Jackage_ None
erg 11
1
summe <function summe at OxO12F6F 18 >

Abbildung 5.7 Hauptprogramm: Aktuelle Werte von i und erg

Wenn Sie sich in der Funktion summe ( ) befinden, sehen Sie die Werte
von a, b, und c (siehe Abbildung 5.8).

a 10
b2
c 12

Abbildung 5.8 Funktion: Aktuelle Werte von a, bund c

Ergebnisse parallel In der PYTHON SHELL werden parallel dazu die ersten Ergebnisse ausgege-
ben.

»>
[DEBUG ON]
»>
10
11

Abbildung 5.9 Python Shell: Ausgabe der ersten Ergebnisse

Debug On Nach Durchlauf der letzten Programmzeile wird noch der Hinweis
[Debug On] in der PYTHON SHELL ausgegeben. IDLE befindet sich nach
wie vor im Debug-Modus, aber die Buttons können erst nach einem
erneuten Programmstart wieder betätigt werden.

Weitere Möglichkeiten
Funktion Um das Programm in etwas größeren Schritten zu durchlaufen, kann
überspringen man den Button OVER betätigen. Die Funktionen werden dann nicht in
Einzelschritten, sondern als Ganzes durchlaufen. Der Debugger springt
also über die Funktionen hinweg.
Fehler und Ausnahmen I 5.6

Sie können auch zwischen den beiden Möglichkeiten (Button STEP und
Button OVER) flexibel hin und her wechseln - je nachdem, welchen Pro-
grammteil Sie sich ganz genau ansehen möchten.

Wenn man sich gerade in Einzelschritten durch eine Funktion bewegt, Funktion verlassen
führt die Betätigung des Buttons OUT dazu, dass der Rest der Funktion
übersprungen wird und mit dem ersten Schritt nach dem Funktionsauf-
ruf fortgefahren wird.

Der Button Go lässt das Programm, das man gerade debuggt, in einem
Schritt bis zum Ende laufen. Der Button QUIT bricht den Lauf des Pro-
Programm
beenden
I
gramms sofort ab, ohne es zu Ende laufen zu lassen. In beiden Fällen ist
der Debug-Modus noch eingeschaltet.

Der Debug-Modus lässt sich an derselben Stelle ausschalten, an der man Debug Off
ihn eingeschaltet hat: In der PYTHON SHELL, im Menü DEBUG • DEBUGGER.
In der PYTHON SHELL erscheint dann die Meldung [DEBUG OFF].

[DEBUG ON]
»>
10
11
12
13
14
[DEBUG ON]
»>
[DEBUG OFF]

Abbildung 5.10 Nach dem Beenden des Debuggers

Auf weniger elegante Weise können Sie den Debugger schließen, indem
Sie das Kreuz oben rechts im Dialogfeld DEBUG (ONTROL anklicken.

Andere Entwicklungsumgebungen für Python bieten noch weitere Mög- Haltepunkte


lichkeiten. Das Setzen von Breakpoints (deutsch: Haltepunkte) ist sehr
nützlich. Diese Haltepunkte werden auf bestimmte Programmzeilen
gesetzt. Das Programm kann man dann bis zu einer solchen Programm-
zeile in einem Schritt durchlaufen lassen und die aktuellen Werte über-
prüfen. Anschließend durchläuft man entweder im Einzelschrittverfah-
ren einen Programmbereich, in welchem man Fehler vermutet, oder
geht direkt zum nächsten, vorher gesetzten Haltepunkt usw.

157
5 I Weiterführende Programmierung

5.6.5 Fehler erzeugen


»Wieso sollte man Fehler erzeugen?«, werden Sie sich angesichts dieser
Überschrift fragen. Hierfür gibt es, besonders im Zusammenhang mit der
Eingabe von Daten durch einen Anwender, durchaus sinnvolle Gründe.
raise Im folgenden Beispiel wird der Anwender dazu aufgefordert, eine Zahl
einzugeben, deren Kehrwert anschließend berechnet wird. Diese Zahl
soll allerdings positiv sein. Diese Einschränkung kann mithilfe der
Anweisung ra i se bearbeitet werden, wie im folgenden Programm dar-
gestellt:
# Wiederholte Eingabe
fehler ~ True
while fehler:
try:
zahl ~ float(input("Eine positive Zahl: "))
i f zahl< 0:
raise
kw ~ 1.0 / z a h 1
fehler ~ False
except:
print( "Fehl er")

lf Ausgabe
print( "Der Kehrwert von". zahl. "i st". kw)

Listing 5.16 Datei [Link]

Ausnahme Ist die eingegebene Zahl kleiner als 0, so wird die Anweisung ra i se aus-
erzeugen geführt. Dadurch wird eine Ausnahme erzeugt, so als ob der Anwender
einen der anderen möglichen Fehler gemacht hätte. Das Programm ver-
zweigt unmittelbar zur Anweisung except und führt die dort angegebe-
nen Anweisungen aus.
In diesem Fall handelt es sich zwar nur um einen logischen Eingabefeh-
ler, aber er wird genauso behandelt wie ein Fehler im Programm. Der
Anwender wird somit veranlasst, nur positive Zahlen einzugeben.
Das folgende Listing zeigt eine mögliche Eingabe, zunächst dreimal mit
Fehler, anschließend richtig:
Eine positive Zahl: 0
Fehler
Eine positive Zahl: abc
Fehler
Fehler und Ausnahmen I 5.6

Eine positive Zahl: -6


Fehler
Eine positive Zahl: 6
Der Kehr wert von 6.0 ist 0.166666666667

Der Benutzer macht verschiedene Fehler:


~ Er gibt die Zahl 0 ein. Dies führt bei der Berechnung des Kehrwerts zu ZeroDivisionError

~
einem Laufzeitfehler, einem Ze ro Div i s i on Er ro r.
Er gibt einen Text ein. Dies führt beim Aufruf der Funktion fl oat()
zu einem Laufzeitfehler, einem Va 1 ue Er ro r.
ValueError I
~ Er gibt eine negative Zahl ein. Dies führt wegen der vorgenommenen Eigener Fehler
Einschränkung zu einem Laufzeitfehler.
Mithilfe der Anweisungen try, raise und except lassen sich also auch
nicht sinnvolle Eingaben des Anwenders abfangen und behandeln. Die
vorgeführte Methode hat den Nachteil, dass alle Fehler gleich behandelt
werden und die Informationen für den Anwender im Fehlerfall noch
nicht sehr genau sind. Dies soll im nächsten Abschnitt verbessert wer-
den.

5.6.6 Unterscheidung von Ausnahmen


Im folgenden Programm sollen verschiedene Arten von Fehlern spezi- Verschiedene
fisch abgefangen werden. Damit kann beispielsweise ein Benutzer über Ausnahmen

seinen Irrtum genauer informiert und eine komfortablere Programm-


bedienung ermöglicht werden.
Es soll wiederum der Kehrwert einer eingegebenen zahl ermittelt werden:
# Wiederholte Eingabe
fehler ~ True
while fehler:
try:
zahl ~ float(input("Eine positive Zahl: "))
i f zahl ~~ 0:
raise RuntimeError("Zahl gleich 0")
i f zahl< 0:
raise RuntimeError("Zahl zu klein")
kw ~ 1.0 / zahl
fehler ~ False
except ValueError:
pri nt(" Fehl er: kei ne Zahl")
except ZeroDivisionError:
print("Fehler: Zahl 0 eingegeben")

159
5 I Weiterführende Programmierung

except RuntimeError as e:
print("Fehler:", e)

lf Ausgabe
print( "Der Kehrwert von", zahl, "i st", kw)
Listing 5.17 Datei [Link]

Das Programm beinhaltet zu einem Versuch (Anweisung try) mehrere


spezifische Abfangmöglichkeiten (Anweisung except).
Nachfolgend wird eine mögliche Eingabe gezeigt - zunächst dreimal mit
Fehler, anschließend richtig:
Eine positive Zahl: 0
Fehl er: Zahl gl ei eh 0
Eine positive Zahl: abc
Fehl er: keine Zahl
Eine positive Zahl: -6
Fehl er: Zahl zu kl ei n
Eine positive Zahl: 6
Der Kehrwert von 6.0 ist 0.166666666667

Der Benutzer macht verschiedene Fehler:


Eigener Fehler ~ Er gibt die zahl 0 ein. Dies führt wegen der vorgenommenen Ein-
schränkung zu einem Laufzeitfehler. Dieser wird als allgemeiner Run-
timeErrorabgefangenmitderMeldungFehler: Zahl gleich O.
ZeroDivisionError ~ Würde die Eingabe von 0 nicht auf diese Weise abgefangen, käme es
später bei der Berechnung des Kehrwerts zu einem Laufzeitfehler,
einem ZeroDivisionError. Dieser würde abgefangen mit der Mel-
dung Fehler: Zahl 0 eingegeben. Zu Demonstrationszweckenwurde
der Fehler zweimal abgefangen, dies ist eigentlich nicht notwendig.
ValueError ~ Der Benutzer gibt einen Text ein. Dies führt beim Aufruf der Funktion
fl 0 a t () zu einem Laufzeitfehler, einem Val ue Er ro r. Dieser wird
abgefangen mit der Meldung Fehl er: kei ne Zahl.
Eigener Fehler ~ Er gibt eine negative Zahl ein. Dies führt wegen der zweiten vorge-
nommenen Einschränkung wiederum zu einem Laufzeitfehler. Dieser
wird auch als allgemeiner Runt i meE r ro r abgefangen mit der Meldung
Fehl er: Zahl zu kl ei n.
~ Beim Erzeugen des Fehlers mit der Anweisung ra i se werden ein Feh-
ler (Runt i meE r ro r) und eine Meldung übergeben.
as ~ Beim Abfangen dieses Fehlers mit der Anweisung except wird die
Meldung mithilfe von as an die Variable e übergeben.

160
Funktionen I 5·7

5.7 Funktionen

Python bietet zum Thema »Funktionen« noch elmge sehr nützliche


Erweiterungen, die in diesem Abschnitt erläutert werden.

5.7.1 Variable Anzahl von Parametern


In den bisherigen Beispielen wurde darauf geachtet, dass Reihenfolge
und Anzahl der Funktionsparameter bei Definition und Aufruf miteinan-
der übereinstimmen. Es können aber auch Funktionen mit einer variab-
len Anzahl von Parametern definiert werden.
I
Bei der Definition einer solchen Funktion muss vor dem letzten (gegebe- Parameter mit *
nenfalls einzigen) Parameter ein * (Stern) notiert werden. Dieser Parame-
ter beinhaltet ein Tupel mit den bis dahin nicht zugeordneten Werten
der Parameterkette.

Im folgenden Beispiel wird eine Funktion definiert, die in der Lage ist,
die Summe aller Parameter zu berechnen und auszugeben. Dies gilt
unabhängig von der Anzahl der zu summierenden Werte.
tf Funktion
def summe(*summanden):
print(len(summanden). "Zahlen")
print(summanden)
erg ~ 0
for s in summanden:
erg +~ s
print("Summe:". erg)

tf Aufrufe
summe(3. 4)
summe(3. 8. 12. -5)

Listing 5.18 Datei [Link]

Folgende Ausgabe wird erzeugt:


2 Zahlen
(3. 4)
Summe: 7
4 Zahlen
(3. 8. 12. -5)
Summe: 18
5 I Weiterführende Programmierung

Zur Erläuterung:

~ Die (nunmehr flexiblere) Funktion wird mit zwei oder mit vier Wer-
ten aufgerufen, die zu summieren sind.
~ Zu Demonstrationszwecken werden Größe und Inhalt des Tupels aus-
gegeben.
~ Die f 0 r-Schleife dient zur Summierung der Werte des Tupels. Die
Summe wird anschließend ausgegeben.

Benannte Parameter
Die definierte Reihenfolge der Parameter muss beim Aufruf nicht einge-
halten werden, falls Parameter mit ihrem Namen übergeben werden
(benannte Parameter).

Parameter mit Im folgenden Beispiel sind einige Varianten zum Aufruf der Funktion
Namen vol umen() dargestellt. Diese Funktion berechnet das Volumen eines
Quaders und gibt dieses aus. Außerdem wird die übergebene Farbe aus-
gegeben.

lf Funktion
def volumen(breite. laenge. tiefe. farbe):
print("Werte:". breite. laenge. tiefe. farbe)
erg ~ breite * laenge * tiefe
print("Volumen:". erg. "Farbe:". farbe)

lf Aufrufe
volumen(4. 6. 2. "rot")
volumen(laenge~2. farbe~"gelb". tiefe~7. breite~3)

volumen(5. tiefe~2. laenge~8. farbe~"blau")

lf Feh 1er
lf volumen(3. tiefe~4. laenge~5. "schwarz")

Listing 5.19 Datei [Link]

Die Ausgabe lautet:

Werte: 4 6 2 rot
Volumen: 48 Farbe: rot
Werte: 3 2 7 gelb
Volumen: 42 Farbe: gelb
Werte: 5 8 2 blau
Volumen: 80 Farbe: blau
Funktionen I 5·7

Zur Erläuterung:
~ Der erste Aufruf findet in der bekannten Form, ohne Benennung von
Parametern statt. Die Werte werden den Parametern in der übergebe-
nen Reihenfolge zugeordnet.
~ Beim zweiten Aufruf werden alle vier Parameter mit Namen überge- Reihenfolge
ben. Die Reihenfolge beim Aufruf ist nicht wichtig, da die Parameter unwichtig

~
eindeutig zugeordnet werden.
Beim dritten Aufruf wird der erste Parameter über seine Stellung in
der Parameterreihe zugeordnet, die anderen Parameter werden über
I
ihre Namen zugeordnet. Es sind also auch Mischformen möglich.
~ Sobald allerdings der erste benannte Parameter beim Aufruf Einmal benannt,
erscheint, müssen alle nachfolgenden Parameter auch benannt sein. immer benannt

Daher würde beim vierten Aufruf ein Fehler bereits in der Syntax
erkannt, obwohl die Zuordnung eigentlich eindeutig wäre.

5.7.3 Voreinstellung von Parametern


Durch die Voreinstellung von Parametern bei der Definition wird eine
variable Parameterzahl ermöglicht. Auch hier können benannte Parame-
ter eingesetzt werden. Dabei ist es wichtig, dass nicht-benannte Parame-
ter vor benannten Parametern stehen müssen.
Die Funktion zur Volumenberechnung des Quaders wurde in dieser Hin- Parameter mit
sicht geändert. Es müssen nur noch zwei Parameter angegeben werden. Standardwert

Die anderen beiden Parameter sind optional, es werden gegebenenfalls


Voreinstellungen verwendet.
lf Funktion
def volumen(breite. laenge. tiefe~l. farbe~"schwarz"):
print("Werte:". breite. laenge. tiefe. farbe)
erg ~ breite * laenge * tiefe
print("Volumen:". erg. "Farbe:". farbe)

lf Aufrufe
volumen(4. 6. 2. "rot")
volumen(2. 12. 7)
volumen(5. 8)
volumen(4. 7. farbe~"rot")

Listing 5.20 Datei [Link]


5 I Weiterführende Programmierung

Das Programm erzeugt die Ausgabe:


Werte: 4 6 2 rot
Volumen: 48 Farbe: rot
Werte: 2 12 7 schwarz
Volumen: 168 Farbe: schwarz
Werte: 5 8 1 schwarz
Volumen: 40 Farbe: schwarz
Werte: 4 7 1 rot
Volumen: 28 Farbe: rot

Zur Erläuterung:
~ Bei der Funktionsdefinition wurden die beiden Parameter tiefe und
fa r be voreingestellt. Sie sind optional und müssen am Ende der Para-
meterreihe stehen.
~ Beim ersten Aufruf werden alle vier Parameter gesendet.
~ Beim zweiten Aufruf wird nur einer der beiden optionalen Parameter
(t i efe) gesendet. Der zweite optionale Parameter erhält deshalb den
voreingestellten Wert (farbe ~ "schwarz").
~ Beim dritten Aufruf wird keiner der optionalen Parameter gesendet.
Daher erhalten beide den voreingestellten Wert.
~ Beim vierten Aufruf wird nur der letzte optionale Parameter gesendet.
Da dieser Parameter nicht mehr über die Reihenfolge zugeordnet wer-
den kann, muss er benannt werden.

5.7.4 Mehrere Rückgabewerte


Im Unterschied zu vielen anderen Programmiersprachen können Funkti-
onen in Python mehr als einen Rückgabewert liefern. Es kann zum Bei-
spiel ein Tupel oder eine Liste zurückgeliefert werden.

Ergebnis-Tupel Im folgenden Beispiel werden in der Funktion geom ( ) die Fläche und der
Umfang eines Rechtecks berechnet und als Tupel zurückgegeben.
import math

# Funktion. die zwei Werte berechnet


def kreis(radius):
flaeche ~ [Link] * radius * radius
umfang ~ 2 * [Link] * radius
return fl aeche. umfang
Funktionen I 5·7

Ir 1. Aufruf
f. u ~ kreis(3)
print("Flaeche:", f)
print("Umfang:", u)

Ir 2. Aufruf
x ~ kreis(3)

I
print("Flaeche:", x[O])
print("Umfang:", x[I])

Ir Feh 1er
Ir a, b, c ~ kreis(3)

Listing 5.21 Datei [Link]

Die Ausgabe lautet:


Flaeche: 28.2743338823
Umfang: 18.8495559215
Flaeche: 28.2743338823
Umfang: 18.8495559215

Zur Erläuterung:

~ Die Anweisung retu rn liefert ein Tupel mit den beiden Ergebnissen return <Tupel>
der Funktion. An der Aufrufstelle muss ein Tupel passender Größe
zum Empfang bereitstehen.
~ Im ersten Fall wird das Tupel zwei einzelnen Variablen zugeordnet.
~ Im zweiten Fall wird das Tupel einer Variablen zugeordnet, die damit
zum Tupel wird.
~ Der letzte Aufruf würde zu einem Laufzeitfehler führen, da die Größe
des zurückgelieferten Tupels nicht passt.

5.7.5 Übergabe von I<opien und Referenzen


Werden Parameter, die an eine Funktion übergeben werden, innerhalb
der Funktion verändert, so wirkt sich dies im aufrufenden Programmteil
unterschiedlich aus:
~ Bei der Übergabe eines einfachen Objekts (Zahl oder Zeichenkette) Kopie übergeben
wird eine Kopie des Objekts angelegt. Eine Veränderung der Kopie
hat keine Auswirkungen auf das Original.
5 I Weiterführende Programmierung

Referenz ~ Bei der Übergabe eines Objekts vom Typ Liste, Dictional}' oder Set
übergeben wird mit einer Referenz auf das Originalobjekt gearbeitet. Eine Ver-
änderung über die Referenz verändert auch das Original.
Vorher, nachher Zur Verdeutlichung dieses Zusammenhangs werden im folgenden Bei-
spiel insgesamt fünf Parameter an eine Funktion übergeben: eine Zahl.
eine Zeichenkette, eine Liste, ein Dictional}' und ein Set. Die Objekte
werden jeweils dreimal ausgegeben:
~ vor dem Aufruf der Funktion
~ nach einer Veränderung innerhalb der Funktion
~ nach der Rückkehr aus der Funktion
lfFunktion
def chg(v. zk. li. di. st):
v ~ 8
zk ~ "ciao"
lHG] ~ 7
di["x"] ~ 7
[Link](3)

# lokale Ausgabe
print("In Funktion:")
print(v. zk)
print(li. di. st)

lf Sta rtwerte
hv ~ 3

hli [3."abc"]
hzk "hallo"
hdi {"x":3. "y":"abc"}
hst set([3. "abc"])

# Ausgabe vorher
print( "vorher:")
print(hv. hzk)
print(hli. hdi. hst)

# Aufruf der Funktion


chg(hv. hzk. hli. hdi. hst)

# Ausgabe nachher
print( "nachher:")
print(hv. hzk)
print(hli. hdi. hst)

Listing 5.22 Datei [Link]

166
Funktionen I 5·7

Die Ausgabe lautet:


v orher:
3 hallo
[3, 'abc'] {'y': 'abc', 'x': 3) {3, 'abc')
In Funktion:
8 ciao
[7, 'abc'] {'y': 'abc', 'x': 7} {'abc')
nachher:
3 hallo
[7, 'abc'] {'y': 'abc', 'x': 7} {'abc')
I
Zur Erläuterung:
~ Es zeigt sich, dass nur bei Liste, Dictionary und Set eine dauerhafte (Un)erwünschter
Veränderung durch die Funktion durchgeführt wurde. Dies kann je Effekt

nach Problemstellung ein erwünschter oder ein unerwünschter Effekt


sein.

Ist die dauerhafte Veränderung von einfachen Objekten durch eine


Funktion erwünscht, so kann man die Tatsache ausnutzen, dass Python-
Funktionen mehr als einen Rückgabewert haben können.

Im folgenden Beispiel dient eine Funktion zum Sortieren von zwei Vari-
ablen. Die beiden Variablen werden als Tupel zurückgeliefert:
# Sortierfunktion
def sortieren(eins, zwei):
if eins< z wei:
return zwei, ei ns
else:
return eins, zwei

i! Bei spi el
x ~ 24
y ~ 29
x, y ~ sortieren(x, y)
print( "x ~", x, "y ~", y)

i! Bei spi el 2
x ~ 124
y ~ 29
x, y ~ sortieren(x, y)
print( "x ~", x, "y ~", y)

Listing 5.23 Datei [Link]


5 I Weiterführende Programmierung

Zur Erläuterung:
~ Es werden zwei Variablen an die Funktion übergeben. Innerhalb der
Funktion wird überprüft, ob die zweite Variable größer als die erste
Variable ist.
~ Trifft dies zu, so werden beide Variablen in umgekehrter Reihenfolge
an die aufrufende Stelle zurückgeliefert.
~ Falls nicht, stehen die beiden Variablen bereits in der gewünschten
Reihenfolge und werden unverändert an die aufrufende Stelle zurück-
geliefert.

5.7.6 Lokal. global


Lokal Die Definition einer Funktion in Python erzeugt einen lokalen Namens-
raum. In diesem lokalen Namensraum stehen alle Namen der Variablen,
denen innerhalb der Funktion ein Wert zugewiesen wird, und die
Namen der Variablen aus der Parameterliste.

Global Wird bei der Ausführung der Funktion auf eine Variable zugegriffen, so
wird diese Variable zunächst im lokalen Namensraum gesucht. Wird der
Name der Variablen im lokalen Namensraum nicht gefunden, so wird im
globalen Namensraum gesucht, also in den bisher bearbeiteten Pro-
grammzeilen außerhalb der Funktion. Sollte die Variable im globalen
Namensraum nicht gefunden werden, so tritt ein Fehler auf.
Ein Beispiel:
lfTestfunktion
def fune():
print(x)

lfHauptprogramm
try:
fune( )
exeept:
print("Fehler")
x ~ 42
fune( )

Listing 5.24 Datei [Link]

Die Ausgabe lautet:


Fehler
42

168
Funktionen I 5·7

Zur Erläuterung:
~ Der erste Aufrufvon func ( ) führt zu einem Fehler, da in der Funktion Variable noch
der Wert von x ausgegeben werden soll. x ist nicht im lokalen unbekannt

Namensraum vorhanden, aber auch nicht in den bisher bearbeiteten


Programmzeilen außerhalb der Funktion.
~ Der zweite Aufrufvon func( ) führt zu keinem Fehler, denn x hat vor- Variable global
her außerhalb der Funktion einen Wert erhalten und ist somit im glo-
balen Namensraum bekannt.
bekannt

I
5.7.7 Lambda-Funktion
Die Lambda-Funktion bietet die Möglichkeit, eine Funktionsdefinition zu Kürzere
verkürzen. Einer solchen Funktion können Parameter übergeben werden. Schreibweise

Sie liefert ihr Ergebnis als einen Ausdruck zurück, der in der gleichen Zeile
stehen muss. In diesem Ausdruck dürfen keine Mehrfachanweisungen,
Ausgaben oder Schleifen vorkommen. Ein Beispielprogramm sieht wie
folgt aus:
# Funktionsdefinitionen
mal ~ lambda x,y: x*y
plus ~ lambda x,y: x+y

# Funktionsaufrufe
print mal (5,3)
print plus(4,7)

Listing 5.25 Datei [Link]

Es wird die Ausgabe erzeugt:


15
11

Zur Erläuterung:
~ Es wird die Funktion ma 1 definiert. Diese hat zwei Parameter (hier x
und y). Das Ergebnis der Funktion ist die Multiplikation dieser beiden
Parameter.
~ Die Lambda-Funktion plus ist analog nach folgendem Muster aufge-
baut: Ergebni s ~ 1 ambda Pa rameterl i ste: Ausdruck.

169
5 I Weiterführende Programmierung

5.8 Eingebaute Funktionen

Als Entwickler können Sie eine Reihe von eingebauten Funktionen ohne
Einbindung eines Moduls verwenden.

5·8.1 Übersicht
Die folgende Tabelle gibt eine Übersicht über die eingebauten Funktio-
nen, die in diesem Buch behandelt werden:

Die Funktion ...

abs ( ) liefert den Betrag einer Zahl siehe 4.1.6


bi n ( ) liefert eine binäre beziehungsweise duale Zahl siehe 4.1.1
eh r ( ) liefert ein Zeichen zu einer Unicode-Zahl siehe 5.8.3
eva 1 ( ) liefert einen ausgeführten Python-Ausdruck siehe 5.1.5
exee ( ) führt eine Anweisung aus siehe 5.1.5
fi 1 ter( ) liefert die Elemente eines iterierbaren Objekts, siehe 5.4.3
für die eine Funktion True ergibt
fl oat() liefert eine Zahl mit Nachkommastellen siehe 3.2.3
format( ) formatiert Zahlen und Zeichenketten siehe 5.2.2
frozenset( ) liefert ein unveränderliches Set siehe 4.6.4
hex ( ) liefert eine hexadezimale Zahl siehe 4.1.1
input ( ) wartet auf eine Eingabe des Benutzers siehe 3.2.2
i nt ( ) liefert eine ganze Zahl siehe 3.2.3
1 en ( ) liefert die Anzahl der Elemente siehe 4.2.3
map ( ) liefert Funktionsergebnisse zu einer Reihe von siehe 5.4.2
Aufrufen
max ( ) liefert das größte Element siehe 5.8.2
mi n ( ) liefert das kleinste Element siehe 5.8.2
oet ( ) liefert eine oktale Zahl siehe 4.1.1
open ( ) öffnet eine Datei zum Lesen oder Schreiben siehe 9.2
o rd ( ) liefert die Unicode-Zahl zu einem Zeichen siehe 5.8.3
pri nt ( ) erzeugt eine Ausgabe siehe 5.2.1
range( ) liefert ein iterierbares Objekt über einen Bereich siehe 3.4.5
reversed( ) liefert ein iterierbares Objekt in umgekehrter siehe 5.8.4
Reihenfolge
round( ) liefert eine gerundete Zahl siehe 4.1.4

Tabelle 5.1 Einige eingebaute Funktionen

170
Eingebaute Funktionen I 5.8

Die Funktion ...

set( ) liefert ein Set siehe 4.6


sorted( ) liefert eine sortierte Liste siehe 5.8.4
st r ( ) liefert eine Zeichen kette siehe 4.2.6
s um( ) liefert die Summe der Elemente siehe 5.8.2
type ( )
zi p( )

Tabelle 5.1
liefert den Typ eines Objekts
verbindet Elemente aus iterierbaren Objekten

Einige eingebaute Funktionen (Forts.)


siehe 4.1.5
siehe 5.4.1 I
5.8.2 Funktionen maxO, minO und sumO
Die Funktionen max() und min() liefern den größten und den kleinsten
Wert, falls nur ein iterierbares Objekt angegeben ist. Falls dagegen meh-
rere iterierbare Objekte angegeben sind, liefern sie das Objekt mit der
größten oder der kleinsten Summe. Die Funktion s um () liefert die
Summe der Elemente des iterierbaren Objekts.

Ein Beispiel:
t1 ~ (3, 12, 9)
print("t1:", t1)
print("Max. Wert:", max(t1»
print("Min. Wert:", min(t1»
print("Summe:", sum(t1»
pr i nt ( )

t2 ~ (1. 0, 13, 1. 2)
print("t2:", t2)
print("Max. Summe:", max(t1,t2»
print("Min. Summe:", min(tl,t2»

Listing 5.26 Datei [Link]

Die Ausgabe lautet:


t1: (3, 12, 9)
Max. Wert: 12
Min. Wert: 3
Summe: 24

t2: (1. 0, 13, 1. 2)


Max. Summe: (3, 12, 9)
Min. Summe: (1. 0, 13, 1. 2)

171
5 I Weiterführende Programmierung

Zur Erläuterung:
Ein Parameter ~ Der größte und der kleinste Wert des Tupels t1 werden ausgegeben.
Anschließend wird die Summe der Werte ausgegeben.
Mehr als ein ~ Beim zweiten Aufruf der Funktionen ma x ( ) und mi n ( ) ist mehr als ein
Parameter Parameter angegeben. Dies bedeutet, dass das Tupel mit der größten
oder der kleinsten Summe der Werte ermittelt und ausgegeben wird.

5.8.3 Funktionen ehr() und ord()


Unicode-Zahl Die Funktion ch r () liefert das zugehörige Zeichen zu einer Unicode-
zahl. Umgekehrt erhält man mithilfe der Funktion 0 rd () die Unicode-
Zahl zu einem Zeichen. Ein Beispiel:
lf Zi ffern
for i in range(48,58):
print(chr(i), end~"")
pr i nt ( )

# grosse Buchstaben
for i in range(65,91):
print(chr(i), end~"")
pr i nt ( )

# kleine Buchstaben
for i in range(97,123):
print(chr(i), end~"")
pr i nt ( )

lf Codenummern
for z in "Robinson":
print(ord(z), end~" ")
pr i nt ( )

lf Verschoben
for z in "Robinson":
print(chr(ord(z)+l), end~"")

Listing 5.27 Datei [Link]

Es wird die Ausgabe erzeugt:


0123456789
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
82 111 98 105 110 115 111 110
Spcjotpo

172
Eingebaute Funktionen I 5.8

Zur Erläuterung:
~ Die Unicode-Zahlen von 48 bis 57 verweisen auf die Ziffern 0 bis 9. Ziffern,
Mithilfe der Unicode-Zahlen von 65 bis 90 beziehungsweise von 97 Buchstaben

bis 122 erhält man die großen und die kleinen Buchstaben.
~ Eine Zeichenkette ist ein iterierbares Objekt, daher können die einzel-
nen Elemente (sprich: Zeichen) in einer f 0 r-Schleife durchlaufen wer-

~
den. Für jedes Zeichen der Zeichenkette wird die zugehörige Unicode-
zahl ausgegeben.
Im letzten Teil des Programms wird jedes Zeichen einer Zeichenkette Verschlüsselung
I
in das codemäßig nachfolgende Zeichen umgewandelt. Die Zeichen-
kette wird verschlüsselt. Dazu werden beide Funktionen eingesetzt.

5.8.4 Funktionen reversed() und sorted()


Die Funktion reve r sed () liefert ein iterierbares Objekt in umgekehrter Umdrehen,
Reihenfolge. Mithilfe der Funktion so rted () wird eine sortierte Liste sortieren

erstellt. Ein Beispiel:


lf Originale
z ~ "Robinson"
print(z)
t ~ [4. 12. 6. -2J
print(t)

lf Umged reht
r ~ reversed(z)
forxinr:
print(x. end~"")
pr i nt ( )

# Sortierte Listen
sI ~ sorted(z)
print(sl)
s2 ~ sorted(t)
print(s2)
Listing 5.28 Datei [Link]

Die Ausgabe lautet:


Robinson
[4. 12. 6. -2J
nosniboR

173
5 I Weiterführende Programmierung

['R', 'b', 'i', 'n', 'n', '0', '0', 's'J


[-2, 4, 6, 12J

Zur Erläuterung:

Umdrehen ~ Die Funktion reversed() liefert einen Iterator, der die Elemente in
umgekehrter Reihenfolge enthält. Die Elemente können zum Beispiel
mithilfe einer f 0 r-Schleife ausgegeben werden.
Sortieren ~ Mithilfe der Funktion sorted() wird eine Liste erstellt, die die Ele-
mente einer gegebenen Sequenz in sortierter Reihenfolge enthält. Bei
Zahlen ist die Sortierung aufsteigend nach Wert, bei Zeichen aufstei-
gend nach codezahl.

5.9 Eigene Module

In den bisherigen Beispielen wurden die Funktion und das eigentliche


Hauptprogramm in der gleichen Datei definiert. Bei spezifischen Funkti-
onen, die auf ein bestimmtes Programm zugeschnitten wurden, ist dies
auch sinnvoll.

Gemeinsame Allerdings werden Sie bald feststellen, dass einige nützliche Funktionen
Nutzung immer wieder und von verschiedenen Programmen aus benötigt wer-
den. Diese Funktionen sollten in eigenen Modulen gespeichert werden.
Die Erstellung und Nutzung von Modulen ist in Python sehr einfach und
wird in diesem Abschnitt erläutert.

Externe Funktion 5.9.1 Eigene Module erzeugen


Zur Erzeugung eines Moduls wird die gewünschte Funktion einfach in
einer eigenen Datei gespeichert. Der Name der Datei ist gleichzeitig der
Name des Moduls. Die Funktion wird wie gewohnt erstellt:
def quadrat(x):
erg ~ x * x
return erg
Listing 5.29 Datei [Link]

Anschließend kann die Funktion in jedem Programm genutzt werden,


vorausgesetzt, sie wird aus dem betreffenden Modul importiert. Die
Importmöglichkeiten werden im nächsten Abschnitt erläutert.

174
Eigene Module I 5·9

5.9.2 Eigene Module verwenden


Eine Funktion in einem eigenen Modul kann auf mehrere Arten genutzt
werden. Das Modul wird zunächst wie gewohnt importiert:
import p0529
z ~ [Link](3)
print(z)

Listing 5.30

Zur Erläuterung:
Datei [Link]
I
~ Alle Funktionen des Moduls p0529, also der Datei [Link], werden import
mithilfe der Anweisung i mpo rt zugänglich gemacht.
~ Die Funktion quadrat() wird in der Schreibweise Modul name. Funk-
ti ons name aufgerufen.

Es folgt der Import mithilfe der Anweisung from:


from p0529 import quadrat
z ~ quadrat(3)
print(z)

Listing 5.31 Datei [Link]

Zur Erläuterung:
~ Mit from p0529 import quadrat wird die Funktion quadrat() aus fram ... import
dem Modul p0529 importiert.
~ Die Funktion quadrat() wird dann ohne den Modulnamen aufgeru-
fen, so als ob sie in der gleichen Datei definiert worden wäre.
Hinweise Empfehlung
1. Falls noch weitere Funktionen im Modul p0529 stehen, die alle importiert
werden sollen, so kann man auch die Anweisung from p0529 import *
nutzen.
2. Die Schreibweise from Modulname import ... hat allerdings Nachteile,
falls man mehrere Funktionen mit gleichem Namen aus unterschiedlichen
Modulen importieren möchte.
3. Auch aus diesem Grund ist die gewohnte Schreibweise mit i mpo rt
Modul name (wie in Datei p0530py) sehr zu empfehlen.
4. Es wird in den Beispielen in den beiden Dateien [Link] und p0531py
davon ausgegangen, dass sich die Datei [Link] im gleichen Verzeichnis
befindet.

175
5 I Weiterführende Programmierung

Übung U0502
Schreiben Sie das Programm aus Übung U0311 um: Die Funktion steuer()
soll in die Datei [Link] ausgelagert werden. Das Hauptprogramm in
Datei [Link] soll die Funktion aus dieser Datei importieren und nutzen.

5.10 Parameter der I<ommandozeile

Ein Python-Programm kann bekanntlich von der Kommandozeile des


Betriebssystems aus aufgerufen werden. In Abschnitt 2.3.2, »Ausführen
unter Windows«, wurde beschrieben, wie man zur Kommandozeile
gelangt.

[Link] Der Aufruf ähnelt dem Aufruf einer Funktion mit Parametern. Die einzel-
nen Parameter werden durch Leerzeichen voneinander getrennt. Sie ste-
hen innerhalb des Programms in der Liste sys . a rg v zur Verfügung. Die
Anzahl der Parameter könnte mithilfe der eingebauten Funktion 1 en ( )
(= Länge der Liste) ermittelt werden.

5.10.1 Übergabe von Zeichenketten


Dem folgenden Programm wird ein einzelnes Wort als Parameter über-
geben. Anschließend werden Elemente der Liste sys. a rgv ausgegeben:
import sys
print "Programmname:", [Link][OJ
print "Erster Parameter:", [Link][lJ

Listing 5.32 Datei [Link]

Wird das Programm von der Kommandozeile aus in folgender Form auf-
gerufen:
python [Link] hallo

so lautet die Ausgabe:


Programmname: [Link]
Erster Parameter: hallo

Zur Erläuterung
~ Das erste Element der Liste ist der Name des Programms.
~ Die weiteren Elemente sind die einzelnen Parameter.
Parameter der Kommandozeile I 5.10

5.10.2 Übergabe von Zahlen


Mit dem folgenden Programm sollen zwei Zahlen addiert werden, die Parameter
dem Programm als Kommandozeilenparameter übergeben werden. Dazu verrechnen

müssen die beiden Parameter mithilfe der Funktion f 1 0 a t () in Zahlen


umgewandelt und eventuell auftretende Ausnahmen abgefangen wer-
den.
import sys

try:
x float([Link][1])
I
y float([Link][2])
z x + y
print("Ergebnis:", z)
except:
print("Parameterfehler")

Listing 5.33 Datei [Link]

Wird das Programm vom Betriebssystem aus wie folgt aufgerufen:


python [Link] 3 6.2

so lautet die Ausgabe:


Ergebnis: 9.2

5.10.3 Beliebige Anzahl von Parametern


Das folgende Programm soll dazu dienen, eine beliebige Menge von zah- Liste der
len zu addieren, die dem Programm als Kommandozeilenparameter Parameter

übergeben werden.
import sys
summe ~ 0

try:
for i in [Link][1:]:
summe +~ float(i)
print("Ergebnis:", summe)
except:
print("Parameterfehler")

Listing 5.34 Datei [Link]

177
5 I Weiterführende Programmierung

Wird das Programm vom Betriebssystem aus wie folgt aufgerufen:


python [Link] 3 6.2 5

so lautet die Ausgabe:


Ergebnis: 14.2
Zur Erläuterung:

Slice ~ Bei sys . a rgv handelt es sich um eine Liste. Das erste Element (der
Name des Programms) muss dabei ausgespart werden, daher die slice-
Operation.
~ Innerhalb der fo r-Schleife werden die einzelnen Parameter umge-
wandelt und zur Gesamtsumme hinzuaddiert.
6 Objel<torientierte Programmierung

Dieses Kapitel bietet eine Einführung in die objektorientierte Program-


mierung. Es erläutert die Möglichkeiten zur Erzeugung einer Klassenhie-
rarchie, mit der Sie große Softwareprojekte anhand von Klassen, Objek-
ten, Eigenschaften, Methoden und dem Prinzip der Vererbung bearbeiten
können. I
6.1 Was ist OOP?

Die objektorientierte Programmierung (OOP) bietet zusätzliche Möglich-


keiten zum verbesserten Aufbau und zur vereinfachten Wartung und
Erweiterung von Programmen. Diese Vorteile erschließen sich besonders
bei großen Programmierprojekten.

Bei der objektorientierten Programmierung werden Klassen erzeugt, in Klasse


denen die Eigenschaften von Objekten sowie die Funktionen festgelegt
werden, die auf diese Objekte angewendet werden können (sogenannte
Methoden). Sie können viele verschiedene Objekte dieser Klassen erzeu-
gen, den Eigenschaften unterschiedliche Werte zuweisen und die Metho-
den anwenden. Die Definitionen aus der Klasse und die zugewiesenen
Werte begleiten diese Objekte über ihren gesamten Lebensweg während
der Dauer des Programms.
Ein Beispiel: Es wird die Klasse Fa h r zeug erschaffen, in der Eigenschaf-
ten und Methoden von verschiedenen Fahrzeugen bestimmt werden
können. Ein Fahrzeug hat unter anderem die Eigenschaften Bezei ch-
nung, Geschwindigkeit und Fahrtrichtung. Außerdem kann man ein
Fahrzeug beschl eunigen und 1 enken. Innerhalb des Programms können
viele unterschiedliche Fahrzeuge erschaffen und eingesetzt werden

Klassen können ihre Eigenschaften und Methoden außerdem vererben. Vererbung


Sie fungieren dann als Basisklasse, ihre Erben nennt man abgeleitete
Klassen. Dadurch kann die Definition von ähnlichen Objekten, die über
eine Reihe von gemeinsamen Eigenschaften und Methoden verfügen,
vereinfacht werden.

179
6 I Objektorientierte Programmierung

Ein Beispiel: Es werden die Klassen PKW und LKW geschaffen. Beide Klas-
sen sind von der Basisklasse Fahrzeug abgeleitet und erben alle Eigen-
schaften und Methoden dieser Klasse. Zusätzlich verfügen sie über
eigene Eigenschaften und Methoden, die bei der jeweiligen Klasse
besonders wichtig sind. Ein PKW hat etwa eine bestimmte Anzahl von
Insassen, und man kann einsteigen und aussteigen. Ein LKW hat eine
Ladung, man kann ihn bel aden und entl aden.

6.2 1<lassen, Objekte und eigene Methoden

Eigenschaft, Als Beispiel wird die Klasse Fahrzeug definiert. Zunächst verfügt ein
Methode Objekt dieser Klasse nur über die Eigenschaft Ges chwi nd i gkeit und die
Methoden beschl euni gen() und ausgabe(). Die Methode ausgabe()
soll dazu dienen, den Anwender über den aktuellen Zustand des jeweili-
gen Fahrzeugs zu informieren.

Klassendefinition Die Definition der Klasse sieht wie folgt aus:


# Definition der Klasse Fahrzeug
class Fahrzeug:
geschwindigkeit ~ 0 lf Ei genschaft
def beschleunigen(self, wert): lf Methode
[Link] +~ wert
def ausgabe(self): lf Methode
print "Geschwindigkeit:", [Link]

Listing 6.1 Datei [Link] (Klassendefinition)

Zur Erläuterung:

dass ~ Die Definition der Klasse wird eingeleitet vom schlüsselwort cl ass,
gefolgt vom Namen der Klasse und einem Doppelpunkt. Eingerückt
folgt die eigentliche Definition.
~ Die Eigenschaft ge sc h wi nd i g k ei t wird definiert und auf den Wert 0
gesetzt.
def ~ Die Methoden sind Funktionen der Klasse, sie werden also mithilfe
des schlüsselworts def definiert. Methoden haben immer mindestens
einen Parameter, dies ist das Objekt selbst. Häufig wird dieser Para-
meter se 1 f genannt - Sie können aber auch einen anderen Namen
wählen.

180
Klassen, Objekte und eigene Methoden I 6.2

~ Die Methode bes ch 1 eun i gen () hat insgesamt zwei Parameter: Der self
erste Parameter ist das Objekt selbst: Es wird mit se 1f bezeichnet. Der
zweite Parameter ist der Wert für die Änderung der Geschwindigkeit.
Innerhalb der Methode wird dieser Wert genutzt, um die Eigenschaft
des Objekts zu ändern.
~ Die Methode ausgabe() hat nur einen Parameter: das Objekt selbst.
Sie dient zur Ausgabe der Geschwindigkeit des Objektes.

Bisher beinhaltete das Programm nur eine Klassendefinition, es führte Hauptprogramm

I
noch nichts aus. Das Hauptprogramm hat folgendes Aussehen:
# Objekte der Klasse Fahrzeug erzeugen
opel ~ Fahrzeug()
volvo ~ Fahrzeug()

# Objektmethoden
[Link]()
[Link](20)
[Link]()

# Objekt betrachten
opel . ausgabe()

Listing 6.2 Datei [Link] (Hauptprogramm)

Das Programm erzeugt die Ausgabe:


Geschwindigkeit: 0
Geschwindigkeit: 20
Geschwindigkeit: 0

Zur Erläuterung:

~ Nach der bereits beschriebenen Klassendefinition werden zunächst Objekt erzeugen


zwei Objekte der Klasse Fahrzeug erzeugt, hier mit den Namen opel
und volvo (opel~Fahrzeug(), volvo~Fahrzeug(». Diesen Vorgang
nennt man auch: Instanzen einer Klasse erzeugen.
~ Beim anschließenden Aufruf der Methoden (hier beschleunigen() Methode für
und aus gabe ( » ist zu beachten, dass das Objekt selbst nicht als Para- Objekt ausführen
meter angegeben wird. Eine Methode bekommt also beim Aufruf
immer einen Parameter weniger übermittelt, als in der Definition
angegeben ist. Dies liegt daran, dass die Methode für ein bestimmtes
Objekt aufgerufen wird. Innerhalb der Methode ist daher bekannt,
um welches Objekt es sich handelt.
6 I Objektorientierte Programmierung

~ Die Geschwindigkeit des Objekts vo 1 vo wird ausgegeben, einmal vor


und einmal nach der Beschleunigung. Die Geschwindigkeit des
Objekts ope 1 wird nur einmal ausgegeben. Zu Beginn, also nach ihrer
Erzeugung, haben die Objekte die Geschwindigkeit 0, wie in der Defi-
nition angegeben.

Hinweis
Die in diesem Kapitel dargestellten Programme sind ein Kompromiss, denn die
Vorteile der objektorientierten Programmierung (OOP) kommen erst bei grö-
ßeren Programmierprojekten zum Tragen. Bei einem kleineren Problem fragt
man sich vielleicht, warum man für dieses einfache Ergebnis ein verhältnismä-
ßig komplexes Programm schreiben sollte. Anhand der hier vorgestellten Pro-
gramme können Sie sich aber die Prinzipien der OOP erschließen, ohne den
Überblick zu verlieren.

6.3 I<onstruktor und Destruktor

Es gibt zwei besondere Methoden, die im Zusammenhang mit einer


Klasse definiert werden können:

Konstruktor ~ Die Konstruktormethode wird genutzt, um einem Objekt zu Beginn


seiner Lebensdauer Anfangswerte zuzuweisen.
Destruktor ~ Die Destruktormethode wird genutzt, um am Ende der Lebensdauer
eines Objekts Aktionen auszulösen.

Die Klasse Fa h r zeug wird wie folgt verändert:


~ Ein Fahrzeug erhält neben der Eigenschaft geschwindigkeit die
Eigenschaft bezei chnung.
~ Die Klasse erhält eine Konstruktormethode zur Festlegung von
Anfangswerten für bezei chnung und ges ch wi nd i gkeit.

Das Programm sieht in seiner veränderten Form wie folgt aus:


# Definition der Klasse Fahrzeug
class Fahrzeug:
def __ init __ (self. bez. gel: # Konstruktormethode
[Link] ~ bez
[Link] ~ ge
def beschleunigen(self. wert):
[Link] +~ wert
[Link]()
Konstruktor und Destruktor I 6.3

def ausgabe(self):
print([Link], [Link], "km/hO)

# Objekte der Klasse Fahrzeug erzeugen


opel ~ Fahrzeug( "Opel Admi ral", 40)
vol vo ~ Fahrzeug("Vol vo Amazon", 45)

# Objekte betrachten
opel . ausgabe()
vol [Link]()

i! Objektmethode
[Link](20)

Listing 6.3 Datei [Link]


I
Die Ausgabe des Programms lautet:
Opel Admi ral 40 km/h
Volvo Amazon 45 km/h
Vol vo Amazon 65 km/h

Zur Erläuterung:

~ Der festgelegte Name __ init_() (mit doppeltem Unterstrich davor _init_O


und danach) bezeichnet die Konstruktormethode. Es werden zwei
Parameter übergeben. Diese beiden Parameter werden genutzt, um
die beiden Eigenschaften mit Anfangswerten zu versorgen.
~ Die Methode ausgabe() dient zur Ausgabe beider Eigenschaften. Sie self
wird in diesem Programm sowohl aus dem Hauptprogramm als auch
aus einer Objektmethode heraus aufgerufen. Im zweiten Fall muss,
wie bei der Zuweisung eines Eigenschaftswerts, das Objekt mit sel f
angegeben werden.
~ Es werden zwei Objekte erzeugt. Dabei werden die Anfangswerte an
den Konstruktor übergeben, hier die Werte »Opel Admiral« und 40
für das Objekt opel, für das Objekt vol vo die Werte »Volvo Amazon«
und 45.
~ Anschließend werden die Eigenschaften der Objekte verändert und
ausgegeben.

Hinweise
1. Konstruktoren werden häufig eingesetzt. Sie ermöglichen eine gezieltere
Erzeugung von Objekten.
6 I Objektorientierte Programmierung

2. Destruktoren werden selten genutzt. Sie kommen zum Einsatz, falls bei der
Löschung eines Objekts weitere Arbeiten durchgeführt werden sollen, wie
zum Beispiel das Schließen einer Datei. Destruktoren werden mit der
Methode del () definiert.

6.4 Besondere Methoden

Die Methoden _ in i t _ () und _de 1_ () gehören zu einer Reihe von


besonderen Methoden, die für die eingebauten Objekttypen bereits vor-
definiert sind.

Sie können für eigene Objekttypen, also Klassen, selber definiert wer-
den. Im folgenden Beispiel wird eine dieser Methoden zur Ausgabe eines
Objekts genutzt:
# Definition der Klasse Fahrzeug
class Fahrzeug:
def _init_(self, bez, gel: # Konstruktormethode
[Link] ~ bez
[Link] ~ ge
def str (self): # Ausgabemethode
return [Link] + \
+ str([Link]) + " km/ho

# Objekte der Klasse Fahrzeug erzeugen


opel ~ Fahrzeug( "Opel Admi ral", 40)
volvo ~ Fahrzeug("Volvo Amazon", 45)

# Objekte ausgeben
print(opel)
print(volvo)

Listing 6.4 Datei [Link]

Die Ausgabe des Programms lautet:


Opel Admi ral 40 km/h
Volvo Amazon 45 km/h

Zur Erläuterung:

_str_{) ~ Bei der Ausgabe eines Objekts mithilfe der Funktion pri nt() wird die
besondere Methode _s t r _ ( ) aufgerufen, falls sie definiert ist. Diese
liefert eine Zeichenkette zur Ausgabe der Eigenschaften. Ist die
Operatormethoden I 6.5

Methode für die betreffende Klasse nicht definiert, so ergibt sich


keine sinnvoll nutzbare Ausgabe.

6.5 Operatormethoden

Ähnlich wie die besonderen Methoden sind die Operatormethoden für


die eingebauten Objekttypen bereits vordefiniert.
Auch die Operatormethoden können für eigene Objekttypen, also Klas-
sen, selber definiert werden. Im folgenden Beispiel werden insgesamt
drei dieser Methoden zum Vergleich zweier Objekte und zur Subtraktion
zweier Objekte genutzt:
I
# Definition der Klasse Fahrzeug
class Fahrzeug:
def __ init __ (self, bez, gel: # Konstruktormethode
[Link] ~ bez
[Link] ~ ge
def __ gt __ (self, other): i! 1. Vergleichsmethode
return [Link] > [Link]
def __ eq __ (self, other): i! 2. Vergleichsmethode
return [Link] ~~ [Link]
def sub (self,other): i! Rechenmethode
return [Link] [Link]

# Objekte der Klasse Fahrzeug erzeugen


opel ~ Fahrzeug( "Opel Admi ral", 60)
volvo ~ Fahrzeug("Volvo Amazon", 45)

# Objekte vergleichen
if opel > vol vo:
print("Opel ist schneller")
e 1 if ope 1 ~~ vo 1 vo :
print("Beide sind gleich schnell")
else:
print("Volvo ist schneller")

# Objekte subtrahieren
differenz ~ opel volvo
print("Geschwindigkeitsdifferenz:", differenz, "km/h")

Listing 6.5 Datei [Link]


6 I Objektorientierte Programmierung

Die Ausgabe des Programms:


Opel ist schnell er
Gesch windigkeitsdifferenz: 15 km/h

Zur Erläuterung:

Objekte ~ Die Methoden __ gt_() und __ eq_() werden beim Objektvergleich


vergleichen durch die Benutzung der Vergleichsoperatoren > und ~~ aufgerufen.
~ Die Methode __ gt_() liefert True, falls das Objekt sel f größer als
das Objekt other ist. Für diese Klasse wird definiert: Größer
bedeutet höhere Geschwindigkeit.
~ Die Methode __ eq_( ) liefert True, falls die beiden Objekte gleich
groß, also gleich schnell sind.
~ Die Methode _sub __ ( ) wird bei der Verwendung des Operators
(Minus) aufgerufen. Zur Ausgabe eines sinnvollen Ergebnisses sollte
sie die Differenz der Geschwindigkeiten der beiden Objekte zurück-
liefern. Sie wird im vorliegenden Programm bei der Berechnung d i f -
ferenz ~ opel - vol vo genutzt.

Vergleichs- Neben den Operatoren> (greater than) und ~~ (equal) können noch wei-
operatoren tere Vergleichsoperatoren zu Funktionsaufrufen führen:

~ >~ führt zu _ge __ (), greater equal


~ < führt zu _1 t_ ( ), lower than
~ <~führtzu_le __ (), lowerequal
~ !~ führt zu _ne __ (), not equal

Rechenoperatoren Neben dem Operator - (Minus) können noch viele weitere Rechenopera-
toren zu Funktionsaufrufen führen, unter anderem:
~ + führt zu add ( )

~ * führt zu mul ( )

~ / führt zu truediv ( )

~ / / führt zu floordi v ( )

~ %führt zu mod ( )

~ ** führt zu _po w_( )

186
Referenz, Identität und Kopie I 6.6

6.6 Referenz, Identität und I<opie

Wie bereits erwähnt, ist der Name eines Objekts lediglich eine Referenz Zweite Referenz
auf das Objekt. Bei Objekten von benutzerdefinierten Klassen erzeugt die
Zuweisung dieser Referenz an einen anderen Namen lediglich eine
zweite Referenz auf das gleiche Objekt.

Echte Kopien von Objekten benutzerdefinierter Klassen können durch Kopie erstellen
Erzeugung eines neuen Objekts erstellt werden, dem zum Beispiel über
den Konstruktor die Werte eines anderen Objekts der gleichen Klasse
zugewiesen werden.

Für umfangreiche Objekte kann man sich auch der Funktion deepcopy()
aus dem Modul copy bedienen. Beide Vorgehensweisen werden im fol-
[Link]
I
genden Programm gezeigt.

Im folgenden Programm werden erzeugt:


~ ein Objekt
~ ein zweites Objekt als Kopie des ersten Objekts, mithilfe von Wert-
zuweisungen
~ ein drittes Objekt als Kopie des ersten Objekts, mit deepcopy()
~ eine zusätzliche Referenz auf das erste Objekt
Ir Modul copy
import copy

# Definition der Klasse Fahrzeug


class Fahrzeug:
def __ init __ (self, bez, gel: # Konstruktormethode
[Link] ~ bez
[Link] ~ ge
def beschleunigen(self, wert):
[Link] +~ wert
def str (sel f): Ir Ausgabemethode
return [Link] + " " \
+ str([Link]) + " km/ho

# Objekt der Klasse Fahrzeug erzeugen


opel ~ Fahrzeug( "Opel Admi ral", 40)

# Kopie eines Objektes erzeugen


zweit_opel ~ Fahrzeug(opel .bezeichnung, [Link])
zweit_opel . beschl euni gen(30)
6 I Objektorientierte Programmierung

# Tiefe Kopie eines Objektes erzeugen


dritt_opel ~ [Link](opel)
[Link](35)

# Zweite Referenz auf Objekt erzeugen


viert_opel ~ opel
viert_opel.beschleunigen(20)

# Kontrollausgaben
print("Original:",opel)
print("Kopie:", zweit_opel)
print("Kopie:", dritLopel)
print("zweite Referenz auf Original:", viert_opel)

lf Identisch
print("2:", opel i s zweit _opel)
print("3:", opel i s dritt _opel)
print("4:", opel i s viert_opel)

Listing 6.6 Datei [Link]

Die Ausgabe des Programms:


Original: Opel Admi ral 60 km/h
Kopie: Opel Admiral 70 km/h
Kopie: Opel Admiral 75 km/h
zweite Referenz auf Original: Opel Admi ral 60 km/h
2: False
3: False
4: True

Zur Erläuterung:

~ Das Objekt opel ist das Original.


~ Das Objekt zweit_opel ist ein eigenes Objekt, das mithilfe des Kon-
struktors und der Daten des Originalobjekts erzeugt wird.
~ Das Objekt dritt_opel ist ein eigenes Objekt, das mithilfe der Funk-
tion copy. deepcopy() erzeugt wird.
~ vi ert_opel ist eine zusätzliche Referenz auf das Originalobjekt opel.

~ Die Änderung einer Eigenschaft über diese Referenz ändert das Origi-
nalobjekt, wie die Ausgabe zeigt.
Operator is ~ Die Vergleiche aufIdentität mithilfe des Operators i s zeigen, dass nur
die Objekte ope 1 und vi e rLope 1 identisch sind.

188
Vererbung I 6·7

6.7 Vererbung

Eine Klasse kann ihre Eigenschaften und Methoden an eine andere Klasse Klassenhierarchie
vererben. Dieser Mechanismus wird häufig angewendet. Man erzeugt
dadurch eine Hierarchie von Klassen, die die Darstellung von Objekten
ermöglicht, die teilweise übereinstimmende, teilweise unterschiedliche
Merkmale aufweisen.

Im folgenden Beispiel wird eine Klasse PK Wdefiniert, mit deren Hilfe die Erben
Eigenschaften und Methoden von pkws dargestellt werden sollen. Bei
der Erzeugung bedient man sich der bereits existierenden Klasse Fa h r -
zeug, in der ein Teil der gewünschten Eigenschaften und Methoden
bereits verwirklicht wurden. Bei der Klasse PK Wkommen noch einige
I
Merkmale hinzu. Diese Klasse ist spezialisiert, im Gegensatz zu der allge-
meinen Klasse Fahrzeug.

Von der Klasse PK Waus gesehen ist die Klasse Fahrzeug eine Basisklasse. Basisklasse und
Von der Klasse Fahrzeug aus gesehen ist die Klasse PK Weine abgeleitete abgeleitete Klasse

Klasse.

Zunächst die Definition der Basisklasse Fahrzeug. Sie beinhaltet drei


Methoden und zwei Eigenschaften:

~ die Konstruktormethode in i t ()
~ die eigene Methode beschl euni gen()
~ die Ausgabemethode _s t r _ ( )
~ die Eigenschaft bezei chnung
~ die Eigenschaft gesch wi nd i gkeit
# Definition der Klasse Fahrzeug
class Fahrzeug:
def _init_(self. bez. gel:
[Link] ~ bez
[Link] ~ ge
def beschleunigen(self. wert):
[Link] +~ wert
def str (self):
return [Link] + " " \
+ str([Link] windigkeit) + " km/ho

Listing 6.7 Datei [Link] (Basisklasse Fahrzeug)

189
6 I Objektorientierte Programmierung

Es folgt die Definition der abgeleiteten Klasse PKW. Diese erbt von der
Klasse Fah rzeug und beinhaltet fünf Methoden und drei Eigenschaften:

Methode ~ die eigene Konstruktormethode _ in i t_ ( ) und die eigene Ausgabe-


überschreiben methode _s t r_ ( ), die jeweils die gleichnamige Methode der Basis-
klasse überschreiben
~ die eigenen Methoden ei ns tei gen ( ) und a uss tei gen ( )
~ die von der Klasse Fa h r zeug geerbte Methode bes eh 1eun i gen ( )
~ die eigene Eigenschaft insassen
~ die von der Klasse Fa h r zeug geerbten Eigenschaften bezei ehn ung und
ges ehwi nd i gkeit

# Definition der Klasse PKW


elass PKW(Fahrzeug):
def init (self. bez. ge. ins):
Fahrzeug. __ init __ (self. bez. gel
[Link] ~ ins
def str (self):
return Fahrzeug . __ str __ ( sel f) + " " \
+ str([Link]) + " Insassen"
def einsteigen(self. anzahl):
[Link] +~ anzahl
def ausstei gen( sel f. anzahl):
[Link] anzahl
Listing 6.8 Datei [Link] (abgeleitete Klasse PKW)

Zur Erläuterung:

dass ... ~ Wenn eine Klasse von einer anderen Klasse abgeleitet wird, so wird
(Basisklasse) der Name der Basisklasse in Klammern hinter dem Namen der abge-
leiteten Klasse angegeben.
~ Eine Methode einer Basisklasse kann in einer abgeleiteten Klasse
überschrieben werden.
Basisklassen- ~ Um eine Methode der Basisklasse aufzurufen, muss der Name dieser
methode Klasse angegeben werden.

Im Hauptprogramm wird ein Objekt der Klasse PKW erzeugt, verändert


und ausgegeben:

# Objekt der abgeleiteten Klasse PKW erzeugen


fiat ~ PKW("Fiat Marea". 50. 0)

19°
Vererbung I 6·7

# eigene Methode anwenden


[Link](3)
[Link](l)

# geerbte Methode anwenden


[Link](lO)

# überschriebene Methode anwenden


print fiat

I
Listing 6.9 Datei [Link] (Hauptprogramm)

Die Ausgabe des Programms:


Fiat Marea 60 km/h 2 Insassen

Zur Erläuterung:

~ Es wird das Objekt f i at erzeugt, dabei wird der Konstruktor aufgeru- Konstruktor ruft
fen. Er wird unmittelbar in der zugehörigen Klasse PKW gefunden. Die- Konstruktor

ser Konstruktor ruft wiederum den Konstruktor der Basisklasse auf,


der bereits in der Lage ist, die Erzeugung von Objekten der Basisklasse
durchzuführen. Diese abgestufte Vorgehensweise ist nicht zwingend
vorgeschrieben, aber empfehlenswert. Anschließend wird die verblie-
bene Eigenschaft der abgeleiteten Klasse initialisiert.
~ Es werden die Methoden einsteigen() und aussteigen() aufgeru-
fen. Diese werden unmittelbar in der Klasse PKW gefunden und verän-
dern die Eigenschaft insassen.
~ Es wird die Methode bes ch 1euni gen () aufgerufen. Diese wird nicht Methode suchen
unmittelbar in der Klasse PKW gefunden, daher wird in der Basisklasse
weiter gesucht. Dort wird sie gefunden und dient zur Veränderung
der Eigenschaft ges chwi nd i g ke i t.
~ Es wird die Ausgabemethode __ s t r _ () aufgerufen. Diese wird Methode ruft
unmittelbar in der Klasse PKW gefunden. Sie ruft wiederum die gleich- Methode

namige Methode der Basisklasse auf. Das Ergebnis dieses Aufrufs


wird mit den restlichen Daten aus der Klasse PKW zusammengesetzt
und zurückgeliefert. Dies führt zur Ausgabe aller Daten des Objekts
fi a t.

Eigenschaften und Methoden werden zunächst in der Klasse des Objekts Suchreihenfolge
gesucht. Sollten sie dort nicht vorhanden sein, so wird die Suche in der
zugehörigen Basisklasse fortgesetzt.

191
6 I Objektorientierte Programmierung

6.8 Mehrfachvererbung

Mehrere Eine abgeleitete Klasse kann wiederum Basisklasse für eine weitere
Basisklassen Klasse sein. Dadurch ergibt sich eine Vererbung über mehrere Ebenen.
Eine Klasse kann außerdem von zwei Basisklassen gleichzeitig abgeleitet
sein (Mehrfachvererbung), sie erbt dann alle Eigenschaften und Metho-
den beider Basisklassen.

Im folgenden Beispiel werden die beiden Klassen PKW und LKW von der
Klasse Fahrzeug abgeleitet. Außerdem wird die Klasse Lieferwagen
erzeugt, die sowohl von der Klasse PKW als auch von der Klasse LKW erbt.
Die Definitionen der Klassen Fa h r zeug und PKW sind bereits aus dem letz-
ten Abschnitt, »Vererbung«, bekannt.

Klasse LKW Es folgt die Definition der abgeleiteten Klasse LKW. Sie ähnelt im Aufbau
der Klasse PKW, erbt von der Klasse Fa h r zeug und beinhaltet fünf Metho-
den und drei Eigenschaften:
~ die eigene Konstruktormethode _ in i t_ ( ) und die eigene Ausgabe-
methode _s t r_ ( ), die jeweils die gleichnamige Methode der Basis-
klasse überschreiben
~ die eigenen Methoden bel aden() und entl aden()
~ die von der Klasse Fa h r zeug geerbte Methode bes eh 1eun i gen ( )
~ die eigene Eigenschaft 1 adung
~ die von der Klasse Fa h r zeug geerbten Eigenschaften bezei ehn ung und
ges ehwi nd i gkeit

# Definition der Klasse LKW


elass LKW(Fahrzeug):
def init (self. bez. ge. la):
Fahrzeug. __ init __ (self. bez. gel
[Link] ~ la
def str (self):
return Fahrzeug . __ str __ ( sel f) + " " \
+ str([Link]) + " Tonnen Ladung"
def beladen(self. wert):
[Link] +~ wert
def entladen(self. wert):
[Link] wert
Listing 6.10 Datei [Link] (abgeleitete Klasse LKW)

192
Mehrfachvererbung I 6.8

Die Klasse Lieferwagen erbt von zwei Klassen, die eine gemeinsame Klasse
Basisklasse haben. Sie beinhaltet sieben Methoden und vier Eigenschaf- Lieferwagen
ten:

~ die eigene Konstruktormethode _ in i t __ ( ) und die eigene Ausgabe-


methode __ s t r _ ( ), die jeweils die geerbten Methoden überschrei-
ben
~ die von der Klasse PK Wgeerbten Methoden einsteigen() und aus-
steigen()
~

~
die von der Klasse LK Wgeerbten Methoden be 1 ade n () und e n tl a -
den ()
die von der Klasse Fa h r zeug geerbte Methode bes eh 1 eun i gen ( )
I
~ die von der Klasse PKW geerbte Eigenschaft insassen
~ die von der Klasse LKW geerbte Eigenschaft 1 adung
~ die von der Klasse Fa h r zeug geerbten Eigenschaften beze i ehn ung und
ges ehwi nd i gkeit

# Definition der Klasse Lieferwagen


elass Lieferwagen(PKW, LKW):
def _init_(self, bez, ge, ins, la):
PKW. init (self, bez, ge, ins)
LKW. init (self, bez, ge, la)
def str (self):
return PKW. str (self) + "\n" \
+ LKW. str (self)

Listing 6.11 Datei [Link] (abgeleitete Klasse Lieferwagen)

Im Hauptprogramm wird ein Objekt der Klasse Lieferwagen erzeugt,


verändert und ausgegeben:
# Objekt der abgeleiteten Klasse Lieferwagen erzeugen
toyota ~ Lieferwagen("Toyota Allround", 0, 0, 0)
[Link](2)
[Link](3.5)
[Link](30)
print toyota

Listing 6.12 Datei [Link] (Hauptprogramm)

Die Ausgabe des Programms lautet:


Toyota All round 30 km/h 2 Insassen
Toyota All round 30 km/h 3.5 Tonnen Ladung

193
6 I Objektorientierte Programmierung

Zur Erläuterung:
~ Es wird das Objekt toyota erzeugt, dabei wird der Konstruktor aufge-
rufen. Er wird unmittelbar in der zugehörigen Klasse Lieferwagen
gefunden. Dieser Konstruktor ruft wiederum die beiden Konstrukto-
ren der Basisklassen PKW und LKW auf. Diese rufen jeweils zum einen
den Konstruktor der Basisklasse Fa h r zeug auf und initialisieren zum
anderen eine spezifische Eigenschaft der Klasse (i ns a s sen oder
1 adung).

~ Es werden die Methoden ei ns tei gen ( ), be 1 aden ( ) und bes ch 1 euni -


gen ( ) aufgerufen. Diese werden in verschiedenen Basisklassen gefun-
den und verändern die Eigenschaften insassen, 1 adung und
geschwindigkeit.

~ Es wird die eigene Ausgabemethode _s t r __ () aufgerufen. Ähnlich


wie beim Konstruktor ruft diese die gleichnamigen Methoden der
Basisklassen auf.

194
7 Neues in Python 3

In diesem Kapitel wird ein Teil der vielen Änderungen beschrieben, die
Python mit der Version 3.0 erfahren hat. Anschließend wird eine der
Umstiegshilfen von Version 2 auf Version 3, das Tool2to3, erläutert.

7.1 Neue und geänderte Eigenschaften

Alle Beispiele dieses Buchs wurden mit und für Python 3.0 entwickelt.
Sie funktionieren teilweise nur unter Python 3.0 und nicht mehr unter
Alles für 3.0 I
älteren Versionen.

In diesem Abschnitt werden noch einmal viele Änderungen gesondert


beschrieben, die sich in Python 3.0 gegenüber Python 2.6 ergeben
haben. Es sind Verweise auf die Stellen im Buch eingefügt, an denen die
jeweiligen Eigenschaften genauer beschrieben sind.

Python 3.0 ist die erste Python-Version, die nicht mehr zu 100% Nicht 100% ab-
abwärtskompatibel ist. Es gibt mehr und wichtigere Änderungen als bei wärtskompatibel
früheren Versionswechseln. Viele bekannte Störungen und Fehler wur-
den beseitigt. Für umfassende Informationen über die Änderungen ver-
weise ich auf die Python-Dokumentation.

Das verbreitete Webframework Django gibt es zurzeit (Stand Januar


2009) noch in keiner Version für Python 3.0. Ebenso verhält es sich mit
der Schnittstelle zu MySQL-Datenbanken.

7.1.1 Auffällige Änderungen


Die Anweisung pr i nt zur Ausgabe auf dem Bildschirm wurde ersetzt printO
durch die Funktion print() (siehe Abschnitt 5.2.1, »Funktion printO«).
Es gibt eine Reihe von Funktionen, die lteratoren (siehe Abschnitt 5.4,
»Iterierbare Objekte«) oder Views liefern (siehe Abschnitt 4.5.3,
»Views«).

195
7 I Neues in Python 3

inputO Die Funktion raw_ input () zur Eingabe von Zeichenketten wurde ersetzt
durch die Funktion input() (siehe Abschnitt 3.2.2, »Eingabe einer Zei-
chenkette«).

Objektvergleiche Es können nur noch sinnvolle Vergleiche zwischen Objekten stattfinden.


Andernfalls wird eine Ausnahme erzeugt, zum Beispiel beim Vergleich 1
< "abc". Statt der besonderen Objektmethode _cmp_( ) muss jetzt eine
der Vergleichsmethoden genutzt werden, wie zum Beispiel _1 t_ ( )
(siehe Abschnitt 6.5, »Operatormethoden«).

int, lang Den Datentyp 1 ong gibt es nicht mehr, also auch keine Integer-Literale
mit einem großen L oder einem kleinen 1 am Ende. Alle ganzen zahlen
laufen jetzt unter dem Datentyp i nt. Dieser Datentyp hat keine Ober-
grenze mehr. Oktalzahlen schreibt man nicht mehr mit 0 (Null) am
Anfang, sondern mit 00 (Null und Buchstabe 0).

Operatoren Der Operator / liefert immer eine mathematisch korrekte Division, eine
Ganzzahldivision erreicht man mit / / (siehe Abschnitt 2.1.3, »Division,
Ganzzahldivision und Modulo«). Anstelle des Operators<> (für ungleich)
wird nun nur noch der Operator ! ~ genutzt.

str, bytes Zeichenketten werden mit Unicode-Zeichen aufgebaut und sind vom
Datentyp st r (siehe Abschnitt 4.2, »Zeichenketten«). Unicode-Literale
dürfen nicht mehr mit u" ... " oder U" ... " gebildet werden. Binärdaten
werden im Datentyp bytes gespeichert (siehe Abschnitt 4.2.7, »Datentyp
bytes«). Sie können mit Byte-Literalen (b" ... ,,) gebildet werden.

7.1.2 Weitere Änderungen


Bei Definition und Aufruf einer Funktion kann eine variable Anzahl von
Parametern zusammen mit benannten Parametern eingesetzt werden.

Tupel entpacken Tupel können auch entpackt werden, wenn nicht genügend Variablen
zum Empfang bereitstehen - sofern einer der Variablen ein * (Stern) vor-
ansteht. Diese Variable stellt eine Liste der verbleibenden Tupel-Ele-
mente dar, die nicht untergebracht werden konnten (siehe Abschnitt
4.4.3, »Tupel entpacken«).

Sets Sets (Mengen) können mit Set-Literalen gebildet werden. Ein Beispiel:
a ~ {3 • 5 • 7) ergibt das Set a mit drei Elementen.

196
Konvertierung von Python 2 zu Python 3 I 7.2

Die Anweisung ra i se zur Erzeugung von Ausnahmen und die Anweisung Ausnahmen
except zur Spezifizierung einer Ausnahmebehandlung haben eine geän-
derte Syntax (siehe Abschnitt 5.6.6, »Unterscheidung von Ausnahmen«).

Die Syntax bei List Comprehensions wurde geändert (siehe Abschnitt 5.5,
»List Comprehension«).

True, False (siehe Abschnitt 4.7.1, »Wahrheitswerte True und False«) True, False, None
und None (siehe Abschnitt 4.7.2, »Nichts, None«) gehören zu den reser-
vierten Wörtern.

Die Funktion exec() ersetzt die Anweisung exec (siehe Abschnitt 5.1.5,
»Funktionen evalO und execO«).

Zum Import von Modulen wird ohnehin die Schreibweise i mpo rt Mod u1 -
name empfohlen (siehe Abschnitt 5.9, »Eigene Module«). Die alternative
Schreibweise f rom Modul name i mpo rt ... darf nicht mehr in Funktionen,
import
I
sondern nur noch auf Modulebene genutzt werden.

Zur Formatierung von Zahlen und Zeichenketten sollte nicht mehr der formatO
Operator % eingesetzt werden, er wird in Kürze nicht mehr unterstützt.
Stattdessen wird die Funktion f 0 rma t () empfohlen (siehe Abschnitt
5.2.2, »Formatierte Ausgabe«).

Die Funktion has_key( ) zur Prüfung der Existenz eines Dictionary-Ele- Operator in
ments gibt es nicht mehr. Stattdessen muss der Operator in genutzt wer-
den (siehe Abschnitt 4.5.2, »Funktionen«).

7.2 I<onvertierung von Python 2 zu Python 3

Man kann Programme mit dem Kommandozeilentool 2to3 und anderen Tool2t03
Hilfen von Python2-Code in Python3-Code überführen. Bei einfachen
Programmen genügt häufig schon das Too12to3 alleine. Es findet sich als
Datei [Link] im Unterverzeichnis Tools/Scripts der Python-Versionen
2.6 und 3.0.

Der Vorgang soll an einem Beispiel gezeigt werden:


n ~ raw_input("Ihr Name: ")
print "Hallo", n
Listing 7.1 Datei [Link]

197
7 I Neues in Python 3

Folgende Elemente werden im Beispiel genutzt:

~ die Funktion raw_input() zur Eingabe einer Zeichenkette, die es in


Python 3 nicht mehr gibt
~ die Anweisung pr i nt, die in Python 3 eine Funktion ist und keine
Anweisung

Python 2.6- Dieses Programm läuft einwandfrei unter Python 2.6, aber nicht unter
Programm Python 3.

In Abschnitt 2.3.2, »Ausführen unter Windows«, wurde beschrieben,


wie man zur Kommandozeile gelangt. Dort wechselt man in das Unter-
verzeichnis Tools/Script. Falls sich die zu konvertierende Datei auch in
diesem Verzeichnis befindet, wird das Tool wie folgt aufgerufen:
2t03 [Link]

Als Ausgabe folgt eine Beschreibung der Vorgänge, die bei der Konvertie-
rung auftreten. Am Ende der Ausgabe steht: Fi 1 es that need to be mod i-
fi ed: gOI. py. Die Datei ist noch unverändert.

Die Datei wird erst verändert, wenn man das Tool wie nachfolgend mit
der Option -w aufruft:
2t03 -w [Link]

Python 3.0- Am Ende der Ausgabe steht nun: Fi 1 es tha t we re mod ifi ed: gOI. py. Die
Programm Datei wurde konvertiert, wie man sehen kann:
n ~ input("Ihr Name: ")
print( "Hallo". n)

Listing 7.2 Datei [Link] (konvertiert)

Die alte Version steht noch in der Datei [Link] zur Verfügung.

198
8 Verschiedene Module

In diesem Kapitel werden Programmiertechniken zur Arbeit mit Datums-


und Zeitangaben, Collections, die Technik des Multithreadings sowie
reguläre Ausdrücke erläutert.

8.1 Datum und Zeit

Das Modul time beinhaltet Funktionen zur Verarbeitung und Formatie- Modul time
rung von Datums- und Zeitangaben.

Auf vielen Betriebssystemen gilt der 1. Januar 1970 00:00 Uhr als Null-
punkt für die Verarbeitung von Datums- und Zeitangaben. Die Zeit wird
Zeitlicher
Nullpunkt
I
in Sekunden ab diesem Zeitpunkt gerechnet.

8.1.1 Spielen mit Zeitangabe


Das Spiel aus dem Programmierkurs können Sie um Datums- und Zeitan- Zeit messen
gaben erweitern. Beispielsweise könnten Sie eine Zeitmessung einbauen,
die feststellt, wie lange ein Benutzer zur Lösung einer oder aller Aufga-
ben benötigt hat.

Falls eine Bestleistung erzielt wurde, zum Beispiel eine hohe Anzahl an
gelösten Aufgaben im ersten Versuch oder die Lösung der Aufgaben
innerhalb besonders kurzer Zeit, so möchte man dies mit Datum und
Uhrzeit festhalten.

8.1.2 Aktuelle Zeit ausgeben


Zwei Beispielprogramme sollen die Ermittlung und die formatierte Aus- timeO, localtimeO
gabe der aktuellen Zeit verdeutlichen. Zunächst ein Programm, das die
Funktionen time ( ) und 1 oca 1 ti me( ) aus dem Modul time nutzt:
Ir Modul time
import time

# Zeit in Sekunden
print("Zeit in Sekunden:", [Link]())

199
8 I Verschiedene Module

# Aktuelle, lokale Zeit als Tupel


lt ~ [Link]()

# Entpacken des Tupels


lf Da t um
jahr, monat, tag ~ lt[0:3]
print("Es ist der {0:02d}.{1:02d}.{2:4d}".
format(tag, monat, jahr))

lf Uhrzeit
stunde, minute, sekunde ~ lt[3:6]
print("genau {0:02d}:{1:02d}:{2:02d}".
format(stunde, minute, sekunde))

lf Wochentag
wtage ["Montag", "Dienstag", "Mittwoch", "Donnerstag",
~

"Freitag", "Samstag", "Sonntag"]


wtagnr ~ lt[6]
print("Das ist ein", wtage[wtagnr])

# Tag des Jahres


tag_des_jahres ~ lt[7]
print("Der {O:d}. Tag des Jahres".
format(tag_des_jahres))

lf Sommerzeit
dst lt[8]
~

i f dst ~~ 1:

print("Die Sommerzeit ist aktiv")


e 1 if ds t ~~ 0:
print("Die Sommerzeit ist nicht aktiv")
else:
print("Keine Sommerzeitinformation vorhanden")

Listing 8.1 Datei [Link]

Es wird die Ausgabe erzeugt:


Zeit in Sekunden: 1229922825.05
Es ist der 22.12.2008
genau 06:13:45
Das ist ein Montag
Der 357. Tag des Jahres
Die Sommerzeit ist nicht aktiv

200
Datum und Zeit I 8.1

Zur Erläuterung:

~ Die Funktion time () liefert die aktuelle Zeit in Sekunden seit dem timeO
1.1.1970.
~ Die Funktion 1 0 ca 1time ( ) ohne Parameter liefert die aktuelle Zeit als localtimeO
ein Tupe!, das aus einer Reihe von Einzelinformationen besteht. Diese
Informationen werden sodann ausgewertet:
~ Die ersten drei Elemente (0 bis 2) liefern Jahr, Monat und Tag. Jahr, Monat, Tag
Monat und Tag sind im Beispiel jeweils mit zwei Ziffern und füh-
render Null formatiert.
~ Die nächsten drei Elemente (3 bis 5) liefern Stunde, Minute und Stunde, Minute,
Sekunde. Alle drei Angaben sind im Beispiel jeweils mit zwei zif- Sekunde

fern und führender Null formatiert.


~ Das nächste Element (6) stellt den Wochentag von 0 bis 6 bereit. Wochentag

~
Montag entspricht dabei der 0, Sonntag der 6.
Die laufende Nummer des Tages innerhalb eines Jahres wird von
Element 7 geliefert.
I
~ Informationen über den Status der Sommerzeit liefert das letzte
Element (8).

Noch genauere Informationen liefert die Funktion s t r ft i me ( ). Sie benö- strftimeO


tigt zwei Parameter:

~ einen Formatierungsstring für die gewünschte Ausgabe


~ ein Zeit-Tupe!, wie es zum Beispiel die Funktion 1 0 c alt i me ( ) liefert

über die Möglichkeiten von 1oca 1 ti me( ) hinaus werden folgende Infor-
mationen bereitgestellt:

~ Zeit im 12-Stunden-Format, mit der Angabe AM oder PM


~ Jahresangabe nur mit zwei Ziffern
~ Name des Wochentags, abgekürzt oder ausgeschrieben. Der Sonntag Wochentagsname
entspricht dabei der 0 (!) im Unterschied zu 1 oca lt i me ( ).
~ Name des Monats, abgekürzt oder ausgeschrieben Monatsname

~ Kalenderwoche des Jahres, bezogen auf zwei verschiedene Systeme


(Sonntag oder Montag als erster Tag der Woche)
~ Angabe der Zeitzone

201
8 I Verschiedene Module

Ein Beispielprogramm:
lf Modul time
import time

lf Aktuell e Zei t
lt ~ [Link]()

print([Link]("[Link]: %d.%m.%Y", lt))


print([Link]("Stunde:Minute:Sekunde: %H:%M:%S", lt))
print([Link]("im 12-Stunden-Format:" \
"%I:%M:%S Uhr %p", lt))
print([Link]("Datum und Zeit: %c", lt))
print([Link]("nur Datum: %x, nur Zeit: %X", lt))
print([Link]("Jahr in zwei Ziffern: %y", lt))
print([Link]("Tag des Jahres: %j", lt))
pr i nt ( )

lf Woche, Monat
print([Link]("Wochentag kurz:%a, ganz:%A" \
", Nr.(Sonntag~O) :%w", lt))
print([Link]("Monat kurz:%b, ganz:%B", lt))
pr i nt ( )

lf Kalenderwoche
print([Link]("Woche des Jahres, " \
"Beginn Sonntag: %U", lt))
print([Link]("Woche des Jahres, " \
"Beginn Montag: %W", lt))
pr i nt ( )

lf Zeitzone
print([Link]("Zeitzone: %Z", lt))

Listing 8.2 Datei [Link]

Die Ausgabe lautet:


[Link]: 22.12.2008
Stunde:Minute:Sekunde: 06:31:41
im 12-Stunden-Format: 06:31:41 Uhr AM
Datum und Zeit: 12/22/08 06:31:41
nur Datum: 12/22/08, nur Zeit: 06:31:41
Jahr in zwei Ziffern: 08
Tag des Jahres: 357

202
Datum und Zeit I 8.1

Wochentag kurz:Mon. ganz:Monday. Nr.(Sonntag~O):1

Monat kurz:Dec. ganz:December

Woche des Jahres. Beginn Sonntag: 51


Woche des Jahres. Beginn Montag: 51

Zeitzone: Westeuropäische Normalzeit

8.1.3 Zeitangabe erzeugen


Zur Erzeugung einer beliebigen Zeitangabe wird die Funktion mkt i me ( ) mktimeO
genutzt. Sie benötigt als Parameter ein Tupel mit allen neun Angaben,
wie sie auch von der Funktion 10 ca 1 time ( ) geliefert werden.

Die Angaben für Wochentag, Tag des Jahres und Sommerzeit kennt man
natürlich nur in den wenigsten Fällen. Sie können einfach mit 0 besetzt
werden, sie werden dennoch automatisch korrekt ermittelt, wie das fol-
I
gende Beispiel zeigt:
i! Modul time
import time

# Zeitangabe erzeugen
dztupel ~ 1979. 2. 15. 13. O. O. O. O. 0
print([Link]("%d.%m.%Y %H:%M:%S". dztupel))
damals ~ [Link](dztupel)

i! Ausgabe
lt ~ [Link](damals)

i! Wochentag
wtage ["Montag". "Dienstag". "Mittwoch". "Donnerstag".
~

"Freitag". "Samstag". "Sonntag"]


wtagnr ~ 1 t[6]
print("Das ist ein". wtage[wtagnr])

# Tag des Jahres


tag_des_jahres ~ lt[7]
print("Der {O:d}. Tag des Jahres".format(tag_des_jahres))

Listing 8.3 Datei [Link]

2°3
8 I Verschiedene Module

Die Ausgabe lautet:


15.02.1979 13:00:00
Das ist ein Donnerstag
Der 46. Tag des Jahres

Zur Erläuterung:
~ Das Datum »15. Februar 1979 13:00 Uhr« soll gespeichert werden.
Dazu werden die ersten vier Elemente des Tupels mit den gegebenen
Werten besetzt. Die Angaben für Minute und Sekunde sowie die drei
restlichen Angaben werden mit 0 besetzt.
~ Wird die Funktion 1 oca 1time () mit einer Zeitangabe als Parameter
aufgerufen, so liefert sie ein Tupel mit den einzelnen Informationen
zu dieser Zeitangabe.

8.1.4 Mit Zeitangaben rechnen


Zeitdifferenz Zur Berechnung eines Zeitraums, also der Differenz zwischen zwei Zeit-
angaben, müssen beide Zeitangaben einzeln erzeugt werden. Anschlie-
ßend kann die Differenz aus den beiden Zeitangaben in Sekunden
berechnet werden. Aus dieser Differenz lässt sich dann auch die Diffe-
renz in Minuten, Stunden und Tagen ermitteln.

Im folgenden Programm wird die Differenz zwischen dem 15. Februar


197923:55:00 Uhr und dem 16. Februar 197900:05:15 Uhr berechnet.
lf Modul time
import time

# Zwei Zeitangaben erzeugen


dztupell ~ 1979. 2. 15. 23. 55. O. O. O. 0
damalsl ~ [Link](dztupell)
print("Zeit 1:". [Link]("%d.%m.%Y %H:%M:%S".
dztupell))

dztupe12 ~ 1979. 2. 16. O. 5. 15. O. O. 0


damals2 ~ [Link](dztupe12)
print("Zeit 2:". [Link]("%d.%m.%Y %H:%M:%S".
dztupe12))
pr i nt ( )

# Differenz berechnen
print("Differenz:")

204
Datum und Zeit I 8.1

diff_sek ~ damals2 damals1


print(diff_sek, "Sekunden")

diff_min ~ diff sek/60


print(difCmin, "Minuten")

diff_std ~ diff min/60


print(diff_std, "Stunden")

diff_tag ~ diff_std/24
print(diff_tag, "Tage")

Listing 8.4 Datei [Link]

Folgende Ausgabe wird erzeugt:

I
Zeit 1: 15.02.1979 23:55:00
Zeit 2: 16.02.1979 00:05:15

Differenz:
615.0 Sekunden
10.25 Minuten
0.170833333333 Stunden
0.00711805555556 Tage

Zur Erläuterung:
~ In der Variablen d i ff se k wird die Differenz zwischen den beiden
Zeitangaben damals1 und damals2 in Sekunden berechnet.
~ Zur Ermittlung der Minuten wird diese Zahl durch 60 geteilt.
~ Zur Ermittlung der Stunden wird wiederum dieses Ergebnis durch 60
geteilt.
~ Zur Ermittlung der Tage wird das letzte Ergebnis durch 24 geteilt.

Zur Berechnung des Alters einer Person wird ein anderer Weg beschrit- Alter berechnen
ten. Dies wird im folgenden Programm gezeigt.
lf Modult time
import time

lf Geburtstag
dztupel ~ 1979, 5, 7, 0, 0, 0, 0, 0, 0
print("Geburt:", [Link]("%d.%m.%Y", dztupel))
geburt ~ [Link](dztupel)
ltgeburt ~ [Link](geburt)

2°5
8 I Verschiedene Module

Ir Akt ue 11
ltheute ~ [Link]()
print("Heute:", [Link]("%d.%m.%Y"))

# Alter berechnen
alter ~ ltheute[OJ ltgeburt[OJ
if ltheute[lJ < ltgeburt[lJ or \
ltheute[lJ ~~ ltgeburt[lJ and \
ltheute[2J < ltgeburt[2J:
alter ~ alter 1
print("Alter:", alter)
Listing 8.5 Datei [Link]

Die Ausgabe lautet:


Geburt: 07.05.1979
Heute: 22.12.2008
Alte r: 29

Zur Erläuterung:
~ Die Zeitangabe für den Geburtstag, zum Beispiel für den 7. Mai 1979,
wird mithilfe der Funktion mkt i me ( ) erzeugt.
~ Die aktuelle Zeitangabe wird mit der Funktion 10 ca 1time () ohne
Parameter erzeugt.
~ Das Alter wird zunächst aus der Differenz der Jahresangaben errech-
net.
~ Falls die Person in diesem Jahr noch nicht Geburtstag hatte, weil
~ entweder der Geburtsmonat noch nicht erreicht wurde
~ oder innerhalb des Geburtsmonats der Geburtstag noch nicht
erreich t wurde,
~ so wird das Alter um 1 reduziert.

8.1.5 Programm anhalten


sleepO Die Funktion s 1 eep () aus dem Modul time ermöglicht das Anhalten
eines Programms für einen bestimmten Zeitraum. In dem folgenden Bei-
spielprogramm wird innerhalb einer Schleife mehrmals die al<tuelle Zeit
ausgegeben. Nach jedem Ausgabevorgang wird das Programm für 2
Sekunden angehalten. Am Ende wird die Zeitdifferenz zwischen Start
und Ende berechnet.

206
Datum und Zeit I 8.1

Ir Modul time
import time

Ir Start
startzeit ~ [Link]()
print("Start:", startzeit)

# Zeitangaben, jeweils mit Pause


for i in range(5):
[Link](2)
print([Link]())

Ir Ende
endzeit ~ [Link]()
print("Ende:", endzeit)

Ir Abstand
differenz ~ endzeit startzeit
print("Differenz:", differenz)
I
Listing 8.6 Datei [Link]

Es wird die folgende Ausgabe erzeugt:


Start: 1229932749.0
1229932751.02
1229932753.03
1229932755.03
1229932757.03
1229932759.03
Ende: 1229932759.03
Differenz: 10.0309998989

Wie die Ausgabe des Durchschnittswerts zeigt, lässt sich die Funktion
s 1 eep ( ) nur für eine zeitliche Steuerung von begrenzter Genauigkeit ein-
setzen, denn

~ zum einen benötigen die einzelnen Programmschritte eine eigene,


wenn auch kurze, Laufzeit und
~ zum anderen unterscheiden sich die Zeitabstände geringfügig.

Dennoch kann die Funktion s 1eep () für viele Anwendungen sinnvoll Einsatz-
eingesetzt werden, unter anderem im Bereich von grafischen Animatio- möglichkeiten

nen, Simulationen oder Spieleprogrammierung.

207
8 I Verschiedene Module

8.1.6 Spiel, Version mit Zeitmessung


Zeitmessung In dieser Spielversion werden fünf Additionsaufgaben mit zahlen aus
dem Bereich von 10 bis 30 gestellt. Der Spieler hat pro Aufgabe nur
einen Versuch. Ungültige Eingaben oder falsche Ergebnisse werden ein-
fach mit dem Text Fa 1 sc h kommentiert und bewertet. Am Ende wird die
Gesamtzeit angegeben, die der Spieler benötigt hat.
1f Modul e
import random, time

1f Initialisierung
[Link]( )
richtig ~ 0
startzeit ~ [Link]()

1f 5 Aufgaben
for aufgabe in range(5):
# Aufgabe mit Ergebnis
a [Link](lO,30)
b ~ [Link](lO,30)
c ~ a + b
pr i nt ( " Auf gab e", auf gab e+ 1, " von 5:", a, "+" b)

1f Eingabe
try:
zahl ~ int(input("Bitte eine Zahl eingeben: "))
i f zahl ~~ c:
print("Richtig")
richtig +~ 1
else:
raise
except:
print("Falsch")

1f Auswertung
endzeit ~ [Link]()
differenz ~ endzeit-startzeit
print("Richtig: {O:d} von 5 in {1:.2f} Sekunden".
format(richtig, differenz))
print("Ergebnis erzielt:",
[Link]("%d.%m.%Y %H:%M:%S"))

Listing 8.7 Datei [Link]

208
Modul collections I 8.2

Die Ausgabe lautet:


Aufgabe 1 von 5: 14 + 30
Bitte eine Zahl eingeben: 44
Richtig
Aufgabe 2 von 5: 17 + 11
Bitte eine Zahl eingeben: 28
Richtig
Aufgabe 3 von 5: 25 + 19
Bitte eine Zahl eingeben: 44
Richtig
Aufgabe 4 von 5: 23 + 22
Bitte eine Zahl eingeben: 45
Richtig
Aufgabe 5 von 5: 19 + 28
Bitte eine Zahl eingeben: 47
Richtig
Richtig: 5 von 5 in 7.63 Sekunden
Ergebnis erzielt: 22.12.2008 09:23:40

Zur Erläuterung:
I
~ Am Anfang und am Ende wird die Zeit genommen und anschließend Zeitdifferenz
die Differenz berechnet.
~ Die Anzahl der richtigen Ergebnisse wird mitgezählt.
~ Im Fall einer ungültigen Eingabe oder eines falschen Ergebnisses wird
eine Ausnahme erzeugt.

8.2 Modul collections

Das Modul co 11 ect ions bietet einige spezialisierte Datentypen, die als Datentyp deque
Container dienen können, unter anderem den Datentyp deque. Die
Datentypen ähneln teilweise den eingebauten Container-Datentypen
(wie Dictional)', Liste, Set oder Tupel), haben allerdings zusätzliche
Fähigkeiten und bieten einen sehr schnellen Zugriff.

Die Bezeichnung des Datentyps deque steht für double-ended queue. An double-ended
beiden Enden eines Objekts dieses Typs kann man Elemente hinzufügen queue
oder entfernen. Ein Beispiel:
lf Modul
import collections

2°9
8 I Verschiedene Module

lf Erzeugen
d ~ [Link]("abc")
print("Neu:", d)

lf El emente
forxind:
print("Element:", x)

lfHinzu links, rechts


[Link](5)
[Link](25)
print("Hinzu:", d)

lfErweitern 1 i nks, rechts


[Link]([7,9J)
[Link]([17,19J)
print("Erweitert:", d)

lf Entfernen 1 i nks, rechts


li ~ [Link]()

print("Links:", li)
re ~ [Link]()
print("Rechts:", re)
print("Entfernt:", d)

lf Rotieren
d. rotate( )
print("Rotiert +1:", d)
[Link](-2)
print("Rotiert -2:", d)

lfLee ren
[Link]()
print("Geleert:", d)

Listing 8.8 Datei [Link]

Die Ausgabe lautet:


Neu: deque(['a', 'b', 'c'J)
El ement: a
El ement: b
El ement: c
Hinzu: deque([5, 'a', 'b', 'c', 25J)
Erweitert: deque([9, 7, 5, 'a', 'b', 'c', 25, 17, 19J)

210
Modul collections I 8.2

Links: 9
Rechts: 19
Entfernt: deque([7, 5, 'a', 'b', 'c', 25, 17])
Rotiert +1: deque([17, 7, 5, 'a', 'b', 'c', 25J)
Rotiert -2: deque([5, 'a', 'b', 'c', 25, 17, 7])
Geleert: deque([J)

Zur Erläuterung:

~ Die Funktion deque() liefert ein neues Objekt des Datentyps deque. dequeO
Als Parameter wird ein iterierbares Objekt benötigt, also eine Zei-
chenkette, eine Liste oder Ähnliches.
~ Die einzelnen Elemente können mit f 0 r ... in erreicht werden.
~ Mithilfe der Methoden appendl eft() und append() können einzelne appendO
Elemente am linken oder am rechten Ende der double-ended queue hin-

I
zugefügt werden.
~ Die Methoden extendl eft() und extend() dienen zum Erweitern extendO
der double-ended queue um mehrere Elemente am linken bezie-
hungsweise am rechten Ende.
~ Die Elemente werden nacheinander in der gegebenen Reihenfolge
am jeweiligen Ende angefügt.
~ Dies führt dazu, dass die hinzugefügten Elemente bei der Methode
extendl eft() in einer anderen Reihefolge stehen.

~ Die Methoden pop 1 eft ( ) und pop( ) entfernen ein Element am linken popO
Ende beziehungsweise am rechten Ende. Dieses Element wird jeweils
als Rückgabewert geliefert.
~ Mithilfe der Methode rotate( ) kann man die Elemente innerhalb der rotateO
double-ended queue zirkular rotieren lassen.
~ Wird kein Parameter angegeben, so wird um ein Element nach
rechts rotiert.
~ Es können auch negative Wert angegeben werden. In diesem Fall
wird nach links rotiert.
~ Ein Element, das bei der Rotation über den Rand geschoben wird,
wird am anderen Ende wieder angefügt.

211
8 I Verschiedene Module

8.3 Multithreading

Parallele Der Begriff Multithreading bezeichnet die Eigenschaft eines Programms,


Verarbeitung mehrere Teile parallel bearbeiten zu lassen. Diese parallel laufenden
Teile eines Programms werden Threads genannt.
Moderne Betriebssysteme erlauben Multithreading, und die Program-
miersprache Python bietet die entsprechenden Routinen.

8.3.1 Wozu dient Multithreading?


Einsatz- Es gibt eine Reihe von Problemstellungen, bei denen sich Multithreading
möglichkeiten als nützlich erweist, zum Beispiel Simulationen von realen Prozessen, bei
denen eine Aktion eine weitere Aktion anstößt, danach aber selbst auch
weiter läuft. Die angestoßene Aktion kann wiederum eine dritte Aktion
auslösen usw. Alle Aktionen greifen auf die gleichen Umgebungsdaten
zu, verändern sie gegebenenfalls, enden zu verschiedenen Zeitpunkten
und mit unterschiedlichen Ergebnissen.
Es kann sich auch um Gur-Anwendungen handeln, bei denen rechen-
intensive Programmteile im Hintergrund laufen (ausgelagert werden) oder
grafisch permanent die Ergebnisse von Messwertauswertungen oder
anderen Echtzeit-Prozessen dargestellt werden.

8.3.2 Erzeugung eines Threads


start_new_ Das Modul _thread bietet eine einfache Möglichkeit zum Multithrea-
threadO ding. Zur Erzeugung eines Threads in Python wird die Funktion
s ta rLnew_th read ( ) benötigt. Diese Funktion verlangt zwei Parameter:
~ den Namen einer Funktion, die im Thread ausgeführt werden soll
~ ein Tupel mit Parametern für diese Funktion; hat die Funktion keine
Parameter, muss ein leeres Tupel angegeben werden
Im folgenden Programm wird aus dem Hauptprogramm ein neuer
Thread gestartet. Anschließend wird das Hauptprogramm für 10 Sekun-
den angehalten und dann beendet. Beginn und Ende des Hauptpro-
gramms werden angezeigt.
In dem Thread läuft die Funktion show ( ), in der insgesamt fünfmal die
aktuelle Zeit angezeigt wird. Nach jeder Anzeige wird das Programm für
1,5 Sekunden angehalten. Beginn und Ende des Threads werden eben-
falls angezeigt.

212
Multithreading I 8.3

Ir Modul e
import time, thread

# Thread-Funktion
def show():
print("Start Thread")
for i in range(5):
print(i, [Link]())
time. s 1 eep (1 .5)
print("Ende Thread")
return

Ir Hauptprogramm
print( "Start Hauptprogramm: ", time. time())
thread.start_new_thread(show,())
[Link](10)
print("Ende Hauptprogramm:", [Link]())

Listing 8.9 Datei [Link] I


Es wird die Ausgabe erzeugt:
Start Hauptprogramm: 1229952093.11
Start Thread
o 1229952093.13
1229952094.64
2 1229952096.16
3 1229952097.66
4 1229952099.16
Ende Thread
Ende Hauptprogramm: 1229952103.13

Zur Erläuterung:

~ Man erkennt, dass das Hauptprogramm circa 10 Sekunden gelaufen Hauptprogramm


ist.
~ Parallel dazu lief ein Thread, der ungefähr alle 1,5 Sekunden eine Aus- Thread
gabe macht.
~ Bei den hier vorgenommenen Zeitangaben endet das Hauptpro-
gramm erst, nachdem der parallel laufende Thread bereits beendet ist.

8.3.3 Identifizierung eines Threads


Zur Unterscheidung der Auswirkungen unterschiedlicher Threads hat geUdentO
jeder Thread eine eindeutige rdentifikationsnummer (ID), die über die

213
8 I Verschiedene Module

Funktion geL i dent () ermittelt werden kann. Das Hauptprogramm ist


ebenfalls ein Thread - auch dieser Haupt-Thread verfügt über eine ID.

Das vorherige Programm wurde erweitert. Aus dem Haupt-Thread wer-


den, zeitlich versetzt, insgesamt zwei Threads mit der Funktion s how( )
gestartet. Für jeden Thread, auch für den Haupt-Thread, wird die ID
ermittelt und bei jeder Ausgabe zusätzlich angezeigt.
lf Modul e
import time, thread

# Thread-Funktion
def show():
id ~ _thread.get_ident()
print("Start Thread", id)
for i in range(5):
print(i, "Thread", id)
[Link](1.5)
print("Ende Thread", id)
return

lf Hauptprogramm
id ~ _thread.get_ident()
print("Start Hauptprogramm", id)
thread.start_new_thread(show,())
[Link](O.5)
thread.start_new_thread(show,())
time. sl eep(10)
print("Ende Hauptprogramm", id)

Listing 8.10 Datei [Link]

Das Programm erzeugt die Ausgabe:


Start Hauptprogramm 3752
Start Thread 3136
o Thread 3136
Start Thread 1612
0 Thread 1612
Thread 3136
Thread 1612
2 Thread 3136
2 Thread 1612
3 Thread 3136
3 Thread 1612
4 Thread 3136

214
Multithreading I 8.3

4 Thread 1612
Ende Thread 3136
Ende Thread 1612
Ende Hauptprogramm 3752

Zur Erläuterung:
~ Der Haupt-Thread hat im vorliegenden Programmlauf die ID 3752,
der erste Unter-Thread die ID 3136, der zweite Unter-Thread die ID
1612. Der parallele Ablauf der Threads kann anhand der IDs beobach-
tet werden.

8.3.4 Gemeinsame Objekte


Alle Threads haben Zugriff auf alle globalen Daten und Objekte des über-
geordneten Threads. Im folgenden Beispiel wird gezeigt, wie eine Vari-
able vom Haupt-Thread und zwei weiteren Threads gemeinsam genutzt
Globale Variablen
I
und verändert wird.
Ir Modul e
import time, thread

# Thread-Funktion
def show():
global counter
id ~ _thread.get_ident()
for i in range(5):
counter +~ 1
print(i, id, counter)
time. s 1 eep (1 .5)
return

Ir Hauptprogramm
id ~ _thread.get_ident()
counter ~ 0
print(id, counter)

thread.start_new_thread(show,())
[Link](O.5)
thread.start_new_thread(sho w,())
[Link](10)

counter +~ 1
print(id, counter)
Listing 8.11 Datei [Link]

215
8 I Verschiedene Module

Die Ausgabe lautet:


512 0
0 3876
0 2672 2
3876 3
2672 4
2 3876 5
2 2672 6
3 3876 7
3 2672 8
4 3876 9
4 2672 10
512 11

Zur Erläuterung:
~ Die Variable counter ist global im Haupt-Thread (hier: ID 512) und
wird dort mit 0 vorbesetzt.
~ Sie wird mithilfe des schlüsselworts 91 oba 1 in der Thread-Funktion
bekannt gemacht, um 1 erhäht und angezeigt.
~ In beiden Unter-Threads (hier: ID 3876 und ID 2672) ist die Variable
bekannt und kann verändert werden.
~ Am Ende wird sie auch im Haupt-Thread um 1 erhäht und angezeigt.

8.3.5 Threads und Exceptions


Laufzeitfehler nur Tritt eine unbehandelte Ausnahme auf, so betrifft dies nur den Thread, in
im Thread dem sie auftritt. Weder der aufrufende Haupt-Thread noch die anderen
Threads werden dadurch gestärt.

Das vorherige Programm wurde erweitert. Falls der Wert der Variablen
counter den Wert 5 hat, so wird die unbehandelte Ausnahme ZeroDi vi-
si on Er ro r künstlich hervorgerufen. Der Thread, in dem dies geschieht,
wird unmittelbar beendet. Die anderen Threads - auch der Haupt-Thread
- laufen unbeeinflusst zu Ende.

Das geänderte Programm sieht wie folgt aus:


lf Modul e
import time. thread

# Thread-Funktion
def show():
910bal counter

216
Multithreading I 8.3

id ~ _thread.get_ident()
for i in range(5):
counter +~ 1
print(i, id, counter)

# Division durch 0
if counter ~~ 5:
erg ~ 1/0
time. s 1 eep (1 .5)
return

i! Hauptprogramm
id ~ _thread.get_ident()
counter ~ 0
print(id, counter)

thread.start_new_thread(show,())
[Link](0.5)
thread.start_new_thread(show,())
[Link](10)
I
counter +~ 1
print(id, counter)

Listing 8.12 Datei [Link]

Es wird die Ausgabe erzeugt:


1832 0
o 324 1
o 2372 2
324 3
2372 4
2 324 5
Unhandled exception in thread
started by <function show at Ox012F6F18>
2 2372 6
3 2372 7
4 2372 8
1832 9

Zur Erläuterung:
~ Der Thread mit der ID 324 endet aufgrund der unbehandelten Aus-
nahme. Der Thread mit der ID 2372 läuft regulär zu Ende, ebenso der
Haupt-Thread mit der ID 1832.

217
8 I Verschiedene Module

8.4 Reguläre Ausdrücke

Suchen und Reguläre Ausdrücke können das Suchen und Ersetzen von bestimmten
Ersetzen Texten oder Teiltexten oder von einzelnen Zeichen erleichtern. Sie kom-
men zum Beispiel bei der Kontrolle und Auswertung von Benutzereinga-
ben oder bei der Suche nach Dateien zum Einsatz.
Modul re Wenn festgestellt wird, dass ein Benutzer eine falsche oder unvollstän-
dige Eingabe gemacht hat, so kann dies zu einer Hilfestellung und einer
erneuten Eingabeaufforderung führen. In Python wird das Modul re
zum Arbeiten mit regulären Ausdrücken benötigt.
Die beiden folgenden Programmbeispiele sollen einen Teil der umfang-
reichen Möglichkeiten von regulären Ausdrücken verdeutlichen.

Suchen von Teiltexten


findaliO Zum Suchen von Teiltexten wird hier die Methode findall () einge-
setzt. Si e findet alle Teiltexte, die zum regulären Ausdruck passen, und
liefert eine Liste dieser Teiltexte zur weiteren Auswertung zurück.
lf Modul
import re

lf 1: Exakter Text
tx ~ "Haus und Maus und Laus"
print(tx)
erg ~ [Link]("Maus",tx)
print("l: ", erg)

lf 2: Wahl zwischen bestimmten Zeichen


erg ~ [Link]("[HMJaus",tx)
print("2: ", erg)

# 3: Alle Buchstaben aus Bereich


erg ~ [Link]("[L MJaus",tx)
print("3: ", erg)

# 4: Alle Buchstaben nicht aus Bereich


erg ~ [Link]("[AL MJaus",tx)
print("4: ", erg)

lf 5: Bel i ebi ges Zei chen


erg ~ [Link](".aus",tx)
print("5: ", erg)

218
Reguläre Ausdrücke I 8.4

# 6: Suchbegriff nur am Anfang des Textes


erg ~ [Link]("".aus",tx)
print("6: ", erg)

# 7: Suchbegriff nur am Ende des Textes


erg ~ [Link](".aus$",tx)
print("7: ", erg)
pr i nt ( )

# 8: alle Ziffern aus Bereich


tx ~ "0172-445633"
print(tx)
erg ~ [Link] ("[0-2]",tx)
print("8: ", erg)

# 9: alle Zeichen nicht aus Ziffernbereich


erg ~ [Link] ("["0-2]",tx)
print("9: ", erg)

# 10: alle Zeichen oder Ziffern, die angegeben sind


I
erg ~ [Link]("[047-]",tx)
print("10: ", erg)
pr i nt ( )

Ir 11: Wiederholung, beliebig oft


tx ~ "aa und aba und abba und abbba und aca"
print(tx)
erg ~ [Link]("ab*a",tx)
print("l1: ", erg)

# 12: Wiederholung, 1 oder mehr


erg ~ [Link]("ab+a",tx)
print("12: ", erg)

# 13: Wiederholung, 0 oder 1


erg ~ [Link]("ab?a",tx)
print("13: ", erg)

# 14: Wiederholung, m bis n


erg ~ [Link] ("ab{2,3}a",tx)
print("14: ", erg)

# 15: Wiederholung der max. Menge von Zeichen


tx ~ "aa und aba und abba und aca und addda"
erg ~ [Link]("a.*a",tx)
print("15: ", erg)

219
8 I Verschiedene Module

# 16: Wiederholung der min. Menge von Zeichen


erg ~ [Link]("a.*?a",tx)
print("16: ", erg)

Listing 8.13 Datei p0813 .py

Die Ausgabe dieses Programms:


Haus und Maus und Laus
1: ['Maus'J
2: ['Haus', 'Maus'J
3: ['Maus', 'Laus'J
4: ['Haus'J
5: ['Haus', 'Maus' , 'Laus'J
6: ['Haus'J
7: ['Laus'J

0172-445633
8: ['0', '1', '2'J
9: ['7', '-', '4', '4', '5', '6', '3', '3'J
10: ['0', '7', '-', '4', '4'J

aa und aba und abba und abbba und aca


11: ['aa', 'aba', 'abba', 'abbba'J
12: ['aba', 'abba', 'abbba'J
13: ['aa', 'aba'J
14: ['abba', 'abbba'J
15: ['aa und aba und abba und aca und addda'J
16: ['aa', 'aba', 'abba', 'aca', 'addda'J

Zur Erläuterung:
1. Basis für die ersten sieben regulären Ausdrücke ist der Text" Haus und
Maus und Laus". Im ersten Beispiel wird der exakte Begriff "Maus"
gesucht. Alle Vorkommen dieses Begriffs werden geliefert.
Eckige Klammern 2. Es werden die Teiltexte gesucht, die mit einem "H" oder einem "M"
beginnen und mit" aus" enden. In den eckigen Klammern steht:
Suche wahlweise "H" oder "M". Gefunden werden "H a us" und
"Maus", aber nicht "Laus".

3. Es werden die Teiltexte gesucht, die mit einem der Zeichen von "L"
bis" M" beginnen und mit" a us" enden. Die eckigen Klammern geben
einen Bereich an. Gefunden werden "Maus" und "Laus", aber nicht
"Ha us".

220
Reguläre Ausdrücke I 8.4

4. Es werden die Teiltexte gesucht, die nicht mit einem der Zeichen von Zeichen A, nicht
" L" bis" M" beginnen, aber mit" aus" enden. Das Zeichen" bedeu-
A"

tet im Zusammenhang mit einem Bereich eine logische Verneinung.


Gefunden wird "Haus", aber nicht "Maus" und "Laus".
5. Es werden die Teiltexte gesucht, die mit einem beliebigen Zeichen Zeichen.
beginnen und mit" a us" enden. Das Zeichen" . " (Punkt) bedeutet:
beliebiges Zeichen. Gefunden werden" Haus", "Maus" und" Laus".
6. Es werden die Teiltexte gesucht, die mit einem beliebigen Zeichen Zeichen A, Beginn
beginnen und mit" a us" enden. Dies gilt allerdings nur für Teiltexte ,
die zu Beginn des untersuchten Texts stehen. Das Zeichen" bedeu-
A"

tet in diesem Zusammenhang: zu Beginn. Gefunden wird nur "H aus" .


7. Es werden die Teiltexte gesucht, die mit einem beliebigen Zeichen Zeichen $
beginnen und mit" a us" enden. Dies gilt allerdings nur für Teiltexte ,
die am Ende des untersuchten Texts stehen. Das Zeichen" $ " bedeutet

8.
in diesem Zusammenhang: am Ende. Gefunden wird nur " La us".
Basis für die nächsten drei regulären Ausdrücke ist der Text" 0172-
445633". Es wird als Teiltext eine der Ziffern von Obis 2 gesucht.
Suche nach Ziffern I
Zusammenhängende Bereiche können sich also auch auf Ziffern
beziehen. Gefunden werden die Ziffern 0, 1 und 2.
9. Es wird als Teiltext ein Zeichen gesucht, das nicht im Ziffernbereich
von Obis 2 liegt. Gefunden werden alle Ziffern außerhalb von Obis
2 sowie alle Nichtziffern.
10. Es wird als Teiltext eines der Zeichen aus der angegebenen Menge
von Zeichen gesucht. Gefunden werden alle Zeichen sowie Ziffern
aus dem Bereich 0, 4, 7 oder" - ".
11. Basis für die letzten sechs regulären Ausdrücke ist der Text" a a und Zeichen *
aba und abba und abbba und aca". An diesem Text soll im Vergleich
das verhalten bei Wiederholungen von Zeichen verdeutlicht werden.
Gefunden werden alle Teiltexte, die aus folgender Zeichenfolge
°
bestehen: ein "a", eine beliebige Anzahl (auch möglich) des Zei-
chens "b", wiederum ein "a". Der "*" (Stern) bedeutet: beliebige
Wiederholungszahl.
12. Gefunden werden alle Teiltexte, die aus folgender Zeichenfolge Zeichen +
bestehen: ein" a " , mindestens einmal das Zeichen" b" , wiederum ein
"a". Das "+" (Plus) bedeutet: beliebige Anzahl von Wiederholungen,
mindestens eine.

221
8 I Verschiedene Module

Zeichen? 13. Gefunden werden alle Teiltexte, die aus folgender Zeichenfolge
bestehen: ein "a", keinmal oder einmal das Zeichen "b", wiederum
ein "a". Das Fragezeichen ? bedeutet in diesem Zusammenhang:
keine oder eine Wiederholung.
Geschweifte 14. Gefunden werden alle Teiltexte die aus folgender Zeichenfolge beste-
Klammern hen: ein "a", zweimal oder dreimal das Zeichen "b", wiederum ein
" a ". Die geschweiften Klammern bieten die Möglichkeit, die
gewünschte Anzahl an Wiederholungen anzugeben.
15. Gefunden werden alle Teiltexte, die aus folgender Zeichenfolge
bestehen: ein" a ", anschließend so viele beliebige Zeichen wie mög-
lich, wiederum ein "a". Da der durchsuchte Text mit einem "a"
beginnt und einem "a" endet, wird genau eine Zeichenfolge gefun-
den.
16. Gefunden werden alle Teiltexte, die aus folgender Zeichenfolge
bestehen: ein" a " , anschließend so wenig beliebige Zeichen wie mög-
lich, wiederum ein "a". Es wird eine ganze Reihe von Zeichenfolgen
gefunden, die dazu passen.

8.4.2 Ersetzen von Teiltexten


subO Die Methode sub() ersetzt alle Teiltexte, die zum regulären Ausdruck
passen, durch einen anderen Text. Zur deutlicheren Darstellung werden
in diesem Programm die gleichen regulären Ausdrücke eingesetzt wie im
vorherigen Programm. Alle Teiltexte, die gemäß dem Ausdruck gefun-
den werden, werden durch "x" ersetzt.
lf Modul
import re

lf 1: Exakter Text
tx ~ "Haus und Maus und Laus"
print(tx)
txneu ~ [Link]("Maus","x",tx)
print("l: ", txneu)

lf 2: Wahl zwischen bestimmten Zeichen


txneu ~ [Link]("[HIMJaus","x",tx)
print ("2: ", txneu)

# 3: alle Buchstaben aus Bereich


txneu ~ [Link]("[L-MJaus","x",tx)
print("3: ", txneu)

222
Reguläre Ausdrücke I 8.4

# 4: alle Buchstaben nicht aus Bereich


txneu ~ [Link]("[AL M]aus","x",tx)
print("4: ", txneu)

Ir 5: Beliebiges Zeichen
txneu ~ [Link](".aus","x",tx)
print( "5: ", txneu)

# 6: Suchbegriff nur am Anfang des Textes


txneu ~ [Link]("[Link]","x",tx)
print("6: ", txneu)

# 7: Suchbegriff nur am Ende des Textes


txneu ~ [Link](".aus$","x",tx)
print( "7: ", txneu)
pr i nt ( )

# 8: alle Ziffern aus Bereich


tx ~ "0172-445633"
print (tx)
I
txneu ~ [Link]("[0-2]","x",tx)
print( "8: ", txneu)

# 9: alle Zeichen nicht aus Ziffernbereich


txneu ~ [Link]("[AO-2]","x",tx)
print ("9: ", txneu)

# 10: alle Zeichen oder Ziffern, die angegeben sind


txneu ~ [Link]("[047-]","x",tx)
print("10: ", txneu)
pr i nt ( )

Ir 11: Wiederholung, beliebig oft


tx ~ "aa und aba und abba und abbba und aca"
print(tx)
txneu ~ [Link]("ab*a","x",tx)
print("l1: ", txneu)

# 12: Wiederholung, 1 oder mehr


txneu ~ [Link]("ab+a","x",tx)
print("12: ", txneu)

# 13: Wiederholung, 0 oder 1


txneu ~ [Link]("ab?a","x",tx)
print("13: ", txneu)

223
8 I Verschiedene Module

# 14: Wiederholung, m bis n


txneu ~ [Link]("ab{2,3}a","x",txl
print( "14: ", txneul

# 15: Wiederholung der max. Menge von Zeichen


tx ~ "aa und aba und abba und aca und addda"
txneu ~ [Link]("a.*a","x",txl
print("15: ", txneul

# 16: Wiederholung der min. Menge von Zeichen


txneu ~ [Link]("a.*?a","x",txl
print( "16: ", txneul

Listing 8.14 Datei [Link]

Die Ausgabe dieses Programms sieht wie folgt aus:


Haus und Maus und Laus
1 : Haus und x und Laus
2 : x und x und Laus
3: Haus und x und x
4: x und Ma us und Laus
5 : x und x und x
6 : x und Ma us und Laus
7 : Haus und Ma us und x

0172-445633
8: xx7x-445633
9 : 01 x 2xxxxxxx
10: xl x2xxx5633

aa und aba und abba und abbba und aca


11: x und x und x und x und aca
12: aa und x und x und x und aca
13: x und x und abba und abbba und aca
14: aa und aba und x und x und aca
15: x
16: x und x und x und x und x

224
9 Dateien

Die dauerhafte Speicherung von Daten kann in einfachen Dateien oder in


Datenbanken vorgenommen werden. In diesem Abschnitt lernen Sie ver-
schiedene Methoden zur Speicherung von Daten in Dateien kennen.

Abschließend wird das bereits bekannte Spiel in einer Version vorge- Highscore
stellt, die das Abspeichern von Spielergebnissen in einer Highscore-Datei speichern

ermöglicht.

9.1 Dateitypen
Bei der Ein- und Ausgabe von Daten in Dateien sollte man wissen, wel-
cher Dateityp vorliegt und welche Zugriffs art man verwenden kann. Man
kann zwischen folgenden Zugriffsarten unterscheiden:
I
~ Sequenzieller Zugriff: Diese Möglichkeit wird bei einer Datei bevor- Sequenziell
zugt, deren einzelne Zeilen unterschiedlich lang sind und jeweils mit
einem Zeilenumbruch beendet werden. Der Inhalt der Datei kann mit
einem einfachen Editor bearbeitet werden. Die Zeilen werden rein
sequenziell gelesen und geschrieben. Der direkte Zugriff auf eine
bestimmte Zeile ist nicht möglich, da die Länge der Vorgängerzeilen
nicht bekannt ist.
~ Wahlfreier Zugriff: Diese Möglichkeit hat man bei einer Datei, die Wahlfrei
Datensätze beinhaltet. Zeilenumbrüche können, müssen aber nicht
existieren. Die Länge und Struktur eines Datensatzes sollte bekannt
sein oder innerhalb der Datei an einer vereinbarten Stelle stehen. Die
Zeilen können direkt gelesen und verändert werden, da man den Ort
jedes Datensatzes berechnen kann.
~ Binärer Zugriff: Diese Zugriffsmöglichkeit steht für alle Dateitypen Binär
zur Verfügung. Man arbeitet mit den reinen Bytefolgen, diese können
mithilfe eines darauf angepassten Python-Programms gelesen oder
verändert werden. Allerdings kann dies zur Folge haben, dass die
Dateien nicht mehr mit den zugehörigen Anwendungsprogrammen
gelesen werden können. Überschreibt man beispielsweise in einer

225
9 I Dateien

Orade-Datenbank die Stelle, an der die Anzahl der Datensätze einer


bestimmten Tabelle steht, so kann dies dazu führen, dass diese Tabelle
oder mehrere Tabellen zerstört werden.

Dateistruktur ohne Kenntnis der Struktur einer Datei ist es daher nicht möglich, sie
bekannt korrekt zu bearbeiten. Außer den genannten Typen gibt es auch Misch-
formen.

9.2 Öffnen und Schließen einer Datei

openO Eine Datei, die bearbeitet werden soll, muss vorher geöffnet werden.
Dies geschieht mithilfe der eingebauten Funktion open ( ). Dabei werden
der Name der Datei (eventuell mit Pfadangabe) und der Öffnungsmodus
angegeben.

Pfad zur Datei Es wird davon ausgegangen, dass sich die zu öffnende Datei im gleichen
Verzeichnis wie das Python-Programm befindet. Anderenfalls muss der
absolute oder relative pfad zur Datei angegeben werden. Der relative
pfad kann wie folgt angegeben werden:

zur Datei [Link] im Unterverzeichnis unt unt/ei n. txt


zur Datei [Link] im übergeordneten Verzeichnis .. /[Link]
zur Datei [Link] im parallelen Verzeichnis neb .. /neb/ei n. txt

Tabelle 9.1 Relativer Pfad

Pfad mit / Hinweis


Bei Python unter Windows ist sowohl der Forward-Slash (I) als auch der Back-
Slash (\) zum Verzeichniswechsel erlaubt. Häufig wird ein Dateizugriff im
Zusammenhang mit Internet-Server-Programmierung genutzt. Im Internet
herrschen Unix-Server vor, daher wird hier die Unix-freundliche Variante mit /
(Forward-Slash) vorgestellt.

Einige Öffnungsmodi:

eWth' Erläuterung
Öffnen zum Lesen (kann auch weggelassen werden, Standard)
w Öffnen zum (Über-)Schreiben
Öffnen zum zusätzlichen Schreiben (Anhängen) am Ende der Datei
r+ Öffnen zum Lesen und Schreiben, aktuelle Position am Anfang

Tabelle 9.2 Öffnungsmodi

226
Sequenzielle Dateien I 9·3

Erläuterung
w+ Öffnen zum Lesen und Schreiben, Datei wird geleert
a+ Öffnen zum Lesen und Schreiben, aktuelle Position am Ende
b Eine zusätzliche Angabe, sie dient zum Öffnen einer Datei, die gelesen
oder geschrieben werden soll; im Binärmodus; siehe auch Abschnitt
9.5

Tabelle 9.2 Öffnungsmodi (Forts.)

Rückgabewert der Funktion open ( ) ist ein Dateiobjekt, das für den wei- Dateiobjekt
teren Zugriff auf die Datei verwendet wird.

In jedem Dateiobjekt ist die aktuelle Zugriffsposition gespeichert. Dies ist seekO
die Position, an der aktuell gelesen oder geschrieben wird. Sie verändert
sich mit jedem Lese- oder Schreibvorgang. Außerdem kann sie mit der
Funktion seek() verändert werden, ohne lesen und schreiben zu müs-
sen.

Nach der Bearbeitung der Datei muss diese mit der Funktion cl ose()
geschlossen werden. Wird die Datei nicht geschlossen, ist sie eventuell
für weitere Zugriffe gesperrt.
doseO

I
9.3 Sequenzielle Dateien

Dateien können sequenziell beschrieben oder gelesen werden.

9.3.1 Sequenzielles Schreiben


Zum Schreiben in eine Datei muss die Datei zunächst mit der Funktion Modus »w«
open() und dem Öffnungsmodus "w" geöffnet werden. Wenn die Datei
noch nicht existiert, wird sie in diesem Moment erzeugt. Achtung: Wenn
sie bereits existiert, wird sie ohne Vorwarnung überschrieben!

Beim Öffnen einer Datei im Schreibmodus kann ein Laufzeitfehler auf- Datei schreiben
treten (zum Beispiel beim Schreiben auf ein schreibgeschütztes Medium
oder ein nicht vorhandenes Laufwerk). Daher sollte hier eine Ausnahme-
behandlung durchgeführt werden.

Anschließend kann man mit der Funktion write() einzelne Strings und writeO,
mit der Funktion wr ite 1 i nes ( ) eine Liste von Strings in die Datei schrei- writelinesO

ben. zahlen können mithilfe der Funktion s t r () in einen String umge-

227
9 I Dateien

wandelt werden. Das Zeichen \ n (= new line) für das Zeilenende muss
jeweils hinzugefügt werden.
import sys

# Zugriffsversuch
try:
d ~ open("[Link]","w")
except:
print("Dateizugriff nicht erfolgreich")
[Link](O)

# Schreiben von einzelnen Strings, mit Zeilenende


[Link]("Die erste Zeile\n")
for i in range(2,II,2):
[Link](str(i) + " ")
[Link]("\n")

# Schreiben einer Liste


x ~ ["abc\n", str(12/7)+"\n", "xyz\n"]
[Link](x)

# Schliessen der Datei


[Link]()

Listing 9.1 Datei [Link]

Die Datei p0901 aus. txt hat anschließend den folgenden Inhalt:
Die erste Zeile
2 4 6 8 10
abc
1.71428571429
xyz

Zur Erläuterung:
writeO ~ Zunächst wird eine einzelne Textzeile mit der Funktion wr i te ( ) in die
Datei geschrieben.
~ Anschließend werden die Zahlen von 2 bis 10 in Schritten von 2 in
Strings umgewandelt und in die Datei geschrieben.
~ Nach jeder Ausgabezeile wird ein Zeilenende zusätzlich ausgegeben.
writelinesO ~ Die Liste x wird erzeugt. Die Elemente sind Strings, die mit dem Zei-
lenende-Zeichen enden. Diese Liste wird mit der Funktion wr ite-
1 i nes ( ) in die Datei geschrieben.

228
Sequenzielle Dateien I 9·3

Hinweis Modus »a«


Verwendet man beim Öffnen der Datei den Öffnungsmodus "a" statt "w" Cd ~
open("[Link]","a"), so werden die Ausgaben an den bisherigen
Dateiinhalt angehängt. Die Datei wird also immer größer.

9·3·2 Sequenzielles Lesen


Die Zeilen einer sequenziellen Datei können mit den Funktionen read - Datei lesen
1 ines(), readl ine() oder read() gelesen werden:

~ Die Funktion read 1 i nes ( ) liest alle Zeilen der Datei in eine Liste von readlinesO
Strings.
~ Die Funktion readl ine() liest jeweils eine einzelne Zeile einer Datei readlineO
in einen String.
~ Die Funktion read() liest alle Zeilen der Datei in einen String. readO

Beispiel 1

Zunächst werden alle Zeilen einer Datei mithilfe der Funktion read-
1 i nes ( ) in eine Liste gelesen:
import sys
I
# Zugriffsversuch
try:
d ~ open("[Link]")
except:
print("Dateizugriff nicht erfolgreich")
[Link](O)

# Lesen aller Zeilen in eine Liste


allezeilen ~ [Link]()

# Schliessen der Datei


[Link]()

# Ausgabe und Summierung der Listenelemente


summe ~ 0
for zeile in allezeilen:
print(zeile. end~"")
summe +~ float(zeile)

# Ausgabe der Summe


print("Summe:". summe)
Listing 9.2 Datei [Link]

229
9 I Dateien

Die Datei [Link] hat folgenden Inhalt:


6
2.5
4

Die Ausgabe des Programms lautet:


6
2.5
4
Summe: 12.5

Zur Erläuterung:

openO ~ Zunächst muss die Datei mithilfe der Funktion open () zum Lesen
geöffnet werden. Der Öffnungsmodus kann in diesem Fall weggelas-
sen werden.
~ Gelingt das öffnen der Datei nicht, so tritt eine Ausnahme auf. Dies
geschieht beispielsweise, wenn
~ die Datei nicht existiert,
~ der Name der Datei falsch geschrieben wurde oder
~ sich die Datei in einem anderen Verzeichnis befindet.
readlinesO ~ Die Funktion readl i nes ( ) wird auf das Dateiobjekt angewendet und
ergibt eine Liste von Strings. Jeder String beinhaltet eine Zeile inklu-
sive dem Zeichen für Zeilenende. Die Strings können unterschiedlich
lang sein.
doseO ~ Nach dem Lesen wird die Datei mit cl ose() geschlossen.
~ Alle Elemente der Liste können mit einer fo r-Schleife bearbeitet wer-
den. Im vorliegenden Beispiel werden sie auf dem Bildschirm ausge-
geben und in Zahlen umgewandelt. Da das Zeichen für das Zeilenende
bereits vorhanden ist, sollte bei der Ausgabe kein zusätzliches Zeile-
nende-Zeichen ausgegeben werden, da sonst unnötige Leerzeilen ent-
stehen.
~ Die Elemente der Liste werden mithilfe der Funktion fl oa t () in Zah-
len umgewandelt und anschließend summiert.
~ Die Summe wird ausgegeben.

Beispiel 2
Im folgenden Programm werden einzelne Zeilen einer Datei mithilfe der
Funktion re a d1 i ne ( )gelesen:

23°
Sequenzielle Dateien I 9·3

import sys

# Zugriffsversuch
try:
d ~ open("[Link]")
except:
print("Dateizugriff nicht erfolgreich")
[Link](O)

# Lesen und Ausgabe einzelner Zeilen


zeilel ~ [Link]()
print(zeilel. end~"")
zeile2 ~ [Link]()
print(zeile2. end~"")

# Summierung und Ausgabe


summe ~ float(zeilel) + float(zeile2)
print("Summe:". summe)

# Schliessen der Datei


[Link]()

Listing 9.3 Datei [Link]


I
Die Ausgabe des Programms lautet:
6
2.5
Summe: 8.5

Zur Erläuterung:

~ Nach dem erfolgreichen öffnen der Datei ist die aktuelle Leseposition
der Anfang der ersten Zeile.
~ Die Funktion re a d 1 in e ( ) ergibt einen String, der eine Zeile inklusive readlineO
dem Zeichen für Zeilenende beinhaltet.
~ Nach einem Aufruf von readl ine() ist die aktuelle Leseposition der
Anfang der nächsten Zeile. Daher wird beim zweiten Aufruf die
zweite Zeile gelesen usw.

Beispiel 3
Auch mit der Funktion re a d 1 in e ( ) können alle Zeilen einer Datei gele-
sen werden. Dazu ist es notwendig, das Ende der Datei zu erkennen. Zu

231
9 I Dateien

diesem Zweck kann der von re a d 1 i ne () zurückgelieferte String unter-


sucht werden.

Ein Beispielprogramm:

import sys

# Zugriffsversuch
try:
d ~ open("[Link]")
except:
print("Dateizugriff nicht erfolgreich")
[Link](O)

# Lesen, Ausgabe und Summierung aller Zeilen


summe ~ 0
zeile ~ [Link]()
while zeile:
summe +~ float(zeile)
print(zeile, end~"")
zeile ~ [Link]()

# Ausgabe der Summe


print("Summe:", summe)

# Schliessen der Datei


[Link]()

Listing 9.4 Datei [Link]

Die Ausgabe des Programms:

6
2.5
4
Summe: 12.5

Zur Erläuterung:

~ Über eine whi 1e-Schleife wird das Lesen der Zeilen gesteuert.
Dateiende ~ Wenn das Dateiende noch nicht erreicht wurde, ist der String z nicht
erkennen leer. Die Bedingung wh i 1e z ist somit wahr und die Schleife wird wei-
ter ausgeführt.
~ Wurde das Dateiende erreicht, so ist der String z leer. Die Bedingung
wh i 1e z ist somit falsch, und das Programm beendet die Schleife.

232
Sequenzielle Dateien I 9·3

Beispiel 4
Die Funktion read() liest den gesamten Inhalt einer Datei in einen
String. Dieser muss anhand des Zeilenende-Zeichens in einzelne Zeilen
zerlegt werden.

Ein Beispielprogramm:
import sys

# Zugriffsversuch
try:
d ~ open("[Link]")
except:
print("Dateizugriff nicht erfolgreich")
[Link](O)

# Lesen des gesamten Texts


gesamtertext ~ [Link]()

# Schliessen der Datei


[Link]()

# Umwandeln in eine Liste


I
zeilenliste ~ [Link](chr(10))

# Summieren und Ausgeben


summe ~ 0
for zeile in zeilenliste:
if zeile:
summe +~ float(zeile)
print(zeile)

# Summe ausgeben
print("Summe:", summe)

Listing 9.5 Datei [Link]

Die Ausgabe des Programms:


6
2.5
4

Summe: 12.5

233
9 I Dateien

Zur Erläuterung:

readO ~ Alle Zeilen werden mithilfe der Funktion read() in einen String gele-
sen.
splitO ~ Der String wird anhand des Zeilenende-Zeichens (Unicode-Zahl 10)
mithilfe der Funktion s pli t ( ) in einzelne Zeilen zerlegt.
~ Über eine whi 1e-Schleife wird das Lesen der Zeilen gesteuert.
~ Die Zeilen werden summiert und ausgegeben, anschließend wird die
Summe ausgegeben.

9.3.3 CSV-Datei schreiben


Comma-separated CSV-Dateien (CSV = Comma-separated Values) sind Textdateien, in denen
Values ein Datensatz pro Zeile steht. Die Daten des Datensatzes sind durch fest-
gelegte Zeichen (wie Semikolon) voneinander getrennt. Solche Dateien
haben meist die Dateiendung .csv. Sie können auch von anderen Pro-
grammen (zum Beispiel Microsoft Excel) erkannt und richtig genutzt
werden.

Ein Beispiel, in dem eine einfache Liste und eine zweidimensionale Liste
als CSV-Datensätze in eine Datei geschrieben werden:

import sys

# Zugriffsversuch
try:
d ~ open("[Link]","w")
except:
print("Dateizugriff nicht erfolgreich")
[Link](O)

# Schreiben einer Liste als CSV-Datensatz


li ~ [42, "Maier", 3524.52J
[Link](str(li[OJ) + ";" + li[lJ + ";"
+ str(1i[2J).replace(".",",") + "\n")

# Schreiben einer zweidim. Liste als Datensatztabelle


dli ~ [[55, "Warner", 3185.00J, [57, "Schulz", 2855.20JJ
for element in dli:
[Link](str(element[OJ) + ";"
+ element[lJ + ";"
+ str(element[2J).replace(".",",") + "\n")

234
Sequenzielle Dateien I 9·3

# Schliessen der Datei


[Link]()

Listing 9.6 Datei [Link]

Die Ausgabedatei [Link] hat anschließend den folgenden Inhalt:


42;Maier;3524.52
55;Warner;3185.0
57;Schulz;2855.2

Zur Erläuterung:

~ Nach dem erfolgreichen Öffnen werden die einzelnen Elemente der writeO
einfachen Liste mithilfe der Funktion wr ite ( ) in die Datei geschrie-
ben.
~ Zwischen den einzelnen Elementen wird jeweils ein Semikolon ein- Semikolon
gefügt.
~ Handelt es sich bei einem Element um eine Zahl, so wird diese mit-

~
hilfe der Funktion s t r ( ) in eine Zeichenkette umgewandelt.
Bei Zahlen mit Nachkommastellen wird anschließend der Dezimal-
punkt mithilfe der Funktion repl ace() in ein Komma verwandelt.
Dezimalpunkt I
Damit können diese Zahlen problemlos von einer deutschen Version
von Microsoft Excel eingelesen werden.
~ Die Struktur der Daten muss also bekannt sein. Darüber hinaus müs-
sen die Daten der verschiedenen Datentypen unterschiedlich verar-
beitet werden, um einen korrekten Export zu gewährleisten.

Falls Excel unter Windows installiert ist, genügt ein Doppelklick auf die Microsoft Excel
Ausgabedatei [Link], um den Inhalt als Excel-Tabelle darzustellen:

p0906

Einfügen Seitenlayout Formel

Abbildung 9.1 CSV-Datei in Excel

235
9 I Dateien

9.3.4 CSV-Datei lesen


Um den Inhalt einer CSV-Datei zu importieren, müssen auch Struktur
und Datentypen der Daten bekannt sein. Die CSV-Datei aus dem vorhe-
rigen Beispiel wird in Excel ergänzt und abgespeichert.

"I A I B C D

~ 42 Maier 3524, 52
-
2 55Tw arner 3185
--
3 5 ~chulz 2855,2
-
~ 98 Esser 3120,66
5

Abbildung 9.2 CSV-Datei in Excel, ergänzt

Die Datei wird mit dem folgenden Programm gelesen. Die Datensätze
werden in einer zweidimensionalen Liste abgelegt:
import sys

# Zugriffs versuch
try:
d ~ open("[Link] v ")
except:
print("Dateizugriff nicht erfolgreich")
[Link](O)

# Lesen des gesamten Texts


gesamtertext ~ [Link]()

# Schliessen der Datei


[Link]()

# Um wandeln in eine Liste von Zeilen


zeilenliste ~ [Link](chr(10))

# Jede Zeile umwandeln in Liste von int. string. float


1i ~ []
for zeile in zeilenliste:
if zeile:
zwliste ~ [Link](";")
[Link]([int(z wliste[O]).
zwliste[1].
fl oat(z wl i ste[2]. repl ace(".". "."))])
Dateien mit festgelegter Struktur I 9.4

Ir
Ausgabe
forpinli:
print("{O:d} {l} {2:.2f}".format(p[0J. p[1J. p[2]))

Listing 9.7 Datei [Link]

Das Programm erzeugt die Ausgabe:


42 Maier 3524.52
55 Warner 3185.00
57 Schulz 2855.20
98 Esser 3120.66

Zur Erläuterung:

~ Zunächst wird der gesamte Text der Datei mithilfe der Funktion readO
read() in einen String eingelesen.

~ Dieser String wird mithilfe der Funktion s pli t () und dem Zeile- splitO
nende-Zeichen (Unicode-Zahl 10) in eine Liste von Zeilen zerlegt.

~
Diese Liste enthält das Zeilenende-Zeichen nicht mehr.
Jedes Element der Liste, also jede Zeile, wird mithilfe der Funktion
s p 1 it ( ) und dem Semikolon-Zeichen in eine Zwischenliste (zwl i s te)
mit den einzelnen Daten zerlegt. Diese Zerlegung wird nur durchge-
I
führt, wenn die Zeile nicht leer ist.
~ Handelt es sich bei einem Element der Zwischenliste um eine Zahl, so
wird diese mithilfe der Funktion in t () oder mit der Funktion
f 1 0 a t ( ) umgewandelt.

~ Bei Zahlen mit Nachkommastellen wurde vorher das Komma mithilfe Dezimalpunkt
der Funktion repl ace() in einen Dezimalpunkt verwandelt. Damit
kann diese Zahl, die aus einer deutschen Version von Excel kommt,
problemlos weiter verarbeitet werden.
~ Zuletzt wird die zweidimensionale Liste zeilenweise, formatiert aus-
gegeben.

9.4 Dateien mit festgelegter Struktur

Wenn eine Datei formatiert beschrieben wird, ist ihre Struktur festge- Lesen
legt. Es ist genau bekannt, an welcher Stelle welche Information steht.
Somit können die gewünschten Informationen direkt aus der Datei gele-
sen werden, ohne die gesamte Datei Zeile für Zeile einlesen zu müssen.

237
9 I Dateien

Schreiben Außerdem ist es möglich, bestimmte Informationen punktuell zu verän-


dern, ohne den restlichen Inhalt der Datei zu beeinflussen. Beide Mög-
lichkeiten werden in den folgenden Abschnitten vorgeführt.

9.4.1 Formatiertes Schreiben


Formatieren Das formatierte Schreiben in eine Datei geschieht auf die gleiche Art und
Weise wie die formatierte Ausgabe. Es werden Datensätze gleicher Länge
und gleichen Aufbaus gebildet.

Editor Optional können Sie nach jedem Datensatz ein Zeilenende einfügen, um
die Datei in einem Editor leichter lesbar zu machen. Sie können die Datei
auch mithilfe eines Editors verändern, solange Sie sich an die festgelegte
Struktur halten.

Ein Beispiel:
import sys

# Zugriffsversuch
try:
d ~ open("[Link]","w")
except:
print("Dateizugriff nicht erfolgreich")
[Link](O)

# Tabelle mit verschiedenen Objekten


fm ~ "{O:04d}{1:)12}{2:4d}{3:8.2f} Euro{4:8.2f} Euro\n"
artname ~ {23:"Apfel", 8:"Banane", 42:"Pfirsich"}
anzahl {23:1. 8:3, 42:5)
epreis ~ {23:2.95, 8:1.45, 42:3.05}

[Link]("{O:)4}{1:)12}{2:)4}{3:)13}{4:)13}\n".format
("Nr","Name","Anz","EP","GP"))
for x in 23, 8, 42:
d. write( fm. format(x, a rtname[xJ. anzahl[xJ.
eprei s[x], anzahl [x] * eprei s[x]))

# Schliessen der Datei


[Link]()

Listing 9.8 Datei [Link]


Dateien mit festgelegter Struktur I 9.4

Anschließend sieht die Datei [Link] wie folgt aus:


Nr Name Anz EP GP
0023 Apfel 2.95 Euro 2.95 Euro
0008 Banane 3 1.45 Euro 4.35 Euro
0042 Pfirsich 5 3.05 Euro 15.25 Euro

Zur Erläuterung:

~ Die Datei wird zum Schreiben geöffnet.

~ Die einzelnen Datensätze werden mithilfe der Funktion f 0 rma t ( ) for- formatO
matiert, wie in Abschnitt 5.2.2, »Formatierte Ausgabe«, beschrieben.
Zusätzlich wird jeweils ein \ n als Zeilenende angefügt.

9.4.2 Lesen an beliebiger Stelle


Die Funktion seek() ermöglicht die Veränderung der aktuellen Lese- seekO
oder Schreibposition innerhalb der Datei. Sie kann mit einem oder zwei

I
Parametern aufgerufen werden. Wird sie mit einem Parameter aufgeru-
fen, so ist dies der Abstand in Byte, gemessen vom Dateianfang. Der
Dateianfang entspricht dem Wert 0, der Aufruflautet dann: d. seek (0).

Diese Position wird direkt erreicht, ohne Lesen der Informationen vor
der Position. Ausgehend von der erreichten Position kann gelesen oder
geschrieben werden.

Die Funktion seek( ) wird im vorliegenden Beispiel zusammen mit einer read
Variante der Funktion rea d ( ) eingeführt. Diese Funktion gestattet neben «Byteanzahl»

dem Einlesen einer ganzen Datei (wie am Anfang dieses Kapitels gezeigt)
auch das Einlesen einer bestimmten Anzahl von Byte, falls die Funktion
mit der entsprechenden Zahl als Parameter angegeben wird.

Ein Beispiel:
import sys, os

# Zugriffsversuch
try:
d ~ open("[Link]")
except:
print("Dateizugriff nicht erfolgreich")
[Link](O)

# Gezieltes Lesen
for i in range(1,4):

239
9 I Dateien

Ir Nr Lesen
[Link](48*i)
nr ~ int([Link](4))

IrEP Lesen
[Link](20 + 48*i)
ep ~ float([Link](8))

Ir Ausgabe
print("Artikel Nr:", nr, EP: ", ep)

# Schliessen der Datei


[Link]()
Listing 9.9 Datei [Link]

Die Ausgabe lautet:


Artikel Nr: 23 , EP: 2.95
Artikel Nr: 8 , EP: 1.45
Artikel Nr: 42 , EP: 3.05

Die Datei ist wie folgt aufgebaut:

Datensatz ~ Jeder Datensatz (also jede Zeile) hat eine Gesamtlänge von 48 Byte,
inklusive der zwei Zeichen, die durch das \ n erzeugt werden.
~ Die erste Zeile beginnt an Position 0 und beinhaltet die Überschrift.
Die zweite Zeile beginnt an Position 48 und beinhaltet den ersten
Datensatz. Die dritte Zeile beginnt an Position 96 und beinhaltet den
zweiten Datensatz usw.

Zur Erläuterung des Programms:

~ Die Datei wird zum Lesen geöffnet.


seek«Position» ~ In einer fo r-Schleife werden mithilfe der Funktion see k ( ) nacheinan-
der Positionen im ersten, zweiten und dritten Datensatz erreicht. Dies
sind
~ die Positionen 48, 96 und 144 für den Anfang jedes Datensatzes
zum Lesen der Artikelnummer und
~ die Positionen (48 + 20) = 68, (96 + 20) = 116 und (144 + 20) =
164 zum Lesen des Einzelpreises.
read ~ An diesen Positionen werden die nächsten 4 Byte (die Artikelnum-
«Byteanzahl» mer) beziehungsweise die nächsten 8 Byte (der Einzelpreis) gelesen.

240
Dateien mit festgelegter Struktur I 9.4

Es handelt sich dabei jeweils um Zeichenketten, die mithilfe von


int() und fl oat() in Zahlen umgewandelt werden.
~ Anschließend werden die zahlen ausgegeben.

9.4.3 Schreiben an beliebiger Stelle


Man kann eine Datei im Modus r+ öffnen. Anschließend kann sie gele- Modus r+
sen und beschrieben werden. Im folgenden Programm wird der aktuelle
Einzelpreis eines bestimmten Artikels gelesen, verändert und wieder in
die Datei geschrieben.
import sys, os

# Zugriffsversuch
try:
d ~ open("[Link]", "r+")
except:
print("Dateizugriff nicht erfolgreich")
[Link](O)

# Lesen des Einzelpreises


[Link](68)
I
ep_str ~ [Link](8)
ep ~ float(ep_str)

# Schreiben des Einzelpreises


[Link](68)
ep ~ ep + 0.2
[Link]("{0:8.2f}".format(ep))

# Schliessen der Datei


[Link]()

Listing 9.10 Datei [Link]

Anschließend sieht die Datei [Link] wie folgt aus:


Nr Name Anz EP GP
0023 Apfel 3.15 Euro 2.95 Euro
0008 Banane 3 1.45 Euro 4.35 Euro
0042 Pfirsich 5 3.05 Euro 15.25 Euro

Der Einzelpreis des Artikels 23 im ersten Datensatz wurde von 2,95 € auf
3,15 € erhöht.

241
9 I Dateien

Zur Erläuterung:

~ Die Datei wird im Modus r+ geöffnet.


Lesen ~ Der Einzelpreis steht als Zeichenkette in den 8 Byte ab der Position
68. Die Zeichenkette wird gelesen und in eine Zahl umgewandelt.
Schreiben ~ Diese zahl wird verändert, als Zeichenkette mit einer Breite von 8
Byte formatiert und ab der Position 68 in die Datei geschrieben.

9.5 Modul pickle


Das Modul pi ckl e dient zur Serialisierung und Deserialisierung von
Objekten. Dies können Objekte der eingebauten Objekttypen oder
Objekte eigener Klassen sein.

{De-}Seriali- Mithilfe der (De-)Serialisierung können Objekte aus Programmen als


sierung Bytefolge auf einfache Art und Weise in Dateien gespeichert oder aus
Dateien wieder in Programme geladen werden.

Beim Speichern wird der Typ des Objekts mitgespeichert, sodass beim
Laden der Typ bekannt ist.

9.5.1 Objekte in Datei schreiben


[Link] Zum Schreiben (Serialisieren) von Objekten dient die Methode dump ( ).
Im folgenden Beispiel werden das Objekt eines eingebauten Objekttyps
und das Objekt einer eigenen Klasse nacheinander in einer Datei gespei-
chert.
import pickle

# Definition der Klasse Fahrzeug


class Fahrzeug:
def __ init __ (self, bez, gel:
[Link] ~ bez
[Link] ~ ge
def str (self):
return [Link] + " " \
+ str([Link]) + " km/ho

# Zugriffsversuch
try:
d ~ open("[Link]", "wb")

242
Modul pickle I 9·5

except:
print("Dateizugriff nicht erfolgreich")
[Link](O)

# Eingebautes Objekt
x ~ ([ 4 , " abc" ,8], "xy z" )
print(x)
[Link](x, d)

# Objekt der eigenen Klasse


opel ~ Fahrzeug( "Opel Admi ral", 40)
print(opel)
[Link](opel, d)

lf Va ri abl e Anzahl an Objekten


[Link](3, d)
[Link]("Berlin", d)
[Link]("Hamburg", d)
[Link]("Dortmund", d)

# Datei schliessen
[Link]()
I
Listing 9.11 Datei [Link]

Die Ausgabe lautet:


([4, 'abc', 8]' 'xyz')
Opel Admi ral 40 km/h

Zur Erläuterung:

~ Das Programm beginnt mit der Definition der eigenen Klasse Fa h r -


zeug, die Sie bereits aus Kapitel 6 zur objektorientierten Programmie-
rung kennen.
~ Die Datei wird im Modus wb geöffnet, also zum Schreiben im Binär- Modus wb
modus. Als zusätzlicher Hinweis auf den Binärmodus wird die Datei-
endung .bin gewählt.
~ Es wird eine zweidimensionale Liste erzeugt. Diese wird zur Kontrolle
auf dem Bildschirm ausgegeben.
~ Mithilfe der Funktion d ump () aus dem Modul pi c k1e wird die Liste [Link]
binär in der geöffneten Datei gespeichert. Der erste Parameter der
Funktion ist der Name des Objekts, der zweite Parameter ist das
Dateiobjekt.

243
9 I Dateien

~ Es wird ein Objekt der Klasse Fahrzeug erzeugt. Dieses Objekt wird
zur Kontrolle auf dem Bildschirm ausgegeben. Anschließend wird es
binär in der geöffneten Datei gespeichert.
Variable Anzahl ~ Zur Speicherung einer variablen Anzahl von Objekten (hier: drei Zei-
von Objekten chenketten) muss zunächst die Anzahl der Objekte gespeichert wer-
den. Anschließend können die Objekte selbst gespeichert werden.
Damit ist für ein Programm zum Laden der Objekte die Anzahl
bekannt (siehe nächster Abschnitt).

Modus ab Hinweis
Ein potenzieller Inhalt der Datei wird überschrieben. Es könnten auch Objekte
an vorhandene Objekte angehängt werden. Zu diesem Zweck hätten Sie die
Datei im Öffnungsmodus ab öffnen müssen.

9.5.2 Objekte aus Datei lesen


[Link] Objekte, die mithilfe der Funktion dump() in einer Datei gespeichert
wurden, können mithilfe der Funktion 1 0 a d () wieder in der gleichen
Reihenfolge aus der Datei in ein Programm übernommen werden.

Handelt es sich um ein Objekt einer eigenen Klasse, muss die Definition
dieser Klasse bekannt sein.

Es folgt ein Beispiel, in dem die beiden Objekte, die mit dem Programm
aus dem vorherigen Abschnitt serialisiert wurden, wieder deserialisiert
und in ein Programm übernommen werden.
import pickle

# Definition der Klasse Fahrzeug


class Fahrzeug:
def __ init __ (self, bez, gel:
[Link] ~ bez
[Link] windigkeit ~ ge
def str (self):
return [Link] + " " \
+ str([Link]) + " km/ho

# Zugriffs versuch
try:
d ~ open("[Link]", "rb")
except:
print("Dateizugriff nicht erfolgreich")
[Link](O)

244
Modul pickle I 9·5

# Eingebautes Objekt
x ~ [Link](d)
print(x)

# Objekt der eigenen Klasse


opel ~ [Link](d)
print(opel)

Ir Va ri abl e Anzahl an Objekten


anzahl ~ [Link](d)
for i in range(anzahl):
print([Link](d))

# Datei schliessen
[Link]()

Listing 9.12 Datei [Link]

Es wird die Ausgabe erzeugt:

([4, 'abc', 8]' 'xyz')


Opel Admi ral 40 km/h
Be rl in
I
Hamburg
Dortmund

Zur Erläuterung:

~ Man kann erkennen, dass die Objekte wieder originalgetreu geladen


werden.
~ Das Programm beginnt mit der Definition der eigenen Klasse Fa h r -
zeug.
~ Die Datei wird im Modus rb geöffnet, also zum Lesen im Binärmodus.
~ Mithilfe der Funktion 1 oad() aus dem Modul pi ckl ewerden nachei- [Link]
nander die Liste und das Objekt der Klasse Fahrzeug geladen.
~ Anschließend wird die Anzahl der nachfolgenden Objekte als Zahl Variable Anzahl
geladen (hier: 3). Damit ist für die nachfolgende Schleife die Anzahl
der zu ladenden Objekte bekannt.
~ Alle Objekte werden zur Kontrolle auf dem Bildschirm ausgegeben.

245
9 I Dateien

9.6 Bearbeitung mehrerer Dateien

Bisher wurde immer eine einzelne Datei bearbeitet, deren Name bekannt
ist. Häufig stellt sich aber die Aufgabe, eine ganze Reihe von Dateien aus
einem Verzeichnis zu bearbeiten, deren genauer Name und deren Anzahl
unbekannt sind.

[Link] Zu diesem Zweck kann man sich der Funktion gl ob() aus dem Modul
gl ob bedienen. Diese Funktion erzeugt eine Liste von Strings. Jeder die-
ser Strings beinhaltet einen Dateinamen.

Dateiliste Im folgenden Beispiel werden zunächst mit der Funktion gl ob( )


bestimmte Dateien aus dem aktuellen Verzeichnis in einer Liste gespei-
chert.
Anschließend werden diese Dateien der Reihe nach geöffnet und durch-
sucht. Wird ein bestimmter Suchtext gefunden, so wird der Name der
betreffenden Datei ausgegeben.
import glob

# Liste der Dateien


dateiliste ~ [Link]("p090*.py")

# Jedes Element der Liste durchsuchen


for datei in dateil i ste:
# Zugriffsversuch
try:
d ~ open(datei)
except:
print("Dateizugriff nicht erfolgreich")
continue

lf Text einlesen
gesamtertext ~ [Link]()

# Zugriff beenden
[Link]()

# Suchtext suchen
if [Link]("csv") !~ -1:
print(datei)

Listing 9.13 Datei p0913 .py


Informationen über Dateien I 9.7

Die Ausgabe lautet:


[Link]
[Link]

Zur Erläuterung:

~ Der Parameter der Funktion 9 lob () ist eine Zeichenkette , die als Fil- Platzhalter * ?
ter dient. Es können unter anderem die Platzhalter * (für mehrere
beliebige Zeichen) und? (für ein einzelnes beliebiges Zeichen) einge-
setzt werden.
~ Es wird nur nach Dateien gesucht, deren Name mit p090 beginnt und
mit. py endet
~ Jedes Element der erzeugten Liste ist ein Dateiname. Jede dieser
Dateien wird geöffnet. Falls das öffnen nicht erfolgreich war, wird
mit der nächsten Datei fortgefahren.
~ Der Inhalt der Datei wird mithilfe der Funktion read ( ) vollständig in readO
eine Zeichenkette eingelesen. Anschließend wird die Datei geschlos-

~
sen.
Diese Zeichenkette wird mithilfe der Funktion find() durchsucht.
Wird der Suchtext (hier »csv«) gefunden, so wird der Dateiname aus-
findO I
gegeben.

9.7 Informationen über Dateien

Die Funktion stat() aus dem Modul os liefert eine Reihe von Informa- [Link]
tionen über Dateien in Form eines Tupels. Ein Beispiel:
import os, time

# Informationstupel
tu ~ [Link]("[Link]")

# Elemente des Tupels


groesse ~ tu[6]
print("Byte:", groesse)

zugr ~ [Link](tu[7])
print("Letzter Zugriff:",
[Link]("%d.%m.%Y %H:%M:%S", zugr))

247
9 I Dateien

mod ~ time.10ca1time(tu[8])
print("Letzte Modifikation:",
[Link]("%d.%m.%Y %H:%M:%S", mod))

Listing 9.14 Datei [Link]

Die Ausgabe lautet:


Byte: 413
Letzter Zugriff: 28.12.2008 00:00:00
Letzte Modifikation: 28.12.2008 06:21:44

Zur Erläuterung:

Dateigröße ~ Das Element 6 des Tupels gibt die Größe der Datei in Byte an.
Zugriffszeitpunkt ~ Die Elemente 7 und 8 liefern den Zeitpunkt des letzten Zugriffs auf
die Datei und der letzten Änderung der Datei.
~ Beide Zeitangaben werden mithilfe der Funktionen 1 oca 1time ( ) und
strftime() formatiert ausgegeben.

9.8 Dateien und Verzeichnisse verwalten

Module os, shutil Die Module os und shut i 1 bieten weitere Funktionen zur Verwaltung
von Dateien und Verzeichnissen. Im folgenden Beispiel wird eine Datei
zunächst kopiert und später umbenannt.
import shuti 1, os, glob

lf Status 1
print(glob.g10b("i??[Link]"))

lf Datei kopi eren


shut i 1. copyfi 1 e( "p0908aus. txt", "p0909aus. txt")

lf Status 2
print(glob.g10b("i??[Link]"))

# Datei umbenennen
try:
[Link]("[Link]","[Link]")
except:
print("Feh1er")
Spiel, Version mit Highscore-Datei I 9.9

Ir Status 3
pr i nt ( 9 lob. 9 1 ob ( " i ?? a us . tx t " ) )

Listing 9.15 Datei [Link]

Die Ausgabe dieses Programms lautet:


[' p0901 aus. txt'. 'p0908aus. txt' ]
['[Link]'. '[Link]'. '[Link]']
Fehler
['[Link]'. '[Link]'. '[Link]']

Zur Erläuterung:

~ Die erste Zeile der Ausgabe gibt den Status 1 wieder: die ursprüng-
liche Liste der Dateien, deren Name mit dem Buchstaben i beginnt
und nach zwei weiteren beliebigen Zeichen mit [Link] endet.
~ Anschließend wird mithilfe der Funktion copyfi 1 e( ) aus dem Modul [Link]
shut i 1 die Datei [Link] kopiert. Die Kopie heißt [Link].

~
Falls die Datei [Link] bereits existiert, so wird sie ohne Vor-
warnung (!) überschrieben.
Die zweite Zeile der Ausgabe gibt den Status 2 wieder: die geänderte
Liste der Dateien nach dem Kopiervorgang.
I
~ Anschließend wird mithilfe der Funktion ren ame ( ) aus dem Modul os [Link]
die Datei p0909aus. txt umbenannt in p0901 aus. txt. Falls die Datei
p0901 aus. txt bereits existiert, tritt ein Laufzeitfehler auf.
~ Die letzte Zeile der Ausgabe gibt den Status 3 wieder: die Liste der
Dateien nach dem (eventuell nur versuchten) Umbenennen.

9.9 Spiel, Version mit Highscore-Datei

In dieser Spielversion wird zunächst nach dem Namen des Spielers Zeit messen
gefragt. Anschließend bekommt der Spieler fünf Additionsaufgaben mit
zahlen aus dem Bereich von 10 bis 30 gestellt. Pro Aufgabe hat er nur
einen Versuch. Ungültige Eingaben oder falsche Ergebnisse werden ein-
fach mit dem Text Falsch kommentiert und bewertet. Zuletzt wird die
Gesamtzeit angegeben, die der Spieler für die Lösungsversuche benötigt
hat.

Wenn der Spieler alle fünf Aufgaben richtig löst, werden sein Name und Highscore in
die Zeit in eine Highscore-Liste aufgenommen, die in einer Datei abge- Textdatei

speichert wird.

249
9 I Dateien

Eingabebeispiel
Die folgende Ausgabe zeigt einen typischen Durchlauf durch das Pro-
gramm:

Bitte eingeben (0: Ende. 1: Highscores. 2: Spielen): 1


P. Name Zeit
1. Bernd 8.59 sec
2. Marc 8.92 sec
Bitte eingeben (0: Ende. 1: Highscores. 2: Spielen): 2
Bitte geben Sie Ihren Namen ein (max. 10 Zeichen): Paul
Aufgabe 1 von 5: 26 + 21 47
*** Richtig ***
Aufgabe 2 von 5 : 26 + 24 50
*** Richtig ***
Aufgabe 3 von 5 : 27 + 22 49
*** Richtig ***
Aufgabe 4 von 5 : 10 + 29 39
*** Richtig ***
Aufgabe 5 von 5 : 19 + 28 47
*** Richtig ***
Ergebnis: 5 von 5 in 10.02 Sekunden. Highscore
P. Name Zeit
1. Bernd 8.59 sec
2. Marc 8.92 sec
3. Paul 10.02 sec
Bitte eingeben (0: Ende. 1: Highscores. 2: Spielen): 0

Zur Erläuterung:

~ Der Benutzer (P a u1) schaut sich zuerst die Highscores an. Dort gibt es
bereits zwei Einträge (Bernd und Marc).
~ Anschließend spielt er eine Runde, löst alle fünf Aufgaben richtig und
erscheint nun auch selbst im Highscore.
~ Er verlässt das Programm wieder.

9.9.2 Aufbau des Programms


Endlosschleife Das Programm beinhaltet ein Hauptprogramm und vier Funktionen. Im
Hauptprogramm wird innerhalb einer Endlosschleife ein Hauptmenü
aufgerufen. Der Spieler hat in diesem Hauptmenü die folgenden Mög-
lichkeiten:

25°
Spiel, Version mit Highscore-Datei I 9.9

~ Anzeige der Highscores


~ Spielen
~ Programm beenden

Die vier Funktionen des Programms sind:

~ Funktion hs_l es en ( ): Lesen der Highscores aus der Datei in eine Liste
~ Funktion hs_anzei gen (): Anzeigen der Highscore-Liste auf dem Bild-
schirm
~ Funktion hs_schrei ben(): Schreiben der Highscore-Liste in die Datei
~ Funktion s pie 1 ( ): Stellen der Aufgaben, Lösen, ermittelte Zeit gege-
benenfalls in Highscore-Liste einfügen

9.9.3 Code des Programms


Das folgende Listing zeigt zunächst den Beginn des Programms, mit der Daten lesen
Funktion zum Lesen der Highscore-Daten aus der Datei:

i! Modul e
import random. time. glob. pickle I
# Funktion Highscore Lesen
def hs_lesen():
# Liste wird hier erzeugt
global hs_liste

# Kein Highscore vorhanden. leere Liste


if not [Link]("[Link]"):
hs liste ~ [J
return

# Highscore vorhanden. laden


d ~ open("[Link]". "rb")
hs_liste ~ [Link](d)
[Link]()

Listing 9.16 Datei [Link], Teil 1 von 5

Zur Erläuterung:

~ Es werden die Module ra ndom (für den Zufallsgenerator), time (für die
Zeitmessung) und gl ob (für die Prüfung der Datei) benötigt.

251
9 I Dateien

Globale Liste ~ In der Liste hs_1iste stehen nach dem Einlesen aus der Datei die
Namen und Ergebniszeiten der Spieler. Da die Liste in dieser Funk-
tion erstmalig benutzt wird, aber im gesamten Programm benötigt
wird, muss sie hier mit gl oba 1 im globalen Namensraum bekannt
gemacht werden.
~ Falls die Datei mit den Highscores nicht vorhanden ist, wird eine leere
Liste erzeugt.
~ Ist die Datei vorhanden, so wird der gesamte Inhalt mithilfe der Funk-
tion 1oad() aus dem Modul pi ck1 e in die Liste hs_1 i ste gelesen.
~ Es folgt die Funktion zum Anzeigen des Highscores:
# Funktion Highscore Anzeigen
def hs_anzeigen():
# Highscore nicht vorhanden
i f not hs_1iste:
print("Keine Highscores vorhanden")
return

# Ausgabe Highscore
print(" P. Name Zeit")
for i in range(len(hs_1iste)):
print("{O:2d}. {1:10} {2:5.2f} sec".format
(i+l, hs_1iste[i][OJ. hs 1iste[i][1]))
if i >~ 9:
break

Listing 9.17 Datei [Link], Teil 2 von 5

Zur Erläuterung:
~ Falls die Highscore-Liste leer ist, wird eine entsprechende Meldung
angezeigt.
~ Ist die Liste nicht leer, so werden nach einer Überschrift die folgenden
Informationen formatiert ausgegeben: Platzierung, Name, Ergebniszeit
~ Es werden maximal 10 Highscores angezeigt.

Die Funktion zum Schreiben der Highscore-Liste in die Datei sieht wie
folgt aus:
# Funktion Highscore Schreiben
def hs_schreiben():
lf Zugri ff
d ~ open("[Link]","wb")

252
Spiel, Version mit Highscore-Datei I 9.9

pi c k1 e . d um p ( hs _1 ist e . d )
[Link]()

Listing 9.18 Datei [Link], Teil 3 von 5

Zur Erläuterung:
~ Die gesamte Liste wird mithilfe der Funktion d ump ( ) aus dem Modul
pi c k 1 e in die Datei geschrieben.
~ Es folgt die Funktion zum Spielen:
lf Funktion Spiel
def spiel():
# Eingabe des Namens
name input("Bitte geben Sie Ihren"
"Namen ein (max. 10 Zeichen): ")
name ~ name[0:10J

lf Initialisierung Counter und Zeit


richtig ~ 0
startzeit ~ [Link]()

lf 5 Aufgaben
I
for aufgabe in range(5):
# Aufgabe mit Ergebnis
a [Link](10.30)
b [Link](10.30)
c a + b

lf Ei ngabe
try:
zahl
~ int(input("Aufgabe "
+ str((aufgabe+l)) + " von 5: "
+ str(a) + " + " + str(b) +" "))
i f zahl ~~ c:
print("*** Richtig ***")
richtig +~ 1
else:
raise
except:
print("* Falsch *")

lf Auswertung
endzeit ~ [Link]()
differenz ~ endzeit-startzeit

253
9 I Dateien

print("Ergebnis: {O:d} von 5 in {1:.2f} Sekunden".


format(richtig, differenz), end ~ "")
i f richtig ~~ 5:
print(", Highscore")
else:
print(", leider kein Highscore")
return

# Mitten in Liste schreiben


gefunden ~ False
for i in range(len(hs_liste)):
# Einsetzen in Liste
i f differenz< hs_liste[iHl]:
hs_liste.insert(i, [name, differenz])
gefunden ~ True
break

# Ans Ende der Liste schreiben


if not gefunden:
hs_liste.append([name, differenz])

# Highscoreliste anzeigen
hs_anzeigen()

Listing 9.19 Datei [Link], Teil 4 von 5

Zur Erläuterung:
~ Nach der Eingabe des Namens wird dieser Name zur einheitlichen
Ausgabe auf maximal 10 Zeichen verkürzt.
~ Es folgen einige Programmteile, die bereits aus früheren Versionen
des Spiels bekannt sind: Stellen der fünf Aufgaben, Eingabe der
Lösungen, Bewerten der Lösungen, Messen der Zeit.
~ Es ist zu beachten, dass die Zahlenvariablen aufgabe, a und b für die
Funktion input ( ) in Zeichenketten umgewandelt werden müssen.
~ Wenn nicht alle fünf Aufgaben richtig gelöst wurden, kann kein Ein-
trag in die Highscore-Liste erfolgen.
~ Die Highscore-Liste wird Element für Element durchsucht. Wird ein
Element gefunden, in dem eine größere als die neue Ergebniszeit ein-
getragen ist, so wird die neue Ergebniszeit mithilfe der Funktion
insert() an dieser Stelle in die Highscore-Liste eingefügt.

254
Spiel, Version mit Highscore-Datei I 9.9

~ Falls kein Eintrag durch Einfügen erfolgte, wird die neue Ergebniszeit
mithilfe der Funktion a ppend ( ) ans Ende der Liste angefügt.
~ Auf diese Weise ist dafür gesorgt, dass die Highscore-Liste immer auf-
steigend nach Ergebniszeit sortiert ist.
~ Die Highscore-Liste wird unmittelbar nach jeder Änderung angezeigt.

Das folgende Listing zeigt schließlich das Hauptprogramm mit dem


Hauptmenü:
i! Hauptprogramm

# Initialisierung Zufallsgenerator
ra ndom. seed ( )

i! Highscore aus Datei in Liste lesen


hs_l esen()

# Endlosschleife
while True:
# Hauptmenu. Auswahl
try:
menu ~ int(input("Bitte eingeben"
I
"(0: Ende. 1: Highscores. 2: Spielen): "))
except:
print("Falsche Eingabe")
continue

# Aufruf einer Funktion oder Ende


if menu ~~ 0:

break
e 1 i f men u ~~ 1:
hs_anzei gen()
e 1 i f men u ~~ 2:
spi el ()
else:
print("Falsche Eingabe")

# Highscore aus Liste in Datei schreiben


hs_schrei ben()

Listing 9.20 Datei [Link], Teil 5 von 5

255
9 I Dateien

Zur Erläuterung:

~ Nach der Initialisierung des Zufalls generators wird die Highscore-


Datei eingelesen.
~ Es beginnt die Endlosschleife mit dem Hauptmenü. Der Benutzer
kann 0, 1 oder 2 eingeben. Alle anderen Eingaben werden als falsch
gewertet.
~ Nach der Eingabe von 1 wird die Highscore-Liste angezeigt, anschlie-
ßend erscheint wieder das Hauptmenü.
~ Nach der Eingabe von 2 beginnt das Spiel, anschließend erscheint
wieder das Hauptmenü.
~ °
Nach der Eingabe von wird die Endlosschleife verlassen. Die High-
score-Liste wird in die Datei geschrieben und das Programm endet.
10 Internet

Dieses Kapitel beschäftigt sich mit dem Laden und dem Senden von Inter-
netdaten und mit der Erstellung von Programmen, die auf einem Web-
server laufen.

Sie können mithilfe von Python auf Daten im Internet zugreifen, Daten
ins Internet senden und Daten anderen Benutzern im Internet zur Verfü-
gung stellen.

Am Ende dieses Kapitels wird das bereits bekannte Spiel in einer Version
vorgestellt, die das Spielen im Internet ermöglicht. Dabei werden Aufga-
bendaten aus dem Internet abgerufen, Benutzereingaben ins Internet
gesendet und Spielergebnisse auf einem Webserver im Internet gespei-
chert.

10.1 laden und Senden von Internetdaten

Das Modul urllib mit den Untermodulen [Link] und url- Modulurllib
I
1 i b . par s e kann zum Laden von Daten aus dem Internet und zum Sen-
den von Daten in das Internet verwendet werden.

Bei existierender Verbindung zu einem Webserver, ob lokal oder im


Internet, hat man folgende Möglichkeiten:

~ Öffnen einer Verbindung zu einer URL mit der Funktion ur 1 0 pen ( ) uriopenO
und anschließendes Einlesen der Inhalte in die Variable eines Python-
Programms
~ direktes Kopieren der Daten von einer URL in eine Datei auf der Fest- uriretrieveO
platte mit der Funktion url retri eve()

Mithilfe der Funktion ur 1 open () können auch Daten an eine URL zur Daten senden
weiteren Verarbeitung auf dem Webserver gesendet werden.

10.1.1 Lokaler Webserver


Zum Testen der Programme dieses Abschnitts wird ein lokaler Webser- LokalerWebserver
ver benötigt. Ein solcher Webserver wird beispielsweise mit dem frei

257
10 I Internet

verfügbaren Paket Xampp zur Verfügung gestellt. Sie können Xampp


unter [Link] herunterladen. Die Installationsdatei
xampp-win32-1. 7. [Link] der Version 1.7.0 von Xampp für Win-
dows liegt auch der Buch-CD bei.

Xampp Xampp ist ein vorkonfiguriertes und einfach zu installierendes Paket, das
neben einem Apache-Webserver weitere Software umfasst, zum Beispiel
die Webserver-Sprache PHP und das Datenbanksystem MySQL.

Xampp starten Nach der Installation von Xampp unter Windows, zum Beispiel in das
Verzeichnis C\xampp, muss der lokale Webserver über das XAMpp CON-
TROL PANEL gestartet werden.

C3 XAMPP Control Panel Application

X AMPP C ontrol Panel Ser vi ce ".

Mo dule s

o Svc Apa che Runn ing Stop I Admin", I


o Svc MyS ql St a rt I Admin", I
o Sv c Fil eZ illa Sta rt I Admin", I
o Svc Mercury St a rt I Admin", I
XAHP P Cont:t: o l Panel V e:t: s i on 2 . 5 (9. May , 2007)
Wind ows 5 . 1 Bu i ld 2600 Platf o :t:m 2 Se :t:vic e Pa c k 3
Cu:t::t: e nt Di:t:ect o :t:y : c: : \ xamp p
In st all Di:t: e c:t o :t:y : c: : \x amp p
S ta tu s e h e c:k OR
Bu sy .. .
Ap ach e s ta:t:te d [ Po rt 8 0]

Abbildung 10.1 Xampp Control Panel, nach Start des Webservers

[Link] Anschließend starten Sie einen Browser und geben dort die URL
[Link] in der Adresszeile ein. Damit erreichen Sie das Basisver-
zeichnis des lokalen Webservers. Bei einer Standardinstallation von
Xampp im oben angegebenen Installationspfad befindet sich das Basis-
verzeichnis des lokalen Webservers im Festplattenverzeichnis C\xampp\
htdocs.

10.1.2 Daten lesen


HTML-Datei lesen Im folgenden Programm wird mithilfe der Funktion ur 1 open ( ) aus dem
Modul ur 11 i b. req ues t der Inhalt der Internetseite [Link]
python/[Link] in eine Liste gelesen. Diese Liste wird anschließend
ausgegeben.
Laden und Senden von Internetdaten I 10.1

Bei der Datei p1 [Link] handelt es sich um eine einfache HTML-Datei.


Zunächst wird der Inhalt dieser Datei aufgeführt:
<html>

<head>
<title>Titelzeile</title>
</head>

<body>
<b>Hallo Python</b>
</body>

</html>
Listing 10.1 Datei [Link]

Zur Erläuterung: Speicherort

~ Die Datei sollte im Festplattenverzeichnis C\xampp\htdocs\python


gespeichert werden; dies setzt eine Standardinstallation von Xampp
voraus.
~ Es werden nur einfache HTML-Codebeispiele gegeben, da eine tiefer-
gehende Einführung in HTML nicht Gegenstand dieses Buchs ist.
Wenn Sie sich diesbezüglich genauer informieren mächten, so finden
Sie ein empfehlenswertes Online-Buch unter [Link]
HTML lernen

I
Gibt man [Link] einem Webbrowser ein, Aufruf über
so erscheint die in Abbildung 10.2 gezeigte Ansicht. Browser

t) Titelzeile . Mozilla Firefox


Q.a t ei ~earbeite n ~n sicht ~hro n ik !:.esezeichen E;!tras t:!ilfe

I .... - - - - : - C X ~ (l'Sl ! http:// localhost/python/[Link]

Hallo Python

Abbildung 10.2 Erstes HTML-Dokument

Das Python-Programm zum Lesen dieser Internetseite sieht wie folgt aus:
import sys. [Link]

# Verbindung zu einer URL


try:
u ~ [Link] \
("[Link]

259
10 I Internet

except:
print("Fehler")
[Link](O)

# Liest alle Zeilen in eine Liste


li ~ [Link]()

# Schliesst die Verbindung


[Link]()

# Ausgabe der Liste


for element in li:
print(element)
Listing 10.2 Datei [Link]

Die Ausgabe lautet:


b'<html>\r\n'
b'\r\n'
b'<head)\r\n'
b'<title)Titelzeile</title)\r\n'
b'</head)\r\n'
b'\r\n'
b'<body)\r\n'
b'<b)Hallo Python</b)\r\n'
b'</body)\r\n'
b'\r\n'
b'</html>\r\n'

Zur Erläuterung:

Webserver ~ Erscheint eine Fehlermeldung, so hat man eventuell vergessen, den


gestartet? lokalen Webserver zu starten (siehe Abschnitt 10.1.1, »Lokaler Web-
server«).
uriopenO ~ Mithilfe der Funktion ur 1 open ( ) wird die Verbindung zur URL geöff-
net. Der Rückgabewert der Funktion ähnelt einem Dateiobjekt. Sie
können lesend auf die Inhalte der geöffneten Datei zugreifen, wie in
Abschnitt 9.3.2, »Sequenzielles Lesen«, beschrieben.
readlinesO ~ Die Funktion read 1 i nes () liefert eine Liste. Jedes Listenelement
umfasst eine Zeile des HTML-Codes der Internetseite.
doseO ~ Nach dem Abspeichern in der Liste kann die Datei mit der Funktion
cl 0 s e ( ) wieder geschlossen werden.

260
Laden und Senden von Internetdaten I 10.1

~ Jedes Element der Liste ist eine Zeichenkette, die als Byte-Literal aus- Byte-Literale
gegeben wird. Byte-Literale sind Zeichenketten des Datentyps bytes
(siehe Abschnitt 4.2.7, »Datentyp bytes«).

10.1.3 Daten kopieren


Das folgende Programm kopiert den Inhalt der Internetseite [Link] HTML-Datei
host/python/[Link] direkt in eine Festplattendatei. kopieren

import [Link]

# Liest Inhalt von URL in eine Datei


[Link] \
("[Link] "[Link]")

Listing 10.3 Datei [Link]

Zur Erläuterung:

~ Die Funktion url retrieve() hat zwei Parameter: die URL und den uriretrieveO
Namen der Datei, in der der Quellcode gespeichert werden soll (hier
[Link]).
~ Diese Datei kann anschließend beispielsweise offline mit einem
Browser gelesen oder mit einem Editor bearbeitet werden.
Offline browsen
I
10.1.4 Daten senden per GET
Man kann den Betrachter einer Webseite auch in die Lage versetzen, spe- Formular
zifische Daten an den Webserver zu senden. Dies geschieht über Formu-
lare, die vom Betrachter ausgefüllt und an den Webserver gesendet wer-
den.

Auf dem Webserver werden dann häufig zwei Vorgänge gestartet:

~ Weiterverarbeitung oder Speicherung der Daten (zum Beispiel in


einer Datenbank)
~ Sendung einer individuellen Antwort an den Benutzer

HTMl-PH P-Variante
Im folgenden Beispiel soll der Betrachter seinen Vor- und Nachnamen HTML-PHP-
eingeben und diese Informationen an den Webserver senden. Er erhält Variante

daraufhin eine Bestätigung.


10 I Internet

Dies wird, zunächst für die Ein- und Ausgabe in einem Browser, mithilfe
einer HTML-Datei und einem zugehörigen PHP-Programm realisiert.

Abbildung 10.3 zeigt zunächst das Formular.

Bitte senden Sie nu·e Daten :

M_a_i8_r _ _ _ _----'[ Nachname


L[

[Werner [Vorname
'---------'

[ Daten absenden

Abbildung 10.3 Formular, mit Beispieleingabe

Die Antwort des Webservers sehen Sie in Abbildung 10.4.

Thre folgenden Daten wurden registriert:

Nachname: Maier
Vorname: Werner

Abbildung 10.4 Antwort des PH P-Programms

Der Quellcode des Formulars lautet:


<html>
<body>
<b>Bitte senden Sie Ihre Daten:</b><p>

<form action~"[Link]" method~"get">


<input name~"nn"> Nachname<p>
<input name~"vn"> Vorname<p>
<input type~"submit">
</form>

</body>
</html>
Listing 10.4 Datei [Link]
Laden und Senden von Internetdaten I 10.1

Zur Erläuterung:
~ Das Formular wird mit form markiert, ein Eingabefeld mit input.
~ Im Formular bedient man sich der sogenannten GET-Methode. Dies GET-Methode
ist wichtig für das Senden und Empfangen der Daten, sowohl für die
HTML-PHP-Variante als auch für die später gezeigte Python-PHP-Vari-
ante.
Es folgt der PHP-Quellcode der zugehörigen Antwort:
<html>
<body>
<b>Ihre folgenden Daten wurden registriert:</b><p>

<?php
echo "Nachname: " . $_GET["nn"J . "<br I>";
echo "Vorname: " . $_GET["vn"J;
?>

</body>
</html>
Listing 10.5

Zur Erläuterung:
Datei [Link]

I
~ Die aus dem Formular übernommenen Daten stehen in PHP im glo-
balen Array $_GET zur Verfügung, weil sie mit der GET-Methode
gesendet wurden.

python-PHP-Variante
Mithilfe des folgenden Python-Formulars können diese Daten ebenfalls Python-PH P-
gesendet werden. Dabei wird wiederum das oben angegebene PHP-Pro- Variante

gramm [Link] auf dem Webserver angesprochen.


import [Link]

i! Ei ngabedaten
pnn input("Bitte den Nachnamen eingeben: ")
pvn ~ input("Bitte den Vornamen eingeben: ")

i! sendet Daten
u ~ [Link] \
("[Link]
+ pnn + "&vn~" + pvn)
10 I Internet

# Empfang der Antwort und Ausgabe


li ~ [Link]()
[Link]()
for element in li:
print(element)
Listing 10.6 Datei [Link]

Zur Erläuterung:

~ Zunächst werden die Eingabedaten vom Benutzer erfragt und in den


beiden Variablen pvn und pnn gespeichert.
urlencoded- ~ Mithilfe der Funktion ur 1open ( ) wird die betreffende URL angespro-
Format chen. Die Eingabeinformationen werden im Format urlencoded ange-
hängt. Dazu werden nach einem Fragezeichen (?) ein oder mehrere
Paare nach dem Muster key~v a 1 ue angehängt. Die einzelnen Paare
werden jeweils durch ein Ampersand (&) voneinander getrennt. Der
schlüssel (key) entspricht der Variablen, der val ue dem Wert der
Variablen.
~ Anschließend wird der Code der Antwort des Webservers wie im ers-
ten Programm gelesen und ausgegeben.
~ Die Ausgabe (für das gleiche Beispiel) lautet nun:
Bitte den Nachnamen eingeben: Maier
Bitte den Vornamen eingeben: Werner
b'<html>\r\n'
b'<body>\r\n'
b'<b>Ihre folgenden Daten wurden registriert:</b><p>\r\n'
b'\r\n'
b'Nachname: Maier<br />Vorname: Werner\r\n'
b'</body>\r\n'
b'</html>\r\n'
Zur Erläuterung:

Daten zum ~ Wie Sie sehen, sind die Daten auf dem Webserver angekommen und
Webserver wurden vom PHP-Programm weiter verarbeitet.
gesendet
~ In diesem Fall hätte man zum Beispiel Nachname und Vorname in
einer Datenbank auf dem Webserver speichern können.

10.1.5 Daten senden per POST


uriencodeO Eine andere Möglichkeit bietet die Funktion url encode(). Sie dient zur
Codierung der Sendedaten und benötigt als Parameter ein Dictionary mit
Laden und Senden von Internetdaten I 10.1

den zu sendenden Daten. Rückgabewert ist eine Zeichenkette im Format


urlencoded, die an die URL angehängt wird.

HTMl-PH P-Variante
Im folgenden Beispiel sehen Ein- und Ausgabe wie im vorherigen HTML-PHP-
Abschnitt aus. Das HTML-Formular sieht wie folgt aus: Variante

<html>
<body>
<b>Bitte senden Sie Ihre Daten:</b><p>

<form action~"[Link]" method~"post">


<input name~"nn"> Nachname<p>
<input name~"vn"> Vorname<p>
<input type~"submit">
</form>

</body>
</html>
Listing 10.7 Datei [Link]

2m E,läutemng'
~ Im Unterschied zum vorherigen Beispiel wurde hier die sogenannte POST-Methode
I
POST-Methode verwendet. Dies ist wichtig für das Senden und Emp-
fangen der Daten, sowohl für die HTML-PHP-Variante als auch für die
Python-PHP-Variante.

Es folgt der PHP-Quellcode der zugehörigen Antwort:


<html>
<body>
<b>Ihre folgenden Daten wurden registriert:</b><p>

<?php
echo "Nachname: " . $_POST["nn"] . "<br I>";
echo "Vorname: " . $_POST["vn"];
?>

</body>
</html>
Listing 10.8 Datei [Link]
10 I Internet

Zur Erläuterung:

Array $_POST ~ Die aus dem Formular übernommenen Daten stehen in PHP im glo-
balen Array $_POST zur Verfügung, weil sie mit der POST-Methode
gesendet wurden.

python-PH P-Variante
Python-PH P- Mithilfe des folgenden Python-Programms können diese Daten ebenfalls
Variante gesendet werden. Dabei wird auch das obige PHP-Programm p1 [Link]
auf dem Webserver angesprochen.
import [Link]. [Link]

lf Ei ngabedaten
pnn input("Bitte den Nachnamen eingeben: ")
pvn ~ input("Bitte den Vornamen eingeben: ")

# Dictionary mit Sendedaten. Codierung


dc ~ {"nn":pnn. "vn":pvn}
data ~ [Link](dc)

lf sendet Daten
u ~ [Link] \
("[Link] data)

# Empfang der Antwort und Ausgabe


li ~ [Link]()
[Link]()
for element in li:
print(element)

Listing 10.9 Datei [Link]

Zur Erläuterung:

Dictionary ~ Aus den eingegebenen Daten wird ein Dictionary erzeugt. schlüssel
ist jeweils der Name der Variablen, Wert ist der Eingabewert des
Benutzers.
Sendedaten ~ Dieses Dictionary wird mithilfe der Funktion ur 1 encode ( ) in ein For-
mat umgewandelt, das zum Senden geeignet ist.
~ Der zweite, optionale Parameter der Funktion url open() enthält
diese Sendedaten.

266
Webserver-Programmierung I 10.2

10.2 Webserver-Programmierung

Das Modul cg i wird zur Web server-Programmierung verwendet. Mit sei- CGI-Skript
ner Hilfe kann man sogenannte CGI-Skripte erzeugen, die auf einem Web-
server ausgeführt werden und ihre Ergebnisse an den Betrachter senden.
Basis für die gesendeten, dynamisch erzeugten Ergebnisse sind unter
anderem Benutzereingaben, Inhalte von Dateien und Datenbanken, die
auf dem Webserver liegen und mithilfe der CGI-Skripte gelesen und
bearbeitet werden.

Voraussetzung für die Entwicklung und den Test der nachfolgenden Pro- Lokaler Webserver
gramme ist ein lokaler Webserver, wie er bereits für die Programme im
vorherigen Abschnitt benötigt wurde.

Die CGI-Skripte werden im Browser über das Verzeichnis mit der Verzeichnis
Adresse [Link] abgerufen. Dieses Verzeichnis entspricht cgi-bin

bei einer Standardinstallation von Xampp unter Windows dem Festplat-


tenverzeichnis c: \xampp \cgi-bin.

Erstes Programm

I
10.2.1

Im Folgenden wird zunächst ein einfaches, statisches CGI-Skript mit Statisches


Python vorgeführt. Das Modul cgi wird hier noch nicht benötigt. In die- CGI-Skript

sem Beispiel sollen nur der Python-Programmaufbau und der HTML-


Dokumentaufbau gezeigt werden:
#!C:\Python30\[Link]
print( "Content type: text/html")
pr i nt ( )

print( "<html)")
print("<body)")
print("<hl)Hallo Python</hl)")
print("</body)")
print( "</html)")

Listing 10.10 Datei [Link]

Zur Erläuterung:

~ In der ersten Zeile wird dem Webserver (unter Windows) die Infor- Python auf dem
mation gegeben, dass die nachfolgenden Zeilen mithilfe von Python Webserver

ausgeführt werden sollen. Der Webserver weiß damit, dass er keine


normale HTML-Datei vor sich hat, deren Daten einfach an den Brow-
10 I Internet

ser des Benutzers gesendet werden sollen, sondern dass der Datei-
inhalt erst von Python vorverarbeitet werden muss. Erst Python
erstellt dann die HTML-Daten.
[Link] ~ Gleichzeitig wird der Ort mitgeteilt, an dem sich der Python-Inter-
preter auf dem Rechner befindet, auf dem auch der Webserver läuft.
Im vorliegenden Fall handelt es sich um die Datei C\Python30\
[Link], also lautet die Zeile: if!C:\Python30\[Link]. Unter
Unix lautet die Zeile meist if! / us r!l oca 1 / bi n/ pyt hon.
Header ~ In der nächsten Zeile wird im sogenannten Header das Format des
Dokumentinhalts (Content-type: text/html) festgelegt. Anschlie-
ßend muss eine Leerzeile ausgegeben werden!
~ Es folgt die Ausgabe der Zeilen des eigentlichen HTML-Quellcodes.

Die Ausgabe im Browser, nach Eingabe der Adresse [Link]


bin/p 1005. cgi, sehen Sie in Abbildung 10.5.

Hallo Python
Abbildung 10.5 Erstes Python-HTML-Dokument

10.2.2 Beantworten einer Benutzereingabe


Dynamisches Im folgenden Beispiel soll der Betrachter seinen Vor- und Nachnamen
CGI-Skript eingeben und diese Informationen an den Webserver senden. Er erhält
daraufhin eine Bestätigung.
Abbildung 10.6 zeigt das Formular.

Bitte senden Sie Du·e Daten:

IMaie,
'-----------'
INachname
w_e_rn_e'_ _ _ _-'I Vorname
Ll

[ Daten absenden I

Abbildung 10.6 Formular mit Beispieleingabe

268
Webserver-Programmierung I 10.2

Die Antwort des Webservers sehen Sie in Abbildung 10.7.

Registrierte Daten:

Nachname: Maier

Vorname : Werner

Abbildung 10.7 Antwort des Python-Programms

Unser bekanntes Beispiel wird nun mithilfe einer HTML-Datei und HTML-Python-
einem zugehörigen Python-Programm als CG I-Skript realisiert. Variante

Zunächst der Code der HTML-Datei mit dem Formular:

<html>
<body>
<b>Bitte senden Sie Ihre Daten:</b><p>

<form action~"/cgi-bin/[Link]">
<input name~"nn"> Nachname<p>
<input name~"vn"> Vorname<p>
<input type~"submit">
I
</form>

</body>
</html>
Listing 10.11 Datei [Link]

Zur Erläuterung:

~ In der fo rm-Markierung ist der Name des Python-Programms angege- Formularziel


ben, das die Antwort zu diesem Formular sendet. Es handelt sich um
die Datei p1 [Link] im Standardverzeichnis für CGI-Skripte (cgi - bi n)
auf dem Webserver.

Das zugehörige CGI-Skript sieht wie folgt aus:

#!C:\Python30\[Link]

i! Modul cgi
import cgi. cgitb

269
10 I Internet

lf Ausgabe bei Fehl er


[Link]()

# Objekt der Klasse FieldStorage


form ~ [Link]()

# Einzelne Elemente des Objekts


if "nn" in form:
nn ~ form["nn"[Link]
if "vn" in form:
vn ~ form["vn"[Link]

# HTML-Dokument mit Variablen


print("Content-type: text/html ")
pr i nt ( )

print( "<html)")
print("<body)")

print("<p)<b)Registrierte Daten:</b)</p)")
print("<p)Nachname:", nn, "</p)")
print("<p)Vorname:", vn, "</p)")

print("</body)")
print("</html)")

Listing 10.12 Datei [Link]

Zur Erläuterung:

Module cgi, cgitb ~ Es werden die Module cgi und cgitb eingebunden.
~ Das Modul cgi wird für die eigentliche Datenübermittlung benötigt.
Das Modul cgi tb kann während der Entwicklungszeit zur Fehler-
suche genutzt werden.
[Link] ~ Die Funktion enabl e() des Moduls cgitb sorgt dafür, dass Fehler
während der Entwicklung des Python-Programms mit Kommentar im
Browser ausgegeben werden. Ein Beispiel sehen Sie am Ende des
Abschnitts. Nach Fertigstellung eines Programms sollte die Zeile mit
cgi tb. enab 1e ( ) wieder auskommentiert werden.
FieldStorage ~ Es wird ein Objekt (hier mit dem Namen fo rm) der Klasse Fi e 1 dSto-
rage des Moduls cgi erzeugt. Dieses Objekt ähnelt einem Dictionary
und beinhaltet alle ausgefüllten Elemente des Formulars mit ihren
jeweiligen Werten.

270
Webserver- Program m ieru ng I 10.2

~ Es muss zunächst geprüft werden, ob der Benutzer einen Wert für ein Formularelement
bestimmtes Formularelement eingegeben hat oder nicht. Dies prüfen

geschieht mithilfe des Operators in (Beispiel: i f "nn" in form). For-


mularelemente ohne Wert werden nicht an das CGI-Programm
übermittelt. Ihre Verwendung würde dann zu einem Laufzeitfehler
führen.
~ Die Anweisung n n ~ form [ "n n" ] . val ue weist daraufhin der Python- Wert des Formu-
Variablen nn den Wert des Formularelernents nn zu, das in dem larelements

Objekt form gespeichert wurde.


~ Es folgt die Ausgabe des HTML-Codes, in dem die ermittelten Python- Header
Variablen eingesetzt werden. Der Code wird eingeleitet durch die
Header-Zeile, in der das Format des Dokumentinhalts (text/html)
festgelegt wird. Anschließend folgt eine Leerzeile.

Ergänzend zum Einsatz des Moduls cgitb veranschaulicht das folgende Fehlerausgabe
Beispiel ein fehlerhaftes Python-Programm und die Ausgabe des Fehlers
über den Browser:

NameError
A pr oblem occurred in a Python script. Here is the sequence offunction
I
o. print("<p > <b>Registrierte Daten:<!b> <!p > ")
05 print ("<p >Nachnarne:", nn, "<!P>")
27 print (" <p >Vornarne: ", pn, " <!P > ")

29 print("<!body>")
builtin print = <built-in function prin!>, pn und~ned

NameElTor: name 'pn' is not define d


args = ("name 'pn' is not defined",)
with_traceback = <built-in method with_traceback ofN ameError

Abbildung 10.8 Fehlermeldung im Browser

Zur Erläuterung:
~ Statt der Variablen vn für den Vornamen wurde versehentlich die
Variable pn gewählt.

271
10 I Internet

10.2.3 Formularelemente mit mehreren Werten


Formularelemente können mehrere verschiedene Werte beinhalten.
Dies ist zum Beispiel bei einem Auswahlmenü vom Typ mult i p 1e der
Fall, in dem der Benutzer mehrere Werte markieren kann.

Zur vereinfachten Formularauswertung können aber auch mehrere For-


mularelemente den gleichen Namen tragen. Auch in diesem Fall wird zu
einem Namen mehr als ein Wert übermittelt.

Auswertung Wird nur ein Wert zu einem solchen Formularelement übermittelt, so


geschieht die Auswertung in der bereits bekannten Form. Falls mehrere
Werte zu einem Formularelement übermittelt wurden, so stehen diese
Werte in einer Liste zur Verfügung. Bei der Auswertung muss also
zunächst festgestellt werden, ob
~ überhaupt ein Wert vorhanden ist oder
~ genau ein Wert vorhanden ist oder
~ mehrere Werte vorhanden sind.

Das folgende exemplarische Formular beinhaltet drei gleichnamige Text-


felder:

U Mozilla Firefox
!2atei ~ea rb e it e n ansicht ~h ron i k ~ese2e ich e n E ~tr as tiilfe

• C X http:// ioca ih os t/python/p 1007, htm

Bitte senden Sie Uu·e D aten:

IMaier I N ac hn am e 1
'-------------'

'----_ _ _ _ _ _---'1 N ac hname 2

LIS_c_hm_i_tz _ _ _ _-----'I N ac hnam e 3

I Daten absenden
Abbildung 10.9 Formular, mit Beispieleingabe

Die Antwort des Webservers zeigt Abbildung 10.10.

272
Webserver-Programmierung I 10.2

U Mozilla Firefox
Qatei ~earbeiten ansicht ~hronik lesezeichen E!tras tiilfe

• C x
Registrierte Daten:

Nachnamen:
Maier
Schmitz

Abbildung 10.10 Antwort des Python-Programms

Der HTML-Code des Formulars:


<html>
<body>
<b>Bitte senden Sie Ihre Daten:</b><p>

<form action~"/cgi-bin/[Link]">
<input name~"nn"> Nachname l<p>
<input name~"nn"> Nachname 2<p>
<input name~"nn"> Nachname 3<p>
<input type~"submit">
</form>

</body>
I
</html>
Listing 10.13 Datei [Link]

Zur Erläuterung:

~ Das Formular wird zur Auswertung an p1 [Link] gesendet. Es bein-


haltet dreimal das Formularelement nn. Es können also bis zu drei ver-
schiedene Nachnamen eingegeben werden.

Das zugehörige CGI-Skript sieht wie folgt aus:


#!C:\Python30\[Link]

Ir Modul cgi
import cgi. cgitb

Ir Ausgabe bei Fehl er


[Link]( )

273
10 I Internet

# Objekt der Klasse FieldStorage


form ~ [Link]()

# HTML-Dokument mit Variablen


print("Content-type: text/html ")
pr i nt ( )

# Auswertung Formularfeld
if "nn" in form:
print("<p)<b)Registrierte Daten:</b)</p)")
print("<p)Nachnamen:<br I)")
try:
print(form["nn"].value)
except:
for element in form["nn"]:
print([Link]. "<br I)")
print( "</p)")
else:
print("<p)<b)Keine Daten gesendet</b)</p)")

print("</body)")
print("</html)")

Listing 10.14 Datei [Link]

Zur Erläuterung:

~ Zunächst wird mithilfe des Operators in festgestellt, ob überhaupt ein


Nachname eingegeben wurde.
Kein Wert ~ Ist dies nicht der Fall, so wird ausgegeben: Kei ne Daten gesendet.
Ein Wert ~ Innerhalb eines t r y-except-Blocks wird versucht, einen einzelnen
Nachnamen auszugeben. Falls mehrere Nachnamen übermittelt wur-
den, schlägt dies fehl.
Mehrere Werte ~ In diesem Fall werden alle Elemente der übermittelten Liste von
Nachnamen ausgegeben.

10.2.4 Typen von Formularelementen


Online-Formular Im folgenden Beispiel wird die Auswertung verschiedener Typen von
Formularelementen an einem größeren Beispiel demonstriert - einer
Online-Bestellung beim Python Pizza Service (siehe Abbildung 10.11).

274
Webserver-Programmierung I 10.2

Python Pizza Se rvi ce

o Stammlomde (5% Rabatt) I. . . . . ICode


o Neukunde
I Maier I N achname IWerne r I Vorname
~=~
I Pepp eroniweg I Straß e I~ I Hausnr.

16399 9 I PLZ IT eigd o rf I Ort

Sorte I Pi zz a Python (8 .50 €) v I

I A
Zusätze: Extra Oli v en (1.20 €) v

o Express-Service (max 30 Minute n, 1.50 € extra)

Bi tt e zw eim a l k li n geln

Bemerkung '----_ _ _ _ _ _ _ _ _----'

I Daten ab senden 11 Zurü cks etz en

Abbildung 10.11 Python Pizza Service, Bestellung


I
Das Formular beinhaltet die folgenden Typen von Formularelementen: Elementtypen

~ zwei Radio-Buttons für den Kundentyp


~ ein Eingabefeld vom Typ »Password« für den Stammkunden-Code
~ sechs einzeilige Eingabefelder für die Adresse
~ ein einfaches Auswahlmenü für die Pizzasorte
~ ein mehrfaches Auswahlmenü für die Zusätze zur Pizza
~ ein Kontrollkästchen (Checkbox) für den Express-Service
~ ein mehrzeiliges Eingabefeld (Textarea) für Bemerkungen
~ je einen Button zum Absenden und zum Zurücksetzen der Bestellung

Die Formularelernente, die eine einfache Auswahl verlangen, sind schon Vorbesetzung
mit einem Standardwert vorbesetzt. Dies sollte beim Formularentwurf
unbedingt beachtet werden, damit der Benutzer nur sinnvolle Inhalte
absenden kann. Gleichzeitig muss im auswertenden Programm nicht
mehr geprüft werden, ob für diese Elemente ein Wert vorhanden ist.

275
10 I Internet

HTML-Formular Das HTML-Formular sieht folgendermaßen aus:


<html>
<body>
<p><b>Python Pizza Service</b></p>

<form action~"lcgi-bin/[Link]">

<p><input type~"radio" name~"ku" value~"S" checked~"checked">


Stammkunde (5% Rabatt)
<input type~"password" name~"kc" size~"6" maxlength~"6">
Code<br I>
<input type~"radio" name~"ku" value~"N"> Neukunde</p>

<table>
<tr>
<td><input name~"nn" size~"12"> Nachname</td>
<td><input name~"vn" size~"12"> Vorname</td>
</tr>
<tr>
<td><input name~"st" size~"12"> Stra&szlig;e</td>
<td><input name~"hn" size~"12"> Hausnr.</td>
</tr>
<tr>
<td><input name~"pz" size~"12"> PLZ</td>
<td><input name~"or" size~"12"> Ort</td>
</tr>
</table>

<p>Sorte;
<select name~"pt">
<option value~"Salami">
Pizza Salami (6.00 &euro;)<loption>
<option value~"Thunfisch">
Pizza Thunfisch (6.50 &euro;)
<option value~"Quattro Stagioni">
Pizza Quattro Stagioni (7.50 &euro;)<loption>
<option value~"Python" selected~"selected">
Pizza Python (8.50 &euro;)<loption>
</select></p>

<p>Zus&auml ;tze;
<select name~"zu" multiple size~"2">
<option value~"Pepperoni">Extra Pepperoni (1.00 &euro;)<loption>
<option value~"Oliven">Extra Oliven (1.20 &euro;)<loption>
Webserver-Programmierung I 10.2

<option value~"Sardellen">Extra Sardellen (1.50 &euro;l</option>


</select></p>

<p><input type~"checkbox" name~"ex">


Express-Service (max. 30 Minuten. 1.50 &euro; extral</p>

<p>Bemerkung;
<textarea name~"bm" rows~"3" cols~"25"></textarea></p>

<p><input type~"submit"> <input type~"reset"></p>

</form>

</body>
</html>

Listing 10.15 Datei [Link]

Zur Erläuterung:
~ Eingabefelder vom Typ rad i 0 (Radio buttons) , die den gleichen Radiobuttons
Namen haben (im vorliegenden Beispiel "k u"), bieten eine einfache
Auswahl zwischen zwei Alternativen, hier zwischen STAMMKUNDE

~
und NEUKUNDE. Die Vorauswahl wird durch checked gekennzeichnet.
Eingaben in Eingabefeldern vom Typ pass word sind nicht erkennbar.
Einfache Auswahlmenüs mit se 1 e ct dienen zur einfachen Auswahl
Passwortfeld

Einfaches
I
zwischen verschiedenen Möglichkeiten, hier zwischen den unter- Auswahlmenü

schiedlichen Pizzasorten. Die Vorauswahl wird durch sel ected


gekennzeichnet.
~ Mehrfache Auswahlmenüs mit se 1 e ct und mu1ti P1 e bieten eine Mehrfaches
mehrfache Auswahl zwischen den verschiedenen Möglichkeiten, hier Auswahlmenü

den unterschiedlichen Zusätzen zu den Pizzen. Eine mehrfache Aus-


wahl wird mithilfe der Tasten GJ und I Strg I vorgenommen.
~ Ein Kontrollkästchen (englisch: checkbox) dient zur Übermittlung Checkbox
einer zusätzlichen Information, hier dem Wunsch nach Express-
Service.
~ Ein mehrzeiliges Eingabefeld (Textarea) bietet die Möglichkeit, län- Textarea
gere Texte einzutragen und zu übermitteln.

Die Antwort des Webservers auf die obige Bestellung (siehe Abbildung
10.12) erfolgt mit einem Python CGI-Skript.

277
10 I Internet

Guten Tag W emer Maier

Thre Adre ss e: Pepper oruweg 4 in 63999 Teigdorf

Thre Best ellung Pizza Python mit Pep p eroru

Mit Express -Service

B emerkung: Bitte zweimal klingeln

R abatt 5%

Preis (ohne Bemerkung) 1045 Euro

Abbildung 10.12 Python Pizza Service, Bestätigung der Bestellung

Python CGI-Skript Das zugehörige CG I-Skript sieht wie folgt aus:


#!C:\Python30\[Link]

lf Modul cgi
import cgi. cgitb

# Allgemeine Check-Funktion
def chk(element):
global form
if element in form:
erg form[[Link]
else:
erg
return erg

lf Ausgabe bei Fehl er


[Link]()

# Objekt der Klasse FieldStorage


form ~ [Link]()

print("Content-type: text/html ")


pr i nt ( )
print( "<html)")
print("<body)")
Webserver-Programmierung I 10.2

Ir An rede
print("(p)Guten Tag", chk("vn"), chk("nn"), "(/p)")

Ir Adresse
print("(p)Ihre Adresse:", chk("st"), chk("hn"),
"in", chk("pz"), chk("or"), "(/p)")

Ir Pizza-Typ
print( "(p)Ihre Bestell ung: Pizza", chk( "pt"))

# Beginn Berechnung Preis


preisliste ~ {"Salami":6, "Thunfisch":6.5,
"Quattro Stagioni":7.5, "Python":8.5}
preis ~ preisliste[form["pt"].value]

Ir Zusatz
zusatzliste {"Pepperoni":l, "Oliven":1.2,
~

"Sardellen":1.5}
if "zu" in form:
try:
print("mit", form["zu"].value)

I
preis +~ zusatzliste[form["zu"].value]
except:
for element in form["zu"]:
print(", mit", [Link])
preis +~ zusatzliste[[Link]]
print( "(/p)")

# Express-Service
if "ex" in form:
print("(p)Mit Express-Service(/p)")
preis +~ 1.5

Ir Bemerkung
if "bm" in form:
print("(p)Bemerkung:", form["bm"].value, "(/p)")

Ir Rabatt
if "kc" in form:
if f 0 r m[ " ku " ] . val ue
~~ "S"

and form["kc"].value "Bingo":


preis ~ preis * 0.95:
print("(p)Rabatt 5%(/p)")

279
10 I Internet

lfPr eis
print("Preis (ohne Bemerkung): {O:.2f} Euro".format(preis))
print("(/body)")
print("(/html)")

Listing 10.16 Datei [Link]

Zur Erläuterung:

Allgemeine Check- ~ Es wird zunächst eine allgemeine Check-Funktion für alle Formular-
Funktion elemente definiert, die maximal einen Wert übermitteln können. Diese
Funktion liefert den Wert des überprüften Elements oder eine leere
Zeichenkette zurück.
Eingabefelder ~ Nach der Überschrift folgt die Anrede. Für die Angabe von Vorname
und Nachname wird die Check-Funktion genutzt.
~ Es folgt die Bestätigung der Adresse, ebenfalls mit Nutzung der Check-
Funktion.
Einfaches ~ Die Pizzasorte wird angegeben, und der zugehörige Preis wird über
Auswahlmenü ein Dictionary berechnet. Die Existenz des Elements muss nicht über-
prüft werden, da bereits eine Vorauswahl getroffen wurde.
Mehrfaches ~ Die optionalen Zusätze für die Pizza werden hinzugefügt, sowohl in
Auswahlmenü der Ausgabe als auch bei der Berechnung des Preises (über ein Dictio-
nary). Hier muss überprüft werden, ob der Benutzer Zusätze gewählt
hat.
Checkbox, ~ Es erfolgt die Prüfung und gegebenenfalls Ausgabe beziehungsweise
Textarea Preisberechnung für Express-Service und die Ausgabe der Bemer-
kung.
Passwortfeld ~ Nach Berechnung eines eventuell zu gewährenden Rabatts für Stamm-
kunden wird der Preis ausgegeben. Dies geschieht allerdings nur, falls
der Code »Bingo« im Passwortfeld eingegeben wurde.

10.3 Browser aufrufen

webbrowser. Das Modul webbrowser beinhaltet Funktionen, um Internetseiten über


openO einen Browser abzurufen. Es genügt, die Funktion open () aufzurufen.
Als Parameter wird die URL der gewünschten Internetseite angegeben:

280
Spiel, Version für das Internet I 10.4

import webbrowser
[Link]("[Link]
print( "Ende")

Listing 10.17 Datei [Link]

Zur Erläuterung:
~ Der Standard-Webbrowser des Systems wird als unabhängiges Pro-
gramm aufgerufen. Nach dem Aufrufläuft das Python-Programm wei-
ter.

10.4 Spiel, Version tür das Internet

In dieser Spielversion kann der Spieler in einem HTML-Formular auf Aufgaben im


einer Internetseite zunächst seinen Namen eingeben. Anschließend wer- Browser

den ihm, wiederum in einem HTML-Formular, fünf Additionsaufgaben


mit zahlen aus dem Bereich von 10 bis 30 gestellt.

Der Spieler gibt seine Lösungen in die fünf zugehörigen Eingabefelder


ein. Pro Aufgabe hat er nur einen Versuch. Am Ende wird die Gesamtzeit
ermittelt, die er für seine Lösungsversuche benötigt hat.

Löst der Spieler alle fünf Aufgaben richtig, so werden sein Name und die Highscore
speichern
I
benötigte Zeit in eine Highscore-Liste aufgenommen, die in einer Datei
auf dem Webserver abgespeichert wird.

10.4.1 Eingabebeispiel
Es folgt ein typischer Durchlauf durch das Programm. Ab bildung 10.13
zeigt zunächst das Formular für die Eingabe des Namens.

Kopfrechnen

[Link] IIhr Name


[ Und los ..

Abbildung 10.13 Beginn des Spiels


10 I Internet

Es folgen die fünf Aufgaben:

Kopfreclmen

Hall o Mario , llu-e Aufgaben

1. 26 + 12 = 138
2. 26 + 12 = 138
3. 27 + 15 = 1 ~2
4. 14 + 17 = 131
5. 25 + 18 = 1 ~3

[!Fertig ]

Abbildung 10.14 Fünf Aufgaben mit Lösungsversuchen

Die Bewertung des Ergebnisses und die Highscore-Liste sehen Sie in


Abbildung 10.15.

Kopfreclmen

Hall o MaIio , llu- Ergebnis

5 von 5 in 8.66 Sekunden, Highseore

Platz Name Zeit


1 Stefan 8. 62 sec
2 Mario 8. 66 sec
3 Mare 9.56 sec
4 Bemd 9.68 sec

Abbildung 10.15 Bewertung, Highscore

Zur Erläuterung:
~ Der Spieler gibt seinen Namen ein (»Mario«) und betätigt den Button
UND LOS ...
Spiel, Version für das Internet I 10.4

~ Er bekommt fünf Aufgaben gestellt, gibt seine Lösungen für die Auf-
gaben ein und betätigt den Button FERTIG.
~ Die Eingaben werden bewertet, und es erscheint die Highscore-Liste,
gegebenenfalls mit einem neuen Eintrag für den aktuellen Spieler.
~ Das Programm hat einen kleinen Schönheitsfehler: Es misst nicht die
Zeit, die der Spieler zum Lösen der Aufgaben tatsächlich benötigt,
sondern die Zeit, die zwischen dem Erscheinen der fünf Aufgaben
und dem Erscheinen der Auswertungsseite verstreicht. Somit fließt
neben der Schnelligkeit des Spielers auch die Qualität der Internetver-
bindung in das Ergebnis ein. Eine aufwändigere Lösung würde dieses
Problem umgehen.

10.4.2 Aufbau des Programms


Das Programm besteht aus drei Dateien:

Erstes Formular
~ Bei der ersten Datei handelt es sich um eine reine HTML-Datei
([Link] Darin steht das Formular mit
dem Feld zur Eingabe des Namens.
Eingabe Name
I
Zweites Formular
~ Bei der zweiten Datei handelt es sich um ein Python CGI-Skript Fünf Aufgaben
([Link] In diesem Skript wird der Einga-
bewert aus dem ersten Formular entgegengenommen und das zweite
Formular wird dynamisch aufgebaut. Das zweite Formular beinhaltet
fünf Eingabefelder für die Lösungsversuche der fünf Aufgaben.
~ Außerdem beinhaltet das zweite Formular insgesamt sieben ver- Versteckte Felder
steckte Felder. In diesen Feldern werden die fünf richtigen Lösungen
der Aufgaben, der Name des Spielers aus dem ersten Formular und
die ermittelte Startzeit unsichtbar an die dritte Datei übermittelt.

Auswertung
~ Die dritte Datei ist wiederum ein Python CGI-Skript ([Link]
host/cgi-bin/[Link]). In diesem Skript werden insgesamt zwölf
Werte aus dem zweiten Formular entgegengenommen. Dies sind:
~ der Spielername
~ die ermittelte Startzeit
10 I Internet

~ die fünf richtigen Lösungen


~ die fünf Eingaben des Benutzers
Ergebniszeit ~ Es wird die Endzeit festgestellt. Aus Startzeit und Endzeit wird die
Ergebniszeit ermittelt, die der Benutzer benötigt hat.
Auswertung ~ Die fünf richtigen Lösungen und die fünf Eingaben des Benutzers
werden miteinander verglichen. Sind alle Lösungen richtig, werden
Name und Zeit in die Highscore-Liste eingetragen. Die Liste wird
anschließend angezeigt.
~ Zuletzt wird ein Hyperlink angezeigt, mit dem der Benutzer wieder
zum Start des Programms gelangt.

10.4.3 Code des Programms

Erstes Formular

<html>
<body>
<p><b>Kopfrechnen</b></p>

<form action~"lcgi-bin/[Link]">
<p><input name~"spielername" size~"12"> Ihr Name</p>
<p><input type~"submit" value~"Und los . .. "></p>
</form>

</body>
</html>
Listing 10.18 Datei p1 01 [Link]

Zur Erläuterung:
~ Dieses erste Formular verweist auf das zweite Formular. Es beinhaltet
das Element spi e 1 ername und den Button zum Absenden.

Zweites Formular

#!C:\Python30\[Link]

lf Modul e
import cgi, cgitb, sys, random, time

lf Ausgabe bei Fehl er


[Link]()
Spiel, Version für das Internet I 10.4

# Initialisierung Zufallsgenerator
ra ndom. seed ( )

# Objekt der Klasse FieldStorage


form ~ cgi .FieldStorage()

lf Header
print( "Content type: text/html")
pr i nt ( )

# HTML-Dokumentbeginn
print( "<html)")
print("<body)")
print("<p)<b)Kopfrechnen</b)</p)")

# Falls kein Name eingetragen


if not "spielername" in form:
print("<p)Kein Name, kein Spiel</p)")
print("<a href~'[Link]
"/[Link]')Zur&uuml :ck</a)")
print("</body)")
print( "</html)")
[Link](O)

# Formularbeginn
print("<form action~'[Link] ')")
I
lf Spi el ername
print("<p)Hallo <b)" , form["spielername"].value,
"</b), Ihre Aufgaben</p)")
print("<td)<input name~'spielername' type~'hidden' "
"value~'" + form["spielername"].value + "')")

lf Sta rtzeit
startzeit ~ [Link]()
print("<td)<input name~'startzeit' type~'hidden' "
"value~'" + str(startzeit) + "')")

# Tabellenbeginn
print("<table border~'O')")

lf 5 Aufgaben
for aufgabe in range(5):
# Aufgabe mit Ergebnis
a ~ [Link](lO,30)
10 I Internet

b [Link](lO.30)
c a + b

lf Tabellenzeile
print( "<tr)")
print("<td)&nbsp;" + str(aufgabe+l)
+ ".&nbsp;</td)")
print("<td)&nbsp;" + str(a) + "&nbsp;</td)")
print("<td)&nbsp;+&nbsp;</td)")
print("<td)&nbsp;" + str(b) + "&nbsp;</td)")
print("<td)&nbsp;~&nbsp;</td)")

print("<td)<input name~'ein" + str(aufgabe)


+ ... size~'12')</td)")
print( "</tr)")

# Richtiges Ergebnis senden


print("<input name~'erg" + str(aufgabe) + .....
+ "type~·hidden· value~'" + str(c) + ''')'')

lf Tabell enende
print("</table)")

lf Absenden
print("<p)<input type~'submit' value~'Fertig')</p)")

# HTML-Dokumentende
print("</form)")
print("</body)")
print("</html)")

Listing 10.19 Datei p1 01 [Link]

Zur Erläuterung:

Python- ~ Dem Webserver wird mitgeteilt, wo er den Python-Interpreter findet.


I nterp reter Nach Einbindung einiger Module wird der Zufallsgenerator initiali-
siert.
~ Eingaben aus dem ersten Formular werden in die Python-Variable
fo rm übernommen.
HTML-Dokument ~ Nach dem HTML-Header beginnt das eigentliche HTML-Dokument.
Hyperlink ~ Falls im ersten Formular kein Spielername eingegeben wurde, wird
nur noch ein Hyperlink angeboten, der zurück zum ersten Formular
führt. ohne Spielername geht es nicht weiter, das HTML-Dokument
und das Python CGI-Skript enden.

286
Spiel, Version für das Internet I 10.4

~ Der übermittelte Spielername wird angezeigt und für die spätere Aus- Versteckte Felder
wertung versteckt (type~' h i dden ,) im Formular eingetragen.
~ Die Startzeit wird aufgezeichnet und für die spätere Auswertung
ebenfalls versteckt im Formular eingetragen.
~ Es wird ein HTML-Tabelle aufgebaut. Darin werden in einer fo r- HTML-Tabelle
Schleife die fünf Aufgaben und die fünf Eingabefelder für die
Lösungsversuche eingetragen. Der Name der fünf Eingabefelder wird
dynamisch zusammengesetzt: ein 0 bis ei n4.
~ Parallel dazu werden die fünf richtigen Lösungen für die spätere Aus-
wertung versteckt im Formular eingetragen. Die Felder erhalten die
Namen ergO bis erg4.
~ Es folgen das Ende der Tabelle, der Button zum Absenden und das
Ende des HTML-Dokuments.

Auswertungsseite
Die Auswertungsseite beinhaltet ein Hauptprogramm und vier Funktio- Modularer Aufbau
nen:
~ Funktion hs_l esen ( ): Lesen der Highscores aus der Datei in eine Liste
~

~
Funktion
Funktion
Funktion
hs_schreiben():

hs_anzei gen ():

hs_h i nzu ( ):
Schreiben der Highscore-Liste in die Datei
Anzeigen der Highscore-Liste im Browser
ermittelte Zeit in Highscore-Liste einfügen
I
Die ersten beiden Funktionen stimmen mit den entsprechenden Funkti-
onen der letzten Spielversion überein. Das Lesen und Schreiben der
Datei hat sich nicht geändert, daher wird der Code hier nicht eigens
abgebildet.

Das Anzeigen der Highscore-Liste wurde an die Ausgabe im Browser HTML-Tabelle


angepasst. Statt einer formatierten Aufgabe auf dem Bildschirm wird
eine HTML-Tabelle erzeugt. Die Funktion hs_hinzu() ist ein Teil der
Funktion s pie 1 ( ) aus der letzten Spielversion.
Sie erkennen daran die leichte Wiederverwendbarkeit von modular auf-
gebauten Programmen. Der Code lautet:
#!C:\Python30\[Link]
lfModul e
import cgi. cgitb. time. glob. pickle
lfAusgabe bei Fehl er
[Link]( )
10 I Internet

# Funktion Highscore Lesen


def hs_lesen(): [ ..... ]

# Funktion Highscore Anzeigen


def hs_anzeigen():
# Ausgabe Highscore
print( "<tabl e)")
print("<tr)<td)Platz</td)<td)&nbsp:Name&nbsp:</td)"
"<td al ign~' right ')Zeit</td)</tr)")
for i in range(len(hs_liste)):
print( "<tr)")
print("<td align~'right')" + str(i+l) + "</td)")
print("<td)&nbsp:" + hs_liste[i][O]
+ "&nbsp:</td)")
print("<td align~'right')" + "{O:.2f} sec". \
format(hs_liste[i][1]) + "</td)")
print( "</tr)")

if i )~ 9:
break
pri nt( "</tabl e)")

# Funktion Highscore Schreiben


def hs_schreiben(): [ ..... ]

# Funktion Highscore Hinzu


def hs_hinzu(name, differenz):
# Mitten in Liste schreiben
gefunden ~ False
for i in range(len(hs_liste)):
# Einsetzen in Liste
i f differenz< hs_liste[iHl]:
hs_liste.insert(i, [name, differenz])
gefunden ~ True
break

# Ans Ende der Liste schreiben


if not gefunden:
hs_l [Link]( [name, differenz])

288
Spiel, Version für das Internet I 10.4

Ir Hauptprogramm

# Objekt der Klasse FieldStorage


form ~ cgi .FieldStorage()

# Zeit berechnen
endzeit ~ [Link]()
differenz ~ endzeit float(form["startzeit"].value)

Ir Header
print( "Content type: text/html")
pr i nt ( )

# HTML-Dokumentbeginn
print( "<html)")
print("<body)")
print("<p)<b)Kopfrechnen</b)</p)")

Ir Spi el ername
print("<p)Hallo <b)", form["spielername"].value,
"</b), Ihr Ergebnis</p)")

Ir Auswertung
richtig ~ 0
for aufgabe in range(5):
if "ein" + str(aufgabe) in form:
I
if form["ein" + str(aufgabe)].value ~~ \
form["erg" + str(aufgabe)].value:
richtig +~ 1

Ir Ausgabe
print("<p){O:d} von 5 in {1:.2f} Sekunden". \
format(richtig, differenz), end ~ "")

Ir Highscore
if richtig ~~ 5:

print(", Highscore</p)")
hs_lesen()
hs_hinzu(form["spielername"].value, differenz)
hs_schrei ben()
hs_anzeigen()
else:
print(", leider kein Highscore</p)")

289
10 I Internet

# Hyperlink zum Anfang


print("<p)<a href~'[Link]
"Zum Start</a)</p)")

# HTML-Dokumentende
print("</body)")
print("</html)")

Listing 10.20 Datei [Link]

Zur Erläuterung:
~ Die Funktion hs_anzei gen () beinhaltet eine HTML-Tabelle mit Über-
schrift und einzelnen Zeilen für die Highscore-Daten. Die Zahlen wer-
den für die Anzeige mithilfe der Funktionen s t r () und form a t ( ) in
Zeichenketten umgewandelt.
~ An die Funktion hs_hinzu() werden Name und ermittelte Zeit des
Spielers übergeben. Diese beiden Werte werden an passender Stelle
in die Highscore-Liste eingefügt oder hinten angehängt.
~ Im Hauptprogramm wird die Endzeit ermittelt. Aus der übermittelten
Startzeit und der Endzeit wird die Ergebniszeit errechnet.
~ Die fünfLösungen werden mit den fünf Eingaben verglichen, und die
Anzahl der gelösten Aufgaben wird berechnet. Wurden alle Aufgaben
richtig gelöst, so werden
~ die Highscores aus der Datei eingelesen,
~ der neue Highscore mit Name und Ergebniszeit hinzugefügt,
~ die Highscore-Liste wieder in die Datei geschrieben und
~ die Highscores angezeigt.
~ Schließlich wird der Hyperlink zum Start des Programms angegeben.

29°
11 Datenbanken

Eine Datenbank dient zur Speicherung größerer Datenmengen und zur


übersichtlichen Darstellung bestimmter Daten aus diesen Datenmengen.

11.1 Aufbau von Datenbanken

Innerhalb einer Datenbank befinden sich verschiedene Tabellen. Im Fol-


genden sehen Sie eine einfache Beispieltabelle.

Personalnummer Geburtstag
Maier Hans 6714 3500,00 15.03.62
Schmitz Peter 81343 3750,00 12.04.58
Mertens Julia 2297 3621,50 30.12.59

Tabelle 11.1 Beispiel mit Personaldaten

Die Begriffe in der ersten Zeile bezeichnet man als die Felder der Tabelle. Feld, Datensatz
Es folgen die einzelnen Datensätze der Tabelle - in diesem Fall sind es drei.

I
Natürlich legt niemand für drei Datensätze eine Datenbank mit einer Struktur,
Tabelle an, aber die vorliegende Struktur könnte auch für mehrere tau- Datentyp

send Datensätze verwendet werden. Die Felder haben jeweils einen


bestimmten Datentyp. In diesem Fall gibt es die Datentypen Text, ganze
Zahlen, zahlen mit Nachkommastellen und Datumsangaben.

Eine Datenbank wird in den folgenden Schritten erzeugt: Reihenfolge

~ Anlegen der Datenbank


~ Anlegen von Tabellen durch Angabe der Struktur
~ Eingeben der Datensätze in die Tabellen

Die Struktur einer existierenden Datenbank oder Tabelle kann auch dann Strukturänderung
noch verändert werden, wenn die Datenbank bereits Daten enthält.
Allerdings sollten Sie die Struktur Ihrer Datenbank stets gründlich pla-
nen, da es bei einer nachträglichen Veränderung leicht zu Datenverlus-
ten kommt.

291
11 I Datenbanken

SQL In diesem Buch arbeiten wir mit einem kleinen Datenbanksystem:


SQLite. Dabei handelt es sich um ein SQL-basiertes System. SQL (Struc-
tured Query Language) ist die meistverwendete Datenbanksprache der
Welt. SQL-Anweisungen dienen

~ zur Erzeugung der Struktur von Datenbanken und Tabellen und


~ zum Bearbeiten der Datensätze (Erzeugen, Anzeigen, Ändern,
Löschen).

11.2 SQlite
Modul sqlite3 SQLite ist ein einfacher Ersatz für ein komplexes Datenbankmanage-
ment-System. Es wird über das Modul sql ite3 direkt in Python einge-
bunden, arbeitet auf der Basis von Textdateien und kann bei kleineren
Datenmengen eingesetzt werden. Es erfordert keine zusätzlichen Instal-
lationen.

Datentypen SQLite bietet standardmäßig die folgenden Datentypen:


~ TE XT, für Zeichenketten
~ INTEGER, für ganze Zahlen
~ FLOAT, für Zahlen mit Nachkommastellen
~ BLOB, für binary Zarge objects, also große binäre Datenmengen
~ NULL, entspricht None in Python

Für die Kontrolle und die richtige Konvertierung anderer Datentypen


von SQLite nach Python, zum Beispiel einer SQLite-Zeichenkette in eine
Python-Variable für eine Datumsangabe, muss der Entwickler selber sor-
gen.

Hinweis
Die oben genannten Datentypen und andere SQL-spezifische Angaben werden
in Großbuchstaben geschrieben. Dies ist für SQL nicht notwendig, dient aber
zur deutlicheren Darstellung.

11.2.1 Datenbank, Tabelle und Datensätze


Erzeugen Im folgenden Programm wird zunächst eine SQLite-Datenbank erzeugt
und eine Tabelle mit einem eindeutigen Index angelegt. Anschließend
werden drei Datensätze in der Tabelle angelegt. Als Beispiel dient Tabelle
11.1 am Anfang dieses Kapitels.

292
SQ Lite I 11.2

Der eindeutige Index dient dazu, Datensätze zu erzeugen, die jeweils ein Eindeutiger Index
unverwechselbares Merkmal haben und somit eindeutig identifiziert
werden können. In der Personentabelle ist dazu das Feld personalnum-
me r geeignet.

Das Programm lautet:


import sqlite3

# Verbindung zur Datenbank erzeugen


connection ~ [Link]("[Link]")

# Datensatzcursor erzeugen
cursor ~ [Link]()

# Tabelle erzeugen
sql ~ "(REATE TABLE personen(" \
"name TEXT, " \
"vorname TEXT, " \
"personal nummer INTEGER PRIMARY KEY, " \
"gehalt FLOAT, " \
"geburtstag TEXT)"
[Link](sql)

# Datensatz erzeugen
sql ~ "INSERT INTO personen VALUES( 'Maier' , " \
"'Hans', 6714,3500, '15.03.1962')"

I
[Link](sql)
[Link]()

# Datensatz erzeugen
sql ~ "INSERT INTO personen VALUES( 'Schmitz', " \
"'Peter', 81343, 3750, '12.04.1958')"
[Link](sql)
[Link]()

# Datensatz erzeugen
sql ~ "INSERT INTO personen VALUES( 'Mertens', " \
"'Julia', 2297,3621.5, '30.12.1959')"
[Link](sql)
[Link]()

# Verbindung beenden
[Link]()

Listing 11.1 Datei [Link]

293
11 I Datenbanken

Zur Erläuterung:

connectO ~ Zunächst wird mithilfe der Funktion connect () aus dem Modul
sql ite3 eine Verbindung zur Datenbank hergestellt. Falls die Daten-
bankdatei (hier die Datei [Link] im gleichen Verzeichnis) noch
nicht existiert, wird sie nun erzeugt.
Connection- ~ Der Rückgabewert der Funktion connect ( ) ist ein Objekt der Klasse
Objekt sql ite3. connect i on. Über diese Verbindung kann auf die Daten-
bank zugegriffen werden.
cursorO ~ Mithilfe der Methode cursor() des Connection-Objekts wird ein
Datensatz-Cursor erzeugt.
Cursor-Objekt ~ Der Rückgabewert der Methode cursor() ist ein Objekt der Klasse
sql [Link]. Über diesen Cursor können SQL-Abfragen an die
Datenbank gesendet und die Ergebnisse empfangen werden.
executeO ~ Es wird eine Zeichenkette zusammengesetzt, die einen SQL-Befehl
beinhaltet. Dieser SQL-Befehl wird anschließend mit der Methode
execute ( ) des Cursor-Objekts an die Datenbank gesendet.

CREATE TABLE ~ Die SQL-Anweisung CREA TE TAB LE erzeugt eine Tabelle in einer
Datenbank. Hinter dem Namen der Tabelle (hier: personen) werden
in Klammern die einzelnen Felder der Tabelle jeweils mit Datentyp
angegeben.
Datentypen ~ Die Felder name, vorname und geburtstag sind vom Typ TEXT. Das
Feld gehal t ist vom Typ FLOAT, das Feld personal nummer vom Typ
INTEGER.
Eindeutiger Index ~ Auf dem Feld personal nummer wird mithilfe der Anweisung PRIMARY
KEY ein eindeutiger Index definiert.
INSERT INTO ~ Mithilfe der SQL-Anweisung I NSERT I NTO werden Datensätze ange-
legt. Es handelt sich um eine sogenannte Aktionsabfrage, die zu einer
Änderung in der Tabelle führt.
commitO ~ Auf eine Aktionsabfrage sollte immer ein Aufruf der Methode com-
mi t () des Connection-Objekts folgen, damit die Änderungen unmit-
telbar ausgeführt werden.
Felder, Werte ~ In der SQL-Anweisung INSERT INTO werden nach dem Namen der
Tabelle und dem schlüsselwort VALUES die einzelnen Werte des
Datensatzes für die Felder der Tabelle in Klammern angegeben. Dabei
ist es wichtig, Zeichenketten in einfache Anführungsstriche zu setzen.
Außerdem muss die Reihenfolge der Felder wie bei der Erzeugung der
Tabelle eingehalten werden.

294
SQ Lite I 11.2

~ Zuletzt wird die Verbindung zur Datenbank mithilfe der Methode doseO
cl 0 s e ( ) wieder geschlossen.

11.2.2 Daten anzeigen


Es sollen alle Datensätze der Tabelle mit allen Inhalten angezeigt werden. Alle Datensätze
Das Programm:
import sqlite3

# Verbindung. Cursor
connection ~ [Link]("[Link]")
cursor ~ [Link]()

lf SOL Abfrage
sql ~ "SELECT * FROM personen"

# Kontrollausgabe der SOL-Abfrage


lf print(sql)

# Absenden der SOL-Abfrage


# Empfang des Ergebnisses
[Link](sql)

# Ausgabe des Ergebnisses


for dsatz in cursor:
print(dsatz[OJ. dsatz[1J. dsatz[2J.
dsatz[3J. dsatz[4J)

# Verbindung beenden
[Link]()
I
Listing 11.2 Datei [Link]

Das Programm erzeugt die Ausgabe:


Mertens Julia 2297 3621.5 30.12.1959
Maier Hans 6714 3500.0 15.03.1962
Schmitz Peter 81343 3750.0 12.04.1958

Zur Erläuterung:

~ Nach Erzeugung von Datenbankverbindung und Datensatz-Cursor executeO


wird mithilfe der Methode execute( ) eine SQL-Abfrage gesendet.

295
11 I Datenbanken

SELECT FROM ~ Die Abfrage SELECT FROM ist eine sogenannte Auswahlabfrage. Solche
Abfragen dienen nur zum Sichten, nicht zum Ändern der Datenbank-
inhalte.
Alle Felder ~ Die Anweisung SELECT * FROM personen liefert alle Felder und alle
Datensätze der Tabelle. Der Stern (*) steht für »alle Felder«.
Kontrollausgabe ~ Die SQL-Anweisung wurde zunächst in einer Zeichenkette gespei-
chert. Dies ist nicht zwingend notwendig, ermöglicht aber eine Aus-
gabe der Zeichenkette zur Kontrolle mit pr i nt (sq 1 ). Dies ist beson-
ders vorteilhaft für die Fehlersuche bei komplexeren SQL-Befehlen.
Ergebnis der ~ Nach Ausführung der Methode execute ( ) steht im Cursor-Objekt das
Abfrage Ergebnis der Abfrage zur Verfügung. Dabei handelt es sich um die
Datensätze, die zur Abfrage passen. Diese Reihe kann mithilfe einer
Schleife durchlaufen werden.
Tupel mit ~ Jeder Ergebnis-Datensatz steht in einem Tupe!, das aus den Werten
Datensatz für die einzelnen Felder in der gleichen Reihenfolge wie bei der
Erzeugung der Tabelle besteht.
~ Zuletzt wird die Verbindung zur Datenbank wieder beendet.

11.2.3 Daten auswählen. Operatoren


SELECTWHERE Mithilfe von SELECT in Verbindung mit der WHERE-Klausel können ein-
zelne oder mehrere Datensätze ausgewählt werden. Einige Beispiele:

import sql ite3

# Verbindung, Cursor
connection ~ [Link]("[Link]")
cursor ~ [Link]()

lf SQL -Abfragen
# Einzelne Felder
sql ~ "SELECT name, vorname FROM personen"
[Link](sql)
for dsatz in cursor:
print(dsatz[OJ, dsatz[lJ)
pr i nt ( )

lf Auswahl mi t where- Kl ausel und Vergl ei chsoperator


sql "SELECT * FROM personen " \
~
"WHERE gehalt> 3600"
[Link](sql)

296
SQ Lite I 11.2

for dsatz in cursor:


print(dsatz[OJ. dsatz[3J)
pr i nt ( )

Ir Auswahl mit Zei chenkette


sql ~ "SELECT * FROM personen " \
"WHERE name ~ . Schmitz'"
[Link](sql)
for dsatz in cursor:
print(dsatz[OJ. dsatz[lJ)
pr i nt ( )

Ir Auswahl mit 1ogi schen Operatoren


sql ~ "SELECT * FROM personen " \
"WHERE gehalt >~ 3600 AND gehalt <~ 3650"
[Link](sql)
for dsatz in cursor:
print(dsatz[OJ. dsatz[3J)

# Verbindung beenden
[Link]()
Listing 11.3 Datei p11 03 .py

Erzeugt wird die Ausgabe:


Mertens Jul i a
Maier Hans
Schmitz Peter

Mertens 3621.5
Schmitz 3750.0
I
Schmitz Peter

Mertens 3621.5

Zur Erläuterung:
~ Es handelt sich um vier verschiedene SQL-Abfragen, die nacheinander
ausgeführt werden.
~ Wenn man nur die Werte einzelner Felder sehen mächte, werden die Felder auswählen
Namen dieser Felder zwischen SELECT und FROM notiert. Die Anwei-
sung SELECT name, vorname FROM personen liefert nur die Inhalte der
beiden genannten Felder aller Datensätze der Tabelle.

297
11 I Datenbanken

Daten sätze ~ Mithilfe von WHERE können Sie die Auswahl der Datensätze einschrän-
auswählen ken, indem Sie eine Bedingung mit Vergleichsoperatoren erstellen
(wie bei den Anweisungen i f oder wh i 1 e in Python).
Vergleichs- ~ Die Anweisung SELECT * FROM personen WHERE gehal t > 3600 liefert
operatoren die Inhalte aller Felder, aber (mithilfe eines Vergleichsoperators) nur
die Datensätze, bei denen der Wert des Feldes geha 1 t oberhalb der
genannten Grenze liegt (siehe auch Tabelle 11.2).
Anführungsstriche ~ Auch bei Zeichenketten kann ein Vergleich stattfinden. Dabei ist aller-
dings auf die einfachen Anführungsstriche zu achten. Die SQL-Anwei-
sung SELECT * FROM personen WHERE name ~ 'Schmitz' liefert nur die
Datensätze, bei denen der Name gleich »Schmitz« ist.
Logische ~ Logische Operatoren ermöglichen, wie in Python, die Verknüpfung
Operatoren mehrerer Bedingungen. Die Anweisung SELECT * FROM personen
WHERE gehal t >~ 3600 AND gehal t <~ 3650 liefert nur die Datensätze,
bei denen der Wert des Feldes geha 1 t innerhalb der genannten Gren-
zen liegt (siehe auch Tabelle 11.3)

Erläuterung
gleich
<> ungleich
größer als
>~ größer als oder gleich
kleiner als
<~ kleiner als oder gleich

Tabelle 11.2 Vergleichsoperatoren in SQL

Erläuterung
NOT Logisches NICHT: Der Wahrheitswert einer Bedingung wird
umgekehrt.
AND Logisches UND: Beide Bedingungen müssen zutreffen.
OR Logisches ODER: Nur eine der Bedingungen muss zutreffen.

Tabelle 11.3 Logische Operatoren in SQL

11.2.4 Operator like


Platzhalter Der Operator 1 i ke dient zur Auswahl von Datensätzen über Zeichenket-
ten, in denen Platzhalter vorkommen dürfen. Man kann also Abfragen
bilden wie:
~ Suche alle Datensätze, die mit ... beginnen.

298
SQ Lite I 11.2

~ Suche alle Datensätze, die mit ... enden.


~ Suche alle Datensätze, die ... beinhalten.

Einige Beispiele:
import sqlite3

# Verbindung. Cursor
connection ~ [Link]("[Link]")
cursor ~ [Link]()

lf SQL -Abfragen

lf Beliebig viele beliebige Zeichen


sql ~ "SELECT * FROM personen WHERE name LIKE 'mI'"
[Link](sql)
for dsatz in cursor:
print(dsatz[OJ. dsatz[lJ)
pr i nt ( )

lf Beinhaltet
sql ~ "SELECT * FROM personen WHERE name LIKE '%i%'"
[Link](sql)
for dsatz in cursor:
print(dsatz[OJ. dsatz[lJ)
pr i nt ( )

# Einzelne beliebige Zeichen


sql ~ "SELECT * FROM personen WHERE name LIKE 'M
[Link](sql)
for dsatz in cursor:
print(dsatz[OJ. dsatz[lJ)
er'"

I
# Verbindung beenden
[Link]()
Listing 11.4 Datei p11 [Link]

Es wird die Ausgabe erzeugt:


Mertens Jul i a
Maier Hans

Maier Hans
Schmitz Peter

Maier Hans

299
11 I Datenbanken

Zur Erläuterung:

Platzhalter % ~ Der Platzhalter % (Prozentzeichen) steht für eine unbestimmte Anzahl


beliebiger Zeichen. Die Anweisung SELECT * FROM personen WHERE
name LI KE 'm%' liefert nur die Datensätze, bei denen der Name mit
dem Buchstaben »m« beginnt (unabhängig von Groß- und Klein-
schreibung).
~ Steht das Prozentzeichen vor und nach einem bestimmten Zeichen, so
werden alle Datensätze gesucht, in denen dieses Zeichen vorkommt.
Die Anweisung SE LECT * FROM pe rsonen WH ERE name LI KE '% i %' liefert
nur die Datensätze, in denen der Buchstabe »i« (oder »I«) vorkommt.
Platzhalter ~ Der Platzhalter _ (Unterstrich) steht für ein einzelnes, beliebiges Zei-
chen. Die Anweisung SELECT * FROM personen WHERE name LI KE
'M_er' liefert nur die Datensätze, bei denen der Name mit »M«
beginnt und der nach zwei weiteren Zeichen mit »er« endet. Dies trifft
zum Beispiel auf »Maien<, »Meier«, »Mayer« oder »Meyer« zu.

11.2.5 Sortierung der Ausgabe


ORDER BY Mithilfe von ORDER BY werden die Datensätze in sortierter Form geliefert.
Es kann nach einem oder mehreren Feldern, aufsteigend oder absteigend
sortiert werden.

Ein Beispiel:
import sql ite3

# Verbindung. Cursor
connection ~ [Link]("[Link]")
cursor ~ [Link]()

# Sortierung fallend
sql ~ "SELECT * FROM personen ORDER BY gehalt DESC"
[Link](sql)
for dsatz in cursor:
print(dsatz[OJ. dsatz[lJ. dsatz[3J)
pr i nt ( )

# Sortierung nach mehreren Feldern


sql ~ "SELECT * FROM personen ORDER BY name. vorname"
[Link](sql)

300
SQ Lite I 11.2

for dsatz in cursor:


print(dsatz[OJ. dsatz[lJ)

[Link]()
Listing 11.5 Datei [Link]

Die Ausgabe lautet:


Maier Wolfgang 3810.0
Schmitz Peter 3750.0
Mertens Jul i a 3621. 5
Maier Hans 3500.0

Maier Hans
Maier Wolfgang
Mertens Jul i a
Schmitz Peter

Zur Erläuterung:
~ Zur deutlicheren Darstellung wurde vor Ausführung dieses Pro-
gramms noch ein weiterer Datensatz hinzugefügt.
~ Die Anweisung SELECT * FROM personen ORDER BY gehal t DESC liefert DEse, Ase
alle Datensätze, absteigend nach Gehalt sortiert. Der Zusatz DESC steht
für descending (absteigend). Für ein aufsteigende Sortierung könnte
man den Zusatz ASC (ascending, deutsch: aufsteigend) verwenden.

I
Dies ist allerdings der Standard, daher kann der Zusatz entfallen.
~ Die Anweisung SELECT * FROM personen ORDER BY name, vorname lie- Mehrere Felder
fert alle Datensätze, aufsteigend nach Name sortiert. Bei gleichem
Namen wird nach Vorname sortiert.

11.2.6 Auswahl nach Eingabe


Der Benutzer kann Datensätze in eingeschränkter Form auch selbst auswäh- Eingabe des
len. Mit dem folgenden Programm werden nur die Datensätze angezeigt, Benutzers

~ die dem eingegebenen Namen entsprechen oder


~ die den eingegebenen Namensteil beinhalten.
import sqlite3

# Verbindung. Cursor
connection ~ [Link]("[Link]")
cursor ~ [Link]()

301
11 I Datenbanken

lf Ei ngabe Name
eingabe ~ input("Bitte den gesuchten Namen eingeben: ")
sql ~ "SELECT * FROM personen WHERE name LIKE '" \
+ eingabe + "'"
print(sql)
[Link](sql)
for dsatz in cursor:
print(dsatz[O], dsatz[l])
pr i nt ( )

lf Ei ngabe Tei 1 des Namens


eingabe ~ input("Bitte den gesuchten Namensteil eingeben: ")
sql ~ "SELECT * FROM personen WHERE name LIKE 'I" \
+ eingabe + "I'"
print(sql)
[Link](sql)
for dsatz in cursor:
print(dsatz[O], dsatz[l])
pr i nt ( )

[Link]()
Listing 11.6 Datei [Link]

Die Ausgabe (mit Eingabe des Benutzers) sieht wie folgt aus:
Bitte den gesuchten Namen eingeben: Maier
SELECT * FROM personen WHERE name LIKE 'Maier'
Maier Hans
Maier Wolfgang

Bitte den gesuchten Namensteil eingeben: r


SELECT * FROM personen WHERE name LIKE '%r%'
Mertens Julia
Maier Hans
Maier Wolfgang

Zur Erläuterung:

~ Beim ersten Mal hat der Benutzer den Namen »Maien< eingegeben. Es
wird ein SQL-Befehl zusammengesetzt, der diese Benutzereingabe
beinhaltet. Sodann werden alle Datensätze mit dem Namen »Maien<
geliefert.
Kontrollausgabe ~ Gerade bei zusammengesetzten SQL-Anweisungen lohnt sich eine
Ausgabe des SQL-Befehls während der Entwicklungszeit. So können
Sie beispielsweise kontrollieren, ob die einfachen Anführungsstriche
gesetzt wurden.

302
SQ Lite I 11.2

~ Beim zweiten Mal hat der Benutzer nur das Zeichen »r« eingegeben.
Diese Eingabe wird in Prozentzeichen (und einfache Anführungsstri-
che) gesetzt. Es werden alle Datensätze geliefert, deren Name ein »r«
beinhaltet.

11.2.7 Datensätze ändern


Die Anweisung UPDA TE dient zur Änderung von Feldinhalten in einem UPDATE
oder mehreren Datensätzen. Sie ähnelt in ihrem Aufbau der Anweisung
SELECT. Wählen Sie Ihre Auswahlkriterien sorgfältig, um nicht verse-
hentlich andere als die gemeinten Datensätze in die Änderung einzube-
ziehen.
SOLCommand ~ "UPDATE personen SET gehalt ~ 3800"

Diese Anweisung würde bei sämtlichen Datensätzen der Tabelle pe r s 0-


nen den Wert für das Feld gehal t auf den Wert 3800 setzen - diese
Aktion ist sicherlich nicht beabsichtigt.

Nehmen Sie daher eine Einschränkung vor, am besten über das Feld mit Eindeutiger Index
dem eindeutigen Index (hier das Feld pe r s on a 1 n umme r).
SOLCommand ~ "UPDATE personen SET gehalt ~ 3780 " \
"WHERE personal nummer ~ 81343"

Das Beispiel mit einer Ausgabe vor der Änderung und einer Ausgabe Vorher, nachher
nach der Änderung sieht wie folgt aus:
import sqlite3

def ausgabe():
# SOL-Abfrage. senden. Ausgabe
I
sql ~ "SELECT * FROM personen"
[Link](sql)
for dsatz in cursor:
print(dsatz[OJ. dsatz[lJ. dsatz[2J. dsatz[3J)
print()

# Verbindung. Cursor
connection ~ [Link]("[Link]")
cursor ~ [Link]()

lf Vorher
ausgabe()

lf Datensatz aktualisieren
11 I Datenbanken

sql "UPDATE personen SET gehalt ~ 3780 " \


~
"WHERE personal nummer ~ 81343"
[Link](sql)
[Link]()

lf Nachher
ausgabe( )

[Link]()

Listing 11.7 Datei [Link]

Folgende Ausgabe wird erzeugt:


Mertens Julia 2297 3621.5
Maier Hans 6714 3500.0
Maier Wolfgang 8339 3810.0
Schmitz Peter 81343 3750.0

Mertens Julia 2297 3621.5


Maier Hans 6714 3500.0
Maier Wolfgang 8339 3810.0
Schmitz Peter 81343 3780.0

Zur Erläuterung:
~ Wie Sie sehen, wurde nur ein Datensatz verändert. Aufbau und Aus-
wirkung des SQL-Befehls wurden bereits erläutert.

Mehrere Felder Sollen mehrere Feldinhalte eines Datensatzes gleichzeitig geändert wer-
ändern den, kännte dies wie folgt aussehen:
sql ~ "UPDATE personen SET gehalt ~ 3780. " \
"vorname ~ 'Hans-Peter' " \
"WHERE personal nummer ~ 81343"

Unerlaubte Zu den Änderungen, die nicht durchgeführt werden dürfen, gehärt der
Änderung Eintrag eines Datensatzes mit einem bereits vorhandenen Wert für das
Feld mit dem eindeutigen Index. In der vorliegenden Tabelle kann also
kein neuer Datensatz eingetragen werden, der im Feld pe r s on a 1 n umme r
einen Wert hat, der bereits in einem anderen Datensatz vorhanden ist.

Das Gleiche gilt für die entsprechende Änderung eines Datensatzes. Der
Wert für das Feld pe rsona 1 nummer eines Datensatzes darf also nur einmal
vorkommen.

3°4
SQ Lite I 11.2

So würde die Anweisung:

sql ~ "UPDATE personen SET personal nummer 6714 " \


"WHERE personal nummer ~ 81343"

zur folgenden Fehlermeldung führen:

[Link]: PRIMARY KEY must be unique

Dies liegt daran, dass für das Feld pe rs ona 1 n umme r mit dem Zusatz PR 1- unique
MA RY KEY ein eindeutiger Index definiert wurde. Daher ist jede Personal-
nummer einzigartig (englisch: unique). Die Personalnummer 6714
gehärt aber bereits zu einem anderen Datensatz.

11.2.8 Datensätze löschen


Mit der SQL-Anweisung DELETE werden Datensätze geläscht. Achten Sie DELETE
auch hier darauf, welche Datensätze Sie genau läschen mächten, damit nicht
unbeabsichtigt alle Datensätze auf einmal geläscht werden. Ein Beispiel:

import sqlite3

def ausgabe():
# SQL-Abfrage. senden. Ausgabe
sql ~ "SELECT * FROM personen"
[Link](sql)
for dsatz in cursor:
print(dsatz[OJ. dsatz[lJ. dsatz[2J. dsatz[3J)
print()

# Verbindung. Cursor
connection ~ [Link]("[Link]")
cursor ~ [Link]()
I
IrVorher
ausgabe()

# Datensatz entfernen
sql ~
"DELETE FROM personen" \
"WHERE personal nummer 8339"
[Link](sql)
[Link]()

IrNachher
ausgabe()

[Link]()

Listing 11.8 Datei p11 [Link]


11 I Datenbanken

Die Ausgabe lautet:


Mertens Julia 2297 3621.5
Maier Hans 6714 3500.0
Maier Wolfgang 8339 3810.0
Schmitz Peter 81343 3780.0

Mertens Julia 2297 3621.5


Maier Hans 6714 3500.0
Schmitz Peter 81343 3780.0
Zur Erläuterung:
~ Der Datensatz mit der Personalnummer 8339 wurde gelöscht, wie der
Vergleich der Ausgabe vor dem Löschen mit der Ausgabe nach dem
Löschen zeigt.

11.3 SQlite auf dem Webserver

Sie können eine SQLite-Datenbank natürlich auch auf einem Webserver


zur dauerhaften Speicherung von Daten einsetzen.
Python CGI-Skript In diesem Abschnitt wird eine SQLite-Datenbank über ein Python CGI-
Interface zugänglich gemacht. Hierzu werden Sie Ihre Kenntnisse aus den
Abschnitten 10.2, »Webserver-Programmierung«, und 11.2, »SQLite«,
nutzen.
Datenbankdatei Da es sich bei einer SQLite-Datenbank um eine einfache Textdatei han-
schützen delt, sollte diese in einem eigenen, per Passwort geschützten Verzeichnis
liegen. Damit verhindert man, dass die Datei einfach komplett herunter-
geladen werden kann. Sie soll nur über das bereitgestellte Python CGI-
Interface genutzt werden.
Das Programm:
#!C:\Python30\[Link]

import sql ite3

lf Dokumenttyp
print("Content type: text/html ")
pr i nt ( )

lf Dokumentbegi nn
print( "<html)")
print("<body)")

306
SQLite auf dem Webserver I 11.3

# Verbindung, Cursor
connection ~ [Link]("sqlite/[Link]")
cursor ~ [Link]()

# SQL-Abfrage, Absenden, Ergebnis


sql ~ "SELECT * FROM personen"
[Link](sql)

# Tabellenausgabe des Ergebnisses


print("<table border~'l'>")

i! Tabell enkopf
print("<tr><td>Name</td><td>Vorname</td>" \
"<td align~'right'>PNr.</td>" \
"<td align~'right'>Gehalt</td>" \
"<td>Geburtstag</td></tr>")

i! Tabellenzeile
for dsatz in cursor:
print( "<tr>" \
+ "<td>" + dsatz[O] + "</td>"
+ "<td>" + dsatz[l] + "</td>"
+ "<td align~'right'>" + str(dsatz[2]) + "</td>"
+ "<td align~'right'>"
+ "{O:.2f}".format(dsatz[3]) + "</td>"
+ "<td>" + dsatz[4] + "</td>" \
+ "</tr>")

i! Tabell enende
print( "</tabl e>")

# Verbindung beenden
[Link]()
I
i! 00 kumentende
print("</body>")
print( "</html >")
Listing 11.9 Datei [Link]

Abbildung 11.1 zeigt die Ausgabe im Browser nach Eingabe der Adresse
[Link]
11 I Datenbanken

~e IVorname I PNr· 1 Gehal~ IGeburts tag ]


IMertens IJulia I 22971362150 130 12 .1959
IMaie r IHans I 671413500001 1503 1962
ISchmitz IPeter ~1378000 11204 1958

Abbildung 11.1 Datenbankinhalte auf dem Webserver

Zur Erläuterung:

Xampp ~ Das Python-Programm [Link] befindet sich (bei einer Standard-


installation von Xampp) im Festplattenverzeichnis C\xampp\cgi-bin.
Datenbankdatei ~ Der Inhalt der SQLite-Datenbankdatei [Link] ist aus dem vorheri-
gen Abschnitt bekannt. Die Datei liegt im Verzeichnis: C\xampp\cgi-
bin\sqlite. Dieses Verzeichnis sollte geschützt werden. Die Standard-
Konfigurationsprogramme für eigene Websites bieten unkomplizierte
Möglichkeiten zum Schutz von Verzeichnissen.
HTML-Dokument, ~ Das HTML-Dokument wird begonnen. Es wird Verbindung zur
Datenbankabfrage Datenbank aufgenommen. Eine Datenbankabfrage wird abgesendet,
das Ergebnis steht über den Datensatz-Cursor zur Verfügung.
HTML-Tabelle ~ Es wird eine HTML-Tabelle mit Rahmen begonnen.
~ Es folgt die erste Tabellenzeile mit der Überschrift. Sie enthält die
Bezeichnungen der einzelnen Felder.
Datensatz ~ Für jeden Datensatz wird eine Tabellenzeile erzeugt. In den einzelnen
Zellen der Tabellenzeile stehen die Werte der Datenbankfelder.
Formatierung ~ Die Personalnummer und das Gehalt werden rechtsbündig in die
Zelle geschrieben. Die Personalnummer wird mithilfe der Funktion
s t r () in eine Zeichenkette umgewandelt. Das Gehalt wird mithilfe
der Funktion fo rma t ( ) mit zwei Nachkommastellen formatiert.
~ Die HTML-Tabelle wird beendet, die Verbindung zur Datenbank
geschlossen und das HTML-Dokument beendet.

308
12 Benutzeroberflächen

Die Erstellung von komfortablen grafischen Benutzero berflächen für ver-


schiedene Betriebssystemplattformen mithilfe des Tk-Interfaces steht im
Zentrum dieses Kapitels. Die ereignisorientierte Programmierung rückt
dabei in den Vordergrund.

12.1 Einführung

Die bisher dargestellten Programme wurden über Eingaben in der Kom-


mandozeile bedient. Möchten Sie dem Benutzer dagegen eine komfor-
table Oberfläche zur Bedienung zur Verfügung stellen, so bietet sich bei
Python das Tk-Interface an.

Bei der Installation von Python unter den verschiedenen Betriebssyste- Tk-Interface
men kann das Tk-Interface leicht eingebunden werden oder steht stan-
dardmäßig zur Verfügung. Es bietet eine Reihe von Klassen zur Erzeu-
gung der einzelnen Elemente der Oberfläche.

Die Erstellung einer Oberflächen-Anwendung, einer sogenannten GUI- GUI


Anwendung (GUI = Graphical User Interface) umfasst die folgenden
wichtigen Schritte:

~ Erzeugung eines Hauptfensters, das alle Elemente der Anwendung Hauptfenster


I
enthält
~ Erzeugung und Anordnung von einzelnen Steuerelementen (hier Widgets
Widgets genannt ) innerhalb des Hauptfensters zur Bedienung der
Anwendung
~ Starten einer Endlosschleife, in der die Bedienung der Steuerelemente Endlosschleife
durch den Benutzer zu Ereignissen und damit zum Ablauf einzelner
Programmteile führt
In den folgenden Abschnitten werden diese drei Schritte genauer erläu-
tert.
12 I Benutzeroberflächen

12.1.1 Eine erste GUI-Anwendung


Das folgende einfache Programm beinhaltet bereits alle notwendigen
Elemente einer Gur-Anwendung:
import sys, tkinter

# Funktion zu Button Ende


def ende():
[Link](O)

lfHauptfenster
main ~ [Link]()

lf Button Ende
b ~ [Link](main, text "Ende", command ende)
[Link]()

#Endlosschleife
[Link]()

Listing 12.1 Datei [Link]

Benutzer- Das Ergebnis sieht in Abhängigkeit vom verwendeten Betriebssystem


oberfläche unterschiedlich aus. In jedem Fall sieht ein Benutzer eine Oberfläche in
gewohntem Design mit den ihm bekannten Bedienungselementen. Das
Ergebnis für Windows zeigt Abbildung 12.1.

Abbildung 12.1 Erstes Programm

Zur Erläuterung:
~ Zunächst wird das Modul sys importiert, das für den Aufruf der Funk-
tion ex i t ( ) benötigt wird. Diese dient zum Beenden des Programms.
Modul tkinter ~ Das Modul t k i nte r mit den Klassen zur Erzeugung der Oberflächen-
elemente wird importiert.
~ Die selbst geschriebene Funktion ende () wird definiert, die beim
Betätigen des gleichnamigen Buttons aufgerufen wird.
Klasse Tk ~ Es wird ein Objekt der Klasse Tk mit dem Namen ma in erzeugt. Dabei
handelt es sich um das Hauptfenster, das alle Elemente der Anwen-
dung enthält.

310
Einführung I 12.1

~ Als Beispiel für ein Steuerelement (ein Widget) wird ein Objekt der Button-Widget
Klasse Button mit dem Namen b erzeugt. Dabei werden drei Parame-
ter angegeben:
~ Der erste Parameter gibt an, zu welchem Hauptelement das wid-
get gehört - in diesem Fall zum Hauptfenster.
~ Der zweite, benannte Parameter text gibt die Aufschrift des But-
tons an.
~ Der dritte, ebenfalls benannte Parameter command gibt den Namen command
der Funktion an, die ausgeführt werden soll, wenn der Button
betätigt wird. Eine solche Kommandofunktion wird ca 1 1ba c k
genannt.
~ Es wird die Methode pa ck () auf den Button b angewendet. Diese packO
Methode dient als Geometriemanager zur geometrischen Anordnung
eines Widgets innerhalb des Hauptfensters. Gleichzeitig dient der
Geometriemanager dazu, das Widget sichtbar zu machen. In
Abschnitt 12.3, »Geometrische Anordnung von Widgets«, werden
noch andere Geometriemanager erläutert.
~ Zu guter Letzt wird mit der Funktion mai n 1 00 P( ) die Endlosschleife mainloopO
für das Hauptfenster aufgerufen, die dafür sorgt, dass alle Benutzer-
ereignisse empfangen und weitergeleitet werden.

Hinweis
Es ist empfehlenswert, eine GUI-Anwendung unter Windows unmittelbar mit
einem Doppelklick auf die Python-Datei (hier [Link]) im Windows Explorer
zu starten.
I
12.1.2 Ändern von Eigenschaften
Im ersten Beispiel wurden die Eigenschaften des Button-Widgets unmit-
telbar bei der Erzeugung festgelegt. Diese Eigenschaften können aber
auch später eingestellt oder verändert werden. Ein Beispiel:
import sys, tkinter

# Funktion zu drei Buttons


def ende():
[Link](O)

lfHauptfenster
main ~ [Link]()

311
12 I Benutzeroberflächen

Ir Button Ende 1
bl ~ [Link](main, text "Ende", command ende)

Ir Button Ende 2
b2 ~ [Link](main)
b2["text"] ~ "Auch Ende"
b2["command"] ende

Ir Button Ende 3
b3 ~ [Link](main)
[Link](text ~ "Ebenfalls Ende", command ende)

# Buttons anzeigen
[Link]()
[Link]()
[Link]()

# Endlosschleife
[Link]()

Listing 12.2 Datei [Link]

Bei Ausführung des Programms werden drei Buttons angezeigt, die auf
unterschiedliche Art und Weise erzeugt wurden:

Abbildung 12.2 Drei unterschiedlich erzeugte Buttons

Zur Erläuterung:
~ Der Button bl wird bei Erzeugung mit allen Eigenschaften versorgt.
Widget- ~ Der Button b2 wird zunächst nur erzeugt und dem Hauptfenster zuge-
Dictionary ordnet. Anschließend wird das Widget wie ein Dictionary genutzt.
Die jeweilige Eigenschaft wird als schlüssel verwendet, dem ein Wert
zugewiesen wird.
configureO ~ Der Button b3 wird ebenfalls zunächst nur erzeugt und dem Haupt-
fenster zugeordnet. Anschließend wird die Methode confi gure ( ) mit
benannten Parametern auf das Widget angewendet, um ihm Eigen-
schaften zuzuweisen.

312
Widget-Typen I 12.2

12.2 Widget- Typen


In diesem Abschnitt werden eine Reihe von Widget-Typen für die ver-
schiedenen Einsatzzwecke vorgestellt.

12.2.1 Anzeigefeld, Label


Ein Label-Widget wird zur Anzeige von Informationen verwendet. Dabei Label-Widget
kann es sich um ein Bild oder um einen unveränderlichen Text handeln.
Die Texte dienen in Gur-Anwendungen zur Erläuterung der Oberfläche
und ihrer Bedienelemente für den Benutzer.

Anhand von drei Labels sollen im folgenden Programm eine Reihe von Allgemeine
allgemeinen Widget-Eigenschaften gezeigt werden, die bei allen Arten Eigenschaften

von Widgets zur Anwendung kommen können.

Dies sind die Eigenschaften:


~ font (Schrift)
~ height (Höhe)
~ width (Breite)
~ borderwidth (Randbreite)
~ re 1 i ef (Randart)
~ image (Bild)

~ bg (background, Hintergrundfarbe)
~

~
fg (foreground, Vordergrundfarbe)
an cho r (Ausrichtung)

Das Programm sieht folgendermaßen aus:


I
import sys, tkinter

def ende():
[Link](O)

main ~ [Link]()

lf Erstes Label, mit Text


lb1 ~ [Link](main, text ~ "groove")
lbl["font"] ~ "Courier 16 italic"
lb1["height"] ~ 2
lb1["width"] ~ 20
lb1["borderwidth"] 5

313
12 I Benutzeroberflächen

lbl["relief"] ~ "groove"
lb1["bg"] ~ "#FFFFFF"
lb1["fg"] ~ "#000000"
lb1["anchor"] ~ "w"
[Link]()

Ir Ende- Button
b ~ [Link](main. text "Ende". command ende)
[Link]()

Ir Zweites Label. mit Text


lb2 ~ [Link](main. text "ridge")
lb2["font"] ~ "Arial 11 bold"
lb2["height"] ~ 2
lb2["width"] ~ 20
lb2["borderwidth"] ~ 5
lb2["relief"] ~ "ridge"
lb2["bg"] ~ "#FFFFFF"
lb2["fg"] ~ "#000000"
lb2["anchor"] ~ "e"
[Link]()

Ir Dri ttes Label. mi t Bi 1 d


lb3 ~ [Link](main)
im ~ [Link](file~"[Link]")
lb3["image"] ~ im
[Link]()

[Link]()

Listing 12.3 Datei [Link]

Das Ergebnis dieses Programms zeigt Abbildung 12.3.

groove

ridge l

Abbildung 12.3 Label

314
Widget-Typen I 12.2

Es werden insgesamt drei Objekte der Klasse Label (lbl, lb2 und lb3)
erzeugt und angezeigt.

Zur Erläuterung des ersten Labels:

~ Es zeigt den Text »groove«. Dieser Text ist in der Schriftart Courier, Schriftart
Größe 16, kursiv (italic) dargestellt.
~ Die Größe des Labels beträgt 2 mal 20 und ist abhängig von der ver- Größe
wendeten Schriftgröße. Diese Abhängigkeit der Größe von der
Schriftgröße gilt für alle Widgets mit Textinhalt. Bei Widgets mit gra-
fischem Inhalt bezieht sich die Größenangabe auf Pixel.
~ Die Randbreite beträgt 5 und die Randart ist 9 roove. Es gibt außerdem Rand
noch die Randarten rai sed (erhoben), sunken (eingesunken), fl at
(flach) und ri dge (mit einem Grat umrandet, siehe zweites Label).
~ Die Ausrichtung innerhalb des Labels hat den Wert "w", dies steht für Ausrichtung
den westlichen, also linken Rand des Labels. Erlaubte Werte sind: w,
e, s, n, nw, ne, s w, se und center.

~ Die Hintergrundfarbe ist weiß, die Vordergrundfarbe schwarz. Die Farbe


Farben können unter anderem in hexadezimalen Ziffern im Format
lfRRGGBB angegeben werden. Dabei gilt:
~ Die beiden ersten Ziffern stehen für den Rot-Anteil der Farbe.
~ Die folgenden beiden Ziffern stehen für den Grün-Anteil der
Farbe.
~ Die beiden letzten Ziffern stehen für den Blau-Anteil der Farbe.

~ Hexadezimale Ziffern sind (in aufsteigender Reihenfolge): 0, 1, 2, 3,


4, 5, 6, 7, 8, 9, A (entspricht dem Dezimalwert 10), B (= 11), C (= 12),
D (= 13), E (= 14), F (= 15). Siehe hierzu auch Abschnitt 4.1.1, »Ganze
I
zahlen«.
Zur Erläuterung des zweiten Labels:

~ Es zeigt den Text »ridge«. Dieser Text ist in der Schriftart Arial, Größe
11, fett (bold) dargestellt.
~ Die Größe des Labels beträgt ebenfalls 2 mal 20. Da die Schriftgröße
geringer ist, ist es kleiner als das erste Label.
~ Die Ausrichtung innerhalb des Labels hat den Wert" e" . Dies steht für
den östlichen, also rechten Rand des Labels (»e« für »east«).

315
12 I Benutzeroberflächen

Zur Erläuterung des dritten Labels:

Bild ~ Es zeigt das Bild aus der Datei [Link].


~ Zunächst wird ein Objekt der Klasse Photo Image erzeugt. Die Eigen-
schaft fi 1 e erhält als Wert den Dateinamen.
Photoimage ~ Der Eigenschaft image des Labels wird anschließend als Wert das
o bj ekt der Klasse Phot 0 I mag e zugeordnet.

12.2.2 Einzeilige Textbox, Entry


Entry-Widget Ein Entry-Widget ist eine einzeilige Textbox und dient im Allgemeinen
zur Eingabe von kurzen Texten oder Zahlen. Das folgende Beispiel soll
die Verarbeitung von eingegebenen Daten und die Ausgabe von berech-
neten Werten verdeutlichen.
Der Benutzer soll eine zahl in ein Entry-Widget eintragen. Diese Zahl
wird quadriert, und das Ergebnis wird in einem Label-Widget ausgege-
ben.
import sys, tkinter

def ende():
[Link](O)

# Funktion zum Quadrieren und Ausgeben


def quad():
eingabe ~ [Link]()
try:
zahl ~ float(eingabe)
lb["text"] "Ergebnis:" + str(zahl * zahl)
except:
lb["text"] "Bitte Zahl eingeben"

main [Link]()

lfeinzeiliges Eingabefeld
e ~ [Link](main)
[Link]()

# Button zur Verarbeitung und Ausgabe


bquad ~ [Link](main,
text ~ "Quadrieren", command quad)
[Link]()

lf Ausgabe- Label

316
Widget-Typen I 12.2

lb ~ [Link](main, text "Ergebnis:")


[Link]()

bende ~
[Link](main, text ~ "Ende",
command ~ ende)
[Link]()

[Link]()

Listing 12.4 Datei [Link]

Zunächst sieht die Anwendung wie in Abbildung 12.4 gezeigt aus.

Quadrieren I
Ergebnis:

Ende

Abbildung 12.4 Entry, Eingabeposition

Nach Eingabe einer zahl durch den Benutzer (hier 4.5) und Betätigung
des Verarbeitungs-Buttons wird das Ergebnis (hier 20.25) im Label ange-
zeigt.

tk GJ[QJ~
4.5
I
I
Quadrieren
Ergebnis: 20.25

Ende

Abbildung 12.5 Entry, Ergebnis

Zur Erläuterung:
~ Insgesamt werden zwei Objekte der Klasse Button (bquad und bende),
ein Objekt der Klasse Label (1 b) und ein Objekt der Klasse Entry (e)
erzeugt und angezeigt.
~ Bei Betätigung des Buttons QUADRIEREN wird die Funktion qua d ( )
aufgerufen.
~ In der Funktion qua d ( ) wird die Methode get () auf das Eingabefeld getO
angewendet. Sie liefert als Rückgabewert eine Zeichenkette, die die
Benutzereingabe beinhaltet. Diese Zeichenkette wird in der Variablen
ei ngabe gespeichert.

317
12 I Benutzeroberflächen

~ Mithilfe der Funktion f 1 0 a t () wird die Zeichenkette in eine Zahl


umgewandel t und in der Variab len z a h 1 gespeichert.
~ Die zahl wird quadriert, das Ergebnis wird mit der Funktion s t r ( ) in
eine Zeichenkette umgewandelt und zusammen mit der Zeichenkette
»Ergebnis:« im Label ausgegeben.

12.2.3 Versteckte Eingabe


show Ein Entry-Widget kann auch zur Eingabe von versteckten Informationen,
zum Beispiel Passwörtern dienen. Dazu dient die Eigenschaft show, in der
festgelegt wird, welches Zeichen in einem Entry-Widget angezeigt wer-
den soll, wenn der Benutzer Eingaben macht.
Passworteingabe Das folgende Beispiel veranschaulicht diese Nutzung. Die Eingabe in
einem Entry-Widget wird untersucht. Gibt der Benutzer das richtige
Wort ein, so erhält er die Rückmeldung Zugang erlaubt, anderenfalls die
Meldung Zugang verweigert.
import sys, tkinter

def ende():
[Link](O)

# Untersuchung des Passwortes


def pwtest():
eingabe ~ [Link]()
if eingabe ~~ "Bingo":
lb["text"] "Zugang erlaubt"
else:
lb["text"] "Zugang verweigert"

main [Link]()

# Eingabefeld mit Zeichen * als Darstellung


e ~ [Link](main, show ~ "*")
[Link]()

# Test der Eingabe


btest [Link](main, text ~ "Login",
~

command ~ pwtest)
[Link]()

# Anzeige des Ergebnisses


lb ~ [Link](main, text "Zugang")

318
Widget-Typen I 12.2

[Link]()

bende [Link](main, text ~ "Ende",


~

command ~ ende)
[Link]()

[Link]()

Listing 12.5 Datei [Link]

Das Ergebnis bei richtiger Eingabe (»Bingo«):

login I
Zugang erlaubt

Ende

Abbildung 12.6 Richtige Eingabe

Das Ergebnis bei falscher Eingabe:

Log;n I
Zugang verw eige rt
Ende

Abbildung 12.7

Zur Erläuterung:
Falsche Eingabe
I
~ Die Eigenschaft show des Entry-Widgets wird auf den Wert * gesetzt. show = "*"
Daher wird für jedes eingegebene Zeichen ein Stern angezeigt, wie
bei Passwörtern üblich.
~ Bei Betätigung des LOGIN-Buttons wird die Funktion pwtes t ( ) aufge-
rufen.
~ In der Funktion pwtest() wird der Inhalt des Eingabefeldes mit der
Funktion get ( ) abgerufen und in der Variablen ei ngabe gespeichert.
Dabei handelt es sich um den tatsächlich eingegebenen Inhalt, der
Stern dient nur zur Darstellung auf dem Bildschirm.
~ In der nachfolgenden Verzweigung wird eine der beiden möglichen
Ausgaben im Label erzeugt, abhängig vom Inhalt des Entry-Widgets.

319
12 I Benutzeroberflächen

12.2.4 Mehrzeilige Textbox, Text


Text-Widget Ein Text-Widget ist eine mehrzeilige Textbox und dient im Allgemeinen
zur Eingabe und Darstellung größerer Textmengen. Gegenüber dem
Entry-Widget bietet es nicht nur mehr Platz, sondern auch mehr Mög-
lichkeiten zur Verarbeitung von Daten.
Das folgende Codebeispiel stellt den Inhalt einer Textdatei in einem Text-
Widget dar.
import sys, tkinter

def ende():
[Link](O)

# Anzeigefunktion
def xshow():
d ~ open("[Link]")
z ~ [Link]()
while z:
[Link]("end", z)
z ~ [Link]()
[Link]()

main ~ [Link]()

lf mehrzeiliges Eingabefeld
t ~ [Link](main, width~70, height~10)

[Link]()

# Inhalt der Datei anzeigen


bshow [Link](main, text ~ "Anzeigen",
~
command ~ xshow)
[Link]()

bende [Link](main, text ~ "Ende",


~

command ~ ende)
[Link]()

[Link]()

Listing 12.6 Datei [Link]

Abbildung 12.8 zeigt die Darstellung nach Aufruf des Programms und
Betätigung des Buttons ANZEIGEN.

320
Widget-Typen I 12.2

zur Eingabe bzw. Darstellung grösserer


deru Entry-hlidget bietet es nicht nur ruehr
Möglichkeiten zur Verarbeitung von Daten.

Abbildung 12.8 Text-Widget mit Inhalt

Zur Erläuterung:

~ Insgesamt werden zwei Objekte der Klasse Button (bsho w und bende)
und ein Objekt der Klasse Text (t) erzeugt und angezeigt.
~ Bei Betätigung des Buttons ANZEIGEN wird die Funktion xsho w( ) auf-
gerufen.
~ In der Funktion xs h ow() wird die Datei p 12 06ein. txt geöffnet. Alle
Zeilen der Datei werden gelesen und mithilfe der Methode insert ()
in der Textbox dargestellt.
~ Die Methode ins er t ( ) benötigt zwei Parameter. Der erste Parameter insertO

I
gibt die Eingabeposition als Zeichenkette an. Der zweite Parameter
gibt die einzufügende Zeichenkette an.
~ Im vorliegenden Beispiel wird für die Einfügeposition der festgelegte end
Begriff end genutzt, der die Position nach dem letzten Zeichen der
letzten Zeile der Textbox bezeichnet.

Zeichen können aber auch an beliebigen Stellen in die Textbox eingefügt Einfügeposition
werden. Die Einfügeposition wird dabei in der Form Zei 1e. Zei ehen
angegeben. Die Zeilennummerierung beginnt innerhalb der Textbox bei
1, die Zeichennummerierung innerhalb einer Zeile beginnt bei O. Ein
Beispiel:

~ Die Anweisung t. i nse rt ( "3.7" . "ha 110") fügt den Text »hallo« in
der dritten Zeile nach dem achten Zeichen ein. Dies gilt allerdings
nur, falls diese Position existiert, falls also die Textbox bereits mindes-
tens drei Zeilen Text beinhaltet und die dritte Zeile mindestens acht
Zeichen beinhaltet.

321
12 I Benutzeroberflächen

12.2.5 Serollende Textbox, ScroliedText


ScroliedText- Falls die Breite der Textbox für den darzustellenden Text nicht ausreicht,
Widget wird der Text in der nächsten Zeile dargestellt. Wird die Anzahl der Zei-
len zu groß, so muss der Cursor zur gewünschten Stelle bewegt werden,
damit diese sichtbar wird.

Vertikales Scrollen In diesem Zusammenhang bringt das ScrolledText-Widget einen Kom-


fortgewinn: Es stellt eine Erweiterung einer mehrzeiligen Textbox dar
und ermöglicht zumindest das vertikale Scrollen innerhalb der Textbox.
Das Programm:
import sys, tkinter, [Link]

def ende():
[Link](O)

# Anzeigefunktion
def xshow():
d ~ open("[Link]")
z ~ [Link]()
while z:
t. insert( "end" ,z)
z ~ [Link]()
[Link]()

main ~ [Link]()

lf mehrzeiliges Eingabefeld
t ~ [Link](main,
width~70, height~3)

[Link]()

# Inhalt der Datei anzeigen


bshow [Link](main, text ~ "Anzeigen",
~
command ~ xshow)
[Link]()

bende [Link](main, text ~ "Ende",


~

command ~ ende)
[Link]()

[Link]()

Listing 12.7 Datei [Link]

322
Widget-Typen I 12.2

Die Ausgabe sieht nach Aufruf, Anzeige und Betätigung der Scrollbar bei-
spielsweise wie in Abbildung 12.9 aus.

Ein Text-~idget ist ein mehrzeiliges Eingabefeld und dient i.A.


zur Eingabe bzw. Darstellung grösserer Textmengen. Gegenüber
dem Entry-hlidget bietet es nicht nur mehr Platz, sondern auch mehr

Abbildung 12.9 Serollende Textbox

Zur Erläuterung:

~ Es wird ein Objekt der Klasse Sc ro 11 edText ( ) aus dem Modul tk in - ScroliedText
te r . sero 11 edtex t erzeugt und angezeigt.

12.2.6 Listbox mit einfacher Auswahl


Ein Listbox-Widget (Auswahlmenü) dient zur Aufnahme einer Reihe von Listbox-Widget
Begriffen, aus denen der Benutzer einen oder mehrere auswählen kann.

Im folgenden Programm wird eine Listbox mit insgesamt vier Elementen


versehen. Wenn der Benutzer ein Element auswählt und den Button
ANZEIGEN betätigt, wird das betreffende Element im Ausgabe-Label ange-
zeigt.
import sys, tkinter

def ende():
[Link](O)
I
def anzeigen():
lb["text"] ~ "Auswahl: "+ [Link]("active")

main ~ [Link]()

# Listbox mit vier Elementen


li ~ [Link](main, height~O)
1 i. insert( "end", "Hamburg")
1 i. insert( "end", "Stuttgart")
1 i. insert( "end", "Berl in")
li .insert("end","Dortmund")
1 i . pa ck ( )

323
12 I Benutzeroberflächen

Ir Auswahl anzei gen 1 assen


bshow ~ [Link](main, text ~ "Anzeigen",
command ~ anzeigen)
[Link]()

Ir Anzei gel abel


lb ~ [Link](main, text "Auswahl:" )
[Link]()

bende ~ [Link](main, text ~ "Ende",


command ~ ende)
[Link]()

[Link]()

Listing 12.8 Datei [Link]

Nach Aufruf, Auswahl eines Elements (hier: »Stuttgart«) und Betätigung


des Anzeige-Buttons ergibt sich folgende Darstellung.

tk [J[Ql[Rl

Auswahl: Stuttgart
Ende

Abbildung 12.10 Liste mit einfacher Auswahl

Zur Erläuterung:

~ Insgesamt werden zwei Objekte der Klasse Button (bs how und bende),
ein Objekt der Klasse La be 1 (1 b) und ein Objekt der Klasse Li s tbox
(1 i) erzeugt und angezeigt.
~ Die Listbox erhält bei Erzeugung die Höhe O. Damit erreicht man, dass
die Höhe immer der Anzahl der Elemente angepasst wird.
insertO ~ Die Methode i nse rt () dient zur Erzeugung von Elementen in der
Listbox. Sie benötigt zwei Parameter. Der erste Parameter gibt - ähn-
lich wie bei der Textbox - die Eingabeposition an. Der zweite Parame-
ter gibt das einzufügende Element an.
end ~ Als Einfügeposition wird der festgelegte Begriff end genutzt, der die
Position am Ende der Liste bezeichnet. Die Elemente werden jeweils

324
Widget-Typen I 12.2

am Ende der Liste eingefügt. Sie werden also in der Reihenfolge ange-
zeigt, in der sie im Programm angegeben sind.
~ In der Funktion a nzei gen ( ) wird die Methode get () auf das Label get (»active«)
angewendet. Diese liefert das Listenelement zur angegebenen Num-
mer. Der festgelegte Begriff a ct i ve liefert immer die Nummer des
vom Benutzer ausgewählten Elements.
~ Der über get ( ) gelieferte Begriff wird im Ausgabe-Label angezeigt.

Hinweise
1. Elemente können auch an beliebigen Stellen in die Listbox eingefügt wer-
den. Die Einfügeposition wird dann als Zahl angegeben. Die Nummerie-
rung beginnt dabei bei O.
2. Ein Beispiel: Hätte man bei allen vier Aufrufen der Methode insert() die
Nummer 0 anstelle der Zeichenkette end angegeben, so wäre jedes Ele-
ment jeweils an erster Position eingefügt worden. Die Elemente wären also
in umgekehrter Reihenfolge erschienen.

12.2.7 Listbox mit mehrfacher Auswahl


Im folgenden Programm wird das gleiche Listbox-Widget wie im vorhe- Listbox-Widget
rigen Abschnitt angezeigt. Allerdings kann der Benutzer nun mehrere
Elemente auswählen. Nach Auswahl und Betätigung des Buttons ANZEI-
GEN werden alle betreffenden Elemente im Ausgabe-Label angezeigt.
import sys, tkinter

def ende():
[Link](O)

def anzeigen():
I
lb["text"] ~ "Anzeige: "
for x in [Link]():
lb["text"] ~ lb["text"] + li .get(x) + " "

main [Link]()

# Listbox mit vier Elementen, mehrfache Auswahl


li ~ [Link](main, height~O,

selectmode~"multiple")

1 i. insert( "end", "Hamburg")


li .insert("end","Stuttgart")
1 i. insert( "end", "Berl in")
li .insert("end","Dortmund")
1 i . pa ck ( )

325
12 I Benutzeroberflächen

Ir Auswahl anzei gen 1 assen


bshow [Link](main, text ~ "Anzeigen",
~
command ~ anzeigen)
bsho [Link]()

Ir Anzei gel abel


lb ~ [Link](main, text "Auswahl:" )
[Link]()

bende [Link](main, text ~ "Ende",


~

command ~ ende)
[Link]()

[Link]()

Listing 12.9 Datei [Link]

Ohne Bei der Auswahl von mehreren Elementen ist zu beachten, dass einfach
Sondertasten nur ein Element nach dem anderen angeldickt wird, ohne die gewohnte
Betätigung der Sondertasten I Strg I oder GJ. Ein erneuter Klick auf ein
ausgewähltes Element macht dessen Auswahl wieder rückgängig.
Die Darstellung nach Aufruf, Auswahl von zwei Elementen (hier: »Ham-
burg« und »Dortmund«) und Betätigung des Anzeige-Buttons zeigt Abbil-
dung12.11.

Abbildung 12.11 Liste mit Mehrfachauswahl

Zur Erläuterung:

selectmode ~ Die Listbox wird zusätzlich mit der Eigenschaft se 1 ectmode und dem
Eigenschaftswert multiple versehen. Bei selectmode ist der Wert
si ngl e standardmäßig eingestellt und musste deshalb beim vorheri-
gen Beispiel (Listbox mit einfacher Auswahl) nicht angegeben wer-
den.

326
Widget-Typen I 12.2

~ Die Nummern der vom Benutzer ausgewählten Elemente stehen in curselectionO


einem Tupel zur Verfügung, das von der Methode cu r se 1 e ct ion ( )
zurückgeliefert wird.
~ In der Funktion anzeigen() werden die einzelnen Elemente dieses
Tupels ermittelt. Die zugehörigen Elemente aus der Listbox werden
nacheinander im Ausgabe-Label angezeigt.

12.2.8 Scrollbar, serollende Widgets


Einige Widgets können mit einer Scrollbar angezeigt werden. Dazu ist es
notwendig, das betreffende Widget sowie eine Scrollbar zu erzeugen und
miteinander zu verbinden.

Im folgenden Programm wird eine Listbox mit der Höhe 4 mit einer Widget und
Scrollbar verbunden, sodass alle sieben Elemente der Listbox sichtbar Scrollbar
verbinden
gemacht werden können.
import sys, tkinter

def ende():
[Link](O)

main ~ [Link]()

button ~ [Link](main, text~"Ende",

command~ende)

I
[Link]( )

# Erzeugen der Scrollbar


scb ~ [Link](main, orient~"vertical")

# Erzeugen der Listbox, Verbindung mit der Scrollbar


li ~ [Link](main, height~4,

yscrollcommand~[Link])

scb["command"J ~ [Link]

# Sieben Elemente
1 i. insert( "end", "Hamburg")
1 i. insert( "end", "Stuttgart")
1 i. insert( "end", "Berl in")
1 i. insert( "end", "Dortmund")
1 i. insert( "end", "Duisburg")
1 i. insert( "end", "Potsdam")
li .insert("end", "Halle")

327
12 I Benutzeroberflächen

# Anzeigen von Listbox und Serollbar


1i .paek(side~"l eft")

[Link](side~"left". fill~"y")

[Link]()

Listing 12.10 Datei p121 [Link]

Abbildung 12.12 und Abbildung 12.13 zeigen die Darstellung mit zwei
verschiedenen Stellungen der Scrollbar.

Abbildung 12.12 Scrollendes Widget, Startzustand

Abbildung 12.13 Scrollendes Widget, nach Scrollvorgang

Zur Erläuterung:
Scrollbar ~ Zunächst wird ein Objekt der Klasse Serollbar erzeugt (seb). Die
Scrollbar ist vertikal ausgerichtet.
~ Eine Listbox (1 i) mit der Anzeigehöhe 4 wird erzeugt.
Zweiseitige ~ Wenn die Scrollbar bewegt wird, soll die Listbox entsprechend nach
Zuweisung oben oder unten scrollen. Dies erreichen Sie durch zwei Maßnahmen:
~ Zuweisung der Methode set () der Scrollbar zur Eigenschaft
yseroll eommand der Listbox

~ Zuweisung der Methode yv i e w( ) der Listbox zur Eigenschaft eom-


ma nd der Scrollbar

~ Die Listbox wird mit insgesamt sieben Elementen gefüllt.


packO ~ Mithilfe des Geometrie-Managers paek() werden Listbox und scroll-
bar nebeneinander angezeigt, beide nach links ausgerichtet. Die
Scrollbar füllt den Platz in y- Richtung neben der Listbox aus, wird also

328
Widget-Typen I 12.2

genauso hoch wie die Listbox. Weitere Angaben zu den Möglichkei-


ten von pack( ) erhalten Sie später noch im Abschnitt 12.3.

12.2.9 Radio-Buttons zur Auswahl. Widget-Variablen


Radio-Buttons (Optionsfelder) ermöglichen wie die einfache Listbox eine Radio-Button-
Auswahl durch den Benutzer. Sie werden allerdings als einzelne Widgets Widget

angezeigt und müssen vom Programmierer zu einer Gruppe zusammen-


gefügt werden, damit sie gemeinsam reagieren können. Dazu ist die Ver-
bindung zu einer sogenannten Widget-Variablen zwingend notwendig.

Hinweis Widget-Variablen
Mehrere Arten von Widgets, nicht nur Radio-Buttons, können mit Widget-
Variablen verbunden werden. Eine Änderung des Widget-Zustands führt dann
zu einer Änderung des Werts der Widget-Variablen und umgekehrt.

Im folgenden Beispiel wird eine Gruppe von drei Radio-Buttons erzeugt


und angezeigt, mit deren Hilfe eine Farbe ausgewählt werden kann. Betä-
tigt der Benutzer den Anzeige-Button, so wird die gewählte Farbe ange-
zeigt.
import sys. tkinter

def ende():
[Link](O)

I
def anzeigen():
lb["text"] ~ "Aus wahl: "+ [Link]()

main ~ [Link]()

# Widget-Variable
farbe ~ [Link]()
[Link]("rot")

# Gruppe von Radio Buttons


rbl ~ [Link](main. text~"rot".

variable~farbe. value~"rot")

rbl. pack( )
rb2 ~ [Link](main. text~"gelb".

variable~farbe. value~"gelb")

rb2. pack( )
rb3 ~ [Link](main. text~"blau".

variable~farbe. value~"blau")

329
12 I Benutzeroberflächen

rb3. pack()

Ir Auswahl anzei gen 1 assen


bshow [Link](main, text ~ "Anzeigen",
~
command ~ anzeigen)
[Link]()

Ir Anzei ge 1 abe 1
lb ~ [Link](main, text "Auswahl:" )
[Link]()

bende [Link](main, text ~ "Ende",


~

command ~ ende)
[Link]()

[Link]()

Listing 12.11 Datei [Link]

Die Anzeige sieht zunächst wie folgt aus:

r. rot

r gelb
r blau

Anzeigen I
Auswahl:
Ende

Abbildung 12.14 Radio-Buttons, Startzustand

Wenn der Benutzer blau auswählt und den Anzeige-Button betätigt, wird
Folgendes angezeigt:

tk [J[Q)[R]
r rot
r gelb
r. blau

Anzeigen I
Auswahl: blau
Ende

Abbildung 12.15 Radio-Buttons, Zustand nach Auswahl und Anzeige

33°
Widget-Typen I 12.2

Zur Erläuterung:

~ Widget-Variablen müssen Objekte aus einer der folgenden Klassen Objekttypen


sein:
~ S tri n9 Va r (für Zeichenketten)
~ In t Va r (für ganze Zahlen)
~ 00 ub 1 eVa r (für Zahlen mit Nachkommastellen)

~ Im vorliegenden Beispiel wird die Widget-Variable fa r be als Objekt StringVar


der Klasse S tri ngV ar erzeugt. Mithilfe der Methode set ( ) wird der
Widget-Variablen der Wert »rot« zugewiesen.
~ Es werden drei Radio-Buttons erzeugt. Der gemeinsame Wert der Gemeinsame
Eigenschaft variable ist der Name der Widget-Variablen (farbe). Widget-Variable

Dadurch ist die Verbindung zwischen den drei Radio-Buttons herge-


stellt. Die Buttons repräsentieren nun diese Widget-Variable und
umgekehrt.
~ Jeder der drei Radio-Buttons erhält individuelle Werte für die Eigen- text, value
schaften text und val ue. Der Text erscheint sichtbar neben dem
Radio-Button. Der Wert der Eigenschaft val ue entspricht (unsichtbar)
dem Wert der zugehörigen Widget-Variablen.
~ Wird einer der drei Radio-Buttons vom Benutzer ausgewählt, so wird Auswahl =
der Widget-Variable der zugehörige Wert der Eigenschaft val ue zuge- Zuweisung

~
wiesen und umgekehrt.
Da zu Beginn für die Widget-Variable farbe der Wert »rot« eingestellt
wurde, ist der zugehörige Radio-Button beim Start des Programms
Vorbelegung I
bereits ausgewählt. Eine solche Vorbelegung gehört zum guten Pro-
grammierstil und verhindert, dass der Benutzer gar keine Auswahl
trifft.
~ In der Funktion anzeigen(), die über den Button aufgerufen wird,
wird mithilfe der Methode get ( ) der Wert der Widget-Variablen und
damit die vom Benutzer getroffene Auswahl ermittelt. Dieser Wert
wird im Label angezeigt.

12.2.10 Radio-Buttons zur Auswahl und Ausführung


Die Betätigung eines Radio-Buttons kann auch unmittelbar zur Ausfüh-
rung einer Funktion führen, da Radio-Button-Widgets wie die Standard-
Buttons über die Eigenschaft comma nd verfügen.

331
12 I Benutzeroberflächen

command Das oben aufgeführte Programm wurde in dieser Hinsicht verändert. Der
Anzeige-Button entfällt. Stattdessen wurde die Eigenschaft comma nd
jedem der drei Radio-Buttons hinzugefügt. Als Resultat wird die ausge-
wählte Farbe unmittelbar nach der Betätigung des Radio-Buttons ange-
zeigt.

Das veränderte Programm sieht wie folgt aus:


import sys, tkinter

def ende():
[Link](O)

def anzeigen():
lbC"text"] ~ "Auswahl: " + [Link]()

main ~ [Link]()

# Widget-Variable
farbe ~ [Link]()
[Link]("rot")

# Gruppe von Radio-Buttons


rbl ~ [Link](main, text~"rot",
variable~farbe, value~"rot", command~anzeigen)

rbl. pack()
rb2 ~ [Link](main, text~"gelb",

variable~farbe, value~"gelb", command~anzeigen)

rb2. pack()
rb3 ~ [Link](main, text~"blau",
variable~farbe, value~"blau", command~anzeigen)

rb3. pack()

lf Anzei gel abel


lb ~ [Link](main, text "Auswahl:" )
[Link]()

bende [Link](main, text ~ "Ende",


~

command ~ ende)
[Link]()

[Link]()

Listing 12.12 Datei [Link]

Die Darstellung nach Auswahl von blau sehen Sie in Ab bildung 12.16.

332
Widget-Typen I 12.2

r rot
r gelb
\0 blau
Aus wahl : blau
Ende

Abbildung 12.16 Radio-Buttons, nach Auswahl

12.2.11 Check-Buttons zur mehrfachen Auswahl


Check-Buttons (Kontrollkästchen) bieten ebenso wie eine Listbox mit Check-Button-
mehrfacher Auswahl mehrere Entscheidungsmöglichkeiten für den Benut- Widget

zer. Check-Buttons werden als einzelne Widgets angezeigt und können mit
einer Widget-Variablen verbunden werden. Dabei gibt es abhängig vom
Zustand des Check-Buttons unterschiedliche Werte für die Variable.

Dem Programmierer stehen wie beim Radio-Button zwei Möglichkeiten Bedienungs-


zur Verfügung: varianten

~ Er kann den Benutzer die Auswahl treffen lassen und anschließend


über einen Standard-Button eine Anzeige- oder Auswertungsfunktion
starten.
~ Er kann die Betätigung eines Check-Buttons unmittelbar mit einer
Aktion verbinden.

Im folgenden Programm wird eine Reservierung für ein Hotelzimmer


durchgeführt. Mithilfe von zwei Check-Buttons kann der Benutzer ent-
scheiden, ob er ein Zimmer mit oder ohne Dusche beziehungsweise mit
oder ohne Minibar möchte. Jede Auswahl führt unmittelbar zur Anzeige.
I
import sys, tkinter

def ende():
[Link](O)

def anzeigen():
lb["text"] ~ "Zimmer" + [Link]() + " " + [Link]()

main ~ [Link]()

i!Anzei gel abel


lb ~ [Link](main, text "Zimmer" width~40)

[Link]()

333
12 I Benutzeroberflächen

# Widget-Variablen
du ~ [Link]()
[Link]("ohne Dusche")
mb ~ [Link]()
[Link]("ohne Minibar")

# Zwei Checkbuttons
cbl ~ [Link](main, text~"Dusche",

variable~du, onvalue~"mit Dusche",


offvalue~"ohne Dusche", command~anzeigen)

cbl. pack( )
cbZ ~ [Link](main, text~"Minibar",

variable~mb, onvalue~"mit Minibar",


offvalue~"ohne Minibar", command~anzeigen)

cbZ. pack( )

bende [Link](main, text ~ "Ende",


~

command ~ ende)
[Link]()

[Link]()
Listing 12.13 Datei [Link]

Abbildung 12.17 zeigt den Startzustand des Formulars.

tk GJ[Q][E]
Zimmer
r Dusche

r Minibar

Ende

Abbildung 12.17 Checkboxen, Startzustand

Nach Markierung beider Check-Buttons sieht das Formular wie folgt aus:

tk GJ[Q][E]
Zimmer mit Dusche mit Minibar
P' Dusche
P' Minibar
Ende

Abbildung 12.18 Checkboxen, nach Markierung

334
Widget-Typen I 12.2

Zur Erläuterung:

~ Es werden zwei Widget-Variablen erzeugt (du und mb). Diese werden Vorbelegung
jeweils mit einem Wert vorbelegt, der dem nicht markierten Zustand
(d.h. ohne Dusche bzw. Minibar) entspricht.
~ Es werden zwei Check-Buttons mit den folgenden Eigenschaften
erzeugt:
~ text (zur Anzeige)
~ va ri abl e (zur Verbindung mit der Widget-Variablen)
~ on val ue (als Wert der Widget-Variablen für den markierten onvalue / offvalue
Zustand)
~ offval ue (als Wert der Widget-Variablen für den nicht markierten
Zustand)
~ comma nd (für die Funktion, die bei Betätigung des Check-Buttons
aufgerufen wird)
~ In der Funktion anzei gen() wirdjeweils mithilfe der Methode get() getO
der Wert der beiden Widget-Variablen und damit die vom Benutzer
getroffene Auswahl ermittelt. Diese Werte werden im Label ange-
zeigt.

12.2.12 Schieberegler, Scale

Ein Scale-Widget entspricht einem Schieberegler, also der visuellen Scale-Widget

I
Anzeige eines Wertes, der mithilfe der Maus verändert werden kann.

Im folgenden Beispiel wird ein Geschwindigkeitsmesser simuliert. Es Visuelle Anzeige


können Geschwindigkeiten zwischen 0 und 200 km/h in Schritten von
5 kmlh angezeigt und eingestellt werden. Der eingestellte Wert wird
zusätzlich in einem Label angezeigt.
import sys, tkinter

def ende():
[Link](O)

def anzeigen(self):
lb["text"] ~ "Geschwindigkeit: " \
+ str(scvwert .get()) + " km/ho

main [Link]()

335
12 I Benutzeroberflächen

Ir Anzei ge 1 abe 1
lb [Link](main,
~

text ~ "Geschwindigkeit: 0 km/ho, width~25)

[Link]()

# Widget-Variablen
scvwert ~ [Link]()
[Link]( 0)

Ir Scale Widget
scv ~ [Link](main, width~20, length~200,

orient~"vertical", from_~O, to~200,

resolution~5, tickinterval~20, label~"km/h",

command~anzeigen, variable~scvwert)

scv. pack()

bende [Link](main, text ~ "Ende",


~

command ~ ende)
[Link]()

[Link]()

Listing 12.14 Datei [Link]

Die Darstellung zu Beginn:

tk [J[Q)(gJ
Geschwindigkeit: 0 km/h

o 0 km/h
20
40
60
80
100
120
140
160
180
200

Ende

Abbildung 12.19 Scale,Startzustand

Abbildung 12.20 zeigt den Geschwindigkeitsmesser nach einer Beschleu-


nigungsphase.
Widget-Typen I 12.2

tk GJ[QJ[gJ
Geschwindigkeit: 110 km/h

km/h
20
40
60
80
100 110
120
140
160
180
200

Ende

Abbildung 12.20 Scale, nach Veränderung

Zur Erläuterung:

~ Es wird eine Widget-Variable erzeugt (scv). Diese wird mit dem Wert
o vorbelegt.
~ Es wird ein Scale-Widget mit den folgenden Eigenschaften und Wer-

-
ten erzeugt:

Eigenschaft Erklärung
width 20 Breite in Pixeln
1 ength 200 Länge oder Höhe in Pixeln
orient "verti cal" Orientierung, Ausrichtung
from

to 200
Minimalwert; der Unterstrich dient dazu, Ver-
wechslungen mit dem Schlüsselwort from zu ver-
meiden
Maximalwert
I
resolution Auflösung; Abstand der Werte bei Bewegung des
Sch iebereglers
ti cki nterval 20 Anzeige der Werte im eingestellten Abstand
1 abe 1 "km/h" zusätzliche Anzeige neben dem Schieberegler
command "anzeigen" Funktion, die bei Betätigung des Schiebereglers
aufgerufen wird
variable scvwert Name der zugeordneten Widget-Variablen

Tabelle 12.1 Eigenschaften des Scale-Widgets

~ In der Funktion anzei gen() wirdjeweils mithilfe der Methode get() getO
der Wert der Widget-Variablen und damit der vom Benutzer einge-
stellte Wert ermittelt. Dieser Wert wird im Label angezeigt.

337
12 I Benutzeroberflächen

12.2.13 Mausereignisse

command Die Widgets, die in den bisherigen Programmen zu Aktionen geführt


haben, beinhalten die Eigenschaft command. Über diese Eigenschaft wird
das Widget mit einer Funktion verbunden, die bei dem entsprechenden
Ereignis, also beim Anklicken des Buttons, Radio-Buttons oder Check-
Buttons, aufgerufen wird.

Event Widgets können mit vielen Events, also Mausereignissen oder Tastatur-
ereignissen (siehe nächster Abschnitt) verbunden werden.

Zu den Mausereignissen gehören:

~ Anklicken des Widgets mit der linken oder rechten Maustaste (Ereig-
nis <Button 1> beziehungsweise< Button3»
~ doppeltes oder dreifaches Anklicken mit einer Maustaste «Ooubl e-
Button> und <Triple-Button»
~ gleichzeitige Betätigung einer oder mehrerer der Sondertasten I St rg I,
0IJ oder [~ (die Ereignisse <Cont ro 1 - Button>, <Alt - Button>,
<Shift-Button»
~ Loslassen der Maustaste in einem Widget (Ereignis <ButtonRel ease»
~ Betreten eines Widgets, also Bewegung der Maus in ein Widget hin-
ein (Ereignis <Enter»
~ Verlassen eines Widgets, also Bewegung der Maus aus einem Widget
heraus (Ereignis< Lea ve»
~ Bewegung der Maus innerhalb eines Widgets (Ereignis <Mot ion»

In dem folgenden Programm werden die genannten Möglichkeiten vor-


geführt:
import sys, tkinter

def ende():
[Link](O)

def mlinks(e):
lbanz["text"] "Linke Maus-Taste"

def mrechts(e):
lbanz["text"] "Rechte Maus-Taste"

def mstrglinks(e):
lbanz["text"] ~ "Strg-Taste und linke Maus-Taste"
Widget-Typen I 12.2

def maltlinks(e):
lbanz["text"] "Alt-Taste und linke Maus-Taste"

def mshiftlinks(e):
lbanz["text"] "Shift-Taste und linke Maus-Taste"

def mlinkslos(e):
lbanz["text"] "Linke Maus-Taste losgelassen"

def mbetreten(e):
lbanz["text"] "Button betreten"

def mverlassen(e):
lbanz["text"] "Button verlassen"

def mbewegt(e):
lbanz["text"] ~ \
"Koordinaten: x~" + str(e.x) +" y~" + str(e.y)

main [Link]()

lf Label mit Events


im ~ [Link](file~"[Link]")
lbm ~ [Link](main, image~im)
[Link]("<Button 1)", mlinks)
[Link]("<Button 3)", mrechts)
[Link]( "<Control-Button 1)", mstrgl inks)
[Link]("<Alt-Button 1)", maltlinks)
[Link]("<Shift-Button 1)", mshiftlinks)
[Link]("<ButtonRelease 1)", mlinkslos)
[Link]("<Motion)", mbewegt)
[Link]()
I
lf Anzei gel abel
lbanz ~ [Link](main, w idth~35)

[Link]()

# Ende-Button, mit Events


bende [Link](main, text ~ "Ende",
~

command ~ ende)
[Link]("<Enter)", mbetreten)
[Link]("<Leave)", mverlassen)
[Link]()

[Link]()
Listing 12.15 Datei [Link]

339
12 I Benutzeroberflächen

In Abbildung 12.21 befindet sich die Maus in der Nähe der linken obe-
ren Bildecke.

Koordinaten : x =lO, y=ll


Ende

Abbildung 12.21 Mausereignis, Maus über Widget bewegt

Rechte Maustaste Hält der Benutzer die rechte Maustaste über dem Bild gedrückt, so ergibt
sich die Darstellung in Abbildung 12.22.

Rechte Maus-Taste

Ende

Abbildung 12.22 Mausereignis, rechte Maustaste über Widget betätigt

Zur Erläuterung:
~ Es wurden insgesamt neun Funktionen definiert, die mit bestimmten
Ereignissen verbunden sind. In einem zusätzlichen Label wird das
jeweilige Ereignis für den Benutzer angezeigt.
bindO ~ Zur Verbindung zwischen einem bestimmten Ereignis und einem
Widget muss die Methode bi nd ( ) für das betreffende Widget aufge-
rufen werden.
~ Der erste Parameter der Methode ist eine Zeichenkette, in der das
Ereignis bezeichnet wird.
~ Der zweite Parameter ist der Name der Funktion, die aufgerufen
wird, wenn das Ereignis eintritt.

340
Widget-Typen I 12.2

~ Die beiden Ereignisse Betreten und Verlassen eines Widgets wurden Ereignisse
mit dem ENDE-Button verbunden. Die übrigen sieben Ereignisse wur- verbinden

den mit einem Label verbunden, in dem ein Bild dargestellt wird.
~ Jede Ereignisfunktion übermittelt Informationen über das Ereignis Event-Objekt
mithilfe eines Event-Objekts (hier: e). Bei einem Mausereignis sind
dabei die Objekteigenschaften x und y, also die Koordinaten des
Mauszeigers innerhalb des Widgets interessant. Diese werden beim
Ereignis Bewegen zusätzlich angezeigt (siehe Abbildung 12.21).

12.2.14 Tastatu rereign isse


Die Verbindung zu Tastaturereignissen wird ähnlich wie die Verbindung
zu Mausereignissen aufgebaut. Ein Beispiel:
import sys, tkinter

def ende():
[Link](O)

def kev (e) :


lbanz["text"] ~ "Zeichen:" + [Link] \
+ Bes ch rei bung: " + e. keysym \
+", Codezahl: "+ str([Link])

main [Link]()

I
i!Key- Events
e ~ [Link](main)
[Link]("(p)",kev)
[Link]("(+)",kev)
[Link]("(%)",kev)
[Link]("(,)",kev)
[Link]()

i!Hi 1 fe- Label


lbhlp ~ [Link](main,
text ~ "Taste: p oder + oder % oder
w idth~40)

[Link]()

i!Anzei gel abel


lbanz ~ [Link](main)
[Link]()

341
12 I Benutzeroberflächen

Ir Ende- Button
bende [Link](main, text ~ "Ende",
~

command ~ ende)
[Link]()

[Link]()

Listing 12.16 Datei [Link]

Abbildung 12.23 zeigt die Darstellung nach Eingabe eines Prozentzei-


chens.

Taste: p oder + oder % oder ,


Zeichen: % , Bes chreibung: percent, Codezahl : 53

Ende

Abbildung 12.23 Tastaturereignis

Zur Erläuterung:

bindO ~ Das Entry-Widget wird mithilfe der Methode bind () mit insgesamt
vier Tastaturereignissen verbunden:
~ Betätigen der Taste [IJ (Buchstabe »p«)
~ Betätigen der Taste G (Pluszeichen)
~ Betätigen der Taste [K] (Prozentzeichen)
~ Betätigen der Taste [J (Kommazeichen)
Ereignisse ~ Die Ereignisse werden jeweils mit der Funktion kev() verbunden.
verbinden

Event-Objekt ~ Jede Ereignisfunktion übermittelt Informationen über das Ereignis


mithilfe eines Event-Objekts (hier: e). Bei einem Tastaturereignis sind
die folgenden Objekteigenschaften relevant:
~ eh a r (Zeichen)
~ keysym (Beschreibung des Zeichens)
~ keycode (Code des Zeichens)
~ Diese Objekteigenschaften werden zusätzlich angezeigt (siehe Abbil-
dung 12.23).

342
Geometrische Anordnung von Widgets I 12.3

12.3 Geometrische Anordnung von Widgets

In den bisherigen Programmen wurde die Methode pa c k ( ) als einfacher Manager


Geometriemanager zur Anordnung und Anzeige der Widgets innerhalb
des Fensters genutzt. Geometriemanager bestimmen das Layout einer
Gur-Anwendung, sie werden daher auch Layoutmanager genannt.

In diesem Abschnitt wird auf die drei Möglichkeiten zur Anordnung von
Widgets genauer eingegangen:
~ pack()

~ pl ace()

~ gri d( )

Außerdem wird das Frame-Widget beschrieben, mit dessen Hilfe ein Frame-Widget
Fenster in Teile zerlegt werden kann. Innerhalb dieser Teile können wie-
derum Widgets passend angeordnet werden. Dies ermöglicht auch den
Einsatz von verschiedenen Geometriemanagern innerhalb eines Pro-
gramms.

Hinweise
1. Die Widgets in den nachfolgend aufgeführten Programmen führen nicht
immer zu Aktionen. Sie werden an einigen Stellen nur dargestellt, um die
verschiedenen Methoden zu verdeutlichen.
2. In den Beispielen werden nur die Widget-Typen Button und Label verwen-
det. Natürlich können alle Typen von Widgets auf die vorgestellte Art und

12.3.1
Weise angeordnet werden.

Frame-Widget, Methode packO


I
Bisher wurden alle Widgets innerhalb des Hauptfensters angeordnet. Das Elternelement
unmittelbare Elternelement, also das übergeordnete Element, ist in die-
sem Fall das Hauptfenster.

Frame-Widgets werden allerdings häufig auch als Elternelemente für Gruppierung


andere Widgets eingesetzt. Dies ermöglicht die Gruppierung von wid-
gets und vielfältige re Möglichkeiten der Anordnung.
Das folgende Beispiel beinhaltet drei Frames sowie mehrere Button-Wid-
gets, die teilweise innerhalb, teilweise außerhalb der Frames angeordnet
wurden. Dabei werden verschiedene Parameter der Methode pa c k ( )
angewendet.

343
12 I Benutzeroberflächen

import sys, tkinter

def ende():
[Link](O)

main ~ [Link]()

# Frame I mit Button Ia und Ib


frl ~ [Link](main, width~200,
height~IOO, relief~"sunken", bd~l)
[Link](side~"left")

bla ~ [Link](frl, text~"Button Ia")


[Link](padx~5, pady~5)
bIb ~ [Link](frl, text~"Button Ib")
[Link](padx~5, pady~5)

# Frame 2 mit Button 2a und 2b


fr2 ~ [Link](main, width~200,
height~IOO, relief~"sunken", bd~l)
[Link](side~"right")

b2a ~ [Link](fr2, text~"Button 2a")


[Link](ipadx~25, ipady~25)
b2b ~ [Link](fr2, text~"Button 2b")
[Link](fill~"x")

Ir Frame 3
fr3 ~ [Link](main, width~200,
height~IOO, relief~"sunken", bd~l)
[Link](side~"bottom", expand~I, fill~"both")

bende [Link](main, text ~ "Ende",


~
command ~ ende)
[Link]()

[Link]()
Listing 12.17 Datei [Link]

Die Darstellung:

Button la I Button 2a

Button lb I

Abbildung 12.24 Geometriemanager pack

344
Geometrische Anordnung von Widgets I 12.3

Zur Erläuterung:

~ Das Fenster ist zunächst in drei Frames eingeteilt: frl, fr2 und fr3.
Für alle drei Frames wurden die Randart s un ken und die Randbreite
1 gewählt, damit sie optisch erkennbar sind. Als Startgröße wurde
jeweils eine Breite von 200 Pixeln und eine Höhe von 100 Pixeln
gewählt. Allerdings werden diese Größen von den eingelagerten wid-
gets beeinflusst.
~ Der erste Frame (f rl) wurde an der linken Seite des Hauptfensters side
angeordnet. Dies wird mit dem Parameter si de und dem Wert 1 eft
bei der Methode pack() erreicht. Der zweite Frame (fr2) und der
dritte Frame (f r3) wurden an der rechten und an der unteren Seite
des Hauptfensters angeordnet (s i de~" r i ght" und s i de~" bottom").
~ Beim dritten Frame wurden außerdem die Parameter expand (Wert 1) expand, fill
und fi 11 (Wert both) eingestellt. Dies führt dazu, dass dieser Frame
den restlichen verfügbaren Platz im Hauptfenster nutzt, auch bei einer
Größenveränderung des Hauptfensters.
~ Der ENDE-Button wurde gar nicht angeordnet. Alle nicht angeordne-
ten Elemente werden, wie bei den bisherigen Programmen, innerhalb
ihrer jeweiligen Umgebung (Frame oder Hauptfenster) der Reihe nach
von oben nach unten dargestellt.
~ Bei den beiden Buttons bl a und bl b wurde als Elternelement nicht Elternelement
das Hauptfenster, sondern der erste Frame (f rl) angegeben. Daher
werden diese Buttons innerhalb dieses Frames angeordnet.
~ Die Parameter padx und pady führen dazu, dass ein Abstand (hier
jeweils 5 Pixel in x-Richtung und in y-Richtung) zum Nachbar-Widget
beziehungsweise zum Rand des Elternelements eingehalten wird.
padx, pady

I
~ Die beiden Buttons b2a und b2b werden innerhalb des Frames fr2
angeordnet.
~ Die Parameter ipadx und ipady beim Button b2a führen dazu, dass ipadx, ipady
dieses Widget vergrößert wird (hier jeweils 5 Pixel in x-Richtung und
in y-Richtung).
~ Der Parameter fi 11 mit dem Wert x beim Button b2b führt dazu, dass fill
dieses Widget den restlichen verfügbaren Platz in x-Richtung inner-
halb des Elternelements ausfüllt.

345
12 I Benutzeroberflächen

Maßeinheiten Hinweise
1. Notiert man die Angaben für die Abstände zum Nachbar-Widget (padx und
pady) und für die erweiterte Ausdehnung eines Widgets (i padx und i pady)
als einfache Zahlen, so handelt es sich automatisch um die Einheit Pixel.
2. Werden die Angaben als Zeichenkette notiert und mit einem Suffix verse-
hen, so sind auch andere Einheiten möglich. Als Suffixe erlaubt sind c (für
Zentimeter), i (für Inches), m (für Millimeter) und p (für Punkte; ein Punkt
entspricht circa 1/72 Inch).

12.3.2 Ein einfacher Taschenrechner


Als Anwendung für eine Anordnung mit mehreren Frames wird im Fol-
genden ein einfacher Taschenrechner vorgestellt. Die Darstellung des
Taschenrechners zeigt Abbildung 12.25.

tk [J[QJ[EJ

• l/x x hoch 2 CL

7 8 9
4 5 6

1 2 3

0 Ende

Abbildung 12.25 Taschenrechner

Der Benutzer kann durch Betätigung der Zifferntasten [QJ bis W und der
Taste für den Dezimalpunkt beliebige Zahlen zusammenstellen, die
anschließend in der Anzeige erscheinen.

Tasten Außerdem gibt es die folgenden Tasten:


~ Taste ITJ [ZJ w: Berechnung und Anzeige des Kehrwerts der angezeig-
ten Zahl
~ Taste W [Jl()ili] W: Berechnung und Anzeige des Quadrats der ange-
zeigten zahl
~ Taste [B: Löschen der Anzeige
~ Taste I Ende I: Beenden des Programms
Geometrische Anordnung von Widgets I 12.3

Das Programm:

import sys, tkinter

def ende():
[Link](O)

lf Kehrwert Kehrwert
def kw():
if not lb["text"]:
return
z ~ float(lb["text"])
z ~ l/z
lb["text"] ~ str(z)

lf Quadrat Quadrat
def qu():
if not lb["text"]:
return
z ~ float(lb["text"])
z ~ z*z
lb["text"] ~ str(z)

# Anzeige leeren
def cl ( ):
lb["text"] ~

I
# Ziffern 0 bis 9 Zifferntasten
def anzO():
lb["text"] +~ "0"

def a nz 1 ( ) :
lb["text"] +~ "1"

def anz2():
lb["text"] +~ "2"

def anz3():
lb["text"] +~ "3"

def anz4():
lb["text"] +~ "4"

def anz5():
lb["text"] +~ "5"

347
12 I Ben utzeroberflächen

def a nz6 ( ) :
1 b [ "tex t"] +~ "6 "

def a nz7 ( ) :
1 b [ "tex t"] +~ "7"

def a nz8( ) :
1 b [ "tex t"] +~ "8"

def a nz9 ( ) :
1 b [ "tex t"] +~ "9"

Dezimalpunkt lf Pun kt. fall s noch nicht vorhanden


def anzp():
if lb["text"].find(".") -1:
lb["text"] +~

Hauptprogramm main ~ [Link]()

Anordnung lf Frame A mi t Anzei ge- Label


fra ~ [Link](main)
[Link](expand~l. fill~"x")

lb ~ [Link](fra. bg~"lfFFFFFF". bd~5.


rel ief~"sunken". anchor~"e")
[Link](expand~l. fill~"x". pady~10)

# Frame B mit Kehrwert. Quadrat und Leeren


frb ~ [Link](main)
frb. pack()
bkw ~ [Link](frb. text~"l/x". width~7.
command~kw)

[Link](side~"left")

bquad ~ [Link](frb. text~"x hoch 2".


width~7. command~qu)

[Link](side~"left")

bel ~ [Link](frb. text~"CL". width~7.

command~cl )
bel . pa c k( s i d e~" 1e ft " )

lf Frame C mit Ziffern 7. 8. 9


frc ~ [Link](main)
frc. pack()
b7 ~ [Link](frc. text~"7". width~7.

command~anz7)
Geometrische Anordnung von Widgets I 12.3

[Link](side~"left")

b8 ~ [Link](frc. text~"8". width~7.

command~anz8)

[Link](side~"left")

b9 ~ [Link](frc. text~"9". width~7.

command~anz9)

[Link](side~"left")

# Frame 0 mit Ziffern 4. 5. 6


frd ~ [Link](main)
frd. pack()
b4 ~ [Link](frd. text~"4". width~7.

command~anz4)

[Link](side~"left")

b5 ~ [Link](frd. text~"5". width~7.

command~anz5)

[Link](side~"left")

b6 ~ [Link](frd. text~"6". width~7.

command~anz6)

[Link](side~"left")

# Frame E mit Ziffern 1. 2. 3


fre ~ [Link](main)
fre. packt )
b1 ~ [Link](fre. text~"l". width~7.

command~anz1)

[Link](side~"left")

b2 ~ [Link](fre.

[Link](side~"left")

b3 ~
text~"2".

command~anz2)

[Link](fre. text~"3".
width~7.

width~7.
I
command~anz3)

[Link](side~"left")

# Frame F mit Dezimalpunkt. Ziffer 0 und Ende


frf ~ [Link](main)
frf. pack()
bp ~ [Link](frf. text~".". width~7.

command~anzp)

[Link](side~"left")

bO ~ [Link](frf. text~"O". width~7.

command~anzO)

[Link](side~"left")

bende ~ [Link](frf. text~"Ende". width~7.

command~ende)

349
12 I Benutzeroberflächen

[Link](side~"left")

[Link]()

Listing12.18 Datei [Link]

Funktionen Erläuterung der Funktionen:


~ In den Funktionen kw ( ) und q u ( ) zur Berechnung von Kehrwert und
Quadrat der angezeigten Zahl wird zunächst überprüft, ob überhaupt
eine Zahl zur Berechnung in der Anzeige steht. Ist dies der Fall, so
wird die entsprechende Berechnung durchgeführt und das Ergebnis
wird angezeigt.
~ Die Funktion cl ( ) zum Löschen setzt den Anzeigetext auf eine leere
Zeichenkette.
~ Die Funktionen anzO() bis anz9() fügen die jeweilige Ziffer zur
Anzeige hinzu. Die Funktion a nzp ( ) fügt einen Dezimalpunkt hinzu,
falls bisher noch kein Dezimalpunkt vorhanden ist. Durch diese Funk-
tionen können beliebige Zahlen, auch mit Nachkommastellen, zusam-
mengesetzt werden.

Hinweis

Das Hinzufügen von Ziffern ist natürlich nur dann sinnvoll, wenn nicht unmit-
telbar zuvor ein Kehrwert oder ein Quadrat berechnet wurde. In diesem Fall
sollte vor der Eingabe einer neuen Ziffer zunächst die Anzeige gelöscht wer-
den.

Geometrische Erläuterung der geometrischen Anordnung:


Anordnung
~ Das Fenster ist in sechs Frames (Frame Abis F) unterteilt, die jeweils
eine waagrechte Reihe bilden.
~ Innerhalb des obersten Frames (Frame A) steht das Label-Widget für
die Zahlenanzeige. Das Label-Widget nimmt die gesamte Breite des
Fensters ein und ist optisch vom Rest des Fensters abgesetzt. Die
Inhalte des Labels werden rechtsbündig angezeigt (anchor~"e"), wie
üblich bei Zahlen.
~ Die restlichen Frames (Frame B bis F) enthalten je drei Buttons, die
immer an der linken Seite des Frames beziehungsweise des Nachbar-
Widgets angesetzt werden (s i de~" 1 eft "). Diese insgesamt 15 Buttons
führenjeweils zu einer der 15 oben genannten Funktionen.

35°
Geometrische Anordnung von Widgets I 12.3

12.3.3 Methode gridO


Die Methode 9 r i d () dient als Geometriemanager zur Erzeugung von Raster
besonders regelmäßigen Anordnungen, die sich in einem Raster darstel-
len lassen. Ähnlich wie in einer Tabelle, die von einem Textverarbei-
tungsprogramm oder in einem HTML-Dokument erzeugt wird, werden
die Widgets in Tabellenzellen angeordnet.
Jede Tabellenzelle ist durch die Nummer der Zeile und die Nummer der Zeile, Spalte
Spalte gekennzeichnet. Jedem Widget werden bei Aufruf der Methode
9 r i d () die betreffenden Nummern (für die Eigenschaften row bezie-
hungsweise co 1 umn) mitgegeben, jeweils beginnend bei O.
Es ist auch möglich, ein Widget über mehrere Tabellenzellen waagrecht Zellen verbinden
und/oder senkrecht auszudehnen. Dazu muss die Spannweite (für die
Eigenschaften rows pa n und co 1 umns pa n) angegeben werden.
Das Taschenrechnerprogramm aus dem vorherigen Abschnitt wurde im
Folgenden verändert. Die geometrische Anordnung der Buttons und des
Labels werden von der Methode 9 r i d ( ) vorgenommen.

Im Folgenden wird nur der Teil des Programms aufgeführt, in dem die Programm-
Widgets erzeugt werden. Die Funktionen bleiben unverändert, ebenso ausschnitt

die Darstellung.

lf Row 0
lb ~ [Link](main. bg~"lfFFFFFF". bd~5.

[Link](row~O.

lf Row
rel ief~"sunken". anchor~"e")
column~O. columnspan~3. sticky~" w e")
I
bkw ~ [Link](main. text~"l/x". width~7.
command~kw)

[Link](row~l. column~O)

bquad ~ [Link](main. text~"x hoch 2".


width~7. command~qu)

[Link](row~l. column~l)

bel ~ [Link](main. text~"CL". width~7.

command~cl )
[Link](row~1. column~2)

lf Row 2
b7 ~ [Link](main. text~"7". width~7.

command~anz7)

[Link](row~2. column~O)

351
12 I Benutzeroberflächen

b8 ~ [Link](main. text~"8". width~7.

command~anz8)

[Link](row~2. column~l)

b9 ~ [Link](main. text~"9". width~7.

command~anz9)

[Link](row~2. column~2)

lf Row 3
b4 ~ [Link](main. text~"4". width~7.

command~anz4)

[Link](row~3. column~O)

b5 ~ [Link](main. text~"5". width~7.

command~anz5)

[Link](row~3. column~l)

b6 ~ [Link](main. text~"6". width~7.

command~anz6)

[Link](row~3. column~2)

lf Row 4
bl ~ [Link](main. text~"l". width~7.

command~anzl)

[Link](row~4. column~O)

b2 ~ [Link](main. text~"2". width~7.

command~anz2)

[Link](row~4. column~l)

b3 ~ [Link](main. text~"3". width~7.

command~anz3)

[Link](row~4. column~2)

lf Row 5
bp ~ [Link](main. text~".". width~7.

command~anzp)

[Link](row~5. column~O)

bO ~ [Link](main. text~"O". width~7.

command~anzO)

[Link](row~5. column~l)

bende ~ [Link](main. text~"Ende". width~7.

command~ende)

[Link](row~5. column~2)

Listing 12.19 Datei [Link], Ausschnitt

352
Geometrische Anordnung von Widgets I 12.3

Zur Erläuterung:

~ Es sind keine Frames mehr notwendig. Ihre Aufgabe wurde von den Tabellenzeilen
einzelnen Zeilen (rows) der Tabelle übernommen.
~ In der ersten Zeile steht nur das Label mit den folgenden Eigenschaf-
ten:
~ row ~ 0, das Widget beginnt in Zeile 0 des Hauptfensters.
~ co 1 umn ~ 0, das Widget beginnt in Spalte 0 des Hauptfensters.
~ col umnspan ~ 3, das Widget erstreckt sich über drei Spalten.
~ s ti c ky ~ "we", das Widget wird zum westlichen (linken) und zum
östlichen (rechten) Rand des Elternelements ausgedehnt. Mögliche
Werte für s t i cky sind: w (westlich, links), e (östlich, rechts), n
(nördlich, oben) und s (südlich, unten). Wird diese Eigenschaft
nicht angegeben, so wird das Widget in der Mitte der Tabellen-
zelle(n) dargestellt.
~ Für die insgesamt 15 Buttons sind jeweils die Nummer der Zeile
(row~l bis row~5) und die Nummer der Spalte (co 1 umn~O bis
co 1 umn~2) angegeben. Mehr ist zur Anordnung nicht notwendig.

Hinweis
Bei der Methode grid() können zusätzlich die Eigenschaften padx, pad y ,
i padx und i pady, wie bei der Methode pac k ( ), angegeben werden.

12.3.4 Methode placeO, absolute I<oordinaten


Die Methode p 1 ace () ermöglicht die Positionierung von Widgets an
absoluten oder an relativen Koordinaten.
Absolute
Koordinaten
bleiben konstant.
I
Absolute Koordinaten haben den Nachteil, dass sie bei einer Größen-
änderung des Fensters konstant bleiben. Eine Anordnung mit absoluten
Koordinaten zeigt das folgende Beispiel:
import sys, tkinter

def ende():
[Link](O)

main ~ [Link]()

bl ~ [Link](main, text~"bl",

command~ende)

[Link](x~50, y~50, anchor~"se")

353
12 I Benutzeroberflächen

b2 ~ [Link](main. text~"b2".

eommand~ende)

[Link](x~50. y~50. anehor~"s w ")

b3 ~ [Link](main. text~"b3".

eommand~ende)

[Link](x~50. y~50. anehor~"ne")

b4 ~ [Link](main. text~"b4".

eommand~ende)

[Link](x~50. y~50. anehor~"n w ")

[Link]()

Listing 12.20 Datei [Link]

Das Fenster sieht wie folgt aus:

tk GJ(QJ~

~
~

Abbildung 12.26 Geometriemanager place, absolute Koordinaten

Die Koordinatenangabe setzt sich aus drei Bestandteilen zusammen:

x,y ~ x-Koordinate: in Pixel oder anderen Einheiten (e für Zentimeter, i für


Inches, mfür Millimeter und p für Punkte), gemessen vom linken Rand
des Elternelements
~ y-Koordinate: in Pixel (oder andere Einheiten, siehe x-Koordinate),
gemessen vom oberen Rand des Elternelements
anchor ~ Ankerpunkt (aneho r): Diese Stelle des Widgets liegt an den angegebe-
nen Koordinaten des Elternelements. Mögliche Angaben sind:
~ se (Süd-Ost, rechte untere Ecke)
~ s w (Süd-West, linke untere Ecke)
~ ne (Nord-Ost, rechte obere Ecke)

354
Geometrische Anordnung von Widgets I 12.3

~ nw (Nord-West, linke obere Ecke)


~ s (Süd, Mitte der unteren Seite)
~ n (Nord, Mitte der oberen Seite)
~ w (West, Mitte der linken Seite)

~ e (Ost, Mitte der rechten Seite)


~ Alle vier Buttons sind an den gleichen Koordinaten (x~50, r50) ange-
ordnet. Allerdings beziehen sich die Koordinaten auf jeweils andere
Ecken des Widgets, daher überlappen sich die vier Buttons nicht.
~ Die rechte untere Ecke des Buttons bl liegt bei x~50, r50.

~ Die linke untere Ecke des Buttons b2 liegt bei x~50, r50.

~ Die rechte obere Ecke des Buttons b3 liegt bei x~50, y~50.

~ Die linke obere Ecke des Buttons b4 liegt bei x~50, y~50.

12.3.5 Methode placeO, relative I<oordinaten


Relative Koordinaten beziehen sich auf Anteile der Breite oder Höhe des Relative
Elternelements. Im folgenden Beispiel befinden sich fünf Buttons - rela- Koordinaten
ändern sich mit
tiv zum Elternelement - immer an der gleichen Stelle. Elternelement.

import sys. tkinter

def ende():
[Link](O)

main

bl ~
~ [Link]()

[Link](main. text~"bl".

command~ende)
I
[Link](relx~O.5. rely~O. anchor~"n")

b2 ~ [Link](main. text~"b2".

command~ende)

[Link](relx~O. rely~O.25. anchor~"w")

b3 ~ [Link](main. text~"b3".

command~ende)

[Link](relx~O. rely~O.5. anchor~"w")

b4 ~ [Link](main. text~"b4".

command~ende)

[Link](relx~O. rely~O.75. anchor~"w")

355
12 I Benutzeroberflächen

b5 ~ [Link](main. text~"b5".

command~ende)

[Link](relx~O.5. rely~1. anchor~"s")

[Link]()
Listing 12.21 Datei [Link]

Das Fenster sieht wie folgt aus:

b5

Abbildung 12.27 Geometriemanager place, relative Koordinaten

Zur Erläuterung:

~ Die Koordinatenangabe setzt sich auch hier aus drei Bestandteilen


zusammen:
~ Werte von 0 bis 1
relx, rely ~ Relative x-Koordinate (rel x): ein Wert zwischen 0 und 1. Der Wert
o steht für den linken Rand des Elternelements, der Wert 1 für den
rechten Rand.
~ Relative y-Koordinate (re 1y): ebenfalls ein Wert zwischen 0 und 1.
Der Wert 0 steht für den oberen Rand des Elternelements, der
Wert 1 für den unteren Rand.
anchor ~ Ankerpunkt (anchor): wie bei den absoluten Koordinaten
~ Im vorliegenden Beispiel sind die fünf Buttons wie folgt angeordnet:
~ Die Mitte der oberen Seite (anchor~"n") von Button bl liegt auf
der Mitte der oberen Seite (re 1x~O . 5, re 1rO) des Elternelements.
~ Die Mitte der linken Seite (anchor~"w") der Buttons b2, b3 und b4
liegt am linken Rand (rel x~O) des Elternelements. Die Höhe ist
Geometrische Anordnung von Widgets I 12.3

jeweils unterschiedlich: Button b2 liegt auf 25% der Höhe des


Elternelements (re 1y~O . 25), Button b3 liegt auf 50% der Höhe des
Elternelements (rely~O .5), Button b4liegt auf 75% der Höhe des
Elternelements (rel rO. 75).
~ Die Mitte der unteren Seite (anchor~"s ,,) von Button b5 liegt auf
der Mitte der unteren Seite (relx~O.5, rely~l) des Elternele-
ments.

12.3.6 Absolute Veränderung von I<oordinaten


Die verschiedenen Geometriemanager können auch mehrmals auf die Bewegliche
Widgets angewendet werden. Dies ermöglicht die Programmierung von Widgets

dynamisch veränderlichen Anordnungen, also von beweglichen wid-


gets.

Das folgende Beispiel soll dies anhand eines Labels verdeutlichen, das
mithilfe von zwei Buttons an zwei verschiedene Positionen bewegt wer-
den kann.

import sys, tkinter

def ende():
[Link](O)

# bewegt nach ganz links


def movetoleft():

I
[Link](relx~O, rely~O, anchor~"nw")

# bewegt nach ganz rechts


def movetoright():
[Link](relx~l, rely~O, anchor~"ne")

main ~ [Link]()

lf Bewegtes La be 1
lb ~ [Link](main, text~"Test",

relief~"sunken", bd~l)

[Link](relx~O, rely~O, anchor~"nw")

# bewegt nach ganz links


bleft ~ [Link](main, text~"ganz links",
command~movetoleft)

[Link](relx~O, rely~l, anchor~"sw")

357
12 I Benutzeroberflächen

# bewegt nach ganz rechts


bright ~ [Link](main, text~"ganz rechts",
command~movetoright)

[Link](relx~l, rely~l, anchor~"se")

bende ~ [Link](main, text~"Ende",

command~ende)

[Link](relx~O.5, rely~l, anchor~"s")

[Link]()

Listing 12.22 Datei [Link]

Das Fenster sieht nach dem Start aus wie in Abbildung 12.28 dargestellt.

Test

ganz links ganz rechts

Abbildung 12.28 Absolute Koordinatenveränderung, Startzustand

Nach der Betätigung des Buttons GANZ RECHTS sieht das Fenster folgen-
dermaßen aus:

tk GJ[Q]~

ganz links ganz rechts

Abbildung 12.29 Absolute Koordinatenveränderung, nach Aktion


Geometrische Anordnung von Widgets I 12.3

Zur Erläuterung:

~ Das Label wird insgesamt dreimal platziert:


~ nach dem Start des Programms, in die obere linke Ecke des Eltern-
elements
~ nach Betätigung des Buttons GANZ RECHTS, in die obere rechte Ecke
des Elternelements, in der Funktion movetori ght()
~ nach Betätigung des Buttons GANZ LINKS, in die obere linke Ecke
des Elternelements, in der Funktion movetol eft()

12.3.7 Relative Veränderung von I<oordinaten


Im vorhergehenden Beispiel wurde zwar mit relativen Widget-Koordina-
ten gearbeitet, es handelt sich aber um eine absolute Koordinatenverän-
derung. Das Label bewegt sich nur zwischen zwei bestimmten Punkten
hin und her.

Ein Widget kann aber auch relativ bewegt werden, also ausgehend von
den aktuellen Koordinaten um einen bestimmten Wert in eine ausge-
wählte Richtung.

Im folgenden Beispiel kann ein Label mithilfe von vier Buttons in vier
verschiedene Richtungen bewegt werden.
import sys, tkinter

I
def ende():
[Link](O)

# Aktuelle Position
posx 0
posy ~ 0

# bewegt nach links


def moveleft():
gl oba 1 pos x , posy
posx -~ 20
[Link](x~posx, y~posy, anchor~"nw")

# bewegt nach rechts


def moveright():
gl oba 1 pos x , posy
posx +~ 20
[Link](x~posx, y~posy, anchor~"nw")

359
12 I Benutzeroberflächen

# bewegt nach oben


def moveup():
gl oba 1 pos x , posy
posy -~ 20
[Link](x~posx, y~posy, anchor~"nw")

# bewegt nach unten


def movedown():
gl oba 1 pos x , posy
posy +~ 20
[Link](x~posx, y~posy, anchor~"nw")

# bewegt nach unten


def movestart():
gl oba 1 pos x , posy
posx ~ 0
posy ~ 0
[Link](x~posx, y~posy, anchor~"nw")

main ~ [Link]()

# Frame mit bewegtem Label


frl ~ [Link](main, width~200, height~150,

relief~"sunken", bd~l)

[Link](side~"top")

# Frame mit Buttons zur Bewegung


fr2 ~ [Link](main, height~80)

[Link](side~"left")

# Frame mit Ende-Button


fr3 ~ [Link](main, width~50, height~80)

[Link](side~"left")

# Bewegtes Label
lb ~ [Link](frl, text~"Test",
rel ief~"sunken", bd~l)
[Link](x~O, y~O, anchor~"nw")

# bewegt nach links


bleft ~ [Link](fr2, text~"nach links",
command~moveleft)

[Link](row~I, column~O)
Geometrische Anordnung von Widgets I 12.3

# bewegt nach rechts


bright ~ [Link](fr2, text~"nach rechts",
command~moveright)

[Link](row~l, column~2)

# bewegt nach oben


bup ~ [Link](fr2, text~"nach oben",
command~moveup)

[Link](row~O, column~l)

# bewegt nach unten


bdown ~ [Link](fr2, text~"nach unten",
command~movedown)

[Link](row~2, column~l)

i! Startposition
bstart ~ [Link](fr2, text~"Start",

command~movestart)

[Link](row~l, column~l)

i! Ende- Button
bende ~ [Link](fr3, text~"Ende",

command~ende)

[Link](relx~l, rely~l, anchor~"se")

[Link]()

I
Listing 12.23 Datei [Link]

Das Fenster hat folgendes Aussehen nach dem Start:

tk GJ(Q]~
Test

nach links

Ende

Abbildung 12.30 Relative Koordinatenveränderung, Startzustand


12 I Benutzeroberflächen

Nach mehrfacher Betätigung der Buttons NACH RECHTS und NACH UNTEN
sieht das Fenster wie in Abbildung 12.31 gezeigt aus.

tk [J[Q][RJ

nach links

Ende

Abbildung 12.31 Relative Koordinatenveränderung, nach mehrfacher Aktion

Erläuterung der Funktionen:

~ Zunächst wird das Label an der absoluten Position x~O, rO platziert.


Diese Position wird gleichzeitig den beiden Variablen posx und posy
zugewiesen.
Globale Variablen ~ In den vier Funktionen mo veleft(), moveright(), mo veup() und
movedo wn() werden jeweils zunächst die Variablen pos x und posy als
globale Variablen bekannt gemacht. Dies bedeutet, dass es sich
sowohl außerhalb als auch innerhalb dieser vier Funktionen um die-
selben Variablen handelt.
Relative ~ Die Werte von posx und posy werden anschließend in den vier Funk-
Platzierung tionenjeweils passend verändert und dazu genutzt, eine neue Platzie-
rung mit der Methode p1 ace ( ) durchzuführen. In den beiden Funk-
tionen mo vel eft() und mo veri ght() wird die x-Koordinate um 20
Pixel verändert. In den beiden Funktionen moveup() und mo vedown()
wird die y-Koordinate um 20 Pixel verändert.
~ Es gibt insgesamt drei Frames:
~ Der erste Frame ist am oberen Fensterrand angesetzt und beinhal-
tet das Label. Das Label soll sich relativ zum ersten Frame bewe-
gen.
~ Der zweite Frame ist am linken Fensterrand angesetzt. Er beinhal-
tet die vier Buttons zum Bewegen des Labels. Sie sind mithilfe der
Menüs und MessageBoxes I 12.4

Methode 9 r i d () in einem Raster angeordnet, um die möglichen


Bewegungsrichtungen zu verdeutlichen.
~ Der dritte Frame ist ebenfalls nach links orientiert und erscheint
daher neben dem zweiten Frame. Er beinhaltet nur den ENDE-But-
ton.

Hinweis
Es ist möglich, das Label über den Fensterrand hinaus zu bewegen. Durch
zusätzlichen Programmieraufwand könnte man dies verhindern - um das Pro-
gramm überschaubar zu halten, wurde hier darauf verzichtet.

12.4 Menüs und MessageBoxes


Viele Benutzeroberflächen verfügen zur Bedienung neben den Steuerele-
menten innerhalb des Fensters zusätzlich über
~ eine Menüleiste am oberen Rand des Fensters, die permanent sicht- Menü
bar ist, sowie
~ Kontextmenüs, die einzelnen Steuerelementen zugeordnet sind und Kontextmenü
nur bei Bedarf eingeblendet werden.

In Python stehen zu diesem Zweck Menu-Widgets zur Verfügung. In den Menu-Widget


folgenden Abschnitten sollen die beiden genannten Menüarten vorge-
stellt werden. Außerdem werden in diesem Abschnitt vorgefertigte Dia-
logfelder (MessageBoxes) behandelt.

12.4.1 Menüleisten
I
Die Erzeugung einer Menüleiste mit einzelnen Menüs und darin enthal-
tenen Menübefehlen erfordert grundsätzlich die folgenden Schritte:

~ Erzeugung eines Objekts der Klasse Menu als Menüleiste Reihenfolge der
Erstellung
~ Erzeugung von weiteren Objekten der Klasse Menu als einzelne Menüs
innerhalb der Menüleiste
~ Erzeugung von einzelnen Menüpunkten verschiedenen Typs inner-
halb eines Menüs
~ Hinzufügen der Menüs zur Menüleiste und Bezeichnen der Menüs
~ Hinzufügen der Menüleiste zum Fenster
12 I Benutzeroberflächen

Das folgende Programm beinhaltet eine Menüleiste mit zwei Menüs. Die
beiden Menüs verfügen über vier beziehungsweise über fünf Menü-
punkte verschiedenen Typs:
import sys, tkinter

def ende():
[Link](O)

def farbwechsel ():


fr["bg"] ~ [Link]()

def randwechsel ():


if [Link]():
fr["relief"] "ridge"
else:
fr["relief"] "flat"

main ~ [Link]()

# Zielobjekt der Menubefehle


fr ~ [Link](main, height~100, width~300,

bg~"#FFFFFF", bd~10)

[Link]()

# erzeugt gesamte Menuleiste


mBar ~ [Link](main)

# erzeugt erstes Menuobjekt der Menuleiste


mFile ~ [Link](mBar)

# erzeugt Elemente in erstem Menu


mFile.add_command(label~"Neu")

mFile.add_command(label~"Laden")

mFile.add_command(label~"Speichern")

mFile.add_separator()
mFile.add_command(label~"Beenden", command~ende)

# Widget-Variablen der Radiobutton Menupunkte


# bzw. Checkbutton-Menupunkte
farbe ~ [Link]()
[Link]("#FFFFFF")
rand ~ [Link]()
[Link](O)
Menüs und MessageBoxes I 12.4

# erzeugt zweites Menuobjekt der Menuleiste


mView ~ [Link](mBar)
mView["tearoff"] ~ 0 # Menu nicht abtrennbar

# erzeugt Elemente in zweitem Menu


[Link] radiobutton(label~"Rot", variable~farbe,
val ue~"lfFFOOOO", underl ine~O, command~farbwechsel)
[Link] radiobutton(label~"Gelb", variable~farbe,
val ue~"lfFFFFOO", underl ine~O, command~farbwechsel)
[Link] radiobutton(label~"Blau", variable~farbe,
val ue~"lfOOOOFF", underl ine~O, command~farbwechsel)
mView.add_radiobutton(label~"Magenta", variable~farbe,

val ue~"lfFFOOFF", underl ine~O, command~farbwechsel)


mView.add_separator()
[Link] checkbutton(label~"Rand sichtbar",
variable~rand, onvalue~l, offvalue~O, underline~5,

command~randwechsel )

# erstes und zweites Menu zur Menuleiste hinzu


[Link] cascade(label~"Datei", menu~mFile)

[Link] cascade(label~"Ansicht", menu~mView)

# gesamte Menuleiste zu Fenster hinzu


main["menu"] ~ mBar

[Link]()

I
Listing 12.24 Datei [Link]

Nach dem Start sind nur die beiden Einträge in der Menüleiste sichtbar Startzustand
sowie der weiße Frame ohne Rand:

tk GJ[Q)[RJ
Datei Ansicht

Abbildung 12.32 Hauptfenster mit Menü

Nach der Anwahl des Menüs DATEI klappt das Menü mit den folgenden Menü Datei
Menüpunkten auf:
12 I Benutzeroberflächen

Neu
Laden
Speichern

Beend en

Abbildung 12.33 Menü Datei

Nur der Menüpunkt BEENDEN ist mit einer Funktion belegt (Beenden des
Programms), die anderen Menüpunkte dienen ausschließlich der Dar-
stellung.

Menü Ansicht Nach der Anwahl des Menüs ANSICHT klappt das Menü mit den folgen-
den Menüpunkten auf:

Bot
§e lb
lli au
tl agenta

Abbildung 12.34 Menü Ansicht, Startzustand

Einstellung Alle Menüpunkte sind mit einer Funktion belegt. Die Bedienung eines
der Farbe der ersten vier Menüpunkte sorgt dafür, dass die Farbe des dargestellten
Frames wechselt. Gleichzeitig wird der betreffende Menüpunkt markiert
und somit die aktuelle Farbe gekennzeichnet. Der letzte Menüpunkt
dient zur Darstellung des Frames mit oder ohne Rand.

Nach Bedienung Nach Anwählen von BLAU und des Menüpunkts RAND SICHTBAR sieht die
Oberfläche aus wie in Abbildung 12.35 dargestellt.

tk
. . Ansicht .p_.GJIi-[gJILI~•


Abbildung 12.35 Hauptfenster und Menü Ansicht, nach Änderung
Menüs und MessageBoxes I 12.4

Oberhalb jedes Menüs wird normalerweise eine gestrichelte Linie ange- Tear-Off
zeigt. Ein Klick auf diese Linie bewirkt die Auslagerung (Tear-Off) des
betreffenden Menüs als eigenständiges Fenster. Dies ist eine Standard-
eigenschaft von Python-GUI-Anwendungen und muss nicht gesondert
programmiert werden. Beim zweiten Menü (in Abbildung 12.36) wurde
diese Möglichkeit unterdrückt.

Zur Erläuterung des Programms:

~ Es wird ein Frame der Höhe 100 Pixel und der Breite 300 Pixel
erzeugt. Dieser dient als Zielobjekt für die Einstellung von Farbe und
Rand. Zu Beginn wird die Farbe Weiß und die Randbreite 10 einge-
stellt. Da keine Randart gewählt wird, ist der Rand noch nicht sicht-
bar.
~ Es wird ein Objekt der Klasse Menu (mBa r) als gesamte Menüleiste für Menu-Objekt
das Fenster erzeugt.
~ Es wird das Menü DATEI (m Fi 1 e) innerhalb der Menüleiste erzeugt.
~ Die Methode add_command() erzeugt einen einzelnen normalen add_commandO
Menüpunkt, der zur Ausführung eines Befehls führt. Der Wert der
Eigenschaft 1 a be 1 dient der sichtbaren Darstellung des Menüpunkts.
Im Menü DATEI ist nur der Menüpunkt BEENDEN mit einer Funktion
verbunden.
~ Die Methode add_sepa ra to r ( ) erzeugt eine optische Trennlinie zwi- add_separatorO
schen verschiedenen, logisch zu trennenden Menüpunkten innerhalb
eines Menüs.
~ Zwei Widget-Variablen werden erzeugt, die später mit den zugehöri-
gen Menüpunkten verbunden werden:
~ zur Farbauswahl die Variable farbe vom Typ StringVar, mit dem
Widget-Variablen
I
Startwert »weiß«
~ zur Auswahl der Sichtbarkeit des Rands die Variable rand vom Typ
In t Va r, mit dem Startwert 0 (= kein Rand)
~ Es wird das zweite Menü (mVi ew) innerhalb der Menüleiste erzeugt.
~ Die Eigenschaft tearoff wird mit 0 (= fal se) belegt. Diese Belegung tearoff
bewirkt, dass das Menü nicht abgetrennt werden kann.
~ Mithilfe der Methode add_radiobutton() werden vier Menüpunkte add_radiobuttonO
als zusammengehörige Gruppe erzeugt, deren Auswahl zur Einstel-
lung der Frame-Farbe führt. Die Verbindung wird über die gemein-
same Widget-Variable hergestellt (Eigenschaft va r i ab 1 e), wie bei
einem Radio-Button-Widget. Jeder Menüpunkt hat einen eigenen
12 I Ben utzeroberflächen

Wert für die Eigenschaft val ue. Dieser Wert wird der zugehörigen
Widget-Variablen fa rbe zugewiesen. Bei Ausführung der Funktion
fa rbwechsel () wird dieser Wert dem Frame zugewiesen.

underline ~ Die Eigenschaft underl ine legt die Nummer des Buchstabens des
sichtbaren Eintrages fest, der unterstrichen wird. Falls das Menü
angewählt wurde, genügt die Eingabe des betreffenden Buchstabens
zur Auswahl des Menüpunktes.
add_check- ~ Mithilfe der Methode add_checkbutton() wird ein Menüpunkt als
buttonO einzelner Ein!Aus-schalter erzeugt, dessen Auswahl zur Einstellung
des Randes führt. Die Verbindung wird über die Widget-Variable her-
gestellt (Eigenschaft va r i ab 1 e), wie bei einem Check-Button-Widget.
Der Wert der Eigenschaften 0 n val u e und 0 ff val ue wird im Fall der
Markierung beziehungsweise Entmarkierung der zugehörigen wid-
get-Variablen rand übergeben. Bei Ausführung der Funktion rand-
wechsel () wird dieser Wert dem Frame zugewiesen.

add_cascadeO ~ Die Methode add_cascade() fügt der Menüleiste die beiden vorher
erzeugten Menüs (mFi 1 e und mVi ew) hinzu.
Eigenschaft menu ~ Dem Hauptfenster wird über die Eigenschaft menu die Menüleiste
(m Bar) hinzugefügt.
~ In der Funktion fa rbwechse 1 ( ) wird der Wert der Widget-Variablen
fa rbe mit der Methode get ( ) ermittelt und der Frame-Eigenschaft bg
(= background) zugewiesen.
getO ~ In der Funktion randwechsel () wird der Wert der Widget-Variablen
rand mit der Methode get() ermittelt und der Frame-Eigenschaft
re 1 i ef zugewiesen.

12.4.2 I<ontextmenüs
Ein Kontextmenü wird auf ähnliche Weise erzeugt wie eine Menüleiste.
Folgende Schritte sind erforderlich:

Reihenfolge der ~ Erzeugung eines Objekts der Klasse Menu als Kontextmenü
Erstellung
~ Erzeugung von einzelnen Menüpunkten verschiedenen Typs inner-
halb des Kontextmenüs
~ Verbindung eines Ereignisses mit einem bestimmten Widget
~ Aufruf des Kontextmenüs als Folge dieses Ereignisses in der Nähe des
betreffenden Widgets
Menüs und MessageBoxes I 12.4

Das besondere Problem bei einem Python-Kontextmenü besteht darin,


dass es an absoluten Bildschirmkoordinaten eingeblendet wird. Vor dem
Einblenden muss also zunächst ermittelt werden, an welcher Stelle des
Bildschirms sich das Hauptfenster befindet.

Außerdem muss die Position des zugehörigen Widgets innerhalb des Widget-Position
Hauptfensters berücksichtigt werden. Sie müssen das Widget mit ermitteln

p1 ace () absolut positionieren, da sich sonst seine Koordinaten verän-


dern können.

Das folgende Programm beinhaltet ein Label mit einem Bild. Über ein
Kontextmenü soll die Hintergrund- oder Rahmenfarbe des Labels geän-
dert werden. Wird die rechte Maustaste innerhalb des Labels betätigt, so
wird das Kontextmenü an der aktuellen Mausposition eingeblendet.
import sys, tkinter

def ende():
[Link](O)

def 1 bpop (e) :


global lbx, lby

# ermittelt geometrischen Ort des Hauptfensters


# Information wird als String gegeben
gm ~ [Link]()

# Position des 1. und 2. Pluszeichens im String


pI
p2
[Link](gm, "+")
[Link](gm, "+" pl+l) I
ir Teilstring zwischen dem 1. und 2. Pluszeichen
mainx ~ gm[pl+l:p2]

# Teilstring nach dem 2. Pluszeichen bis zum Ende


mainy ~ gm[p2+1:]

# Ermittlung der Position des Popup-Menus:


# Fensterposition plus Labelposition plus Position
# innerhalb des Labels plus Versatz
mpop.tk_popup(int(mainx) + lbx + e.x + 5,
int(mainy) + lby + e.y + 30)

def farbwechsel ():


lb["bg"] ~ [Link]()
12 I Benutzeroberflächen

main ~ [Link]()

# Frame zur Erzeugung der Fenstermasse


fr ~ [Link](main. height~200. width~300)
[Link]()

lf Label mit Bild. Rahmen und Farbe


# Koordinaten des Labels in Variablen
im [Link](file~"[Link]")

lb ~ [Link](main. image~im. relief~"ridge".


bd~5. bg~"#OOOOOO")

[Link]("(Button 3)".lbpop)
lbx ~ 60
1 by ~ 30
[Link](x~lbx. y~lby. anchor~"nw")

# Widget-Variable der Farbe


farbe ~ [Link]()
[Link]("#OOOOOO")

# Menu zur Farbeinstellung


mpop ~ [Link](main)
mpop["tearoff"] ~ 0
mpop.add_radiobutton(label~"rot". variable~farbe.

val ue~"lfFFOOOO". command~farbwechsel)


mpop.add_radiobutton(label~"gelb". variable~farbe.

val ue~"lfFFFFOO". command~farbwechsel)


mpop.add_radiobutton(label~"schwarz". variable~farbe.

val ue~"lfOOOOOO". command~farbwechsel)

lf Ende
bende ~ [Link](main. text~"Ende".

command~ende)

[Link](relx~l. rely~O. anchor~"ne")

[Link]()

Listing 12.25 Datei [Link]

Startzustand Nach dem Start ist das Label inklusive Bild mit schwarzem Rahmen sicht-
bar (siehe Abbildung 12.36).

370
Menüs und MessageBoxes I 12.4

tk GJ[QJ[EJ
Ende

Abbildung 12.36 Label mit Kontextmenü, Startzustand

Nach der Betätigung der rechten Maustaste innerhalb des Labels wird das Nach Bedienung
folgende Kontextmenü an der aktuellen Mausposition eingeblendet:

tk GJ[QJ[EJ
Ende

." schwarz

Abbildung 12.37 Kontextmenü innerhalb des Labels

Zur Erläuterung des Menü-Widgets:


I
~ Das Menü (mpop) wird als Menü des Hauptfensters erzeugt. Klasse Menu

~ Die Eigenschaft te ar off wird auf 0 (= fa 1se) gestellt, da das Abtren- tearoff
nen eines Kontextmenüs nicht sinnvoll ist.
~ Es werden drei Radio-Buttons als Menüpunkte erzeugt. Diese werden Menüpunkt
über die Widget-Variable fa r be miteinander verbunden und ermög-
lichen den Wechsel zwischen den Farben Rot, Gelb und Schwarz.
Startwert für die Widget-Variable ist Schwarz.
Zur Erläuterung des Kontextmenü-Aufrufs:

~ Beim Label 1 b wird das Ereignis rechte Maustaste betätigt mit der Ereignis
Funktion 1 bpop ( ) verbunden.

371
12 I Benutzeroberflächen

geometryO ~ Innerhalb der Funktion 1 bpop ( ) wird zum Hauptfenster die Methode
geomet r y () aufgerufen. Diese Methode liefert eine Zeichenkette mit
den Maßen und den Koordinaten des Fensters. Befindet sich das Fens-
ter beispielsweise aktuell an der Position x~589, y~2 0 1, so sieht die
Zeichenkette wie folgt aus: 300x200+589+201. Die ersten beiden Zah-
len bezeichnen die Maße des Labels, hinter den beiden Pluszeichen
stehen die aktuellen x- und y-Koordinaten.
~ Mithilfe der Methode f in d ( ) aus dem Modul s tri n 9 wird die Posi-
tion der beiden Pluszeichen ermittelt. Die jeweils nachfolgenden Teil-
strings werden extrahiert.
Position des ~ Aus diesen Werten und den Koordinaten des Labels, der aktuellen
Kontextmenüs Mausposition und einem kleinen Versatz werden die gewünschten
Koordinaten des Kontextmenüs berechnet.
~ Die Methode tk_popup() wird aufgerufen, um das Kontextmenü an
diesen Koordinaten erscheinen zu lassen.

12.4.3 MessageBoxes
Dialogfelder Es gibt eine Reihe von vorgefertigten Dialogfeldern, die die Informations-
übermittlung zwischen Benutzer und Programm vereinfachen. Diese
sogenannten MessageBoxes werden mithilfe von Funktionen des Moduls
[Link] aufgerufen. Die Tabelle 12.2 gibt eine Übersicht
über diese Dialogfelder.

Funktionsname Buttons Funktion


showinfo() OK Information an den Benutzer übermit-
teln, bestätigen lassen
showwarni ng() OK Benutzer warnen, bestätigen lassen
showerror( ) OK Fehler an den Benutzer melden, bestäti-
gen lassen
askyesno( ) JA, NEIN Antwort JA oder NEIN vom Benutzer
erfragen
askokcancel () OK, ABBRECHEN Antwort OK oder ABBRECHEN vom
Ben utzer erfragen
askretrycancel () WIEDERHOLEN, Antwort WIEDERHOLEN oder ABBRECHEN
ABBRECHEN vom Benutzer erfragen
s how( ) eigene Auswahl Antwort vom Benutzer erfragen, alige-
von Buttons mein

Tabelle 12.2 Funktionen des Moduls [Link]

372
Menüs und MessageBoxes I 12·4

Im folgenden Programm werden alle sieben Funktionen, jeweils über Alle sieben
einen eigenen Button, aufgerufen. Ergibt die Bedienung der Dialogbox Funktionen

eine Antwort, so wird diese Antwort in einem Label dargestellt.


import sys, tkinter, [Link]

def ende():
[Link](O)

def msginfo(): Info


[Link] \
("Info","Eine Info-Box")

def msgwarning(): Warnung


[Link] \
("Warnung","Eine Warnungs-Box")

def msgerror(): Fehler


[Link] \
("Fehler","Eine Fehler-Box")

def msgyesno(): Ja, Nein


ant wort ~ [Link] \
("Ja/Nein", "Eine Ja/Nein-Box")
if antwort ~~ 1:
lbanz["text"] "Ja"
else:

I
lbanz["text"] "Nein"

def msgokcancel (): Ok / Abbrechen


antwort ~ [Link] \
("Ok/Abbrechen", "Eine Ok/Abbrechen-Box")
if antwort ~~ 1:
lbanz["text"] "Ok"
else:
lbanz["text"] "Abbrechen"

def msgretrycancel (): Wiederholen /


antwort ~ [Link] \ Abbrechen
(" Wiederholen/Abbrechen",
"Eine Wiederholen/Abbrechen-Box")
if antwort ~~ 1:
lbanz["text"] "Wiederholen"
else:
lbanz["text"] "Abbrechen"

373
12 Ben utzeroberflächen

Allgemeines def msgfrage():


Dialogfeld lf hier einmal in allgemeiner Technik, ohne Komfort
msgbox ~ [Link](main,
type~[Link],

icon~[Link],

title~"Beenden/Wiederholen/Ignorieren",

message~"Beenden, Wiederholen oder Ignorieren")

antwort ~ [Link]()

if antwort ~~ "abort":
lbanz["text"] ~ "Beenden"
elif antwort ~~ "retry":
lbanz["text"] "Wiederholen"
else:
1 banz[ "text"] "Ignorieren"

main ~ [Link]()

lf Button: Message Info


binfo ~ [Link](main,
text ~ "Info", command~msginfo)
[Link]()

# Button: Message Box Warning


bwarning ~ [Link](main,
text ~ "Warnung", command~msgwarning)
[Link]( )

# Button: Message Box Error


berror ~ [Link](main,
text ~ "Fehl er", command~msgerror)
[Link]( )

# Button: Message Box Ja/Nein


byesno ~ [Link](main,
text ~ "Ja/Nein", command~msgyesno)
[Link]()

# Button: Message Box OK/Cancel


bokcancel ~ [Link](main,
text ~ "Ok/ Abbrechen", command~msgokcancel)
bokcancel . pack()

374
Menüs und MessageBoxes I 12.4

# Button: Message Box Retry/Cancel


bretrycancel ~ tki nter. Button(mai n,
text ~ "Wiederholen/Abbrechen",
command~msgretrycancel )
bretrycancel . pack()

# Button: Message Box Frage


bfrage ~ [Link](main,
text ~ "Allgemeine Frage", command~msgfrage)
bfrage. pack()

i! Ende- Button
bende ~ [Link](main,
text ~ "Ende", command~ende)

[Link]()

i! Anzei ge- Label


lbanz ~ [Link](main)
[Link]()

[Link]()

Listing 12.26 Datei [Link]

Die folgenden Ab bildungen geben jeweils die Darstellung der verschie-


denen Dialogboxen bei Windows wieder.

Info

Eine Info-Box
[E]
I
OK

Abbildung 12.38 Info-Box

Warnung (gJ
.n Eine Warnungs-Box

OK

Abbildung 12.39 Warnungs-Box

375
12 Benutzeroberflächen

Fehler lRl
Eine Fehler -Bo x

OK

Abbildung 12_40 Fehler-Box

Ja/Nein lRl
Eine Ja/Nein-Box

Ja Nein

Abbildung 12_41 Ja/Nein-Box

OkJAbbrechen lRl
Eine Ok/Abbrechen-Box

OK Abbrechen

Abbildung 12_42 Ok/Abbrechen-Box

Wiederholen/Abbrechen ~

~ Eine Wiederholen/Abbrechen-Bo x

I Wiederholen I Abbrechen

Abbildung 12_43 Wiederholen/Abbrechen-Box

BeendenlWiederholenlignorieren lRl
Beenden, Wiederholen oder Ignorieren

Abbrechen Wiederholen I Ignorieren

Abbildung 12_44 Allgemeine Frage-Box

376
Menüs und MessageBoxes I 12.4

Zur Erläuterung:

~ Die verschiedenen Funktionen haben jeweils zwei Parameter:


~ Der erste Parameter beinhaltet den Text für den Titel der Box.
~ Der zweite Parameter beinhaltet den Informationstext für den
Benutzer beziehungsweise die Frage neben den Buttons.
~ Zusätzlich werden passende Symbole (Icons) dargestellt.
~ Die drei as k-Funktionen, die eine Frage an den Benutzer beinhalten, ask
liefern als Rückgabewert 1 oder o.
~ Der Wert 1 bedeutet, dass der erste Button gedrückt wurde, also
eine positive Antwort gegeben wurde (JA oder OK oder WIEDER-
HOLEN).
~ Der Wert 0 bedeutet, dass der zweite Button gedrückt wurde, also
eine negative Antwort gegeben wurde (NEIN oder ABBRECHEN).
~ Die allgemeine Funktion show( ) ist nicht so komfortabel zu benutzen showO
wie die anderen Funktionen, bietet aber mehr Möglichkeiten bei der
Gestaltung:
~ Es wird zunächst ein Objekt der Klasse Message erzeugt (hier: msg-
box), dem verschiedene Eigenschaften gegeben werden: type (wel-
che Buttons), i con (dargestelltes Symbol), ti tl e (Titel) und mes-
sage (Informationstext neben den Buttons).

~ Die Methode show ( ) wird auf dieses Objekt angewendet.


~

I
Rückgabewert ist eine Zeichenkette, die die Bezeichnung des
gedrückten Buttons beinhaltet (hier: abort, retry oder ignore).

377
13 Lösungen

Sollten Sie die Übungsaufgaben nicht vollständig gelöst haben, geben


Ihnen die folgenden Lösungen eine Hilfestellung. Wenn Sie selbst eine
lauffähige Lösung gefunden haben, sollten Sie diese mit der hier vorge-
stellten Lösung vergleichen.

13·1 lösungen zu I<apitel 2

übung U0201:

»> 13 5 * 2 + 12 / 6
5.0
»> 7 / 2 5 / 4
2.25
»> (12 5 * 2) / 4
0.5
»> (1 / 2 1 / 4 + (4 + 3) / 8) * 2
2.25

Übung U0202:

»> inch ~ 2.54


»> 5 * inch
12.699999999999999
»> 20 * inch
50.799999999999997
»> 92.7 * inch
I
235.458

13.2 lösungen zu I<apitel 3

übung U0301:

# Umrechnungsfaktor
inch ~ 2.54

379
13 I Lösungen

# Eingabe des inch-Wertes


print("Bitte geben Sie den inch-Wert ein:")
xi ~ float(input())

lf Umrechnung
xcm ~ xi * inch

lf Ausgabe
print(xi. "inch sind". xcm. "cm")

Übung U0302:

lf Ei ngabe
print("Geben Sie Ihr Bruttogehalt in Euro ein:")
bruttobetrag ~ float(input())

lf Umrechnung
steuerbetrag bruttobetrag * 0.18

lf Ausgabe
print("Es ergibt sich ein Steuerbetrag von".
steuerbetrag. "Euro")

Übung U0303:

lf Ei ngabe
print("Geben Sie Ihr Bruttogehalt in Euro ein:")
bruttobetrag ~ float(input())

lf Umrechnung
if bruttobetrag > 2500:
steuerbetrag bruttobetrag * 0.22
else:
steuerbetrag bruttobetrag * 0.18

lf Ausgabe
print("Es ergibt sich ein Steuerbetrag von".
steuerbetrag. "Euro")

Übung U0304:

lf Ei ngabe
print("Geben Sie Ihr Bruttogehalt in Euro ein:")
bruttobetrag ~ float(input())
Lösungen zu Kapitel 3 I 13.2

Ir Umrechnung
if bruttobetrag > 4000:
steuerbetrag ~ bruttobetrag * 0.26
elif bruttobetrag < 2500:
steuerbetrag bruttobetrag * 0.18
else:
steuerbetrag bruttobetrag * 0.22

Ir Ausgabe
print("Es ergibt sich ein Steuerbetrag von".
steuerbetrag. "Euro")

Übung U0305:

Ir Ei ngabe
print("Geben Sie Ihr Bruttogehalt in Euro ein:")
gehalt ~ float(input())
print( "Geben Sie Ihren Famil ienstand ein"
+ " (1~ledig. 2~verheiratet):")

fs ~ int(input())

Ir Umrechnung
if gehalt> 4000 and fs 1:
sb ~ gehalt * 0.26
elif gehalt <~ 4000 and fs 2:
sb gehalt * 0.18
else:
sb ~ gehalt * 0.22

Ir Ausgabe
print("Es ergibt sich ein Steuerbetrag von". sb. "Euro")

Übung U0306:
I
Schl eife
2
3
6.5
-7
Schl eife 2
3
6
9
Schl eife 3
-3
13 I Lösungen

5
9
13
Schl eife 4
3
0
-3
-6
-9

Übung U0307:

# Umrechnungsfaktor
inch ~ 2.54

lf Schl eife
for xi in range (15, 41. 5):
xcm ~ xi * inch
print(xi, "inch xcm, "cm")

Übung U0308:

# Umrechnungsfaktor
inch ~ 2.54

lf Erste Ei ngabe
print("Bitte geben Sie den inch-Wert ein:")
xi ~ float(input())

# while-Schleife
while xi !~ 0:
# Umrechnung, Ausgabe
xcm ~ xi * inch
print(xi, "inch sind", xcm, "cm")

# Weitere Eingabe
print("Bitte geben Sie den inch-Wert ein:")
xi ~ float(input())

Übung U0309:

# Umrechnungsfaktor
inch ~ 2.54
Lösungen zu Kapitel 3 I 13.2

# Initialisierung der while-Schleife


fehler ~ 1

# Schleife bei falscher Eingabe


while fehler ~~ 1:
Ir Ei ng abe
print("Bitte geben Sie den inch- Wert ein")
xi ~ input()

# Versuch der Umwandlung


try:
xi ~ fl oat(xi)
fehler ~ 0
# Fehler bei Umwandlung
except:
print("Falsche Eingabe")

# Umrechnung, Ausgabe
xcm ~ xi * inch
print(xi, "inch sind", xcm, "cm")

Übung U0310:

Ir Funktion
def steuer(bb):
Ir Umrechnung
if bb > 2500:
sb bb * 0.22
else:
sb~bb*0.18

Ir Ausgabe
print("Bruttobetrag:", bb,
"Euro, Steuerbetrag:", sb, "Euro")
I
# Verschiedene Werte
steuer(1800)
steuer(2200)
steuer(2500)
steuer(2900)

Übung U0311:

Ir Funktion
def steuer(bb):
13 I Lösungen

lf Umrechnung
if bb > 2500:
sb bb * 0.22
else:
sb bb*0.18

# Ergebnis senden
return sb

# Verschiedene Werte
print("Bruttobetrag: 1800 Euro, Steuerbetrag:",
steuer(1800), "Euro")
print("Bruttobetrag: 1800 Euro, Steuerbetrag:",
steuer(2200), "Euro")
print("Bruttobetrag: 1800 Euro, Steuerbetrag:",
steuer(2500), "Euro")
print("Bruttobetrag: 1800 Euro, Steuerbetrag:",
steuer(2900), "Euro")

13·3 lösungen zu I<apitel 5

Übung U0501:

# Umrechnungsfaktor
inch ~ 2.54

lf Tabell enkopf
pr i nt ( " {0 : >7} {1 >
: 7} " . form a t ( " i n c h" , "cm" ) )

lf Schl eife
for xi in range (15, 41. 5):
xcm ~ xi * inch
pr i nt ( " { 0 : 7 . 1 f} {1 : 7 . 1f} " . f 0 rma t ( xi, xcm ) )

Übung U0502

Datei [Link]:

lf Funktion
def steuer(bb):
lf Umrechnung
if bb > 2500:
sb bb * 0.22
else:
sb bb*0.18
Lösungen zu Kapitel 5 I 13.3

# Ergebnis senden
return sb

Übung U0502

Datei [Link]:

i! Import
import u0502mod

# Verschiedene Werte
print("Bruttobetrag: 1800 Euro, Steuerbetrag:",
[Link](1800), "Euro")
print("Bruttobetrag: 1800 Euro, Steuerbetrag:",
[Link](2200), "Euro")
print("Bruttobetrag: 1800 Euro, Steuerbetrag:",
[Link](2500), "Euro")
print("Bruttobetrag: 1800 Euro, Steuerbetrag:",
[Link](2900), "Euro")

I
Index

- (Minus)
Set 117 Python 20, 32
Subtraktion 18 SQL 298
!= 38 == 38,114,125
# 27 >
#!/usr/bin/python 27 Format 143
$_GET 263 Python 38
$]OST 266 Set 116
% (Prozent) SQL 298
Format 142,197 >=
Modulo 19, 83 Python 38
%= 133 Set 116
& 117 SQL 298
, 86 [l. Dictionary 110
* (Stern) 1\ 117
Multiplikation 18 _add_O 186
Parameter 161 _cmp_O 196
Vervielfachung 87,100 _deLO 184
** 80 _eq_O 186
**= 132 _floordiv_O 186
*= 132 _ge_O 186
+ (Plus) _gt_O 186
Addition 18 _init_O 183
Verkettung 87, 100 _le_O 186
+= 132 _11_0 186
. 67 _mod_O 186
/ 18 _mul_O 186
// 19 _ne_O 186
//= 133 _pow_O 186
/= 133 _str_O 184
: (Doppelpunkt) 38, 56 _sub_O 186
< _truediv_O 186
Format 143 _thread
Python 38 geUdentO 214
Set 116 Modul 212
SQL 298 starCnew_threadO 212
<= {}
Python 38 Dictionary 110
Set 116 Formatierung 141
SQL 298 117
<> 100-Dollar-Laptop 14
Python 196 2t03 197
SQL 298
-= 132
Index

A Bedingung 37, 56, 120


verknüpfen 42
absO 86 Benannter Parameter 162,196
addO 116 Benutzeroberfläche 309
add_cascadeO 368 Betrag 86
add_checkbuttonO 368 bg 313
add_commandO 367 Bild einbinden (GUI) 313
addjadiobuttonO 367 Bild-Widget 316
add_separatorO 367 binO 78
Aktionsabfrage (Datenbank) 294 Binärdaten 97
anchor 313 bindO 340, 342
and 42 Bogenmaß 82
AND (SQL) 298 bool 120
Antwort-Box (GUI) 372 borderwidth 313
Anweisung break 48
ausführen 137 Breakpoint 157
leere 135 Breite (GUI) 313
Anzahl Browser 259
Elemente 89 aufrufen 280
Teiltexte 92 Bruch 83
Anzeigefeld (GUI) 313 annähern 85
Apache-Webserver 258 Button
appendO 104,211 tkinter 311
appendleftO 211 Button-Widget 311
argv Byte-Literal 97, 261
sys 176 bytes 97
Array 98
as 160 c
ASCII-Zeichen 97
askokcancelO 372 callback (GUI) 311
Ausdruck auswerten 137 Carriage Return 97
Ausgabe formatieren 140 cgi
Ausnahme 58 FieldStorage 270
Thread 216 Modul 267,270
Ausnahmebehandlung 60 cgi-bin 267,269
Ausrichtung (GUI) 313 CGI-Skript 267
Auswahlabfrage (Datenbank) 296 Standardverzeichnis 269
Auswahlmenü cgitb
einfaches (GUI) 323 enableO 270
mehrfaches (GUI) 325 Modul 270
Auswahlmenü (HTML) 275 checkbox (HTML) 277
Checkbutton-Widget 333
B checked (HTML) 277
chrO 172
b class 180
Format 144 clearO 116
Prefix 97 closeO 227
Basisverzeichnis 258 connection 295
Bedingter Ausdruck 144 cmd 24
Index

collections Datei (Forts.)


dequeO 211 Liste erstellen 246
Modul 209 öffnen 226
command 311,331,335 Position verändern 239
Comma-separated Values 234 schließen 227
commitO schreiben 227
connection 294 Speicherung 225
Compiler 14 Typ 225
Conditional Expression 144 umbenennen 249
configureO 312 verwalten 248
connectO ZugriJfszeitpunkt 248
sqlite3 294 Dateiendung
connection .csv 234
closeO 295 .py 22
commitO 294 Dateizugriff
cursorO 294 binärer 225
sqlite3 294 sequenzieller 22 5
Content-type 268 wahlfreier 225
continue 63 Datenbank 291
copy erzeugen 292
deepcopyO 128,187 im Internet 306
Modul 128,187 Verbindung herstellen 294
copyO 116 Datenbankmanagement-System 292
copyfileO Datensatz (Datenbank) 291
shutil 249 ändern 303
cosO anlegen 292,294
math 82 anzeigen 295
countO 104 auswählen 296
str 92 sortieren 300
CREATE TABLE (SQL) 294 Datensatzcursor (Datenbank) 294
CSV-Datei 234 Datentyp
cursor bool 120
executeO 294 bytes 97
sqlite3 294 Datenbank 291
cursorO deque 209
connection 294 ermitteln 83
jloat 79
D FLOAT (SQL) 292
int 77
d (Format) 144 INTEGER (SQL) 292
Datei long 196
Eigenschaften 247 NoneType 123
Ende erkennen 231 spezieller 209
festgelegte Struktur 237 str 86
formatierte Ausgabe 23 8 TEXT (SQL) 292
Größe 248 Datum und Zeit 199
kopieren 249 Differenz 204
lesen 229 erzeugen 203
lesen und schreiben 241 formatieren 199,201
Index

Datum und Zeit (Forts.) Eingabe


Nullpunkt 199 kommentierte 134
Debug Contral 154 nicht sinnvolle 159
Debug Off 157 versteckte (GUI) 318
Debug On 154 versteckte (HMTL) 275
Debugger 154 wiederholen 62
deepcopyO Zeichenkette 33,87
copy 128,187 Eingabe, Verarbeitung, Ausgabe 34
def 67 Eingabefeld
Klassenmethode 180 einzeilig (GUI) 316
deI 101,127 HTML 275
delO 111 mehrzeiliges (GUI) 320
DELETE (SQL) 305 scrollbares (GUI) 322
denominator 85 Eingebaute Funktion 170
deque 209 Einrücken 56
dequeO doppelt 49
collections 211 Einzelschrittverfahren 154
Deserialisierung 242 elif 41
Destruktor 182 else 39,41
dezimale Zahl 77 Elternelement (GUI) 343
Dezimalformat 144 enableO
Dezimalzeichen 18 cgitb 270
Dictionary 109 end 138
aktualisieren 111 Endlosschleife 120, 309
Element löschen 111 endswithO
Elementexistenz 111 str 94
erzeugen 110 Entry-Widget 316
Funktionen 110 Escape-Sequenz 97
leeres 120 evalO 137
vergleichen 113 Excel 235
View 111 except 60,158
Differenzmenge 118 execO 137
discardO 116 executeO
Doppelpunkt 89 cursor 294
double-ended queue 209 exit 25
DoubleVar 331 exitO
Duale Zahl 77 sys 310
Dualformat 144 Exponentialformat 142
dumpO extendO 211
pickle 242 extendleftO 211

E F
e f (Format) 142
Eulersche Zahl 82 falsch 120
Exponentialschreibweise 79 False 120
Format 142 Fehler 58,151
Eigenschaft 180 abfangen 60,61
Eindeutiger Index (Datenbank) 293,305 erzeugen 158

39°
Index

Fehler (Forts.) Funktion (Forts.)


im Browser anzeigen 271 trigonometrische 82
Laufzeitfehler 153 überspringen 156
logischer 154 variable Parameteranzahl 161
Nachricht (GUI) 372 verlassen 157
Syntaxfehler 152
Unterscheidung 159 G
Feld (Datenbank) 291
fg 313 Ganze Zahl 77
FieldStorage Ganzzahldivision
cgi 270 Rest 19
value 271 Ganzzahligkeit ermitteln 83
filterO 148 gcdO
findO fractions 85
str 92 Geometriemanager (GUI) 311, 343, 351,
findallO 353
re 218 geometryO 372
Fließkommazahl 79 gesetzt 61
float 79 getO 317,325,331
FLOAT (SQL) 292 geUdentO
floatO 34, 94 thread 214
font 313 GEI-Methode 263
for 47 Gleich
form (HTML) 263 in Python 38
formatO 140,239 in SQL 298
FractionO globO
fractions 84 glob 246
fractions global 168
FractionO 84 Graphical User Interface 309
gcdO 85 gridO 351
Modul 83 Groß- und Kleinschreibung 21
Frame-Widget 343 Größter gemeinsamer Teiler 85
from 175 GUI-Anwendung 309
Frozenset 119
frozensetO 119 H
Funktion 65
Aufruf 67 Haltepunkt 157
beenden 70 has_keyO 197
benannter Parameter 162 Header 268
Definition 67 height 313
eingebaute 170 hexO 78
mehrere Rückgabewerte 164 hexadezimale Zahl 77
Mehrfachaufruf 146 Hexadezimalformat 144
Name 67 Hintergrundfarbe (GUI) 313
Parameter, ein 68 Höhe (GUI) 313
Parameter, mehrere 69 htdocs 258
Parameterübergabe 165 HTML
Parametervoreinstellung 163 Datei kopieren 261
Rückgabewert 70 Datei lesen 259

391
Index

HTML (Forts.) J
Formular 269
Formulardaten 270 Ja/Nein-Box (GUI) 372
Formularelement 272
lernen 259 I<
http 258
Kalenderwoche 201
keysO 113
Klammersetzung 19
Identität 126 Klasse 179
IDLE 17,154 abgeleitete 189
if 38 Basisklasse 189
image 313 Definition 180
import 37,175 Kommandozeile 24,176
in Kommentar 27
Dictionary 111 Konstruktor 182
Element-View 113 Kontextmenü (GUI) 368
for 47 Kontrollkästchen
Key- View 113 GUI 333
Liste 100 HTML 275
Sequenz 88 Kontrollstruktur
Set 115 geschachtelt 48
Werte-View 112 Kopfrechnen 31
Index einer Sequenz 89
indexO 104 l
Info-Nachricht (GUI) 372
input (HTML) 263 Label-Widget 313
inputO 26,33,134 Lambda 169
INSERT INTO (SQL) 294 Lange Ausgaben 28
insertO 103,321,324 Laufzeitfehler 153
Instanz 181 Layoutmanager (GUI) 343
int 77 lenO 89
intO 34, 80, 94 like (SQL) 298
INTEGER (SQL) 292 limiCdenominatorO 85
Internet 257 Line Feed 97
Daten lesen 259 Linksbündig 143
Daten senden 261,264 Linux 14
Datenbank im 306 List Comprehension 149
Interpreter 14 Listbox-Widget 323, 325
IntVar 331 Liste 98
is 125,188 Anzahl bestimmter Elemente 104
itemsO 113 eingebettete 99
Itera ble 145 Element anfügen 104
filtern 148 Element einfügen 103
verbinden 146 Element löschen 101, 104
Iterierbares Objekt 145 filtern 149
leere 120
mehrdimensionale 99
Operation 101

392
Index

Liste (Forts.) Menüleiste (GUI) 363


Position ermitteln 104 messagebox
sortieren 104 tkinter 372
umdrehen 104 Methode 180
loadO besondere 184
pickle 244 minO 171
localhost 258 Minimum 171
localtimeO mktimeO
time 199 time 203
logischer Fehler 154 Modul
logischer Operator 42 thread 212
lokaler Namensraum 168 cgi 267,270
lokaler Webserver 257 cgitb 270
long 196 rollections 209
Lösungen 15 ropy 128,187
eigenes 174
M einbinden 37, 175
fractions 83
mainloopO glob 246
Tk 311 math 82
mapO 146 os 247,248
math random 37
rosO 82 re 218
e 82 shutil 248
Modul 82 sqlite3 292
pi 82 sys 310
sinO 82 tkinter 310
tanO 82 [Link] 372
Maus-Ereignis (GUI) 338 [Link] 323
maxO 171 urllib 257
Maximum 171 urllib. parse 257
Menge 114 [Link] 257
DiJferenzmenge 118 webbrowser 280
Element hinzufügen 116 Modularisierung 65, 174
Element löschen 116 Monatsname 201
kopieren 116 multiple (HTML) 277
leere 120 Multithreading 212
leeren 116
Schnittmenge 118 N
Teilmenge 116
Vereinigungsmenge 118 NachkommastelIen, Anzahl 140
Menu Nachrichtenbox (GUI) 372
tkinter 363 Namensraum 168
Menü Nenner eines Bruchs 85
Debug 154 NICHT
File 22 logisches (SQL) 298
Run 24 nicht
Menü (GUI) 363 logisches (Python) 42
abtrennen 367 Nichts 123

393
Index

None 123 os
NoneType 123 Modul 247,248
not 42 renameO 249
NOT (SQL) 298 statO 247
numerator 85 Out 157
Over 156
o
p
o (Format) 144
Objekt 77,180 packO 311
aus Datei lesen 244 Parallele Verarbeitung 212
ausgeben 184 Parameter 68, 69
erzeugen 181 benannter 162,196
Identität 188 variable Anzahl 161,196
in Datei schreiben 242 Voreinstellung 163
kopieren 128,187 partitionO
Referenz 125,187 str 94
Typ ermitteln 83 pass 135
vergleichen 186 password (HTML) 277
o bj ektorientierte Programmierung 179 Passworteingabe
octO 78 GUI 318
Oder, logisches (Python) 42 HTML 275
ODER, logisches (SQL) 298 PhotoImage
offvalue 335 tkinter 316
Ok/Abbrechen-Box (GUI) 372 PHP 258,262
Oktale Zahl 77 pi
Oktalformat 144 math 82
Online-Bestellung 274 pickle 242
onvalue 335 dumpO 242
OOP 179 loadO 244
openO placeO 353,355,357,359
Datei 226 popO 211
webbrowser 280 popleftO 211
Operator Position Teiltext 92
für Sequenzen 88 POST-Methode 265
logischer 42 PRIMARY KEY (SQL) 294, 305
mehrere Vergleichsoperatoren 44 printO 22,138
Rangfolge 19, 46 mehrere Ausgaben 28
Rechenoperator 80,186 Programm
Vergleichsoperator 38,186 abbrechen 157
Verkettung 88 Abbruch vermeiden 59
Vervielfachung 88 anhalten 26,206
Operatormethode 185 ausführen im Windows-Explorer 26
Optionsfeld (GUI) 329 ausführen in IDLE 24
or 42 ausführen unter Linux 27
OR (SQL) 298 ausführen von Kommandozeile 24
ordO 172 beenden 310
ORDER BY (SQL) 300 eingeben 22
konvertieren 197

394
Index

Programm (Forts.) Regulärer Ausdruck 218


Parameter 176 relief 313
Python removeO 104
auf dem Webserver 268 renameO
installieren 16 os 249
Interpreter 268 replaceO
Shell 17 str 93
starten 17 Reset-Button (HTML) 275
Version 3.0 195 return 70
[Link] 268 mehrere Werte 165
[Link] 16 reverseO 104
[Link] 16 reversedO 173
rfindO
Q str 92
rotateO 211
Quit 157 roundO 80
rpartitionO
R str 94
Rückgabewert 70, 123
RAD 13 mehrere 164
radio (HTML) 277 Run Module 24,155
Radiobutton Runden 80
GUI 329 RuntimeError 160
HTML 275
Rahmen (GUI) 343 s
raise 158
Randart (GUI) 313 Scale-Widget 335
Randbreite (GUI) 313 Schaltfläche (GUI) 311
randintO Schieberegler (GUI) 335
random 37 Schleife 47
random Abbruch 48
Modul 37 Durchlauf abbrechen 63
randintO 37 for 47
seedO 37 while 56
rangeO 51 Schlüssel-Wert-Kom bination 109
Rapid Application Development 13 Schnittmenge 118
raw_inputO 196 Schrift (GUI) 313
re Scrollbalken (GUI) 327
findallO 218 Scrollbar
Modul 218 tkinter 328
subO 222 Scrollbar-Widget 327
readO 229 ScrolledTextO
readlineO 229 [Link] 323
readlinesO 229 ScrolledText-Widget 322
Rechenregel 18 SerolIen (GUI) 322
Rechtsbündig 143 seedO
Referenz 125,187 random 37
löschen 127 seekO 239
übergeben 166 select (HTML) 277

395
Index

SELECT (SQL) 296 statO


selected (HTML) 277 os 247
self 181 Step 155
Selfhtml 259 str
Sende button (HTML) 275 countO 92
sep 138 Datentyp 86
Separator 138 endswithO 94
Sequenz 86 findO 92
Index 89 partitionO 94
Operatoren 88 replaceO 93
Teilbereich 89 rfindO 92
umdrehen 173 rpartitionO 94
Serialisierung 242 splitO 94
Set 114 startswithO 94
unveränderliches 119 strO 96
setO 115 strftimeO
GUI 328,331 time 201
Set-Literal 196 String 86
show 318 leerer 120
showO 372 StringVar 331
showerrorO 372 subO
showinfoO 372 re 222
showwarningO 372 Suchen und Ersetzen 218
shutil sumO 171
copyfileO 249 Summe 171
Modul 248 Syntaxfehler 152
sinO sys
math 82 argv 176
sleepO exitO 310
time 206 Modul 310
Slice 89
sortO 104 T
sortedO 173
Sortieren 173 Tabelle (Datenbank) 291
Spiel, Kopfrechnen 31 anlegen 292,294
splitO tanO
str 94 math 82
SQL 292 Taschenrechner 17
SQL-Befehl senden 294 Tastatur-Ereignis (GUI) 338
SQLite 292 Taste F5 24, 155
sqlite3 Teilbereich einer Sequenz 89
connectO 294 Teilmenge 116
connection 294 Teiltext ersetzen 93
cursor 294 TEXT (SQL) 292
Modul 292 text/html 268
starCnew_threadO Text-Area (HTML) 277
_thread 212 Text-Widget 320
startswithO Thread 212
str 94 Ausnahme 216
Index

Thread (Forts.) Umrechnung (Forts.)


globale Daten 215 in hexadezimal 78
Identifikation 213 in oktal 78
time 199 Umwandlung
localtimeO 199 in ganze Zahl 80
mktimeO 203 in Zahl 34, 94
sleepO 206 in Zeichen kette 96
strftimeO 201 Und, logisches (Python) 42
timeO 199 UND, logisches (SQL) 298
timeO Ungleich
time 199 Python 38
Tk SQL 298
Interface 309 Unicode 172
mainloop 311 Literal 196
tkinter 310 unique (SQL) 305
tkinter UPDATE (SQL) 303
Button 311 updateO 111
Menu 363 urlencodeO
messagebox 372 [Link] 266
Modul 310 urllib
Photoimage 316 Modul 257
Scrollbar 328 [Link]
Tk 310 Modul 257
tkinter .message box urlencodeO 266
askokcancelO 372 [Link]
askretrycancelO 372 Modul 257
askyesnoO 372 urlopenO 260
Modul 372 urlretrieveO 261
showO 372 urlopenO
showerrorO 372 [Link] 260
showinfoO 372 urlretrieveO
showwamingO 372 [Link] 261
[Link]
ScrolledTextO 323 v
True 120
try 60,158 value, FieldStorage 271
Tupel 104 ValueError 59
entpacken 108 valuesO 112
leeres 120 Variable 20, 32
mehrdimensionales 105 kontrollieren 156
verpacken 108 Name 21
typeO 83 Vereinigungsmenge 118
Vererbung 189
u Mehrfachvererbung 192
Vergleichsoperator 38
Übungsaufgabe 15 Verzeichnis verwalten 248
Umlaut 97 Verzweigung 37
Umrechnung einfach 38
in dual 78 mehrfache 40

397
Index

View 111 Widget (Forts.)


Vordergrundfarbe (GUI) 313 placeO 353,355,357,359
Vorzeichen 46 relief 313
scrollbares 327
w setO 328,331
show 318
Wagenrücklauf 97 StringVar 331
Wahr 120 Variable 329
Wahrheitswert 120 width 313
Wahrheitswerttabelle 42 yviewO 328
Warnungs-Nachricht (GUI) 372 width 313
Webbrowser 259 Wiederholen/Abbrechen-Box (GUI) 372
webbrowser Wiederholung 47
Modul 280 Windows 14
openO 280 Wochentagsname 201
Webserver 257 writeO 227
Programmierung 267 writelinesO 227
while 56
while(frue) 120 x
Widget 309
addJascadeO 368 x (Format) 144
addJheckbuttonO 368 Xampp 258
addJommandO 367 Control Panel 258
addJadiobuttonO 367
add_separatorO 367 y
anchor 313
anordnen 343,351,353,355 yviewO 328
Bewegung 357,359
bg 313
bindO 340, 342
z
borderwidth 313 Zahl 77
command 311,331,335 als Bruch annähern 85
configureO 312 ganze 77
DoubleVar 331 mit NachkommastelIen 79
Eigenschaften ändern 311 Zahlensystem 77
Ereignis 340 Zähler eines Bruchs 85
fg 313 Zeichenkette 86
font 313 beginnt mit 94
geometryO 372 Eingabe 87
getO 317,325,331 endet mit 94
gridO 351 mehrzeilig 87
Größe, Ort 372 partitionieren 94
height 313 zerlegen 94
image 313 Zeilenende 138
insertO 321, 324 Zeilenumbruch in Code 133
IntVar 331 Zeilenvorschub 97
offvalue 335 Zeitzone 201
onvalue 335 zipO 146
packO 311
Index

Zufallszahl
Generator 36
Generator initialisieren 37
liefern 37
Zuweisung 20, 32
kombinierte Operatoren 131
mehrfache 106

399

Das könnte Ihnen auch gefallen