I finished up the problem from yesterday that I couldn’t solve by starting out reviewing the problem one more time, the notes I made from the day before, and starting to fix things. My hunch from yesterday was correct: for the rounding up #ceil
method to work properly, I needed to make sure my numbers were roundable in the first place. They needed to be changed to floats with a little #to_f
method. This was the heart of the problem.
Then I gave myself a new mini-challenge that, of course, ended up taking a lot longer than I thought: rubocop.
First I picked off the “low hanging fruit” and removed the trailing whitespace, etc. I got it down to three “Method has too many lines” offenses. For times’ sake, I decided to just tackle one of these today.
This:
def normalize_ciphertext
word_size = (normalize_plaintext.size / size).ceil
number_of_lines = (normalize_plaintext.size / word_size).ceil
results = []
old_text = ciphertext
number_of_lines.downto(1) do |line|
if line == 1
results.push(old_text)
elsif line > 1
word_size = old_text/number_of_lines if old_text % number_of_lines == 0
results.push(old_text.slice!(0..(word_size - 1)))
end
end
results.join(' ')
end
Became this:
def remove_front_letters(arr, text, word_size)
arr.push(text.slice!(0..(word_size - 1)))
end
def create_words_array(word_size, number_of_lines)
arr = []
text = ciphertext
number_of_lines.downto(1) do |line|
word_size = text.size / line if text.size % line == 0
line == 1 ? arr.push(text) : remove_front_letters(arr, text, word_size)
end
arr
end
def normalize_ciphertext
word_size = (normalize_plaintext.size.to_f / size).ceil
number_of_lines = (normalize_plaintext.size.to_f / word_size).ceil
create_words_array(word_size, number_of_lines).join(' ')
end
Still not perfect, but at least Rubocop likes it. It is still a little too much happening in every method. It would be better to pull out more lines of code and make new helper methods, like calculate_word_size, perhaps. Gosh darn it, might as well try it:
def remove_front_letters(arr, text, word_size)
arr.push(text.slice!(0..(word_size - 1)))
end
def calculate_word_size
(normalize_plaintext.size.to_f / size).ceil
end
def calculate_number_of_lines(word_size)
(normalize_plaintext.size.to_f / word_size).ceil
end
def create_words_array
arr = []
text = ciphertext
word_size = calculate_word_size
number_of_lines = calculate_number_of_lines(word_size)
number_of_lines.downto(1) do |line|
word_size = text.size / line if text.size % line == 0
line == 1 ? arr.push(text) : remove_front_letters(arr, text, word_size)
end
arr
end
def normalize_ciphertext
create_words_array.join(' ')
end