kabal 0.3.5 → 1.0.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
  SHA1:
3
- metadata.gz: 87d659049e316b750ac3b8d89e42c3a95bfecc4d
4
- data.tar.gz: 19aa78c47a2aa03e90871de4cf094654c568b142
3
+ metadata.gz: de5e475e931da2b5e708213ce699c0e69cdcb1c5
4
+ data.tar.gz: 8f37d26b3228d9b9471fff1397de6a1ed3dee356
5
5
  SHA512:
6
- metadata.gz: d326228e18f5f2a2ae8cbb291cd3880771c7498cd3360f9ebc7c0503dc774f207fef91731cc0ff498c8cf21dea5a7e45e006122a90554df9addf8bde001f7937
7
- data.tar.gz: 8594a4ef587c65f98a1fd19259dbc0ef672c1309a38bdc2126c937c84137b729e4908550b54a0141e279799bd7972514dfdb385c93abf2a656482cf37cde528b
6
+ metadata.gz: a75d13edce6e537158b6ab2d9be8a5bbd46db205b9d693e851777fb4bb13fbcf0c6d9448ee4cf78425ad5e715666accf37e16025b373733d7650ce1b9847ec3c
7
+ data.tar.gz: 61291e01e663a5b7a05daa5117df56b3fe0976681d61037ace697056f63d9e90d0bcc97770d21bbd2338b3891661e0375f39e8b303f2722548d010c40d8ecd87
data/.gitignore CHANGED
@@ -20,5 +20,3 @@ tmp
20
20
  *.o
21
21
  *.a
22
22
  mkmf.log
23
- *.swp
24
- *.swo
data/Gemfile CHANGED
@@ -8,3 +8,4 @@ gem 'tconsole', git: "git://github.com/gma/tconsole"
8
8
  gem 'coveralls', require: false
9
9
  gem 'simplecov'
10
10
  gem 'minitest', '4.7.5'
11
+ gem 'activesupport'
data/README.md CHANGED
@@ -7,9 +7,10 @@
7
7
  [![endorse](https://api.coderwall.com/kalashnikovisme/endorsecount.png)](https://coderwall.com/kalashnikovisme)
8
8
  [![Dependency Status](https://gemnasium.com/kalashnikovisme/kabal.svg)](https://gemnasium.com/kalashnikovisme/kabal)
9
9
  [![Still MainTained](http://stillmaintained.com/kalashnikovisme/kabal.png)](http://stillmaintained.com/kalashnikovisme/kabal)
10
+ [![Code Climate](https://codeclimate.com/github/kalashnikovisme/kabal/badges/gpa.svg)](https://codeclimate.com/github/kalashnikovisme/kabal)
10
11
 
11
12
 
12
- Kabal allows you to translate number into text.
13
+ Kabal allows you to translate number into text. See Demo on [http://kabal.herokuapp.com](http://kabal.herokuapp.com)
13
14
 
14
15
  ## Installation
15
16
 
@@ -51,6 +52,7 @@ Supported Languages:
51
52
  * Negative Numbers
52
53
  * Deutsch
53
54
  * Natural Number { max 10 ** 24 }
55
+ * Fractional Numbers
54
56
  * Negative Numbers
55
57
 
56
58
  Interfaces:
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
9
9
  spec.authors = ["Pavel Kalashnikov"]
10
10
  spec.email = ["kalashnikovisme@gmail.com"]
11
11
  spec.summary = %q{Number To Text Helper}
12
- spec.description = %q{Kabal allows you to translate numbers into text on languages: English, Russian, Deutsch}
12
+ spec.description = %q{Kabal allows you to translate numbers into text on languages: English, Russian, Deutsch. See demo on http://kabal.herokuapp.com}
13
13
  spec.homepage = "https://github.com/kalashnikovisme/kabal"
14
14
  spec.license = "MIT"
15
15
  spec.required_ruby_version = '>= 2.0.0'
@@ -1,7 +1,7 @@
1
- autoload :Version, "kabal/version"
2
- require "kabal/supported_languages"
3
- require "kabal/errors"
4
- require "kabal/config"
1
+ autoload :Version, 'kabal/version'
2
+ require 'kabal/supported_languages'
3
+ require 'kabal/errors'
4
+ require 'kabal/config'
5
5
  require 'yaml'
6
6
 
7
7
  module Kabal
@@ -14,22 +14,22 @@ module Kabal
14
14
  end
15
15
 
16
16
  def language=(language_to_set)
17
- languages = Kabal::Config::YamlLoader.yaml_object "languages"
17
+ languages = Kabal::Config::YamlLoader.yaml_object 'languages'
18
18
  if languages[language_to_set]
19
19
  @language = language_to_set
20
20
  else
21
- raise NoLanguageSupportError.message
21
+ fail NoLanguageSupportError.message
22
22
  end
23
23
  end
24
24
 
25
25
  def to_text_in_language(number, language_at_once)
26
26
  number = string_convert number
27
- languages = Kabal::Config::YamlLoader.yaml_object "languages"
27
+ languages = Kabal::Config::YamlLoader.yaml_object 'languages'
28
28
  if languages[language_at_once]
29
- if number > maximum_for(language_at_once) or number < minimum_for(language_at_once)
29
+ if number > maximum_for(language_at_once) || number < minimum_for(language_at_once)
30
30
  NumberOutRangeError.message
31
31
  else
32
- obj = Object.const_get("Kabal::" + language_at_once).new
32
+ obj = Object.const_get(language_class_name(language_at_once)).new
33
33
  obj.convert number
34
34
  end
35
35
  else
@@ -39,9 +39,9 @@ module Kabal
39
39
 
40
40
  def to_text_in_language_by_index(number, language_at_once_index)
41
41
  number = string_convert number
42
- languages = Kabal::Config::YamlLoader.yaml_object("languages").to_a
42
+ languages = Kabal::Config::YamlLoader.yaml_object('languages').to_a
43
43
  if languages[language_at_once_index]
44
- obj = Object.const_get("Kabal::" + languages[language_at_once_index].first).new
44
+ obj = Object.const_get(language_class_name(languages[language_at_once_index].first)).new
45
45
  obj.convert number
46
46
  else
47
47
  NoLanguageSupportError.message
@@ -49,42 +49,42 @@ module Kabal
49
49
  end
50
50
 
51
51
  def current_language
52
- @language ||= "Russian"
52
+ @language ||= 'English'
53
53
  @language
54
54
  end
55
55
 
56
56
  def supported_languages
57
- languages = Kabal::Config::YamlLoader.yaml_object "languages"
57
+ languages = Kabal::Config::YamlLoader.yaml_object 'languages'
58
58
  languages.keys
59
59
  end
60
60
 
61
61
  def current_language_supports_natural?
62
- obj = Object.const_get("Kabal::" + current_language).new
62
+ obj = Object.const_get(language_class_name(current_language)).new
63
63
  obj.supports_natural?
64
64
  end
65
65
 
66
66
  def current_language_supports_fractional?
67
- obj = Object.const_get("Kabal::" + current_language).new
67
+ obj = Object.const_get(language_class_name(current_language)).new
68
68
  obj.supports_fractional?
69
69
  end
70
70
 
71
71
  def language_supports_negative?(language)
72
- obj = Object.const_get("Kabal::" + language).new
72
+ obj = Object.const_get(language_class_name(language)).new
73
73
  obj.supports_negative?
74
74
  end
75
75
 
76
76
  def language_supports_fractional?(language)
77
- obj = Object.const_get("Kabal::" + language).new
77
+ obj = Object.const_get(language_class_name(language)).new
78
78
  obj.supports_fractional?
79
79
  end
80
80
 
81
81
  def maximum_for(language)
82
- obj = Object.const_get("Kabal::" + language).new
82
+ obj = Object.const_get(language_class_name(language)).new
83
83
  obj.max_value
84
84
  end
85
85
 
86
86
  def minimum_for(language)
87
- obj = Object.const_get("Kabal::" + language).new
87
+ obj = Object.const_get(language_class_name(language)).new
88
88
  obj.min_value
89
89
  end
90
90
 
@@ -103,6 +103,10 @@ module Kabal
103
103
  end
104
104
 
105
105
  def string_is_float?(number)
106
- number.include? "."
106
+ number.include? '.'
107
+ end
108
+
109
+ def language_class_name(language)
110
+ 'Kabal::' + language
107
111
  end
108
112
  end
@@ -1,3 +1,3 @@
1
1
  module Kabal::Config
2
- autoload :YamlLoader, "kabal/config/yaml_loader.rb"
2
+ autoload :YamlLoader, 'kabal/config/yaml_loader.rb'
3
3
  end
@@ -1,12 +1,14 @@
1
+ require 'active_support/core_ext/hash'
2
+
1
3
  module Kabal
2
4
  module Config
3
5
  class YamlLoader
4
6
  def self.gem_root
5
- Gem::Specification.find_by_name("kabal").gem_dir
7
+ Gem::Specification.find_by_name('kabal').gem_dir
6
8
  end
7
9
 
8
10
  def self.yaml_object(filename)
9
- yaml_obj = YAML.load_file(gem_root + "/yaml/" + filename + ".yml")
11
+ YAML.load_file(gem_root + '/yaml/' + filename + '.yml').with_indifferent_access
10
12
  end
11
13
  end
12
14
  end
@@ -1,6 +1,8 @@
1
- module Kabal::Errors
2
- require "kabal/errors/no_language_support_error"
3
- require "kabal/errors/number_out_range_error"
4
- require "kabal/errors/no_support_for_fractional_numbers_on_current_language_error"
5
- require "kabal/errors/error"
1
+ module Kabal
2
+ module Errors
3
+ require 'kabal/errors/no_language_support_error'
4
+ require 'kabal/errors/number_out_range_error'
5
+ require 'kabal/errors/no_support_for_fractional_numbers_on_current_language_error'
6
+ require 'kabal/errors/error'
7
+ end
6
8
  end
@@ -1,14 +1,14 @@
1
- require "kabal/config"
1
+ require 'kabal/config'
2
2
 
3
3
  module Kabal
4
4
  module Errors
5
5
  class Error < StandardError
6
- @message = "There is some error"
7
- @code = "Unknown error code"
6
+ @message = 'There is some error'
7
+ @code = 'Unknown error code'
8
8
 
9
9
  def self.message
10
- errors = Kabal::Config::YamlLoader.yaml_object "errors"
11
- errors["errors"]["messages"][@code]
10
+ errors = Kabal::Config::YamlLoader.yaml_object 'errors'
11
+ errors[:errors][:messages][@code]
12
12
  end
13
13
  end
14
14
  end
@@ -1,4 +1,4 @@
1
- require "kabal/errors/error"
1
+ require 'kabal/errors/error'
2
2
 
3
3
  module Kabal
4
4
  module Errors
@@ -1,4 +1,4 @@
1
- require "kabal/errors/error"
1
+ require 'kabal/errors/error'
2
2
 
3
3
  module Kabal
4
4
  module Errors
@@ -1,4 +1,4 @@
1
- require "kabal/errors/error"
1
+ require 'kabal/errors/error'
2
2
 
3
3
  module Kabal
4
4
  module Errors
@@ -3,20 +3,9 @@ require 'kabal/languages/deutsch/natural_numbers'
3
3
  require 'kabal/languages/deutsch/declinations'
4
4
  require 'kabal/languages/deutsch/fractional_numbers'
5
5
 
6
- class Kabal::Deutsch < Kabal::Language
7
- include Kabal::DeutschRules::NaturalNumbers
8
- include Kabal::DeutschRules::FractionalNumbers
9
-
10
- def convert(number)
11
- if need_minus? number
12
- minus + " " + number_words(-number)
13
- else
14
- number_words number
15
- end
16
- end
17
-
18
- def number_words(number)
19
- return natural_number_name number.round if natural? number
20
- fractional_number_name number if fractional? number
6
+ module Kabal
7
+ class Deutsch < Kabal::Language
8
+ include Kabal::DeutschRules::NaturalNumbers
9
+ include Kabal::DeutschRules::FractionalNumbers
21
10
  end
22
11
  end
@@ -3,10 +3,10 @@ module Kabal
3
3
  module Declinations
4
4
  def self.name_with_declination(number_name, count)
5
5
  if count != 1
6
- if number_name[-1, 1] == "n"
7
- return number_name + "en"
8
- elsif number_name[-1, 1] == "e"
9
- return number_name + "n"
6
+ if number_name[-1, 1] == 'n'
7
+ return number_name + 'en'
8
+ elsif number_name[-1, 1] == 'e'
9
+ return number_name + 'n'
10
10
  end
11
11
  end
12
12
  number_name
@@ -2,7 +2,7 @@ module Kabal
2
2
  module DeutschRules
3
3
  module FractionalNumbers
4
4
  def fractional_number_name(number)
5
- whole_part_name(number) + " " + dot + " " + fractional_part_name(number)
5
+ whole_part_name(number) + ' ' + dot + ' ' + fractional_part_name(number)
6
6
  end
7
7
 
8
8
  def whole_part_name(number)
@@ -10,33 +10,9 @@ module Kabal
10
10
  natural_number_name(count)
11
11
  end
12
12
 
13
- def fractional_part_name(number)
14
- name = ""
15
- count_string = fractional_part_string(number).split('.')[1]
16
- count = count_string.to_i
17
- if count_string.size != count.to_s.size
18
- (count_string.size - count.to_s.size).times do
19
- name += names["single"][0] + " "
20
- end
21
- name + natural_number_name(count)
22
- else
23
- natural_number_name(count)
24
- end
25
- end
26
-
27
13
  def fractional_part_string(number)
28
14
  "%.#{fractional_part_order(number)}f" % number
29
15
  end
30
-
31
- def fractional_part_order(number)
32
- #FIXME find better way with whole 0 numbers
33
- number_string = number.to_s
34
- if number_string.include? "-"
35
- number_string.split('-')[1].to_i
36
- else
37
- number_string.split('.')[1].length
38
- end
39
- end
40
16
  end
41
17
  end
42
18
  end
@@ -1,35 +1,29 @@
1
1
  module Kabal
2
2
  module DeutschRules
3
3
  module NaturalNumbers
4
- def natural_number_name(number)
5
- return single number if number >= 0 and number <= 19
6
- return two_words number if number >= 0 and number <= 99
7
- return three_words number if number >= 100 and number <= 999
8
- ten_powers number if number >= 100
9
- end
10
4
  def single(number)
11
- unless @ein
12
- names["single"][number]
13
- else
5
+ if @ein
14
6
  @ein = false
15
- names["single"][number].chop
7
+ names[:single][number].chop
8
+ else
9
+ names[:single][number]
16
10
  end
17
11
  end
18
12
 
19
13
  def two_words(number)
20
14
  return single number if number <= 19
21
- number_name = names["two_words"][number / 10]
15
+ number_name = names[:two_words][number / 10]
22
16
  @ein = (number % 10 == 1)
23
- number_name = single(number % 10) + names["and"] + number_name if (number % 10 != 0)
17
+ number_name = single(number % 10) + names[:and] + number_name if (number % 10 != 0)
24
18
  number_name
25
19
  end
26
20
 
27
21
  def three_words(number)
28
22
  return two_words number if number <= 99
29
23
  @ein = (number / 100 == 1)
30
- number_name = single(number / 100) + names["ten_powers"][2]
24
+ number_name = single(number / 100) + names[:ten_powers][2]
31
25
  number_name += two_words(number % 100) if (number % 100 >= 10)
32
- number_name += single(number % 100) if number % 100 < 10 and number % 100 != 0
26
+ number_name += single(number % 100) if number % 100 < 10 && number % 100 != 0
33
27
  number_name
34
28
  end
35
29
 
@@ -37,7 +31,7 @@ module Kabal
37
31
  less_thousands number if number_is_thousands? number
38
32
  return @number_name if number_is_thousands? number
39
33
  create_number_name number
40
- ten_powers number % (10 ** number_order(number))
34
+ ten_powers number % (10**number_order(number))
41
35
  end
42
36
 
43
37
  def create_number_name(number)
@@ -63,11 +57,19 @@ module Kabal
63
57
 
64
58
  def words_to_add(number)
65
59
  if millions_or_greater?(number)
66
- @number_name = count_name(number) + " " + Declinations.name_with_declination(names["ten_powers"][number_order(number)], count(number)) + " "
60
+ number_with_space number
67
61
  else
68
- @number_name = count_name(number) + Declinations.name_with_declination(names["ten_powers"][number_order(number)], count(number))
62
+ number_without_space number
69
63
  end
70
64
  end
65
+
66
+ def number_with_space(number)
67
+ @number_name = count_name(number) + ' ' + Declinations.name_with_declination(names[:ten_powers][number_order(number)], count(number)) + ' '
68
+ end
69
+
70
+ def number_without_space(number)
71
+ @number_name = count_name(number) + Declinations.name_with_declination(names[:ten_powers][number_order(number)], count(number))
72
+ end
71
73
  end
72
74
  end
73
75
  end
@@ -2,19 +2,9 @@ require 'kabal/languages/language'
2
2
  require 'kabal/languages/english/natural_numbers'
3
3
  require 'kabal/languages/english/fractional_numbers'
4
4
 
5
- class Kabal::English < Kabal::Language
6
- include Kabal::EnglishRules::NaturalNumbers
7
- include Kabal::EnglishRules::FractionalNumbers
8
- def convert_number(number)
9
- if need_minus? number
10
- minus + " " + number_words(-number)
11
- else
12
- number_words number
13
- end
14
- end
15
-
16
- def number_words(number)
17
- return natural_number_name number.round if natural? number
18
- fractional_number_name number if fractional? number
5
+ module Kabal
6
+ class English < Kabal::Language
7
+ include Kabal::EnglishRules::NaturalNumbers
8
+ include Kabal::EnglishRules::FractionalNumbers
19
9
  end
20
10
  end
@@ -2,45 +2,21 @@ module Kabal
2
2
  module EnglishRules
3
3
  module FractionalNumbers
4
4
  def fractional_number_name(number)
5
- if whole_part_name(number) != ""
6
- whole_part_name(number) + " " + dot + " " + fractional_part_name(number)
5
+ if whole_part_name(number) != ''
6
+ whole_part_name(number) + ' ' + dot + ' ' + fractional_part_name(number)
7
7
  else
8
- dot + " " + fractional_part_name(number)
8
+ dot + ' ' + fractional_part_name(number)
9
9
  end
10
10
  end
11
11
 
12
12
  def whole_part_name(number)
13
13
  count = number.floor
14
- count != 0 ? natural_number_name(count) : ""
15
- end
16
-
17
- def fractional_part_name(number)
18
- name = ""
19
- count_string = fractional_part_string(number).to_s.split('.')[1]
20
- count = count_string.to_i
21
- if count_string.size != count.to_s.size
22
- (count_string.size - count.to_s.size).times do
23
- name += names["single"][0] + " "
24
- end
25
- name + natural_number_name(count)
26
- else
27
- natural_number_name(count)
28
- end
14
+ count != 0 ? natural_number_name(count) : ''
29
15
  end
30
16
 
31
17
  def fractional_part_string(number)
32
18
  "%.#{fractional_part_order(number)}f" % number
33
19
  end
34
-
35
- def fractional_part_order(number)
36
- #FIXME find better way with whole 0 numbers
37
- number_string = number.to_s
38
- if number_string.include? "-"
39
- number_string.split('-')[1].to_i
40
- else
41
- number_string.split('.')[1].length
42
- end
43
- end
44
20
  end
45
21
  end
46
22
  end
@@ -1,28 +1,22 @@
1
1
  module Kabal
2
2
  module EnglishRules
3
3
  module NaturalNumbers
4
- def natural_number_name(number)
5
- return single number if number >= 0 and number <= 19
6
- return two_words number if number >= 0 and number <= 99
7
- return three_words number if number >= 100 and number <= 999
8
- ten_powers number if number >= 100
9
- end
10
4
  def single(number)
11
- names["single"][number]
5
+ names[:single][number]
12
6
  end
13
7
 
14
8
  def two_words(number)
15
9
  return single number if number <= 19
16
- number_name = names["two_words"][number / 10]
17
- number_name += " " + single(number % 10) if (number % 10 != 0)
10
+ number_name = names[:two_words][number / 10]
11
+ number_name += ' ' + single(number % 10) if (number % 10 != 0)
18
12
  number_name
19
13
  end
20
14
 
21
15
  def three_words(number)
22
16
  return two_words number if number <= 99
23
- number_name = single(number / 100) + " " + names["ten_powers"][2]
24
- number_name += " " + two_words(number % 100) if number % 100 >= 10
25
- number_name += " " + names["and"] + " " + single(number % 100) if number % 100 < 10 and number % 100 != 0
17
+ number_name = single(number / 100) + ' ' + names[:ten_powers][2]
18
+ number_name += ' ' + two_words(number % 100) if number % 100 >= 10
19
+ number_name += ' ' + names[:and] + ' ' + single(number % 100) if number % 100 < 10 && number % 100 != 0
26
20
  number_name
27
21
  end
28
22
 
@@ -30,25 +24,17 @@ module Kabal
30
24
  less_thousands number if number_is_thousands? number
31
25
  return @number_name if number_is_thousands? number
32
26
  create_number_name number
33
- ten_powers number % (10 ** number_order(number))
34
- end
35
-
36
- def create_number_name(number)
37
- if @number_name.nil?
38
- @number_name = count_name(number) + " " + names["ten_powers"][number_order(number)]
39
- elsif count(number) != 0
40
- @number_name += " " + count_name(number) + " " + names["ten_powers"][number_order(number)]
41
- end
27
+ ten_powers number % (10**number_order(number))
42
28
  end
43
29
 
44
- def count_name(number)
45
- three_words count(number)
30
+ def count_name_with_order_name(number)
31
+ three_words(count(number)) + ' ' + names[:ten_powers][number_order(number)]
46
32
  end
47
33
 
48
34
  def less_thousands(number)
49
35
  return if number == 0
50
- @number_name += " " + names["and"] if number < 100
51
- @number_name += " " + three_words(number % 1000) unless number == 0
36
+ @number_name += ' ' + names[:and] if number < 100
37
+ @number_name += ' ' + three_words(number % 1000) unless number == 0
52
38
  end
53
39
  end
54
40
  end
@@ -0,0 +1,40 @@
1
+ module Kabal
2
+ module GlobalRules
3
+ module FractionalNumbers
4
+ def fractional_part_order(number)
5
+ number_string = number.to_s
6
+ if number_string.include? '-'
7
+ number_string.split('-')[1].to_i
8
+ else
9
+ number_string.split('.')[1].length
10
+ end
11
+ end
12
+
13
+ def fractional_part_name(number)
14
+ @count_string = fractional_part_string(number).to_s.split('.')[1]
15
+ @count_int = @count_string.to_i
16
+ if there_zeros_before_fractional_part?
17
+ number_name_with_zeros + natural_number_name(@count_int)
18
+ else
19
+ natural_number_name @count_int
20
+ end
21
+ end
22
+
23
+ def there_zeros_before_fractional_part?
24
+ @count_string.size != @count_int.to_s.size
25
+ end
26
+
27
+ def zeros_number
28
+ @count_string.size - @count_int.to_s.size
29
+ end
30
+
31
+ def number_name_with_zeros
32
+ name = ''
33
+ zeros_number.times do
34
+ name += names[:single][0] + ' '
35
+ end
36
+ name
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,20 @@
1
+ module Kabal
2
+ module GlobalRules
3
+ module NaturalNumbers
4
+ def natural_number_name(number)
5
+ return single number if number >= 0 && number <= 19
6
+ return two_words number if number >= 0 && number <= 99
7
+ return three_words number if number >= 100 && number <= 999
8
+ ten_powers number if number >= 100
9
+ end
10
+
11
+ def create_number_name(number)
12
+ if @number_name.nil?
13
+ @number_name = count_name_with_order_name number
14
+ elsif count(number) != 0
15
+ @number_name += ' ' + count_name_with_order_name(number)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -1,8 +1,15 @@
1
+ require 'kabal/languages/global/fractional_numbers'
2
+ require 'kabal/languages/global/natural_numbers'
3
+
1
4
  module Kabal
2
5
  class Language
6
+ include Kabal::GlobalRules::NaturalNumbers
7
+ include Kabal::GlobalRules::FractionalNumbers
8
+
3
9
  def initialize
4
10
  @names = Kabal::Config::YamlLoader.yaml_object "languages/#{lang}"
5
- @supports = Kabal::Config::YamlLoader.yaml_object("support")["support"][lang]
11
+ support_file = Kabal::Config::YamlLoader.yaml_object('support')
12
+ @supports = support_file[:support][lang]
6
13
  end
7
14
 
8
15
  def convert(number)
@@ -13,22 +20,36 @@ module Kabal
13
20
  end
14
21
  end
15
22
 
23
+ def convert_number(number)
24
+ @number_name = nil
25
+ if need_minus? number
26
+ minus + ' ' + number_words(-number)
27
+ else
28
+ number_words number
29
+ end
30
+ end
31
+
32
+ def number_words(number)
33
+ return natural_number_name number.round if natural? number
34
+ fractional_number_name number if fractional? number
35
+ end
36
+
16
37
  def error(number)
17
38
  if number_is_out_of_the_range? number
18
39
  return Kabal::Errors::NumberOutRangeError.message
19
40
  end
20
- if not supports_fractional? and number % 1 != 0
41
+ if (!supports_fractional?) && (number % 1 != 0)
21
42
  Kabal::Errors::NoSupportForFractionalNumberOnCurrentLanguages.message
22
43
  end
23
44
  end
24
45
 
25
46
  def lang
26
- languages = Kabal::Config::YamlLoader.yaml_object "languages"
27
- @lang = languages[self.to_s.split(":")[-2]]
47
+ languages = Kabal::Config::YamlLoader.yaml_object 'languages'
48
+ @lang = languages[self.to_s.split(':')[-2]]
28
49
  end
29
50
 
30
51
  def supports_natural?
31
- @supports["natural"]
52
+ @supports[:natural]
32
53
  end
33
54
 
34
55
  def supports_negative?
@@ -36,11 +57,11 @@ module Kabal
36
57
  end
37
58
 
38
59
  def min_value
39
- eval @supports["natural"]["min"]
60
+ eval @supports[:natural][:min]
40
61
  end
41
62
 
42
63
  def max_value
43
- eval @supports["natural"]["max"]
64
+ eval @supports[:natural][:max]
44
65
  end
45
66
 
46
67
  def names
@@ -48,15 +69,15 @@ module Kabal
48
69
  end
49
70
 
50
71
  def minus
51
- names["minus"]
72
+ names[:minus]
52
73
  end
53
74
 
54
75
  def whole
55
- names["whole"]
76
+ names[:whole]
56
77
  end
57
78
 
58
79
  def dot
59
- names["dot"]
80
+ names[:dot]
60
81
  end
61
82
 
62
83
  def fractional?(number)
@@ -72,7 +93,7 @@ module Kabal
72
93
  end
73
94
 
74
95
  def number_is_google?(number)
75
- count(number) == 10 and number_order(number) == 99
96
+ count(number) == 10 && number_order(number) == 99
76
97
  end
77
98
 
78
99
  def number_order(number)
@@ -80,19 +101,23 @@ module Kabal
80
101
  end
81
102
 
82
103
  def count(number)
83
- number / (10 ** number_order(number))
104
+ number / (10**number_order(number))
84
105
  end
85
106
 
86
107
  def supports_fractional?
87
- @supports["fractional"]
108
+ @supports[:fractional]
88
109
  end
89
110
 
90
111
  def number_is_out_of_the_range?(number)
91
- number >= max_value or number <= min_value
112
+ number >= max_value || number <= min_value
113
+ end
114
+
115
+ def fractional_but_no_support_fractional?(number)
116
+ number % 1 != 0 && !supports_fractional?
92
117
  end
93
118
 
94
119
  def no_supports?(number)
95
- (number % 1 != 0 and not supports_fractional?) or number_is_out_of_the_range?(number)
120
+ fractional_but_no_support_fractional?(number) || number_is_out_of_the_range?(number)
96
121
  end
97
122
 
98
123
  def need_minus?(number)
@@ -3,22 +3,9 @@ require 'kabal/languages/russian/declinations'
3
3
  require 'kabal/languages/russian/natural_numbers'
4
4
  require 'kabal/languages/russian/fractional_numbers'
5
5
 
6
- class Kabal::Russian < Kabal::Language
7
- include Kabal::RussianRules::NaturalNumbers
8
- include Kabal::RussianRules::FractionalNumbers
9
-
10
- def convert_number(number)
11
- #FIXME find better way
12
- @number_name = nil
13
- if need_minus? number
14
- minus + " " + number_words(-number)
15
- else
16
- number_words number
17
- end
18
- end
19
-
20
- def number_words(number)
21
- return natural_number_name number.round if natural? number
22
- fractional_number_name number if fractional? number
6
+ module Kabal
7
+ class Russian < Kabal::Language
8
+ include Kabal::RussianRules::NaturalNumbers
9
+ include Kabal::RussianRules::FractionalNumbers
23
10
  end
24
11
  end
@@ -2,32 +2,30 @@ module Kabal
2
2
  module RussianRules
3
3
  module Declinations
4
4
  def self.name_with_declination(number_name, count)
5
- #for 5.0e-11 like numbers
6
- #FIXME find another way to convert number from exp form
7
- if count.to_s.include? "e"
5
+ if count.to_s.include? 'e'
8
6
  count = count.to_s.split('.')[0].to_i
9
7
  end
10
- #FIXME add gem russian
11
- if number_name[-1, 1] == "а"
8
+ # FIXME add gem russian
9
+ if number_name[-1, 1] == 'а'
12
10
  return number_name if ends_with_one? count
13
- return number_name[0..4] + "и" if end_with_two_or_three_of_four? count
11
+ return number_name[0..4] + 'и' if end_with_two_or_three_of_four? count
14
12
  number_name[0..4]
15
- elsif number_name[-1, 1] == "я"
13
+ elsif number_name[-1, 1] == 'я'
16
14
  return number_name if ends_with_one? count
17
- number_name[0..-3] + "ых"
15
+ number_name[0..-3] + 'ых'
18
16
  else
19
17
  return number_name if ends_with_one? count
20
- return number_name + "а" if end_with_two_or_three_of_four? count
21
- number_name + "ов"
18
+ return number_name + 'а' if end_with_two_or_three_of_four? count
19
+ number_name + 'ов'
22
20
  end
23
21
  end
24
22
 
25
23
  def self.ends_with_one?(count)
26
- count.to_s[-1] == "1" and (count % 100) / 10 != 1
24
+ count.to_s[-1] == '1' && (count % 100) / 10 != 1
27
25
  end
28
26
 
29
27
  def self.end_with_two_or_three_of_four?(count)
30
- count.to_s[-1] == "2" or count.to_s[-1] == "3" or count.to_s[-1] == "4"
28
+ count.to_s[-1] == '2' || count.to_s[-1] == '3' || count.to_s[-1] == '4'
31
29
  end
32
30
  end
33
31
  end
@@ -2,49 +2,38 @@ module Kabal
2
2
  module RussianRules
3
3
  module FractionalNumbers
4
4
  def fractional_number_name(number)
5
- whole_part_name(number) + " " + fractional_part_name(number)
5
+ whole_part_name(number) + ' ' + fractional_part_name(number)
6
6
  end
7
7
 
8
8
  def fractional_part_name(number)
9
- fractional_part = (number % 1).round(fractional_number_order(number))
10
- fractional_order = ((fractional_part) * (10 ** fractional_number_order(number))).to_s.split('.')[0].to_i
11
- feminine_natural_number_name(fractional_order, true) + " " + Declinations.name_with_declination(fractional_ten_powers_name(number), fractional_part)
9
+ fractional_part = (number % 1).round(fractional_part_order(number))
10
+ fractional_order = ((fractional_part) * (10**fractional_part_order(number))).to_s.split('.')[0].to_i
11
+ feminine_natural_number_name(fractional_order, true) + ' ' + Declinations.name_with_declination(fractional_ten_powers_name(number), fractional_part)
12
12
  end
13
13
 
14
14
  def whole_part_name(number)
15
15
  count = number.floor
16
- feminine_natural_number_name(count) + " " + Declinations.name_with_declination(whole, count)
16
+ feminine_natural_number_name(count) + ' ' + Declinations.name_with_declination(whole, count)
17
17
  end
18
18
 
19
19
  def fractional_ten_powers_name(number)
20
- ten_powers_name = ""
21
20
  if need_pre_word? number
22
- ten_powers_name = fractional_pre_word(number) + fractional_order_word(number)
21
+ fractional_pre_word(number) + fractional_order_word(number)
23
22
  else
24
- ten_powers_name = names["fractional_ten_powers"][fractional_number_order(number)]
23
+ names[:fractional_ten_powers][fractional_part_order(number)]
25
24
  end
26
25
  end
27
26
 
28
27
  def fractional_order_word(number)
29
- names["fractional_ten_powers"][fractional_number_order(number) - (fractional_number_order(number) % 3)]
28
+ names[:fractional_ten_powers][fractional_part_order(number) - (fractional_part_order(number) % 3)]
30
29
  end
31
30
 
32
31
  def fractional_pre_word(number)
33
- names["fractional_pre_words"][fractional_number_order(number) % 3]
32
+ names[:fractional_pre_words][fractional_part_order(number) % 3]
34
33
  end
35
34
 
36
35
  def need_pre_word?(number)
37
- fractional_number_order(number) > 3 and fractional_number_order(number) % 3 != 0
38
- end
39
-
40
- def fractional_number_order(number)
41
- #FIXME find better way with whole 0 numbers
42
- number_string = number.to_s
43
- if number_string.include? "-"
44
- number_string.split('-')[1].to_i
45
- else
46
- number_string.split('.')[1].length
47
- end
36
+ fractional_part_order(number) > 3 && fractional_part_order(number) % 3 != 0
48
37
  end
49
38
  end
50
39
  end
@@ -2,74 +2,67 @@ module Kabal
2
2
  module RussianRules
3
3
  module NaturalNumbers
4
4
  def feminine_natural_number_name(number, fractional_part = false)
5
+ @number_name = nil
5
6
  @number = number
6
7
  @feminine_name = !fractional_part
7
8
  @fractional_part = fractional_part
8
9
  natural_number_name number
9
10
  end
10
11
 
11
- def natural_number_name(number)
12
- #FIXME switch case next lines
13
- return single(number, true) if number >= 0 and number <= 19
14
- return two_words(number, true) if number >= 20 and number <= 99
15
- return three_words(number, true) if number >= 100 and number <= 999
16
- ten_powers(number) if number >= 1000
17
- end
18
-
19
- def single(number, this_is_end = false)
12
+ def single(number, this_is_end = true)
20
13
  if @feminine_name
21
14
  @feminine_name = false
22
- return names["single_feminine"][count(number) % 10] if count(number) % 10 == 1 or count(number) % 10 == 2
15
+ return names[:single_feminine][count(number) % 10] if count_can_be_feminine? number
23
16
  end
24
- if @fractional_part and this_is_end
17
+ if @fractional_part && this_is_end
25
18
  @fractional_part = false
26
- return names["single_feminine"][count(number) % 10] if count(number) % 10 == 1 or count(number) % 10 == 2
19
+ return names[:single_feminine][count(number) % 10] if count_can_be_feminine? number
27
20
  end
28
- names["single"][number]
21
+ names[:single][number]
29
22
  end
30
23
 
31
- def two_words(number, this_is_end = false)
24
+ def two_words(number, this_is_end = true)
32
25
  return single(number, this_is_end) if number <= 19
33
- number_name = names["two_words"][number / 10]
34
- number_name += " " + single(number % 10, this_is_end) if (number % 10 != 0)
26
+ number_name = names[:two_words][number / 10]
27
+ number_name += ' ' + single(number % 10, this_is_end) if (number % 10 != 0)
35
28
  number_name
36
29
  end
37
30
 
38
- def three_words(number, this_is_end = false)
31
+ def three_words(number, this_is_end = true)
39
32
  return two_words(number, this_is_end) if number / 100 == 0
40
- number_name = names["three_words"][number / 100]
41
- return number_name += " " + two_words(number % 100, this_is_end) if (number % 100 >= 20)
42
- return number_name += " " + single(number % 100, this_is_end) if (number % 100 != 0)
33
+ number_name = names[:three_words][number / 100]
34
+ return number_name += ' ' + two_words(number % 100, this_is_end) if (number % 100 >= 20)
35
+ return number_name += ' ' + single(number % 100, this_is_end) if (number % 100 != 0)
43
36
  number_name
44
37
  end
45
38
 
46
39
  def ten_powers(number)
47
- return names["ten_powers"][100] if number_is_google? number
40
+ return names[:ten_powers][100] if number_is_google? number
48
41
  less_thousands number if number_is_thousands? number
49
42
  return @number_name if number_is_thousands? number
50
43
  create_number_name number
51
44
  ten_powers(number % (10 ** number_order(number)))
52
45
  end
53
46
 
54
- def create_number_name(number)
55
- if @number_name.nil?
56
- @number_name = count_name(number) + " " + Declinations.name_with_declination(names["ten_powers"][number_order(number)], count(number))
57
- elsif count(number) != 0
58
- @number_name += " " + count_name(number) + " " + Declinations.name_with_declination(names["ten_powers"][number_order(number)], count(number))
59
- end
47
+ def count_can_be_feminine?(number)
48
+ count(number) % 10 == 1 || count(number) % 10 == 2
60
49
  end
61
50
 
62
51
  def less_thousands(number)
63
- @number_name += " " + three_words(number % 1000, true) unless number == 0
52
+ @number_name += ' ' + three_words(number % 1000) unless number == 0
64
53
  end
65
54
 
66
55
  def count_name(number)
67
- if (number.to_s[-4] == "1" or number.to_s[-4] == "2") and count(number) and (count(number) % 100) / 10 != 1 and number_order(number) == 3
56
+ if (number.to_s[-4] == '1' || number.to_s[-4] == '2') && count(number) && (count(number) % 100) / 10 != 1 && number_order(number) == 3
68
57
  @feminine_name = true
69
58
  else
70
59
  @feminine_name = false
71
60
  end
72
- three_words count(number)
61
+ three_words count(number), false
62
+ end
63
+
64
+ def count_name_with_order_name(number)
65
+ count_name(number) + ' ' + Declinations.name_with_declination(names[:ten_powers][number_order(number)], count(number))
73
66
  end
74
67
  end
75
68
  end
@@ -1,3 +1,3 @@
1
1
  module Kabal
2
- VERSION = "0.3.5"
2
+ VERSION = '1.0.0'
3
3
  end
@@ -5,10 +5,11 @@ include Kabal
5
5
  class KabalTest < TestCase
6
6
  def test_language_init
7
7
  Kabal.language = "Russian"
8
- assert_equal Kabal.current_language, "Russian"
8
+ assert_equal "Russian", Kabal.current_language
9
9
  end
10
10
 
11
11
  def test_to_text
12
+ Kabal.language = "Russian"
12
13
  assert_equal "сто двадцать пять миллиардов сто двадцать пять миллионов сто двадцать пять тысяч сто двадцать пять", Kabal.to_text(125125125125)
13
14
  assert_equal "сто двадцать пять миллиардов сто двадцать пять миллионов сто двадцать пять тысяч сто двадцать пять", Kabal.to_text("125125125125")
14
15
  end
@@ -57,15 +58,15 @@ class KabalTest < TestCase
57
58
  end
58
59
 
59
60
  def test_maximum_for_language
60
- assert_equal Kabal.maximum_for("Russian"), 10 ** 102
61
- assert_equal Kabal.maximum_for("English"), (10 ** 66) - 1
62
- assert_equal Kabal.maximum_for("Deutsch"), (10 ** 24) - 1
61
+ assert_equal 10 ** 102, Kabal.maximum_for("Russian")
62
+ assert_equal (10 ** 66) - 1, Kabal.maximum_for("English")
63
+ assert_equal (10 ** 24) - 1, Kabal.maximum_for("Deutsch")
63
64
  end
64
65
 
65
66
  def test_minimum_for_language
66
- assert_equal Kabal.minimum_for("Russian"), -(10 ** 102)
67
- assert_equal Kabal.minimum_for("English"), -(10 ** 66) + 1
68
- assert_equal Kabal.minimum_for("Deutsch"), -(10 ** 24) + 1
67
+ assert_equal -(10 ** 102), Kabal.minimum_for("Russian")
68
+ assert_equal -(10 ** 66) + 1, Kabal.minimum_for("English")
69
+ assert_equal -(10 ** 24) + 1, Kabal.minimum_for("Deutsch")
69
70
  end
70
71
 
71
72
  def test_minimum_and_maximum_convert_for_language
@@ -88,9 +89,11 @@ class KabalTest < TestCase
88
89
  end
89
90
 
90
91
  def test_bad_number_test
91
- assert_equal Kabal.to_text("110000000000000001011"), "сто десять квинтиллионов одна тысяча одиннадцать"
92
- assert_equal Kabal.to_text("11000000000000011"), "одиннадцать квадраллионов одиннадцать"
93
- assert_equal Kabal.to_text("112223334445556661011"), "сто двенадцать квинтиллиона двести двадцать три квадраллиона триста тридцать четыре триллиона четыреста сорок пять миллиардов пятьсот пятьдесят шесть миллионов шестьсот шестьдесят одна тысяча одиннадцать"
94
- assert_equal Kabal.to_text("909090909.1234"), "девятьсот девять миллионов девяносто тысяч девятьсот девять целых девятьсот девять миллионов девяносто тысяч девятьсот девять одна тысяча двести тридцать четыре десятитысячных"
92
+ Kabal.language = "Russian"
93
+ assert_equal "сто десять квинтиллионов одна тысяча одиннадцать", Kabal.to_text("110000000000000001011")
94
+ assert_equal "одиннадцать квадраллионов одиннадцать", Kabal.to_text("11000000000000011")
95
+ assert_equal "сто двенадцать квинтиллиона двести двадцать три квадраллиона триста тридцать четыре триллиона четыреста сорок пять миллиардов пятьсот пятьдесят шесть миллионов шестьсот шестьдесят одна тысяча одиннадцать", Kabal.to_text("112223334445556661011")
96
+ assert_equal "девятьсот девять миллионов девяносто тысяч девятьсот девять целых одна тысяча двести тридцать четыре десятитысячных", Kabal.to_text("909090909.1234")
97
+ assert_equal "девятьсот девять миллионов девяносто тысяч девятьсот девять целых одна тысяча двести тридцать четыре десятитысячных", Kabal.to_text(909090909.1234)
95
98
  end
96
99
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kabal
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.5
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pavel Kalashnikov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-02 00:00:00.000000000 Z
11
+ date: 2014-08-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -39,7 +39,7 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  description: 'Kabal allows you to translate numbers into text on languages: English,
42
- Russian, Deutsch'
42
+ Russian, Deutsch. See demo on http://kabal.herokuapp.com'
43
43
  email:
44
44
  - kalashnikovisme@gmail.com
45
45
  executables: []
@@ -70,6 +70,8 @@ files:
70
70
  - lib/kabal/languages/english.rb
71
71
  - lib/kabal/languages/english/fractional_numbers.rb
72
72
  - lib/kabal/languages/english/natural_numbers.rb
73
+ - lib/kabal/languages/global/fractional_numbers.rb
74
+ - lib/kabal/languages/global/natural_numbers.rb
73
75
  - lib/kabal/languages/language.rb
74
76
  - lib/kabal/languages/russian.rb
75
77
  - lib/kabal/languages/russian/declinations.rb