背景需求:
最近保教主任一直在为总园的活动室安排而头疼不已,和组长们商议许久,依旧无法合理把活动室安排好。3月2日下午,听主任和游戏室成员聊了一个小时的排班,结论是除沙水和建构外,其余空余时间都是”自主游戏“,但具体排班依旧无法实现。
由于我马上要成为中班班主任,也需要总园活动室安排表做周计划(准备用Python批量制作20周周计划模板)。于是主动请缨,提出想用Python代码来试试能不能排班。主任详细介绍了排班规律。
内容安排
沙水游戏室只有一个(户外大沙坑),因此每周的上午、下午只能排1次,一天2次,一周10次,但是总园有14个班级,也就是一周“吃不完”,实际7个工作日才能轮完总园所有班级。
建构游戏室有“中班建构室、大班建构室“”两间,可以上午、下午都运作(2间*2次*5天=20班,目前大班8个+中班6个=14个,因此14个班级用2个建构室,可以一周内全部轮到,
角色游戏、表演游戏统称自主游戏,填入没有沙水、建构的时间段。
成因
过去,没有沙水游戏室场地限制(1个)四类活动的排班基本都能一周固定或者8周一次轮流固定。
今年一定要平均分配沙水室,7天轮流与5天轮流产生了冲突,依靠人工难以合理、快速排序。
思路:
沙水游戏室:各班轮到的周次、星期、时段都不同。
由于沙水游戏室室7天轮一次,所以先做沙水游戏室排版,7个工作日轮回1次,将导致每个班级不可能在固定的某一天(每周星期几)游戏,同时,各班使用沙水游戏室的时段(上午、下午)也可能不同。
建构游戏室:各班轮到的周次、星期、时段相同,确保不与沙水室的时段重合
在沙水室活动的时段外,如何让各班每周的建构游戏室活动时间时段都一样,也是一个难点(因为沙水活动室的活动时间不固定)
运行情况:
一、沙水活动室(代码设计)
从活动室角度设计:
周次 | 时段 | 星期一 | 星期二 | 星期三 | 星期四 | 星期五 |
第1周 | 上午 | 大1 | 大2 | 大3 | 大4 | 大5 |
第1周 | 下午 | 大6 | 大7 | 大8 | 中3 | 中4 |
第2周 | 上午 | 中5 | 中6 | 中7 | 中8 | 大1 |
第2周 | 下午 | 大2 | 大3 | 大4 | 大5 | 大6 |
从这个表格中,可以看到,滚动14个班级,需要第1周5天*2+第2周4天*1=14次。14个班级轮流滚动14次,
从班级角度设计:
周次 | 班级 | 星期一 | 星期二 | 星期三 | 星期四 | 星期五 |
第1周 | 大1 | 沙水上 | 自主游戏 | 自主游戏 | 自主游戏 | 自主游戏 |
第1周 | 大2 | 自主游戏 | 沙水上 | 自主游戏 | 自主游戏 | 自主游戏 |
第1周 | 大3 | 自主游戏 | 自主游戏 | 沙水上 | 自主游戏 | 自主游戏 |
第1周 | 大4 | 自主游戏 | 自主游戏 | 自主游戏 | 沙水上 | 自主游戏 |
第1周 | 大5 | 自主游戏 | 自主游戏 | 自主游戏 | 自主游戏 | 沙水上 |
第1周 | 大6 | 沙水下 | 自主游戏 | 自主游戏 | 自主游戏 | 自主游戏 |
第1周 | 大7 | 自主游戏 | 自主游戏 | 自主游戏 | 自主游戏 | 自主游戏 |
第1周 | 中3 | 自主游戏 | 自主游戏 | 沙水下 | 自主游戏 | 自主游戏 |
第1周 | 中4 | 自主游戏 | 自主游戏 | 自主游戏 | 沙水下 | 自主游戏 |
第1周 | 中5 | 自主游戏 | 自主游戏 | 自主游戏 | 自主游戏 | 沙水下 |
第2周 | 中6 | 沙水上 | 自主游戏 | 自主游戏 | 自主游戏 | 自主游戏 |
第2周 | 中7 | 自主游戏 | 沙水上 | 自主游戏 | 自主游戏 | 自主游戏 |
第2周 | 中8 | 自主游戏 | 自主游戏 | 沙水上 | 自主游戏 | 自主游戏 |
第2周 | 大1 | 自主游戏 | 自主游戏 | 自主游戏 | 沙水上 | 自主游戏 |
第2周 | 大2 | 自主游戏 | 自主游戏 | 自主游戏 | 自主游戏 | 沙水上 |
第2周 | 大3 | 沙水下 | 自主游戏 | 自主游戏 | 自主游戏 | 自主游戏 |
第2周 | 大4 | 自主游戏 | 沙水下 | 自主游戏 | 自主游戏 | 自主游戏 |
第2周 | 大5 | 自主游戏 | 自主游戏 | 沙水下 | 自主游戏 | 自主游戏 |
第2周 | 大6 | 自主游戏 | 自主游戏 | 自主游戏 | 沙水下 | 自主游戏 |
第2周 | 大6 | 自主游戏 | 自主游戏 | 自主游戏 | 自主游戏 | 沙水下 |
最终代码如下:
#20230303 2022学年下学期沙水大班活动室安排(14个班级 轮一次14次7个工作日,每个班级不可能固定一天去沙水活动)
import sys
import random
import xlrd
import xlwt
from openpyxl import load_workbook
import time
time.sleep(2)
'''班主任贴周计划用的(按班级分类)'''
# weekweek=int(input('共有几周?(如20周 20)\n'))
print('---------第1步:把8个活动室游戏活动室循环21次(105元素组成的列表)------')
# 本学期:大1,大2,大3,大4,大5,大7,大8,大9班,其中6班空缺,一共有8个大班
gradenum=['大1','大2','大3','大4','大5','大7','大8','大9','中3','中4','中5','中6','中7','中8']
L=[]# 这里的L等于list,因为和最后excle合并程序中的代码有冲突,所以全部改成大写的首字母
L1=[]
L3=[]
L2=[]
L4=[]
# 这里是8个活动室游戏活动室,因为后面有递进,所以把最后一个 08,放到01前面,这样摆放后面才会正确)
# list1=['1','2','3','4','5',]
list1=['沙水(上)','自主','自主','自主','自主',]
list2=['沙水(下)','自主','自主','自主','自主',]
list11=[]
for i in range (2):
for k1 in list1:
print(k1)
list11.append(k1)
print(list11)
# ['沙水(上)', '自主', '自主', '自主', '自主', '沙水(上)', '自主', '自主', '自主', '自主']
# 倒过来取值
for g1 in range(5,0,-1): # 4,3,2,1,0
lll=list11[g1:g1+5]
for mmm in lll:
L1.append(mmm)
print(L1)
list22=[]
for i in range (2):
for k2 in list2:
print(k2)
list22.append(k2)
print(list22)
# ['沙水(下)', '自主', '自主', '自主', '自主', '沙水(上)', '自主', '自主', '自主', '自主']
# 倒过来取值
for g2 in range(5,0,-1): # 4,3,2,1,0
lll2=list22[g2:g2+5]
for mmm2 in lll2:
L2.append(mmm2)
print(L2)
L=[]
for c in range(7000): # 各班“游戏活动室基本元素8个”循环21次,数量多一点,
for a in L1:
L.append(a)
for b in L2:
L.append(b)
print(L)
Lwrite=[]
# print('---------第2步:如果一周有5天(不考虑跳过假日)------')
# #
# # print('{}班'.format(gradenum[num]))
for i in range(0,int(20*5*2.4)):#第1周
Lwrite.append(L[5*i:5*i+5])
# print(Lwrite)
for content in Lwrite:
print(content)
print('---------第4步:xls写入)------')
workbook = xlwt.Workbook()# 新建xls工作簿
sheet = workbook.add_sheet("Sheet")# 新建xls工作簿的工作表的名字是sheet
# 第0列 写入班级,
classroom=[]
for l in range(0,17):
for i in range(0,len(gradenum)):
n="{}".format(gradenum[i])
classroom.append(n)
print(classroom)
# print(date)
row=1
for dd in range(0, len(classroom)):
sheet.write(row, 1, classroom[dd]) # 这里enumerate不能用,因为只有一列,所以就用
row += 1
# 第1列 写入周次(每10次一周)
dates=[]
for u in range(1,21):
for e in range(0,10): # 10行换一周
n="第{}周".format('%02d'%u) # 用遍历方法获得“第1周、第2周、第21周”字样,
dates.append(n) # 添加到列表 s
print(dates)
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
# 第B2开始写入 活动室内容
content = len(Lwrite)# L2['07', '08', '01', '02', '03']的长度 21组
row = 1 # 第2行
for i in range(content): # 遍历21组[]的总数
for col,item in enumerate(Lwrite[i],2): # 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") # 新建保存 只能xls
print('计划生成成功')
except e:
print('失败...')
print(e)
运行后的结果。
运用数据透视图,把表格按照“班级“拆开
通过观察班级的分类表,可以看到
跳过某几周——某几周里,这个班级没有轮到沙水活动
活动周呈现斜线排列,并且轮到周一、三、五的沙水活动是下午场,轮到周二、四的沙水活动是上午场,
分析:
通过观察分表,可以看到各班虽然沙水活动在不同周次里出现在不同的“星期X”里,但是“星期X”里。有一定规律,统一上午、或者统一下午。
可以利用这种统一性,把建构室填进去。
二、沙建构活动室(代码设计)
规律如下:
通过对各班沙水游戏活动(班级版)的观察,选出沙水之外的空余时间。
以大1班为例,可以看到 它班级 的星期一沙水在上午,星期二沙水在下午,星期三沙水在上午、星期四沙水在下午、星期五沙水在上午
以大2班为例,可以看到 它班级 的星期一沙水在下午,星期二沙水在上午,星期三沙水在下午、星期四沙水在上午、星期五沙水在下午
大一和大二正好交错开
班级 | 周一 | 周二 | 周三 | 周四 | 周五 |
大1 | 沙水上 | 沙水下 | 沙水上· | 沙水下 | 沙水上 |
大2 | 沙水下 | 沙水上· | 沙水下 | 沙水上 | 沙水上 |
由此可以推测出:这两个班级可以被用到的建构游戏的时间段
班级 | 周一 | 周二 | 周三 | 周四 | 周五 |
大1 | 建构下 | 建构上 | 建构下 | 建构上 | 建构下 |
大2 | 建构上 | 建构下 | 建构上 | 建构下 | 沙水上 |
也就是说大1班的第1周建构时间可以安排在周一下午,这样就不会与大1班第1周轮到的沙水时间上午产生冲突。
通过一定的梳理后,建构安排如下
大班建构活动室(上午场4个班、下午场4个班)-双数排列要交错
中班建构活动室(上午场3个班、下午场3个班)-单数排列不用交错
建构活动室固定活动时间
活动室 | 时段 | 星期一 | 星期二 | 星期三 | 星期四 | 星期五 |
建构活动室1(大班) | 上午 | / | 大5 | 大7 | 大8 | 大9 |
下午 | 大1 | 大2 | 大3 | 大4 | / | |
活动室 | 时段 | 星期一 | 星期二 | 星期三 | 星期四 | 星期五 |
建构活动室2 (中班) | 上午 | 中6 | 中7 | 中8 | / | / |
下午 | 中3 | 中4 | 中5 | / | / |
建构游戏室内代码运行
#20230302 2022学年下学期大班建构活动室安排(14个班级 不跳节日)
import sys
import random
import xlrd
import xlwt
from openpyxl import load_workbook
import time
time.sleep(2)
'''班主任贴周计划用的(按班级分类)'''
# weekweek=int(input('共有几周?(如20周 20)\n'))
print('---------第1步:把8个活动室游戏活动室循环21次(105元素组成的列表)------')
# 本学期:大1,大2,大3,大4,大5,大7,大8,大9班,其中6班空缺,一共有8个大班
gradenum=['大1','大2','大3','大4','大5','大7','大8','大9','中3','中4','中5','中6','中7','中8']
L=[]# 这里的L等于list,因为和最后excle合并程序中的代码有冲突,所以全部改成大写的首字母
L1=[]
L3=[]
L2=[]
L4=[]
# 这里是8个活动室游戏活动室,因为后面有递进,所以把最后一个 08,放到01前面,这样摆放后面才会正确)
# list1=['1','2','3','4','5',]
listda1=['建构1(下)','自主','自主','自主','自主']
listda2=[ '自主','建构1(上)','自主','自主','自主']
listzhong1=['建构2(下)','自主', '自主','自主','自主',]
listzhong2=['建构2(上)','自主','自主','自主','自主',]
# 大班建构下午班4个
list11=[]
for i in range (2):
for k11 in listda1:
list11.append(k11)
# print(list11)
# ['建构1(上) ', '自主', '自主', '自主', '自主', '建构1(上) ', '自主', '自主', '自主', '自主']
L11=[]
# 倒过来取值
for g11 in range(5,1,-1): # 4,3,2,1,0
lll1=list11[g11:g11+5]
for mmm1 in lll1:
L11.append(mmm1)
print(L11)
# 大班建构上午班4个
list12=[]
for i in range (2):
for k12 in listda2:
list12.append(k12)
# print(list12)
# ['建构1(上) ', '自主', '自主', '自主', '自主', '建构1(上) ', '自主', '自主', '自主', '自主']
L12=[]
# 倒过来取值
for g12 in range(5,1,-1): # 4,3,2,1,0
lll2=list12[g12:g12+5]
for mmm2 in lll2:
L12.append(mmm2)
print(L12)
# # 中班建构下午班3
list21=[]
for i in range (2):
for k21 in listzhong1:
list21.append(k21)
# print(list21)
# ['建构1(上) ', '自主', '自主', '自主', '自主', '建构1(上) ', '自主', '自主', '自主', '自主']
L21=[]
# 倒过来取值
for g21 in range(5,2,-1): # 4,3,2,1,0
lll3=list21[g21:g21+5]
for mmm3 in lll3:
L21.append(mmm3)
print(L21)
# # 中班建构上午班3个
list22=[]
for i in range (2):
for k22 in listzhong2:
list22.append(k22)
# print(list22)
# ['建构1(上) ', '自主', '自主', '自主', '自主', '建构1(上) ', '自主', '自主', '自主', '自主']
L22=[]
# 倒过来取值
for g22 in range(5,2,-1): # 4,3,2,1,0
lll4=list22[g22:g22+5]
for mmm4 in lll4:
L22.append(mmm4)
print(L22)
L=[]
for i in range(5000): # 各班“游戏活动室基本元素8个”循环21次,数量多一点,
for a in L11:
L.append(a)
for b in L12:
L.append(b)
for c in L21:
L.append(c)
for d in L22:
L.append(d)
print(L)
Lwrite=[]
# print('---------第2步:如果一周有5天(不考虑跳过假日)------')
# #
# # print('{}班'.format(gradenum[num]))
for i in range(0,int(20*5*3)):#第1周
Lwrite.append(L[5*i:5*i+5])
# print(Lwrite)
for content in Lwrite:
print(content)
print('---------第4步:xls写入)------')
workbook = xlwt.Workbook()# 新建xls工作簿
sheet = workbook.add_sheet("Sheet")# 新建xls工作簿的工作表的名字是sheet
# 第0列 写入班级,
classroom=[]
for l in range(0,20):
for i in range(0,len(gradenum)):
n="{}".format(gradenum[i])
classroom.append(n)
print(classroom)
# print(date)
row=1
for d in range(0, len(classroom)):
sheet.write(row, 1, classroom[d]) # 这里enumerate不能用,因为只有一列,所以就用
row += 1
# 第1列 写入周次(每10次一周)
dates=[]
for u in range(1,21):
for e in range(len(gradenum)):
# 10个班级换一周
n="第{}周".format('%02d'%u) # 用遍历方法获得“第1周、第2周、第21周”字样,
dates.append(n) # 添加到列表 s
print(dates)
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
# 第B2开始写入 活动室内容
content = len(Lwrite)# L2['07', '08', '01', '02', '03']的长度 21组
row = 1 # 第2行
for i in range(content): # 遍历21组[]的总数
for col,item in enumerate(Lwrite[i],2): # 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") # 新建保存 只能xls
print('计划生成成功')
except e:
print('失败...')
print(e)
生成的列表
每周每班时间、房间、时段都一样
合并版
把沙水表格和建构表格合在一起(手动排序),看看是否有上午下午活动室内重合的情况
筛选结果
以第一周为例,红色10个班级上下午都有沙水或建构活动(时段不重复)黄色4个班级只有建构活动
运用EXCLE数据透视图对“班级”进行分表
以大1班为例,可以看到
建构沙水有3次在同一天(红色),但是分上午下午
同一天活动上下午到另一次同一天活动上下午,有2次纯“建构”的周(绿色)
从排序来看,沙水14个班级进行14天循环,产生了一定的斜线排列规律
同理可以看大2班
1、也是“建构沙水”错开时段、错开星期X。并且每隔2次轮到1次“纯建构“”
感悟:
运行速度快,准确度高:
通过程序制作排班表,可以反复测试,获得最佳、最准确的效果。运行速度远超人工排序。正确率也有保障(人工贴容易疲劳出错)
找到循环点,构建规则:
无论列表的循环取索引,合成需要的组合(5天5天的组合)。还是14班轮一次、1周排10行、1周排14行……这些循环中总有一个交点,找到这个交际点,就可以建立循环。
枚举多种表,反推设计:
今天批量的是班主任版的活动室内安排,精确到班级。后续我通过调试代码设置3个活动室里面张贴的表格,得到领导的好评。
客户好评
体会
学以致用,提高工作中的计算机办公效率
新版用起来有点熟悉了,