Skip to content

Commit fbd93ef

Browse files
committed
Merge branch 'main' of https://github.com/ikostan/python
2 parents 82570d5 + 1cfd2b3 commit fbd93ef

File tree

3 files changed

+247
-5
lines changed

3 files changed

+247
-5
lines changed

README.md

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,3 @@ Exercism provides you with thousands of exercises spread across numerous languag
1919
You complete a challenge by downloading the exercise to your computer and solving it in your normal working environment. Once you've finished you submit it online and one of our mentors will give you feedback on how you could improve it using features of the language that you may not be familiar with. After a couple of rounds of refactoring, your exercise will be complete and you will unlock both the next core exercise and also a series of related side-exercises for you to practice with.
2020

2121
Exercism is entirely open source and relies on the contributions of thousands of wonderful people.
22-
23-
Exercism is designed to be fun and friendly, and we place a strong emphasis on empathetic communication.
24-
25-
Sign up and have fun. Exercism is 100% free :)
26-
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
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+
if text[:2] == "qu":
79+
return True
80+
81+
for char in text[: text.index("qu")]:
82+
if is_vowel(char):
83+
return False
84+
return True
85+
return False
86+
87+
88+
def is_rule_4(text: str) -> bool:
89+
"""
90+
Check if a word starts with one or more consonants followed by "y".
91+
92+
:param text: The word to check
93+
:return: True if the word matches the pattern, False otherwise
94+
"""
95+
if "y" in text and text[0] != "y":
96+
for char in text[: text.index("y")]:
97+
if is_vowel(char):
98+
return False
99+
return True
100+
return False
101+
102+
103+
def is_vowel(char: str) -> bool:
104+
"""
105+
Check if a character is a vowel (a, e, i, o, or u).
106+
107+
:param char: The character to check
108+
:return: True if the character is a vowel, False otherwise
109+
"""
110+
return char in "aeiou"
111+
112+
113+
def get_consonant_cluster_index(text: str) -> int:
114+
"""
115+
Find the index of the last consonant in the initial consonant cluster.
116+
117+
:param text: The word to analyze
118+
:return: The index of the last consonant in the initial consonant cluster
119+
"""
120+
index: int = 0
121+
for i, char in enumerate(text):
122+
if not is_vowel(char):
123+
index = i
124+
else:
125+
break
126+
127+
return index
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)