Spaces:
Sleeping
Sleeping
Update SchedBuilderClasses2.py
Browse files- SchedBuilderClasses2.py +43 -20
SchedBuilderClasses2.py
CHANGED
|
@@ -408,7 +408,7 @@ class Schedule():
|
|
| 408 |
if self.ee[lowManID].slOK(self,sl,tp='F'): return lowManID,'F'
|
| 409 |
self.assnLog.append('NO STAFF! No one to force to '+sl.key())
|
| 410 |
return None,'N' #No one to force
|
| 411 |
-
|
| 412 |
def checkForceStop(self,tup,iter,assn):
|
| 413 |
if tup!=None:
|
| 414 |
if iter==tup[0] and assn==tup[1]: return True
|
|
@@ -485,7 +485,7 @@ class Schedule():
|
|
| 485 |
WIPschd.assnLog.append('The last assignment created a broken schedule where the person' +WIPschd.ee[eId].lastNm+' had a forcing (previously assigned) after 48h in the week (just assigned.) Adding this slot to priority sequence and reiterating')
|
| 486 |
self.assnLog.extend(WIPschd.assnLog) #add to master before iterating
|
| 487 |
self.assnLog.extend('RETURN A')
|
| 488 |
-
return self.fillOutSched_v3(WIPschd.noVol,iter,pre8=pre8,last=WIPschd) #WIPschd,'P-Frce Brk' #<-Alt return for debugging
|
| 489 |
newK=set([k for k in WIPschd.slots if len(WIPschd.slots[k].eligVol)==0 and WIPschd.slots[k].assnType not in ['WWF','F','V','nV','DNS','N']]) #After assignment, see if anything now needing forcing that hasn't been seen before
|
| 490 |
if len(newK-set(WIPschd.noVol))>0: #Case that a forced assignment made someone ineligible for a slot they were marked as the last volunteer in, creating a slot requiring forcing that hasn't been seen before, requiring re iteration
|
| 491 |
pullK=newK-set(WIPschd.noVol) #Get the keys for slots that are now without volunteers(could be more than one so use set subtraction)
|
|
@@ -493,7 +493,7 @@ class Schedule():
|
|
| 493 |
WIPschd.noVol.extend(pullK)
|
| 494 |
self.assnLog.extend(WIPschd.assnLog) #Add to master before iterating
|
| 495 |
self.assnLog.extend('RETURN B')
|
| 496 |
-
return self.fillOutSched_v3(WIPschd.noVol,iter,pre8=pre8,last=WIPschd) # WIPschd,'P-Bump' #<-Alt return for debugging
|
| 497 |
#=====
|
| 498 |
#======
|
| 499 |
#Phase 0.5 - Make 8 Hour shift assignments previously identified in Phase 1, to set the scene
|
|
@@ -547,14 +547,14 @@ class Schedule():
|
|
| 547 |
WIPschd.noVol.extend(pullK)
|
| 548 |
self.assnLog.extend(WIPschd.assnLog) #Add to master before iterating
|
| 549 |
self.assnLog.extend('RETURN C')
|
| 550 |
-
return self.fillOutSched_v3(WIPschd.noVol,iter,pre8=pre8,last=WIPschd) # WIPschd,'P-Bump' #<-Alt return for debugging
|
| 551 |
else:
|
| 552 |
pre8[k1]=eId
|
| 553 |
pre8[k2]=eId
|
| 554 |
WIPschd.assnLog.append("Assigning "+str(WIPschd.ee[eId].lastNm)+" a voluntary 8 hour shift to "+str(k1)+", "+str(k2)+" means they can't be forced for a later slot they were forced in for already. Reiterating schedule with this 8 hour assignment on the initial-fill priority list")
|
| 555 |
self.assnLog.extend(WIPschd.assnLog)
|
| 556 |
self.assnLog.extend('RETURN D')
|
| 557 |
-
return self.fillOutSched_v3(WIPschd.noVol,iter,pre8=pre8,last=WIPschd)
|
| 558 |
if s==1:
|
| 559 |
break #Break out of searching through ee's, it got assigned and so, done
|
| 560 |
if s==1: break #Break out of incrementing through k2 as k1 has been assignd so we need to look at another k1
|
|
@@ -593,14 +593,14 @@ class Schedule():
|
|
| 593 |
WIPschd.noVol.extend(pullK)
|
| 594 |
self.assnLog.extend(WIPschd.assnLog) #Add to master before iterating
|
| 595 |
self.assnLog.extend('RETURN G')
|
| 596 |
-
return self.fillOutSched_v3(WIPschd.noVol,iter,pre8=pre8,last=WIPschd) # WIPschd,'P-Bump' #<-Alt return for debugging
|
| 597 |
else:
|
| 598 |
pre8[k1]=eId
|
| 599 |
pre8[k2]=eId
|
| 600 |
WIPschd.assnLog.append("Assigning "+str(WIPschd.ee[eId].lastNm)+" a voluntary 8 hour shift to "+str(k1)+", "+str(k2)+" means they can't be forced for a later slot they were forced in for already. Reiterating schedule with this 8 hour assignment on the initial-fill priority list")
|
| 601 |
self.assnLog.extend(WIPschd.assnLog)
|
| 602 |
self.assnLog.extend('RETURN H')
|
| 603 |
-
return self.fillOutSched_v3(WIPschd.noVol,iter,pre8=pre8,last=WIPschd)
|
| 604 |
if s==1:
|
| 605 |
break #Break out of searching through ee's, it got assigned and so, done
|
| 606 |
if s==1: break #Break out of incrementing through k2 as k1 has been assignd so we need to look at another k1
|
|
@@ -659,13 +659,13 @@ class Schedule():
|
|
| 659 |
WIPschd.noVol.extend(pullK)
|
| 660 |
self.assnLog.extend(WIPschd.assnLog) #Add to master before iterating
|
| 661 |
self.assnLog.extend('RETURN I')
|
| 662 |
-
return self.fillOutSched_v3(WIPschd.noVol,iter,pre8=pre8,last=WIPschd) # WIPschd,'P-Bump' #<-Alt return for debugging
|
| 663 |
if r==False and curS.key() not in WIPschd.noVol:
|
| 664 |
WIPschd.noVol.append(curS.key())
|
| 665 |
WIPschd.assnLog.append('The last assignment created a broken schedule where the person ('+WIPschd.ee[eId].lastNm+') had a forcing (previously assigned) after 48h in the week (just assigned.) Adding this slot to priority sequence and reiterating')
|
| 666 |
self.assnLog.extend(WIPschd.assnLog)
|
| 667 |
self.assnLog.extend('RETURN E')
|
| 668 |
-
return self.fillOutSched_v3(WIPschd.noVol,iter,pre8=pre8,last=WIPschd) # WIPschd,'V-F Rule' #<-Alt return for debugging
|
| 669 |
# if len(postNoVol-preNoVol)>0: #Recurse, an assignment made another slot have noVol
|
| 670 |
# WIPschd.assnLog.append('The last assignment caused slot(s) '+str(list(postNoVol-preNoVol))+' to have no more eligible volunteers. A new iteration will take place with these slots getting priority assignment')
|
| 671 |
# WIPschd.noVol.extend(list(postNoVol-preNoVol))
|
|
@@ -685,7 +685,7 @@ class Schedule():
|
|
| 685 |
WIPschd.assnLog.append('The last assignment resulted in slot ('+str([k for k in slLost if k!=lastK])+') having no more eligible volunteers. Those slots are added to the list of slots to force at the start, and a new schedule will be made with updated list of slots to Force')
|
| 686 |
self.assnLog.extend(WIPschd.assnLog)
|
| 687 |
self.assnLog.extend('RETURN F')
|
| 688 |
-
return self.fillOutSched_v3(WIPschd.noVol,iter,pre8=pre8,last=WIPschd)# WIPschd,'V-Bump' #<-Alt return for debugging
|
| 689 |
|
| 690 |
|
| 691 |
|
|
@@ -1036,22 +1036,45 @@ class Schedule():
|
|
| 1036 |
c+=1
|
| 1037 |
#=============================================
|
| 1038 |
#Print assignments to a separate sheet, in alphabetical order by last name
|
| 1039 |
-
|
| 1040 |
-
|
| 1041 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1042 |
# ws2.cell(row=1,column=1).value='Note that the seniority value presented is not actual plant seniority number, but just the sequence of '
|
| 1043 |
-
n=
|
| 1044 |
for rec in tls.viewTBL('senRef',sortBy=[('last','ASC')]):
|
| 1045 |
eId=rec[2]
|
| 1046 |
if len(self.ee[eId].assignments)>0 and self.slots[self.ee[eId].assignments[0]].assnType!='WWF':#If the person has an assignment and isn't WWF, print it
|
| 1047 |
n+=1
|
| 1048 |
-
|
| 1049 |
-
#
|
|
|
|
|
|
|
|
|
|
| 1050 |
c=0
|
| 1051 |
for k in sorted(self.ee[eId].assignments,key=lambda k:int(k[:k.index('_')])):
|
| 1052 |
-
styleNfill(
|
| 1053 |
# ws2.cell(row=n+1,column=2+c).value=self.slots[k].dispNm+' '+ self.slLeg[self.slots[k].seqID-1][2]+' ('+self.slLeg[self.slots[k].seqID-1][1]+')'
|
| 1054 |
-
|
| 1055 |
c+=1
|
| 1056 |
#==========================
|
| 1057 |
#Print succint assignment log to a separate sheet
|
|
@@ -1078,7 +1101,7 @@ class Schedule():
|
|
| 1078 |
ws2.cell(column=1,row=2+n).value=rec
|
| 1079 |
n+=1
|
| 1080 |
|
| 1081 |
-
#=============================================
|
| 1082 |
#Print assignments to a separate sheet, sequenced by seniority
|
| 1083 |
ws2 = wb.create_sheet(title="Assignments (Sen'ty)")
|
| 1084 |
ws2.cell(row=2,column=1).value='Seniority'
|
|
@@ -1097,7 +1120,7 @@ class Schedule():
|
|
| 1097 |
styleNfill(ws2.cell(row=n+1,column=3+c),self.slots[k])
|
| 1098 |
ws2.cell(row=n+1,column=3+c).value=self.slots[k].dispNm+' '+ self.slLeg[self.slots[k].seqID-1][2]+' ('+self.slLeg[self.slots[k].seqID-1][1]+')'
|
| 1099 |
c+=1
|
| 1100 |
-
|
| 1101 |
|
| 1102 |
|
| 1103 |
|
|
|
|
| 408 |
if self.ee[lowManID].slOK(self,sl,tp='F'): return lowManID,'F'
|
| 409 |
self.assnLog.append('NO STAFF! No one to force to '+sl.key())
|
| 410 |
return None,'N' #No one to force
|
| 411 |
+
# @debug
|
| 412 |
def checkForceStop(self,tup,iter,assn):
|
| 413 |
if tup!=None:
|
| 414 |
if iter==tup[0] and assn==tup[1]: return True
|
|
|
|
| 485 |
WIPschd.assnLog.append('The last assignment created a broken schedule where the person' +WIPschd.ee[eId].lastNm+' had a forcing (previously assigned) after 48h in the week (just assigned.) Adding this slot to priority sequence and reiterating')
|
| 486 |
self.assnLog.extend(WIPschd.assnLog) #add to master before iterating
|
| 487 |
self.assnLog.extend('RETURN A')
|
| 488 |
+
return self.fillOutSched_v3(WIPschd.noVol,iter,pre8=pre8,last=WIPschd,stop=stop) #WIPschd,'P-Frce Brk' #<-Alt return for debugging
|
| 489 |
newK=set([k for k in WIPschd.slots if len(WIPschd.slots[k].eligVol)==0 and WIPschd.slots[k].assnType not in ['WWF','F','V','nV','DNS','N']]) #After assignment, see if anything now needing forcing that hasn't been seen before
|
| 490 |
if len(newK-set(WIPschd.noVol))>0: #Case that a forced assignment made someone ineligible for a slot they were marked as the last volunteer in, creating a slot requiring forcing that hasn't been seen before, requiring re iteration
|
| 491 |
pullK=newK-set(WIPschd.noVol) #Get the keys for slots that are now without volunteers(could be more than one so use set subtraction)
|
|
|
|
| 493 |
WIPschd.noVol.extend(pullK)
|
| 494 |
self.assnLog.extend(WIPschd.assnLog) #Add to master before iterating
|
| 495 |
self.assnLog.extend('RETURN B')
|
| 496 |
+
return self.fillOutSched_v3(WIPschd.noVol,iter,pre8=pre8,last=WIPschd,stop=stop) # WIPschd,'P-Bump' #<-Alt return for debugging
|
| 497 |
#=====
|
| 498 |
#======
|
| 499 |
#Phase 0.5 - Make 8 Hour shift assignments previously identified in Phase 1, to set the scene
|
|
|
|
| 547 |
WIPschd.noVol.extend(pullK)
|
| 548 |
self.assnLog.extend(WIPschd.assnLog) #Add to master before iterating
|
| 549 |
self.assnLog.extend('RETURN C')
|
| 550 |
+
return self.fillOutSched_v3(WIPschd.noVol,iter,pre8=pre8,last=WIPschd,stop=stop) # WIPschd,'P-Bump' #<-Alt return for debugging
|
| 551 |
else:
|
| 552 |
pre8[k1]=eId
|
| 553 |
pre8[k2]=eId
|
| 554 |
WIPschd.assnLog.append("Assigning "+str(WIPschd.ee[eId].lastNm)+" a voluntary 8 hour shift to "+str(k1)+", "+str(k2)+" means they can't be forced for a later slot they were forced in for already. Reiterating schedule with this 8 hour assignment on the initial-fill priority list")
|
| 555 |
self.assnLog.extend(WIPschd.assnLog)
|
| 556 |
self.assnLog.extend('RETURN D')
|
| 557 |
+
return self.fillOutSched_v3(WIPschd.noVol,iter,pre8=pre8,last=WIPschd,stop=stop)
|
| 558 |
if s==1:
|
| 559 |
break #Break out of searching through ee's, it got assigned and so, done
|
| 560 |
if s==1: break #Break out of incrementing through k2 as k1 has been assignd so we need to look at another k1
|
|
|
|
| 593 |
WIPschd.noVol.extend(pullK)
|
| 594 |
self.assnLog.extend(WIPschd.assnLog) #Add to master before iterating
|
| 595 |
self.assnLog.extend('RETURN G')
|
| 596 |
+
return self.fillOutSched_v3(WIPschd.noVol,iter,pre8=pre8,last=WIPschd,stop=stop) # WIPschd,'P-Bump' #<-Alt return for debugging
|
| 597 |
else:
|
| 598 |
pre8[k1]=eId
|
| 599 |
pre8[k2]=eId
|
| 600 |
WIPschd.assnLog.append("Assigning "+str(WIPschd.ee[eId].lastNm)+" a voluntary 8 hour shift to "+str(k1)+", "+str(k2)+" means they can't be forced for a later slot they were forced in for already. Reiterating schedule with this 8 hour assignment on the initial-fill priority list")
|
| 601 |
self.assnLog.extend(WIPschd.assnLog)
|
| 602 |
self.assnLog.extend('RETURN H')
|
| 603 |
+
return self.fillOutSched_v3(WIPschd.noVol,iter,pre8=pre8,last=WIPschd,stop=stop)
|
| 604 |
if s==1:
|
| 605 |
break #Break out of searching through ee's, it got assigned and so, done
|
| 606 |
if s==1: break #Break out of incrementing through k2 as k1 has been assignd so we need to look at another k1
|
|
|
|
| 659 |
WIPschd.noVol.extend(pullK)
|
| 660 |
self.assnLog.extend(WIPschd.assnLog) #Add to master before iterating
|
| 661 |
self.assnLog.extend('RETURN I')
|
| 662 |
+
return self.fillOutSched_v3(WIPschd.noVol,iter,pre8=pre8,last=WIPschd,stop=stop) # WIPschd,'P-Bump' #<-Alt return for debugging
|
| 663 |
if r==False and curS.key() not in WIPschd.noVol:
|
| 664 |
WIPschd.noVol.append(curS.key())
|
| 665 |
WIPschd.assnLog.append('The last assignment created a broken schedule where the person ('+WIPschd.ee[eId].lastNm+') had a forcing (previously assigned) after 48h in the week (just assigned.) Adding this slot to priority sequence and reiterating')
|
| 666 |
self.assnLog.extend(WIPschd.assnLog)
|
| 667 |
self.assnLog.extend('RETURN E')
|
| 668 |
+
return self.fillOutSched_v3(WIPschd.noVol,iter,pre8=pre8,last=WIPschd,stop=stop) # WIPschd,'V-F Rule' #<-Alt return for debugging
|
| 669 |
# if len(postNoVol-preNoVol)>0: #Recurse, an assignment made another slot have noVol
|
| 670 |
# WIPschd.assnLog.append('The last assignment caused slot(s) '+str(list(postNoVol-preNoVol))+' to have no more eligible volunteers. A new iteration will take place with these slots getting priority assignment')
|
| 671 |
# WIPschd.noVol.extend(list(postNoVol-preNoVol))
|
|
|
|
| 685 |
WIPschd.assnLog.append('The last assignment resulted in slot ('+str([k for k in slLost if k!=lastK])+') having no more eligible volunteers. Those slots are added to the list of slots to force at the start, and a new schedule will be made with updated list of slots to Force')
|
| 686 |
self.assnLog.extend(WIPschd.assnLog)
|
| 687 |
self.assnLog.extend('RETURN F')
|
| 688 |
+
return self.fillOutSched_v3(WIPschd.noVol,iter,pre8=pre8,last=WIPschd,stop=stop)# WIPschd,'V-Bump' #<-Alt return for debugging
|
| 689 |
|
| 690 |
|
| 691 |
|
|
|
|
| 1036 |
c+=1
|
| 1037 |
#=============================================
|
| 1038 |
#Print assignments to a separate sheet, in alphabetical order by last name
|
| 1039 |
+
ws = wb.create_sheet(title="Assignments (Alpha)")
|
| 1040 |
+
ws.cell(row=3,column=1).value='Last, First'
|
| 1041 |
+
ws.cell(row=2,column=2).value='Time slots'
|
| 1042 |
+
styleCell(ws['A3'],'shift')
|
| 1043 |
+
# styleCell(ws['A2'],'shift')
|
| 1044 |
+
ws.column_dimensions['A'].width =22.78
|
| 1045 |
+
dys=['Friday','Saturday','Sunday','Monday']
|
| 1046 |
+
shifts=['C','A','B']*4
|
| 1047 |
+
tSlots=['11p - 3a','3a - 7a','7a - 11a', '11a - 3p','3p-7p', '7p-11p']*4
|
| 1048 |
+
for i in range(0,24,6): #Print Days of week
|
| 1049 |
+
cl=ws.cell(column=2+i,row=1)
|
| 1050 |
+
styleCell(cl,'day',6) #Style all the cells within the merge
|
| 1051 |
+
ws.merge_cells(start_row=1, start_column=2+i, end_row=1, end_column=2+i+5)
|
| 1052 |
+
cl.value=dys.pop(0)
|
| 1053 |
+
for i in range(0,24,2): #Print the shift title
|
| 1054 |
+
cl=ws.cell(column=2+i,row=2)
|
| 1055 |
+
styleCell(cl,'shift',1)
|
| 1056 |
+
ws.merge_cells(start_row=2, start_column=2+i, end_row=2, end_column=2+i+1)
|
| 1057 |
+
cl.value=shifts.pop(0)
|
| 1058 |
+
for i in range(24): #Print the shift times row
|
| 1059 |
+
cl=ws.cell(column=2+i,row=3)
|
| 1060 |
+
cl.value=tSlots.pop(0)
|
| 1061 |
+
styleCell(cl,'hours')
|
| 1062 |
# ws2.cell(row=1,column=1).value='Note that the seniority value presented is not actual plant seniority number, but just the sequence of '
|
| 1063 |
+
n=3
|
| 1064 |
for rec in tls.viewTBL('senRef',sortBy=[('last','ASC')]):
|
| 1065 |
eId=rec[2]
|
| 1066 |
if len(self.ee[eId].assignments)>0 and self.slots[self.ee[eId].assignments[0]].assnType!='WWF':#If the person has an assignment and isn't WWF, print it
|
| 1067 |
n+=1
|
| 1068 |
+
ws.cell(row=n,column=1).value=self.ee[eId].lastNm+', '+self.ee[eId].firstNm[0]+'.' #Print name in column A
|
| 1069 |
+
#Print N/A to all other cells, actual assignments will overwrite.
|
| 1070 |
+
for i in range(2,26):
|
| 1071 |
+
styleCell(ws.cell(row=n,column=i),'DNS')
|
| 1072 |
+
ws.cell(row=n,column=i).value="-"
|
| 1073 |
c=0
|
| 1074 |
for k in sorted(self.ee[eId].assignments,key=lambda k:int(k[:k.index('_')])):
|
| 1075 |
+
styleNfill(ws.cell(row=n,column=1+int(k[:k.index('_')])),self.slots[k])
|
| 1076 |
# ws2.cell(row=n+1,column=2+c).value=self.slots[k].dispNm+' '+ self.slLeg[self.slots[k].seqID-1][2]+' ('+self.slLeg[self.slots[k].seqID-1][1]+')'
|
| 1077 |
+
ws.cell(row=n,column=1+int(k[:k.index('_')])).value=self.slots[k].dispNm
|
| 1078 |
c+=1
|
| 1079 |
#==========================
|
| 1080 |
#Print succint assignment log to a separate sheet
|
|
|
|
| 1101 |
ws2.cell(column=1,row=2+n).value=rec
|
| 1102 |
n+=1
|
| 1103 |
|
| 1104 |
+
#==========================================================
|
| 1105 |
#Print assignments to a separate sheet, sequenced by seniority
|
| 1106 |
ws2 = wb.create_sheet(title="Assignments (Sen'ty)")
|
| 1107 |
ws2.cell(row=2,column=1).value='Seniority'
|
|
|
|
| 1120 |
styleNfill(ws2.cell(row=n+1,column=3+c),self.slots[k])
|
| 1121 |
ws2.cell(row=n+1,column=3+c).value=self.slots[k].dispNm+' '+ self.slLeg[self.slots[k].seqID-1][2]+' ('+self.slLeg[self.slots[k].seqID-1][1]+')'
|
| 1122 |
c+=1
|
| 1123 |
+
#====================================================
|
| 1124 |
|
| 1125 |
|
| 1126 |
|