密立根油滴仪测油滴电荷数据计算 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则代码已经跑通

打开后如下图,按需将数据摘抄下来即可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值