Censor Dispenser Challenge Project (Python)

Congratulations on completing your project!

Compare your project to our solution code and share your project below! Your solution might not look exactly like ours, and that’s okay! The most important thing right now is to get your code working as it should (you can always refactor more later). There are multiple ways to complete these projects and you should exercise your creative abilities in doing so.

This is a safe space for you to ask questions about any sample solution code and share your work with others! Simply reply to this thread to get the conversation started. Feedback is a vital component in getting better with coding and all ability levels are welcome here, so don’t be shy!

About community guidelines: This is a supportive and kind community of people learning and developing their skills. All comments here are expected to keep to our community guidelines

How do I share my own solutions?

  • If you completed the project off-platform, you can upload your project to your own GitHub and share the public link on the relevant project topic.
  • If you completed the project in the Codecademy learning environment, use the share code link at the bottom of your code editor to create a gist, and then share that link here.

Do I really need to get set up on GitHub?
Yes! Both of these sharing methods require you to get set up on GitHub, and trust us, it’s worth your time. Here’s why:

  1. Once you have your project in GitHub, you’ll be able to share proof of your work with potential employers, and link out to it on your CV.
  2. It’s a great opportunity to get your feet wet using a development tool that tech workers use on the job, every day.

Not sure how to get started? We’ve got you covered - read this article for the easiest way to get set up on GitHub.

Best practices for asking questions about the sample solution

  • Be specific! Reference exact line numbers and syntax so others are able to identify the area of the code you have questions about.

3 posts were split to a new topic: Censor_four strips out the newlines from the original email

I’m fairly pleased with my end results of this project. (Ignore my poor naming conventions, I would absolutely clean that up for readability but have spent enough time on this project.)

The only thing I would have particularly liked more would be for my censor4 function to put the list back together WITH the original line breaks, but I’ll still take the win.


Here was my solution for this challenge. Manages to hit all the objectives with what I feel is fairly concise code–I took an approach of creating 1 function that grew with each objective rather than starting a new one for each task. Only thing I didn’t specifically address was punctuation, but code puts out the results I was expecting. Nice that it also preserves the formatting from the original E-mail, had to split the E-mail first at the line breaks ("\n"), then a second split into words. Now that I type this, I guess a sentence level split would be a good spot to deal w/ punctuation, but at this point I’m ready to move on from this XD


I know it’s a stupid question but…how do we run the code we write in Jupyter? In previous lesson with jupyter, “Reggie Linear Regression” we had “run” button, but now only things I hae is File, Edit, View and language? My “View” button only have Toggle Line Numbers and Toggle Header options.

Why do CC omit something so important?

Edit: I stuck so I looked at the people solutions for a hint. People use stuff that wahe not been covered, like “scrub” (what?).

Is this course really for beginners or did made a mistake and should find some easier course? All of you people seem like someone who already have some experience coding, no way you come with those solutions just after those couple CC lessons :frowning: I feel like a caveman in a library full of people, I mean my code to censor first email is this:

e1 = email_one.replace("learning algorithms", "CENSORED")

When in solution it’s this:

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

I know all those methods and syntaxes but theres just no way I could come up with something like this, which makes me think that either I’m an idiot or this course just requires something more than just what I gather from this course

Could someone point me to REALLY beginner friendly course? Jumping from 4 line functions straight to over 100 line code is not beginner friendly in my case,.


I think what stops you is perspective, your expectation on how one goes about writing code.

For any task you would consider what input you get and what output you need to produce.
Then, using every-day logic, what steps does that involve?
What is the first thing that needs to happen? Write a few lines for that first thing. Then reassess, what have you now got available, and how do you continue from there, what is the next thing that needs to happen?

It’s an interactive process. Make one small change to bring you a bit closer, test it, look at what you got, and keep going.

Pay special attention to types of things. Both the input and the output, but also your intermediary values. That’s what determines what operations are available. You might need to convert to a different type if you need a different operation. If you have two things that need to be combined in some way, then the two things and the thing you want from it says everything you need to know about the relation/action to make that happen (this would typically be a function, having several inputs and wanting an output)


Hey there! Don’t be discouraged by comparing your own solution to the example shared here. My first version of the first censor is pretty much exactly the same as yours!

def censor_word(text,word):
    result = text.replace(word,"####")
    return result

The solution provided doesn’t explain it very clearly, but why their solution looks much more complicated than yours (or mine!) is that they’ve added some additional logic to complete one of the ‘additional challenges’ from task six.

The task reads

Censor words while preserving their length.

So that extra code that looks much more complex than ours is because they’ve also included the solution for the extra challenge at the end. After I got to task six, I also updated my first censor and it came out like this.

### Censor a word or phrase in a piece of text.
def censor_word(text,word):
    censor = ""
    # Make the sensor the same length as the original word (incl spaces).
    for letter in word:
        if letter == " ":
            censor += " "
            censor += "#"
    result = text.replace(word,censor)
    return result

You’re not alone in the way you’re thinking and approaching the challenges! Think of the solutions provided as a way to inspire you with ideas on how to improve from your initial attempt, not necessarily what your first attempt should look like.

PS. I don’t understand the other two examples posted either, hehe. Don’t worry about comparing yourself to others though. We’ll all keep learning and getting better as we progress.


Greetings everyone!

I just finished my project, it doesn’t solve most of the extra challenges, but i thought the suggested paths to solve the challenges were more time consuming then the alternative solutions. I used the identities ‘objectVar’ or ‘objectList’ to name the disposable amorphous variables I used to store track data within the confines a functions scope. other than that my naming conventions are pretty standard and I only used the functions / methods / syntax covered in the python lessons thus far so my code should be highly legible however chunky

instead of listing all instances of ‘REDACTED’ in censoreAll one could just check ( if ‘REDACTED’ in objectLst3[y] ) to the same effect


Did my best to fulfill what I could of the challenge without delving into things I know from experimenting around (I’ve had to play with Regular Expressions quite a bit for some personal projects, though for this project it would feel like I’m not applying what I’m learning).

Some things here I’m lacking on is maintaining the structure of email 4 (I wind up losing some of the \n’s in favor of finding extra words to censor). I wasn’t paying attention fully as I went through the project twice after realizing I was taking some instructions wrong and not fully looking at the output (I had to zoom out the page to see what I was actually doing).

I kept trying to solve the issue of some words showing up as substrings of other words, but gave it up fighting it as the solution I had breaks on other situations (researcher, “she”, etc). I spent a good few hours trying to sort things out as best I could and researching possible solutions but kept coming back to needing regular expressions to do what I wanted to do (and was sorely tempted to start doing, but I’m trying to restrict myself to things I’ve gone through from the course).

Haven’t compared to other people’s code as of yet as I didn’t want it to start influencing what I coded in before I felt like I’d done all I could.

1 Like

Hi everyone.
It took me some time, but I managed to finish this project, or at least, I think so …

I didn’t really know how handle the punctuation for the second and third email. Someone on the forum suggested to look at Regular expressions.
I used the first part of the course (Practical Data Cleaning) and this page from the Python documentation. It’s helped me to handle upper, lower letters too.

I found the last part really tricky (censor the words that come before and after) but it seem’s to work.

Here’s my code :

import re

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()

## Email_One ##

def censor_words(email, words):

  asterisk = []
  while len(asterisk) < len(words):
  asterisk_join = ''.join(asterisk)
  new_email = email.replace(words, asterisk_join)

  return new_email

print(censor_words(email_one, 'learning algorithms'))

## Email_Two ##

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

def censor_lst(email, lst):
  update_email = ''
  i = 0
  for item in lst:
    stars = []
    while len(stars) < len(item):
    stars_join = ''.join(stars)

    if i == 0:
      regex =  "\\b"+ item + "\\b"
      update_email = re.sub(regex, stars_join, email, flags = re.IGNORECASE)

      i += 1
      regex =  "\\b"+ item + "\\b"
      update_email = re.sub(regex, stars_join, update_email, re.IGNORECASE)

  return update_email

print(censor_lst(email_two, proprietary_terms))

## Email_Three ##

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 negative_proprietary_censor(email, lst1, lst2):

  update_email = ''
  i = 0
  k = 0

  for item in lst1:

    stars = []
    while len(stars) < len(item):
    stars_join = ''.join(stars)

    string_item = str(item)
    regex =  "\\b"+ item + "\\b"
    tmp_lst = re.search(regex, email)
    if tmp_lst != None:
      i += 1
    if i >= 2:

  for word in lst1:
    if i >=2 and k == 0 :
      regex = "\\b"+ word + "\\b"
      update_email = re.sub(regex, stars_join, email, flags = re.IGNORECASE)
      k += 1

    elif i >= 2 and k != 0:
      regex = "\\b"+ word + "\\b"
      update_email = re.sub(regex, stars_join, update_email, flags = re.IGNORECASE)

  update_email = censor_lst(update_email, lst2)
  return update_email

print(negative_proprietary_censor(email_three, negative_words,proprietary_terms))

## Email_Four ##

def censor_it_all(email, lst1, lst2):
  censor_email = negative_proprietary_censor(email,lst1,lst2)
  split_email = censor_email.split(' ')
  new_split_email = []
  i = 0
  k = 0
    for word in split_email:

      if k < i:
        k += 1

        tmp_value1 = word.find('*')
        tmp_value2 = word.find('\n')
        if tmp_value1 == -1:
          if split_email[i + 1].find('*') != -1 :
            stars = []
            while len(stars) < len(word):
            stars_join = ''.join(stars)
            i += 1
            k += 1
            i += 1
            k += 1
          if tmp_value2 == -1:
            if split_email[i +1].find('*') == -1 :
              stars = []
              while len(stars) < len(split_email[i + 1]):
              stars_join = ''.join(stars)
              i += 2
              k += 1
              i += 1
              k += 1
            i += 1
            k += 1

  except IndexError:
    new_join_email = ' '.join(new_split_email)
    return new_join_email


For the fourth email, i get this result :

**** *******!

Helena has sealed the entrances and exits to the lab. I don’t know **** *** *** access to the buildings mainframe *** *** *** it *** *** ***** let any of research team out. I’m cut off from the rest of the team here in my office. Helena has locked the doors, but I’ve managed to destroy the camera ** *** ***** see me in here. I don’t think this email will even get out.

This all started when we tried to **** *** ******* for maintenance. ** ******* ** discover that we were unable to access to **** ****************** *** when we tried to override the system manually a circuit blew, knocking Phil unconscious.

Helena ** *******. *** ** completely unpredictable and cannot be allowed to escape this facility. So *** ***'s **** contained because the lab contains all ** *** ********** power, but ********** *** *** mentioned before the lockdown that ** *** ****** ******* ****** billions of connected devices spanning the ***** *** ***** be able to vastly exceed the ********* *** *** here.

It’s been four days now we’ve been trapped in here. I have no idea if anyone else is left alive. If anyone is reading this, cut the power to the whole building. It’s the only way to stop her. ****** *******.


1 Like

This is my first Codecademy project. It looks to me that functions are too big.
I am also having difficult to figure out how to keep the length of censored words (that’s why I changed to "[CENSORED].
Any thought or advices?

How can I stop my “replacements” from reverting/disappearing:

email_two = "she had a personality matrix of sense of self self-preservation and a learning algorithm in her as herself"

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

def multiple_censor(text):
  for text in proprietary_terms:
    email_two_replaced = email_two.replace(text, "censored")


I’ve noticed that everytime I run the function, it will only “censor” the last item in the proprietary terms list. Here it is “herself”

How can I stop my previous replacements from reverting?

there’s no reverting, you’re discarding the result

I see. Is there a way to stop discarding the results? I could only think of appending something to a list. But I’m not sure how to stop the results from being discarded in this case.

Not sure how a list would help. A list is for having many values. You only care about one value.
You’ll have to consider how the things you use behave. What input do they expect, what output do they produce, what do you therefore want to feed into it and where do you therefore put the output you get from it?

Python does as you say. So you’ll likely need to think a bit about what you meant as it is you the programmer who makes sure things line up, python won’t snap anything in place and do “what you meant” without you having thought of it.

1 Like

my brain right now :exploding_head:

1 Like

So you’d have an original string. Make replacements. You’d now have a new string. To the new string, make replacements. Repeat until you’re through with all your replacements. Hand the last result to whoever asked for it.

It’s only discarded because you’re not doing anything with it.

I see, thanks ionatan

Can I ask please, how do we know when to use 1,2 or 3+ variables in a function?

I’ve been writing the functions according to codeacademy but when given no specific instructions I am not sure how many variables I would need to use.

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 + " "
        censored_word = censored_word + "X"
    input_text = input_text.replace(word, censored_word)
  return input_text

Here they have used 2, how do I know to use 2 without them telling me so.

There are like… 6 local variables in that function, maybe you mean parameters in which case you’d need to ask yourself what the input is and how many things that is. You get that by considering what you’re at all doing.