Zum Inhalt springen
aviral gupta

// B3.5 · ca. 38 Min. · Einstieg

Projekt: ein Notenbericht

Nach diesem Projekt machen Sie aus einer Liste von Testpunkten einen Bericht: eine Note pro Ergebnis, den Durchschnitt, das beste und das schlechteste Ergebnis, ungültige Werte übersprungen.

Lektion 5 von 5 in B3 Kontrollfluss und Schleifen

Ende des Moduls

Danach können Sie

  • Eine Liste von Punkten in einer Schleife summieren und Durchschnitt, Bestwert und schlechtesten Wert ermitteln
  • Punkten mit einer else-if-Kette in der richtigen Reihenfolge eine Note zuordnen, oder einem festen Wert mit switch
  • Ungültige Punkte mit continue überspringen und den Bericht mit toFixed und Template-Literalen formatieren
  1. Aufwärmen · Aufgabe 1 von 7

    Zum Aufwärmen: Eine Schleife addiert jedes Ergebnis mit total += score zu total. Welchen Wert sollte total vor der Schleife haben?

  2. Vorhersagen · Aufgabe 2 von 7

    Sagen Sie es vorher, bevor Sie weiterlesen: Das Ergebnis ist 95. Was gibt dieser Code aus?

    const score = 95;
    let grade;
    if (score >= 60) {
      grade = "D";
    } else if (score >= 90) {
      grade = "A";
    } else {
      grade = "F";
    }
    console.log(grade);
  3. Üben · Aufgabe 3 von 7

    Ergänzen Sie den Operator, sodass best am Ende das höchste Ergebnis enthält, 95.

    const scores = [72, 95, 58];
    let best;
    for (const score of scores) {
      if (best === undefined || score ____ best) {
        best = score;
      }
    }
    console.log("best:", best);
    if (best === undefined || score best) {
  4. Üben · Aufgabe 4 von 7

    Sechs Ergebnisse ergeben zusammen 377. Was gibt dieser Code aus?

    const total = 377;
    const count = 6;
    console.log(`Average: ${(total / count).toFixed(1)}`);
  5. Üben · Aufgabe 5 von 7

    Diese Kette ordnet einem Ergebnis eine Note zu. Ordnen Sie jedem Ergebnis seine Note zu.

    let grade;
    if (score >= 90) {
      grade = "A";
    } else if (score >= 80) {
      grade = "B";
    } else if (score >= 70) {
      grade = "C";
    } else {
      grade = "F";
    }
  6. Denksport · Aufgabe 6 von 7

    Knobelaufgabe. Wie viele dieser Ergebnisse kommen durch die Prüfung? Was gibt dieser Code aus?

    const scores = [80, NaN, "90"];
    let used = 0;
    for (const score of scores) {
      if (typeof score !== "number" || score < 0 || score > 100) {
        continue;
      }
      used++;
    }
    console.log(used);
  7. Anwenden · Aufgabe 7 von 7

    Mini-Aufgabe. Schreiben Sie den ganzen Notenbericht selbst: die Ergebnisse in einem Array-Literal, mit einigen ungültigen Einträgen; eine Schleife, die die ungültigen mit continue überspringt und zählt, jedes gültige Ergebnis mit seiner Note ausgibt und total, count, best und worst aktualisiert; dann drei Zeilen mit den Anzahlen, dem Durchschnitt auf eine Nachkommastelle und dem besten und schlechtesten Ergebnis. Fügen Sie danach ein Ergebnis hinzu und sagen Sie die neue Ausgabe vorher.

    Prüfen Sie Ihr Ergebnis anhand dieser Liste

Selbst programmieren

Lesen Sie das ausgearbeitete Beispiel und lösen Sie dann die Übungen. Ihr Code läuft in Ihrem Browser oder auf Ihrem Computer und wird nie hochgeladen.

Ausgearbeitetes Beispiel

Der Notenbericht

Acht Ergebnisse eines Tests, von 100 Punkten, drei davon unbrauchbar: Ein Schüler fehlte, ein Ergebnis wurde als 101 eingetippt und eines als -4. Das Programm geht sie einmal durch. Es überspringt und meldet die ungültigen, gibt jedes gültige Ergebnis mit seiner Note auf der eigenen A-bis-F-Skala dieses Programms aus und führt eine laufende Summe, Anzahl, den Bestwert und den schlechtesten Wert. Die Zusammenfassung kommt nach der Schleife. Ändern Sie ein Ergebnis oder fügen Sie eines hinzu, und sagen Sie die Ausgabe vorher, bevor Sie es erneut ausführen.

main.js

// A grade report for one test. Scores are out of 100.
const scores = [72, 95, "absent", 58, 101, 88, -4, 64];

let total = 0;
let count = 0;
let skipped = 0;
let best;
let worst;

for (const score of scores) {
  if (typeof score !== "number" || score < 0 || score > 100) {
    console.log(`Skipped: ${score}`);
    skipped++;
    continue;
  }

  let grade;
  if (score >= 90) {
    grade = "A";
  } else if (score >= 80) {
    grade = "B";
  } else if (score >= 70) {
    grade = "C";
  } else if (score >= 60) {
    grade = "D";
  } else {
    grade = "F";
  }
  console.log(`${score} -> ${grade}`);

  total += score;
  count++;
  if (best === undefined || score > best) {
    best = score;
  }
  if (worst === undefined || score < worst) {
    worst = score;
  }
}

console.log(`Scores: ${count}, skipped: ${skipped}`);
console.log(`Average: ${(total / count).toFixed(1)}`);
console.log(`Best: ${best}, worst: ${worst}`);

Ausführen mit

node main.js

Ausgabe

72 -> C
95 -> A
Skipped: absent
58 -> F
Skipped: 101
88 -> B
Skipped: -4
64 -> D
Scores: 5, skipped: 3
Average: 75.4
Best: 95, worst: 58
  • Jeder ungültige Eintrag wird gemeldet und von continue übersprungen, er erreicht also nie die Note oder die Summe.
  • Die Kette prüft 90 zuerst, also ist 95 ein A, und 64 fällt bis zum D-Zweig durch.
  • best und worst beginnen mit undefined, also setzt das erste gültige Ergebnis, 72, beide.
  • Der Durchschnitt ist 377 / 5 = 75.4, einmal nach der Schleife berechnet und mit toFixed(1) formatiert.
Ändern und ausführen

Tab rückt ein, Umschalt+Tab rückt aus. Um den Editor mit der Tastatur zu verlassen, drücken Sie Esc und dann Tab.

Beim ersten Ausführen lädt Ihr Browser den JavaScript-Runner herunter (bis zu 0.1 MB) und speichert ihn im Cache. Ihr Code läuft in der eigenen Engine Ihres Browsers und bleibt auf Ihrem Gerät.

Übungen

Übung 1 von 3

Schritt 1: Summe, Durchschnitt, Bestwert und schlechtester Wert

Die Schleife zählt die Ergebnisse, tut aber sonst noch nichts. Addieren Sie in der Schleife jedes Ergebnis zu total und aktualisieren Sie best und worst, sodass das Programm Scores: 5, dann Average: 75.4, dann Best: 95, worst: 58 ausgibt. Lassen Sie die drei console.log-Zeilen, wie sie sind.

Tab rückt ein, Umschalt+Tab rückt aus. Um den Editor mit der Tastatur zu verlassen, drücken Sie Esc und dann Tab.

Beim ersten Ausführen lädt Ihr Browser den JavaScript-Runner herunter (bis zu 0.1 MB) und speichert ihn im Cache. Ihr Code läuft in der eigenen Engine Ihres Browsers und bleibt auf Ihrem Gerät.

Hinweise
  1. Hinweis 1

    total += score; addiert das Ergebnis dieses Durchlaufs zur laufenden Summe.

  2. Hinweis 2

    best beginnt mit undefined. if (best === undefined || score > best) { best = score; } speichert das erste Ergebnis und danach jedes höhere.

  3. Hinweis 3

    worst funktioniert genauso, mit < statt >.

Eine Lösung zeigen

Ein möglicher Lösungsweg. Ihrer kann anders aussehen und trotzdem alle Prüfungen bestehen.

const scores = [72, 95, 58, 88, 64];
let total = 0;
let count = 0;
let best;
let worst;

for (const score of scores) {
  count++;
  total += score;
  if (best === undefined || score > best) {
    best = score;
  }
  if (worst === undefined || score < worst) {
    worst = score;
  }
}

console.log(`Scores: ${count}`);
console.log(`Average: ${(total / count).toFixed(1)}`);
console.log(`Best: ${best}, worst: ${worst}`);
Auf dem eigenen Computer ausführen

Installieren Sie ECMAScript 2026 oder neuer. Speichern Sie diese Dateien in einem Ordner, öffnen Sie dort ein Terminal und führen Sie die Befehle unten aus.

main.js

const scores = [72, 95, 58, 88, 64];
let total = 0;
let count = 0;
let best;
let worst;

for (const score of scores) {
  count++;
  // Add the score to total, and update best and worst.
}

console.log(`Scores: ${count}`);
console.log(`Average: ${(total / count).toFixed(1)}`);
console.log(`Best: ${best}, worst: ${worst}`);

main.test.js

import {test} from 'node:test';
import assert from 'node:assert/strict';
import {runMain} from './learnrun.js';

const lines = async () => (await runMain()).trimEnd().split('\n');

test('zählt fünf Ergebnisse', async () => {
  const got = await lines();
  assert.equal(got[0], 'Scores: 5', `die erste Zeile ist ${JSON.stringify(got[0])}, erwartet "Scores: 5"`);
});

test('berechnet den Durchschnitt', async () => {
  const got = await lines();
  assert.equal(got[1], 'Average: 75.4', `die zweite Zeile ist ${JSON.stringify(got[1])}, erwartet "Average: 75.4"`);
});

test('findet das beste und das schlechteste Ergebnis', async () => {
  const got = await lines();
  assert.equal(got[2], 'Best: 95, worst: 58', `die dritte Zeile ist ${JSON.stringify(got[2])}, erwartet "Best: 95, worst: 58"`);
});

test('gibt genau drei Zeilen aus', async () => {
  const got = await lines();
  assert.equal(got.length, 3, `das Programm hat ${got.length} Zeile(n) ausgegeben, erwartet 3`);
});

package.json

{
  "type": "module"
}

package.json sagt Node.js, dass die .js-Dateien Module sind; lassen Sie die Datei im Ordner.

Programm ausführen:

node main.js

Prüfungen ausführen (learnrun.js muss im selben Ordner liegen):

node --test
learnrun.js herunterladen

Übung 2 von 3

Schritt 2: von Punkten zur Note

Jedes Ergebnis soll seine Note bekommen: A ab 90, B ab 80, C ab 70, D ab 60 und F unter 60. Die Kette steht in der falschen Reihenfolge, deshalb bekommt fast alles ein D. Ordnen Sie sie neu, sodass das Programm 72 -> C, 95 -> A, 58 -> F, 88 -> B, 60 -> D und 90 -> A ausgibt, eine Zeile pro Ergebnis.

Tab rückt ein, Umschalt+Tab rückt aus. Um den Editor mit der Tastatur zu verlassen, drücken Sie Esc und dann Tab.

Beim ersten Ausführen lädt Ihr Browser den JavaScript-Runner herunter (bis zu 0.1 MB) und speichert ihn im Cache. Ihr Code läuft in der eigenen Engine Ihres Browsers und bleibt auf Ihrem Gerät.

Hinweise
  1. Hinweis 1

    Die Kette führt den ersten Zweig aus, dessen Bedingung wahr ist. Welche Bedingung ist für 95 wahr und steht zuerst?

  2. Hinweis 2

    Prüfen Sie die höchste Grenze zuerst: score >= 90, dann >= 80, >= 70 und >= 60.

  3. Hinweis 3

    Behalten Sie das letzte else für F: Es läuft nur, wenn jede Prüfung darüber falsch ist.

Eine Lösung zeigen

Ein möglicher Lösungsweg. Ihrer kann anders aussehen und trotzdem alle Prüfungen bestehen.

const scores = [72, 95, 58, 88, 60, 90];

for (const score of scores) {
  let grade;
  if (score >= 90) {
    grade = "A";
  } else if (score >= 80) {
    grade = "B";
  } else if (score >= 70) {
    grade = "C";
  } else if (score >= 60) {
    grade = "D";
  } else {
    grade = "F";
  }
  console.log(`${score} -> ${grade}`);
}
Auf dem eigenen Computer ausführen

Installieren Sie ECMAScript 2026 oder neuer. Speichern Sie diese Dateien in einem Ordner, öffnen Sie dort ein Terminal und führen Sie die Befehle unten aus.

main.js

const scores = [72, 95, 58, 88, 60, 90];

for (const score of scores) {
  let grade;
  if (score >= 60) {
    grade = "D";
  } else if (score >= 70) {
    grade = "C";
  } else if (score >= 80) {
    grade = "B";
  } else if (score >= 90) {
    grade = "A";
  } else {
    grade = "F";
  }
  console.log(`${score} -> ${grade}`);
}

main.test.js

import {test} from 'node:test';
import assert from 'node:assert/strict';
import {runMain} from './learnrun.js';

const lines = async () => (await runMain()).trimEnd().split('\n');

test('gibt jedem Ergebnis seine Note', async () => {
  const got = await lines();
  assert.deepEqual(got.slice(0, 4), ['72 -> C', '95 -> A', '58 -> F', '88 -> B'], `die ersten vier Zeilen sind ${JSON.stringify(got.slice(0, 4))}`);
});

test('ein Ergebnis auf einer Grenze bekommt die höhere Note', async () => {
  const got = await lines();
  assert.deepEqual(got.slice(4), ['60 -> D', '90 -> A'], `die letzten Zeilen sind ${JSON.stringify(got.slice(4))}, erwartet ["60 -> D","90 -> A"]`);
});

package.json

{
  "type": "module"
}

package.json sagt Node.js, dass die .js-Dateien Module sind; lassen Sie die Datei im Ordner.

Programm ausführen:

node main.js

Prüfungen ausführen (learnrun.js muss im selben Ordner liegen):

node --test
learnrun.js herunterladen

Übung 3 von 3

Schritt 3: ungültige Ergebnisse überspringen

Jetzt enthält die Liste ungültige Einträge: "absent", 101 und -4, und der Bericht geht kaputt: Der Durchschnitt ist NaN, und 101 ist der Bestwert. Überspringen Sie am Anfang der Schleife jeden Eintrag, der keine Zahl von 0 bis 100 ist: Geben Sie Skipped: absent aus (mit dem Eintrag), erhöhen Sie skipped um 1 und rufen Sie continue auf. Der Bericht soll dann mit Scores: 5, skipped: 3, Average: 75.4 und Best: 95, worst: 58 enden.

Tab rückt ein, Umschalt+Tab rückt aus. Um den Editor mit der Tastatur zu verlassen, drücken Sie Esc und dann Tab.

Beim ersten Ausführen lädt Ihr Browser den JavaScript-Runner herunter (bis zu 0.1 MB) und speichert ihn im Cache. Ihr Code läuft in der eigenen Engine Ihres Browsers und bleibt auf Ihrem Gerät.

Hinweise
  1. Hinweis 1

    Ein Eintrag ist ungültig, wenn typeof score !== "number" || score < 0 || score > 100 gilt.

  2. Hinweis 2

    In diesem if: console.log(`Skipped: ${score}`); dann skipped++; dann continue;.

  3. Hinweis 3

    Das if steht als Erstes in der Schleife, damit nichts darunter, weder Note noch Summe, je einen ungültigen Eintrag sieht.

Eine Lösung zeigen

Ein möglicher Lösungsweg. Ihrer kann anders aussehen und trotzdem alle Prüfungen bestehen.

// A grade report for one test. Scores are out of 100.
const scores = [72, 95, "absent", 58, 101, 88, -4, 64];

let total = 0;
let count = 0;
let skipped = 0;
let best;
let worst;

for (const score of scores) {
  if (typeof score !== "number" || score < 0 || score > 100) {
    console.log(`Skipped: ${score}`);
    skipped++;
    continue;
  }

  let grade;
  if (score >= 90) {
    grade = "A";
  } else if (score >= 80) {
    grade = "B";
  } else if (score >= 70) {
    grade = "C";
  } else if (score >= 60) {
    grade = "D";
  } else {
    grade = "F";
  }
  console.log(`${score} -> ${grade}`);

  total += score;
  count++;
  if (best === undefined || score > best) {
    best = score;
  }
  if (worst === undefined || score < worst) {
    worst = score;
  }
}

console.log(`Scores: ${count}, skipped: ${skipped}`);
console.log(`Average: ${(total / count).toFixed(1)}`);
console.log(`Best: ${best}, worst: ${worst}`);
Auf dem eigenen Computer ausführen

Installieren Sie ECMAScript 2026 oder neuer. Speichern Sie diese Dateien in einem Ordner, öffnen Sie dort ein Terminal und führen Sie die Befehle unten aus.

main.js

const scores = [72, 95, "absent", 58, 101, 88, -4, 64];

let total = 0;
let count = 0;
let skipped = 0;
let best;
let worst;

for (const score of scores) {
  // Skip and count the invalid scores here.

  let grade;
  if (score >= 90) {
    grade = "A";
  } else if (score >= 80) {
    grade = "B";
  } else if (score >= 70) {
    grade = "C";
  } else if (score >= 60) {
    grade = "D";
  } else {
    grade = "F";
  }
  console.log(`${score} -> ${grade}`);

  total += score;
  count++;
  if (best === undefined || score > best) {
    best = score;
  }
  if (worst === undefined || score < worst) {
    worst = score;
  }
}

console.log(`Scores: ${count}, skipped: ${skipped}`);
console.log(`Average: ${(total / count).toFixed(1)}`);
console.log(`Best: ${best}, worst: ${worst}`);

main.test.js

import {test} from 'node:test';
import assert from 'node:assert/strict';
import {runMain} from './learnrun.js';

const lines = async () => (await runMain()).trimEnd().split('\n');

test('meldet jedes ungültige Ergebnis', async () => {
  const got = (await lines()).filter((line) => line.startsWith('Skipped'));
  assert.deepEqual(got, ['Skipped: absent', 'Skipped: 101', 'Skipped: -4'], `die Skipped-Zeilen sind ${JSON.stringify(got)}`);
});

test('benotet nur die gültigen Ergebnisse', async () => {
  const got = (await lines()).filter((line) => line.includes(' -> '));
  assert.deepEqual(got, ['72 -> C', '95 -> A', '58 -> F', '88 -> B', '64 -> D'], `die Notenzeilen sind ${JSON.stringify(got)}`);
});

test('endet mit der Zusammenfassung', async () => {
  const got = (await lines()).slice(-3);
  assert.deepEqual(got, ['Scores: 5, skipped: 3', 'Average: 75.4', 'Best: 95, worst: 58'], `die letzten drei Zeilen sind ${JSON.stringify(got)}`);
});

package.json

{
  "type": "module"
}

package.json sagt Node.js, dass die .js-Dateien Module sind; lassen Sie die Datei im Ordner.

Programm ausführen:

node main.js

Prüfungen ausführen (learnrun.js muss im selben Ordner liegen):

node --test
learnrun.js herunterladen

Häufige Fehler

Einen Bestwert formatieren, der nie gesetzt wurde

const scores = ["absent", "ill"];
let best;
for (const score of scores) {
  if (typeof score !== "number") {
    continue;
  }
  if (best === undefined || score > best) {
    best = score;
  }
}
console.log(`Best: ${best.toFixed(1)}`);

Was Node.js ausgibt

TypeError: Cannot read properties of undefined (reading 'toFixed')

Warum, und die Lösung

Jeder Eintrag wurde übersprungen, also ist best noch undefined, und undefined hat kein toFixed. Dieselbe Liste würde den Durchschnitt zu 0 / 0 machen, also NaN. Prüfen Sie vor der Zusammenfassung, ob etwas gezählt wurde: if (count === 0) { console.log("No valid scores"); } else { … die Zusammenfassung … }.

Eine laufende Summe, mit const deklariert

const scores = [72, 95, 58];
const total = 0;
for (const score of scores) {
  total += score;
}
console.log(total);

Was Node.js ausgibt

TypeError: Assignment to constant variable.

Warum, und die Lösung

total += score gibt total in jedem Durchlauf einen neuen Wert, und eine const kann keinen neuen Wert bekommen. Deklarieren Sie laufende Werte mit let: let total = 0;. const passt für die Liste selbst und für das Ergebnis jedes Durchlaufs, das jedes Mal eine neue Variable ist.

Die Note in den Zweigen deklariert

const score = 72;
if (score >= 70) {
  let grade = "C";
} else {
  let grade = "F";
}
console.log(score, grade);

Was Node.js ausgibt

ReferenceError: grade is not defined

Warum, und die Lösung

Ein let existiert nur innerhalb der geschweiften Klammern, in denen es deklariert ist. Jedes grade verschwindet also, wenn sein Block endet, und die console.log-Zeile findet kein grade. Deklarieren Sie es einmal vor der Kette, let grade;, und weisen Sie es in den Zweigen nur zu: grade = "C";.

JavaScript im Browser: die eigene Engine Ihres Browsers in einem abgeschotteten Worker. Syntaxfehler findet acorn 8.18.0, MIT. Lizenz und Quellcode

Abschlussquiz

5 Fragen, ohne Hinweise. Ab 80 % ist die Lektion abgeschlossen.

Erledigen Sie zuerst alle Aufgaben oben, um das Abschlussquiz freizuschalten.

Problem melden

Etwas ist falsch oder unklar? Beschreiben Sie es kurz, dann wird es geprüft und korrigiert.

#

Mindestens 20 Zeichen.

Nur, wenn Sie eine Antwort wünschen.

Kernideen

Eine Schleife, laufende Summen

Legen Sie vor der Schleife an, was Sie sammeln: let total = 0; let count = 0; und let best; let worst; noch ohne Wert. Jeder Durchlauf addiert die Punkte zu total und 1 zu count. Für den Bestwert nimmt if (best === undefined || score > best) { best = score; } das erste Ergebnis und danach jedes höhere; worst funktioniert genauso mit <. Beginnen Sie worst nicht mit 0: Kein Ergebnis liegt unter 0, also bliebe es 0. Der Durchschnitt kommt nach der Schleife: total / count. Wurde nichts gezählt, ist das 0 / 0, also NaN; prüfen Sie count deshalb zuerst.

Von Punkten zur Note: die Reihenfolge der Prüfungen

Eine if...else-if-Kette führt nur den ersten Zweig aus, dessen Bedingung wahr ist, und überspringt den Rest. Prüfen Sie also die höchste Grenze zuerst: if (score >= 90) ergibt "A", else if (score >= 80) ergibt "B" und so weiter bis zu einem letzten else für "F". In umgekehrter Reihenfolge kommt score >= 60 zuerst, und 95 Punkte bekommen ein "D". Nehmen Sie >=, damit 90 selbst ein A ist. Ein switch kann keinen Bereich enthalten, case >= 90: ist ein SyntaxError, passt aber zu festen Werten, etwa um den Buchstaben "B" in das Wort "passed" zu verwandeln.

Fehlerhafte Punkte überspringen, am Ende formatieren

Echte Listen enthalten unbrauchbare Einträge: "absent", 101, -4. Prüfen Sie sie als Erstes in der Schleife, if (typeof score !== "number" || score < 0 || score > 100), zählen oder melden Sie sie und rufen Sie continue auf, sodass der Rest des Blocks nur gültige Punkte sieht. Eine Lücke: NaN hat den Typ "number", und jeder Vergleich damit ist false, also kommt es durch diese Prüfung; Number.isNaN(score) fängt es ab. Formatieren Sie zuletzt: (total / count).toFixed(1) rundet auf eine Nachkommastelle und liefert einen String, und ein Template-Literal wie `${score} -> ${grade}` baut jede Zeile.

Quellen

Zuletzt geprüft am 3. Oktober 2026