Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support year style numbers e.g. "nineteen twenty" #5

Closed
wants to merge 29 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
cd04850
num_parse: support years notation (nineteen twenty)
dimidd Mar 5, 2015
2a1f9a1
num_parse: fix compress
dimidd Mar 17, 2015
dbf601f
gem: version bump; contact info
dimidd Mar 29, 2015
1b42f14
to_num: add year notation for decimals
dimidd Apr 13, 2015
77ba1c2
spec: years
dimidd Apr 13, 2015
01aa835
num_parse: support years notation (nineteen twenty)
dimidd Mar 5, 2015
a71d278
gem: version bump; contact info
dimidd Mar 29, 2015
76e0d06
to_num: add year notation for decimals
dimidd Apr 13, 2015
e67f358
spec: years
dimidd Apr 13, 2015
68cac08
Revert " gem: version bump; contact info"
Apr 15, 2015
204fa23
Merge branch 'master' of github.com:dimidd/numbers_in_words
dimidd Apr 15, 2015
2ae6fdb
num_parse: allow to get just the compressed array
dimidd Apr 21, 2015
6a40c31
gem: version bump
dimidd Apr 21, 2015
383655a
num_parse: fix num_compress for empty string
dimidd Apr 21, 2015
5b594a1
num_parse: fix compress for 'zero'
dimidd Apr 21, 2015
a39012d
num_parse: fix error with pair parsing 10
dimidd Aug 2, 2015
dafc82d
in_num: support numeric strings
dimidd Sep 9, 2015
b578476
gem: replace debugger with pry, update rspec
dimidd Oct 23, 2015
c851cf8
in_num: support simple mixed strings
dimidd Oct 23, 2015
3dc769e
spec: add numerical_strings, fix years
dimidd Oct 23, 2015
9b7d5e6
Convert specs to RSpec 3.3.2 syntax with Transpec
dimidd Oct 23, 2015
c0da9e4
gem: add pry-nav
dimidd Oct 27, 2015
a9f61dd
in_num: support 'one 10**n'
dimidd Oct 27, 2015
fe3e078
spec: fix WS
dimidd Oct 27, 2015
337c6ac
in_num: fix negative num_compress
dimidd Oct 27, 2015
ceded97
in_num: strip trailing WS from text
dimidd Oct 27, 2015
7002c91
in_num: fix 'minus'
dimidd Oct 28, 2015
a3ed7d1
merge master
markburns Nov 30, 2015
060e602
fix non monkey patched version
markburns Nov 30, 2015
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
PATH
remote: .
specs:
numbers_in_words (0.3.1)
activesupport

GEM
remote: https://rubygems.org/
specs:
activesupport (4.2.5)
i18n (~> 0.7)
json (~> 1.7, >= 1.7.7)
minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
codeclimate-test-reporter (0.4.8)
simplecov (>= 0.7.1, < 1.0.0)
diff-lcs (1.2.5)
docile (1.1.5)
i18n (0.7.0)
json (1.8.3)
minitest (5.8.3)
rspec (3.4.0)
rspec-core (~> 3.4.0)
rspec-expectations (~> 3.4.0)
rspec-mocks (~> 3.4.0)
rspec-core (3.4.1)
rspec-support (~> 3.4.0)
rspec-expectations (3.4.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.4.0)
rspec-mocks (3.4.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.4.0)
rspec-support (3.4.1)
simplecov (0.11.0)
docile (~> 1.1.0)
json (~> 1.8)
simplecov-html (~> 0.10.0)
simplecov-html (0.10.0)
thread_safe (0.3.5)
tzinfo (1.2.2)
thread_safe (~> 0.1)

PLATFORMS
ruby

DEPENDENCIES
codeclimate-test-reporter
numbers_in_words!
rspec (~> 3.4.0)

BUNDLED WITH
1.10.6
8 changes: 4 additions & 4 deletions lib/numbers_in_words.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ def language
@language ||= "English"
end

def in_words(i, language=NumbersInWords.language)
NumbersInWords::ToWord.new(i, language).in_words
def in_words(i, language=NumbersInWords.language, only_compress=false)
NumbersInWords::ToWord.new(i, language).in_words(only_compress)
end

def in_numbers(s, language=NumbersInWords.language)
NumbersInWords::ToNumber.new(s, language).in_numbers
def in_numbers(s, language=NumbersInWords.language, only_compress=false)
NumbersInWords::ToNumber.new(s, language).in_numbers(only_compress)
end
end
end
Expand Down
4 changes: 2 additions & 2 deletions lib/numbers_in_words/duck_punch.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ def in_words language=NumbersInWords.language
end

module WordsInNumbers
def in_numbers language=NumbersInWords.language
NumbersInWords.in_numbers(self, language)
def in_numbers(only_compress = false, language=NumbersInWords.language)
NumbersInWords::ToNumber.new(self, language).in_numbers(only_compress)
end
end

Expand Down
42 changes: 39 additions & 3 deletions lib/numbers_in_words/number_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,14 @@ module NumbersInWords::NumberParser
#3. add memory to answer,reset, because power of ten>2 0 2000
#4. add 1 to memory 1 2000
#5. finish - add memory to answer 0 2001
def parse(integers)
def parse(integers, only_compress = false)
scales_n = [100, 1000, 1000000, 1000000000, 1000000000000, 10**100]
if integers.length < 2
return only_compress ? integers : integers.empty? ? 0 : integers[0]
end
if [] == scales_n & integers
return pair_parse(integers, only_compress)
end
memory = 0
answer = 0
reset = true #reset each time memory is reset
Expand All @@ -58,8 +65,7 @@ def parse(integers)
reset = true
end
end

if memory < integer
if memory < integer
memory *= integer
else
memory += integer
Expand All @@ -77,5 +83,35 @@ def power_of_ten? integer
power_of_ten(integer) == power_of_ten(integer).to_i
end

# 15,16
# 85,16
def pair_parse(ints, only_compress = false)
ints = compress(ints)
return ints if only_compress
return ints[0] if ints.length == 1
sum = 0
ints.each do |n|
sum *= n >= 10 ? 100 : 10
sum += n
end
sum
end

# [40, 2] => [42]
def compress(ints)
res = []; i = 0
return [] if ints.empty?
while i < ints.length - 1
if ints[i] > 0 && ints[i] % 10 == 0 && ints[i + 1] < 10
res << ints[i] + ints[i + 1]
i += 2
else
res << ints[i]
i += 1
end
end
i < ints.length ? res << ints[-1] : res
end

extend self
end
51 changes: 31 additions & 20 deletions lib/numbers_in_words/to_number.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,48 @@ def language
end
end

def handle_negative text
-1 * (text.gsub(/^minus /, "")).in_numbers if text =~ /^minus /
def handle_negative(text, only_compress)
if text =~ /^minus/
stripped = text.gsub(/^minus/, "")
stripped_n = NumbersInWords.in_numbers(stripped, language, only_compress)
only_compress ? stripped_n.map{ |k| k * -1 } : -1 * stripped_n
end
end

def in_numbers
text = to_s
def in_numbers(only_compress = false)
text = to_s.strip
return text.to_f if text =~ /^-?\d+(.\d+)?$/

text = strip_punctuation text
i = handle_negative text

i = handle_negative(text, only_compress)
return i if i

mixed = text.match /^(-?\d+(.\d+)?) (hundred|thousand|million|billion|trillion)$/

if mixed && mixed[1] && mixed[3]
third_match = NumbersInWords.in_numbers(mixed[3])
first_match = NumbersInWords.in_numbers(mixed[1])
return first_match * third_match
end

one = text.match /^one (hundred|thousand|million|billion|trillion)$/

if one
first_match = NumbersInWords.in_numbers(one[1])
return only_compress ? [first_match] : first_match
end

h = handle_decimals text
return h if h

integers = word_array_to_integers text.split(" ")

NumbersInWords::NumberParser.parse integers
NumbersInWords::NumberParser.parse integers, only_compress
end

def strip_punctuation text
text = text.downcase.gsub(/[^a-z ]/, " ")
text = text.downcase.gsub(/[^a-z 0-9]/, " ")
to_remove = true

to_remove = text.gsub! " ", " " while to_remove
Expand All @@ -47,22 +68,12 @@ def strip_punctuation text
def handle_decimals text
match = text.match(/\spoint\s/)
if match
integer = match.pre_match.in_numbers

decimal = decimal_portion match.post_match

integer + decimal
integer = NumbersInWords.in_numbers(match.pre_match)
decimal = NumbersInWords.in_numbers(match.post_match)
integer += "0.#{decimal}".to_f
end
end


def decimal_portion text
words = text.split " "
integers = word_array_to_integers words
decimal = "0." + integers.join()
decimal.to_f
end

#handles simple single word numbers
#e.g. one, seven, twenty, eight, thousand etc
def word_to_integer word
Expand Down
2 changes: 1 addition & 1 deletion lib/numbers_in_words/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module NumbersInWords
VERSION = "0.3.0"
VERSION = "0.3.1"
end
6 changes: 3 additions & 3 deletions numbers_in_words.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ Gem::Specification.new do |gem|
gem.summary = "Example: 123.in_words # => \"one hundred and twenty three\", \"seventy-five point eight\".in_numbers # = > 75.8"

gem.version = NumbersInWords::VERSION
gem.authors = ["Mark Burns"]
gem.email = ["markthedeveloper@gmail.com"]
gem.homepage = "http://github.com/markburns/numbers_in_words"
gem.authors = ["Mark Burns", "Dimid Duchovny"]
gem.email = ["dimidd@gmail.com"]
gem.homepage = "http://github.com/dimidd/numbers_in_words"

gem.add_dependency "activesupport"
gem.add_development_dependency "rspec", "~> 3.4.0"
Expand Down
6 changes: 6 additions & 0 deletions spec/non_monkey_patch_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@
describe ".in_numbers" do
it do
expect(NumbersInWords.in_numbers("one hundred")).to eq 100

expect(NumbersInWords.in_numbers("minus one hundred")).to eq -100
expect(NumbersInWords.in_numbers("twenty four" )).to eq 24
expect(NumbersInWords.in_numbers("one point two")).to eq 1.2
expect(NumbersInWords.in_numbers("one hundred googol")).to eq 100*10**100
expect(NumbersInWords.in_numbers("one hundred googol and thirty")).to eq 30 + 100*10**100
end
end

Expand Down
19 changes: 19 additions & 0 deletions spec/numerical_strings_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
require './spec/spec_helper'

describe NumbersInWords do
it "should recognize numerical strings" do
arr = %w(8 56 100 5789 3435356)
arr.each{ |s| expect(s.in_numbers).to eql(s.to_f) }
end

it "should recognize mixed strings" do
mixed = {
"19 hundred" => 1_900.0,
"20 thousand" => 20_000.0,
"100 million" => 100_000_000.0,
"7 billion" => 7_000_000_000.0,
"42 trillion" => 42_000_000_000_000.0
}
mixed.each{ |k, v| expect(k.in_numbers).to eql(v) }
end
end
10 changes: 10 additions & 0 deletions spec/words_in_numbers_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -132,4 +132,14 @@
in_numbers).to eq(75.84327694518)
end

it "should handle years notation" do
expect("fifteen sixteen".in_numbers) .to eq(1516)
expect("eighty five sixteen".in_numbers) .to eq(8516)
expect("nineteen ninety six".in_numbers) .to eq(1996)
expect("forty nine ninety eight forty seven seventy nine".in_numbers) .to eq(49984779)
expect("fifteen sixteen".in_numbers) .to eq(1516)
expect("fifteen sixteen seven".in_numbers) .to eq(15167)
expect("fifteen sixteen seventeen".in_numbers) .to eq(151617)
end

end
16 changes: 16 additions & 0 deletions spec/years_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
require './spec/spec_helper'

describe WordsInNumbers do
it "should handle years notation" do
expect("fifteen sixteen seventeen".in_numbers) .to eq(151617)
expect("forty nine ninety eight forty seven seventy nine".in_numbers) .to eq(49984779)
expect("sixty seven six".in_numbers) .to eq(676)
expect("one fifty".in_numbers).to eq(150)
expect("two fifty".in_numbers).to eq(250)
expect("one point fifty six fifty seven".in_numbers).to eq(1.5657)
expect("one three forty seven".in_numbers).to eq(1347)
expect("one three five point forty seven".in_numbers).to eq(135.47)
expect("one ten sixty three".in_numbers).to eq(11063)
end

end