Fragenformat

tech-exam liest Fragen aus einer Datei ein. Diese Seite beschreibt, wie sie aufgebaut sein muss — damit eine KI Ihrer Wahl Fragen schreiben kann, die Sie danach in Ihre Sammlung übernehmen. Alle Beispiele hier sind der Inhalt, mit dem ein neues Konto startet, und liessen sich unverändert einlesen. Das Fach darin ist ein Beispiel und kein Vorbild: Gefragt ist der Aufbau, nicht das Thema.

Mit einer eigenen KI zu Fragen kommen

  1. In der Fragensammlung «Mit eigener KI» wählen und dort Thema, Anzahl und Aufgabentyp vorgeben.
  2. Den fertigen Auftrag in einem KI-Dienst öffnen oder ihn kopieren. Er verweist auf diese Seite, damit die KI den Aufbau kennt.
  3. Das Ergebnis aus dem Chat kopieren und im selben Dialog einfügen — oder als Datei sichern und über «Aus Datei» einlesen.
  4. Die Fragen in der Sammlung durchlesen, bevor eine Prüfung damit gehalten wird. Erfundene Fragen enthalten mitunter Fehler, die glaubwürdig aussehen.

Der Aufbau

Aussen stehen eine Kennung, eine Versionsnummer und die Liste der Fragen. Alles Weitere gehört zu den Fragen selbst. Ein Feld, das seinen Vorgabewert trägt, wird weggelassen — so sehen die Beispiele auf dieser Seite aus, und so darf auch eine geschriebene Datei aussehen.

{
  "format": "tech-exam/questions",
  "formatVersion": 1,
  "questions": [
    {
      "topic": "Beispielfragen",
      "subtopic": "Fragetypen",
      "subsubtopic": "Multiple Choice",
      "title": "Aussagen über Listen",
      "contentType": "mc",
      "maxPoints": 4,
      "description": "Welche Aussagen über Listen in Python sind richtig?",
      "answerSpec": {
        "kind": "mc",
        "options": [
          {
            "id": "o1",
            "text": "Eine Liste ist veränderbar."
          },
          {
            "id": "o2",
            "text": "Eine Liste kann nur Zahlen enthalten."
          },
          {
            "id": "o3",
            "text": "Eine Liste behält die Reihenfolge der Einträge."
          },
          {
            "id": "o4",
            "text": "`len(zahlen)` gibt den grössten Wert der Liste zurück."
          }
        ],
        "multiple": true,
        "scoring": {
          "mode": "allOrNothing"
        }
      },
      "answerKey": {
        "kind": "mc",
        "correct": [
          "o1",
          "o3"
        ]
      }
    },
    {
      "topic": "Beispielfragen",
      "subtopic": "Fragetypen",
      "subsubtopic": "Langtext",
      "title": "Wann Liste, wann Dictionary?",
      "contentType": "langtext",
      "maxPoints": 6,
      "description": "Begründe in einem Abschnitt, wann sich eine Liste besser eignet als ein Dictionary – und wann umgekehrt. Nenne je ein Beispiel.",
      "solution": "Eine Liste passt, wenn die Reihenfolge zählt und alle Einträge der Reihe nach durchlaufen werden, etwa eine Rangliste.\n\nEin Dictionary passt, wenn ein Wert über einen Schlüssel gefunden werden soll, etwa die Note zu einem Namen: Der Zugriff bleibt gleich schnell, egal wie viele Einträge dazukommen.\n",
      "criteria": [
        {
          "text": "Die Begründung trifft das Entscheidende: Reihenfolge und Durchlaufen bei der Liste, Zugriff über den Schlüssel beim Dictionary.",
          "points": 3
        },
        {
          "text": "Zu beiden Fällen steht ein konkretes Beispiel, das das genannte Merkmal wirklich braucht.",
          "points": 3
        }
      ]
    }
  ]
}

Die Felder

Drei Felder muss eine Frage tragen: Titel, Aufgabentyp und Punktzahl. Alle übrigen dürfen fehlen — dann gilt, was in der dritten Spalte steht. Eine Datei mit drei richtigen Feldern ist mehr wert als eine mit lauter geratenen.

Aussen um die Fragen

FeldWerteFehlt es, giltBedeutung
format"tech-exam/questions"PflichtDie Kennung, an der die Datei erkannt wird. Sie lautet immer gleich.
formatVersion1PflichtDie Nummer des Aufbaus.
questions[ … ]PflichtDie Fragen. Jede ist entweder eine Frage mit Antwortbereich oder eine Frage mit Teilfragen.

An jeder Frage

FeldWerteFehlt es, giltBedeutung
titleTextPflichtDer Titel, der über der Aufgabe steht.
contentType"svg" · "tigerpython" · "tigerpython_robotik" · "python" · "mc" · "lueckentext" · "langtext"PflichtWomit geantwortet wird: «mc» Auswahl, «lueckentext» Lücken im Text, «langtext» Fliesstext, «python» und «tigerpython» Programmcode, «tigerpython_robotik» ein Programm für den micro:bit oder einen Roboter daran, «svg» eine Zeichnung.
maxPoints≥ 0.5PflichtWie viele Punkte die Frage höchstens gibt.
topicText""Der Ordner in der Sammlung.
subtopicText""Der Unterordner.
subsubtopicText""Der Unterunterordner.
descriptionTextnullDie Aufgabenstellung. Beim Lückentext bleibt sie leer, weil dessen Text in den Segmenten steht.
descriptionFormat"markdown" · "html""markdown"Wie die Aufgabenstellung gesetzt ist. Markdown kennt Tabellen, Code-Blöcke und Mathe zwischen Dollarzeichen.
solutionTextnullDie Musterlösung. Nur für Lehrpersonen sichtbar.
starterCodeTextnullCode, der im Editor schon dasteht, wenn die Aufgabe geöffnet wird.
answerSpec{ … }nullDie Antwortmöglichkeiten. Nötig bei Auswahl und Lückentext, sonst weglassen.
answerKey{ … }nullDie richtige Antwort. Sie benutzt dieselben Kennungen wie answerSpec.
criteria[ … ][]Korrekturanweisungen: je ein Text für die Lernenden und die Punkte dazu. Punkte mit Plus kommen zur Bewertung dazu, Punkte mit Minus gehen weg.
graderCodeTextnullPython-Code, der die Punkte dieser Frage selbst vergibt, statt sie von Hand geben zu lassen. Er wird ausgeführt, sobald damit korrigiert wird.
graderRules{ … }{}Was gilt, wenn das Programm einer Abgabe nicht läuft oder nicht fertig wird. Nur bei «python» und «tigerpython» von Bedeutung.

Programmieren und Zeichnen

Bei «tigerpython», «tigerpython_robotik», «python» und «svg» wird in einer eingebetteten Umgebung geantwortet. Bei «tigerpython_robotik» ist dort das Gerät eingeschaltet: Die Umgebung zeigt den Simulator des micro:bit, und sobald das Programm eine Roboterbibliothek einbindet, auch den des Roboters. «starterCode» legt hinein, was dort schon dasteht, wenn die Aufgabe geöffnet wird. «graderCode» vergibt die Punkte selbst: eine Python-Funktion «grade(answer, task, run)», die Punkte und Rückmeldung zurückgibt — «answer» ist die Abgabe, «task» die Aufgabe samt ihrer Punktzahl, «run» der Lauf des Programms mit seiner Ausgabe. «graderRules» nimmt ihr die beiden Fälle ab, in denen ein Programm gar nicht erst durchläuft. Bewertungscode wird ausgeführt, sobald damit korrigiert wird; beim Einlesen wird eigens darauf hingewiesen, und er gehört vorher gelesen.

{
  "format": "tech-exam/questions",
  "formatVersion": 1,
  "questions": [
    {
      "topic": "Beispielfragen",
      "subtopic": "Programmieren",
      "subsubtopic": "TigerPython",
      "title": "Quadrat mit repeat",
      "contentType": "tigerpython",
      "maxPoints": 6,
      "description": "Zeichne mit der Turtle ein Quadrat mit Seitenlänge 100. Nutze dafür die `repeat`-Schleife von TigerPython.",
      "solution": "from gturtle import *\n\nmakeTurtle()\nrepeat 4:\n    forward(100)\n    right(90)\n",
      "criteria": [
        {
          "text": "`repeat 4:` wiederholt den eingerückten Block viermal – für ein Quadrat braucht es genau vier Durchgänge.",
          "points": 3
        },
        {
          "text": "Im Schleifenkörper gehören `forward(100)` und `right(90)` zusammen; ohne die Drehung entsteht eine Linie statt eines Quadrats.",
          "points": 3
        },
        {
          "text": "Ohne `makeTurtle()` gibt es nichts, was zeichnen könnte – das Programm bleibt gleich zu Beginn stehen.",
          "points": -1
        }
      ]
    },
    {
      "topic": "Beispielfragen",
      "subtopic": "Programmieren",
      "subsubtopic": "Roboter",
      "title": "Zwei Sekunden geradeaus",
      "contentType": "tigerpython_robotik",
      "maxPoints": 3,
      "description": "Lass den Roboter zwei Sekunden geradeaus fahren und danach anhalten.",
      "solution": "from mbrobot import *\n\nforward()\ndelay(2000)\nstop()\n",
      "criteria": [
        {
          "text": "`forward()` setzt den Roboter in Bewegung, `stop()` hält ihn wieder an.",
          "points": 2
        },
        {
          "text": "`delay(2000)` lässt dazwischen zwei Sekunden verstreichen – ohne die Wartezeit steht er, bevor er losgefahren ist.",
          "points": 1
        }
      ]
    },
    {
      "topic": "Beispielfragen",
      "subtopic": "Programmieren",
      "subsubtopic": "Python",
      "title": "Summe zweier Zahlen",
      "contentType": "python",
      "maxPoints": 10,
      "description": "Schreibe eine Funktion `add(a, b)`, die die Summe der beiden Argumente zurückgibt.",
      "solution": "def add(a, b):\n    return a + b\n",
      "starterCode": "def add(a, b):\n    # Gib hier die Summe von a und b zurück.\n    pass\n",
      "graderCode": "def grade(answer, task, run):\n    # Die Abgabe ausführen und die Funktion aus der Musterlösung holen. Ob sie\n    # sich überhaupt ausführen lässt, entscheiden die Regeln über diesem Feld.\n    umgebung = {}\n    exec(answer[\"value\"], umgebung)\n\n    funktion = umgebung.get(\"add\")  # Name aus der Musterlösung\n    if not callable(funktion):\n        return {\"points\": 0, \"feedback\": \"Die Funktion «add» fehlt.\"}\n\n    faelle = [((1, 2), 3), ((-1, 1), 0), ((0, 0), 0)]  # (Argumente, erwartet)\n    treffer = 0\n    for argumente, erwartet in faelle:\n        try:\n            if funktion(*argumente) == erwartet:\n                treffer += 1\n        except Exception:\n            pass\n\n    return {\n        \"points\": round(task[\"maxPoints\"] * treffer / len(faelle), 2),\n        \"feedback\": f\"{treffer} von {len(faelle)} Testfällen bestanden.\",\n    }\n",
      "graderRules": {
        "error": {
          "points": 0,
          "feedback": "Das Programm läuft nicht."
        },
        "timeout": {
          "points": 0,
          "feedback": "Das Programm wird nicht fertig."
        }
      }
    },
    {
      "topic": "Beispielfragen",
      "subtopic": "Programmieren",
      "subsubtopic": "SVG",
      "title": "Roter Kreis",
      "contentType": "svg",
      "maxPoints": 10,
      "description": "Zeichne mit SVG einen roten Kreis mit Radius 50 in der Mitte einer Zeichenfläche von $200 * 200$.",
      "solution": "<svg viewBox=\"0 0 200 200\">\n  <circle cx=\"100\" cy=\"100\" r=\"50\" fill=\"red\" />\n</svg>\n",
      "starterCode": "<svg viewBox=\"0 0 200 200\">\n  <!-- Zeichne den Kreis hier hinein. -->\n</svg>\n",
      "criteria": [
        {
          "text": "`cx` und `cy` liegen bei `100`, also in der Mitte der Zeichenfläche, und `r` bei `50`.",
          "points": 6
        },
        {
          "text": "`fill=\"red\"` füllt den Kreis rot – ohne `fill` zeichnet der Browser schwarz.",
          "points": 4
        }
      ]
    }
  ]
}

Lückentext

Der Lückentext ist der einzige Typ, dessen Aufgabenstellung nicht in «description» steht: Sein Text liegt vollständig in den Segmenten. Eine Lücke ohne Auswahl wird getippt, eine mit Auswahl angeklickt — und jede Lücke braucht dieselbe Kennung auf beiden Seiten.

{
  "format": "tech-exam/questions",
  "formatVersion": 1,
  "questions": [
    {
      "topic": "Beispielfragen",
      "subtopic": "Fragetypen",
      "subsubtopic": "Lückentext",
      "title": "Klammern in Python",
      "contentType": "lueckentext",
      "maxPoints": 2,
      "answerSpec": {
        "kind": "cloze",
        "segments": [
          {
            "type": "text",
            "text": "Eine Liste wird mit "
          },
          {
            "type": "gap",
            "id": "g1",
            "choices": null
          },
          {
            "type": "text",
            "text": " erzeugt, ein Dictionary mit "
          },
          {
            "type": "gap",
            "id": "g2",
            "choices": [
              {
                "id": "g2c1",
                "text": "geschweiften Klammern"
              },
              {
                "id": "g2c2",
                "text": "runden Klammern"
              },
              {
                "id": "g2c3",
                "text": "spitzen Klammern"
              }
            ]
          },
          {
            "type": "text",
            "text": "."
          }
        ],
        "compare": {
          "caseSensitive": false,
          "normalizeWhitespace": true,
          "numericTolerance": null
        }
      },
      "answerKey": {
        "kind": "cloze",
        "gaps": {
          "g1": {
            "type": "text",
            "accepted": [
              "eckigen Klammern"
            ]
          },
          "g2": {
            "type": "choice",
            "correct": [
              "g2c1"
            ]
          }
        }
      }
    }
  ]
}

Fragen mit Teilfragen

Gehören mehrere Teilaufgaben zu einer gemeinsamen Aufgabenstellung, treten an die Stelle von Aufgabentyp und Punktzahl die Teilfragen. Der gemeinsame Text steht dann oben, alles Übrige bei ihnen. In der Fragensammlung wird daraus je eine einzelne Frage, die den gemeinsamen Text mitnimmt — weiter oben auf dieser Seite stehen genau diese drei deshalb auch einzeln. Hier tragen sie nur Titel, Aufgabentyp und Punktzahl, denn mehr verlangt eine Teilfrage nicht.

FeldWerteFehlt es, giltBedeutung
titleTextPflichtDer Titel, der über der Aufgabe steht.
subQuestions[ … ]PflichtDie Teilfragen. Aufgabentyp und Punkte trägt jede von ihnen selbst.
descriptionTextnullDie Aufgabenstellung. Beim Lückentext bleibt sie leer, weil dessen Text in den Segmenten steht.
{
  "format": "tech-exam/questions",
  "formatVersion": 1,
  "questions": [
    {
      "title": "Robotik mit dem micro:bit",
      "description": "Die beiden Teilfragen programmieren dasselbe Gerät: zuerst sein Display, dann den Roboter, auf dem es sitzt.\n\nZum Ausprobieren braucht es keine Hardware – die Programmierumgebung zeigt beides im Simulator.",
      "subQuestions": [
        {
          "title": "Ein blinkendes Herz",
          "contentType": "tigerpython_robotik",
          "maxPoints": 4
        },
        {
          "title": "Zwei Sekunden geradeaus",
          "contentType": "tigerpython_robotik",
          "maxPoints": 3
        }
      ]
    }
  ]
}

Was sonst noch gilt

  • Die Punktzahl ist mindestens 0.5 und hat höchstens 2 Nachkommastellen.
  • Jede Kennung in «answerKey» muss es in «answerSpec» geben, sonst lässt sich die Frage nicht öffnen.
  • Eine Auswahlfrage braucht mindestens zwei Antwortmöglichkeiten und mindestens eine richtige.
  • Bilder bringt die Datei nicht mit. Sie werden nachträglich im Editor eingefügt.
  • Die Datei enthält nichts ausser den Fragen — keinen einleitenden Satz davor, keine Erklärung danach.