Please create a colorful handbook pdf with 10 conversation speaking practice questions based on attached file with vocabulary words list.The questions must be logical and creative and must really help my ESL B2+ proficiency students in speaking practice.
cd /tmp/workspace/attachments/c6a0601c-c438-41c6-ad40-350bad783484/ && python3 -c " import pdfplumber with pdfplumber.open('DOC-20261031-WA0000.pdf') as p: print(len(p.pages)) for pg in p.pages: print(pg.extract_text()); print('----') "
mkdir -p /tmp/workspace/esl-handbook && cat > /tmp/workspace/esl-handbook/build.py <<'EOF' from reportlab.pdfgen import canvas from reportlab.lib.pagesizes import A4 from reportlab.lib.colors import HexColor, white from reportlab.platypus import Paragraph from reportlab.lib.styles import ParagraphStyle from reportlab.pdfbase.pdfmetrics import stringWidth import math, random W, H = A4 NAVY = HexColor('#2D3A5C'); CREAM = HexColor('#FFF8EC') PAL = [HexColor(x) for x in ['#FF6B6B','#1ABC9C','#F5A623','#7D5BA6','#3D9BE9','#4CAF50','#FF8A3D','#E8509E','#00A8B5','#8E6CEF']] LIGHT = [HexColor(x) for x in ['#FFE3E3','#D9F5EF','#FFF0D1','#EBE2F5','#DCEEFC','#E1F3E2','#FFE6D5','#FCE0EE','#D3F1F3','#E9E1FC']] def st(size=10, lead=None, color=NAVY, bold=False, align=0, name='x'): return ParagraphStyle(name, fontName='Helvetica-Bold' if bold else 'Helvetica', fontSize=size, leading=lead or size*1.3, textColor=color, alignment=align) def para(c, text, x, ytop, w, style): p = Paragraph(text, style); _, h = p.wrap(w, 1000) p.drawOn(c, x, ytop-h); return h def pheight(text, w, style): return Paragraph(text, style).wrap(w, 1000)[1] def confetti(c, x0, y0, x1, y1, n=40, seed=1): random.seed(seed) for _ in range(n): col = random.choice(PAL); c.setFillColor(col) x = random.uniform(x0, x1); y = random.uniform(y0, y1); r = random.uniform(3, 9) if random.random() < .5: c.circle(x, y, r, stroke=0, fill=1) else: c.saveState(); c.translate(x, y); c.rotate(random.uniform(0, 90)); c.rect(-r, -r/2, 2*r, r, stroke=0, fill=1); c.restoreState() def header(c, title, sub, col): c.setFillColor(col); c.rect(0, H-80, W, 80, stroke=0, fill=1) c.setFillColor(HexColor('#FFFFFF')); c.setFillAlpha(.18) c.circle(W-40, H-20, 60, stroke=0, fill=1); c.circle(W-120, H-85, 28, stroke=0, fill=1); c.setFillAlpha(1) c.setFillColor(white); c.setFont('Helvetica-Bold', 24); c.drawString(36, H-44, title) c.setFont('Helvetica', 11); c.drawString(36, H-64, sub) def footer(c, n): c.setFillColor(NAVY); c.setFont('Helvetica', 8.5) c.drawString(36, 22, 'Talk It Out! | B2+ Speaking Handbook') c.drawRightString(W-36, 22, 'Page %d' % n) for i, col in enumerate(PAL): c.setFillColor(col); c.rect(36 + i*(W-72)/10, 36, (W-72)/10, 3, stroke=0, fill=1) def chip(c, x, y, text, col, size=9): w = stringWidth(text, 'Helvetica-Bold', size) + 16 c.setFillColor(col); c.roundRect(x, y, w, 17, 8.5, stroke=0, fill=1) c.setFillColor(white); c.setFont('Helvetica-Bold', size); c.drawString(x+8, y+5, text) return w QS = [ dict(topic='The Age of Energy', words=['spry','sedate'], type='Opinion + Imagination', q='Imagine you could design your seventies. Would you live as a <b>spry</b> adventurer who is always on the move, or enjoy a calm, <b>sedate</b> routine? Describe a typical week in the life you would choose, and explain why.', fu=['Do you know an older person who is surprisingly <b>spry</b>? How has this person changed your view of ageing?', 'Is a <b>sedate</b> life a well-earned reward after years of work, or a missed opportunity?', 'What should families and cities do to help active older people stay independent?'], up='Persuade your partner that your choice is the wiser one. Use a concession first: "Admittedly, ... but ..."'), dict(topic='Loyalty and Forgiveness', words=['true blue','magnanimous'], type='Personal Experience + Ethics', q='Your <b>true blue</b> best friend has accidentally hurt you badly. Is being <b>magnanimous</b> always the right response, or are there situations where you should refuse to forgive? Where would you draw the line?', fu=['What makes someone a <b>true blue</b> friend or colleague, rather than just a pleasant acquaintance?', 'Describe a time when someone was <b>magnanimous</b> towards you, or when you were towards someone else.', 'Can a person be too forgiving? Is a <b>magnanimous</b> person sometimes taken advantage of?'], up='Tell a one-minute story, real or invented, about a rivalry that ended with a <b>magnanimous</b> gesture.'), dict(topic='Moments That Vanish', words=['fleeting','singular'], type='Storytelling', q='Some of our most powerful memories last only a few seconds. Describe a <b>fleeting</b> moment in your life that you can still picture clearly, and explain what made the experience so <b>singular</b>.', fu=['Why do <b>fleeting</b> feelings, such as the excitement of a new purchase, disappear so quickly?', 'Do photos and social media help us keep <b>fleeting</b> moments, or do they stop us from living in them?', 'If you could stretch one <b>fleeting</b> moment into a whole day, which would you choose?'], up='Describe your moment so vividly that your partner can guess where you were and how you felt.'), dict(topic='A Taste of Home', words=['quintessential','tart'], type='Culture + Description', q='A foreign friend has only one evening in your country. Design a menu of the most <b>quintessential</b> dishes and drinks they must try. Include at least one with a <b>tart</b> or sharp flavour, and explain how to eat or drink it properly.', fu=['Which food do foreigners most often misunderstand about your culture?', 'Is a taste for <b>tart</b> or bitter flavours something we learn? Which food did you hate as a child but love now?', 'Is a country\'s <b>quintessential</b> dish still authentic when restaurants change it for tourists?'], up='"Sell" your menu in 60 seconds, as if you were the owner of the restaurant.'), dict(topic='Weather Extremes', words=['gelid','torrid'], type='Preference + Figurative Language', q='You must live for a year in a place with either <b>gelid</b> winters or <b>torrid</b> summers. Which would you choose, and how would it affect your daily routine, your health and your mood?', fu=['Describe the most extreme weather you have ever experienced. How did you cope?', 'Summers are becoming more <b>torrid</b> in many regions. How might this change the way we build cities and plan holidays?', 'We say a <b>gelid</b> stare or a <b>torrid</b> romance. Why do so many languages use temperature to describe emotions?'], up='Make two sentences about relationships, one with <b>gelid</b> and one with <b>torrid</b>, used figuratively.'), dict(topic='Reading People', words=['perceptive','sagacious'], type='Discussion + Advice', q='Think of the most <b>perceptive</b> person you know, someone who can tell you are upset before you say a word. Is this a natural talent or a skill that can be learned? And is a <b>perceptive</b> person automatically <b>sagacious</b>?', fu=['What is the most <b>sagacious</b> advice you have ever received? Did you follow it?', 'Whom would you ask for advice about money, career and love? Why those people?', 'Could an AI ever be truly <b>perceptive</b> or <b>sagacious</b>? What would it be missing?'], up='Your partner describes a problem. Give <b>sagacious</b> advice in three steps, using "If I were you, I would..."'), dict(topic='Complaints and Excuses', words=['irate','flimsy'], type='Role-play', q='<b>Role-play.</b> Student A is an <b>irate</b> customer whose online order is three days late. Student B works in customer service and begins with a <b>flimsy</b> excuse. After two minutes, switch roles. How does the conversation change when the agent shows real empathy?', fu=['What is the most <b>flimsy</b> excuse you have ever heard, or used?', 'What do you do to calm down when you feel <b>irate</b>?', 'Is it ever acceptable to lose your temper with someone who works in customer service?'], up='Solve the problem in under two minutes while both of you stay polite and professional.'), dict(topic='Style and Standards', words=['punctilious','unadorned'], type='Preference + Debate', q='Would you rather work for a <b>punctilious</b> boss who checks every detail or a relaxed one who trusts you completely? Then describe your ideal <b>unadorned</b> workspace. What do your choices say about your personality?', fu=['When is being <b>punctilious</b> essential, for example in surgery or aviation, and when does it become annoying?', 'Why have <b>unadorned</b>, minimalist styles become so popular? Is simplicity always better?', 'Is your own room <b>unadorned</b> or full of personal things? What would a stranger learn from it?'], up='Mini-debate: "Perfectionism helps a career more than it hurts it." One minute for each side.'), dict(topic='Money, Charity and Scandal', words=['munificent','sordid'], type='Ethical Dilemma', q='A <b>munificent</b> billionaire donates half of their fortune to build new hospitals. Then a journalist reveals <b>sordid</b> details about how the money was made. Should the city accept the donation? Does the source of money matter if it saves lives?', fu=['Should rich people be expected to be <b>munificent</b>, or is giving a personal choice?', 'Why are people so fascinated by <b>sordid</b> scandals? Does the media have a responsibility here?', 'How do you decide whether a charity deserves your trust and your money?'], up='Panel discussion with four roles: donor, journalist, hospital director, local citizen. Two minutes each.'), dict(topic='Boring or Brilliant?', words=['soporific','jejune'], type='Creative Problem-Solving', q='You are hired to rescue a TV series that critics call <b>jejune</b> and a lecture series that students find <b>soporific</b>. What exactly is going wrong, and what three changes would you make to keep the audience awake and interested?', fu=['Has short online content made us less patient, or has it made creators better at their job?', 'Does anything <b>soporific</b>, such as music, tea or a podcast, help you fall asleep?', 'Is a simple, even <b>jejune</b>, story always bad? Think about children\'s books and fairy tales.'], up='Give a 60-second pitch for your "rescued" show, as if talking to a TV director.'), ] VOC = [('Tart','adj','sharp and sour; (of words) sharp and cutting'),('Spry','adj','lively and active, especially an older person'), ('Fleeting','adj','lasting a very short time'),('Sedate','adj','calm, quiet, unhurried'), ('True blue','adj phr','completely loyal and reliable'),('Unadorned','adj','plain and simple; without decoration'), ('Singular','adj','very strange or unusual; exceptional'),('Flimsy','adj','thin and weak; (of an excuse) unconvincing'), ('Magnanimous','adj','generous and forgiving, especially to a rival'),('Perceptive','adj','quick to notice feelings and hidden details'), ('Sagacious','adj','wise, with good judgement'),('Quintessential','adj','the most typical example of something'), ('Sordid','adj','dirty; morally low or shameful'),('Soporific','adj','making you feel sleepy'), ('Punctilious','adj','very careful about details and rules'),('Munificent','adj','very generous; giving lavishly'), ('Irate','adj','extremely angry'),('Gelid','adj','extremely cold; icy'), ('Torrid','adj','very hot and dry; passionate'),('Jejune','adj','naive and simplistic; dull')] PRON = ['tahrt','sprye','FLEE-ting','sih-DAYT','TROO bloo','un-uh-DORND','SING-gyuh-ler','FLIM-zee','mag-NAN-ih-mus','per-SEP-tiv', 'suh-GAY-shus','kwin-tih-SEN-shul','SOR-did','sop-uh-RIF-ik','punk-TIL-ee-us','myoo-NIF-ih-sunt','eye-RAYT','JEL-id','TOR-id','jih-JOON'] c = canvas.Canvas('/tmp/workspace/esl-handbook/Talk_It_Out_B2plus_Speaking_Handbook.pdf', pagesize=A4) c.setTitle('Talk It Out! B2+ Speaking Handbook'); c.setAuthor('Orris') # ---- COVER c.setFillColor(NAVY); c.rect(0, 0, W, H, stroke=0, fill=1) confetti(c, 0, 0, W, H, 90, 7) c.setFillColor(CREAM); c.roundRect(48, 190, W-96, 470, 28, stroke=0, fill=1) for i, col in enumerate(PAL[:6]): c.setFillColor(col); c.circle(90 + i*83, 625, 14, stroke=0, fill=1) c.setFillColor(PAL[0]); c.setFont('Helvetica-Bold', 66); c.drawCentredString(W/2, 530, 'Talk It Out!') c.setFillColor(NAVY); c.setFont('Helvetica-Bold', 22); c.drawCentredString(W/2, 487, '10 Conversation Challenges') c.setFont('Helvetica', 15); c.drawCentredString(W/2, 462, 'for confident, natural speaking') c.setFillColor(PAL[1]); c.roundRect(W/2-120, 395, 240, 40, 20, stroke=0, fill=1) c.setFillColor(white); c.setFont('Helvetica-Bold', 15); c.drawCentredString(W/2, 409, 'ESL | B2+ to C1 | Speaking') c.setFillColor(NAVY); c.setFont('Helvetica', 12.5) c.drawCentredString(W/2, 350, 'Built around 20 advanced vocabulary words') c.drawCentredString(W/2, 330, 'tart * spry * fleeting * sedate * gelid * torrid * and more') x = 110 for t, col in [('Pairs', PAL[2]), ('Role-plays', PAL[3]), ('Debates', PAL[4]), ('Stories', PAL[6])]: x += chip(c, x, 260, t, col, 11) + 12 c.setFont('Helvetica-Oblique', 11); c.setFillColor(NAVY) c.drawCentredString(W/2, 225, 'Use the words. Share your ideas. Disagree politely.') c.showPage() # ---- HOW TO USE pg = 2 header(c, 'How to Use This Handbook', 'Get the most from every conversation', PAL[1]) y = H-110 steps = [('1','Pair up','Work with a partner or in a group of three. Choose a question card.',PAL[0]), ('2','Prepare for 1 minute','Read the target words on the card. Think of at least one idea or example for each.',PAL[2]), ('3','Speak for 2 to 3 minutes','Answer the main question, then use the follow-up questions to keep talking. Ask each other extra "Why?" and "Can you give an example?"',PAL[4]), ('4','Level up','Try the challenge at the bottom of the card. It makes you use the words in a more demanding way.',PAL[3]), ('5','Reflect','Use the checklist on the last page to give each other kind, specific feedback.',PAL[5])] for n, t, d, col in steps: c.setFillColor(LIGHT[PAL.index(col)]); c.roundRect(36, y-62, W-72, 62, 14, stroke=0, fill=1) c.setFillColor(col); c.circle(70, y-31, 20, stroke=0, fill=1) c.setFillColor(white); c.setFont('Helvetica-Bold', 20); c.drawCentredString(70, y-38, n) c.setFillColor(NAVY); c.setFont('Helvetica-Bold', 13); c.drawString(104, y-24, t) para(c, d, 104, y-30, W-170, st(10, 13)) y -= 74 y -= 8 c.setFillColor(NAVY); c.setFont('Helvetica-Bold', 16); c.drawString(36, y-6, 'Speaking Toolkit: phrases to sound natural') y -= 20 tk = [('Giving an opinion', 'From my point of view... / As far as I am concerned... / I would argue that...', PAL[0]), ('Conceding a point', 'Admittedly... / That is a fair point, but... / I see where you are coming from, however...', PAL[1]), ('Giving examples', 'A case in point is... / Take my cousin, for instance... / A good example would be...', PAL[2]), ('Buying thinking time', 'That is an interesting question... / Let me think about that for a second... / How can I put it?', PAL[3]), ('Disagreeing politely', 'I am not entirely convinced... / I would take a slightly different view... / I am afraid I see it differently.', PAL[4]), ('Asking for more', 'Could you elaborate on that? / What makes you say that? / How would that work in practice?', PAL[5])] bw = (W-72-14)/2 for i, (t, d, col) in enumerate(tk): cx = 36 + (i%2)*(bw+14); cy = y - (i//2)*88 c.setFillColor(LIGHT[PAL.index(col)]); c.roundRect(cx, cy-80, bw, 80, 12, stroke=0, fill=1) c.setFillColor(col); c.roundRect(cx, cy-24, bw, 24, 12, stroke=0, fill=1); c.rect(cx, cy-24, bw, 10, stroke=0, fill=1) c.setFillColor(white); c.setFont('Helvetica-Bold', 11); c.drawString(cx+12, cy-17, t) para(c, d, cx+12, cy-32, bw-24, st(9.5, 12.5)) footer(c, pg); c.showPage() # ---- WORD BANK pg += 1 header(c, 'Word Bank', 'Your 20 target words. Can you use all of them today?', PAL[3]) colw = (W-72-14)/2; rowh = 62; y0 = H-96 for i, (w, pos, m) in enumerate(VOC): col_i = i // 10; r = i % 10 x = 36 + col_i*(colw+14); y = y0 - r*(rowh+4) col = PAL[i % 10] c.setFillColor(LIGHT[i % 10]); c.roundRect(x, y-rowh, colw, rowh, 10, stroke=0, fill=1) c.setFillColor(col); c.roundRect(x, y-rowh, 8, rowh, 4, stroke=0, fill=1) c.setFillColor(NAVY); c.setFont('Helvetica-Bold', 13); c.drawString(x+18, y-20, '%d. %s' % (i+1, w)) wd = stringWidth('%d. %s' % (i+1, w), 'Helvetica-Bold', 13) c.setFont('Helvetica-Oblique', 8.5); c.setFillColor(col); c.drawString(x+18+wd+8, y-20, '(%s)' % pos) c.setFillColor(HexColor('#555B6E')); c.setFont('Helvetica', 8.5); c.drawString(x+18, y-33, '[%s]' % PRON[i]) para(c, m, x+18, y-38, colw-30, st(9, 11)) footer(c, pg); c.showPage() # ---- QUESTION PAGES SLOT_TOP = H-100; SLOT_H = 340 def card(c, x, ytop, w, h, n, q): col = PAL[n-1]; lt = LIGHT[n-1] c.setFillColor(lt); c.roundRect(x, ytop-h, w, h, 18, stroke=0, fill=1) c.setStrokeColor(col); c.setLineWidth(2); c.roundRect(x, ytop-h, w, h, 18, stroke=1, fill=0) c.setFillColor(col); c.circle(x+34, ytop-34, 22, stroke=0, fill=1) c.setFillColor(white); c.setFont('Helvetica-Bold', 22); c.drawCentredString(x+34, ytop-42, str(n)) c.setFillColor(NAVY); c.setFont('Helvetica-Bold', 16.5); c.drawString(x+68, ytop-30, q['topic']) c.setFillColor(col); c.setFont('Helvetica-Bold', 9); c.drawString(x+68, ytop-45, q['type'].upper()) # word chips cx = x + w - 14 for wd in reversed(q['words']): cw = stringWidth(wd, 'Helvetica-Bold', 10) + 18; cx -= cw c.setFillColor(col); c.roundRect(cx, ytop-38, cw, 20, 10, stroke=0, fill=1) c.setFillColor(white); c.setFont('Helvetica-Bold', 10); c.drawString(cx+9, ytop-31.5, wd); cx -= 6 y = ytop - 62 # main question box qs = st(11.5, 15.5) qh = pheight(q['q'], w-48, qs) c.setFillColor(white); c.roundRect(x+12, y-qh-16, w-24, qh+16, 10, stroke=0, fill=1) para(c, q['q'], x+24, y-8, w-48, qs) y -= qh + 28 c.setFillColor(col); c.setFont('Helvetica-Bold', 10.5); c.drawString(x+14, y-4, 'KEEP THE CONVERSATION GOING') y -= 12 fs = st(10, 13) for f in q['fu']: c.setFillColor(col); c.circle(x+20, y-9, 3, stroke=0, fill=1) hh = pheight(f, w-56, fs); para(c, f, x+32, y-3, w-56, fs); y -= hh + 5 y -= 4 us = st(9.8, 12.8) uh = pheight('<b>LEVEL UP:</b> ' + q['up'], w-70, us) c.setFillColor(NAVY); c.roundRect(x+12, ytop-h+10, w-24, uh+14, 10, stroke=0, fill=1) ust = ParagraphStyle('u', fontName='Helvetica', fontSize=9.8, leading=12.8, textColor=white) para(c, '<b><font color="#FFC857">LEVEL UP:</font></b> ' + q['up'], x+42, ytop-h+10+uh+7, w-70, ust) c.setFillColor(HexColor('#FFC857')); c.setFont('Helvetica-Bold', 14); c.drawString(x+22, ytop-h+10+uh/2+2, '*') return y - (ytop-h+10+uh+14) # free space (should be >= 0) for k in range(5): pg += 1 header(c, 'Speaking Challenges', 'Questions %d and %d' % (2*k+1, 2*k+2), PAL[(2*k)%10]) for j in range(2): n = 2*k+j+1 top = SLOT_TOP - j*(SLOT_H+14) free = card(c, 36, top, W-72, SLOT_H, n, QS[n-1]) print(n, 'free space', round(free)) footer(c, pg); c.showPage() # ---- CHECKLIST pg += 1 header(c, 'Reflect and Improve', 'Peer feedback and self-check', PAL[5]) y = H-110 c.setFillColor(NAVY); c.setFont('Helvetica-Bold', 16); c.drawString(36, y, 'Speaking Checklist') y -= 14 items = [('Vocabulary','I used at least 3 target words correctly and naturally.',PAL[0]), ('Range','I used a mix of simple and complex sentences (although, whereas, which...).',PAL[2]), ('Fluency','I kept going without long pauses. I used fillers like "Well, let me think...".',PAL[1]), ('Interaction','I asked my partner a follow-up question and reacted to their ideas.',PAL[4]), ('Examples','I supported my opinions with a personal example or a reason.',PAL[3]), ('Pronunciation','I stressed the target words correctly (check the Word Bank).',PAL[6])] for t, d, col in items: c.setFillColor(LIGHT[PAL.index(col)]); c.roundRect(36, y-40, W-72, 40, 10, stroke=0, fill=1) c.setStrokeColor(col); c.setLineWidth(2); c.roundRect(48, y-28, 16, 16, 3, stroke=1, fill=0) c.setFillColor(NAVY); c.setFont('Helvetica-Bold', 11); c.drawString(76, y-17, t) c.setFont('Helvetica', 9.5); c.drawString(160, y-17, d) if stringWidth(d,'Helvetica',9.5) < W-72-140 else para(c, d, 160, y-11, W-72-130, st(9,11)) y -= 48 y -= 14 c.setFillColor(NAVY); c.setFont('Helvetica-Bold', 16); c.drawString(36, y, 'Word Tracker') y -= 8 c.setFont('Helvetica', 10); c.drawString(36, y-12, 'Tick each word when you have used it in a real conversation.') y -= 28 for i, (w, pos, m) in enumerate(VOC): cx = 36 + (i % 4)*((W-72)/4); cy = y - (i//4)*28 col = PAL[i % 10] c.setFillColor(LIGHT[i % 10]); c.roundRect(cx, cy-22, (W-72)/4-8, 22, 8, stroke=0, fill=1) c.setStrokeColor(col); c.setLineWidth(1.6); c.roundRect(cx+7, cy-17, 12, 12, 2, stroke=1, fill=0) c.setFillColor(NAVY); c.setFont('Helvetica-Bold', 9.5); c.drawString(cx+26, cy-15, w) y -= 5*28 + 16 c.setFillColor(NAVY); c.setFont('Helvetica-Bold', 16); c.drawString(36, y, 'Teacher Tips') y -= 8 tips = ['Pre-teach pronunciation and word stress before speaking starts. Several words (sagacious, punctilious, munificent) are hard to say.', 'Ask students to choose one idea from the question and add a reason and an example (the "Reason + Example" rule).', 'Collect two or three sentences with the target words during the activity. Write them on the board for delayed error correction.', 'Rotate partners after each question so students meet new ideas and viewpoints.'] for t in tips: c.setFillColor(PAL[2]); c.circle(44, y-10, 3.5, stroke=0, fill=1) h = para(c, t, 56, y-3, W-100, st(10, 13)); y -= h + 6 footer(c, pg); c.showPage() c.save() EOF cd /tmp/workspace/esl-handbook && python3 build.py
cd /tmp/workspace/esl-handbook && python3 -c " import pdfplumber with pdfplumber.open('Talk_It_Out_B2plus_Speaking_Handbook.pdf') as p: print(len(p.pages)) for i in [0,1,2,3,9]: p.pages[i].to_image(resolution=60).save(f'p{i+1}.png') "; ls
cd /tmp/workspace/esl-handbook && python3 -c " import pdfplumber with pdfplumber.open('Talk_It_Out_B2plus_Speaking_Handbook.pdf') as p: for i in [0,1,2,3,8]: p.pages[i].to_image(resolution=70).save(f'p{i+1}.png') "; ls
cd /tmp/workspace/esl-handbook && python3 - <<'EOF' s = open('build.py').read() s = s.replace("qs = st(11.5, 15.5)", "qs = st(12.5, 17)") s = s.replace("fs = st(10, 13)", "fs = st(11, 14.5)") s = s.replace("hh = pheight(f, w-56, fs); para(c, f, x+32, y-3, w-56, fs); y -= hh + 5", "hh = pheight(f, w-56, fs); para(c, f, x+32, y-3, w-56, fs); y -= hh + 6") s = s.replace("c.circle(x+20, y-9, 3, stroke=0, fill=1)", "c.circle(x+20, y-10, 3, stroke=0, fill=1)") # tip box s = s.replace(" y -= 4\n us = st(9.8, 12.8)", """ y -= 2 tip = TIPS[n-1] ts = ParagraphStyle('t', fontName='Helvetica-Oblique', fontSize=10, leading=13, textColor=NAVY) th = pheight('<b>Useful language:</b> ' + tip, w-48, ts) c.setFillColor(white); c.setStrokeColor(col); c.setLineWidth(1); c.setDash(3,3) c.roundRect(x+12, y-th-12, w-24, th+12, 8, stroke=1, fill=1); c.setDash() para(c, '<b><font color="%s">Useful language:</font></b> ' % col.hexval().replace('0x','#') + tip, x+22, y-6, w-44, ts) y -= th + 14 us = st(9.8, 12.8)""") s = s.replace("QS = [", """TIPS = [ 'I would rather... than... / What appeals to me about... is... / Admittedly, ... but on the other hand...', 'It depends on whether... / I would give them the benefit of the doubt unless... / There is a limit to...', 'It all happened so quickly that... / What stands out in my memory is... / Looking back, I realise that...', 'It is best known for... / You have to try... / It might sound odd, but...', 'If I had to choose, I would go for... / I would cope better with... / It is hard to say which is worse, but...', 'Some people have a knack for... / I tend to rely on... / It takes experience to...', 'I understand how frustrating this must be. / Let me see what I can do. / I do apologise for the inconvenience.', 'I am the kind of person who... / It comes down to... / Attention to detail matters when...', 'On the one hand... on the other hand... / The ends do not justify the means. / It is a question of principle.', 'The main problem is... / What I would do is... / It would hold people\\'s attention if...', ] QS = [""",1) s = s.replace("drawCentredString(W/2, 330, 'tart * spry * fleeting * sedate * gelid * torrid * and more')","drawCentredString(W/2, 330, 'tart | spry | fleeting | sedate | gelid | torrid | and more')") s = s.replace("c.drawString(x+22, ytop-h+10+uh/2+2, '*')","c.drawString(x+22, ytop-h+10+uh/2-2, '>')") s = s.replace("chip(c, x, 260, t, col, 11)","chip(c, x, 270, t, col, 11)") open('build.py','w').write(s) EOF python3 build.py && python3 -c " import pdfplumber with pdfplumber.open('Talk_It_Out_B2plus_Speaking_Handbook.pdf') as p: for i in [3,6,7,8]: p.pages[i].to_image(resolution=70).save(f'p{i+1}.png') "
Talk It Out B2plus Speaking Handbook
PDF Document · PDF
| # | Topic | Words | Format |
|---|---|---|---|
| 1 | The Age of Energy | spry, sedate | Imagine and compare |
| 2 | Loyalty and Forgiveness | true blue, magnanimous | Ethics from personal experience |
| 3 | Moments That Vanish | fleeting, singular | Storytelling |
| 4 | A Taste of Home | quintessential, tart | Culture, plus selling a menu |
| 5 | Weather Extremes | gelid, torrid | Preference, plus figurative use |
| 6 | Reading People | perceptive, sagacious | Discussion and giving advice |
| 7 | Complaints and Excuses | irate, flimsy | Role-play with a role switch |
| 8 | Style and Standards | punctilious, unadorned | Preference and mini-debate |
| 9 | Money, Charity and Scandal | munificent, sordid | Ethical dilemma and panel |
| 10 | Boring or Brilliant? | soporific, jejune | Creative problem-solving and pitch |