Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -32,7 +32,6 @@ class QuizGenerator:
|
|
| 32 |
prompt = self._create_prompt(text, num_questions)
|
| 33 |
|
| 34 |
try:
|
| 35 |
-
# API call with simplified parameters
|
| 36 |
response = self.client.chat.completions.create(
|
| 37 |
messages=[
|
| 38 |
{
|
|
@@ -58,8 +57,18 @@ class QuizGenerator:
|
|
| 58 |
questions = self._parse_response(content)
|
| 59 |
validated = self._validate_questions(questions, num_questions)
|
| 60 |
|
| 61 |
-
if
|
| 62 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 63 |
|
| 64 |
return validated
|
| 65 |
|
|
@@ -69,9 +78,56 @@ class QuizGenerator:
|
|
| 69 |
print("Response content:", content if 'content' in locals() else None)
|
| 70 |
raise QuizGenerationError(f"Failed to generate questions: {str(e)}")
|
| 71 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 72 |
def _create_prompt(self, text: str, num_questions: int) -> str:
|
| 73 |
-
"""Create a simple, clear prompt optimized for
|
| 74 |
-
return f"""Create {num_questions} multiple choice questions about this text. Return only the JSON array in this exact format:
|
| 75 |
[
|
| 76 |
{{
|
| 77 |
"question": "Write the question here?",
|
|
@@ -87,9 +143,10 @@ class QuizGenerator:
|
|
| 87 |
|
| 88 |
Rules:
|
| 89 |
1. Return only the JSON array
|
| 90 |
-
2.
|
| 91 |
-
3.
|
| 92 |
-
4.
|
|
|
|
| 93 |
|
| 94 |
Text to use:
|
| 95 |
{text.strip()}"""
|
|
|
|
| 32 |
prompt = self._create_prompt(text, num_questions)
|
| 33 |
|
| 34 |
try:
|
|
|
|
| 35 |
response = self.client.chat.completions.create(
|
| 36 |
messages=[
|
| 37 |
{
|
|
|
|
| 57 |
questions = self._parse_response(content)
|
| 58 |
validated = self._validate_questions(questions, num_questions)
|
| 59 |
|
| 60 |
+
# Check if we have exactly the requested number of questions
|
| 61 |
+
if len(validated) < num_questions:
|
| 62 |
+
# Generate additional questions if needed
|
| 63 |
+
additional_needed = num_questions - len(validated)
|
| 64 |
+
additional_questions = self.generate_questions(text, additional_needed)
|
| 65 |
+
validated.extend(additional_questions)
|
| 66 |
+
elif len(validated) > num_questions:
|
| 67 |
+
# Trim to exact number needed
|
| 68 |
+
validated = validated[:num_questions]
|
| 69 |
+
|
| 70 |
+
if len(validated) != num_questions:
|
| 71 |
+
raise ValueError(f"Failed to generate exactly {num_questions} questions")
|
| 72 |
|
| 73 |
return validated
|
| 74 |
|
|
|
|
| 78 |
print("Response content:", content if 'content' in locals() else None)
|
| 79 |
raise QuizGenerationError(f"Failed to generate questions: {str(e)}")
|
| 80 |
|
| 81 |
+
def _validate_questions(self, questions: List[Dict], num_questions: int) -> List[Question]:
|
| 82 |
+
"""Validate questions with strict checking and ensure correct number"""
|
| 83 |
+
validated = []
|
| 84 |
+
|
| 85 |
+
for q in questions:
|
| 86 |
+
try:
|
| 87 |
+
# Skip invalid questions
|
| 88 |
+
if not isinstance(q, dict):
|
| 89 |
+
continue
|
| 90 |
+
|
| 91 |
+
# Check required fields
|
| 92 |
+
if not all(key in q for key in ['question', 'options', 'correct_answer']):
|
| 93 |
+
continue
|
| 94 |
+
|
| 95 |
+
# Validate options
|
| 96 |
+
if not isinstance(q['options'], list) or len(q['options']) != 4:
|
| 97 |
+
continue
|
| 98 |
+
|
| 99 |
+
# Validate correct_answer
|
| 100 |
+
try:
|
| 101 |
+
correct_idx = int(q['correct_answer'])
|
| 102 |
+
if not 0 <= correct_idx <= 3:
|
| 103 |
+
continue
|
| 104 |
+
except (ValueError, TypeError):
|
| 105 |
+
continue
|
| 106 |
+
|
| 107 |
+
# Validate question content
|
| 108 |
+
if not q['question'].strip() or any(not opt.strip() for opt in q['options']):
|
| 109 |
+
continue
|
| 110 |
+
|
| 111 |
+
# Create validated Question object
|
| 112 |
+
validated.append(Question(
|
| 113 |
+
question=str(q['question']).strip(),
|
| 114 |
+
options=[str(opt).strip() for opt in q['options']],
|
| 115 |
+
correct_answer=correct_idx
|
| 116 |
+
))
|
| 117 |
+
|
| 118 |
+
except Exception as e:
|
| 119 |
+
print(f"Validation error: {str(e)}")
|
| 120 |
+
continue
|
| 121 |
+
|
| 122 |
+
# Stop if we have enough validated questions
|
| 123 |
+
if len(validated) == num_questions:
|
| 124 |
+
break
|
| 125 |
+
|
| 126 |
+
return validated
|
| 127 |
+
|
| 128 |
def _create_prompt(self, text: str, num_questions: int) -> str:
|
| 129 |
+
"""Create a simple, clear prompt optimized for gemma2-9b-it with emphasis on exact number"""
|
| 130 |
+
return f"""Create exactly {num_questions} multiple choice questions about this text. Return only the JSON array in this exact format:
|
| 131 |
[
|
| 132 |
{{
|
| 133 |
"question": "Write the question here?",
|
|
|
|
| 143 |
|
| 144 |
Rules:
|
| 145 |
1. Return only the JSON array
|
| 146 |
+
2. Generate exactly {num_questions} questions
|
| 147 |
+
3. Each question must have exactly 4 options
|
| 148 |
+
4. correct_answer must be 0, 1, 2, or 3
|
| 149 |
+
5. No explanations or additional text
|
| 150 |
|
| 151 |
Text to use:
|
| 152 |
{text.strip()}"""
|