patruff commited on
Commit
e13fea5
·
verified ·
1 Parent(s): 8873e29

Upload tool

Browse files
Files changed (2) hide show
  1. requirements.txt +1 -1
  2. tool.py +21 -64
requirements.txt CHANGED
@@ -1,2 +1,2 @@
1
- pronouncing
2
  smolagents
 
 
 
1
  smolagents
2
+ pronouncing
tool.py CHANGED
@@ -1,8 +1,8 @@
1
  from smolagents.tools import Tool
2
- import pronouncing
3
- import difflib
4
  import json
5
  import string
 
 
6
 
7
  class ParodyWordSuggestionTool(Tool):
8
  name = "parody_word_suggester"
@@ -11,39 +11,21 @@ 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:
@@ -53,8 +35,6 @@ class ParodyWordSuggestionTool(Tool):
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 = []
@@ -75,17 +55,10 @@ class ParodyWordSuggestionTool(Tool):
75
  "error": f"'{target}' not found in CMU dictionary",
76
  "suggestions": []
77
  }, indent=2)
78
-
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:
@@ -94,29 +67,11 @@ class ParodyWordSuggestionTool(Tool):
94
  if phones:
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)
@@ -138,7 +93,8 @@ class ParodyWordSuggestionTool(Tool):
138
  "syllable_match": syllable_score == 1.0,
139
  "string_similarity": round(string_similarity, 3),
140
  "syllables": word_syl,
141
- "phones": word_phones
 
142
  })
143
 
144
  # Sort by similarity score descending
@@ -148,6 +104,7 @@ class ParodyWordSuggestionTool(Tool):
148
  "target": target,
149
  "target_syllables": pronouncing.syllable_count(target_phones),
150
  "target_phones": target_phones,
 
151
  "suggestions": suggestions
152
  }
153
 
 
1
  from smolagents.tools import Tool
 
 
2
  import json
3
  import string
4
+ import pronouncing
5
+ import difflib
6
 
7
  class ParodyWordSuggestionTool(Tool):
8
  name = "parody_word_suggester"
 
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 _has_vowel(self, phone: str) -> bool:
15
+ """Check if a phone contains a vowel."""
16
+ VOWELS = ['A', 'E', 'I', 'O', 'U']
17
+ for vowel in VOWELS:
18
+ if vowel in phone:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  return True
 
20
  return False
21
 
22
 
23
+ def _get_rhyme_part(self, phones: list) -> list:
24
+ """Get the rhyming part of a word (last vowel onwards)."""
25
+ for i, phone in enumerate(reversed(phones)):
26
+ if self._has_vowel(phone):
27
+ return phones[-(i+1):]
28
+ return phones
29
 
30
 
31
  def forward(self, target: str, word_list_str: str, min_similarity: str = "0.5") -> str:
 
35
  import json
36
  from difflib import SequenceMatcher
37
 
 
 
38
  target = target.lower().strip(string.punctuation)
39
  min_similarity = float(min_similarity)
40
  suggestions = []
 
55
  "error": f"'{target}' not found in CMU dictionary",
56
  "suggestions": []
57
  }, indent=2)
58
+
59
  target_phones = target_phones[0]
60
  target_phone_list = target_phones.split()
61
+ target_rhyme_part = self._get_rhyme_part(target_phone_list)
 
 
 
 
 
 
 
62
 
63
  # Check each word
64
  for word in words:
 
67
  if phones:
68
  word_phones = phones[0]
69
  word_phone_list = word_phones.split()
70
+ word_rhyme_part = self._get_rhyme_part(word_phone_list)
 
 
 
 
 
 
 
71
 
72
  # 1. Rhyme score (most important - 60%)
73
+ # Perfect rhyme if the rhyming parts match exactly
74
+ rhyme_score = 1.0 if word_rhyme_part == target_rhyme_part else 0.0
 
 
 
 
 
 
 
 
 
 
 
75
 
76
  # 2. Syllable match (25%)
77
  target_syl = pronouncing.syllable_count(target_phones)
 
93
  "syllable_match": syllable_score == 1.0,
94
  "string_similarity": round(string_similarity, 3),
95
  "syllables": word_syl,
96
+ "phones": word_phones,
97
+ "rhyme_part": " ".join(word_rhyme_part)
98
  })
99
 
100
  # Sort by similarity score descending
 
104
  "target": target,
105
  "target_syllables": pronouncing.syllable_count(target_phones),
106
  "target_phones": target_phones,
107
+ "target_rhyme_part": " ".join(target_rhyme_part),
108
  "suggestions": suggestions
109
  }
110