Spaces:
No application file
No application file
Update app.py
Browse files
app.py
CHANGED
|
@@ -3,8 +3,9 @@ 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
|
| 7 |
from docx.enum.text import WD_ALIGN_PARAGRAPH
|
|
|
|
| 8 |
|
| 9 |
# -------------------------
|
| 10 |
# Initialize GROQ client
|
|
@@ -17,16 +18,14 @@ difficulty_levels = ["Pretest (Beginner)", "Intermediate", "Advanced"]
|
|
| 17 |
min_mcq, max_mcq = 5, 50
|
| 18 |
|
| 19 |
# -------------------------
|
| 20 |
-
# Chapters by grade & subject
|
| 21 |
-
# Use your complete chapters_by_subject_and_grade dictionary here (same as previous code)
|
| 22 |
# -------------------------
|
| 23 |
chapters_by_subject_and_grade = {
|
| 24 |
-
#
|
| 25 |
-
# ...
|
| 26 |
}
|
| 27 |
|
| 28 |
# -------------------------
|
| 29 |
-
#
|
| 30 |
# -------------------------
|
| 31 |
def generate_mcqs(grade, subject, chapter, difficulty, num_questions):
|
| 32 |
prompt = f"""
|
|
@@ -48,14 +47,13 @@ def generate_mcqs(grade, subject, chapter, difficulty, num_questions):
|
|
| 48 |
import json
|
| 49 |
mcq_list = json.loads(response.text)
|
| 50 |
except:
|
| 51 |
-
# fallback: placeholder MCQs if Groq fails
|
| 52 |
mcq_list = [{"question": f"Sample question {i} for {subject} chapter {chapter}",
|
| 53 |
"options": ["Option A","Option B","Option C","Option D"],
|
| 54 |
"answer": "A"} for i in range(1, num_questions+1)]
|
| 55 |
|
| 56 |
questions = [q["question"] for q in mcq_list]
|
| 57 |
-
answers = [q["answer"] for q in mcq_list]
|
| 58 |
options_list = [q["options"] for q in mcq_list]
|
|
|
|
| 59 |
|
| 60 |
return questions, options_list, answers
|
| 61 |
|
|
@@ -64,13 +62,22 @@ def generate_mcqs(grade, subject, chapter, difficulty, num_questions):
|
|
| 64 |
# -------------------------
|
| 65 |
def export_to_word(mcqs, options_list, answers, grade, subject, chapter, difficulty):
|
| 66 |
doc = Document()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
heading = doc.add_paragraph("MONTHLY/ WEEKLY TEST")
|
| 68 |
heading.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
run.font.size = Pt(16)
|
| 72 |
|
| 73 |
-
#
|
|
|
|
|
|
|
| 74 |
table = doc.add_table(rows=6, cols=2)
|
| 75 |
table.style = 'Table Grid'
|
| 76 |
info = [
|
|
@@ -82,15 +89,22 @@ def export_to_word(mcqs, options_list, answers, grade, subject, chapter, difficu
|
|
| 82 |
row.cells[1].text = value
|
| 83 |
row.cells[0].paragraphs[0].runs[0].bold = True
|
| 84 |
|
|
|
|
|
|
|
| 85 |
# MCQs
|
| 86 |
for i, (q, opts) in enumerate(zip(mcqs, options_list), start=1):
|
| 87 |
-
|
|
|
|
| 88 |
for letter, text in zip(["A","B","C","D"], opts):
|
| 89 |
-
doc.add_paragraph(f"{letter}. {text}"
|
|
|
|
|
|
|
| 90 |
|
| 91 |
-
#
|
| 92 |
-
|
| 93 |
-
|
|
|
|
|
|
|
| 94 |
ans_table.style = 'Table Grid'
|
| 95 |
headers = ["Q#", "A", "B", "C", "D"]
|
| 96 |
for idx, text in enumerate(headers):
|
|
@@ -106,7 +120,7 @@ def export_to_word(mcqs, options_list, answers, grade, subject, chapter, difficu
|
|
| 106 |
return file_path
|
| 107 |
|
| 108 |
# -------------------------
|
| 109 |
-
# Generate test
|
| 110 |
# -------------------------
|
| 111 |
def on_generate(grade, subject, chapter, difficulty, num_questions):
|
| 112 |
mcqs, options_list, answers = generate_mcqs(grade, subject, chapter, difficulty, num_questions)
|
|
@@ -118,26 +132,30 @@ def on_generate(grade, subject, chapter, difficulty, num_questions):
|
|
| 118 |
# -------------------------
|
| 119 |
with gr.Blocks() as demo:
|
| 120 |
gr.Markdown("### **MCQ Test Generator - Developer: Najaf Ali Sharqi**")
|
|
|
|
| 121 |
with gr.Row():
|
| 122 |
grade_dropdown = gr.Dropdown(choices=grades, label="Select Grade")
|
| 123 |
subject_dropdown = gr.Dropdown(choices=[], label="Select Subject")
|
| 124 |
chapter_dropdown = gr.Dropdown(choices=[], label="Select Chapter")
|
|
|
|
| 125 |
with gr.Row():
|
| 126 |
difficulty_dropdown = gr.Dropdown(choices=difficulty_levels, label="Select Difficulty")
|
| 127 |
num_mcq_slider = gr.Slider(minimum=min_mcq, maximum=max_mcq, value=20, step=1, label="Number of MCQs")
|
|
|
|
| 128 |
generate_btn = gr.Button("Generate Test")
|
| 129 |
output_text = gr.Textbox(label="Status")
|
| 130 |
output_file = gr.File(label="Download Test")
|
| 131 |
-
|
| 132 |
# Dropdown updates
|
| 133 |
def update_subjects(grade):
|
| 134 |
return gr.update(choices=list(chapters_by_subject_and_grade.get(grade, {}).keys()), value=None)
|
|
|
|
| 135 |
def update_chapters(subject, grade):
|
| 136 |
return gr.update(choices=chapters_by_subject_and_grade.get(grade, {}).get(subject, []), value=None)
|
| 137 |
|
| 138 |
grade_dropdown.change(update_subjects, grade_dropdown, subject_dropdown)
|
| 139 |
subject_dropdown.change(update_chapters, [subject_dropdown, grade_dropdown], chapter_dropdown)
|
| 140 |
-
|
| 141 |
generate_btn.click(on_generate, inputs=[grade_dropdown, subject_dropdown, chapter_dropdown, difficulty_dropdown, num_mcq_slider], outputs=[output_text, output_file])
|
| 142 |
|
| 143 |
demo.launch()
|
|
|
|
| 3 |
from groq import Groq
|
| 4 |
from datetime import datetime
|
| 5 |
from docx import Document
|
| 6 |
+
from docx.shared import Pt, Inches
|
| 7 |
from docx.enum.text import WD_ALIGN_PARAGRAPH
|
| 8 |
+
from docx.oxml.ns import qn
|
| 9 |
|
| 10 |
# -------------------------
|
| 11 |
# Initialize GROQ client
|
|
|
|
| 18 |
min_mcq, max_mcq = 5, 50
|
| 19 |
|
| 20 |
# -------------------------
|
| 21 |
+
# Chapters by grade & subject (use your full dictionary here)
|
|
|
|
| 22 |
# -------------------------
|
| 23 |
chapters_by_subject_and_grade = {
|
| 24 |
+
# Paste full dictionary from your previous code (Grades 1-12)
|
|
|
|
| 25 |
}
|
| 26 |
|
| 27 |
# -------------------------
|
| 28 |
+
# Generate MCQs from Groq LLaMA-3
|
| 29 |
# -------------------------
|
| 30 |
def generate_mcqs(grade, subject, chapter, difficulty, num_questions):
|
| 31 |
prompt = f"""
|
|
|
|
| 47 |
import json
|
| 48 |
mcq_list = json.loads(response.text)
|
| 49 |
except:
|
|
|
|
| 50 |
mcq_list = [{"question": f"Sample question {i} for {subject} chapter {chapter}",
|
| 51 |
"options": ["Option A","Option B","Option C","Option D"],
|
| 52 |
"answer": "A"} for i in range(1, num_questions+1)]
|
| 53 |
|
| 54 |
questions = [q["question"] for q in mcq_list]
|
|
|
|
| 55 |
options_list = [q["options"] for q in mcq_list]
|
| 56 |
+
answers = [q["answer"] for q in mcq_list]
|
| 57 |
|
| 58 |
return questions, options_list, answers
|
| 59 |
|
|
|
|
| 62 |
# -------------------------
|
| 63 |
def export_to_word(mcqs, options_list, answers, grade, subject, chapter, difficulty):
|
| 64 |
doc = Document()
|
| 65 |
+
|
| 66 |
+
# Set document default font (Times New Roman)
|
| 67 |
+
style = doc.styles['Normal']
|
| 68 |
+
font = style.font
|
| 69 |
+
font.name = 'Times New Roman'
|
| 70 |
+
font.size = Pt(12)
|
| 71 |
+
|
| 72 |
+
# Heading
|
| 73 |
heading = doc.add_paragraph("MONTHLY/ WEEKLY TEST")
|
| 74 |
heading.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
| 75 |
+
heading.runs[0].bold = True
|
| 76 |
+
heading.runs[0].font.size = Pt(16)
|
|
|
|
| 77 |
|
| 78 |
+
doc.add_paragraph() # empty line
|
| 79 |
+
|
| 80 |
+
# Info Table
|
| 81 |
table = doc.add_table(rows=6, cols=2)
|
| 82 |
table.style = 'Table Grid'
|
| 83 |
info = [
|
|
|
|
| 89 |
row.cells[1].text = value
|
| 90 |
row.cells[0].paragraphs[0].runs[0].bold = True
|
| 91 |
|
| 92 |
+
doc.add_paragraph() # empty line
|
| 93 |
+
|
| 94 |
# MCQs
|
| 95 |
for i, (q, opts) in enumerate(zip(mcqs, options_list), start=1):
|
| 96 |
+
q_para = doc.add_paragraph(f"{i}. {q}")
|
| 97 |
+
q_para.paragraph_format.space_after = Pt(2)
|
| 98 |
for letter, text in zip(["A","B","C","D"], opts):
|
| 99 |
+
opt_para = doc.add_paragraph(f"{letter}. {text}")
|
| 100 |
+
opt_para.paragraph_format.left_indent = Inches(0.25)
|
| 101 |
+
opt_para.paragraph_format.space_after = Pt(1)
|
| 102 |
|
| 103 |
+
doc.add_paragraph() # empty line
|
| 104 |
+
|
| 105 |
+
# Answer Key Table
|
| 106 |
+
doc.add_paragraph("ANSWER KEY")
|
| 107 |
+
ans_table = doc.add_table(rows=len(answers)+1, cols=5)
|
| 108 |
ans_table.style = 'Table Grid'
|
| 109 |
headers = ["Q#", "A", "B", "C", "D"]
|
| 110 |
for idx, text in enumerate(headers):
|
|
|
|
| 120 |
return file_path
|
| 121 |
|
| 122 |
# -------------------------
|
| 123 |
+
# Generate test
|
| 124 |
# -------------------------
|
| 125 |
def on_generate(grade, subject, chapter, difficulty, num_questions):
|
| 126 |
mcqs, options_list, answers = generate_mcqs(grade, subject, chapter, difficulty, num_questions)
|
|
|
|
| 132 |
# -------------------------
|
| 133 |
with gr.Blocks() as demo:
|
| 134 |
gr.Markdown("### **MCQ Test Generator - Developer: Najaf Ali Sharqi**")
|
| 135 |
+
|
| 136 |
with gr.Row():
|
| 137 |
grade_dropdown = gr.Dropdown(choices=grades, label="Select Grade")
|
| 138 |
subject_dropdown = gr.Dropdown(choices=[], label="Select Subject")
|
| 139 |
chapter_dropdown = gr.Dropdown(choices=[], label="Select Chapter")
|
| 140 |
+
|
| 141 |
with gr.Row():
|
| 142 |
difficulty_dropdown = gr.Dropdown(choices=difficulty_levels, label="Select Difficulty")
|
| 143 |
num_mcq_slider = gr.Slider(minimum=min_mcq, maximum=max_mcq, value=20, step=1, label="Number of MCQs")
|
| 144 |
+
|
| 145 |
generate_btn = gr.Button("Generate Test")
|
| 146 |
output_text = gr.Textbox(label="Status")
|
| 147 |
output_file = gr.File(label="Download Test")
|
| 148 |
+
|
| 149 |
# Dropdown updates
|
| 150 |
def update_subjects(grade):
|
| 151 |
return gr.update(choices=list(chapters_by_subject_and_grade.get(grade, {}).keys()), value=None)
|
| 152 |
+
|
| 153 |
def update_chapters(subject, grade):
|
| 154 |
return gr.update(choices=chapters_by_subject_and_grade.get(grade, {}).get(subject, []), value=None)
|
| 155 |
|
| 156 |
grade_dropdown.change(update_subjects, grade_dropdown, subject_dropdown)
|
| 157 |
subject_dropdown.change(update_chapters, [subject_dropdown, grade_dropdown], chapter_dropdown)
|
| 158 |
+
|
| 159 |
generate_btn.click(on_generate, inputs=[grade_dropdown, subject_dropdown, chapter_dropdown, difficulty_dropdown, num_mcq_slider], outputs=[output_text, output_file])
|
| 160 |
|
| 161 |
demo.launch()
|