numbers_in_words 0.4.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +1 -0
- data/.rspec +1 -0
- data/.rubocop.yml +35 -1148
- data/.travis.yml +14 -4
- data/Gemfile +4 -1
- data/README.md +6 -44
- data/Rakefile +3 -1
- data/lib/numbers_in_words.rb +44 -19
- data/lib/numbers_in_words/duck_punch.rb +12 -8
- data/lib/numbers_in_words/exceptional_numbers.rb +115 -0
- data/lib/numbers_in_words/fraction.rb +136 -0
- data/lib/numbers_in_words/number_group.rb +34 -21
- data/lib/numbers_in_words/parsing/fraction_parsing.rb +34 -0
- data/lib/numbers_in_words/parsing/number_parser.rb +98 -0
- data/lib/numbers_in_words/parsing/pair_parsing.rb +64 -0
- data/lib/numbers_in_words/parsing/parse_fractions.rb +45 -0
- data/lib/numbers_in_words/parsing/parse_individual_number.rb +68 -0
- data/lib/numbers_in_words/parsing/parse_status.rb +17 -0
- data/lib/numbers_in_words/parsing/special.rb +67 -0
- data/lib/numbers_in_words/parsing/to_number.rb +77 -0
- data/lib/numbers_in_words/powers_of_ten.rb +49 -0
- data/lib/numbers_in_words/to_word.rb +78 -13
- data/lib/numbers_in_words/version.rb +3 -1
- data/lib/numbers_in_words/writer.rb +69 -0
- data/numbers_in_words.gemspec +14 -13
- data/spec/exceptional_numbers_spec.rb +26 -0
- data/spec/fraction_spec.rb +152 -0
- data/spec/fractions_spec.rb +31 -0
- data/spec/non_monkey_patch_spec.rb +39 -20
- data/spec/number_group_spec.rb +12 -12
- data/spec/number_parser_spec.rb +31 -0
- data/spec/numbers_in_words_spec.rb +63 -70
- data/spec/numerical_strings_spec.rb +28 -12
- data/spec/spec_helper.rb +23 -4
- data/spec/to_word_spec.rb +18 -0
- data/spec/words_in_numbers_spec.rb +132 -125
- data/spec/writer_spec.rb +26 -0
- data/spec/years_spec.rb +23 -13
- metadata +43 -27
- data/lib/numbers_in_words/english/constants.rb +0 -124
- data/lib/numbers_in_words/english/language_writer_english.rb +0 -116
- data/lib/numbers_in_words/language_writer.rb +0 -30
- data/lib/numbers_in_words/number_parser.rb +0 -135
- data/lib/numbers_in_words/to_number.rb +0 -88
- data/spec/language_writer_spec.rb +0 -23
data/spec/writer_spec.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe NumbersInWords::Writer do
|
4
|
+
let(:number) { 2_111 }
|
5
|
+
let(:writer) { described_class.new(number) }
|
6
|
+
|
7
|
+
it 'should display numbers grouped' do
|
8
|
+
count = 0
|
9
|
+
|
10
|
+
writer.group_words(3) do |power, name, digits|
|
11
|
+
case count
|
12
|
+
when 0
|
13
|
+
expect(power).to eq(3)
|
14
|
+
expect(name).to eq('thousand')
|
15
|
+
expect(digits).to eq(2)
|
16
|
+
when 1
|
17
|
+
expect(power).to eq(0)
|
18
|
+
expect(name).to eq('one')
|
19
|
+
expect(digits).to eq(111)
|
20
|
+
end
|
21
|
+
count += 1
|
22
|
+
end
|
23
|
+
|
24
|
+
expect(count).to eq 2
|
25
|
+
end
|
26
|
+
end
|
data/spec/years_spec.rb
CHANGED
@@ -1,17 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require './spec/spec_helper'
|
2
4
|
|
3
|
-
describe
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
5
|
+
describe NumbersInWords::NumericExtension do
|
6
|
+
YEARS = {
|
7
|
+
'thirteen hundred' => 13_00,
|
8
|
+
'twenty-two hundred' => 22_00,
|
9
|
+
'twenty-two hundred and five' => 22_05,
|
10
|
+
'fifteen sixteen seventeen' => 151_617,
|
11
|
+
'forty-nine ninety-eight forty-seven seventy-nine' => 49_984_779,
|
12
|
+
'one fifty' => 150,
|
13
|
+
'two fifty' => 250,
|
14
|
+
'three fifty' => 350,
|
15
|
+
'one point fifty-six fifty-seven' => 1.5657,
|
16
|
+
'one three forty-seven' => 1347,
|
17
|
+
'one three five-point forty-seven' => 135.47,
|
18
|
+
'one ten sixty-three' => 11_063,
|
19
|
+
'one nineteen ten oh five' => 1_191_005
|
20
|
+
}.freeze
|
16
21
|
|
22
|
+
YEARS.each do |k, v|
|
23
|
+
it do
|
24
|
+
expect(k.in_numbers).to eql(v)
|
25
|
+
end
|
26
|
+
end
|
17
27
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: numbers_in_words
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mark Burns
|
@@ -9,42 +9,41 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2020-11-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
15
|
+
name: rspec
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
-
- - "
|
18
|
+
- - "~>"
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version:
|
21
|
-
type: :
|
20
|
+
version: 3.4.0
|
21
|
+
type: :development
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
|
-
- - "
|
25
|
+
- - "~>"
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version:
|
27
|
+
version: 3.4.0
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
|
-
name:
|
29
|
+
name: rubocop
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
31
31
|
requirements:
|
32
|
-
- - "
|
32
|
+
- - ">="
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version:
|
34
|
+
version: '0'
|
35
35
|
type: :development
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
|
-
- - "
|
39
|
+
- - ">="
|
40
40
|
- !ruby/object:Gem::Version
|
41
|
-
version:
|
42
|
-
description:
|
41
|
+
version: '0'
|
42
|
+
description: convert written numbers into Integers and vice-versa
|
43
43
|
email:
|
44
44
|
- markthedeveloper@gmail.com
|
45
45
|
- dimidd@gmail.com
|
46
|
-
executables:
|
47
|
-
- spec
|
46
|
+
executables: []
|
48
47
|
extensions: []
|
49
48
|
extra_rdoc_files: []
|
50
49
|
files:
|
@@ -54,28 +53,41 @@ files:
|
|
54
53
|
- ".rubocop.yml"
|
55
54
|
- ".travis.yml"
|
56
55
|
- Gemfile
|
56
|
+
- Gemfile.lock
|
57
57
|
- LICENSE.txt
|
58
58
|
- README.md
|
59
59
|
- Rakefile
|
60
60
|
- bin/spec
|
61
61
|
- lib/numbers_in_words.rb
|
62
62
|
- lib/numbers_in_words/duck_punch.rb
|
63
|
-
- lib/numbers_in_words/
|
64
|
-
- lib/numbers_in_words/
|
65
|
-
- lib/numbers_in_words/language_writer.rb
|
63
|
+
- lib/numbers_in_words/exceptional_numbers.rb
|
64
|
+
- lib/numbers_in_words/fraction.rb
|
66
65
|
- lib/numbers_in_words/number_group.rb
|
67
|
-
- lib/numbers_in_words/
|
68
|
-
- lib/numbers_in_words/
|
66
|
+
- lib/numbers_in_words/parsing/fraction_parsing.rb
|
67
|
+
- lib/numbers_in_words/parsing/number_parser.rb
|
68
|
+
- lib/numbers_in_words/parsing/pair_parsing.rb
|
69
|
+
- lib/numbers_in_words/parsing/parse_fractions.rb
|
70
|
+
- lib/numbers_in_words/parsing/parse_individual_number.rb
|
71
|
+
- lib/numbers_in_words/parsing/parse_status.rb
|
72
|
+
- lib/numbers_in_words/parsing/special.rb
|
73
|
+
- lib/numbers_in_words/parsing/to_number.rb
|
74
|
+
- lib/numbers_in_words/powers_of_ten.rb
|
69
75
|
- lib/numbers_in_words/to_word.rb
|
70
76
|
- lib/numbers_in_words/version.rb
|
77
|
+
- lib/numbers_in_words/writer.rb
|
71
78
|
- numbers_in_words.gemspec
|
72
|
-
- spec/
|
79
|
+
- spec/exceptional_numbers_spec.rb
|
80
|
+
- spec/fraction_spec.rb
|
81
|
+
- spec/fractions_spec.rb
|
73
82
|
- spec/non_monkey_patch_spec.rb
|
74
83
|
- spec/number_group_spec.rb
|
84
|
+
- spec/number_parser_spec.rb
|
75
85
|
- spec/numbers_in_words_spec.rb
|
76
86
|
- spec/numerical_strings_spec.rb
|
77
87
|
- spec/spec_helper.rb
|
88
|
+
- spec/to_word_spec.rb
|
78
89
|
- spec/words_in_numbers_spec.rb
|
90
|
+
- spec/writer_spec.rb
|
79
91
|
- spec/years_spec.rb
|
80
92
|
homepage: http://github.com/markburns/numbers_in_words
|
81
93
|
licenses: []
|
@@ -95,18 +107,22 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
95
107
|
- !ruby/object:Gem::Version
|
96
108
|
version: '0'
|
97
109
|
requirements: []
|
98
|
-
|
99
|
-
rubygems_version: 2.4.5
|
110
|
+
rubygems_version: 3.0.3
|
100
111
|
signing_key:
|
101
112
|
specification_version: 4
|
102
|
-
summary: 'Example:
|
103
|
-
point eight"
|
113
|
+
summary: 'Example: NumbersInWords.in_words(123) # => "one hundred and twenty three",
|
114
|
+
NumbersInWords.in_numbers("seventy-five point eight") # = > 75.8'
|
104
115
|
test_files:
|
105
|
-
- spec/
|
116
|
+
- spec/exceptional_numbers_spec.rb
|
117
|
+
- spec/fraction_spec.rb
|
118
|
+
- spec/fractions_spec.rb
|
106
119
|
- spec/non_monkey_patch_spec.rb
|
107
120
|
- spec/number_group_spec.rb
|
121
|
+
- spec/number_parser_spec.rb
|
108
122
|
- spec/numbers_in_words_spec.rb
|
109
123
|
- spec/numerical_strings_spec.rb
|
110
124
|
- spec/spec_helper.rb
|
125
|
+
- spec/to_word_spec.rb
|
111
126
|
- spec/words_in_numbers_spec.rb
|
127
|
+
- spec/writer_spec.rb
|
112
128
|
- spec/years_spec.rb
|
@@ -1,124 +0,0 @@
|
|
1
|
-
module NumbersInWords
|
2
|
-
module English
|
3
|
-
|
4
|
-
def self.canonize(w)
|
5
|
-
aliases = {
|
6
|
-
"oh" => "zero"
|
7
|
-
}
|
8
|
-
canon = aliases[w]
|
9
|
-
return canon ? canon : w
|
10
|
-
end
|
11
|
-
|
12
|
-
def self.exceptions
|
13
|
-
{
|
14
|
-
0 => "zero",
|
15
|
-
1 => "one",
|
16
|
-
2 => "two",
|
17
|
-
3 => "three",
|
18
|
-
4 => "four",
|
19
|
-
5 => "five",
|
20
|
-
6 => "six",
|
21
|
-
7 => "seven",
|
22
|
-
8 => "eight",
|
23
|
-
9 => "nine",
|
24
|
-
|
25
|
-
10 => "ten",
|
26
|
-
11 => "eleven",
|
27
|
-
12 => "twelve",
|
28
|
-
|
29
|
-
13 => "thirteen",
|
30
|
-
14 => "fourteen",
|
31
|
-
15 => "fifteen",
|
32
|
-
16 => "sixteen" ,
|
33
|
-
17 => "seventeen",
|
34
|
-
18 => "eighteen",
|
35
|
-
19 => "nineteen",
|
36
|
-
|
37
|
-
20 => "twenty",
|
38
|
-
30 => "thirty",
|
39
|
-
40 => "forty",
|
40
|
-
50 => "fifty",
|
41
|
-
60 => "sixty",
|
42
|
-
70 => "seventy",
|
43
|
-
80 => "eighty",
|
44
|
-
90 => "ninety"
|
45
|
-
}
|
46
|
-
end
|
47
|
-
|
48
|
-
def self.swap_keys hsh
|
49
|
-
hsh.inject({}){|h,(k,v)| h[v]=k; h}
|
50
|
-
end
|
51
|
-
|
52
|
-
def self.powers_of_ten
|
53
|
-
{
|
54
|
-
0 => "one",
|
55
|
-
1 => "ten",
|
56
|
-
2 => "hundred",
|
57
|
-
3 => "thousand",
|
58
|
-
6 => "million",
|
59
|
-
9 => "billion",
|
60
|
-
12 => "trillion",
|
61
|
-
15 => "quadrillion",
|
62
|
-
18 => "quintillion",
|
63
|
-
21 => "sextillion",
|
64
|
-
24 => "septillion",
|
65
|
-
27 => "octillion",
|
66
|
-
30 => "nonillion",
|
67
|
-
33 => "decillion",
|
68
|
-
36 => "undecillion",
|
69
|
-
39 => "duodecillion",
|
70
|
-
42 => "tredecillion",
|
71
|
-
45 => "quattuordecillion",
|
72
|
-
48 => "quindecillion",
|
73
|
-
51 => "sexdecillion",
|
74
|
-
54 => "septendecillion",
|
75
|
-
57 => "octodecillion",
|
76
|
-
60 => "novemdecillion",
|
77
|
-
63 => "vigintillion",
|
78
|
-
66 => "unvigintillion",
|
79
|
-
69 => "duovigintillion",
|
80
|
-
72 => "trevigintillion",
|
81
|
-
75 => "quattuorvigintillion",
|
82
|
-
78 => "quinvigintillion",
|
83
|
-
81 => "sexvigintillion",
|
84
|
-
84 => "septenvigintillion",
|
85
|
-
87 => "octovigintillion",
|
86
|
-
90 => "novemvigintillion",
|
87
|
-
93 => "trigintillion",
|
88
|
-
96 => "untrigintillion",
|
89
|
-
99 => "duotrigintillion",
|
90
|
-
100 => "googol"
|
91
|
-
}
|
92
|
-
end
|
93
|
-
|
94
|
-
def self.exceptions_to_i
|
95
|
-
swap_keys exceptions
|
96
|
-
end
|
97
|
-
|
98
|
-
def self.powers_of_ten_to_i
|
99
|
-
swap_keys powers_of_ten
|
100
|
-
end
|
101
|
-
|
102
|
-
POWERS_RX = Regexp.union(powers_of_ten.values[1..-1])
|
103
|
-
|
104
|
-
def self.check_mixed(txt)
|
105
|
-
mixed = txt.match /^(-?\d+(.\d+)?) (#{POWERS_RX}s?)$/
|
106
|
-
if mixed && mixed[1] && mixed[3]
|
107
|
-
matches = [mixed[1], mixed[3]].map{ |m| NumbersInWords.in_numbers m }
|
108
|
-
return matches.reduce(&:*)
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
def self.check_one(txt)
|
113
|
-
one = txt.match /^one (#{POWERS_RX})$/
|
114
|
-
end
|
115
|
-
|
116
|
-
def self.strip_minus(txt)
|
117
|
-
stripped = txt.gsub(/^minus/, "") if txt =~ /^minus/
|
118
|
-
end
|
119
|
-
|
120
|
-
def self.check_decimal(txt)
|
121
|
-
txt.match(/\spoint\s/)
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
@@ -1,116 +0,0 @@
|
|
1
|
-
module NumbersInWords
|
2
|
-
module English
|
3
|
-
class LanguageWriterEnglish < LanguageWriter
|
4
|
-
delegate :to_i, to: :that
|
5
|
-
|
6
|
-
def initialize that
|
7
|
-
super that
|
8
|
-
@language = "English"
|
9
|
-
end
|
10
|
-
|
11
|
-
def negative
|
12
|
-
"minus " + NumbersInWords.in_words(-@that)
|
13
|
-
end
|
14
|
-
|
15
|
-
def in_words
|
16
|
-
v = handle_exception
|
17
|
-
return v if v
|
18
|
-
|
19
|
-
in_decimals = decimals
|
20
|
-
return in_decimals if in_decimals
|
21
|
-
|
22
|
-
number = to_i
|
23
|
-
|
24
|
-
return negative() if number < 0
|
25
|
-
|
26
|
-
output = if number.to_s.length == 2 #20-99
|
27
|
-
handle_tens(number)
|
28
|
-
else
|
29
|
-
write() #longer numbers
|
30
|
-
end
|
31
|
-
|
32
|
-
output.strip
|
33
|
-
end
|
34
|
-
|
35
|
-
def handle_tens(number)
|
36
|
-
output = ""
|
37
|
-
|
38
|
-
tens = (number/10).round*10 #write the tens
|
39
|
-
|
40
|
-
output << exceptions[tens] # e.g. eighty
|
41
|
-
|
42
|
-
digit = number - tens #write the digits
|
43
|
-
|
44
|
-
unless digit == 0
|
45
|
-
output << " " + NumbersInWords.in_words(digit)
|
46
|
-
end
|
47
|
-
|
48
|
-
output
|
49
|
-
end
|
50
|
-
|
51
|
-
def handle_exception
|
52
|
-
exceptions[@that] if @that.is_a?(Integer) and exceptions[@that]
|
53
|
-
end
|
54
|
-
|
55
|
-
|
56
|
-
def write
|
57
|
-
length = @that.to_s.length
|
58
|
-
output =
|
59
|
-
if length == 3
|
60
|
-
#e.g. 113 splits into "one hundred" and "thirteen"
|
61
|
-
write_groups(2)
|
62
|
-
|
63
|
-
#more than one hundred less than one googol
|
64
|
-
elsif length < LENGTH_OF_GOOGOL
|
65
|
-
write_groups(3)
|
66
|
-
|
67
|
-
elsif length >= LENGTH_OF_GOOGOL
|
68
|
-
write_googols
|
69
|
-
end
|
70
|
-
output.strip
|
71
|
-
end
|
72
|
-
|
73
|
-
def decimals
|
74
|
-
int, decimals = NumberGroup.new(@that).split_decimals
|
75
|
-
if int
|
76
|
-
out = NumbersInWords.in_words(int) + " point "
|
77
|
-
decimals.each do |decimal|
|
78
|
-
out << NumbersInWords.in_words(decimal.to_i) + " "
|
79
|
-
end
|
80
|
-
out.strip
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
private
|
85
|
-
|
86
|
-
def write_googols
|
87
|
-
googols, remainder = NumberGroup.new(@that).split_googols
|
88
|
-
output = ""
|
89
|
-
|
90
|
-
output << " " + NumbersInWords.in_words(googols) + " googol"
|
91
|
-
if remainder > 0
|
92
|
-
prefix = " "
|
93
|
-
prefix << "and " if remainder < 100
|
94
|
-
output << prefix + NumbersInWords.in_words(remainder)
|
95
|
-
end
|
96
|
-
|
97
|
-
output
|
98
|
-
end
|
99
|
-
|
100
|
-
def write_groups group
|
101
|
-
#e.g. 113 splits into "one hundred" and "thirteen"
|
102
|
-
output = ""
|
103
|
-
group_words(group) do |power, name, digits|
|
104
|
-
if digits > 0
|
105
|
-
prefix = " "
|
106
|
-
#no and between thousands and hundreds
|
107
|
-
prefix << "and " if power == 0 and digits < 100
|
108
|
-
output << prefix + NumbersInWords.in_words(digits)
|
109
|
-
output << prefix + name unless power == 0
|
110
|
-
end
|
111
|
-
end
|
112
|
-
output
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
end
|