Summary to each graphs in pdf
cd /home/daytona/workspace/attachments/44ad74e1-8c7c-4abb-b78a-dfdd2bc518af/ && python3 -c " import pdfplumber with pdfplumber.open('Graphs_with_Principle_and_4Points.pdf') as pdf: print(f'Total pages: {len(pdf.pages)}') for i, page in enumerate(pdf.pages): print(f'\n========== PAGE {i+1} ==========') text = page.extract_text() print(text if text else '[No text extracted]') "
Add this summary to pdf
python3 << 'EOF' import io from pypdf import PdfReader, PdfWriter from reportlab.lib.pagesizes import A4 from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle from reportlab.lib.units import cm from reportlab.lib import colors from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer from reportlab.lib.enums import TA_LEFT, TA_CENTER # All summaries per page (14 graphs) summaries = [ { "title": "Graph 1 - Single Muscle Twitch", "principle": "A muscle responds with a single twitch to one effective stimulus.", "points": [ "The graph shows three phases: a short latent period before contraction begins, a contraction phase where the muscle shortens, and a relaxation phase where it returns to resting length.", "The muscle reaches a peak contraction height before fully relaxing back to baseline.", "Reaches maximum contraction then relaxes.", "Has latent, contraction and relaxation phases." ] }, { "title": "Graph 2 - Effect of Temperature on Muscle", "principle": "Temperature alters the rate of biochemical reactions in muscle.", "points": [ "At higher temperatures, enzyme activity increases, speeding up contraction and producing a faster, sharper twitch.", "At lower temperatures, enzyme activity slows, reducing both the force and speed of contraction and prolonging the twitch duration.", "High temperature speeds contraction.", "Low temperature prolongs contraction." ] }, { "title": "Graph 3 - Graded Response / Recruitment", "principle": "Greater stimulus strength recruits more muscle fibres until a maximal response is reached.", "points": [ "A subthreshold stimulus produces no response.", "As stimulus intensity increases, more fibres are recruited and contraction force rises.", "At the maximal stimulus, all fibres are recruited and maximum contraction is achieved.", "A supramaximal stimulus produces no additional increase in contraction." ] }, { "title": "Graph 4 - Summation and Refractory Period", "principle": "The muscle's response to a second stimulus depends on the timing of that stimulus.", "points": [ "A second stimulus delivered during the refractory period produces no response.", "A second stimulus delivered after the refractory period causes summation - the second contraction adds onto the first, producing a greater overall force.", "No summation occurs during the refractory period.", "Later stimulus causes summation." ] }, { "title": "Graph 5 - Tetanus (Fused Contraction)", "principle": "Rapid, repetitive stimulation causes fused contraction (tetanus).", "points": [ "At moderate repetition rates, the muscle shows incomplete tetanus with partial relaxation between contractions.", "At high repetition rates, contractions fuse completely into complete tetanus - a sustained, smooth, maximal contraction with no relaxation intervals.", "Rapid stimuli produce tetanus.", "Complete tetanus gives sustained contraction." ] }, { "title": "Graph 6 - Neuromuscular Fatigue", "principle": "Fatigue occurs mainly at the neuromuscular junction in the frog muscle preparation.", "points": [ "With repeated stimulation, the force of contraction progressively decreases as the neuromuscular junction becomes fatigued.", "Direct muscle stimulation still produces contraction initially, showing the muscle itself is not the primary site of fatigue.", "After a rest period, contractile force is restored, confirming that fatigue is reversible.", "Fatigue is reversible after rest." ] }, { "title": "Graph 7 - Effect of Load on Muscle Contraction", "principle": "The load placed on a muscle influences the extent and type of contraction.", "points": [ "A free (no) load allows the greatest degree of shortening.", "As load increases, the height of contraction decreases.", "With an after-load, the muscle must first lift the load before shortening begins, introducing a delay in the contraction curve.", "Heavy load reduces shortening." ] }, { "title": "Graph 8 - Nerve Conduction Velocity", "principle": "Nerve impulse velocity is calculated from the distance between two stimulation points and the difference in conduction time (latency).", "points": [ "Stimulating at a farther point from the recording site increases the latency of the response.", "Velocity = Distance / Time, expressed in m/s.", "Myelinated nerves conduct much faster than unmyelinated nerves.", "Myelination increases conduction velocity." ] }, { "title": "Graph 9 - Normal Cardiac Rhythm (Cardiogram)", "principle": "Heart contractions occur rhythmically due to spontaneous pacemaker activity.", "points": [ "The cardiogram shows a series of regular, uniform beats at a consistent rate and amplitude.", "The graph is used to assess heart rate and rhythm and serves as a baseline for comparison with experimental interventions.", "Shows regular heart beats.", "Assesses heart rate and rhythm." ] }, { "title": "Graph 10 - Effect of Temperature on the Heart", "principle": "Temperature changes alter cardiac pacemaker activity.", "points": [ "Warming the heart increases both the rate and force of contraction.", "Cooling the heart slows the pacemaker, decreasing heart rate, and may slow or arrest the heart entirely at very low temperatures.", "Warm increases heart rate.", "Cold decreases heart rate." ] }, { "title": "Graph 11 - Stannius Ligatures", "principle": "Stannius ligatures demonstrate the pacemaker hierarchy of the heart.", "points": [ "The 1st ligature (placed between the sinus venosus and atria) blocks impulse conduction, stopping ventricular beats.", "The 2nd ligature (placed between the atria and ventricle) reveals the ventricle's own automaticity, restoring slow, independent ventricular beats.", "This confirms the SA node > AV node > ventricle pacemaker hierarchy.", "2nd ligature restores slow ventricular beats." ] }, { "title": "Graph 12 - All-or-None Law, Extrasystole, and Staircase", "principle": "Cardiac muscle obeys the all-or-none law and has a long refractory period.", "points": [ "Each cardiac contraction is either full or absent (all-or-none law).", "A premature stimulus during the relative refractory period produces an extrasystole (extra beat), followed by a compensatory pause.", "The staircase (Treppe) phenomenon shows that with repeated stimuli, successive contractions gradually increase in force.", "Extrasystole is followed by a compensatory pause." ] }, { "title": "Graph 13 - Vagal Stimulation", "principle": "The vagus nerve inhibits the heart by releasing acetylcholine at muscarinic receptors.", "points": [ "Vagal stimulation slows or arrests the heart.", "With strong or prolonged vagal stimulation, the heart may escape inhibition (vagal escape) and resume beating spontaneously.", "Decreases heart rate.", "Strong stimulation may arrest the heart temporarily." ] }, { "title": "Graph 14 - Drug Effects on the Heart (Adrenaline & Acetylcholine)", "principle": "Drugs modify heart rate and force by acting on specific cardiac receptors.", "points": [ "Adrenaline (acting on beta-adrenergic receptors) increases both the rate and force of contraction - a positive chronotropic and inotropic effect.", "Acetylcholine (acting on muscarinic receptors) decreases heart rate - a negative chronotropic effect.", "Adrenaline increases rate and force.", "Acetylcholine decreases heart rate." ] }, ] def make_summary_page(summary): """Generate a single summary PDF page as bytes.""" buf = io.BytesIO() doc = SimpleDocTemplate( buf, pagesize=A4, leftMargin=2*cm, rightMargin=2*cm, topMargin=2*cm, bottomMargin=2*cm ) styles = getSampleStyleSheet() title_style = ParagraphStyle( 'TitleStyle', parent=styles['Heading1'], fontSize=15, textColor=colors.HexColor('#1a3a5c'), spaceAfter=8, leading=20, alignment=TA_CENTER ) label_style = ParagraphStyle( 'LabelStyle', parent=styles['Normal'], fontSize=10, textColor=colors.HexColor('#7b2d00'), spaceBefore=10, spaceAfter=3, fontName='Helvetica-Bold' ) principle_style = ParagraphStyle( 'PrincipleStyle', parent=styles['Normal'], fontSize=11, textColor=colors.HexColor('#1a3a5c'), leading=16, spaceAfter=10, backColor=colors.HexColor('#eaf2fb'), borderPad=6, fontName='Helvetica-Oblique' ) bullet_style = ParagraphStyle( 'BulletStyle', parent=styles['Normal'], fontSize=10.5, leading=16, leftIndent=14, spaceAfter=5, textColor=colors.HexColor('#222222'), bulletIndent=0, bulletFontName='Helvetica', bulletFontSize=12, bulletColor=colors.HexColor('#1a7abf') ) divider_style = ParagraphStyle( 'DividerStyle', parent=styles['Normal'], fontSize=7, textColor=colors.HexColor('#aaaaaa'), spaceAfter=6, alignment=TA_CENTER ) story = [] story.append(Paragraph(summary["title"], title_style)) story.append(Paragraph("_" * 80, divider_style)) story.append(Paragraph("Principle:", label_style)) story.append(Paragraph(summary["principle"], principle_style)) story.append(Paragraph("Key Points:", label_style)) for pt in summary["points"]: story.append(Paragraph(f'<bullet>\u2022</bullet> {pt}', bullet_style)) doc.build(story) buf.seek(0) return buf # Build the final merged PDF input_path = "/home/daytona/workspace/attachments/44ad74e1-8c7c-4abb-b78a-dfdd2bc518af/Graphs_with_Principle_and_4Points.pdf" output_path = "/home/daytona/workspace/Graphs_with_Summaries.pdf" reader = PdfReader(input_path) writer = PdfWriter() for i, page in enumerate(reader.pages): # Add original graph page writer.add_page(page) # Add summary page after it summary_buf = make_summary_page(summaries[i]) summary_reader = PdfReader(summary_buf) writer.add_page(summary_reader.pages[0]) with open(output_path, "wb") as f: writer.write(f) print(f"Done! Output: {output_path}") print(f"Total pages in output: {len(writer.pages)}") EOF
Graphs with Summaries
PDF Document · PDF