Anti_vowel


#1


https://www.codecademy.com/courses/python-intermediate-en-rCQKw/1/2?curriculum_id=4f89dab3d788890003000096


I get the following error when I execute my code. "Oops, try again. Your function fails on anti_vowel("Hey look Words!"). It returns "['e', 'y', ' ', 'l', 'o', 'o', 'k', ' ', 'W', 'o', 'r', 'd', 's', '!']" when it should return "Hy lk Wrds!"."


I do not understand why I keep getting this error. Can someone please help me out.

def anti_vowel(text):
    
    newtext = list(text)
    for letter in newtext:
        if letter == "a" or "A":
            newtext == newtext.remove(letter)
        elif letter == "e" or "E":
            newtext == newtext.remove(letter)
        elif letter == "i" or "I":
            newtext == newtext.remove(letter)
        elif letter == "o" or "O":
            newtext == newtext.remove(letter)
        elif letter == "u" or "U":
            newtext == newtext.remove(letter)
        else:
            return newtext
        return str(newtext)

#2

a function ends the moment a return keyword is reached

so what you want to do, is build a loop, get all the constants, after the loop, return the string without vowels

remove() is a difficult approach, i recommend the opposite approach: append constants to a new list/string


#3

Hi Michael

The first problem

lies in the tests: if letter == "a" or "A" means literally:

  1. calculate "a" or "A"

    which is True because "a" is not an empty string

  2. exactly compare that to letter

    which is False because they are not the same data types (String != Boolean)

All the tests fail for the same reason and you don't get any letters removed. Probably the better solution would be

    if letter == "A" or letter == "a":

or even if letter.upper() == "A": which is slightly less prone to a typing error.

The second problem

is that you formatting a list r with str(r) gives you a string representation of a list. What you want is to join all the elements of the list back into a single string. This is done by the join method like this:

    newstring = ''.join(newtext)
    return(newstring)

Hope that makes things a bit clearer :slight_smile:

Tim F


#4

Ok, that got me really close but for some reason my code is not dropping the third "o" in the string.

"Oops, try again. Your function fails on anti_vowel("Hey look Words!"). It returns "Hy lk Words!" when it should return "Hy lk Wrds!""

'''
def anti_vowel(text):

newtext = list(text)
for letter in newtext:
    if letter == "a" or letter == "A":
        newtext == newtext.remove(letter)
    elif letter == "e" or letter ==  "E":
        newtext == newtext.remove(letter)
    elif letter == "i" or letter ==  "I":
        newtext == newtext.remove(letter)
    elif letter == "o" or letter ==  "O":
        newtext == newtext.remove(letter)
    elif letter == "u" or letter ==  "U":
        newtext == newtext.remove(letter)
newertext = "".join(newtext)
return newertext

,,,


#5

this is because index shifts occurs. You are removing from the same string you are looping over.

you could overcome this problem by looping over text and removing from newtext


#6

You could just use a for loop that for every character in 'aeiouAEIOU' and then replaces it.


#7

A post was split to a new topic: Anti vowel


#8

Okay: as @stetim94 says, it's because you are removing elements from the list that you are iterating. Silly of me not to catch that. Imagine you are in a queue: the bouncer goes through all the people one by one. He pulls out the person in front of you (say in position 5): everybody moves up so you are the new position 5. Then the bouncer continues at position six, having not inspected you at all. It is the same with the iterator too: it will remove the first 'o' and not even see the second one.

The immediate cure is to use a copy of the list to iterate over:
for letter in newtext[:]:
or you can use newtext.copy() if that makes more sense to you. You should still remove from the original newtext list, of course.

I have to add, though, that this is not the best strategy. Removing things from a list is highly inefficient because it involves all this shuffling up and down. Have you thought about starting from an empty string and appending anything that is not a vowel? Still, you have learned a lot about how lists work!

Hope that helps

Tim F


#9

This helped out a lot. I changed my code to whats below and it passed. I am sure there was a prettier way to do it but it works so I am happy for now. Thanks for all the help!

'''
def anti_vowel(text):
newtext = list(text)
novowel = []

for letter in newtext:
    if letter != 'a' and letter != 'A' and letter != 'e' and letter != 'E' and letter != 'i' and letter != 'I' and letter != 'o'  and letter != 'O' and letter != 'u' and letter != 'U':
        novowel.append(letter)

newertext = "".join(novowel)
return newertext

'''


#10

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.