Posted on

# Hamming (coding challenge) Part II

Hamming coding challenge Part I

This article is the second part of Exercism's Hamming coding challenge. Initially I had explained my first solution and the lesson learnt as hinted by Exrecism. This second part focuses more on how I refactored my initial solution as seen in part I.

The refactored code goes like this:

``````class UnequalStrandError < ArgumentError
def initialize(error_message = 'Strands must be of equal length')
super
end
end

class Hamming
def self.compute(first_strand, second_strand)
new(first_strand, second_strand).distance
end

private

def initialize(first_strand, second_strand)
@first_strand = first_strand
@second_strand = second_strand
validate
@distance = nucleotides.count { |n1, n2| n1 != n2 }
end

def nucleotides(first_strand, second_strand)
first_strand.chars.zip(second_strand.chars)
end

public

def validate
raise UnequalStrandError unless first_strand.length == second_strand.length
end
end
``````

From this second iteration you can observed that it is now leaner and readable. However, what did do to make it leaner and readable?
As usual I will start with the `UnequalStrandError` class. In the new code I created a function called `validate`. This will take care of raising errors whenever any error is encountered in the code. Note that I now have a one line code:

`````` raise UnequalStrandError unless first_strand.length == second_strand.length
``````

compared to what I had earlier to help handle raising errors:

`````` raise UnequalStrandError if first_strand.empty? && second_strand.size.positive?
raise UnequalStrandError if first_strand.size.positive? && second_strand.empty?
raise UnequalStrandError if first_strand.size > second_strand.size
raise UnequalStrandError if first_strand.size < second_strand.size
``````

Secondly I refactored `compute` as :

``````  def self.compute(first_strand, second_strand)
new(first_strand, second_strand).distance
end
``````

The compute method in the above is a class method as indicated with the `self` prefix and also in compute body, I instatiated `Hamming` class and called `distance` on it.
The `distance` method is defined in `initialize` method:

``````  def initialize(first_strand, second_strand)
@first_strand = first_strand
@second_strand = second_strand
validate
**@distance = nucleotides.count { |n1, n2| n1 != n2 }**
end
``````

and it is defined as an instance variable which is then exposed using `attr_reader` method.

``````  attr_reader :distance, :first_strand, :second_strand
``````

Note that `@distance` is a variable holding the result derived from `nucleotides.count { |n1, n2| n1 != n2 }`. Also the `nucleotides` method defined in the body of `Hamming` class handles the separation and zipping of `first_strand` and `second_strand`
In the initial code I had used the `split()` method to get an array from the string supplied but I found `chars()` to be effective as well. After creating the array I zipped both `first_strand` and `second_strand` array together. While using the `zip()` method this is what it does:

``````  first_strand = [G,A,G,C]
second_strand = [C,A,T,C]
first_strand.zip(second_strand)
result = [[G,C],[A,A],[G,T],[C,C]]
``````

After zipping I called the `count()` method on the zipped array and this method was able to get a count of items in the sub array that are not the same.

With this refactoring for readability, I learnt about `self`, and what `self` means in the context of this challenge. I understood that when `self` is used in a code, it refers to the class and in this case it is reffering to the class `Hamming`.
I also learnt a new trick: instantiating a class in a class method and calling a defined method in the class on it.

``````  def self.compute(first_strand, second_strand)
new(first_strand, second_strand).distance
end
``````

When `Hamming.compute` is called, the new class instantiation will also call the method involved. This is a quick way of getting results instead of having to create new objects of `class Hamming`.
I also learned that, I can raise Errors in the initialize method to catch the errors thrown as quick as possible.

These are what I learned while solving the hamming coding challenge on Exercism. I will be solving more challenges on Exercism and do watch out for more articles on how I solved and refactored the challenges.