Closed jvoigtlaender closed 5 days ago
https://github.com/fmidue/output-blocks/commit/5619823dab84921176c14ad80a85fe714fb712bb ermöglicht jetzt den Aufruf von multiplechoice
mit anderer Grenze als 50%.
Direkt
Config.percentageOfChanged %
als Threshold zu nehmen, ist vielleicht auch nicht ganz richtig. Es muss ja sowohl an Fälle, wo zu viele angebliche Fehler eingegeben werden, als auch an Fälle, wo zu wenige Fehler eingegeben werden, gedacht werden.
extendedMultipleChoice
erlaubt es auch, die Bestrafung für falsche Antworten anzupassen. Wäre solch eine Anpassung vorstellbar?:
Config.percentageOfChanged %
Antworten erhält der Studierende die normale Bestrafung (das sollte glaube ich -1/rowCount Punkte pro falsche Antwort sein)Versuchen wir das einfach und schauen, wie es sich in der Praxis auswirkt. Aus Klausureinsichten weiß ich, dass Studierende durchaus gut darin sind, sich konkret zu beschweren, wenn bei teilweise falsch gelösten Aufgaben die erhaltenen Teilpunkte ihnen nicht angemessen erscheinen. :smile:
Wenn da nachvollziehbare Einwände kommen, können wir noch nachsteuern.
Beim Austesten ist mir gerade aufgefallen, dass das, was wir hier (bzw. an anderer Stelle) besprechen, gar nicht funktioniert.
Allerdings könnte, zumindest bevor https://github.com/fmidue/output-blocks/issues/14 umgesetzt ist, eine Teilbepunktung nach multiplechoice-Art all zu hohe Punktzahlen in Decide-Aufgaben geben. Wenn etwa vier Fehler in eine 16-zeiligen Wahrheitstafel vorliegen, würden für die Abgabe [] immer 75% der Punkte vergeben werden.
Diese Aussage (https://github.com/fmidue/logic-tasks/pull/175#issuecomment-2360984803) stimmt nicht. Wenn ich die derzeitige Implementierung nutze und []
eingebe (klappt das erstmal nicht, da min. ein Index verlangt wird) erhalte ich 0 Punkte als Ergebnis.
Das Problem liegt darin, dass man nur für falsche / zu viele Eingaben Punkte abziehen und nur für richtige Eingaben Punkte addieren kann. Ich kann also z. B. nicht sagen, dass man am Anfang mit voller Punktzahl startet und dann pro fehlender / falscher Antwort Teilpunkte abgezogen bekommt.
Ich denke aber, dass eventuell die Idee, diese Aufgabe mit multipleChoice
umzusetzen, schon ein Fehler war. Wir wollen ja schließlich, dass man die volle Punktzahl erhält, wenn:
Ich sehe hier eine Analogie zu Fill
. Man erhält pro richtiger Zeile einen Punkt. Der einzige Unterschied ist, dass man bei Fill
einen Wert für jede Zeile eingeben muss und hier nur "(implizit) die Werte für die falschen Zeilen, indem man deren Index angibt".
Ich denke daher, dass es eher Sinn ergeben würde, eine weitere Abstraktion für solche Aufgaben zu implementieren und Fill
und Decide
darauf aufzubauen.
Ich habe dennoch bei Decide
ein wenig herumgespielt und konnte z. B. folgendes umsetzen:
1/changed
Punkte-1/rowCount
PunkteDie Bewertung sieht dann z.B. so aus (4 von 16 Zeilen wurden geändert):
[]
=> 0 Punkte[1]
(wobei die 1. Zeile geändert wurde) => 1/4 Punkt[3]
(falsch) => 0 Punkte[1,2]
(wobei die 1. und 2. Zeile geändert wurde) => 1/2 Punkt[1,2,3]
(wobei nur die 1. und 2. Zeile geändert wurde) => 7/16 Punkt[1,2,4,5]
(alle richtig) => 1 Punkt[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
=> 1/4 PunktAlso erstmal, das:
Die Bewertung sieht dann z.B. so aus (4 von 16 Zeilen wurden geändert):
[]
=> 0 Punkte[1]
(wobei die 1. Zeile geändert wurde) => 1/4 Punkt[3]
(falsch) => 0 Punkte[1,2]
(wobei die 1. und 2. Zeile geändert wurde) => 1/2 Punkt[1,2,3]
(wobei nur die 1. und 2. Zeile geändert wurde) => 7/16 Punkt[1,2,4,5]
(alle richtig) => 1 Punkt[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
=> 1/4 Punkt
finde ich eigentlich ganz gut. Eventuell würde ich dann dennoch noch einen Threshhold von 1/2 setzen, das heißt der zweite, drittletzte und letzte Fall würden auf 0 Punkte runtergedrückt. Aber das ist eine separate Betrachtung. Es könnte zum Beispiel auch 1/3 sein, so dass der drittletzte Fall "überlebt".
Ist dieses Verhalten denn nun mittels multipleChoice
oder extendedMultipleChoice
umgesetzt? Dann wäre aus meiner Sicht alles fein.
Dies:
Ich denke daher, dass es eher Sinn ergeben würde, eine weitere Abstraktion für solche Aufgaben zu implementieren und
Fill
undDecide
darauf aufzubauen.
würde ich lieber vermeiden. Wir wollen die Bewertungsfunktionen möglichst wiederverwendbar über viele Aufgabentypen (auch in modelling-tasks
etwa) einsetzen, und je mehr Abstraktionen man hat, zwischen denen man sich entscheiden muss, desto weniger nützlich wird es.
Vor allem aber sehe ich nicht, inwiefern Decide
(und in der Tat auch Fill
) keine Multiple-Choice-Tasks sind, die auch entsprechend bewertbar sein sollten.
Und in diesem Kontext irritiert mich auch dies hier:
Allerdings könnte, zumindest bevor https://github.com/fmidue/output-blocks/issues/14 umgesetzt ist, eine Teilbepunktung nach multiplechoice-Art all zu hohe Punktzahlen in Decide-Aufgaben geben. Wenn etwa vier Fehler in eine 16-zeiligen Wahrheitstafel vorliegen, würden für die Abgabe [] immer 75% der Punkte vergeben werden.
Diese Aussage (https://github.com/fmidue/logic-tasks/pull/175#issuecomment-2360984803) stimmt nicht.
Das müsste eigentlich stimmen, wenn die "normale" multipleChoice
-Funktion für die Bewertung benutzt wird. Es sind dann 16 Ja/Nein-Antworten zu geben, wobei an vier Stellen Ja korrekt ist und an 12 Stellen Nein korrekt ist. Eingabe von []
heißt, dass alle 16 Stellen mit Nein beantwortet wurden. Das ergibt 12/16 richtige Antworten, also 75% der Punkte. So ist die Umsetzung (mittels multipleChoice
) bei vielen Aufgaben in modelling-tasks
, und zeigt genau dieses Verhalten. (Also es sind etwa unter vier vermeintlichen Klassendiagrammen die korrekt geformten herauszufinden. Zufällig ist nur eins korrekt. Es wird []
eingegeben. Dann gibt es 75% der Punkte.)
Daher kann ich nicht so recht einordnen, was Sie oben beobachtet haben, das der Aussage widerspricht.
Das müsste eigentlich stimmen, wenn die "normale"
multipleChoice
-Funktion für die Bewertung benutzt wird. Es sind dann 16 Ja/Nein-Antworten zu geben, wobei an vier Stellen Ja korrekt ist und an 12 Stellen Nein korrekt ist. Eingabe von[]
heißt, dass alle 16 Stellen mit Nein beantwortet wurden. Das ergibt 12/16 richtige Antworten, also 75% der Punkte. So ist die Umsetzung (mittelsmultipleChoice
) bei vielen Aufgaben inmodelling-tasks
, und zeigt genau dieses Verhalten. (Also es sind etwa unter vier vermeintlichen Klassendiagrammen die korrekt geformten herauszufinden. Zufällig ist nur eins korrekt. Es wird[]
eingegeben. Dann gibt es 75% der Punkte.)Daher kann ich nicht so recht einordnen, was Sie oben beobachtet haben, das der Aussage widerspricht.
Ich kann das irgendwie nicht reproduzieren. Mit
completeGrade :: (OutputCapable m,Alternative m, Monad m) => DecideInst -> [Int] -> Rated m
completeGrade DecideInst{..} sol = reRefuse
(extendedMultipleChoice
(MinimumThreshold 0) -- nur fürs debugging
(Punishment 0) -- wie bei `multipleChoice`
(TargetedCorrect (length solution)) -- wie bei `multipleChoice`
DefiniteArticle
what
solutionDisplay
solution
nubSol)
$ when (diff /= 0) $ translate $ do
german $ "In der Menge der unterschiedlichen Indizes " ++ ger ++ " falsch."
english $ "The set of unique indices contains " ++ eng
where
nubSol = nubOrd sol
diff = length $ filter (`notElem` changed) nubSol
(ger, eng) = if diff == 1
then ("ist 1 Index", "1 wrong index")
else ("sind " ++ show diff ++ " Indizes", show diff ++ " wrong indices") -- no-spell-check
what = translations $ do
german "Indizes"
english "indices"
solutionDisplay | showSolution = Just $ show changed
| otherwise = Nothing
tableLen = length $ readEntries $ getTable formula
solution = Map.fromAscList $ map (\i -> (i, i `elem` changed)) [1..tableLen]
erhalte ich:
ghci> testModule Nothing German (genDecideInst dDecideConf) LogicTasks.Semantics.Decide.description LogicTasks.Semantics.Decide.partialGrade LogicTasks.Semantics.Decide.completeGrade parser
Betrachten Sie die folgende Formel:>>>> <F = (¬B ∨ ¬C) ∧ (A ∨ C ∨ D)> <<<<
Finden Sie alle fehlerhaften Wahrheitswerte in der letzten Spalte der folgenden Wahrheitstafel.>>>> <A | B | C | D | F
--|---|---|---|--
0 | 0 | 0 | 0 | 0
0 | 0 | 0 | 1 | 1
0 | 0 | 1 | 0 | 1
0 | 0 | 1 | 1 | 1
0 | 1 | 0 | 0 | 0
0 | 1 | 0 | 1 | 0
0 | 1 | 1 | 0 | 0
0 | 1 | 1 | 1 | 0
1 | 0 | 0 | 0 | 1
1 | 0 | 0 | 1 | 1
1 | 0 | 1 | 0 | 0
1 | 0 | 1 | 1 | 0
1 | 1 | 0 | 0 | 1
1 | 1 | 0 | 1 | 1
1 | 1 | 1 | 0 | 0
1 | 1 | 1 | 1 | 1
> <<<<
Geben Sie die Lösung als eine Liste der Indizes der fehlerhaften Zeilen an. Dabei zählt die Zeile mit 0 für alle atomaren Formeln als Zeile 1.
>>>>Ein Lösungsversuch könnte beispielsweise so aussehen: <[1,4,5]> <<<<
Lösung: [6,11,12,16] (nur fürs debugging)
Just ()
[]
---- Input ----
[]
---- Partial ----
Lösung enthält Indizes?
>>>> <Nein.> <<<<
>>>>Die Lösung muss mindestens einen Index enthalten.<<<<
Nothing
!!! The following would not be printed in Autotool !!!
---- Complete ----
Alle angegebenen Indizes sind korrekt?
>>>> <Ja.> <<<<
Die angegebenen Indizes sind vollzählig?
>>>> <Nein.> <<<<
Just (0 % 1)
[]
würde also zu 0 Punkten führen (wenn partialGrade
nicht abbrechen würde).
Ist dieses Verhalten denn nun mittels
multipleChoice
oderextendedMultipleChoice
umgesetzt? Dann wäre aus meiner Sicht alles fein.
Das ist mit extendedMultipleChoice
. Den Pull Request öffne ich gleich.
@nimec01 Besteht dieses Problem hier noch https://github.com/fmidue/logic-tasks/issues/178#issuecomment-2388347069. Die neueste Version von output-blocks
sollte sich anders verhalten (zumindest mit multipleChoice
– für die Benutzung von extendedMultipleChoice
ist es ggf. sinnvoll, den Aufruf in der Implementierung von multipleChoice
anzuschauen)
@nimec01 Besteht dieses Problem hier noch #178 (comment). Die neueste Version von
output-blocks
sollte sich anders verhalten (zumindest mitmultipleChoice
– für die Benutzung vonextendedMultipleChoice
ist es ggf. sinnvoll, den Aufruf in der Implementierung vonmultipleChoice
anzuschauen)
Nein. Es verhält sich nun wie zuvor beschrieben. Also 75 % erreichte Punkte bei Abgabe von []
@marcellussiegburg Ist es auch richtig so, dass sich das Punishment
additiv zur normalen Bewertung verhält? Wenn ich in dem Beispiel oben Punishment (1 % 2)
setze und neben den korrekten Indizes einen falschen Index hinzufüge, erhalte ich 7/16 Punkte. Es ist also ein Abzug von 1/2 + 1/16 Punkten. Dabei sind 1/16 die Punkte, die regulär (also mit Punishment 0
) abgezogen werden.
Die einzige Möglichkeit, die hier weiterhelfen würde, wäre dieses "default punishment" anpassen zu können. Punishment
alleine bringt da gerade nicht viel, da es nur eine Auswirkung auf explizit falsch angegebene Indizes hat. Das ist aber nicht das Problem, was wir hier beheben wollen. Wir wollen ja vielmehr, dass eine Abgabe wie []
nicht direkt zu 75 % der Punkte führt. Das "default punishment" für Abgaben mit weniger als percentageOfChanged %
Indizes anzupassen könnte dem meiner Meinung nach ein wenig entgegenwirken.
Ist es auch richtig so, dass sich das Punishment additiv zur normalen Bewertung verhält?
Ja, in diesem Sinne ist es eigentlich eine zusätzliche Bestrafung. So hatte ich die Anforderung von Bestrafungen von falschen Antworten verstanden. Wenn keine zusätzliche Bestrafung gewünscht wird, kann der Wert aber einfach auf 0 gesetzt werden.
Die einzige Möglichkeit, die hier weiterhelfen würde, wäre dieses "default punishment" anpassen zu können.
Das ließe sich implizit anpassen, wie in meinem vorherigen Kommentar. Oder braucht es noch ein zusätzliches Punishment? (Wofür wäre das die einzige Möglichkeit?)
Punishment alleine bringt da gerade nicht viel, da es nur eine Auswirkung auf explizit falsch angegebene Indizes hat. Das ist aber nicht das Problem, was wir hier beheben wollen. Wir wollen ja vielmehr, dass eine Abgabe wie
[]
nicht direkt zu 75 % der Punkte führt.
Achtung! extendedMultipleChoice
kann vom Typ her schon gar nicht []
annehmen. Um im Detail zu verstehen, was hier der Gedankengang ist, müsste ich aber die Grundannahmen und Modellierung der Bewertung sehen oder erklärt bekommen, denn sonst reden wir wahrscheinlich aneinander vorbei.
extendedMultipleChoice
ist etwas generischer gedacht, als es hier gebraucht wird. Der Anwendungsfall (wie ich ihn ursprünglich verstanden hatte, wäre damit auch abgedeckt), dass es möglich ist, nur einen Teil der Antworten zu geben. Also etwa: 1 ist Falsch, 2 ist Richtig, 3 und 4 gebe ich gar nicht an.
Wenn es darum geht, das hier https://github.com/fmidue/logic-tasks/issues/178#issuecomment-2386492723 umzusetzen, so kann das mit extendedMultipleChoice
zum Beispiel so erfolgen (ich kopiere aus dem ghci):
ghci> runLangMReport (return ()) (>>) (extendedMultipleChoice (MinimumThreshold 0) (Punishment $ 1 % 16) (TargetedCorrect 4) IndefiniteArticle (Blocks.translations $ do {Blocks.english "test"; Blocks.german "test"}) Nothing (M.fromList [(1 :: Int, True), (2, True), (4, True), (5, True)]) (M.fromList [])) >>= \(r, x) -> (x English :: IO ()) >> return r
All given test are correct?
>>>> <Yes.> <<<<
The given test are exhaustive?
>>>> <No.> <<<<
Just (0 % 1)
ghci> runLangMReport (return ()) (>>) (extendedMultipleChoice (MinimumThreshold 0) (Punishment $ 1 % 16) (TargetedCorrect 4) IndefiniteArticle (Blocks.translations $ do {Blocks.english "test"; Blocks.german "test"}) Nothing (M.fromList [(1 :: Int, True), (2, True), (4, True), (5, True)]) (M.fromList [(1, True)])) >>= \(r, x) -> (x English :: IO ()) >> return r
All given test are correct?
>>>> <Yes.> <<<<
The given test are exhaustive?
>>>> <No.> <<<<
Just (1 % 4)
ghci> runLangMReport (return ()) (>>) (extendedMultipleChoice (MinimumThreshold 0) (Punishment $ 1 % 16) (TargetedCorrect 4) IndefiniteArticle (Blocks.translations $ do {Blocks.english "test"; Blocks.german "test"}) Nothing (M.fromList [(1 :: Int, True), (2, True), (4, True), (5, True)]) (M.fromList [(3, True)])) >>= \(r, x) -> (x English :: IO ()) >> return r
All given test are correct?
>>>> <No.> <<<<
Just (0 % 1)
ghci> runLangMReport (return ()) (>>) (extendedMultipleChoice (MinimumThreshold 0) (Punishment $ 1 % 16) (TargetedCorrect 4) IndefiniteArticle (Blocks.translations $ do {Blocks.english "test"; Blocks.german "test"}) Nothing (M.fromList [(1 :: Int, True), (2, True), (4, True), (5, True)]) (M.fromList [(1, True), (2, True)])) >>= \(r, x) -> (x English :: IO ()) >> return r
All given test are correct?
>>>> <Yes.> <<<<
The given test are exhaustive?
>>>> <No.> <<<<
Just (1 % 2)
ghci> runLangMReport (return ()) (>>) (extendedMultipleChoice (MinimumThreshold 0) (Punishment $ 1 % 16) (TargetedCorrect 4) IndefiniteArticle (Blocks.translations $ do {Blocks.english "test"; Blocks.german "test"}) Nothing (M.fromList [(1 :: Int, True), (2, True), (4, True), (5, True)]) (M.fromList [(1, True), (2, True), (3, True)])) >>= \(r, x) -> (x English :: IO ()) >> return r
All given test are correct?
>>>> <No.> <<<<
Just (7 % 16)
ghci> runLangMReport (return ()) (>>) (extendedMultipleChoice (MinimumThreshold 0) (Punishment $ 1 % 16) (TargetedCorrect 4) IndefiniteArticle (Blocks.translations $ do {Blocks.english "test"; Blocks.german "test"}) Nothing (M.fromList [(1 :: Int, True), (2, True), (4, True), (5, True)]) (M.fromList [(1, True), (2, True), (4, True), (5, True)])) >>= \(r, x) -> (x English :: IO ()) >> return r
All given test are correct?
>>>> <Yes.> <<<<
The given test are exhaustive?
>>>> <Yes.> <<<<
Just (1 % 1)
ghci> runLangMReport (return ()) (>>) (extendedMultipleChoice (MinimumThreshold 0) (Punishment $ 1 % 16) (TargetedCorrect 4) IndefiniteArticle (Blocks.translations $ do {Blocks.english "test"; Blocks.german "test"}) Nothing (M.fromList [(1 :: Int, True), (2, True), (4, True), (5, True)]) (M.fromList [(1, True), (2, True), (3, True), (4, True), (5, True), (6, True), (7, True), (8, True), (9, True), (10, True), (11, True), (12, True), (13, True), (14, True), (15, True), (16, True)])) >>= \(r, x) -> (x English :: IO ()) >> return r
All given test are correct?
>>>> <No.> <<<<
Just (1 % 4)
(MinimumThreshold
sollte in der Praxis vermutlich noch auf 1 % 2
oder so gesetzt werden; aber so wird die Analogie zu oben wohl deutlicher)
Update: Link to correct comment; shorten to relevant ghci-Output
Wenn es darum geht, das hier #178 (comment) umzusetzen, so kann das mit
extendedMultipleChoice
zum Beispiel so erfolgen (ich kopiere aus dem ghci): [...]
Das reicht mir erstmal aus. Wenn sonst bei #187 noch Fragen aufkommen, melde ich mich.
Siehe https://github.com/fmidue/logic-tasks/pull/175#issuecomment-2360984803.
Direkt
Config.percentageOfChanged %
als Threshold zu nehmen, ist vielleicht auch nicht ganz richtig. Es muss ja sowohl an Fälle, wo zu viele angebliche Fehler eingegeben werden, als auch an Fälle, wo zu wenige Fehler eingegeben werden, gedacht werden.Außerdem scheint mir, dass diverse aktuelle (bzw. nach 0583969edc3eacb8841fd19f7d8a7dbbd3e4317b noch) durchgeführte Extra-Tests in
Decide.completeGrade
nicht wirklich sein müsste. Also vielleicht lässt sich das auf einen direkten Aufruf vonmultiplechoice
reduzieren.