Can u convert whole question paper and answer pdf in short and brief one to 2 lines or interactive flowchats for related expected questions or topics in neet pg 2026
Please upload your NEET PG 2026 question paper + answer PDF so I can process it. Have you attached it? · What output format do you want?
Yes this is the pdf
What output format do you prefer for this FMGE June 2026 paper?
cd /home/daytona/workspace && python3 - << 'EOF' from pypdf import PdfReader import json, re pdf_path = "/home/daytona/workspace/attachments/862d080e-600a-4366-bc8e-d8c04ace454c/FMGE JUNE 2026 RECALL QAE 258.pdf" reader = PdfReader(pdf_path) print(f"Total pages: {len(reader.pages)}") # Extract first 10 pages to understand structure for i in range(min(10, len(reader.pages))): text = reader.pages[i].extract_text() print(f"\n=== PAGE {i+1} ===") print(text[:800]) EOF
python3 - << 'EOF' from pypdf import PdfReader import re pdf_path = "/home/daytona/workspace/attachments/862d080e-600a-4366-bc8e-d8c04ace454c/FMGE JUNE 2026 RECALL QAE 258.pdf" reader = PdfReader(pdf_path) full_text = "" for i, page in enumerate(reader.pages): t = page.extract_text() if t: full_text += t + "\n" # Save full text with open("/home/daytona/workspace/fmge_full.txt", "w") as f: f.write(full_text) print(f"Total chars: {len(full_text)}") print(f"Total pages: {len(reader.pages)}") # Quick subject detection from content subjects_seen = [] for keyword in ["anatomy","physiology","biochemistry","pathology","pharmacology","microbiology","forensic","dermatology","surgery","medicine","obst","paediatric","ophthalmology","ENT","radiology","psychiatry","ortho","community"]: count = full_text.lower().count(keyword) subjects_seen.append((keyword, count)) subjects_seen.sort(key=lambda x: -x[1]) print("\nSubject frequency:") for s, c in subjects_seen: print(f" {s}: {c}") EOF
python3 - << 'EOF' # Parse questions from the full text import re with open("/home/daytona/workspace/fmge_full.txt") as f: text = f.read() # Split by question numbers - pattern: number followed by period or dot at start of line # Questions are numbered 1, 2, 3... # Extract each Q+Answer block # Find all questions using regex # Pattern: digit(s). at start or after newline, followed by text blocks = re.split(r'\n(?=\d{1,3}\.\s)', text) questions = [] for block in blocks: block = block.strip() if not block: continue # Check if starts with a number m = re.match(r'^(\d+)\.\s+(.+)', block, re.DOTALL) if m: qnum = int(m.group(1)) content = m.group(2).strip() # Extract answer ans_match = re.search(r'[Aa]nswer\s*:\s*([A-D][^.\n]*)', content, re.IGNORECASE) answer = ans_match.group(1).strip() if ans_match else "See text" # Extract question text (before options A B C D) q_text = re.split(r'\n[A-D]\.\s', content)[0].strip() # Clean up q_text = re.sub(r'\s+', ' ', q_text) if len(q_text) > 200: q_text = q_text[:200] + "..." questions.append({ "num": qnum, "question": q_text, "answer": answer, "full": content[:500] }) print(f"Parsed {len(questions)} questions") for q in questions[:5]: print(f"\nQ{q['num']}: {q['question'][:100]}") print(f" Ans: {q['answer'][:80]}") EOF
python3 - << 'EOF' import re, json with open("/home/daytona/workspace/fmge_full.txt") as f: text = f.read() blocks = re.split(r'\n(?=\d{1,3}\.\s)', text) def classify_subject(q_text): t = q_text.lower() if any(k in t for k in ["nerve","artery","vein","muscle","bone","ligament","tendon","joint","skull","scalp","scalp","foramen","pleura","peritoneum","fascia","lymph node","duct","embryo","anatomical","sternocleidomastoid","spleen","hilum","lesser omentum","suture","meatus","nasal","orbit","styloid","condyle","hip","femur","tibia","fibula","humerus","radius","ulna","carpal","metacarpal","phalanx","vertebra","sacrum","pelvis","thorax","abdomen","inguinal","femoral","popliteal","axilla","brachial plexus","cervical","lumbar","dermatome","myotome"]): return "Anatomy" if any(k in t for k in ["blood gas","ph ","paco","hco3","anion gap","osmolarity","gfr","creatinine clearance","inulin","aldosterone","cortisol","adh","insulin","glucagon","renin","angiotensin","spirometry","fev","fvc","cardiac output","stroke volume","ejection fraction","preload","afterload","starling","action potential","resting membrane","refractory","eeg","emg","sleep","rer","bmr","receptor","g-protein","camp","cgmp","second messenger"]): return "Physiology" if any(k in t for k in ["enzyme","substrate","cofactor","coenzyme","vitamin","amino acid","protein","lipid","cholesterol","fatty acid","glucose","glycogen","glycolysis","krebs","electron transport","oxidative phosphorylation","dna","rna","pcr","mutation","gene","chromosome","nucleotide","purine","pyrimidine","urea cycle","ammonia","bilirubin","porphyrin","collagen","keratin","hemoglobin","heme","iron","megaloblastic","folate","b12","b1","b2","thiamine","niacin","riboflavin","pyridoxine","biotin","pantothenic","ascorbic","retinol","calciferol","tocopherol","phylloquinone","metabolic","metabolism","ketone","galactose","fructose","sucrose","lactose","phenylketonuria","alkaptonuria","homocystinuria","maple syrup","gaucher","niemann","tay-sachs","hurler","hunter"]): return "Biochemistry" if any(k in t for k in ["malignant","benign","carcinoma","adenocarcinoma","squamous cell","basal cell","lymphoma","leukemia","myeloma","sarcoma","tumor","neoplasm","biopsy","histology","histological","microscopy","stain","eosinophil","neutrophil","granuloma","necrosis","apoptosis","fibrosis","cirrhosis","infarct","embolism","thrombosis","atherosclerosis","inflammation","edema","congestion","hyperplasia","metaplasia","dysplasia","anaplasia","amyloid","psammoma","keratin pearl","giant cell","reed-sternberg","aschoff","rokitansky","virchow","paget","bowen"]): return "Pathology" if any(k in t for k in ["drug","antibiotic","penicillin","amoxicillin","ampicillin","tetracycline","doxycycline","erythromycin","azithromycin","clarithromycin","ciprofloxacin","gentamicin","vancomycin","metronidazole","rifampicin","isoniazid","pyrazinamide","ethambutol","dapsone","chloroquine","quinine","artemisinin","fluconazole","amphotericin","acyclovir","oseltamivir","aspirin","ibuprofen","paracetamol","morphine","codeine","tramadol","diazepam","lorazepam","haloperidol","chlorpromazine","lithium","ssri","snri","maoi","tricyclic","beta blocker","ace inhibitor","arb","calcium channel","diuretic","digoxin","warfarin","heparin","statin","metformin","insulin","thyroxine","corticosteroid","adrenaline","dopamine","serotonin","dose","mechanism of action","side effect","adverse","toxicity","antidote","ld50","therapeutic index","bioavailability","half life","pharmacokinetics","pharmacodynamics","receptor agonist","antagonist","clofazimine","mdt","who"]): return "Pharmacology" if any(k in t for k in ["bacteria","virus","fungus","parasite","protozoa","helminth","culture","gram","acid-fast","ziehl","giemsa","pas stain","agar","media","colony","sensitivity","resistance","antibiogram","pcr","elisa","serology","antibody","antigen","vaccine","immunization","hiv","hepatitis","tuberculosis","malaria","dengue","chikungunya","typhoid","cholera","shigella","salmonella","e. coli","klebsiella","staphylococcus","streptococcus","pneumococcus","meningococcus","haemophilus","bordetella","clostridium","listeria","brucella","leptospira","treponema","borrelia","rickettsia","chlamydia","mycoplasma","candida","aspergillus","cryptococcus","plasmodium","leishmania","trypanosoma","giardia","entamoeba","ascaris","hookworm","tapeworm","filaria"]): return "Microbiology" if any(k in t for k in ["skin","rash","lesion","papule","vesicle","bulla","pustule","macule","patch","plaque","wheal","burrow","scabies","tinea","dermatophyte","psoriasis","eczema","atopic","contact dermatitis","urticaria","angioedema","pemphigus","pemphigoid","sle","systemic lupus","leprosy","hansen","vitiligo","albinism","alopecia","hair","nail","melanoma","basal cell carcinoma","squamous cell skin","acne","rosacea","seborrhea","wood's lamp","koh","patch test","koebner","nikolsky"]): return "Dermatology" if any(k in t for k in ["incision","excision","resection","anastomosis","flap","graft","hernia","appendectomy","cholecystectomy","gastrectomy","colectomy","thyroidectomy","parathyroidectomy","mastectomy","amputation","tourniquet","wound","healing","suture technique","laparoscopy","laparotomy","diathermy","cautery","drain","catheter","tracheostomy","intubation","anesthesia","general anesthesia","spinal","epidural","local anesthesia","preoperative","postoperative","complication","blood transfusion","burns","fracture fixation","osteosynthesis","internal fixation","external fixation","imhizement","immobilize","cast","splint","tension band","intramedullary","plate screw","trauma","rta","road traffic","polytrauma","triage","damage control","tension pneumothorax","hemothorax","flail chest","cardiac tamponade","FAST","focused assessment"]): return "Surgery" if any(k in t for k in ["chest pain","myocardial","angina","heart failure","hypertension","diabetes","thyroid","hypothyroid","hyperthyroid","liver","jaundice","hepatitis","pancreatitis","peptic ulcer","crohn","ulcerative colitis","ibs","irritable bowel","celiac","malabsorption","anemia","polycythemia","sickle cell","thalassemia","bleeding disorder","hemophilia","thrombocytopenia","von willebrand","dvt","pulmonary embolism","pneumonia","copd","asthma","bronchiectasis","pleural effusion","renal failure","nephrotic","nephritic","uti","cystitis","pyelonephritis","gout","rheumatoid","osteoarthritis","spondylitis","systemic sclerosis","dermatomyositis","polymyositis","stroke","tia","epilepsy","seizure","parkinson","alzheimer","multiple sclerosis","meningitis","encephalitis","spinal cord","neuropathy","myasthenia","guillain","bell's palsy"]): return "Medicine" if any(k in t for k in ["obstetric","pregnancy","antenatal","prenatal","postnatal","delivery","labour","labor","cesarean","c-section","placenta","fetus","fetal","amniotic","uterus","cervix","ovary","fallopian","menstrual","menopause","contraception","abortion","miscarriage","ectopic","preeclampsia","eclampsia","gestational","pih","pprom","prom","oxytocin","ergometrine","gynaecology","gynecology","pcos","endometriosis","fibroids","carcinoma cervix","carcinoma ovary","carcinoma endometrium","papsmear","colposcopy"]): return "Obs & Gynae" if any(k in t for k in ["child","paediatric","pediatric","neonate","newborn","infant","developmental","milestone","vaccination","immunization schedule","kwashiorkor","marasmus","rickets","scurvy","growth","iugr","preterm","surfactant","nicu","jaundice neonate","breast feeding","weaning","enuresis","febrile convulsion","intussusception","pyloric stenosis","hirschsprung","wilms","neuroblastoma","retinoblastoma","asd","vsd","tetralogy"]): return "Paediatrics" if any(k in t for k in ["eye","vision","retina","cornea","lens","iris","pupil","glaucoma","cataract","uveitis","conjunctivitis","trachoma","optic","squint","strabismus","amblyopia","diplopia","ptosis","proptosis","orbital","tonometry","fundus","slit lamp","visual field","acuity","color blindness","nyctalopia","scotoma"]): return "Ophthalmology" if any(k in t for k in ["ear","hearing","deafness","tinnitus","vertigo","tympanic","mastoid","cochlea","vestibular","nose","sinusitis","rhinitis","polyp","septum","epistaxis","throat","tonsil","adenoid","larynx","pharynx","voice","hoarseness","tracheostomy","ent","otitis","meniere","bppv"]): return "ENT" if any(k in t for k in ["x-ray","radiograph","ct scan","mri","ultrasound","sonography","doppler","angiography","barium","contrast","nuclear","pet scan","isotope","scintigraphy","mammography","fluoroscopy","interventional","radiation","dose","gray","sievert","rem","roentgen"]): return "Radiology" if any(k in t for k in ["schizophrenia","psychosis","bipolar","mania","depression","anxiety","phobia","ocd","ptsd","autism","adhd","intellectual disability","personality disorder","dementia","delirium","substance abuse","alcohol","addiction","electroconvulsive","cbt","psychotherapy","iq","mental status","mmse","gaf","dsm","icd"]): return "Psychiatry" if any(k in t for k in ["community","epidemiology","incidence","prevalence","mortality","morbidity","surveillance","outbreak","pandemic","endemic","epidemic","vaccination program","immunization schedule","health program","national health","vital statistics","census","demographic","malnutrition","nutrition","calorie","protein","kwashiorkor","marasmus","fluoride","iodine","water","sanitation","sewage","vector control","insecticide","fumigation","quarantine","isolation","sterilization","disinfection","biosafety","hospital infection","nosocomial"]): return "Community Medicine" if any(k in t for k in ["forensic","poison","toxicology","autopsy","post-mortem","rigor mortis","livor","decomposition","drowning","hanging","strangulation","firearm","gunshot","wound age","time of death","dna fingerprint","blood group","paternity","rape","sexual assault","child abuse","medicolegal","ipc","crpc","indian penal","mca","mental health act","consent","negligence","malpractice"]): return "Forensic Medicine" return "General/Mixed" questions = [] for block in blocks: block = block.strip() if not block: continue m = re.match(r'^(\d+)\.\s+(.+)', block, re.DOTALL) if m: qnum = int(m.group(1)) content = m.group(2).strip() ans_match = re.search(r'[Aa]nswer\s*:?\s*([A-D][^\n]*)', content) if not ans_match: ans_match = re.search(r'[Cc]orrect [Aa]nswer\s*:?\s*([A-D][^\n]*)', content) answer_full = ans_match.group(1).strip() if ans_match else "See PDF" # Clean answer to just letter + short text answer_full = re.sub(r'\s+', ' ', answer_full)[:120] q_text = re.split(r'\n[A-D]\.\s', content)[0].strip() q_text = re.sub(r'\s+', ' ', q_text) subject = classify_subject(q_text) # One-line summary: trim q to key clinical clue summary = q_text[:160].strip() questions.append({ "num": qnum, "subject": subject, "question": q_text[:300], "summary": summary, "answer": answer_full }) # Count by subject from collections import Counter subj_count = Counter(q["subject"] for q in questions) print("Subject distribution:") for s, c in subj_count.most_common(): print(f" {s}: {c}") with open("/home/daytona/workspace/fmge_questions.json", "w") as f: json.dump(questions, f, indent=2) print(f"\nTotal: {len(questions)} questions parsed") EOF
python3 - << 'PYEOF' import json with open("/home/daytona/workspace/fmge_questions.json") as f: questions = json.load(f) # Build subject -> questions map from collections import defaultdict, Counter subj_map = defaultdict(list) for q in questions: subj_map[q["subject"]].append(q) subjects_ordered = ["Anatomy","Biochemistry","ENT","Pharmacology","Physiology","Surgery","Pathology", "Microbiology","Medicine","Paediatrics","Ophthalmology","Obs & Gynae","Dermatology", "Community Medicine","Radiology","Psychiatry","Forensic Medicine","General/Mixed"] # Subject colors COLORS = { "Anatomy": "#e74c3c", "Biochemistry": "#8e44ad", "ENT": "#2980b9", "Pharmacology": "#16a085", "Physiology": "#d35400", "Surgery": "#c0392b", "Pathology": "#7f8c8d", "Microbiology": "#27ae60", "Medicine": "#2c3e50", "Paediatrics": "#f39c12", "Ophthalmology": "#1abc9c", "Obs & Gynae": "#e91e63", "Dermatology": "#ff5722", "Community Medicine": "#795548", "Radiology": "#607d8b", "Psychiatry": "#9c27b0", "Forensic Medicine": "#455a64", "General/Mixed": "#546e7a" } # Flowchart topics per subject (top recurring themes) def get_topics(qs): """Extract recurring clinical themes for flowchart""" themes = Counter() for q in qs: t = q["question"].lower() # Anatomy themes if "nerve" in t: themes["Nerve Injuries"] += 1 if "artery" in t or "vein" in t: themes["Vascular Anatomy"] += 1 if "embryo" in t or "pharyngeal" in t or "cleft" in t: themes["Embryology"] += 1 if "bone" in t or "fracture" in t: themes["Skeletal/Fractures"] += 1 if "muscle" in t: themes["Muscle Anatomy"] += 1 if "ligament" in t or "joint" in t: themes["Joint Anatomy"] += 1 if "skull" in t or "scalp" in t or "cranial" in t: themes["Head & Neck Anatomy"] += 1 if "chest" in t or "thorax" in t or "lung" in t: themes["Thoracic Anatomy"] += 1 if "abdomen" in t or "periton" in t or "bowel" in t: themes["Abdominal Anatomy"] += 1 # Biochem themes if "vitamin" in t: themes["Vitamins"] += 1 if "enzyme" in t or "deficiency" in t: themes["Enzyme Deficiencies"] += 1 if "amino acid" in t or "keratin" in t or "collagen" in t: themes["Amino Acids/Proteins"] += 1 if "metabolism" in t or "glycogen" in t or "glucose" in t: themes["Carbohydrate Metabolism"] += 1 if "dna" in t or "rna" in t or "gene" in t: themes["Molecular Biology"] += 1 if "lipid" in t or "cholesterol" in t: themes["Lipid Metabolism"] += 1 if "acid-base" in t or "anion gap" in t or "ph " in t: themes["Acid-Base Balance"] += 1 # Pharma themes if "antibiotic" in t or "penicillin" in t or "rifampicin" in t or "dapsone" in t: themes["Antibiotics/Antimicrobials"] += 1 if "dose" in t or "mechanism" in t: themes["Drug Mechanisms & Dosing"] += 1 if "toxicity" in t or "adverse" in t or "antidote" in t: themes["Toxicity & Antidotes"] += 1 # Physio themes if "cardiac" in t or "heart" in t or "ejection" in t: themes["Cardiac Physiology"] += 1 if "renal" in t or "kidney" in t or "clearance" in t: themes["Renal Physiology"] += 1 if "respiratory" in t or "spirometry" in t or "fev" in t: themes["Respiratory Physiology"] += 1 if "hormone" in t or "endocrine" in t: themes["Endocrine Physiology"] += 1 # Micro if "bacteria" in t or "gram" in t: themes["Bacteriology"] += 1 if "virus" in t or "hiv" in t or "hepatitis" in t: themes["Virology"] += 1 if "parasite" in t or "malaria" in t or "plasmodium" in t: themes["Parasitology"] += 1 if "fungus" in t or "candida" in t: themes["Mycology"] += 1 # Patho if "carcinoma" in t or "cancer" in t or "malignant" in t: themes["Neoplasia"] += 1 if "infarct" in t or "thrombosis" in t or "embolism" in t: themes["Vascular Pathology"] += 1 if "inflammation" in t or "granuloma" in t: themes["Inflammation"] += 1 # ENT if "ear" in t or "hearing" in t or "otitis" in t: themes["Ear/Audiology"] += 1 if "nose" in t or "sinus" in t or "epistaxis" in t: themes["Nose & Sinuses"] += 1 if "throat" in t or "tonsil" in t or "larynx" in t: themes["Throat & Larynx"] += 1 # Surgery if "wound" in t or "healing" in t: themes["Wound Healing"] += 1 if "anesthesia" in t or "anesthetic" in t: themes["Anesthesia"] += 1 if "hernia" in t: themes["Hernias"] += 1 return themes.most_common(6) # Generate JavaScript data questions_js = json.dumps(questions, ensure_ascii=False) subj_data = {} for s in subjects_ordered: qs = subj_map.get(s, []) if qs: subj_data[s] = {"qs": qs, "topics": get_topics(qs), "color": COLORS.get(s,"#666")} subj_js = json.dumps(subj_data, ensure_ascii=False) html = f"""<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>FMGE June 2026 - Interactive Study Guide | NEET PG 2026</title> <style> :root {{ --primary: #1a237e; --accent: #e53935; --bg: #f5f7fa; --card: #ffffff; --border: #e0e0e0; --text: #212121; --sub: #757575; }} * {{ box-sizing: border-box; margin:0; padding:0; }} body {{ font-family: 'Segoe UI', system-ui, sans-serif; background: var(--bg); color: var(--text); }} /* HEADER */ .header {{ background: linear-gradient(135deg, #1a237e 0%, #283593 50%, #3949ab 100%); color: white; padding: 20px 24px; }} .header h1 {{ font-size: 1.6rem; font-weight: 700; }} .header p {{ opacity: .8; font-size: .9rem; margin-top: 4px; }} .header-stats {{ display: flex; gap: 20px; margin-top: 12px; flex-wrap: wrap; }} .stat {{ background: rgba(255,255,255,0.15); border-radius: 8px; padding: 6px 14px; font-size: .85rem; }} .stat b {{ font-size: 1.1rem; }} /* TABS */ .tabs-outer {{ background: #1a237e; padding: 0 20px; overflow-x: auto; white-space: nowrap; }} .tab-btn {{ display: inline-block; padding: 10px 16px; cursor: pointer; color: rgba(255,255,255,0.7); font-size: .8rem; font-weight: 600; border-bottom: 3px solid transparent; transition: all .2s; }} .tab-btn:hover {{ color: white; }} .tab-btn.active {{ color: white; border-bottom-color: #ffeb3b; }} .tab-badge {{ background: rgba(255,255,255,0.2); border-radius: 10px; padding: 1px 7px; font-size: .7rem; margin-left: 4px; }} /* MAIN */ .main {{ max-width: 1400px; margin: 0 auto; padding: 20px; }} /* OVERVIEW PANEL */ #overview-panel {{ display: block; }} .overview-grid {{ display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 12px; margin-bottom: 24px; }} .subj-card {{ background: var(--card); border-radius: 10px; padding: 14px; cursor: pointer; border-left: 5px solid; box-shadow: 0 2px 6px rgba(0,0,0,.08); transition: transform .2s, box-shadow .2s; }} .subj-card:hover {{ transform: translateY(-2px); box-shadow: 0 6px 16px rgba(0,0,0,.12); }} .subj-card h3 {{ font-size: .85rem; font-weight: 700; }} .subj-card .count {{ font-size: 2rem; font-weight: 800; margin: 6px 0; }} .subj-card .sub {{ font-size: .75rem; color: var(--sub); }} /* SEARCH BAR */ .search-box {{ display: flex; gap: 10px; margin-bottom: 20px; }} .search-box input {{ flex: 1; padding: 10px 16px; border: 2px solid var(--border); border-radius: 8px; font-size: .9rem; outline: none; }} .search-box input:focus {{ border-color: #3949ab; }} .search-box select {{ padding: 10px 12px; border: 2px solid var(--border); border-radius: 8px; font-size: .9rem; outline: none; background: white; cursor: pointer; }} /* SUBJECT PANEL */ .subj-panel {{ display: none; }} .subj-panel.active {{ display: block; }} .panel-header {{ display: flex; align-items: center; gap: 14px; margin-bottom: 20px; }} .panel-header h2 {{ font-size: 1.3rem; font-weight: 700; }} .panel-header .count-badge {{ background: var(--accent); color: white; border-radius: 20px; padding: 3px 12px; font-size: .85rem; font-weight: 700; }} /* FLOWCHART */ .flowchart-section {{ background: var(--card); border-radius: 12px; padding: 18px; margin-bottom: 20px; box-shadow: 0 2px 8px rgba(0,0,0,.06); }} .flowchart-section h3 {{ font-size: 1rem; font-weight: 700; color: var(--primary); margin-bottom: 14px; }} .flow-row {{ display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }} .flow-node {{ padding: 8px 16px; border-radius: 8px; font-size: .82rem; font-weight: 600; color: white; cursor: pointer; transition: opacity .2s; position: relative; }} .flow-node:hover {{ opacity: .85; }} .flow-node .fn {{ font-size: .72rem; opacity: .85; display: block; }} .flow-arrow {{ font-size: 1.2rem; color: var(--sub); }} .flow-node.main-topic {{ border-radius: 50px; font-size: .88rem; }} /* QUESTIONS LIST */ .q-list {{ display: flex; flex-direction: column; gap: 10px; }} .q-card {{ background: var(--card); border-radius: 10px; padding: 14px 16px; box-shadow: 0 1px 5px rgba(0,0,0,.07); cursor: pointer; border-left: 4px solid; transition: box-shadow .2s; }} .q-card:hover {{ box-shadow: 0 4px 14px rgba(0,0,0,.12); }} .q-card.expanded {{ box-shadow: 0 4px 14px rgba(0,0,0,.12); }} .q-header {{ display: flex; gap: 10px; align-items: flex-start; }} .q-num {{ background: var(--primary); color: white; border-radius: 6px; padding: 2px 8px; font-size: .75rem; font-weight: 700; min-width: 36px; text-align: center; margin-top: 2px; }} .q-text {{ font-size: .88rem; line-height: 1.5; flex: 1; }} .q-ans {{ margin-top: 8px; padding: 8px 12px; background: #e8f5e9; border-radius: 6px; font-size: .82rem; color: #2e7d32; font-weight: 600; display: none; }} .q-card.expanded .q-ans {{ display: block; }} .q-toggle {{ font-size: .75rem; color: var(--sub); margin-top: 6px; }} /* FILTER CHIPS */ .filter-chips {{ display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 14px; }} .chip {{ padding: 5px 12px; border-radius: 20px; font-size: .78rem; cursor: pointer; border: 2px solid; font-weight: 600; transition: all .2s; }} .chip.active {{ color: white; }} .chip:not(.active) {{ background: white; }} /* FLASHCARD MODE */ .flashcard-btn {{ background: #1a237e; color: white; border: none; border-radius: 8px; padding: 8px 18px; font-size: .85rem; font-weight: 600; cursor: pointer; margin-bottom: 16px; }} .flashcard-overlay {{ display: none; position: fixed; inset: 0; background: rgba(0,0,0,.7); z-index: 1000; align-items: center; justify-content: center; }} .flashcard-overlay.open {{ display: flex; }} .flashcard {{ background: white; border-radius: 16px; padding: 30px; max-width: 600px; width: 90%; text-align: center; }} .flashcard .fc-q {{ font-size: 1rem; line-height: 1.6; margin-bottom: 20px; color: var(--text); }} .flashcard .fc-subj {{ font-size: .8rem; color: var(--sub); margin-bottom: 8px; }} .flashcard .fc-num {{ font-size: .8rem; font-weight: 700; color: var(--primary); }} .fc-reveal {{ background: var(--accent); color: white; border: none; border-radius: 8px; padding: 10px 24px; font-size: .9rem; cursor: pointer; margin: 0 6px; }} .fc-next {{ background: var(--primary); color: white; border: none; border-radius: 8px; padding: 10px 24px; font-size: .9rem; cursor: pointer; margin: 0 6px; }} .fc-close {{ background: #ccc; color: #333; border: none; border-radius: 8px; padding: 10px 24px; font-size: .9rem; cursor: pointer; margin: 0 6px; }} .fc-answer {{ display: none; background: #e8f5e9; border-radius: 8px; padding: 12px; color: #2e7d32; font-weight: 700; margin: 12px 0; font-size: .95rem; }} .fc-progress {{ font-size: .8rem; color: var(--sub); margin-top: 12px; }} /* RESPONSIVE */ @media (max-width: 600px) {{ .overview-grid {{ grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); }} .header h1 {{ font-size: 1.2rem; }} }} .hidden {{ display: none !important; }} .back-btn {{ background: none; border: 2px solid var(--primary); color: var(--primary); border-radius: 8px; padding: 6px 14px; cursor: pointer; font-size: .85rem; font-weight: 600; margin-bottom: 14px; }} .back-btn:hover {{ background: var(--primary); color: white; }} </style> </head> <body> <div class="header"> <h1>FMGE June 2026 - Quick Study Guide</h1> <p>Interactive review for NEET PG 2026 preparation | 259 questions with answers</p> <div class="header-stats"> <div class="stat"><b>259</b> Questions</div> <div class="stat"><b>17</b> Subjects</div> <div class="stat"><b>FMGE June 2026</b> Recall Paper</div> <div class="stat"><b>NEET PG 2026</b> Ready</div> </div> </div> <div class="tabs-outer"> <span class="tab-btn active" onclick="showTab('overview')">Overview</span> <span class="tab-btn" onclick="showTab('all')">All Questions <span class="tab-badge">259</span></span> <span class="tab-btn" onclick="showTab('flashcard')">Flashcard Mode</span> </div> <div class="main"> <!-- OVERVIEW PANEL --> <div id="overview-panel"> <p style="color:var(--sub); margin-bottom:14px; font-size:.85rem;">Click any subject card to see questions + flowchart</p> <div class="overview-grid" id="overview-grid"> </div> </div> <!-- ALL QUESTIONS PANEL --> <div id="all-panel" class="hidden"> <div class="search-box"> <input type="text" id="search-input" placeholder="Search questions..." oninput="filterAll()"> <select id="subj-filter" onchange="filterAll()"> <option value="">All Subjects</option> </select> </div> <div id="all-q-list" class="q-list"></div> </div> <!-- SUBJECT PANELS --> <div id="subject-panels"> </div> <!-- FLASHCARD OVERLAY --> <div class="flashcard-overlay" id="fc-overlay"> <div class="flashcard"> <div class="fc-num" id="fc-num"></div> <div class="fc-subj" id="fc-subj"></div> <div class="fc-q" id="fc-q"></div> <div class="fc-answer" id="fc-answer"></div> <div> <button class="fc-reveal" onclick="revealAnswer()">Reveal Answer</button> <button class="fc-next" onclick="nextCard()">Next →</button> <button class="fc-close" onclick="closeFlashcard()">Close</button> </div> <div class="fc-progress" id="fc-progress"></div> </div> </div> </div><!-- /main --> <script> const DATA = {subj_js}; const ALL_Q = {questions_js}; const COLORS = {{ "Anatomy":"#e74c3c","Biochemistry":"#8e44ad","ENT":"#2980b9","Pharmacology":"#16a085", "Physiology":"#d35400","Surgery":"#c0392b","Pathology":"#7f8c8d","Microbiology":"#27ae60", "Medicine":"#2c3e50","General/Mixed":"#546e7a","Paediatrics":"#f39c12","Ophthalmology":"#1abc9c", "Obs & Gynae":"#e91e63","Dermatology":"#ff5722","Community Medicine":"#795548", "Radiology":"#607d8b","Psychiatry":"#9c27b0","Forensic Medicine":"#455a64" }}; // Build overview grid const grid = document.getElementById('overview-grid'); Object.entries(DATA).forEach(([subj, d]) => {{ const card = document.createElement('div'); card.className = 'subj-card'; card.style.borderLeftColor = d.color; card.innerHTML = ` <h3>${{subj}}</h3> <div class="count" style="color:${{d.color}}">${{d.qs.length}}</div> <div class="sub">questions</div> `; card.onclick = () => openSubject(subj); grid.appendChild(card); }}); // Build subject panels const spanel = document.getElementById('subject-panels'); Object.entries(DATA).forEach(([subj, d]) => {{ const div = document.createElement('div'); div.id = 'sp-' + subj.replace(/[^a-z]/gi,''); div.className = 'subj-panel'; // Build flowchart nodes const topicNodes = d.topics.map((tp, i) => {{ const colors2 = ['#e74c3c','#3498db','#2ecc71','#f39c12','#9b59b6','#1abc9c']; return `<div class="flow-node" style="background:${{colors2[i % colors2.length]}}" onclick="filterByTopic('${{subj}}','${{tp[0]}}')"> ${{tp[0]}}<span class="fn">${{tp[1]}} q</span> </div>` + (i < d.topics.length-1 ? '<span class="flow-arrow">→</span>' : ''); }}).join(''); const qs_html = d.qs.map(q => ` <div class="q-card" id="qcard${{q.num}}" style="border-left-color:${{d.color}}" onclick="toggleQ(${{q.num}})"> <div class="q-header"> <span class="q-num">Q${{q.num}}</span> <div class="q-text">${{q.summary}}</div> </div> <div class="q-ans">✓ Answer: ${{q.answer}}</div> <div class="q-toggle">Click to toggle answer</div> </div> `).join(''); div.innerHTML = ` <button class="back-btn" onclick="goBack()">← Back to Overview</button> <div class="panel-header"> <h2>${{subj}}</h2> <span class="count-badge">${{d.qs.length}} Questions</span> </div> <div class="flowchart-section"> <h3>▶ Key Topics Flow (click to filter)</h3> <div class="flow-row">${{topicNodes}}</div> </div> <button class="flashcard-btn" onclick="startFlashcards('${{subj}}')">▶ Flashcard Mode for ${{subj}}</button> <div id="qlist-${{subj.replace(/[^a-z]/gi,'')}}" class="q-list">${{qs_html}}</div> `; spanel.appendChild(div); }}); // Build all-questions select const sel = document.getElementById('subj-filter'); Object.keys(DATA).forEach(s => {{ const opt = document.createElement('option'); opt.value = s; opt.textContent = s; sel.appendChild(opt); }}); // Build all questions list const allList = document.getElementById('all-q-list'); function buildAllList(filtered) {{ const qs = filtered || ALL_Q; allList.innerHTML = qs.map(q => ` <div class="q-card" style="border-left-color:${{COLORS[q.subject] || '#666'}}" onclick="toggleQ(${{q.num}})"> <div class="q-header"> <span class="q-num" style="background:${{COLORS[q.subject] || '#666'}}">Q${{q.num}}</span> <div> <div class="q-text">${{q.summary}}</div> <div style="font-size:.72rem;color:var(--sub);margin-top:3px">${{q.subject}}</div> </div> </div> <div class="q-ans" id="qa${{q.num}}">✓ ${{q.answer}}</div> </div> `).join(''); }} buildAllList(); function filterAll() {{ const term = document.getElementById('search-input').value.toLowerCase(); const subj = document.getElementById('subj-filter').value; let filtered = ALL_Q; if (subj) filtered = filtered.filter(q => q.subject === subj); if (term) filtered = filtered.filter(q => q.question.toLowerCase().includes(term) || q.answer.toLowerCase().includes(term)); buildAllList(filtered); }} function toggleQ(num) {{ const card = document.getElementById('qcard' + num); if (card) {{ card.classList.toggle('expanded'); return; }} // From all list const ans = document.getElementById('qa' + num); if (ans) ans.style.display = ans.style.display === 'block' ? 'none' : 'block'; }} let currentPanel = null; function openSubject(subj) {{ document.getElementById('overview-panel').classList.add('hidden'); document.getElementById('all-panel').classList.add('hidden'); const id = 'sp-' + subj.replace(/[^a-z]/gi,''); if (currentPanel) document.getElementById(currentPanel).classList.remove('active'); document.getElementById(id).classList.add('active'); currentPanel = id; }} function goBack() {{ if (currentPanel) {{ document.getElementById(currentPanel).classList.remove('active'); currentPanel = null; }} document.getElementById('overview-panel').classList.remove('hidden'); // reset tabs document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active')); document.querySelector('.tab-btn').classList.add('active'); }} function showTab(tab) {{ document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active')); event.target.classList.add('active'); document.getElementById('overview-panel').classList.add('hidden'); document.getElementById('all-panel').classList.add('hidden'); if (currentPanel) {{ document.getElementById(currentPanel).classList.remove('active'); currentPanel = null; }} if (tab === 'overview') document.getElementById('overview-panel').classList.remove('hidden'); else if (tab === 'all') document.getElementById('all-panel').classList.remove('hidden'); else if (tab === 'flashcard') startFlashcards(null); }} function filterByTopic(subj, topic) {{ // highlight relevant questions - just scroll to first match alert('Filtering by: ' + topic + '\\nTip: Use Ctrl+F to search for keywords in the question list below.'); }} // FLASHCARD MODE let fcQueue = [], fcIdx = 0; function startFlashcards(subj) {{ fcQueue = subj ? DATA[subj].qs : ALL_Q; fcQueue = [...fcQueue].sort(() => Math.random() - 0.5); fcIdx = 0; document.getElementById('fc-overlay').classList.add('open'); showCard(); }} function showCard() {{ if (fcIdx >= fcQueue.length) {{ closeFlashcard(); alert('All done! Great job!'); return; }} const q = fcQueue[fcIdx]; document.getElementById('fc-num').textContent = 'Q' + q.num; document.getElementById('fc-subj').textContent = q.subject; document.getElementById('fc-q').textContent = q.question; document.getElementById('fc-answer').style.display = 'none'; document.getElementById('fc-answer').textContent = 'Answer: ' + q.answer; document.getElementById('fc-progress').textContent = (fcIdx+1) + ' / ' + fcQueue.length; }} function revealAnswer() {{ document.getElementById('fc-answer').style.display = 'block'; }} function nextCard() {{ fcIdx++; showCard(); }} function closeFlashcard() {{ document.getElementById('fc-overlay').classList.remove('open'); }} </script> </body> </html> """ out_path = "/home/daytona/workspace/FMGE_2026_Study_Guide.html" with open(out_path, "w", encoding="utf-8") as f: f.write(html) import os size = os.path.getsize(out_path) print(f"HTML written: {out_path}") print(f"File size: {size/1024:.1f} KB") PYEOF
python3 - << 'EOF' import json from collections import defaultdict with open("/home/daytona/workspace/fmge_questions.json") as f: questions = json.load(f) subj_map = defaultdict(list) for q in questions: subj_map[q["subject"]].append(q) subjects_ordered = ["Anatomy","Biochemistry","ENT","Pharmacology","Physiology","Surgery","Pathology", "Microbiology","Medicine","Paediatrics","Ophthalmology","Obs & Gynae","Dermatology", "Community Medicine","Radiology","Psychiatry","General/Mixed"] lines = [] lines.append("FMGE JUNE 2026 - QUICK REVISION SHEET") lines.append("=" * 70) lines.append("259 Questions | Subject-wise | NEET PG 2026 Preparation") lines.append("=" * 70) lines.append("") for subj in subjects_ordered: qs = subj_map.get(subj, []) if not qs: continue lines.append(f"\n{'='*60}") lines.append(f" {subj.upper()} ({len(qs)} Questions)") lines.append(f"{'='*60}") for q in qs: # Shorten question to key clinical pointer qtext = q["summary"][:140].strip() ans = q["answer"][:80].strip() lines.append(f"Q{q['num']:3d}. {qtext}") lines.append(f" >> ANS: {ans}") lines.append("") text_out = "\n".join(lines) with open("/home/daytona/workspace/FMGE_2026_Quick_Revision.txt", "w") as f: f.write(text_out) print(f"Text file written: {len(text_out)} chars, {len(lines)} lines") EOF
FMGE 2026 Study Guide
HTML File · HTML
FMGE 2026 Quick Revision
Text File · TXT
| Mode | What it does |
|---|---|
| Overview | Subject cards showing question count per subject - click any to open |
| Subject View | Flowchart of key topics + all questions with toggle-able answers |
| Flashcard Mode | Randomized Q&A cards - reveal answer on click, track progress |
| Subject | Questions |
|---|---|
| Anatomy | 68 |
| Biochemistry | 29 |
| ENT | 28 |
| Pharmacology | 21 |
| Physiology | 18 |
| Surgery | 15 |
| Pathology | 14 |
| Microbiology | 12 |
| Medicine | 11 |
| Paediatrics | 10 |
.html file and open it in Chrome/Safari/FirefoxCreate a PDF printable version with all subjects
python3 -c "from reportlab.lib.pagesizes import A4; print('reportlab OK')"
python3 - << 'PYEOF' import json from collections import defaultdict from reportlab.lib.pagesizes import A4 from reportlab.lib import colors from reportlab.lib.units import mm, cm from reportlab.platypus import (SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, HRFlowable, PageBreak, KeepTogether) from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_RIGHT from reportlab.platypus.flowables import HRFlowable with open("/home/daytona/workspace/fmge_questions.json") as f: questions = json.load(f) subj_map = defaultdict(list) for q in questions: subj_map[q["subject"]].append(q) subjects_ordered = [ ("Anatomy", "#C0392B", 68), ("Biochemistry", "#6C3483", 29), ("ENT", "#1A5276", 28), ("Pharmacology", "#0E6655", 21), ("Physiology", "#784212", 18), ("Surgery", "#922B21", 15), ("Pathology", "#4D5656", 14), ("Microbiology", "#1E8449", 12), ("Medicine", "#1B2631", 11), ("Paediatrics", "#9A7D0A", 10), ("General/Mixed", "#2E4053", 10), ("Ophthalmology", "#148F77", 7), ("Obs & Gynae", "#A93226", 6), ("Dermatology", "#BA4A00", 5), ("Community Medicine","#5D4037", 2), ("Radiology", "#37474F", 2), ("Psychiatry", "#6A1B9A", 1), ] # Flowchart topics per subject FLOWCHART_TOPICS = { "Anatomy": ["Nerve Injuries","Vascular Anatomy","Joint & Bone","Embryology","Head & Neck","Abdominopelvic"], "Biochemistry": ["Vitamins","Enzyme Deficiencies","Amino Acids","Carb Metabolism","Molecular Biology","Lipids & Acid-Base"], "ENT": ["Ear / Audiology","Nose & Sinuses","Throat & Larynx","Head & Neck Tumors","Vestibular","Hearing Loss"], "Pharmacology": ["Antibiotics","Drug Mechanisms","Toxicity & Antidotes","CNS Drugs","CVS Drugs","Dosing Regimens"], "Physiology": ["Cardiac Physio","Renal Physio","Respiratory","Endocrine","Acid-Base","Neurophysio"], "Surgery": ["Wound Healing","Anesthesia","Abdominal Surgery","Trauma / FAST","Hernias","Thyroid & Breast"], "Pathology": ["Neoplasia","Vascular Pathology","Inflammation","Cell Injury","Hemodynamics","Genetic Disorders"], "Microbiology": ["Bacteriology","Virology","Parasitology","Mycology","Serology / Vaccines","Lab Diagnosis"], "Medicine": ["Cardiology","Respiratory","Neurology","Gastroenterology","Nephrology","Hematology"], "Paediatrics": ["Developmental","Neonatal","Nutrition","Vaccinations","Congenital","Infections"], "Ophthalmology": ["Glaucoma","Retina","Cornea & Lens","Orbit & Lids","Visual Pathways","Infections"], "Obs & Gynae": ["Obstetric Emergencies","Labour & Delivery","Gynaecology","Contraception","Fetal Wellbeing","Hormones"], "Dermatology": ["Infections","Papulosquamous","Blistering","Pigment Disorders","Tumors","Treatment"], "Community Medicine": ["Epidemiology","Vaccines & Programs","Nutrition","Biostatistics","Health Programs","Sanitation"], "Radiology": ["X-ray Interpretation","CT / MRI","Contrast Studies","Radiation Physics","Nuclear Medicine","Interventional"], "Psychiatry": ["Psychotic Disorders","Mood Disorders","Anxiety","Substance Abuse","Cognitive","Therapy"], "General/Mixed": ["Clinical Anatomy","Applied Physiology","Diagnostics","Mixed Clinical","Investigations","Management"], } # Subject hex -> reportlab color def hex_color(h): h = h.lstrip('#') r, g, b = tuple(int(h[i:i+2],16)/255 for i in (0,2,4)) return colors.Color(r, g, b) out_path = "/home/daytona/workspace/FMGE_2026_Printable.pdf" doc = SimpleDocTemplate( out_path, pagesize=A4, leftMargin=15*mm, rightMargin=15*mm, topMargin=18*mm, bottomMargin=18*mm, title="FMGE June 2026 - Quick Revision PDF", author="NEET PG 2026 Prep" ) styles = getSampleStyleSheet() # Custom styles TITLE_STYLE = ParagraphStyle("Title2", parent=styles["Title"], fontSize=22, textColor=colors.HexColor("#1A237E"), spaceAfter=4, alignment=TA_CENTER, fontName="Helvetica-Bold") SUBTITLE_STYLE = ParagraphStyle("Subtitle2", parent=styles["Normal"], fontSize=10, textColor=colors.HexColor("#5C6BC0"), spaceAfter=2, alignment=TA_CENTER) SUBJ_HEADING = ParagraphStyle("SubjHead", parent=styles["Heading1"], fontSize=15, textColor=colors.white, spaceBefore=6, spaceAfter=4, fontName="Helvetica-Bold", leftIndent=6) Q_STYLE = ParagraphStyle("QStyle", parent=styles["Normal"], fontSize=8.5, leading=12, textColor=colors.HexColor("#212121"), spaceAfter=1) ANS_STYLE = ParagraphStyle("AnsStyle", parent=styles["Normal"], fontSize=8.5, leading=12, textColor=colors.HexColor("#1B5E20"), fontName="Helvetica-Bold", spaceAfter=4) FLOW_STYLE = ParagraphStyle("FlowStyle", parent=styles["Normal"], fontSize=8, leading=10, textColor=colors.white, alignment=TA_CENTER, fontName="Helvetica-Bold") TOC_STYLE = ParagraphStyle("TocStyle", parent=styles["Normal"], fontSize=9.5, leading=14, textColor=colors.HexColor("#1A237E")) story = [] # ─── COVER PAGE ─── story.append(Spacer(1, 30*mm)) # Cover box cover_data = [[Paragraph("FMGE June 2026", TITLE_STYLE)], [Paragraph("Quick Revision Guide", ParagraphStyle("cv2", parent=styles["Normal"], fontSize=16, textColor=colors.HexColor("#3949AB"), alignment=TA_CENTER, fontName="Helvetica-Bold"))], [Spacer(1, 4*mm)], [Paragraph("NEET PG 2026 Preparation", ParagraphStyle("cv3", parent=styles["Normal"], fontSize=12, textColor=colors.HexColor("#5C6BC0"), alignment=TA_CENTER))], [Spacer(1, 8*mm)], [Paragraph("259 Questions | 17 Subjects | 1-2 Line Summaries + Answers", ParagraphStyle("cv4", parent=styles["Normal"], fontSize=10, textColor=colors.HexColor("#455A64"), alignment=TA_CENTER))], [Spacer(1, 4*mm)], [Paragraph("Compiled: July 2026", ParagraphStyle("cv5", parent=styles["Normal"], fontSize=9, textColor=colors.grey, alignment=TA_CENTER))]] cover_table = Table(cover_data, colWidths=[170*mm]) cover_table.setStyle(TableStyle([ ("BOX", (0,0), (-1,-1), 2, colors.HexColor("#1A237E")), ("BACKGROUND", (0,0), (-1,-1), colors.HexColor("#F3F4FF")), ("TOPPADDING", (0,0), (-1,-1), 8), ("BOTTOMPADDING", (0,0), (-1,-1), 6), ("LEFTPADDING", (0,0), (-1,-1), 16), ("RIGHTPADDING", (0,0), (-1,-1), 16), ("ROWBACKGROUNDS", (0,0), (-1,-1), [colors.HexColor("#F3F4FF")]), ])) story.append(cover_table) story.append(Spacer(1, 14*mm)) # Stats table on cover stat_data = [ ["259\nQuestions", "17\nSubjects", "1-2 Line\nSummaries", "Answers\nIncluded"] ] stat_table = Table(stat_data, colWidths=[40*mm]*4, rowHeights=[20*mm]) stat_table.setStyle(TableStyle([ ("BACKGROUND", (0,0), (0,0), colors.HexColor("#C0392B")), ("BACKGROUND", (1,0), (1,0), colors.HexColor("#1A5276")), ("BACKGROUND", (2,0), (2,0), colors.HexColor("#0E6655")), ("BACKGROUND", (3,0), (3,0), colors.HexColor("#6C3483")), ("TEXTCOLOR", (0,0), (-1,-1), colors.white), ("ALIGN", (0,0), (-1,-1), "CENTER"), ("VALIGN", (0,0), (-1,-1), "MIDDLE"), ("FONTNAME", (0,0), (-1,-1), "Helvetica-Bold"), ("FONTSIZE", (0,0), (-1,-1), 10), ("ROUNDEDCORNERS", [4]), ("TOPPADDING", (0,0), (-1,-1), 6), ("BOTTOMPADDING", (0,0), (-1,-1), 6), ])) story.append(stat_table) story.append(PageBreak()) # ─── TABLE OF CONTENTS ─── story.append(Paragraph("Contents", ParagraphStyle("TocTitle", parent=styles["Heading1"], fontSize=16, textColor=colors.HexColor("#1A237E"), fontName="Helvetica-Bold", spaceAfter=10))) toc_data = [["#", "Subject", "Questions"]] for subj, color_hex, count in subjects_ordered: qs = subj_map.get(subj, []) if qs: toc_data.append([str(subjects_ordered.index((subj, color_hex, count))+1), subj, str(len(qs))]) toc_table = Table(toc_data, colWidths=[12*mm, 120*mm, 30*mm]) toc_ts = [ ("BACKGROUND", (0,0), (-1,0), colors.HexColor("#1A237E")), ("TEXTCOLOR", (0,0), (-1,0), colors.white), ("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"), ("FONTSIZE", (0,0), (-1,-1), 9), ("ROWBACKGROUNDS", (0,1), (-1,-1), [colors.HexColor("#F8F9FA"), colors.white]), ("ALIGN", (0,0), (-1,-1), "LEFT"), ("ALIGN", (2,0), (2,-1), "CENTER"), ("LEFTPADDING", (0,0), (-1,-1), 8), ("TOPPADDING", (0,0), (-1,-1), 5), ("BOTTOMPADDING", (0,0), (-1,-1), 5), ("GRID", (0,0), (-1,-1), 0.3, colors.HexColor("#E0E0E0")), ] toc_table.setStyle(TableStyle(toc_ts)) story.append(toc_table) story.append(PageBreak()) # ─── SUBJECT SECTIONS ─── for subj, color_hex, _ in subjects_ordered: qs = subj_map.get(subj, []) if not qs: continue subj_color = hex_color(color_hex) light_bg = colors.Color(subj_color.red, subj_color.green, subj_color.blue, alpha=0.08) # Subject header bar hdr_data = [[Paragraph(f"{subj.upper()} ({len(qs)} Questions)", SUBJ_HEADING)]] hdr_table = Table(hdr_data, colWidths=[170*mm]) hdr_table.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,-1), subj_color), ("TOPPADDING", (0,0), (-1,-1), 6), ("BOTTOMPADDING", (0,0), (-1,-1), 6), ("LEFTPADDING", (0,0), (-1,-1), 10), ])) story.append(KeepTogether([hdr_table, Spacer(1, 2*mm)])) # Flowchart row topics = FLOWCHART_TOPICS.get(subj, []) if topics: flow_cells = [] fc_colors = ["#E53935","#1565C0","#2E7D32","#E65100","#6A1B9A","#00695C"] for i, tp in enumerate(topics[:6]): c = hex_color(fc_colors[i % len(fc_colors)]) p = Paragraph(tp, ParagraphStyle("ft", parent=styles["Normal"], fontSize=7.5, textColor=colors.white, alignment=TA_CENTER, fontName="Helvetica-Bold", leading=10)) flow_cells.append(p) # Build as a colored table row flow_table_data = [flow_cells] col_w = 170*mm / len(flow_cells) flow_table = Table(flow_table_data, colWidths=[col_w]*len(flow_cells), rowHeights=[9*mm]) flow_styles = [ ("TOPPADDING", (0,0), (-1,-1), 4), ("BOTTOMPADDING", (0,0), (-1,-1), 4), ("LEFTPADDING", (0,0), (-1,-1), 3), ("RIGHTPADDING", (0,0), (-1,-1), 3), ("ALIGN", (0,0), (-1,-1), "CENTER"), ("VALIGN", (0,0), (-1,-1), "MIDDLE"), ] for i, tp in enumerate(topics[:6]): c = hex_color(fc_colors[i % len(fc_colors)]) flow_styles.append(("BACKGROUND", (i,0), (i,0), c)) flow_table.setStyle(TableStyle(flow_styles)) story.append(flow_table) story.append(Spacer(1, 3*mm)) # Questions table - 2 columns for space efficiency q_rows = [] for i, q in enumerate(qs): qtext = q["summary"] if len(qtext) > 160: qtext = qtext[:157] + "..." ans = q["answer"] if len(ans) > 100: ans = ans[:97] + "..." cell = [ Paragraph(f"<b>Q{q['num']}.</b> {qtext}", Q_STYLE), Paragraph(f"✓ {ans}", ANS_STYLE), ] q_rows.append(cell) # Pack into 2-column layout two_col_rows = [] for i in range(0, len(q_rows), 2): left = q_rows[i] right = q_rows[i+1] if i+1 < len(q_rows) else [Paragraph("", Q_STYLE), Paragraph("", ANS_STYLE)] left_cell = Table([[left[0]], [left[1]]], colWidths=[83*mm]) left_cell.setStyle(TableStyle([ ("TOPPADDING",(0,0),(-1,-1),3),("BOTTOMPADDING",(0,0),(-1,-1),2), ("LEFTPADDING",(0,0),(-1,-1),4),("RIGHTPADDING",(0,0),(-1,-1),4), ("BACKGROUND",(0,0),(-1,-1), colors.HexColor("#FAFAFA") if i%4<2 else colors.white), ("BOX",(0,0),(-1,-1),0.5,colors.HexColor("#E0E0E0")), ("LINEBELOW",(0,0),(-1,0),0.3,colors.HexColor("#E8E8E8")), ])) right_cell = Table([[right[0]], [right[1]]], colWidths=[83*mm]) right_cell.setStyle(TableStyle([ ("TOPPADDING",(0,0),(-1,-1),3),("BOTTOMPADDING",(0,0),(-1,-1),2), ("LEFTPADDING",(0,0),(-1,-1),4),("RIGHTPADDING",(0,0),(-1,-1),4), ("BACKGROUND",(0,0),(-1,-1), colors.HexColor("#FAFAFA") if i%4<2 else colors.white), ("BOX",(0,0),(-1,-1),0.5,colors.HexColor("#E0E0E0")), ("LINEBELOW",(0,0),(-1,0),0.3,colors.HexColor("#E8E8E8")), ])) two_col_rows.append([left_cell, right_cell]) if two_col_rows: main_table = Table(two_col_rows, colWidths=[85*mm, 85*mm], spaceBefore=0, spaceAfter=0) main_table.setStyle(TableStyle([ ("VALIGN",(0,0),(-1,-1),"TOP"), ("LEFTPADDING",(0,0),(-1,-1),0), ("RIGHTPADDING",(0,0),(-1,-1),0), ("TOPPADDING",(0,0),(-1,-1),1), ("BOTTOMPADDING",(0,0),(-1,-1),1), ])) story.append(main_table) story.append(Spacer(1, 4*mm)) story.append(PageBreak()) # Build PDF doc.build(story) import os size = os.path.getsize(out_path) print(f"PDF created: {out_path}") print(f"Size: {size/1024:.1f} KB") PYEOF
python3 -c " from pypdf import PdfReader r = PdfReader('/home/daytona/workspace/FMGE_2026_Printable.pdf') print(f'Pages: {len(r.pages)}') # Sample first page text print(r.pages[0].extract_text()[:200]) print('---PAGE 2---') print(r.pages[1].extract_text()[:200]) print('---PAGE 3---') print(r.pages[2].extract_text()[:300]) "
FMGE 2026 Printable
PDF Document · PDF
| Page | Content |
|---|---|
| 1 | Cover page with stats |
| 2 | Table of Contents (17 subjects with question counts) |
| 3-25 | All 17 subjects, one section per subject |
Always remember plz i have i phone ios so html do not open here
FMGE 2026 Printable
PDF Document · PDF