num_words 0.1.0 → 0.3.0
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 +4 -4
- data/README.md +21 -25
- data/lib/num_words/converter.rb +129 -0
- data/lib/num_words/version.rb +1 -1
- data/lib/num_words.rb +1 -0
- data/num_words-0.1.0.gem +0 -0
- data/num_words-0.2.0.gem +0 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 24463f1da6ace2a42347b2e4bd275527a02510175087ebc98eaf3011ea56f4ff
|
4
|
+
data.tar.gz: e61dc04d74d11bde0825d575a5240b96790d1a156ad8048813449adf1e267e05
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9decb67c34898169365951b2c04c79449c0024ea83263ed30a8d0412ce1f6f2ac62a6423e380c9492cd87afce0841085e3f4e06900b9141a87427d4043fc8a04
|
7
|
+
data.tar.gz: 2f5fe30029e8c3ed6915c0ace3f913d3ed3ea0f47ac119f200b1a8dc4b410e0575317f5011275bc40c466e1593af21732c918829b02bfa1a47cd5ac3f0709704
|
data/README.md
CHANGED
@@ -1,36 +1,32 @@
|
|
1
1
|
# NumWords
|
2
2
|
|
3
|
-
|
3
|
+
**NumWords** is a Ruby gem that converts numbers into words in multiple numbering systems, including US, European, UK, French, and Indian. It supports both integer and decimal numbers and is useful for invoices, financial documents, or any application that requires converting numeric values into readable text.
|
4
4
|
|
5
|
-
|
5
|
+
---
|
6
6
|
|
7
|
-
##
|
8
|
-
|
9
|
-
TODO: Replace `UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG` with your gem name right after releasing it to RubyGems.org. Please do not do it earlier due to security reasons. Alternatively, replace this section with instructions to install your gem from git if you don't plan to release to RubyGems.org.
|
10
|
-
|
11
|
-
Install the gem and add to the application's Gemfile by executing:
|
12
|
-
|
13
|
-
```bash
|
14
|
-
bundle add UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
|
15
|
-
```
|
7
|
+
## Features
|
16
8
|
|
17
|
-
|
9
|
+
- Convert integers and decimals to words.
|
10
|
+
- Supports multiple country numbering systems:
|
11
|
+
- **US / American** – `thousand, million, billion`
|
12
|
+
- **European** – `thousand, million, milliard, billion`
|
13
|
+
- **UK** – `thousand, million, billion`
|
14
|
+
- **France** – `mille, million, milliard`
|
15
|
+
- **India** – `thousand, lakh, crore`
|
16
|
+
- Easy to integrate into Ruby or Rails applications.
|
17
|
+
- Supports numbers up to `duovigintillion` (10^69) in the American system.
|
18
18
|
|
19
|
-
|
20
|
-
gem install UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
|
21
|
-
```
|
22
|
-
|
23
|
-
## Usage
|
24
|
-
|
25
|
-
TODO: Write usage instructions here
|
19
|
+
---
|
26
20
|
|
27
|
-
##
|
21
|
+
## Installation
|
28
22
|
|
29
|
-
|
23
|
+
### Using RubyGems
|
30
24
|
|
31
|
-
|
25
|
+
After releasing your gem to [RubyGems.org](https://rubygems.org), install it with:
|
32
26
|
|
33
|
-
|
27
|
+
```bash
|
28
|
+
# Using Bundler
|
29
|
+
bundle add gem 'num_words'
|
34
30
|
|
35
|
-
|
36
|
-
|
31
|
+
# Or install manually
|
32
|
+
gem install num_words
|
@@ -0,0 +1,129 @@
|
|
1
|
+
# lib/num_words/converter.rb
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module NumWords
|
5
|
+
ONES = %w[zero one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen].freeze
|
6
|
+
TENS = %w[zero ten twenty thirty forty fifty sixty seventy eighty ninety].freeze
|
7
|
+
|
8
|
+
AM_EXPONENTS = {
|
9
|
+
3 => 'thousand', 6 => 'million', 9 => 'billion', 12 => 'trillion',
|
10
|
+
15 => 'quadrillion', 18 => 'quintillion', 21 => 'sexillion', 24 => 'septillion',
|
11
|
+
27 => 'octillion', 30 => 'nonillion', 33 => 'decillion', 36 => 'undecillion',
|
12
|
+
39 => 'duodecillion', 42 => 'tredecillion', 45 => 'quattuordecillion', 48 => 'quindecillion',
|
13
|
+
51 => 'sexdecillion', 54 => 'septendecillion', 57 => 'octodecillion', 60 => 'novemdecillion',
|
14
|
+
63 => 'vigintillion', 66 => 'unvigintillion', 69 => 'duovigintillion'
|
15
|
+
}.freeze
|
16
|
+
|
17
|
+
EU_EXPONENTS = {
|
18
|
+
3 => 'thousand', 6 => 'million', 9 => 'milliard', 12 => 'billion',
|
19
|
+
15 => 'billiard', 18 => 'trillion', 21 => 'trilliard', 24 => 'quadrillion',
|
20
|
+
27 => 'quadrilliard', 30 => 'quintillion', 33 => 'quintilliard', 36 => 'sextillion',
|
21
|
+
39 => 'sextilliard', 42 => 'septillion', 45 => 'septilliard', 48 => 'octillion',
|
22
|
+
51 => 'octilliard', 54 => 'noventillion', 57 => 'noventilliard', 60 => 'decillion',
|
23
|
+
63 => 'decilliard', 66 => 'undecillion', 69 => 'undecilliard'
|
24
|
+
}.freeze
|
25
|
+
|
26
|
+
UK_EXPONENTS = {
|
27
|
+
3 => 'thousand', 6 => 'million', 12 => 'billion', 15 => 'billiard',
|
28
|
+
18 => 'trillion', 21 => 'trilliard', 24 => 'quadrillion'
|
29
|
+
}.freeze
|
30
|
+
|
31
|
+
FR_EXPONENTS = {
|
32
|
+
3 => 'mille', 6 => 'million', 9 => 'milliard', 12 => 'billion',
|
33
|
+
15 => 'billiard', 18 => 'trillion', 21 => 'trilliard'
|
34
|
+
}.freeze
|
35
|
+
|
36
|
+
INDIAN_UNITS = ['', 'thousand', 'lakh', 'crore'].freeze
|
37
|
+
|
38
|
+
COUNTRY_EXPONENTS = {
|
39
|
+
us: AM_EXPONENTS,
|
40
|
+
eu: EU_EXPONENTS,
|
41
|
+
uk: UK_EXPONENTS,
|
42
|
+
fr: FR_EXPONENTS,
|
43
|
+
in: INDIAN_UNITS
|
44
|
+
}.freeze
|
45
|
+
|
46
|
+
class << self
|
47
|
+
def to_words(number, country: :us, include_and: true)
|
48
|
+
return to_words_indian(number) if country == :in
|
49
|
+
|
50
|
+
val = number.to_i.abs
|
51
|
+
return 'zero' if val.zero?
|
52
|
+
|
53
|
+
exp_hash = COUNTRY_EXPONENTS[country] || AM_EXPONENTS
|
54
|
+
to_words_generic(val, exp_hash, include_and)
|
55
|
+
end
|
56
|
+
|
57
|
+
def to_words_indian(num)
|
58
|
+
integer_part, decimal_part = num.to_s.split('.')
|
59
|
+
integer_words = indian_units_to_words(integer_part.to_i)
|
60
|
+
return integer_words if decimal_part.nil? || decimal_part.to_i.zero?
|
61
|
+
|
62
|
+
decimal_words = decimal_part.chars.map { |d| sub_thousand_to_words(d.to_i) }.join(' ')
|
63
|
+
"#{integer_words} and #{decimal_words}"
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def to_words_generic(val, exp_hash, include_and)
|
69
|
+
chunks = []
|
70
|
+
while val.positive?
|
71
|
+
chunks << val % 1000
|
72
|
+
val /= 1000
|
73
|
+
end
|
74
|
+
|
75
|
+
result = []
|
76
|
+
chunks.each_with_index do |chunk, index|
|
77
|
+
next if chunk.zero?
|
78
|
+
words = hundreds_to_words(chunk, include_and && index.zero?)
|
79
|
+
result.unshift("#{words} #{exp_hash[index * 3]}".strip)
|
80
|
+
end
|
81
|
+
result.join(' ').strip
|
82
|
+
end
|
83
|
+
|
84
|
+
def hundreds_to_words(val, include_and = false)
|
85
|
+
return '' if val.zero?
|
86
|
+
|
87
|
+
words = []
|
88
|
+
if val >= 100
|
89
|
+
words << "#{ONES[val / 100]} hundred"
|
90
|
+
val %= 100
|
91
|
+
words << 'and' if val.positive? && include_and
|
92
|
+
end
|
93
|
+
|
94
|
+
words << TENS[val / 10] if val >= 20
|
95
|
+
val %= 10 if val >= 20
|
96
|
+
words << ONES[val] if val.positive?
|
97
|
+
words.join(' ').strip
|
98
|
+
end
|
99
|
+
|
100
|
+
def indian_units_to_words(num)
|
101
|
+
num = num.to_i
|
102
|
+
return 'zero' if num.zero?
|
103
|
+
words = []
|
104
|
+
unit_index = 0
|
105
|
+
|
106
|
+
loop do
|
107
|
+
break if num.zero?
|
108
|
+
|
109
|
+
num, remainder = unit_index.zero? ? num.divmod(1000) : num.divmod(100)
|
110
|
+
words.unshift("#{sub_thousand_to_words(remainder)} #{INDIAN_UNITS[unit_index]}".strip) if remainder.positive?
|
111
|
+
unit_index += 1
|
112
|
+
end
|
113
|
+
|
114
|
+
words.join(' ').strip
|
115
|
+
end
|
116
|
+
|
117
|
+
def sub_thousand_to_words(num)
|
118
|
+
num = num.to_i
|
119
|
+
return ONES[num] if num < 20
|
120
|
+
return "#{ONES[num / 100]} hundred" if num >= 100 && (num % 100).zero?
|
121
|
+
|
122
|
+
if num < 100
|
123
|
+
"#{TENS[num / 10]} #{ONES[num % 10]}".strip
|
124
|
+
else
|
125
|
+
"#{ONES[num / 100]} hundred and #{sub_thousand_to_words(num % 100)}"
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
data/lib/num_words/version.rb
CHANGED
data/lib/num_words.rb
CHANGED
data/num_words-0.1.0.gem
ADDED
Binary file
|
data/num_words-0.2.0.gem
ADDED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: num_words
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- mrmalvi
|
@@ -22,7 +22,10 @@ files:
|
|
22
22
|
- Rakefile
|
23
23
|
- exe/num_words
|
24
24
|
- lib/num_words.rb
|
25
|
+
- lib/num_words/converter.rb
|
25
26
|
- lib/num_words/version.rb
|
27
|
+
- num_words-0.1.0.gem
|
28
|
+
- num_words-0.2.0.gem
|
26
29
|
- sig/num_words.rbs
|
27
30
|
homepage: https://github.com/mrmalvi/num_words
|
28
31
|
licenses: []
|
@@ -37,7 +40,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
37
40
|
requirements:
|
38
41
|
- - ">="
|
39
42
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
43
|
+
version: 2.7.0
|
41
44
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
42
45
|
requirements:
|
43
46
|
- - ">="
|