numbers_in_words 0.2.0 → 0.5.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 +7 -0
- data/.codeclimate.yml +14 -0
- data/.gitignore +2 -0
- data/.rspec +2 -0
- data/.rubocop.yml +58 -0
- data/.travis.yml +15 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +50 -26
- data/README.md +20 -70
- data/Rakefile +3 -1
- data/bin/spec +2 -0
- data/lib/numbers_in_words.rb +49 -15
- 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 -25
- 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 +15 -14
- 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 +51 -0
- data/spec/number_group_spec.rb +12 -12
- data/spec/number_parser_spec.rb +31 -0
- data/spec/numbers_in_words_spec.rb +74 -54
- data/spec/numerical_strings_spec.rb +35 -0
- data/spec/spec_helper.rb +24 -0
- data/spec/to_word_spec.rb +18 -0
- data/spec/words_in_numbers_spec.rb +135 -117
- data/spec/writer_spec.rb +26 -0
- data/spec/years_spec.rb +27 -0
- metadata +61 -59
- data/lib/numbers_in_words/english/constants.rb +0 -93
- data/lib/numbers_in_words/english/language_writer_english.rb +0 -107
- data/lib/numbers_in_words/language_writer.rb +0 -31
- data/lib/numbers_in_words/number_parser.rb +0 -81
- data/lib/numbers_in_words/to_number.rb +0 -82
- data/spec/language_writer_spec.rb +0 -23
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 71344514fae412865a50ec69a9b58335ac9249aadf29bd5145a8455f503473b0
|
4
|
+
data.tar.gz: 128abd6b5546902d819c11b9105d573a564e6e1679c84bbeb8910bb6f28c03f8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2cb8730bc67b4be3a3aba9a63e4198c1a2e11e9664879d9f859fc4cf11b26743671abb97d180d411cd6a2dfaa6309afadf9f2d61a584c6ef2d5b05ecbbbfab16
|
7
|
+
data.tar.gz: 1c50db96276a5a9a9211bdb460c1f9e686fb35436a180d0aaf8de34961061cfd400421680a227558642b124d9be88eaa9f5a67ff3dfbbf65e4ba8ebfed5293d1
|
data/.codeclimate.yml
ADDED
data/.gitignore
CHANGED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
# The behavior of RuboCop can be controlled via the .rubocop.yml
|
2
|
+
# configuration file. It makes it possible to enable/disable
|
3
|
+
# certain cops (checks) and to alter their behavior if they accept
|
4
|
+
# any parameters. The file can be placed either in your home
|
5
|
+
# directory or in some project directory.
|
6
|
+
#
|
7
|
+
# RuboCop will start looking for the configuration file in the directory
|
8
|
+
# where the inspected file is and continue its way up to the root directory.
|
9
|
+
#
|
10
|
+
# See https://docs.rubocop.org/rubocop/configuration
|
11
|
+
Layout/EmptyLinesAroundAttributeAccessor:
|
12
|
+
Enabled: true
|
13
|
+
Layout/SpaceAroundMethodCallOperator:
|
14
|
+
Enabled: true
|
15
|
+
Lint/DeprecatedOpenSSLConstant:
|
16
|
+
Enabled: true
|
17
|
+
Lint/MixedRegexpCaptureTypes:
|
18
|
+
Enabled: true
|
19
|
+
Lint/RaiseException:
|
20
|
+
Enabled: true
|
21
|
+
Lint/StructNewOverride:
|
22
|
+
Enabled: true
|
23
|
+
Style/ExponentialNotation:
|
24
|
+
Enabled: true
|
25
|
+
Style/HashEachMethods:
|
26
|
+
Enabled: true
|
27
|
+
Style/HashTransformKeys:
|
28
|
+
Enabled: true
|
29
|
+
Style/HashTransformValues:
|
30
|
+
Enabled: true
|
31
|
+
Style/RedundantFetchBlock:
|
32
|
+
Enabled: true
|
33
|
+
Style/RedundantRegexpCharacterClass:
|
34
|
+
Enabled: true
|
35
|
+
Style/RedundantRegexpEscape:
|
36
|
+
Enabled: true
|
37
|
+
Style/SlicingWithRange:
|
38
|
+
Enabled: true
|
39
|
+
Lint/DuplicateElsifCondition:
|
40
|
+
Enabled: true
|
41
|
+
Style/AccessorGrouping:
|
42
|
+
Enabled: true
|
43
|
+
Style/ArrayCoercion:
|
44
|
+
Enabled: true
|
45
|
+
Style/BisectedAttrAccessor:
|
46
|
+
Enabled: true
|
47
|
+
Style/CaseLikeIf:
|
48
|
+
Enabled: true
|
49
|
+
Style/Documentation:
|
50
|
+
Enabled: false
|
51
|
+
Style/HashAsLastArrayItem:
|
52
|
+
Enabled: true
|
53
|
+
Style/HashLikeCase:
|
54
|
+
Enabled: true
|
55
|
+
Style/RedundantAssignment:
|
56
|
+
Enabled: true
|
57
|
+
Style/RedundantFileExtensionInRequire:
|
58
|
+
Enabled: true
|
data/.travis.yml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
env:
|
2
|
+
global:
|
3
|
+
- CC_TEST_REPORTER_ID=9a548b48c1c0804d8fb9083ae8e9693a5d5197eb86e8cf1b63a89d18f33e0464
|
4
|
+
sudo: false
|
5
|
+
language: ruby
|
6
|
+
rvm:
|
7
|
+
- "2.6.6"
|
8
|
+
- "2.7.1"
|
9
|
+
before_script:
|
10
|
+
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
11
|
+
- chmod +x ./cc-test-reporter
|
12
|
+
- ./cc-test-reporter before-build
|
13
|
+
script: ./bin/spec
|
14
|
+
after_script:
|
15
|
+
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,39 +1,63 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
numbers_in_words (0.
|
5
|
-
activesupport
|
4
|
+
numbers_in_words (0.5.1)
|
6
5
|
|
7
6
|
GEM
|
8
7
|
remote: https://rubygems.org/
|
9
8
|
specs:
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
rspec-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
9
|
+
ast (2.4.1)
|
10
|
+
byebug (11.1.3)
|
11
|
+
diff-lcs (1.4.4)
|
12
|
+
docile (1.3.2)
|
13
|
+
json (2.3.1)
|
14
|
+
parallel (1.19.2)
|
15
|
+
parser (2.7.1.4)
|
16
|
+
ast (~> 2.4.1)
|
17
|
+
rainbow (3.0.0)
|
18
|
+
regexp_parser (1.7.1)
|
19
|
+
rexml (3.2.4)
|
20
|
+
rspec (3.4.0)
|
21
|
+
rspec-core (~> 3.4.0)
|
22
|
+
rspec-expectations (~> 3.4.0)
|
23
|
+
rspec-mocks (~> 3.4.0)
|
24
|
+
rspec-core (3.4.4)
|
25
|
+
rspec-support (~> 3.4.0)
|
26
|
+
rspec-expectations (3.4.0)
|
27
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
28
|
+
rspec-support (~> 3.4.0)
|
29
|
+
rspec-mocks (3.4.1)
|
30
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
31
|
+
rspec-support (~> 3.4.0)
|
32
|
+
rspec-support (3.4.1)
|
33
|
+
rubocop (0.88.0)
|
34
|
+
parallel (~> 1.10)
|
35
|
+
parser (>= 2.7.1.1)
|
36
|
+
rainbow (>= 2.2.2, < 4.0)
|
37
|
+
regexp_parser (>= 1.7)
|
38
|
+
rexml
|
39
|
+
rubocop-ast (>= 0.1.0, < 1.0)
|
40
|
+
ruby-progressbar (~> 1.7)
|
41
|
+
unicode-display_width (>= 1.4.0, < 2.0)
|
42
|
+
rubocop-ast (0.1.0)
|
43
|
+
parser (>= 2.7.0.1)
|
44
|
+
ruby-progressbar (1.10.1)
|
45
|
+
simplecov (0.17.1)
|
46
|
+
docile (~> 1.1)
|
47
|
+
json (>= 1.8, < 3)
|
48
|
+
simplecov-html (~> 0.10.0)
|
49
|
+
simplecov-html (0.10.2)
|
50
|
+
unicode-display_width (1.7.0)
|
32
51
|
|
33
52
|
PLATFORMS
|
34
53
|
ruby
|
35
54
|
|
36
55
|
DEPENDENCIES
|
37
|
-
|
56
|
+
byebug
|
38
57
|
numbers_in_words!
|
39
|
-
rspec
|
58
|
+
rspec (~> 3.4.0)
|
59
|
+
rubocop
|
60
|
+
simplecov (< 0.18.0)
|
61
|
+
|
62
|
+
BUNDLED WITH
|
63
|
+
2.1.4
|
data/README.md
CHANGED
@@ -1,42 +1,37 @@
|
|
1
|
+
[](https://travis-ci.org/markburns/numbers_in_words)
|
2
|
+
[](https://codeclimate.com/github/markburns/numbers_in_words/maintainability)
|
3
|
+
[](https://codeclimate.com/github/markburns/numbers_in_words/test_coverage)
|
4
|
+
[](https://rubygems.org/gems/numbers_in_words)
|
5
|
+
[](http://markburns.mit-license.org)
|
6
|
+
|
1
7
|
Installation
|
2
8
|
============
|
3
9
|
|
4
|
-
```
|
10
|
+
```ruby
|
5
11
|
gem 'numbers_in_words'
|
6
|
-
|
7
|
-
require 'numbers_in_words'
|
8
|
-
require 'numbers_in_words/duck_punch' #see why later
|
9
12
|
```
|
10
13
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
I'm going to hopefully preempt some support queries by predicting this will happen:
|
14
|
+
Usage
|
15
|
+
=========
|
15
16
|
|
16
|
-
|
17
|
+
```ruby
|
18
|
+
require 'numbers_in_words'
|
17
19
|
|
18
|
-
|
19
|
-
|
20
|
-
NoMethodError: undefined method `in_numbers' for "123":String
|
21
|
-
```
|
20
|
+
NumbersInWords.in_words(112)
|
21
|
+
#=> one hundred and twelve
|
22
22
|
|
23
|
-
|
24
|
-
|
23
|
+
NumbersInWords.in_numbers("one googol")
|
24
|
+
#=>10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
with:
|
26
|
+
NumbersInWords.in_numbers("Seventy million, five-hundred and fifty six thousand point eight nine three")
|
27
|
+
#=> 70556000.893
|
29
28
|
|
30
|
-
|
31
|
-
|
32
|
-
require 'numbers_in_words/duck_punch'
|
29
|
+
NumbersInWords.in_numbers("nineteen sixty five")
|
30
|
+
#=> 1965
|
33
31
|
```
|
34
32
|
|
35
|
-
Plus it now only adds a single `#in_words` method to `Numeric` and an `#in_numbers`
|
36
|
-
method to `String` instead of a whole bunch of them.
|
37
33
|
|
38
|
-
|
39
|
-
=========
|
34
|
+
Monkey patch version
|
40
35
|
|
41
36
|
```ruby
|
42
37
|
require 'numbers_in_words'
|
@@ -50,48 +45,3 @@ require 'numbers_in_words/duck_punch'
|
|
50
45
|
"Seventy million, five-hundred and fifty six thousand point eight nine three".in_numbers
|
51
46
|
#=> 70556000.893
|
52
47
|
```
|
53
|
-
|
54
|
-
---------------
|
55
|
-
|
56
|
-
Whilst creating this project I realized that in English:
|
57
|
-
|
58
|
-
* Numbers are grouped in groups of threes
|
59
|
-
* Numbers less than 1,000 are grouped by hundreds and then by tens
|
60
|
-
* There are specific rules for when we put an "and" in between numbers
|
61
|
-
|
62
|
-
It makes sense to manage the numbers by these groups, so
|
63
|
-
I created a method groups_of which will split any integer into
|
64
|
-
groups of a certain size. It returns a hash with the power of ten
|
65
|
-
as the key and the multiplier as the value. E.g:
|
66
|
-
|
67
|
-
```ruby
|
68
|
-
31245.groups_of(3)
|
69
|
-
#=> {0=>245,3=>31} #i.e. 31 thousands, and 245 ones
|
70
|
-
|
71
|
-
245.group_of(2)
|
72
|
-
#=> {0=>45,2=>2} #i.e. 2 hundreds, and 45 ones
|
73
|
-
```
|
74
|
-
|
75
|
-
(In Japanese numbers are grouped in groups of 4, so it makes sense to try and
|
76
|
-
separate the language related stuff from the number grouping related stuff)
|
77
|
-
|
78
|
-
Example of usage:
|
79
|
-
|
80
|
-
```ruby
|
81
|
-
245.group_words(2,"English") do |power, name, digits|
|
82
|
-
puts "#{digits}*10^#{power} #{digits} #{name}s"
|
83
|
-
end
|
84
|
-
|
85
|
-
|
86
|
-
2 * 10^2 = 2 hundreds
|
87
|
-
45 * 10^0 = 45 ones
|
88
|
-
|
89
|
-
```
|
90
|
-
|
91
|
-
Future plans
|
92
|
-
============
|
93
|
-
|
94
|
-
* Handle complex numbers
|
95
|
-
* Option for outputting punctuation
|
96
|
-
* Reject invalid numbers
|
97
|
-
* Support for other languages
|
data/Rakefile
CHANGED
data/bin/spec
ADDED
data/lib/numbers_in_words.rb
CHANGED
@@ -1,24 +1,58 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require 'numbers_in_words/
|
5
|
-
|
6
|
-
require 'numbers_in_words/english/constants'
|
7
|
-
require 'numbers_in_words/english/language_writer_english'
|
8
|
-
|
9
|
-
require 'numbers_in_words/number_group'
|
10
|
-
require 'numbers_in_words/number_parser'
|
11
|
-
require 'numbers_in_words/to_number'
|
3
|
+
require 'numbers_in_words/version'
|
4
|
+
require 'numbers_in_words/exceptional_numbers'
|
5
|
+
require 'numbers_in_words/parsing/number_parser'
|
12
6
|
require 'numbers_in_words/to_word'
|
7
|
+
require 'numbers_in_words/parsing/to_number'
|
13
8
|
|
14
9
|
module NumbersInWords
|
15
|
-
LENGTH_OF_GOOGOL
|
10
|
+
LENGTH_OF_GOOGOL = 101 # length of the string i.e. one with 100 zeros
|
11
|
+
Error = ::Class.new(::StandardError)
|
12
|
+
AmbiguousParsingError = ::Class.new(Error)
|
13
|
+
DivideByZeroError = ::Class.new(Error)
|
14
|
+
InvalidNumber = ::Class.new(Error)
|
16
15
|
|
17
16
|
class << self
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
extend Forwardable
|
18
|
+
def_delegators :exceptional_numbers, :fraction
|
19
|
+
|
20
|
+
def in_words(num, fraction: false)
|
21
|
+
ToWord.new(num).in_words(fraction: fraction)
|
22
|
+
end
|
23
|
+
|
24
|
+
def in_numbers(words, only_compress: false)
|
25
|
+
ToNumber.new(words, only_compress).call
|
26
|
+
end
|
27
|
+
|
28
|
+
def exceptional_numbers
|
29
|
+
@exceptional_numbers ||= ExceptionalNumbers.new
|
30
|
+
end
|
31
|
+
|
32
|
+
def lookup(number)
|
33
|
+
exceptional_numbers.lookup(number)
|
34
|
+
end
|
35
|
+
|
36
|
+
def exceptional_number(text)
|
37
|
+
exceptional_numbers_to_i[text]
|
38
|
+
end
|
39
|
+
|
40
|
+
def power_of_ten(text)
|
41
|
+
powers_of_ten_to_i[text]
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def exceptional_numbers_to_i
|
47
|
+
@exceptional_numbers_to_i ||= swap_keys exceptional_numbers.to_h
|
48
|
+
end
|
49
|
+
|
50
|
+
def powers_of_ten_to_i
|
51
|
+
@powers_of_ten_to_i ||= swap_keys POWERS_OF_TEN
|
52
|
+
end
|
53
|
+
|
54
|
+
def swap_keys(hash)
|
55
|
+
hash.each_with_object({}) { |(k, v), h| h[v] = k }
|
21
56
|
end
|
22
57
|
end
|
23
58
|
end
|
24
|
-
|
@@ -1,19 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module NumbersInWords
|
2
|
-
|
3
|
-
|
4
|
+
module NumericExtension
|
5
|
+
def in_words(fraction: false)
|
6
|
+
NumbersInWords::ToWord.new(self).in_words(fraction: fraction)
|
7
|
+
end
|
4
8
|
end
|
5
|
-
end
|
6
9
|
|
7
|
-
module
|
8
|
-
|
9
|
-
|
10
|
+
module StringExtension
|
11
|
+
def in_numbers(only_compress: false)
|
12
|
+
NumbersInWords::ToNumber.new(self, only_compress).call
|
13
|
+
end
|
10
14
|
end
|
11
15
|
end
|
12
16
|
|
13
17
|
class String
|
14
|
-
include
|
18
|
+
include NumbersInWords::StringExtension
|
15
19
|
end
|
16
20
|
|
17
21
|
class Numeric
|
18
|
-
include NumbersInWords
|
22
|
+
include NumbersInWords::NumericExtension
|
19
23
|
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'forwardable'
|
4
|
+
|
5
|
+
require_relative 'fraction'
|
6
|
+
require_relative 'powers_of_ten'
|
7
|
+
|
8
|
+
module NumbersInWords
|
9
|
+
class ExceptionalNumbers
|
10
|
+
extend Forwardable
|
11
|
+
|
12
|
+
DEFINITIONS = {
|
13
|
+
0 => { number: 'zero', ordinal: 'zeroth' },
|
14
|
+
1 => { number: 'one', ordinal: 'first' },
|
15
|
+
2 => { number: 'two', ordinal: 'second', fraction: { singular: 'half', plural: 'halves' } },
|
16
|
+
3 => { number: 'three', ordinal: 'third' },
|
17
|
+
4 => { number: 'four', ordinal: 'fourth', fraction: { singular: 'quarter', plural: 'quarters' } },
|
18
|
+
5 => { number: 'five', ordinal: 'fifth' },
|
19
|
+
6 => { number: 'six' },
|
20
|
+
7 => { number: 'seven' },
|
21
|
+
8 => { number: 'eight', ordinal: 'eighth' },
|
22
|
+
9 => { number: 'nine', ordinal: 'ninth' },
|
23
|
+
10 => { number: 'ten' },
|
24
|
+
11 => { number: 'eleven' },
|
25
|
+
12 => { number: 'twelve', ordinal: 'twelfth' },
|
26
|
+
13 => { number: 'thirteen' },
|
27
|
+
14 => { number: 'fourteen' },
|
28
|
+
15 => { number: 'fifteen' },
|
29
|
+
16 => { number: 'sixteen' },
|
30
|
+
17 => { number: 'seventeen' },
|
31
|
+
18 => { number: 'eighteen' },
|
32
|
+
19 => { number: 'nineteen' },
|
33
|
+
20 => { number: 'twenty', ordinal: 'twentieth' },
|
34
|
+
30 => { number: 'thirty', ordinal: 'thirtieth' },
|
35
|
+
40 => { number: 'forty', ordinal: 'fortieth' },
|
36
|
+
50 => { number: 'fifty', ordinal: 'fiftieth' },
|
37
|
+
60 => { number: 'sixty', ordinal: 'sixtieth' },
|
38
|
+
70 => { number: 'seventy', ordinal: 'seventieth' },
|
39
|
+
80 => { number: 'eighty', ordinal: 'eightieth' },
|
40
|
+
90 => { number: 'ninety', ordinal: 'ninetieth' }
|
41
|
+
}.freeze
|
42
|
+
|
43
|
+
def fraction_names
|
44
|
+
@fraction_names ||= determine_fraction_names
|
45
|
+
end
|
46
|
+
|
47
|
+
def lookup_fraction(words)
|
48
|
+
fraction_lookup[words]
|
49
|
+
end
|
50
|
+
|
51
|
+
def fraction_lookup
|
52
|
+
@fraction_lookup ||= generate_fraction_lookup
|
53
|
+
end
|
54
|
+
|
55
|
+
def lookup(number)
|
56
|
+
to_h[number]
|
57
|
+
end
|
58
|
+
|
59
|
+
def fraction(denominator: nil, numerator: nil, word: nil)
|
60
|
+
raise unless denominator || word
|
61
|
+
|
62
|
+
numerator ||= 1
|
63
|
+
|
64
|
+
denominator ||= NumbersInWords.in_numbers(word)
|
65
|
+
|
66
|
+
Fraction.new(denominator: denominator, numerator: numerator, attributes: DEFINITIONS[denominator])
|
67
|
+
end
|
68
|
+
|
69
|
+
def to_h
|
70
|
+
@to_h ||= DEFINITIONS.transform_values do |h|
|
71
|
+
h[:number]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def generate_fraction_lookup
|
78
|
+
named_fractions.each_with_object({}) do |f, result|
|
79
|
+
f.lookup_keys.each do |k|
|
80
|
+
key = k.split(' ').last
|
81
|
+
result[key] = 1.0 / f.denominator.to_f
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def named_fractions
|
87
|
+
@named_fractions ||= numbers.flat_map do |n|
|
88
|
+
[
|
89
|
+
Fraction.new(denominator: n, numerator: 1),
|
90
|
+
Fraction.new(denominator: n, numerator: 2)
|
91
|
+
]
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def numbers
|
96
|
+
(2..100).to_a + powers_of_ten_skipping_googolplex.map { |p| 10**p }
|
97
|
+
end
|
98
|
+
|
99
|
+
def powers_of_ten_skipping_googolplex
|
100
|
+
POWERS_OF_TEN.keys[0..-2]
|
101
|
+
end
|
102
|
+
|
103
|
+
def determine_fraction_names
|
104
|
+
names = named_fractions.map(&:in_words)
|
105
|
+
|
106
|
+
words = names.map(&:split).map(&:last)
|
107
|
+
words += strip_punctuation(words)
|
108
|
+
words.uniq
|
109
|
+
end
|
110
|
+
|
111
|
+
def strip_punctuation(words)
|
112
|
+
words.map { |w| w.gsub(/^a-z/, ' ') }
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|