样例展示:跳过节日的运动场地循环排序表(8个班级8组内容 下学期一共20周)




python 值班算法 python值班表轮换_Powered by 金山文档


背景需求:

上学期做过一次大班运动场地安排,跳过节日。2023.2下学期运动场地排班(跳过节日)又来了。

一、场地器械微调


python 值班算法 python值班表轮换_python 值班算法_02


python 值班算法 python值班表轮换_首字母_03


二、排序顺序不变


python 值班算法 python值班表轮换_python 值班算法_04


三、如果让节日的格子空在正确的位置?

上学期虽然程序批量生成了跳过节日的运动场地,但是涉及到节日的部分内容还是需要手动调整。(而且是1个班级的手工剪切复制)


python 值班算法 python值班表轮换_python 值班算法_05


比如 第一周周一的2天但是跳过的节日那一周的运动是从星期一开始排的,需要人工手动把场地贴到指定的格子里(如第一周的星期一星期二的内容实际上是星期四、星期五)


python 值班算法 python值班表轮换_python_06


python 值班算法 python值班表轮换_Powered by 金山文档_07


本代码解决的重点——跳过节日,并补全节日名称,每周正好5个

测算场地及中间节日在五天内的总排序


python 值班算法 python值班表轮换_python 值班算法_08


根据校历计算数量、设计占位空格


python 值班算法 python值班表轮换_python 值班算法_09


2023年2月17日 2022学年下学期大班分散运动(跳过节日 20周)备份

import sys
import random
import xlrd
import xlwt
from openpyxl import load_workbook
import time
print('---------运动场地的循环------')
print('---------规则:------')
print('---------1.有8个运动场地,01 02 03 04 05 06 07 08:------')
print('---------2.大1班从01开始游戏,01 02 03 04 05 06 07 08:------')
print('---------3.大2班从02开始游戏,02 03 04 05 06 07 08,01 ------')
print('---------4.大3班从03开始游戏,03 04 05 06 07 08,01 02 ------')
print('---------依次类推,最后制作出所有大班的每周的运动排序表 ------')
print('---------通常是每周5天,需要跳过节假日 ------')
time.sleep(2)





print('---------第1步:把8个运动场地循环21次(105元素组成的列表)------')

# 本学期:大1,大2,大3,大4,大5,大7,大8,大9班,其中6班空缺,一共有8个大班
gradenum=['1','2','3','4','5','7','8','9']
# print(len(gradenum))# 8

# radenum的长度=7,0-7,一共循环8次
for num in range(0,len(gradenum)):

    L=[]# 这里的L等于list,因为和最后excle合并程序中的代码有冲突,所以全部改成大写的首字母
    L1=[]
    L3=[]  
    L2=[]
    # 这里是8个运动场地,因为后面有递进,所以把最后一个 08,放到01前面,这样摆放后面才会正确)
    L3=['小小交通车\n(平衡车、三轮车、扭扭车、自行车、木桥)',
'爬笼接力赛\n(爬笼、树屋、沙漏、书包、铃铛)',
'百变小能手\n(小足球、箩筐、百变迷宫架、垫子、马甲)',
'平衡小勇士\n(长短竹梯、三脚架、长凳、轮胎、安全垫)',
'跑跳小达人\n(轮胎、跨栏、锣鼓、接力棒)',
'勇敢者道路\n(背篓、布袋、矿泉水瓶)',
'对战投投乐\n(弹力棉球、吸盘球、飞镖盘)',
'山洞大探险\n(轮胎、安全垫、麻绳)',]



    # 生成8个班级8组运动(第1个元素不同)
    for i in range(0,len(gradenum)):        # 
        b = L3.pop(0)    # 在运动场地列表L3中 删除 第1个元素 大1班 先删除08,就是从01开始
        L3.append(b)  # 在运动场地列表L3最后 添加 第1个元素
        # print(L[0])
        L1.append(L3[0:len(gradenum)])     # 把不断变化的内容添加到L1 
        # 8个班级场地“基本元素“构成了L1列表:[['01', '02', '03', '04', '05', '06', '07', '08'], ['02', '03', '04', '05', '06', '07', '08', '01'], ['03', '04', '05', '06', '07', '08', '01', '02'], ['04', '05', '06', '07', '08', '01', '02', '03'], ['05', '06',  
    # print(L1)

    for b in range(22):        # 把各班“场地基本元素8个”循环21次,数量多一点,便于后期提取内容
        for y in L1[num]:    #抽取L1中的一组组内容  L1[0]=['01', '02', '03', '04', '05', '06', '07', '08']、L1[1]=['02', '03', '04', '05', '06', '07', '08', '01'],
            # print(y)               # 在用 y提取L1[0]中的'01', '02', '03', '04', '05', '06', '07', '08'三个元素
            L.append(y)     #把y提取的单个元素一个个加到列表里,并且依次循环22次,数量足够多
    print(L)
    # 打印出来大1班 列表组=['01', '02', '03', '04', '05', '06', '07', '08','01', '02', '03', '04', '05', '06', '07', '08','01', '02', '03', '04', '05', '06', '07', '08','01', '02', '03', '04', '05', '06', '07', '08','01', '02', '03', '04', '05', '06', '07', '08']


    print('---------第2步:如果一周有5天(不考虑跳过假日)------')
#   
    # print('大{}班'.format(gradenum[num]))

    # for i in range(1):#共20周这是第1周,是原始的位置81234
    #     print(L[0:5]) # 列表有8个运动项目,但只要其中5个(周一到周五)
    #     L2.append(L[0:5])
    # for i in range(2,22):  #共20周    这是第2-20周  ,如果是21周,把2,21 改成2,22 
    #     L=L[5:]  #  5代表前面一个数已经取过5位
    #     L.append(L) # 将a安排到最后一个座位
    #     print(L[0:5]) # 列表是八个循环,我只要其中5个
    #     L2.append(L[0:5])  

    print('大{}班'.format(gradenum[num]))

    print('---------第3步:如果每周需要跳过假日(考虑跳过假日)------')
    
    #  每周需要的天数 (跳过节日.如第1周只有2天工作,9月1-2日(周四周五) ,第3周周一是中秋节放假1天,所以只有4个工作日)
    # day=['3','5','5','6','5','2','5','5','5','5','5','5','5','5','5','5','5','4','5','5','2']
    kong=''
    tt1='清明节'
    tt2='劳动节'
    tt3='端午节'
   
    # 第1周 第2-7周开始 第8周部分
    # for d in range(0,1):       
    L2.append(kong) 
    L2.append(kong) 
    for kk in L[0:int(3+5*6+2)]:
        L2.append(kk) 
    # 清明
    L2.append(tt1) 
     # 清明后到五一前 
    for kk in L[int(3+5*6+2):int((3+5*6+2)+(2+5*2))]:
        L2.append(kk)    

    # 23日(周日)也上班 所以一共6天 一周排5填,28号周五放到下周周一算
    for kk in L[int((3+5*6+2)+(2+5*2)):int((3+5*6+2)+(2+5*2)+6)]:
        L2.append(kk)      
    # 劳动节休息休息3天,实际1天空格 (28日放到周一了 周二五一节) 
    L2.append(tt2)    
    # 劳动节456三天上班+6周5填天 1周3天(劳动节后到端午节前)
    for kk in L[int((3+5*6+2)+(2+5*2+6)):int((3+5*6+2)+(2+5*2+6)+3+(5*6+3))]:
        L2.append(kk)    
    # 端午节三天,占一个格子在周四 周日要上班顶替周五
    L2.append(tt3) 
    for kk in L[int((3+5*6+2)+(2+5*2+6)+3+(5*6+3)):int((3+5*6+2)+(2+5*2+6)+3+(5*6+3))+6]:
        L2.append(kk)    
     
    print(L2) 
    
   

    print('---------第4步:xls写入)------') 
    workbook = xlwt.Workbook()# 新建xls工作簿
    sheet = workbook.add_sheet("Sheet")# 新建xls工作簿的工作表的名字是sheet 

   # 第0列 写入“第1周、第2周、第3周……第21周
    dates=[]
    for i in range(1,21):
        n="第{}周".format(i)    # 用遍历方法获得“第1周、第2周、第21周”字样,
        dates.append(n)          # 添加到列表    
    print(dates)        
    # print(date)

    row=1
    for d in range(0, len(dates)):
        sheet.write(row, 0, dates[d])         # 这里enumerate不能用,因为只有一列,所以就用
        row += 1    
    
    # 第0行 写入 星期一  '星期二','星期三','星期四','星期五  #
    weeks = ['周次','星期一','星期二','星期三','星期四','星期五']
    week = len(weeks) 

    col=0
    for d in range(0, len(weeks)):
        sheet.write(0,col,weeks[d])         # 因为只有一行,所以就用有两种写法(enumerate和这种)
        col+= 1  

    # 输入星期的另一种写法
    # col=0 
    # for row,item in enumerate(weeks,0):            # 可以这样写L2[i]=表格内的内容=item,索引数字=col 0代表在A1 1代表在B1
    #     sheet.write(col,row,item)           # 第1行第1列开始写入一行”星期X"
    # col+=1
 
    # 第B2开始写入 运动内容

    print('-----------第3步,保存到excle--------')
    # 以下是xls保存
     #  在list_date五个五个取值   
    list3=[]
    for k in range(0,21):
        list3.append(L2[k*5:k*5+5])       
    print(list3)

    # print(list)
    for opq in list3:
        print(opq)
        
    
    # arrlan2 = len(list_d)# 日期抽取5天一组

    arrlan = len(list3)# L2['07', '08', '01', '02', '03']的长度 21组
    row = 1     # 第2行
    for i in range(arrlan):         # 遍历21组[]的总数
        for col,item in enumerate(list3[i],1):            # L2[i]=表格内的内容=item,索引数字=col
            sheet.write(row,col,item)  # row,col,item 行=1、列=索引数字、内容=表格内容 写入第一行第一列
        row += 1   
   
    print('---------第5步:xls保存N份工作簿(每份一页)------')             
    try:
        workbook.save(r"C:\Users\jg2yXRZ\OneDrive\桌面\word2pdf2png\大{}班分散运动.xls".format(gradenum[num]))    # 新建保存 只能xls
        print('计划生成成功')
    except e:
        print('失败...')
        print(e)

print('---------第6步:把N份xls单页内容合并在1个工作簿的N个工作表内)------')      
time.sleep(2)


# 获取目录下所有的表
import os
import pandas as pd

dir = r'C:\Users\jg2yXRZ\OneDrive\桌面\word2pdf2png'
# 获取目录下所有的表
origin_file_list = os.listdir(dir)
print(origin_file_list)

with pd.ExcelWriter(r'C:\Users\jg2yXRZ\OneDrive\桌面\word2pdf2png\20230217大班分散运动(编程详细版 跳过节日).xls') as writer:
    # 循环遍历表格
    for i in origin_file_list:
        # 拼接每个文件的路径
        file_path = dir + '/' + i
        # 把表名赋予给对应的sheet
        sheet_name = i[:-4]
        df = pd.read_excel(file_path)

        # 变相解决表格中第一行第一列为空的缺陷
        ring = "".join(list(str(i) for i in df.index))
        # string = .join(list(str(i) for i in df.index))
        # 判断如果索引都为数字,则不保留索引(根据自己代码调整)
        if ring.isdigit():
            df.to_excel(writer, sheet_name,index=False)
        else:
            df.to_excel(writer, sheet_name)


python 值班算法 python值班表轮换_表名_10


导出位置


python 值班算法 python值班表轮换_python 值班算法_11


最初的样式是这样的(节日已经写进去了)


python 值班算法 python值班表轮换_表名_12


全选每张表格,进行格式设置。


python 值班算法 python值班表轮换_Powered by 金山文档_13


第11-12周 五一劳动节的排班比较乱,所以加彩色底纹,最下面备注号这一周的“星期排序”(周六周日要补班)


python 值班算法 python值班表轮换_python_14


大3班的运动排序情况


python 值班算法 python值班表轮换_表名_15


大7班的运动排序情况


python 值班算法 python值班表轮换_python_16


(没有大6班,所以7班就用6班的场地场地,8班用7班场地,9班用8班场地)

实用效果:

组长强推收藏


python 值班算法 python值班表轮换_Powered by 金山文档_17


特别感悟:


python 值班算法 python值班表轮换_Powered by 金山文档_18


第二次用这个代码做运动场地排列,我感觉人工排场地很费时费力,没有必要。利用程序提高文本资料产生的效率,更精确,更快速。

学以致用,提升效率。节约时间去做更有价值的事情。