Skip to content

Commit 23f5579

Browse files
authored
Merge pull request #91 from ikostan/exercism-sync/c4cf456caa7bfd12
[Sync Iteration] python/pig-latin/16
2 parents ec55f58 + 62200c8 commit 23f5579

File tree

1 file changed

+120
-0
lines changed

1 file changed

+120
-0
lines changed
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
"""
2+
The task is to translate text from English to Pig Latin.
3+
The translation is defined using four rules, which look at the pattern
4+
of vowels and consonants at the beginning of a word. These rules look
5+
at each word's use of vowels and consonants:
6+
7+
vowels: the letters a, e, i, o, and u
8+
consonants: the other 21 letters of the English alphabet
9+
"""
10+
11+
12+
def translate(text: str) -> str:
13+
"""
14+
Translate English text to Pig Latin.
15+
16+
:param text: The English text to translate
17+
:return: The text translated to Pig Latin
18+
"""
19+
words: list[str] = text.split(" ")
20+
return " ".join(process_word(word) for word in words)
21+
22+
23+
def process_word(text: str) -> str:
24+
"""
25+
Process a single word and convert it to Pig Latin using
26+
the four translation rules.
27+
28+
:param text: The English word to convert
29+
:return: The word converted to Pig Latin
30+
"""
31+
if not text:
32+
return ""
33+
34+
text_lower: str = text.lower()
35+
36+
# Rule 1
37+
if is_vowel(text_lower[0]) or text_lower[:2] in ("xr", "yt"):
38+
# If a word begins with a vowel,
39+
# or starts with "xr" or "yt",
40+
# add an "ay" sound to the end of the word.
41+
return f"{text}ay"
42+
43+
# Rule 3
44+
if is_rule_3(text_lower):
45+
# If a word starts with zero or more consonants followed by "qu",
46+
# first move those consonants (if any) and the "qu" part to the
47+
# end of the word, and then add an "ay" sound to the end of the word.
48+
i = text_lower.index("qu")
49+
return f"{text[i + 2 :]}{text[: i + 2]}ay"
50+
51+
# Rule 4
52+
if is_rule_4(text_lower):
53+
# If a word starts with one or more consonants followed by "y",
54+
# first move the consonants preceding the "y" to the end of the
55+
# word, and then add an "ay" sound to the end of the word.
56+
i = text_lower.index("y")
57+
return f"{text[i:]}{text[:i]}ay"
58+
59+
# Rule 2
60+
if not is_vowel(text_lower[0]):
61+
# If a word begins with one or more consonants, first move those
62+
# consonants to the end of the word and then add an "ay" sound
63+
# to the end of the word.
64+
i = get_consonant_cluster_index(text_lower)
65+
return f"{text[i + 1 :]}{text[: i + 1]}ay"
66+
67+
raise ValueError(f"Unhandled word in Pig Latin translation: '{text}'")
68+
69+
70+
def is_rule_3(text: str) -> bool:
71+
"""
72+
Check if a word starts with zero or more consonants followed by "qu".
73+
74+
:param text: The word to check
75+
:return: True if the word matches the pattern, False otherwise
76+
"""
77+
if "qu" in text:
78+
qu_indx: int = text.index("qu")
79+
return all(not is_vowel(char) for char in text[: qu_indx])
80+
return False
81+
82+
83+
def is_rule_4(text: str) -> bool:
84+
"""
85+
Check if a word starts with one or more consonants followed by "y".
86+
87+
:param text: The word to check
88+
:return: True if the word matches the pattern, False otherwise
89+
"""
90+
if "y" in text and text[0] != "y":
91+
y_indx: int = text.index("y")
92+
return all(not is_vowel(char) for char in text[: y_indx])
93+
return False
94+
95+
96+
def is_vowel(char: str) -> bool:
97+
"""
98+
Check if a character is a vowel (a, e, i, o, or u).
99+
100+
:param char: The character to check
101+
:return: True if the character is a vowel, False otherwise
102+
"""
103+
return char in "aeiou"
104+
105+
106+
def get_consonant_cluster_index(text: str) -> int:
107+
"""
108+
Find the index of the last consonant in the initial consonant cluster.
109+
110+
:param text: The word to analyze
111+
:return: The index of the last consonant in the initial consonant cluster
112+
"""
113+
index: int = 0
114+
for i, char in enumerate(text):
115+
if not is_vowel(char):
116+
index = i
117+
else:
118+
break
119+
120+
return index

0 commit comments

Comments
 (0)