Cómo calcular masa molar con un parser pequeño y sin usar eval
Una fórmula química parece una cadena sencilla, pero contiene símbolos, cantidades y paréntesis. Convertirla directamente con eval() sería incorrecto y peligroso; necesitamos una gramática mínima y una tabla de masas.
El problema y el alcance del ejemplo
La ficha de ElementalHub: Tabla periódica resume su función así: «Tabla periódica interactiva, calculadora de masa molar e isótopos sin conexión.» ElementalHub describe tabla periódica y calculadora de masa molar sin conexión. Este tutorial implementa un parser limitado y explícito como ejercicio de programación, no el motor científico de la aplicación.
Cómo reproducir la idea
Utiliza Python 3. Guarda el código como masa_molar.py y ejecútalo. La tabla contiene solo cuatro elementos de ejemplo.
import re
from decimal import Decimal
MASAS = {"H": Decimal("1.008"), "O": Decimal("15.999"),
"C": Decimal("12.011"), "Ca": Decimal("40.078")}
def masa_molar(formula):
tokens = re.findall(r'[A-Z][a-z]?|[1-9][0-9]*|[()]', formula)
if ''.join(tokens) != formula or not tokens:
raise ValueError('Fórmula inválida')
pos = 0
def grupo():
nonlocal pos
total = Decimal('0')
while pos < len(tokens) and tokens[pos] != ')':
token = tokens[pos]
pos += 1
if token == '(':
value = grupo()
if pos >= len(tokens) or tokens[pos] != ')':
raise ValueError('Paréntesis sin cerrar')
pos += 1
elif token in MASAS:
value = MASAS[token]
else:
raise ValueError('Elemento u operador no admitido: ' + token)
factor = 1
if pos < len(tokens) and tokens[pos].isdigit():
factor = int(tokens[pos]); pos += 1
total += value * factor
return total
result = grupo()
if pos != len(tokens):
raise ValueError('Paréntesis no balanceados')
return result
for f in ['H2O', 'CO2', 'Ca(OH)2']:
print(f, masa_molar(f), 'g/mol')
Qué demuestra el código
El tokenizador distingue símbolos químicos de multiplicadores. La función recursiva procesa paréntesis y multiplica la contribución de cada grupo. El resultado usa Decimal, lo que ayuda a controlar la representación de las masas proporcionadas.
Pruebas recomendadas
Comprueba que H2O da aproximadamente 18.015 g/mol, CO2 cerca de 44.009 g/mol y Ca(OH)2 cerca de 74.092 g/mol. Prueba un símbolo desconocido o un paréntesis sin cerrar para ver la validación.
Límites que conviene reconocer
El parser no admite cargas, hidratos con punto, coeficientes de reacción ni todos los elementos. Las masas usadas son redondeos de ejemplo; distintos isótopos y convenciones pueden cambiar el cálculo. No debe tratarse como referencia de laboratorio validada.
Qué aprendemos
Las herramientas científicas necesitan tanto un parser de entrada verificable como un conjunto de datos con fuentes y unidades conocidas.
Contexto y enlaces del autor
El tema se relaciona con las funciones declaradas públicamente de ElementalHub: Tabla periódica, una aplicación Android de AppInitDev. El código anterior es un ejemplo independiente: no se ha inspeccionado el repositorio privado ni se afirma que sea la implementación interna de la app. La referencia aparece al final para ofrecer contexto, no como requisito para completar el tutorial.
- Google Play: ElementalHub: Tabla periódica
- Página de la aplicación: https://elementalhub.appinitdev.com/
- Sitio del desarrollador: AppInitDev

Top comments (0)