Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .unosim-compatible-commit
Original file line number Diff line number Diff line change
@@ -1 +1 @@
5ce3564b2b770e59f48d8bc3b97097bf1f2ab894
4f4b7e5bc8b781ad193030861f517092c7125db9
44 changes: 37 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,20 +49,50 @@ The effective strategy precedence is:
2. repository `defaultStrategy`,
3. UnoSim `built-in-default`.

For example:
### Writing Tutor instructions for an Example (template)

Schema 2 lets a teacher say what the Tutor should ask for this Example. The
Tutor works through the `focus` areas in order and then switches to the free
Tutor (`afterFocus: free`, the default). `afterFocus: topics` continues with
the repository Topics instead.

```cpp
/* @unosim-tutor
schemaVersion: 1
topics:
- variables-and-serial
primaryTopic: variables-and-serial
schemaVersion: 2
learningObjectives:
- Die Studierenden sollen erklären können, welche Rolle die Variable im aktuellen Sketch spielt.
- Sie sollen den Zusammenhang zwischen gespeichertem Wert und serieller Ausgabe verstehen.
- "Die Studierenden sollen … erklären können."
afterFocus: free
focus:
- id: kurzer-bezeichner # lower-case, digits, hyphens
title: "Kurzer Titel"
objective: "Was die Studierenden nach diesem Bereich können sollen."
questions: # 1 to 6, asked in this order
- kind: recall # recall | concept | application | prediction | transfer
text: "Welchen Wert besitzt `variable` nach der Deklaration?"
- kind: concept
text: "Warum …?"
- kind: transfer
text: "Wie würdest du … erweitern?"
@end-unosim-tutor */
```

Rules and recommendations:

- 2 to 3 focus areas per Example, 1 to 3 questions per area. Keep functions
and parameters to one or two areas; the Tutor does not drift beyond them.
- Put every code term in backticks. Each backticked term must occur in the
sketch outside comments; the quality gate rejects the rest. Refer to
elements by description (for example "das Element mit dem Index 2") and
not by an expression that is not in the code.
- Never name a type or construct the sketch does not use (`long` for an
`unsigned long` sketch).
- Mix question kinds: start with `recall` or `concept`, then `prediction`,
and end with `application` or `transfer`.
- Questions carry no answers and no hints; the Tutor gives feedback.
- A focus area counts as mastered after one answer rated 3 or better. If the
questions are used up without that, the Tutor also switches to the free
mode.

Tutor repository data is normalized didactic data, never a system prompt.

### Deterministic Tutor quality gate
Expand Down
8 changes: 5 additions & 3 deletions examples/IT01/it01-01-variable-speichern.ino
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,21 @@ schemaVersion: 2
learningObjectives:
- "Die Studierenden sollen erklären können, welche Rolle die Variable im aktuellen Sketch spielt."
- "Sie sollen den Zusammenhang zwischen gespeichertem Wert und serieller Ausgabe verstehen."
exclusive: true
afterFocus: free
focus:
- id: wert-und-zuweisung
title: "Wert und Zuweisung"
objective: "Die Studierenden sollen den Aspekt \"Wert und Zuweisung\" erklären können."
objective: "Erklären, welchen Wert die Variable nach Deklaration und nach einer neuen Zuweisung besitzt und was mit dem alten Wert geschieht."
questions:
- kind: recall
text: "Welchen Wert besitzt `anzahlTeile` direkt nach der Deklaration?"
- kind: prediction
text: "Was geschieht mit dem alten Wert von `anzahlTeile`, wenn `anzahlTeile = 5` ausgeführt wird?"
- kind: application
text: "Wie viele Werte kann `anzahlTeile` zu einem Zeitpunkt gleichzeitig speichern?"
- id: sichtbare-ausgabe
title: "Sichtbare Ausgabe"
objective: "Die Studierenden sollen den Aspekt \"Sichtbare Ausgabe\" erklären können."
objective: "Begründen, warum die Ausgaben genau so und nur einmal erscheinen, und eine Erweiterung planen."
questions:
- kind: concept
text: "Warum erscheint jede Ausgabe von `Serial.println` nur einmal?"
Expand Down
11 changes: 7 additions & 4 deletions examples/IT01/it01-02-konstante.ino
Original file line number Diff line number Diff line change
Expand Up @@ -34,23 +34,26 @@ void loop() {
/* @unosim-tutor
schemaVersion: 2
learningObjectives:
- "Einen Wert mit const als Konstante deklarieren."
exclusive: true
- "Die Studierenden sollen eine Konstante von einer Variablen unterscheiden können."
- "Sie sollen erklären können, warum der Compiler eine nachträgliche Änderung ablehnt."
afterFocus: free
focus:
- id: konstante-oder-variable
title: "Konstante oder Variable"
objective: "Die Studierenden sollen den Aspekt \"Konstante oder Variable\" erklären können."
objective: "Den Unterschied zwischen einer Konstante und einer Variablen erklären und die Folge einer Änderung vorhersagen."
questions:
- kind: concept
text: "Wodurch unterscheidet sich `MAXIMALE_ANZAHL` von einer gewöhnlichen Variablen?"
- kind: prediction
text: "Was würde der Compiler melden, wenn man später versucht, `MAXIMALE_ANZAHL` einen neuen Wert zuzuweisen, und warum?"
- id: const-und-namen
title: "const und Namenswahl"
objective: "Die Studierenden sollen den Aspekt \"const und Namenswahl\" erklären können."
objective: "Die Rolle von `const` und die Namenskonvention für Konstanten begründen."
questions:
- kind: concept
text: "Welche Aufgabe hat das Schlüsselwort `const` in der Deklaration?"
- kind: concept
text: "Warum ist der Name `MAXIMALE_ANZAHL` hier großgeschrieben?"
- kind: transfer
text: "Für welchen weiteren Wert in einem Sketch wäre eine Konstante sinnvoll?"
@end-unosim-tutor */
11 changes: 7 additions & 4 deletions examples/IT02/it02-01-arithmetische-operatoren.ino
Original file line number Diff line number Diff line change
Expand Up @@ -43,20 +43,23 @@ void loop() {
/* @unosim-tutor
schemaVersion: 2
learningObjectives:
- "Die Operatoren +, -, *, / und % anwenden."
exclusive: true
- "Die Studierenden sollen die Operatoren +, -, *, / und % anwenden können."
- "Sie sollen das Verhalten der Ganzzahldivision erklären können."
afterFocus: free
focus:
- id: ganzzahldivision
title: "Ganzzahldivision"
objective: "Die Studierenden sollen den Aspekt \"Ganzzahldivision\" erklären können."
objective: "Erklären, warum die Division zweier `int`-Werte ein ganzzahliges Ergebnis liefert."
questions:
- kind: concept
text: "Warum liefert `a / b` bei Variablen vom Typ `int` ein ganzzahliges Ergebnis?"
- kind: prediction
text: "Welches Ergebnis erwartest du für `a / b`, wenn `a` den Wert 13 und `b` den Wert 5 hat?"
- kind: transfer
text: "Was müsstest du an den Deklarationen ändern, um ein Ergebnis mit Nachkommastellen zu erhalten?"
- id: modulo
title: "Rest einer Division"
objective: "Die Studierenden sollen den Aspekt \"Rest einer Division\" erklären können."
objective: "Die Bedeutung des Rests erklären und einen Einsatzzweck nennen."
questions:
- kind: concept
text: "Welche Bedeutung hat das Ergebnis von `a % b`?"
Expand Down
11 changes: 7 additions & 4 deletions examples/IT02/it02-02-vergleichsoperatoren.ino
Original file line number Diff line number Diff line change
Expand Up @@ -41,23 +41,26 @@ void loop() {
/* @unosim-tutor
schemaVersion: 2
learningObjectives:
- "Vergleichsoperatoren anwenden und ihr boolesches Ergebnis beobachten."
exclusive: true
- "Die Studierenden sollen Vergleichsoperatoren anwenden und ihr Ergebnis deuten können."
- "Sie sollen Zuweisung und Vergleich unterscheiden können."
afterFocus: free
focus:
- id: vergleichsergebnis
title: "Ergebnis eines Vergleichs"
objective: "Die Studierenden sollen den Aspekt \"Ergebnis eines Vergleichs\" erklären können."
objective: "Das Ergebnis mehrerer Vergleiche bestimmen und die Darstellung als 1 oder 0 erklären."
questions:
- kind: prediction
text: "Welche der Vergleiche `a == b`, `a != b`, `a < b` und `a >= b` sind mit den aktuellen Werten wahr?"
- kind: recall
text: "Wie werden ein wahres und ein falsches Ergebnis in der Ausgabe dargestellt?"
- id: zuweisung-oder-vergleich
title: "Zuweisung oder Vergleich"
objective: "Die Studierenden sollen den Aspekt \"Zuweisung oder Vergleich\" erklären können."
objective: "Den Unterschied zwischen `=` und `==` erklären und den Ergebnistyp eines Vergleichs nennen."
questions:
- kind: concept
text: "Was ist der Unterschied zwischen `=` und `==`?"
- kind: concept
text: "Welchen Datentyp hat das Ergebnis eines Vergleichs?"
- kind: prediction
text: "Was würde sich ändern, wenn `b` den Wert 7 hätte?"
@end-unosim-tutor */
8 changes: 4 additions & 4 deletions examples/IT02/it02-03-boolesche-operatoren.ino
Original file line number Diff line number Diff line change
Expand Up @@ -39,20 +39,20 @@ void loop() {
/* @unosim-tutor
schemaVersion: 2
learningObjectives:
- "Die Operatoren &&, || und ! auf Wahrheitswerte anwenden."
exclusive: true
- "Die Studierenden sollen UND, ODER und NICHT auf Wahrheitswerte anwenden können."
afterFocus: free
focus:
- id: verknuepfungen
title: "UND und ODER"
objective: "Die Studierenden sollen den Aspekt \"UND und ODER\" erklären können."
objective: "Die Ergebnisse von UND und ODER bei gegebenen Wahrheitswerten bestimmen und begründen."
questions:
- kind: concept
text: "Wann ergibt `schalter1 && schalter2` den Wert `true`?"
- kind: prediction
text: "Welche Ausgabe erwartest du für `schalter1 || schalter2` mit den aktuellen Werten?"
- id: negation
title: "Negation"
objective: "Die Studierenden sollen den Aspekt \"Negation\" erklären können."
objective: "Die Wirkung von `!` erklären und eine eigene Verknüpfung formulieren."
questions:
- kind: concept
text: "Welche Wirkung hat der Operator `!` auf `schalter1`?"
Expand Down
14 changes: 8 additions & 6 deletions examples/IT02/it02-04-bitoperatoren.ino
Original file line number Diff line number Diff line change
Expand Up @@ -40,23 +40,25 @@ void loop() {
/* @unosim-tutor
schemaVersion: 2
learningObjectives:
- "Eine Bitmaske mit dem bitweisen UND-Operator anwenden."
exclusive: true
- "Die Studierenden sollen eine Bitmaske mit dem bitweisen UND anwenden können."
afterFocus: free
focus:
- id: bitmaske
title: "Bitmaske"
objective: "Die Studierenden sollen den Aspekt \"Bitmaske\" erklären können."
objective: "Erklären, wie eine Maske einzelne Bits herausfiltert, und das Ergebnis vorhersagen."
questions:
- kind: concept
text: "Warum bleibt bei `wert & MASKE_BIT_2` nur ein gesetztes Bit erhalten?"
- kind: prediction
text: "Welches Ergebnis erwartest du für `wert & MASKE_BIT_2`, wenn Bit 2 in `wert` nicht gesetzt wäre?"
- id: bitweise-oder-logisch
title: "Bitweise oder logisch"
objective: "Die Studierenden sollen den Aspekt \"Bitweise oder logisch\" erklären können."
- id: darstellung-und-abgrenzung
title: "Darstellung und Abgrenzung"
objective: "Die Binärausgabe deuten und bitweise von logischen Operatoren unterscheiden."
questions:
- kind: concept
text: "Welche Rolle spielt `BIN` in `Serial.println(wert, BIN)`?"
- kind: concept
text: "Worin unterscheidet sich der bitweise Operator `&` vom logischen UND mit zwei Und-Zeichen?"
- kind: transfer
text: "Wie würdest du prüfen, ob Bit 3 in `wert` gesetzt ist?"
@end-unosim-tutor */
8 changes: 4 additions & 4 deletions examples/IT03/it03-01-serielle-ausgabe.ino
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,20 @@ void loop() {
/* @unosim-tutor
schemaVersion: 2
learningObjectives:
- "Die serielle Verbindung starten und Text mit print() und println() ausgeben."
exclusive: true
- "Die Studierenden sollen die serielle Verbindung starten und Text ausgeben können."
afterFocus: free
focus:
- id: print-und-println
title: "print und println"
objective: "Die Studierenden sollen den Aspekt \"print und println\" erklären können."
objective: "Den Unterschied zwischen `print` und `println` erklären und die Zeilenzahl der Ausgabe bestimmen."
questions:
- kind: concept
text: "Was unterscheidet `Serial.print` von `Serial.println`?"
- kind: application
text: "Wie viele Zeilen erscheinen im Monitor, und woran erkennst du das im Code?"
- id: initialisierung
title: "Serielle Verbindung starten"
objective: "Die Studierenden sollen den Aspekt \"Serielle Verbindung starten\" erklären können."
objective: "Begründen, warum die Verbindung vor der ersten Ausgabe gestartet wird und warum der Text nur einmal erscheint."
questions:
- kind: concept
text: "Warum muss `Serial.begin` vor der ersten Ausgabe stehen?"
Expand Down
8 changes: 4 additions & 4 deletions examples/IT03/it03-02-serielles-zeichen-einlesen.ino
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,20 @@ void loop() {
/* @unosim-tutor
schemaVersion: 2
learningObjectives:
- "Mit Serial.available() und Serial.read() ein einzelnes Zeichen empfangen."
exclusive: true
- "Die Studierenden sollen ein einzelnes Zeichen seriell einlesen und ausgeben können."
afterFocus: free
focus:
- id: zeichen-empfangen
title: "Zeichen empfangen"
objective: "Die Studierenden sollen den Aspekt \"Zeichen empfangen\" erklären können."
objective: "Erklären, warum vor dem Lesen geprüft wird, ob ein Zeichen vorliegt, und was `loop` in der Zwischenzeit tut."
questions:
- kind: concept
text: "Warum wird `Serial.available` vor `Serial.read` geprüft?"
- kind: prediction
text: "Was geschieht in `loop`, solange kein Zeichen gesendet wurde?"
- id: datentyp-char
title: "Datentyp char"
objective: "Die Studierenden sollen den Aspekt \"Datentyp char\" erklären können."
objective: "Die Rolle von `char` erklären und die Folge eines anderen Datentyps vorhersagen."
questions:
- kind: concept
text: "Welche Rolle spielt der Datentyp `char` für die Variable `zeichen`?"
Expand Down
8 changes: 5 additions & 3 deletions examples/IT03/it03-03-digitaler-ausgang.ino
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,21 @@ schemaVersion: 2
learningObjectives:
- "Die Studierenden sollen erklären können, wie ein digitaler Ausgang im aktuellen Sketch gesetzt wird."
- "Sie sollen den Zusammenhang zwischen Ausgangszustand und beobachtbarer Wirkung beschreiben können."
exclusive: true
afterFocus: free
focus:
- id: pin-konfigurieren
title: "Pin konfigurieren"
objective: "Die Studierenden sollen den Aspekt \"Pin konfigurieren\" erklären können."
objective: "Erklären, wie ein Pin als Ausgang konfiguriert und auf einen Zustand gesetzt wird."
questions:
- kind: concept
text: "Welche Aufgabe hat `pinMode(PIN_LED, OUTPUT)`?"
- kind: concept
text: "Welche elektrische Bedeutung hat `HIGH` an diesem Pin?"
- kind: prediction
text: "Was würdest du im Simulator beobachten, wenn dort stattdessen der niedrige Pegel gesetzt würde?"
- id: programmstruktur
title: "Programmstruktur"
objective: "Die Studierenden sollen den Aspekt \"Programmstruktur\" erklären können."
objective: "Begründen, warum `setup` genügt, und eine Erweiterung entwerfen."
questions:
- kind: concept
text: "Warum reicht für dieses Beispiel die Funktion `setup` aus?"
Expand Down
10 changes: 6 additions & 4 deletions examples/IT03/it03-04-digitaler-eingang.ino
Original file line number Diff line number Diff line change
Expand Up @@ -35,23 +35,25 @@ void loop() {
/* @unosim-tutor
schemaVersion: 2
learningObjectives:
- "Einen Eingang mit internem Pullup-Widerstand konfigurieren und lesen."
exclusive: true
- "Die Studierenden sollen einen Eingang mit internem Pullup-Widerstand lesen können."
afterFocus: free
focus:
- id: eingang-lesen
title: "Eingang lesen"
objective: "Die Studierenden sollen den Aspekt \"Eingang lesen\" erklären können."
objective: "Die möglichen Werte von `digitalRead` nennen und den Zweck des Pullups erklären."
questions:
- kind: recall
text: "Welche Werte kann `digitalRead` liefern?"
- kind: concept
text: "Welchen Zweck hat `INPUT_PULLUP` für den Pin `PIN_TASTER`?"
- id: taster-logik
title: "Taster-Logik"
objective: "Die Studierenden sollen den Aspekt \"Taster-Logik\" erklären können."
objective: "Den ausgegebenen Wert bei gedrücktem Taster vorhersagen und die Rolle der Wartezeit erklären."
questions:
- kind: prediction
text: "Welcher Wert wird ausgegeben, solange der Taster gedrückt ist, und warum?"
- kind: concept
text: "Warum steht in `loop` der Aufruf `delay(500)`?"
- kind: transfer
text: "Wie würdest du eine Meldung nur dann ausgeben, wenn der Taster gedrückt ist?"
@end-unosim-tutor */
8 changes: 5 additions & 3 deletions examples/IT03/it03-05-millis.ino
Original file line number Diff line number Diff line change
Expand Up @@ -34,22 +34,24 @@ schemaVersion: 2
learningObjectives:
- "Die Studierenden sollen erklären können, warum millis() einen Zeitwert liefert."
- "Sie sollen den Zeitwert als Grundlage für einen wiederkehrenden Ablauf einordnen können."
exclusive: true
afterFocus: free
focus:
- id: zeitwert
title: "Der Zeitwert"
objective: "Die Studierenden sollen den Aspekt \"Der Zeitwert\" erklären können."
objective: "Die Einheit von `millis()` nennen und das Wachstum des Werts über die Schleifendurchläufe erklären."
questions:
- kind: concept
text: "In welcher Einheit liefert `millis()` die Zeit?"
- kind: prediction
text: "Wie verändert sich der ausgegebene Wert von einem Schleifendurchlauf zum nächsten?"
- id: datentyp
title: "Der Datentyp"
objective: "Die Studierenden sollen den Aspekt \"Der Datentyp\" erklären können."
objective: "Begründen, warum ein vorzeichenloser langer Ganzzahltyp für Zeitwerte passt, und das Verhalten über Durchläufe hinweg erklären."
questions:
- kind: concept
text: "Warum eignet sich `unsigned long` für `zeitSeitStart`?"
- kind: concept
text: "Wird der Zeitwert durch einen erneuten Durchlauf von `loop` zurückgesetzt?"
- kind: transfer
text: "Wie könntest du mit zwei `millis()`-Werten messen, wie lange etwas gedauert hat?"
@end-unosim-tutor */
8 changes: 4 additions & 4 deletions examples/IT04/it04-01-analoger-eingang.ino
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,20 @@ void loop() {
/* @unosim-tutor
schemaVersion: 2
learningObjectives:
- "Einen Messwert mit analogRead() erfassen."
exclusive: true
- "Die Studierenden sollen einen analogen Messwert einlesen und seinen Wertebereich erklären können."
afterFocus: free
focus:
- id: wertebereich
title: "Wertebereich"
objective: "Die Studierenden sollen den Aspekt \"Wertebereich\" erklären können."
objective: "Den Wertebereich von `analogRead` nennen und aus der Auflösung begründen."
questions:
- kind: recall
text: "Welchen Wertebereich liefert `analogRead` beim Arduino Uno?"
- kind: concept
text: "Warum sind für diesen Bereich 10 Bit erforderlich?"
- id: pin-und-messwert
title: "Pin und Messwert"
objective: "Die Studierenden sollen den Aspekt \"Pin und Messwert\" erklären können."
objective: "Einordnen, wie ein Analogeingang eingerichtet wird, und einen Messwert abschätzen."
questions:
- kind: concept
text: "Muss ein analoger Eingang wie `PIN_SENSOR` mit pinMode() eingerichtet werden?"
Expand Down
Loading
Loading