10/15 MemoryError


#1

I did't konw the .spilt() function and used my own codes. And it says MemoryError which confuses me.
here are my codes.

def censor(text,word):
j=0
modi_t=[]
while j<len(text):
    add_t=''
    for i in range(j,len(text)):
        if text[i]==' ':
           break
        else:
            add_t+=text[i]
    modi_t.append(add_t)
    j=i
for each in modi_t:
    t=''
    if each ==word:
        each='****'
    t+=each
return t

print censor('The number of asterisks you put should correspond to the number of letters in the censored word.','number')


#2

Anybody could answer my Q?
I was entirly confused


#3

ok no reply.
I figure it out myself.
cry


#4

Man you should just delete that whole thing and start again.

I understand that the instructions can be confusing so I will break down what you need to do.

The lesson ask you to take any word of any length and replace a select sequence with the * for each part of the word.

So here are the things you will want to get from the string,

 1. The length of the word
 2. The position of the word on the string(we can convert the string into a list)

Ok now that we know what to get from the string we need to know where at in the string the word is. The easiest method for a beginner to use is to change the string into a list.

Also the other reason for changing the string into a list is that in python strings are immutable.

So lets create our function to replace our censor word in our string.

First part

def censor(text, c_word):
    length_of_c_word = len(c_word)

Now we need to split the words into a list because we don't want a list of letters.

def censor(text, c_word):
    length_of_c_word = len(c_word)
    word_list = text.split()

Easy enough?

Next we need to match our word to the c_word,

def censor(text, c_word):
    length_of_c_word = len(c_word)
    word_list = text.split()
    for word in word_list:
        if word.lower() == c_word.lower():
            print(word)

Ok, now we have a way to find the word and it tells us when it finds the word.

Next, lets replace the word with our character *.

def censor(text, c_word):
    length_of_c_word = len(c_word)
    word_list = text.split()
    for index, word in enumerate(word_list):
        if word.lower() == c_word.lower():
            word_list[index] = len(word) * "*"

OK, the only thing left is to return the list as a string again. This part is easy but you have to use a string method to accomplish it easily.

def censor(text, c_word):
    length_of_c_word = len(c_word)
    word_list = text.split()
    for index, word in enumerate(word_list):
        if word.lower() == c_word.lower():
            word_list[index] = len(word) * "*"
    return ' '.join(word_list)

That is all there is to is, if I did not explain something or missed something feel free to tell me.


#5

thx a lot.
I just tried to find out a way not to use .spilt() and had corrected it. But I find that it's too complex.
thank you,you did a lot of help :smile:
@zeziba


#6

I should also add one of my favorite methods of use, the list comprehension and ternary functions!

If you don't know of them don't worry these are kinda advanced, well list comprehension is more of a moderate skill and ternary functions are advanced.

def censor(text, c_word):
     return ' '.join([(("*" * len(word)) if word.lower() == c_word.lower() else word) for word in text.split()])

#7

I can get it.
but my code has a problem again....

 def censor(text,word):
    c_word='*'*len(word)
    lists_text=text.spilt()
    for each in lists_text:
        if each.lower()==word.lower():
            each=c_word
    return ' '.join(lists_text)

it says line 3 has a problem.
And how can i print code like you


#8

Uh.... no bother anymore
I often spell the wrong word( English is not my first Language..... sorry to bother


#9

Hi there! Hang in there, you're doing just fine! First of all, this problem is mean. There are several functions it wants you to use, but doesn't give you in the hints. In addition, the hints create another problem for the programmer. The string.split() function splits a string into a list. After using a for loop and if statements to see find and censor all the words, the list.append(string) function adds the words back into an empty list.

Very cool, but how can we turn a list back into a string? Well, there is this function called character.join(final_phrase). Where character can take on any symbol such as " " or "-" to create spaces in the string. Perhaps adding that bit of information in the hints would help out most beginner coders. I am doing this the second time myself, and things are becoming clearer to me.

In any case here is my answer, with comments. I tried to keep the code simple, but detailed to maintain the concepts taught in this course. Try doing this several times yourself, before looking at the answer!

def censor (text, word):
    # split the string into a list
    split_string = text.split()
    #create an empty string
    final_phrase = []
    # run a for loop that iterates through the list
    for i in split_string:
        if i == word:
            # turn the print statement on to see how the code behaves
            # print final_phrase.append("*" * len (word))
            final_phrase.append("*" * len(word))
        else:
            # turn the print statement on to see how the code behaves
            # print final_phrase.append(i)
            final_phrase.append(i)
    # exit the if statements and add the words togather in a list
    # print final_phrase
    # use .join(list) function to concatenate items in a list into a string:
    final_phrase = " ".join(final_phrase)
    # return final_string
    return final_phrase


# and now to test the function
print censor ("hey hey hey", "hey")
print censor ("fish try to swim away and hide from orcas , but the orcas used echolocation and caught them anyway", "orcas")

#10

Thanks for the nice and thorough explanation. I just want to point out one thing in your code: the line length_of_c_word = len(c_word) is unused and unnecessary and therefore can be taken out. :thumbsup:


#11

I'm confused regarding syntax. When you use
for (variable), (variable) in (something)
I don't understand the "," followed by a second part. Please explain.


#12

@codeslayer22157

Again here is me code

let's break this down a little,

Declaring the function

def censor(text, c_word):

There are two variables in this function. one is the text to fiter and the other is the word that is the filter.

Ternary Function

("*" * len(word)) if word.lower() == c_word.lower() else word)

This is simple if you understand ternary functions. What this is, is a conditional variable assignment, it's as easy as that. If condition one is false then it will give the else instead of the leading variable.

List Comprehension

[(("*" * len(word)) if word.lower() == c_word.lower() else word) for word in text.split()]

This thing here after you take out the ternary part

[(variable_here for word in text.split()]

Now as you can see it is just a simple list comprehension generator. I am using the string method split to create a list of the words to iterate. The rest is just simple comparison.

@thatchweave

enumerate() is a builtin function that allows you to access the index of what you are iterating over. It comes in handy a bunch of times when you need access to the index and the value.

So when you use enumerate() it returns a tuple that you have to handle, if you do not then it will trow an error, and the way to capture the tuple and unpack it is using the syntax of,

a = [5, 4, 3, 2, 1]
for index, item in enumerate(a):
    print(index, item)

If you get creative you can do all types of things with this.


#13

I understand the enumerate function. It's the "for" statement with the comma that confuses me.

typically it's for x in/not in or some other condition which tells the loop how long to run. For index, item in....
that is what I don't get. Thanks for your time.


#14

It's simply the first item is the index and the second is the normal item it would iterate over.

a = ['a', 'b', 'c', 'd', 'e']
for index, item in enumerate(list):
    print(index, item)

This will do the following,

# OUTPUT
# 0, 'a'
# 1, 'b'
# 2, 'c'
# 3, 'd'
# 4, 'e'

#15

Now I get it. Basically, do 2 things for every iteration right? Or better said, examine 2 things.


#16

Well sorta, it is doing what a normal for loop does except it gives us access to the index it is on, like a list that has an index of 5 it allows us to get the index so we can work with it in our for loop. That is what I named them such, index and item one is the index two the item.


#17

Of course this method excludes any partial matches, so if you're looking for "dog" it won't match "dogs" to make "***s". Then again, the exercise doesn't mention the need for this :smile:

Seriously though, kudos to you for the very thorough explanations you offer here. They're excellent!


#18

Actually it does match dog in dogs that is what the in keyword is used for.

Example:

'dog' in 'dogs'
# OUTPUT: True

If you want it to still censor the word then you have to add that to your code to do so, you can have it loop through the word to get the position of the word in the string then change it and add the leading letters and trailing letters back to the string then return the string. Or you can just use the string method replace.

Here is an example below.

Example:

def censor(text, c_word):
    return ' '.join([(word.replace(c_word, '*' * len(c_word)) if c_word.lower() in word.lower()
                      else word) for word in text.split()])

This code does what you want, we could use regular expressions to fine tune our code even further to match if a word is really something we want to censor or not.


#19

Thanks Zeziba :smile: I appreciate your thorough explanations!


#20