3
\$\begingroup\$

Given a sentence in 'bird language', where there are two rules:

  1. After each consonant there is a random vowel added. For example if the consonant is "l" it will end as "la" or "le"...
  2. After each vowel there are two extra vowels which are the same as the first. For example if there is a "u" it will end as "uuu"

    • Vowels are "aeiouy"

Examples:

  • hieeelalaooohello
  • hoooowe yyyooouuu duoooiiinehow you doin
  • aaa bo cy da eee fea b c d e f
  • sooooso aaaaaaaaasos aaa

The code is:

VOWELS = "aeiouy"

def translate(phrase):

    result = ""
    num_of_letters_to_ignore = 0

    for i, letter in enumerate(phrase):
        if num_of_letters_to_ignore > 0:
            num_of_letters_to_ignore -= 1
            continue

        if letter in VOWELS:
            num_of_letters_to_ignore += 2
        elif letter.isalpha():
            num_of_letters_to_ignore += 1
        result += letter

    return result

How can it be improved?

EDIT: I have added the first sentence which was missing where it is correctly specified that y is in the vowels!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ @jonrsharpe Seems to work now with the inclusion of the global constant. \$\endgroup\$
    – Graipher
    May 25, 2019 at 21:40

2 Answers 2

1
\$\begingroup\$

Considering that you have four concrete test cases, it would be a good idea to put them in a docstring as doctests.

Your iteration is awkward. First of all, you never use i, so there is no need to call enumerate(). A better way to conditionally skip ahead is to call next() on an iterator over the phrase.

def translate(phrase):
    """
    Translate the phrase from bird language.

    >>> translate('hieeelalaooo')
    'hello'
    >>> translate('hoooowe yyyooouuu duoooiiine')
    'how you doin'
    >>> translate('aaa bo cy da eee fe')
    'a b c d e f'
    >>> translate('sooooso aaaaaaaaa')
    'sos aaa'
    """
    phrase = iter(phrase)
    result = ""
    for letter in phrase:
        result += letter
        if letter in VOWELS:   # Vowel. Skip the next two characters.
            next(phrase)
            next(phrase)
        elif letter.isalpha(): # Consonant. Skip the next character.
            next(phrase)
    return result

A much more compact solution, though, would be to perform a regular expression substitution.

import re

def translate(phrase):
    return re.sub(r'([aeiouy])\1\1|([a-z])[aeiouy]', r'\1\2', phrase, flags=re.I)
\$\endgroup\$
0
\$\begingroup\$

At first I thought it can be improved in more functional way, but after several minutes I see your solution is pretty optimal and elegant. I see two places for improvement:

  • for i, letter in enumerate(phrase): - you don't use i so you don't need enumerate. You can replace it with an ordinary loop: for letter in phrase:

  • You can add try-except block or check that phrase is actually a string, not a random type object

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Hello, @vurmmux could you explain me how could we do the try and catch which you suggest, please? \$\endgroup\$
    – Yone
    May 24, 2019 at 22:04
  • \$\begingroup\$ Type verification is not common practice in Python. \$\endgroup\$ May 25, 2019 at 1:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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