class-scheduling / HtmlOutput.py
garizz's picture
Update HtmlOutput.py
5814fd7
Raw History Blame Contribute Delete
7.41 kB
from model.Constant import Constant
from model.Reservation import Reservation
from collections import defaultdict
import streamlit as st
import json
class HtmlOutput:
ROOM_COLUMN_NUMBER = Constant.DAYS_NUM + 1
ROOM_ROW_NUMBER = Constant.DAY_HOURS + 1
# COLOR1 = "#319378"
# COLOR2 = "#CE0000"
CRITERIAS = ('R', 'S', 'L', 'P', 'G')
# CRITERIAS_DESCR = ("Current room has {any}overlapping", "Current room has {any}enough seats",
# "Current room with {any}enough computers if they are required",
# "Professors have {any}overlapping classes", "Student groups has {any}overlapping classes")
PERIODS = (
"","8 - 8h50", "8h50 - 9h40", "9h40 - 10h30", "10h35 - 11h25", "11h25 - 12h15", "12h15 - 13h05", "13h15 - 14h05", "14h05 - 14h55", "14h55 - 15h45", "15h50 - 16h40", "16h40 - 17h30")
WEEK_DAYS = ("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday")
@staticmethod
def getCourseClass(cc, criterias, ci):
sb = []
sb.append(" <span style='color:#00FFFF' title=''> <b>MH: <b/> </span>")
sb.append(cc.Course.Name)
sb.append("<br /> <span style='color:#00FFFF' title=''> <b>GV: <b/> </span>")
sb.append(cc.Professor.Name)
sb.append("<br /> <span style='color:#00FFFF' title=''> <b>Room: <b/> </span>")
# sb.append(room.Name)
# sb.append("/".join(map(lambda grp: grp.Name, cc.Groups)),)
if cc.LabRequired:
sb.append(" <br /><span style='color:#00FFFF' title=''> <b>Lab <b/> </span>")
return sb
@staticmethod
def generateTimeTable(solution, slot_table):
ci = 0
time_table = defaultdict(list)
items = solution.classes.items
ROOM_COLUMN_NUMBER = HtmlOutput.ROOM_COLUMN_NUMBER
getCourseClass = HtmlOutput.getCourseClass
for cc, reservation_index in items():
reservation = Reservation.parse(reservation_index)
# coordinate of time-space slot
dayId = reservation.Day + 1
dur = cc.Duration
periodId = reservation.Time + 1
if dur == 3:
if 3 < periodId <= 6:
periodId = 4
elif 1 <= periodId <= 3:
periodId = 1
else:
periodId = 7
elif dur == 4 or dur == 5:
if periodId <= 6:
periodId = 1
else:
periodId = 7
else:
periodId = 1
roomId = reservation.Room
key = (periodId, roomId)
if key in slot_table:
room_duration = slot_table[key]
else:
room_duration = ROOM_COLUMN_NUMBER * [0]
slot_table[key] = room_duration
room_duration[dayId] = dur
for m in range(1, dur):
next_key = (periodId + m, roomId)
if next_key not in slot_table:
slot_table[next_key] = ROOM_COLUMN_NUMBER * [0]
if slot_table[next_key][dayId] < 1:
slot_table[next_key][dayId] = -1
if key in time_table:
room_schedule = time_table[key]
else:
room_schedule = ROOM_COLUMN_NUMBER * [None]
time_table[key] = room_schedule
room_schedule[dayId] = "".join(getCourseClass(cc, solution.criteria, ci))
ci += len(HtmlOutput.CRITERIAS)
return time_table
@staticmethod
def getHtmlCell(content, rowspan):
if rowspan == 0:
return "<td></td>"
if content is None:
return ""
sb = []
if rowspan > 1:
sb.append("<td style='border: .25em solid white; padding: .25em' rowspan='")
sb.append(rowspan)
sb.append("'>")
else:
sb.append("<td style='border: .25em solid white; padding: .25em'>")
sb.append(content)
sb.append("</td>")
return "".join(str(v) for v in sb)
@staticmethod
def getResult(solution):
configuration = solution.configuration
nr = configuration.numberOfRooms
getRoomById = configuration.getRoomById
slot_table = defaultdict(list)
time_table = HtmlOutput.generateTimeTable(solution, slot_table) # Tuple[0] = time, Tuple[1] = roomId
# st.markdown(slot_table)
if not slot_table or not time_table:
return ""
sb = []
for roomId in range(nr):
temp = []
room = getRoomById(roomId)
for periodId in range(HtmlOutput.ROOM_ROW_NUMBER):
if periodId == 0:
temp.append("<div id='room_")
temp.append(room.Name)
temp.append("' style='padding: 0.5em'>\n")
temp.append("<table style=' border: .25em solid white; text-align: center; width: 100%'>\n")
temp.append(HtmlOutput.getTableHeader(room))
else:
key = (periodId, roomId)
room_duration = slot_table[key] if key in slot_table.keys() else None
room_schedule = time_table[key] if key in time_table.keys() else None
temp.append("<tr>")
for dayId in range(HtmlOutput.ROOM_COLUMN_NUMBER):
if dayId == 0:
temp.append("<th style='color: #00FFFF; border: .25em solid white; text-align: center; padding: .25em' scope='row' colspan='2'>")
temp.append(HtmlOutput.PERIODS[periodId])
temp.append("</th>\n")
continue
if room_schedule is None and room_duration is None:
continue
content = room_schedule[dayId] if room_schedule is not None else None
temp.append(HtmlOutput.getHtmlCell(content, room_duration[dayId]))
temp.append("</tr>\n")
if periodId == HtmlOutput.ROOM_ROW_NUMBER - 1:
temp.append("</table>\n</div>\n")
temp = json.dumps(temp).replace(" <b>Room: <b/> </span>", "<b> <b>Room: <b/> </span>{}".format(room.Name))
temp = json.loads(temp)
sb = sb + temp
return "".join(str(v) for v in sb)
@staticmethod
def getTableHeader(room):
sb = ["<tr><th style='color:#00FFFF; border: .25em solid white' scope='col' colspan='2'>Room: ", room.Name, "</th>\n"]
for weekDay in HtmlOutput.WEEK_DAYS:
sb.append("<th style='color: #00FFFF; border: .25em solid white; padding: .25em; width: 15%; text-align: center' scope='col' rowspan='2'>")
sb.append(weekDay)
sb.append("</th>\n")
sb.append("</tr>\n")
sb.append("<tr>\n")
sb.append("<th style='color:#00FFFF; border: .25em solid white; padding: .25em'>Lab: ")
sb.append("Yes" if room.Lab else "No")
sb.append("</th>\n")
sb.append("<th style='color:#00FFFF; border: .25em solid white; padding: .25em'>Seats: ")
sb.append(room.NumberOfSeats)
sb.append("</th>\n")
sb.append("</tr>\n")
return "".join(str(v) for v in sb)