24. Proyecto integrador: conversor y validador de mediciones

El proyecto final reúne magnitudes, unidades, conversiones, incertidumbre, cifras significativas y validación en una herramienta JavaScript utilizable.

24.1 Objetivo del proyecto

Construiremos una aplicación que reciba una medición, compruebe su coherencia, la convierta a otra unidad compatible y genere un registro estructurado. No se trata solo de obtener un número: la herramienta debe explicar qué hizo y rechazar datos físicamente inválidos.

El resultado será una base extensible para incorporar nuevas magnitudes, unidades y reglas sin reescribir toda la interfaz.

24.2 Requisitos funcionales

  • Ingresar valor, incertidumbre, unidad y cifras significativas.
  • Elegir únicamente unidades compatibles con la magnitud.
  • Convertir valores mediante una referencia interna.
  • Propagar la incertidumbre a través de la conversión.
  • Validar números, dominios físicos y coherencia del resultado.
  • Mostrar un reporte legible y un objeto JSON reutilizable.

24.3 Requisitos de calidad

  • Interfaz accesible mediante etiquetas y mensajes claros.
  • Lógica independiente de la presentación.
  • Datos originales preservados sin redondeos prematuros.
  • Errores visibles, sin reemplazos silenciosos por cero.
  • Diseño adaptable a pantallas pequeñas.
  • Pruebas para ejemplos, límites y propiedades generales.

24.4 Diseño por capas

Catálogo

Define magnitudes, símbolos y transformaciones.

Dominio

Valida y convierte cantidades.

Presentación

Lee controles y muestra resultados.

Pruebas

Comprueba reglas y casos límite.

Esta separación evita que un cambio de estilo altere una equivalencia física y permite probar las funciones sin cargar el documento HTML.

24.5 Contrato de una medición

{
  "value": 12.5,
  "uncertainty": 0.1,
  "unit": "ft",
  "quantity": "length",
  "significantDigits": 3
}

La incertidumbre se interpreta aquí como estándar y no negativa. En una aplicación real convendría añadir fecha, instrumento, método, identificador y condiciones.

24.6 Catálogo de unidades

function linear(quantity, symbol, scale) {
  return { quantity, symbol, scale,
    toBase: value => value * scale,
    fromBase: value => value / scale };
}

function affine(quantity, symbol, scale, offset) {
  return { quantity, symbol, scale,
    toBase: value => value * scale + offset,
    fromBase: value => (value - offset) / scale };
}

const units = {
  m:  linear("length", "m", 1),
  cm: linear("length", "cm", 0.01),
  ft: linear("length", "ft", 0.3048),
  degC: affine("temperature", "°C", 1, 273.15)
};

console.log("Unidades registradas:", Object.keys(units).join(", "));
console.log("12,5 ft =", units.ft.toBase(12.5), "m");
console.log("20 °C =", units.degC.toBase(20), "K");

Las claves internas son estables; los símbolos pertenecen a la presentación. Las unidades lineales usan escala y las afines añaden un desplazamiento.

24.7 Conversión del valor

base = toBase(valor)   →   destino = fromBase(base)

Antes de transformar se verifica que origen y destino existan y compartan magnitud. Para temperatura absoluta también se comprueba que el equivalente en kelvin no sea negativo.

24.8 Conversión de la incertidumbre

En una transformación lineal y = ax, la incertidumbre se convierte como u(y) = |a|u(x). Para una transformación afín y = ax + b, el desplazamiento b no influye:

udestino = uorigen × |escalaorigen / escaladestino|

Esta regla convierte una incertidumbre ya estimada; no incorpora automáticamente resolución, calibración u otras fuentes omitidas.

24.9 Reglas de validación

  1. El valor debe ser un número finito.
  2. La incertidumbre debe ser finita y mayor o igual que cero.
  3. Las cifras significativas deben ser enteras dentro del intervalo admitido.
  4. Las unidades deben existir y ser compatibles.
  5. El valor debe pertenecer al dominio físico de la magnitud.
  6. El resultado convertido también debe ser finito.

24.10 Aplicación integradora

Probá distintas magnitudes y observá el reporte de validación. El redondeo afecta la presentación; el objeto JSON conserva los valores numéricos calculados.

Conversor y validador de mediciones

Convierte valor e incertidumbre, verifica el dominio y construye un registro.

Valor sin redondear
Incertidumbre convertida
Valor en referencia interna

Validación

    Registro generado

    Este prototipo trabaja en el navegador y no envía ni almacena los datos ingresados.

    24.11 Redondeo para presentación

    El proyecto usa cifras significativas para mostrar el resultado, pero conserva el número completo en el registro. En informes metrológicos suele redondearse primero la incertidumbre a una o dos cifras significativas y luego el valor a la misma posición decimal.

    La cantidad de dígitos elegida aquí permite experimentar; no sustituye una decisión basada en la incertidumbre y el propósito de la medición.

    24.12 Mensajes útiles

    “Error” informa muy poco. Un mensaje eficaz identifica el problema y su solución: “La incertidumbre debe ser mayor o igual que cero” o “La temperatura equivale a −2 K y está por debajo del cero absoluto”.

    La validación debe aparecer junto al resultado y actualizarse cuando cambia la entrada.

    24.13 Accesibilidad y uso con teclado

    Cada control posee una etiqueta asociada, los resultados dinámicos usan una región anunciable y el estado no se comunica únicamente mediante color. Los elementos nativos conservan navegación con teclado y comportamiento familiar.

    Una versión ampliada debería mover el foco al resumen de errores al enviar un formulario y relacionar cada mensaje con su campo mediante atributos ARIA.

    24.14 Pruebas unitarias esenciales

    const registry = {
      m: { quantity: "length", toBase: x => x, fromBase: x => x },
      ft: { quantity: "length", toBase: x => x * 0.3048, fromBase: x => x / 0.3048 },
      s: { quantity: "duration", toBase: x => x, fromBase: x => x },
      K: { quantity: "temperature", toBase: x => x, fromBase: x => x },
      degC: { quantity: "temperature", toBase: x => x + 273.15, fromBase: x => x - 273.15 },
      degF: { quantity: "temperature", toBase: x => (x - 32) * 5 / 9 + 273.15,
        fromBase: x => (x - 273.15) * 9 / 5 + 32 }
    };
    
    function convert(value, source, target) {
      const from = registry[source];
      const to = registry[target];
      if (!from || !to || from.quantity !== to.quantity) {
        throw new Error("Magnitudes incompatibles");
      }
      return to.fromBase(from.toBase(value));
    }
    
    function validateUncertainty(value) {
      if (!Number.isFinite(value) || value < 0) {
        throw new Error("Incertidumbre no válida");
      }
    }
    
    function assertClose(actual, expected, tolerance = 1e-12) {
      if (Math.abs(actual - expected) > tolerance) {
        throw new Error(`Esperado ${expected}; obtenido ${actual}`);
      }
    }
    
    function assertThrows(operation) {
      try { operation(); } catch { return; }
      throw new Error("Se esperaba una excepción");
    }
    
    assertClose(convert(1, "ft", "m"), 0.3048);
    assertClose(convert(0, "degC", "K"), 273.15);
    assertClose(convert(32, "degF", "degC"), 0);
    assertThrows(() => convert(1, "m", "s"));
    assertThrows(() => validateUncertainty(-0.1));
    console.log("Pruebas superadas: 5 de 5");
    console.log("Conversión verificada: 1 ft =", convert(1, "ft", "m"), "m");

    assertClose compara con tolerancia para contemplar la representación binaria de punto flotante.

    24.15 Pruebas de propiedades

    • Convertir una unidad a sí misma conserva valor e incertidumbre.
    • La ida y vuelta recupera el dato dentro de una tolerancia.
    • La composición por una tercera unidad coincide con la conversión directa.
    • Una conversión lineal nunca vuelve negativa una incertidumbre válida.
    • Magnitudes incompatibles siempre son rechazadas.

    24.16 Casos límite

    Probá cero, números negativos permitidos, temperaturas cercanas a 0 K, incertidumbre cero, valores muy grandes y pequeños, coma decimal, campos vacíos e infinito. También conviene ensayar la misma unidad como origen y destino.

    Un caso límite no es una rareza irrelevante: suele revelar supuestos que el código no hizo explícitos.

    24.17 Persistencia e intercambio

    El JSON generado puede enviarse a una API o almacenarse, pero requiere un esquema versionado. El receptor debe conocer la convención de unidades, el tipo de incertidumbre y la versión del catálogo.

    JSON utiliza punto decimal en números. Las comas localizadas pertenecen a la interfaz, no al formato de intercambio.

    24.18 Posibles ampliaciones

    • Historial local y exportación CSV o JSON.
    • Conversión de unidades compuestas mediante vectores dimensionales.
    • Propagación de incertidumbres en fórmulas.
    • Importación de certificados de calibración.
    • Soporte multilingüe y alias de unidades.
    • Pruebas automatizadas con un marco como Vitest.

    24.19 Criterios de evaluación

    Rúbrica sugerida para el proyecto.
    AspectoEvidencia esperada
    ModeloValor, unidad, magnitud e incertidumbre explícitos.
    ConversiónFactores y transformaciones correctos.
    ValidaciónRechazo de entradas y dominios inválidos.
    CalidadFunciones separadas, nombres claros y sin duplicación.
    PruebasCasos normales, límites y propiedades.
    InterfazResultados comprensibles, accesibles y adaptables.

    24.20 Desafíos finales

    1. Agregá volumen y comprobá que galón estadounidense e imperial tengan claves distintas.
    2. Permití ingresar una lista de mediciones y convertir media y desviación estándar.
    3. Implementá redondeo de valor e incertidumbre a la misma posición decimal.
    4. Exportá el registro con fecha, instrumento y versión del catálogo.
    5. Escribí una prueba que recorra automáticamente todas las unidades y compruebe ida y vuelta.

    24.21 Síntesis del curso

    A lo largo del curso distinguimos magnitudes, dimensiones, unidades y sistemas; utilizamos el SI, notación científica y análisis dimensional; estudiamos instrumentos, errores, incertidumbres, repeticiones, propagación, calibración y trazabilidad.

    El proyecto integra esas ideas en software: cada número conserva contexto, cada conversión valida dimensiones y cada resultado comunica su alcance. Medir bien y programar bien comparten una misma disciplina: hacer explícitos los supuestos.

    24.22 Ideas para recordar

    • Un conversor correcto comienza con un modelo de magnitudes, no con una colección de fórmulas aisladas.
    • Valor, unidad, incertidumbre y contexto forman una medición.
    • Validar antes de calcular evita resultados numéricos sin sentido físico.
    • La presentación se redondea; el dato interno conserva precisión.
    • Las pruebas y los mensajes de error son parte del resultado científico.

    Con este proyecto queda completado el curso de Magnitudes, Unidades y Sistemas de Medición.