5
\$\begingroup\$

Used Python 3 for a solution to a Reddit /r/DailyProgrammer challenge.

When we Swedes are young, we are taught a SUPER-SECRET language that only kids know, so we can hide secrets from our confused parents. This language is known as "Rövarspråket" (which means "Robber's language", more or less), and is surprisingly easy to become fluent in, at least when you're a kid...

Rövarspråket is not very complicated: you take an ordinary word and replace the consonants with the consonant doubled and with an "o" in between. So the consonant "b" is replaced by "bob", "r" is replaced with "ror", "s" is replaced with "sos", and so on. Vowels are left intact. It's made for Swedish, but it works just as well in English. Your task today is to write a program that can encode/decode a string of text into Rövarspråket.

Encoder:

import string

def main():
    word = input('Enter Phrase : ')
    final_word = rövarspråket(word)
    print(final_word)

def is_vowel(letter):
    VOWELS = ['A', 'E', 'I', 'O', 'U', 'Y', 'Å', 'Ä', 'Ö']
    if str.upper(letter) in VOWELS:
        return True
    else:
        return False

def rövarspråket(word):
    new_word = []
    for character in word:
        if character.isalpha() and not is_vowel(character):
            new_word.append(character + 'o' + str.lower(character))
        else:
            new_word.append(character)
    return ''.join(new_word)

if __name__ == '__main__':
    main()

Decoder program is identical to the Encoder except for a different central function of course:

def decode_rövarspråket(word):
    original_word = []
    i = 0
    while i <= (len(word) - 1):
        original_word.append(word[i])
        if word[i].isalpha() and not is_vowel(word[i]):
            i += 3
        else:
            i += 1
    return ''.join(original_word)

I'm newer to Python and one of my main concerns is writing code that is idiomatic and properly "Pythonic". Another is the loop in the decoder program. The algorithm I decided to go with revolves around iterating one character for vowels and three for consonants (to skip the o and repeated letter). Using a for-loop seemed like it would involve jumping through more hoops than just biting the bullet and using a while instead.

\$\endgroup\$
4
\$\begingroup\$
  • Your program has an unused import: import string. You can use tools like flake8, pylint to catch such errors.

  • I ran your code at pep8online and it pointed out 3 errors:

E302:3:1:expected 2 blank lines, found 1
E302:8:1:expected 2 blank lines, found 1
E302:15:1:expected 2 blank lines, found 1

Basically this means there should be two empty lines after imports, class definition, function definition. Check PEP 8 for more details.

  • VOWELS variable is well suited to be a global variable. Plus you can convert it to a string to make it easier to read: VOWELS = 'AEIOUYÅÄÖ'.

  • str.upper() is redundant as str objects already have upper methods, hence letter.upper() in VOWELS is all you need. Similarly str.lower() call can be changed to character.lower().

  • Note that the in check already returns boolean, hence unless you are trying to be extra explicit you can reduce those 3 lines to return letter.upper() in VOWELS.

  • You can assign word[i] to a variable inside the while loop to make it easier to read: character = word[i]. Plus i can renamed to better variable like index.

  • For case insensitive comparison you probably want to read up this thread: How do I do a case insensitive string comparison in Python?

  • Lastly add annotations to your function definitions so that it becomes more clear what type of arguments a function is expecting and what it returns. Function annotation can also be used to static analysis tools like mypy to catch errors beforehand.

VOWELS = 'AEIOUYÅÄÖ'


def main() -> None:
    word = input('Enter Phrase : ')
    final_word = rövarspråket(word)
    print(final_word)


def is_vowel(letter: str) -> bool:
    return letter.upper() in VOWELS


def rövarspråket(word: str) -> str:
    new_word = []

    for character in word:
        new_word.append(character)
        if character.isalpha() and not is_vowel(character):
            new_word.append('o' + character.lower())

    return ''.join(new_word)


def decode_rövarspråket(word: str) -> str:
    original_word = []
    i = 0
    while i <= (len(word) - 1):
        character = word[i]
        original_word.append(character)
        if character.isalpha() and not is_vowel(character):
            i += 3
        else:
            i += 1
    return ''.join(original_word)
\$\endgroup\$
  • \$\begingroup\$ Ah, the is_vowel conditional feels so obvious! Can't believe I didn't catch that. Didn't know function annotations were a thing, though they look incredibly useful. Will certainly be using them from now on. \$\endgroup\$ – Aaron S. Jun 5 '17 at 15:37

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.