Spaces:
Build error
Build error
# assignment_evaluation.py | |
import streamlit as st | |
from datetime import datetime | |
from pymongo import MongoClient | |
import os | |
from openai import OpenAI | |
from dotenv import load_dotenv | |
from bson import ObjectId | |
load_dotenv() | |
# MongoDB setup | |
MONGO_URI = os.getenv('MONGO_URI') | |
client = MongoClient(MONGO_URI) | |
db = client["novascholar_db"] | |
assignments_collection = db["assignments"] | |
assignment_evaluation_collection = db["assignment_evaluation"] | |
resources_collection = db["resources"] | |
students_collection = db["students"] | |
def evaluate_assignment(session_id, student_id, assignment_id): | |
""" | |
Generate evaluation and analysis for submitted assignments | |
""" | |
try: | |
# Fetch assignment and student submission | |
assignment = assignments_collection.find_one({"_id": assignment_id}) | |
if not assignment: | |
return None | |
# Find student's submission | |
submission = next( | |
(sub for sub in assignment.get('submissions', []) | |
if sub['student_id'] == str(student_id)), | |
None | |
) | |
if not submission: | |
return None | |
# Default rubric for assignment evaluation | |
default_rubric = """ | |
1. Understanding & Implementation (1-4): | |
- Demonstrates understanding of assignment requirements | |
- Implements required components correctly | |
- Shows attention to detail | |
2. Quality & Completeness (1-4): | |
- Work is complete and thorough | |
- Meets all assignment objectives | |
- Shows evidence of effort and care | |
3. Presentation & Organization (1-4): | |
- Clear and professional presentation | |
- Well-structured and organized | |
- Follows required format and guidelines | |
""" | |
# Initialize OpenAI client | |
client = OpenAI(api_key=os.getenv('OPENAI_KEY')) | |
# Create evaluation prompt | |
prompt_template = f"""As an assignment evaluator, assess this student's submission based on the provided rubric criteria. Follow these guidelines: | |
1. Evaluation Process: | |
- Use each rubric criterion (scored 1-4) | |
- Evaluate completeness and quality | |
- Check alignment with assignment requirements | |
- Calculate final score: sum of criteria scores converted to 10-point scale | |
Assignment Title: {assignment['title']} | |
Due Date: {assignment['due_date']} | |
Submission Content: | |
{submission.get('text_content', 'No text content available')} | |
Rubric Criteria: | |
{default_rubric} | |
Provide your assessment in the following format: | |
**Overall Score and Summary** | |
- Score: [X]/10 | |
- Overall Assessment: [2-3 sentence summary] | |
**Strengths** | |
- [Key strength 1] | |
- [Key strength 2] | |
- [Key strength 3] | |
**Areas for Improvement** | |
- [Improvement point 1] | |
- [Improvement point 2] | |
- [Improvement point 3] | |
**Specific Recommendations** | |
[2-3 sentences with actionable feedback] | |
""" | |
# Generate evaluation using OpenAI | |
response = client.chat.completions.create( | |
model="gpt-4o-mini", | |
messages=[{"role": "user", "content": prompt_template}], | |
max_tokens=1000, | |
temperature=0.4 | |
) | |
# Store evaluation in MongoDB | |
evaluation_doc = { | |
"assignment_id": assignment_id, | |
"student_id": student_id, | |
"session_id": session_id, | |
"evaluation": response.choices[0].message.content, | |
"evaluated_at": datetime.utcnow() | |
} | |
assignment_evaluation_collection.insert_one(evaluation_doc) | |
return evaluation_doc | |
except Exception as e: | |
print(f"Error in evaluate_assignment: {str(e)}") | |
return None | |
def display_evaluation_to_faculty(session_id, student_id, course_id): | |
""" | |
Display interface for faculty to generate and view assignment evaluations | |
""" | |
st.header("Evaluate Assignments") | |
try: | |
# Fetch available assignments | |
assignments = list(assignments_collection.find({ | |
"session_id": str(session_id), | |
"course_id": course_id | |
})) | |
if not assignments: | |
st.info("No assignments found for this session.") | |
return | |
# Select assignment | |
assignment_options = { | |
f"{assignment['title']} (Due: {assignment['due_date'].strftime('%Y-%m-%d')})" if 'due_date' in assignment else assignment['title']: assignment['_id'] | |
for assignment in assignments | |
} | |
if assignment_options: | |
selected_assignment = st.selectbox( | |
"Select Assignment to Evaluate", | |
options=list(assignment_options.keys()) | |
) | |
if selected_assignment: | |
assignment_id = assignment_options[selected_assignment] | |
assignment = assignments_collection.find_one({"_id": assignment_id}) | |
if assignment: | |
submissions = assignment.get('submissions', []) | |
if not submissions: | |
st.warning("No submissions found for this assignment.") | |
return | |
# Create a dropdown for student submissions | |
student_options = { | |
f"{students_collection.find_one({'_id': ObjectId(sub['student_id'])})['full_name']} (Submitted: {sub['submitted_at'].strftime('%Y-%m-%d %H:%M')})": sub['student_id'] | |
for sub in submissions | |
} | |
selected_student = st.selectbox( | |
"Select Student Submission", | |
options=list(student_options.keys()) | |
) | |
if selected_student: | |
student_id = student_options[selected_student] | |
submission = next(sub for sub in submissions if sub['student_id'] == student_id) | |
# Display submission details | |
st.subheader("Submission Details") | |
st.markdown(f"**Submitted:** {submission['submitted_at'].strftime('%Y-%m-%d %H:%M')}") | |
st.markdown(f"**File Name:** {submission['file_name']}") | |
# Add download button for submitted file | |
if 'file_content' in submission: | |
st.download_button( | |
label="Download Submission", | |
data=submission['file_content'], | |
file_name=submission['file_name'], | |
mime=submission['file_type'] | |
) | |
# Check for existing evaluation | |
existing_eval = assignment_evaluation_collection.find_one({ | |
"assignment_id": assignment_id, | |
"student_id": student_id, | |
"session_id": str(session_id) | |
}) | |
if existing_eval: | |
st.subheader("Evaluation Results") | |
st.markdown(existing_eval['evaluation']) | |
st.success("✓ Evaluation completed") | |
if st.button("Regenerate Evaluation"): | |
with st.spinner("Regenerating evaluation..."): | |
evaluation = evaluate_assignment( | |
str(session_id), | |
student_id, | |
assignment_id | |
) | |
if evaluation: | |
st.success("Evaluation regenerated successfully!") | |
st.rerun() | |
else: | |
st.error("Error regenerating evaluation.") | |
else: | |
if st.button("Generate Evaluation"): | |
with st.spinner("Generating evaluation..."): | |
evaluation = evaluate_assignment( | |
str(session_id), | |
student_id, | |
assignment_id | |
) | |
if evaluation: | |
st.success("Evaluation generated successfully!") | |
st.markdown("### Generated Evaluation") | |
st.markdown(evaluation['evaluation']) | |
st.rerun() | |
else: | |
st.error("Error generating evaluation.") | |
except Exception as e: | |
st.error(f"An error occurred while loading the evaluations: {str(e)}") | |
print(f"Error in display_evaluation_to_faculty: {str(e)}") | |
def display_assignment_results(assignment_id, student_id): | |
""" | |
Display assignment results and analysis for a student | |
""" | |
try: | |
# Fetch analysis from evaluation collection | |
analysis = assignment_evaluation_collection.find_one({ | |
"assignment_id": assignment_id, | |
"student_id": str(student_id) | |
}) | |
if not analysis: | |
st.info("Evaluation will be available soon. Please check back later.") | |
return | |
st.header("Assignment Evaluation") | |
# Display evaluation content | |
st.markdown(analysis["evaluation"]) | |
# Display evaluation timestamp | |
st.caption(f"Evaluation generated on: {analysis['evaluated_at'].strftime('%Y-%m-%d %H:%M:%S UTC')}") | |
except Exception as e: | |
st.error("An error occurred while loading the evaluation. Please try again later.") | |
print(f"Error in display_assignment_results: {str(e)}") |