~/fmge-neetpg/create_timeline.py
from openpyxl import Workbook
from openpyxl.styles import (
Font, PatternFill, Alignment, Border, Side
)
from openpyxl.utils import get_column_letter
from openpyxl.styles.numbers import FORMAT_PERCENTAGE
wb = Workbook()
# ── Color palette ──────────────────────────────────────────────────
HDR_DARK = "1F3864" # dark navy – sheet headers
HDR_MED = "2E75B6" # blue – section headers
HDR_LIGHT = "BDD7EE" # light blue – column headers
YEAR_COLS = ["E8F0FE", "FFF2CC", "E2EFDA", "FCE4D6", "EDE7F6"] # Y1-Y5 tints
GREEN = "E2EFDA"
ORANGE = "FCE4D6"
YELLOW = "FFF2CC"
WHITE = "FFFFFF"
GREY_ROW = "F2F2F2"
def side():
return Side(style="thin", color="CCCCCC")
def border():
s = side()
return Border(left=s, right=s, top=s, bottom=s)
def hdr_font(size=11, bold=True, color="FFFFFF"):
return Font(name="Arial", size=size, bold=bold, color=color)
def body_font(size=10, bold=False, color="000000"):
return Font(name="Arial", size=size, bold=bold, color=color)
def fill(hex_color):
return PatternFill("solid", start_color=hex_color, fgColor=hex_color)
def center():
return Alignment(horizontal="center", vertical="center", wrap_text=True)
def left():
return Alignment(horizontal="left", vertical="center", wrap_text=True)
# ═══════════════════════════════════════════════════════════════════
# SHEET 1 – OVERVIEW DASHBOARD
# ═══════════════════════════════════════════════════════════════════
ws1 = wb.active
ws1.title = "Overview"
# Title row
ws1.merge_cells("A1:H1")
ws1["A1"] = "FMGE + NEET PG | 5-Year Master Study Timeline"
ws1["A1"].font = Font(name="Arial", size=16, bold=True, color="FFFFFF")
ws1["A1"].fill = fill(HDR_DARK)
ws1["A1"].alignment = center()
ws1.row_dimensions[1].height = 36
# Subtitle
ws1.merge_cells("A2:H2")
ws1["A2"] = "Starting: July 2026 | FMGE Target: Dec 2029 | NEET PG Target: 2031"
ws1["A2"].font = Font(name="Arial", size=11, bold=False, color="FFFFFF")
ws1["A2"].fill = fill(HDR_MED)
ws1["A2"].alignment = center()
ws1.row_dimensions[2].height = 22
ws1.append([]) # blank row 3
# ── Key Stats ──────────────────────────────────────────────────────
ws1.merge_cells("A4:H4")
ws1["A4"] = "KEY TARGETS AT A GLANCE"
ws1["A4"].font = hdr_font(12)
ws1["A4"].fill = fill(HDR_MED)
ws1["A4"].alignment = center()
ws1.row_dimensions[4].height = 22
stats_headers = ["Exam", "Target Year", "Total Subjects", "MCQs/Day (avg)", "Revisions", "Primary Platform", "Backup Platform", "Pass Mark"]
stats_data = [
["FMGE", "Dec 2029", 19, 100, 3, "Marrow", "DigiNerve", "150/300 (50%)"],
["NEET PG", "2031", 19, 200, 4, "Marrow", "PrepLadder", "50th Percentile"],
]
ws1.append(stats_headers)
r = ws1.max_row
for c, h in enumerate(stats_headers, 1):
cell = ws1.cell(r, c)
cell.font = hdr_font(10)
cell.fill = fill(HDR_LIGHT)
cell.alignment = center()
cell.border = border()
for row_data in stats_data:
ws1.append(row_data)
r = ws1.max_row
for c in range(1, len(row_data)+1):
cell = ws1.cell(r, c)
cell.font = body_font(10)
cell.alignment = center()
cell.border = border()
cell.fill = fill(WHITE)
ws1.append([]) # spacer
# ── Year-by-year summary table ──────────────────────────────────────
ws1.merge_cells("A9:H9")
ws1["A9"] = "YEAR-BY-YEAR PHASE SUMMARY"
ws1["A9"].font = hdr_font(12)
ws1["A9"].fill = fill(HDR_MED)
ws1["A9"].alignment = center()
ws1.row_dimensions[9].height = 22
phase_cols = ["Year", "Period", "Phase", "Focus Subjects", "Daily Study Hours", "MCQs/Day", "Key Milestone", "Platform"]
ws1.append(phase_cols)
r = ws1.max_row
for c, h in enumerate(phase_cols, 1):
cell = ws1.cell(r, c)
cell.font = hdr_font(10)
cell.fill = fill(HDR_LIGHT)
cell.alignment = center()
cell.border = border()
phase_data = [
["Year 1", "Jul 2026 – Jun 2027", "Foundation", "Anatomy, Physiology, Biochemistry", "6–7", 30, "Complete preclinicals | Start MCQ habit", "Textbooks only"],
["Year 2", "Jul 2027 – Jun 2028", "Paraclinical", "Pathology, Pharmacology, Micro, Forensic", "7–8", 100, "Buy Marrow 24-month plan | 100 MCQs/day", "Marrow"],
["Year 3", "Jul 2028 – Jun 2029", "Clinical Giants", "Medicine, Surgery, OBG, Paediatrics", "8–9", 150, "First Grand Test | Complete clinical core", "Marrow"],
["Year 4", "Jul 2029 – Jun 2030", "Allied + FMGE", "PSM, ENT, Ophth, Ortho, Derm, Psychiatry", "8–9", 200, "FMGE Dec 2029 – TARGET ATTEMPT", "Marrow + DigiNerve"],
["Year 5", "Jul 2030 – Jun 2031", "NEET PG Mode", "All 19 subjects – full revision", "9–10",250, "NEET PG 2031 – MAIN TARGET", "Marrow"],
]
for i, row_data in enumerate(phase_data):
ws1.append(row_data)
r = ws1.max_row
row_fill = YEAR_COLS[i]
for c in range(1, len(row_data)+1):
cell = ws1.cell(r, c)
cell.font = body_font(10, bold=(c==3))
cell.fill = fill(row_fill)
cell.alignment = center() if c != 4 else left()
cell.border = border()
ws1.row_dimensions[r].height = 28
# Column widths for Overview
col_widths_ov = [8, 22, 18, 40, 18, 12, 34, 22]
for i, w in enumerate(col_widths_ov, 1):
ws1.column_dimensions[get_column_letter(i)].width = w
# ═══════════════════════════════════════════════════════════════════
# SHEET 2 – SUBJECT-WISE PLAN
# ═══════════════════════════════════════════════════════════════════
ws2 = wb.create_sheet("Subject-Wise Plan")
ws2.merge_cells("A1:J1")
ws2["A1"] = "SUBJECT-WISE STUDY PLAN – All 19 MBBS Subjects"
ws2["A1"].font = Font(name="Arial", size=14, bold=True, color="FFFFFF")
ws2["A1"].fill = fill(HDR_DARK)
ws2["A1"].alignment = center()
ws2.row_dimensions[1].height = 32
subj_cols = ["#", "Subject", "Group", "Priority", "Textbook", "Marrow Lectures (hrs)", "FMGE Qs (~)", "NEET PG Qs (~)", "Study Year", "Status"]
ws2.append(subj_cols)
r = ws2.max_row
for c, h in enumerate(subj_cols, 1):
cell = ws2.cell(r, c)
cell.font = hdr_font(10)
cell.fill = fill(HDR_LIGHT)
cell.alignment = center()
cell.border = border()
ws2.row_dimensions[r].height = 28
subjects = [
# # Subject Group Priority Textbook Hrs FMGE NEET Year
[1, "Anatomy", "Preclinical", "Medium", "BD Chaurasia + Snell's", 55, 15, 12, "Year 1"],
[2, "Physiology", "Preclinical", "Medium", "Ganong", 60, 15, 14, "Year 1"],
[3, "Biochemistry", "Preclinical", "Medium", "Lippincott / Harper's", 45, 12, 10, "Year 1"],
[4, "Pathology", "Paraclinical", "HIGH", "Robbins", 75, 25, 22, "Year 2"],
[5, "Pharmacology", "Paraclinical", "HIGH", "KD Tripathi", 65, 22, 20, "Year 2"],
[6, "Microbiology", "Paraclinical", "Medium", "Ananthanarayan", 50, 14, 12, "Year 2"],
[7, "Forensic Medicine", "Paraclinical", "Medium", "Reddy / Pillay", 35, 12, 10, "Year 2"],
[8, "Medicine", "Clinical", "HIGH", "Davidson's + Harrison's", 90, 45, 42, "Year 3"],
[9, "Surgery", "Clinical", "HIGH", "Bailey & Love", 75, 28, 26, "Year 3"],
[10, "OBG", "Clinical", "HIGH", "Dutta (Obs + Gynae)", 65, 22, 20, "Year 3"],
[11, "Paediatrics", "Clinical", "Medium", "OP Ghai / Nelson Essent.", 55, 18, 16, "Year 3"],
[12, "PSM", "Allied", "HIGH", "Park's Textbook", 60, 36, 30, "Year 4"],
[13, "ENT", "Allied", "Medium", "Dhingra", 35, 12, 10, "Year 4"],
[14, "Ophthalmology", "Allied", "Medium", "Khurana", 35, 12, 10, "Year 4"],
[15, "Orthopaedics", "Allied", "Medium", "Maheshwari", 30, 12, 10, "Year 4"],
[16, "Dermatology", "Allied", "Medium", "Neena Khanna", 25, 9, 8, "Year 4"],
[17, "Psychiatry", "Allied", "Medium", "Ahuja", 25, 8, 7, "Year 4"],
[18, "Anaesthesia", "Allied", "Low", "Morgan & Mikhail (sel.)", 20, 5, 4, "Year 4"],
[19, "Radiology", "Allied", "Low", "Notes / Marrow videos", 20, 5, 4, "Year 4"],
]
priority_colors = {"HIGH": "FFD7D7", "Medium": "FFF9C4", "Low": "E8F5E9"}
for i, row in enumerate(subjects):
ws2.append(row)
r = ws2.max_row
p_color = priority_colors.get(row[3], WHITE)
for c in range(1, len(row)+1):
cell = ws2.cell(r, c)
cell.font = body_font(10, bold=(row[3]=="HIGH"))
cell.alignment = center() if c not in [2, 5] else left()
cell.border = border()
if c == 4:
cell.fill = fill(p_color)
else:
cell.fill = fill(GREY_ROW if i % 2 else WHITE)
ws2.row_dimensions[r].height = 22
# Totals row
ws2.append(["", "TOTALS", "", "", "",
f'=SUM(F3:F{ws2.max_row})',
f'=SUM(G3:G{ws2.max_row})',
f'=SUM(H3:H{ws2.max_row})',
"", ""])
r = ws2.max_row
for c in range(1, 11):
cell = ws2.cell(r, c)
cell.font = hdr_font(10, color="000000")
cell.fill = fill(HDR_LIGHT)
cell.alignment = center()
cell.border = border()
col_widths_s2 = [4, 20, 14, 10, 30, 22, 14, 16, 12, 12]
for i, w in enumerate(col_widths_s2, 1):
ws2.column_dimensions[get_column_letter(i)].width = w
# ═══════════════════════════════════════════════════════════════════
# SHEET 3 – MONTHLY STUDY PLANNER (Year-by-Year)
# ═══════════════════════════════════════════════════════════════════
ws3 = wb.create_sheet("Monthly Planner")
ws3.merge_cells("A1:G1")
ws3["A1"] = "MONTHLY STUDY PLANNER – 5 Years (Jul 2026 – Jun 2031)"
ws3["A1"].font = Font(name="Arial", size=14, bold=True, color="FFFFFF")
ws3["A1"].fill = fill(HDR_DARK)
ws3["A1"].alignment = center()
ws3.row_dimensions[1].height = 32
monthly_cols = ["Year", "Month", "Primary Subject(s)", "Secondary Subject(s)", "MCQs Target", "Mock Tests", "Key Activity / Milestone"]
ws3.append(monthly_cols)
r = ws3.max_row
for c, h in enumerate(monthly_cols, 1):
cell = ws3.cell(r, c)
cell.font = hdr_font(10)
cell.fill = fill(HDR_LIGHT)
cell.alignment = center()
cell.border = border()
ws3.row_dimensions[r].height = 24
monthly_plan = [
# Year 1
["Year 1","Jul 2026","Anatomy (Upper Limb)","–",900,0,"Start study routine | Buy BD Chaurasia"],
["Year 1","Aug 2026","Anatomy (Lower Limb + Thorax)","–",900,0,"Complete limb anatomy"],
["Year 1","Sep 2026","Anatomy (Abdomen + Pelvis)","–",900,0,"Detailed notes on GIT anatomy"],
["Year 1","Oct 2026","Anatomy (Head & Neck + Neuro)","–",900,0,"Complete Anatomy"],
["Year 1","Nov 2026","Physiology (General + Nerve)","Anatomy revision",1200,0,"Start Ganong"],
["Year 1","Dec 2026","Physiology (CVS + Respiratory)","Anatomy MCQs",1200,0,"Solve 30 Anatomy PYQs"],
["Year 1","Jan 2027","Physiology (GIT + Renal)","–",1200,0,"Make physiology short notes"],
["Year 1","Feb 2027","Physiology (Endo + Repro + Neuro)","–",1200,0,"Complete Physiology"],
["Year 1","Mar 2027","Biochemistry (General + Carbs)","Physio revision",1500,0,"Start Lippincott"],
["Year 1","Apr 2027","Biochemistry (Proteins + Enzymes)","–",1500,0,"Enzyme charts + diagrams"],
["Year 1","May 2027","Biochemistry (Lipids + Vitamins)","–",1500,0,"Vitamin deficiency table"],
["Year 1","Jun 2027","Preclinical Revision","All 3 subjects",2000,1,"First mock test (preclinicals only)"],
# Year 2
["Year 2","Jul 2027","Pathology (General)","–",2100,0,"BUY MARROW – Start video lectures"],
["Year 2","Aug 2027","Pathology (CVS + Respiratory)","–",2100,0,"Robbins + Marrow parallel"],
["Year 2","Sep 2027","Pathology (GIT + Hepato)","–",2100,0,"High-yield Pathology tables"],
["Year 2","Oct 2027","Pathology (Neoplasia + Haemo)","–",2100,0,"Complete Pathology"],
["Year 2","Nov 2027","Pharmacology (General + ANS)","Pathology revision",2400,0,"KD Tripathi + Marrow"],
["Year 2","Dec 2027","Pharmacology (CVS + CNS)","–",2400,0,"Drug classification charts"],
["Year 2","Jan 2028","Pharmacology (Antibiotics + Chemo)","–",2400,0,"Antibiotic mechanism tables"],
["Year 2","Feb 2028","Microbiology (Bacteriology)","Pharma revision",2400,0,"Gram staining + culture media"],
["Year 2","Mar 2028","Microbiology (Virology + Parasito)","–",2400,0,"Complete Microbiology"],
["Year 2","Apr 2028","Forensic Medicine","–",2100,0,"Reddy / Pillay – complete"],
["Year 2","May 2028","Paraclinical Full Revision","All 4 subjects",3000,1,"Marrow Grand Test #1"],
["Year 2","Jun 2028","Paraclinical Revision + MCQs","Weak areas",3000,2,"100 MCQs/day minimum"],
# Year 3
["Year 3","Jul 2028","Medicine (Cardiology + Resp)","–",3600,0,"Davidson's + Harrison's (selective)"],
["Year 3","Aug 2028","Medicine (GIT + Hepatology)","–",3600,0,"High-yield Medicine tables"],
["Year 3","Sep 2028","Medicine (Nephrology + Endo)","–",3600,0,"Diabetes + CKD in detail"],
["Year 3","Oct 2028","Medicine (Neuro + Haemo + Infect)","–",3600,1,"Marrow Grand Test #2"],
["Year 3","Nov 2028","Surgery (General + GIT)","Medicine revision",3600,0,"Bailey & Love + Marrow"],
["Year 3","Dec 2028","Surgery (Ortho + Urology + Neuro)","–",3600,0,"Complete Surgery"],
["Year 3","Jan 2029","OBG (Obstetrics)","Surgery revision",3600,0,"Dutta Obstetrics"],
["Year 3","Feb 2029","OBG (Gynaecology)","–",3600,0,"Dutta Gynaecology complete"],
["Year 3","Mar 2029","Paediatrics","OBG revision",3600,1,"OP Ghai complete | Grand Test #3"],
["Year 3","Apr 2029","Clinical Full Revision – I","Medicine + Surgery",4500,1,"Marrow Grand Test #4"],
["Year 3","May 2029","Clinical Full Revision – II","OBG + Paeds",4500,2,"200 MCQs/day"],
["Year 3","Jun 2029","Clinical Revision + Weak areas","All clinical",4500,2,"Performance analytics review"],
# Year 4
["Year 4","Jul 2029","PSM (Epidemiology + Biostatistics)","–",4500,0,"Park's Textbook – detailed"],
["Year 4","Aug 2029","PSM (National Programmes + Nutrition)","–",4500,0,"NHP + Immunisation schedule"],
["Year 4","Sep 2029","ENT + Ophthalmology","PSM revision",4500,1,"Dhingra + Khurana | Grand Test #5"],
["Year 4","Oct 2029","Orthopaedics + Dermatology","–",4500,0,"Maheshwari + Neena Khanna"],
["Year 4","Nov 2029","Psychiatry + Anaesthesia + Radiology","–",4500,1,"Complete allied subjects"],
["Year 4","Dec 2029","⭐ FMGE ATTEMPT","Full revision",5000,2,"TARGET: FMGE Dec 2029 🎯"],
["Year 4","Jan 2030","All 19 subjects Revision – I","Weak subjects",5000,2,"Post-FMGE analysis"],
["Year 4","Feb 2030","All 19 subjects Revision – II","Pharmacology + PSM",5000,2,"Marrow Grand Test #6"],
["Year 4","Mar 2030","High-yield Revision","Medicine + Surgery",5000,2,"PYQ solving (NEET PG 5 yrs)"],
["Year 4","Apr 2030","PYQ Marathon","All subjects",6000,3,"Solve 3000+ PYQs total"],
["Year 4","May 2030","Full Revision + Mocks","All subjects",6000,3,"Marrow Grand Test #7 + #8"],
["Year 4","Jun 2030","NEET PG Prep – Intensify","All subjects",6000,4,"Score target: 580+"],
# Year 5
["Year 5","Jul 2030","All Subjects Revision – III","Focus: weak areas",6000,2,"Marrow analytics deep dive"],
["Year 5","Aug 2030","Medicine + Surgery Intensive","Pathology",6000,2,"Marrow Grand Test #9"],
["Year 5","Sep 2030","PSM + Pharmacology Intensive","Micro + Forensic",6000,2,"High-repeat topic focus"],
["Year 5","Oct 2030","OBG + Paediatrics + ENT","Ophth + Ortho",6000,3,"Marrow Grand Test #10"],
["Year 5","Nov 2030","All 19 subjects Revision – IV","Especially allied",7500,3,"4th full revision"],
["Year 5","Dec 2030","PYQ Marathon – 10 years","All subjects",7500,4,"Target 5000+ MCQs solved total"],
["Year 5","Jan 2031","High-yield only Revision","Top 5 subjects",7500,4,"Marrow Grand Test #11 + #12"],
["Year 5","Feb 2031","Mock test + Analysis","Weak areas only",7500,5,"2 full mocks/week"],
["Year 5","Mar 2031","Final Revision – Speed Mode","All subjects",7500,5,"Aim: 200 MCQs in 42 min"],
["Year 5","Apr 2031","Pre-exam Revision","High-yield topics",6000,4,"Light revision – no new topics"],
["Year 5","May 2031","⭐ NEET PG ATTEMPT","Full revision",3000,2,"TARGET: NEET PG 2031 🎯"],
["Year 5","Jun 2031","Post exam / Counselling","–",0,0,"MCC Counselling | Seat selection"],
]
year_fill_map = {
"Year 1": YEAR_COLS[0],
"Year 2": YEAR_COLS[1],
"Year 3": YEAR_COLS[2],
"Year 4": YEAR_COLS[3],
"Year 5": YEAR_COLS[4],
}
for row in monthly_plan:
ws3.append(row)
r = ws3.max_row
row_color = year_fill_map.get(row[0], WHITE)
is_exam = "ATTEMPT" in str(row[6])
for c in range(1, 8):
cell = ws3.cell(r, c)
cell.font = Font(name="Arial", size=10, bold=is_exam,
color="CC0000" if is_exam else "000000")
cell.fill = fill("FFE599" if is_exam else row_color)
cell.alignment = center() if c in [1,2,5,6] else left()
cell.border = border()
ws3.row_dimensions[r].height = 22
col_widths_s3 = [8, 12, 30, 28, 14, 12, 38]
for i, w in enumerate(col_widths_s3, 1):
ws3.column_dimensions[get_column_letter(i)].width = w
# ═══════════════════════════════════════════════════════════════════
# SHEET 4 – WEEKLY SCHEDULE
# ═══════════════════════════════════════════════════════════════════
ws4 = wb.create_sheet("Weekly Schedule")
ws4.merge_cells("A1:H1")
ws4["A1"] = "WEEKLY STUDY SCHEDULE – Template (Adjust per Year)"
ws4["A1"].font = Font(name="Arial", size=14, bold=True, color="FFFFFF")
ws4["A1"].fill = fill(HDR_DARK)
ws4["A1"].alignment = center()
ws4.row_dimensions[1].height = 32
week_cols = ["Time Slot", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
ws4.append(week_cols)
r = ws4.max_row
for c, h in enumerate(week_cols, 1):
cell = ws4.cell(r, c)
cell.font = hdr_font(10)
cell.fill = fill(HDR_LIGHT)
cell.alignment = center()
cell.border = border()
ws4.row_dimensions[r].height = 24
week_data = [
["6:00–8:00 AM", "Revise Yesterday", "Revise Yesterday", "Revise Yesterday", "Revise Yesterday", "Revise Yesterday", "Weak Topics", "REST / Light read"],
["8:00–10:00 AM", "Subject A – Video", "Subject B – Video", "Subject A – Theory", "Subject B – Video", "Subject C – Video", "MCQ Marathon", "REST"],
["10:00 AM–1 PM", "Subject A – Theory", "Subject B – Theory", "Subject A – MCQs", "Subject B – Theory", "Subject C – Theory", "MCQ Marathon", "REST"],
["1:00–2:00 PM", "LUNCH + BREAK", "LUNCH + BREAK", "LUNCH + BREAK", "LUNCH + BREAK", "LUNCH + BREAK", "LUNCH + BREAK", "LUNCH"],
["2:00–4:00 PM", "Subject A – MCQs", "Subject B – MCQs", "Subject C – Video", "Subject A – MCQs", "Subject C – Theory", "Full Mock Test", "Grand Test / Review"],
["4:00–5:00 PM", "Wrong Ans Review", "Wrong Ans Review", "Wrong Ans Review", "Wrong Ans Review", "Wrong Ans Review", "Mock Analysis", "Grand Test Analysis"],
["5:00–6:00 PM", "BREAK / WALK", "BREAK / WALK", "BREAK / WALK", "BREAK / WALK", "BREAK / WALK", "BREAK", "BREAK"],
["8:00–10:00 PM", "Short Notes Revision", "Short Notes Revision","Short Notes Revision","Short Notes Revision","Weekly Summary Notes", "Weak Area Revision", "Plan Next Week"],
]
day_colors = ["FFF9C4","E8F5E9","E3F2FD","FDE7F3","F3E5F5","FFE0B2","ECEFF1"]
for row in week_data:
ws4.append(row)
r = ws4.max_row
for c, val in enumerate(row, 1):
cell = ws4.cell(r, c)
cell.font = body_font(10, bold=(c==1))
cell.fill = fill("F5F5F5" if c==1 else day_colors[(c-2)%7])
cell.alignment = center()
cell.border = border()
ws4.row_dimensions[r].height = 30
col_widths_s4 = [18, 22, 22, 22, 22, 22, 22, 22]
for i, w in enumerate(col_widths_s4, 1):
ws4.column_dimensions[get_column_letter(i)].width = w
# ═══════════════════════════════════════════════════════════════════
# SHEET 5 – PROGRESS TRACKER
# ═══════════════════════════════════════════════════════════════════
ws5 = wb.create_sheet("Progress Tracker")
ws5.merge_cells("A1:I1")
ws5["A1"] = "SUBJECT PROGRESS TRACKER – Update as You Complete"
ws5["A1"].font = Font(name="Arial", size=14, bold=True, color="FFFFFF")
ws5["A1"].fill = fill(HDR_DARK)
ws5["A1"].alignment = center()
ws5.row_dimensions[1].height = 32
track_cols = ["#","Subject","1st Reading\nDate","1st Revision\nDate","2nd Revision\nDate","3rd Revision\nDate",
"MCQs Done","Accuracy %","Notes / Comments"]
ws5.append(track_cols)
r = ws5.max_row
for c, h in enumerate(track_cols, 1):
cell = ws5.cell(r, c)
cell.font = hdr_font(10)
cell.fill = fill(HDR_LIGHT)
cell.alignment = center()
cell.border = border()
ws5.row_dimensions[r].height = 34
subj_list = [
"Anatomy","Physiology","Biochemistry","Pathology","Pharmacology",
"Microbiology","Forensic Medicine","Medicine","Surgery","OBG",
"Paediatrics","PSM","ENT","Ophthalmology","Orthopaedics",
"Dermatology","Psychiatry","Anaesthesia","Radiology"
]
for i, s in enumerate(subj_list, 1):
ws5.append([i, s, "", "", "", "", 0, "", ""])
r = ws5.max_row
for c in range(1, 10):
cell = ws5.cell(r, c)
cell.font = body_font(10)
cell.fill = fill(GREY_ROW if i%2 else WHITE)
cell.alignment = center() if c != 9 else left()
cell.border = border()
ws5.row_dimensions[r].height = 22
col_widths_s5 = [4, 20, 16, 16, 16, 16, 14, 14, 30]
for i, w in enumerate(col_widths_s5, 1):
ws5.column_dimensions[get_column_letter(i)].width = w
# ═══════════════════════════════════════════════════════════════════
# SHEET 6 – BUDGET PLANNER
# ═══════════════════════════════════════════════════════════════════
ws6 = wb.create_sheet("Budget Planner")
ws6.merge_cells("A1:F1")
ws6["A1"] = "5-YEAR STUDY BUDGET PLANNER"
ws6["A1"].font = Font(name="Arial", size=14, bold=True, color="FFFFFF")
ws6["A1"].fill = fill(HDR_DARK)
ws6["A1"].alignment = center()
ws6.row_dimensions[1].height = 32
bud_cols = ["Year","Item","Type","Approx Cost (INR)","Priority","Notes"]
ws6.append(bud_cols)
r = ws6.max_row
for c, h in enumerate(bud_cols, 1):
cell = ws6.cell(r, c)
cell.font = hdr_font(10)
cell.fill = fill(HDR_LIGHT)
cell.alignment = center()
cell.border = border()
ws6.row_dimensions[r].height = 24
budget_data = [
["Year 1","BD Chaurasia (3 vols)","Book",1500,"Must","Standard anatomy textbook"],
["Year 1","Ganong Physiology","Book",900,"Must","Latest edition"],
["Year 1","Lippincott Biochemistry","Book",800,"Must","Concise + well illustrated"],
["Year 1","Stationery + Notebooks","Misc",1000,"Must","For making short notes"],
["Year 2","Marrow 24-Month Plan (NEET PG)","Platform",45000,"Must","Core investment – covers FMGE+NEET PG"],
["Year 2","Robbins Pathology","Book",2500,"Must","Essential for Pathology"],
["Year 2","KD Tripathi Pharmacology","Book",1200,"Must","Standard textbook"],
["Year 2","Ananthanarayan Microbiology","Book",900,"Recommended",""],
["Year 3","Davidson's Medicine","Book",1800,"Must","Alongside Marrow"],
["Year 3","Bailey & Love Surgery","Book",2200,"Must","Alongside Marrow"],
["Year 3","Dutta Obstetrics + Gynaecology","Book",1600,"Must","Two separate volumes"],
["Year 3","OP Ghai Paediatrics","Book",1200,"Must",""],
["Year 4","Marrow Renewal / Test Series","Platform",15000,"Must","Continued access"],
["Year 4","Park's PSM","Book",1500,"Must","Complete PSM"],
["Year 4","Allied subject books (ENT/Ophth/etc)","Book",3000,"Recommended","Dhingra + Khurana + Maheshwari"],
["Year 4","DigiNerve FMGE QBank","Platform",8000,"Recommended","NBE official – FMGE PYQs"],
["Year 4","FMGE Registration Fee","Exam",5000,"Must","NBE registration"],
["Year 5","NEET PG Test Series","Platform",8000,"Must","Marrow/PrepLadder final mocks"],
["Year 5","NEET PG Registration Fee","Exam",4250,"Must","NBE registration"],
["Year 5","Miscellaneous + Revision material","Misc",3000,"Recommended","Notes printing, etc."],
]
year_bud_map = {
"Year 1": YEAR_COLS[0], "Year 2": YEAR_COLS[1],
"Year 3": YEAR_COLS[2], "Year 4": YEAR_COLS[3], "Year 5": YEAR_COLS[4]
}
for row in budget_data:
ws6.append(row)
r = ws6.max_row
row_color = year_bud_map.get(row[0], WHITE)
for c in range(1, 7):
cell = ws6.cell(r, c)
cell.font = body_font(10)
cell.fill = fill(row_color)
cell.alignment = center() if c in [1,3,4,5] else left()
cell.border = border()
ws6.row_dimensions[r].height = 22
# Totals
last_data_row = ws6.max_row
ws6.append(["","TOTAL ESTIMATED BUDGET","","=SUM(D3:D{})".format(last_data_row),"",""])
r = ws6.max_row
for c in range(1, 7):
cell = ws6.cell(r, c)
cell.font = hdr_font(11, color="000000")
cell.fill = fill(HDR_LIGHT)
cell.alignment = center()
cell.border = border()
ws6.row_dimensions[r].height = 26
col_widths_s6 = [8, 36, 14, 22, 14, 36]
for i, w in enumerate(col_widths_s6, 1):
ws6.column_dimensions[get_column_letter(i)].width = w
# ═══════════════════════════════════════════════════════════════════
# SAVE
# ═══════════════════════════════════════════════════════════════════
out_path = "/home/daytona/workspace/fmge-neetpg/FMGE_NEETPG_5Year_Timeline.xlsx"
wb.save(out_path)
print(f"Saved: {out_path}")