6/6 Extra step for fun (multiple redacts)


#1

Below is my code. I want it to replace the words with AWESOME for multiple redacts, but can't get it to work. Any solutions?

puts "Enter a sentence."
text = gets.chomp
text.downcase!

puts "Which word would you like to redact?"
redact1 = gets.chomp
text.downcase!

puts "Choose another word to redact?"
redact2 = gets.chomp
text.downcase!

words = text.split(" ")

words.each do |x, y|
    if x == redact1  && y == redact2
        print "AWESOME "
    else
        print x + " "
    end
end

#2

Your problem is probably in your condition:

if x == redact1  && y == redact2

You want to redact when x is equal to redact1 OR equal to redact2. Not equal to both of them at the same time.


#3

Thank you. They both must be true in order to print AWESOME. That's why I used &&.


#4

Actually, there's another problem here.

Your words variable is an array, not a hash, so you need only one variable in your each loop. You don't need the y variable, you should get rid of it.

As for your condition, no, x needs to be true with only one of these. Either it's equal to redact1 or either it's equal to redact2 (and if redact1 and redact2 are the same words then it's fine as well).


#5

Excellent point. Thanks.


#6

This code asks user to enter a sentence and redact with two other sentences. If redact1 or redact2 is same as user's sentence, puts AWESOME, else "There is nothing awesome here".

puts "Enter a sentence."
text = gets.chomp
text.downcase!

puts "Which word would you like to redact?"
redact1 = gets.chomp
redact1.downcase!

puts "Choose another word to redact?"
redact2 = gets.chomp
redact2.downcase!

words = text.split(" ")

if text == redact1 || text == redact2
puts "AWESOME!!"
else
puts "There is nothing awesome here! "
end

words.each do |x|
print x + " "
end


#7

Hi everyone.

I have been having fun with this exercise and I would like to share some tips. In the code posted above we can see that the 'multiple redacts' challenge has been met imperatively. That means they have made code which requires updating for each additional word we want to redact. If we wanted to redact 4 unique words, the code would grow 4 times in size.

How can we solve this problem without having to add additional code?

If we think declaratively (as opposed to imperatively) we truly can redact an unlimited number of words without actually adding any extra code. If you look at how the initial sentence is read & split up, we can see already that the code is capable of handling a sentence of infinite length. So intuition would say that if we did the same to the redaction input, we could get the same result. Super cool!

Ok, enough blabbing on -- show me the code!!!!

found= FALSE
print "Good Words:"
text= gets.chomp
print "Bad Words:"
redact= gets.chomp

good_words= text.split(" ")
bad_words= redact.split(" ")

good_words.each do |good_word|
bad_words.each do |bad_word|
if good_word.downcase == bad_word.downcase
print "REDACTED "
found= TRUE
end
end
print good_word + " " unless found
found= FALSE
end

I tried to use descriptive variable names so you can follow along easily. The key here (which may look confusing) is that for every good word, we are comparing it to ALL bad words. so for each 1 loop of a good word, we make X number of loops over bad words. Where X = the number of bad words in your array. If at any point during the bad_word iterations we find a match, we output REDACTED and set found = TRUE so that we do not output this word to the user. If no matches are found, then we do the opposite.

Happy to answer any questions if you have them. Have fun!

p.s this code can also handle any capitalization differences, so JUSTIN will match as redacted against JuStIn. This is because I take whatever the user provides and when checking for a match, temporarily convert both to be downcase.

If you do not want to check for downcase you can greatly simplify the code:

puts "Sentance:"
text= gets.chomp
puts "Bad Word:"
redact= gets.chomp

good_words= text.split(" ")
bad_words= redact.split(" ")

good_words.each do |good_word|
if bad_words.include?(good_word)
print "REDACTED "
else
print good_word + " "
end
end


#9

Here's how I did it:

#Asks the user for text
puts "Enter text"
text = gets.chomp
text.downcase!

#Word to redact number 1
puts "Enter word to remove"
redact_1 = gets.chomp
redact_1.downcase!

#Word to redact number 2
puts "Enter a new word to remove"
redact_2 = gets.chomp
redact_2.downcase!

words = text.split(" ")

#Create a new string which is empty
new_word = ""

#Add x or REDACTED to the string new_word
words.each do |x|
    if x == redact_1 || x == redact_2
        new_word << "REDACTED "
    else
        new_word << x + " "
    end
end

#Puts the new_word to check if it works
puts new_word

Question: how can we keep asking the user for more words to redact until they no longer want to add a word?


#10

The easiest way is to ask them to provide as many words as they like separated by a space, then you split this input and you use it as an array of words.

Another solution less user-friendly is to ask after each input a yes/no question to know if he wants to add a new word, and after each answer (to the REDACT question) you store the string in an array.


#11

Hi my name is Laura, I'm new to coding and your suggestions were all very useful.
Here's my code:

puts "enter text please"
text=gets.chomp
text.upcase!

puts "which word would you like to replace?"
redact1=gets.chomp
redact1.upcase!

puts "you may choose a second word"
redact2=gets.chomp
redact2.upcase!

words=text.split (" ")
if text==redact1 || redact2 # on this line was the essential change
puts "success "
else
puts "fail "
end
words.each do |x|
print x+" "
end

Thank you :smile:


#12

Could you please expand your explanation on the found= true and found=false parts of your code? what exactly is their function?

thanks!
-L


#13

Hi everyone!

Is it possible to assign an input array to a global redact variable instead of setting up multiple redact variables for each word.
What if I want a more than two words redacted?
What if I want to redact a sequence of words?

Just wondering if there's a more efficient way?

Cheers!


#14

I'm very new to coding and all the responses helped! Here's what I used. @mikeev85: it handles multiple words, but I don't know how to do the sequence or words. I'm still trying to figure out how to deal with punctuation. For example, if I wanted to redact "rooftop" from the sentence "Meet me on the rooftop.", it won't because there is a period attached to "rooftop". A user wouldn't know how to input that, so how would I get rid of it?

Anyhow, my code:

puts "Enter text:"
text = gets.chomp
text = text.downcase

puts "Which words are secret? (No commas please, 007.)"
redact = gets.chomp
redact = redact.downcase

words = text.split(" ")
secrets = redact.split(" ")

words.each do |word|
if secrets.include? word
print "REDACTED "
else
print word + " "
end
end


#15

Wow you showed me the kind of perspective I'm hoping to develop by learning to code so thank you for that!
Also thanks to you explanation I understand theory behind the exercise much more clearly, however there a few lines of for which I don't understand their purpose in you code. Could you explain why you needed to add the:

found= FALSE
&
print good_word + " " unless found
found= FALSE

I don't think I get what exactly this is saying


#16
puts "Insert a text"
text = gets.chomp
text.downcase!

puts "Insert words to be redacted"
redact = gets.chomp
redact.downcase!

words = text.split (" ")
words_redact = redact.split (" ")

words.each do |word|
    if words_redact.include? word
    print "REDACTED "
    else
    print word + " "
    end
end

i've come with this solution for multiples entry, but it still has some problemas, like punctuation.


#17

That looks nice. I was going off on a tangent with mine...and it still breaks because it stops checking after the redact list ends. Thanks for doing it right.

puts "Enter something"
text = gets.chomp
puts "What do you want to redact?"
redact = gets.chomp

final_sent = []
text_index = 0
redact_index = 0

words=text.split(" ")
redactor = redact.split(" ")

while (text_index < words.length && redact_index < redactor.length)
if redactor[redact_index] == words[text_index]
final_sent << "REDACT"
text_index += 1
redact_index +=1
elsif redactor[redact_index] != words[text_index]
final_sent << words[text_index]
text_index +=1
#elsif redactor[redact_index] == nil
# final_sent << words[text_index]
else
redact_index +=1
end
end
puts final_sent


#18

first off, congrats for coming up with a clean solution. That said, what you need down here in order to solve your punctuation problem is that you must strip all text off the punctuation marks including the full stop .i.e "." as well as other punctuation.marks such as ".,-\/#!$%\^&*;:{}=-_`~()"
lucky for us, we can accomplish that just by making use of .gsub() that we learned up earlier and a bit of regex so our new and improved code becomes:

puts "Enter text:"
text = gets.chomp.gsub!(/[.,-\/#!$%\^&*;:{}=-_`~()]/,"") # to fix the punctuation
text = text.downcase

puts "Which words are secret? (No commas please, 007.)"
redact = gets.chomp
redact = redact.downcase

words = text.split(" ")
secrets = redact.split(" ")

words.each do |word|
if secrets.include? word
print "REDACTED "
else
print word + " "
end
end

and here is the outupt:

IMPORTANT:

for some reasons copying the whole .gsub!() line and then pasting it in the workplace doesn't work and returns error. you must manually write the said line for the code to work correctly.


What does this excercise do and what is a Redact?
#19

Please tell me what I'm doing wrong...
Since I couldn't get anyting to work without giving me a warning that I was doing someting wrong even when it worked properly OR it was telling me Good Job when it was wrong I tried to copy some code from here. I copied the above code from coremaster77739 with some adjustments just to get it to work.
This is my final code (Iknow it isn't exactly what is above but that is because that didn't work)

puts "what are you looking for?"
text = gets.chomp
text = text.downcase.gsub!(/.?,\';:/,"") # to account for punctuation

text = text.downcase - this is # because it wasn't recognized nil:nilcase

puts " what do you want to redact?"
redact = gets.chomp
redact.downcase

words = text.split(" ") - this is #'d as undefined

redacted = redact.split(" ")

words.each do |word|
if redacted.include? word
print "REDACTED "
else
print word + " "
end
end

This is the output to which I received a "Way To Go start next Lesson"

what are you looking for?
.gsub!(/.?,\';:/,"") # to account for punctuation
what do you want to redact?
# account for
the meaning of life, the universe, and everything ["the", "meaning", "of", "life,", "the", "universe,", "and", "everything"]

Please explain tis to me...


#20

hi there, I'm sorry I could not quite get what you are really trying to say here? is there some typo in the output that you have posted? also can you try manually writing my above code into the console and see if that works? ( I know it's pretty long thing to ask). in my experience, copying and pasting the whole code results in stupid #nill class errors, however if you manually write down the all code, it works with no errors whatsoever. hope it helps!


#21

I started all over. I have no idea why it would save old text once new text has been entered. I have not encountered that before. anyway, Once I started from scratch I finally got it to work... Finicky little system here...