Skip to content
v0.1.4latest release159 skills5 categories7 sub-categories303 tested scripts468 reference docsContact us
scripts/ielts_gap.py
#!/usr/bin/env python3
"""Estimate the study needed to close an IELTS band gap, from overall or per-skill scores.

Overall band = mean of the four skills, rounded the IELTS way (.25 rounds up to .5, .75 rounds up to the next
band). Hours use a common rule of thumb of about 200 guided hours per band (range 150-250), weighted up for
gains above band 7. This is a planning estimate, not a promise: progress varies with exposure, intensity,
motivation and the gap between the weakest skill and the target.

Usage:
    python ielts_gap.py --current 5.5 --target 6.5 --hours-per-week 20
    python ielts_gap.py --skills L6 R6.5 W5 S5.5 --target 6.5 --min-skill 6 --weeks 10 --hours-per-week 20

Exit codes: 0 estimate fits the time available (or no time given), 1 not enough time, 2 bad arguments.
"""

import argparse
import math
import re
import sys

CEFR = [(8.5, "C2"), (7.0, "C1"), (5.5, "B2"), (4.0, "B1"), (0, "below B1")]  # IELTS published alignment (approx.)


def overall(scores):
    return math.floor(sum(scores) / len(scores) * 2 + 0.5) / 2


def hours(cur, tgt):
    h, b = 0.0, cur
    while b < tgt:
        step = min(0.5, tgt - b)
        h += step * 2 * (100 if b < 7 else 130)  # per half band; higher bands take longer
        b += step
    return h


def cefr(b):
    return next(level for cut, level in CEFR if b >= cut)


def main():
    ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
    ap.add_argument("--current", type=float)
    ap.add_argument("--skills", nargs=4, help="L R W S scores like L6 R6.5 W5 S5.5")
    ap.add_argument("--target", type=float, required=True)
    ap.add_argument("--min-skill", type=float, help="minimum required in every skill (e.g. 6.0)")
    ap.add_argument("--hours-per-week", type=float)
    ap.add_argument("--weeks", type=int, help="weeks until the test or course start")
    a = ap.parse_args()
    skills = {}
    if a.skills:
        for s in a.skills:
            m = re.fullmatch(r"([LRWS])(\d(?:\.[05])?)", s.upper())
            if not m:
                print(f"error: skill score '{s}' should look like W5.5", file=sys.stderr)
                return 2
            skills[m.group(1)] = float(m.group(2))
        if len(skills) != 4:
            print("error: give L, R, W and S once each", file=sys.stderr)
            return 2
    cur = overall(list(skills.values())) if skills else a.current
    if cur is None or not 0 <= cur <= 9 or not 0 <= a.target <= 9:
        print("error: give --current or --skills, and bands between 0 and 9", file=sys.stderr)
        return 2
    print(f"Current overall {cur:.1f} ({cefr(cur)}) -> target {a.target:.1f} ({cefr(a.target)})")
    need = 0.0
    if skills:
        print("Skills: " + "  ".join(f"{k} {v:g}" for k, v in skills.items()))
        floor = a.min_skill or 0
        gaps = {k: max(floor, a.target - 0.5) - v for k, v in skills.items()}
        weak = sorted((k for k in gaps if gaps[k] > 0), key=lambda k: -gaps[k])
        if weak:
            print("Priority skills: " + ", ".join(f"{k} (+{gaps[k]:g})" for k in weak))
        need = max((hours(skills[k], skills[k] + gaps[k]) for k in weak), default=0)
    need = max(need, hours(cur, a.target))
    if need == 0:
        print("Target already met")
        return 0
    print(f"Estimated guided study: about {need:.0f} hours (range {need * 0.75:.0f}-{need * 1.25:.0f})")
    if a.hours_per_week:
        wk = math.ceil(need / a.hours_per_week)
        print(f"At {a.hours_per_week:g} h/week: about {wk} weeks")
        if a.weeks:
            ok = wk <= a.weeks
            print(f"Time available: {a.weeks} weeks - {'feasible' if ok else 'not enough; consider a longer course, more hours, or a later test date'}")
            return 0 if ok else 1
    return 0


if __name__ == "__main__":
    sys.exit(main())
More in Language Teaching

actfl-proficiency-curriculum-mapper

Map world language curricula to the ACTFL framework: proficiency levels (Novice, Intermediate, Advanced, Superior, Distinguished with sublevels), functions, contexts, text types and accuracy, proficiency vs performance, the three modes of communication (interpretive, interpersonal, presentational), the 5 Cs World-Readiness Standards, backward-designed thematic units with Integrated Performance Assessments, typical programme targets and FSI time estimates. Looks up approximate ACTFL-CEFR-ILR equivalences with what each level can do, and checks a unit map for missing modes, rehearsed skits mislabelled as interpersonal, translation or word lists as interpretive tasks, and units without an integrated performance assessment.

adult-literacy-esl-lesson-builder

Build lessons for adult ESL learners who are developing literacy (LESLLA learners: pre-literate, non-literate, semi-literate, literate in a non-Roman script): learner profiles and sensitive initial assessment, principles (oral language first, known to new, systematic phonics with adult-relevant text, repetition, classroom skills, respect for experience), a lesson routine (oral warm-up, review, new grapheme, blending, segmenting, decodable text, writing, functional literacy, Language Experience Approach), a phonics sequence for adults, sight words, functional literacy targets (forms, signs, medicine labels) and portfolio assessment. Checks whether a reading text is decodable with the letter-sound patterns and sight words taught so far, catching untaught digraphs, listing non-decodable words with the untaught part, and suggesting the most useful next patterns.

authentic-material-lesson-adapter

Turn authentic material (news articles, podcasts, videos, songs, menus, timetables, adverts, social media posts, forms, infographics) into language lessons by grading the task rather than the text. Selects texts for interest, relevance, exploitability, coverage, cultural load and rights; finds the 4-6 words to pre-teach, words to gloss on the page and words learners can ignore, plus names and cultural references to explain, with reading time by level; and builds a lesson shape (lead-in, pre-teach, gist or scanning, graded detail task, language focus on chunks and register, response) with task ideas per material type and level from A1 to C1. Covers copyright, fair dealing and fair use, Creative Commons and attribution.

can-do-statement-writer

Write and review can-do statements for language courses, units, lessons and learner self-assessment, CEFR or NCSSFL-ACTFL style: action (observable verb) + text or situation + level-specific conditions, learner ('I can') and descriptor ('Can') versions, progressions of one activity from A1 to C1, and coverage of reception, production, interaction and mediation. Includes a verb bank by mode and level and condition and text-type banks. Lints statements for teacher-centred phrasing, knowledge instead of use (learn, know, understand the passive), missing context, two skills in one statement, vague quality words, grammar items as outcomes, overlong statements and missing modes in a set.

cefr-aligned-syllabus-builder

Build language course syllabuses aligned to the CEFR (A1-C2, plus levels, Companion Volume 2020): entry and exit levels, guided learning hours and course length (with an L1-distance adjustment), syllabus type (topic, functional-notional, task-based, skills-based, multi-strand), unit-by-unit can-do outcomes, grammar from a core inventory by level, vocabulary, functions, pronunciation, balance of reception, production, interaction and mediation, recycling and assessment points. Checks a syllabus for units without can-do statements, core grammar for the level not covered, items above the course level, skills missing from most units and units with no vocabulary or functions.

classroom-management-for-esl-coach

Coach ESL/EFL teachers in classroom management: the instruction sequence (attention, group first, graded imperatives, demonstration, ICQs, hand out, start, check), ICQ examples, online instructions, routines for the first weeks (class agreement, L1 use, phones, lateness, homework, seating), strategies for L1 use in tasks, dominant and quiet learners, mixed levels, large classes, fast finishers, low motivation, disruptive young learners and teens, cultural expectations, classroom language to teach early and teacher presence. Checks planned instructions for length, missing ICQs, useless ICQs like 'Do you understand?', no demonstration, long sentences, filler and missing grouping or timing, and builds seating plans that keep named learners apart, seat learners who need the front, mix first languages and alternate stronger and weaker learners.