Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,173 +1,136 @@
|
|
| 1 |
-
import gradio as gr from datetime import datetime from io import BytesIO import tempfile
|
| 2 |
-
|
| 3 |
-
Try to import FPDF for PDF generation; if missing, app still runs (no-PDF fallback)
|
| 4 |
-
|
| 5 |
-
HAS_FPDF = True try: from fpdf import FPDF except Exception: HAS_FPDF = False
|
| 6 |
-
|
| 7 |
-
------------------------------
|
| 8 |
-
|
| 9 |
-
Question Banks (100 total)
|
| 10 |
-
|
| 11 |
-
------------------------------
|
| 12 |
-
|
| 13 |
-
Each question: {"q": str, "options": [str, str, str, str], "answer": str}
|
| 14 |
-
|
| 15 |
-
ENG_Q = [ {"q": "1) Which word is a noun?", "options": ["Quickly", "Beautiful", "Chair", "Running"], "answer": "Chair"}, {"q": "2) Choose the correct plural of 'Child':", "options": ["Childs", "Children", "Childes", "Childer"], "answer": "Children"}, {"q": "3) The opposite of 'Hot' is:", "options": ["Warm", "Cool", "Boil", "Heat"], "answer": "Cool"}, {"q": "4) What is the past tense of 'Go'?", "options": ["Goed", "Going", "Went", "Gone"], "answer": "Went"}, {"q": "5) Which sentence is correct?", "options": ["She are happy.", "She is happy.", "She happy is.", "She be happy."], "answer": "She is happy."}, {"q": "6) Choose the synonym of 'Big':", "options": ["Small", "Large", "Short", "Tiny"], "answer": "Large"}, {"q": "7) The sun rises in the :", "options": ["West", "North", "East", "South"], "answer": "East"}, {"q": "8) Which is an adjective?", "options": ["Slowly", "Beautiful", "Jump", "Swim"], "answer": "Beautiful"}, {"q": "9) Fill in the blank: 'I ___ a book.'", "options": ["Reads", "Read", "Reading", "Reader"], "answer": "Read"}, {"q": "10) Antonym of 'Fast':", "options": ["Speedy", "Quick", "Slow", "Rapid"], "answer": "Slow"}, {"q": "11) Which is a pronoun?", "options": ["He", "Book", "Run", "Chair"], "answer": "He"}, {"q": "12) Choose the correct spelling:", "options": ["Calender", "Calendar", "Calindar", "Clander"], "answer": "Calendar"}, {"q": "13) The plural of 'Leaf' is:", "options": ["Leafs", "Leaves", "Leafes", "Leves"], "answer": "Leaves"}, {"q": "14) Which word means the same as 'Begin'?", "options": ["Start", "Stop", "End", "Close"], "answer": "Start"}, {"q": "15) 'I like to ___ football.'", "options": ["Plays", "Play", "Played", "Playing"], "answer": "Play"}, {"q": "16) Opposite of 'Happy':", "options": ["Glad", "Sad", "Joyful", "Cheerful"], "answer": "Sad"}, {"q": "17) Which is a verb?", "options": ["Jump", "Sky", "Mountain", "Blue"], "answer": "Jump"}, {"q": "18) 'She ___ reading a book now.'", "options": ["is", "are", "was", "be"], "answer": "is"}, {"q": "19) Choose the correct sentence:", "options": ["They is running.", "They are running.", "They running.", "They runs."], "answer": "They are running."}, {"q": "20) Which is a question word?", "options": ["When", "Book", "Run", "Quickly"], "answer": "When"}, {"q": "21) Fill in: 'He ___ to school yesterday.'", "options": ["go", "went", "goes", "going"], "answer": "went"}, {"q": "22) Synonym of 'Happy':", "options": ["Sad", "Glad", "Angry", "Cry"], "answer": "Glad"}, {"q": "23) Choose the correct article: ' apple a day keeps the doctor away.'", "options": ["A", "An", "The", "None"], "answer": "An"}, {"q": "24) Which is a preposition?", "options": ["Under", "Play", "Run", "Chair"], "answer": "Under"}, {"q": "25) The opposite of 'day' is:", "options": ["Morning", "Night", "Evening", "Afternoon"], "answer": "Night"}, {"q": "26) Which is a proper noun?", "options": ["Boy", "Pakistan", "City", "Country"], "answer": "Pakistan"}, {"q": "27) Fill in: 'The birds ___ flying.'", "options": ["is", "are", "was", "be"], "answer": "are"}, {"q": "28) Antonym of 'Old':", "options": ["Young", "Aged", "Ancient", "Elder"], "answer": "Young"}, {"q": "29) Which is a compound word?", "options": ["Sunflower", "Flower", "Sun", "Tree"], "answer": "Sunflower"}, {"q": "30) Choose the correct form: 'We ___ at home now.'", "options": ["am", "are", "is", "be"], "answer": "are"}, {"q": "31) Which is a conjunction?", "options": ["And", "Quickly", "Run", "Book"], "answer": "And"}, {"q": "32) Past tense of 'Eat':", "options": ["Eated", "Ate", "Eats", "Eating"], "answer": "Ate"}, {"q": "33) 'The sky is ___.',", "options": ["blue", "jump", "play", "walk"], "answer": "blue"}, {"q": "34) Opposite of 'Come':", "options": ["Go", "Arrive", "Stay", "Reach"], "answer": "Go"}, ]
|
| 16 |
-
|
| 17 |
-
MATH_Q = [ {"q": "35) 125 + 248 = ?", "options": ["343", "373", "383", "413"], "answer": "373"}, {"q": "36) 600 − 375 = ?", "options": ["125", "215", "225", "235"], "answer": "225"}, {"q": "37) 45 × 8 = ?", "options": ["320", "360", "380", "400"], "answer": "360"}, {"q": "38) 924 ÷ 4 = ?", "options": ["221", "231", "241", "246"], "answer": "231"}, {"q": "39) Which fraction is larger?", "options": ["1/4", "1/3", "1/5", "1/6"], "answer": "1/3"}, {"q": "40) 3/4 + 2/4 = ?", "options": ["3/8", "1/4", "5/4", "1"], "answer": "5/4"}, {"q": "41) 5.6 + 2.45 = ?", "options": ["7.95", "8.05", "8.15", "8.25"], "answer": "8.05"}, {"q": "42) 7.8 − 3.25 = ?", "options": ["4.45", "4.55", "4.65", "4.75"], "answer": "4.55"}, {"q": "43) 1/3 of 12 is:", "options": ["2", "3", "4", "5"], "answer": "4"}, {"q": "44) Area of rectangle 12cm × 8cm:", "options": ["20 cm²", "80 cm²", "96 cm²", "100 cm²"], "answer": "96 cm²"}, {"q": "45) 9 × 7 = ?", "options": ["56", "60", "63", "72"], "answer": "63"}, {"q": "46) 1000 − 435 = ?", "options": ["455", "565", "575", "585"], "answer": "565"}, {"q": "47) 6 × (5 + 3) = ?", "options": ["48", "30", "36", "18"], "answer": "48"}, {"q": "48) 2.5 × 4 = ?", "options": ["8", "9", "10", "12"], "answer": "10"}, {"q": "49) 500 ÷ 25 = ?", "options": ["10", "15", "20", "25"], "answer": "20"}, {"q": "50) 1/2 + 1/4 = ?", "options": ["1/4", "1/2", "3/4", "1"], "answer": "3/4"}, {"q": "51) 4² + 3² = ?", "options": ["12", "16", "18", "25"], "answer": "25"}, {"q": "52) Perimeter of square (side 5 cm) = ?", "options": ["10 cm", "15 cm", "20 cm", "25 cm"], "answer": "20 cm"}, {"q": "53) 15% of 200 = ?", "options": ["20", "25", "30", "35"], "answer": "30"}, {"q": "54) 0.75 as a fraction = ?", "options": ["1/2", "3/4", "4/5", "2/3"], "answer": "3/4"}, {"q": "55) 7 × 12 = ?", "options": ["72", "74", "82", "84"], "answer": "84"}, {"q": "56) 84 ÷ 7 = ?", "options": ["10", "11", "12", "14"], "answer": "12"}, {"q": "57) 3/5 + 1/10 = ?", "options": ["2/5", "7/10", "3/10", "4/5"], "answer": "7/10"}, {"q": "58) 2 km = ? meters", "options": ["20", "200", "2000", "20000"], "answer": "2000"}, {"q": "59) Angle in a straight line = ?", "options": ["90°", "120°", "150°", "180°"], "answer": "180°"}, {"q": "60) 9² = ?", "options": ["18", "81", "72", "92"], "answer": "81"}, {"q": "61) 1 liter = ? milliliters", "options": ["10", "100", "1000", "10000"], "answer": "1000"}, {"q": "62) 0.6 + 0.15 = ?", "options": ["0.65", "0.70", "0.75", "0.80"], "answer": "0.75"}, {"q": "63) Area of square (side 9 cm) = ?", "options": ["18 cm²", "27 cm²", "36 cm²", "81 cm²"], "answer": "81 cm²"}, {"q": "64) 14 + 29 + 7 = ?", "options": ["46", "48", "50", "52"], "answer": "50"}, {"q": "65) 105 − 68 = ?", "options": ["35", "37", "39", "41"], "answer": "37"}, {"q": "66) 8 × 11 = ?", "options": ["80", "82", "88", "98"], "answer": "88"}, {"q": "67) 2/3 of ninety is:", "options": ["30", "45", "60", "75"], "answer": "60"}, ]
|
| 18 |
-
|
| 19 |
-
ISL_Q = [ {"q": "68) How many pillars of Islam are there?", "options": ["3", "4", "5", "6"], "answer": "5"}, {"q": "69) First Kalimah is called:", "options": ["Kalimah Tayyiba", "Kalimah Shahadat", "Kalimah Tamjeed", "Kalimah Tauheed"], "answer": "Kalimah Tayyiba"}, {"q": "70) The holy book of Muslims is:", "options": ["Torah", "Bible", "Quran", "Zaboor"], "answer": "Quran"}, {"q": "71) Number of Surahs in the Quran:", "options": ["100", "110", "114", "124"], "answer": "114"}, {"q": "72) The first Prophet is:", "options": ["Hazrat Ibrahim (A.S)", "Hazrat Adam (A.S)", "Hazrat Nuh (A.S)", "Hazrat Musa (A.S)"], "answer": "Hazrat Adam (A.S)"}, {"q": "73) The last Prophet is:", "options": ["Hazrat Isa (A.S)", "Hazrat Musa (A.S)", "Hazrat Muhammad (S.A.W)", "Hazrat Yusuf (A.S)"], "answer": "Hazrat Muhammad (S.A.W)"}, {"q": "74) How many Rak'ah in Fajr (Farz)?", "options": ["1", "2", "3", "4"], "answer": "2"}, {"q": "75) The city of Prophet's migration (Hijrah) is:", "options": ["Makkah", "Madinah", "Taif", "Jerusalem"], "answer": "Madinah"}, {"q": "76) Laylat-ul-Qadr is in month of:", "options": ["Muharram", "Rabi-ul-Awwal", "Ramadan", "Zilhajj"], "answer": "Ramadan"}, {"q": "77) Zakat is obligatory on:", "options": ["Poor", "Traveler", "Eligible wealth", "Children"], "answer": "Eligible wealth"}, {"q": "78) The first revelation came in cave:", "options": ["Saur", "Hira", "Arafat", "Uhud"], "answer": "Hira"}, {"q": "79) How many daily prayers (Salah) are obligatory?", "options": ["3", "4", "5", "6"], "answer": "5"}, {"q": "80) The direction Muslims face during prayer is called:", "options": ["Qiblah", "Mehrab", "Minbar", "Rukun"], "answer": "Qiblah"}, {"q": "81) The month of Hajj is:", "options": ["Shawwal", "Zilqa'dah", "Zilhajj", "Safar"], "answer": "Zilhajj"}, {"q": "82) The father of Prophet Ibrahim (A.S) is known as:", "options": ["Azar", "Imran", "Yaqoob", "Amran"], "answer": "Azar"}, {"q": "83) The city where Ka'bah is located:", "options": ["Madinah", "Makkah", "Taif", "Arafat"], "answer": "Makkah"}, {"q": "84) Roza means:", "options": ["Prayer", "Charity", "Fasting", "Pilgrimage"], "answer": "Fasting"}, {"q": "85) The language of the Quran is:", "options": ["Arabic", "Persian", "Urdu", "Hebrew"], "answer": "Arabic"}, {"q": "86) The night journey (Isra) was to:", "options": ["Arafat", "Taif", "Masjid Al-Aqsa", "Uhud"], "answer": "Masjid Al-Aqsa"}, {"q": "87) The fast-breaking meal is called:", "options": ["Suhoor", "Iftar", "Dinner", "Lunch"], "answer": "Iftar"}, {"q": "88) Charity given to poor (obligatory) is:", "options": ["Sadaqah", "Zakat", "Khairat", "Fitrana"], "answer": "Zakat"}, {"q": "89) Muslims pray facing:", "options": ["Masjid Al-Aqsa", "Ka'bah", "Madinah", "Uhud"], "answer": "Ka'bah"}, {"q": "90) The call to prayer is called:", "options": ["Iqamah", "Adhan", "Takbir", "Khutbah"], "answer": "Adhan"}, {"q": "91) The 'Sunnah' means:", "options": ["Obligatory", "Recommended practice", "Forbidden", "None"], "answer": "Recommended practice"}, {"q": "92) The Prophet's (S.A.W) birthplace is:", "options": ["Madinah", "Makkah", "Taif", "Badr"], "answer": "Makkah"}, {"q": "93) The month after Ramadan is:", "options": ["Shawwal", "Muharram", "Safar", "Rabi-ul-Awwal"], "answer": "Shawwal"}, {"q": "94) The festival after Hajj is:", "options": ["Eid-ul-Fitr", "Eid-ul-Adha", "Eid Milad", "Shab-e-Barat"], "answer": "Eid-ul-Adha"}, {"q": "95) The first revelation word was:", "options": ["Iqra", "Qul", "Qad", "Kun"], "answer": "Iqra"}, {"q": "96) The battle fought in 2 AH was:", "options": ["Uhud", "Badr", "Khandaq", "Hunain"], "answer": "Badr"}, {"q": "97) The mother of Prophet Ismail (A.S) is:", "options": ["Sarah", "Hajra", "Maryam", "Aasiyah"], "answer": "Hajra"}, {"q": "98) The Zamzam well appeared near:", "options": ["Safa", "Marwah", "Ka'bah", "Arafat"], "answer": "Ka'bah"}, {"q": "99) 'Salah' means:", "options": ["Fasting", "Prayer", "Charity", "Pilgrimage"], "answer": "Prayer"}, {"q": "100) The animal sacrificed on Eid-ul-Adha is called:", "options": ["Fidya", "Qurbani", "Aqiqa", "Udhiyah"], "answer": "Qurbani"}, ]
|
| 20 |
-
|
| 21 |
-
------------------------------
|
| 22 |
-
|
| 23 |
-
Utility functions
|
| 24 |
-
|
| 25 |
-
------------------------------
|
| 26 |
-
|
| 27 |
-
def evaluate(name, father, roll, *answers): total_q = len(ENG_Q) + len(MATH_Q) + len(ISL_Q) # 100 # Split answers by section eng_ans = answers[0:len(ENG_Q)] math_ans = answers[len(ENG_Q):len(ENG_Q)+len(MATH_Q)] isl_ans = answers[len(ENG_Q)+len(MATH_Q):]
|
| 28 |
-
|
| 29 |
-
eng_correct = sum(1 for i, q in enumerate(ENG_Q) if eng_ans[i] == q["answer"]) if eng_ans else 0
|
| 30 |
-
math_correct = sum(1 for i, q in enumerate(MATH_Q) if math_ans[i] == q["answer"]) if math_ans else 0
|
| 31 |
-
isl_correct = sum(1 for i, q in enumerate(ISL_Q) if isl_ans[i] == q["answer"]) if isl_ans else 0
|
| 32 |
-
|
| 33 |
-
total_correct = eng_correct + math_correct + isl_correct
|
| 34 |
-
percentage = round((total_correct / total_q) * 100, 2)
|
| 35 |
-
|
| 36 |
-
# Build summary text
|
| 37 |
-
summary = (
|
| 38 |
-
f"Student: {name}\n"
|
| 39 |
-
f"Father's Name: {father}\n"
|
| 40 |
-
f"Roll Number: {roll}\n\n"
|
| 41 |
-
f"English: {eng_correct}/{len(ENG_Q)}\n"
|
| 42 |
-
f"Math: {math_correct}/{len(MATH_Q)}\n"
|
| 43 |
-
f"Islamiat: {isl_correct}/{len(ISL_Q)}\n"
|
| 44 |
-
f"Total: {total_correct}/{total_q} | Percentage: {percentage}%\n"
|
| 45 |
-
)
|
| 46 |
-
|
| 47 |
-
pdf_path = None
|
| 48 |
-
if HAS_FPDF:
|
| 49 |
-
try:
|
| 50 |
-
pdf = FPDF()
|
| 51 |
-
pdf.add_page()
|
| 52 |
-
pdf.set_auto_page_break(auto=True, margin=12)
|
| 53 |
-
|
| 54 |
-
pdf.set_font("Arial", "B", 16)
|
| 55 |
-
pdf.cell(0, 10, "Grade 5 Test - Result Card", ln=True, align="C")
|
| 56 |
-
pdf.ln(2)
|
| 57 |
-
|
| 58 |
-
pdf.set_font("Arial", size=12)
|
| 59 |
-
pdf.cell(0, 8, f"Name: {name}", ln=True)
|
| 60 |
-
pdf.cell(0, 8, f"Father's Name: {father}", ln=True)
|
| 61 |
-
pdf.cell(0, 8, f"Roll Number: {roll}", ln=True)
|
| 62 |
-
pdf.cell(0, 8, f"Date & Time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}", ln=True)
|
| 63 |
-
pdf.ln(4)
|
| 64 |
-
|
| 65 |
-
pdf.set_font("Arial", "B", 13)
|
| 66 |
-
pdf.cell(0, 8, "Scores", ln=True)
|
| 67 |
-
pdf.set_font("Arial", size=12)
|
| 68 |
-
pdf.cell(0, 8, f"English: {eng_correct}/{len(ENG_Q)}", ln=True)
|
| 69 |
-
pdf.cell(0, 8, f"Math: {math_correct}/{len(MATH_Q)}", ln=True)
|
| 70 |
-
pdf.cell(0, 8, f"Islamiat: {isl_correct}/{len(ISL_Q)}", ln=True)
|
| 71 |
-
pdf.cell(0, 8, f"Total: {total_correct}/{total_q}", ln=True)
|
| 72 |
-
pdf.cell(0, 8, f"Percentage: {percentage}%", ln=True)
|
| 73 |
-
|
| 74 |
-
with tempfile.NamedTemporaryFile(delete=False, suffix=f"_{roll}.pdf") as tmp:
|
| 75 |
-
pdf.output(tmp.name)
|
| 76 |
-
pdf_path = tmp.name
|
| 77 |
-
except Exception:
|
| 78 |
-
pdf_path = None
|
| 79 |
-
|
| 80 |
-
return summary, pdf_path
|
| 81 |
-
|
| 82 |
-
------------------------------
|
| 83 |
-
|
| 84 |
-
Build Gradio UI
|
| 85 |
-
|
| 86 |
-
------------------------------
|
| 87 |
-
|
| 88 |
-
with gr.Blocks(title="Grade 5 Test — 100 MCQs", theme=gr.themes.Soft()) as demo: gr.Markdown(""" # 🧮 Grade 5 Test — 100 MCQs Fill student info, answer all questions in three sections, then submit to get scores, percentage, and a PDF result card. """)
|
| 89 |
-
|
| 90 |
-
with gr.Box():
|
| 91 |
-
name = gr.Textbox(label="Student Name", placeholder="Enter full name")
|
| 92 |
-
father = gr.Textbox(label="Father's Name", placeholder="Enter father's name")
|
| 93 |
-
roll = gr.Textbox(label="Roll Number", placeholder="e.g., 5A-023")
|
| 94 |
-
|
| 95 |
-
with gr.Tab("English (34)"):
|
| 96 |
-
eng_inputs = [gr.Radio(choices=q["options"], label=q["q"], type="value") for q in ENG_Q]
|
| 97 |
-
|
| 98 |
-
with gr.Tab("Math (33)"):
|
| 99 |
-
math_inputs = [gr.Radio(choices=q["options"], label=q["q"], type="value") for q in MATH_Q]
|
| 100 |
-
|
| 101 |
-
with gr.Tab("Islamiat (33)"):
|
| 102 |
-
isl_inputs = [gr.Radio(choices=q["options"], label=q["q"], type="value") for q in ISL_Q]
|
| 103 |
-
|
| 104 |
-
submit = gr.Button("Submit Test ✅")
|
| 105 |
-
|
| 106 |
-
result = gr.Textbox(label="Result Summary", lines=10)
|
| 107 |
-
pdf_file = gr.File(label="Download Result Card (PDF)")
|
| 108 |
-
|
| 109 |
-
all_inputs = [name, father, roll] + eng_inputs + math_inputs + isl_inputs
|
| 110 |
-
submit.click(fn=evaluate, inputs=all_inputs, outputs=[result, pdf_file])
|
| 111 |
-
|
| 112 |
-
gr.Markdown("""
|
| 113 |
-
---
|
| 114 |
-
**Notes:** If the PDF file does not appear, ensure the Space has `fpdf` installed via `requirements.txt`.
|
| 115 |
-
""")
|
| 116 |
-
|
| 117 |
-
if name == "main": demo.launch()
|
| 118 |
-
|
| 119 |
import gradio as gr
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 120 |
|
| 121 |
-
# ----------------------------
|
| 122 |
-
# Data: Questions
|
| 123 |
-
# ----------------------------
|
| 124 |
-
QUESTIONS = [
|
| 125 |
-
{"q": "1) 125 + 248 = ?", "options": ["343", "373", "383", "413"], "answer": "373"},
|
| 126 |
-
{"q": "2) 600 − 375 = ?", "options": ["125", "215", "225", "235"], "answer": "225"},
|
| 127 |
-
{"q": "3) 45 × 8 = ?", "options": ["320", "360", "380", "400"], "answer": "360"},
|
| 128 |
-
{"q": "4) 924 ÷ 4 = ?", "options": ["221", "231", "241", "246"], "answer": "231"},
|
| 129 |
-
{"q": "5) Which fraction is larger?", "options": ["1/4", "1/3", "1/5", "1/6"], "answer": "1/3"},
|
| 130 |
-
{"q": "6) 3/4 + 2/4 = ?", "options": ["3/8", "1/4", "5/4", "1"], "answer": "5/4"},
|
| 131 |
-
{"q": "7) 5.6 + 2.45 = ?", "options": ["7.95", "8.05", "8.15", "8.25"], "answer": "8.05"},
|
| 132 |
-
{"q": "8) 7.8 − 3.25 = ?", "options": ["4.45", "4.55", "4.65", "4.75"], "answer": "4.55"},
|
| 133 |
-
{"q": "9) 1/3 of 12 is:", "options": ["2", "3", "4", "5"], "answer": "4"},
|
| 134 |
-
{"q": "10) Area of rectangle 12cm × 8cm:", "options": ["20 cm²", "80 cm²", "96 cm²", "100 cm²"], "answer": "96 cm²"},
|
| 135 |
-
]
|
| 136 |
-
|
| 137 |
-
# ----------------------------
|
| 138 |
-
# Function
|
| 139 |
-
# ----------------------------
|
| 140 |
-
def evaluate(name, father_name, roll_no, *user_answers):
|
| 141 |
-
correct = 0
|
| 142 |
-
total = len(QUESTIONS)
|
| 143 |
-
for i, q in enumerate(QUESTIONS):
|
| 144 |
-
if user_answers[i] == q["answer"]:
|
| 145 |
-
correct += 1
|
| 146 |
-
percent = round((correct / total) * 100, 2)
|
| 147 |
-
|
| 148 |
-
return f"Student: {name}\nFather's Name: {father_name}\nRoll No: {roll_no}\nScore: {correct}/{total}\nPercentage: {percent}%"
|
| 149 |
-
|
| 150 |
-
# ----------------------------
|
| 151 |
-
# UI
|
| 152 |
-
# ----------------------------
|
| 153 |
inputs = [
|
| 154 |
-
gr.Textbox(label="
|
| 155 |
gr.Textbox(label="Father's Name"),
|
| 156 |
gr.Textbox(label="Roll Number")
|
| 157 |
]
|
| 158 |
|
| 159 |
-
|
| 160 |
-
|
|
|
|
|
|
|
|
|
|
| 161 |
|
| 162 |
-
outputs =
|
|
|
|
|
|
|
|
|
|
| 163 |
|
| 164 |
-
demo = gr.Interface(
|
| 165 |
-
fn=evaluate,
|
| 166 |
-
inputs=inputs,
|
| 167 |
-
outputs=outputs,
|
| 168 |
-
title="🧮 5th Class Test",
|
| 169 |
-
description="Answer the questions to get your score and percentage."
|
| 170 |
-
)
|
| 171 |
|
| 172 |
if __name__ == "__main__":
|
| 173 |
demo.launch()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
import gradio as gr
|
| 2 |
+
from fpdf import FPDF
|
| 3 |
+
import tempfile
|
| 4 |
+
import datetime
|
| 5 |
+
|
| 6 |
+
# --------------------------
|
| 7 |
+
# Questions Bank
|
| 8 |
+
# --------------------------
|
| 9 |
+
|
| 10 |
+
english_questions = [
|
| 11 |
+
{
|
| 12 |
+
"question": "Choose the correct synonym of 'Happy':",
|
| 13 |
+
"options": ["Sad", "Joyful", "Angry", "Tired"],
|
| 14 |
+
"answer": "Joyful"
|
| 15 |
+
},
|
| 16 |
+
{
|
| 17 |
+
"question": "Choose the correct antonym of 'Cold':",
|
| 18 |
+
"options": ["Hot", "Freezing", "Cool", "Chilly"],
|
| 19 |
+
"answer": "Hot"
|
| 20 |
+
},
|
| 21 |
+
{
|
| 22 |
+
"question": "Fill in the blank: She _____ to school every day.",
|
| 23 |
+
"options": ["go", "goes", "gone", "going"],
|
| 24 |
+
"answer": "goes"
|
| 25 |
+
}
|
| 26 |
+
] * 10 # Repeat to make 30 for example
|
| 27 |
+
|
| 28 |
+
islamiat_questions = [
|
| 29 |
+
{
|
| 30 |
+
"question": "Who was the first Caliph of Islam?",
|
| 31 |
+
"options": ["Hazrat Umar (RA)", "Hazrat Abu Bakr (RA)", "Hazrat Ali (RA)", "Hazrat Usman (RA)"],
|
| 32 |
+
"answer": "Hazrat Abu Bakr (RA)"
|
| 33 |
+
},
|
| 34 |
+
{
|
| 35 |
+
"question": "How many times Muslims pray in a day?",
|
| 36 |
+
"options": ["3", "4", "5", "6"],
|
| 37 |
+
"answer": "5"
|
| 38 |
+
},
|
| 39 |
+
{
|
| 40 |
+
"question": "Which Surah is the shortest in the Quran?",
|
| 41 |
+
"options": ["Al-Fatiha", "Al-Ikhlas", "Al-Kawthar", "Al-Nas"],
|
| 42 |
+
"answer": "Al-Kawthar"
|
| 43 |
+
}
|
| 44 |
+
] * 10 # Repeat to make 30
|
| 45 |
+
|
| 46 |
+
math_questions = [
|
| 47 |
+
{
|
| 48 |
+
"question": "What is 15 + 6?",
|
| 49 |
+
"options": ["21", "20", "22", "19"],
|
| 50 |
+
"answer": "21"
|
| 51 |
+
},
|
| 52 |
+
{
|
| 53 |
+
"question": "What is 9 × 7?",
|
| 54 |
+
"options": ["63", "72", "56", "49"],
|
| 55 |
+
"answer": "63"
|
| 56 |
+
},
|
| 57 |
+
{
|
| 58 |
+
"question": "What is 100 ÷ 4?",
|
| 59 |
+
"options": ["20", "25", "24", "30"],
|
| 60 |
+
"answer": "25"
|
| 61 |
+
}
|
| 62 |
+
] * 10 # Repeat to make 30
|
| 63 |
+
|
| 64 |
+
questions_bank = {
|
| 65 |
+
"English": english_questions,
|
| 66 |
+
"Islamiat": islamiat_questions,
|
| 67 |
+
"Math": math_questions
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
# --------------------------
|
| 71 |
+
# PDF Generation Function
|
| 72 |
+
# --------------------------
|
| 73 |
+
|
| 74 |
+
def generate_pdf(name, father_name, roll_number, score, total):
|
| 75 |
+
percentage = (score / total) * 100
|
| 76 |
+
pdf = FPDF()
|
| 77 |
+
pdf.add_page()
|
| 78 |
+
pdf.set_font("Arial", size=16)
|
| 79 |
+
pdf.cell(200, 10, txt="5th Class Test Result Card", ln=True, align='C')
|
| 80 |
+
pdf.ln(10)
|
| 81 |
+
pdf.set_font("Arial", size=12)
|
| 82 |
+
pdf.cell(200, 10, txt=f"Name: {name}", ln=True)
|
| 83 |
+
pdf.cell(200, 10, txt=f"Father's Name: {father_name}", ln=True)
|
| 84 |
+
pdf.cell(200, 10, txt=f"Roll Number: {roll_number}", ln=True)
|
| 85 |
+
pdf.cell(200, 10, txt=f"Score: {score}/{total}", ln=True)
|
| 86 |
+
pdf.cell(200, 10, txt=f"Percentage: {percentage:.2f}%", ln=True)
|
| 87 |
+
pdf.cell(200, 10, txt=f"Date: {datetime.date.today()}", ln=True)
|
| 88 |
+
|
| 89 |
+
temp_pdf = tempfile.NamedTemporaryFile(delete=False, suffix=".pdf")
|
| 90 |
+
pdf.output(temp_pdf.name)
|
| 91 |
+
return temp_pdf.name
|
| 92 |
+
|
| 93 |
+
# --------------------------
|
| 94 |
+
# Test Logic
|
| 95 |
+
# --------------------------
|
| 96 |
+
|
| 97 |
+
def test_app(name, father_name, roll_number, *answers):
|
| 98 |
+
score = 0
|
| 99 |
+
total = sum(len(q_list) for q_list in questions_bank.values())
|
| 100 |
+
|
| 101 |
+
# Check answers
|
| 102 |
+
idx = 0
|
| 103 |
+
for section in questions_bank:
|
| 104 |
+
for q in questions_bank[section]:
|
| 105 |
+
if answers[idx] == q["answer"]:
|
| 106 |
+
score += 1
|
| 107 |
+
idx += 1
|
| 108 |
+
|
| 109 |
+
pdf_path = generate_pdf(name, father_name, roll_number, score, total)
|
| 110 |
+
return f"You scored {score}/{total} ({(score/total)*100:.2f}%)", pdf_path
|
| 111 |
+
|
| 112 |
+
# --------------------------
|
| 113 |
+
# Build Gradio Interface
|
| 114 |
+
# --------------------------
|
| 115 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 116 |
inputs = [
|
| 117 |
+
gr.Textbox(label="Name"),
|
| 118 |
gr.Textbox(label="Father's Name"),
|
| 119 |
gr.Textbox(label="Roll Number")
|
| 120 |
]
|
| 121 |
|
| 122 |
+
# Add questions dynamically
|
| 123 |
+
for section, q_list in questions_bank.items():
|
| 124 |
+
inputs.append(gr.Label(value=f"--- {section} Section ---"))
|
| 125 |
+
for q in q_list:
|
| 126 |
+
inputs.append(gr.Radio(choices=q["options"], label=q["question"]))
|
| 127 |
|
| 128 |
+
outputs = [
|
| 129 |
+
gr.Textbox(label="Result"),
|
| 130 |
+
gr.File(label="Download Result PDF")
|
| 131 |
+
]
|
| 132 |
|
| 133 |
+
demo = gr.Interface(fn=test_app, inputs=inputs, outputs=outputs, title="5th Class Test")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 134 |
|
| 135 |
if __name__ == "__main__":
|
| 136 |
demo.launch()
|