patruff commited on
Commit
0111e58
·
verified ·
1 Parent(s): 863e430

Upload tool

Browse files
Files changed (1) hide show
  1. tool.py +70 -18
tool.py CHANGED
@@ -1,7 +1,7 @@
1
  from smolagents.tools import Tool
2
  import pronouncing
3
- import json
4
  import difflib
 
5
  import string
6
 
7
  class ParodyWordSuggestionTool(Tool):
@@ -11,6 +11,41 @@ class ParodyWordSuggestionTool(Tool):
11
  inputs = {'target': {'type': 'string', 'description': 'The word you want to find rhyming alternatives for'}, 'word_list_str': {'type': 'string', 'description': 'JSON string of word list (e.g. \'["word1", "word2"]\')'}, 'min_similarity': {'type': 'string', 'description': 'Minimum similarity threshold (0.0-1.0)', 'nullable': True}}
12
  output_type = "string"
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  def forward(self, target: str, word_list_str: str, min_similarity: str = "0.5") -> str:
15
  """Get rhyming word suggestions."""
16
  import pronouncing
@@ -18,6 +53,8 @@ class ParodyWordSuggestionTool(Tool):
18
  import json
19
  from difflib import SequenceMatcher
20
 
 
 
21
  target = target.lower().strip(string.punctuation)
22
  min_similarity = float(min_similarity)
23
  suggestions = []
@@ -42,6 +79,14 @@ class ParodyWordSuggestionTool(Tool):
42
  target_phones = target_phones[0]
43
  target_phone_list = target_phones.split()
44
 
 
 
 
 
 
 
 
 
45
  # Check each word
46
  for word in words:
47
  word = word.lower().strip(string.punctuation)
@@ -50,39 +95,46 @@ class ParodyWordSuggestionTool(Tool):
50
  word_phones = phones[0]
51
  word_phone_list = word_phones.split()
52
 
 
 
 
 
 
 
 
 
53
  # 1. Rhyme score (most important - 60%)
54
  rhyme_score = 0
55
- if len(word_phone_list) > 1 and len(target_phone_list) > 1:
56
- # Check if words share the same ending (vowel + final consonants)
57
- vowel_plus_end = -2 # Index of the vowel in final syllable
58
- while vowel_plus_end < -1:
59
- if 'A' in word_phone_list[vowel_plus_end] or 'E' in word_phone_list[vowel_plus_end] or 'I' in word_phone_list[vowel_plus_end] or 'O' in word_phone_list[vowel_plus_end] or 'U' in word_phone_list[vowel_plus_end]:
60
- break
61
- vowel_plus_end += 1
62
-
63
- if vowel_plus_end == -1:
64
- vowel_plus_end = -2 # Fall back if no vowel found
65
-
66
- # Check if the ending (from vowel onwards) matches
67
- if word_phone_list[vowel_plus_end:] == target_phone_list[vowel_plus_end:]:
68
- rhyme_score = 1.0
69
 
70
  # 2. Syllable match (25%)
71
  target_syl = pronouncing.syllable_count(target_phones)
72
  word_syl = pronouncing.syllable_count(word_phones)
73
  syllable_score = 1.0 if target_syl == word_syl else 0.0
74
 
75
- # 3. Overall similarity (15%) - using string similarity
76
  string_similarity = SequenceMatcher(None, target, word).ratio()
77
 
78
- # Combined score (60% rhyme, 25% syllables, 15% similarity)
79
  similarity = (rhyme_score * 0.6) + (syllable_score * 0.25) + (string_similarity * 0.15)
80
 
81
  if similarity >= min_similarity:
82
  suggestions.append({
83
  "word": word,
84
  "similarity": round(similarity, 3),
85
- "rhyme_match": rhyme_score == 1.0,
 
86
  "syllable_match": syllable_score == 1.0,
87
  "string_similarity": round(string_similarity, 3),
88
  "syllables": word_syl,
 
1
  from smolagents.tools import Tool
2
  import pronouncing
 
3
  import difflib
4
+ import json
5
  import string
6
 
7
  class ParodyWordSuggestionTool(Tool):
 
11
  inputs = {'target': {'type': 'string', 'description': 'The word you want to find rhyming alternatives for'}, 'word_list_str': {'type': 'string', 'description': 'JSON string of word list (e.g. \'["word1", "word2"]\')'}, 'min_similarity': {'type': 'string', 'description': 'Minimum similarity threshold (0.0-1.0)', 'nullable': True}}
12
  output_type = "string"
13
 
14
+ def _are_vowels_similar(self, v1: str, v2: str) -> bool:
15
+ """Check if two vowel sounds are similar enough to rhyme."""
16
+ # Strip stress markers
17
+ v1 = v1.rstrip('012')
18
+ v2 = v2.rstrip('012')
19
+
20
+ # Define groups of similar vowel sounds
21
+ similar_vowels = [
22
+ {'AH', 'UH'}, # Short u sounds
23
+ {'AE', 'EH'}, # Short e/a sounds
24
+ {'IY', 'IH'}, # Long/short i sounds
25
+ {'AO', 'AA'}, # Open o/a sounds
26
+ {'UW', 'UH'}, # Long/short oo sounds
27
+ ]
28
+
29
+ # Direct match
30
+ if v1 == v2:
31
+ return True
32
+
33
+ # Check if they're in the same similarity group
34
+ for group in similar_vowels:
35
+ if v1 in group and v2 in group:
36
+ return True
37
+
38
+ return False
39
+
40
+
41
+ def _contains_vowel(self, phone: str, vowels: list) -> bool:
42
+ """Helper function to check if a phone contains any vowel from the list."""
43
+ for v in vowels:
44
+ if v in phone:
45
+ return True
46
+ return False
47
+
48
+
49
  def forward(self, target: str, word_list_str: str, min_similarity: str = "0.5") -> str:
50
  """Get rhyming word suggestions."""
51
  import pronouncing
 
53
  import json
54
  from difflib import SequenceMatcher
55
 
56
+ VOWEL_LETTERS = ['A', 'E', 'I', 'O', 'U']
57
+
58
  target = target.lower().strip(string.punctuation)
59
  min_similarity = float(min_similarity)
60
  suggestions = []
 
79
  target_phones = target_phones[0]
80
  target_phone_list = target_phones.split()
81
 
82
+ # Find the last vowel in target
83
+ target_last_vowel = None
84
+ target_last_vowel_idx = -1
85
+ for i, phone in enumerate(target_phone_list):
86
+ if self._contains_vowel(phone, VOWEL_LETTERS):
87
+ target_last_vowel = phone
88
+ target_last_vowel_idx = i
89
+
90
  # Check each word
91
  for word in words:
92
  word = word.lower().strip(string.punctuation)
 
95
  word_phones = phones[0]
96
  word_phone_list = word_phones.split()
97
 
98
+ # Find last vowel in word
99
+ word_last_vowel = None
100
+ word_last_vowel_idx = -1
101
+ for i, phone in enumerate(word_phone_list):
102
+ if self._contains_vowel(phone, VOWEL_LETTERS):
103
+ word_last_vowel = phone
104
+ word_last_vowel_idx = i
105
+
106
  # 1. Rhyme score (most important - 60%)
107
  rhyme_score = 0
108
+ if word_last_vowel and target_last_vowel:
109
+ # Check if the vowels are similar
110
+ if self._are_vowels_similar(word_last_vowel, target_last_vowel):
111
+ # Check if the endings after the vowel match
112
+ if (word_phone_list[word_last_vowel_idx:] ==
113
+ target_phone_list[target_last_vowel_idx:]):
114
+ rhyme_score = 1.0
115
+ # Partial match for similar endings
116
+ elif (len(word_phone_list) > word_last_vowel_idx + 1 and
117
+ len(target_phone_list) > target_last_vowel_idx + 1 and
118
+ word_phone_list[-1] == target_phone_list[-1]):
119
+ rhyme_score = 0.8
 
 
120
 
121
  # 2. Syllable match (25%)
122
  target_syl = pronouncing.syllable_count(target_phones)
123
  word_syl = pronouncing.syllable_count(word_phones)
124
  syllable_score = 1.0 if target_syl == word_syl else 0.0
125
 
126
+ # 3. Overall similarity (15%)
127
  string_similarity = SequenceMatcher(None, target, word).ratio()
128
 
129
+ # Combined score
130
  similarity = (rhyme_score * 0.6) + (syllable_score * 0.25) + (string_similarity * 0.15)
131
 
132
  if similarity >= min_similarity:
133
  suggestions.append({
134
  "word": word,
135
  "similarity": round(similarity, 3),
136
+ "rhyme_match": rhyme_score > 0,
137
+ "rhyme_score": round(rhyme_score, 3),
138
  "syllable_match": syllable_score == 1.0,
139
  "string_similarity": round(string_similarity, 3),
140
  "syllables": word_syl,