Lecture 1-91 blank table and give space for lecture completion(tick space only) and topic name( blank space) i have to complete Biochemistry lectures
ls -la /home/daytona/workspace/ 2>/dev/null || mkdir -p /home/daytona/workspace
mkdir -p /home/daytona/workspace/biochem-tracker && cat << 'EOF' > /home/daytona/workspace/biochem-tracker/create_tracker.py import openpyxl from openpyxl.styles import ( Font, PatternFill, Alignment, Border, Side, GradientFill ) from openpyxl.utils import get_column_letter wb = openpyxl.Workbook() ws = wb.active ws.title = "Biochemistry Lectures" # โโ Colours โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ HEADER_BG = "1A237E" # deep indigo HEADER_FG = "FFFFFF" ROW_ODD = "E8EAF6" # very light indigo ROW_EVEN = "FFFFFF" TICK_BG = "C8E6C9" # light green BORDER_COL = "9FA8DA" thin = Side(style="thin", color=BORDER_COL) med = Side(style="medium", color=HEADER_BG) def cell_border(top=thin, bot=thin, left=thin, right=thin): return Border(top=top, bottom=bot, left=left, right=right) # โโ Column widths โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ ws.column_dimensions["A"].width = 10 # Lecture # ws.column_dimensions["B"].width = 45 # Topic Name ws.column_dimensions["C"].width = 14 # Completed โ # โโ Title row โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ ws.merge_cells("A1:C1") title_cell = ws["A1"] title_cell.value = "Biochemistry Lecture Tracker" title_cell.font = Font(name="Arial", bold=True, size=16, color=HEADER_FG) title_cell.fill = PatternFill("solid", fgColor=HEADER_BG) title_cell.alignment = Alignment(horizontal="center", vertical="center") ws.row_dimensions[1].height = 34 # โโ Sub-header row โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ ws.merge_cells("A2:C2") sub = ws["A2"] sub.value = "Lectures 1 โ 91 | Tick the box when completed" sub.font = Font(name="Arial", italic=True, size=10, color="5C6BC0") sub.alignment = Alignment(horizontal="center", vertical="center") ws.row_dimensions[2].height = 18 # โโ Column headers โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ headers = [("A3","Lecture #"), ("B3","Topic Name"), ("C3","Completed โ")] for cell_addr, label in headers: c = ws[cell_addr] c.value = label c.font = Font(name="Arial", bold=True, size=11, color=HEADER_FG) c.fill = PatternFill("solid", fgColor=HEADER_BG) c.alignment = Alignment(horizontal="center", vertical="center") c.border = cell_border(top=med, bot=med, left=med, right=med) ws.row_dimensions[3].height = 22 # โโ Data rows 1-91 โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ for i in range(1, 92): row = i + 3 # row 4 โ lecture 1, row 94 โ lecture 91 bg = ROW_ODD if i % 2 == 1 else ROW_EVEN fill = PatternFill("solid", fgColor=bg) # Lecture number num_cell = ws.cell(row=row, column=1, value=i) num_cell.font = Font(name="Arial", bold=True, size=11, color="1A237E") num_cell.fill = fill num_cell.alignment = Alignment(horizontal="center", vertical="center") num_cell.border = cell_border() # Topic name (blank โ student fills in) topic_cell = ws.cell(row=row, column=2, value="") topic_cell.font = Font(name="Arial", size=11) topic_cell.fill = fill topic_cell.alignment = Alignment(horizontal="left", vertical="center", wrap_text=True) topic_cell.border = cell_border() # Completed checkbox cell (blank โ student ticks) tick_cell = ws.cell(row=row, column=3, value="") tick_cell.font = Font(name="Arial", size=13, bold=True, color="2E7D32") tick_cell.fill = PatternFill("solid", fgColor=TICK_BG) tick_cell.alignment = Alignment(horizontal="center", vertical="center") tick_cell.border = cell_border() ws.row_dimensions[row].height = 22 # โโ Freeze panes at row 4 (keep header visible while scrolling) โโโโโโโโโโโโโโโ ws.freeze_panes = "A4" # โโ Progress summary (below the table) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ summary_row = 96 ws.merge_cells(f"A{summary_row}:C{summary_row}") sr = ws[f"A{summary_row}"] sr.value = ('Tip: Type โ in column C when you finish a lecture. ' 'Topic name goes in column B.') sr.font = Font(name="Arial", italic=True, size=9, color="757575") sr.alignment = Alignment(horizontal="center") # โโ Save โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ out = "/home/daytona/workspace/biochem-tracker/Biochemistry_Lecture_Tracker.xlsx" wb.save(out) print(f"Saved: {out}") EOF python3 /home/daytona/workspace/biochem-tracker/create_tracker.py
df -h /home/daytona/workspace/ && ls -la /home/daytona/workspace/biochem-tracker/
python3 - << 'EOF' import openpyxl, shutil from openpyxl.styles import Font, PatternFill, Alignment, Border, Side wb = openpyxl.Workbook() ws = wb.active ws.title = "Biochemistry Lectures" HEADER_BG = "1A237E" HEADER_FG = "FFFFFF" ROW_ODD = "E8EAF6" ROW_EVEN = "FFFFFF" TICK_BG = "C8E6C9" BORDER_COL= "9FA8DA" thin = Side(style="thin", color=BORDER_COL) med = Side(style="medium", color=HEADER_BG) def cb(top=thin, bot=thin, left=thin, right=thin): return Border(top=top, bottom=bot, left=left, right=right) ws.column_dimensions["A"].width = 10 ws.column_dimensions["B"].width = 46 ws.column_dimensions["C"].width = 14 # Title ws.merge_cells("A1:C1") t = ws["A1"] t.value = "Biochemistry Lecture Tracker" t.font = Font(name="Arial", bold=True, size=16, color=HEADER_FG) t.fill = PatternFill("solid", fgColor=HEADER_BG) t.alignment = Alignment(horizontal="center", vertical="center") ws.row_dimensions[1].height = 34 # Sub-header ws.merge_cells("A2:C2") s = ws["A2"] s.value = "Lectures 1 โ 91 | Type โ in column C when completed | Write topic name in column B" s.font = Font(name="Arial", italic=True, size=10, color="5C6BC0") s.alignment = Alignment(horizontal="center", vertical="center") ws.row_dimensions[2].height = 18 # Column headers for addr, label in [("A3","Lecture #"), ("B3","Topic Name"), ("C3","Completed โ")]: c = ws[addr] c.value = label c.font = Font(name="Arial", bold=True, size=11, color=HEADER_FG) c.fill = PatternFill("solid", fgColor=HEADER_BG) c.alignment = Alignment(horizontal="center", vertical="center") c.border = cb(top=med, bot=med, left=med, right=med) ws.row_dimensions[3].height = 22 # Data rows for i in range(1, 92): row = i + 3 bg = ROW_ODD if i % 2 == 1 else ROW_EVEN fill = PatternFill("solid", fgColor=bg) n = ws.cell(row=row, column=1, value=i) n.font = Font(name="Arial", bold=True, size=11, color="1A237E") n.fill = fill n.alignment = Alignment(horizontal="center", vertical="center") n.border = cb() b = ws.cell(row=row, column=2, value="") b.font = Font(name="Arial", size=11) b.fill = fill b.alignment = Alignment(horizontal="left", vertical="center", wrap_text=True) b.border = cb() tk = ws.cell(row=row, column=3, value="") tk.font = Font(name="Arial", size=13, bold=True, color="2E7D32") tk.fill = PatternFill("solid", fgColor=TICK_BG) tk.alignment = Alignment(horizontal="center", vertical="center") tk.border = cb() ws.row_dimensions[row].height = 22 ws.freeze_panes = "A4" tip_row = 96 ws.merge_cells(f"A{tip_row}:C{tip_row}") tip = ws[f"A{tip_row}"] tip.value = "Tip: Type โ in column C when you finish a lecture. Topic name goes in column B." tip.font = Font(name="Arial", italic=True, size=9, color="757575") tip.alignment = Alignment(horizontal="center") tmp = "/tmp/Biochemistry_Lecture_Tracker.xlsx" wb.save(tmp) shutil.copy(tmp, "/home/daytona/workspace/biochem-tracker/Biochemistry_Lecture_Tracker.xlsx") print("Done") EOF
python3 - << 'EOF' import openpyxl, shutil from openpyxl.styles import Font, PatternFill, Alignment, Border, Side wb = openpyxl.Workbook() ws = wb.active ws.title = "Biochemistry Lectures" HEADER_BG = "1A237E" HEADER_FG = "FFFFFF" ROW_ODD = "E8EAF6" ROW_EVEN = "FFFFFF" TICK_BG = "C8E6C9" BORDER_COL= "9FA8DA" thin = Side(style="thin", color=BORDER_COL) med = Side(style="medium", color=HEADER_BG) def cb(top=thin, bot=thin, left=thin, right=thin): return Border(top=top, bottom=bot, left=left, right=right) ws.column_dimensions["A"].width = 10 ws.column_dimensions["B"].width = 46 ws.column_dimensions["C"].width = 14 ws.merge_cells("A1:C1") t = ws["A1"] t.value = "Biochemistry Lecture Tracker" t.font = Font(name="Arial", bold=True, size=16, color=HEADER_FG) t.fill = PatternFill("solid", fgColor=HEADER_BG) t.alignment = Alignment(horizontal="center", vertical="center") ws.row_dimensions[1].height = 34 ws.merge_cells("A2:C2") s = ws["A2"] s.value = "Lectures 1 - 91 | Type tick/check in column C when completed | Write topic name in column B" s.font = Font(name="Arial", italic=True, size=10, color="5C6BC0") s.alignment = Alignment(horizontal="center", vertical="center") ws.row_dimensions[2].height = 18 for addr, label in [("A3","Lecture #"), ("B3","Topic Name"), ("C3","Completed")]: c = ws[addr] c.value = label c.font = Font(name="Arial", bold=True, size=11, color=HEADER_FG) c.fill = PatternFill("solid", fgColor=HEADER_BG) c.alignment = Alignment(horizontal="center", vertical="center") c.border = cb(top=med, bot=med, left=med, right=med) ws.row_dimensions[3].height = 22 for i in range(1, 92): row = i + 3 bg = ROW_ODD if i % 2 == 1 else ROW_EVEN fill = PatternFill("solid", fgColor=bg) n = ws.cell(row=row, column=1, value=i) n.font = Font(name="Arial", bold=True, size=11, color="1A237E") n.fill = fill n.alignment = Alignment(horizontal="center", vertical="center") n.border = cb() b = ws.cell(row=row, column=2, value="") b.font = Font(name="Arial", size=11) b.fill = fill b.alignment = Alignment(horizontal="left", vertical="center", wrap_text=True) b.border = cb() tk = ws.cell(row=row, column=3, value="") tk.font = Font(name="Arial", size=13, bold=True, color="2E7D32") tk.fill = PatternFill("solid", fgColor=TICK_BG) tk.alignment = Alignment(horizontal="center", vertical="center") tk.border = cb() ws.row_dimensions[row].height = 22 ws.freeze_panes = "A4" tip_row = 96 ws.merge_cells(f"A{tip_row}:C{tip_row}") tip = ws[f"A{tip_row}"] tip.value = "Tip: Type a tick or check mark in column C when done. Topic name goes in column B." tip.font = Font(name="Arial", italic=True, size=9, color="757575") tip.alignment = Alignment(horizontal="center") tmp = "/tmp/Biochemistry_Lecture_Tracker.xlsx" wb.save(tmp) # copy using open/read/write to avoid chmod issues with open(tmp, 'rb') as src, open("/home/daytona/workspace/biochem-tracker/Biochemistry_Lecture_Tracker.xlsx", 'wb') as dst: dst.write(src.read()) print("Done - file written") EOF
Biochemistry Lecture Tracker
Spreadsheet ยท XLSX
| Column | Purpose |
|---|---|
| A โ Lecture # | Pre-filled: 1 โ 91 |
| B โ Topic Name | Blank โ write the lecture topic here |
| C โ Completed | Blank (green cell) โ type a โ or any mark when done |
Set it in 1 page only and in pdf format
python3 - << 'EOF' from reportlab.lib.pagesizes import A3, landscape from reportlab.lib import colors from reportlab.lib.units import mm from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle from reportlab.lib.enums import TA_CENTER, TA_LEFT out = "/tmp/Biochemistry_Lecture_Tracker.pdf" # Use A3 landscape to fit 91 rows on one page doc = SimpleDocTemplate( out, pagesize=landscape(A3), leftMargin=10*mm, rightMargin=10*mm, topMargin=10*mm, bottomMargin=10*mm, ) styles = getSampleStyleSheet() title_style = ParagraphStyle( "title", fontSize=18, fontName="Helvetica-Bold", textColor=colors.white, alignment=TA_CENTER, spaceAfter=2 ) sub_style = ParagraphStyle( "sub", fontSize=9, fontName="Helvetica-Oblique", textColor=colors.HexColor("#5C6BC0"), alignment=TA_CENTER, spaceAfter=4 ) # โโ Build table data โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ header = ["Lecture #", "Topic Name", "Completed โ"] data = [header] for i in range(1, 92): data.append([str(i), "", ""]) # Page width (A3 landscape) minus margins page_w = landscape(A3)[0] - 20*mm # ~400mm usable # Column widths: lecture# small, topic wide, tick small col_w = [18*mm, page_w - 18*mm - 28*mm, 28*mm] # Row heights โ shrink to fit 91 data rows + 1 header on one page # A3 landscape height โ 297mm, minus margins 20mm, minus title ~18mm = ~259mm for table # 92 rows โ ~2.8mm each row_h = 7.2 # points (~2.54mm) tbl = Table(data, colWidths=col_w, rowHeights=[14] + [row_h]*91, repeatRows=1) # โโ Alternating row colours โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ HEADER_BG = colors.HexColor("#1A237E") ODD = colors.HexColor("#E8EAF6") EVEN = colors.white TICK_BG = colors.HexColor("#C8E6C9") BORDER = colors.HexColor("#9FA8DA") style_cmds = [ # Header row ("BACKGROUND", (0,0), (-1,0), HEADER_BG), ("TEXTCOLOR", (0,0), (-1,0), colors.white), ("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"), ("FONTSIZE", (0,0), (-1,0), 9), ("ALIGN", (0,0), (-1,0), "CENTER"), ("VALIGN", (0,0), (-1,-1), "MIDDLE"), # Data rows font ("FONTNAME", (0,1), (-1,-1), "Helvetica"), ("FONTSIZE", (0,1), (-1,-1), 6), # Lecture # column โ bold, centered, indigo text ("FONTNAME", (0,1), (0,-1), "Helvetica-Bold"), ("TEXTCOLOR", (0,1), (0,-1), colors.HexColor("#1A237E")), ("ALIGN", (0,0), (0,-1), "CENTER"), # Topic col โ left aligned ("ALIGN", (1,1), (1,-1), "LEFT"), # Completed col โ centered, green background ("ALIGN", (2,0), (2,-1), "CENTER"), # Grid ("GRID", (0,0), (-1,-1), 0.4, BORDER), ("LINEBELOW", (0,0), (-1,0), 1.2, HEADER_BG), # Row padding ("TOPPADDING", (0,0), (-1,-1), 1), ("BOTTOMPADDING",(0,0),(-1,-1), 1), ("LEFTPADDING", (0,0), (-1,-1), 3), ("RIGHTPADDING",(0,0), (-1,-1), 3), ] # Alternating row colours + green tick column for i in range(1, 92): bg = ODD if i % 2 == 1 else EVEN style_cmds.append(("BACKGROUND", (0,i), (1,i), bg)) style_cmds.append(("BACKGROUND", (2,i), (2,i), TICK_BG)) tbl.setStyle(TableStyle(style_cmds)) # โโ Title block โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ from reportlab.platypus import KeepTogether from reportlab.graphics.shapes import Drawing, Rect, String from reportlab.graphics import renderPDF # Simple coloured title bar via a table row title_data = [["Biochemistry Lecture Tracker โ Lectures 1 to 91"]] title_tbl = Table(title_data, colWidths=[sum(col_w)]) title_tbl.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,-1), HEADER_BG), ("TEXTCOLOR", (0,0), (-1,-1), colors.white), ("FONTNAME", (0,0), (-1,-1), "Helvetica-Bold"), ("FONTSIZE", (0,0), (-1,-1), 14), ("ALIGN", (0,0), (-1,-1), "CENTER"), ("VALIGN", (0,0), (-1,-1), "MIDDLE"), ("TOPPADDING", (0,0), (-1,-1), 6), ("BOTTOMPADDING",(0,0), (-1,-1), 6), ])) sub_data = [["Tick column C when completed | Write topic name in column B"]] sub_tbl = Table(sub_data, colWidths=[sum(col_w)]) sub_tbl.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,-1), colors.HexColor("#E8EAF6")), ("TEXTCOLOR", (0,0), (-1,-1), colors.HexColor("#5C6BC0")), ("FONTNAME", (0,0), (-1,-1), "Helvetica-Oblique"), ("FONTSIZE", (0,0), (-1,-1), 8), ("ALIGN", (0,0), (-1,-1), "CENTER"), ("TOPPADDING", (0,0), (-1,-1), 3), ("BOTTOMPADDING",(0,0), (-1,-1), 3), ])) elements = [title_tbl, sub_tbl, tbl] doc.build(elements) print("PDF saved to", out) EOF
with open("/tmp/Biochemistry_Lecture_Tracker.pdf", 'rb') as src, \ open("/home/daytona/workspace/biochem-tracker/Biochemistry_Lecture_Tracker.pdf", 'wb') as dst: dst.write(src.read()) print("Copied to workspace")
python3 -c " src = open('/tmp/Biochemistry_Lecture_Tracker.pdf', 'rb').read() open('/home/daytona/workspace/biochem-tracker/Biochemistry_Lecture_Tracker.pdf', 'wb').write(src) print('Copied', len(src), 'bytes') "
Biochemistry Lecture Tracker
PDF Document ยท PDF
Divide it into three column for better space in landscape a4 page format for printing
python3 - << 'EOF' from reportlab.lib.pagesizes import A4, landscape from reportlab.lib import colors from reportlab.lib.units import mm from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Spacer from reportlab.lib.styles import getSampleStyleSheet out_tmp = "/tmp/Biochemistry_Lecture_Tracker_A4.pdf" PAGE = landscape(A4) # 297 x 210 mm LM = RM = 8*mm TM = 8*mm BM = 6*mm doc = SimpleDocTemplate( out_tmp, pagesize=PAGE, leftMargin=LM, rightMargin=RM, topMargin=TM, bottomMargin=BM, ) # โโ Colours โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ HDR_BG = colors.HexColor("#1A237E") HDR_FG = colors.white ODD = colors.HexColor("#E8EAF6") EVEN = colors.white TICK_BG = colors.HexColor("#C8E6C9") BORDER = colors.HexColor("#9FA8DA") # โโ Page & column geometry โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ usable_w = PAGE[0] - LM - RM # ~281 mm usable_h = PAGE[1] - TM - BM # ~196 mm GAP = 5*mm # gap between the 3 column-groups group_w = (usable_w - 2*GAP) / 3 # width of one column-group # Each group has 3 sub-columns: #, Topic, Tick n_w = 9*mm tick_w = 11*mm topic_w = group_w - n_w - tick_w # โโ Split 91 lectures into 3 groups of ~31, ~30, ~30 โโโโโโโโโโโโโโโโโโโโโโโโ # 31 + 30 + 30 = 91 splits = [(1, 31), (32, 61), (62, 91)] # Build one sub-table per column-group sub_tables = [] for (start, end) in splits: rows = [["#", "Topic Name", "โ"]] for i in range(start, end + 1): rows.append([str(i), "", ""]) n_data = end - start + 1 # number of data rows # title height + data rows must fit usable_h # title row = 13pt, data rows fill the rest title_h = 13 data_h = (usable_h - title_h) / n_data # auto-distribute col_widths = [n_w, topic_w, tick_w] row_heights = [title_h] + [data_h] * n_data tbl = Table(rows, colWidths=col_widths, rowHeights=row_heights) cmds = [ # Header ("BACKGROUND", (0,0), (-1,0), HDR_BG), ("TEXTCOLOR", (0,0), (-1,0), HDR_FG), ("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"), ("FONTSIZE", (0,0), (-1,0), 7), ("ALIGN", (0,0), (-1,0), "CENTER"), ("VALIGN", (0,0), (-1,-1), "MIDDLE"), # Data font ("FONTNAME", (0,1), (-1,-1), "Helvetica"), ("FONTSIZE", (0,1), (-1,-1), 6.5), # # col ("FONTNAME", (0,1), (0,-1), "Helvetica-Bold"), ("TEXTCOLOR", (0,1), (0,-1), colors.HexColor("#1A237E")), ("ALIGN", (0,0), (0,-1), "CENTER"), # Topic col ("ALIGN", (1,1), (1,-1), "LEFT"), # Tick col ("ALIGN", (2,0), (2,-1), "CENTER"), # Grid ("GRID", (0,0), (-1,-1), 0.35, BORDER), ("LINEBELOW", (0,0), (-1,0), 1.0, HDR_BG), # Padding ("TOPPADDING", (0,0), (-1,-1), 1), ("BOTTOMPADDING", (0,0), (-1,-1), 1), ("LEFTPADDING", (0,0), (-1,-1), 2), ("RIGHTPADDING", (0,0), (-1,-1), 2), ] for idx in range(1, n_data + 1): bg = ODD if idx % 2 == 1 else EVEN cmds.append(("BACKGROUND", (0,idx), (1,idx), bg)) cmds.append(("BACKGROUND", (2,idx), (2,idx), TICK_BG)) tbl.setStyle(TableStyle(cmds)) sub_tables.append(tbl) # โโ Arrange 3 sub-tables side by side in a wrapper table โโโโโโโโโโโโโโโโโโโโโ # Spacer column between groups spacer_w = GAP wrapper_data = [[sub_tables[0], "", sub_tables[1], "", sub_tables[2]]] wrapper_widths = [group_w, spacer_w, group_w, spacer_w, group_w] wrapper = Table(wrapper_data, colWidths=wrapper_widths) wrapper.setStyle(TableStyle([ ("VALIGN", (0,0), (-1,-1), "TOP"), ("PADDING", (0,0), (-1,-1), 0), ("LEFTPADDING", (0,0), (-1,-1), 0), ("RIGHTPADDING", (0,0), (-1,-1), 0), ("TOPPADDING", (0,0), (-1,-1), 0), ("BOTTOMPADDING",(0,0), (-1,-1), 0), ])) # โโ Title banner โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ title_data = [["Biochemistry Lecture Tracker โ Lectures 1 to 91 | Write topic in blank column | Tick when completed"]] title_tbl = Table(title_data, colWidths=[usable_w]) title_tbl.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,-1), HDR_BG), ("TEXTCOLOR", (0,0), (-1,-1), HDR_FG), ("FONTNAME", (0,0), (-1,-1), "Helvetica-Bold"), ("FONTSIZE", (0,0), (-1,-1), 10), ("ALIGN", (0,0), (-1,-1), "CENTER"), ("VALIGN", (0,0), (-1,-1), "MIDDLE"), ("TOPPADDING", (0,0), (-1,-1), 5), ("BOTTOMPADDING", (0,0), (-1,-1), 5), ])) elements = [title_tbl, Spacer(1, 3*mm), wrapper] doc.build(elements) print("PDF saved:", out_tmp) EOF
python3 - << 'EOF' from reportlab.lib.pagesizes import A4, landscape from reportlab.lib import colors from reportlab.lib.units import mm from reportlab.pdfgen import canvas as pdfcanvas from reportlab.platypus import Table, TableStyle PAGE_W, PAGE_H = landscape(A4) # 841.89 x 595.28 pt LM = RM = 8*mm TM = 8*mm BM = 6*mm out_tmp = "/tmp/Biochemistry_A4_3col.pdf" c = pdfcanvas.Canvas(out_tmp, pagesize=landscape(A4)) # โโ Colours โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ HDR_BG = colors.HexColor("#1A237E") HDR_FG = colors.white ODD = colors.HexColor("#E8EAF6") EVEN = colors.white TICK_BG = colors.HexColor("#C8E6C9") BORDER = colors.HexColor("#9FA8DA") usable_w = PAGE_W - LM - RM # available width in pts usable_h = PAGE_H - TM - BM # available height in pts TITLE_H = 18 # pts for title banner GAP = 4*mm group_w = (usable_w - 2*GAP) / 3 n_w = 10*mm tick_w = 12*mm topic_w = group_w - n_w - tick_w splits = [(1, 31), (32, 61), (62, 91)] # โโ Draw title banner โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ banner_y = PAGE_H - TM - TITLE_H c.setFillColor(HDR_BG) c.rect(LM, banner_y, usable_w, TITLE_H, fill=1, stroke=0) c.setFillColor(HDR_FG) c.setFont("Helvetica-Bold", 10) c.drawCentredString( PAGE_W/2, banner_y + 5, "Biochemistry Lecture Tracker | Lectures 1 - 91 | Write topic name in blank column | Tick when completed" ) # Table area starts below banner table_top = banner_y - 2 # small gap # per-group available height avail_h = table_top - BM # row heights: header row fixed, data rows share remaining COL_HEADER_H = 13 # pts data_rows_per_group = [31, 30, 30] max_rows = max(data_rows_per_group) row_h = (avail_h - COL_HEADER_H) / max_rows def draw_group(c, x_left, start, end, row_h): n_data = end - start + 1 col_widths = [n_w, topic_w, tick_w] # Draw column headers headers = ["#", "Topic Name", "โ"] x = x_left y_hdr = table_top - COL_HEADER_H for col_idx, (label, cw) in enumerate(zip(headers, col_widths)): c.setFillColor(HDR_BG) c.rect(x, y_hdr, cw, COL_HEADER_H, fill=1, stroke=0) c.setFillColor(HDR_FG) c.setFont("Helvetica-Bold", 6.5) c.drawCentredString(x + cw/2, y_hdr + 3.5, label) x += cw # Draw data rows for idx in range(n_data): lec_num = start + idx y_row = table_top - COL_HEADER_H - (idx+1)*row_h x = x_left bg = ODD if (idx % 2 == 0) else EVEN # # cell c.setFillColor(bg) c.rect(x, y_row, n_w, row_h, fill=1, stroke=0) c.setStrokeColor(BORDER) c.setLineWidth(0.3) c.rect(x, y_row, n_w, row_h, fill=0, stroke=1) c.setFillColor(HDR_BG) c.setFont("Helvetica-Bold", 6) c.drawCentredString(x + n_w/2, y_row + row_h*0.28, str(lec_num)) x += n_w # Topic cell c.setFillColor(bg) c.rect(x, y_row, topic_w, row_h, fill=1, stroke=0) c.setStrokeColor(BORDER) c.rect(x, y_row, topic_w, row_h, fill=0, stroke=1) x += topic_w # Tick cell c.setFillColor(TICK_BG) c.rect(x, y_row, tick_w, row_h, fill=1, stroke=0) c.setStrokeColor(BORDER) c.rect(x, y_row, tick_w, row_h, fill=0, stroke=1) # โโ Draw the three groups โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ for col_idx, (start, end) in enumerate(splits): x_start = LM + col_idx * (group_w + GAP) draw_group(c, x_start, start, end, row_h) c.save() print("Saved:", out_tmp) EOF
python3 -c " src = open('/tmp/Biochemistry_A4_3col.pdf', 'rb').read() open('/home/daytona/workspace/biochem-tracker/Biochemistry_Lecture_Tracker_A4.pdf', 'wb').write(src) print('Copied', len(src), 'bytes') "
Biochemistry Lecture Tracker A4
PDF Document ยท PDF
| Column Group | Lectures | Sub-columns |
|---|---|---|
| Left | 1 โ 31 | # ยท Topic Name ยท โ |
| Middle | 32 โ 61 | # ยท Topic Name ยท โ |
| Right | 62 โ 91 | # ยท Topic Name ยท โ |