ejLev
ejLev

Reputation: 3211

List slicing issues in python

This code seems like it should work. It sums up the number of words that are "striped" (letter-consonant-letter-etc.) and then returns the sum. However when I test it with print (striped("My name is ...") ) it only counts my and is and gives me a sum of 2 instead of 3... why is name missing?

VOWELS = "AEIOUY"
CONSONANTS = "BCDFGHJKLMNPQRSTVWXZ"


def striped(text):

    my_sum = 0
    text = text.replace(".", " ").replace(",", " ").split()
    vowels = VOWELS.lower()
    consonants = CONSONANTS.lower()

    for word in text:
        word = word.lower()
        if ((word[::2] in vowels and word[1::2] in consonants)\
        or (word[::2] in consonants and word[1::2] in vowels))\
        and len(word) > 1:
            print (word)
            my_sum += 1

    return my_sum        

Upvotes: 1

Views: 501

Answers (2)

Tim Zimmermann
Tim Zimmermann

Reputation: 6420

Here is a solution with lists. The problem with your code is that words longer than two characters return a substring when you use [::2] rather than single characters that are tested whether they are contained in vowels / constants. By converting it to a list first, you can check every item of the list whether it is contained in the according set of characters.

VOWELS = "AEIOUY"
CONSONANTS = "BCDFGHJKLMNPQRSTVWXZ"


def striped(text):

    my_sum = 0
    text = text.replace(".", " ").replace(",", " ").split()
    vowels = VOWELS.lower()
    consonants = CONSONANTS.lower()

    for word in text:
        word = word.lower()

        if ((all(c in vowels for c in list(word[::2]))\
            and all(c in consonants for c in list(word[1::2])))\
        or (all(c in consonants for c in list(word[::2]))\
            and all(c in vowels for c in list(word[1::2]))))\
        and len(word) > 1:
            print (word)
            my_sum += 1

    return my_sum

print striped("My name is")

Upvotes: 1

jh314
jh314

Reputation: 27812

You should use set.issubset() instead.

VOWELS = "AEIOUY"
CONSONANTS = "BCDFGHJKLMNPQRSTVWXZ"

def striped(text):

    my_sum = 0
    text = text.replace(".", " ").replace(",", " ").split()
    vowels = set(c for c in VOWELS.lower())
    consonants = set(c for c in CONSONANTS.lower())

    for word in text:
        word = word.lower()
        if ((set(word[::2]).issubset(vowels) and set(word[1::2]).issubset(consonants))\
        or (set(word[::2]).issubset(consonants) and set(word[1::2]).issubset(vowels)))\
        and len(word) > 1:
            print (word)
            my_sum += 1
    return my_sum        

striped('My name is...')

The reason it works for my and is is that they are two char words, so you are checking if if m is in the string of constants, and if y is in the string of vowels, which works. For longer words like name, then clearly nm is not in the string of sonsonants, so it fails.


Instead, you should use sets. Essentially, you want to find if set(['n','m']) is a subset of the set of consonants.

Upvotes: 1

Related Questions