Spaces:
Restarting
Restarting
| """ | |
| MCQ Validator and Scorer | |
| """ | |
| from typing import List, Dict | |
| class MCQValidator: | |
| def validate_mcq(mcq: Dict) -> bool: | |
| """ | |
| Validate if MCQ has all required fields | |
| Args: | |
| mcq: MCQ dictionary | |
| Returns: | |
| True if valid, False otherwise | |
| """ | |
| required_fields = ['question', 'options', 'correct_answer'] | |
| # Check required fields | |
| if not all(field in mcq for field in required_fields): | |
| return False | |
| # Check options | |
| if not isinstance(mcq['options'], dict): | |
| return False | |
| if len(mcq['options']) < 2: | |
| return False | |
| # Check correct answer | |
| if mcq['correct_answer'] not in mcq['options']: | |
| return False | |
| return True | |
| def score_answers( | |
| mcqs: List[Dict], | |
| user_answers: Dict[int, str] | |
| ) -> Dict: | |
| """ | |
| Score user answers | |
| Args: | |
| mcqs: List of MCQs | |
| user_answers: Dict mapping question index to user's answer | |
| Returns: | |
| Scoring result dictionary | |
| """ | |
| total_questions = len(mcqs) | |
| correct_count = 0 | |
| results = [] | |
| for i, mcq in enumerate(mcqs): | |
| user_answer = user_answers.get(i) | |
| correct_answer = mcq['correct_answer'] | |
| is_correct = user_answer == correct_answer | |
| if is_correct: | |
| correct_count += 1 | |
| results.append({ | |
| 'question_index': i, | |
| 'question': mcq['question'], | |
| 'user_answer': user_answer, | |
| 'correct_answer': correct_answer, | |
| 'is_correct': is_correct, | |
| 'explanation': mcq.get('explanation', '') | |
| }) | |
| score_percentage = (correct_count / total_questions * 100) if total_questions > 0 else 0 | |
| return { | |
| 'total_questions': total_questions, | |
| 'correct_answers': correct_count, | |
| 'incorrect_answers': total_questions - correct_count, | |
| 'score_percentage': round(score_percentage, 2), | |
| 'grade': MCQValidator._calculate_grade(score_percentage), | |
| 'results': results | |
| } | |
| def _calculate_grade(score: float) -> str: | |
| """Calculate letter grade from score""" | |
| if score >= 90: | |
| return 'A+' | |
| elif score >= 80: | |
| return 'A' | |
| elif score >= 70: | |
| return 'B' | |
| elif score >= 60: | |
| return 'C' | |
| elif score >= 50: | |
| return 'D' | |
| else: | |
| return 'F' | |