# 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

Is this any help?

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

Harry

The linguistics gem might be what you want.

See dev(E)iate

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’.

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

2. end
end
str
end
end

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

1. 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

1. 1000000 v. 1_000_000

num = num - 10

v.

num -= 10

1. Use spacing or parentheses in your calculations:

tens = num/10*10

v.

tens = num/10 * 10

1. You don’t need to recursively call your function.
2. You can make your if_else decision tree more consistent and
therefore easier to understand:

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

1. Should you even be monkey patching Integer?? You could do the same

1_000_000.to_words

you would write:

to_words(1_000_000)

This:

def hundreds_helper(num)

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

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

can be changed to:

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

And 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_fragments = []
num = self

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

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

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

string_fragments.join(' ')
``````

end