非常无语的,同济大一什么物理理论都没学,需要的高数基础也都没有学过,竟然要我们先学物理实验,而且要处理数据,计算平均值和标准误差什么的,十分麻烦……
上次处理数据弄了个零碎的小程序来,很麻烦,这次就把他统一编为一个模块,方便以后使用……这个模块里面的说有公式依据是同济大学出版社《物理实验教程》第1版第二章的内容。
如何使用这个模块呢?首先,作为一个 Python 模块,肯定要用 Python……
直接输入数据,标准格式输出~
最后是代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | #!/usr/bin/env python # -*- coding: utf-8 -*- import math sqrt = math.sqrt def gen_imet(func): def retfunc(self, other): ret = func(self, other) self.ave = ret.ave self.u = ret.u self.digs = ret.digs return self return retfunc def get_digs(a, b): if a == 0: return b elif b == 0: return a else: return min(a, b) class PhyStat: """ 物理实验数据 PhyStat(ave, u = 0.0, digs = 0) ave 表示平均值,如果传入一列数则自动计算平均值及其标准误差 u 表示标准误差,如果 ave 传入数据列表则此处表示仪器精度 digs 表示有效数字个数,0 表示不限制 """ def __init__(self, ave, u = 0.0, digs = 0): """ 对于 ave 为数据列表的情况,使用下面公式计算平均值: ave = Σx[i] / n 根据下面公式计算标准误差: S = Sqrt(Σ(x[i]-ave)^2 / (n - 1)) u = Δinst / Sqrt(3) U = Sqrt(S^2 + u^2) """ self.digs = digs if isinstance(ave, tuple) or isinstance(ave, list): data = ave n = len(data) ave = math.fsum(ave) / n self.ave = ave s = 0.0 for i in data: s += (i - ave) ** 2 s = sqrt(s / (n - 1)) u /= sqrt(3) self.u = sqrt(s ** 2 + u ** 2) else: self.ave = float(ave) self.u = abs(float(u)) def __repr__(self): ave = self.ave exp = int(math.floor(math.log10(ave))) exp10 = 10 ** exp ave = ave / exp10 u = self.u / exp10 digs = self.digs if digs == 0: ret = '%f ±%f' else: ret = '%%.%df ±%%.%df' % (digs, digs) if exp: ret = '(%s) E %d' % (ret, exp) return ret % (ave, u) __neg__ = lambda self: PhyStat(-self.ave, self.u, self.digs) __pos__ = lambda self: self __abs__ = lambda self: PhyStat(abs(self.ave), self.u, self.digs) def __add__(self, other): if isinstance(other, PhyStat): ave = self.ave + other.ave u = sqrt(self.u ** 2 + other.u ** 2) digs = get_digs(self.digs, other.digs) return PhyStat(ave, u, digs) else: ave = self.ave + other return PhyStat(ave, self.u, self.digs) __radd__ = __add__ __sub__ = lambda self, other: self + (-other) __rsub__ = lambda self, other: other + (-self) def __mul__(self, other): if isinstance(other, PhyStat): a = self.ave b = other.ave ave = a * b u = ave * sqrt((self.u / a) ** 2 + (other.u / b) ** 2) digs = get_digs(self.digs, other.digs) return PhyStat(ave, u, digs) else: ave = self.ave * other u = self.u * other return PhyStat(ave, u, self.digs) __rmul__ = __mul__ def __div__(self, other): if isinstance(other, PhyStat): return self * other ** -1 else: return (1.0 / other) * self __rdiv__ = lambda self, other: other * self ** -1 def __pow__(self, other): a = self.ave ave = a ** other u = abs(other * self.u / a * ave) return PhyStat(ave, u, self.digs) __iadd__ = gen_imet(lambda self, other: self + other) __isub__ = gen_imet(lambda self, other: self - other) __imul__ = gen_imet(lambda self, other: self * other) __idiv__ = gen_imet(lambda self, other: self / other) __ipow__ = gen_imet(lambda self, other: self ** other) __int__ = lambda self: int(self.ave) __long__ = lambda self: long(self.ave) __float__ = lambda self: self.ave |
如果大家发现什么 bug,或者有什么改进建议,欢迎提哈~

可否加一个链接?
什么链接?
建议:
1)外部数据文件输入,如netcdf hdf格式支持
2)可以用blade 做界面
3)matplotlib 等图像输出
您好,感谢您的建议,但我不准备对这一程序做进一步完善。如果您对此有兴趣,可以在此程序发布协议(GPLv3)的约定下自行修改和完善该程序~