ssctopper/generators/english_generator.py

546 lines
31 KiB
Python

#!/usr/bin/env python3
"""
English Language & Comprehension Question Generator for SSC CGL.
Generates ~25,000 questions covering vocabulary, grammar, sentence structure, error detection.
"""
import random
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from generators.base import make_question, get_qtid, get_db, insert_questions_batch
SUBJECT = "English Language and Comprehension"
# ============ WORD BANKS ============
SYNONYMS = [
("Abundant", "Plentiful", ["Scarce", "Meager", "Rare"]),
("Accurate", "Precise", ["Wrong", "Vague", "Incorrect"]),
("Admire", "Respect", ["Despise", "Hate", "Ignore"]),
("Affluent", "Wealthy", ["Poor", "Needy", "Destitute"]),
("Agile", "Nimble", ["Clumsy", "Slow", "Stiff"]),
("Amiable", "Friendly", ["Hostile", "Rude", "Cold"]),
("Ancient", "Old", ["Modern", "New", "Recent"]),
("Arduous", "Difficult", ["Easy", "Simple", "Effortless"]),
("Audacious", "Bold", ["Timid", "Meek", "Cowardly"]),
("Authentic", "Genuine", ["Fake", "False", "Counterfeit"]),
("Benevolent", "Kind", ["Cruel", "Malicious", "Harsh"]),
("Bizarre", "Strange", ["Normal", "Usual", "Ordinary"]),
("Candid", "Frank", ["Deceptive", "Dishonest", "Sly"]),
("Cautious", "Careful", ["Reckless", "Careless", "Rash"]),
("Comprehend", "Understand", ["Misunderstand", "Confuse", "Ignore"]),
("Conceal", "Hide", ["Reveal", "Expose", "Display"]),
("Contempt", "Scorn", ["Respect", "Admiration", "Regard"]),
("Courage", "Bravery", ["Cowardice", "Fear", "Timidity"]),
("Delight", "Joy", ["Sorrow", "Grief", "Misery"]),
("Diligent", "Hardworking", ["Lazy", "Idle", "Indolent"]),
("Diminish", "Reduce", ["Increase", "Enlarge", "Expand"]),
("Eloquent", "Expressive", ["Inarticulate", "Stammering", "Dull"]),
("Enormous", "Huge", ["Tiny", "Small", "Minute"]),
("Eternal", "Everlasting", ["Temporary", "Brief", "Fleeting"]),
("Exquisite", "Beautiful", ["Ugly", "Plain", "Crude"]),
("Feeble", "Weak", ["Strong", "Powerful", "Mighty"]),
("Ferocious", "Fierce", ["Gentle", "Mild", "Tame"]),
("Frigid", "Cold", ["Hot", "Warm", "Tropical"]),
("Generous", "Liberal", ["Stingy", "Miserly", "Tight"]),
("Gratitude", "Thankfulness", ["Ingratitude", "Ungratefulness", "Resentment"]),
("Halt", "Stop", ["Continue", "Proceed", "Advance"]),
("Hazardous", "Dangerous", ["Safe", "Secure", "Harmless"]),
("Hostile", "Unfriendly", ["Friendly", "Warm", "Kind"]),
("Immense", "Vast", ["Tiny", "Small", "Little"]),
("Impeccable", "Flawless", ["Faulty", "Defective", "Imperfect"]),
("Jubilant", "Joyful", ["Sad", "Gloomy", "Depressed"]),
("Keen", "Eager", ["Reluctant", "Unwilling", "Indifferent"]),
("Laudable", "Praiseworthy", ["Blameworthy", "Shameful", "Disgraceful"]),
("Lucid", "Clear", ["Confusing", "Vague", "Obscure"]),
("Magnificent", "Splendid", ["Ordinary", "Plain", "Dull"]),
("Meticulous", "Careful", ["Careless", "Sloppy", "Negligent"]),
("Mundane", "Ordinary", ["Extraordinary", "Unusual", "Special"]),
("Novice", "Beginner", ["Expert", "Veteran", "Professional"]),
("Obstinate", "Stubborn", ["Flexible", "Yielding", "Compliant"]),
("Opulent", "Luxurious", ["Poor", "Shabby", "Modest"]),
("Pacify", "Calm", ["Agitate", "Provoke", "Irritate"]),
("Prudent", "Wise", ["Foolish", "Reckless", "Imprudent"]),
("Replenish", "Refill", ["Drain", "Empty", "Deplete"]),
("Serene", "Calm", ["Turbulent", "Agitated", "Noisy"]),
("Tedious", "Boring", ["Interesting", "Exciting", "Engaging"]),
("Trivial", "Insignificant", ["Important", "Significant", "Vital"]),
("Ubiquitous", "Everywhere", ["Rare", "Scarce", "Uncommon"]),
("Valiant", "Brave", ["Cowardly", "Timid", "Fearful"]),
("Verbose", "Wordy", ["Concise", "Brief", "Terse"]),
("Wrath", "Anger", ["Calm", "Peace", "Happiness"]),
("Zealous", "Enthusiastic", ["Apathetic", "Indifferent", "Passive"]),
]
ANTONYMS = [
("Accept", "Reject"), ("Advance", "Retreat"), ("Ancient", "Modern"),
("Arrival", "Departure"), ("Ascend", "Descend"), ("Bold", "Timid"),
("Brave", "Cowardly"), ("Bright", "Dim"), ("Calm", "Agitated"),
("Create", "Destroy"), ("Dawn", "Dusk"), ("Defend", "Attack"),
("Expand", "Contract"), ("Forget", "Remember"), ("Generous", "Miserly"),
("Guilty", "Innocent"), ("Humble", "Proud"), ("Import", "Export"),
("Joy", "Sorrow"), ("Knowledge", "Ignorance"), ("Liberty", "Captivity"),
("Major", "Minor"), ("Natural", "Artificial"), ("Optimist", "Pessimist"),
("Peace", "War"), ("Rapid", "Slow"), ("Rigid", "Flexible"),
("Simple", "Complex"), ("Temporary", "Permanent"), ("Victory", "Defeat"),
("Wisdom", "Folly"), ("Zenith", "Nadir"), ("Transparent", "Opaque"),
("Voluntary", "Compulsory"), ("Shallow", "Deep"), ("Fertile", "Barren"),
("Concord", "Discord"), ("Benign", "Malignant"), ("Prolific", "Barren"),
("Affluent", "Destitute"),
]
ONE_WORD_SUBS = [
("A person who loves books", "Bibliophile", ["Bibliographer", "Librarian", "Bookworm"]),
("Government by the people", "Democracy", ["Monarchy", "Autocracy", "Oligarchy"]),
("One who hates mankind", "Misanthrope", ["Philanthropist", "Misogynist", "Anthropologist"]),
("A person who speaks two languages", "Bilingual", ["Polyglot", "Monoglot", "Linguist"]),
("A person who walks in sleep", "Somnambulist", ["Insomniac", "Sleepwalker", "Narcoleptic"]),
("Fear of water", "Hydrophobia", ["Aquaphobia", "Claustrophobia", "Acrophobia"]),
("Fear of heights", "Acrophobia", ["Hydrophobia", "Claustrophobia", "Agoraphobia"]),
("One who eats human flesh", "Cannibal", ["Carnivore", "Omnivore", "Herbivore"]),
("A word that is opposite in meaning", "Antonym", ["Synonym", "Homonym", "Acronym"]),
("Killing of a king", "Regicide", ["Homicide", "Genocide", "Fratricide"]),
("A place for keeping bees", "Apiary", ["Aviary", "Aquarium", "Nursery"]),
("One who knows everything", "Omniscient", ["Omnipresent", "Omnipotent", "Omnivore"]),
("Medicine that kills germs", "Antiseptic", ["Antibiotic", "Antidote", "Analgesic"]),
("A person who is 100 years old", "Centenarian", ["Octogenarian", "Nonagenarian", "Septuagenarian"]),
("Study of stars", "Astronomy", ["Astrology", "Cosmology", "Astrophysics"]),
("Government by a single person", "Autocracy", ["Democracy", "Monarchy", "Theocracy"]),
("One who does not believe in God", "Atheist", ["Theist", "Agnostic", "Pagan"]),
("A speech delivered without preparation", "Extempore", ["Impromptu", "Rehearsed", "Deliberate"]),
("One who lives on vegetables", "Vegetarian", ["Vegan", "Carnivore", "Omnivore"]),
("A place for keeping dead bodies", "Mortuary", ["Cemetery", "Crematorium", "Mausoleum"]),
("That which cannot be read", "Illegible", ["Eligible", "Legible", "Indelible"]),
("A person who cannot be corrected", "Incorrigible", ["Incurable", "Invincible", "Inevitable"]),
("One who is present everywhere", "Omnipresent", ["Omniscient", "Omnipotent", "Omnivore"]),
("One who looks on the bright side", "Optimist", ["Pessimist", "Realist", "Fatalist"]),
("Study of ancient things", "Archaeology", ["Anthropology", "Paleontology", "Geology"]),
]
IDIOMS = [
("Break the ice", "To initiate conversation in a social setting", ["To break something", "To melt ice", "To cool down"]),
("Burn the midnight oil", "To work or study late into the night", ["To waste oil", "To start a fire", "To cook at night"]),
("Cry over spilt milk", "To regret something that cannot be undone", ["To cry while drinking milk", "To waste milk", "To be sad about dairy"]),
("Hit the nail on the head", "To be exactly right", ["To do carpentry", "To hurt oneself", "To break something"]),
("A piece of cake", "Something very easy", ["A type of dessert", "A small portion", "A bakery item"]),
("Bite the bullet", "To face a difficult situation bravely", ["To eat ammunition", "To hurt teeth", "To be violent"]),
("Cost an arm and a leg", "Very expensive", ["Physical injury", "Amputation", "Medical procedure"]),
("Let the cat out of the bag", "To reveal a secret", ["To free an animal", "To open a bag", "To go shopping"]),
("Once in a blue moon", "Very rarely", ["During full moon", "Monthly", "Nightly"]),
("Raining cats and dogs", "Raining very heavily", ["Animals falling", "Pet show", "Zoo visit"]),
("Spill the beans", "To reveal secret information", ["To cook", "To waste food", "To plant seeds"]),
("The ball is in your court", "It is your turn to take action", ["Playing tennis", "Court hearing", "Ball game"]),
("Under the weather", "Feeling unwell", ["In rain", "Below clouds", "Bad climate"]),
("Actions speak louder than words", "What you do matters more than what you say", ["Being noisy", "Shouting", "Speaking loudly"]),
("Beat around the bush", "To avoid the main topic", ["Gardening", "Playing in bush", "Walking in forest"]),
("Burning bridges", "Destroying relationships", ["Arson", "Building fire", "Demolition"]),
("Every cloud has a silver lining", "Good things come after bad", ["Weather forecast", "Cloud watching", "Silver mining"]),
("Keep your chin up", "Stay positive", ["Posture advice", "Exercise tip", "Looking upward"]),
("Back to the drawing board", "Start over", ["Art class", "Going backwards", "Drawing pictures"]),
("Barking up the wrong tree", "Making a wrong assumption", ["Disturbing a dog", "Climbing trees", "Forest activity"]),
]
# ============ GENERATORS ============
def gen_synonyms(conn, count=2500):
questions = []
qtid = get_qtid(conn, SUBJECT, "Vocabulary", "Synonyms", "Choose synonym")
if not qtid: return questions
for _ in range(count):
word, syn, wrongs = random.choice(SYNONYMS)
questions.append(make_question(qtid,
f"Choose the synonym of '{word}':",
syn, wrongs, f"'{word}' means '{syn}'", 1))
return questions
def gen_antonyms(conn, count=2500):
questions = []
qtid = get_qtid(conn, SUBJECT, "Vocabulary", "Antonyms", "Choose antonym")
if not qtid: return questions
for _ in range(count):
word, ant = random.choice(ANTONYMS)
other_ants = [a[1] for a in random.sample(ANTONYMS, 3) if a[0] != word][:3]
if len(other_ants) < 3:
other_ants = ["None", "All", "Some"][:3]
questions.append(make_question(qtid,
f"Choose the antonym of '{word}':",
ant, other_ants, f"Opposite of '{word}' is '{ant}'", 1))
return questions
def gen_one_word(conn, count=2000):
questions = []
qtid = get_qtid(conn, SUBJECT, "Vocabulary", "One Word Substitution", "Find one word for phrase")
if not qtid: return questions
for _ in range(count):
phrase, word, wrongs = random.choice(ONE_WORD_SUBS)
questions.append(make_question(qtid,
f"One word for: '{phrase}'",
word, wrongs, f"'{phrase}' = {word}", 1))
return questions
def gen_idioms(conn, count=2000):
questions = []
qtid = get_qtid(conn, SUBJECT, "Vocabulary", "Idioms and Phrases", "Meaning of idiom")
if not qtid: return questions
for _ in range(count):
idiom, meaning, wrongs = random.choice(IDIOMS)
questions.append(make_question(qtid,
f"What does the idiom '{idiom}' mean?",
meaning, wrongs, f"'{idiom}' = {meaning}", 1))
return questions
def gen_spelling(conn, count=1500):
questions = []
qtid = get_qtid(conn, SUBJECT, "Vocabulary", "Spelling Correction", "Choose correct spelling")
if not qtid: return questions
words = ["Accommodation", "Achievement", "Acknowledge", "Acquaintance", "Aggressive",
"Apparently", "Argument", "Assassination", "Beautiful", "Beginning",
"Believe", "Bureaucracy", "Calendar", "Changeable", "Committed",
"Conscience", "Conscious", "Definitely", "Dilemma", "Disappear",
"Disappoint", "Discipline", "Embarrass", "Environment", "Exaggerate",
"Existence", "Experience", "Fascinate", "February", "Fluorescent",
"Foreign", "Forty", "Government", "Guarantee", "Harass",
"Hierarchy", "Humorous", "Hygiene", "Immediately", "Independent",
"Intelligence", "Jewellery", "Judgement", "Knowledge", "Leisure",
"License", "Maintenance", "Mediterranean", "Millennium", "Necessary",
"Noticeable", "Occasion", "Occurrence", "Parliament", "Perseverance",
"Pneumonia", "Possession", "Privilege", "Pronunciation", "Psychology",
"Questionnaire", "Receive", "Recommend", "Rhythm", "Schedule",
"Separate", "Successful", "Supersede", "Surprise", "Threshold",
"Tomorrow", "Tyranny", "Unnecessary", "Vacuum", "Vegetable",
"Wednesday", "Weird"]
for _ in range(count):
w = random.choice(words)
# Create misspellings
misspells = []
for _ in range(3):
idx = random.randint(1, len(w) - 2)
chars = list(w)
chars[idx] = random.choice('aeiou') if chars[idx] not in 'aeiou' else random.choice('bcdfg')
m = "".join(chars)
if m != w:
misspells.append(m)
while len(misspells) < 3:
misspells.append(w[:-1] + random.choice('aeioust'))
questions.append(make_question(qtid,
f"Choose the correctly spelled word:",
w, misspells[:3], f"Correct spelling: {w}", 1))
return questions
def gen_tenses(conn, count=1500):
questions = []
qtid = get_qtid(conn, SUBJECT, "Grammar", "Tenses", "Fill in correct tense")
if not qtid: return questions
templates = [
("She ___ to school every day.", "goes", ["go", "went", "going"], "Simple Present"),
("They ___ playing football yesterday.", "were", ["was", "are", "is"], "Past Continuous"),
("He ___ the work by tomorrow.", "will finish", ["finished", "finishes", "finishing"], "Simple Future"),
("I ___ this book already.", "have read", ["had read", "read", "reading"], "Present Perfect"),
("She ___ dinner when I arrived.", "was cooking", ["cooked", "cooks", "cooking"], "Past Continuous"),
("We ___ here since morning.", "have been", ["are", "were", "was"], "Present Perfect Continuous"),
("The train ___ before we reached.", "had left", ["left", "leaves", "leaving"], "Past Perfect"),
("By next year, I ___ my degree.", "will have completed", ["complete", "completed", "completing"], "Future Perfect"),
("He ___ a letter now.", "is writing", ["writes", "wrote", "written"], "Present Continuous"),
("They ___ the match last week.", "won", ["win", "wins", "winning"], "Simple Past"),
("She ___ the piano since childhood.", "has been playing", ["plays", "played", "play"], "Present Perfect Continuous"),
("I ___ you tomorrow.", "will call", ["called", "call", "calling"], "Simple Future"),
]
for _ in range(count):
q_text, correct, wrongs, tense = random.choice(templates)
questions.append(make_question(qtid, f"Fill in the blank: {q_text}",
correct, wrongs, f"Tense: {tense}", 1))
return questions
def gen_articles(conn, count=1000):
questions = []
qtid = get_qtid(conn, SUBJECT, "Grammar", "Articles", "Fill in correct article")
if not qtid: return questions
templates = [
("___ apple a day keeps the doctor away.", "An", ["A", "The", "No article"]),
("He is ___ honest man.", "an", ["a", "the", "no article"]),
("___ sun rises in the east.", "The", ["A", "An", "No article"]),
("She is ___ doctor.", "a", ["an", "the", "no article"]),
("I saw ___ elephant in the zoo.", "an", ["a", "the", "no article"]),
("___ Ganges is a holy river.", "The", ["A", "An", "No article"]),
("He gave me ___ useful tip.", "a", ["an", "the", "no article"]),
("___ gold is a precious metal.", "No article", ["A", "An", "The"]),
("She is ___ European.", "a", ["an", "the", "no article"]),
("I need ___ umbrella.", "an", ["a", "the", "no article"]),
]
for _ in range(count):
q_text, correct, wrongs = random.choice(templates)
questions.append(make_question(qtid, f"Fill in the correct article: {q_text}",
correct, wrongs, f"Article rule applied", 1))
return questions
def gen_prepositions(conn, count=1000):
questions = []
qtid = get_qtid(conn, SUBJECT, "Grammar", "Prepositions", "Fill in preposition")
if not qtid: return questions
templates = [
("The book is ___ the table.", "on", ["in", "at", "by"]),
("She arrived ___ Monday.", "on", ["in", "at", "by"]),
("He lives ___ Mumbai.", "in", ["on", "at", "by"]),
("The meeting is ___ 3 PM.", "at", ["in", "on", "by"]),
("I have been waiting ___ morning.", "since", ["for", "from", "by"]),
("She is good ___ mathematics.", "at", ["in", "on", "with"]),
("He is fond ___ music.", "of", ["with", "in", "at"]),
("The cat jumped ___ the wall.", "over", ["on", "in", "at"]),
("She is interested ___ painting.", "in", ["on", "at", "by"]),
("He walked ___ the park.", "through", ["in", "on", "at"]),
("They traveled ___ train.", "by", ["in", "on", "with"]),
("The match starts ___ 5 o'clock.", "at", ["in", "on", "by"]),
]
for _ in range(count):
q_text, correct, wrongs = random.choice(templates)
questions.append(make_question(qtid, f"Fill in the correct preposition: {q_text}",
correct, wrongs, f"Preposition: {correct}", 1))
return questions
def gen_voice(conn, count=1500):
questions = []
qtid = get_qtid(conn, SUBJECT, "Sentence Structure", "Active and Passive Voice", "Convert to passive")
if not qtid: return questions
templates = [
("She writes a letter.", "A letter is written by her.", ["A letter was written by her.", "A letter were written by her.", "A letter has written by her."]),
("He plays cricket.", "Cricket is played by him.", ["Cricket was played by him.", "Cricket were played by him.", "Cricket has played by him."]),
("They are building a house.", "A house is being built by them.", ["A house was being built by them.", "A house has been built by them.", "A house is built by them."]),
("She cooked food.", "Food was cooked by her.", ["Food is cooked by her.", "Food has been cooked by her.", "Food was being cooked by her."]),
("I have finished the work.", "The work has been finished by me.", ["The work was finished by me.", "The work is finished by me.", "The work had been finished by me."]),
("The teacher teaches the students.", "The students are taught by the teacher.", ["The students were taught by the teacher.", "The students has been taught by the teacher.", "The students is taught by the teacher."]),
("He will write a book.", "A book will be written by him.", ["A book would be written by him.", "A book shall be written by him.", "A book is written by him."]),
("Ram killed Ravana.", "Ravana was killed by Ram.", ["Ravana is killed by Ram.", "Ravana has been killed by Ram.", "Ravana were killed by Ram."]),
]
for _ in range(count):
active, passive, wrongs = random.choice(templates)
questions.append(make_question(qtid,
f"Convert to passive voice: '{active}'",
passive, wrongs, f"Passive: {passive}", 1))
return questions
def gen_direct_indirect(conn, count=1500):
questions = []
qtid = get_qtid(conn, SUBJECT, "Sentence Structure", "Direct and Indirect Speech", "Convert to indirect speech")
if not qtid: return questions
templates = [
('He said, "I am happy."', 'He said that he was happy.',
['He said that he is happy.', 'He said that I am happy.', 'He told that he was happy.']),
('She said, "I will come tomorrow."', 'She said that she would come the next day.',
['She said that she will come tomorrow.', 'She told she would come next day.', 'She said she will come.']),
('He asked, "Where do you live?"', 'He asked where I lived.',
['He asked where do I live.', 'He asked that where I lived.', 'He asked me where I live.']),
('She said, "I have finished my work."', 'She said that she had finished her work.',
['She said that she has finished her work.', 'She told she had finished work.', 'She said she finished her work.']),
('The teacher said, "The Earth revolves around the Sun."', 'The teacher said that the Earth revolves around the Sun.',
['The teacher said the Earth revolved around the Sun.', 'The teacher told the Earth revolves around Sun.', 'The teacher said Earth revolving around Sun.']),
]
for _ in range(count):
direct, indirect, wrongs = random.choice(templates)
questions.append(make_question(qtid,
f"Convert to indirect speech: {direct}",
indirect, wrongs, f"Indirect: {indirect}", 1))
return questions
def gen_sentence_improvement(conn, count=2000):
questions = []
qtid = get_qtid(conn, SUBJECT, "Sentence Structure", "Sentence Improvement", "Replace underlined part")
if not qtid: return questions
templates = [
("He don't know the answer.", "doesn't know", ["don't knows", "didn't knew", "not know"]),
("She is more taller than her sister.", "taller", ["most taller", "more tall", "tallest"]),
("I am going to market.", "to the market", ["in market", "for market", "at market"]),
("He told to me a story.", "told me", ["said to me", "tell me", "telling me"]),
("Each of the boys have done their work.", "has done his", ["have done his", "has did their", "have done their"]),
("One should do his duty.", "one's duty", ["their duty", "your duty", "our duty"]),
("She is knowing the answer.", "knows", ["is know", "was knowing", "has knowing"]),
("I am having a car.", "have", ["is having", "has", "having"]),
("He prevented me to go.", "from going", ["for going", "about going", "of going"]),
("She is elder than me.", "older than I", ["elder than I", "more elder than me", "oldest than me"]),
]
for _ in range(count):
sentence, correct, wrongs = random.choice(templates)
questions.append(make_question(qtid,
f"Improve the sentence: '{sentence}'",
correct, wrongs, f"Correct: {correct}", 2))
return questions
def gen_error_detection(conn, count=2500):
questions = []
qtid = get_qtid(conn, SUBJECT, "Error Detection", "Spot the Error", "Identify erroneous part")
if not qtid: return questions
templates = [
("He go to school daily.", "Part A: 'go' should be 'goes'", ["Part B: 'to' is wrong", "Part C: 'daily' is wrong", "No error"]),
("She don't like ice cream.", "Part A: 'don't' should be 'doesn't'", ["Part B: 'like' is wrong", "Part C is wrong", "No error"]),
("The news are good.", "Part A: 'are' should be 'is'", ["Part B: 'good' is wrong", "Part C is wrong", "No error"]),
("Mathematics are my favourite subject.", "Part A: 'are' should be 'is'", ["Part B is wrong", "Part C is wrong", "No error"]),
("Each of the students have passed.", "Part B: 'have' should be 'has'", ["Part A is wrong", "Part C is wrong", "No error"]),
("He is more stronger than me.", "Part A: 'more stronger' should be 'stronger'", ["Part B is wrong", "Part C is wrong", "No error"]),
("I am agree with you.", "Part A: 'am agree' should be 'agree'", ["Part B is wrong", "Part C is wrong", "No error"]),
("The furniture are expensive.", "Part A: 'are' should be 'is'", ["Part B is wrong", "Part C is wrong", "No error"]),
("He gave me a advise.", "Part B: 'advise' should be 'advice'", ["Part A is wrong", "Part C is wrong", "No error"]),
("She discuss about the matter.", "Part A: 'discuss about' should be 'discussed'", ["Part B is wrong", "Part C is wrong", "No error"]),
]
for _ in range(count):
sentence, error, wrongs = random.choice(templates)
questions.append(make_question(qtid,
f"Find the error in: '{sentence}'",
error, wrongs, f"Error: {error}", 2))
return questions
def gen_fill_blanks(conn, count=2000):
questions = []
qtid = get_qtid(conn, SUBJECT, "Sentence Structure", "Sentence Completion", "Fill in the blank (single)")
if not qtid: return questions
templates = [
("Hard work is the key to ___.", "success", ["failure", "defeat", "loss"]),
("The weather is ___ today.", "pleasant", ["unpleasant", "horrible", "terrible"]),
("She showed great ___ in the face of danger.", "courage", ["cowardice", "fear", "hesitation"]),
("The doctor ___ the patient carefully.", "examined", ["ignored", "neglected", "avoided"]),
("He has a strong ___ for justice.", "passion", ["hatred", "dislike", "disregard"]),
("The students were ___ to learn the new topic.", "eager", ["reluctant", "unwilling", "indifferent"]),
("Her ___ attitude made everyone uncomfortable.", "arrogant", ["humble", "polite", "modest"]),
("The company achieved remarkable ___ this year.", "growth", ["decline", "loss", "failure"]),
("He is ___ of solving complex problems.", "capable", ["incapable", "unable", "unfit"]),
("The ___ of the river was very strong after the rain.", "current", ["calm", "stillness", "silence"]),
("She has an ___ personality that attracts people.", "amiable", ["hostile", "rude", "cold"]),
("The government ___ new policies for education.", "introduced", ["removed", "cancelled", "deleted"]),
]
for _ in range(count):
sentence, correct, wrongs = random.choice(templates)
questions.append(make_question(qtid,
f"Fill in the blank: {sentence}",
correct, wrongs, f"Answer: {correct}", 1))
return questions
def gen_sentence_rearrangement(conn, count=1500):
questions = []
qtid = get_qtid(conn, SUBJECT, "Sentence Structure", "Sentence Rearrangement", "Arrange sentence parts")
if not qtid: return questions
templates = [
(["The early bird", "catches", "the worm"], "The early bird catches the worm",
["catches the worm the early bird", "the worm catches the early bird", "the worm the early bird catches"]),
(["Knowledge is", "better than", "wealth"], "Knowledge is better than wealth",
["better than wealth knowledge is", "wealth is better than knowledge", "is knowledge better than wealth"]),
(["Honesty", "is the", "best policy"], "Honesty is the best policy",
["is the best policy honesty", "the best policy is honesty", "policy best is the honesty"]),
(["United we stand", "divided", "we fall"], "United we stand divided we fall",
["divided we fall united we stand", "we fall divided united we stand", "stand united we divided fall we"]),
(["Practice makes", "a man", "perfect"], "Practice makes a man perfect",
["a man perfect practice makes", "makes practice a man perfect", "perfect a man makes practice"]),
]
for _ in range(count):
parts, correct, wrongs = random.choice(templates)
random.shuffle(parts)
questions.append(make_question(qtid,
f"Arrange in correct order: {' / '.join(parts)}",
correct, wrongs, f"Correct order: {correct}", 2))
return questions
def gen_cloze_test(conn, count=1500):
questions = []
qtid = get_qtid(conn, SUBJECT, "Comprehension", "Cloze Test", "Fill appropriate word")
if not qtid: return questions
templates = [
("Education is the most powerful ___ to change the world.", "weapon", ["weakness", "problem", "barrier"]),
("The ___ of success is hard work and dedication.", "foundation", ["destruction", "failure", "absence"]),
("A healthy mind lives in a healthy ___.", "body", ["house", "room", "place"]),
("Books are the ___ teachers of all time.", "best", ["worst", "slowest", "latest"]),
("Time and ___ wait for none.", "tide", ["money", "people", "luck"]),
("Prevention is better than ___.", "cure", ["disease", "medicine", "treatment"]),
("All that ___ is not gold.", "glitters", ["shines", "sparkles", "reflects"]),
("A rolling stone gathers no ___.", "moss", ["grass", "dust", "speed"]),
("Where there is a will, there is a ___.", "way", ["wall", "path", "road"]),
("Rome was not built in a ___.", "day", ["week", "month", "hour"]),
]
for _ in range(count):
sentence, correct, wrongs = random.choice(templates)
if isinstance(wrongs, str): # Fix the Rome template
wrongs = [wrongs, "year", "hour"]
questions.append(make_question(qtid,
f"Fill in the blank: {sentence}",
correct, wrongs, f"Answer: {correct}", 1))
return questions
def gen_subject_verb(conn, count=1000):
questions = []
qtid = get_qtid(conn, SUBJECT, "Grammar", "Subject-Verb Agreement", "Choose correct verb")
if not qtid: return questions
templates = [
("The team ___ playing well this season.", "is", ["are", "were", "have been"]),
("Neither the teacher nor the students ___ present.", "were", ["was", "is", "has been"]),
("Each of the boys ___ given a prize.", "was", ["were", "are", "have been"]),
("Either you or I ___ going to attend.", "am", ["are", "is", "were"]),
("The quality of these apples ___ good.", "is", ["are", "were", "have been"]),
("Bread and butter ___ my favourite breakfast.", "is", ["are", "were", "have been"]),
("One of my friends ___ from Delhi.", "is", ["are", "were", "have been"]),
("The news ___ very surprising.", "was", ["were", "are", "have been"]),
("No news ___ good news.", "is", ["are", "were", "have been"]),
("Mathematics ___ my favourite subject.", "is", ["are", "were", "have been"]),
]
for _ in range(count):
sentence, correct, wrongs = random.choice(templates)
questions.append(make_question(qtid,
f"Choose the correct verb: {sentence}",
correct, wrongs, f"Correct: {correct}", 2))
return questions
def generate_all(conn):
"""Generate all English Language questions."""
generators = [
("Synonyms", gen_synonyms, 2500),
("Antonyms", gen_antonyms, 2500),
("One Word Substitution", gen_one_word, 2000),
("Idioms & Phrases", gen_idioms, 2000),
("Spelling", gen_spelling, 1500),
("Tenses", gen_tenses, 1500),
("Articles", gen_articles, 1000),
("Prepositions", gen_prepositions, 1000),
("Subject-Verb Agreement", gen_subject_verb, 1000),
("Active/Passive Voice", gen_voice, 1500),
("Direct/Indirect Speech", gen_direct_indirect, 1500),
("Sentence Improvement", gen_sentence_improvement, 2000),
("Error Detection", gen_error_detection, 2500),
("Fill in Blanks", gen_fill_blanks, 2000),
("Sentence Rearrangement", gen_sentence_rearrangement, 1500),
("Cloze Test", gen_cloze_test, 1500),
]
total = 0
all_questions = []
for name, gen_func, count in generators:
questions = gen_func(conn, count)
all_questions.extend(questions)
print(f" {name}: {len(questions)} questions")
total += len(questions)
batch_size = 5000
for i in range(0, len(all_questions), batch_size):
insert_questions_batch(conn, all_questions[i:i+batch_size])
print(f" TOTAL English: {total}")
return total
if __name__ == '__main__':
conn = get_db()
print("Generating English Language questions...")
generate_all(conn)
conn.close()