Categories

# 30 Days of Code #4

In which I give my brain a break and the solution appears like magic. Plus a rubocop-based refactor.

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``````