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:

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:

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:

Mögliche Werte für data-forms:

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

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&auml;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:

Das obige Beispiel generiert folgende Aufgabe:

radio

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 &gt; 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:

checkbox

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:

checkbox

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&auml;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:

quadratische Gleichung mit set

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:

Faktorisierung mit set

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-sols 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>) &gt; 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>) 
            &lt; 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:

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:

Antworttyp Expression

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:

Antworttyp Expression


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:


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: