Learn Python 2 - Censor

Hi there,

I believe I have a correct solution to this problem - however, the automated check keeps failing me on this exercise.

https://www.codecademy.com/courses/learn-python/lessons/practice-makes-perfect/exercises/censor

My solution is…

def censor(text, word):
  txtsplt = text.split(' ')
  s = " "
  i = 0
  while i <= len(txtsplt) - 1:
    if txtsplt[i] == word:
      txtsplt[i] = "*" * len(txtsplt)
    i += 1
  txtsplt = s.join(txtsplt)
  return txtsplt

When I print txtsplt instead of return it, I am getting expected results, and they seem to align with what Codecademy says as the correct answers. I’m not totally sure what I’m doing wrong.

Any thoughts would be greatly appreciated… thanks!

Please post the error message the SCT is reporting.

Should that be, len(word)?

Aside

When working with indices, a for loop is probably the way to go since it is simpler to manage.

3 Likes

Sorry about that! Here is the error:

Your function fails on censor(“hey hey hey”,”hey”). It returns “None” when it should return “ *** *** ***”.

However - what I get returned is different than what codecademy is telling me:

the password is ****
*** *** ***

With your suggestion, however, I passed.

2 Likes

Extra Study – enumerate()

Enumeration is the act of creating a special object that consists of index - value pairs. A list of tuples is what it generates.

>>> print list((enumerate([5, 8, 13, 21, 34, 55])))
[(0, 5), (1, 8), (2, 13), (3, 21), (4, 34), (5, 55)]
>>> 

We don’t need the list, just the object. It allows us to iterate it for both index and value, which is pretty handy in this problem and many others you will encounter going forward. When we want both the index and the value, it is worth the investment.

>>> def censor_(text, word):
	t = text.split()
	r = range(len(t))
	s = '*' * len(word)
	for i, x in enumerate(t):
		if x == word:
			t[i] = s
	return ' '.join(t)

>>> censor_('hey hey hey','hey')
'*** *** ***'
>>> censor_('text text text text', 'text')
'**** **** **** ****'
>>> censor_('the password is 12345','12345')
'the password is *****'

I’m a big fan of simple symbols. The first three lines of the function contain all the clutter, and they are all self-described. We don’t need bulky names for these transient variables, imho.

By the time we get to the loop we know what everything is, and the rest is just mechanics. The space character is only in the return statement and nowhere else in the code so I opted for using the literal in the expression.

3 Likes

Extra, extra study - list comprehension:
Write the function body in a single line of code, returning the ' '.join()-ed list comprehension.

List Comprehension
def censor(text, word):
  return ' '.join ([w if w != word else "*" * len(w) for w in text.split(' ')])
4 Likes