This commit is contained in:
2025-08-20 09:50:45 +08:00
parent 397084995e
commit 9c92a3a449

View File

@ -3,12 +3,10 @@ import streamlit as st
import pubchempy as pcp import pubchempy as pcp
import re import re
from typing import Optional, Dict, List, cast from typing import Optional, Dict, List, cast
from io import BytesIO
import base64
from PIL import Image
import requests import requests
import pandas as pd import pandas as pd
import numpy as np import numpy as np
import traceback
class PubChemCompound: class PubChemCompound:
def __init__(self, def __init__(self,
@ -294,11 +292,12 @@ def reaction_table_page():
st.session_state.reaction_table_refresh = 2 st.session_state.reaction_table_refresh = 2
st.rerun() st.rerun()
# print(st.session_state.reaction_data) def get_mass_safe(chemical_name: str) -> float:
# 仅当返回的是 DataFrame 时再回写;如果是变更字典则由回调处理 try:
# if isinstance(edited_data, pd.DataFrame): mass = molmass.Formula(chemical_name).mass
# print("Edited DataFrame:", edited_data) return mass
# st.session_state.reaction_data = edited_data except Exception as e:
return float("nan")
def calc_reaction_data(): def calc_reaction_data():
try: try:
@ -317,6 +316,9 @@ def calc_reaction_data():
st.error("质量、体积和密度不能同时存在或可求") st.error("质量、体积和密度不能同时存在或可求")
raise ValueError raise ValueError
fil = df["mw"].isna() & df["name"].notna()
df.loc[fil, "mw"] = df[fil]["name"].apply(get_mass_safe)
# mol -> mass # mol -> mass
fil = df["mw"].notna() & df["mol"].notna() fil = df["mw"].notna() & df["mol"].notna()
df.loc[fil, "mass"] = df[fil]["mol"] * df[f"{'mw'}"] / 1000.0 # mmol -> mol再乘以 g/mol df.loc[fil, "mass"] = df[fil]["mol"] * df[f"{'mw'}"] / 1000.0 # mmol -> mol再乘以 g/mol
@ -339,10 +341,10 @@ def calc_reaction_data():
eql = df[(df["eq"] > 0) & (df["mol"] > 0)] eql = df[(df["eq"] > 0) & (df["mol"] > 0)]
if not st.session_state.get("no_check",False): if not st.session_state.get("no_check",False):
if eql.size > 1: if eql.shape[0] > 1:
st.error("对于当量存在物质,只允许一个物质设置用量、质量或体积") st.error("对于当量存在物质,只允许一个物质设置用量、质量或体积")
raise ValueError raise ValueError
if eql.size == 0 and not df[(df["eq"] > 0)].empty: if eql.shape[0] == 0 and not df[(df["eq"] > 0)].empty:
st.error("设置了当量,但是均没有设置用量、质量或体积") st.error("设置了当量,但是均没有设置用量、质量或体积")
raise ValueError raise ValueError
if not eql.empty: if not eql.empty:
@ -370,9 +372,10 @@ def calc_reaction_data():
st.session_state.reaction_data = df st.session_state.reaction_data = df
except Exception as e: except Exception as e:
if "df" in locals():
st.session_state.reaction_data = df
st.error("计算过程中出错,表格可能有误") st.error("计算过程中出错,表格可能有误")
raise e print("calc_reaction_data error:", traceback.format_exc())
print("calc_reaction_data error:", e)
return return
def recalculate_reaction_data(): def recalculate_reaction_data():
@ -467,12 +470,7 @@ def recalculate_reaction_data():
brow = df.loc[basis_idx] brow = df.loc[basis_idx]
if "物质" in edited.keys() and pd.isna(brow["分子量"]) and "分子量" not in edited.keys(): if "物质" in edited.keys() and pd.isna(brow["分子量"]) and "分子量" not in edited.keys():
try: df.loc[basis_idx, "分子量"] = get_mass_safe(edited["物质"])
mass = molmass.Formula(edited["物质"]).mass
edited["分子量"] = mass
df.loc[basis_idx, "分子量"] = mass
except Exception as e:
pass
if "密度(g/mL)" in edited.keys(): if "密度(g/mL)" in edited.keys():
if _to_float(brow.get("体积(mL)")) is None and "质量(g)" in brow.keys(): if _to_float(brow.get("体积(mL)")) is None and "质量(g)" in brow.keys():