clidx commited on
Commit
055ede8
·
verified ·
1 Parent(s): 4721f11

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +263 -123
src/streamlit_app.py CHANGED
@@ -2,98 +2,208 @@ import streamlit as st
2
  import pandas as pd
3
  import math
4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  # 配置页面
6
  st.set_page_config(
7
- page_title="溶剂分数转换器",
8
  page_icon="🧪",
9
  layout="wide"
10
  )
11
 
12
  # 页面标题
13
- st.title("🧪 溶剂摩尔分数与体积分数转换器")
14
  st.markdown("---")
15
 
16
- # 常见溶剂的摩尔质量和密度数据库
17
- SOLVENTS_DB = {
18
- "水": {"M": 18.02, "density": 1.000},
19
- "乙醇": {"M": 46.07, "density": 0.789},
20
- "甲醇": {"M": 32.04, "density": 0.792},
21
- "异丙醇": {"M": 60.10, "density": 0.786},
22
- "丙酮": {"M": 58.08, "density": 0.784},
23
- "乙酸乙酯": {"M": 88.11, "density": 0.902},
24
- "甲苯": {"M": 92.14, "density": 0.867},
25
- "二氯甲烷": {"M": 84.93, "density": 1.326},
26
- "氯仿": {"M": 119.38, "density": 1.489},
27
- "四氢呋喃": {"M": 72.11, "density": 0.889},
28
- "二甲基亚砜": {"M": 78.13, "density": 1.100},
29
- "N,N-二甲基甲酰胺": {"M": 73.09, "density": 0.944},
30
- "乙腈": {"M": 41.05, "density": 0.786},
31
- "正己烷": {"M": 86.18, "density": 0.659},
32
- "环己烷": {"M": 84.16, "density": 0.779},
33
- "苯": {"M": 78.11, "density": 0.876},
34
- "乙二醇": {"M": 62.07, "density": 1.113},
35
- "甘油": {"M": 92.09, "density": 1.261}
36
- }
37
-
38
  # 侧边栏 - 转换模式选择
39
- st.sidebar.header("转换模式")
40
  conversion_mode = st.sidebar.radio(
41
- "选择转换方向:",
42
- ["摩尔分数 → 体积分数", "体积分数 → 摩尔分数"]
43
  )
44
 
45
  # 溶剂选择
46
- st.sidebar.header("溶剂选择")
47
- st.sidebar.write("选择两种溶剂或自定义参数:")
 
 
 
 
48
 
49
  # 溶剂A选择
50
- solvent_a_name = st.sidebar.selectbox("溶剂A:", list(SOLVENTS_DB.keys()) + ["自定义"])
51
 
52
- if solvent_a_name == "自定义":
53
  col1, col2 = st.sidebar.columns(2)
54
  with col1:
55
- M_a = st.number_input("摩尔质量A (g/mol):", value=18.02, min_value=0.1, step=0.01)
56
  with col2:
57
- rho_a = st.number_input("密度A (g/cm³):", value=1.000, min_value=0.1, step=0.001)
58
  else:
59
- M_a = SOLVENTS_DB[solvent_a_name]["M"]
60
- rho_a = SOLVENTS_DB[solvent_a_name]["density"]
61
- st.sidebar.write(f"摩尔质量: {M_a} g/mol")
62
- st.sidebar.write(f"密度: {rho_a} g/cm³")
63
 
64
  # 溶剂B选择
65
- solvent_b_name = st.sidebar.selectbox("溶剂B:", list(SOLVENTS_DB.keys()) + ["自定义"])
66
 
67
- if solvent_b_name == "自定义":
68
  col1, col2 = st.sidebar.columns(2)
69
  with col1:
70
- M_b = st.number_input("摩尔质量B (g/mol):", value=46.07, min_value=0.1, step=0.01)
71
  with col2:
72
- rho_b = st.number_input("密度B (g/cm³):", value=0.789, min_value=0.1, step=0.001)
73
  else:
74
- M_b = SOLVENTS_DB[solvent_b_name]["M"]
75
- rho_b = SOLVENTS_DB[solvent_b_name]["density"]
76
- st.sidebar.write(f"摩尔质量: {M_b} g/mol")
77
- st.sidebar.write(f"密度: {rho_b} g/cm³")
78
 
79
  # 主界面内容
80
  col1, col2 = st.columns(2)
81
 
82
- if conversion_mode == "摩尔分数 → 体积分数":
83
  with col1:
84
- st.header("输入摩尔分数")
85
- x_a = st.slider(
86
- f"{solvent_a_name}的摩尔分数 (x_A):",
87
  min_value=0.0,
88
  max_value=1.0,
89
  value=0.5,
90
- step=0.01
 
91
  )
92
  x_b = 1.0 - x_a
93
- st.write(f"{solvent_b_name}的摩尔分数 (x_B): {x_b:.3f}")
94
 
95
  # 计算体积分数
96
- # V_A/V_total = (x_A * M_A / rho_A) / (x_A * M_A / rho_A + x_B * M_B / rho_B)
97
  V_ratio_a = x_a * M_a / rho_a
98
  V_ratio_b = x_b * M_b / rho_b
99
  V_total = V_ratio_a + V_ratio_b
@@ -105,28 +215,28 @@ if conversion_mode == "摩尔分数 → 体积分数":
105
  phi_a = phi_b = 0
106
 
107
  with col2:
108
- st.header("计算结果 - 体积分数")
109
- st.metric(f"{solvent_a_name}的体积分数 (φ_A)", f"{phi_a:.4f}")
110
- st.metric(f"{solvent_b_name}的体积分数 (φ_B)", f"{phi_b:.4f}")
111
 
112
  # 验证
113
- st.write(f"验证: φ_A + φ_B = {phi_a + phi_b:.4f}")
114
 
115
  else: # 体积分数 → 摩尔分数
116
  with col1:
117
- st.header("输入体积分数")
118
- phi_a = st.slider(
119
- f"{solvent_a_name}的体积分数 (φ_A):",
120
  min_value=0.0,
121
  max_value=1.0,
122
  value=0.5,
123
- step=0.01
 
124
  )
125
  phi_b = 1.0 - phi_a
126
- st.write(f"{solvent_b_name}的体积分数 (φ_B): {phi_b:.3f}")
127
 
128
  # 计算摩尔分数
129
- # x_A = (phi_A * rho_A / M_A) / (phi_A * rho_A / M_A + phi_B * rho_B / M_B)
130
  n_ratio_a = phi_a * rho_a / M_a
131
  n_ratio_b = phi_b * rho_b / M_b
132
  n_total = n_ratio_a + n_ratio_b
@@ -138,101 +248,131 @@ else: # 体积分数 → 摩尔分数
138
  x_a = x_b = 0
139
 
140
  with col2:
141
- st.header("计算结果 - 摩尔分数")
142
- st.metric(f"{solvent_a_name}的摩尔分数 (x_A)", f"{x_a:.4f}")
143
- st.metric(f"{solvent_b_name}的摩尔分数 (x_B)", f"{x_b:.4f}")
144
 
145
  # 验证
146
- st.write(f"验证: x_A + x_B = {x_a + x_b:.4f}")
147
-
148
  # 详细信息展示
149
  st.markdown("---")
150
- st.header("详细信息")
151
 
152
  col1, col2, col3 = st.columns(3)
153
 
154
  with col1:
155
- st.subheader("溶剂参数")
156
  df_params = pd.DataFrame({
157
- "溶剂": [solvent_a_name, solvent_b_name],
158
- "摩尔质量 (g/mol)": [M_a, M_b],
159
- "密度 (g/cm³)": [rho_a, rho_b]
160
  })
161
  st.dataframe(df_params)
162
 
163
  with col2:
164
- if conversion_mode == "摩尔分数 → 体积分数":
165
- st.subheader("摩尔分数")
166
  df_mole = pd.DataFrame({
167
- "溶剂": [solvent_a_name, solvent_b_name],
168
- "摩尔分数": [x_a, x_b]
169
  })
170
  st.dataframe(df_mole)
171
  else:
172
- st.subheader("体积分数")
173
  df_vol = pd.DataFrame({
174
- "溶剂": [solvent_a_name, solvent_b_name],
175
- "体积分数": [phi_a, phi_b]
176
  })
177
  st.dataframe(df_vol)
178
 
179
  with col3:
180
- if conversion_mode == "摩尔分数 → 体积分数":
181
- st.subheader("体积分数")
182
  df_vol_result = pd.DataFrame({
183
- "溶剂": [solvent_a_name, solvent_b_name],
184
- "体积分数": [phi_a, phi_b]
185
  })
186
  st.dataframe(df_vol_result)
187
  else:
188
- st.subheader("摩尔分数")
189
  df_mole_result = pd.DataFrame({
190
- "溶剂": [solvent_a_name, solvent_b_name],
191
- "摩尔分数": [x_a, x_b]
192
  })
193
  st.dataframe(df_mole_result)
194
 
195
  # 公式说明
196
  st.markdown("---")
197
- st.header("计算公式")
198
-
199
- if conversion_mode == "摩尔分数 → 体积分数":
200
- st.markdown("""
201
- **摩尔分数转换为体积分数:**
202
-
203
- $$\\phi_A = \\frac{x_A \\cdot M_A / \\rho_A}{x_A \\cdot M_A / \\rho_A + x_B \\cdot M_B / \\rho_B}$$
204
-
205
- $$\\phi_B = \\frac{x_B \\cdot M_B / \\rho_B}{x_A \\cdot M_A / \\rho_A + x_B \\cdot M_B / \\rho_B}$$
206
-
207
- 其中:
208
- - $x_A, x_B$: 摩尔分数
209
- - $\\phi_A, \\phi_B$: 体积分数
210
- - $M_A, M_B$: 摩尔质量 (g/mol)
211
- - $\\rho_A, \\rho_B$: 密度 (g/cm³)
212
- """)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
213
  else:
214
- st.markdown("""
215
- **体积分数转换为摩尔分数:**
216
-
217
- $$x_A = \\frac{\\phi_A \\cdot \\rho_A / M_A}{\\phi_A \\cdot \\rho_A / M_A + \\phi_B \\cdot \\rho_B / M_B}$$
218
-
219
- $$x_B = \\frac{\\phi_B \\cdot \\rho_B / M_B}{\\phi_A \\cdot \\rho_A / M_A + \\phi_B \\cdot \\rho_B / M_B}$$
220
-
221
- 其中:
222
- - $\\phi_A, \\phi_B$: 体积分数
223
- - $x_A, x_B$: 摩尔分数
224
- - $M_A, M_B$: 摩尔质量 (g/mol)
225
- - $\\rho_A, \\rho_B$: 密度 (g/cm³)
226
- """)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
227
 
228
  # 使用说明
229
  st.markdown("---")
230
- st.header("使用说明")
231
- st.markdown("""
232
- 1. **选择转换模式**: 在侧边栏选择转换方向
233
- 2. **选择溶剂**: 从预设的常见溶剂中选择,或选择"自定义"输入参数
234
- 3. **输入数值**: 使用滑块调整摩尔分数或体积分数
235
- 4. **查看结果**: 右侧显示转换结果和详细信息
236
-
237
- **注意**: 本计算假设理想混合,实际情况可能存在偏差。
238
  """)
 
2
  import pandas as pd
3
  import math
4
 
5
+ # 语言配置
6
+ LANGUAGES = {
7
+ "中文": {
8
+ "page_title": "溶剂分数转换器",
9
+ "main_title": "🧪 溶剂摩尔分数与体积分数转换器",
10
+ "conversion_mode": "转换模式",
11
+ "mode_mole_to_vol": "摩尔分数 → 体积分数",
12
+ "mode_vol_to_mole": "体积分数 → 摩尔分数",
13
+ "select_conversion": "选择转换方向:",
14
+ "solvent_selection": "溶剂选择",
15
+ "select_solvents": "选择两种溶剂或自定义参数:",
16
+ "solvent_a": "溶剂A:",
17
+ "solvent_b": "溶剂B:",
18
+ "custom": "自定义",
19
+ "molar_mass": "摩尔质量",
20
+ "density": "密度",
21
+ "input_mole_fraction": "输入摩尔分数",
22
+ "input_volume_fraction": "输入体积分数",
23
+ "mole_fraction_of": "的摩尔分数",
24
+ "volume_fraction_of": "的体积分数",
25
+ "result_volume_fraction": "计算结果 - 体积分数",
26
+ "result_mole_fraction": "计算结果 - 摩尔分数",
27
+ "verification": "验证",
28
+ "detailed_info": "详细信息",
29
+ "solvent_params": "溶剂参数",
30
+ "solvent": "溶剂",
31
+ "mole_fraction": "摩尔分数",
32
+ "volume_fraction": "体积分数",
33
+ "calculation_formula": "计算公式",
34
+ "formula_mole_to_vol_title": "**摩尔分数转换为体积分数:**",
35
+ "formula_vol_to_mole_title": "**体积分数转换为摩尔分数:**",
36
+ "formula_where": "其中:",
37
+ "usage_instructions": "使用说明",
38
+ "instruction_1": "1. **选择转换模式**: 在侧边栏选择转换方向",
39
+ "instruction_2": "2. **选择溶剂**: 从预设的常见溶剂中选择,或选择\"自定义\"输入参数",
40
+ "instruction_3": "3. **输入数值**: 使用滑块调整摩尔分数或体积分数",
41
+ "instruction_4": "4. **查看结果**: 右侧显示转换结果和详细信息",
42
+ "note": "**注意**: 本计算假设理想混合,实际情况可能存在偏差。",
43
+ "language": "语言"
44
+ },
45
+ "English": {
46
+ "page_title": "Solvent Fraction Converter",
47
+ "main_title": "🧪 Solvent Mole Fraction & Volume Fraction Converter",
48
+ "conversion_mode": "Conversion Mode",
49
+ "mode_mole_to_vol": "Mole Fraction → Volume Fraction",
50
+ "mode_vol_to_mole": "Volume Fraction → Mole Fraction",
51
+ "select_conversion": "Select conversion direction:",
52
+ "solvent_selection": "Solvent Selection",
53
+ "select_solvents": "Select two solvents or customize parameters:",
54
+ "solvent_a": "Solvent A:",
55
+ "solvent_b": "Solvent B:",
56
+ "custom": "Custom",
57
+ "molar_mass": "Molar Mass",
58
+ "density": "Density",
59
+ "input_mole_fraction": "Input Mole Fraction",
60
+ "input_volume_fraction": "Input Volume Fraction",
61
+ "mole_fraction_of": "Mole fraction of",
62
+ "volume_fraction_of": "Volume fraction of",
63
+ "result_volume_fraction": "Results - Volume Fraction",
64
+ "result_mole_fraction": "Results - Mole Fraction",
65
+ "verification": "Verification",
66
+ "detailed_info": "Detailed Information",
67
+ "solvent_params": "Solvent Parameters",
68
+ "solvent": "Solvent",
69
+ "mole_fraction": "Mole Fraction",
70
+ "volume_fraction": "Volume Fraction",
71
+ "calculation_formula": "Calculation Formula",
72
+ "formula_mole_to_vol_title": "**Mole Fraction to Volume Fraction:**",
73
+ "formula_vol_to_mole_title": "**Volume Fraction to Mole Fraction:**",
74
+ "formula_where": "Where:",
75
+ "usage_instructions": "Usage Instructions",
76
+ "instruction_1": "1. **Select Conversion Mode**: Choose conversion direction in sidebar",
77
+ "instruction_2": "2. **Select Solvents**: Choose from preset common solvents or select 'Custom' to input parameters",
78
+ "instruction_3": "3. **Input Values**: Use sliders to adjust mole fraction or volume fraction",
79
+ "instruction_4": "4. **View Results**: Results and detailed information are displayed on the right",
80
+ "note": "**Note**: This calculation assumes ideal mixing; actual situations may deviate.",
81
+ "language": "Language"
82
+ }
83
+ }
84
+
85
+ # 常见溶剂的摩尔质量和密度数据库(中英文对照)
86
+ SOLVENTS_DB = {
87
+ "中文": {
88
+ "水": {"M": 18.02, "density": 1.000, "en": "Water"},
89
+ "乙醇": {"M": 46.07, "density": 0.789, "en": "Ethanol"},
90
+ "甲醇": {"M": 32.04, "density": 0.792, "en": "Methanol"},
91
+ "异丙醇": {"M": 60.10, "density": 0.786, "en": "Isopropanol"},
92
+ "丙酮": {"M": 58.08, "density": 0.784, "en": "Acetone"},
93
+ "乙酸乙酯": {"M": 88.11, "density": 0.902, "en": "Ethyl Acetate"},
94
+ "甲苯": {"M": 92.14, "density": 0.867, "en": "Toluene"},
95
+ "二氯甲烷": {"M": 84.93, "density": 1.326, "en": "Dichloromethane"},
96
+ "氯仿": {"M": 119.38, "density": 1.489, "en": "Chloroform"},
97
+ "四氢呋喃": {"M": 72.11, "density": 0.889, "en": "Tetrahydrofuran"},
98
+ "二甲基亚砜": {"M": 78.13, "density": 1.100, "en": "Dimethyl Sulfoxide"},
99
+ "N,N-二甲基甲酰胺": {"M": 73.09, "density": 0.944, "en": "N,N-Dimethylformamide"},
100
+ "乙腈": {"M": 41.05, "density": 0.786, "en": "Acetonitrile"},
101
+ "正己烷": {"M": 86.18, "density": 0.659, "en": "n-Hexane"},
102
+ "环己烷": {"M": 84.16, "density": 0.779, "en": "Cyclohexane"},
103
+ "苯": {"M": 78.11, "density": 0.876, "en": "Benzene"},
104
+ "乙二醇": {"M": 62.07, "density": 1.113, "en": "Ethylene Glycol"},
105
+ "甘油": {"M": 92.09, "density": 1.261, "en": "Glycerol"}
106
+ },
107
+ "English": {
108
+ "Water": {"M": 18.02, "density": 1.000, "cn": "水"},
109
+ "Ethanol": {"M": 46.07, "density": 0.789, "cn": "乙醇"},
110
+ "Methanol": {"M": 32.04, "density": 0.792, "cn": "甲醇"},
111
+ "Isopropanol": {"M": 60.10, "density": 0.786, "cn": "异丙醇"},
112
+ "Acetone": {"M": 58.08, "density": 0.784, "cn": "丙酮"},
113
+ "Ethyl Acetate": {"M": 88.11, "density": 0.902, "cn": "乙酸乙酯"},
114
+ "Toluene": {"M": 92.14, "density": 0.867, "cn": "甲苯"},
115
+ "Dichloromethane": {"M": 84.93, "density": 1.326, "cn": "二氯甲烷"},
116
+ "Chloroform": {"M": 119.38, "density": 1.489, "cn": "氯仿"},
117
+ "Tetrahydrofuran": {"M": 72.11, "density": 0.889, "cn": "四氢呋喃"},
118
+ "Dimethyl Sulfoxide": {"M": 78.13, "density": 1.100, "cn": "二甲基亚砜"},
119
+ "N,N-Dimethylformamide": {"M": 73.09, "density": 0.944, "cn": "N,N-二甲基甲酰胺"},
120
+ "Acetonitrile": {"M": 41.05, "density": 0.786, "cn": "乙腈"},
121
+ "n-Hexane": {"M": 86.18, "density": 0.659, "cn": "正己烷"},
122
+ "Cyclohexane": {"M": 84.16, "density": 0.779, "cn": "环己烷"},
123
+ "Benzene": {"M": 78.11, "density": 0.876, "cn": "苯"},
124
+ "Ethylene Glycol": {"M": 62.07, "density": 1.113, "cn": "乙二醇"},
125
+ "Glycerol": {"M": 92.09, "density": 1.261, "cn": "甘油"}
126
+ }
127
+ }
128
+
129
+ # 语言选择
130
+ language = st.sidebar.selectbox("Language/语言:", ["中文", "English"])
131
+ lang = LANGUAGES[language]
132
+
133
  # 配置页面
134
  st.set_page_config(
135
+ page_title=lang["page_title"],
136
  page_icon="🧪",
137
  layout="wide"
138
  )
139
 
140
  # 页面标题
141
+ st.title(lang["main_title"])
142
  st.markdown("---")
143
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
  # 侧边栏 - 转换模式选择
145
+ st.sidebar.header(lang["conversion_mode"])
146
  conversion_mode = st.sidebar.radio(
147
+ lang["select_conversion"],
148
+ [lang["mode_mole_to_vol"], lang["mode_vol_to_mole"]]
149
  )
150
 
151
  # 溶剂选择
152
+ st.sidebar.header(lang["solvent_selection"])
153
+ st.sidebar.write(lang["select_solvents"])
154
+
155
+ # 获取当前语言的溶剂列表
156
+ current_solvents = SOLVENTS_DB[language]
157
+ solvent_names = list(current_solvents.keys()) + [lang["custom"]]
158
 
159
  # 溶剂A选择
160
+ solvent_a_name = st.sidebar.selectbox(lang["solvent_a"], solvent_names)
161
 
162
+ if solvent_a_name == lang["custom"]:
163
  col1, col2 = st.sidebar.columns(2)
164
  with col1:
165
+ M_a = st.number_input(f"{lang['molar_mass']} A (g/mol):", value=18.02, min_value=0.1, step=0.01)
166
  with col2:
167
+ rho_a = st.number_input(f"{lang['density']} A (g/cm³):", value=1.000, min_value=0.1, step=0.001)
168
  else:
169
+ M_a = current_solvents[solvent_a_name]["M"]
170
+ rho_a = current_solvents[solvent_a_name]["density"]
171
+ st.sidebar.write(f"{lang['molar_mass']}: {M_a} g/mol")
172
+ st.sidebar.write(f"{lang['density']}: {rho_a} g/cm³")
173
 
174
  # 溶剂B选择
175
+ solvent_b_name = st.sidebar.selectbox(lang["solvent_b"], solvent_names)
176
 
177
+ if solvent_b_name == lang["custom"]:
178
  col1, col2 = st.sidebar.columns(2)
179
  with col1:
180
+ M_b = st.number_input(f"{lang['molar_mass']} B (g/mol):", value=46.07, min_value=0.1, step=0.01)
181
  with col2:
182
+ rho_b = st.number_input(f"{lang['density']} B (g/cm³):", value=0.789, min_value=0.1, step=0.001)
183
  else:
184
+ M_b = current_solvents[solvent_b_name]["M"]
185
+ rho_b = current_solvents[solvent_b_name]["density"]
186
+ st.sidebar.write(f"{lang['molar_mass']}: {M_b} g/mol")
187
+ st.sidebar.write(f"{lang['density']}: {rho_b} g/cm³")
188
 
189
  # 主界面内容
190
  col1, col2 = st.columns(2)
191
 
192
+ if conversion_mode == lang["mode_mole_to_vol"]:
193
  with col1:
194
+ st.header(lang["input_mole_fraction"])
195
+ x_a = st.number_input(
196
+ f"{lang['mole_fraction_of']} {solvent_a_name} (x_A):",
197
  min_value=0.0,
198
  max_value=1.0,
199
  value=0.5,
200
+ step=0.001,
201
+ format="%.4f"
202
  )
203
  x_b = 1.0 - x_a
204
+ st.write(f"{lang['mole_fraction_of']} {solvent_b_name} (x_B): {x_b:.4f}")
205
 
206
  # 计算体积分数
 
207
  V_ratio_a = x_a * M_a / rho_a
208
  V_ratio_b = x_b * M_b / rho_b
209
  V_total = V_ratio_a + V_ratio_b
 
215
  phi_a = phi_b = 0
216
 
217
  with col2:
218
+ st.header(lang["result_volume_fraction"])
219
+ st.metric(f"{lang['volume_fraction_of']} {solvent_a_name} (φ_A)", f"{phi_a:.4f}")
220
+ st.metric(f"{lang['volume_fraction_of']} {solvent_b_name} (φ_B)", f"{phi_b:.4f}")
221
 
222
  # 验证
223
+ st.write(f"{lang['verification']}: φ_A + φ_B = {phi_a + phi_b:.4f}")
224
 
225
  else: # 体积分数 → 摩尔分数
226
  with col1:
227
+ st.header(lang["input_volume_fraction"])
228
+ phi_a = st.number_input(
229
+ f"{lang['volume_fraction_of']} {solvent_a_name} (φ_A):",
230
  min_value=0.0,
231
  max_value=1.0,
232
  value=0.5,
233
+ step=0.001,
234
+ format="%.4f"
235
  )
236
  phi_b = 1.0 - phi_a
237
+ st.write(f"{lang['volume_fraction_of']} {solvent_b_name} (φ_B): {phi_b:.4f}")
238
 
239
  # 计算摩尔分数
 
240
  n_ratio_a = phi_a * rho_a / M_a
241
  n_ratio_b = phi_b * rho_b / M_b
242
  n_total = n_ratio_a + n_ratio_b
 
248
  x_a = x_b = 0
249
 
250
  with col2:
251
+ st.header(lang["result_mole_fraction"])
252
+ st.metric(f"{lang['mole_fraction_of']} {solvent_a_name} (x_A)", f"{x_a:.4f}")
253
+ st.metric(f"{lang['mole_fraction_of']} {solvent_b_name} (x_B)", f"{x_b:.4f}")
254
 
255
  # 验证
256
+ st.write(f"{lang['verification']}: x_A + x_B = {x_a + x_b:.4f}")
257
+
258
  # 详细信息展示
259
  st.markdown("---")
260
+ st.header(lang["detailed_info"])
261
 
262
  col1, col2, col3 = st.columns(3)
263
 
264
  with col1:
265
+ st.subheader(lang["solvent_params"])
266
  df_params = pd.DataFrame({
267
+ lang["solvent"]: [solvent_a_name, solvent_b_name],
268
+ f"{lang['molar_mass']} (g/mol)": [M_a, M_b],
269
+ f"{lang['density']} (g/cm³)": [rho_a, rho_b]
270
  })
271
  st.dataframe(df_params)
272
 
273
  with col2:
274
+ if conversion_mode == lang["mode_mole_to_vol"]:
275
+ st.subheader(lang["mole_fraction"])
276
  df_mole = pd.DataFrame({
277
+ lang["solvent"]: [solvent_a_name, solvent_b_name],
278
+ lang["mole_fraction"]: [x_a, x_b]
279
  })
280
  st.dataframe(df_mole)
281
  else:
282
+ st.subheader(lang["volume_fraction"])
283
  df_vol = pd.DataFrame({
284
+ lang["solvent"]: [solvent_a_name, solvent_b_name],
285
+ lang["volume_fraction"]: [phi_a, phi_b]
286
  })
287
  st.dataframe(df_vol)
288
 
289
  with col3:
290
+ if conversion_mode == lang["mode_mole_to_vol"]:
291
+ st.subheader(lang["volume_fraction"])
292
  df_vol_result = pd.DataFrame({
293
+ lang["solvent"]: [solvent_a_name, solvent_b_name],
294
+ lang["volume_fraction"]: [phi_a, phi_b]
295
  })
296
  st.dataframe(df_vol_result)
297
  else:
298
+ st.subheader(lang["mole_fraction"])
299
  df_mole_result = pd.DataFrame({
300
+ lang["solvent"]: [solvent_a_name, solvent_b_name],
301
+ lang["mole_fraction"]: [x_a, x_b]
302
  })
303
  st.dataframe(df_mole_result)
304
 
305
  # 公式说明
306
  st.markdown("---")
307
+ st.header(lang["calculation_formula"])
308
+
309
+ if conversion_mode == lang["mode_mole_to_vol"]:
310
+ if language == "中文":
311
+ st.markdown(f"""
312
+ {lang["formula_mole_to_vol_title"]}
313
+
314
+ $$\\phi_A = \\frac{{x_A \\cdot M_A / \\rho_A}}{{x_A \\cdot M_A / \\rho_A + x_B \\cdot M_B / \\rho_B}}$$
315
+
316
+ $$\\phi_B = \\frac{{x_B \\cdot M_B / \\rho_B}}{{x_A \\cdot M_A / \\rho_A + x_B \\cdot M_B / \\rho_B}}$$
317
+
318
+ {lang["formula_where"]}
319
+ - $x_A, x_B$: 摩尔分数
320
+ - $\\phi_A, \\phi_B$: 体积分数
321
+ - $M_A, M_B$: 摩尔质量 (g/mol)
322
+ - $\\rho_A, \\rho_B$: 密度 (g/cm³)
323
+ """)
324
+ else:
325
+ st.markdown(f"""
326
+ {lang["formula_mole_to_vol_title"]}
327
+
328
+ $$\\phi_A = \\frac{{x_A \\cdot M_A / \\rho_A}}{{x_A \\cdot M_A / \\rho_A + x_B \\cdot M_B / \\rho_B}}$$
329
+
330
+ $$\\phi_B = \\frac{{x_B \\cdot M_B / \\rho_B}}{{x_A \\cdot M_A / \\rho_A + x_B \\cdot M_B / \\rho_B}}$$
331
+
332
+ {lang["formula_where"]}
333
+ - $x_A, x_B$: Mole fractions
334
+ - $\\phi_A, \\phi_B$: Volume fractions
335
+ - $M_A, M_B$: Molar mass (g/mol)
336
+ - $\\rho_A, \\rho_B$: Density (g/cm³)
337
+ """)
338
  else:
339
+ if language == "中文":
340
+ st.markdown(f"""
341
+ {lang["formula_vol_to_mole_title"]}
342
+
343
+ $$x_A = \\frac{{\\phi_A \\cdot \\rho_A / M_A}}{{\\phi_A \\cdot \\rho_A / M_A + \\phi_B \\cdot \\rho_B / M_B}}$$
344
+
345
+ $$x_B = \\frac{{\\phi_B \\cdot \\rho_B / M_B}}{{\\phi_A \\cdot \\rho_A / M_A + \\phi_B \\cdot \\rho_B / M_B}}$$
346
+
347
+ {lang["formula_where"]}
348
+ - $\\phi_A, \\phi_B$: 体积分数
349
+ - $x_A, x_B$: 摩尔分数
350
+ - $M_A, M_B$: 摩尔质量 (g/mol)
351
+ - $\\rho_A, \\rho_B$: 密度 (g/cm³)
352
+ """)
353
+ else:
354
+ st.markdown(f"""
355
+ {lang["formula_vol_to_mole_title"]}
356
+
357
+ $$x_A = \\frac{{\\phi_A \\cdot \\rho_A / M_A}}{{\\phi_A \\cdot \\rho_A / M_A + \\phi_B \\cdot \\rho_B / M_B}}$$
358
+
359
+ $$x_B = \\frac{{\\phi_B \\cdot \\rho_B / M_B}}{{\\phi_A \\cdot \\rho_A / M_A + \\phi_B \\cdot \\rho_B / M_B}}$$
360
+
361
+ {lang["formula_where"]}
362
+ - $\\phi_A, \\phi_B$: Volume fractions
363
+ - $x_A, x_B$: Mole fractions
364
+ - $M_A, M_B$: Molar mass (g/mol)
365
+ - $\\rho_A, \\rho_B$: Density (g/cm³)
366
+ """)
367
 
368
  # 使用说明
369
  st.markdown("---")
370
+ st.header(lang["usage_instructions"])
371
+ st.markdown(f"""
372
+ {lang["instruction_1"]}
373
+ {lang["instruction_2"]}
374
+ {lang["instruction_3"]}
375
+ {lang["instruction_4"]}
376
+
377
+ {lang["note"]}
378
  """)