numbers_in_words 0.4.0 → 0.4.1
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 +5 -5
- data/.gitignore +1 -0
- data/.rspec +1 -0
- data/.rubocop.yml +35 -1148
- data/.travis.yml +4 -4
- data/Gemfile +3 -1
- data/README.md +5 -43
- data/Rakefile +3 -1
- data/lib/numbers_in_words.rb +43 -19
- data/lib/numbers_in_words/duck_punch.rb +12 -8
- data/lib/numbers_in_words/exceptional_numbers.rb +119 -0
- data/lib/numbers_in_words/fraction.rb +151 -0
- data/lib/numbers_in_words/number_group.rb +34 -21
- 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/to_number.rb +159 -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 +132 -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 +63 -0
- data/spec/numbers_in_words_spec.rb +56 -69
- data/spec/numerical_strings_spec.rb +28 -12
- data/spec/spec_helper.rb +2 -4
- data/spec/to_word_spec.rb +18 -0
- data/spec/words_in_numbers_spec.rb +130 -125
- data/spec/writer_spec.rb +26 -0
- data/spec/years_spec.rb +23 -13
- metadata +40 -25
- 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
@@ -1,135 +0,0 @@
|
|
1
|
-
module NumbersInWords::NumberParser
|
2
|
-
SCALES_N = [100, 1000, 1000000, 1000000000, 1000000000000, 10**100]
|
3
|
-
# Example: 364,895,457,898
|
4
|
-
#three hundred and sixty four billion eight hundred and ninety five million
|
5
|
-
#four hundred and fifty seven thousand eight hundred and ninety eight
|
6
|
-
#
|
7
|
-
#3 100 60 4 10^9, 8 100 90 5 10^6, 4 100 50 7 1000, 8 100 90 8
|
8
|
-
# memory answer
|
9
|
-
#x1. 3 add to memory because answer and memory are zero 3 0
|
10
|
-
#x2. memory * 100 (because memory<100) 300 0
|
11
|
-
#x3. 60 add to memory because memory > 60 360 0
|
12
|
-
#x3. 4 add to memory because memory > 4 364 0
|
13
|
-
#x4. multiply memory by 10^9 because memory < power of ten 364*10^9 0
|
14
|
-
#x5. add memory to answer (and reset)memory > 8 (memory pow of ten > 2) 0 364*10^9
|
15
|
-
#x6. 8 add to memory because not finished 8 ''
|
16
|
-
#x7. multiply memory by 100 because memory < 100 800 ''
|
17
|
-
#x8. add 90 to memory because memory > 90 890 ''
|
18
|
-
#x9. add 5 to memory because memory > 5 895 ''
|
19
|
-
#x10. multiply memory by 10^6 because memory < power of ten 895*10^6 ''
|
20
|
-
#x11. add memory to answer (and reset) because memory power ten > 2 0 364895 * 10^6
|
21
|
-
#x12. 4 add to memory because not finished 4 ''
|
22
|
-
#x13. memory * 100 because memory < 100 400 ''
|
23
|
-
#x14. memory + 50 because memory > 50 450 ''
|
24
|
-
#x15. memory + 7 because memory > 7 457 ''
|
25
|
-
#x16. memory * 1000 because memory < 1000 457000 ''
|
26
|
-
#x17. add memory to answer (and reset)memory > 8 (memory pow of ten > 2) 0 364895457000
|
27
|
-
#x18. 8 add to memory because not finished 8 ''
|
28
|
-
#x19. memory * 100 because memory < 100 800 ''
|
29
|
-
#x14. memory + 90 because memory > 90 890 ''
|
30
|
-
#x15. memory + 8 because memory > 8 898 ''
|
31
|
-
#16. finished so add memory to answer
|
32
|
-
|
33
|
-
#Example
|
34
|
-
#2001
|
35
|
-
#two thousand and one
|
36
|
-
#2 1000 1
|
37
|
-
# memory answer
|
38
|
-
#1. add 2 to memory because first 2 0
|
39
|
-
#2. multiply memory by 1000 because memory < 1000 2000 0
|
40
|
-
#3. add memory to answer,reset, because power of ten>2 0 2000
|
41
|
-
#4. add 1 to memory 1 2000
|
42
|
-
#5. finish - add memory to answer 0 2001
|
43
|
-
def parse_ints(integers)
|
44
|
-
memory = 0
|
45
|
-
answer = 0
|
46
|
-
reset = true #reset each time memory is reset
|
47
|
-
integers.each do |integer|
|
48
|
-
if reset
|
49
|
-
reset = false
|
50
|
-
memory += integer
|
51
|
-
else
|
52
|
-
#x4. multiply memory by 10^9 because memory < power of ten
|
53
|
-
if power_of_ten?(integer)
|
54
|
-
if power_of_ten(integer)> 2
|
55
|
-
memory *= integer
|
56
|
-
#17. add memory to answer (and reset) (memory pow of ten > 2)
|
57
|
-
answer += memory
|
58
|
-
memory = 0
|
59
|
-
reset = true
|
60
|
-
end
|
61
|
-
end
|
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 parse(integers, only_compress = false)
|
73
|
-
if integers.length < 2
|
74
|
-
return integers if only_compress
|
75
|
-
return integers.empty? ? 0 : integers[0]
|
76
|
-
end
|
77
|
-
if [] == (SCALES_N & integers)
|
78
|
-
return pair_parse(integers, only_compress)
|
79
|
-
end
|
80
|
-
|
81
|
-
parse_ints(integers)
|
82
|
-
end
|
83
|
-
|
84
|
-
def power_of_ten integer
|
85
|
-
Math.log10(integer)
|
86
|
-
end
|
87
|
-
|
88
|
-
def power_of_ten? integer
|
89
|
-
power_of_ten(integer) == power_of_ten(integer).to_i
|
90
|
-
end
|
91
|
-
|
92
|
-
# 15,16
|
93
|
-
# 85,16
|
94
|
-
def pair_parse(ints, only_compress = false)
|
95
|
-
ints = compress(ints)
|
96
|
-
return ints if only_compress
|
97
|
-
return ints[0] if ints.length == 1
|
98
|
-
sum = 0
|
99
|
-
ints.each do |n|
|
100
|
-
sum *= n >= 10 ? 100 : 10
|
101
|
-
sum += n
|
102
|
-
end
|
103
|
-
sum
|
104
|
-
end
|
105
|
-
|
106
|
-
# [40, 2] => [42]
|
107
|
-
def compress(ints)
|
108
|
-
res = []
|
109
|
-
i = 0
|
110
|
-
return [] if ints.empty?
|
111
|
-
while i < ints.length - 1
|
112
|
-
int, jump = compress_int(ints[i], ints[i + 1])
|
113
|
-
res << int
|
114
|
-
i += jump
|
115
|
-
end
|
116
|
-
if i < ints.length
|
117
|
-
res << ints[-1]
|
118
|
-
else
|
119
|
-
res
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
def compress_int(int, sequel)
|
124
|
-
tens = int % 10 == 0 && int > 10
|
125
|
-
if tens && sequel < 10
|
126
|
-
return [int + sequel, 2]
|
127
|
-
else
|
128
|
-
return [int, 1]
|
129
|
-
end
|
130
|
-
|
131
|
-
[res, jump]
|
132
|
-
end
|
133
|
-
|
134
|
-
extend self
|
135
|
-
end
|
@@ -1,88 +0,0 @@
|
|
1
|
-
class NumbersInWords::ToNumber
|
2
|
-
delegate :to_s, to: :that
|
3
|
-
delegate :powers_of_ten_to_i, :exceptions_to_i, :canonize, \
|
4
|
-
:check_mixed, :check_one, :strip_minus, :check_decimal, to: :language
|
5
|
-
attr_reader :that, :language
|
6
|
-
|
7
|
-
def initialize that, language=NumbersInWords.language
|
8
|
-
@that = that
|
9
|
-
@language = language
|
10
|
-
end
|
11
|
-
|
12
|
-
def language
|
13
|
-
if @language.is_a? Module
|
14
|
-
@language
|
15
|
-
else
|
16
|
-
@language = NumbersInWords.const_get(@language)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def handle_negative(text, only_compress)
|
21
|
-
stripped = strip_minus text
|
22
|
-
if stripped
|
23
|
-
stripped_n = NumbersInWords.in_numbers(stripped, language, only_compress)
|
24
|
-
only_compress ? stripped_n.map{ |k| k * -1 } : -1 * stripped_n
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def in_numbers(only_compress = false)
|
29
|
-
text = to_s.strip
|
30
|
-
return text.to_f if text =~ /^-?\d+(.\d+)?$/
|
31
|
-
|
32
|
-
text = strip_punctuation text
|
33
|
-
|
34
|
-
i = handle_negative(text, only_compress)
|
35
|
-
return i if i
|
36
|
-
|
37
|
-
mixed = check_mixed text
|
38
|
-
return mixed if mixed
|
39
|
-
|
40
|
-
one = check_one text
|
41
|
-
if one
|
42
|
-
res = NumbersInWords.in_numbers(one[1], language)
|
43
|
-
return only_compress ? [res] : res
|
44
|
-
end
|
45
|
-
|
46
|
-
h = handle_decimals text
|
47
|
-
return h if h
|
48
|
-
|
49
|
-
integers = word_array_to_integers text.split(" ")
|
50
|
-
|
51
|
-
NumbersInWords::NumberParser.parse integers, only_compress
|
52
|
-
end
|
53
|
-
|
54
|
-
def strip_punctuation text
|
55
|
-
text = text.downcase.gsub(/[^a-z 0-9]/, " ")
|
56
|
-
to_remove = true
|
57
|
-
|
58
|
-
to_remove = text.gsub! " ", " " while to_remove
|
59
|
-
|
60
|
-
text
|
61
|
-
end
|
62
|
-
|
63
|
-
def handle_decimals text
|
64
|
-
match = check_decimal text
|
65
|
-
if match
|
66
|
-
integer = NumbersInWords.in_numbers(match.pre_match)
|
67
|
-
decimal = NumbersInWords.in_numbers(match.post_match)
|
68
|
-
integer += "0.#{decimal}".to_f
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
#handles simple single word numbers
|
73
|
-
#e.g. one, seven, twenty, eight, thousand etc
|
74
|
-
def word_to_integer word
|
75
|
-
text = canonize(word.to_s.chomp.strip)
|
76
|
-
|
77
|
-
exception = exceptions_to_i[text]
|
78
|
-
return exception if exception
|
79
|
-
|
80
|
-
power = powers_of_ten_to_i[text]
|
81
|
-
return 10 ** power if power
|
82
|
-
end
|
83
|
-
|
84
|
-
def word_array_to_integers words
|
85
|
-
words.map { |i| word_to_integer i }.compact
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
@@ -1,23 +0,0 @@
|
|
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
|
-
expect(power).to eq(3)
|
11
|
-
expect(name).to eq("thousand")
|
12
|
-
expect(digits).to eq(2)
|
13
|
-
when 1
|
14
|
-
expect(power).to eq(0)
|
15
|
-
expect(name).to eq("one")
|
16
|
-
expect(digits).to eq(111)
|
17
|
-
end
|
18
|
-
count += 1
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
|