eis-website/js/notenrechner.js

372 lines
9.8 KiB
JavaScript

/**
* 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 = `
<div class="grade-input-wrapper">
<input
type="number"
class="grade-points"
placeholder="Punkte"
min="0"
step="0.5"
>
<span class="grade-separator">/</span>
<input
type="number"
class="grade-max"
placeholder="Max"
value="100"
min="1"
step="1"
>
<div class="grade-result">
<span class="grade-note">-</span>
<span class="grade-percent">0%</span>
</div>
<button class="grade-remove-btn" onclick="removeGradeInput('${gradeId}')">✕</button>
</div>
`;
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 = `<p class="error-message">⚠️ Bitte füllen Sie alle Felder korrekt aus!</p>`;
return;
}
// Einzelnote-Ergebnisse anzeigen
let resultHTML = '<div class="result-list"><h4>📊 Einzelne Noten:</h4>';
noten.forEach((note, index) => {
const color = getGradeColor(note.note);
resultHTML += `
<div class="result-item">
<span class="result-number">#${index + 1}</span>
<span class="result-details">${note.punkte} / ${note.maxPunkte} Punkte (${note.prozent}%)</span>
<span class="result-grade" style="color: ${color};">${note.note}</span>
</div>
`;
});
resultHTML += '</div>';
resultDiv.innerHTML = resultHTML;
// Durchschnitt berechnen
if (noten.length > 1) {
const average = berechneDurchschnitt(noten);
if (average.valid) {
const color = getGradeColor(average.durchschnittNote);
let averageHTML = `
<div class="average-box">
<h4>📈 Durchschnitt:</h4>
<div class="average-display">
<div class="average-percent">${average.durchschnittProzent}%</div>
<div class="average-note" style="color: ${color};">${average.durchschnittNote}</div>
</div>
<p class="average-details">Von ${average.gueltig} Note(n) berechnet</p>
</div>
`;
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';
}