Calculadora de Notas

¡Tus Resultados!

Nota Previa: --

Nota Necesaria en Examen Final: --

Info Importante

¿Cómo se calcula tu Nota Previa?

Se saca el promedio de tus notas del primer y segundo parcial. ¡Ojo! Si el resultado te da con .5 (por ejemplo, 12.5), se redondea para arriba (quedaría en 13).

¿Cómo usas la Tabla de Notas?

Las "Notas Previas" están arriba (horizontal). Las "Notas del Examen Final" están a la izquierda (vertical). Donde se cruzan, ¡esa es tu "Nota Definitiva"!

Reglas para Aprobar:

body { font-family: 'Arial', sans-serif; background-color: #003366; /* Azul oscuro de fondo */ color: #f0f0f0; /* Texto claro */ display: flex; justify-content: center; align-items: center; min-height: 100vh; margin: 0; padding: 20px; box-sizing: border-box; } .container { background-color: #004080; /* Un azul un poco más claro para el contenedor principal */ padding: 30px; border-radius: 12px; /* Bordes un poco más suaves */ box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3); /* Sombra más pronunciada */ width: 100%; max-width: 650px; /* Un poco más ancho */ text-align: center; border: 1px solid #0056b3; /* Borde sutil */ } h1 { color: #FFC107; /* Naranja/amarillo vibrante para títulos */ margin-bottom: 30px; font-size: 2.2em; text-shadow: 1px 1px 2px rgba(0,0,0,0.2); } h2 { color: #ADD8E6; /* Azul claro para subtítulos */ margin-bottom: 20px; font-size: 1.6em; } .input-section, .results-section, .explanation-section { margin-bottom: 25px; padding: 20px; border: 1px solid #0056b3; /* Borde con azul más claro */ border-radius: 10px; background-color: #004a99; /* Fondo de sección ligeramente diferente */ box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.15); /* Sombra interna sutil */ } .input-section label { display: block; margin-bottom: 10px; font-weight: bold; text-align: left; color: #e0e0e0; /* Texto de etiqueta más claro */ font-size: 1.1em; } .input-section input[type="number"] { width: calc(100% - 22px); /* Ajuste para padding */ padding: 12px; margin-bottom: 18px; border: 1px solid #0066cc; /* Borde del input */ border-radius: 6px; font-size: 1.1em; background-color: #0056b3; /* Fondo de input */ color: #ffffff; /* Color de texto del input */ box-shadow: inset 0 1px 3px rgba(0,0,0,0.2); } /* Placeholder color */ .input-section input[type="number"]::placeholder { color: #a0a0a0; } .input-section button { background-color: #FFC107; /* Naranja/amarillo vibrante para el botón */ color: #003366; /* Texto oscuro para el botón */ padding: 14px 30px; border: none; border-radius: 8px; cursor: pointer; font-size: 1.2em; font-weight: bold; transition: background-color 0.3s ease, transform 0.2s ease; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2); } .input-section button:hover { background-color: #FFD700; /* Un poco más claro al pasar el ratón */ transform: translateY(-2px); } .results-section p { font-size: 1.2em; margin: 12px 0; color: #ffffff; /* Blanco para resultados */ } .results-section strong { color: #ADD8E6; /* Azul claro para las etiquetas */ } .results-section span { font-weight: bold; color: #FFD700; /* Naranja/amarillo para los valores de resultados */ font-size: 1.3em; } .explanation-section h2 { color: #ADD8E6; margin-bottom: 15px; } .explanation-section p, .explanation-section ul { text-align: left; margin-bottom: 10px; line-height: 1.8; color: #e0e0e0; } .explanation-section ul { list-style-type: disc; padding-left: 25px; } .explanation-section ul li { margin-bottom: 8px; } document.addEventListener('DOMContentLoaded', () => { const primerParcialInput = document.getElementById('primerParcial'); const segundoParcialInput = document.getElementById('segundoParcial'); const calcularBtn = document.getElementById('calcularBtn'); const notaPreviaResult = document.getElementById('notaPreviaResult'); const notaFinalNeededResult = document.getElementById('notaFinalNeededResult'); // Reconstrucción de la "TABLA DE NOTAS" // Los índices del array se ajustan: Nota Previa 10 será index 0, Nota Examen Final 01 será index 0. // E.g., table[notaExamenFinal-1][notaPrevia-10] const gradeTable = [ // NOTA PREVIA: 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 /* EF 01 */ [10, 10, 10, 10, 10, 10, 10, 11, 11, 15, 16], /* EF 02 */ [10, 10, 10, 10, 10, 10, 11, 11, 12, 15, 16], /* EF 03 */ [10, 10, 10, 10, 10, 11, 11, 12, 12, 15, 16], /* EF 04 */ [10, 10, 10, 10, 11, 11, 11, 12, 12, 15, 16], /* EF 05 */ [10, 10, 10, 11, 11, 11, 12, 12, 13, 16, 16], /* EF 06 */ [10, 10, 11, 11, 11, 12, 12, 13, 13, 16, 17], /* EF 07 */ [10, 11, 11, 11, 12, 12, 13, 13, 14, 16, 17], /* EF 08 */ [11, 11, 11, 12, 12, 13, 13, 14, 14, 16, 17], /* EF 09 */ [11, 11, 12, 12, 13, 13, 14, 14, 15, 17, 17], /* EF 10 */ [11, 12, 12, 13, 13, 14, 14, 15, 15, 17, 18], /* EF 11 */ [11, 12, 12, 13, 13, 14, 14, 15, 15, 17, 18], /* EF 12 */ [12, 12, 12, 13, 14, 14, 15, 15, 16, 17, 18], /* EF 13 */ [12, 12, 13, 13, 14, 14, 15, 16, 16, 18, 19], /* EF 14 */ [12, 13, 13, 14, 14, 15, 15, 16, 16, 18, 19], /* EF 15 */ [13, 13, 13, 14, 15, 15, 16, 16, 17, 18, 19], /* EF 16 */ [13, 13, 14, 14, 15, 16, 16, 17, 17, 19, 19], /* EF 17 */ [14, 14, 14, 15, 15, 16, 16, 17, 17, 19, 20], /* EF 18 */ [15, 15, 15, 16, 16, 16, 17, 17, 18, 19, 20], /* EF 19 */ [15, 16, 16, 16, 17, 17, 17, 18, 18, 19, 20], /* EF 20 */ [16, 16, 17, 17, 17, 18, 18, 18, 19, 20, 20] ]; function calculateNotaPrevia(partial1, partial2) { const average = (partial1 + partial2) / 2; // Math.round en JavaScript redondea .5 hacia arriba al entero más cercano. // Ej: 2.5 -> 3, 3.5 -> 4. Esto coincide con el comportamiento de redondeo de las imágenes. return Math.round(average); } function getNotaDefinitiva(notaPrevia, notaExamenFinal) { // Asegurarse de que las notas estén dentro de los rangos válidos de la tabla if (notaPrevia < 10 || notaPrevia > 20 || notaExamenFinal < 1 || notaExamenFinal > 20) { return null; // Fuera de los límites de la tabla } // Ajustar índices para la búsqueda en arrays (base 0) const colIndex = notaPrevia - 10; // Nota Previa 10 está en el índice 0 const rowIndex = notaExamenFinal - 1; // Nota Examen Final 1 está en el índice 0 if (gradeTable[rowIndex] && gradeTable[rowIndex][colIndex] !== undefined) { return gradeTable[rowIndex][colIndex]; } return null; // No encontrado en la tabla (debería ser raro si los rangos son correctos) } function calculateNotaFinalNeeded() { const partial1 = parseFloat(primerParcialInput.value); const partial2 = parseFloat(segundoParcialInput.value); // Validación de entrada if (isNaN(partial1) || isNaN(partial2) || partial1 < 0 || partial1 > 20 || partial2 < 0 || partial2 > 20) { alert('¡Ups! Por favor, ingresa notas válidas entre 0 y 20 para ambos parciales.'); notaPreviaResult.textContent = '--'; notaFinalNeededResult.textContent = '--'; return; } const notaPrevia = calculateNotaPrevia(partial1, partial2); notaPreviaResult.textContent = notaPrevia; // Verificar aprobación automática if (notaPrevia >= 16) { notaFinalNeededResult.textContent = '¡Materia APROBADA! ¡Ya la pasaste! 🎉'; return; } // Buscar la nota mínima necesaria en el examen final let minNotaFinal = -1; for (let ef = 1; ef <= 20; ef++) { const notaDefinitiva = getNotaDefinitiva(notaPrevia, ef); if (notaDefinitiva !== null && notaDefinitiva >= 10) { minNotaFinal = ef; break; // Encontró la primera nota de examen final que permite aprobar } } if (minNotaFinal !== -1) { notaFinalNeededResult.textContent = `¡Necesitas un ${minNotaFinal} para aprobar!`; } else { // Si llega aquí y no encontró, significa que ni con 20 en el final se aprueba const highestPossibleDefinitive = getNotaDefinitiva(notaPrevia, 20); if (highestPossibleDefinitive !== null && highestPossibleDefinitive < 10) { notaFinalNeededResult.textContent = '¡Uhm, está difícil! Parece imposible aprobar con esta nota previa, aunque saques 20 en el final.'; } else { // Mensaje genérico de error si algo inesperado sucede notaFinalNeededResult.textContent = 'No se pudo determinar (verifica la tabla o los rangos de notas).'; } } } calcularBtn.addEventListener('click', calculateNotaFinalNeeded); // Permitir calcular con la tecla 'Enter' para una mejor experiencia de usuario primerParcialInput.addEventListener('keypress', (e) => { if (e.key === 'Enter') { segundoParcialInput.focus(); } }); segundoParcialInput.addEventListener('keypress', (e) => { if (e.key === 'Enter') { calcularBtn.click(); } }); });