Turbiling commited on
Commit
580be88
·
verified ·
1 Parent(s): 7b8cb98

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +66 -340
app.py CHANGED
@@ -1,325 +1,81 @@
1
- # app.py
2
  import os
3
- import re
4
- import random
5
  import gradio as gr
6
  from groq import Groq
7
  from datetime import datetime
8
  from docx import Document
9
  from docx.shared import Pt, RGBColor
10
  from docx.enum.text import WD_ALIGN_PARAGRAPH
 
 
11
 
12
- # ---------------------------
13
- # Initialize GROQ client (reads API key from env variable)
14
- # ---------------------------
15
  GROQ_API_KEY = os.getenv("GROQ_API_KEY")
16
  client = Groq(api_key=GROQ_API_KEY)
17
 
18
- # ---------------------------
19
- # Grades and subjects (UI choices)
20
- # ---------------------------
21
  grades = [f"Grade {i}" for i in range(1, 13)]
22
- subjects_by_grade = {
23
- "Grade 1": ["Mathematics", "English", "Urdu", "Islamiyat", "General Knowledge"],
24
- "Grade 2": ["Mathematics", "English", "Urdu", "Islamiyat", "General Knowledge"],
25
- "Grade 3": ["Mathematics", "English", "Urdu", "Science", "Islamiyat", "General Knowledge"],
26
- "Grade 4": ["Mathematics", "English", "Urdu", "Science", "Islamiyat", "Social Studies"],
27
- "Grade 5": ["Mathematics", "English", "Urdu", "Science", "Islamiyat", "Social Studies"],
28
- "Grade 6": ["Mathematics", "English", "Urdu", "Science", "Islamiyat", "Social Studies"],
29
- "Grade 7": ["Mathematics", "English", "Urdu", "Science", "Islamiyat", "Social Studies", "Computer"],
30
- "Grade 8": ["Mathematics", "English", "Urdu", "Science", "Islamiyat", "Social Studies", "Computer"],
31
- "Grade 9": ["Mathematics", "English", "Urdu", "Biology", "Chemistry", "Physics", "Islamiyat", "Pakistan Studies", "Computer"],
32
- "Grade 10": ["Mathematics", "English", "Urdu", "Biology", "Chemistry", "Physics", "Islamiyat", "Pakistan Studies", "Computer"],
33
- "Grade 11": ["Mathematics", "English", "Urdu", "Biology", "Chemistry", "Physics", "Computer", "Islamiyat", "Pakistan Studies"],
34
- "Grade 12": ["Mathematics", "English", "Urdu", "Biology", "Chemistry", "Physics", "Computer", "Islamiyat", "Pakistan Studies"]
35
- }
36
 
37
- # ---------------------------
38
- # Chapters by subject and grade (complete, 1-12)
39
- # Based on National Curriculum (2006) where available.
40
- # For Grades 9-10 biological/chem/phys/pkstudies, kept your exact lists.
41
- # For Grades 1-8 and other subjects, chapter/unit headings derive from curriculum SLO groupings.
42
- # ---------------------------
43
- chapters_by_subject_and_grade = {
44
- # ---------- Grades 1-5 (competency-based curriculum — grouped into practical unit headings) ----------
45
- "Grade 1": {
46
- "Mathematics": ["Counting & Number Recognition", "Basic Addition", "Basic Subtraction", "Shapes & Space", "Measurement (Length, Weight)"],
47
- "English": ["Alphabet & Phonics", "Listening & Speaking", "Basic Vocabulary", "Simple Sentences", "Early Reading"],
48
- "Urdu": ["حروف اور آوازیں", "الفاظ", "سادہ جملے", "پڑھائی کا تعارف", "چھوٹی کہانیاں"],
49
- "Islamiyat": ["Iman Basics", "Prophets' Stories (selected)", "Good Manners", "Simple Prayers & Worship"],
50
- "General Knowledge": ["My Home & Family", "Plants & Animals", "Seasons & Weather", "My School"]
51
- },
52
- "Grade 2": {
53
- "Mathematics": ["Place Value", "Addition & Subtraction Facts", "Money", "Time (clock)", "Basic Shapes"],
54
- "English": ["Reading Short Texts", "Simple Grammar (nouns, verbs)", "Vocabulary Building", "Speaking Activities"],
55
- "Urdu": ["روزمرہ الفاظ", "مختصر کہانیاں", "قرأتِ آسان"],
56
- "Islamiyat": ["Stories of Prophets", "Good Deeds", "Worship Basics"],
57
- "General Knowledge": ["Local Community", "Transportation & Safety", "Plants & Animals"]
58
- },
59
- "Grade 3": {
60
- "Mathematics": ["Multiplication & Division", "Fractions (intro)", "Geometry Basics", "Measurement", "Patterns"],
61
- "English": ["Tenses (simple)", "Comprehension Passages", "Vocabulary Development", "Sentence Writing"],
62
- "Urdu": ["قواعد كا تعارف", "کہیں کہانیاں"],
63
- "Science": ["Plants & Animals", "Human Body (basic)", "Materials & Uses"],
64
- "Islamiyat": ["Seerat Stories & Morals", "Basic Akhlaq"]
65
- },
66
- "Grade 4": {
67
- "Mathematics": ["Fractions & Decimals (intro)", "Geometry (angles, shapes)", "Data & Graphs", "Word Problems"],
68
- "English": ["Grammar (parts of speech)", "Paragraph Writing", "Comprehension", "Listening & Speaking"],
69
- "Urdu": ["نظم و نثر کا مطالعہ", "قواعد"],
70
- "Science": ["Ecosystems", "Forces & Simple Machines", "Heat & Energy"],
71
- "Islamiyat": ["Pillars of Islam", "Seerah Highlights"],
72
- "Social Studies": ["Local Geography", "Community & Careers", "Citizenship"]
73
- },
74
- "Grade 5": {
75
- "Mathematics": ["Number Operations", "Percentage & Ratio (intro)", "Geometry & Area", "Statistics (intro)"],
76
- "English": ["Advanced Comprehension", "Essay & Letter Writing", "Grammar Consolidation"],
77
- "Urdu": ["ادبی مطالعہ اور تحریر", "قواعد"],
78
- "Science": ["Cells (intro)", "Matter & its Properties", "Energy & Sound"],
79
- "Islamiyat": ["Quranic Stories & Morals"],
80
- "Social Studies": ["History (local & national)", "Map Skills", "Basic Economics"]
81
- },
82
 
83
- # ---------- Grades 6-8 ----------
84
- "Grade 6": {
85
- "Mathematics": ["Number System & Factors", "Algebraic Expressions (intro)", "Geometry Basics", "Data Handling"],
86
- "English": ["Grammar & Usage", "Comprehension", "Writing Paragraphs", "Poetry & Prose"],
87
- "Urdu": ["نثر و نظم", "قواعد ِاردو", "تحریر"],
88
- "Science": ["Atoms & Molecules (intro)", "Human Body Systems", "Plants & Ecology"],
89
- "Islamiyat": ["Seerah & Ahkam (intro)"],
90
- "Social Studies": ["Physical Geography", "Early Civilizations", "Citizenship"]
91
- },
92
- "Grade 7": {
93
- "Mathematics": ["Algebra (linear)", "Geometry (polygons, areas)", "Mensuration", "Graphs"],
94
- "English": ["Advanced Grammar", "Comprehension Passages", "Composition"],
95
- "Urdu": ["ادبی اور تنقیدی مطالعہ", "قواعد"],
96
- "Science": ["Cell Biology", "Electricity & Magnetism (basic)", "Properties of Matter"],
97
- "Islamiyat": ["Islamic History & Ethics"],
98
- "Social Studies": ["Regional Geography", "Historical Events & Movements"],
99
- "Computer": ["ICT Basics", "Introductory Coding Concepts"]
100
- },
101
- "Grade 8": {
102
- "Mathematics": ["Linear Equations & Inequalities", "Coordinate Geometry", "Pythagoras & Trigonometry (intro)", "Probability"],
103
- "English": ["Critical Reading", "Extended Writing", "Grammar Review"],
104
- "Urdu": ["ادبی تنقید", "تحریر"],
105
- "Science": ["Forces & Motion", "Heat & Temperature", "Waves & Optics (intro)"],
106
- "Islamiyat": ["Fiqh Basics & Seerah"],
107
- "Social Studies": ["Civics & Government", "Economic Concepts"],
108
- "Computer": ["Algorithms & Flowcharts", "Application Software"]
109
- },
110
 
111
- # ---------- Grade 9 (kept as you provided earlier for science subjects) ----------
 
112
  "Grade 9": {
113
- "Mathematics": ["Number Systems & Algebra", "Coordinate Geometry", "Trigonometry", "Graphs"],
114
- "English": ["Advanced Grammar", "Comprehension", "Writing Skills"],
115
- "Urdu": ["ادب اور نثر", "نظم", "مضامین"],
116
  "Biology": [
117
- "INTRODUCTION TO BIOLOGY",
118
- "SOLVING A BIOLOGICAL PROBLEM",
119
- "BIODIVERSITY",
120
- "CELLS AND TISSUES",
121
- "CELL CYCLE",
122
- "ENZYMES",
123
- "BIOENERGETICS",
124
- "NUTRITION",
125
- "TRANSPORT"
126
  ],
127
  "Chemistry": [
128
- "FUNDAMENTALS OF CHEMISTRY",
129
- "STRUCTURE OF ATOMS",
130
- "PERIODIC TABLE AND PERIODICITY OF PROPERTIES",
131
- "STRUCTURE OF MOLECULES",
132
- "PHYSICAL STATES OF MATTER",
133
- "SOLUTIONS",
134
- "ELECTROCHEMISTRY",
135
- "CHEMICAL REACTIVITY"
136
  ],
137
  "Physics": [
138
- "PHYSICAL QUANTITIES AND MEASUREMENT",
139
- "KINEMATICS",
140
- "DYNAMICS",
141
- "TURNING EFFECT OF FORCES",
142
- "GRAVITATION",
143
- "WORK AND ENERGY",
144
- "PROPERTIES OF MATTER",
145
- "THERMAL PROPERTIES OF MATTER",
146
- "TRANSFER OF HEAT"
147
  ],
148
- "Islamiyat": ["Seerat of Prophet", "Faith & Beliefs", "Worship Practices"],
149
  "Pakistan Studies": [
150
- "IDEOLOGICAL BASIS OF PAKISTAN",
151
- "MAKING OF PAKISTAN",
152
- "LAND AND ENVIRONMENT",
153
- "HISTORY OF PAKISTAN"
154
  ],
155
- "Computer": ["Fundamentals of Computing", "ICT Applications"]
 
 
156
  },
157
-
158
- # ---------- Grade 10 (kept as you provided earlier for science subjects) ----------
159
  "Grade 10": {
160
- "Mathematics": ["Advanced Algebra", "Trigonometry", "Geometry", "Probability"],
161
- "English": ["Literature", "Advanced Composition", "Comprehension"],
162
- "Urdu": ["ادبِ جدید", "تحقیقی مضمون"],
163
  "Biology": [
164
- "GASEOUS EXCHANGE",
165
- "HOMEOSTASIS",
166
- "COORDINATION",
167
- "SUPPORT AND MOVEMENT",
168
- "REPRODUCTION",
169
- "INHERITANCE",
170
- "MAN AND HIS ENVIRONMENT",
171
- "BIOTECHNOLOGY",
172
- "PHARMA"
173
  ],
174
  "Chemistry": [
175
- "CHEMICAL EQUILIBRIUM",
176
- "ACIDS, BASES AND SALTS",
177
- "ORGANIC CHEMISTRY",
178
- "HYDROCARBONS",
179
- "BIOCHEMISTRY",
180
- "ENVIRONMENTAL CHEMISTRY I: THE ATMOSPHERE",
181
- "ENVIRONMENTAL CHEMISTRY II: WATER",
182
- "CHEMICAL INDUSTRIES"
183
  ],
184
  "Physics": [
185
- "SIMPLE HARMONIC MOTION AND WAVES",
186
- "SOUND",
187
- "GEOMETRICAL OPTICS",
188
- "ELECTROSTATICS",
189
- "CURRENT ELECTRICITY",
190
- "ELECTROMAGNETISM",
191
- "INTRODUCTORY ELECTRONICS",
192
- "INFORMATION AND COMMUNICATION TECHNOLOGY",
193
- "RADIOACTIVITY"
194
  ],
195
- "Islamiyat": ["Islamic Studies II", "Ethics & Society", "Fiqh Basics"],
196
  "Pakistan Studies": [
197
- "HISTORY OF PAKISTAN-II",
198
- "PAKISTAN IN WORLD AFFAIRS",
199
- "ECONOMIC DEVELOPMENTS",
200
  "POPULATION, SOCIETY AND CULTURE OF PAKISTAN"
201
  ],
202
- "Computer": ["Programming Basics", "ICT in Society"]
203
- },
204
-
205
- # ---------- Grade 11 (Higher Secondary — XI) ----------
206
- "Grade 11": {
207
- "Mathematics": ["Advanced Algebra & Calculus Intro", "Coordinate Geometry", "Trigonometry", "Vectors"],
208
- "English": ["Academic Writing", "Literature Studies", "Critical Reading"],
209
- "Urdu": ["ادبی مطالعہ", "نظم و نثر کی تشریح"],
210
- "Biology": [
211
- "Cell Structure and Functions",
212
- "Biological Molecules",
213
- "Enzymes",
214
- "Bioenergetics",
215
- "Acellular Life & Microorganisms",
216
- "Diversity of Plants",
217
- "Diversity of Animals",
218
- "Plant Form and Function",
219
- "Digestion and Nutrition",
220
- "Circulation and Respiration",
221
- "Immunity"
222
- ],
223
- "Chemistry": [
224
- "Stoichiometry & Chemical Calculations",
225
- "Atomic Structure & Periodicity",
226
- "Bonding & Molecular Shape",
227
- "States of Matter (Gases, Liquids, Solids)",
228
- "Solutions & Colligative Properties",
229
- "Thermochemistry",
230
- "Chemical Kinetics",
231
- "Electrochemistry & Redox"
232
- ],
233
- "Physics": [
234
- "Measurement & Vectors",
235
- "Forces & Motion",
236
- "Work & Energy",
237
- "Rotational Motion",
238
- "Fluid Mechanics",
239
- "Oscillations & Waves",
240
- "Geometrical Optics",
241
- "Thermodynamics",
242
- "Electrostatics",
243
- "Current Electricity"
244
- ],
245
- "Computer": ["Programming Fundamentals", "Data Structures Intro", "Databases & File Systems"],
246
- "Islamiyat": ["Advanced Seerah", "Islamic Ethics"],
247
- "Pakistan Studies": [
248
- "Pakistan in Geographical Perspective",
249
- "Resources & Economy",
250
- "Historical Overview",
251
- "Political & Constitutional Development",
252
- "Human Rights & Citizenship"
253
- ]
254
  },
255
-
256
- # ---------- Grade 12 (Higher Secondary — XII) ----------
257
- "Grade 12": {
258
- "Mathematics": ["Calculus", "Advanced Algebra", "Statistics", "Analytical Geometry"],
259
- "English": ["Research Writing", "Advanced Literature", "Critical Analysis"],
260
- "Urdu": ["تحقیق و تنقید", "ادبی شخصیات"],
261
- "Biology": [
262
- "Respiration & Exchange",
263
- "Homeostasis & Coordination (Nervous & Chemical)",
264
- "Support, Movement & Musculoskeletal System",
265
- "Reproduction & Development",
266
- "Genetics & Inheritance",
267
- "Evolution & Biodiversity",
268
- "Man and His Environment",
269
- "Biotechnology & Its Applications",
270
- "Biology and Human Welfare"
271
- ],
272
- "Chemistry": [
273
- "s and p Block Elements",
274
- "d Block & Transition Elements",
275
- "Organic Reaction Mechanisms",
276
- "Hydrocarbons & Functional Groups",
277
- "Alcohols, Phenols, Ethers",
278
- "Aldehydes & Ketones",
279
- "Carboxylic Acids & Derivatives",
280
- "Biochemistry (Carbohydrates, Proteins, Lipids)",
281
- "Analytical & Industrial Chemistry",
282
- "Environmental Chemistry"
283
- ],
284
- "Physics": [
285
- "Electromagnetism & EM Induction",
286
- "Alternating Current Circuits",
287
- "Electronics & Semiconductors",
288
- "Atomic & Nuclear Physics",
289
- "Modern Physics Topics",
290
- "Optics & Waves (advanced)"
291
- ],
292
- "Computer": ["Advanced Programming Concepts", "Web Technologies & Networks"],
293
- "Islamiyat": ["Islamic Jurisprudence (Fiqh)", "Contemporary Islamic Thought"],
294
- "Pakistan Studies": [
295
- "Society & Culture",
296
- "Foreign Relations",
297
- "Economic Policies & Development",
298
- "Contemporary Challenges & National Identity"
299
- ]
300
- }
301
  }
302
 
303
- # ---------------------------
304
- # Mediums (kept English as before)
305
- # ---------------------------
306
- mediums = ["English"]
307
-
308
- # ---------------------------
309
- # MCQ generation function: uses grade, subject, chapter, difficulty, and num_questions
310
- # Behavior otherwise remains same (GROQ model call, parsing, docx export)
311
- # ---------------------------
312
  def generate_mcqs(grade, subject, chapter, difficulty, num_questions):
313
- system_msg = "You are an expert educational test developer. Follow instructions strictly."
314
- user_msg = (
315
- f"Create {num_questions} MCQs for {grade} - {subject} - Chapter: '{chapter}'.\n"
316
- f"Difficulty: {difficulty}.\n\n"
317
- "Rules:\n"
318
- "- ONLY output the MCQ items (numbered). For each MCQ provide stem and four options labeled A, B, C, D.\n"
319
- "- At the end, provide an 'Answer Key' table listing question numbers and correct option letters.\n"
320
- "- Do NOT include any other explanatory or introductory text.\n"
321
- "- Align questions with the Pakistani National Curriculum (2006) learning outcomes for this grade.\n"
322
- )
323
 
324
  response = client.chat.completions.create(
325
  messages=[
@@ -330,29 +86,23 @@ def generate_mcqs(grade, subject, chapter, difficulty, num_questions):
330
  )
331
 
332
  text = response.choices[0].message.content
333
- # Parse MCQs roughly by splitting on question numbers like "1." or newline number.
334
- mcqs = re.split(r'\n\s*\d+\s*\.', text)
335
  mcqs = [q.strip() for q in mcqs if q.strip()]
 
 
336
 
337
- # Keep your previous behavior: if generation returns fewer questions, still handle gracefully
338
- # Random answer key (demo) — leave unchanged to preserve behavior
339
- answer_key = [random.choice(["A", "B", "C", "D"]) for _ in mcqs]
340
-
341
- return mcqs[:num_questions], answer_key[:num_questions], text
342
 
343
- # ---------------------------
344
- # DOCX export (MS Word) — unchanged layout but includes difficulty & MCQ count
345
- # ---------------------------
346
  def export_to_word(mcqs, answers, grade, subject, chapter, difficulty, num_questions):
347
  doc = Document()
348
-
349
  heading = doc.add_heading("WEEKLY/MONTHLY TEST", level=1)
350
  heading.alignment = WD_ALIGN_PARAGRAPH.CENTER
351
  run = heading.runs[0]
352
  run.bold = True
353
- run.font.color.rgb = RGBColor(0, 128, 0)
354
  run.font.size = Pt(18)
355
 
 
356
  table = doc.add_table(rows=6, cols=2)
357
  table.style = 'Table Grid'
358
  info = [
@@ -368,84 +118,60 @@ def export_to_word(mcqs, answers, grade, subject, chapter, difficulty, num_quest
368
  row.cells[1].text = value
369
  row.cells[0].paragraphs[0].runs[0].bold = True
370
 
371
- doc.add_paragraph("") # spacing
372
-
373
- # Add MCQs
374
  for i, q in enumerate(mcqs, start=1):
375
  p = doc.add_paragraph(f"{i}. {q}")
376
  p.alignment = WD_ALIGN_PARAGRAPH.LEFT
377
 
378
- # Answer key table
379
  doc.add_paragraph("\nAnswer Key:")
380
- rows_needed = max(1, len(answers) + 1)
381
- ans_table = doc.add_table(rows=rows_needed, cols=5)
382
  ans_table.style = 'Table Grid'
383
  headers = ["Q#", "A", "B", "C", "D"]
384
- for idx, text_h in enumerate(headers):
385
- ans_table.cell(0, idx).text = text_h
386
  ans_table.cell(0, idx).paragraphs[0].runs[0].bold = True
387
 
388
  for r, ans in enumerate(answers, start=1):
389
- if r >= ans_table.rows:
390
- # extend table if necessary
391
- ans_table.add_row()
392
  ans_table.cell(r, 0).text = str(r)
393
- for c, option in enumerate(["A", "B", "C", "D"], start=1):
394
- ans_table.cell(r, c).text = "✔" if ans == option else ""
395
 
396
- safe_chapter = re.sub(r'[\\/*?:"<>|]', "_", chapter)
397
- file_path = f"{grade}_{subject}_{safe_chapter}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.docx"
398
  doc.save(file_path)
399
  return file_path
400
 
401
- # ---------------------------
402
- # Handler called by the UI
403
- # ---------------------------
404
  def on_generate(grade, subject, chapter, difficulty, num_questions):
405
- if not (grade and subject and chapter):
406
- return "Please select Grade, Subject, and Chapter.", None
407
-
408
- mcqs, answers, raw_text = generate_mcqs(grade, subject, chapter, difficulty, num_questions)
409
  file_path = export_to_word(mcqs, answers, grade, subject, chapter, difficulty, num_questions)
410
  return f"Test ready: {file_path}", file_path
411
 
412
- # ---------------------------
413
  # Gradio UI
414
- # ---------------------------
415
  with gr.Blocks() as demo:
416
- gr.Markdown("### **MCQ Test Generator — National Curriculum (2006) — Grades 1–12**")
417
  with gr.Row():
418
  grade_dropdown = gr.Dropdown(choices=grades, label="Select Grade")
419
  subject_dropdown = gr.Dropdown(choices=[], label="Select Subject")
420
  chapter_dropdown = gr.Dropdown(choices=[], label="Select Chapter")
421
-
422
- difficulty_dropdown = gr.Dropdown(
423
- choices=["Absolute Beginner (Pretest)", "Intermediate", "Advanced"],
424
- value="Intermediate",
425
- label="Select Difficulty Level"
426
- )
427
-
428
- num_questions_slider = gr.Slider(minimum=5, maximum=60, step=1, value=20, label="Number of MCQs")
429
-
430
  generate_btn = gr.Button("Generate Test")
431
- output_text = gr.Textbox(label="Status / Generated MCQs (preview)", lines=18)
432
- output_file = gr.File(label="Download Test (.docx)")
433
 
434
  def update_subjects(selected_grade):
435
- return gr.update(choices=subjects_by_grade.get(selected_grade, []), value=None)
 
436
 
437
  def update_chapters(selected_subject, selected_grade):
438
- chapters = chapters_by_subject_and_grade.get(selected_grade, {}).get(selected_subject, [])
439
- return gr.update(choices=chapters, value=None)
440
-
441
- grade_dropdown.change(update_subjects, inputs=grade_dropdown, outputs=subject_dropdown)
442
  subject_dropdown.change(update_chapters, inputs=[subject_dropdown, grade_dropdown], outputs=chapter_dropdown)
443
- grade_dropdown.change(update_chapters, inputs=[subject_dropdown, grade_dropdown], outputs=chapter_dropdown)
444
 
445
  generate_btn.click(
446
- on_generate,
447
- inputs=[grade_dropdown, subject_dropdown, chapter_dropdown, difficulty_dropdown, num_questions_slider],
448
  outputs=[output_text, output_file]
449
  )
450
 
451
- demo.launch(share=True, ssr_mode=False)
 
 
1
  import os
 
 
2
  import gradio as gr
3
  from groq import Groq
4
  from datetime import datetime
5
  from docx import Document
6
  from docx.shared import Pt, RGBColor
7
  from docx.enum.text import WD_ALIGN_PARAGRAPH
8
+ import re
9
+ import random
10
 
11
+ # Initialize GROQ client
 
 
12
  GROQ_API_KEY = os.getenv("GROQ_API_KEY")
13
  client = Groq(api_key=GROQ_API_KEY)
14
 
15
+ # Grades
 
 
16
  grades = [f"Grade {i}" for i in range(1, 13)]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
 
18
+ # Difficulty levels
19
+ difficulty_levels = ["Pretest (Beginner)", "Intermediate", "Advanced"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
 
21
+ # MCQ count range
22
+ min_mcq, max_mcq = 5, 50
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
 
24
+ # Example chapters database (fill official chapters later)
25
+ chapters_by_grade_subject = {
26
  "Grade 9": {
 
 
 
27
  "Biology": [
28
+ "INTRODUCTION TO BIOLOGY","SOLVING A BIOLOGICAL PROBLEM","BIODIVERSITY",
29
+ "CELLS AND TISSUES","CELL CYCLE","ENZYMES","BIOENERGETICS",
30
+ "NUTRITION","TRANSPORT"
 
 
 
 
 
 
31
  ],
32
  "Chemistry": [
33
+ "FUNDAMENTALS OF CHEMISTRY","STRUCTURE OF ATOMS","PERIODIC TABLE AND PERIODICITY OF PROPERTIES",
34
+ "STRUCTURE OF MOLECULES","PHYSICAL STATES OF MATTER","SOLUTIONS",
35
+ "ELECTROCHEMISTRY","CHEMICAL REACTIVITY"
 
 
 
 
 
36
  ],
37
  "Physics": [
38
+ "PHYSICAL QUANTITIES AND MEASUREMENT","KINEMATICS","DYNAMICS",
39
+ "Turning Effect of Forces","GRAVITATION","WORK AND ENERGY",
40
+ "PROPERTIES OF MATTER","THERMAL PROPERTIES OF MATTER","TRANSFER OF HEAT"
 
 
 
 
 
 
41
  ],
 
42
  "Pakistan Studies": [
43
+ "IDEOLOGICAL BASIS OF PAKISTAN","MAKING OF PAKISTAN",
44
+ "LAND AND ENVIRONMENT","HISTORY OF PAKISTAN"
 
 
45
  ],
46
+ "Mathematics": ["Chapter 1", "Chapter 2"], # Placeholder
47
+ "English": ["Chapter 1", "Chapter 2"],
48
+ "Urdu": ["Chapter 1", "Chapter 2"]
49
  },
 
 
50
  "Grade 10": {
 
 
 
51
  "Biology": [
52
+ "GASEOUS EXCHANGE","HOMEOSTASIS","COORDINATION","SUPPORT AND MOVEMENT",
53
+ "REPRODUCTION","INHERITANCE","MAN AND HIS ENVIRONMENT","BIOTECHNOLOGY","PHARMA"
 
 
 
 
 
 
 
54
  ],
55
  "Chemistry": [
56
+ "CHEMICAL EQUILIBRIUM","ACIDS, BASES AND SALTS","ORGANIC CHEMISTRY",
57
+ "HYDROCARBONS","BIOCHEMISTRY","ENVIRONMENTAL CHEMISTRY I: THE ATMOSPHERE",
58
+ "ENVIRONMENTAL CHEMISTRY II: WATER","CHEMICAL INDUSTRIES"
 
 
 
 
 
59
  ],
60
  "Physics": [
61
+ "SIMPLE HARMONIC MOTION AND WAVES","SOUND","GEOMETRICAL OPTICS","ELECTROSTATICS",
62
+ "CURRENT ELECTRICITY","ELECTROMAGNETISM","INTRODUCTORY ELECTRONICS",
63
+ "INFORMATION AND COMMUNICATION TECHNOLOGY","RADIOACTIVITY"
 
 
 
 
 
 
64
  ],
 
65
  "Pakistan Studies": [
66
+ "HISTORY OF PAKISTAN-II","PAKISTAN IN WORLD AFFAIRS","ECONOMIC DEVELOPMENTS",
 
 
67
  "POPULATION, SOCIETY AND CULTURE OF PAKISTAN"
68
  ],
69
+ "Mathematics": ["Chapter 1", "Chapter 2"], # Placeholder
70
+ "English": ["Chapter 1", "Chapter 2"],
71
+ "Urdu": ["Chapter 1", "Chapter 2"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  },
73
+ # Placeholder for other grades (1–8, 11–12)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  }
75
 
 
 
 
 
 
 
 
 
 
76
  def generate_mcqs(grade, subject, chapter, difficulty, num_questions):
77
+ system_msg = "You are an educational expert. Generate MCQs strictly aligned with the Pakistani National Curriculum."
78
+ user_msg = f"Create {num_questions} MCQs for {grade} {subject} on the chapter '{chapter}' at '{difficulty}' level. Each question must have 4 options. Provide answer key separately."
 
 
 
 
 
 
 
 
79
 
80
  response = client.chat.completions.create(
81
  messages=[
 
86
  )
87
 
88
  text = response.choices[0].message.content
89
+ mcqs = re.split(r'\n?\d+\.', text)
 
90
  mcqs = [q.strip() for q in mcqs if q.strip()]
91
+ # Random answers as placeholder
92
+ answer_key = [random.choice(["A","B","C","D"]) for _ in mcqs]
93
 
94
+ return mcqs[:num_questions], answer_key[:num_questions]
 
 
 
 
95
 
 
 
 
96
  def export_to_word(mcqs, answers, grade, subject, chapter, difficulty, num_questions):
97
  doc = Document()
 
98
  heading = doc.add_heading("WEEKLY/MONTHLY TEST", level=1)
99
  heading.alignment = WD_ALIGN_PARAGRAPH.CENTER
100
  run = heading.runs[0]
101
  run.bold = True
102
+ run.font.color.rgb = RGBColor(0,128,0)
103
  run.font.size = Pt(18)
104
 
105
+ # Info table
106
  table = doc.add_table(rows=6, cols=2)
107
  table.style = 'Table Grid'
108
  info = [
 
118
  row.cells[1].text = value
119
  row.cells[0].paragraphs[0].runs[0].bold = True
120
 
121
+ # MCQs
 
 
122
  for i, q in enumerate(mcqs, start=1):
123
  p = doc.add_paragraph(f"{i}. {q}")
124
  p.alignment = WD_ALIGN_PARAGRAPH.LEFT
125
 
126
+ # Answer Key
127
  doc.add_paragraph("\nAnswer Key:")
128
+ ans_table = doc.add_table(rows=num_questions+1, cols=5)
 
129
  ans_table.style = 'Table Grid'
130
  headers = ["Q#", "A", "B", "C", "D"]
131
+ for idx, text in enumerate(headers):
132
+ ans_table.cell(0, idx).text = text
133
  ans_table.cell(0, idx).paragraphs[0].runs[0].bold = True
134
 
135
  for r, ans in enumerate(answers, start=1):
 
 
 
136
  ans_table.cell(r, 0).text = str(r)
137
+ for c, option in enumerate(["A","B","C","D"], start=1):
138
+ ans_table.cell(r, c).text = "✔" if ans==option else ""
139
 
140
+ file_path = f"{grade}_{subject}_{chapter}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.docx"
 
141
  doc.save(file_path)
142
  return file_path
143
 
 
 
 
144
  def on_generate(grade, subject, chapter, difficulty, num_questions):
145
+ mcqs, answers = generate_mcqs(grade, subject, chapter, difficulty, num_questions)
 
 
 
146
  file_path = export_to_word(mcqs, answers, grade, subject, chapter, difficulty, num_questions)
147
  return f"Test ready: {file_path}", file_path
148
 
 
149
  # Gradio UI
 
150
  with gr.Blocks() as demo:
151
+ gr.Markdown("### **MCQ Test Generator - Developer: Najaf Ali Sharqi**")
152
  with gr.Row():
153
  grade_dropdown = gr.Dropdown(choices=grades, label="Select Grade")
154
  subject_dropdown = gr.Dropdown(choices=[], label="Select Subject")
155
  chapter_dropdown = gr.Dropdown(choices=[], label="Select Chapter")
156
+ with gr.Row():
157
+ difficulty_dropdown = gr.Dropdown(choices=difficulty_levels, label="Select Difficulty")
158
+ num_mcq_slider = gr.Slider(minimum=min_mcq, maximum=max_mcq, value=20, step=1, label="Number of MCQs")
 
 
 
 
 
 
159
  generate_btn = gr.Button("Generate Test")
160
+ output_text = gr.Textbox(label="Status")
161
+ output_file = gr.File(label="Download Test")
162
 
163
  def update_subjects(selected_grade):
164
+ return gr.update(choices=list(chapters_by_grade_subject.get(selected_grade, {}).keys()), value=None)
165
+ grade_dropdown.change(update_subjects, inputs=grade_dropdown, outputs=subject_dropdown)
166
 
167
  def update_chapters(selected_subject, selected_grade):
168
+ return gr.update(choices=chapters_by_grade_subject.get(selected_grade, {}).get(selected_subject, []), value=None)
 
 
 
169
  subject_dropdown.change(update_chapters, inputs=[subject_dropdown, grade_dropdown], outputs=chapter_dropdown)
 
170
 
171
  generate_btn.click(
172
+ on_generate,
173
+ inputs=[grade_dropdown, subject_dropdown, chapter_dropdown, difficulty_dropdown, num_mcq_slider],
174
  outputs=[output_text, output_file]
175
  )
176
 
177
+ demo.launch()