Vadym Myroshnyk commited on
Commit
4fe5320
·
1 Parent(s): a9763ea
Files changed (1) hide show
  1. utils/comparator.py +29 -58
utils/comparator.py CHANGED
@@ -1,66 +1,37 @@
 
1
  import re
2
 
3
- from rapidfuzz import fuzz
4
 
 
 
 
5
 
6
- def preprocess(text):
7
- return re.sub(r"[^\w\s]", "", text.lower()).split()
8
-
9
-
10
- def is_position_acceptable(expected_index, actual_index, max_shift=1):
11
- return abs(expected_index - actual_index) <= max_shift
12
-
13
-
14
- def highlight_fuzzy_diff(user_text, original_text, threshold=92, max_position_shift=1):
15
- user_words = preprocess(user_text)
16
- original_words = preprocess(original_text)
17
-
18
- used_user_indices = set()
19
  highlighted = []
20
  correct_count = 0
21
-
22
- original_display_words = re.findall(r"\w+|[^\w\s]", original_text)
23
-
24
- display_index = 0
25
-
26
- for i, orig_word in enumerate(original_words):
27
- best_score = 0
28
- best_index = -1
29
- for j, user_word in enumerate(user_words):
30
- if j in used_user_indices:
31
- continue
32
- if not is_position_acceptable(i, j, max_position_shift):
33
- continue
34
- score = fuzz.ratio(orig_word, user_word)
35
- if score > best_score:
36
- best_score = score
37
- best_index = j
38
-
39
- while display_index < len(original_display_words):
40
- display_candidate = original_display_words[display_index]
41
- if re.match(r"\w+", display_candidate):
42
- display_word = display_candidate
43
- display_index += 1
44
- break
45
- else:
46
- highlighted.append(display_candidate)
47
- display_index += 1
48
- else:
49
- display_word = orig_word
50
-
51
- if best_score >= threshold and best_index != -1:
52
- used_user_indices.add(best_index)
53
- highlighted.append(
54
- f"<span style='background-color:#e6ffe6; color:#006600; padding:4px 10px; "
55
- f"margin:4px; border-radius:999px; font-weight:500; display:inline-block;'>{display_word}</span>"
56
- )
57
- correct_count += 1
58
  else:
59
- highlighted.append(
60
- f"<span style='background-color:#ffe6e6; color:#990000; padding:4px 10px; "
61
- f"margin:4px; border-radius:999px; font-weight:500; display:inline-block;'>...</span>"
62
- )
63
-
64
- score_percent = round((correct_count / len(original_words)) * 100) if original_words else 0
 
 
 
 
 
65
  return " ".join(highlighted), score_percent
66
-
 
1
+ import difflib
2
  import re
3
 
 
4
 
5
+ def highlight_fuzzy_diff(user_text, original_text):
6
+ original_words = re.findall(r"\w+|[^\w\s]", original_text)
7
+ user_words = re.findall(r"\w+|[^\w\s]", user_text)
8
 
9
+ matcher = difflib.SequenceMatcher(None, user_words, original_words)
 
 
 
 
 
 
 
 
 
 
 
 
10
  highlighted = []
11
  correct_count = 0
12
+ total_count = 0
13
+
14
+ for op, i1, i2, j1, j2 in matcher.get_opcodes():
15
+ segment = original_words[j1:j2]
16
+ if op == 'equal':
17
+ for word in segment:
18
+ if re.match(r"\w+", word): # тільки слова рахуються в score
19
+ correct_count += 1
20
+ total_count += 1
21
+ highlighted.append(
22
+ f"<span style='background-color:#e6ffe6; color:#006600; padding:4px 10px; "
23
+ f"margin:4px; border-radius:999px; font-weight:500; display:inline-block;'>{word}</span>"
24
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  else:
26
+ for word in segment:
27
+ if re.match(r"\w+", word):
28
+ total_count += 1
29
+ highlighted.append(
30
+ f"<span style='background-color:#ffe6e6; color:#990000; padding:4px 10px; "
31
+ f"margin:4px; border-radius:999px; font-weight:500; display:inline-block;'>...</span>"
32
+ )
33
+ else:
34
+ highlighted.append(word)
35
+
36
+ score_percent = round((correct_count / total_count) * 100) if total_count > 0 else 0
37
  return " ".join(highlighted), score_percent