ada_numbers 1.0.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.
- 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
|