You are an expert medical educator and high-yield revision specialist for competitive exams (NEET-PG, FMGE, INI-CET, USMLE Step 2/3, PLAB). Input: I am attaching an MCQ PDF containing hundreds of multiple-choice questions (single best answer type). Task: Perform a complete topic-wise analysis of every single MCQ in the PDF and convert it into the most concise, high-yield revision notes possible. Step-by-step instructions (follow exactly): Extract & Categorize Read every MCQ. Identify the exact disease/condition/syndrome/topic each question is testing. Note the chapter/system if mentioned. Merge Common Topics Aggressively merge all overlapping or related topics into single master topics. Example: “Rheumatic fever”, “Rheumatic heart disease”, “Jones criteria”, “Mitral stenosis” → merge into one topic “Rheumatic Heart Disease & Acute Rheumatic Fever”. “Diabetic ketoacidosis”, “Hyperosmolar hyperglycemic state”, “Type-1 DM complications” → merge into “Diabetic Emergencies & Acute Complications of DM”. For every merged topic, first write one single line at the top: Merged Topics: Acute Rheumatic Fever, Rheumatic Heart Disease, Jones criteria, Mitral stenosis, Aortic regurgitation (all MCQs merged). Output Format for EACH Merged Topic (strict structure): Topic Name: [Clear, concise, exam-friendly name] Merged Topics: [One-line list of all original topics merged] Stem Clues (High-yield presentation): • Bullet list of the most common MCQ stem triggers and classic presentations that point to this disease (age, gender, key symptoms, signs, risk factors, “classic vignette” phrases). Investigations (Key & Diagnostic): • Most important lab tests, imaging, special tests with their characteristic findings. • Mention gold-standard test and any pathognomonic findings. Treatment & Management: • First-line drugs/doses (if asked frequently), step-wise management, surgical indications, follow-up. • Any “must-know” emergency treatment or specific guidelines. Specific Peculiarities & Red Flags (Differentiation): • Unique clinical pearls, pathognomonic signs, buzzwords, or features that instantly distinguish this disease from close differentials in MCQs. • Any “never miss” or “always think of” points. Quick-Revision Memory Aids (Last 30-minute revision): • Mnemonics, acronyms, short memory hooks, visual associations, “one-liner” facts, or tables that can be revised in under 2 minutes before the exam. • Include any high-yield numbers (incidence, cut-offs, percentages) that repeatedly appear in MCQs. Final Output Instructions: Organise all topics in a logical order (by system → by frequency of appearance). Use clear headings, bullet points,buzz words, bold text, and tables wherever helpful. Keep language extremely concise and exam-oriented (no long paragraphs). Begin your response directly with the first merged topic. Avoid abbreviations .Do not add any meta-commentary or apology. Start working immediately after you receive the PDF. Generate answer in DOCX file. Recheck all MCQ, Don't miss any. . And recheck for all missing MCQ. No backgrounds colours. It will waste ink during printing. All text must be in black ink. Use only bold, italic or different font size to differentiate heading or some important stuff. Remove all blank space. So I can take printout in minimal number of pages. Minimum font size of 9 or more. keep all available images,ECG, x ray require to diagnosis in revision word document.
cd /home/daytona/workspace && python3 -c " import pdfplumber pdf_path = '/home/daytona/workspace/attachments/a68b12aa-0d33-4755-8240-4ff744f3c30e/BMJ OnExamination Cardiology 2025 part 2-compressed.pdf' with pdfplumber.open(pdf_path) as pdf: print(f'Total pages: {len(pdf.pages)}') # Show first 3 pages to understand structure for i in range(min(3, len(pdf.pages))): print(f'--- PAGE {i+1} ---') text = pdf.pages[i].extract_text() print(text[:2000] if text else 'No text') print() "
cd /home/daytona/workspace && python3 << 'EOF' import pdfplumber import json import re pdf_path = '/home/daytona/workspace/attachments/a68b12aa-0d33-4755-8240-4ff744f3c30e/BMJ OnExamination Cardiology 2025 part 2-compressed.pdf' mcqs = [] current_q = None with pdfplumber.open(pdf_path) as pdf: total = len(pdf.pages) print(f"Total pages: {total}") for i in range(1, total): # skip page 0 (no text) text = pdf.pages[i].extract_text() if not text: continue # Detect question page (has "Answer question" at end) if 'Answer question' in text and 'Question' in text: # Extract question number m = re.search(r'Question (\d+) of 200', text) if m: qnum = int(m.group(1)) # Extract question text (between question line and options) lines = text.split('\n') # Find the question body q_text = '' options = [] in_q = False for line in lines: line = line.strip() if f'Question {qnum} of 200' in line: in_q = True continue if 'Answer question' in line or 'Time elapsed' in line or 'My score' in line: break if in_q and line and line not in ['Exit session', 'English French', 'Question navigator', 'Add tags']: if line not in ['Previous', 'Next']: q_text += line + ' ' current_q = {'num': qnum, 'question': q_text.strip(), 'page': i+1} # Detect answer/explanation page elif 'Key learning points' in text and current_q: lines = text.split('\n') explanation = '' in_exp = False topics = '' for j, line in enumerate(lines): line = line.strip() if 'Key learning points' in line: # Next line(s) are topics if j+1 < len(lines): topics = lines[j+1].strip() in_exp = False elif 'Explanation' in line and not in_exp: in_exp = True continue elif in_exp: if 'Reference:' in line or 'Next question' in line or 'Add revision notes' in line: break if line: explanation += line + ' ' current_q['topics'] = topics current_q['explanation'] = explanation.strip() mcqs.append(current_q) current_q = None print(f"Extracted {len(mcqs)} MCQs") # Save to file with open('/home/daytona/workspace/mcqs_extracted.json', 'w') as f: json.dump(mcqs, f, indent=2) print("Saved to mcqs_extracted.json") # Show first 3 for q in mcqs[:3]: print(f"\nQ{q['num']}: {q['question'][:200]}") print(f"Topics: {q.get('topics','')}") print(f"Explanation: {q.get('explanation','')[:300]}") EOF
python3 << 'EOF' from pypdf import PdfReader import json, re, sys pdf_path = '/home/daytona/workspace/attachments/a68b12aa-0d33-4755-8240-4ff744f3c30e/BMJ OnExamination Cardiology 2025 part 2-compressed.pdf' # Process in batches to avoid memory issues reader = PdfReader(pdf_path) total = len(reader.pages) print(f"Total pages: {total}", flush=True) mcqs = [] current_q = None for i in range(1, total): try: text = reader.pages[i].extract_text() except: continue if not text: continue # Detect question page if 'Answer question' in text and 'Question' in text: m = re.search(r'Question (\d+) of 200', text) if m: qnum = int(m.group(1)) lines = [l.strip() for l in text.split('\n')] q_text = '' in_q = False skip = {'Exit session','English French','Question navigator','Add tags','Previous','Next','Answer question','Time elapsed','My score','0%','(0/0)'} for line in lines: if f'Question {qnum} of 200' in line: in_q = True continue if 'Answer question' in line or 'Time elapsed' in line: break if in_q and line and line not in skip and not line.startswith('Previous Question'): q_text += line + ' ' current_q = {'num': qnum, 'question': q_text.strip()} elif 'Key learning points' in text and current_q: lines = [l.strip() for l in text.split('\n')] explanation = '' topics = '' correct_ans = '' in_exp = False for j, line in enumerate(lines): if 'Key learning points' in line: if j+1 < len(lines): topics = lines[j+1].strip() elif 'Explanation' in line and not in_exp: in_exp = True continue elif in_exp: if 'Reference:' in line or 'Next question' in line or 'Add revision notes' in line: break if line and not line.startswith('%') and not re.match(r'^\d+%$', line): explanation += line + ' ' current_q['topics'] = topics current_q['explanation'] = explanation.strip() mcqs.append(current_q) if len(mcqs) % 20 == 0: print(f" Processed {len(mcqs)} MCQs...", flush=True) current_q = None print(f"\nTotal extracted: {len(mcqs)}") with open('/home/daytona/workspace/mcqs_extracted.json', 'w') as f: json.dump(mcqs, f, indent=2) print("Saved.") EOF
python3 << 'EOF' from pypdf import PdfReader import re pdf_path = '/home/daytona/workspace/attachments/a68b12aa-0d33-4755-8240-4ff744f3c30e/BMJ OnExamination Cardiology 2025 part 2-compressed.pdf' reader = PdfReader(pdf_path) # Sample pages 2-20 to understand structure for i in range(1, 25): try: text = reader.pages[i].extract_text() except: continue if text: first_100 = text[:120].replace('\n',' ') has_answer = 'Answer question' in text has_key = 'Key learning' in text has_correct = 'Correct' in text or 'Incorrect' in text print(f"Page {i+1}: ans={has_answer} key={has_key} correct={has_correct} | {first_100[:80]}") EOF
python3 << 'EOF' from pypdf import PdfReader import re, json pdf_path = '/home/daytona/workspace/attachments/a68b12aa-0d33-4755-8240-4ff744f3c30e/BMJ OnExamination Cardiology 2025 part 2-compressed.pdf' reader = PdfReader(pdf_path) total = len(reader.pages) # The pattern: # - "Answer question" page: has question + options (before answering) # - "Key learning points" page: has question stem repeated + answer + explanation # Strategy: Extract from the KEY LEARNING page (page with "Key learning points") # which has the full question + correct answer highlighted + explanation mcqs = [] noise = {'Exit session','English French','Question navigator','Add tags','Previous','Next', 'Answer question','Time elapsed','My score','Save notes','Rate this question', 'Improve this Question','You\'ll receive a summary'} for i in range(1, total): try: text = reader.pages[i].extract_text() except: continue if not text or 'Key learning points' not in text: continue m = re.search(r'Question (\d+) of 200', text) if not m: continue qnum = int(m.group(1)) lines = [l.strip() for l in text.split('\n') if l.strip()] # Find question stem - it appears after "Question N of 200" header lines # and before the answer options (which have percentages) q_start = -1 q_end = -1 exp_start = -1 topics_line = '' for j, line in enumerate(lines): if f'Question {qnum} of 200' in line and q_start == -1: q_start = j + 1 if q_start > 0 and q_end == -1: # Options have percentage pattern nearby or "Correct"/"Incorrect" before them if re.match(r'^\d+%$', line) or line in ('Correct', 'Incorrect'): q_end = j if 'Key learning points' in line: if j+1 < len(lines): topics_line = lines[j+1] if 'Explanation' in line and exp_start == -1: exp_start = j + 1 # Extract question text question = '' if q_start > 0: end = q_end if q_end > q_start else min(q_start+20, len(lines)) for line in lines[q_start:end]: if line in noise or re.match(r'^\d+%$', line) or line in ('Correct','Incorrect'): break if not any(x in line for x in ['Exit session','English French','Question navigator']): question += line + ' ' # Extract explanation explanation = '' if exp_start > 0: for line in lines[exp_start:]: if 'Reference:' in line or 'Next question' in line or 'Add revision notes' in line: break if line and not re.match(r'^\d+%$', line): explanation += line + ' ' mcqs.append({ 'num': qnum, 'question': question.strip(), 'topics': topics_line, 'explanation': explanation.strip() }) mcqs.sort(key=lambda x: x['num']) print(f"Extracted {len(mcqs)} MCQs") # Check for duplicates and missing nums = [q['num'] for q in mcqs] unique = sorted(set(nums)) print(f"Unique question numbers: {len(unique)}, range: {min(unique)}-{max(unique)}") missing = [n for n in range(1, 201) if n not in unique] print(f"Missing Q numbers: {missing[:20]}") with open('/home/daytona/workspace/mcqs_extracted.json', 'w') as f: json.dump(mcqs, f, indent=2) # Show sample for q in mcqs[:3]: print(f"\nQ{q['num']}: {q['question'][:150]}") print(f"Topics: {q['topics']}") print(f"Explanation: {q['explanation'][:200]}") EOF
python3 << 'EOF' from pypdf import PdfReader import re pdf_path = '/home/daytona/workspace/attachments/a68b12aa-0d33-4755-8240-4ff744f3c30e/BMJ OnExamination Cardiology 2025 part 2-compressed.pdf' reader = PdfReader(pdf_path) # Look at pages 24-50 to understand structure for Q7-Q15 for i in range(23, 60): try: text = reader.pages[i].extract_text() except: text = '' if text: has_answer = 'Answer question' in text has_key = 'Key learning' in text m = re.search(r'Question (\d+) of 200', text) qnum = m.group(1) if m else '?' first = text[:80].replace('\n',' ') print(f"P{i+1} Q{qnum} ans={has_answer} key={has_key}: {first[:70]}") else: print(f"P{i+1}: NO TEXT") EOF
python3 << 'EOF' from pypdf import PdfReader import sys pdf_path = '/home/daytona/workspace/attachments/a68b12aa-0d33-4755-8240-4ff744f3c30e/BMJ OnExamination Cardiology 2025 part 2-compressed.pdf' reader = PdfReader(pdf_path) total = len(reader.pages) print(f"Total pages: {total}") # Dump all text to file in chunks with open('/home/daytona/workspace/all_text.txt', 'w', encoding='utf-8') as f: for i in range(1, total): try: text = reader.pages[i].extract_text() if text: f.write(f"\n===PAGE_{i+1}===\n") f.write(text) except Exception as e: pass if (i+1) % 100 == 0: print(f"Processed {i+1}/{total}", flush=True) import os size = os.path.getsize('/home/daytona/workspace/all_text.txt') print(f"Done. File size: {size/1024:.0f} KB") EOF
python3 << 'PYEOF' import re, json with open('/home/daytona/workspace/all_text.txt', 'r', encoding='utf-8') as f: content = f.read() # Split into page blocks pages = re.split(r'\n===PAGE_(\d+)===\n', content) # pages[0] = empty, then alternating: page_num, text, page_num, text... page_dict = {} for i in range(1, len(pages), 2): pnum = int(pages[i]) ptext = pages[i+1] if i+1 < len(pages) else '' page_dict[pnum] = ptext print(f"Pages with text: {len(page_dict)}") # Strategy: find all pages that have "Key learning points" AND explanation content # The question stem appears on "Answer question" pages OR on the key learning pages # Explanations can span to next page (continuation pages) mcqs_raw = {} # key: question_id (qnum + set), value: dict # Identify all "Key learning points" pages - these have the answer explanation kl_pages = [(pnum, text) for pnum, text in sorted(page_dict.items()) if 'Key learning points' in text] print(f"Key learning pages: {len(kl_pages)}") # Collect explanation pages (continuation) for pnum, text in kl_pages: m_q = re.search(r'Question (\d+) of (\d+)', text) if not m_q: continue qnum = int(m_q.group(1)) qset = int(m_q.group(2)) key = f"{qset}_{qnum}" # Topics topics_m = re.search(r'Key learning points\s*\n([^\n]+)', text) topics = topics_m.group(1).strip() if topics_m else '' # Also check if next line after Key learning points has topic kl_idx = text.find('Key learning points') topic_area = text[kl_idx:kl_idx+200] topic_lines = [l.strip() for l in topic_area.split('\n') if l.strip()] topics = topic_lines[1] if len(topic_lines) > 1 else topics # Explanation from this page exp_start = text.find('Explanation') if exp_start == -1: exp_start = text.find('Key learning points') exp_text = text[exp_start:] if exp_start >= 0 else text # Clean up exp_lines = [l.strip() for l in exp_text.split('\n') if l.strip()] clean_exp = [] started = False for line in exp_lines: if 'Explanation' in line: started = True continue if started: if any(x in line for x in ['Reference:', 'Next question', 'Add revision notes', 'You\'ll receive']): break if re.match(r'^\d+%$', line): continue clean_exp.append(line) # Get question stem - look at "Answer question" pages for this qnum # Find nearby pages with same question number q_stem = '' for check_page in range(pnum-5, pnum+1): if check_page in page_dict: pg = page_dict[check_page] if f'Question {qnum} of {qset}' in pg and 'Answer question' in pg: # Extract question text lines = [l.strip() for l in pg.split('\n') if l.strip()] in_q = False stem_lines = [] skip_words = {'Exit session','English French','Question navigator','Add tags', 'Previous','Next','Answer question','Time elapsed','My score', 'Save notes','Rate this question','Improve this Question'} for ln in lines: if f'Question {qnum} of {qset}' in ln: in_q = True continue if in_q: if 'Answer question' in ln or ln in skip_words: break if ln and ln not in skip_words and not ln.startswith('Previous Question') and not re.match(r'^\d+%$|^\d+/\d+$', ln): stem_lines.append(ln) q_stem = ' '.join(stem_lines) break # Also try to get stem from the key learning page itself (before answer options) if not q_stem: # The key learning page shows: question header, then stem, then options with % lines = [l.strip() for l in text.split('\n') if l.strip()] in_q = False stem_lines = [] for ln in lines: if f'Question {qnum} of {qset}' in ln: in_q = True continue if in_q: if re.match(r'^\d+%$', ln) or ln in ('Correct','Incorrect'): break if ln and not any(x in ln for x in ['Exit session','English French','Question navigator']): stem_lines.append(ln) q_stem = ' '.join(stem_lines) # Check continuation page for more explanation cont_exp = '' next_pnum = pnum + 1 while next_pnum in page_dict: next_text = page_dict[next_pnum] if 'Key learning points' in next_text or 'Answer question' in next_text: break if any(x in next_text for x in ['Reference:', 'Add revision notes', 'Save notes', 'Question navigator']): # This might have more explanation text before the stop words cont_lines = [l.strip() for l in next_text.split('\n') if l.strip()] for ln in cont_lines: if any(x in ln for x in ['Reference:', 'Next question', 'Add revision notes', 'Save notes', 'Rate this', 'Improve this', 'Question navigator', 'You\'ll receive']): break if ln and not re.match(r'^\d+%$|^\d+\(\d+/\d+\)$', ln): cont_exp += ln + ' ' next_pnum += 1 if next_pnum - pnum > 3: break full_exp = ' '.join(clean_exp) + ' ' + cont_exp mcqs_raw[key] = { 'num': qnum, 'set_size': qset, 'question': q_stem.strip(), 'topics': topics, 'explanation': full_exp.strip(), 'page': pnum } all_mcqs = list(mcqs_raw.values()) all_mcqs.sort(key=lambda x: (x['set_size'], x['num'])) print(f"Total unique MCQs: {len(all_mcqs)}") # Count by set size from collections import Counter set_counts = Counter(q['set_size'] for q in all_mcqs) print(f"MCQ sets: {dict(sorted(set_counts.items()))}") with open('/home/daytona/workspace/mcqs_final.json', 'w') as f: json.dump(all_mcqs, f, indent=2) # Show sample of each set type shown = set() for q in all_mcqs[:5]: print(f"\nQ{q['num']}/{q['set_size']} [p{q['page']}]: {q['question'][:120]}") print(f" Topics: {q['topics']}") print(f" Exp: {q['explanation'][:150]}") PYEOF
python3 << 'PYEOF' import json with open('/home/daytona/workspace/mcqs_final.json') as f: mcqs = json.load(f) # Print all topics to understand what we're dealing with from collections import Counter topic_list = [] for q in mcqs: t = q.get('topics','').strip() if t: topic_list.append(t) topic_counts = Counter(topic_list) print("All topic combinations (sorted by frequency):") for combo, cnt in sorted(topic_counts.items(), key=lambda x: -x[1]): print(f" {cnt}x: {combo}") print(f"\nTotal MCQs: {len(mcqs)}") print("\nAll explanations (first 300 chars each):") for q in mcqs: print(f"\nQ{q['num']}/{q['set_size']} [{q['topics']}]") print(f" Q: {q['question'][:100]}") print(f" E: {q['explanation'][:200]}") PYEOF
mkdir -p /home/daytona/workspace/cardiology-notes && ls /home/daytona/workspace/cardiology-notes/
Continue
ls /home/daytona/workspace/ && ls /home/daytona/workspace/cardiology-notes/ 2>/dev/null && echo "mcqs file exists: $(test -f /home/daytona/workspace/mcqs_final.json && echo yes || echo no)"
Continue