Censor


#1



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

I have copy pasted the code from another topic here -as I'm unable to solve the exercise on my own - completely stuck here, haven't got a clue. Still, it won't work

def censor(text,word):
list = text.split()
for i in range(0,len(list)):
if list(i) == word:
list(i) = "*" * len(word)
return "".join(list)
It says "Oops, try again. Does your censor function take exactly two arguments, a text string and a word to replace with asterisks? Your code threw a "'list' object is not callable" error. "

While on the console I get this: File "python", line 5
SyntaxError: can't assign to function call

Can someone help? I don't understand anything


Replace this line with your code.


#2

Hi @bogdanel77,

I have some comments for you:

1.. using list as a variable name

in Python, list is a keyword, which means that it represents something and should not be used casually as a variable name for any assignments...so change a variable name :slight_smile:

2.. what you are looping over

When you do this, you are looping over the numbers 0 to the length of the split text (I'm ignoring your use of list here, which has been addressed in 1..). In reality, you are trying to compare each word in word with each word in text and seeing if they are the same, which means you are trying to loop over the words in "list" (again, please change your variable name!) instead of looping over numbers 0 to len(list).

3.. doing list(i)

I am not sure why you did this. By doing this, I imagine you to be having this conversation with Python:

You: Hey Python, I have a request.

Python: Yes?

You: For each number from 0 to length of my variable, can you check if each number is equal to each word in word after it has been converted into a list type? Like check if [0] is equal to word, [1] is equal to word etc.

Python: ??? *(&$

Recall that word is a string input, so in fact there is no need for i to be converted to a list type.

Additionally, for the next bit, you have missed out something that is a good habit to practise. The proper way to do it would be to first create a new empty list before your for loop where you can append your "*" * len(word), so that you're not modifying the original lists/strings etc but creating something new entirely, making it easier to check for mistakes etc.

4.. what you return eventually

If you take up my suggestion and create a new empty list stored under a new variable name before your for loop, make sure you return the correct list! :stuck_out_tongue:

Hope this helps :slight_smile:


#3

Thx. I've tried to put in practice what you've said. I've renamed the variable "split",created an empty list "censored", rewrote the loop
Now my code looks like this:

def censor(text,word):
    split = text.split()
    censored = []
    for word in split:
        if split(word) == word:
            split(word) = "*" * len(word)
            censored.append(split(word))
            return censored

I still get the same error message concerning line six - split(word) = "*" * len(word) - this line. It says:
File "python", line 6
SyntaxError: can't assign to function call

I don't understand what I did wrong and how can I fix it.


#4

split is a list, you can't get item of list by calling split(word). You can access list items by index. For example:

text = "big black cat"
split = text.split() # split is a list ["big", "black", "cat"]
print split[0] # big
print split[2] # cat

Also, you have named variable in for as word, this is overriding word variable passed as argument, so you can't check if the loop's word equals the word variable from arguments.

Check my answer to similar question to get know how to get indexes of words and change items in list.


#5

Well I think I've got an improved version. But still isn't what it should be

def censor(text,word):
    split = text.split()
    censored = []
    for c in split:
        if c == word:
            c = "*" * len(word)
            censored.append(c)
    return censored

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


#6

Your function will return only list with censored words, but it should return whole text with censored words.

If you call print censor("hey asd hey","hey") it will return
['***', '***'],
but should return *** asd ***.

You should rewrite your function to change items of text list (if c == word) and then return
" ".join(text) which returns all elements of list joined by space. Please revisit linked topic :slight_smile:


#7

You should rewrite your function to change items of text list (if c == word)

Ok, I give up. How do I do that?
I understand what I did wrong, I still don't know how to make it right.


#8

I think you should understand what is done here.
If you don't know what enumerate() means check documentation.

def censor(text, censored):
    split = text.split()
    for index, word in enumerate(split): # enumerate returns tuple (index, split[index])
        if word.lower() == censored.lower(): # checking case insensitive
            split[index] = "*" * len(word)
    return " ".join(split)

#9

Thx. You're right, I don't really understand what is it about (well, i think now I do after your spoon-feeding). In my defense I could say that most I've learned in previous chapters on code academy is too basic for the tasks to be solved here. For example I don't recall learning about enumerate() and I took all the steps one by one. It seems to me the gap is too big between what's here and what one learns before


#10

I used this code and it worked:

def censor(text, word):
if word in text:
new_word = "*" * len(word)
text = text.replace(word, new_word)
return text

print censor("this hack is wack hack","hack")


#11

Alternatively, you can also consider something like this:

def censor(text, word):
    new = text.split()
    censored_list = []
    for item in new:
        if item == word:
            censored_list.append("*" * len(word))
        else:
            censored_list.append(item)
    return " ".join(censored_list)

where only the.split() function is new, and " ".join(list_name) came from the Battleships chapter.

P.S. the enumerate function was actually introduced in Unit 8: Loops, the exercise directly preceding this Practice Makes Perfect bit...


#12

Thx, your code is very clean and simple but you have to know about the text.replace function -which I did not. Seems I have to do some documentation work.


#13

thx, your code is also very clear. Me thinks me understands now.


#14

def censor(text,word):
l=[]
l=text.split()
c=[]
for w in l:
wl=len(w)
if w==word:
c.append("*" * wl)
else:
c.append(w)

return " ".join(c)