/** * Notenrechner - Berechnet Noten aus Punktzahlen * David & Karo - EIS Projekt */ // Notenmaßstab definieren const NOTENMASSTAB = { 'sehr gut': { min: 90, max: 100 }, 'gut': { min: 75, max: 89 }, 'befriedigend': { min: 60, max: 74 }, 'ausreichend': { min: 50, max: 59 }, 'nicht bestanden': { min: 0, max: 49 } }; /** * Berechnet die Note basierend auf der Punktzahl * @param {number} punkte - Erreichte Punktzahl * @param {number} maxPunkte - Maximale Punktzahl (default: 100) * @returns {object} - Enthält Note, Prozentage und Details */ function berechneNote(punkte, maxPunkte = 100) { // Eingabe validieren punkte = parseFloat(punkte); maxPunkte = parseFloat(maxPunkte); if (isNaN(punkte) || isNaN(maxPunkte)) { return { note: 'Fehler', prozent: 0, valid: false, nachricht: 'Bitte geben Sie Zahlen ein!' }; } if (maxPunkte <= 0) { return { note: 'Fehler', prozent: 0, valid: false, nachricht: 'Maximale Punktzahl muss größer als 0 sein!' }; } if (punkte < 0 || punkte > maxPunkte) { return { note: 'Fehler', prozent: 0, valid: false, nachricht: `Punkte müssen zwischen 0 und ${maxPunkte} liegen!` }; } // Prozentage berechnen const prozent = Math.round((punkte / maxPunkte) * 100); // Note basierend auf Prozentage bestimmen let note = 'nicht bestanden'; for (const [noteText, range] of Object.entries(NOTENMASSTAB)) { if (prozent >= range.min && prozent <= range.max) { note = noteText; break; } } return { note: note, prozent: prozent, punkte: punkte, maxPunkte: maxPunkte, valid: true, nachricht: `${punkte} von ${maxPunkte} Punkten (${prozent}%) = ${note}` }; } /** * Berechnet den Durchschnitt mehrerer Noten * @param {array} noten - Array von Objekten mit Note-Informationen * @returns {object} - Durchschnitt und Gesamtnote */ function berechneDurchschnitt(noten) { if (!noten || noten.length === 0) { return { valid: false, nachricht: 'Keine Noten zum Berechnen vorhanden!' }; } // Alle gültigen Prozentagen sammeln const prozente = noten .filter(n => n.valid) .map(n => n.prozent); if (prozente.length === 0) { return { valid: false, nachricht: 'Keine gültigen Noten zum Berechnen vorhanden!' }; } // Durchschnitt berechnen const durchschnittProzent = Math.round( prozente.reduce((sum, p) => sum + p, 0) / prozente.length ); // Note für Durchschnitt bestimmen let durchschnittNote = 'nicht bestanden'; for (const [noteText, range] of Object.entries(NOTENMASSTAB)) { if (durchschnittProzent >= range.min && durchschnittProzent <= range.max) { durchschnittNote = noteText; break; } } return { anzahl: noten.length, gueltig: prozente.length, durchschnittProzent: durchschnittProzent, durchschnittNote: durchschnittNote, valid: true, nachricht: `Durchschnitt: ${durchschnittProzent}% = ${durchschnittNote}` }; } /** * Live-Konvertierung von Note zu Punkten * @param {string} noteText - Die Note als Text * @param {number} maxPunkte - Maximale Punktzahl * @returns {object} - Min und Max Punkte für diese Note */ function noteZuPunkte(noteText, maxPunkte = 100) { const range = NOTENMASSTAB[noteText.toLowerCase()]; if (!range) { return { valid: false, nachricht: 'Unbekannte Note!' }; } const minPunkte = Math.round((range.min / 100) * maxPunkte); const maxPunkteNote = Math.round((range.max / 100) * maxPunkte); return { note: noteText, minPunkte: minPunkte, maxPunkte: maxPunkteNote, valid: true, nachricht: `Note "${noteText}": ${minPunkte}-${maxPunkteNote} Punkte von ${maxPunkte}` }; } // DOM-Manipulation und Event-Listener document.addEventListener('DOMContentLoaded', function() { const addBtn = document.getElementById('add-grade-btn'); const calculateBtn = document.getElementById('calculate-btn'); const resetBtn = document.getElementById('reset-btn'); const gradesContainer = document.getElementById('grades-container'); const resultDiv = document.getElementById('result'); const averageDiv = document.getElementById('average-result'); // Neue Note hinzufügen if (addBtn) { addBtn.addEventListener('click', function() { addGradeInput(); }); } // Berechnen-Button if (calculateBtn) { calculateBtn.addEventListener('click', function() { calculateAllGrades(); }); } // Zurücksetzen-Button if (resetBtn) { resetBtn.addEventListener('click', function() { resetCalculator(); }); } // Initiale Note hinzufügen if (gradesContainer) { addGradeInput(); } }); /** * Neue Note-Input-Zeile hinzufügen */ function addGradeInput() { const container = document.getElementById('grades-container'); if (!container) return; const gradeId = Date.now(); const gradeDiv = document.createElement('div'); gradeDiv.className = 'grade-input-group'; gradeDiv.id = `grade-${gradeId}`; gradeDiv.innerHTML = `
/
- 0%
`; container.appendChild(gradeDiv); // Live-Berechnung hinzufügen const pointsInput = gradeDiv.querySelector('.grade-points'); const maxInput = gradeDiv.querySelector('.grade-max'); const noteSpan = gradeDiv.querySelector('.grade-note'); const percentSpan = gradeDiv.querySelector('.grade-percent'); function updateGrade() { const points = parseFloat(pointsInput.value) || 0; const max = parseFloat(maxInput.value) || 100; if (max > 0 && points >= 0 && points <= max) { const result = berechneNote(points, max); if (result.valid) { noteSpan.textContent = result.note; percentSpan.textContent = result.prozent + '%'; noteSpan.style.color = getGradeColor(result.note); } } else { noteSpan.textContent = '-'; percentSpan.textContent = '0%'; } } pointsInput.addEventListener('input', updateGrade); maxInput.addEventListener('input', updateGrade); pointsInput.focus(); } /** * Note-Input-Zeile entfernen */ function removeGradeInput(gradeId) { const element = document.getElementById(`grade-${gradeId}`); if (element) { element.remove(); } } /** * Alle Noten berechnen */ function calculateAllGrades() { const container = document.getElementById('grades-container'); const resultDiv = document.getElementById('result'); const averageDiv = document.getElementById('average-result'); if (!container) return; const gradeInputs = container.querySelectorAll('.grade-input-group'); const noten = []; let hasErrors = false; // Alle Noten sammeln gradeInputs.forEach(input => { const points = parseFloat(input.querySelector('.grade-points').value); const max = parseFloat(input.querySelector('.grade-max').value); if (isNaN(points) || isNaN(max)) { hasErrors = true; return; } const result = berechneNote(points, max); if (result.valid) { noten.push(result); } else { hasErrors = true; } }); if (hasErrors || noten.length === 0) { resultDiv.innerHTML = `

⚠️ Bitte füllen Sie alle Felder korrekt aus!

`; return; } // Einzelnote-Ergebnisse anzeigen let resultHTML = '

📊 Einzelne Noten:

'; noten.forEach((note, index) => { const color = getGradeColor(note.note); resultHTML += `
#${index + 1} ${note.punkte} / ${note.maxPunkte} Punkte (${note.prozent}%) ${note.note}
`; }); resultHTML += '
'; resultDiv.innerHTML = resultHTML; // Durchschnitt berechnen if (noten.length > 1) { const average = berechneDurchschnitt(noten); if (average.valid) { const color = getGradeColor(average.durchschnittNote); let averageHTML = `

📈 Durchschnitt:

${average.durchschnittProzent}%
${average.durchschnittNote}

Von ${average.gueltig} Note(n) berechnet

`; averageDiv.innerHTML = averageHTML; // Console und Alert console.log(average.nachricht); console.log(`Details: ${average.gueltig} von ${average.anzahl} Noten`); } } else { averageDiv.innerHTML = ''; } } /** * Notenrechner zurücksetzen */ function resetCalculator() { const container = document.getElementById('grades-container'); const resultDiv = document.getElementById('result'); const averageDiv = document.getElementById('average-result'); container.innerHTML = ''; resultDiv.innerHTML = ''; averageDiv.innerHTML = ''; addGradeInput(); } /** * Farbe basierend auf Note auswählen */ function getGradeColor(note) { const colors = { 'sehr gut': '#ff1493', 'gut': '#ff69b4', 'befriedigend': '#ffa500', 'ausreichend': '#ff8c00', 'nicht bestanden': '#dc143c' }; return colors[note.toLowerCase()] || '#6b3a5f'; }