ppt

Werbung
Datenverwaltung mit Datenstrukturen
Klaus Becker
2012
2
Datenverwaltung mit Datenstrukturen
131.246.0.13 - - [24/Jul/2012:12:44:21 +0200] "GET /informatik/index.html HTTP/1.1" 200 512
131.246.0.13 - - [24/Jul/2012:12:44:25 +0200] "GET /informatik/bild.png HTTP/1.1" 200 805
# ...
3
Teil 1
Fallstudie - Lottosimulation
4
Lottosimulation
Wie wahrscheinlich ist es, dass man beim Lottospielen gewinnt? Diese Frage soll hier mit
einem Simulationsprogramm beantwortet werden. Bei der Programmentwicklung werden wir
uns mit der Verwaltung vieler Daten beschäftigen.
5
Datenverwaltung mit Listen
Die Zahlen einer Lotto-Ziehung (ohne Zusatzzahl) sollen
mit Hilfe von Python verwaltet werden. Im Folgenden
findest du zwei Vorschläge, wie man das machen könnte.
# Datenverwaltung
zahl1 = 25
zahl2 = 40
zahl3 = 44
zahl4 = 1
zahl5 = 45
zahl6 = 21
# Ausgabe
print(zahl1)
print(zahl2)
print(zahl3)
print(zahl4)
print(zahl5)
print(zahl6)
Verwendung vieler Variablen
# Datenverwaltung
ziehung = [25, 40, 44, 1, 45, 21]
# Ausgabe
i=0
while i < len(ziehung):
print(ziehung[i])
i = i+1
Verwendung einer Variablen sowie einer
Liste als "Datencontainer"
Aufgaben:
(a) Welchen Vorteil hat es, wenn man eine
Liste als eine Art "Datencontainer" benutzt?
(b) Wie bildet man in Python eine Liste? Wie
greift man auf einzelne Listenelemente zu?
Wie sind diese durchnummeriert?
6
Datenverwaltung mit Listen
Aufgabe:
Ein Tipp soll verwaltet werden. Zwei Möglichkeiten
stehen zur Auswahl. Entscheide dich für eine Version und
ergänze die fehlenden Teile.
# Datenverwaltung
feld1 = True
feld2 = False
...
# Ausgabe
print(feld1)
print(feld2)
...
# Datenverwaltung
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,
]
# Ausgabe
...
7
Eine Liste durchlaufen
Die Zahlen einer Lotto-Ziehung (ohne Zusatzzahl) werden mit einer Liste verwaltet. Die
Listenelemente sind dabei - beginnend mit 0 mit einem Index durchnummeriert.
Liste über den Index durchlaufen
# Initialisierung
ziehung = [25, 40, 44, 1, 45, 21]
# Verarbeitung und Ausgabe
i=0
while i < len(ziehung):
print(ziehung[i])
i = i+1
# Initialisierung
ziehung = [25, 40, 44, 1, 45, 21]
# Verarbeitung und Ausgabe
for i in range(len(ziehung)):
print(i)
print(ziehung[i])
Aufgabe:
Ergänze das Programm so,
dass man folgende
Ausgabe erhält:
Aufgabe:
Teste auch das oben gezeigte Programm.
Was leistet der range-Operator?
>>>
Kugel
Kugel
Kugel
Kugel
Kugel
Kugel
1
2
3
4
5
6
:
:
:
:
:
:
25
40
44
1
45
21
>>> list(range(6))
[0, 1, 2, 3, 4, 5]
>>> list(range(3, 7))
[3, 4, 5, 6]
>>> list(range(2, 12, 3))
[2, 5, 8, 11]
8
Eine Liste durchlaufen
Die Zahlen einer Lotto-Ziehung (ohne Zusatzzahl) werden mit einer Liste verwaltet. Die
Listenelemente sind dabei - beginnend mit 0 mit einem Index durchnummeriert.
# Initialisierung
ziehung = [25, 40, 44, 1, 45, 21]
# Verarbeitung und Ausgabe
for z in ziehung:
print(z)
Aufgabe:
Teste auch dieses Programm. Was leistet
es?
Liste über die Elemente durchlaufen
9
Anzahl der Richtigen
Ziel ist, es, die Anzahl der richtig getippten
Zahlen mit einem Programm zu ermitteln.
Aufgabe:
Die folgenden Programm liefert ein Gerüst, mit
dem man jede Zahl der Liste ziehung mit jeder
Zahl der Liste tipp vergleichen kann.
# Initialisierung
ziehung = [25, 40, 44, 1, 45, 21]
tipp = [1, 12, 21, 31, 37, 46]
# Verarbeitung
richtige = 0
i=0
while i < len(ziehung):
j=0
while j < len(tipp):
print('vergleiche: ', ziehung[i], tipp[j])
# ...
j = j+1
i = i+1
# Ausgabe
print(richtige)
# Initialisierung
ziehung = [25, 40, 44, 1, 45, 21]
tipp = [1, 12, 21, 31, 37, 46]
# Verarbeitung
richtige = 0
for z in ziehung:
for t in tipp:
print('vergleiche: ', z, t)
# ...
# Ausgabe
print(richtige)
Teste erst einmal, was die Programme
schon leisten. Ergänze die noch fehlenden
Teile.
10
Anzahl der Richtigen
Aufgabe:
Die Lotto- und Tippzahlen sollen hier ebenfalls
mit Listen verwaltet werden, aber auf eine
etwas andere Weise. Ergänze das Programm
so, dass man die Anzahl der Richtigen erhält.
# Initialisierung
ziehung = [
True , False, False, False, False, False, False,
False, False, False, False, False, False, False,
...
]
tipp = [
True , False, False, False, False, False, False,
False, False, False, False, True , False, False,
...
]
# Verarbeitung
richtige = 0
# ...
# Ausgabe
print(richtige)
11
Ziehung automatisiert erzeugen
Beim Lotto werden die 6 Kugeln mit Zahlen aus dem Bereich 1..49 der Reihe nach mit einem
Zufallsgerät ermittelt. Ziel ist es, diesen Ziehungsvorgang zu simulieren und die gezogenen
Zahlen schrittweise in eine Liste aufzunehmen
Elemente hinzufügen
12
Der folgende Python-Dialog zeigt, wie man eine Liste zur Verwaltung der Zahlen eines Tipps
schrittweise aufbauen kann.
>>> liste
>>> liste
[]
>>> liste
>>> tipp
[12]
>>> liste
>>> liste
[12, 15]
>>> liste
>>> liste
...
>>> liste
>>> liste
...
>>> liste
>>> liste
...
= []
= liste + [12]
= liste + [15]
= [7] + liste
= liste + [42, 47]
= [3] + liste
Listen aneinanderhängen
Aufgabe:
Analysiere den gezeigten Python-Dialog.
Stelle Vermutungen auf, was an Stelle der
drei Punkte ... steht. Überprüfe deine
Vermutung.
13
Ziehung automatisiert erzeugen
Ziel ist es, eine Ziehung der Lottozahlen mit Hilfe des
Zufallsgenerators von Python zu simulieren. Hier ein
erster Vorschlag:
from random import *
# Verarbeitung
ziehung = []
for i in range(6):
zahl = randint(1, 49)
ziehung = ziehung + [zahl]
# Ausgabe
print(ziehung)
Aufgabe:
(a) Analysiere das Programm und erkläre die
einzelnen Anweisungen.
(b) Teste das Programm mehrfach. Welche
Schwierigkeit tritt hier auf.
(c) Kannst du die Schwierigkeit beheben?
14
Ziehung automatisiert erzeugen
Ziel ist es, eine Ziehung der Lottozahlen mit Hilfe des
Zufallsgenerators von Python zu simulieren. Hier ein
weiterer Vorschlag:
from random import *
# Verarbeitung
ziehung = []
for i in range(49):
ziehung = ziehung + [False]
for i in range(6):
zahl = randint(1, 49)
ziehung[zahl-1] = True
# Ausgabe
for i in range(49):
if ziehung[i] == True:
print(i+1)
Aufgabe:
(a) Teste das folgende Programm. Erkläre,
wie hier die Liste zur Verwaltung der
Wahrheitswerte aufgebaut wird.
(b) Auch hier ist noch etwas nicht in
Ordnung. Kannst du die Schwierigkeit durch
Ergänzungen im Programm beheben?
15
Gewinnchancen beim Lotto
Die Gewinnchancen beim Lottospiel kann man näherungsweise
ermitteln, indem man sehr oft einen (evtl. festen) Tipp vorgibt und
eine Lotto-Ziehung durchführt. Man muss dann nur mitzählen, wie
oft man 0, 1, ..., 6 Richtige hatte.
Tipp
Ziehung
Richtige
--------------------------------------------------------------------------[ 1, 12, 21, 31, 37, 46]
[25, 40, 44, 1, 45, 21]
[0, 0, 1, 0, 0, 0, 0]
[ 1, 12, 21, 31, 37, 46]
[11, 15, 3, 20, 40, 30]
[1, 0, 1, 0, 0, 0, 0]
[ 1, 12, 21, 31, 37, 46]
[ 6, 49, 32, 18, 19, 24]
[2, 0, 1, 0, 0, 0, 0]
...
Aufgaben:
(a) Entwickle ein Programm zur Ermittlung der Gewinnchancen beim Lotto. Mit dem Programm
soll es z.B. möglich sein zu ermitteln, wie oft man 0, 1, 2, ..., 6 Richtige erhält, wenn man
10000 mal Lotto spielt. Strukturiere das Programm mit Hilfe von Funktionen.
(b) Wie lange dauert es im wirklichen Leben, bis 10000 Ziehungen durchgeführt wurden, wenn
man von einer Ziehung am Mittwoch und einer am Samstag ausgeht und wenn man einen
Tipp pro Spiel abgibt? Beurteile mit den Ergebnissen die Gewinnaussichten beim Lottospiel.
16
Gewinnchancen beim Lotto
Wenn man ein Programm zur wiederholten Simulation entwickeln möchte, dann sollte man
Funktionen zur Durchführung von Teilaufgaben nutzen. Hier ein Vorschlag zur Modellierung von
Funktionen.
17
Gewinnchancen beim Lotto
Aufgabe:
Implementiere die vorgeschlagenen Funktionen. Benutze dabei die bereits entwickelten
Listenverarbeitungsprogramme.
def neueZiehung():
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
return ziehung
mögliche Implementierung
18
Gewinnchancen beim Lotto
Aufgabe:
Implementiere die vorgeschlagenen Funktionen. Benutze die bereits implementierten
Funktionen.
19
Teil 2
Fallstudie - Newsletter
20
Newsletter
Newsletter werden benutzt, um allen Mitgliedern einer Gruppe Informationen per E-Mail
zukommen zu lassen. So könnte z.B. das inf-schule-Team allen Interessierten eine E-Mail
schicken, wenn es Neuerungen in den Materialien gibt.
>>>
From: [email protected]
To: [email protected]
Subject: Neuerungen
Hallo!
...
21
Newsletter automatisiert senden
Solche elektronischen Rundschreiben kann man automatisiert verfassen und versenden. Das
folgende Python-Programm zeigt, wie das (im Prinzip) geht.
# Mail erstellen
mail_from = '[email protected]'
mail_to = '[email protected]'
mail_subject = 'Neuerungen'
mail_header = 'From: ' + mail_from + '\n' + 'To: ' + mail_to + '\n' + 'Subject: ' +
mail_subject + '\n'
mail_text = 'Hallo!\n ...'
mail_body = '\n' + mail_text + '\n\n'
mail = mail_header + mail_body
print(mail)
# Mail versenden
import smtplib
benutzer = '[email protected]'
passwort = '...' # wird nicht verraten
empfaenger = '[email protected]'
mailserver = 'smtp.gmx.de'
smtp = smtplib.SMTP(mailserver)
smtp.login(benutzer, passwort)
smtp.sendmail(benutzer, empfaenger, mail)
smtp.quit()
22
Datenverwaltung mit einer Liste
Interessant wird das Programm, wenn man das elektronische Rundschreiben an mehrere
Empfänger verschicken kann.
# Mail erstellen
mail_from = '[email protected]'
mail_to = '[email protected]'
mail_subject = 'Neuerungen'
mail_header = 'From: ' + mail_from + '\n' + 'To: ' + mail_to + '\n' + 'Subject: ' +
mail_subject + '\n'
mail_text = 'Hallo!\n ...'
# Datenverwaltung
mail_body = '\n' + mail_text + '\n\n'
listeAdressen = [
mail = mail_header + mail_body
'[email protected]',
print(mail)
'[email protected]',
# Mail versenden
'[email protected]',
import smtplib
'[email protected]',
benutzer = '[email protected]'
'[email protected]',
passwort = '...' # wird nicht verraten
'[email protected]',
empfaenger = '[email protected]'
'[email protected]'
mailserver = 'smtp.gmx.de'
]
smtp = smtplib.SMTP(mailserver)
# Datenverarbeitung
smtp.login(benutzer, passwort)
for adresse in listeAdressen:
smtp.sendmail(benutzer, empfaenger, mail)
# verarbeite adresse
smtp.quit()
23
Eine Liste dynamisch verändern
Im Newsletter-Programm des MSS-Leiters werden die E-Mail-Adressen sämtlicher
Schülerinnen und Schüler der 11. Jahrgangsstufe mit einer Liste verwaltet. Beachte, dass die
Liste mehr als 100 Elemente haben kann.
Während der ersten Wochen des Schuljahres gibt es ständig Änderungswünsche:
 Durch Schulwechsel, Umzug, freiwilliges Wiederholen
etc. werden 7 Schülerinnen und Schüler neu in die 11.
Jahrgangsstufe aufgenommen. Ihre E-Mail-Adressen
müssen in die Liste integriert werden.
'[email protected]'
'[email protected]'
'[email protected]'
 Herbert Fluhr hat sich doch für eine Ausbildung als
Bankkaufmann entschieden und die Schule verlassen.
Seine E-Mail-Adresse muss gelöscht werden.
'[email protected]'
 Carla hat sich mal wieder eine neue E-Mail-Adresse
zugelegt. Ihre alte Adresse muss durch die neue ersetzt
werden.
'[email protected]'
'[email protected]'
'[email protected]'
'[email protected]'
...
'[email protected]'
Um den MSS-Leiter zu entlasten, sollen im Folgenden Programmeinheiten entwickelt werden,
mit denen eine dynamische Veränderung einer bestehenden Liste leicht möglich ist.
24
Zugriff auf Listenelemente
>>> listeAdressen = [
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]'
]
>>> listeAdressen
['[email protected]', '[email protected]', '[email protected]', '[email protected]',
'[email protected]', '[email protected]', '[email protected]']
>>> listeAdressen[0]
'[email protected]'
>>> listeAdressen[1]
lesender Zugriff
'[email protected]'
>>> listeAdressen[6]
'[email protected]'
>>> listeAdressen[7]
Traceback (most recent call last):
...
listeAdressen[7]
IndexError: list index out of range
25
Zugriff auf Listenelemente
>>> listeAdressen = [
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]'
]
>>> listeAdressen
['[email protected]', '[email protected]', '[email protected]', '[email protected]',
'[email protected]', '[email protected]', '[email protected]']
>>> listeAdressen[1] = '[email protected]'
schreibender Zugriff
>>> listeAdressen
['[email protected]', '[email protected]', '[email protected]', '[email protected]',
'[email protected]', '[email protected]', '[email protected]']
...
26
Zugriff auf Teillisten
Ein Zugriff auf eine Teilliste ist möglich: Wenn liste eine Liste bezeichnet, dann beschreibt der
Ausdruck liste[i:j] die Liste, die alle Elemente der Ausgangsliste liste mit den Nummern von i
bis j-1 enthält. Beachte, dass diese Teilliste auch leer sein kann.
>>> liste = ['G', 'i', 'r', 'a', 'f', 'f', 'e']
>>> liste[0:2]
['G', 'i']
>>> liste[2:5]
Zugriff auf eine Teilliste
['r', 'a', 'f']
>>> liste[1:6]
['i', 'r', 'a', 'f', 'f']
>>> liste[3:3]
[]
>>> liste = ['G', 'i', 'r', 'a', 'f', 'f', 'e']
>>> liste[3:]
['a', 'f', 'f', 'e']
>>> liste[:3]
['G', 'i', 'r']
>>> liste[:]
['G', 'i', 'r', 'a', 'f', 'f', 'e']
# von Nummer 3 bis zum Ende der Nummerierung
# von Nummer 0 bis zur Nummer 2 (= 3-1)
# von Nummer 0 bis zum Ende der Nummerierung
27
Zugriff auf Teillisten
Aufgabe:
Stelle zunächst Vermutungen auf, was an Stelle der drei Punkte steht. Überprüfe deine
Vermutungen, indem du den Python-Dialog selbst ausführst.
>>> listeAdressen = [
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]'
]
>>>
...
>>>
...
>>>
...
>>>
...
>>>
...
>>>
...
>>>
...
>>>
...
>>>
...
listeAdressen[0:2]
listeAdressen[2:5]
listeAdressen[1:4]
listeAdressen[3:3]
listeAdressen[3:9]
listeAdressen[0:len(listeAdressen)]
listeAdressen[2:]
listeAdressen[:2]
listeAdressen[:]
28
Listen zusammenfügen
Bei der Konkatenation von Listen werden diese zu einer Gesamtliste verbunden. Wenn liste1
und liste2 zwei Listen bezeichnen, dann beschreibt der Ausdruck liste1+liste2 die Liste, die
zunächst alle Elemente von L und danach alle Elemente von M enthält.
>>> liste1 = ['T', 'e', 'r', 'm']
>>> liste2 = ['i', 'n']
>>> liste1 + liste2
['T', 'e', 'r', 'm', 'i', 'n']
Listen zusammenfügen
29
Aufgabe:
Stelle zunächst Vermutungen auf, was an Stelle der drei Punkte steht. Überprüfe deine
Vermutungen, indem du den Python-Dialog selbst ausführst.
>>>
>>>
>>>
>>>
>>>
>>>
>>>
...
>>>
...
>>>
...
a = [1]
b = [2]
c = [3]
a = a+b
b = a+c
c = c+b
a
b
c
>>>
>>>
[]
>>>
>>>
...
>>>
>>>
...
>>>
>>>
...
>>>
>>>
...
>>>
>>>
...
liste = []
liste
liste = liste + ['n']
liste
liste = liste + ['t']
liste
liste = ['o'] + liste
liste
liste = liste + ['a', 'g']
liste
liste = ['M'] + liste
liste
30
Listenelemente einfügen
Das Einfügen von Listenelementen am Anfang und Ende einer Liste ist einfach.
>>> listeAdressen = [
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]'
]
erzeugt eine neue Liste
>>> listeAdressen + ['[email protected]']
['[email protected]', '[email protected]', '[email protected]', '[email protected]',
'[email protected]', '[email protected]', '[email protected]', '[email protected]']
>>> listeAdressen
['[email protected]', '[email protected]', '[email protected]', '[email protected]',
'[email protected]', '[email protected]', '[email protected]']
>>> listeAdressen = listeAdressen + ['[email protected]']
verändert die Liste
>>> listeAdressen
['[email protected]', '[email protected]', '[email protected]', '[email protected]',
'[email protected]', '[email protected]', '[email protected]', '[email protected]']
31
Listenelemente einfügen
Ein Einfügen von Listenelementen an einer bestimmten Stelle innerhalb einer Liste ist wie folgt
möglich.
>>> listeAdressen = [
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]'
erzeugt eine neue Liste
]
>>> listeAdressen[0:2] + ['[email protected]'] + listeAdressen[2:7]
['[email protected]', '[email protected]', '[email protected]', '[email protected]',
'[email protected]', '[email protected]', '[email protected]', '[email protected]']
>>> listeAdressen
['[email protected]', '[email protected]', '[email protected]', '[email protected]',
verändert die Liste
'[email protected]', '[email protected]', '[email protected]']
>>> listeAdressen = listeAdressen[0:2] + ['[email protected]'] + listeAdressen[2:7]
>>> listeAdressen
['[email protected]', '[email protected]', '[email protected]', '[email protected]',
'[email protected]', '[email protected]', '[email protected]', '[email protected]']
32
Listenelemente entfernen
Aus einer Liste kann man Elemente auch wieder löschen. Der folgende Python-Dialog zeigt wie
das geht.
>>> listeAdressen = [
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
]
>>> listeAdressen = ['[email protected]', '[email protected]', '[email protected]',
'[email protected]']
erzeugt eine neue Liste
>>> listeAdressen[0:len(listeAdressen)-1]
['[email protected]', '[email protected]', '[email protected]']
>>> listeAdressen
['[email protected]', '[email protected]', '[email protected]', '[email protected]']
>>> listeAdressen = listeAdressen[0:len(listeAdressen)-1]
>>> listeAdressen
verändert die Liste
['[email protected]', '[email protected]', '[email protected]']
33
Listenelemente entfernen
Aus einer Liste kann man Elemente auch wieder löschen. Der folgende Python-Dialog zeigt wie
das geht.
>>> listeAdressen = [
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]'
]
>>> listeAdressen = ['[email protected]', '[email protected]', '[email protected]',
'[email protected]']
erzeugt eine neue Liste
>>> listeAdressen[0:1] + listeAdressen[2:5]
['[email protected]', '[email protected]', '[email protected]']
>>> listeAdressen
['[email protected]', '[email protected]', '[email protected]', '[email protected]']
>>> listeAdressen = listeAdressen[0:1] + listeAdressen[2:5]
>>> listeAdressen
verändert die Liste
['[email protected]', '[email protected]', '[email protected]']
34
Eine Liste dynamisch verändern
Aufgabe:
Benutze die eingeführten Listenoperationen, um die Liste mit E-Mail-Adressen in der gezeigten
Weise zu verändern.
>>> listeAdressen = [
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]'
]
'[email protected]'
'[email protected]'
'[email protected]'
'[email protected]'
'[email protected]'
'[email protected]'
'[email protected]'
'[email protected]'
'[email protected]'
'[email protected]'
35
Listenoperationen selbst definieren
Bei der automatisierten Verwaltung und Versendung von Newsletter ist es günstig, wenn
unterschiedliche Operationen zur Verarbeitung von Listen mit E-Mail-Adressen zur Verfügung
stehen. Mit solchen Operationen sollte es z.B. möglich sein, auf einfache Weise neue E-MailAdressen hinzuzufügen oder auch vohandene E-Mail-Adressen wieder zu löschen.
Programmiersysteme wie Python stellen in der Regel eine Reihe vordefinierter Operationen zur
Verarbeitung von Listen zur Verfügung. So kann man in Python die Operation len zur
Bestimmung der Anzahl der Listenelemente und die Operation + zum Aneinanderhängen von
Listen benutzen.
Zur flexiblen Verarbeitung von Listen sind weitere Operationen wünschenswert. Im Folgenden
wird gezeigt, wie man sich Listenoperationen selbst definieren kann.
Operationen zur Listenverarbeitung werden dabei mit Hilfe von Funktionen realisiert. Wir
werden versuchen, die Listenoperationen als flexibel verwendbare Bausteine zu konzipieren.
Das hat den Vorteil, dass man sie in vielen verschiedenen Anwendungssituationen benutzen
kann. Wir werden daher zunächst vom Kontext "Newsletter" absehen und neue Operationen zur
Listenverarbeitung möglichst allgemein festlegen.
36
Listenoperationen selbst definieren
Das Verhalten der Funktion mitErstemElement lässt sich gut mit einem Black-Box-Diagramm
verdeutlichen.
Der folgende Python-Quelltext zeigt, wie man die Funktion mitErstemElement definieren kann.
Beachte, dass in der Funktionsdefinition Testfälle zur Verhaltensbeschreibung integriert sind.
def mitErstemElement(element, liste):
"""
>>> mitErstemElement(3, [25, 40, 44, 1, 45, 21])
[3, 25, 40, 44, 1, 45, 21]
>>> mitErstemElement(7, [])
[7]
"""
neueListe = [element] + liste
return neueListe
37
Listenoperationen selbst definieren
Testen im Ausführfenster:
>>> adressen = [
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]'
]
>>> mitErstemElement('[email protected]', adressen)
['[email protected]', '[email protected]',
'[email protected]', '[email protected]',
'[email protected]', '[email protected]',
'[email protected]', '[email protected]']
>>> adressen
['[email protected]', '[email protected]',
'[email protected]', '[email protected]',
'[email protected]', '[email protected]',
'[email protected]']
>>> adressen = mitErstemElement('[email protected]',
adressen)
>>> adressen
['[email protected]', '[email protected]',
'[email protected]', '[email protected]',
'[email protected]', '[email protected]',
'[email protected]', '[email protected]']
Testen mit einem Testprogramm:
def mitErstemElement(element, liste):
"""
>>> mitErstemElement(3, [25, 40, 44, 1, 45, 21])
[3, 25, 40, 44, 1, 45, 21]
>>> mitErstemElement(7, [])
[7]
"""
neueListe = [element] + liste
return neueListe
# Test
adressen = ['[email protected]', '[email protected]',
'[email protected]', '[email protected]', '[email protected]', '[email protected]', '[email protected]']
print(adressen)
adressen = mitErstemElement('[email protected]',
adressen)
print(adressen)
38
Listenoperationen selbst definieren
Test der integrierten Testfälle:
def mitErstemElement(element, liste):
"""
>>> mitErstemElement(3, [25, 40, 44, 1, 45, 21])
[3, 25, 40, 44, 1, 45, 21]
>>> mitErstemElement(7, [])
[7]
"""
neueListe = [element] + liste
return neueListe
if __name__ == '__main__':
from doctest import testmod
testmod(verbose=True)
39
Listenoperationen selbst definieren
Aufgabe:
Entwickle und teste analog Funktionen zur Realisierung der folgenden Listenoperationen:
40
Listenoperationen selbst definieren
Aufgabe:
Entwickle und teste analog Funktionen zur Realisierung der folgenden Listenoperationen:
41
Daten sichern
Wenn man E-Mail-Adressen mit einer Liste verwaltet, dann erfolgt die Datenhaltung nur solange
das Programmiersystem aktiv ist. Für eine längerfristige Datenhaltung müssen die Daten in
einer externen Datei gespeichert werden. Um beides nutzen zu können - längerfristige
Datenhaltung in einer Datei und flexible Datenhaltung und -verarbeitung mit Listen - benötigt
man Funktionen, die das Speichern und Laden von Daten sowie das Umwandeln von Listen und
Texten ermöglichen.
>>> adressen = ['[email protected]', '[email protected]', '[email protected]',
'[email protected]', '[email protected]', '[email protected]', '[email protected]']
>>> adressen
['[email protected]', '[email protected]', '[email protected]', '[email protected]',
'[email protected]', '[email protected]', '[email protected]']
>>> ========================== RESTART ====================
>>> adressen
Traceback (most recent call last):
File "<pyshell#30>", line 1, in <module>
adressen
NameError: name 'adressen' is not defined
42
Bausteine
Funktionen zur Listenverarbeitung muss man nicht immer selbst konzipieren und definieren. Oft
kann man auf bereits existierende Funktionsdefinitionen zurückgreifen. Wenn die
Funktionsdefinitionen hinreichend dokumentiert sind, dann kann man die Funktionen als fertige
Bausteine benutzen.
def textAusDatei(dateiname):
# lädt einen Text aus einer Datei und gibt ihn als
# Zeichenkette zurück
# beachte: setzt die Codierung iso-8859-1 voraus
datei = open(dateiname, 'r', encoding='iso-8859-1')
text = datei.read()
datei.close()
return text
def textInDateiSpeichern(dateiname, text):
# speichert eine Zeichenkette in einer Datei
# beachte: benutzt die Codierung iso-8859-1
datei = open(dateiname, 'w', encoding='iso-8859-1')
datei.write(text)
datei.close()
Bausteine
43
def textAusStringListe(liste):
"""
>>> textAusStringListe(['Tamara', 'Peter', 'Bello'])
'Tamara\nPeter\nBello'
"""
text = ''
if len(liste) > 0:
text = text + liste[0]
for element in liste[1:]:
text = text + '\n' + element
return text
def stringListeAusText(text):
"""
>>> stringListeAusText('Tamara\nPeter\nBello')
['Tamara', 'Peter', 'Bello']
>>> stringListeAusText('Text\nmit\n\nmehreren\nZeilen')
['Text', 'mit', '', 'mehreren', 'Zeilen']
"""
liste = text.split('\n')
return liste
44
Bausteine verwenden
Aufgabe:
Speichere die Bausteine zum Laden und Speichern in einer Datei mit dem Dateinamen
listenoperationen_zum_laden_und_speichern.py ab. Führe das Python-Programm mit den
Funktionsdefinitionen einmal aus, damit Python die Funktionsdefinitionen "übernimmt".
Entwickle anschließend geeignete Testprogramme. Beachte, dass die Testprogramme im selben
Verzeichnis gespeichert sind wie das Programm mit den Funktionsdefinitionen.
from listenoperationen_zum_laden_und_speichern import *
# Test
listeAdressen = [
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]'
]
text = textAusStringListe(listeAdressen)
print(text)
45
Teil 3
Listen in Python
46
Fachkonzept - Liste
Eine Liste ist eine Datenstruktur zur Verwaltung endlicher
Folgen von Daten, bei der man flexibel neue Daten
hinzufügen und vorhandene Daten entfernen kann.
 Listen werden mit eckigen Klammern dargestellt.
 Alle Elemente e. Liste werden mit Kommata getrennt.
 Eine besondere Liste ist die leere Liste.
 Die Elemente einer Liste können (in Python) 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]'
'[email protected]'
'[email protected]'
'[email protected]'
'[email protected]'
'[email protected]'
'[email protected]'
'[email protected]'
[1, 12, 21, 31, 37, 46]
['[email protected]', '[email protected]', '[email protected]', ...]
[]
[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]]
47
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 immer
bei 0. Die Nummer wird auch Index genannt.
Element
ziehung
25
40
44
1
45
21
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]
48
Liste als sequentieller Datentyp
ziehung
>>> ziehung = [25, 40, 44, 1, 45, 21]
>>> ziehung[0:2]
[25, 40]
>>> ziehung[2:5]
[44, 1, 45]
>>> ziehung[3:3]
[]
Teillisten
25
40
44
1
45
21
0
1
2
3
4
5
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.
>>> ziehung = [25, 40, 44, 1, 45, 21]
>>> ziehung[:2]
[25, 40]
>>> ziehung[2:]
[44, 1, 45, 21]
>>> ziehung[:]
[25, 40, 44, 1, 45, 21]
49
Liste als sequentieller Datentyp
ziehung
25
40
44
1
45
21
0
1
2
3
4
5
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.
>>> tippAnfang = [2, 6]
>>> tippEnde = [16, 40, 41, 43]
>>> tippAnfang + tippEnde
[2, 6, 16, 40, 41, 43]
>>> tippAnfang + [10]
[2, 6, 10]
>>> [] + tippAnfang
[2, 6]
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.
>>> tippAnfang = [2, 6, 16, 40]
>>> len(tippAnfang)
4
>>> len([])
0
Länge
50
Liste als sequentieller Datentyp
ziehung
25
40
44
1
45
21
0
1
2
3
4
5
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
tippAnfang = [2, 6, 16, 40]
t = 25
t in tippAnfang
>>> ziehung = [25, 40, 44, 1, 45, 21]
>>> for z in ziehung:
print(z)
t = 40
t in tippAnfang
25
40
44
1
45
21
Elementbeziehung
Durchlaufen einer Liste
51
Eine Liste kopieren
Wie kopiert man eine E-Mail-Adressliste? Das ist gar nicht so einfach, wie der folgende PythonDialog zeigt.
>>> adressen1 = ['[email protected]', '[email protected]', '[email protected]',
'[email protected]']
>>> adressen2 = adressen1
>>> adressen2[1] = '[email protected]'
>>> adressen2
['[email protected]', '[email protected]', '[email protected]', '[email protected]']
>>> adressen1
['[email protected]', '[email protected]', '[email protected]', '[email protected]']
52
Eine Liste kopieren
Wie kopiert man eine E-Mail-Adressliste? Das ist gar nicht so einfach, wie der folgende PythonDialog zeigt.
>>> adressen1 = ['[email protected]', '[email protected]', '[email protected]',
'[email protected]']
>>> adressen2 = adressen1[:]
>>> adressen2[1] = '[email protected]'
>>> adressen2
['[email protected]', '[email protected]', '[email protected]', '[email protected]']
>>> adressen1
['[email protected]', '[email protected]', '[email protected]', '[email protected]']
53
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]
>>> liste1 = [4, 13, 21, 33, 34, 42]
>>> id(liste1)
12289008
>>> type(liste1)
<type 'list'>
>>> liste1
[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.
54
Verwaltung von Listen mit Variablen
>>> liste1 = [4, 13, 21, 33, 34, 42]
>>> liste2 = liste1
>>> liste2[1] = 8
>>> liste2
[4, 8, 21, 33, 34, 42]
>>> liste1
[4, 8, 21, 33, 34, 42]
>>> liste1 = [4, 13, 21, 33, 34, 42]
>>> liste1
[4, 13, 21, 33, 34, 42]
>>> liste2
[4, 8, 21, 33, 34, 42]
>>> liste2[0] = 3
>>> liste2
[3, 8, 21, 33, 34, 42]
>>> liste1
[4, 13, 21, 33, 34, 42]
55
Listen als Objekte
Listen sind - in Python - Objekte der Klasse list. Listen bringen daher eine
Reihe vordefinierter Operationen (Methoden) zur Verarbeitung mit.
>>> adressen1 = ['[email protected]', '[email protected]', '[email protected]',
'[email protected], '[email protected]', '[email protected]', '[email protected]']
>>> listeAdressen.append('[email protected]')
>>> listeAdressen
['[email protected]', '[email protected]', '[email protected]', '[email protected]',
'[email protected]', '[email protected]', '[email protected]', '[email protected]']
>>> listeAdressen.insert(3, '[email protected]')
>>> listeAdressen
['[email protected]', '[email protected]', '[email protected]', '[email protected]',
'[email protected]', '[email protected]', '[email protected]', '[email protected]',
'[email protected]']
>>> listeAdressen.remove('[email protected]')
>>> listeAdressen
['[email protected]', '[email protected]', '[email protected]', '[email protected]',
'[email protected]', '[email protected]', '[email protected]', '[email protected]']
>>> listeAdressen.extend(['[email protected]', '[email protected]'])
>>> listeAdressen
['[email protected]', '[email protected]', '[email protected]', '[email protected]',
'[email protected]', '[email protected]', '[email protected]', '[email protected]',
'[email protected]', '[email protected]']
56
Listen als Objekte
objektorientiert: L.Listenoperation
>>> liste = ['a', 'b']
>>> liste
['a', 'b']
>>> id(liste)
20306640
>>> liste.append('c')
>>> liste
['a', 'b', 'c']
Veränderung einer
>>> id(liste)
bestehenden Listen
20306640
>>> liste = ['a', 'b']
>>> liste
['a', 'b']
>>> id(liste)
20306120
>>> liste[0] = 'c'
>>> liste
['c', 'b']
Veränderung einer
>>> id(liste)
bestehenden Listen
20306120
funktional: L = Listenkonstruktor
>>> liste = ['a', 'b']
>>> liste
['a', 'b']
>>> id(liste)
10126560
>>> liste + ['c']
['a', 'b', 'c']
>>> id(liste + ['c'])
20307000
>>> liste
['a', 'b']
>>> id(liste)
10126560
>>> liste[0:2]
['a', 'b']
>>> id(liste[0:2])
19981656
>>> liste
['a', 'b']
>>> id(liste)
Erzeugung neuer Listen
10126560
57
Teil 4
Fallstudie - Logdatei
58
Logdateien
Logdateien werden benutzt, um Information über Prozesse, die auf einem Computersystem
laufen, automatisiert zu protokollieren. Logdateien werden von bestimmten Rechnern für
unterschiedlichste Zwecke erstellt.
131.246.0.13 - - [24/Jul/2012:12:44:21 +0200] "GET /informatik/index.html HTTP/1.1" 200 512
131.246.0.13 - - [24/Jul/2012:12:44:25 +0200] "GET /informatik/bild.png HTTP/1.1" 200 805
# ...
Beispiele:
 Ein Schulserver protokolliert (je nach Einstellung) u.a., wann welches Programm auf
welchem Rechner benutzt wurde.
 Web-Serber protokollieren u.a., wer welche Webseite wann aufgerufen hat.
 Die Rechner von Telekommunikationsanbietern protokollieren u.a., wann und wo welches
Handy eingeschaltet war.
Beachte:
Mit der Erstellung von Logdateien eng verbunden ist das Problem der
Vorratsdatenspeicherung. Häufig werden in Logdateien Daten über einen längeren Zeitraum
gespeichert, die personenbeziehbar sind und Rückschlüsse auf das Verhalten der betreffenden
Personen zulassen. (siehe z.B.: http://www.zeit.de/datenschutz/malte-spitz-vorratsdaten)
59
Eine Webserver-Logdatei
In einer Webserver-Logdatei werden alle Zugriffe auf Dateien, die zur Darstellung von
Webseiten benötigt werden, protokolliert. Wir betrachten im Folgenden die Daten einer
solchen Webserver-Logdatei (in etwas vereinfachter Form, da weitere Angaben weggelassen
sind):
131.246.0.13 - - [24/Jul/2012:12:44:21 +0200] "GET /informatik/index.html HTTP/1.1" 200 512
131.246.0.13 - - [24/Jul/2012:12:44:25 +0200] "GET /informatik/bild.png HTTP/1.1" 200 805
# ...
Erläuterung:
 131.246.0.13
IP-Adresse des aufrufenden Hosts
-
Benutzernamer, sofern erforderlich
-
Passwort, falls erforderlich
 [24/Jul/2012:12:44:21 +0200]
Zeitstempel bestehend aus
Datum, Uhrzeit und Zeitverschiebung
 "GET /informatik/index.html HTTP/1.1"
Anfrage an den Server
 200
Antwort des Servers
(200: erfolgreiche Anfrage)
 512
Dateigröße (Anzahl der Bytes)
60
Verwaltung von Logdatei-Daten
Wenn Daten einer Logdatei automatisiert analysiert weren sollen, dann sollten sie in einer gut
verarbeitbaren Form vorliegen.
Eine naheliegende Möglichkeit wäre, die einzelnen Einträge einer Logdatei als Zeichenketten
darzustellen und alle diese Zeichenketten mit einer Liste zu verwalten.
131.246.0.13 - - [24/Jul/2012:12:44:21 +0200] "GET /informatik/index.html HTTP/1.1" 200 512
131.246.0.13 - - [24/Jul/2012:12:44:25 +0200] "GET /informatik/bild.png HTTP/1.1" 200 805
# ...
[
'131.246.0.13 - - [24/Jul/2012:12:44:21 +0200] "GET /informatik/index.html HTTP/1.1" 200 512',
'131.246.0.13 - - [24/Jul/2012:12:44:25 +0200] "GET /informatik/bild.png HTTP/1.1" 200 805',
...
]
Aufgabe:
Welchen Nachteil hätte diese Darstellung der Daten mit Hilfe von Zeichenketten?
61
Verwaltung mit geschachtelten Listen
Wir werden im Folgenden versuchen, die Strukur der darzustellenden Daten besser zu
erfassen. Vorerst betrachten wir nur den Zeitstempel eines Datensatzes.
131.246.0.13 - - [24/Jul/2012:12:44:21 +0200] "GET /informatik/index.html HTTP/1.1" 200 512
131.246.0.13 - - [24/Jul/2012:12:44:25 +0200] "GET /informatik/bild.png HTTP/1.1" 200 805
# ...
>>> zeitstempel = [[24, 'Jul', 2012], [12, 44, 21], ['+', 2, 0]]
>>> zeitstempel
[[24, 'Jul', 2012], [12, 44, 21], ['+', 2, 0]]
>>> zeitstempel[0]
[24, 'Jul', 2012]
>>> zeitstempel[0][1]
...
>>> zeitstempel[1]
...
>>> zeitstempel[1][0]
...
>>> zeitstempel[1][0:2]
...
>>> zeitstempel[2][1]
...
62
Verwaltung mit geschachtelten Listen
Aufgabe:
(a) Wie würde man analog den Zeitstempel [21/Jan/2008:12:44:01 +0100] mit Listen
darstellen?
(b) Im Python-Dialog oben fehlen etliche Auswertungsergebnisse (hier angedeutet durch ...).
Stelle zunächst Vermutungen auf, was hier von Python als Ergebnis zurückgeliefert wird.
Überprüfe anschließend deine Vermutungen.
(c) Welche Vorteile hat die Darstellung strukturierter Daten mit geschachtelten Listen?
(d) Überlege dir eine strukturierte Listendarstellung für die Daten einer Logdatei.
131.246.0.13 - - [24/Jul/2012:12:44:21 +0200] "GET /informatik/index.html HTTP/1.1" 200 512
131.246.0.13 - - [24/Jul/2012:12:44:25 +0200] "GET /informatik/bild.png HTTP/1.1" 200 805
# ...
63
Datenverwaltung mit Tupeln
Daten mit einer komplexen Struktur lassen sich oft auch (in Python) als Tupel verwalten.
Beachte, dass hier bei der Datendarstellung runde Klammern benutzt werden .
131.246.0.13 - - [24/Jul/2012:12:44:21 +0200] "GET /informatik/index.html HTTP/1.1" 200 512
131.246.0.13 - - [24/Jul/2012:12:44:25 +0200] "GET /informatik/bild.png HTTP/1.1" 200 805
# ...
>>> zeitstempel = ((24, 'Jul', 2012), (12,
44, 21), ('+', 2, 0))
>>> zeitstempel
((24, 'Jul', 2012), (12, 44, 21), ('+', 2, 0))
>>> zeitstempel[0]
(24, 'Jul', 2012)
>>> zeitstempel[0][1]
'Jul'
>>> zeitstempel[1]
(12, 44, 21)
>>> zeitstempel[1][0]
12
>>> zeitstempel[1][0:2]
(12, 44)
>>> zeitstempel[2][1]
2
>>> zeitstempel = [[24, 'Jul', 2012], [12,
44, 21], ['+', 2, 0]]
>>> zeitstempel
[[24, 'Jul', 2012], [12, 44, 21], ['+', 2, 0]]
>>> zeitstempel[0]
[24, 'Jul', 2012]
>>> zeitstempel[0][1]
'Jul'
>>> zeitstempel[1]
[12, 44, 21]
>>> zeitstempel[1][0]
12
>>> zeitstempel[1][0:2]
[12, 44]
>>> zeitstempel[2][1]
2
64
Unterschied Tupel - Liste
Aufgabe:
Der folgende Python-Dialog zeigt einen weiteren Unterschied zwischen Listen und Tupeln.
Beschreibe diesen Unterschied.
>>> datum1 = [24, 'Jul', 2012]
>>> datum1
[24, 'Jul', 2012]
>>> datum1[0] = 25
>>> datum1
[25, 'Jul', 2012]
>>> datum2 = (24, 'Jul', 2012)
>>> datum2
(24, 'Jul', 2012)
>>> datum2[0] = 25
Traceback (most recent call last):
File ...
datum2[0] = 25
TypeError: 'tuple' object does not support
item assignment
>>> uhrzeit1 = [12, 44]
>>> uhrzeit1 = uhrzeit1 + [1]
>>> uhrzeit1
[12, 44, 1]
>>> uhrzeit2 = (12, 44)
>>> uhrzeit2 = uhrzeit2 + (1)
Traceback (most recent call last):
File ...
uhrzeit2 = uhrzeit2 + (1)
TypeError: can only concatenate tuple (not
"int") to tuple
65
Fachkonzept - Tupel
Eine Tupel ist eine Datenstruktur, bei der mehrere Daten zu einer Einheit zusammengefasst
werden.
Tupel weisen einige Ähnlichkeiten mit Listen auf, unterscheiden sich aber in einigen Punkten
wesentlich von Listen.
Ein lesender Zugriff auf Tupelelemente erfolgt genau wie bei Listen. Ein schreibender Zugriff
auf Tupelelemente ist - anders als bei Listen - nicht möglich. Man kann ein Tupel nicht dadurch
abändern, dass man ein Element durch ein anderes ersetzt. Wenn man ein Tupel abändern
will, muss man ein neues Tupelobjekt erzeugen.
>>> datum = (24, 'Jul', 2012)
>>> uhrzeit = (12, 44, 21)
>>> zeitverschiebung = ('+', 2, 0)
>>> zeitstempel = (datum, uhrzeit,
zeitverschiebung)
>>> zeitstempel
((24, 'Jul', 2012), (12, 44, 21), ('+', 2, 0))
Tupel zusammenpacken
>>> zeitstempel = ((25, 'Jul', 2012), (10,
20, 0), ('+', 2, 0))
>>> (datum, uhrzeit, zeitverschiebung) =
zeitstempel
>>> datum
(25, 'Jul', 2012)
>>> uhrzeit
(10, 20, 0)
>>> zeitverschiebung
('+', 2, 0)
Tupel auspacken
66
Datenverwaltung mit Tupeln und Listen
Aufgabe:
Die Daten einer Webserver-Logdatei sollen mit Hilfe von Listen und Tupeln adäquat dargestellt
werden. Was könnte man mit Tupeln erfassen, was sollte man mit Listen erfassen?
131.246.0.13 - - [24/Jul/2012:12:44:21 +0200] "GET /informatik/index.html HTTP/1.1" 200 512
131.246.0.13 - - [24/Jul/2012:12:44:25 +0200] "GET /informatik/bild.png HTTP/1.1" 200 805
# ...
Aufgabe:
Ergänze selbst weitere Datensätze. Entwickle geeignete Funktionen zur Analyse der Daten
einer Logdatei.
67
Teil 5
Fallstudie - Spiel des Lebens
68
Spiel des Lebens
Beim Spiel des Lebens geht es darum, ob einzelne Zellen in einer Welt, die nur aus Zellen
besteht, überleben oder ob sie absterben.
Spielregeln:
 Eine tote Zelle mit genau drei lebenden Nachbarn wird in der Folgegeneration neu geboren.
 Lebende Zellen mit weniger als zwei lebenden Nachbarn sterben in der Folgegeneration an
Einsamkeit.
 Eine lebende Zelle mit zwei oder drei lebenden Nachbarn bleibt in der Folgegeneration
lebend.
 Lebende Zellen mit mehr als drei lebenden Nachbarn sterben in der Folgegeneration an
Überbevölkerung.
69
Verwaltung der Spielwelt
Diese Welt kann man z.B. mit Hilfe von Listen darstellen:
zweidimensionale
Datenanordnung
Liste bestehend aus Listen
>>> welt = [[0, 0, 0, 0, 0], [0, 1, 1, 1, 0], [0, 0, 1, 0, 0], [0, 0, 1, 1, 0], [0, 0, 0, 0, 0]]
>>> welt
[[0, 0, 0, 0, 0], [0, 1, 1, 1, 0], [0, 0, 1, 0, 0], [0, 0, 1, 1, 0], [0, 0, 0, 0, 0]]
>>> welt[0][3]
...
>>> welt[1][2]
...
>>> welt[2][1]
...
>>> welt[2]
...
>>> [welt[0][3], welt[1][3], welt[2][3], welt[3][3], welt[4][3]]
...
70
Verwaltung der Spielwelt
Aufgabe: Entwickle ein Programm zur Ausgabe der Spielwelt auf dem Bildschirm.
# Initialisierung
welt = [[0, 0, 0, 0, 0], [0, 1, 1, 1, 0], [0, 0, 1, 0, 0], [0, 0, 1, 1, 0], [0, 0, 0, 0, 0]]
# Ausgabe
...
71
Algorithmus zur Spielsimulation
ALGORITHMUS neueWelt:
Übergabe: welt
FÜR i von 0 bis 4:
FÜR j von 0 bis 4:
anzahl = Anzahl der lebenden Nachbarn von welt[i][j]
# Eine tote Zelle mit genau drei lebenden Nachbarn
# wird in der Folgegeneration neu geboren.
WENN welt[i][j] == 0 und anzahl == 3:
welt[i][j] = 1
# Lebende Zellen mit weniger als zwei lebenden Nachbarn
# sterben in der Folgegeneration an Einsamkeit.
SONST WENN welt[i][j] == 1 und anzahl < 2:
welt[i][j] = 0
# ...
Rückgabe: welt
Aufgabe:
Wo steckt der Fehler?
Achtung: fehlerhaft!
72
Algorithmus zur Spielsimulation
ALGORITHMUS neueWelt:
Übergabe: welt
kopie = Kopie der Liste welt
FÜR i von 0 bis 4:
FÜR j von 0 bis 4:
anzahl = Anzahl der lebenden Nachbarn von welt[i][j]
# Eine tote Zelle mit genau drei lebenden Nachbarn
# wird in der Folgegeneration neu geboren.
WENN welt[i][j] == 0 und anzahl == 3:
kopie[i][j] = 1
# Lebende Zellen mit weniger als zwei lebenden Nachbarn
# sterben in der Folgegeneration an Einsamkeit.
SONST WENN welt[i][j] == 1 und anzahl < 2:
kopie[i][j] = 0
# ...
Rückgabe: kopie
So ist es korrekt!
73
Eine Kopie der Welt erzeugen
>>> welt = [[0, 0, 0, 0, 0], [0, 1, 1, 1, 0], [0, 0, 1, 0, 0], [0, 0, 1, 1, 0], [0, 0, 0, 0, 0]]
>>> kopie = welt[:]
>>> welt
[[0, 0, 0, 0, 0], [0, 1, 1, 1, 0], [0, 0, 1, 0, 0], [0, 0, 1, 1, 0], [0, 0, 0, 0, 0]]
>>> kopie
[[0, 0, 0, 0, 0], [0, 1, 1, 1, 0], [0, 0, 1, 0, 0], [0, 0, 1, 1, 0], [0, 0, 0, 0, 0]]
>>> kopie[2][2] = 0
>>> kopie
[[0, 0, 0, 0, 0], [0, 1, 1, 1, 0], [0, 0, 0, 0, 0], [0, 0, 1, 1, 0], [0, 0, 0, 0, 0]]
>>> welt
[[0, 0, 0, 0, 0], [0, 1, 1, 1, 0], [0, 0, 0, 0, 0], [0, 0, 1, 1, 0], [0, 0, 0, 0, 0]]
So funktioniert es nicht!
Aufgabe:
Wie kann man es besser machen?
74
Anzahl der Nachbarn zählen
anzahlLebendeNachbarn
2
x
3
[[0, 0, 0, 0, 0],
[0, 1, 1, 1, 0],
[0, 0, 1, 0, 0],
[0, 0, 1, 1, 0],
[0, 0, 0, 0, 0]]
y
welt
return
5
Black-Box-Modellierung
Aufgabe:
Entwickle eine Funktionsdefinition zu der beschriebenen Funktion und teste sie mit
verschiedenen Übergabedaten. Beachte, dass die Zellen an den Rändern der Welt weniger
Nachbarn haben.
75
Eine neue Welt erzeugen
neueWelt
[[0, 0, 0, 0, 0],
[0, 1, 1, 1, 0],
[0, 0, 1, 0, 0],
[0, 0, 1, 1, 0],
[0, 0, 0, 0, 0]]
welt
return
[[0, 0, 1, 0, 0]
[0, 1, 1, 1, 0],
[0, 0, 0, 0, 0],
[0, 0, 1, 1, 0],
[0, 0, 0, 0, 0]]
Black-Box-Modellierung
Aufgabe:
Implementiere diese Funktion. Du kannst dich dabei an dem oben gezeigten (verbesserten)
Algorithmus orientieren.
76
Spiel des Lebens
Aufgabe:
Es gibt zahlreiche interessante Fragestellungen zum Spiel des Lebens, z.B.: Gibt es Welten, die
sich nicht verändern? Weitere Fragestellungen ergeben sich aus dem Artikel bei Wikipedia.
Entwickle dein Simulationsprogramm entsprechend selbstständig weiter.
77
Verwaltung zweidim. Dateneinheiten
Häufig steht man vor dem Problem, eine zweidimensionale Dateneinheit zu verwalten. Hier
bietet es sich an, diese Dateneinheit aus Listen aufzubauen.
L[0][1]
L[0][0]
L[0][3]
L[0][2]
L[0][4]
L:
0
0
0
0
0
0
1
1
1
0
0
0
1
0
0
0
0
1
1
0
0
0
0
0
0
0
0
0
0
0
L[0]
0
1
1
1
0
L[1]
0
0
1
0
0
L[2]
0
0
1
1
0
L[3]
0
0
0
0
0
L[4]
L[4][0]
L[4][2]
L[4][1]
L[4][4]
L[4][3]
78
Verarbeitung zweidim. Dateneinheiten
Häufig steht man vor dem Problem, eine zweidimensionale Dateneinheit zu verwalten. Hier
bietet es sich an, diese Dateneinheit aus Listen aufzubauen.
L[0][1]
L[0][0]
L[0][3]
L[0][2]
L[0][4]
L:
# L: Liste bestehend aus Listen zur
Verwaltung einer 2-D-Dateneinheit
# n: Anzahl der Daten pro Zeile
bzw. Spalte
FÜR i von 0 bis n-1:
FÜR j von 0 bis n-1:
verarbeite L[i][j]
0
0
0
0
0
L[0]
0
1
1
1
0
L[1]
0
0
1
0
0
L[2]
0
0
1
1
0
L[3]
0
0
0
0
0
L[4]
L[4][0]
L[4][2]
L[4][1]
L[4][4]
L[4][3]
Fachkonzept - Datenstruktur
79
Datenstrukturen ermöglichen es, strukturierte Daten als Einheit zu verwalten.
3
6
19
21
'Losnummer'
38
41
4
9
17
37
38
39
18
23
28
36
38
46
4440674
'Superzahl'
4
'Ziehungstage'
'Sa + Mi'
'Laufzeit'
1
'Spiel 77'
False
'Super 6'
False
'Gluecksspirale'
False
Datenmodellierung mit den Datenstrukturen
"Liste" und "Tupel"
Fachkonzept - Datenstruktur
80
Zentrale Datenstrukturen in Python sind Listen und Tupel.
3
6
19
21
'Losnummer'
38
41
4
9
17
37
38
39
18
23
28
36
38
46
4440674
'Superzahl'
4
'Ziehungstage'
'Sa + Mi'
'Laufzeit'
1
'Spiel 77'
False
'Super 6'
False
'Gluecksspirale'
False
Implementierung mit den Datenstrukturen
"Liste" und "Tupel"
>>> lottoschein = [
[(3, 6, 19, 21, 38, 41), (4, 9, 17, 37, 38, 39), (18, 23,
28, 36, 38, 46)],
('Losnummer', 4440674),
('Superzahl', 4),
('Ziehungstage', 'Sa + Mi'),
('Laufzeit', 1),
('Spiel 77', False),
('Super 6', False),
('Gluecksspirale', False)
]
81
Fachkonzept - Datenstruktur
Datenstrukturen ermöglichen es, strukturierte Daten als Einheit zu verwalten.
>>> lottoschein = [
[(3, 6, 19, 21, 38, 41), (4, 9, 17, 37, 38, 39), (18, 23, 28, 36, 38, 46)],
('Losnummer', 4440674),
('Superzahl', 4),
('Ziehungstage', 'Sa + Mi'),
('Laufzeit', 1),
('Spiel 77', False),
('Super 6', False),
('Gluecksspirale', False)
]
Datenmodellierung mit den Datenstrukturen
"Liste" und "Tupel"
82
Übungen - Datenstruktur
Aufgabe: Zugriff auf geschachtelte Daten
Ergänze die Ergebnisse. Überprüfe sie mit Python.
>>> lottoschein = [
[(3, 6, 19, 21, 38, 41), (4, 9, 17, 37, 38, 39), (18, 23, 28, 36, 38, 46)],
('Losnummer', 4440674),
('Superzahl', 4),
('Ziehungstage', 'Sa + Mi'),
('Laufzeit', 1),
('Spiel 77', False),
('Super 6', False),
('Gluecksspirale', False)
]
>>> lottoschein[0][1]
...
>>> lottoschein[0][1][2]
...
>>> lottoschein[1][0]
...
Aufgabe: Datenmodellierung
Wie könnte man die Gewinnquoten beim Lotto mit
Datenstrukturen erfassen?
83
Übungen - Datenstruktur
Aufgabe: Magische Quadrate
Ein magisches Quadrat ist eine quadratische Anordnung
der Zahlen 1, 2, ..., sodass die Summe der Zahlen aller
Zeilen, Spalten und der beiden Diagonalen gleich ist.
Eines der bekanntesten magischen Quadrate ist auf dem
Kupferstich Melencolia I von Albrecht Dürer zu sehen.
Entwickle ein Programm, mit dem man ein quadratisches
Zahlenfeld daraufhin überprüfen kann, ob es ein
magisches Quadrat darstellt.
84
Übungen - Datenstruktur
Aufgabe: Sudoku
Deine Aufgabe ist es, ein Programm zu entwickeln, mit
dem man Sudoku-Lösungsvorschläge auf ihre Korrektheit
überprüfen kann. Das Programm soll gegebenenfalls
Rückmeldungen über die gefundenen Fehler machen.
Überlege dir zunächst eine Datenstruktur zur Verwaltung
von Sudokus. Entwickle anschließend ein Verfahren, mit
dem man die Korrektheit von Sudokus testen kann und
implementiere es in Python.
Für Experten: Viel schwieriger ist es, zu einem
vorgegebenen Sudoku-Rätsel eine Lösung automatisiert
zu erzeugen.
3
1
9
9
5
8
6
8
6
4
3
1
2
6
2
4
1
8
9
7
5
3
4
6
7
8
9
1
2
6
7
2
1
9
5
3
4
8
1
9
8
3
4
2
5
6
7
8
5
9
7
6
1
4
2
3
4
2
6
8
5
3
7
9
1
7
1
3
9
2
4
8
5
7
9
6
1
5
7
3
2
8
4
2
8
7
4
1
9
6
3
5
3
4
5
2
8
6
1
7
9
Herunterladen