Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

Datenverwaltung mit Datenstrukturen Klaus Becker 2016.

Ähnliche Präsentationen


Präsentation zum Thema: "Datenverwaltung mit Datenstrukturen Klaus Becker 2016."—  Präsentation transkript:

1 Datenverwaltung mit Datenstrukturen Klaus Becker 2016

2 2 Datenverwaltung mit Datenstrukturen Anna Cem Maria Paul Luis Tara Noah Julia

3 3 Teil 1 Fallstudie - Aktienkurse

4 4 Aktienkurse Jeden Tag, an dem die Börse geöffnet hat, wird am Ende des Tages ein neuer DAX-Wert ermittelt. Die Abbildung zeigt, dass der DAX-Wert vielen Schwankungen unterliegt. Interessant wäre es, wenn man DAX-Werte automatisiert verarbeiten könnte. Von Interesse sind zum Beispiel das Maximum und das Minimum in einem Zeitintervall oder auch günstige (Ver)-Kauftermine. Ziel in diesem Abschnitt ist es, solche Verarbeitungseinheiten zu entwickeln. Quelle: https://commons.wikimedia.org/wiki/File:DAX.png

5 5 Datenverwaltung # Datenverwaltung dax0 = 10944.97 # 30.06.2015 dax1 = 11083.20 # 29.06.2015 dax2 = 11492.43 # 26.06.2015 dax3 = 11473.13 # 25.06.2015 dax4 = 11471.26 # 24.06.2015... # Datenverarbeitung print(dax0) print(dax1) print(dax2) print(dax3) print(dax4)... 30.06.2015: 10944.97 29.06.2015: 11083.20 26.06.2015: 11492.43 25.06.2015: 11473.13 24.06.2015: 11471.26 Verwendung vieler Variablen Verwendung einer Variablen sowie einer Liste als "Datencontainer" Aufgabe: Welchen Vorteil hat es, wenn man eine Liste als eine Art "Datencontainer" benutzt? Auszug aus der DAX- Kursentwicklung. # Datenverwaltung daxListe = [10944.97, 11083.20, 11492.43, 11473.13, 11471.26] # Datenverarbeitung print(daxListe)

6 6 Zugriff auf Listenelemente >>> daxListe = [10944.97, 11083.20, 11492.43, 11473.13, 11471.26, 11542.54, 11460.50] >>> daxListe[0]... >>> daxListe[1]... >>> daxListe[6]... >>> daxListe[10]... >>> len(daxListe)... >>> daxListe[len(daxListe)-1]... >>> daxListe... >>> daxListe[1] = 11083.21 >>> daxListe... lesender Zugriff schreibender Zugriff Aufgabe: Führe den Dialog selbst durch. Stelle Vermutungen auf, was die Operationen jeweils bewirken. Führe weitere Experimente durch, um die Vermutungen zu bestätigen oder zu widerlegen.

7 7 Zugriff auf Teillisten >>> daxListe = [10944.97, 11083.20, 11492.43, 11473.13, 11471.26, 11542.54, 11460.50] >>> daxListe[0:2]... >>> daxListe[3:6]... >>> daxListe[3:3]... >>> daxListe[0:len(daxListe)]... >>> daxListe[0:len(daxListe)]... >>> daxListe[5:2] … >>> daxListe[7:10] … Aufgabe: Führe den Dialog selbst durch. Stelle Vermutungen auf, was die Angaben innerhalb der eckigen Klammern jeweils bewirken. Führe weitere Experimente durch, um die Vermutungen zu bestätigen oder zu widerlegen.

8 8 Zugriff auf Teillisten >>> daxListe = [10944.97, 11083.20, 11492.43, 11473.13, 11471.26, 11542.54, 11460.50] >>> daxListe[3:]... >>> daxListe[:3]... >>> daxListe[:]... Aufgabe: Führe den Dialog selbst durch. Stelle Vermutungen auf, was die Angaben innerhalb der eckigen Klammern jeweils bewirken. Führe weitere Experimente durch, um die Vermutungen zu bestätigen oder zu widerlegen.

9 9 Eine Liste durchlaufen # Liste initialisieren daxListe = [10944.97, 11083.20, 11492.43, 11473.13, 11471.26] # Liste durchlaufen i = 0 while i < len(daxListe): print(daxListe[i]) i = i+1 Aufgabe: Wie funktioniert das Durchlaufen aller Listenelemente? Teste beide Programme. Teste auch den range-Operator. Für viele Anwendungen muss man alle Listenelemente durchlaufen. In Python gibt es hierfür mehrere Möglichkeiten. Liste über den Index durchlaufen # Liste initialisieren daxListe = [10944.97, 11083.20, 11492.43, 11473.13, 11471.26] # Liste durchlaufen anzahlElemente = len(daxListe) for i in range(anzahlElemente): print(daxListe[i]) >>> 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] Liste über den Index durchlaufen 10 L 0 15 1 21 2 33 3 37 4 40 5

10 10 Eine Liste durchlaufen # Liste initialisieren daxListe = [10944.97, 11083.20, 11492.43, 11473.13, 11471.26] # Liste durchlaufen for wert in daxListe: print(wert) Aufgabe: Teste auch diese Version. Worin bestehen die Vorteile der jeweiligen Möglichkeiten? # Liste initialisieren daxListe = [10944.97, 11083.20, 11492.43, 11473.13, 11471.26] # Liste durchlaufen anzahlElemente = len(daxListe) for i in range(anzahlElemente): print(daxListe[i]) Liste über den Index durchlaufenListe über die Elemente durchlaufen Für viele Anwendungen muss man alle Listenelemente durchlaufen. In Python gibt es hierfür mehrere Möglichkeiten. 10 L 0 15 1 21 2 33 3 37 4 40 5

11 11 Anwendung – maximaler Kurswert Der Aktionindex DAX unterliegt vielen Schwankungen. Bei der Analyse ist es manchmal von Interesse, den maximalen oder minimalen Kurswert zu bestimmen. Aufgabe: Überlege dir jeweils zunächst einen geeigneten Algorithmus. Entwickle anschließend entsprechende Funktionsdefinitionen und teste sie ausgiebig. Entwickle auch Funktionen, mit denen man das Minimum und dessen Index bei einer Zahlenliste bestimmen kann.

12 12 Weitere Anwendungen Aufgabe: Entwickle eine Funktion, mit der man den Durchschnittswert aller Kurswerte bestimmen kann. Aufgabe: Entwickle eine Funktion, mit der man ermitteln kann, wie oft die Kurswerte über einem übergebenen Schwellenwert gelegen haben.

13 13 Fachkonzept - Liste Eine Liste ist eine Datenstruktur zur dynamischen Verwaltung endlicher Folgen von Daten.  Listen werden in Python mit eckigen Klammern dargestellt.  Alle Elemente einer 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. # Liste zur Verwaltung von E-Mailadressen ['amueller@gmx.de', 'carla2@hotmail.org', 'herbert.fluhr@web.de'] # Liste zur Verwaltung von Lottozahlen [1, 12, 21, 31, 37, 46] # Liste zur Verwaltung erzielter Tore ['Lukas Podolski', 14] # Liste zur Verwaltung von Personendaten ['Lisa', 'Schmitz', [25, 2, 1995]] # Liste ohne Listenelemente []

14 14 Liste als sequentieller Datentyp Index >>> L = [10, 15, 21, 33, 37, 40] >>> L[0] 10 >>> L[1] 15 lesender Zugriff >>> L = [10, 15, 21, 33, 37, 40] >>> L [10, 15, 21, 33, 37, 40] >>> L[4] = 36 >>> L [10, 15, 21, 33, 36, 40] schreibender Zugriff 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. 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. 10 L 0 15 1 21 2 33 3 37 4 40 5 Element

15 15 Elemente in eine Liste hinzufügen >>> daxListe = [11180.50, 10944.97, 11083.20] >>> daxListe [11180.5, 10944.97, 11083.2] >>> daxListe + [11492.43] [11180.5, 10944.97, 11083.2, 11492.43] >>> daxListe... >>> daxListe = daxListe + [11492.43] >>> daxListe... >>> daxListe = daxListe + [11473.13, 11471.26] >>> daxListe... >>> daxListe = [11099.35] + daxListe >>> daxListe... >>> daxListe = [11058.39] + daxListe >>> daxListe... >>> Aufgabe: Führe den Python-Dialog selbst durch und erkläre die jeweils von Python erzeugten Ergebnisse.

16 16 Elemente hinzufügen und löschen >>> daxListe = [11058.39, 11099.35, 10944.97, 11083.2, 11492.43, 11473.13, 11471.26] >>> daxListe = daxListe[:2] + [11180.5] + daxListe[2:] >>> daxListe … >>> daxListe = daxListe[:2] + daxListe[3:] >>> daxListe … Aufgabe: Stelle zunächst eine Vermutung über das von Python erzeugte Ergebnis auf. Überprüfe anschließend die Vermutung. Wie kann man ein Listenelement an beliebiger Stelle hinzufügen oder löschen?

17 17 Konkatenation von Listen 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. >>> liste = [] >>> liste [] >>> liste = liste + ['n'] >>> liste... >>> liste = liste + ['t'] >>> liste... >>> liste = ['o'] + liste >>> liste... >>> liste = liste + ['a', 'g'] >>> liste... >>> liste = ['M'] + liste >>> liste... >>> a = [1] >>> b = [2] >>> c = [3] >>> a = a+b >>> b = a+c >>> c = c+b >>> a... >>> b... >>> c...

18 18 Weitere Listenoperationen Listen sind - in Python - Objekte der Klasse list. Listen bringen eine Reihe vordefinierter Operationen (Methoden) zur Verarbeitung mit. >>> adressen1 = ['amueller@gmx.de', 'carla2@hotmail.org', 'herbert.fluhr@web.de', 'petra@dahm.de, 'ewen@t-online.de', 't_schmidt@web.de', 'nicole.weber@gmx.de'] >>> listeAdressen.append('tom.brand@schule.de') >>> listeAdressen ['amueller@gmx.de', 'carla2@hotmail.org', 'herbert.fluhr@web.de', 'petra@dahm.de', 'ewen@t-online.de', 't_schmidt@web.de', 'nicole.weber@gmx.de', 'tom.brand@schule.de'] >>> listeAdressen.insert(3, 'katrin12@yahoo.com') >>> listeAdressen ['amueller@gmx.de', 'carla2@hotmail.org', 'herbert.fluhr@web.de', 'katrin12@yahoo.com', 'petra@dahm.de', 'ewen@t-online.de', 't_schmidt@web.de', 'nicole.weber@gmx.de', 'tom.brand@schule.de'] >>> listeAdressen.remove('carla2@hotmail.org') >>> listeAdressen ['amueller@gmx.de', 'herbert.fluhr@web.de', 'katrin12@yahoo.com', 'petra@dahm.de', 'ewen@t-online.de', 't_schmidt@web.de', 'nicole.weber@gmx.de', 'tom.brand@schule.de'] >>> listeAdressen.extend(['carla2@hotmail.org', 'carl3@hotmail.org']) >>> listeAdressen ['amueller@gmx.de', 'herbert.fluhr@web.de', 'katrin12@yahoo.com', 'petra@dahm.de', 'ewen@t-online.de', 't_schmidt@web.de', 'nicole.weber@gmx.de', 'tom.brand@schule.de', 'carla2@hotmail.org', 'carl3@hotmail.org']

19 19 Anwendung - Schwellenwert Aufgabe: Gesucht ist eine Funktion, die in einer übergebenen Kurswertliste und einem übergebenen Kurswert (als Schwellenwert) eine Liste mit all den Werten zurückliefert, die über dem vorgegebenen Schwellenwert liegen.

20 20 Anwendung – Kursschwankungen Aufgabe: Hier sollen jetzt ausgehend von einer Liste mit Kurswerten alle Kurszu- und Kursabnahmen bestimmt und in einer neuen Liste gespeichert werden. Entwickle zunächst einen geeigneten Algorithmus. Achte auf die Grenzen der Indexwerte. Berücksichtige auch den Fall, dass in der übergebenen Liste weniger als 2 Elemente sind. Entwickle anschließend eine entsprechende Funktionsdefinition und teste sie ausgiebig. >>> daxListe = [11058.39, 11099.35, 10944.97, 11083.2, 11492.43, 11473.13, 11471.26] >>> kursschwankungen = [] >>> kursAenderung = round(daxListe[1] - daxListe[0], 2) >>> kursAenderung 40.96 >>> kursschwankungen = kursschwankungen + [kursAenderung] >>> kursschwankungen [40.96] >>> …

21 21 Verwaltung komplexer Daten # Datenverwaltung daxListe = [10944.97, 11083.20, 11492.43, 11473.13, 11471.26] 30.06.2015: 10944.97 29.06.2015: 11083.20 26.06.2015: 11492.43 25.06.2015: 11473.13 24.06.2015: 11471.26 Liste mit Tupeln Tupel aus e. Zeichenkette und e. Zahl Auszug aus der DAX- Kursentwicklung. # Datenverwaltung daten = [('2015-06-30', 10944.97), ('2015-06-29', 11083.2), ('2015-06-26', 11492.43), ('2015-06-25', 11473.13), ('2015-06-24', 11471.26)] Liste mit Zahlen

22 22 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

23 23 Zugriff auf die Elemente >>> daten = [('2015-06-30', 10944.97), ('2015-06-29', 11083.2), ('2015-06-26', 11492.43), ('2015-06-25', 11473.13), ('2015-06-24', 11471.26)] >>> daten[0] ('2015-06-30', 10944.97) >>> daten[0][0]... >>> daten[0][1]... >>> daten[2][1]... >>> daten[3][0]... Aufgabe: Stelle Vermutungen auf, was Python als Ergebnisse zurückliefert. Überprüfe deine Vermutungen, indem du den Python-Dialog selbst führst.

24 24 Anwendung – maximaler Kurswert Aufgabe: Ändere die Funktion zur Bestimmung des maximalen Kurswertes so ab, dass sie Listen mit Datum-Kurswert-Tupeln verarbeiten kann.

25 25 Anwendung - Schwellenwert Aufgabe: Gesucht ist eine Funktion, die in einer übergebenen Kurswertliste und einem übergebenen Kurswert (als Schwellenwert) eine Liste mit all den Tagen zurückliefert, an denen der Kurswert über dem vorgegebenen Schwellenwert lag.

26 26 Anwendung – längste Gewinnstrecke Aufgabe: Der DAX-Index steigt und fällt. Manchmal steigt er über etliche Tage hinweg. Gesucht ist eine Funktion, die in einer übergebenen Kurswertliste die längste Sequenz von steigenden Werten ermittelt und das Anfangs- und Enddatum dieser Sequenz zurück liefert.

27 27 Anwendung – gleitende Mittelwerte Aufgabe: Der DAX-Index verhält sich meist sehr sprunghaft. Um längerfristige Trends besser beschreiben zu können, erstellt man sogenannte gleitende Mittelwerte. Man bildet hierzu jeweils den Durchschnitt von z.B. 7 aufeinander folgenden Tagen. Gesucht ist eine Funktion, die aus einer übergebenen Kurswertliste (und ggf. einer Anzahl von Tagen) eine neue Liste mit gleitenden Mittelwerten (zu der vorgegebenen Anzahl von Tagen) bestimmt und zurückliefert.

28 28 Anwendung – Gewinnstrategie Aufgabe: Gesucht ist eine Funktion, mit der man den Gewinn bei folgender Strategie bestimmt: Wenn die Kurslinie über den gleitenden Mittelwert steigt: kaufen! Wenn die Kurslinie unter den gleitenden Mittelwert fällt: verkaufen!

29 29 Kurswertlisten automatisiert erstellen Es gibt zahlreiche Webseiten im Internet, die Daten zur Entwicklung des DAX bereit stellen. Siehe z.B.: https://de.finance.yahoo.com/q/hp?s=^GDAXI&b=26&a=10&c=1990&e=4&d=06&f=2015&g=d.

30 def aktienkursListe(csvDatei): try: datei = open(csvDatei, 'r', encoding='iso-8859-1') liste = [] for zeile in datei: jahr = zeile[0:4] if jahr != 'Date': daten = zeile.strip().split(',') kurs = round(float(daten[6]), 2) liste = liste + [kurs] datei.close() return liste except: return [] 30 Kurswertlisten automatisiert erstellen Aufgabe: Probiere das selbst aus. Erstelle so auch eine Liste mit allen Kursdaten des Jahres 2015. Entwickle auch eine Funktion, die eine Liste mit Datentupeln zurückliefert. Date,Open,High,Low,Close,Volume,Adj Close 2015-06-30,11058.040039,11137.139648,10897.969727,10944.969727,131523600,10944.969727 2015-06-29,11404.709961,11409.80957,10964.240234,11083.200195,130184700,11083.200195 2015-06-26,11387.129883,11561.830078,11373.44043,11492.429688,91723700,11492.429688 2015-06-25,11410.620117,11594.240234,11352.400391,11473.129883,73555500,11473.129883 2015-06-24,11566.349609,11589.349609,11364.450195,11471.259766,91865500,11471.259766 CSV-Format >>> aktienkursListe('table.csv') [10944.97, 11083.2, 11492.43, 11473.13, 11471.26]

31 31 Kopie einer Liste erstellen Listen sind (in Python) veränderbare Objekte und verhalten sich manchmal anders als unveränderbare Objekte wie z.B. Zahlen. Wir verdeutlichen das in diesem Abschnitt anhand eines einfachen Kopierproblems aus. Betrachte folgende Situation: Mit einer Liste werden die Kurswerte eines bestimmten Zeitraums (z.B. eines Jahres) verwaltet. Bevor neue Kurwerte hinzugefügt werden sollen, soll erst einmal eine Kopie der bereits bestehenden Liste erzeugt werden. Wir spielen das im Kleinen einmal hier durch. Zum Hinzufügen von neuen Listenelementen verwenden wir die vordefinierte Listenoperation extend. >>> daxListe = [11058.39, 11099.35, 10944.97, 11083.2, 11492.43] >>> daxListeNeu = daxListe >>> daxListeNeu.extend([11473.13, 11471.26]) >>> daxListeNeu... >>> daxListe... Teste auch mit dem Python-Tutor (http://pythontutor.com/).

32 32 Kopie einer Liste erstellen Hier zwei weitere Versionen. Teste ebenfalls. Erkläre das Verhalten. >>> daxListe = [11058.39, 11099.35, 10944.97, 11083.2, 11492.43] >>> daxListeNeu = daxListe[:] >>> daxListeNeu.extend([11473.13, 11471.26]) >>> daxListeNeu... >>> daxListe... >>> daxListe = [11058.39, 11099.35, 10944.97, 11083.2, 11492.43] >>> daxListeNeu = daxListe >>> daxListeNeu = daxListeNeu + [11473.13, 11471.26] >>> daxListeNeu... >>> daxListe...

33 33 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]) >>> [4, 13, 21, 33, 34, 42] [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. >>> liste1 = [4, 13, 21, 33, 34, 42] >>> id(liste1) 12289008 >>> type(liste1) >>> liste1 [4, 13, 21, 33, 34, 42]

34 34 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]

35 35 Listen als Objekte Listen sind - in Python - Objekte der Klasse list. Listen bringen eine Reihe vordefinierter Operationen (Methoden) zur Verarbeitung mit. >>> adressen1 = ['amueller@gmx.de', 'carla2@hotmail.org', 'herbert.fluhr@web.de', 'petra@dahm.de, 'ewen@t-online.de', 't_schmidt@web.de', 'nicole.weber@gmx.de'] >>> listeAdressen.append('tom.brand@schule.de') >>> listeAdressen ['amueller@gmx.de', 'carla2@hotmail.org', 'herbert.fluhr@web.de', 'petra@dahm.de', 'ewen@t-online.de', 't_schmidt@web.de', 'nicole.weber@gmx.de', 'tom.brand@schule.de'] >>> listeAdressen.insert(3, 'katrin12@yahoo.com') >>> listeAdressen ['amueller@gmx.de', 'carla2@hotmail.org', 'herbert.fluhr@web.de', 'katrin12@yahoo.com', 'petra@dahm.de', 'ewen@t-online.de', 't_schmidt@web.de', 'nicole.weber@gmx.de', 'tom.brand@schule.de'] >>> listeAdressen.remove('carla2@hotmail.org') >>> listeAdressen ['amueller@gmx.de', 'herbert.fluhr@web.de', 'katrin12@yahoo.com', 'petra@dahm.de', 'ewen@t-online.de', 't_schmidt@web.de', 'nicole.weber@gmx.de', 'tom.brand@schule.de'] >>> listeAdressen.extend(['carla2@hotmail.org', 'carl3@hotmail.org']) >>> listeAdressen ['amueller@gmx.de', 'herbert.fluhr@web.de', 'katrin12@yahoo.com', 'petra@dahm.de', 'ewen@t-online.de', 't_schmidt@web.de', 'nicole.weber@gmx.de', 'tom.brand@schule.de', 'carla2@hotmail.org', 'carl3@hotmail.org']

36 36 Listen als Objekte >>> liste = ['a', 'b'] >>> liste ['a', 'b'] >>> id(liste) 20306640 >>> liste.append('c') >>> liste ['a', 'b', 'c'] >>> id(liste) 20306640 >>> liste = ['a', 'b'] >>> liste ['a', 'b'] >>> id(liste) 20306120 >>> liste[0] = 'c' >>> liste ['c', 'b'] >>> id(liste) 20306120 >>> 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) 10126560 Erzeugung neuer Listen Veränderung einer bestehenden Listen objektorientiert: L.Listenoperation funktional: L = Listenkonstruktor

37 37 Teil 2 Fallstudie - Lottosimulation

38 38 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.

39 39 Datenverwaltung mit Listen Die Daten bei einer Lotto-Ziehung (ohne Zusatzzahl) sollen mit Hilfe von Python verwaltet werden. Wie könnte man das mit Hilfe von Listen machen? # Datenverwaltung ziehung = [25, 40, 44, 1, 45, 21] tipp = [1, 12, 21, 31, 37, 46] Aufgabe: Erstelle ein Programm, das die folgende Ausgabe erzeugt. >>> Kugel 1 : 25 Kugel 2 : 40 Kugel 3 : 44 Kugel 4 : 1 Kugel 5 : 45 Kugel 6 : 21

40 40 Datenverwaltung mit Listen Die Daten bei einer Lotto-Ziehung (ohne Zusatzzahl) sollen mit Hilfe von Python verwaltet werden. Wie könnte man das mit Hilfe von Listen machen? # Datenverwaltung 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, ] 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, ]

41 41 Anzahl der Richtigen Ziel ist, es, die Anzahl der richtig getippten Zahlen mit einer Funktion zu ermitteln. anzahlRichtige 2 ziehung tipp

42 42 Anzahl der Richtigen Aufgabe: Entwickle eine Funktionsdefinition für eine (oder beide) Version(en) der Datenverwaltung. anzahlRichtige 2 ziehung tipp

43 43 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

44 44 Ziehung automatisiert erzeugen Aufgabe: Entwickle eine Funktionsdefinition für eine (oder beide) Version(en) der Datenverwaltung. neueZiehung >>> from random import randint >>> randint(1, 49) 44 >>> randint(1, 49) 6

45 45 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 geeignete Funktionen zur Ermittlung der Gewinnchancen beim Lotto. Mit den Funktionen 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. (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.

46 46 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.

47 47 Teil 3 Fallstudie - Logdatei

48 48 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. 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) 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.

49 49 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)

50 50 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?

51 51 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]...

52 52 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 #...

53 53 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

54 54 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

55 55 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

56 56 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.

57 57 Teil 4 Fallstudie - Spiel des Lebens

58 58 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.

59 59 Verwaltung der Spielwelt Diese Welt kann man z.B. mit Hilfe von Listen darstellen: >>> 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]]... Liste bestehend aus Listen zweidimensionale Datenanordnung

60 60 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...

61 61 Algorithmus zur Spielsimulation Aufgabe: Wo steckt der Fehler? 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 Achtung: fehlerhaft!

62 62 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!

63 63 Kopie einer Liste erstellen Listen sind (in Python) veränderbare Objekte und verhalten sich manchmal anders als unveränderbare Objekte wie z.B. Zahlen. Wir verdeutlichen das in diesem Abschnitt anhand eines einfachen Kopierproblems aus. >>> liste1 = [4, 13, 21, 33, 34, 42] >>> liste2 = liste1 >>> liste2[1] = 8 >>> liste2... >>> liste1... Führe den Python-Dialog selbst durch. Kannst du die Ergebnisse erklären? Teste auch mit dem Python-Tutor (http://pythontutor.com/).

64 64 Kopie einer Liste erstellen Listen sind (in Python) veränderbare Objekte und verhalten sich manchmal anders als unveränderbare Objekte wie z.B. Zahlen. Wir verdeutlichen das in diesem Abschnitt anhand eines einfachen Kopierproblems aus. >>> liste1 = [4, 13, 21, 33, 34, 42] >>> liste2 = liste1[:] >>> liste2[1] = 8 >>> liste2... >>> liste1... Führe den Python-Dialog selbst durch. Kannst du die Ergebnisse erklären? Teste auch mit dem Python-Tutor (http://pythontutor.com/).

65 65 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: Warum funktioniert das hier nicht?

66 66 Eine Kopie der Welt erzeugen def kopieWelt(welt): … return kopie Aufgabe: Entwickle eine geeignete Funktionsdefinition. Teste gründlich.

67 67 Anzahl der Nachbarn zählen 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. anzahlLebendeNachbarn 2 x 3 y 5 return [[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

68 68 Eine neue Welt erzeugen Aufgabe: Implementiere diese Funktion. Du kannst dich dabei an dem bereits gezeigten (verbesserten) Algorithmus orientieren. neueWelt [[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]] return [[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

69 69 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. 00000 01110 00100 00110 00000 00000 01110 00100 00110 00000 L[0] L: L[1] L[2] L[3] L[4] L[0][0] L[0][1] L[0][2] L[0][3] L[0][4] L[4][0] L[4][1] L[4][2] L[4][3] L[4][4]

70 70 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. 00000 01110 00100 00110 00000 L[0] L: L[1] L[2] L[3] L[4] L[0][0] L[0][1] L[0][2] L[0][3] L[0][4] L[4][0] L[4][1] L[4][2] L[4][3] L[4][4] # 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]

71 71 Fachkonzept - Datenstruktur Datenstrukturen ermöglichen es, strukturierte Daten als Einheit zu verwalten. 'Losnummer' 36192138414917373839182328363846 'Superzahl' 'Ziehungstage' 'Laufzeit' 'Spiel 77' 'Super 6' 'Gluecksspirale' 4440674 4 'Sa + Mi' 1 False Datenmodellierung mit den Datenstrukturen "Liste" und "Tupel"

72 72 Fachkonzept - Datenstruktur 'Losnummer' 3 6 19 213841 4 9 17 373839 18 23 28 363846 'Superzahl' 'Ziehungstage' 'Laufzeit' 'Spiel 77' 'Super 6' 'Gluecksspirale' 4440674 4 'Sa + Mi' 1 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) ] Zentrale Datenstrukturen in Python sind Listen und Tupel.

73 73 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"

74 74 Übungen - Datenstruktur >>> 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: Zugriff auf geschachtelte Daten Ergänze die Ergebnisse. Überprüfe sie mit Python. Aufgabe: Datenmodellierung Wie könnte man die Gewinnquoten beim Lotto mit Datenstrukturen erfassen?

75 75 Ü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.

76 76 Ü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.

77 77 Teil 5 Fallstudie – Geschachtelte Listen

78 78 Gewinnbilanz Bilanz A: [307.5,401.6,-34.2,211.6,…] Jan.Feb.MärzApril Ziel: Aus der Bilanz soll der Gesamtgewinn berechnet werden. Bilanz B: [87.5,[30.6,-4.2,89.6,-5.6],435.3, …] Jan.FebMärz Bilanz C: [87.5,200.6, [[50.1,45.3,76.1,45.3],3.1, 5.2, 2.1], …] Jan.FebMärz

79 79 „flache“ Liste bilanz = [307.5, 401.6, -34.2,211.6] def summe(liste): i = 0 ergebnis = 0 while i < len(liste): zahl = liste[i] ergebnis = ergebnis + zahl i = i + 1 return ergebnis # Test print(summe(bilanz))

80 80 geschachtelte Listen bilanz = [87.5, [30.6, -4.2, 89.6, -5.6], 435.3] def summe(liste): i = 0 ergebnis = 0 while i < len(liste): zahl = liste[i] ergebnis = ergebnis + zahl i = i + 1 return ergebnis # Test print(summe(bilanz)) Falscher Ansatz! bilanz = [87.5, [30.6, -4.2, 89.6, -5.6], 435.3] def summe(liste): i = 0 ergebnis = 0 while i < len(liste): element = liste[i] if type(element) == list: j = 0 e = 0 while j < len(element): z = element[j] e = e + z j = j + 1 zahl = e else: zahl = element ergebnis = ergebnis + zahl i = i + 1 return ergebnis # Test print(summe(bilanz)) Sinnvoller Ansatz?

81 81 geschachtelte Listen bilanz = [87.5, [30.6, -4.2, 89.6, -5.6], 435.3] def summe(liste): if len(liste) == 0: ergebnis = 0 else: erstesElement = liste[0] restListe = liste[1:] if type(erstesElement) == list: ergebnis = summe(erstesElement) + summe(restListe) else: ergebnis = erstesElement + summe(restListe) return ergebnis # Test print(summe(bilanz)) Rekursiver Ansatz! bilanz = [87.5, [30.6, -4.2, 89.6, -5.6], 435.3] def summe(liste): i = 0 ergebnis = 0 while i < len(liste): element = liste[i] if type(element) == list: j = 0 e = 0 while j < len(element): z = element[j] e = e + z j = j + 1 zahl = e else: zahl = element ergebnis = ergebnis + zahl i = i + 1 return ergebnis # Test print(summe(bilanz)) Iterativer Ansatz

82 82 Eine Liste ist entweder eine leere Liste, oder besteht aus einem ersten Element und einer (Rest-)Liste. Liste als rekursive Datenstruktur def summe(liste): if len(liste) == 0: # liste: [] ergebnis = 0 else: # liste: [erstesElement] + restListe erstesElement = liste[0] restListe = liste[1:] if type(erstesElement) == list: ergebnis = summe(erstesElement) + summe(restListe) else: ergebnis = erstesElement + summe(restListe) return ergebnis bilanz = \ [ 87.5, [ 30.6, -4.2, 89.6, -5.6 ], 435.3 ]

83 83 Rekursive Verarbeitung summe( [87.5, [30.6, -4.2, 89.6, -5.6], 435.3]) ergebnis: 87.5 + summe([[30.6, -4.2, 89.6, -5.6], 435.3]) summe([[30.6, -4.2, 89.6, -5.6], 435.3]) ergebnis: summe([30.6, -4.2, 89.6, -5.6]) + summe([435.3]) summe([30.6, -4.2, 89.6, -5.6]) ergebnis: 30.6 + summe([-4.2, 89.6, -5.6]) summe([-4.2, 89.6, -5.6]) ergebnis: -4.2 + summe([89.6, -5.6]) summe([89.6, -5.6]) ergebnis: 89.6 + summe([-5.6]) summe([-5.6]) ergebnis: -5.6 + summe([]) summe([]) ergebnis: 0 return: 0 return: -5.6 return: 84.0 return: 79.8 return: 110.4 summe([435.3]) … return: 435.3 return: 545.7 return: 633.2 def summe(liste): if len(liste) == 0: ergebnis = 0 else: erstesElement = liste[0] restListe = liste[1:] if type(erstesElement) == list: ergebnis = summe(erstesElement) + summe(restListe) else: ergebnis = erstesElement + summe(restListe) return ergebnis rekursiver Algorithmus Ausführung

84 84 Aufgabe bilanz = [87.5, [30.6, -4.2, 89.6, -5.6], 435.3] def summe(liste): print('summe(', liste, ')') if len(liste) == 0: ergebnis = 0 else: erstesElement = liste[0] restListe = liste[1:] if type(erstesElement) == list: ergebnis = summe(erstesElement) + summe(restListe) else: ergebnis = erstesElement + summe(restListe) print('return:', ergebnis) return ergebnis # Test print(summe(bilanz)) Aufgabe Teste selbst das Programm und erkläre die Ausgaben. Verwende beim Testen auch Bilanz C: [87.5,200.6, [[50.1,45.3,76.1,45.3],3.1, 5.2, 2.1], …]

85 85 Entwicklung rekursiver Algorithmen Problem: Es soll gezählt werden, wie oft ein Element in einer Liste vorkommt. anzahl('b', []) -> 0 Reduktionsanfang: Löse das Problem direkt Rekursive Problemreduktion: Reduziere des Problems auf ein entsprechendes, aber „verkleinertes“ Problem. anzahl('b', ['b', 'b', 'd', 'a', 'c', 'b']) -> 1 + anzahl('b', ['b', 'd', 'a', 'c', 'b']) anzahl('b', ['a', 'b', 'b', 'd', 'a', 'c', 'b']) -> anzahl('b', ['b', 'b', 'd', 'a', 'c', 'b']) Rekursionsschritt: Löse ein entsprechendes Problem Fall 2: Bearbeite eine nicht-leere Liste Fall 1: Bearbeite eine leere Liste

86 86 Entwicklung rekursiver Algorithmen Problem: Es soll gezählt werden, wie oft ein Element in einer Liste vorkommt. anzahl('b', []) -> 0 anzahl('b', ['b', 'b', 'd', 'a', 'c', 'b']) -> 1 + anzahl('b', ['b', 'd', 'a', 'c', 'b']) anzahl('b', ['a', 'b', 'b', 'd', 'a', 'c', 'b']) -> anzahl('b', ['b', 'b', 'd', 'a', 'c', 'b']) def anzahl(element, liste): if len(liste) == 0: return 0 else: if liste[0] == element: return (1 + anzahl(element, liste[1:])) else: return anzahl(element, liste[1:]) (rekursive) Reduktionsschritte (rekursive) Reduktionsregeln Rekursive Problemreduktion: Reduziere des Problems auf ein entsprechendes, aber „verkleinertes“ Problem.

87 87 Entwicklung rekursiver Algorithmen Problem: Es soll gezählt werden, wie oft ein Element in einer Liste vorkommt. anzahl('b', ['a', 'b', 'd', 'a', 'b']) -> anzahl('b', ['b', 'd', 'a', 'b']) -> 1 + anzahl('b', ['d', 'a', 'b']) -> 1 + anzahl('b', ['a', 'b']) -> 1 + anzahl('b', ['b']) -> 1 + (1 + anzahl('b', [])) -> 1 + (1 + 0) -> 2 def anzahl(element, liste): if len(liste) == 0: return 0 else: if liste[0] == element: return (1 + anzahl(element, liste[1:])) else: return anzahl(element, liste[1:]) Reduktionskette (rekursive) Reduktionsregeln >>> anzahl('b', ['a', 'b', 'd', 'a', 'b']) 2

88 88 Übungen Rekursionsgymnastik: Bearbeite die Aufgaben auf inf-schule: http://www.inf-schule.de/algorithmen/algorithmen/rekursion/rekursionlisten/uebungen

89 89 Teil 6 Fallstudie – Geometrische Objekte

90 90 Geometrische Objekte Im Folgenden geht es um die Verwaltung und Verarbeitung geometrischer Objekte. Wir betrachten vereinfachend nur geometrische Objekte, die aus Streckenzügen mit Punkten mit ganzzahligen Koordinaten bestehen. Die folgende Abbildung (Logo des Fachbereichs Informatik der TU Kaiserslautern) ist aus solchen geometrischen Objekte aufgebaut.

91 91 Exkurs - Turtle-Grafik Turtle-Grafik basiert auf der Vorstellung, dass eine Schildkröte mit bestimmten Anweisungen auf einer Zeichenfläche bewegt wird und dass die Schildkröte dabei eine Spur hinterlässt. zeichne_Quadrat(laenge): wiederhole 4 mal: gehe_vorwaerts(laenge) drehe_dich_nach_links(90)  stift_hoch  stift_runter  gehe_vorwaerts(betrag)  gehe_rueckwaerts(betrag)  drehe_dich_nach_links(winkel)  drehe_dich_nach_rechts(winkel)  gehe_zu_punkt(punkt) ... Turtle-Algorithmus Turtle-Befehle vorwaerts(100)

92 92 Exkurs - Turtle-Grafik in Python Turtle-Grafik basiert auf der Vorstellung, dass eine Schildkröte mit bestimmten Anweisungen auf einer Zeichenfläche bewegt wird und dass die Schildkröte dabei eine Spur hinterlässt. zeichne_Quadrat(laenge): wiederhole 4 mal: gehe_vorwaerts(laenge) drehe_dich_nach_links(90)  stift_hoch  stift_runter  gehe_vorwaerts(betrag)  gehe_rueckwaerts(betrag)  drehe_dich_nach_links(winkel)  drehe_dich_nach_rechts(winkel)  gehe_zu_punkt(punkt) ... Turtle-Programm Turtle-Klasse from turtle import * # Deklaration einer Zeichenprozedur def quadrat(laenge): for i in range(4): forward(laenge) left(90) # Test der Zeichenprozedur quadrat(100) t.forward(100) >>> from turtle import * >>> forward(100) >>> bye()

93 93 Geometrische Objekte Geometrische Objekte: -Punkt -Streckenzug: Folge von Punkten -Figur: Folge von Steckenzügen und Figuren Dach Block-oben Raute Block-unten Verbindung 1 Verbindung 2 Verbindung 3 Verbindung 4 Verbindung 5 Stuetze-links Tor: Stuetze-links, Stuetze-rechts, Dach Stuetze-rechts: Verbindung 1, Block-oben, … Rahmen Logo: Tor, Rahmen

94 94 Datenverwaltung mit Listen Es gibt verschiedene Möglichkeiten, die geometrischen Objekte mit Hilfe geeigneter Datenstrukturen darzustellen. Hier eine Möglichkeiten mit geschachtelten Listen: stuetzelinks = [[0, 0],[20, 0],[50, 100],[30, 100],[0, 0]] blockunten = [[90, 10],[110, 10],[110, 30],[90, 30],[90, 10]] blockoben = [[90, 70],[110, 70],[110, 90],[90, 90],[90, 70]] raute = [[80, 50],[100, 40],[120, 50],[100, 60],[80, 50]] verbindung1 = [[100, 110], [100, 90]] verbindung2 = [[100, 70], [100, 60]] verbindung3 = [[100, 40], [100, 30]] verbindung4 = [[100, 10], [100, 0]] verbindung5 = [[80, 50], [70, 50], [70, 100], [100, 100]] stuetzerechts = [verbindung1, blockoben, verbindung2, raute, \ verbindung5, verbindung3, blockunten, verbindung4] dach = [[10, 110],[130, 110],[130, 125],[70, 140],[10, 125],[10, 110]] tor = [stuetzelinks, stuetzerechts, dach] rahmen = [[0, 0],[140, 0],[140, 140],[0, 140],[0, 0]] logo = [tor, rahmen] Geometrische Objekte: -Punkt: Liste mit genau 2 Zahlen (vom Typ int) -Streckenzug: Liste mit Punkten -Figur: Liste mit Steckenzügen und Figuren

95 95 Funktionen zur Strukturanalyse def istPunkt(L): if type(L) == list: if len(L) == 2: if (type(L[0]) == int) and (type(L[1]) == int): return True else: return False else: return False else: return False Geometrische Objekte: -Punkt: Liste mit genau 2 Zahlen (vom Typ int) -Streckenzug: Liste mit Punkten -Figur: Liste mit Steckenzügen und Figuren def istPunkt(L): return (type(L) == list) and (len(L) == 2) and (type(L[0]) == int) and (type(L[1]) == int)

96 96 Funktionen zur Strukturanalyse def istStreckenzug(L): if type(L) == list: if len(L) == 0: return True else: if istPunkt(L[0]): return istStreckenzug(L[1:]) else: return False Geometrische Objekte: -Punkt: Liste mit genau 2 Zahlen (vom Typ int) -Streckenzug: Liste mit Punkten -Figur: Liste mit Steckenzügen und Figuren def istStreckenzug (L): return (type(L) == list) and \ ((len(L) == 0) or \ (istPunkt(L[0]) and istStreckenzug(L[1:]))) [[0, 0],[20, 0],[50, 100],[30, 100],[0, 0]] istStreckenzug? istPunkt?istStreckenzug?und istListe?

97 97 Funktionen zur Strukturanalyse def istFigur(L): if type(L) == list: if len(L) == 0: return True else: if … return … else: return False Geometrische Objekte: -Punkt: Liste mit genau 2 Zahlen (vom Typ int) -Streckenzug: Liste mit Punkten -Figur: Liste mit Steckenzügen und Figuren def istFigur(L): return Aufgabe: Ergänze die fehlenden Teile.

98 98 Figuren zeichnen … def zeichneStreckenzug(streckenzug): if istStreckenzug(streckenzug): if streckenzug != []: punkt = streckenzug[0] up() goto(punkt) down() for punkt in streckenzug[1:]: goto(punkt) def zeichneFigur(figur): if istFigur(figur): if figur != []: objekt = figur[0] if istStreckenzug(objekt): zeichneStreckenzug(objekt) else: zeichneFigur(objekt) zeichneFigur(figur[1:]) … from turtle import * # Initialisierung left(90) # Test zeichneFigur(logo) Aufgabe: Teste das Programm.

99 99 Anwendung - Verschieben def xVerschiebenPunkt(punkt, x): if istPunkt(punkt): return [punkt[0]+x, punkt[1]] Aufgabe: Analysiere die Funktionsdefinitionen. Erläutere und erkläre die Bestandteile. Mit Hilfe geeigneter Funktionen soll ein beliebiges geometrisches Objekt um einen bestimmten Betrag x-Richtung verschoben werden. def xVerschiebenStreckenzug(streckenzug, x): if istStreckenzug(streckenzug): if streckenzug == []: return [] else: punkt = streckenzug[0] restStreckenzug = streckenzug[1:] return [xVerschiebenPunkt(punkt, x)] + xVerschiebenStreckenzug(restStreckenzug, x)

100 100 Anwendung - Verschieben Aufgabe: Entwickle eine geeignete Funktionsdefinition und teste gründlich. Mit Hilfe geeigneter Funktionen soll ein beliebiges geometrisches Objekt um einen bestimmten Betrag x-Richtung verschoben werden. def xVerschiebenFigur(figur, x): …

101 101 Weitere Anwendungen Aufgabe: Definiere analog eine Funktion yVerschieben zur Verschiebung in y-Richtung und eine Funktion xyVerschieben in beide Richtungen. Teste die Funktionen mit verschiedenen geometrischen Objekten. Aufgabe: Mit Hilfe einer Funktion xSpiegeln soll ein beliebiges geometrisches Objekt an der x-Achse gespiegelt werden. Einfache Variante: Alle Punkte werden gespiegelt. Schwierige Variante: Alle Punkte werden gespiegelt. Die Reihenfolge der Punkte eines Streckenzugs werden umgekehrt. Auch bei Gruppierungen wird die Reihenfolge der Objekte umgekehrt.

102 102 Weitere Anwendungen Aufgabe: Mit Hilfe einer Funktion xMaximum bzw. yMaximum soll die maximale x- bzw. y-Koordinate eines in einer Figur vorkommenden Punktes bestimmt werden. Entwickle eine geeignete Funktionsdefinition. Aufgabe: Mit Hilfe einer Funktion linksVon(L, M) soll bestimmt werden, ob das geometrische Objekt L links vom geometrischen Objekt in M liegt. Entwickle eine geeignete Funktionsdefinition. Aufgabe: Denk dir selbst weitere geometrische Probleme aus, die analog zu den oben beschriebenen gelöst werden können.


Herunterladen ppt "Datenverwaltung mit Datenstrukturen Klaus Becker 2016."

Ähnliche Präsentationen


Google-Anzeigen