722 lines
33 KiB
Python
722 lines
33 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
Quantitative Aptitude Question Generator for SSC CGL.
|
||
Generates ~30,000 template-based math questions across all topics.
|
||
"""
|
||
import random
|
||
import math
|
||
import sys
|
||
import os
|
||
|
||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
|
||
from generators.base import make_question, get_qtid, nearby_wrong, nearby_wrong_float, get_db, insert_questions_batch
|
||
|
||
SUBJECT = "Quantitative Aptitude"
|
||
|
||
|
||
def gen_number_system(conn, count=800):
|
||
questions = []
|
||
# Unit digit questions
|
||
qtid = get_qtid(conn, SUBJECT, "Arithmetic", "Number System", "Unit digit")
|
||
if qtid:
|
||
for _ in range(count // 4):
|
||
base = random.randint(2, 99)
|
||
exp = random.randint(10, 200)
|
||
unit = pow(base, exp, 10)
|
||
q = make_question(qtid,
|
||
f"What is the unit digit of {base}^{exp}?",
|
||
str(unit), nearby_wrong(unit, 4),
|
||
f"Unit digit of {base}^{exp} = {unit}", random.choice([1,1,2]))
|
||
questions.append(q)
|
||
|
||
# Divisibility
|
||
qtid = get_qtid(conn, SUBJECT, "Arithmetic", "Number System", "Divisibility test")
|
||
if qtid:
|
||
divs = [2, 3, 4, 5, 6, 7, 8, 9, 11]
|
||
for _ in range(count // 4):
|
||
d = random.choice(divs)
|
||
num = random.randint(100, 9999) * d
|
||
q = make_question(qtid,
|
||
f"Which of the following numbers is divisible by {d}?",
|
||
str(num), [str(num + random.randint(1, d-1)) for _ in range(3)],
|
||
f"{num} ÷ {d} = {num//d}", 1)
|
||
questions.append(q)
|
||
|
||
# Remainder
|
||
qtid = get_qtid(conn, SUBJECT, "Arithmetic", "Number System", "Remainder problems")
|
||
if qtid:
|
||
for _ in range(count // 4):
|
||
divisor = random.randint(3, 20)
|
||
quotient = random.randint(10, 200)
|
||
remainder = random.randint(0, divisor - 1)
|
||
num = divisor * quotient + remainder
|
||
q = make_question(qtid,
|
||
f"What is the remainder when {num} is divided by {divisor}?",
|
||
str(remainder), nearby_wrong(remainder, max(3, divisor)),
|
||
f"{num} = {divisor} × {quotient} + {remainder}", 1)
|
||
questions.append(q)
|
||
|
||
# Find the value
|
||
qtid = get_qtid(conn, SUBJECT, "Arithmetic", "Number System", "Find the value")
|
||
if qtid:
|
||
for _ in range(count // 4):
|
||
a, b = random.randint(10, 99), random.randint(10, 99)
|
||
ops = [(f"{a} × {b}", a*b), (f"{a}² - {b}²", a*a - b*b),
|
||
(f"{a}² + {b}²", a*a + b*b)]
|
||
expr, ans = random.choice(ops)
|
||
q = make_question(qtid, f"Find the value of {expr}.",
|
||
str(ans), nearby_wrong(ans),
|
||
f"{expr} = {ans}", random.choice([1,2]))
|
||
questions.append(q)
|
||
return questions
|
||
|
||
|
||
def gen_hcf_lcm(conn, count=500):
|
||
questions = []
|
||
qtid_hcf = get_qtid(conn, SUBJECT, "Arithmetic", "HCF and LCM", "Find HCF")
|
||
qtid_lcm = get_qtid(conn, SUBJECT, "Arithmetic", "HCF and LCM", "Find LCM")
|
||
qtid_word = get_qtid(conn, SUBJECT, "Arithmetic", "HCF and LCM", "Word problems on HCF/LCM")
|
||
|
||
for _ in range(count // 3):
|
||
a, b = random.randint(10, 200), random.randint(10, 200)
|
||
h = math.gcd(a, b)
|
||
l = (a * b) // h
|
||
if qtid_hcf:
|
||
questions.append(make_question(qtid_hcf,
|
||
f"Find the HCF of {a} and {b}.", str(h), nearby_wrong(h),
|
||
f"HCF({a}, {b}) = {h}", 1))
|
||
if qtid_lcm:
|
||
questions.append(make_question(qtid_lcm,
|
||
f"Find the LCM of {a} and {b}.", str(l), nearby_wrong(l),
|
||
f"LCM({a}, {b}) = {l}", 1))
|
||
if qtid_word:
|
||
for _ in range(count // 3):
|
||
h = random.randint(5, 30)
|
||
m1, m2 = random.randint(2, 6), random.randint(2, 6)
|
||
a, b = h * m1, h * m2
|
||
questions.append(make_question(qtid_word,
|
||
f"Two ropes of lengths {a} cm and {b} cm are to be cut into pieces of equal length. What is the maximum length of each piece?",
|
||
str(h) + " cm", [str(h+i) + " cm" for i in [1, 2, -1]],
|
||
f"HCF({a}, {b}) = {h} cm", 1))
|
||
return questions
|
||
|
||
|
||
def gen_simplification(conn, count=600):
|
||
questions = []
|
||
qtid = get_qtid(conn, SUBJECT, "Arithmetic", "Simplification", "Simplify expression")
|
||
if not qtid:
|
||
return questions
|
||
for _ in range(count):
|
||
a, b, c = random.randint(2, 50), random.randint(2, 50), random.randint(1, 30)
|
||
templates = [
|
||
(f"{a} + {b} × {c}", a + b * c),
|
||
(f"{a} × {b} - {c}", a * b - c),
|
||
(f"({a} + {b}) × {c}", (a + b) * c),
|
||
(f"{a}² - {b} × {c}", a*a - b * c),
|
||
(f"{a} + {b}² - {c}", a + b*b - c),
|
||
]
|
||
expr, ans = random.choice(templates)
|
||
questions.append(make_question(qtid, f"Simplify: {expr}",
|
||
str(ans), nearby_wrong(ans), f"{expr} = {ans}", random.choice([1,1,2])))
|
||
return questions
|
||
|
||
|
||
def gen_percentage(conn, count=2000):
|
||
questions = []
|
||
# Basic percentage
|
||
qtid = get_qtid(conn, SUBJECT, "Percentage", "Basic Percentage", "Find X% of Y")
|
||
if qtid:
|
||
for _ in range(count // 4):
|
||
pct = random.choice([5, 10, 12, 15, 16, 20, 25, 30, 33, 40, 50, 60, 75])
|
||
val = random.randint(50, 5000)
|
||
ans = val * pct / 100
|
||
if ans == int(ans):
|
||
ans = int(ans)
|
||
questions.append(make_question(qtid,
|
||
f"What is {pct}% of {val}?", str(ans), nearby_wrong(ans),
|
||
f"{pct}% of {val} = {val} × {pct}/100 = {ans}", 1))
|
||
|
||
qtid = get_qtid(conn, SUBJECT, "Percentage", "Basic Percentage", "What percent is X of Y")
|
||
if qtid:
|
||
for _ in range(count // 4):
|
||
total = random.randint(50, 1000)
|
||
part = random.randint(1, total)
|
||
pct = round(part * 100 / total, 2)
|
||
questions.append(make_question(qtid,
|
||
f"What percentage is {part} of {total}?", str(pct) + "%",
|
||
[str(round(pct + random.uniform(-10, 10), 2)) + "%" for _ in range(3)],
|
||
f"{part}/{total} × 100 = {pct}%", 1))
|
||
|
||
qtid = get_qtid(conn, SUBJECT, "Percentage", "Basic Percentage", "Percentage change")
|
||
if qtid:
|
||
for _ in range(count // 4):
|
||
old = random.randint(100, 5000)
|
||
change = random.randint(5, 50)
|
||
direction = random.choice(["increased", "decreased"])
|
||
new_val = old + old * change // 100 if direction == "increased" else old - old * change // 100
|
||
questions.append(make_question(qtid,
|
||
f"If a value {direction} from {old} to {new_val}, what is the percentage change?",
|
||
str(change) + "%", [str(change + i) + "%" for i in [2, -3, 5]],
|
||
f"Change = {abs(new_val-old)}/{old} × 100 = {change}%", 1))
|
||
|
||
# Successive percentage
|
||
qtid = get_qtid(conn, SUBJECT, "Percentage", "Successive Percentage", "Net percentage change")
|
||
if qtid:
|
||
for _ in range(count // 4):
|
||
p1, p2 = random.randint(5, 40), random.randint(5, 40)
|
||
net = round(p1 + p2 + p1 * p2 / 100, 2)
|
||
questions.append(make_question(qtid,
|
||
f"If a price increases by {p1}% and then by {p2}%, what is the net percentage increase?",
|
||
str(net) + "%", nearby_wrong_float(net),
|
||
f"Net = {p1} + {p2} + ({p1}×{p2})/100 = {net}%", 2))
|
||
return questions
|
||
|
||
|
||
def gen_profit_loss(conn, count=2000):
|
||
questions = []
|
||
qtid = get_qtid(conn, SUBJECT, "Profit and Loss", "Basic Profit and Loss", "Find profit/loss percentage")
|
||
if qtid:
|
||
for _ in range(count // 3):
|
||
cp = random.randint(100, 5000)
|
||
margin = random.randint(5, 50)
|
||
is_profit = random.choice([True, False])
|
||
sp = cp + cp * margin // 100 if is_profit else cp - cp * margin // 100
|
||
word = "profit" if is_profit else "loss"
|
||
questions.append(make_question(qtid,
|
||
f"An article bought for ₹{cp} is sold for ₹{sp}. Find the {word} percentage.",
|
||
str(margin) + "%", [str(margin + i) + "%" for i in [2, -3, 5]],
|
||
f"{word.title()} = {abs(sp-cp)}/{cp} × 100 = {margin}%", 1))
|
||
|
||
qtid = get_qtid(conn, SUBJECT, "Profit and Loss", "Discount and Marked Price", "Find selling price after discount")
|
||
if qtid:
|
||
for _ in range(count // 3):
|
||
mp = random.randint(200, 10000)
|
||
d = random.choice([5, 10, 15, 20, 25, 30, 40, 50])
|
||
sp = mp - mp * d // 100
|
||
questions.append(make_question(qtid,
|
||
f"The marked price of an article is ₹{mp}. If a discount of {d}% is given, find the selling price.",
|
||
f"₹{sp}", [f"₹{sp + i*10}" for i in [1, -2, 3]],
|
||
f"SP = {mp} - {d}% of {mp} = ₹{sp}", 1))
|
||
|
||
qtid = get_qtid(conn, SUBJECT, "Profit and Loss", "Discount and Marked Price", "Find single equivalent discount")
|
||
if qtid:
|
||
for _ in range(count // 3):
|
||
d1, d2 = random.choice([10,15,20,25,30]), random.choice([5,10,15,20])
|
||
eq = round(d1 + d2 - d1 * d2 / 100, 2)
|
||
questions.append(make_question(qtid,
|
||
f"Find the single equivalent discount for successive discounts of {d1}% and {d2}%.",
|
||
str(eq) + "%", nearby_wrong_float(eq),
|
||
f"Equivalent = {d1} + {d2} - ({d1}×{d2})/100 = {eq}%", 2))
|
||
return questions
|
||
|
||
|
||
def gen_ratio(conn, count=1800):
|
||
questions = []
|
||
qtid = get_qtid(conn, SUBJECT, "Ratio and Proportion", "Basic Ratio", "Divide in given ratio")
|
||
if qtid:
|
||
for _ in range(count // 4):
|
||
a, b = random.randint(1, 10), random.randint(1, 10)
|
||
total = (a + b) * random.randint(10, 100)
|
||
part_a, part_b = total * a // (a + b), total * b // (a + b)
|
||
questions.append(make_question(qtid,
|
||
f"Divide ₹{total} in the ratio {a}:{b}. Find the larger share.",
|
||
f"₹{max(part_a, part_b)}", [f"₹{max(part_a,part_b) + i*10}" for i in [1,-2,3]],
|
||
f"Larger share = {total} × {max(a,b)}/{a+b} = ₹{max(part_a,part_b)}", 1))
|
||
|
||
qtid = get_qtid(conn, SUBJECT, "Ratio and Proportion", "Mixture and Alligation", "Mean price of mixture")
|
||
if qtid:
|
||
for _ in range(count // 4):
|
||
p1, p2 = random.randint(20, 60), random.randint(60, 120)
|
||
q1, q2 = random.randint(1, 10), random.randint(1, 10)
|
||
mean = round((p1*q1 + p2*q2) / (q1+q2), 2)
|
||
questions.append(make_question(qtid,
|
||
f"If {q1} kg of rice at ₹{p1}/kg is mixed with {q2} kg of rice at ₹{p2}/kg, find the price of the mixture per kg.",
|
||
f"₹{mean}", [f"₹{round(mean+i,2)}" for i in [2,-3,5]],
|
||
f"Mean = ({p1}×{q1} + {p2}×{q2})/{q1+q2} = ₹{mean}", 2))
|
||
|
||
qtid = get_qtid(conn, SUBJECT, "Ratio and Proportion", "Partnership", "Divide profit among partners")
|
||
if qtid:
|
||
for _ in range(count // 4):
|
||
inv_a = random.randint(1000, 10000)
|
||
inv_b = random.randint(1000, 10000)
|
||
profit = random.randint(5000, 50000)
|
||
share_a = round(profit * inv_a / (inv_a + inv_b))
|
||
questions.append(make_question(qtid,
|
||
f"A invests ₹{inv_a} and B invests ₹{inv_b}. Total profit is ₹{profit}. Find A's share.",
|
||
f"₹{share_a}", [f"₹{share_a + i*100}" for i in [1,-2,3]],
|
||
f"A's share = {profit} × {inv_a}/({inv_a}+{inv_b}) = ₹{share_a}", 2))
|
||
|
||
qtid = get_qtid(conn, SUBJECT, "Ratio and Proportion", "Proportion", "Find fourth proportional")
|
||
if qtid:
|
||
for _ in range(count // 4):
|
||
a, b, c = random.randint(2, 20), random.randint(2, 20), random.randint(2, 20)
|
||
d = b * c // a if a != 0 else 1
|
||
if a * d == b * c:
|
||
questions.append(make_question(qtid,
|
||
f"Find the fourth proportional to {a}, {b}, and {c}.",
|
||
str(d), nearby_wrong(d),
|
||
f"a:b = c:d → d = b×c/a = {b}×{c}/{a} = {d}", 1))
|
||
return questions
|
||
|
||
|
||
def gen_average(conn, count=1200):
|
||
questions = []
|
||
qtid = get_qtid(conn, SUBJECT, "Average", "Simple Average", "Find average")
|
||
if qtid:
|
||
for _ in range(count // 3):
|
||
n = random.randint(3, 8)
|
||
nums = [random.randint(10, 100) for _ in range(n)]
|
||
avg = round(sum(nums) / n, 2)
|
||
nums_str = ", ".join(map(str, nums))
|
||
questions.append(make_question(qtid,
|
||
f"Find the average of {nums_str}.",
|
||
str(avg), nearby_wrong_float(avg),
|
||
f"Average = {sum(nums)}/{n} = {avg}", 1))
|
||
|
||
qtid = get_qtid(conn, SUBJECT, "Average", "Simple Average", "Average after adding/removing")
|
||
if qtid:
|
||
for _ in range(count // 3):
|
||
n = random.randint(5, 15)
|
||
avg = random.randint(20, 80)
|
||
new_val = random.randint(avg + 5, avg + 50)
|
||
new_avg = round((avg * n + new_val) / (n + 1), 2)
|
||
questions.append(make_question(qtid,
|
||
f"The average of {n} numbers is {avg}. When a new number {new_val} is added, what is the new average?",
|
||
str(new_avg), nearby_wrong_float(new_avg),
|
||
f"New avg = ({avg}×{n} + {new_val})/{n+1} = {new_avg}", 2))
|
||
|
||
qtid = get_qtid(conn, SUBJECT, "Average", "Age Problems", "Average age of family")
|
||
if qtid:
|
||
for _ in range(count // 3):
|
||
n = random.randint(3, 6)
|
||
avg_age = random.randint(20, 40)
|
||
baby_age = random.randint(1, 5)
|
||
new_avg = round((avg_age * n + baby_age) / (n + 1), 2)
|
||
questions.append(make_question(qtid,
|
||
f"The average age of {n} members of a family is {avg_age} years. A baby of {baby_age} year(s) is born. Find the new average age.",
|
||
str(new_avg) + " years", [str(round(new_avg+i,2)) + " years" for i in [1,-2,3]],
|
||
f"New avg = ({avg_age}×{n} + {baby_age})/{n+1} = {new_avg} years", 1))
|
||
return questions
|
||
|
||
|
||
def gen_time_work(conn, count=1500):
|
||
questions = []
|
||
qtid = get_qtid(conn, SUBJECT, "Time and Work", "Basic Time and Work", "Find combined time")
|
||
if qtid:
|
||
for _ in range(count // 3):
|
||
a, b = random.randint(5, 30), random.randint(5, 30)
|
||
combined = round(a * b / (a + b), 2)
|
||
questions.append(make_question(qtid,
|
||
f"A can do a work in {a} days and B can do it in {b} days. In how many days can they do it together?",
|
||
str(combined) + " days", [str(round(combined+i,2)) + " days" for i in [1,-2,3]],
|
||
f"Together = {a}×{b}/({a}+{b}) = {combined} days", 2))
|
||
|
||
qtid = get_qtid(conn, SUBJECT, "Time and Work", "Pipes and Cisterns", "Time to fill tank")
|
||
if qtid:
|
||
for _ in range(count // 3):
|
||
a, b = random.randint(5, 30), random.randint(5, 30)
|
||
combined = round(a * b / (a + b), 2)
|
||
questions.append(make_question(qtid,
|
||
f"Two pipes can fill a tank in {a} hours and {b} hours respectively. How long to fill the tank if both are opened?",
|
||
str(combined) + " hours", [str(round(combined+i,2)) + " hours" for i in [1,-2,3]],
|
||
f"Together = {a}×{b}/({a}+{b}) = {combined} hours", 2))
|
||
|
||
qtid = get_qtid(conn, SUBJECT, "Time and Work", "Work and Wages", "Divide wages")
|
||
if qtid:
|
||
for _ in range(count // 3):
|
||
da, db = random.randint(5, 20), random.randint(5, 20)
|
||
wage = random.randint(1000, 10000)
|
||
eff_a, eff_b = 1/da, 1/db
|
||
share_a = round(wage * eff_a / (eff_a + eff_b))
|
||
questions.append(make_question(qtid,
|
||
f"A can do a work in {da} days and B in {db} days. For a total wage of ₹{wage}, find A's share.",
|
||
f"₹{share_a}", [f"₹{share_a + i*50}" for i in [1,-2,3]],
|
||
f"A's share = ₹{wage} × (1/{da}) / (1/{da} + 1/{db}) = ₹{share_a}", 2))
|
||
return questions
|
||
|
||
|
||
def gen_speed_distance(conn, count=2000):
|
||
questions = []
|
||
qtid = get_qtid(conn, SUBJECT, "Time, Speed and Distance", "Basic Speed and Distance", "Average speed")
|
||
if qtid:
|
||
for _ in range(count // 4):
|
||
s1, s2 = random.randint(20, 80), random.randint(20, 80)
|
||
avg = round(2 * s1 * s2 / (s1 + s2), 2)
|
||
questions.append(make_question(qtid,
|
||
f"A person goes from A to B at {s1} km/h and returns at {s2} km/h. Find the average speed.",
|
||
str(avg) + " km/h", [str(round(avg+i,2)) + " km/h" for i in [2,-3,5]],
|
||
f"Avg speed = 2×{s1}×{s2}/({s1}+{s2}) = {avg} km/h", 2))
|
||
|
||
qtid = get_qtid(conn, SUBJECT, "Time, Speed and Distance", "Trains", "Train passing pole")
|
||
if qtid:
|
||
for _ in range(count // 4):
|
||
length = random.randint(100, 500)
|
||
speed_kmh = random.randint(36, 144)
|
||
speed_ms = round(speed_kmh * 5 / 18, 2)
|
||
time = round(length / speed_ms, 2)
|
||
questions.append(make_question(qtid,
|
||
f"A train {length}m long passes a pole in {time} seconds. Find its speed in km/h.",
|
||
str(speed_kmh) + " km/h", [str(speed_kmh + i) + " km/h" for i in [4,-6,9]],
|
||
f"Speed = {length}/{time} m/s = {speed_kmh} km/h", 2))
|
||
|
||
qtid = get_qtid(conn, SUBJECT, "Time, Speed and Distance", "Boats and Streams", "Find speed in still water")
|
||
if qtid:
|
||
for _ in range(count // 4):
|
||
boat = random.randint(10, 30)
|
||
stream = random.randint(2, 8)
|
||
ds = boat + stream
|
||
us = boat - stream
|
||
questions.append(make_question(qtid,
|
||
f"A boat goes {ds} km/h downstream and {us} km/h upstream. Find speed in still water.",
|
||
str(boat) + " km/h", [str(boat + i) + " km/h" for i in [1, -2, 3]],
|
||
f"Speed = ({ds}+{us})/2 = {boat} km/h", 1))
|
||
|
||
qtid = get_qtid(conn, SUBJECT, "Time, Speed and Distance", "Basic Speed and Distance", "Find distance")
|
||
if qtid:
|
||
for _ in range(count // 4):
|
||
speed = random.randint(20, 100)
|
||
time = random.randint(1, 10)
|
||
dist = speed * time
|
||
questions.append(make_question(qtid,
|
||
f"A car travels at {speed} km/h for {time} hours. Find the distance covered.",
|
||
str(dist) + " km", nearby_wrong(dist),
|
||
f"Distance = {speed} × {time} = {dist} km", 1))
|
||
return questions
|
||
|
||
|
||
def gen_interest(conn, count=1500):
|
||
questions = []
|
||
qtid = get_qtid(conn, SUBJECT, "Interest", "Simple Interest", "Find SI")
|
||
if qtid:
|
||
for _ in range(count // 3):
|
||
p = random.choice([1000, 2000, 5000, 8000, 10000, 15000, 20000])
|
||
r = random.choice([4, 5, 6, 8, 10, 12, 15])
|
||
t = random.randint(1, 5)
|
||
si = p * r * t // 100
|
||
questions.append(make_question(qtid,
|
||
f"Find the simple interest on ₹{p} at {r}% per annum for {t} years.",
|
||
f"₹{si}", [f"₹{si + i*50}" for i in [1,-2,3]],
|
||
f"SI = {p}×{r}×{t}/100 = ₹{si}", 1))
|
||
|
||
qtid = get_qtid(conn, SUBJECT, "Interest", "Compound Interest", "Find CI")
|
||
if qtid:
|
||
for _ in range(count // 3):
|
||
p = random.choice([1000, 2000, 5000, 10000])
|
||
r = random.choice([5, 10, 15, 20])
|
||
t = random.choice([1, 2, 3])
|
||
amt = round(p * (1 + r/100)**t, 2)
|
||
ci = round(amt - p, 2)
|
||
questions.append(make_question(qtid,
|
||
f"Find the compound interest on ₹{p} at {r}% for {t} year(s).",
|
||
f"₹{ci}", [f"₹{round(ci+i*20,2)}" for i in [1,-2,3]],
|
||
f"CI = {p}(1+{r}/100)^{t} - {p} = ₹{ci}", 2))
|
||
|
||
qtid = get_qtid(conn, SUBJECT, "Interest", "Compound Interest", "Difference between CI and SI")
|
||
if qtid:
|
||
for _ in range(count // 3):
|
||
p = random.choice([1000, 2000, 5000, 10000])
|
||
r = random.choice([5, 10, 15, 20])
|
||
si = p * r * 2 // 100
|
||
ci = round(p * (1 + r/100)**2 - p, 2)
|
||
diff = round(ci - si, 2)
|
||
questions.append(make_question(qtid,
|
||
f"Find the difference between CI and SI on ₹{p} at {r}% for 2 years.",
|
||
f"₹{diff}", [f"₹{round(diff+i*5,2)}" for i in [1,-2,3]],
|
||
f"Diff = P×(r/100)² = {p}×({r}/100)² = ₹{diff}", 2))
|
||
return questions
|
||
|
||
|
||
def gen_algebra(conn, count=2000):
|
||
questions = []
|
||
qtid = get_qtid(conn, SUBJECT, "Algebra", "Linear Equations", "Solve for x")
|
||
if qtid:
|
||
for _ in range(count // 4):
|
||
a = random.randint(2, 15)
|
||
x = random.randint(1, 30)
|
||
b = random.randint(1, 50)
|
||
c = a * x + b
|
||
questions.append(make_question(qtid,
|
||
f"Solve: {a}x + {b} = {c}",
|
||
f"x = {x}", [f"x = {x+i}" for i in [1,-2,3]],
|
||
f"{a}x = {c} - {b} = {c-b}, x = {x}", 1))
|
||
|
||
qtid = get_qtid(conn, SUBJECT, "Algebra", "Algebraic Identities", "Find value of expression")
|
||
if qtid:
|
||
for _ in range(count // 4):
|
||
a, b = random.randint(2, 20), random.randint(1, 15)
|
||
val = a*a + b*b + 2*a*b # (a+b)²
|
||
questions.append(make_question(qtid,
|
||
f"If a = {a} and b = {b}, find a² + b² + 2ab.",
|
||
str(val), nearby_wrong(val),
|
||
f"a² + b² + 2ab = (a+b)² = ({a}+{b})² = {val}", 1))
|
||
|
||
qtid = get_qtid(conn, SUBJECT, "Algebra", "Surds and Indices", "Find value")
|
||
if qtid:
|
||
for _ in range(count // 4):
|
||
base = random.randint(2, 10)
|
||
exp = random.randint(2, 5)
|
||
val = base ** exp
|
||
questions.append(make_question(qtid,
|
||
f"Find the value of {base}^{exp}.",
|
||
str(val), nearby_wrong(val),
|
||
f"{base}^{exp} = {val}", 1))
|
||
|
||
qtid = get_qtid(conn, SUBJECT, "Algebra", "Quadratic Equations", "Sum and product of roots")
|
||
if qtid:
|
||
for _ in range(count // 4):
|
||
r1, r2 = random.randint(-10, 10), random.randint(-10, 10)
|
||
a = 1
|
||
b = -(r1 + r2)
|
||
c = r1 * r2
|
||
s = r1 + r2
|
||
questions.append(make_question(qtid,
|
||
f"Find the sum of roots of x² + ({b})x + ({c}) = 0.",
|
||
str(s), nearby_wrong(s),
|
||
f"Sum = -b/a = {s}", 1))
|
||
return questions
|
||
|
||
|
||
def gen_geometry(conn, count=2000):
|
||
questions = []
|
||
qtid = get_qtid(conn, SUBJECT, "Geometry", "Triangles", "Find angle in triangle")
|
||
if qtid:
|
||
for _ in range(count // 4):
|
||
a = random.randint(20, 80)
|
||
b = random.randint(20, 160 - a)
|
||
c = 180 - a - b
|
||
questions.append(make_question(qtid,
|
||
f"In a triangle, two angles are {a}° and {b}°. Find the third angle.",
|
||
f"{c}°", [f"{c+i}°" for i in [5,-10,15]],
|
||
f"Third angle = 180 - {a} - {b} = {c}°", 1))
|
||
|
||
qtid = get_qtid(conn, SUBJECT, "Geometry", "Circles", "Tangent properties")
|
||
if qtid:
|
||
for _ in range(count // 4):
|
||
r = random.randint(3, 20)
|
||
d = random.randint(r + 5, r + 30)
|
||
tangent = round(math.sqrt(d*d - r*r), 2)
|
||
questions.append(make_question(qtid,
|
||
f"The radius of a circle is {r} cm and a point is {d} cm from the center. Find the length of the tangent.",
|
||
str(tangent) + " cm", [str(round(tangent+i,2)) + " cm" for i in [1,-2,3]],
|
||
f"Tangent = √({d}²-{r}²) = {tangent} cm", 2))
|
||
|
||
qtid = get_qtid(conn, SUBJECT, "Geometry", "Coordinate Geometry", "Find distance between points")
|
||
if qtid:
|
||
for _ in range(count // 4):
|
||
x1, y1 = random.randint(-10, 10), random.randint(-10, 10)
|
||
x2, y2 = random.randint(-10, 10), random.randint(-10, 10)
|
||
dist = round(math.sqrt((x2-x1)**2 + (y2-y1)**2), 2)
|
||
questions.append(make_question(qtid,
|
||
f"Find the distance between ({x1}, {y1}) and ({x2}, {y2}).",
|
||
str(dist), nearby_wrong_float(dist),
|
||
f"Distance = √[({x2}-{x1})² + ({y2}-{y1})²] = {dist}", 2))
|
||
|
||
qtid = get_qtid(conn, SUBJECT, "Geometry", "Lines and Angles", "Find angle value")
|
||
if qtid:
|
||
for _ in range(count // 4):
|
||
angle = random.randint(10, 170)
|
||
supp = 180 - angle
|
||
questions.append(make_question(qtid,
|
||
f"Find the supplement of {angle}°.",
|
||
f"{supp}°", [f"{supp+i}°" for i in [5,-10,15]],
|
||
f"Supplement = 180 - {angle} = {supp}°", 1))
|
||
return questions
|
||
|
||
|
||
def gen_mensuration(conn, count=2000):
|
||
questions = []
|
||
qtid = get_qtid(conn, SUBJECT, "Mensuration", "2D Figures", "Find area")
|
||
if qtid:
|
||
for _ in range(count // 4):
|
||
l, w = random.randint(5, 50), random.randint(5, 50)
|
||
area = l * w
|
||
questions.append(make_question(qtid,
|
||
f"Find the area of a rectangle with length {l} cm and width {w} cm.",
|
||
f"{area} cm²", [f"{area+i*5} cm²" for i in [1,-2,3]],
|
||
f"Area = {l} × {w} = {area} cm²", 1))
|
||
for _ in range(count // 4):
|
||
r = random.randint(3, 25)
|
||
area = round(math.pi * r * r, 2)
|
||
questions.append(make_question(qtid,
|
||
f"Find the area of a circle with radius {r} cm. (Use π = 3.14)",
|
||
str(round(3.14 * r * r, 2)) + " cm²",
|
||
[str(round(3.14 * r * r + i * 5, 2)) + " cm²" for i in [1, -2, 3]],
|
||
f"Area = πr² = 3.14 × {r}² = {round(3.14*r*r,2)} cm²", 1))
|
||
|
||
qtid = get_qtid(conn, SUBJECT, "Mensuration", "3D Figures", "Find volume")
|
||
if qtid:
|
||
for _ in range(count // 4):
|
||
l, w, h = random.randint(3, 20), random.randint(3, 20), random.randint(3, 20)
|
||
vol = l * w * h
|
||
questions.append(make_question(qtid,
|
||
f"Find the volume of a cuboid with dimensions {l}×{w}×{h} cm.",
|
||
f"{vol} cm³", [f"{vol+i*10} cm³" for i in [1,-2,3]],
|
||
f"Volume = {l}×{w}×{h} = {vol} cm³", 1))
|
||
|
||
qtid = get_qtid(conn, SUBJECT, "Mensuration", "3D Figures", "Find surface area")
|
||
if qtid:
|
||
for _ in range(count // 4):
|
||
a = random.randint(3, 20)
|
||
sa = 6 * a * a
|
||
questions.append(make_question(qtid,
|
||
f"Find the total surface area of a cube with side {a} cm.",
|
||
f"{sa} cm²", [f"{sa+i*6} cm²" for i in [1,-2,3]],
|
||
f"TSA = 6a² = 6×{a}² = {sa} cm²", 1))
|
||
return questions
|
||
|
||
|
||
def gen_trigonometry(conn, count=1500):
|
||
questions = []
|
||
trig_vals = {0: {'sin': 0, 'cos': 1, 'tan': 0},
|
||
30: {'sin': 0.5, 'cos': 0.866, 'tan': 0.577},
|
||
45: {'sin': 0.707, 'cos': 0.707, 'tan': 1},
|
||
60: {'sin': 0.866, 'cos': 0.5, 'tan': 1.732},
|
||
90: {'sin': 1, 'cos': 0, 'tan': 'undefined'}}
|
||
|
||
qtid = get_qtid(conn, SUBJECT, "Trigonometry", "Trigonometric Ratios", "Find value of expression")
|
||
if qtid:
|
||
for _ in range(count // 3):
|
||
ang = random.choice([0, 30, 45, 60])
|
||
func = random.choice(['sin', 'cos', 'tan'])
|
||
val = trig_vals[ang][func]
|
||
if isinstance(val, (int, float)):
|
||
questions.append(make_question(qtid,
|
||
f"Find the value of {func}({ang}°).",
|
||
str(val), nearby_wrong_float(val if val != 0 else 0.5),
|
||
f"{func}({ang}°) = {val}", 1))
|
||
|
||
qtid = get_qtid(conn, SUBJECT, "Trigonometry", "Trigonometric Identities", "Find value given condition")
|
||
if qtid:
|
||
for _ in range(count // 3):
|
||
ang = random.choice([30, 45, 60])
|
||
val = trig_vals[ang]['sin']**2 + trig_vals[ang]['cos']**2
|
||
questions.append(make_question(qtid,
|
||
f"Find the value of sin²({ang}°) + cos²({ang}°).",
|
||
"1", ["0", "2", "0.5"],
|
||
f"sin²θ + cos²θ = 1 (identity)", 1))
|
||
|
||
qtid = get_qtid(conn, SUBJECT, "Trigonometry", "Heights and Distances", "Find height of tower")
|
||
if qtid:
|
||
for _ in range(count // 3):
|
||
dist = random.randint(20, 100)
|
||
ang = random.choice([30, 45, 60])
|
||
height = round(dist * trig_vals[ang]['tan'], 2) if ang != 90 else dist
|
||
questions.append(make_question(qtid,
|
||
f"From a point {dist}m from the base of a tower, the angle of elevation is {ang}°. Find the height.",
|
||
str(height) + " m", [str(round(height+i,2)) + " m" for i in [2,-5,8]],
|
||
f"h = {dist} × tan({ang}°) = {height} m", 2))
|
||
return questions
|
||
|
||
|
||
def gen_di(conn, count=1500):
|
||
questions = []
|
||
qtid = get_qtid(conn, SUBJECT, "Data Interpretation", "Table", "Calculate from table")
|
||
if qtid:
|
||
for _ in range(count // 2):
|
||
vals = [random.randint(100, 1000) for _ in range(5)]
|
||
total = sum(vals)
|
||
avg = round(total / 5, 2)
|
||
years = ["2019", "2020", "2021", "2022", "2023"]
|
||
table = ", ".join(f"{y}: {v}" for y, v in zip(years, vals))
|
||
questions.append(make_question(qtid,
|
||
f"Production (in units) - {table}. Find the total production.",
|
||
str(total), nearby_wrong(total),
|
||
f"Total = {'+'.join(map(str, vals))} = {total}", 1))
|
||
|
||
qtid = get_qtid(conn, SUBJECT, "Data Interpretation", "Table", "Percentage calculation")
|
||
if qtid:
|
||
for _ in range(count // 2):
|
||
vals = [random.randint(100, 1000) for _ in range(5)]
|
||
idx = random.randint(0, 4)
|
||
total = sum(vals)
|
||
pct = round(vals[idx] * 100 / total, 2)
|
||
years = ["2019", "2020", "2021", "2022", "2023"]
|
||
table = ", ".join(f"{y}: {v}" for y, v in zip(years, vals))
|
||
questions.append(make_question(qtid,
|
||
f"Sales - {table}. What percentage of total sales occurred in {years[idx]}?",
|
||
str(pct) + "%", [str(round(pct+i,2)) + "%" for i in [2,-3,5]],
|
||
f"{vals[idx]}/{total} × 100 = {pct}%", 2))
|
||
return questions
|
||
|
||
|
||
def gen_statistics(conn, count=800):
|
||
questions = []
|
||
qtid = get_qtid(conn, SUBJECT, "Statistics", "Mean, Median and Mode", "Find mean")
|
||
if qtid:
|
||
for _ in range(count // 3):
|
||
n = random.randint(5, 10)
|
||
nums = sorted([random.randint(1, 100) for _ in range(n)])
|
||
mean = round(sum(nums) / n, 2)
|
||
questions.append(make_question(qtid,
|
||
f"Find the mean of: {', '.join(map(str, nums))}",
|
||
str(mean), nearby_wrong_float(mean),
|
||
f"Mean = {sum(nums)}/{n} = {mean}", 1))
|
||
|
||
qtid = get_qtid(conn, SUBJECT, "Statistics", "Mean, Median and Mode", "Find median")
|
||
if qtid:
|
||
for _ in range(count // 3):
|
||
n = random.choice([5, 7, 9])
|
||
nums = sorted([random.randint(1, 100) for _ in range(n)])
|
||
median = nums[n // 2]
|
||
questions.append(make_question(qtid,
|
||
f"Find the median of: {', '.join(map(str, nums))}",
|
||
str(median), nearby_wrong(median),
|
||
f"Sorted: {nums}, Median = {median}", 1))
|
||
|
||
qtid = get_qtid(conn, SUBJECT, "Statistics", "Mean, Median and Mode", "Find mode")
|
||
if qtid:
|
||
for _ in range(count // 3):
|
||
mode_val = random.randint(1, 50)
|
||
nums = [mode_val] * 3 + [random.randint(1, 100) for _ in range(4)]
|
||
random.shuffle(nums)
|
||
questions.append(make_question(qtid,
|
||
f"Find the mode of: {', '.join(map(str, nums))}",
|
||
str(mode_val), nearby_wrong(mode_val),
|
||
f"Mode = {mode_val} (appears most)", 1))
|
||
return questions
|
||
|
||
|
||
def generate_all(conn):
|
||
"""Generate all Quantitative Aptitude questions."""
|
||
generators = [
|
||
("Number System", gen_number_system, 800),
|
||
("HCF/LCM", gen_hcf_lcm, 500),
|
||
("Simplification", gen_simplification, 600),
|
||
("Percentage", gen_percentage, 2500),
|
||
("Profit & Loss", gen_profit_loss, 2500),
|
||
("Ratio & Proportion", gen_ratio, 2200),
|
||
("Average", gen_average, 1500),
|
||
("Time & Work", gen_time_work, 1800),
|
||
("Speed & Distance", gen_speed_distance, 2500),
|
||
("Interest", gen_interest, 2000),
|
||
("Algebra", gen_algebra, 2500),
|
||
("Geometry", gen_geometry, 2500),
|
||
("Mensuration", gen_mensuration, 2500),
|
||
("Trigonometry", gen_trigonometry, 2000),
|
||
("Data Interpretation", gen_di, 2000),
|
||
("Statistics", gen_statistics, 1200),
|
||
]
|
||
|
||
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)
|
||
|
||
# Insert in batches
|
||
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 Quantitative Aptitude: {total}")
|
||
return total
|
||
|
||
|
||
if __name__ == '__main__':
|
||
conn = get_db()
|
||
print("Generating Quantitative Aptitude questions...")
|
||
generate_all(conn)
|
||
conn.close()
|