capradeepgujaran commited on
Commit
a4b4349
·
verified ·
1 Parent(s): 4be5ff1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +64 -61
app.py CHANGED
@@ -19,35 +19,19 @@ class QuizApp:
19
  prompt = f"""Create exactly {num_questions} multiple choice questions based on this text:
20
  {text}
21
 
22
- Format your response EXACTLY like this example:
23
  [
24
  {{
25
- "question": "What is the main topic discussed?",
26
  "options": [
27
- "Correct answer",
28
- "Wrong answer 1",
29
- "Wrong answer 2",
30
- "Wrong answer 3"
31
- ],
32
- "correct_answer": 0
33
- }},
34
- {{
35
- "question": "Another question here?",
36
- "options": [
37
- "Correct answer",
38
- "Wrong answer 1",
39
- "Wrong answer 2",
40
- "Wrong answer 3"
41
  ],
42
  "correct_answer": 0
43
  }}
44
  ]
45
-
46
- Important:
47
- - Return ONLY the JSON array
48
- - Each question must have exactly 4 options
49
- - correct_answer must be the index (0-3) of the correct option
50
- - Do not add any explanation or additional text
51
  """
52
 
53
  try:
@@ -55,7 +39,7 @@ class QuizApp:
55
  messages=[
56
  {
57
  "role": "system",
58
- "content": "You are a quiz generator that creates clear, single-choice questions. Always respond with valid JSON array only."
59
  },
60
  {
61
  "role": "user",
@@ -63,63 +47,81 @@ class QuizApp:
63
  }
64
  ],
65
  model="llama-3.2-3b-preview",
66
- temperature=0.5,
67
- max_tokens=2048
 
68
  )
69
 
70
  # Clean up the response
71
  response_text = response.choices[0].message.content.strip()
72
- # Remove any markdown formatting or additional text
73
- response_text = response_text.replace("```json", "").replace("```", "").strip()
74
 
75
- # Ensure response starts with [ and ends with ]
76
- response_text = response_text[response_text.find("["):response_text.rfind("]")+1]
77
 
78
- print("Generated response:", response_text) # Debug print
 
 
79
 
80
- # Parse and validate questions
81
- questions = json.loads(response_text)
82
- if not isinstance(questions, list):
83
- raise ValueError("Response is not a list")
84
 
85
- # Validate each question
 
 
 
 
 
 
 
 
 
 
 
 
86
  validated_questions = []
87
  for q in questions:
88
  if not isinstance(q, dict):
89
  continue
 
 
90
  if not all(key in q for key in ["question", "options", "correct_answer"]):
91
  continue
 
 
92
  if not isinstance(q["options"], list) or len(q["options"]) != 4:
93
- continue
94
- if not isinstance(q["correct_answer"], int) or q["correct_answer"] not in range(4):
95
- continue
 
 
 
 
 
 
 
96
  validated_questions.append(q)
97
 
98
  if not validated_questions:
99
- raise ValueError("No valid questions generated")
100
 
101
- self.current_questions = validated_questions
102
- return True, validated_questions
103
 
104
- except json.JSONDecodeError as e:
105
- print(f"JSON parsing error: {e}")
106
- # Return a default question for testing/debugging
107
  default_questions = [{
108
- "question": "Sample question (Error occurred in generation)",
109
  "options": [
110
- "Option 1",
111
- "Option 2",
112
- "Option 3",
113
- "Option 4"
114
  ],
115
  "correct_answer": 0
116
  }]
117
  self.current_questions = default_questions
118
  return True, default_questions
119
-
120
- except Exception as e:
121
- print(f"Error generating questions: {e}")
122
- return False, []
123
 
124
  def calculate_score(self, answers):
125
  if not answers or not self.current_questions:
@@ -196,27 +198,29 @@ def create_quiz_interface():
196
  )
197
  certificate_display = gr.Image(label="Your Certificate")
198
 
199
-
200
  def update_questions(text, num_questions):
201
  if not text.strip():
202
  return (
203
- gr.update(value="Please enter some text content to generate questions."),
204
  *[gr.update(visible=False, choices=[]) for _ in range(5)],
205
  [],
206
  0
207
  )
208
-
209
  success, questions = quiz_app.generate_questions(text, num_questions)
 
210
  if not success or not questions:
211
  return (
212
- gr.update(value="Failed to generate questions. Please try again with different content."),
213
  *[gr.update(visible=False, choices=[]) for _ in range(5)],
214
  [],
215
  0
216
  )
217
 
218
  # Update question display
219
- questions_html = "### Answer all questions below:\n\n"
 
 
220
  for i, q in enumerate(questions, 1):
221
  questions_html += f"### Question {i}\n{q['question']}\n\n"
222
 
@@ -228,13 +232,12 @@ def create_quiz_interface():
228
  visible=True,
229
  choices=questions[i]["options"],
230
  value=None,
231
- label=f"Question {i+1}"
232
  ))
233
  else:
234
  updates.append(gr.update(visible=False, choices=[]))
235
 
236
- return (gr.update(value=questions_html), *updates, questions, 1)
237
-
238
 
239
  def submit_quiz(q1, q2, q3, q4, q5, questions):
240
  answers = [q1, q2, q3, q4, q5][:len(questions)]
 
19
  prompt = f"""Create exactly {num_questions} multiple choice questions based on this text:
20
  {text}
21
 
22
+ Return ONLY a JSON array with this EXACT format - no other text:
23
  [
24
  {{
25
+ "question": "Question text here?",
26
  "options": [
27
+ "Option 1",
28
+ "Option 2",
29
+ "Option 3",
30
+ "Option 4"
 
 
 
 
 
 
 
 
 
 
31
  ],
32
  "correct_answer": 0
33
  }}
34
  ]
 
 
 
 
 
 
35
  """
36
 
37
  try:
 
39
  messages=[
40
  {
41
  "role": "system",
42
+ "content": "You are a quiz generator. Respond only with a properly formatted JSON array."
43
  },
44
  {
45
  "role": "user",
 
47
  }
48
  ],
49
  model="llama-3.2-3b-preview",
50
+ temperature=0.3, # Reduced temperature for more consistent formatting
51
+ max_tokens=2048,
52
+ stop=["\n\n", "```"] # Stop generation at these tokens
53
  )
54
 
55
  # Clean up the response
56
  response_text = response.choices[0].message.content.strip()
 
 
57
 
58
+ # Remove any markdown formatting
59
+ response_text = response_text.replace("```json", "").replace("```", "").strip()
60
 
61
+ # Find the JSON array
62
+ start_idx = response_text.find("[")
63
+ end_idx = response_text.rfind("]")
64
 
65
+ if start_idx == -1 or end_idx == -1:
66
+ raise ValueError("No valid JSON array found in response")
 
 
67
 
68
+ response_text = response_text[start_idx:end_idx + 1]
69
+
70
+ # Try to parse the JSON
71
+ try:
72
+ questions = json.loads(response_text)
73
+ except json.JSONDecodeError:
74
+ # If parsing fails, try to fix common JSON formatting issues
75
+ response_text = response_text.replace("'", '"') # Replace single quotes with double quotes
76
+ response_text = response_text.replace("},]", "}]") # Fix trailing comma
77
+ response_text = response_text.replace(",]", "]") # Fix trailing comma
78
+ questions = json.loads(response_text)
79
+
80
+ # Validate questions
81
  validated_questions = []
82
  for q in questions:
83
  if not isinstance(q, dict):
84
  continue
85
+
86
+ # Ensure all required fields are present
87
  if not all(key in q for key in ["question", "options", "correct_answer"]):
88
  continue
89
+
90
+ # Ensure options is a list with exactly 4 items
91
  if not isinstance(q["options"], list) or len(q["options"]) != 4:
92
+ # Try to fix by padding with additional options if needed
93
+ if isinstance(q["options"], list) and len(q["options"]) < 4:
94
+ q["options"].extend([f"Additional option {i+1}" for i in range(4 - len(q["options"]))])
95
+ else:
96
+ continue
97
+
98
+ # Ensure correct_answer is valid
99
+ if not isinstance(q["correct_answer"], (int)) or q["correct_answer"] not in range(4):
100
+ q["correct_answer"] = 0 # Default to first option if invalid
101
+
102
  validated_questions.append(q)
103
 
104
  if not validated_questions:
105
+ return False, []
106
 
107
+ self.current_questions = validated_questions[:num_questions] # Limit to requested number
108
+ return True, self.current_questions
109
 
110
+ except Exception as e:
111
+ print(f"Error in question generation: {str(e)}")
112
+ # Create a single default question for testing
113
  default_questions = [{
114
+ "question": "Default question (Error in generation - please try again)",
115
  "options": [
116
+ "Option A",
117
+ "Option B",
118
+ "Option C",
119
+ "Option D"
120
  ],
121
  "correct_answer": 0
122
  }]
123
  self.current_questions = default_questions
124
  return True, default_questions
 
 
 
 
125
 
126
  def calculate_score(self, answers):
127
  if not answers or not self.current_questions:
 
198
  )
199
  certificate_display = gr.Image(label="Your Certificate")
200
 
 
201
  def update_questions(text, num_questions):
202
  if not text.strip():
203
  return (
204
+ gr.update(value="⚠️ Please enter some text content to generate questions."),
205
  *[gr.update(visible=False, choices=[]) for _ in range(5)],
206
  [],
207
  0
208
  )
209
+
210
  success, questions = quiz_app.generate_questions(text, num_questions)
211
+
212
  if not success or not questions:
213
  return (
214
+ gr.update(value="Failed to generate questions. Please try again with different content."),
215
  *[gr.update(visible=False, choices=[]) for _ in range(5)],
216
  [],
217
  0
218
  )
219
 
220
  # Update question display
221
+ questions_html = "# 📝 Assessment Questions\n\n"
222
+ questions_html += "> Please select one answer for each question below.\n\n"
223
+
224
  for i, q in enumerate(questions, 1):
225
  questions_html += f"### Question {i}\n{q['question']}\n\n"
226
 
 
232
  visible=True,
233
  choices=questions[i]["options"],
234
  value=None,
235
+ label=f"Select answer for Question {i+1}"
236
  ))
237
  else:
238
  updates.append(gr.update(visible=False, choices=[]))
239
 
240
+ return (gr.update(value=questions_html), *updates, questions, 1)
 
241
 
242
  def submit_quiz(q1, q2, q3, q4, q5, questions):
243
  answers = [q1, q2, q3, q4, q5][:len(questions)]