Mundo em Python

Calculadora de Massa Molar

from tkinter import *
import re
from collections import defaultdict
nomes_elementos = {
'H': 'Hidrogénio', 'He': 'Hélio',
'Li': 'Lítio', 'Be': 'Berílio', 'B': 'Boro', 'C': 'Carbono', 'N': 'Azoto',
'O': 'Oxigénio', 'F': 'Flúor', 'Ne': 'Neão',
'Na': 'Sódio', 'Mg': 'Magnésio', 'Al': 'Alumínio', 'Si': 'Silício', 'P': 'Fósforo',
'S': 'Enxofre', 'Cl': 'Cloro', 'Ar': 'Árgon',
'K': 'Potássio', 'Ca': 'Cálcio', 'Sc': 'Escândio', 'Ti': 'Titânio', 'V': 'Vanádio',
'Cr': 'Crómio', 'Mn': 'Manganês', 'Fe': 'Ferro', 'Co': 'Cobalto', 'Ni': 'Níquel',
'Cu': 'Cobre', 'Zn': 'Zinco', 'Ga': 'Gálio', 'Ge': 'Germânio', 'As': 'Arsénio',
'Se': 'Selénio', 'Br': 'Bromo', 'Kr': 'Crípton',
'Rb': 'Rubídio', 'Sr': 'Estrôncio', 'Y': 'Ítrio', 'Zr': 'Zircónio',
'Nb': 'Nióbio', 'Mo': 'Molibdénio', 'Tc': 'Tecnécio', 'Ru': 'Ruténio',
'Rh': 'Ródio', 'Pd': 'Paládio', 'Ag': 'Prata', 'Cd': 'Cádmio', 'In': 'Índio',
'Sn': 'Estanho', 'Sb': 'Antimónio', 'Te': 'Telúrio', 'I': 'Iodo', 'Xe': 'Xénon',
'Cs': 'Césio', 'Ba': 'Bário', 'La': 'Lantânio', 'Ce': 'Cério', 'Pr': 'Praseodímio',
'Nd': 'Neodímio', 'Pm': 'Promécio', 'Sm': 'Samário', 'Eu': 'Európio', 'Gd': 'Gadolínio',
'Tb': 'Térbio', 'Dy': 'Disprósio', 'Ho': 'Hólmio', 'Er': 'Érbio', 'Tm': 'Túlio',
'Yb': 'Itérbio', 'Lu': 'Lutécio', 'Hf': 'Háfnio', 'Ta': 'Tântalo', 'W': 'Tungsténio',
'Re': 'Rénio', 'Os': 'Ósmio', 'Ir': 'Irídio', 'Pt': 'Platina', 'Au': 'Ouro',
'Hg': 'Mercúrio', 'Tl': 'Tálio', 'Pb': 'Chumbo', 'Bi': 'Bismuto', 'Po': 'Polónio',
'At': 'Ástato', 'Rn': 'Radão', 'Fr': 'Frâncio', 'Ra': 'Rádio', 'Ac': 'Actínio',
'Th': 'Tório', 'Pa': 'Protactínio', 'U': 'Urânio', 'Np': 'Neptúnio', 'Pu': 'Plutónio',
'Am': 'Amerício', 'Cm': 'Cúrio', 'Bk': 'Berquélio', 'Cf': 'Califórnio', 'Es': 'Einsténio',
'Fm': 'Férmio', 'Md': 'Mendelévio', 'No': 'Nobélio', 'Lr': 'Laurêncio', 'Rf': 'Rutherfórdio',
'Db': 'Dúbnio', 'Sg': 'Seabórgio', 'Bh': 'Bóhrio', 'Hs': 'Hássio', 'Mt': 'Meitnério',
'Ds': 'Darmstádtio', 'Rg': 'Roentgénio', 'Cn': 'Copernício', 'Nh': 'Nihónio',
'Fl': 'Fleróvio', 'Mc': 'Moscóvio', 'Lv': 'Livermório', 'Ts': 'Tenessino', 'Og': 'Oganessónio'
} massas_molares = {
'H': 1.008, 'He': 4.0026,
'Li': 6.94, 'Be': 9.0122, 'B': 10.81, 'C': 12.011, 'N': 14.007,
'O': 15.999, 'F': 18.998, 'Ne': 20.180,
'Na': 22.990, 'Mg': 24.305, 'Al': 26.982, 'Si': 28.085, 'P': 30.974,
'S': 32.06, 'Cl': 35.45, 'Ar': 39.948,
'K': 39.098, 'Ca': 40.078, 'Sc': 44.956, 'Ti': 47.867, 'V': 50.942,
'Cr': 51.996, 'Mn': 54.938, 'Fe': 55.845, 'Co': 58.933, 'Ni': 58.693,
'Cu': 63.546, 'Zn': 65.38, 'Ga': 69.723, 'Ge': 72.63, 'As': 74.922,
'Se': 78.96, 'Br': 79.904, 'Kr': 83.798,
'Rb': 85.468, 'Sr': 87.62, 'Y': 88.906, 'Zr': 91.224,
'Nb': 92.906, 'Mo': 95.95, 'Tc': 98.0, 'Ru': 101.07,
'Rh': 102.91, 'Pd': 106.42, 'Ag': 107.87, 'Cd': 112.41, 'In': 114.82,
'Sn': 118.71, 'Sb': 121.76, 'Te': 127.60, 'I': 126.90, 'Xe': 131.29,
'Cs': 132.91, 'Ba': 137.33, 'La': 138.91, 'Ce': 140.12, 'Pr': 140.91,
'Nd': 144.24, 'Pm': 145.0, 'Sm': 150.36, 'Eu': 151.96, 'Gd': 157.25,
'Tb': 158.93, 'Dy': 162.50, 'Ho': 164.93, 'Er': 167.26, 'Tm': 168.93,
'Yb': 173.05, 'Lu': 174.97, 'Hf': 178.49, 'Ta': 180.95, 'W': 183.84,
'Re': 186.21, 'Os': 190.23, 'Ir': 192.22, 'Pt': 195.08, 'Au': 196.97,
'Hg': 200.59, 'Tl': 204.38, 'Pb': 207.2, 'Bi': 208.98, 'Po': 209.0,
'At': 210.0, 'Rn': 222.0, 'Fr': 223.0, 'Ra': 226.0, 'Ac': 227.0,
'Th': 232.04, 'Pa': 231.04, 'U': 238.03, 'Np': 237.0, 'Pu': 244.0,
'Am': 243.0, 'Cm': 247.0, 'Bk': 247.0, 'Cf': 251.0, 'Es': 252.0,
'Fm': 257.0, 'Md': 258.0, 'No': 259.0, 'Lr': 262.0
} def parse_formula(formula): tokens = re.findall(r'([A-Z][a-z]?|\d+|\(|\))', formula)
stack = [defaultdict(int)]
i = 0
while i < len(tokens):
token = tokens[i]
if token == '(':
stack.append(defaultdict(int))
elif token == ')':
top = stack.pop()
i += 1
multiplier = int(tokens[i]) if i < len(tokens) and tokens[i].isdigit() else 1
for element, count in top.items():
stack[-1][element] += count * multiplier
elif re.match(r'[A-Z][a-z]?', token):
element = token
i += 1
count = int(tokens[i]) if i < len(tokens) and tokens[i].isdigit() else 1
stack[-1][element] += count
if count != 1:
i += 1
continue
i += 1
return stack[0] def calcular_massa_molar(formula):
elementos = parse_formula(formula)
massa_total = 0.0
for elemento, quantidade in elementos.items():
# Verifica se o elemento está no dicionário de massas molares
if elemento not in massas_molares:
raise ValueError(f"Elemento desconhecido: {elemento}")
# Adiciona a massa do elemento multiplicada pela sua quantidade à massa total
massa_total += massas_molares[elemento] * quantidade
return massa_total root = Tk()
root.geometry("700x300")
root.resizable(0, 0)
root.config(bg="#103030")
root.title("Calculadora de Massa Molar") titulo = Label(text="Calculadora de Massa Molar",
font=("Arial", 28, "bold"), bg="#103030", fg="#49e3e3")
titulo.place(relx=0.13, rely=0.05)
texto_sub1 = Label(text="Fórmula química:",
font=("Arial", 18, "bold"), bg="#103030", fg="#49e3e3")
texto_sub1.place(relx=0.15, rely=0.3) texto_sub2 = Label(text="Entrada de fórmulas químicas válidas (ex: H2O, C6H12O6, Ca(OH)2)",
font=("Arial", 12, "bold"), bg="#103030", fg="#49e3e3")
texto_sub2.place(relx=0.15, rely=0.47) Fórmula_Química = StringVar()
Fórmula_Química_entrada = Entry(textvariable=Fórmula_Química,
font=("Arial", 12, "bold"),
bg="white", fg="blue", justify='center')
Fórmula_Química_entrada.place(relx=0.5, rely=0.31, relwidth=0.35) resultado_texto = Text(root, font=("Arial", 12, "bold"),
bg="#cfe2f3", fg="black", wrap="word")
resultado_texto.place(relx=0.05, rely=0.8, relwidth=0.9, relheight=0.15) scrollbar = Scrollbar(root, command=resultado_texto.yview)
scrollbar.place(relx=0.95, rely=0.8, relheight=0.15) resultado_texto.config(yscrollcommand=scrollbar.set) def app(): try:
formula = Fórmula_Química.get()
elementos = parse_formula(formula)
massa = calcular_massa_molar(formula)
detalhes = "\n".join(
f"{nomes_elementos.get(elem, 'Desconhecido')} ({elem}): {quantidade}"
for elem, quantidade in sorted(elementos.items())
) mensagem = f"Massa molar de {formula}: {massa:.3f} g/mol\n\nElementos:\n{detalhes}"
resultado_texto.config(state="normal")
resultado_texto.delete("1.0", END)
resultado_texto.insert(END, mensagem)
resultado_texto.config(state="disabled")
except ValueError as e:
resultado_texto.config(state="normal")
resultado_texto.delete("1.0", END)
resultado_texto.insert(END, str(e))
resultado_texto.config(state="disabled")
except Exception:
resultado_texto.config(state="normal")
resultado_texto.delete("1.0", END)
resultado_texto.insert(END, "Erro: fórmula inválida!")
resultado_texto.config(state="disabled") def limpar(): Fórmula_Química_entrada.delete(0, END)
resultado_texto.config(state="normal")
resultado_texto.delete("1.0", END)
resultado_texto.config(state="disabled") but1 = Button(text="Calcular", bd=2, bg='#107db2', fg='white',
font=('Verdana', 12, 'bold'), command=app)
but1.place(relx=0.1, rely=0.65, relwidth=0.25, relheight=0.1) but_limpar = Button(text="Limpar", bd=2, bg='#107db2', fg='white',
font=('Verdana', 12, 'bold'), command=limpar)
but_limpar.place(relx=0.4, rely=0.65, relwidth=0.25, relheight=0.1) but_sair = Button(text="Sair", bd=2, bg='#107db2', fg='white',
font=('Verdana', 12, 'bold'), command=root.destroy)
but_sair.place(relx=0.7, rely=0.65, relwidth=0.25, relheight=0.1) root.mainloop()
0