clidx commited on
Commit
4721f11
·
verified ·
1 Parent(s): 764e014

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +236 -38
src/streamlit_app.py CHANGED
@@ -1,40 +1,238 @@
1
- import altair as alt
2
- import numpy as np
3
- import pandas as pd
4
  import streamlit as st
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
- """
7
- # Welcome to Streamlit!
8
-
9
- Edit `/streamlit_app.py` to customize this app to your heart's desire :heart:.
10
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
11
- forums](https://discuss.streamlit.io).
12
-
13
- In the meantime, below is an example of what you can do with just a few lines of code:
14
- """
15
-
16
- num_points = st.slider("Number of points in spiral", 1, 10000, 1100)
17
- num_turns = st.slider("Number of turns in spiral", 1, 300, 31)
18
-
19
- indices = np.linspace(0, 1, num_points)
20
- theta = 2 * np.pi * num_turns * indices
21
- radius = indices
22
-
23
- x = radius * np.cos(theta)
24
- y = radius * np.sin(theta)
25
-
26
- df = pd.DataFrame({
27
- "x": x,
28
- "y": y,
29
- "idx": indices,
30
- "rand": np.random.randn(num_points),
31
- })
32
-
33
- st.altair_chart(alt.Chart(df, height=700, width=700)
34
- .mark_point(filled=True)
35
- .encode(
36
- x=alt.X("x", axis=None),
37
- y=alt.Y("y", axis=None),
38
- color=alt.Color("idx", legend=None, scale=alt.Scale()),
39
- size=alt.Size("rand", legend=None, scale=alt.Scale(range=[1, 150])),
40
- ))
 
 
 
 
1
  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
100
+
101
+ if V_total > 0:
102
+ phi_a = V_ratio_a / V_total
103
+ phi_b = V_ratio_b / V_total
104
+ else:
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
133
+
134
+ if n_total > 0:
135
+ x_a = n_ratio_a / n_total
136
+ x_b = n_ratio_b / n_total
137
+ 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
+ """)