numbers_in_words 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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