3
\$\begingroup\$

I wrote an NLP script for processing Turkish language. Yesterday I added syllabication but I wonder if it could be done better. It is kinda hard-coded, so I would like to know if I can improve it.

Here is the syllabication part.

def syllabicate(self, word):
    """
    :param word: The word to be syllabicated
    :return: The syllabicated list that contains syllabs
    """
    word = word.lower()
    syllabs = []
    syllab = ""
    keep_index = 0
    last_was_vowel = False
    next_is_vowel = False

    for let_ind in range(len(word)):
        if let_ind != len(word) - 1:
            if word[let_ind + 1] in self.vowels:
                next_is_vowel = True
            else:
                next_is_vowel = False
        else:
            syllab = word[keep_index:]
            syllabs.append(syllab)
            break

        if next_is_vowel and not last_was_vowel and syllab:
            syllabs.append(syllab)
            syllab = ""
            keep_index = let_ind

        elif next_is_vowel and word[let_ind] not in self.vowels and syllab:
            syllabs.append(syllab)
            syllab = ""
            keep_index = let_ind

        syllab += word[let_ind]

        if word[let_ind] in self.vowels:
            last_was_vowel = True
        else:
            last_was_vowel = False

    return syllabs
\$\endgroup\$
4
\$\begingroup\$

First of all you should know that the script doesn't syllabize properly for every word. For example if you give the word authenticated the function returns ['aut', 'hen', 'ti', 'ca', 'ted'] which is incorrect. The correct case would be ['au','then','ti','cat','ed']. However I do not know how to fix that.

Edit: The point made above doesn't stand since this script isn't for the english language.

Second you have a lot of ifs where you check if a character is a vowel like this:

if word[let_ind] in self.vowels:
        last_was_vowel = True
    else:
        last_was_vowel = False

They could be written better like this:

last_was_vowel = word[let_ind] in self.vowels

Or even better I would have written a function that checks if a letter is a vowel.

def is_vowel(self, char):
    return char in self.vowels

The first if in your for loop

if let_ind != len(word) - 1:
    if word[let_ind + 1] in self.vowels:
        next_is_vowel = True
    else:
        next_is_vowel = False
else:
    syllab = word[keep_index:]
    syllabs.append(syllab)
    break

checks if the next one is a vowel except the last char. It would be more good looking like this:

for pos, char in enumerate(word[:-1]):
    next_is_vowel = self.is_vowel(word[pos + 1])
    ...

syllab = word[keep_index:]
syllabs.append(syllab)

We enumerate through the word to get the position of the letter and the letter itself. The word[:-1] means we are going to iterate the whole word except its last letter.

Lastly you got 2 ifs here that do the same thing. You also don't need the keep_index.

if next_is_vowel and not last_was_vowel and syllab:
    syllabs.append(syllab)
    syllab = ""

elif next_is_vowel and word[let_ind] not in self.vowels and syllab:
    syllabs.append(syllab)
    syllab = ""

The could be easily written as one if like this:

if next_is_vowel and syllab and not (last_was_vowel and self.is_vowel(char)):
    syllabs.append(syllab)
    syllab = ""

The place where the keep index was used can be replaced like this from syllab = word[keep_index:] to syllab += word[-1]

With these changes in mind the code looks now like this.

def is_vowel(self, char):
    """

    :param char: the character to check
    :return: bool depending if the char is a vowel
    """
    return char in self.vowels

def syllabicate(self, word):
    """
    :param word: The word to be syllabicated
    :return: The syllabicated list that contains syllabs
    """
    word = word.lower()
    syllabs = []
    syllab = ""
    last_was_vowel = False
    # we don't want the last character

    for pos, char in enumerate(word[:-1]):
        next_is_vowel = self.is_vowel(word[pos + 1])

        if next_is_vowel and syllab and not (last_was_vowel and self.is_vowel(char)):

            syllabs.append(syllab)
            syllab = ""

        syllab += char
        last_was_vowel = self.is_vowel(char)

    syllab += word[-1]
    syllabs.append(syllab)

    return syllabs
\$\endgroup\$
  • 1
    \$\begingroup\$ As I mentioned it is for Turkish language only since every language has its own rules it is not going to work for English. And thanks a lot for the advices, they are totally on point. \$\endgroup\$ – MeteHan Sep 10 '18 at 8:22
  • \$\begingroup\$ Oh I am sorry about that. I will remove that part then from the post since it doesn't offer anything constructive. \$\endgroup\$ – Giannis Papaioannou Sep 10 '18 at 8:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.