Skip to content

Commit

Permalink
feat:euphony (#277)
Browse files Browse the repository at this point in the history
* feat:euphony

closes #273

* feat:euphony

* es support

* es support
  • Loading branch information
JarbasAl authored Nov 12, 2024
1 parent eeb2890 commit ae95904
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 0 deletions.
4 changes: 4 additions & 0 deletions ovos_workshop/res/text/es/word_connectors.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"and": "y",
"or": "o"
}
66 changes: 66 additions & 0 deletions ovos_workshop/skills/ovos.py
Original file line number Diff line number Diff line change
Expand Up @@ -2533,6 +2533,11 @@ def join_word_list(items: List[str], connector: str, sep: str, lang: str) -> str
Returns:
str: the connected list phrase
"""
if lang.startswith("it"):
return _join_word_list_it(items, connector, sep)
elif lang.startswith("es"):
return _join_word_list_es(items, connector, sep)

cons = {
"and": _get_word(lang, "and"),
"or": _get_word(lang, "or")
Expand All @@ -2549,3 +2554,64 @@ def join_word_list(items: List[str], connector: str, sep: str, lang: str) -> str
return (sep.join(str(item) for item in items[:-1]) +
" " + cons[connector] +
" " + items[-1])


def _join_word_list_it(items: List[str], connector: str, sep: str = ",") -> str:
cons = {
"and": _get_word("it", "and"),
"or": _get_word("it", "or")
}
if not items:
return ""
if len(items) == 1:
return str(items[0])

if not sep:
sep = ", "
else:
sep += " "

final_connector = cons[connector]
if len(items) > 2:
joined_string = sep.join(item for item in items[:-1])
else:
joined_string = items[0]

# Check for euphonic transformation cases for "e" and "o"
if cons[connector] == "e" and items[-1][0].lower() == "e":
final_connector = "ed"
elif cons[connector] == "o" and items[-1][0].lower() == "o":
final_connector = "od"
return f"{joined_string} {final_connector} {items[-1]}"


def _join_word_list_es(items: List[str], connector: str, sep: str = ",") -> str:
cons = {
"and": _get_word("es", "and"),
"or": _get_word("es", "or")
}
if not items:
return ""
if len(items) == 1:
return str(items[0])

if not sep:
sep = ", "
else:
sep += " "

final_connector = cons[connector]
if len(items) > 2:
joined_string = sep.join(item for item in items[:-1])
else:
joined_string = items[0]

# Check for euphonic transformation cases for "y"
w = items[-1].lower().lstrip("h")[0]
if cons[connector] == "y" and w in ["i", "í"]:
final_connector = "e"
# Check for euphonic transformation cases for "o"
if cons[connector] == "o" and w in ["o", "ó"]:
final_connector = "u"

return f"{joined_string} {final_connector} {items[-1]}"
76 changes: 76 additions & 0 deletions test/unittests/test_euphony.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import unittest

from ovos_workshop.skills.ovos import _join_word_list_it, _join_word_list_es


class TestJoinWordListIt(unittest.TestCase):

def test_basic_conjunction_and(self):
# Test without euphonic transformation for "and"
result = _join_word_list_it(["mare", "montagna"], "and")
self.assertEqual(result, "mare e montagna")

def test_basic_conjunction_or(self):
# Test without euphonic transformation for "or"
result = _join_word_list_it(["mare", "montagna"], "or")
self.assertEqual(result, "mare o montagna")

def test_euphonic_conjunction_or(self):
# Test euphonic transformation for "or" to "od"
result = _join_word_list_it(["mare", "oceano"], "or")
self.assertEqual(result, "mare od oceano")

def test_euphonic_conjunction_and(self):
# Test euphonic transformation for "and" to "ed"
result = _join_word_list_it(["inverno", "estate"], "and")
self.assertEqual(result, "inverno ed estate")

def test_euphonic_conjunction_or_with_other_words(self):
# Test euphonic transformation for "or" to "od" with different words
result = _join_word_list_it(["libro", "orologio"], "or")
self.assertEqual(result, "libro od orologio")

def test_join_three_words(self):
result = _join_word_list_it(["mare", "estate", "inverno"], "and")
self.assertEqual(result, "mare, estate e inverno")

def test_empty_list(self):
result = _join_word_list_it([], "and")
self.assertEqual(result, "")

def test_single_word(self):
result = _join_word_list_it(["mare"], "and")
self.assertEqual(result, "mare")

def test_multiple_euphonic_transformations(self):
# Test multiple 'ed' transformations in the same list
result = _join_word_list_it(["casa", "estate", "inverno", "autunno"], "and")
self.assertEqual(result, "casa, estate, inverno e autunno")

def test_mixed_conjunctions(self):
# Test combining 'and' and 'or' conjunctions
result = _join_word_list_it(["mare", "oceano", "isola"], "or")
self.assertEqual(result, "mare, oceano o isola")


class TestJoinWordListEs(unittest.TestCase):

def test_euphonic_conjunction_and(self):
# Test euphonic transformation from "y" to "e"
result = _join_word_list_es(["Juan", "Irene"], "and")
self.assertEqual(result, "Juan e Irene")
result = _join_word_list_es(["vaqueros", "indios"], "and")
self.assertEqual(result, "vaqueros e indios")
result = _join_word_list_es(["Manuel", "Hilario"], "and")
self.assertEqual(result, "Manuel e Hilario")

def test_euphonic_conjunction_or(self):
# Test euphonic transformation from "o" to "u"
result = _join_word_list_es(["Manuel", "Óscar"], "or")
self.assertEqual(result, "Manuel u Óscar")
result = _join_word_list_es(["unos", "otros"], "or")
self.assertEqual(result, "unos u otros")


if __name__ == "__main__":
unittest.main()

0 comments on commit ae95904

Please sign in to comment.