Dziennik krok 4: walidacja i wyjątki

Projekt: dziennik ocen krok po kroku - JavaScript od podstaw: konsola (JavaScript)

Prawdziwe dane bywają zepsute: tu są ocena 7, wiersz bez oceny i ocena zapisana słowem. Poprzednia wersja policzyłaby z nich `NaN`. Teraz `parseLine` sprawdza wiersz i rzuca wyjątek z opisem, a pętla wczytująca łapie go, zapamiętuje numer wiersza i pomija go. Raport liczy się tylko z poprawnych ocen, więc wychodzi taki sam jak wcześniej, a nad nim widać listę pominiętych wierszy.

const DATA = `Ola;matematyka;5
Jan;matematyka;3
Ola;polski;4
Ala;fizyka;7
Ewa;matematyka;6
Jan;polski;2
Kuba;matematyka
Ewa;polski;5
Ola;matematyka;6
Ola;polski;cztery
Jan;matematyka;4`;
function parseLine(line) {
  const parts = line.split(';');
  if (parts.length !== 3) throw new Error('oczekiwano 3 pól');
  const [name, subject, gradeText] = parts.map(p => p.trim());
  if (name === '' || subject === '') throw new Error('puste imię lub przedmiot');
  const grade = Number(gradeText);
  if (!Number.isInteger(grade) || grade < 1 || grade > 6) {
    throw new Error(`ocena spoza skali 1-6: "${gradeText}"`);
  }
  return { name, subject, grade };
}

function groupBy(records, key) {
  const groups = {};
  for (const r of records) {
    if (!(r[key] in groups)) groups[r[key]] = [];
    groups[r[key]].push(r.grade);
  }
  return groups;
}

function average(grades) {
  return grades.reduce((a, b) => a + b, 0) / grades.length;
}

const records = [];
DATA.split('\n').forEach((line, i) => {
  try {
    records.push(parseLine(line));
  } catch (e) {
    console.log(`Pominięto wiersz ${i + 1}: ${e.message}`);
  }
});
const byName = groupBy(records, 'name');

console.log('Uczniowie:');
for (const [name, grades] of Object.entries(byName)) {
  console.log(`${name}: ${average(grades).toFixed(2)}`);
}
console.log('Przedmioty:');
for (const [subject, grades] of Object.entries(groupBy(records, 'subject'))) {
  console.log(`${subject}: ${average(grades).toFixed(2)} (ocen: ${grades.length})`);
}
const [bestName, bestGrades] = Object.entries(byName).reduce(
  (best, entry) => (average(entry[1]) > average(best[1]) ? entry : best),
);
console.log(`Najlepsza średnia: ${bestName} (${average(bestGrades).toFixed(2)})`);

Ładowanie interaktywnego edytora... Jeśli się nie pojawi, włącz JavaScript.

Wszystkie lekcje kursu JavaScript od podstaw: konsola·Zaloguj się, aby zapisać postęp na koncie.