Differences
This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
| lehrkraefte:snr:informatik:glf22:python:simulationen [2023/01/18 09:27] – [Aufgabe: Verdopplungs-Strategie (= Doublieren)] Olaf Schnürer | lehrkraefte:snr:informatik:glf22:python:simulationen [2024/03/20 13:01] (current) – [Eventuell: Exakte mathematische Lösung für die Münz- oder Würfelaufgabe] Olaf Schnürer | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ~~NOTOC~~ | ||
| + | |||
| + | ====== Simulationen ====== | ||
| + | |||
| + | Mit // | ||
| + | * Wettersimulation: | ||
| + | * Klimasimulation | ||
| + | * Simulation wirtschaftlicher Szenarien (wie entwickelt sich die Gesamtwirschaft, | ||
| + | * Flug- oder Zugsimulator, | ||
| + | * Virtual reality (etwa bei Computerspielen, | ||
| + | * Simulationen zur Entwicklung neuer Medikamente oder Impfstoffe, etwa gegen Corona (viele Stoffe können am Computer getestet werden, so dass man aussichtsreiche Kandidation für reale Tests bekommt) | ||
| + | * Simulationen von biochemischen Vorgängen (etwa Falten von Proteinen, vgl. https:// | ||
| + | * Simulationen in Naturwissenschaften (etwa Simulationen von Atomen und Molekülen) | ||
| + | * etc. (evtl. auch künstliche Intelligenz, | ||
| + | |||
| + | Die klassischen Standbeine der Naturwissenschaften sind Experiment und Theorie. Als drittes Standbein kommt mit zunehmenden Rechenkapazitäten die Simulation hinzu.((vgl. etwa https:// | ||
| + | |||
| + | ====== Kopf oder Zahl: Simulation von Münz- und Würfelexperimenten ====== | ||
| + | |||
| + | ===== Motivation ===== | ||
| + | |||
| + | <WRAP center round box> | ||
| + | Schätze: | ||
| + | |||
| + | - Wie oft muss man einen (Spiel-)Würfel im Schnitt werfen, bis zweimal direkt hintereinander eine Sechs (also 66) erscheint? | ||
| + | - Muss man einen Würfel im Schnitt gleich oft, weniger oft oder öfter werfen, bis das erste Mal eine Sechs direkt gefolgt von einer Fünf (also 65) erscheint? | ||
| + | - Wie oft muss man eine Münze im Schnitt werfen, bis zweimal direkt hintereinander Kopf (also KK) erscheint? | ||
| + | </ | ||
| + | |||
| + | |||
| + | ===== Kopf oder Zahl - vom Problem zum Programm ===== | ||
| + | |||
| + | |||
| + | ==== Experimentelle Lösung und Beschreibung des Experiments ==== | ||
| + | |||
| + | <WRAP center round todo> | ||
| + | Zweierarbeit: | ||
| + | - Beantworte experimentell: | ||
| + | - Wenn ihr fertig seid: Beschreibt handschriftlich **möglichst genau** auf einem Blatt Papier, was ihr gemacht habt! (Denn wir wollen dies später einem Computer beibringen.) | ||
| + | </ | ||
| + | |||
| + | ==== Von der Beschreibung des Experiments zum Pseudo-Code ==== | ||
| + | |||
| + | <WRAP center round todo> | ||
| + | Gemeinsam: Experiment in Worten beschreiben, | ||
| + | </ | ||
| + | |||
| + | {{ : | ||
| + | |||
| + | ==== Aufgabe: Pseudo-Code in ein Python-Programm übertragen ==== | ||
| + | |||
| + | <WRAP center round todo> | ||
| + | Wandle den zuvor erstellten Pseudo-Code in ein Python-Programm namens '' | ||
| + | |||
| + | <hidden Höchstes Niveau: Selbständig programmieren> | ||
| + | Schreibe selbst das entsprechende Programm. | ||
| + | |||
| + | Hinweise: | ||
| + | * Um Zufallszahlen((genauer handhelt es sich um Pseudozufallszahlen)) zu erzeugen: | ||
| + | * Schreibe '' | ||
| + | * Der Funktionsaufruf '' | ||
| + | * Interpretiere die zufällig erzeugten Zahlen wie folgt: 1 steht für " | ||
| + | |||
| + | Bemerkung: Gib Zwischenergebnisse aus, damit es bei hoher Anzahl von Simulationen etwas weniger langweilig ist, das Endergebnis abzuwarten (etwa alle 100000 Simulationen ein Zwischenergebnis). | ||
| + | </ | ||
| + | |||
| + | <hidden Mittleres Niveau: Programmieren nach Anweisungen (vgl. Malen nach Zahlen)> | ||
| + | Verwende das folgende Programmgerüst: | ||
| + | Alle Kommentarzeilen (beginnend mit ''#'' | ||
| + | |||
| + | <code python muenzwurf-simulation-vorlage.py> | ||
| + | # Vereinbarung: | ||
| + | # 1 = Kopf | ||
| + | # 2 = Zahl | ||
| + | |||
| + | # Import der Zufallsbibliothek | ||
| + | from random import * | ||
| + | |||
| + | # Anzahl der durchzuführenden Simulationen | ||
| + | ANZAHL_SIMULATIONEN = 100000 | ||
| + | |||
| + | # Vereinbare eine Variable namens " | ||
| + | # die die Gesamtzahl aller Münzwürfe zählt und setze sie auf Null. | ||
| + | ??? | ||
| + | |||
| + | # Beginn einer for-Schleife, | ||
| + | # wie die Variable ANZAHL_SIMULATIONEN angibt. | ||
| + | # Nenne die Laufvariable simulationsnummer. | ||
| + | ??? | ||
| + | # Gibt die Simulationsnummer aus und die aktuelle durchschnittliche Dauer, | ||
| + | # falls diese durch 10000 teilbar und positiv ist. | ||
| + | if simulationsnummer % 100000 == 0: | ||
| + | print(simulationsnummer) | ||
| + | # | ||
| + | # Beginn des Einzelexperiments: | ||
| + | # Vereinbare zwei Variablen namens | ||
| + | # " | ||
| + | # und weise ihnen jeweils als Startwert einen Fantasiewert zu, | ||
| + | # etwa ' | ||
| + | ??? | ||
| + | ??? | ||
| + | |||
| + | # Vereinbare eine Variable " | ||
| + | # Einzelexperiment bereits die Münze geworfen wurde. | ||
| + | ??? | ||
| + | # Beginn einer while-Schleife: | ||
| + | # Der eingerückte Code-Block nach der mit " | ||
| + | # wird so lange durchgeführt, | ||
| + | # die Bedingung ??? wahr ist. Wodurch musst du ??? ersetzen? | ||
| + | while not (???): | ||
| + | # Erzeugt zufällig die Zahl 1 (alias Kopf) oder 2 (alias Zahl) | ||
| + | # und speichert sie in der Variablen " | ||
| + | aktueller_wurf = randrange(1, | ||
| + | # Passe die Variable anzahl_wuerfe an. | ||
| + | ??? | ||
| + | # Aktualisiere die beiden Variablen " | ||
| + | # Der letzte Wurf wird zum vorletzten Wurf, | ||
| + | # der aktuelle Wurf wird zum letzten Wurf. | ||
| + | ??? | ||
| + | ??? | ||
| + | # Erhöhe die Variable " | ||
| + | # der im aktuellen Einzelexperiment getätigten Würfe. | ||
| + | ??? | ||
| + | |||
| + | # Berechne die durchschnittliche Dauer für zweimal Kopf | ||
| + | # und gib sie aus! | ||
| + | ??? | ||
| + | </ | ||
| + | Bemerkung: Die Variable '' | ||
| + | </ | ||
| + | |||
| + | <hidden Niedrigstes Level: Lehrperson programmiert vor> | ||
| + | Du programmierst mit und versuchst, das Programm zu verstehen. | ||
| + | Ausserdem vergleichst du es mit dem Pseudo-Code. | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | <WRAP center round todo> | ||
| + | Indem du dein Programm 1' | ||
| + | |||
| + | Wie oft muss man eine Münze im Schnitt werfen, bis zweimal direkt hintereinander Kopf erscheint? | ||
| + | |||
| + | Was denkst du? | ||
| + | | ||
| + | Wie oft muss man eine Münze im Schnitt werfen, bis direkt hintereinander Kopf-Zahl erscheint? | ||
| + | Genauso lang wie für zweimal Kopf hintereinander? | ||
| + | | ||
| + | Ändere dein Programm ein wenig, um diese Frage zu erforschen. | ||
| + | </ | ||
| + | |||
| + | <WRAP center round important> | ||
| + | Bevor man ein kompliziertes Problem löst (und dafür etwa ein Computerprogramm schreibt), ist es stets eine gute Idee, das Problem **auf einem Blatt Papier handschriftlich** möglichst genau zu analysieren (und den beabsichtigten Programmablauf schrittweise immer genauer festzulegen (etwa: welche Variablen, Schleifen, Funktionen benötige ich?)). | ||
| + | </ | ||
| + | |||
| + | ===== Würfeln, bis zwei Sechser kommen ===== | ||
| + | |||
| + | <WRAP center round todo> | ||
| + | * Öffne ein neues Python-Programm namens '' | ||
| + | * Ändere das Programm so, dass es per Simulation die Frage beantwortet: | ||
| + | | ||
| + | Bonusaufgabe: | ||
| + | * Wie oft muss man im Schnitt würfeln, bis dreimal direkt hintereinander eine Sechs erscheint? | ||
| + | </ | ||
| + | |||
| + | ===== Zusatzfragen ===== | ||
| + | |||
| + | ==== Münzwurf ==== | ||
| + | |||
| + | <WRAP center round box> | ||
| + | Welche der Folgen KKK (= Kopf-Kopf-Kopf), | ||
| + | </ | ||
| + | |||
| + | ==== Würfeln ==== | ||
| + | |||
| + | Es bieten sich jede Menge ähnliche Fragen an. Finde selbst eine oder suche dir eine aus der folgenden Liste aus! | ||
| + | |||
| + | <WRAP center round box> | ||
| + | Wie oft muss man einen Würfel im Schnitt werfen, | ||
| + | - bis insgesamt 10 Mal eine 6 gewürfelt wurde? | ||
| + | - bis insgesamt 20 Mal eine 6 gewürfelt wurde? | ||
| + | - bis eine 6 gewürfelt wird? | ||
| + | - bis zweimal direkt hintereinander dieselbe Zahl (also ein Pasch) erscheint? | ||
| + | - bis direkt hintereinander 1, 2 erscheint? | ||
| + | - bis direkt hintereinander 6, 6 oder direkt hintereinander 1, 2 erscheint? | ||
| + | - bis direkt hintereinander 6, 6 oder direkt hintereinander 1, 1 erscheint? | ||
| + | - bis zwei Päsche hintereinander erscheinen? (Entscheide selbst, ob dreimal hintereinander dieselbe Zahl (etwa 3, 3, 3) als zwei Päsche hintereinander zählen oder nicht.) | ||
| + | - bis 5 Mal hintereinander eine Sechs erscheint? (Empehlung, wenn bekannt: Verwende eine Liste!) | ||
| + | - bis 10 Mal (oder gar 1000 Mal) hintereinander eine Sechs erscheint? (Achtung: Nicht zu viele Simulationen durchführen.) | ||
| + | |||
| + | Welche Folge von drei Zahlen kommt im Schnitt am frühesten? | ||
| + | |||
| + | Wie viele Päsche (alias zweimal dieselbe Zahl direkt hintereinander) hat man im Schnitt geworfen, bevor man einen Sechserpasch wirft? | ||
| + | |||
| + | Wie lange dauert es im Schnitt, bis man eine " | ||
| + | |||
| + | Wie lange dauert es im Schnitt, bis die Summe aller gewürfelten Zahlen 100 übersteigt? | ||
| + | |||
| + | Bei wieviel Prozent der Versuche kommt man beim wiederholten würfeln genau bei 100 an? | ||
| + | |||
| + | Würdest du darauf wetten, dass man in vier Würfen mit einem Würfel mindestens eine Sechs würfelt? | ||
| + | |||
| + | Würdest du darauf wetten, dass man in 38 Würfen mit einem Würfel mindestens zwei Sechser direkt hintereinander würfelt? (Man könnte 38 durch irgendeinen andere Zahl ersetzen.) | ||
| + | |||
| + | Wenn man mit jeweils mit zwei Würfeln gleichzeitig würfelt, wie lange muss man im Schnitt auf den Sechserpasch warten? | ||
| + | </ | ||
| + | |||
| + | ==== Warum " | ||
| + | |||
| + | <WRAP center round box> | ||
| + | Bei vielen dieser Fragestellungen legen die Simulationen nahe, dass als Ergebnis eine ganze Zahl heraus kommt (also etwa 6 oder 42, aber nicht 43.5). Genauer vermute ich, dass dies bei allen Fragestellungen der Fall ist, wo man auf eine einzige Folge wartet. | ||
| + | |||
| + | Wenn das so ist (was man sich mathematisch recht leicht überlegen können sollte), gibt es dafür einen offensichtlichen Grund? | ||
| + | </ | ||
| + | ==== Eventuell: Exakte mathematische Lösung für die Münz- oder Würfelaufgabe ==== | ||
| + | |||
| + | Per Zustandsdiagramm, | ||
| + | |||
| + | Bemerkungen: | ||
| + | * Erst mit einer mathematisch korrekten Begründung kann man absolut sicher sein, die Antwort zu kennen (und hoffentlich stimmt sie mit der auf Grund der Simulationen erwarteten Antwort überein.) | ||
| + | * Gewisse Fragen ("Wie lange dauert es im Schnitt für 100 Sechser?" | ||
| + | |||
| + | ====== Simulation von Roulette ====== | ||
| + | |||
| + | Wenn man im Wesentlichen weiss, wie Roulette funktioniert, | ||
| + | * Die Zahlen von 0 bis 37 fallen gleichhäufig. | ||
| + | * Die Zahl Null ist grün, die Hälfte der restlichen Zahlen ist rot, die andere Hälfte schwarz. | ||
| + | * Wer seinen Einsatz (etwa 30 Jetons) auf Rot setzt, verliert ihn bei Null oder einer der 18 schwarzen Zahlen; bei einer der 18 roten Zahlen bekommt er seinen Einsatz zurück und zusätzlich dieselbe Summe von der Spielbank (also 30 Jetons zurück + 30 Jetons von der Bank). | ||
| + | |||
| + | ===== Aufgabe: Verdopplungs-Strategie (= Doublieren) ===== | ||
| + | |||
| + | <WRAP center round todo> | ||
| + | Jemand vermutet (irrtümlich), | ||
| + | |||
| + | <code text> | ||
| + | Er startet mit einem Anfangsvermögen von 100 Jetons. | ||
| + | Er beginnt mit einem Einsatz von 1 Jeton. | ||
| + | Solange er nicht alles Geld verloren hat oder sein Anfangsvermögen verdoppelt hat, macht er das folgende: | ||
| + | Er setzt seinen Einsatz auf Rot. | ||
| + | (Nun folgt der Wurf der Kugel.) | ||
| + | Wenn die Kugel in einem roten Fach zu liegen kommt (er also gewinnt), | ||
| + | startet er beim nächsten Mal wieder mit einem Einsatz von 1 Jeton; | ||
| + | sonst (im Fall, dass die Kugel schwarz oder grün (= Null) liefert) | ||
| + | verdoppelt er seinen Einsatz für das nächste Mal, falls er dafür genügend Geld übrig hat. | ||
| + | Sonst setzt er beim nächsten Mal all sein verbliebenes Vermögen. | ||
| + | </ | ||
| + | Die Idee dahinter: Wenn er beispielsweise 5 Mal verloren hat, also 1+2+4+8+16 = 31 Jetons verloren hat, so setzt er beim nächsten Mal 32 Jetons und macht so seinen Verlust weg und gewinnt sogar einen Jeton dazu. | ||
| + | |||
| + | Schreibe ein Programm, das 10'000 Spielbankbesuche simuliert, jeweils mit einem Startvermögen von 100 Jetons. | ||
| + | Auszugeben sind am Ende: | ||
| + | * Durchschnittsgewinn pro Spielbankbesuch (dieser wird negativ sein - de facto verliert man also langfristig); | ||
| + | * Anteil der Spielbankbesuche in Prozent, die mit einer Vermögensverdopplung enden. | ||
| + | |||
| + | ---- | ||
| + | |||
| + | <hidden Gerüst des fast fertigen Programms, falls benötigt> | ||
| + | Alles zwischen den Fragezeichen ist in Code umzusetzen. | ||
| + | <code python roulette-simulation.py> | ||
| + | from random import * | ||
| + | |||
| + | ANZAHL_SIMULATIONEN = 10000 | ||
| + | ANFANGSVERMOEGEN = 100 | ||
| + | |||
| + | anzahl_gewinne = 0 | ||
| + | gesamt_gewinn = 0 # Kann und wird auch negativ sein. | ||
| + | |||
| + | for simulationsnummer in range(1, ANZAHL_SIMULATIONEN + 1): | ||
| + | vermoegen = ANFANGSVERMOEGEN | ||
| + | einsatz = 1 | ||
| + | while ??? weder pleite noch ANFANGSVERMOEGEN verdoppelt ???: | ||
| + | if randrange(37) < 18: | ||
| + | # die Zufallszahl ist eine der 18 Zahlen von 0 bis 17, | ||
| + | # was wir als Rot interpretieren, | ||
| + | # d.h. der Spieler gewinnt und | ||
| + | # bekommt seinen Einsatz von der Bank. | ||
| + | ??? Passe die Variable " | ||
| + | ??? Passe die Variable " | ||
| + | else: | ||
| + | # Farbe ist Schwarz, | ||
| + | # d.h. der Spieler verliert seinen Einsatz. | ||
| + | ??? Passe die Variable " | ||
| + | einsatz = min(2 * einsatz, vermoegen) | ||
| + | if ??? Vermögen verdoppelt ???: | ||
| + | ??? Zähle den erzielten Gewinn zu " | ||
| + | ??? Erhöhe " | ||
| + | else: | ||
| + | # Alles verloren. | ||
| + | ??? Passe die Variable " | ||
| + | |||
| + | print(f' | ||
| + | print(f' | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | Weitere mögliche Fragestellungen: | ||
| + | * Wie wären die Gewinnchancen, | ||
| + | * Was passiert, wenn man dieselbe Verdopplungsstrategie verwendet, jedoch erst bei einer Verzehnfachung des Anfangsvermögens nach Hause geht? | ||
| + | * Wie viele Runden spielt man durchschnittlich im Gewinnfall? | ||
| + | * Wie viele Runden spielt man durchschnittlich im Verlustfall? | ||
| + | </ | ||
| + | |||
| + | |||
| + | ====== Ideen ====== | ||
| + | |||
| + | (eventuell: Listen und dann Ergebnis-Darstellung durch Säulendiagramme) | ||
| + | * Lissajou-Figuren (passt zu Trigonometrie) | ||
| + | * [[lehrkraefte: | ||
| + | * vermutlich gut für Listen + Säulendiagramm, | ||
| + | * https:// | ||
| + | * | ||
| + | * Roulette mit naheliegender Verdopplungsstrategie (Achtung, Null kann vorkommen): Wie hoch ist der durchschnittlicher erwartete Verlust? | ||
| + | * Mathematische Simulation: $\pi$ per Monte-Carlo (eher nicht) | ||
| + | * Naturwissenschaftliche Simulationen (jeweils Programm-Gerüst vorgeben; braucht jeweils ein zweidimensionales Array; könnte man aber auch mitsamt " | ||
| + | * Korallenwachstum | ||
| + | * Versickerung: | ||
| + | * Game of Life oder Corona-Ausbreitung? | ||
| + | |||
| + | (in Schublade: Turtle-Grafik selbst schreiben, ausgehend von '' | ||
| + | |||
| + | ====== Lösungsvorschlag ====== | ||
| + | |||
| + | <hidden Simulationsprogramm für die durchschnittliche Dauer bis zweimal Kopf, zusätzlich mit Häufigkeits-Säulendiagramm> | ||
| + | <code python muenz-simulation.py> | ||
| + | from random import * | ||
| + | from matplotlib import pyplot | ||
| + | |||
| + | gesamtzahl_wuerfe = 0 | ||
| + | ANZAHL_SIMULATIONEN = 1000000 | ||
| + | |||
| + | def zeichneSaeulendiagramm(xWerte, | ||
| + | # xWerte: Liste der Werte auf der horizontalen Achse | ||
| + | # yWerte: Liste der zugehörigen Funktionswerte | ||
| + | # titel: Titel der Graphik | ||
| + | # xBeschriftung: | ||
| + | # yBeschriftung: | ||
| + | pyplot.figure(" | ||
| + | pyplot.title(titel) | ||
| + | pyplot.xlabel(xBeschriftung) | ||
| + | pyplot.ylabel(yBeschriftung) | ||
| + | pyplot.bar(xWerte, | ||
| + | # pyplot.xticks(xWerte, | ||
| + | pyplot.xticks(range(min(xWerte), | ||
| + | pyplot.tight_layout() | ||
| + | pyplot.show() | ||
| + | |||
| + | haeufigkeit_bei_dauer = [] | ||
| + | for simulationsnummer in range(ANZAHL_SIMULATIONEN): | ||
| + | if simulationsnummer % 100000 == 0 and simulationsnummer > 0: | ||
| + | print(simulationsnummer, | ||
| + | letzter_wurf = 'nicht definiert' | ||
| + | vorletzter_wurf = 'nicht definiert' | ||
| + | anzahl_wuerfe = 0 | ||
| + | while not (letzter_wurf == 1 and vorletzter_wurf == 1): | ||
| + | aktueller_wurf = randrange(1, | ||
| + | anzahl_wuerfe = anzahl_wuerfe + 1 | ||
| + | vorletzter_wurf = letzter_wurf | ||
| + | letzter_wurf = aktueller_wurf | ||
| + | while anzahl_wuerfe > len(haeufigkeit_bei_dauer) - 1: | ||
| + | haeufigkeit_bei_dauer.append(0) | ||
| + | haeufigkeit_bei_dauer[anzahl_wuerfe] = haeufigkeit_bei_dauer[anzahl_wuerfe] + 1 | ||
| + | gesamtzahl_wuerfe = gesamtzahl_wuerfe + anzahl_wuerfe | ||
| + | print(gesamtzahl_wuerfe / ANZAHL_SIMULATIONEN) | ||
| + | # print(haeufigkeit_bei_dauer) | ||
| + | zeichneSaeulendiagramm(range(len(haeufigkeit_bei_dauer)), | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | <hidden Simulationsprogramm für Roulette mit Verdopplungsstrategie> | ||
| + | <code python roulette-simulation.py> | ||
| + | from random import * | ||
| + | |||
| + | ANZAHL_SIMULATIONEN = 100000 | ||
| + | ANFANGSVERMOEGEN = 100 | ||
| + | |||
| + | anzahl_gewinne = 0 | ||
| + | gesamt_gewinn = 0 | ||
| + | |||
| + | for simulationsnummer in range(1, ANZAHL_SIMULATIONEN + 1): | ||
| + | vermoegen = ANFANGSVERMOEGEN | ||
| + | einsatz = 1 | ||
| + | while 0 < vermoegen < 2 * ANFANGSVERMOEGEN: | ||
| + | if randrange(37) < 18: | ||
| + | # die Zufallszahl ist eine der 18 Zahlen von 0 bis 17, | ||
| + | # was wir als Rot interpretieren, | ||
| + | # d.h. der Spieler gewinnt und | ||
| + | # bekommt seinen Einsatz von der Bank. | ||
| + | vermoegen = vermoegen + einsatz | ||
| + | einsatz = 1 | ||
| + | else: | ||
| + | # Farbe ist Schwarz, | ||
| + | # d.h. der Spieler verliert seinen Einsatz. | ||
| + | vermoegen = vermoegen - einsatz | ||
| + | einsatz = min(2 * einsatz, vermoegen) | ||
| + | if vermoegen >= 2 * ANFANGSVERMOEGEN: | ||
| + | gesamt_gewinn = gesamt_gewinn + vermoegen - ANFANGSVERMOEGEN | ||
| + | anzahl_gewinne = anzahl_gewinne + 1 | ||
| + | else: | ||
| + | # Alles verloren. | ||
| + | gesamt_gewinn = gesamt_gewinn - ANFANGSVERMOEGEN | ||
| + | |||
| + | print(f' | ||
| + | print(f' | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | ===== Link zur Kursseite ===== | ||
| + | |||
| + | [[lehrkraefte: | ||
| + | |||