numbers_in_words 0.1.1 → 0.2.0

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.
@@ -0,0 +1,31 @@
1
+ module NumbersInWords
2
+ class LanguageWriter
3
+ attr_reader :that
4
+ delegate :exceptions, :powers_of_ten, to: :language
5
+
6
+ def initialize that
7
+ @that = that
8
+ end
9
+
10
+ def language
11
+ if @language.is_a? Module
12
+ @language
13
+ else
14
+ @language = NumbersInWords.const_get(@language)
15
+ end
16
+ end
17
+
18
+
19
+ def group_words size
20
+ #1000 and over Numbers are split into groups of three
21
+ groups = NumberGroup.groups_of @that, size
22
+ powers = groups.keys.sort.reverse #put in descending order
23
+
24
+ powers.each do |power|
25
+ name = powers_of_ten[power]
26
+ digits = groups[power]
27
+ yield power, name, digits
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,55 @@
1
+ module NumbersInWords
2
+ class NumberGroup
3
+ include Enumerable
4
+ attr_accessor :number
5
+
6
+ def each
7
+ @array.each { |item| yield item}
8
+ end
9
+
10
+ def initialize number
11
+ @number = number
12
+ end
13
+
14
+ #split into groups this gives us 1234567 => 123 456 7
15
+ #so we need to reverse first
16
+ #in stages
17
+ def groups size
18
+ #1234567 => %w(765 432 1)
19
+ @array = @number.to_s.reverse.split("").in_groups_of(size)
20
+ #%w(765 432 1) => %w(1 432 765)
21
+ @array.reverse!
22
+
23
+ #%w(1 432 765) => [1, 234, 567]
24
+ @array.map! {|group| group.reverse.join("").to_i}
25
+ @array.reverse! # put in ascending order of power of ten
26
+
27
+ power = 0
28
+
29
+ #[1, 234, 567] => {6 => 1, 3 => 234, 0 => 567}
30
+ @array.inject({}) do |o, digits|
31
+ o[power] = digits
32
+ power += size
33
+ o
34
+ end
35
+ end
36
+
37
+ def split_decimals
38
+ if @number.is_a? Float
39
+ int, decimal = @number.to_s.split "."
40
+
41
+ return int.to_i, decimal.split(//).map(&:to_i)
42
+ end
43
+ end
44
+
45
+ def self.groups_of number, size
46
+ new(number).groups(size)
47
+ end
48
+
49
+ def split_googols
50
+ googols = @number.to_s[0 .. (-LENGTH_OF_GOOGOL)].to_i
51
+ remainder = @number.to_s[(1-LENGTH_OF_GOOGOL) .. -1].to_i
52
+ return googols, remainder
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,81 @@
1
+ module NumbersInWords::NumberParser
2
+ # Example: 364,895,457,898
3
+ #three hundred and sixty four billion eight hundred and ninety five million
4
+ #four hundred and fifty seven thousand eight hundred and ninety eight
5
+ #
6
+ #3 100 60 4 10^9, 8 100 90 5 10^6, 4 100 50 7 1000, 8 100 90 8
7
+ # memory answer
8
+ #x1. 3 add to memory because answer and memory are zero 3 0
9
+ #x2. memory * 100 (because memory<100) 300 0
10
+ #x3. 60 add to memory because memory > 60 360 0
11
+ #x3. 4 add to memory because memory > 4 364 0
12
+ #x4. multiply memory by 10^9 because memory < power of ten 364*10^9 0
13
+ #x5. add memory to answer (and reset)memory > 8 (memory pow of ten > 2) 0 364*10^9
14
+ #x6. 8 add to memory because not finished 8 ''
15
+ #x7. multiply memory by 100 because memory < 100 800 ''
16
+ #x8. add 90 to memory because memory > 90 890 ''
17
+ #x9. add 5 to memory because memory > 5 895 ''
18
+ #x10. multiply memory by 10^6 because memory < power of ten 895*10^6 ''
19
+ #x11. add memory to answer (and reset) because memory power ten > 2 0 364895 * 10^6
20
+ #x12. 4 add to memory because not finished 4 ''
21
+ #x13. memory * 100 because memory < 100 400 ''
22
+ #x14. memory + 50 because memory > 50 450 ''
23
+ #x15. memory + 7 because memory > 7 457 ''
24
+ #x16. memory * 1000 because memory < 1000 457000 ''
25
+ #x17. add memory to answer (and reset)memory > 8 (memory pow of ten > 2) 0 364895457000
26
+ #x18. 8 add to memory because not finished 8 ''
27
+ #x19. memory * 100 because memory < 100 800 ''
28
+ #x14. memory + 90 because memory > 90 890 ''
29
+ #x15. memory + 8 because memory > 8 898 ''
30
+ #16. finished so add memory to answer
31
+
32
+ #Example
33
+ #2001
34
+ #two thousand and one
35
+ #2 1000 1
36
+ # memory answer
37
+ #1. add 2 to memory because first 2 0
38
+ #2. multiply memory by 1000 because memory < 1000 2000 0
39
+ #3. add memory to answer,reset, because power of ten>2 0 2000
40
+ #4. add 1 to memory 1 2000
41
+ #5. finish - add memory to answer 0 2001
42
+ def parse(integers)
43
+ memory = 0
44
+ answer = 0
45
+ reset = true #reset each time memory is reset
46
+ integers.each_with_index do |integer, index|
47
+ if reset
48
+ reset = false
49
+ memory += integer
50
+ else
51
+ #x4. multiply memory by 10^9 because memory < power of ten
52
+ if power_of_ten?(integer)
53
+ if power_of_ten(integer)> 2
54
+ memory *= integer
55
+ #17. add memory to answer (and reset) (memory pow of ten > 2)
56
+ answer += memory
57
+ memory = 0
58
+ reset = true
59
+ end
60
+ end
61
+
62
+ if memory < integer
63
+ memory *= integer
64
+ else
65
+ memory += integer
66
+ end
67
+ end
68
+ end
69
+ answer += memory
70
+ end
71
+
72
+ def power_of_ten integer
73
+ Math.log10(integer)
74
+ end
75
+
76
+ def power_of_ten? integer
77
+ power_of_ten(integer) == power_of_ten(integer).to_i
78
+ end
79
+
80
+ extend self
81
+ end
@@ -0,0 +1,82 @@
1
+ class NumbersInWords::ToNumber
2
+ delegate :to_s, to: :that
3
+ delegate :powers_of_ten_to_i, :exceptions_to_i, to: :language
4
+ attr_reader :that, :language
5
+
6
+ def initialize that, language=NumbersInWords.language
7
+ @that = that
8
+ @language = language
9
+ end
10
+
11
+ def language
12
+ if @language.is_a? Module
13
+ @language
14
+ else
15
+ @language = NumbersInWords.const_get(@language)
16
+ end
17
+ end
18
+
19
+ def handle_negative text
20
+ -1 * (text.gsub(/^minus /, "")).in_numbers if text =~ /^minus /
21
+ end
22
+
23
+ def in_numbers
24
+ text = to_s
25
+
26
+ text = strip_punctuation text
27
+ i = handle_negative text
28
+ return i if i
29
+
30
+ h = handle_decimals text
31
+ return h if h
32
+
33
+ integers = word_array_to_integers text.split(" ")
34
+
35
+ NumbersInWords::NumberParser.parse integers
36
+ end
37
+
38
+ def strip_punctuation text
39
+ text = text.downcase.gsub(/[^a-z ]/, " ")
40
+ to_remove = true
41
+
42
+ to_remove = text.gsub! " ", " " while to_remove
43
+
44
+ text
45
+ end
46
+
47
+ def handle_decimals text
48
+ match = text.match(/\spoint\s/)
49
+ if match
50
+ integer = match.pre_match.in_numbers
51
+
52
+ decimal = decimal_portion match.post_match
53
+
54
+ integer + decimal
55
+ end
56
+ end
57
+
58
+
59
+ def decimal_portion text
60
+ words = text.split " "
61
+ integers = word_array_to_integers words
62
+ decimal = "0." + integers.join()
63
+ decimal.to_f
64
+ end
65
+
66
+ #handles simple single word numbers
67
+ #e.g. one, seven, twenty, eight, thousand etc
68
+ def word_to_integer word
69
+ text = word.to_s.chomp.strip
70
+
71
+ exception = exceptions_to_i[text]
72
+ return exception if exception
73
+
74
+ power = powers_of_ten_to_i[text]
75
+ return 10 ** power if power
76
+ end
77
+
78
+ def word_array_to_integers words
79
+ words.map { |i| word_to_integer i }.compact
80
+ end
81
+ end
82
+
@@ -0,0 +1,19 @@
1
+ class NumbersInWords::ToWord
2
+ def initialize that, language=NumbersInWords.language
3
+ @that = that
4
+ @language = language
5
+ end
6
+
7
+ def in_words language=nil
8
+ language ||= @language
9
+
10
+ case language
11
+ when "English" #allow for I18n
12
+ in_english
13
+ end
14
+ end
15
+
16
+ def in_english
17
+ NumbersInWords::English::LanguageWriterEnglish.new(@that).in_words
18
+ end
19
+ end
@@ -0,0 +1,3 @@
1
+ module NumbersInWords
2
+ VERSION = "0.2.0"
3
+ end
@@ -1,32 +1,24 @@
1
1
  # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'numbers_in_words/version'
2
5
 
3
- Gem::Specification.new do |s|
4
- s.name = "numbers_in_words"
5
- s.version = "0.1.1"
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "numbers_in_words"
8
+ gem.description = "#in_words method for integers and #in_numbers for strings"
9
+ gem.summary = "Example: 123.in_words # => \"one hundred and twenty three\", \"seventy-five point eight\".in_numbers # = > 75.8"
6
10
 
7
- s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
- s.authors = ["Mark Burns"]
9
- s.date = "2012-04-10"
10
- s.description = "#in_words method for integers and #in_numbers for strings"
11
- s.email = "markthedeveloper@gmail.com"
12
- s.extra_rdoc_files = ["CHANGELOG", "README", "lib/numbers.rb", "lib/numbers_in_words.rb", "lib/words.rb"]
13
- s.files = ["CHANGELOG", "Manifest", "README", "Rakefile", "examples/display_numbers_in_words.rb", "init.rb", "lib/numbers.rb", "lib/numbers_in_words.rb", "lib/words.rb", "spec/numbers_in_words_spec.rb", "spec/words_in_numbers_spec.rb", "numbers_in_words.gemspec"]
14
- s.homepage = "http://rubygems.org/gems/numbers_in_words"
15
- s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Numbers_in_words", "--main", "README"]
16
- s.require_paths = ["lib"]
17
- s.rubyforge_project = "numbers_in_words"
18
- s.rubygems_version = "1.8.17"
19
- s.summary = "Example: 123.in_words #=> \"one hundred and twenty three\", \"seventy-five point eight\".in_numbers #=> 75.8"
11
+ gem.version = NumbersInWords::VERSION
12
+ gem.authors = ["Mark Burns"]
13
+ gem.email = ["markthedeveloper@gmail.com"]
14
+ gem.homepage = "http://github.com/markburns/numbers_in_words"
20
15
 
21
- if s.respond_to? :specification_version then
22
- s.specification_version = 3
16
+ gem.add_dependency "activesupport"
17
+ gem.add_development_dependency "rspec"
18
+ gem.add_development_dependency "debugger"
23
19
 
24
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
25
- s.add_runtime_dependency(%q<active_support>, [">= 0"])
26
- else
27
- s.add_dependency(%q<active_support>, [">= 0"])
28
- end
29
- else
30
- s.add_dependency(%q<active_support>, [">= 0"])
31
- end
20
+ gem.files = `git ls-files`.split($/)
21
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
22
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
23
+ gem.require_paths = ["lib"]
32
24
  end
@@ -0,0 +1,23 @@
1
+ require './spec/spec_helper'
2
+
3
+ describe NumbersInWords::English::LanguageWriterEnglish do
4
+ it "should display numbers grouped" do
5
+ count = 0
6
+ @writer = NumbersInWords::English::LanguageWriterEnglish.new(2111)
7
+ @writer.group_words(3) do |power, name, digits|
8
+ case count
9
+ when 0
10
+ power.should == 3
11
+ name.should == "thousand"
12
+ digits.should == 2
13
+ when 1
14
+ power.should == 0
15
+ name.should == "one"
16
+ digits.should == 111
17
+ end
18
+ count += 1
19
+ end
20
+ end
21
+ end
22
+
23
+
@@ -0,0 +1,17 @@
1
+ require './spec/spec_helper'
2
+
3
+ describe NumbersInWords::NumberGroup do
4
+ it "should split into group of three digit numbers" do
5
+ g = Numeric::NumberGroup
6
+
7
+ g.groups_of(1 ,3 ).should == {0=>1 }
8
+ g.groups_of(12 ,3 ).should == {0=>12 }
9
+ g.groups_of(123 ,3 ).should == {0=>123 }
10
+ g.groups_of(1111 ,3 ).should == {3=>1 , 0=>111 }
11
+ g.groups_of(87654 ,3 ).should == {3=>87 , 0=>654 }
12
+ g.groups_of(1_234_567 ,3 ).should == {6=>1 , 3=>234 , 0=>567 }
13
+ g.groups_of(123_456_789_101_112 ,3 ).should == {12=>123 , 9=>456 , 6=>789 , 3=>101 , 0=>112 }
14
+ end
15
+ end
16
+
17
+
@@ -1,38 +1,4 @@
1
- require './lib/numbers_in_words'
2
-
3
- describe NumbersInWords::NumberGroup do
4
-
5
- it "should split into group of three digit numbers" do
6
- Numeric::NumberGroup.groups_of(1,3).should == {0=>1}
7
- Numeric::NumberGroup.groups_of(12,3).should == {0=>12}
8
- Numeric::NumberGroup.groups_of(123,3).should == {0=>123}
9
- Numeric::NumberGroup.groups_of(1111,3).should == {3=>1,0=>111}
10
- Numeric::NumberGroup.groups_of(87654,3).should == {3=>87,0=>654}
11
- Numeric::NumberGroup.groups_of(1234567,3).should == {6=>1,3=>234,0=>567}
12
- Numeric::NumberGroup.groups_of(123456789101112,3).should == {12=>123,9=>456,6=>789,3=>101,0=>112}
13
- end
14
- end
15
-
16
- describe NumbersInWords::LanguageWriterEnglish do
17
- it "should display numbers grouped" do
18
- count = 0
19
- @writer = NumbersInWords::LanguageWriterEnglish.new(2111)
20
- @writer.group_words(3) do |power, name, digits|
21
- case count
22
- when 0
23
- power.should == 3
24
- name.should == "thousand"
25
- digits.should == 2
26
- when 1
27
- power.should == 0
28
- name.should == "one"
29
- digits.should == 111
30
- end
31
- count += 1
32
- end
33
- end
34
- end
35
-
1
+ require './spec/spec_helper'
36
2
 
37
3
  describe NumbersInWords do
38
4
  it "should print the digits 0-9 correctly" do
@@ -0,0 +1,2 @@
1
+ require 'numbers_in_words'
2
+ require 'numbers_in_words/duck_punch'
@@ -1,4 +1,4 @@
1
- require './lib/words'
1
+ require './spec/spec_helper'
2
2
 
3
3
  describe WordsInNumbers do
4
4
  it "should do the digits 0-10" do
metadata CHANGED
@@ -1,60 +1,97 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: numbers_in_words
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
5
4
  prerelease:
5
+ version: 0.2.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Mark Burns
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-10 00:00:00.000000000 Z
12
+ date: 2013-01-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
- name: active_support
16
- requirement: &70207857965260 !ruby/object:Gem::Requirement
15
+ type: :runtime
16
+ version_requirements: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
20
20
  - !ruby/object:Gem::Version
21
21
  version: '0'
22
- type: :runtime
22
+ name: activesupport
23
23
  prerelease: false
24
- version_requirements: *70207857965260
24
+ requirement: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ type: :development
32
+ version_requirements: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ name: rspec
39
+ prerelease: false
40
+ requirement: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ type: :development
48
+ version_requirements: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ name: debugger
55
+ prerelease: false
56
+ requirement: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
25
62
  description: ! '#in_words method for integers and #in_numbers for strings'
26
- email: markthedeveloper@gmail.com
63
+ email:
64
+ - markthedeveloper@gmail.com
27
65
  executables: []
28
66
  extensions: []
29
- extra_rdoc_files:
30
- - CHANGELOG
31
- - README
32
- - lib/numbers.rb
33
- - lib/numbers_in_words.rb
34
- - lib/words.rb
67
+ extra_rdoc_files: []
35
68
  files:
36
- - CHANGELOG
37
- - Manifest
38
- - README
69
+ - .gitignore
70
+ - Gemfile
71
+ - Gemfile.lock
72
+ - LICENSE.txt
73
+ - README.md
39
74
  - Rakefile
40
- - examples/display_numbers_in_words.rb
41
- - init.rb
42
- - lib/numbers.rb
43
75
  - lib/numbers_in_words.rb
44
- - lib/words.rb
76
+ - lib/numbers_in_words/duck_punch.rb
77
+ - lib/numbers_in_words/english/constants.rb
78
+ - lib/numbers_in_words/english/language_writer_english.rb
79
+ - lib/numbers_in_words/language_writer.rb
80
+ - lib/numbers_in_words/number_group.rb
81
+ - lib/numbers_in_words/number_parser.rb
82
+ - lib/numbers_in_words/to_number.rb
83
+ - lib/numbers_in_words/to_word.rb
84
+ - lib/numbers_in_words/version.rb
85
+ - numbers_in_words.gemspec
86
+ - spec/language_writer_spec.rb
87
+ - spec/number_group_spec.rb
45
88
  - spec/numbers_in_words_spec.rb
89
+ - spec/spec_helper.rb
46
90
  - spec/words_in_numbers_spec.rb
47
- - numbers_in_words.gemspec
48
- homepage: http://rubygems.org/gems/numbers_in_words
91
+ homepage: http://github.com/markburns/numbers_in_words
49
92
  licenses: []
50
93
  post_install_message:
51
- rdoc_options:
52
- - --line-numbers
53
- - --inline-source
54
- - --title
55
- - Numbers_in_words
56
- - --main
57
- - README
94
+ rdoc_options: []
58
95
  require_paths:
59
96
  - lib
60
97
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -62,18 +99,29 @@ required_ruby_version: !ruby/object:Gem::Requirement
62
99
  requirements:
63
100
  - - ! '>='
64
101
  - !ruby/object:Gem::Version
102
+ segments:
103
+ - 0
104
+ hash: -1513551754306869579
65
105
  version: '0'
66
106
  required_rubygems_version: !ruby/object:Gem::Requirement
67
107
  none: false
68
108
  requirements:
69
109
  - - ! '>='
70
110
  - !ruby/object:Gem::Version
71
- version: '1.2'
111
+ segments:
112
+ - 0
113
+ hash: -1513551754306869579
114
+ version: '0'
72
115
  requirements: []
73
- rubyforge_project: numbers_in_words
74
- rubygems_version: 1.8.17
116
+ rubyforge_project:
117
+ rubygems_version: 1.8.23
75
118
  signing_key:
76
119
  specification_version: 3
77
- summary: ! 'Example: 123.in_words #=> "one hundred and twenty three", "seventy-five
78
- point eight".in_numbers #=> 75.8'
79
- test_files: []
120
+ summary: ! 'Example: 123.in_words # => "one hundred and twenty three", "seventy-five
121
+ point eight".in_numbers # = > 75.8'
122
+ test_files:
123
+ - spec/language_writer_spec.rb
124
+ - spec/number_group_spec.rb
125
+ - spec/numbers_in_words_spec.rb
126
+ - spec/spec_helper.rb
127
+ - spec/words_in_numbers_spec.rb