Spaces:
Build error
Build error
import ast | |
from pymongo import MongoClient | |
from datetime import datetime | |
import openai | |
import google.generativeai as genai | |
from google.generativeai import GenerativeModel | |
from dotenv import load_dotenv | |
import os | |
from file_upload_vectorize import resources_collection, vectors_collection, courses_collection2, faculty_collection | |
# Load environment variables | |
load_dotenv() | |
MONGO_URI = os.getenv('MONGO_URI') | |
OPENAI_KEY = os.getenv('OPENAI_KEY') | |
GEMINI_KEY = os.getenv('GEMINI_KEY') | |
# Configure APIs | |
openai.api_key = OPENAI_KEY | |
genai.configure(api_key=GEMINI_KEY) | |
model = genai.GenerativeModel('gemini-pro') | |
# Connect to MongoDB | |
client = MongoClient(MONGO_URI) | |
db = client['novascholar_db'] | |
quizzes_collection = db["quizzes"] | |
def strip_code_markers(response_text): | |
"""Strip off the markers ``` and python from a LLM model's response""" | |
if response_text.startswith("```python"): | |
response_text = response_text[len("```python"):].strip() | |
if response_text.startswith("```"): | |
response_text = response_text[len("```"):].strip() | |
if response_text.endswith("```"): | |
response_text = response_text[:-len("```")].strip() | |
return response_text | |
# New function to generate MCQs using Gemini | |
def generate_mcqs(context, num_questions, session_title, session_description): | |
"""Generate MCQs either from context or session details""" | |
try: | |
# Initialize Gemini model | |
if context: | |
prompt = f""" | |
Based on the following content, generate {num_questions} multiple choice questions. | |
Format each question as a Python dictionary with the following structure: | |
{{ | |
"question": "Question text here", | |
"options": ["A) option1", "B) option2", "C) option3", "D) option4"], | |
"correct_option": "A) option1" or "B) option2" or "C) option3" or "D) option4" | |
}} | |
Content: | |
{context} | |
Generate challenging but clear questions that test understanding of key concepts. | |
Return only the Python list of dictionaries. | |
""" | |
else: | |
prompt = f""" | |
Generate {num_questions} multiple choice questions about the topic: | |
Title: {session_title} | |
Description: {session_description} | |
Format each question as a Python dictionary with the following structure: | |
{{ | |
"question": "Question text here", | |
"options": ["A) option1", "B) option2", "C) option3", "D) option4"], | |
"correct_option": "A" or "B" or "C" or "D" | |
}} | |
Generate challenging but clear questions. | |
Return only the Python list of dictionaries without any additional formatting or markers | |
Do not write any other text, do not start the response with (```python), do not end the response with backticks(```) | |
A Sample response should look like this: Response Text: [ | |
{ | |
"question": "Which of the following is NOT a valid data type in C++?", | |
"options": ["int", "double", "boolean", "char"], | |
"correct_option": "C" | |
} | |
] (Notice that there are no backticks(```) around the response and no (```python)) | |
. | |
""" | |
response = model.generate_content(prompt) | |
response_text = response.text.strip() | |
print("Response Text:", response_text) | |
modified_response_text = strip_code_markers(response_text) | |
print("Response Text Modified to:", modified_response_text) | |
# Extract and parse the response to get the list of MCQs | |
mcqs = ast.literal_eval(modified_response_text) # Be careful with eval, consider using ast.literal_eval for production | |
print(mcqs) | |
if not mcqs: | |
raise ValueError("No questions generated") | |
return mcqs | |
except Exception as e: | |
print(f"Error generating MCQs: , error: {e}") | |
return None | |
# New function to save quiz to database | |
def save_quiz(course_id, session_id, title, questions, user_id): | |
"""Save quiz to database""" | |
try: | |
quiz_data = { | |
"user_id": user_id, | |
"course_id": course_id, | |
"session_id": session_id, | |
"title": title, | |
"questions": questions, | |
"created_at": datetime.utcnow(), | |
"status": "active", | |
"submissions": [] | |
} | |
result = quizzes_collection.insert_one(quiz_data) | |
return result.inserted_id | |
except Exception as e: | |
print(f"Error saving quiz: {e}") | |
return None | |
def get_student_quiz_score(quiz_id, student_id): | |
"""Get student's score for a specific quiz""" | |
quiz = quizzes_collection.find_one( | |
{ | |
"_id": quiz_id, | |
"submissions.student_id": student_id | |
}, | |
{"submissions.$": 1} | |
) | |
if quiz and quiz.get('submissions'): | |
return quiz['submissions'][0].get('score') | |
return None | |
# def submit_quiz_answers(quiz_id, student_id, student_answers): | |
# """Submit and score student's quiz answers""" | |
# quiz = quizzes_collection.find_one({"_id": quiz_id}) | |
# if not quiz: | |
# return None | |
# # Calculate score | |
# correct_answers = 0 | |
# total_questions = len(quiz['questions']) | |
# for q_idx, question in enumerate(quiz['questions']): | |
# if student_answers.get(str(q_idx)) == question['correct_option']: | |
# correct_answers += 1 | |
# score = (correct_answers / total_questions) * 100 | |
# # Store submission | |
# submission_data = { | |
# "student_id": student_id, | |
# "answers": student_answers, | |
# "score": score, | |
# "submitted_at": datetime.utcnow() | |
# } | |
# # Update quiz with submission | |
# quizzes_collection.update_one( | |
# {"_id": quiz_id}, | |
# { | |
# "$push": {"submissions": submission_data} | |
# } | |
# ) | |
# return score | |
def submit_quiz_answers(quiz_id, student_id, student_answers): | |
"""Submit and score student's quiz answers""" | |
try: | |
quiz = quizzes_collection.find_one({"_id": quiz_id}) | |
if not quiz: | |
return None | |
# Calculate score | |
correct_answers = 0 | |
total_questions = len(quiz['questions']) | |
for q_idx, question in enumerate(quiz['questions']): | |
student_answer = student_answers.get(str(q_idx)) | |
if student_answer: # Only check if answer was provided | |
# Extract the option letter (A, B, C, D) from the full answer string | |
answer_letter = student_answer.split(')')[0].strip() | |
if answer_letter == question['correct_option']: | |
correct_answers += 1 | |
score = (correct_answers / total_questions) * 100 | |
# Store submission | |
submission_data = { | |
"student_id": student_id, | |
"answers": student_answers, | |
"score": score, | |
"submitted_at": datetime.utcnow() | |
} | |
# Update quiz with submission | |
result = quizzes_collection.update_one( | |
{"_id": quiz_id}, | |
{"$push": {"submissions": submission_data}} | |
) | |
return score if result.modified_count > 0 else None | |
except Exception as e: | |
print(f"Error submitting quiz: {e}") | |
return None |