Censor, How to prevent each letter from being added to a List Individually



Oops, try again.
Your function fails on censor("hey hey hey","hey"). It returns "* * * * * * * * *" when it should return "*** *** ***".

I expected that the strings should combine into one string, instead they input each individual letter of words as a string on the w list. I am aware of the error, but I don't understand how the error arises.

Replace this line with your code. 
def censor(text, word):
    q = text.split(" ")
    w = []
    for words in q: 
        if word in words: 
            w += '*' * len(word)
            w += words
    z = " ".join(w)
    return z
print censor("this hack is wack hack", "hack")

Also, this is the first time I have asked a question on Codecademy, so I apologize in advance if I did anything wrong.


Examine the data types in each line.

text, word    # a string of words, a single word

q             # a list of words
w             # an empty list

words         # a single member in the q list, misnomer?

word in words # both are single items, `in` is misused

w += ....     # list concatenation is misused

The latter two indicate points of possible issue.

It might an idea to review the naming convention used in your code.

words = text.split(" ")

This makes sense to me since it is semantic. A sentence contains words.

result = []

Again, semantic. This is the intended return value.

for w in words:

word would be nice to use here, but it is already defined as the word to censor so we can't.

if w == word:
    result.append('*' * len(word))

Notice we used identity and the list.append() method?

return " ".join(result)

It would still be worthwhile closely examining your code to see what is happening and why. The above will help you solve the exercise, but it doesn't address your code. This is still yet to do, so don't cheat yourself out of it; and, share your findings, please.


Alright, so I solved the exercise with this code, thanks to your advice.
def censor(text, word):
q = text.split(" ")
result = []
asterisks = '*' * len(word)
for words in q:
if word in words:
return " ".join(result)
print censor("this hack is wack hack", "hack")

I was tired at the time, so I think that is a decent explanation for why I messed up the logic with adding to the lists like that. Now that I am looking at the original code again, I would think that the multiplication * causes the same thing to be appended multiple times, am I correct?


This is still an impractical way to compare identity. When comparing two objects we would not look for one in the other, just whether they are identical or not.

if w == word:

Now if we change the parameter variable to `term', as in,

def censor(text, term):

that will free up the variable name, word which works to our favor...

    words = text.split(" ")

    for word in words:
        if word == term:
            result.append("*" * len(term)

As you progress through learning, especially once you enter a formal learning environment such as university, semantics will be pounded into your thinking. If your prof cannot make sense of your code because it is unreadable, it will be your fault for choosing non-semantic terms in your code. Keep this in mind and write semantic (meaningful) code that others can read and make sense of.


Thank you for the advice, I am fairly sure that this won't be the last time I go through this same course.