-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathanswer_validator.py
More file actions
78 lines (62 loc) 路 2.94 KB
/
Copy pathanswer_validator.py
File metadata and controls
78 lines (62 loc) 路 2.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
"""
Answer validation utilities for COMPU LOGIC
Provides robust answer checking with normalization and fuzzy matching
"""
import re
from typing import Tuple
from difflib import SequenceMatcher
class AnswerValidator:
"""Validates user answers against correct answers with multiple strategies"""
@staticmethod
def normalize_text(text: str) -> str:
"""Normalize text for comparison"""
if not text:
return ""
# Convert to lowercase and strip whitespace
normalized = text.lower().strip()
# Remove extra whitespace
normalized = re.sub(r'\s+', ' ', normalized)
# Remove punctuation that doesn't affect meaning
normalized = re.sub(r'[.,;:!?"]', '', normalized)
return normalized
@staticmethod
def check_exact_match(user_answer: str, correct_answer: str) -> bool:
"""Check for exact match after normalization"""
return AnswerValidator.normalize_text(user_answer) == AnswerValidator.normalize_text(correct_answer)
@staticmethod
def check_substring_match(user_answer: str, correct_answer: str) -> bool:
"""Check if user answer is contained in correct answer"""
user_norm = AnswerValidator.normalize_text(user_answer)
correct_norm = AnswerValidator.normalize_text(correct_answer)
if not user_norm or not correct_norm:
return False
return user_norm in correct_norm
@staticmethod
def check_fuzzy_match(user_answer: str, correct_answer: str, threshold: float = 0.8) -> bool:
"""Check similarity using fuzzy matching"""
user_norm = AnswerValidator.normalize_text(user_answer)
correct_norm = AnswerValidator.normalize_text(correct_answer)
if not user_norm or not correct_norm:
return False
similarity = SequenceMatcher(None, user_norm, correct_norm).ratio()
return similarity >= threshold
@staticmethod
def validate_answer(user_answer: str, correct_answer: str) -> Tuple[bool, str]:
"""
Validate user answer with multiple strategies
Returns:
Tuple of (is_correct, feedback_message)
"""
if AnswerValidator.check_exact_match(user_answer, correct_answer):
return True, "Exact match!"
if AnswerValidator.check_substring_match(user_answer, correct_answer):
return True, "Correct concept identified!"
if AnswerValidator.check_fuzzy_match(user_answer, correct_answer):
return True, "Close enough - good understanding!"
return False, "Answer needs improvement"
# Convenience function for backward compatibility
def validate_answer(user_answer: str, correct_answer: str) -> bool:
"""Simple boolean validation for existing code"""
validator = AnswerValidator()
is_correct, _ = validator.validate_answer(user_answer, correct_answer)
return is_correct