Sie sind auf Seite 1von 529

https://www. Python-lernen.

de

Das E-Book zur Website

Python lernen
für Einsteiger & Fortgeschrittene
Autor: Axel Pratzner
Stand: Februar 2021
Über den Autor:
Axel Pratzner studierte an der
Universität Tübingen
Erwachsenenbildung/Weiterbildung.

Neben der Tätigkeit als Autor gebe


ich seit 1998 Kurse in
verschiedenen Einrichtungen und
betreue neben meiner Website
www.Python-lernen.de auch das
www.HTML-Seminar.de, meinen
www.PHP-Kurs.com sowohl den
www.Javascript-Kurs.de und
www.Foto-Kurs.com

Ich denke, dass die sprechende URLs aussagekräftig genug sind, um zu sehen, was
ich so mache :).

Das E-Book wird laufend weiterentwickelt.

Bei längerem Programmiercode ist Copy & Paste nicht sinnvoll, da Einrückungen
verschwinden können! Diese sind in Python sehr wichtig. Daher ist beim E-Book links
oben immer die URL der Website, von der der Programmcode kopiert werden kann!

Hier kann auch nachgeschlagen werden, falls Code nicht vollständig sichtbar sein
sollte.

Über Rückmeldungen und Fehlermeldungen freue ich mich immer.

Danke für Ihre Unterstützung und viel Freude beim Lernen vom Python.

© Copyright 2021 Axel Pratzner - Urheberrechtshinweis

Alle Inhalte dieses E-Books, insbesondere Texte, Fotografien und Grafiken, sind urheberrechtlich
geschützt. Das Urheberrecht liegt, soweit nicht ausdrücklich anders gekennzeichnet, bei mir (Axel
Pratzner).
Inhaltsverzeichnis

1 Startseite
3 Python installieren
5 Python IDLE - Lernumgebung
8 Python Befehle ausführen
10 Programm ausführen + Command Line zum debuggen
12 Hilfefunktionen
16 Online-Editor zum schnellen Lernen
18 Text Editor Atom
21 Atom und Python
24 Python Grundlagen
26 Ausgabebefehl print()
28 Variablen/Strings in Python
31 Funktionen und Methoden für Strings
34 Leerzeichen am Anfang entfernen lstrip()
36 umschließende Leerzeichen entfernen strip()
38 Leerzeichen rechts entfernen rstrip()
40 Linksbündig ausgeben: ljust()
42 Zentrierte Ausgabe .center()
44 Rechtsbündig ausgeben: rjust()
46 Nullen am Anfang .zfill()
48 Umwandeln in Großschreibung upper()
49 Umwandeln in Kleinschreibung lower()
50 aggressive Kleinschreibung .casefold()
52 Erster Buchstaben in Großschreibung capitalize()
54 Anfangsbuchstaben in Großschreibung title()
55 Groß- u. Kleinschreibung vertauschen: swapcase()
56 Zeichen ersetzen .replace()
58 Vorkommen zählen .count()
60 Finden erstes Vorkommen .find()
61 String auf Bedingungen testen
63 Strings Aufteilen .split()
65 Endet-mit-Methode .endswith()
67 Beginnt-mit-Methode .startswith()
69 Tabs in Leerzeichen .expandtabs()
72 in Einzelteile zerlegen .partition()
74 Zusammenfügen join()
76 Operatoren für Strings
78 Rechnen mit Zahlen
81 Listen · viele Inhalte speichern
84 mit Listen arbeiten: Methoden
90 Übersicht aller Methoden des Datentyps Liste
91 Variablen sind Listen?
93 Datentyp Dictionary
97 Übersicht Methoden von dictionary
98 Tupel (Werte konstant speichern)
100 Übersicht Methoden von Tuple
102 Mengen managen set u. frozenset
107 Übersicht Methoden von set
108 input · Nutzerangaben anfordern
110 Kommentare nutzen
112 ausführbares Python-Programm erstellen
115 if-Bedingung
119 Zufallszahlen über random
122 Übung: Schmeichelprogramm
125 while-Schleife in Python
127 Übung: Zahlenraten-Spiel
130 for-Schleife in Python
133 Übung: Chatbot
139 range() · Listen erstellen
141 Übung: Lotto Simulator
143 Schleifenablauf beeinflussen: break & continue
145 Übung: Galgenmännchen
152 Funktionen in Python
156 Funktionen mit variabler Parameteranzahl
159 Rückgabewert bei Funktionen
164 eingebaute Funktionen
171 Module nutzen
173 Standardbibliothek/Module
175 Modul os: Betriebssystemfunktionalität
178 Modul datetime
185 Modul time
188 Modul calendar
190 tkinter - GUI erstellen
191 Tkinter importieren
192 Überblick über alle Steuerelemente
193 Label-Widget
195 Farben in tkinter
196 Schriftart und Schriftgröße
197 grid: Platzieren im Fenster
199 entry: 1-zeiliges Eingabefeld
200 Button/Schaltfläche erstellen
204 Cursorform ändern
205 Höhe und Breite setzen
206 Radiobutton
208 Checkbutton/Checkbox
211 LabelFrame · Gruppieren
213 Listbox: Inhalt zur Auswahl
215 Webbrowser über Python nutzen
217 URLLIB · Internetseiten auslesen
222 Bibliothek requests
227 Selenium Browser fernsteuern
230 matplotlib - 2D Diagramme
236 Natural Language Toolkit (NLTK)
239 Wordcloud mit Python erstellen
245 Tic-Tac-Toe Spiele-Tutorial
246 Spielfeld erstellen
247 Spielzug durch Spieler
249 Hauptroutine des Spiels erstellen
251 Spielfigur setzen
254 Spielende durch Gewinnen oder Unentschieden
258 Spielzugkontrolle
261 Dumme KI integrieren
262 Turtle-Modul von Python
266 Hauptprogramm __main__
268 Dateien auslesen
271 in Dateien schreiben
273 CSV Datei einlesen
276 Objektorientierte Programmierung Grundlagen (OOP)
280 Klassen in Python
282 Initialisieren der Klasse
285 Lösung Klasse erstellen
287 Instanz einer Klasse anlegen
290 Methoden in Klassen
297 Lösung Methoden in Klasse einbauen
300 Vererbung und Python
307 Attribute und Methoden in Klassen überschreiben
312 Lösung Aufgabe Vererbung
317 Vererbung weiterdenken
321 Variablen im Unterschied zu Eigenschaften in Klassen
325 Eigenschaften vor Zugriff absichern
334 Klassen auslagern
339 Python und Datenbanken
341 SQLite: grundsätzliche Vorgehensweise
345 Daten speichern: INSERT INTO
348 Viele Datensatz in Datenbank speichern
350 Datenbank auslesen
352 Datensätze ändern: UPDATE
354 Löschen: DELETE FROM
356 SQL Grundlagen lernen
361 SQLite3 Shell
364 CSV-Datei in SQlite3 Datenbank importieren
367 Pygame Einführung
376 Pygame installieren macOS
378 Formen zeichnen
383 Spiel Pong: Bewegung des Balls
391 Steuerung durch Spieler: Tastatur
401 Kollisions-Kontrolle · Aktion bei Schlägerberührung
407 Soundeffekte für unser Spiel und Hintergrundmusik
410 Koordinatensystem für Computerspiele
417 Spiel Breakout programmieren
420 Zeichnen der Mauersteine
423 Spielfeld mit Mauersteinen nach Vorgabe füllen
426 Breakout-Ball im Spiel zeichnen und bewegen
432 Kollision zwischen Ball und Mauerstein
438 Kontrolle: Spielende durch gewinnen
443 Spielerfigur (Schläger) einbauen und bewegen
448 Kollisionskontrolle Ball und Schläger
450 Kontrolle: Spielende durch verlieren
456 Grundgerüst für Pygame
462 Bilder und Grafiken anzeigen
468 Grafiken rotieren
478 Grafiken skalieren
484 Spielerfigur animieren
491 Space Invaders war gestern
494 eigene Spielerfigur einbauen
497 Spielerfigur steuern
501 Bewegung der Spielerfigur begrenzen
502 Gegner einbauen
506 Gegner automatisch bewegen
507 Gegner abschießen
510 Berechnung, wann Geschoss trifft
515 viele Gegner fürs Spiel
519 Kontrolle: Spiel gewonnen
520 aktuelle Punktestand anzeigen
521 Hintergrundmusik und Sounds einbauen
522 Raspberry Pi · Python Interpreter
523 Impressum
© https://www.python-lernen.de/ Seite 1

Python Kurs: Mit Python programmieren lernen für


Anfänger und Fortgeschrittene
Dieses Python Tutorial entsteht im Rahmen von Uni-Kursen und kann hier kostenlos genutzt
werden. Python ist eine für Anfänger und Einsteiger sehr gut geeignete Programmiersprache,
die später auch den Fortgeschrittenen und Profis alles bietet, was man sich beim
Programmieren wünscht. Der Kurs ist eine Einführung und bietet einen guten Einstieg. Es wird
aktuelles Wissen vermittelt - daher schreiben wir unseren Python-Code mit der aktuellen
Python-Version 3.

einfach Python lernen über das Programmieren von Spielen


Damit programmieren lernen mit Python noch mehr Spaß macht, werden wir im Kurs anhand
verschiedener Spiele die Anwendung von Python kennen lernen und unser Wissen als
Programmierer aufbauen. Die Grundlagen werden direkt in bekannte Spiele umgesetzt wie:

Galgenmännchen

Lotto-Simulator

einen Chatbot

Tic-Tac-Toe Spiel

Pong (damit noch mehr Bewegung ins Spiel kommt)

Breakout

Bee Invaders (cooler Space Invaders Clone mit Honig)

und vieles mehr

Dazu werden im Kurs Schritt für Schritt die Vorgehensweise beim Lernen von Programmieren
gezeigt. Es wird anhand von Beispiel-Code alle Befehle erklärt, wie man mit diesem Wissen
Programme schreibt. Beispielsweise wie aus einem Sprite-Sheet mit den einzelnen
Bewegungsstadien eine animierte Spielerfigur wird – in diesem Fall eine Honigbiene.

Und das fertige Ergebnis (sieht dann umgesetzt in Python + Pygame noch besser aus):

Biene mit animierter Bewegung im Flug

Python ist Zukunftsorientiert


Python hat sich zu einer sehr beliebten Programmiersprache entwickelt. In immer weiteren
Softwareprogrammen und Hardware kann man Python einsetzen – was Python noch
© https://www.python-lernen.de/ Seite 2

interessanter macht. Im Kurs gibt es auch einen Abstecher zum Einplatinencomputer


Raspberry Pi (Pi steht für Python-Interpreter).

Das Programmieren in Python kann in folgenden Formen gemacht werden:

Funktionale Programmierung

Objektorientierte Programmierung (OOP)

wie auch Aspektorientierte Programmierung (AOP)

Python ist eine gute Programmiersprache auch für Einsteiger, die bisher noch nicht mit
Programmieren und Programmiersprachen in Berührung gekommen sind.

Bei Python spricht man von einer Skriptsprache – ein erstelltes Programm wird interpretiert,
wenn es gestartet wird. Daher bekommt man erst dann Fehlermeldungen, wenn Fehler im
Python-Programm sind. Dazu aber später mehr. Die Sprache ist sehr einfach zu lernen und
durch die (erzwungene) saubere Erstellung von Code punktet die Sprache: Sie ist gut lesbar
und hat einen übersichtlichen kurzen Code. Daher ist Python sehr einfach zu lernen und ideal
als Einführung in eine Programmiersprache.

Viel Spaß in diesem Python Kurs.


© https://www.python-lernen.de/python-installieren.htm Seite 3

Python schon installiert?


Python ist bereits in vielen Betriebssystemen installiert. Das kann sehr einfach kontrolliert
werden, indem wir Python seine Version ausgeben lassen. Ist Python nicht installiert, kommt
eine Fehlermeldung oder wir kennen danach die aktuelle Version.

Unter Windows benötigen wir die Befehlszeile, die wir über die Suche und cmd.exe ( win + x -
Eingabeaufforderung) direkt starten können. Wir geben beim Cursor dann ein:

python - - version

Beim Mac und Linux öffnen wird die Kommandozeile ( CMD + Leertaste ) das Terminal
(terminal.app) und tippe dort ein:

Python --Version

bzw.

Python3 --Version

Auf dem Mac ist es durchaus möglich 2 verschiedene Versionen von Python installiert zu
haben. Normalerweise wird die alte Python 2.7 Version automatisch installiert sein. Sinnvoll
zum Lernen sind neue Versionen von Python >= 3.7

Python installieren
Die Installation ist sehr einfach – unter der Website https://www.python.org/ erhält man
Downloads für alle üblichen Betriebssystemen wie Windows, Linux/Unix, macOS und weitere.

Im ersten Schritt laden wir den Installer für das eigene Betriebssystem herunter und lassen
diesen dann Python installieren.

Python unter Windows installieren

Beim Installer unter Windows auf jeden Fall "Add Python 3.7 to PATH" anklicken!

Hat man vergessen, beim Installer die Option zum automatischen Eintrag des Pfads unter
Windows anzuklicken, dann ist Handarbeit angesagt. Unter Windows muss der Pfad für die
Umgebungsvariablen eingestellt werden: Diesse finden man unter: Systemeigenschaften - >
© https://www.python-lernen.de/python-installieren.htm Seite 4

Reiter Erweitert -> Button Umgebungsvariablen -> Systemvariablen und dort Path auswählen
und Bearbeiten anklicken. Falls vorhanden, sollten bestehende Einträge erhalten werden! Man
erweitert den Pfad unter Windows mit einem Semikolon und den Pfad auf der eigenen
Festplatte, z.B. (;C:Python34)

Über eine Kommandozeile kann in Windows getestet werden, ob alles funktioniert. Über
Windowssuche "cmd" eingeben und in der "schwarzen Box" dann einfach python eingeben.

Kommandozeile unter Windows mit gestartetem Python

Hier sieht man die Version von Python und dessen Datum.

Zum Testen kann man jetzt direkt eingeben:

print('Hallo Welt')

Die Schreibweisen des Codes in alten Python-Versionen sieht anders aus, daher immer mit der
aktuellsten Version arbeiten.

Jetzt können wir mit dem Lernen von Python beginnen.


© https://www.python-lernen.de/python-idle.htm Seite 5

Python IDLE – Integrated Development and Learning


Environment
Die Abkürzung IDLE steht für „Integrated Development and Learning Environment“ – diese
Entwicklungsumgebung ist bei einer normalen Python-Installation mit an Bord und muss nicht
extra installiert werden. Viele Programmierer kennen IDLE als eine integrierte
Entwicklungsumgebung. Bei Python wurde Wert daraufgelegt, dass es zum Lernen der Sprache
der Einsteiger so einfach wie möglich tut. Daher wurde bei der Entwicklung des Tools darauf
geachtet, dass es den Einsteiger unterstützt und diesen nicht durch überfrachtete
Möglichkeiten erschlägt.

Vorteile von IDLE:

Einfärben von Codeeingaben im Python-Shell-Fenster

direkte Ausgaben und Fehlermeldungen

plattformübergreifend verfügbar (Windows, Mac OS X und Unix)

Mehrere Fenster gleichzeitig

Debugging

Starten der IDLE


Die interaktive Shell wird je nach Betriebssystem gestartet:

Windows: auch Startmenü klicken und IDLE eingeben – auswählen von IDLE (Python GUI)

macOS: Finder öffnen und auf Programm klicken. Dort unter Python auf das IDLE-Symbol
klicken. Oder über Spotlight-Suche ( CMD + Leertaste ) und IDLE eintragen und die IDLE-App
auswählen

Linux: Terminal-Fenster öffnen und idle3 eingeben

Nach dem Start erscheint ein Fenster mit der Angabe der Python-Version:

IDLE von Python gestartet

Jetzt können direkt nach der Eingabeaufforderung (sprich den >>>) Befehle eingegeben
werden.

Autovervollständigung über TAB -Taste


Innerhalb der interaktiven Shell (also IDLE) kann man eine Autovervollständigung nutzen. Nach
dem Tippen der ersten 2-3 Buchstaben einfach einmal die TAB -Taste drücken und man
bekommt Vorschläge zur Auswahl bzw. wenn es eindeutig ist, den kompletten Python-Befehl
© https://www.python-lernen.de/python-idle.htm Seite 6

ausgeschrieben. Sehr praktisch um Schreibfehler zu vermeiden!

Weitere Tastenkombinationen innerhalb von IDLE


Um nochmal die letzte Codeanweisung angezeigt zu bekommen einfach die
Tastenkombination Alt + p drücken.

Über Alt + n bekommt man die nächsten Codeanweisung angezeigt, sofern vorhanden.

Programm mit IDLE Dateieditor schreiben und speichern


IDLE verfügt über einen Dateieditor. Diesen Dateieditor kann gestartet werden, indem man im
Menü oben auf den Reiter „File“ und dort auf „New File“ klickt.

Wir erhalten ein weiteres leeres Fenster. In dieses können wir unser Python-Programm
schreiben.

Zum Testen geben wir ein:

print ("Hallo Welt")


print ("!")

Hier wird bereits der Vorteil sichtbar. Wir erhalten automatisch eine Code-Highlighting (eine
Einfärbung des Quellcodes).

Jetzt speichern mit „File“ -> „Save as..“.

Zum direkten Ausführen können wir entweder

im Menü „Run“ den Unterpunkt „Run Module“ auswählen

oder einfach F5 drücken.

Das Programm wird nun direkt in der IDLE Shell ausgeführt:

IDLE Dateieditor und IDLE SHELL

So ist ein schnelles Lernen möglich.


© https://www.python-lernen.de/python-idle.htm Seite 7

Im folgenden Kapitel wird eine weitere Variante beschrieben, wie ein erstelltes Python-
Programm direkt über die Befehlszeile gestartet wird bzw. die Python Command Line genutzt
werden kann.
© https://www.python-lernen.de/python-befehle-ausfuehren.htm Seite 8

Python Befehle ausführen


Um mit Python Befehle ausführen zu können, haben wir 2 Möglichkeiten:

wir schreiben ein Python-Programm in einem Texteditor und rufen dieses dann auf oder

wir tippen unsere Python-Befehle direkt in die „Python Command Line“ und die Befehle werden
sofort und direkt ausgeführt.

Beides hat seine Berechtigung! Schauen wir uns beide Vorgehensweisen an.

Python Command Line


Um schnell einen Befehl zu testen, können wir Python Command Line nutzen. Diese rufen wir
über die Befehlszeile unseres Betriebssystems (egal ob Windows, Mac oder Linux) direkt auf.

Dazu entsprechend dem Betriebssystem:

bei Windows „cmd.exe“ über das Suchfeld eingeben und somit erhalten wir die Befehlszeile

beim Mac öffnen wir die Kommandozeile über CMD + Leertaste und dort das Terminal über
„terminal.app“

Haben wir die Befehlszeile des Betriebssystems, starten wir Python über python (unter
Umständen ist bei der Installation von 2 verschiedenen Versionen beim Mac als Start
python3 notwendig.

Wir erhalten als Rückmeldung folgende Ausgabe:

Axels-MBP:~ axelpratzner$ python3


Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 16:52:21)
[Clang 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>

Nach den 3 „>>>“ geben wir unseren Python-Befehl ein und dieser wird direkt ausgeführt,
nachdem wir diesen mit Return bestätigen.

Axels-MBP:~ axelpratzner$ python3


Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 16:52:21)
[Clang 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> print("Hallo Welt")
Hallo Welt
>>>

Danach können wir den nächsten Befehl eingeben. Werden Variablen definiert, liegen diese zur
weiteren Nutzung vor, solange nicht diese Instanz über exit() geschlossen wird.

Unsere bisherigen Befehle sind so natürlich nicht gespeichert und wenn wir diese wieder
ausführen lassen wollten, dann müssten wir alle Befehle in der entsprechenden Reihenfolge
wieder tippen. Diese Vorgehensweise ist also ungeschickt für sich wiederholende Aufgaben.
Da lohnt es sich dann immer über ein Python-Programm zu arbeiten, da in einer Datei
gespeichert ist, was wir im nächsten Schritt machen.

Python Programm schreiben und speichern


© https://www.python-lernen.de/python-befehle-ausfuehren.htm Seite 9

Wir wollen unser Python-Programm erstens öfters ausführen lassen und zweitens auch
ergänzen und erweitern. Dann hilft die „Python Command Line“ nicht weiter. Wir nutzen einen
Texteditor unserer Wahl und speichern unser Python-Programm unter einem Dateinamen mit
der Endung „.py“ ab.

Wir erstellen also eine Textdatei mit dem Dateinamen „hallo.py“ und folgendem Inhalt:

print("Hallo Welt")

Um unser Python-Programm nun ausführen zu lassen, rufen wir dieses über die
Kommandozeile auf. Wie man die Kommandozeile von seinem Betriebssystem erhält, ist oben
beschrieben.

Gehen Sie in der Befehlszeile in das Verzeichnis, in dem unser Python-Programm gespeichert
wurde. Dazu wechseln sie die Verzeichnisse mit „cd“, was für „change directory“ steht. Unter
Windows z.B. „cd c:/python-kurs.de/hallo.py“

Jetzt starten wir Python mit Leerzeichen und dem Dateinamen danach:

python hallo.py

Alternativ kann auch beim Programmaufruf das Verzeichnis mitgegeben werden:

python c:/python-lernen.de/hallo.py

Das Programm wird ausgeführt und wir erhalten die entsprechenden Ausgaben.

Viel Spaß beim Testen.


© https://www.python-lernen.de/trick-programm-ausfuehren-und-in-konsole-debuggen.htm Seite 10

Tipp: Python Programm ausführen und danach direkt in


Command Line debuggen
Für dein Einsteiger hört sich folgendes Thema ein wenig abgefahren an. Aber es hilft später
immens weiter, wenn man schnell und einfach einmal ein Programm debuggen möchte.

Wir haben die 2 Möglichkeiten kennen gelernt, wie wir Python-Code ausführen lassen
können:

Python Command Line: Befehle in Eingabe-Konsole eintippen und direkt ausführen

Programm mit Editor schreiben und ausführen lassen

Jetzt wäre eine Kombination aus beiden gut – gesagt getan und einfach möglich.

Das Python-Programm ausführen mit anschließender Python Command Line und Zugriff auf
alle Variablen und Möglichkeiten des ausgeführten Programms. Und das Ganze geht mit
einem kleinen Kniff.

Für Anfänger einfach für den Hinterkopf, damit man es später einsetzen kann bzw.
nachschlagen.

Wir haben ein kleines Python-Programm, dass „Hallo Welt“ ausgibt (was auch sonst) und eine
Variable speichert.

print("Hallo Welt")
nachricht = "alles in Ordnung"

Dieses Programm speichern wir mit dem Namen „hallowelt.py“ und starten es in der
Kommandozeile über „python hallowelt.py“.

Als Ausgabe erhalten wir:

Hallo Welt

Wenn wir aber jetzt nachsehen wollen, was in der Variablen mit dem Namen nachricht
steckt, haben wir anscheinend Pech. Theoretisch können wir unser Programm erweitern mit
dem typischen print() , speichern, ausführen lassen und später wieder diese Zeile
löschen. Diese war ja nur zum Debuggen da. ODER …

Oder wir kennen den Trick, beides zu bekommen. Die Ausführung des Programms und nach
Beendigung des Programms die Kommandozeile von Python mit den typischen 3
Größerzeichen:

python -i programmname.py – Ausführung + Python


Kommandozeile
Der Trick liegt im Aufruf. Wenn wir zwischen python und dem Dateinamen noch ein -i
einbauen, dann haben wir diesen Effekt.

Axels-MacBook-Pro:Python-lernen.de ich$ python -i hallowelt.py


Hallo Welt
>>>
© https://www.python-lernen.de/trick-programm-ausfuehren-und-in-konsole-debuggen.htm Seite 11

Das Programm wurde nun ausgeführt. Nachdem das Programm alles abgearbeitet hat (eine
Ausgabe von „Hallo Welt“ ist ja nicht viel), landen wir direkt in der Python Kommando Zeile
und können diese wie gewohnt nutzen.

Jetzt können wir den Inhalt der Variablen mit dem Namen nachricht einfach direkt
abfragen. Einfach nach dem Prompt ">>>" den gewünschten Befehl tippen bzw. in diesem Fall
den gewünschten Variablennamen um den Inhalt der Variablen zu erhalten:

Axels-MacBook-Pro:Python-lernen.de ich$ python -i hallowelt.py


Hallo Welt
>>> nachricht
'alles in Ordnung'
>>>

Hätten wir eine Funktion im Programm integriert, könnten wir auch diese nutzen.

Wir bauen uns eine Funktion ein, um Zahlen zu quadrieren (sprich eine Zahl wird mit sich
selber multipliziert).

print("Hallo Welt")
nachricht = "alles in Ordnung"

def quadrieren(zahl):
print(zahl*zahl)

Nachdem wir das Programm neu gestartet haben, können wir diese Funktion nun in unserer
Kommandozeile nutzen:

Axels-MacBook-Pro:Python-lernen.de ich$ python -i hallowelt.py


Hallo Welt
>>> quadrieren(4)
16
>>> quadrieren(5)
25

Beenden von Python Kommandozeile


Zum Beenden unsere Python Kommandozeile einfach exit() eingeben.
© https://www.python-lernen.de/python-help.htm Seite 12

Hilfe-Funktionen in Python
Es gibt mehrere Möglichkeiten sich in Python Hilfen ausgeben zu lassen.

Windows Hilfe Programm „Python Manuals“

Online als HTML-Dokumentation (mit Suche)

Offline (die gleiche HTML-Dokumentation)

über IDLE

in der Python-Konsole (Python Shell)

Windows Hilfe Programm „Python Manuals“


Bei der Installation unter Windows wird auch das Windows-Hilfeprogramm „Python Manuals“
mit installiert. Dieses kann jederzeit aufgerufen werden und bequem durchsucht werden.

Windows Hilfe Programm Python Manuals

Hilfe Online als HTML-Dokumentation (mit Suche)


Direkt Online kann man sich über die URL https://docs.python.org/3/library/ die komplette
aktuelle Hilfe anzeigen lassen. Diese ist mit einer Suchfunktion ausgestattet.
© https://www.python-lernen.de/python-help.htm Seite 13

Online-Hilfe – Python Dokumentation

Es gibt eine Auswahl der verschiedenen Python-Versionen und als Sprache Englisch,
Französisch, Japanisch, Koreanisch, Chinesisch.

Offline (die gleiche HTML-Dokumentation)


Die HTML-Dokumentation wird der Installation mitgeliefert. Diese findet sich in einem
Unterverzeichnis.

Beim Mac:
© https://www.python-lernen.de/python-help.htm Seite 14

file:///Library/Frameworks/Python.framework/
Versions/3.7/Resources/English.lproj/Documentation/index.html

Effektiv ist diese identisch mit der Online-Dokumentation – allerdings wird man Online immer
den aktuellen Stand bekommen.

Hilfe über IDLE aufrufen


Über die Menüzeile von IDLE kann direkt die Python Dokumentation aufgerufen werden. Hier
bekommen wir die HTML-Dokumentation angezeigt, die bei der Installation mitgeliefert wurde.
Gibt es bereits eine neuere Python-Version, ist die Online-Dokumentation empfehlenswert (wie
auch die neue Version zu installieren).

Hilfe über IDLE aufrufen

In diesem Screenshot sieht man zusätzlich das Ausführen der Hilfe über die Konsole mit
help() .

Hilfe über die Python-Konsole (Python Shell)


Die einfachste Möglichkeit besteht wie in der Begrüßung von Python angekündigt über
help() .

>>> help()

Welcome to Python 3.7's help utility!

If this is your first time using Python, you should definitely check out the tutorial on the Internet
at https://docs.python.org/3.7/tutorial/. Enter the name of any module, keyword, or topic to get
help on writing Python programs and using Python modules. To quit this help utility and return
to the interpreter, just type "quit".

To get a list of available modules, keywords, symbols, or topics, type "modules", "keywords",
"symbols", or "topics". Each module also comes with a one-line summary of what it does; to list
the modules whose name or summary contain a given string such as "spam", type "modules
spam".

Module von Python


Zu den Modulen gibt es später im Kurs entsprechenden Tutorials.

Über die Python-Konsole können wir uns über die bereits standardmäßig in Python verfügbaren
Module informieren. Dazu einfach nach dem Prompt help> dann module eingeben.

help> modules
Please wait a moment while I gather a list of all available modules...
© https://www.python-lernen.de/python-help.htm Seite 15

__future__ _tkinter glob sched


_abc _tracemalloc grp secrets
_ast _uuid gzip select
_asyncio _warnings hallowelt selectors
_bisect _weakref hashlib setuptools
_blake2 _weakrefset heapq shelve
_bootlocale _xxtestfuzz hmac shlex
_bz2 abc html shutil
_codecs aifc http signal
_codecs_cn antigravity idlelib site
_codecs_hk argparse imaplib smtpd
_codecs_iso2022 array imghdr smtplib
_codecs_jp ast imp sndhdr
_codecs_kr asynchat importlib socket
_codecs_tw asyncio inspect socketserver
_collections asyncore io sqlite3
_collections_abc atexit ipaddress sre_compile
_compat_pickle audioop itertools sre_constants
_compression base64 json sre_parse
_contextvars bdb keyword ssl
_crypt binascii lib2to3 stat
_csv binhex linecache statistics
_ctypes bisect locale string
_ctypes_test builtins logging stringprep
_curses bz2 lzma struct
_curses_panel cProfile macpath subprocess
_datetime calendar mailbox sunau
_dbm cgi mailcap symbol
_decimal cgitb marshal symtable
_dummy_thread chunk math sys
_elementtree cmath mimetypes sysconfig
_functools cmd mmap syslog
_hashlib code modulefinder tabnanny
_heapq codecs multiprocessing tarfile
_imp codeop netrc telnetlib
_io collections nis tempfile
_json colorsys nntplib termios
_locale compileall ntpath test
_lsprof concurrent nturl2path textwrap
_lzma configparser numbers this
_markupbase contextlib opcode threading
_md5 contextvars operator time
_multibytecodec copy optparse timeit
_multiprocessing copyreg os tkinter
_opcode crypt parser token
_operator csv pathlib tokenize
_osx_support ctypes pdb trace
_pickle curses pickle traceback
_posixsubprocess dataclasses pickletools tracemalloc
_py_abc datetime pip tty
_pydecimal dbm pipes turtle
_pyio decimal pkg_resources turtledemo
_queue difflib pkgutil types
_random dis platform typing
_scproxy distutils plistlib unicodedata
_sha1 doctest poplib unittest
_sha256 dummy_threading posix urllib
_sha3 easy_install posixpath uu
_sha512 email pprint uuid
_signal encodings profile venv
_sitebuiltins ensurepip pstats warnings
_socket enum pty wave
_sqlite3 errno pwd weakref
_sre faulthandler py_compile webbrowser
_ssl fcntl pyclbr wsgiref
_stat filecmp pydoc xdrlib
_string fileinput pydoc_data xml
_strptime fnmatch pyexpat xmlrpc
_struct formatter queue xxlimited
_symtable fractions quopri xxsubtype
_sysconfigdata_m_darwin_darwin ftplib random zipapp
_testbuffer functools re zipfile
_testcapi gc readline zipimport
_testimportmultiple genericpath reprlib zlib
_testmultiphase getopt resource
_thread getpass rlcompleter
_threading_local gettext runpy
Enter any module name to get more help. Or, type "modules spam" to search
for modules whose name or summary contain the string "spam".
© https://www.python-lernen.de/python-online-lern-editor.htm Seite 16

Online-Lern-Editor zum schnellen Lernen und Verstehen von Python


Wer das erste Mal eine Programmiersprache lernt, möchte unter Umständen nicht etwas auf
seinem System installieren. Für die ersten Schritte gibt es einen Online-Editor, der auch sofort
Python-Code ausführt!

Das Tolle an diesem Online-Python-Editor ist, dass dieser einen ideal beim Lernen unterstützt.
Klar ist, dass dieses Kapitel zum Vorstellen des Online-Lern-Editors vor den Kapiteln zum
Lernen von Python etwas problematisch ist, da wir ja noch kein Python programmieren
können. Aber einfach einmal ansehen und im Zweifel später, wenn nicht alles klar geworden ist
(was logischerweise normal wäre), nochmals dieses Kapitel lesen.

Der Aufruf des Python-Online-Editors geschieht über folgende URL:


http://pythontutor.com/live.html

Wir erhalten folgendes unscheinbares Fenster. Hier nicht täuschen lassen – die Möglichkeiten
sind klasse und beschleunigt das Verständnis zum Lernen von Python!

Oberhalb des Fensters können wir die Python-Version wechseln.

Pythontutor von Philip Guo

Jetzt gebe ich den ersten Python Code ein – das typische "Hallo Welt" Ausgabe Programm:

Python Code in Online Editor automatisch ausgeführt

Rechts sehen wir nun die Ausgabe, die wir auch erhalten würden, wenn wir Python auf dem
eigenen Computer installieren. Das ist schon mal ganz nett, aber das besondere kommt erst
noch!

Jede Programmiersprache hat unterschiedliche Typen von Variablen und Datenstrukturen. Im


folgenden Code lege ich eine Variable mit dem Kursnamen "www.python-lernen.de" und eine
Datenstruktur mit der Bezeichnung "Liste" und eine als "Tupel" an.
© https://www.python-lernen.de/python-online-lern-editor.htm Seite 17

Sofort sehe ich rechts im Bereich "Global frame", die vergebenen Namen für unsere
verschiedenen Variablen und Datenstrukturen.

Zusätzlich weiter rechts, in Gelb unterlegt, noch den Inhalt von "list" und "tuple". Hier sieht man
auch, dass Python immer bei 0 anfängt zu zählen.

Sonst unsichtbare Datenstrukturen, Datentypen und Inhalt sichtbar

Und hier hört der Spaß noch lange nicht auf. Wenn wir dann in das Kapitel zur
objektorientierten Programmierung kommen, hilft auch hier der Online-Editor schnell weiter,
um ein Verständnis aufzubauen. Ich möchte nur den rechten Ausgabeteil für OOP anzeigen.

Wir bekommen automatisch Klassen und Instanzen visualisiert:

Klassen und Instanzen visualisiert

So gut wie alle Beispiele aus diesem Kurs können direkt im Online-Editor ausprobiert werden.
Viel Spaß beim schnellen Lernen.
© https://www.python-lernen.de/text-editor-atom.htm Seite 18

Text-Editor für Python: Atom


Es gibt mehrere Gründe, warum man mit einem
anderen als dem von Python zur Verfügung gestellten
Editor arbeiten möchte. Man kann deutlich mehr
Komfort bekommen durch:

automatische Vervollständigung von Code


(intelligent code completion)

Vorschläge von Anweisungen und möglichen


Parametern

farbliche Hervorhebung, Syntaxhervorhebung


(Syntax-Highlighting)

Allerdings stellt die Wahl des Text-Editors für manche


Programmierer fast schon eine Religionsfrage dar.
Wenn man noch kein Programm seiner Wahl hat, kann
ich den Editor Atom empfehlen.

Text-Editor Atom
Der Text-Editor Atom hat viele Komfortmerkmale zum Programmieren in Python von Haus aus
und bietet noch deutlich mehr durch seine Erweiterbarkeit. Er ist für die Plattformen Windows,
Mac OS X, Unix/X verfügbar und ist Open Source (sprich es entstehen keine Kosten). Er wurde
von den GitHub Leuten entwickelt und steht seit 2014 unter der freien MIT-Lizenz zur
Verfügung.

Der Editor kann über Plug-ins und Themen erweitert werden.

Installation Editor Atom


Erster Schritt ist das Herunterladen der Software für das eigene Betriebssystem unter:
https://atom.io/

Nach der Installation (nachdem alles in die Rakete geladen wurde) sieht der Editor eher
unscheinbar aus. Was ein großer Vorteil ist: wir haben eine aufgeräumte Oberfläche, die nicht
vom eigentlichen ablenkt – dem programmieren.

Jetzt können wir uns im frisch gestarteten Editor über das Menü „File“ eine neue Datei „New
File“ erstellen.

Natürlich testen wir mit dem typischen "Hallo Welt"-Programm. Erst durch das Speichern ist
dem Editor klar, dass wir in Python programmieren und die farbige Syntaxhervorhebung wird
automatisch aktiviert. Will man die Syntaxhervorhebung ohne zu speichern aktivieren, kann
man im Fußbereich rechts (links neben dem Logo von GitHub) die gewünschte
Programmiersprache einstellen.
© https://www.python-lernen.de/text-editor-atom.htm Seite 19

Python-Programm in Atom

Nutzen wir Variablen in unserem Code, werden auch diese uns vorgeschlagen. Im folgenden
Beispiel sieht man das schön anhand des unkreativen Variablennamens "variablenname".

Variablennamen wird von der code completion vorgeschlagen

Farbwahl für Atom


Die verwendeten Farben für die Oberfläche von Atom und für die Darstellung des Codes
können eingestellt werden. Dabei ist wichtig zu wissen, dass diese getrennt voneinander
eingestellt werden können.

Dies geschieht im ersten Menüpunkt „settings“ bzw. „Preferences“ (Shortcut CMD und + beim
Mac bzw. Strg und + bei Windows) über den Unterpunkt „Themes“. Hier kann dann für die UI
(sprich Benutzeroberfläche) bzw. für das Syntax-Theme (Code) etwas nach dem eigenen
Geschmack ausgewählt werden. Ist nichts Passendes da, können online unzählige Themen
nachinstalliert werden.

Atom für Python optimieren


© https://www.python-lernen.de/text-editor-atom.htm Seite 20

Im folgenden Kapitel schauen wir uns an, wie wir den Editor noch wesentlich besser für das
Programmieren mit Python ausrüsten können.
© https://www.python-lernen.de/text-editor-atom-plugins-python.htm Seite 21

Atom besser für Python ausrüsten


Es gibt viele Plug-ins für den Texteditor Atom, die uns das Programmiererleben einfach
machen. Wichtig ist, dass man mehr Komfort und Spaß beim Programmieren hat.

Vervollständigung (autocomplete) von Code optimieren


In der Grundinstallation haben wir bereits eine Vervollständigung von Code, die uns auch
Variablennamen anbietet. Allerdings erhalten wir öfters auch merkwürdige Vorschläge.

unerwünschtes code completion, was wir abschalten wollen

Das gewöhnen wir Atom direkt ab und packen ein Plug-in direkt für die Python
Codevervollständigung dazu.

Abschalten von Standard-Codevervollständigung:


Die Pakete, die deaktiviert werden sollen um die unerwünschte Vervollständigung zu
unterbinden, findet man unter:

Settings -> Packages -> in den “Core Packages” die folgenden 2 Pakete abschalten

autocomplete-plus -> Disable

autocomplete-snippets -> Disable

unerwünschte Vervollständigungsvorschläge abgeschaltet

Danach haben wir Ruhe von merkwürdigen Vorschlägen!

Optimales Autokomplete für Python installieren


Und jetzt installieren wir das Paket „autocomplete-python“:
© https://www.python-lernen.de/text-editor-atom-plugins-python.htm Seite 22

Plug-in für optimales Autokomplete für Python

Ab jetzt haben wir mehr Komfort und bekommen beim Tippen der ersten Buchstaben
entsprechende Befehle vorgeschlagen.

Python-Programme direkt in Atom ausführen - Package: script


Im Menü „File“ und „Settings“ unter dem Punkt „Install“ können wir nach „script“ suchen. Dieses
Plug-in gibt uns eine Command-Shell direkt im Editor und über diese wird direkt Python
gestartet und wir können unseren Code testen, ob dieser macht, was er soll.

Package script installieren

Nach dem Installieren des Plug-ins zur Sicherheit den Editor neu starten und dann einfach den
Shortcut für den Aufruf ausprobieren:

CMD + i (bei Mac OS X)

Shift + CTRL + b (bei Windows)

Mit CMD + SHIFT + i kann der Aufruf noch getunt werden. Beim Mac wird (je nach Version)
noch Python 2.7 standardmäßig aufgerufen. Oder man hat die Version 3.x laufen und möchte
mit einer alten 2.7 Version testen – dann ist die Vorgehensweise wie folgend beschrieben.

Über den Python-Code bekommen wir den Pfad unserer Python-Installation direkt angezeigt:

import sys
print(sys.executable)

In meinem Fall kommt:

/Library/Frameworks/Python.framework/Versions/3.7/bin/python3

Der eigene Pfad wird unten im Feld „Command“ eingetragen:


© https://www.python-lernen.de/text-editor-atom-plugins-python.htm Seite 23

andere Python-Version einstellen bei script

Speichern als „profile“, dass dann aufgerufen werden kann. Beim Mac mit der
Tastenkombination CMD + SHIFT + K und Windows Shift + Ctrl + alt + b

Sollte es Probleme mit dem Ausführen des Packages geben, weil Atom keine Pfade vorliegen
hat, dann Atom über die console/terminal starten:

atom .

Mehr Informationen zu dem Paket unter https://atom.io/packages/script


© https://www.python-lernen.de/python-grundlagen.htm Seite 24

Python Grundlagen
Zum Lernen einer Programmiersprache (und bevor man irgendwelche coolen Spiele
programmieren kann), benötigt man ein paar Grundlagen. Dies ist das Grundlagen-Kapitel.

Was benötigt man so als Grundlagen?

Grundsätzlich zeichnen sich Programmiersprachen durch das EVA-Prinzip aus. Dabei steht
jeder Buchstabe für eine wichtige Möglichkeit und beschreibt die Grundprinzipien der
Datenverarbeitung:

E: Eingabe

V: Verarbeitung

A: Ausgabe

In diesem Grundlagen-Kapitel drehen wir die Reihenfolge um – sprich wir machen EVA und
begrüßen Python und tolle Möglichkeiten mit einer schnellen und einfach zu erlernenden
Programmiersprache.

Ausgabe in Python
Wir schauen uns als Erstes die Ausgabe an – sprich wir lassen etwas über print auf dem
Bildschirm ausgeben.

Verarbeitung
Natürlich möchten wir nicht nur einen bestehenden Inhalt ausgeben, sondern diesen auch
verarbeiten können. Dazu helfen mathematische Funktionen – großes Wort, gemeint ist damit
einfach Grundrechenarten wie z.B. addieren.

Zum Verarbeiten müssen wir den Text „zwischenspeichern“ können. Dazu lernen wir Variablen,
Listen und Tupel kennen.

Eingabe
Und ohne eine Nutzereingabe macht es viel weniger Spaß. Daher sollen in unser Programm
auch Inhalte von außen kommen können – sprich wir fragen den Benutzer und verarbeiten
dann diese Eingaben weiter. Es kann sehr einfach aussehen, dass das Eingegebene einfach
wieder auf dem Bildschirm ausgegeben wird, oder damit gerechnet wird.

Kommentieren und Auskommentieren von Code


Klar fragt man sich was Kommentieren und Auskommentieren im Grundlagen-Kapitel zu
suchen haben. In einem Programm werden wir umfangreicheren Quellcode (und komplizierte
Bereiche) kommentieren. Beides haben wir am Anfang nicht. Aber mit „auskommentieren“
können wir einzelne Teile von unserem Programm abschalten und somit Fehler eingrenzen.
Daher wird diese Möglichkeit im Grundlagen-Kapitel gezeigt.

Das sind unsere Grundlagen. In allen Programmiersprachen immer dasselbe – nur der
Befehlsaufbau unterscheidet sich.

Und nun viel Spaß beim Lernen von Python!


© https://www.python-lernen.de/python-grundlagen.htm Seite 25
© https://www.python-lernen.de/ausgabebefehl-print.htm Seite 26

Ausgaben über print()


Um eine Ausgabe in Python zu erhalten, gibt es die Funktion print() . Innerhalb der
Klammer kann eine Zeichenkette (String) eintragen werden, die dann auf dem Bildschirm
ausgegeben wird. Dazu wird diese Zeichenkette in Anführungszeichen gesetzt. Dabei ist es
egal, ob doppelte oder einfache Anführungszeichen!

print('Hallo Welt');

Die in der Klammer angegebenen Anführungszeichen dienen zum Umschließen der Ausgabe
und werden nicht mit ausgegeben.

Mit der Funktion print() können wir auch den Inhalt von Variablen (mehr zu Variablen im
folgenden Kapitel) ausgeben lassen. Dazu wird einfach der Variablennamen in die Klammern
geschrieben (auf jeden Fall ohne Anführungszeichen, sonst wird der Variablenname einfach
als Zeichenkette ausgegeben und nicht der Inhalt des Strings).

print(vorname)

Ist der Variable noch kein Inhalt zugewiesen, wird eine Fehlermeldung (Traceback)
ausgegeben: NameError: name 'vorname' is not defined

Daher erst einmal den Inhalt der Variable vor der Ausgabe über print() festlegen:

kursname = 'Python Kurs'


print(kursname)

Leerzeilen ausgeben über print()


Wir können auch eine Leerzeile ausgeben, in dem wir ein leeres print() nutzen:

print ("Hallo Welt")


print ()
print ("Leerzeile davor")

Es gibt noch weitere Möglichkeiten, eine Leerzeile auszugeben. Dazu benötigen wir aber erst
unseren Sonderfall im sofort folgenden Abschnitt!

Sonderfall Backslash
Enthält eine Variable ein Backslash, dann ist spannend, was die Ausgabe daraus macht.
Natürlich fragt man sich, wann man überhaupt einen Backslash in einer Variablen haben sollte.
Nehmen wir an, wir wollen einen Pfadnamen von der Festplatte in einer Variablen speichern.
Dann wäre die Schreibweise

pfad = 'C:\niedlicherverzeichnisname'
pfad = "C:\niedlicherverzeichnisname"

Lassen wir nun unsere Variable pfad über print() ausgeben.

print(pfad)

Nun erhalten wir eine Ausgabe über 2 Zeilen umgebrochen ohne den Backslash und vor wurde
allem unser "niedlich" zu "iedlich":
© https://www.python-lernen.de/ausgabebefehl-print.htm Seite 27

c:
iedlicherverzeichnisname

Was ist passiert. Den Backslash haben wir bei den Variablen bereits kennengelernt. Hier war er
dafür da, bestimmte Zeichen zu maskieren, damit diese überhaupt ausgegeben werden
können. Unser Backslash hat also mehr als eine Bedeutung. Wollen wir einen Backslash
ausgeben, müssen wir den Backslash mit einem Backslash maskieren:

pfad = "C:\\niedlicherverzeichnisname"

Aber was ist nun wirklich im Hintergrund passiert? Es gibt sogenannte Steuersequenzen, die
die Ausgabe beeinflussen. Und genau so eine Steuersequenz haben wir mit \n versehentlich
erwischt.

Dabei steht \n für den Zeilenumbruch.

Wollen wir also eine Leerzeile gezielt ausgeben lassen, dann einfach 2-mal den Zeilenumbruch
\n\n in der Anweisung print nutzen.

Steuersequenzen für Tabulator


Andere Steuersequenzen sind z.B.

\t für den Tabulator. Einfach einmal in print() testen.

Ausgabe mit print(r)


Möchte man der print() -Funktion abgewöhnen, dass diese Inhalte interpretiert, kann man
bei dieser eine "rohe" Ausgabe (raw) über das Kürzel "r" am Anfang erzwingen. Dann erhält
man auch die unverfälschte Ausgabe:

print(r"C:\niedlicherverzeichnisname")

So richtig praktisch ist das bei Variablen allerdings nicht:

print(rpfad)

Nun haben wir da keine eindeutige Angabe und bekommen eine Fehlermeldung!

Mehrere Umbrüche bei der Ausgabe


Das Umbrechen in der Ausgabe mit dem Steuerzeichen ist eine Möglichkeit, mehrere Zeilen bei
der Ausgabe zu erzeugen. Das Ganze klappte auch durch die Angabe von 3 Anführungszeichen
am Anfang und dann natürlich auch am Ende. Hier können sowohl die doppelten wie die
einfachen Anführungszeichen verwendet werden. Es sollten nur dieselben verwendet werden:

print("""Hallo
Welt
– in 3 Zeilen""")
© https://www.python-lernen.de/variablen-einsetzen.htm Seite 28

Variablen in Python einsetzen


Variablen dienen zum Speichern von Inhalten. Mit diesen Variablen kann man dann weitere
Aktionen machen. Aber was ist eine Variable? Variablen sind wie ein Schrank mit vielen
kleinen Schubladen. In jede Schublade kann nur 1 Inhalt gesteckt werden. Wird ein neuer
Inhalt in eine Schublade gesteckt, fällt der alte Inhalt raus.

Unser virtueller Schrank hat beliebig viele Schubladen. Jetzt müssen wir natürlich irgendwie
in Python sagen, welche Schublade wir nutzen möchten. Um eine bestimmte Schublade
auszuwählen, ist die Variante "dritte Schublade von rechts und zweite von oben" ein wenig
unhandlich.

Daher benötigen wir ein System, das handlicher ist und verständlich. Daher können wir
unseren Schubladen Namen geben. So können wir Beispielsweise eine Schublade beschriften
mit "vorname". Somit wissen wir, dass wir in dieser Schublade einen Vornamen finden.

Bei der Vergabe von Namen für unsere Variablen gibt es folgende Kriterien:

keine Leerzeichen

Um nun die Schublade zu nutzen, also etwas in der Schublade (Variablen) abzulegen wird
dem Variablennamen über ein Gleichheitszeichen ein Inhalt zugewiesen.

vorname = 'Axel'

Wichtig ist, dass der Inhalt (hier der Name 'Axel') mit einfachen Anführungszeichen
umschlossen wird (das neben der Enter-Taste – NICHT "accent circonflexe/grave"!).

Es können auch doppelte Anführungszeichen verwendet werden – wo der Unterschied liegt,


wird später erklärt.

vorname = "Axel"

Dieses Umschließen ist aus zwei Gründen wichtig, da der Variableninhalt auch aus mehreren
Worten bestehen kann. Somit umschließen unsere einfachen Anführungszeichen unseren
Inhalt. Würde wir ganz auf Anführungszeichen verzichten, würden wir einer Variablen den
Inhalt der zweiten Variablen zuweisen. Technisch funktioniert dies problemlos – nur wenn es
nicht gewünscht ist, dann kommen irritierende Ergebnisse!

Der Vollständigkeit halber:

vorname = Axel

Das klappt nicht. Wir bekommen eine Fehlermeldung "NameError: name 'Axel' is not defined".
Warum? Hier versuchen wir der Variablen vorname den Inhalt der (jetzt kommt es) Variable
mit dem Namen "Axel" zuzuweisen. Daher kommt es zu dieser Fehlermeldung.

Funktionieren würde (Über den Sinn kann man sich Gedanken machen):

Axel = "Test"
vorname = Axel

Wir können auch leere Inhalte zuweisen:

vorname = ''

Das Beispiel sieht natürlich verwirrend aus, da 2 hintereinanderkommende einfach


Anführungszeichen aussehen wie 1 doppeltes Anführungszeichen. Die Schreibweise mit
© https://www.python-lernen.de/variablen-einsetzen.htm Seite 29

doppelten Anführungszeichen sieht auch lustig aus.

vorname = ""

Was passiert aber, wenn wir das einfache Anführungszeichen als Inhalt benötigen? Also
Wörter mit Apostroph – im Deutschen wird das Hochkomma auch Apostroph genannt und
wird zur kennzeichnet beispielsweise den Genitiv von Eigennamen oder Auslassungen (sorry
für den Ausflug in die Grammatik der deutschen Sprache). Als Beispiel dafür "Ku’damm für
Kurfürstendamm". Wollten wir nun aber den "Ku'damm" in einer Variablen nutzen:

strasse = 'Ku'damm'

Dann ergibt diese Nutzung Probleme! Warum. Python schaut nach dem Anfangs-
Anführungszeichen und startet dann, alles danach bis zum nächsten einfachen
Anführungszeichen dies der Variablen zuzuweisen. In unserem Fall wäre das dann "Ku". Mit
dem Rest ist nun Python komplett verwirrt und weiß nicht mehr was tun und wirft mit einer
Fehlermeldung nach uns: "SyntaxError: invalid syntax"

Um nun keine Katastrophe mit dem Apostroph zu erleben, müssen wir diesen "tarnen". Hier
spricht man bei Programmiersprachen von "maskieren". Vor diesem Zeichen wird ein
Backslash gepackt und die Welt ist für Python wieder in Ordnung

strasse = 'Ku\'damm'

Im Zusammenhang mit Variablen fallen Begriffe wie "string". Dahinter verbirgt sich, dass eine
Zeichenkette (sprich "string") genutzt wird. Unterschieden werden z.B. Ganzzahlen, die dann
als "int" (ausgeschrieben Integer bzw. Ganzzahl").

Konvention der Schreibweise


Kleinschreibung der Variablennamen
Variablennamen werden kleingeschrieben. Das ist ein Abkommen, sprich Konvention, die
Sinn ergibt, eingehalten zu werden. Dadurch weiß ein anderer Programmierer beim Lesen des
Codes „Hey, hier handelt es sich um eine Variable“.

Unterstriche bei mehreren Wörtern


Besteht der Variablennamen aus mehreren Wörtern, wird als Trennung der Unterstrich
verwendet:

Beispiel Variablennamen mit mehreren Worten:

meine_variable = "Inhalt"

Sprechende Variablennamen
Ein Variablenname sollte sprechend, also erkennbar sein, was in der Variablen gespeichert
ist. Früher hat man lustig Variablennamen wie „x1“ oder „i3“ vergeben. Spätestens nach 2
Wochen wusste selbst der Programmierer des Codes nicht mehr so genau, was hinter der
Variablen steckt (sobald das Programm ein wenig komplexer war als ein 3-Zeiler). Daher ist
es sinnvoll, kurze aussagekräftige Variablennamen zu vergeben.

Variableninhalt über mehrere Zeilen


© https://www.python-lernen.de/variablen-einsetzen.htm Seite 30

Wenn der Inhalt unserer Variablen über mehrere Zeilen gehen soll, weil wir z.B. Macbeths
Hexenszene in einer Variablen speichern wollen, dann klappt folgende Variante NICHT:

# FUNKTIONIERT NICHT!
macbethtext = "Schön ist häßlich, häßlich schön.
Wir weichen wie Wolken und Windeswehn."

Hier kommen nun 3 Anführungszeichen hintereinander zum Einsatz. Dadurch können wir
über beliebig viele Zeilen den Inhalt der Variable schreiben:

macbethtext = """Schön ist häßlich, häßlich schön.


Wir weichen wie Wolken und Windeswehn."""

Wobei sowohl doppelte wir einfache Anführungszeichen funktionieren (nur müssen die
gewählten Anführungszeichen sowohl am Anfang wie am Ende genutzt werden). Das letzte
Beispiel mit einfachen Anführungszeichen:

macbethtext = '''Schön ist häßlich, häßlich schön.


Wir weichen wie Wolken und Windeswehn.'''
© https://www.python-lernen.de/unterschied-methoden-funktionen.htm Seite 31

Funktionen und Methoden bei Variablen/Strings


Wir haben im letzten Kapitel Variablen kennen gelernt. In einer Variablen kann also ein Wert
abgelegt und wieder ausgegeben werden.

Über die Funktion print() erhalten wir den abgelegten Inhalt einer Variablen angezeigt.

kursname = 'Python-lernen.de'
print(kursname)

Funktionen bei Variablen


Einer Funktion wird also nach dem Funktionsnamen in den folgenden Klammern Werte (und
Anweisungen) mit übergeben. Unserer Funktion print(kursname) bekommt also in der
Klammer die Variable mit übergeben und weiß somit, was auf dem Bildschirm ausgegeben
werden soll.

Es muss allerdings nicht immer einer Funktion weitere Werte und Anweisungen in der
Klammer mit übergeben werden. Wird print() einfach mit einer leeren Klammer
aufgerufen, dann erhalten wir als Ergebnis eine Leerzeile ausgegeben.

Schauen wir uns eine andere Funktion neben print() an. Zum Bestimmen der Länge eines
Strings gibt es die Funktion len(x) . Als Information erhalten wir hier die Anzahl der
enthaltenen Zeichen. Bei len handelt es sich um die Abkürzung des englischen Worts
„length“. Allerdings müssen wir irgendwas mit dieser Information machen. Lassen wir uns
diese ausgeben:

kursname = 'Python-lernen.de'
print(len(kursname))

Funktionen können also innerhalb anderer Funktionen genutzt werden.

Funktionen sind unabhängig. Wir können die Funktionen nicht nur für Strings nutzen!

Funktionen sind soweit einfach verständlich. Was aber sind Methoden und was können wir
damit bei Variablen anstellen?

Methoden bei Variablen/Strings


Ändern wir unsere Sichtweise. Wenn wir unsere Variable als ein Objekt ansehen, dann kann
dieses Objekt verschiedene Möglichkeiten bieten. Ich schreibe hier bewusst Möglichkeiten.
Warum? Wenn wir es aus objektorientierter Sicht ansehen, stecken wir schon voll in der
objektorientierten Programmierung (OOP). Diese wird später im Detail besprochen.
Grundlegend ist, dass bei der OOP die Punktschreibweise genutzt wird. Wir haben unser
Objekt, was an erster Stelle steht und wollen hier für dieses Objekt etwas abfragen bzw. eine
festgelegte Aktion ausführen: Die Aktion wird über einen Punkt direkt dahinter gepackt.

objektname.aktion

Beispielsweise könnten wir unseren in der Variablen gespeicherten Text komplett in


Kleinschreibung erhalten.

kursname = 'www.Python-lernen.de'
kursname.lower()
© https://www.python-lernen.de/unterschied-methoden-funktionen.htm Seite 32

Wer sich jetzt denkt, das fühlt sich doch an wie eine Funktion, die einfach alles in
Kleinbuchstaben umwandelt, liegt nicht wirklich falsch. Es ist einfach eine andere Sichtweise
– sprich die objektorientierte Sichtweise. Und somit wird die objektorientierte Schreibweise
notwendig.

Die wirkliche Kunst liegt darin zu wissen, welche Objekte welche Möglichkeiten (sprich
Methoden) bieten.

Diese Hilfe können wir über die Anweisung help(str) anfordern für unsere Strings (was
unsere Variablen sind). Hier kommt dann ein sehr umfangreicher Text:

>>> help(str)

Help on class str in module builtins:

class str(object)
| str(object='') -> str
| str(bytes_or_buffer[, encoding[, errors]]) -> str
|
| Create a new string object from the given object. If encoding or
| errors is specified, then the object must expose a data buffer
| that will be decoded using the given encoding and error handler.
| Otherwise, returns the result of object.__str__() (if defined)
| or repr(object).
| encoding defaults to sys.getdefaultencoding().
| errors defaults to 'strict'.
|
| Methods defined here:
...

Zum Scrollen die Pfeiltasten nutzen, zum Beenden der Hilfe einfach „q“ drücken.

Möchte man eine kürzere Übersicht, was uns Strings (sprich „str“) bieten, dann können wir
diese über dir(str) erhalten:

>>> dir(str) ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__',


'__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__',
'__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__',
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__',
'__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith',
'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isascii', 'isdecimal',
'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust',
'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip',
'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']

Alles ohne Unterstriche sind Methoden, die für String-Objekte zur Verfügung stehen. Hier
taucht unser lower aus dem letzten Beispiel auf.

Und wollen wir nur genauere Hilfe zu der Methode lower dann bekommen wir diese über
die Anweisung help(str.lower)
© https://www.python-lernen.de/unterschied-methoden-funktionen.htm Seite 33

Help on method_descriptor:

lower(self, /)
Return a copy of the string converted to lowercase.

Das war jetzt ein größerer Brocken. Wer unseren oberen Code einmal getestet hat, wird sich
wundern, dass keine Ausgabe in Kleinschreibung erfolgt ist. Das ist auch korrekt so. Die
Methode lower() wandelt nur in Kleinschreibung um. Wollen wir eine Ausgabe, benötigen
wir wie gewohnt unsere print() -Anweisung:

kursname = 'www.Python-lernen.de'
print(kursname.lower())

Am Rande bemerkt: Unser Inhalt der Variable „kursname“ wird nicht verändert! Diese bleibt
unberührt. Einfach mal folgenden Code testen:

kursname = 'www.Python-lernen.de'
print(kursname.lower())
print(kursname)

Zusammengefasst:
Unterschied zwischen Funktionen und Methoden
Funktionen können direkt über ihren Namen aufgerufen werden – Methoden dagegen
benötigen immer ihr Objekt.

Die Schreibweise:
Funktionen: funktionsname()
Methoden: objekt.methode()

Funktionen sind unabhängig. Einer Funktion kann beliebiges übergeben werden, mit dem
dann weitergearbeitet wird. Methoden sind festgelegt – sprich jedes Objekt verfügt über
bestimmte Möglichkeiten (sprich Methoden). Die Kunst ist nur zu wissen, was es an
Methoden bereits „standardmäßig“ gibt.

Tipp für Einsteiger


In den folgenden Unterkapiteln schauen wir uns Variablen (100 % korrekt für Strings) an,
welche Methoden existieren und wie diese angewendet werden können. Als Einsteiger kann
man die Unterkapitel überfliegen, wird sich aber besser später hier nochmals genauer die
Möglichkeiten ansehen. Bevor man also durch viele kleine Möglichkeiten erschlagen wird,
bitte erst den grundlegenden Überblick verschaffen und im nächsten Kapitel „Operatoren für
Strings“ (operatoren-strings.htm) weitermachen und sich später diese Unterkapitel ansehen!
© https://www.python-lernen.de/string-methode-lstrip.htm Seite 34

Leerzeichen am Anfang entfernen über lstrip()


Gerne werden bei Benutzereingaben versehentlich vom Nutzer Leerzeichen am Anfang mit
eingegeben. Leerzeichen auf der linken Seite des Strings (sprich am Anfang der
Zeichenkette) können über lstrip (l = left) entfernt werden. Englisch am Rande gelernt:
„tease“ bedeutet „Verzögerung“. „Strip“ hat im Englischen die Bedeutung von „ausziehen,
abziehen, abkratzen“ und ist auch die Kurzform von „Striptease“, wobei in Python sofort und
nicht kunstvoll langsam die unerwünschten Zeichen entfernt werden.

Befehlsaufbau:

str.lstrip([Zeichen])

Nehmen wir unseren Beispieltext mit Leerzeichen rechts und links:

inhalt = " Python rocks "


ausgabe = inhalt.lstrip()
print(ausgabe)

Als Ergebnis erhalten wir einen linksbündigen Text ohne führende Leerzeichen:

Python rocks

Die Leerzeichen rechts bleiben bestehen. Wenn wir einen zusätzlichen Text ausgeben lassen,
sieht man das:

inhalt = " Python rocks "


ausgabe = inhalt.lstrip()
print(ausgabe + ", daher www.Python-lernen.de")

Und als Ergebnis:

Python rocks , daher www.Python-lernen.de

Parameter nutzen: Beliebige Zeichen, die entfernt werden


Wir können mehr als Leerzeichen entfernen lassen! Über den Parameter können wir beliebige
Zeichen mitgeben, die links entfernt werden sollen. Im Beispiel haben wir einen
merkwürdigen Text mit vielen Zahlen am Anfang. Diese sollen beseitigt werden.

inhalt = "321 Python 3 rocks"


ausgabe = inhalt.lstrip('123')
print(ausgabe)

Als Ergebnis erhalten wir:

Python 3 rocks

Es ist möglich mehrere Zeichen einzugeben, die entfernt werden sollen - auch das
Leerzeichen!
© https://www.python-lernen.de/string-methode-lstrip.htm Seite 35

inhalt = "321 Python 3 rocks"


ausgabe = inhalt.lstrip(' 123456789')
print(ausgabe)

Es werden also folgende Zeichen entfernt: Zahlen von 1 bis 9 und Leerzeichen:

Python 3 rocks

Alles am Anfang wird entfernt, bis die Methode auf das Erste nicht zu entfernende Zeichen
stößt. Daher bleibt die 3 nach Python mitten im Text stehen!

Alle String-Methoden zum Beseitigen von Leerzeichen:


lstrip() – links Zeichen entfernen (meistens Leerzeichen)

strip() – rechts und links bestimmte Zeichen entfernen (meistens Leerzeichen)

rstrip() – rechts Zeichen entfernen (meistens Leerzeichen)


© https://www.python-lernen.de/string-methode-strip.htm Seite 36

Leerzeichen am Anfang und Ende entfernen über strip()


Leerzeichen schleichen sich gerne ein – vor allem bei Nutzereingaben über Formulare. Da ist
schnell ein Leerzeichen am Anfang oder am Ende zu viel, was bei vielen Formularfelder auch
für den Nutzer fast nicht sichtbar ist. Diese Leerzeichen wollen wir wieder entfernen. Dafür gibt
es in Python den Befehl strip() . Die englische Bedeutung ist „ausziehen, abziehen,
abschälen und abkratzen“. Wir wollen also die unnötigen Leerzeichen abkratzen. Schauen wir
uns den Befehlsaufbau an.

Befehlsaufbau:

str.strip([Zeichen])

Der Parameter ist optional (daher die eckigen Klammern). Der Parameter steht für das Zeichen
bzw. die Zeichen, die am Anfang und Ende entfernt werden sollen. Wird hier nichts angegeben,
wird das Leerzeichen (der übliche Übeltäter) entfernt. Schauen wir es uns im Beispiel an:

inhalt = " https://www.python-lernen.de "


ausgabe = inhalt.strip()
print(ausgabe)

Alle Leerzeichen um unseren Beispieltext (eine URL, in der es einfach auch Leerzeichen geben
darf) sind entfernt.

https://www.python-lernen.de

beliebige Zeichen entfernen durch strip()


Das Tolle an der Python-Methode ist, dass nicht nur Leerzeichen entfernt werden können. Es
können beliebige Zeichen entfernt.

Kommt unser Text aus einer Aufzählung z.B. heraus, können wir die Zahlen und den
Aufzählungspunkt auch entfernen:

inhalt = "1.) https://www.python-lernen.de "


ausgabe = inhalt.strip('1')
print(ausgabe)

Das Ergebnis, das noch nicht befriedigend ist:

.) https://www.python-lernen.de

Wir wollen auch keine Punkte, Klammern und Leerzeichen. Also geben wir alle unerwünschten
Zeichen als Parameter an:

inhalt = "1.) https://www.python-lernen.de "


ausgabe = inhalt.strip('.) 1234567890')
print(ausgabe)

Und nun haben wir unser gewünschtes Ergebnis:

https://www.python-lernen.de
© https://www.python-lernen.de/string-methode-strip.htm Seite 37

Auch wenn wir alle Punkte entfernen, dann bezieht sich das nur auf die Punkte am Anfang und
Ende! Die strip() -Methode hört sofort mit dem entfernen auf, sobald das erste erwünschte
Zeichen kommt. Sprich unsere Punkte innerhalb der URL bleiben erhalten. Das wäre anders,
wenn wir einen deutschen Satz mit einem Punkt am Ende hätten. Dieser Punkt würde bei
unserem Beispielaufbau der strip() -Methode zum Opfer fallen.

Langer Rede kurzer Sinn: diese Methode wird überaus häufig in der Praxis genutzt.

Alle String-Methoden zum Beseitigen von Leerzeichen:


lstrip() – links Zeichen entfernen (meistens Leerzeichen)

strip() – rechts und links bestimmte Zeichen entfernen (meistens Leerzeichen)

rstrip() – rechts Zeichen entfernen (meistens Leerzeichen)


© https://www.python-lernen.de/string-methode-rstrip.htm Seite 38

Leerzeichen rechts entfernen über rstrip()


Gerne werden bei Benutzereingaben versehentlich vom Nutzer Leerzeichen am Anfang oder
Ende mit eingegeben. Leerzeichen auf der rechten Seite eines Strings (sprich am Ende der
Zeichenkette) können über rstrip() entfernt werden. Das „r“ am Anfang steht für rechts
(englisch „right“).

Befehlsaufbau:

str.rstrip([Zeichen])

Nehmen wir unseren Beispieltext mit Leerzeichen rechts und links:

inhalt = " Python 3 rocks "


ausgabe = inhalt.rstrip()
print(ausgabe + ", daher www.Python-lernen.de")

Für die bessere Sichtbarkeit des Effekts lassen wir einen zusätzlichen Text ausgeben. Wir
erhalten folgende Ausgabe:

Python 3 rocks, daher www.Python-lernen.de

Parameter nutzen: Beliebige Zeichen, die entfernt werden


Wir können mehr als Leerzeichen entfernen lassen! Über den Parameter können wir alle
gewünschten Zeichen mitgeben, die rechts entfernt werden sollen. Jetzt haben wir zum
Beispiel eine merkwürdige Eingabe mit vielen 4ern am Ende. Diese sollen beseitigt werden.

inhalt = " Python 3 rocks 1233 4444"


ausgabe = inhalt.rstrip('4')
print(ausgabe + ", daher www.Python-lernen.de")

Als Ergebnis erhalten wir:

Python 3 rocks 1233 , daher www.Python-lernen.de

Es ist möglich mehrere Zeichen einzugeben, die entfernt werden sollen.

inhalt = " Python 3 rocks 1233 4444"


ausgabe = inhalt.rstrip('1234 ?XYZ')
print(ausgabe + ", daher www.Python-lernen.de")

Es werden also folgende Zeichen entfernt: Zahlen von 1 bis 9, Fragezeichen, Leerzeichen und
„XYZ“ (aber nur in Großschreibung):

Python 3 rocks, daher www.Python-lernen.de

Alles am rechten Ende wird entfernt, bis die Methode auf das Erste nicht zu entfernende
Zeichen stößt. Daher bleibt die 3 nach Python mitten im Text stehen!

Entfernen von Zeilenumbruch, Newline \r\n mit Python


© https://www.python-lernen.de/string-methode-rstrip.htm Seite 39

Die rstrip() -Methode von Python entfernt standardmäßig alle Arten von nachgestellten
Leerzeichen. Dazu gehören nicht Zeilenumbruch und neue Zeilen, die über den Steuercode \r\n
übertragen werden.

inhalt = " Python rocks \n \r\n "


ausgabe = inhalt.rstrip('')
print(ausgabe + ", damit sichtbar wird, was gelöscht wurde")

Das Ergebnis:

Python rocks

, damit sichtbar wird, was gelöscht wurde

Möchte man gezielt einen bestimmten Zeilenumbruch nur entfernen, muss dieser als
Parameter mit Übergeben werden:

inhalt = " Python rocks \n \r\n "


ausgabe = inhalt.rstrip('\n ')
print(ausgabe + ", damit sichtbar wird, was gelöscht wurde")

Als Ergebnis werden alle Umbruch (\n) und Leerzeichen gelöscht. Ein Umbruch (\r) bleibt
erhalten:

Python rocks
, damit sichtbar wird, was gelöscht wurde

Sollen alle Zeilenumbruch und Leerzeichen entfernt werden, müssen alle 3 Angaben in
rstrip('\n \r') gemacht werden! Dabei ist die Reihenfolge egal. Es funktioniert genauso:
rstrip(' \r\n')

inhalt = " Python rocks \n \r\n "


ausgabe = inhalt.rstrip('\n \r')
print(ausgabe + ", damit sichtbar wird, was gelöscht wurde")

Das Ergebnis:

Python rocks, damit sichtbar wird, was gelöscht wurde

Alle String-Methoden zum Beseitigen von Leerzeichen:


lstrip() – links Zeichen entfernen (meistens Leerzeichen)

strip() – rechts und links bestimmte Zeichen entfernen (meistens Leerzeichen)

rstrip() – rechts Zeichen entfernen (meistens Leerzeichen)


© https://www.python-lernen.de/string-methode-ljust.htm Seite 40

Linksbündig ausgeben, rechts auffüllen mit Zeichen: ljust()


Die String Methode ljust() füllt rechts mit vorbestimmten Zeichen auf. Dabei haben wir
beim Methodennamen wieder die für Python typischen Abkürzung von englischen Begriffen.
Die Bedeutung von „left justify“ ist „linksbündig“. Das mag auf den ersten Blick irritieren, da
die Methode rechts auffüllt. Wichtig ist, dass der Text links platziert ist und somit
linksbündig. Schauen wir uns den Befehlsaufbau ab:

str.ljust(Breite[, Füllzeichen])

Schauen wir unser erstes Beispielprogramm an. Wir lassen uns das Wort „Vier“ ausgeben,
dass 4 Buchstaben breit ist. Es bekommt einen Platz von 10 über ljust() :

inhalt = "Vier"
ausgabe = inhalt.ljust(10)
print(ausgabe)

In der Ausgabe sieht man nicht direkt die Auswirkung von ljust() :

Vier

Würde danach gleich ein Text kommen, wäre die Auswirkung sichtbar:

inhalt = "Vier"
ausgabe = inhalt.ljust(10)
print(ausgabe, "mehr Text")

Und nun ist der Abstand 6 Zeichen – 4 Zeichen von unserem Beispielwort minus den 10
vorgegebenen Zeichen ergibt 6 Leerzeichen:

Vier mehr Text

Wir können bei der Methode noch die Füllzeichen mitgeben und damit wird das Auszählen der
Abstände einfacher:

inhalt = "Vier"
ausgabe = inhalt.ljust(10, '.')
print(ausgabe, "mehr Text")

Und das Ergebnis:

Vier...... mehr Text

Hier taucht ein Leerzeichen zwischen unserem weiteren Text und den 10 Zeichen von
ljust() auf. Durch eine Verknüpfung mit „+“ wird dies nicht mehr erscheinen:

inhalt = "Vier"
ausgabe = inhalt.ljust(10, '.')
print(ausgabe + "mehr Text")

Allerdings hat der Inhalt Vorrang vor Breitenangabe. Ist der Inhalt breiter als die mitgegebene
Breite, wird der komplette Inhalt gefolgt von einem Leerzeichen ausgegeben:
© https://www.python-lernen.de/string-methode-ljust.htm Seite 41

inhalt = "Vier"
ausgabe = inhalt.ljust(2, '.')
print(ausgabe, "mehr Text")

Und als Ausgabe erhalten wir:

Vier mehr Text

Alle String-Methoden für formatierte Ausgabe:


ljust() = String wird linksbündig zurückgeliefert (Füllzeichen möglich)

center() = String wird zentriert ausgegeben (Füllzeichen möglich)

rjust() = String wird rechtsbündig zurückgeliefert (Füllzeichen möglich)

zfill() = String wird mit Nullen (Zero) aufgefüllt


© https://www.python-lernen.de/string-methode-center.htm Seite 42

Zentrierte Ausgabe über .center()


Über die String-Methode .center() kann ein Text zentriert ausgegeben werden. Dabei wird
eine Länge vorgegeben, in der vorhandener Text mittig platziert wird. Zusätzlich kann auch ein
beliebiges Füllzeichen mitgegeben werden. Wird kein Füllzeichen mitgegeben, wird ein
Leerzeichen als Füllzeichen verwendet.

Beispielcode:

inhalt = "mittig"
print( inhalt.center(12) )

Als Ergebnis erhalten wir:

mittig

Besser sichtbar ist die Arbeitsweise von zentrierten Ausgaben, wenn wir ein anderes
Füllzeichen als das Leerzeichen wählen:

Beispielcode:

inhalt = "mittig"
print( inhalt.center(12,"^") )

Als Ergebnis erhalten wir:

^^^mittig^^^

Unser Beispielwort ist 6 Zeichen lang und wir wollen es zentriert auf 12 Zeichen ausgeben.
Dann kommen 3 Füllzeichen rechts und 3 Füllzeichen links neben unserem Beispielwort.

Geht es nicht so schön auf, dass wir die gleiche Anzahl von Füllzeichen links wie rechts haben,
wird auf einer Seite ein Füllzeichen mehr ausgegeben:

inhalt = "mittig"
print( inhalt.center(11,"^") )

Bringt als Ergebnis:

^^^mittig^^

Lustigerweise ist die Verteilung, ob das Füllzeichen rechts oder links von unserem Text mehr
ausgegeben wird, abhängig davon, ob wir eine gerade oder ungerade Anzahl von Zeichen bei
unserem Text haben. Einfach einmal probieren.

inhalt = "Mitte"
print( inhalt.center(8,"^") )

Ergibt dann rechts mehr Füllzeichen:

^Mitte^^
© https://www.python-lernen.de/string-methode-center.htm Seite 43

nur ein Füllzeichen möglich


Kommt man auf die Idee, mehrere Füllzeichen eingeben zu wollen, erhält man die
Fehlermeldung: „TypeError: The fill character must be exactly one character long“.

zu wenig Zeichen zum Zentrieren


Wird als Breite zu wenig Zeichen angegeben, wird trotzdem eine komplette Ausgabe des
Textes stattfinden:

inhalt = "Mitte"
print(inhalt.center(2,"^"))

Unser Beispielwort „Mitte“ benötigt mindestens 5 Zeichen, bekommt aber im Beispiel nur 2 zur
Verfügung gestellt. Macht nichts, da wir die Ausgabe des kompletten Beispielwortes erhalten,
was allerdings nicht zentriert werden kann.

Mitte

Alle String-Methoden für formatierte Ausgabe:


ljust() = String wird linksbündig zurückgeliefert (Füllzeichen möglich)

center() = String wird zentriert ausgegeben (Füllzeichen möglich)

rjust() = String wird rechtsbündig zurückgeliefert (Füllzeichen möglich)

zfill() = String wird mit Nullen (Zero) aufgefüllt


© https://www.python-lernen.de/string-methode-rjust.htm Seite 44

Rechtsbündig ausgeben, links auffüllen mit Zeichen:


rjust()
Die String Methode rjust() füllt links mit vorbestimmten Zeichen auf. Dabei haben wir
beim Methodennamen wieder die für Python typischen Abkürzung von englischen Begriffen.
Die Bedeutung von „right justify“ ist „rechtsbündig“. Schauen wir uns den Befehlsaufbau ab:

str.rjust(Breite[, Füllzeichen])

Wird kein Füllzeichen festgelegt, wird ein Leerzeichen verwendet.

Schauen wir unser erstes Beispielprogramm an. Wir lassen uns das Wort „Vier“ ausgeben,
dass 4 Buchstaben breit ist. Es bekommt einen Platz von 10 über rjust() :

inhalt = "Vier"
ausgabe = inhalt.rjust(10)
print(ausgabe)

In der Ausgabe sieht man direkt die Auswirkung von rjust() . Es werden 6 Leerzeichen vor
dem Wort „Vier“ ausgegeben:

Vier

Nachfolgender Text kommen mit einem Leerzeichen davor:

inhalt = "Vier"
ausgabe = inhalt.rjust(10)
print(ausgabe, ", weiterer Text")

Und nun der Abstand von 6 Zeichen (4 Zeichen von unserem Beispielwort minus den 10
vorgegebenen Zeichen ergibt 6 Leerzeichen):

Vier , weiterer Text

Hier fällt das Leerzeichen vor unserem „weiteren Text“, sprich vor dem Komma auf. Durch
eine Verknüpfung mit „+“ wird dies nicht mehr erscheinen:

inhalt = "Vier"
ausgabe = inhalt.rjust(10)
print(ausgabe + ", weiterer Text")

Ergebnis:

Vier, weiterer Text

Wir können bei der Methode noch die Füllzeichen mitgeben und damit wird das Auszählen der
Abstände einfacher:

inhalt = "Vier"
ausgabe = inhalt.rjust(10, '.')
print(ausgabe + ", weiterer Text")

Und das Ergebnis:


© https://www.python-lernen.de/string-methode-rjust.htm Seite 45

......Vier, weiterer Text

Allerdings hat der Inhalt Vorrang vor Breitenangabe. Ist der Inhalt breiter als die mitgegebene
Breite, wird der komplette Inhalt gefolgt von einem Leerzeichen ausgegeben:

inhalt = "Vier"
ausgabe = inhalt.rjust(2, '.')
print(ausgabe + ", weiterer Text")

Und als Ausgabe erhalten wir:

Vier, weiterer Text

Alle String-Methoden für formatierte Ausgabe:


ljust() = String wird linksbündig zurückgeliefert (Füllzeichen möglich)

center() = String wird zentriert ausgegeben (Füllzeichen möglich)

rjust() = String wird rechtsbündig zurückgeliefert (Füllzeichen möglich)

zfill() = String wird mit Nullen (Zero) aufgefüllt


© https://www.python-lernen.de/string-methode-zfill.htm Seite 46

Führende 0 am Anfang auffüllen über .zfill()


Über die Methode zfill() werden am Anfang Nullen auffüllen. Es muss ein Parameter für
die gewünschten Anzahl aufzufüllenden Stellen mitgegeben werden.

Dabei steht das „z“ bei der Methode für „Zero“ – also mit „Nullen füllen“ wenn man den
englischen Begriff übersetzt.

Beispiel:

text = "20"
print(text.zfill(8))

Als Ergebnis erhalten wir:

00000020

Wird der Parameter vergessen, erhält man als Fehlermeldung: „TypeError: zfill() takes exactly
one argument (0 given)“

Es muss auch ein String übergeben werden! Man denkt zwar beim Auffüllen mit Nullen immer
an Zahlen, allerdings werden wir auch dann eine Fehlermeldung erhalten, wenn wir eine Zahl
anstelle eines Strings übergeben würden ( zahl = 20 ). Als Fehlermeldung kommt dann:
„AttributeError: 'int' object has no attribute 'zfill'“

Inhalt länger als Anzahl der aufzufüllenden Nullen


Wenn unser Inhalt länger ist als die Anzahl der aufzufüllenden Nullen, kommt einfach unser
Inhalt und keine Nullen.

text = "Inhalt länger als 8 Zeichen"


print(text.zfill(8))

Ergebnis:

Inhalt länger als 8 Zeichen

Führendes +/- Zeichen - wird nach vorne geschoben


Wenn es ein führendes +/- Zeichen gibt, werden die anzuhängenden Nullen nach den +/-
Zeichen aufgefüllt.

text = "-123"
print(text.zfill(8))

Somit erhalten wir als Ergebnis:

-0000123

Alternativen zu zfill() - rjust()


Die Methode .rjust() kann auch einen String auffüllen, als weiteren Vorteil können wir
© https://www.python-lernen.de/string-methode-zfill.htm Seite 47

aber das Zeichen angeben, mit dem der String aufgefüllt werden soll. Hierzu folgendes
Beispiel:

text = "-123"
print(text.rjust(8,"0"))

Als Ergebnis erhalten wir:

0000-123

Alle String-Methoden für formatierte Ausgabe:


ljust() = String wird linksbündig zurückgeliefert (Füllzeichen möglich)

center() = String wird zentriert ausgegeben (Füllzeichen möglich)

rjust() = String wird rechtsbündig zurückgeliefert (Füllzeichen möglich)

zfill() = String wird mit Nullen (Zero) aufgefüllt


© https://www.python-lernen.de/string-methode-upper.htm Seite 48

Umwandeln in Großschreibung über die String-Methode


.upper()
Wollen wir alle Buchstaben eines Strings in Großbuchstaben, können wir über die Methode
upper() diese umwandeln:

inhalt = "Hier kommt ein String-Inhalt"


grossbuchstaben = inhalt.upper()
print ( grossbuchstaben )

Als Ausgabe erhalten wir:

HIER KOMMT EIN STRING-INHALT

Weitere Methoden zur Umwandlung zwischen Groß- und


Kleinschreibung
Alle String-Methoden für die Umwandlung bei Klein- und Großschreibung:
casefold(), upper(), lower(), capitalize(), title(), swapcase()
© https://www.python-lernen.de/string-methode-lower.htm Seite 49

Umwandeln in Kleinschreibung über die String-Methode


.lower()
Alles wird in Kleinschreibung umgewandelt:

inhalt = "Hier kommt ein String-Inhalt"


kleinbuchstaben = inhalt.lower()
print ( kleinbuchstaben )

Als Ausgabe erhalten wir:

hier kommt ein string-inhalt

Weitere Methoden zur Umwandlung zwischen Groß- und


Kleinschreibung
Alle String-Methoden für die Umwandlung bei Klein- und Großschreibung:
casefold(), upper(), lower(), capitalize(), title(), swapcase()
© https://www.python-lernen.de/string-methode-casefold.htm Seite 50

aggressive Umwandlung in Kleinbuchstaben .casefold()


Eine weitere String-Methode zur Umwandlung in Kleinbuchstaben. Aber warum zur Hölle
benötigen wir neben der Methode .lower() eine weitere Methode? Hier kommt das schöne
Wort „aggressiv“ zum Tragen.

casefold() ändert unter Umständen auch Zeichenfolgen. Was geht da vor. Normalerweise
wird man sich denken, zu jedem Großbuchstaben gibt es einen Kleinbuchstaben. Aus einem
großen „A“ wird einfach ein kleines „a“. Aber was ist beispielsweise mit „ß“? Schauen wir uns
an, was casefold() uns daraus bastelt:

text = "Inhalt mit Umlauten: ÄÖÜß"


print("Originaltext:")
print(text)
print()
print("Umwandlung durch lower:")
print(text.lower())
print()
print("Umwandlung durch casefold:")
print(text.casefold())

Als Ergebnis erhalten wir:

Originaltext:
Inhalt mit Umlauten: ÄÖÜß

Umwandlung durch lower:


inhalt mit umlauten: äöüß

Umwandlung durch casefold:


inhalt mit umlauten: äöüss

Aus einem „ß“ wir korrekt ein „ss“. Hier werden als nationale Besonderheiten berücksichtigt.
Wer es genau benötigt, kann sich die Zusammenstellung beim Unicode-Konsortium
herunterladen (siehe https://unicode.org/faq/casemap_charprop.html unter CaseFolding.txt).

Hier als kleine Übung wofür man casefold() sinnvoll einsetzen können. Es bietet uns die
Möglichkeit zur Normalisierung von Text und wir können von einem vorliegenden Text
überprüfen, ob dieser ein Palindrom ist. Was ist ein Palindrom? Für alle, bei denen der
Schulunterricht schon ein paar Tage zurückliegt: Übersetzt bedeutet Palindrom „rückwärts
laufend“. So ist der Name „Otto“ und „Hannah“ rückwärts geschrieben exakt das Gleiche.

Aufgabe Palindrom über casefold() testen


Aufgabe: Testen, ob bei dem Wort „Rentner“ ein Palindrom vorliegt.

Erst selber ein Python-Programm erstellen und dann die Lösung ansehen. Wir benötigen dazu
auch die Funktion reversed(str) , .join() und list() , die uns die Reihenfolge
umdreht.

Lösung Palindrom mit casefold()


Als Erstes drehen wir die Reihenfolge um und lassen uns zur Kontrolle den Inhalt ausgeben:
© https://www.python-lernen.de/string-methode-casefold.htm Seite 51

text = "Rentner"
text = text.casefold()
rueckwarts = reversed(text)
print(text)
print(rueckwarts)

Wir erhalten bei unserem reversed() ein „reversed object at …“.

Als Objekt können wir es nicht mit einem String vergleichen. Also erstellen wir über .join
einen String.

text = "Rentner"
text = text.casefold()
rueckwarts = ''.join (reversed(text))

Und jetzt können wir bequem vergleichen:

text = "Rentner"
text = text.casefold()
rueckwarts = ''.join (reversed(text))

if text == rueckwarts:
print(text, " ist ein Palindrom")
else:
print("KEIN Palindrom")

Ach ja – das Wort „Rentner“ ist ein Palindrom.

Weitere Methoden zur Umwandlung zwischen Groß- und


Kleinschreibung
Alle String-Methoden für die Umwandlung bei Klein- und Großschreibung:
casefold(), upper(), lower(), capitalize(), title(), swapcase()
© https://www.python-lernen.de/string-methode-capitalize.htm Seite 52

Erster Buchstaben in Großschreibung über


capitalize() – Rest klein!
Nur der erste Buchstabe wird in Großschreibung, der Rest wird aber in Kleinbuchstaben
umgesetzt bei der Python Methode capitalize() ! Schauen wir uns unsere Beispiele an:

vornachname = "Rolf von und zu Maier-Müller"


umgewandelt = vornachname.capitalize()
print(umgewandelt)

Und als Ergebnis erhalten wir:

Rolf von und zu maier-müller

Die Schreibweise vom Text ist gleichgültig. Alle Zeichen, egal wie diese im Ursprungstext
geschrieben wurden, werden bis auf das erste Zeichen in Kleinbuchstaben umgesetzt. Nur der
erste Buchstabe wird als Großbuchstaben ausgegeben:

zeichenkette = "hIeR kOmMt TeXT"


print(zeichenkette.capitalize())

Als Ergebnis erhalten wir:

Hier kommt text

Sonderfälle bei Großbuchstaben


Sofern möglich wird das erste Zeichen in einen Großbuchstaben umgewandelt. Das
funktioniert natürlich nur bei Buchstaben – wobei es auch hier Sonderfälle gibt.

Probieren wir es bei Zahlen und Vorzeichen. Hier haben wir keinen Unterschied bei Groß- und
Kleinschreibung. Das wäre jetzt nicht weiter Erwähnenswert, wenn es nicht den Buchstaben „ß“
(Eszett) gäbe. Aber der Reihe nach. Schauen wir uns das Verhalten von capitalize() bei
Zahlen und Vorzeichen an:

zeichenkette = "123 Text"


print(zeichenkette.capitalize())

Als Ausgabe erhalten wir:

123 text

Ober bei Vorzeichen:

zeichenkette = "+123 Text"


print(zeichenkette.capitalize())

Auch bei Vorzeichen bleibt das Ursprungszeichen einfach bestehen:

+123 text
© https://www.python-lernen.de/string-methode-capitalize.htm Seite 53

Sonderfall „ß“ und capitalize() !


Interessant ist die Umwandlung bei capitalize() von dem Sonderfall mit dem deutschen
„ß“:

zeichenkette = "ß Text"


print(zeichenkette.capitalize())

Als Ergebnis erhalten wir:

Ss text

Wobei das Großes Eszett es seit 2017 auch offiziell als Großbuchstaben gibt! Und dieses hat
definitiv nicht die Umsetzung in „Ss“ - wobei hier schätzungsweise wieder nationale
Sonderwege gibt. Vielleicht ist es bei den Schweizern oder Österreichern in dieser Form üblich.

Bei Umlauten, die über eine Großschreibung verfügen, funktioniert es problemlos:

zeichenkette = "äöü Text"


print(zeichenkette.capitalize())

Äöü text

Bisher ist mir keine direkte Anwendung beim Programmieren unter die Finger gekommen. Aber
wer weiß, irgendwann und irgendwer wird die Methode capitalize() schon sinnvoll
benutzen können.

Weitere Methoden zur Umwandlung zwischen Groß- und


Kleinschreibung
Alle String-Methoden für die Umwandlung bei Klein- und Großschreibung:
casefold(), upper(), lower(), capitalize(), title(), swapcase()
© https://www.python-lernen.de/string-methode-title.htm Seite 54

Jeder Anfangsbuchstaben in Großschreibung über title()


Jeder Anfangsbuchstabe wird in Großschreibung umgesetzt. Schauen wir uns unser Beispiel
an:

vornachname = "Rolf von und zu Maier-Müller"


umgewandelt = vornachname.title()
print(umgewandelt)

Und als Ergebnis erhalten wir:

Rolf Von Und Zu Maier-Müller

Das könnte man bei „normalen“ Vor- und Nachnamen machen, aber sobald ein „von“ oder
„van“ dazukommt, läuft es schief.

Weitere Methoden zur Umwandlung zwischen Groß- und


Kleinschreibung
Alle String-Methoden für die Umwandlung bei Klein- und Großschreibung:
casefold(), upper(), lower(), capitalize(), title(), swapcase()
© https://www.python-lernen.de/string-methode-swapcase.htm Seite 55

Groß- und Kleinschreibung wird vertauscht: swapcase()


Alles was ursprünglich ein Großbuchstabe war wird zum Kleinbuchstaben und andersherum.

Am Beispiel wird es deutlich:

vornachname = "Rolf von und zu Maier-Müller"


umgewandelt = vornachname.swapcase()
print(umgewandelt)

Und als Ergebnis erhalten wir:

rOLF VON UND ZU mAIER-mÜLLER

Weitere Methoden zur Umwandlung zwischen Groß- und


Kleinschreibung
Alle String-Methoden für die Umwandlung bei Klein- und Großschreibung:
casefold(), upper(), lower(), capitalize(), title(), swapcase()
© https://www.python-lernen.de/string-replace.htm Seite 56

Zeichen ersetzen/austauschen mit Python: String


replace('alt', 'neu', [Anzahl])
Bei der Arbeit mit Strings ist es oft notwendig, Zeichenketten bzw. Teile des Inhalts
auszutauschen. Python bietet mit der Funktion variable.replace("alt", "neu") eine
einfache Möglichkeit. Die Funktion zum Austauschen bzw. Ersetzen von Zeichenfolgen ist
nicht auf einzelne Buchstaben begrenzt. Im folgenden Beispiel wollen wir in dem String alle
DM durch Euro ersetzen (wenn das auch schon ein paar Tage her ist).

ausgabetext = "Der Preis für 2 Socken beträgt 5 DM und 5 Paar kosten 10 DM"
print(ausgabetext)
ausgabetext = ausgabetext.replace("DM", "Euro")
print("Nach dem Austauschen über replace():")
print(ausgabetext)

Als Ergebnis erhalten wir:

Der Preis für 2 Socken beträgt 5 DM und 5 Paar kosten 10 DM


Nach dem Austauschen über replace():
Der Preis für 2 Socken beträgt 5 Euro und 5 Paar kosten 10 Euro

Parameter von replace('x', 'y', [Anzahl])


Der dritte Parameter für die Anzahl ist Optional. Hier können wir festlegen, wie viele
Vorkommen des alten Wertes ersetzt werden soll. Wird dieser Parameter nicht angegeben,
werden alle Vorkommen ersetzt.

Beispiel: es sollen nur die erste 3 Vorkommen ersetzt werden:

ausgabetext = "Der Preis für 2 Socken beträgt 2 DM und 2 Paar kosten 3.50 DM"
ausgabetext = ausgabetext.replace("DM", "Euro")
ausgabetext = ausgabetext.replace("2", "zwei", 2)
print("Nach dem Austauschen über replace():")
print(ausgabetext)

Als Ergebnis erhalten wir:

Der Preis für zwei Socken beträgt zwei Euro und 2 Paar kosten 3.50 Euro

Mehrere Ersetzungen durchführen


Bei der Methode replace() können wir nur eine Ersetzung mitgeben. Was aber, wenn
mehrere Ersetzungen gewünscht sind. In unserem Beispiel sollen die Zahl 1,2 und 3
ausgeschrieben werden. Es soll also jede „1“ durch „eins“ und jede „2“ durch „zwei“ und jede
„3“ durch „drei“ ersetzt werden. Welche Möglichkeiten haben wir dafür?
© https://www.python-lernen.de/string-replace.htm Seite 57

ausgabetext = "1 1 2 2 3 3 4 4"


ausgabetext = ausgabetext.replace("1", "eins")
ausgabetext = ausgabetext.replace("2", "zwei")
ausgabetext = ausgabetext.replace("3", "drei")
print("Nach dem Austauschen über replace():")
print(ausgabetext)

Als Ergebnis erhalten wir die gewünschten Ersetzungen:

eins eins zwei zwei drei drei 4 4

zweite Variante für mehrfache Ersetzungen


Die zweite Möglichkeit ist, einfach unsere Aufrufe hintereinander durchzuführen:

ausgabetext = "1 1 2 2 3 3 4 4"


ausgabetext = ausgabetext.replace("1","eins").replace("2","zwei").replace("3","drei"
print("Nach dem Austauschen über replace():")
print(ausgabetext)

Als Ergebnis erhalten wir wieder die gewünschten Ersetzungen:

eins eins zwei zwei drei drei 4 4


© https://www.python-lernen.de/methode-string-count.htm Seite 58

Zählen von bestimmten Vorkommen über die String-


Methode .count()
Wenn man wissen möchte, wie oft etwas in einem String vorkommt, hilft die Methode
.count() in Python weiter. In den Klammern gibt man das Gesuchte ein. Will man zum
Beispiel von unserem String mit den Variablennamen „inhalt“ wissen, wie viele „i“ in diesem
vorhanden sind bekommt man das im Handumdrehen über folgenden Code:

inhalt = "Hier kommt ein String-Inhalt"


print ( inhalt.count("i") )

Als Rückmeldung erhält man „3“. Der Buchstabe „i“ kommt also 3-mal in unserem String vor.

Wir können auch nach mehr als einem Buchstaben suchen. Natürlich gehen ganze Wörter oder
auch Wortteile wie z.B. „in“.

inhalt = "Hier kommt ein String-Inhalt"


print ( inhalt.count("in") )

Als Rückmeldung kommt:

Das Wort „in“ kommt 2-mal vor in unserem String:

Hier kommt ein String-Inhalt

Bei dem Wort „Inhalt“ haben wir ein weiteres „in“, das allerdings mit Großschreibung beginnt.
Mit der Großschreibung wird es allerdings nicht gefunden, sprich das „In“ von dem Wort
„Inhalt“ wurde nicht gefunden und somit auch nicht mitgezählt. Es gibt bei der Methode
.count() keinen optionalen Parameter, aber ein die entsprechende Methode zur
Umwandlung in Kleinbuchstaben haben wir bereits kennengelernt, mit der wir dies erreichen.

Gemeint ist die Methode .lower() . Hier unser Beispiel in Teilschritten:

inhalt = "Hier kommt ein String-Inhalt"


kleinbuchstaben = inhalt.lower()
print ( kleinbuchstaben )
print ( kleinbuchstaben.count("in") )

Optionale Parameter bei .count("teilstring", index_anfang=...,


index_ende=...)
Wollen wir nur innerhalb der ersten 15 Zeichen den String überprüfen lassen, können wir dies
über die optionalen Parameter für den Bereich (also Anfangspunkt und Endpunkt) erreichen:

inhalt = "Hier kommt ein String-Inhalt"


print ( inhalt.count("in", 0, 15) )

Es wird dann nur der Teil des Strings mit dem Inhalt „Hier kommt ein“ ausgewertet und dort
wird dann einmal der gesuchte Teilstring „in“ gefunden im letzten Wort „ein“.
© https://www.python-lernen.de/methode-string-count.htm Seite 59

Weitere Nutzungsmöglichkeiten
Die Methode .count() kann genauso bei Listen eingesetzt werden!
© https://www.python-lernen.de/methode-string-find.htm Seite 60

erstes Vorkommen bestimmen über die String-Methode


.find()
Wollen wir das erste Vorkommen bestimmen, können wir die Methode find() nutzen:

inhalt = "Hier kommt ein String-Inhalt"


print ( inhalt.find("e") )

Wir bekommen als Feedback:

Die Zählung beginnt bei 0, daher ist die dritte Stelle dann die Nummer 2.

Wollen wir das nächste Vorkommen von „e“ finden, können wir den Start mitgeben als weitere
Parameter:

inhalt = "Hier kommt ein String-Inhalt"


print ( inhalt.find("e", 3) )

Als Rückmeldung erhalten wir:

11

Bereiche können auch definiert werden. Wird die letzte Zahl negativ angegeben, erfolgt die
Zählung von hinten:

inhalt = "Hier kommt ein String-Inhalt"


print ( inhalt.find("i", 5, -10) )
© https://www.python-lernen.de/string-methoden-uebersicht-is.htm Seite 61

String auf Bedingungen testen


Es gibt verschiedene Abfragen um zu testen, ob ein bestimmtes Kriterium für einen String
vorliegt. Diese String-Methoden starten immer mit is…. .

Im Folgenden die Übersicht aller Methoden des Datentyp Strings und is…:

Methode Beschreibung

string.isalnum() Überprüft auf alphanumerische Zeichen (a-zA-Z0-9). Leerzeichen ist kein alphanumerisches
Zeichen!

string.isalpha() Überprüft auf alphabetische Zeichen (a-zA-Z). Leerzeichen ist kein alphanumerisches Zeichen!

string.isdecimal() Überprüft auf Zahlen – wenn alle Zeichen Dezimalzahlen sind, wird True zurückgeliefert

string.isdigit() Überprüft auf Numerische und digitale Zeichen z.B. ‚123‘ oder '3\u00B2' (was 3 hoch 2
entspricht!)

string.isidentifier() Ob ein Identifier vorliegt (siehe


https://docs.python.org/3.3/reference/lexical_analysis.html#identifiers)

string.islower() Überprüft, ob alles in Kleinschreibung vorliegt

string.isnumeric() Überprüft auf numerische Zeichen (z.B. 1/2, 3hoch2 etc.)

string.isprintable() Überprüft, ob Druckbar ist

string.isspace() Überprüft, ob nur Leerzeichen (u.ä.) vorhanden sind

string.istitle() Überprüft, ob es sich um eine Überschrift handelt

string.isupper() Überprüft, ob alles in Großschreibung vorliegt

Im Folgenden werden zwei Methoden beispielhaft vorgestellt:

isalnum() Methode: Test auf alphanumerische Zeichen


Liegen nur alphanumerische Zeichen vor? Wenn das zutrifft, wird „True“ als Rückgabewert
zurückgegeben. Alphanumerische Zeichen sind die Buchstaben („Alpha“) des Alphabets und
Zahlen („numerische“) von 0 bis 9 – daher Alphanumerisch.

inhalt = "Beispieltext"
ergebnis = inhalt.isalnum()
print(ergebnis)

Ergebnis:

True

Sobald Leerzeichen vorkommen, sind nicht mehr alle Zeichen alphanumerisch und somit
kommt beim folgenden Beispiel False zurück:

inhalt = "Beispieltext mit Leerzeichen"


ergebnis = inhalt.isalnum()
print(ergebnis)
© https://www.python-lernen.de/string-methoden-uebersicht-is.htm Seite 62

False

isalpha() Methode: Test auf Buchstaben (Alphabet)


Test, ob nur Buchstaben vorliegen, sprich das Alphabet verwendet wird. Zahlen und
Leerzeichen führen zu einem „False“, da diese nicht dazu gehören!

inhalt = "Beispieltext"
ergebnis = inhalt.isalpha()
print(ergebnis)

Ergebnis:

True

Und hier mit Zahl und somit trifft es nicht zu:

inhalt = "123Beispieltext"
ergebnis = inhalt.isalpha()
print(ergebnis)

False
© https://www.python-lernen.de/methode-string-split.htm Seite 63

Aufteilen von einem String in eine Liste .split()


Oft liegen uns Daten vor, die durch Komma getrennt sind. Beispielsweise ein Export von Excel
im Format CSV (englisch „comma separated values“).

Diesen String können wir einfach „aufspalten“ über split()

Die Methode split(Trennzeichen, Anzahl_Aufteilungen_maximal) hat 2


Parameter, die beide Optional sind. Schauen wir uns den ersten Parameter an. Über diesen
geben wir das gewünschte Trennzeichen mit.

daten = "vorname, nachname, alter"


einzeldaten = daten.split(",")
print(einzeldaten)

Als Ergebnis erhalten wir eine Liste. Listen lernen wir im Kapitel https://www.python-
lernen.de/listen.htm kennen.

['vorname', ' nachname', ' alter']

Achtet man nun genau auf den zurückgelieferten Inhalt, sieht man vor ' nachname' und ' alter'
jeweils ein Leerzeichen. Diese Leerzeichen sind oft unerwünscht, können aber sehr einfach mit
der Methode strip() entfernt werden. Oder man achtet bereits beim Ausgangsmaterial
darauf, dass keine Leerzeichen nach den Kommas vorhanden sind.

Wenn man allerdings sicher weiß, dass immer im Ausgangsmaterial nach dem Komma ein
Leerzeichen kommt, kann man dies auch als Parameter nutzen! Der Parameter kann also aus
einer beliebigen Zeichenkombination bestehen. Wir übergeben der Methode bei unserem
Beispiel neben dem Komma auch das Leerzeichen:

daten = "vorname, nachname, alter"


einzeldaten = daten.split(", ")
print(einzeldaten)

Als Ausgabe erhalten wir:

['vorname', 'nachname', 'alter']

erste Parameter bei split()


Bei der Methode split() sind zwei Parameter möglich und beide sind optional! Im letzten
Beispiel haben wir als ersten Parameter das gewünschte Trennzeichen vorgegeben. Diese
Angabe können wir auch weglassen. Schauen wir uns an, was passiert, wenn wir das letzte
Beispiel ohne Parameter ausführen lassen. Wir ändern nichts am Beispiel außer bei split()

daten = "vorname, nachname, alter"


einzeldaten = daten.split()
print(einzeldaten)

Als Ergebnis erhalten wir nun:

['vorname,', 'nachname,', 'alter']


© https://www.python-lernen.de/methode-string-split.htm Seite 64

Wird also split() ohne Parameter aufgerufen, erfolgt eine Trennung bei jedem Leerzeichen!
Jetzt werden die Kommas als Inhalt angesehen und sind bei der Liste in „vorname,“ und
„nachname,“ gelandet.

Interessant ist noch, dass mehrere Leerzeichen (falls vorhanden) als eines angesehen werden.
Wir erhalten das gleiche Ergebnis wie oben bei folgenden String:

daten = "vorname, nachname, alter"

zweiter Parameter: Anzahl_Aufteilungen_maximal


Beim zweiten Parameter von split(Trennzeichen,
Anzahl_Aufteilungen_maximal) können wir festlegen, wie viele Aufteilungen wir gerne
maximal bekommen möchten. Wird nichts angegeben (was dem Standard von -1 entspricht)
erhalten wir alle möglichen. Wären 2 möglich (wie bei unseren vorherigen Beispielen) und wir
geben 1 an, erhalten wir auch nur noch eine Aufsplittung:

daten = "vorname,nachname,alter"
einzeldaten = daten.split(",", 1)
print(einzeldaten)

Als Ergebnis bekommen wir auch genau eine Teilung:

['vorname', 'nachname,alter']

Wir bekommen also als Anzahl von Listenelemente unsere Anzahl von Trennungen + 1.

Anzahl Wörter in einem Text über split()


Über die Methode split() ist es sehr einfach, die Anzahl der Wörter in einem Text zu
bestimmen. Wir wissen, dass Leerzeichen die Trennung zwischen Wörtern in einem Text
darstellen. Also nutzen wir das Leerzeichen als Trennzeichen in split() und können danach
über len() die Anzahl der Elemente (sprich Wörter) zählen.

inhalt = "Anzahl Wörter in einem Text zählen!"


woerter = inhalt.split()
print("Anzahl der Wörter: ", len(woerter))
© https://www.python-lernen.de/methode-string-endswith.htm Seite 65

„Endet mit“-Methode: Strings auf Suffix überprüfen mit


.endswith()
Die Methode .endswith() liefert „True“ zurück, wenn das gesuchte Ende vorhanden ist.
Ansonsten kommt als Rückgabewert „False“.

Die englische Zusammenziehung liest sich ungewohnt. Übersetzt man es ein wenig „holprig“
ins deutsche, ist die Funktion der Methode klar: ends = wird beendet, endet / with = mit

Also einfach die Methode „endet-mit“.

Syntax von endswith()


string.endswith(Suffix[, Startposition[, Endposition]])

Wir haben also 3 Parameter:

Suffix (muss angegeben werden): zu überprüfende Zeichenfolge

Startposition (optional): Startpunkt, ab dem überprüft wird

Endposition (optional): Endpunkt, bis zu dem überprüft wird

Anhand eines Beispiels wird die Anwendung klarer.

inhalt = "https://www.python-lernen.de"
ergebnis = inhalt.endswith(".de")
print(ergebnis)

Wir bekommen als Ergebnis zurückgeliefert:

True

Wir können also überprüfen, ob es zutrifft (hier in unserem Fall, ob es eine deutsche
Domainendung ist).

Damit können wir auch in eine if -Abfrage gehen oder in eine while -Schleife.

Anfangs- und Endposition einsetzen


Je nach Fall ist es manchmal geschickt, die Anfangs- und Endposition für die Überprüfung
festzulegen. Geben wir hier 28 als Ende an, bekommen wir weiterhin „True“ zurück, da unser
String 28 Zeichen lang ist.

inhalt = "https://www.python-lernen.de"
ergebnis = inhalt.endswith(".de", 0, 28)
print(ergebnis)

Sobald wir 27 eingeben haben wir zur Überprüfung nur noch „…python-lernen.d“ – und somit
kein „.de“ mehr.

Mehrere Fälle überprüfen


Diese Methode kann auch mit Tupel’s eingesetzt werden. Hört sich kompliziert an, ist aber in
der Praxis sehr einfach und wird öfters benötigt. Was ist ein Tupel? Ein Tupel ist eine
© https://www.python-lernen.de/methode-string-endswith.htm Seite 66

Wertesammlung.

Nehmen wir an, wir wollen unseren String überprüfen, ob die URL mit einer dieser Endungen
endet:

.de

.com

.net

Also nehmen wir alle 3 Fälle (unsere Wertesammlung) auf und es soll, wenn einer der Fälle
zutrifft „True“ zurückgeliefert werden. Wir erstellen aus unseren Fällen ein Tupel (siehe
entsprechendes Kapitel https://www.python-lernen.de/tupel.htm)

Unser Tupel aus den 3 Domainendungen:

datentyp_tupel = (".de", ".com", ".net")

Dieses Tupel wird nun in unsere Methode .endswith() eingesetzt:

inhalt = "https://www.python-lernen.de"
datentyp_tupel = (".de", ".com", ".net")
ergebnis = inhalt.endswith(datentyp_tupel)
print(ergebnis)

Jetzt kann die URL auf „.de“ oder auf „.com“ oder auf „.net“ enden und wir erhalten ein „True“
zurück.

Öfters wird man diese Konstruktion sehen. Hier ist schneller ersichtlich, dass ein Tupel
eingesetzt wird:

inhalt = "https://www.python-lernen.de"
ergebnis = inhalt.endswith((".de", ".com", ".net"))
print(ergebnis)
© https://www.python-lernen.de/methode-string-startswith.htm Seite 67

„Beginnt mit“-Methode: Stringanfang überprüfen mit


.startswith()
Die Methode .startswith() liefert „True“ zurück, wenn das Gesuchte am Anfang des
Strings vorhanden ist. Ansonsten kommt als Rückgabewert „False“.

Die englische Zusammenziehung liest sich ungewohnt. Übersetzt man es ein wenig „holprig“
ins deutsche, ist die Funktion der Methode klar:

starts = startet, beginnt

with = mit

Also einfach die Methode „Beginnt-mit“.

Wir können also Überprüfen, ob bei einem String der Anfang einer von uns bestimmten
Zeichenfolge entspricht.

Nehmen wir an, wir haben als String als Text eine URL und wollen überprüfen, ob diese mit
„https://“ startet.

inhalt = "https://www.python-lernen.de"
ergebnis = inhalt.startswith("https://")
print(ergebnis)

Als Rückmeldung erhalten wir „True“, da die Überprüfung korrekt war. Würde die URL
allerdings mit „http://“ starten, kommt ein „False“ zurück:

inhalt = "http://www.python-lernen.de"
ergebnis = inhalt.startswith("https://")
print(ergebnis)

Wie schon bei der Methode „.endswith()“ gibt es weitere Parameter.

Suffix (muss angegeben werden): zu überprüfende Zeichenfolge

Startposition (optional): Startpunkt, ab dem überprüft wird

Endposition (optional): Endpunkt, bis zu dem überprüft wird

Wir können also auch festlegen, ab welcher Position angefangen wird, die Überprüfung zu
starten und bis zu welcher Position.

Mehrere Fälle überprüfen mit .startswith()


Im obigen Beispiel haben wir schon gesehen, dass es mehrere Fälle geben kann. In unserem
Beispiel kann eine Internetadresse mit „https://“ oder mit „http://“ beginnen. Klar wäre es
jetzt einfach nur auf „http“ zu überprüfen. Wenn wir allerdings sicherstellen wollen, dass
auch der „://“ für eine korrekte URL vorhanden ist, dann haben wir diese beiden Fälle:

https://

http://

Und diese beide Fälle können wir als Tupel (siehe entsprechendes Kapitel) schreiben:

urlanfang_als_tupel = ("https://", "http://")


© https://www.python-lernen.de/methode-string-startswith.htm Seite 68

Und genau dieses Tupel können wir als Kontrollwert unserer Methode .startswith()
übergeben und erhalten ein „True“ als Rückgabewert, wenn einer der Werte des Tupels
zutrifft.

inhalt = "https://www.python-lernen.net"
urlanfang_als_tupel = ("https://", "http://")
ergebnis = inhalt.startswith(urlanfang_als_tupel)
print(ergebnis)

Öfters ist auch die Methode in der folgenden Schreibweise anzutreffen (auf die 2 runden
Klammern achten!):

inhalt = "https://www.python-lernen.net"
ergebnis = inhalt.startswith(("https://", "http://"))
print(ergebnis)
© https://www.python-lernen.de/string-methode-expandtabs.htm Seite 69

Python String Methode .expandtabs() zum Umwandeln


von Tabs in Leerzeichen
Über die Methode expandtabs() werden alle in einem Strings enthaltene Tabs (\t) in
Leerzeichen umgewandelt. Es werden 8 Leerzeichen für einen Tab genutzt, sofern man keine
andere Angabe als Parameter mitgibt:

string.expandtabs([Anzahl_Leerzeichen])

Schauen wir es uns als Beispielcode an:

inhalt = "Textinhalt\t1234567890\tmehr Inhalt"


ergebnis = inhalt.expandtabs()
print(ergebnis)

Als Ergebnis erhalten wir folgende Ausgabe:

Textinhalt 1234567890 mehr Inhalt

Parameter bei expandtabs()


Über den Parameter kann man die gewünschte Anzahl an Tabs angeben, wenn man eine
andere Anzahl als 8 (was der Standardeinstellung entspricht), gerne hätte.

Beispiele:
© https://www.python-lernen.de/string-methode-expandtabs.htm Seite 70

inhalt = "Textinhalt\t1234567890\tmehr Inhalt"


print("01234567890123456789012345678901234567890123456789")
print(inhalt.expandtabs(), " (Standardeinstellung 8)\n")

print("01234567890123456789012345678901234567890123456789")
print(inhalt.expandtabs(2), " (Tabstopp bei 2)\n")

print("01234567890123456789012345678901234567890123456789")
print(inhalt.expandtabs(3), " (Tabstopp bei 3)\n")

print("01234567890123456789012345678901234567890123456789")
print(inhalt.expandtabs(4), " (Tabstopp bei 4)\n")

print("01234567890123456789012345678901234567890123456789")
print(inhalt.expandtabs(5), " (Tabstopp bei 5)\n")

print("01234567890123456789012345678901234567890123456789")
print(inhalt.expandtabs(6), " (Tabstopp bei 6)\n")

print("01234567890123456789012345678901234567890123456789")
print(inhalt.expandtabs(7), " (Tabstopp bei 7)\n")

print("01234567890123456789012345678901234567890123456789")
print(inhalt.expandtabs(8), " (Tabstopp bei 8)\n")

print("01234567890123456789012345678901234567890123456789")
print(inhalt.expandtabs(9), " (Tabstopp bei 9)\n")

print("01234567890123456789012345678901234567890123456789")
print(inhalt.expandtabs(10), " (Tabstopp bei 10)\n")

Und als Ergebnis erhalten wir:


© https://www.python-lernen.de/string-methode-expandtabs.htm Seite 71

01234567890123456789012345678901234567890123456789
Textinhalt 1234567890 mehr Inhalt (Standardeinstellung 8)

01234567890123456789012345678901234567890123456789
Textinhalt 1234567890 mehr Inhalt (Tabstopp bei 2)

01234567890123456789012345678901234567890123456789
Textinhalt 1234567890 mehr Inhalt (Tabstopp bei 3)

01234567890123456789012345678901234567890123456789
Textinhalt 1234567890 mehr Inhalt (Tabstopp bei 4)

01234567890123456789012345678901234567890123456789
Textinhalt 1234567890 mehr Inhalt (Tabstopp bei 5)

01234567890123456789012345678901234567890123456789
Textinhalt 1234567890 mehr Inhalt (Tabstopp bei 6)

01234567890123456789012345678901234567890123456789
Textinhalt 1234567890 mehr Inhalt (Tabstopp bei 7)

01234567890123456789012345678901234567890123456789
Textinhalt 1234567890 mehr Inhalt (Tabstopp bei 8)

01234567890123456789012345678901234567890123456789
Textinhalt 1234567890 mehr Inhalt (Tabstopp bei 9)

01234567890123456789012345678901234567890123456789
Textinhalt 1234567890 mehr Inhalt (Tabstopp bei 10)

Auch wenn es so wirkt, als würde sich bei der Einstellung für dem Tabstopp für 2, 3 wie auch
bei 4 nichts ändern, passt das Verhalten durchaus. Im Beispiel liegt bei allen 3 Einstellungen
der Beginn nach dem ersten umgewandelten Tab bei 12. Und 12 ist ein Vielfaches von 2,3 und
4.

Bis zur Position 10 ist alles belegt durch den vorherigen Text plus eines Leerzeichens. Also
kann erst nach 10 der Tab „wirken“. Schauen wir uns die Reihen an:

Bei der 2er-Reihe:


2,4,6,8,10 (alles nicht möglich), 12 (und dort startet dann auch unser Text)

Bei der 3er-Reihe:


3,6,9 (alles nicht möglich), 12 (und dort startet dann auch unser Text)

Bei der 4er-Reihe:


4,8 (alles nicht möglich), 12 (und dort startet dann auch unser Text)

Bei der 6er-Reihe:


6 (nicht möglich), 12 (und dort startet dann auch unser Text)

Die 5er-Reihe ist anders, da hier unser Text bei 15 startet 5,10 (alles nicht möglich), 15 (startet
unser Text)
© https://www.python-lernen.de/string-methode-partition.htm Seite 72

String Methode partition() – String in Einzelteile zerlegen


Die Methode partition() erhalt als Parameter den Suchtext, anhand der komplette String
zerlegt werden soll.

string.partition("Suchtext")

Wir bekommen 3 Teile als Rückgabewerte:

alles vor dem Suchtext

den Suchtext

alles nach dem Suchtext

Schauen wir es am Beispiel an. Wir haben den Satz „Python ist einfach zu lernen“. Jetzt wollen
wir diesen Text zerlegen, und zwar bei dem Wort „ist“.

satz = "Python ist einfach zu lernen"


ergebnis = satz.partition("ist")
print(ergebnis)

Das Ergebnis ist als Datenform ein Tupel und wir erhalten:

('Python ', 'ist', ' einfach zu lernen')

Bitte ein Augenmerk darauf, dass nichts verloren geht! Es werden auch alle Leerzeichen um der
Suchwert „ist“ behalten. Dieser finden sich nach dem ersten Wert des Tupels nach „Python “
und vor dem dritten Wert „ einfach zu lernen“.

Suchtext öfters vorhanden – was passiert?


Was passiert nun eigentlich, wenn unser Suchtext öfters vorhanden ist? Erweitern wir unseren
Satz auf: „Python ist einfach zu lernen und ist cool“.

satz = "Python ist einfach zu lernen und ist cool"


ergebnis = satz.partition("ist")
print(ergebnis)

Im Ergebnis sieht man schön, dass nur das erste Auftreten des Suchtextes berücksichtigt wird.
Das zweite „ist“ in unserem Beispiel endet im dritten Rückgabewert des Tupels.

('Python ', 'ist', ' einfach zu lernen und ist cool')

Suchtext am Anfang sofort vorhanden


Was passiert, wenn der Suchtext sofort am Anfang unseres Strings vorhanden ist?

satz = "ist Python einfach zu lernen?"


ergebnis = satz.partition("ist")
print(ergebnis)

Hier wird das Ergebnis für das Verständnis der Funktion von .partition() wichtig. Als
Rückgabe-Tupel erhalten wir:
© https://www.python-lernen.de/string-methode-partition.htm Seite 73

('', 'ist', ' Python einfach zu lernen?')

Unser Suchtext ist in dem Tupel also immer der zweite Wert! Tritt er im Text in der ersten
Position auf, kommt vor ihm also nichts. Somit bleibt der erste Wert unseres Rückgabetupels
leer und im dritten Wert steht alles nach dem „ist“.

Suchtext nicht vorhanden


Wenn unser Suchtext nicht im Text vorkommt, ist die Reaktion der partition() -Methode,
dass im Ergebnis alles im ersten Bereichs unseres Tupels landet und der zweite Wert des
Tupels leer bleibt. Unsere Suche war ja nicht erfolgreich und im zweiten Wert steht immer das
erfolgreich gesuchte Wort:

satz = "Ist Python einfach zu lernen?"


ergebnis = satz.partition("ist")
print(ergebnis)

Ergebnis:

('Ist Python einfach zu lernen?', '', '')

Man sieht an diesem Beispiel auch, dass Groß- und Kleinschreibung einen Unterschied macht.

Fehlermeldung „ValueError: empty separator“


Die Methode partition() benötigt einen Parameter (für den Suchtext), ansonsten erhält
man als Fehlermeldung „ValueError: empty separator“. Das passiert, wenn ein leerer Suchtext
übergeben wird: ergebnis = satz.partition("") .

Gibt man anstelle des Suchtextes keinen Parameter ein ergebnis = satz.partition() ,
erhält man die Fehlermeldung: „TypeError: partition() takes exactly one argument (0 given)“

Für das Aufspalten muss also ein sinnvoller Wert mitgegeben werden. Wobei ein Leerzeichen
auch ein sinnvoller Wert ist:

satz = "Ist Python einfach zu lernen?"


ergebnis = satz.partition(" ")
print(ergebnis)

Er wird dann einfach beim ersten Leerzeichen aufgeteilt. Unser Ergebnis:

('Ist', ' ', 'Python einfach zu lernen?')

Die Methode partition() bietet viele Möglichkeiten im praktischen Einsatz. Einfach im


Hinterkopf behalten, dass es diese Methode gibt.
© https://www.python-lernen.de/string-methode-join.htm Seite 74

Zusammenfügen von Zeichenketten über join()


Die Methode join() ist extrem hilfreich, um Zeichenketten zusammenzufügen. Wir
erhalten als Rückgabe ein String. Was sich so beiläufig anhört, ist extrem wichtig. Denn wir
können join() mit verschiedenen Datentypen „füttern“ und bekommen eine Zeichenkette
zurück!

Befehlsaufbau:

str = trennzeichen.join(Aufzählung)

Beispiel: Einsatz von join() mit dem Datentyp Liste

wortliste = ['Axel', 'Elke', 'Martin']


trennzeichen = '#'
ergebnis = trennzeichen.join(wortliste)
print(ergebnis)

Als Ergebnis erhalten wir zurück:

Axel#Elke#Martin

Wir erhalten aus dem Datentyp Liste eine String. Die einzelnen Elemente sind durch „#“
getrennt.

Die Nutzung von join() ist anhand von dem Datentyp Listen einfacher verständlich und die
Mächtigkeit der Methode schnell klar. Es funktioniert genauso mit Zeichenketten („Strings“).
Allerdings wird jedes Zeichen des Textes getrennt durch das Trennzeichen vom nächsten
Zeichen:

zeichenkette = "abcd"
trennzeichen = '#'
ergebnis = trennzeichen.join(zeichenkette)
print(ergebnis)

Als Ergebnis erhalten wir:

a#b#c#d

Wir können die Datentyp „List“, „Tupel“, „String“, „Dictionary“ und „Set“ nutzen und join()
übergeben.

beliebige Anzahl von Trennzeichen


Dabei kann auch mehr als 1 Trennzeichen angegeben werden. Die Nutzung von
trennzeichen = ' #123# ' führt beispielsweise zu „Axel #123# Elke #123# Martin“.

wortliste = ['Axel', 'Elke', 'Martin']


trennzeichen = ' #123# '
ergebnis = trennzeichen.join(wortliste)
print(ergebnis)

Und als Ergebnis erhalten wir:


© https://www.python-lernen.de/string-methode-join.htm Seite 75

Axel #123# Elke #123# Martin

Datentyp Dictionary und Fallstricke bei join()


Der Datentyp Dictionary (auf deutsch „Wörterbuch“ bzw. assoziative Liste) kann als Inhalte
sowohl Strings wie Werte haben. Besteht das Wörterbuch nur aus Strings, haben wir kein
Problem. Wichtig ist nur zu wissen, dass immer bei dem Datentyp Dictionary der „key“
verwendet wird.

deutschenglisch = { 'null': 'zero', 'eins': 'one' }


trennzeichen = '#'
print(trennzeichen.join(deutschenglisch))

Und als Ergebnis erhalten wir:

null#eins

Ist der Inhalt allerdings numerisch, bekommen wir eine Fehlermeldung!

woerterbuch = {0: 'null', 1: 'eins' }


trennzeichen = '#'
print(trennzeichen.join(woerterbuch))

Anstelle eines Ergebnisses erhalten wir die Fehlermeldung: „TypeError: sequence item 0:
expected str instance, int found“
© https://www.python-lernen.de/operatoren-strings.htm Seite 76

Operatoren für Strings


Lustigerweise kann man in Python auch mit Operatoren (+-*/) auf Zeichenkettenausgaben
losgehen. Was passiert, wenn man folgende Anweisung schreibt?

print( 3 * 'mi' );

Nun erfolgt als Ausgabe

mimimi

Ein Operator ist eine mathematische Vorschrift. So steht das „*“ wie üblich in der Mathematik
für die Multiplikation – wenden wir diese Multiplikation in Python auf einen Text an, wird dieser
entsprechend oft wiederholt.

Anmerkung am Rande – wem "mimimi" nichts sagt, unbedingt die Videos der Muppets
ansehen unter https://www.youtube.com/watch?v=VnT7pT6zCcA.

Jetzt können wir auch noch dahinter ein Plus packen:

print( 3 * 'mi' + 'mo' );

Nun kommt als Ausgabe

mimimimo

Gibt man 2 Strings hintereinander an:

print( 'mi' 'mo' );

Werden bei zusammen hintereinander ausgegeben. Im Vergleich zu anderen


Programmiersprachen benötigen wir kein zusätzliches Zeichen, um mehrere Zeichenketten
miteinander zu verketten. In JavaScript würde man mit einem Pluszeichen arbeiten, in PHP mit
einem Punkt verketten. Python macht es einfacher.

Allerdings funktioniert das bei 2 Variablen nicht und es gibt eine Fehlermeldung. Versucht man
bei Variablen folgende Programm:

variable1 = "ich"
variable2 = "du"
print( variable1 variable2 )

Es kommt nun die Fehlermeldung "SyntaxError: invalid syntax".

Es klappt dann wieder, wenn wir ein Pluszeichen mitgeben. Daher bietet es sich an, das
Pluszeichen immer zu machen (auch bei Zeichenketten, wo es eigentlich ohne gehen würde).

variable1 = "ich"
variable2 = "du"
print( variable1 + variable2 )

Beispielanwendung: Funktionsgrafen ausgeben ohne Grafik


Natürlich kann man sich fragen, wofür man die Wiederholung von Ausgaben benutzen könnte.
Eine einfache (und manchmal ausreichende) Variante ist die Ausgabe einer Kurve.
© https://www.python-lernen.de/operatoren-strings.htm Seite 77

Im Folgendem ein kleines Beispiel: Nicht besonders schön programmiert, aber es funktioniert.
Schöner geht es dann, wenn wir im Kurs Schleifen kennengelernt haben.

print( 'Ausgabe Kurve ohne Grafik' );

print( 3 * '*' );
print( 5 * '*' );
print( 8 * '*' );
print( 9 * '*' );
print( 10 * '*' );
print( 9 * '*' );
print( 8 * '*' );
print( 5 * '*' );
print( 3 * '*' );
© https://www.python-lernen.de/grundrechenarten-in-python.htm Seite 78

Grundrechenarten: Rechnen mit Zahlen


Wir können in Python wie aus der Grundschule gewohnt ganz einfach rechnen.

Addition und Subtraktion


Für eine Addition machen wir in der Kommandozeile einfach folgende Eingabe:

3 + 3

Als Ergebnis erhalten wir "6".

Die komplette Form wäre eigentlich:

print(3 + 3)

Der Übersichtlichkeit halber wird in diesem Kapitel immer die kurze Form verwendet.

Das klappt natürlich auch mit Minus (dann allerdings kommt ein anderes Ergebnis raus).

3 - 3

Multiplizieren
Irgendwann kam in der Schule noch multiplizieren und teilen im Mathematikunterricht. Auch
das können wir mit den gewohnten mathematischen Zeichen bewirken:

3 * 3

Und als Ergebnis erhalten wir "9"

Division
Und wir bereits in der Schule ist ein Teilen durch das "/" möglich aber auch in Python ist ein
Teilen durch 0 nicht möglich.

3/3

Ergibt als Ergebnis "1". Versuchen wir durch "0" zu teilen, bekommen wir eine Fehlermeldung!

3/0

Dies führt zu einer Fehlermeldung "Traceback …" mit einer Angabe der Programmzeile („line
X“), wo der Fehler aufgetreten ist. Zusätzlich bekommen wir die Fehlerbezeichnung in Englisch.
In diesem Fall dann "ZeroDivisionError: … division by zero".

Modulo in Python
Sehr viel später in der Schule ist ein Teilen mit "Rest" angesagt. Mathematiker würden diese
mathematische Funktion als Modulo (mod) bezeichnen, die als Ausgabe den Rest bei einer
Division ganzer Zahlen als Rückgabe liefert.

Im folgenden Beispiel wird es nachvollziehbar und verständlich. Die Schreibweise von Modulo
ist das Prozentzeichen. Wir wollen nun den Rest der Division von 7 und 2 erhalten:

7%2
© https://www.python-lernen.de/grundrechenarten-in-python.htm Seite 79

Als Ergebnis bekommen wir „1“. Die 2 geht 3-mal komplett in die 7 - sprich 2+2+2 ergibt 6 und
dann bleibt von der 7 eine 1 übrig.

Wir können auch anstelle des Rests die Anzahl erhalten, wie oft die Zahl in zu teilende Zahl
„komplett rein geht“. Bei unserem obigen Beispiel mit

7//2

erhalten wir dann 3. Unsere 2 geht 3-mal in die 7 und der Rest wird ignoriert. Jetzt haben wir
auch schon die Schreibweise eingeführt. Hier haben wir einfach 2 x "/".

Diese 2 Funktionen klappen nur mit ganzzahligen Zahlen.

Hoch irgendwas
Was fehlt noch an den typischen Funktionen? Das typische "hoch" – sprich in der netten
mathematischen Schreibweise 23. Hier haben wir dann als Schreibweise in Python:

2**3

Gerechnet wird intern "2 * 2 * 2" und als Ergebnis erhalten wir "8". Bei 3 2 erhalten wir 9.

Quadratwurzel
Wer jetzt noch das Wurzelziehen vermisst. Die Quadratwurzel ist der einfachste Fall. Der läuft
über den Kniff mit 0.5

Also als Schreibweise:

9**0.5

Als Ergebnis bekommen wir die „3“. Hier sehen wir auch, dass die Schreibweise in Python
immer mit Punkt geschrieben werden – im Deutschen spricht man von Nachkommazahlen!
Wir haben also in Python „NachPUNKTzahlen“.

Möchte man nicht nur die Quadratwurzel ziehen, dann wird das Modul „math“ benötigt, dass
erst später im Kurs eingeführt wird. Der Vollständigkeit halber einfach hier die Schreibweise:

import math as m
print(m.sqrt(25))

Das so weit zu den Grundrechenarten und der Anwendung in Python.

TIPP: Große Zahlen gut lesbar


Sobald wir im Millionenbereich sind, werden große Zahlen schlecht lesbar. In Python können
wir den Unterstrich (_) dafür nutzen, dass die Zahl gut lesbar wird, aber für die Berechnung ist
dieser Strich komplett egal. Einfach einmal probieren:
© https://www.python-lernen.de/grundrechenarten-in-python.htm Seite 80

# schlecht lesbar
zahl1 = 1000000
zahl2 = 100000000
print(zahl1 + zahl2)

# gut lesbar
zahl3 = 1_000_000
zahl4 = 100_000_000
print(zahl3 + zahl4)

# beides mal das gleiche Ergebnis!


# 101000000

Es ist und bleibt auch eine Integer-Zahl. Mit der Anweisung type() können wir den Variablen-
Typ anfragen.

zahl3 = 1_000_000
print(type(zahl3))

Als Ergebnis kommt:

<class 'int'>
© https://www.python-lernen.de/listen.htm Seite 81

Listen in Python – viele Inhalte geordnet speichern


Wir haben mit Variablen die Möglichkeit kennen gelernt, in einem Platzhalter (sprich die
Variable) Inhalt zu speichern. Allerdings kann jede Variable nur einen Inhalt haben. Das kann je
nach Fall unpraktisch werden.

Wenn man sich vorstellt, dass man ein Telefonbuch in Variablen speichern möchte, dann hätte
man wilde Konstruktionen wie:

vorname1 = 'Axel'
vorname2 = 'Elke'
vorname3 = 'Martin'

Aber wo soll das enden? Das wäre als eine wenig handliche Vorgehensweise. Und daher gibt
es sogenannte „Listen“ in Python. Wer schon eine andere Programmiersprache kennt, hier wird
diese Möglichkeit Array genannt.

Wie können wir in Python nun in Listen Inhalte speichern? Ganz einfach über die eckigen
Klammern

vornamen = ['Axel', 'Elke', 'Martin']

Die Ausgabe kann wie gewohnt über print() erfolgen:

vornamen = ['Axel', 'Elke', 'Martin']


print(vornamen)

Es werden nun alle Vornamen ausgegeben. Wollen wir nun nur einen bestimmten Vornamen
ausgeben, müssen wir die Index-Nummer mitgeben. Diese wird in einer eckigen Klammer
geschrieben.

vornamen = ['Axel', 'Elke', 'Martin']


print(vornamen[1])

Das Ergebnis der Ausgabe ist nun:

Elke

Warum nicht das erste Element unserer Liste, was ja offensichtlich den Inhalt „Axel“ enthält?
Hier ist es wichtig, dass Computer immer bei 0 anfangen zu zählen, insbesondere bei Listen.
Wollen wir also das erste Element unserer vornamen-Liste erhalten, müssen wir als Index 0
angeben:

vornamen = ['Axel', 'Elke', 'Martin']


print(vornamen[0])

Jetzt bekommen wir das erste Element der Liste. Daher der wichtige Merksatz

MERKE: Listenelemente fangen immer beim Index 0 an!

letztes Listenelement ansprechen


Wir können auch von hinten anfangen etwas ausgeben. Und hier fängt man mit -1 an! Somit
wird das letzte Element ausgegeben:
© https://www.python-lernen.de/listen.htm Seite 82

vornamen = ['Axel', 'Elke', 'Martin']


print(vornamen[-1])

Somit bekommen wir als Ausgabe unseren „Martin“.

Listenwerte überschreiben
Wollen wir einen bestehenden Listeneintrag überschreiben, weil aus dem Martin eine Martina
geworden ist, können wir das über die Index-Nummer und einer neuen Wertzuweisung machen:

vornamen = ['Axel', 'Elke', 'Martin']


vornamen[2] = 'Martina'

Lassen wir nun unsere Liste mit print() ausgeben:

vornamen = ['Axel', 'Elke', 'Martin']


vornamen[2] = 'Martina'
print(vornamen)

kommt der Liste mit dem geänderten Wert:

['Axel', 'Elke', 'Martina']

Listen durch weitere Elemente erweitern


Wir können Python-Listen einfach über das Pluszeichen erweitern.

vornamen = ['Axel', 'Elke', 'Martin']


vornamen += ['Heike', 'Sabine']

Nun wird die bestehende Liste um diese 2 Elemente erweitert. Lassen wir die Liste ausgeben,
erhalten wir:

['Axel', 'Elke', 'Martina', 'Heike', 'Sabine']

Die Schreibweise "vornamen +=" ist die Kurzschreibweise von

vornamen = vornamen + ['neue Werte']

Python stellt verschiedene Funktion für Listen zur Verfügung. Hier gibt es eine Funktion zum
Erweitern von Listen: listenname.append('neuer Wert') . Als konkretes Beispiel sieht
das nun so aus:

vornamen = ['Axel', 'Elke', 'Martin']


vornamen.append('Rolf')

Komplette Liste löschen: del()


Wird eine komplette Liste nicht mehr benötigt bzw. soll diese im nachfolgenden Code wieder
neu aufgebaut werden, kann die alte Liste gelöscht werden. Dies geschieht über die Funktion
del()
© https://www.python-lernen.de/listen.htm Seite 83

Unser Beispiel von oben wandeln wir ab. Wir wollen nicht mehr die bestehende Liste mit den
Vornamen erweitern, sondern durch einen komplett anderen Inhalt ersetzen:

vornamen = ['Axel', 'Elke', 'Martin']


print(vornamen)

del(vornamen)
vornamen = ['Heike', 'Sabine']
print(vornamen)

Als Ergebnis erhalten wir:

['Axel', 'Elke', 'Martina']


['Heike', 'Sabine']
© https://www.python-lernen.de/listen-methoden.htm Seite 84

mit Listen arbeiten – Einsatz von Methoden


Im letzten Kapitel haben wir Listen kennengelernt und deren grundsätzliche Möglichkeiten. Da
geht aber noch deutlich mehr und sehr einfach.

Wir haben eine Liste erstellt und komplett ausgegeben über:

vornamen = ['Axel', 'Elke', 'Martin']


print(vornamen)

Eine Liste erweitert über:

vornamen = ['Axel', 'Elke', 'Martin']


vornamen += ['Heike', 'Sabine']
print(vornamen)

Und ein einzelnes Element der Liste ausgegeben.

Wichtig war, dass der Index einer Liste immer bei 0 beginnt!

Im Folgenden lernen wir alle wichtigen Möglichkeiten der Listen-Methoden kennen:

Element in Liste am Ende einfügen

Element an bestimmter Position in Liste einfügen

Element vom Listenende löschen

Element von bestimmter Position der Liste löschen

Element anhand vom Wert aus einer Liste löschen

Aber was sind Methoden?

Methoden und Listen


Bisher sind wir im Python Kurs noch nicht direkt auf Methoden zu sprechen gekommen. Aber
was sind diese Methoden, die es in jeder Programmiersprache gibt? Sucht man nach
Synonymen von dem Wort „Methode“ stößt man auf „Vorgehen, Arbeitsweise und
Handhabung“. Wir können also auf ein bestimmtes Objekt (in unserem Fall sind die Objekte der
Begierde die Listen) vorgegebene Methoden (sprich Möglichkeiten) anwenden. Wer sich schon
ein bisschen mit objektorientierter Programmierung auseinandergesetzt hat, kennt das. Wir
haben ein Objekt und das Objekt hat einerseits Inhalt (sprich Attribute) und mögliche
vordefinierte Funktionen (sprich Methoden).

Und hier kommt auch die Schreibweise zum Vorschein. Als Erstes wird das Objekt genannt und
dann wird die Methode an dieses Objekt mit einem Punkt „verkettet“. Gegebenenfalls kann
man noch weitere Parameter für die Funktionsweise der Methode mit übergeben. Klarer wird
es im konkreten Beispiel (natürlich hier mit Listen).

Nutzen wir die Liste mit den Vornamen und lassen uns den zweiten Namen (sprich
Indexnummer 1) ausgeben:

vornamen = ['Axel', 'Elke', 'Martin']


print(vornamen[1])

Jetzt wenden wir die Methode upper() auf unser Objekt (in diesem Fall einen String) an.
Unsere Ausgabe vom Listenobjekt mit dem Index 1 wird mit der Methode „schreib alles groß“
bzw. upper() verbunden:
© https://www.python-lernen.de/listen-methoden.htm Seite 85

vornamen = ['Axel', 'Elke', 'Martin']


print(vornamen[1].upper())

Als Ergebnis bekommen wir:

ELKE

Der Inhalt der Liste selber ändert sich nicht, sondern nur die Ausgabe wird in Großschreibung
gebracht.

Hier haben wir das erste Beispiel für eine Methode, die keine weiteren Angaben braucht. Es soll
ja einfach alles in Großbuchstaben geschrieben werden.

Schauen wir im nächsten Beispiel Methoden an, die weitere Angaben benötigen, damit sie ihre
Funktion auch erfüllen können.

Weiterer Eintrag am Ende einer Liste anhängen: append()


Wir wollen in einer Liste einen weiteren Eintrag anhängen. Dazu gibt es eine Methode mit dem
Namen append() . Hier ist sofort einsichtig, dass wir etwas übergeben müssen, was dann an
die bestehende Liste angehängt werden wird. Unsere „Anhäng-Methode“ wird also immer mit
zusätzlichem Parameter in Erscheinung treten: append('anzuhängende Eintrag')

Wir erstellen eine leere Liste mit dem Namen „buchstaben“.

buchstaben = []
print(buchstaben)

Wir haben also mit der Liste „buchstaben“ ein Objekt. Diesem Listenobjekt wollen wir einen
weiteren (in diesem Fall den ersten) Eintrag anhängen. Also wenden wir append() an:

buchstaben = []
print(buchstaben)
buchstaben.append('a')
buchstaben.append('b')
print(buchstaben)

Als Ausgabe erhalten wir:

[]
['a', 'b']

In der ersten Zeile sehen wir, dass eine leere Liste existiert.

Dann wird über append() zweimal ein Buchstabe angefügt. Dieser wird jeweils am Ende der
Liste eingetragen!

Element in Liste an bestimmte Position einfügen: insert()


Wollen wir nicht am Ende, sondern an einer vordefinierten Stelle Inhalt in der Liste einfügen,
kommt die Methode insert() zum Einsatz.
© https://www.python-lernen.de/listen-methoden.htm Seite 86

Weil es so schön übersichtlich ist, nutzen wir wieder unser Buchstabenbeispiel und wollen nun
in der bestehenden Liste mit ['a', 'b'] ein „c“ zwischen „a“ und „b“ schieben (sprich einfügen).

Jetzt benötigen wir bei der Methode insert() bereits 2 Parameter:

was soll eingefügt werden

wo soll es einfügt werden

Beide Angaben werden in den Runden Klammern der Methode mit übergeben. Vergisst man
Angaben, erhält man den Fehler „TypeError: insert() takes exactly 2 arguments (1 given)“. Die
Reihenfolge ist:

wo soll es eingefügt werden als Index

was soll eingefügt werden

buchstaben = ['a', 'b']


print(buchstaben)
buchstaben.insert(1, 'c')
print(buchstaben)

Das Programm ergibt dann folgende Ausgabe:

['a', 'b']
['a', 'c', 'b']

Element aus Liste entfernen: del


Genauso wichtig wie einfügen ist auch das Löschen. In vielen Spielen werden Daten in Listen
gespeichert. Sind die Gegner in Listen gespeichert und fällt ein Gegner einem heimtückischen
Anschlag zum Opfer und verstirbt tragisch, muss dieser aus der Liste entfernt werden. Dazu
bietet Python die Anweisung del , der ein Index mit übergeben werden muss, welches
Listenelement gelöscht werden soll. Unser Buchstabenbeispiel:

buchstaben = ['a', 'b']


print(buchstaben)
del buchstaben[0]
print(buchstaben)

Und als Ergebnis kommt:

['a', 'b']
['b']

Hier wurde mal eine Anweisung (und keine Methode eingeschmuggelt)! Aber es gibt auch
Methoden, um Elemente aus Listen zu löschen.

Letztes Element aus Liste entfernen: pop()


Der Vorteil unserer Methode pop() ist, dass wir als Rückgabewert den Inhalt des gelöschten
letzten Listeneintrags bekommen und damit weiterarbeiten können (wenn wir das wollen).
© https://www.python-lernen.de/listen-methoden.htm Seite 87

Wichtig ist, pop() löscht immer den letzten Eintrag!

buchstaben = ['a', 'b']


print(buchstaben)
letztereintrag = buchstaben.pop()
print(buchstaben)
print("Letzter gelöschter Eintrag: ", letztereintrag)

Und als Ausgabe kommt:

['a', 'b']

['a']

Letzter gelöschter Eintrag: b

Elemente aus Liste entfernen anhand seines Wertes: remove()


Wir können auch ein Element anhand seines Wertes aus einer Liste entfernen lassen. Dazu
wird der Wert mit übergeben:

buchstaben = ['a', 'b', 'c']


print(buchstaben)
buchstaben.remove('b')
print(buchstaben)

Ergibt als Ergebnis:

['a', 'b', 'c']


['a', 'c']

Versuchen wir einen Wert zu löschen, der nicht in der Liste existiert, erhalten wir die
Fehlermeldung „buchstaben.remove('e')
ValueError: list.remove(x): x not in list”

Diese Fehlermeldungen können wir später über bestimmte Techniken abfangen, jetzt müssen
wir vorerst damit noch leben.

Sortieren von Listen über sorted()


Benötige man die Listeneinträge sortiert, kann die über die Funktion sorted() durchgeführt
werden. Im folgenden Beispiel liegen die Buchstaben in der Liste in einer nicht definierten
Reihenfolge vor. Im Folgenden Beispiel erfolgt die erste Sortierung aufsteigend und dann im
nächsten Schritt absteigend:
© https://www.python-lernen.de/listen-methoden.htm Seite 88

buchstaben = ['a', 'c', 'b']


print(buchstaben)

buchstaben_sortiert = sorted(buchstaben)
print(buchstaben_sortiert)

buchstaben_sortiert_absteigend = sorted(buchstaben, reverse=True)


print(buchstaben_sortiert_absteigend)

Das Ergebnis:

['a', 'c', 'b'] # unsortierte Liste


['a', 'b', 'c'] # sortiert aufsteigend
['c', 'b', 'a'] # sortiert absteigend

Soll bei der Sortierreihenfolge nicht auf Groß- und Kleinschreibung geachtet werden, muss die
entsprechende Anweisung mitgegeben werden.

buchstaben = ['a', 'c', 'B', 'A']


print(buchstaben)

# sortiert, Groß-Kleinschreibung wird beachtet


buchstaben_sortiert_1 = sorted(buchstaben)
print(buchstaben_sortiert_1)

# sortiert ohne Rücksicht auf Großbuchstaben


buchstaben_sortiert_2 = sorted(buchstaben, key=str.lower)
print(buchstaben_sortiert_2)

Wir erhalten nun wie erwartet als Ausgabe:

['a', 'c', 'B', 'A'] # unsortierte Liste


['A', 'B', 'a', 'c'] # sortiert, Groß-Kleinschreibung wird beachtet
['a', 'A', 'B', 'c'] # sortiert ohne Rücksicht auf Großbuchstaben

alle wichtige Möglichkeiten für Listen


Somit haben wir alle wichtigen Möglichkeiten der Listen-Methoden kennengelernt:

Element in Liste am Ende einfügen

Element an bestimmter Position in Liste einfügen

Element vom Listenende löschen

Element von bestimmter Position in der Liste löschen

Element anhand vom Wert aus Liste löschen

Damit lassen sich viele Aufgaben bei Listen schnell und einfach erledigen!
© https://www.python-lernen.de/listen-methoden.htm Seite 89
© https://www.python-lernen.de/list-methoden-uebersicht.htm Seite 90

Übersicht aller Methoden des Datentyps Liste


Über die Anweisung dir(list) erhalten wir alle Methoden zu Listen:

>>> dir(list)

['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__',


'__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__',
'__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__',
'__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert',
'pop', 'remove', 'reverse', 'sort']

Im Folgenden die Übersicht aller Methoden des Datentyps Liste:

Methode Beschreibung

.append() hinzufügen von einem Eintrag am Ende der Liste

.clear() Löscht alle Einträge der Liste

.copy() Erstellt eine Kopie

.count() Liefert die Anzahl der vorhandenen Listeneinträge zurück

.extend() hinzufügen aller Einträge einer anderen Liste

.index() suchen nach Element in Liste und liefert Index (Nummern fangen bei 0 an!) zurück

.insert() fügt einen Eintrag an der vorgegebenen Index-Nummer ein (folgende Einträge werden nach hinten
verschoben)

.pop() löscht den Eintrag aus der Liste des übergebenen Index und liefert dessen Inhalt als Rückgabewert

.remove() löscht den Eintrag aus der Liste (im Gegensatz zu pop() wird der Wert und nicht der Index übergeben)

.sort() sortiert die Liste in gewünschter Form


© https://www.python-lernen.de/variablen-listen.htm Seite 91

Variablen sind Listen? Was nun? Python Spezial


In Listen greifen wir über die Index-Nummer, geschrieben in eckigen Klammern, auf ein
gewünschtes Element zu. Was passiert aber, wenn wir bei einem Variablen mit einer eckigen
Klammer und einer Index-Nummer zugreifen. Das schöne ist, dass wir immer testen können
und auch an Fehlern lernen. Erstellen wir als ein Variable und probieren einfach:

variableA = 'Ich bin eine Variable'


print( variableA[1] )

Was kommt als Ausgabe? Wir erhalten als Ausgabe nur ein

Was passiert nun. Auch beim String beginnt die Zählung bei 0 - unser erstes Zeichen "I" ist als
am Index 0 zu finden. Wir haben die Index-Nummer 1 angefragt und bekommen das zweite
Zeichen vom String. Daher erhalten wir als Ausgabe das "c".

Wir können also die Vorgehensweise von Listen auch auf Variablen anwenden.

Ausgabe rückwärts
Wie bei Listen schon gesehen, können wir auch die Ausgabe von hinten uns anzeigen lassen.
Wenn wir den letzten Buchstaben (sprich -1) uns ausgeben lassen möchten, ist unsere
Anweisung:

variableA = 'Ich bin eine Variable'


print( variableA[-1] )

Als Ergebnis erhalten wir das kleine "e".

Mehr als 1 Buchstaben – von bis


Wollen wir nun mehr als nur ein Zeichen auslesen, können wir das über das "bis"-Zeichen. In
Python wird dazu der Doppelpunkt verwendet.

Unser vorheriges Beispiel erweitern wir. Es sollen nicht nur 1, sondern 6 Zeichen ausgelesen
werden:

variableA = 'Ich bin eine Variable'


print( variableA[0:5] )

Als Ausgabe erhalten wir direkt ab dem Anfang (daher die 0) die folgenden 5 Zeichen:

Ich b

Hier gibt es auch die Kurzschreibweise. Man kann vor oder nach dem Doppelpunkt auch
keine Angabe machen. Dann wird von Anfang an (wenn vor dem Doppelpunkt nichts
angegeben wird) oder bis zum Schluss (wenn nach dem Doppelpunkt nichts angegeben wird)
ausgegeben.

variableA = 'Ich bin eine Variable'


print( variableA[7:] )
© https://www.python-lernen.de/variablen-listen.htm Seite 92

Dies führt zu der Ausgabe

eine Variable

Oder vor dem Doppelpunkt:

variableA = 'Ich bin eine Variable'


print( variableA[:7] )

Dies führt zu der Ausgabe

Ich bin

Natürlich können wir auch die Variante mit der "Zählung ab dem Ende" einsetzen:

variableA = 'Ich bin eine Variable'


print( variableA[-4:] )

Und nun erhalten wir als Ergebnis die letzten 4 Zeichen:

able

Anzahl der Zeichen – Funktion len()


Eine weitere Funktion, die Python bietet, ist die Ausgabe der Länge eines Strings. Über die
Funktion len() bekommen wir die Anzahl der Zeichen als Rückgabewert.

variableA = 'Ich bin eine Variable'


print( len (variableA) )

Als Ergebnis erhalten wir die Zahl

21
© https://www.python-lernen.de/python-dictionary.htm Seite 93

Datentyp Dictionary – Wörterbücher in Python


Der Datentyp Dictionary (auf Deutsch „Wörterbuch“ bzw. assoziative Liste) ermöglicht ein
Aufbau ähnlich einer Liste aber als Indizes anstelle von Zahlen dann „Text“. Der Begriff
Dictionary ist wirklich mit dem dafür deutschen Wort „Wörterbuch“ am besten verständlich.
Über den Datentyp Dictionary können wir also in Python eine Zuordnungstabelle (in anderen
Sprachen „assoziatives Array“) aufbauen und nutzen. Durch die folgenden Beispiele wird es
schnell verständlich.

Schauen wir uns den Aufbau anhand einer deutsch-englisch Wörterbuches an.

Wir wollen Zahlen in beiden Sprachen erhalten:

null = zero
eins = one
zwei = two
drei = three

Als Dictionary wird in Python im ersten Schritt ein leeres „Wörterbuch“ erstellt – dies ist an den
geschweiften Klammern zu sehen. Wir nennen es „deutschenglisch“:

deutschenglisch = {}

Jetzt füllen wir das Dictionary mit Inhalt:

deutschenglisch = {}
deutschenglisch['null'] = 'zero'
deutschenglisch['eins'] = 'one'
deutschenglisch['zwei'] = 'two'
deutschenglisch['drei'] = 'three'

Und wie üblich können wir den Inhalt ausgeben über

deutschenglisch

Als Rückmeldung erhalten wir den kompletten Inhalt des Dictionary

>>> deutschenglisch

{'null': 'zero', 'eins': 'one', 'zwei': 'two', 'drei': 'three'}

Diese folgende Variante ist auch eine andere Möglichkeit, ein „Dictionary“ aufzubauen:

deutschitalienisch = {'eins': 'uno', 'zwei': 'due', 'drei': 'tre'}

Wollen wir ein bestimmtes Element der assoziativen Liste erhalten, geben wir das gewünschte
einfach mit dem „Klartext-Index“ an.

>>> deutschenglisch['zwei']
'two'

Löschen von Elementen - Aktion auf das dictionary


Wollen wir ein Element, sprich Schlüssel-Wert Paar aus unserem Wörterbuch löschen, können
wir dies direkt mit der Anweisung del und dem entsprechenden Index tun:
© https://www.python-lernen.de/python-dictionary.htm Seite 94

del deutschenglisch['zwei']

Nun fehlt dieses Element in unserem dictionary

>>> deutschenglisch

{'null': 'zero', 'eins': 'one', 'drei': 'three'}

Aber Vorsicht mit del !

Wird kein Index (Schlüssel-Wert Paar) angegeben, wird das komplette dictionary gelöscht!

del deutschenglisch

Das kann also ins Auge gehen:

>>> del deutschenglisch

>>> deutschenglisch

Traceback (most recent call last):

File "<stdin>", line 1, in <module>

NameError: name 'deutschenglisch' is not defined

Dictionary Methoden – Python stellt verschiedene Methoden


bereit
>>> dir(dict)
['__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__'

values()
Über die Methode values() werden alle Werte des dictionary zurückgeliefert. Aus unserem
vorherigen Wörterbuchbeispiel wäre das dann:

deutschitalienisch.values()

Ergebnis:

>>> deutschitalienisch.values()

dict_values(['uno', 'due', 'tre'])

keys()
Über die Methode keys() werden alle Schlüssel des dictionary zurückgeliefert. Aus unserem
vorherigen Wörterbuchbeispiel wäre das dann:

deutschitalienisch.keys()
© https://www.python-lernen.de/python-dictionary.htm Seite 95

Als Ergebnis dann:

>>> deutschitalienisch.keys()

dict_keys(['eins', 'zwei', 'drei'])

items()
Über die Methode items() werden alle Elemente des dictionary zurückgeliefert. Aus
unserem vorherigen Wörterbuchbeispiel wäre das dann:

deutschitalienisch.items()

Ergebnis:

>>> deutschitalienisch.items()

dict_items([('eins', 'uno'), ('zwei', 'due'), ('drei', 'tre')])

Die Feinheiten der Rückgabe:

eckige Klammern zeigen, dass es sich um eine Liste handelt

runde Klammern zeigen, dass es sich um Tupel handelt

clear()
Alle Elemente werden aus dem dictionary gelöscht. Im Unterschied zum vorher gezeigten del
besteht weiterhin ein dictionary mit seinem Namen, dass allerdings keinen Inhalt hat.

deutschitalienisch.clear()

copy()
Legt eine Kopie des dictonary an.

woerterbuch = deutschitalienisch.copy()

Nun steckt der Inhalt auch in dem neuen „dictionary“, dass aber diesen Inhalt so behält, auch
wenn das Original verändert wird. Hier liegt der Unterschied zu einem Aliasnamen (siehe weiter
unten).

>>> woerterbuch = deutschitalienisch.copy()

>>> woerterbuch

{'eins': 'uno', 'zwei': 'due', 'drei': 'tre'}

Wird mit Aliasnamen gearbeitet (und nicht mit Kopien) verändert sich der Inhalt, egal ob man
mit dem Alias oder dem originalen Namen zugreift!
© https://www.python-lernen.de/python-dictionary.htm Seite 96

neuernamen = deutschitalienisch
deutschitalienisch['vier'] = 'quattro'
neuernamen['vier']

Wir erhalten als Ausgabe dann „quattro“. Die Änderungen gelten für alle Aktion, egal ob
Elemente dazukommen oder entfernt werden.
© https://www.python-lernen.de/dictionary-methoden-uebersicht.htm Seite 97

Übersicht aller Methoden des Datentyp Dictionary


Über die Anweisung dir(dict) erhalten wir alle Methoden zu Dictionary

>>> dir(dict)

['__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__',


'__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__',
'__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
'__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'items',
'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']

Im Folgenden die Übersicht aller Methoden des Datentyp Dictionary:

Methode Beschreibung

.clear() Löscht alle Einträge des Dictionarys

.copy() Erstellt eine Kopie

.fromkeys() Erstellt eine Kopie aus den Schlüsseln eines Dictionary

.get() Liest einen Wert zu einem übergebenen Schlüssel aus

.items() Gibt alles Schlüssel und Werte aus (bei Python 2.7 .viewitems())

.keys() Zeit die Schlüssel eines Dictionary an

.pop() löscht den Eintrag aus dem Dictionary des übergebenen Schlüssels und liefert dessen Inhalt als
Rückgabewert

.popitem() Liefert einen Eintrag als Tupel zurück und löscht den Eintrag aus dem Dictionary (im Gegensatz zu
pop() muss kein Schlüssel übergeben werden)

.setdefault() liefert den Wert eines Eintrags aus dem Dictionary, wenn der Schlüssel vorhanden ist. Ist kein
entsprechender Schlüssel vorhanden, wird ein Schlüssel mit dem Wert im Dictionary gespeichert

.update() Aktualisiert einen Wert, wenn der Schlüssel vorhanden ist. Wenn noch kein entsprechender Schlüssel
vorhanden ist, wird Wert und Schlüssel eingetragen

.values() Liefert alle Werte des Dictionary zurück (ohne Schlüssel)


© https://www.python-lernen.de/tupel.htm Seite 98

Tupel – und der Unterschied zu Variablen und Listen


Wir haben bereits Variablen und Listen kennengelernt. Man fragt sich nun natürlich nach dem
Unterschied zwischen Variablen und Listen im Vergleich zu Tupeln in Python.

Unterschied Variablen und Listen:

Variable speichert einen Inhalt

Liste speichert VIELE Inhalte (bzw. kann das)

Und was ist ein Tupel? Eigentlich eine Liste aber der wichtige Unterschied ist, dass der Inhalt
eines Tupels NICHT änderbar ist. Daher sind Tupel besonders geeignet, um Konstanten zu
verkörpern.

Um unsere Auflistung von oben zu komplementieren:

Variable speichert einen Inhalt

Liste speichert VIELE Inhalte (bzw. kann das)

Tupel speichern VIELE Inhalte UNVERÄNDERLICH

Der Sinn hinter UNVERÄNDERLICH (nicht löschbar) bei Tupels


Warum macht das „unveränderlich“ überhaupt Sinn? Genau dann, wenn gespeicherte Werte nur
zusammen Sinn ergeben! Als Beispiel ist es einfacher nachvollziehbar. Wir wollen Werte für ein
2D-Koordinatensystem speichern. Dazu benötigen wir den X-Wert und den Y-Wert. Als könnten
wir hier ein Tupel bilden mit punkt1 = (10, 22) . Der erste Wert stellt den X-Wert dar, der
zweite Wert den Y-Wert. Gäbe es nur einen Wert (egal ob X oder Y) wären diese Daten sinnlos.
Wir wollen also nicht, dass einer der Daten gelöscht werden kann!

Tupel in Python erstellen


Üblicherweise wird ein Tupel durch runde Klammern erstellt:

tupel = ('wert1', 'wert2')

Technisch möglich ist es auch ohne Klammern – aber erstens unüblich und zweitens für den
typischen Python-Programmierer irritierend.

tupel = 'wert1', 'wert2'


type(tupel)

Und hat man ein Tupel mit nur einem einzigen Element ist das Komma am Schluss wichtig!
Einfach mal folgenden Code testen:

inhaltA = ('wert1',)
inhaltB = ('wert2')
type(inhaltA)
type(inhaltB)

Warum wir überhaupt Tupel nutzen sollen ist anhand der obigen Beispiele wenig einsichtig. Wie
gesagt, Tupel sind die Speicherform von unveränderbaren Daten – was man in anderen
Programmiersprachen als Konstanten bezeichnet. Solche Daten wäre z.B. Name

personl = ('Elke', 'Maier', '1985')


© https://www.python-lernen.de/tupel.htm Seite 99

Zugriff auf Werte in einem Tupel


Der Zugriff und die Möglichkeiten sind gleich wie bei der Liste. Ich kann gezielt auf einen
bestimmten Inhalt zugreifen:

tupel = ('wert1', 'wert2', 'wert3', 'wert4', 'wert5')


print (tupel[0])

Über die eckigen Klammern greife ich per Index auf den entsprechenden Wert zu. Auch wie bei
Listen startet der Index bei 0!

Ich kann auch mehrere Werte anhand von „von – bis“ auswählen:

tupel = ('wert1', 'wert2', 'wert3', 'wert4', 'wert5')


print (tupel[2:4])

Wir erhalten als Ergebnis:

('wert3', 'wert4')
© https://www.python-lernen.de/tuple-methoden-uebersicht.htm Seite 100

Übersicht aller Methoden des Datentyps Tuple


Über die Anweisung dir(tuple) erhalten wir alle Methoden zum Datentyp Tupel. Die Anzahl
der Methoden ist überschaubar – sprich 2 Stück. Dies liegt daran, dass Tupel unveränderlich
sind im Gegensatz zu Listen.

>>> dir(tuple)

['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__',


'__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__',
'__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__',
'count', 'index']

Im Folgenden die Übersicht aller Methoden des Datentyp Dictionary:

Methode Beschreibung

.count("gesucht") Anzahl der Vorkommen des Gesuchten – Beispiel unten

.index( Das erste Vorkommen im Index des Gesuchten – Beispiel unten

Beispiel für tuple.count("gesucht")


In der folgenden Namensliste, die als Tuple gespeichert ist, gibt es Mehrfachnennungen. Über
die Methode .count("gesucht") erhält man die Anzahl.

vornamen = ( "Hans","Peter","Elke","Peter","Sabine","Elke")
print(vornamen)

# Wie oft kommt bestimmter Vornamen im Tuple vor


print (vornamen.count("Peter"))

Als Rückgabe erhalten wir 2, da Peter zweimal vorkommt.

Beispiel für tuple.index("gesucht")


Die Methode .index("gesucht") liefert uns die Position im Index zurück.

vornamen = ( "Hans","Peter","Elke","Peter","Sabine","Elke")
print(vornamen)
print (vornamen.index("Peter"))

Als Ergebnis erhalten wir:

('Hans', 'Peter', 'Elke', 'Peter', 'Sabine', 'Elke')

Ganz wichtig – die Zählung beginnt bei 0. Daher kommt die 1 beim Suchen nach „Peter“, der an
der zweiten Stelle steht.
© https://www.python-lernen.de/tuple-methoden-uebersicht.htm Seite 101

Sollte das Gesuchte nicht in dem Tuple vorhanden sein, erhalten wir als Rückmeldung
„ValueError: tuple.index(x): x not in tuple“
© https://www.python-lernen.de/mengenlehre-set-frozenset.htm Seite 102

Mengen managen über: set und frozenset


Über das Objekt set ist in Python das Konzept der Mathematik mit Mengen und Mengenlehre
nachgebaut.

In einem Set steckt eine ungeordnete Sammlung von Objekten, die nur 1-Mal vorkommen!

Aufbau eines Sets über geschweifte Klammern:

set_a = { 1, 2, 3, 'A', 'B', 'C' }

In einem Set steckt eine ungeordnete Sammlung von Objekten, die nur 1-Mal vorkommen! Dies
sieht man sehr schön, wenn man ein Tupel mit Dopplungen in ein set umwandelt:

werte_als_tupel = (1,1,1,3,5,3,4,5,3)
werte_als_set = set(werte_als_tupel)
print(werte_als_set)

Als Ergebnis erhalten wir dann ein Set mit jeweils nur einmalig vorkommenden Werten:

{1, 3, 4, 5}

Mengenlehre mit Set


Das Besondere ist nun, dass über 2 Sets Mengenlehre mit „Schnittmenge“,
„Vereinigungsmenge“, „A ohne B“ usw. durchgeführt werden kann.

set_a = { 1, 2, 3, 'A', 'B', 'C' }


set_b = { 2, 3, 'B', 'D' }

Wollen wir nun die Schnittmenge (also was in beiden Mengen vorkommt) herausfiltern, läuft
dies über das kaufmännische Und & :

set_a = { 1, 2, 3, 'A', 'B', 'C' }


set_b = { 2, 3, 'B', 'D' }
print( set_a & set_b )

Als Ergebnis erhalten wir:

{2, 3, 'B'}

Im folgenden Beispiel die üblichen Verdächtigen bei der Mengenlehre:


© https://www.python-lernen.de/mengenlehre-set-frozenset.htm Seite 103

set_a = { 1, 2, 3, 'A', 'B', 'C' }


set_b = { 2, 3, 'B', 'D' }

print("Set A:")
print(set_a)

print("Set B:")
print(set_b)
print()

print("Schnittmenge über &")


print( set_a & set_b )
print()

print("Vereinigungsmenge über |")


print( set_a | set_b )
print()

print("Differenzmenge über - ")


print( set_a - set_b )
print()

print("Symmmetrische Differnz (entweder-oder) über ^")


print( set_a ^ set_b )
print()

print("Obermenge von > ")


print( set_a > set_b )

Und unsere Ergebnisse:

Set A:
{1, 2, 3, 'A', 'B', 'C'}

Set B:
{2, 3, 'D', 'B'}

Schnittmenge über &


{2, 3, 'B'}

Vereinigungsmenge über |
{1, 2, 3, 'A', 'B', 'C', 'D'}

Differenzmenge über -
{'C', 1, 'A'}

Symmetrische Differenz (entweder-oder) über ^


{1, 'A', 'C', 'D'}

Obermenge von >


False
© https://www.python-lernen.de/mengenlehre-set-frozenset.htm Seite 104

frozenset und Unterschied zu set


set-Objekte sind veränderbar – diese werden eingefroren und somit unveränderbar über
frozenset .

Die Umwandlung kann man vorwärts wie rückwärts machen, sprich aus einem Set ein
Frozenset und rückwärts.

set_a = { 1, 2, 3, 'A', 'B', 'C' }


set_c = frozenset(set_a)

print(set_c)
print(type(set_c))

Ergebnis:

frozenset({'C', 1, 2, 3, 'B', 'A'})


<class 'frozenset'>

Und locker aus der Hüfte wieder rückwärts:

set_a = { 1, 2, 3, 'A', 'B', 'C' }


set_c = frozenset(set_a)

print(set_c)
print(type(set_c))

set_c = set(set_c)
print(set_c)
print(type(set_c))

Und das Ergebnis:

frozenset({1, 2, 3, 'C', 'B', 'A'})


<class 'frozenset'>

{1, 2, 3, 'C', 'B', 'A'}


<class 'set'>

Beispiel Anzahl Buchstaben in Text zählen mit Hilfe von set


Anhand der Anweisung set werten wir einen Text aus und zählen die Anzahl der Buchstaben.
Dabei wird im ersten Code es Schritt für Schritt gemacht. Dasselbe kommt dann nochmals
komprimiert.
© https://www.python-lernen.de/mengenlehre-set-frozenset.htm Seite 105

inhalt = "anzahl"

# doppelte Buchstaben entfernen


buchstaben = set(inhalt)
print(buchstaben)

# zum Sortieren aus dem SET eine Liste machen


buchstabenliste = list(buchstaben)
print(buchstabenliste)

# sortieren
buchstabensortiert = sorted(buchstabenliste)
print(buchstabensortiert)

# der Reihen nach durchlaufen und Anzahl zählen


# die for-Schleife kommt in einem späteren Kapitel

for einzelbuchstabe in buchstabensortiert:


print(einzelbuchstabe ,": Anzahl ", inhalt.count(einzelbuchstabe))

Als Ergebnis erhalten wir:

{'n', 'a', 'l', 'z', 'h'}


['n', 'a', 'l', 'z', 'h']
['a', 'h', 'l', 'n', 'z']

a : Anzahl 2
h : Anzahl 1
l : Anzahl 1
n : Anzahl 1
z : Anzahl 1

Und nun dasselbe in 3 Zeilen:

inhalt = "Buchstaben zählen"


for einzelbuchstabe in sorted(list(set(inhalt))):
print(einzelbuchstabe ,": Anzahl ", inhalt.count(einzelbuchstabe))

Als Ergebnis erhalten wir:


© https://www.python-lernen.de/mengenlehre-set-frozenset.htm Seite 106

: Anzahl 1
B : Anzahl 1
a : Anzahl 1
b : Anzahl 1
c : Anzahl 1
e : Anzahl 2
h : Anzahl 2
l : Anzahl 1
n : Anzahl 2
s : Anzahl 1
t : Anzahl 1
u : Anzahl 1
z : Anzahl 1
ä : Anzahl 1
© https://www.python-lernen.de/set-methoden-uebersicht.htm Seite 107

Übersicht aller Methoden zu set


Über die Anweisung dir(set) erhalten wir alle Methoden zu set

>>> dir(set)

['__and__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__',


'__ge__', '__getattribute__', '__gt__', '__hash__', '__iand__', '__init__', '__init_subclass__', '__ior__',
'__isub__', '__iter__', '__ixor__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__or__', '__rand__',
'__reduce__', '__reduce_ex__', '__repr__', '__ror__', '__rsub__', '__rxor__', '__setattr__', '__sizeof__',
'__str__', '__sub__', '__subclasshook__', '__xor__', 'add', 'clear', 'copy', 'difference',
'difference_update', 'discard', 'intersection', 'intersection_update', 'isdisjoint', 'issubset',
'issuperset', 'pop', 'remove', 'symmetric_difference', 'symmetric_difference_update', 'union',
'update']

Im Folgenden die Übersicht aller Methoden von set:

Methode Kurzbeschreibung

.add(neues Element) fügt ein Element zu einem Set hinzu

.clear() löschen aller Elemente von dem Set

.copy() gibt eine Kopie des Sets zurück

.difference() liefert ein neues Set mit der Rückgabe der Unterschiede der übergebenen Sets

.intersection() liefert ein neues Set zurück mit den Werten der Überschneidung der übergebenen
Sets

.intersection_update() aktualisiert ein Set mit den Überschneidungen zwischen sich selber und dem
übergebenen Set

.isdisjoint() Überprüft, ob 2 Sets keinerlei Überschneidungen haben. Als Rückgabe wird „True“
oder „False“ geliefert

.issubset() Überprüft, ob das Set im anderen Set enthalten ist. Rückgabe „True“ oder „False“

.issuperset() Überprüft, ob jedes Element des Sets im anderen Set enthalten ist. Rückgabe
„True“ oder „False“

.pop() Liefert vom Set ein zufälliges Element zurück und löscht dieses aus dem Set

.remove(wegmitdiesem) Löscht ein Element (das übergeben wird) aus einem Set

.symmetric_difference() liefert ein neues Set zurück mit allen Werten beider Sets, die sich nicht
überschneiden der übergebenen Sets

.symmetric_difference_update() aktualisiert ein Set mit den Werten beider Sets, bei denen keine Überschneidungen
zwischen sich selber und dem übergebenen Set vorliegt

.union() liefert alle Werte der übergebenen Sets zurück

.update() aktualisiert ein Set mit allen Werten von sich selber und den übergebenen Sets
© https://www.python-lernen.de/input-nutzereingaben.htm Seite 108

input – Nutzereingaben anfordern


Eingaben vom Nutzer abfragen in Python
Wir haben bei den vorherigen Kapiteln immer wieder Daten auf dem Bildschirm ausgegeben.
Allerdings werden in der Realität die Daten entweder aus einer Datenbank kommen oder durch
einen Nutzer festgelegt, also eingegeben werden.

Um eine Angabe vom Nutzer anzufordern, gibt es in Python den Befehl input

Diesem Befehl können wir einen Text mitgeben, damit dem Nutzer klar ist, was er denn
eingeben soll. Die Eingabe selber wird in einer Variablen gespeichert, mit der wir dann
weiterarbeiten können.

Unser Befehl sieht dann so aus:

benutzereingabe = input("Bitte Zahl eingeben")

Das Python-Programm pausiert nun, wenn es diese Programmzeile erreicht hat und wartet ab,
bis der Nutzer eine Eingabe gemacht hat. Erst nach der Eingabe läuft das Programm dann
weiter.

Nun können wir die Variable, die im Beispiel „benutzereingabe“ genannt wurde, im weiteren
Programmablauf nutzen.

benutzereingabe = input("Bitte Zahl eingeben")


print(benutzereingabe)

Input liefert Strings


Als Rückgabewert der input -Funktion erhalten wir eine String. Den Typ einer Variablen
können wir uns über die Funktion type ausgeben lassen. Im folgenden Beispiel zum Testen:

benutzereingabe = input("Bitte Zahl eingeben")


print(type(benutzereingabe))

Als Ergebnis erhalten wir:

class 'str'

Wollen wir aber mit der vom Benutzer eingegebenen Zahl weiterrechnen, müssen wir den
String erst in eine Zahl konvertieren.

Hier kommt das Prinzip des „castens“ zum Einsatz. Der Typ einer Variablen umgewandelt.

Wenn man den Typ einer Variablen umwandelt, spricht man „casting“. Das Wort erinnert nicht
zu Unrecht an das Besetzen von Filmrollen (also die Rollenverteilung). Und genau das machen
wir mit dem Typ. Wir sagen, du bist nun eine Ganzzahl (integer).

benutzereingabe = int(benutzereingabe)

Jetzt können wir mit der Benutzereingabe als Zahl arbeiten. Diese Zahl können wir über
print ausgeben lassen.

print(benutzereingabe)
© https://www.python-lernen.de/input-nutzereingaben.htm Seite 109

Wollen wir nun die Zahl mit einem Text am Anfang ausgeben lassen, kommen kleine Probleme
zum Vorschein:

print("Eingegeben wurde: " + benutzereingabe)

Wir versuchen nun die STRING-Ausgabe "Eingegeben wurde" mit einer Integer zu verknüpfen
und das wird mit einer Fehlermeldung quittiert. Hier müssen wir den Typ wieder umwandeln
und alles ist gut:

print("Eingegeben wurde: " + str(benutzereingabe))

Gibt der Benutzer allerdings die Zahl in andere Form ein (sprich keine Zahl), dann bekommt
man Fehlermeldungen.

Tipp für Fortgeschrittene: unsichtbare input-Eingaben (z.B. für


Passwort)
Eigentlich greifen wir nicht besonders tief in die Trickkiste, aber es passt so perfekt an diesem
Platz. Mit der bisherigen input -Eingabe sind immer alle Nutzereingaben sichtbar. Allerdings
sollten Passworteingaben beim eintippen unsichtbar sein sonst kann jemand Unberechtigtes
das Passwort einfach vom Bildschirm ablesen.

Dazu nutzen wir das Modul getpass .

Folgender Code macht die Magie:

from getpass import getpass

nutzername = input("Nutzername: ")


kennwort = getpass("Passwort: ")

print("Eingegebener Nutzername", nutzername)


print("Eingegebenes Kennwort", kennwort)
© https://www.python-lernen.de/kommentare.htm Seite 110

Kommentare in Python nutzen


Kommentare in Programmen können für unterschiedliche Zwecke genutzt werden. Dazu
gehören die typischen 3 folgende Varianten:

erklärende Kommentare innerhalb vom Code

bessere Lesbarkeit des Codes

zum Testen von Code, bzw. zum Verhindern der Ausführung auskommentierter
Programmteile

erklärende Kommentare
Wird ein Programm komplexer und man betreut es über Jahre bzw. mehrere Personen
arbeiten an einer Software, ist es hilfreich, Codeabschnitte zu kommentieren. Dadurch ist
auch noch Jahre später schnell klar, warum etwas an einer bestimmten Stelle in der
entsprechenden Art umgesetzt wurde.

Auch beim Programmieren in Teams können Kommentare weiterhelfen.

Als Einsteiger wird man aber eher von der folgenden Art profitieren:

bessere Lesbarkeit von Code


Der Quellcode kann durch Kommentare entsprechend besser Lesbar gemacht werden.
Python zwingt durch das Einrücken bereits zu sehr sauberem Code. Allerdings kann je nach
Anwendung ein Kommentar die Lesbarkeit weiter verbessern.

auskommentieren zum Testen von Code


Funktioniert einmal ein Programmteil nicht wie gewünscht, kann schnell einmal zum Testen
bestehender Code auskommentiert werden und Testcode eingefügt werden.
Auskommentierter Code kann nach Auffinden des Fehlers wieder schnell aktiviert werden.
Das hat gegen löschen den großen Vorteil, dass alles wieder vorhanden ist und nichts
versehentlich vergessen wird.

Möglichkeiten zum Kommentieren/Auskommentieren


Kommentare starten mit einer Raute. Alles nach dem Doppelkreuz „#“ wird von Python
ignoriert.

Beispiel:

# hier kommt ein Kommentar


print("Hallo Welt")

Die Kommentare können auch nach Befehlen platziert werden. Ab dem Doppelkreuz „#“ wird
alles ignoriert!

print("Hallo Welt") # hier kommt ein Kommentar

Soll ein Code auskommentiert („ausgeschaltet“) werden, wird das Doppelkreuz einfach am
Anfang der Zeile platziert:
© https://www.python-lernen.de/kommentare.htm Seite 111

# print("Hallo")
print("Welt")

Als Ergebnis erhalten wir nur noch als Ausgabe das Wort „Welt“. Die Zeile mit der Ausgabe für
„Hallo“ wird durch das Kommentarzeichen komplett ignoriert.

Kommentare über mehrere Zeilen


Meistens möchte man nicht nur eine Zeile Code auskommentieren und möchte auch nicht vor
jeder einzelnen Programmzeile ein Doppelkreuz platzieren. Dann bietet sich die Möglichkeit
an, mehrere Zeilen auf einen Schlag auszukommentieren.

Dies geschieht über 3 doppelte Anführungszeichen:

"""
Hier kommt auskommentierter Bereich
der über mehrere Zeilen sich zieht
"""

Am Ende kommen dann wieder 3 doppelte Anführungszeichen. Ab jetzt werden wieder alle
Python-Befehle ausgeführt.

Dieses Vorgehen kann man sowohl zum Platzieren von umfangreichen Kommentaren nutzen
wie auch um ganze Programmteile auszukommentieren:

"""
print("Hallo")
print("Welt")
"""
© https://www.python-lernen.de/ausfuehrbares-python-programm-erstellen.htm Seite 112

ausführbares Python-Programm erstellen


Um ein ausführbares Python-Programm (Python-Script) zu erstellen, benötigen wir eine Datei.
Das Besondere an dieser Datei ist die Dateiendung. Hier wird für Python dann ".py" verwendet.

Es ist egal, mit welchem Betriebssystem wir arbeiten. Im Beispiel wird unter Windows der im
Betriebssystem vorhandene Editor „notepad“ verwendet.

Die einfachste Variante ist, auf Start zu klicken und dann einfach loszutippen. Sobald wir die
ersten Buchstaben von „editor“ eingetippt haben bekommen wir bereits den Vorschlag für den
Standardeditor.

Diesen Editor auswählen.

Und nun können wir direkt im Editor unser Python-Programm eintippen.

In unserem Texteditor geben wir ein:

print('Hallo Welt')

Beim Speichern auf die Dateiendung „.py“ achten! Als Dateiname verwende ich für unser erstes
Programm „hallowelt.py“.

Ich speichere mein Python-Programm im Ordner „python-kurs.de“ unter „C:“ ab.

Jetzt sollte unser Ordner diesen Inhalt haben:

Ordner mit Python-Programm

Zum Starten des Python-Programms


Python starten unter Windows
Zum Starten des Python-Programms benötigen wir eine DOS-Konsole. Diese rufen wir unter
Windows auf, indem wir wieder auf den Start-Button klicken und dort einfach „cmd“ eintippen.
Die vorgeschlagene DOS-Konsole können wir dann übernehmen.
© https://www.python-lernen.de/ausfuehrbares-python-programm-erstellen.htm Seite 113

cmd unter Windows starten

Ist bei Installation von Python nun der Pfad im Betriebssystem richtig hinterlegt worden,
können in direkt in der DOS-Konsole Python starten. Zum Test kann man Python ohne unser
geschriebenes Programm starten. Einfach direkt in der DOS-Konsole „python“ eintippen.

Klappt das, können wir unser Python-Programm „hallowelt.py“ starten. Dazu werden nach dem
Programmaufruf noch der Pfad und der Dateiname angegeben.

python c:\python-kurs.de\hallowelt.py

Wir erhalten durch die Ausführung des Programms nun die Ausgabe in der Konsole von „Hallo
Welt“.

Wenn wir uns den langen Pfadnamen zum eintippen sparen wollen, können wir einmal in das
Verzeichnis wechseln über die DOS-Anweisungen cd und dann das Programm ohne
Pfadangaben ausführen. Einfach sich den folgenden Screenshot ansehen. Hier wird am Anfang
das Programm mit Pfadangabe ausgeführt und dann wird in den Ordner „Python-Kurs.de“
gewechselt (sieht aus wie eine Internetadresse, kann man aber auch als Verzeichnis
verwenden (ein bisschen Werbung und Kopierschutz)).

Python-Programm ohne Pfadangaben ausführen

Ausführen von Python-Programmen mit dem Mac OSx


Beim Mac starten wir das Terminal. Hier haben wir die Besonderheit, dass die alte Version von
Python bereits im Betriebssystem ausgeliefert wird. Wir können direkt im Terminal python
eingeben und erhalten als Rückmeldung die Versionsnummer von Python – im Beispiel ist das
„Python 2.7.10“. Haben wir das aktuelle Python3 installiert, können wir dieses in Terminal mit
© https://www.python-lernen.de/ausfuehrbares-python-programm-erstellen.htm Seite 114

python3 aufrufen und erhalten als Feedback die entsprechende Versionsnummer.

Python unter Mac OSx

Zum Starten von unserem Programm geben wir im Terminal nach dem Startbefehl für Python
noch den Pfad und den Dateinamen an:

python3 Documents/Python-Kurs.de/hallowelt.py

Das Programm wird dann ausgeführt.

Python-Programm mit Mac ausführen


© https://www.python-lernen.de/if-abfrage-python.htm Seite 115

if-Bedingung in Python
In Python gibt es die Möglichkeiten Bedingungen zu überprüfen und entsprechend im
Programmablauf darauf zu reagieren. Hier könnten wir abhängig von der Uhrzeit den Nutzer
entsprechend Begrüßen. Aber erst einmal der allgemeine Aufbau von if -Abfragen und wie
wird diese einsetzen.

Aufbau der if -Abfrage


Würden wir in Deutsch eine Bedingung formulieren, würde diese wie folgt aussehen

wenn Wert kleiner als 5 dann mache alles Doppelpunkt

Und nun das Ganze als Python-Programm, in der wir als Erstes die Variable definieren:

wert = 3
if wert < 5:
print('Wert ist kleiner als 5')

Das wichtige ist, dass nach der if -Abfrage das weitere, was zu der if -Abfrage gehört,
eingerückt wird! Diese Einrückungen sind der Dreh- und Angelpunkt in Python und garantiert
einen sauberen Quellcode. Pfuscht man bei den Einrückungen, funktioniert das Programm
nicht wie erwartet.

Bei unserer if -Anfrage gehört alles Folgende, was eingerückt ist, zu der Bedingung. Und das
kann mehr als eine Zeile sein!

wert = 3
if wert < 5:
print('Wert ist kleiner als 5')
print('Ich gehöre auch noch zu der Bedingung')
print('und hier geht es nach der if-Abfrage weiter')

Lassen wir das Programm ausführen, erhalten wir als Ergebnis alle 3 Zeilen ausgegeben. Die 2
Textzeilen, die „innerhalb“ der if -Abfrage sind (sprich, die eingerückt sind) und die letzte
Textzeile, die nach der if -Abfrage kommt und nicht eingerückt ist.

Ändern wir nun unsere Variable am Anfang auf wert = 9" , erhalten wir bei der
Programmausführung nur noch die letzte Zeile ausgegeben, die nach der if -Abfrage kommt.
Die if -Abfrage ist nicht wahr, weil der Wert mit 9 bereits größer ist als die Bedingung < 5
und somit das eingerückte der if -Abfrage nicht ausgeführt wird.

Wichtig ist bei Programmänderungen, dass man speichern nicht vergisst!

Was passiert eigentlich genau bei wert < 5 ? Python überprüft, ob das Ergebnis wahr oder
falsch ist. Dabei kann auch direkt „true“ oder „false“ der if -Abfrage präsentiert werden und
diese reagiert darauf entsprechend:

if True:
print('if-Bedingung ist wahr')

Es erscheint als Ergebnis:


© https://www.python-lernen.de/if-abfrage-python.htm Seite 116

if-Bedingung ist wahr

Natürlich könnten wir auch eingeben if false: und es würde nichts angezeigt werden, da
unsere if -Abfrage nicht wahr ist.

Natürlich würde kein Mensch so eine if -Abfrage erstellen, denn die if -Abfrage würde ja
immer exakt zum gleichen Ergebnis führen. Allerdings können wir auch Variablen übergeben,
die diesen Wert haben.

wahroderfalsch = True
if wahroderfalsch:
print('if-Bedingung ist wahr')

Unsere Variable "wahroderfalsch" hat nun den Wert "true" zugewiesen bekommen und die if -
Abfrage reagiert entsprechend darauf.

Diese Variablen sind vom Typ Boolean – es gibt nur die Werte true oder false bei
Boolean. Diese Variablen-Typen sind benannt nach dem Erfinder George Boole.

Ungleich != in Python
Oft möchte man auch einfach wissen, ob eine bestimmte Bedingung nicht zutrifft, also
ungleich ist.

Dazu kann man den Operator != (ungleich) nutzen.

Als Beispiel wollen wir von einer Stundenzahl wissen, ob es NICHT 12 Uhr ist. Dazu unser
Code:

wert = 11
if wert != 5:
print('Es ist nicht 12 Uhr')

Alternative, wenn if -Abfrage nicht zutrifft


Jetzt ist es oft geschickt gleich darauf reagieren zu können, wenn die if -Abfrage nicht
zutrifft. Ohne diese Kenntnis müssten wir solche kantigen Konstruktionen bauen wie folgt:

wert = 9
if wert < 5:
print('Wert ist kleiner als 5')
if wert > 4:
print('Wert ist größer als 4')

Dies wollen wir kürzer, da die zweite if -Abfrage einfach das Gegenteil gerade von der ersten
darstellt. Alles was nicht kleiner ist als 5 ist auf jeden Fall größer als 4. Und hier kommt das
schöne Wort else zum Einsatz:

wert = 9
if wert < 5:
print('Wert ist kleiner als 5')
else:
print('Wert ist größer als 4')
© https://www.python-lernen.de/if-abfrage-python.htm Seite 117

Unseren zweiten Part ersetzen wird durch else: . Trifft unsere if -Abfrage nicht zu, sprich
ist diese nicht wahr, sondern falsch, dann wird der Block unter else: ausgegeben:

Als Ausgabe erhalten wir nun bei der Programmausführung:

Wert ist größer als 4

Alle Vergleichs-Operatoren
Je nach Aufgabenstellung den passenden Vergleich nutzen!

== gleich

!= ungleich

< kleiner

> größer

<= kleiner oder gleich

>= größer oder gleich

Weitere Bedingungen innerhalb der Bedingung prüfen – elif


Unser bisheriges Programm ist nicht wirklich sexy. Es gibt die Ausgabe „Wert ist kleiner als 5“
oder „Wert ist größer als 4“. Eigentlich wären folgenden 3 mögliche Ergebnisse deutlich
schicker.

Wert ist kleiner 5

Wert ist exakt 5

Wert ist größer 5

Dazu brauchen wir eine Abfrage innerhalb der Abfrage. Und dazu kennt Python den Befehl
elif . In den meisten anderen Programmiersprachen kennt man dies als „elseif“ aber in
Python ist es elif .

Unser Programm von oben sieht nun damit so aus.

wert = 9
if wert < 5:
print('Wert ist kleiner als 5')
elif wert == 5:
print('Wert ist exakt 5')
else:
print('Wert ist größer als 5')

Der Überprüfung von der Bedingung hinter elif wird nur dann überprüft, wenn die erste
Bedingung nicht zutrifft. Trifft unsere Bedingung unter elif auch nicht zu, dann kommt die
Alternative unter else zum Tragen.

Wichtig sind die Einrückungen!

Kleine böse Fehlerquelle – doppeltes Gleichzeichen


© https://www.python-lernen.de/if-abfrage-python.htm Seite 118

Hier unser Code, in dem sich ein Fehler eingeschlichen hat:

wert = 9
if wert < 5:
print('Wert ist kleiner als 5')
elif wert = 5:
print('Wert ist exakt 5')
else:
print('Wert ist größer als 5')

Wir überprüfen bei elif , ob dieses exakt 5 entspricht. Hier ist der Standardfehler, dass
versehentlich nur ein Gleichzeichen (anstelle von 2) gemacht wurde. Das ist aber nicht möglich
und somit kommt eine Fehlermeldung von Python in Form von „SyntaxError: invalid syntax“

beliebig viele elif


Wir sind bei elif nicht auf eines begrenzt. Von diesen weiteren Abfragen können beliebig
viele gemacht werden. Je nach Aufgabenstellung ist es sinnvoll.
© https://www.python-lernen.de/zufallszahlen-random.htm Seite 119

mit random Zufallszahlen nutzen – import random in


Python
Die meisten Spiele nutzen den Zufall für das Spiel. Als erstes einfaches Spiel programmieren
wir „Schere, Stein, Papier“ in Python um die Anwendung von random in Python kennen
zulernen.

Um random nutzen zu können, müssen wir das random-Modul in unser Python-Programm


importieren!

Was ist ein Modul und warum gibt es dieses Konzept?


Eigentlich könnte man meinen, dass eine Zufallsfunktion so wichtig ist, dass diese sofort
verfügbar ist. Dies ist nicht der Fall: diese Funktionen sind im „Lieferumfang“ der normalen
Installation enthalten, müssen aber erst „aktiviert“ werden. Dieses „Aktivieren“ erfolgt über das
Importieren des Moduls. So kann jedes benötigte Modul vom Programmierer nachgeladen
werden und Python schlank und somit auch schnell gehalten werden. Das „Aktivieren“ erfolgt
über die Anweisung import :

import random

Über die Hilfeanweisung erhalten wir die ersten Informationen zu verfügbaren Methoden der
Anweisung random .

print(help(random.random))
help(random.random)

Als Rückmeldung erhalten wir:

random() -> x in the interval [0,1)

Zufallszahlen zwischen 0 und 0.99999


Wir bekommen also eine zufällige Zahl beim Aufruf von random() zurückgeliefert. Wer
genau auf die Rückmeldung der Python-Hilfe schaut, dem fällt die eckige Klammer vor 0 und
die runde Klammer nach 1 auf. Die eckige Klammer bedeutet, dass eine 0 zurückgeliefert
werden kann – die runde Klammer bedeutet dagegen, dass niemals eine 1 zurückgeliefert wird!

Lassen wir uns ein Ergebnis ausgeben:

print(random.random())

Bei jeder Ausgabe erfolgt eine andere Zahl – das ist das Wesen des Zufalls.

>>> print(random.random())

0.1229030667914014

>>> print(random.random())

0.4683265429999067

>>> print(random.random())

0.5755756960623487
© https://www.python-lernen.de/zufallszahlen-random.htm Seite 120

durch uns festgelegtes Intervall für random


Wenn wir nun Zufallszahlen in einem anderen Intervall benötigen, könnten wir eine eigene
Funktion dafür programmieren. Das ist eine Möglichkeit. Hier der Vollständigkeit halber.

def zufallszahl():
return random.random() * 9 + 1
print (zufallszahl())

Dadurch bekommen wir Zahlen zwischen 1 und unter 10

random.uniform – eigenes Intervall einfach festlegen


Python bietet über die Anweisung random.uniform weitere Möglichkeiten:

help(random.uniform)

Wir bekommen über random.uniform eine zufällige Nummer zwischen „a“ und „b“
zurückgeliefert.

print(random.uniform(5,8))

Somit bekommen wir nur noch Nummer zwischen 5 und maximal 8.

Zufallsnummer aus Normalverteilung (Glockenkurve)


Zufallsnummer aus Normalverteilung – random.normalvariate(Standardabweichung sigma)

print(random.normalvariate(5, 0.1))

Würfel simulieren randint(min, max)


Wenn wir wie bei einem Würfel eine festgelegte Anzahl von Möglichkeiten haben, die alle gleich
wahrscheinlich sind, dann bietet sich randint an.

print(random.randint(1,6))

Wir bekommen nur ganzzahlige Werte wie bei einem normalen 6-seitigen Würfel zurück
zwischen eins und sechs (inklusive der Sechs).

Gut sichtbar, wenn wir 15-mal den Würfel „werfen“:

for i in range(15):
print(random.randint(1,6))

Zufälliges Element aus einer Liste


Wir können auch aus einer Liste von Elementen ein Element zufällig auswählen lassen. Hier
sind wir unserem „Schere, Stein, Papier“.

Wir erstellen also als Erstes eine Liste mit unseren 3 Elementen:

handgeste = ['Schere', 'Stein', 'Papier']

Und nun können wir Python zufällig auswählen lassen:


© https://www.python-lernen.de/zufallszahlen-random.htm Seite 121

print(random.choice(handgeste))

Das Modul random bietet noch weitere Möglichkeiten, die einem über
print(dir(random)) angezeigt werden. Für die meisten Anwendungen reichen die bisher
vorgestellten aus.

Somit haben wir schon eine schöne Möglichkeit für die zufällige Auswahl der Handgeste. Im
folgenden Kapitel bauen wir unser Spiel zusammen.
© https://www.python-lernen.de/uebung-lobesreden.htm Seite 122

Lob ist wichtig – Schmeichelprogramm


Wir haben mit dem Modul „random“ aus dem letzten Kapitel nun die Möglichkeit kennengelernt,
in unseren Python-Programmen mit dem Zufall zu spielen. Jetzt wollen wir uns ein
Schmeichelprogramm programmieren. Dieses soll uns loben, was das Zeug hält. Wer lieber die
Welt negativ sieht, darf natürlich genauso ein Beschimpfungsprogramm erstellen. Alles eine
Frage der Wortwahl.

Das gewünschte Ergebnis: ein sich immer änderndes Lob ausgeben in der Form:
„Du bist der ADJEKTIV NOMEN“

Beispielsweise:
„Du bist der beste Freund“
„Du bist der liebenswürdigste Mensch“

Was benötigen wir? Natürlich haben wir die jetzt benutzten Funktionen und Vorgehensweisen
bei Python schon in den letzten Kapiteln kennengelernt. Am besten ist natürlich nicht einfach
den später folgenden Code abzutippen, sondern erst einmal selber probieren, eine Lösung zu
erstellen.

Was haben wir:

wir haben beliebige viele positive Adjektive (die Liste kann beliebig erweitert werden):

beste

liebenswürdigste

schönste

größte

Zusätzlich haben wir Nomen:

Mensch

Hecht

Freund

Kumpel

Programmierer

Aus diesen 2 Listen können wir nun eine Ausgabe auf dem Bildschirm durch Zufall erzeugen
lassen. Beispiele dazu, die können kommen:

Du bist der größte Freund

Du bist der liebenswürdigste Mensch

Du bist …

Aufgabe: Lobesprogramm
Wir benötigen also in Python die Möglichkeit,

die Adjektive zu speichern


© https://www.python-lernen.de/uebung-lobesreden.htm Seite 123

die Nomen zu speichern

eine zufällige Auswahl aus den beiden gesicherten

und diese soll dann ausgegeben werden

Unbedingt selber probieren. Dadurch lernt man am schnellsten (auch aus den unter
Umständen gemachten Fehlern).

Lösungsweg: Lobesprogramm:
Probiert und zu einem Ergebnis gekommen? Hier eine Lösung für unser Lob-Programm.

Im ersten Schritt erstellen wir 2 Listen. Variablen wären hier unpraktisch, da wir ja viele
ähnliche Wörter haben, uns später per Zufall aus den Listen auswählen wollen:

Unsere Liste für die Adjektive:

adjektive = ["beste", "liebenswuerdigste", "schoenste", "groesste"]

Und jetzt können wir auch gleich eine zweite Liste mit den Nomen machen:

adjektive = ["beste", "liebenswuerdigste", "schoenste", "groesste"]


nomen = ["Mensch", "Hecht", "Freund", "Kumpel", "Programmierer"]

Wir wollen nun eine Ausgabe auf dem Bildschirm:

adjektive = ["beste", "liebenswuerdigste", "schoenste", "groesste"]


nomen = ["Mensch", "Hecht", "Freund", "Kumpel", "Programmierer"]
print ("Du bist der ")

Ab jetzt benötigen wir den Zufall. Dazu müssen wir das Modul random importieren. Das muss
gleich am Anfang unseres Python-Programmes geschehen. Muss ist übertrieben. Es muss
importiert sein, bevor es eingesetzt wird. Allerdings ist guter Stil am Anfang von einem Python-
Programm alle Module zu importieren.

import random
adjektive = ["beste", "liebenswuerdigste", "schoenste", "groesste"]
nomen = ["Mensch", "Hecht", "Freund", "Kumpel", "Programmierer"]
print ("Du bist der ")

Und nun wollen wir eine zufällige Auswahl. Diese erhalten wir über random und choice :

import random
adjektive = ["beste", "liebenswuerdigste", "schoenste", "groesste"]
nomen = ["Mensch", "Hecht", "Freund", "Kumpel", "Programmierer"]
print ("Du bist der ")
print (random.choice(adjektive))
print (random.choice(nomen))

Als Ergebnis erhalten wir:

Du bist der
beste
Freund
© https://www.python-lernen.de/uebung-lobesreden.htm Seite 124

Die Ausgabe kommt bereits, allerdings untereinander. Also nutzen wir nur 1 print und unser
Schmeichelprogramm ist fertig. Dies einmal nach dem Aufstehen ausführen und die Stimmung
ist mindestens um 3,5 Prozent besser:

import random
adjektive = ["beste", "liebenswuerdigste", "schoenste", "groesste"]
nomen = ["Mensch", "Hecht", "Freund", "Kumpel", "Programmierer"]
print ("Du bist der " +
random.choice(adjektive) +
" " +
random.choice(nomen)
)

Ausgabe von unserem erstellten Programm:

Du bist der beste Freund

Kleine Anmerkung am Rande. Es wurde in der fertigen Lösung noch ein Leerzeichen in der
Ausgabe zwischen dem Adjektiv und dem Nomen ausgegeben. Die print -Ausgabe ist im
obigen Code umgebrochen, um besser lesbar zu sein. Diese könnte auch komplett in einer
Zeile im Programmcode stehen.

Und nun „frohes Loben“.


© https://www.python-lernen.de/while-schleife.htm Seite 125

while -Schleife in Python


Über Schleifen können wir Aktion mehrmals ausführen lassen, bis eine festgelegte Bedingung
erfüllt ist. So können wir z.B. in einem Shop 10 Artikel ausgeben lassen. Die while -Schleife
läuft 10-mal und gibt dann 10 Artikel aus.

Wie sieht eine while -Schleife in Python aus? Wieder benötigen wir eine Bedingung, die wir
bereits im Kapitel zu if -Bedingungen kennengelernt haben. Anhand dieser wird kontrolliert,
ob die Schleife weiter „ihre Kreise“ ziehen darf – die Bedingung wird kontrolliert, ob diese noch
richtig ist (sprich wahr ist). Ist die Bedingung nicht mehr wahr, wird die while -Schleife nicht
mehr ausgeführt und das Programm läuft nach der Schleife weiter bis zum Ende des
Programmcodes (wenn nach der Schleife noch Code kommt).

Im Vorfeld brauchen wir eine Variable, welche die Durchgänge zählt. Diese kontrollieren wir, ob
diese kleiner 11 ist (damit wir 10 Durchgänge bekommen).

durchgang = 1
while durchgang < 11:
print(durchgang)
print("nach der Schleife")

Wir sehen nun die Schleife und den typischen Aufbau mit der Einrückung. Alles was eingerückt
wird, gehört in den Schleifenkörper und wird bei jedem Schleifendurchgang durchlaufen.

Allerdings läuft das obige Programm unendlich lang. Warum? Unsere Variable „durchgang“ ist
immer unter 11, denn es ändert sich ja nichts an der Höhe der Zahl in der Variablen
„durchgang“. Zum Abbrechen hilft ctrl + c

Daher müssen wir unbedingt im Schleifenkörper die Zahl bei jedem Durchgang um 1 erhöhen.
Es muss also noch integriert werden durchgang = durchgang + 1 . Und auch dieser
Python-Code muss eingerückt in den Schleifenkörper, sonst wird dieser nicht als Bestand der
Schleife ausgeführt!

durchgang = 1
while durchgang < 11:
print(durchgang)
durchgang = durchgang + 1
print("nach der Schleife")

Lassen wir nun unser Python-Programm ablaufen, erhalten wir folgende Ausgabe:

1
2
3
4
5
6
7
8
9
10
nach der Schleife
© https://www.python-lernen.de/while-schleife.htm Seite 126

Hat die Variable dann den Wert 11, ist die Bedingung durchgang < 11 unwahr (false) und
die Schleife wird verlassen und die Ausgabe „nach der Schleife“ erfolgt.

So einfach sind Schleifen umsetzbar. Angebracht ist, dass die Bedingung irgendwann auch
„False“ annehmen kann, sonst läuft die Schleife unendlich lang (bis man das Kommando-
Fenster schließt oder den Computer ausschaltet).
© https://www.python-lernen.de/uebung-zahlenraten.htm Seite 127

Übung: Spiel Zahlenraten


Wir haben im letzten Kapitel die while -Schleife in Python kennengelernt. Wie können wir
daraus ein kleines Spiel basteln? Lustigerweise benötigen wir die while -Schleife so gut wie
immer in Python-Programmen. Aber langsam mit den Pferden.

Unser Zahlenraten-Spiel: der Computer bestimmt durch Zufall eine Zahl zwischen 0 und 100.
Wir haben 7 Versuche, exakt diese Zahl zu erraten. Bei jedem Rateversuch bekommen wir eine
der folgenden 3 möglichen Reaktionen von unserem Spiel:

deine geratene Zahl ist zu groß

deine geratene Zahl ist zu klein

Gewonnen! Die geheime Zahl ist nicht mehr geheim

Zusätzlich müssen wir neben der Zahl auch noch die Anzahl der Runden kontrollieren. Unsere
while -Schleife läuft maximal siebenmal durch.

Für diese maximal 7 Durchgänge gibt es verschiedene Möglichkeiten:

Die im letzten Kapitel kennengelernte Variante:

durchgang = 0
while durchgang < 7:
print(durchgang)
durchgang = durchgang + 1
print("nach der Schleife")

Wir benötigen natürlich die Möglichkeit die Schleife vorzeitig zu beenden. Dies können wir über
die Anweisung break in einer if -Abfrage erreichen. Im folgenden Beispiel brechen wir bei 3
ab – im Spiel brechen wir ab, wenn der Spieler der Zahl erraten hat.

durchgang = 0
while durchgang < 7:
print(durchgang)
durchgang = durchgang + 1
if (durchgang == 3):
break
print("nach der Schleife")

die „unendliche“ while -Schleife


Die zweite Möglichkeit von einer while -Schleife ist in den meisten Fällen die bessere
Vorgehensweise. Wir wissen bei vielen Anwendungen nicht, wie oft eine Schleife durchlaufen
werden muss. Daher geben wir der while -Schleife nur eine Variable mit dem Vorgabewert
„True“ mit. Jetzt können wir innerhalb der while -Schleife die Bedingung abfragen.

durchgang = 0
aktiv = True
while aktiv:
print(durchgang)
durchgang = durchgang + 1
if (durchgang == 3):
aktiv = False
print("nach der Schleife")
© https://www.python-lernen.de/uebung-zahlenraten.htm Seite 128

Was ist nun der große Vorteil von der zweiten Variante? Ich kann auf Benutzereingaben
reagieren und beschränke die Anzahl der Schleifendurchläufe nicht im Vorfeld. Nehmen wir an,
der Benutzer kann das Programm beenden mit der Eingabe von „ende“. Somit können wir
zusätzlich die Benutzereingabe kontrollieren und sobald vom Benutzer „ende“ eintippt wird,
setzen wir den Inhalt der Variable „aktiv“ auf „False“ und das Programm wird beendet:

durchgang = 0
aktiv = True
while aktiv:
print(durchgang)
durchgang = durchgang + 1
benutzereingabe = input("Bitte Zahl eingeben: ")
if (benutzereingabe == "ende"):
aktiv = False
print("nach der Schleife")

Wichtig ist, dass wir hier Python3 nutzen. Ansonsten bekommen wir eine Fehlermeldung bei
Python2.

Aufgabe: Zahlenratespiel
Der Spieler hat 7-mal die Chance die vom Computer durch Zufall festgelegte Zahl zu erraten.
Als Rückmeldung bekommt er nur:

deine geratene Zahl ist zu groß

deine geratene Zahl ist zu klein

Gewonnen! Die geheime Zahl ist nicht mehr geheim

Wenn der Spieler gewonnen hat, kommt eine entsprechende Meldung. Hat der Spieler die Zahl
nicht erraten, kommt als Nachricht: „Schade – verloren. Einfach nochmals probieren“.

Bitte erst selber eine Lösung probieren, bevor die folgende Lösung kommt. Alle benötigten
Python-Befehle wurden in den vorherigen Kapiteln vorgestellt.

Lösung: Zahlenratespiel
Sehr oft wird man am Anfang beim Programmieren über die Umwandlung von den Inhalten der
Variablen stolpern. Wir wollen einen Vergleich zwischen der Nutzereingabe und einer Zahl
machen. Also müssen wir eine Umwandlung über int machen. Wenn wir am Spielende die
vom Computer erstellte Zahl ausgeben wollen, müssen wir die Zahl für die Ausgabe dann
umwandeln anhand von var .

Hier nun eine mögliche Lösung (und immer daran denken: es gibt mehr als einen Weg nach
Rom):
© https://www.python-lernen.de/uebung-zahlenraten.htm Seite 129

import random
durchgang = 0
aktiv = True
ratezahl = random.randint(0,100)

while aktiv:
durchgang = durchgang + 1
print() # für Abstand (nur Optik)
print(durchgang)
benutzereingabe = int (input("Bitte Zahl eingeben: "))

if benutzereingabe == ratezahl:
print("Gewonnen! Die geheime Zahl ist nicht mehr geheim")
aktiv = False
break
elif benutzereingabe > ratezahl:
print("deine geratene Zahl ist zu groß")
else:
print("deine geratene Zahl ist zu klein")

if (durchgang == 7):
print("Schade – verloren. Einfach nochmals probieren")
print("Es war die Zahl " + str(ratezahl))
aktiv = False
print("Ende des Spiels")
© https://www.python-lernen.de/for-schleife.htm Seite 130

for -Schleife in Python


Es gibt weitere Arten von Schleifen neben while in Python. Je nach Anwendung spart die
geschickte Wahl der Schleife Programmierarbeit. Und um das geht es ja beim Programmieren
– eine zeitsparende Lösung mit dem geringstmöglichen Aufwand.

Schauen wir uns den Aufbau und die Möglichkeiten der for -Schleife an. In Python ist die
for -Schleife mit Listen eng verbunden. Daher sollte man sich das Kapitel mit Listen bereits
zu Gemüte geführt haben.

Die for -Schleife durchläuft eine vorgegebene Liste und wir können direkt die Einzelwerte der
Liste verwenden.

Nehmen wir wieder unsere Liste mit den Vornamen:

vornamen = ['Axel', 'Elke', 'Martin']

Die Vornamen-Liste soll nun über die for-Schleife durchlaufen werden und jeder Einzelwert
ausgegeben werden.

vornamen = ['Axel', 'Elke', 'Martin']


for einzelwert in vornamen:
print(einzelwert)
print("nach der for-Schleife")

Als Ergebnis erhalten wir nun folgende Ausgabe:

Axel
Elke
Martin
nach der for-Schleife

Bemerkenswert ist der große Unterschied der for -Schleife zu anderen Programmiersprachen.
Allerdings ist der Aufbau sehr geschickt, sobald man sich daran gewöhnt hat. Kennt man keine
andere Programmiersprache, dann ist die Anwendung der for -Schleife sehr einfach zu
verstehen.

Im Klartext ausgedrückt wäre die for -Schleife: solange es Einzelwerte in der Liste
„vornamen“ gibt, durchlaufe die Schleife (sprich den eingerückten Bereich danach). Dort stehen
dann in der Variablen „einzelwert“ der in diesem Durchlauf aktuelle Wert der Liste zur
Verfügung.

Im ersten Durchgang wird in der Liste „vorname“ als Wert „Axel“ ausgelesen und in die Variable
„einzelwert“ eingetragen. Diese lassen wir dann im Inneren der Schleife über
print(einzelwert) ausgeben.

Dann überprüft Python, ob ein weiterer Wert in der Liste „vornamen“ vorhanden ist. Das ist der
Fall. Somit läuft die Schleife eine zweite Runde und die Variable „einzelwert“ wird durch den
Wert „Elke“ überschrieben, die dann ausgegeben wird.

Im dritten Durchgang überprüft Python wieder, ob ein weiterer Wert in der Liste „vornamen“
vorhanden ist. Das ist der Fall – wieder wird die Variable „einzelwert“ mit dem Wert „Martin“
überschrieben und im Schleifenkörper ausgegeben.
© https://www.python-lernen.de/for-schleife.htm Seite 131

Wieder überprüft Python, ob ein weiterer Wert in der Liste vorhanden ist. Dies ist nach den
ersten 3 Werten nicht mehr der Fall. Unsere Liste verfügt nur über diese 3 Werte. Die for -
Schleife ist beendet.

Dabei ist es egal, ob in der Liste Zeichenketten oder Zahlen oder ein Mischmasch steht.

vornamen = ['Axel', 108, 'Elke', 30, 'Martin', 22]

Wir haben mit dem letzten Beispiel eine gemischte Liste mit Zahlen (Integer) und
Zeichenketten (String). Daher müssen wir darauf achten, was wir mit den Ergebnissen
anstellen. Mit den Zahlen könnten wir zwar rechnen, aber nicht mit den Strings. Da ist einfach
gesunder Menschenverstand angesagt, was man mit den zur Verfügung stehenden Variablen
und Inhalten so treibt.

if -Abfragen in Schleifen
Wir können auch if -Abfragen in Schleifen einbauen. Dann wird die Einrückung entsprechend
tiefer und bei jedem Durchlauf wird diese if -Bedingung überprüft. In unserem Beispiel wollen
wir schauen, ob der Wert z.B. „Axel“ ist und entsprechend darauf reagieren.

Unser bisheriges Programm sieht wie folgt aus:

vornamen = ['Axel', 'Elke', 'Martin']


for einzelwert in vornamen:
print(einzelwert)
print("nach der for-Schleife")

Jetzt gehen wir in die for -Schleife und überprüfen mit folgender if -Abfrage:

if einzelwert == "Axel"
print("Ich")
else
print(einzelwert)

Nun müssen wir beide Programmteile zusammenbringen. Hier ist nur die Schachtelung wichtig
und dass entsprechend eingerückt wird. Unsere if -Abfrage muss also tiefer eingerückt
werden, da diese ja in den Schleifenkörper von unserer for -Schleife muss:

vornamen = ['Axel', 'Elke', 'Martin']


for einzelwert in vornamen:
if einzelwert == "Axel":
print("Ich")
else:
print(einzelwert)
print("nach der for-Schleife")

Als Ausgabe erhalten wir nun:

Ich
Elke
Martin
nach der Schleife

Ja, ja ich weiß – der Esel nennt sich immer zuerst (aber woher kommt dieses Sprichwort?).
© https://www.python-lernen.de/for-schleife.htm Seite 132

Tipp für Fortgeschrittene: for -Ausgabe mit Nummerierung


durch enumerate
Öfters möchte man auch den laufenden Index mit ausgeben, der bei 0 startet. Also kommen
für den Anfänger Konstruktion wie diese:

vornamen = ['Axel', 'Elke', 'Martin']

# aufwendige Konstruktion
nummer = 0
for einzelwert in vornamen:
print(nummer, einzelwert)
nummer += 1

Als Ergebnis erhalten wir:

0 Axel

1 Elke

2 Martin

Schöner geht es mit enumerate - in der deutschen Übersetzung bedeutet „enumerate“


einfach „aufzählen“. Und so kommen wir zum exakt gleichen Ergebnis wie oben mit:

vornamen = ['Axel', 'Elke', 'Martin']


for nr, einzelwert in enumerate(vornamen):
print(nr, einzelwert)
© https://www.python-lernen.de/chatbot-programmieren.htm Seite 133

Chatbot mit Python programmieren


Endlich sich mit dem eigenen programmierten Python-Programm unterhalten, sprich chatten.
Das englische Wort „chatter“ bedeutet nichts anderes wie plaudern bzw. plappern. Chatbots
mit Texteingabe durch den Nutzer und intelligenten (mehr oder weniger) Antworten haben eine
lange Tradition. Bereits 1964 wurde Eliza von Joseph Weizenbaum programmiert.

Und genau so einen Chatbot wollen wir mit Python programmieren. Dazu brauchen wir die
grundlegende Funktionsweise.

In diesem Kapitel werden dazu eingesetzt:

Listen

Dictionary

while-Schleifen

for-Schleifen

die Abfrage „in“

Funktionsweise Chatbot
© https://www.python-lernen.de/chatbot-programmieren.htm Seite 134

Grundlegendes Ablaufdiagramm für Chatbot

Der Nutzer wird vom Chatbot begrüßt und gleich aufgeklärt, dass er die Unterhaltung mit „bye“
beenden kann. Dann wird auf die Nutzereingabe gewartet.

Liegt die Nutzereingabe vor, wird dir dieser Satz in Einzelteile (sprich Wörter) zerlegt.

Die einzelnen Wörter werden harmonisiert (Groß- und Kleinschreibung angeglichen).

Dann wird überprüft, ob Einzelwörter in der Datenbasis vorkommen, die als „passende“ Antwort
vorliegen.

Wenn eine „passende“ Antwort vorliegt, wird diese als Feedback ausgegeben.

Liegt keine passende Antwort vor, wird eine zufällige Antwort vom Chatbot zurückgegeben, um
das Gespräch aufrechtzuerhalten.

Es wird auf die nächste Nutzereingabe gewartet.

Diesen Ablauf werden wir nun Schritt für Schritt in Python programmieren. Dazu werden wir alle
bisher gelernten Elemente von Python nutzen.
© https://www.python-lernen.de/chatbot-programmieren.htm Seite 135

Schritt 1: Eingabe mit Schleife bis zu dem Beenden durch den Benutzer
Im ersten Schritt wollen wir nach der Begrüßung unsere Nutzer zur Eingabe eines Textes
auffordern.

Bevor wir nun mit deutschen Texten arbeiten, in denen immer wieder Umlaute wie „öäü“
vorkommen können (egal ob bei der Eingabe oder bei der Ausgabe), sollten wir Python darauf
vorbereiten. Wir speichern unsere Datei mit dem UTF-8 Encoding ab. Daher teilen wir das auch
Python mit. Diese geschieht über:

# -*- coding: utf-8 -*-

Wichtig ist, dass dies in der ersten Zeile unseres Programm-Codes geschieht. Wer mehr
darüber lesen will, kann einfach mal „Encoding Cookies Python“ in eine Suchmaschine
eingeben

Es gibt noch weitere Codings, die hier nicht weiter aufgeführt werden.

Jetzt begrüßen wir unsere Nutzer und geben einen Hinweis, wie das Programm auch wieder
beendet werden kann:

# -*- coding: utf-8 -*-


print("Willkommen beim Chatbot")
print("Worüber würden Sie gerne heute sprechen?")
print("Zum Beenden einfach 'bye' eintippen")
print("")

Wir wollen jetzt die Texteingabe des Nutzers erfassen. Diese wird in der Variable
„ nutzereingabe “ gespeichert und zur Kontrolle auf dem Bildschirm ausgegeben:

# -*- coding: utf-8 -*-


print("Willkommen beim Chatbot")
print("Worüber würden Sie gerne heute sprechen?")
print("Zum Beenden einfach 'bye' eintippen")
print("")
nutzereingabe = ""
nutzereingabe = input("Ihre Frage/Antwort: ")
print(nutzereingabe)

Sollte jetzt eine Fehlermeldung in Form eines „NameError“ kommen, dann bitte sicherstellen,
dass wir auch eine aktuelle Python-Version (mindestens Python ab Version 3) verwenden! Bei
den alten Python2-Versionen wird der Anweisung input() anders gehandhabt. Bei Python3
wird die Eingabe als String verarbeitet.

Wie man in unserem Ablaufdiagramm sieht, soll der Nutzer immer weitere Eingaben machen
können, bis dieser die Eingabe „bye“ zum Beenden eintippt.

Also packen wir unsere Eingabe in eine while -Schleife:

# -*- coding: utf-8 -*-


print("Willkommen beim Chatbot")
print("Worüber würden Sie gerne heute sprechen?")
print("Zum Beenden einfach 'bye' eintippen")
print("")
nutzereingabe = ""
while nutzereingabe != "bye":
nutzereingabe = ""
nutzereingabe = input("Ihre Frage/Antwort: ")
print(nutzereingabe)
print("Einen schönen Tag wünsche ich Dir. Bis zum nächsten Mal")

Wir benötigen 2-mal die Anweisung nutzereingabe = "" . Die erste Anweisung initialisiert
die Variabel „ nutzereingabe “ und die zweite leert einen eventuell vorhandenen Inhalt, was
© https://www.python-lernen.de/chatbot-programmieren.htm Seite 136

im ersten Durchgang noch nicht vorkommt.

Wenn wir unser Programm nun testen, können wir etwas eingeben und dieses wird einfach
wieder ausgegeben. Allerdings können wir auch nichts eingeben und einfach nur die Eingabe
mit der Return-Taste leer übergeben. Das ist natürlich wenig hilfreich für den folgenden
Programmablauf. Daher sollten wir noch sicherstellen, dass eine leere Eingabe nicht möglich
ist und der Benutzer weiter gefragt wird. Also bauen wir in unsere while -Schleife eine zweite
while -Schleife, die eine Eingabe sicherstellt.

# -*- coding: utf-8 -*-


print("Willkommen beim Chatbot")
print("Worüber würden Sie gerne heute sprechen?")
print("Zum beenden einfach 'bye' eintippen")
print("")
nutzereingabe = ""
while nutzereingabe != "bye":
nutzereingabe = ""
while nutzereingabe == "":
nutzereingabe = input("Ihre Frage/Antwort: ")
print(nutzereingabe)
print("Einen schönen Tag wünsche ich Dir. Bis zum nächsten Mal")

Wir haben nun den ersten Strang unseres Ablaufdiagramms erledigt.

Schritt 2: zufällige Antwort auf Nutzereingabe


Stürzen wir uns nun auf die Ausgabe einer zufälligen Antwort. Dazu benötigen wir eine
Sammlung an Antworten, die irgendwie immer passen. Aus dieser können wir dann per Zufall
später eine auswählen. Die Antwortsammlung speichern wir in einer Liste ab:

zufallsantworten=["Oh, wirklich", "Interessant ...", "Das kann man so sehen", "Ich verstehe ..."

Da wir das random-Modul für eine zufällige Antwort benötigen, binden wir das am Anfang
unseres Programms ein (wie auch unsere Liste mit den möglichen zufälligen Antworten).

# -*- coding: utf-8 -*-


import random
zufallsantworten=["Oh, wirklich", "Interessant ...", "Das kann man so sehen", "Ich verstehe ..."
print("Willkommen beim Chatbot")

Über die Anweisung random.choice(zufallsantworten) erhalten wir eine zufällige


Antwort. Diese können wir nun nach der Nutzereingabe ausgeben lassen:

# -*- coding: utf-8 -*-


import random
zufallsantworten=["Oh, wirklich", "Interessant ...", "Das kann man so sehen", "Ich verstehe ..."
print("Willkommen beim Chatbot")
print("Worüber würden Sie gerne heute sprechen?")
print("Zum beenden einfach 'bye' eintippen")
print("")
nutzereingabe = ""
while nutzereingabe != "bye":
nutzereingabe = ""
while nutzereingabe == "":
nutzereingabe = input("Ihre Frage/Antwort: ")
print(random.choice(zufallsantworten))
print("Einen schönen Tag wünsche ich Dir. Bis zum nächsten Mal")
exit()
© https://www.python-lernen.de/chatbot-programmieren.htm Seite 137

Schritt 3: passende Antworten auf Nutzereingabe


Die bisherige Unterhaltung mit nur zufälligen Antworten ist für den Nutzer eher merkwürdig.
Daher wollen wir auf die Nutzereingabe möglichst eine passende Antwort liefern. Dazu
erfassen wir über den Datentyp Dictionary eine Anzahl von passenden Antworten auf
bestimmte Stoppwörter. Unser Dictionary enthält neben dem Stoppwort eine dafür
vorgesehene Antwort (siehe mehr zu den Datentyp Dictionary im Kapitel https://www.python-
lernen.de/python-dictionary.htm )

Hier eine kleine Auswahl – je größer, desto besser für die Unterhaltung. Unser Dictionary
packen wir auch an den Anfang unseres Programms.

reaktionsantworten = {"hallo": "aber Hallo",


"geht": "Was verstehst du darunter?",
"essen": "Ich habe leider keinen Geschmackssinn :("
}

Jetzt müssen wir überprüfen, ob ein Stoppwort in der Nutzereingabe vorkommt. Um nicht
Probleme mit Groß- und Kleinschreibung zu haben, setzen wir die Eingabe komplett in
Kleinbuchstaben um

Und dann erstellen wir aus dieser Umsetzung eine Liste:

nutzereingabe = nutzereingabe.lower()
nutzerwoerter = nutzereingabe.split()

Diese Liste können wir Wort für Wort durchgehen und wenn ein Wort in den Stoppwörtern
auftaucht, diese mögliche Antwort nutzen:

# -*- coding: utf-8 -*-


import random
zufallsantworten=["Oh, wirklich", "Interessant ...", "Das kann man so sehen", "Ich verstehe ..."
reaktionsantworten = {"hallo": "aber Hallo",
"geht": "Was verstehst du darunter?",
"essen": "Ich habe leider keinen Geschmackssinn :("
}
print("Willkommen beim Chatbot")
print("Worüber würden Sie gerne heute sprechen?")
print("Zum beenden einfach 'bye' eintippen")
print("")
nutzereingabe = ""
while nutzereingabe != "bye":
nutzereingabe = ""
while nutzereingabe == "":
nutzereingabe = input("Ihre Frage/Antwort: ")
nutzereingabe = nutzereingabe.lower()
nutzerwoerter = nutzereingabe.split()
# print(nutzerwoerter)
for einzelwoerter in nutzerwoerter:
if einzelwoerter in reaktionsantworten:
print(reaktionsantworten[einzelwoerter])

Wichtig ist hier die Anwendung von dem unscheinbaren Python-Befehl in . Wir überprüfen, ob
Wörter aus unserer Liste „einzelwoerter“ innerhalb unseres Wörterbuches „reaktionsantworten“
als Keys vorkommen. Als Rückantwort erhalten wir ein „True“ wenn vorhanden bzw. ein „False“
wenn nicht vorhanden. Dies bewirkt die obige Anweisung:

if einzelwoerter in reaktionsantworten:

Jetzt wird unsere „reaktionsantwort“ ausgegeben.

Wir müssen uns nur merken, dann eine „passende“ Antwort gefunden wurde. Ansonsten muss
© https://www.python-lernen.de/chatbot-programmieren.htm Seite 138

eine zufällige Antwort ausgewählt werden. Das speichern wir über „intelligenteAntworten =
True“, die am Anfang auf „False“ gesetzt werden muss.

Diese können wir nun abfragen und dann unsere zufällige Antwort ausgeben:

# -*- coding: utf-8 -*-


import random

zufallsantworten=["Oh, wirklich", "Interessant ...", "Das kann man so sehen", "Ich verstehe ..."

reaktionsantworten = {"hallo": "aber Hallo",


"geht": "Was verstehst du darunter?",
"essen": "Ich habe leider keinen Geschmackssinn :("
}

print("Willkommen beim Chatbot")


print("Worüber würden Sie gerne heute sprechen?")
print("Zum beenden einfach 'bye' eintippen")
print("")

nutzereingabe = ""
while nutzereingabe != "bye":
nutzereingabe = ""
while nutzereingabe == "":
nutzereingabe = input("Ihre Frage/Antwort: ")

nutzereingabe = nutzereingabe.lower()
nutzerwoerter = nutzereingabe.split()

intelligenteAntworten = False
for einzelwoerter in nutzerwoerter:
if einzelwoerter in reaktionsantworten:
print(reaktionsantworten[einzelwoerter])
intelligenteAntworten = True
if intelligenteAntworten == False:
print(random.choice(zufallsantworten))

print("")

print("Einen schönen Tag wünsche ich Dir. Bis zum nächsten Mal")

Das war ein sehr einfacher Chatbot in Python. Dieser kann natürlich noch ausgefeilt werden.
© https://www.python-lernen.de/range-listen-mit-werten-erstellen.htm Seite 139

range() – Listen erstellen und mit Werten füllen


Wir haben bisher unsere Listen immer von Hand gefüllt. Nun lernen wir die Python-Funktion
range kenne.

Über die Funktion range können wir eine Liste erstellen, die von einem vorgegebenen Wert
bis zu einem vorgegebenen Wert geht.

werte = list(range(3))
print(werte)

Als Ergebnis erhalten wir

[0, 1, 2]

Anmerkung: bei der alten Python-Version reichte der folgende Code noch aus: werte =
range(3) – aber bitte nur mit aktueller Python-Version arbeiten (und vor allem Python
lernen)!

Der Wert startet bei 0 und zählt dann 3 Zahlen hoch. Wir kommen also bei einer Zahl eins
kleiner als unser vorgegebener Endwert raus.

Die range -Funktion können wir nun in den aus dem vorherigen Kapitel eingesetzten for -
Schleifen nutzen:

for durchgang in range(3):


print(durchgang)

Als Ergebnis erhalten wir

0
1
2

Somit wird die for -Schleife deutlich „ähnlicher“ wie auch anderen Programmiersprachen
diese einsetzen. Aber die Umsetzung in Python ist deutlich clever, da diese sehr flexibel ist.

Aber zurück zu unserer range -Funktion.

von-bis bei range -Funktion


Wenn wir bei der range -Funktion nur einen Wert angeben, ist das der Endwert und es wird bei
0 angefangen. Wir können aber auch den Startwert festlegen. Somit brauchen wir 2 Werte bei
der range -Funktion, die durch ein Komma getrennt werden.

werte = list(range(2,8))
print(werte)

Wir erhalten nun eine Liste mit den Werten:

werte[2,3,4,5,6,7]
© https://www.python-lernen.de/range-listen-mit-werten-erstellen.htm Seite 140

Hier sieht man bei der Aussage von vorher, dass „3-Zahlen ab 0“ so nicht ganz richtig ist. Bei
der range -Funktion wird eins kleiner als die „Endzahl“ genutzt. Im Beispiel haben wir 8
angegeben und erhalten in der erstellten Liste dann als letzte und größte Zahl 7.

Schrittweite (Schrittgröße) bei range festlegen


Neben dem Anfangswert und „Endwert-1“ können wir auch die Schrittweite angeben. Somit
kommen wir aus dem Standard mit der Schrittweite von 1 heraus und können für unseren
Anwendungsfall eine passende Schrittweite festlegen. Diese Angabe wird als dritter Wert
mitgegeben. Erweitern wir unser Beispiel, dass in 2-er Schritten vorgegangen werden soll.

werte = list(range(2,8,2))
print(werte)

Wir erhalten er Ergebnis:

werte[2, 4, 6]

Die 8 bei range(2,8,2) ist raus, da ja nur „Endwert-1“ bei range genutzt wird.

Es können auch negative Schrittweiten angegeben werden. Dazu muss der Startwert größer als
der Endwert sein:

werte = list(range(12,8,-1))
print(werte)

Wir erhalten er Ergebnis:

werte[12, 11, 10, 9]

Das Ganze geht natürlich auch ins Minus, wenn das bei den End- bzw. Anfangswerte
angegeben wurde:

werte = list(range(3,-3,-1))
print(werte)

Wir erhalten er Ergebnis:

werte[3, 2, 1, 0, -1, -2]


© https://www.python-lernen.de/uebung-lotto-simulator.htm Seite 141

Lottozahlen Simulator programmieren – 6 aus 49


Als folgende Aufgabe lernen wir den Python-Befehl range anzuwenden und erweitern unser
Wissen über Listen und Methoden bei Listen.

Bei einem Lotto-Simulator mit einer Ziehung von 6 Zahlen aus 49 möglichen Zahlen darf keine
Zahl doppelt vorkommen. Wäre sonst sehr merkwürdig. Daher fällt dafür die Methode über
random.randint(1, 50) aus. Man könnte damit auch eine Umsetzung einer Simulation
der Ziehung von Lottozahlen programmieren – nur der Aufwand ist deutlich zu hoch (genau
aus dem Problem der eventuell doppelten Zahlen).

Also erstellen wir uns als Erstes eine Liste aller möglichen Zahlen über range(1,50) . Als
Start beginnen wir bei 1 und lassen range bis 50 laufen – was bewirkt, dass wir alles Zahlen
von 1 bis einschließlich 49 bekommen.

Für die Zufallsfunktion nutzen wir sample() . Hier wird in der Klammer die Liste und die
gewünschte Anzahl angegeben:

lottozahlen_gewinner = random.sample(lottozahlen_alle, 6)

Bevor man die unten folgenden Schritt für Schritt Lösung liest, bitte selber testen! Es gibt auch
mehrere Wege nach Rom. Es muss nicht unbedingt sample() genutzt werden.

Lösung: Lotto Simulator in Python


Wir benötigen dazu eine leere Liste:

lottozahlen_alle = []

Diese Liste erweitern wir über extend . Hier bitte nicht auf die Python-Anweisung append
hereinfallen.

lottozahlen_alle = []
lottozahlen_alle.extend(range(1,50))
print(lottozahlen_alle)

Ab jetzt gibt es mehrere Möglichkeiten ans Ziel. Benutzen wir als Erstes die einfachste. Python
soll uns einfach 6 Einträge aus unserer Liste aller Lottozahlen per Zufall auswählen. Dazu gibt
es die Anweisung sample() . Diese Anweisung ist in dem Modul random integriert – sprich
wir müssen dieses am Anfang unseres Python-Programmes importieren!

Wir lassen das Ergebnis von sample() einer neuer Liste mit dem Namen
„lottozahlen_gewinner“ zuweisen.

import random
lottozahlen_alle = []
lottozahlen_alle.extend(range(1,50))
lottozahlen_gewinner = random.sample(lottozahlen_alle, 6)
print(lottozahlen_gewinner)

Wir erhalten nun als Ergebnis:

[33, 36, 2, 3, 40, 12]


© https://www.python-lernen.de/uebung-lotto-simulator.htm Seite 142

Es fällt auf, dass wir eine wild gemischte Liste erhalten. Erst einmal erstaunlich, da die
ursprüngliche Gesamtliste „lottozahlen_alle“ aufsteigend sortiert ist.

Lassen wir einfach noch sortieren und dann erst ausgeben:

import random
lottozahlen_alle = []
lottozahlen_alle.extend(range(1,50))
lottozahlen_gewinner = random.sample(lottozahlen_alle, 6)
lottozahlen_gewinner.sort()
print(lottozahlen_gewinner)

Wichtig ist: Es ist keine Zahl doppelt! Das ist der große Unterschied zu dem Einsatz von
choices() . Der Vollständigkeit halber hier auch eine Ausgabe damit. Bei dieser Anweisung
muss über „k=6“ die gewünschte Anzahl mitgegeben werden.

import random
lottozahlen_alle = []
lottozahlen_alle.extend(range(1,50))
lottozahlen_gewinner = random.sample(lottozahlen_alle, 6)
lottozahlen_gewinner.sort()
print(lottozahlen_gewinner)
print(random.choices(lottozahlen_alle, k=6))

Das Ergebnis:

[12, 16, 20, 22, 28, 45]


[34, 15, 22, 32, 18, 32]

Die erste Zeile kommt von sample() und die zweite Zeile von choices() . In der zweiten
Zeile ist dir 32 doppelt. Einfach einmal testen.

Weitere Möglichkeiten über Mischen „shuffle()“


Eine weitere Möglichkeit stellt das mischen über shuffle dar. Auch dafür müssen wir im
ersten Schritt random importieren. Wir lassen unsere Liste mit allen Lottozahlen kräftig
mischen und holen uns dann einfach die ersten 6 Zahlen aus der gemischten Liste. Zum
Auslesen aus der Liste setzen wir die Kombination einer for -Schleife mit range() ein.

import random
lottozahlen = []
lottozahlen.extend(range(1,50))
random.shuffle(lottozahlen)
for x in range(6):
print(lottozahlen[x])

Und nun viel Spaß beim Lotto spielen mit Python.


© https://www.python-lernen.de/break-continue-schleifen-ablauf.htm Seite 143

break und continue – Schleifen im Ablauf abbrechen


Sowohl die for - wie auch die while -Schleife gibt es die Möglichkeit diese frühzeitig
abzubrechen, auch wenn das Schleifenende eigentlich noch nicht erreicht wurde. Dies läuft
über den Python-Befehl break

Wir haben eine for -Schleife, die die Zahlen von 0 bis 9 durchläuft. Diese soll aber bei
Erreichen von der Zahl 7 abbrechen und nach der Schleife weitermachen.

for durchgang in range(10):


if durchgang == 7:
print("Schleifenabbruch wird erzwungen")
break
print(durchgang)

print("Nach der Schleife")

Als Ergebnis erhalten wird

0
1
2
3
4
5
6
Schleifenabbruch wird erzwungen
Nach der Schleife

Schleifendurchgang im Ablauf überspringen


Nicht ganz so radikal wie break funktioniert die Anweisung continue in Python. Es wird
nur der Schleifendurchgang abgebrochen, aber wieder den nächsten Schleifendurchgang mit
neuem Wert durchlaufen.

Dies wird in einem Beispiel klarer. Wir wollen beispielsweise nur gerade Ergebnisse ausgeben
lassen. Dazu wird die mathematische Funktion des Modulo genutzt.

Was macht der Modulo? Diese gibt uns als Rückantwort entweder 0 für gerade oder 1 für
ungerade zurück. Der Modulo wird über die Konstruktion " %2 " aktiviert. Schauen wir Beispiele
dazu an:

wert = 3
print(wert%2)

Hier erhalten wir als Ausgabe dann 1. Die Zahl 3 ist ungerade und somit kommt als Ergebnis
dann 1.

wert = 4
print(wert%2)

Hier erhalten wir als Rückgabe die 0, da unsere Zahl 4 gerade ist.
© https://www.python-lernen.de/break-continue-schleifen-ablauf.htm Seite 144

wert = 13
print(wert%2)

Die Zahl 13 ist ungerade und somit liefert der Modulo als Rückgabe 1.

Setzten wir dieses Wissen nun in unsere for -Schleife ein, damit nur noch gerade Zahlen
ausgegeben werden und die Schleife in diesem Durchgang nicht weiter durchlaufen wird.

for durchgang in range(10):


if durchgang%2 == 1:
continue
print(durchgang)

print("Nach der Schleife")

Als Ausgabe erhalten wir alle geraden Zahlen (ohne 10, da ja der Durchgang nur bis 9 geht)

0
2
4
6
8
Nach der Schleife

Dies waren beide Möglichkeiten, eine Schleife komplett abzubrechen ( break ) oder den
Schleifendurchlauf zu überspringen ( continue ).

Das klappt sowohl bei der for -Schleife wie auch bei der while -Schleife.
© https://www.python-lernen.de/hangman-python-programmieren.htm Seite 145

Galgenmännchen, Galgenraten – hangman-Spiel


Wir programmieren uns das bekannte Spiel Galgenmännchen (auch bekannt als Galgenmann
und im Englischen als „hangman“) in Python.

Hier kommen bereits bekannte Python-Befehle zum Einsatz:

Liste

while -Schleife

for -Schleife

in

Schleifen abbrechen mit break

Wir benötigen wieder für unser Spiel den Zufall, daher können wir gleich am Anfang unseres
Codes das random -Modul importieren:

import random

Natürlich benötigen wir noch Wörter, aus denen unser Programm dann per Zufall auswählen
kann für das Ratespiel. Bisher haben wir Listen immer der folgenden Form aufgebaut:

woerter = ['Wort1', 'Wort2', 'Wort3']

Einfacher (vor allem für später, wenn die Wörter über eine Datei geladen werden) ist die
Anweisung split() . Diese erzeugt aus einem String eine Liste.

woerter = 'Wort1 Wort2 Wort3'.split()

Dieser Aufruf von split() ohne einen Parameter erledigt für uns schon unsere Aufgabe. Der
Vollständigkeitshalber: als Parameter kann das verwendete Trennzeichen angegeben werden.
Soll Beispielsweise anhand von „@“ getrennt werden, erhalten wir bei einer E-Mail-Adresse
sofort den Domainnamen extrahiert.

mailaufgeteilt = 'mailadresse@pyhton-lernen.de'.split('@')

Zusätzlich kann eine Anzahl mitgegeben werden, wie groß die erzeugte Liste werden soll.

beispiel = 'Wort1#Wort2#Wort3'.split('#', 2)

Einfach mal probieren.

Zurück zu unserem Spiel. Zum Entwickeln nutzen wir übersichtliche Anzahl von 5 Wörter – es
geht hier um das Prinzip. Die Anzahl der Wörter kann später ja beliebig erweitert werden.

import random
print("hangman in Python")
woerter = 'Hund Katze Maus Haus raus'.split()

Wir benötigen nun aus unserer Liste ein zufälliges Wort. Dazu bietet uns die Anweisung
random.choice() die schnellste Möglichkeit.

Das zufällig ausgewählte Wort speichern wir in der Variable ratewort und lassen es zur
Kontrolle ausgeben. Bei jedem Programmaufruf sollte ein anderes kommen.
© https://www.python-lernen.de/hangman-python-programmieren.htm Seite 146

import random
print("hangman in Python")
woerter = 'Hund Katze Maus Haus raus'.split()
ratewort = random.choice(woerter)
print (ratewort)

Wir wollen für die einzelnen Buchstaben des Wortes nur Unterstriche ausgegeben bekommen.
Zusätzlich soll ein Leerzeichen nach dem Unterstrich kommen, damit es deutlich ist, wie viele
Buchstaben es sind.

Dazu entwickeln wir in 2 Schritten den entsprechenden Code. Erst das es wie gewünscht
ausgegeben wird und dann packen wir diesen Code in eine Funktion.

Wir durchlaufen die einzelnen Buchstaben unserer Variablen „ratewort“ und lassen zum Testen
jeden Buchstaben mit Leerzeichen danach ausgeben.

Für jeden Buchstaben soll als Bildschirmausgabe ein Unterstrich mit zusätzlichem Leerzeichen
ausgeben werden:

import random
print("hangman in Python")
woerter = 'Hund Katze Maus Haus raus'.split()
ratewort = random.choice(woerter)
print (ratewort)
# zum Test nur!
for buchstaben in ratewort:
print (buchstaben, " ")

Als Ergebnis erhalten wir die einzelnen Buchstaben jeweils in einer neuen Zeile.

hangman in Python

Katze
K
a
t
z
e

Von unserem Leerzeichen sehen wir nicht mehr viel. In der alten Python2-Version konnte man
noch mit einem Komma nach der print -Anweisung den Umbruch verhindern. Wir wollen
aber nicht mit einer alten Version arbeiten! Schaut man sich den Befehlsaufbau von print()
in der aktuellen Python Version an, können wir der Funktion print() noch weitere Parameter
mitgeben wie beispielsweise end=' ' oder in unserem Fall ein Unterstrich:

for buchstaben in ratewort:


print (buchstaben, " ", end='_')

Als Ausgabe erhalten wir in einer Zeile dann:

K _a _t _z _e _

Wenn wir nur die Unterstriche ohne Buchstaben wollen, dann können wir auch nur unseren
Parameter „missbrauchen“.
© https://www.python-lernen.de/hangman-python-programmieren.htm Seite 147

for buchstaben in ratewort:


print ("", end='_ ')

Wir erhalten dann unsere gewünschte Ausgabe:

_ _ _ _ _

Im folgenden Schritt werden wir 2 Fliegen mit einer Klappe erschlagen.

Speichern von erratenen Buchstaben


Wir benötigen eine Möglichkeit, bereits erratene Buchstaben zu speichern und dann
zusammen mit den nicht erratenen (sprich die Unterstriche) auszugeben.

Legen wir dazu eine weitere Liste mit dem Namen erraten an. Diese wird am Anfang
unseres Python-Codes gemacht, damit alle Variablen und Listen-Bezeichnungen sofort
sichtbar sind:

import random
print("hangman in Python")
woerter = 'Hund Katze Maus Haus raus'.split()
erraten = []
ratewort = random.choice(woerter)

Bisher ist unsere Liste mit Leer. Also füllen wir diese vor unserer ersten Raterunde mit
Unterstrichen. Dazu durchlaufen wir mit der for -Anweisung unser durch Zufall bestimmtes
ratewort und werden für jeden einzelnen Buchstaben unsere Liste erraten mit einem
Eintrag „_“ ergänzen:

import random
print("hangman in Python")
woerter = 'Hund Katze Maus Haus raus'.split()
erraten = []
ratewort = random.choice(woerter)
for buchstaben in ratewort:
erraten.append('_')

Jetzt können wir übergehen, dass der Nutzer seine Eingaben machen kann.

Nutzereingabe in Schleife
Da unser Spiel auf jeden Fall über mehrere Runden läuft, benötigen wir eine Schleife. Diese
haben wir bereits im Kapitel zum Chatbot ( https://www.python-lernen.de/chatbot-
programmieren.htm ) kennengelernt. Der Nutzer hat auch immer die Möglichkeit das Spiel
vorzeitig zu beenden. Wieder brauchen wir eine Variable mit dem Namen nutzereingabe ,
die wir am Anfang festlegen. Und nun kommt unsere while -Schleife, bis entweder das Spiel
gewonnen oder verloren ist oder der Spieler abbricht.
© https://www.python-lernen.de/hangman-python-programmieren.htm Seite 148

import random
print("hangman in Python")
woerter = 'Hund Katze Maus Haus raus'.split()
erraten = []
nutzereingabe = ""
ratewort = random.choice(woerter)
for buchstaben in ratewort:
erraten.append('_')
while nutzereingabe != "bye":
nutzereingabe = input("Ihr Vorschlag: ")

Der Nutzer kann nun unendlich lange Vorschläge machen – noch wird weder etwas kontrolliert
noch ausgegeben.

Lassen wir vor der Nutzereingabe unseren bisherigen erraten Stand ausgeben (Unterstriche
und erratene Buchstaben) – also vor der ersten Runde nur Unterstriche.

while nutzereingabe != "bye":


for ausgabe in erraten:
print (ausgabe, end=' ')
print()
nutzereingabe = input("Ihr Vorschlag: ")

Das print() benötigen wir, damit der Text „Ihr Vorschlag:“ in der nächsten Zeile kommt.

Bisher unsere Bildschirmausgabe:

hangman in Python

_ _ _ _

Ihr Vorschlag:

Kontrolle, ob Buchstabe von Nutzereingabe in Ratewort


vorkommt
Unser Ratewort lassen wir nun Buchstabe für Buchstabe über eine for -Schleife durchlaufen
und überprüfen, ob der Spieler-Buchstabe vorkommt:

nutzereingabe = input("Ihr Vorschlag: ")


for buchstaben in ratewort:
if buchstaben == nutzereingabe:
print ("Treffer")

Jetzt kann schon getestet werden und wir erhalten bei Übereinstimmung als
Bildschirmausgabe „Treffer“.

Jetzt ist es wichtig, einfach auch Großschreibung zu testen bzw. was passiert, wenn mehr als
1 Buchstaben durch den Spieler eingegeben wird.

Ergebnis:

Eine Eingabe von mehr als einem Buchstaben durch den Spieler läuft ins Leere. Dann hat der
Spieler Pech gehabt – damit können wir leben (zumal der Spieler auch „bye“ zum Spielabbruch
© https://www.python-lernen.de/hangman-python-programmieren.htm Seite 149

eingeben können muss).

Großschreibung ist ein Problem – sowohl bei Eingabe des Spielers wie auch beim zu
erratendem Wort. Also vergleichen wir immer nur Kleinbuchstaben und wir sind aus dem
Problem raus.

import random
print("hangman in Python")
woerter = 'Hund Katze Maus Haus raus'.split()
erraten = []
nutzereingabe = ""
ratewort = random.choice(woerter)
for buchstaben in ratewort:
erraten.append('_')
while nutzereingabe != "bye":
for ausgabe in erraten:
print (ausgabe, end=' ')
print()
nutzereingabe = input("Ihr Vorschlag: ")
for buchstaben in ratewort:
if buchstaben.lower() == nutzereingabe.lower():
print ("Treffer")

Richtiges Raten eines Buchstabens speichern


Zusätzlich zu der Bildschirmausgabe „Treffer“ soll der korrekte Buchstabe in unserer Liste
erraten an den entsprechenden Positionen gespeichert werden.

Dazu brauchen wir noch eine Hilfsvariable „x“ um die Position des aktuellen Buchstabens in
der Liste zu kennen.

Diese Hilfsvariable wird bei jedem Durchlauf hochgezählt und bei einem Treffer wird der
Buchstabe in unserer Liste erraten an der entsprechenden Position eingetragen:

x = 0
for buchstaben in ratewort:
if buchstaben.lower() == nutzereingabe.lower():
print ("Treffer")
erraten[x] = buchstaben
x += 1

Spiel gewonnen?
Jetzt wollen wir kontrollieren, ob das Spiel gewonnen wurde. Dazu dürfen in unserer Liste
erraten keine Unterstriche mehr vorhanden sein. Diese Kontrolle läuft bei Listen sehr
einfach über die Python-Anweisung in .

# Kontrolle ob gewonnen
if '_' in erraten:
print('Noch nicht gewonnen')
else:
print("gewonnen")
© https://www.python-lernen.de/hangman-python-programmieren.htm Seite 150

Damit das Python-Programm bei gewonnenem Spiel beendet wird, müssen wir nur unsere
Schleife vorzeitig beenden. Das können wir über die Anweisung break erzwingen.

import random
print("hangman in Python")
woerter = 'Hund Katze Maus Haus raus'.split()
erraten = []
nutzereingabe = ""
ratewort = random.choice(woerter)
for buchstaben in ratewort:
erraten.append('_')
while nutzereingabe != "bye":
for ausgabe in erraten:
print (ausgabe, end=' ')
print()
nutzereingabe = input("Ihr Vorschlag: ")
x = 0
for buchstaben in ratewort:
if buchstaben.lower() == nutzereingabe.lower():
print ("Treffer")
erraten[x] = buchstaben
x += 1
print()
# Kontrolle ob gewonnen
if '_' in erraten:
print('Noch nicht gewonnen')
else:
print("gewonnen")
break

Spiel verloren?

Bisher können wir unendlich lange raten und habe nicht das Spiel verloren. Daher sollten wir
die Bedingung, wann das Spiel verloren ist einbauen. Verloren ist, wenn man 7-mal einen
falschen Tipp als Spiel abgibt. Diese Zahl führen wir in der Variabel fehlversuche mit. Auch
diese wird am Anfang festgelegt.

Innerhalb der Kontrolle, ob gewonnen nehmen wir die Kontrolle auf, ob verloren. Die Ausgabe
„Noch nicht gewonnen“ werden deaktiviert.

# Kontrolle ob gewonnen
if '_' in erraten:
# print('Noch nicht gewonnen')
fehlversuche -= 1
if fehlversuche == 0:
print("Schade - verloren!")
break
else:
print("gewonnen")
break

Und somit haben wir den kompletten Python-Programmcode für unser Galgenmännchen-Spiel.
© https://www.python-lernen.de/hangman-python-programmieren.htm Seite 151

import random
print("hangman in Python")
woerter = 'Hund Katze Maus Haus raus'.split()
erraten = []
nutzereingabe = ""
fehlversuche = 7
ratewort = random.choice(woerter)
for buchstaben in ratewort:
erraten.append('_')
while nutzereingabe != "bye":
for ausgabe in erraten:
print (ausgabe, end=' ')
print()
nutzereingabe = input("Ihr Vorschlag: ")
x = 0
for buchstaben in ratewort:
if buchstaben.lower() == nutzereingabe.lower():
print ("Treffer")
erraten[x] = buchstaben
x += 1
print()
# Kontrolle ob gewonnen
if '_' in erraten:
# print('Noch nicht gewonnen')
fehlversuche -= 1
if fehlversuche == 0:
print("Schade - verloren!")
break
else:
print("Gewonnen, das Wort war: ", ratewort)
break
© https://www.python-lernen.de/funktionen-in-python.htm Seite 152

Funktionen in Python
Bisher haben wir unsere Programmcode einfach von oben nach unten geschrieben und in
dieser Reihenfolge wurde dieser abgearbeitet. Jetzt kann es vorkommen, dass wir einige
Programmabläufe öfters benötigen. Beispielsweise wollen wir die Uhrzeit am Programmstart
und am Programmende ausgeben. Dazu müssten wir den gleichen Code also verdoppelt und
am Anfang und Ende unseres Programmes schreiben. Das bläht das Programm auf und bringt
unnötige Fehlerquellen. Hier helfende Funktionen.

Was ist eine Funktion?


Eine Funktion ist ein erstellter Programmcode, der aus dem „von-oben-nach-unten“-Ablauf des
Programmes genommen wird und gezielt aufgerufen werden muss bzw. kann. Das ermöglicht
uns, diese Funktionen auch bei Bedarf öfters aufzurufen und somit übersichtlichen Code zu
schreiben, der weniger Fehlerquellen enthält.

Wir vergeben also einen Namen für unsere Funktion, die wir an jeder beliebigen Stelle in
unserem Python-Programm aufrufen können.

Hierzu wird eine Funktion definiert. Und genau dieses Schlüsselwort def erwartet Python
auch, wenn ein Funktionsname festlegt wird. Die typischen Klammern danach zeigen auch,
dass es sich um eine Funktion handelt. Aber definieren wir es eine Funktion. Die nichts
anderes macht, als die Textausgabe "Ausgabe von Text aus einer Funktion".

def ausgabe():
print("Ausgabe von Text aus einer Funktion")

print("Programm abgelaufen")

Alles was eingerückt ist, gehört zu unserer definierten Funktion.

Rufen wir nun unser Programm auf, erhalten wir nur die Ausgabe:

Programm abgelaufen

Die neue Funktion mit dem Namen ausgabe selber wurde offensichtlich nicht ausgeführt,
sonst hätte eine weitere Textausgabe stattfinden müssen.

Zum Aufrufen einer Funktion benötigen wir den Funktionsnamen gefolgt von den runden
Klammern.

def ausgabe():
print("Ausgabe von Text aus einer Funktion")

ausgabe()
print("Programm abgelaufen")

Jetzt erhalten wir die erwartete Ausgabe

Ausgabe von Text aus einer Funktion

Programm abgelaufen
© https://www.python-lernen.de/funktionen-in-python.htm Seite 153

Die Funktion können wir beliebig oft aufrufen. So können wir Code recyceln und sparen uns
Tipparbeit:

def ausgabe():
print("Ausgabe von Text aus einer Funktion")

ausgabe()
ausgabe()
print("Programm abgelaufen")

Werte in die Funktion übergeben


In die Funktionen hinein können Parameter übergeben werden. Dazu erweitern wir bei der
Definition die Klammern, die bisher leer waren. Hier legen wir die Variablennamen fest. Mit
diesen Variablen kann dann in der Funktion gearbeitet werden. Diesen Wert muss bei
Funktionsaufruf in den Klammern übergeben werden. Wir übergeben die Zahl 5 in die Funktion:

def ausgabe(wert1):
print("Ausgabe von Text aus einer Funktion")
print(wert1)

ausgabe(5)

Als Ausgabe erfolgt nun:

Ausgabe von Text aus einer Funktion

mehrere Werte in Funktion übergeben


Soll nicht nur ein Wert, sondern mehrere Werte übergeben werden, werden die Variablennamen
über Kommas getrennt.

def ausgabe(wert1, wert2):


print("Ausgabe von Text aus einer Funktion")
print(wert1)
print(wert2)

ausgabe(5,3)

Jetzt kann man natürlich nach Belieben mit den vorhandenen Variablen arbeiten. Als Beispiel
lassen wir nun in der Funktion hinein 3 Werte übertragen und dann mit der Funktion eine for -
Ausgabe (siehe früheres Kapitel über for ) und entsprechender Schrittweite.

def ausgabe(anfangswert, endwert, schrittweite):


for x in range(anfangswert, endwert, schrittweite):
print(x)
print("Funktion ausgabe durchlaufen")

ausgabe(4, 9, 2)
ausgabe(-5, -8, -1)
print("habe fertig")
© https://www.python-lernen.de/funktionen-in-python.htm Seite 154

Wir erhalten nun die Ausgabe:

4
6
8
Funktion ausgabe durchlaufen
5
6
7
Funktion ausgabe durchlaufen
habe fertig

Somit sind wir deutlich flexibler bei der Ausgabe geworden. Je nach Anwendung ist der
Umfang innerhalb einer Funktion deutlich umfangreicher als unsere 3 Beispielzeilen. An der
Funktion und den Einsatzmöglichkeiten ändert sich dadurch nichts.

Standardvorgabe bei Funktionsaufruf


In unserem letzten Beispiel haben wir eine for -Schleife ausgegeben. In vielen Fällen ist die
Schrittweite sehr oft 1. Daher wäre schön, wenn wir nur eine Angabe der Schrittweite machen
müssen, wenn diese von 1 abweicht. Und das ist sehr einfach bei Python-Funktion möglich. Wir
können einen Vorgabewert setzen. Dazu wird der Variablen bei der Definition über ein
Gleichzeichen der Vorgabewert mitgegeben. Kommt kein Wert von außen, wird der
Vorgabewert genutzt. Kommt ein Wert durch den Funktionsaufruf von außerhalb der Variablen,
wieder dieser verwendet.

def ausgabe(anfangswert, endwert, schrittweite=1):


for x in range(anfangswert, endwert, schrittweite):
print(x)
print("Funktion ausgabe durchlaufen")

ausgabe(4, 9)
ausgabe(4, 9, 2)

Als Ergebnis erhalten wir:

4
5
6
7
8
Funktion ausgabe durchlaufen
4
6
8
Funktion ausgabe durchlaufen

Beim ersten Aufruf wird der Vorgabewert von 1 genommen und wir sparen Tipparbeit beim
Standardfall. Beim zweiten Aufruf wird die übergeben 2 als Schrittweite genutzt.
© https://www.python-lernen.de/funktionen-in-python.htm Seite 155

Wollen wir nun auch den Startwert für unsere for -Ausgabe auf 1 setzen, weil in unserem Fall
das sehr oft vorkommt, können wir das tun:

def ausgabe(anfangswert=1, endwert, schrittweite=1):


for x in range(anfangswert, endwert, schrittweite):
print(x)
print("Funktion ausgabe durchlaufen")

ausgabe(9)

Allerdings führt es zu der Fehlermeldung „SyntaxError: non-default argument follows default


argument“. Warum? Der Interpreter von Python weist die Zahl 9 unserem Anfangswert zu und
erwartet dann für den endwert auf jeden Fall eine Eingabe. Da dieser keine Vorgabe hat, wirft
Python mit Fehlermeldungen nach uns.

Hier ist die übliche Vorgehensweise, dass Werte mit Vorgaben einfach rechts von den Werten
ohne Vorgaben stehen. Bauen wir unser Beispiel entsprechend um:

def ausgabe(endwert, anfangswert=1, schrittweite=1):


for x in range(anfangswert, endwert, schrittweite):
print(x)
print("Funktion ausgabe durchlaufen")

ausgabe(9)

Jetzt funktioniert unserer Funktion auch mit dem Aufruf von nur einer Angabe. Allerdings
müssen wir im Hinterkopf haben, dass nun die Reihenfolge des Funktionsaufrufs erst der
endwert, dann ein eventueller anfangswert (wenn nicht anders als 1) und eine
schrittweite (wenn nicht anders als 1) ist.

Das ist die übliche Vorgehensweise und kann extrem viel Tipparbeit sparen.
© https://www.python-lernen.de/funktionen-mit-variabler-parameteranzahl.htm Seite 156

Funktionen mit variabler Parameteranzahl


Bisher sind wir bei der Übergabe der Parameter immer davon ausgegangen, dass wir die
Anzahl der Parameter kennen.

def ausgabe(wert1, wert2):


print("Ausgabe von Text aus einer Funktion")
print(wert1)
print(wert2)

ausgabe(5,3)

Was passiert aber, wenn wir die Anzahl der Parameter nicht kennen? Wenn also eine variable
Parameteranzahl vorliegt? Auch für diesen Fall hat und Python eine Lösung. Wir kennzeichnen
unseren Parameternamen mit einem Stern am Anfang.

def ausgabe( *mehrereParameter ):


for einzelwert in mehrereParameter:
print(einzelwert)

ausgabe("Hallo", "Welt", "guten", "Morgen")

Jetzt können wir beliebig viele Parameter übergeben. Die Ausgabe des Beispielcodes ergibt:

Hallo
Welt
guten
Morgen

Jeder einzelne Parameter wird über die print -Ausgabe in einer eigenen Zeile ausgegeben.

Allerdings funktioniert eine Vorbelegung eines einzelnen Parameters nicht mehr, wie wir es
bereits kennengelernt haben:

def ausgabe(wert1="Hallo", wert2="Welt"):


print("Ausgabe von Text aus einer Funktion")
print(wert1)
print(wert2)

ausgabe(5,3)

Wir haben bei Funktionen mit variabler Parameteranzahl auch keinen einzelnen Parameter –
die folgende Konstruktion führt zu der Fehlermeldung "SyntaxError: invalid syntax".

def ausgabe( *mehrereParameter="falsch!" ):

Und das gute ist – wir benötigen es in diesem Fall auch nicht wirklich. Wir können beliebig viele
Parameter übergeben. Und dabei meint mit "beliebig viele" auch keinen Inhalt. Folgender Code
wird ohne Fehlermeldung korrekt abgearbeitet – es erfolgt auch keine Ausgabe, denn wir
haben auch keinen Inhalt unserem Parameter "*mehrereParameter" übergeben:
© https://www.python-lernen.de/funktionen-mit-variabler-parameteranzahl.htm Seite 157

def ausgabe( *mehrereParameter ):


for einzelwert in mehrereParameter:
print(einzelwert)

ausgabe()

Vorsicht bei der Verwendung! Hier wird eine spätere Fehlersuche aufwendiger – besonders bei
Logikfehlern.

*args and **kwargs – Konventionen unter Programmierer


Bei der eingeführten variablen Parameteranzahl haben wir oben im Beispiel die Bezeichnung
*mehrereParameter verwendet. Das funktioniert auch wunderbar. Wer diesen Bereich von
Python kennt, wundert sich vielleicht über die gewählte Bezeichnung. Viele Tutorials
verwenden hier die Bezeichnung *args und **kwargs . Wichtig sind nur die
Sternchenoperatoren am Anfang – die Bezeichnung danach kann beliebig gesetzt werden! Die
nach Konvention benutzte Bezeichnung *args steht einfach für das englische „arguments“.
Somit haben wir die Wortherkunft. Für den Einsteiger ist es meiner Erfahrung nach klarer, wenn
man erst einmal *mehrereParameter verwendet.

Unterschied zwischen *args and **kwargs


Bei der Verwendung von **kwargs spielen Dictionary die Hauptrolle. Wir verwenden für die
Parameterübergabe also Key-Value Paare.

def uebergeben(**kwargs):
for key, value in kwargs.items():
print("{0} = {1}".format(key, value))

uebergeben(vorname="Axel")

Als Ergebnis erhalten wir:

vorname = Axel

Und was ist die Herkunft der Bezeichnung **kwargs? Diese kommt aus Englischen
keywordarguments.

In der deutschen Schreibweise müsste dann unser **kwargs dann etwas mit
*mehrereWoerterbuchParameter sich nennen. Kann man machen, muss man aber nicht.
Wie gesagt: Es sind primär die zwei Sternchenoperatoren am Anfang wichtig – alles danach
kann nach Belieben benannt werden.

Reihenfolge, wenn alle 3 Arten von Übergaben verwendet


werden
Wenn wir in unserem Programm nun alle 3 Arten von Übergaben verwenden wollen, dann muss
die Reihenfolge eingehalten werden:

eineFunktion(Argument1, *args, **kwargs)


© https://www.python-lernen.de/funktionen-mit-variabler-parameteranzahl.htm Seite 158
© https://www.python-lernen.de/rueckgabewert-funktionen.htm Seite 159

Rückgabewert bei Funktionen


Funktionen sind praktisch um immer wieder verwendeten Code nutzen zu können. Bisher
haben wir bei unseren Funktionen in Python immer fleißig Daten in die Funktion reingegeben.
In diesem Kapitel lassen wir uns Ergebnisse aus einer Funktion herausgeben.

Mit den herausgegebenen Ergebnissen in Form von Variablen können wir dann im weiteren
Programmcode nach Belieben weiteres anstellen.

Unsere Funktion haben dann folgenden Aufbau:

def bspfunktionfuerrueckgabe(eingabewert):
rueckgabewert = eingabewert * 2
return rueckgabewert

ergebnisausfunktion = bspfunktionfuerrueckgabe (5)


print(ergebnisausfunktion)

Wir übergeben in unserem obigen Beispiel die Zahl 5 in unserer Funktion mit dem vielsagenden
Namen „ bspfunktionfuerrueckgabe “. In der Funktion wird nun etwas mit dem
hereingegeben Wert angestellt – im Beispiel einfach verdoppelt und dann über return das
Ergebnis wieder aus der Funktion gegeben.

Außerhalb bekommt unser Funktionsaufruf vorneweg eine Variable, die das zurückgelieferte
Ergebnis aufnehmen soll und ein Gleichheitszeichen.

Warum Variable über return übergeben


Warum müssen wir überhaupt die Variable über die return -Funktion zurückgeben?
Eigentlich geben wir nicht die Variable, sondern den Wert der Variable zurück.

Die Variable steht außerhalb der Funktion nicht zur Verfügung. Probieren wir in unserem
Python-Programm einfach nach Aufruf der Funktion direkt auf die Variable rueckgabewert ,
die nur innerhalb der Funktion benutzt wird, außerhalb der Funktion zu nutzen, erhalten wir die
Fehlermeldung: „NameError: name 'rueckgabewert' is not defined“

def bspfunktionfuerrueckgabe(eingabewert):
rueckgabewert = eingabewert * 2
return rueckgabewert

ergebnisausfunktion = bspfunktionfuerrueckgabe (5)


print(ergebnisausfunktion)
print(rueckgabewert)

Dies ist eine extrem praktische Einrichtung, da wir beim Erstellen unserer Funktion nicht auf die
genutzten Variablennamen außerhalb der Funktion achten müssen. Wir können alles nach
Belieben verwenden.

Geltungsbereich/Gültigkeitsbereich von Variablen


Das Verständnis der Unterschiede zwischen globalen und lokalen Variablen ist extrem wichtig
bei der Verwendung von Variablen innerhalb und außerhalb von Funktionen.

Bauen wir für das Verständnis ein kleines Python-Programm auf, dass nur für die Nutzung der
Variablen da ist. Dazu haben wir eine Funktion und diese Funktion bekommt Funktionen
© https://www.python-lernen.de/rueckgabewert-funktionen.htm Seite 160

integriert. Aber Schritt für Schritt:

variablenWert = "außerhalb der Funktion"


print("Variablenwert vor Funktion:", variablenWert)
def bspfunktion():
print("Variablenwert in Funktion 1:", variablenWert)
variablenWert = "IN der Funktion"
print("Variablenwert in Funktion 2:", variablenWert)

bspfunktion()
print("Variablenwert nach Funktion:", variablenWert)

Ab jetzt sind Fehlermeldungen interessant. Das Programm läuft die ersten 2 Zeilen noch
problemlos. Die Variable mit dem Namen variablenWert wird vor der Funktion gesetzt und
direkt ausgegeben. Das funktioniert problemlos.

Danach wird die Funktion aufgerufen und in der Funktion soll sofort die außerhalb gesetzte
Variable variablenWert ausgegeben werden. Jetzt erhalten wir unsere erste
Fehlermeldung „UnboundLocalError: local variable 'variablenWert' referenced before
assignment“. Die Variable existiert offensichtlich nicht innerhalb der Funktion.

Also nehmen wir diese Zeile raus und setzen der Wert der Variable neu innerhalb der Funktion.

variablenWert = "außerhalb der Funktion"


print("Variablenwert vor Funktion:", variablenWert)
def bspfunktion():
variablenWert = "IN der Funktion"
print("Variablenwert in Funktion:", variablenWert)

bspfunktion()
print("Variablenwert nach Funktion:", variablenWert)

Nun bekommen wir keine Fehlermeldung mehr aber der gleiche Variablennamen ist
offensichtlich unterschiedlich vom Wert – je nachdem, ob er in oder außerhalb der Funktion
benutzt wird.

Als Ergebnis sehen wir:

Variablenwert vor Funktion: außerhalb der Funktion

Variablenwert in Funktion: IN der Funktion

Variablenwert nach Funktion: außerhalb der Funktion

Globale Variablen
Nun steigern wir die Komplexität, da wir eine Variable auch als global definieren können.

Innerhalb der Funktion setzen wir unsere Variable " variablenWert " auf global
© https://www.python-lernen.de/rueckgabewert-funktionen.htm Seite 161

variablenWert = "außerhalb der Funktion"


print("Variablenwert vor Funktion:", variablenWert)
def bspfunktion():
global variablenWert
variablenWert = "IN der Funktion"
print("Variablenwert in Funktion:", variablenWert)

bspfunktion()
print("Variablenwert nach Funktion:", variablenWert)

Jetzt bekommen wir als Ausgabe:

Variablenwert vor Funktion: außerhalb der Funktion

Variablenwert in Funktion: IN der Funktion

Variablenwert nach Funktion: IN der Funktion

Wir haben also den Wert der außerhalb gesetzten Variablen überschrieben mit einer Variablen
in der Funktion.

Und noch eine Steigerung!

nonlocal in Python für Variablen


Zwischen global und local gibt es noch eine Zwischenform. Dazu muss man wissen,
dass wir in Funktionen weitere Funktionen packen können, die aber nur für die jeweilige
Funktion innerhalb der Funktion zur Verfügung steht. Und hier können wir in der Funktion in der
Funktion ein Variable erstellen, die dann auch in der aufrufenden Funktion verfügbar ist.

Das ist etwas, was man bei Bedarf einfach nochmals durchlesen sollte. Hier der
Vollständigkeit halber.

Im Beispiel wird es klarer:


© https://www.python-lernen.de/rueckgabewert-funktionen.htm Seite 162

variable = "Inhalt außerhalb gesetzt"


def grundfunktion():
variable = "Inhalt innerhalb gesetzt"

def fkt_local():
variable = "Inhalt innerhalb local"

def fkt_nonlocal():
nonlocal variable
variable = "Inhalt innerhalb nonlocal"

def fkt_global():
global varibale
variable = "Inhalt innerhalb global"

print("2. in Fkt: ", variable)


fkt_local()
print("3. in Fkt – flt_local aufgerufen: ", variable)
fkt_nonlocal()
print("4. in Fkt – flt_nonlocal aufgerufen: ", variable)
fkt_global()
print("5. in Fkt – flt_global aufgerufen: ", variable)

print("1. vor Funktionsaufruf: ", variable)


grundfunktion()
print("6. nach Funktionsaufruf: ", variable)

Was erhalten wir als Ergebnis?

1. vor Funktionsaufruf: Inhalt außerhalb gesetzt

2. in Fkt: Inhalt innerhalb gesetzt

3. in Fkt – flt_local aufgerufen: Inhalt innerhalb gesetzt

4. in Fkt – flt_nonlocal aufgerufen: Inhalt innerhalb nonlocal

5. in Fkt – flt_global aufgerufen: Inhalt innerhalb global

6. nach Funktionsaufruf: Inhalt innerhalb global

Schaut man sich das Ergebnis an, wird der Geltungsbereich der Variablen und die
Möglichkeiten, diese durch nonlocal und global zu erweitern, deutlich.

Stichworte dazu sind: local_scope

Vorteile von Funktionen


Dadurch werden unsere Funktionen auch für weitere Projekte wiederverwertbar! Benötigen wir
wieder diese Funktion, können wir unsere bereits aus einem alten Projekt erstellte Funktion in
unser neues Projekt übernehmen (egal welche Variablennamen in der Funktion früher
verwendet wurden).

Wie wir universelle verwendbare Funktionen einfach einbindet, sehen wir im folgenden Kapitel.
© https://www.python-lernen.de/rueckgabewert-funktionen.htm Seite 163
© https://www.python-lernen.de/built-in-functions.htm Seite 164

eingebaute Funktionen („Built-in Functions“)


Eine Frage ist immer, welche Methoden und Klassen enthält ein Paket? Was gibt es bereits an
Funktionen und kann sehr einfach genutzt werden, ohne dass man das Rad neu erfinden
muss? Auch was ist bereits vorhanden und muss bzw. muss nicht importiert werden

Über dir haben wir eine mächtige Funktion, die uns eine Liste der Attribute und Methoden
von jedem Objekt zurückliefert.

bei Klassen-Objekten wird eine Liste von Namen aller validen Attribute (und auch Basis-
Attribute) zurück übergeben

bei Modulen (Library-Objekten) wird eine Liste der Namen von allen Attributen, die in dem
Modul vorhanden sind.

wenn kein Parameter angegeben wird, wird eine Liste von Namen des aktuellen lokalen
Geltungsbereichs/Namensbereich („local scope“) zurückgeliefert

Das letzte Verhalten machen wir uns zunutze.

>>> dir()

Als Rückmeldung erhalten wir:

['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__']

Mehr Informationen (Anmerkung: In Python 2.7 wurde noch bedeutend weniger bzw. anders
ausgegeben) erhalten wir über die bereits enthaltenen Funktionen und Typen von Python mit

dir(__builtins__)

Als Ergebnis erhalten wir:


© https://www.python-lernen.de/built-in-functions.htm Seite 165

>>> dir(__builtins__)

['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BlockingIOError',


'BrokenPipeError', 'BufferError', 'BytesWarning', 'ChildProcessError', 'ConnectionAbortedError',
'ConnectionError', 'ConnectionRefusedError', 'ConnectionResetError', 'DeprecationWarning',
'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FileExistsError', 'FileNotFoundError',
'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning',
'IndentationError', 'IndexError', 'InterruptedError', 'IsADirectoryError', 'KeyError',
'KeyboardInterrupt', 'LookupError', 'MemoryError', 'ModuleNotFoundError', 'NameError', 'None',
'NotADirectoryError', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError',
'PendingDeprecationWarning', 'PermissionError', 'ProcessLookupError', 'RecursionError',
'ReferenceError', 'ResourceWarning', 'RuntimeError', 'RuntimeWarning', 'StopAsyncIteration',
'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError',
'TimeoutError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError',
'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning',
'ValueError', 'Warning', 'ZeroDivisionError', '_', '__build_class__', '__debug__', '__doc__',
'__import__', '__loader__', '__name__', '__package__', '__spec__', 'abs', 'all', 'any', 'ascii', 'bin', 'bool',
'breakpoint', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'compile', 'complex', 'copyright',
'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'exec', 'exit', 'filter', 'float', 'format',
'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass',
'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord',
'pow', 'print', 'property', 'quit', 'range', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted',
'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars', 'zip']

Mehr über die einzelnen Objekte zu erfahren nutzt man die Anweisung help

Möchte man also mehr über die print-Funktion erfahren, gibt man einfach ein:

help(print)

Als Ausgabe erfolgt:

>>> help(print)

Help on built-in function print in module builtins:

print(...)

print(value, ..., sep=' ', end='

', file=sys.stdout, flush=False)

Prints the values to a stream, or to sys.stdout by default.

Optional keyword arguments:

file: a file-like object (stream); defaults to the current sys.stdout.

sep: string inserted between values, default a space.

end: string appended after the last value, default a newline.

flush: whether to forcibly flush the stream.


© https://www.python-lernen.de/built-in-functions.htm Seite 166

Die erste Linie zeigt einem, aus welchem Modul diese Funktion ist – im Fall von print
kommt diese Funktion aus bereits im System integrierten Bereich. Wir müssen also nichts in
unser Python-Programm importieren, um diese Funktion nutzen zu können.

In den darauffolgenden Linien wird die Nutzungsweise beschreiben.

Man sieht bei dieser Funktion, dass weitere Parameter übergeben werden können (was auch
Sinn ergibt, sonst wird nichts ausgegeben). Auch sind bereits Parameter mit
Standardausgaben belegt wie beispielsweise der Separator sep=' ' als Leerzeichen.

Hier können wir eingreifen, wenn gewünscht. Anstelle des Leerzeichens des Separators lassen
wir einen Unterstrich ausgeben:

>>> print("Hallo", "Welt", "Wie", sep='_')

Als Ergebnis erhalten wir:

Hallo_Welt_Wie

Schauen wir uns eine weitere Funktion an: hex

>>> help(hex)

Help on built-in function hex in module builtins:

hex(number, /)

Return the hexadecimal representation of an integer.

>>> hex(12648430)

'0xc0ffee'

Wir haben wieder eine Funktion die „ab Werk“ sofort in Python zur Verfügung steht.

Es wird eine Ganzzahl (Integer) als Hexadezimale Zahl ausgegeben:

>>> hex(255)
'0xff'

Wir sehen, dass wir als Rückgabe einen String erhalten – daher wird der Rückgabewert in
Anführungszeichen ausgegeben.

Wofür steht das „0x“? Das ist sehr einfach: das x steht für „heXadezimal“. Hätten wir einen
binären Wert (z.B. 0110011) würde als Präfix „0b“ für „Binär“ ausgegeben. Für eine klare
Abgrenzung zu einer dezimalen Zahl fangen hexadezimale und binäre Zahlen immer damit an
– das wurde bereits in der ANSI Norm für C Compiler anno dazumal festgelegt.

Siehe dazu einfach auch help(bin)

Durch die Schreibweise wird auch direkt im Python-Interpreter eine binäre bzw. Hexadezimale
Eingabe in dezimaler Ausgabe zurückgegeben:

>>> 0xff
255
© https://www.python-lernen.de/built-in-functions.htm Seite 167

Liste von Modulen


Um alle weiteren Module angezeigt zu bekommen, einfach eingeben:

>>> help('modules')

Wir bekommen daraufhin eine sehr umfangreiche Ausgabe aller Module:


© https://www.python-lernen.de/built-in-functions.htm Seite 168

>>> help('modules')

Please wait a moment while I gather a list of all available modules...

__future__ _threading_local getpass rlcompleter


_abc _tkinter gettext runpy
_ast _tracemalloc glob sched
_asyncio _uuid grp secrets
_bisect _warnings gzip select
_blake2 _weakref hashlib selectors
_bootlocale _weakrefset heapq setuptools
_bz2 _xxtestfuzz hmac shelve
_codecs abc html shlex
_codecs_cn aifc http shutil
_codecs_hk antigravity idlelib signal
_codecs_iso2022 argparse imaplib site
_codecs_jp array imghdr smtpd
_codecs_kr ast imp smtplib
_codecs_tw asynchat importlib sndhdr
_collections asyncio inspect socket
_collections_abc asyncore io socketserver
_compat_pickle atexit ipaddress sqlite3
_compression audioop itertools sre_compile
_contextvars base64 json sre_constants
_crypt bdb keyword sre_parse
_csv binascii lib2to3 ssl
_ctypes binhex linecache stat
_ctypes_test bisect locale statistics
_curses builtins logging string
_curses_panel bz2 lzma stringprep
_datetime cProfile macpath struct
_dbm calendar mailbox subprocess
_decimal cgi mailcap sunau
_dummy_thread cgitb marshal symbol
_elementtree chunk math symtable
_functools cmath mimetypes sys
_hashlib cmd mmap sysconfig
_heapq code modulefinder syslog
_imp codecs multiprocessing tabnanny
_io codeop netrc tarfile
_json collections nis telnetlib
_locale colorsys nntplib tempfile
_lsprof compileall ntpath termios
_lzma concurrent nturl2path test
_markupbase configparser numbers textwrap
_md5 contextlib opcode this
_multibytecodec contextvars operator threading
_multiprocessing copy optparse time
_opcode copyreg os timeit
_operator crypt parser tkinter
_osx_support csv pathlib token
_pickle ctypes pdb tokenize
_posixsubprocess curses pickle trace
_py_abc dataclasses pickletools traceback
_pydecimal datetime pip tracemalloc
_pyio dbm pipes tty
_queue decimal pkg_resources turtle
_random difflib pkgutil turtledemo
_scproxy dis platform types
_sha1 distutils plistlib typing
_sha256 doctest poplib unicodedata
_sha3 dummy_threading posix unittest
_sha512 easy_install posixpath urllib
_signal email pprint uu
_sitebuiltins encodings profile uuid
_socket ensurepip pstats venv
_sqlite3 enum pty warnings
_sre errno pwd wave
_ssl faulthandler py_compile weakref
_stat fcntl pyclbr webbrowser
_string filecmp pydoc wsgiref
_strptime fileinput pydoc_data xdrlib
_struct fnmatch pyexpat xml
_symtable formatter queue xmlrpc
_sysconfigdata_m_darwin_darwin fractions quopri xxlimited
_testbuffer ftplib random xxsubtype
_testcapi functools re zipapp
_testimportmultiple gc readline zipfile
_testmultiphase genericpath reprlib zipimport
_thread getopt resource zlib

Enter any module name to get more help. Or, type "modules spam" to search

for modules whose name or summary contain the string "spam".

Um ein Modul nutzen zu können, müssen wir dieses im ersten Schritt importieren:
© https://www.python-lernen.de/built-in-functions.htm Seite 169

import math

Zur Kontrolle, ob der Import geklappt hat und uns dieses Modul zur Verfügung steht, können
wir die Funktion dir() aufrufen.

dir()

Nun sollte das Modul zusätzlich erscheinen:

>>> dir()

['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__',


'math']

Um die nun durch „math“ möglichen Funktionen anzusehen, einfach auf diese dir(math)
anwenden.

>>> dir(math)

['__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin',


'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1',
'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf',
'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'pi', 'pow', 'radians', 'remainder',
'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'trunc']

Es werden bei dem Aufruf keine Anführungszeichen verwendet! Wir wollen das Modul nutzen
und nicht einen Zeichenkette (string).

Um nun weitere Hilfen über help für die im Modul math vorhandenen Möglichkeiten zu
bekommen muss immer das Modul mit angegeben werden. Ansonsten bekommen wir eine
„Traceback“-Fehlermeldung.

>>> help(math.sin)
Help on built-in function sin in module math:
sin(x, /)
Return the sine of x (measured in radians).

Testen wir die Sinusfunktion:

>>> sin(45)
Traceback (most recent call last):
File "<pyshell#33>", line 1, in <module>
sin(45)
NameError: name 'sin' is not defined

Wir erhalten als Fehler einen NameError.

Wir müssen also immer den Pfad zur Funktion „math“ angeben, um die Funktion nutzen zu
können.

>>> math.sin(45)
0.8509035245341184
© https://www.python-lernen.de/built-in-functions.htm Seite 170
© https://www.python-lernen.de/module-in-python.htm Seite 171

Module in Python nutzen


In den letzten Kapiteln haben wir fleißig Funktionen erstellt.

Wir könnten durch „Copy-and-paste“ diese einfach immer wieder in neue Projekte einfügen.
Dagegen sprechen mehrere Dinge. Unser Code wird unnötig aufgebläht, da wir in jeder
Programmdatei (und ein Programm kann ja aus mehreren Dateien durchaus bestehen) den
Code integrieren müssten und Fehler sich so fleißig „vermehren“ und die Beseitigung
dementsprechend aufwendig wird. Das beste Argument ist, dass es eine sehr viel einfachere
Vorgehensweise gibt.

Jetzt wäre es doch sehr praktisch alle unsere Funktionen in einer Datei zu haben, dir wir immer
wieder in unseren Projekten verwenden. Das geht in Python sehr einfach. Man spricht in
Python von Modulen. Schauen wir uns die Verwendung von Modulen an, dann sind die Vorteile
schnell griffig und verständlich.

Dazu gibt es den import -Befehl. Wichtig dabei ist, dass beide Dateien im selben Verzeichnis
sich befinden. Erstellen wir als Erstes unsere Funktionssammlung in der Datei
„fktsammlung.py“. In unserer Sammlung von Funktionen haben wir 2 Beispielfunktionen, von
denen wir annehmen, dass wir diese immer wieder und in verschiedenen Projekten benötigen.
Als Erstes die Funktion, die wir im letzten Kapitel als Beispiel für Rückgabewerte erstellt haben
und eine Funktion zur Begrüßung.

Die Funktion aus dem letzten Kapitel:

def bspfunktionfuerrueckgabe(eingabewert):
rueckgabewert = eingabewert * 2
return rueckgabewert

Und unsere Funktion zur Begrüßung (da gibt es ein Kartenspiel, das diese Begrüßung
verwendet).

def bspfunktionfuerrueckgabe(eingabewert):
rueckgabewert = eingabewert * 2
return rueckgabewert

def hallomeister():
print("Hallo Herr und Meister")

Diese beiden Funktionen speichern wir in der Datei „fktsammlung.py“. Würden wir das Python-
Programm ablaufen lassen, würde absolut nichts passieren, da zwar die Funktionen definiert
sind, diese aber nicht aufgerufen werden. Dies wollen wir ja aus einer anderen Programmdatei
machen.

Unsere Datei, die unsere Funktionssammlung verwendet, muss sich im selben Verzeichnis wie
unsere Datei „fktsammlung.py“ befinden.

Im ersten Schritt werden wir in der neuen Datei „beispieleinsatzmodule.py“ die


Funktionssammlung importieren. Hier ist wichtig, dass der Dateinamen ohne Schreibfehler und
ohne die Endung „.py“ eingetragen wird!

import fktsammlung

Jetzt könnte man natürlich auf die Idee kommen, einfach in unseren neuen Dateien die
Funktion hallomeister aufrufen. Das würde eine Fehlermeldung ergeben. Wir müssen
auch das Modul angeben!
© https://www.python-lernen.de/module-in-python.htm Seite 172

Diese Angabe erfolgt über die Verknüpfung mit dem Punkt:

import fktsammlung
fktsammlung.hallomeister()

Die Verwendung von Übergabe- und Rückgabewerten erfolgt wie gewohnt. Nur der Verweis auf
das Modul mit der Punktverknüpfung bleibt. So ist auch immer klar, woher eine Funktion
stammt, falls man doch noch Änderungen oder Erweiterungen in seiner universellen
Funktionssammlung benötigt.

import fktsammlung
fktsammlung.hallomeister()
ergebnisausfunktion = fktsammlung.bspfunktionfuerrueckgabe(2)
print(ergebnisausfunktion)

Das war der Einsatz von Modulen bei Python.


© https://www.python-lernen.de/python-standardbibliothek.htm Seite 173

Standardbibliothek von Python / Module


Python verfügt über die Python Standardbibliothek, die eine umfangreiche Anzahl von Modulen
einer Standardinstallation von Python mit an Bord hat. Diese Module bieten viele Lösungen, die
man sich ansonsten mühsam durch eigene Programme erarbeiten müsste. Hier stecken
unzählige Stunden an gesparter Arbeit, wenn man einen Überblick über die verfügbaren Module
und deren Möglichkeiten hat.

Warum dieses Modulsystem?


Das modulare System ist aus Gründen der Performance in dieser Form integriert. Würde man
automatisch alle Möglichkeiten in der Grundinstallation von Python sofort verfügbar haben
(ohne den Import des entsprechenden Moduls) würde die Geschwindigkeit aller Python-
Programme darunter leiden. Daher muss man zum Nutzen eines Moduls dieses erst durch die
Anweisung import MODULNAME importieren.

Modul importieren
Hierbei kann man selbst „sparsam“ importieren, also wirklich nur die Teile eines Moduls, die
man auch für sein Programm benötigt oder alles.

import MODUL
# bei der Nutzung müssen die Namen des Moduls angegeben werden
# Beispiel MODUL.MODULNAME

from MODUL import *


# Alles wird importiert und es kann direkt angesprochen werden.
# das kann schnell unschön, da unübersichtlich, werden

from MODUL import NAME


# bestimmte Teile des Moduls werden importiert

Im Folgenden werden in diesem Tutorial genutzte Module beschrieben und sind hoffentlich
irgendwann hier komplett zum Nachlesen verfügbar. Ansonsten gibt es die englische
Nachschlageoption unter https://docs.python.org/3/library/

Verwendung von Modulen


Nach dem Importieren eines Moduls können die im Modul definierten Klassen, Funktionen und
Variablen mit folgender Syntax aufgerufen werden:

modulname.Klassenname
modulname.variablenname
modulname.funktionsname()

Als konkretes Beispiel: wir nutzen aus dem Modul datetime nur den Bereich date . Dieses
bietet uns eine Funktion für das aktuelle Datum. Wir lassen uns also das Tagesdatum
ausgeben.

from datetime import date


aktuellesDatum = date.today()
print(aktuellesDatum)

Hier sieht man nun schön den Aufruf: modulname.funktionsname()


© https://www.python-lernen.de/python-standardbibliothek.htm Seite 174

Im folgenden Kapitel mehr zum Modul datetime

Python Package Index: PyPi


Wenn die Standardbibliothek nicht ausreicht, gibt es unter https://pypi.org/ eine große
Sammlung (Repository) an Modulen zu allen erdenklichen Bereichen und Lösungen für
Probleme. Einfach einmal ansehen!
© https://www.python-lernen.de/python-modul-os.htm Seite 175

Python Modul os – arbeiten mit


Betriebssystemfunktionalität
In Python ist da Modul os bereits integriert. Dieses kann nach dem typischen Import einfach
genutzt werden. Es muss also nicht Installiert werden über PIP.

import os

Name des Betriebssystems über os.name


In der Variablen os.name kann abgerufen werden, ob es ein Windows-System oder ein Linus-
System ist. Was ist mich dem macOS? Der Mac basiert auf Unix, daher erhalten wir auch dort
dann als Rückmeldung „posix“.

import os
print(os.name)

Als Rückmeldung erhalten wir:


nt für Windows
posix für Linux/Unix und den Mac

Arbeitsverzeichnis auslesen getcwd()


Das aktuelle Arbeitsverzeichnis kann über getcwd() ermittelt werden. Die englische
Anweisung wird mit Übersetzung klar: getcwd -> get current working directory - > hole aktuelles
Arbeitsverzeichnis

import os
print(os.getcwd())

Unter einem Mac:


/Users/axelp/Documents/Projekte/Python-lernen.de/Skripte

Arbeitsverzeichnis ändern os.chdir(Pfad)


Die Funktion os.chdir(Pfad) kann das Arbeitsverzeichnis geändert werden. Die
Anweisung steht für das englische „change directory“.

Mögliche (vorhandene) Systemvariablen os.environ


Eine Abfrage für die im genutzten Betriebssystem vorhandenen Systemvariablen.

import os
print(os.environ)

Führt man das Python-Programm mit dem Mac aus, erhält man folgende Ausgabe:
© https://www.python-lernen.de/python-modul-os.htm Seite 176

environ({'USER': 'axelp', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'LOGNAME': 'axelp',


'SSH_AUTH_SOCK': '/private/tmp/com.apple.launchd.cXrqjKktJJ/Listeners', 'HOME':
'/Users/axelp', 'SHELL': '/bin/zsh', '__CF_USER_TEXT_ENCODING': '0x1F5:0x0:0x3', 'TMPDIR':
'/var/folders/7c/xrfbm9tx6nv5kwgw0mx0h4840000gn/T/', 'XPC_SERVICE_NAME': '0',
'XPC_FLAGS': '0x0', 'LC_CTYPE': 'UTF-8', 'PYTHONPATH': '/Applications/Python
3.9/IDLE.app/Contents/Resources', 'DYLD_LIBRARY_PATH': '/Applications/Python
3.9/IDLE.app/Contents/Frameworks', 'DYLD_FRAMEWORK_PATH': '/Applications/Python
3.9/IDLE.app/Contents/Frameworks'})

Wen jetzt die Frage plagt, was man mit den gesetzten Systemvariablen machen könnte, wird
sich den folgenden Befehl freuen:

Systemvariablen abfragen os.getenv(key)


Mit diesem Befehl erhält man Informationen über System-Variablen (ist abhängig zum
Betriebssystem. Unter MacOS bekommt man über folgende Abfrage das HOME-Verzeichnis:

import os
print(os.name)
print(os.getcwd())
print(os.getenv('HOME'))

Als Rückgabe erhalten wir:

posix

/Users/axelp/Documents/Projekte/Python-lernen.de/Skripte

/Users/axelp

Verzeichnisinhalt auflisten os.listdir(Pfad)


Um den Inhalt eines Verzeichnisses auszulesen, gibt es den Befehl os.listdir(Pfad) .
Hiermit erhalten wir eine Liste von den Dateien aus dem angegebenen Pfad. Wenn kein Pfad
angegeben wird, wird die Liste aus dem aktuellen Pfad erstellt:

import os
print(os.getcwd())
print(os.listdir())

Und als Ergebnis ein List-Objekt:

['datei1.pdf', 'datei2.txt', 'programm3.py']

Verzeichnis löschen über os.rmdir(Pfad)


Ein Verzeichnis wird über die Anweisung os.rmdir(Pfad) gelöscht

Datei löschen über os.remove(Pfad)


© https://www.python-lernen.de/python-modul-os.htm Seite 177

Eine Datei wird über die Anweisung os.remove(Pfad) gelöscht. Um Verzeichnisse zu


löschen wird die Anweisung os.rmdir(Pfad) benötigt. Über die Anweisung isfile()
und isdir() kann im Vorfeld überprüft werden, ob eine Datei oder ein Verzeichnis vorliegt.

Verzeichnis oder Datei? os.path.isfile('Pfad') und


os.path.isdir('Pfad')
Über die Abfrage können wir ermitteln, ob Verzeichnis oder Datei. Als Rückmeldung bekommen
wir „True“ bzw. „False“.

import os
print(os.path.isfile('datei.pdf'))
print(os.path.isdir('datei.pdf'))

Datei umbenennen über os.rename(Alter_Name, Neuer_Name)


Über die Anweisung os.rename() können sowohl Dateien wie auch Verzeichnisse
umbenannt werden.

Systembefehle ausführen über os.system(Systembefehl)


Mit dem Befehl os.system(Systembefehl) können Systembefehle ausgeführt werden.
Wenn man das System kennt, dann passt alles. Soll aber das Python Programm auf allen
Systemen laufen, sollte man das verwendete System abfragen und die entsprechenden
Systembefehle dann passen ausführen lassen.

Schauen wir uns die Anweisung für den Mac an und aktivieren die Sprachausgabe beim Mac
(die Standardmäßig installiert ist):

import os
os.system('say "Hallo Python"')

Lautsprecher aufdrehen und der Computer sollte nun laut und deutlich „Hallo Python“ von sich
geben.
© https://www.python-lernen.de/python-modul-datetime.htm Seite 178

Modul datetime – mit Datum und Zeit jonglieren


Im Folgenden nutzen wir das Modul datetime . Nach dem Import lassen wir uns die Klassen
etc. ausgeben über dir(datetime)

import datetime
print(dir(datetime))

Wir erhalten diese Ausgabe:

['MAXYEAR', 'MINYEAR', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__',


'__package__', '__spec__', 'date', 'datetime', 'datetime_CAPI', 'sys', 'time', 'timedelta', 'timezone',
'tzinfo']

Wir verfügen nach diesem kompletten Import über die Klassen:

date

datetime

time

timedelta

timezone

tzinfo

Hier eine kurze Beschreibung. Anhand der folgenden Beispiele werden die
Einsatzmöglichkeiten schnell klar.

Klasse Beschreibung

date Datumsklasse mit Jahr (year), Monat (month) und Tag (day). Voraussetzungen sind der gregorianische
Kalender (und dass dieser gilt)

time idealisierte Zeit mit den Attributen Stunde (hour), Minute (minute), Sekunde (second) und Mikrosekunde
(microsecond). Voraussetzung ist, dass jeder Tag aus exakt 24 * 60 * 60 Sekunden besteht. Idealisiert
deshalb, weil es keine Schaltsekunde gibt.

datetime Kombination aus date und time. Attribute und Voraussetzung entsprechenden den einzelnen Klassen.

timedelta Zum Berechnen der Zeitdauer zwischen 2 Zeitpunkten. Rückgabe in Mikrosekunden.

timezone Zeitzonen und UTC. Die abstrakte Basisklasse tzinfo wird von timezone genutzt

Importieren wir datetime über from datetime import * erhalten wir alle verfügbaren
Klassennamen:

from datetime import *


print(dir(datetime))
© https://www.python-lernen.de/python-modul-datetime.htm Seite 179

kompletter Import von datetime über *

['__add__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__',


'__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__',
'__new__', '__radd__', '__reduce__', '__reduce_ex__', '__repr__', '__rsub__', '__setattr__', '__sizeof__',
'__str__', '__sub__', '__subclasshook__', 'astimezone', 'combine', 'ctime', 'date', 'day', 'dst', 'fold',
'fromordinal', 'fromtimestamp', 'hour', 'isocalendar', 'isoformat', 'isoweekday', 'max',
'microsecond', 'min', 'minute', 'month', 'now', 'replace', 'resolution', 'second', 'strftime', 'strptime',
'time', 'timestamp', 'timetuple', 'timetz', 'today', 'toordinal', 'tzinfo', 'tzname', 'utcfromtimestamp',
'utcnow', 'utcoffset', 'utctimetuple', 'weekday', 'year']

Man sieht auch sehr schön, wenn wir nur einen Teil (vorzugsweise diesen Teil, den wir auch
benötigen) importieren. Somit spart man Speicherplatz und bekommt ein schnelleres
Pythonprogramm. Der Import nur von date .

from datetime import date


print(dir(date))

date vom Modul datetime importiert

['__add__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__',


'__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__',
'__new__', '__radd__', '__reduce__', '__reduce_ex__', '__repr__', '__rsub__', '__setattr__', '__sizeof__',
'__str__', '__sub__', '__subclasshook__', 'ctime', 'day', 'fromordinal', 'fromtimestamp', 'isocalendar',
'isoformat', 'isoweekday', 'max', 'min', 'month', 'replace', 'resolution', 'strftime', 'timetuple', 'today',
'toordinal', 'weekday', 'year']

Beispiele für unsere Objekt datetime


Ausgabe des aktuellen Datums:
© https://www.python-lernen.de/python-modul-datetime.htm Seite 180

from datetime import date


aktuellesDatum = date.today()
print(aktuellesDatum)

Als Ergebnis erhält man das aktuelle Datum – als Beispiel erhält die Variable „2020-01-14“

aktuelles Datum als Datumsinstanz des Objekts date

Über date kann auch ein Datum „zugewiesen“ werden:

from datetime import date


weihnachten2020 = date(2020, 12, 24)
print(weihnachten2020)

Als Ausgabe erhalten wir dann:

2020-12-24

Soll es anders ausgegeben werden, können wir dies nach Belieben einstellen:

Formatierte Ausgabe eines Datums


Soll das Datum entsprechend ausgegeben werden, kann über strftime() die gewünschten
Einstellungen vorgenommen werden. Die Anweisung strftime steht für die Abkürzung
„STRingFromTIME“ – wir konvertieren damit das datetime-Objekt als String für die Ausgabe.
Dabei können wir noch angeben, welche Daten vom Datum (sprich Tag, Jahreszahl etc.) wir
ausgeben lassen wollen. Im folgenden Beispiel wollen wir uns das Datum in typisch deutscher
Schreibweise mit 4-stelliger Jahreszahl ausgeben lassen:

from datetime import date


weihnachten2020 = date(2020, 12, 24)
print(weihnachten2020.strftime("%d.%m.%Y"))

Dies ergibt als Ausgabe dann

24.12.2020

Um neben Datum auch die Uhrzeit nutzen zu können, importieren wir alles:
© https://www.python-lernen.de/python-modul-datetime.htm Seite 181

import datetime
weihnachten2020 = datetime.datetime(2020, 12, 4, 15, 30)
print(weihnachten2020.strftime("%H:%M:%S %d.%m.%Y"))

Hier stehen folgende Kürzel zur Verfügung:

Anweisung Bedeutung Beispiel

%a Wochentag in Kurzschreibweise Sun, Mon, …, Sat (en_US); So, Mo, …, Sa (de_DE)

%A Wochentag ausgeschrieben Sunday, Monday, …, Saturday (en_US); Sonntag,


Montag, …, Samstag (de_DE)

%w Wochentag als Nummer: dabei steht 0 für den 0, 1, …, 6


Sonntag und 6 für Samstag

%d Tag des Monates mit führender Null 01, 02, …, 31

%b Monatsname abgekürzt. Jan, Feb, …, Dec (en_US); Jan, Feb, …, Dez


(de_DE)

%B Monatsname ausgeschrieben January, February, …, December (en_US); Januar,


Februar, …, Dezember (de_DE)

%m Monat als Zahl mit führender Null. 01, 02, …, 12

%y Jahreszahl zweistellig 00, 01, …, 99

%Y Jahreszahl vierstellig 0001, 0002, …, 2013, 2014, …, 9998, 9999

%H Stunde als 24 Stunden mit führender Null 00, 01, …, 23

%I Stunde mit 12 Stunden mit führender Null 01, 02, …, 12

%p Anzeige ob AM oder PM (at morning/past morning) AM, PM (en_US); am, pm (de_DE)

%M Minuten mit führender Null 00, 01, …, 59

%S Sekunden mit führender Null 00, 01, …, 59

%f Mikrosekunden mit führenden Nullen 000000, 000001, …, 999999

%z UTC Offset (empty), 0000, -0400, 1030, 063415, -


030712.345216

%Z Name der Zeitzone (empty), UTC, EST, CST

%j Tag des Jahres 001, 002, …, 366

%U Wochennummer (wenn Sonntag der erste Tag in der 00, 01, …, 53


Woche ist)

%W Wochennummer (wenn Montag der erste Tag in der 00, 01, …, 53


Woche ist)

%c Komplette Ausgabe von Datum und Uhrzeit Tue Aug 16 21:30:00 1988 (en_US); Di 16 Aug
21:30:00 1988 (de_DE)

%x Komplettes Datum 08/16/88 (None); 08/16/1988 (en_US);


16.08.1988 (de_DE)

%X Komplette Uhrzeit 21:30:00 (en_US); 21:30:00 (de_DE)


© https://www.python-lernen.de/python-modul-datetime.htm Seite 182

Anweisung Bedeutung Beispiel

%% Falls man doch mal das Prozentzeichen ausgeben %


möchte, einfach doppelt schreiben

Wochentag als Nummer


Die Nummer des Wochentags von einem gegebenen Datum wird ausgegeben über .
weekday() . Wobei für Montag die 0 steht, Dienstag die 1 usw.

from datetime import date


aktuellesDatum = date.today()
print(aktuellesDatum.weekday())

möchte man lieber, dass der Wochentag mit 1 für Montag startet, hilft .timetuple()

from datetime import date


aktuellesDatum = date.today()
print(aktuellesDatum.isoweekday())

Und nun den Wochentag anhand einer Liste als Text ausgeben:

from datetime import date


aktuellesDatum = date.today()
wochentag_nr = aktuellesDatum.isoweekday()
print(wochentag_nr)

wochentage_kuerzel = ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"]


print("aktueller Wochentag: ", wochentage_kuerzel[wochentag_nr])

Kalenderwoche, Jahr und Wochentag als Nummer


Benötigt man die Kalenderwoche, erhält man über .isocalendar() ein Tupel mit dem
Inhalt in der Reihenfolge (Jahr, Kalenderwoche, Wochentag im ISO-Format):

from datetime import date


aktuellesDatum = date.today()
print(aktuellesDatum.isocalendar())
kalenderwoche = aktuellesDatum.isocalendar()

Als Rückgabe erhalten wir:

(2020, 1, 22)
© https://www.python-lernen.de/python-modul-datetime.htm Seite 183

Informationen zum Wochentag: Jahr, Kalenderwoche, Wochentag

deutsche Schreibweise für Monatsname und Wochentag


Erhalten wir als Python-Ausgabe die Monatsnamen bzw. Wochentage nur in englischer
Schreibweise als Rückgabe, gibt es dafür eine einfache Möglichkeit für die Ausgabe in
Deutsch.

Unser Beispiel von oben würde für den Weihnachtstag 2021 folgende Information (in
englischer Schreibweise) ausspucken:

Python-Code:

weihnachten2021 = datetime.datetime(2021, 12, 24, 15, 30)


print(weihnachten2021.strftime("%A %B %d.%m.%Y"))

Ergebnis:

Friday December 24.12.2021

Wir wollen aber die deutsche Schreibweise für Wochentage und Monatsnamen. Dazu
importieren wir am Anfang import locale und nutzen über die Anweisung
locale.setlocale() das Länderkürzel de:

import locale, datetime


locale.setlocale(locale.LC_TIME, locale.normalize("de"))

weihnachten2021 = datetime.datetime(2021, 12, 24, 15, 30)


print(weihnachten2021.strftime("%A %B %d.%m.%Y"))

Und nun haben wie überall bei jeder Datumsausgabe die korrekte deutsche Schreibweise:

Freitag Dezember 24.12.2021

Im Datum etwas austauschen: replace


© https://www.python-lernen.de/python-modul-datetime.htm Seite 184

Möchte man etwas in einem bestehenden Datum austauschen, kann das sehr einfach über
replace() geschehen. Dabei ist der Aufbau:

replace (year=self.year, month=self.month, day=self.day)¶

Nehmen wir an, wir möchten von Weihnachten (wahlweise geht auch der eigene Geburtstag)
dieses und nächsten Jahres den Wochentag und die Kalenderwoche erfahren. Also setzen wir
das Datum von diesem Jahr und tauschen für die zweite Ausgabe das Jahr aus.

from datetime import date


weihnachten2020 = date(2020, 12, 24)
print(weihnachten2020.isocalendar())
weihnachten2021 = weihnachten2020.replace(year=2021)
print(weihnachten2021.isocalendar())

Wir erhalten als Ergebnis:

(2020, 52, 4)

(2021, 51, 5)

2020 ist Weihnachten in der Kalenderwoche 52 an einem Donnerstag (4) und 2021 an einem
Freitag (5).

mit Tagen rechnen


Wir können sehr einfach über das Datum rechnen. Wir errechnen im folgenden Beispiel die
vergangenen Tage seit der Geburt:

from datetime import date


heute = date.today()
print(heute)

heute_umf = heute.strftime("%m-%d-%Y. %d.%b.%Y ist ein %A am %d. Tag des %B.")


print(heute_umf)

# mit dem Datum lässt sich rechnen


geburtstag = date(1969,10,5)
heute = date.today()
alter = heute - geburtstag
print(alter.days, "Tage seit Geburt vergangen")
© https://www.python-lernen.de/python-modul-time.htm Seite 185

Modul time in Python nutzen


Über das „Zeit“-Modul können wir Berechnungen mit der Zeit anstellen, aber auch unser
Programm für eine definierte Zeit schlafen schicken.

Wie gehabt, muss man bei gewünschter Verwendung das Modul importieren und über dir
erhalten wir einen Überblick über die Möglichkeiten:

import time
print(dir(time))

Und die Ausgabe:

['_STRUCT_TM_ITEMS', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'altzone',


'asctime', 'clock', 'ctime', 'daylight', 'get_clock_info', 'gmtime', 'localtime', 'mktime', 'monotonic',
'monotonic_ns', 'perf_counter', 'perf_counter_ns', 'process_time', 'process_time_ns', 'sleep',
'strftime', 'strptime', 'struct_time', 'time', 'time_ns', 'timezone', 'tzname', 'tzset']

Lassen wir unser Programm für n-Sekunden schlafen gehen. Dann ausgeschlafen erfolgt die
zweite Rückmeldung:

import time
print("Ich bin müde und gehe schlafen")
time.sleep(5)
print("habe geschlafen")

Die Angabe bei time.sleep(n) sind Sekunden. Sollen Millisekunden mitgegeben werden,
dann einfach über die Nachkommastelle!

Wir können auch eine Auswertung der Dauer der Programmausführung machen:

import time
print(time.time())
zeitanfang = time.time()
print("Ich bin müde und gehe schlafen")
time.sleep(5)
print("habe geschlafen")
zeitende = time.time()
print("Dauer Programmausführung:",)
print(zeitende-zeitanfang)

Bei der ersten Ausgabe der Zeit über time.time() erhalten wir eine große Zahl wie z.B.
„1579782074.592673“. Diese Zahl stellt die vergangenen Sekunden seit dem 1.1.1970 dar.
Damit kann man gut rechnen, wenn man eine Anfangszeit von der Endzeit abzieht, wir im
Programm geschehen.

Die Ausgabe:
© https://www.python-lernen.de/python-modul-time.htm Seite 186

1579782074.592673

Ich bin müde und gehe schlafen

habe geschlafen

Dauer Programmausführung:

5.000827789306641

Wir sehen, dass unser Programm länger als die 5 Sekunden Schlafenszeit benötigt. Jeder
Befehl und jede Ausgabe frisst Zeit, auch wenn es nur Millisekunden sind. Daher die
„Nachkommazeit“ im Beispiel von ".000827789306641".

time.time() lesbar über time.asctime()


Zurück zu der großen Zahl, die uns time.time() auswirft. In unserem letzten Beispiel war
das „1579782074.592673“. Nichts, womit ein normaler Mensch etwas anfangen kann (vermute
ich mal). Daher gibt es die Methode asctime() . Wir fragen (kann man sich über das falsch
geschriebene „ask“ merken) nach der Zeit und bekommen diese auch für einen Menschen
verständlich als Rückmeldung:

import time
print(time.time())
print(time.localasctime())

Und darauf kommt als Rückmeldung:

1579790660.517235

Thu Jan 23 15:44:20 2020

In die gleiche Richtung geht gmtime() - „gm“ steht für „greenwich meantime“, also die
mittlere Sonnenzeit in Greenwich. Und wer sich schon immer mal gefragt hat, warum zur Hölle
Greenwich? Greenwich liegt im Südosten von London und dort war früher das Zentrum der
britischen Marine und es gibt dort eine Sternwarte.

import time
print(time.gmtime())

Als Rückmeldung bekommen wir:

time.struct_time(tm_year=2020, tm_mon=1, tm_mday=23, tm_hour=14, tm_min=44,


tm_sec=22, tm_wday=3, tm_yday=23, tm_isdst=0)

Und von dieser Zeit-Instanz (mal wieder ein Objekt ;)) können wir nun die Einzelteile verwenden.
Im Index 0 steckt das Jahr – im Index 6 der Wochentag (gezählt wird ab Montag mit 0 – also
bedeutet der Rückgabewert 3, dass es Donnerstag ist)
© https://www.python-lernen.de/python-modul-time.htm Seite 187

import time
jetzt = time.gmtime()
print (jetzt[0]). # ergibt das Jahr
print (jetzt[6]) # Wochentag, Montag ist 0, Di = 1 usw.

Und die Rückgabewerte:

2020

localtime() – Zeit von eigener Zeitzone nutzen


Anstelle der englischen Zeit ist die eigene Zeitzone meistens nützlicher. Dafür gibt es die
Methode localtime() . Die Rückgabeform ist exakt gleich wie bei gmtime() .

import time
jetzt = time.localtime()
print(jetzt)
© https://www.python-lernen.de/python-modul-calendar.htm Seite 188

Modul calendar: Kalender ausgeben über Python


Python bietet ein Modul um ein Kalenderblatt bzw. mehrere auszugeben.

Januar 2020
Mo Di Mi Do Fr Sa So
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31

Dabei kann gewählt werden zwischen den 4 Formen:

TextCalendar

LocaleTextCalendar

HTMLCalendar

LocaleHTMLCalendar

TextCalendar gibt das gewählte Kalenderblatt als reinen Text aus, dagegen werden beim
HTMLCalendar auch entsprechende HTML-Tags um die verschiedenen Daten ausgeben.
Sobald der Kalender mit "Locale…" startet, erhält man als Beschriftung die lokale Sprache (in
unserem Fall dann deutsche Monatsbezeichnungen und die abgekürzten Wochentage in
Deutsch).

Über die Anweisung formatmonth wird das gewünschte Jahr und der gewünschte Monat
angegeben.

import calendar
kalenderblatt = calendar.TextCalendar(calendar.MONDAY)
ausgabe = kalenderblatt.formatmonth(2020,1)
print(ausgabe)

Modul calendar als Textkalender

oder in Deutsch

import calendar
kalenderblatt = calendar.LocaleTextCalendar(calendar.MONDAY)
ausgabe = kalenderblatt.formatmonth(2020,1)
print(ausgabe)

Januar 2020
Mo Di Mi Do Fr Sa So
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31

ein HTML-Kalender:
Möchte man direkt HTML-Code mit Klassen (für das Design später über CSS) erhalten, kann
man die HTML-Variante über LocaleHTMLCalendar auswählen.

import calendar
kalenderblatt = calendar.HTMLCalendar(calendar.MONDAY)
ausgabe = kalenderblatt.formatmonth(2020,1)
print(ausgabe)

<table border="0" cellpadding="0" cellspacing="0" class="month">


<tr><th colspan="7" class="month">Januar 2020</th></tr>
<tr><th class="mon">Mo</th><th class="tue">Di</th><th class="wed">Mi</th><th class="thu">Do</th><th class="fri">Fr</th><th class="sat">Sa</th><th class="sun">So</th></tr>
<tr><td class="noday"> </td><td class="noday"> </td><td class="wed">1</td><td class="thu">2</td><td class="fri">3</td><td class="sat">4</td><td class="sun">5</td></tr>
<tr><td class="mon">6</td><td class="tue">7</td><td class="wed">8</td><td class="thu">9</td><td class="fri">10</td><td class="sat">11</td><td class="sun">12</td></tr>
<tr><td class="mon">13</td><td class="tue">14</td><td class="wed">15</td><td class="thu">16</td><td class="fri">17</td><td class="sat">18</td><td class="sun">19</td></tr>
<tr><td class="mon">20</td><td class="tue">21</td><td class="wed">22</td><td class="thu">23</td><td class="fri">24</td><td class="sat">25</td><td class="sun">26</td></tr>
<tr><td class="mon">27</td><td class="tue">28</td><td class="wed">29</td><td class="thu">30</td><td class="fri">31</td><td class="noday"> </td><td class="noday"> </td></tr>
</table>

Kompletter Jahreskalender
© https://www.python-lernen.de/python-modul-calendar.htm Seite 189

import calendar
kalenderblatt = calendar.LocaleTextCalendar(calendar.MONDAY)
ausgabe = kalenderblatt.formatyear(2020, 2, 1, 1, 3)
print(ausgabe)

2020

Januar Februar März


Mo Di Mi Do Fr Sa So Mo Di Mi Do Fr Sa So Mo Di Mi Do Fr Sa So
1 2 3 4 5 1 2 1
6 7 8 9 10 11 12 3 4 5 6 7 8 9 2 3 4 5 6 7 8
13 14 15 16 17 18 19 10 11 12 13 14 15 16 9 10 11 12 13 14 15
20 21 22 23 24 25 26 17 18 19 20 21 22 23 16 17 18 19 20 21 22
27 28 29 30 31 24 25 26 27 28 29 23 24 25 26 27 28 29
30 31

April Mai Juni


Mo Di Mi Do Fr Sa So Mo Di Mi Do Fr Sa So Mo Di Mi Do Fr Sa So
1 2 3 4 5 1 2 3 1 2 3 4 5 6 7
6 7 8 9 10 11 12 4 5 6 7 8 9 10 8 9 10 11 12 13 14
13 14 15 16 17 18 19 11 12 13 14 15 16 17 15 16 17 18 19 20 21
20 21 22 23 24 25 26 18 19 20 21 22 23 24 22 23 24 25 26 27 28
27 28 29 30 25 26 27 28 29 30 31 29 30

Juli August September


Mo Di Mi Do Fr Sa So Mo Di Mi Do Fr Sa So Mo Di Mi Do Fr Sa So
1 2 3 4 5 1 2 1 2 3 4 5 6
6 7 8 9 10 11 12 3 4 5 6 7 8 9 7 8 9 10 11 12 13
13 14 15 16 17 18 19 10 11 12 13 14 15 16 14 15 16 17 18 19 20
20 21 22 23 24 25 26 17 18 19 20 21 22 23 21 22 23 24 25 26 27
27 28 29 30 31 24 25 26 27 28 29 30 28 29 30
31
Oktober November Dezember
Mo Di Mi Do Fr Sa So Mo Di Mi Do Fr Sa So Mo Di Mi Do Fr Sa So
1 2 3 4 1 1 2 3 4 5 6
5 6 7 8 9 10 11 2 3 4 5 6 7 8 7 8 9 10 11 12 13
12 13 14 15 16 17 18 9 10 11 12 13 14 15 14 15 16 17 18 19 20
19 20 21 22 23 24 25 16 17 18 19 20 21 22 21 22 23 24 25 26 27
26 27 28 29 30 31 23 24 25 26 27 28 29 28 29 30 31
30
© https://www.python-lernen.de/tkinter-gui.htm Seite 190

GUI Programmierung über tkinter in Python


Mit dem Modul tkinter kann sehr einfach eine grafischen Benutzeroberfläche (GUI von englisch
„graphical user interface“) erstellt werden.

Da es sich bei Tkinter um das erste in Python integrierte GUI-Toolkit handelte, ist es in der
Standardinstallation (bei Windows und Mac Os) bereits verfügbar. Die Benennung des Moduls
kommt aus einer Geschichte. „Tk“ steht für „Toolkit“ und „inter“ für Interface und wurde als
erstes für die Sprache „Tcl“ entwickelt.

Tkinter zeichnet sich dadurch aus, dass man nun sehr einfach eine Grafische
Benutzeroberfläche umsetzen kann mit allen üblichen Steuerelementen:

Textlabels

Textboxen

Inputboxen

Schaltflächen (Buttons)

Radiobuttons

Checkbottons

Menüs

und alles was man so für die GUI-Erstellung benötigt.

Die verwendeten Anzeigeelemente werden entsprechend dem verwendeten Betriebssystem


dargestellt. Unser Python Programm wird also unter Windows in der typischen
Windowsanzeigeart erscheinen. Beim Mac OS wird dessen typisches Erscheinungsbild für
Fenster automatisch genutzt. Beim Programmieren muss man sich also nicht um das
betriebssystemspezifische Aussehen kümmern, sondern nur um die Anordnung der
gewünschten Elemente. Und für die Anordnung der Elemente unterstützt einen Tkinter über
Layout-Manager.

Tkinter verfügt über verschiedene Layout-Manager um das Platzieren der einzelnen Elemente
schnell erledigen zu können.

Schauen wir uns im Folgenden an, wie wir Tkinter integrieren, Elemente erstellen, die Platzieren
und die Interaktion zwischen User und Python-Programm ermöglichen.
© https://www.python-lernen.de/tkinter-import.htm Seite 191

Tkinter in Python importieren


Im ersten Schritt muss das Modul tkinter importiert werden.

import tkinter as tk

Teilweise sieht man auch den Import über from tkinter import * . Das spart zwar im
folgenden Code Tipparbeit, birgt aber die Gefahr von Namenskonflikten, wenn man weitere
Module importiert, die gleiche Namen nutzen. Daher lieber Sicherheit und Stressfrei als ein
bisschen Tipparbeit zu sparen. Zusätzlich sieht man im Tutorial so sehr schnell, dass es sich
um ein Element der Bibliothek tkinter handelt. Wir werden die Elemente dann immer über
tk.__ ansprechen.

import tkinter as tk

Nach dem Import müssen wir unser Fenster initialisieren. Dazu wird ein Konstruktor
aufgerufen, der in die Variable root den Bildschirm setzt:

import tkinter as tk
root = tk.Tk()

Jetzt benötigen wir noch unsere Hauptschleife, damit unsere GUI nicht gleich wieder
verschwindet.

import tkinter as tk
root = tk.Tk()
root.mainloop()

Als Ergebnis erhalten wir mit dem Aufruf des Programms ein neues Fenster –
Betriebssystemtypisch mit den entsprechenden Schließen- und Maximieren-Buttons im
Fensterkopf.

[bild[erstes GUI über tkinter]]

Ein leeres Fenster ist natürlich mäßig spannend. Dieses können wir nun mit den gewünschten
Steuerelementen füllen. Im folgenden Kapitel ein Überblick über die verfügbaren
Steuerelemente (auch Widgets) genannt und dann Schritt für Schritt die Verwendung aller
einzelnen Elemente mit Beispielen und im Einsatz.
© https://www.python-lernen.de/tkinter-steuerelemente.htm Seite 192

Überblick über alle Steuerelemente für die GUI und tkinter


In unser Fenster wollen wir nun verschiedene Steuerelemente einsetzen. Im ersten Schritt eine
Übersicht der verfügbaren Steuerelemente in alphabetischer Reihenfolge, die wir in den
folgenden Kapiteln Schritt für Schritt kennen lernen.

Widget Funktion

Button Schaltfläche, Button – anklicken und es passiert was

Canvas kann Grafiken und Zeichnungen aufnehmen

Checkbutton anklickbare Auswahl

Entry einzeiliges Eingabefeld

Label Textlabel für Beschriftungen

LabelFrame beschrifteter Rahmen

Listbox Liste mit Auswahl

Menu Kontextmenü

Menubutton Schaltfläche für Kontextmenü

OptionMenu Schaltfläche, die bei Bestätigung eine Auswahlliste anzeigt

Radiobutton Auswahlfeld, im Gegensatz zu Checkbutton kann nur eine innerhalb einer Gruppe gewählt sein

Scrollbar Scrollleiste

Spinbox Zahlenwertauswahlfeld

Text mehrzeiliges Texteingabefeld

Widget-Basisklasse Basisklasse eines Steuerelements (alle Grundfunktionen, die für alle Widgets verfügbar ist)
© https://www.python-lernen.de/tkinter-label-widget.htm Seite 193

Label-Widget (Text) in unsere Fenster ausgeben


Das Label-Widget ist in Tkinter das einfachste Widget und stellt als Klasse Text und Bilder im
Fenster dar. Der Nutzer sieht nur den Text bzw. Bild, kann aber nicht damit interagieren.

Unser bisheriges Programm ergänzen wir vor der Hauptschleife mit dem Label (auch Label-
Widget genannt) mit dem Namen „label1“. Und aus Tradition lassen wir „Hallo Welt“ ausgeben.

Das Label-Widget wird vor dem mainloop() -Befehl gepackt.

import tkinter as tk
root = tk.Tk()

# Textausgabe erzeugen
label1 = tk.Label(root, text="Hallo Welt")

root.mainloop()

Noch passiert gar nichts! Es erfolgt keine Ausgabe. Die Ausgabe müssen wir über die
Anweisung .pack() anstoßen.

import tkinter as tk
root = tk.Tk()

# Textausgabe erzeugen
label1 = tk.Label(root, text="Hallo Welt")

# in GUI Elemente einbetten


label1.pack()

root.mainloop()

Als Ausgabe erfolgt:

[bild[Label-Widget zur Textausgabe]]

Später lernen wir eine weitere Form der Ausgabe anstelle von .pack() kennen. Dadurch wird
Design von der GUI deutlich einfacher.

Ausgabe eines Bildes über das Label-Widget


Jetzt wollen wir ein Bild in unsere GUI integrieren. Die hier verwendete Grafik der Biene kann
über die URL https://www.python-lernen.de/bilder/biene.png zum Testen heruntergeladen
werden. Der Einfachheit halber sollte die Grafik sich im selben Verzeichnis befinden wir unser
Python-Programm.

Den Pfad des Bildes speichern wir unter bild1 , welches über das label2 integriert wird.
Dabei wird das Label ergänzt mit der pack() -Methode, der die Ausrichtung rechts bzw. links
mitgegeben werden kann:
© https://www.python-lernen.de/tkinter-label-widget.htm Seite 194

import tkinter as tk

root = tk.Tk()

# Textausgabe erzeugen
label1 = tk.Label(root, text="Hallo Welt")

# in GUI Elemente einbetten


label1.pack(side="left")

# Grafik einbetten
bild1 = tk.PhotoImage(file="biene.png")
label2 = tk.Label(root, image=bild1).pack(side="right")

root.mainloop()

[bild[GUI mit Text und Bildausgabe]]

Bitte einmal probieren, erst das Bild auszugeben und dann den Text (der dann ohne die
Ausrichtung links angegeben wird). Als Ergebnis erhalten wir:

[bild[Ausgabe erst von rechtsbündigen Bild und dann des Textes]]

Für die Ausrichtung über das Attribut side= stehen uns 3 Werte zur Verfügung:

LEFT für links

CENTER für mittig

RIGHT für rechts


© https://www.python-lernen.de/tkinter-farben-fg-bg.htm Seite 195

Text mit Farbe ausgeben – Hintergrundfarbe und


Textfarbe
Dem Text selber kann natürlich auch Farbe mitgeben werden. Nehmen wir unser einfaches
Beispiel mit Text aus dem letzten Kapitel:

import tkinter as tk
root = tk.Tk()

# Textausgabe erzeugen
label1 = tk.Label(root, text="Hallo Welt")

# in GUI Elemente einbetten


label1.pack()

root.mainloop()

Vordergrundfarbe fg
Jetzt kommt das Attribut fg= für die Vordergrundfarbe hinzu. Die Farbangabe geschieht über
die englischen Farbnamen bzw. über die Hexadezimalangaben für Farben (wie man es von
HTML kennt über #ff00ff ).

# Textausgabe erzeugen
label1 = tk.Label(root, text="Hallo Welt", fg="red")

Zur besseren Lesbarkeit wird folgenden die Attribute auf mehrere Zeilen verteilt.

Hintergrundfarbe bg
Dasselbe wie bei der Vordergrundfarbe können wir über das Attribut bg= für eine
Hintergrundfarbe (backgroundcolor) umsetzen. Die Trennung zwischen den einzelnen
Attributen erfolgt über jeweils ein Komma:

# Textausgabe erzeugen
label1 = tk.Label(root, text='Hallo Welt',
fg='#00ff00',
bg='orange')
© https://www.python-lernen.de/tkinter-schriftart-schriftgroesse.htm Seite 196

Schriftart und Schrfitgröße setzen über font


Zusätzlich können Schriftart und Größe usw. angegeben werden:

# Textausgabe erzeugen
label1 = tk.Label(root, text='Hallo Welt',
fg='#00ff00',
bg='orange',
font=('times', 25, 'bold', 'italic'))
© https://www.python-lernen.de/tkinter-gui-platzierung-grid.htm Seite 197

Platzieren der Elemente in der GUI über pack() versus


grid()
Bisher haben wir unsere Elemente einfach über die Methode .pack() ausgegeben. Dies ist je
nach Anwendungsfall sehr aufwendig. Schauen wir uns die Möglichkeiten über .grid() an.
Das englische Wort „grid“ bedeutet nichts anderes wie Gitter. Die zwischenräume des Gitters
können sehr einfach angegeben werden über die Reihe („row“) und Spalte („colum“).

Im folgenden Beispiel erzeugen wir 3 Textausgaben mit unterschiedlichen Hintergrundfarben,


die wir dann durch das Gitter sehr einfach platzieren können.

import tkinter as tk

root = tk.Tk()

label1 = tk.Label(root, text="Hallo Welt", bg="orange")


label1.grid(row=0, column=0)

label2 = tk.Label(root, text="R1 / C1", bg="lightgreen")


label2.grid(row=1, column=1)

label3 = tk.Label(root, text="R2 / C2", bg="lightblue")


label3.grid(row=2, column=2)

root.mainloop()

Wir sehen hier sehr schön, wie die einzelnen Texte in die entsprechenden Reihen und Spalten
platziert werden. Dabei bestimmt der benötigte Platz des Textes die Spaltenbreite.

[bild[Ausgabe von TKinter über grid()]]

Haben wir eine weitere Ausgabe in Spalte 0 und Zeile 3, die weniger Platz benötigt, wird diese
standardmäßig mittig ausgerichtet:

[bild[Ausgabe in GUI standardmäßig mittig]]

Über die Anweisung print(dir(tk.Grid)) erhalten wir alle Informationen über die
Möglichkeiten von Grid .

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__',


'__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__',
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__',
'__subclasshook__', '__weakref__', 'bbox', 'columnconfigure', 'config', 'configure', 'forget', 'grid',
'grid_bbox', 'grid_columnconfigure', 'grid_configure', 'grid_forget', 'grid_info', 'grid_location',
'grid_propagate', 'grid_remove', 'grid_rowconfigure', 'grid_size', 'grid_slaves', 'info', 'location',
'propagate', 'rowconfigure', 'size', 'slaves']

Und die Attribute für unser grid(…) über print(help(tk.Grid.grid)) :

Wir können also folgende Attribute mitgeben:


© https://www.python-lernen.de/tkinter-gui-platzierung-grid.htm Seite 198

grid_configure(self, cnf={}, **kw)

Position a widget in the parent widget in a grid. Use as options:

column=number - use cell identified with given column (starting with 0)

columnspan=number - this widget will span several columns

in=master - use master to contain this widget

in_=master - see 'in' option description

ipadx=amount - add internal padding in x direction

ipady=amount - add internal padding in y direction

padx=amount - add padding in x direction

pady=amount - add padding in y direction

row=number - use cell identified with given row (starting with 0)

rowspan=number - this widget will span several rows

sticky=NSEW - if cell is larger on which sides will this

widget stick to the cell boundary

Über das Attribut sticky= können wir unseren Inhalt an einer Seite ausrichten und sind nicht
auf die zentrierte Ausgabe festgelegt. Als Attributwert diesen die Himmelsrichtungen wir „n, s,
w, e, sw, se, ..“

import tkinter as tk

root = tk.Tk()

label1 = tk.Label(root, text="Hallo Welt", bg="orange")


label1.grid(row=0, column=0)

label2 = tk.Label(root, text="R1 / C1", bg="lightgreen")


label2.grid(row=1, column=1)

label3 = tk.Label(root, text="R2 / C2", bg="lightblue")


label3.grid(row=2, column=2)

label4 = tk.Label(root, text="R2/C0", bg="yellow")


label4.grid(row=2, column=0, sticky='e')

root.mainloop()

Unser gelber Inhalt (R2/C0) ist jetzt rechts ausgerichtet – sprich im Osten (englisch east = „e“)

[bild[Inhalt in den Zellen ausrichten, z.B. rechtsbündig]]


© https://www.python-lernen.de/tkinter-entry-eingabefeld-einzeilig.htm Seite 199

Entry : Einzeiliges Eingabefeld erstellen in tkinter


Sehr oft benötigen wir einen kurzen Text oder Zahleneingabe von unserem Nutzer. Dazu eignet
sich oft das einzeilige Eingabefeld am besten.

eingabefeld_wert=tk.StringVar()
eingabefeld=tk.Entry(root, textvariable=eingabefeld_wert)
eingabefeld.pack()

Über das Attribut textvariable= wird eine Steuerelementvariable gesetzt, über die wir auf
den Inhalt (sprich die Nutzereingabe) lesend zugreifen können über variablenname.get() .
Genauso können wir auch selber Inhalt aus dem Programm in diesen Bereich schreiben über
variablenname.set() .

eingabefeld_wert=tk.StringVar()
eingabefeld=tk.Entry(root, textvariable=eingabefeld_wert)
eingabefeld.pack()
eingabefeld_wert.set('12345')

Entry-Eingabefeld als Passwort-Feld


Wenn wir ein Passwort abfragen möchten, bietet sich das einzeilige Eingabefeld an. Allerdings
möchten wir nicht, dass jemand das Passwort mitlesen kann, wenn er über die Schulter auf
den Bildschirm eines „Geheimnisträgers“ schaut.

Daher soll doch bitte anstelle von der eigentlichen Eingabe dann die typischen Sterne kommen.
Kein Problem bei Tkinter: wir haben einen weiteren Parameter, der die Zeichen festlegt, die
anstelle einer Eingabe angezeigt werden. Dieser Paramater ist show="*" und sollte mehr als
ein Zeichen im Parameter eingetragen werden, wird nur das erste Zeichen verwendet. Einfach
einmal testen über show=":)"

Und hier als Beispielcode:

eingabefeld_wert=tk.StringVar()
eingabefeld=tk.Entry(root, textvariable=eingabefeld_wert, show="*")
eingabefeld.pack() 

Der Parameter kann auch in anderer Form übergeben werden. Dadurch wird der Code
übersichtlicher:

eingabefeld=tk.Entry(root)
eingabefeld_wert=tk.StringVar()
eingabefeld["textvariable"] = eingabefeld_wert
eingabefeld["show"] = "*"
eingabefeld.pack()

Weitere Parameter bei entry


background, bd, bg, borderwidth, fg, foreground, justify, relief, takefocus, width
© https://www.python-lernen.de/tkinter-button.htm Seite 200

Button/Schaltfläche erstellen auf GUI mit Tkinter


Für eine Benutzeraktion bieten sich Buttons an, die wir in unserem Fenster platzieren können
und die wir mit Aktionen hinterlegen können.

import tkinter as tk

root = tk.Tk()

# Textausgabe erzeugen
label1 = tk.Label(root, text="Hallo Welt")
label1.pack()

schaltf1 = tk.Button(root, text="Aktion durchführen")


schaltf1.pack()

root.mainloop()

Das erzeugt uns eine Schaltfläche, die zwar noch nichts tut, aber schon einmal angezeigt wird.

Die Schreibweise über 2 Zeilen mit pack() können wir noch kürzer machen, indem wir das Pack
an unsere Anweisung tk.Button().pack() „anheften“ (diese Schreibweise klappt bei allen
Elementen, so auch bei dem Label für die Textausgabe). Das macht unseren Code schlanker
(was zum Lernen suboptimal ist, aber man mal gesehen haben sollte):

import tkinter as tk

root = tk.Tk()
label1 = tk.Label(root, text="Hallo Welt").pack()
schaltf1 = tk.Button(root, text="Aktion durchführen").pack()

root.mainloop()

Auch die Platzierung der Schaltfläche können wir wie beim Label-Widget über
side="left|center|right") beeinflussen.

label1 = tk.Label(root, text="Hallo Welt").pack(side="left")

schaltf1 = tk.Button(root, text="Aktion durchführen").pack(side="right")

Button/Schaltfläche mit Aktion verknüpfen


Jetzt belegen wir unsere Schaltfläche mit einer Aktion. Dazu geben wir dem Button-Widget
noch das Attribut command=Funktionsaufruf mit:

schaltf1 = tk.Button(root, text="Aktion durchführen", command=aktionSF)


schaltf1.pack()

Zusätzlich benötigen wir noch eine Funktion, die etwas macht. Hier nutzen wir die „Beenden“-
Funktion von Tkinter .destroy .

schaltf1 = tk.Button(root, text="Fenster schließen", command=tk.destroy)


schaltf1.pack()

Mit anklicken der Schaltfläche wird also unser Tkinter-Fenster geschlossen. Hier der komplette
Code:
© https://www.python-lernen.de/tkinter-button.htm Seite 201

import tkinter as tk

root = tk.Tk()

label1 = tk.Label(root, text="Hallo Welt", bg="orange")


label1.pack()

schaltf1 = tk.Button(root, text="Aktion durchführen", command=root.destroy)


schaltf1.pack()

root.mainloop()

Im nächsten Schritt wollen wir eigene Aktionen mit der Schaltfläche „verbinden“.

Eigene Aktionen mit Buttons verbinden


Wir lassen einfach eine Ausgabe im Fenster erfolgen. Das Attribut command erhält nun als
Wert den Funktionsnamen übergeben.

import tkinter as tk

def aktionSF():
label3 = tk.Label(root, text="Aktion durchgeführt", bg="yellow")
label3.pack()

root = tk.Tk()

label1 = tk.Label(root, text="Hallo Welt", bg="orange")


label1.pack()

schaltf1 = tk.Button(root, text="Aktion durchführen", command=aktionSF)


schaltf1.pack()

root.mainloop()

Jedes Mal, wenn wir nun die Schaltfläche anklicken erweitert sich das Fenster mit der Ausgabe
„Aktion durchgeführt“.

Inhalte auslesen und verarbeiten


Hier kommt der Begriff der Steuerelementvariablen ins Spiel. Von Python kennen wir
verschiedene Datentypen wie String, Integer, Float und Bool.

Um diese in Tkinter nutzen zu können, müssen die Benennung von Tkinter genutzt werden.

Datentyp Tkinter Datentyp Python-Datentyp

tkinter.StringVar str

tkinter.IntVar int

tkinter.DoubleVar float

tkinter.BooleanVar bool
© https://www.python-lernen.de/tkinter-button.htm Seite 202

Datentyp Tkinter Datentyp Python-Datentyp

Wir wollen in unserem kleinen Programm ein Feld mit einer Zahl auslesen und die Gradangabe
in Kelvin umrechnen. Mathematisch schön einfach, da wir einfach zu Gradangabe einfach 273
dazurechnen. Dazu müssen wir für unser Feld Entry die Art der Textvariable mitgeben – in
folgendem Beispiel ein String über tkinter.StringVar

eingabefeld_wert=tk.StringVar()
eingabefeld=tk.Entry(root, textvariable=eingabefeld_wert)
eingabefeld.pack()

Auf den vom Benutzer eingegebenen Inhalt wollen wir nun zugreifen, wenn der Button
angeklickt wird:

schaltf1 = tk.Button(root, text="Aktion durchführen", command=grad_nach_kelvin)


schaltf1.pack()

Und es wir nun die Funktion grad_nach_kelvin aufgerufen.

In der Funktion lassen wir zu Kontrolle einfach den Wert ausgeben. Unser erster Test dazu:

def grad_nach_kelvin():
print(eingabefeld_wert)

Als Ergebnis erhalten wir nur:

PY_VAR0

Was müssen wir machen, um auf den eigentlichen Inhalt zuzugreifen? Wir müssen diese mit
get() auslesen! Nun erhalten wir auch den eingegebenen Inhalt. Aber warum nutzen wir hier
Strings und nicht einen numerischen Datentyp? Probieren wir einfach einmal aus, was passiert,
wenn wir tk.IntVar() anstelle von tk.StringVar() nutzen.

Solange der Nutzer Ganzzahlen eingibt, ist alles gut. Sobald er versehentlich Text eingibt und
der Button geklickt wird, wird Python einen Fehler.

Es ist also gerade einfacher für uns, alle Eingaben zuzulassen und dann die Eingabe zu
„casten“ (siehe entsprechendes Kapitel):

Jetzt fehlt uns noch die Umrechnung von Grad Celsius in Kelvin. Hier die Formal dazu:

def grad_nach_kelvin():
# print(eingabefeld_wert.get())
grad = int(eingabefeld_wert.get())
kelvin = grad + 273
textausgabe = tk.Label(root, text=kelvin, bg="yellow")
textausgabe.pack()

Und schon haben wir einen Umrechner, den man garantiert jeden Tag benötigt :)

Der komplette Code:


© https://www.python-lernen.de/tkinter-button.htm Seite 203

import tkinter as tk

root = tk.Tk()

def grad_nach_kelvin():
# print(eingabefeld_wert.get())
grad = int(eingabefeld_wert.get())
kelvin = grad + 273
textausgabe = tk.Label(root, text=kelvin, bg="yellow")
textausgabe.pack()

eingabefeld_wert=tk.StringVar()
eingabefeld=tk.Entry(root, textvariable=eingabefeld_wert)
eingabefeld.pack()

schaltf1 = tk.Button(root, text="Aktion durchführen", command=grad_nach_kelvin)


schaltf1.pack()

root.mainloop()

Aussehen Button verändern


Es gibt weitere Attribute, um das Aussehen der Schaltfläche zu verändern. Hier eine Liste zum
selber testen. Ich denke, die jeweilige Möglichkeit ist klar:

highlightthickness="20"
highlightbackground="white", highlightcolor="blue"
© https://www.python-lernen.de/tkinter-cursor-aussehen.htm Seite 204

Cursorform ändern
Cursor verändern bei Mauskontakt
Über das Attribut cursor= können wir das Aussehen des Cursors verändern, wenn die Maus
unsere Schaltfläche berührt. Dabei haben wir verschiedene Aussehen zur Auswahl:

cursor='tcross'
cursor='hand1'
cursor='hand2'
cursor='heart'
cursor='pencil'
© https://www.python-lernen.de/tkinter-hoehe-breite-setzen.htm Seite 205

Höhe und Breite setzen


label1 = tk.Label(root, text="Hallo Welt", bg="orange", height=2, width=30)

Haben wir nun genügend Platz können wir den Text in diesem Bereich platzieren. Das läuft über
die Himmelsrichtungen und Kombinationen davon. Soll etwas links platziert werden, dann ist
dies die Angabe anchor="w"

Soll es links unten platziert werden, dann anchor="sw"

label1 = tk.Label(root, text="Hallo Welt", bg="orange", height=2, width=30, anchor="sw"

Folgenden Angaben der Himmelsrichtungen zum Platzieren stehen zur Verfügung:

n, ne, e, se, s, sw, w, nw, or center


© https://www.python-lernen.de/tkinter-radiobutton.htm Seite 206

Radiobutton in Tkinter
Der Name Radiobutton hat seinen technischen Ursprung von Omas Radio aus der Küche.
Dieses hatte Knöpfe, die man mit einzelnen Radiosendern belegen konnte. Drücke man einen,
sprang der bisher gedrückte in seine Ausgangsstellung. Man. konnte also immer nur einen
Sender gleichzeitig wählen (was auch irgendwie sinnvoll ist).

Das gleiche gilt für unsere Radiobutton in einer GUI. Hier haben wir die tpyschen Elemente, um
Eingaben abzufragen wie beispielsweise Mann oder Frau etc.

Radiobuttons machen also erst Sinn, wenn man mehr als eine Auswahl hat (sonst wäre die
Checkbutton die erste Wahl).

Wir haben bei Radiobuttons eine Beschriftung und einen Rückgabewert jeder Auswahl. Hierbei
kann aber Beschriftung und Rückgabewert gleich sein, muss aber nicht. Sprich wir haben einen
Button mit der Beschriftung „Herr“ und als Rückgabewert wird „m“ geliefert bzw. („Frau“ mit
Rückgabewert „w“). Im ersten Beispiel zum Verständnis des Widgets ist Beschriftung und
Rückgabewert identisch.

Wir erstellen dazu eine Liste in Python:

anrede = ["Frau", "Herr"]

Im nächsten Schritt müssen wir festlegen, welche Art unsere Rückgabevariable hat (String, Int,
…) und wie diese benannt ist:

anrede = ["Frau", "Herr"]

ausgewaehlt = tk.StringVar()

Und nun können wir unsere Liste durchlaufen und die Radiobuttons ausgeben lassen:

for einzelwert in anrede:


radiob = tk.Radiobutton(root, text=einzelwert, value=einzelwert, variable=ausgewaehlt
radiob.pack()

Das führt zu folgender Ausgabe:

[bild[Radiobutton ohne Vorgabewert]]

Wir erhalten die Lustige Ausgabe mit durchstrichenen Buttons, weil wir keinen Wert vorab
gesetzt haben! Wir können auch einen Wert vorab als erste angewählten Wert setzen:

ausgewaehlt = tk.StringVar()
ausgewaehlt.set("Frau")

Den gewählten Wert können wir abfragen über:

print(ausgewaehlt.get())
aktuell_ausgewaehlt = ausgewaehlt.get()

Jetzt wollen wir direkt bei Änderung des Wertes eine Aktion anstoßen. Also wird das typische
command aufgenommen:

Hier der komplette Code:


© https://www.python-lernen.de/tkinter-radiobutton.htm Seite 207

def ausgabe():
print(ausgewaehlt.get())
aktuell_ausgewaehlt = ausgewaehlt.get()
textausgabe = tk.Label(root, text=aktuell_ausgewaehlt, bg="orange")
textausgabe.pack()

anrede = ["Frau", "Herr"]

ausgewaehlt = tk.StringVar()
ausgewaehlt.set("Frau")

for einzelwert in anrede:


radiob = tk.Radiobutton(root, text=einzelwert, value=einzelwert, variable=ausgewaehlt
radiob.pack()

Würde man den Rückgabewert anders als den Anzeigewert setzen wollen, würde anstelle der
Liste ein Dictionary nutzen.

Folgende Attribute stehen zur Verfügung:


activebackground, activeforeground, anchor, background, bd, bg, bor- derwidth, command, fg,
foreground, height, justify, overrelief, padx, pady, relief, state, takefocus, text, textvariable, width

indicatoron und variable


© https://www.python-lernen.de/tkinter-checkbutton-checkbox.htm Seite 208

Checkbutton/Checkbox
Im Gegensatz zum Radiobutton kann jeder Checkbutton einen eigenständigen Status haben,
wobei es als Status angeklickt und nicht angeklickt, sprich aktiv oder deaktiviert gibt.

Im Folgenden kann der Befragte über Checkbuttons seine Hobbies auswählen:

[bild[Auswahl von Hobbies]]

Unseren Chechbutton erhalten wir über folgende 3 Zeilen:

checkbox01 = tk.Checkbutton(root)
checkbox01["text"] = "Sport treiben"
checkbox01.pack()

Wollen wir den Wert setzen bzw. anfragen, müssen wir einen Variablennamen an den
Checkbutton „binden“:

checkbox01 = tk.Checkbutton(root)
checkbox01["text"] = "Sport treiben"
checkbox01.pack()

checkbox01var = tk.BooleanVar()
checkbox01["variable"] = checkbox01var

Das Abfragen des Status erfolgt wie bereits bei den anderen Widgets über get() . Als
Rückgabewert erhalten wir „1“ für „angeklickt“ und „0“ für „nicht angeklickt“.

print(checkbox01var.get())

Wollen wir den Status ändern, können wir über set() diesen entsprechend setzen:

checkbox01var.set(True)

Und hier der komplette Code:


© https://www.python-lernen.de/tkinter-checkbutton-checkbox.htm Seite 209

import tkinter as tk

root = tk.Tk()

def ausgabe():
print(checkbox01var.get())
aktuell_ausgewaehlt = checkbox01var.get()
textausgabe = tk.Label(root, text=aktuell_ausgewaehlt, bg="orange")
textausgabe.pack()

checkbox01 = tk.Checkbutton(root)
checkbox01["text"] = "Sport treiben"
checkbox01.pack()

checkbox01var = tk.BooleanVar()
checkbox01var.set(True)
checkbox01["variable"] = checkbox01var

checkbox02 = tk.Checkbutton(root)
checkbox02["text"] = "Lesen"
checkbox02.pack()

checkbox02var = tk.BooleanVar()
checkbox02["variable"] = checkbox02var

checkbox03 = tk.Checkbutton(root)
checkbox03["text"] = "Filme schauen"
checkbox03.pack()

checkbox03var = tk.BooleanVar()
checkbox03["variable"] = checkbox03var

schaltf1 = tk.Button(root, text="Aktion durchführen", command= ausgabe)


schaltf1.pack()

root.mainloop()

Weitere Möglichkeiten bei Checkbutton


indicatoron (Bool)

offvalue

onvalue

checkbox01 = tk.Checkbutton(root, indicatoron=False, onvalue="Ja", offvalue="Nein")


checkbox01["text"] = "Sport treiben"
checkbox01.pack()
checkbox01var = tk.StringVar()
© https://www.python-lernen.de/tkinter-checkbutton-checkbox.htm Seite 210

Mögliche Attribute:
activebackground, activeforeground, anchor, background, bd, bg, bor- derwidth, command, fg,
foreground, height, justify, overrelief, padx, pady, relief, state, takefocus, text, textvariable, width
© https://www.python-lernen.de/tkinter-labelframe.htm Seite 211

LabelFrame – Gruppieren von Steuerelementen


Besonders bei Checkbutton und Radiobutton kennt man in der Praxis das Gruppieren der
Steuerelemente. Dadurch ist für den Nutzer schnell sichtbar, was zusammengehört und
zwischen Optionen er sich entscheiden kann. Ergänzen wir unsere Auswahl der Hobbies durch
eine Gruppierung, die wir „gruppehobby“ nennen. Wir erstellen einen Bereich mit der Benennung
„gruppehobby“. Diesem Bereich werden alle Steuerelemente zugewiesen, die innerhalb der
Gruppe dann ausgegeben werden sollen:

gruppehobby = tk.LabelFrame(root, text="Ihre Hobbies?")

[bild[LabelFrame – Steuerelemente gruppiert darstellen]]

Diese müssen wir dann noch den einzelnen Steuerelementen zuweisen und über pack()
ausgeben lassen. Der komplette Code:

import tkinter as tk
root = tk.Tk()

gruppehobby = tk.LabelFrame(root, text="Ihre Hobbies?")


gruppehobby.pack()

checkbox01 = tk.Checkbutton(gruppehobby)
checkbox01["text"] = "Sport treiben"
checkbox01.pack()
checkbox01var = tk.BooleanVar()
checkbox01["variable"] = checkbox01var

checkbox02 = tk.Checkbutton(gruppehobby)
checkbox02["text"] = "Lesen"
checkbox02.pack()
checkbox02var = tk.BooleanVar()
checkbox02["variable"] = checkbox02var

checkbox03 = tk.Checkbutton(gruppehobby)
checkbox03["text"] = "Filme schauen"
checkbox03.pack()
checkbox03var = tk.BooleanVar()
checkbox03["variable"] = checkbox03var

root.mainloop()

Wollen wir nun die Elemente noch sauber untereinander, können diese über anchor="w"
ausgerichtet werden:

[bild[Auswahl sauber untereinander ausgerichtet]]

Der komplette Quellcode in Python:


© https://www.python-lernen.de/tkinter-labelframe.htm Seite 212

import tkinter as tk
root = tk.Tk()

gruppehobby = tk.LabelFrame(root, text="Ihre Hobbies?")


gruppehobby.pack()

checkbox01 = tk.Checkbutton(gruppehobby)
checkbox01["text"] = "Sport treiben"
checkbox01.pack(anchor="w")
checkbox01var = tk.BooleanVar()
checkbox01["variable"] = checkbox01var

checkbox02 = tk.Checkbutton(gruppehobby)
checkbox02["text"] = "Lesen"
checkbox02.pack(anchor="w")
checkbox02var = tk.BooleanVar()
checkbox02["variable"] = checkbox02var

checkbox03 = tk.Checkbutton(gruppehobby)
checkbox03["text"] = "Filme schauen"
checkbox03.pack(anchor="w")
checkbox03var = tk.BooleanVar()
checkbox03["variable"] = checkbox03var

root.mainloop()

Weitere Optionen
labelanchor = n/ne/e/se/s/sw/w/nw

Ausrichtung der Beschriftung

labelwidget

Anstelle von Beschriftung ein anderes Widget (im Bereich wo ansonsten die Beschriftung
sitzen würde)
© https://www.python-lernen.de/tkinter-listbox.htm Seite 213

Listbox – Viel Inhalt zur Auswahl (auch Mehrfachauswahl)


Über das Element Listbox können Inhalte als Liste aufgeführt werden, in der ein oder mehrere
Einträge ausgewählt werden können.

Im folgenden Beispiel eine Einkaufsliste. Der Inhalt wird als Liste in Python erstellt und dann
über eine for-Schleife jeder einzelner Listenpunkt eingefügt.

Der dazugehörte Python-Code:

import tkinter as tk
fenster = tk.Tk()

einkaufsliste = ["Mehl", "Butter", "Hefe", "Wasser", "O-Saft", "Haferflocken"]

lbox = tk.Listbox(fenster)
lbox.pack()

for lebensmittel in einkaufsliste:


lbox.insert("end", lebensmittel)

schaltf1 = tk.Button(fenster, text="Aktion durchführen", command= ausgabe)


schaltf1.pack()

fenster.mainloop()

Standardmäßig kann nur 1 Auswahl gemacht werden, bis etwas anderes eingestellt wird. Wir
erhalten über curselection() den Index des gewählten Listenpunktes:

import tkinter as tk

fenster = tk.Tk()

def ausgabe():
print(lbox.curselection())
aktuell_ausgewaehlt = lbox.curselection()
textausgabe = tk.Label(fenster, text=aktuell_ausgewaehlt, bg="orange")
textausgabe.pack()

einkaufsliste = ["Mehl", "Butter", "Hefe", "Wasser", "O-Saft", "Haferflocken"]

lbox = tk.Listbox(fenster)
lbox.pack()

for lebensmittel in einkaufsliste:


lbox.insert("end", lebensmittel)

schaltf1 = tk.Button(fenster, text="Aktion durchführen", command= ausgabe)


schaltf1.pack()

fenster.mainloop()

Wollen wir es ermöglichen, dass mehrere Einträge ausgewählt werden können, geschieht dies
über lbox["selectmode"] = "extended"
© https://www.python-lernen.de/tkinter-listbox.htm Seite 214

Jetzt erhalten wir als Rückgabewert, wenn das zweite, dritte und fünfte Element gewählt wurde
dann (1, 2, 4) (zur Erinnerung: Computer fangen bei 0 an zu zählen).

Bei selectmode stehen uns folgende Möglichkeiten zur Verfügung:

selectmode:

single/browse es kann nur 1 Eintrag ausgewählt werden

multiple oder extended mehrere Einträge auswählbar


© https://www.python-lernen.de/webbrowser-mit-python-nutzen.htm Seite 215

Webbrowser über Python nutzen


Python kann sehr einfach über das Modul webbrowser einen auf dem System installierten
Internetbrowser nutzen und diesem eine URL übergeben.

Im ersten Schritt muss das Modul importiert werden:

import webbrowser

Im nächsten Schritt kann bereits eine URL geöffnet werden. Der übersichtlichkeitshalber wird
erst eine Variable mit der URL erstellt und diese dann im Befehl webbrowser.open()
genutzt:

import webbrowser

url = 'https://www.Python-lernen.de/'
webbrowser.open(url)

Das Gleiche kann über die Anweisung webbrowser.open_new(url) erreicht werden.

import webbrowser

url = 'https://www.Python-lernen.de/'
webbrowser.open_new(url)

Und noch ein Befehl: allerdings wieder das gleiche wie oben kann über die Anweisung
webbrowser.open_new_tab(url) erreicht werden.

import webbrowser

url = 'https://www.Python-lernen.de/'
webbrowser.open_new_tab(url)

Browser auswählen (sofern installiert)


Soll gezielt ein Browser ausgewählt werden (sofern dieser Browser auch installiert ist – nicht
überall ist Firefox, Chrome etc. vorhanden) kann dies über webbrowser.get('firefox')
erfolgen:

Dabei haben hier nur die üblichen Verdächtigen:

firefox

safari

chrome

opera

windows-default

Und der Code als komplettes Beispiel, in dem die URL in Browser Firefox geöffnet wird:

import webbrowser

url = 'https://www.Python-lernen.de/'
webbrowser.get('firefox').open(url)

Der Browser ‚windows-default‘ funktioniert nur auf Windows Systemen und erzeugt auf
© https://www.python-lernen.de/webbrowser-mit-python-nutzen.htm Seite 216

anderen Systemen einen „webbrowser.Error“. Das Gleiche gilt für ‚safari‘ – dieser funktioniert
nur auf macOS Plattformen.

Zusätzlich kann open() weitere Parameter übergeben werden:


open(url, neu=0)

Der Parameter „neu“ kann 0 (Standard) für eine vorhandene Browserinstanz sein, 1 für ein
neues Browserfenster (wenn möglich) und 2 für ein neues Browserfenster mit Tab. Testen –
reagiert je nach Betriebssystem anders.

Suche bei Google über Python nutzen


Wenn wir die Suche von Google direkt aus unserem Python-Programm ansteuern wollen,
müssen wir im ersten Schritt unsere Suchbegriffe in Python erfassen und dann über das
Webbrowser-Modul die entsprechende URL zusammenbauen. Bei der Suche werden die
Suchbegriffe über „&q=“ übergeben:

import webbrowser
url = 'https://www.google.de/?q='

suchbegriff = input("Bitte Suchbegriff eingeben: ")


webbrowser.open(url+suchbegriff)

Wollen wir die Suche direkt ausgeführt bekommen, dann ändert sich die URL entsprechend:

import webbrowser
url = 'https://www.google.de/search?q='

suchbegriff = input("Bitte Suchbegriff eingeben: ")


webbrowser.open(url+suchbegriff)
© https://www.python-lernen.de/bibliothek-urllib.htm Seite 217

urllib – Internetseiten auslesen


Über die System-Bibliothek urllib können Inhalte von Internetseiten ausgelesen werden.
Dabei ist die Handhabung sehr einfach, wenn die ausgelesene Internetseiten das Auslesen
nicht unterbindet. Schauen wir uns die Handhabung an.

Im Browser gibt man eine URL an, um eine Website abzurufen. Dabei steht URL für „Uniform
Resource Locator“ – also übersetzt „einheitlicher Ressourcenzeiger“. Dabei kann die URL viele
Informationen enthalten.

Schauen wir es uns am Beispiel von folgender URL an:


https://www.python-lernen.de/search?q=Axel#top

Aufbau URL:

Protokoll: Am Anfang steht das Protokoll, z.B. https, http, ftp usw.

Hostname: dann kommt der Hostname, im Beispiel www.python-lernen.de

Port: manchmal kommt danach ein Doppelpunkt mit einer Nummer danach. Dadurch wird der
Port festgelegt. Standardmäßig steht der Port 80 für http und der Port 443 für https – diese
müssen nicht angegeben werden. Aussehen würde es sonst so: https://www.python-
lernen.de:443/

Pfad: Wenn nicht dir Startseite angezeigt werden soll, wird der Pfad zur gewünschten Seite
mitgegebenen

Query-String: nach dem Fragezeichen können zusätzlich Daten über dir URL übertragen
werden. Im Beispiel wird der Inhalt für die Suchfunktion übertragen

Sprungmarke: Am Ende kann gekennzeichnet durch die Raute noch eine Sprungmarke
innerhalb der Seite mitgegeben werden

Die URLLIB-Bibliothek unterstützt das Erstellen, Herunterladen und Parsing von URLs. Dafür
stehen in der Bibliothek 5 Module zur Verfügung, von denen 4 durch den Programmierer
eingesetzt werden können:

request

response (wird intern von URLLIB genutzt)

error

parse

robotparser

Über request öffnen wird URLs

Über error können wir auf Fehler während dem Zugriff etc. reagieren

Mit parse stehen praktische URL-Funktionen zur Verfügung

Und über robotparser können wir den Inhalt der robots.txt auswerten.

request-Modul – Laden von Inhalten


Zum Nutzen der URLLIB-Bibliothek müssen wir diese importieren.
© https://www.python-lernen.de/bibliothek-urllib.htm Seite 218

import urllib
print(help(urllib))

Über die Help-Funktion sehen wir wieder unsere 5 Module (request, error, parse, …), die wir
nutzen können.

Wir wollen im Folgenden das Modul request nutzen:

from urllib import request

Lassen wir uns mit dir alle Angaben ausgeben, sehen wir die vielen Methoden und Klassen,
die uns über das Modul zur Verfügung stehen:

from urllib import request


print(dir(request))

['AbstractBasicAuthHandler', 'AbstractDigestAuthHandler', 'AbstractHTTPHandler',


'BaseHandler', 'CacheFTPHandler', 'ContentTooShortError', 'DataHandler', 'FTPHandler',
'FancyURLopener', 'FileHandler', 'HTTPBasicAuthHandler', 'HTTPCookieProcessor',
'HTTPDefaultErrorHandler', 'HTTPDigestAuthHandler', 'HTTPError', 'HTTPErrorProcessor',
'HTTPHandler', 'HTTPPasswordMgr', 'HTTPPasswordMgrWithDefaultRealm',
'HTTPPasswordMgrWithPriorAuth', 'HTTPRedirectHandler', 'HTTPSHandler', 'MAXFTPCACHE',
'OpenerDirector', 'ProxyBasicAuthHandler', 'ProxyDigestAuthHandler', 'ProxyHandler', 'Request',
'URLError', 'URLopener', 'UnknownHandler', '__all__', '__builtins__', '__cached__', '__doc__', '__file__',
'__loader__', '__name__', '__package__', '__spec__', '__version__', '_cut_port_re', '_ftperrors',
'_get_proxies', '_get_proxy_settings', '_have_ssl', '_localhost', '_noheaders', '_opener',
'_parse_proxy', '_proxy_bypass_macosx_sysconf', '_randombytes', '_safe_gethostbyname',
'_splitattr', '_splithost', '_splitpasswd', '_splitport', '_splitquery', '_splittag', '_splittype', '_splituser',
'_splitvalue', '_thishost', '_to_bytes', '_url_tempfiles', 'addclosehook', 'addinfourl', 'base64', 'bisect',
'build_opener', 'contextlib', 'email', 'ftpcache', 'ftperrors', 'ftpwrapper', 'getproxies',
'getproxies_environment', 'getproxies_macosx_sysconf', 'hashlib', 'http', 'install_opener', 'io',
'localhost', 'noheaders', 'os', 'parse_http_list', 'parse_keqv_list', 'pathname2url', 'posixpath',
'proxy_bypass', 'proxy_bypass_environment', 'proxy_bypass_macosx_sysconf', 'quote', 're',
'request_host', 'socket', 'ssl', 'string', 'sys', 'tempfile', 'thishost', 'time', 'unquote',
'unquote_to_bytes', 'unwrap', 'url2pathname', 'urlcleanup', 'urljoin', 'urlopen', 'urlparse',
'urlretrieve', 'urlsplit', 'urlunparse', 'warnings']

Wir wollen ein URL laden, daher benötigen wir urlopen(url) . Zum Testen nutzen wir die
Beispielseite www.example.com

from urllib import request


rueckgabewert = request.urlopen('http://www.example.com/')
print(type(rueckgabewert))

Als Rückgabewert erhalten wir ein Response-Objekt (kann man wohl am besten mit Antwort-
Objekt übersetzten) – siehe type(rueckgabewert) .

<class 'http.client.HTTPResponse'>

Dieses Antwort-Objekt stellt und verschiedene Methoden zur Verfügung:


© https://www.python-lernen.de/bibliothek-urllib.htm Seite 219

from urllib import request


rueckgabewert = request.urlopen('http://www.example.com/')
print(type(rueckgabewert))
print(dir(rueckgabewert))

Als Ergebnis von dir(rueckgabewert) erhalten wir:

['__abstractmethods__', '__class__', '__del__', '__delattr__', '__dict__', '__dir__', '__doc__', '__enter__',


'__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__',
'__init_subclass__', '__iter__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__next__',
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__',
'_abc_impl', '_checkClosed', '_checkReadable', '_checkSeekable', '_checkWritable',
'_check_close', '_close_conn', '_get_chunk_left', '_method', '_peek_chunked', '_read1_chunked',
'_read_and_discard_trailer', '_read_next_chunk_size', '_read_status', '_readall_chunked',
'_readinto_chunked', '_safe_read', '_safe_readinto', 'begin', 'chunk_left', 'chunked', 'close', 'closed',
'code', 'debuglevel', 'detach', 'fileno', 'flush', 'fp', 'getcode', 'getheader', 'getheaders', 'geturl',
'headers', 'info', 'isatty', 'isclosed', 'length', 'msg', 'peek', 'read', 'read1', 'readable', 'readinto',
'readinto1', 'readline', 'readlines', 'reason', 'seek', 'seekable', 'status', 'tell', 'truncate', 'url', 'version',
'will_close', 'writable', 'write', 'writelines']

Wir können also den Rückantwort-Code anfragen über .code :

from urllib import request


rueckgabewert = request.urlopen('http://www.example.com/')
print(rueckgabewert.code)

Hier erhalten wir als Rückgabe den Wert 200 . Dieser sagt uns, dass die Anfrage geklappt hat.
Es gibt verschiedene Rückgabewerte, die über Erfolg oder Misserfolg der Aktion uns alles
sagen. Diese nennen sich http Status Codes:

200: OK

400: Bad Request

403: Forbidden

404: Not Found

Wir können genauso die Größe der „Datei“ über .length abfragen:

from urllib import request


rueckgabewert = request.urlopen('http://www.example.com/')
print("Dateigröße in Bytes: ", rueckgabewert.length)

Und wir können den Anfang des Inhalts anzeigen lassen über .peek() :

from urllib import request


rueckgabewert = request.urlopen('http://www.example.com/')
print("Anfang des Inhalts:
", rueckgabewert.peek())

Und hier bekommen wir folgende Rückgabe – wichtig ist der Anfang mit b' !
© https://www.python-lernen.de/bibliothek-urllib.htm Seite 220

b'<!doctype html>
<html>
<head>
<title>Example Domain</title>
<meta charset="utf-8" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
body {
background-color: #f0f0f2;
margin: 0;
padding

Dieses b' am Anfang sagt uns, dass es sich um ein Byte-Objekt handelt.

Jetzt können wir die komplette Datei auslesen über die Anweisung rueckantwort.read() .

from urllib import request


rueckgabewert = request.urlopen('http://www.example.com/')
inhalt = rueckgabewert.read()
print(type(inhalt))

Wir bekommen als Rückantwort die Bestätigung über das Überprüfen des Typs, dass es sich
um einen Byte-Strom handelt:

<class 'bytes'>

Den Inhalt können wir umwandeln. Dazu muss das Format bekannt sein. Wir haben bei den
ersten Zeilen des Inhalts gesehen, dass es sich um das UTF8-Format handelt.

from urllib import request


rueckgabewert = request.urlopen('http://www.example.com/')
inhalt = rueckgabewert.read()
print(type(inhalt))
inhalt_text = inhalt.decode("UTF-8")
print(type(inhalt_text))

Danach liegt und ein String vor („<class 'str'>“) und wir können dieses ausgeben.

from urllib import request


rueckgabewert = request.urlopen('http://www.example.com/')
inhalt = rueckgabewert.read()
inhalt_text = inhalt.decode("UTF-8")
print(inhalt_text)

<!doctype html>
<html>
<head>
<title>Example Domain</title>
<meta charset="utf-8" />

Nachdem wir den Inhalt ausgelesen haben, wird die Verbindung automatisch geschlossen. Es
kann der Inhalt kein zweites Mal aus dem Byte-Strom ausgelesen werden!

Dazu weitere Information unter:


https://docs.python.org/3/library/urllib.html
© https://www.python-lernen.de/bibliothek-urllib.htm Seite 221
© https://www.python-lernen.de/requests-bibliothek-online-zugriffe.htm Seite 222

Bibliothek requests – jede Ressource online nutzen


Wir können über die Bibliothek requests einfach Zugriffe auf Onlineinhalte durchführen.

Zuvor muss die Bibliothek über PIP installiert werden:

pip install requests

Als Rückmeldung erhalten wir:

mac:Python-lernen.de axelpratzner$ pip install requests


Collecting requests
Downloading requests-2.23.0-py2.py3-none-any.whl (58 kB)
|████████████████████████████████| 58 kB 471 kB/s
Collecting chardet4,=3.0.2
Downloading chardet-3.0.4-py2.py3-none-any.whl (133 kB)
|████████████████████████████████| 133 kB 1.0 MB/s
Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in
/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages (from
requests) (1.25.8)
Requirement already satisfied: idna<3,>=2.5 in
/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages (from
requests) (2.9)
Collecting certifi>=2017.4.17
Downloading certifi-2019.11.28-py2.py3-none-any.whl (156 kB)
|████████████████████████████████| 156 kB 1.3 MB/s
Installing collected packages: chardet, certifi, requests
Successfully installed certifi-2019.11.28 chardet-3.0.4 requests-2.23.0

Wollen wir jetzt einen Inhalt herunterladen wie z.B. die Website www.example.com, dann klappt
das in einem Dreizeiler:

import requests
r = requests.get('https://www.example.com/')
print(r.text)

Wir erhalten darauf den kompletten HTML-Code der Seite angezeigt:

<!doctype html>
<html>
<head>
<title>Example Domain</title>
<meta charset="utf-8" />

Das klappt sowohl bei http bei wie auch bei https – also kein Problem mit SSL-Zertifikaten.

Zum Überprüfen des HTTP-Status-Codes gibt es die Anweisung r.status_code

import requests
r = requests.get('https://www.example.com/')
print (r.status_code)

Als Rückmeldung erhalten wir „200“ – also lief gut!

Wollen wir nur die Information, ob es geklappt hat oder nicht: r.ok
© https://www.python-lernen.de/requests-bibliothek-online-zugriffe.htm Seite 223

Online-Grafikdatei herunterladen
Wollen wir ein Bild von einer Website herunterladen, dann klappt das ebenso einfach. Wir
wollen von unserer Python Kurs das GIF-Bild mit der animierten Biene herunterladen. Dazu
benötigen wir die URL „https://www.python-lernen.de/bilder/biene-sprite-animiert-01.gif“
(rechte Maustaste auf das Bild und „Bild in neuem Tab öffnen“ gibt uns die URL)

Anstelle des Inhalts als r.text bekommen wir diesen als r.content ausgelesen.

import requests
r = requests.get('https://www.python-lernen.de/bilder/biene-sprite-animiert-01.gif')
print(r.content)

Geben wir den Inhalt direkt auf dem Bildschirm aus sehen wir anhand der Anfangszeichen,
dass es sich um eine binäre Datei (b') handelt und um das Grafikformat GIF.

b'GIF89a2​�w!�

Diesen Inhalt können wir nun auch direkt abspeichern:

import requests
r = requests.get('https://www.python-lernen.de/bilder/biene-sprite-animiert-01.gif')

with open('biene.gif', 'wb') as f:


f.write(r.content)

Jetzt befindet sich in unserem Verzeichnis eine Grafikdatei mit dem Namen „biene.gif“. Einfach
mal nachsehen ;)

header-Daten auslesen einer Internetseite


Sehr einfach können wir die header-Inforamtionen von einer Online-Quelle erhalten. Wir
erhalten diese über r.headers :

import requests
r = requests.get('https://www.example.com/')
print (r.status_code)
print (r.ok)
print (r.headers)

Wir erhalten diese in Form des Datentyps Dictionary:

{'Content-Encoding': 'gzip', 'Accept-Ranges': 'bytes', 'Age': '9820', 'Cache-Control': 'max-


age=604800', 'Content-Type': 'text/html; charset=UTF-8', 'Date': 'Sat, 29 Feb 2020 11:00:04
GMT', 'Etag': '"3147526947"', 'Expires': 'Sat, 07 Mar 2020 11:00:04 GMT', 'Last-Modified': 'Thu, 17
Oct 2019 07:18:26 GMT', 'Server': 'ECS (nyb/1D2F)', 'Vary': 'Accept-Encoding', 'X-Cache': 'HIT',
'Content-Length': '648'}

Parameter übermitteln über get/post


© https://www.python-lernen.de/requests-bibliothek-online-zugriffe.htm Seite 224

Die Bibliothek unterstützt das einfache übermitteln von Parametern sowohl mit „get“ wie auch
„post“. Der Online-Dienst https://httpbin.org/ ermöglicht das einfach Testen der jeweiligen
Anfragen:

import requests

payload = {'key1': 'value1', 'key2': 'value2'}


r = requests.post("https://httpbin.org/post", data=payload)
print (r.text)

print (r.status_code)
print (r.ok)

Als Rückmeldung erhalten wir:

{
"args": {},
"data": "",
"files": {},
"form": {
"key1": "value1",
"key2": "value2"
},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Content-Length": "23",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.23.0",
"X-Amzn-Trace-Id": "Root=1-5e5a4638-d6b461203ebe5a0becaf4e4c"
},
"json": null,
"origin": "79.197.98.81",
"url": "http://httpbin.org/post"
}

200

True

Oder das gleiche Spiel mit „get“:

import requests
payload = {'schluessel1': 'wert1', 'schluessel2': 'wert2'}
r = requests.get("http://httpbin.org/get", params=payload)
print (r.text)

Als Rückmeldung erhalten wir:


© https://www.python-lernen.de/requests-bibliothek-online-zugriffe.htm Seite 225

"args": {
"schluessel1": "wert1",
"schluessel2": "wert2"
},

"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.23.0",
"X-Amzn-Trace-Id": "Root=1-5e5a46eb-f349c1c4e9543820b57730d8"
},

"origin": "79.197.98.81",
"url": "http://httpbin.org/get?schluessel1=wert1&schluessel2=wert2"
}

Die Bibliothek erzeugt also die korrekten Parameter und kümmert sich um die korrekte
Übergabe.

Anstelle von einer Textrückgabe können wir auch es Form von JSON erhalten. Dazu einfach
folgende Zeile ändern:

import requests
payload = {'schluessel1': 'wert1', 'schluessel2': 'wert2'}
r = requests.get("http://httpbin.org/get", params=payload)
r_dict = r.json()
print(r_dict['args'])

Rückgabe:

{'schluessel1': 'wert1', 'schluessel2': 'wert2'}

Auth-Zugang - geschütze Bereiche nutzen


Geschütze Bereiche können auch über requests genutzt werden (sofern man die
Zugangsdaten kennt). Bei der üblichen Nutzung der Auth-Methode über die .htaccess
bekommt man normalerweise die Eingabeaufforderung über den Browser.

Diese kann man über requests „übergehen“:

import requests
r = requests.get('http://httpbin.org/basic-auth/a/b', auth=('a', 'b'))
print (r.status_code)
print (r.ok)
print (r.text)

Als Rückmeldung erhalten wir:


© https://www.python-lernen.de/requests-bibliothek-online-zugriffe.htm Seite 226

200
True
{
"authenticated": true,
"user": "a"
}

Verzögerungen einplanen
Wenn der Zugriff auf die Online-Ressource länger dauert, kann man diese Verzögerung
„einplanen“.

Wir geben der Anweisung request.get(url, timeout=5) einen entsprechenden Wert


bei dem Parameter timeout mit.

Website Hersteller
Weitere Informationen (auch in deutscher Übersetzung) findet sich auf der Programmierer-
Websites der Bibliothek requests unter:
https://requests.readthedocs.io/de/latest/index.html
© https://www.python-lernen.de/selenium-fernsteuern-browser.htm Seite 227

Selenium automatisiert/fernsteuert den Browser über


Python
Selenium ist eine Bibliothek für Python, um Aktionen im Browser fernzusteuern bzw. zu
automatisieren. So kann man sehr einfach darüber auch Online-Anwendungen testen.

Im ersten Schritt müssen wir Selenium installieren. Das passiert über pip :

pip install selenium

Selenium über PIP installieren

Jetzt benötigen wir den passenden Treiber (engl. „driver“) für unseren gewählten Browser (und
Betriebssystem) unsere Wahl. Wenn wir Chrome nutzen, dann findet sich der Treiber unter:
https://chromedriver.chromium.org/downloads

Und dort für das eigene Betriebssystem und die Browserversion

chromedriver für eigenes Betriebssystem

Für Firefox:
https://github.com/mozilla/geckodriver/releases

Bei Mac Catalina kommt es zu Problemen wegen der Downloadquelle. Mehr dazu unter
https://firefox-source-docs.mozilla.org/testing/geckodriver/Notarization.html

Wenn das ein Problem beim Mac ist, hilft das:

# für Chrome
xattr -r -d com.apple.quarantine chromedriver

# für Firefox
xattr -r -d com.apple.quarantine geckodriver
© https://www.python-lernen.de/selenium-fernsteuern-browser.htm Seite 228

Jetzt können wir unser erstes Python-Programm mit dem Modul Selenium schreiben:

from selenium import webdriver

driver = webdriver.Chrome('/Users/ich/Python-lernen.de/fs/chromedriver')

driver.get('https://www.google.de/')

Als Ausgabe erhalten wir nun den Browser gestartet und Google.de angezeigt:

Chrome über Selenium: Ausgabe Chrome wird von automatisierten Testsoftware gesteuert

Nachdem der Browser gestartet wurde und die Seite aufgebaut wurde, bleibt der Browser
offen.

Jetzt wollen wir Aktionen im Browser ausführen. Allerdings sollten wir kurz warten, dass die
Seite auch aufgerufen wurde und komplett dargestellt ist.

Daher schicken wir den Browser nach dem Aufruf der URL erst einmal schlafen. Dazu wird das
Modul time importiert und dann schicken wir unser Python-Programm 3 Sekunden schlafen
(ein PowerNap soll gesund sein).

from selenium import webdriver


import time

driver = webdriver.Chrome('/Users/ich/Python-lernen.de/fs/chromedriver')

driver.get('https://www.google.de/')

time.sleep(3)

Jetzt packen wir das Suchfeld in eine Variable über find_element_by_name() und
schicken dort Tastatureingaben hin:
© https://www.python-lernen.de/selenium-fernsteuern-browser.htm Seite 229

from selenium import webdriver


import time

driver = webdriver.Chrome('/Users/ich/Python-lernen.de/fs/chromedriver')

driver.get('https://www.google.de/')

time.sleep(3)

aktion = driver.find_element_by_name('q')
aktion.send_keys("Python lernen")
aktion.submit()

time.sleep(10)
driver.quit()
© https://www.python-lernen.de/bibliothek-matplotlib.htm Seite 230

matplotlib – mehr als nur eine 2D Diagramm


Bibliothek
Bei matplotlib handelt es sich um eine Python 2D Diagramm Bibliothek – wir können also
sehr einfach grafische Darstellungen von Daten und Zahlenreihen erstellen.

Zahlreiche Beispiele finden sich auf der dazugehörigen Website unter https://matplotlib.org

Im ersten Schritt müssen wir die Bibliothek über PIP installieren:

pip install matplotlib

Nach der Installation können wir die Bibliothek durch den typischen Import in Python nutzen:

import matplotlib as plt

Hier wird die Abkürzung „plt“ genutzt – Konvention hilft anderen Programmieren schneller
Python-Code zu verstehen, daher sollte man solche Konventionen einhalten.

Wir erstellen nun eine Liste mit Zahlen, die wir als Diagramm ausgeben lassen wollen:

import matplotlib.pyplot as plt

daten = [4, 7, 1, 9, 5, 2, 8]

Jetzt müssen wir die Form der Ausgabe festlegen über plot() und die Ausgabe starten über
show() :

import matplotlib.pyplot as plt

daten = [4, 7, 1, 9, 5, 2, 8]
plt.plot(daten)
plt.show()

Wir erhalten nun in einem neuen Fenster die Ausgabe:


© https://www.python-lernen.de/bibliothek-matplotlib.htm Seite 231

Ausgabe eines Liniendiagramms über matplotlib.pyplot

Beschriftung der Achsen aktivieren


Um eine Beschriftung der Achsen zu aktivieren, geben wir die Anweisung plt.xlabel() und
plt.ylabel() mit. Dies muss vor der Ausgabe mit show() erfolgen:

import matplotlib.pyplot as plt

daten = [4, 7, 1, 9, 5, 2, 8]
plt.plot(daten)
plt.xlabel("X-Werte")
plt.ylabel("Y-Werte")
plt.show()

Als Ergebnis erhalten wir die Beschriftung unter der x-Achse und links neben der y-Achse.

Beschriftung X- und Y-Achse

Ausgabe als Balkendiagramm


Bemerkenswert ist, dass die Werte der x-Achse einfach erstellt werden. Bei vielen Diagramme
benötigen wir sowohl die X wie Y-Werte. Wir machen aus unserer Liste mit der Bezeichnung
daten nun unsere Liste ywerte und erstellen eine zweite Liste xwerte . Diese könnten wir
auch über range() erstellen. Als Ausgabe wählen wir den Diagrammtyp plt.bar(x, y)
und übergeben die beiden Listen:
© https://www.python-lernen.de/bibliothek-matplotlib.htm Seite 232

import matplotlib.pyplot as plt

ywerte = [4, 7, 1, 9, 5, 2, 8]
xwerte = [1, 2, 3, 4, 5, 6, 7]
plt.bar(xwerte, ywerte)
plt.xlabel("X-Werte")
plt.ylabel("Y-Werte")
plt.show()

Wir erhalten nun ein Balkendiagramm:

Balkendiagramm

Diagramm mit Punkten


Diagrammtyp plt.scatter(x, y) auswählen und die beiden Listen übergeben:

import matplotlib.pyplot as plt

ywerte = [4, 7, 1, 9, 5, 2, 8]
xwerte = [1, 2, 3, 4, 5, 6, 7]
plt.scatter(xwerte, ywerte)
plt.xlabel("X-Werte")
plt.ylabel("Y-Werte")
plt.show()

Wir erhalten nun ein Diagramm mit Punkten:


© https://www.python-lernen.de/bibliothek-matplotlib.htm Seite 233

Diagramm mit Punkten

Mehrere Diagramme kombinieren


Kombiniert man mehrere Diagrammtypen wie beispielsweise das Liniendiagramm mit dem
Punktdiagramm, kann ein Mehrwert entstehen:

import matplotlib.pyplot as plt

ywerte = [4, 7, 1, 9, 5, 2, 8]
xwerte = [1, 2, 3, 4, 5, 6, 7]
plt.plot(xwerte, ywerte)
plt.scatter(xwerte, ywerte)
plt.xlabel("X-Werte")
plt.ylabel("Y-Werte")
plt.show()

Möchte man nun die Punkte hervorheben und diesen eine andere Farbe zuweisen, ist das kein
Problem. Die Anweisung plt.scatter(x,y,c=color) wird um den Parameter „c“ für
Farbe (color) erweitert:

plt.scatter(xwerte, ywerte, color='red')

Einfach testen – als Ergebnis sollte folgende Diagrammausgabe erscheinen:


© https://www.python-lernen.de/bibliothek-matplotlib.htm Seite 234

Diagrammtypen kombiniert mit zugewiesenen Farben

Diagramm als Grafik speichern


Neben der Ausgabe eines Diagramms beherrscht die matplotlib-Bibliothek auch das Speichern
der Diagramme als Datei. Dafür gibt es die Anweisung:

plt.savefig('gespeichertesdiagramm.png')

Diese kann anstelle von plt.show() oder zusätzlich zu der Bildschirmausgabe erfolgen.

Gerade in Diagramm einzeichnen (z.B. als Trendlinie)


Wollen wir noch eine Gerade in das Diagramm einzeichnen z.B. als Trendlinie, ist dies sehr
einfach möglich durch plt.plot((x1, x2), (y1,y2)) .

import matplotlib.pyplot as plt

ywerte = [4, 7, 1, 9, 5, 2, 8]
xwerte = [1, 2, 3, 4, 5, 6, 7]
plt.plot(xwerte, ywerte)
plt.scatter(xwerte, ywerte, color='red')
plt.xlabel("X-Werte")
plt.ylabel("Y-Werte")

x1 = 1
x2 = 7
y1 = 3.5
y2 = 4.5
plt.plot((x1, x2), (y1, y2))

plt.show()
© https://www.python-lernen.de/bibliothek-matplotlib.htm Seite 235

Und somit haben wir automatisch ein drittes Element mit einer automatisch zugewiesenen
Farbe:

Trendlinie in Diagramm

viele viele Diagrammarten möglich


Die zahlreichen Möglichkeiten sieht man bei den Beispielen unter https://matplotlib.org/gallery
- viel Spaß beim Einsatz der Bibliothek matplotlib.
© https://www.python-lernen.de/nltk-bibliothek-natural-language-toolkit.htm Seite 236

Natural Language Toolkit (NLTK) – Sprache mit Python


auswerten
Bei der Bibliothek NLTK (Natural Language Toolkit) kann ideal in der Computerlinguistik
genutzt werden. Damit können natürliche Sprache algorithmisch verarbeitet werden.

Hier soll die einfache Anwendung in Form von der Auswertung von Worthäufigkeiten gezeigt
werden und die Ausgabe einer Grafik über die Wörterhäufigkeitsverteilung. Das schöne ist, wie
einfach dies über die NLTK-Bibliothek möglich ist.

Im ersten Schritt muss in Python die NLTK-Bibliothek über PIP installiert werden:

pip install nltk

Jetzt können wir die Bibliothek auf Text loslassen. Als Erstes müssen wir diese aktivieren
durch import nltk und dann benötigen wir einen Text. Wir nutzen die bekannte Ballade
„Erlkönig“ von „Wolfgang von Goethe“. Den kompletten Text gibt es bei Wikipedia unter:
https://de.wikipedia.org/wiki/Erlk%C3%B6nig_(Ballade)

import nltk

inhalt = """Der Erlkönig


Wer reitet so spät durch Nacht und Wind?
Es ist der Vater mit seinem Kind;
Er hat den Knaben wohl in dem Arm,
er faßt ihn sicher, er hält ihn warm.
Mein Sohn, was birgst du so bang dein Gesicht?
Siehst, Vater, du den Erlkönig nicht?
Den Erlkönig mit Kron und Schweif? -
Mein Sohn, es ist ein Nebelstreif. -
"Du liebes Kind, komm geh mit mir!
"""

woerter = inhalt.split()
worthaeufigkeit = nltk.FreqDist(woerter)
print(worthaeufigkeit)
print(worthaeufigkeit.most_common())

Unseren Text in der Variable inhalt wandeln wir über die Funktion split() in eine Liste
mit dem Namen woerter um, die wir mit Methoden unserer Bibliothek nltk nutzen können.
Über die Methode most_common() erhalten wir die Verteilung - als Ergebnis bekommen wir
angezeigt:

python3 worthaeufigkeit-erlkoenig.py

[('Erlkönig', 3), ('mit', 3), ('so', 2), ('und', 2), ('ist', 2), ('den', 2), ('er', 2), ('ihn', 2), ('Mein', 2), ('Sohn,',
2), ('du', 2), ('-', 2), ('Der', 1), ('Wer', 1), ('reitet', 1), ('spät', 1), ('durch', 1), ('Nacht', 1), ('Wind?', 1),
('Es', 1), ('der', 1), ('Vater', 1), ('seinem', 1), ('Kind;', 1), ('Er', 1), ('hat', 1), ('Knaben', 1), ('wohl', 1),
('in', 1), ('dem', 1), ('Arm,', 1), ('faßt', 1), ('sicher,', 1), ('hält', 1), ('warm.', 1), ('was', 1), ('birgst', 1),
('bang', 1), ('dein', 1), ('Gesicht?', 1), ('Siehst,', 1), ('Vater,', 1), ('nicht?', 1), ('Den', 1), ('Kron', 1),
('Schweif?', 1), ('es', 1), ('ein', 1), ('Nebelstreif.', 1), ('"Du', 1), ('liebes', 1), ('Kind,', 1), ('komm', 1),
('geh', 1), ('mir!', 1)]

Hier fallen die Satzzeichen auf, die problematisch werden können. Uns interessiert nicht
wirklich, wie viele Gedankenstriche vorkommen und Satzzeichen beim Wort oben wie im
Beispiel „Gesicht?“. Also beseitigen wir die Satzzeichen komplett:
© https://www.python-lernen.de/nltk-bibliothek-natural-language-toolkit.htm Seite 237

import nltk

inhalt = """Der Erlkönig


Wer reitet so spät durch Nacht und Wind?
Es ist der Vater mit seinem Kind;
Er hat den Knaben wohl in dem Arm,
er faßt ihn sicher, er hält ihn warm.
Mein Sohn, was birgst du so bang dein Gesicht?
Siehst, Vater, du den Erlkönig nicht?
Den Erlkönig mit Kron und Schweif? -
Mein Sohn, es ist ein Nebelstreif. -
"Du liebes Kind, komm geh mit mir!
"""

satzzeichen = (",", ";", ":", ".", "?", "!", '"', '-', '–')

for unerwuenschtes in satzzeichen:


inhalt = inhalt.replace(unerwuenschtes, "")

bereinigt = inhalt.split()
worthaeufigkeit = nltk.FreqDist(bereinigt)

print(worthaeufigkeit.most_common())

Jetzt bekommen wir die Auswertung der Worthäufigkeiten, die wir über die Angabe in der
Klammer auf eine gewünschte Ausgabeanzahl über
print(worthaeufigkeit.most_common(20)) einschränken können. Für die gesamte
Ballade die Häufigkeit der ersten 20 Begriffe:

[('Vater', 9), ('und', 7), ('mit', 6), ('Mein', 6), ('du', 6), ('Kind', 5), ('mein', 5), ('so', 4), ('den', 4), ('Sohn',
4), ('nicht', 4), ('mir', 4), ('Erlkönig', 3), ('Er', 3), ('hat', 3), ('er', 3), ('ich', 3), ('Meine', 3), ('Töchter', 3),
('dich', 3)]

Und über die weitere Anweisung print(worthaeufigkeit.plot(20)) erhalten wir die


grafische Auswertung:
© https://www.python-lernen.de/nltk-bibliothek-natural-language-toolkit.htm Seite 238

Grafische Auswertung von Worthäufigkeiten über NLTK (Natural Language Toolkit)

Dies hier als kleine Einführung in eine extrem umfangreiche Bibliothek. Viele Informationen
finden sich auf der Website https://www.nltk.org/ des Projekts.
© https://www.python-lernen.de/wordcloud-erstellen-python.htm Seite 239

Wordcloud mit Python erstellen


Eine „Wörterwolke“, besser bekannt unter dem englischen Wordcloud, zeigt
die Häufigkeit von dem Vorkommen von Wörtern in einem Text als Grafik.
Je häufiger ein Wort vorkommt, desto prominenter wird es dargestellt. Die
Anzeigegröße der einzelnen Wörter wird größer, je öfters es vorkommt. Die
dazugehörige Farbe ändert sich entsprechend.

Das selber programmieren einer Wordcloud ist zwar möglich aber


aufwendig. Daher sind fertige Module und Bibliotheken natürlich eine gute
Sache, besonders wenn eine solche in dem großen Umfang vorliegt wie bei
wordcloud . Mit diesem Modul wird ein Text ausgewertet und es können
zusätzlich Wörter ausgeschlossen werden. Wörter wie „der, die, das etc.“
kommen natürlich vielfach in einem Text vor und wären wenig spannend in
Groß dargestellt zu werden. Diese können gezielt ausgeschlossen werden.
Zusätzlich können Masken genutzt werden, dass die Wörter in Form eines
Bildes dann dargestellt werden.

Über die Bibliothek Wordcloud ist eine einfache Erstellung einer solchen
mit Python schnell erledigt.

Jetzt aber Schritt für Schritt zur Nutzung (und erst einmal die Installation).

Installation Modul Wordcloud


Als Erstes muss die Bibliothek installiert werden:

pip install wordcloud

Jetzt werden alle benötigten Module installiert, sofern diese im System nicht schon vorhanden
sind. Dazu gehört neben wordcloud zum Beispiel auch numpy und matplotlib :

Installation WordCloud

Nach der Installation können wir mit unserer ersten Wordcloud in Python starten.

erste Wordcloud in Python


Wir erstellen zum Einstieg eine sehr einfache Wörterwolke mit einem kurzen Text. Als Text
nehmen wir von der Startseite https://www.python-lernen.de/ die erste 3 Absätze.

Im ersten Schritt müssen wir in unser Python-Programm WordCloud importieren

from wordcloud import WordCloud

Zusätzlich benötigen wir für die Ausgabe das Modul matplot :


© https://www.python-lernen.de/wordcloud-erstellen-python.htm Seite 240

from wordcloud import WordCloud


import matplotlib.pyplot as plt

Jetzt kommt unser Text, den wir zu einer Wörterwolke umgebaut bekommen wollen:

from wordcloud import WordCloud


import matplotlib.pyplot as plt

text = 'Python Kurs: mit Python programmieren lernen für Anfänger und Fortgeschrittene Dieses Python Tutorial entsteht im Rah

Dieser wird als Variable übergeben:

from wordcloud import WordCloud


import matplotlib.pyplot as plt

text = 'Python Kurs: mit Python programmieren lernen für Anfänger und Fortgeschrittene Dieses Python Tutorial entsteht im Rah

# Generate a word cloud image


wordcloud = WordCloud().generate(text)

Und jetzt noch die Ausgabe über matplot :

from wordcloud import WordCloud


import matplotlib.pyplot as plt

text = 'Python Kurs: mit Python programmieren lernen für Anfänger und Fortgeschrittene Dieses Python Tutorial entsteht im Rah

# Generate a word cloud image


wordcloud = WordCloud().generate(text)

plt.imshow(wordcloud, interpolation="bilinear")
plt.show()

Als Ergebnis erhalten wir:

erste Wordcloud über 6 Zeilen Python-Code

Natürlich ist die Bemaßung hier wenig sinnvoll. Daher schalten wir diese ab über:

plt.imshow(wordcloud, interpolation="bilinear")
plt.axis("off")
plt.show()

Weißer Hintergrund für die Ausgabe


Wir können noch weitere Angaben dem Modul für die Ausgabe mitgeben. Dazu gehört die
Hintergrundfarbe:
© https://www.python-lernen.de/wordcloud-erstellen-python.htm Seite 241

wordcloud = WordCloud(background_color="white").generate(text)

plt.imshow(wordcloud, interpolation="bilinear")
plt.axis("off")
plt.show()

Die Farben der Schrift werden automatisch angepasst:

Wordcloud mit weißer Hintergrundfarbe

Wörter ausschließen aus Wordcloud


Viele Wörter sind in der Ausgabe wenig interessant. Am bisherigen Beispiel fallen die Wörter
„und, von, Der, das, den, wir, ist, die, auf, im“ auf. Diese wollen wir ausschließen. Dazu erstellen
wir eine Liste mit den unerwünschten Wörtern:

Unseren Import müssen wir mit den STOPWORDS ergänzen:

from wordcloud import WordCloud, STOPWORDS

Aus unserer Variablen „uninteressant“ mit den unwichtigen Wörtern erstellen wir über
split() eine Liste:

uninteressant = "und von Der das den wir ist die auf im"
liste_der_unerwuenschten_woerter = nichtinteressant.split()

Und die STOPWORDS werden vor dem Erzeugen der WordCloud geupdatet:

STOPWORDS.update(liste_der_unerwuenschten_woerter)
wordcloud = WordCloud(background_color="white").generate(text)

Das Ergebnis ist eine viel aussagekräftigere WordCloud:


© https://www.python-lernen.de/wordcloud-erstellen-python.htm Seite 242

WordCloud ohne bestimmte nichtssagenden Wörter

Der komplette Code bisher:

from wordcloud import WordCloud, STOPWORDS


import matplotlib.pyplot as plt

text = 'Python Kurs: mit Python programmieren lernen für Anfänger und Fortgeschrittene Dieses Python Tutorial entsteht im Rah

nichtinteressant = "und von Der das den wir ist die auf im"
liste_der_unerwuenschten_woerter = nichtinteressant.split()

STOPWORDS.update(liste_der_unerwuenschten_woerter)
wordcloud = WordCloud(background_color="white").generate(text)

plt.imshow(wordcloud, interpolation="bilinear")
plt.axis("off")
plt.show()

Es fällt noch eine gewisse Unschärfe unseres Bildes auf. Diese können wir durch die
Ausgabegröße ändern!

wordcloud = WordCloud(background_color="white",width=1920, height=1080).generate(text)

Jetzt wird das Ausgabebild eine Breite von 1920 Pixel haben und eine Höhe von 1080 und
somit scharf dargestellt:

Text aus Datei für WordCloud


Bisher haben wir relativ kurze Texte genutzt. Bei längeren Texten ist es sinnvoll, diese aus
einer Datei einfach zu laden.

Dazu müssen wir das Modul „os“ importieren:

import os

Und nun können wir die Datei laden und den enthaltenen Text in der Variablen text
speichern.

d = os.path.dirname(__file__) if "__file__" in locals() else os.getcwd()

with open("wordcloud-beispieltext.txt") as f:
text = f.read()

Hier ist es egal, ob wir einen kurzen oder langen Text nutzen wie beispielsweise „Faust“ von
Goehte ( https://de.wikisource.org/wiki/Faust_-_Der_Trag%C3%B6die_erster_Teil ) mit
lockeren 8300 Zeilen.

Wir erhalten innerhalb von ein paar Sekunden dann folgende Ausgabe:
© https://www.python-lernen.de/wordcloud-erstellen-python.htm Seite 243

Wordcloud zu Goethes Faust

Folgende der komplette Python-Code:

from wordcloud import WordCloud, STOPWORDS


import matplotlib.pyplot as plt
import os

d = os.path.dirname(__file__) if "__file__" in locals() else os.getcwd()

with open("wordcloud-beispieltext.txt") as f:
text = f.read()

nichtinteressant = "und von Der das den wir ist die auf im"
liste_der_unerwuenschten_woerter = nichtinteressant.split()

STOPWORDS.update(liste_der_unerwuenschten_woerter)
wordcloud = WordCloud(background_color="white",width=1920, height=1080).generate(text)

plt.imshow(wordcloud, interpolation="bilinear")
plt.axis("off")
plt.show()

Parameter für WordCloud


Über folgende Parameter können gewünschte Einstellungen getätigt werden. Dazu werden
diese wie in den bisherigen Beispielen gezeigt dem Aufruf
WordCloud(PARAMETER).generate(text) übergeben. Werden mehrere Parameter
übergeben, erfolgt die Trennung anhand von Kommas.

max_font_size=40
Maximale Schriftgröße

max_words=500
Maximale Anzahl der angezeigten Wörter

Viele weitere Parameter gibt es auf der Seite des Entwicklers unter:
https://amueller.github.io/word_cloud/

Ausgabe in Formen von WordCloud


Der Einsatz von Masken ermöglicht die Ausgabe der Wordcloud in beliebiger Art und Weise.
Wir kommen so weg von der rechteckigen Anzeige hin zu Kreisen, Ellipsen oder einfach als
Füllung von Figuren.

Starten wir mit einem Kreis:

Dazu erstellen wir eine Maske, die wir dem Aufruf mitgeben.
© https://www.python-lernen.de/wordcloud-erstellen-python.htm Seite 244

Für das Beispiel benötigen wir das Modul numpy :

import numpy as np

Und folgende Angaben führen zu einem Kreis:

x, y = np.ogrid[:1000, :1000]

mask = (x - 500) ** 2 + (y - 500) ** 2 > 400 ** 2


mask = 255 * mask.astype(int)

wordcloud = WordCloud(background_color="white",width=1920, height=1080, mask=mask).generate(text)

Ausgabe einer WordCloud in Form eines Kreises


© https://www.python-lernen.de/tic-tac-toe-python-tutorial.htm Seite 245

Tic-Tac-Toe (Drei gewinnt) in Python programmieren


In diesem Tutorial lernen wir spielend Python programmieren. Schritt für Schritt
programmieren wird das Spiel Tic-Tac-Toe, was im deutschen auch unter „Drei gewinnt“
bekannt ist.

Das Zweipersonen-Spiel wird auf einem Spielfeld mit 3x3 Feldern gespielt. Wer es nicht kennt.
Abwechselnd setzt jeder Spieler seine Marke (X und O) in ein freies Feld. Wer als erstes 3
Felder belegt, die in einer Reihe oder Spalte oder in der Diagonale liegen, gewinnt.

Tic-Tac-Toe mit Computergegner

Hier lernt man, wie man ein Spiel in Python programmiert und die Spiellogik integriert.

Dazu wird der Ablauf in mehrere Teile aufgeteilt um das Lernen zu vereinfachen. Durch
folgende Schritte bauen wir das Spiel auf.

Spielfeld erstellen und ausgeben

Spielzug erfassen vom Spieler

Eingabekontrolle Spielzug: möglich auf gewähltes Felder

Hauptroutine des Spiels festlegen

Spiel vorzeitig beenden

Spielfigur setzen

Spielende durch Gewinnen oder Unentschieden

Python-Datei erstellen
Als erstes erstellen wir eine Datei mit dem Dateinamen „tic-tac-toe.py“ und lassen die
Spielnamen ausgeben:

# Spiel Tic-Tac-Toe
print("Tic-Tac-Toe Python Tutorial")
© https://www.python-lernen.de/tic-tac-toe-spielfeld.htm Seite 246

Spielfeld als Liste erstellen


Für unser Spiel Tic-Tac-Toe benötigen als erstes ein 3x3 großes Spielfeld. Dazu bietet sich die
Liste in Python an ( listen.htm).

spielfeld = [" ",


"1","2","3",
"4","5","6",
"7","8","9"]

Listen fangen immer mit dem Index 0 an der in Python auch erstellt werden muss. Die Position
0 ist für uns im folgenden Verlauf eher irritierend, daher erstellen wir zwar eine Position 0, die
wir aber im folgenden Spielverlauf nicht nutzen! Diese Liste wird mit den Werten gefüllt, die der
Spieler später als Position für das Belegen mit seiner Spielfigur auswählen kann. Diese Zahlen
werden ausgegeben. So ist bei der Ausgabe sichtbar, welche Zahl gedrückt werden muss, um
das entsprechende Feld zu wählen.

Ausgabe Spielfeld
Wir lassen uns das Spielfeld ausgeben über print() :

# Spielfeld ausgeben
print (spielfeld[1] + "|" + spielfeld[2] + "|" + spielfeld[3] )
print (spielfeld[4] + "|" + spielfeld[5] + "|" + spielfeld[6] )
print (spielfeld[7] + "|" + spielfeld[8] + "|" + spielfeld[9] )

Da im Spiel das Spielfeld nach jedem Zug eines Spielers wieder neu ausgegeben werden muss,
packen wir dies in eine Funktion (siehe funktionen-in-python.htm ) und rufen diese dann für die
Ausgabe auf.

# Spielfeld ausgeben
def spielfeld_ausgeben():
print (spielfeld[1] + "|" + spielfeld[2] + "|" + spielfeld[3] )
print (spielfeld[4] + "|" + spielfeld[5] + "|" + spielfeld[6] )
print (spielfeld[7] + "|" + spielfeld[8] + "|" + spielfeld[9] )
spielfeld_ausgeben()

Das Spielfeld wird nach jedem Zug eines Spielers wieder neu in der Console ausgegeben. Das
mag im ersten Augenblick ungewohnt erscheinen, ist aber bisher unsere einzige Möglichkeit.
In einem späteren Kapitel lernen wir Möglichkeiten kennen, einen Spielzug auf ein bestehendes
Spielbrett zu „zeichnen“. Die bisherige Vorgehensweise ist Ok, da wir ein Spiel programmieren
möchten mit den bisher bekannten Python-Befehlen.
© https://www.python-lernen.de/tic-tac-toe-spielzug-erfassen.htm Seite 247

Spielzug erfassen vom Spieler


Der Spieler kann nun anhand der Zahleneingabe 1-9 sein gewünschtes Feld auswählen. Dazu
wird der Python-Befehl input() genutzt ( input-nutzereingaben.htm ):

spielzug = input("Bitte Feld eingeben: ")


print (spielzug)

Wichtig zu berücksichtigen ist, dass wir durch input() ein String zurückgeliefert bekommen.
Lassen wir diesen zum Testen uns ausgeben:

spielzug = input("Bitte Feld eingeben: ")


print (spielzug)
print (type(spielzug))

Das ist in diesem Fall wenig hilfreich. Daher wandeln wir diese Eingabe in eine Ganzzahl um.
Python stellt uns für das Umwandeln (Englisch „casting“) entsprechende Anweisungen zur
Verfügung:

spielzug = input("Bitte Feld eingeben: ")


spielzug = int(spielzug)
print (type(spielzug))

Jetzt sollten wir noch sicher gehen, dass eine Zahleneingabe erfolgt, die auch ein Feld
repräsentiert – also irgendwas zwischen 1 und 9. Ansonsten muss eine Meldung erscheinen
und eine weitere Spielereingabe angefordert werden. Hier sperren wir unser Input in eine
while -Schleife ( while-schleife.htm ). Solange dieses nicht entsprechend erfüllt ist, kommt
immer wieder die Benutzerangabe.

Wir erstellen uns eine eigene Funktion für die Benutzereingabe. In dieser wird die Eingabe
kontrolliert und nur mögliche Züge (Eingaben) werden zugelassen.

def spieler_eingabe():
# Eingabe durch Spieler und Überprüfung

Wir wollen so lange vom Spieler eine Eingabe, solange diese nicht korrekt ist. Daher packen wir
diese Aktion in eine unendliche Schleife:

def spieler_eingabe():
while True:
spielzug = input("Bitte Feld eingeben: ")

Um sicherzustellen, dass die richtige Eingabe reinkommt, kontrollieren wir im ersten Schritt
durch eine except , ob es sich um einen nummerischen Wert handelt:

def spieler_eingabe():
while True:
spielzug = input("Bitte Feld eingeben: ")
try:
spielzug = int(spielzug)
except ValueError:
print("Bitte Zahl von 1 bis 9 eingeben")
else:
return spielzug

Im zweiten Schritt kontrollieren wir, ob es sich um eine Zahl zwischen 1 und 9 handelt:
© https://www.python-lernen.de/tic-tac-toe-spielzug-erfassen.htm Seite 248

def spieler_eingabe():
while True:
spielzug = input("Bitte Feld eingeben: ")
try:
spielzug = int(spielzug)
except ValueError:
print("Bitte Zahl von 1 bis 9 eingeben")
else:
if spielzug >= 1 and spielzug <= 9:
return spielzug
else:
print("Zahl muss zwischen 1 und 9 liegen")

Ist alles korrekt, wird die Zahl zurückgeliefert über return

Unser bisheriger Python-Code:

# Spiel Tic-Tac-Toe
print("Tic-Tac-Toe Python Tutorial")

# Spielfeld als Liste erstellen


spielfeld = [" ",
"1","2","3",
"4","5","6",
"7","8","9"]

# Spielfeld ausgeben
def spielfeld_ausgeben():
print (spielfeld[1] + "|" + spielfeld[2] + "|" + spielfeld[3] )
print (spielfeld[4] + "|" + spielfeld[5] + "|" + spielfeld[6] )
print (spielfeld[7] + "|" + spielfeld[8] + "|" + spielfeld[9] )

spielfeld_ausgeben()

# Spielereingabe und Kontrolle der Eingabe


def spieler_eingabe():
while True:
spielzug = input("Bitte Feld eingeben: ")
try:
spielzug = int(spielzug)
except ValueError:
print("Bitte Zahl von 1 bis 9 eingeben")
else:
if spielzug >= 1 and spielzug <= 9:
return spielzug
else:
print("Zahl muss zwischen 1 und 9 liegen")
spielzug = spieler_eingabe()
print("Spielzug: " + str(spielzug))
© https://www.python-lernen.de/tic-tac-toe-hauptroutine.htm Seite 249

Bisher läuft unser Spiel genau eine Runde. Das ist nicht wirklich ein amüsantes Spiel – und das
Wort kurzweilig trifft es auch nicht wirklich. Wir wollen, dass unser Spiel so lange läuft, bis
entweder ein Spieler gewonnen hat, es unentschieden steht oder das Spiel vorzeitig durch
Spieler bewusst beendet wurde.

Bevor wir in unser Spiel eine Schleife einbauen, damit es nicht nach 1 Runde bereits
automatisch beendet wird, bauen wir als Erstes die Möglichkeit ein, dass ein Spieler gezielt
selber das Spiel beenden kann. Diese Funktion benötigen wir auf jeden Fall - und sobald unser
Spiel unendlich lang läuft, ist man froh über die Abbruchmöglichkeit

Spiel beenden über q


Wir wollen die Möglichkeit schaffen, dass der Spieler das Spiel vorzeitig durch die Taste q

beenden kann. Gibt der Spieler also anstelle einer Zahl von 1 bis 9 den Buchstaben „q“ ein, soll
das Spiel beendet werden. Dazu erweitern wir die Funktion spieler_eingabe() um eine
entsprechende if -Abfrage.

# Spieleingabe und Kontrolle der Eingabe


def spieler_eingabe():
while True:
spielzug = input("Bitte Feld eingeben: ")
# vorzeitiges Spielende durch Spieler
if spielzug == 'q':
return
try:
spielzug = int(spielzug)
except ValueError:
print("Bitte Zahl von 1 bis 9 eingeben")
else:
if spielzug >= 1 and spielzug <= 9:
return spielzug
else:
print("Zahl muss zwischen 1 und 9 liegen")

Allerdings passt da nicht viel, da unser Spiel bisher sowieso nach einer Eingabe beendet wird.
Wir benötigen also eine Schleife, die entweder am Spielende oder durch den Spieler beendet
wird.

Hauptroutine notwendig
Diese Schleife ist eigentlich das Hauptprogramm und umfasst später alle Aktion wie

Spielfeld ausgeben

Spielereingabe aktivieren

Kontrolle, ob eine Partei die Partie gewonnen hat

Kontrolle, ob ein Unentschieden vorliegt

Wechsel des aktuellen Spielers

Kontrolle, ob das Spiel vorzeitig beendet werden soll

Unsere bisherigen 2 Funktionsaufrufe für „Spielfeld zeichnen“ und „Spielerzug abfragen“


packen wir in diese Schleife:
© https://www.python-lernen.de/tic-tac-toe-hauptroutine.htm Seite 250

while spiel_aktiv:
# aktuelles Spielfeld ausgeben
spielfeld_ausgeben()
# Eingabe des aktiven Spielers
spielzug = spieler_eingabe()
print("Spielzug: " + str(spielzug))

Das Spiel läuft so lange, solange die Variable spiel_aktiv den Wert True enthält.

Starten wir das Spiel nun, erhalten wir eine Fehlermeldung mit der Ausgabe „NameError: name
spiel_aktiv“ ist nicht definiert.

Für den guten Stil aktivieren wir alle benötigen Variablen am Anfang von unserem Programm
als ersten Schritt:

# Spiel Tic-Tac-Toe
print("Tic-Tac-Toe Python Tutorial")

spiel_aktiv = True

Und die am Anfang gesetzte Variable spiel_aktiv setzen wir auf False , wenn der Spieler
das Spiel vorzeitig durch q beendet. Wichtig ist, dass wir am Anfang der Funktion die
verwendete Variable spiel_aktiv auf global setzen.

# Spielereingabe und Kontrolle der Eingabe


def spieler_eingabe():
global spiel_aktiv
while True:
spielzug = input("Bitte Feld eingeben: ")
# vorzeitiges Spielende durch Spieler
if spielzug == 'q':
spiel_aktiv = False
return
© https://www.python-lernen.de/tic-tac-toe-spielfigur-setzen.htm Seite 251

Spielfigur setzen - Spielfeld mit X oder O kennzeichnen


Über unser bisheriges Programm bekommen wir nun in einer Variablen das gewünschte Feld.
In dieses können wir nun „X“ oder „O“ für die Spielfigur des jeweiligen Spielers eintragen.
Danach müssen wir wieder das Spielfeld ausgeben:

while spiel_aktiv:
# Eingabe des aktiven Spielers
spielzug = spieler_eingabe()
if spielzug:
spielfeld[spielzug] = 'X'
# aktuelles Spielfeld ausgeben
spielfeld_ausgeben()

Allerdings haben wir noch gar keinen zweiten Spieler bzw. den Wechsel von Spieler X zu
Spieler O.

Also brauchen wir ganz am Anfang wieder eine Variable für den aktuellen Spieler
spieler_aktuell . Diesen lassen wir auch vor der Eingabe durch den Spieler am Bildschirm
ausgeben:

# Spiel Tic-Tac-Toe
print("Tic-Tac-Toe Python Tutorial")
spiel_aktiv = True
spieler_aktuell = 'X'

Und in unserer Hauptroutine:

while spiel_aktiv:
# Eingabe des aktiven Spielers
print ("Spieler " + spieler_aktuell + " am Zug")
spielzug = spieler_eingabe()
if spielzug:
spielfeld[spielzug] = spieler_aktuell
# aktuelles Spielfeld ausgeben
spielfeld_ausgeben()

automatischer Spielerwechsel
Jetzt benötigen wir einen automatischen Wechsel des Spielers nach jedem Spielzug. Dazu
erstellen wir eine Funktion mit dem Namen spieler_wechseln() . Dabei darf man nicht
vergessen, die Variable spieler_aktuell auf global zu setzen.

def spieler_wechseln():
global spieler_aktuell
if spieler_aktuell == 'X':
spieler_aktuell = 'O'
else:
spieler_aktuell = 'X'

Diese Funktion rufen wir nach der Ausgabe von Spielfeld in unserer Hauptschleife auf:
© https://www.python-lernen.de/tic-tac-toe-spielfigur-setzen.htm Seite 252

while spiel_aktiv:
# Eingabe des aktiven Spielers
print ("Spieler " + spieler_aktuell + " am Zug")
spielzug = spieler_eingabe()
if spielzug:
# spielfeld[spielzug] = 'X'
spielfeld[spielzug] = spieler_aktuell
# aktuelles Spielfeld ausgeben
spielfeld_ausgeben()
# Spieler wechseln
spieler_wechseln()

Hier der bisherige komplett Code:

# Spiel Tic-Tac-Toe
print("Tic-Tac-Toe Python Tutorial")

spiel_aktiv = True
spieler_aktuell = 'X'

# Spielfeld als Liste erstellen


spielfeld = [" ",
"1","2","3",
"4","5","6",
"7","8","9"]

# Spielfeld ausgeben
def spielfeld_ausgeben():
print (spielfeld[1] + "|" + spielfeld[2] + "|" + spielfeld[3] )
print (spielfeld[4] + "|" + spielfeld[5] + "|" + spielfeld[6] )
print (spielfeld[7] + "|" + spielfeld[8] + "|" + spielfeld[9] )

# Spielereingabe und Kontrolle der Eingabe


def spieler_eingabe():
global spiel_aktiv
while True:
spielzug = input("Bitte Feld eingeben: ")
# vorzeitiges Spielende durch Spieler
if spielzug == 'q':
spiel_aktiv = False
return
try:
spielzug = int(spielzug)
except ValueError:
print("Bitte Zahl von 1 bis 9 eingeben")
else:
if spielzug >= 1 and spielzug <= 9:
return spielzug
else:
print("Zahl muss zwischen 1 und 9 liegen")

def spieler_wechseln():
global spieler_aktuell
if spieler_aktuell == 'X':
© https://www.python-lernen.de/tic-tac-toe-spielfigur-setzen.htm Seite 253

if spieler_aktuell == 'X':
spieler_aktuell = 'O'
else:
spieler_aktuell = 'X'

# aktuelles Spielfeld ausgeben


spielfeld_ausgeben()
while spiel_aktiv:
# Eingabe des aktiven Spielers
print ("Spieler " + spieler_aktuell + " am Zug")
spielzug = spieler_eingabe()
if spielzug:
# spielfeld[spielzug] = 'X'
spielfeld[spielzug] = spieler_aktuell
# aktuelles Spielfeld ausgeben
spielfeld_ausgeben()
# Spieler wechseln
spieler_wechseln()
© https://www.python-lernen.de/tic-tac-toe-kontrolle-gewonnen.htm Seite 254

Spielende: Kontrolle auf Gewonnen


Das Spiel hat der Spieler gewonnen, der entweder 3 Spalten oder 3 Reihen komplett hat.

Dies wird nun kontrolliert. Dazu müssen einfach in den entsprechenden 3 Feldern der gleiche
Inhalt vorliegen (sprich entweder dreimal X oder dreimal O). Dazu erstellen wir die Funktion
kontrolle_gewonnen() .

In dieser Funktion werden der Reihe nach die:

3 Reihen von oben nach unten

3 Spalten von links nach rechts

und die 2 Diagonalen kontrolliert

# Kontrolle, ob ein Spieler gewonnen hat


def kontrolle_gewonnen():
# wenn alle 3 Felder gleich sind, hat der entsprechende Spieler gewonnen
# Kontrolle auf Reihen
if spielfeld[1] == spielfeld[2] == spielfeld[3]:
return spielfeld[1]
if spielfeld[4] == spielfeld[5] == spielfeld[6]:
return spielfeld[4]
if spielfeld[7] == spielfeld[8] == spielfeld[9]:
return spielfeld[7]
# Kontrolle auf Spalten
if spielfeld[1] == spielfeld[4] == spielfeld[7]:
return spielfeld[1]
if spielfeld[2] == spielfeld[5] == spielfeld[8]:
return spielfeld[2]
if spielfeld[3] == spielfeld[6] == spielfeld[9]:
return spielfeld[3]
# Kontrolle auf Diagonalen
if spielfeld[1] == spielfeld[5] == spielfeld[9]:
return spielfeld[5]
if spielfeld[7] == spielfeld[5] == spielfeld[3]:
return spielfeld[5]

Und in der Hauptschleife integrieren:


© https://www.python-lernen.de/tic-tac-toe-kontrolle-gewonnen.htm Seite 255

while spiel_aktiv:
# Eingabe des aktiven Spielers
print ("Spieler " + spieler_aktuell + " am Zug")
spielzug = spieler_eingabe()
if spielzug:
# spielfeld[spielzug] = 'X'
spielfeld[spielzug] = spieler_aktuell
# aktuelles Spielfeld ausgeben
spielfeld_ausgeben()
# Kontrolle, ob jemand gewonnen hat
gewonnen = kontrolle_gewonnen()
if gewonnen:
print ("Spieler " + gewonnen + " hat gewonnen!")
spiel_aktiv = False
# Spieler wechseln
spieler_wechseln()

Kontrolle auf Unentschieden


Es fehlt nun noch die Kontrolle, ob es ein Unentschieden gegeben hat. Das liegt dann vor, wenn
keine Züge mehr möglich sind. Dazu basteln wir eine neue Funktion und kontrollieren
entsprechend die Felder:

# Kontrolle, ob unentschieden
unentschieden = kontrolle_auf_unentschieden()
if unentschieden:
print ("Spiel ist unentschieden ausgegangen")
spiel_aktiv = False

Und die Kontrolle selber:

def kontrolle_auf_unentschieden():
if (spielfeld[1] == 'X' or spielfeld[1] == 'O') \
and (spielfeld[2] == 'X' or spielfeld[2] == 'O') \
and (spielfeld[3] == 'X' or spielfeld[3] == 'O') \
and (spielfeld[4] == 'X' or spielfeld[4] == 'O') \
and (spielfeld[5] == 'X' or spielfeld[5] == 'O') \
and (spielfeld[6] == 'X' or spielfeld[6] == 'O') \
and (spielfeld[7] == 'X' or spielfeld[7] == 'O') \
and (spielfeld[8] == 'X' or spielfeld[8] == 'O') \
and (spielfeld[9] == 'X' or spielfeld[9] == 'O'):
return ('unentschieden')

bisherige komplette Code


Der komplette Code bisher:

# Spiel Tic-Tac-Toe
print("Tic-Tac-Toe Python Tutorial")
spiel_aktiv = True
spieler_aktuell = 'X'
# Spielfeld als Liste erstellen
spielfeld = [" ",
"1","2","3",
© https://www.python-lernen.de/tic-tac-toe-kontrolle-gewonnen.htm Seite 256

"1","2","3",
"4","5","6",
"7","8","9"]
# Spielfeld ausgeben
def spielfeld_ausgeben():
print (spielfeld[1] + "|" + spielfeld[2] + "|" + spielfeld[3] )
print (spielfeld[4] + "|" + spielfeld[5] + "|" + spielfeld[6] )
print (spielfeld[7] + "|" + spielfeld[8] + "|" + spielfeld[9] )

# Spieleingabe und Kontrolle der Eingabe


def spieler_eingabe():
global spiel_aktiv
while True:
spielzug = input("Bitte Feld eingeben: ")
# vorzeitiges Spielende durch Spieler
if spielzug == 'q':
spiel_aktiv = False
return
try:
spielzug = int(spielzug)
except ValueError:
print("Bitte Zahl von 1 bis 9 eingeben")
else:
if spielzug >= 1 and spielzug <= 9:
return spielzug
else:
print("Zahl muss zwischen 1 und 9 liegen")

def spieler_wechseln():
global spieler_aktuell
if spieler_aktuell == 'X':
spieler_aktuell = 'O'
else:
spieler_aktuell = 'X'

# Kontrolle, ob ein Spieler gewonnen hat


def kontrolle_gewonnen():
# wenn alle 3 Felder gleich sind, hat der entsprechende Spieler gewonnen
# Kontrolle auf Reihen
if spielfeld[1] == spielfeld[2] == spielfeld[3]:
return spielfeld[1]
if spielfeld[4] == spielfeld[5] == spielfeld[6]:
return spielfeld[4]
if spielfeld[7] == spielfeld[8] == spielfeld[9]:
return spielfeld[7]
# Kontrolle auf Spalten
if spielfeld[1] == spielfeld[4] == spielfeld[7]:
return spielfeld[1]
if spielfeld[2] == spielfeld[5] == spielfeld[8]:
return spielfeld[2]
if spielfeld[3] == spielfeld[6] == spielfeld[9]:
return spielfeld[3]
# Kontrolle auf Diagonalen
© https://www.python-lernen.de/tic-tac-toe-kontrolle-gewonnen.htm Seite 257

# Kontrolle auf Diagonalen


if spielfeld[1] == spielfeld[5] == spielfeld[9]:
return spielfeld[5]
if spielfeld[7] == spielfeld[5] == spielfeld[3]:
return spielfeld[5]

def kontrolle_auf_unentschieden():
if (spielfeld[1] == 'X' or spielfeld[1] == 'O') \
and (spielfeld[2] == 'X' or spielfeld[2] == 'O') \
and (spielfeld[3] == 'X' or spielfeld[3] == 'O') \
and (spielfeld[4] == 'X' or spielfeld[4] == 'O') \
and (spielfeld[5] == 'X' or spielfeld[5] == 'O') \
and (spielfeld[6] == 'X' or spielfeld[6] == 'O') \
and (spielfeld[7] == 'X' or spielfeld[7] == 'O') \
and (spielfeld[8] == 'X' or spielfeld[8] == 'O') \
and (spielfeld[9] == 'X' or spielfeld[9] == 'O'):
return ('unentschieden')

# aktuelles Spielfeld ausgeben


spielfeld_ausgeben()
while spiel_aktiv:
# Eingabe des aktiven Spielers
print()
print ("Spieler " + spieler_aktuell + " am Zug")
spielzug = spieler_eingabe()
if spielzug:
# spielfeld[spielzug] = 'X'
spielfeld[spielzug] = spieler_aktuell
# aktuelles Spielfeld ausgeben
spielfeld_ausgeben()
# Kontrolle, ob jemand gewonnen hat
gewonnen = kontrolle_gewonnen()
if gewonnen:
print ("Spieler " + gewonnen + " hat gewonnen!")
spiel_aktiv = False
break
# Kontrolle, ob unentschieden
unentschieden = kontrolle_auf_unentschieden()
if unentschieden:
print ("Spiel ist unentschieden ausgegangen")
spiel_aktiv = False
# Spieler wechseln
spieler_wechseln()
print()
© https://www.python-lernen.de/tic-tac-toe-kontrolle-spielzug.htm Seite 258

Eingabekontrolle Spielzug: möglich auf gewähltes Felder


Bisher können wir in bereits belegte Felder noch einmal einen Eintrag machen. Das ergibt
natürlich keinen Sinn. Also wollen wir hier noch diesen „Fehler“ abfangen.

Dazu erweitern wir unsere Exception entsprechend und überprüfen das vom Spieler
gewünschte Feld, ob sich dort bereits ein Eintrag befindet. Dies erfolgt über eine if -Abfrage
in der Form:

# Spielereingabe und Kontrolle der Eingabe


if spielfeld[spielzug] == 'X' or spielfeld[spielzug] == 'O':
print("Das Feld ist bereits belegt - ein anderes wählen!")
else:
return spielzug

Im Python-Code integriert:

# Spielereingabe und Kontrolle der Eingabe


def spieler_eingabe():
global spiel_aktiv
while True:
spielzug = input("Bitte Feld eingeben: ")
# vorzeitiges Spielende durch Spieler
if spielzug == 'q':
spiel_aktiv = False
return
try:
spielzug = int(spielzug)
except ValueError:
print("Bitte Zahl von 1 bis 9 eingeben")
else:
if spielzug >= 1 and spielzug <= 9:
if spielfeld[spielzug] == 'X' or spielfeld[spielzug] == 'O':
print("Das Feld ist bereits belegt - ein anderes wählen!")
else:
return spielzug
else:
print("Zahl muss zwischen 1 und 9 liegen")

Und der komplette Code:

# Spiel Tic-Tac-Toe
print("Tic-Tac-Toe Python Tutorial")
spiel_aktiv = True
spieler_aktuell = 'X'
© https://www.python-lernen.de/tic-tac-toe-kontrolle-spielzug.htm Seite 259

spieler_aktuell = 'X'
# Spielfeld als Liste erstellen
spielfeld = [" ",
"1","2","3",
"4","5","6",
"7","8","9"]
# Spielfeld ausgeben
def spielfeld_ausgeben():
print (spielfeld[1] + "|" + spielfeld[2] + "|" + spielfeld[3] )
print (spielfeld[4] + "|" + spielfeld[5] + "|" + spielfeld[6] )
print (spielfeld[7] + "|" + spielfeld[8] + "|" + spielfeld[9] )
# Spieleingabe und Kontrolle der Eingabe
def spieler_eingabe():
global spiel_aktiv
while True:
spielzug = input("Bitte Feld eingeben: ")
# vorzeitiges Spielende durch Spieler
if spielzug == 'q':
spiel_aktiv = False
return
try:
spielzug = int(spielzug)
except ValueError:
print("Bitte Zahl von 1 bis 9 eingeben")
else:
if spielzug >= 1 and spielzug <= 9:
if spielfeld[spielzug] == 'X' or spielfeld[spielzug] == 'O':
print("Das Feld ist bereits belegt - ein anderes wählen!")
else:
return spielzug
else:
print("Zahl muss zwischen 1 und 9 liegen")
def spieler_wechseln():
global spieler_aktuell
if spieler_aktuell == 'X':
spieler_aktuell = 'O'
else:
spieler_aktuell = 'X'
# Kontrolle, ob ein Spieler gewonnen hat
def kontrolle_gewonnen():
# wenn alle 3 Felder gleich sind, hat der entsprechende Spieler gewonnen
# Kontrolle auf Reihen
if spielfeld[1] == spielfeld[2] == spielfeld[3]:
return spielfeld[1]
if spielfeld[4] == spielfeld[5] == spielfeld[6]:
return spielfeld[4]
if spielfeld[7] == spielfeld[8] == spielfeld[9]:
return spielfeld[7]
# Kontrolle auf Spalten
if spielfeld[1] == spielfeld[4] == spielfeld[7]:
return spielfeld[1]
if spielfeld[2] == spielfeld[5] == spielfeld[8]:
return spielfeld[2]
if spielfeld[3] == spielfeld[6] == spielfeld[9]:
© https://www.python-lernen.de/tic-tac-toe-kontrolle-spielzug.htm Seite 260

if spielfeld[3] == spielfeld[6] == spielfeld[9]:


return spielfeld[3]
# Kontrolle auf Diagonalen
if spielfeld[1] == spielfeld[5] == spielfeld[9]:
return spielfeld[5]
if spielfeld[7] == spielfeld[5] == spielfeld[3]:
return spielfeld[5]

def kontrolle_auf_unentschieden():
if (spielfeld[1] == 'X' or spielfeld[1] == 'O') \
and (spielfeld[2] == 'X' or spielfeld[2] == 'O') \
and (spielfeld[3] == 'X' or spielfeld[3] == 'O') \
and (spielfeld[4] == 'X' or spielfeld[4] == 'O') \
and (spielfeld[5] == 'X' or spielfeld[5] == 'O') \
and (spielfeld[6] == 'X' or spielfeld[6] == 'O') \
and (spielfeld[7] == 'X' or spielfeld[7] == 'O') \
and (spielfeld[8] == 'X' or spielfeld[8] == 'O') \
and (spielfeld[9] == 'X' or spielfeld[9] == 'O'):
return ('unentschieden')

# aktuelles Spielfeld ausgeben


spielfeld_ausgeben()
while spiel_aktiv:
# Eingabe des aktiven Spielers
print()
print ("Spieler " + spieler_aktuell + " am Zug")
spielzug = spieler_eingabe()
if spielzug:
# spielfeld[spielzug] = 'X'
spielfeld[spielzug] = spieler_aktuell
# aktuelles Spielfeld ausgeben
spielfeld_ausgeben()
# Kontrolle, ob jemand gewonnen hat
gewonnen = kontrolle_gewonnen()
if gewonnen:
print ("Spieler " + gewonnen + " hat gewonnen!")
spiel_aktiv = False
break
# Kontrolle, ob unentschieden
unentschieden = kontrolle_auf_unentschieden()
if unentschieden:
print ("Spiel ist unentschieden ausgegangen")
spiel_aktiv = False
# Spieler wechseln
spieler_wechseln()
print()
© https://www.python-lernen.de/tic-tac-toe-ki.htm Seite 261

Dumme Künstliche Intelligenz (KI) erstellen


Wir erstellen für unser Tic-Tac-Toe nun als zweiten Spieler einen Computergegner. Allerdings
machen wir dessen Zug rein zufällig. Das bedeutet, es ist eine extrem dumme KI – eigentlich
dürfte man nicht einmal von Intelligenz sprechen (aber der Begriff KD für „Künstlicher
Dummkopf“ gibt es leider nicht, auch nicht im Englischen als „AF = Artificial Fool“). Da ist also
noch viel Luft nach oben.

Im Tutorial soll einfach gezeigt werden, wo man eingreifen muss, um den zweiten Spieler
durch eine KI (bzw. KD) ersetzen zu lassen:

while spiel_aktiv:
# Eingabe des aktiven Spielers
print()
print ("Spieler " + spieler_aktuell + " am Zug")

# aus der Liste spielfeld alle X und O und leere Felder entfernen
spielfeld_KI = []
for moegliche_felder in spielfeld:
if moegliche_felder != 'X' and moegliche_felder != 'O' and moegliche_felder
spielfeld_KI += moegliche_felder
# print (spielfeld_KI)
# print()
# print(random.choice(spielfeld_KI))

# wenn Computergegner am Zug ist, ein freies zufälliges Feld belegen


if spieler_aktuell == 'O':
spielzug = int(random.choice(spielfeld_KI))
else:
spielzug = spieler_eingabe()
© https://www.python-lernen.de/python-turtle.htm Seite 262

Turtle-Modul von Python


Anfangs wurde die Sprache Turtle zum Lernen einer Computersprache für Kinder entwickelt.
Eine Schildkröte (Turtle) kann über den Bildschirm bewegt werden. Dabei hinterlässt die Turtle
auf ihrer Bewegungsbahn eine Linie. So können Grafiken erstellt werden.

mit Turtle erstellte Grafik

In Python ist ein Turtle-Modul integriert, dass man nach dem Import nutzen kann. Hier eine
kleine Einführung und danach setzen wir das Modul zum Zeichnen einer Benutzeroberfläche
für ein Spiel ein.

Im ersten Schritt müssen wir das Modul in Python importieren:

import turtle

Bewegen der Schildkröte (turtle) – forward / backward


Jetzt können wir die Turtle bewegen, beispielsweise 200 Pixel vorwärts.

import turtle
turtle.forward(200)

Unsere Turtle wird exakt mittig auf dem Ausgabebildschirm platziert. Dort sind die X und Y
Koordinaten von 0.

Die Schildkröte schaut nach rechts und mit der Anweisung vorwärts ( turtle.forward )
bewegt sich um die angegebene Pixelanzahl nach rechts.

unsere Turtle (Schildkröte) wird genau mittig platziert und bewegt sich um 200 Pixel

Was sich vorwärts bewegen kann, kann sich auch rückwärts bewegen. Das funktioniert mit der
Anweisung turtle.backward
© https://www.python-lernen.de/python-turtle.htm Seite 263

Schildkröte drehen – right / left


Unsere Turtle können wir drehen. Dazu gibt es für die jeweiligen Richtungen die Anweisung:

turtle.right(90)
turtle.left(120)

Stiftfarbe ändern - color


Die Stiftfarbe wird anhand folgender Anweisung festgelegt:

turtle.color('yellow')

Strichstärke ändern - width


Die Strichstärke wird anhand folgender Anweisung festgelegt:

turtle.width(10)

Hintergrundfarbe vom Turtle-Fenster festlegen - bgcolor


Die Hintergrundfarbe vom Turtle-Fenster wird über die folgende Anweisung festgelegt:

turtle.bgcolor('black')

gezeichnetes Element füllen - begin_fill() / end_fill()


Über die zwei Anweisungen turtle.begin_fill() und am Ende die Anweisung
turtle.end_fill() wird mit der zuletzt benutzten Farbe die bisherige Figur gefüllt. Dazu
muss die Figur nicht vollständig umrandet sein!

gefülltes Dreieck

Die gezeigte Grafik wurde durch folgenden Python-Code erstellt:

import turtle
turtle.bgcolor('black')
turtle.color('yellow')
turtle.width(10)
turtle.begin_fill()
turtle.forward(100)
turtle.right(90)
turtle.forward(100)
turtle.color('orange')
turtle.end_fill()

Kreis bzw. Kreisausschnitt zeichnen - circle


Über die Anweisung turtle.circle() wird ein Kreis gezeichnet. Der erste Wert legt den
Kreisradius fest. Gibt es keinen zweiten Wert, wird ein kompletter Kreis gezeichnet. Gibt es
einen zweiten Wert, wird der entsprechende Kreisausschnitt (die Angabe erfolgt in Winkel ohne
Maßeinheit) gezeichnet.
© https://www.python-lernen.de/python-turtle.htm Seite 264

# Kreis mit 100 Pixel Radius


turtle.circle(100)
# Kreisausschnitt mit 50 Pixel Radius und 90 Grad (sprich ein ¼ Kreis)
turtle.circle(50,90)

Stift an bestimmten Punkt platzieren - goto


Der Stift kann über die Anweisung goto(X,Y) an einen bestimmten Punkt platziert werden.

import turtle
turtle.bgcolor('black')
turtle.color('yellow')
turtle.circle(100)
turtle.goto(250,250)
turtle.color('orange')
turtle.circle(100)

Allerdings wird ein Strich zwischen dem Endpunkt und dem neuen über goto
angesprungenen Anfangspunkt gezeichnet. Dies können wir über folgende 2 Befehle up()
und down() vermeiden.

Stift abheben und neu aufsetzen (sprich platzieren) – up() / down()


Wollen wir nicht immer einen durchgezogenen Strich erhalten, können wir mit dem Befehl
turtle.up() den Stift abheben und wieder neu aufsetzen über die Anweisung
turtle.down() :

turtle.color('yellow')
turtle.circle(100)
turtle.up()
turtle.color('orange')
turtle.forward(150)
turtle.down()
turtle.circle(100)

Anstelle die Turtle über forward zu bewegen, kann auch der Befehl goto eingesetzt
werden.

Aufgabe Olympische Ring mit Turtle zeichnen

Aufgabe: zeichne die olympischen Ringe.

Jede Farbe präsentiert einen Kontinent:

Blau für Europa,

Gelb für Asien,


© https://www.python-lernen.de/python-turtle.htm Seite 265

Schwarz für Afrika,

Grün für Australien

Rot für Amerika.

Und wer es perfekt machen möchte, kann die Verschlungenheit der Ringe korrekt darstellen :)

Text schreiben - write


Text kann über die Anweisung write(text) geschrieben werden.

import turtle
turtle.write('Hallo Welt')

Die Textgröße und Schriftart können festgelegt werden über:

turtle.write("Turtle ist super", font=('Arial', 60, 'normal'))

Auch die Schriftstärke, ob normal oder kursiv und ob unterstrichen:

turtle.write("Turtle ist super", font=('Arial', 60, 'normal', 'bold', 'italic', 'underline'))

Dabei gibt es folgende Parameter:

turtle.write(text, bewegen=False, ausrichtung="left", font=("Arial", 12, "normal"))

Parameters:

text – object to be written to the TurtleScreen

bewegen – True/False

ausrichtung – one of the strings “left”, “center” or right”

font – a triple (fontname, fontsize, fonttype)

Bildschirm löschen – clear() / reset()


Der Bildschirm kann gelöscht werden über

turtle.clear()

Soll sowohl der Bildschirm gelöscht werden wie auch alle Variablen zurückgestellt werden,
dann hilft reset()

turtle.reset()
© https://www.python-lernen.de/main-python.htm Seite 266

__main__ - Hauptprogramm festlegen


Im letzten Kapitel haben wir die Möglichkeit kennengelernt, Code aus einer anderen Datei zu
importieren und somit die dort vorhandenen Funktionen nutzen zu können. Die Schreibweise
der Funktionen wurde mit einem Punkt und dem Import-Namen verkettet.

Was passiert aber, wenn in der importierten Datei neben den Funktionen auch direkt
ausführbarer Code enthalten ist?

def bspfunktionfuerrueckgabe(eingabewert):
rueckgabewert = eingabewert * 2
return rueckgabewert

print("Ich stehe in der Datei:")

Dann wird immer genau an der Stelle, wo diese Datei importiert wird auch zusätzlich der im
Beispiel eingebaute print -Befehl ausgeführt.

Das ist in den meisten Fällen nicht wünschenswert.

Daher gibt es den Main-Bereich. Diesen erzeugen wir, indem wir den Dateinamen mit dem
Systemwert __main__ vergleichen. Den Dateinamen erhalten wir über __name__

Wenn wir uns den Inhalt von __name__ ausgeben lassen, werden wir feststellen, dass wir bei
direktem Aufruf als Rückgabewert __main__ erhalten. Bei indirektem Aufruf erhalten wir den
Dateinamen!

print(__name__)

Ausgabe auf Bildschirm:

__main__

Packen wir nun unseren Programmcode in eine andere Datei mit dem Namen
„fktsammlung.py“. Hier deutet sich auch die Funktion der „externen“ Datei an - wir haben dort
eine Sammlung von Funktionen, die wir immer wieder verwenden können. Dann wird der Wert
von __name__ den Dateinamen der importierten Datei enthalten.

Um jetzt überprüfen zu können, ob eine Datei direkt ausgeführt wird, werden beide
Systemkonstanten in eine if -Bedingung gepackt. So wissen wir, ob die Datei direkt
aufgerufen wird und somit der Code ausgeführt werden soll oder diese importiert wurde uns
somit nur die Funktionen zur Verfügung stehen sollen.

Hier nun der Inhalt der Datei „fktsammlung.py“:

def bspfunktionfuerrueckgabe(eingabewert):
rueckgabewert = eingabewert * 2
return rueckgabewert

if __name__ == "__main__":
print("Datei wurde direkt aufgerufen und die Main wird ausgeführt")
else:
print("Datei wurde als Modul aufgerufen")

print("Ich stehe in der Datei: " + __name__)


© https://www.python-lernen.de/main-python.htm Seite 267

Nutzen wir nun dieses Programm als Modul und rufen dieses über eine andere Datei auf (siehe
letzte Kapitel) erhalten wir die entsprechende Ausgabe.

Unser aufrufendes Programm nennen wir „hauptprogramm.py“:

import fktsammlung
fktsammlung.bspfunktionfuerrueckgabe(3)

Als Rückgabe erhalten wir:

Datei wurde als Modul aufgerufen


Ich stehe in der Datei: fktsammlung
© https://www.python-lernen.de/dateien-auslesen.htm Seite 268

Dateien auslesen und Inhalt nutzen


Dateien lesen mit Python ist kein großes Problem. Wir wollen Daten aus einer Datei laden und
diese können wir dann nach Belieben weiterverarbeiten.

Die Datei selber, die wir mit Python laden wollen, sollte sich im gleichen Verzeichnis befinden.
Wir erstellen uns eine Textdatei mit dem Inhalt „Text, der aus Datei kommt“. Der Dateinamen
sollte den üblichen Kriterien entsprechen. Es muss nicht einmal eine Dateiendung vergeben
werden – ich mache dies rein aus Gewohnheit und nenne meine Textdatei „textdatei.txt“.

Text, der aus Datei kommt

Um diese Datei nun zu laden, erstellen wir ein Python-Programm im gleichen Verzeichnis, in
der sich auch unsere Textdatei befindet.

Im ersten Schritt müssen wir die Datei zum Lesen öffnen.

open('textdatei.txt', MODUS)

Bisher passiert noch nichts, da wir die Art der Verwendung bei open im MODUS angeben
müssen. Es gibt verschiedene Modi, um eine Datei zu lesen, in eine Datei zu schreiben bzw.
gleichzeitiges lesen und schreiben.

Folgende Kürzel stehen für den Modus zur Verfügung:

w für „write“ - nur schreiben (bestehender Inhalt wird überschrieben)

a für „append“ – wird an bestehenden Inhalt angehängt

r für „read“ - nur für Lesen (siehe r+)

r+ also Lesen und Schreiben

b In Binärform für Lesen und Schreiben (die anderen Modi werden durch b ergänzt)

Wir wollen jetzt erst einmal unseren Inhalt aus der Datei lesen, also verwenden wir den „nur
lesen“-Modus r .

open('textdatei.txt','r')

Soweit so gut. Was liefert uns eigentlich die Funktion open zurück? Diese liefert uns einen
Rückgabewert zurück, auf den wir dann verschiedene Methoden anwenden können.

datei = open('textdatei.txt','r')
print(datei)

Wir erhalten als Rückgabewert: "<_io.TextIOWrapper name='textdatei.txt' mode='r'


encoding='UTF-8'>"

Jetzt können wir die zur Verfügung stehende Methoden darauf anwenden wie z.B. read .

datei = open('textdatei.txt','r')
print(datei.read())

Wir erhalten nun den Inhalt „Text, der aus Datei kommt“ angezeigt.

Erweitern wir nun den Inhalt unserer Datei „textdatei.txt“ um 2 weitere Zeilen:
© https://www.python-lernen.de/dateien-auslesen.htm Seite 269

Text, der aus Datei kommt


Ich bin die zweite Zeile
und die Dritte folgt sogleich

Speichern nicht vergessen. Wenn wir nun wieder unsere Methode read darauf anwenden,
sehen wir als Ergebnis den kompletten Inhalt (egal wie viele Zeilen es sind).

Immer nur 1 Zeile auslesen über readline


Wollen wir aber nur eine Zeile auslesen, um den Inhalt der Datei Zeile für Zeile zu verarbeiten,
hilft die Methode readline weiter. Zum Beispiel haben wir in jeder Zeile einen Zahlenwert
gespeichert und wollen diese der Reihen nach einlesen und weiterverarbeiten:

Wenn wir nun unser bestehendes Programm darauf anwenden:

datei = open('textdatei.txt','r')
print(datei.readline())

Erhalten wir nur die erste Zeile.

Um jetzt Zeile für Zeile einzulesen, packen wir die readline() Methode in eine for -
Schleife:

datei = open('textdatei.txt','r')
for zeile in datei:
print("Inhalt aus Datei: ")
print(zeile)

Jetzt wird Zeile für Zeile durchlaufen:

Länge des Lesens festlegen über .read()


Bei der Methode read() kann in der Klammer die Länge des Lesens festgelegt werden.
Somit können z.B. die erste 5 Zeichen ausgelesen werden.

datei = open('textdatei.txt','r')
print(datei.read(7))

Als Ergebnis erhalten wir nun von unserem Mustertext als Rückgabe die ersten sieben Zeichen:

Text, d

Wäre das siebte Zeichen ein Zeilenumbruch, würde dieses dann als letztes Zeichen gelesen
und ausgegeben. Einfach einmal probieren :).

Guter Stil – beenden über .close()


Es ist eine Frage des guten Stils, dass wir für das System kundtun, dass wir die Datei „fertig
genutzt“ haben. Daher wird nach Lese- und Schreibvorgänge die Verbindung wieder
geschlossen über die Methode close()
© https://www.python-lernen.de/dateien-auslesen.htm Seite 270

datei = open('textdatei.txt','r')
print(datei.read())
datei.close()
© https://www.python-lernen.de/in-dateien-schreiben.htm Seite 271

in Dateien schreiben mit Python


Nach dem Auslesen einer Datei wollen wir nun aus Python heraus in eine Datei schreiben.
Unser bisheriger Stand zum Auslesen der Datei mit dem Namen „textdatei.txt“ ist:

datei = open('textdatei.txt','r')
print(datei.read())

Im ersten Schritt müssen wir den Modus ändern, wie die Datei bei dem Befehl open geöffnet
wird. Es stehen und für das Schreiben die Methoden 'w', 'a' und 'r+' zur Verfügung.

Zum Testen verwenden wir den Modus 'a' für „append“ um Inhalt an eventuell bestehenden
Inhalt anzuhängen.

datei = open('textdatei.txt','a')
datei.write("weitere Zeile")

Wenn wir nun das Programm ausführen lassen, erhalten wir keinerlei sichtbare Reaktion. Wenn
wir nun in unsere Datei „textdatei.txt“ sehen, wurde für jedes ausführen des Python-
Programms der Text „weitere Zeile“ in die Datei zu dem bestehenden Text hinzugefügt.

Der Text wird einfach am bestehenden Text am Ende angefügt. Ohne eine neue Zeile! Lassen
wir das Programm zweimal ausführen, steht dann in der Datei hintereinander ohne Umbruch
und ohne Leerzeichen:

weitere Zeileweitere Zeile

Wir haben also keine weitere Zeile erstellt, sondern Text an eine bestehende Zeile angehängt.

Um auch einen Zeilenumbruch zu erhalten, brauchen wir die entsprechenden Steuerzeichen.


Ungeschickterweise sind diese zwischen Windows, Linux und Mac unterschiedlich. Bei einigen
Systemen reicht

„\n“ für newline

„\r\n“ für return/newline

Unser Code sieht also wie folgt aus:

datei = open('textdatei.txt','r')
datei.write("\r\nweitere Zeile")

Wir fügen vor unserem Text den Zeilenumbruch hinzu. Lassen wir nun unser Programm 2-mal
ausführen, erhalten wir wie gewünscht in der Datei das Ergebnis mit Zeilenumbruch:

weitere Zeile
weitere Zeile

Modus 'w' beim schreiben


Ändern wir den Modus auf 'w' wird der bereits bestehende Inhalt der Datei überschrieben mit
dem neuen Inhalt.

datei = open('textdatei.txt','w')
datei.write("\r\nweitere Zeile")
© https://www.python-lernen.de/in-dateien-schreiben.htm Seite 272

Lassen wir nun unser Programm ausführen, erhalten wir im Ergebnis nur noch die Zeile. Alle
alten Inhalte wurden "überschrieben".

weitere Zeile

gleichzeitig schreiben und lesen – 'r+'


Wollen wir aus einer Datei sowohl lesen wie in diese Datei schreiben, benötigen wir als Modus
'r+'. Jetzt können wir unser Python-Programm erweitern und auch gleich die neuen Inhalte
auslesen.

datei = open('textdatei.txt','r+')
datei.write("\r\nweitere Zeile")
print(datei.read())

Sollte nun nichts als Ausgabe erscheinen, dann sieht man das Problem bei 'r+'. Wir lesen
schneller aus, als in die Datei geschrieben wurde bzw. das System puffert und daher kommt
Chaos. Daher kommt nichts in der Ausgabe. Daher den Modus 'r+' nur mit Vorsicht nutzen! Hier
hilft das Schließen der Verbindung über die Methode close() . Allerdings muss dann auch
die Datei wieder geöffnet werden.

datei = open('textdatei.txt','r+')
datei.write("\r\nweitere Zeile")
datei.close()
datei = open('textdatei.txt','r+')
print(datei.read())
datei.close()

Lesen/Schreiben binär
Sollten wir nun mit binären Daten arbeiten, dann ist als Modus 'b' angesagt, der an das primäre
Kürzel angehängt wird.

Beispiel für Schreiben Binär

datei = open('textdatei.txt','wb')

Oder für Lesen Binär

datei = open('textdatei.txt','rb')
© https://www.python-lernen.de/csv-datei-einlesen.htm Seite 273

CSV Datei einlesen mit Python


Viele Daten liegen als CSV-Datei vor bzw. können sehr einfach in dem Format CSV gespeichert
werden. Was ist eine CSV-Datei überhaupt? Schaut man sich die Bedeutung der einzelnen
Buchstaben an, wird vieles klarer:

C = Comma = Komma

S = separated = getrennte

V = values = Werte

Unsere Daten liegen also durch Kommas voneinander getrennt in einer Datei vor. Meistens sind
in der ersten Linie die Namen der Datenspalten hinterlegt.

Schauen wir uns den Inhalt einer CSV-Datei an:

nachname,vorname,geburtstag
Müller,Mike,1980-03-05
Sommer,Elke,1987-05-02
Schuster,Johanna,1993-10-10

Allerdings muss man wissen, dass das Trennzeichen nicht zwingend ein Komma sein muss,
aber das Dateiformat weiterhin CSV sich nennt.

Gerne werden auch folgende Trennzeichen (engl. delimiters) verwendet:

Semikolon ;

Doppelpunkt :

TAB \t

Verfügt man über Daten, die in einer Exceltabelle vorliegen, kann man diese direkt aus Excel
heraus im CSV-Format abspeichern. Excel erlaubt zusätzlich die Angabe, welche Trennzeichen
verwendet werden sollen.

Und hier kommt der Vorteil von fertigen Bibliotheken. Einfach nutzen ohne große Probleme.

CSV-Datei mit der in Python eingebauten Bibliothek auslesen


Python verfügt bei der Standardinstallation bereits über eine CSV-Bibliothek. Diese können wir
einfach über import csv in unser Python-Programm einbinden.

Zum Testen speichern wir unsere Adressdaten von oben in die Textdatei mit dem Namen
„adressen.csv“.

import csv

Jetzt müssen wir unsere CSV-Datei zum Auslesen öffnen:

import csv
with open('adressen.csv') as csvdatei:

Wir können nun unser Programm ausführen, aber es passiert noch nichts. Wir benötigen unser
csv.reader , der uns aus geöffneten CSV-Datei ein „csv.reader object“ macht:
© https://www.python-lernen.de/csv-datei-einlesen.htm Seite 274

import csv
with open('adressen.csv') as csvdatei:
csv_reader_object = csv.reader(csvdatei, delimiter=',')
print(csv_reader_object)

Unserem csv.reader übergeben wir unsere geöffnete CSV-Datei und können auch das
Trennzeichen über die Anweisung delimiter=',' mitgeben. Als Standard ist das Komma
hinterlegt, daher müssten wir bei einem Komma als Trennzeichen nicht einmal den „delimiter“
festlegen.

import csv
with open('adressen.csv') as csvdatei:
csv_reader_object = csv.reader(csvdatei)
print(csv_reader_object)

Jetzt haben wir unser „csv.reader object“, dass wir über die for … in Konstruktion
durchlaufen und unsere Daten ausgeben können.

import csv
with open("adressen.csv") as csvdatei:
csv_reader_object = csv.reader(csvdatei)
for row in csv_reader_object:
print(row)

Unsere Daten liegen in Form einer Liste vor und können dementsprechend genutzt werden. Als
Ausgabe erhalten wir:

['nachname', 'vorname', 'geburtstag']


['Müller', 'Mike', '1980-03-05']
['Sommer', 'Elke', '1987-05-02']
['Schuster', 'Johanna', '1993-10-10']

Jetzt können wir noch die erste Zeile abfangen und unsere Daten nutzen. Unser kompletter
Programmcode:

import csv

with open("adressen.csv") as csvdatei:


csv_reader_object = csv.reader(csvdatei)

zeilennummer = 0
for row in csv_reader_object:

if zeilennummer == 0:
print(f'Spaltennamen sind: {", ".join(row)}')
else:
print(f'- Nachname: {row[0]} \t| Vorname: {row[1]} \t| Geburtstag: {row[
zeilennummer += 1

print(f'Anzahl Datensätze: {zeilennummer-1}')


© https://www.python-lernen.de/csv-datei-einlesen.htm Seite 275

CSV-Datei einlesen als Datentyp Dictionary


Anstelle einer Liste können wir auch den Datentyp „Dictionary“ erhalten. Dazu gibt es den
csv.DictReader . Unsere eingelesene Datei liegt danach als Wörterbuch („Dictionary“) vor.

import csv
with open("adressen.csv") as csvdatei:
csv_reader_object = csv.DictReader(csvdatei)
for row in csv_reader_object:
print(row)

Die erste Zeile wird automatisch für Indizes verwendet:

OrderedDict([('nachname', 'Müller'), ('vorname', 'Mike'), ('geburtstag', '1980-03-05')])

OrderedDict([('nachname', 'Sommer'), ('vorname', 'Elke'), ('geburtstag', '1987-05-02')])

OrderedDict([('nachname', 'Schuster'), ('vorname', 'Johanna'), ('geburtstag', '1993-10-10')])

Funktionen und Klassen des Moduls „csv“


Welche Funktionen und Klassen das Modul „csv“ beinhaltet, kann man über
print(dir(csv)) ausgeben lassen.
© https://www.python-lernen.de/oop-objektorientierte-programmierung-grundlagen.htm Seite 276

Grundlagen: Objektorientierte Programmierung (OOP)


verstehen und anwenden in Python
Öfters liest man solche Worte wie Programmierparadigma und komplex zum Thema
objektorientierte Programmierung. Davon nicht erschrecken lassen!

Objektorientierte Programmierung ist nicht schwer und macht vieles einfacher! Also einfach
auf das Abenteuer einlassen. Um das sperrige Wort objektorientierte Programmierung zu
vermeiden, verwende ich die geläufige Abkürzung OOP.

Am Rande bemerkt: durch das Verständnis von OOP werden auch die Python Module und die
komplette Sprache sehr viel einfacher verständlich.

OOP ganz einfach: Sprechen wir mal von Dingen (um die Materie greifbar zu machen)

Dinge haben Eigenschaften wie z.B. Größe, Farbe und Alter

Dinge können Aktionen machen/bzw. mit diesen Dingen gemacht werden wie z.B. knurren,
schmusen und schlafen

Bisher hatten wir in Python entweder Daten (was wir bei unseren Dingen mit Eigenschaften
beschrieben haben) oder wir haben irgendwelche Aufgaben erledigt mit Funktionen und
Methoden (in die wir zeitweise verschiedene Daten reingekippt haben).

Was aber passiert, wenn wir Daten und Methoden miteinander verknüpfen? Dann haben wir
schon objektorientierte Programmierung (OOP) bzw. den Kerngedanken begriffen.

Wir trennen uns von den unspezifischen Datenstrukturen wie Variablen, Listen und Tupeln und
gehen hin zu Datenstrukturen, die ein Objekt (sprich ein Ding) beschreiben.

Schauen wir uns einmal ganz konkret (m)eine Katze an. Die ist orange, fett und frisst nur
Lasagne, falls sie nicht schläft und heißt Garfield. Spaß beiseite, aber es kommt mit dieser
Beschreibung schon relativ gut hin. Überleg einmal, welche Eigenschaften von Katzen einem
einfallen und was Katzen so machen.

Eigenschaften:

hat eine Farbe

hat ein Alter

hat einen Namen

hat 4 Beine

Wir bauen uns also ein allgemeines Bild von einer Katze – einen Bauplan. Wir spielen mit
Python Gott und schaffen einen allgemeinen Katzen-Zusammenbau-Plan. Das ist unsere
Katzen-Klasse.
© https://www.python-lernen.de/oop-objektorientierte-programmierung-grundlagen.htm Seite 277

Und nun können wir virtuelle Katzen in beliebiger Anzahl erschaffen – sprich ganz viele Objekte,
die grundlegend Gleich nach dem Bauplan aufgebaut sind, aber sich in Ihren Eigenschaften
(Farbe, Alter, Name) unterscheiden und in der Ausprägung der Methoden.

Methoden in der OOP


Was sind nun Methoden? Nichts anderes wie in der bisherigen Programmierung die
Funktionen! Nur nennt sich Methode bei der OOP, die wir aufrufen können.

Methoden (Funktionen) einer Katze wären z.B.:

tut fressen

tut schlafen

tut schmusen

tut fauchen

tut krallen (manchmal)

Unsere Katze kann also, sobald die Methode „fressen()“ aufgerufen wird, den Futternapf leeren
(oder die Maus verspeisen).

Je nach Objekt (nicht jede Katze ist gleich) tut (sprich wird eine Methode angewendet) eine
Katze spielen, schmusen oder fauchen – muss aber nicht. Prinzipiell wäre es nach der
Katzenklasse möglich.

Klasse Objekt
© https://www.python-lernen.de/oop-objektorientierte-programmierung-grundlagen.htm Seite 278

Klasse Objekt

allgemeiner Bauplan: Klasse Katze Konkretes Tier: Objekt katze_sammy

Eigenschaften: Objekt:

Farbe fast orange

Alter 3

Rufname Sammy

Methoden: Methoden:

miauen miauen()

schlafen schlafen()

fressen fressen()

schmusen schmusen()

Allgemeine Beschreibung, die Blaupause (Klassen definieren Objekte haben konkrete Werte
Objekte)

Aus der Klasse können wir noch jede Menge weitere Objekte machen. „Machen“ hört sich nicht
wirklich professionell an, daher spricht man bei der OOP von Instanzen erstellen bzw.
instanziieren.

Wir haben also folgende Begriffe in der OOP:

Klassen (die Blaupause)

Objekte (aus Klassen erstellte Instanzen)

Instanz (nichts anderes wie ein Objekt – Lateinische Begriffe hören sich einfach hipper an – die
lateinische Bedeutung ist „abgeschlossene Einheit“)

Eigenschaft (sprich Attribute – eine Beschreibung, wie das Objekt „ist“)

Methoden (flapsig „Funktionen“ – was das Objekt tun kann)

Vererbung (hoppla – noch nicht beschrieben)

Ein letzter Begriff aus der OOP: Vererbung


© https://www.python-lernen.de/oop-objektorientierte-programmierung-grundlagen.htm Seite 279

Ähnlich wie bei einem Erbfall bekommt der Erbende etwas vom Verblichenen. Allerdings muss
bei der Programmierung nichts sterben.

Bleiben wir bei unserem Katzenbeispiel. Eine Katze ist schon sehr konkret (was man
spätestens beim Einsatz der Krallen spürt). Hier können wir noch einen Schritt davor machen.
Wir können uns eine allgemeine Klasse „Tier“ vorstellen. So ein Tier hat wie die Katze „Farbe,
Alter, Bezeichnung“ und „frisst und schläft“ normalerweise. Es ist eine allgemeine Sichtweise.

Wir können nun eine Klasse „Tier“ erzeugen, was diese Eigenschaften und Methoden hat.

Sprich unsere Klasse „Katze“ kann von der Klasse „Tier“ diese Eigenschaften und Methoden
erben und die Katzen-Klasse benötigt dann nur noch die fehlenden Eigenschaften und
Methoden (nicht jedes Tier kann schmusen oder hat Krallen für das Gegenteil).

Man spart sich also Programmierarbeit. Zumal wir aus der Klasse Tier auch eine Klasse Hund
erstellen können. Auch der Hund hat alle Eigenschaften und Methoden von der Klasse Tier.

Um einen letzten Begriff noch einzuführen. Passt etwas bei der Vererbung nicht, dann kann
man es in der Realität einfach nicht annehmen oder wegwerfen. Beim Programmieren dagegen
kann man diese Eigenschaft bzw. Methode „überschreiben“. Viele Möglichkeiten die dann beim
Programmieren eine konkrete Welt als binäre Welt abbilden lassen.

Das soll soweit erst einmal als grundlegendes Verständnis der OOP reichen. Diese werden in
den folgenden Kapiteln noch deutlich klarer, wenn wir diese konkret an Beispielen nutzen.

In den folgenden Kapiteln schauen wir uns also an, wie wir in Python Klassen aufbauen und
daraus Instanzen bilden (sprich Objekte wie die Katze Sammy erstellen).
© https://www.python-lernen.de/klassen-in-python.htm Seite 280

Klassen in Python
Nun starten wir mit Python und klassenorientierter Programmierung.

Wir definieren eine Klasse. Die Definition von Klassen muss vor dem Hauptprogramm im Code
stehen. Zur Erinnerung aus dem letzten Kapitel: Klassen sind Baupläne, aus denen dann später
die Objekte erstellt werden.

Starten wir einfach, denn am Beispiel wird die Funktion und die Vorteile klar.

Aus didaktischen Gründen basteln wir eine Katzen-Klasse (wer


Allergien gegen Katzen hat, darf wahlweise auch eine Hunde-Klasse
erstellen).

Also nennen wir das Kind beim Namen. In vielen Kursen und später
bei gewohntem Umgang mit Klassen und objektorientierter
Programmierung wird man den Klassennamen sehr kurz und
aussagekräftig halten – dann würde man etwas in die Richtung
class Katze festlegen. Zum Lernen werde ich den etwas
sperrigeren Klassennamen BauplanKatzenKlasse einsetzen.

Zum Festlegen einer Klasse in Python benötigen wir das


Schlüsselwort class und darauf folgt der Namen der Klasse.

Unsere erste Zeile für unsere Klasse lautet also:

class BauplanKatzenKlasse():

Was fällt auf? Der Klassenname startet mit einem Großbuchstaben! So erkennt man bereits am
Namen, dass es sich um eine Klasse handeln muss! Sind es mehrere Worte, werden diese über
die UpperCamelCase-Variante zusammengeschrieben. Wer ein deutsches Wort dafür benötigt
– Binnenmajuskel :) – Großbuchstaben mitten im Wort wie bei den Kamelhöckern. Leerzeichen
und Unterstriche werden auf keinen Fall genutzt! (Siehe Spickzettel zum Thema Konventionen
und Schreibweisen)

Nach dem Klassennamen folgt eine öffnende und schließende runde Klammer und dann der
Doppelpunkt, den man gerne einmal versehentlich vergisst.

Eine kleine Beschreibung gleich nach der Klassendefinition mitzugeben, macht sehr viel Sinn.
Diese Beschreibung taucht bei der Nutzung von help(Klassenname) wieder auf. Diese
Hilfen kennt man von allen Befehlen von Python, die man aufrufen kann über help(befehl) .

Diese Hilfen sind auch wichtig, wenn man mit mehreren Programmierern an einem Projekt
arbeitet bzw. wenn man seine Klassen weitergeben möchte oder an einem schlechten
Gedächtnis leidet.

Wie sieht das im Code aus? Nach der ersten Zeile mit class … starten wir in der nächsten
Zeile eingerückt mit 3 doppelten Anführungszeichen – das nennt sich Docstring
(Dokumentationsstring). Abgeschlossen wird der Hilfetext mit 3 doppelten Anführungszeichen.

class BauplanKatzenKlasse():
""" Klasse für das Erstellen von Katzen
Hilfetext ideal bei mehreren Programmierern in
einem Projekt oder bei schlechtem Gedächtnis """

Um uns die Hilfe einmal ausgeben lassen zu können, geben wir noch in unserem Programm die
folgende help -Zeile ein:
© https://www.python-lernen.de/klassen-in-python.htm Seite 281

class BauplanKatzenKlasse():
""" Klasse für das Erstellen von Katzen
Hilfetext ideal bei mehreren Programmierern in
einem Projekt oder bei schlechtem Gedächtnis """

print(help(BauplanKatzenKlasse))

Wir erhalten dann als Rückmeldung:

Help on class BauplanKatzenKlasse in module __main__:

class BauplanKatzenKlasse(builtins.object)
| Klasse für das Erstellen von Katzen
| Hilfetext ideal bei mehreren Programmierern in
| einem Projekt oder bei schlechtem Gedächtnis
|
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)

Bisher haben wir nur den Rumpf für unsere Klasse erstellt. Im folgenden Kapitel wollen wir nun
die Eigenschaften festlegen.
© https://www.python-lernen.de/konstruktoren.htm Seite 282

Initialisieren der Klasse


Eigenschaften einer Klasse müssen initialisiert werden. Wir wollen also die Einführung der
Benennung unserer Eigenschaften, damit wir später darauf zugreifen können.

In unserer Klasse sollen folgende Eigenschaften vorhanden sein:

Eigenschaften:

Farbe

Alter

Rufname

Bisher haben wir nur unseren Rumpf unserer Klasse „BauplanKatzenKlasse“ erstellt.

class BauplanKatzenKlasse():
""" Klasse für das Erstellen von Katzen
Hilfetext ideal bei mehreren Programmierern in
einem Projekt oder bei schlechtem Gedächtnis """

Jetzt wollen wir unsere Eigenschaften einführen. Dazu wird ein neuer eingerückter Block
erstellt, der immer den gleichen Aufruf hat: def __init__(self, …): . Folgend für unsere
Katzen-Klasse:

class BauplanKatzenKlasse():
""" Klasse für das Erstellen von Katzen
Hilfetext ideal bei mehreren Programmierern in
einem Projekt oder bei schlechtem Gedächtnis """

def __init__(self, rufname, farbe, alter):


self.rufname = rufname
self.farbe = farbe
self.alter = alter

Unserer Methode __init__ wird immer mit 2 Unterstrichen am Anfang und am Ende
geschrieben. In der Klammer kommt als erstes Argument immer „self“! Hier kommt ein
wichtiges Prinzip zum Tragen, dass Klassen so stark macht.

Dazu müssen wir kurz vorgreifen und uns ein Objekt erstellen. Bauen wir unsere erste Katze
mit dem Namen „Sammy“, die orange ist und 3 Jahre alt.

class BauplanKatzenKlasse():
""" Klasse für das Erstellen von Katzen
Hilfetext ideal bei mehreren Programmierern in
einem Projekt oder bei schlechtem Gedächtnis """

def __init__(self, rufname, farbe, alter):


self.rufname = rufname
self.farbe = farbe
self.alter = alter

katze_sammy = BauplanKatzenKlasse("Sammy", "orange", 3)

__self__ verstehen (WICHTIG!)


Was passiert nun da genau? Am besten ist dies an folgender Zeichnung nachzuverfolgen:

Wenn wir das Objekt „katze_sammy“ der Klasse „BauplanKatzenKlasse“ erstellen, wird der
Objektname „katze_sammy“ als erstes Argument in die „__init__(self)“ übergeben. Rufen wir
dann später Attribute der Klasse ab, machen wir das wieder über unseren Objektnamen
„katze_sammy“, die über „self.alter“ auf den Wert von Alter zugreift.
© https://www.python-lernen.de/konstruktoren.htm Seite 283

Erklärung zu __self__ und Ablauf beim Erstellen und Nutzen

Sehr schön sieht man auch die Auswirkungen unseren bisherigen Codes beim Live-Editor
(python-online-lern-editor.htm):

Eigenschaften der Klasse für das Objekt im Speicher angelegt

und in groß:

Sowohl die Klasse wie das Objekt wird erzeugt

Jetzt können wir das Alter über unsere Instanz (sprich Objekt) „katze_sammy“ abrufen:

katze_sammy = BauplanKatzenKlasse("Sammy", "orange", 3)


print(katze_sammy.alter)

Als Rückgabewert erhalten wir:

3
© https://www.python-lernen.de/konstruktoren.htm Seite 284

Hier sieht man schön die Gewichtigkeit von self sowohl beim „Befüllen“ unsere Klasse, wie
beim Erzeugen eines Objekts und letztendlich auch immer beim Abruf von Attributen (wie im
Beispiel das Alter oder den Rufnamen).

Zeit zum Üben!


Aufgabe: eine Klasse für Autos erstellen
Aus didaktischen Gründen basteln wir in dieser Aufgabe eine Klasse für Autos. Das liegt nicht
daran, dass Autos irgendwie wichtig wären (in der aktuellen Diskussion zur Umwelt), sondern
daran, dass sich jeder etwas unter Autos vorstellen kann und dies daher griffige Beispiele
ergibt.

Wer mag, darf die folgenden Beispiele auch mit Fahrrädern oder was auch immer durchführen.

Erste Überlegung:

wie benenne ich meine Klasse

welche Eigenschaften (und später Methoden) sollen meine „Autos“ bekommen?

Bitte eine Klasse erstellen mit mindestens dem Wert „Farbe“ und ein Objekt erstellen und
darüber die Farbe abrufen.
© https://www.python-lernen.de/loesung-uebung-klasse-auto-erstellen.htm Seite 285

Lösung zur Übung Klasse für Auto erstellen


Die Aufgabe war, eine Klasse für Autos zu erstellen. Dabei sind die ersten Überlegungen:

wie benenne ich meine Klasse

welche Eigenschaften (und später Methoden) sollen meine „Autos“ bekommen?

Grundsätzlich kann man sich überlegen, ob die Benennung Auto denn so glücklich ist? Man
kann bei den grundsätzlichen Überlegungen auch weiter verallgemeinern bzw. ähnliches
suchen. Ähnlich wäre der Pkw (der PersonenKraftWagen oder in der Schweiz PW für
PersonenWagen).

Es handelt sich um ein Fahrzeug mit eigenem Antrieb zum Personen befördern. Also kein
Fahrrad, da diese keinen eigenen Antrieb haben. Weiter verallgemeinert wäre es ein
Kraftfahrzeug. Wir könnten also für das Auto die Klasse „Pkw“ wählen.

class Pkw():
""" Klasse für das Erstellen von Personenkraftwagen """

Im nächsten Schritt können wir uns überlegen, welche Eigenschaften wichtig sind. Dabei
bestimmt unsere Anwendung die Auswahl der Eigenschaften. Für bestimmte Menschen ist
zum Beispiel das Material des Interieurs wichtig. Wurzelholz oder kein Wurzelholz – das ist hier
die Frage. Wir halten es allgemeiner und wir wollen die wichtigen Dinge als Eigenschaften. Uns
interessiert neben

der Farbe des Autos

das Baujahr

der aktuelle KM-Stand

Anzahl Sitzplätze

Marke

Also definieren wir diese Eigenschaften in unserer __init__() -Methode:

class Pkw():
""" Klasse für das Erstellen von Personenkraftwagen """

def __init__(self, farbe, baujahr, kmstand, sitze, marke):


self.farbe = farbe
self.baujahr = baujahr
self.sitze = sitze
self.marke = marke

Aber hier ist wie gesagt die Anwendung wichtig und diese bestimmt die dafür benötigten
Eigenschaften. Ganz außen vor ist gerade PS und Kraftstoffverbrauch.

Und jetzt können wir noch ein Objekt instanziieren – sprich wir basteln uns einen Trabi.
© https://www.python-lernen.de/loesung-uebung-klasse-auto-erstellen.htm Seite 286

class Pkw():
""" Klasse für das Erstellen von Personenkraftwagen """

def __init__(self, farbe, baujahr, kmstand, sitze, marke):


self.farbe = farbe
self.baujahr = baujahr
self.kmstand = kmstand
self.sitze = sitze
self.marke = marke

trabi = Pkw("rot", 1981, 143000, 4, "Trabi")

Als Ergebnis haben wir ein Objekt, mit dem wir nun weiterarbeiten können:

erstellte Klasse Pkw mit dem Objekt trabi

Zum Abrufen der Farbe benötigen wir nach unserer erstellten Klasse mit dem Objekt „trabi“ nur
den Aufruf:

print(trabi.farbe)
© https://www.python-lernen.de/oop-klasse-objekt-instanz-anlegen.htm Seite 287

Instanz einer Klasse anlegen


Im letzten Kapitel haben wir bereits eine Instanz unserer Klasse „BauplanKatzenKlasse“
angelegt. Hier nun die Feinheiten. Unser bisheriger Code der Klasse Katze:

class BauplanKatzenKlasse():
""" Klasse für das Erstellen von Katzen """

def __init__(self, rufname, farbe, alter):


self.rufname = rufname
self.farbe = farbe
self.alter = alter

Und zum Anlegen einer Instanz (sprich ein Objekt) hatten wir folgenden Aufruf:

katze_sammy = BauplanKatzenKlasse("Sammy", "orange", 3)

Extrem gut sieht man die internen Auswirkungen des Codes bei der Nutzung des Live-Editor
(https://www.python-lernen.de/python-online-lern-editor.htm):

was Intern in Python bei Nutzen von Klassen/Objekten passiert

Wir haben die erste Instanz angelegt – unser erstes Objekt lebt.

Schauen wir uns weitere Möglichkeiten an.

Vorgabewerte für Eigenschaften festlegen


Beim Anlegen einer Klasse wäre es praktisch, auch bereits Vorgabewerte festlegen zu können.
So könnte man sich ja vorstellen, dass man die Katzen immer „frisch geschlüpft“ bekommt.
Somit hätten die als Alter einfach 0.

Genau das wollen wir zum Testen für das Alter als Vorgabewert hinterlegen.

Hier kommt wieder unsere __init__() -Methode zum Tragen. Wir können Eigenschaften mit
Vorgabewert erweitern. Das kann man, muss aber nicht. Im Beispiel machen wir es nur für die
Eigenschaft „alter“:

def __init__(self, rufname, farbe, alter=0):

Intern im Speicher ist nun beim Alter die 0 als Standard-Argument hinterlegt:
© https://www.python-lernen.de/oop-klasse-objekt-instanz-anlegen.htm Seite 288

Vorgabewert über __init__

Erstellen wir unsere Instanz (Objekt) mit einer Angabe vom Alter, wird dieses genommen. Diese
Angabe hat immer Vorrang.

Tragen wir allerdings beim Initialisieren nichts ein, dann kommt der Vorgabewert zum Zug. So
könnten wir auch noch festlegen, dass die meisten Katzen schwarz sind (das weiß man doch,
wenn man dem Sprichwort glaub).

def __init__(self, rufname, farbe="schwarz", alter=0):

Erstellen wir nun ein neues Objekt „katze_karlo“ nur mit seinem Rufnamen, erhält dieser die
Vorgabewerte zugewiesen:

katze_sammy = BauplanKatzenKlasse("Sammy", "orange", 3)


katze_karlo = BauplanKatzenKlasse("Karlchen")

Wir haben nun 2 Katzen:

Objekt erzeugt mit Vorgabewerte

Und natürlich sind genau deshalb in dieser Sekunde irgendwo auf der Welt (und natürlich in
Ihrem Computer) zwei Katzen entstanden. „High five“ sage ich da nur!
© https://www.python-lernen.de/oop-klasse-objekt-instanz-anlegen.htm Seite 289

2 Objekte - mit Vorgabewerte erzeugt

Wichtig bei Vorgabewerten in Klassen


Sehr wichtig bei der Vergabe von Vorgabewerte ist die Platzierung innerhalb von __init__ .
Unsere Vorgabewerte müssen immer am Ende kommen!

Haben wir beispielsweise nur die Farbe als Vorgabewert und nicht das Alter, kommt eine
Fehlermeldung. Folgender Code geht schief!

def __init__(self, rufname, farbe="schwarz", alter):

Als Fehlermeldung erhalten wir dann: „SyntaxError: non-default argument follows default
argument“
© https://www.python-lernen.de/klassen-methoden-erstellen-und-aufrufen.htm Seite 290

Methoden bei Klassen erstellen und aufrufen bei Python


In unserer Katzen-Klasse haben wir bisher nur Eigenschaften und nur die Methode
__init__() .

Bei der Festlegung, welche Methoden für unsere BauplanKatzenKlasse hatten wir notiert:

Eigenschaften:

Farbe

Alter

Rufname

Methoden:

miauen

schlafen

fressen

schmusen

Also integrieren wir als Methode „miauen“. Eigentlich müssten wir für die Lautsprache von
Katzen 10 weitere unterschiedliche Lautarten als Methode integrieren (man sollte seiner Katze
mal genauer zuhören – im Gegensatz zum Hund, der nur 10 kann, kann die Katze bis 100
Einzellaute). Aber wir wollen nicht übertreiben. Unsere digitale Katze darf nur „miauen“ als
Methode.

Unser bisheriger Code:

class BauplanKatzenKlasse():
""" Klasse für das Erstellen von Katzen """

def __init__(self, rufname, farbe, alter):


self.rufname = rufname
self.farbe = farbe
self.alter = alter

katze_sammy = BauplanKatzenKlasse("Sammy", "orange", 3)

Wir bauen einen weiteren Bereich (Einrückung nicht vergessen!) mit def tut_miauen() ein.
Auch hier ist extrem wichtig, dass „self“ als erstes Argument nicht zu vergessen! Sonst erhält
man die Fehlermeldung „TypeError: tut_miauen() takes 0 positional arguments but 1 was
given“
© https://www.python-lernen.de/klassen-methoden-erstellen-und-aufrufen.htm Seite 291

class BauplanKatzenKlasse():
""" Klasse für das Erstellen von Katzen """

def __init__(self, rufname, farbe, alter):


self.rufname = rufname
self.farbe = farbe
self.alter = alter

def tut_miauen(self):
print("miau")

katze_sammy = BauplanKatzenKlasse("Sammy", "orange", 3)

Um nun die Methode „tut_miauen()“ zu nutzen, wird nach dem Erzeugen des Objektes diese mit
Objektnamen und Methode (verknüpft mit einem Punkt) und danach Klammern aufgerufen:

class BauplanKatzenKlasse():
""" Klasse für das Erstellen von Katzen """

def __init__(self, rufname, farbe, alter):


self.rufname = rufname
self.farbe = farbe
self.alter = alter

def tut_miauen(self):
print("miau")

katze_sammy = BauplanKatzenKlasse("Sammy", "orange", 3)


katze_sammy.tut_miauen()

Auf dem Bildschirm erhalten wir als Ausgabe:

miau

Werte beim Methodenaufruf übergeben


Wir wollen nun die Anzahl des Miauens noch mitgeben können bzw. wenn wir keine Anzahl
mitgeben, soll nur ein „Miau“ kommen. Wie bereits von den Eigenschaften können wir auch bei
den Methoden Vorgabewerte mitgeben. In diesem Fall soll 1 die Vorgabe sein:

def tut_miauen(self, anzahl = 1):


print(anzahl * "miau ")

Rufen wir nun die Methode auf, können wir die Anzahl übergeben:

katze_sammy.tut_miauen(3)

Es erscheinen ordnungsgemäß die 3 „Miaus“:

miau miau miau


© https://www.python-lernen.de/klassen-methoden-erstellen-und-aufrufen.htm Seite 292

beliebig viele Methoden in einer Klasse anlegen


Wir sind in der Anzahl der Methoden nicht begrenzt. Im folgenden Beispiel integrieren wir noch
schlafen und die Anzahl der Minuten des Schlafens:

Das ist dasselbe, wie wir schon bei der Methode „tut_miauen“ programmiert haben. Wir
machen noch eine Textausgabe, wie lange geschlafen wird:

def tut_schlafen(self, dauer):


print(self.rufname, " schläft jetzt ", dauer , " Minuten ")

katze_sammy = BauplanKatzenKlasse("Sammy", "orange", 3)


katze_sammy.tut_schlafen(3)

Interessant wäre doch, wie lange die Katze insgesamt über den Tag weg schläft?

Dauer aufaddieren in Methode einer Klasse


Wir wollen mal die Schlafdauer aufsummieren. Dazu benötigen wir eine weitere Eigenschaft,
die wir am Anfang mit 0 initialisieren. Wir nennen die Eigenschaft „schlafdauer“:

def __init__(self, rufname, farbe, alter):


self.rufname = rufname
self.farbe = farbe
self.alter = alter
self.schlafdauer = 0

Jetzt müssen wir unsere Methode tut_schlafen() noch entsprechend erweitern. Auf den
Wert der Eigenschaft „schlafdauer“ können wir einfach über das self.schlafdauer
zugreifen und diesen Wert entsprechend erhöhen. Danach lassen wir uns die bisherige
Gesamtdauer ausgeben

class BauplanKatzenKlasse():
""" Klasse für das Erstellen von Katzen """

def __init__(self, rufname, farbe, alter):


self.rufname = rufname
self.farbe = farbe
self.alter = alter
self.schlafdauer = 0

def tut_miauen(self, anzahl = 1):


print(anzahl * "miau ")

def tut_schlafen(self, dauer):


print(self.rufname, " schläft jetzt ", dauer , " Minuten ")
self.schlafdauer += dauer
print(self.rufname, " Schlafdauer insgesamt: ", self.schlafdauer, " Minuten "

katze_sammy = BauplanKatzenKlasse("Sammy", "orange", 3)


katze_sammy.tut_miauen(3)
katze_sammy.tut_schlafen(3)
katze_sammy.tut_schlafen(6)
© https://www.python-lernen.de/klassen-methoden-erstellen-und-aufrufen.htm Seite 293

Wir erhalten nun als Ausgabe:

miau miau miau

Sammy schläft jetzt 3 Minuten

Sammy Schlafdauer insgesamt: 3 Minuten

Sammy schläft jetzt 6 Minuten

Sammy Schlafdauer insgesamt: 9 Minuten

Der coole Trick zum live Methoden und Klassen testen


Schöner wäre, wenn wir nicht bereits im Code unsere Aufrufe für die verschiedenen Methoden
machen müssten, sondern live testen könnten. Das klappt, wenn wir unser Python-Programm
in der Konsole mit einem Parameter aufrufen. Der Parameter verhindert, dass unser Programm
sofort beendet wird und alle weiteren Eingaben werden ausgeführt, bis wir exit() eingeben.

Starten Sie in der Konsole das Programm mit dem Parameter „-i“ – die exakte Beschreibung
von dem Trick gibt es im Kapitel www.python-lernen.de/trick-programm-ausfuehren-und-in-
konsole-debuggen.htm

python -i BauplanKatzenKlasse.py

Im Folgenden sieht man die Möglichkeiten – erster Schritt: Das bestehende Programm wird
abgearbeitet und gibt folgende Ausgaben.

Axels-MacBook-Pro:Python-lernen.de$ python3 -i BauPlanKatze.py

miau miau miau

Sammy schläft jetzt 3 Minuten

Sammy Schlafdauer insgesamt: 3 Minuten

Sammy schläft jetzt 6 Minuten

Sammy Schlafdauer insgesamt: 9 Minuten

>>>

Jetzt können wir „katze_sammy“ miauen lassen – dazu geben wir einfach nach den 3
Größerzeichen den Funktionsaufruf ein:
© https://www.python-lernen.de/klassen-methoden-erstellen-und-aufrufen.htm Seite 294

Axels-MacBook-Pro:Python-lernen.de$ python3 -i BauPlanKatze.py

miau miau miau

Sammy schläft jetzt 3 Minuten

Sammy Schlafdauer insgesamt: 3 Minuten

Sammy schläft jetzt 6 Minuten

Sammy Schlafdauer insgesamt: 9 Minuten

>>> katze_sammy.tut_miauen(5)

miau miau miau miau miau

>>>

Und dann ein Powernap von 10 Minuten:

Axels-MacBook-Pro:Python-lernen.de$ python3 -i BauPlanKatze.py

miau miau miau

Sammy schläft jetzt 3 Minuten

Sammy Schlafdauer insgesamt: 3 Minuten

Sammy schläft jetzt 6 Minuten

Sammy Schlafdauer insgesamt: 9 Minuten

>>> katze_sammy.tut_miauen(5)

miau miau miau miau miau

>>> katze_sammy.tut_schlafen(10)

Sammy schläft jetzt 10 Minuten

Sammy Schlafdauer insgesamt: 19 Minuten

>>>

Wir können auch neue Objekte anlegen! Erwecken wir eine neue Katze zum Leben über:

katze_soni = BauplanKatzenKlasse("Soni", "getigert", 2)

Als Rückmeldung kommt nichts, da beim Anlegen einer neuen Instanz (Objektes) dies nicht
von unserem Programm kommentiert wird:
© https://www.python-lernen.de/klassen-methoden-erstellen-und-aufrufen.htm Seite 295

Axels-MacBook-Pro:Python-lernen.de$ python3 -i BauPlanKatze.py

miau miau miau

Sammy schläft jetzt 3 Minuten

Sammy Schlafdauer insgesamt: 3 Minuten

Sammy schläft jetzt 6 Minuten

Sammy Schlafdauer insgesamt: 9 Minuten

>>> katze_sammy.tut_miauen(5)

miau miau miau miau miau

>>> katze_sammy.tut_schlafen(10)

Sammy schläft jetzt 10 Minuten

Sammy Schlafdauer insgesamt: 19 Minuten

>>> katze_soni = BauplanKatzenKlasse("Soni", "getigert", 2)

>>>

Auch „katze_soni“ darf schlafen – hier sieht man, dass die Schlafdauer für alle Katzen getrennt
aufaddiert wird:

Axels-MacBook-Pro:Python-lernen.de$ python3 -i BauPlanKatze.py


miau miau miau
Sammy schläft jetzt 3 Minuten
Sammy Schlafdauer insgesamt: 3 Minuten
Sammy schläft jetzt 6 Minuten
Sammy Schlafdauer insgesamt: 9 Minuten
>>> katze_sammy.tut_miauen(5)
miau miau miau miau miau
>>> katze_sammy.tut_schlafen(10)
Sammy schläft jetzt 10 Minuten
Sammy Schlafdauer insgesamt: 19 Minuten
>>> katze_soni = BauplanKatzenKlasse("Soni", "getigert", 2)
>>> katze_soni.tut_schlafen(5)
Soni schläft jetzt 5 Minuten
Soni Schlafdauer insgesamt: 5 Minuten
>>>

Zum Beende der Testsession einfach quit() eingeben.

Unbedingt testen – diese Möglichkeit macht richtig Spaß und so kann man auch hartnäckige
Fehler einfacher finden.

Zeit zum Üben! Methoden für unsere PKW-Klasse


Wir hatten als letzte Übung eine Klasse „pkw“ erstellt. Dieser fehlen noch Methoden. Unser
Auto soll können:
© https://www.python-lernen.de/klassen-methoden-erstellen-und-aufrufen.htm Seite 296

hupen (ganz wichtige Methode!)

fahren (hier die Anzahl der KM eingeben und aufaddieren)

parken

Kilometerstand ausgeben

Viel Spaß beim Umsetzen. Unser bisheriger Programmcode als Beispiellösung, an dem
weitergearbeitet werden kann:

class Pkw():
""" Klasse für das Erstellen von Personenkraftwagen """

def __init__(self, farbe, baujahr, kmstand, sitze, marke):


self.farbe = farbe
self.baujahr = baujahr
self.kmstand = kmstand
self.sitze = sitze
self.marke = marke

trabi = Pkw("rot", 1981, 143000, 4, "Trabi")


© https://www.python-lernen.de/loesung-uebung-klassen-methoden-integrieren.htm Seite 297

Lösung zur Aufgabe: Methoden in PKW-Klasse einbauen


Hier der fertige Code. Es wurden auch die entsprechenden Anmerkungen als Docstrings
gemacht. Dadurch kann die Hilfe entsprechend ausgegeben werden. Daher bitte bis zum Ende
von diesem Kapitel lesen ;).

class Pkw():
""" Klasse für das Erstellen von Personenkraftwagen """

def __init__(self, farbe, baujahr, kmstand, sitze, marke):


""" Eigenschaften farbe, baujahr, kmstand, Sitzplätze, Marke erfassen """
self.farbe = farbe
self.baujahr = baujahr
self.kmstand = kmstand
self.sitze = sitze
self.marke = marke

def hupen(self):
""" hier sollte noch eine MP3-Datei ausgegeben werden """
print("Trööt")

def fahren(self, km):


""" wie viele KM gefahren werden, was dem Tachostand aufaddiert wird """
self.kmstand += km
print("Ich fahre ", km, " Kilometer")
print("Insgesamt bin ich ", self.kmstand ," gefahren")

def parken(self):
""" neben fahren schon das größere Problem in Städten """
print("Ich habe eine Parkplatz gefunden")

def kilometerstand(self):
""" Ausgabe des KM-Standes vom Tacho """
print("Ich habe ", str(self.kmstand) ," auf dem Tacho")

trabi = Pkw("rot", 1981, 143000, 4, "Trabi")


trabi.hupen()
trabi.kilometerstand()
trabi.fahren(5)
trabi.kilometerstand()
trabi.parken()

Jetzt können wir uns die Hilfe-Funktion zu dieser Klasse ausgeben lassen und erhalten die von
uns eingegebene Erklärung zur Klasse und Methoden:

….
trabi.kilometerstand()
trabi.parken()
print(help(Pkw))

Und wir bekommen diese Ausgabe:


© https://www.python-lernen.de/loesung-uebung-klassen-methoden-integrieren.htm Seite 298

Help on class Pkw in module __main__:

class Pkw(builtins.object)
| Pkw(farbe, baujahr, kmstand, sitze, marke)
|
| Klasse für das Erstellen von Personenkraftwagen
|
| Methods defined here:
|
| __init__(self, farbe, baujahr, kmstand, sitze, marke)
| Eigenschaften farbe, baujahr, kmstand, Sitzplätze, Marke erfassen
|
| fahren(self, km)
| weiviel KM gefahren werden, was dem Tachostand aufaddiert wird
|
| hupen(self)
| hier sollte noch eine MP3-Datei ausgegeben werden
|
| kilometerstand(self)
| Ausgabe des KM-Standes vom Tacho
|
| parken(self)
| neben fahren schon das größere Problem in Städten
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)

Zusätzlich können wir uns noch die enthaltenen Methoden der Klasse und des erzeugten
Objekts anzeigen lassen über die Python-Anweisung dir() . Auch das packen wir ans Ende
dazu:

….
trabi.kilometerstand()
trabi.parken()
print(help(Pkw))

print(dir(Pkw))
print(dir(trabi))

Für die Klasse dir(Pkw) erhalten wir folgende Informationen:

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__',


'__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__',
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__',
'__subclasshook__', '__weakref__', 'fahren', 'hupen', 'kilometerstand', 'parken']
© https://www.python-lernen.de/loesung-uebung-klassen-methoden-integrieren.htm Seite 299

Es sind alle von uns definierten Methoden von fahren, hupen bis parken aufgeführt.

Schauen wir uns die Ausgabe von dem Objekt mit dir(trabi) an, dann haben wir zusätzlich
neben den Methoden auch die Eigenschaften aufgeführt:

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__',


'__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__',
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__',
'__subclasshook__', '__weakref__', 'baujahr', 'fahren', 'farbe', 'hupen', 'kilometerstand', 'kmstand',
'marke', 'parken', 'sitze']
© https://www.python-lernen.de/vererbung-python.htm Seite 300

Vererbung bei Klassen in Python


Warum sollte eine Klasse etwas vererben? Gibt es auch digitales Sterben, könnte man sich
fragen? Ja und Nein – aber was auf jeden Fall leidet, ist die Übersicht, wenn Klassen immer
größer und größer und dadurch unübersichtlicher werden. Und daher ist wichtig, rechtzeitig
eine Erbfolge aufzubauen, bevor die Übersichtlichkeit stirbt!

Was passiert bei der Vererbung von Klassen?


Die erbende Klasse übernimmt alle Eigenschaften und Methoden der beerbten Klasse!

Bleiben wir bei unserem Beispiel mit Katzen. Bisher hatte unsere Klasse Katzen folgenden
Aufbau:

Klasse

Eigenschaften:

Farbe

Alter

Rufname

Methoden:

miauen

schlafen

fressen

schmusen

Jetzt wollen wir den Überbegriff zur Katze: Es handelt sich um ein Tier und genauer um ein
Säugetier (was man als Mensch auch manchmal beim Milchtritt der Katze direkt abbekommt).

Um das Beispiel besser ausbauen zu können, nehmen wir noch die Konkurrenz zur Katze dazu,
also Hunde. Wir haben also für beide den Überbegriff Säugetier – unsere neue „Über“-Klasse,
die es zu beerben gilt!
© https://www.python-lernen.de/vererbung-python.htm Seite 301

Baustruktur unserer Klassen mit Hierarchie

Und nun können die Eigenschaften der Katze in die Klasse Säugetier umgebaut werden. Die
Oberklasse Säugetier bekommt nun Eigenschaften der Unterklasse Katze, damit auch etwas
vererbt werden kann. In der Unterklasse Katze werden die übernommenen Eigenschaften
entfernt und somit haben wir eine sehr aufgeräumte Klasse was den Code sehr gut lesbar
macht.

Oberklasse bekommt Eigenschaften der Unterklasse, damit auch etwas vererbt werden kann.
© https://www.python-lernen.de/vererbung-python.htm Seite 302

Unser bisheriger Code:

class BauplanKatzenKlasse():
""" Klasse für das Erstellen von Katzen """

def __init__(self, rufname, farbe, alter):


self.rufname = rufname
self.farbe = farbe
self.alter = alter
self.schlafdauer = 0

katze_sammy = BauplanKatzenKlasse("Sammy", "orange", 3)


print(katze_sammy.farbe)

Jetzt erstellen wir unsere allgemeine Klasse „Tier“, die alle Eigenschaften der Katze erhält, was
die Klasse der Katze bereinigt (doppelt ist unnötig):

class Tier():
""" Klasse für das Erstellen von Säugetieren """

def __init__(self, rufname, farbe, alter):


self.rufname = rufname
self.farbe = farbe
self.alter = alter
self.schlafdauer = 0

class BauplanKatzenKlasse():
""" Klasse für das Erstellen von Katzen """

katze_sammy = BauplanKatzenKlasse("Sammy", "orange", 3)


print(katze_sammy.farbe)

Nach dem Starten des Python-Programms erhalten wir allerdings eine Fehlermeldung, dass
unsere Katzen-Klasse keinen Konstruktor hat, der das Argument übernehmen könnte.

Bisher gibt es auch noch keine Verbindung zwischen den beiden Klassen. Schaffen wir die
Verbindung!

Vererbung aktivieren zwischen 2 Klassen


Um die Vererbung und die Erbreihenfolge festzulegen, muss nur die erbende Klasse im
class -Aufruf in Klammern die allgemeine Klasse notiert werden:

class BauplanKatzenKlasse(Tier):

Die __init__ -Methode wird weiterhin benötigt! Allerdings wird bei der erbenden Klasse
innerhalb von __init__ die Eigenschaften über super() aus der Eltern-Klasse (also die Klasse
von der man erbt) „abgeholt“:

def __init__(self, rufname, farbe, alter):


super().__init__(rufname, farbe, alter)

Dieses erst einmal ominöse super() steht für „superclass“, sprich Oberklasse. Wir stellen
damit eine Verbindung zwischen der Eltern-Klasse (Klasse, von der Kind erbt) und Kind-Klasse
her.
© https://www.python-lernen.de/vererbung-python.htm Seite 303

Und nun funktioniert das auch!

Unsere Katzen-Klasse ist schlanker geworden, wobei wir noch keinen Code gespart haben, da
der bisherige Code in die neue Klasse „Tier“ gewandert ist. Hier der bisher erstellte Code
komplett:

class Tier():
""" Klasse für das Erstellen von Säugetieren """

def __init__(self, rufname, farbe, alter):


self.rufname = rufname
self.farbe = farbe
self.alter = alter
self.schlafdauer = 0

class BauplanKatzenKlasse(Tier):
""" Klasse für das Erstellen von Katzen """

def __init__(self, rufname, farbe, alter):


""" Initalisieren über Eltern-Klasse """
super().__init__(rufname, farbe, alter)

katze_sammy = BauplanKatzenKlasse("Sammy", "orange", 3)


print(katze_sammy.farbe)

Legen wir nun eine weitere Kind-Klasse (also noch eine Klasse, die von der Eltern-Klasse erbt)
an, sieht man die Ersparnisse deutlich. Und der Code ist übersichtlicher! Bauen wir eine Klasse
Hund. Nachdem wir nun schon mit Klassen umgehen können und den sperrigen Namen
„BauplanKatzenKlasse“ nicht wirklich schön ist, bekommt unsere Hunde-Klasse einen
schöneren Namen, und zwar „Hund“. Zur Erinnerung: erkennbar ist die Klasse immer an der
Schreibweise vom ersten Buchstaben in Großschreibung. Wir legen uns auch gleich ein neues
Objekt „hund_bello“ zum Testen an, zum Testen, ob das alles funktioniert.
© https://www.python-lernen.de/vererbung-python.htm Seite 304

class Tier():
""" Klasse für das Erstellen von Säugetieren """

def __init__(self, rufname, farbe, alter):


self.rufname = rufname
self.farbe = farbe
self.alter = alter
self.schlafdauer = 0

class BauplanKatzenKlasse(Tier):
""" Klasse für das Erstellen von Katzen """

def __init__(self, rufname, farbe, alter):


""" Initalisieren über Eltern-Klasse """
super().__init__(rufname, farbe, alter)

class Hund(Tier):
""" Klasse für das Erstellen von Hunden """

def __init__(self, rufname, farbe, alter):


""" Initalisieren über Eltern-Klasse """
super().__init__(rufname, farbe, alter)

katze_sammy = BauplanKatzenKlasse("Sammy", "orange", 3)


print(katze_sammy.farbe)

hund_bello = Hund("Bello", "braun", 5)


print(hund_bello.farbe)

Methoden vererben in der OOP


Bisher haben wir uns nur die vererbten Eigenschaften angesehen. Genauso können wir die
Methoden vererben. Als Erstes vererben wir unsere Methode „tut_schlafen()“. Schlaf benötigt
jedes Tier und interessant ist bei unserer Methode, dass die Gesamtschlafdauer aufaddiert
wird.

Unsere Klasse Tier wird nun über die Methode „tut_schlafen()“ erweitert.

class Tier():
""" Klasse für das Erstellen von Säugetieren """

def __init__(self, rufname, farbe, alter):


self.rufname = rufname
self.farbe = farbe
self.alter = alter
self.schlafdauer = 0

def tut_schlafen(self, dauer):


print(self.rufname, " schläft jetzt ", dauer , " Minuten ")
self.schlafdauer += dauer
print(self.rufname, " Schlafdauer insgesamt: ", self.schlafdauer, " Minuten "
© https://www.python-lernen.de/vererbung-python.htm Seite 305

Weder bei unserer Katzen-Klasse noch bei der Hund-Klasse müssen wir irgendetwas machen.
Beide erben automatisch alle Methoden der Eltern-Klasse „Tier“, die sofort zur Verfügung
stehen. Das können wir auch gleich testen über:

hund_bello.tut_schlafen(4)
katze_sammy.tut_schlafen(5)
hund_bello.tut_schlafen(2)

Der Hund schläft öfters, dass man schön sieht, dass für jede Instanz (also Bello und Sammy
getrennt voneinander) automatisch ein Schlafkonto geführt wird:

hund_bello.tut_schlafen(4)
katze_sammy.tut_schlafen(5)
hund_bello.tut_schlafen(2)

Unser Ergebnis ist:

Bello schläft jetzt 4 Minuten


Bello Schlafdauer insgesamt: 4 Minuten

Sammy schläft jetzt 5 Minuten


Sammy Schlafdauer insgesamt: 5 Minuten

Bello schläft jetzt 2 Minuten


Bello Schlafdauer insgesamt: 6 Minuten

Wir integrieren noch die Methode tut_reden() in unsere Hauptklasse:

def tut_reden(self, anzahl = 1):


print(self.rufname, "sagt: ", anzahl * "miau ")

Unser kompletter Code:


© https://www.python-lernen.de/vererbung-python.htm Seite 306

class Tier():
""" Klasse für das Erstellen von Säugetieren """

def __init__(self, rufname, farbe, alter):


self.rufname = rufname
self.farbe = farbe
self.alter = alter
self.schlafdauer = 0

def tut_schlafen(self, dauer):


print(self.rufname, " schläft jetzt ", dauer , " Minuten ")
self.schlafdauer += dauer
print(self.rufname, " Schlafdauer insgesamt: ", self.schlafdauer, " Minuten "

def tut_reden(self, anzahl = 1):


print(self.rufname, "sagt: ", anzahl * "miau ")

class BauplanKatzenKlasse(Tier):
""" Klasse für das Erstellen von Katzen """

def __init__(self, rufname, farbe, alter):


""" Initalisieren über Eltern-Klasse """
super().__init__(rufname, farbe, alter)

class Hund(Tier):
""" Klasse für das Erstellen von Hunden """

def __init__(self, rufname, farbe, alter):


""" Initalisieren über Eltern-Klasse """
super().__init__(rufname, farbe, alter)

katze_sammy = BauplanKatzenKlasse("Sammy", "orange", 3)


hund_bello = Hund("Bello", "braun", 5)

katze_sammy.tut_reden(1)
hund_bello.tut_reden(3)
© https://www.python-lernen.de/attribute-und-methoden-ueberschreiben.htm Seite 307

Attribute und Methoden in Klassen überschreiben


Unser Programm aus dem letzten Kapitel ist für die Katz (wortwörtlich). Der Hund zieht den
Kürzeren, da er sich nicht korrekt mitteilen kann. Die geerbte Methode passt nicht!

Aber was ist mit Methoden, die so nicht passen? Unsere Methode „tut_miauen()“ mag ja noch
für die Katze passen, ist aber beim Hund merkwürdig. Also bekommt die Elternklasse die
Methode „tut_reden()“ (sorry, ein besserer Methodenname fällt mir gerade nicht ein). Bei der
„Rede“ kommt noch als Ausgabe, wer da gerade redet:

Wir erhalten:

Sammy sagt: miau

Bello sagt: miau miau miau

Unser bisher entstandener kompletter Code:


© https://www.python-lernen.de/attribute-und-methoden-ueberschreiben.htm Seite 308

class Tier():
""" Klasse für das Erstellen von Säugetieren """

def __init__(self, rufname, farbe, alter):


self.rufname = rufname
self.farbe = farbe
self.alter = alter
self.schlafdauer = 0

def tut_schlafen(self, dauer):


print(self.rufname, " schläft jetzt ", dauer , " Minuten ")
self.schlafdauer += dauer
print(self.rufname, " Schlafdauer insgesamt: ", self.schlafdauer, " Minuten "

def tut_reden(self, anzahl = 1):


print(self.rufname, "sagt: ", anzahl * "miau ")

class BauplanKatzenKlasse(Tier):
""" Klasse für das Erstellen von Katzen """

def __init__(self, rufname, farbe, alter):


""" Initalisieren über Eltern-Klasse """
super().__init__(rufname, farbe, alter)

class Hund(Tier):
""" Klasse für das Erstellen von Hunden """

def __init__(self, rufname, farbe, alter):


""" Initalisieren über Eltern-Klasse """
super().__init__(rufname, farbe, alter)

katze_sammy = BauplanKatzenKlasse("Sammy", "orange", 3)


hund_bello = Hund("Bello", "braun", 5)

katze_sammy.tut_reden(1)
hund_bello.tut_reden(3)

Als Ergebnis miaut nun unser Hund :(

Sammy sagt: miau

Bello sagt: miau miau miau

Das ist natürlich für den Hund frustrierend und führt langfristig zu Hundedepressionen. Dem
wollen wir vorbeugen.

Methoden Überschreiben in der objektorientierten


Programmierung
Wir können Methoden überschreiben. Passt eine geerbte Methode nicht, können wir diese in
der Kindklasse einfach überschreiben. Unser Hund im Beispiel soll artgerecht bellen.
© https://www.python-lernen.de/attribute-und-methoden-ueberschreiben.htm Seite 309

Also erzeugen wir in der Hund-Klasse eine Methode mit dem exakt gleichen Namen! Somit wird
diese bei Aufruf ausgeführt und somit überschreibt diese die Methode der Elternklasse:

Unsere Hundeklasse:

class Hund(Tier):
""" Klasse für das Erstellen von Hunden """

def __init__(self, rufname, farbe, alter):


""" Initalisieren über Eltern-Klasse """
super().__init__(rufname, farbe, alter)

def tut_reden(self, anzahl = 1):


print(self.rufname, "sagt: ", anzahl * "WAU ")

Wird nun eine Unterhaltung zwischen Hund und Katze gehalten, läuft diese wie gewohnt ab:

katze_sammy.tut_reden(1)
hund_bello.tut_reden(3)

Mit dem Ergebnis:

Sammy sagt: miau

Bello sagt: WAU WAU WAU

Und der komplette Code:


© https://www.python-lernen.de/attribute-und-methoden-ueberschreiben.htm Seite 310

class Tier():
""" Klasse für das Erstellen von Säugetieren """

def __init__(self, rufname, farbe, alter):


self.rufname = rufname
self.farbe = farbe
self.alter = alter
self.schlafdauer = 0

def tut_schlafen(self, dauer):


print(self.rufname, " schläft jetzt ", dauer , " Minuten ")
self.schlafdauer += dauer
print(self.rufname, " Schlafdauer insgesamt: ", self.schlafdauer, " Minuten "

def tut_reden(self, anzahl = 1):


print(self.rufname, "sagt: ", anzahl * "miau ")

class BauplanKatzenKlasse(Tier):
""" Klasse für das Erstellen von Katzen """

def __init__(self, rufname, farbe, alter):


""" Initalisieren über Eltern-Klasse """
super().__init__(rufname, farbe, alter)

class Hund(Tier):
""" Klasse für das Erstellen von Hunden """

def __init__(self, rufname, farbe, alter):


""" Initalisieren über Eltern-Klasse """
super().__init__(rufname, farbe, alter)

def tut_reden(self, anzahl = 1):


print(self.rufname, "sagt: ", anzahl * "WAU ")

katze_sammy = BauplanKatzenKlasse("Sammy", "orange", 3)


hund_bello = Hund("Bello", "braun", 5)

katze_sammy.tut_reden(1)
hund_bello.tut_reden(3)

Zeit zum Üben: Vererbung beim Auto und Methoden


überschreiben
Unsere Klasse „Pkw“ aus der letzten Übung soll eine weitere Geschwisterklasse (nicht von der
man erbt) bekommen, den „Lkw“. Alle bisher vorhandenen Eigenschaften und Methoden sollen
in die Elternklasse „Fahrzeug“ verlagert werden.

Das Auto soll zusätzlich die Eigenschaft kofferraumvolumen bekommen.

Beim Lkw soll die Methode „parken()“ überschrieben werden. Es soll als Ausgabe kommen „auf
Firmenhof abgestellt“.
© https://www.python-lernen.de/attribute-und-methoden-ueberschreiben.htm Seite 311

Der Lkw soll eine zusätzliche Methode bekommen: aufladen()

Unser bisheriger Code aus der letzten Lösung, der jetzt erweitert werden soll.

class Pkw():
""" Klasse für das Erstellen von Personenkraftwagen """

def __init__(self, farbe, baujahr, kmstand, sitze, marke):


""" Eigenschaften farbe, baujahr, kmstand, Sitzplätze, Marke erfassen """
self.farbe = farbe
self.baujahr = baujahr
self.kmstand = kmstand
self.sitze = sitze
self.marke = marke

def hupen(self):
""" hier sollte noch eine MP3-Datei ausgegeben werden """
print("Trööt")

def fahren(self, km):


""" wie viele KM gefahren werden, was dem Tachostand aufaddiert wird """
self.kmstand += km
print("Ich fahre ", km, " Kilometer")
print("Insgesamt bin ich ", self.kmstand ," gefahren")

def parken(self):
""" neben fahren schon das größere Problem in Städten """
print("Ich habe eine Parkplatz gefunden")

def kilometerstand(self):
""" Ausgabe des KM-Standes vom Tacho """
print("Ich habe ", str(self.kmstand) ," auf dem Tacho")

trabi = Pkw("rot", 1981, 143000, 4, "Trabi")


trabi.hupen()
trabi.kilometerstand()
trabi.fahren(5)

Viel Spaß beim Umbauen.


© https://www.python-lernen.de/loesung-klassen-vererbung.htm Seite 312

Lösung Aufgabe Vererbung


In der Aufgabe zum Üben (und Testen) von Vererbung von Elternklassen und Überschreiben
von Methoden sollten wir zu unserer Klasse „Pkw“ eine weitere Geschwisterklasse erstellen,
den „Lkw“. Alle bisher vorhandenen Eigenschaften und Methoden sollen in die Elternklasse
„Fahrzeug“ verlagert werden.

Beim Auto zusätzlich Eigenschaft: Kofferraumvolumen

Methode „parken()“ beim Lkw überschrieben mit Ausgabe: „auf Firmenhof abgestellt“.

Der Lkw soll eine zusätzliche Methode bekommen: aufladen()

Sortieren wir die Punkte, in welcher Reihenfolge diese am meisten Sinn ergeben:

Elternklasse „Fahrzeug“ erstellen

alle Eigenschaften und Methoden verlagern

Klasse Auto mit Eigenschaft Kofferraumvolumen erweitern

Klasse Lkw erzeugen

Lkw-Methode parken() überschreiben

Lkw-Methode aufladen() erzeugen

Gehen wir es an:

Punkt 1: Elternklasse „Fahrzeug“ erstellen


Das Erstellen einer neuen Klasse ist nicht wirklich ein Thema:

class Fahrzeug():
""" Klasse für das Erstellen von Fahrzeugen """

Punkt 2: alle Eigenschaften und Methoden verlagern


Nach dem Verlagern müssen wir an die Vererbung denken ( class Pkw(Fahrzeug): ) und
die __init__ in der Kindklasse entsprechend mit super() ausstatten.

class Pkw(Fahrzeug):
""" Klasse für das Erstellen von Personenkraftwagen """

def __init__(self, farbe, baujahr, kmstand, sitze, marke):


super().__init__(farbe, baujahr, kmstand, sitze, marke)

Der gesamte Code (auch zum Testen, denn an der Ausgabe hat sich nichts geändert – aber
funktionieren sollte es)
© https://www.python-lernen.de/loesung-klassen-vererbung.htm Seite 313

class Fahrzeug():
""" Klasse für das Erstellen von Fahrzeugen """

def __init__(self, farbe, baujahr, kmstand, sitze, marke):


""" Eigenschaften farbe, baujahr, kmstand, Sitzplätze, Marke erfassen """
self.farbe = farbe
self.baujahr = baujahr
self.kmstand = kmstand
self.sitze = sitze
self.marke = marke

def hupen(self):
""" hier sollte noch eine MP3-Datei ausgegeben werden """
print("Trööt")

def fahren(self, km):


""" wie viele KM gefahren werden, was dem Tachostand aufaddiert wird """
self.kmstand += km
print("Ich fahre ", km, " Kilometer")
print("Insgesamt bin ich ", self.kmstand ," gefahren")

def parken(self):
""" neben fahren schon das größere Problem in Städten """
print("Ich habe eine Parkplatz gefunden")

def kilometerstand(self):
""" Ausgabe des KM-Standes vom Tacho """
print("Ich habe ", str(self.kmstand) ," auf dem Tacho")

class Pkw(Fahrzeug):
""" Klasse für das Erstellen von Personenkraftwagen """

def __init__(self, farbe, baujahr, kmstand, sitze, marke):


super().__init__(farbe, baujahr, kmstand, sitze, marke)

trabi = Pkw("rot", 1981, 143000, 4, "Trabi")


trabi.hupen()
trabi.kilometerstand()
trabi.fahren(5)

Punkt 3: Klasse Auto mit Eigenschaft Kofferraumvolumen


erweitern
Wir können auch komplett eigenständige Eigenschaften in einer Kindklasse haben, die nicht in
der Elternklasse vorkommen. Das sieht man schön am Kofferraumvolumen.

Diese müssen wir wie gewohnt in der __init__ übertragen:

def __init__(self, farbe, baujahr, kmstand, sitze, marke, kofferraumvolumen):

Und natürlich beim Erzeugen des Objekts nicht vergessen:

trabi = Pkw("rot", 1981, 143000, 4, "Trabi", 20)


© https://www.python-lernen.de/loesung-klassen-vererbung.htm Seite 314

Und nun noch in Eigenschaft ( self nicht vergessen) speichern, damit wir darauf zugreifen
können:

class Pkw(Fahrzeug):
""" Klasse für das Erstellen von Personenkraftwagen """

def __init__(self, farbe, baujahr, kmstand, sitze, marke, kofferraumvolumen):


super().__init__(farbe, baujahr, kmstand, sitze, marke)
self.kofferraumvolumen = kofferraumvolumen

Jetzt können wir diese Eigenschaft abfragen

trabi = Pkw("rot", 1981, 143000, 4, "Trabi", 20)


print(trabi.kofferraumvolumen)

Eine von der Elternklasse unabhängige Eigenschaft. Auch andere Geschwisterklassen wissen
von der Eigenschaft nichts, denn diese erben nur von der Elternklasse!

Punkt 4: Klasse Lkw erzeugen


Hier kommt bisher keine große Überraschung:

class Lkw(Fahrzeug):
""" Klasse für das Erstellen von Lastkraftwagen """

def __init__(self, farbe, baujahr, kmstand, sitze, marke):


super().__init__(farbe, baujahr, kmstand, sitze, marke)

Und nun ein Lkw-Objekt erstellen:

lkw_plattnase = Lkw("orange", 1999, 50000, 3, "MAN")


print(lkw_plattnase.farbe)

Am Rande bemerkt: ein klasse Artikel über „Plattnasen“ und „Langhauber“:


https://www.spiegel.de/auto/fahrkultur/warum-lastwagen-in-deutschland-und-den-usa-
unterschiedlich-aussehen-a-855319.html

Punkt 5: Lkw-Methode parken() überschreiben


Und nun bekommt unsere Klasse Lkw die Methode „parken()“. Nachdem diese sich exakt
gleich schreibt, wie die in der Elternklasse „Fahrzeug“ überschreibt diese die ursprüngliche
Methode.
© https://www.python-lernen.de/loesung-klassen-vererbung.htm Seite 315

class Lkw(Fahrzeug):
""" Klasse für das Erstellen von Lastkraftwagen """

def __init__(self, farbe, baujahr, kmstand, sitze, marke):


super().__init__(farbe, baujahr, kmstand, sitze, marke)

def parken(self):
print("auf Firmenhof abgestellt")

lkw_plattnase = Lkw("orange", 1999, 50000, 3, "MAN")


print(lkw_plattnase.farbe)
lkw_plattnase.parken()

Punkt 6: Lkw-Methode aufladen() erzeugen


Und nun noch eine zusätzliche Methode für den Lkw:

class Lkw(Fahrzeug):
""" Klasse für das Erstellen von Lastkraftwagen """

def __init__(self, farbe, baujahr, kmstand, sitze, marke):


super().__init__(farbe, baujahr, kmstand, sitze, marke)

def parken(self):
print("auf Firmenhof abgestellt")

def aufladen(self):
print("habe fertig geladen")

lkw_plattnase = Lkw("orange", 1999, 50000, 3, "MAN")


print(lkw_plattnase.farbe)
lkw_plattnase.parken()
lkw_plattnase.aufladen()

Und unser kompletter Code:

class Fahrzeug():
""" Klasse für das Erstellen von Fahrzeugen """

def __init__(self, farbe, baujahr, kmstand, sitze, marke):


""" Eigenschaften farbe, baujahr, kmstand, Sitzplätze, Marke erfassen """
self.farbe = farbe
self.baujahr = baujahr
self.kmstand = kmstand
self.sitze = sitze
self.marke = marke

def hupen(self):
""" hier sollte noch eine MP3-Datei ausgegeben werden """
print("Trööt")

def fahren(self, km):


""" wie viele KM gefahren werden, was dem Tachostand aufaddiert wird """
self.kmstand += km
© https://www.python-lernen.de/loesung-klassen-vererbung.htm Seite 316

self.kmstand += km
print("Ich fahre ", km, " Kilometer")
print("Insgesamt bin ich ", self.kmstand ," gefahren")

def parken(self):
""" neben fahren schon das größere Problem in Städten """
print("Ich habe eine Parkplatz gefunden")

def kilometerstand(self):
""" Ausgabe des KM-Standes vom Tacho """
print("Ich habe ", str(self.kmstand) ," auf dem Tacho")

class Pkw(Fahrzeug):
""" Klasse für das Erstellen von Personenkraftwagen """

def __init__(self, farbe, baujahr, kmstand, sitze, marke, kofferraumvolumen):


super().__init__(farbe, baujahr, kmstand, sitze, marke)
self.kofferraumvolumen = kofferraumvolumen

class Lkw(Fahrzeug):
""" Klasse für das Erstellen von Lastkraftwagen """

def __init__(self, farbe, baujahr, kmstand, sitze, marke):


super().__init__(farbe, baujahr, kmstand, sitze, marke)

def parken(self):
print("auf Firmenhof abgestellt")

def aufladen(self):
print("habe fertig geladen")

lkw_plattnase = Lkw("orange", 1999, 50000, 3, "MAN")


print(lkw_plattnase.farbe)
lkw_plattnase.parken()
lkw_plattnase.aufladen()

trabi = Pkw("rot", 1981, 143000, 4, "Trabi", 20)


print(trabi.kofferraumvolumen)
trabi.hupen()
trabi.kilometerstand()
trabi.fahren(5)
© https://www.python-lernen.de/oop-vererbung-weiterdenken.htm Seite 317

Vererbung weiterdenken! Erben von Listen etc.


Wir haben bisher fleißig aus von uns erstellten Klassen geerbt. Aber Vererbung in Python kann
man noch weiterdenken! Die daraus entstehenden Möglichkeiten wird man erst nach und nach
erfassen (wirklich).

Hier einfach mal zum Kennenlernen. Aber Schritt für Schritt!

Der große Vorteil von objektorientierter Programmierung haben wir am Anfang vom Kapitel
gesehen, dass wir benötigte Datenstrukturen passend zu unserem Objekt (was Realität
abbildet) zusammenbauen können.

Einen Schritt zurück. Schauen wir uns den Datentyp Liste an.

datenliste = ["Hans", "Elke", "Sonja", "Kai"]


print(dir(datenliste))

Über die Anweisung dir() sehen wir die verfügbaren Methoden (es handelt sich bei Listen
auch im Objekte, was man auch in der Anwendung sieht).

Das Ergebnis ist:

['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__',


'__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__',
'__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__',
'__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert',
'pop', 'remove', 'reverse', 'sort']

Wir können zum Beispiel die Daten der Liste auslesen über die Methode pop() :

datenliste = ["Hans", "Elke", "Sonja", "Kai"]


print(datenliste)
print(datenliste.pop())
print(datenliste)

Die Anweisung pop() liest das letzte Element aus und wirft es aus der Liste:

['Hans', 'Elke', 'Sonja', 'Kai']

Kai

['Hans', 'Elke', 'Sonja']

Schauen wir uns eine Klasse an mit einer ähnlichen Datenstruktur. Wir basteln uns einen
sportiven Jogger, der durch die Welt läuft und gelaufene Zeiten sammelt. Hier haben wir in
unserer Klasse eine Liste mit dem Namen gelaufene_zeiten und einer Methode
zeiterfassung() .
© https://www.python-lernen.de/oop-vererbung-weiterdenken.htm Seite 318

class Jogger():
""" sportliche Klasse für das Verwalten von gelaufenen Zeiten """

def __init__(self, altersklasse, zeit=[]):


self.altersklasse = altersklasse
self.gelaufene_zeiten = zeit

def zeiterfassen(self, zeiten):


self.gelaufene_zeiten += zeiten

Wir sehen bei der __init__ , dass unsere übergebene Zeit eine Liste ist (die eckigen
Klammern verraten dies).

Jetzt erstellen wir die Jogger-Instanz – unser Objekt heißt „Laeufer_Hans“

class Jogger():
""" sportliche Klasse für das Verwalten von gelaufenen Zeiten """

def __init__(self, altersklasse, zeit=[]):


self.altersklasse = altersklasse
self.gelaufene_zeiten = zeit

def zeiterfassen(self, zeiten):


self.gelaufene_zeiten += zeiten

Laeufer_Hans = Jogger("M40")
print(Laeufer_Hans.altersklasse)
Laeufer_Hans.zeiterfassen(["2:30"])
print(Laeufer_Hans.gelaufene_zeiten)
Laeufer_Hans.zeiterfassen(["2:40", "3:10"])
print(Laeufer_Hans.gelaufene_zeiten)

Als Ergebnis sehen wir die Altersklasse (das ist das Teil, damit Läufer sich untereinander
vergleichen können – sprich unser Läufer ist zwischen 40 und 50 Jahre alt. Und seine
gesammelten Zeiten:

M40
['2:30']
['2:30', '2:40', '3:10']

Lassen wir uns über dir() ausgeben, was so an Methoden und Eigenschaften unsere Klasse
und unser Objekt hat:

print(dir(Jogger))
print(dir(Laeufer_Hans))

Als Ergebnis bekommen wir:


© https://www.python-lernen.de/oop-vererbung-weiterdenken.htm Seite 319

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__',


'__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__',
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__',
'__subclasshook__', '__weakref__', 'zeiterfassen']

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__',


'__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__',
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__',
'__subclasshook__', '__weakref__', 'altersklasse', 'gelaufene_zeiten', 'zeiterfassen']

Und das Ganze übersichtlicher:

Die Klasse Jogger hat:

die Methode „zeiterfassung“

Das Objekt „Laeufer_Hans“ hat:

die Methode „zeiterfassung“ (logisch, ist ja aus Klasse „Jogger“ entstanden)

die Eigenschaft „altersklasse“

die Eigenschaft „gelaufene_zeiten“

Wenn wir nun für die Eigenschaft „gelaufene_zeiten“ Methoden wie es die Datenstruktur „Liste“
anbietet gerne anwenden würden, müssten wir selber neue Methoden schreiben. Aber Faulheit
siegt (zumindest, wenn man irgendwann auch mal Feierabend haben möchte).

Methoden von Datentyp „Liste“ erben


Also wollen wir die Methoden des Datentyps Liste („list“) erben. Unsere Klasse Jogger soll also
ein Kindelement von „list“ werden.

class Jogger(list):

Lassen wir uns jetzt wieder die Möglichkeiten des Objekts über dir() ausgeben:

print(dir(Jogger))

Jetzt stehen uns neben „zeiterfassung()“ auch alle Methoden von „list” zur Verfügung:

['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dict__', '__dir__', '__doc__',


'__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__',
'__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__module__', '__mul__',
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__',
'__setitem__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'append', 'clear', 'copy',
'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort', 'zeiterfassen']

Und diese wenden wir nun auch an – unser kompletter Code:


© https://www.python-lernen.de/oop-vererbung-weiterdenken.htm Seite 320

class Jogger(list):
""" sportliche Klasse für das Verwalten von gelaufenen Zeiten """

def __init__(self, altersklasse, zeit=[]):


self.altersklasse = altersklasse
self.gelaufene_zeiten = zeit

def zeiterfassen(self, zeiten):


self.gelaufene_zeiten += zeiten

Laeufer_Hans = Jogger("M40")
Laeufer_Hans.zeiterfassen(["2:30"])
Laeufer_Hans.zeiterfassen(["2:40", "3:10"])

# print(dir(Jogger))

print()
print("vor POP:")
print(Laeufer_Hans.gelaufene_zeiten)
print("POP:")
print(Laeufer_Hans.gelaufene_zeiten.pop())
print("nach POP:")
print(Laeufer_Hans.gelaufene_zeiten)

Und als Ergebnis erhalten wir wie erwartet nach der allgemeinen Methode pop() , die uns das
Objekt „Liste“ zur Verfügung stellt:

vor POP:

['2:30', '2:40', '3:10']

POP:

3:10

nach POP:

['2:30', '2:40']

Am Rande: die Methode pop() würde auch so in der Klasse zu Verfügung stehen :). Hier
sieht man auf jeden Fall, wie weit Klassen erben können und ich denke, das Wissen darum
kann sehr hilfreich sein.
© https://www.python-lernen.de/oop-unterschied-eigenschaften-und-variablen.htm Seite 321

Variablen (Unterschied zu Eigenschaften) in Klassen


nutzen
In der „normalen“ Programmierung spricht man viel über Variablen – was kann man nun in
Klassen damit anstellen (es sind nicht die Eigenschaften gemeint!)

Unsere Oberklasse „Tier“ bekommt eine Variable gleich nach der Anlage der Klasse:

class Tier():
""" Beispiel für Variablen in Klassen """
tieranzahl = 0

def __init__(self, rufname):


self.rufname = rufname

def anzahl_tiere(self):
print(" aktuelle Anzahl: ", Tier.tieranzahl)

Zusätzlich können wir und die Anzahl der Tiere über die Methode anzahl_tiere()
ausgeben lassen.

Unsere Kindklassen „Katze“ und „Hund“ greifen auf die Variable gleich am Anfang zu und
lassen diese ausgeben:

class Tier():
""" Beispiel für Variablen in Klassen """
tieranzahl = 0

def __init__(self, rufname):


self.rufname = rufname

def anzahl_tiere():
print("aktuelle Anzahl: ", Tier.tieranzahl)

class Katze(Tier):
""" Klasse für das Erstellen von Katzen """
print("Aus Klasse Katze: ", Tier.tieranzahl)

def __init__(self, rufname):


""" Initalisieren über Eltern-Klasse """
super().__init__(rufname)

class Hund(Tier):
""" Klasse für das Erstellen von Hunden """
print("Aus Klasse Hund: ", Tier.tieranzahl)

def __init__(self, rufname):


""" Initalisieren über Eltern-Klasse """
super().__init__(rufname)

Tier.anzahl_tiere()

Als Ergebnis erhalten wir:


© https://www.python-lernen.de/oop-unterschied-eigenschaften-und-variablen.htm Seite 322

Aus Klasse Katze: 0

Aus Klasse Hund: 0

aktuelle Anzahl: 0

Man sieht hier sehr schön, dass der „Kopfbereich“ der Klassen auf jeden Fall ausgeführt
werden. Somit erhalten wir sofort die Ausgabe „Aus Klasse Katze: 0“ und dasselbe beim Hund.
Erst dann rufen wir die Methode Tier.anzahl_tiere() auf.

Wir könnten die Variable auf außerhalb direkt abfragen

print(Tier.tieranzahl)

Und natürlich können wir überall die Variable setzen (auch außerhalb der Klassen und die
Anzahl innerhalb der Klasse würde sich ändern!). Einfach einmal probieren.

Tier.anzahl_tiere()
print(Tier.tieranzahl)
Tier.tieranzahl = 5
Tier.anzahl_tiere()

Nutzwert von Variablen in Klassen


Mit diesem Wissen können wir die Anzahl der generierten (sprich instanziierten) Objekte sehr
einfach erfassen.

Jedes Mal, wenn wir ein neues Objekt erstellen, wird die __init__ durchlaufen. Wenn wir
nun in beide (sowohl bei Hund wie Katze) dieses Variable erhöhen, können wir jederzeit die
Gesamtanzahl der aktuell erstellten Objekte (sprich wie viele Hunde und Katzen gibt es
insgesamt) abfragen:

class Katze(Tier):
""" Klasse für das Erstellen von Katzen """
print("Aus Klasse Katze: ", Tier.tieranzahl)

def __init__(self, rufname):


""" Initalisieren über Eltern-Klasse """
super().__init__(rufname)
Tier.tieranzahl += 1

Und nun basteln wir Tiere – sprich wir erzeugen Objekte in Form von einer Katze und zwei
Hunden:
© https://www.python-lernen.de/oop-unterschied-eigenschaften-und-variablen.htm Seite 323

Tier.anzahl_tiere()
katze_schnurri = Katze("Schnurri")
print(katze_schnurri.rufname)
Tier.anzahl_tiere()

hund_bello = Hund("Bello")
print(hund_bello.rufname)
Tier.anzahl_tiere()

hund_wedler = Hund("Wedler")
print(hund_wedler.rufname)
Tier.anzahl_tiere()

Als Ausgabe erhalten wir:

aktuelle Anzahl: 0

Schnurri

aktuelle Anzahl: 1

Bello

aktuelle Anzahl: 2

Wedler

aktuelle Anzahl: 3

Zur Sicherheit der komplette Code:


© https://www.python-lernen.de/oop-unterschied-eigenschaften-und-variablen.htm Seite 324

class Tier():
""" Beispiel für Variablen in Klassen """
tieranzahl = 0

def __init__(self, rufname):


self.rufname = rufname

def anzahl_tiere():
print("aktuelle Anzahl: ", Tier.tieranzahl)

class Katze(Tier):
""" Klasse für das Erstellen von Katzen """
# print("Aus Klasse Katze: ", Tier.tieranzahl)

def __init__(self, rufname):


""" Initalisieren über Eltern-Klasse """
super().__init__(rufname)
Tier.tieranzahl += 1

class Hund(Tier):
""" Klasse für das Erstellen von Hunden """
# print("Aus Klasse Hunde: ", Tier.tieranzahl)

def __init__(self, rufname):


""" Initalisieren über Eltern-Klasse """
super().__init__(rufname)
Tier.tieranzahl += 1

Tier.anzahl_tiere()
katze_schnurri = Katze("Schnurri")
print(katze_schnurri.rufname)
Tier.anzahl_tiere()

hund_bello = Hund("Bello")
print(hund_bello.rufname)
Tier.anzahl_tiere()

hund_wedler = Hund("Wedler")
print(hund_wedler.rufname)
Tier.anzahl_tiere()
© https://www.python-lernen.de/oop-eigenschaften-zugriff-absichern.htm Seite 325

Eigenschaften vor Zugriff absichern


Im letzten Kapitel haben wir gesehen, wie einfach wir von außen auf Variablen (und auch
Eigenschaften) zugreifen und diese beliebig ändern können.

Dies ist je nach Anwendung fatal!

Nehmen wir an, wir sind eine Bank (die fiktive Kontinentalbank) und verwalten Konten und Geld
für unsere Kunden.

Also brauchen wir eine Klasse, die sowohl Konten (mit einer Kontonummer) und aktuelles
Guthaben verwaltet.

class Konto:
""" unsere kleines Bankprogramm zum Verwalten Konten/Geld """

def __init__(self, kontonummer, kontostand=0):


self.kontonummer = kontonummer
self.kontostand = kontostand

def geld_abheben(self, betrag):


self.kontostand -= betrag

def geld_einzahlen(self, betrag):


self.kontostand += betrag

def kontostand_anzeigen(self):
print("aktueller Kontostand: ", self.kontostand)

kunde_schulz = Konto("000111555")
kunde_schulz.kontostand_anzeigen()

Jetzt kann der Kunde Geld einzahlen:

kunde_schulz = Konto("000111555")
kunde_schulz.kontostand_anzeigen()
kunde_schulz.geld_einzahlen(150)
kunde_schulz.kontostand_anzeigen()

Bei Banken und Buchführung gibt es immer doppelte Buchführung – es darf nichts nicht
nachvollziehbar sein. Wir realisieren dies in kleiner Form, in dem wir (wie im letzten Kapitel
schon gezeigt) eine Bestandszahl mitführen, wie viel Geld insgesamt gerade in der Bank sein
müsste und geben Einzahlungen, Auszahlungen und den Gesamtbestand aus:
© https://www.python-lernen.de/oop-eigenschaften-zugriff-absichern.htm Seite 326

class Konto:
""" unsere kleines Bankprogramm zum Verwalten Konten/Geld """
geldbestand = 0

def __init__(self, kontonummer, kontostand=0):


self.kontonummer = kontonummer
self.kontostand = kontostand

def geld_abheben(self, betrag):


print("Geld wird abgehoben:", betrag)
self.kontostand -= betrag
Konto.geldbestand -= betrag

def geld_einzahlen(self, betrag):


print("Geld wird eingezahlt:", betrag)
self.kontostand += betrag
Konto.geldbestand += betrag

def kontostand_anzeigen(self):
print("aktueller Kontostand: ", self.kontostand)
print("aktueller Geldbestand der Bank: ", Konto.geldbestand, "\n")

Wir lassen den Kunden Schulz 2-mal einzahlen und einmal abheben:

kunde_schulz = Konto("000111555")
kunde_schulz.kontostand_anzeigen()
kunde_schulz.geld_einzahlen(150)
kunde_schulz.kontostand_anzeigen()
kunde_schulz.geld_einzahlen(250)
kunde_schulz.kontostand_anzeigen()
kunde_schulz.geld_abheben(75)
kunde_schulz.kontostand_anzeigen()

Als Ergebnis erhalten wir:

aktueller Kontostand: 0
aktueller Geldbestand der Bank: 0

Geld wird eingezahlt: 150


aktueller Kontostand: 150
aktueller Geldbestand der Bank: 150

Geld wird eingezahlt: 250


aktueller Kontostand: 400
aktueller Geldbestand der Bank: 400

Geld wird abgehoben: 75


aktueller Kontostand: 325
aktueller Geldbestand der Bank: 325

So weit, so gut. Die Rechnung passt: 150 + 250 -75 = 325 (was auch der aktuelle Geldbestand
der Bank zeigt).
© https://www.python-lernen.de/oop-eigenschaften-zugriff-absichern.htm Seite 327

Was passiert aber, wenn unser Kunde ein Schlitzohr ist? Er betätigt sich einfach eines direkten
Zugriffs. Vor dem letzten Abheben erhöht er einfach einmal sein Kontostand um 1000.

kunde_schulz = Konto("000111555")
kunde_schulz.kontostand_anzeigen()
kunde_schulz.geld_einzahlen(150)
kunde_schulz.kontostand_anzeigen()
kunde_schulz.geld_einzahlen(250)
kunde_schulz.kontostand_anzeigen()
kunde_schulz.kontostand += 1000
kunde_schulz.geld_abheben(75)
kunde_schulz.kontostand_anzeigen()

Und schon haben wir ein massives Problem – die Kontrollzahl weicht von dem Kontostand ab:

aktueller Kontostand: 1325


aktueller Geldbestand der Bank: 325

Die Kontinentalbank leidet gewissermaßen an „Inkontinenz“, Geld verrinnt.

Das müssen wir verhindern!

Unser bisher kritischer Code komplett:


© https://www.python-lernen.de/oop-eigenschaften-zugriff-absichern.htm Seite 328

class Konto:
""" unsere kleines Bankprogramm zum Verwalten Konten/Geld """
geldbestand = 0

def __init__(self, kontonummer, kontostand=0):


self.kontonummer = kontonummer
self.kontostand = kontostand

def geld_abheben(self, betrag):


print("Geld wird abgehoben:", betrag)
self.kontostand -= betrag
Konto.geldbestand -= betrag

def geld_einzahlen(self, betrag):


print("Geld wird eingezahlt:", betrag)
self.kontostand += betrag
Konto.geldbestand += betrag

def kontostand_anzeigen(self):
print("aktueller Kontostand: ", self.kontostand)
print("aktueller Geldbestand der Bank: ", Konto.geldbestand, "\n")

kunde_schulz = Konto("000111555")
kunde_schulz.kontostand_anzeigen()
kunde_schulz.geld_einzahlen(150)
kunde_schulz.kontostand_anzeigen()
kunde_schulz.geld_einzahlen(250)
kunde_schulz.kontostand_anzeigen()
kunde_schulz.kontostand += 1000
kunde_schulz.geld_abheben(75)
kunde_schulz.kontostand_anzeigen()

Eigenschaften (und auch Variablen) dürfen nicht von außen veränderbar sein. Auch hier hilft
uns Python. Wir können die Sichtbarkeit von Eigenschaften und Variablen einschränken:

Sichtbarkeit von Eigenschaften/Variablen in der OOP


Wir können die „Nutzbarkeit“ von Variablen einschränken über folgende Schreibweisen:

public standard, kann auch von Außerhalb der Klassen genutzt und geändert werden

protect Schreibweise: _1Unterstrichamanfang


kann in eigener Klasse und davon abgeleiteten Klassen verwendet werden

privat Schreibweise: __2Unterstricheamanfang


kann nur in innerhalb eigener Klasse genutzt werden

Das bedeutet, dass wir unsere Eigenschaften und Variablen als privat auszeichnen müssen.

Weil wir ein sicherheitsbewusster Programmierer sind, werden alle verwendeten Eigenschaften
und Variablen als „privat“ mit den 2 Unterstrichen am Anfang gekennzeichnet.
© https://www.python-lernen.de/oop-eigenschaften-zugriff-absichern.htm Seite 329

class Konto:
""" unsere kleines Bankprogramm zum Verwalten Konten/Geld """
__geldbestand = 0

def __init__(self, kontonummer, kontostand=0):


self.__kontonummer = kontonummer
self.__kontostand = kontostand

def geld_abheben(self, betrag):


print("Geld wird abgehoben:", betrag)
self.__kontostand -= betrag
Konto.__geldbestand -= betrag

def geld_einzahlen(self, betrag):


print("Geld wird eingezahlt:", betrag)
self.__kontostand += betrag
Konto.__geldbestand += betrag

def kontostand_anzeigen(self):
print("aktueller Kontostand: ", self.__kontostand)
print("aktueller Geldbestand der Bank: ", Konto.__geldbestand, "\n")

Ab jetzt ist weder das direkte Abfragen von Variablen/Eigenschaften noch das Setzen von
Werten außerhalb der Klasse möglich. Ein Versuch endet mit einer Fehlermeldung:

kunde_schulz = Konto("000111555")
kunde_schulz.kontostand_anzeigen()
kunde_schulz.geld_einzahlen(150)
kunde_schulz.__kontostand += 1000

Es kommt als Fehlermeldung: „AttributeError: 'Konto' object has no attribute '__kontostand'“

Wir können weder etwas verändern noch abfragen von außen.

Bank gerettet!

Was passiert, wenn wir mit einer Kindklasse auf die geschützten Werte zugreifen wollen?

Zugriff auf geschützte Eigenschaften über Kindklasse


Wir wollen eine Klasse erstellen, welche die Konto-Klasse beerbt. Wann kann das erforderlich
sein? Seit ein paar Jahre gibt es das sogenannte „Guthabenkonto“. Diese wurde für insolvente
bzw. überschuldete Menschen eingeführt und bei diesen Konten gibt es nicht die Möglichkeit
der Überziehung.

Diese ist für uns natürlich die ideale Übung als Kindeklasse eines normalen Kontos.

Auszahlen finden nur statt, wenn der gewählte Betrag nicht das Konto in das Minus treiben
würde.

Allerdings kommt nun als Erschwerung dazu, dass wir nicht mehr so einfach Zugriff auf alle
Werte und Eigenschaften der Klasse „Konto“ haben, da diese als „__privat“ gekennzeichnet
sind.

Aber einen Schritt nach dem anderen!


© https://www.python-lernen.de/oop-eigenschaften-zugriff-absichern.htm Seite 330

Wir erstellen unsere Kindklasse „Pluskonto“:

class Pluskonto(Konto):
""" ein Konto, dass nicht überzogen werden kann """

def __init__(self, kontonummer, kontostand=0):


""" Initalisieren über Eltern-Klasse """
super().__init__(kontonummer, kontostand=0)

def geld_abheben(self, betrag):


print("Geld soll vom Pluskonto abgehoben werden:", betrag)

Jetzt wollen wir auf den Kontostand der Elternklasse „Konto“ zugreifen. Was bisher einfach
funktionierte, geht durch die __privat gesetzten Eigenschaften nicht mehr. Aber wir benötigen ja
nur den Wert um vergleichen zu können, ob das Konto ins Minus gehen würde und wollen
diesen nicht verändert.

Also programmieren wir uns eine Methode in der Elternklasse, die uns diesen Wert liefert:

class Konto:
""" unsere kleines Bankprogramm zum Verwalten Konten/Geld """
__geldbestand = 0

def __init__(self, kontonummer, kontostand=0):


self.__kontonummer = kontonummer
self.__kontostand = kontostand

def geld_abheben(self, betrag):


print("Geld wird abgehoben:", betrag)
self.__kontostand -= betrag
Konto.__geldbestand -= betrag

def geld_einzahlen(self, betrag):


print("Geld wird eingezahlt:", betrag)
self.__kontostand += betrag
Konto.__geldbestand += betrag

def kontostand_anzeigen(self):
print("aktueller Kontostand: ", self.__kontostand)
print("aktueller Geldbestand der Bank: ", Konto.__geldbestand, "\n")

def kontostand_aktuell(self):
return self.__kontostand

Die letzte Methode kontostand_aktuell(self) liefert uns den aktuellen Wert über
return zurück:

Auf diesen können wir in der Kindklasse „Pluskonto“ zugreifen und zum Vergleich heranziehen:
© https://www.python-lernen.de/oop-eigenschaften-zugriff-absichern.htm Seite 331

def geld_abheben(self, betrag):


print("Geld soll vom Pluskonto abgehoben werden:", betrag)
print("Maximal verfügbar ist gerade:", self.kontostand_aktuell())

if self.kontostand_aktuell() - betrag >= 0:


print("Auszahlen von Pluskonto: ", betrag)
else:
print("Sorry, Konto kann nicht überzogen werden!")

Jetzt müssen wir noch das Geld verbuchen!

Wir können von der Kindklasse auf die Methoden der Elternklasse über
super().geld_abheben() zugreifen. Dies ergänzen wir innerhalb unserer if-Abfrage.

def geld_abheben(self, betrag):


print("Geld soll vom Pluskonto abgehoben werden:", betrag)
print("Maximal verfügbar ist gerade:", self.kontostand_aktuell())

if self.kontostand_aktuell() - betrag >= 0:


print("Auszahlen von Pluskonto: ", betrag)
super().geld_abheben(betrag)
else:
print("Sorry, Konto kann nicht überzogen werden!")

Der vollständige Code:


© https://www.python-lernen.de/oop-eigenschaften-zugriff-absichern.htm Seite 332

class Konto:
""" unsere kleines Bankprogramm zum Verwalten Konten/Geld """
__geldbestand = 0

def __init__(self, kontonummer, kontostand=0):


self.__kontonummer = kontonummer
self.__kontostand = kontostand

def geld_abheben(self, betrag):


print("Geld wird abgehoben:", betrag)
self.__kontostand -= betrag
Konto.__geldbestand -= betrag

def geld_einzahlen(self, betrag):


print("Geld wird eingezahlt:", betrag)
self.__kontostand += betrag
Konto.__geldbestand += betrag

def kontostand_anzeigen(self):
print("aktueller Kontostand: ", self.__kontostand)
print("aktueller Geldbestand der Bank: ", Konto.__geldbestand, "\n")

def kontostand_aktuell(self):
return self.__kontostand

class Pluskonto(Konto):
""" ein Konto, dass nicht überzogen werden kann """

def __init__(self, kontonummer, kontostand=0):


""" Initalisieren über Eltern-Klasse """
super().__init__(kontonummer, kontostand=0)

def geld_abheben(self, betrag):


print("Geld soll vom Pluskonto abgehoben werden:", betrag)
print("Maximal verfügbar ist gerade:", self.kontostand_aktuell())

if self.kontostand_aktuell() - betrag >= 0:


print("Auszahlen von Pluskonto: ", betrag)
super().geld_abheben(betrag)
else:
print("Sorry, Konto kann nicht überzogen werden!")

kunde_minderjaehrig = Pluskonto("0000935")
kunde_minderjaehrig.kontostand_anzeigen()
kunde_minderjaehrig.geld_einzahlen(200)
kunde_minderjaehrig.geld_abheben(101)
kunde_minderjaehrig.kontostand_anzeigen()

Sicherheit benötigt also ein wenig mehr Arbeit – ist aber problemlos machbar, wenn man weiß
wie.
© https://www.python-lernen.de/oop-eigenschaften-zugriff-absichern.htm Seite 333
© https://www.python-lernen.de/oop-import-klassen-auslagern.htm Seite 334

Klassen auslagern
Unsere erstellten Klassen benötigen Platz und wenn alles sich in einer Datei befindet, wird es
unübersichtlich. Daher ist eine gute Vorgehensweise, die Klassen als Module auszulagern und
einfach zu importieren.

Aus dem Bank-Beispiel aus dem letzten Kapitel machen wir ein Modul. Der Modulname ist
„konto.py“. Die Benennung ist sehr wichtig, da wir beim Import die Datei in der Form from
konto import Konto ohne Dateiendung „.py“ angeben!

Der Inhalt der Datei „konto.py“ – vorneweg der DOCstring für die Hilfe nicht vergessen:
© https://www.python-lernen.de/oop-import-klassen-auslagern.htm Seite 335

""" Klasse Konto und Pluskonto zum verwalten, ein- und auszahlen von Bankkonten """

class Konto:
""" unsere kleines Bankprogramm zum Verwalten Konten/Geld """
__geldbestand = 0

def __init__(self, kontonummer, kontostand=0):


self.__kontonummer = kontonummer
self.__kontostand = kontostand

def geld_abheben(self, betrag):


print("Geld wird abgehoben:", betrag)
self.__kontostand -= betrag
Konto.__geldbestand -= betrag

def geld_einzahlen(self, betrag):


print("Geld wird eingezahlt:", betrag)
self.__kontostand += betrag
Konto.__geldbestand += betrag

def kontostand_anzeigen(self):
print("aktueller Kontostand: ", self.__kontostand)
print("aktueller Geldbestand der Bank: ", Konto.__geldbestand, "\n")

def kontostand_aktuell(self):
return self.__kontostand

class Pluskonto(Konto):
""" ein Konto, dass nicht überzogen werden kann """

def __init__(self, kontonummer, kontostand=0):


""" Initalisieren über Eltern-Klasse """
super().__init__(kontonummer, kontostand=0)

def geld_abheben(self, betrag):


print("Geld soll vom Pluskonto abgehoben werden:", betrag)
print("Maximal verfügbar ist gerade:", self.kontostand_aktuell())

if self.kontostand_aktuell() - betrag >= 0:


print("Auszahlen von Pluskonto: ", betrag)
super().geld_abheben(betrag)
else:
print("Sorry, Konto kann nicht überzogen werden!")

Und jetzt stehen und 5 Varianten zum Import zur Verfügung:


© https://www.python-lernen.de/oop-import-klassen-auslagern.htm Seite 336

# eine von den 5 wählen!


from konto import *

# oder
from konto import Konto

# oder
from konto import Pluskonto

# oder
from konto import Konto, Pluskonto

# oder
import konto

Warum gibt es da so viel Auswahl? Wir haben in unserem Modus sowohl die Klasse „Konto“
wie die Klasse „Pluskonto“.

from konto import Konto


Über die Anweisung from konto import Konto sagen wir, lade die Datei „konto.py“ und
verwende die Klasse „Konto“. Die Kindklasse „Pluskonto“ steht nicht zur Verfügung und wir
bekommen eine Fehlermeldung beim Aufruf der Klasse „Pluskonto“.

from konto import Konto

# funktioniert
kunde_minderjaehrig = Konto("0000935")

# FEHLERMELDUNG NameError: name 'Pluskonto' is not defined


kunde_minderjaehrig = Pluskonto("0000935")

from konto import Pluskonto


Über die Anweisung from konto import Pluskonto laden wir aus dem Modul „konto“
nur das Pluskonto und können auch dieses nutzen (auch wenn dieses Intern auf Konto
zugreift):

from konto import Pluskonto

# FEHLERMELDUNG (und bricht dann ab, das Zugriff unten würde funktionieren
kunde_minderjaehrig = Konto("0000935")

# funktioniert
kunde_minderjaehrig = Pluskonto("0000935")

import konto
Über die Anweisung import konto laden wir das gesamte Modul, allerdings müssen wir mit
dem Aufruf „Modulname.klassenname“ auf die Klassen zugreifen!
© https://www.python-lernen.de/oop-import-klassen-auslagern.htm Seite 337

import konto

# Zugriff über "Modulname.klassenname"!


kunde_minderjaehrig = konto.Konto("0000935")

# bzw.
kunde_minderjaehrig = konto.Pluskonto("0000935")

from konto import *


Über die Anweisung from konto import * laden wir beide Modul, die wir dann nutzen
können. Im Vergleich zum import konto (siehe Punkt davor) müssen wir keine weiteren
Angaben machen!

from konto import *

# funktioniert
kunde_minderjaehrig = Konto("0000935")

# funktioniert
kunde_minderjaehrig = Pluskonto("0000935")

Macht man ungern um Namenskonflikte zu vermeiden und man sieht auch so nicht, welche
Klassen eigentlich genutzt werden. Daher besser gleich folgende Variante!

from konto import Konto, Pluskonto


Über die Anweisung from konto import Konto, Pluskonto laden wir beide Modul, die
wir dann nutzen können:

from konto import Konto, Pluskonto

# funktioniert
kunde_minderjaehrig = Konto("0000935")

# funktioniert
kunde_minderjaehrig = Pluskonto("0000935")

Fertiger Code in auszuführender Datei


Und hier nun unser fertiger Code mit der Variante für den Import beider Klassen:
© https://www.python-lernen.de/oop-import-klassen-auslagern.htm Seite 338

from konto import Konto, Pluskonto

kunde_schulz = Konto("000111555")
kunde_schulz.kontostand_anzeigen()
kunde_schulz.geld_einzahlen(400)
kunde_schulz.geld_abheben(150)
kunde_schulz.kontostand_anzeigen()

kunde_minderjaehrig = Pluskonto("0000935")
kunde_minderjaehrig.kontostand_anzeigen()
kunde_minderjaehrig.geld_einzahlen(200)
kunde_minderjaehrig.geld_abheben(101)
kunde_minderjaehrig.kontostand_anzeigen()

Als Ausgabe erhalten wir:

aktueller Kontostand: 0
aktueller Geldbestand der Bank: 0

Geld wird eingezahlt: 400


Geld wird abgehoben: 150
aktueller Kontostand: 250
aktueller Geldbestand der Bank: 250

aktueller Kontostand: 0
aktueller Geldbestand der Bank: 250

Geld wird eingezahlt: 200


Geld soll vom Pluskonto abgehoben werden: 101
Maximal verfügbar ist gerade: 200
Auszahlen von Pluskonto: 101
Geld wird abgehoben: 101
aktueller Kontostand: 99
aktueller Geldbestand der Bank: 349

Wer nachrechnen will, das passt mit der doppelten Buchführung so :).
© https://www.python-lernen.de/python-datenbanksysteme.htm Seite 339

Python und Datenbanken


Python bietet sehr einfach die Nutzung von Datenbankmanagementsysteme (DBMS) an. Im
Folgenden wird anstelle des sperrigen Wortes einfach von Datenbanksystem gesprochen. Was
ist der Vorteil eines Datenbanksystems?

Wir trennen dadurch Daten von Programm und müssen uns nicht kümmern um:

die Speicherung der Daten

die Verwaltung der Daten

Wir übergeben einfach unserer Datenbank unsere Daten und im Folgenden können wir dann
über unser Programm bestimmen, was mit den Daten passieren soll. Meistens möchte man
diese in irgendeiner Form auswerten oder einfach nur ausgeben. Wobei bei der Ausgabe gerne
eine Auswahl (Selektion) stattfindet, damit nur gerade benötigte Daten angezeigt werden.

Konkretes Beispiel, das wir Schritt für Schritt umsetzen


Wie sieht das in einem konkreten Beispiel aus?

Wir wollen einen Geburtstagswarner programmieren, der seine Daten in einer Datenbank
speichert. Dazu benötigen wir Vorname, Nachname und das Datum des Geburtstags. Wer mag,
kann noch Telefonnummer und E-Mail mit in die Daten aufnehmen. Im ersten Schritt müssen
die Daten über ein Formular eingegeben und gespeichert werden können.

Diese Daten können durchsucht werden.

Zusätzlich können die Daten ausgegeben werden mit der gewünschten Sortierreihenfolge, z.B.
nach dem Vornamen oder Nachnamen oder Geburtsdatum.

Und als Bonbon sollen immer die kommenden 3 Geburtstage beim Start des Programms
angezeigt werden. Wir haben hier also eine Selektion der Daten nach einem bestimmten
Kriterium und eine sortierte Ausgabe.

Und zu guter Letzt wollen wir auch wieder Daten ändern (Tippfehler kommen vor) und auch
löschen (manchen Menschen möchte man nicht mehr zum Geburtstag gratulieren) können.

Das zur Funktion. Was bietet uns Python zum Thema Datenbanken?

Verschiedene Datenbanksysteme
Mit Python können wir verschiedene Datenbanksysteme wie MySQL, SQLite, Oracle,
PostgreSQL und weitere Datenbanken nutzen.

Über ein Datenbanksystem kann man sehr einfach Daten verwalten. Dazu gehört:

Datensätze anlegen

Datensätze löschen

Daten ändern

Daten suchen

Daten sortieren
© https://www.python-lernen.de/python-datenbanksysteme.htm Seite 340

Im folgenden Kapitel wollen wir mit SQLite arbeiten. Diese Variante ist ein optimaler Einstieg in
das Thema Datenbanken. Die grundsätzliche Programmierung ist bei allen Datenbanken die
Gleiche. Der Vorteil bei SQLite ist, dass dieses bereits als Modul in Python vorhanden ist und
direkt als Datei bei dem Softwareprojekt eingebettet ist. Wer im Dateisystem nachsehen mag –
es ist eine „.db“ -Datei.

Der große Vorteil für den Einsteiger ist: Wir müssen keine Client-Server-Datenbank wie
beispielsweise bei MySQL installieren. So kann auch sehr einfach die Anwendung mit der
Datenbank und bereits erfasste Daten weitergegeben werden.

Aber Schritt für Schritt.

Unsere Lernanwendung für Datenbank-Nutzung


Im Folgenden wollen wir die Anwendung „Geburtstagswarner“ programmieren, die Geburtstage
verwaltet. Dafür nutzen wir die folgenden Datenfelder:

Vorname

Nachname

Geburtstag

Als Aktionen gibt es:

Datensatz anlegen

anzeigen

ändern

löschen

suchen

sortieren

Dies setzen wir Schritt für Schritt in den folgenden Kapiteln um und lernen so den Umgang mit
Datenbanken in Python.
© https://www.python-lernen.de/sqlite-vorgehensweise.htm Seite 341

Grundsätzliche Vorgehensweise für Nutzung von


Datenbankzugriffen (hier SQLite)
Für die Nutzung von Datenbanken mit Python gibt es eine grundsätzliche Vorgehensweise, die
wir in 5 Schritten hier ansehen möchten. Dabei ist für die meisten verfügbaren Datenbanken
(im folgenden SQLite) die Vorgehensweise nahezu identisch. Im folgenden Kapitel bauen wir
eine Verbindung zur Datenbank auf und führen eine Aktion mit der Datenbank aus (im Beispiel
erzeugen wir eine leere Tabelle).

Wir starten mit SQLite, weil es uns gleich mehrere Vorteile bietet (wie in der einführenden
Beschreibung erwähnt). Es ist bereits in Python vorhanden und das Modul kann einfach
importiert werden. Die Daten selber werden in einer Datei mit der Dateiendung „.db“
gespeichert und können somit problemlos weitergegeben werden.

erster Schritt: SQL-Modul importieren


Als Erstes müssen wir unser SQL-Modul importieren:

import sqlite3

Die folgenden 5 Schritte sind für die Interaktion mit Datenbanken meistens notwendig:

Verbindung zur Datenbank herstellen

Cursor-Objekt (zum Zugriff auf die Datenbank)

SQL-Query übergeben

commit: wir bestätigen der Datenbank, dass wir die SQL-Anweisung wirklich ausführen lassen
wollen

Schließen der Datenbankverbindung (Ordnung muss sein)

Schritt 1: Unsere Verbindung zur Datenbank aufbauen


Wir wollen nun eine Verbindung zu unserer Datenbank aufbauen. Dazu benötigen wir einen
Datenbanknamen, auf den wir dann über eine Variable (Zeiger) zugreifen können.

Schauen wir uns erst den Befehl an und dann kommt die Erklärung:

verbindung = sqlite3.connect("geburtstage.db")

Wir bauen also eine Verbindung (engl. „connection“ und das Verb verbinden „connect“) zu
unserer Datenbank „geburtstage.db“ auf. Gibt es diese Datenbank noch nicht, legt unser
Datenbanksystem „SQLite“ automatisch beim ersten Aufruf eine Datei im selben Ordner an.

Möchte man es nicht im gleichen Ordner wie die Python-Programme haben, dann einfach den
gewünschten Unterordner angeben (der Unterordner sollte bereits angelegt sein):

verbindung = sqlite3.connect("datenbank/geburtstage.db")

Ist der Ordner nicht angelegt, schlägt das Anlegen der Datenbank fehl und wir erhalten die
Fehlermeldung: „sqlite3.OperationalError: unable to open database file“

Also einfach Ordner im Betriebssystem anlegen, bevor wir unseren connect -Befehl darauf
loslassen!
© https://www.python-lernen.de/sqlite-vorgehensweise.htm Seite 342

Schritt 2: Cursor-Objekt cursor()


Im nächsten Schritt wird das Cursor-Objekt eingerichtet. Was ist ein Cursor eigentlich? Man
verwendet schon immer auf dem Bildschirm den Cursor, hat sich aber noch nie gefragt, woher
dieses Wort wohl kommt. Wie das meiste entweder aus dem Lateinischen oder Griechischen.
Im Lateinischen hat das Wort Cursor die Bedeutung von „Läufer“. Mit dem Cursor wird die
aktuelle Bearbeitungsposition auf dem Bildschirm gezeigt. Mit dem Datenbankcursor das
gleiche – aber auf den Datenbanksatz bezogen. Er zeigt also die aktuelle Position beim Lesen
bzw. Schreiben von Datensätzen.

So ein Objekt wollen wir nun erzeugen:

import sqlite3
verbindung = sqlite3.connect("datenbank/geburtstage.db")
zeiger = verbindung.cursor()

Ab jetzt können wir unseren Zeiger verwenden.

Schritt 3: SQL-Code erstellen und an Datenbank senden:


execute()
Jetzt können wir unsere SQL-Anweisung an die Datenbank übergeben. Mit dieser Anweisung
sagen wir der Datenbank, was zu tun ist: Ob Beispielsweise ein neuer Datensatz angelegt wird
oder die Datenbank bestimmte Datensätze zurückliefern soll, damit wir diese anzeigen können.
Die Übergabe läuft als String ab. Mit der Anweisung execute() wird die SQL-Anweisung
ausgeführt.

Bisher haben wir eine Datenbank mit dem Namen „geburtstage.db“. Allerdings haben wir noch
keine Tabellen in der Datenbank. Grundsätzlich wäre der Aufbau unseres execute -Befehls:

zeiger.execute(SQL-Anweisung)

Was steht nun in unserer SQL-Anweisung?

Eine Tabelle besteht wie in Excel aus Zeilen und Spalten. In Excel wird für die Spalten
automatisch die Benennung „A, B, C, … AA, AB“ verwendet. Das wäre für uns eher unpraktisch.
Im Unterschied zu Excel vergeben wir also für unsere Datenbank für jede Spalte:

einen Namen (damit wir die „Spalte“ ansprechen können)

die Art der Inhalte (String, Integer, Datum etc.)

die Feldlänge

Wir erzeugen (engl. „create“) eine Tabelle (engl. „table“) die einen Namen hat.

zeiger.execute("CREATE TABLE personen (vorname VARCHAR(20), nachname VARCHAR(30), geburtst

Gerne wird eine SQL-Anweisung auch als String vorbereitet und dann dieser String der
Anweisung execute übergeben. Das macht die SQL-Anweisung besser lesbar und somit
können sich Fehler nicht so einfach einschleichen. Also nochmals die gleiche Anweisung wie
oben:
© https://www.python-lernen.de/sqlite-vorgehensweise.htm Seite 343

sql_anweisung = """
CREATE TABLE personen (
vorname VARCHAR(20),
nachname VARCHAR(30),
geburtstag DATE
);"""

zeiger.execute(sql_anweisung)

Schritt 4: Anweisung ausführen lassen mit commit()


Beim Verändern von Daten in der Datenbank ist eine weitere Bestätigung zum Ausführen
notwendig. Die übergebene SQL-Anweisung muss nun ausgeführt werden. Dazu wird über den
Befehl commit() dem Datenbanksystem mitgeteilt, dass endgültig die Anweisung ausgeführt
werden darf. In unserem Beispiel wird also die Tabelle angelegt:

import sqlite3
verbindung = sqlite3.connect("datenbank/geburtstage.db")
zeiger = verbindung.cursor()

sql_anweisung = """
CREATE TABLE personen (
vorname VARCHAR(20),
nachname VARCHAR(30),
geburtstag DATE
);"""

zeiger.execute(sql_anweisung)

verbindung.commit()

Schritt 5: Verbindung schließen mit close()


Aufräumen ist immer eine gute Sache. Also schließen wir die Verbindung nach getaner Arbeit
über die Anweisung close()

verbindung.close()

kompletter Code zum Tabelle anlegen


Und hier unser kompletter Code:
© https://www.python-lernen.de/sqlite-vorgehensweise.htm Seite 344

import sqlite3
verbindung = sqlite3.connect("datenbank/geburtstage.db")
zeiger = verbindung.cursor()

sql_anweisung = """
CREATE TABLE personen (
vorname VARCHAR(20),
nachname VARCHAR(30),
geburtstag DATE
);"""

zeiger.execute(sql_anweisung)

verbindung.commit()
verbindung.close()

Jetzt können wir unser Programm ausführen lassen und erhalten unsere Datenbank angelegt.
Auch wenn es noch keine Inhalte gibt, wird die Datei „geburtstage.db“ erzeugt und besitzt eine
Dateigröße (es steckt jetzt die vorbereitete Struktur darin).

Lassen wir den Code nochmals ausführen, bekommen wir eine Fehlermeldung:

sqlite3.OperationalError: table personen already exists

Diesen Fehler können wir vermeiden, indem wir die SQL-Anweisung nur ausführen lassen, wenn
noch keine Tabelle existiert. Wir erweitern dazu unsere SQL-Anweisung um „IF NOT EXISTS”:

sql_anweisung = """
CREATE TABLE IF NOT EXISTS personen (
vorname VARCHAR(20),
nachname VARCHAR(30),
geburtstag DATE
);"""
© https://www.python-lernen.de/sqlite-insert-into-datensatz-speichern.htm Seite 345

Daten in Datenbank speichern: INSERT INTO


Auch zum Eintragen von Daten in die Datenbank gibt es die entsprechende SQL-Anweisung.
Diese lautet INSERT INTO . Als Nächstes muss die entsprechende Tabelle angegeben
werden:

INSERT INTO tabellennamen

In unserem Beispiel in die Tabelle mit dem Namen „personen“:

INSERT INTO personen

Jetzt werden im nächsten Schritt die Daten (engl. „values“) übergeben – die Daten werden in
Klammern geschrieben:

INSERT INTO personen VALUES ()

Die Daten werden in der Reihenfolge eingegeben, wie wir die Felder festgelegt haben. Also in
unserem Beispiel: vorname, nachname, geburtstag

Wir wollen unseren „Johann Wolfgang von Goethe“ mit aufnehmen. Geboren wurde er am
28.8.1749.

Unsere SQL-Anweisung ergänzen wir entsprechend:

INSERT INTO personen VALUES (Johann Wolfgang von Goethe 28.8.1749)

So weit, so gut. In diesem Fall, nicht gut. Warum? Die Datenbank weiß nicht, was
zusammengehört: wo hört der Vorname auf und wo fängt der Nachname an. Daher werden
Daten, die zu einem Feld gehören, jeweils in Anführungszeichen gesetzt. Dabei nutzt man
sehr gerne einfache Anführungszeichen, da unsere SQL-Anweisung selber oft als String
erstellt wird.

Probieren wir es aus:

INSERT INTO personen VALUES ('Johann Wolfgang von', 'Goethe', '28.8.1749')

Ob das nun passt oder nicht, sagt uns einfach die Reaktion der Datenbank. Also testen!

Unser kompletter Python-Code bisher:


© https://www.python-lernen.de/sqlite-insert-into-datensatz-speichern.htm Seite 346

import sqlite3
verbindung = sqlite3.connect("datenbank/geburtstage.db")
zeiger = verbindung.cursor()

sql_anweisung = """
CREATE TABLE IF NOT EXISTS personen (
vorname VARCHAR(20),
nachname VARCHAR(30),
geburtstag DATE
);"""

zeiger.execute(sql_anweisung)

sql_anweisung = """
INSERT INTO personen VALUES ('Johann Wolfgang von', 'Goethe', '28.8.1749')
"""

zeiger.execute(sql_anweisung)

verbindung.commit()
verbindung.close()

Beim Ausführen bekommen wir keine Fehlermeldung. Scheint also geklappt zu haben.
Spannend wird es, wenn wir die Daten wieder auslesen. Wenn die Daten exakt so wieder
herauskommen, dann passt es. Oder doch nicht?

Wer auf die Auflösung der Anmerkung nicht warten kann, hier der Typ dazu. In SQLite
unterstützt die folgenden Datentypen: INTEGER, REAL, TEXT, BLOB und NULL. Wenn mir mit
DATE ums Eck kommen, kommt zwar keine Fehlermeldung aber effektiv wird es als TEXT
gespeichert! Gespeichert ist es, nur mit Datum „rechnen“ können wir erst nach irgendwelchen
Umwandlungsaktion über Python.

Variablen nutzen für die INSERT -SQL-Anweisung


Gerade haben wir eine SQL-Anweisung über INSERT INTO aufgebaut und direkt in der SQL-
Anweisung die Daten mitgegeben. Das wird in den seltensten Fällen zielführend sein.
Meistens liegen uns Werte in Variablen vor, die z.B. über Nutzereingaben erfasst worden
sind.

Bauen wir also unsere SQL-Anweisung über Variablen auf. Wir bleiben beim gleichen Beispiel
oben und ergänzen weitere bekannte Namen in unserer Datenbank, die man schon immer mal
gerne in seiner Adressliste gehabt hätte.

nachname = "Schiller"
vorname = "Friedrich"
geburtstag = "10.11.1759"

Und jetzt bauen wir eine SQL-Anweisung (die noch nicht optimal ist!):

zeiger.execute("INSERT INTO personen VALUES (vorname, nachname, geburtstag)")

Warum ist diese Vorgehensweise so nicht gut? Über solche Konstruktionen wird die
Datenbank anfällig für SQL-Injektions. Sprich von außen wird schadhafter Code eingebracht,
der dann unter Umständen direkt ausgeführt wird. Schlimmstenfalls könnte die komplette
© https://www.python-lernen.de/sqlite-insert-into-datensatz-speichern.htm Seite 347

Datenbank gelöscht oder Daten ausgespäht werden.

Daher wollen wir die Daten nicht ungeprüft übergeben. Der folgende Aufbau filtert die
größten Probleme heraus:

zeiger.execute("INSERT INTO personen VALUES (?,?,?)", (vorname, nachname, geburtstag

Man sieht an der oberen Zeile, dass die SQL-Anweisung sehr lang werden kann und man
nach rechts scrollen muss. Das ist natürlich einerseits unpraktisch und andererseits
verbessert es nicht die Lesbarkeit. Abhilfe schafft die Technik der 3 Anführungszeichen
einsetzen. Somit hat Python kein Problem mehr, wenn wir unsere Anweisung in mehrere
Zeilen verteilen. Das macht besonders bei SQL-Anweisungen Sinn, da wir dann die Felder von
den Variablen besser getrennt darstellen können.

Hier die Anweisung von oben sinnvoll in mehrere Zeilen umgebrochen:

zeiger.execute("""
INSERT INTO personen
VALUES (?,?,?)
""",
(vorname, nachname, geburtstag)
)

Und nun der komplette Code:

import sqlite3
verbindung = sqlite3.connect("datenbank/geburtstage.db")
zeiger = verbindung.cursor()

nachname = "Schiller"
vorname = "Friedrich"
geburtstag = "10.11.1759"

zeiger.execute("""
INSERT INTO personen
VALUES (?,?,?)
""",
(vorname, nachname, geburtstag)
)

verbindung.commit()
verbindung.close()

Im folgenden Kapitel speichern wir mehrere Datensätze auf einen Rutsch – nicht nur einen
wie bisher.
© https://www.python-lernen.de/sqlite-insert-into-executemany.htm Seite 348

Viele Datensätze in Datenbank speichern


Im letzten Kapitel haben wir genau einen neuen Datensatz in unserer SQLite-Datenbank
gespeichert. Dazu haben wir folgenden Python-Code erstellt:

import sqlite3
verbindung = sqlite3.connect("datenbank/geburtstage.db")
zeiger = verbindung.cursor()

nachname = "Schiller"
vorname = "Friedrich"
geburtstag = "10.11.1759"

zeiger.execute("""
INSERT INTO personen
VALUES (?,?,?)
""",
(vorname, nachname, geburtstag)
)

verbindung.commit()
verbindung.close()

Wenn uns allerdings mehrere Daten vorliegen, dann möchten wir diese so effektiv wie möglich
in unserer Datenbank speichern können.

Als Erstes benötigen wir die Daten selber. Dazu bieten sich natürlich Listen an. Bisher haben
wir einzelne Variablen verwendet, was sehr schnell ab einer gewissen Menge an verschiedenen
Variablen sehr unübersichtlich wird. Daher nutzen wir eine Liste, in der wir in einer
vorgegebenen Reihenfolge unsere Namen und Geburtstagsdaten abspeichern:

personendaten = ("Heinrich Hermann Robert", "Koch", "11.12.1843")

Diese Liste kann jetzt einfach unsere SQL-Anweisung execute übergeben werden.

personendaten = ("Heinrich Hermann Robert", "Koch", "11.12.1843")

zeiger.execute("""
INSERT INTO personen
VALUES (?,?,?)
""", personendaten)

Was passiert aber, wenn wir eine geschachtelte Liste haben – sprich eine Liste mit vielen
Personendaten?

beruehmtheiten = [('Georg Wilhelm Friedrich', 'Hegel', '27.08.1770'),


('Johann Christian Friedrich', 'Hölderlin', '20.03.1770'),
('Rudolf Ludwig Carl', 'Virchow', '13.10.1821')]

Wenn wir nun die geschachtelte Liste unserer SQL-Anweisung execute übergeben, erhalten
wir eine Fehlermeldung:

sqlite3.InterfaceError: Error binding parameter 0 - probably unsupported type.


© https://www.python-lernen.de/sqlite-insert-into-executemany.htm Seite 349

Geschachtelte Listen per SQL ausführen lassen: executemany


Und jetzt kommt es. Es gibt mehr als die execute -Anweisung. Über die SQL-Anweisung
executemany werden auch geschachtelte Listen auf einen Rutsch abgearbeitet.

import sqlite3
verbindung = sqlite3.connect("datenbank/geburtstage.db")
zeiger = verbindung.cursor()

beruehmtheiten = [('Georg Wilhelm Friedrich', 'Hegel', '27.08.1770'),


('Johann Christian Friedrich', 'Hölderlin', '20.03.1770'),
('Rudolf Ludwig Carl', 'Virchow', '13.10.1821')]

zeiger.executemany("""
INSERT INTO personen
VALUES (?,?,?)
""", beruehmtheiten)

verbindung.commit()

Es muss aber eine geschachtelte Liste sein. Diese kann aber auch nur einen Datensatz
enthalten wie im folgenden Beispiel:

personendaten = [("Heinrich Hermann Robert", "Koch2", "11.12.1843")]

Im folgenden Kapitel wollen wir auch mal schauen, was in unserer Datenbank angekommen
ist. Dazu lesen wir die Datenbank aus und zeigen die Inhalte an.
© https://www.python-lernen.de/sqlite-datenbank-auslesen.htm Seite 350

Datenbank auslesen und anzeigen: SELECT * FROM


Wir wollen eine Datenbank auslesen und anzeigen. Dazu müssen wir auswählen, was
angezeigt werden soll. Wir selektieren (engl. „select“) also eine Teilmenge (oder auch die
kompletten Datensätze) unserer Datenbank. Am Anfang sind wir nicht wählerisch und
nehmen alle Felder – sprich „Alles“ wird über den Stern „*“ ausgewählt. Jetzt müssen wir
noch unsere SQL-Anweisung mitgeben, von welcher Tabelle etwas ausgelesen wird („von“ =
engl. „from“):

SELECT * FROM tabellennamen

In unserem bisherigen Beispiel wäre das:

zeiger.execute("SELECT * FROM personen")

Und nun „holen“ wir die Daten ab und übergeben diese einer Liste. Am Rande bemerkt, das
englische Wort für holen bzw. abholen ist „fetch“. Mit den abgeholten in einer Liste
gespeicherten Daten können wir weiterarbeiten – in unserem Fall erst einmal ausgeben um
zu sehen, ob die in die Datenbank geschriebenen Daten auch wieder korrekt herauskommen.

inhalt = zeiger.fetchall()

Da wir nur Daten abholen, benötigen wir keine commit() -Anweisung.

Jetzt noch die Ausgabe:

print(inhalt)

Der dazu notwendige komplette Code:

import sqlite3
verbindung = sqlite3.connect("datenbank/geburtstage.db")
zeiger = verbindung.cursor()
zeiger.execute("SELECT * FROM personen")
inhalt = zeiger.fetchall()
print(inhalt)
verbindung.close()

Als Feedback bekommen wir folgende Ausgabe auf dem Bildschirm:

[('Johann Wolfgang von', 'Goethe', '28.8.1749'), ('Johann Wolfgang von', 'Goethe', '28.8.1749'),
('Friedrich', 'Schiller', '10.11.1759')]

Wir haben also eine Liste mit unseren einzelnen Elementen. Unseren Goethe haben wir
versehentlich 2-mal in die Datenbank gespeichert. Interessanterweise scheint das
Geburtsdatum korrekt übernommen worden zu sein, obwohl wir dies in deutscher
Schreibweise gespeichert haben.

Nicht alle Felder auslesen


Möchte ich aus meiner Tabelle nicht alle Felder auslesen, kann ich dies in der SELECT -
Anweisung mitgeben. Jetzt gebe ich anstelle des Sterns (sprich nicht mehr alle Felder) meine
gewünschten Felder an.

Möchte ich aus meiner Datenbank „personen“ nur noch den Nachnamen und den Geburtstag
erhalten, gebe ich nur diese beiden Feldnamen an:
© https://www.python-lernen.de/sqlite-datenbank-auslesen.htm Seite 351

SELECT nachname, geburtstag FROM personen"

Und im kompletten Code:

import sqlite3
verbindung = sqlite3.connect("datenbank/geburtstage.db")
zeiger = verbindung.cursor()
zeiger.execute("SELECT nachname, geburtstag FROM personen")
inhalt = zeiger.fetchall()
print(inhalt)
verbindung.close()

Als Ergebnis erhalten wir:

[('Goethe', '28.8.1749'), ('Goethe', '28.8.1749'), ('Schiller', '10.11.1759')]


© https://www.python-lernen.de/sqlite-update-datensatz-aendern.htm Seite 352

Datensätze ändern/ergänzen: UPDATE


Falls in einem Datensatz eine Änderung ansteht oder einzelne Angaben eines Datensatzes
ergänzt werden müssen gibt es die SQL-Anweisung UPDATE .

Wir wollen unseren Datensatz von Herrn Schiller korrigieren. Schiller ist zwar primär mit dem
Vornamen Friedrich bekannt, aber seine kompletten Vornamen lauten: „Johann Christoph
Friedrich“

Also wollen wir unseren Datensatz aktualisieren. Schauen wir uns dazu erst die komplette SQL-
Anweisung an:

UPDATE personen SET vorname='Johann Christoph Friedrich' WHERE nachname='Schiller'

Die Anweisung UPDATE ist logisch: Aktualisiere (update) in der Tabelle „personen“ folgende
angegebene Daten. Bei den angegebenen Daten müssen wir nur die zu änderten Daten und das
entsprechende Feld über die SQL-Anweisung SET angeben.

Nicht alles Datensätze ändern: Datensatz auswählen


Wir grenzen unsere Datensätze über die zusätzliche SQL-Anweisung WHERE ein. Hier können
wir festlegen, dass unsere Aktion nur für die Datensätze mit der in der WHERE -Bedingung
formulierten Einschränkung durchgeführt wird.

In unserem Fall wollen wir unseren Herrn Schiller auswählen, also WHERE
nachname='Schiller' . Auf das Problem, dass es mehr als einen „Schiller“ in unserer
Tabelle gibt, kommen wir später noch zu sprechen.

Bauen wir unsere SQL-Anweisung um, damit wir wie gewohnt mit Variablen arbeiten können
und geschützt vor SQL-Injektionen sind.

nachname = "Schiller"
vorname = "Johann Christoph Friedrich"

zeiger.execute("UPDATE personen SET vorname=? WHERE nachname=?", (vorname, nachname)


verbindung.commit()

Noch einmal, da es so wichtig ist! Hier ist die korrekte formulierte Bedingung in der SQL-
Anweisung mit WHERE extrem wichtig. Ansonsten bekommen ALLE Datensätze den neuen
Vornamen. Und das würde Goethe definitiv nicht gefallen.

Nach Ausführung der Anweisung haben wir als Ergebnis:

[('Johann Christoph Friedrich', 'Schiller', '10.11.1759')]

[('Johann Christoph Friedrich', 'Schiller', '10.11.1759'), ('Johann Wolfgang von', 'Goethe',


'28.8.1749'), ('Johann Wolfgang von', 'Goethe', '28.8.1749')]

Und einfach, weil es so schön ist, einmal diesen fatalen Fehler zu machen, lassen wir die
WHERE-Anweisung weg:

zeiger.execute("UPDATE personen SET vorname=? ", (vorname, ))


verbindung.commit()

Anmerkung: das Komma nach (vorname, ) ist wichtig. Dazu später mehr.
© https://www.python-lernen.de/sqlite-update-datensatz-aendern.htm Seite 353

Einfach einmal probieren, was dabei rauskommt!


© https://www.python-lernen.de/sqlite-delete-from-datensatz-loeschen.htm Seite 354

Löschen von Datensätzen: DELETE FROM


Jetzt wollen wir unseren doppelten Datensatz aus dem letzten Kapitel mit „Goethe“ wieder
löschen. Hierzu gibt es die SQL-Anweisung DELETE FROM .

In unserem Beispiel wäre das:

zeiger.execute("DELETE FROM personen WHERE nachname=?", ('Goethe',))

Diese Anweisung müssen wir über commit() „bestätigen“.

Hier der komplette Code mit Anzeige der Datensätze:

import sqlite3
verbindung = sqlite3.connect("datenbank/geburtstage.db")
zeiger = verbindung.cursor()

zeiger.execute("DELETE FROM personen WHERE nachname=?", ('Goethe',))


verbindung.commit()

zeiger.execute("SELECT * FROM personen")


inhalt = zeiger.fetchall()

print(inhalt)

verbindung.close()

Lassen wir es aufführen. Falls eine Fehlermeldung kommt, bitte das Komma nach „('Goethe',)”
beachten.

Wir bekommen als Ergebnis angezeigt:

[('Friedrich', 'Schiller', '10.11.1759')]

Ungeschickterweise sind jetzt alle Goethes den Weg der Sterblichen gegangen. Wir haben
keinen einzigen mehr in der Datenbank.

Unsere SQL-Anweisung wurde exakt so ausgeführt, wie wir diese geschrieben haben. Lösche
alle Personen mit dem Nachnamen „Goethe“, egal wie oft diese Vorkommen und welchen
Vornamen diese haben. Wäre eine „Susanne Goethe“ in der Datenbank vorhanden gewesen,
wäre auch diese unserem Löschangriff zum Opfer gefallen.

Hier kommt nun ein grundsätzliches Problem in unserem Datenbankdesign zum Vorschein,
dass wir in den nächsten Kapiteln angehen müssen.

Bisher haben wir keine Möglichkeit exakt den einen Datensatz auszuwählen, den wir wollen.
Wir könnten zwar unsere WHERE -Bedingung noch weiter präzisieren mit Beispielsweise der
Angabe von weiteren Feldern:

zeiger.execute("DELETE FROM personen WHERE nachname=?, geburtstag=?", ('Goethe', '28.8.174

Es würden aber weiterhin mehrere Datensätze betroffen sein!

Daher sind DELETE FROM außerordentlich gefährlich. Was passiert wohl bei der Anweisung:

zeiger.execute("DELETE FROM personen")


© https://www.python-lernen.de/sqlite-delete-from-datensatz-loeschen.htm Seite 355

Korrekt – alles wird gelöscht! Nur doof, wenn wir das eigentlich nicht wollten oder irgendwas
schieflief mit der WHERE -Bedingung!

Daher benötigen wir ein exaktes einmaliges Kriterium zum Löschen, damit exakt der eine
gewünschte Datensatz gelöscht werden kann.

Dafür brauchen wir zum Verständnis SQL-Grundlagen, die in den folgenden Kapiteln aufgebaut
werden.
© https://www.python-lernen.de/sql-grundlagen.htm Seite 356

SQL Grundlagen lernen


Bisher haben wir mit Python ohne SQL-Grundlagenwissen einfach Datenbankerstellung und
Datenbankzugriffe durchgeführt. Dabei kamen wir bei verschiedenen Aktionen schnell an
unsere Grenzen durch die fehlenden Grundlagenkenntnisse. Grundlagen haben Vorteile und
bringen Sicherheit in die Anwendung und Nutzung von Datenbanken bzw. SQL. Wenn wir von
SQL sprechen, sprechen wir von einem relationalem Datenbankmanagementsystem (RDBMS:
Relational Database Management System). Flapsig gesagt: Daten stehen in einer Beziehung –
einer Relation. Diese Beziehungen können ausgewertet und ausgegeben werden.

Das Kürzel SQL stehen für „Structured Query Language“ – eine strukturierte Abfrage-Sprache.

SQL selber hat 4 große Bereiche:

DDL: Data Definition Language

DML: Data Manipulation Language

DQL: Data Query Language

DCL: Data Control Language

Was machen diese Bereiche für uns?

DDL: Data Definition Language – Daten-Definitions-Sprache


© https://www.python-lernen.de/sql-grundlagen.htm Seite 357

Bevor wir ein Datenbanksystem nutzen können, müssen wir erst unsere Datenbank mit deren
Tabellen einrichten. Auf gut Deutsch: welche Felder gibt es und wie nennen wir diese, damit wir
komfortable wieder darauf zugreifen können. Wir definieren also unsere Daten bzw.
Datenfelder und können die gewünschte Struktur über eine SQL-Anweisung in der Datenbank
erzeugen. Ohne eine Datenbank und Daten können wir auch nicht die folgenden Bereiche
nutzen wie die Datenbank mit Daten zu füllen bzw. auszuwerten.

DML: Data Manipulation Language – Daten-Manipulations-


Sprache
Nachdem wir unsere gewünschte Struktur über die
DDL erstellt haben, wollen wir Daten in unser
Datenbanksystem hineinschreiben, ändern und
löschen können. Genau das macht man mit der DML.

DQL: Data Query Language – Daten Abfrage Sprache

Auslesen der Datenbank auch mit bestimmten Bedingungen (man will ja nicht immer alle
Daten). Hier können auch mehrere Tabellen miteinander verknüpft werden und daraus das
Ergebnis ausgegeben werden.
© https://www.python-lernen.de/sql-grundlagen.htm Seite 358

DCL: Data Control Language – Daten-Kontroll-Sprache


Data Control Language: Daten-Kontroll-Sprache
(Besser Zugriffs-Kontroll-Sprache)

Nicht jeder darf auf alle Daten zugreifen. Daher


ergibt es Sinn, hier eine Kontrolle einzubauen.

Zur DCL gehört auch die Transaktionssteuerung,


damit es auch sichergestellt ist, dass alle
Änderungen bzw. Aktionen in der Datenbank
stattfinden. Ansonsten (je nach System) gibt es
automatisch ein zurück auf den definierten
Ausgangspunkt. Einfach einmal eine
Banküberweisung sich vorstellen, wo beim Bezahlenden abgebucht wird, aber nicht beim
Empfänger gutgeschrieben wird. Das gibt Ärger! Daher entweder beides oder gar nichts!

ANSI-SQL
Hier der Begriff ANSI-SQL, damit man es mal gelesen hat und verorten kann. Das American
National Standards Institut (ANSI) hat festgelegte Standards. Diese gibt es auch für SQL.
Allerdings gibt es da über die Jahre mehrere verschiedene, da es bei SQL Verbesserungen und
Erweiterungen gegeben hat. Die verschiedenen SQL-Server bieten im Kern die gleiche Funktion,
die aber in der Nutzung leicht unterschiedlich sein kann, was hier am Anfang über das von uns
benötigte Wissen hinausgeht. Sollte man mal schlaflose Nächte haben, kann man sich mit den
verschiedenen ANSI-SQL-Varianten die Nacht vertreiben.

MySQL, MariaSQL, Microsoft SQL Server (MSSQL), Oracle –


verschiedene Datenbanksysteme
Es gibt verschiedene und am Anfang nutzt man eins um in die Materie hineinzukommen.

Lustig am Rande: MySQL – die ersten 2 Buchstaben vom Namen der Datenbank kommen von
dem Vornamen „My“. Diese ist die Tochter des MySQL-AB-Mitgründers Michael Widenius
(Monty genannt). Seine zweite Tochter heißt Maria (wurde auch als Namen für ein
Datenbanksystem verwendet: MariaSQL).

Die verschiedenen Datenbankserver orientieren sich alle am Standard der aktuellen SQL-
Version.

Begriffe rund um SQL


Anweisungen, Statement: SQL ist eine Anweisungssprache, keine Programmiersprache!

Schlüsselwörter:

einzelne SQL-Befehle

Anwendung:

nicht case-sensitiv (Groß- und Kleinschreibung macht keinen Unterschied), es gibt aber
Empfehlungen in Form von Schlüsselworten immer in Großbuchstaben, Rest in
Kleinschreibung bzw. gemischte Schreibweise.
© https://www.python-lernen.de/sql-grundlagen.htm Seite 359

Leerzeichen, Tabulatoren und Zeilenumbrüche dürfen nach Belieben genutzt werden. Hier ist
die bestmögliche Lesbarkeit das Ziel!

Speicherung der Daten mit SQL


Die Daten werden in Tabellen gespeichert. Dabei wird jeder Spalte (man spricht auch von
Feldern bzw. Datenfelder) mit einem Namen benannt um später darauf zugreifen zu können.
Es wird festgelegt, ob in dieses Datenfeld nur Text, ganze Zahlen, Zahlen mit
Nachkommastellen oder z.B. ein Datum zukünftig gespeichert werden soll. Hier spricht man
von Datentypen, die verfügbar sind. Grob gesagt haben wir hier Zahlen, alphanumerische
Zeichen (flapsig gesagt also Texte, die zusätzlich Zahlen enthalten können, mit denen wir aber
nicht rechnen) und Datumstypen. Die Festlegung der Datentypen ist sehr wichtig, da nur mit
Zahlen gerechnet werden kann und auch es auf Sortierungen Auswirkungen hat. In der
Anwendung werden wir dann bei der Definition der Felder noch präzise den benötigten
Datentyp definieren. Das dann später genauer im passenden Kapitel.

Zusätzlich wird auch für die meisten Datentypen eine Feldlänge vergeben.

Bezeichnung Datensatz: Die Zeilen in der Tabelle werden als Datensätze bezeichnet. Hier
haben wir dann alle Einzeldaten, die zu diesem Datensatz gehört. Bei einem Telefonbuch gäbe
es dann z.B. Vorname, Nachname, PLZ, Telefonnummer

Tabellen beherbergen somit gleichartige Informationen.

Ein Datensatz ist eine Zusammenstellung von einzelnen Informationen, die sinnvoll
zusammengehören und daher schlecht getrennt werden können. In unserem Beispiel vom
Telefonbuch macht es Sinn, dass der Vorname und der Nachname in der gleichen Tabelle als
Datenfelder vorhanden sind.

Primärschlüssel (Primärschlüsselspalte): Um bei der Anwendung exakt auf einen


gewünschten Datensatz zugreifen zu können, benötigen wir Primärschlüssel. Anhand des
Primärschlüssels können wir den benötigten Datensatz bearbeiten. Hätten wir keinen
Primärschlüssel, hätte z.B. der Name Müller öfters Pech, da ab einer gewissen Anzahl von
Adressen mehrere Müller vorkommen können. Man kann also schlecht nach dem Nachnamen
suchen und erwarten, dass dort immer exakt nur 1 Treffer zurückkommt. Daher benötigen wir
eine eindeutige Zahl. Wird in unserer Tabelle ein Primärschlüssel definiert, müssen wir uns
meistens nicht mehr darum kümmern, dass dieser einmalig ist. Versucht man einen
Primärschlüssel mehrfach zu vergeben, erhalten wir eine Fehlermeldung vom DBMS – somit ist
sichergestellt, dass es nur einen gibt. Die Vergabe des Primärschlüssels kann automatisch
laufen und somit ist sichergestellt, dass eindeutige Zugriffe möglich sind.

Beziehungen in relationaler Datenbank: Schauen wir unser Beispiel mit der Telefonliste an.
Neben dem Vor- und Nachnamen speichern wir die Postleitzahl – aber keinen Ort! Warum? Hier
kommt der Vorteil von relationalen Datenbanken ins Spiel. Es geht um Beziehungen: Unser
Postleitzahlensystem in Deutschland hat zu jeder Postleitzahl genau einen Ort. Es macht also
wenig Sinn zusätzlich neben der PLZ den Ort in der Tabelle mit den Namen zu speichern. Für
die Orte können wir eine weitere Tabelle anlegen, in der nur Postleitzahl und zugehörige Orte
gespeichert werden. In dem Fall der neuen Tabelle ist unsere PLZ der Primärschlüssel unserer
Tabelle „ortsnamen“ (wir gehen jetzt einfach nur von Orten in Deutschland aus). Unser Feld
PLZ in der Tabelle „telefonbuch“ nennt sich auch „Fremdschlüssel“. Dieser Fremdschlüssel aus
der Tabelle „telefonbuch“ zeigt auf den Primärschlüssel „PLZ“ in der Tabelle „ortsnamen“.

Diese Beziehungen können in Datenbankdiagrammen dargestellt werden.


© https://www.python-lernen.de/sql-grundlagen.htm Seite 360

[bild[Beispiel Datenbankdiagrammen]]

Den Primärschlüssel sieht man i.d.R. anhand eines Schlüsselsymbols und die Art der
Verknüpfung der Daten ist sofort sichtbar anhand einer Linie. Die Enden der Linien zeigen die
Art der Relation (Verknüpfung):

Schlüssel: Primärschlüssel

Unendlichzeichen: es können 0, 1 oder mehrere Datensätze betroffen sein

Referentielle Integrität (RI): die Referentielle Integrität dient zur Sicherstellung der
Datenintegrität zwischen den Tabellen. Durch die Verknüpfung von Fremdschlüssel und
Primärschlüssel kann das Datenbanksystem kontrollieren, ob ein Datensatz vorhanden ist und
der Fremdschlüssel verwendet werden darf. Auch ist es nicht einfach möglich den
Primärschlüssel zu verändern, wenn dieser als Fremdschlüssel bereits verwendet wird.

Es kann nur auf die formale Korrektheit kontrolliert werden – inhaltlich ist immer noch der
Nutzer in der Pflicht mitzudenken!

Schauen wir uns diese Grundlagen in konkreten Anwendungen an. Dann wird es auch greifbar.
Im folgenden Kapitel nutzen wir den Primärschlüssel für die eindeutige Auswahl eines
Datensatzes.
© https://www.python-lernen.de/sqlite3-shell.htm Seite 361

Tools für SQLite3 – SQLite Shell


SQLite bietet eine Shell. Diese kann direkt im Terminalfenster gestartet werden über

sqlite3

Danach erscheint im Terminalfenster dann:

Axels-MBP:Python-lernen.de axel$ sqlite3


SQLite version 3.28.0 2019-04-15 14:49:49
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.

Jetzt können wir mit .help uns alle Befehle ansehen, die uns die sqlite3-Shell bietet.

Wir können alle Funktionen, die wir über den Umweg von Python kennengelernt haben auch
direkt in der SQLite3-Shell ausführen. Wollen wir unsere erstellte Datenbank „geburtstage.db“
nutzen, müssen wir diese laden. Da wir diese in einem Unterordner gespeichert haben, müssen
wir beim Pfad den Unterordner mit angeben:

.open datenbank/geburtstage.db

Bitte nicht wundern, wenn wir kein Feedback von der Shell bekommen:

sqlite> .open datenbank/geburtstage.db


sqlite>

Wir erhalten automatisch die Möglichkeit, den nächsten Befehl anzugeben.

Jetzt können wir uns die Datenbanken anzeigen lassen über:

.databases

Als Rückmeldung erhalte ich auf meinem System dann:

sqlite> .databases
main: /Users/axel/Documents/Python-lernen.de/datenbank/geburtstage.db

Haben wir die erstellten Tabellen vergessen, erhalten wir über den Befehl .tables eine
Auflistung aller in der Datenbank vorhandenen Tabellen:

sqlite> .tables

adressen personen

Und jetzt können wir bereits direkt mit weiteren SQL-Anweisungen die Tabelle auslesen.
Lassen wir uns den Inhalt komplett anzeigen:

sqlite> SELECT * FROM personen;

Johann Christoph Friedrich|Schiller|10.11.1759


© https://www.python-lernen.de/sqlite3-shell.htm Seite 362

Wir bekommen den Datensatz von „Schiller“ angezeigt.

…> - was geht?


Bekommen wir allerdings versehentlich nur als Ausgabe „…>“ haben wir ein abschließendes
Semikolon vergessen. Einfach einmal probieren:

sqlite> SELECT * FROM adressen


...>
...> ;

Um wieder die normalen Shell-Eingaben machen zu können, müssen wir das anschließende
Semikolon angeben!

sqlite> SELECT * FROM adressen


...>
...> ;
sqlite>

SQLite-Shell beenden: .quit


Um die Shell zu beenden, einfach in der Eingabeaufforderung .quit eingeben. Somit sind wir
im normalen Terminal zurück.

sqlite> .quit
Axels-MBP:Python-lernen.de axel$

Bessere Ausgabe der Daten in SQLite3-Shell aktivieren


Bei unserem letzten Test kamen die Daten sehr unübersichtlich in der Ausgabe. Wir können
aber eine wesentlich bessere Übersicht bekommen, wenn wir den Spalten-Modus aktivieren
über .mode column und uns zusätzlich die Spaltenbezeichnungen ausgeben lassen über die
Anweisung .headers on .

Schauen wir es uns an:

sqlite> .open datenbank/geburtstage.db


sqlite> .headers on
sqlite> .mode column
sqlite> SELECT * FROM personen;
vorname nachname geburtstag
-------------------------- ---------- ----------
Johann Christoph Friedrich Schiller 10.11.1759
sqlite>

Einstellungen (und Änderungsmöglichkeiten)


© https://www.python-lernen.de/sqlite3-shell.htm Seite 363

Über die Shell-Anweisung .show bekommen wir weitere Informationen über die Anzeige und
über die aktuell gewählte Datenbank:

sqlite> .show
echo: off
eqp: off
explain: auto
headers: on
mode: column
nullvalue: ""
output: stdout
colseparator: "|"
rowseparator: "\n"
stats: off
width:
filename: datenbank/geburtstage.db

sqlite>

Hier können wir nach Bedarf auch Änderungen durchführen. Beispielsweise können wir den
Trenner, der als Zeichen „|“ verwendet umstellen über die Anweisung .separator ^

Direkt aus Shell starten


Gerade sind wir in mehreren Schritten zu unserem Ergebnis gekommen. Wir können auch
direkt aus unserem Terminal (CMD-Line unter Windows) eine komplette SQL-Ausgabe
erreichen. Dazu nutzen wird folgenden Aufbau:

sqlite3 datenbankname.db "SELECT * FROM tabellennamen"


© https://www.python-lernen.de/sqlite3-datenbank-import-aus-csv-datei.htm Seite 364

CSV-Datei in SQLite3 Datenbank importieren


Schauen wir uns den Inhalt einer CSV-Datei an. Meistens liegen uns Daten in Excel vor. In Excel
kann der Export direkt in eine CSV-Datei exportiert werden:

Daten aus Excel über CSV-Datei in Python Datenbank importieren

Der Export aus Excel wird über:

Datei -> Speichern unter -> Dateiformat

Excel-Daten als CSV-Datei speichern

Wir erhalten dann eine Textdatei, deren Datenfelder der Semikolons getrennt sind:

nachname;vorname;geburtstag
Müller;Mike;05.03.80
Sommer;Elke;02.05.87
Schuster;Johanna;10.10.93
Trister;Theodor;08.03.87

Und die CSV-Datei über Python ausgelesen und angezeigt:

import csv
with open("adressen.csv") as csvdatei:
csv_reader_object = csv.reader(csvdatei, delimiter=';')
for row in csv_reader_object:
print(row)

Als Ergebnis erhalten wir die Daten als Datentyp "Liste":


© https://www.python-lernen.de/sqlite3-datenbank-import-aus-csv-datei.htm Seite 365

['ufeffnachname', 'vorname', 'geburtstag']


['Müller', 'Mike', '05.03.80']
['Sommer', 'Elke', '02.05.87']
['Schuster', 'Johanna', '10.10.93']
['Trister', 'Theodor', '08.03.87']

Die ersten Zeichen 'ufeff' kommen daher, dass wir in der entsprechenden UTF8-Variante
abgespeichert haben. Da wir die Überschriften nicht benötigt, kann man diesen kleinen
Schönheitsfehler ignorieren und diese erste Zeile mit den Überschriften einfach mit einem
Texteditor aus der CSV-Datei löschen. Dann passt alles beim richtigen Import.

Jetzt wollen wir eine Verbindung zur Datenbank „adressen.db“ aufbauen und diese
gegebenenfalls neu anlegen, falls diese noch nicht existiert:

import csv
import sqlite3
verbindung = sqlite3.connect("adressen.db")
zeiger = verbindung.cursor()

sql_anweisung = """
CREATE TABLE IF NOT EXISTS adressen (
nachname VARCHAR(30),
vorname VARCHAR(20),
geburtstag DATE
);"""

zeiger.execute(sql_anweisung)

with open("adressen.csv") as csvdatei:


csv_reader_object = csv.reader(csvdatei, delimiter=';')
for row in csv_reader_object:
print(row)

Ab jetzt können wir unsere SQLite3 Datenbank befüllen. Wir benötigen die entsprechende SQL-
Anweisung:
© https://www.python-lernen.de/sqlite3-datenbank-import-aus-csv-datei.htm Seite 366

import csv
import sqlite3
verbindung = sqlite3.connect("adressen.db")
zeiger = verbindung.cursor()

sql_anweisung = """
CREATE TABLE IF NOT EXISTS adressen (
nachname VARCHAR(30),
vorname VARCHAR(20),
geburtstag DATE
);"""

zeiger.execute(sql_anweisung)

sql_anweisung = """
INSERT INTO adressen (nachname, vorname, geburtstag)
VALUES (:nachname, :vorname, :geburtstag)
"""

with open("adressen.csv") as csvdatei:


csv_reader_object = csv.reader(csvdatei, delimiter=';')

with sqlite3.connect("adressen.db") as verbindung:


zeiger = verbindung.cursor()
zeiger.executemany(sql_anweisung, csv_reader_object)

Und zum Test können wir jetzt die Datenbank auslesen und den Inhalt anzeigen:

import sqlite3
verbindung = sqlite3.connect("adressen.db")
zeiger = verbindung.cursor()
zeiger.execute("SELECT * FROM adressen")
inhalt = zeiger.fetchall()
print(inhalt)
verbindung.close()

Wir haben alle Daten auf einen Rutsch in unsere SQLite3-Datenbank importiert und können
damit weiterarbeiten.

So kann man schnell SQLite-Datenbanken mit Inhalt füllen.


© https://www.python-lernen.de/pygame-tutorial.htm Seite 367

Pygame Library nutzen zum Spiele programmieren in Python


Pygame ist eine Bibliothek, die für uns die Spieleentwicklung mit Python sehr viel einfacher
macht. Diese regelt für uns:

Elemente Zeichen wie Rechtecke, Kreise etc.

Bitmap-Grafiken anzeigen

Animationen von Elementen

Einbinden von Tastatur, Maus und Gamepads

Kollisionskontrolle

Sound abspielen

Pygame importieren/initialisieren
Da es sich um ein Modul handelt (muss auch erst installiert sein) muss dieses geladen und
initialisiert werden. Das können wir gleich am Anfang von unserem Python-Programm
erledigen:

# Importieren der Pygame-Bibliothek


import pygame

# initialisieren von pygame


pygame.init()

Starten wir nun unser Programm und ist Pygame installiert, erhalten wir als Ausgabe:

pygame 1.9.6

Hello from the pygame community. https://www.pygame.org/contribute.html

Unser Programm macht noch nichts – wir erhalten nur in der Konsole eine kleine Rückmeldung
(aus der wir auch die Version der verwendeten Pygame-Library erfahren).

Sollte Pygame noch nicht installiert sein, dann erscheint eine Fehlermeldung. Dann bitte
Pygame installieren.

Farben nutzen
Was wäre ein Spiel ohne Farben? Um Farben nutzen zu können, müssen wir diese festlegen.
Hierbei hilft nicht, zu sagen, wir wollen „orange“ verwenden und gut ist. Nein – Farben werden
über die 3 Grundfarben Rot, Grün und Blau festgelegt. Daher auch die Bezeichnung RGB.
Dankbarweise fangen auf Englisch die 3 Grundfarben mit den gleichen Buchstaben an (red,
green, blue).
© https://www.python-lernen.de/pygame-tutorial.htm Seite 368

Aufbau der Farben über dezimal/hexadezimale Zahlen

Zum Festlegen der Farben geben wir jeder dieser 3 Grundfarben einen Wert zwischen 0 und
255. Somit können wir über 16 Millionen verschiedener Farben nutzen. Geben wir dem ersten
Wert (der für Rot steht) die maximalen 255 und den zweiten und dritten Wert jeweils 0 erhalten
wir ein Rot.

Geben wir allen 3 Grundfarben der Werten 255 erhalten wir weiß.

Haben alle 3 Grundfarben der Wert 0 erhalten wir Schwarz.

Mischen wir die Werte lustig, erhalten wir eine der 16,7 Millionen möglichen Farben.

Es gibt zahlreiche Dienste Online, über die man die RGB-Werte herausbekommt (wie
beispielsweise https://www.webfx.com/web-design/color-picker/ ). Aber auch jedes
Bildbearbeitungsprogramm zeigt Farbwerte als RGB-Werte an (man muss nur wissen, wo man
suchen muss). Und darauf achten, dass wir dezimale Werte erhalten, ansonsten siehe weiter
unten bei hexadezimalen Werten.

Nachdem wir die gewünschte Farbe haben (unser Orange hat z.B. die Werte 255 bei Rot, 140
bei Grün und 0 bei Blau) können wir diese nutzen.

Die Farben werden in Pygame in Form von Tupel (siehe https://www.python-


lernen.de/tupel.htm ) genutzt.

Hier als Beispiel (die Erklärung von screen.fill() folgt später noch ausführlich).

screen.fill((255,140,0))

Diese Schreibweise funktioniert zwar, aber macht wenig Spaß, da oft unklar ist, welche Farbe
damit gemeint ist. Daher nutzen wir einfach Konstanten. Wir legen also unsere Farben also
Konstante fest und nutzen dann den vergebenen Namen:

ORANGE = ( 255, 140, 0)


screen.fill(ORANGE)

So können wir am Anfang von unserem Spiel alle genutzten Farben definieren und haben dann
einen übersichtlichen Code:
© https://www.python-lernen.de/pygame-tutorial.htm Seite 369

# genutzte Farbe
ORANGE = ( 255, 140, 0)
ROT = ( 255, 0, 0)
GRUEN = ( 0, 255, 0)
SCHWARZ = ( 0, 0, 0)
WEISS = ( 255, 255, 255)

Hexadezimale Schreibweise von Farben

Sollen die Farben in hexadezimaler Schreibweise genutzt werden, ist das in Python absolut
kein Problem. Hexadezimal zeichnet sich dadurch aus, dass unsere Zahlen nicht von 0 bis 9
gehen, sondern bis 16. Daher benötigen wir ab 9 dann entsprechende Codierung:

Dezimal Hexadezimal

8 8

9 9

10 A

11 B

12 C

13 D

14 E

15 F

Haben wir also den Maximalwert in Dezimal von 255 wird er als hexadezimale Zahl mit FF
angegeben.

Wollen wir hexadezimale Zahlen in Python nutzen, wird vorweg „0x“ angegeben. Also für FF
dann „0xFF“.

Unsere Farbdefinition von oben wäre also:

FF8C00

# genutzte Farbe
ORANGE = ( 0xFF, 0x8C, 0x00)
ROT = ( 0xFF, 0x00, 0x00)

Für die Nutzung ist es egal, ob man mit dezimalen oder hexadezimalen Zahlen arbeitet

ein Pygame-Fenster öffnen


Um ein Fenster für unser Spiel zu öffnen, benötigen wir die Anweisung
pygame.display.set_mode() . Hier wird dann die Breite (erster Wert) und die Höhe
(zweiter Wert) übergeben.

Unser bisheriger Code:

# Importieren der Pygame-Bibliothek


import pygame

# initialisieren von pygame


pygame.init()

# genutzte Farbe
ORANGE = ( 255, 140, 0)
ROT = ( 255, 0, 0)
GRUEN = ( 0, 255, 0)
SCHWARZ = ( 0, 0, 0)
WEiSS = ( 255, 255, 255)

# Fenster öffnen
pygame.display.set_mode((640, 480))

Lassen wir nun unser Programm ausführen, kommt für einen Sekundenbruchteil das Fenster
und verschwindet wieder. Logisch, da unser Programm ja sofort wieder beendet ist. Es hat
alles erledigt und räumt dann ordentlich wie Python ist das angezeigte Fenster wieder „auf“.

Vielleicht wundert man sich anfangs über set_mode . Von der Logik her würde man ja auf
irgendwas mit „open_window“ schließen. Das liegt daran, dass die pygame.display -
Anweisung deutlich mehr kann, außer ein Fenster zu erstellen.

Zusätzlich können wir unserem Fenster noch einen Titel verpassen, der dann später im
Fensterkopf angezeigt wird. Dazu nutzen wir wieder unsere Anweisung pygame.display mit
pygame.display.set_caption()
© https://www.python-lernen.de/pygame-tutorial.htm Seite 370

Schreiben wir einfach einmal in den Fensterkopf: „Unser erstes Pygame-Spiel“:

# Titel für Fensterkopf


pygame.display.set_caption("Unser erstes Pygame-Spiel")

Störend ist natürlich, dass sich unser gezeichnetes Fenster sofort wieder schließt. Daher wird
es Zeit für Benutzeraktionen

mit dem Nutzer interagieren


Wir wollen nun dem Nutzer auch Möglichkeiten zur Interaktion bieten. Im ersten Schritt
erstellen wir eine endlos ablaufende while -Schleife, bis der Nutzer den Exit-Button angeklickt
hat.

Den Aufbau der Hauptroutine haben wir bereits in den vorherigen Kapiteln bei anderen Spielen
kennengelernt. Daher wird hier nicht nochmals darauf eingegangen. Unsere while -Schleife
läuft so lange, wie unsere Variable mit dem Namen „spielaktiv“ auf „True“ gesetzt ist. Sprich vor
der while-Schleife führen wir diese Variable ein.

Innerhalb der while -Schleife überprüfen wir, ob ein bestimmtes Ereignis (englisch „event“)
stattgefunden hat wie z.B. das Klicken auf den Exit-Button.

Schauen wir unseren bisherigen Code an:

# Importieren der Pygame-Bibliothek


import pygame

# initialisieren von pygame


pygame.init()

# genutzte Farbe
ORANGE = ( 255, 140, 0)
ROT = ( 255, 0, 0)
GRUEN = ( 0, 255, 0)
SCHWARZ = ( 0, 0, 0)
WEiSS = ( 255, 255, 255)

# Fenster öffnen
pygame.display.set_mode((640, 480))

# Titel für Fensterkopf


pygame.display.set_caption("Unser erstes Pygame-Spiel")

# solange die Variable True ist, soll das Spiel laufen


spielaktiv = True

# Schleife Hauptprogramm
while spielaktiv:
for event in pygame.event.get():
if event.type == pygame.QUIT:
spielaktiv = False

Die grundlegende Logik und der Ablauf


Um nun noch die Logik hinter unsere Hauptprogramm-Schleife zu zeigen, integriere ich
Anmerkungen, die später mit dem entsprechenden Code gefüllt werden.

Wichtig ist diese grundlegende Logik. Wer diese verletzt, kann in unnötige Probleme laufen. Wir
haben in der Hauptschleife 5 Blöcke. Diese sollten auch nicht bunt gemischt werden.

Die Blöcke der Hauptschleife:

Nutzeraktion überprüfen (Tastatur/Maus etc.)

Spielelogik berechnen (wenn Figur bewegt wird, Kollision etc.)

Zeichnen von Spielfeld und Spielfiguren

Fenster löschen

Inhalt frisch zeichnen/Fenster aktualisieren

Dies sieht in unserem Programm wie folgt aus. Es wurden Platzhalter in Form von
Anmerkungen eingebaut:
© https://www.python-lernen.de/pygame-tutorial.htm Seite 371

# Schleife Hauptprogramm
while spielaktiv:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat
for event in pygame.event.get():
if event.type == pygame.QUIT:
spielaktiv = False

# Spiellogik hier integrieren

# Spielfeld/figur(en) zeichnen (davor Spielfeld löschen)

# Fenster aktualisieren

# Refresh-Zeiten festlegen

Bei den Refresh-Zeiten wird die Häufigkeit der Fenster-Aktualisierung festgelegt. Diese darf
weder zu häufig (bremst den Computer herunter) noch zu selten (Figuren bewegen sich
merkwürdig) stattfinden.

Vor dem Zeichnen des Spielfelds und der Spielfigur(en) wird das Fenster gelöscht. Dazu
zeichnen wir einfach den kompletten Bereich in der Grundfarbe. Hat unser Spiel die
Hintergrundfarbe Weiß, dann wäre unser Aufruf:

screen.fill(WEISS)

Unsere Farbe in der Konstanten WEISS haben wir am Anfang definiert. Zur Erinnerung: WEISS
= ( 255, 255, 255) .

Wichtig ist noch, dass der Zugriff auf screen eingerichtet wurde. Dazu wird beim „Fenster
öffnen“ dieser Zugriff festgelegt über:

# Fenster öffnen
screen = pygame.display.set_mode((640, 480))

Nach dem Zeichnen müssen wir das Fenster aktualisieren:

pygame.display.flip()

Refreshzeiten des Bildschirms einstellen


Um diese Zeiten einzustellen, müssen wir folgende Zuweisung machen:

# Bildschirm Aktualisierungen einstellen


clock = pygame.time.Clock()

Bei folgendem Code stellen wir 60 fps (frames per second = Bilder pro Sekunde) ein:

# 60 fps (frames per second)


clock.tick(60)

Wollen wir nur 10 Aktualisierungen pro Sekunden, dann ist die Angabe clock.tick(10)

Und nun der bisherige komplette Code:

# Schleife Hauptprogramm
while spielaktiv:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat
for event in pygame.event.get():
if event.type == pygame.QUIT:
spielaktiv = False
print("Spieler hat Quit-Button angeklickt")

# Spiellogik hier integrieren

# Spielfeld löschen
screen.fill(WEISS)

# Spielfeld/figuren zeichnen

# Fenster aktualisieren
pygame.display.flip()

# Refresh-Zeiten festlegen
clock.tick(60)

Programm sicher beenden


Und um das Programm sauber zu beenden, wird das Programm über die Anweisung
pygame.quit() sicher geschlossen. Wird dies nicht gemacht, kann durchaus das
© https://www.python-lernen.de/pygame-tutorial.htm Seite 372

Programm „crashen“ und im Hintergrund weiterlaufen und Prozesse im Computer belegen.

Daher einfach am Ende:

pygame.quit()

Tastatur/Maus abfragen mit Pygame


Aber schauen wir uns noch die weiteren Möglichkeiten für die Spielerinteraktion an. Bisher
haben wir nur den Exit-Button kennengelernt. Genauso können wir die Tastatur abfragen.
Erweitern wir unsere event -Anfrage. Bei jeder Aktion wird in der Konsole eine entsprechende
Meldung ausgegeben:

# Schleife Hauptprogramm
while spielaktiv:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat
for event in pygame.event.get():
if event.type == pygame.QUIT:
spielaktiv = False
print("Spieler hat Quit-Button angeklickt")
elif event.type == pygame.KEYDOWN:
print("Spieler hat Taste gedrückt")

Genauso können wir einen Klick mit der Maus abfragen über event.type ==
pygame.MOUSEBUTTONDOWN

# Schleife Hauptprogramm
while spielaktiv:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat
for event in pygame.event.get():
if event.type == pygame.QUIT:
spielaktiv = False
print("Spieler hat Quit-Button angeklickt")
elif event.type == pygame.KEYDOWN:
print("Spieler hat Taste gedrückt")
elif event.type == pygame.MOUSEBUTTONDOWN:
print("Spieler hast Maus angeklickt")

Und für die meisten Spiele benötigen wir als Steuerung die Pfeiltasten auf der Tastatur. Diese
werden über folgende Bezeichnungen angesprochen

K_LEFT

K_RIGHT

K_UP

K_DOWN

K_SPACE

Hier kommt nun die Besonderheit, dass wir nur dann in die Auswertung gehen, wenn im
Allgemeinen eine Taste genutzt wird (und zwar beim Herunterdrücken). Wir verschachteln also
eine if-Abfrage in den Bereich elif event.type == pygame.KEYDOWN:

# Schleife Hauptprogramm
while spielaktiv:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat
for event in pygame.event.get():
if event.type == pygame.QUIT:
spielaktiv = False
print("Spieler hat Quit-Button angeklickt")
elif event.type == pygame.KEYDOWN:
print("Spieler hat Taste gedrückt")
if event.key == pygame.K_RIGHT:
print("Spieler hat Pfeiltaste rechts gedrückt")
elif event.key == pygame.K_LEFT:
print("Spieler hat Pfeiltaste links gedrückt")
elif event.key == pygame.K_UP:
print("Spieler hat Pfeiltaste hoch gedrückt")
elif event.key == pygame.K_DOWN:
print("Spieler hat Pfeiltaste runter gedrückt")
elif event.key == pygame.K_SPACE:
print("Spieler hat Leertaste gedrückt")
elif event.type == pygame.MOUSEBUTTONDOWN:
print("Spieler hast Maus angeklickt")

Und weil wir gerade bei den wichtigsten Tasten sind (falls wir 2 Spieler haben), sollten wir auch
die üblichen Tasten „w,a,s,d“ abfragen können. Diese Tastenkombination wurde mit dem Ego-
© https://www.python-lernen.de/pygame-tutorial.htm Seite 373

Shooter Quake 1996 bekannt. Die Abfrage läuft über das Kürzel pygame.K_a: - sprich
großes K (für Keyboard) und Unterstrich und dann die gewünschte Taste.

# Schleife Hauptprogramm
while spielaktiv:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat
for event in pygame.event.get():
if event.type == pygame.QUIT:
spielaktiv = False
print("Spieler hat Quit-Button angeklickt")
elif event.type == pygame.KEYDOWN:
print("Spieler hat Taste gedrückt")

# Taste für Spieler 1


if event.key == pygame.K_RIGHT:
print("Spieler hat Pfeiltaste rechts gedrückt")
elif event.key == pygame.K_LEFT:
print("Spieler hat Pfeiltaste links gedrückt")
elif event.key == pygame.K_UP:
print("Spieler hat Pfeiltaste hoch gedrückt")
elif event.key == pygame.K_DOWN:
print("Spieler hat Pfeiltaste runter gedrückt")
elif event.key == pygame.K_SPACE:
print("Spieler hat Leertaste gedrückt")

# Taste für Spieler 2


elif event.key == pygame.K_w:
print("Spieler hat Taste w gedrückt")
elif event.key == pygame.K_a:
print("Spieler hat Taste a gedrückt")
elif event.key == pygame.K_s:
print("Spieler hat Taste s gedrückt")
elif event.key == pygame.K_d:
print("Spieler hat Taste d gedrückt")

elif event.type == pygame.MOUSEBUTTONDOWN:


print("Spieler hast Maus angeklickt")

Unser bisher entstandener Code komplett:


© https://www.python-lernen.de/pygame-tutorial.htm Seite 374

# Importieren der Pygame-Bibliothek


import pygame

# initialisieren von pygame


pygame.init()

# genutzte Farbe
ORANGE = ( 255, 140, 0)
ROT = ( 255, 0, 0)
GRUEN = ( 0, 255, 0)
SCHWARZ = ( 0, 0, 0)
WEISS = ( 255, 255, 255)

# Fenster öffnen
screen = pygame.display.set_mode((640, 480))

# Titel für Fensterkopf


pygame.display.set_caption("Unser erstes Pygame-Spiel")

# solange die Variable True ist, soll das Spiel laufen


spielaktiv = True

# Bildschirm Aktualisierungen einstellen


clock = pygame.time.Clock()

# Schleife Hauptprogramm
while spielaktiv:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat
for event in pygame.event.get():
if event.type == pygame.QUIT:
spielaktiv = False
print("Spieler hat Quit-Button angeklickt")
elif event.type == pygame.KEYDOWN:
print("Spieler hat Taste gedrückt")

# Taste für Spieler 1


if event.key == pygame.K_RIGHT:
print("Spieler hat Pfeiltaste rechts gedrückt")
elif event.key == pygame.K_LEFT:
print("Spieler hat Pfeiltaste links gedrückt")
elif event.key == pygame.K_UP:
print("Spieler hat Pfeiltaste hoch gedrückt")
elif event.key == pygame.K_DOWN:
print("Spieler hat Pfeiltaste runter gedrückt")
elif event.key == pygame.K_SPACE:
print("Spieler hat Leertaste gedrückt")

# Taste für Spieler 2


elif event.key == pygame.K_w:
print("Spieler hat Taste w gedrückt")
elif event.key == pygame.K_a:
print("Spieler hat Taste a gedrückt")
elif event.key == pygame.K_s:
print("Spieler hat Taste s gedrückt")
elif event.key == pygame.K_d:
print("Spieler hat Taste d gedrückt")

elif event.type == pygame.MOUSEBUTTONDOWN:


print("Spieler hast Maus angeklickt")

# Spiellogik hier integrieren

# Spielfeld löschen
screen.fill(WEISS)

# Spielfeld/figuren zeichnen

# Fenster aktualisieren
pygame.display.flip()

# Refresh-Zeiten festlegen
clock.tick(60)

pygame.quit()
© https://www.python-lernen.de/pygame-tutorial.htm Seite 375

Uns somit haben wir unser Template für unsere Spiele. Auf diese Basis können wir aufbauen.
© https://www.python-lernen.de/pygame-installieren-mac-os-x.htm Seite 376

Pygame installieren auf dem macOS


Im Folgenden eine einfache Möglichkeit, wenn PIP vorhanden ist. Bei PIP handelt es sich um
das Paketverwaltungsprogramm für Python-Pakete. Bei Bezeichnung „PIP“ steht für „pip
installs packages“.

Hier in 5 Schritten

Terminal starten

Testen, ob PIP3 vorhanden ist: pip3

Test, ob PIP vorhanden ist

Wenn vorhanden, dann einfach eintippen: pip3 install pygame

über PIP pygame installieren

Testen, ob Installation korrekt ausgeführt worden ist: Python Shell starten (über IDLE) >>>
import pygame

Installation von pygame testen

Wenn keine Fehlermeldung, dann lief alles nach Plan


© https://www.python-lernen.de/pygame-installieren-mac-os-x.htm Seite 377

Und nun viel Spaß beim Nutzen von Pygame.


© https://www.python-lernen.de/formen-zeichnen-pygame.htm Seite 378

Zeichnen mit Pygame


Mit Pygame können wir alle Formen zeichnen, die man so üblicherweise benötigt:

Rechtecke

Polygone

Kreise

Ellipsen

Linien

Für jede Art benötigen wir mehrere Angaben:

worauf soll gezeichnet werden (üblicherweise auf „screen“)

welche Farbe soll das Element haben

wo ist der Startpunkt (X und Y) und Breite und Höhe

Soll das Element ausgefüllt sein oder nur umrandet

Für ein Rechteck haben wir dann folgenden Befehlsaufbau:

pygame.draw.rect(screen, ROT, [10, 20, 100, 100], 1)

Wir erhalten ein rot umrandetes Rechteck

Rechteck mit Pygame zeichnen

Wenn die Umrandung dicker sein soll, wird die letzte Zahl (hier die 1) einfach größer gewählt.

Wollen wir ein farbig ausgefülltes Rechteck, wird die letzte Zahl auf 0 gesetzt (weglassen hat
den gleichen Effekt). Das mag im ersten Augenblick irritieren, funktioniert aber. Einfach einmal
testen:

pygame.draw.rect(screen, ROT, [10, 20, 100, 100])

Linien zeichnen (auch mit Antialiasing)


Wollen wir eine Linie zeichnen, ist der Aufbau zum Rechteck ähnlich. Anstelle der Breite und
Höhe wird der Endpunkt in Form eines Tupels angegeben. Auch hier kann die letzte Angabe mit
der Stärke der Linie weggelassen werden, was aber weniger schön und offensichtlich ist. Fehlt
die Angabe, wird die Linie 1 Pixel breit. Besser immer dazu machen.

pygame.draw.line(screen, ORANGE, [10, 20], [100, 120], 4)

In unserem Beispiel startet die Linie an dem Punkt, der sich 10 Pixel von linken oberen Eck in X-
Richtung und 20 Pixel in Y-Richtung befindet und läuft zu dem X-Punkt 100 und Y-Punkt 120
© https://www.python-lernen.de/formen-zeichnen-pygame.htm Seite 379

Linie mit Pygame zeichnen

Wir sehen eine Linie mit „Treppeneffekt“ – diesen Effekt können wir durch Antialiasing
beseitigen. Dafür gibt es in Pygame eine Anweisung (allerdings kann dann keine Strichstärke
mitgegeben werden):

# normale Linie (orange)


pygame.draw.line(screen, ORANGE, [10, 20], [100, 120])

# Linie mit Antialiasing (rot)


pygame.draw.aaline(screen, ROT, [20, 20], [110, 120])

Und in der Vergrößerung sieht man deutlich den Effekt der „gebügelten“ Linie.

Linie mit Antialiasing gezeichnet

Ellipsen bzw. Kreise zeichnen


Wichtig zum Zeichnen von Kreisen bzw. Ellipsen ist die Vorstellung eines Vierecks. Denn die
linke obere Ecke ist die, die auch für die Ellipse angegeben werden muss.

Grundsätzlich ist der Befehl sehr einfach:

pygame.draw.ellipse(screen, ORANGE, [10,30,150,100], 1)

Das Ergebnis sieht dann wie folgt aus.

Ellipse mit Pygame zeichnen

Zeichnen wir zusätzlich ein Viereck mit denselben Angaben, dann ist deutlich, wie
Ellipsen/Kreise funktionieren.

pygame.draw.ellipse(screen, ORANGE, [10,30,150,100], 1)


pygame.draw.rect(screen, ROT, [10, 30, 150, 100], 1)
© https://www.python-lernen.de/formen-zeichnen-pygame.htm Seite 380

Ellipse mit Pygame zeichnen – zum Verständnis das Quadrat

Möchte man einen Kreis erhalten, dann muss die dritte und vierte Angabe, sprich die Breite und
die Höhe die gleiche Abmessung haben.

pygame.draw.ellipse(screen, ORANGE, [10,30,150,150], 1)

Und somit erhalten wir einen Kreis.

Kreis mit Pygame zeichnen

Kreisausschnitt zeichnen
Um einen Kreisausschnitt zu zeichnen, benötigen wir weitere Angaben als beim Kreis.
Allerdings sind die ersten Angaben identisch:

worauf zeichnen (screen)

welche Farbe

In welchem Bereich (wie beim Kreis)

wo startet der Kreisausschnitt? Bei der Uhr auf 3 Uhr (einfach einmal probieren)

den Kreisausschnitt wird über PI angegeben, wobei PI einen Halbkreis ergibt

zum Schluss die Stärke des Strichs

pygame.draw.arc(screen, SCHWARZ, [10,10,200,200], 0, math.pi/2, 1)

Und nun mehrere Kreisausschnitte in verschiedenen Farben:

pygame.draw.arc(screen, SCHWARZ, [10,10,200,200], 0, math.pi, 1)


pygame.draw.arc(screen, ROT, [10,10,200,200], math.pi, 3*math.pi/2, 1)
© https://www.python-lernen.de/formen-zeichnen-pygame.htm Seite 381

Kreissegmente mit Pygame zeichnen

Polygone zeichnen
Bei einem Polygon können beliebig viele Punkte angeben werden und somit ein beliebig
komplexes Gebilde erstellt werden.

In unserem Beispiel erstellen wir ein Dreieck.

pygame.draw.polygon(screen, ROT, [[50,50], [50,200], [200,200]], 2)

Wenn wir uns den Aufbau der Koordinaten genau ansehen, sehen wir eine Liste in der weiteren
Liste geschachtelt sind.

Dreieck mit Pygame zeichnen

Text auf Bildschirm bringen


Für die Ausgabe von Text benötigen wir 3 Angaben:

Festlegung der Schrift (Schriftart, Farbe, Größe)

Den Textinhalt

Dieser wird dann auf den Bildschirm an einer bestimmten Position gebracht

Schauen wir uns die 3 Schritte in Form von Python-Code an, dann wird die Vorgehensweise
schnell klar:

schrift = pygame.font.SysFont('Arial', 35, True, False)


text = schrift.render("Textinhalt", True, ROT)
screen.blit(text, [250, 250])

Wir erzeugen ein Schriftobjekt mit einer festgelegten Schriftart und Schriftgröße. Möchte man
einfach die Systemschrift nutzen, kann hier die Angabe „None“ erfolgen:
© https://www.python-lernen.de/formen-zeichnen-pygame.htm Seite 382

schrift = pygame.font.SysFont('Arial', 35, True, False)

Die Angaben der Reihenfolge nach:

Schriftart

Schriftgröße

ob fett (bold)

ob kursiv (italics)

text = schrift.render("Textinhalt", True, ROT)

Die Angaben der Reihenfolge nach:

Textinhalt selber

ob Antialiasing angewendet werden soll

Farbe des Textes

screen.blit(text, [250, 250])


© https://www.python-lernen.de/pygame-animation.htm Seite 383

Spiel Pong: Bewegung des Balls - Elemente animieren


Viele Spiele leben von der Aktion auf dem Bildschirm. Hier kommt nun die
Animation von Elementen in unsere Programmierung. Wir werden im
folgenden Kapitel einen Ball animieren, wie wir diese aus dem Spieleklassiker
Pong kennen.

Hier spielen 2 Spieler praktisch Tischtennis (Ping-Pong) und der Blick auf das
Spielfeld ist von oben auf die Platte, den Ball und die Schläger. Grafisch
extrem simpel – was bei der Erstveröffentlichung von Pong 1972 so möglich
war. Lustigerweise war der Begriff „Ping Pong“ geschützt und so wurde das Spiel Pong
genannt.

Wir wollen jetzt nur einen Ball animieren, der immer, wenn der den Fensterrand erreicht, wieder
im entsprechenden Winkel abprallt.

Dazu benötigen wir unser Grundgerüst aus dem Kapitel „Grundgerüst für Spiele mit Pygame“.
© https://www.python-lernen.de/pygame-animation.htm Seite 384

# Importieren der Pygame-Bibliothek


import pygame

# initialisieren von pygame


pygame.init()

# genutzte Farbe
ORANGE = ( 255, 140, 0)
ROT = ( 255, 0, 0)
GRUEN = ( 0, 255, 0)
SCHWARZ = ( 0, 0, 0)
WEISS = ( 255, 255, 255)

# Fenster öffnen
screen = pygame.display.set_mode((640, 480))

# Titel für Fensterkopf


pygame.display.set_caption("Unser erstes Pygame-Spiel")

# solange die Variable True ist, soll das Spiel laufen


spielaktiv = True

# Bildschirm Aktualisierungen einstellen


clock = pygame.time.Clock()

# Schleife Hauptprogramm
while spielaktiv:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat
for event in pygame.event.get():
if event.type == pygame.QUIT:
spielaktiv = False
print("Spieler hat Quit-Button angeklickt")

# Spiellogik hier integrieren

# Spielfeld löschen
screen.fill(SCHWARZ)

# Spielfeld/figuren zeichnen

# Fenster aktualisieren
pygame.display.flip()

# Refresh-Zeiten festlegen
clock.tick(60)

pygame.quit()

Bei unserem Klassiker ist der Hintergrund des Spielfelds schwarz. Daher können wir jedes Mal,
wenn wir unser Spielfeld neu aufbauen (sprich löschen) einfach unseren screen mit der
Farbe Schwarz füllen:
© https://www.python-lernen.de/pygame-animation.htm Seite 385

# Spielfeld löschen
screen.fill(SCHWARZ)

Zur Erinnerung. Die Konstanten für die Farben (wie z.B. SCHWARZ) haben wir am Anfang
unseres Pygame-Programmes definiert:

# genutzte Farbe
ORANGE = ( 255, 140, 0)
SCHWARZ = ( 0, 0, 0)

Ball zeichnen für unser Spiel


Im letzten Kapitel haben wir bereits einen Kreis gezeichnet. Genau diesen wollen wir nun als
Spielball nutzen.

# Spielfeld/figuren zeichnen
pygame.draw.ellipse(screen, WEISS, [10,30,20,20])

Wir platzieren unseren Ball am Anfang mit dieser Anweisung an den Punkt X=10 und
Y=30

Allerdings wollen wir unseren Ball animieren. Also setzten wir diese Werte nicht fest
als Zahl, sondern nutzen Variablen. Nennen wir diese ballpos_x und
ballpos_y . Unsere Ballposition steckt also in diesen beiden Variablen, die wir vor
der Hauptroutine definieren müssen:

# Definieren der Variablen


ballpos_x = 10
ballpos_y = 30

# Schleife Hauptprogramm
while spielaktiv:

Jetzt können wir diese Variablen beim Zeichnen unseres Kreises nutzen:

pygame.draw.ellipse(screen, WEISS, [ballpos_x, ballpos_y, 20, 20])

Unser Ball ruht nun in der Ecke und das Spiel wird extrem spannungslos ohne Bewegung (man
könnte auch langweilig dazu sagen).

Ball bewegen (sprich animieren)


Jetzt können wir in unserer Hauptroutine diese 2 Werte bei jedem Schleifendurchlauf ändern
und der Ball bewegt sich dann. Das muss innerhalb der Hauptroutine geschehen!
© https://www.python-lernen.de/pygame-animation.htm Seite 386

# Schleife Hauptprogramm
while spielaktiv:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat
for event in pygame.event.get():
if event.type == pygame.QUIT:
spielaktiv = False

# Spielfeld/figuren zeichnen
pygame.draw.ellipse(screen, WEISS, [ballpos_x, ballpos_y, 20, 20])

# bewegen unseres Kreises


ballpos_x += 4
ballpos_y += 4

Hurra, unser Spielball bewegt sich nach unten rechts. Und hoppla – er verschwindet auf
Nimmerwiedersehen aus dem sichtbaren Bereich (und rollt unter irgendeinen Schrank
bestimmt).

Also müssen wir darauf reagieren, wenn der Ball den Spielrand erreicht. Über das Erstellen der
Fenstergröße wissen wir, ab wann der Ball aus dem sichtbaren Bereich verschwindet:

# Fenster öffnen
screen = pygame.display.set_mode((640, 480))

Und auch hier sollten wir nicht mit direkt eingetragenen Werten (im Beispiel 640 und 480)
arbeiten, sondern mit Variablen (oder in dem Fall Konstanten), da diese Größen sich ja während
dem gesamten Spielablauf nicht ändern.

Setzen wir also hier diese Zahlen als Konstanten:

FENSTERBREITE = 640
FENSTERHOEHE = 480

# Fenster öffnen
screen = pygame.display.set_mode((FENSTERBREITE, FENSTERHOEHE))

Die gewählten Begriffe im Deutschen sind zwar sehr lang, dafür sollte aber klar sein, welche
Werte sich dahinter verbergen. Und jetzt können wir kontrollieren, ob der Ball das sichtbare
Fenster verlassen möchte.

Ball am Fensterrand abprallen lassen


Wir kennen die Position des Balls über die Variablen ballpos_x und ballpos_y und wir
kennen die Größe des Spielfelds anhand der Konstanten FENSTERBREITE und
FENSTERHOEHE .

Überprüfen wir als Erstes, ob der Ball am unteren Rand ankommt. Hier wissen wir, wenn der
Wert der Variable ballpos_y größer ist als die Konstante FENSTERHOEHE , dann sollten wir
die Bewegungsrichtung ändern. Die Bewegungsrichtung ändern sich, indem wir die
ballpos_y wieder verkleinern. Anstelle von „plus 4“ werden wir dann „minus 4“ rechnen.

Also benötigen wir eine Abfrage, bevor wir unseren Kreis bewegen. Bisher haben wir für unsere
Bewegung:
© https://www.python-lernen.de/pygame-animation.htm Seite 387

# bewegen unseres Kreises


ballpos_x += 4
ballpos_y += 4

Natürlich wollen wir auch hier nicht mit fest eingetragenen Werten wie im Beispiel „4“ arbeiten,
sondern auch hier eine Variable nutzen. Eigentlich sollten wir die Variablen nennen wie z.B.
„bewegungsaenderung_x“ – aber das ist deutlich zu lang. Wir nutzen dafür die Variablen mit
der Bezeichnung bewegung_x und bewegung_y . Auch diese müssen außerhalb unserer
Hauptschleife das erste Mal festgelegt werden, um dann in der Hauptschleife genutzt zu
werden.

# Definieren der Variablen


ballpos_x = 10
ballpos_y = 30

bewegung_x = 4
bewegung_y = 4

Und innerhalb der Hauptschleife ändern wir von „ballpos_x += 4“ zu:

# bewegen unseres Kreises


ballpos_x += bewegung_x
ballpos_y += bewegung_y

Jetzt wollen wir über eine if -Abfrage die Berührung des Fensterrands kontrollieren:

if ballpos_y < FENSTERHOEHE:


ballpos_y += bewegung_y
else:
ballpos_y -= bewegung_y

Das wäre im ersten Augenblick eine Variante, die aber leider dazu führt, dass der Ball bei
Verlassen des unteren Fensterbereichs nicht nach oben fliegt, sondern dann nach rechts
wegrutscht.

Wir müssen also EINMAL die Bewegungsrichtung ändern. Dazu nutzen wir den
mathematischen Trick von * -1 . So können wir die Bewegungsrichtung „umschalten“. Zur
Erinnerung an die alten Schulzeiten die 2 wichtigen Fälle von „mal minus 1“:

Haben wir ein + wird durch * -1 aus dem Plus ein Minus.

Haben wir ein – wird durch * -1 aus dem Minus ein Plus.

Die benötigten Variablen für die beiden Bewegungsrichtungen haben wir bereits und können
dann darauf unsere Mathematik anwenden.

if ballpos_y > FENSTERHOEHE:


bewegung_y = bewegung_y * -1

Wenn man es testet, dann verschwindet der Ball fast unten (darum kümmern wir uns später)
und springt dann nach oben, um rechts zu verschwinden. Also kümmern wir uns um den
rechten Rand. Hier dieselbe Vorgehensweise, nur für unsere x-Bewegung:

if ballpos_x > FENSTERBREITE:


bewegung_x = bewegung_x * -1

Jetzt überlebt unser Ball unten und rechts, aber verschwindet oben aus dem Fensterrahmen
© https://www.python-lernen.de/pygame-animation.htm Seite 388

bzw. links. Also auch hierfür die entsprechende Abfrage wobei wir einfach mit 0 vergleichen
(was den oberen und den linken Fensterrand darstellt):

Unsere bisher komplette Abfrage:

if ballpos_y > FENSTERHOEHE:


bewegung_y = bewegung_y * -1

if ballpos_x > FENSTERBREITE:


bewegung_x = bewegung_x * -1

if ballpos_y < 0:
bewegung_y = bewegung_y * -1

if ballpos_x < 0:
bewegung_x = bewegung_x * -1

Das funktioniert zwar, aber kürzer ist schöner – also machen wir aus den 8 Zeilen nur noch 4
und fassen die if -Abfragen zusammen:

if ballpos_y > FENSTERHOEHE or ballpos_y < 0:


bewegung_y = bewegung_y * -1

if ballpos_x > FENSTERBREITE or ballpos_x < 0:


bewegung_x = bewegung_x * -1

Jetzt haben wir noch den Schönheitsfehler, dass der Ball unten und rechts aus dem sichtbaren
Bereich fast verschwindet. Unsere Rechnung ist bisher nicht exakt richtig: wir vergleichen die
Ballposition mit der Fensterbreite (bzw. Höhe). Aber eigentlich ist die Breite (bzw. Höhe des
Balls) auch noch ausschlaggebend. Daher sollten wir berechnen:

(FENSTERHOEHE – Balldurchmesser)

Und auch hier gehört eine Variable (bzw. Konstante her). Wir müssen diese Konstante bereits
(wie die anderen auch) im Vorfeld definieren, können diese beim Zeichnen unseres Balls
verwenden und dann bei der if -Abfrage einsetzen:

Wieder wollen wir einen sprechenden Namen haben – wer die mathematischen Bezeichnungen
gewohnt ist, wird „d“ für Durchmesser nehmen, sprich die Konstantenbezeichnung wäre dann
„BALL_D“ – wir nutzen lieber für 100 % Transparenz den wuchtigen Namen:
BALL_DURCHMESSER“

Also Vorneweg definieren:

# Definieren der Variablen/Konstanten


ballpos_x = 10
ballpos_y = 30

BALL_DURCHMESSER = 20

Und einsetzen beim Kreis zeichnen:

pygame.draw.ellipse(screen, WEISS, [ballpos_x, ballpos_y, BALL_DURCHMESSER, BALL_D


© https://www.python-lernen.de/pygame-animation.htm Seite 389

Und noch in der Abfrage wegen Fensterrand:

if ballpos_y > FENSTERHOEHE - BALL_DURCHMESSER or ballpos_y < 0:


bewegung_y = bewegung_y * -1

if ballpos_x > FENSTERBREITE - BALL_DURCHMESSER or ballpos_x < 0:


bewegung_x = bewegung_x * -1

Und somit haben wir einen wunderbar herum springenden Ball. Wir können die Spielfeldgröße,
Ballgröße und Geschwindigkeit durch Ändern der Werte bei der entsprechenden Variablen
(bzw. Konstanten) schnell anpassen und alle Programmteile reagieren darauf.

Hier der komplette Quellcode:

# Importieren der Pygame-Bibliothek


import pygame, math

# initialisieren von pygame


pygame.init()

# genutzte Farbe
ORANGE = ( 255, 140, 0)
ROT = ( 255, 0, 0)
GRUEN = ( 0, 255, 0)
SCHWARZ = ( 0, 0, 0)
WEISS = ( 255, 255, 255)

FENSTERBREITE = 640
FENSTERHOEHE = 480

# Fenster öffnen
screen = pygame.display.set_mode((FENSTERBREITE, FENSTERHOEHE))

# Titel für Fensterkopf


pygame.display.set_caption("Unser erstes Pygame-Spiel")

# solange die Variable True ist, soll das Spiel laufen


spielaktiv = True

# Bildschirm Aktualisierungen einstellen


clock = pygame.time.Clock()

# Definieren der Variablen/Konstanten


ballpos_x = 10
ballpos_y = 30

BALL_DURCHMESSER = 20

bewegung_x = 4
bewegung_y = 4

# Schleife Hauptprogramm
while spielaktiv:
© https://www.python-lernen.de/pygame-animation.htm Seite 390

while spielaktiv:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat
for event in pygame.event.get():
if event.type == pygame.QUIT:
spielaktiv = False

# Spiellogik hier integrieren

# Spielfeld löschen
screen.fill(SCHWARZ)

# Spielfeld/figuren zeichnen
pygame.draw.ellipse(screen, WEISS, [ballpos_x, ballpos_y, BALL_DURCHMESSER

# bewegen unseres Kreises


ballpos_x += bewegung_x
ballpos_y += bewegung_y

if ballpos_y > FENSTERHOEHE - BALL_DURCHMESSER or ballpos_y < 0:


bewegung_y = bewegung_y * -1

if ballpos_x > FENSTERBREITE - BALL_DURCHMESSER or ballpos_x < 0:


bewegung_x = bewegung_x * -1

# Fenster aktualisieren
pygame.display.flip()

# Refresh-Zeiten festlegen
clock.tick(60)

pygame.quit()
quit()
© https://www.python-lernen.de/pygame-tastatur-abfragen.htm Seite 391

Steuerung durch Spieler: Tastatur, Maus und Game


Controller
Pygame unterstützt uns und das Einbinden der Steuerung der Spielfiguren und Bewegen durch
den Spieler ist kein Problem. Wir haben bereits bei unserem Grundgerüst aus dem ersten
Pygame-Kapitel eine Abfrage der Tastatur integriert. In diesem Kapitel wollen wir die
Spielsteuerung auch mit einer Spielerfigur verbinden und Aktion auf dem Bildschirm sehen.

Im ersten Schritt werden wir die Spielerfigur mit der Tastatur steuern – in einem folgenden
Kapitel wird die Abfrage der Maus und Game-Controller über Pygame gezeigt.

Wir benötigen unser Grundgerüst aus dem Kapitel „Grundgerüst für Spiele mit Pygame“.

Als Erstes benötigen wir eine Spielerfigur – aus dem letzten Kapitel mit Pong benötigen wir
einen Tischtennisschläger. Dieser wird Grafisch ganz simpel über ein Rechteck dargestellt.
Auch hier benötigen wir wieder die Definition der Variablen außerhalb unsere Hauptroutine.

Für den ersten Spieler legen wird fest:

spielfigur_1_x

spielfigur_1_y

Diese setzen wir auf die linke Spielbrettseite an die Position X = 20 und Y = 20:

spielfigur_1_x = 20
spielfigur_1_y = 20

# Schleife Hauptprogramm
while spielaktiv:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat

Nun zeichnen wir innerhalb der Hauptroutine den Tischtennisschläger des ersten Spielers:

# Spielfeld/figuren zeichnen
# -- Ball
pygame.draw.ellipse(screen, WEISS, [ballpos_x, ballpos_y, BALL_DURCHMESSER, BALL_DURCH

# -- Spielerfigur 1
pygame.draw.rect(screen, WEISS, [spielfigur_1_x, spielfigur_1_y, 20, 100])

Tastatur abfragen und in Variablen speichern


In unserer Hauptschleife wird nun die Tastatur abgefragt. Hier können wir unsere
Programmcodevorlage aus dem ersten Kapitel entsprechend erweitern und die im Vorfeld
(was wir noch tun müssen) gesetzt Variable spielfigur_1_bewegung mit entweder einer
positiven Zahl (für die Bewegung nach unten) oder mit einer negativen Zahl (für die Bewegung
nach oben) ändern. Eine Variable reicht aus, weil unsere Spielfigur sich nur nach oben bzw.
nach unten bewegen kann!
© https://www.python-lernen.de/pygame-tastatur-abfragen.htm Seite 392

spielfigur_1_x = 20
spielfigur_1_y = 20
spielfigur_1_bewegung = 0

# Schleife Hauptprogramm
while spielaktiv:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat
for event in pygame.event.get():
if event.type == pygame.QUIT:
spielaktiv = False
print("Spieler hat Quit-Button angeklickt")
elif event.type == pygame.KEYDOWN:
print("Spieler hat Taste gedrückt")

# Taste für Spieler 1


elif event.key == pygame.K_UP:
print("Spieler hat Pfeiltaste hoch gedrückt")
spielfigur_1_bewegung = -6
elif event.key == pygame.K_DOWN:
print("Spieler hat Pfeiltaste runter gedrückt")
spielfigur_1_bewegung = 6

Zusätzlich erweitern wir unsere Programmcodevorlage um die Möglichkeit, das Spiel auch mit
der Escape-Taste beenden zu können. Somit kann das Spiel entweder über das Schließen des
Fensters oder über die Escape-Taste beendet werden:

if event.type == pygame.QUIT or event.type == pygame.KEYDOWN and event.key ==

Wichtig: Trennung Spiellogik und Zeichnen


Wichtig ist die Trennung zwischen der Eingabeabfrage (wohin wollen die Spieler ihre Figur
bewegen) und dem eigentlichen Zeichnen! Sonst kommt ersten schnell Chaos in die
Programmierung und zweitens können wir die Spielerfigur (in dem Fall den Schläger) nicht
beliebig weit nach unten bzw. oben bewegen. Denn sonst würde dieser aus dem Spielfeld
verschwinden.

Aber der Reihe nach – vor dem Zeichnen kommt die Berechnung. Dazu haben wir im Ablauf
unseres Programms den Punkt „# Spiellogik“ vorgesehen. Danach zeichnen wir frisch den
Schläger. Dazu müssen wir einfach die bisher fixen Werte durch das Ergebnis der neuen
Variablen spielfigur_1_bewegung ersetzen.
© https://www.python-lernen.de/pygame-tastatur-abfragen.htm Seite 393

spielfigur_1_bewegung = 0

# Schleife Hauptprogramm
while spielaktiv:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat
for event in pygame.event.get():
if event.type == pygame.QUIT:
spielaktiv = False
print("Spieler hat Quit-Button angeklickt")

if event.type == pygame.KEYDOWN:
print("Spieler hat Taste gedrückt")

# Taste für Spieler 1


if event.key == pygame.K_UP:
print("Spieler hat Pfeiltaste runter gedrückt")
spielfigur_1_bewegung = -6
elif event.key == pygame.K_DOWN:
print("Spieler hat Pfeiltaste runter gedrückt")
spielfigur_1_bewegung = 6

# Spiellogik
if spielfigur_1_bewegung != 0:
spielfigur_1_y += spielfigur_1_bewegung

Spieler im sichtbaren Bereich halten


Bevor der Schläger aus der sichtbaren Fläche verschwindet, müssen wir bei der Spiellogik dies
verhindern.

Die Position des Schlägers darf nicht kleiner als 0 werden. Dazu Überprüfen wir die y-Position
und wird diese kleiner als 0, setzten wird diese einfach wieder auf 0 zurück. Dies ist die
einfachere Möglichkeit als viel Aufwand zu treiben und im Vorfeld darauf zu überprüfen.

# Spiellogik
if spielfigur_1_bewegung != 0:
spielfigur_1_y += spielfigur_1_bewegung

if spielfigur_1_y < 0:
spielfigur_1_y = 0

Wenn wir das Gleich für den unteren Fensterbereich machen wollen, dann sollten wir unbedingt
die Höhe des Schlägers berücksichtigen. Die erste gezeigte Variante ist suboptimal:

if spielfigur_1_y > FENSTERHOEHE:


spielfigur_1_y = FENSTERHOEHE

Besser (noch nicht optimal) ist:

if spielfigur_1_y > FENSTERHOEHE - 100:


spielfigur_1_y = FENSTERHOEHE – 100

Und noch besser ist, wenn wir wieder mit Variablen arbeiten (hier kann man sich streiten, ob
das auch eine Konstante sein sollte). Aber einfach einmal als Gedanken für mehr Spielspaß,
© https://www.python-lernen.de/pygame-tastatur-abfragen.htm Seite 394

dass der Schläger umso kleiner wird, je länger das Spiel läuft als Spielerschwernis. Daher
machen wir eine Variable.

Also vornweg wieder definieren und dann nutzen:

spielfigur_1_bewegung = 0

schlaegerhoehe = 100

# Schleife Hauptprogramm

Und für die Berechnung der Spiellogik und die Bewegung:

# Spiellogik
if spielfigur_1_bewegung != 0:
spielfigur_1_y += spielfigur_1_bewegung

if spielfigur_1_y < 0:
spielfigur_1_y = 0

if spielfigur_1_y > FENSTERHOEHE - schlaegerhoehe:


spielfigur_1_y = FENSTERHOEHE - schlaegerhoehe

# Spielfeld löschen
screen.fill(SCHWARZ)

# Spielfeld/figuren zeichnen
# -- Ball
pygame.draw.ellipse(screen, WEISS, [ballpos_x, ballpos_y, BALL_DURCHMESSER, BALL_DURCH

# -- Spielerfigur 1
pygame.draw.rect(screen, WEISS, [spielfigur_1_x, spielfigur_1_y, 20, schlaegerhoehe

Bewegung stoppen, wenn die Taste losgelassen wird


Bei der bisherigen Tastaturabfrage gaben wir immer geschaut, ob eine Taste gedrückt wurde
und haben dann die entsprechende Variable für die Bewegung gesetzt. Wenn wir die Bewegung
stoppen wollen, dann können wir einfach abfragen, ob eine bestimmte Taste losgelassen
wurde, nachdem diese gedrückt wurde. Ist das der Fall, dann kann man die Variable für die
Bewegung auf 0 setzen.

Machen wir das Beispielhaft für den ersten Spieler:

# zum Stoppen der Spielerbewegung


if event.type == pygame.KEYUP:
print("Spieler hat Taste losgelassen")

# Tasten für Spieler 1


if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
print("Spieler 1 stoppt bewegung")
spielfigur_1_bewegung = 0

Für den zweiten Spieler ist es dasselbe.


© https://www.python-lernen.de/pygame-tastatur-abfragen.htm Seite 395

Zweiter Spieler
Das war die Steuerung für die erste Spielfigur. Jetzt benötigen wir es für die Zweite. Hier gibt
es die Variante, einfach wieder so vorzugehen wie wir es bei der ersten Spielfigur gemacht
haben oder eine schönere Lösung über Funktionen (was wir später machen). Bei 2 Spielern
wählen wir den erst einmal den simplen Weg, was wir später durch Funktionen dann ändern.
Didaktisch wichtig ist, langsam das Verständnis aufzubauen.

Wir benötigen für unseren 2 Spieler wieder die entsprechenden Variablen:

spielfigur_1_x = 20
spielfigur_1_y = 20
spielfigur_1_bewegung = 0

spielfigur_2_x = FENSTERBREITE - (2 * 20)


spielfigur_2_y = 20
spielfigur_2_bewegung = 0

schlaegerhoehe = 60

# Schleife Hauptprogramm

Bei den Tasten, die wir für die Steuerung auswählen, nutzen wir nun aus Tradition die Tasten
w und s .

In der Hauptschleife erweitern die Kontrolle für die Steuerung:


© https://www.python-lernen.de/pygame-tastatur-abfragen.htm Seite 396

# Schleife Hauptprogramm
while spielaktiv:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat
for event in pygame.event.get():
if event.type == pygame.QUIT:
spielaktiv = False
print("Spieler hat Quit-Button angeklickt")

if event.type == pygame.KEYDOWN:
print("Spieler hat Taste gedrückt")

# Taste für Spieler 1


if event.key == pygame.K_UP:
print("Spieler hat Pfeiltaste runter gedrückt")
spielfigur_1_bewegung = -6
elif event.key == pygame.K_DOWN:
print("Spieler hat Pfeiltaste runter gedrückt")
spielfigur_1_bewegung = 6

# Taste für Spieler 2


elif event.key == pygame.K_w:
print("Spieler 2 hat w für hoch gedrückt")
spielfigur_2_bewegung = -6
elif event.key == pygame.K_s:
print("Spieler 2 hat s für runter gedrückt")
spielfigur_2_bewegung = 6

# zum Stoppen der Spielerbewegung


if event.type == pygame.KEYUP:
print("Spieler hat Taste losgelassen")

# Tasten für Spieler 1


if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
print("Spieler 1 stoppt bewegung")
spielfigur_1_bewegung = 0

# Tasten für Spieler 2


elif event.key == pygame.K_w or event.key == pygame.K_s:
print("Spieler 1 stoppt bewegung")
spielfigur_2_bewegung = 0

Und erweitern die Spiellogik:


© https://www.python-lernen.de/pygame-tastatur-abfragen.htm Seite 397

# Spiellogik
if spielfigur_1_bewegung != 0:
spielfigur_1_y += spielfigur_1_bewegung

if spielfigur_1_y < 0:
spielfigur_1_y = 0

if spielfigur_1_y > FENSTERHOEHE - schlaegerhoehe:


spielfigur_1_y = FENSTERHOEHE - schlaegerhoehe

if spielfigur_2_bewegung != 0:
spielfigur_2_y += spielfigur_2_bewegung

if spielfigur_2_y < 0:
spielfigur_2_y = 0

if spielfigur_2_y > FENSTERHOEHE - schlaegerhoehe:


spielfigur_2_y = FENSTERHOEHE - schlaegerhoehe

Und noch den Schläger für den zweiten Spieler zeichnen:

# Spielfeld/figuren zeichnen
# -- Ball
pygame.draw.ellipse(screen, WEISS, [ballpos_x, ballpos_y, BALL_DURCHMESSER, BALL_DURCH

# -- Spielerfigur 1
pygame.draw.rect(screen, WEISS, [spielfigur_1_x, spielfigur_1_y, 20, schlaegerhoehe
# -- Spielerfigur 2
pygame.draw.rect(screen, WEISS, [spielfigur_2_x, spielfigur_2_y, 20, schlaegerhoehe

Somit haben wir die Interaktion vom den 2 Spieler eingebaut, die nun Ihre Schläger bewegen
können. Nun sollte der Ball noch entsprechend reagieren, wenn dieser auf die Schläger auftrifft:
Wir benötigen eine Kollisionskontrolle. Diese schauen wir uns im folgenden Kapitel an.

Alle Kürzel für die komplette Tastatur


Zum Abrunden des Kapitels über die Steuerug durch Tastatureingaben hier alle Bezeichnungen
der Tasten um diese über Pygame abfragen zu können.

Pygame Code Bezeichnung

K_BACKSPACE Backspace-Taste (dt. Rücktaste)

K_RETURN Return

K_TAB Tab-Taste

K_ESCAPE Escape

K_SPACE Leertaste

K_COMMA , Komma

K_MINUS - Minus

K_PERIOD period slash


© https://www.python-lernen.de/pygame-tastatur-abfragen.htm Seite 398

Pygame Code Bezeichnung

K_SLASH / Schrägstrich

K_0 0

K_1 1

K_2 2

K_3 3

K_4 4

K_5 5

K_6 6

K_7 7

K_8 8

K_9 9

K_SEMICOLON ; Semikolon

K_EQUALS = Gleichheitszeichen

K_LEFTBRACKET [ linke Klammer

K_RIGHTBRACKET ] rechte Klammer

K_BACKSLASH Rückwärtsschrägstrich

K_BACKQUOTE rückwärts geneigtes Hochkomma

K_a a

K_b b

K_c c

K_d d

K_e e

K_f f

K_g g

K_h h

K_i i

K_j j

K_k k

K_l l

K_m m

K_n n

K_o o

K_p p

K_q q
© https://www.python-lernen.de/pygame-tastatur-abfragen.htm Seite 399

Pygame Code Bezeichnung

K_r r

K_s s

K_t t

K_u u

K_v v

K_w w

K_x x

K_y y

K_z z

K_DELETE Taste delete

K_KP0 Zehnerblock 0

K_KP1 Zehnerblock 1

K_KP2 Zehnerblock 2

K_KP3 Zehnerblock 3

K_KP4 Zehnerblock 4

K_KP5 Zehnerblock 5

K_KP6 Zehnerblock 6

K_KP7 Zehnerblock 7

K_KP8 Zehnerblock 8

K_KP9 Zehnerblock 9

K_KP_PERIOD . Zehnerblock Punkt

K_KP_DIVIDE // Zehnerblock geteilt

K_KP_MULTIPLY * Zehnerblock mal

K_KP_MINUS - Zehnerblock Minus

K_KP_PLUS Zehnerblock Plus

K_KP_ENTER Zehnerblock Enter

K_KP_EQUALS = Zehnerblock Gleich

K_UP Pfeil hoch

K_DOWN Pfeil nach unten

K_RIGHT Pfeil rechts

K_LEFT Pfeil links

K_INSERT Taste Einfügen

K_HOME Taste Home

K_END Taste Ende


© https://www.python-lernen.de/pygame-tastatur-abfragen.htm Seite 400

Pygame Code Bezeichnung

K_PAGEUP Taste Seite hoch

K_PAGEDOWN Taste Seite nach unten

K_F1 F1

K_F2 F2

K_F3 F3

K_F4 F4

K_F5 F5

K_F6 F6

K_F7 F7

K_F8 F8

K_F9 F9

K_F10 F10

K_F11 F11

K_F12 F12

K_NUMLOCK Taste numlock

K_CAPSLOCK Feststelltaste

K_RSHIFT Shift rechts

K_LSHIFT Shift links

K_RCTRL ctrl (STRG) Taste rechts

K_LCTRL ctrl (STRG) Taste links

K_RALT alt-Taste rechts

K_LALT alt-Taste links


© https://www.python-lernen.de/pygame-kollisions-kontrolle.htm Seite 401

Kollisionskontrolle: Aktion bei Berührung der Spielerfigur


Unser Spiel macht natürlich nur Spaß, wenn im Spiel die Schläger auch eine Wirkung zeigen
und der Ball dann entsprechend physikalisch korrekt abprallt.

Dazu müssen wir im Programm auch mitbekommen, ob der Ball den Schläger berührt oder
verfehlt. Dazu ist eine Kollisionskontrolle im Pygame integriert, die das für uns als
Programmierer sehr einfach macht. Diese Anweisung ist colliderect . Wenn wir die
Anweisung ansehen, steckt dort 2 Wörter darin: collide (engl. für „kollidieren“) und die
Abkürzung rect (rectangle) steht für ein Rechteck.

Wir können also mit einem Befehl überprüfen, ob eine Kollision zwischen 2 Rechtecken
vorliegt. Auch wenn unser Ball als Kreis gezeichnet ist, funktioniert die Kollisionskontrolle
trotzdem hervorragend. Wir wollen unsere Spielerfigur player1 und unseren Spielball
ball auf eine Kollision überprüfen:

player1.colliderect(ball)

Wir erhalten bei der Kontrolle auf eine Kollision zwischen der Spielerfigur und dem Ball ein
True als Rückgabewert, wenn eine Kollision vorliegt. Also können wir hier eine if -Abfrage
durchführen:

if player1.colliderect(ball):
print("Zusammenstoß Spieler 1 und Ball")

Jetzt müssen wir darauf reagieren und die X-Bewegung umdrehen. Mathematisch
funktioniert das über das Multiplizieren mit -1:

if player1.colliderect(ball):
print("Zusammenstoß Spieler 1 und Ball")
bewegung_x = bewegung_x * -1

Wenn wir den Code probieren, dann sieht die Bewegung sehr merkwürdig aus und wir
bekommen als Rückmeldung in der Konsole, dass es mehrere Kollisionen gab. Was ist
passiert. Da unser Ball sich mit einer Geschwindigkeit von 6 Pixeln bewegen kann, wird die
Kollision irgendwo zwischen Pixel 1 und 6 vom Programm erst wahrgenommen. Pro
Durchgang in der Hauptroutine liegt immer 6 Pixel Unterschied zur letzten Ballposition.
Würde die gleich am Anfang liegen (Pixel 1) würde er wie gewünscht abprallen. Liegt die
Kollision allerdings bei Pixel 2, ändert er die Richtung, aber es liegt sofort wieder eine
Kollision vor und er ändert wieder die Richtung. Das kann einige Male passieren. So eine
Reaktion wollen wir nicht wirklich.

Um uns nicht in ewigen Berechnungen zu verlieren, setzen wir die Ballposition ballpos_x
einfach vor dem Schläger und fertig.

if player1.colliderect(ball):
print("Zusammenstoß P1")
bewegung_x = bewegung_x * -1
ballpos_x = 40

In unserer if -Schleife haben wir nun noch weitere Möglichkeiten:

wir können die Anzahl der Ballwechsel zählen

wir können bei jedem Ballwechsel die Größe des Schlägers verkleinern und somit das Spiel
schwieriger machen
© https://www.python-lernen.de/pygame-kollisions-kontrolle.htm Seite 402

Um die Ballwechsel zu zählen, benötigen wir noch eine Variable ballwechsel , die wir vor
der Schleife erstellen müssen, damit wir diese bei Kollision erhöhen können.

# Definieren der Variablen/Konstanten


schlaegerhoehe = 220

ballwechsel = 0

# Schleife Hauptprogramm
while spielaktiv:

Und innerhalb der Kollisionskontrolle:

if player1.colliderect(ball):
print("Zusammenstoß P1")
bewegung_x = bewegung_x * -1
ballpos_x = 40
ballwechsel += 1

Wollen wir noch die Größe des Schlägers beeinflussen, dann verkleinern wir die Variable für
die Schlägerhöhe:

if player1.colliderect(ball):
print("Zusammenstoß P1")
bewegung_x = bewegung_x * -1
ballpos_x = 40
ballwechsel += 1
schlaegerhoehe -= 5

Das Ganze müssen wir noch für den zweiten Spieler genauso machen, allerdings wird dort die
Ballposition links vor dem Schläger gesetzt. Die brachiale Variante ist ballpos_x = 570 -
besser wäre die Berechnung über unsere Konstante für Spielfeldbreite und Schlägerbreite
(darf man machen, wenn alles so weit funktioniert – daher hier die brachiale Variante:

if player2.colliderect(ball):
print("Zusammenstoß P2")
bewegung_x = bewegung_x * -1
ballpos_x = 570
ballwechsel += 1
schlaegerhoehe -= 5

Und nun können wir endlich das Spiel richtig testen. Viel Spaß beim ersten Match:

Sinnvoll ist noch die Ausgabe der Anzahl der Ballwechsel:

ausgabetext = "Ballwechsel: " + str(ballwechsel)


font = pygame.font.SysFont(None, 70)
text = font.render(ausgabetext, True, ROT)
screen.blit(text, [100, 10])

# Fenster aktualisieren
pygame.display.flip()

Und der komplette Quellcode für unser Spiel Pong:

# Importieren der Pygame-Bibliothek


© https://www.python-lernen.de/pygame-kollisions-kontrolle.htm Seite 403

# Importieren der Pygame-Bibliothek


import pygame, math
from pygame.locals import *

# initialisieren von pygame


pygame.init()

# genutzte Farbe
ORANGE = ( 255, 140, 0)
ROT = ( 255, 0, 0)
GRUEN = ( 0, 255, 0)
SCHWARZ = ( 0, 0, 0)
WEISS = ( 255, 255, 255)

FENSTERBREITE = 640
FENSTERHOEHE = 480

# Fenster öffnen
screen = pygame.display.set_mode((FENSTERBREITE, FENSTERHOEHE))

# Titel für Fensterkopf


windowSurface = pygame.display.set_caption("Unser erstes Pygame-Spiel")
spielaktiv = True

# Bildschirm Aktualisierungen einstellen


clock = pygame.time.Clock()

# Definieren der Variablen/Konstanten


ballpos_x = 10
ballpos_y = 30

BALL_DURCHMESSER = 20

bewegung_x = 4
bewegung_y = 4

spielfigur_1_x = 20
spielfigur_1_y = 20
spielfigur_1_bewegung = 0

spielfigur_2_x = FENSTERBREITE - (2 * 20)


spielfigur_2_y = 20
spielfigur_2_bewegung = 0

schlaegerhoehe = 220

ballwechsel = 0

# Schleife Hauptprogramm
while spielaktiv:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat
for event in pygame.event.get():
if event.type == pygame.QUIT or event.type == pygame.KEYDOWN and event.key ==
© https://www.python-lernen.de/pygame-kollisions-kontrolle.htm Seite 404

spielaktiv = False
print("Spieler hat Quit-Button angeklickt")
if event.type == pygame.KEYDOWN:
print("Spieler hat Taste gedrückt")

# Taste für Spieler 1


if event.key == pygame.K_UP:
print("Spieler hat Pfeiltaste runter gedrückt")
spielfigur_1_bewegung = -6
elif event.key == pygame.K_DOWN:
print("Spieler hat Pfeiltaste runter gedrückt")
spielfigur_1_bewegung = 6

# Taste für Spieler 2


elif event.key == pygame.K_w:
print("Spieler 2 hat w für hoch gedrückt")
spielfigur_2_bewegung = -6
elif event.key == pygame.K_s:
print("Spieler 2 hat s für runter gedrückt")
spielfigur_2_bewegung = 6

# zum Stoppen der Spielerbewegung


if event.type == pygame.KEYUP:
print("Spieler hat Taste losgelassen")

# Tasten für Spieler 1


if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
print("Spieler 1 stoppt bewegung")
spielfigur_1_bewegung = 0

# Tasten für Spieler 2


elif event.key == pygame.K_w or event.key == pygame.K_s:
print("Spieler 1 stoppt bewegung")
spielfigur_2_bewegung = 0

# Spiellogik
if spielfigur_1_bewegung != 0:
spielfigur_1_y += spielfigur_1_bewegung

if spielfigur_1_y < 0:
spielfigur_1_y = 0

if spielfigur_1_y > FENSTERHOEHE - schlaegerhoehe:


spielfigur_1_y = FENSTERHOEHE - schlaegerhoehe

if spielfigur_2_bewegung != 0:
spielfigur_2_y += spielfigur_2_bewegung

if spielfigur_2_y < 0:
spielfigur_2_y = 0

if spielfigur_2_y > FENSTERHOEHE - schlaegerhoehe:


spielfigur_2_y = FENSTERHOEHE - schlaegerhoehe
© https://www.python-lernen.de/pygame-kollisions-kontrolle.htm Seite 405

spielfigur_2_y = FENSTERHOEHE - schlaegerhoehe

# Spielfeld löschen
screen.fill(SCHWARZ)

# Spielfeld/figuren zeichnen
# -- Ball
ball = pygame.draw.ellipse(screen, WEISS, [ballpos_x, ballpos_y, BALL_DURCHMESSER

# -- Spielerfigur 1
player1 = pygame.draw.rect(screen, WEISS, [spielfigur_1_x, spielfigur_1_y, 20, schlaeg
# -- Spielerfigur 2
player2 = pygame.draw.rect(screen, WEISS, [spielfigur_2_x, spielfigur_2_y, 20, schlaeg

# bewegen unseres Balls/Kreises


ballpos_x += bewegung_x
ballpos_y += bewegung_y

if ballpos_y > FENSTERHOEHE - BALL_DURCHMESSER or ballpos_y < 0:


bewegung_y = bewegung_y * -1

if ballpos_x > FENSTERBREITE - BALL_DURCHMESSER or ballpos_x < 0:


bewegung_x = bewegung_x * -1

# if ball.colliderect(player1):
if player1.colliderect(ball):
print("Zusammenstoß P1")
bewegung_x = bewegung_x * -1
ballpos_x = 40
ballwechsel += 1
schlaegerhoehe -= 5

if player2.colliderect(ball):
print("Zusammenstoß P2")
bewegung_x = bewegung_x * -1
ballpos_x = 570
ballwechsel += 1
schlaegerhoehe -= 5

ausgabetext = "Ballwechsel: " + str(ballwechsel)


font = pygame.font.SysFont(None, 70)
text = font.render(ausgabetext, True, ROT)
screen.blit(text, [100, 10])

# Fenster aktualisieren
pygame.display.flip()

# Refresh-Zeiten festlegen
clock.tick(60)

pygame.quit()
© https://www.python-lernen.de/pygame-kollisions-kontrolle.htm Seite 406
© https://www.python-lernen.de/pygame-spiele-sound-hintergrundmusik.htm Seite 407

Soundeffekte für unser Spiel und Hintergrundmusik


Was wäre ein Spiel ohne Soundeffekte und zusätzlich einer fetzigen Hintergrundmusik? Nur
ein halbes Spiel wahrscheinlich.

In Pygame sind sowohl Soundeffekte wie auch Hintergrundmusik kein großer Aufwand.
Wichtig ist, dass einem entsprechende Musik- und Sounddateien vorliegen. Wichtig dabei ist,
dass wir für die Soundeffekte das Format .WAV benötigen. Die Hintergrundmusik kann auch
eine MP3-Datei sein bzw. MIDI-File.

Woher nehmen, wenn nicht stehlen? Hier kann Google bemühen. Einfach nach „midi download
kostenlos“ suchen. Für WAV- und MP3-Dateien kann man sich z.B. bei
„https://soundbible.com/“ umschauen.

Aber nun zur Integration in Python Pygame.

Hintergrundmusik für unser Spiel


Wir haben nun auf unserer Festplatte eine Musikdatei. Diese wollen wir in unser Spiel einbauen,
die permanent im Hintergrund läuft.

Dazu packen gleich am Anfang den Aufruf hinein:

# initialisieren von pygame


pygame.init()

# Musik/Soundeffekte einrichten
pygame.mixer.music.load('sound/eine-MP3-Datei.mp3')

Wollen wir eine MIDI-Datei nutzen, sieht der Aufruf wie folgt aus:

pygame.mixer.music.load('sound/eine-midi-datei.mid')

Somit haben wir die Musikdatei geladen. Das bedeutet aber noch nicht, dass diese
automatisch abgespielt wird. Dazu müssen wir noch den „Play“-Button in Pygame drücken.

Hier erst der Befehl und dann die Erklärung:

# initialisieren von pygame


pygame.init()

# Musik/Soundeffekte einrichten
pygame.mixer.music.load('sound/eine-MP3-Datei.mp3')
pygame.mixer.music.play(-1,0.0)

Über Play-wird das abspiele der Musik gestartet. Die Werte in der Klammer haben natürlich
auch eine Bedeutung:

Erster Wert bestimmt die Anzahl. Wobei die Zahl 0 bedeutet, dass das Musikstück einmal
abgespielt wird. Tragen wir 5 ein, erhalten wir 6-mal das abspielen. Tragen wir hier -1 ein, dann
wird das Musikstück immer wieder wiederholt (sprich unendlich abgespielt).

Der zweite Wert sagt, ab welchem Zeitpunkt das Musikstück abgespielt werden soll. Wir wollen
es von Anfang an, daher geben wir 0.0 an. Dabei ist auch noch das Musikformat für die Art der
Angabe unterschiedlich. Bei MP3 und OGG sind es Sekundenangaben. Bei MOD ist es die
„Pattern order number“. Und bei MIDI funktioniert keine Zeitangabe.
© https://www.python-lernen.de/pygame-spiele-sound-hintergrundmusik.htm Seite 408

Musiklautstärke einstellen
Jetzt sollten wir Hintergrundmusik spielen haben. Zusätzlich können wir noch die Lautstärke
über die Anweisung pygame.mixer.music.set_volume() angeben. Die möglichen Werte
liegen zwischen 0 und 1 – 0 für unhörbar und 1 für maximale Lautstärke.

pygame.mixer.music.load('sound/eine-MP3-Datei.mp3')
pygame.mixer.music.play(-1,0.0)
pygame.mixer.music.set_volume(.6)

Das Einstellen der Lautstärke für die Hintergrundmusik ist wichtig. Die Hintergrundmusik soll ja
nicht die Soundeffekte vom Spiel überdecken.

Musikwiedergabe pausieren bzw. weiterspielen


Auch diese Funktion macht öfters Sinn. Hat unser Spiel beispielsweise eine Pausefunktion
(Telefon klingelt und wir müssen unbedingt hin) und während der Pausefunktion soll auch die
Hintergrundmusik schweigen, dann hilft hier die Anweisung
pygame.mixer.music.pause() und pygame.mixer.music.unpause() weiter.

In unserem Spiel soll beispielsweise durch Drücken der Taste p die Pause aktiviert werden,
pausieren wir auch die Musik. In folgendem Beispiel wird die Taste p doppelt belegt. Ist keine
Pause, wird pausiert. Ist bereits die Pause aktiviert, dann wird diese aufgehoben und die Musik
spielt weiter. Zusätzlich wird der Ball noch eingefroren bzw. beim Beenden der Pause seine
ursprünglichen Werte wieder genutzt:

# Spiel pausieren
elif event.key == pygame.K_p:
print("Spiel pausieren")
if spielpause == True:
spielpause = False
pygame.mixer.music.unpause()
bewegung_x = spielpause_x
bewegung_y = spielpause_y
else:
spielpause = True
pygame.mixer.music.pause()
spielpause_x = bewegung_x
spielpause_y = bewegung_y
bewegung_x = 0
bewegung_y = 0

Soundeffekte für Spielereignisse


Wir wollen ein hörbares Feedback für Spielergebnisse. Dann macht unser Spiel noch mehr
Spaß. Hier ist wichtig, dass nicht alle Formate für die Soundeffekte funktionieren. Auf der
sicheren Seite ist man mit WAV-Dateien. MP3-Dateien ergeben auf jeden Fall beim MAC eine
Fehlermeldung.

Hier kommt ein anderer Befehl wie bei der Hintergrundmusik zum Einsatz.

getroffen = pygame.mixer.Sound('sound/treffer.wav')

Über diese Pygame-Anweisung erstellen wir ein neues Sound-Objekt. Auf dieses können wir im
folgenden Zugreifen.
© https://www.python-lernen.de/pygame-spiele-sound-hintergrundmusik.htm Seite 409

Irritierend ist hier die Schreibweise. Hier wird auf einmal das „S“ bei der Anweisung
großgeschrieben. Bei der Hintergrundmusik pygame.mixer.music.load war alles noch
Kleinschreibung. Merkwürdig aber so ist es eben. Hält man sich nicht daran, erhält man einen
Traceback-Fehler „AttributeError: module 'pygame.mixer' has no attribute 'sound'“

Nachdem wir nun unser Objekt erzeugt haben, können wir auf dieses Zugreifen. Wir wollen den
Sound abspielen – dazu benötigen wir die Anweisung.

Jetzt wird dies noch an der entsprechenden Stelle in unserem Spiel integriert und wir haben
deutlich mehr Spielspaß:

# if ball.colliderect(player1):
if player1.colliderect(ball):
print("Zusammenstoß P1")
pygame.mixer.Sound.play(getroffen)
# … restlicher Aktionscode

if player2.colliderect(ball):
print("Zusammenstoß P2")
pygame.mixer.Sound.play(getroffen)
# … restlicher Aktionscode

Das war es auch schon – und nun viel Spaß beim Heraussuchen der passenden Musik und
Soundeffekte für das Spiel. Dadurch kann man einem Spiel einen ganz eigenen Charakter
verpassen (oder es extrem nervig machen).
© https://www.python-lernen.de/koordinatensystem-computerspiel.htm Seite 410

Ein Koordinatensystem für unsere Computerspiele


Ein Verständnis des verwendeten Koordinatensystems ist hilfreich für die Programmierung von
Computerspielen. Wir wollen in den folgenden Kapiteln ein Breakout-Spiel programmieren.
Dazu verwenden wir eine andere Technik als im bisherigen programmierten Spiel Pong.

Als Erstes schauen wir uns einfach das aus Schulzeiten vielleicht noch bekannte kartesische
Koordinatensystem an. Wer sich nicht mehr an die Schulzeiten erinnert (oder es bisher nicht
kennengelernt hat) – jetzt bekommt Mathe endlich eine praktische Anwendung. Aber keine
Panik: es ist keine wilde Rechnerei, sondern es geht um das Verständnis zwischen
Koordinatensystem und die Anwendung beim Programmieren!

Das kartesische Koordinatensystem wurde von dem Franzosen René Descartes entwickelt.
Dabei war es damals hip, Latein zu verwenden und so wurde das Koordinatensystem nach
dem latinisierten Nachnamen von Descartes, also „Cartesius“ benannt (wir müssen jetzt nicht
Latein lernen, aber manchmal kann man im Klugscheißermodus beeindrucken).

Das typische kartesische Koordinatensystem:

das kartesische Koordinatensystem


© https://www.python-lernen.de/koordinatensystem-computerspiel.htm Seite 411

Welche Eigenschaften hat das kartesische Koordinatensystem?

die Koordinatenachsen stehen


senkrecht (orthogonal) aufeinander

Koordinatenlinien sind Geraden in


konstantem Abstand voneinander

die waagrechte Achse heißt x-Achse


(Abszisse/Abszissenachse)

die senkrechte Achse heißt y-Achse


(Ordinate/Ordinatenachse)

die Nennung ist immer in der


Reihenfolge x und dann y

der Punkt 0 (beide Achsen treffen dort


aufeinander) ist der
Koordinatenursprung
(Ursprung/Nullpunkt)
© https://www.python-lernen.de/koordinatensystem-computerspiel.htm Seite 412

die 4 Bereiche werden als Quadranten


bezeichnet (der erste liegt rechts oben
und die Nummerierung erfolgt gegen
den Uhrzeigersinn)

Was hat das mit unserer Programmierung zu tun?

Das Koordinatensystem beim Programmieren


Unseren Bildschirm können wir mathematisch auch als Koordinatensystem sehen, allerdings
mit nur einem Quadranten! Wichtig dabei ist, dass der Nullpunkt (Koordinatenursprung) am
linken oberen Eck sitzt. Das gilt auch für ein Fenster. Die x-Achse geht vom Nullpunkt nach
rechts (wie beim kartesischen Koordinatensystem). Die y-Achse geht nach unten und wird mit
positiven Zahlen bezeichnet.

Auch hier sagt ein Bild mehr als tausend Worte:


© https://www.python-lernen.de/koordinatensystem-computerspiel.htm Seite 413

Koordinatensystem beim Programmieren

In dieses Koordinatensystem können wir nun über Pygame einfach etwas einzeichnen:

pygame.draw.rect(screen, ROT, [20, 50, 30, 30])

Rechteck im Koordinatensystem

Unsere erste Angabe mit 20 bezieht sich auf die x-Achse und die zweite Angabe mit 50 bezieht
sich auf die y-Achse. Das Viereck wird als an der Position 20 (rechts vom Nullpunkt) und an der
Position 50 (nach unten vom Nullpunkt aus gesehen) gezeichnet. Es ist jeweils 30 Pixel breit
wie hoch.

Hier kommt das Koordinatensystem zum Einsatz.


© https://www.python-lernen.de/koordinatensystem-computerspiel.htm Seite 414

WICHTIG für das Verständnis


Und jetzt kommt der Trick beim Programmieren von Spielen: Der Bildschirm dient nur zur
Ausgabe – die Berechnung, ob ein Ereignis stattfindet, geschieht im Hintergrund über
Listenelemente!

Wir geben auf dem Bildschirm (in einem Fenster) unsere Spielgrafik aus, aber im Hintergrund
haben wir eine ineinander verschachtelte Liste, durch die wir bequem unsere 2-dimensionale
Spielekarte (map) darstellen können und Ereignisse berechnen. Schauen wir uns diese Listen
an:

Unsere Liste – man könnte auch Karte dazu sagen (oder map hört sich auch gut an):

In unserer ersten Zeile (die 8 Felder hat) sollen:

leere Flächen über ein "-" (Minus),

Essen zum Einsammeln über die "E"

und Berge (unüberwindbare Hindernisse) über "B" dargestellt werden.

In Python wäre das eine typische Liste:

karte = ["-", "-", "E", "B", "B", "E", "-", "E"]

Wir haben also an der dritten Position Essen, dass wir einsammeln wollen und dann kommen 2
Bergelemente, die wir so nicht überwinden können um das darauffolgende Essen einsammeln
zu können.

In Python kann man den Inhalt eines bestimmten Listenfeldes über den Index abfragen. Wollen
wir nun die dritte Position abfragen und wir denken, da müsste doch ein „E“ für Essen
herauskommen, wird sich wundern. Es kommt ein B!

karte = ["-", "-", "E", "B", "B", "E", "-", "E"]


print(karte[3])

Kleine Gemeinheit am Rande. Wir können den Inhalt von Listen sehr einfach abfragen. Aber der
Index fängt bei 0 an – sprich unser erstes Element ist also karte[0] . Unser drittes Element
aus unserem obigen Beispiel sprechen wir an über:

karte = ["-", "-", "E", "B", "B", "E", "-", "E"]


print(karte[2])

Für die Vorstellungskraft: immer Minus 1 und dann passt das mit Index ab 0 :)

karte = ["-", "-", "E", "B", "B", "E", "-", "E"]


print(karte[3-1])

Zahlen auf Karten sind praktischer


In der Praxis wird man lieber Zahlen auf unserer virtuellen Karte einsetzen, da diese einfacher
zu handhaben sind und mehr Möglichkeiten bieten. Die leere Fläche wäre 0, Essen ist die Zahl
1 und Berge sind die Zahl 7. Unsere Karte würde also so aussehen:

karte = [0, 0, 1, 7, 7, 1, 0, 1]

Also wollen auch eine weitere Zeile – unsere Karte wird somit 2-Dimensional. In Python werden
verschachtelte Listen einfach über ein Komma getrennt und das komplette Element wird durch
eine weitere eckige Klammer umschlossen. Die unübersichtliche Schreibweise wäre, alles in
eine Zeile zu schreiben (hier einmal, dass man es sich nicht angewöhnt):

karte = [[0, 0, 1, 7, 7, 1, 0, 1], [5, 0, 0, 1, 0, 0, 0, 7] ]

In der zweiten Zeile kommt eine 5 als erste Angabe (das könnte eine Höhle darstellen). Diese
Angabe ist wichtig für das Verständnis im Folgenden:
© https://www.python-lernen.de/koordinatensystem-computerspiel.htm Seite 415

Und die schönere Darstellung ist (weil man sich dann fast schon die Landschaft vorstellen
kann) einfach untereinander:

karte = [
[0, 0, 1, 7, 7, 1, 0, 1],
[5, 0, 0, 1, 0, 0, 0, 7]
]

Für die Abfrage einer Position müssen wir nun sowohl die x-Achse wie die y-Achse angeben:

karte = [
[0, 0, 1, 7, 7, 1, 0, 1],
[5, 0, 0, 1, 0, 0, 0, 7]
]
print(karte[1][0])

Aber hoppla – was kommt da nun raus? Als Rückgabewert erhalten wir „5“ und nicht „0“.
Warum? Bei verschachtelten Listen haben wir den Unterschied zum kartesischen
Koordinatensystem, dass die erste Angabe die Zeile ausmacht, sprich Y und die zweite Angabe
dann X!

Das folgende Bild soll es klarer machen, wenn wir die Position karte[1][3] auslesen
wollen:

Auslesen von der Position karte[1][3]

Wir werden von unserer Spielfigur den „Aufenthaltsort“ in 2 weiteren Variablen speichern.
Vorteil: wir können auf unserer Karte nachschauen, was je nach Zugrichtung passieren würde
(und den Zug dann unter Umständen nicht zulassen).

spielfigur_x = 0
spielfigur_y = 0

Jetzt können wir die Anweisung geben, dass die Figur sich nach rechts bewegt. Bevor wir die
Figur bewegen, überprüfen wir, ob in unserer Karte rechts neben unsere Spielfigur ein Berg
befindet, wo die Figur sich nicht hinbewegen kann. Also ein kleiner Check über unsere Karte:

# kann Spielfigur nach rechts sich bewegen?


if karte[ spielfigur_y ][ spielfigur_x + 1] == 7:
echo ("Da ist ein Berg, das geht nicht")
else:
echo ("und ein Feld nach rechts laufen")

Hier sieht man auch den Vorteil von Zahl. Wir könnten in unserem Spiel zusätzliche
unüberwindbare Bereiche einbauen. Neben Berge (7) gibt es noch Flüsse (8) und Schluchten
(9). Und somit wäre unsere Abfrage einfach anstelle von „==“ einfach „>=“
© https://www.python-lernen.de/koordinatensystem-computerspiel.htm Seite 416

if karte[ spielfigur_y ][ spielfigur_x + 1] >= 7:


echo ("Da ist ein Berg oder Fluss oder Schlucht, das geht nicht")
else:
echo ("und ein Feld nach rechts laufen")

Kurz und gut:


Auf dem Bildschirm wird nur ausgegeben! Im Hintergrund wird eine virtuelle Karte in Form von
verschachtelten Listen bereitgehalten, auf der überprüft wird, welches Möglichkeiten welches
Feld bietet.

Soweit so gut. Das als Hintergrundwissen für Spieleentwicklung.


© https://www.python-lernen.de/breakout-spiel-programmieren.htm Seite 417

Spiel Breakout programmieren mit Python


Wir wollen in diesem Kapitel das alte (kam 1976 raus)
Spiel Breakout in Python programmieren und dadurch
weitere Programmiertechniken lernen. Kurz zu
Breakout:

Der Spieler muss den von oben kommenden Ball mit


einem Schläger vor dem Absturz bewahren und alle
Mauersteine treffen, die dann verschwinden. Sind alle
Mauersteine getroffen, ist das Level geschafft und das
nächste (schwierigere startet). Anfangs war dieses
Spiel eigentlich noch kein Computerspiel, da die
komplette Hardware fest verdrahtet war (sprich nicht
wirklich ein Computer). Lustigerweise wurden die
Farben über farbige Folien umgesetzt. Breakout war
extrem erfolgreich und über die Jahre kamen viele
Klone des Spiels mit Erweiterungen und noch mehr
Spielspaß.

Was sich erst einmal wie Pong mit Mauersteinen aus


dem letzten Kapitel nur um 90 Grad gedreht anhört,
setzten wir hier in einer komplett anderen
Programmiertechnik um! Es ist immer von Vorteil,
wenn man als Programmierer mehrere Optionen als
Vorgehensweise hat. Also mitmachen und die
Unterschiede zum vorherigen Kapitel ansehen. Es wird
wieder Pygame eingesetzt.

Aufbau des Fensters von Breakout


Wir haben ein Spielfeld, das hochkant ausgerichtet ist. Dabei setzten wir unser Wissen aus
dem Kapitel „ein Koordinatensystem für unsere Computerspiele“ ein.

Unsere Mauersteine werden für eine Vereinfachung als Quadrate (alle Seiten sind gleich lang)
umgesetzt. Es geht hier um die Vorgehensweise und nicht um eine unnötige Komplizierung.
Wer Spaß hat, kann am Ende sich eine Breakout-Variante mit länglichen Ziegelsteinen basteln.

Unser Ball ist gleich Breit (und somit auch gleich hoch) wie die Ziegelsteine. Somit können wir
sehr einfach überprüfen, ob er im nächsten Bewegungsschritt einen Stein trifft.

Wir können also unser Spielfeld einfach über das Koordinatensystem aufbauen. Allerdings
haben die Mauersteine eine vorgegebene Größe. Wir geben unseren Spielsteinen eine
Feldbreite von 20 Pixel und eine Feldhöhe von 20 Pixeln. Die Zahl 20 ist schön einfach auch im
Kopf zu rechnen.

Unser Spielfeld selber soll bis zu 20 Ziegelsteine nebeneinander darstellen können – somit ist
es 20 x 20 = 400 Pixel breit (unsere Gesamtbreite). Die Spielfeldhöhe soll 30 Positionen haben
– sprich wir haben die Feldhöhe 20 mal 30 mögliche Positionen – sprich 30 x 20 = 600 Pixel
Gesamthöhe. Wir haben also einen Multiplikator (Faktor), den wir immer wieder im ganzen
Spiel nutzen – sprich diesen setzen wir als Konstante im Spiel ein.

Hier nun unbedingt von Anfang an mit diesem Multiplikator rechnen. Somit ist eine Änderung
der Spielfeldgröße extrem einfach umsetzbar. Hier unsere ersten Programmzeilen:
© https://www.python-lernen.de/breakout-spiel-programmieren.htm Seite 418

# Importieren der Pygame-Bibliothek


import pygame, sys, time, random
from pygame.locals import *

# unser Multiplikator
MULTIPLIKATOR = 20

# Spielfeld erzeugen über Berechnung


fenster = pygame.display.set_mode((20 x MULTIPLIKATOR, 30 * MULTIPLIKATOR))

Jetzt kommt unsere typische Schleife für unser Hauptprogramm. Diese wie bereits aus dem
bisherigen Kapitel einsetzt mit der Möglichkeit, dass der Spieler das Spiel über die Escape-
Taste beenden kann. Da wir diese Vorgehensweise schon öfters im Kurs gemacht haben, keine
große Erklärung dazu (wenn gewünscht, einfach in den entsprechenden Kapiteln
nachschlagen).

# Importieren der Pygame-Bibliothek


import pygame, sys, time, random
from pygame.locals import *

# unser Multiplikator
MULTIPLIKATOR = 20

# Spielfeld erzeugen über Berechnung


fenster = pygame.display.set_mode((20 * MULTIPLIKATOR, 30 * MULTIPLIKATOR))

# Titel für Fensterkopf


pygame.display.set_caption("Breakout in Python")
spielaktiv = True

# Bildschirm Aktualisierungen einstellen


clock = pygame.time.Clock()

# Schleife Hauptprogramm
while spielaktiv:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat
for event in pygame.event.get():
if event.type == pygame.QUIT or event.type == pygame.KEYDOWN and event.key ==
spielaktiv = False
print("Spieler hat beendet")

# Fenster aktualisieren
pygame.display.flip()

# Refresh-Zeiten festlegen
clock.tick(10)

pygame.quit()

Wir bekommen nun unser Spielfenster mit der Größe 400 auf 600 Pixel erstellt. Ändern wir die
Konstante „MULTIPLIKATOR“, ändert sich automatisch die Größe des Fensters – später auch
automatisch die Größe der Spielelemente.
© https://www.python-lernen.de/breakout-spiel-programmieren.htm Seite 419
© https://www.python-lernen.de/breakout-spielgegner-mauersteine-zeichnen.htm Seite 420

Zeichnen der Mauersteine


Jetzt kommen wir zu der im Kapitel „ ein Koordinatensystem für unsere Computerspiele“
gezeigten Vorgehensweise. Wir haben 2 Ziele:

Mauersteine zeichnen

überprüfen können auf Kollision

Wir setzen zum Zeichnen der Mauersteine als Grundlage eine ineinander verschachtelte Liste
ein (siehe Kapitel Listen). Diese verschachtelte Liste dient einerseits zum ersten Zeichnen
unsere Spielelemente „Mauersteine“ und während dem Spiel zur Kollisionskontrolle. Hier haben
wir einen großen Unterschied zum Kapitel mit Pong. Wir selber überprüfen, ob eine Kollision
vorliegt und können dann darauf reagieren. Somit wären auch unterschiedliche Reaktionen
möglich (zum Beispiel trifft man einen grünen Ziegelstein, wird der Ball schneller – trifft man
einen braunen Ziegelstein könnte der Ball langsamer werden – das nur zum gedanklich
durchspielen, warum gerne eine Kollisionskontrolle nicht aus der Hand gibt).

Aber zeichnen wir erst einmal unsere Ziegelsteine. Zum Zeichnen erstellen wir uns eine
Funktion, der wir nur das gewünschte Feld mitgeben. Die Berechnung, auf welcher x- und y-
Position das Feld sich befindet, wird in der Funktion über die Konstante „MULTIPLIKATOR“
erledigt.

Die Funktion nennen wir element_zeichnen() und übergeben von unserem Feld dann die
Reihen- und die Spaltennummer. Bauen wir Schritt für Schritt die Funktion auf. Wir benötigen
auch noch Farben, die wir wie gewohnt definieren:

# genutzte Farben
ORANGE = ( 255, 140, 0)

# Spielelement zeichnen
def element_zeichnen(spalte,reihe):
pygame.draw.rect(fenster, ORANGE,(spalte*MULTIPLIKATOR, reihe*MULTIPLIKATOR,MULTIPLIKA

Wenn wir nun ein Spielelement zeichnen wollen, dann können wir einfach die Funktion
aufrufen:

# genutzte Farben
ORANGE = ( 255, 140, 0)

# Spielelement zeichnen
def element_zeichnen(spalte,reihe):
pygame.draw.rect(fenster, ORANGE,(spalte*MULTIPLIKATOR, reihe*MULTIPLIKATOR,MULTIPLIKA

# Testen der Ausgabe im Spielfenster


element_zeichnen(0,0)
element_zeichnen(1,1)
element_zeichnen(2,2)
element_zeichnen(3,2)
element_zeichnen(19,0)

Wir erhalten als Ergebnis des Zeichnens der 4 Spielelemente dann folgendes Aussehen:
© https://www.python-lernen.de/breakout-spielgegner-mauersteine-zeichnen.htm Seite 421

Ausgabe von Steinen

Was fällt bei unseren orangen Mauersteinen auf?

Unsere erste Position ist bei Spalte 0 und Zeile 0

Unsere letzte Position ist daher nicht Spalte 20, sondern Spalte 19

die Mauersteine kleben aneinander und sind damit schlecht unterscheidbar

Start bei 0 ist Ok. Das ist das übliche Verhalten von den allermeisten Programmiersprachen.
Wichtig ist einfach, dass man bei der Entwicklung daran denkt.

Damit wir einen guten Eindruck vom Aussehen bekommen, wird der Hintergrund in der
endgültigen Farbe Weiß gezeichnet:

# genutzte Farben
ORANGE = ( 255, 140, 0)
SCHWARZ = ( 0, 0, 0)
WEISS = ( 255, 255, 255)

# Hintergrundfarbe Fenster
fenster.fill(WEISS)

Damit die Mauersteine nicht so aneinanderkleben, lassen wir 1 Pixel Abstand.

Als Erstes erstellen wir eine neue Funktion mit dem Namen kor() . Diese berechnet den
Korrekturfaktor und gibt den korrigierten Wert zurück. Dadurch wird unsere Funktion
element_zeichnen() deutlich übersichtlicher:

def kor(zahl):
zahl = zahl * MULTIPLIKATOR
return zahl

# Spielelement zeichnen
def element_zeichnen(spalte,reihe):
pygame.draw.rect(fenster, ORANGE, [kor(spalte), kor(reihe), kor(1), kor(1)])

Und wenn wir nun die 1-Pixel-Abstände noch integrieren, sieht unser Programm wie folgt aus:
© https://www.python-lernen.de/breakout-spielgegner-mauersteine-zeichnen.htm Seite 422

# Korrekturfaktor berechnen
def kor(zahl):
zahl = zahl * MULTIPLIKATOR
return zahl

# Spielelement zeichnen
def element_zeichnen(spalte,reihe):
pygame.draw.rect(fenster, ORANGE, [kor(spalte)+1, kor(reihe)+1,kor(1)-1,kor(1)-

# Testen der Ausgabe im Spielfenster


element_zeichnen(0,0)
element_zeichnen(0,1)
element_zeichnen(0,2)
element_zeichnen(1,0)
element_zeichnen(1,1)
element_zeichnen(1,2)
element_zeichnen(2,0)
element_zeichnen(2,1)
element_zeichnen(2,2)

Als Ergebnis erhalten wir Mauersteine mit Abständen:

unsere ersten Mauersteine


© https://www.python-lernen.de/breakout-spielfeld-ueber-listen.htm Seite 423

Spielfeld mit Mauersteinen nach Vorgabe füllen


Wie im Kapitel „Koordinatensystem für unsere Computerspiele“ gezeigt, erstellen wir uns
verschachtelte Listen, die unsere Mauersteine darstellen. Dabei lassen wir einen großen Smiley
über die Mauersteine „bauen“.

# Spielfeld mit Mauersteinen


karte=[
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0],
[0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0],
[0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0],
[0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0],
[0,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,0],
[0,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,0],
[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,0],
[0,0,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,0,0],
[0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0],
[0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0],
[0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
]

Und nun lassen wir unsere verschachtelte Liste mit dem Listennamen karte über eine for -
Schleife ausgeben:

# Ausgabe Mauersteine im Spielfenster


for x in range(0,20):
for y in range(0,27):
if karte[y][x] != 0:
element_zeichnen(x,y)

Unser kompletter Code bisher:

# Importieren der Pygame-Bibliothek


import pygame, sys, time, random
from pygame.locals import *

# unser Multiplikator
MULTIPLIKATOR = 20
© https://www.python-lernen.de/breakout-spielfeld-ueber-listen.htm Seite 424

# Spielfeld erzeugen über Berechnung


fenster = pygame.display.set_mode((20 * MULTIPLIKATOR, 30 * MULTIPLIKATOR))

# Titel für Fensterkopf


pygame.display.set_caption("Breakout in Python")
spielaktiv = True

# Bildschirm Aktualisierungen einstellen


clock = pygame.time.Clock()

# genutzte Farben
ORANGE = ( 255, 140, 0)
SCHWARZ = ( 0, 0, 0)
WEISS = ( 255, 255, 255)

# Spielfeld mit Mauersteinen


karte=[
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0],
[0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0],
[0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0],
[0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0],
[0,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,0],
[0,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,0],
[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,0],
[0,0,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,0,0],
[0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0],
[0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0],
[0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
]

# Hintergrundfarbe Fenster
fenster.fill(WEISS)

# Korrekturfaktor berechnen
def kor(zahl):
zahl = zahl * MULTIPLIKATOR
return zahl
© https://www.python-lernen.de/breakout-spielfeld-ueber-listen.htm Seite 425

return zahl

# Spielelement zeichnen
def element_zeichnen(spalte,reihe):
pygame.draw.rect(fenster, ORANGE, [kor(spalte)+1, kor(reihe)+1,kor(1)-1,kor(1)-

# Ausgabe Mauersteine im Spielfenster


for x in range(0,20):
for y in range(0,27):
if karte[y][x] != 0:
element_zeichnen(x,y)

# Schleife Hauptprogramm
while spielaktiv:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat
for event in pygame.event.get():
if event.type == pygame.QUIT or event.type == pygame.KEYDOWN and event.key ==
spielaktiv = False
print("Spieler hat beendet")

# Fenster aktualisieren
pygame.display.flip()

# Refresh-Zeiten festlegen
clock.tick(10)

pygame.quit()

Ausgabe unserer Mauersteine als Smiley


© https://www.python-lernen.de/breakout-ball-bewegen.htm Seite 426

Breakout-Ball im Spiel zeichnen und bewegen


Als Nächstes wollen wir unseren Ball für unser Breakout-Spiel zeichnen. Hierbei werden wird
wieder unsere bisher verwendete Größe nutzen. Der Ball wird eine Größe von 20 auf 20 Pixel
haben.

Auch für das Zeichnen des Balls erstellen wir eine Funktion mit dem Namen
ball_zeichnen() :

def ball_zeichnen(x,y):
pygame.draw.ellipse(fenster, SCHWARZ, [kor(x), kor(y),kor(1), kor(1)], 0)

Unser Ball benötigt eine Position in unserem Fenster. Dazu erstellen wir 2 Variablen: ball_x
und ball_y . Diese könnten wir zwar per Zufall setzen, der Einfachheit halber setzen wir diese
für den Anfang einfach fix:

# Spielball Variablen
ball_x = 10
ball_y = 23

Der Ball hat noch eine Bewegungsrichtung, die durch 2 Variablen gespeichert wird. Die
verwendeten Variablen sind: ball_x_richtung und ball_y_richtung .

Dabei können diese Variablen positiv wie negativ sein und somit sind alle 4
Bewegungsrichtungen abgedeckt:

ball_x_richtung ball_y_richtung Bewegungsrichtung

1 1 rechts unten

1 -1 rechts oben

-1 1 links unten

-1 -1 links oben

Der Ball muss sich immer schräg bewegen, da bei einer geraden Bewegung das Abprallen vom
Schläger denn Ball exakt in die Richtung zurückwerfen würde, woher er gerade kam (was für
das Spiel nicht besonders sinnvoll wäre).

Wir ergänzen unsere Variablen:

# Spielball Variablen
ball_x = 10
ball_y = 23
ball_x_richtung = 1
ball_y_richtung = 1

Wer mehr Zufall an der ersten Position haben möchte, versieht einfach der Position ball_x
mit einer zufälligen Zahl zwischen 3 und 16 (ganz an den Rand macht am Anfang auch nicht
wirklich Sinn, daher der Abstand zwischen 0 und 3 und im oberen Bereich):

# Spielball Variablen
ball_x = random.randint(3,16)
ball_y = 23
ball_x_richtung = 1
ball_y_richtung = 1
© https://www.python-lernen.de/breakout-ball-bewegen.htm Seite 427

Innerhalb unserer Hauptprogramm-Schleife zeichnen wir nun den Ball:

# Schleife Hauptprogramm
while spielaktiv:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat
for event in pygame.event.get():
if event.type == pygame.QUIT or event.type == pygame.KEYDOWN and event.key ==
spielaktiv = False
print("Spieler hat beendet")

# Ball zeichnen
ball_zeichnen(ball_x, ball_y)

Keine Bewegung vom Ball macht natürlich wenig Spaß in einem Spiel. Daher werden wir denn
Ball pro Durchgang über unsere 2 Variablen ball_x_richtung und ball_y_richtung
weiterbewegen.

ball_x += ball_x_richtung
ball_y += ball_y_richtung

# Ball zeichnen
ball_zeichnen(ball_x, ball_y)

Während dem Entwickeln unseres Breakout-Spiels ist diese Bewegung nun ein wenig schnell.
Daher schalten wir auf Zeitlupe um. Unsere Refresh-Zeit ist zu schnell – also schalten wir die
Zeitlupe ein über clock.tick(3) .

Jetzt sieht man schön, wie unser Ball in Zeitlupe am Rand aus dem Bildschirmfenster
verschwindet und zusätzlich eine Spur hinterlässt.
© https://www.python-lernen.de/breakout-ball-bewegen.htm Seite 428

Ball flüchtet aus Bildschirmfenster

Zur Kontrolle lassen wir uns in der Konsole die aktuelle Position ausgeben:

# Ball zeichnen
ball_zeichnen(ball_x, ball_y)
print("Ballposition X=", ball_x, " / Y = ", ball_y)

Wir sehen in der Konsole, dass ab einer Position von Y=30 der Ball als Nächstes unten
verschwindet. Solange wir noch keinen Schläger haben, soll der Ball im Spiel bleiben. Daher
ändern wir die Y-Richtung des Balls, sobald er die untere Bildschirmkante erreicht.

# Spiellogik
if ball_x >= 19:
ball_x_richtung = -1

ball_x += ball_x_richtung
ball_y += ball_y_richtung

# Ball zeichnen
ball_zeichnen(ball_x, ball_y)
print("Ballposition X=", ball_x, " / Y = ", ball_y)

Aber bevor unser Ball an allen 4 Seiten abprallt, müssen wir alle 4 Seiten kontrollieren. Auch
das kommt an den Punkt innerhalb der Hauptschleife bei der Spiellogik (genaugenommen
Bewegungslogik).
© https://www.python-lernen.de/breakout-ball-bewegen.htm Seite 429

Ball prallt an allen 4 Seiten ab


© https://www.python-lernen.de/breakout-ball-bewegen.htm Seite 430

# Schleife Hauptprogramm
while spielaktiv:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat
for event in pygame.event.get():
if event.type == pygame.QUIT or event.type == pygame.KEYDOWN and event.key ==
spielaktiv = False
print("Spieler hat beendet")

# Spiellogik
if ball_x <= 0:
ball_x_richtung = 1
if ball_x >= 19:
ball_x_richtung = -1
if ball_y <= 0:
ball_y_richtung *= -1
if ball_y >= 29:
ball_y_richtung *= -1

ball_x += ball_x_richtung
ball_y += ball_y_richtung

# Ball zeichnen
ball_zeichnen(ball_x, ball_y)
print("Ballposition X=", ball_x, " / Y = ", ball_y)

# Fenster aktualisieren
pygame.display.flip()

# Refresh-Zeiten festlegen
clock.tick(3)

pygame.quit()

Nun wollen wir die Felder löschen, wo der Ball sich davor befunden hat. Dazu zeichnen wir
einfach ein weißes Viereck an die alte Position. Würden wir es mit der Trennung zwischen
Spiellogik und Ausgabelogik (Ball zeichnen etc.) nicht genau nehmen, würden wir keine
weiteren Variablen benötigen. Wir wollen aber so nachvollziehbar wie möglich programmieren
und daher trennen wir. Es gibt 2 neue Variablen, in der die alte Position des Balls gespeichert
werden.

# Spielball Variablen
ball_x = random.randint(3,16)
ball_y = 23
ball_x_richtung = 1
ball_y_richtung = 1
ball_x_alt = 0
ball_y_alt = 0

In diesen Variablen werden bei jedem Durchgang die alten Positionen gespeichert, bevor die
Positionen neu gesetzt werden:
© https://www.python-lernen.de/breakout-ball-bewegen.htm Seite 431

ball_x_alt = ball_x
ball_y_alt = ball_y
ball_x += ball_x_richtung
ball_y += ball_y_richtung

# Ball zeichnen
ball_zeichnen(ball_x, ball_y)

Und nun müssen wir nur noch die alte Position löschen. Dazu erstellen wir uns eine Funktion
element_loeschen() . Diese ist ähnlich der Zeichenfunktion für unsere Mauersteine (nur
mit Weiß als Farbe):

def element_loeschen(spalte,reihe):
pygame.draw.rect(fenster, WEISS, [kor(spalte), kor(reihe),kor(1),kor(1)])

Diese Funktion zum Löschen des Inhalts an der alten Bildschirmposition wird vor dem
Zeichnen der neuen Ballposition aufgerufen:

# Ball zeichnen
element_loeschen(ball_x_alt, ball_y_alt)
ball_zeichnen(ball_x, ball_y)

Wir haben ein interessantes Ergebnis:

Ball prallt an Mauersteinen nicht ab, sondern hinterlässt eine Schneise


© https://www.python-lernen.de/breakout-kollision-ball-mauerstein.htm Seite 432

Kollision zwischen Ball und Mauerstein, der dann


verschwindet
In unseren bisherigen Code integrieren wir das Spielverhalten, dass bei Kollision mit dem Ball
der Mauerstein verschwindet. Hier der bisher erstellte Code (ein wenig erweitert – es wurde
eine „Schritt-für-Schritt“-Funktion eingebaut, damit man in Ruhe die Zahl kontrollieren kann. Bei
jedem drücken der Leertaste bewegt sich unser Ball erst weiter):

import pygame, sys, time, random


from pygame.locals import *

# unser Multiplikator
MULTIPLIKATOR = 20

# Spielfeld erzeugen über Berechnung


fenster = pygame.display.set_mode((20 * MULTIPLIKATOR, 30 * MULTIPLIKATOR))

# Titel für Fensterkopf


pygame.display.set_caption("Breakout in Python")
spielaktiv = True

# Bildschirm Aktualisierungen einstellen


clock = pygame.time.Clock()

# genutzte Farben
ORANGE = ( 255, 140, 0)
SCHWARZ = ( 0, 0, 0)
WEISS = ( 255, 255, 255)

# Spielfeld mit Mauersteinen


karte=[
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0],
[0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0],
[0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0],
[0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0],
[0,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,0],
[0,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,0],
[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,0],
[0,0,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,0,0],
[0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0],
[0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0],
[0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
© https://www.python-lernen.de/breakout-kollision-ball-mauerstein.htm Seite 433

[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
]

# Spielball Variablen
ball_x = random.randint(3,16)
ball_y = 23
ball_x_richtung = 1
ball_y_richtung = 1
ball_x_alt = 0
ball_y_alt = 0

# Hintergrundfarbe Fenster
fenster.fill(WEISS)

# Korrekturfaktor berechnen
def kor(zahl):
zahl = zahl * MULTIPLIKATOR
return zahl

# Spielelement zeichnen
def element_zeichnen(spalte,reihe):
pygame.draw.rect(fenster, ORANGE, [kor(spalte)+1, kor(reihe)+1,kor(1)-1,kor(1)-

def element_loeschen(spalte,reihe):
pygame.draw.rect(fenster, WEISS, [kor(spalte), kor(reihe),kor(1),kor(1)])

def ball_zeichnen(x,y):
pygame.draw.ellipse(fenster, SCHWARZ, [kor(x), kor(y),kor(1), kor(1)], 0)

# Ausgabe Mauersteine im Spielfenster


for x in range(0,20):
for y in range(0,27):
if karte[y][x] != 0:
element_zeichnen(x,y)

naechsterschritt = False

# Schleife Hauptprogramm
while spielaktiv:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat
for event in pygame.event.get():
if event.type == pygame.QUIT or event.type == pygame.KEYDOWN and event.key ==
spielaktiv = False
print("Spieler hat beendet")

if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:


naechsterschritt = True
© https://www.python-lernen.de/breakout-kollision-ball-mauerstein.htm Seite 434

naechsterschritt = True
print("Nächster Schritt")

# Spiellogik
if ball_x <= 0:
ball_x_richtung = 1
if ball_x >= 19:
ball_x_richtung = -1
if ball_y <= 0:
ball_y_richtung = 1
if ball_y >= 29:
ball_y_richtung = -1

# Ball trifft Ziegelstein

if naechsterschritt == True:
ball_x_alt = ball_x
ball_y_alt = ball_y
ball_x += ball_x_richtung
ball_y += ball_y_richtung
naechsterschritt = False

# Ball zeichnen
element_loeschen(ball_x_alt, ball_y_alt)
ball_zeichnen(ball_x, ball_y)
print("Ballposition X=", ball_x, " / Y = ", ball_y)

# Fenster aktualisieren
pygame.display.flip()

# Refresh-Zeiten festlegen
clock.tick(3)

pygame.quit()

Wir wissen, dass wenn der Ball sich in der Aufwärtsbewegung befindet, die Variable
ball_y_richtung dann den Wert -1 hat. Damit müssen wir also überprüfen, ob das Feld
oberhalb der aktuellen Ballposition einen Mauerstein in dem Listenobjekt karte eingetragen
hat. Ob es das rechte oder links ist, sagt und die Variable ball_x_richtung

im nächsten Schritt trifft der Ball den Mauerstein, der dann verschwinden muss

Schauen wir uns die Berechnung an. Wir haben folgenden 4 Werte:

ball_x

ball_y

ball_x_richtung
© https://www.python-lernen.de/breakout-kollision-ball-mauerstein.htm Seite 435

ball_y_richtung

Daraus ergibt sich unserer Kontrolle:

# Ball trifft Ziegelstein


# Kontrolle auf möglich Kollision
if ball_y_richtung == -1:
# Ball ist in Aufwärtsbewegung
# genau darüber ein Mauerstein?
if karte[ball_y-1][ball_x] != 0:
print("trifft Mauerstein rechts oberhalb")
ball_y_richtung = 1

Nun wird der Ball nach unten abprallen. Wir müssen nur noch den Mauerstein entfernen – und
zwar zweimal:

der Mauerstein muss vom Bildschirm gelöscht werden

der Mauerstein muss aus unserer virtuellen Karte gelöscht werden!

Im ersten Schritt löschen wir den Bereich auf dem Bildschirm und im weiteren Schritt wird in
dem Listenobjekt das entsprechende Feld mit 0 gefüllt.

# Ball trifft Ziegelstein


# Kontrolle auf möglich Kollision
if ball_y_richtung == -1:
# Ball ist in Aufwärtsbewegung
# genau darüber ein Mauerstein?
if karte[ball_y-1][ball_x] != 0:
print("trifft Mauerstein rechts oberhalb")
# Mauerstein wird gelöscht von Bildschirm
element_loeschen(ball_x, ball_y-1)
# Mauerstein wird gelöscht aus Liste karte
karte[ball_y-1][ball_x] = 0
ball_y_richtung = 1

Soweit so gut – allerdings kann der Ball auch schräg treffen:

Fall: Ball trifft schräg

Auch diesen Fall sollen wir berücksichtigen. Hier haben wir eine nicht 100 Prozent saubere
Lösung. Einfach selber einmal austüfteln, wie es am besten umgesetzt wird!
© https://www.python-lernen.de/breakout-kollision-ball-mauerstein.htm Seite 436

# Ball trifft Ziegelstein


# Kontrolle auf möglich Kollision
if ball_y_richtung == -1:
# Ball ist in Aufwärtsbewegung
# genau darüber ein Mauerstein?
if karte[ball_y-1][ball_x] != 0:
print("trifft Mauerstein rechts oberhalb")
# Mauerstein wird gelöscht von Bildschirm
element_loeschen(ball_x, ball_y-1)
# Mauerstein wird gelöscht aus Liste karte
karte[ball_y-1][ball_x] = 0
ball_y_richtung = 1

if ball_x_richtung == 1:
# Ball bewegt sich nach rechts
if karte[ball_y-1][ball_x+1] != 0:
print("trifft Mauerstein rechts oberhalb")
# Mauerstein wird gelöscht von Bildschirm
element_loeschen(ball_x+1, ball_y-1)
# Mauerstein wird gelöscht aus Liste karte
karte[ball_y-1][ball_x+1] = 0
ball_y_richtung = 1
else:
# Ball bewegt sich nach links
if karte[ball_y-1][ball_x-1] != 0:
print("trifft Mauerstein links oberhalb")
# Mauerstein wird gelöscht von Bildschirm
element_loeschen(ball_x-1, ball_y-1)
# Mauerstein wird gelöscht aus Liste karte
karte[ball_y-1][ball_x-1] = 0
ball_y_richtung = 1

Lösung gefunden? Hier ist die Lösung mitsamt der Erweiterung, wenn der Ball auf eine Ecke
von einem Mauerstein auftrifft:
© https://www.python-lernen.de/breakout-kollision-ball-mauerstein.htm Seite 437

# Ball trifft Mauerstein


# Kontrolle auf möglich Kollision
if ball_y_richtung == -1:
# Ball ist in Aufwärtsbewegung
# genau darüber ein Mauerstein?
if karte[ball_y-1][ball_x] != 0:
print("trifft Mauerstein oberhalb")
# Mauerstein wird gelöscht von Bildschirm
element_loeschen(ball_x, ball_y-1)
# Mauerstein wird gelöscht aus Liste karte
karte[ball_y-1][ball_x] = 0
ball_y_richtung = 1
else:
if ball_x_richtung == 1:
# Ball bewegt sich nach rechts
if karte[ball_y-1][ball_x+1] != 0:
print("trifft Mauerstein rechts oberhalb")
# Mauerstein wird gelöscht von Bildschirm
element_loeschen(ball_x+1, ball_y-1)
# Mauerstein wird gelöscht aus Liste karte
karte[ball_y-1][ball_x+1] = 0
ball_y_richtung = 1
# trifft auf Ecke, also gleich Richtung zurück
ball_x_richtung = -1
else:
# Ball bewegt sich nach links
if karte[ball_y-1][ball_x-1] != 0:
print("trifft Mauerstein links oberhalb")
# Mauerstein wird gelöscht von Bildschirm
element_loeschen(ball_x-1, ball_y-1)
# Mauerstein wird gelöscht aus Liste karte
karte[ball_y-1][ball_x-1] = 0
ball_y_richtung = 1
# trifft auf Ecke, also gleich Richtung zurück
ball_x_richtung = +1

Apropos – wenn das wiederholte Drücken der Leertaste lästig wird, kann Pygame eine
Wiederholungsfrequenz mitgeben:

# Bildschirm Aktualisierungen einstellen


clock = pygame.time.Clock()
pygame.key.set_repeat(50,0)
© https://www.python-lernen.de/breakout-kontrolle-spielende-gewinnen.htm Seite 438

Kontrolle: Spielende durch Gewinnen


Sobald der Spieler alle Mauersteine abgeräumt hat, hat er gewonnen. Juhu!

Wie können wir am einfachsten überprüfen, ob diese Siegbedingung eingetreten ist? Wir zählen
in unserer virtuellen Karte die virtuellen Mauersteine (sprich die Einser).

# Siegbedingung erfüllt?
mauersteine = 0
for i in range(len(karte)):
for j in range(len(karte[i])):
if karte[i][j] == 1:
mauersteine = mauersteine + 1
if mauersteine > 1:
print("noch sind Mauersteine ", mauersteine ," da")
else:
# gewonnen, alle Mauersteine sind weg
# Ball wird eingefroren
ball_x_richtung = 0
ball_y_richtung = 0
# Meldung für Sieg
print("Gewonnen - herzlichen Glückwunsch")

Wenn man es genau nimmt, haben wir das aktuelle Level erspielt. Jetzt sollten wir weitere und
schwierigere Levels im Spiel einbauen. Dies kann jeder für sich machen. Anregungen dazu
wäre:

Mauersteine näher am Schläger platzieren

Ball schneller machen

Schläger kleiner machen

unterschiedlich farbige Steine

je nach Farbe passieren Dinge (Schläger kleiner oder größer, Ball schneller oder langsamer)

ein 2-Spieler Game daraus machen mit versetzten Schlägern

u.s.w.

Hier der bisher entstandene Quellcode:

# Importieren der Pygame-Bibliothek


import pygame, sys, time, random
from pygame.locals import *

# unser Multiplikator
MULTIPLIKATOR = 20

# Spielfeld erzeugen über Berechnung


fenster = pygame.display.set_mode((20 * MULTIPLIKATOR, 30 * MULTIPLIKATOR))

# Titel für Fensterkopf


pygame.display.set_caption("Breakout in Python")
spielaktiv = True

# Bildschirm Aktualisierungen einstellen


clock = pygame.time.Clock()
© https://www.python-lernen.de/breakout-kontrolle-spielende-gewinnen.htm Seite 439

clock = pygame.time.Clock()
pygame.key.set_repeat(50,0)

# genutzte Farben
ORANGE = ( 255, 140, 0)
SCHWARZ = ( 0, 0, 0)
WEISS = ( 255, 255, 255)

# Spielfeld mit Mauersteinen


karte=[
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0],
[0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0],
[0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0],
[0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0],
[0,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,0],
[0,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,0],
[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,0],
[0,0,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,0,0],
[0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0],
[0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0],
[0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
]

# Spielball Variablen
ball_x = random.randint(3,16)
ball_y = 23
ball_x_richtung = 1
ball_y_richtung = 1
ball_x_alt = 0
ball_y_alt = 0

# Hintergrundfarbe Fenster
fenster.fill(WEISS)
© https://www.python-lernen.de/breakout-kontrolle-spielende-gewinnen.htm Seite 440

# Korrekturfaktor berechnen
def kor(zahl):
zahl = zahl * MULTIPLIKATOR
return zahl

# Spielelement zeichnen
def element_zeichnen(spalte,reihe):
pygame.draw.rect(fenster, ORANGE, [kor(spalte)+1, kor(reihe)+1,kor(1)-1,kor(1)-

def element_loeschen(spalte,reihe):
pygame.draw.rect(fenster, WEISS, [kor(spalte), kor(reihe),kor(1),kor(1)])

def ball_zeichnen(x,y):
pygame.draw.ellipse(fenster, SCHWARZ, [kor(x), kor(y),kor(1), kor(1)], 0)

# Ausgabe Mauersteine im Spielfenster


for x in range(0,20):
for y in range(0,27):
if karte[y][x] != 0:
element_zeichnen(x,y)

naechsterschritt = False

# Schleife Hauptprogramm
while spielaktiv:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat
for event in pygame.event.get():
if event.type == pygame.QUIT or event.type == pygame.KEYDOWN and event.key ==
spielaktiv = False
print("Spieler hat beendet")

if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:


naechsterschritt = True
print("Nächster Schritt")

# Spiellogik
if ball_x <= 0:
ball_x_richtung = 1
if ball_x >= 19:
ball_x_richtung = -1
if ball_y <= 0:
ball_y_richtung = 1
if ball_y >= 29:
ball_y_richtung = -1

# Ball trifft Mauerstein


# Kontrolle auf möglich Kollision
if ball_y_richtung == -1:
# Ball ist in Aufwärtsbewegung
# genau darüber ein Mauerstein?
if karte[ball_y-1][ball_x] != 0:
print("trifft Mauerstein oberhalb")
© https://www.python-lernen.de/breakout-kontrolle-spielende-gewinnen.htm Seite 441

print("trifft Mauerstein oberhalb")


# Mauerstein wird gelöscht von Bildschirm
element_loeschen(ball_x, ball_y-1)
# Mauerstein wird gelöscht aus Liste karte
karte[ball_y-1][ball_x] = 0
ball_y_richtung = 1
else:
if ball_x_richtung == 1:
# Ball bewegt sich nach rechts
if karte[ball_y-1][ball_x+1] != 0:
print("trifft Mauerstein rechts oberhalb")
# Mauerstein wird gelöscht von Bildschirm
element_loeschen(ball_x+1, ball_y-1)
# Mauerstein wird gelöscht aus Liste karte
karte[ball_y-1][ball_x+1] = 0
ball_y_richtung = 1
# trifft auf Ecke, also gleich Richtung zurück
ball_x_richtung = -1
else:
# Ball bewegt sich nach links
if karte[ball_y-1][ball_x-1] != 0:
print("trifft Mauerstein links oberhalb")
# Mauerstein wird gelöscht von Bildschirm
element_loeschen(ball_x-1, ball_y-1)
# Mauerstein wird gelöscht aus Liste karte
karte[ball_y-1][ball_x-1] = 0
ball_y_richtung = 1
# trifft auf Ecke, also gleich Richtung zurück
ball_x_richtung = +1

# Siegbedingung erfüllt?
mauersteine = 0
for i in range(len(karte)):
for j in range(len(karte[i])):
if karte[i][j] == 1:
mauersteine = mauersteine + 1
if mauersteine > 1:
print("noch sind Mauersteine ", mauersteine ," da")
else:
# gewonnen, alle Mauersteine sind weg
# Ball wird eingefroren
ball_x_richtung = 0
ball_y_richtung = 0
# Meldung für Sieg
print("Gewonnen - herzlichen Glückwunsch")

if naechsterschritt == True:
ball_x_alt = ball_x
ball_y_alt = ball_y
ball_x += ball_x_richtung
ball_y += ball_y_richtung
# naechsterschritt = False
© https://www.python-lernen.de/breakout-kontrolle-spielende-gewinnen.htm Seite 442

# Ball zeichnen
element_loeschen(ball_x_alt, ball_y_alt)
ball_zeichnen(ball_x, ball_y)

if naechsterschritt == True:
print()
print("Richtung X=", ball_x_richtung, " / Y = ", ball_y_richtung)
print("Ballposition X=", ball_x, " / Y = ", ball_y)
# naechsterschritt = False

# Fenster aktualisieren
pygame.display.flip()

# Refresh-Zeiten festlegen
clock.tick(20)

pygame.quit()

exit()
© https://www.python-lernen.de/breakout-spieler-einbauen-bewegen.htm Seite 443

Spielerfigur (Schläger) einbauen und bewegen


Bisher spielt unser Spiel alleine. Das ist nicht ganz im Sinne des Erfinders und daher wollen wir
dem Spieler einen Schläger geben, den er bewegen kann und somit den Ball zurückschlagen.

Wir benötigen in unserem Bereich für die Vorgabe der Variablen 3 weitere Variablen:

spielfigur_1_x (für die horizontale (x) Start-Position des Schlägers)

spielfigur_1_y (für die vertikale (y) Position des Schlägers – diese verändert sich im
ganzen Spiel nicht)

spielfigur_1_bewegung (die Bewegung der Spielerfigur)

Bei unseren Vorgaben packen wir nach den Spielball-Variablen nun:

spielfigur_1_x = 10
spielfigur_1_y = 27
spielfigur_1_bewegung = 0

In unserem Bereich „# Spielelement zeichnen“ erstellen wir 2 weitere Funktionen. Als Erstes
wollen wir die Spielfigur zeichnen. Die Funktion nennen wir spielfigur_zeichnen() und
wir übergeben dieser die X-Position.

def spielfigur_zeichnen(x):
pygame.draw.rect(fenster, SCHWARZ,(kor(x), kor(spielfigur_1_y),50,kor(1)))

Für den Eindruck der Bewegung müssen wir die Spielfigur auch wieder vom Bildschirm löschen
können. Die zweite Funktion spielfigur_loeschen(x) zeichnet uns dazu einfach ein
weißes Quadrat.

def spielfigur_loeschen(x):
pygame.draw.rect(fenster, WEISS,(kor(x), kor(spielfigur_1_y),50,kor(1)))

Spielfigur (Schläger) zeichnen


Innerhalb unserer Hauptschleife zeichnen wir nun unseren Schläger, nachdem wir den Ball
gezeichnet haben (die Reihenfolge ist eigentlich egal).

# Ball zeichnen
element_loeschen(ball_x_alt, ball_y_alt)
ball_zeichnen(ball_x, ball_y)

spielfigur_zeichnen(spielfigur_1_x)

Und nun haben wir eine Spielerfigur:


© https://www.python-lernen.de/breakout-spieler-einbauen-bewegen.htm Seite 444

Schläger als Spielerfigur

Diesen wollen wir natürlich auch bewegen können. Dazu ergänzen wir in der Hauptroutine die
Abfrage der Tastatur in der Hauptschleife. Wir nutzen die Pfeiltaste nach rechts und links für
die Steuerung.

Je nachdem welche Taste der Spieler gedrückt hat, bekommt die Variable
spielfigur_1_bewegung entweder plus 1 oder minus 1 zugewiesen.

# Schleife Hauptprogramm
while spielaktiv:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat
for event in pygame.event.get():
if event.type == pygame.QUIT or event.type == pygame.KEYDOWN and event.key ==
spielaktiv = False
print("Spieler hat beendet")

if event.type == pygame.KEYDOWN:
print("Spieler hat Taste gedrückt")

# Taste für Spieler 1


if event.key == pygame.K_LEFT:
print("Spieler hat Pfeiltaste links gedrückt")
spielfigur_1_bewegung = -1
elif event.key == pygame.K_RIGHT:
print("Spieler hat Pfeiltaste rechts gedrückt")
spielfigur_1_bewegung = 1
© https://www.python-lernen.de/breakout-spieler-einbauen-bewegen.htm Seite 445

Über unsere Variable können wir nun die Bewegung der Spielerfigur einfach umsetzen. Im
Bereich „# Spiellogik“

# Spiellogik
# Ballbewegung
if ball_x <= 0:
ball_x_richtung = 1
if ball_x >= 19:
ball_x_richtung = -1
if ball_y <= 0:
ball_y_richtung = 1
if ball_y >= 29:
ball_y_richtung = -1

# Spielfigurbewegung
spielfigur_1_x += spielfigur_1_bewegung

Die Spielfigur soll sich auch nur einmal bewegen. Daher setzen wir die Variable nach dem
Zeichnen der Bewegung wieder auf 0:

spielfigur_zeichnen(spielfigur_1_x)
spielfigur_1_bewegung = 0

Schlägerbewegung sauber
Wenn wir nun das Spiel starten, können wir den Schläger bewegen. Es gibt aber noch 2
Schönheitsfehler. Wir zeichnen einen Strich, da wir die alte Schlägerposition nicht löschen. Und
als Zweites prallt unser Ball nicht ab.
© https://www.python-lernen.de/breakout-spieler-einbauen-bewegen.htm Seite 446

alte Schlägerposition wird nicht gelöscht

Für die alte Schlägerposition benötigen wir eine „neue“ Variable mit dem Namen
spielfigur_1_x_alt . Diese Variable setzen wir bei dem Definitionsbereich am Anfang von
unseren Pythoncode und zusätzlich bevor wir die neue Position des Schlägers berechnen.

# Spielfigurbewegung
spielfigur_1_x_alt = spielfigur_1_x
spielfigur_1_x += spielfigur_1_bewegung

Und nun können wir den Schläger löschen, bevor er an der neuen Position gezeichnet wird.

# Ball zeichnen
element_loeschen(ball_x_alt, ball_y_alt)
ball_zeichnen(ball_x, ball_y)

# Spielerfigur zeichnen
spielfigur_loeschen(spielfigur_1_x_alt)
spielfigur_zeichnen(spielfigur_1_x)
spielfigur_1_bewegung = 0

Soweit so gut. Unser Schläger kann aus dem Fenster verschwinden. Hier müssen wir in der
Spiellogik gegen wirken.

Wir fragen die Position des Schlägers ab und wenn dieser an der rechten oder linken
Fensterrand sich befindet, setzen wir die Bewegung wieder auf 0:
© https://www.python-lernen.de/breakout-spieler-einbauen-bewegen.htm Seite 447

# Spiellogik
# -- Spielfigur darf das Spielfeld links nicht verlassen
if (spielfigur_1_x == 0 and spielfigur_1_bewegung == -1):
spielfigur_1_bewegung = 0

if spielfigur_1_x == 18 and spielfigur_1_bewegung == 1:


spielfigur_1_bewegung = 0

# Ballbewegung

Für den rechten Rand setzen wir nicht bei Position 20, sondern 18 – unser Schläger hat ja eine
Breite und er muss bei 18 stoppen, damit er komplett sichtbar bleibt.
© https://www.python-lernen.de/breakout-kollisionskontrolle-spielerfigur.htm Seite 448

Kollisionskontrolle Ball und Schläger


Jetzt kommt die Spiellogik, wenn der Ball den Schläger trifft. Hierzu haben wir ähnlich wie bei
dem Ereignis, wenn der Ball die Mauersteine, trifft mehrere Fälle.

Der Ball trifft:

gerade auf dem Schläger auf

der Ball trifft das Eck des Schlägers

Wenn der Ball auf die gerade Fläche des Schlägers auftrifft, wird dieser im entsprechenden
Winkel abgeschmettert.

Wenn der Ball auf die Kante trifft, fliegt er auf der gleichen Linie zurück.

Machen wir den ersten Fall:

Ball trifft gerade auf Schläger


Unser Schläger bewegt sich horizontal auf der Höhe von spielfigur_1_y = 28 . Daher
müssen wir nur kontrollieren, wenn der Ball sich abwärts bewegt und sich auf der Ebene 27
befindet:

# Ball trifft Schläger


# Kontrolle auf möglich Kollision
if ball_y == 27 and ball_y_richtung == 1:
print("Kontrolle auf Kollsion mit Schläger")

Wir haben von unserem Schläger die Position spielfigur_1_x und wissen, dass der
Schläger 3 Felder breit ist. Daher können wir die folgenden Berechnungen machen:

# Ball trifft Schläger


# Kontrolle auf möglich Kollision
if ball_y == 27 and ball_y_richtung == 1:
print("Kontrolle auf Kollision mit Schläger")

# Ball kommt von links:


if ball_x_richtung == 1:
print("Ball kommt von links")
if ball_x+1 >= spielfigur_1_x and ball_x+1 <= spielfigur_1_x+3:
print("Ball trifft Schläger")
ball_y_richtung = -1

# Ball kommt von rechts:


if ball_x_richtung == -1:
print("Ball kommt von rechts")
if ball_x-1 >= spielfigur_1_x and ball_x-1 <= spielfigur_1_x+3:
print("Ball trifft Schläger")
ball_y_richtung = -1

Wer nun Spaß hat, kann das Auftreffen auf der Kante noch berücksichtigen, was die
Flugrichtung des Balls beeinflussen sollte. Er sollte dann in der gleichen Richtung
zurückfliegen.

Wenn das Spiel zu schwierig ist, würde das Vergrößern des Schlägers helfen.
© https://www.python-lernen.de/breakout-kollisionskontrolle-spielerfigur.htm Seite 449
© https://www.python-lernen.de/breakout-kontrolle-spielende-verloren.htm Seite 450

Kontrolle auf Spielende bei Breakout: Ball kommt auf dem


Boden auf
Und nun der Fall, dass der Ball den Boden erreicht, weil der Spieler nicht rechtzeitig mit dem
Schläger an der richtigen Position war, um den Ball abzuwehren. Wir müssen dazu unsere
bisherige Logik, dass er am Boden abprallt wieder verändern (was ja bei der Entwicklung des
Spiels hilfreich war, aber jetzt nicht mehr).

Wenn der Ball über die Position 29 kommt, dann ist das Spiel verloren. Bisher hatten wir
folgende Abfrage:

# Ballbewegung
if ball_x <= 0:
ball_x_richtung = 1
if ball_x >= 19:
ball_x_richtung = -1
if ball_y <= 0:
ball_y_richtung = 1
if ball_y >= 29:
ball_y_richtung = -1

Jetzt können wir ganz Brachial hier das Spiel beenden und keine Trennung von Logik und
Ausgabe machen. Also einmal die faule Variante:

# Ballbewegung
if ball_x <= 0:
ball_x_richtung = 1
if ball_x >= 19:
ball_x_richtung = -1
if ball_y <= 0:
ball_y_richtung = 1
if ball_y > 29:
# ball_y_richtung = -1
ball_y_richtung = 0
ball_x_richtung = 0
print("Verloren :(")

Hier kommt dann bei jedem vernünftigen Spiel der Abspann mit Auflistung der Beteiligten und
in welchem Filmstudio gedreht wurde …

Ähm – eigentlich sollten wir mehr als 1 Leben haben. Hier sollte also überprüft werden, ob wir
noch Leben (also weitere Bälle) haben und der nächste Ball dann eingeblendet werden und das
Spiel weitergehen. Darf man machen, kann man machen aber wichtig war bis hierher das
Verständnis vom Ablauf des Programmierens eines Spiels. Alles Weitere ist neben
Fingerübung ein wenig Knobeln und das Kombinieren von jetzt bekannten Elementen.

Viel Spaß beim Erweitern und Optimieren des Breakout-Spiels in Python.

Hier unser kompletter Code, falls auf dem Weg etwas verloren ging:

# Importieren der Pygame-Bibliothek


import pygame, sys, time, random
from pygame.locals import *

# unser Multiplikator
MULTIPLIKATOR = 20
© https://www.python-lernen.de/breakout-kontrolle-spielende-verloren.htm Seite 451

MULTIPLIKATOR = 20

# Spielfeld erzeugen über Berechnung


fenster = pygame.display.set_mode((20 * MULTIPLIKATOR, 30 * MULTIPLIKATOR))

# Titel für Fensterkopf


pygame.display.set_caption("Breakout in Python")
spielaktiv = True

# Bildschirm Aktualisierungen einstellen


clock = pygame.time.Clock()
pygame.key.set_repeat(10,0)

# genutzte Farben
ORANGE = ( 255, 140, 0)
SCHWARZ = ( 0, 0, 0)
WEISS = ( 255, 255, 255)

# Spielfeld mit Mauersteinen


karte=[
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0],
[0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0],
[0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0],
[0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0],
[0,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,0],
[0,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,0],
[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,0],
[0,0,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,0,0],
[0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0],
[0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0],
[0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
]
© https://www.python-lernen.de/breakout-kontrolle-spielende-verloren.htm Seite 452

# Spielball Variablen
ball_x = random.randint(3,16)
ball_y = 23
ball_x_richtung = 1
ball_y_richtung = 1
ball_x_alt = 0
ball_y_alt = 0

# Spielerfigur
spielfigur_1_x = 10
spielfigur_1_y = 28
spielfigur_1_bewegung = 0

# Hintergrundfarbe Fenster
fenster.fill(WEISS)

# Korrekturfaktor berechnen
def kor(zahl):
zahl = zahl * MULTIPLIKATOR
return zahl

# Spielelement zeichnen
def element_zeichnen(spalte,reihe):
pygame.draw.rect(fenster, ORANGE, [kor(spalte)+1, kor(reihe)+1,kor(1)-1,kor(1)-

def element_loeschen(spalte,reihe):
pygame.draw.rect(fenster, WEISS, [kor(spalte), kor(reihe),kor(1),kor(1)])

def ball_zeichnen(x,y):
pygame.draw.ellipse(fenster, SCHWARZ, [kor(x), kor(y),kor(1), kor(1)], 0)

def spielfigur_zeichnen(x):
pygame.draw.rect(fenster, SCHWARZ,(kor(x), kor(spielfigur_1_y),50,kor(1)))

def spielfigur_loeschen(x):
pygame.draw.rect(fenster, WEISS,(kor(x), kor(spielfigur_1_y),50,kor(1)))

# Ausgabe Mauersteine im Spielfenster


for x in range(0,20):
for y in range(0,27):
if karte[y][x] != 0:
element_zeichnen(x,y)

naechsterschritt = False

# Schleife Hauptprogramm
while spielaktiv:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat
for event in pygame.event.get():
if event.type == pygame.QUIT or event.type == pygame.KEYDOWN and event.key ==
spielaktiv = False
print("Spieler hat beendet")
© https://www.python-lernen.de/breakout-kontrolle-spielende-verloren.htm Seite 453

# if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:


# naechsterschritt = True
# print("Nächster Schritt")

if event.type == pygame.KEYDOWN:
print("Spieler hat Taste gedrückt")

# Taste für Spieler 1


if event.key == pygame.K_LEFT:
print("Spieler hat Pfeiltaste links gedrückt")
spielfigur_1_bewegung = -1
elif event.key == pygame.K_RIGHT:
print("Spieler hat Pfeiltaste rechts gedrückt")
spielfigur_1_bewegung = 1

# Spiellogik
# -- Spielfigur darf das Spielfeld links nicht verlassen
if (spielfigur_1_x == 0 and spielfigur_1_bewegung == -1):
spielfigur_1_bewegung = 0

if spielfigur_1_x == 18 and spielfigur_1_bewegung == 1:


spielfigur_1_bewegung = 0

# Ballbewegung
if ball_x <= 0:
ball_x_richtung = 1
if ball_x >= 19:
ball_x_richtung = -1
if ball_y <= 0:
ball_y_richtung = 1
if ball_y > 29:
# ball_y_richtung = -1
ball_y_richtung = 0
ball_x_richtung = 0
print("Verloren :(")

# Spielfigurbewegung
spielfigur_1_x_alt = spielfigur_1_x
spielfigur_1_x += spielfigur_1_bewegung

# Ball trifft Mauerstein


# Kontrolle auf möglich Kollision
if ball_y_richtung == -1:
# Ball ist in Aufwärtsbewegung
# genau darüber ein Mauerstein?
if karte[ball_y-1][ball_x] != 0:
print("trifft Mauerstein oberhalb")
# Mauerstein wird gelöscht von Bildschirm
element_loeschen(ball_x, ball_y-1)
# Mauerstein wird gelöscht aus Liste karte
karte[ball_y-1][ball_x] = 0
ball_y_richtung = 1
© https://www.python-lernen.de/breakout-kontrolle-spielende-verloren.htm Seite 454

else:
if ball_x_richtung == 1:
# Ball bewegt sich nach rechts
if karte[ball_y-1][ball_x+1] != 0:
print("trifft Mauerstein rechts oberhalb")
# Mauerstein wird gelöscht von Bildschirm
element_loeschen(ball_x+1, ball_y-1)
# Mauerstein wird gelöscht aus Liste karte
karte[ball_y-1][ball_x+1] = 0
ball_y_richtung = 1
# trifft auf Ecke, also gleich Richtung zurück
ball_x_richtung = -1
else:
# Ball bewegt sich nach links
if karte[ball_y-1][ball_x-1] != 0:
print("trifft Mauerstein links oberhalb")
# Mauerstein wird gelöscht von Bildschirm
element_loeschen(ball_x-1, ball_y-1)
# Mauerstein wird gelöscht aus Liste karte
karte[ball_y-1][ball_x-1] = 0
ball_y_richtung = 1
# trifft auf Ecke, also gleich Richtung zurück
ball_x_richtung = +1

# Ball trifft Schläger


# Kontrolle auf möglich Kollision
if ball_y == 27 and ball_y_richtung == 1:
print("Kontrolle auf Kollision mit Schläger")

# Ball kommt von links:


if ball_x_richtung == 1:
print("Ball kommt von links")
if ball_x+1 >= spielfigur_1_x and ball_x+1 <= spielfigur_1_x+3:
print("Ball trifft Schläger")
ball_y_richtung = -1

# Ball kommt von rechts:


if ball_x_richtung == -1:
print("Ball kommt von rechts")
if ball_x-1 >= spielfigur_1_x and ball_x-1 <= spielfigur_1_x+3:
print("Ball trifft Schläger")
ball_y_richtung = -1

# Siegbedingung erfüllt?
mauersteine = 0
for i in range(len(karte)):
for j in range(len(karte[i])):
if karte[i][j] == 1:
mauersteine = mauersteine + 1
if mauersteine == 0:
# print("noch sind Mauersteine ", mauersteine ," da")
# else:
# gewonnen, alle Mauersteine sind weg
© https://www.python-lernen.de/breakout-kontrolle-spielende-verloren.htm Seite 455

# gewonnen, alle Mauersteine sind weg


# Ball wird eingefroren
ball_x_richtung = 0
ball_y_richtung = 0
# Meldung für Sieg
print("Gewonnen - herzlichen Glückwunsch")

ball_x_alt = ball_x
ball_y_alt = ball_y
ball_x += ball_x_richtung
ball_y += ball_y_richtung

# Ball zeichnen
element_loeschen(ball_x_alt, ball_y_alt)
ball_zeichnen(ball_x, ball_y)

# Spielerfigur zeichnen
spielfigur_loeschen(spielfigur_1_x_alt)
spielfigur_zeichnen(spielfigur_1_x)
spielfigur_1_bewegung = 0

# Fenster aktualisieren
pygame.display.flip()

# Refresh-Zeiten festlegen
clock.tick(10)

pygame.quit()

exit()
© https://www.python-lernen.de/grundgeruest-fuer-pygame.htm Seite 456

Aufräumen unseres Grundgerüsts für Pygame-


Anwendungen
Wir haben im Kapitel Pygame Einführung ein Grundaufbau erstellt. Diesen wollen wir in diesem
Kapitel optimieren und aufräumen. Denn je mehr Übersicht, desto schneller und mehr Spaß
macht die Entwicklung von Spielen.

Gehen wir Logisch wie im Flussdiagramm gezeigt nach den einzelnen Bereichen vor.

Schritt 1: Import und initialisieren der Pygame-Bibliothek


Nach dem Start wird als Erstes die Pygame-Bibliothek importiert und initialisiert. Ohne den
Import des Moduls können wir dieses auch nicht nutzen. Daher ist das der erste Schritt in
unserem Programm, alle benötigten Module zu importieren:

# Importieren u. initialisieren der Pygame-Bibliothek


import pygame

Namensraum („namespace“) importieren


Jetzt können wir uns durch den Import des Namensraums (das englische „namespace“ ist
geläufiger) viel Tipparbeit sparen. Ohne dass wir im „normalen“ Bereich unseres Programmes
die Namen verfügbar machen, müssten wir immer den „namespace“ dazuschreiben. Wenn wir
zum Beispiel pygame.KEYDOWN abfragen wollen, reicht nach dem Import von
© https://www.python-lernen.de/grundgeruest-fuer-pygame.htm Seite 457

pygames.locals in den allgemeinen Namensraum „*“ dann direkt die Abfrage KEYDOWN .

Natürlich will man nicht von jeglichem Modul, dass man importiert auch die verwendeten
Namen direkt verfügbar machen, da sonst schnell ein unübersichtliches Chaos entsteht. Für
uns macht es aber Pygame-Programm deutlich übersichtlicher.

Als zweite Zeile kommt also der „namespace“-import:

# Importieren u. initialisieren der Pygame-Bibliothek


import pygame
from pygame.locals import *

Die Auswirkungen an einem Beispiel: somit wird später aus der deutlich längeren Zeile für die
Nutzerabfrage:

if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame

dann die optimierte kürze Zeile:

if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):

Diese Zeile benötigen wir später in diesem Kapitel zum Schritt 4. Hier nur als Beispiel zum
besseren Verständnis!

Sollte der Import des Namespaces nicht erfolgt sein, erhalten wir dann für die optimierte Zeile
einen NameError: „NameError: name 'QUIT' is not defined“.

Kürzer ist schöner und unübersichtlicher

Initialisieren (starten) von Pygame


Nur der Import reicht nicht auch. Wir müssen das Modul Pygame auch initialisieren – wollte
man es in Deutsch sagen: „das Modul starten“. Das ist unsere dritte Anweisung in unserem
ersten Programmblock:

# Importieren u. initialisieren der Pygame-Bibliothek


import pygame
from pygame.locals import *
pygame.init()

Jetzt können wir Pygame nutzen – sehen aber noch nichts davon. Also öffnen wir erst einmal
eine Ausgabe, sprich ein Fenster. Für das Fenster benötigen wir Angaben wie die Breite und die
Höhe. Wir benötigen also Konstanten.

Schritt 2: Variablen und Konstanten definieren


Wir definieren unsere Konstanten für unser Ausgabefenster. Konstanten sind es deshalb, da
sich die Fenstergröße in der Regel nicht ändert. Wobei im Python es direkt eine Konstanten-
Definition gibt, sondern eher der Konvention (sprich die Festlegung, so macht man es am
besten), dass KONSTANTENNAMEN komplett in Großbuchstaben geschrieben werden.

Wir benötigen eine Breite und eine Höhe. Bisher haben wir für jede Variable und Konstante eine
extra Zeile in Python erstellt. Das werden wir nun für logisch zusammengehörige Variablen
nicht mehr machen und Python erlaubt auch sehr einfach die Wertzuweisung in einer Zeile.

Für die Breite nutzen wir ein großes „W“ und für die Höhe ein großes „H“. Das große H ist jedem
sofort klar. Hier kommt das „H“ aus dem Wort „Höhe“. Hier haben wir den Zufall, dass das
© https://www.python-lernen.de/grundgeruest-fuer-pygame.htm Seite 458

englische Wort für Höhe auch mit „h“ beginnt: „height“.

Bei der Breite kommt das große „W“ von dem Anfangsbuchstaben des englischen Worts
„widht“. Da es üblich ist, verwenden wir diese 2 Werte mit dieser Bezeichnung und als
Konstante:

# Variablen/KONSTANTEN setzen
W, H = 800, 600

In diesem Bereich sind auch im Programm genutzte Farben gut untergebracht. Für die
Fensterfarbe benötigen wir zum Beispiel später auch eine Hintergrundfarbe. Wir setzen hier die
deutschen Namen als Konstanten. Wer englische Bezeichnungen bevorzugt, kann natürlich
auch mit englischen Namen arbeiten:

# Variablen/KONSTANTEN setzen
W, H = 800, 600

# Farben setzen
SCHWARZ = ( 0, 0, 0)
WEISS = ( 255, 255, 255)

Den Bereich für die Variablen erweitern wir nach und nach, wenn wir die entsprechenden Werte
in unserem Programm benötigen.

Unser bisher entstandener kompletter Code:

# Importieren u. initialisieren der Pygame-Bibliothek


import pygame
from pygame.locals import *
pygame.init()

# Variablen/KONSTANTEN setzen
W, H = 800, 600
SCHWARZ = ( 0, 0, 0)
WEISS = ( 255, 255, 255)

Schritt 3: Definieren und Öffnen eines neuen Fensters


Für ein Fenster benötigen wir mehrere Angaben. Wir benötigen für das Fenster unbedingt eine
Breite und eine Höhe. Der Fenstertitel wäre schön (ist aber nicht zwingend notwendig.

Um das Fenster zu setzen, wird die Anweisung display.set_mode() aufgerufen. Die


Bezeichnung display in Python ist nicht wirklich glücklich gewählt worden (eigentlich würde
man von der Logik her eher an „screen“ denken) – aber so ist es eben. Unsere Zuweisung zu
der Variable fenster ist einigermaßen verständlich. Allerdings kann die Ausgabe auch im
„fullscreen“-Modus erfolgen (was dann nicht mehr so in die Fenster-Denkweise passt). Aber
zum Verständnis ist fenster als Bezeichnung gut geeignet.

fenster = pygame.display.set_mode((W, H))

Zum Setzen des Titels im Fensterkopf benötigen wir folgenden Befehl:

fenster = pygame.display.set_mode((W, H))


pygame.display.set_caption("Titel für Fensterkopf")

Als letzte Angabe wollen wir noch die Uhr verfügbar machen, damit wir später die Häufigkeit
© https://www.python-lernen.de/grundgeruest-fuer-pygame.htm Seite 459

der Aktualisierung einstellen können:

fenster = pygame.display.set_mode((W, H))


pygame.display.set_caption("Titel für Fensterkopf")
clock = pygame.time.Clock()

Unser bisher entstandener Code komplett:

# Importieren u. initialisieren der Pygame-Bibliothek


import pygame
from pygame.locals import *
pygame.init()

# Variablen/KONSTANTEN setzen
W, H = 800, 600
SCHWARZ = ( 0, 0, 0)
WEISS = ( 255, 255, 255)

# Definieren und Öffnen eines neuen Fensters


fenster = pygame.display.set_mode((W, H))
pygame.display.set_caption("Titel für Fensterkopf")
clock = pygame.time.Clock()

Es wird für einen Bruchteil einer Sekunde ein Fenster angezeigt und schon ist unser Programm
wieder beendet. Wir benötigen also ein Hauptprogramm, das länger läuft. Das wird im vierten
Bereich umgesetzt.

Schritt 4: unser Hauptprogramm in einer Endlosschleife


Bisher haben wir für unser Hauptprogramm eine Variable erstellt, die auf True gesetzt und in
einer while -Schleife abgefragt wurde.

Wenn wir eine Endlosschleife erstellen wollen, können wir auch direkt while True:
verwenden. Wird das Programm durch die Escape-Taste oder durch das entsprechende im
Fensterkopf beendet, können wir direkt das Programm über pygame.quit() beenden.

Innerhalb unseres Hauptprogramms kommt die Abfrage für die Nutzeraktion. Diese haben wir
uns bereits beim Schritt 1 angesehen. Somit haben wir folgenden Code:
© https://www.python-lernen.de/grundgeruest-fuer-pygame.htm Seite 460

# Importieren u. initialisieren der Pygame-Bibliothek


import pygame
from pygame.locals import *
pygame.init()

# Variablen/KONSTANTEN setzen
W, H = 800, 600
SCHWARZ = ( 0, 0, 0)
WEISS = ( 255, 255, 255)

# Definieren und Öffnen eines neuen Fensters


fenster = pygame.display.set_mode((W, H))
pygame.display.set_caption("Titel für Fensterkopf")
clock = pygame.time.Clock()

# Schleife Hauptprogramm
while True:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat
for event in pygame.event.get():
# Beenden bei [ESC] oder [X]
if event.type==QUIT or (event.type==KEYDOWN and event.key==K_ESCAPE):
pygame.quit()

Schritt 5: Logik des Spiels


Innerhalb der Hauptschleife ist es sehr sinnvoll, die Logik vom Spiel von der Ausgabe zu
trennen. Dadurch entsteht sauberer Code und verschiedene Aktionen können vor einer
Ausgabe abgefangen werden. Die Ausgabe selber wird dann in Schritt 6 machen. Noch gibt es
nur einen Platzhalter für unsere Spiellogik.

# Spiellogik

Schritt 6: Fenster aktualisieren


Jetzt wird Hintergrund, alle Spielfiguren gezeichnet und der Inhalt des Fensters aktualisiert. Es
wird also nicht jede einzelne Figur platziert und sofort gezeichnet, sondern erst werden alle
Elemente platziert und dann alle auf einen Streich in der Fensteranzeige aktualisiert. Das
beschleunigt unser Programm.

# Spielfeld löschen
fenster.fill(HGFARBE)

# Spielfeld/figuren zeichnen

# Fenster aktualisieren
pygame.display.flip()
clock.tick(FPS)

Bei den Refresh-Zeiten bei clock.tick(FPS) muss die Konstante oben im Programm in
unseren Bereich von Schritt 2 noch gesetzt werden.
© https://www.python-lernen.de/grundgeruest-fuer-pygame.htm Seite 461

Unser Grundgerüst, dass wir in den folgenden Kapiteln


verwenden
Hier der komplette Code, der uns in Zukunft als Grundgerüst für jede Pygame-Anwendung
dient.

# Importieren u. initialisieren der Pygame-Bibliothek


import pygame
from pygame.locals import *
pygame.init()

# Variablen/KONSTANTEN setzen
W, H = 800, 600
FPS = 60
SCHWARZ = ( 0, 0, 0)
WEISS = ( 255, 255, 255)

# Definieren und Öffnen eines neuen Fensters


fenster = pygame.display.set_mode((W, H))
pygame.display.set_caption("Titel für Fensterkopf")
clock = pygame.time.Clock()

# Schleife Hauptprogramm
while True:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat
for event in pygame.event.get():
# Beenden bei [ESC] oder [X]
if event.type==QUIT or (event.type==KEYDOWN and event.key==K_ESCAPE):
pygame.quit()

# Spiellogik

# Spielfeld löschen
fenster.fill(WEISS)

# Spielfeld/figuren zeichnen

# Fenster aktualisieren
pygame.display.flip()
clock.tick(FPS)
© https://www.python-lernen.de/bilder-grafiken-anzeigen-pygame.htm Seite 462

Grafiken und Bilder in Python über Pygame anzeigen


Viele Spiele leben unter anderem von guter Grafik. Wobei Grafiken sowohl die eigene
Spielerfigur wie die Gegner und die Hintergrundgrafiken sind. Mit Pygame ist es sehr einfach in
Python Grafiken anzuwenden. Diese können eingebunden, bewegt und animiert werden. In
diesem Kapitel werden alle Grundlagen über Grafiken gezeigt und wie (und wo) diese
eingebunden werden. In den Folgekapiteln werden wir dann Spiele mit Grafiken aufpeppen.

Aber erst zu den Grundlagen.

Grundlagen Grafiken/Bilder
Bildformate
Bei Bildern gibt es verschiedene Bildformate. Uns stehen in Python die Bildformate „.jpg“, „.png“
und „.gif“ zur Verfügung.

Größenangaben und Ursprung bei Grafiken


Auch wenn es sich selbstverständlich anhört, schauen wir uns kurz die Größenangaben und
den Ursprung bei Bildern an.

Der Nullpunkt ist immer oben links wie in der folgenden Grafik eingezeichnet. Von hier aus
werden nach rechts die X-Werte und nach unten die y-Werte größer. Wichtig in diesem
Zusammenhang ist die gesamte Breite und die Höhe. Hier kann man sich gleich die englischen
Begriffe für Breite = width und Höhe = height einprägen.

Denn spätestens, wenn unsere Grafik am rechten Fensterrand nicht einfach verschwinden soll,
sondern dort abprallen, benötigen wir die Breite für Berechnungen. Wir können über die
Position unserer Grafik auf den Nullpunkt zugreifen aber erst mit Nullpunkt plus der Breite bzw.
Höhe können wir berechnen, ob die Grafik den Fensterrand rechts bzw. unten berührt.
© https://www.python-lernen.de/bilder-grafiken-anzeigen-pygame.htm Seite 463

Schauen wir uns dies im Quellcode an.

Im ersten Schritt wollen wir eine Grafik laden. Dabei wird die Grafik noch nicht im Fenster
platziert, sprich sie ist noch nicht sichtbar. Diese muss erst erfolgreich geladen werden. Wir
vergeben eine „Variable“, auf die wir dann zugreifen können.

spielerfigur = pygame.image.load("biene.png")

Die hier verwendete Grafik der Biene kann über die URL: https://www.python-
lernen.de/bilder/biene.png zum Spielen und Testen heruntergeladen werden. Dazu einfach auf
die Grafik mit der rechten Maustaste klicken und „speichern unter“ wählen.

Lässt man sich die „Variable“ über print(spielerfigur) ausgeben, erhalten wir als
Rückgabe: <Surface(100x99x32 SW)>

WICHTIG! Unsere Grafik „biene.png“ befindet sich im gleichen Verzeichnis wie unser Python-
Programm. Sonst kann Python die Grafik nicht finden. Wer mehr Ordnung halten möchte, kann
auch alle Grafiken in ein Unterverzeichnis packen und dann darauf zugreifen. Dazu erstellen wir
im Verzeichnis, in dem unser Python-Programm liegt das Unterverzeichnis „bilder“ und packen
dort alle verwendeten Grafiken hinein. Dann ändert sich unser Python-Code entsprechend:

spielerfigur = pygame.image.load("bilder/biene.png")

Sollte das Bild sich nicht im Verzeichnis befinden oder ein Tippfehler im Dateinamen (Groß-
Kleinschreibung ist wichtig, Dateiende ist wichtig!) sich eingeschlichen haben, erhalten wir eine
Fehlermeldung in folgender Form:

pygame.error: Couldn't open bilder/biene.png


© https://www.python-lernen.de/bilder-grafiken-anzeigen-pygame.htm Seite 464

Jetzt kann es durchaus sein, dass uns die Bildgrößen der Grafiken nicht bekannt sind. Wir
können mit Pygame die Größen ermitteln und ausgeben lassen. Um die Größen zu ermitteln,
nutzen wir die Anweisung get_rect() .

spielerfigur = pygame.image.load("bilder/biene.png")
bildgroessen = spielerfigur.get_rect()

Darüber haben wir nun Zugriff auf die Werte:

Breite über bildgroessen.width

Höhe über bildgroessen.height

die Mitte der Breite (was der Hälfte der Breite entspricht) über bildgroessen.center[0]

die Mitte der Höhe über bildgroessen.center[1]

Die Werte können wir uns einfach einmal zur Kontrolle ausgeben lassen:

spielerfigur = pygame.image.load("bilder/biene.png")
bildgroessen = spielerfigur.get_rect()
print(bildgroessen)
print(bildgroessen.center[0])
print(bildgroessen.center[1])
print(bildgroessen.width)
print(bildgroessen.height)

Alle Daten können jetzt entsprechend weiterverwendet werden.

Grafik im Fenster platzieren


Jetzt wollen wir unsere Grafik im Fenster platzieren und anzeigen lassen. Wir verwenden unser
Grundgerüst für Pygame (siehe https://www.python-lernen.de/grundgeruest-fuer-pygame.htm
ganz unten).

# Importieren u. initialisieren der Pygame-Bibliothek


import pygame
from pygame.locals import *
pygame.init()

# Variablen/KONSTANTEN setzen
W, H = 800, 600
FPS = 60
SCHWARZ = ( 0, 0, 0)
WEISS = ( 255, 255, 255)
spielaktiv = True

# Definieren und Öffnen eines neuen Fensters


fenster = pygame.display.set_mode((W, H))
pygame.display.set_caption("Grafiken nutzen")
clock = pygame.time.Clock()

# Schleife Hauptprogramm
while spielaktiv:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat
for event in pygame.event.get():
# Beenden bei [ESC] oder [X]
if event.type==QUIT or (event.type==KEYDOWN and event.key==K_ESCAPE):
spielaktiv = False

# Spiellogik

# Spielfeld löschen
fenster.fill(WEISS)

# Spielfeld/figuren zeichnen

# Fenster aktualisieren
pygame.display.flip()
clock.tick(FPS)
© https://www.python-lernen.de/bilder-grafiken-anzeigen-pygame.htm Seite 465

Unsere Grafik laden wir vor der Hauptschleife vor dem „# Definieren und Öffnen eines neuen
Fensters“.

# Variablen/KONSTANTEN setzen
W, H = 800, 600
FPS = 60
SCHWARZ = ( 0, 0, 0)
WEISS = ( 255, 255, 255)
spielaktiv = True

spielerfigur = pygame.image.load("bilder/biene.png")
bildgroessen = spielerfigur.get_rect()
print(bildgroessen)
print(bildgroessen.center[0])
print(bildgroessen.center[1])
print(bildgroessen.width)
print(bildgroessen.height)

# Definieren und Öffnen eines neuen Fensters


fenster = pygame.display.set_mode((W, H))

Lassen wir unser Python-Programm ausführen, erhalten wir in der Konsole folgende Ausgabe
für die Größen:

Axels-MacBook-Pro:Python-lernen.de axel$ python3 grafiken-verwenden.py


pygame 1.9.6
Hello from the pygame community. https://www.pygame.org/contribute.html
<rect(0, 0, 100, 99)>
50
49
100
99

Jetzt können wir in unserer Hauptroutine (Schleife Hauptprogramm) die Grafik ausgeben
lassen.

# Spielfeld/figuren zeichnen
fenster.blit(spielerfigur, (200, 100))

Unsere Biene als Grafik erscheint nun an der Position x=200 und y=100 in unserem Fenster:

Grafik wird über blit() im Fenster platziert

Klugscheißermodus zu blit(): wer sich über die merkwürdige Anweisung blit() wundert.
Diese kommt aus der Bezeichnung „Bit blit“ – auch als BITBLT „allgemein“ bekannt ;). Und das
BLT steht dann für „BLock Transfer“. Es wird im Vorfeld alles auf einer Bitmap verrechnet
bevor es auf einen Schlag angezeigt wird. Dadurch wird Rechenleistung gespart.

Wenn wir nun die Hintergrundfarbe des Fensters ändern, sehen wir die quadratische Struktur
unseres Bildes:

# Variablen/KONSTANTEN setzen
W, H = 800, 600
FPS = 60
SCHWARZ = ( 0, 0, 0)
WEISS = ( 255, 255, 255)
GRAU = ( 155, 155, 155)

Und in der Hauptroutine:


© https://www.python-lernen.de/bilder-grafiken-anzeigen-pygame.htm Seite 466

# Spielfeld löschen
fenster.fill(GRAU)

Wir wollen auf jeden Fall, dass die Hintergrundfarbe die Kontur der Biene „umfließt“:

Hintergrundfarbe soll Kontur der Grafik umfließen

Dazu ist wichtig zu wissen, dass wir bei den Grafikformaten PNG und GIF einen transparenten
Bereich definieren können. Hier spricht man vom Alphakanal.

Und nun müssen wir beim Laden der Grafik noch mitgeben, dass dieser Alphakanal genutzt
werden soll.

Dies geschieht über die Erweiterung unserer Anweisung pygame.image.load() am Ende


um pygame.image.load().convert_alpha()

Unser bisher entstandener kompletter Code:


© https://www.python-lernen.de/bilder-grafiken-anzeigen-pygame.htm Seite 467

# Importieren u. initialisieren der Pygame-Bibliothek


import pygame
from pygame.locals import *
pygame.init()

# Variablen/KONSTANTEN setzen
W, H = 800, 600
FPS = 60
SCHWARZ = ( 0, 0, 0)
WEISS = ( 255, 255, 255)
GRAU = ( 155, 155, 155)
spielaktiv = True

spielerfigur = pygame.image.load("bilder/biene.png").convert_alpha()
bildgroessen = spielerfigur.get_rect()
print(bildgroessen)
print(bildgroessen.center[0])
print(bildgroessen.center[1])
print(bildgroessen.width)
print(bildgroessen.height)

# Definieren und Öffnen eines neuen Fensters


fenster = pygame.display.set_mode((W, H))
pygame.display.set_caption("Grafiken nutzen")
clock = pygame.time.Clock()

# Schleife Hauptprogramm
while spielaktiv:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat
for event in pygame.event.get():
# Beenden bei [ESC] oder [X]
if event.type==QUIT or (event.type==KEYDOWN and event.key==K_ESCAPE):
spielaktiv = False

# Spiellogik

# Spielfeld löschen
fenster.fill(GRAU)

# Spielfeld/figuren zeichnen
fenster.blit(spielerfigur, (200, 100))

# Fenster aktualisieren
pygame.display.flip()
clock.tick(FPS)

In den folgenden Kapiteln schauen wir uns an, wie man Grafiken bewegen, rotieren, skalieren
und Animieren kann.
© https://www.python-lernen.de/grafiken-rotieren.htm Seite 468

Grafiken rotieren um Mittelpunkt


Animationen mit Python erstellen
Im letzten Kapitel haben wir uns das „einbauen“ von Grafiken und Bildern in Python über
Pygame angesehen. Jetzt wollen wir mehr Spaß mit den Grafiken haben und diese rotieren
lassen. Darüber lässt sich bereits einiges an Animation umsetzen. Besonders wichtig ist der
Rotationspunkt … dazu mehr Schritt für Schritt.

Das im Teaser gezeigte Flugzeug wollen wir in Einzelteile zerlegen – genaugenommen in 2


Einzelteile: Den Propeller (der rotieren soll) und den Rest (also Rumpf mit Flügel und
Fahrwerk).

Die beiden Grafiken können über die jeweilige URL heruntergeladen werden oder einfach mit
der Maus auf die Grafik klicken und „speichern unter“ wählen:

https://www.python-lernen.de/bilder/propeller.png

https://www.python-lernen.de/bilder/propellerflieger.png

Zum Einbauen der 2 Grafiken nutzen wir unseren bisherigen Code aus dem letzten Kapitel:
© https://www.python-lernen.de/grafiken-rotieren.htm Seite 469

# Importieren u. initialisieren der Pygame-Bibliothek


import pygame
from pygame.locals import *
pygame.init()

# Variablen/KONSTANTEN setzen
W, H = 800, 600
FPS = 60
SCHWARZ = ( 0, 0, 0)
WEISS = ( 255, 255, 255)
GRAU = ( 155, 155, 155)
spielaktiv = True

spielerfigur = pygame.image.load("bilder/biene.png").convert_alpha()
bildgroessen = spielerfigur.get_rect()

# Definieren und Öffnen eines neuen Fensters


fenster = pygame.display.set_mode((W, H))
pygame.display.set_caption("Grafiken nutzen")
clock = pygame.time.Clock()

# Schleife Hauptprogramm
while spielaktiv:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat
for event in pygame.event.get():
# Beenden bei [ESC] oder [X]
if event.type==QUIT or (event.type==KEYDOWN and event.key==K_ESCAPE):
spielaktiv = False

# Spiellogik

# Spielfeld löschen
fenster.fill(GRAU)

# Spielfeld/figuren zeichnen
fenster.blit(spielerfigur, (200, 100))

# Fenster aktualisieren
pygame.display.flip()
clock.tick(FPS)

Anstelle unserer Biene aus dem Kapitel Space Invaders war gestern – Varroa Invaders
importieren wir nun unsere 2 Grafiken und vergeben die Namen propeller und
flugzeugrumpf :

Folgender Code wird an den entsprechenden Stellen in unserem Python-Programm eingebaut:

propeller = pygame.image.load("bilder/propeller.png")
flugzeugrumpf = pygame.image.load("bilder/propellerflieger.png")

Und zum Platzieren unseres Fliegers:

# Spielfeld/figuren zeichnen
fenster.blit(flugzeugrumpf, (0, 0))
fenster.blit(propeller, (0, 0))
© https://www.python-lernen.de/grafiken-rotieren.htm Seite 470

Allerdings haben wir noch einen grauen Himmel – wir sind aber Schönwetterflieger und wollen
deshalb einen schönen blauen Himmel!

Also die Hintergrundfarbe auf Hellblau ändern. Meine benutzte Farbe hat den Wert:
HIMMELBLAU = (120, 210, 255)

Flieger und Propeller als getrennte Grafikelemente

Bitte umsetzen, bevor man in den folgenden Code schaut.

Unser bisheriger Code:


© https://www.python-lernen.de/grafiken-rotieren.htm Seite 471

# Importieren u. initialisieren der Pygame-Bibliothek


import pygame
from pygame.locals import *
pygame.init()

# Variablen/KONSTANTEN setzen
W, H = 800, 600
FPS = 60
SCHWARZ = ( 0, 0, 0)
WEISS = (255, 255, 255)
GRAU = (155, 155, 155)
HIMMELBLAU = (120, 210, 255)
spielaktiv = True

propeller = pygame.image.load("bilder/propeller.png")
flugzeugrumpf = pygame.image.load("bilder/propellerflieger.png")

# Definieren und Öffnen eines neuen Fensters


fenster = pygame.display.set_mode((W, H))
pygame.display.set_caption("www.Python-lernen.de - Grafiken rotieren und skalieren")
clock = pygame.time.Clock()

# Schleife Hauptprogramm
while spielaktiv:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat
for event in pygame.event.get():
# Beenden bei [ESC] oder [X]
if event.type==QUIT or (event.type==KEYDOWN and event.key==K_ESCAPE):
spielaktiv = False

# Spiellogik

# Spielfeld löschen
fenster.fill(HIMMELBLAU)

# Spielfeld/figuren zeichnen
fenster.blit(flugzeugrumpf, (0, 0))
fenster.blit(propeller, (0, 0))

# Fenster aktualisieren
pygame.display.flip()
clock.tick(FPS)

Grafiken an gewünschten Punkt platzieren


Unsere Grafiken kleben nun im Eck bei x=0 und y=0. Allerdings braucht unser Propeller nach
oben Platz und sollte auf der Flugzeugnase sitzen.

Unsere Werte entsprechend ändern auf:

# Spielfeld/figuren zeichnen
fenster.blit(flugzeugrumpf, (20, 30))
fenster.blit(propeller, (118, 32))

Nun sitzt der Propeller am gewünschten Fleck auf der Flugzeugnase:


© https://www.python-lernen.de/grafiken-rotieren.htm Seite 472

Propeller proper positioniert

Grafik rotieren mit Pygame


Pygame biete einen Befehl zum Rotieren von Grafiken. Dieser rotiert eine Grafik gegen den
Uhrzeigersinn.

Bei dem Rotationsbefehl gibt man in der Klammer das zu rotierende Ursprungsbild an und den
Winkel (ohne Größenangabe).

Wir erzeugen eine zweite Grafik, um das Verständnis bei Rotationen schnell zu bekommen:

propeller2 = pygame.transform.rotate(propeller, 20)

Nach dem Platzieren passt da allerdings etwas nicht bzw. ist nicht wie erwartet:

# Spielfeld/figuren zeichnen
fenster.blit(flugzeugrumpf, (20, 30))
fenster.blit(propeller, (118, 32))
fenster.blit(propeller2, (118, 32))

rotiert nicht wie gewünscht

Unser Propeller rotiert nicht wie gewünscht. Der rote Punkt (der aus didaktischen Gründen rot
ist und sofort sichtbar) ist der Mittelpunkt unseres Propellers. Nach unserer ersten Rotation
scheint der Propeller vom Flieger abzufallen. Nichts was man bei einem gemütlichen Flug
gerne hätte.

Was ist passiert?

Die Rotation hat nicht um das Zentrum unserer Grafik stattgefunden. Zum Testen erstellen wir
uns eine Funktion mit dem Namen rotieren_zentrieren() , der wir neben der X und Y-
Angabe noch unser Bild und den Rotationsgrad angeben:

def rotieren(x, y, bild, gradangabe):


rotiert = pygame.transform.rotate(bild, gradangabe)
fenster.blit(rotiert, (x, y))

Im Hauptprogramm beim Spiel erweitern wir um den Aufruf der Funktion rotieren()
anstelle von fenster.blit(propeller2, (118, 32))
© https://www.python-lernen.de/grafiken-rotieren.htm Seite 473

# Spielfeld/figuren zeichnen
fenster.blit(flugzeugrumpf, (20, 30))
fenster.blit(propeller, (118, 32))
# fenster.blit(propeller2, (118, 32))
rotieren(118, 32, propeller, 20)

Damit wir besser sehen, in welchem Bereich die Berechnung erfolgt, zeichnen wir ein rotes
Viereck um die aktuelle Stellung des Propellers. Dies geschieht in unserer neuen Funktion:

def rotieren(x, y, bild, gradangabe):


rotiert = pygame.transform.rotate(bild, gradangabe)
fenster.blit(rotiert, (x, y))

# Viereck zeichnen - erst Größe ermitteln


viereck = rotiert.get_rect()
pygame.draw.rect(fenster, (200, 0, 0), (x, y, viereck.width, viereck.height), 1)

Wenn wir die Propeller in der Grundstellung ohne Rotation mit Viereck zeichnen lassen und
dann rotiert, sieht man schön das nach unten rechts wachsendem Quadrat:

rotieren(118, 32, propeller, 0)


rotieren(118, 32, propeller, 20)

Für die Rotation wird also der Nullpunkt links oben gesetzt – daher „wächst“ das Quadrat nach
rechts und unten und unser Propeller eiert durch die Gegend.

Propeller wird um die linke obere Ecke rotiert

Bild gegen den Uhrzeigersinn permanent rotieren lassen


Für unsere Bewegung des Propellers erweitern wir den Bereich „# Spiellogik“ um die Rotation.
Wir lassen eine Zahl von 0 bis 359 pro Durchgang ansteigen. Überschreitet die Zahl unseren
Kreis mit 360 Grad, fängt diese wieder bei 0 an.

# Spiellogik
if gradzahl <= 359:
gradzahl += 5
else:
gradzahl = 0

Zur Erinnerung: Unsere Rotation erfolgt gegen den Uhrzeigersinn. Wollte man nun eine
Rotation im Uhrzeigersinn, würde man von 359 nach 0 zählen lassen.

Unsere Variable gradzahl können wir nun unserer Rotationsfunktion mitgeben.

# Spielfeld/figuren zeichnen
fenster.blit(flugzeugrumpf, (20, 30))
rotieren(118, 32, propeller, gradzahl)

Grafiken um Mittelpunkt rotieren


© https://www.python-lernen.de/grafiken-rotieren.htm Seite 474

Wir wollen also, dass unsere Grafik um den Mittelpunkt rotiert – bei unserem Propeller sitzt
dieser exakt auf dem roten Punkt.

Daher erstellen wir uns im nächsten Schritt eine Funktion mit dem Namen
rotieren_zentrieren() .

Auch dieser Funktion wird neben der X und Y-Angabe noch unser Bild und den Rotationsgrad
mitgegeben:

def rotieren_zentrieren(x, y, bild, gradangabe):


# rotieren und in einem neuen "surface" speichern
rotiert = pygame.transform.rotate(bild, gradangabe)

# Bestimmen der neuen Abmessungen (nach Rotation ändern sich diese!)


groesse = rotiert.get_rect()

# Ausgabe
fenster.blit(rotiert, (x - groesse.center[0],y - groesse.center[1]))

Wenn man sich den Programmcode anschaut, sieht man den Trick. Es wird nach der Rotation
die Größen der Grafik bestimmt und dann diese mittig ausgegeben. Über center[0] und
center[1] haben wir den Mittelpunkt.

Propeller rotiert um Mittelpunkt

Und als Animation:

Animation Propeller zentriert und mit falschem Nullpunkt

Man sieht schön anhand des Vierecks der alten Rotationsfunktion, dass die Rotation exakt auf
dem Nullpunkt der x- und y-Angabe sitzt. Diese verschieben wir später noch.

Jetzt lassen wir uns einfach zur Kontrolle noch ein Viereck ausgeben:
© https://www.python-lernen.de/grafiken-rotieren.htm Seite 475

def rotieren_zentrieren(x, y, bild, gradangabe):


# rotieren und in einem neuen "surface" speichern
rotiert = pygame.transform.rotate(bild, gradangabe)

# Bestimmen der neuen Abmessungen (nach Rotation ändern sich diese!)


groesse = rotiert.get_rect()

# Ausgabe
fenster.blit(rotiert, (x - groesse.center[0],y - groesse.center[1]))

pygame.draw.rect(fenster, (255, 255, 255), (x - groesse.center[0], y - groesse.center[

Wir wissen, dass unser Propeller eine Breite von 100 und eine Höhe von 63 hat. Also geben wir
die beim Aufruf die Hälfe jeweils mit (die Zahl 118 und 32 stammt aus dem ursprünglichen
Platzieren des Flugzeugrumpfs):

rotieren_zentrieren(118+50, 32+31, propeller, gradzahl)

Rotation des Propellers um dessen Mittelpunkt

Somit haben wir eine saubere Rotation um den Mittelpunkt (was man dann doch öfters
benötigt) und haben alle Möglichkeiten von Rotationen von Grafiken über Pygame und Python
kennengelernt.

Hier der komplette Quellcode zur Sicherheit:

# Importieren u. initialisieren der Pygame-Bibliothek


import pygame
from pygame.locals import *
pygame.init()

# Variablen/KONSTANTEN setzen
W, H = 800, 600

W_HALBE = W / 2
H_HALBE = H / 2

FPS = 60
SCHWARZ = ( 0, 0, 0)
WEISS = (255, 255, 255)
GRAU = (155, 155, 155)
HIMMELBLAU = (120, 210, 255)
spielaktiv = True

gradzahl = 0

propeller = pygame.image.load("bilder/propeller.png")
flugzeugrumpf = pygame.image.load("bilder/propellerflieger.png")

# Definieren und Öffnen eines neuen Fensters


© https://www.python-lernen.de/grafiken-rotieren.htm Seite 476

# Definieren und Öffnen eines neuen Fensters


fenster = pygame.display.set_mode((W, H))
pygame.display.set_caption("www.Python-lernen.de - Grafiken rotieren")
clock = pygame.time.Clock()

# Funktion zum Grafiken rotieren und zentrieren


# def rotieren_zentrieren(ausgabe, x, y, bild, gradangabe):
def rotieren_zentrieren(x, y, bild, gradangabe):
# rotieren und in einem neuen "surface" speichern
rotiert = pygame.transform.rotate(bild, gradangabe)

# Bestimmen der neuen Abmessungen (nach Rotation ändern sich diese!)


groesse = rotiert.get_rect()

# Ausgabe
fenster.blit(rotiert, (x - groesse.center[0],y - groesse.center[1]))

# Viereck zur Kontrolle zeichnen


pygame.draw.rect(fenster, (255, 255, 255), (x - groesse.center[0], y - groesse.center[

def rotieren(x, y, bild, gradangabe):


rotiert = pygame.transform.rotate(bild, gradangabe)
fenster.blit(rotiert, (x, y))

# Viereck zeichnen - erst Größe ermitteln


viereck = rotiert.get_rect()
pygame.draw.rect(fenster, (200, 0, 0), (x, y, viereck.width, viereck.height), 1)

# Schleife Hauptprogramm
while spielaktiv:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat
for event in pygame.event.get():
# Beenden bei [ESC] oder [X]
if event.type==QUIT or (event.type==KEYDOWN and event.key==K_ESCAPE):
spielaktiv = False

# Spiellogik
if gradzahl <= 359:
gradzahl += 5
else:
gradzahl = 0

# Spielfeld löschen
fenster.fill(HIMMELBLAU)

# Spielfeld/figuren zeichnen
fenster.blit(flugzeugrumpf, (20, 30))
# rotieren(118, 32, propeller, gradzahl)
rotieren_zentrieren(118+50, 32+31, propeller, gradzahl)

# Fenster aktualisieren
pygame.display.flip()
clock.tick(FPS)
© https://www.python-lernen.de/grafiken-rotieren.htm Seite 477
© https://www.python-lernen.de/grafiken-skalieren.htm Seite 478

Grafiken skalieren (verkleinern bzw. vergrößern)


Alleine durch unterschiedliche Größenverhältnisse kann ein Eindruck der Raumtiefe entstehen.
Für das Beispiel nutzen wir unsere Biene, die man zum Testen herunterladen kann unter:
https://www.python-lernen.de/bilder/biene-gr.png

Und wieder nehmen wir unser Grundgerüst, und setzen dort unsere Grafik ein.
© https://www.python-lernen.de/grafiken-skalieren.htm Seite 479

# Importieren u. initialisieren der Pygame-Bibliothek


import pygame
from pygame.locals import *
pygame.init()

# Variablen/KONSTANTEN setzen
W, H = 800, 600
FPS = 30
SCHWARZ = ( 0, 0, 0)
WEISS = ( 255, 255, 255)
GRAU = ( 155, 155, 155)
spielaktiv = True

spielerfigur = pygame.image.load("bilder/biene-gr.png")
bildgroessen = spielerfigur.get_rect()
print(bildgroessen)
print(bildgroessen.center[0])
print(bildgroessen.center[1])
print(bildgroessen.width)
print(bildgroessen.height)

# Definieren und Öffnen eines neuen Fensters


fenster = pygame.display.set_mode((W, H))
pygame.display.set_caption("Grafik skalieren")
clock = pygame.time.Clock()

# Schleife Hauptprogramm
while spielaktiv:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat
for event in pygame.event.get():
# Beenden bei [ESC] oder [X]
if event.type==QUIT or (event.type==KEYDOWN and event.key==K_ESCAPE):
spielaktiv = False

# Spiellogik

# Spielfeld löschen
fenster.fill(GRAU)

# Spielfeld/figuren zeichnen
fenster.blit(spielerfigur, (200, 100))

# Fenster aktualisieren
pygame.display.flip()
clock.tick(FPS)

Bauen wir nun unsere 3 Bienen fix ein. Effektiv müssen wir diese nur einmal laden und erstellen
dann durch transform.scale() uns die gewünschte Anzahl von Grafiken in der
gewünschte Größe:
© https://www.python-lernen.de/grafiken-skalieren.htm Seite 480

# Importieren u. initialisieren der Pygame-Bibliothek


import pygame
from pygame.locals import *
pygame.init()

# Variablen/KONSTANTEN setzen
W, H = 800, 600
FPS = 60
SCHWARZ = ( 0, 0, 0)
WEISS = ( 255, 255, 255)
GRAU = ( 155, 155, 155)
spielaktiv = True

spielerfigur = pygame.image.load("bilder/biene-gr.png")

# Definieren und Öffnen eines neuen Fensters


fenster = pygame.display.set_mode((W, H))
pygame.display.set_caption("Grafik skalieren")
clock = pygame.time.Clock()

# Schleife Hauptprogramm
while spielaktiv:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat
for event in pygame.event.get():
# Beenden bei [ESC] oder [X]
if event.type==QUIT or (event.type==KEYDOWN and event.key==K_ESCAPE):
spielaktiv = False

# Spiellogik

# Spielfeld löschen
fenster.fill(GRAU)

# Spielfeld/figuren zeichnen
bienen_klein = pygame.transform.scale(spielerfigur, (150,150))
bienen_mittel = pygame.transform.scale(spielerfigur, (250,250))
bienen_gross = pygame.transform.scale(spielerfigur, (350,350))
fenster.blit(bienen_klein, (500, 60))
fenster.blit(bienen_mittel, (340, 190))
fenster.blit(bienen_gross, (80, 60))

# Fenster aktualisieren
pygame.display.flip()
clock.tick(FPS)

Das ergibt dann:


© https://www.python-lernen.de/grafiken-skalieren.htm Seite 481

3 Bienen scheinen nebeneinander zu fliegen

Wenn wir nun noch mit den Größen und der Zeit spielen, entsteht ein interessanter Effekt. Wir
lassen die Größen leicht variieren.

Dazu setzen wir bei der Definition der Variablen der Startwert skalierung = 0 und
verändernden Faktor über skalierungswert = 1 .

In der Spiellogik verändern wir den Wert und fragen ab, ob er über 6 geht und verändern die
Richtung:

# Spiellogik
skalierung += skalierungswert

if skalierung > 6 or skalierung < -6:


skalierungswert = -skalierungswert

Und beim Zeichnen der Spielfiguren geben wir den Wert bei 2 Grafiken mit Plus und bei einer
Grafik mit Minus mit. Somit bewegen sich die Bienen zueinander.

# Spielfeld/figuren zeichnen
bienen_klein = pygame.transform.scale(spielerfigur, (150+skalierung,150+skalierung))
bienen_mittel = pygame.transform.scale(spielerfigur, (250-skalierung,250-skalierung))
bienen_gross = pygame.transform.scale(spielerfigur, (350+skalierung,350+skalierung))
fenster.blit(bienen_klein, (500, 60))
fenster.blit(bienen_mittel, (340, 190))
fenster.blit(bienen_gross, (80, 60))

Und hier der komplette Code:


© https://www.python-lernen.de/grafiken-skalieren.htm Seite 482

# Importieren u. initialisieren der Pygame-Bibliothek


import pygame
from pygame.locals import *
pygame.init()

# Variablen/KONSTANTEN setzen
W, H = 800, 600
FPS = 30
SCHWARZ = ( 0, 0, 0)
WEISS = ( 255, 255, 255)
GRAU = ( 155, 155, 155)
spielaktiv = True

skalierung = 0
skalierungswert = 1

spielerfigur = pygame.image.load("bilder/biene-gr.png")

# Definieren und Öffnen eines neuen Fensters


fenster = pygame.display.set_mode((W, H))
pygame.display.set_caption("Grafik skalieren")
clock = pygame.time.Clock()

# Schleife Hauptprogramm
while spielaktiv:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat
for event in pygame.event.get():
# Beenden bei [ESC] oder [X]
if event.type==QUIT or (event.type==KEYDOWN and event.key==K_ESCAPE):
spielaktiv = False

# Spiellogik
skalierung += skalierungswert

if skalierung > 6 or skalierung < -6:


skalierungswert = -skalierungswert

# Spielfeld löschen
fenster.fill(GRAU)

# Spielfeld/figuren zeichnen
bienen_klein = pygame.transform.scale(spielerfigur, (150+skalierung,150+skalierung))
bienen_mittel = pygame.transform.scale(spielerfigur, (250-skalierung,250-skalierung))
bienen_gross = pygame.transform.scale(spielerfigur, (350+skalierung,350+skalierung))
fenster.blit(bienen_klein, (500, 60))
fenster.blit(bienen_mittel, (340, 190))
fenster.blit(bienen_gross, (80, 60))

# Fenster aktualisieren
pygame.display.flip()
clock.tick(FPS)

Und als Ergebnis erhalten wir folgende Animation (in Python dann sehr viel flüssiger als hier):
© https://www.python-lernen.de/grafiken-skalieren.htm Seite 483

Eindruck der Raumtiefe durch unterschiedliche wechselnde Skalierung

Jetzt wäre noch schön, wenn die Flügel schlagen würden. Die Animation der Flügel wird das
Thema unseres nächsten Kapitels sein.
© https://www.python-lernen.de/animationen-erstellen.htm Seite 484

Animationen erstellen: Spielerfigur animieren über Sprite-


Sheets in 2 verschiedenen Vorgehensweisen
„Was ist ein Sprite“ ist die erste logische Frage. Als englische Übersetzung taucht „Elf, Kobold“
auf. Das Sprite ist ein Grafikobjekt, dass über einen Hintergrund eingeblendet wird und
ausgetauscht werden kann. Ursprünglich kommt die Bezeichnung daher, dass das Sprite nicht
im Grafikspeicher zu finden war aber trotzdem über den Bildschirm „spuckt“. Anmerkung am
Rande: Heutzutage mit der enormen Rechenkapazität findet es sich sehr wohl im
Grafikspeicher.

Dieses Sprite wird in mehreren Varianten vorgehalten und wird dann je nach Zustand
angezeigt. So können Bewegungen simuliert werden. Da unser Auge träge ist, müssen auch
nicht alle Zwischenschritte eine Bewegung angezeigt werden.

Folgendes Beispiel werden wir Schritt für Schritt umsetzen:

Für das Beispiel mit dem Flügelschlag der Biene reichen uns 6 Bilder, die sich abwechseln:

Die einzelnen Stadien der Bewegung kann man in einer Grafikdatei abspeichern und jeweils nur
einen Ausschnitt davon anzeigen. Sind also mehrere Bewegungsschritte in einer Datei
abgespeichert, spricht man von Sprite-Sheet (kennt man aus dem Englischen mit dem Begriff
„data sheet“ für Datenblatt – anstelle von einzelnen Daten haben wir eben einzelne Grafiken in
unserem Sprite-Sheet).

Wie können wir nun mit Python und Pygame daraus eine Animation erstellen? Sehr einfach und
sogar auf 2 Wege, die hier beide gezeigt werden sollen.

Animation über Einzelgrafiken


Um das Beispiel nachzuvollziehen, können die einzelnen Grafiken von unserer bewegten Biene
heruntergeladen werden unter:

https://www.python-lernen.de/bilder/biene-r-001.png

https://www.python-lernen.de/bilder/biene-r-002.png

https://www.python-lernen.de/bilder/biene-r-003.png

https://www.python-lernen.de/bilder/biene-r-004.png

https://www.python-lernen.de/bilder/biene-r-005.png

https://www.python-lernen.de/bilder/biene-r-006.png

Diese Grafiken speichern wir im Unterordner „bilder“ und laden diese über Pygame in eine
Liste. Dadurch können wir dann im Spiel gezielt für die Animation die einzelnen Stadien der
© https://www.python-lernen.de/animationen-erstellen.htm Seite 485

Bewegung über den Index auswählen.

Wir erstellen uns eine leere Liste für die Grafiken:

biene = ['','','','','','']

Und füllen nun diese:

biene = ['','','','','','']
biene[0] = pygame.image.load("bilder/biene-r-001.png")
biene[1] = pygame.image.load("bilder/biene-r-002.png")
biene[2] = pygame.image.load("bilder/biene-r-003.png")
biene[3] = pygame.image.load("bilder/biene-r-004.png")
biene[4] = pygame.image.load("bilder/biene-r-005.png")
biene[5] = pygame.image.load("bilder/biene-r-006.png")

Das ginge zwar als Code galanter, aber so ist es am einfachsten zu verstehen, was hier
passiert.

Jetzt brauchen wir einen Status, welche Grafik aktuell angezeigt werden soll. Wir definieren
eine Variable mit dem Namen frame = 0 .

Und innerhalb unserer Hauptschleife laufen wir durch alle vorhandenen Framenummer durch
und beginnen wieder bei 0, wenn wir den letzten erreicht haben. Noch schöner wäre, wenn wir
die Frames einfach rückwärts wieder durchgehen würden.

frame += 1

if frame > 5:
frame = 0

Und nun müssen wir nur noch unsere Biene mit dem entsprechenden Index (sprich Frame)
zeichnen:

fenster.blit(biene[frame], (10, 10))

Unsere Biene ist nun wild am Flügelschlagen (man will ja im Leben vorwärtskommen).

Biene mit animierter Bewegung der Flügel

Und hier nun der komplette Code:

# Importieren u. initialisieren der Pygame-Bibliothek


import pygame
from pygame.locals import *
pygame.init()

# Variablen/KONSTANTEN setzen
W, H = 800, 600
FPS = 30
SCHWARZ = ( 0, 0, 0)
WEISS = ( 255, 255, 255)
© https://www.python-lernen.de/animationen-erstellen.htm Seite 486

WEISS = ( 255, 255, 255)


GRAU = ( 155, 155, 155)
spielaktiv = True

biene = ['','','','','','']
biene[0] = pygame.image.load("bilder/biene-r-001.png")
biene[1] = pygame.image.load("bilder/biene-r-002.png")
biene[2] = pygame.image.load("bilder/biene-r-003.png")
biene[3] = pygame.image.load("bilder/biene-r-004.png")
biene[4] = pygame.image.load("bilder/biene-r-005.png")
biene[5] = pygame.image.load("bilder/biene-r-006.png")

frame = 0

# Definieren und Öffnen eines neuen Fensters


fenster = pygame.display.set_mode((W, H))
pygame.display.set_caption("python-lernen.de - Sprite (mehrere Grafiken) animieren")
clock = pygame.time.Clock()

# Schleife Hauptprogramm
while spielaktiv:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat
for event in pygame.event.get():
# Beenden bei [ESC] oder [X]
if event.type==QUIT or (event.type==KEYDOWN and event.key==K_ESCAPE):
spielaktiv = False

# Spiellogik

# Spielfeld löschen
fenster.fill(GRAU)

# Spielfeld/figuren zeichnen
frame += 1

if frame > 5:
frame = 0

fenster.blit(biene[frame], (10, 10))

# Fenster aktualisieren
pygame.display.flip()
clock.tick(FPS)

Falls man sich die Bewegung langsam ansehen möchten, kann man einfach den FPS-Wert
umstellen auf: FPS = 1

Animation über ein Sprite-Sheet (alle Grafiken in nur einer Datei)


Der große Unterschied ist, dass wir nun nicht zig Einzeldateien haben, sondern eine große
Datei, in der alle Bewegungsstadien enthalten sind.

Zum besseren verdeutlichen ist um jedes Stadium ein bunter Rahmen gezogen:
© https://www.python-lernen.de/animationen-erstellen.htm Seite 487

die 6 Stadien des Fluges unserer Biene

Was können wir nun damit anfangen?

Jedes Bild unserer Bienen ist 100 Pixel breit und 100 Pixel hoch.

Aufbau eines Sprite-Sheets mit Maßen

Somit können wir für jedes Stadium exakt die Angaben machen, bei welchem X- und Y-Wert
das entsprechende Teilstück des Bildes anfängt und auch aufhört.

Wir erhalten also 4 Werte. Wollen wir beispielsweise das dritte Stadium nutzen (die grün
umrandete Biene), dann können wir dies direkt über die Werte (201, 0, 301, 100) ansprechen.

Bei der Anweisung blit() gibt es die Möglichkeit, dass nur ein Teilbereich des gesamten
Bildes (also ein Ausschnitt) angezeigt wird. Dieser Ausschnitt wird festgelegt über den
Startpunkt, also den oberen X- und Y-Wert und zusätzlich die Breite und die Höhe. Als Beispiel:
der Teilausschnitt mit dem grünen Rahmen kann somit über die Angabe (201, 0, 100,100)
ausgewählt werden.

Unser Code:

fenster.blit(GRAFIK, (POSITION X, Y), angezeigter TEILBEREICH)

Oder mit Zahlen gefüllt – man achte auf die Klammern!

fenster.blit(biene, (20, 10), (201, 0, 100,100))

Unser Code unterscheidet sich also nicht so wesentlich wie in der ersten Vorgehensweise. Wir
bauen im Folgenden nochmals das gleiche Beispiel wie schon in der Vorgehensweise mit den
Einzelgrafiken – jetzt aber mit unserer Grafik als Sprite-Sheet.

Die Grafik kann zum Testen heruntergeladen werden unter:


© https://www.python-lernen.de/animationen-erstellen.htm Seite 488

https://www.python-lernen.de/bilder/biene-sprite-sheet.png


(oder einfach auf die Grafik mit der rechten Maustaste klicken und "speichern unter" wählen)

Wir laden im Python-Code unsere Biene als Grafik:

biene = pygame.image.load("bilder/biene-sprite-sheet.png")

Und hinterlegen die Koordinaten unter bereich : X- und Y-Wert, wo der Bereich beginnt und
die letzten beiden Zahlen sind die Breite und die Höhe (was in allen Fällen 100 Pixel sind).

bereich = ['','','','','','']
bereich[0] = (0,0,100,100)
bereich[1] = (101,0,100,100)
bereich[2] = (202,0,100,100)
bereich[3] = (303,0,100,100)
bereich[4] = (404,0,100,100)
bereich[5] = (505,0,100,100)

Innerhalb unserer Hauptschleife ändern wir in jedem Durchgang die Frame-Nummer und
lassen uns den durch den Bereich festgelegten Teilausschnitt ausgeben:

# Spielfeld/figuren zeichnen
frame += 1

if frame > 5:
frame = 0

print(frame, bereich[frame])

fenster.blit(biene, (240, 10), bereich[frame])

Als Ergebnis erhalten wir wieder unsere animierte fliegende Biene.

Der komplette Code:

# Importieren u. initialisieren der Pygame-Bibliothek


import pygame
from pygame.locals import *
pygame.init()

# Variablen/KONSTANTEN setzen
W, H = 800, 600
FPS = 2
SCHWARZ = ( 0, 0, 0)
WEISS = ( 255, 255, 255)
GRAU = ( 155, 155, 155)
spielaktiv = True

biene = pygame.image.load("bilder/biene-sprite-sheet.png")

bereich = ['','','','','','']
© https://www.python-lernen.de/animationen-erstellen.htm Seite 489

bereich[0] = (0,0,100,100)
bereich[1] = (101,0,100,100)
bereich[2] = (202,0,100,100)
bereich[3] = (302,0,100,100)
bereich[4] = (402,0,100,100)
bereich[5] = (504,0,100,100)

print(bereich)

frame = 0

# Definieren und Öffnen eines neuen Fensters


fenster = pygame.display.set_mode((W, H))
pygame.display.set_caption("python-lernen.de - Sprite-Sheet animieren")
clock = pygame.time.Clock()

# Schleife Hauptprogramm
while spielaktiv:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat
for event in pygame.event.get():
# Beenden bei [ESC] oder [X]
if event.type==QUIT or (event.type==KEYDOWN and event.key==K_ESCAPE):
spielaktiv = False

# Spiellogik

# Spielfeld löschen
fenster.fill(WEISS)

# Spielfeld/figuren zeichnen
frame += 1

if frame > 5:
frame = 0

print(frame, bereich[frame])

fenster.blit(biene, (240, 10), bereich[frame])

# Fenster aktualisieren
pygame.display.flip()
clock.tick(FPS)

PS: die Sprünge bei den verschiedenen Bereichen kommen daher, dass die Grundgrafik nicht
sauber ist – sprich nicht überall 100 Pixel Breite pro Biene haben (die Grafik mache ich bei
Gelegenheit noch sauber). Wichtig ist hier erst einmal das Verständnis für die Vorgehensweise.

Aufgabe: Animation eines Pferdes


Es gibt eine sehr bekannte Fotografie eines laufenden Pferdes aus dem Jahr 1872 von
Eadweard Muybridge. Aufgabe ist, dieses Foto aus Wikipedia zu laden und über die Sprite-
Sheet-Technik animieren. Das Foto findet sich unter:
© https://www.python-lernen.de/animationen-erstellen.htm Seite 490

https://en.wikipedia.org/wiki/Eadweard_Muybridge#/media/File:The_Horse_in_Motion_high_res.jpg

Viel Spaß bei der Umsetzung.


© https://www.python-lernen.de/space-invaders-python-varroa-invaders.htm Seite 491

Space Invaders war gestern – Varroa Invaders selber


programmieren ist heute!
Der Klassiker Space Invaders aus dem Jahr 1978 war als Automatenspiel in Japan so gefragt,
dass 100-Yen-Münzen landesweit knapp wurden. Die Spielgeschichte ist simpel und das
Spielen ist einfach nur Spaß. Außerirdische (Space) wollen die Erde überfallen (engl. invaders =
Eindringlinge) und man als Held muss mit einem kleinen Geschütz die Invasion abwehren, die
in Reihen immer schneller näher kommen. Zusätzlich hat man kleine Schilde, die während dem
Spiel durch die nach unten fallenden Bomben immer mehr zerstört werden. Erreicht die
Invasion den Verteidiger (oder wird der von einer Bombe getroffen) ist das Spiel verloren.

Was wollen wir in Python als Übungsspiel programmieren? Ähnlich dem Spielprinzip wie bei
Space Invaders greifen wir in unserem Spiel nicht nach den Sternen, sondern stellen und einem
realen Problem, mit dem jeder Imker kämpft: Der Varroamilbe – dieser Schädling ist die Furcht
jedes Imkers. Wenn wir es uns einen ähnlichen Schädling beim Menschen vorstellen: es wäre,
als müsste man als Mensch mit einer fetten Ratte, die einen in den Rücken gebissen hat und
seitdem dort festhängend Nahrung saugt, herumlaufen und trotzdem noch fröhlich seine
Arbeit machen. Will man nicht haben und daher auf zum Programmieren des „Varro Invaders“!

In der Realität geht der Imker mit diversen Mitteln gegen Varroa vor, was aber als Spiel nicht so
lustig wäre. Daher müssen wir als Kampfbiene unseren Bienenstock geben die böse
Varroamilbe (lat. Varroa destructor) verteidigen.

Space Invaders war gestern – heute ist Varroa Invaders

Im Gegensatz zu Space Invaders spielt sich unser Spielgeschehen von rechts nach links ab.
Unsere Kampfbiene bewegt sich vor dem Bienenstock und kann einen Honigtropen abfeuern.

Die Schädlinge mit dem Namen Varroa kommen je nach Level in einer bestimmten Anzahl und
wandern von hoch und runter. Jedes Mal, wenn diese am Fensterrand angekommen sind,
kommen diese dem Bienenstock näher.

Je nach Level sind es mehr Gegner und bewegen sich auch schneller.

Erreicht ein Gegner die Kampfbiene gibt es mehrere Möglichkeiten:

einfach Umsetzung: das Spiel ist verloren

anspruchsvoller: die Varroamilbe klebt sich an die Kampfbiene und diese wird schwerfälliger,
was sich direkt in der Steuerung auswirkt. Ab 3 angeklebten Milben war es das für unsere
tapfere Kampfbiene

Das zum prinzipiellen Spielablauf.

Was benötigen wir für unser Spiel:

das übliche Grundgerüst (aus https://www.python-lernen.de/grundgeruest-fuer-pygame.htm )

unsere animierte Biene (siehe https://www.python-lernen.de/animationen-erstellen.htm )


© https://www.python-lernen.de/space-invaders-python-varroa-invaders.htm Seite 492

unsere Gegner als Grafik (kommt im passenden Zeitpunkt bei der Umsetzung)

einen Honigtropfen (was auch sonst)

ein Hintergrundbild

eine Hintergrundmusik

einen Sound für das schießen

und einen Sound für das treffen

zusätzlich natürlich ein Glas deutscher Imkerhonig (wichtig: wenn auf einem Honigglas so ein
Satz „aus EU- und Nicht-EU Ländern“ steht, dann stehen lassen. Wir wollen das reine
Honigerlebnis, ohne das verschiedene zusammengerührt werden. Zusätzlicher „Funfact“: Honig
ist das weltweit am meisten gefälschte Lebensmittel

Folgende Punkte setzen wir der Reihe nach um:

Grundgerüst übernehmen und unsere Spielfigur integrieren

Unsere Spielfigur über Tastatur bewegen (und Bewegungsradius festlegen)

unseren Feind einbauen

Bewegungsmechanik vom Feind integrieren

aus einem Feind viele Feinde machen

Ein Hintergrundbild hinzufügen

Geschosse (passenderweise Honigtropfen) einbauen

abschießen des Geschosses

Zusammenstoß zwischen Geschosse und Feind

mehr als 1 Feind: eine Invasion von Feinden

Punktestand anzeigen

Sounds & Hintergrundmusik

Game over

weitere Level einbauen

Wir haben also etwas zu tun - und los geht es:

Grundgerüst in Python für unser Spiel


Erstellen wir eine Python-Datei mit dem Namen „varroa-invaders.py“ und unserem Grundgerüst.
Dieses können wir aus dem Kapitel https://www.python-lernen.de/grundgeruest-fuer-
pygame.htm übernehmen (und sollte etwas beim Code nicht klar sein, kann man dort
nachlesen):
© https://www.python-lernen.de/space-invaders-python-varroa-invaders.htm Seite 493

# Importieren u. initialisieren der Pygame-Bibliothek


import pygame
from pygame.locals import *
pygame.init()

# Variablen/KONSTANTEN setzen
W, H = 800, 600
FPS = 30
SCHWARZ = ( 0, 0, 0)
WEISS = ( 255, 255, 255)

spielaktiv = True

# Definieren und Öffnen eines neuen Fensters


fenster = pygame.display.set_mode((W, H))
pygame.display.set_caption("Varroa Invaders")
clock = pygame.time.Clock()

# Schleife Hauptprogramm
while spielaktiv = False:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat
for event in pygame.event.get():
# Beenden bei [ESC] oder [X]
if event.type==QUIT or (event.type==KEYDOWN and event.key==K_ESCAPE):
spielaktiv = False

# Spiellogik

# Spielfeld löschen
fenster.fill(WEISS)

# Spielfeld/figuren zeichnen

# Fenster aktualisieren
pygame.display.flip()
clock.tick(FPS)

Und was wäre bisher ein Spiel ohne eigene Spielerfigur. Diese folgt im nächsten Kapitel.
© https://www.python-lernen.de/invaders-game-python-spielerfigur.htm Seite 494

Eigene Spielerfigur ins Spiel programmieren


Für ein erfolgreiches Spiel benötigt man einen sympathischen Helden. In unserem Fall mit dem
Thema liegt es nahe, dass wir eine Biene zur heldenhaften furchtlosen Spielerfigur machen.
Unsere eigene Spielfigur soll nun ins Spiel integriert werden – dazu benötigen wir unsere
Kampfbiene als Sprite-Sheet aus dem Kapitel:
https://www.python-lernen.de/animationen-erstellen.htm

Die Grafik kann heruntergeladen werden unter:


https://www.python-lernen.de/bilder/biene-sprite-sheet.png

Die Grafik dann im Ordner „bilder“ im Unterverzeichnis speichern, wo unser Pythonspiel


gespeichert ist.

Nun können wir unsere Spielerfigur im Code integrieren.

spieler = pygame.image.load("bilder/biene-sprite-sheet.png")

Für die Animation benötigen wir noch die einzelnen Bereiche der Bewegung aus dem Sprite-
Sheet:

bereich = ['','','','','','']
bereich[0] = (0,0,100,100)
bereich[1] = (101,0,100,100)
bereich[2] = (202,0,100,100)
bereich[3] = (303,0,100,100)
bereich[4] = (404,0,100,100)
bereich[5] = (505,0,100,100)

Alles das kommt vor der Hauptschleife.

Auch sollten wir eine Variable für den aktuellen Bewegungsframe festlegen, damit wir die
Animation durchlaufen lassen können. Nennen wir die Variable hier animbereich und geben
diesem als Start die 0:

animbereich = 0

Alles das kommt vor der Hauptschleife. Hier der bisher entstandene Code komplett:
© https://www.python-lernen.de/invaders-game-python-spielerfigur.htm Seite 495

# Importieren u. initialisieren der Pygame-Bibliothek


import pygame
from pygame.locals import *
pygame.init()

# Variablen/KONSTANTEN setzen
W, H = 800, 600
FPS = 30
SCHWARZ = ( 0, 0, 0)
WEISS = ( 255, 255, 255)

spielaktiv = True

spieler = pygame.image.load("bilder/biene-sprite-sheet.png")
bereich = ['','','','','','']
bereich[0] = (0,0,100,100)
bereich[1] = (101,0,100,100)
bereich[2] = (202,0,100,100)
bereich[3] = (303,0,100,100)
bereich[4] = (404,0,100,100)
bereich[5] = (505,0,100,100)
animbereich = 0

# Definieren und Öffnen eines neuen Fensters


fenster = pygame.display.set_mode((W, H))
pygame.display.set_caption("Varroa Invaders")
clock = pygame.time.Clock()

# Schleife Hauptprogramm
while spielaktiv = False:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat
for event in pygame.event.get():
# Beenden bei [ESC] oder [X]
if event.type==QUIT or (event.type==KEYDOWN and event.key==K_ESCAPE):
spielaktiv = False

# Spiellogik

# Spielfeld löschen
fenster.fill(WEISS)

# Spielfeld/figuren zeichnen

# Fenster aktualisieren
pygame.display.flip()
clock.tick(FPS)

Jetzt müssen wir unsere Biene zeichnen und die Animation kontinuierlich durchlaufen lassen.
Dies geschieht in der Hauptschleife unseres Spiels:
© https://www.python-lernen.de/invaders-game-python-spielerfigur.htm Seite 496

# Spielfeld/figuren zeichnen
animbereich += 1

if animbereich > 5:
animbereich = 0

fenster.blit(spieler, (100, 300), bereich[animbereich ])


© https://www.python-lernen.de/invaders-game-python-spieler-steuerung.htm Seite 497

Spielerfigur bewegen – Steuerung über Tastatur


Im Gegensatz zu Space Invaders, das von oben nach unten sich bewegt, kommen unsere
Gegner von rechts und unsere Bewegungsrichtung läuft horizontal. Die Spielerfigur hat als
Bewegungsmöglichkeit hoch und runter.

Wir wollen unsere Spielerfigur nach oben und unten bewegen können. Dazu legen wir eine
weitere Variable fest, in der die aktuelle Position der Spielerfigur hinterlegt ist. Auch diese
Variable kommt vor unsere Hauptschleife:

spielerposY = 300

Jetzt müssen wir die Tastatur abfragen und entsprechend auf einen Tastendruck des Spielers
reagieren. Wer in aller Ausführlichkeit über Tastaturabfragen lesen mag, kann das im Kapitel
https://www.python-lernen.de/pygame-tastatur-abfragen.htm tun.

Für uns ist wichtig, dass wir im Bereich event die entsprechende Abfrage der „Pfeil nach
oben“ bzw. „nach unten“-Taste einbauen:

# Schleife Hauptprogramm
while spielaktiv:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat
for event in pygame.event.get():
# Beenden bei [ESC] oder [X]
if event.type==QUIT:
spielaktiv = False

if event.type == KEYDOWN:
# print("Spieler hat Taste gedrückt")

# Taste für Spieler 1


if event.key == K_UP:
print("Spieler hat Pfeiltaste hoch gedrückt")
elif event.key == K_DOWN:
print("Spieler hat Pfeiltaste runter gedrückt")
elif event.key == K_ESCAPE:
spielaktiv = False

Somit fragen wir die Tasten ab und bekomme ein Feedback in der Konsole. Jetzt soll sich
unsere Spielerfigur auch bewegen. Wir benötigen eine weitere Variable, in der die
Bewegungsrichtung hinterlegt ist: spielerbewegung . Diese müssen wir im Vorfeld bei den
Variablen auf 0 setzen und dann je nach Taste entsprechend ändern:

spielerbewegung = 0

Und bei der Tastaturabfrage wird die Variable entsprechend gesetzt – bei einer Bewegung nach
unten mit „+6“ und nach oben mit „-6“:
© https://www.python-lernen.de/invaders-game-python-spieler-steuerung.htm Seite 498

# Taste für Spieler 1


if event.key == K_UP:
# print("Spieler hat Pfeiltaste hoch gedrückt")
spielerbewegung = -6
elif event.key == K_DOWN:
# print("Spieler hat Pfeiltaste runter gedrückt")
spielerbewegung = 6
elif event.key == K_ESCAPE:
spielaktiv = False

In der Spiellogik wird nun die Bewegung berechnet:

# Spiellogik
if spielerbewegung != 0:
spielerposY += spielerbewegung

Die Berechnung über „+=“ wirkt sich korrekt auf das Ergebnis aus, denn wenn als Wert der
Spielerbewegung eine negative Zahl angeliefert wird, wird diese von der aktuellen
Spielerposition abgezogen.

Damit sich aber unsere Figur überhaupt bewegt, müssen wir bei blit() die entsprechende
Variable auch einsetzen:

fenster.blit(spieler, (100, spielerposY), bereich[animbereich ])

Unser kompletter Code bisher:

# Importieren u. initialisieren der Pygame-Bibliothek


import pygame
from pygame.locals import *
pygame.init()

# Variablen/KONSTANTEN setzen
W, H = 800, 600
FPS = 30
SCHWARZ = ( 0, 0, 0)
WEISS = ( 255, 255, 255)

spielaktiv = True

spieler = pygame.image.load("bilder/biene-sprite-sheet.png")
bereich = ['','','','','','']
bereich[0] = (0,0,100,100)
bereich[1] = (101,0,100,100)
bereich[2] = (202,0,100,100)
bereich[3] = (303,0,100,100)
bereich[4] = (404,0,100,100)
bereich[5] = (505,0,100,100)
animbereich = 0

spielerposY = 300
spielerbewegung = 0

# Definieren und Öffnen eines neuen Fensters


fenster = pygame.display.set_mode((W, H))
© https://www.python-lernen.de/invaders-game-python-spieler-steuerung.htm Seite 499

fenster = pygame.display.set_mode((W, H))


pygame.display.set_caption("Varroa Invaders")
clock = pygame.time.Clock()

# Schleife Hauptprogramm
while spielaktiv:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat
for event in pygame.event.get():
# Beenden bei [ESC] oder [X]
if event.type==QUIT:
spielaktiv = False

if event.type == KEYDOWN:
# print("Spieler hat Taste gedrückt")

# Taste für Spieler 1


if event.key == K_UP:
# print("Spieler hat Pfeiltaste hoch gedrückt")
spielerbewegung = -6
elif event.key == K_DOWN:
# print("Spieler hat Pfeiltaste runter gedrückt")
spielerbewegung = 6
elif event.key == K_ESCAPE:
spielaktiv = False

# Spiellogik
if spielerbewegung != 0:
spielerposY += spielerbewegung

# Spielfeld löschen
fenster.fill(WEISS)

# Spielfeld/figuren zeichnen
animbereich += 1

if animbereich > 5:
animbereich = 0

fenster.blit(spieler, (100, spielerposY), bereich[animbereich ])

# Fenster aktualisieren
pygame.display.flip()
clock.tick(FPS)

Wenn wir die Bewegung stoppen wollen, wenn die Taste nicht mehr gedrückt ist, fragen wir
einfach das „loslassen“ der Taste ab und setzen dann den Wert der Variablen
spielerbewegung auf 0. Man könnte noch zusätzlich abfragen, ob die Pfeil-hoch- bzw.
Pfeil-unten-Taste losgelassen wurde.
© https://www.python-lernen.de/invaders-game-python-spieler-steuerung.htm Seite 500

if event.type == KEYDOWN:
# print("Spieler hat Taste gedrückt")

# Taste für Spieler 1


if event.key == K_UP:
# print("Spieler hat Pfeiltaste hoch gedrückt")
spielerbewegung = -6
elif event.key == K_DOWN:
# print("Spieler hat Pfeiltaste runter gedrückt")
spielerbewegung = 6
elif event.key == K_ESCAPE:
spielaktiv = False

if event.type == KEYUP:
print("Spieler stoppt bewegung")
spielerbewegung = 0

Wir können uns allerdings nicht unendlich in eine Richtung bewegen, sonst sind wir als
Spielerfigur weg vom Fenster (wir haben uns dann in den unsichtbaren Bereich bewegt, was
wenig hilfreich ist). Im folgenden Kapitel begrenzen wir die Bewegungsmöglichkeit.
© https://www.python-lernen.de/invaders-game-python-bewegung-begrenzen.htm Seite 501

Bewegung der Spielerfigur begrenzen - damit nicht „weg


vom Fenster“
Die wunderschöne Redensart „weg vom Fenster“ gibt es schon lange vor Computer und
Fensteranwendungen. Früher zeigten sich Würdenträger hoheitsvoll im Rathaus am Fenster
und winkten deren Untergebenen zu. Ein Todesfall des Würdenträgers erschwerte solche
Aktionen und die Person war somit weg vom Fenster (daher soll die Redensart kommen).

Gerade passiert unserer Spielerfigur auch noch, dass diese sich aus dem bestehenden
Fenster bewegen kann – sprich diese ist dann auch „weg vom Fenster“ was wenig hilfreich
für das Spielgeschehen ist.

Wir können die Spielerfigur aus dem Spielfeld nach oben bzw. nach unten bewegen, wenn wir
zu lange in eine Richtung gehen (im Fall unserer Biene „fliegen“). Suboptimal!

Spielerfigur verschwindet aus Fenster

Also fragen wir die Position ab und alles über 0 geht nicht bzw. alles was Größer ist als die
Fensterhöhe:

# Spiellogik
if spielerbewegung != 0:
spielerposY += spielerbewegung

if spielerposY < 0:
spielerposY = 0
spielerbewegung = 0

if spielerposY > H - 90:


spielerposY = H - 90
spielerbewegung = 0

Für die untere Stoppmarke wird die Höhe des Fensters minus der Höhe der Biene berechnet.
Daher die „- 90“.
© https://www.python-lernen.de/invaders-game-python-gegener-einbauen.htm Seite 502

Gegner einbauen für mehr Spaß im Spiel


Und nun kommt unser Gegner: die blut- und proteinsaugende Varroamilbe. Als Grafik kann
man diese herunterladen unter:
https://www.python-lernen.de/bilder/varroa.png

Wer Spaß hat, kann diese ja noch als Sprite-Sheet animieren.

Unser Gegner wird wie gehabt als Bild integriert:

# Gegner
gegnerBild = pygame.image.load("bilder/varroa.png")
gegnerX = W - 100
gegnerY = 20
gegnerbewegung = 0

Da sich unser Gegner auch in X-Richtung bewegt, benötigen auch dafür eine Variable!

Nun platzieren wir zum Testen den Gegner in der Hauptschleife:

# Spielfeld/figuren zeichnen
animbereich += 1

if animbereich > 5:
animbereich = 0

fenster.blit(spieler, (100, spielerposY), bereich[animbereich])

fenster.blit(gegnerBild, (gegnerX , gegnerY))

Soweit sollte das nun funktionieren. Wir erhalten als Ausgabe unsere Spielfigur und den
ersten Gegner.

Spielerfigur und erster Gegner

Nachdem wir nicht nur einen Gegner haben werden, ist es hilfreich eine Funktion für die
Ausgabe der Gegner zu erstellen. Wir nehmen also die Ausgabe über blit() aus der
Hauptschleife und erstellen eine Funktion:

Vor der Hauptschleife erstellen wir eine Funktion für die Ausgabe des Gegners:

def gegner(x, y):


fenster.blit(gegnerBild, (x, y))

# Schleife Hauptprogramm

Und in der Hauptschleife den Aufruf der Funktion zum Zeichnen des Gegners:
© https://www.python-lernen.de/invaders-game-python-gegener-einbauen.htm Seite 503

# Spielfeld/figuren zeichnen
animbereich += 1

if animbereich > 5:
animbereich = 0

fenster.blit(spieler, (100, spielerposY), bereich[animbereich])

gegner (gegnerX, gegnerY)

Und zum Vergleich der bisher erstellte Code komplett:

# Importieren u. initialisieren der Pygame-Bibliothek


import pygame
from pygame.locals import *
pygame.init()

# Variablen/KONSTANTEN setzen
W, H = 800, 600
FPS = 30
SCHWARZ = ( 0, 0, 0)
WEISS = ( 255, 255, 255)

spielaktiv = True

spieler = pygame.image.load("bilder/biene-sprite-sheet.png")
bereich = ['','','','','','']
bereich[0] = (0,0,100,100)
bereich[1] = (101,0,100,100)
bereich[2] = (202,0,100,100)
bereich[3] = (303,0,100,100)
bereich[4] = (404,0,100,100)
bereich[5] = (505,0,100,100)
animbereich = 0

spielerposY = 300
spielerbewegung = 0

# Gegner
gegnerBild = pygame.image.load("bilder/varroa.png")
gegnerX = W - 100
gegnerY = 20
gegnerbewegung = 0

# Definieren und Öffnen eines neuen Fensters


fenster = pygame.display.set_mode((W, H))
pygame.display.set_caption("Varroa Invaders")
clock = pygame.time.Clock()

def gegner(x, y):


fenster.blit(gegnerBild, (x, y))

# Schleife Hauptprogramm
while spielaktiv:
© https://www.python-lernen.de/invaders-game-python-gegener-einbauen.htm Seite 504

while spielaktiv:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat
for event in pygame.event.get():
# Beenden bei [ESC] oder [X]
if event.type==QUIT:
spielaktiv = False

if event.type == KEYDOWN:
# print("Spieler hat Taste gedrückt")

# Taste für Spieler 1


if event.key == K_UP:
# print("Spieler hat Pfeiltaste hoch gedrückt")
spielerbewegung = -6
elif event.key == K_DOWN:
# print("Spieler hat Pfeiltaste runter gedrückt")
spielerbewegung = 6
elif event.key == K_ESCAPE:
spielaktiv = False

if event.type == KEYUP:
# print("Spieler stoppt bewegung")
spielerbewegung = 0

# Spiellogik
if spielerbewegung != 0:
spielerposY += spielerbewegung

if spielerposY < 0:
spielerposY = 0
spielerbewegung = 0

if spielerposY > H - 90:


spielerposY = H - 90
spielerbewegung = 0

# Spielfeld löschen
fenster.fill(WEISS)

# Spielfeld/figuren zeichnen
animbereich += 1

if animbereich > 5:
animbereich = 0

fenster.blit(spieler, (100, spielerposY), bereich[animbereich])

gegner (gegnerX, gegnerY)

# Fenster aktualisieren
pygame.display.flip()
clock.tick(FPS)
© https://www.python-lernen.de/invaders-game-python-gegener-einbauen.htm Seite 505

zufällige Platzierung des Gegners am Spielstart


Wenn wir nun noch eine zufällige Platzierung des Gegners für den Spielstart erreichen
wollen, müssen wir unser Modul random am Anfang importieren.

# Importieren u. initialisieren der Pygame-Bibliothek


import pygame
from pygame.locals import *
import random

Und nun können wir eine zufällige Position über die Anweisung random.randint()
erreichen. Wir müssen uns nur überlegen, wo der Feind auftauchen soll.

Unsere Festlegungen sind:

auf der rechten Seite des Spielfelds ab der Mitte:

also X >= Spielfeldbreite / 2

und X <= Spielfeldbreite – 50 # soll nicht ganz am Rand platziert sein

Und von der Höhe her:

zwischen Y > 50

und maximal Y <= Spielfeldhöhe – 50

Und das ganze nun als Funktion integriert:

# Gegner
gegnerBild = pygame.image.load("bilder/varroa.png")
# gegnerX = W - 100
gegnerX = random.randint(W/2, W-50)
# gegnerY = 20
gegnerY = random.randint(50, H-50)
© https://www.python-lernen.de/invaders-game-python-gegener-bewegen-lassen.htm Seite 506

Gegner durch Python automatisch bewegen lassen


Ähnlich die unsere Spielerfigur lassen wir den Gegner bewegen (außer dass der nie stillhält).
Erreicht die Gegnerfigur den Rand, springt der Gegner wieder ein Stück näher an den Spieler
und bewegt sich weiter in der der Spalte in die Gegenrichtung.

Die Schnelligkeit der Gegnerbewegung setzen wir für den Level 1 dann auf gegnerbewegung
= 5

Innerhalb der Hauptschleife bekommt der nun seine Bewegung:

gegnerY += gegnerbewegung

Jetzt haben wir das gleiche Thema wie beim Spieler: Der Gegner verschwindet aus dem
sichtbaren Bereich des Fensters. Also auch hier die Abfragen für die Randberührung:

gegnerY += gegnerbewegung

if gegnerY < 10:


gegnerbewegung *= -1

if gegnerY > H - 50:


gegnerbewegung *= -1

Nun bewegt sich der Gegner von oben nach unten und andersherum, sobald der den
Fensterrand erreicht.

Zusätzlich soll er beim Erreichen des Fensterrands noch in die Richtung des Spielers sich
bewegen:

gegnerY += gegnerbewegung

if gegnerY < 10:


gegnerbewegung *= -1
gegnerX -= 30

if gegnerY > H - 50:


gegnerbewegung *= -1
gegnerX -= 30

Soweit so gut. Dies ist eine sehr zufällige Bewegung. Im Original bewegen sich dann alle
Gegner fein säuberlich sortiert in Reihen.

Auch die Geschwindigkeit während des Spiels des Gegners sollten wir ja nach Level
entsprechend erhöhen und die Schwierigkeit des Spiels in den höheren Leveln zu steigern.
© https://www.python-lernen.de/invaders-game-python-gegner-abschiessen.htm Seite 507

Gegner abschießen mit Honigtropfen


Jetzt wollen wir von unserer Spielerfigur aus ein Geschoss abschießen können. Dazu müssen
wir immer von rechts und der Mitte unserer Spielfigur von der aktuellen Position der Spielfigur
„absenden“.

Zum Schießen nutzen wir die Leertaste (und einen Honigtropfen):

Das Bild kann über folgende URL heruntergeladen werden:


https://www.python-lernen.de/bilder/honigtropfen.png

Auch dieses Bild binden wir wie gehabt ein:

Da man nicht mit Lebensmittel spielt, nennen wir es „kugel“.

# Kugel
kugel = pygame.image.load("bilder/honigtropfen.png")

Und wir setzen gleich alle benötigten Variablen für unser Geschoss:

# Kugel
kugel = pygame.image.load("bilder/honigtropfen.png")
kugelX = 0
kugelY = 0
kugelXbewegung = 12

Und jetzt wir unsere Kugel nur in Aktion kommen, wenn der Spieler diese abfeuert. Also
brauchen wir den aktuellen Status der Kugel, der für den Anfang „False“ ist:

kugelstatus = False

Diesen Status ändern wir, sobald der Spieler die Leertaste drückt. Zusätzlich geben wir der
Kugel die X und Y-Position mit, die abhängig ist von der Spielerfigur. Wir brauchen zur Y-
Position noch eine Addition von 50, damit die Kugel ungefähr beim Kopf der Biene startet.

# Taste für Spieler 1


if event.key == K_UP:
# print("Spieler hat Pfeiltaste hoch gedrückt")
spielerbewegung = -6
elif event.key == K_DOWN:
# print("Spieler hat Pfeiltaste runter gedrückt")
spielerbewegung = 6
elif event.key == K_ESCAPE:
spielaktiv = False

elif event.key == K_SPACE:


# print("Kugel abfeuern")
kugelstatus = True
kugelX = 200
kugelY = spielerposY+50

Und nun kommen wir zum Teil, dass die Kugel gezeichnet wird und sich bewegt. Für das
zeichnen erstellen wir eine Funktion ähnlich wir für unseren Gegner:
© https://www.python-lernen.de/invaders-game-python-gegner-abschiessen.htm Seite 508

def kugelfliegt(x, y):


fenster.blit(kugelBild, (x, y))

Und diese Funktion wird in der Hauptschleife aufgerufen im Bereich „# Spielfeld/figuren


zeichnen“.

Der Aufruf erfolgt nur, wenn der Status der Kugel auf „True“ gesetzt ist:

# Spielfeld/figuren zeichnen
animbereich += 1

if animbereich > 5:
animbereich = 0

fenster.blit(spieler, (100, spielerposY), bereich[animbereich])

if kugelstatus == True:
kugelfliegt(kugelX,kugelY)

Nun wird unsere Kugel angezeigt, wenn die Leertaste gedrückt wird:

unsere Kugel taucht auf dem Spielfeld auf

Sobald also der Status der Kugel „True“ ist, darf diese auch losfliegen. Dazu erweitern wir
unseren Bereich „# Spiellogik“

if kugelstatus == True:
kugelX += kugelXbewegung

Allerdings gilt auch bei der Kugel: wenn diese trifft (soweit sind wir noch nicht) oder das
Spielfenster verlässt, dann müssen wir reagieren. Also erst einmal, wenn die Kugel das Fenster
verlässt (was wir nur überprüfen müssen, wenn die Kugel aktiv ist):

if kugelstatus == True:
kugelX += kugelXbewegung

if kugelX > W:
kugelstatus = False

Jetzt kommt noch die Besonderheit – es darf keine neue Kugel abgeschossen werden, solange
eine noch im Spiel sich befindet! Sonst wäre es ja zu einfach. Wir erweitern unsere Abfrage von
der Leertaste.

elif event.key == K_SPACE:


# print("Kugel abfeuern")
# nur möglich, wenn keine Kugel sichtbar ist
if kugelstatus == False:
kugelstatus = True
kugelX = 200
kugelY = spielerposY+50
© https://www.python-lernen.de/invaders-game-python-gegner-abschiessen.htm Seite 509


© https://www.python-lernen.de/invaders-game-python-collision-detection-geschoss-gegner.htm Seite 510

Gegner abschießen – Berechnung, wann Geschoss trifft


Jetzt wollen wir auch eine Aktion haben, wenn die Kugel den Gegner trifft. Dazu benötigen wir
eine „Collision Detection“ – sprich eine Kontrolle, ob ein Zusammenstoß vorliegt zwischen
Kugel und Gegner.

Jetzt kommt eine kleine Portion Mathe ins Spiel – endlich kann man auch mal Schulwissen
ergiebig umsetzen. Das Zauberwort bei dem Abstand zwischen zwei Punkten im kartesischen
Koordinatensystem basiert auf den Satz des Pythagoras. Damit kann man sich die folgende
Formel herleiten, um die Berechnung des Abstands zweier Punkte durchzuführen. Lange her?
Egal – wenn man die Formel sieht, darf man nicht erschrecken:

Formel für die Berechnung des Abstands zweier Punkte

Also wenden wir diese Formel für die Berechnung des Abstands zweier Punkte einfach an.

Grundsätzlich benötigen wir nun auch das Python-Modul „math“, das wir am Anfang unseres
Python-Programms importieren:

# Importieren u. initialisieren der Pygame-Bibliothek


import pygame
from pygame.locals import *
import random
import math

Dazu Erstellen wir eine neue Funktion in Python mit dem Namen „kollisionskontrolle()“.

In dieser Funktion benötigen wir für die Berechnung die Position unserer Kugel (X wie Y) wie
auch die Position unseres Gegners (X wie Y):

def kollisionskontrolle(kugelX, kugelY, gegnerX, gegnerY):


abstand = math.sqrt(math.pow(kugelX-gegnerX,2) + math.pow(kugelY-gegnerY,2))
print("Abstand zwichen Kugel und Gegner: ", abstand)

Wir lassen uns in der Konsole nun auch die Werte für den Abstand zwischen Kugel und Gegner
ausgeben. Hier sieht man schön den Abstand (mit zig Nachkommastellen). Das ist deutlich zu
viel der Genauigkeit. Also lassen wir uns einfach Ganzzahlen über int() zurückliefern.

def kollisionskontrolle(kugelX, kugelY, gegnerX, gegnerY):


abstand = int( math.sqrt(math.pow(kugelX-gegnerX,2) + math.pow(kugelY-gegnerY,2)
print("Abstand zwischen Kugel und Gegner: ", abstand)

Und jetzt können wir einfach festlegen, wenn die Kugel trifft. Wir lassen uns von der Funktion
„True“ zurückliefern, wenn die Distanz unter 25 liegt und „False“, wenn die Kugel weiter vorbei
geht.
© https://www.python-lernen.de/invaders-game-python-collision-detection-geschoss-gegner.htm Seite 511

def kollisionskontrolle(kugelX, kugelY, gegnerX, gegnerY):


abstand = int( math.sqrt(math.pow(kugelX-gegnerX,2) + math.pow(kugelY-gegnerY,2)
# print("Abstand zwischen Kugel und Gegner: ", abstand)

if abstand < 25:


return True
else:
return False

Wenn man genau hinsieht, merkt man, dass die Kugel auch oberhalb trifft aber nicht die
komplette Gegnerfigur am unteren Bereich. Diese Ungenauigkeit kommt daher, dass wir für die
Berechnung die Punkt 0,0 von den Grafiken nehmen. Aber unsere Kugel ist 19 hoch und der
Gegner hat eine Höhe von 50. Wenn wir also eine Y-Korrektur von 25 vornehmen, dass sollte
das Treffen deutlich besser passen – zusätzlich noch eine Korrektur bei X um 30 (was der
Kugelbreite entspricht):

def kollisionskontrolle(kugelX-30, kugelY+25, gegnerX, gegnerY):

Und können nun können wir auf einen Treffer entsprechend reagieren:

if kugelstatus == True:
kugelX += kugelXbewegung

if kollisionskontrolle(kugelX,kugelY,gegnerX, gegnerY) == True:


# Kugel hat getroffen
print("Kugel hat getroffen")
kugelstatus = False

if kugelX > W:
kugelstatus = False

Natürlich wollen wir auch Siegpunkte für einen Treffer. Also führen wir eine Variable für die
Siegpunkte mit dem aussagekräftigen Namen „siegpunkte“ ein und bei jedem Treffer wird
diese um 1 erhöht und in der Konsole ausgeben.

if kollisionskontrolle(kugelX,kugelY,gegnerX, gegnerY) == True:


# Kugel hat getroffen
# print("Kugel hat getroffen")
siegpunkte += 1
print("aktueller Stand der Siegpunkte: ", siegpunkte)
kugelstatus = False

Testen

Hier der bisherige Code komplett:

# Importieren u. initialisieren der Pygame-Bibliothek


import pygame
from pygame.locals import *
import random
import math
pygame.init()

# Variablen/KONSTANTEN setzen
W, H = 800, 600
© https://www.python-lernen.de/invaders-game-python-collision-detection-geschoss-gegner.htm Seite 512

FPS = 30
SCHWARZ = ( 0, 0, 0)
WEISS = ( 255, 255, 255)

spielaktiv = True

spieler = pygame.image.load("bilder/biene-sprite-sheet.png")
bereich = ['','','','','','']
bereich[0] = (0,0,100,100)
bereich[1] = (101,0,100,100)
bereich[2] = (202,0,100,100)
bereich[3] = (303,0,100,100)
bereich[4] = (404,0,100,100)
bereich[5] = (505,0,100,100)
animbereich = 0

spielerposY = 300
spielerbewegung = 0

# Gegner
gegnerBild = pygame.image.load("bilder/varroa.png")
# gegnerX = W - 100
gegnerX = random.randint(W/2, W-50)
# gegnerY = 20
gegnerY = random.randint(50, H-50)
gegnerbewegung = 5

# Kugel
kugelBild = pygame.image.load("bilder/honigtropfen.png")
kugelX = 0
kugelY = 0
kugelXbewegung = 12
kugelstatus = False

siegpunkte = 0

# Definieren und Öffnen eines neuen Fensters


fenster = pygame.display.set_mode((W, H))
pygame.display.set_caption("Varroa Invaders")
clock = pygame.time.Clock()

def gegner(x, y):


fenster.blit(gegnerBild, (x, y))

def kugelfliegt(x, y):


fenster.blit(kugelBild, (x, y))

def kollisionskontrolle(kugelX, kugelY, gegnerX, gegnerY):


abstand = int( math.sqrt(math.pow(kugelX-gegnerX,2) + math.pow(kugelY-gegnerY,2)
# print("Abstand zwichen Kugel und Gegner: ", abstand)

if abstand < 25:


return True
© https://www.python-lernen.de/invaders-game-python-collision-detection-geschoss-gegner.htm Seite 513

return True
else:
return False

# Schleife Hauptprogramm
while spielaktiv:
# Überprüfen, ob Nutzer eine Aktion durchgeführt hat
for event in pygame.event.get():
# Beenden bei [ESC] oder [X]
if event.type==QUIT:
spielaktiv = False

if event.type == KEYDOWN:
# print("Spieler hat Taste gedrückt")

# Taste für Spieler 1


if event.key == K_UP:
# print("Spieler hat Pfeiltaste hoch gedrückt")
spielerbewegung = -6
elif event.key == K_DOWN:
# print("Spieler hat Pfeiltaste runter gedrückt")
spielerbewegung = 6
elif event.key == K_ESCAPE:
spielaktiv = False

elif event.key == K_SPACE:


# print("Kugel abfeuern")
# nur möglich, wenn keine Kugel sichtbar ist
if kugelstatus == False:
kugelstatus = True
kugelX = 200
kugelY = spielerposY+50

if event.type == KEYUP:
# print("Spieler stoppt bewegung")
spielerbewegung = 0

# Spiellogik
if spielerbewegung != 0:
spielerposY += spielerbewegung

if spielerposY < 0:
spielerposY = 0
spielerbewegung = 0

if spielerposY > H - 90:


spielerposY = H - 90
spielerbewegung = 0

gegnerY += gegnerbewegung

if gegnerY < 10:


gegnerbewegung *= -1
© https://www.python-lernen.de/invaders-game-python-collision-detection-geschoss-gegner.htm Seite 514

gegnerX -= 30

if gegnerY > H - 50:


gegnerbewegung *= -1
gegnerX -= 30

if kugelstatus == True:
kugelX += kugelXbewegung

if kollisionskontrolle(kugelX,kugelY,gegnerX, gegnerY) == True:


# Kugel hat getroffen
# print("Kugel hat getroffen")
siegpunkte += 1
print("aktueller Stand der Siegpunkte: ", siegpunkte)
kugelstatus = False

if kugelX > W:
kugelstatus = False

# Spielfeld löschen
fenster.fill(WEISS)

# Spielfeld/figuren zeichnen
animbereich += 1

if animbereich > 5:
animbereich = 0

fenster.blit(spieler, (100, spielerposY), bereich[animbereich])

if kugelstatus == True:
kugelfliegt(kugelX,kugelY)

gegner(gegnerX, gegnerY)

# Fenster aktualisieren
pygame.display.flip()
clock.tick(FPS)

Wenn wir jetzt den einzigen Gegner killen, wäre das Spiel sofort aus. Also brauchen wir
dringend mehr Gegner. Im nächsten Kapitel erzeugen wir jede Menge Gegner getreu dem
Motto: „viel Gegner, viel Ehr“.
© https://www.python-lernen.de/invaders-game-python-viele-gegner.htm Seite 515

viele Gegner fürs Spiel


Um jetzt aus unserem bisher einen Gegner mehr zu machen, müssen wir uns überlegen in
welchem Element wir diese speichern. Unter Python bietet sich dafür Listen an. Also bauen wir
unseren bisherigen Bereich für den Gegner um zu viele Gegner gespeichert in Listen.

Für den Start nehmen wir 5 Gegner.

Wie erstellen eine Liste:

# Gegner
# gegnerBild = pygame.image.load("bilder/varroa.png")
# gegnerX = random.randint(W/2, W-50)
# gegnerY = random.randint(50, H-50)
# gegnerbewegung = 5

gegnerBild = []
gegnerX = []
gegnerY = []
gegnerbewegung = []

Wir legen die Zahl der Gegner in einer Variablen fest:

anzahlgegner = 5

Über eine for -Schleife lassen wir nun unsere Gegner als Liste erstellen:

for x in range(anzahlgegner):
gegnerBild.append(pygame.image.load("bilder/varroa.png"))
gegnerX.append(random.randint(W/2, W-50))
gegnerY.append(random.randint(50, H-50))
gegnerbewegung.append(5)

Ab jetzt müssen wir bei jeder Aktion, die wir für einen Gegner machen (egal ob bewegen oder
Kontrolle auf Treffer), für alle unsere Gegner durchführen.

Gehen wir unser bestehendes Programm durch und ändern die entsprechenden Stellen:

Aus dem Code für einen Gegner:

gegnerY += gegnerbewegung

if gegnerY < 10:


gegnerbewegung *= -1
gegnerX -= 30

if gegnerY > H - 50:


gegnerbewegung *= -1
gegnerX -= 30

Wird nun folgender Code für unsere Gegner, die aus der Liste kommen. Da nach einem Treffer
die Anzahl der Gegner sich ändert, lassen wir uns die Anzahl der Einträge die Liste über
len() jeweils berechnen:
© https://www.python-lernen.de/invaders-game-python-viele-gegner.htm Seite 516

for x in range(len(gegnerBild)):
gegnerY[x] += gegnerbewegung[x]

if gegnerY[x] < 10:


gegnerbewegung[x] *= -1
gegnerX[x] -= 30

if gegnerY[x] > H - 50:


gegnerbewegung[x] *= -1
gegnerX[x] -= 30

Und zum Überprüfen auf einen Treffer:

if kugelstatus == True:
kugelX += kugelXbewegung

for x in gegnerBild:
if kollisionskontrolle(kugelX,kugelY,gegnerX[x], gegnerY[x]) == True:

Und beim Zeichnen der Gegner:

for x in range(len(gegnerBild)):
gegner(gegnerX[x], gegnerY[x])

Wobei wir die Funktion erweitern über die Nummer des Gegners:

def gegner(nr, x, y):


fenster.blit(gegnerBild[nr], (x, y))

Was nun auch im Aufruf beachtet werden muss:

for x in range(len(gegnerBild)):
gegner(x, gegnerX[x], gegnerY[x])

Und wenn sich kein Tippfehler eingeschlichen hat, wuselt es auf dem Bildschirm:

durch viele Gegner wuselt es auf dem Bildschirm

Jetzt soll auch bei einem Treffer der entsprechende Gegner verschwinden. Getroffen ist
schließlich getroffen!

Dazu löschen wir aus unserer Liste den entsprechenden Gegner:


© https://www.python-lernen.de/invaders-game-python-viele-gegner.htm Seite 517

for x in gegnerBild:
if kollisionskontrolle(kugelX,kugelY,gegnerX[x], gegnerY[x]) == True:
# Kugel hat getroffen
# print("Kugel hat getroffen")
siegpunkte += 1
print("aktueller Stand der Siegpunkte: ", siegpunkte)
kugelstatus = False

# Gegner Nr. x löschen


del gegnerBild[x]
del gegnerX[x]
del gegnerY[x]
del gegnerbewegung[x]

Allerdings stürzt nun unser Programm bei einem Treffer ab. Was passiert da. Wir löschen ein
Element aus unserer Liste und versuchen die alte Anzahl von Listenelementen durchzugehen.

Unsere Variable mit x enthält nicht das, was wir glauben, dass diese enthält. Eine Liste wird
nach dem löschen automatisch mit einem neuen Index versehen.

Und hier kommt dann gezieltes debuggen zum Einsatz. Wir wollen unser Programm vor dem
Crash anhalten.

Wir wissen, dass es ein Problem nach dem Treffer und löschen im Index gibt. Also geben wir
da unserem Programm ein exit() mit und starten das Programm mit dem Paramater -i

python3 -i varroa-invaders.py

Jetzt kommt man sehr schnell darauf, dass wir unsere x so nicht verwenden können. Wir
basteln uns eine Hilfvariable mit dem Namen durchgang , die wir bei 0 starten und bei jedem
Durchgang erhöhen.

Findet ein Treffer statt, dann können wir den Listeneintrag mit der Nummer von „durchgang“
löschen.

durchgang = 0
for x in gegnerBild:
if kollisionskontrolle(kugelX-30,kugelY-25,gegnerX[durchgang], gegnerY[durchga
# Kugel hat getroffen
# print("Kugel hat getroffen")
siegpunkte += 1
print("aktueller Stand der Siegpunkte: ", siegpunkte)
kugelstatus = False

del gegnerNr[durchgang]
del gegnerBild[durchgang]
del gegnerX[durchgang]
del gegnerY[durchgang]
del gegnerbewegung[durchgang]

durchgang += 1
© https://www.python-lernen.de/invaders-game-python-viele-gegner.htm Seite 518
© https://www.python-lernen.de/invaders-game-python-spiel-gewonnen.htm Seite 519

Kontrolle: Spiel gewonnen


Vor Aktualisieren des Fensters können wir kontrollieren, ob wir das Spiel gewonnen haben.
Wenn es keine Gegner mehr gibt (was wir an dem Eintrag in der Liste der Gegner sehen), haben
wir das Spiel gewonnen.

# Kontrolle auf gewonnen!


if len(gegnerNr) == 0:
print("Gewonnen!")
spielaktiv = False

# Spielfeld löschen

Hier sollte noch eine schöne Ausgabe erfolgen.

Aber davor sollte noch unsere aktuelle Punktezahl eingeblendet werden.


© https://www.python-lernen.de/invaders-game-python-punktestand-anzeigen.htm Seite 520

aktueller Punktestand anzeigen


Als erstes müssen wir die verwendete Schrift definieren. Gibt man bei font.font() „None“
an, wird die Systemschrift verwendet. Die zweite Zahl ist die Schriftgröße:

# Definieren und Öffnen eines neuen Fensters


fenster = pygame.display.set_mode((W, H))
pygame.display.set_caption("Varroa Invaders")
clock = pygame.time.Clock()

# für Textausgabe
font = pygame.font.Font(None, 36)

Und nun können wir die Punkte ausgeben, nachdem wir den Bildschirm gelöscht haben:

# Spielfeld löschen
fenster.fill(WEISS)

# Siegpunkte ausgeben
inhalt = "Punkte: {}".format(siegpunkte)
text = font.render(inhalt, 1, SCHWARZ)
fenster.blit(text, (20,20))
© https://www.python-lernen.de/invaders-game-python-sound-integrieren.htm Seite 521

Hintergrundmusik und Sounds einbauen


Hintergrundmusik aktivieren

# für Textausgabe
font = pygame.font.Font(None, 36)

# Musik/Soundeffekte einrichten
pygame.mixer.music.load('sound/bienensummen.mp3')
pygame.mixer.music.play(-1,0.0)
pygame.mixer.music.set_volume(.4)

Und schon läuft das im Hintergrund

Sounddatei für Treffer in Pygame anlegen:

getroffen = pygame.mixer.Sound('sound/treffer.wav')

Gegner getroffen

if kollisionskontrolle(kugelX-30,kugelY-25,gegnerX[durchgang], gegnerY[durchga
# Kugel hat getroffen
# print("Kugel hat getroffen")
pygame.mixer.Sound.play(getroffen)
© https://www.python-lernen.de/raspberry-pi-python-interpreter.htm Seite 522

Raspberry Pi – der Einplatinencomputer zum Python


programmieren
Mit dem Raspberry Pi steht ein sehr günstiger und kleiner Computer in verschiedenen Größen
zur Verfügung. Durch die Schnittstellen können verschiedenste Sensoren angesprochen
werden und somit können Bastelprojekte sehr einfach umgesetzt werden.

Die Benennung des Einplatinencomputer steht in der Tradition, Computern mit Früchtenamen
zu versehen wie z.B. „apple“. Wobei die Aussprache auf den englischen Kuchen („Pie“) abzielt –
es handelt sich also um einen Himbeerkuchen. Ursprünglich wurde geplant, Python fest
eingebaut werden. Daher auch das Kürzel „Pi“, was für „Python Interpreter“ steht.
© https://www.python-lernen.de/impressum.php Seite 523

Kontakt/Impressum
Impressum gemäß §6 Teledienstegesetz (TDG)
Verantwortlicher Redakteur und Webmaster für die Planung, Realisierung und Betreuung der
Internetinhalte sowie für die Administration der Domains www.python-lernen.de und
www.pythonlernen.de (Admin-c) ist:

Axel Pratzner
Albblickweg 9
73560 Böbingen
E-Mail kontakt python-lernen.de
Internet: https://www.python-lernen.de/
Tel. 0 71 73-9 14 66 2 + eine weitere Nummer - aber erst weiterlesen! Bitte keine Anrufe! Ich bin
gesetzlich verpflichtet, hier eine Nummer anzugeben. Ich biete keine telefonische Beratung,
daher bitte bei Kontaktaufnahme die E-Mail-Adresse nutzen - und die 9 ist die letzte Nummer
zur kompletten Telefonnummer. Danke für die Berücksichtigung.

https://www.python-lernen.de

Das Projekt verfolgt keine kommerziellen Interessen, sondern dient als Kursunterlagen zu
meinen Kursen. Falls Sie Fragen, Kritik oder Anregungen zu diesem Internetprojekt haben, dann
senden Sie einfach eine E-Mail.

Bildquellen
Verwendete Bilder (sofern nicht anders gekennzeichnet) stammen aus dem eigenen Fundus.
Eine Nutzung meiner Bilder zu kommerziellen Zwecken und Veröffentlichung auf anderen
Internetseiten und Medien ist untersagt, sofern ich nicht zugestimmt habe. Eine Nutzung in
Schulbüchern und im Schulunterricht ist ausdrücklich erlaubt bei Namensnennung und der
Nennung der URL der Website - bei Veröffentlichungen mir bitte Bescheid geben.