patternrubyMinor
Putting numbers into words
Viewed 0 times
intonumberswordsputting
Problem
I have some embarrassingly long code which puts into words any number up into the trillions. As a newbie, and understanding that shorter, non-repetitive code is best, I am looking for suggestions on how to reduce this code to a respectable quantity. I realize that there is a lot of repetition in it. However, depending on the number being evaluated, the math looks a little different with each rep, so I am not sure if I can reduce that. I have tried rewriting it solely as an if/else (without the recursion) but it quickly becomes just as bad if not worse.
```
class :: Fixnum
def in_words(number)
if number 999999999999
if write 9) && (write 19) && (write 19,000,000 - 999,000,000
millions = in_words(write)
numString = numString + millions + ' trillion'
end
if left > 0
numString = numString + ' '
end
#-----------------------------------------billions
#left = number
write = left/1000000000
left = left - (write*1000000000)
if number > 999999999
if write 9) && (write 19) && (write 19,000,000 - 999,000,000
millions = in_words(write)
numString = numString + millions + ' billion'
end
if left > 0
numString = numString + ' '
end
# ----------------------------------------millions
write = left/1000000
left = left - (write*1000000)
if number > 999999
if write 9) && (write 19) && (write 19,000,000 - 999,000,000
millions = in_words(write)
numString = numString + millions + ' million'
end
if left > 0
numString = numString + ' '
end
#-----------------------------------------thousands
write = left/1000
left = left - (write*1000)
if number > 999
if write 9) && (write 19) && (write 19,000 - 999,000
thousands = in_words(write)
numString = numString + thousands + ' thousand'
end
if left > 0
numString = numString + ' '
end
end
```
class :: Fixnum
def in_words(number)
if number 999999999999
if write 9) && (write 19) && (write 19,000,000 - 999,000,000
millions = in_words(write)
numString = numString + millions + ' trillion'
end
if left > 0
numString = numString + ' '
end
#-----------------------------------------billions
#left = number
write = left/1000000000
left = left - (write*1000000000)
if number > 999999999
if write 9) && (write 19) && (write 19,000,000 - 999,000,000
millions = in_words(write)
numString = numString + millions + ' billion'
end
if left > 0
numString = numString + ' '
end
# ----------------------------------------millions
write = left/1000000
left = left - (write*1000000)
if number > 999999
if write 9) && (write 19) && (write 19,000,000 - 999,000,000
millions = in_words(write)
numString = numString + millions + ' million'
end
if left > 0
numString = numString + ' '
end
#-----------------------------------------thousands
write = left/1000
left = left - (write*1000)
if number > 999
if write 9) && (write 19) && (write 19,000 - 999,000
thousands = in_words(write)
numString = numString + thousands + ' thousand'
end
if left > 0
numString = numString + ' '
end
end
Solution
Rather than rewrite your whole solution, I'll point out more idiomatic ways to do this stuff in Ruby.
Recursion
You don't need an argument to do recursion,
String Arrays
Long Numbers
For powers of 10, you can also use exponentiation
Modulus
Assignment Shortcut
Recursion
You don't need an argument to do recursion,
self is enough.class ::Fixnum
def in_words
# ...
millions = write.in_words
# ...
end
endString Arrays
%w{} is handy for making arrays containing one-word stringsones_place = %{one two three four five six seven eight nine}Long Numbers
_ can be used like a comma (or period, if you're European) in long numbers.billion = 1_000_000_000For powers of 10, you can also use exponentiation
trillion = 10 ** 12Modulus
% gets the remainder of a number after dividing.write = left / 10 ** 9
left = left % 10 ** 9Assignment Shortcut
x = x y can be written as x = y where ` is any operator.
numString += ' '
left %= 10 ** 9
Loops
Once you incorporate all of those, you should be able to see how that huge nested if` can be turned into a tiny[12, 9, 6, 3].each do |power|
break if self < 10 ** power
# ...
endCode Snippets
class ::Fixnum
def in_words
# ...
millions = write.in_words
# ...
end
endones_place = %{one two three four five six seven eight nine}billion = 1_000_000_000trillion = 10 ** 12write = left / 10 ** 9
left = left % 10 ** 9Context
StackExchange Code Review Q#85010, answer score: 4
Revisions (0)
No revisions yet.