Spaces:
No application file
No application file
Update app.py
Browse files
app.py
CHANGED
|
@@ -12,7 +12,7 @@ import random
|
|
| 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 |
# Subjects by grade
|
|
@@ -31,107 +31,60 @@ subjects_by_grade = {
|
|
| 31 |
"Grade 12": ["Mathematics", "English", "Urdu", "Biology", "Chemistry", "Physics", "Computer", "Islamiyat", "Pakistan Studies"]
|
| 32 |
}
|
| 33 |
|
| 34 |
-
# Chapters by subject & grade (
|
| 35 |
chapters_by_subject_and_grade = {
|
| 36 |
-
"Grade 9": {
|
| 37 |
-
"Biology": ["INTRODUCTION TO BIOLOGY","SOLVING A BIOLOGICAL PROBLEM","BIODIVERSITY","CELLS AND TISSUES","CELL CYCLE","ENZYMES","BIOENERGETICS","NUTRITION","TRANSPORT"],
|
| 38 |
-
"Chemistry": ["FUNDAMENTALS OF CHEMISTRY","STRUCTURE OF ATOMS","PERIODIC TABLE AND PERIODICITY OF PROPERTIES","STRUCTURE OF MOLECULES","PHYSICAL STATES OF MATTER","SOLUTIONS","ELECTROCHEMISTRY","CHEMICAL REACTIVITY"],
|
| 39 |
-
"Physics": ["PHYSICAL QUANTITIES AND MEASUREMENT","KINEMATICS","DYNAMICS","TURNING EFFECT OF FORCES","GRAVITATION","WORK AND ENERGY","PROPERTIES OF MATTER","THERMAL PROPERTIES OF MATTER","TRANSFER OF HEAT"],
|
| 40 |
-
"Pakistan Studies": ["IDEOLOGICAL BASIS OF PAKISTAN","MAKING OF PAKISTAN","LAND AND ENVIRONMENT","HISTORY OF PAKISTAN"],
|
| 41 |
-
"Mathematics": ["Number Systems & Algebra", "Coordinate Geometry", "Trigonometry", "Graphs"],
|
| 42 |
-
"English": ["Advanced Grammar", "Comprehension", "Writing Skills"],
|
| 43 |
-
"Urdu": ["ادب اور نثر", "نظم", "مضامین"],
|
| 44 |
-
"Islamiyat": ["Seerat of Prophet", "Faith & Beliefs", "Worship Practices"],
|
| 45 |
-
"Computer": ["Fundamentals of Computing", "ICT Applications"]
|
| 46 |
-
},
|
| 47 |
-
"Grade 10": {
|
| 48 |
-
"Biology": ["GASEOUS EXCHANGE","HOMEOSTASIS","COORDINATION","SUPPORT AND MOVEMENT","REPRODUCTION","INHERITANCE","MAN AND HIS ENVIRONMENT","BIOTECHNOLOGY","PHARMA"],
|
| 49 |
-
"Chemistry": ["CHEMICAL EQUILIBRIUM","ACIDS, BASES AND SALTS","ORGANIC CHEMISTRY","HYDROCARBONS","BIOCHEMISTRY","ENVIRONMENTAL CHEMISTRY I: THE ATMOSPHERE","ENVIRONMENTAL CHEMISTRY II: WATER","CHEMICAL INDUSTRIES"],
|
| 50 |
-
"Physics": ["SIMPLE HARMONIC MOTION AND WAVES","SOUND","GEOMETRICAL OPTICS","ELECTROSTATICS","CURRENT ELECTRICITY","ELECTROMAGNETISM","INTRODUCTORY ELECTRONICS","INFORMATION AND COMMUNICATION TECHNOLOGY","RADIOACTIVITY"],
|
| 51 |
-
"Pakistan Studies": ["HISTORY OF PAKISTAN-II","PAKISTAN IN WORLD AFFAIRS","ECONOMIC DEVELOPMENTS","POPULATION, SOCIETY AND CULTURE OF PAKISTAN"],
|
| 52 |
-
"Mathematics": ["Advanced Algebra", "Trigonometry", "Geometry", "Probability"],
|
| 53 |
-
"English": ["Literature", "Advanced Composition", "Comprehension"],
|
| 54 |
-
"Urdu": ["ادبِ جدید", "تحقیقی مضمون"],
|
| 55 |
-
"Islamiyat": ["Islamic Studies II", "Ethics & Society", "Fiqh Basics"],
|
| 56 |
-
"Computer": ["Programming Basics", "ICT in Society"]
|
| 57 |
-
},
|
| 58 |
-
# Grades 11 & 12 example (add all chapters)
|
| 59 |
"Grade 11": {
|
| 60 |
-
"Mathematics": ["Advanced Algebra
|
|
|
|
|
|
|
|
|
|
|
|
|
| 61 |
"English": ["Academic Writing", "Literature Studies", "Critical Reading"],
|
| 62 |
"Urdu": ["ادبی مطالعہ", "نظم و نثر کی تشریح"],
|
| 63 |
-
"
|
| 64 |
-
"
|
| 65 |
-
"Physics": ["Measurement & Vectors","Forces & Motion","Work & Energy","Oscillations & Waves"],
|
| 66 |
-
"Computer": ["Programming Fundamentals","Data Structures Intro","Databases & File Systems"],
|
| 67 |
-
"Islamiyat": ["Advanced Seerah","Islamic Ethics"],
|
| 68 |
-
"Pakistan Studies": ["Pakistan in Geographical Perspective","Resources & Economy","Historical Overview"]
|
| 69 |
},
|
| 70 |
"Grade 12": {
|
| 71 |
"Mathematics": ["Calculus", "Advanced Algebra", "Statistics", "Analytical Geometry"],
|
|
|
|
|
|
|
|
|
|
|
|
|
| 72 |
"English": ["Research Writing", "Advanced Literature", "Critical Analysis"],
|
| 73 |
"Urdu": ["تحقیق و تنقید", "ادبی شخصیات"],
|
| 74 |
-
"
|
| 75 |
-
"
|
| 76 |
-
"Physics": ["Electromagnetism & EM Induction","Alternating Current Circuits","Electronics & Semiconductors","Atomic & Nuclear Physics"],
|
| 77 |
-
"Computer": ["Advanced Programming Concepts","Web Technologies & Networks"],
|
| 78 |
-
"Islamiyat": ["Islamic Jurisprudence (Fiqh)","Contemporary Islamic Thought"],
|
| 79 |
-
"Pakistan Studies": ["Society & Culture","Foreign Relations","Economic Policies & Development"]
|
| 80 |
}
|
| 81 |
}
|
| 82 |
|
| 83 |
-
# Difficulty levels
|
| 84 |
difficulty_levels = ["Pretest (Beginner)", "Intermediate", "Advanced"]
|
| 85 |
|
|
|
|
| 86 |
def generate_mcqs(grade, subject, chapter, difficulty, num_questions):
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
response = client.chat.completions.create(
|
| 91 |
-
messages=[
|
| 92 |
-
{"role": "system", "content": system_msg},
|
| 93 |
-
{"role": "user", "content": user_msg}
|
| 94 |
-
],
|
| 95 |
-
model="llama-3.3-70b-versatile"
|
| 96 |
-
)
|
| 97 |
-
|
| 98 |
-
text = response.choices[0].message.content
|
| 99 |
-
mcqs = re.split(r'\n?\d+\.', text)
|
| 100 |
-
mcqs = [q.strip() for q in mcqs if q.strip()]
|
| 101 |
|
| 102 |
-
|
| 103 |
-
return mcqs[:num_questions], answer_key[:num_questions]
|
| 104 |
-
|
| 105 |
-
def export_to_word(mcqs, answers, grade, subject, chapter, difficulty, num_questions):
|
| 106 |
doc = Document()
|
| 107 |
-
# Heading
|
| 108 |
heading = doc.add_heading("MONTHLY/WEEKLY TEST", level=1)
|
| 109 |
heading.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
| 110 |
run = heading.runs[0]
|
| 111 |
run.bold = True
|
| 112 |
run.font.size = Pt(18)
|
| 113 |
-
run.font.color.rgb = RGBColor(0,0,0)
|
| 114 |
|
| 115 |
-
# Info table
|
| 116 |
table = doc.add_table(rows=5, cols=2)
|
| 117 |
table.style = 'Table Grid'
|
| 118 |
-
info = [
|
| 119 |
-
|
| 120 |
-
("Subject", subject),
|
| 121 |
-
("Chapter", chapter),
|
| 122 |
-
("Date", datetime.now().strftime("%d-%m-%Y")),
|
| 123 |
-
("Difficulty", difficulty)
|
| 124 |
-
]
|
| 125 |
for row, (label, value) in zip(table.rows, info):
|
| 126 |
row.cells[0].text = label
|
| 127 |
row.cells[1].text = value
|
| 128 |
row.cells[0].paragraphs[0].runs[0].bold = True
|
| 129 |
|
| 130 |
-
# MCQs
|
| 131 |
for i, q in enumerate(mcqs, start=1):
|
| 132 |
doc.add_paragraph(f"{i}. {q}")
|
| 133 |
|
| 134 |
-
# Answer key table
|
| 135 |
doc.add_paragraph("\nAnswer Key:")
|
| 136 |
ans_table = doc.add_table(rows=len(answers)+1, cols=5)
|
| 137 |
ans_table.style = 'Table Grid'
|
|
@@ -139,51 +92,46 @@ def export_to_word(mcqs, answers, grade, subject, chapter, difficulty, num_quest
|
|
| 139 |
for idx, text in enumerate(headers):
|
| 140 |
ans_table.cell(0, idx).text = text
|
| 141 |
ans_table.cell(0, idx).paragraphs[0].runs[0].bold = True
|
| 142 |
-
|
| 143 |
for r, ans in enumerate(answers, start=1):
|
| 144 |
ans_table.cell(r,0).text = str(r)
|
| 145 |
for c, option in enumerate(["A","B","C","D"], start=1):
|
| 146 |
ans_table.cell(r,c).text = "✔" if ans==option else ""
|
| 147 |
-
|
| 148 |
file_path = f"{grade}_{subject}_{chapter}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.docx"
|
| 149 |
doc.save(file_path)
|
| 150 |
return file_path
|
| 151 |
|
| 152 |
def on_generate(grade, subject, chapter, difficulty, num_questions):
|
| 153 |
mcqs, answers = generate_mcqs(grade, subject, chapter, difficulty, num_questions)
|
| 154 |
-
file_path = export_to_word(mcqs, answers, grade, subject, chapter, difficulty
|
| 155 |
return f"Test ready: {file_path}", file_path
|
| 156 |
|
| 157 |
# Gradio UI
|
| 158 |
with gr.Blocks() as demo:
|
| 159 |
-
gr.Markdown("### **MCQ
|
| 160 |
with gr.Row():
|
| 161 |
grade_dropdown = gr.Dropdown(choices=grades, label="Select Grade")
|
| 162 |
-
subject_dropdown = gr.Dropdown(choices=[], label="Select Subject")
|
| 163 |
-
chapter_dropdown = gr.Dropdown(choices=[], label="Select Chapter")
|
| 164 |
difficulty_dropdown = gr.Dropdown(choices=difficulty_levels, label="Select Difficulty")
|
| 165 |
num_mcqs_slider = gr.Slider(minimum=5, maximum=50, step=1, label="Number of MCQs", value=20)
|
| 166 |
generate_btn = gr.Button("Generate Test")
|
| 167 |
output_text = gr.Textbox(label="Status")
|
| 168 |
output_file = gr.File(label="Download Test")
|
| 169 |
|
| 170 |
-
# Update subjects
|
| 171 |
def update_subjects(grade):
|
| 172 |
subjects = list(chapters_by_subject_and_grade.get(grade, {}).keys())
|
| 173 |
-
return
|
| 174 |
|
| 175 |
-
# Update chapters
|
| 176 |
def update_chapters(subject, grade):
|
| 177 |
chapters = chapters_by_subject_and_grade.get(grade, {}).get(subject, [])
|
| 178 |
-
return
|
| 179 |
|
| 180 |
grade_dropdown.change(update_subjects, inputs=grade_dropdown, outputs=subject_dropdown)
|
| 181 |
subject_dropdown.change(update_chapters, inputs=[subject_dropdown, grade_dropdown], outputs=chapter_dropdown)
|
| 182 |
-
|
| 183 |
-
|
| 184 |
-
|
| 185 |
-
inputs=[grade_dropdown, subject_dropdown, chapter_dropdown, difficulty_dropdown, num_mcqs_slider],
|
| 186 |
-
outputs=[output_text, output_file]
|
| 187 |
-
)
|
| 188 |
|
| 189 |
demo.launch()
|
|
|
|
| 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 |
# Subjects by grade
|
|
|
|
| 31 |
"Grade 12": ["Mathematics", "English", "Urdu", "Biology", "Chemistry", "Physics", "Computer", "Islamiyat", "Pakistan Studies"]
|
| 32 |
}
|
| 33 |
|
| 34 |
+
# Chapters by subject & grade (simplified example; you can expand)
|
| 35 |
chapters_by_subject_and_grade = {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 36 |
"Grade 11": {
|
| 37 |
+
"Mathematics": ["Advanced Algebra", "Calculus Intro", "Trigonometry", "Vectors"],
|
| 38 |
+
"Biology": ["Cell Structure", "Biological Molecules", "Enzymes", "Plant Diversity"],
|
| 39 |
+
"Chemistry": ["Stoichiometry", "Atomic Structure", "Bonding", "States of Matter"],
|
| 40 |
+
"Physics": ["Forces & Motion", "Work & Energy", "Oscillations & Waves"],
|
| 41 |
+
"Computer": ["Programming Fundamentals", "Data Structures", "Databases"],
|
| 42 |
"English": ["Academic Writing", "Literature Studies", "Critical Reading"],
|
| 43 |
"Urdu": ["ادبی مطالعہ", "نظم و نثر کی تشریح"],
|
| 44 |
+
"Islamiyat": ["Advanced Seerah", "Islamic Ethics"],
|
| 45 |
+
"Pakistan Studies": ["Pakistan Geography", "Resources & Economy", "Historical Overview"]
|
|
|
|
|
|
|
|
|
|
|
|
|
| 46 |
},
|
| 47 |
"Grade 12": {
|
| 48 |
"Mathematics": ["Calculus", "Advanced Algebra", "Statistics", "Analytical Geometry"],
|
| 49 |
+
"Biology": ["Respiration & Exchange","Homeostasis","Support & Movement","Reproduction","Genetics"],
|
| 50 |
+
"Chemistry": ["s and p Block Elements","d Block & Transition Elements","Organic Reactions","Hydrocarbons"],
|
| 51 |
+
"Physics": ["Electromagnetism","AC Circuits","Semiconductors","Atomic & Nuclear Physics"],
|
| 52 |
+
"Computer": ["Advanced Programming", "Web Technologies", "Networks"],
|
| 53 |
"English": ["Research Writing", "Advanced Literature", "Critical Analysis"],
|
| 54 |
"Urdu": ["تحقیق و تنقید", "ادبی شخصیات"],
|
| 55 |
+
"Islamiyat": ["Fiqh", "Contemporary Islamic Thought"],
|
| 56 |
+
"Pakistan Studies": ["Society & Culture","Foreign Relations","Economic Policies"]
|
|
|
|
|
|
|
|
|
|
|
|
|
| 57 |
}
|
| 58 |
}
|
| 59 |
|
|
|
|
| 60 |
difficulty_levels = ["Pretest (Beginner)", "Intermediate", "Advanced"]
|
| 61 |
|
| 62 |
+
# MCQ generation (demo)
|
| 63 |
def generate_mcqs(grade, subject, chapter, difficulty, num_questions):
|
| 64 |
+
mcqs = [f"Sample question {i} for {subject} ({chapter})" for i in range(1, num_questions+1)]
|
| 65 |
+
answers = [random.choice(["A","B","C","D"]) for _ in mcqs]
|
| 66 |
+
return mcqs, answers
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
|
| 68 |
+
def export_to_word(mcqs, answers, grade, subject, chapter, difficulty):
|
|
|
|
|
|
|
|
|
|
| 69 |
doc = Document()
|
|
|
|
| 70 |
heading = doc.add_heading("MONTHLY/WEEKLY TEST", level=1)
|
| 71 |
heading.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
| 72 |
run = heading.runs[0]
|
| 73 |
run.bold = True
|
| 74 |
run.font.size = Pt(18)
|
|
|
|
| 75 |
|
|
|
|
| 76 |
table = doc.add_table(rows=5, cols=2)
|
| 77 |
table.style = 'Table Grid'
|
| 78 |
+
info = [("Grade", grade), ("Subject", subject), ("Chapter", chapter),
|
| 79 |
+
("Date", datetime.now().strftime("%d-%m-%Y")), ("Difficulty", difficulty)]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 80 |
for row, (label, value) in zip(table.rows, info):
|
| 81 |
row.cells[0].text = label
|
| 82 |
row.cells[1].text = value
|
| 83 |
row.cells[0].paragraphs[0].runs[0].bold = True
|
| 84 |
|
|
|
|
| 85 |
for i, q in enumerate(mcqs, start=1):
|
| 86 |
doc.add_paragraph(f"{i}. {q}")
|
| 87 |
|
|
|
|
| 88 |
doc.add_paragraph("\nAnswer Key:")
|
| 89 |
ans_table = doc.add_table(rows=len(answers)+1, cols=5)
|
| 90 |
ans_table.style = 'Table Grid'
|
|
|
|
| 92 |
for idx, text in enumerate(headers):
|
| 93 |
ans_table.cell(0, idx).text = text
|
| 94 |
ans_table.cell(0, idx).paragraphs[0].runs[0].bold = True
|
|
|
|
| 95 |
for r, ans in enumerate(answers, start=1):
|
| 96 |
ans_table.cell(r,0).text = str(r)
|
| 97 |
for c, option in enumerate(["A","B","C","D"], start=1):
|
| 98 |
ans_table.cell(r,c).text = "✔" if ans==option else ""
|
|
|
|
| 99 |
file_path = f"{grade}_{subject}_{chapter}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.docx"
|
| 100 |
doc.save(file_path)
|
| 101 |
return file_path
|
| 102 |
|
| 103 |
def on_generate(grade, subject, chapter, difficulty, num_questions):
|
| 104 |
mcqs, answers = generate_mcqs(grade, subject, chapter, difficulty, num_questions)
|
| 105 |
+
file_path = export_to_word(mcqs, answers, grade, subject, chapter, difficulty)
|
| 106 |
return f"Test ready: {file_path}", file_path
|
| 107 |
|
| 108 |
# Gradio UI
|
| 109 |
with gr.Blocks() as demo:
|
| 110 |
+
gr.Markdown("### **MCQ TEST GENERATOR**")
|
| 111 |
with gr.Row():
|
| 112 |
grade_dropdown = gr.Dropdown(choices=grades, label="Select Grade")
|
| 113 |
+
subject_dropdown = gr.Dropdown(choices=[], label="Select Subject", allow_custom_value=True)
|
| 114 |
+
chapter_dropdown = gr.Dropdown(choices=[], label="Select Chapter", allow_custom_value=True)
|
| 115 |
difficulty_dropdown = gr.Dropdown(choices=difficulty_levels, label="Select Difficulty")
|
| 116 |
num_mcqs_slider = gr.Slider(minimum=5, maximum=50, step=1, label="Number of MCQs", value=20)
|
| 117 |
generate_btn = gr.Button("Generate Test")
|
| 118 |
output_text = gr.Textbox(label="Status")
|
| 119 |
output_file = gr.File(label="Download Test")
|
| 120 |
|
| 121 |
+
# Update subjects
|
| 122 |
def update_subjects(grade):
|
| 123 |
subjects = list(chapters_by_subject_and_grade.get(grade, {}).keys())
|
| 124 |
+
return gr.update(choices=subjects, value=subjects[0] if subjects else None)
|
| 125 |
|
| 126 |
+
# Update chapters
|
| 127 |
def update_chapters(subject, grade):
|
| 128 |
chapters = chapters_by_subject_and_grade.get(grade, {}).get(subject, [])
|
| 129 |
+
return gr.update(choices=chapters, value=chapters[0] if chapters else None)
|
| 130 |
|
| 131 |
grade_dropdown.change(update_subjects, inputs=grade_dropdown, outputs=subject_dropdown)
|
| 132 |
subject_dropdown.change(update_chapters, inputs=[subject_dropdown, grade_dropdown], outputs=chapter_dropdown)
|
| 133 |
+
generate_btn.click(on_generate,
|
| 134 |
+
inputs=[grade_dropdown, subject_dropdown, chapter_dropdown, difficulty_dropdown, num_mcqs_slider],
|
| 135 |
+
outputs=[output_text, output_file])
|
|
|
|
|
|
|
|
|
|
| 136 |
|
| 137 |
demo.launch()
|