Powerpointpräsentation

Werbung
Python
-
Konzepte imperativer Programmierung
Klaus Becker
2009
2
Python
3
Teil 0
Vorbemerkungen zu Python
4
Entwicklungsgeschichte
Die Sprache wurde Anfang der 1990er Jahre von Guido van
Rossum am Centrum voor Wiskunde en Informatica (Zentrum
für Mathematik und Informatik) in Amsterdam als Nachfolger
für die Programmier-Lehrsprache ABC entwickelt, ursprünglich
für das verteilte Betriebssystem Amoeba. Alle bisherigen
Implementierungen der Sprache übersetzen den Text eines
Python-Programms transparent in einen Zwischencode, der
dann von einem Interpreter ausgeführt wird.
Der Name geht nicht etwa (wie das Logo vermuten ließe) auf
die gleichnamige Schlangengattung Pythons zurück, sondern
bezog sich ursprünglich auf die englische Komikertruppe
Monty Python. In der Dokumentation finden sich daher auch
einige Anspielungen auf Sketche aus dem Flying Circus.
Trotzdem etablierte sich die Assoziation zur Schlange, was
sich u. a. in der Programmiersprache Cobra sowie dem
Python Toolkit „Boa“ äußert.
Quelle: Wikipedia
5
Ziele
Python wurde mit dem Ziel entworfen, möglichst einfach und übersichtlich zu sein. Dies soll
durch zwei Maßnahmen erreicht werden: Zum einen kommt die Sprache mit relativ wenigen
Schlüsselwörtern aus, zum anderen ist die Syntax reduziert und auf Übersichtlichkeit optimiert.
Dies führt dazu, dass Python eine Sprache ist, in der man schnell, einfach und leicht
programmieren kann. Sie ist daher besonders dort geeignet, wo Übersichtlichkeit und
Lesbarkeit des Codes eine herausragende Rolle spielen – z. B. in der Teamarbeit, bei
Beschäftigung mit dem Quelltext nach längeren Pausen oder bei Programmieranfängern.
Durch die Möglichkeit, auch Programme anderer Sprachen als Modul einzubetten, werden viele
Nischen in der Programmierung abgedeckt. Bei Bedarf lassen sich so beispielsweise
zeitkritische Teile durch maschinennah in C programmierte Routinen ersetzen, oder Python
kann als Skriptsprache eines anderen Programms dienen (Beispiele: OpenOffice.org, Blender,
Maya, PyMOL, SPSS und GIMP).
Python ist eine Multiparadigmensprache. Das heißt, es zwingt den Programmierer nicht zu
einem einzigen bestimmten Programmierparadigma, sondern erlaubt es, das für die jeweilige
Aufgabe am besten geeignete Paradigma zu wählen. Objektorientierte und strukturierte
Programmierung werden vollständig unterstützt, weiterhin gibt es Spracheigenschaften für
funktionale und aspektorientierte Programmierung.
Quelle: Wikipedia
6
Philosophie von Python
# Schön ist besser als hässlich.
# Explizit ist besser als implizit.
# Einfach ist besser als kompliziert.
# Kompliziert ist besser als undurchschaubar.
# Flach ist besser als verschachtelt.
# Spärlich ist besser als beschränkt.
# Lesbarkeit zählt.
# Spezialfälle sind nicht spezial genug, als dass sie die Regeln sprengen dürften.
# Fehler sollten nie schweigend verlaufen.
# Außer man hat sie explizit zum Schweigen gebracht.
# Es sollten einen --- und bevorzugt genau einen --- offensichtlichen Weg geben, es zu tun.
# Wenn die Implementierung schwer zu erklären ist, ist es eine schlechte Idee.
# Wenn die Implementierung einfach zu erklären ist, könnte es eine gute Idee sein.
# ...
Quelle: http://www.python-kurs.eu/index.php
Interne Abläufe
7
Der Quelltext eines Python Programms wird mit einem
Texteditor geschrieben (z.B. Idle oder Pyscripter).
Compiler
Interpreter
Der Python-Compiler erzeugt einen
(maschinenunabhängigen) Byte-Code.
Der Compiler entscheidet selbst, ob der Byte-Code nur als
Zwischenprodukt im Arbeitsspeicher erzeugt wird, oder ob
er auch als .pyc-Datei gespeichert wird.
Der Python-Interpreter führt den vom Compiler erzeugten
Byte-Code aus. Derselbe Byte-Code kann auf verschiedenen
Plattformen ausgeführt werden, sofern diese einen PythonInterpreter zur Verfügung stellen.
8
Gängige Python-Versionen
http://www.python.org/download/
http://portablepython.com/releases/
9
Entwicklungsumgebung Idle
10
Entwicklungsumgebung PyScripter
11
Literatur
Bücher:
 Johannes Ernesti, Peter Kaiser: Python 3. Das umfassende Handbuch.
Galileo Computing 2009. (Preis: 40 €)
 Michael Weigend: Objektorientierte Programmierung mit Python. mitp
2008. (Preis: 40 €)
 Michael Weigend: Python Ge-Packt. mitp 2006. (Preis: 16 €)
 Thomas Theis: Einstieg in Python 3. Galileo Computing 2009. (Preis: 25 €)
 Gregor Lingl: Python für Kids. bhv 2008. (Preis: 20 €)
 ...
12
Materialien
Internet:
 Python Official Website
http://www.python.org/
 Python-Tutorium von Guido van Rossum:
http://starship.python.net/crew/gherman/publications/tut-de/tut-de-21.pdf
http://starship.python.net/crew/gherman/publications/tut-de/online/tut/
 offenes eBook von von Peter Kaiser und Johannes Ernesti (Python 2.5):
http://openbook.galileocomputing.de/python/?GalileoSession=10541258A3Vg6VBUX8A
 PythonWiki:
http://wiki.python.de/
 Python-Kurs von W.Spiegel:
http://www.wspiegel.de/pykurs/pykurs.htm
 Python, Programmieren macht Spaß :
http://www.thomas-guettler.de/vortraege/python/einfuehrung.html
 BICS:
http://schule.de/bics/inf2/programmiersprachen/python/
 Unterrichtsmaterialien von Klaus Merkert:
http://www.hsg-kl.de/faecher/inf/python/index.php
 Unterrichtsmaterialien auf
www.inf-schule.de
13
Teil 1
Variablen
14
Mäusepopulation
Modellannahmen:
 Unterteilung in drei Alterklassen:
junge Mäuse, erwachsene Mäuse und alte Mäuse.
 In jedem Schritt erfolgt ein Wechsel der Altersklasse:
Junge Mäuse werden erwachsen, erwachsene werden alt
(und alte Mäuse leider nicht mehr jung).
 Nur ein bestimmter Anteil (siehe Diagramm) erreicht die
nächste Altersstufe.
 Im Diagramm sind zusätzlich die Geburtenraten
eingetragen. Wir gehen davon aus, dass jede erwachsene
Maus (im Durchschnitt) vier junge Mäuse erzeugt und dass
jede alte Maus (im Durchschnitt) zwei junge Mäuse
erzeugt.
Aufgabe
15
Schritt
jung
erwachsen
alt
0
6
9
12
1
60 = 4*9+2*12
3 = 6/2
3 = 9/3
2
3
4
5
>>>
>>>
>>>
>>>
6
>>>
9
>>>
12
>>>
>>>
>>>
>>>
18
>>>
3
>>>
3
>>>
jung = 6
erwachsen = 9
alt = 12
jung
erwachsen
alt
alt = erwachsen // 3
erwachsen = jung // 2
jung = erwachsen*4 + alt*2
jung
erwachsen
alt
Python-Dialog
...
Berechne die Populationswerte (ohne / mit Python).
Ist im gezeigten Python-Dialog
alles ok?.
Was ist eine Variable?
16
Variablen dienen in der Informatik dazu, Daten zu verwalten. Eine Variable ist ein Name, der
mit einer Speicherzelle verknüpft ist. Mit der Variable kann man auf den in der zugehörigen
Speicherzelle abgelegten Datenwert zugreifen.
"Behältersemantik"
Speicherzelle mit
Datenwert
Name
Variablen dienen in der Informatik dazu, Daten zu verwalten. Eine Variable ist ein Name, der
(in der Regel) mit einem Datenobjekt verknüpft ist.
"Zeigersemantik"
Name
Zeiger
Datenobjekt
Variablen dienen in der Informatik dazu, Daten zu verwalten. Eine Variable ist ein Name, der
(in der Regel) mit einem Wert verknüpft ist.
"Wertsemantik"
{jung -> 6; erwachsen -> 9; alt -> 12}
Name
Datenwert
Variablen in Python
17
Variablen dienen in der Informatik dazu, Daten zu verwalten. Eine Variable ist ein Name, der
(in der Regel) mit einem Datenobjekt verknüpft ist.
"Zeigersemantik"
Name
Zeiger
Datenobjekt
Jedes Datenobjekt in Python hat eine
Identitätsnummer, einen Typ und einen Wert.
Die Identitätsnummer ist die Adresse des
Objekts im Speicher. Sie ist also eine Zahl, mit
der man ein Datenobjekt eindeutig
identifizieren kann.
>>> id(2)
505300136
>>> type(2)
<class 'int'>
>>> 2
2
Eine Variable ist ein Name, der (in der Regel)
mit einem Datenobjekt verknüpft ist. Die
Verknüpfung wird durch einen Verweis
(Referenz) auf die Speicheradresse des
Datenobjekts hergestellt.
>>> id(2)
505300136
>>> zahl = 2
>>> id(zahl)
505300136
>>> type(zahl)
<class 'int'>
>>> zahl
2
18
Zuweisungen in Python
Eine Veränderung eines Variablenwerts kann mit Hilfe einer Zuweisung erfolgen.
Erst wird der Wert des Terms (auf der rechten Seite der Zuweisung)
mit Hilfe des aktuellen Variablenzustands ermittelt. Dann wird ein
Datenobjekt mit diesem Wert an die Variable (auf der linken Seite der
Zuweisung) gebunden. Dieses Datenobjekt kann ein bereits
existierendes Datenobjekt sein oder ein neu erzeugtes. Python
entscheidet nach internen Strategien, welche Version günstiger ist. Je
nach Programmablaufsituation können gleiche Zuweisungen durchaus
zu unterschiedlichen Datenobjektkonstellationen führen. Entscheidend
ist nur, dass der Variablen ein Datenobjekt zugeordnet wird, das den
gewünschten Datenwert hat.
Beachte: Auch wenn zwei Variablen
denselben Wert haben, müssen sie
nicht auf dasselbe Datenobjekt
verweisen.
>>> a = 2
>>> id(a)
505300136
>>> b = a
>>> id(b)
505300136
[variable] = [term]
Struktur
Auswertung
>>> a = "Test"
>>> b = "Test"
>>> id(a)
27764768
>>> id(b)
27757280
19
Mehrfachzuweisungen
Python erlaubt Zuweisungen der Gestalt [variablentupel] = [termtupel].
>>> (jung, erwachsen, alt) = (6, 9, 12)
>>> jung
6
>>> erwachsen
9
>>> alt
Variablentupel
Termtupel
12
>>> (jung, erwachsen, alt) = (erwachsen*4+alt*2, jung//2, erwachsen//3)
>>> (jung, erwachsen, alt)
(60, 3, 3)
20
Übungen
Teste interaktiv die folgenden Zuweisungssequenzen mit Hilfe von Python-Dialogen:
a=5
b=9
a=a-b
b=a+b
a=b-a
x=5
y=9
(x, y) = (y, x)
21
Teil 2
Datentypen
22
Python als Taschenrechner
>>> 365 * 17 + 212
6417
>>> (42 - 67) * 21
-525
>>> 14 // 4
3
>>> 14 / 4
3.5
>>> 14 % 4
2
>>> 2.4 * 6.3
15.119999999999999
>>> 2**500
32733906078961418700131
89696827599152216642046
04306478948329136809613
37964046745548832700923
25904157150886684127560
07100921725654588539305
3328527589376
Alles klar?
>>> 1 + 1
2
>>> 1 + 1.0
2.0
>>> 1.0 + 1.0
2.0
>>> "1" + "1"
'11'
>>> 1,0 + 1,0
(1, 1, 0)
>>> (1, 0) + (1, 0)
(1, 0, 1, 0)
>>> 1,0 + 1
(1, 1)
>>> (1, 0) + 1
Traceback (most recent call last):
File ...
TypeError: can only concatenate tuple (not "int") to tuple
>>> 1 + "1"
Traceback (most recent call last):
File ...
TypeError: unsupported operand type(s) for +: 'int' and 'str'
23
Datentyp
Zu verarbeitende Daten können von ganz unterschiedlichem Typ sein, z. B. Zahlen, mit denen
man rechnen kann, oder Zeichenketten, die man hintereinanderhängen kann. Ein Datentyp
beschreibt eine Menge von Datenobjekten, die alle die gleiche Struktur haben und mit denen
die gleichen Operationen ausgeführt werden können.
>>> 1 + 1
>>> type(1)
2
<class 'int'>
>>> 1 + 1.0
>>> type(1.0)
2.0
<class 'float'>
>>> 1.0 + 1.0
>>> type("1")
2.0
<class 'str'>
>>> "1" + "1"
>>> type(1,0)
'11'
Traceback (most recent call last):
>>> 1,0 + 1,0
File ...
(1, 1, 0)
TypeError: type() takes 1 or 3 arguments
>>> (1, 0) + (1, 0)
>>> type((1,0))
(1, 0, 1, 0)
<class 'tuple'>
>>> 1,0 + 1
>>> <type 'tuple'>
(1, 1)
>>> (1, 0) + 1
TypeError: can only concatenate tuple (not "int") to tuple
>>> 1 + "1"
TypeError: unsupported operand type(s) for +: 'int' and 'str'
24
Datentypen in Python
>>> 2
2
Datentyp: ganze Zahl
int
>>> 2.0
2.0
Datentyp: Dezimalzahl
float
>>> True
True
Datentyp: Wahrheitswert
bool
Datentyp: Zeichenkette
string
>>> ('Hans', 'Meier', 34, 'Koblenz')
('Hans', 'Meier', 34, 'Koblenz')
Datentyp: Tupel
tuple
>>> [1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
Datentyp: Liste
list
...
...
>>> 'Hallo!'
'Hallo!'
>>> "Hallo!"
'Hallo!'
25
Numerische Datentypen in Python
Numerische Datentypen sind in Pythen Datentypen, die Rechenoperationen zur Verarbeitung
der Daten vorsehen. Zu diesen Datentypen gehören int, float und auch bool. Beachte, dass
die Wahrheitswerte False und True in vielerlei Hinsicht wie die Zahlen 0 und 1 behandelt
werden.
Für numerische Datentypen sind folgende Rechenoperationen definiert:
Operator
Bedeutung
Rechenausdruck
Ergebnis
+
Addition
1+1
2
-
Subtraktion
4-2
2
*
Multiplikation
3*4
12
//
ganzzahlige Division
14//3
4
%
Rest b. ganzzahliger Division 14%3
2
/
Gleitkommazahldivision
3/4
0.75
**
Potenz
2**3
8
+
positives Vorzeichen
+1
1
-
negatives Vorzeichen
-1
-1
26
Typumwandlungen in Python
Häufig benötigt man Operatoren, mit denen man aus einem Datenobjekt ein entsprechendes
mit einem anderen Datentyp erzeugen kann. Der folgende Python-Dialog zeigt einige
Möglichkeiten auf.
>>> int("3")
3
>>> float("3")
3.0
>>> int(3.0)
3
>>> int(3.5)
3
>>> float(3)
3.0
>>> str(3)
'3'
>>> list("[1, 2, 3]")
['[', '1', ',', ' ', '2', ',', ' ', '3', ']']
>>> eval("[1, 2, 3]")
[1, 2, 3]
27
Teil 3
Programme
Body-Mass-Index
28
Der Body-Mass-Index (kurz: BMI) ist eine Zahl,
mit der man abschätzen kann, ob man Unter-,
Normal oder Übergewicht hat.
Kategorie
Untergewicht
Normalgewicht
Übergewicht
BMI [kg/m2]
bis 18.5
18.5 - 25
ab 25
Beachte aber, dass die hier vorgenommene
Einschätzung umstritten ist, da sie Alter,
Geschlecht, Statur usw. eines Menschen nicht
berücksichtigt.
>>> gewicht = 60.0
>>> groesse = 1.7
>>> bmi = gewicht / (groesse * groesse)
>>> bmi
20.761245674740486
>>>
interaktive Ausführung
Gewicht
BMI = -----------------Größe * Größe
(in kg)
(in m)
# Eingabe
gewicht = float(input("Gewicht in kg: "))
groesse = float(input("Größe in m: "))
# Verarbeitung
bmi = gewicht / (groesse * groesse)
# Ausgabe
print("BMI:", bmi)
Programm in Datei
>>>
Gewicht in kg: 75
Größe in m: 1.80
BMI: 23.1481481481
Programmausführung
29
Programm
Ein (Python-) Programm ist eine Folge von (Python-) Anweisungen und Kommentaren. Der
Programmtext wird auch Quelltext genannt.
 Jede Anweisung wird (in der Regel) im
Quelltext in eine neue Zeile geschrieben.
 Die Verständlichkeit eines Programms wird
durch sogenannte sprechende Bezeichner
deutlich erhöht. Ein sprechende Bezeichner ist
ein Name (z. B. für eine Variable), der die
Bedeutung des bezeichneten Gegenstands
möglichst gut wiedergibt.
 Kommentare dienen dazu, die Bedeutung
von Programmteilen zu erläutern.
Kommentare werden eigentlich nur für die
Menschen ergänzt, die den Quelltext
bearbeiten. Bei der Ausführung von
Programmen werden sie ignoriert.
 In einem Programm dürfen Umlaute oder
andere Sonderzeichen vorkommen, da
standardmäßig eine UTF-8-Kodierung für
Unicode-Zeichen benutzt wird.
# Eingabe
gewicht = float(input("Gewicht in kg: "))
groesse = float(input("Größe in m: "))
# Verarbeitung
bmi = gewicht / (groesse * groesse)
# Ausgabe
print("BMI:", bmi)
Quelltext
EVA-Prinzip
30
Viele Programme lassen sich wie im folgenden Beispiel nach dem EVA-Prinzip strukturieren.
EVA steht hier für Eingabe - Verarbeitung - Ausgabe. Auf einen Eingabeteil folgt ein
Verarbeitungsteil und schließlich ein Ausgabeteil.
Eingabe
Verarbeitung
Ausgabe
# Eingabe
gewicht = float(input("Gewicht in kg: "))
groesse = float(input("Größe in m: "))
# Verarbeitung
bmi = gewicht / (groesse * groesse)
# Ausgabe
print("BMI:", bmi)
Eingaben in Python: Der input-Operator gibt zunächst den Aufforderungstext aus, wartet
dann, bis der Benutzer seine Eingabe mit der Return-Taste abgeschlossen hat und liefert diese
Eingabe als Zeichenkette vom Typ str zurück.
Ausgaben in Pythen: Die print-Anweisung gibt alle übergebenen Werte der Reihe nach (in
einer Zeile) auf dem Bildschirm aus.
31
Übungen
Aufgabe (siehe 1.6.3.7):
Der optimale Puls bei Ausdauersportarten hängt vom Alter ab. Er lässt sich mit der Formel P =
165 - 0.75*A bestimmen. Schreibe ein Programm, das folgenden Dialog ermöglicht:
Alter: 18
optimaler Puls: 151.5
32
Übungen
Aufgabe (siehe 1.6.3.7):
In der Fahrschule lernt man folgende Faustformeln zur Berechnung von Anhaltewegen:
Reaktionsweg (in Metern) = (Geschwindigkeit (in km/h) geteilt durch 10) mal 3
Bremsweg (in Metern) = (Geschwindigkeit (in km/h) geteilt durch 10) mal (Geschwindigkeit
(in km/h) geteilt durch 10)
Anhalteweg (in Metern) = Reaktionsweg plus Bremsweg
Entwickle ein Programm, mit dem man den Anhalteweg für eine beliebige eingegebene
Geschwindigkeit bestimmen kann.
33
Teil 4
Entscheidungen
34
Aufgabe:
Ergänze das bereits
angefangene Programm.
Achte genau auf
Doppelpunkte und
Einrückungen.
# Eingabe
jahr = int(input("Jahr: "))
# Verarbeitung
if jahr % 4 == 0:
if jahr % 100 == 0:
if jahr % 400 == 0:
schaltjahr = True
else:
...
# Ausgabe
if schaltjahr == True:
print(jahr, "ist ein Schaltjahr.")
...
Schaltjahre
35
Fallunterscheidung
Eine Fallunterscheidung dient dazu, alternative Abläufe bzw. Fallunterscheidungen zu
beschreiben.
zweiseitige
Fallunterscheidung
einseitige
Fallunterscheidung
Doppelpunkt
if [Bedingung]:
[Anweisungssequenz]
else:
[Anweisungssequenz]
Schlüsselwort
Einrückung
if konto < 0:
print("Der Kontostand ist negativ!")
print("Bitte die Schulden begleichen!")
else:
print("Alles ok!")
if [Bedingung]:
[Anweisungssequenz]
if konto < 0:
print "Der Kontostand ist negativ!"
print "Du hast Schulden!"
if konto > 0:
print "Der Kontostand ist positiv!"
print "Eine Auszahlung ist möglich!"
36
Mehrfachfallunterscheidung
Eine Fallunterscheidung dient dazu, alternative Abläufe bzw. Fallunterscheidungen zu
beschreiben.
if konto > 0:
print "Der Kontostand ist positiv!"
else:
if konto < 0:
print "Der Kontostand ist negativ!"
else:
print "Der Kontostand ist gleich Null!"
Schlüsselwort
Einrückung
if zahl > 0:
print "Die Zahl ist positiv!"
elif zahl < 0:
print "Die Zahl ist negativ!"
else:
print "Die Zahl ist gleich Null!"
if [Bedingung]:
[Anweisungssequenz]
elif [Bedingung]:
[Anweisungssequenz]
elif [Bedingung]:
[Anweisungssequenz]
...
else:
[Anweisungssequenz]
Doppelpunkt
37
Übungen
Aufgabe:
Der Body-Mass-Index (kurz: BMI) ist eine Zahl, die darüber Auskunft gibt, ob man
Normalgewicht hat. Sie berechnet sich so: Gewicht in kg geteilt durch das Quadrat der
Körpergröße in m!. Wenn man also 1.80 m groß ist und ein Gewicht von 75 kg hat, dann
erhält man einen BMI von etwa 23. Wenn die so berechnete Zahl zwischen 18.5 und 26 liegt,
dann hat man Normalgewicht. Wenn sie kleiner als 18.5 / größer als 26 ist, dann hat man
Untergewicht / Übergewicht.
Ergänze das Programm zur Berechnung des BMI um eine adäquate Rückmeldung.
38
Übungen
Aufgabe (siehe 1.6.4.5):
Mit Hilfe der Variablen a, b und c werden drei Zahlen verwaltet. Mit Hilfe eines Programms soll
entschieden werden, ob die drei Zahlen verschieden sind. Entwickle erst ein geeignetes
Struktogramm und anschließend ein hierzu passendes Programm.
39
Teil 5
Wiederholungen
40
Ein Blick in die Zukunft
# Initialisierung
kapital = float(input("Kapital: "))
zinssatz = float(input("Zinssatz: "))
jahr = 0
# Iterierung
while jahr < 10:
zinsen = kapital * (zinssatz/100)
kapital = kapital + zinsen
jahr = jahr + 1
# Ausgabe
print("Kapital nach 10 Jahren: ", kapital)
"Legen Sie ihr Geld zinsgünstig bei
unserer Bank an. Nach einigen Jahren
können Sie sich dann ihr Traum...
leisten."
2000
1800
1600
1400
1200
1000
800
600
400
200
0
1
3
5
7
9
11
13
15
17
19
Aufgaben:
Ändere das Programm so ab, dass folgende Aufgaben erledigt werden:
 In jedem Berechnungsschritt sollen die aktuell berechneten Werte ausgegeben werden.
 Der Benutzer kann selbst eingeben, wie viele Schritte simuliert werden sollen.
 Der Benutzer kann einen bestimmten Zielbetrag eingeben, bis zu der die Kapitalverzinsung
durchgeführt werden soll. Ausgegeben werden soll, wie viele Jahre hierzu benötigt werden.
21
41
Wiederholung
Eine Wiederholung dient dazu, wiederholte Abläufe zu beschreiben. Sie ist aus einer
Bedingung und einer (eventuell einelementigen) Anweisungssequenz aufgebaut.
Struktur
Semantik
# Initialisierung
kapital = float(input("Kapital: "))
zinssatz = float(input("Zinssatz: "))
jahr = 0
# Iterierung
while jahr < 10:
zinsen = kapital * (zinssatz/100)
kapital = kapital + zinsen
jahr = jahr + 1
# Ausgabe
print("Kapital nach 10 Jahren: ", kapital)
Schlüsselwort
Einrückung
Doppelpunkt
while [Bedingung]:
[Anweisungssequenz]
42
wiederhole ... bis ...
Eine Wiederholung dient dazu, wiederholte Abläufe zu beschreiben. Sie ist aus einer
Bedingung und einer (eventuell einelementigen) Anweisungssequenz aufgebaut.
# Initialisierung
kapital = float(input("Kapital: "))
zinssatz = float(input("Zinssatz: "))
beginn = int(input("Beginn: "))
ende = int(input("Ende: "))
jahr = beginn
# Iterierung
while True:
jahr = jahr + 1
zinsen = kapital * (zinssatz/100)
kapital = kapital + zinsen
if jahr == ende:
break
# Ausgabe
print("Jahr: ", jahr)
print("neues Kapital: ", kapital)
Mit break und continue kann man sehr flexibel Wiederholungen modellieren.
Im Unterricht reicht in der Regel die Solange-Schleife.
for-Anweisung in Python
43
# Initialisierung
kapital = float(input("Kapital: "))
zinssatz = float(input("Zinssatz: Liste
"))
# Iterierung
for jahr in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]:
zinsen = kapital * (zinssatz/100)
kapital = kapital + zinsen
# Ausgabe
print("Kapital nach 10 Jahren: ", kapital)
Schlüsselwort
Einrückung
# Initialisierung
kapital = float(input("Kapital: "))
zinssatz = float(input("Zinssatz:
"))
erzeugt Iterator
# Iterierung
for jahr in range(10):
zinsen = kapital * (zinssatz/100)
kapital = kapital + zinsen
# Ausgabe
print("Kapital nach 10 Jahren: ", kapital)
Doppelpunkt
for [Element] in [iterierbares Objekt]:
[Anweisungssequenz]
for-Anweisung in Python
44
Doppelpunkt
Schlüsselwort
Einrückung
for [Element] in [iterierbares Objekt]:
[Anweisungssequenz]
for element in ["Heute", "ist", "ein", "Mittwoch", "."]:
print(element)
Liste als iterierbares Objekt
for zeichen in "Informatik":
print(zeichen)
Zeichenkette als iterierbares Objekt
for komponente in ("Petra", "Schmidt", 18):
print(komponente)
Tupel als iterierbares Objekt
45
Zählschleifen in Python
for i in range(5):
print(i)
for i in range(2, 5):
print(i)
0
1
2
3
4
2
3
4
for i in range(1, 5, 2):
print(i)
for i in range(5, 1, -1):
print(i)
1
3
5
4
3
2
46
Übungen
Aufgabe (siehe 1.6.4.5):
Was leistet der folgende Algorithmus? Implementiere den Algorithmus in Python und versuche
mit Hilfe von Tests herauszufinden, was er leistet.
# Eingabe
Eingabe: x, y # natürliche Zahlen größer 1
# Verarbeitung
SOLANGE y > 0:
h = x % y # Rest bei der ganzzahligen Division
x=y
y=h
# Ausgabe
Ausgabe: x
Aufgabe:
Entwickle ein Algorithmus / Programm, mit dem man die Anzahl der Teiler einer eingegebenen
natürlichen Zahl bestimmen kann.
47
Übungen
Aufgabe (siehe 1.6.5.5):
Was leisten die folgenden for-Anweisungen? Stell zunächst jeweils eine Vermutung auf. Teste
anschließend, ob die Vermutung stimmt.
for i in [1, 2, 3]:
print("Hallo")
for i in [1, 2, 3]:
print(i*i)
for i in range(3):
print(i)
for i in range(3, 7):
print(i)
for c in ["a", "b", "c"]:
print(c)
48
Teil 6
Bedingungen
49
Würfeln mit dem Computer
from random import randint
# Verarbeitung
w1 = randint(1, 6)
w2 = randint(1, 6)
w3 = randint(1, 6)
versuche = 0
while not ((w1 == w2) and (w1 == w3)):
w1 = randint(1, 6)
w2 = randint(1, 6)
w3 = randint(1, 6)
versuche = versuche + 1
# Ausgabe
print(versuche)
Aufgabe:
Was leisten die Programme?
from random import randint
# Verarbeitung
w1 = randint(1, 6)
w2 = randint(1, 6)
w3 = randint(1, 6)
versuche = 0
while (w1 != w2) or (w1 != w3):
w1 = randint(1, 6)
w2 = randint(1, 6)
w3 = randint(1, 6)
versuche = versuche + 1
# Ausgabe
print(versuche)
Komplexe Bedingungen
50
Eine Bedingung wird aus elementaren Bedingungen und logischen Operatoren aufgebaut.
while (w1 != w2) or (w1 != w3):
...
logischer Operator
el. Bedingung
el. Bedingung
Operator
<
>
<=
>=
==
!=
Bedeutung
kleiner
größer
kleiner oder gleich
größer oder gleich
gleich
ungleich
Bsp.
2<1
4>2
3 <= 3
3 >= 4
4 == 3
2 != 3
Ergebnis
False
True
True
False
False
True
Vergleichsoperatoren
Operator
not
and
or
Bedeutung
nicht
und
oder
Bsp.
not True
True and False
True or False
Ergebnis
False
False
True
logische Operatoren
51
Übungen
Aufgabe (vgl. 1.6.7.5):
Was leistet das folgende Programm. Versuche es erst einmal durch Analyse des Quelltextes
herauszufinden. Überprüfe deine Vermutung, indem du das Programm testest.
genug = False
richtig = True
zahl = 1
while richtig and (not genug):
print("Noch eine Quadratzahl?")
antwort = input("Antwort (j/n): ")
if antwort == "j":
print(zahl, " * ", zahl)
ergebnis = int(input("Ergebnis:"))
if ergebnis != zahl * zahl:
richtig = False
print("falsch!")
else:
print("richtig!")
zahl = zahl + 1
else:
genug = True
52
Übungen
Aufgabe (vgl. 1.6.7.1):
Entwickle ein Programm, mit dem man bestimmen kann, wie viele Versuche man benötigt, bis
man einen 3er-Pasch erhält.
53
Teil 7
Unterprogramme
54
halb so alt
# Initialisierung
datumGeburt = (21, 1, 1992)
datumHeute = (5, 7, 2009)
# Verarbeitung
anzahl = 0
datum = datumGeburt
while datum != datumHeute:
(tag, monat, jahr) = datum
if monat in [1, 3, 5, 7, 8, 10, 12]:
maxtage = 31
elif monat in [4, 6, 9, 11]:
maxtage = 30
elif (jahr % 400 == 0) or \
((jahr % 4 == 0) and not (jahr %
100 == 0)):
maxtage = 29
else:
maxtage = 28
if tag < maxtage:
tag = tag + 1
elif monat < 12:
guter Stil?
...
...
tag = 1
monat = monat + 1
else:
tag = 1
monat = 1
jahr = jahr + 1
datum = (tag, monat, jahr)
anzahl = anzahl + 1
halbeanzahl = anzahl // 2
datum = datumGeburt
zaehler = 0
while zaehler < halbeanzahl:
(tag, monat, jahr) = datum
if monat in [1, 3, 5, 7, 8, 10, 12]:
maxtage = 31
elif monat in [4, 6, 9, 11]:
maxtage = 30
elif (jahr % 400 == 0) or \
((jahr % 4 == 0) and not (jahr %
100 == 0)):
maxtage = 29
...
55
halb so alt
def schaltjahr(jahr):
return (jahr % 400 == 0) or ((jahr % 4 == 0) and not (jahr % 100 == 0))
def anzahlTageImMonat(monat, jahr):
if monat in [1, 3, 5, 7, 8, 10, 12]:
anzahl = 31
elif monat in [4, 6, 9, 11]:
anzahl = 30
elif schaltjahr(jahr):
anzahl = 29
else:
anzahl = 28
return anzahl
def naechstesDatum(datum):
(tag, monat, jahr) = datum
if tag < anzahlTageImMonat(monat, jahr):
tag = tag + 1
elif monat < 12:
tag = 1
monat = monat + 1
else:
tag = 1
monat = 1
jahr = jahr + 1
return (tag, monat, jahr)...
def anzahlTageZwischenDatum(datum1, datum2):
anzahl = 0
datum = datum1
while datum != datum2:
datum = naechstesDatum(datum)
anzahl = anzahl + 1
return anzahl
Unterprogramme
56
halb so alt
def anzahlTageZwischenDatum(datum1, datum2):
anzahl = 0
datum = datum1
while datum != datum2:
datum = naechstesDatum(datum)
anzahl = anzahl + 1
return anzahl
def neuesdatum(datum1, anzahlTage):
anzahl = 0
datum = datum1
while anzahl < anzahlTage:
datum = naechstesDatum(datum)
anzahl = anzahl + 1
return datum
Unterprogramme
datumGeburt = (21, 1, 1992)
datumHeute = (5, 7, 2009)
anzahlTage = anzahlTageZwischenDatum(datumGeburt, datumHeute)
halbeAnzahlTage = anzahlTage // 2
datumHalbzeit = datum(datumGeburt, halbeAnzahlTage)
print(anzahlTage)
print(datumHalbzeit)
Hauptprogramm
57
Unterprogramme
Unterprogramme sind eigenständige Programmeinheiten. Sie werden innerhalb von
Programmen benutzt, um Teilaufgaben zu implementieren.
def anzahlTageZwischenDatum(datum1, datum2):
anzahl = 0
...
return anzahl
def neuesDatum(datum1, anzahlTage):
anzahl = 0
datum = datum1
while anzahl < anzahlTage:
datum = naechstesDatum(datum)
anzahl = anzahl + 1
return datum
Strukturierung des
Quelltextes
Vermeidung von
Codeduplizierung
datumGeburt = (21, 1, 1992)
datumHeute = (5, 7, 2009)
anzahlTage = anzahlTageZwischenDatum(datumGeburt, datumHeute)
halbeAnzahlTage = anzahlTage // 2
datumHalbzeit = datum(datumGeburt, halbeAnzahlTage)
print(anzahlTage)
print(datumHalbzeit)
Funktionen
58
Eine Funktion ist eine Unterprogrammeinheit, die übergebene Daten verarbeitet und den
berechneten Funktionswert als Ergebnis zurückgibt. Die Verarbeitung wird über eine
Funktionsdefinition (man sagt oft auch Funktionsdeklaration) festgelegt. Aktiviert wird eine
Verarbeitung durch einen Funktionsaufruf.
Schlüsselwort
Funktionsname(Parameter)
def anzahlTageImMonat(monat, jahr):
Funktionsdefinition
if monat in [1, 3, 5, 7, 8, 10, 12]:
anzahl = 31
Doppelpunkt
elif monat in [4, 6, 9, 11]:
anzahl = 30
elif schaltjahr(jahr):
anzahl = 29
else:
anzahl = 28
return anzahl
Einrückung
anzahlTageImMonat(2, 2012)
Funktionsaufruf
Parameter
59
Parameter sind Platzhalter, mit deren Hilfe man Daten zur Laufzeit an Funktionen übergeben
kann.
formale Parameter
def anzahlTageImMonat(monat, jahr):
if monat in [1, 3, 5, 7, 8, 10, 12]:
anzahl = 31
elif ....
...
return anzahl
aktuelle Parameter
anzahlTageImMonat(2, 2012)
Funktionsaufruf
Funktionsdefinition
60
Komplexe Rückgaben
Sollen mehrere Daten zurückgegeben werden, so nutzt man eine Datenstruktur (z.B. Tupel),
um eine Dateneinheit zu bilden.
def initialisierungDaten():
datum1 = (21, 1, 1992)
datum2 = (5, 7, 2009)
return (datum1, datum2)
komplexe Rückgabe
def ausgabeDaten(dGeburt, dAktuell, dHalbzeit):
print("Geburtsdatum:", dGeburt)
print("aktuelles Datum:", dAktuell)
print("halb-so-alt-Datum:", dHalbzeit)
# Initialisierung
(datumGeburt, datumHeute) = initialisierungDaten()
# Verarbeitung
anzahlTage = anzahlTageZwischenDatum(datumGeburt, datumHeute)
halbeAnzahlTage = anzahlTage // 2
datumHalbzeit = neuesDatum(datumGeburt, halbeAnzahlTage)
# Ausgabe
ausgabeDaten(datumGeburt, datumHeute, datumHalbzeit)
61
Prozeduren
Eine Prozedur ist eine Verarbeitungseinheit, die kein Ergebnis zurückliefert.
def initialisierungDaten():
datum1 = (21, 1, 1992)
datum2 = (5, 7, 2009)
return (datum1, datum2)
def ausgabeDaten(dGeburt, dAktuell, dHalbzeit):
print("Geburtsdatum:", dGeburt)
print("aktuelles Datum:", dAktuell)
print("halb-so-alt-Datum:", dHalbzeit)
keine Rückgabe
# Initialisierung
(datumGeburt, datumHeute) = initialisierungDaten()
# Verarbeitung
anzahlTage = anzahlTageZwischenDatum(datumGeburt, datumHeute)
halbeAnzahlTage = anzahlTage // 2
datumHalbzeit = neuesDatum(datumGeburt, halbeAnzahlTage)
# Ausgabe
ausgabeDaten(datumGeburt, datumHeute, datumHalbzeit)
62
Übungen
Aufgabe (vgl. 1.6.8.7):
Entwickle eine Funktion mit folgender Eigenschaft:
* Die Funktion bestimmt die ganzzahlige Wurzel zu einer vorgegebenen natürlichen Zahl. Z.
B. gibt sie den Wert 2 zurück, wenn man 5 als Eingabe wählt.
* Die Funktion bestimmt die nächst größere Primzahl zu einer vorgegebenen natürlichen
Zahl. Z. B. gibt sie 7 zurück, wenn man 5 als Eingabe wählt.
Aufgabe (vgl. 1.6.8.7):
Ergänze die Delaration der Funktionen succ
(für Nachfolger einer Zahl), pred (für
Vorgänger einer Zahl) und add (Addition von
zwei Zahlen).
Die Addition der beiden übergebenen
natürlichen Zahlen soll dabei nicht mit dem
vordefinierten Plus-Operator vorgenommen
werden, sondern mit Hilfe der beiden
Hilfsfunktionen succ und pred.
# Unterprogramme
def succ(n):
...
def pred(n):
...
def add(m, n):
...
# Hauptprogramm
zahl1 = int(input("Zahl 1: "))
zahl2 = int(input("Zahl 2: "))
summe = add(zahl1, zahl2)
print("Summe: ", summe)
63
Teil 8
Lokale und globale Variablen
64
Experimente mit Variablen
def d(x):
y=x+x
return y
def d(a):
a=a+a
return a
def d():
b=a+a
return b
# Test
a=2
print(a)
a = d(a)
print(a)
# Test
a=2
print(a)
a = d(a)
print(a)
# Test
a=2
print(a)
a = d()
print(a)
def d():
a=a+a
# Test
a=2
print(a)
d()
print(a)
Das Zusammenspiel von Variablen des Hauptprogramms, von Variablen von
Unterprogrammen und von Parametern ist nicht so einfach. Mit Hilfe von Experimenten sollen
die Zusammenhänge erschlossen werden.
Stell jeweils eine Vermutung auf, was die print-Anweisungen ausgeben. Kannst du die
Ergebnisse erklären?
65
def d(x):
y=x+x
return y
# Test
a=2
print(a)
a = d(a)
print(a)
def d(x):
y=x+x
print(locals())
return y
# Test
a=2
print(a)
print(globals())
a = d(a)
print(a)
Experimente mit Variablen
Erweitere in den oben gezeigten Vorschlägen die Funktionsdefinition
und das Testprogramm jeweils um die Aufrufe print(locals()) bzw.
print(globals()). Was wird hier ausgegeben?
66
Experimente mit Variablen
Wie funktioniert die Parameterübergabe? Kann man es aus den Ausgaben der folgenden
Testprogramme erschließen?
def d(x):
print("x:", x)
print("id(x):", id(x))
y=x+x
print("y:", y)
print("id(y):", id(y))
return y
def d(a):
print("a:", a)
print("id(a):", id(a))
a=a+a
print("a:", a)
print("id(a):", id(a))
return a
# Test
a=2
print("a:", a)
print("id(a):", id(a))
a = d(a)
print("a:", a)
print("id(a):", id(a))
# Test
a=2
print("a:", a)
print("id(a):", id(a))
a = d(a)
print("a:", a)
print("id(a):", id(a))
67
lokale / globale Variable
Eine globale Variable ist (vereinfacht gesagt) eine Variable, die im Hauptprogramm eingeführt
wird. Eine lokale Variable ist (vereinfacht gesagt) eine Variable, die nur innerhalb eines
Unterprogramms benutzt wird. Beachte, dass die (formalen) Parameter eines
Unterprogramms auch zu diesen lokalen Variablen zählen.
def d(x):
y=x+x
print(locals())
return y
# Test
a=2
print(a)
print(globals())
a = d(a)
print(a)
>>>
2
{'a': 2, ...}
{'y': 4, 'x': 2}
4
a=2
{a -> 2}
-------------------------d(a)
{a -> 2, {x -> 2}}
y=x+x
{a -> 2, {x -> 2, y -> 4}}
return y
4
-------------------------a = d(a)
{a -> 4}
a=2
{a -> 2}
---------------------d(a)
{a -> 2, {a -> 2}}
a=a+a
{a -> 2, {a -> 4}}
return a
4
----------------------a = d(a)
{a -> 4}
globals(): globaler Namensraum
locals(): lokaler Namensraum
def d(a):
a=a+a
print(locals())
return a
# Test
a=2
print(a)
print(globals())
a = d(a)
print(a)
>>>
2
{'a': 2, ...}
{'a': 4}
4
68
lokale / globale Variable
Eine lokale Variable ist nur innerhalb des Unterprogramms, in dem sie eingeführt ist, gültig
bzw. sichtbar.
Auf eine globale Variable kann man innerhalb eines Unterprogramms lesend zugreifen - sofern
dort nicht eine gleichlautende Variable eingeführt ist. Wird eine Variable nicht im lokalen
Namensraum gefunden, so wird sie im globalen Namensraum gesucht.
def d():
b=a+a
return b
# Test
a=2
print(a)
a = d()
print(a)
a=2
{a -> 2}
-------------------------d()
{a -> 2}
b=a+a
{a -> 2, {b -> 4}}
return b
4
-------------------------a = d()
{a -> 4}
def d():
a=a+a
# Test
a=2
print(a)
d()
print(a)
Fehlermeldung
def d():
global a
a=a+a
# Test
a=2
print(a)
d()
print(a)
Seiteneffekt
69
def d(x):
print("x:", x)
print("id(x):", id(x))
y=x+x
print("y:", y)
print("id(y):", id(y))
return y
# Test
a=2
print("a:", a)
print("id(a):", id(a))
a = d(a)
print("a:", a)
print("id(a):", id(a))
a: 2
id(a): 505300136
x: 2
id(x): 505300136
y: 4
id(y): 505300168
a: 4
id(a): 505300168
Parameterübergabe
70
Übungen
Aufgabe:
Erkläre die Ergebnisse des unten gezeigten Programms mit Hilfe geeigneter Diagramme.
def d(a):
a=a+a
print(locals())
return a
# Test
a=2
print(a)
print(globals())
a = d(a)
print(a)
71
Teil 9
Listen
Lotto
72
# Version 2
Liste mit Zahlen
tipp = [1, 12, 21, 31, 37, 46]
ziehung = [1, 21, 25, 40, 44, 45]
# Version 1
tipp1 = 1
tipp2 = 12
tipp3 = 21
tipp4 = 31
tipp5 = 37
tipp6 = 46
ziehung1 = 1
ziehung2 = 21
ziehung3 = 25
ziehung4 = 40
ziehung5 = 44
ziehung6 = 45
einzelne Zahlen
# Version 3
Liste mit Wahrheitswerten
tipp = [ \
True , False, False, False, False, False, False, \
False, False, False, False, True , False, False, \
False, False, False, False, False, False, True , \
False, False, False, False, False, False, False, \
False, False, True , False, False, False, False, \
False, True , False, False, False, False, False, \
False, False, False, True , False, False, False, \
]
ziehung = [ \
True , False, False, False, False, False, False, \
False, False, False, False, False, False, False, \
False, False, False, False, False, False, True , \
False, False, False, True , False, False, False, \
False, False, False, False, False, False, False, \
False, False, False, False, True , False, False, \
False, True , True , False, False, False, False, \
]
73
Lotto
Bearbeiten Sie die Aufgaben des Abschnitts 1.6.10.2:
Aufgabe 1: Zugriff auf Listenelemente
Aufgabe 2/3: Verarbeitung von Listen
Aufgabe 4: Analyse von Programmen
Aufgabe 5: Ergänzung von Programmen
Aufgabe 6: Entwicklung eines Programms
Bei Bedarf können Sie sich in den folgenden Abschnitten über Listen und ihre Verarbeitung
informieren.
74
Lösungen - Aufgaben
Aufgabe 2/3: Anzahl der Richtigen
# Version 2
tipp = [1, 12, 21, 31, 37, 46]
ziehung = [1, 21, 25, 40, 44, 45]
# Anzahl der Richtigen
richtige = 0
for t in tipp:
for z in ziehung:
if t == z:
richtige = richtige + 1
print(richtige)
# Version 3
tipp = [ \
True , False, False, False, False, False, False, \
False, False, False, False, True , False, False, \
False, False, False, False, False, False, True , \
False, False, False, False, False, False, False, \
False, False, True , False, False, False, False, \
False, True , False, False, False, False, False, \
False, False, False, True , False, False, False, \
]
ziehung = [ \
True , False, False, False, False, False, False, \
...
False, True , True , False, False, False, False, \
]
# Anzahl der Richtigen
richtige = 0
for i in range(49):
if (tipp[i] == True) and (ziehung[i] == True):
richtige = richtige + 1
print(richtige)
75
Lösungen - Aufgaben
Aufgabe 4/5: Erzeugung der Lottoziehung
# Version 2
from random import *
ziehung = []
for i in range(6):
zahl = randint(1, 49)
ziehung = ziehung + [zahl]
print(ziehung)
# Version 3
from random import *
ziehung = []
for i in range(49):
ziehung = ziehung + [False]
for i in range(6):
zahl = randint(1, 49)
ziehung[zahl-1] = True
for i in range(49):
if ziehung[i] == True:
print(i+1)
# Version 3
from random import *
ziehung = []
for i in range(49):
ziehung = ziehung + [False]
for i in range(6):
ok = False
while not ok:
zahl = randint(1, 49)
if ziehung[zahl-1] == False:
ok = True
ziehung[zahl-1] = True
for i in range(49):
if ziehung[i] == True:
print(i+1)
76
Lösungen - Aufgaben
Aufgabe 6: Wiederholte Lottoziehungen
from random import *
def tipp():
t=[\
True , False, False, False, ...
...
False, False, False, True , ...
]
return t
def ziehung():
z = []
for i in range(49):
z = z + [False]
for i in range(6):
ok = False
while not ok:
zahl = randint(1, 49)
if z[zahl-1] == False:
ok = True
z[zahl-1] = True
return z
def richtige(z, t):
r=0
for i in range(49):
if (t[i] == True) and (z[i] == True):
r=r+1
return r
def simulation(n):
t = tipp()
haeufigkeiten = [0, 0, 0, 0, 0, 0, 0]
i=0
while i < n:
z = ziehung()
r = richtige(z, t)
haeufigkeiten[r] = haeufigkeiten[r] + 1
i=i+1
return haeufigkeiten
def ausgabe(h):
for i in range(7):
print(i, " Richtige: ", h[i])
# Test
haeufigkeiten = simulation(10000)
ausgabe(haeufigkeiten)
77
Liste
Eine Liste ist eine endliche Folge von Elementen, bei der man neue
Elemente hinzufügen und vorhandene Elemente entfernen kann.
 Zur Darstellung von Listen verwenden wir - wie in Python - eckige
Klammern.
 Alle Elemente einer Liste werden mit Kommata getrennt.
 Eine besondere Liste ist die leere Liste. Sie enthält keine Elemente.
 Die Elemente einer Liste können (in unserer Darstellung hier) von
beliebigem - also auch unterschiedlichem - Typ sein.
 Eine Liste kann selbst wieder Listen als Elemente haben. Listen
können also geschachtelt werden.
['[email protected]', '[email protected]', '[email protected]', ...]
[1, 12, 21, 31, 37, 46]
[]
[1, 21, 25, 40, 44, 45, ("Zusatzzahl", 3), ("Superzahl", 5)]
[[1, 12, 21, 31, 37, 46], [3, 8, 10, 30, 31, 49], [5, 12, 20, 22, 29, 40]]
Brot
Butter
Joghurt
Äpfel
Schokolade
Mehl
Eier
...
78
Liste als sequentieller Datentyp
Sequentielle Datenobjekte sind in Python zusammengesetzte Datenobjekte, die aus einer Folge
von (gleichartigen oder auch verschiedenen) Datenobjekten bestehen. Die Elemente eines
solchen sequentiellen Datenobjekts sind durchnummeriert Die Nummerierung beginnt dabei
mit 0. Die Nummer wird auch Index genannt.
Element
[10, 15, 21, 33, 37, 40]
0
1
2
3
4
5
Index
Während ein lesender Zugriff auf jedes Element der Sequenz bei allen sequentiellen
Datenobjekten möglich ist, ist ein schreibender Zugriff nur bei veränderbaren Datenobjekten
(wie Listen) möglich.
>>> L = [10, 15, 21, 33, 37, 40]
>>> L[0]
10
>>> L[1]
lesender Zugriff
15
>>> L = [10, 15, 21, 33, 37, 40]
>>> L
[10, 15, 21, 33, 37, 40]
>>> L[4] = 36
schreibender Zugriff
>>> L
[10, 15, 21, 33, 36, 40]
79
Liste als sequentieller Datentyp
Element
['g', 't', 'e', 'c', 's', 'k', 'p']
0
1
2
3
4
5
6
Index
>>> L = ['g', 't', 'e', 'c', 's', 'k', 'p']
>>> L[0:2]
['g', 't']
>>> L[2:5]
['e', 'c', 's']
>>> L[1:5]
['t', 'e', 'c', 's']
>>> L[3:3]
[]
Teillisten
Ein Zugriff auf eine Teilliste ist möglich:
Wenn L eine Liste bezeichnet, dann
beschreibt der Ausdruck L[i:j] die Liste, die
alle Elemente der Ausgangsliste L mit den
Nummern von i bis j-1 enthält. Beachte,
dass diese Teilliste auch leer sein kann.
>>> L = ['g', 't', 'e', 'c', 's', 'k', 'p']
>>> L[2:]
['e', 'c', 's', 'k', 'p']
>>> L[:2]
['g', 't']
>>> L[:]
['g', 't', 'e', 'c', 's', 'k', 'p']
80
Liste als sequentieller Datentyp
Element
['g', 't', 'e', 'c', 's', 'k', 'p']
0
1
2
3
4
5
6
Index
Bei der Konkatenation von Listen werden
diese zu einer Gesamtliste verbunden. Wenn
L und M zwei Listen bezeichnen, dann
beschreibt der Ausdruck L+M die Liste, die
zunächst alle Elemente von L und danach
alle Elemente von M enthält.
>>> L = ['g', 't', 'e', 'c', 's', 'k', 'p']
>>> M = ['a', 'g', 't']
>>> L + M
['g', 't', 'e', 'c', 's', 'k', 'p', 'a', 'g', 't']
>>> L + ['u']
['g', 't', 'e', 'c', 's', 'k', 'p', 'u']
>>> [] + M
['a', 'g', 't']
Konkatenation
Da Listen dynamisch wachsen oder
schrumpfen können, benötigt man häufig
eine Operation zur Bestimmung der Länge
der Liste. Die Länge einer Liste beschreibt
dabei die Anzahl der Listenelemente. Wenn
L eine Listen bezeichnet, dann beschreibt
der Ausdruck len(L) die Länge der Liste.
>>>
>>>
7
>>>
0
>>>
2
L = ['g', 't', 'e', 'c', 's', 'k', 'p']
len(L)
len([])
len([1, [2, 3]])
Länge
Liste als sequentieller Datentyp
81
Element
['g', 't', 'e', 'c', 's', 'k', 'p']
0
1
2
3
4
5
6
Index
Mit einem Ausdruck der Gestalt e in L kann
man überprüfen, ob das von e verwaltete
Datenobjekt in der von L verwalteten Liste
vorkommt.
Mit einer for-Anweisung der Gestalt
for e in L: ...
kann man alle Elemente einer Liste
(Sequenz) der Reihe nach durchlaufen.
>>>
>>>
>>>
False
>>>
>>>
True
L = ['g', 't', 'e', 'c', 's', 'k', 'p']
for e in L:
print(e)
L = ['g', 't', 'e', 'c', 's', 'k', 'p']
e = 'a'
e in L
e = 's'
e in L
Konkatenation
Länge
82
Übungen
Bearbeiten Sie die Aufgaben des Abschnitts 1.6.10.7:
Aufgabe 1: Eine Liste durchlaufen
Aufgabe 2: Eine Liste auf eine Eigenschaft untersuchen
Aufgabe 3: Eine neue Liste aufbauen
Aufgabe 4: Eine Liste über die Elementnummern durchlaufen
83
Merkwürdiges Verhalten
Im folgenden Python-Dialog wird ein Lotto-Tipp kopiert und anschließend etwas abgeändert.
Was fällt auf?
>>> tipp1 = [4, 13, 21, 33, 34, 42]
>>> tipp2 = tipp1
>>> tipp2[1] = 8
>>> tipp2
[4, 8, 21, 33, 34, 42]
>>> tipp1
[4, 8, 21, 33, 34, 42]
>>> tipp1 = [4, 13, 21, 33, 34, 42]
>>> tipp1
[4, 13, 21, 33, 34, 42]
>>> tipp2
[4, 8, 21, 33, 34, 42]
>>> tipp2[0] = 3
>>> tipp2
[3, 8, 21, 33, 34, 42]
>>> tipp1
[4, 13, 21, 33, 34, 42]
84
Verwaltung von Listen mit Variablen
Jedes Datenobjekt hat (in Python) eine Identitätsnummer, einen Typ und einen bestimmten
Wert.
>>> id([4, 13, 21, 33, 34, 42])
12289008
>>> type([4, 13, 21, 33, 34, 42])
<type 'list'>
>>> [4, 13, 21, 33, 34, 42]
[4, 13, 21, 33, 34, 42]
>>> tipp1 = [4, 13, 21, 33, 34, 42]
>>> id(tipp1)
12289008
>>> type(tipp1)
<type 'list'>
>>> tipp1
[4, 13, 21, 33, 34, 42]
Variablen dienen in der Informatik dazu, Datenobjekte zu verwalten. Variablen werden an
Datenobjekte angebunden, um die betreffenden Datenobjekte verwalten zu können.
Eine Variable, die ein Datenobjekt referenziert, ist eine Art Name für das betreffende
Datenobjekt. Mit dem Variablennamen kann man sich die Identitätsnummer, den Typ und den
Wert des referenzierten Datenobjekts verschaffen.
85
Verwaltung von Listen mit Variablen
>>> tipp1 = [4, 13, 21, 33, 34, 42]
>>> tipp2 = tipp1
>>> tipp2[1] = 8
>>> tipp2
[4, 8, 21, 33, 34, 42]
>>> tipp1
[4, 8, 21, 33, 34, 42]
>>> tipp1 = [4, 13, 21, 33, 34, 42]
>>> tipp1
[4, 13, 21, 33, 34, 42]
>>> tipp2
[4, 8, 21, 33, 34, 42]
>>> tipp2[0] = 3
>>> tipp2
[3, 8, 21, 33, 34, 42]
>>> tipp1
[4, 13, 21, 33, 34, 42]
86
Listen als Objekte
Listen sind (in Python) Objekte vom Typ list, die Daten
verwalten und die dem Benutzer Operationen zur
Verarbeitung der Daten zur Verfügung stellen.
>>> L
[3, 7, 5, 4, 2]
>>> L.__len__()
5
>>> L.__getitem__(1)
7
>>> L.__setitem__(1, 8)
>>> L
[3, 8, 5, 4, 2]
>>> L.__delitem__(1)
>>> L
[3, 5, 4, 2]
>>> L.__len__()
4
>>> L = []
>>> L
[]
>>> L.append(3)
>>> L
[3]
>>> L.append(5)
>>> L
[3, 5]
>>> L.insert(1, 7)
>>> L
[3, 7, 5]
>>> L.insert(0, 5)
>>> L
[5, 3, 7, 5]
>>> L.remove(5)
>>> L
[3, 7, 5]
>>> L.extend([4, 2])
>>> L
[3, 7, 5, 4, 2]
87
Listenverarbeitung
L = Listenkonstruktor
>>> L = [1, 2, 3]
>>> L
[1, 2, 3]
>>> id(L)
12283056
>>> L = L + [4]
>>> L
[1, 2, 3, 4]
>>> id(L)
12289008
>>> L = L[1:]
>>> L
[2, 3, 4]
>>> id(L)
12257720
>>> L = [1, 2] + L[1:]
>>> L
[1, 2, 3, 4]
>>> id(L)
Erzeugung neuer Listen
12289008
L.Listenoperation
>>> L = [1, 2, 3]
>>> L
[1, 2, 3]
>>> id(L)
12283536
>>> L[1] = 5
>>> L
[1, 5, 3]
>>> id(L)
12283536
>>> L.remove(5)
>>> L
[1, 3]
>>> id(L)
12283536
>>> L.insert(1, 2)
>>> L
[1, 2, 3]
>>> id(L)
12283536
Veränderung einer
bestehenden Listen
88
Übungen
Bearbeiten Sie die Aufgaben des Abschnitts 1.6.10.7:
Aufgabe 7: Kopieren von Listen
Aufgabe 8: Ein Listenelement durch ein anderes ersetzen
Aufgabe 9: Eine Liste umkehren
Aufgabe 10: Seiteneffekte bei der Listenverarbeitung
Übungen
89
Implementieren Sie Quicksort.
ALGORITHMUS quicksort(liste)
wenn liste mehr als 1 Element enthält:
wähle ein Pivotelement pivot aus liste
(z.B. das Element in der Listenmitte)
pivot
5
1
8
4
3
7
2
2
1
3
4
8
7
5
kleinerPivot
gleichPivot
groesserPivot
zerlege liste wie folgt:
- kleinerPivot: alle Elemente, die
kleiner als pivot sind
- gleichPivot: alle Elemente, die gleich
pivot sind
- groesserPivot: alle Elemente, die
größer als pivot sind
Rückgabe:
quicksort(kleinerPivot) + gleichPivot +
quicksort(groesserPivot)
sonst:
Rückgabe: liste
90
Teil 10
Zeichenketten
Caesar-Veschlüsselung
91
PYLZFOWBNQCYBUVNCBLGYC
HYAYBYCGMWBLCZNYHNTCZY
LN
VDOYH
FDHVDU
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
D E F G H I J K L M N O P Q R S T U V W X Y Z A B C
Quelltext:
SALVECAESAR
Schlüssel: 3
Geheimtext:
VDOYHFDHVDU
Verarbeitung von Zeichen
92
>>>
>>>
'A'
>>>
>>>
65
>>>
>>>
68
>>>
>>>
'D'
zeichen = 'A'
zeichen
zahl = ord(zeichen)
zahl
neuezahl = zahl + 3
neuezahl
neueszeichen = chr(neuezahl)
neueszeichen
Das "Verschieben von
Buchstaben" im Alphabet
kann man auch von einem
Rechner ausführen lassen.
Der folgende Python-Dialog
zeigt, wie das gehen kann
93
Verarbeitung von Zeichenketten
def textkopieren(text):
neuertext = "#"
for zeichen in text:
neuertext = neuertext + zeichen
neuertext = neuertext + "#"
return neuertext
# Eingabe
ausgangstext = input("Klartext: ")
# Verarbeitung
neuertext = textkopieren(ausgangstext)
# Ausgabe
print("Ausgangstext: ", ausgangstext)
print("neuer Text: ", neuertext)
Das folgende Programm
zeigt, wie man eine
Zeichenkette durchläuft
und mit den Zeichen dieser
vorgegebenen Zeichenkette
eine neue Zeichenkette
aufbaut.
Übungen
94
Quelltext:
Schlüssel: 3
SALVECAESAR
Geheimtext:
VDOYHFDHVDU
Entwickle eine Funktion textcodieren, mit deren Hilfe man kurze Texte mit dem CaesarVerfahren verschlüsseln kann. Es soll z.B. folgender Python-Dialog mit dieser Funktion möglich
sein:
>>> klartext = "SALVECAESAR"
>>> verschiebung = 3
>>> textcodieren(klartext, verschiebung)
'VDOYHFDHVDU'
Übungen
95
Geheimtext:
Schlüssel: 3
VDOYHFDHVDU
Klartext:
SALVECAESAR
Entwickle auch eine Funktion textdecodieren, mit deren Hilfe man kurze Texte mit dem CaesarVerfahren entschlüsseln kann. Es soll z.B. folgender Python-Dialog mit dieser Funktion möglich
sein:
>>> geheimtext = "VDOYHFDHVDU"
>>> verschiebung = 3
>>> textdecodieren(geheimtext, verschiebung)
'SALVECAESAR'
96
Teil 11
Didaktik
97
Programmierstile
imperativ: Am Anfang stehen Variablen zur Verwaltung von Daten und Anweisungen zur
Verarbeitung der Daten.
• wird vielfach praktiziert, da es historisch gesehen zuerst entwickelt wurde und da es relativ
einfach erscheint
• wird vielfach kritisiert, da das Denken stark an maschinenellem Vorgehen orientiert ist
objektorientiert: Am Anfang stehen Objekte, die dem Nutzer Dienste zur Verfügung stellen.
• wird heute oft propagiert, da Objekte das menschliche Denken prägen und Objekte in der
Softwareentwicklung heute von zentraler Bedeutung sind
• wird auch kritisch gesehen, da Objekte in der Regel komplex sind und ihre Gestaltung und
Verwaltung schwierig ist
funktional: Am Anfang stehen Funktionen, die aus (Übergabe-) Daten (Rückgabe-) Daten
erzeugt.
• wird selten praktiziert, weil es weniger bekannt ist
• von Befürwortern wird herausgestellt, weil es konzeptionelles Denken schult und technische
Details in den Hintergrund rückt
objektbasiert: Am Anfang stehen vordefinierte Objekte, die die Basisoperationen für
imperative Programme bereitstellen.
98
imperative Programmierung
Warum mit imperativer Programmierung anfangen?
• Nutzung einfacher und durchschaubarer Systeme (jede Zeile im Programm ist
interpretierbar)
• Idee der Automatisierbarkeit herausstellen und Ablaufmodellierung in den Vordergrund
stellen
•
99
Python als Programmiersprache
Implementierungen in Python sind meist "nahe am Algorithmus"
# Eingabe
zahl1 = int(input("Zahl 1: "))
zahl2 = int(input("Zahl 2: "))
# Verarbeitung
produkt = 0
while zahl1 > 0:
if zahl1 % 2 == 1:
produkt = produkt + zahl2
zahl1 = zahl1 // 2
zahl2 = zahl2 * 2
# Ausgabe
print("Produkt: ", produkt)
•
•
•
•
•
einfache Syntax
wenige Programmierkonstrukte
mächtige und flexible Programmierkonstrukte (z.B. Listen)
klare Strukturierung durch Einrückungen
...
100
Python als Programmiersprache
def pivot(liste):
return liste[len(liste) // 2];
ALGORITHMUS quicksort(liste)
wenn liste mehr als 1 Element enthält:
wähle ein Pivotelement pivot aus liste
(z.B. das Element in der Listenmitte)
def zerlege(liste, pivot):
zerlege liste wie folgt:
- kleinerPivot: alle Elemente, die kleiner als pivot sind
kleinerPivot = []
- gleichPivot: alle Elemente, die gleich pivot sind
gleichPivot = []
- groesserPivot: alle Elemente, die größer als pivot sind
groesserPivot = []
Rückgabe:
for element in liste:
quicksort(kleinerPivot) + gleichPivot + quicksort(groesserPivot)
if element < pivot:
sonst:
kleinerPivot = kleinerPivot + [element] Rückgabe: liste
elif element > pivot:
groesserPivot = groesserPivot + [element]
else:
gleichPivot = gleichPivot + [element]
return [kleinerPivot, gleichPivot, groesserPivot]
def quicksort(liste):
if len(liste) > 1:
(kleinerPivot, gleichPivot, groesserPivot) = zerlege(liste, pivot(liste))
return quicksort(kleinerPivot) + gleichPivot + quicksort(groesserPivot)
else:
return liste
Implementierungen in Python sind meist "nahe am Algorithmus"
101
Python als Programmiersprache
Python erlaubt interaktives und experimentelles Vorgehen und ist somit "lernerfreundlich".
>>> (jung, erwachsen, alt) = (6, 9, 12)
>>> jung
6
>>> erwachsen
9
>>> alt
12
>>> (jung, erwachsen, alt) = (erwachsen*4+alt*2, jung//2, erwachsen//3)
>>> (jung, erwachsen, alt)
(60, 3, 3)
>>> geheimtext = "VDOYHFDHVDU"
>>> verschiebung = 3
>>> textdecodieren(geheimtext, verschiebung)
'SALVECAESAR'
• Dialoge mit dem Python-Interpreter
• einfaches, direktes Austesten von Programmteilen
• ...
102
Python als Programmiersprache
Python erlaubt "Stilmix" - passend zur jeweiligen Problemlösung.
def pivot(liste):
return liste[len(liste) // 2];
def zerlege(liste, pivot):
kleinerPivot = []
gleichPivot = []
groesserPivot = []
for element in liste:
if element < pivot:
kleinerPivot = kleinerPivot + [element]
elif element > pivot:
groesserPivot = groesserPivot + [element]
else:
gleichPivot = gleichPivot + [element]
return [kleinerPivot, gleichPivot, groesserPivot]
..
# Test
from random import randint
def datenErzeugen(anzahl, maximum):
L = []
for i in range(anzahl):
L = L + [randint(0, maximum)]
return L
daten = datenErzeugen(10, 10000)
print(daten)
print(quicksort(daten))
def quicksort(liste):
if len(liste) > 1:
(kleinerPivot, gleichPivot, groesserPivot) = zerlege(liste, pivot(liste))
return quicksort(kleinerPivot) + gleichPivot + quicksort(groesserPivot)
else:
return liste
...
• imperativ + funktional (+ objektorientiert)
• ...
103
Variablenkonzept
Variablen dienen in der Informatik dazu, Daten zu verwalten. Eine Variable ist ein Name, der
... mit einer Speicherzelle verknüpft ist. Mit der Variable kann man auf den in der zugehörigen
Speicherzelle abgelegten Datenwert zugreifen.
(Speichersemantik - klassisch imperative Sicht)
... (in der Regel) mit einem Datenobjekt verknüpft ist.
(Zeigersemantik - objektorientierte Sicht)
... (in der Regel) mit einem Wert verknüpft ist.
(Wertsemantik - funktionale Sicht)
Warum Zeigersemantik?
• Die Variablen-Sichtweise soll ein mentales Modell liefern, das als Erklärungsmodell möglichst
universell einsetzbar ist. Wenn man sich für Python als Implementierungssprache entschieden
hat, dann sind manche Phänomene nur mit Zeigersemantik erklärbar.
• Zeigersemantik orientiert sich - genauso wie Speichersemantik - an einer natürlichen Form
der Verwaltung von Gegenständen:
Speichersemantik: Ein Name wird mit einem Ort verknüpft. (Lokalisierung)
Zeigersemantik: Ein Name wird mit einem Gegenstand verknüpft. (Identifizierung)
• Zeigersemantik kann - genauso wie Speichersemantik - gut auf enaktiver und ikonischer
Ebene dargestellt werden.
104
Kontrollstrukturen
Kontrollstrukturen dienen dazu, die Reihenfolge der Abarbeitung von Anweisungen (eines
Algorithmus / eines Programms festzulegen.
Kontrollstrukturen benutzt man also zur Ablaufmodellierung.
Ablaufmodellierung mit Kontrollstrukturen
• Kontrollstrukturen liefern Standard-Ablaufmodelle, mit deren Hilfe man komplexe Abläufe
beschreiben kann.
• Programmiersprachen wie Python stellen geeignete Anweisungstypen zur Implementierung
dieser Standard-Ablaufmodelle bereit.
• Zur Verdeutlichung von Kontrollstrukturen (bzw. der Semantik der entsprechenden
Anweisungen) eignen sich Flussdiagramme / Programmablaufpläne.
• Zur Ablaufmodellierung eignen sich Struktogramme / Pseudo-Programmiersprachen, die
Kontrollstrukturen als Bausteine zur Verfügung stellen.
105
Unterprogramme
Unterprogramme sind eigenständige Programmeinheiten,. Sie werden innerhalb von
Programmen benutzt, um Teilaufgaben zu implementieren.
Unterprogramme benutzt man zur Modellierung funktionaler Verarbeitungssituationen.
Funktionale Abstraktion mit Unterprogrammen
• Unterprogramme dienen dazu, eine Programmeinheit mit einem bestimmten
Verarbeitungsverhalten durch eine Operation / Anweisung zu ersetzen.
• Hierdurch lassen sich Codeduplizierungen vermeiden und Programme besser strukturieren.
• Unterprogramme haben in der Regel Schnittstellen zur Übergabe und Rückgabe von Daten.
• Python stellt ein flexibles Funktionskonzept zur Implementierung von Unterprogrammen zur
Verfügung.
• Funktionen ordnen Übergabedaten Rückgabedaten zu. Prozeduren sind Funktionen ohne
Rückgaben.
• Bei der Konzeption von Unterprogrammen kommt funktionale Abstraktion ins Spiel: Das
"Wie" wird in die Unterprogramm-Deklaration verlagert, bei der Verwendung von
Unterprogrammen (durch Aufrufe) spielt das "Was" die entscheidende Rolle.
• Bei der Verwendung von Unterprogrammen spielt Datenverwaltung eine Rolle (lokale
Variablen, Parameterübergabe). Es ist hilfreich, über adäquate Erklärungsmodelle für die
Datenverwaltung zu verfügen.
106
Datenstrukturen
Datenstrukturen ermöglichen es, strukturierte Daten als Einheit zu verwalten.
Standardmodelle zur Verwaltung komplexer Daten
• Datenstrukturen liefern Standardmodelle zur Verwaltung komplexer Daten.
• Programmiersprachen stellen geeignete Datenstrukturen zur Implementierung dieser
Standardmodelle bereit.
• Python stellt als zentrale Datenstruktur die Datenstruktur Liste zur Verfügung. Diese kann
vielfältig zur Datenmodellierung benutzt werden.
• Achtung: Die Verwendung von Listen in Python ist sehr einfach, wenn man sich an
bestimmte Regeln hält, aber auch fehleranfällig, wenn man den objektorientierten Charakter
von Listen nicht beachtet.
Herunterladen