密立根油滴仪测油滴电荷数据计算 Python实现
内容仅供参考,如有错误,欢迎指正,如有疑问,欢迎交流。
只想无脑输入数据的请用第一代,想要方便修改数据的请用第二代,想要看着舒服的请用第三代
祝大家早日摆脱物理实验的苦海
第一代
因为物理实验的数据一个个计算实在太麻烦了,因此第一代python代码诞生了,仅需输入原始数据,后面的计算全部一次性算完
代码
# auther: Htlang
p_md = 0.981 * 10 ** 3 # 油的密度
g = 9.793 # 重力加速度
n_air = 1.83 * 10 ** (-5) # 空气粘滞系数
l = 2.00 * 10 ** (-3) # 下降距离
b = 8.226 * 10 ** (-3) # 修正常数
p_yq = 101325 # 大气压强
d = 0.005 # 平行板之间的距离
e0 = 1.6 * 10 ** (-19) # 电子电量公认值
import math
for i in range(1, 6):
v = 0
t = 0
v_lst = []
t_lst = []
print(f"请输入第{i}组数据(共三行,每行格式:平衡电压 下降时间)")
for j in range(1, 4):
vv, tt = map(float, input().split())
# vv, tt = map(float, input().split())
v_lst.append(vv)
t_lst.append(tt)
v += vv
t += tt
v /= 3 # 平均平衡电压
t /= 3 # 平均下落时间
a = ((9 * n_air * l) / (2 * p_md * g * t)) ** 0.5 # 粗略半径
n_xz = n_air / (1 + b / (p_yq * a)) # 修正后的粘滞系数
k = (18 * math.pi * d) / (2 * p_md * g) ** 0.5 * ((n_air * l) / (1 + b / (p_yq * a))) ** (3 / 2)
q = k * (1 / t) ** (3 / 2) * (1 / v) # 油滴电量
_t = (sum([(t_lst[i] - t) ** 2 for i in range(3)]) / 2 + 0.01) ** 0.5
_v = 1
_q = q * (((3 * _t) / (2 * t)) ** 2 + (_v / v) ** 2) ** 0.5
n = (q / e0 + 0.5) // 1 # 电荷数
e = q / n # 基本电荷量
_e = _q / n
E = (e - e0) / e0 * 100 # 百分差
print(f"第{i}组数据计算结果:\n"
f"平均平衡电压:{v:.0f}, 平均下落时间:{t:.1f}, 粗略半径:{a * 10 ** 7:.2f}×10^(-7), 修正后的粘滞系数:{n_xz * 10 ** 5:.2f}×10^(-5), K的值:{k * 10 ** 14:.2f}×10^(-14)\n"
f"油滴电量:{q * 10 ** 19:.2f}×10^(-19), 油滴电量不确定度:{_q * 10 ** 19:.2f}×10^(-19), 油滴电量最终结果:{q * 10 ** 19:.2f}±{_q * 10 ** 19:.2f}×10^(-19)\n"
f"电荷数:{n:.0f}, 基本电荷量:{e * 10 ** 19:.2f}×10^(-19), 基本电荷量不确定度:{_e * 10 ** 19:.2f}×10^(-19), 基本电荷量最终结果:{e * 10 ** 19:.2f}±{_e * 10 ** 19:.2f}×10^(-19), 百分差:{E:.1f}%\n")
第一代操作起来十分方便,仅需新建.py文件然后将代码复制进去按运行即可,运行结果大致如下
第二代
鉴于第一代一旦数据输错就要重新运行代码重新输入原先的数据,实在是太让人头大了,因此诞生了第二代。
代码
# author: Htlang
p_md = 0.981 * 10 ** 3 # 油的密度
g = 9.793 # 重力加速度
n_air = 1.83 * 10 ** (-5) # 空气粘滞系数
l = 2.00 * 10 ** (-3) # 下降距离
b = 8.226 * 10 ** (-3) # 修正常数
p_yq = 101325 # 大气压强
d = 0.005 # 平行板之间的距离
e0 = 1.6 * 10 ** (-19) # 电子电量公认值
import math
with open('test.txt', 'r', encoding="UTF-8") as file:
lines = []
for line in file:
lines.append(line.strip())
for i in range(5):
v = 0
t = 0
v_lst = []
t_lst = []
for j in range(i * 3, i * 3 + 3):
line = lines[j]
vv, tt = map(float, line.split())
v_lst.append(vv)
t_lst.append(tt)
v += vv
t += tt
v /= 3 # 平均平衡电压
t /= 3 # 平均下落时间
a = ((9 * n_air * l) / (2 * p_md * g * t)) ** 0.5 # 粗略半径
n_xz = n_air / (1 + b / (p_yq * a)) # 修正后的粘滞系数
k = (18 * math.pi * d) / (2 * p_md * g) ** 0.5 * ((n_air * l) / (1 + b / (p_yq * a))) ** (3 / 2)
q = k * (1 / t) ** (3 / 2) * (1 / v) # 油滴电量
_t = (sum([(t_lst[i] - t) ** 2 for i in range(3)]) / 2 + 0.01) ** 0.5
_v = 1
_q = q * (((3 * _t) / (2 * t)) ** 2 + (_v / v) ** 2) ** 0.5
n = (q / e0 + 0.5) // 1 # 电荷数
e = q / n # 基本电荷量
_e = _q / n
E = (e - e0) / e0 * 100 # 百分差
print(f"第{i + 1}组数据计算结果:\n"
f"平均平衡电压:{v:.0f}, 平均下落时间:{t:.1f}, 粗略半径:{a * 10 ** 7:.2f}×10^(-7), 修正后的粘滞系数:{n_xz * 10 ** 5:.2f}×10^(-5), K的值:{k * 10 ** 14:.2f}×10^(-14)\n"
f"油滴电量:{q * 10 ** 19:.2f}×10^(-19), 油滴电量不确定度:{_q * 10 ** 19:.2f}×10^(-19), 油滴电量最终结果:{q * 10 ** 19:.2f}±{_q * 10 ** 19:.2f}×10^(-19)\n"
f"电荷数:{n:.0f}, 基本电荷量:{e * 10 ** 19:.2f}×10^(-19), 基本电荷量不确定度:{_e * 10 ** 19:.2f}×10^(-19), 基本电荷量最终结果:{e * 10 ** 19:.2f}±{_e * 10 ** 19:.2f}×10^(-19), 百分差:{E:.1f}%\n")
操作过程
第二代使用起来需要新建一个test.txt,PyCharm选手和VS Code选手可以这么放:
IDLE选手可以这么放(这是在桌面,忽略图标是VS Code):
打开test.txt,输入15组实验数据(必须输满15组,否则会报错,数据不够可以用1或者重复的数据代替,注意不要用0),如下图所示
如果想将test.txt换个名,需要将代码第14行中test.txt一起改掉,运行结果大致如下:
如果出现
请先检查文件名是否一致,检查无误还报错,那就试试绝对引用,即将文本文件的文件路径复制到代码第14行,引号前面再加个r(或者把"\"全改为"\\"或"/"),如下图
第三代
“哎呀主播主播,这个输出一坨文字看着好难受,有没有更好的处理办法。”
“有的兄弟,有的,能看着更舒服的办法,我还有2个”
一个是用csv库,一个是用openpyxl库,我一开始用的是csv,但是CSV 格式本身不包含格式信息(例如列宽设置),所以无法直接在 CSV 文件中指定列宽,所以使用openpyxl库的第三代代码诞生了
预处理,先看这里
因为要用到openpyxl扩展库,所以请先win+r打开cmd然后输入pip install openpyxl,如下图
我这里是因为已经装过了所以显示的是Requirement already satisfied,没装过应该会有什么什么succeed之类的信息
如果你有VS Code或者PyCharm,请看这里
代码
# auther: Htlang
import math
from openpyxl import Workbook # pip install openpyxl
from openpyxl.utils import get_column_letter
def to_superscript(s):
"""将字符串中的数字和负号转换为 Unicode 上标字符"""
mapping = {'-': '⁻', '0': '⁰', '1': '¹', '2': '²', '3': '³',
'4': '⁴', '5': '⁵', '6': '⁶', '7': '⁷', '8': '⁸', '9': '⁹'}
return ''.join(mapping.get(ch, ch) for ch in s)
# 物理常量
p_md = 0.981 * 10 ** 3 # 油的密度
g = 9.793 # 重力加速度
n_air = 1.83 * 10 ** (-5) # 空气粘滞系数
l = 2.00 * 10 ** (-3) # 下降距离
b = 8.226 * 10 ** (-3) # 修正常数
p_yq = 101325 # 大气压强
d = 0.005 # 平行板之间的距离
e0 = 1.6 * 10 ** (-19) # 公认的电子电量
with open('test.txt', 'r', encoding="UTF-8") as file:
lines = [line.strip() for line in file]
results = [] # 存储各组计算结果
for i in range(1, 6):
v = 0
t = 0
v_lst = []
t_lst = []
for j in range((i - 1) * 3, (i - 1) * 3 + 3):
line = lines[j]
vv, tt = map(float, line.split())
v_lst.append(vv)
t_lst.append(tt)
v += vv
t += tt
v /= 3 # 平均平衡电压
t /= 3 # 平均下落时间
a = ((9 * n_air * l) / (2 * p_md * g * t)) ** 0.5 # 粗略半径
n_xz = n_air / (1 + b / (p_yq * a)) # 修正后的粘滞系数
k = (18 * math.pi * d) / (2 * p_md * g) ** 0.5 * ((n_air * l) / (1 + b / (p_yq * a))) ** (3 / 2)
q = k * (1 / t) ** (3 / 2) * (1 / v) # 油滴电量
_t = (sum([(t_lst[k] - t) ** 2 for k in range(3)]) / 2 + 0.01) ** 0.5
_v = 1
_q = q * (((3 * _t) / (2 * t)) ** 2 + (_v / v) ** 2) ** 0.5
n = (q / e0 + 0.5) // 1 # 电荷数
e = q / n # 基本电荷量
_e = _q / n
E = (e - e0) / e0 * 100 # 百分差
result = {
"组": i,
"VB (V)": f'="{v:.0f}"',
"tg (s)": f'="{t:.1f}"',
"a (×10" + to_superscript("-7") + " m)": f'="{a * 10 ** 7:.2f}"',
"η (×10" + to_superscript("-5") + " kg/ms)": f'="{n_xz * 10 ** 5:.2f}"',
"K (×10" + to_superscript("-14") + ")": f'="{k * 10 ** 14:.2f}"',
"q (×10" + to_superscript("-19") + " C)": f'="{q * 10 ** 19:.2f}"',
"Δq (×10" + to_superscript("-19") + " C)": f'="{_q * 10 ** 19:.2f}"',
"q结果 (×10" + to_superscript("-19") + " C)": f'="{q * 10 ** 19:.2f}±{_q * 10 ** 19:.2f}"',
"n": f'="{n:.0f}"',
"e (×10" + to_superscript("-19") + " C)": f'="{e * 10 ** 19:.2f}"',
"Δe (×10" + to_superscript("-19") + " C)": f'="{_e * 10 ** 19:.2f}"',
"e结果 (×10" + to_superscript("-19") + " C)": f'="{e * 10 ** 19:.2f}±{_e * 10 ** 19:.2f}"',
"Ep (%)": f'="{E:.1f}"'
}
results.append(result)
# 定义字段顺序
fieldnames = [
"组",
"VB (V)",
"tg (s)",
"a (×10" + to_superscript("-7") + " m)",
"η (×10" + to_superscript("-5") + " kg/ms)",
"K (×10" + to_superscript("-14") + ")",
"q (×10" + to_superscript("-19") + " C)",
"Δq (×10" + to_superscript("-19") + " C)",
"q结果 (×10" + to_superscript("-19") + " C)",
"n",
"e (×10" + to_superscript("-19") + " C)",
"Δe (×10" + to_superscript("-19") + " C)",
"e结果 (×10" + to_superscript("-19") + " C)",
"Ep (%)"
]
# 创建工作簿和工作表
wb = Workbook()
ws = wb.active
ws.title = "Result Table"
# 写入表头
for col_num, header in enumerate(fieldnames, 1):
ws.cell(row=1, column=col_num, value=header)
# 写入数据行
for row_num, result in enumerate(results, 2):
for col_num, field in enumerate(fieldnames, 1):
ws.cell(row=row_num, column=col_num, value=result[field])
# 设置列宽
for col_num, field in enumerate(fieldnames, 1):
col_letter = get_column_letter(col_num)
ws.column_dimensions[col_letter].width = len(field) + 4
# 保存工作簿
wb.save("result_table.xlsx")
print("结果已保存到 result_table.xlsx 文件中。")
操作过程
和第二代一样,先在打开的文件夹中创建一个test.txt,然后在txt中输入数据(要求同第二代),然后运行代码,文件夹中会新建一个result_table.xlsx,里面保存的就是运行结果
如果你只有IDLE,请看这里
代码
# auther: Htlang
import math
from openpyxl import Workbook #pip install openpyxl
from openpyxl.utils import get_column_letter
def to_superscript(s):
"""将字符串中的数字和负号转换为 Unicode 上标字符"""
mapping = {'-': '⁻', '0': '⁰', '1': '¹', '2': '²', '3': '³',
'4': '⁴', '5': '⁵', '6': '⁶', '7': '⁷', '8': '⁸', '9': '⁹'}
return ''.join(mapping.get(ch, ch) for ch in s)
# 物理常量
p_md = 0.981 * 10 ** 3 # 油的密度 (kg/m^3)
g = 9.793 # 重力加速度 (m/s^2)
n_air = 1.83 * 10 ** (-5) # 空气粘滞系数 (Pa·s)
l = 2.00 * 10 ** (-3) # 下降距离 (m)
b = 8.226 * 10 ** (-3) # 修正常数
p_yq = 101325 # 大气压强 (Pa)
d = 0.005 # 平行板之间的距离 (m)
e0 = 1.6 * 10 ** (-19) # 电子电量 (C)
filename = r"C:\Users\86138\Desktop\test.txt" # 将这里改为你的文件路径
with open(filename, 'r', encoding="UTF-8") as file:
lines = [line.strip() for line in file]
results = [] # 存储各组计算结果
for i in range(1, 6):
v = 0
t = 0
v_lst = []
t_lst = []
# 每组取3行数据
for j in range((i - 1) * 3, (i - 1) * 3 + 3):
line = lines[j]
vv, tt = map(float, line.split())
v_lst.append(vv)
t_lst.append(tt)
v += vv
t += tt
v /= 3 # 平均平衡电压
t /= 3 # 平均下落时间
a = ((9 * n_air * l) / (2 * p_md * g * t)) ** 0.5 # 粗略半径
n_xz = n_air / (1 + b / (p_yq * a)) # 修正后的粘滞系数
k = (18 * math.pi * d) / (2 * p_md * g) ** 0.5 * ((n_air * l) / (1 + b / (p_yq * a))) ** (3 / 2)
q = k * (1 / t) ** (3 / 2) * (1 / v) # 油滴电量
_t = (sum([(t_lst[k] - t) ** 2 for k in range(3)]) / 2 + 0.01) ** 0.5
_v = 1
_q = q * (((3 * _t) / (2 * t)) ** 2 + (_v / v) ** 2) ** 0.5
n = (q / e0 + 0.5) // 1 # 电荷数
e = q / n # 基本电荷量
_e = _q / n
E = (e - e0) / e0 * 100 # 百分差
result = {
"组": i,
"VB (V)": f'="{v:.0f}"',
"tg (s)": f'="{t:.1f}"',
"a (×10" + to_superscript("-7") + " m)": f'="{a * 10 ** 7:.2f}"',
"η (×10" + to_superscript("-5") + " kg/ms)": f'="{n_xz * 10 ** 5:.2f}"',
"K (×10" + to_superscript("-14") + ")": f'="{k * 10 ** 14:.2f}"',
"q (×10" + to_superscript("-19") + " C)": f'="{q * 10 ** 19:.2f}"',
"Δq (×10" + to_superscript("-19") + " C)": f'="{_q * 10 ** 19:.2f}"',
"q结果 (×10" + to_superscript("-19") + " C)": f'="{q * 10 ** 19:.2f}±{_q * 10 ** 19:.2f}"',
"n": f'="{n:.0f}"',
"e (×10" + to_superscript("-19") + " C)": f'="{e * 10 ** 19:.2f}"',
"Δe (×10" + to_superscript("-19") + " C)": f'="{_e * 10 ** 19:.2f}"',
"e结果 (×10" + to_superscript("-19") + " C)": f'="{e * 10 ** 19:.2f}±{_e * 10 ** 19:.2f}"',
"Ep (%)": f'="{E:.1f}"'
}
results.append(result)
# 定义字段顺序
fieldnames = [
"组",
"VB (V)",
"tg (s)",
"a (×10" + to_superscript("-7") + " m)",
"η (×10" + to_superscript("-5") + " kg/ms)",
"K (×10" + to_superscript("-14") + ")",
"q (×10" + to_superscript("-19") + " C)",
"Δq (×10" + to_superscript("-19") + " C)",
"q结果 (×10" + to_superscript("-19") + " C)",
"n",
"e (×10" + to_superscript("-19") + " C)",
"Δe (×10" + to_superscript("-19") + " C)",
"e结果 (×10" + to_superscript("-19") + " C)",
"Ep (%)"
]
# 创建工作簿和工作表
wb = Workbook()
ws = wb.active
ws.title = "Result Table"
# 写入表头
for col_num, header in enumerate(fieldnames, 1):
ws.cell(row=1, column=col_num, value=header)
# 写入数据行
for row_num, result in enumerate(results, 2):
for col_num, field in enumerate(fieldnames, 1):
ws.cell(row=row_num, column=col_num, value=result[field])
# 设置列宽
for col_num, field in enumerate(fieldnames, 1):
col_letter = get_column_letter(col_num)
ws.column_dimensions[col_letter].width = len(field) + 4
lst = filename.split("\\")[:-1]
out = ""
for x in lst:
out += x + "\\"
# 保存工作簿
wb.save(out + "result_table.xlsx")
print("结果已保存到 result_table.xlsx 文件中。")
操作过程
同第二代,在桌面或其它位置新建.py,在当前位置创建test.txt,然后在txt中输入数据(要求同第二代),复制test.txt的文件路径,粘贴到代码的第24行,注意不要把引号前面的r删掉,如下图
运行代码,如果运行结果如下图且可以在test.txt所在文件夹位置找到result_table则代码已经跑通
打开后如下图,按需将数据摘抄下来即可