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.
Files changed (46) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -0
  3. data/.rspec +1 -0
  4. data/.rubocop.yml +35 -1148
  5. data/.travis.yml +14 -4
  6. data/Gemfile +4 -1
  7. data/README.md +6 -44
  8. data/Rakefile +3 -1
  9. data/lib/numbers_in_words.rb +44 -19
  10. data/lib/numbers_in_words/duck_punch.rb +12 -8
  11. data/lib/numbers_in_words/exceptional_numbers.rb +115 -0
  12. data/lib/numbers_in_words/fraction.rb +136 -0
  13. data/lib/numbers_in_words/number_group.rb +34 -21
  14. data/lib/numbers_in_words/parsing/fraction_parsing.rb +34 -0
  15. data/lib/numbers_in_words/parsing/number_parser.rb +98 -0
  16. data/lib/numbers_in_words/parsing/pair_parsing.rb +64 -0
  17. data/lib/numbers_in_words/parsing/parse_fractions.rb +45 -0
  18. data/lib/numbers_in_words/parsing/parse_individual_number.rb +68 -0
  19. data/lib/numbers_in_words/parsing/parse_status.rb +17 -0
  20. data/lib/numbers_in_words/parsing/special.rb +67 -0
  21. data/lib/numbers_in_words/parsing/to_number.rb +77 -0
  22. data/lib/numbers_in_words/powers_of_ten.rb +49 -0
  23. data/lib/numbers_in_words/to_word.rb +78 -13
  24. data/lib/numbers_in_words/version.rb +3 -1
  25. data/lib/numbers_in_words/writer.rb +69 -0
  26. data/numbers_in_words.gemspec +14 -13
  27. data/spec/exceptional_numbers_spec.rb +26 -0
  28. data/spec/fraction_spec.rb +152 -0
  29. data/spec/fractions_spec.rb +31 -0
  30. data/spec/non_monkey_patch_spec.rb +39 -20
  31. data/spec/number_group_spec.rb +12 -12
  32. data/spec/number_parser_spec.rb +31 -0
  33. data/spec/numbers_in_words_spec.rb +63 -70
  34. data/spec/numerical_strings_spec.rb +28 -12
  35. data/spec/spec_helper.rb +23 -4
  36. data/spec/to_word_spec.rb +18 -0
  37. data/spec/words_in_numbers_spec.rb +132 -125
  38. data/spec/writer_spec.rb +26 -0
  39. data/spec/years_spec.rb +23 -13
  40. metadata +43 -27
  41. data/lib/numbers_in_words/english/constants.rb +0 -124
  42. data/lib/numbers_in_words/english/language_writer_english.rb +0 -116
  43. data/lib/numbers_in_words/language_writer.rb +0 -30
  44. data/lib/numbers_in_words/number_parser.rb +0 -135
  45. data/lib/numbers_in_words/to_number.rb +0 -88
  46. data/spec/language_writer_spec.rb +0 -23
@@ -1,30 +0,0 @@
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
- def group_words size
19
- #1000 and over Numbers are split into groups of three
20
- groups = NumberGroup.groups_of @that, size
21
- powers = groups.keys.sort.reverse #put in descending order
22
-
23
- powers.each do |power|
24
- name = powers_of_ten[power]
25
- digits = groups[power]
26
- yield power, name, digits
27
- end
28
- end
29
- end
30
- end
@@ -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
-