ada_numbers 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.idea/.gitignore +8 -0
- data/.idea/ada_numbers.iml +46 -0
- data/.idea/modules.xml +9 -0
- data/.idea/vcs.xml +6 -0
- data/Gemfile +7 -0
- data/Gemfile.lock +21 -0
- data/Rakefile +10 -0
- data/ada_numbers.gemspec +30 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/ada_numbers/constants/en/separators.rb +11 -0
- data/lib/ada_numbers/constants/en/written_numbers.rb +113 -0
- data/lib/ada_numbers/constants/message.rb +8 -0
- data/lib/ada_numbers/constants/pt/separators.rb +9 -0
- data/lib/ada_numbers/constants/pt/written_numbers.rb +116 -0
- data/lib/ada_numbers/converters/en/number_to_words_converter.rb +185 -0
- data/lib/ada_numbers/converters/en/words_to_number_converter.rb +151 -0
- data/lib/ada_numbers/converters/number_to_words_converter_extensions.rb +32 -0
- data/lib/ada_numbers/converters/pt/number_to_words_converter.rb +179 -0
- data/lib/ada_numbers/converters/pt/words_to_number_converter.rb +143 -0
- data/lib/ada_numbers/converters/words_to_number_converter_extensions.rb +17 -0
- data/lib/ada_numbers/utilities/hash_extensions.rb +15 -0
- data/lib/ada_numbers/utilities/integer_extensions.rb +39 -0
- data/lib/ada_numbers/utilities/number_category.rb +11 -0
- data/lib/ada_numbers/utilities/settings.rb +35 -0
- data/lib/ada_numbers/utilities/string_extensions.rb +5 -0
- data/lib/ada_numbers/version.rb +3 -0
- data/lib/ada_numbers.rb +13 -0
- metadata +77 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 687cb405cfb56c733e1f7744a14999e22bc15ef11ae93c3163522c2a1dbe2e0f
|
4
|
+
data.tar.gz: 6324a7fe749ed13b5589ce8c180758ff46415f1427981ea10ac49c3a12506e6e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a3be0a5c634712132d807f58524629ce698a74447745394380ff082aec034cb95cb1466859f62b826068a971e583fe941046d0ddec091b9a1ebcf1570ec3299d
|
7
|
+
data.tar.gz: 9b6d9d02c84bd66f179bdf6002c65fd8bcb21d8cf816034ddb74fb91c4f7544062f63b655b5e8430fb90c6dd383bc6338a72c93ff451062f607b15c9122071fc
|
data/.idea/.gitignore
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<module type="RUBY_MODULE" version="4">
|
3
|
+
<component name="ModuleRunConfigurationManager">
|
4
|
+
<shared />
|
5
|
+
</component>
|
6
|
+
<component name="NewModuleRootManager">
|
7
|
+
<content url="file://$MODULE_DIR$">
|
8
|
+
<sourceFolder url="file://$MODULE_DIR$/features" isTestSource="true" />
|
9
|
+
<sourceFolder url="file://$MODULE_DIR$/spec" isTestSource="true" />
|
10
|
+
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
|
11
|
+
</content>
|
12
|
+
<orderEntry type="jdk" jdkName="rbenv: 2.7.7" jdkType="RUBY_SDK" />
|
13
|
+
<orderEntry type="sourceFolder" forTests="false" />
|
14
|
+
<orderEntry type="library" scope="PROVIDED" name="bundler (v2.1.4, rbenv: 2.7.7) [gem]" level="application" />
|
15
|
+
<orderEntry type="library" scope="PROVIDED" name="minitest (v5.18.0, rbenv: 2.7.7) [gem]" level="application" />
|
16
|
+
<orderEntry type="library" scope="PROVIDED" name="rake (v12.3.3, rbenv: 2.7.7) [gem]" level="application" />
|
17
|
+
</component>
|
18
|
+
<component name="RakeTasksCache">
|
19
|
+
<option name="myRootTask">
|
20
|
+
<RakeTaskImpl id="rake">
|
21
|
+
<subtasks>
|
22
|
+
<RakeTaskImpl description="Build ada_numbers-0.1.0.gem into the pkg directory" fullCommand="build" id="build" />
|
23
|
+
<RakeTaskImpl description="Remove any temporary products" fullCommand="clean" id="clean" />
|
24
|
+
<RakeTaskImpl description="Remove any generated files" fullCommand="clobber" id="clobber" />
|
25
|
+
<RakeTaskImpl description="Build and install ada_numbers-0.1.0.gem into system gems" fullCommand="install" id="install" />
|
26
|
+
<RakeTaskImpl id="install">
|
27
|
+
<subtasks>
|
28
|
+
<RakeTaskImpl description="Build and install ada_numbers-0.1.0.gem into system gems without network access" fullCommand="install:local" id="local" />
|
29
|
+
</subtasks>
|
30
|
+
</RakeTaskImpl>
|
31
|
+
<RakeTaskImpl description="Create tag v0.1.0 and build and push ada_numbers-0.1.0.gem to rubygems.org" fullCommand="release[remote]" id="release[remote]" />
|
32
|
+
<RakeTaskImpl description="Run tests" fullCommand="test" id="test" />
|
33
|
+
<RakeTaskImpl description="" fullCommand="default" id="default" />
|
34
|
+
<RakeTaskImpl description="" fullCommand="release" id="release" />
|
35
|
+
<RakeTaskImpl id="release">
|
36
|
+
<subtasks>
|
37
|
+
<RakeTaskImpl description="" fullCommand="release:guard_clean" id="guard_clean" />
|
38
|
+
<RakeTaskImpl description="" fullCommand="release:rubygem_push" id="rubygem_push" />
|
39
|
+
<RakeTaskImpl description="" fullCommand="release:source_control_push" id="source_control_push" />
|
40
|
+
</subtasks>
|
41
|
+
</RakeTaskImpl>
|
42
|
+
</subtasks>
|
43
|
+
</RakeTaskImpl>
|
44
|
+
</option>
|
45
|
+
</component>
|
46
|
+
</module>
|
data/.idea/modules.xml
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<project version="4">
|
3
|
+
<component name="ProjectModuleManager">
|
4
|
+
<modules>
|
5
|
+
<module fileurl="file://$PROJECT_DIR$/.idea/ada_numbers.iml" filepath="$PROJECT_DIR$/.idea/ada_numbers.iml" />
|
6
|
+
<module fileurl="file://$PROJECT_DIR$/../.idea/ada_numbers_gem.iml" filepath="$PROJECT_DIR$/../.idea/ada_numbers_gem.iml" />
|
7
|
+
</modules>
|
8
|
+
</component>
|
9
|
+
</project>
|
data/.idea/vcs.xml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
ada_numbers (1.0.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
minitest (5.18.0)
|
10
|
+
rake (12.3.3)
|
11
|
+
|
12
|
+
PLATFORMS
|
13
|
+
ruby
|
14
|
+
|
15
|
+
DEPENDENCIES
|
16
|
+
ada_numbers!
|
17
|
+
minitest (~> 5.0)
|
18
|
+
rake (~> 12.0)
|
19
|
+
|
20
|
+
BUNDLED WITH
|
21
|
+
2.1.4
|
data/Rakefile
ADDED
data/ada_numbers.gemspec
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require_relative 'lib/ada_numbers/version'
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = "ada_numbers"
|
5
|
+
spec.version = AdaNumbers::VERSION
|
6
|
+
spec.authors = ["Roberto W. P. Ribeiro"]
|
7
|
+
spec.email = ["rober.will@hotmail.com"]
|
8
|
+
|
9
|
+
spec.summary = %q{It converts a number to its equivalent in written words,
|
10
|
+
i.e. 123 to "cento e vinte três" or to "one hundred and twenty-three", and vice versa.}
|
11
|
+
spec.description = %q{It converts a number to its equivalent in written words,
|
12
|
+
i.e. 123 to "cento e vinte três" or to "one hundred and twenty-three", and vice versa.}
|
13
|
+
spec.homepage = "https://github.com/roberwil/ada_numbers_gem"
|
14
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
|
15
|
+
|
16
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
17
|
+
spec.metadata["source_code_uri"] = "https://github.com/roberwil/ada_numbers_gem"
|
18
|
+
spec.metadata["changelog_uri"] = "https://github.com/roberwil/ada_numbers_gem/blob/main/CHANGELOG.md"
|
19
|
+
|
20
|
+
# Specify which files should be added to the gem when it is released.
|
21
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
22
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
23
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
24
|
+
end
|
25
|
+
|
26
|
+
spec.bindir = "exe"
|
27
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
28
|
+
spec.require_paths = ["lib"]
|
29
|
+
spec.license = "MIT"
|
30
|
+
end
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "ada_numbers"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
module AdaNumbers
|
2
|
+
module WrittenNumber
|
3
|
+
class En
|
4
|
+
ZERO = "Zero"
|
5
|
+
ONE = "One"
|
6
|
+
TWO = "Two"
|
7
|
+
THREE = "Three"
|
8
|
+
FOUR = "Four"
|
9
|
+
FIVE = "Five"
|
10
|
+
SIX = "Six"
|
11
|
+
SEVEN = "Seven"
|
12
|
+
EIGHT = "Eight"
|
13
|
+
NINE = "Nine"
|
14
|
+
TEN = "Ten"
|
15
|
+
ELEVEN = "Eleven"
|
16
|
+
TWELVE = "Twelve"
|
17
|
+
THIRTEEN = "Thirteen"
|
18
|
+
FOURTEEN = "Fourteen"
|
19
|
+
FIFTEEN = "Fifteen"
|
20
|
+
SIXTEEN = "Sixteen"
|
21
|
+
SEVENTEEN = "Seventeen"
|
22
|
+
EIGHTEEN = "Eighteen"
|
23
|
+
NINETEEN = "Nineteen"
|
24
|
+
TWENTY = "Twenty"
|
25
|
+
THIRTY = "Thirty"
|
26
|
+
FORTY = "Forty"
|
27
|
+
FIFTY = "Fifty"
|
28
|
+
SIXTY = "Sixty"
|
29
|
+
SEVENTY = "Seventy"
|
30
|
+
EIGHTY = "Eighty"
|
31
|
+
NINETY = "Ninety"
|
32
|
+
HUNDRED = "Hundred"
|
33
|
+
THOUSAND = "Thousand"
|
34
|
+
MILLION = "Million"
|
35
|
+
THOUSAND_MILLION = "Thousand Million"
|
36
|
+
BILLION = "Billion"
|
37
|
+
TRILLION = "Trillion"
|
38
|
+
|
39
|
+
@@numbers_that_ignore_separator = [
|
40
|
+
HUNDRED, THOUSAND, MILLION,
|
41
|
+
THOUSAND_MILLION, BILLION, TRILLION
|
42
|
+
]
|
43
|
+
|
44
|
+
def self.numbers_that_ignore_separator; @@numbers_that_ignore_separator; end
|
45
|
+
|
46
|
+
@@unities_that_combine_with_separator = [
|
47
|
+
TWENTY, THIRTY, FORTY, FIFTY,
|
48
|
+
SIXTY, SEVENTY, EIGHTY, NINETY
|
49
|
+
]
|
50
|
+
|
51
|
+
def self.unities_that_combine_with_separator; @@unities_that_combine_with_separator; end
|
52
|
+
|
53
|
+
@@words_to_number_map = {
|
54
|
+
ZERO => 0, ONE => 1, TWO => 2, THREE => 3, FOUR => 4,
|
55
|
+
FIVE => 5, SIX => 6, SEVEN => 7, EIGHT => 8, NINE => 9,
|
56
|
+
TEN => 10, ELEVEN => 11, TWELVE => 12, THIRTEEN => 13, FOURTEEN => 14,
|
57
|
+
FIFTEEN => 15, SIXTEEN => 16, SEVENTEEN => 17, EIGHTEEN => 18, NINETEEN => 19,
|
58
|
+
TWENTY => 20, THIRTY => 30, FORTY => 40, FIFTY => 50, SIXTY => 60,
|
59
|
+
SEVENTY => 70, EIGHTY => 80, NINETY => 90, HUNDRED => 100, THOUSAND => 1e3.to_i,
|
60
|
+
MILLION => 1e6.to_i
|
61
|
+
}
|
62
|
+
|
63
|
+
def self.words_to_number_map; @@words_to_number_map; end
|
64
|
+
|
65
|
+
@@words_to_number_unities_and_tens_map = {
|
66
|
+
ZERO => 0, ONE => 1, TWO => 2, THREE => 3, FOUR => 4,
|
67
|
+
FIVE => 5, SIX => 6, SEVEN => 7, EIGHT => 8, NINE => 9,
|
68
|
+
TEN => 10, ELEVEN => 11, TWELVE => 12, THIRTEEN => 13, FOURTEEN => 14,
|
69
|
+
FIFTEEN => 15, SIXTEEN => 16, SEVENTEEN => 17, EIGHTEEN => 18, NINETEEN => 19,
|
70
|
+
TWENTY => 20, THIRTY => 30, FORTY => 40, FIFTY => 50, SIXTY => 60,
|
71
|
+
SEVENTY => 70, EIGHTY => 80, NINETY => 90
|
72
|
+
}
|
73
|
+
|
74
|
+
def self.words_to_number_unities_and_tens_map; @@words_to_number_unities_and_tens_map; end
|
75
|
+
|
76
|
+
@@words_to_number_map_long_scale = {
|
77
|
+
THOUSAND_MILLION => 1e9.to_i,
|
78
|
+
BILLION => 1e12.to_i
|
79
|
+
}
|
80
|
+
|
81
|
+
def self.words_to_number_map_long_scale; @@words_to_number_map_long_scale; end
|
82
|
+
|
83
|
+
@@words_to_number_map_short_scale = {
|
84
|
+
BILLION => 1e9.to_i,
|
85
|
+
TRILLION => 1e12.to_i
|
86
|
+
}
|
87
|
+
|
88
|
+
def self.words_to_number_map_short_scale; @@words_to_number_map_short_scale; end
|
89
|
+
|
90
|
+
@@not_to_combine_with_thousand = [
|
91
|
+
MILLION, BILLION, TRILLION
|
92
|
+
]
|
93
|
+
|
94
|
+
def self.not_to_combine_with_thousand; @@not_to_combine_with_thousand; end
|
95
|
+
|
96
|
+
@@numbers_to_words_map_unities = {
|
97
|
+
0 => ZERO, 1 => ONE, 2 => TWO , 3 => THREE, 4 => FOUR,
|
98
|
+
5 => FIVE, 6 => SIX, 7 => SEVEN, 8 => EIGHT, 9 => NINE
|
99
|
+
}
|
100
|
+
|
101
|
+
def self.numbers_to_words_map_unities; @@numbers_to_words_map_unities; end
|
102
|
+
|
103
|
+
@@numbers_to_words_map_tens = {
|
104
|
+
10 => TEN , 11 => ELEVEN , 12 => TWELVE , 13 => THIRTEEN, 14 => FOURTEEN,
|
105
|
+
15 => FIFTEEN, 16 => SIXTEEN, 17 => SEVENTEEN, 18 => EIGHTEEN, 19 => NINETEEN,
|
106
|
+
20 => TWENTY , 30 => THIRTY , 40 => FORTY , 50 => FIFTY , 60 => SIXTY ,
|
107
|
+
70 => SEVENTY, 80 => EIGHTY , 90 => NINETY
|
108
|
+
}
|
109
|
+
|
110
|
+
def self.numbers_to_words_map_tens; @@numbers_to_words_map_tens; end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
module AdaNumbers
|
2
|
+
module WrittenNumber
|
3
|
+
class Pt
|
4
|
+
ZERO = "Zero"
|
5
|
+
ONE = "Um"
|
6
|
+
TWO = "Dois"
|
7
|
+
THREE = "Três"
|
8
|
+
FOUR = "Quatro"
|
9
|
+
FIVE = "Cinco"
|
10
|
+
SIX = "Seis"
|
11
|
+
SEVEN = "Sete"
|
12
|
+
EIGHT = "Oito"
|
13
|
+
NINE = "Nove"
|
14
|
+
TEN = "Dez"
|
15
|
+
ELEVEN = "Onze"
|
16
|
+
TWELVE = "Doze"
|
17
|
+
THIRTEEN = "Treze"
|
18
|
+
FOURTEEN = "Catorze"
|
19
|
+
FIFTEEN = "Quinze"
|
20
|
+
SIXTEEN = "Dezasseis"
|
21
|
+
SEVENTEEN = "Dezassete"
|
22
|
+
EIGHTEEN = "Dezoito"
|
23
|
+
NINETEEN = "Dezanove"
|
24
|
+
TWENTY = "Vinte"
|
25
|
+
THIRTY = "Trinta"
|
26
|
+
FORTY = "Quarenta"
|
27
|
+
FIFTY = "Cinquenta"
|
28
|
+
SIXTY = "Sessenta"
|
29
|
+
SEVENTY = "Setenta"
|
30
|
+
EIGHTY = "Oitenta"
|
31
|
+
NINETY = "Noventa"
|
32
|
+
ONE_HUNDRED_SINGLE = "Cem"
|
33
|
+
ONE_HUNDRED = "Cento"
|
34
|
+
TWO_HUNDRED = "Duzentos"
|
35
|
+
THREE_HUNDRED = "Trezentos"
|
36
|
+
FOUR_HUNDRED = "Quatrocentos"
|
37
|
+
FIVE_HUNDRED = "Quinhentos"
|
38
|
+
SIX_HUNDRED = "Seiscentos"
|
39
|
+
SEVEN_HUNDRED = "Setecentos"
|
40
|
+
EIGHT_HUNDRED = "Oitocentos"
|
41
|
+
NINE_HUNDRED = "Novecentos"
|
42
|
+
THOUSAND = "Mil"
|
43
|
+
MILLION_SINGULAR = "Um Milhão"
|
44
|
+
MILLION_PLURAL = "Milhões"
|
45
|
+
THOUSAND_MILLION = "Mil Milhões"
|
46
|
+
BILLION_SINGULAR = "Um Bilião"
|
47
|
+
BILLION_PLURAL = "Biliões"
|
48
|
+
TRILLION_SINGULAR = "Um Trilião"
|
49
|
+
TRILLION_PLURAL = "Triliões"
|
50
|
+
|
51
|
+
@@numbers_that_ignore_separator = [
|
52
|
+
ONE_HUNDRED, TWO_HUNDRED, THREE_HUNDRED, FOUR_HUNDRED, FIVE_HUNDRED,
|
53
|
+
SIX_HUNDRED, SEVEN_HUNDRED, EIGHT_HUNDRED, NINE_HUNDRED, THOUSAND,
|
54
|
+
MILLION_SINGULAR, MILLION_PLURAL, THOUSAND_MILLION, BILLION_SINGULAR,
|
55
|
+
BILLION_PLURAL, TRILLION_SINGULAR, TRILLION_PLURAL
|
56
|
+
]
|
57
|
+
|
58
|
+
def self.numbers_that_ignore_separator; @@numbers_that_ignore_separator; end
|
59
|
+
|
60
|
+
@@words_to_number_map = {
|
61
|
+
ZERO => 0, ONE => 1, TWO => 2, THREE => 3,
|
62
|
+
FOUR => 4, FIVE => 5, SIX => 6, SEVEN => 7,
|
63
|
+
EIGHT => 8, NINE => 9, TEN => 10, ELEVEN => 11,
|
64
|
+
TWELVE => 12, THIRTEEN => 13, FOURTEEN => 14, FIFTEEN => 15,
|
65
|
+
SIXTEEN => 16, SEVENTEEN => 17, EIGHTEEN => 18, NINETEEN => 19,
|
66
|
+
TWENTY => 20, THIRTY => 30, FORTY => 40, FIFTY => 50,
|
67
|
+
SIXTY => 60, SEVENTY => 70, EIGHTY => 80, NINETY => 90,
|
68
|
+
ONE_HUNDRED => 100, ONE_HUNDRED_SINGLE => 100, TWO_HUNDRED => 200, THREE_HUNDRED => 300,
|
69
|
+
FOUR_HUNDRED => 400, FIVE_HUNDRED => 500, SIX_HUNDRED => 600, SEVEN_HUNDRED => 700,
|
70
|
+
EIGHT_HUNDRED => 800, NINE_HUNDRED => 900, THOUSAND => 1e3.to_i, MILLION_SINGULAR => 1e6.to_i,
|
71
|
+
MILLION_PLURAL => 1e6.to_i
|
72
|
+
}
|
73
|
+
|
74
|
+
def self.words_to_number_map; @@words_to_number_map; end
|
75
|
+
|
76
|
+
@@words_to_number_map_long_scale = {
|
77
|
+
THOUSAND_MILLION => 1e9.to_i,
|
78
|
+
BILLION_SINGULAR => 1e12.to_i,
|
79
|
+
BILLION_PLURAL => 1e12.to_i
|
80
|
+
}
|
81
|
+
|
82
|
+
def self.words_to_number_map_long_scale; @@words_to_number_map_long_scale; end
|
83
|
+
|
84
|
+
@@words_to_number_map_short_scale = {
|
85
|
+
BILLION_SINGULAR => 1e9.to_i,
|
86
|
+
BILLION_PLURAL => 1e9.to_i,
|
87
|
+
TRILLION_SINGULAR => 1e12.to_i,
|
88
|
+
TRILLION_PLURAL => 1e12.to_i
|
89
|
+
}
|
90
|
+
|
91
|
+
def self.words_to_number_map_short_scale; @@words_to_number_map_short_scale; end
|
92
|
+
|
93
|
+
@@not_to_combine_with_thousand = [
|
94
|
+
MILLION_SINGULAR, BILLION_PLURAL, TRILLION_PLURAL
|
95
|
+
]
|
96
|
+
|
97
|
+
def self.not_to_combine_with_thousand; @@not_to_combine_with_thousand; end
|
98
|
+
|
99
|
+
@@numbers_to_words_map_unities = {
|
100
|
+
0 => ZERO, 1 => ONE, 2 => TWO , 3 => THREE, 4 => FOUR,
|
101
|
+
5 => FIVE, 6 => SIX, 7 => SEVEN, 8 => EIGHT, 9 => NINE
|
102
|
+
}
|
103
|
+
|
104
|
+
def self.numbers_to_words_map_unities; @@numbers_to_words_map_unities; end
|
105
|
+
|
106
|
+
@@numbers_to_words_map_tens = {
|
107
|
+
10 => TEN , 11 => ELEVEN , 12 => TWELVE , 13 => THIRTEEN, 14 => FOURTEEN,
|
108
|
+
15 => FIFTEEN, 16 => SIXTEEN, 17 => SEVENTEEN, 18 => EIGHTEEN, 19 => NINETEEN,
|
109
|
+
20 => TWENTY , 30 => THIRTY , 40 => FORTY , 50 => FIFTY , 60 => SIXTY ,
|
110
|
+
70 => SEVENTY, 80 => EIGHTY , 90 => NINETY
|
111
|
+
}
|
112
|
+
|
113
|
+
def self.numbers_to_words_map_tens; @@numbers_to_words_map_tens; end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,185 @@
|
|
1
|
+
require_relative '../../utilities/integer_extensions'
|
2
|
+
require_relative '../../utilities/hash_extensions'
|
3
|
+
require_relative '../../utilities/settings'
|
4
|
+
require_relative '../../utilities/number_category'
|
5
|
+
|
6
|
+
require_relative '../../constants/en/written_numbers'
|
7
|
+
require_relative '../../constants/en/separators'
|
8
|
+
require_relative '../../constants/message'
|
9
|
+
|
10
|
+
module AdaNumbers
|
11
|
+
module NumberToWordsConverter
|
12
|
+
class En
|
13
|
+
@@use_short_scale = false
|
14
|
+
@@number_tokens = []
|
15
|
+
|
16
|
+
def self.convert(number)
|
17
|
+
return convert_integer(number) if number.class == Integer
|
18
|
+
return convert_float(number)
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def self.convert_integer(number)
|
24
|
+
return Message::UNSUPPORTED if number.number_of_digits > Settings::Parameters::DIGITS_LIMIT
|
25
|
+
|
26
|
+
select_scale
|
27
|
+
@@number_tokens.clear
|
28
|
+
return resolve_number number
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.convert_float(number)
|
32
|
+
select_scale
|
33
|
+
|
34
|
+
str_number = number.to_s.split '.'
|
35
|
+
|
36
|
+
str_integer_part = str_number.first
|
37
|
+
str_decimal_part = str_number.size == 1 ? "0" : str_number.last
|
38
|
+
|
39
|
+
return Message::UNSUPPORTED if str_integer_part.size > Settings::Parameters::DIGITS_LIMIT || str_decimal_part.size > Settings::Parameters::DIGITS_LIMIT
|
40
|
+
|
41
|
+
whole_part = str_integer_part.to_i
|
42
|
+
decimal_part = str_decimal_part.to_i
|
43
|
+
|
44
|
+
@@number_tokens.clear
|
45
|
+
result = resolve_number whole_part
|
46
|
+
|
47
|
+
return result if decimal_part == 0
|
48
|
+
|
49
|
+
result += " #{Separator::En::DECIMAL_SEPARATOR.downcase} "
|
50
|
+
# just aggregating the zeros
|
51
|
+
result += str_decimal_part.split('').
|
52
|
+
take_while { |c| c == "0" }.
|
53
|
+
collect { |c| WrittenNumber::En::ZERO }.
|
54
|
+
join ' '
|
55
|
+
|
56
|
+
@@number_tokens.clear
|
57
|
+
result += result[-1] == ' ' ? resolve_number(decimal_part) :
|
58
|
+
" #{resolve_number(decimal_part)}"
|
59
|
+
|
60
|
+
return result
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.select_scale
|
64
|
+
@@use_short_scale = Settings.scale == Settings::Parameters::SCALES[:short]
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.resolve_number(number)
|
68
|
+
result = ''
|
69
|
+
number_category = number.category
|
70
|
+
|
71
|
+
case number_category
|
72
|
+
when NumberCategory::UNITY
|
73
|
+
result = unities number
|
74
|
+
when NumberCategory::TEN
|
75
|
+
result = tens number
|
76
|
+
when NumberCategory::HUNDRED
|
77
|
+
result = hundreds number
|
78
|
+
when NumberCategory::THOUSAND
|
79
|
+
result = thousands number
|
80
|
+
when NumberCategory::MILLION
|
81
|
+
result = millions number
|
82
|
+
when NumberCategory::THOUSAND_MILLIONS
|
83
|
+
result = thousand_millions number
|
84
|
+
when NumberCategory::BILLION
|
85
|
+
result = billions number
|
86
|
+
end
|
87
|
+
|
88
|
+
if result.empty?
|
89
|
+
str_number = number.to_s
|
90
|
+
bridge = number.bridge
|
91
|
+
|
92
|
+
first_digits = (str_number[0...bridge] + '0' * number_category).to_i
|
93
|
+
other_digits = (str_number[bridge..-1]).to_i
|
94
|
+
|
95
|
+
resolve_number first_digits
|
96
|
+
resolve_number other_digits
|
97
|
+
else
|
98
|
+
@@number_tokens << result
|
99
|
+
end
|
100
|
+
|
101
|
+
add_separators_to_number @@number_tokens
|
102
|
+
end
|
103
|
+
|
104
|
+
def self.unity_or_ten?(number)
|
105
|
+
result = !WrittenNumber::En.words_to_number_unities_and_tens_map.resolve(number).nil?
|
106
|
+
result ? result : number.include?(Separator::En::DASH)
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.add_separators_to_number(number_tokens)
|
110
|
+
result = number_tokens.first
|
111
|
+
|
112
|
+
(1...number_tokens.size).each do |cursor|
|
113
|
+
current_token = number_tokens[cursor]
|
114
|
+
|
115
|
+
is_hundred = cursor + 1 < number_tokens.size && unity_or_ten?(current_token) &&
|
116
|
+
(number_tokens[cursor + 1] == WrittenNumber::En::HUNDRED ||
|
117
|
+
number_tokens[cursor + 1] == WrittenNumber::En::THOUSAND ||
|
118
|
+
number_tokens[cursor + 1] == WrittenNumber::En::MILLION ||
|
119
|
+
number_tokens[cursor + 1] == WrittenNumber::En::THOUSAND_MILLION ||
|
120
|
+
number_tokens[cursor + 1] == WrittenNumber::En::BILLION ||
|
121
|
+
number_tokens[cursor + 1] == WrittenNumber::En::TRILLION)
|
122
|
+
|
123
|
+
add_comma = cursor > 1 && is_hundred
|
124
|
+
no_separator = WrittenNumber::En.numbers_that_ignore_separator.include?(current_token) || is_hundred
|
125
|
+
|
126
|
+
if (add_comma)
|
127
|
+
result += "#{Separator::En::COMMA} #{current_token}"
|
128
|
+
elsif no_separator
|
129
|
+
result += " #{current_token}"
|
130
|
+
else
|
131
|
+
result += " #{Separator::En::NUMBERS_SEPARATOR.downcase} #{current_token}"
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
return result
|
136
|
+
end
|
137
|
+
|
138
|
+
def self.unities(number)
|
139
|
+
WrittenNumber::En.numbers_to_words_map_unities.resolve number
|
140
|
+
end
|
141
|
+
|
142
|
+
def self.tens(number)
|
143
|
+
result = WrittenNumber::En.numbers_to_words_map_tens.resolve number
|
144
|
+
return result if result != ''
|
145
|
+
|
146
|
+
bridge = number.bridge
|
147
|
+
ten = number.to_s[0...bridge].to_i * 10
|
148
|
+
unity = number.to_s[bridge..-1].to_i
|
149
|
+
|
150
|
+
result = "#{tens(ten)}#{Separator::En::DASH}#{unities(unity).downcase}"
|
151
|
+
result
|
152
|
+
end
|
153
|
+
|
154
|
+
def self.hundreds(number)
|
155
|
+
evaluate_hundreds_and_over number, 1e2.to_i, WrittenNumber::En::HUNDRED
|
156
|
+
end
|
157
|
+
|
158
|
+
def self.thousands(number)
|
159
|
+
evaluate_hundreds_and_over number, 1e3.to_i, WrittenNumber::En::THOUSAND
|
160
|
+
end
|
161
|
+
|
162
|
+
def self.millions(number)
|
163
|
+
evaluate_hundreds_and_over number, 1e6.to_i, WrittenNumber::En::MILLION
|
164
|
+
end
|
165
|
+
|
166
|
+
def self.thousand_millions(number)
|
167
|
+
qualifier = (@@use_short_scale ? WrittenNumber::En::BILLION : WrittenNumber::En::THOUSAND_MILLION)
|
168
|
+
evaluate_hundreds_and_over number, 1e9.to_i, qualifier
|
169
|
+
end
|
170
|
+
|
171
|
+
def self.billions(number)
|
172
|
+
qualifier = (@@use_short_scale ? WrittenNumber::En::TRILLION : WrittenNumber::En::BILLION)
|
173
|
+
evaluate_hundreds_and_over number, 1e12.to_i, qualifier
|
174
|
+
end
|
175
|
+
|
176
|
+
def self.evaluate_hundreds_and_over(number, category_identifier, qualifier)
|
177
|
+
return '' if number % category_identifier != 0
|
178
|
+
|
179
|
+
partial_number = number.to_s[0...number.bridge].to_i
|
180
|
+
resolve_number partial_number
|
181
|
+
return qualifier
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|