Spaces:
Sleeping
Sleeping
File size: 4,054 Bytes
4a62ede 9721299 4a62ede aaa470c 4a62ede c76704b 7577eec c76704b 7577eec 9336c43 7577eec 9336c43 7577eec c76704b 7577eec c76704b 7577eec 4a62ede 3b83d24 4a62ede c76704b 4a62ede 6db22a1 3cf8485 6db22a1 3b83d24 6db22a1 3cf8485 6db22a1 3b83d24 6db22a1 3b83d24 3cf8485 3b83d24 4a62ede 6db22a1 ea4b12c 6db22a1 4a62ede 3b83d24 4a62ede 3b83d24 6db22a1 3b83d24 4a62ede | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | import os
import json
import gradio as gr
from mistralai.client import Mistral
api_key = os.environ["MISTRAL_API_KEY"]
client = Mistral(api_key=api_key)
model_name = "mistral-large-latest"
def generate_MCQquestion(text):
prompt = f"""
You are a strict Arabic exam generator.
You MUST use ONLY the information explicitly written in the Context.
DO NOT use any external knowledge.
Context:
{text}
Generate MCQs in Arabic based on the length of the Context.
Question count rules:
- Very short context (< 100 words): 3 questions.
- Short context (100–300 words): 3–5 questions.
- Medium context (300–700 words): 5–7 questions.
- Long context (> 700 words): 7–10 questions.
STRICT RULES FOR OPTIONS & ANSWERS:
1. **Randomize Answer Position:** The correct answer index (0-3) MUST be distributed randomly across the questions. Do NOT always place the correct answer at index 0.
2. **Length Consistency:** All 4 options for a single question should have roughly the same length. Do NOT make the correct answer significantly longer or more detailed than the distractors.
3. **Plausible Distractors:** Incorrect options must be highly plausible and derived from the context's vocabulary to challenge the student.
4. **Source Integrity:** Every correct answer and its "answer_source" MUST exist explicitly in the text.
STRICT QUALITY RULES:
- Quality over quantity.
- No outside knowledge or general info.
- If the context doesn't support the required number of questions, stop at what is factual.
Return ONLY valid JSON:
{{
"mcqs": [
{{
"question": "string",
"options": ["opt1", "opt2", "opt3", "opt4"],
"answer_index": integer (0 to 3),
"answer_source": "exact sentence from context"
}}
]
}}
"""
try:
response = client.chat.complete(
model=model_name,
messages=[
{"role": "user", "content": prompt}
],
response_format={"type": "json_object"},
temperature=0.2
)
content = response.choices[0].message.content
data = json.loads(content)
# handle both dict and list formats
if isinstance(data, dict):
mcqs = data.get("mcqs", [])
elif isinstance(data, list):
mcqs = data
else:
return json.dumps({"error": "Invalid response format"}, ensure_ascii=False)
# enforce limits
if len(mcqs) < 3:
return json.dumps({"error": "Model generated fewer than 3 questions"}, ensure_ascii=False)
if len(mcqs) > 10:
mcqs = mcqs[:10]
questions = []
answers = []
for i, item in enumerate(mcqs, start=1):
# safety checks
if (
"question" not in item or
"options" not in item or
"answer_index" not in item
):
continue
if not isinstance(item["options"], list) or len(item["options"]) != 4:
continue
if item["answer_index"] < 0 or item["answer_index"] > 3:
continue
questions.append({
"id": i,
"question": item["question"],
"options": item["options"]
})
answers.append({
"question_id": i,
"correct_answer_index": item["answer_index"] + 1
})
final_output = {
"questions": questions,
"answers": answers
}
return json.dumps(final_output, ensure_ascii=False, indent=2)
except Exception as e:
return json.dumps({"error": str(e)}, ensure_ascii=False, indent=2)
# UI
demo = gr.Interface(
fn=generate_MCQquestion,
inputs=gr.Textbox(lines=10, label="أدخل النص"),
outputs=gr.Code(language="json", label="JSON Output"),
title="Arabic MCQ Generator API Ready",
)
demo.launch()
|