Transform numbers into written words

This is the solution I came up from a code challenge.

require 'test/unit'

class EnglishNumber
  def initialize(number)
    raise ArgumentError, 'Only numbers expected.' unless validate_argument(number)

    @number = number
    @written_numbers_list = written_numbers_list
  end

  def in_english
    return "minus-#{@written_numbers_list[formatted_number]}" if @number < 0
    @written_numbers_list[formatted_number]
  end

  private

    def formatted_number
      @number.floor.abs
    end

    def written_numbers_list
      written_numbers_list = numbers_initilizer
      tens.each do |ten|
        written_numbers_list << ten
        (1..9).each {|i| written_numbers_list << "#{ten}-#{written_numbers_list[i]}" }
      end
      written_numbers_list
    end

    def numbers_initilizer
      %w(
        zero one two three four five six seven eight nine ten eleven twelve
        thirteen fourteen fifteen sixteen seventeen eighteen nineteen
        )
    end

    def tens
      %w(twenty thirty forty fifty sixty seventy eighty ninety)
    end

    def validate_argument(number)
      number.is_a? Numeric
    end
end

class EnglishNumberTest < Test::Unit::TestCase
  test 'zero returns zero' do
    assert_equal EnglishNumber.new(0).in_english, 'zero'
  end

  test 'minus than one and greater than zero is zero' do
    assert_equal EnglishNumber.new(0.4).in_english, 'zero'
  end

  test 'minus than zero and greater than minus one is minus one' do
    assert_equal EnglishNumber.new(-0.1).in_english, 'minus-one'
  end

  test 'returns right results for positive integers' do
    assert_equal EnglishNumber.new(25).in_english, 'twenty-five'
  end

  test 'returns right results for negative integers' do
    assert_equal EnglishNumber.new(-33).in_english, 'minus-thirty-three'
  end

  test 'returns right results for positive floats' do
    assert_equal EnglishNumber.new(7.7).in_english, 'seven'
  end

  test 'returns right results for negative floats' do
    assert_equal EnglishNumber.new(-69.7).in_english, 'minus-seventy'
  end

  test 'reject anything that is not a float or integer' do
    exception = assert_raise(ArgumentError) { EnglishNumber.new('Hello!') }
    assert_equal('Only numbers expected.', exception.message)
  end
end
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s