Closed nimec01 closed 7 months ago
Beim Resolve
-Aufgabentyp wäre ich durchaus dafür, zumindest optional (durch Lehrenden konfigurierbar) das Feedback zu der Korrektheit der Schritte etc. auch schon in partialGrade
zu aktivieren. Einfach weil die Aufgabe an sich kompliziert ist und vorstellbar ist, dass wir für sie ein inkrementelles Lösen ermöglichen wollen, also dass die Studierenden sich dabei vom System helfen lassen. (Beobachtung: Im aktuellen Durchlauf hat eine Person zur selben Aufgabe diesen Typs über 700 Einreichungen gemacht. Eventuell hat hier das System die Rolle des Lehrenden übernommen. Die Punkte sind dann durch "Leaking" entstanden, aber sicher wurde etwas gelernt, also ist das ein machbarer Tradeoff. Was denkst du, @owestphal?)
Eine Sache, die mir noch nicht so ganz gefällt, ist die Nutzung von preventWithHint
. Wenn man z.B. folgenden Code betrachtet
preventWithHint (missingLen > solLen)
(translate $ do
german "Lösung hat genügend Werte?"
english "Solution contains enough values?"
)
(translate $ do
german "Lösung enthält zu wenige Werte."
english "Solution does not contain enough values."
)
preventWithHint (not (solLen == tableLen || solLen == missingLen))
(translate $ do
german "Lösung hat korrekte Länge?"
english "Solution has correct length?"
)
(translate $ do
german $ "Die Lösung muss genau " ++ show missingLen ++ " Lücken enthalten."
english $ "The solution must contain exactly " ++ show missingLen ++ " gaps."
)
wird der zweite Aufruf von preventWithHint
keinen Text ausgeben, falls der erste Aufruf ein Hint geprintet hat (und somit die Lösung rejected wird).
Hier ein Ausschnitt aus einem Test:
Des Weiteren sind mir nochmal ein paar Ungereimtheiten in Hinsicht auf #78 aufgefallen. Bei einer Aufgabe wird z.B. trotz richtiger Lösung nochmal eine mögliche Lösung angezeigt. Das sollte (eventuell zusammen mit möglichen Änderungen bzgl. des letzten Kommentars) noch einmal evaluiert werden.
Bzgl. der Sache mit
preventWithHint (missingLen > solLen)
und
preventWithHint (not (solLen == tableLen || solLen == missingLen))
oben vermute ich, dass es Absicht ist, dass der erste Hinweis den zweiten deaktiviert.
Hintergrund dürfte sein, dass hier ein häufiger Fehleingabefall speziell abgefangen (bzw. gezielt uminterpretiert) wird.
Die Aufgabe verlangt eigentlich die Angabe von nur den Lücken. Also sagen wir, es gab drei Eingaben, folglich 8 Zeilen der Wahrheitstafel. Darin sind 3 Lücken. Eigentlich sollen die Studierenden nun also eine dreielementige Liste einreichen. Manche aber übersehen, dass sie nur die Lücken angeben sollen und reichen stattdessen eine achtelementige Liste ein. Da das so oft vorkam, wurde der Aufgabentyp so umgeschrieben, dass er das akzeptiert. Daraufhin ist auch die Eingabebehandlung speziell.
Wenn also jemand eine zweielementige Liste einreicht, wird ihm nur gesagt, dass sie zu kurz ist (sie wäre zu kurz, egal ob eigentlich drei oder acht Elemente einzugeben gewesen wären).
Wenn jemand eine fünfelementige Liste einreicht, wird gesagt, dass eine dreielementige Liste erwartet wurde.
Wenn jemand eine achtelementige Liste einreicht, wird das hingenommen und diese Eingabe dann bei der Bewertung speziell behandelt.
Würde es unter diesen Gesichtspunkten wirklich Sinn ergeben, bei der Eingabe einer zweielementigen Liste beide Hinweise zu geben?
Bzgl.
Des Weiteren sind mir nochmal ein paar Ungereimtheiten in Hinsicht auf https://github.com/fmidue/logic-tasks/pull/78 aufgefallen.
wäre vielleicht am besten, das in einem separaten Issue zu dokumentieren.
Vielleicht war mein Beispiel zu preventWithHint
unpassend gewählt, aber worauf ich hinaus wollte:
Bei completeGrade
hat der Studierende keine Möglichkeiten mehr die Abgabe anzupassen. Wäre es dann nicht sinnvoll, die Ergebnisse aller Checks (eventuell mit Ausnahmen) dort auch anzuzeigen? Es würde ihm/ihr ja nichts nützen nur zu wissen, dass die Lösung z.B. zu wenig Werte beinhaltet.
Da der letzte preventWithHint
Aufruf auch noch die Aufgabe hat, falls entsprechend konfiguriert, eine mögliche Lösung anzuzeigen, ist dies auch problematisch. Diese würde dann nämlich nicht angezeigt werden.
Dies:
Da der letzte
preventWithHint
Aufruf auch noch die Aufgabe hat, falls entsprechend konfiguriert, eine mögliche Lösung anzuzeigen, ist dies auch problematisch. Diese würde dann nämlich nicht angezeigt werden.
verstehe ich wiederum nicht. Inwiefern hat der letzte preventWithHint
Aufruf die Aufgabe, eine Lösung anzuzeigen? Sehe ich zumindest in dem Beispiel nicht. Oder geht es darum, dass in einem späteren Teil desselben do
-Blocks (aber nicht in dem preventWithHint
) die Lösungsausgabe erfolgt?
Und zudem: Ist die Sache mit den Hinweisen zur Lückenanzahl überhaupt Teil von completeGrade
? Ist das nicht in partialGrade
, wo irgendeine Lösungsausgabe sowieso nicht infrage kommt?
Ich glaube, wir müssten mal genauer schauen, um welche konkrete Aufgabe es geht. Vielleicht ist das Problem einfach, dass zu viel von partialGrade
nach completeGrade
verschoben wurde.
Bei Decide
sieht completeGrade
wie folgt aus
completeGrade :: OutputMonad m => DecideInst -> [Int] -> LangM m
completeGrade DecideInst{..} sol = do
preventWithHint (solLen > acLen)
(translate $ do
german "Lösung enthält nicht zu viele Indizes?"
english "Solution does not contain too many indices?"
)
(translate $ do
german "Lösung enthält zu viele Indizes."
english "Solution contains too many indices."
)
preventWithHint (acLen > solLen)
(translate $ do
german "Lösung enthält genügend Indizes?"
english "Solution contains enough indices?"
)
(translate $ do
german "Lösung enthält zu wenige Indizes."
english "Solution does not contain enough indices."
)
preventWithHint (diff /= 0)
(translate $ do
german "Lösung ist korrekt?"
english "Solution is correct?"
)
(do
translate $ do
german $ "Die Lösung beinhaltet " ++ display ++ " Fehler."
english $ "Your solution contains " ++ display ++ " mistakes."
when showSolution $ example (show changed) $ do
english "A possible solution for this task is:"
german "Eine mögliche Lösung für die Aufgabe ist:"
pure ()
)
pure ()
where
nubSol = nub sol
diff = length $ filter (`notElem` changed) nubSol
acLen = length $ nub changed
solLen = length $ nub sol
distance = abs (solLen - acLen)
display = show distance
Mal angenommen ein Student reicht die Lösung [1]
ein und printFeedback = True
. Dann sieht das Feedback wie folgt aus:
Die Aufgabe wurde nun bewertet und der Student sieht nur, dass ihm noch einige Indizes fehlen. Da acLen > solLen == True
, wird hier die Lösung abgelehnt und kein weiteres Feedback (außer dem entsprechenden Hint) ausgegeben. Demnach geht "Lösung ist korrekt?" verloren, was bei einer falschen Lösung dazu führen würde, dass "Eine mögliche Lösung für die Aufgabe ist" ausgegeben wird.
Ähnlich ist dies bei Fill
der Fall. Die Instanz hat hier 6 Lücken und printFeedback = True
.
Natürlich hat der Student hier zu viele Werte angegeben, allerdings sollte das Feedback trotzdem angezeigt werden. Mit der aktuellen Umsetzung mit preventWithHint
ist das allerdings nicht so einfach umzusetzen.
Bei Decide
sehe ich das Problem. Die Lösung wäre wohl einfach, die beiden Teile preventWithHint (solLen > acLen)
und preventWithHint (acLen > solLen)
jeweils durch geeignete Aufrufe von yesNo
zu ersetzen.
Bei Fill
sollte sich das Problem dadurch auflösen, dass die Teile preventWithHint (missingLen > solLen)
und preventWithHint (not (solLen == tableLen || solLen == missingLen))
zurück nach partialGrade
verschoben werden. Sie "leaken" ja gar keine Information, da die Anzahl der Lücken in der Aufgabenstellung sowieso schon "verraten" wird (während bei Decide
nicht der Fall ist, dass die Aufgabenstellung die Anzahl der Fehler preisgibt).
Siehe auch noch https://github.com/nimec01/logic-tasks/pull/1
Wie in #68 bereits angesprochen, verrät das Feedback von
partialGrade
teilweise die Lösung. Demnach habe ich einige Rückmeldungen nachcompleteGrade
verschoben.