#!/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()