10. Censor


#1




Hello python community, this is my first post to you (written in html) and so I would like to know what you think of my code so far. However, onto the serious part(ish):
Does this look like a 'type' error?
By this I mean int, str, list etc.
I may be a little off since I've done 5 courses these past 3 weeks (still stuck in js sytax really)
Thanks in advance...



def censor(text,censorword):
text = text.split()
fntxt = ""
for word in text:
if word == censorword:
fntxt += "*" * len(word)
fntxt += " "
print fntxt
else:
fntxt += word
fntxt += " "
print fntxt
print fntxt
return fntxt
censor("Hello, how are you today? No, how are you?", "how")

This returns:

Hello,
Hello, ***
Hello, *** are
Hello, *** are you
Hello, *** are you today?
Hello, *** are you today? No,
Hello, *** are you today? No, ***
Hello, *** are you today? No, *** are
Hello, *** are you today? No, *** are you?
Hello, *** are you today? No, *** are you?

I would really appreciate it if you guys could help here.
(validation error message = "Oops, try again. Your function fails on censor("hey hey hey","hey"). It returns "*** *** *** " when it should return "*** *** ***". "

Thanks again.



#2

my code

def censor(text,word):
return text.replace(word.lower(),''len(word))

as longer code you make as much mistake's you'l have


#3

not all code is depicted, don't know why !!! after word in replace should be( "multiply symbol"multiply ) or ''star''star before len....

Mistake will happen when there is an upper case in original text, but check system don't look on this


#4

I think there's only 1 mistake, perhaps with the extra spaces I'm adding.


#5

You are using "print tntxt" allow. Is this test code? If so, its good practice to comment it as such #TEST CODE allows you to see where you are at with test V draft/final code cleaning up your script appropriately. The call using quotation marks and actual test is not good practice. You should wrap that text in a variable. so:

text = "Hello, how are you today? No, how are you?"
censorword = "how"

Here is how I solved it. Note the following:

a) text.split is wrapped in a variable t.
b) return is using .join() to bring all the split text back together again
c) the use of a list to input all letters that are censored and not censored rebuilding the text through .append()

text = str(raw_input("Please input your subject text for censorship")).lower()
word = str(raw_input("Please enter the offending word to be returned in the censored version of the text")).lower()

def censor(text, word):
    result = []
    t = text.split()
    
    for w in t:
        if w == word:
            result.append("*"*len(word))
        else:
            result.append(w)
    return " ".join(result)
print censor(text, word)

#6

def censor(text, word):
return text.replace(word.lower(),''len(word))


#7

Here is what I did and it works.

def censor(text, word):
for i in text:
i = word
x = len(word)
a = ''x
new_str = str.replace(text, word, a, 5)
return new_str


#8

Hi johmmlhll,
I tried something similar but don't get any validation of the exercise:

********* my code ************

define a censure function

def censurer(texte, mot):
liste = []
separe = texte.split()
for i in separe:
if i == mot:
i = '*' * len(mot)
liste.append(i)
else:
liste.append(i)
return ' '.join(liste)

Calling the text and word to censor

mot = raw_input('Entrez votre mot :')
texte = raw_input('Entrez votre texte :')

calling the function

resultat = censurer(texte, mot)
print resultat

*************** answer System ********************
"global name 'censure' is not defined"
However, code give the correct sensor result.


#9

try

return fntxt.strip()

#10

@kleyer I have had a look at your code and think its returning the * censored part, not the refilled strong from the list. I tested your code as follows:

mot = raw_input('Entrez votre mot: ')
texte = raw_input('Entrez votre texte: ')

def censurer(texte, mot):
    liste = []
    separe = texte.split()
    print "Length of separe variable", len(separe) #TEST CODE - PASS
    for i in separe:
        if i == mot:
            i = '*' * len(mot) #Why use the variable i to assign the astrix? Why not append straight (liste.append(*)*len(mot))
            liste.append(i)
            print "List print using 'i' var is", liste #TEST CODE - ??
        else:
            liste.append(i)
            print "List print is", liste #TEST CODE - PASS - ??
        return ' '.join(liste)

resultat = censurer(texte, mot) #Why introduce a variable here. It should "print censurer(texte ,mot)"
print resultat

It gave me the following return in a Python editor when ran from cli:

Entrez votre mot: mes
Entrez votre texte: Les mot de la texte est difficult for mes ami d'Irelande
Length of separe variable 11
List print is ['Les']
Les

Can you can see, the test code outputs clearly show your for loop is not iterating over the list that has correctly split the string into words, but is not iterating over, populating the new liste through the if statement looking for a match to the word (mot) and then replacing the word letters with *. The issue lies in your if statement. I shall post my debug of your code next.


#11

@kleyer ok, here is my fix. Basic changes were returning the for loop return to under the for and not the if statement. The rest were good coding practices to allow readability and reusability. My short time (13 months from scratch) training in code and doing code in C# and Java has shown me that convention and readability are very important. In Python, respecting the curves of indentation is even more important as whitespace indentation will leave you stummed for hours debugging. Hope this helps bro!

mot = str(raw_input("Entrez votre mot: ")).lower()#up front for definition PRE function and lower() helps with matching
texte = str(raw_input("Entrez votre texte: ")).lower()#up front for definition PRE function

def censurer(texte, mot):
    liste = []
    separe = texte.split()#this
    print "Length of separe variable is ", len(separe) #TEST CODE - PASS
    for i in separe:
        if i == mot:
            liste.append("*"*len(mot)) #I removed the further use of the variable "i", which was not working.
            print "List print using 'i' var is", liste #TEST CODE - PASS
        else:
            liste.append(i)
            print "List print is", liste #TEST CODE - PASS
    return " ".join(liste)#Watch your indentation, it returns out of the loop IF under else and not for loop indentation
print censurer(texte, mot)#streamlined function call
#Deleted this print command removing the variable by deleting print resultat

#12

Hi @johmmlhll ,

Thanks fr this feedback and sorry for answering back such a long time after your reply.
I was quite busy with the work. no time for coding :frowning:
I tried again using your script but get a new error code.
"'str' object is not callable".

Any idea?
If not I will have to cheat :wink:
Thanks
Kleyer


#13

Hi Kleyer,
Sounds like a typo, you are doing something incorrect and minor.. I got my code posted to work first time round. Check it out (it includes test code outputs in the CLI):

mot = str(raw_input("Entrez votre mot: ")).lower()#up front for definition PRE function and lower() helps with matching
texte = str(raw_input("Entrez votre texte: ")).lower()#up front for definition PRE function

    def censurer(texte, mot):
        liste = []
        separe = texte.split()#this
        print "Length of separe variable is ", len(separe) #TEST CODE - PASS
        for i in separe:
            if i == mot:
                liste.append("*"*len(mot)) #I removed the further use of the variable "i", which was not working.
                print "List print using 'i' var is", liste #TEST CODE - PASS
            else:
                liste.append(i)
                print "List print is", liste #TEST CODE - PASS
        return " ".join(liste)#Watch your indentation, it returns out of the loop IF under else and not for loop indentation
    print censurer(texte, mot)#streamlined function call`

I would post your code if you want to trouble shoot it

Here are the outputs I got through the CLI:

John-Mulhalls-MacBook-Pro:downloads jmulhall$ python python_codeacademy_example.py
Entrez votre mot: love
Entrez votre texte: I love the name and the text of this loving article of love
Length of separe variable is 13
List print is ['i']
List print using 'i' var is ['i', '****']
List print is ['i', '****', 'the']
List print is ['i', '****', 'the', 'name']
List print is ['i', '****', 'the', 'name', 'and']
List print is ['i', '****', 'the', 'name', 'and', 'the']
List print is ['i', '****', 'the', 'name', 'and', 'the', 'text']
List print is ['i', '****', 'the', 'name', 'and', 'the', 'text', 'of']
List print is ['i', '****', 'the', 'name', 'and', 'the', 'text', 'of', 'this']
List print is ['i', '****', 'the', 'name', 'and', 'the', 'text', 'of', 'this', 'loving']
List print is ['i', '****', 'the', 'name', 'and', 'the', 'text', 'of', 'this', 'loving', 'article']
List print is ['i', '****', 'the', 'name', 'and', 'the', 'text', 'of', 'this', 'loving', 'article', 'of']
List print using 'i' var is ['i', '****', 'the', 'name', 'and', 'the', 'text', 'of', 'this', 'loving', 'article', 'of', '****']
i **** the name and the text of this loving article of ****


#14

If you wanna remove the test code and clean up the outputs to a finish code snippet, code looks like this:
mot = str(raw_input("Entrez votre mot: ")).lower()#up front for definition PRE function and lower() helps with matching
texte = str(raw_input("Entrez votre texte: ")).lower()#up front for definition PRE function

def censurer(texte, mot):
    liste = []
    separe = texte.split()#this
    for i in separe:
        if i == mot:
            liste.append("*"*len(mot)) #I removed the further use of the variable "i", which was not working.
        else:
            liste.append(i)
    return " ".join(liste)#Watch your indentation, it returns out of the loop IF under else and not for loop indentation
print censurer(texte, mot)#streamlined function call

Outputs are as follows:

John-Mulhalls-MacBook-Pro:downloads jmulhall$ python python_codeacademy_example.py
Entrez votre mot: love
Entrez votre texte: I love the love in spring, its to lovely...
i **** the **** in spring, its to lovely...
John-Mulhalls-MacBook-Pro:downloads jmulhall$


#15

its the best to keep everything short and simple.

def censor(text,word):
censorWord = ''.join('*' for char in word)
return text.replace(word.lower(),censorWord,len(word))


#16

hey,

could you explain why you need to put word.lower() and len(word) in the last line?

The question specifies that there won't be any upper case letters & when I removed word.lower()the error didn't mention upper case letters.

Thanks!


#17

Oh sorry, I made some correction and forget to change it here, and I actually didnt notice that no uppercase will be given in the question
it should be the following:

def censor(text,word):
censorWord = ''.join('*' for char in word)
return text.replace(word.lower(),censorWord)

The len(word) in my wrong example was actually defining the occurrence of the censor word, and no, dont put that in for this case, anyway, thanks


#18

and what about word.lower()?

That seems to be required, since I got an error when I removed it.


#19

def censor(text,word):
censorWord = ''.join('*' for char in word)
return text.replace(word,censorWord)

I dont get any error without the .lower(). Try copy and paste the one above and see if it works properly.


#20

Yup, that worked. Thanks!