numbers_in_words 0.0.7 → 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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