kekse Antworttypen - Benutzerhandbuch
1. Einleitung
Für jede kekse-Aufgabe muss ein Antworttyp gewählt werden. Dieser besteht aus drei Komponenten: ein Eingabeformat, ein Lösungsformat und eine interne Logik. Das Eingabeformat bestimmt die Benutzeroberfläche, mit der der Student/die Studentin beim Lösen der Aufgabe interagieren wird. Das Lösungsformat bestimmt die Syntax, nach der der Entwickler/die Entwicklern der Aufgabe der Lösung der Aufgabe angeben muss; das Lösungsformat bestimmt auch, welche Optionen zur Benutzeroberfläche oder zur Funktionalität des Antworttyps gesetzt werden können. Die interne Logik bestimmt, die interne Funktionsweise des Antworttyps und wird hier nicht erklärt.
Für die meisten Antworttypen ist das Eingabeformat bereits festgelegt und die Benutzeroberfläche automatisch erzeugt; zudem kann die Oberfläche über Optionen angepasst werden. Im Antworttyp custom
muss der Entwickler/die Entwicklerin die Benutzeroberfläche selber angeben. Eine weiter Ausnahme bilden multiple
und set
, die selber wiederum (möglicherweise mehrere) Antworttypen enthalten und deren Benutzeroberfläche verwenden.
In jedem Fall muss das Lösungsformat beim Entwickeln der kekse-Aufgabe eingehalten werden.
1.1 Angabe des globalen Antworttyps
Der Antworttyp der Aufgabe wird über das Meta-Element atype
gesetzt. Zum Beispiel wird hier der Antworttyp caps
verwendet:
<div class="ex">
...
<div class="meta">
...
<div class="atype">caps</div>
...
</div>
...
</div>
Wir sprechen auch vom globalen Antworttyp, weil Antworttypen mittels multiple
und set
verschachtelt werden können.
1.2 Angabe der Lösung
Unabhängig des durch den globalen Antworttypen vorgeschriebenen Lösungsformats, wird die Lösung der Aufgabe im solution-Element angegeben:
<div class="ex">
...
<div class="solution" ...>
...
</div>
...
</div>
Der Inhalt des Elements muss gemäss das Lösungsformat des verwendeten globalen Antworttyps formatiert sein. Das solution-Element akzeptiert optionale Attribute:
data-no-input-feedback
,"true"
oder"false"
(standardmässig"false"
). Bestimmt, ob im Eingabeelement oder den Eingabeelementen Feedback über die Richtigkeit der Antwort des Studenten/der Studentin unterdrückt wird. Diese Option ermöglicht vor allem im Fall vonmultiple
, differenziertes Feedback zu verschiedenen Teilantworten ein- oder auszuschalten. Feedback zur die Richtigkeit der gesamten Antwort wird in allen Fällen über den Prüfen-Button der Aufgabe gegeben.id
, string (standardmässig"sol_0"
). Fallsid
gesetzt ist, wird der Wert als id für das UI-Element verwendet (je nach Eingabeformat ist dieses Element ein verschiedenes).
Weitere Optionen beziehen sich auf die jeweiligen Antworttypen/Eingabeformate/Lösungsformate und werden später behandelt.
1.3 Verschachtelte Lösungen
Alle Antworttypen können in multiple
verschachtelt werden (einschliesslich multiple
selber); alle Antworttypen ausser radio
und set
können im Antworttyp set
verwendet werden. Verschachtelte Antworttypen werden verwendet, um neue, komplexere Antworttypen zu konstruieren (z.B. wenn zwei Lösungen einer quadratischen Gleichungen erwartet sind, anstelle nur einer).
Die Syntax der inneren Lösungen ist dieselbe wie für die (globale) Lösung, ausser, dass nicht direkt <div class="solution"...>
verwendet wird; mehr dazu weiter unten. Insbesondere können die gleichen Optionen gesetzt werden.
2. Liste von Antworttypen
Nachfolgend werden alle implementierten Antworttypen aufgeführt. Bei jedem Antworttyp wird das dazugehörige Lösungsformat sowie Eingabeformat behandelt. Da viele Antworttypen als Eingabeformat eine Textbox verwenden, wird dieses Format separat behandelt.
2.1 text
und davon abgeleitete Typen
Eingabeformat/Lösungsformat: Textbox (siehe Kapitel 3), wobei der Lösungstext gerade der Text ist, der als richtig gewertet werden soll.
Optionale Attribute für solution-Element:
data-correct-case
,"optional"
oder"required"
(Standard). Bestimmt, ob ob die Gross/Kleinschreibung beim Überprüfen der Antwort eine Rolle spielt.data-fallback
, string (standardmässig""
). Wird anstelle der Antwort verwendet, wenn der Student/die Studentin eine leere Antwort absendet. Diese Option ist im Moment ohne Nutzen.
Zum Beispiel ist hier der Lösungstext der Aufgabe "Zürich" und Gross/Kleinschreibung wird nicht beachtet:
<div class="ex">
<div class="meta">
...
<div class="atype">text</div>
...
</div>
...
<div class="question">
<p>Wo steht die ETH?</p>
</div>
<div class="solution" data-correct-case="optional">Zürich</div>
...
</div>
2.1.1 caps
Genau wie text
, ausser, dass in der Textbox alle Buchstaben automatisch als Grossbuchstaben geschrieben werden. Um Probleme mit Lösungen in Kleinbuchstaben zu vermeiden, wird automatisch data-correct-case="optional"
gesetzt.
2.1.2 lowers
Genau wie text
, ausser, dass in der Textbox alle Buchstaben automatisch als Kleinbuchstaben geschrieben werden. Um Probleme mit Lösungen in Grossbuchstaben zu vermeiden, wird automatisch data-correct-case="optional"
gesetzt.
2.1.3 letters
Genau wie text
.
2.2 Numerische Antworttypen mit predicate
, number
, integer
, usw.
Der Antworttyp predicate
wird verwendet, um Zahlen in verschiedenen Formaten abzufragen. Nachdem die Antwort gemäss dem verwendeten Format in eine Zahl umgewandelt wurde, wird sie anhand einer vom Entwickler/der Entwicklerin definierten Prädikatenfunktion ausgewertet. Der Antworttyp predicate
dient auch als Grundlage für eine Reihe weiterer Antworttypen (number
rational
, improper
, mixed
, decimal
, siehe weiter unten), die bereits spezifische Kombinationen von erlaubten Formaten vordefinieren. Meistens werden die abgeleiteten Antworttypen verwendet.
Eingabeformat/Lösungsformat: Textbox (siehe Kapitel 3). Die akzeptierten Formen für die vom Studenten eingegebene Antwort werden über die Option data-forms
gesetzt (siehe unten). Der Lösungstext ist für predicate
der Quellcode einer JavaScript-Funktion, für die abgeleiteten Antworttypen jedoch der numerische Wert der Lösung (siehe weiter unten).
Optionale Attribute für solution-div:
data-forms
, string (standardmässig"integer, proper, improper, mixed, decimal"
). Beschreibt die Formate, in denen Antworten akzeptiert werden. Vonpredicate
abgeleitete Antworttypen definieren ihre eigenen Standardwerte;data-forms
kann aber auch dort gesetzt werden, um die Standardwerte zu überschreiben. Dies ist vor allem für den Antworttypnumber
sinnvoll, da dieser als generischer Antworttyp für Zahlen verstanden wird; bei spezifischeren Antworttypen wierational
(Brüche) macht ein Überschreiben der Standardwerte weniger Sinn. Die verschiedenen Formate werden weiter unten erklärt.data-inexact
, gesetzt/nicht gesetzt (standardmässig nicht gesetzt). Falls gesetzt, müssen eingegebene Zahlen, nicht exakt mit der Lösung übereinstimmen, um dennoch als korrekt angenommen zu werden. Gleichzeitig sollte dann die Optiondata-max-error
gesetzt werden, um den grössten erlaubten Fehler festzulegen.data-inexact
sollte immer dann gesetzt werden, wenn die Lösung nicht genau ist (der Dezimalbruch ist "unendlich", z.B.0.33333333
oder3.141593
).data-max-error
, float (standardmässig 0, wird zum Basiswert2^-42
addiert). Beschreibt den grösstmöglichen Fehler zwischen Lösung und Antwort des Studenten, damit die Antwort immer noch akzeptiert wird.data-simplify
,"enforced"
oder"optional"
(standardmässig"enforced"
). Beschreibt, ob Brüche vereinfacht werden müssen.data-ratio
,"true"
oder"false"
(standardmässig"false"
). Beschreibt, ob trotz Vereinfachungsvorschrift Verhältnisse in der Formn/1
erlaubt sind.data-show-tooltip
,"true"
oder"false"
(standardmässig"false"
). Beschreibt, ob in einem Tooltip Informationen zu den erlaubten Formaten angezeigt wird.data-fallback
, string (standardmässig""
). Wird anstelle der Antwort verwendet, wenn eine leere Antwort abgesendet wird. Diese Option ist im Moment ohne Nutzen.
Mögliche Werte für data-forms
:
integer
: eine ganze Zahl wie z.B.6
.proper
: ein eigentlicher Bruch wie z.B.1/2
oder6/10
.improper
: ein uneigentlicher Bruch wie z.B.7/4
.pi
: ein Vielfaches vonpi
wie z.B.12 pi
oder2/3 pi
. Es können auch Vielfache vontau
sowie ganze Zahlen und Brüche angegeben werden.log
: ein Ausdruck wie z.B.log(100)
.percent
: eine Prozentzahl wie z.B.12.3%
.mixed
: eine gemischte Zahl wie z.B.1 3/4
.decimal
: eine Dezimalzahl wie z.B.0.75
.
Wert der Lösung: predicate
erwartet innerhalb vom solution-div (einfaches Textbox-Format) oder dem .value
-Element (erweitertes Textbox-Format) den Quellcode einer JavaScript-Funktion, die die beiden Parameter guess
und maxError
annimmt und einen bool zurückgibt. guess
ist die Antwort des Studenten/der Studentin, umgewandelt in eine Zahl gemäss angegebenen Formate. maxError
ist der maximal erlaubte Fehler. Der Rückgabewert wird als Wahrheitswert der Antwort interpretiert.
Zum Beispiel wird in folgendem Code eine Zahl grösser als Null als korrekt gewertet (maxError
wird ignoriert):
<div class="solution" data-no-input-feedback="true">
<span class="instruction">
Geben Sie eine Zahl <code>\blue{x}</code> grösser als 0 ein und kürzen Sie Brüche:
</span>
<span class="label">x=</span>
<span class="xlabel"><code>\blue{x}=</code></span>
<span class="value" data-simplify="true" data-show-tooltip="true">
function(guess, maxError) {
return guess > 0;
}
</span>
</div>
In diesem Bespiel wird der Standardwert von data-forms
verwendet, zudem wird verlangt, dass Brüche gekürzt eingegeben werden müssen und Tooltips sind aktiviert.
2.2.1 number
Verwendet intern predicate
. Standardmässig wird data-forms
wie in predicate
gesetzt ("integer, proper, improper, mixed, decimal"
). Anstelle einer Prädikatenfunktion muss der numerische Wert der Lösung in solution gesetzt werden (Variablen erlaubt). Dieser Antworttyp eignet sich für generische numerische Antworten.
Beispiel:
<div class="meta">
...
<div class="atype">number</div>
...
</div>
...
<div class="solution" data-simplify="true" data-show-tooltip="true">
3.75
</div>
2.2.2 decimal
Wie number
, aber mit data-forms="decimal"
.
2.2.3 rational
Wie number
, aber mit data-forms="integer, proper, improper, mixed"
.
2.2.4 improper
Wie number
, aber mit data-forms="integer, proper, improper"
.
2.2.5 mixed
Wie number
, aber mit data-forms="integer, proper, mixed"
.
2.3 Reguläre Ausdrücke mit regex
Der Antworttype regex
ermöglicht, eine Texteingabe mit einem regulären Ausdruck abzugleichen.
Eingabeformat/Lösungsformat: Textbox (siehe Kapitel 3). Der Lösungstext ist der reguläre Ausdruck, dem korrekte Antworten genügen müssen.
Optionale Attribute für solution-div
data-caseInsensitive
, gesetzt oder nicht gesetzt (standardmässig nicht gesetzt). Falls gesetzt, wird Gross-/Kleinschreibung ignoriert.data-fallback
, string (standardmässig""
). Wir anstelle der Antwort verwendet, wenn eine leere Antwort abgesendet wird. Diese Option ist im Moment ohne Nutzen.
2.4 Single-choice mit radio
Der Antworttype radio
wird für single-choice-Aufgabe eingesetzt.
Eingabeformat: radio
stellt automatisch eine Liste untereinander angeordneten Radio-Buttons zur Verfügung, von denen der Student/die Studentin einen auswählen kann.
Lösungsformat: Das Lösungsformat umfasst eine Liste möglicher Antworten, die richtige Antwort, sowie eine Reihe von Optionen. Zum Beispiel:
...
<div class="meta">
...
<div class="atype">radio</div>
...
</div>
...
<div class="question">
<p>Für welche Zahl <code>\blue{x}</code> gilt <code>\blue{x}^2 = 100</code>?</p>
</div>
<div class="solution" data-no-input-feedback="false">
<span class="instruction">
<em>Wählen Sie aus:</em>
</span>
<span class="value">10</span>
<ul class="choices" data-none="true" data-show="6">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
</ul>
</div>
.instruction
ist ein optionales Element und erlaubt wie bei anderen Antworttypen eigenes HTML direkt oberhalb der Single-choice-Liste anzuzeigen (LaTeX und Variablen erlaubt). .value
muss gesetzt werden und enthält die korrekte Lösung. .choices
ist ebenfalls notwendig und enthält alle falschen Antworten (ist data-category="true"
, so muss .choices
zudem auch die richtige Antwort enthalten). Auf .choices
kann eine Reihe von Optionen gesetzt werden:
data-category
,"true"
oder"false"
(standardmässig"false"
). Fallsdata-cateogry="true"
, wird stets die gesamte Liste der.choices
als klickbare Antworten angezeigt, und zwar in der Reihenfolge, in der sie aufgelistet sind..choices
muss dann auch die richtige Antwort beinhalten, an der Position, an der sie erwünscht ist.data-category="true"
ist immer dann nützlich, wenn bei allen Instanzen einer Aufgabe stets die gleichen Antworten zur Verfügung stehen (mit möglicherweise verschiedener korrekter Antwort).Falls
data-category="false"
, werden nicht alle Antworten angezeigt (die korrekte Antwort wird immer angezeigt, ausser wenndata-none="true"
, siehe unten). Zudem werden die angezeigten Antworten zufällig angeordnet. Mitdata-category="false"
können auch die beiden Optionendata-none
unddata-show
auf.choices
gesetzt werden.data-none
,"true"
oder"false"
(standardmässig"false"
). Falls gesetzt, ist die letzte anklickbare Antwort stets"Keine der obigen Antworten"
. Auch wird die richtige Antwort (der Inhalt von.value
) nun nicht mehr unbedingt angezeigt; ist dies der Fall, wird"Keine der obigen Antowrten"
als richtig gewertet.data-show
, positive ganze Zahl (standardmässig Anzahl in.choices
+ 1; bzw. + 2, fallsdata-none
gesetzt ist). Gibt an, wie viele klickbare Antworten insgesamt angezeigt werden.
Das obige Beispiel generiert folgende Aufgabe:
Hier wird 10
als korrekt gewertet; sollte 10
nicht aufgelistet sein, so würde "Keine der obigen Antworten"
als korrekt gewertet.
Legacy-Lösungsformat: Wird radio
als globaler Antworttyp verwendet, kann aus Kompatibilitätsgründen auch die ältere Khan-Syntax für das Solution-div verwendet werden:
<div class="solution">Richtige Antwort</div>
<ul class="choices">
<li>Falsche Antwort #1</li>
<li>Falsche Antwort #2</li>
<li>Falsche Antwort #3</li>
</ul>
Die Optionen werden in dieser Syntax direkt auf das .choices
-Element gesetzt; falls data-category="true"
gesetzt ist, muss wie in der neuen Syntax die richtige Antwort neben den falschen auch in .choices
vorhanden sein.
2.5 checkbox
Der Antworttyp kann für wahr/falsch-Antworten verwendet werden.
Eingabeformat: checkbox
erstellt eine Checkbox, die der Student/die Studentin an- und abwählen kann.
Einfaches Lösungsformat: Die korrekte Antwort (true
oder false
) kann direkt als Text im Solution-div eingegeben werden. Die Checkbox wird ohne jeglichen zusätzlichen Text erzeugt.
Erweitertes Lösungsformat: Mehr Optionen ermöglicht das erweiterte Lösungsformat. Zum Beispiel:
<div class="solution">
<span class="instruction">Wählen Sie aus, falls zutreffend:</span>
<span class="label">x = <var>X</var> ist grösser als 0</span>
<span class="xlabel">
<code>\blue{x} = <var>X</var></code> ist grösser als <code>0</code>
</span>
<span class="value"><var>X > 0</var></span>
</div>
.instruction
enthält optionales HTML, das direkt oberhalb der Checkbox angezeigt wird.
.label
enthält optionalen Text, der nur für Screen-Reader sichtbar ist und den Inhalt von .xlabel
widerspiegeln sollte.
.xlabel
enthält optionales HTML, das rechts neben der Checkbox angezeigt wird.
.value
enthält die korrekte Antwort.
Das obige Beispiel erzeugt folgendes Antwort-UI:
2.6 list
Eingabeformat: list
erstellt eine drop-down-Liste, aus der der Student/die Studentin auswählen kann.
Einfaches Lösungsformat: Die korrekte Antwort wird im Text des solution-Elements angegeben. Die verschiedenen Antworten (einschliesslich der korrekten) werden formatiert als JavaScript-array im Attribut data-choices
des solution-Elements gesetzt. Die Optionen können weder LaTeX, noch Variablen enthalten. Zum Beispiel:
<div class="solution"
data-choices="['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']">
10
</div>
Hier ist die richtige Antwort 10. Dieses Beispiel erzeugt folgende drop-down-Liste:
Erweitertes Lösungsformat: Gleich wie das einfache Lösungsformat, ausser, dass die korrekte Lösung als Text von .value
innerhalb des solution-Elements angegeben und data-choices
auf .value
gesetzt werden:
<div class="solution">
<span class="instruction">
<em>Wählen Sie aus:</em>
</span>
<span class="value"
data-choices="['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']">
10
</span>
</div>
.instruction
ermöglicht, optionales HTML direkt oberhalb der drop-down-Liste anzuzeigen.
2.7 multiple
Der Antworttyp multiple
ermöglicht, mehrere Antworttypen zu verschachteln, um komplexere Antworttypen zu erhalten. Dazu werden die gewünschten Antworten hintereinander in divs der Klasse sol
innerhalb des solution-Elements angeordnet. Die Syntax einer Antwort in multiple
ist dieselbe, wie wenn der Antworttyp global verwendet wird; nur übernimmt das .sol
-div die Rolle des solution-Elements. Insbesondere können darauf Optionen gesetzt werden. Der Typ jeder Antworten in multiple
wird auf dem jeweiligen .sol
-div über data-type
gesetzt. id
kann auf jedem .sol
-div gesetzt werden. Zum Beispiel zwei number
-Antworten:
<div class="solution">
<div class="sol" data-type="number">
<span class="label">untere Grenze:</span>
<span class="xlabel"><span style="width: 7em">untere Grenze:</span></span>
<span id="sol_c" class="value"
data-show-tooltip="true"
data-forms="integer"
>
<var>RANGE[0]</var>
</span>
</div>
<div class="sol" data-type="number">
<span class="label">obere Grenze:</span>
<span class="xlabel"><span style="width: 7em">obere Grenze:</span></span>
<span id="sol_a" class="value"
data-show-tooltip="true"
data-forms="integer"
>
<var>RANGE[1]</var>
</span>
</div>
</div>
Wird der Antworttyp radio
in multiple
verwendet, kann das Legacy-Format von radio
nicht verwendet werden.
Die Antwort wird als richtig gewertet, wenn alle Teilantworten richtig sind. Die Option data-no-input-feedback
auf dem solution-div steuert, ob Feedback über die Richtigkeit der Teilantworteten gegeben wird ("false"
, standard) oder nicht ("true"
).
Legacy-Format: Aus Kompatibilitätsgründen mit vorherigen kekse-Versionen kann auch das folgende Format für multiple
verwendet werden:
<div class="solution">
<div>
<span class="label">untere Grenze:</span>
<span class="xlabel">untere Grenze:</span>
<span id="sol_c" class="sol" data-type="number"><var>RANGE[0]</var></span>
</div>
<div>
<span class="label">obere Grenze:</span>
<span class="xlabel">obere Grenze:</span>
<span id="sol_a" class="sol" data-type="number"><var>RANGE[1]</var></span>
</div>
</div>
Hier wird jede Teilantwort in einem eigenen div angegeben. Das .sol
-div innerhalb dieses divs wird blind als .value
interpretiert für den Antworttyp, der durch data-type
gegeben ist. Weitere Elemente innerhalb des divs werden ebenfalls blind als Elemente dieser Antwort interpretiert.
Es wird dringend empfohlen, diese Syntax nicht für neue Aufgaben zu verwenden, da sie äusserst verwirrend ist. Das Legacy-Format funktioniert auch bloss für diejenigen Antworttypen, die ein .value
-div enthalten.
2.8 set
Der Antworttyp ermöglicht dem Studenten/der Studentin, mehrere korrekte Lösungen eines bestimmten Antworttyps in beliebiger Ordnung einzugeben. Der Entwickler/die Entwicklerin der Aufgabe gibt dazu eine Reihe korrekter Antworten an, und bestimmt zudem das Eingabeformat; dieses legt fest, wie viele korrekte Antworten verlangt sind. Alle korrekten Antworten müssen den gleichen Antworttyp verwenden. Ausser set
und radio
dürfen alle Antworttypen in set
verwendet werden (sogar multiple
).
Um Fehler zu vermeiden, sollten stets mehr oder gleich viele korrekte Antworten existieren, wie Kopien der Benutzeroberfläche, sodass Studenten/Studentinnen alle Benutzeroberflächen mit verschiedenen, richtigen Antworten ausfüllen müssen. In Khan war es jedoch möglich, im Eingabeformat mehr Kopien der Benutzeroberflächen zur Verfügung zu stellen, als die Anzahl korrekter Antworten; Studenten und Studentinnen mussten in solchen Aufgaben alle korrekten Antworten angeben und die restlichen Benutzeroberflächen leerlassen. Dies funktionierte jedoch nur in Ausnahmefällen, da für die meisten Antworttypen nicht klar ist, wann die Benutzeroberfläche "leer gelassen" wurde (z.B. checkbox
). In kekse könnten mehr Kopien der Benutzeroberfläche als korrekte Antworten ebenfalls in Ausnahmefällen funktionieren, davon wird aber abgeraten.
Ein typisches Beispiel für die Verwendung von set
sind die beiden Lösungen (bzw. zwei identische Lösungen) quadratischer Gleichungen; wir werden daran gleich die Verwendung von set
erklären:
<div class="question">
<p> Lösen Sie die quadratische Gleichung für <code>x</code> auf:</p>
<p><code><var>plus(SQUARE + "x^2")</var> + <var>plus( LINEAR + "x" )</var> + <var>CONSTANT</var> = 0</code>.</p>
<p>Geben Sie beide Lösungen an.</p>
</div>
<div class="solution">
<div class="set-sol" data-type="rational" data-simplify="optional">
<var>A</var>
</div>
<div class="set-sol" data-type="rational" data-simplify="optional">
<var>B</var>
</div>
<div class="input-format">
<div class="entry" data-type="rational"
data-simplify="optional"
data-show-tooltop="true"
>
<span class="label"></span>
<span class="xlabel"><code>\blue{x_1} =</code></span>
<span class="value"></span>
</div>
<div class="entry" data-type="rational"
data-simplify="optional"
data-show-tooltop="true"
>
<span class="label"></span>
<span class="xlabel"><code>\blue{x_2} =</code></span>
<span class="value"></span>
</div>
</div>
</div>
Die divs .set-sol
bestimmen die korrekten Antworten der Aufgabe. Sie folgen dem Format für Solution-divs des Antworttyps, ausser, dass alle Format-spezifischen Angaben ignoriert werden; die .set-sol
-Elemente werden bloss für ihre interne Logik verwendet und nicht für die Erzeugung von Benutzeroberflächen. Deshalb bieten sich wie im Beispiel auch sonst meistens das einfache Lösungsformat des verwendeten Antworttyps an (sofern dieser überhaupt zwei Lösungsformate besitzt). Auf allen .set-sols
muss data-type
gesetzt werden, um den Antworttyp festzulegen; alle .set-sol
-Elemente müssen den gleichen Antworttyp verwenden.
.input-format
enthält das Eingabeformat. Für jede gewünschte Kopie der Benutzeroberfläche, in der Studenten und Studentinnen eine Antwort eingeben können, wird darin ein div .entry
geschrieben. Hier können zum Beispiel zwei Antworten eingegeben werden, was gerade der Anzahl korrekter Antworten entspricht. Der Antworttyp rational
(eine Variante von number
) im Beispiel besitzt eine Textbox als Benutzeroberfläche; es werden also zwei Textboxen angezeigt. Auch .entry
folgen dem Format des zugrundeliegenden Antworttyps. Ausser, dass jetzt der Wert der Antwort ignoriert wird, die Format-spezifischen Angaben jedoch nicht. Die verschieden .entry
-Elemente müssen keinesfalls gleich sein; so können die verschiedenen Kopien der Benutzeroberfläche unterschiedlich formatiert werden.
Das Beispiel erzeugt folgende (gesamte) Benutzeroberfläche:
Ein etwas komplexeres Beispiel ist das folgende:
<div class="vars">
<var id="FACTORS">[1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 20, 24, 30, 40, 60, 120]</var>
</div>
<div class="question">
<p>Finden Sie zwei ganze Zahlen <code>\blue{x}</code> und <code>\red{y}</code>, sodass <code>\blue{x} \cdot \red{y} = 120</code>.</p>
</div>
<div class="solution" data-no-input-feedback="true">
<div class="set-sol" data-type="multiple" data-each="FACTORS as factor">
<div class="sol" data-type="number" data-forms="integer">
<var>factor</var>
</div>
<div class="sol" data-type="number" data-forms="integer">
<var>120 / factor</var>
</div>
</div>
<div class="input-format">
<div class="entry" data-type="multiple">
<div class="sol" data-type="number"
data-forms="integer"
data-show-tooltip="true"
>
<span class="xlabel"><code>\blue{x} =</code></span>
<span class="value"></span>
</div>
<div class="sol" data-type="number"
data-forms="integer"
data-show-tooltip="true"
>
<span class="xlabel"><code>\red{y} =</code></span>
<span class="value"></span>
</div>
</div>
</div>
</div>
Dies erzeugt folgende Benutzeroberfläche:
Hier ist der Antworttyp nicht etwa number
, sondern multiple
mit zwei verschachtelten number
-Antworttypen. Auch werden nicht zwei Antworten, sondern nur eine Antwort erwartet. Hier wurde so vorgegangen, da zwei beliebige Teiler von 120 natürlich nicht unbedingt zu 120 multiplizieren; Die korrekten Antworten sind nur gewisse Paare aller möglichen Faktorpaare.
Damit nicht alle möglichen Paare von Hand in .set-sol
s eingegeben werden müssen, wurde hier data-each
verwendet: das .set-sol
-Element wird also automatisch für jeden Faktor im Array FACTORS
wiederholt, mit dem jeweiligen Faktor als Wert der Variable factor
.
2.9 custom
Der Antworttyp custom
ermöglicht eine vom Entwickler/von der Entwicklerin definierte Benutzeroberfläche mit ebenfalls benutzerdefinierten interner Logik.
<div class="solution">
<div class="instruction">
Ziehen Sie den Punkt an die korrekte Position.
</div>
<div class="guess">[graph.p.coord]</div>
<div class="validator-function">
console.log(guess[0]);
return (guess[0][0] > 0 && guess[0][1] > 0);
</div>
<div class="show-guess">
graphi.p.setCoord(guess[0]);
</div>
</div>
custom
ist besonders praktisch für interaktive Aufgaben.
.instruction
enthält das (optionale) html der Benutzeroberfläche. In diesem Beispiel ist bloss eine kurze Anleitung gegeben, da der Student/die Studentin direkt mit Graphie interagiert.
.guess
gibt an, was zur Antwort des Studenten/der Studentin zählt. Hier sind es die Koordinaten eines Punkts im interaktiven Graphie.
.validator-function
ist der Quellcode einer JavaScript-Funktion, die die in .guess
definierte Antwort in form des Arrays guess
annimmt, und einen bool zurückgeben soll; true
bedeutet, dass die gegeben Antwort als korrekt gewertet werden soll ist. Aus Kompatibilität zu Khan kann auch ein string zurückgegeben werden, der aber als false gewertet wird. In der validator-Funktion sollte nur der Inhalt von guess
verwendet werden, sowie bereits definierte Globale Variablen. Hier werden die Koordinaten des Punkts zuerst zu Debug-Zwecken ausgegeben; die Antwort wird anschliessend als richtig gewertet, wenn sich der Punkt im ersten Quadrant befindet.
.show-guess
ist optional und enthält JavaScript-Code, um aus de Wert von guess
die Antwort in der Benutzeroberfläche wiederherzustellen. Hier werden einfach die Koordinaten des Punkts gesetzt. Diese Funktion hat momentan noch keinen Nutzen.
Validator-Funktionen können durchaus komplex sein. Dieses Beispiel wurde ohne grosse Anpassungen direkt aus einem alten Khan-Beispiel übernommen:
var xyMessage = null, xyEmpty = false;
var slopeValidator = Khan.answerTypes.predicate.createValidatorFunctional(
function(slope, error) {
if (Math.abs(slope - <var>SLOPE</var>) > Math.pow(2, -42)) {
return false;
}
var yMessage = null, yEmpty = false;
var xValidator = Khan.answerTypes.predicate.createValidatorFunctional(
function(x, error) {
var yValidator = Khan.answerTypes.predicate.createValidatorFunctional(
function(y, error) {
return Math.abs((x * slope - y) - <var>INTERCEPT</var>)
< Math.pow(2, -42);
}, {forms: 'integer, proper, improper, mixed, decimal'});
var yResult = yValidator(guess[0]);
if (yResult.empty) {
yEmpty = true;
}
if (yResult.message !== null) {
yMessage = yResult.message;
}
if (yResult.correct) {
yEmpty = false;
yMessage = null;
}
return yResult.correct;
}, {forms: 'integer, proper, improper, mixed, decimal'});
var xResult = xValidator(guess[2]);
if (xResult.empty || yEmpty) {
xyEmpty = true;
}
if (xResult.message !== null || yMessage !== null) {
xyMessage = xResult.message || yMessage;
}
if (xResult.correct) {
xyEmpty = false;
xyMessage = null;
}
return xResult.correct;
}, {forms: 'integer, proper, improper, mixed, decimal, coefficient', fallback: 1});
var slopeResult = slopeValidator(guess[1]);
if (slopeResult.empty || xyEmpty) {
return "";
} else if (slopeResult.message !== null) {
return slopeResult.message;
} else if (xyMessage !== null) {
return xyMessage;
}
return slopeResult.correct;
Hier wurde insbesondere an mehreren Stellen ein predicate-Validator erzeugt, der dann ausgewertet wurde (siehe weiter unten für mehr Details zur Verwendung der Antworttyp-Validatoren im eigenen JavaScript).
2.10 expression
Der Antworttyp expression
nimmt mathematische Ausdrücke über eine Textbox entgegen und vergleicht sie semantisch zur Lösung. Je nach gesetzten Optionen, muss die Eingabe möglichst vereinfacht sein oder genau mit der Lösung übereinstimmen (und nicht nur zur Lösung umformbar sein). expression
eignet sich zum Beispiel, um die Faktorisierung von Polynomen abzufragen.
Bei jeder Änderung der Eingabe wird die Eingabe gelesen und falls sie semantisch korrekt ist, wird unterhalb der Textbox der eingegebene Ausdruck in LaTeX ausgegeben. Dies hilft dem Studenten/der Studentin, mathematische Operationen richtig einzugeben. Falls die Eingabe nicht interpretiert werden kann (z.B. wenn Klammern nicht übereinstimmen), wird "Ungültige Eingabe" angezeigt.
Multiplikationen werden mit *
geschrieben (Bsp.: 2*2
); zwischen einer Zahl und einer Variablen kann *
auch weggelassen werden (Bsp.: 3*x
, 3x
). Brüche werden mit /
geschrieben (Bsp.: x/y
). Potenzen verwenden das Symbol ^
(Bsp.: x^y
). Die Quadratwurzel von x
wird als sqrt(x)
geschrieben, dasselbe gilt für trigonometrische Funktionen: sin(x)
, cos(x)
, usw. Pi wird mit pi
notiert, die Eulersche Zahl mit e
, die imaginäre Einheit mit i
. <=
und >=
bedeuten kleiner gleich bzw. grösser gleich, =/=
bedeutet ungleich.
Eingabeformat/Lösungsformat: Textbox (siehe Kapitel 3).
Optionale Attribute für solution-div:
data-same-form
,"true"
oder"false"
(standardmässig"false"
). Gibt an, ob der eingegebene Ausdruck in der selben Form vorliegen muss wie die Lösung. Kommutativität von Addition und Multiplikation sowie überschüssige Minuszeichen werden jedoch nicht berücksichtigt. Wenn die Lösung z.B.(x-1)(x+2)
ist, dann werden(x-1)(x+2)
,(x+2)(x-1)
,---(-x-2)(-1+x)
, usw. akzeptiert, aberx^2+x-2
,x*x+x-2
,x(x+1)-2
,(x-1)(x+2)^1
, usw. nicht, obwohl sie gleich der Lösung sind. Diese Option ist zum Beispiel nützlich, wenn die Antwort faktorisiert eingegeben werden soll.data-functions
, string (standardmässig""
). Liste von Buchstaben, die als Funktionen interpretiert werden sollen. Standardmässig werden alle einzelnen Buchstaben als Variablen interpretiert.e
undi
können keine Funktionen sein, da sie für Konstanten reserviert sind. Ist z.B.f
keine Funktion, so istf(x + y)
gleichfx + fy
, ansonsten nicht.data-simplify
,"true"
oder"false"
(standardmässig"false"
). Falls gesetzt, muss die Antwort vereinfacht eingegeben werden. Die Lösung sollte dann auch bereits in vereinfachter Form angegeben werden.data-times
,"true"
oder"false"
(standardmässig"false"
). Falls gesetzt, wird in der LaTeX-Ausgabe anstelle von\cdot
\times
als Multiplikationssymbol verwendet.data-show-tooltip
,"true"
oder"false"
(standardmässig"false"
). Zeigt einen Tooltip mit Formatvorschlägen an (ähnlich den Formatbeschreibungen oben).
Wert der Lösung: Mathematischer Ausdruck (im selben Format wie die Eingaben des Studenten/der Studentin).
Beispiel:
...
<div class="question">
<p>Faktorisieren Sie <code>x^2 - y^2</code>.</p>
</div>
<div class="solution"
data-no-input-feedback="true"
data-same-form="true"
data-show-tooltip="true"
>
(x+y)(x-y)
</div>
...
Dieser Code erzeugt folgende Benutzeroberfläche:
In der grauen Box wird die letzte Eingabe in LaTeX-Form angezeigt, die erfolgreich interpretiert wurde. Da hier data-same-form
gesetzt wurde, muss die Antwort faktorisiert sein.
Weiteres Beispiel:
...
<div class="question">
<p>Schreiben Sie <code>1234</code> in wissenschaftlicher Schreibweise.</p>
</div>
<div class="solution"
data-no-input-feedback="true"
data-same-form="true"
data-times="true"
>
1.234 * 10^3
</div>
...
Dies erzeugt folgende Benutzeroberfläche:
3. Eingabeformat und Lösungsformat Textbox
Alle Antworttypen, die Textbox als Lösungs- und Eingabeformat verwenden, werden automatisch mit einer Textbox ausgestattet, wo der Student/die Studentin ihre Antwort eingeben kann.
Textbox unterstützt zwei mögliche Lösungsformate:
Einfaches Format. Der Lösungwert wird direkt als Text in das solution-div geschrieben (Variablen sind erlaubt). Zum Beispiel für den Antworttyp
number
:<div class="solution"><var>X + Y</var></div>
Das resultierende UI sieht für alle einfach formatierten Textboxen gleich aus:
Erweitertes Format. Innerhalb des solution-divs werden spans verwendet, um den Lösungswert anzugeben und das Aussehen der Textbox weiter anzupassen. Im erweiterten Format ist die Angabe des span
.value
notwendig, die anderen drei sind optional. Beispiel:<div class="solution" id="sol_1"> <span class="instruction">Geben Sie hier <em>Ihre Antwort</em> ein:</span> <span class="label">x</span> <span class="xlabel"><code>\blue{x}=</code></span> <span class="value"><var>result</var></span> </div>
.value
enthält den Lösungswert..instruction
enthält HTML, das oberhalb der Textbox angezeigt wird (LaTeX und Variablen erlaubt)..xlabel
enthält HTML, das als Addon links neben der Textbox angezeigt wird (LaTeX und Variablen erlaubt)..label
enthält Text, der von Screen-Readern angezeigt wird (Variablen erlaubt). Werden.instruction
und.xlabel
nicht gesetzt, sieht die Textbox gleich aus wie im einfachen Format.Das obige Beispiel erzeugt folgende Textbox:
4. Antworttypen-Validatoren im eigenen JavaScript
Wie in einem vorherigen Beispiel demonstriert (Antworttyp custom
), können die Validator-Funktionen der meisten Antworttypen direkt in eigenem JavaScript-Code verwendet werden: in .validator-function
, .show-guess
von custom
, im Prädikat von predicate
oder an anderen Orten, wie zum Beispiel in einem graphie
-div.
Die Validator-Funktionen aller Antworttypen ausser mutliple
, set
, radio
und custom
können so direkt verwendet werden. Jede Validator-Funktion muss über
var validator_function = Khan.answerTypes.Antworttyp.createValidatorFunctional(...);
erzeugt werden, wobei Antworttyp
für den jeweiligen Antworttyp steht. Ebenfalls möglich ist
var validator_function = Khan.answerTypes["Antworttyp"].createValidatorFunctional(...);
createValidatorFunctional(correct, options)
erwartet für alle Antworttypen zwei Argumente. correct
ist der korrekte Wert, gegen den die Validator-Funktion später Eingaben vergleichen wird. Je nach Antworttyp ist der Datentyp von correct
verschieden, am besten wird dazu der Quellcode von kekse konsultiert. options
enthält Optionen, die sonst auf dem solution-div gesetzt würden.
Einmal erstellt, kann eine Validator-Funktion wie folgt verwendet werden:
var score = validator_function(guess);
guess
ist der Wert, der validiert werden soll. Der Datentyp von guess
ist auch vom Antworttyp abhängig. score
ist ein Objekt, das folgende Felder enthält:
score.correct
,bool
, zeigt an, obguess
korrekt gewertet wurde.score.empty
,bool
, zeigt an, obguess
als leer gewertet wurde; funktioniert nur für gewisse Antworttypen.score.guess
, enthält eine Kopie vonguess
. Je nach Antworttyp können auch andere Felder vorkommen.