Skip to content

Commit 961fdac

Browse files
authored
Merge pull request #65 from ikostan/exercism-sync/ff0dd5a6a0fa92c6
[Sync Iteration] python/pig-latin/5
2 parents 6000bf6 + b5488be commit 961fdac

File tree

1 file changed

+155
-0
lines changed

1 file changed

+155
-0
lines changed
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
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 of vowels
4+
and consonants at the beginning of a word. These rules look at each word's use
5+
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 text from English to Pig Latin.
15+
16+
:param text:
17+
:return:
18+
"""
19+
words: list = text.split(" ")
20+
return " ".join(process_text(word) for word in words)
21+
22+
23+
def process_text(text: str) -> str:
24+
"""
25+
Convert a string based on 4 rules of Pig Latin.
26+
27+
:param text:
28+
:return:
29+
"""
30+
# Rule 1
31+
if is_rule_1(text):
32+
# If a word begins with a vowel,
33+
# or starts with "xr" or "yt",
34+
# add an "ay" sound to the end of the word.
35+
return text + "ay"
36+
37+
# Rule 2
38+
if is_rule_2(text):
39+
# If a word begins with one or more consonants, first move those consonants
40+
# to the end of the word and then add an "ay" sound to the end of the word.
41+
i = get_last_consonant_indx(text)
42+
return text[i + 1 :] + text[: i + 1] + "ay"
43+
44+
# Rule 3
45+
if is_rule_3(text):
46+
# If a word starts with zero or more consonants followed by "qu", first move
47+
# those consonants (if any) and the "qu" part to the end of the word, and then
48+
# add an "ay" sound to the end of the word.
49+
i = text.index("qu")
50+
return text[i + 2 :] + text[: i + 2] + "ay"
51+
52+
# Rule 4
53+
if is_rule_4(text):
54+
# If a word starts with one or more consonants followed by "y", first move the
55+
# consonants preceding the "y" to the end of the word, and then add an "ay" sound
56+
# to the end of the word.
57+
i = text.index("y")
58+
return text[i:] + text[:i] + "ay"
59+
60+
raise ValueError(f"Unhandled word in Pig Latin translation: '{text}'")
61+
62+
63+
def is_rule_1(text: str) -> bool:
64+
"""
65+
Check if a word begins with a vowel, or starts with "xr" or "yt".
66+
67+
:param text:
68+
:return:
69+
"""
70+
if is_vowel(text[0]):
71+
return True
72+
if text[:2] in ("xr", "yt"):
73+
return True
74+
return False
75+
76+
77+
def is_rule_2(text: str) -> bool:
78+
"""
79+
Check ff a word begins with one or more consonants.
80+
No 'qu' or 'y' in it.
81+
82+
:param text:
83+
:return:
84+
"""
85+
return is_consonant(text[0]) and not is_rule_3(text) and not is_rule_4(text)
86+
87+
88+
def is_rule_3(text: str) -> bool:
89+
"""
90+
Check if a word starts with zero or more consonants followed by "qu".
91+
92+
:param text:
93+
:return:
94+
"""
95+
if "qu" in text:
96+
if text[:2] == "qu":
97+
return True
98+
99+
for char in text[: text.index("qu")]:
100+
if is_vowel(char):
101+
return False
102+
return True
103+
return False
104+
105+
106+
def is_rule_4(text: str) -> bool:
107+
"""
108+
Check if a word starts with one or more consonants followed by "y".
109+
110+
:param text:
111+
:return:
112+
"""
113+
if "y" in text and text[0] != "y":
114+
for char in text[: text.index("y")]:
115+
if is_vowel(char):
116+
return False
117+
return True
118+
return False
119+
120+
121+
def is_vowel(char: str) -> bool:
122+
"""
123+
Test that char in vowels: the letters a, e, i, o, and u.
124+
125+
:param char:
126+
:return:
127+
"""
128+
return char in "aeiou"
129+
130+
131+
def is_consonant(char: str) -> bool:
132+
"""
133+
Check that char is consonant (the other 21 letters of the English alphabet).
134+
135+
:param char:
136+
:return:
137+
"""
138+
return char.isalpha() and not is_vowel(char)
139+
140+
141+
def get_last_consonant_indx(text: str) -> int:
142+
"""
143+
Get last index of consonant inside the string.
144+
145+
:param text:
146+
:return:
147+
"""
148+
i = 0
149+
for n, char in enumerate(text):
150+
if is_consonant(char):
151+
i = n
152+
else:
153+
break
154+
155+
return i

0 commit comments

Comments
 (0)