~~NOTOC~~ ====== Fortgeschrittene Techniken für Listen samt Aufgaben zu Goethes Faust ====== ==== Nützliche Funktionen und list comprehension ==== Bitte anschauen: [[https://fginfo.ksbg.ch/~olaf/begruessung.mp4|Begrüßungsvideo]] In vorigen Lektionen hast du bereits Listen kennengelernt. Heute wirst du neben einigen Funktionen für Listen insbesondere **list comprehension** kennenlernen, eine elegante Methode zur Definition von Listen. Die Vermittlung dieser Inhalte wird vor allem durch Lern-Videos (inklusive kleiner Aufgaben) geschehen. Danach gibt es als Lernkontrolle einige Aufgaben zum Text von Goethes Faust - dieser Text wird dir als Liste zur Verfügung gestellt. Beispielsweise wirst du herausfinden, wie viele Wörter welcher Länge in Goethes Faust vorkommen und wie man dieses Ergebnis in einem Säulendiagramm graphisch darstellen kann. {{:lehrkraefte:snr:informatik:fachdidaktik:anzahl-woerter-nach-laenge.png?300}} Außerdem wirst du herausfinden, dass es im gesamten Faust nur 23 Palindrome (= Wörter, die von vorne wie von hinten gelesen vorkommen) gibt. ==== Empfohlenes Vorgehen ==== * Checke, ob du die im nächsten Abschnitt beschriebenen Vorkenntnisse hast. * Wenn dies der Fall ist, sollten Aufgabe 0 und Aufgabe 1 schnell gelöst sein. * Schau dir das Erklärvideo zu Listenfunktionen an und löse die darin gestellten Aufgaben. * Schau dir das Erklärvideo zu //list comprehension// an und löse die darin gestellten Aufgaben. * Bearbeite die Aufgaben 2, 3 und 4 zur Erprobung des Gelernten. ===== Vorkenntnisse ===== Wir nehmen an, dass du * mindestens die im folgenden Link erklärten Sachverhalte über Listen und Strings kennst: [[lehrkraefte:snr:informatik:fachdidaktik:vorkenntnisse|Vorkenntnisse]] Nützlich, aber nicht zwingend erforderlich ist es, wenn du mit Visual Studio Code (= VS Code) vertraut bist: * Du weißt, wie man dort Python-Programme schreibt und ausführt (''Ctrl+F5''). * Du weißt, wie man im Terminal von VS Code eine interaktive Python-Session öffnet und benutzt. * Die Vorbereitungen in Aufgabe 0 im nächsten Abschnitt stellen dich vor keinerlei Probleme. ===== Allgemeine Vorbereitung und Test der Vorkenntnisse ===== ==== Aufgabe 0: Vorbereitung ==== Erstelle ein neues Verzeichnis namens ''list-comprehension'' für deine heutigen Python-Programme. Öffne dieses Verzeichnis mit VS Code und öffne darin eine neue, leere Datei mit dem Namen ''faust-analyse.py''. Kopiere den folgenden Python-Code in diese Datei und speichere sie ab. Hinweis: Durch Anklicken des "Clipboard-Symbols" rechts oben im Fenster um den Code kannst du den Python-Code direkt in die Zwischenablage kopieren. eingabeDatei = open("faust-1-und-2.txt", encoding='utf-8') # Die Angabe des Encodings ist unter Windows nötig. wortliste = eingabeDatei.read().splitlines() eingabeDatei.close() print("Berühmte Passage:") print(wortliste[2454:2470]) Die folgende Datei enthält alle Wörter aus Goethes Faust (Teil I und Teil II) in der richtigen Reihenfolge. Speichere sie in deinem neu erstellten Verzeichnis ab, indem du sie mit der rechten Maustaste anklickst und "Speichern unter"/"Save as" auswählst. {{ :lehrkraefte:snr:informatik:fachdidaktik:faust-1-und-2.txt |}} Führe das Python-Programm aus (per ''Ctrl-F5'' in VS Code) - wenn du alles richtig gemacht hast, wird eine berühmte Passage aus Faust (als Liste von Strings) ausgegeben. Berühmte Passage: ['Habe', 'nun', 'ach', 'Philosophie', 'Juristerei', 'und', 'Medizin', 'Und', 'leider', 'auch', 'Theologie', 'Durchaus', 'studiert', 'mit', 'heißem', 'Bemühn'] Falls es wider Erwarten nicht mit dem Einlesen der Wörter aus der Datei klappt: Im folgenden Python-Programm ist die faustsche Wörterliste explizit in der ersten (sehr langen) Zeile angegeben: {{ :lehrkraefte:snr:informatik:fachdidaktik:faust-analyse-wortliste-explizit.py |}} Speichere diese Datei (per Anklicken mit der rechten Maustaste) ab und führe sie aus. Arbeite im Folgenden mit dem Python-Programm ''faust-analyse-wortliste-explizit.py'' statt mit ''faust-analyse.py''. Alle folgenden Aufgaben zur Analyse des Faust-Textes starten mit dem Programm ''faust-analyse.py'' als Grundgerüst. ==== Aufgabe 1 zu Goethes Faust: Test der Vorkenntnisse ==== Ergänze das Programm ''faust-analyse.py'' so (bei den ersten drei Teilaufgaben genügt jeweils eine neue Zeile am Ende des Python-Programms), dass * (1a) die Anzahl der Wörter in Goethes Faust ausgegeben wird; * (1b) die ersten 10 Wörter als Liste ausgegeben werden (es handelt sich um Wörter aus dem Inhaltsverzeichnis); * (1c) die letzten 10 Wörter als Liste ausgegeben werden; * (1d) die berühmte Passage (= der Anfang von Fausts Monolog) rückwärts ausgegeben wird (als Liste). Wenn du willst, kannst du das Programm unter einem beliebigen Namen deiner Wahl (etwa ''aufgabe-1.py'') abspeichern. Lies [[lehrkraefte:snr:informatik:fachdidaktik:vorkenntnisse|Vorkenntnisse]]. Verwende eine Zusatzvariable ''faustMonolog'', die die Passage als Liste enthält. Gib die Liste ''faustMonolog = wortliste[2454:2470]'' rückwärts aus. ---- 76101 Wörter ['Zueignung', 'Vorspiel', 'auf', 'dem', 'Theater', 'Prolog', 'im', 'Himmel', 'Nacht', 'Vor'] ['Unbeschreibliche', 'Hier', 'ists', 'getan', 'Das', 'Ewig', 'Weibliche', 'Zieht', 'uns', 'hinan'] ['Bemühn', 'heißem', 'mit', 'studiert', 'Durchaus', 'Theologie', 'auch', 'leider', 'Und', 'Medizin', 'und', 'Juristerei', 'Philosophie', 'ach', 'nun', 'Habe'] ---- eingabeDatei = open("faust-1-und-2.txt", encoding='utf-8') wortliste = eingabeDatei.read().splitlines() eingabeDatei.close() print("Berühmte Passage:") print(wortliste[2454:2470]) # Teilaufgabe 1a print("Anzahl Wörter:") # Diese Zeile war nicht verlangt - es ist aber natürlich sinnvoll, jede Ausgabe zu erklären. print(len(wortliste)) # Teilaufgabe 1b print("Erste 10 Wörter:") print(wortliste[:10]) # Teilaufgabe 1c print("Letzte 10 Wörter:") print(wortliste[-10:]) # Teilaufgabe 1d print("Fausts Monolog rückwärts:") faustMonolog = wortliste[2454:2470] print(faustMonolog[::-1]) # Alternative 1 zu 1d: # print(wortliste[2469:2453:-1]) # und NICHT: print(wortliste[2470:2454:-1]) # Alternative 2 zu 1d: # print(wortliste[2454:2470][::-1]) ===== Nützliche Funktionen und Methoden für Listen ===== Schau nun das [[https://fginfo.ksbg.ch/~olaf/einige-funktionen-und-methoden-fuer-listen.mp4|hier verlinkte Erklärvideo]] an. Darin werden die fünf Listen-Funktionen((Es handelt sich dabei um sogenannte //built-in functions//, vgl. https://docs.python.org/3/library/functions.html. Eine weitere solche Funktion, die man auf Listen anwenden kann, ist ''sum''.)) ''len'', ''max'', ''min'', ''sorted'', ''reversed'' und die drei Listen-Methoden ''append'', ''count'', ''index'' erklärt; das Video endet mit einer Übungsaufgabe dazu. ===== List comprehension ===== Die Bezeichnung "list comprehension" ist historisch bedingt und nicht besonders glücklich gewählt. Es geht darum, neue Listen mit möglichst leicht verständlicher Syntax zu definieren. List comprehension wird in dem [[https://fginfo.ksbg.ch/~olaf/list-comprehension.mp4|hier verlinkten Video]] erklärt.((Bisher habe ich die folgenden Versprecher bemerkt: 4:03 gemeint sind eckige Klammern; 10:03 ignoriere Kommentar mit 10 Minuten; 12:04 es sollte heißen: "Nur die hat am ANFANG ein e")) Erklärt werden "list comprehension-Ausdrücke" wie etwa ''[i**2 for i in range(1, 101)]'' oder ''[i**2 for i in range(1, 101) if i**2 <= 1000]'' als Vereinfachungen des sukzessiven Listenaufbaus mit ''for''-Schleifen (mit Bedingung). Diese Notation ähnelt der mathematischen "Set-builder notation" $\{x^2 \mid x \in \{1, 2, 3, \dots, 100\} \text{ mit } x^2 \leq 100\}$. ===== Aufgaben dazu ===== ==== Aufgabe 2 zu Goethes Faust: Vorkommen des Wortes "Hexe" ==== Ergänze das Programm ''faust-analyse.py'' (aus [[lehrkraefte:snr:informatik:fachdidaktik:list-comprehension#aufgabe_0vorbereitung| Aufgabe 0: Vorbereitung]]) so, dass * (2a) ausgegeben wird, wie oft das Wort ''Hexe'' in Goethes Faust vorkommt; - Möglichkeit: Die Methode ''.count(...)'' zählt, wie oft ein Element in einer Liste auftaucht. - Möglichkeit: Verwende die Längenfunktion ''len(...)'' und //list comprehension//. 8 Mal ---- * (2b) ausgegeben wird, an welcher Position das Wort ''Hexe'' zum ersten Mal auftaucht; Die Methode ''.index(...)'' liefert den Index des ersten Auftretens eines Elements einer Liste. An Position 15247 (in Informatik-Zählweise). ---- * (2c) der "Kontext" des ersten Auftretens des Wortes ''Hexe'' ausgegeben wird; dieser "Kontext" soll als Liste von 21 Wörtern um dieses Wort herum mit dem Wort ''Hexe'' in der Mitte ausgegeben werden. Gib eine geeignete Teilliste der Liste ''wortliste'' aus. Berechne Start- und Endindex aus der Zahl in der vorigen Teilaufgabe. Verwende die Syntax''wortliste[:]''. ['mir', 'gar', 'nicht', 'an', 'MEPHISTOPHELES', 'So', 'muß', 'denn', 'doch', 'die', 'Hexe', 'dran', 'FAUST', 'Warum', 'denn', 'just', 'das', 'alte', 'Weib', 'Kannst', 'du'] ---- * (2d) eine Liste aller Positionen (in informatischer Zählweise) ausgegeben wird, an denen das Wort ''Hexe'' erscheint. Die gesuchte Liste ist eine Teilliste der Liste aller Zahlen von 0 bis zur Länge unserer Wortliste (minus Eins). Beschreibe diese Teilliste durch eine geeignete //list comprehension//. Der //list comprehension//-Ausdruck ''[i for i in range(len(wortliste)) if ...]'' beschreibt diese Teilliste, wenn die drei Punkte geeignet ersetzt werden. [15247, 15980, 16094, 16483, 16855, 16903, 16927, 25973] ---- eingabeDatei = open("faust-1-und-2.txt", encoding='utf-8') wortliste = eingabeDatei.read().splitlines() eingabeDatei.close() print("Berühmte Passage:") print(wortliste[2454:2470]) # Teilaufgabe 2a print("Anzahl des Wortes 'Hexe':") print(wortliste.count("Hexe")) # Alternative: # print(len([x for x in wortliste if x == "Hexe"])) # Teilaufgabe 2b print("Position des ersten Auftretens des Wortes 'Hexe':") print(wortliste.index("Hexe")) # Teilaufgabe 2c print("Kontext des ersten Auftretens von 'Hexe':") erstePositionHexe= wortliste.index("Hexe") print(wortliste[erstePositionHexe-10:erstePositionHexe+11]) # Teilaufgabe 2d print("Liste der Positionen, an denen das Wort 'Hexe' auftritt:") print([i for i in range(len(wortliste)) if wortliste[i] == "Hexe"]) ==== Aufgabe 3 zu Goethes Faust: Wortlängen (samt Darstellung als Säulendiagramm) ==== Starte wieder mit dem Programm ''faust-analyse.py'' (aus [[lehrkraefte:snr:informatik:fachdidaktik:list-comprehension#aufgabe_0vorbereitung| Aufgabe 0: Vorbereitung]]). * (3a) Definiere eine Liste namens ''wortlaengen'', deren Einträge die Längen der Wörter aus Goethes Faust sind: Der nullte Eintrag ist die Länge des nullten Worts, der erste Eintrag die Länge des zweiten Worts usw. Diese List kann mit einer //list comprehension// definiert werden: ''wortlaengen = [... for w in wortliste]''. ---- * (3b) Speichere die Länge des längsten Wortes (oder der längsten Wörter) in Goethes Faust in der Variable ''maxLaenge'' und gib diese Variable aus. Verwende die Funktion ''max(...)''. Die maximale Wortlänge ist 32. ---- * (3c) Definiere eine Liste ''anzahlBeiLaenge'', deren Einträge angeben, wie viele Wörter einer gegebenen Länge vorkommen: Der nullte Eintrag ist Null (= die Anzahl aller Wörter der Länge Null), der erste Eintrag ist die Anzahl aller Wörter der Länge eins, der zweite Eintrag die Anzahl aller Wörter der Länge zwei usw.
Gib diese Liste aus. * Bemerkung: In der folgenden [[lehrkraefte:snr:informatik:fachdidaktik:list-comprehension#darstellung_als_saeulendiagramm|Infobox (Darstellung als Säulendiagramm)]] erfährst du, wie du diese Liste als Säulendiagramm ausgeben kannst. Die Methode ''.count()'' zählt, wie oft ein Eintrag in einer Liste vorkommt. Die gesuchte Liste kann mit einer //list comprehension// definiert werden: ''anzahlBeiLaenge = [... for i in range(...)]''. ''anzahlBeiLaenge = [wortlaengen.count(...) for i in range(maxLaenge + 1)]''. ---- eingabeDatei = open("faust-1-und-2.txt", encoding='utf-8') wortliste = eingabeDatei.read().splitlines() eingabeDatei.close() print("Berühmte Passage:") print(wortliste[2454:2470]) # Teilaufgabe 3a wortlaengen = [len(w) for w in wortliste] # Teilaufgabe 3b maxLaenge = max(wortlaengen) print("Maximale Wortlänge:") print(maxLaenge) # Teilaufgabe 3c anzahlBeiLaenge = [wortlaengen.count(i) for i in range(maxLaenge + 1)] print("Liste der Wörter bei gegebener Wortlänge (Lesehilfe: der n-te Eintrag gibt an, wie viele Wörter n Buchstaben haben):") print(anzahlBeiLaenge)
=== Darstellung als Säulendiagramm === Mit der Python-Bibliotheken ''matplotlib'' (für "Library for mathematical plots) ist es einfach, das Ergebnis der Text-Analyse in Aufgabe 3 graphisch als Säulendiagramm darzustellen: Kopiere den folgenden Code-Block ans Ende deines Programms und führe das Programm aus (falls dies nicht funktioniert, musst du vermutlich die Bibliothek ''matplotlib'' installieren, siehe die "gelbe" Glühbirnen-Box unter der folgenden Code-Box). from matplotlib import pyplot as plt def zeichneSaeulendiagramm(xWerte, yWerte, titel, xBeschriftung, yBeschriftung): # xWerte: Liste der Werte auf der horizontalen Achse # yWerte: Liste der zugehörigen Funktionswerte # titel: Titel der Graphik # xBeschriftung: Text unter der horizontalen Achse # yBeschriftung: Text links der vertikalen Achse plt.figure("Säulendiagramm-Fenster") plt.title(titel) plt.xlabel(xBeschriftung) plt.ylabel(yBeschriftung) plt.bar(xWerte, yWerte, color='blue') plt.xticks(xWerte, xWerte, rotation='horizontal') plt.tight_layout() plt.show() zeichneSaeulendiagramm(range(maxLaenge + 1), anzahlBeiLaenge, 'Anzahl der Wörter gegebener Länge', 'Wortlänge', 'Anzahl der Wörter') Eventuell musst du die Bibliothek ''matplotlib'' installieren. Dies geht (unter Windows) mit dem Programm "Befehlszeile"/"Command prompt" wie folgt: Gib die beiden folgenden Zeilen dort ein, jeweils gefolgt von ''Return''. python -m pip install -U pip python -m pip install -U matplotlib Der erste Befehl installiert ''pip'' bzw. führt ein Upgrade davon durch. Die eigentliche Installation der Bibliothek ist dann der zweite Befehl. Hier stellt sich etwa die "Forschungsfrage": Kann man einen Autor (bzw. eine Sprache) anhand der Buchstabenhäufigkeiten erkennen? ==== Aufgabe 4 zu Goethes Faust: Palindrome ==== Palindrome sind Wörter (und manchmal auch Sätze), die von vorne wie von hinten gelesen dasselbe Wort liefern, vgl. https://de.wikipedia.org/wiki/Palindrom. Starte wieder mit dem Programm ''faust-analyse.py''. Die Liste ''wortliste'' enthält viele Wörter mehrfach; beispielsweise taucht das Wort "aber" mehrfach auf - überdies taucht es großgeschrieben als "Aber" auf. Ergänze das Programm am Ende um die Code-Zeile wortlisteOhneWiederholungen = list({x.lower() for x in wortliste}) Die Liste ''wortlisteOhneWiederholungen'' enthält dann alle Wörter aus Goethes Faust in Kleinschreibung ohne Wiederholungen.((Wer es genau wissen will: ''{x.lower() for x in wortliste}'' liefert die //Menge// aller Wörter (wobei Großbuchstaben durch Kleinbuchstaben ersetzt wurden). Diese Menge wird mit dem Befehl ''list(...)'' in eine Liste verwandelt.)) Ergänze das Programm so, dass * (4a) eine alphabetisch sortierte Liste aller Wörter der Länge 19 ausgegeben wird. Die Funktion ''sorted(...)'' sortiert eine Liste (genauer nimmt sie eine Liste entgegen und liefert deren Sortierung zurück). Erstelle mit einer geeigneten //list comprehension// eine Liste aller Wörter der Länge 19. List der Wörter der Länge 19, alphabetisch sortiert: ['fratzengeisterspiel', 'menschenfresserisch', 'rechtsgelehrsamkeit', 'scharfangeschloßnem', 'sonnedurchstrahlten', 'unwiederbringlichen', 'zweigleinbeflügelte'] ---- * (4b) Eine alphabetisch sortierte Liste aller Wörter, die mit dem Buchstaben 'q' beginnen, ausgegeben wird. Gehe ähnlich vor wie bei der vorigen Aufgabe. Den ersten Buchstaben eines Strings ''s'' bekommt man per ''s[0]''. Liste der mit 'q' beginnenden Wörter, alphabetisch sortiert: ['quadrat', 'qual', 'qualen', 'qualität', 'qualitäten', 'qualm', 'qualmend', 'quammig', 'quappig', 'quark', 'quasten', 'quecksilber', 'quell', 'quelle', 'quellen', 'quellt', 'quem', 'quentchen', 'quer', 'quetschend', 'quetschender', 'quid', 'quidquid', 'quillen', 'quillend', 'quillt', 'quintessenz', 'quirlt', 'quäle', 'quälen', 'quälte'] ---- * (4c) Eine Liste aller Palindromwörter in Goethes Faust ausgegeben wird; außerdem soll die Anzahl aller Palindromwörter ausgegeben werden. (Genauer sind damit diejenigen Wörter im Faust gemeint, die auch von hinten gelesen im Faust auftauchen.) Wie kann man feststellen, ob ein String ''s'' ein Palindromwort ist? Der String ''s[::-1]'' ist ''s'' rückwärts gelesen. Genau dann ist ''s'' ein Palindromwort, wenn ''s == s[::-1]'' wahr ist. Verwende //list comprehension//, um die gesuchte Liste zu definieren. ''[... for s in wortlisteOhneWiederholungen if ...]'' Liste der Palindrome, alphabetisch sortiert: ['a', 'aha', 'beleb', 'bub', 'e', 'ehe', 'höh', 'i', 'ii', 'madam', 'neben', 'nennen', 'neuen', 'nun', 'o', 'retter', 's', 'stets', 'tat', 'tot', 'tut', 'tät', 'uhu'] Anzahl der Palindrome: 23 ---- eingabeDatei = open("faust-1-und-2.txt", encoding='utf-8') wortliste = eingabeDatei.read().splitlines() eingabeDatei.close() print("Berühmte Passage:") print(wortliste[2454:2470]) wortlisteOhneWiederholungen = list({x.lower() for x in wortliste}) # Teilaufgabe 4a wortliste19 = [s for s in wortlisteOhneWiederholungen if len(s) == 19] print("List der Wörter der Länge 19, alphabetisch sortiert:") print(sorted(wortliste19)) # Teilaufgabe 4b wortlisteQ = [s for s in wortlisteOhneWiederholungen if s[0] == "q"] print("Liste der mit 'q' beginnenden Wörter, alphabetisch sortiert:") print(sorted(wortlisteQ)) # Teilaufgabe 4c palindromliste = [s for s in wortlisteOhneWiederholungen if s == s[::-1]] print("Liste der Palindrome, alphabetisch sortiert:") print(sorted(palindromliste)) print("Anzahl der Palindrome:") print(len(palindromliste)) ===== Bonusmaterial (Aufgaben, weitere Ideen, nachfolgende Themen) ===== Siehe [[lehrkraefte:snr:informatik:fachdidaktik:bonusmaterial|Bonusmaterial]]. ===== Nachfolgende Themen (folgende Lektionen) ===== * Verschachtelte Listen * Kopieren von Listen (shallow copy, deep copy) und dadurch motiviert: * mutable and immutable data types (deutsch etwa: veränderliche und unveränderliche Datentypen); vlg. meine bisherigen Versuche dazu: [[lehrkraefte:snr:informatik:python:listen#listen_sind_mutabel_veraenderlich_englisch_mutable]] oder noch genauer [[lehrkraefte:snr:informatik:python:variablen-in-python]]. * Wie bekomme ich einen beliebigen Text aus dem Internet in Listenform?