Integers to English Words

Hi,

I'm a junior software engineer who has been blessed with the gift of
Ruby as my introductory language. However, I'm a little anxious about a
coding test I have been asked to do....convert numbers to english words.
My solution is below which I was pretty pleased with...but I have to
present it and explain what it is that I could have done better. I was
hoping some of you could take a look and offer your opinions?

$hash = Hash[1 => "one", 2 => "two", 3=> "three", 4 => "four", 5 =>
"five", 6 => "six", 7 => "seven", 8 => "eight", 9 => "nine", 10 =>
"ten", 11 => "eleven", 12 => "twelve" , 13 => "thirteen", 14 =>
"fourteen", 15 => "fifteen", 16 => "sixteen", 17 => "seventeen", 18 =>
"eighteen", 19 => "nineteen", 20 => "twenty", 30=> "thirty", 40
=>"forty", 50 => "fifty", 60 => "sixty", 70 => "seventy", 80 =>"eighty",
90 => "ninety", 100 => "hundred", 1000 => "thousand"]

class Integer
  def to_words
    str = ""
    num = self

    if num >= 1000000
      millions = num/1000000
      str += millions.to_words + " million"
      str += " "
      num = num - millions*1000000
    end

    if num >= 1000
      thousands = num/1000
      str += thousands.to_words + " thousand "
      num = num - thousands*1000
    end

    if num >= 100
      hundreds = num/100
      str += $hash[hundreds] + " hundred"
      if (num-hundreds*100) > 0
        str += " and "
      end
      num = num - hundreds*100
    end

    if num > 0
      if num <= 19
        str += $hash[num]
      else
        tenths = num
        num = num / 10
        if num > 0
          str += $hash[num*10] + " "
        end
        if (tenths-num*10) > 0
          str += $hash[tenths-num*10]
        end
      end
    end
    str
  end
end

decode = nil
  puts "Enter 'decode x' replacing x with an integer between 1 and
999999999. Simply type 0 to finish:"
  decode = gets.gsub(/[a-zA-Z]+\s/, '').to_i
  puts decode.to_words

while (1..999999999).include?(decode)
  puts "Enter 'decode x' replacing x with an integer between 1 and
999999999. Simply type 0 to finish:"
  decode = gets.gsub(/[a-zA-Z]+\s/, '').to_i
  puts decode.to_words
end

···

--
Posted via http://www.ruby-forum.com/.

Is this any help?

http://www.rubyquiz.com/quiz25.html

Harry

The linguistics gem might be what you want.

See http://deveiate.org/projects/Linguistics/wiki/English

1) $hash
Never use global variables. Instead, you can make that a constant
inside Integer.

3)
      end
    end
    str
  end
end

str is hidden in your ends. You need to insert some blank lines in
there.

4) You recursively call your to_words() method, which accomplishes
nothing.

5) The 'and' in the final result is improper.

nine hundred and fifty two million one hundred thousand fifty two

v.

nine hundred and fifty two million and one hundred thousand and fifty
two

v.

nine hundred fifty two million one hundred thousand fifty two

6) 1000000 v. 1_000_000

7) num = num - .... v. num -= ....

8) Use spacing or parentheses in your calculations:

tens = num/10*10

v.

tens = num/10 * 10

9) You don't need to recursively call your function.
10) You can make your decision tree more consistent.

class Integer
  NUMBER_TO_WORD = Hash[
    1 => "one",
    2 => "two",
    3 => "three",
    4 => "four",
    5 => "five",
    6 => "six",
    7 => "seven",
    8 => "eight",
    9 => "nine",
    10 =>"ten",
    11 => "eleven",
    12 => "twelve" ,
    13 => "thirteen",
    14 => "fourteen",
    15 => "fifteen",
    16 => "sixteen",
    17 => "seventeen",
    18 => "eighteen",
    19 => "nineteen",
    20 => "twenty",
    30 => "thirty",
    40 =>"forty",
    50 => "fifty",
    60 => "sixty",
    70 => "seventy",
    80 =>"eighty",
    90 => "ninety",
    100 => "hundred",
    1000 => "thousand",
  ]

  def hundreds_helper(num)
    string_fragments = []

    if num >= 100
      hundreds = num/100
      string_fragments << "%s hundred" % NUMBER_TO_WORD[hundreds]
      num -= hundreds*100
    end

    if num >= 20
      tens = num/10 * 10
      string_fragments << NUMBER_TO_WORD[tens]
      num -= tens
    end

    if num >= 11
      string_fragments << NUMBER_TO_WORD[num]
      num = 0
    end

    if num > 0
      string_fragments << NUMBER_TO_WORD[num]
    end

    string_fragments.join(' ');

  end

  def to_words
    string_fragment= []
    num = self

    if num >= 1_000_000
      millions = num/1_000_000
      string_fragment << "%s million" % hundreds_helper(millions)
      num -= millions*1_000_000
    end

    if num >= 1_000
      thousands = num/1_000
      string_fragment << "%s thousand" % hundreds_helper(thousands)
      num -= thousands*1_000
    end

    string_fragment << hundreds_helper(num)
    string_fragment.join(' ')

  end
end

···

--
Posted via http://www.ruby-forum.com/.

This:

def to_words
    string_fragment= []
    num = self

    if num >= 1_000_000
      millions = num/1_000_000
      string_fragment << "%s million" % hundreds_helper(millions)
      num -= millions*1_000_000
    end

    if num >= 1_000
      thousands = num/1_000
      string_fragment << "%s thousand" % hundreds_helper(thousands)
      num -= thousands*1_000
    end

    string_fragment << hundreds_helper(num)
    string_fragment.join(' ')

  end

can be changed to:

def to_words
    string_fragment= []
    num = self

    if num >= 1_000_000
      millions = num/1_000_000
      string_fragment << "%s million" % hundreds_helper(millions)
      num -= millions*1_000_000
    end

    if num >= 1_000
      thousands = num/1_000
      string_fragment << "%s thousand" % hundreds_helper(thousands)
      num -= thousands*1_000
    end

    if num > 0
      string_fragment << hundreds_helper(num)
    end

    string_fragment.join(' ')

  end

···

--
Posted via http://www.ruby-forum.com/.

Thanks Harry, that's exactly the type of alternative (and write up) I
was after.

I should have said Peter, that no external libraries were allowed; it is
purely a test to see how I would tackle the 'problem'.

···

--
Posted via http://www.ruby-forum.com/.