Anti vowel; I have difficulties understanding the logic


#1

Sorry, but I'm having difficulties understanding the logics. Often I can't see why the code wont work and have to resort to copy code from here (am I the only one?. But I would like to figure out at least for once why I can't make it work!
So, thanks a lot for your kindness and patience.

On the code above I try with both text and vowels in between qotation marks and without quotation marks but can never make it to work. Can any one offer an explanation?
Much appreciated!!!

DD


#2

Hi DD,

I find with challenging problems it sometimes helps to plug the code into a simulator to see what's happening step-by-step.
I like this one:
Python Tutor

So there are two issues I see:

The first is that the argument (text) that is to be entered will be a string, and strings are immutable in Python; in other words, you can't change or remove characters from text. So you can't use

text.remove(char)

because remove isn't a method for strings.

The second issue is that, as you suspected, there's a problem here:

for char in "text":
    if char in "vowels":

because text and vowels are variable names --- they must be text and vowels without quotation marks.

So what can we do? One possibility is this:

def anti_vowel(text):
    vowels = "aeiouAEIOU"
    newtext = ""
    for char in text:
        if char in vowels:
            continue
        else:    
            newtext = newtext + char
    return newtext

What we are doing is defining the function anti_vowel to take one argument (text). The function creates an empty string variable (newtext) for holding our non-vowel characters. So as the function looks at the string text, it evaluates each individual character.

If the character is in vowels, it skips it; if the character is not in vowels, it adds it to the newtext string. And finally, at the end, it returns the value of newtext, which is a string without vowels.

I hope that helps!


#3

Thank you very much joeb.
I really appreciate! And it is exactly what i need, a breakdown of the problematic parts and the reason why. I'm sure it will also help other people stuck on the same problem.
It is very good feedback. Many thanks.

DD


#4

Hi joeb! :smile:
Thanks for the hel, but could you please elaborate the step

if char in vowels: continue

is the string vowels treated as a list ? How are we traversing this vowels string ?


#5

Hi bhavuk_s!

The string vowels is treated almost like a list, in the sense that the expression

for char in text:
    if char in vowels:
        continue

says something like: Let's look at each character in text, one by one, and see if any of those characters can also be found in the string vowels. The continue here just means "continue searching the text starting with the next character". And of course char is a made-up variable; we could also say i or x or letter, for example.

Here's a simpler version of this structure:

title = "I love Python"
vowels = "aeiouAEIOU"

for letter in title:    # "letter" here could also be x or char, for example
    if letter in vowels:
        print "This is in vowels: " + letter
    else:
        continue

If we run this code we get this result printed:

This is in vowels: I
This is in vowels: o
This is in vowels: e
This is in vowels: o

I hope that helps!


#6

Thank you a lot, usually it's pretty hard to find a clear explanation of using logic. But you did it very clear, and your solution is so simple and obvious. :wink:


#7

@joeb
def anti_vowel(text):
v=['a','e','i','o','u','A','E','I','O','U']
j=[]
for letter in text:
j.append(letter)

    for x in j:
        if x in v:
            j.remove(x)

    return "".join(j)
print anti_vowel("hey look Words!")

i tried your method using string and it works great, i just wanted to solve it by using the list method, but somehow it doesn't detect 'o' in words, before that it works fine..
i tried that python tutor but it didn't worked out well
plz tell what i m doing wrong.!!
and what difference would it make if i solve it using list or string !


#8

Hi chipace,
If j in your example above is a list, the reason you are having problems is that you cannot iterate (go through the elements) through a list in Python while calling the remove method on the same list. This is also true in some other languages, I believe; at least it's also true in Ruby.


#9

it is working for first two words, but as the third one 'Words!' came in string it kinda just ignored it
if i put string "eeee" as input it gives output of "ee" ..thats weird


#10

Yeah, it's a little weird. What happens is that as you are going through the list and removing elements you are changing the list indexes and thereby getting a confusing result. The way to use the method you are using successfully is to iterate through a copy of the list, which you can create simply by adding [:] to the list name in the loop. See below:

def anti_vowel(text):
    v=['a','e','i','o','u','A','E','I','O','U']
    j=[]
    for letter in text:
        j.append(letter)
        
    for x in j[:]:  <== right here, make j into j[:], which is a copy of j 
        if x in v:
            j.remove(x)

    return "".join(j)
print anti_vowel("hey look Words!")

It's strange, but this making a copy with [:] seems to get around this feature.


#11

Thank you joeb. I used the below code and it worked.
best

def anti_wovel(text):
	wovel = "aeiouAEIOU"
	result = ""
	for c in text:
		if c not in wovel:
			result += c
	return result

#12

yeah, this seems to work
thanks man, you really helped a lot..


#13

Thanks @joeb you were very helpful :smiley: