Spaces:
Runtime error
Runtime error
Create new file
Browse files- codeFile.py +162 -0
codeFile.py
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from datetime import datetime, timedelta
|
| 2 |
+
from openpyxl import load_workbook
|
| 3 |
+
import openpyxl as pyxl
|
| 4 |
+
|
| 5 |
+
class Brw():
|
| 6 |
+
def __init__(self,bNo,brnd,fltr,frm,times):
|
| 7 |
+
self.brewNo=bNo
|
| 8 |
+
self.brand=brnd
|
| 9 |
+
# self.mixer
|
| 10 |
+
self.fltr=fltr
|
| 11 |
+
self.cookStart=t[0]
|
| 12 |
+
self.mixStart=t[1]
|
| 13 |
+
self.filtStart=t[2]
|
| 14 |
+
self.ktlStart=t[3]
|
| 15 |
+
self.ktlFull=t[4]
|
| 16 |
+
self.wrtclStart=t[5]
|
| 17 |
+
self.wrtclEnd=t[6]
|
| 18 |
+
|
| 19 |
+
def Gantiffy(brwschd):
|
| 20 |
+
wb = load_workbook(filename = brwSchd,data_only=True)
|
| 21 |
+
#Generate objects
|
| 22 |
+
ws=wb['Schedule']
|
| 23 |
+
brews={}
|
| 24 |
+
i=6
|
| 25 |
+
while ws['E'+str(i)].value!=None:
|
| 26 |
+
t=[] #to grab times
|
| 27 |
+
bNo=ws['C'+str(i)].value
|
| 28 |
+
brnd=ws['E'+str(i)].value
|
| 29 |
+
fltr=ws['F'+str(i)].value
|
| 30 |
+
frm=ws['G'+str(i)].value
|
| 31 |
+
for col in ('P','Q','R','S','T','U','V'):
|
| 32 |
+
t.append(ws[col+str(i)].value)
|
| 33 |
+
brews[bNo]=Brw(bNo,brnd,fltr,frm,t)
|
| 34 |
+
|
| 35 |
+
i+=1 #increment so no inf loop
|
| 36 |
+
#-------------------
|
| 37 |
+
#Column widths
|
| 38 |
+
#Generate a big list of all column names AAA-ZZZ in excel and set the column width to 1 pt for each
|
| 39 |
+
master=[]
|
| 40 |
+
alph=[chr(65+i) for i in range(26)]
|
| 41 |
+
master.extend(alph)
|
| 42 |
+
alph1=[[chr(65+i)+l for l in alph] for i in range(26)]
|
| 43 |
+
ls=[]
|
| 44 |
+
for l in alph1:
|
| 45 |
+
ls.extend(l)
|
| 46 |
+
master.extend(l)
|
| 47 |
+
alph2=[[chr(65+i)+l for l in ls] for i in range(26)]
|
| 48 |
+
alph2
|
| 49 |
+
ls=[]
|
| 50 |
+
for l in alph2:
|
| 51 |
+
ls.extend(l)
|
| 52 |
+
master.extend(l)
|
| 53 |
+
for c in master[1:1500]:
|
| 54 |
+
ws.column_dimensions[c].width =1.5
|
| 55 |
+
#------------------
|
| 56 |
+
#Set time step, in minutes, and print timeline
|
| 57 |
+
ts=10
|
| 58 |
+
i=0 #Pull first brew with below statement to get the first time needs to be on schedule
|
| 59 |
+
st=min(brews[list(brews.keys())[i]].cookStart,brews[list(brews.keys())[i]].mixStart)
|
| 60 |
+
# sheet["A3"].alignment = Alignment(text_rotation=90)
|
| 61 |
+
#Print starting value, starting from top of the hour
|
| 62 |
+
#-------------------
|
| 63 |
+
#Generate dictionary containing column id (number or letters?) keyed by datetime for that column at same time as printout
|
| 64 |
+
timeCol={}
|
| 65 |
+
for i in range(1420): #720 10 min chunks in 5 days
|
| 66 |
+
tVal=datetime(st.year,st.month,st.day,st.hour)+timedelta(minutes=10*i)
|
| 67 |
+
timeCol[tVal]=i+2 #Column Number 2 for iteration 0, etc
|
| 68 |
+
#Print the half hours and hours
|
| 69 |
+
if tVal.minute in (20,30):ws.cell(column=i+2,row=2).value="-" #Print '--' on the middle of the hour
|
| 70 |
+
elif tVal.minute==0:ws.cell(column=i+2,row=2).value="'"+str(tVal.hour) #Print the hour
|
| 71 |
+
if tVal.hour==0 and tVal.minute==0: #Print the weekday name
|
| 72 |
+
v=tVal.weekday()
|
| 73 |
+
if v==0: ws.cell(column=i+2,row=1).value="Monday"
|
| 74 |
+
elif v==1: ws.cell(column=i+2,row=1).value="Tuesday"
|
| 75 |
+
elif v==2: ws.cell(column=i+2,row=1).value="Wednesday"
|
| 76 |
+
elif v==3: ws.cell(column=i+2,row=1).value="Thursday"
|
| 77 |
+
elif v==4: ws.cell(column=i+2,row=1).value="Friday"
|
| 78 |
+
elif v==5: ws.cell(column=i+2,row=1).value="Saturday"
|
| 79 |
+
elif v==6: ws.cell(column=i+2,row=1).value="Sunday"
|
| 80 |
+
def styleCell(cl,val):
|
| 81 |
+
if val==0:
|
| 82 |
+
cl.font=pyxl.styles.Font(bold=True,size=14)
|
| 83 |
+
cl.alignment=pyxl.styles.Alignment(horizontal='center')
|
| 84 |
+
cl.fill=pyxl.styles.PatternFill(fill_type="solid",start_color='0092D050',end_color='0092D050')
|
| 85 |
+
cl.border=pyxl.styles.Border(left=pyxl.styles.Side(border_style='thin'),
|
| 86 |
+
right=pyxl.styles.Side(border_style='thin'),
|
| 87 |
+
top=pyxl.styles.Side(border_style='thin'),
|
| 88 |
+
bottom=pyxl.styles.Side(border_style='thin'))
|
| 89 |
+
else:
|
| 90 |
+
cl.fill=pyxl.styles.PatternFill(fill_type="solid",start_color='00B0F0',end_color='00B0F0')
|
| 91 |
+
cl.font=pyxl.styles.Font(bold=True,size=14,color="00FFFFFF")
|
| 92 |
+
cl.alignment=pyxl.styles.Alignment(horizontal='center')
|
| 93 |
+
cl.border=pyxl.styles.Border(left=pyxl.styles.Side(border_style='thin'),
|
| 94 |
+
right=pyxl.styles.Side(border_style='thin'),
|
| 95 |
+
top=pyxl.styles.Side(border_style='thin'),
|
| 96 |
+
bottom=pyxl.styles.Side(border_style='thin'))
|
| 97 |
+
#-------------------
|
| 98 |
+
#Print brew info to the cell on each row where it starts,
|
| 99 |
+
#and merge that cell appropriately to the right.
|
| 100 |
+
#Round the previous process down to nearest 10 min and next process up to ensure no conflcit when the schedule makes them very tight
|
| 101 |
+
def d_key(tm):#d for round DOWN
|
| 102 |
+
#Given time from a brew object, returns that time rounded DOWN to the nearest 10 minute,
|
| 103 |
+
#corresponding to key for finding which column to print to
|
| 104 |
+
tm = tm - timedelta(minutes=tm.minute % 10,seconds=tm.second,microseconds=tm.microsecond)
|
| 105 |
+
return tm
|
| 106 |
+
def u_key(tm):#u for round UP
|
| 107 |
+
#returns key for slot rounded up.
|
| 108 |
+
discard = timedelta(minutes=tm.minute % 10,seconds=tm.second,microseconds=tm.microsecond)
|
| 109 |
+
tm -= discard
|
| 110 |
+
# if discard >= timedelta(minutes=5): #Include this statement and indent next to make it classic rounding
|
| 111 |
+
tm += timedelta(minutes=10)
|
| 112 |
+
return tm
|
| 113 |
+
class mm1():
|
| 114 |
+
def __init__(self):
|
| 115 |
+
self.log=[]
|
| 116 |
+
def sched(self,st,en):
|
| 117 |
+
self.log.append((st,en))
|
| 118 |
+
def busy(self,st,en):
|
| 119 |
+
for r in self.log:
|
| 120 |
+
if r[0]<st<r[1]:
|
| 121 |
+
return True
|
| 122 |
+
if r[0]<en<r[1]:
|
| 123 |
+
return True
|
| 124 |
+
if st<r[0] and r[1]<en:
|
| 125 |
+
return True
|
| 126 |
+
return False
|
| 127 |
+
|
| 128 |
+
mm=mm1()
|
| 129 |
+
for brN in brews.keys():
|
| 130 |
+
b=brews[brN]
|
| 131 |
+
#Cereal Cooker - assume only used if cook time is diff from mix time
|
| 132 |
+
r=3
|
| 133 |
+
if d_key(b.cookStart)!=d_key(b.mixStart):
|
| 134 |
+
ws.cell(column=timeCol[u_key(b.cookStart)],row=r).value=str(b.brewNo) +b.brand[:5]
|
| 135 |
+
ws.merge_cells(start_row=r, start_column=timeCol[u_key(b.cookStart)], end_row=r, end_column=timeCol[d_key(b.mixStart)])
|
| 136 |
+
styleCell(ws.cell(column=timeCol[u_key(b.cookStart)],row=r),brN%2)
|
| 137 |
+
#Mixer
|
| 138 |
+
if mm.busy(b.mixStart,b.filtStart):r=5
|
| 139 |
+
else:
|
| 140 |
+
r=4
|
| 141 |
+
mm.sched(b.mixStart,b.filtStart)
|
| 142 |
+
ws.cell(column=timeCol[u_key(b.mixStart)],row=r).value=str(b.brewNo) +b.brand[:5]
|
| 143 |
+
ws.merge_cells(start_row=r, start_column=timeCol[u_key(b.mixStart)], end_row=r, end_column=timeCol[d_key(b.filtStart)])
|
| 144 |
+
styleCell(ws.cell(column=timeCol[u_key(b.mixStart)],row=r),brN%2)
|
| 145 |
+
#Filter - choose row based on
|
| 146 |
+
if fltr=='1-MF':r=6
|
| 147 |
+
elif fltr=='2-MF':r=7
|
| 148 |
+
else:r=8
|
| 149 |
+
ws.cell(column=timeCol[u_key(b.filtStart)],row=r).value=str(b.brewNo) +b.brand[:5]
|
| 150 |
+
ws.merge_cells(start_row=r, start_column=timeCol[u_key(b.filtStart)], end_row=r, end_column=timeCol[d_key(b.ktlFull)])
|
| 151 |
+
styleCell(ws.cell(column=timeCol[u_key(b.filtStart)],row=r),brN%2)
|
| 152 |
+
#Kettle
|
| 153 |
+
r=9
|
| 154 |
+
ws.cell(column=timeCol[u_key(b.ktlStart)],row=r).value=str(b.brewNo) +b.brand[:5]
|
| 155 |
+
ws.merge_cells(start_row=r, start_column=timeCol[u_key(b.ktlStart)], end_row=r, end_column=timeCol[d_key(b.wrtclStart)])
|
| 156 |
+
styleCell(ws.cell(column=timeCol[u_key(b.ktlStart)],row=r),brN%2)
|
| 157 |
+
#Cool
|
| 158 |
+
r=10
|
| 159 |
+
ws.cell(column=timeCol[u_key(b.wrtclStart)],row=r).value=str(b.brewNo) +b.brand[:5]
|
| 160 |
+
ws.merge_cells(start_row=r, start_column=timeCol[u_key(b.wrtclStart)], end_row=r, end_column=timeCol[d_key(b.wrtclEnd)])
|
| 161 |
+
styleCell(ws.cell(column=timeCol[u_key(b.wrtclStart)],row=r),brN%2)
|
| 162 |
+
wb.save(filename = 'gantt.xlsx')
|