Initial commit
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
from pathlib import Path
|
||||
import PyPDF2
|
||||
from typing import Dict, List, Optional
|
||||
from pydantic import BaseModel
|
||||
from modules.pdf_utils import PDFUtils
|
||||
|
||||
class TestAnalysis(BaseModel):
|
||||
overall_score: float
|
||||
section_scores: Dict[str, float]
|
||||
feedback: str
|
||||
recommendations: List[str]
|
||||
detailed_analysis: Optional[Dict] = None
|
||||
|
||||
class TestAnalyzer:
|
||||
def __init__(self, api_key: str):
|
||||
self.api_key = api_key
|
||||
|
||||
def extract_text_from_pdf(self, pdf_file: Path) -> str:
|
||||
"""
|
||||
Extract text content from a PDF file
|
||||
"""
|
||||
if not pdf_file.exists():
|
||||
raise FileNotFoundError(f"PDF file not found: {pdf_file}")
|
||||
|
||||
text = ""
|
||||
with open(pdf_file, 'rb') as file:
|
||||
pdf_reader = PyPDF2.PdfReader(file)
|
||||
for page in pdf_reader.pages:
|
||||
text += page.extract_text() + "\n"
|
||||
|
||||
return text
|
||||
|
||||
def analyze_test(self, pdf_content: str, marks_data: Dict, mode: str = 'detailed') -> TestAnalysis:
|
||||
"""
|
||||
Analyze a test and generate feedback based on marks data
|
||||
"""
|
||||
# Calculate overall score
|
||||
total_marks = sum(marks_data.values())
|
||||
max_marks = len(marks_data) * 100 # Assuming each question is out of 100
|
||||
overall_score = (total_marks / max_marks) * 100
|
||||
|
||||
# Calculate section scores (group by first part of question number)
|
||||
section_scores = {}
|
||||
for question, marks in marks_data.items():
|
||||
section = question.split('.')[0]
|
||||
if section not in section_scores:
|
||||
section_scores[section] = []
|
||||
section_scores[section].append(marks)
|
||||
|
||||
# Calculate average for each section
|
||||
for section, marks in section_scores.items():
|
||||
section_scores[section] = sum(marks) / len(marks)
|
||||
|
||||
# Generate feedback
|
||||
feedback = self._generate_feedback(overall_score, section_scores)
|
||||
|
||||
# Generate recommendations
|
||||
recommendations = self._generate_recommendations(section_scores)
|
||||
|
||||
# Create detailed analysis if requested
|
||||
detailed_analysis = None
|
||||
if mode == 'detailed':
|
||||
detailed_analysis = {
|
||||
'question_analysis': self._analyze_questions(pdf_content, marks_data),
|
||||
'strengths': self._identify_strengths(section_scores),
|
||||
'weaknesses': self._identify_weaknesses(section_scores)
|
||||
}
|
||||
|
||||
return TestAnalysis(
|
||||
overall_score=overall_score,
|
||||
section_scores=section_scores,
|
||||
feedback=feedback,
|
||||
recommendations=recommendations,
|
||||
detailed_analysis=detailed_analysis
|
||||
)
|
||||
|
||||
def _generate_feedback(self, overall_score: float, section_scores: Dict[str, float]) -> str:
|
||||
"""
|
||||
Generate feedback based on overall score and section scores
|
||||
"""
|
||||
if overall_score >= 90:
|
||||
return "Excellent performance! You have demonstrated a strong understanding of the material."
|
||||
elif overall_score >= 80:
|
||||
return "Very good performance. You have a solid grasp of most concepts."
|
||||
elif overall_score >= 70:
|
||||
return "Good performance. You understand the main concepts but could improve in some areas."
|
||||
elif overall_score >= 60:
|
||||
return "Satisfactory performance. You have a basic understanding but need to work on several areas."
|
||||
else:
|
||||
return "Needs improvement. Focus on understanding the fundamental concepts better."
|
||||
|
||||
def _generate_recommendations(self, section_scores: Dict[str, float]) -> List[str]:
|
||||
"""
|
||||
Generate recommendations based on section scores
|
||||
"""
|
||||
recommendations = []
|
||||
for section, score in section_scores.items():
|
||||
if score < 70:
|
||||
recommendations.append(f"Focus on improving your understanding of Section {section}")
|
||||
elif score < 80:
|
||||
recommendations.append(f"Review Section {section} to strengthen your knowledge")
|
||||
|
||||
if not recommendations:
|
||||
recommendations.append("Continue practicing to maintain your strong performance")
|
||||
|
||||
return recommendations
|
||||
|
||||
def _analyze_questions(self, pdf_content: str, marks_data: Dict) -> Dict:
|
||||
"""
|
||||
Analyze individual questions
|
||||
"""
|
||||
question_analysis = {}
|
||||
for question, marks in marks_data.items():
|
||||
question_analysis[question] = {
|
||||
'score': marks,
|
||||
'performance': 'excellent' if marks >= 90 else 'good' if marks >= 70 else 'needs_improvement'
|
||||
}
|
||||
return question_analysis
|
||||
|
||||
def _identify_strengths(self, section_scores: Dict[str, float]) -> List[str]:
|
||||
"""
|
||||
Identify strong sections
|
||||
"""
|
||||
return [f"Section {section}" for section, score in section_scores.items() if score >= 80]
|
||||
|
||||
def _identify_weaknesses(self, section_scores: Dict[str, float]) -> List[str]:
|
||||
"""
|
||||
Identify weak sections
|
||||
"""
|
||||
return [f"Section {section}" for section, score in section_scores.items() if score < 70]
|
||||
Reference in New Issue
Block a user