louiecerv commited on
Commit
a9c2070
Β·
1 Parent(s): 689e65c

completed the multimodal page

Browse files
app.py CHANGED
@@ -11,11 +11,10 @@ if "is_starting" not in st.session_state:
11
  if "authenticated" not in st.session_state:
12
  st.session_state["authenticated"] = False
13
 
14
- from pages.About import show_about
15
- from pages.Text_prompt import show_text_prompt
16
- from pages.Multimodal import show_multimodal
17
- from pages.Settings import show_settings
18
-
19
 
20
  if "authenticated" not in st.session_state:
21
  st.session_state["authenticated"] = False
 
11
  if "authenticated" not in st.session_state:
12
  st.session_state["authenticated"] = False
13
 
14
+ #from pages.About import show_about
15
+ #from pages.Text_prompt import show_text_prompt
16
+ #from pages.Multimodal import show_multimodal
17
+ #from pages.Settings import show_settings
 
18
 
19
  if "authenticated" not in st.session_state:
20
  st.session_state["authenticated"] = False
pages/{About.py β†’ 1_About.py} RENAMED
File without changes
pages/{Text_prompt.py β†’ 2_Text_prompt.py} RENAMED
File without changes
pages/{Multimodal.py β†’ 3_Multimodal.py} RENAMED
@@ -15,6 +15,15 @@ from reportlab.lib.pagesizes import letter
15
  from reportlab.pdfgen import canvas
16
  from reportlab.platypus import Paragraph, Frame, Spacer
17
  from reportlab.lib.styles import getSampleStyleSheet
 
 
 
 
 
 
 
 
 
18
 
19
  MODEL_ID = "gemini-2.0-flash-exp"
20
  api_key = os.getenv("GEMINI_API_KEY")
@@ -171,28 +180,32 @@ def create_pdf(data):
171
  data = json.loads(data)
172
 
173
  if 'metadata' not in data or 'content' not in data:
174
- print("Error: Invalid data format. Missing 'metadata' or 'content' keys.")
175
  return None
176
 
177
  metadata = data['metadata']
178
  content = data['content']
179
-
180
- print(f"metadata: {metadata}")
181
 
182
  # Validate metadata
183
  required_metadata_keys = ['subject', 'topic', 'exam_type', 'num_questions']
184
  if not all(key in metadata for key in required_metadata_keys):
185
- print("Error: Invalid metadata format. Missing required keys.")
186
  return None
187
 
188
  # Create a unique filename with timestamp
189
  timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
190
  pdf_filename = f"quiz_output_{timestamp}.pdf"
191
- pdf_path = os.path.join(os.getcwd(), pdf_filename)
192
-
 
 
 
193
  c = canvas.Canvas(pdf_path, pagesize=letter)
194
  c.setFont("Helvetica", 10)
195
 
 
 
196
  styles = getSampleStyleSheet()
197
  style_normal = styles["Normal"]
198
 
@@ -203,57 +216,132 @@ def create_pdf(data):
203
 
204
  for idx, q in enumerate(content):
205
  if not isinstance(q, dict):
206
- print(f"Error: Invalid question format at index {idx}. Skipping...")
207
- continue
208
-
209
- # Validate question structure
210
- required_question_keys = ['question', 'options', 'correct_answer']
211
- if not all(key in q for key in required_question_keys):
212
- print(f"Error: Invalid question format at index {idx}. Skipping...")
213
  continue
214
-
215
- if first_page:
216
- # Print metadata once
217
- for key, label in [("subject", "Subject"), ("topic", "Topic"),
218
- ("exam_type", "Type"), ("num_questions", "Number of Questions")]:
219
- c.drawString(50, y_position, f"{label}: {metadata[key]}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
220
  y_position -= line_height
221
 
222
- y_position -= line_height # Extra space before questions
223
- first_page = False
224
-
225
- # Print question
226
- question_text = f"{idx+1}. {q['question']}"
227
- paragraph = Paragraph(question_text, style_normal)
228
- paragraph.wrapOn(c, frame_width, 100)
229
- paragraph.drawOn(c, 50, y_position)
230
-
231
- y_position -= paragraph.height
232
-
233
- # Print options
234
- for option_idx, option in enumerate(q['options'], ord('a')):
235
- c.drawString(70, y_position, f"{chr(option_idx)}) {option}")
236
- y_position -= line_height
237
-
238
- if y_position < 50:
239
- c.showPage()
240
- c.setFont("Helvetica", 10)
241
- y_position = 750
242
-
243
- # Print correct answer
244
- c.drawString(70, y_position, f"Correct Answer: {q['correct_answer']}")
245
- y_position -= line_height * 2
246
-
247
- if y_position < 50:
248
- c.showPage()
249
- c.setFont("Helvetica", 10)
250
- y_position = 750
 
 
 
 
 
 
 
 
 
251
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
252
  c.save()
253
  return pdf_path
254
 
255
  except Exception as e:
256
- print(f"Error creating PDF: {e}")
257
  return None
258
 
259
  def generate_quiz_content(data):
@@ -271,8 +359,9 @@ def generate_quiz_content(data):
271
  data = json.loads(data)
272
  metadata = data["metadata"]
273
  content = data["content"]
274
-
275
- md_text = f"""# {metadata['subject']} - {metadata['topic']}
 
276
 
277
  **Exam Type:** {metadata['exam_type']}
278
  **Number of Questions:** {metadata['num_questions']}
@@ -281,25 +370,76 @@ def generate_quiz_content(data):
281
  ---
282
 
283
  """
 
 
 
284
 
285
- for i, q in enumerate(content):
286
- md_text += f"""Question {i+1}:
 
287
 
288
- {q['question']}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
289
 
290
- **Options:**
291
 
292
  """
293
- for j, option in enumerate(q['options'], ord('a')):
294
- md_text += f"""{chr(j)}. {option}
 
 
 
 
 
 
 
295
  """
296
 
297
- md_text += f"""**Correct Answer:** {q['correct_answer']}
 
 
 
 
 
 
 
 
 
 
 
 
298
 
299
  ---
300
 
301
  """
302
 
 
 
 
 
 
 
 
 
 
 
 
 
 
303
  return md_text
304
 
305
  def generate_metadata(subject, topic, num_questions, exam_type):
@@ -367,6 +507,9 @@ def show_multimodal():
367
  username = st.session_state["username"]
368
  st.write(f"Welcome, {username}! This page allows you to generate questions based on an image or PDF file.")
369
 
 
 
 
370
  # we dont use the system instruction for now
371
  #system_instruction = get_system_instruction(username)
372
 
@@ -451,7 +594,7 @@ def show_multimodal():
451
  prompt += """Indicate whether the statement is true or false. Keep the statement brief and concise.
452
  Use the following JSON format for each question:
453
  [{
454
- "Statement": "Your question here",
455
  "options": ["True", "False"],
456
  "correct_answer": True"
457
  }, ... more questions]
@@ -529,20 +672,14 @@ def show_multimodal():
529
  st.markdown(quiz_markdown)
530
 
531
  pdf_path = create_pdf(json_string)
532
- print(pdf_path)
533
-
534
  if pdf_path:
535
- """Allows downloading the generated PDF."""
536
  try:
537
- # Use a temporary directory for file management
538
- with tempfile.TemporaryDirectory() as tmpdirname:
539
- temp_pdf_path = os.path.join(tmpdirname, os.path.basename(pdf_path))
540
- os.rename(pdf_path, temp_pdf_path) # Move PDF to the temporary directory
541
-
542
- with open(temp_pdf_path, "rb") as f:
543
- st.download_button("Download PDF", f, file_name=os.path.basename(pdf_path))
544
  except Exception as e:
545
- st.error(f"Error handling temporary file: {e}")
546
  else:
547
  st.error("Failed to generate the PDF. Please try again.")
548
 
 
15
  from reportlab.pdfgen import canvas
16
  from reportlab.platypus import Paragraph, Frame, Spacer
17
  from reportlab.lib.styles import getSampleStyleSheet
18
+ import shutil
19
+
20
+ import json
21
+ import os
22
+ import datetime
23
+ from reportlab.pdfgen import canvas
24
+ from reportlab.lib.pagesizes import letter, A4
25
+ from reportlab.lib.styles import getSampleStyleSheet
26
+ from reportlab.platypus import Paragraph
27
 
28
  MODEL_ID = "gemini-2.0-flash-exp"
29
  api_key = os.getenv("GEMINI_API_KEY")
 
180
  data = json.loads(data)
181
 
182
  if 'metadata' not in data or 'content' not in data:
183
+ st.error("Error: Invalid data format. Missing 'metadata' or 'content' keys.")
184
  return None
185
 
186
  metadata = data['metadata']
187
  content = data['content']
188
+
 
189
 
190
  # Validate metadata
191
  required_metadata_keys = ['subject', 'topic', 'exam_type', 'num_questions']
192
  if not all(key in metadata for key in required_metadata_keys):
193
+ st.error("Error: Invalid metadata format. Missing required keys.")
194
  return None
195
 
196
  # Create a unique filename with timestamp
197
  timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
198
  pdf_filename = f"quiz_output_{timestamp}.pdf"
199
+
200
+ # Get the temporary directory
201
+ temp_dir = tempfile.gettempdir()
202
+ pdf_path = os.path.join(temp_dir, pdf_filename)
203
+
204
  c = canvas.Canvas(pdf_path, pagesize=letter)
205
  c.setFont("Helvetica", 10)
206
 
207
+ exam_type = metadata['exam_type']
208
+
209
  styles = getSampleStyleSheet()
210
  style_normal = styles["Normal"]
211
 
 
216
 
217
  for idx, q in enumerate(content):
218
  if not isinstance(q, dict):
219
+ st.error(f"Error: Invalid question format at index {idx}. Skipping...")
 
 
 
 
 
 
220
  continue
221
+ if exam_type == "Multiple Choice":
222
+ # Validate question structure
223
+ required_question_keys = ['question', 'options', 'correct_answer']
224
+ if not all(key in q for key in required_question_keys):
225
+ st.error(f"Error: Invalid question format at index {idx}. Skipping...")
226
+ continue
227
+
228
+ if first_page:
229
+ # Print metadata once
230
+ for key, label in [("subject", "Subject"), ("topic", "Topic"),
231
+ ("exam_type", "Type"), ("num_questions", "Number of Questions")]:
232
+ c.drawString(50, y_position, f"{label}: {metadata[key]}")
233
+ y_position -= line_height
234
+
235
+ y_position -= line_height # Extra space before questions
236
+ first_page = False
237
+
238
+ # Print question
239
+ question_text = f"{idx+1}. {q['question']}"
240
+ paragraph = Paragraph(question_text, style_normal)
241
+ paragraph.wrapOn(c, frame_width, 100)
242
+ paragraph.drawOn(c, 50, y_position)
243
+
244
+ y_position -= paragraph.height
245
+
246
+ # Print options
247
+ for option_idx, option in enumerate(q['options'], ord('a')):
248
+ c.drawString(70, y_position, f"{chr(option_idx)}) {option}")
249
  y_position -= line_height
250
 
251
+ if y_position < 50:
252
+ c.showPage()
253
+ c.setFont("Helvetica", 10)
254
+ y_position = 750
255
+
256
+ # Print correct answer
257
+ c.drawString(70, y_position, f"Correct Answer: {q['correct_answer']}")
258
+ y_position -= line_height * 2
259
+
260
+ elif exam_type == "True or False":
261
+ # Validate question structure
262
+ required_question_keys = ['statement', 'options', 'correct_answer']
263
+ if not all(key in q for key in required_question_keys):
264
+ st.error(f"Error: Invalid question format at index {idx}. Skipping...")
265
+ continue
266
+
267
+ if first_page:
268
+ # Print metadata once
269
+ for key, label in [("subject", "Subject"), ("topic", "Topic"),
270
+ ("exam_type", "Type"), ("num_questions", "Number of Questions")]:
271
+ c.drawString(50, y_position, f"{label}: {metadata[key]}")
272
+ y_position -= line_height
273
+
274
+ y_position -= line_height # Extra space before questions
275
+ first_page = False
276
+
277
+ # Print question
278
+ question_text = f"{idx+1}. {q['statement']}"
279
+ paragraph = Paragraph(question_text, style_normal)
280
+ paragraph.wrapOn(c, frame_width, 100)
281
+ paragraph.drawOn(c, 50, y_position)
282
+
283
+ y_position -= paragraph.height
284
+
285
+ # Print options
286
+ for option_idx, option in enumerate(q['options'], ord('a')):
287
+ c.drawString(70, y_position, f"{option}")
288
+ y_position -= line_height
289
 
290
+ if y_position < 50:
291
+ c.showPage()
292
+ c.setFont("Helvetica", 10)
293
+ y_position = 750
294
+
295
+ # Print correct answer
296
+ c.drawString(70, y_position, f"Correct Answer: {q['correct_answer']}")
297
+ y_position -= line_height * 2
298
+
299
+ elif exam_type in ["Short Response", "Essay Type"]:
300
+ # Validate question structure
301
+ required_question_keys = ['question', 'correct_answer']
302
+ if not all(key in q for key in required_question_keys):
303
+ st.error(f"Error: Invalid question format at index {idx}. Skipping...")
304
+ continue
305
+
306
+ if first_page:
307
+ # Print metadata once
308
+ for key, label in [("subject", "Subject"), ("topic", "Topic"),
309
+ ("exam_type", "Type"), ("num_questions", "Number of Questions")]:
310
+ c.drawString(50, y_position, f"{label}: {metadata[key]}")
311
+ y_position -= line_height
312
+
313
+ y_position -= line_height # Extra space before questions
314
+ first_page = False
315
+
316
+ # Print question
317
+ question_text = f"{idx+1}. {q['question']}"
318
+ paragraph = Paragraph(question_text, style_normal)
319
+ paragraph.wrapOn(c, frame_width, y_position)
320
+ paragraph_height = paragraph.height
321
+ paragraph.drawOn(c, 50, y_position - paragraph_height)
322
+ y_position -= paragraph_height + line_height # Adjust position after the paragraph
323
+
324
+ # Print correct answer
325
+ answer = f"Correct Answer: {q['correct_answer']}"
326
+ paragraph = Paragraph(answer, style_normal)
327
+ paragraph.wrapOn(c, frame_width, y_position)
328
+ paragraph_height = paragraph.height
329
+ paragraph.drawOn(c, 50, y_position - paragraph_height)
330
+ y_position -= paragraph_height + line_height * 2 # Adjust position after the paragraph
331
+
332
+ # Add the notice at the end
333
+ if y_position < 50:
334
+ c.showPage()
335
+ y_position = 750
336
+
337
+ notice = "This exam was generated by the WVSU Exam Maker (c) 2025 West Visayas State University"
338
+ c.drawString(50, y_position, notice)
339
+
340
  c.save()
341
  return pdf_path
342
 
343
  except Exception as e:
344
+ st.error(f"Error creating PDF: {e}")
345
  return None
346
 
347
  def generate_quiz_content(data):
 
359
  data = json.loads(data)
360
  metadata = data["metadata"]
361
  content = data["content"]
362
+ exam_type = metadata["exam_type"]
363
+ if exam_type == "Multiple Choice":
364
+ md_text = f"""# {metadata['subject']} - {metadata['topic']}
365
 
366
  **Exam Type:** {metadata['exam_type']}
367
  **Number of Questions:** {metadata['num_questions']}
 
370
  ---
371
 
372
  """
373
+ for i, q in enumerate(content):
374
+ md_text += f"""Question {i+1}:
375
+ {q['question']}
376
 
377
+ """
378
+ for j, option in enumerate(q['options'], ord('a')):
379
+ md_text += f"""{chr(j)}. {option}
380
 
381
+ """
382
+ md_text += f"""**Correct Answer:** {q['correct_answer']}
383
+
384
+ ---
385
+
386
+ """
387
+ md_text += """This exam was generated by the WVSU Exam Maker
388
+ (c) 2025 West Visayas State University
389
+ """
390
+
391
+ elif exam_type == "True or False":
392
+ md_text = f"""# {metadata['subject']} - {metadata['topic']}
393
+
394
+ **Exam Type:** {metadata['exam_type']}
395
+ **Number of Questions:** {metadata['num_questions']}
396
+ **Timestamp:** {metadata['timestamp']}
397
 
398
+ ---
399
 
400
  """
401
+
402
+ for i, q in enumerate(content):
403
+ md_text += f"""Statement {i+1}:
404
+
405
+ {q['statement']}
406
+
407
+ """
408
+ for j, option in enumerate(q['options'], ord('a')):
409
+ md_text += f"""{option}
410
  """
411
 
412
+ md_text += f"""**Correct Answer:** {q['correct_answer']}
413
+
414
+ ---
415
+ """
416
+ md_text += """This exam was generated by the WVSU Exam Maker
417
+ (c) 2025 West Visayas State University"""
418
+
419
+ elif exam_type == "Short Response" or exam_type == "Essay Type":
420
+ md_text = f"""# {metadata['subject']} - {metadata['topic']}
421
+
422
+ **Exam Type:** {metadata['exam_type']}
423
+ **Number of Questions:** {metadata['num_questions']}
424
+ **Timestamp:** {metadata['timestamp']}
425
 
426
  ---
427
 
428
  """
429
 
430
+ for i, q in enumerate(content):
431
+ md_text += f"""Question {i+1}:
432
+
433
+ {q['question']}
434
+
435
+ """
436
+ md_text += f"""**Correct Answer:** {q['correct_answer']}
437
+
438
+ ---
439
+ """
440
+ md_text += """This exam was generated by the WVSU Exam Maker
441
+ (c) 2025 West Visayas State University"""
442
+
443
  return md_text
444
 
445
  def generate_metadata(subject, topic, num_questions, exam_type):
 
507
  username = st.session_state["username"]
508
  st.write(f"Welcome, {username}! This page allows you to generate questions based on an image or PDF file.")
509
 
510
+ # Display username and logout button on every page
511
+ st.sidebar.write(f"Current user: {st.session_state['username']}")
512
+
513
  # we dont use the system instruction for now
514
  #system_instruction = get_system_instruction(username)
515
 
 
594
  prompt += """Indicate whether the statement is true or false. Keep the statement brief and concise.
595
  Use the following JSON format for each question:
596
  [{
597
+ "statement": "Your statement here",
598
  "options": ["True", "False"],
599
  "correct_answer": True"
600
  }, ... more questions]
 
672
  st.markdown(quiz_markdown)
673
 
674
  pdf_path = create_pdf(json_string)
675
+
 
676
  if pdf_path:
677
+ """Click the button to download the generated PDF."""
678
  try:
679
+ with open(pdf_path, "rb") as f:
680
+ st.download_button("Download PDF", f, file_name=os.path.basename(pdf_path))
 
 
 
 
 
681
  except Exception as e:
682
+ st.error(f"Error handling file download: {e}")
683
  else:
684
  st.error("Failed to generate the PDF. Please try again.")
685
 
pages/{Settings.py β†’ 4_Settings.py} RENAMED
File without changes
users.db CHANGED
Binary files a/users.db and b/users.db differ