to_decimal 1.0.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +20 -0
- data/README.md +54 -44
- data/lib/to_decimal/base_class.rb +73 -0
- data/lib/to_decimal.rb +1 -26
- data/test/to_decimal_test.rb +43 -202
- metadata +35 -51
- data/Gemfile +0 -15
- data/Gemfile.lock +0 -53
- data/Rakefile +0 -25
- data/lib/to_decimal/convertor_class.rb +0 -40
- data/lib/to_decimal/validator_class.rb +0 -38
- data/lib/to_decimal/wrong_base_input_error.rb +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 3b6653d23069ad770aaea5c3c964526f4af9d834d55b011ffdb0b3ea78077340
|
4
|
+
data.tar.gz: e0c1d4c94a2db2d31b1a46cc32a5b26842832aab4aa992a53a594d557fc55ca9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 67c5be620307348487f0e492a41ba7b81427fa4b5b880a8cd3b14859d4f9cc3432ec4fcdfb1b84d84d431e73c923ad3cf2eb6d68df32da3f5d88339483da6130
|
7
|
+
data.tar.gz: 1e80bec78c78e43922f6a7372f796d76135fc8515be84ac6b85d73a8974eb5db81f7bb6db32ba57fb6bdfc540001cda78b476b62d579be4b27001a6f7adcef59
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,23 @@
|
|
1
|
+
# to_decimal 2.0.0 (2022-10-02)
|
2
|
+
---
|
3
|
+
New Features :
|
4
|
+
- Allow instantiation of new base objects
|
5
|
+
- Allow usage of bases up to 36
|
6
|
+
|
7
|
+
Breaking Changes :
|
8
|
+
|
9
|
+
- `WrongBaseInputError` is renamed `WrongInputBaseError`
|
10
|
+
- The `Base2`, `Base3`, ... `Base10` constants are no longer provided, you need to instantiate Base object yourself
|
11
|
+
|
12
|
+
Other :
|
13
|
+
- Change Convertor class name to Base
|
14
|
+
- Update development dependecies and use Standard instead of Rubocop for linting
|
15
|
+
|
16
|
+
# to_decimal 1.0.2 (2019-12-20)
|
17
|
+
---
|
18
|
+
- fix a bug by removing the require statements at the top of `lib/to_decimal.rb`
|
19
|
+
- slight improvements to readme
|
20
|
+
|
1
21
|
# to_decimal 1.0.1 (2019-03-16)
|
2
22
|
---
|
3
23
|
|
data/README.md
CHANGED
@@ -1,16 +1,15 @@
|
|
1
|
-
# to_decimal
|
1
|
+
# to_decimal (Version 2.0.0)
|
2
2
|
|
3
|
-
A simple gem to convert an integer expressed in bases
|
4
|
-
ranging from 2 to
|
3
|
+
A simple gem to convert an integer or string representation of an integer expressed in bases
|
4
|
+
ranging from 2 to 36 into a decimal integer.
|
5
5
|
|
6
|
-
Ruby comes with
|
6
|
+
Ruby comes with built-in methods to convert integers and string
|
7
7
|
representations of integers to another base ([`String#to_i(base=10)`](http://ruby-doc.org/core-2.5.3/String.html#method-i-to_i),
|
8
8
|
[`Kernel#Integer(arg, base=0)`](https://ruby-doc.com/core-2.5.2/Kernel.html#method-i-Integer) and
|
9
9
|
[`Integer#to_s(base=10)`](http://ruby-doc.org/core-2.5.3/Integer.html#method-i-to_s).
|
10
10
|
|
11
11
|
You can also use prefixes with [litteral numeric constant](https://ruby-doc.com/core-2.5.2/doc/syntax/literals_rdoc.html#label-Numbers),
|
12
|
-
|
13
|
-
the most usecases):
|
12
|
+
for binary, octal, decimal and hexadecimal notation :
|
14
13
|
|
15
14
|
```ruby
|
16
15
|
# binary
|
@@ -26,35 +25,54 @@ the most usecases):
|
|
26
25
|
0x17 # => 23
|
27
26
|
```
|
28
27
|
|
29
|
-
|
30
|
-
you need to proceed like this (AFAIK):
|
28
|
+
For other bases ranging from 2 to 36, you can proceed like this :
|
31
29
|
|
32
30
|
```ruby
|
33
31
|
12.to_s.to_i(6) # => 8
|
32
|
+
# OR
|
33
|
+
Integer("12", 6) # => 8)
|
34
34
|
```
|
35
35
|
|
36
|
-
|
37
|
-
manage using prefixes, but I thought there could be a more straightforward,
|
38
|
-
consise and explicit way to perform this, showing more clearly what your intent
|
39
|
-
is.
|
36
|
+
The `Kernel#Integer` method raises useful error messages when using invalid arguments.
|
40
37
|
|
41
|
-
|
42
|
-
|
38
|
+
```
|
39
|
+
Integer "17", 6 # => `Integer': invalid value for Integer(): "17" (ArgumentError)
|
40
|
+
|
41
|
+
Integer "17, 37 # => `Integer': invalid radix 37 (ArgumentError)
|
42
|
+
```
|
43
|
+
|
44
|
+
The `String#to_i` method on the other hand also raises an ArgumentError when trying to use an invalid radix, _but_ if the string value does not represent a valid integer, or an integer that doesn't match the provided base, the method silently stop the conversion process when it encounters an invalid character, and returns the result of the conversion so far :
|
45
|
+
|
46
|
+
```
|
47
|
+
"17".to_i(37) # => invalid radix 37 (ArgumentError)
|
48
|
+
"17".to_i(6) # => 1
|
49
|
+
"12378".to_i(6) # => 51
|
50
|
+
```
|
43
51
|
|
44
|
-
|
52
|
+
This gem is simply a wrapper around the `String#to_i` and `Kernel#Integer` methods, with some argument validations and useful error messages.
|
53
|
+
|
54
|
+
If you need more features, checkout these twp gems :
|
45
55
|
- [bases](https://github.com/whatyouhide/bases) ;
|
46
56
|
- [radix](https://github.com/rubyworks/radix) ;
|
47
57
|
|
48
58
|
They are very comprehensive, go both behind the base 36, which is the limit
|
49
59
|
of Ruby, and allow to convert form bases back and forth.
|
50
60
|
|
51
|
-
But they were a little too heavy for my purpose, which was simply
|
52
|
-
converting from a base lesser or equal than 10 and to return an integer
|
53
|
-
expressed in base 10. So I decided to write my own gem.
|
54
61
|
|
55
62
|
# Installation
|
56
63
|
```shell
|
57
64
|
$ gem install to_decimal
|
65
|
+
```
|
66
|
+
|
67
|
+
Or add this line to your Gemfile
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
gem 'to_decimal'
|
71
|
+
```
|
72
|
+
|
73
|
+
and run
|
74
|
+
|
75
|
+
```shell
|
58
76
|
$ bundle install
|
59
77
|
```
|
60
78
|
|
@@ -66,42 +84,35 @@ This project is tested under minitest.
|
|
66
84
|
|
67
85
|
# Usage
|
68
86
|
|
69
|
-
|
70
|
-
|
87
|
+
You can create a `ToDecimal::Base` object with the required base as an integer argument :
|
88
|
+
|
89
|
+
```ruby
|
90
|
+
b8 = ToDecimal::Base.new(8)
|
91
|
+
```
|
71
92
|
|
72
|
-
Each object
|
73
|
-
representation of the corresponding base and returns this integer expressed
|
93
|
+
Each object is frozen after initialisation and exposes a `[]` method, which takes as argument an integer OR a string
|
94
|
+
representation of an integer of the corresponding base and returns this integer expressed
|
74
95
|
in base 10 :
|
75
96
|
|
76
97
|
```ruby
|
77
|
-
base2 = ToDecimal::
|
98
|
+
base2 = ToDecimal::Base.new(2)
|
78
99
|
base2[10] # => 2
|
100
|
+
base2["10"] # => 2
|
101
|
+
base2["010"] # => 2
|
79
102
|
|
80
|
-
b8 = ToDecimal::
|
103
|
+
b8 = ToDecimal::Base.new(8)
|
81
104
|
b8[12] # => 10
|
82
|
-
|
83
105
|
b8['12'] # => 10
|
84
106
|
b8['012'] # => 10
|
85
|
-
```
|
86
|
-
|
87
|
-
These objects and their associated `[]` method are basically wrappers for the
|
88
|
-
`Integer.to_s.to_i(original_base)` or `String.to_i(original_base)` methods,
|
89
|
-
with a custom error when the input is not of the excpected base, or not a valid
|
90
|
-
string representation of an integer. In this case, you will get
|
91
|
-
a `WrongBaseInputError` instead of the default results of the previous methods, which can lead to unexpected results if drown into some other computations.
|
92
107
|
|
93
|
-
|
108
|
+
b8["99"]
|
109
|
+
# => raises : A number of base 8 cannot have a digit greater or equal to '7'. Check your argument: '99'. (ToDecimal::WrongInputBaseError)
|
94
110
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
methods, which sometimes throw an error (`Kernel#Integer(arg, base)`) or worse,
|
99
|
-
silently stop the conversion process when they encounter an invalid character, returning the result of the conversion so far. Instead, you have a consistent
|
100
|
-
behavior, and you are free to decide what to do with the error.
|
101
|
-
|
102
|
-
- **allow you to work with strings with leading zeros** : in this case, zeros are removed form the beginning of the string, avoiding the implict conversion in
|
103
|
-
base 8, which is, most of the time, not what you want ;
|
111
|
+
b36 = ToDecimal::Base.new(36)
|
112
|
+
b36[12] # => 38
|
113
|
+
b36["ruby"] # => 1299022
|
104
114
|
|
115
|
+
```
|
105
116
|
|
106
117
|
# Contribute
|
107
118
|
|
@@ -122,5 +133,4 @@ Laurent Guinotte
|
|
122
133
|
|
123
134
|
# Licence
|
124
135
|
|
125
|
-
|
126
|
-
for further details.
|
136
|
+
MIT
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module ToDecimal
|
2
|
+
class WrongInputBaseError < ArgumentError; end
|
3
|
+
|
4
|
+
NUMBERS = %w[0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v w x y z].freeze
|
5
|
+
|
6
|
+
class Base
|
7
|
+
attr_reader :base
|
8
|
+
|
9
|
+
def initialize(base)
|
10
|
+
validate_base(base)
|
11
|
+
@base = base
|
12
|
+
freeze
|
13
|
+
end
|
14
|
+
|
15
|
+
def [](input)
|
16
|
+
validate_input(input)
|
17
|
+
|
18
|
+
convert(input)
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def convert(input)
|
24
|
+
if input.is_a?(Integer)
|
25
|
+
input.to_s.to_i(base)
|
26
|
+
else
|
27
|
+
Integer(input, base)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def validate_base(base)
|
32
|
+
raise ArgumentError, "Base must be an Integer" unless base.is_a?(Integer)
|
33
|
+
raise ArgumentError, "Base must be 2..36" unless \
|
34
|
+
(2..36) === base
|
35
|
+
end
|
36
|
+
|
37
|
+
def validate_input(input)
|
38
|
+
err_value = "Argument must be an integer or a valid string\
|
39
|
+
representation of an integer. You input : #{input}, of class #{input.class}."
|
40
|
+
raise ArgumentError, err_value unless valid_integer_string_or_integer?(input)
|
41
|
+
|
42
|
+
err_base = "A number of base #{base} cannot have a\
|
43
|
+
digit greater than '#{NUMBERS[base - 1]}'. Check your argument: '#{input}'."
|
44
|
+
raise WrongInputBaseError, err_base unless valid_input_base?(input)
|
45
|
+
end
|
46
|
+
|
47
|
+
def valid_integer_string_or_integer?(input)
|
48
|
+
valid_integer?(input) || valid_integer_string?(input)
|
49
|
+
end
|
50
|
+
|
51
|
+
def valid_integer?(input)
|
52
|
+
input.is_a?(Integer)
|
53
|
+
end
|
54
|
+
|
55
|
+
def valid_integer_string?(input)
|
56
|
+
return false unless input.is_a?(String)
|
57
|
+
input = remove_leading_zeros(input)
|
58
|
+
|
59
|
+
return false unless input.match?(/\A[a-z0-9]+\z/i)
|
60
|
+
true
|
61
|
+
end
|
62
|
+
|
63
|
+
def valid_input_base?(input)
|
64
|
+
input = input.to_s
|
65
|
+
digitized_input = input.chars.map(&:downcase)
|
66
|
+
digitized_input.none? { |digit| NUMBERS.index(digit) > base - 1 }
|
67
|
+
end
|
68
|
+
|
69
|
+
def remove_leading_zeros(input)
|
70
|
+
input.sub(/\A0+/, "")
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/lib/to_decimal.rb
CHANGED
@@ -1,26 +1 @@
|
|
1
|
-
|
2
|
-
require 'bundler/setup'
|
3
|
-
Bundler.require(:default, :development)
|
4
|
-
|
5
|
-
require_relative 'to_decimal/validator_class'
|
6
|
-
require_relative 'to_decimal/convertor_class'
|
7
|
-
require_relative 'to_decimal/wrong_base_input_error'
|
8
|
-
|
9
|
-
module ToDecimal
|
10
|
-
Base2 = Convertor.new(2)
|
11
|
-
Base3 = Convertor.new(3)
|
12
|
-
Base4 = Convertor.new(4)
|
13
|
-
Base5 = Convertor.new(5)
|
14
|
-
Base6 = Convertor.new(6)
|
15
|
-
Base7 = Convertor.new(7)
|
16
|
-
Base8 = Convertor.new(8)
|
17
|
-
Base9 = Convertor.new(9)
|
18
|
-
Base10 = Convertor.new(10)
|
19
|
-
|
20
|
-
# Ensure no other convertor object will be created
|
21
|
-
class Convertor
|
22
|
-
class << self
|
23
|
-
private :new
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
1
|
+
require_relative "to_decimal/base_class"
|
data/test/to_decimal_test.rb
CHANGED
@@ -1,221 +1,62 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "minitest/autorun"
|
2
|
+
require "minitest/reporters"
|
3
3
|
Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
|
4
4
|
|
5
|
-
require_relative
|
5
|
+
require_relative "../lib/to_decimal"
|
6
6
|
|
7
|
-
class
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
base2 = ToDecimal::Base2
|
13
|
-
assert_raises(ToDecimal::WrongBaseInputError) { base2[2] }
|
14
|
-
assert_raises(ToDecimal::WrongBaseInputError) { base2[9] }
|
15
|
-
end
|
16
|
-
|
17
|
-
def test_raises_error_if_input_is_not_from_base_3
|
18
|
-
base3 = ToDecimal::Base3
|
19
|
-
assert_raises(ToDecimal::WrongBaseInputError) { base3[3] }
|
20
|
-
assert_raises(ToDecimal::WrongBaseInputError) { base3[9] }
|
21
|
-
end
|
22
|
-
|
23
|
-
def test_raises_error_if_input_is_not_from_base_4
|
24
|
-
base4 = ToDecimal::Base4
|
25
|
-
assert_raises(ToDecimal::WrongBaseInputError) { base4[4] }
|
26
|
-
assert_raises(ToDecimal::WrongBaseInputError) { base4[9] }
|
27
|
-
end
|
28
|
-
|
29
|
-
def test_raises_error_if_input_is_not_from_base_5
|
30
|
-
base5 = ToDecimal::Base5
|
31
|
-
assert_raises(ToDecimal::WrongBaseInputError) { base5[5] }
|
32
|
-
assert_raises(ToDecimal::WrongBaseInputError) { base5[9] }
|
33
|
-
end
|
34
|
-
|
35
|
-
def test_raises_error_if_input_is_not_from_base_6
|
36
|
-
base6 = ToDecimal::Base6
|
37
|
-
assert_raises(ToDecimal::WrongBaseInputError) { base6[6] }
|
38
|
-
assert_raises(ToDecimal::WrongBaseInputError) { base6[9] }
|
39
|
-
end
|
40
|
-
|
41
|
-
def test_raises_error_if_input_is_not_from_base_7
|
42
|
-
base7 = ToDecimal::Base7
|
43
|
-
assert_raises(ToDecimal::WrongBaseInputError) { base7[7] }
|
44
|
-
assert_raises(ToDecimal::WrongBaseInputError) { base7[9] }
|
45
|
-
end
|
46
|
-
|
47
|
-
def test_raises_error_if_input_is_not_from_base_8
|
48
|
-
base8 = ToDecimal::Base8
|
49
|
-
assert_raises(ToDecimal::WrongBaseInputError) { base8[8] }
|
50
|
-
assert_raises(ToDecimal::WrongBaseInputError) { base8[9] }
|
51
|
-
end
|
52
|
-
|
53
|
-
def test_raises_error_if_input_is_not_from_base_9
|
54
|
-
base9 = ToDecimal::Base9
|
55
|
-
assert_raises(ToDecimal::WrongBaseInputError) { base9[9] }
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
# ========= Testing return values of [] method =================================
|
60
|
-
|
61
|
-
# ========= Test helper method
|
62
|
-
|
63
|
-
def execute_test_with(test_values, base_convertor)
|
64
|
-
test_values.each do |data_set|
|
65
|
-
assert_equal data_set[1], base_convertor[data_set[0]]
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
# ========= Test class
|
70
|
-
|
71
|
-
class ToDecimalConvserionFromIntegerTest < Minitest::Test
|
72
|
-
|
73
|
-
# Test data
|
74
|
-
TEST_VALUES_BASE_2 = [[101, 5], [100_000_000, 256]].freeze
|
75
|
-
TEST_VALUES_BASE_3 = [[1_122_111, 1201], [12, 5]].freeze
|
76
|
-
TEST_VALUES_BASE_4 = [[11_001, 321], [322, 58]].freeze
|
77
|
-
TEST_VALUES_BASE_5 = [[14, 9], [10_011_302, 78_952]].freeze
|
78
|
-
TEST_VALUES_BASE_6 = [[13, 9], [1_405_304, 78_952]].freeze
|
79
|
-
TEST_VALUES_BASE_7 = [[12, 9], [446_116, 78_952]].freeze
|
80
|
-
TEST_VALUES_BASE_8 = [[11, 9], [232_150, 78_952]].freeze
|
81
|
-
TEST_VALUES_BASE_9 = [[10, 9], [130_264, 78_952]].freeze
|
82
|
-
TEST_VALUES_BASE_10 = [[9, 9], [78_952, 78_952]].freeze
|
83
|
-
|
84
|
-
def test_returns_decimal_value_of_integer_of_base_2
|
85
|
-
execute_test_with(TEST_VALUES_BASE_2, ToDecimal::Base2)
|
86
|
-
end
|
87
|
-
|
88
|
-
def test_returns_decimal_value_of_integer_of_base_3
|
89
|
-
execute_test_with(TEST_VALUES_BASE_3, ToDecimal::Base3)
|
90
|
-
end
|
91
|
-
|
92
|
-
def test_returns_decimal_value_of_integer_of_base_4
|
93
|
-
execute_test_with(TEST_VALUES_BASE_4, ToDecimal::Base4)
|
94
|
-
end
|
95
|
-
|
96
|
-
def test_returns_decimal_value_of_integer_of_base_5
|
97
|
-
execute_test_with(TEST_VALUES_BASE_5, ToDecimal::Base5)
|
98
|
-
end
|
99
|
-
|
100
|
-
def test_returns_decimal_value_of_integer_of_base_6
|
101
|
-
execute_test_with(TEST_VALUES_BASE_6, ToDecimal::Base6)
|
102
|
-
end
|
103
|
-
|
104
|
-
def test_returns_decimal_value_of_integer_of_base_7
|
105
|
-
execute_test_with(TEST_VALUES_BASE_7, ToDecimal::Base7)
|
106
|
-
end
|
107
|
-
|
108
|
-
def test_returns_decimal_value_of_integer_of_base_8
|
109
|
-
execute_test_with(TEST_VALUES_BASE_8, ToDecimal::Base8)
|
110
|
-
end
|
111
|
-
|
112
|
-
def test_returns_decimal_value_of_integer_of_base_9
|
113
|
-
execute_test_with(TEST_VALUES_BASE_9, ToDecimal::Base9)
|
114
|
-
end
|
115
|
-
|
116
|
-
def test_returns_decimal_value_of_integer_of_base_10
|
117
|
-
execute_test_with(TEST_VALUES_BASE_10, ToDecimal::Base10)
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
class ToDecimalConvserionFromStringTest < Minitest::Test
|
122
|
-
TEST_VALUES_BASE_2 = [['101', 5], ['100000000', 256]].freeze
|
123
|
-
TEST_VALUES_BASE_3 = [['1122111', 1_201], ['12', 5]].freeze
|
124
|
-
TEST_VALUES_BASE_4 = [['11001', 321], ['322', 58]].freeze
|
125
|
-
TEST_VALUES_BASE_5 = [['14', 9], ['10011302', 78_952]].freeze
|
126
|
-
TEST_VALUES_BASE_6 = [['13', 9], ['1405304', 78_952]].freeze
|
127
|
-
TEST_VALUES_BASE_7 = [['12', 9], ['446116', 78_952]].freeze
|
128
|
-
TEST_VALUES_BASE_8 = [['11', 9], ['232150', 78_952]].freeze
|
129
|
-
TEST_VALUES_BASE_9 = [['10', 9], ['130264', 78_952]].freeze
|
130
|
-
TEST_VALUES_BASE_10 = [['9', 9], ['78952', 78_952]].freeze
|
131
|
-
|
132
|
-
def test_returns_decimal_value_of_string_of_base_2
|
133
|
-
execute_test_with(TEST_VALUES_BASE_2, ToDecimal::Base2)
|
134
|
-
end
|
135
|
-
|
136
|
-
def test_returns_decimal_value_of_string_of_base_3
|
137
|
-
execute_test_with(TEST_VALUES_BASE_3, ToDecimal::Base3)
|
138
|
-
end
|
139
|
-
|
140
|
-
def test_returns_decimal_value_of_string_of_base_4
|
141
|
-
execute_test_with(TEST_VALUES_BASE_4, ToDecimal::Base4)
|
142
|
-
end
|
143
|
-
|
144
|
-
def test_returns_decimal_value_of_string_of_base_5
|
145
|
-
execute_test_with(TEST_VALUES_BASE_5, ToDecimal::Base5)
|
146
|
-
end
|
147
|
-
|
148
|
-
def test_returns_decimal_value_of_string_of_base_6
|
149
|
-
execute_test_with(TEST_VALUES_BASE_6, ToDecimal::Base6)
|
150
|
-
end
|
151
|
-
|
152
|
-
def test_returns_decimal_value_of_string_of_base_7
|
153
|
-
execute_test_with(TEST_VALUES_BASE_7, ToDecimal::Base7)
|
154
|
-
end
|
155
|
-
|
156
|
-
def test_returns_decimal_value_of_string_of_base_8
|
157
|
-
execute_test_with(TEST_VALUES_BASE_8, ToDecimal::Base8)
|
158
|
-
end
|
159
|
-
|
160
|
-
def test_returns_decimal_value_of_string_of_base_9
|
161
|
-
execute_test_with(TEST_VALUES_BASE_9, ToDecimal::Base9)
|
162
|
-
end
|
163
|
-
|
164
|
-
def test_returns_decimal_value_of_string_of_base_10
|
165
|
-
execute_test_with(TEST_VALUES_BASE_10, ToDecimal::Base10)
|
7
|
+
class ToDecimalTest < Minitest::Test
|
8
|
+
def test_base_object_can_be_initialized_with_correct_argument
|
9
|
+
(2..36).to_a.each do |valid_base|
|
10
|
+
assert_silent { ToDecimal::Base.new(valid_base) }
|
11
|
+
end
|
166
12
|
end
|
167
|
-
end
|
168
|
-
|
169
|
-
class RemoveLeadingZeroesFromStringsTest < Minitest::Test
|
170
|
-
TEST_VALUES_BASE_2 = [['00101', 5], ['0100000000', 256]].freeze
|
171
|
-
TEST_VALUES_BASE_3 = [['001122111', 1_201], ['012', 5]].freeze
|
172
|
-
TEST_VALUES_BASE_4 = [['0011001', 321], ['322', 58]].freeze
|
173
|
-
TEST_VALUES_BASE_5 = [['0014', 9], ['010011302', 78_952]].freeze
|
174
|
-
TEST_VALUES_BASE_6 = [['0013', 9], ['01405304', 78_952]].freeze
|
175
|
-
TEST_VALUES_BASE_7 = [['0012', 9], ['0446116', 78_952]].freeze
|
176
|
-
TEST_VALUES_BASE_8 = [['0011', 9], ['0232150', 78_952]].freeze
|
177
|
-
TEST_VALUES_BASE_9 = [['0010', 9], ['0130264', 78_952]].freeze
|
178
|
-
TEST_VALUES_BASE_10 = [['009', 9], ['078952', 78_952]].freeze
|
179
13
|
|
180
|
-
def
|
181
|
-
|
14
|
+
def test_base_object_initialisation_raises_if_incorrect_argument
|
15
|
+
[1, 37, "10", "a", :a].each do |invalid_base|
|
16
|
+
assert_raises(ArgumentError) { ToDecimal::Base.new(invalid_base) }
|
17
|
+
end
|
182
18
|
end
|
183
19
|
|
184
|
-
def
|
185
|
-
|
186
|
-
|
20
|
+
def test_raises_wrong_input_base_error_if_input_is_not_of_the_correct_base
|
21
|
+
base2 = ToDecimal::Base.new(2)
|
22
|
+
assert_raises(ToDecimal::WrongInputBaseError) { base2[2] }
|
23
|
+
assert_raises(ToDecimal::WrongInputBaseError) { base2["2"] }
|
24
|
+
assert_raises(ToDecimal::WrongInputBaseError) { base2["02"] }
|
187
25
|
|
188
|
-
|
189
|
-
|
190
|
-
|
26
|
+
base10 = ToDecimal::Base.new(10)
|
27
|
+
assert_raises(ToDecimal::WrongInputBaseError) { base10["a"] }
|
28
|
+
assert_raises(ToDecimal::WrongInputBaseError) { base10["0a"] }
|
29
|
+
assert_raises(ToDecimal::WrongInputBaseError) { base10["A"] }
|
191
30
|
|
192
|
-
|
193
|
-
|
31
|
+
base35 = ToDecimal::Base.new(35)
|
32
|
+
assert_raises(ToDecimal::WrongInputBaseError) { base35["z"] }
|
33
|
+
assert_raises(ToDecimal::WrongInputBaseError) { base35["0z"] }
|
194
34
|
end
|
195
35
|
|
196
|
-
def
|
197
|
-
|
198
|
-
|
36
|
+
def test_returns_correct_value_as_integer
|
37
|
+
base2 = ToDecimal::Base.new(2)
|
38
|
+
assert_equal 2, base2[10]
|
39
|
+
assert_equal 2, base2["10"]
|
40
|
+
assert_equal 2, base2["010"]
|
199
41
|
|
200
|
-
|
201
|
-
|
42
|
+
base36 = ToDecimal::Base.new(36)
|
43
|
+
assert_equal 1, base36[1]
|
44
|
+
assert_equal 146, base36["42"]
|
202
45
|
end
|
203
46
|
|
204
|
-
def
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
def test_removes_leading_zeros_from_string_with_base9
|
209
|
-
execute_test_with(TEST_VALUES_BASE_9, ToDecimal::Base9)
|
210
|
-
end
|
47
|
+
def test_is_case_insensitive
|
48
|
+
base16 = ToDecimal::Base.new(16)
|
49
|
+
assert_equal 15, base16["f"]
|
50
|
+
assert_equal 15, base16["F"]
|
211
51
|
|
212
|
-
|
213
|
-
|
52
|
+
assert_equal 255, base16["ff"]
|
53
|
+
assert_equal 255, base16["FF"]
|
214
54
|
end
|
215
|
-
end
|
216
55
|
|
217
|
-
|
218
|
-
|
219
|
-
|
56
|
+
def test_handles_leading_zeros_in_strings
|
57
|
+
base8 = ToDecimal::Base.new(8)
|
58
|
+
assert_equal 34, base8["42"]
|
59
|
+
assert_equal 34, base8["042"]
|
60
|
+
assert_equal 34, base8["0000042"]
|
220
61
|
end
|
221
62
|
end
|
metadata
CHANGED
@@ -1,123 +1,108 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: to_decimal
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Laurent Guinotte
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-10-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: rake
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '13.0'
|
20
20
|
- - ">="
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version:
|
22
|
+
version: 13.0.6
|
23
23
|
type: :development
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - "~>"
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: '
|
29
|
+
version: '13.0'
|
30
30
|
- - ">="
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version:
|
33
|
-
- !ruby/object:Gem::Dependency
|
34
|
-
name: rake
|
35
|
-
requirement: !ruby/object:Gem::Requirement
|
36
|
-
requirements:
|
37
|
-
- - "~>"
|
38
|
-
- !ruby/object:Gem::Version
|
39
|
-
version: '12.3'
|
40
|
-
type: :development
|
41
|
-
prerelease: false
|
42
|
-
version_requirements: !ruby/object:Gem::Requirement
|
43
|
-
requirements:
|
44
|
-
- - "~>"
|
45
|
-
- !ruby/object:Gem::Version
|
46
|
-
version: '12.3'
|
32
|
+
version: 13.0.6
|
47
33
|
- !ruby/object:Gem::Dependency
|
48
34
|
name: minitest
|
49
35
|
requirement: !ruby/object:Gem::Requirement
|
50
36
|
requirements:
|
51
37
|
- - "~>"
|
52
38
|
- !ruby/object:Gem::Version
|
53
|
-
version: '5.
|
39
|
+
version: '5.16'
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 5.16.3
|
54
43
|
type: :development
|
55
44
|
prerelease: false
|
56
45
|
version_requirements: !ruby/object:Gem::Requirement
|
57
46
|
requirements:
|
58
47
|
- - "~>"
|
59
48
|
- !ruby/object:Gem::Version
|
60
|
-
version: '5.
|
49
|
+
version: '5.16'
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 5.16.3
|
61
53
|
- !ruby/object:Gem::Dependency
|
62
54
|
name: minitest-reporters
|
63
55
|
requirement: !ruby/object:Gem::Requirement
|
64
56
|
requirements:
|
65
57
|
- - "~>"
|
66
58
|
- !ruby/object:Gem::Version
|
67
|
-
version: '1.
|
68
|
-
|
69
|
-
prerelease: false
|
70
|
-
version_requirements: !ruby/object:Gem::Requirement
|
71
|
-
requirements:
|
72
|
-
- - "~>"
|
73
|
-
- !ruby/object:Gem::Version
|
74
|
-
version: '1.1'
|
75
|
-
- !ruby/object:Gem::Dependency
|
76
|
-
name: pry
|
77
|
-
requirement: !ruby/object:Gem::Requirement
|
78
|
-
requirements:
|
79
|
-
- - "~>"
|
59
|
+
version: '1.5'
|
60
|
+
- - ">="
|
80
61
|
- !ruby/object:Gem::Version
|
81
|
-
version:
|
62
|
+
version: 1.5.0
|
82
63
|
type: :development
|
83
64
|
prerelease: false
|
84
65
|
version_requirements: !ruby/object:Gem::Requirement
|
85
66
|
requirements:
|
86
67
|
- - "~>"
|
87
68
|
- !ruby/object:Gem::Version
|
88
|
-
version:
|
69
|
+
version: '1.5'
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: 1.5.0
|
89
73
|
- !ruby/object:Gem::Dependency
|
90
|
-
name:
|
74
|
+
name: standard
|
91
75
|
requirement: !ruby/object:Gem::Requirement
|
92
76
|
requirements:
|
93
77
|
- - "~>"
|
94
78
|
- !ruby/object:Gem::Version
|
95
|
-
version:
|
79
|
+
version: '1.16'
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 1.16.1
|
96
83
|
type: :development
|
97
84
|
prerelease: false
|
98
85
|
version_requirements: !ruby/object:Gem::Requirement
|
99
86
|
requirements:
|
100
87
|
- - "~>"
|
101
88
|
- !ruby/object:Gem::Version
|
102
|
-
version:
|
89
|
+
version: '1.16'
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: 1.16.1
|
103
93
|
description: |
|
104
94
|
Provides a simple way to convert an integer expressed in bases
|
105
|
-
2 up to
|
95
|
+
2 up to 36 to a decimal integer
|
106
96
|
email: laurentguinotte@icloud.com
|
107
97
|
executables: []
|
108
98
|
extensions: []
|
109
99
|
extra_rdoc_files: []
|
110
100
|
files:
|
111
101
|
- CHANGELOG.md
|
112
|
-
- Gemfile
|
113
|
-
- Gemfile.lock
|
114
102
|
- LICENCE.txt
|
115
103
|
- README.md
|
116
|
-
- Rakefile
|
117
104
|
- lib/to_decimal.rb
|
118
|
-
- lib/to_decimal/
|
119
|
-
- lib/to_decimal/validator_class.rb
|
120
|
-
- lib/to_decimal/wrong_base_input_error.rb
|
105
|
+
- lib/to_decimal/base_class.rb
|
121
106
|
- test/to_decimal_test.rb
|
122
107
|
homepage: https://github.com/loranger32/to_decimal
|
123
108
|
licenses:
|
@@ -140,9 +125,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
140
125
|
- !ruby/object:Gem::Version
|
141
126
|
version: '0'
|
142
127
|
requirements: []
|
143
|
-
|
144
|
-
rubygems_version: 2.6.14.3
|
128
|
+
rubygems_version: 3.3.7
|
145
129
|
signing_key:
|
146
130
|
specification_version: 4
|
147
|
-
summary: A small gem to convert integers from bases 2..
|
131
|
+
summary: A small gem to convert integers from bases 2..36 to decimal integers
|
148
132
|
test_files: []
|
data/Gemfile
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
source 'https://rubygems.org'
|
2
|
-
|
3
|
-
ruby '~> 2.4.5'
|
4
|
-
|
5
|
-
source 'https://rubygems.org'
|
6
|
-
|
7
|
-
gem 'bundler', '~> 2.0', '>= 2.0.1'
|
8
|
-
gem 'rake', '~> 12.3', '>= 12.3.2'
|
9
|
-
|
10
|
-
group :development do
|
11
|
-
gem 'minitest', '~> 5.11', '>= 5.11.3'
|
12
|
-
gem 'minitest-reporters', '~> 1.3', '>= 1.3.6'
|
13
|
-
gem 'pry', '~> 0.12.2'
|
14
|
-
gem 'rubocop', '~> 0.65.0'
|
15
|
-
end
|
data/Gemfile.lock
DELETED
@@ -1,53 +0,0 @@
|
|
1
|
-
GEM
|
2
|
-
remote: https://rubygems.org/
|
3
|
-
specs:
|
4
|
-
ansi (1.5.0)
|
5
|
-
ast (2.4.0)
|
6
|
-
builder (3.2.3)
|
7
|
-
coderay (1.1.2)
|
8
|
-
jaro_winkler (1.5.2)
|
9
|
-
method_source (0.9.2)
|
10
|
-
minitest (5.11.3)
|
11
|
-
minitest-reporters (1.3.6)
|
12
|
-
ansi
|
13
|
-
builder
|
14
|
-
minitest (>= 5.0)
|
15
|
-
ruby-progressbar
|
16
|
-
parallel (1.14.0)
|
17
|
-
parser (2.6.0.0)
|
18
|
-
ast (~> 2.4.0)
|
19
|
-
powerpack (0.1.2)
|
20
|
-
pry (0.12.2)
|
21
|
-
coderay (~> 1.1.0)
|
22
|
-
method_source (~> 0.9.0)
|
23
|
-
psych (3.1.0)
|
24
|
-
rainbow (3.0.0)
|
25
|
-
rake (12.3.2)
|
26
|
-
rubocop (0.65.0)
|
27
|
-
jaro_winkler (~> 1.5.1)
|
28
|
-
parallel (~> 1.10)
|
29
|
-
parser (>= 2.5, != 2.5.1.1)
|
30
|
-
powerpack (~> 0.1)
|
31
|
-
psych (>= 3.1.0)
|
32
|
-
rainbow (>= 2.2.2, < 4.0)
|
33
|
-
ruby-progressbar (~> 1.7)
|
34
|
-
unicode-display_width (~> 1.4.0)
|
35
|
-
ruby-progressbar (1.10.0)
|
36
|
-
unicode-display_width (1.4.1)
|
37
|
-
|
38
|
-
PLATFORMS
|
39
|
-
ruby
|
40
|
-
|
41
|
-
DEPENDENCIES
|
42
|
-
bundler (~> 2.0.1)
|
43
|
-
minitest (~> 5.11, >= 5.11.3)
|
44
|
-
minitest-reporters (~> 1.3, >= 1.3.6)
|
45
|
-
pry (~> 0.12.2)
|
46
|
-
rake (~> 12.3, >= 12.3.2)
|
47
|
-
rubocop (~> 0.65.0)
|
48
|
-
|
49
|
-
RUBY VERSION
|
50
|
-
ruby 2.4.5p335
|
51
|
-
|
52
|
-
BUNDLED WITH
|
53
|
-
2.0.1
|
data/Rakefile
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
require 'rake/testtask'
|
2
|
-
require 'find'
|
3
|
-
|
4
|
-
desc 'Run tests'
|
5
|
-
Rake::TestTask.new(:test) do |t|
|
6
|
-
t.libs << 'lib'
|
7
|
-
t.libs << 'test'
|
8
|
-
t.test_files = FileList['test/**/*_test.rb']
|
9
|
-
end
|
10
|
-
|
11
|
-
desc 'Run tests'
|
12
|
-
task :default => :test
|
13
|
-
|
14
|
-
desc 'Display inventory of all files'
|
15
|
-
task :inventory do
|
16
|
-
Find.find('.') do |name|
|
17
|
-
next if name.include?('/.') # Excludes files and directories with . names
|
18
|
-
puts name if File.file?(name)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
desc 'Run rubocop'
|
23
|
-
task :rub do
|
24
|
-
sh 'rubocop'
|
25
|
-
end
|
@@ -1,40 +0,0 @@
|
|
1
|
-
module ToDecimal
|
2
|
-
# The main class that performs the actual conversion
|
3
|
-
class Convertor
|
4
|
-
attr_reader :base
|
5
|
-
|
6
|
-
def initialize(base)
|
7
|
-
validate_base(base)
|
8
|
-
@base = base
|
9
|
-
freeze
|
10
|
-
end
|
11
|
-
|
12
|
-
def [](input)
|
13
|
-
input = remove_leading_zeros_of(input)
|
14
|
-
Validator.new(input, base).validate
|
15
|
-
|
16
|
-
input_as_integer = integerize(input)
|
17
|
-
convert(input_as_integer)
|
18
|
-
end
|
19
|
-
|
20
|
-
private
|
21
|
-
|
22
|
-
def remove_leading_zeros_of(input)
|
23
|
-
input.is_a?(String) ? input.sub(/\A0+/, '') : input
|
24
|
-
end
|
25
|
-
|
26
|
-
def convert(integer)
|
27
|
-
integer.to_s.to_i(base)
|
28
|
-
end
|
29
|
-
|
30
|
-
def integerize(input)
|
31
|
-
input.is_a?(String) ? input.to_i : input
|
32
|
-
end
|
33
|
-
|
34
|
-
def validate_base(base)
|
35
|
-
raise ArgumentError, 'Base must be an Integer' unless base.is_a?(Integer)
|
36
|
-
raise ArgumentError, 'Base must be 1..10' unless \
|
37
|
-
base.positive? && base <= 10
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
@@ -1,38 +0,0 @@
|
|
1
|
-
module ToDecimal
|
2
|
-
# Class to validate arguments
|
3
|
-
class Validator
|
4
|
-
def initialize(input, base)
|
5
|
-
@input = input
|
6
|
-
@base = base
|
7
|
-
end
|
8
|
-
|
9
|
-
def validate
|
10
|
-
err_value = "Argument must be an integer or a valid string\
|
11
|
-
representation of an integer. You input : #{@input}, of class #{@input.class}."
|
12
|
-
raise ArgumentError, err_value unless valid_integer_string_or_integer?
|
13
|
-
|
14
|
-
err_base = "A number of base #{@base} cannot have a\
|
15
|
-
digit greater or equal to #{@base}. Check your argument: #{@input}."
|
16
|
-
raise WrongBaseInputError, err_base unless valid_input_base?
|
17
|
-
end
|
18
|
-
|
19
|
-
private
|
20
|
-
|
21
|
-
def valid_integer_string_or_integer?
|
22
|
-
valid_integer_string? || valid_integer?
|
23
|
-
end
|
24
|
-
|
25
|
-
def valid_integer?
|
26
|
-
@input.is_a?(Integer)
|
27
|
-
end
|
28
|
-
|
29
|
-
def valid_integer_string?
|
30
|
-
(@input.is_a?(String) && @input.to_i.to_s == @input)
|
31
|
-
end
|
32
|
-
|
33
|
-
def valid_input_base?
|
34
|
-
digitized_input = @input.to_i.digits
|
35
|
-
digitized_input.none? { |digit| digit >= @base }
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|