复制10%优惠码 【96YF71WTUG】
购买优动漫PAINT(CLIP STUDIO PAINT官方中文正版)
详情请戳:https://www.udongman.cn/index.php?m=product&c=csp
import datetime # 随便给sheet取个名 import math # log及向上取整 import os # 截取路径 import random # 随机 import time # time sleep import tkinter.font as tkFont # 字体设置 import tkinter.ttk # tkinter进度条等骚操作 from decimal import Decimal # 十进制及修约 from itertools import chain # 交错插入 from tkinter import * # UI需要 from tkinter import filedialog # 选择路径需要 import numpy as np # 数学计算包 import openpyxl # excel无损写入sheet import pandas as pd # 科学计算包 from docx import Document # word删除空行 from docx.shared import Mm # 设置图片大小 from docxtpl import DocxTemplate, InlineImage # 模板渲染 from openpyxl.styles import Border, Side # 设置边框及自适应表格大小 from openpyxl.utils import get_column_letter # 设置列宽
# 标准曲线的不确定度
std_origin = [[0.253, 0.506, 1.265, 2.024, 2.530], [102436, 210017, 533276, 796984, 1019877]] # 创建标曲原始x和y序列
test_ar = [0.889, 0.887, 0.889]
test_not = len(test_ar) # 计算试样测试次数
std_not = len(std_origin[0]) # 计算标准点数
vol_b = (std_not * sum([i * j for i, j in zip(std_origin[0], std_origin[1])]) - (sum(std_origin[0]) * sum(std_origin[1]))) / (
len(std_origin[1]) * sum([pow(i, 2) for i in std_origin[1]]) - pow(float(sum(std_origin[1])), 2)) # 计算斜率并转化成十进制
vol_a = average(std_origin[0]) - vol_b * average(std_origin[1]) # 计算截距
vol_ssd = pow(sum([pow((i - j), 2) for i, j in zip(std_origin[0], [vol_b * i + vol_a for i in std_origin[1]])]) / (std_not - 2), 0.5) # 计算残差
std_oup = [(i - vol_a) / vol_b for i in std_origin[0]] # 计算拟合理论x
c_0a = average(test_ar) # 计算试样浓度y均值
c_sa = average(std_origin[0]) # 计算标准理论y均值
getcontext().prec = 3 # 保留三位有效数字并且修约是按照4舍6入5留双
end_u = Decimal.from_float(
pow((pow((c_0a - c_sa), 2) / (sum([pow((i - average(std_oup)), 2) for i in std_oup]) * pow(vol_b, 2)) + (1 / test_not) + (1 / std_not)), 0.5) * vol_ssd) # 计算标准不确定度
std_ur = end_u / Decimal.from_float(average(test_ar)) # 计算相对不确定度
print('标准曲线相对{}%'.format(std_ur * 100))本部分主要低啊用的包为decimal,主要起到的作用并非十进制的计算而是保留数字的修约方式,并非保留小数位数,这个其实还是挺重要的,并且可以明确的是,不进行特别设置的话同样采取的是“四舍六入五留双”的机制,做一个如下的实验:
from decimal import Decimal, getcontext a = Decimal.from_float(0.1) print(a) getcontext().prec = 16 print(a*Decimal.from_float(1)) getcontext().prec = 17 print(a*Decimal.from_float(1)) getcontext().prec = 18 print(a*Decimal.from_float(1)) a = Decimal.from_float(0.1534) print(a) getcontext().prec = 16 print(a*Decimal.from_float(1)) getcontext().prec = 17 print(a*Decimal.from_float(1)) getcontext().prec = 18 print(a*Decimal.from_float(1)) a = Decimal.from_float(0.00001534) print(a) getcontext().prec = 16 print(a*Decimal.from_float(1)) getcontext().prec = 17 print(a*Decimal.from_float(1)) getcontext().prec = 18 print(a*Decimal.from_float(1))
0.1000000000000000055511151231257827021181583404541015625 0.1000000000000000 0.10000000000000001 0.100000000000000006 0.1534000000000000085709217501062084920704364776611328125 0.1534000000000000 0.15340000000000001 0.153400000000000009 0.00001533999999999999881879209073787251327303238213062286376953125 0.00001534000000000000 0.000015339999999999999 0.0000153399999999999988
可以看到,有效位数为16位以内的情况下,使用Decimal.from_float还是可以基本保证精度的,getcontext().prec = 为设置有效数字位数。
其他的进位方式的调整可以看官方文档:
l1 = locals()
l1['tpl' + str(h)] = DocxTemplate(varF_2.get()) # 打开模板
# 要插入的图片1路径
image1_path = varF_3.get()
# 要插入的图片2路径
image2_path = varF_4.get()
# 创建2张图片对象
insert_image1 = InlineImage(l1['tpl' + str(h)], image1_path, width=Mm(30))
insert_image2 = InlineImage(l1['tpl' + str(h)], image2_path, width=Mm(30))
if varF_3.get():
countext = {
'number': paramet0[0][0],
'method': paramet0[0][1],
'name': paramet0[0][2],
'workstd_number': paramet0[0][11],
'sample_weight1': paramet0[0][3],
'sample_weight2': paramet0[0][4],
'zero': paramet0[0][5],
'temperature': paramet0[0][9],
'humidity': paramet0[0][10],
'yyyy': paramet0[0][6],
'mm': paramet0[0][7],
'dd': paramet0[0][8],
'img1': insert_image1,
'img2': insert_image2,
}
# 取出数据组成字典
else:
countext = {
'number': paramet0[0][0],
'method': paramet0[0][1],
'name': paramet0[0][2],
'workstd_number': paramet0[0][11],
'sample_weight1': paramet0[0][3],
'sample_weight2': paramet0[0][4],
'zero': paramet0[0][5],
'temperature': paramet0[0][9],
'humidity': paramet0[0][10],
'yyyy': paramet0[0][6],
'mm': paramet0[0][7],
'dd': paramet0[0][8],
}
for qs in range(1, len(paramet0)):
l1['context' + str(qs)] = {
'parameter{b}'.format(b=qs - 1): '{}'.format(paramet0[qs][0]),
'concentration_name{b}'.format(b=qs - 1): '{}'.format(paramet0[qs][1]),
'content_name{b}'.format(b=qs - 1): '{}'.format(paramet0[qs][2]),
'average_name{b}'.format(b=qs - 1): '{}'.format(paramet0[qs][3]),
'revision_name{b}'.format(b=qs - 1): '{}'.format(paramet0[qs][4]),
'RR_name{b}'.format(b=qs - 1): '{}'.format(paramet0[qs][5]),
'concentration1{b}'.format(b=qs - 1): '{}'.format(paramet0[qs][6]),
'concentration2{b}'.format(b=qs - 1): '{}'.format(paramet0[qs][7]),
'content1{b}'.format(b=qs - 1): '{}'.format(paramet0[qs][8]),
'content2{b}'.format(b=qs - 1): '{}'.format(paramet0[qs][9]),
'average{b}'.format(b=qs - 1): '{}'.format(paramet0[qs][10]),
'revision{b}'.format(b=qs - 1): '{}'.format(paramet0[qs][11]),
'RR{b}'.format(b=qs - 1): '{}'.format(paramet0[qs][12]),
}
countext.update(l1['context' + str(qs)]) # 合并字典
print(countext)
l1['tpl' + str(h)].render(countext) # 执行渲染
l1['tpl' + str(h)].save(file_run + '/' + paramet0[0][0] + '.docx') # 另存
document = Document(file_run + '/' + paramet0[0][0] + '.docx') # 读入文件
tables = document.tables # 获取文件中的表格集
table = tables[0] # 获取文件中的第一个表格
num_sum = [num for num in range(18, len(table.rows) - 3) if not table.cell(num, 1).text] # 记录空行位置
print(num_sum)
# 删除空行↓
for ed in reversed(num_sum):
row = table.rows[ed]
row._element.getparent().remove(row._element)
# 删除空行结束↑
document.save(file_run + '/' + paramet0[0][0] + '.docx')使用的是docxtpl,既然是填写模板,那么就需要一个word的模板,需要渲染的部分使用双花括号括起来,例如代码中“number”这个值需要替换成给定的值,那么模板中相对应的位置应该是写作“{{number}}“。从第66行开始,渲染后的文件需要删除多余的空行,因此采取python-docx进行删除操作。
book_b = openpyxl.load_workbook(r"D:Usersxxxx.xlsx") # 使用openpyxl读取Excel
ws = book_b['2022.11.30_11.27.31'] # 要操作的sheet名
max_rows = ws.max_row # 获取最大行
max_columns = ws.max_column # 获取最大列
borders = Border(left=Side(style='thin'), bottom=Side(style='thin'), right=Side(style='thin'), top=Side(style='thin')) # 设置边框,thin为细边框
for c in range(1, max_rows + 1): # 遍历从1开始至最大行数
for x in range(1, max_columns + 1): # 遍历从1开始至最大列数
ws.cell(c, x).border = borders # 为每一个行的所有列设置边框
# 推导,因openpyxl下标以1开始,因此[取最大值(计算字节数(转化为字符(c,x组成cell的位置的值)使用gbk编码)) x从第一行开始) c从第一列开始] = 最大列宽度
max_col = [max(len(str(ws.cell(row=x, column=c).value).encode('gbk')) for x in range(1, max_rows + 1)) for c in range(1, max_columns + 1)]
# 设置列宽
for r in range(1, ws.max_column + 1):
letter_s = get_column_letter(r) # 将数字转化为列名
ws.column_dimensions[letter_s].width = max_col[r - 1] + 2 # 设置列宽,加两个字节留出一点富余量
book_b.save(r"D:Usersxxxx.xlsx")Copyright © 2022
wuwofcproject.com, All rights reserved
独家内容 未经许可 严禁复制、镜像、转载