Einstieg in Python 3
Einstieg in Python 3
Einstieg in Python 3
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!
ch ristine .siedle@[Link]
[Link]
Galileo Press· Rheinwerkallee 4·53227 Bonn
Auf einen Blick
1 Einführung ............................................................................ 13
3 Programmierkurs ................................................................... 31
4 Datentypen ........................................................................... 77
9 Dateien................................................................................. 225
12 Benutzeroberflächen 309
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
Dieses Buch wurde gesetzt aus der Linotype Syntax Serif (9,25/13,25 pt) in FrameMaker.
Gedruckt wurde es auf chlorfrei gebleichtem Offsetpapier.
ISBN 978-3-8362-1406-3
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
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
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
7
Inhalt
8
Inhalt
9
Inhalt
10
Inhalt
11
Inhalt
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.
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
13
1 I Einführung
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.
Sowohl Windows als auch Linux bieten komfortable grafische Benutzero- Grafische
berflächen. Kapitel 12, »Benutzeroberflächen«, beschäftigt sich daher mit Oberflächen
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
15
1 I Einführung
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.
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:
~ Python Manuals
6 Uninstall 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.
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
ID LE 3 . 0
>>> I
17
2 I Erste Schritte
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.
Zur Erläuterung:
18
Python als Taschenrechner I 2.1
Zur Erläuterung:
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.
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
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:
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.
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
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.
Zur Erläuterung:
~ Die eingebaute Funktion pr i nt ( ) gibt Text oder Werte von Variablen
auf dem Bildschirm aus.
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
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" )
23
2 I Erste Schritte
Personal firewall
roakes to its subpr
interface. This c
interface and no d
IDLE 3.0
» > ~~~~~~~~~~~~~~~~~~
» >
Hallo Welt
>>> I
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:
24
Speichern und Ausführen I 2.3
Ausführen
Öffnen: I_ v I
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.
25
2 I Erste Schritte
Dieses verhalten können Sie ändern, indem Sie den Programmcode wie
folgt modifizieren:
print("Hallo Welt")
input ()
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.
Dateiordne r
Dateio rdne r
Dat ei or dne r
Dateior dn er
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
f-l i ~ 1 ;: 1 '
I .,1. . "00' I
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.
27
2 I Erste Schritte
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.
Ü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" )
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.
31
3 I Programmierkurs
lf Berechnung
c ~ a + b
lf Ausgabe
print("Die Aufgabe:", a, "+", b)
print("Das Ergebnis:", c)
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.
print("Ihre Eingabe:", x)
Listing 3.2 Datei [Link]
~ Der Benutzer gibt einen kleinen Satz ein. Dieser Satz wird in der Vari-
ablen x gespeichert und anschließend ausgegeben.
33
3 I Programmierkurs
Ein Beispiel:
# Eingabe einer Zahl
print("Bitte eine ganze Zahl eingeben")
x~input()
print("Ihre Eingabe:", x)
# Mit Berechnung
xdoppel ~ xganz * 2
print("Das Doppelte:", xdoppel)
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
I
dem Bildschirm aus)
lf Ei ngabe
print("Bitte eine Zahl eingeben:")
z~input()
lf Ausgabe
print("Ihre Eingabe:", z)
print("Das Ergebnis:", c)
Die Aufgabe: 5 + 3
Bitte eine Zahl eingeben:
9
Ihre Eingabe: 9
Das Ergebnis: 8
Zur Erläuterung:
35
3 I Programmierkurs
# Zufallsgenerator initialisieren
[Link]( )
IrEi ngabe
I
print("Bitte eine Zahl eingeben:")
z~input()
zahl ~ int(z)
IrAusgabe
print("Ihre Eingabe:", z)
print("Das Ergebnis:", c)
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
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
print("x:", x)
if x > 0:
print("Diese Zahl ist positiv")
else:
print("Diese Zahl ist 0 oder negativ")
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.
i! Ei ngabe
print("Bitte eine Zahl eingeben:")
z~input()
zahl ~ int(z)
i! Verzwei gung
if zahl ~~ c:
39
3 I Programmierkurs
Zur Erläuterung:
Ü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
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")
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%
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")
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
~ l:rmrnl . •
> 4.000 Euro ledig 26%
> 4.000 Euro verheiratet 22%
s 4.000 Euro ledig 22%
s 4.000 Euro verheiratet 18%
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.
print("x:", x)
print("y:", y)
print("z:", z)
lfBed i ngung
ifx<y<z:
print("y liegt z wischen x und z")
44
Verzweigungen I 3·3
Zur Erläuterung:
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 ( )
Ir Ei ngabe
print("Bitte eine Zahl eingeben:")
z~input()
zahl ~ int(z)
Ir Ende
print("Ergebnis:" c)
Listing 3.11 Datei [Link]
45
3 I Programmierkurs
Zur Erläuterung:
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
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]
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.
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.
print(x. "positiv")
else:
ifx<O:
print(x. "negativ")
else:
print(x. "gleich 0")
I
Listing 3.14 Datei [Link]
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.
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
49
3 I Programmierkurs
mehr Leerzeichen, damit die Struktur auch für den Entwickler gut
erkennbar ist.
Die Anweisung b rea k dient zum Abbruch der Schleife, sobald der Benut-
zer das richtige Ergebnis eingegeben hat.
# Zufallsgenerator
import random
[Link]( )
zahl ~ int(z)
lf Verzwei gung
if zahl ~~ c:
lf Ende
print("Ergebnis:" c)
5°
Schleifen I 3·4
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
~ 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)
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)
Die Ausgabe:
Za h 1: 0
Za h1 :
Za h1: 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
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
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
54
Schleifen I 3·4
I
a [Link](I,10)
b [Link](I,10)
c a + b
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)
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
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")
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.
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 ( )
# Schleife initialisieren
zahl ~ c +
lf Anzahl initialisieren
versuch ~ 0
zahl ~ int(z)
# Verzweigung
if zahl ~~ c:
57
3 I Programmierkurs
Ir Anzahl ausgeben
print("Ergebnis: ", c)
print( "Anzahl Versuche:", versuch)
Listing 3.22 Datei p0322 .py
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.
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")
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).
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()
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:
60
Fehler und Ausnahmen I 3.5
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).
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]).
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]
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.
b [Link](l,10)
c a + b
lf Eingabe
print("Bitte eine Zahl eingeben:")
z~input()
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)
I
11a
Sie haben keine Zahl eingegeben
Bitte eine Zahl eingeben:
11
11 ist richtig
Ergebnis: 11
Anzahl Versuche: 3
Zur Erläuterung:
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
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.
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]
x ~
12 Y ~
5
x + y ~
17
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
lf Hauptprogramm
quadrat(4.5)
a ~ 3
quadrat(a)
quadrat(2*a)
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
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.
Ir Hauptprogramm
berechnung(2,3,5)
berechnung(5,2,3)
69
3 I Programmierkurs
lf Hauptprogramm
c ~ mittelwert(3, 9)
print("Mittelwert:", c)
x ~ 5
print("Mittelwert:", mittelwert(x,4))
Listing 3.31 Datei [Link]
Zur Erläuterung:
70
Funktionen und Module I 3.6
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()
lf Ei ng abe
print("Bitte eine Zahl eingeben:")
z~input()
71
3 I Programmierkurs
Ir Kommenta r
kommenta r( zahl, c)
IrAnzahl Versuche
print("Ergebnis: ", c)
print( "Anzahl Versuche:", versuch)
Ü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.
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
# 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)
lf 11: Kommenta r
i f zahl~~ c:
74
Das fertige Spiel I 3.7
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
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
77
4 I Datentypen
Ein Beispiel:
a ~ 27
print("Dezimal:", a)
print("Hexadezimal :", hex(a))
print("Oktal:",oct(a))
print("Dual:", bin(a))
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:
print(a. b. c. d)
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).
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)
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.
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
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)
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
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).
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)
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
lf Umrechnen
x ~ "2.375"
print("Zahl:", x)
b2 ~ [Link](x)
print("Fraction:", b2)
pr i nt ( )
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
# 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.
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
I
print("t5:", t5)
print("Typ:", type(tl))
Zur Erläuterung:
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
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")
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
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)
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)
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"
9°
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
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.
# Suchtexte zahlen
such ~ "ei"
anz ~ [Link](such)
print( "count: Der String", such, "kommt", anz, "mal vor")
91
4 I Datentypen
endpos ~ [Link](such)
print("rfind: Zum letzten Mal an Position", endpos)
Zur Erläuterung:
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.
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])
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 ( " ; " )
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)
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
try:
x ~ float(x)
print(x*2)
except:
print("Zeichenkette konnte nicht umgewandelt 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.
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))
96
Zeichen ketten I 4·2
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.
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
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
Zur Erläuterung:
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")
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
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)
100
Listen I 4·3
~
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.
101
4 I Datentypen
Zur Erläuterung:
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)
102
Listen I 4·3
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
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)
print("x:". x. "y:". y)
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.
lf 6: Rest in Liste
pr i nt ( )
106
Tupel I 4·4
3
[5.2000000000000002, 'hallo', 7.2999999999999998J
2.9
3
[J
5.2
~ Die Variable x bekommt den Wert 3, die Variable y den Wert 5.2 und Mehrfache
die Variable z den Wert »hallo« zugewiesen. Zuweisung
107
4 I Datentypen
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.
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.
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)
lf Ausgabe
print("Julia:". alter["Julia"J)
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 )
# Element enthalten?
i f "Julia" not in alter:
print("Julia ist nicht enthalten")
lf Anzahl El emente
print("Anzahl: ". len(alter))
110
Dictionarys I 4·5
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.
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
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
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")
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.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]
~ 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)
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)
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)
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
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]
~ 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
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.
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.
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.
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 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 ( )
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
I
Li ste nachher: [J
Liste ist leer. also False
Tupel: (5. 8. 2)
Tupel ist nicht leer. also True
Zur Erläuterung:
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))
Ergebnis: 1.75
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
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 ( )
x
print("gleiches Objekt:", x i s y)
y[1J ~
"welt"
print("gleiches Objekt:", x i s y)
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.
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
~
# 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")
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.
128
Referenz, Identität und Kopie I 4.8
I
[Link](i)
print ("gleiches Objekt:", x is y)
print ("gleicher Inhalt:", x y)
pr i nt ( )
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
x +~ 3 lf Erhoehen von x
print(x)
x -~ 9 # Vermindern von x
print(x)
131
5 I Weiterführende Programmierung
x *~ 3 # Verdreifachen von x
print(x)
x /~ 4 lf Teilen von x
print(x)
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.
Ein Beispiel:
print("Umrechnung von Celsius in Fahrenheit")
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.
print("Summe:", summe)
pr i nt ( )
# Geografiespiel
hauptstadt ~ {"Italien":"Rom", "Spanien":"Madrid",
"Portugal":"Lissabon"}
hs ~ [Link]()
134
Allgemeines I 5·1
if eingabe~~stadt:
print("Richtig")
else:
print("Falsch. richtig ist:". stadt)
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.
135
5 I Weiterführende Programmierung
Ein Programm mit Beispielen zu diesen Fällen sähe wie folgt aus:
# Funktions-Dummy
def OuadraturDesKreises():
pass
# Funktionsaufruf
OuadraturDesKreises()
pass
else:
print("Eine der Zahlen ist negativ")
print("Fall 1")
elif a ~~ 2:
print("Fall 2")
elifa<O:
pass
else:
print("Ansonsten")
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.
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
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.
Ein Beispiel:
Ir Berechnung
a 23
b 7.5
c a + b
# normale Ausgabe
print("Ergebnis:", a, "+", b,
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~" # ")
Hamburg
Be rl in
Augsburg
Stadt~>Hamburg # Stadt~>Berlin # Stadt~>Augsburg #
Zur Erläuterung:
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.
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:
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) )
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
141
5 I Weiterführende Programmierung
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
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)
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:
143
5 I Weiterführende Programmierung
Ü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
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
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.
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:
lf Verbi nden
kombi ~ zip(plz, stadt, bundesland)
lf Ausgabe
for element in kombi:
print(element)
Zur Erläuterung:
erg ~ x * x
return erg
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.
else:
return False
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.
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.
149
5 I Weiterführende Programmierung
for i in range(len(xliste))
if xliste[iJ < 10 and yliste[iJ < 10J
print(cliste)
[3. 6. 8. 9. 15J
[2. 13. 4. 8. 4J
15°
Fehler und Ausnahmen I 5.6
[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.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
152
Fehler und Ausnahmen I 5.6
I
Abbildung 5.2 Anzeige des zweiten 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
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)
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]
»>
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.
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.
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 >
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
Ergebnisse parallel In der PYTHON SHELL werden parallel dazu die ersten Ergebnisse ausgege-
ben.
»>
[DEBUG ON]
»>
10
11
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]
Auf weniger elegante Weise können Sie den Debugger schließen, indem
Sie das Kreuz oben rechts im Dialogfeld DEBUG (ONTROL anklicken.
157
5 I Weiterführende Programmierung
lf Ausgabe
print( "Der Kehrwert von". zahl. "i st". kw)
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
~
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.
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]
160
Funktionen I 5·7
5.7 Funktionen
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)
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)
lf Feh 1er
lf volumen(3. tiefe~4. laenge~5. "schwarz")
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.
lf Aufrufe
volumen(4. 6. 2. "rot")
volumen(2. 12. 7)
volumen(5. 8)
volumen(4. 7. 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.
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
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)
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.
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)
# Ausgabe nachher
print( "nachher:")
print(hv. hzk)
print(hli. hdi. hst)
166
Funktionen I 5·7
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)
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.
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( )
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
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)
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
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:
170
Eingebaute Funktionen I 5.8
Tabelle 5.1
liefert den Typ eines Objekts
verbindet Elemente aus iterierbaren Objekten
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»
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.
# 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~"")
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.
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]
173
5 I Weiterführende Programmierung
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.
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.
174
Eigene Module I 5·9
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.
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.
[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.
Wird das Programm von der Kommandozeile aus in folgender Form auf-
gerufen:
python [Link] 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
try:
x float([Link][1])
I
y float([Link][2])
z x + y
print("Ergebnis:", z)
except:
print("Parameterfehler")
übergeben werden.
import sys
summe ~ 0
try:
for i in [Link][1:]:
summe +~ float(i)
print("Ergebnis:", summe)
except:
print("Parameterfehler")
177
5 I Weiterführende Programmierung
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
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.
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.
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.
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()
Zur Erläuterung:
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.
def ausgabe(self):
print([Link], [Link], "km/hO)
# Objekte betrachten
opel . ausgabe()
vol [Link]()
i! Objektmethode
[Link](20)
Zur Erläuterung:
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.
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 ausgeben
print(opel)
print(volvo)
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
6.5 Operatormethoden
# 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")
Zur Erläuterung:
Vergleichs- Neben den Operatoren> (greater than) und ~~ (equal) können noch wei-
operatoren tere Vergleichsoperatoren zu Funktionsaufrufen führen:
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 ( )
186
Referenz, Identität und Kopie I 6.6
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.
# 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)
Zur Erläuterung:
~ 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.
~ 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
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:
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.
19°
Vererbung I 6·7
I
Listing 6.9 Datei [Link] (Hauptprogramm)
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
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
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 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
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).
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.
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.
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.
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«).
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.
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«).
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.
197
7 I Neues in Python 3
Python 2.6- Dieses Programm läuft einwandfrei unter Python 2.6, aber nicht unter
Programm Python 3.
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)
Die alte Version steht noch in der Datei [Link] zur Verfügung.
198
8 Verschiedene Module
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.
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.
# Zeit in Sekunden
print("Zeit in Sekunden:", [Link]())
199
8 I Verschiedene Module
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",
~
lf Sommerzeit
dst lt[8]
~
i f dst ~~ 1:
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
~
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).
über die Möglichkeiten von 1oca 1 ti me( ) hinaus werden folgende Infor-
mationen bereitgestellt:
201
8 I Verschiedene Module
Ein Beispielprogramm:
lf Modul time
import time
lf Aktuell e Zei t
lt ~ [Link]()
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))
202
Datum und Zeit I 8.1
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".
~
2°3
8 I Verschiedene Module
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.
# Differenz berechnen
print("Differenz:")
204
Datum und Zeit I 8.1
diff_tag ~ diff_std/24
print(diff_tag, "Tage")
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]
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.
206
Datum und Zeit I 8.1
Ir Modul time
import time
Ir Start
startzeit ~ [Link]()
print("Start:", startzeit)
Ir Ende
endzeit ~ [Link]()
print("Ende:", endzeit)
Ir Abstand
differenz ~ endzeit startzeit
print("Differenz:", differenz)
I
Listing 8.6 Datei [Link]
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
Dennoch kann die Funktion s 1eep () für viele Anwendungen sinnvoll Einsatz-
eingesetzt werden, unter anderem im Bereich von grafischen Animatio- möglichkeiten
207
8 I Verschiedene Module
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"))
208
Modul collections I 8.2
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.
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)
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)
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
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]())
Zur Erläuterung:
213
8 I Verschiedene Module
# 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)
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.
# 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
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.
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.
# 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)
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
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.
lf 1: Exakter Text
tx ~ "Haus und Maus und Laus"
print(tx)
erg ~ [Link]("Maus",tx)
print("l: ", erg)
218
Reguläre Ausdrücke I 8.4
219
8 I Verschiedene Module
0172-445633
8: ['0', '1', '2'J
9: ['7', '-', '4', '4', '5', '6', '3', '3'J
10: ['0', '7', '-', '4', '4'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"
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.
lf 1: Exakter Text
tx ~ "Haus und Maus und Laus"
print(tx)
txneu ~ [Link]("Maus","x",tx)
print("l: ", txneu)
222
Reguläre Ausdrücke I 8.4
Ir 5: Beliebiges Zeichen
txneu ~ [Link](".aus","x",tx)
print( "5: ", txneu)
223
8 I Verschiedene Module
0172-445633
8: xx7x-445633
9 : 01 x 2xxxxxxx
10: xl x2xxx5633
224
9 Dateien
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
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.
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:
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
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
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
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
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)
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
~ 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)
229
9 I Dateien
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)
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
Ein Beispielprogramm:
import sys
# Zugriffsversuch
try:
d ~ open("[Link]")
except:
print("Dateizugriff nicht erfolgreich")
[Link](O)
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)
# Summe ausgeben
print("Summe:", summe)
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.
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)
234
Sequenzielle Dateien I 9·3
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
235
9 I Dateien
"I A I B C D
~ 42 Maier 3524, 52
-
2 55Tw arner 3185
--
3 5 ~chulz 2855,2
-
~ 98 Esser 3120,66
5
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)
Ir
Ausgabe
forpinli:
print("{O:d} {l} {2:.2f}".format(p[0J. p[1J. p[2]))
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.
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
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)
[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]))
Zur Erläuterung:
~ 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.
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)
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.
240
Dateien mit festgelegter Struktur I 9.4
# Zugriffsversuch
try:
d ~ open("[Link]", "r+")
except:
print("Dateizugriff nicht erfolgreich")
[Link](O)
Der Einzelpreis des Artikels 23 im ersten Datensatz wurde von 2,95 € auf
3,15 € erhöht.
241
9 I Dateien
Zur Erläuterung:
Beim Speichern wird der Typ des Objekts mitgespeichert, sodass beim
Laden der Typ bekannt ist.
# 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)
# Datei schliessen
[Link]()
I
Listing 9.11 Datei [Link]
Zur Erläuterung:
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.
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
# 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)
# Datei schliessen
[Link]()
Zur Erläuterung:
245
9 I 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.
lf Text einlesen
gesamtertext ~ [Link]()
# Zugriff beenden
[Link]()
# Suchtext suchen
if [Link]("csv") !~ -1:
print(datei)
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.
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]")
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))
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.
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 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 " ) )
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.
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:
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.
25°
Spiel, Version mit Highscore-Datei I 9.9
~ 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
i! Modul e
import random. time. glob. pickle I
# Funktion Highscore Lesen
def hs_lesen():
# Liste wird hier erzeugt
global hs_liste
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
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]()
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 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
# Highscoreliste anzeigen
hs_anzeigen()
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.
# Initialisierung Zufallsgenerator
ra ndom. seed ( )
# Endlosschleife
while True:
# Hauptmenu. Auswahl
try:
menu ~ int(input("Bitte eingeben"
I
"(0: Ende. 1: Highscores. 2: Spielen): "))
except:
print("Falsche Eingabe")
continue
break
e 1 i f men u ~~ 1:
hs_anzei gen()
e 1 i f men u ~~ 2:
spi el ()
else:
print("Falsche Eingabe")
255
9 I Dateien
Zur Erläuterung:
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.
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.
~ Ö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.
257
10 I Internet
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.
Mo dule s
[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.
<head>
<title>Titelzeile</title>
</head>
<body>
<b>Hallo Python</b>
</body>
</html>
Listing 10.1 Datei [Link]
I
Gibt man [Link] einem Webbrowser ein, Aufruf über
so erscheint die in Abbildung 10.2 gezeigte Ansicht. Browser
Hallo Python
Das Python-Programm zum Lesen dieser Internetseite sieht wie folgt aus:
import sys. [Link]
259
10 I Internet
except:
print("Fehler")
[Link](O)
Zur Erläuterung:
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«).
import [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.
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
Dies wird, zunächst für die Ein- und Ausgabe in einem Browser, mithilfe
einer HTML-Datei und einem zugehörigen PHP-Programm realisiert.
[Werner [Vorname
'---------'
[ Daten absenden
Nachname: Maier
Vorname: Werner
</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
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
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.
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>
</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.
<?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: ")
lf sendet Daten
u ~ [Link] \
("[Link] data)
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
Erstes Programm
I
10.2.1
print( "<html)")
print("<body)")
print("<hl)Hallo Python</hl)")
print("</body)")
print( "</html)")
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
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.
Hallo Python
Abbildung 10.5 Erstes Python-HTML-Dokument
IMaie,
'-----------'
INachname
w_e_rn_e'_ _ _ _-'I Vorname
Ll
[ Daten absenden I
268
Webserver-Programmierung I 10.2
Registrierte Daten:
Nachname: Maier
Vorname : Werner
Unser bekanntes Beispiel wird nun mithilfe einer HTML-Datei und HTML-Python-
einem zugehörigen Python-Programm als CG I-Skript realisiert. Variante
<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:
#!C:\Python30\[Link]
i! Modul cgi
import cgi. cgitb
269
10 I Internet
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)")
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
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
Zur Erläuterung:
~ Statt der Variablen vn für den Vornamen wurde versehentlich die
Variable pn gewählt.
271
10 I Internet
U Mozilla Firefox
!2atei ~ea rb e it e n ansicht ~h ron i k ~ese2e ich e n E ~tr as tiilfe
IMaier I N ac hn am e 1
'-------------'
I Daten absenden
Abbildung 10.9 Formular, mit Beispieleingabe
272
Webserver-Programmierung I 10.2
U Mozilla Firefox
Qatei ~earbeiten ansicht ~hronik lesezeichen E!tras tiilfe
• C x
Registrierte Daten:
Nachnamen:
Maier
Schmitz
<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:
Ir Modul cgi
import cgi. cgitb
273
10 I Internet
# 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)")
Zur Erläuterung:
274
Webserver-Programmierung I 10.2
I A
Zusätze: Extra Oli v en (1.20 €) v
Bi tt e zw eim a l k li n geln
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
<form action~"lcgi-bin/[Link]">
<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ß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 €)<loption>
<option value~"Thunfisch">
Pizza Thunfisch (6.50 €)
<option value~"Quattro Stagioni">
Pizza Quattro Stagioni (7.50 €)<loption>
<option value~"Python" selected~"selected">
Pizza Python (8.50 €)<loption>
</select></p>
<p>Zusä ;tze;
<select name~"zu" multiple size~"2">
<option value~"Pepperoni">Extra Pepperoni (1.00 €)<loption>
<option value~"Oliven">Extra Oliven (1.20 €)<loption>
Webserver-Programmierung I 10.2
<p>Bemerkung;
<textarea name~"bm" rows~"3" cols~"25"></textarea></p>
</form>
</body>
</html>
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ü
Die Antwort des Webservers auf die obige Bestellung (siehe Abbildung
10.12) erfolgt mit einem Python CGI-Skript.
277
10 I Internet
R abatt 5%
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
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"))
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"
279
10 I Internet
lfPr eis
print("Preis (ohne Bemerkung): {O:.2f} Euro".format(preis))
print("(/body)")
print("(/html)")
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.
280
Spiel, Version für das Internet I 10.4
import webbrowser
[Link]("[Link]
print( "Ende")
Zur Erläuterung:
~ Der Standard-Webbrowser des Systems wird als unabhängiges Pro-
gramm aufgerufen. Nach dem Aufrufläuft das Python-Programm wei-
ter.
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
Kopfreclmen
1. 26 + 12 = 138
2. 26 + 12 = 138
3. 27 + 15 = 1 ~2
4. 14 + 17 = 131
5. 25 + 18 = 1 ~3
[!Fertig ]
Kopfreclmen
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.
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
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
# Initialisierung Zufallsgenerator
ra ndom. seed ( )
lf Header
print( "Content type: text/html")
pr i nt ( )
# HTML-Dokumentbeginn
print( "<html)")
print("<body)")
print("<p)<b)Kopfrechnen</b)</p)")
# 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) " + str(aufgabe+l)
+ ". </td)")
print("<td) " + str(a) + " </td)")
print("<td) + </td)")
print("<td) " + str(b) + " </td)")
print("<td) ~ </td)")
lf Tabell enende
print("</table)")
lf Absenden
print("<p)<input type~'submit' value~'Fertig')</p)")
# HTML-Dokumentende
print("</form)")
print("</body)")
print("</html)")
Zur Erläuterung:
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_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.
if i )~ 9:
break
pri nt( "</tabl e)")
288
Spiel, Version für das Internet I 10.4
Ir Hauptprogramm
# 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
# HTML-Dokumentende
print("</body)")
print("</html)")
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
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
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
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
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.
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.
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.
# 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]()
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.
# Verbindung. Cursor
connection ~ [Link]("[Link]")
cursor ~ [Link]()
lf SOL Abfrage
sql ~ "SELECT * FROM personen"
# Verbindung beenden
[Link]()
I
Listing 11.2 Datei [Link]
Zur Erläuterung:
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.
# 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 ( )
296
SQ Lite I 11.2
# Verbindung beenden
[Link]()
Listing 11.3 Datei p11 03 .py
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
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.
298
SQ Lite I 11.2
Einige Beispiele:
import sqlite3
# Verbindung. Cursor
connection ~ [Link]("[Link]")
cursor ~ [Link]()
lf SQL -Abfragen
lf Beinhaltet
sql ~ "SELECT * FROM personen WHERE name LIKE '%i%'"
[Link](sql)
for dsatz in cursor:
print(dsatz[OJ. dsatz[lJ)
pr i nt ( )
I
# Verbindung beenden
[Link]()
Listing 11.4 Datei p11 [Link]
Maier Hans
Schmitz Peter
Maier Hans
299
11 I Datenbanken
Zur Erläuterung:
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 ( )
300
SQ Lite I 11.2
[Link]()
Listing 11.5 Datei [Link]
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.
# 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 ( )
[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
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.
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
lf Nachher
ausgabe( )
[Link]()
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
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.
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]()
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]()
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
Zur Erläuterung:
308
12 Benutzeroberflächen
12.1 Einführung
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.
lfHauptfenster
main ~ [Link]()
lf Button Ende
b ~ [Link](main, text "Ende", command ende)
[Link]()
#Endlosschleife
[Link]()
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
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]()
Bei Ausführung des Programms werden drei Buttons angezeigt, die auf
unterschiedliche Art und Weise erzeugt wurden:
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
Anhand von drei Labels sollen im folgenden Programm eine Reihe von Allgemeine
allgemeinen Widget-Eigenschaften gezeigt werden, die bei allen Arten Eigenschaften
~ bg (background, Hintergrundfarbe)
~
~
fg (foreground, Vordergrundfarbe)
an cho r (Ausrichtung)
def ende():
[Link](O)
main ~ [Link]()
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]()
[Link]()
groove
ridge l
314
Widget-Typen I 12.2
Es werden insgesamt drei Objekte der Klasse Label (lbl, lb2 und lb3)
erzeugt und angezeigt.
~ 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.
~ 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
def ende():
[Link](O)
main [Link]()
lfeinzeiliges Eingabefeld
e ~ [Link](main)
[Link]()
lf Ausgabe- Label
316
Widget-Typen I 12.2
bende ~
[Link](main, text ~ "Ende",
command ~ ende)
[Link]()
[Link]()
Quadrieren I
Ergebnis:
Ende
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
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
def ende():
[Link](O)
main [Link]()
command ~ pwtest)
[Link]()
318
Widget-Typen I 12.2
[Link]()
command ~ ende)
[Link]()
[Link]()
login I
Zugang erlaubt
Ende
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
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]()
command ~ ende)
[Link]()
[Link]()
Abbildung 12.8 zeigt die Darstellung nach Aufruf des Programms und
Betätigung des Buttons ANZEIGEN.
320
Widget-Typen I 12.2
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
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]()
command ~ ende)
[Link]()
[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.
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.
def ende():
[Link](O)
I
def anzeigen():
lb["text"] ~ "Auswahl: "+ [Link]("active")
main ~ [Link]()
323
12 I Benutzeroberflächen
[Link]()
tk [J[Ql[Rl
Auswahl: Stuttgart
Ende
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.
def ende():
[Link](O)
def anzeigen():
I
lb["text"] ~ "Anzeige: "
for x in [Link]():
lb["text"] ~ lb["text"] + li .get(x) + " "
main [Link]()
selectmode~"multiple")
325
12 I Benutzeroberflächen
command ~ ende)
[Link]()
[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.
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
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]()
command~ende)
I
[Link]( )
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
[Link](side~"left". fill~"y")
[Link]()
Abbildung 12.12 und Abbildung 12.13 zeigen die Darstellung mit zwei
verschiedenen Stellungen der Scrollbar.
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
328
Widget-Typen I 12.2
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.
def ende():
[Link](O)
I
def anzeigen():
lb["text"] ~ "Aus wahl: "+ [Link]()
main ~ [Link]()
# Widget-Variable
farbe ~ [Link]()
[Link]("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 Anzei ge 1 abe 1
lb ~ [Link](main, text "Auswahl:" )
[Link]()
command ~ ende)
[Link]()
[Link]()
r. rot
r gelb
r blau
Anzeigen I
Auswahl:
Ende
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
33°
Widget-Typen I 12.2
Zur Erläuterung:
~
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.
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.
def ende():
[Link](O)
def anzeigen():
lbC"text"] ~ "Auswahl: " + [Link]()
main ~ [Link]()
# Widget-Variable
farbe ~ [Link]()
[Link]("rot")
rbl. pack()
rb2 ~ [Link](main, text~"gelb",
rb2. pack()
rb3 ~ [Link](main, text~"blau",
variable~farbe, value~"blau", command~anzeigen)
rb3. pack()
command ~ ende)
[Link]()
[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
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.
def ende():
[Link](O)
def anzeigen():
lb["text"] ~ "Zimmer" + [Link]() + " " + [Link]()
main ~ [Link]()
[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",
cbl. pack( )
cbZ ~ [Link](main, text~"Minibar",
cbZ. pack( )
command ~ ende)
[Link]()
[Link]()
Listing 12.13 Datei [Link]
tk GJ[Q][E]
Zimmer
r Dusche
r Minibar
Ende
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
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.
I
Anzeige eines Wertes, der mithilfe der Maus verändert werden kann.
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,
~
[Link]()
# Widget-Variablen
scvwert ~ [Link]()
[Link]( 0)
Ir Scale Widget
scv ~ [Link](main, width~20, length~200,
command~anzeigen, variable~scvwert)
scv. pack()
command ~ ende)
[Link]()
[Link]()
tk [J[Q)(gJ
Geschwindigkeit: 0 km/h
o 0 km/h
20
40
60
80
100
120
140
160
180
200
Ende
tk GJ[QJ[gJ
Geschwindigkeit: 110 km/h
km/h
20
40
60
80
100 110
120
140
160
180
200
Ende
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
~ 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
Event Widgets können mit vielen Events, also Mausereignissen oder Tastatur-
ereignissen (siehe nächster Abschnitt) verbunden werden.
~ 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»
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]()
[Link]()
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.
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
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).
def ende():
[Link](O)
main [Link]()
I
i!Key- Events
e ~ [Link](main)
[Link]("(p)",kev)
[Link]("(+)",kev)
[Link]("(%)",kev)
[Link]("(,)",kev)
[Link]()
[Link]()
341
12 I Benutzeroberflächen
Ir Ende- Button
bende [Link](main, text ~ "Ende",
~
command ~ ende)
[Link]()
[Link]()
Ende
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
342
Geometrische Anordnung von Widgets I 12.3
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.
343
12 I Benutzeroberflächen
def ende():
[Link](O)
main ~ [Link]()
Ir Frame 3
fr3 ~ [Link](main, width~200,
height~IOO, relief~"sunken", bd~l)
[Link](side~"bottom", expand~I, fill~"both")
[Link]()
Listing 12.17 Datei [Link]
Die Darstellung:
Button la I Button 2a
Button lb I
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).
tk [J[QJ[EJ
• l/x x hoch 2 CL
7 8 9
4 5 6
1 2 3
0 Ende
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.
Das Programm:
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"
[Link](side~"left")
[Link](side~"left")
command~cl )
bel . pa c k( s i d e~" 1e ft " )
command~anz7)
Geometrische Anordnung von Widgets I 12.3
[Link](side~"left")
command~anz8)
[Link](side~"left")
command~anz9)
[Link](side~"left")
command~anz4)
[Link](side~"left")
command~anz5)
[Link](side~"left")
command~anz6)
[Link](side~"left")
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")
command~anzp)
[Link](side~"left")
command~anzO)
[Link](side~"left")
command~ende)
349
12 I Benutzeroberflächen
[Link](side~"left")
[Link]()
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.
35°
Geometrische Anordnung von Widgets I 12.3
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)
[Link](row~l. column~l)
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
command~anz8)
[Link](row~2. column~l)
command~anz9)
[Link](row~2. column~2)
lf Row 3
b4 ~ [Link](main. text~"4". width~7.
command~anz4)
[Link](row~3. column~O)
command~anz5)
[Link](row~3. column~l)
command~anz6)
[Link](row~3. column~2)
lf Row 4
bl ~ [Link](main. text~"l". width~7.
command~anzl)
[Link](row~4. column~O)
command~anz2)
[Link](row~4. column~l)
command~anz3)
[Link](row~4. column~2)
lf Row 5
bp ~ [Link](main. text~".". width~7.
command~anzp)
[Link](row~5. column~O)
command~anzO)
[Link](row~5. column~l)
command~ende)
[Link](row~5. column~2)
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.
def ende():
[Link](O)
main ~ [Link]()
bl ~ [Link](main, text~"bl",
command~ende)
353
12 I Benutzeroberflächen
b2 ~ [Link](main. text~"b2".
eommand~ende)
b3 ~ [Link](main. text~"b3".
eommand~ende)
b4 ~ [Link](main. text~"b4".
eommand~ende)
[Link]()
tk GJ(QJ~
~
~
354
Geometrische Anordnung von Widgets I 12.3
~ 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.
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)
b3 ~ [Link](main. text~"b3".
command~ende)
b4 ~ [Link](main. text~"b4".
command~ende)
355
12 I Benutzeroberflächen
b5 ~ [Link](main. text~"b5".
command~ende)
[Link]()
Listing 12.21 Datei [Link]
b5
Zur Erläuterung:
Das folgende Beispiel soll dies anhand eines Labels verdeutlichen, das
mithilfe von zwei Buttons an zwei verschiedene Positionen bewegt wer-
den kann.
def ende():
[Link](O)
I
[Link](relx~O, rely~O, anchor~"nw")
main ~ [Link]()
lf Bewegtes La be 1
lb ~ [Link](main, text~"Test",
relief~"sunken", bd~l)
357
12 I Benutzeroberflächen
command~ende)
[Link]()
Das Fenster sieht nach dem Start aus wie in Abbildung 12.28 dargestellt.
Test
Nach der Betätigung des Buttons GANZ RECHTS sieht das Fenster folgen-
dermaßen aus:
tk GJ[Q]~
Zur Erläuterung:
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
359
12 I Benutzeroberflächen
main ~ [Link]()
relief~"sunken", bd~l)
[Link](side~"top")
[Link](side~"left")
[Link](side~"left")
# Bewegtes Label
lb ~ [Link](frl, text~"Test",
rel ief~"sunken", bd~l)
[Link](x~O, y~O, anchor~"nw")
[Link](row~I, column~O)
Geometrische Anordnung von Widgets I 12.3
[Link](row~l, column~2)
[Link](row~O, column~l)
[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]()
I
Listing 12.23 Datei [Link]
tk GJ(Q]~
Test
nach links
Ende
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
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.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)
main ~ [Link]()
bg~"#FFFFFF", bd~10)
[Link]()
mFile.add_command(label~"Laden")
mFile.add_command(label~"Speichern")
mFile.add_separator()
mFile.add_command(label~"Beenden", command~ende)
command~randwechsel )
[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
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
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
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.
~ 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
Außerdem muss die Position des zugehörigen Widgets innerhalb des Widget-Position
Hauptfensters berücksichtigt werden. Sie müssen das Widget mit ermitteln
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)
main ~ [Link]()
[Link]("(Button 3)".lbpop)
lbx ~ 60
1 by ~ 30
[Link](x~lbx. y~lby. anchor~"nw")
lf Ende
bende ~ [Link](main. text~"Ende".
command~ende)
[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
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
~ 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.
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
def ende():
[Link](O)
I
lbanz["text"] "Nein"
373
12 Ben utzeroberflächen
icon~[Link],
title~"Beenden/Wiederholen/Ignorieren",
antwort ~ [Link]()
if antwort ~~ "abort":
lbanz["text"] ~ "Beenden"
elif antwort ~~ "retry":
lbanz["text"] "Wiederholen"
else:
1 banz[ "text"] "Ignorieren"
main ~ [Link]()
374
Menüs und MessageBoxes I 12.4
i! Ende- Button
bende ~ [Link](main,
text ~ "Ende", command~ende)
[Link]()
[Link]()
Info
Eine Info-Box
[E]
I
OK
Warnung (gJ
.n Eine Warnungs-Box
OK
375
12 Benutzeroberflächen
Fehler lRl
Eine Fehler -Bo x
OK
Ja/Nein lRl
Eine Ja/Nein-Box
Ja Nein
OkJAbbrechen lRl
Eine Ok/Abbrechen-Box
OK Abbrechen
Wiederholen/Abbrechen ~
~ Eine Wiederholen/Abbrechen-Bo x
I Wiederholen I Abbrechen
BeendenlWiederholenlignorieren lRl
Beenden, Wiederholen oder Ignorieren
376
Menüs und MessageBoxes I 12.4
Zur Erläuterung:
I
Rückgabewert ist eine Zeichenkette, die die Bezeichnung des
gedrückten Buttons beinhaltet (hier: abort, retry oder ignore).
377
13 Lösungen
ü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:
übung U0301:
# Umrechnungsfaktor
inch ~ 2.54
379
13 I Lösungen
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
# 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")
Ü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
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
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
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
395
Index
397
Index
Zufallszahl
Generator 36
Generator initialisieren 37
liefern 37
Zuweisung 20, 32
kombinierte Operatoren 131
mehrfache 106
399