Zum Inhalt springen

Übungen: Unterschied zwischen den Versionen

Aus Martins Wiki
Keine Bearbeitungszusammenfassung
 
(3 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 181: Zeile 181:
* Unterstütze auch Sekundenangaben d.h. 8:15:23 bedeutet 23 Sekunden nach 8:15
* Unterstütze auch Sekundenangaben d.h. 8:15:23 bedeutet 23 Sekunden nach 8:15
* Denke dir Fehler aus, die der Benutzer bei der Eingabe machen könnte (Da gibt es sehr viele!) und erweitere das Programm so, dass diese Fehler benannt werden und der Benutzer danach einen neuen Versuch unternehmen kann.
* Denke dir Fehler aus, die der Benutzer bei der Eingabe machen könnte (Da gibt es sehr viele!) und erweitere das Programm so, dass diese Fehler benannt werden und der Benutzer danach einen neuen Versuch unternehmen kann.
== Zahlenraten ==
Schreibe ein Programm, welches den Benutzer auf der Konsole auffordert, eine zufällig gewählte Zahl zwischen 1 und 100 zu raten (die 1 und 100 sind eingeschlossen). Ein Dialog mit dem Programm könnte so aussehen:
Raten Sie eine Zahl zwischen 1 und 100!
Geben Sie einen Tipp:  <span style="color:red">55</span>
Ihr Tipp liegt zu niedrig!
Geben Sie einen Tipp:  <span style="color:red">88</span>
Ihr Tipp liegt zu hoch!
Geben Sie einen Tipp:  <span style="color:red">74</span>
Richtig geraten!
a) Erweitere das Programm um einen Zähler für die Tipps, die der Benutzer benötigt und gib den Zählerstand am Ende aus.
b) Lege einen maximale Anzahl N von Tipps fest, nach deren Erreichen das Programm abbricht mit der Meldung: "Schade, du hast die Zahl x in N Versuchen nicht erraten!"
c) Gib nach jedem Tipp aus, wie viel Versuche der Spieler noch hat.
d) Frage nach Ende eines Durchgangs, ob der Spieler noch einmal spielen will. Mit der Eingabe von j=ja und n=nein wird ein neuer Durchgang gestartet bzw. das Spiel beendet mit der Ausgabe "Tschüss bis zum nächsten Mal".


== Zahlenraten umgekehrt ==  
== Zahlenraten umgekehrt ==  
Zeile 289: Zeile 273:
  Von den 5 Wörtern hast du 4 korrekt eingegeben.
  Von den 5 Wörtern hast du 4 korrekt eingegeben.


Die Vokabeln (und ihre Übersetzungen) werden zu Beginn von einer Datei gelesen. Eine kleine Sammlung englischer Vokabeln kannst du [[Index.php?title=Medium:Englisch.txt|hier]] herunterladen. Die Datei ist in [https://de.wikipedia.org/wiki/UTF-8 utf-8] kodiert.
Die Vokabeln (und ihre Übersetzungen) werden zu Beginn von einer Datei gelesen. Eine kleine Sammlung englischer Vokabeln kannst du [[Medium:Englisch.txt|hier]] herunterladen. Die Datei ist in [https://de.wikipedia.org/wiki/UTF-8 utf-8] kodiert.


=== Erweiterungen ===
=== Erweiterungen ===
Zeile 449: Zeile 433:
Schreibe ein Konsolenprogramm, das eine Datei einliest und Zeile für Zeile präsentiert. Mit der Return-Taste wird diese Zeile in eine Datei namens 'passt.txt' geschrieben. Wird vorher eine andere Taste gedrückt, z.B. die Leertaste, landet die Zeile in der Datei 'rest.txt'. Man kann das Programm jederzeit anhalten mit der Taste 'q'.
Schreibe ein Konsolenprogramm, das eine Datei einliest und Zeile für Zeile präsentiert. Mit der Return-Taste wird diese Zeile in eine Datei namens 'passt.txt' geschrieben. Wird vorher eine andere Taste gedrückt, z.B. die Leertaste, landet die Zeile in der Datei 'rest.txt'. Man kann das Programm jederzeit anhalten mit der Taste 'q'.


Mit dieser [[Index.php?title=Medium:WoerterGravitar.txt|Wortliste]] kann man z.B. für das Wordle-Programm eine sinnvolle Untermenge an Wörtern auswählen.
Mit dieser [[Medium:WoerterGravitar.txt|Wortliste]] kann man z.B. für das Wordle-Programm eine sinnvolle Untermenge an Wörtern auswählen.


== Radieschen - Ra-dies-chen! ==
== Radieschen - Ra-dies-chen! ==
Stell' dir vor du als Gemüsehändler fragst deine Kunden nach ihren persönlichen Lieblingssorten der Radieschen, die du im Programm hast. Als Ergebnis erhältst du eine Datei, die du [[Index.php?title=Medium:Radieschen.txt|hier]] herunterladen kannst ([http://www.opentechschool.org/ Quelle]). Schreibe ein Python-Programm, das diese Datei einliest und folgende Fragen beantwortet:
Stell' dir vor du als Gemüsehändler fragst deine Kunden nach ihren persönlichen Lieblingssorten der Radieschen, die du im Programm hast. Als Ergebnis erhältst du eine Datei, die du [[Medium:Radieschen.txt|hier]] herunterladen kannst ([http://www.opentechschool.org/ Quelle]). Schreibe ein Python-Programm, das diese Datei einliest und folgende Fragen beantwortet:


* Welche Radieschen-Sorten wurden genannt? Erzeuge eine alphabetisch geordnete Liste.
* Welche Radieschen-Sorten wurden genannt? Erzeuge eine alphabetisch geordnete Liste.
Zeile 794: Zeile 778:
</nowiki>
</nowiki>
Auf diese Weise entfernen wir alle Redundanzen, denn die Verbindung von z.B. G, Gly und Glycine tritt nur einmal auf.
Auf diese Weise entfernen wir alle Redundanzen, denn die Verbindung von z.B. G, Gly und Glycine tritt nur einmal auf.
Schreibe ein Python-Programm, welches obige Tabelle einliest (download [[Index.php?title=Medium:Genetic code.tsv|hier]]) und die geforderte Tabelle mit 21 Zeilen erstellt! Sie sieht in Teilen wie folgt aus:
Schreibe ein Python-Programm, welches obige Tabelle einliest (download [[Medium:Genetic code.tsv|hier]]) und die geforderte Tabelle mit 21 Zeilen erstellt! Sie sieht in Teilen wie folgt aus:


  <nowiki>
  <nowiki>
Zeile 848: Zeile 832:


Legende: Statt einer Färbung wird eine separate Zeile mit folgendem Code ausgegeben: * = grün, ? = gelb, . = grau.
Legende: Statt einer Färbung wird eine separate Zeile mit folgendem Code ausgegeben: * = grün, ? = gelb, . = grau.
Diese [[Index.php?title=Medium:Wortliste.txt|Wortliste]] ist für den Beginn ganz gut geeignet.
Diese [[Medium:Wortliste.txt|Wortliste]] ist für den Beginn ganz gut geeignet.


== Blocksatz ==
== Blocksatz ==
Zeile 1.003: Zeile 987:
Schreibe ein Python-Programm, das dieses Rätsel (und alle anderen dieser Art) löst! Benutze einen [https://de.wikipedia.org/wiki/Texterkennung OCR]-Dienst (z.B. im Internet), welcher das Bild in eine Textdatei umwandelt. So sparst du dir Zeit und Übertragungsfehler!
Schreibe ein Python-Programm, das dieses Rätsel (und alle anderen dieser Art) löst! Benutze einen [https://de.wikipedia.org/wiki/Texterkennung OCR]-Dienst (z.B. im Internet), welcher das Bild in eine Textdatei umwandelt. So sparst du dir Zeit und Übertragungsfehler!


Die Zeitungskopie kann [[Index.php?title=Medium:Wortsuchspiel-24-10-18.jpg|hier]] in besserer Auflösung heruntergeladen werden. Weitere Rätsel finden sich [[Index.php?title=Medium:Wortsuchspiel.zip|hier]].
Die Zeitungskopie kann [[Medium:Wortsuchspiel-24-10-18.jpg|hier]] in besserer Auflösung heruntergeladen werden. Weitere Rätsel finden sich [[Medium:Wortsuchspiel.zip|hier]].


==Sonnenfinsternis==
==Sonnenfinsternis==

Aktuelle Version vom 30. Oktober 2026, 18:34 Uhr

Achtung!

Diese Seite präsentiert Übungsprojekte, die für die Eigenarbeit gedacht sind. Projekte passend für den Unterricht finden sich hier

Schneller Gauß

Es wird erzählt, dass einst der Lehrer von Carl Friedrich Gauß seine Schüler beauftragte, die ersten 100 natürlichen Zahlen zu addieren. So wollte er sich Ruhe für die Zeitungslektüre verschaffen. Doch schon nach zwei Minuten kommt der kleine Fritz mit der richtigen Antwort daher. Wie hat er gerechnet? Und wie kann eine Python-Programmiererin es ihm gleichtun - ohne geniale Idee? Und wie stände sie sehr viel besser als Carl Friedrich da, wenn die Summe der Quadrate der ersten 100 natürlichen Zahlen gefragt wären?

Pferde und Ochsen

Von Leonard Euler ist aus dem 18. Jahrhundert folgende Aufgabe überliefert:

Ein Amtmann kauft Pferde und Ochsen zusammen für 1770 Taler.
Zahlt für ein Pferd 31 Taler. Für einen Ochsen aber 21 Taler.
Wie viel sind es Pferde und Ochsen gewesen?

Die mathematische Lösung dieses Problems ist anspruchsvoll, siehe dieses Video. Der coolen Programmiererin reichen hingegen 6 Zeilen Python-Code, um zur selben Lösung zu gelangen.

Ascii-Gitter

Schreibe ein Programm, das folgende Ausgabe als Text erzeugt:

+--+--+--+--+
|  |  |  |  |
+--+--+--+--+
|  |  |  |  |
+--+--+--+--+
|  |  |  |  |
+--+--+--+--+

Tipp: Der Python Ausdruck 'ab' * 5 liefert 'ababababab'

Danach implementiere die Funktion gitter(rows, columns), welche ein Gitter mit der Zeilenzahl rows und der Spaltenzahl columns produziert.

Ascii-Dach

Schreibe ein Programm mit 2 Zeilen Code, das diese Ausgabe als Text erzeugt:

    /\
   /--\
  /----\
 /------\
/--------\

Danach implementiere die Funktion ascii_dach(height), welche solche Dächer mit der Höhe height produziert.

Erfinde weitere Muster und schreibe Programme dazu, die sie generieren!

Kleines Einmaleins

Schreibe ein Programm mit nur 5 Zeilen Python-Code, das folgende Ausgabe als Text erzeugt:

   1   2   3   4   5   6   7   8   9  10
   2   4   6   8  10  12  14  16  18  20
   3   6   9  12  15  18  21  24  27  30
   4   8  12  16  20  24  28  32  36  40
   5  10  15  20  25  30  35  40  45  50
   6  12  18  24  30  36  42  48  54  60
   7  14  21  28  35  42  49  56  63  70
   8  16  24  32  40  48  56  64  72  80
   9  18  27  36  45  54  63  72  81  90
  10  20  30  40  50  60  70  80  90 100

Tipp: Python print(f'{x:4d}', end='') druckt die ganze Zahl x rechtsbündig in 4 Stellen und vermeidet einen Zeilenumbruch.

Turtles

Turtle ist das englische Wort für Schildkröte. Benutze zum Zeichnen der folgenden Bilder das Turtles-Paket: from turtles import * ... hier kommt dein Code ... done()

Alle Befehle findet ihr hier beschrieben.

Pentagramm

(pente ist das griechische Zahlwort für fünf, gramma ist griechisch und bedeutet Geschriebenes)

Um den Winkel zu bestimmen, um den sich die Schildkröte an jeder Ecke drehen muss, gehe wie folgt vor: Zeichne das Pentagramm mit 5 Linien auf Papier. Dann folge der Figur mit einem flach liegenden Stift anstelle der Schildkröte und beobachte, wie viele Umdrehungen er vollendet hat, wenn er wieder am Ausgangspunkt angekommen ist und die ursprüngliche Richtung wieder eingenommen hat. Verteile diesen Gesamtwinkel auf alle Spitzen der Figur!

Erweiterung: Zeichne einen (rot gefüllten!) Roten Stern!

Hexagramm

(hex ist das griechische Zahlwort für sechs, gramma ist griechisch und bedeutet Geschriebenes)

Ein Hexagramm entsteht durch die Überlagerung zweier gleichseitiger Dreiecke. Mit einer ähnlichen Überlegung wie beim Pentagramm lassen sich dann auch hier die Drehwinkel für die Schildkröte bestimmen. Allerdings muss man hier der Kontur folgen!

Stern

Auf dieser Seite oben kannst du die benötigten Winkel erkennen!

Quadrat-Spirale

Verändere das Programm so, dass eine Dreieck-Spirale oder eine 5-Eck-Spirale entsteht. Schließlich programmiere eine Funktion, welche die Anzahl der Ecken als Parameter erhält.

Spirale

Zeichne folgende Spirale, ohne Winkelfunktionen (sin, cos) zu verwenden!

Konzentrische Quadrate

Wenn die Bewegung der Schildkröte keinen Spur hinterlassen soll, sage einfach vorher penup() und anschließend wieder pendown()

Mäander

Schreibe eine Python-Funktion namens meander, die ein beliebig langes Mäander-Muster zeichnet, so wie dieses:

meander hat 2 Parameter: 1. Höhe des Bandes, 2. Anzahl der Wiederholungen. Passe die Strichstärke automatisch an die Höhe an!

Schachbrett

Tipp: Schreibe erst ein Programm, das eine Reihe Felder malt. Dann wiederhole dies, aber starte mit der anderen Füllfarbe.

Polygon

Schreibe dazu eine Funktion 'poygon(n, size)' mit n = Anzahl der Seiten und size = Seitenlänge, welche die einzelnen Vielecke zeichnet.

Skalierung

Unter Skalierung sei hier die Anpassung der Größe einer Grafik verstanden. Das Bild zeigt Kerzen in absteigender Größe. Sie wurden mit immer derselben Funktion in einer for-Schleife gezeichnet, wobei der zeichnenden Funktion eine size-Parameter übergeben wurde, der beständig kleiner wurde. Programmiere eine eigene Grafikfunktion und multipliziere alle Längen in den forward-Befehlen mit dieser size. Male beispielsweise ein kleines Haus mit rotem Spitzdach, Tür und Fenster. Dies kann dann auf deinem Bild an verschiedenen Stellen in veschiedenen Größen erscheinen.

Flaggen

Nationalflaggen bieten eine gute Gelegenheit, das Programmieren mit Turtle zu üben. Von ganz einfach (wie die deutsche Flagge) über mittelschwer (wie das Star Sparkled Banner der USA) bis zu sehr ausgefallen und komplex (portugiesische Flagge) ist alles dabei. Hier findet man sie sortiert! Versuche zunächst für ein Land deiner Wahl die Flagge zu zeichnen. Danach packe den Code in eine Python-Funktion mit entsprechendem Namen, der man als Argument die Breite in Pixel übergibt. Alle anderen Abmessungen sollen aus dieser einzigen Größe abgeleitet werden. Das ermöglicht es, die Flagge an irgendeiner Position in irgend einer Richtung (= aktuelle Stellung der Turtle) in irgend einer Größe zeichnen zu lassen. So kann man sich später leicht einen "Flaggen-Teppich" zusammen basteln. Tipp: Um beim Zeichnen an einen Start- oder Zwischenpunkt zurück zu kehren, merke man sich diesen mit der Funktion position() und heading(), um ihn dann später mit goto(pos) und setheading(head) wieder einzunehmen.


Kranz

Schreibe ein Python-Programm, das obige Grafiken

  1. des einfachen Musters,
  2. der Kette und
  3. des Kranzes produziert.

Danach verallgemeinere den Code wie folgt.

  • Schreibe eine Funktion def kette(größe, n, muster): ..., die eine beliebige Funktion namens muster entgegen nimmt und das Muster n-Mal mit der Größe größe in einer Reihe darstellt.
  • Schreibe eine Funktion def kranz(größe, n, muster): ..., die eine beliebige Funktion namens muster entgegen nimmt und das Muster n-Mal mit der Größe größe in einem Kranz darstellt.

Erfinde dazu neue Muster und/oder übernehme das Pentagramm und den Mäander von oben! Im einfachsten Fall ist das Muster eine Linie und es ergibt sich als Kette ... ?

Parkettierung

Dazu bemerkt die Wikipedia: "In der Mathematik bezeichnet Parkettierung die lückenlose und überlappungsfreie Überdeckung der (euklidischen) Ebene durch gleichförmige Teilflächen." Wer einmal die Logik des Aufbaus verstanden hat, kann sich an die Umsetzung mit Turtles machen. So entstehen Schritt für Schritt die schönsten Muster. Man muss nicht immer alle Abstände und Längen vorab ausrechnen. Wenn's zu kompliziert wird, kann man auch ein wenig rumprobieren, bis der Bildeindruck (auch im Detail) stimmt. Versucht euch einmal an den Mustern auf dieser Seite!

Bewegliche Lettern

So hieß die Erfindung von Johannes Gutenberg, der die Massenproduktion von Schriften in die Welt brachte. (Vorher musste man Bücher von Hand abschreiben!) Den Lettern in seinem Setzkasten entsprechen bei uns Python-Funktionen, je eine für jeden Buchstaben des Alphabets. Beim Setzen bzw. Schreiben war sein Vorrat erschöpflich, unser ist es nicht! (Warum nicht?)

Schreibe ein Python-Programm, das beliebige Texte mit diesen Lettern zeichnet, wie im Bild zu sehen. Tipps:

  • Setze die Buchstaben aus einzelnen Linien und Halbkreisen zusammen!
  • Benutze für die Funktion des Buchstabens ? die Signatur write_?(height, width).
  • Jede Funktion zeichnet ihren Buchstaben an der aktuellen Turtle-Position als linke untere Ecke in ein Rechtecks mit der Höhe height und der Breite width.
  • Zur Vereinfachung des elliptischen 'O' zeichne stattdessen ein Oval mit zwei Halbkreisen oder eine Raute! (Im Bild wurden Sinus/Cosinus-Funktionen verwendet)
  • Für das obige Bild wurden folgende Turtle-Funktionen verwendet: penup, goto, pendown, speed, left, forward, right, circle, pos, width, heading, setheading, done.
  • Mit WIDTH = 600; HEIGHT = 220; getscreen().setup(width=WIDTH, height=HEIGHT) verkleinert man das Fenster.

Erweiterungen:

  • Lese den zu schreibenden Text aus einem String bzw. von einer Datei! Verwende dazu ein dictionary mit key = Buchstabe und value = Buchstabenfunktion!
  • Wie muss man die Buchstabenfunktionen programmieren, damit die Buchstaben beliebig gedreht und so auf einen Kreisumfang erscheinen können? Realisiere das!
  • Füge einen automatischen Zeilenumbruch ein bzw. verwende den Blocksatz, wie weiter unten in einem anderen Projekt beschrieben!
  • Variiere beim Schreiben die Höhe, Breite und Abstand der Buchstaben!
  • Übergebe Strichstärke und Farbe als Parameter und erzeuge so bunte Texte!
  • Zeichne einen Text, der in einer Spirale immer kleiner wird...
  • Denke dir andere Spielarten der Textgestaltung aus und programmiere sie!

Bunte Würfel

Neun bunte Würfel schweben im Raum -- aber irgendwas stimmt da nicht!

Was dich aber nicht hindern sollte, diese Grafik mit Turtle zu erzeugen: Aus welchen elementaren Figuren besteht das Bild? Welche Winkel sind im Spiel? Wie könnte man das Programm in Funktionen aufteilen? Wie geht man mit der Unmöglichkeit um? Erst wenn du diese Fragen beantwortet hast, mache dich ans programmieren! Wenn du es besonders gut machen willst, führe eine Konstante ein, die die Anzahl von Würfeln in einer der Reihen festlegt! Wie sieht die Grafik mit 3, 5 oder mehr Würfeln in der Reihe aus?

Zeitraum

Wie viel Zeit vergeht zwischen 8:15 Uhr und 13:10 Uhr? Das Berechnen von Zeiträumen zwischen zwei Tageszeiten ist wegen des verwendeten Sexagesimalsystems umständlich. Dem kannst zu abhelfen! Schreibe ein Python-Programm, das ohne Importe von Spezialmodulen folgenden Dialog erzeugen kann (und sonst natürlich alle Zeitdifferenzen berechnen!):

Bitte zwei Zeiten eingeben: 8:15 13:10
Die Zeitdifferenz beträgt   4:55

Die Benutzereingabe ist in rot dargestellt. Tipp: Benutze die Funktionen split, int und str!

Erweiterungen:

  • Statt 8:5 schreibe 08:05 d.h. schreibe führende Nullen (Benutze f'{x:02d}', um x umzuwandeln!)
  • Falls die zweite Uhrzeit kleiner ist als die erste, nimm an, dass sie im kommenden Tag liegt! Zwischen 23:55 und 00:05 sollten also 10 Minuten (00:10) vergehen!
  • Unterstütze auch Sekundenangaben d.h. 8:15:23 bedeutet 23 Sekunden nach 8:15
  • Denke dir Fehler aus, die der Benutzer bei der Eingabe machen könnte (Da gibt es sehr viele!) und erweitere das Programm so, dass diese Fehler benannt werden und der Benutzer danach einen neuen Versuch unternehmen kann.

Zahlenraten umgekehrt

Jetzt muss der Computer raten, welche Zahl sich der Benutzer gemerkt hat. Ein Dialog mit der Merkzahl 42 könnte so aussehen:

Merke dir eine Zahl zwischen 1 und 100!
Ich werde versuchen, sie so schnell wie möglich herauszufinden.
Drücke die Eingabetaste, wenn du soweit bist!
Ich tippe auf 50. Bitte gib ein:  1, falls 50 zu klein ist;  2, falls 50 richtig ist;  3, falls 50 zu groß ist
3
Ich tippe auf 25. Bitte gib ein:  1, falls 25 zu klein ist;  2, falls 25 richtig ist;  3, falls 25 zu groß ist
1
Ich tippe auf 37. Bitte gib ein:  1, falls 37 zu klein ist;  2, falls 37 richtig ist;  3, falls 37 zu groß ist
1
Ich tippe auf 43. Bitte gib ein:  1, falls 43 zu klein ist;  2, falls 43 richtig ist;  3, falls 43 zu groß ist
3
Ich tippe auf 40. Bitte gib ein:  1, falls 40 zu klein ist;  2, falls 40 richtig ist;  3, falls 40 zu groß ist
1
Ich tippe auf 41. Bitte gib ein:  1, falls 41 zu klein ist;  2, falls 41 richtig ist;  3, falls 41 zu groß ist
1
Es muss die 42 sein!
Ende

Lesetest

Wenn dir klar ist, was mit obiger Darstellung gemeint ist, schreibe ein Python-Programm, dass jeden Text in diese Form umwandelt! Man kann es auch noch weiter treiben:

D1353 M17731LU\G D13\7 4L5 83W315 D4FU3R, W45 FU3R 3R574U\L1C#3 D1\G3 U\53R V3R574\D L31573\ K4\\. 8331\DRUCK3\D! 4M 4\F4\G W4R'5 \0C# 5C#W3R, 483R J3727, 1\ D1353R 231L3 L1357 35 D31\ G3#1R\ 4U70M4715C# 0#\3 D4RU383R \4C#2UD3\K3\, 531 570L2 D4R4UF! 4L50 731L3 D13535 81LD, W3\\ DU 35 L353\ K4\\57!

Ballonjagd für Fortgeschrittene

Die Ballonjagd aus der Projektliste stellt eine Magerversion dar, die unbedingt um spannende Elemente erweitert werden sollte, wie z.B. diese:

  • Das Spielfeld sollte vergrößert werden!
  • Sobald sich der Mauszeiger dem Ballon nähert, wird dieser unsichtbar. Er kann aber weiterhin getroffen werden! Dazu registriert eine Funktion, welche die Mausbewegung erfasst: canvas.bind('<Motion>', mouse_moved). Dann könnt ihr in einer Funktion def mouse_moved(event): print('mouse moved:', event) die Maus-Koordinaten auswerten.
  • Es sind immer mehrere Ballons zu sehen, die nach kurzer Zeit wieder verschwinden, auch wenn man sie nicht abgeschossen hat. Das gibt dann Punkteabzug!
  • Es erscheinen viele Ballons mit unterschiedlicher Färbung, welche auf eine Wertigkeit verweist. Z.B. zählen rote Ballons 10 Punkte, gelbe 5 und grüne 2 Punkte. Dafür verschwinden sie auch von selbst wieder nach z.B. 1, 3 bzw. 5 Sekunden.
  • Neue Ballons erscheinen in der unteren Hälfte des Spielfeldes und wandern dann nach oben. Man darf keinen entkommen lassen, sonst...
  • Füge Sounds für den Schuss sowie - falls getroffen - das Platzen des Ballons hinzu! Benutze dazu die Technik aus dem Übungsprojekt "Zahlenvorleser". Du kannst zwei Sounddateien hier herunterladen: shot.wav und bamf.wav.

Reaktionszeit-Tester

Schreibe ein Konsolenprogramm, dass deine Reaktionszeit testet. Nach dessen Start vergeht eine unbekannte Anzahl von Sekunden (z.B. 2-10), bevor eine Reihe von Sternen auf der Ausgabe erscheint. Jetzt musst du schnell reagieren. Die Ausgabe sieht dann so aus:

  • Wenn du bereit bist, drücke die ENTER-Taste.
  • Sobald du Sterne siehst, drücke ein zweites Mal!
  • Mit "q" beendest du das Programm
  • --- hier drückt der Benutzer im Sekundentakt ---
  • Deine Reaktionszeit betrug 0.39 Sekunden.

Danach hast du einen weiteren Versuch: "Wenn du bereit bist, ..." usw. Anstatt der Sternchen kannst du auch mit print('\a') einen Ton ausgeben, auf den man reagieren muss.

Bunte Schlange

Mit sehr wenig Aufwand lässt sich die Schlange aus dem Snake-Projekt aufhübschen: Mit z.B. einem gelben Kopf und einer regelmäßigen Bänderung. Es kommen zur Hilfe: Der Modulo-Operator sowie der enumerate-Befehl.

Wer darüber hinaus noch Anregungen für Erweiterungen sucht, hier sind ein paar Vorschläge:

  1. Erlaube der Schlange auch diagonale Bewegungen. Dabei kann ein Joystick/Gamepad helfen!
  2. Verstreue zufällig oder permanent Giftpillen auf dem Feld, welche die Schlange meiden muss. Ansonsten ist sie erledigt oder wird kurzerhand halbiert.
  3. Erhöhe die Anzahl der Zellen, ohne das Spielfeld zu vergrößern und lasse die Schlange dafür entsprechend schneller laufen.
  4. Lasse die Gitterlinien weg, sodass man genauer hinschauen muss, um den richtigen Zeitpunkt zum Abbiegen zu finden.
  5. Lege mehrere Beutestücke aus, die sich in der Farbe unterscheiden und verschiedene Bonuspunkte sammeln. Zeige diese in einem zusätzlichen Bereich des Fensters kontinuierlich an!
  6. Füge Spiel-Ebenen (Levels) ein, in die man kommt, wenn die Schlange eine bestimmte Länge erreicht bzw. genügend Bonuspunkte gesammelt hat.
  7. Anstatt einfarbiger Zellen fülle diese mit kleinen Bildchen.
  8. Lasse eine verfeindete Schlange mit über das Bild laufen, der deine Schlange fern bleiben muss.
  9. Mache die Beute beweglich
  10. usw. usf.

Schaltjahr

Schreibe eine Funktion tage_im_monat(jahr, monat) welche die Anzahl der Tage zurückgibt, die unser Kalender für das gegebene Jahr und den gegebenen Monat festlegt. Der Monat sei hier durch die Zahlen 1-12 entsprechend Januar-Dezember vertreten.

Der Aufruf tage_im_monat(2024, 3) soll also die Zahl 31 liefern.

Als Vorbereitung mache dich schlau bezüglich der Schaltjahre und welches Problem damit gelöst wird, zum Beispiel in der Wikipedia.

Benutze als Testdaten alle Monate der Jahre 2023 und 2024 sowie den Februar der Jahre 1900 und 2000.

Erweitere deinen Code, sodass du den Zeitraum zwischen zwei Kalendertagen auf Anfrage berechnen und ausgeben kannst, z.B. zwischen dem 12.1.2024 und dem 5.10.2024 oder auch 5.10.2027. Beachte: Man kann diese Aufgabe auch mit dem time-Modul lösen!

Ping-Pong

Erweitere das Pong-Spiel um einen zweiten Spieler, der für das Ping zuständig ist! Oder erweitere es um eine Maus-Steuerung und Spielsteine, die man abräumen muss. Als Anregung schaue dir das Video über Atari ST Bolo an!

Vokabeltrainer

Schreibe ein Konsolenprogramm, das Vokabeln in zufälliger Reihenfolge abfragt. Ein Dialog könnte so aussehen:

Willkommen beim Vokabeltrainer!
Auto - car
Blume - flower
Vater - vather
Falsch! Richtig wäre gewesen: father
Fenster - window
Ohr - ear
Von den 5 Wörtern hast du 4 korrekt eingegeben.

Die Vokabeln (und ihre Übersetzungen) werden zu Beginn von einer Datei gelesen. Eine kleine Sammlung englischer Vokabeln kannst du hier herunterladen. Die Datei ist in utf-8 kodiert.

Erweiterungen

  • Gib eine nützliche (!) Fehlermeldung aus, falls eine Zeile in der Wörterdatei nicht dem geforderten Format entspricht!
  • Gib abwechselnd oder vom Zufall gesteuert entweder das deutsche oder das fremdsprachige Wort vor!
  • Stoppe die benötigte Zeit!
  • Vermeide die Wiederholung eines Wörterpaares während einer Sitzung!
  • Signalisiere, wenn alle Wortpaare der geladenen Datei einmal abgefragt wurden!
  • Frage zunächst nach der zu benutzenden Wörterdatei. Liste dazu alle Textdateien im aktuellen Verzeichnis auf, sodass der Benutzer über deren Position in der Liste wählen kann d.h. Nummer 1 - ...
  • Führe eine Datei, in der du deine Leistungen protokollierst (Datum nicht vergessen!). So kannst du deinen Fortschritt über die Tage und Wochen verfolgen.

Euklid interaktiv

Erweitere das Programm zur Berechnung des größten gemeinsamen Teilers nach Euklid so, dass folgender Dialog möglich wird:

Berechnung des größten gemeinsamen Teiler zweier Zahlen
Gib hier die erste Zahl ein: 1071
Und jetzt die zweite Zahl: 1029
Der größte gemeinsame Teiler von 1071 und 1029 ist 21
1071 / 21 = 51
1029 / 21 = 49
Nochmal? Gib j für ja oder n für nein ein: j
Berechnung des größten gemeinsamen Teiler zweier Zahlen
Gib hier die erste Zahl ein: 1920
Und jetzt die zweite Zahl: 1280
Der größte gemeinsame Teiler von 1920 und 1280 ist 640
1920 / 640 = 3
1280 / 640 = 2
Nochmal? Gib j für ja oder n für nein ein: n
Bis zum nächsten Mal!

Quatsch-Generator

Schreibe ein Programm, das Sätze ausgibt wie folgende:

Die verrückte Lokführerin streichelt jeden Tag den Mond.
Meine coole Tante beschimpft immerzu das Fenster.

Die entstehenden Sätze sind grammatikalisch immer korrekt, ihr Inhalt sollte oft skurril und manchmal lustig sein. Tipps:

  • Bestimme die grammatikalischen Satzteile der beiden Sätze oben.
  • Lege Vorräte d.h. Wörter bzw. Wort-Kombinationen dieser Satzteile an.
  • Füge die Wörter zufallsgesteuert nach dem selben Schema wie oben zusammen.

Angenommen du hast für jeden Satzteil 10 Stück im Vorrrat. Wieviel Sätze kannst du damit bauen?

Interessante Erweiterung: Lasse die Sätze aussprechen, indem du die einzelnen Bausteine erst per Mikrofon aufnimmst und dann als Audio-Dateien hintereinander abspielst. Siehe das Projekt "Zahlenvorleser" um zu sehen, wie man so etwas macht.

Abrechnung

Fünf Leute fahren ein paar Tage zum Skilaufen. Drei von Ihnen haben Proviant eingekauft, dessen Kosten sich die fünf teilen wollen. Die Abrechnung soll ein Python-Konsolenprogramm erledigen. Ein Dialog könnte so aussehen:

-- Willkommen bei der Abrechnung --
Gib die Namen und ausgelegten Beträge ein! Ein "=" startet die Berechnung.
Anja 157
Boris 55
Celine 63
Denise 0
Emil 0
=
5 Personen teilen sich Kosten von insgesamt 275 Euro.
Das macht für jeden 55.0 Euro.
Der Kostenausgleich sieht folgendermaßen aus:
>  Anja bekommt 102.0 Euro zurück
>  Boris zahlt nichts und bekommt auch nichts zurück
>  Celine bekommt 8.0 Euro zurück
>  Denise zahlt 55.0 Euro ein
>  Emil zahlt 55.0 Euro ein

Erweitere das Programm um die Option, dass einige Teilnehmer früher abreisen als andere, auch wenn sie mit eingekauft haben. Deren Anteile sollen proportional zur Zeitdauer in ganzen Tagen berechnet werden. Tipp 1: Man gibt die Aufenthaltsdauer in Tagen als drittes Datum für jeden Teilnehmer ein. Tipp 2: Berechne die Tagesportionen, auf die der Proviant verteilt wird und berechne dann den Verbrauch pro Person. Entwickle eine Lösung für das Problem als Tabellenkalkulation (z.B. mit Excel) und vergleiche die Resultate bezüglich Aufwand, Handhabung, auch für nachträgliche Korrekturen der Eingabe etc.

Innere Uhr

Schreibe ein Programm, welches dir zeigt, wie gut du den Verlauf der Zeit in Sekunden abschätzen kannst. Mit wiederholtem Drücken auf die Return-Taste gibst du deinen gefühlten Sekundentakt vor. Am Ende wird ein Diagramm erstellt, das dir deine Leistung verdeutlicht. Liegen die Punkte, welche deine Tastendrücke darstellen, exakt auf der Linie, tickst du perfekt!

7-Segment-Digitaluhr

Schreibe ein Programm, das auf der Kommandozeile im Sekundentakt die aktuelle Uhrzeit anzeigt, und zwar in diesem Format:

Tipps zum schrittweisen Vorgehen:

  1. Gib zunächst eine Null in Textform aus.
  2. Trenne die auszugebenden Strings vom print()-Befehl und speichere sie in einer Liste.
  3. Programmiere die Anzeige in einer for-Schleife.
  4. Erweitere auf die Ziffern 1-9.
  5. Zeige alle Ziffern nebeneinander an.
  6. Bestimme die numerischen Werte der Uhrzeit für Stunden, Minuten und Sekunden mit dem time-Paket.
  7. Gib nur die Sekunden als 2 Ziffern aus. Fülle bei Bedarf eine Null ein.
  8. Erweitere auf die gesamte Uhrzeit.

Alternative: Gib die Uhrzeit in grafischer Form aus, z.B. mit tkinter oder Pygame!

Rückgeld

LOC 70. Kassen-Automaten in Bahnhöfen oder Parkhäusern akzeptieren Bargeld. Darum müssen sie auch "herausgeben", wie man sagt d.h. bei Überzahlung den überschüssigen Betrag auswerfen.

Schreibe ein Python-Konsolenprogramm, das

  1. dem Benutzer einen zufälligen Zahlbetrag präsentiert.
  2. eine symbolische Zahlung als Münzen oder Scheine entgegen nimmt.
  3. den überzahlten Betrag ebenso symbolisch ausgibt.

Beispiele für Dialoge: (Benutzer-Eingabe in rot)

Bitte zahlen Sie 38.64 Euro!
20E 10E 10E
Sie haben 40.00 Euro gegeben. Das reicht.
Es werden 1.36 Euro zurückgezahlt.
Ihr Rückgeld: 1E 20C 10C 5C 1C
Bezahlung erfolgreich abgeschlossen
---
Bitte zahlen Sie 83.01 Euro!
50E
Sie haben bislang 50.00 Euro gegeben. Es fehlen noch 33.01 Euro.
20E 20E
Sie haben 90.00 Euro gegeben. Das reicht.
Es werden 6.99 Euro zurückgezahlt.
Ihr Rückgeld: 5E 1E 50C 20C 20C 5C 2C 2C
Bezahlung erfolgreich abgeschlossen

Brute-Force Attack

Das Caesar-Verfahren zur Verschlüsselung von Texten (Siehe das Projekt Geheim) ist leicht auszuhebeln: Man muss nur alle 26 Schlüssel durchprobieren und schauen, ob sich ein sinnvoller Text ergibt. Schreibe ein Programm, das einen Dialog wie den folgenden unterstützt:

Willkommen beim Brute-Force Angriff!
Bitte Geheimtext eingeben: xirw mfe vcq zjk uvi mviiäkvi. evydk zye wvjk!
-------------- brute force --------------
a : xirw mfe vcq zjk uvi mviiäkvi. evydk zye wvjk!
b : whqv led ubp yij tuh luhhäjuh. duxcj yxd vuij!
...
q : hsbg wpo fma jtu efs wfssäufs. ofinu jio gftu!
r : graf von elz ist der verräter. nehmt ihn fest!
s : fqze unm dky hrs cdq udqqäsdq. mdgls hgm edrs!
...

Geheimer

Sicherer als die Caesar-Verschlüsselung ist ein Verfahren, bei dem man die Buchstaben des Alphabets nach Plan verwürfelt. Dieser Plan kann z.B. einem Code-Wort zur Verschlüsselung und Entschlüsselung folgen, wie dem folgenden Bild zu entnehmen:

Verschlüsselung mit dem Code-Wort "Zuckerdose":

Klarbuchstabe:     zuckerdosabfghijlmnpqtvwxy
                   ||||||||||||||||||||||||||
Geheimbuchstabe:   abcdefghijklmnopqrstuvwxyz

Man notiert zunächst das Code-Wort und unterdrückt die Wiederholung von Buchstaben (im Beispiel das e am Ende des Wortes). Dann füllt man die Reihe auf mit den noch verbleibenden d.h. ungenutzten Buchstaben des Alphabets. Jetzt kann man jeden Buchstaben des Klartextes durch Geheimbuchstaben ersetzen d.h. jedes z durch ein a, jedes u durch ein b und so weiter. Schreibe zwei Python-Funktionen, die einen gegebenen Text anhand eines Code-Wortes ver- bzw. entschlüsseln! Beide Funktionen nutzen eine dritte, welche das "verwürfelte Alphabet" (im obigen Bild die erste Zeile) generiert.

Noch geheimer

Die Caesar-Verschlüsselung lässt sich automatisch mit Brute-Force knacken, wenn man den "Klartext" auf bekannte Wörter hin untersuchen lässt. Die werden nämlich nur mit dem richtigen Schlüssel erscheinen. Dem kann man nun entgegenwirken, indem man folgende Erkenntnis nutzt:

Afugrnud enier Sduite an enier Elingshcen Unvirestiät ist es eagl, in wlehcer Rienhnelfoge die Bcuhtsbaen in eniem Wrot sethen, das enizg wcihitge dbaei ist, dsas der estre und lzete Bcuhtsbae am rcihgiten Paltz snid. Der Rset knan ttolaer Bölsdinn sien, und du knasnt es torztedm onhe Porbelme lseen. Das ghet dseahlb, wiel wir nchit Bcuhtsbae für Bcuhtsbae enizlen lseen, snodren Wröetr als Gnaezs.

Schreibe ein Python-Programm, das jeden Text auf diese Weise verschleiert (obfuscated). Kurze Wörter könnte man zusätzlich "umdrehen" d.h. die Reihenfolge der Buchstaben umkehren, also rückwärts lesen.

KFZ-Kennzeichen

Erweitere das Programm aus dem Unterricht so, dass der Benutzer neue Einträge vornehmen kann, wie z.B. HCH für Hechingen. Mehr Tipps finden sich hier. Diese Einträge sollen auf Anweisung mit dem alten Datenbestand gespeichert werden. Die Auswahl des Bundeslandes soll dabei mit einem 2-Buchstaben-Code möglich sein, also z.B. mit BW = Baden-Württemberg. Alle Abkürzungen findet man hier. Wer noch weiter gehen will, kann auch die Löschung eines Eintrages programmieren. Die Originaltabelle gibt es hier zum herunter laden. Tipp: Schreibe zunächst einen konkreten Dialog zwischen Programm und Benutzer für die Zusatzfunktionen und nimm diesen als Leitfaden für die Programmierung.

Angenommen, zwei Benutzer haben mit dem obigen Programm unterschiedliche Neu-Einträge an der Liste der Kfz-Kennzeichen vorgenommen und in jeweils eine Datei gespeichert. Schreibe ein Programm, welches beide Dateien einliest und alle Ergänzungen in einer dritten Datei zusammenführt! (Doppelte Einträge sind natürlich unerwünscht!)

Aschenputtel

"Die schlechten ins Kröpfchen, die guten ins Töpfchen!" - so heißt es in dem Märchen. Will man z.B. aus einer langen Wortliste passende Wörter herausfischen, so tut man sich mit einem Texteditor schwer, denn das ist zu umständlich. Warum nicht ein Wort nach dem anderen vorschlagen lassen und mit einem Tastendruck zwischen Töpfchen und Kröpfchen entscheiden?

Schreibe ein Konsolenprogramm, das eine Datei einliest und Zeile für Zeile präsentiert. Mit der Return-Taste wird diese Zeile in eine Datei namens 'passt.txt' geschrieben. Wird vorher eine andere Taste gedrückt, z.B. die Leertaste, landet die Zeile in der Datei 'rest.txt'. Man kann das Programm jederzeit anhalten mit der Taste 'q'.

Mit dieser Wortliste kann man z.B. für das Wordle-Programm eine sinnvolle Untermenge an Wörtern auswählen.

Radieschen - Ra-dies-chen!

Stell' dir vor du als Gemüsehändler fragst deine Kunden nach ihren persönlichen Lieblingssorten der Radieschen, die du im Programm hast. Als Ergebnis erhältst du eine Datei, die du hier herunterladen kannst (Quelle). Schreibe ein Python-Programm, das diese Datei einliest und folgende Fragen beantwortet:

  • Welche Radieschen-Sorten wurden genannt? Erzeuge eine alphabetisch geordnete Liste.
  • Was sind die 5 beliebtesten Sorten?
  • Welche Sorte bekam die wenigsten Stimmen und wie viele waren dies?
  • Hat jemand zweimal seine bzw. ihre Stimme abgegeben? Dann zähle nur die erste!
  • Welche praktischen Probleme ergaben sich bei der Auswertung und wie hast du sie gelöst? Was hast du daraus für ähnliche Aufgaben gelernt?

In einer zweiten Version deines Programms benutze den Datentyp Counter aus dem collections-Modul.

Bundesliga

Aus dem Netz, oder (hier), kann man sich die Ergebnisse aller Spiele der Fußball-Bundesliga der Saison 2019-2020 herunterladen. Man erhält dann eine Datei der Form (von mir etwas aufgehübscht):

1. Spieltag
16.08.2019  20:30  Bayern München - Hertha BSC         2:2 (1:2)  
17.08.2019  15:30  Borussia Dortmund - FC Augsburg     5:1 (1:1)  
            15:30  Bayer Leverkusen - SC Paderborn 07  3:2 (2:2)  
            15:30  VfL Wolfsburg - 1. FC Köln          2:1 (1:0)  
...

mit insgesamt 340 Zeilen. Schreibe Python-Programme für folgende Aufgabenstellungen:

  1. Welche Vereine haben gespielt? Gib die Liste auf der Konsole aus!
  2. Wie erklärt sich die Anzahl der Spieltage? Diese Frage kann man ohne zu programmieren beantworten.
  3. Wieviel Spiele wurden insgesamt durchgeführt? Auch diese Frage kann man ohne zu programmieren beantworten.
  4. Gibt es einen Heimvorteil d.h. wie oft gewann der Gastgeber? (Der Gastgeber wird bei den Spielen immer zuerst genannt.)
  5. Wieviel Tore wurden insgesamt geschossen?
  6. Welcher Verein hat die meisten Auswärtsspiele gewonnen?
  7. Wie oft gelang es, einen Halbzeitrückstand in einen Sieg zu verwandeln?
  8. Wer musste die längste Serie von Niederlagen hinnehmen?
  9. Erstelle eine Schlusstabelle mit den Spalten: Rang, Verein, Anzahl Spiele, Siege, Unentschieden, Niederlagen, Torverhältnis, Tordifferenz, Punktestand
  10. Wie sähe die Schlusstabelle aus, wenn nur die Spiele der besten 7 Vereine gegeneinander gezählt worden wären?
  11. Wann wurde klar, dass Bayern München Meister wird?
  12. An welchem Spieltag wurden die meisten Tore geschossen?
  13. Denke dir weitere Fragen aus, die du mit Python beantworten kannst!

Tipps allgemein:

  1. Befreie dich nach dem Lesen der Spiele-Datei von allem Leerraum (engl. whitespace) d.h. allen Leerzeichen, Tabs und Zeilenumbrüchen am Anfang und Ende der Strings.
  2. Erzeuge eine Spieletabelle mit den Spalten Spieltag, Datum, Uhrzeit, Heim, Gast, Endstand, Halbzeitstand für alle Spiele. Diese dient als Grundlage für alle weiteren Auswertungen.

Tipps für die Schlusstabelle:

  1. Erkenne die Vereine d.h. versammle die Vereinsnamen in eine Liste.
  2. Erstelle eine noch leere Statistik als Dictionary mit dem Vereinsnamen als Schlüssel und für jeden Verein als Wert ein eingebettetes Dictionary mit den Spalten der Schlusstabelle als Schlüssel.
  3. Fülle die Statistik mit den Daten aus der Spieletabelle Spiel für Spiel.
  4. Verwandle die Statistik in eine Tabelle und sortiere diese. (Das ist nicht so einfach!)
  5. Drucke die Tabelle auf die Konsole und achte dabei auf Bündigkeit. Die ersten Zeilen sehen so aus:
 1 Bayern München       34 26  4  4 100:32   68 82
 2 Borussia Dortmund    34 21  6  7 84:41    43 69
 3 RB Leipzig           34 18 12  4 81:37    44 66

Zum Knobeln

Achtung: Die folgenden Aufgaben erledigt man nicht so nebenher. Man muss sich schon intensiv eindenken! Letztlich steckt der wichtige Code in den while- und for-Schleifen.

Primfaktorzerlegung

Der Fundamentalsatz der Arithmetik besagt, dass jede natürliche Zahl, die größer als 1 und selbst keine Primzahl ist, sich als Produkt von mindestens zwei Primzahlen schreiben lässt. Programmiere eine Primfaktorzerlegung der Zahl N durch Probedivision. Statt nur durch Primzahlen zu dividieren, verwende alle Zahlen kleiner Wurzel N. Dies erhöht zwar die Laufzeit des Programms, vereinfacht aber den Code. Beispiele: 120 = 2 * 2 * 2 * 3 * 5, 8.305.813.539 = 3 * 3 * 17 * 19 * 31 * 37 * 47 * 53.

Vier-Quadrate-Satz

Der Vier-Quadrate-Satz der mathematischen Zahlentheorie besagt, dass sich jede natürliche Zahl als Summe von genau 4 Quadratzahlen darstellen lässt. Quadratzahlen sind 0, 1, 4, 9, 16, 25, 36, ..., also jeweils 0, 1, 2, 3, 4, 5, 6, ... mit sich selbst malgenommen. Beispiele: 15 = 9 + 4 + 1 + 1, 35 = 25 + 9 + 1 + 0. Schreibe ein Python-Skript, dass für eine gegebene natürliche Zahl eine entsprechende Darstellung bzw. Zerlegung liefert! Wie lauten die Zerlegungen der Zahlen von 0 bis 10.000?

Wechselgeld

Wieviel Möglichkeiten gibt es, einen Euro in kleinere Münzen zu wechseln? Tipp: Gehe schrittweise vor und betrachte zunächst nur 50 Cent, dann 50 und 20-Cent Münzen. Nehme dann 10er und 5er hinzu usw. Mit rekursiver Programmierung und Ausgabe jeder Kombination auf der Kommandozeile bin ich erfolgreich gewesen. Interessant: Chat-GPT liefert ein kürzeres, mir aber schwer verständliches rekursives Python-Programm ohne jede Schleife, das jedoch meine Ergebnisse bestätigt :-)


Herzkurve

Schreibe ein Programm mit Pygame, das die nachfolgende Grafik, eine sogenannte Kardioide, erzeugt. Verwende das Verfahren "Einhüllende einer Geradenschar" wie in diesem Artikel der Wikipedia beschrieben!

Erweitere das Programm so, dass

  • es die Kardioide mit allen N im Bereich von 20 bis 200 nacheinander zeichnet.
  • die Herzkurve wie ein Herz pulsiert
  • die Grafiken in einer GIF-Datei gespeichert werden
  • die Farbe wechselt
  • oder, oder, oder ...

Retro-Screensaver

Aus den Zeiten, als es noch nützlich war, den Bildschirm des Computers bei Nichtbenutzung (weitgehend) abzudunkeln, ihn also zu schonen, kommt diese Idee: Zwei Punkte wandern schräg über den Bildschirm und werden von dessen Rändern 'reflektiert', wie beim Pong-Spiel. Statt der Punkte selbst wird deren Verbindungsgerade gezeichnet, die also ebenfalls dauernd wandert. In einem weiteren Schritt wird nicht nur diese eine sondern die jeweils letzten 20 Linien gemalt, wobei ein variabler wandernder Fächer entsteht. Um die Darstellung zu 'entruckeln' bietet sich an, die Helligkeit der Linien stetig zu modulieren: Ganz neue und ganz alte erscheinen dunkel, die mittel-alten hell.

Passwort-Prüfung

Manche Online-Dienste verlangen, dass ein vom Benutzer gewähltes Passwort gewissen Mindest-Standards genügen muss, damit es nicht leicht zu erraten ist. Darum fordern sie Mindestlängen, Verwendung von Ziffern und Sonderzeichen, keine Wiederholungen usw. Die Agentur für Arbeit z.B. bemängelt ein Passwort '123' wie folgt:

Schreibe eine Funktion check_password, welche prüft, ob diese Regeln von Passwort-Kandidaten erfüllt werden. Wird die Datei, die check_password enthält, direkt ausgeführt, muss check_password verschiedene Tests absolvieren mit gültigen und ungültigen Passwort-Kandidaten . Die Ausgabe auf der Kommandozeile soll am Ende entweder

*** Test passed ***
 oder
*** Test failed ***
 anzeigen. Im Falle nicht-bestandener Tests sollen diese zuvor genannt werden.

Log-In

Schreibe ein Programm, dass auf der Kommandozeile einen Anmeldeprozess (=Log-In) realisiert. Zusätzlich kann der Administrator Benutzer verwalten. Nach Programmstart ist einzig 'admin' als Benutzer aufgesetzt. Eine Sitzung könnte folgendermaßen verlaufen:

Willkommen bei Log-In!
Anmelden: admin
Sie sind angemeldet als admin.
Bitte vergeben Sie ein Passwort für admin: 1234
 
Wählen Sie eine der folgenden Funktionen:
(1) abmelden
(2) neuen Benutzer anlegen
(3) alle Benutzer auflisten
(4) Benutzer entfernen
(5) Programm beenden
admin> 1
Sie wurden abgemeldet.
Willkommen bei Log-In!
Anmelden: admin
Passwort: 1234
Sie sind angemeldet als admin
 
Wählen Sie eine der folgenden Funktionen:
(1) abmelden
(2) neuen Benutzer anlegen
(3) alle Benutzer auflisten
(4) Benutzer entfernen
(5) Programm beenden
admin> 
...

Natürlich soll das System eine Anmeldung mit unbekanntem Nutzernamen oder falschem Passwort zurückweisen.

Erweiterungen

  • Der aktuell angemeldete Benutzer kann sein Passwort ändern.
  • Nach dreimalig falscher Eingabe eines Passwortes wird der Benutzer gelöscht.
  • Benutzer und Passwörter werden in einer Datei gespeichert, die zu Beginn geladen und nach jeder Änderung überschrieben wird.
  • Es werden nicht die Passwörter selbst, sondern nur deren Hash-Code gespeichert. Somit kann die Passwort-Datei nicht genutzt werden, um sich illegal einzuloggen.

Tipp: Die folgenden Zeilen zeigen den Umgang mit der hashlib:

import hashlib
p = bytearray('meinPasswort', encoding="utf-8")
m = hashlib.sha256()
m.update(p)
store = m.hexdigest()
print(store)

Rechentrainer

Schreibe ein Programm, das dem Benutzer 5 zufällige Aufgaben präsentiert und danach die Zeit ausgibt, die sie oder er für die Lösung gebraucht hat. Ein Dialog könnte so aussehen:

Willkommen beim Rechentrainer!
Tippe dein Ergebnis nach dem = ein!
24 + 43 = 67
Korrekt!
10 + 12 = 22
Korrekt!
11 + 11 = 33
Falsch! Probiere es nochmal:
11 + 11 = 22
Korrekt!
7 + 19 = 26
Korrekt!
49 + 16 = 65
Korrekt!
Du hast 18 Sekunden gebraucht.


Tipps

Mit dem Paket time liefert der Aufruf time.time() den Sekundenwert einer Uhr. Ruft man ein zweites Mal diese Funktion, liefert die Differenz der Rückgabewerte die verstrichene Zeit in Sekunden.

Erweiterungen

  • Lasse den Benutzer zunächst eine der vier Grundrechenarten Rechenart wählen: +, -, *, /
  • Frage zu Beginn nach dem größten Zahlenwert der Operanden. So kann man den Schwierigkeitsgrad steuern und sich z.B. auf das kleine Einmaleins beschränken.
  • Frage zunächst den Namen ab und speichere das Ergebnis in eine Datei. Damit kannst du dann eine Bestenliste verwalten und ausgeben.

Bruchrechnen

Addiere zwei Brüche, deren Zähler und Nenner der Benutzer eingibt. Verwende den euklidischen Algorithmus, um den sich ergebenden Bruch zu kürzen. Beispielhafte Anzeige auf der Konsole:

Addition zweier Brüche (Bitte nur ganze Zahlen eingeben!)
Zähler der ersten Zahl: 12
Nenner der ersten Zahl: 18
Zähler der zweiten Zahl: 21
Nenner der zweiten Zahl: 14
12/18 + 21/14 = 13/6 = 2 1/6

Tipp: a/b + c/d = (a*d+c*b)/(b*d), kürze mit dem ggT nach Euklid!

Babylonisches Wurzelziehen

Natürlich braucht sich eine Python-Programmiererin keine Gedanken machen, wie sie die Wurzel aus einer Zahl x zieht. Sie ruft einfach math.sqrt(x). Aber schon die Babylonier wussten, wie man mit den Grundrechenarten zum Ziel kommt: Gesucht sei die Wurzel r aus x, d.h. x = r * r. Man wählt eine beliebige Zahl p zwischen 1 und x. Dann teilt man: q = x / p. Im Glücksfall liegt q sehr nahe bei p, sodass für praktische Belange r = p = q gilt. Aber in der Regel liegen p und q doch weit auseinander. Das heißt, eine von beiden Zahlen ist deutlich größer als r und eine ist kleiner. Diesen Umstand kann man sich an einem Bild verdeutlichen:

Geometrisch betrachtet bedeutet Wurzelziehen, die Kantenlänge r eines Quadrats mit dem Flächeninhalt x zu bestimmen. Wenn die Fläche rechts der Fläche links entspricht (und das tut sie, weil x = p * q), dann ist die kurze Seite kleiner als r und die lange größer als r. Also ergibt sich ein verbesserter Wert für p, wenn man aus p und q den Mittelwert bildet. Mit diesem neuen p wiederholt man die Prozedur solange, bis sich p und q genügend angenähert haben. Beachte: Auch die Ergebnisse von math.sqrt(r) sind meist nur Näherungswerte mit vielen Nachkommastellen! Anleitung zur Lösung:

  • Führe die ersten Schritte des Verfahrens handschriftlich aus: x = 16 und p = 1. Man sieht, wie schnell man sich der Lösung 4 nähert.
  • Übertrage die Rechnung in ein Python-Programm, wo die ersten Zeilen 'x = 16' und 'p = 1' lauten.
  • Wähle zunächst eine feste Anzahl von Durchläufen aus, z.B. 6 und drucke alle Zwischenergebnisse. (for i in range(6):)
  • Stelle um auf eine while-Schleife mit den Abbruchkriterium, dass p ungefähr q entspricht. (Tipp: Benutze die Funktion 'abs')
  • Statt einer festen Programmierung von x frage den Radikanden (so nennt man x) vom Benutzer via 'input' ab.
  • Erweitere das Programm so, dass es mit allen Eingaben sinnvoll umgeht! In seiner einfachsten Version haben wir nur mit Zahlen größer eins gerechnet. Was sind die Sonderfälle und ungültige Eingaben?

Übrigens: Mit dem Befehl "exit(0)" kann man einen Programmlauf jederzeit beenden!

Eratosthenes siebt Primzahlen

Studiere die Funktionsweise des Sieb des Eratosthenes. Anders als in der Wikipedia entferne die Vielfachen der Primzahlen nacheinander aus einer Liste. Schreibe ein Programm nach folgendem Muster:

  1. Lege eine Liste aller natürlichen Zahlen von 2 bis N an
  2. Starte mit der ersten Zahl der Liste (=2)
  3. Entferne alle Vielfachen dieser Zahl aus der Liste
  4. Gehe zur nächsten Zahl in der Liste. (Sie ist immer eine Primzahl!)
  5. Stoppe den Prozess, sobald die Zahl größer als Wurzel(N) ist.
  6. Gehe zu Schritt 3!

Tipp: Dein Programm wird garantiert nicht auf Anhieb funktionieren! Darum begrenze N zunächst auf 50 und führe dein Programm Zeile für Zeile im Degbug-Modus aus. Beobachte im Variablenfenster, ob genau das passiert, was du erwartest! Zusatzaufgabe: Programmiere die Lösung aus der Wikipedia in Python!

Benzinrechner

Füge dem Programm aus der Projektliste folgende Erweiterugen hinzu:

  • Sobald die Menge des Benzins bekannt d.h. gegeben oder berechnet ist, berechne die Menge CO2, die bei der Verbrennung frei wird und zeige sie an. Laut Wikipedia sind dies 2,7 kg CO2 pro Liter Benzin.
  • Füge dem Programm noch Felder für den Benzinpreis [EUR/Liter] sowie den Rechnungsbetrag [EUR] hinzu. Jetzt soll es z.B. rechnen können: Wie weit komme ich mit 100 EUR bei einem Verbrauch von 6,1 l/100km, wenn das Benzin 1,55 EUR/l kostet?

Zahlenvorleser

Mit den vier Python-Befehlen:

import simpleaudio as sa
wave_obj = sa.WaveObject.from_wave_file('eins.wav')
play_obj = wave_obj.play()
play_obj.wait_done()

kann man die Sound-Datei 'eins.wav' abspielen. Schreibe ein Konsolenprogramm, welches eine Ziffernfolge, z.B. 135724680, entgegen nimmt und die Ziffern nacheinander ausspricht. Zu diesem Zweck fertige dir z.B. mit Audacity entsprechende Sound-Dateien mit deiner Stimme an, für jede Ziffer eine.

Tipps

  1. Ein Python Dictionary kann dir helfen!
  2. Beginne die Programmentwicklung ohne Töne und drucke für jede Ziffer das Zahlwort aus.
  3. Anschließend kannst du den Sound einbinden, die Logik funktioniert ja schon.

Zeitansage

Schreibe ein Programm, das folgende 288 Zeilen ausgibt:

00:00   Es ist zwölf Uhr
00:05   Es ist fünf nach zwölf
00:10   Es ist zehn nach zwölf
00:15   Es ist viertel nach zwölf
00:20   Es ist zwanzig nach zwölf
00:25   Es ist fünf vor halb eins
00:30   Es ist halb eins
00:35   Es ist fünf nach halb eins
00:40   Es ist zwanzig vor eins
00:45   Es ist viertel vor eins
00:50   Es ist zehn vor eins
00:55   Es ist fünf vor eins
01:00   Es ist ein Uhr
01:05   Es ist fünf nach eins
01:10   Es ist zehn nach eins
...
23:15   Es ist viertel nach elf
23:20   Es ist zwanzig nach elf
23:25   Es ist fünf vor halb zwölf
23:30   Es ist halb zwölf
23:35   Es ist fünf nach halb zwölf
23:40   Es ist zwanzig vor zwölf
23:45   Es ist viertel vor zwölf
23:50   Es ist zehn vor zwölf
23:55   Es ist fünf vor zwölf

Tipp: Benutze Pythons match/case Konstrukt.

Baue die Zeitansage ("Es ist ...") aus Teilstrings so zusammen, dass du nach Fertigstellung des Programms die textuelle Ausgabe leicht durch eine Sprachausgabe ersetzen kannst. Z.B. wird dann anstatt den Text "zwanzig" auszugeben die Sound-Datei "zwanzig.wav" abgespielt. Wie man das macht, siehst du in der Beschreibung des Projektes "Zahlenvorleser" weiter oben.

Wenn du abschließend noch die Echtzeituhr einbindest, hast du eine voll funktionsfähige App für deinen PC.

Wörteruhr

LOC 178. Den Code des vorangegangenen Projektes kannst du in Teilen wiederverwenden für die Simulation einer Wörteruhr: Diese Uhr ohne Zeiger und Ziffern gibt die Uhrzeit in Wörtern bekannt, welche auf einer Tafel erscheinen. Man sieht dort einen festen Vorrat an Buchstaben, welche passend zur aktuellen Uhrzeit hinterleuchtet werden. Dieses Video gibt einen spannenden Einblick in solch ein Projekt – an Variationen hat YouTube einiges auf Lager. Schaltet man in der Demo die (aktuelle) Uhrzeit aus, läuft die Zeit beschleunigt, um schnell alle möglichen Anzeigen zu begutachten. "Reset" stellt die Schnelllauf-Zeit auf Mitternacht.

Monte Carlo Pi

Wir wollen die Kreiszahl Pi annähernd bestimmen mit Hilfe eines Zufallsprozesses - darum der Name. Zu diesem Zweck schießen wir mit einer idealen Schrotflinte auf eine quadratische Zielscheibe mit den Abmaßen des Einheitskreises:

Nach vielen Schüssen ergibt sich eine gleichmäßige Verteilung der Treffer und man kann erwarten, dass deren Anzahl proportional ist zur Fläche. Weil in deren Formel (Dreisatz!) die Zahl Pi auftaucht, kann man nach ihr auflösen und erhält einen Schätzwert. Er wird umso genauer sein, je mehr Schüsse abgefeuert wurden. Stelle den Schätzwert in einem Graphen mit der Matplotlib dar. Z.B. kann man nach jeweils 100 Schüssen einen Punkt der Kurve plotten bei einer Gesamtzahl von 10.000 Schüssen. Tipp: Zeichne den genauen Wert als zweite Kurve d.h. horizontale Linie mit zwei Punkten!

Wanderpunkt

Diesen Projektnamen habe ich mir ausgedacht, um das überraschende Ergebnis nicht vorweg zu nehmen. Die Aufgabe ist einfach: Gegeben seien drei feste Punkte in der Ebene, welche typischerweise ein Dreieck definieren, also nicht auf einer Geraden liegen. Nun wählen wir einen beliebigen Punkt innerhalb oder außerhalb des Dreiecks als Startposition des Wanderpunktes. Eine einzige Regel bestimmt nun die Folge der Wanderpunkte:

  • Wähle zufällig einen der drei festen Punkte.
  • Die neue Position des Wanderpunktes liegt auf der Hälfte der Wegstrecke des gewählten festen Punktes und der aktuellen Position des Wanderpunktes.
  • Fahre fort mit dem ersten Schritt!

Schreibe ein Programm, mit dessen Hilfe man zunächst die drei festen Punkte in einem leeren Fenster durch Anklicken markiert und dann die Startposition des Wanderpunktes. Danach berechnet das Programm 50.000 Folgepunkte und zeichnet diese in das Fenster. Finde heraus, wie man die entstehende Figur nennt! Hier kannst du ein StarterSet herunterladen und mit der eigenen Entwicklung starten!

Ziegenproblem

Im Folgenden geht es darum, ein Auto zu gewinnen und sich nicht mit einer Ziege zu begnügen:

„Nehmen Sie an, Sie wären in einer Spielshow und hätten die Wahl zwischen drei Toren. Hinter einem der Tore ist ein Auto, hinter den anderen sind Ziegen. Sie wählen ein Tor, sagen wir, Tor Nummer 1, und der Showmaster, der weiß, was hinter den Toren ist, öffnet ein anderes Tor, sagen wir, Nummer 3, hinter dem eine Ziege steht. Er fragt Sie nun: ‚Möchten Sie das Tor Nummer 2?‘ Ist es von Vorteil, die Wahl des Tores zu ändern?“

Dieses Rätsel hat wegen der Fehleinschätzungen vieler Experten solche Wellen ausgelöst, dass unzählige Artikel darüber geschrieben wurden und ein langer Wikipedia-Eintrag zustande kam. Dabei ist die Lösung - wie bei allen Rätsel dieser Art - leicht zu begründen, wenn man das Problem erst einmal richtig verstanden hat. Auf deinem Weg dorthin schreibe ein Python-Programm, das die Erfolgsaussichten der Wechsel- bzw. Bleibe-Strategie durch Simulation erforscht. Prüfe dann mit deinem Mathematiklehrer, wie aussagefähig das Ergebnis bei z.B. 10.000 Durchläufen ist. Wahrscheinlich wird dir aber schon beim Programmieren die Lösung klar :-) Beachte: Egal, welches Tor der Kandidat zu Beginn wählt, der Showmaster öffnet immer eine Tür mit Ziege und bietet immer den Wechsel an.

Fußgängerampel

Schreibe ein Programm, das eine Fußgängerampel auf einer grafischen Oberfläche (tkinter) simuliert. Die Ampelanlage dient einzig dem Zweck, den Autoverkehr kurzzeitig anzuhalten, um Fußgängern das sichere Queren der Straße zu ermöglichen. Ihre Funktion sei wie folgt beschrieben:

  1. Zu Beginn sind alle Lampen aus.
  2. Drückt der Benutzer die "Drücken"-Taste, sehen die Autofahrer ein grünes, die Fußgänger ein rotes Licht. Die Lampe "Signal kommt" leuchtet.
  3. Nach einiger Zeit springt die Auto-Ampel auf gelb ... und so weiter...
  4. Am Ende sind alle Lichter wieder erloschen.

Hier kannst du ein StarterSet herunterladen und mit der eigenen Entwicklung starten!

Taschenrechner

Einen Taschenrechner zu programmieren sollte doch recht einfach sein, oder? Immerhin gibt es die seit vielen Jahrzehnten. Außerdem möchte man vielleicht auch mal seine eigenen Spezialitäten einbauen. Kein Problem: Hier kannst du ein StarterSet herunterladen und mit der eigenen Entwicklung starten!

Genetischer Code

Achtung:

  1. Die folgende Beschreibung ist zwar korrekt, aber sehr verkürzt. Wer mehr wissen will, schaue sich zum Thema DNA z.B. in der Wikipedia oder bei YouTube um.
  2. Für die Bearbeitung von DNA-Sequenzen existiert ein spezielles Package namens Biopython. Professionelle Entwickler benutzen dieses Package, anstatt – so wie hier – auf die Basis-Funktionen von Python zurückzugreifen.

In den Zellen unseres Körpers ist die Erbinformation als Folge von Nukleotiden innerhalb der sogenannten DNA gespeichert. Jedes Nukleotid lässt sich durch einen der vier Buchstaben A, C, G oder T beschreiben. Jeweils 3 aufeinander folgende Nukleotide (=Triplett) nennt man ein Codon, denn es codiert gemäß dem genetischen Code genau eine Aminosäure. Diese Aminosäuren werden von den Körperzellen produziert und aneinander gereiht. So entstehen alle wichtigen Proteine, die die verschiedensten Funktionen übernehmen. Zum Beispiel würde die Nukleotidfolge CTAGCAACG die Aminosäuren Leucin, Alanin, Threonin codieren und zwar genau in dieser Reihenfolge. Bei vier verfügbaren Buchstaben ergeben sich bei jedem Triplett 4 * 4 * 4 = 64 Möglichkeiten der Kombination. Es könnten also 64 unterschiedliche Aminosäuren codiert werden. Tatsächlich genügen 20 Aminosäuren, um alle Proteine zu erzeugen. Dieser Überschuss bedeutet, dass bestimmte Aminosäuren auf verschiedene Weise codiert werden können. Die folgende Tabelle fasst den genetischen Code zusammen. Beachte: Für den Buchstaben T steht hier ein U, was für unsere vereinfachte Betrachtung aber unerheblich ist.

UUU	F	Phe	Phenylalanine
UUC	F	Phe	Phenylalanine
UUA	L	Leu	Leucine
…
AUG	M	Met	Methionine (Start)
…
UAU	Y	Tyr	Tyrosine
UAC	Y	Tyr	Tyrosine
UAA	X	Stop	(Stop)
UAG	X	Stop	(Stop)
CAU	H	His	Histidine
…
AGG	R	Arg	Arginine
GGU	G	Gly	Glycine
GGC	G	Gly	Glycine
GGA	G	Gly	Glycine
GGG	G	Gly	Glycine

Diese Tabelle hat 64 Einträge. In jeder Zeile wird das Triplett gefolgt von einem eindeutigen Buchstaben-Code, der 3-Buchstaben-Abkürzung und dem vollen Namen der codierten Aminosäure. Wie man erkennt, codieren alle vier Triplets, die mit GG beginnen, für Glycine, unabhängig vom letzten Basenpaar. Neben den Codes für Aminosäuren erkannte man auch Steuerzeichen: UAA, UAG, UGA beenden das Ablesen der Sequenz (Stop), während ein anfängliches AUG den Beginn einer Sequenz markiert (Start).

Wir wollen die Tabelle so umstrukturieren, dass jede Zeile von genau einer Aminosäure handelt, z.B.

Glycine (G, Gly) GGU GGC GGA GGG

Auf diese Weise entfernen wir alle Redundanzen, denn die Verbindung von z.B. G, Gly und Glycine tritt nur einmal auf. Schreibe ein Python-Programm, welches obige Tabelle einliest (download hier) und die geforderte Tabelle mit 21 Zeilen erstellt! Sie sieht in Teilen wie folgt aus:

(Stop)        (X, Stop) UAA UAG UGA 
Alanine       (A, Ala)  GCA GCC GCG GCU 
Arginine      (R, Arg)  AGA AGG CGA CGC CGG CGU 
Asparagine    (N, Asn)  AAC AAU
…
Phenylalanine (F, Phe)  UUC UUU
…
Tyrosine      (Y, Tyr)  UAC UAU 
Valine        (V, Val)  GUA GUC GUG GUU 

Man beachte die alphabetische Sortierung und die exakte Ausrichtung der Spalten! Man kommt mit 28 Zeilen Code aus! (Zusatzaufgabe: Erzeuge aus der Ergebnistabelle wieder die Ursprungstabelle - die genaue Reihenfolge der Zeilen dort kann vernachlässigt werden.)

Set

Wer erkennt - wie ich - mindestens 5 Sets in den 12 Karten dieses Bildes?:

Beim Gesellschafts-Kartenspiel Set kommt es darauf an, die einzige Spielregel schneller als die Mitspieler auf die offen liegenden Karten anzuwenden. Das ist eine echte Herausforderung! Es bietet aber auch ein gute Gelegenheit, Einzelspieler mit einem Trainingsprogramm zu unterstützen. Schreibe ein Python-Programm, das die Karten am Bildschirm auslegt, sodass der Spieler jeweils drei Karten als Set durch anklicken markieren kann. Das Programm prüft die Einhaltung der Regel, führt einen Punktestand, entfernt das Set und füllt die Lücken der Karten auf. Eine Vorschau-Funktion zeigt nacheinander alle vorliegenden Sets. Die Implementierung des Memory-Spiels (siehe die Projektseite) hilft euch dabei als Vorübung. Will man nicht alle 81 Karten einscannen oder anderweitig als Bilder importieren, bietet sich an, sie im Moment des Auslegens zu erzeugen, gegebenenfalls in einer alternativen Form.


Wordle

Fordere deinen aktiven Wortschatz heraus bei diesem kurzweiligen Spiel! Rate gegen die Zeit ein verborgenes Wort, indem du nacheinander die richtigen Buchstaben ermittelst. Je nach Wörterbuch kann man beliebige Sprachen verwenden. Aber Achtung: So einfach ist das bei Fremdsprachen nicht!

Das obige Bild stellt einen Spielablauf dar, wobei der erste Tipp des Spielers das Wort KATER war. Jeder eingegebene Buchstabe wird wie folgt dargestellt:

  • grün: Dieser Buchstabe ist richtig geraten.
  • gelb: Dieser Buchstabe kommt im Lösungswort an einer anderen Stelle vor.
  • grau; Dieser Buchstabe kommt im Lösungswort gar nicht vor.

Nachdem dem Spieler klar war, dass an zweiter Stelle ein A sowie ein E vorkommt (aber nicht an vierter Stelle), hat er auf das Wort TANNE getippt. So hangelt er sich weiter und trifft am Ende das Lösungswort PAUSE. Bevor du das Spiel vorteilhaft mit Pygame implementierst, beginne mit einem Konsolenprogramm, bei dem eine Sitzung folgendermaßen aussehen könnte:

Herzlich willkommen zu Wordle!
Das Spiel beginnt!
Gib einen Tipp: vater
VATER
.*.?.
Gib einen Tipp: macke
MACKE
.*..*
Gib einen Tipp: galle
GALLE
**..*
Gib einen Tipp: gasse
Du hast das gesuchte Wort gefunden!
Es lautet 'GASSE'
Willst du nochmal spielen? j/n n
Und tschüss!

Legende: Statt einer Färbung wird eine separate Zeile mit folgendem Code ausgegeben: * = grün, ? = gelb, . = grau. Diese Wortliste ist für den Beginn ganz gut geeignet.

Blocksatz

Texte in Zeitungen, Zeitschriften und Websites sind oft im Blocksatz formatiert. Für den einfachsten Fall der nichtproportionalen Schriftart lässt sich eine Formatierung zum Blocksatz vergleichsweise einfach in Python programmieren. Der erste Absatz aus Immanuel Kants "Beantwortung der Frage: Was ist Aufklärung?" sieht im Blocksatz so aus:

Aufklärung  ist der Ausgang des Menschen aus
seiner  selbst  verschuldeten  Unmündigkeit.
Unmündigkeit ist das Unvermögen, sich seines
Verstandes  ohne  Leitung  eines  anderen zu
bedienen.    Selbstverschuldet   ist   diese
Unmündigkeit,  wenn  die  Ursache  derselben
nicht  am Mangel des Verstandes, sondern der
Entschließung  und  des  Mutes  liegt,  sich
seiner   ohne   Leitung   eines  anderen  zu
bedienen.  Sapere aude! Habe Mut dich deines
eigenen Verstandes zu bedienen! ist also der
Wahlspruch der Aufklärung.

Hier wurde eine Spaltenbreite von 44 gewählt.

Schreibe ein Programm, das eine Textdatei einliest und den block-formatierten Text auf der Konsole ausgibt! Die Blockweite soll beliebig wählbar sein. Der obige Text ist im UTF-8 Format gespeichert. Dies muss beim Öffnen des Files bedacht werden. Jeder Absatz ist als eine Zeichenkette (string) gespeichert, die mit einem New-Line-Zeichen endet. Bei der Ansicht mit z.B. Notepad++ kann man alle Zeichen der Datei anzeigen lassen. Die Zeichenkette des ersten Absatzes lautet:

Aufklärung ist der Ausgang des Menschen aus seiner selbst verschuldeten Unmündigkeit. Unmündigkeit 
ist das Unvermögen, sich seines Verstandes ohne Leitung eines anderen zu bedienen. Selbstverschulde
t ist diese Unmündigkeit, wenn die Ursache derselben nicht am Mangel des Verstandes, sondern der En
tschließung und des Mutes liegt, sich seiner ohne Leitung eines anderen zu bedienen. Sapere aude! H
abe Mut dich deines eigenen Verstandes zu bedienen! ist also der Wahlspruch der Aufklärung.<CR><LF>

(Weil die gesamte Zeichenkette wegen ihrer Länge hier nicht auf einer Zeile dargestellt werden kann, wurde sie willkürlich nach jeweils 100 Zeichen umgebrochen.) Die CR-LF Kombinationen am Zeilenende erkennt Python automatisch als New-Line-Zeichen.

Tipps zur Programmierung

  • Lese den Text Absatz für Absatz ein.
  • Zerlege jeden Absatz in seine untrennbaren Teile.
  • Nehme nacheinander so viele Wörter aus dem Absatz, wie in eine Zeile passen.
  • Berechne den gesamten Leerraum für diese Zeile und teile ihn auf die Zwischenräume auf.
  • Formatiere die Ausgabezeile und drucke sie.
  • Mache eine Ausnahme für die letzte Zeile.

Erweiterungen

  • Ist ein einzelnes Wort länger als die Spaltenbreite, sollte eine Fehlermeldung erfolgen.
  • Bei kleinen Spaltenbreiten und langen Wörtern können unschöne Löcher zwischen den Wörtern entstehen. Dem kann man abhelfen, indem lange Wörter getrennt werden. Führe eine Trennungsliste ein, die beim Formatieren hilft, die Löcher klein zu halten und wende sie an!
  • Führe Optionen ein, sodass der Text auch linksbündig, rechtsbündig oder zentriert formatiert werden kann.

Schweizer Zeitmesser App

Der Titel ist ein Wortspiel: Ein Schweizer Taschenmesser hat viele einzelne Werkzeuge, also Klingen, Schraubendreher usw. Entsprechend hat diese App mehrere Teile, die sich mit Zeitmessung beschäftigen:

  • Wecker (alarm clock)
  • Stoppuhr (stopwatch)
  • Zeitgeber (timer)
  • Weltzeit-Anzeige (world clock)
  • Zeiterfassung (time-tracking)

Diese Bestandteile werden durch Auswahl des Reiters (Tab) aktiviert:

Wie man sieht, ist aktuell nur der Zeitgeber implementiert. Die übrigen Bestandteile sollen von den Kursteilnehmern entwickelt werden. Dies hat die Vorteile, dass einerseits die Umgebung schon präpariert ist und andererseits eine funktionierende Vorlage existiert, aus der man Teile wiederverwenden oder einfach abschauen kann. Man kann also beliebig kreativ sein und dabei möglichst originelle bzw. benutzerfreundliche Elemente hinzufügen. Natürlich darf man sich auch die Aufgabe stellen, eine eigene Implementierung des Zeitgebers zu entwickeln. Hier kannst du ein StarterSet herunterladen und mit der eigenen Entwicklung starten!

Backup

Am heimischen PC möchte man sich davor schützen, bei Wohnungsbrand, Virenbefall oder Hardware-Versagen seine wertvollen Daten zu verlieren. Seien es Fotos, Briefe oder Programme - im Laufe der Jahre kommt da einiges zusammen, was man sichern möchte. Spezialprogramme können dies für einen übernehmen und eine komplette Sicherungskopie d.h. "Backup" der gesamten Festplatte anlegen. Eine einfache Lösung wäre, auf einem externen Datenträger den gesamten Verzeichnisbaum zu spiegeln, zum Beispiel alles was bei Windows unter C:\Users\<Dein Name>\Documents liegt. Schließt man per USB eine Festplatte an, so könnten diese Daten dort unter G:\Backup\Documents liegen. Wenn man den möglichen Verlust an Daten klein halten möchte, empfiehlt es sich, den Verzeichnisbaum möglichst häufig zu kopieren. Doch das kann wegen der Menge an Daten dauern und ist auch nicht notwendig. Eigentlich braucht man ja nur die Veränderungen seit dem letzten Backup zu berücksichtigen. Nur neue oder veränderte Dateien müssen kopiert werden. Doch wie macht man das?

Einfachster Algorithmus

Ermittle alle Dateien und Unterverzeichnisse im Quell-Verzeichnis:

  • Mit den Dateien:
    • falls nicht im Ziel vorhanden, kopiere nach Ziel
    • falls nur im Ziel vorhanden, lösche im Ziel
    • falls neueren Datums, überschreibe im Ziel
  • Mit den Unterverzeichnissen:
    • falls nicht im Ziel vorhanden, erzeuge im Ziel
    • falls nur im Ziel vorhanden, lösche im Ziel
  • Wende obige Operationen rekursiv auf alle Unterverzeichnisse der Quelle an!

Typischerweise werden nicht alle zu schützenden Daten in einem einzigen Verzeichnisbaum liegen. Daher würde man praktischerweise eine Liste von Quell-Verzeichnissen definieren, wobei der obige Algorithmus dann auf jedes Element dieser Liste angewendet wird.

Tipps

  • Die Python-Funktion os.walk übernimmt bereits den rekursiven Besuch aller Verzeichnisse in einem Baum!
  • Schreibe zunächst ein Programm, das zwei Bäume miteinander vergleicht und Unterschiede berichtet. Dies hilft sowohl einen Testaufbau mit Quell- und Zielbaum zu validieren, als auch den Erfolg eines Backup-Programm-Laufs zu überprüfen. Außerdem ähnelt dieses Programm dem Backup-Programm sehr. Für unsere Zwecke reicht es, wenn die Zeitmarken der Dateien (most recent content modification time) übereinstimmen. Diese müssen also mit kopiert werden. shutil.copy2 übernimmt das.
  • Unter Windows traten bei manchen Dateien mysteriöse Unterschiede in den Zeitmarken von Quell- und Zieldatei im Sekundenbereich auf. Darum ignoriert mein Programm solche Differenzen, wenn sie kleiner als 10 Sekunden sind.

Ideen

  • Gebe am Ende die Anzahl der kopierten Dateien und deren Gesamtgröße aus, zusätzlich die Dauer der Operation.
  • Schreibe eine Log-Datei, in der alle Operationen protokolliert werden (Python logging Modul).
  • Mit einem Aufruf-Parameter kann man bewirken, dass sich der PC nach Vollendung schlafen legt. (Wie kann man verhindern, dass dies nicht schon vorher passiert?) So kann man den Backup bequem vor dem zu Bett gehen starten.
  • Erzeuge einen Button auf der Task-Bar, damit das Programm schnell gestartet werden kann.
  • Starte das Programm über ein Skript, damit man dort Parameter festlegen kann. (Die könnte man aber auch im Programm hart codieren)

Performance

Erster Test: Mit Windows 10 und einer 13 Jahre alten externen USB-Festplatte dauerte der Backup eines Verzeichnisses (8300 Dateien in 660 Ordnern, 1.2 GB) beim ersten Anlegen etwa 5 Minuten. Beim zweiten Durchlauf (kein File-Transfer) war das Programm in 58 Sekunden fertig! (Nach einem Windows Reboot, vorher hat es nur verdächtige 8 Sekunden benötigt (caching))

Mit diesem Programm wird durch das Umbenennen bzw. Verschieben von Ordnern u.U. eine große Kopieraktion ausgelöst, die eigentlich unnötig wäre. Dieser Fall tritt aber selten auf und die Laufzeit des Programms ist vermutlich meist ohne Belang.

Stromer

Die Schwachstellen batterie-elektrischer Fahrzeuge (BEV) sind (derzeit noch) ihre vergleichsweise geringe Reichweite und der erhöhte Zeitbedarf zum Tanken, sprich Aufladen. Die Ladezeit hängt zudem von der verfügbaren Leistung der Ladestation ab. Außerdem ist der Ladevorgang nicht-linear: Die letzten 20% Ladung benötigen ungefähr doppelt so lange wie die ersten 20 %. Wie kann man nun berechnen, wie lange man aufladen muss, um z.B. wieder 200 km weit fahren zu können? Schreibe ein Programm ähnlich dem Rechner des "Benzin"-Projekts.

Gegeben sei z.B.

  • die Ladekurve eines Volkswagen ID.4 (siehe Grafik oben),
  • ein aktueller Ladezustand (SOC) in Prozent,
  • eine Akku-Kapazität von 82 kWh,
  • ein Verbrauch von 150 Wh/km
  • sowie eine Ladestation mit 150 kW.

Mehr Details siehe hier. Das Programm soll auch sagen, wie lange man warten muss, bis die Akkus wieder zu x % gefüllt sind. Tipps:

  • Programmiere die stückweise lineare Funktion P(SOC) mit P = Ladeleistung in kW und SOC = Akkufüllstand in Prozent
  • Die geladene Energie E = SOC * Akku-Kapazität
  • Wegen P = E / t erhält man dE/dt = P(E), d.h. eine nichtlineare Differentialgleichung erster Ordnung.
  • Diese kann man leicht schrittweise (nach Euler) integrieren, indem man für je eine Minute die Ladeleistung konstant hält.
  • Man erhält schließlich eine Funktionstabelle, welche für jeden Minutenschritt die verfügbare Akkuladung angibt. Aus der lässt sich dann die Reichweite ableiten.

Was bedeutet es, wenn die Ladesäule nur 75 kW hergibt?

System-Log

Python eignet sich hervorragend, um sogenannte Logdateien zu analysieren. Das sind (zumeist) Textdateien, in denen wichtige Ereignisse während des Betriebs von Computersystemen protokolliert werden, gerade wie im Logbuch eines Schiffes. Diese Dateien wachsen schnell und es wird dann beinahe unmöglich, sie „händisch“ zu analysieren, z.B. mit einem Texteditor. Meist ist man nur an wenigen Informationen interessiert, die man dann zwecks Weiterverarbeitung herausfischen will, z.B. alle Fehlermeldungen, die sich auf ein bestimmtes Teilsystem beziehen. Diese Informationen sollen dann zweckmäßig formatiert in eine andere Datei ausgegeben werden.

Z.B. möchte man sich einen Überblick über die Betriebszeiten eines konkreten PCs im vergangenen Jahr verschaffen. Dazu hält bei Windows 10 die Datei System.evtx im Verzeichnis C:\Windows\System32\winevt\Logs Daten bereit. (Daneben gibt es noch 360 andere Log-Dateien!). Zwar ist dieser System-Log in einem proprietärem Format gespeichert, kann aber mithilfe des Programms "Ereignisanzeige" in eine Textdatei exportiert werden. Eine kurze Testreihe am PC und anschließende Analyse der Datei zeigt, wie das Ein- und Ausschalten bzw. das Schlafen Legen und Aufwecken oder ein Neustart dort aufgezeichnet werden.

Nachdem man einige kleinere technische Hürden überwunden hat, lassen sich die interessierenden Ereignisse mithilfe eines Python-Skriptes in eine andere Datei schreiben als z.B.

200 02.03.2022 17:39:32 start_up
201 02.03.2022 17:39:19 shut_down
221 02.03.2022 17:37:24 wake_up
231 02.03.2022 17:34:31 sleep
241 02.03.2022 14:40:33 wake_up

Hier sind pro Zeile 4 Informationshappen enthalten: Nummer des Eintrags, Kalenderdatum, Uhrzeit, Ereignis. Damit hat man alles beisammen, um mit Matplotlib eine Grafik zu erstellen, die die Betriebszeiten des PCs visualisiert. Die Betriebszuständen nehmen die Werte on (in Betrieb) , sleeping (schlafend) und off (ausgeschaltet) an.

Wie man leicht erkennt, wurde der PC beinahe täglich benutzt und nur selten heruntergefahren. Meist schläft er. (Windows-Sprech: „Energie sparen“) Man schreibt also typischerweise zwei Programme: Eines zur Extraktion interessanter Informationen und eines zur Auswertung, z.B. grafischen Darstellung.

Irrgarten

Hier geht es darum, ein Programm zu schreiben, das Irrgärten erzeugt, so wie dieses:

Danach mache man sich an die Lösung: Wie muss man in dem Irrgarten laufen, um von der linken oberen Ecke zur rechten unten zu gelangen? Also nochmal programmieren! Wer hier an Rekursion denkt, liegt richtig! Zu diesem Projekt angeregt wurde ich durch Dan Shiffman.

15-Puzzle

Dieses Programm simuliert u.a. das bekannte 15-Puzzle. Dazu wird ein beliebiges quadratisches Foto in N x N Teile zerlegt, die zu Beginn so verschoben werden, dass das Original nur zu erahnen ist. Für N = 4 erhält man besagtes 15-Puzzle. Klickt man auf ein Teilfoto, wandert es auf die benachbarte Leerstelle, falls vorhanden. Mit etwas Geschick lässt sich so das Originalbild - hier ein Portrait - rekonstruieren.

Hier kannst du ein StarterSet herunterladen und mit deiner eigenen Entwicklung beginnen!

Erweiterungen:

  • Anstatt mit Fotoschnipseln arbeite mit numerierten Kacheln, wie im Original des Puzzles. Im StarterSet ist der Code zum Erzeugen dieser Kacheln schon gegeben.
  • Mit N > 4 wird es fast unmöglich, das Bild zu rekonstruieren. Darum verändere das Programm wie folgt:
    • Alle N x N Teilbilder werden zufällig verteilt ausgelegt, es bleibt also kein "Loch".
    • Der Spieler kann die Teilbilder per Drag-and-Drop verschieben. Dabei tauschen Start- und Zielfoto die Plätze.
    • Alternativ können die Teilbilder auf ein zweites, zunächst leeres, N x N Quadrat verschoben und dort weiter sortiert werden. Damit nähert man sich dem Vorgehen bei einem traditionellen Puzzle.

Wortsuchspiel

Folgendes Spiel entnahm ich der lokalen Tageszeitung:

Die Rechteinhaber mögen eine Nachsehen haben, wenn ich es hier verwende. Schreibe ein Python-Programm, das dieses Rätsel (und alle anderen dieser Art) löst! Benutze einen OCR-Dienst (z.B. im Internet), welcher das Bild in eine Textdatei umwandelt. So sparst du dir Zeit und Übertragungsfehler!

Die Zeitungskopie kann hier in besserer Auflösung heruntergeladen werden. Weitere Rätsel finden sich hier.

Sonnenfinsternis

Am 12.8.2026 gab es in Deutschland eine partielle Sonnenfinsternis. Sie verlief ungefähr so, wie in dieser Animation zu sehen:

Schreibe ein Python-Programm, das die Bedeckung der Sonne bei Finsternissen der Typen total, ringförmig und partiell in Zeitraffer darstellt! Natürlich ist die Berechnung dieser Bilder allein aus astronomischen Daten (Bahndaten von Sonne und Mond, sowie Erddrehung) eine Sache für Experten, weil mathematisch anspruchsvoll. Aber die braucht man ja auch nicht für eine ungefähre Darstellung, wie wir sie hier programmieren wollen.

Stromzähler

Jeder Haushalt verfügt über einen Stromzähler zur Verbrauchsmessung. Dessen Stand wird turnusmäßig abgelesen, um die Stromrechnung zu erstellen. Die Differenz der Zählerstände zwischen Ende und Anfang des Messzeitraums ergibt den Verbrauch. Er hat die Einheit Kilowattstunden (kWh). Die Stadtwerke Tübingen informieren ihre Kunden über deren Verbrauch der letzten Jahre z.B. mit folgender Darstellung:

Der grüne Balken am rechten Rand bedeutet: Zwischen dem 14.10.2024 und 11.8.2025 wurden knapp 1000 kWh Strom verbraucht. Das Balkendiagram vermittelt den Eindruck, als hätte der Stromverbrauch des betroffenen Haushaltes über die Jahre stark geschwankt. Dies soll nun geprüft werden.

Aufgaben:

  1. Übernehme die Daten aus der Tabelle in ein Python-Programm!
  2. Erzeuge daraus mit der Matplotlib ein gleichartiges Balkendiagramm!
  3. Erzeuge mit korrekten Zeitpunkten und akkumulierten (aufaddierten) Verbräuchen ein Streudiagramm! (Bei durchweg konstantem Verbrauch müssten alle Punkte auf einer Linie liegen.)
  4. Führe mithilfe von SciPy eine lineare Regression durch: 'from scipy import stats', rufe 'stats.linregress' mit nur zwei Argumenten auf (Zeitpunkte und akkumulierter Verbräuche).
  5. Die Steigung der Regressionsgeraden liefert den mittleren Verbrauch. Wie weit liegen die gemessenen Verbrauchswerte von dieser Geraden entfernt und was bedeutet das?
  6. Warum erscheint das Balkendiagram so zerklüftet und was ist wohl die Ursache? (Man kann sie anhand des Bildes erraten!)
  7. Führe die gleiche Analyse mit einer Tabellenkalkulation, also z.B. Excel oder LibreOffice Calc durch! Welche Vor- und Nachteile erkennst du?