numbers_in_words 0.0.7 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
data/Manifest CHANGED
@@ -1,11 +1,14 @@
1
1
  Manifest
2
+ README
2
3
  Rakefile
3
4
  examples/display_numbers_in_words.rb
4
5
  index_cyclo.html
6
+ init.rb
7
+ lib/numbers.rb
5
8
  lib/numbers_in_words.rb
6
9
  lib/numbers_in_words.rb_cyclo.html
7
- lib/words_in_numbers.rb
10
+ lib/words.rb
8
11
  lib/words_in_numbers.rb_cyclo.html
9
- numbers_in_words.rb
12
+ numbers_in_words.gemspec
10
13
  spec/numbers_in_words_spec.rb
11
14
  spec/words_in_numbers_spec.rb
data/README ADDED
@@ -0,0 +1,70 @@
1
+ Installation
2
+ ============
3
+
4
+
5
+ gem install numbers_in_words
6
+
7
+ or
8
+
9
+ sudo gem install numbers_in_words
10
+
11
+
12
+
13
+ The file numbers_to_words defines a module NumbersToWords which is included in Fixnum and Bignum.
14
+ The in_words method can then be used on any Fixnum or Bignum object.
15
+
16
+ E.g.
17
+ >require 'numbers_in_words'
18
+ >112.in_words
19
+ #=> one hundred and twelve
20
+
21
+ To try it out the program display_numbers_to_words.rb expects two integer parameters to define a
22
+ range. It then prints out all numbers in words included in this range.
23
+
24
+ e.g.
25
+
26
+ >ruby display_numbers_to_words.rb 1 11
27
+ one
28
+ two
29
+ three
30
+ four
31
+ five
32
+ six
33
+ seven
34
+ eight
35
+ nine
36
+ ten
37
+ eleven
38
+
39
+ Whilst creating this project I realized that in English:
40
+
41
+ * Numbers are grouped in groups of threes
42
+ * Numbers less than 1,000 are grouped by hundreds and then by tens
43
+ * There are specific rules for when we put an "and" in between numbers
44
+
45
+ It makes sense to manage the numbers by these groups, so
46
+ I created a method groups_of which will split any integer into
47
+ groups of a certain size. It returns a hash with the power of ten
48
+ as the key and the multiplier as the value. E.g:
49
+
50
+ > 31245.groups_of(3)
51
+ #=>
52
+ {0=>245,3=>31} #i.e. 31 thousands, and 245 ones
53
+
54
+ > 245.group_of(2)
55
+ #=>
56
+ {0=>45,2=>2} #i.e. 2 hundreds, and 45 ones
57
+
58
+ I also created a method group_words takes a block and a size parameter
59
+ This method which could be used by different languages.
60
+ (In Japanese numbers are grouped in groups of 4, so it makes sense to try and
61
+ separate the language related stuff from the number grouping related stuff)
62
+
63
+ Example of usage:
64
+ 245.group_words(2,"English") do |power, name, digits|
65
+ puts "#{digits}*10^#{power} #{digits} #{name}s"
66
+ end
67
+
68
+ 2*10^2= 2 hundreds
69
+ 45*10^0 = 45 ones
70
+
data/Rakefile CHANGED
@@ -1,8 +1,9 @@
1
1
  require 'rubygems'
2
2
  require 'rake'
3
3
  require 'echoe'
4
- Echoe.new('numbers_in_words','0.0.7') do |e|
5
- e.description = ""
4
+ Echoe.new('numbers_in_words','0.0.9') do |e|
5
+ e.description = "#in_words method for integers and #in_numbers for strings"
6
+ e.summary = "Example: 123.in_words #=> \"one hundred and twenty three\", \"seventy-five\".in_numbers #=> 75"
6
7
  e.url = "http://rubygems.org/gems/numbers_in_words"
7
8
  e.author = "Mark Burns"
8
9
  e.email = "markthedeveloper@googlemail.com"
File without changes
@@ -0,0 +1,208 @@
1
+ require 'rubygems'
2
+ require 'active_support'
3
+ module NumbersInWords
4
+
5
+ #handle exceptions to normal numbers
6
+ EXCEPTIONS = {10=> "ten", 11=>"eleven", 12 => "twelve", 13 => "thirteen",
7
+ 14=>"fourteen", 15=>"fifteen", 16=>"sixteen" ,
8
+ 17=> "seventeen", 18=> "eighteen", 19=> "nineteen",
9
+ 20 => "twenty", 30=>"thirty",
10
+ 40=>"forty", 50=>"fifty", 60 => "sixty", 70=> "seventy", 80=>"eighty",
11
+ 90 => "ninety"}
12
+
13
+ DIGITS= %w[zero one two three four five six seven eight nine]
14
+ POWERS_OF_TEN ={0=>"one", 1 => "ten", 2=> "hundred",
15
+ 3 => "thousand", 6=>"million",
16
+ 9=>"billion",
17
+ 12=>"trillion",
18
+ 15=>"quadrillion",
19
+ 18=>"quintillion",
20
+ 21=>"sextillion",
21
+ 24=>"septillion",
22
+ 27=>"octillion",
23
+ 30=>"nonillion",
24
+ 33=>"decillion",
25
+ 36=>"undecillion",
26
+ 39=>"duodecillion",
27
+ 42=>"tredecillion",
28
+ 45=>"quattuordecillion",
29
+ 48=>"quindecillion",
30
+ 51=>"sexdecillion",
31
+ 54=>"septendecillion",
32
+ 57=>"octodecillion",
33
+ 60=>"novemdecillion",
34
+ 63=>"vigintillion",
35
+ 66=>"unvigintillion",
36
+ 69=>"duovigintillion",
37
+ 72=>"trevigintillion",
38
+ 75=>"quattuorvigintillion",
39
+ 78=>"quinvigintillion",
40
+ 81=>"sexvigintillion",
41
+ 84=>"septenvigintillion",
42
+ 87=>"octovigintillion",
43
+ 90=>"novemvigintillion",
44
+ 93=>"trigintillion",
45
+ 96=>"untrigintillion",
46
+ 99=>"duotrigintillion",
47
+ 100 => "googol"
48
+ }
49
+ LENGTH_OF_GOOGOL = 101 #length of the string i.e. one with 100 zeros
50
+
51
+ def initialize
52
+ power = 9
53
+ POWERS_OF_TEN_NAMES.each do |name|
54
+ POWERS_OF_TEN[power]=name
55
+ power += 3
56
+ end
57
+ end
58
+
59
+ #returns a hash with powers of ten and their multipliers
60
+ def powers_of_ten
61
+ i = self.to_i
62
+ digits=i.to_s.split ""
63
+ #turn back into integers
64
+ digits.map! { |x| x.to_i}
65
+
66
+ digits.reverse!
67
+ #create a hash where the key is the
68
+ #power of ten and the value is the multipler
69
+ power = 0
70
+ return digits.inject({}) do |result,digit|
71
+ result[power]=digit unless digit==0
72
+ power+=1
73
+ result
74
+ end
75
+ end
76
+
77
+ def groups_of size
78
+ i=self.to_i
79
+ #split into groups this gives us 1234567 => 123 456 7
80
+ #so we need to reverse first
81
+ #in stages
82
+ #i.e. 1234567 => 7654321
83
+ groups = i.to_s.reverse
84
+ #7654321 => 765 432 1
85
+ groups = groups.split("").in_groups_of(size)
86
+ #765 432 1 => 1 432 765
87
+ groups.reverse!
88
+ #1 432 765 => 1 234 567
89
+ groups.map! {|group| group.reverse}
90
+
91
+ #turn back into integers
92
+ groups.map! {|group| group.join("").to_i }
93
+ groups.reverse! # put in ascending order of power of ten
94
+
95
+ #output hash where key is the power of ten
96
+ #and value if the multiplier
97
+ power = 0
98
+ return groups.inject({}) do |output, digits|
99
+ output[power]=digits
100
+ power+=size
101
+ output
102
+ end
103
+
104
+ end
105
+
106
+ def group_words size, language="English"
107
+ #1000 and over Numbers are split into groups of three
108
+ number = self.to_i
109
+ groups = number.groups_of(size)
110
+ powers = groups.keys.sort.reverse #put in descending order
111
+ powers.each do |power|
112
+ name = POWERS_OF_TEN[power] if language=="English"
113
+ digits = groups[power]
114
+ yield power, name, digits
115
+ end
116
+
117
+ end
118
+
119
+ def english_group group_size
120
+ number = self.to_i
121
+ output = ""
122
+ number.group_words(group_size) do |power, name, digits|
123
+ if digits > 0
124
+ prefix = " "
125
+ #no 'and' between thousands and hundreds
126
+ prefix << "and " if power == 0 and digits < 100
127
+ output << prefix + digits.in_english
128
+ output << prefix + name unless power == 0
129
+ end
130
+ end
131
+ return output
132
+ end
133
+
134
+ def split_googols
135
+ number = self.to_i
136
+ output = ""
137
+ googols = number.to_s[0..(-LENGTH_OF_GOOGOL)].to_i
138
+ remainder = number.to_s[1-LENGTH_OF_GOOGOL .. -1].to_i
139
+ output << " " + googols.in_words + " googol"
140
+ if remainder > 0
141
+ prefix = " "
142
+ prefix << "and " if remainder < 100
143
+ output << prefix + remainder.in_english
144
+ end
145
+ return output
146
+ end
147
+
148
+ def in_googols
149
+
150
+ number = self.to_i
151
+ output = ""
152
+ output << " " + number.to_s[0..0].to_i.in_english + " googol"
153
+ remainder = number.to_s[1..-1].to_i
154
+ prefix = " "
155
+ prefix << "and " if remainder < 100
156
+ output << prefix + remainder.in_english if remainder > 0
157
+
158
+ return output
159
+ end
160
+
161
+ def in_english
162
+ number = self.to_i # make a copy
163
+ #handle negative numbers
164
+ if number < 0
165
+ return "minus " + (-number).in_english
166
+ end
167
+ #handle 0-10
168
+ return DIGITS[number] if number < 10
169
+ return EXCEPTIONS[number] if EXCEPTIONS[number]
170
+
171
+ output = ""
172
+ length = number.to_s.length
173
+ if length == 2 #20-99
174
+ tens = (number/10).round*10 #write the tens
175
+ # e.g. eighty
176
+ output << EXCEPTIONS[tens]
177
+ #write the digits
178
+ digit= number - tens
179
+ output << " " + digit.in_english unless digit==0
180
+ elsif length == 3
181
+ #e.g. 113 splits into "one hundred" and "thirteen"
182
+ output << number.english_group(2)
183
+ elsif length < LENGTH_OF_GOOGOL #more than one hundred less than one googol
184
+ output << number.english_group(3)
185
+ elsif length == LENGTH_OF_GOOGOL
186
+ output << number.in_googols
187
+ elsif length > LENGTH_OF_GOOGOL #one googol and larger
188
+ output << number.split_googols
189
+ end
190
+
191
+ return output.strip
192
+ end
193
+
194
+ def in_words language="English"
195
+ case language
196
+ when "English" #allow for I18n
197
+ in_english
198
+ end
199
+ end
200
+ end
201
+
202
+ class Fixnum
203
+ include NumbersInWords
204
+ end
205
+
206
+ class Bignum
207
+ include NumbersInWords
208
+ end
@@ -1,208 +1,8 @@
1
1
  require 'rubygems'
2
- require 'active_support'
3
- module NumbersInWords
4
2
 
5
- #handle exceptions to normal numbers
6
- EXCEPTIONS = {10=> "ten", 11=>"eleven", 12 => "twelve", 13 => "thirteen",
7
- 14=>"fourteen", 15=>"fifteen", 16=>"sixteen" ,
8
- 17=> "seventeen", 18=> "eighteen", 19=> "nineteen",
9
- 20 => "twenty", 30=>"thirty",
10
- 40=>"forty", 50=>"fifty", 60 => "sixty", 70=> "seventy", 80=>"eighty",
11
- 90 => "ninety"}
3
+ $LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__)))
12
4
 
13
- DIGITS= %w[zero one two three four five six seven eight nine]
14
- POWERS_OF_TEN ={0=>"one", 1 => "ten", 2=> "hundred",
15
- 3 => "thousand", 6=>"million",
16
- 9=>"billion",
17
- 12=>"trillion",
18
- 15=>"quadrillion",
19
- 18=>"quintillion",
20
- 21=>"sextillion",
21
- 24=>"septillion",
22
- 27=>"octillion",
23
- 30=>"nonillion",
24
- 33=>"decillion",
25
- 36=>"undecillion",
26
- 39=>"duodecillion",
27
- 42=>"tredecillion",
28
- 45=>"quattuordecillion",
29
- 48=>"quindecillion",
30
- 51=>"sexdecillion",
31
- 54=>"septendecillion",
32
- 57=>"octodecillion",
33
- 60=>"novemdecillion",
34
- 63=>"vigintillion",
35
- 66=>"unvigintillion",
36
- 69=>"duovigintillion",
37
- 72=>"trevigintillion",
38
- 75=>"quattuorvigintillion",
39
- 78=>"quinvigintillion",
40
- 81=>"sexvigintillion",
41
- 84=>"septenvigintillion",
42
- 87=>"octovigintillion",
43
- 90=>"novemvigintillion",
44
- 93=>"trigintillion",
45
- 96=>"untrigintillion",
46
- 99=>"duotrigintillion",
47
- 100 => "googol"
48
- }
49
- LENGTH_OF_GOOGOL = 101 #length of the string i.e. one with 100 zeros
5
+ require 'numbers'
6
+ require 'words'
50
7
 
51
- def initialize
52
- power = 9
53
- POWERS_OF_TEN_NAMES.each do |name|
54
- POWERS_OF_TEN[power]=name
55
- power += 3
56
- end
57
- end
58
8
 
59
- #returns a hash with powers of ten and their multipliers
60
- def powers_of_ten
61
- i = self.to_i
62
- digits=i.to_s.split ""
63
- #turn back into integers
64
- digits.map! { |x| x.to_i}
65
-
66
- digits.reverse!
67
- #create a hash where the key is the
68
- #power of ten and the value is the multipler
69
- power = 0
70
- return digits.inject({}) do |result,digit|
71
- result[power]=digit unless digit==0
72
- power+=1
73
- result
74
- end
75
- end
76
-
77
- def groups_of size
78
- i=self.to_i
79
- #split into groups this gives us 1234567 => 123 456 7
80
- #so we need to reverse first
81
- #in stages
82
- #i.e. 1234567 => 7654321
83
- groups = i.to_s.reverse
84
- #7654321 => 765 432 1
85
- groups = groups.split("").in_groups_of(size)
86
- #765 432 1 => 1 432 765
87
- groups.reverse!
88
- #1 432 765 => 1 234 567
89
- groups.map! {|group| group.reverse}
90
-
91
- #turn back into integers
92
- groups.map! {|group| group.join("").to_i }
93
- groups.reverse! # put in ascending order of power of ten
94
-
95
- #output hash where key is the power of ten
96
- #and value if the multiplier
97
- power = 0
98
- return groups.inject({}) do |output, digits|
99
- output[power]=digits
100
- power+=size
101
- output
102
- end
103
-
104
- end
105
-
106
- def group_words size, language="English"
107
- #1000 and over Numbers are split into groups of three
108
- number = self.to_i
109
- groups = number.groups_of(size)
110
- powers = groups.keys.sort.reverse #put in descending order
111
- powers.each do |power|
112
- name = POWERS_OF_TEN[power] if language=="English"
113
- digits = groups[power]
114
- yield power, name, digits
115
- end
116
-
117
- end
118
-
119
- def english_group group_size
120
- number = self.to_i
121
- output = ""
122
- number.group_words(group_size) do |power, name, digits|
123
- if digits > 0
124
- prefix = " "
125
- #no 'and' between thousands and hundreds
126
- prefix << "and " if power == 0 and digits < 100
127
- output << prefix + digits.in_english
128
- output << prefix + name unless power == 0
129
- end
130
- end
131
- return output
132
- end
133
-
134
- def split_googols
135
- number = self.to_i
136
- output = ""
137
- googols = number.to_s[0..(-LENGTH_OF_GOOGOL)].to_i
138
- remainder = number.to_s[1-LENGTH_OF_GOOGOL .. -1].to_i
139
- output << " " + googols.in_words + " googol"
140
- if remainder > 0
141
- prefix = " "
142
- prefix << "and " if remainder < 100
143
- output << prefix + remainder.in_english
144
- end
145
- return output
146
- end
147
-
148
- def in_googols
149
-
150
- number = self.to_i
151
- output = ""
152
- output << " " + number.to_s[0..0].to_i.in_english + " googol"
153
- remainder = number.to_s[1..-1].to_i
154
- prefix = " "
155
- prefix << "and " if remainder < 100
156
- output << prefix + remainder.in_english if remainder > 0
157
-
158
- return output
159
- end
160
-
161
- def in_english
162
- number = self.to_i # make a copy
163
- #handle negative numbers
164
- if number < 0
165
- return "minus " + (-number).in_english
166
- end
167
- #handle 0-10
168
- return DIGITS[number] if number < 10
169
- return EXCEPTIONS[number] if EXCEPTIONS[number]
170
-
171
- output = ""
172
- length = number.to_s.length
173
- if length == 2 #20-99
174
- tens = (number/10).round*10 #write the tens
175
- # e.g. eighty
176
- output << EXCEPTIONS[tens]
177
- #write the digits
178
- digit= number - tens
179
- output << " " + digit.in_english unless digit==0
180
- elsif length == 3
181
- #e.g. 113 splits into "one hundred" and "thirteen"
182
- output << number.english_group(2)
183
- elsif length < LENGTH_OF_GOOGOL #more than one hundred less than one googol
184
- output << number.english_group(3)
185
- elsif length == LENGTH_OF_GOOGOL
186
- output << number.in_googols
187
- elsif length > LENGTH_OF_GOOGOL #one googol and larger
188
- output << number.split_googols
189
- end
190
-
191
- return output.strip
192
- end
193
-
194
- def in_words language="English"
195
- case language
196
- when "English" #allow for I18n
197
- in_english
198
- end
199
- end
200
- end
201
-
202
- class Fixnum
203
- include NumbersInWords
204
- end
205
-
206
- class Bignum
207
- include NumbersInWords
208
- end
File without changes
@@ -2,21 +2,21 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{numbers_in_words}
5
- s.version = "0.0.7"
5
+ s.version = "0.0.9"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Mark Burns"]
9
9
  s.date = %q{2010-04-06}
10
- s.description = %q{}
10
+ s.description = %q{#in_words method for integers and #in_numbers for strings}
11
11
  s.email = %q{markthedeveloper@googlemail.com}
12
- s.extra_rdoc_files = ["lib/numbers_in_words.rb", "lib/numbers_in_words.rb_cyclo.html", "lib/words_in_numbers.rb", "lib/words_in_numbers.rb_cyclo.html"]
13
- s.files = ["Manifest", "Rakefile", "examples/display_numbers_in_words.rb", "index_cyclo.html", "lib/numbers_in_words.rb", "lib/numbers_in_words.rb_cyclo.html", "lib/words_in_numbers.rb", "lib/words_in_numbers.rb_cyclo.html", "numbers_in_words.rb", "spec/numbers_in_words_spec.rb", "spec/words_in_numbers_spec.rb", "numbers_in_words.gemspec"]
12
+ s.extra_rdoc_files = ["README", "lib/numbers.rb", "lib/numbers_in_words.rb", "lib/numbers_in_words.rb_cyclo.html", "lib/words.rb", "lib/words_in_numbers.rb_cyclo.html"]
13
+ s.files = ["Manifest", "README", "Rakefile", "examples/display_numbers_in_words.rb", "index_cyclo.html", "init.rb", "lib/numbers.rb", "lib/numbers_in_words.rb", "lib/numbers_in_words.rb_cyclo.html", "lib/words.rb", "lib/words_in_numbers.rb_cyclo.html", "numbers_in_words.gemspec", "spec/numbers_in_words_spec.rb", "spec/words_in_numbers_spec.rb"]
14
14
  s.homepage = %q{http://rubygems.org/gems/numbers_in_words}
15
- s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Numbers_in_words"]
15
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Numbers_in_words", "--main", "README"]
16
16
  s.require_paths = ["lib"]
17
17
  s.rubyforge_project = %q{numbers_in_words}
18
18
  s.rubygems_version = %q{1.3.6}
19
- s.summary = %q{}
19
+ s.summary = %q{Example: 123.in_words #=> "one hundred and twenty three", "seventy-five".in_numbers #=> 75}
20
20
 
21
21
  if s.respond_to? :specification_version then
22
22
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 7
9
- version: 0.0.7
8
+ - 9
9
+ version: 0.0.9
10
10
  platform: ruby
11
11
  authors:
12
12
  - Mark Burns
@@ -29,30 +29,34 @@ dependencies:
29
29
  version: "0"
30
30
  type: :development
31
31
  version_requirements: *id001
32
- description: ""
32
+ description: "#in_words method for integers and #in_numbers for strings"
33
33
  email: markthedeveloper@googlemail.com
34
34
  executables: []
35
35
 
36
36
  extensions: []
37
37
 
38
38
  extra_rdoc_files:
39
+ - README
40
+ - lib/numbers.rb
39
41
  - lib/numbers_in_words.rb
40
42
  - lib/numbers_in_words.rb_cyclo.html
41
- - lib/words_in_numbers.rb
43
+ - lib/words.rb
42
44
  - lib/words_in_numbers.rb_cyclo.html
43
45
  files:
44
46
  - Manifest
47
+ - README
45
48
  - Rakefile
46
49
  - examples/display_numbers_in_words.rb
47
50
  - index_cyclo.html
51
+ - init.rb
52
+ - lib/numbers.rb
48
53
  - lib/numbers_in_words.rb
49
54
  - lib/numbers_in_words.rb_cyclo.html
50
- - lib/words_in_numbers.rb
55
+ - lib/words.rb
51
56
  - lib/words_in_numbers.rb_cyclo.html
52
- - numbers_in_words.rb
57
+ - numbers_in_words.gemspec
53
58
  - spec/numbers_in_words_spec.rb
54
59
  - spec/words_in_numbers_spec.rb
55
- - numbers_in_words.gemspec
56
60
  has_rdoc: true
57
61
  homepage: http://rubygems.org/gems/numbers_in_words
58
62
  licenses: []
@@ -63,6 +67,8 @@ rdoc_options:
63
67
  - --inline-source
64
68
  - --title
65
69
  - Numbers_in_words
70
+ - --main
71
+ - README
66
72
  require_paths:
67
73
  - lib
68
74
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -86,6 +92,6 @@ rubyforge_project: numbers_in_words
86
92
  rubygems_version: 1.3.6
87
93
  signing_key:
88
94
  specification_version: 3
89
- summary: ""
95
+ summary: "Example: 123.in_words #=> \"one hundred and twenty three\", \"seventy-five\".in_numbers #=> 75"
90
96
  test_files: []
91
97