电信专业课电子测量学科使用,包括粗大误差处理、肖维纳检验法、莱特检验法、 格拉布斯检验法、累进性误差判断、周期性误差判断及给定置信概率求取置信区间部分。
题目要求:
用C语言或Matlab设计测量数据误差处理的通用程序
(1)提供测试数据输入、粗大误差判别准则选择的人机界面
(2)编写程序使用说明
(3)通过实例来验证程序的正确性
涉及知识
测量误差的分类及特点
随机误差的处理与估计
系统误差的处理
粗大误差的处理
测量数据处理
流程图
import tkinterimport tkinter.messageboximport mathimport copy# t分布积分表table1_row = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30, 40, 60, 120]table1_col = [50, 60, 70, 80, 90, 95, 98, 99, 999]table1 = [[1.000, 1.376, 1.936, 3.078, 6.314, 12.706, 31.821, 63.657, 636.619],[0.816, 1.061, 1.386, 1.886, 2.920, 4.303, 6.965, 9.925, 31.598],[0.765, 0.978, 1.250, 1.638, 2.353, 3.182, 4.541, 5.841, 12.924],[0.741, 0.941, 1.190, 1.553, 2.132, 2.776, 3.747, 4.604, 8.610],[0.727, 0.920, 1.156, 1.476, 2.015, 2.571, 3.365, 4.032, 6.859],[0.718, 0.906, 1.134, 1.440, 1.943, 2.447, 3.143, 3.707, 5.959],[0.711, 0.896, 1.119, 1.415, 1.895, 2.365, 2.998, 3.499, 5.405],[0.706, 0.889, 1.108, 1.397, 1.860, 2.306, 2.896, 3.355, 5.041],[0.703, 0.883, 1.100, 1.383, 1.833, 2.262, 2.821, 3.250, 4.781],[0.700, 0.879, 1.093, 1.372, 1.812, 2.228, 2.764, 3.169, 4.587],[0.691, 0.866, 1.074, 1.341, 1.753, 2.131, 2.602, 2.947, 4.073],[0.687, 0.860, 1.064, 1.325, 1.725, 2.086, 2.528, 2.845, 3.850],[0.684, 0.856, 1.058, 1.316, 1.708, 2.06, 2.485, 2.787, 3.725],[0.683, 0.854, 1.055, 1.310, 1.697, 2.042, 2.457, 2.750, 3.646],[0.681, 0.851, 1.050, 1.303, 1.684, 2.021, 2.423, 2.704, 3.551],[0.679, 0.848, 1.046, 1.296, 1.671, 2.000, 2.390, 2.660, 3.460],[0.677, 0.845, 1.041, 1.289, 1.658, 1.980, 2.358, 2.617, 3.373]]# 肖维纳准则表table2 = [1.65, 1.73, 1.79, 1.86, 1.92, 1.96, 2, 2.04, 2.07, 2.1, 2.13, 2.16, 2.18, 2.2, 2.22, 2.24, 2.26, 2.28, 2.3,2.32, 2.33, 2.34, 2.35, 2.37, 2.38, 2.39, 2.45, 2.5, 2.58, 2.64, 2.74, 2.81, 3.02]# 格拉布斯准则表table3_95 = [1.15, 1.46, 1.67, 1.82, 1.94, 2.03, 2.11, 2.18, 2.23, 2.29, 2.33, 2.37, 2.41, 2.44, 2.47, 2.5, 2.53, 2.56,2.58, 2.60, 2.62, 2.64, 2.66]table3_99 = [1.16, 1.49, 1.75, 1.94, 2.1, 2.22, 2.32, 2.41, 2.48, 2.55, 2.61, 2.66, 2.71, 2.75, 2.79, 2.82, 2.85, 2.88,2.91, 2.94, 2.96, 2.99, 3.01]# 平均值def average(data):sum_num = 0.0for i in data:sum_num += ireturn sum_num / len(data)# 方差def variance(data):aver = average(data)sum_num = 0for i in data:sum_num += (i - aver) ** 2return math.sqrt(sum_num / len(data) / (len(data) - 1))# 累进性系统误差判断def system_error1(data):aver = average(data)max_num = abs(data[0] - aver)for i in data:if max_num < abs(i - aver):max_num = abs(i - aver)sum1 = sum2 = 0for i in range(len(data) // 2 - 1):sum1 += abs(data[i] - aver)for i in range(len(data) // 2, len(data)):sum2 += abs(data[i] - aver)if abs(sum1 - sum2) >= max_num:return "测量中存在累进性系统误差!"else:return "测量中无累进性系统误差"# 周期性系统误差判断def system_error2(data):aver = average(data)num = (variance(data) * math.sqrt(len(data))) ** 2 # 标准偏差的平方sum_num = 0for i in range(len(data) - 1):sum_num += (data[i] - aver) * (data[i + 1] - aver)sum_num = abs(sum_num)if sum_num > num * math.sqrt(len(data) - 1):return "测量中存在周期性系统误差"else:return "测量中无周期性系统误差"# 剔除坏值def cull(data, num):while True:varian = variance(data)aver = average(data)length = len(data)for i in data:if abs(i - aver) > num * varian * math.sqrt(length):data.remove(i)breakif len(data) == length:breakreturn data# 莱特检验法剔除坏值def check1(data):return cull(data, 3)# 肖维纳检验法剔除坏值def check2(data):if len(data) < 5:print("数据少于5个!不能使用肖维纳检验法")returnch = table2[len(data) - 5]return cull(data, ch)# 格拉布斯检验法剔除坏值def check3(data, choose):if len(data) < 3:print("数据少于3个!不能使用格拉布斯检验法")returnif choose == 95:g = table3_95[len(data) - 3]elif choose == 99:g = table3_99[len(data) - 3]return cull(data, g)# 根据k和p查看置信系数def find1(k, p):row = Nonecol = Nonetry:for i in range(len(table1_row)):if table1_row[i] == k:row = ibreakfor i in range(len(table1_col)):if table1_col[i] == p:col = ibreakreturn table1[row][col]except TypeError:Tax3.insert(tkinter.END, "所查找的值不在表\n")# 根据p求置信空间def solve_range(data, p):aver = average(data)varian = variance(data)try:t = find1(len(data) - 1, p)min_num = aver - t*varianmax_num = aver + t*varianreturn [min_num, max_num]except:return None# 根据置信空间求pdef solve_chance(data, min_num=None):aver = average(data)varian = variance(data)t = (aver - min_num) / varianreturn t# 剔除坏值的检验法选择def select1():if var1.get() == -1:var2.set(0)# 剔除坏值的置信概率选择def select2():if var2.get() == 0:var1.set(-1)def main():Tax3.delete(0.0, tkinter.END)# 获得输入数据,并转换为列表data_original = var.get()data_original = data_original.strip()data_original = data_original.split(',')for i in range(len(data_original)):data_original[i] = data_original[i].strip()data_original[i] = float(data_original[i])# 深拷贝原始数据data_new = copy.deepcopy(data_original)# 剔除坏值过程,choose11为用户的选择choose11 = var1.get()if choose11 == 0:data_new = check1(data_new)elif choose11 == 1:data_new = check2(data_new)elif choose11 == 2:data_new = check3(data_new, var2.get())else:pass# 求解置信区间或置信概率choose21 = var4.get()if choose21 == 0:p = int(var5.get())result_range = solve_range(data_new, p)elif choose21 == 1:num1 = float(var5.get())result_t = solve_chance(data_new, num1)# 数据的转换,都转换为字符串aver1 = str(round(average(data_original), 3))vari1 = str(round(variance(data_original), 3))piancha1 = str(round((variance(data_original) * math.sqrt(len(data_original))), 3))aver2 = str(round(average(data_new), 3))vari2 = str(round(variance(data_new), 3))piancha2 = str(round((variance(data_new) * math.sqrt(len(data_new))), 3))str1 = system_error1(data_new)str2 = system_error2(data_new)# 把列表转换为字符串for i in range(len(data_original)):data_original[i] = str(data_original[i])for i in range(len(data_new)):data_new[i] = str(data_new[i])data_original = ", ".join(data_original)data_new = ", ".join(data_new)Tax3.insert(tkinter.END, "测量数据:" + data_original + "\n")Tax3.insert(tkinter.END, "测量数据的均值:" + aver1 + "\n")Tax3.insert(tkinter.END, "测量数据的标准偏差:" + vari1 + "\n")Tax3.insert(tkinter.END, "测量数据的方差:" + piancha1 + "\n")if var1.get() != -1:Tax3.insert(tkinter.END, "剔除坏值后测量数据:" + data_new + "\n")Tax3.insert(tkinter.END, "剔除坏值后测量数据的均值:" + aver2 + "\n")Tax3.insert(tkinter.END, "剔除坏值后测量数据的标准偏差:" + vari2 + "\n")Tax3.insert(tkinter.END, "剔除坏值后测量数据的方差:" + piancha2 + "\n")if var4.get() == 0:try:zuo = str(round(result_range[0], 3))you = str(round(result_range[1], 3))except:Tax3.insert(tkinter.END, "所输入数据的自由度不在列表中,无法计算置信区间!\n")else:Tax3.insert(tkinter.END, "置信区间为:[" + zuo + ", " + you + "]\n")if var4.get() == 1:Tax3.insert(tkinter.END, "求出的t值为:" + str(round(result_t, 4)) + "\n")if var3.get() == 1:Tax3.insert(tkinter.END, str1 + "\n")Tax3.insert(tkinter.END, str2)if __name__ == "__main__":window = tkinter.Tk()window.title("测量数据误差处理程序")window.geometry("900x700")window.resizable(height=False, width=False)# 窗口标题Lab1 = tkinter.Label(window, text="测量数据误差处理程序", font=("", 25))Lab1.place(x=250, y=0)# 输入数据提示及输入文本框var = tkinter.StringVar()var.set("")Lab2 = tkinter.Label(window, text="输入数据[数据,数据,...]:", font=("", 15))Lab2.place(x=3, y=60)Tax1 = tkinter.Entry(window, textvariable=var, width=125, font=("", 12))Tax1.place(x=3, y=90)# 误差处理的选择Lab3 = tkinter.Label(window, text="误差处理方式:", font=("", 15))Lab3.place(x=3, y=150)# 选择剔除的检验法(单选)Lab4 = tkinter.Label(window, text="剔除坏值检验法", font=("", 10))Lab4.place(x=30, y=190)var1 = tkinter.IntVar()var1.set(-1)Rbt1_1 = tkinter.Radiobutton(window, text="莱特检验法", variable=var1, value=0, command=select1)Rbt1_2 = tkinter.Radiobutton(window, text="肖维纳检验法", variable=var1, value=1, command=select1)Rbt1_3 = tkinter.Radiobutton(window, text="格布拉斯检验法", variable=var1, value=2, command=select1)Rbt1_4 = tkinter.Radiobutton(window, text="不进行坏值剔除", variable=var1, value=-1, command=select1)Rbt1_1.place(x=30, y=210)Rbt1_2.place(x=100, y=210)Rbt1_3.place(x=170, y=210)Rbt1_4.place(x=240, y=210)# 选择剔除坏值的置信概率Lab5 = tkinter.Label(window, text="剔除坏值置信概率", font=("", 10))Lab5.place(x=30, y=240)var2 = tkinter.IntVar()var2.set(0)Rbt2_1 = tkinter.Radiobutton(window, text="95%", variable=var2, value=95, command=select2)Rbt2_2 = tkinter.Radiobutton(window, text="99%", variable=var2, value=99, command=select2)Rbt2_3 = tkinter.Radiobutton(window, text="不进行坏值剔除", variable=var2, value=0, command=select2)Rbt2_1.place(x=30, y=260)Rbt2_2.place(x=100, y=260)Rbt2_3.place(x=170, y=260)# 选择是否进行系统误差检测Lab6 = tkinter.Label(window, text="是否进行系统误差检测", font=("", 10))Lab6.place(x=30, y=290)var3 = tkinter.IntVar()var3.set(0)Rbt3_1 = tkinter.Radiobutton(window, text="是", variable=var3, value=1)Rbt3_2 = tkinter.Radiobutton(window, text="否", variable=var3, value=0)Rbt3_1.place(x=30, y=310)Rbt3_2.place(x=100, y=310)# 选择求置信概率还是置信区间Lab7 = tkinter.Label(window, text="求置信概率还是置信区间", font=("", 10))Lab7.place(x=30, y=340)var4 = tkinter.IntVar()var4.set(0)Rbt4_1 = tkinter.Radiobutton(window, text="置信概率", variable=var4, value=1)Rbt4_2 = tkinter.Radiobutton(window, text="置信区间", variable=var4, value=0)Rbt4_1.place(x=30, y=360)Rbt4_2.place(x=100, y=360)# 输入文本框(置信概率或置信区间)Lab8 = tkinter.Label(window, text="请输入置信概率(求置信区间)\n(求置信概率,给出t值,自行查表)\n格式为:""50(表示50%置信概率)", font=("", 10))Lab8.place(x=3, y=400)var5 = tkinter.StringVar()var5.set("")Tax2 = tkinter.Entry(window, textvariable=var5, width=25, font=("", 12))Tax2.place(x=30, y=450)# 输出Btn1 = tkinter.Button(window, text="运行", font=("", 20), command=main)Btn1.place(x=70, y=510)Tax3 = tkinter.Text(window, width=65, height=40)Tax3.place(x=400, y=150)window.mainloop()
程序运行
界面板块:
数据输入板块——输入数据,以“,”分割
误差处理方式选择板块——选择检验法与置信概率等必要选项
运行板块——点击运行按钮执行程序
输出板块——输出误差处理结果
个人水平有限,仅限于大学学习内容,希望对各位有所帮助。
如果觉得《电子测量技术——基于Python的测量数据误差处理程序》对你有帮助,请点赞、收藏,并留下你的观点哦!