num_words 0.2.0 → 0.4.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: 92bd9503909fd6d11da13baeccbe68e60c86505d1cb9aabc057ca704c962af4b
4
- data.tar.gz: db689f477ab8a791fc8c09a648407b2edb3a2fa954a780034b6c5d1e2218fe10
3
+ metadata.gz: dcb338b276c0afbc161d4ede15bb75c6f64fd279be42066ecabb9c2c986be10c
4
+ data.tar.gz: 60b8112d1ad8729eb652d7acd893b1cd1e5aa83b5ac31a200ff8df06ca83a4a8
5
5
  SHA512:
6
- metadata.gz: 98db3a1bcf32c42384c53cd990c83e37c22d1a0bb47ad91beecf0b96009051405e18c72cec3a35ec71de49bdd127aca44cf41fa2d34c78fdae5a6acbb82bde7d
7
- data.tar.gz: 7df9d662a74480d9ae3f1b41a1153d5700726cf19f4f6572cf8e93c2224f4e90ab3f6490dd1411d70f339333cf09dd70dbc05795d4d773685a4a9e9ad521e992
6
+ metadata.gz: e12980e8da746190aa011b645978741ac7c7dbc2ce5c9dc91c8fa6ebae3ca4dd57d25b81295d3d28294fc417e7ca0dc3536e45cead806363fcc62122c633442b
7
+ data.tar.gz: 42dc76855150a5c44fa7cce78d6fa401ec4e161ee6808642dfded60919d65b5ec01bee2b939b288f37ac5dd16948c556b5f79a8f7d5f9cd8af2536c58f580e5f
data/README.md CHANGED
@@ -1,36 +1,31 @@
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 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
+ bundle add num_words
@@ -2,70 +2,69 @@
2
2
  # frozen_string_literal: true
3
3
 
4
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
5
+ # --- English words ---
6
+ ONES_EN = %w[zero one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen].freeze
7
+ TENS_EN = %w[zero ten twenty thirty forty fifty sixty seventy eighty ninety].freeze
7
8
 
9
+ # --- Hindi words ---
10
+ ONES_HI = %w[शून्य एक दो तीन चार पाँच छह सात आठ नौ दस ग्यारह बारह तेरह चौदह पंद्रह सोलह सत्रह अठारह उन्नीस].freeze
11
+ TENS_HI = %w[शून्य दस बीस तीस चालीस पचास साठ सत्तर अस्सी नब्बे].freeze
12
+ INDIAN_UNITS_HI = ['', 'हज़ार', 'लाख', 'करोड़', 'अरब', 'खरब'].freeze
13
+
14
+ # --- English exponents ---
8
15
  AM_EXPONENTS = {
9
16
  3 => 'thousand', 6 => 'million', 9 => 'billion', 12 => 'trillion',
10
17
  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'
18
+ 27 => 'octillion', 30 => 'nonillion', 33 => 'decillion', 36 => 'undecillion'
24
19
  }.freeze
25
20
 
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
21
+ INDIAN_UNITS_EN = ['', 'thousand', 'lakh', 'crore', 'arab', 'kharab'].freeze
37
22
 
38
23
  COUNTRY_EXPONENTS = {
39
24
  us: AM_EXPONENTS,
40
- eu: EU_EXPONENTS,
41
- uk: UK_EXPONENTS,
42
- fr: FR_EXPONENTS,
43
- in: INDIAN_UNITS
25
+ in: INDIAN_UNITS_EN
44
26
  }.freeze
45
27
 
46
28
  class << self
47
- def to_words(number, country: :us, include_and: true)
48
- return to_words_indian(number) if country == :in
29
+ # Main method: convert number to words
30
+ # language: :en or :hi
31
+ def to_words(number, country: :us, language: :en, include_and: true)
32
+ if [:in].include?(country) && language == :hi
33
+ return to_words_indian(number, language: language)
34
+ end
49
35
 
50
36
  val = number.to_i.abs
51
37
  return 'zero' if val.zero?
52
38
 
53
39
  exp_hash = COUNTRY_EXPONENTS[country] || AM_EXPONENTS
54
- to_words_generic(val, exp_hash, include_and)
40
+ ones_array = language == :hi ? ONES_HI : ONES_EN
41
+ tens_array = language == :hi ? TENS_HI : TENS_EN
42
+ units = language == :hi ? INDIAN_UNITS_HI : INDIAN_UNITS_EN
43
+
44
+ if country == :in
45
+ to_words_indian(number, language: language)
46
+ else
47
+ to_words_generic(val, exp_hash, include_and, ones_array, tens_array)
48
+ end
55
49
  end
56
50
 
57
- def to_words_indian(num)
51
+ # Indian system (supports English & Hindi)
52
+ def to_words_indian(num, language: :en)
58
53
  integer_part, decimal_part = num.to_s.split('.')
59
- integer_words = indian_units_to_words(integer_part.to_i)
54
+ ones_array = language == :hi ? ONES_HI : ONES_EN
55
+ tens_array = language == :hi ? TENS_HI : TENS_EN
56
+ units = language == :hi ? INDIAN_UNITS_HI : INDIAN_UNITS_EN
57
+
58
+ integer_words = indian_units_to_words(integer_part.to_i, ones_array, tens_array, units)
60
59
  return integer_words if decimal_part.nil? || decimal_part.to_i.zero?
61
60
 
62
- decimal_words = decimal_part.chars.map { |d| sub_thousand_to_words(d.to_i) }.join(' ')
61
+ decimal_words = decimal_part.chars.map { |d| sub_thousand_to_words(d.to_i, ones_array, tens_array) }.join(' ')
63
62
  "#{integer_words} and #{decimal_words}"
64
63
  end
65
64
 
66
65
  private
67
66
 
68
- def to_words_generic(val, exp_hash, include_and)
67
+ def to_words_generic(val, exp_hash, include_and, ones_array, tens_array)
69
68
  chunks = []
70
69
  while val.positive?
71
70
  chunks << val % 1000
@@ -75,55 +74,62 @@ module NumWords
75
74
  result = []
76
75
  chunks.each_with_index do |chunk, index|
77
76
  next if chunk.zero?
78
- words = hundreds_to_words(chunk, include_and && index.zero?)
77
+ words = hundreds_to_words(chunk, include_and && index.zero?, ones_array, tens_array)
79
78
  result.unshift("#{words} #{exp_hash[index * 3]}".strip)
80
79
  end
81
80
  result.join(' ').strip
82
81
  end
83
82
 
84
- def hundreds_to_words(val, include_and = false)
83
+ def hundreds_to_words(val, include_and, ones_array, tens_array)
85
84
  return '' if val.zero?
86
85
 
87
86
  words = []
88
87
  if val >= 100
89
- words << "#{ONES[val / 100]} hundred"
88
+ words << "#{ones_array[val / 100]} #{ones_array == ONES_HI ? 'सौ' : 'hundred'}"
90
89
  val %= 100
91
- words << 'and' if val.positive? && include_and
90
+ words << 'and' if val.positive? && include_and && ones_array != ONES_HI
92
91
  end
93
92
 
94
- words << TENS[val / 10] if val >= 20
93
+ words << tens_array[val / 10] if val >= 20
95
94
  val %= 10 if val >= 20
96
- words << ONES[val] if val.positive?
95
+ words << ones_array[val] if val.positive?
97
96
  words.join(' ').strip
98
97
  end
99
98
 
100
- def indian_units_to_words(num)
99
+ def indian_units_to_words(num, ones_array, tens_array, units)
101
100
  num = num.to_i
102
- return 'zero' if num.zero?
101
+ return ones_array[0] if num.zero?
102
+
103
103
  words = []
104
104
  unit_index = 0
105
105
 
106
106
  loop do
107
107
  break if num.zero?
108
-
109
108
  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?
109
+ words.unshift("#{sub_thousand_to_words(remainder, ones_array, tens_array)} #{units[unit_index]}".strip) if remainder.positive?
111
110
  unit_index += 1
112
111
  end
113
112
 
114
113
  words.join(' ').strip
115
114
  end
116
115
 
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?
116
+ def sub_thousand_to_words(num, ones_array, tens_array)
117
+ return ones_array[num] if num < 20
118
+ return "#{ones_array[num / 100]} #{ones_array == ONES_HI ? 'सौ' : 'hundred'}" if num >= 100 && (num % 100).zero?
121
119
 
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)}"
120
+ words = []
121
+ if num >= 100
122
+ words << "#{ones_array[num / 100]} #{ones_array == ONES_HI ? 'सौ' : 'hundred'}"
123
+ num %= 100
124
+ end
125
+
126
+ if num >= 20
127
+ words << tens_array[num / 10]
128
+ num %= 10
126
129
  end
130
+
131
+ words << ones_array[num] if num.positive?
132
+ words.join(' ').strip
127
133
  end
128
134
  end
129
135
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module NumWords
4
- VERSION = "0.2.0"
4
+ VERSION = "0.4.0"
5
5
  end
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.2.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - mrmalvi
@@ -24,10 +24,10 @@ files:
24
24
  - lib/num_words.rb
25
25
  - lib/num_words/converter.rb
26
26
  - lib/num_words/version.rb
27
- - num_words-0.1.0.gem
28
27
  - sig/num_words.rbs
29
28
  homepage: https://github.com/mrmalvi/num_words
30
- licenses: []
29
+ licenses:
30
+ - MIT
31
31
  metadata:
32
32
  allowed_push_host: https://rubygems.org
33
33
  homepage_uri: https://github.com/mrmalvi/num_words
@@ -39,7 +39,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
39
39
  requirements:
40
40
  - - ">="
41
41
  - !ruby/object:Gem::Version
42
- version: 3.2.0
42
+ version: 2.7.0
43
43
  required_rubygems_version: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
data/num_words-0.1.0.gem DELETED
Binary file