gpt-4o继续迭代考场安排程序 一键生成考场清单
接上两篇gpt-4o考场安排-CSDN博客,考场分层次安排,最终exe版-CSDN博客
当然你也可以只看这一篇。
今天又添加了以下功能,程序见后。
1、自动分页,每个考场打印一页
2、添加了打印试场单页眉
3、添加了页脚 第X页,其X页, 打印时间
表结构
程序运行界面
测试分配考场环境,共15个班分为两个层次由字段“层次”指定a, b。a层次9个考场,b层次15个,从b层开始编号,a层次考场号从16开编。
预览结果b层次
层次a预览结果
完整程序
import sysimport pandas as pdimport randomimport openpyxlfrom openpyxl.worksheet.pagebreak import Breakfrom openpyxl.styles import Font, Alignment, PatternFill, Border, Sidefrom openpyxl.worksheet.page import PageMarginsfrom datetime import datetimefrom PyQt5.QtWidgets import (QApplication, QLabel, QLineEdit, QPushButton, QFileDialog,QVBoxLayout, QWidget, QMessageBox)from PyQt5.QtGui import QFont as QPyQtFontdef load_data(filename):return pd.read_excel(filename)def save_data(df, filename, exam_name):df.to_excel(filename, index=False)format_excel(filename, df, exam_name)def assign_seats(df, total_halls, start_hall=1):grouped = df.groupby('班级')groups = [group.sample(frac=1).reset_index(drop=True) for _, group in grouped]groups.sort(key=lambda x: len(x), reverse=True)iterators = [iter(group.iterrows()) for group in groups]arranged_data = []hall_number = start_hallseat_number = 1total_students = len(df)students_per_hall = total_students // total_hallsextra_students = total_students % total_hallswhile iterators:random.shuffle(iterators)for it in iterators[:]:try:_, student = next(it)student_data = student.to_dict()student_data["考场"] = hall_numberstudent_data["考号"] = f"{seat_number:02d}"arranged_data.append(student_data)seat_number += 1if seat_number > students_per_hall + (1 if hall_number - start_hall + 1 <= extra_students else 0):hall_number += 1seat_number = 1if hall_number >= start_hall + total_halls:hall_number = start_hallexcept StopIteration:iterators.remove(it)return arranged_datadef check_and_adjust_seating(arranged_data):def has_adjacent_same_class(data):for i in range(len(data) - 1):if data[i]['班级'] == data[i + 1]['班级']:return ireturn -1def find_valid_swap(index, data):current_class = data[index]['班级']for j in range(len(data)):if j != index and data[j]['班级'] != current_class:if (j == 0 or data[j - 1]['班级'] != current_class) and (j == len(data) - 1 or data[j + 1]['班级'] != current_class):return jreturn -1swap_operations = []while True:index = has_adjacent_same_class(arranged_data)if index == -1:breakswap_index = find_valid_swap(index + 1, arranged_data)if swap_index == -1:raise ValueError("Cannot find a valid swap to adjust the seating arrangement.")swap_operations.append((index + 1, swap_index))arranged_data[index + 1], arranged_data[swap_index] = arranged_data[swap_index], arranged_data[index + 1]return arranged_data, swap_operationsdef reassign_seats(arranged_data, total_halls, start_hall=1):hall_number = start_hallseat_number = 1total_students = len(arranged_data)students_per_hall = total_students // total_hallsextra_students = total_students % total_hallsfor i, student in enumerate(arranged_data):student['考场'] = hall_numberstudent['考号'] = f"{seat_number:02d}"seat_number += 1if seat_number > students_per_hall + (1 if hall_number - start_hall + 1 <= extra_students else 0):hall_number += 1seat_number = 1if hall_number >= start_hall + total_halls:hall_number = start_hallreturn arranged_datadef format_excel(filename, df, exam_name):if '层次' in df.columns:df = df.drop(columns=['层次'])wb = openpyxl.Workbook()ws = wb.activews.title = "考场安排结果"# 将标题从第一行开始写入for col_num, column_title in enumerate(df.columns, 1):cell = ws.cell(row=1, column=col_num, value=column_title)cell.font = Font(bold=True, color="FFFFFF", size=16)cell.fill = PatternFill(start_color="4F81BD", end_color="4F81BD", fill_type="solid")cell.alignment = Alignment(horizontal="center", vertical="center")for row_num, row_data in enumerate(df.itertuples(index=False, name=None), 2):for col_num, cell_value in enumerate(row_data, 1):ws.cell(row=row_num, column=col_num, value=cell_value)for col in ws.columns:max_length = 0column = col[0].column_letter# Check if the column header is "考号"if ws.cell(row=1, column=col[0].col_idx).value == "考号":adjusted_width = 20 # 设置考号列的宽度为20else:for cell in col:if cell.value is not None:max_length = max(max_length, len(str(cell.value)))adjusted_width = max_length + 10ws.column_dimensions[column].width = adjusted_width# 调整页面边距ws.page_margins = PageMargins(left=1.5, right=0.75, top=1.2, bottom=0.5)ws.print_title_rows = '1:1' # 标题行在第一行开始ws.page_setup.orientation = 'portrait'ws.page_setup.paperSize = ws.PAPERSIZE_A4ws.page_setup.fitToPage = Truews.page_setup.fitToWidth = 1ws.page_setup.fitToHeight = Falsews.page_setup.horizontalCentered = Truews.page_setup.verticalCentered = Truepage_height_in_inches = 11.69 - ws.page_margins.top - ws.page_margins.bottompage_height_in_points = page_height_in_inches * 72header_height_in_points = 50available_row_height_in_points = page_height_in_points - header_height_in_pointshall_groups = df.groupby('考场')previous_max_row = 1 # 前一个最大行号调整为1以考虑空行thin_border = Border(left=Side(style='thin'), right=Side(style='thin'), top=Side(style='thin'), bottom=Side(style='thin'))for hall_number, (hall_id, hall_df) in enumerate(hall_groups):row_count = len(hall_df) + 1max_row = hall_df.index[-1] + 2 # 从第二行开始每个考场的数据row_height = available_row_height_in_points / row_countrow_height = max(row_height, 15)for row in range(previous_max_row, max_row + 1):ws.row_dimensions[row].height = row_heightfor cell in ws[row]:cell.border = thin_bordercell.font = Font(size=15)cell.alignment = Alignment(horizontal="center", vertical="center")if max_row < ws.max_row:ws.row_breaks.append(Break(max_row))previous_max_row = max_row + 1# 添加页眉和页脚,并使用制表符来向左移动页眉ws.oddHeader.center.text = f"&\"微软雅黑,Bold\"&20\t{exam_name}" # 添加制表符以向左移动ws.oddFooter.center.text = "第 &P 页,共 &N 页"ws.oddFooter.right.text = f"&D &T"wb.save(filename)def dataframe_to_rows(df, index=True, header=True):if header:rows = [list(df.columns)]else:rows = [[]]for row in df.itertuples(index=index, name=None):rows.append(list(row)[1:])return rowsdef run_allocation(input_filename, a_total_halls, b_total_halls, start_level, exam_name):df = load_data(input_filename)if start_level == 'b':other_level = 'a'first_total_halls = b_total_hallssecond_total_halls = a_total_hallselse:other_level = 'b'first_total_halls = a_total_hallssecond_total_halls = b_total_hallsfirst_level_students = df[df['层次'] == start_level]arranged_first_students = assign_seats(first_level_students, first_total_halls, start_hall=1)adjusted_first_students, _ = check_and_adjust_seating(arranged_first_students)final_first_students = reassign_seats(adjusted_first_students, first_total_halls, start_hall=1)second_level_students = df[df['层次'] == other_level]arranged_second_students = assign_seats(second_level_students, second_total_halls, start_hall=first_total_halls + 1)adjusted_second_students, _ = check_and_adjust_seating(arranged_second_students)final_second_students = reassign_seats(adjusted_second_students, second_total_halls,start_hall=first_total_halls + 1)combined_students = final_first_students + final_second_studentsarranged_df = pd.DataFrame(combined_students)current_time = datetime.now().strftime("%Y%m%d_%H%M%S")output_filename = f"考场安排结果_{current_time}.xlsx"save_data(arranged_df, output_filename, exam_name)return output_filenameclass ExamArrangementApp(QWidget):def __init__(self):super().__init__()self.initUI()def initUI(self):layout = QVBoxLayout()font = QPyQtFont("Arial", 14)self.file_label = QLabel('选择文件:')self.file_label.setFont(font)layout.addWidget(self.file_label)self.file_btn = QPushButton('选择文件')self.file_btn.setFont(font)self.file_btn.clicked.connect(self.select_file)layout.addWidget(self.file_btn)self.exam_name_label = QLabel('考试名称:')self.exam_name_label.setFont(font)layout.addWidget(self.exam_name_label)self.exam_name_input = QLineEdit()self.exam_name_input.setFont(font)layout.addWidget(self.exam_name_input)self.a_halls_label = QLabel('A层次考场数:')self.a_halls_label.setFont(font)layout.addWidget(self.a_halls_label)self.a_halls_input = QLineEdit()self.a_halls_input.setFont(font)layout.addWidget(self.a_halls_input)self.b_halls_label = QLabel('B层次考场数:')self.b_halls_label.setFont(font)layout.addWidget(self.b_halls_label)self.b_halls_input = QLineEdit()self.b_halls_input.setFont(font)layout.addWidget(self.b_halls_input)self.start_level_label = QLabel('首先开始编号的层次 (a/b):')self.start_level_label.setFont(font)layout.addWidget(self.start_level_label)self.start_level_input = QLineEdit()self.start_level_input.setFont(font)layout.addWidget(self.start_level_input)self.run_btn = QPushButton('运行')self.run_btn.setFont(font)self.run_btn.clicked.connect(self.run)layout.addWidget(self.run_btn)self.setLayout(layout)self.setWindowTitle('考场安排工具,By Bobo googaobo@gmail.com')self.resize(900, 630)self.center()def select_file(self):options = QFileDialog.Options()options |= QFileDialog.DontUseNativeDialogfile_name, _ = QFileDialog.getOpenFileName(self, "选择Excel文件", "", "Excel Files (*.xlsx);;All Files (*)",options=options)if file_name:self.file_label.setText(f'文件: {file_name}')self.input_filename = file_namedef run(self):try:a_total_halls = int(self.a_halls_input.text())b_total_halls = int(self.b_halls_input.text())start_level = self.start_level_input.text()exam_name = self.exam_name_input.text()output_filename = run_allocation(self.input_filename, a_total_halls, b_total_halls, start_level, exam_name)QMessageBox.information(self, "成功", f"已成功生成文件:{output_filename}", QMessageBox.Ok)except Exception as e:QMessageBox.critical(self, "错误", str(e), QMessageBox.Ok)def center(self):qr = self.frameGeometry()cp = self.screen().availableGeometry().center()qr.moveCenter(cp)self.move(qr.topLeft())if __name__ == '__main__':app = QApplication(sys.argv)ex = ExamArrangementApp()ex.show()sys.exit(app.exec_())
程序已打包exe,点赞留言QQ,发送程序。程序运行中有问题请评论区留言交流!!!
相关文章:

gpt-4o继续迭代考场安排程序 一键生成考场清单
接上两篇gpt-4o考场安排-CSDN博客,考场分层次安排,最终exe版-CSDN博客 当然你也可以只看这一篇。 今天又添加了以下功能,程序见后。 1、自动分页,每个考场打印一页 2、添加了打印试场单页眉 3、添加了页脚 第X页,…...

php 设置时区
date_default_timezone_set() 设置所有日期/时间函数使用的默认时区 除了在脚本中使用此函数设置默认时区,还可以使用 INI 设置 date.timezone 设置默认时区。 参数 timezoneId 时区标识符,像 UTC、Africa/Lagos、Asia/Hong_Kong 或 Europe/Lisbon。…...
ArcGIS不同图斑设置不同的透明度
对于设置一个图层的整体的透明度,我们在 ArcGIS制作带蒙版的遥感影像地图http://mp.weixin.qq.com/s?__bizMzIzNjM2NTYxMg&mid2247509080&idx1&sn38dccf0a52bb3bb3758f57114ee38b72&chksme8da161bdfad9f0d363da90959a8524dcf2b60d0e8d999f8ebeef0…...

前端 CSS 经典:图片边框
前言:有这么一个业务,需要边框随着图片宽度的变化而变化,比如一些聊天的气泡框等。 实现原理:使用 border-image 属性 效果图: 实现代码: <!DOCTYPE html> <html lang"en"><he…...

异常有什么,异常类有什么
在Java中,异常(Exception)是一种在程序运行过程中出现的不正常情况。异常机制提供了一种从错误中恢复的途径。异常分为两大类:检查异常(Checked Exception)和运行时异常(Runtime Exception&…...

如何解压忘记了密码的加密zip压缩包?这两个方法收藏好!
加密是一种保护信息不被未经授权访问的重要手段。ZIP压缩包作为一种常见的文件压缩格式,zip文件加密是很多人都回去做的一件事情,那么zip加密文件如何解密?有几种方法可以解密呢?今天介绍几种方法给大家。 一、尝试常用密码 我们…...

java中,怎样用最简单方法实现写word文档
在跨平台环境中实现写word时,如果用现成的库,就会涉及跨平台兼容性问题,比如在安卓与java中实现写word的功能。还有一个问题就是,完全用程序生成word文档,工作量较大。所以采用了模板替换的方法。 docx文档本质就是一…...

大语言模型的工程技巧(三)——分布式计算
相关说明 这篇文章的大部分内容参考自我的新书《解构大语言模型:从线性回归到通用人工智能》,欢迎有兴趣的读者多多支持。 本文将讨论如何利用多台机器进行神经网络的分布式训练。利用多台机器来加速大语言模型的训练,是其获得成功的重要原…...

AI开发初体验:昇腾加持,OrangePi AIpro 开发板
文章目录 一、前言二、板子介绍2.1 拆箱2.2 板子规格2.2.1 常规项目2.2.2 扩展项目2.2.3 操作系统 2.3 点板画面 三、AI程序初体验3.1 新奇的地方3.2 运行第一个AI程序3.2.1 硬件连接3.2.2 串口连接3.2.3 开启外部IP端口3.2.4 查询板子IP地址3.2.5 了解 juypter lab 启动脚本&a…...

微服务架构下Docker容器技术与Kubernetes(K8S)
Kubernetes、微服务和Docker容器技术的结合提供了一个强大、灵活且高效的平台,能够应对现代应用程序的复杂性和动态性。Kubernetes的自动化管理、服务发现、负载均衡和配置管理,与Docker的标准化打包和运行环境相结合,最大化地发挥了微服务架…...

风萧萧兮易水寒,壮士一去兮不复还 的 rm 命令
风萧萧兮易水寒,壮士一去兮不复还 的 rm 命令 风萧萧兮易水寒,壮士一去兮不复还 的 rm语法几个示例/bin/rm Argument list too long – Linux”配合find与xargs完成删除海量文件使用find的delete选项 快速删除大文件 风萧萧兮易水寒,壮士一去…...

How Diffusion Models Work
introduction intuition goal 让神经网络学到图像是什么样的,一种方式是对数据添加不同级别的噪音,让神经网络能够区分细节/总体轮廓 训练一个神经网络去产生精灵 sampling nn 图像恢复 论文 https://zhuanlan.zhihu.com/p/686235079...

antd table列选中效果实现
前言 开发中有一个需要呈现不同时间点各个气象要素的值需求,我觉得一个table可以实现这类数据的展示,只是因为时间点时关注的重点,所以需要列选中效果,清晰的展示时间点下的要素数据。我选择的是antd的table组件,这个…...

Golang实现文件复制
方法:三种 package zdpgo_fileimport ("errors""io""os" )// CopyFile 使用io.Copy进行文件的复制,同时也会复制文件的所有权限 // param src 复制文件 // param des 目标文件 // return error 错误信息 func CopyFile(s…...

探秘SpringBoot默认线程池:了解其运行原理与工作方式(@Async和ThreadPoolTaskExecutor)
文章目录 文章导图Spring封装的几种线程池SpringBoot默认线程池TaskExecutionAutoConfiguration(SpringBoot 2.1后)主要作用优势使用场景如果没有它 2.1版本以后如何查看参数方式一:通过Async注解--采用ThreadPoolTaskExecutordetermineAsync…...

kubernetes(Jenkins、kubernetes核心、K8s实战-KubeSphere、)
文章目录 1. Jenkins1.1. 概述1.1.1. 简单部署1.1.2. 自动化部署1.1.3. DevOps概述1.1.4. CI/CD概述 1.2. jenkins介绍及安装1.2.1. 安装1.2.2. 解锁jenkins1.2.3. 安装推荐插件1.2.4. 创建管理员用户1.2.5. 升级jenkins版本1.2.6. 安装额外插件blue ocean1.2.7. jenkins界面说…...

国际数字影像产业园|科技与文创产品创意集市,共筑创新文化新高地
5月29日,为进一步增强园区与企业之间粘性,不断激发企业的创新活力,园区举办了“数媒大厦科技与文创产品创意集市活动”。本次活动由成都树莓信息技术有限公司主办,成都目莓商业管理有限公司、树莓科技(成都)…...

leetcode-55 跳跃游戏
leetcode Problem: 55. 跳跃游戏 思路 假设我们是一个小人,从第一个下标开始,每次经过一个位置,我们就可以根据当前位置的数值nums[i]和位置下标i计算出该位置所能到达的后续位置的最大值rnums[i]i。而这个r之前的区域一定都是可以经过的。…...

Vue——计算属性 computed 与方法 methods 区别探究
文章目录 前言计算属性的由来方法实现 计算属性 同样的效果计算属性缓存 vs 方法 前言 在官方文档中,给出了计算属性的说明与用途,也讲述了计算属性与方法的区别点。本篇博客只做自己的探究记录,以官方文档为准。 vue 计算属性 官方文档 …...

Java中的ORM框架——myBatis
一、什么是ORM ORM 的全称是 Object Relational Mapping。Object代表应用程序中的对象,Relational表示的是关系型数据库,Mapping即是映射。结合起来就是在程序中的对象和关系型数据库之间建立映射关系,这样就可以用面向对象的方式,…...

vue2生命周期和计算属性
vue2的生命周期 删除一些没用的 App.vue 删成这个样子就行 <template><router-view/></template><style lang"scss"></style>来到路由把没用的删除 import Vue from vue import VueRouter from vue-router import HomeView from .…...

Hadoop3:MapReduce之简介、WordCount案例源码阅读、简单功能开发
一、概念 MapReduce是一个 分布式运算程序 的编程框架,是用户开发“基于 Hadoop的数据分析 应用”的核心框架。 MapReduce核心功能是将 用户编写的业务逻辑代码 和 自带默认组件 整合成一个完整的 分布式运算程序 ,并发运行在一个 Hadoop集群上。 1、M…...

centos8stream 编译安装 php-rabbit-mq模块
官方GitHub:https://github.com/php-amqp/php-amqp 环境依赖安装 dnf install cmake make -y 1.安装rabbitmq-c cd /usr/local/src/ wget https://github.com/alanxz/rabbitmq-c/archive/refs/tags/v0.14.0.tar.gz tar xvf v0.14.0.tar.gz cd rabbitmq-c-0.14.0/…...

「异步魔法:Python数据库交互的革命」(二)
哈喽,我是阿佑,上篇文章带领了大家跨入的异步魔法的大门——Python数据库交互,一场魔法与技术的奇幻之旅! 从基础概念到DB-API,再到ORM的高级魔法,我们一步步揭开了数据库操作的神秘面纱。SQLAlchemy和Djan…...

php正则中的i,m,s,x,e分别表示什么
正则表达式模式修饰符(也称为标志或模式修饰符)用于改变正则表达式的行为。这些修饰符可以附加在正则表达式的定界符之后,通常为正斜杠(/)或井号(#),以改变搜索或替换的方式。 1、i…...

最新!2023年台湾10米DEM地形瓦片数据
上次更新谷歌倾斜摄影转换生成OSGB瓦片V1.1版本,使用该版本生产了台北、台中、桃园三个地方的倾斜摄影OSGB数据,在OSGB可视化软件中进行展示,可视化效果和加载效率俱佳。已经很久没更新地形瓦片数据,主要是热点地区的原始数据没有…...

网络学习(11) |深入解析客户端缓存与服务器缓存:HTTP缓存控制头字段及优化实践
文章目录 客户端缓存与服务器缓存的区别客户端缓存浏览器缓存应用程序缓存优点缺点 服务器缓存优点缺点 HTTP缓存控制头字段Cache-ControlExpiresLast-ModifiedETag 缓存策略的优化与实践经验分享1. 使用合适的缓存头字段2. 结合使用Last-Modified和ETag3. 利用CDN进行缓存4. 实…...

uniapp中二次封装jssdk和使用
直接上代码 // import wx from "weixin-js-sdk"; /*** 考虑到包的大小,所以直接在 index.html 文件中cdn引入了jssdk* <script src"https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>* 注意:这里 jWeixin 一…...

只刷题可以通过PMP考试吗?
咱们都知道,PMBOK那本书,哎呀,读起来确实有点费劲。所以,有些人就想了,干脆我就刷题吧,题海战术,没准儿也能过。这话啊,听起来似乎有点道理,但咱们得好好琢磨琢磨。 刷题…...

Python Selenium 详解:实现高效的UI自动化测试
落日余辉,深情不及久伴。大家好,在当今软件开发的世界中,自动化测试已经成为保障软件质量和快速迭代的重要环节。而在自动化测试的领域中,UI自动化测试是不可或缺的一部分,它可以帮助测试团队快速验证用户界面的正确性…...