当前位置: 首页 > article >正文

用python重写了座位表生成器

如图,用python重写了座位表生成器,在会议排座时方便使用,手残党可以直接下载
在这里插入图片描述
在这里插入图片描述

from tkinter import Tk, Button, Frame, Label, Entry, Checkbutton, StringVar, BooleanVar, messagebox, filedialog
import pandas as pd
import numpy as np
import os
import sys
from pandas import ExcelWriter

def resource_path(relative_path):
    """ 获取资源绝对路径 """
    try:
        # PyInstaller创建临时文件夹,将路径存储于_MEIPASS
        base_path = sys._MEIPASS
    except Exception:
        base_path = os.path.abspath(".")
    return os.path.join(base_path, relative_path)

class SeatingChart:
    def __init__(self):
        self.window = Tk()
        self.window.title("座位表生成器")
        # 设置窗口图标(如果有的话)
        try:
            self.window.iconbitmap(resource_path("icon.ico"))
        except:
            pass
        
        # 设置窗口大小和位置
        window_width = 400
        window_height = 300
        screen_width = self.window.winfo_screenwidth()
        screen_height = self.window.winfo_screenheight()
        x = (screen_width - window_width) // 2
        y = (screen_height - window_height) // 2
        self.window.geometry(f"{window_width}x{window_height}+{x}+{y}")
        
        self.names = []
        
        # 添加说明文字
        note_label = Label(self.window, text="注意:EXCEL文件必须包含姓名和备注列", fg="red")
        note_label.pack(pady=10)
        
        # 创建打开文件按钮
        self.open_btn = Button(self.window, text="打开姓名列表", command=self.open_file)
        self.open_btn.pack(pady=10)
        
        # 创建输入框框架
        input_frame = Frame(self.window)
        input_frame.pack(pady=10)
        
        # 左侧列数输入
        Label(input_frame, text="左:").grid(row=0, column=0)
        self.left_var = StringVar(value="8")
        self.left_entry = Entry(input_frame, textvariable=self.left_var, width=10)
        self.left_entry.grid(row=0, column=1, padx=5)
        
        # 中间列数输入
        Label(input_frame, text="中:").grid(row=0, column=2)
        self.middle_var = StringVar(value="10")
        self.middle_entry = Entry(input_frame, textvariable=self.middle_var, width=10)
        self.middle_entry.grid(row=0, column=3, padx=5)
        
        # 右侧列数输入
        Label(input_frame, text="右:").grid(row=0, column=4)
        self.right_var = StringVar(value="8")
        self.right_entry = Entry(input_frame, textvariable=self.right_var, width=10)
        self.right_entry.grid(row=0, column=5, padx=5)
        
        # 添加交替排列复选框
        self.alternate_var = BooleanVar(value=True)
        self.alternate_check = Checkbutton(self.window, text="左右两侧交替排列", 
                                            variable=self.alternate_var)
        self.alternate_check.pack(pady=5)
        
        # 创建生成按钮
        self.generate_btn = Button(self.window, text="生成座位表", command=self.generate_seating)
        self.generate_btn.pack(pady=10)
        
    def open_file(self):
        file_path = filedialog.askopenfilename(filetypes=[("Excel files", "*.xlsx")])
        if file_path:
            try:
                df = pd.read_excel(file_path)
                # 检查文件格式
                if not {'姓名', '备注'}.issubset(df.columns):
                    messagebox.showerror("错误", "文件格式错误,需要工作表中包含姓名和备注列")
                    return
                self.names = df[df['备注'].isna()]['姓名'].tolist()
            except Exception as e:
                messagebox.showerror("错误", f"读取文件时出错:{str(e)}")
        
    def generate_seating(self):
        try:
            # 检查是否已导入数据
            if not self.names:
                messagebox.showerror("错误", "请先选择姓名列表文件")
                return
            
            left_cols = int(self.left_var.get())
            middle_cols = int(self.middle_var.get())
            right_cols = int(self.right_var.get())
            
            # 创建空的座位表
            total_rows = (len(self.names) + middle_cols + left_cols + right_cols - 1) // (middle_cols + left_cols + right_cols)
            seating = np.full((total_rows, left_cols + middle_cols + right_cols), "", dtype=object)
            
            # 用于记录每个学生的座位位置
            seat_index = []
            
            # 填充座位
            name_index = 0
            for row in range(total_rows):
                if name_index >= len(self.names):
                    break
                    
                # 先填充中间部分
                middle_start = left_cols
                middle_end = left_cols + middle_cols
                middle_center = middle_start + middle_cols // 2
                
                # 从中间向两边填充
                positions = []
                # 先添加中心位置
                if middle_cols % 2 == 0:
                    positions.append(middle_center)
                    positions.append(middle_center - 1)
                    # 然后向两边扩展
                    for i in range(1, middle_cols // 2):
                        if middle_center + i < middle_end:
                            positions.append(middle_center + i)
                        if middle_center - i - 1 >= middle_start:
                            positions.append(middle_center - i - 1)
                else:
                    positions.append(middle_center)
                    # 先添加左边的位置,再添加右边的位置
                    for i in range(1, middle_cols // 2 + 1):
                        if middle_center - i >= middle_start:
                            positions.append(middle_center - i)
                        if middle_center + i < middle_end:
                            positions.append(middle_center + i)
                
                # 填充中间位置
                for pos in positions:
                    if name_index < len(self.names):
                        seating[row][pos] = self.names[name_index]
                        seat_index.append((self.names[name_index], f"第{row+1}排中{pos-left_cols+1}"))
                        name_index += 1
                
                # 填充左右两侧
                if self.alternate_var.get():
                    # 交替排列模式
                    left_idx = left_cols - 1
                    right_idx = left_cols + middle_cols
                    while (left_idx >= 0 or right_idx < left_cols + middle_cols + right_cols) and name_index < len(self.names):
                        if left_idx >= 0:
                            seating[row][left_idx] = self.names[name_index]
                            seat_index.append((self.names[name_index], f"第{row+1}排左{left_idx+1}"))
                            name_index += 1
                            left_idx -= 1
                        if right_idx < left_cols + middle_cols + right_cols and name_index < len(self.names):
                            seating[row][right_idx] = self.names[name_index]
                            seat_index.append((self.names[name_index], f"第{row+1}排右{right_idx-left_cols-middle_cols+1}"))
                            name_index += 1
                            right_idx += 1
                else:
                    # 先左后右模式
                    # 填充左侧
                    left_idx = left_cols - 1
                    while left_idx >= 0 and name_index < len(self.names):
                        seating[row][left_idx] = self.names[name_index]
                        seat_index.append((self.names[name_index], f"第{row+1}排左{left_idx+1}"))
                        name_index += 1
                        left_idx -= 1
                    
                    # 填充右侧
                    right_idx = left_cols + middle_cols
                    while right_idx < left_cols + middle_cols + right_cols and name_index < len(self.names):
                        seating[row][right_idx] = self.names[name_index]
                        seat_index.append((self.names[name_index], f"第{row+1}排右{right_idx-left_cols-middle_cols+1}"))
                        name_index += 1
                        right_idx += 1
                
            # 创建输出DataFrame
            header = ['行号', '过道']
            header.extend([f'左{i+1}' for i in range(left_cols)])
            header.append('过道')
            header.extend([f'中{i+1}' for i in range(middle_cols)])
            header.append('过道')
            header.extend([f'右{i+1}' for i in range(right_cols)])
            
            output_data = []
            for row in range(total_rows):
                row_data = [f'第{row+1}排', '']
                row_data.extend(seating[row, :left_cols])
                row_data.append('')
                row_data.extend(seating[row, left_cols:left_cols+middle_cols])
                row_data.append('')
                row_data.extend(seating[row, left_cols+middle_cols:])
                output_data.append(row_data)
                
            # 创建两个DataFrame
            df_seating = pd.DataFrame(output_data, columns=header)
            df_index = pd.DataFrame(seat_index, columns=['姓名', '座位'])
            
            # 使用ExcelWriter保存到不同的工作表
            with pd.ExcelWriter('座位表.xlsx') as writer:
                df_seating.to_excel(writer, sheet_name='座位表', index=False)
                df_index.to_excel(writer, sheet_name='座位索引', index=False)
                
            messagebox.showinfo("成功", "座位表已生成!")
            
        except ValueError:
            messagebox.showerror("错误", "请输入有效的数字!")
        except Exception as e:
            messagebox.showerror("错误", f"生成座位表时出错:{str(e)}")
            
    def run(self):
        self.window.mainloop()

if __name__ == "__main__":
    app = SeatingChart()
    app.run()


http://www.kler.cn/a/465990.html

相关文章:

  • 仓库叉车高科技安全辅助设备——AI防碰撞系统N2024G-2
  • 【74HC192减法24/20/72进制】2022-5-17
  • 在 pandas.Grouper() 中,freq 参数用于指定时间频率,它定义了如何对时间序列数据进行分组。freq 的值可以是多种时间单位
  • 发现一个可用的免费docker镜像源
  • AI智能生成PPT,告别手工操作的新选择
  • 安卓11 SysteUI添加按钮以及下拉状态栏的色温调节按钮
  • MATLAB画柱状图
  • 【Spring学习】为什么Spring中的IOC(控制反转)能够降低耦合性(解耦)?
  • springboot和vue项目前后端交互
  • 竞品分析对于ASO优化的重要性
  • MySql---进阶篇(六)---SQL优化
  • 在 SQL 中获取第m个开始的n条记录方法汇总
  • 亚远景-ASPICE与ISO 26262:汽车软件开发与功能安全的协同作用
  • GitHub Actions 工作流编写指南
  • Mysql8主从复制(兼容低高版本)
  • 【AI部署】腾讯云每月1w小时免费GPU获取
  • DBSCAN 聚类 和 gmm 聚类 测试
  • Gitlab-runner 修改默认的builds_dir并使用custom_build_dir配置
  • Milvus×合邦电力:向量数据库如何提升15%电价预测精度
  • ASP.NET Core 中的响应压缩中间件