Project:censor dispenser,

i dont realy understand why my code give back- none

email_one = open("email_one.txt", "r").read()
email_two = open("email_two.txt", "r").read()
email_three = open("email_three.txt", "r").read()
email_four = open("email_four.txt", "r").read()
#this function will censor a word from email
def email_censor(email,censor):
  censor_item=""
  for letter in range(len(censor)):
    if censor[letter]==" ":
      censor_item==censor_item+" "
    else:
      censor_item=censor_item+'x'
  return email.replace(censor,censor_item) 
      
#print(email_censor(email_one,"learning algorithms") )

proprietary_terms = ["she", "personality matrix", "sense of self", "self-preservation", "learning algorithms", "her", "herself"]
#this function will censor a list of words
def censor_multi(email,lst_censor):
  
  for word in proprietary_terms:
    email=email_censor(email,word)
  return email

#print(censor_multi(email_two,proprietary_terms))
negative_words = ["concerned", "behind", "danger", "dangerous", "alarming", "alarmed", "out of control", "help", "unhappy", "bad", "upset", "awful", "broken", "damage", "damaging", "dismal", "distressed", "distressed", "concerning", "horrible", "horribly", "questionable"]

def censor_three(email_three,negative_words,lst_censor):
  count=0
  for word in email_three:
    if word in negative_words:
      if count<2:
        count+=1
      else:
        email_three=email_censor(email_three,word)
      return censor_multi(email_three,lst_censor)
    
print(censor_three(email_three,negative_words,proprietary_terms))
  

be happy for any help, by the way my goal in the seconed function is to censor all words that in negative words list, after the seconed word appear,
and to censor all words in the list

why would you get something other than none, and what did you do differently from that? you could use print to print out what is being done

im not sure i understand the goals of the third function,
like i should censor all the words in the two lists, except the first two(words )?
i mean the first two negative words is cool, and the rest i need to censor?

Is that a different question? I can’t tell.

You’re getting None because your function has more than one possible path through it, and not all of them end in the return statement but instead reach the end of the function, like this:

def f():
    1 + 1

print(f())  # None

The reason you’d get something other than None is if you returned some value, for example:

def f():
    return 1 + 1

print(f())  # 2

What the function should do, that’s something the instructions describe. I’m not sure what their wording are.

… I suppose I can go look it up

Write a function that can censor any occurance of a word from the “negative words” list after any “negative” word has occurred twice, as well as censoring everything from the list from the previous step as well and use it to censor email_three .

allowing two negative words and censoring the rest sounds like a reasonable interpretation. the end result would have a total of two negative words

as well as censoring everything from the list from the previous step as well and use it to censor email_three .

that looks to me like it would be unrelated to the count of 2, and would be something you could do before or after… I guess you’d have to decide.

thank you bro,
so actually my mistake was indetetion with return?
like i need to put the return out of the loop,
cause in the project solution they did somthing completry different, their solution more elegant but i didnt understood what the meant to do, like wich word they censor

punctuation = [",", "!", "?", ".", "%", "/", "(", ")"]
def censor_three(input_text, censored_list, negative_words):
  input_text_words = []
  
  for x in input_text.split(" "):
    x1 = x.split("\n")
    for word in x1:
      input_text_words.append(word)
  for i in range(0,len(input_text_words)):
    if (input_text_words[i] in censored_list) == True:
      word_clean = input_text_words[i]
      censored_word = ""
      for x in range(0,len(word_clean)):
        censored_word = censored_word + "X"
      input_text_words[i] = input_text_words[i].replace(word_clean, censored_word)
    count = 0
    for i in range(0,len(input_text_words)):
      if (input_text_words[i] in negative_words) == True:
        count += 1
        if count > 2:
          word_clean = input_text_words[i]
          for x in punctuation:
            word_clean = word_clean.strip(x)
          censored_word = ""
          for x in range(0,len(word_clean)):
            censored_word = censored_word + "X"
          input_text_words[i] = input_text_words[i].replace(word_clean, censored_word)
  return " ".join(input_text_words)
  
print(censor_three(email_three, proprietary_terms, negative_words))

# These are the emails you will be censoring. The open() function is opening the text file that the emails are contained in and the .read() method is allowing us to save their contexts to the following variables:
email_one = open("email_one.txt", "r").read()
email_two = open("email_two.txt", "r").read()
email_three = open("email_three.txt", "r").read()
email_four = open("email_four.txt", "r").read()

def censor_one(input_text, censor):
  censored_item = ""
  for x in range(0,len(censor)):
    if censor[x] == " ":
      censored_item = censored_item + " "
    else:
    	censored_item = censored_item + "X"
  return input_text.replace(censor, censored_item)

# print(censor_one(email_one, "learning algorithm"))

proprietary_terms = ["she", "personality matrix", "sense of self", "self-preservation", "learning algorithm", "her", "herself", "Helena"]

def censor_two(input_text, censored_list):
  for word in censored_list:
    censored_word = ""
    for x in range(0,len(word)):
      if word[x] == " ":
        censored_word = censored_word + " "
      else:
        censored_word = censored_word + "X"
    input_text = input_text.replace(word, censored_word)
  return input_text

#print(censor_two(email_two, proprietary_terms))

negative_words = ["concerned", "behind", "danger", "dangerous", "alarming", "alarmed", "out of control", "help", "unhappy", "bad", "upset", "awful", "broken", "damage", "damaging", "dismal", "distressed", "distressed", "concerning", "horrible", "horribly", "questionable"]
punctuation = [",", "!", "?", ".", "%", "/", "(", ")"]
def censor_three(input_text, censored_list, negative_words):
  input_text_words = []
  
  for x in input_text.split(" "):
    x1 = x.split("\n")
    for word in x1:
      input_text_words.append(word)
  for i in range(0,len(input_text_words)):
    if (input_text_words[i] in censored_list) == True:
      word_clean = input_text_words[i]
      censored_word = ""
      for x in range(0,len(word_clean)):
        censored_word = censored_word + "X"
      input_text_words[i] = input_text_words[i].replace(word_clean, censored_word)
    count = 0
    for i in range(0,len(input_text_words)):
      if (input_text_words[i] in negative_words) == True:
        count += 1
        if count > 2:
          word_clean = input_text_words[i]
          for x in punctuation:
            word_clean = word_clean.strip(x)
          censored_word = ""
          for x in range(0,len(word_clean)):
            censored_word = censored_word + "X"
          input_text_words[i] = input_text_words[i].replace(word_clean, censored_word)
  return " ".join(input_text_words)
  
print(censor_three(email_three, proprietary_terms, negative_words))

punctuation = [",", "!", "?", ".", "%", "/", "(", ")"]

def censor_four(input_text, censored_list):
  input_text_words = []
  for x in input_text.split(" "):
    x1 = x.split("\n")
    for word in x1:
      input_text_words.append(word)
  for i in range(0,len(input_text_words)):
    checked_word = input_text_words[i].lower()
    for x in punctuation:
      checked_word = checked_word.strip(x)
    if checked_word in censored_list:

      # Censoring the targeted word
      word_clean = input_text_words[i]
      censored_word = ""
      for x in punctuation:
        word_clean = word_clean.strip(x)
      for x in range(0,len(word_clean)):
        censored_word = censored_word + "X"
      input_text_words[i] = input_text_words[i].replace(word_clean, censored_word)

      # Censoring the word before the targeted word
      word_before = input_text_words[i-1]
      for x in punctuation:
        word_before = word_before.strip(x)
      censored_word_before = ""
      for x in range(0,len(word_before)):
        censored_word_before = censored_word_before + "X"
      input_text_words[i-1] = input_text_words[i-1].replace(word_before, censored_word_before)

      # Censoring the word after the targeted word
      word_after = input_text_words[i+1]
      for x in punctuation:
        word_after = word_after.strip(x)
      censored_word_after = ""
      for x in range(0,len(word_after)):
        censored_word_after = censored_word_after + "X"
      input_text_words[i+1] = input_text_words[i+1].replace(word_after, censored_word_after)
  return " ".join(input_text_words)

censor_all = proprietary_terms + negative_words

print(censor_four(email_four, censor_all))

this is all their solution, i didnt understood why they check again the length of the word instead using the first/seconed function
i will be happy for explanation

We’re not reasoning about text… we’re reasoning about what should happen.

Should it happen while iterating, or afterwards? Both? You have to refer to the actions otherwise … it’s moving stuff around randomly and that’s no good.

  for x in input_text.split(" "):
    x1 = x.split("\n")
    for word in x1:
      input_text_words.append(word)
  for i in range(0,len(input_text_words)):
    if (input_text_words[i] in censored_list) == True:
      word_clean = input_text_words[i]
      censored_word = ""
      for x in range(0,len(word_clean)):
        censored_word = censored_word + "X"
      input_text_words[i] = input_text_words[i].replace(word_clean, censored_word)
    count = 0
    for i in range(0,len(input_text_words)):
      if (input_text_words[i] in negative_words) == True:
        count += 1
        if count > 2:
          word_clean = input_text_words[i]
          for x in punctuation:
            word_clean = word_clean.strip(x)
          censored_word = ""
          for x in range(0,len(word_clean)):
            censored_word = censored_word + "X"
          input_text_words[i] = input_text_words[i].replace(word_clean, censored_word)
  return " ".join(input_text_words)

^ that right there is a horror show in my eyes you can do better than that, don’t be impressed so easily xD

the problem with this is that there’s no way you can keep this in your head and say “yeah that’s the right thing”, it’s one big blob and it’s asking for problems to hide in it!

Here’s a function that accepts disallowed phrases (list of list of strings, for example:

[["her"], ["personality", "matrix"]]

which would be a 1-word phrase and a 2-word phrase

and then an email, but only words (having isolated the words elsewhere)

["blah", "blah", "blah", "more", "blahs"]

There’s no whitespace or punctuation, the input is all neat, and that means the code doesn’t have to bend over backwards to get at the parts it cares about.

def indices_to_censor(phrases, email, after=0):
    should_censor = set()
    count = 0
    for i, phrase in product(range(len(email)), phrases):
        words_here = email[i : i + len(phrase)]
        if words_here == phrase:
            if count >= after:
                should_censor.update(set(range(i, i + len(phrase))))
            count += 1
    return should_censor

This then would return the locations that should be censored.

Why is it short? Because it doesn’t need to do very much thanks to the clean input, all it needs to do, is to compare each disallowed phrase at each location of the email, and if there’s a match, those locations get remembered.
See, its description fits in one sentence.

There is an accompanying function to this that accepts a whole email string, pops out the words and puts them in a list, calls the above censoring function, and puts it all back together again like a zipper.

sorry, but, can’t call that elegant, not allowed.

Your best guide to what needs to/should happen is to consider how you yourself would go about it. What would your strategy be if you were given an email on paper and a pen to cross things out?
Pay special attention to how you read that email and the words, because your program would also need to read using that same strategy and order, it would need to move through the email and make comparisons and decisions and occasionally it would scratch something out.

When you manually read an email you are isolating the words from one another. This can be difficult to do in code while also doing other things at the same time, but this doesn’t need to happen at the same time, the words can be cleaned up before they’re sent into the censoring algorithm. This is exactly what lists are for, this is why we use types at all. We don’t do all our computation on strings!

if the email i got i so clean, why should i split it to lists, instread just iterate every word, if the word soppuse to be cesored> i switch it with xxx ( another function check the length)

why is it better to use lists?

and thanks a lot for your help,

That would be the goal, but you can’t iterate through words until you’ve extracted them from the big string. If you iterate over the email string you would be iterating over the characters, not words. So there’s an intermediary step required, and the result of that step would be a list. If you have many of something then you’d probably put them in a list, if you have many words… then you’d have a list of words.

1 Like

ohhh it a noob mistake!
thank you so much!