Hamming (coding challenge) Part II
Tags: hamming, ruby, exercism
Published: 2022-11-29 12:57:14

---
title: Hamming (coding challenge) Part II
published: true
description: 
tags: Hamming, ruby, exercism
# Use a ratio of 100:42 for best results.
# published_at: 2022-11-29 08:46 +0000
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7stlbcnpswak4ynjifgw.jpg
---

[Hamming coding challenge Part I](https://dev.to/tundeiness/hamming-coding-challenge-part-i-4499)

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](https://dev.to/tundeiness/hamming-coding-challenge-part-i-4499).

The refactored code goes like this:

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

  attr_reader :distance, :first_strand, :second_strand

  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:

```rb
 raise UnequalStrandError unless first_strand.length == second_strand.length
```
compared to what I had earlier to help handle raising errors:

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

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

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

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

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

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