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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 21d205d24368e2f8f01249971360cd573497c2892cea31840289831937af26f0
4
- data.tar.gz: 5597dd4bc9baf0217b5bca0111dc2e214cae69838de05635ba53849ba72c017c
3
+ metadata.gz: 24463f1da6ace2a42347b2e4bd275527a02510175087ebc98eaf3011ea56f4ff
4
+ data.tar.gz: e61dc04d74d11bde0825d575a5240b96790d1a156ad8048813449adf1e267e05
5
5
  SHA512:
6
- metadata.gz: e4ff68ce798397ccea435a92976665940d8fe23a869a4dc34332318f81caf6ec81f3c85153349c52bc40bd52999fd557f709fff04c60e8c434aa3e7d4ce2661d
7
- data.tar.gz: f5cf56ac330f7de0d23ead06d6989e40ad461a85484adb044ad20c65fd493cc01f25aeb3df00bfbe2700955292844378615b43764849b3ae57c996b8a10bf111
6
+ metadata.gz: 9decb67c34898169365951b2c04c79449c0024ea83263ed30a8d0412ce1f6f2ac62a6423e380c9492cd87afce0841085e3f4e06900b9141a87427d4043fc8a04
7
+ data.tar.gz: 2f5fe30029e8c3ed6915c0ace3f913d3ed3ea0f47ac119f200b1a8dc4b410e0575317f5011275bc40c466e1593af21732c918829b02bfa1a47cd5ac3f0709704
data/README.md CHANGED
@@ -1,36 +1,32 @@
1
1
  # NumWords
2
2
 
3
- TODO: Delete this and the text below, and describe your gem
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
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/num_words`. To experiment with that code, run `bin/console` for an interactive prompt.
5
+ ---
6
6
 
7
- ## Installation
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
- If bundler is not being used to manage dependencies, install the gem by executing:
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
- ```bash
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
- ## Development
21
+ ## Installation
28
22
 
29
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
23
+ ### Using RubyGems
30
24
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
25
+ After releasing your gem to [RubyGems.org](https://rubygems.org), install it with:
32
26
 
33
- ## Contributing
27
+ ```bash
28
+ # Using Bundler
29
+ bundle add gem 'num_words'
34
30
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/num_words.
36
- # num_words
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module NumWords
4
- VERSION = "0.1.0"
4
+ VERSION = "0.3.0"
5
5
  end
data/lib/num_words.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "num_words/version"
4
+ require_relative "num_words/converter"
4
5
 
5
6
  module NumWords
6
7
  class Error < StandardError; end
Binary file
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.1.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: 3.2.0
43
+ version: 2.7.0
41
44
  required_rubygems_version: !ruby/object:Gem::Requirement
42
45
  requirements:
43
46
  - - ">="