Python 101 LN 0 (Null)#
Übungsblatt 0, Punkte: 0
Anliegen dieses LN: So könnte ein Lernprotokoll aussehen. Das hier ist ein Beispiel für ein Lernjournal.
Theorie, Hintergrund#
Es gibt das wunderbare Büchlein “Schreibdenken” von Ulrike Scheuermann.
Herangehensweise im Lernprozess selbst: spielerisches Programmieren. Aber Vorsicht: “Spiel” ist ein Polysem (ein Wort mit mehreren Bedeutungen):
Spiel_1: zielorientiert; oft wettbewerblich; meist mit klaren, das Spiel definierende Regeln; mit klaren Erfolgs- und Bewertungsbedingungen; theoretisch bestens erforscht in der mathematischen Spieltheorie … auch sehr interessant in der Programmier-Pädagogik; wir empfehlen hier https://www.codewars.com/
Spiel_2: das Spielen eines Kindes; spielerisch als Gegenentwurf zu zielorientiert; EN: playful
Das Adjektiv “spielerisch” verwenden wir im Folgenden ausschließlich in der Bedeutung Spiel_2.
Spielerisches Lernen bedeutet nicht Spiel_1: zielorientiert, regelbasiert, wettbewerblich; sondern
bedeutet Spiel_2: explorativ, ungezielt, interessante und offene Ziele generierend.
Literatur:
https://www.sciencedirect.com/science/article/pii/S0960982214011245 | https://doi.org/10.1016/j.cub.2014.09.009
Beispiel: Gegeben sei eine Liste von Klausurnoten zwischen 1 und 5. Aufgabe sei es, den Notenschnitt der bestandenen Klausuren (also 4 oder besser) zu berechnen.
Konventionelles Setting: Schüler erzeugt eine lauffähige Lösung; Dozent vergewissert sich, dass die Lösung für eine Anzahl vorgegebener Tests korrekt ist: “ok, abgehakt”!
Spielerische Herangehensweise: Student findet eine erste Lösung und testet sie mit den vorgegebenen Test: geht!
Jetzt bleibt man aber nicht beim “abhakt” stehen, sondern sucht sich weitere Tests –insbesondere auch solche, die untypisch oder mehr oder weniger “bösartig” sind und dann doch einen Fehler erzeugen.
Soll daraufhin die existierende Lösung umgearbeitet werden? NEIN, die erste Lösung wird als ein Dokument der Zeitgeschichte unverändert belassen. Stattdessen wird eine Kopie der ersten Lösung erzeugt und diese Kopie zur zweiten Lösung weiterentwickelt. Ein Ziel besteht darin, die Lösungen nebeneinander zu sehen, vergleichen, kombinieren, verbessern, und auch auf frühere Lösunen zurückgreifen zu können.
Um die Lösungen zu bewerten stellt man sich traditionell die Frage “Was heißt besser”? Auch hier ist wieder eine spielerische Herangehenswese möglich: technisch “besser” in Bezug auf Laufzeit, Speicherverbrauch? praktisch besser in Bezug auf Lesbarkeit, Wartbarkeit, Erweiterbarkeit, Ähnlichkeit zu anderen Lösungen, Lernwirksamkeit, Kommunizierbarkeit etc.?
Aufgabe 1: Mittelwert von Klausurnoten#
gegeben:
eine Liste von Klausurergebnissen
gesucht:
Berechne den Mittelwert aller bestandenen Klausuren.
Montag: Initialer Entwurf#
def notenschnitt(notenliste):
summe = 0
for zahl in notenliste:
summe += zahl
return summe / len(notenliste)
Tests:
ss2023 = [1, 2, 3, 2, 1]
notenschnitt( ss2023 )
1.8
Klappt, Aufgabe gelöst!
Montag Nachmittag#
… Ich war eben einkaufen. Meine Lieblingsschokolade war ausverkauft, schluchz! … dabei ist mir eingefallen: Was macht meine Funktion, wenn ich eine leere Liste übergebe? Denn im ws2023 habe ich ja keine Klausur mitgeschrieben.
ws2023 = []
notenschnitt(ws2023)
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
Cell In[3], line 2
1 ws2023 = []
----> 2 notenschnitt(ws2023)
Cell In[1], line 5, in notenschnitt(notenliste)
3 for zahl in notenliste:
4 summe += zahl
----> 5 return summe / len(notenliste)
ZeroDivisionError: division by zero
Da wird 0
zurückgeliefert: Kein gültiger Durchschnittswert für eine Notenliste, nicht gut. Wir wollen bei einer leeren Liste lieber einen anderen Wert zurückgeben, z.B. False
.
def notenschnitt_2(notenliste):
if len(notenliste) == 0:
return False
else:
summe = 0
for zahl in notenliste:
summe += zahl
return summe / len(notenliste)
print(notenschnitt_2( ss2023 ))
print(notenschnitt_2( ws2023 ))
1.8
False
Mittwoch#
Habe es dem Dozenten gezeigt, ok. Aber Er meint, dass das else
unnötig ist, weil das return
ja den Funktionsaufruf beendet. Neuer Versuch:
def notenschnitt_3(notenliste):
if len(notenliste) == 0:
return False
summe = 0
for zahl in notenliste:
summe += zahl
return summe / len(notenliste)
print(notenschnitt_3( ss2023 ))
print(notenschnitt_3( ws2023 ))
1.8
False
Im ss2024 hatte ich eine Fünf, eine Zwei und einen Einser. Da nur die bestandenen Klauren zählen, sollte der Schnitt also 1.5 sein:
ss2024 = [5, 2, 1]
print(notenschnitt_3( ss2024 ))
2.6666666666666665
Hm, nicht gut. Was ist das Problem? … ich sehe es nicht, spüle mal das Geschirr vom Vortag ab;
Mittwoch Nachmittag#
Beim Topfschrubben weiß ich plötzlich: Klar, ich muss die Fünfer weglassen! Weiß nicht, wie das geht, habe meinen großen Bruder gefragt, er hat mir das Programm netterweise gleich aufgeschrieben:
ss2024 = [5, 2, 1]
def notenschnitt_4(notenliste):
gueltig = [ x for x in notenliste if 0 < x < 5 ]
return False if not len(gueltig) else sum(gueltig) / len(gueltig)
print(notenschnitt_4( ss2024 ))
1.5
Klappt! … aber genau verstehen tue ich nicht, was da steht … da kümmere ich mich später ‘drum ;-)
Aufgabe 2: empirische Varianz#
Wie oben bei Aufgabe 1; jetzt ist aber die empirische Varianz aller bestandenen Klausurnoten gesucht.