Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat:euphony #277

Merged
merged 4 commits into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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")

JarbasAl marked this conversation as resolved.
Show resolved Hide resolved
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")

JarbasAl marked this conversation as resolved.
Show resolved Hide resolved
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()
Loading