rational_number 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/Gemfile.lock +1 -1
- data/README.md +1 -1
- data/lib/rational_number/version.rb +1 -1
- data/lib/rational_number.rb +68 -8
- data/spec/rational_number_spec.rb +252 -163
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 794dc0823355a2349f3f92c556d9256119791143
|
4
|
+
data.tar.gz: 7560fbf7d62ba9aefb95f243ad1ca16142591c96
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b0c44b8906a602e9a715878855762692a532e369a6928f90b212487829890b0d1eff7eb732586a174dcf98dc5b37d36d718dd893398bd4f37ab048313687d315
|
7
|
+
data.tar.gz: ee14b91f09f34c9045c0ec27bdb0a47352d89027dcd2e752ab59e4fdab765315dee0718cd2ebfc3f5821142ae6f4529c42d4a9c907148023a6af4417b7198c1c
|
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# rational_number
|
2
|
-
[](https://travis-ci.org/leifcr/rational_number) [](https://coveralls.io/r/leifcr/rational_number?branch=master)
|
2
|
+
[](http://badge.fury.io/rb/rational_number) [](https://travis-ci.org/leifcr/rational_number) [](https://coveralls.io/r/leifcr/rational_number?branch=master) [](https://codeclimate.com/github/leifcr/rational_number)
|
3
3
|
|
4
4
|
This implements basic rational numbers in Ruby. It can be used in tree implementations and provides a really fast way of looking up a sorted tree.
|
5
5
|
|
data/lib/rational_number.rb
CHANGED
@@ -14,10 +14,13 @@
|
|
14
14
|
|
15
15
|
class RationalNumber # < Object
|
16
16
|
include Comparable
|
17
|
-
|
17
|
+
attr_reader :nv, :dv, :snv, :sdv, :number
|
18
18
|
|
19
19
|
##
|
20
20
|
# Compare to other (Comparable)
|
21
|
+
# Returns 1 if greater than, -1 if less than, and 0 for equality
|
22
|
+
#
|
23
|
+
# @return [Integer] Integer stating the comparison.
|
21
24
|
#
|
22
25
|
def <=>(other)
|
23
26
|
return 0 if (@nv === other.nv) and (@dv === other.dv) and (@snv == other.snv) and (@sdv == other.sdv)
|
@@ -25,8 +28,6 @@ class RationalNumber # < Object
|
|
25
28
|
-1
|
26
29
|
elsif @number > other.number
|
27
30
|
1
|
28
|
-
else
|
29
|
-
0
|
30
31
|
end
|
31
32
|
end
|
32
33
|
|
@@ -57,23 +58,78 @@ class RationalNumber # < Object
|
|
57
58
|
##
|
58
59
|
# Initialize rational number
|
59
60
|
#
|
61
|
+
# @param [Integer/RationalNumber] The nominator value or a rational number, depending on number of given parameters
|
62
|
+
# @param [Integer] The denominator value
|
63
|
+
# @param [Integer] The SNV value
|
64
|
+
# @param [Integer] The SDV Value
|
65
|
+
#
|
66
|
+
# @return [undefined]
|
67
|
+
#
|
68
|
+
def initialize(a = nil, b = nil, c = nil, d = nil)
|
69
|
+
if a == nil and b == nil and c == nil and d == nil
|
70
|
+
init_with_4_args()
|
71
|
+
elsif b == nil and c == nil and d == nil
|
72
|
+
init_with_1_arg(a)
|
73
|
+
elsif c == nil and d == nil
|
74
|
+
init_with_2_args(a,b)
|
75
|
+
else
|
76
|
+
init_with_4_args(a,b,c,d)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
##
|
81
|
+
# Initialize rational number with 1 argument
|
82
|
+
#
|
83
|
+
# @param [RationalNumber] The rational number to initialize with
|
84
|
+
#
|
85
|
+
# @return [undefined]
|
86
|
+
#
|
87
|
+
def init_with_1_arg(rational_number)
|
88
|
+
raise ArgumentError, "given :rational_number in options is of wrong type, should be RationalNumber" unless rational_number.instance_of?(RationalNumber)
|
89
|
+
set_values(rational_number.nv, rational_number.dv, rational_number.snv, rational_number.sdv)
|
90
|
+
end
|
91
|
+
|
92
|
+
##
|
93
|
+
# Initialize rational number with 2 arguments
|
94
|
+
#
|
95
|
+
# @param [Integer] The nominator value
|
96
|
+
# @param [Integer] The denominator value
|
97
|
+
#
|
98
|
+
# @return [undefined]
|
99
|
+
#
|
100
|
+
def init_with_2_args(nv = 0, dv = 1)
|
101
|
+
raise ArgumentError, ":nv and :dv must be kind_of?(Integer)." unless nv.kind_of?(Integer) and dv.kind_of?(Integer)
|
102
|
+
# initial values needed when getting parent and position
|
103
|
+
@nv = nv
|
104
|
+
@dv = dv
|
105
|
+
# calculate value
|
106
|
+
val = value_from_parent_and_position(self.parent, self.position)
|
107
|
+
raise ArgumentError, "Cannot set nv and dv values. verify the values for :nv and :dv" unless ((val.nv == nv) and (val.dv == dv))
|
108
|
+
set_values(val.nv,val.dv,val.snv,val.sdv)
|
109
|
+
end
|
110
|
+
|
111
|
+
##
|
112
|
+
# Initialize rational number with 4 arguments
|
113
|
+
#
|
60
114
|
# @param [Integer] The nominator value
|
61
|
-
# @param [Integer] The
|
115
|
+
# @param [Integer] The denominator value
|
62
116
|
# @param [Integer] The SNV value
|
63
117
|
# @param [Integer] The SDV Value
|
64
118
|
#
|
65
119
|
# @return [undefined]
|
66
120
|
#
|
67
|
-
def
|
121
|
+
def init_with_4_args(nv = 0, dv = 1, snv = 1, sdv = 0)
|
122
|
+
unless nv.kind_of?(Integer) and dv.kind_of?(Integer) and snv.kind_of?(Integer) and sdv.kind_of?(Integer)
|
123
|
+
raise ArgumentError, ":nv, :dv, :snv and :sdv must be kind_of?(Integer)."
|
124
|
+
end
|
68
125
|
set_values(nv, dv, snv, sdv)
|
69
|
-
#super()
|
70
126
|
end
|
71
127
|
|
72
128
|
##
|
73
129
|
# Set the values of nv,dv,snv and sdv directly
|
74
130
|
#
|
75
131
|
# @param [Integer] The nominator value
|
76
|
-
# @param [Integer] The
|
132
|
+
# @param [Integer] The denominator value
|
77
133
|
# @param [Integer] The SNV value
|
78
134
|
# @param [Integer] The SDV Value
|
79
135
|
#
|
@@ -82,7 +138,11 @@ class RationalNumber # < Object
|
|
82
138
|
@dv = dv
|
83
139
|
@snv = snv
|
84
140
|
@sdv = sdv
|
85
|
-
|
141
|
+
if nv == 0 and dv == 0
|
142
|
+
@number = Float(0)
|
143
|
+
else
|
144
|
+
@number = Float(nv)/Float(dv)
|
145
|
+
end
|
86
146
|
end
|
87
147
|
|
88
148
|
##
|
@@ -1,165 +1,254 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
describe "RationalNumber" do
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
3
|
+
|
4
|
+
describe "when initializing" do
|
5
|
+
describe "using 0 options" do
|
6
|
+
it "should initialize properly" do
|
7
|
+
a = RationalNumber.new
|
8
|
+
a.nv.should == 0
|
9
|
+
a.dv.should == 1
|
10
|
+
a.snv.should == 1
|
11
|
+
a.sdv.should == 0
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "using 1 option" do
|
16
|
+
it "should initialize with a single RationalNumber as argument" do
|
17
|
+
a = RationalNumber.new
|
18
|
+
a.set_values(5,2,8,3)
|
19
|
+
b = RationalNumber.new(a)
|
20
|
+
b.nv.should == a.nv
|
21
|
+
b.dv.should == a.dv
|
22
|
+
b.snv.should == a.snv
|
23
|
+
b.sdv.should == a.sdv
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should raise an error if rational_number option has the wrong type/data" do
|
27
|
+
expect {RationalNumber.new(4)}.to raise_error(ArgumentError)
|
28
|
+
end
|
29
|
+
end # describe 1 option
|
30
|
+
|
31
|
+
describe "using 2 options" do
|
32
|
+
it "should initialize with nv and dv values" do
|
33
|
+
a = RationalNumber.new(5, 2)
|
34
|
+
a.nv.should == 5
|
35
|
+
a.dv.should == 2
|
36
|
+
a.snv.should == 8
|
37
|
+
a.sdv.should == 3
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should raise an error if rational_number option has the wrong type/data" do
|
41
|
+
expect {RationalNumber.new("cow", 2)}.to raise_error(ArgumentError)
|
42
|
+
end
|
43
|
+
end # describe 2 options
|
44
|
+
|
45
|
+
describe "using 4 options" do
|
46
|
+
it "should initialize with nv, dv, snv and sdv values" do
|
47
|
+
a = RationalNumber.new(5, 2, 8, 3)
|
48
|
+
a.nv.should == 5
|
49
|
+
a.dv.should == 2
|
50
|
+
a.snv.should == 8
|
51
|
+
a.sdv.should == 3
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should raise an error if rational_number option has the wrong type/data" do
|
55
|
+
expect {RationalNumber.new(5, 2, 5, "cow" )}.to raise_error(ArgumentError)
|
56
|
+
end
|
57
|
+
end # describe 4 options
|
58
|
+
end # describe when initializing
|
59
|
+
|
60
|
+
describe "when using" do
|
61
|
+
|
62
|
+
before(:each) do
|
63
|
+
@root = RationalNumber.new
|
64
|
+
@first_child = @root.child_from_position(1)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should verify that @root is @root" do
|
68
|
+
@root.root?.should == true
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should raise an error when trying to get parent rational number on @root" do
|
72
|
+
expect {@root.parent}.to raise_error(NoParentRationalNumberIsRootError)
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should raise an error when trying to get a sibling on @root" do
|
76
|
+
expect {@root.next_sibling}.to raise_error(RationalNumberIsRootNoSiblingsError)
|
77
|
+
expect {@root.sibling_from_position(0)}.to raise_error(RationalNumberIsRootNoSiblingsError)
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should verify values" do
|
81
|
+
@root.nv.should == 0
|
82
|
+
@root.dv.should == 1
|
83
|
+
@root.snv.should == 1
|
84
|
+
@root.sdv.should == 0
|
85
|
+
@root.number.should == Float(0)
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should create a 0 based rational number without getting div by zero" do
|
89
|
+
test = RationalNumber.new(0,0,0,0)
|
90
|
+
test.number.should == Float(0)
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should get the first child values" do
|
94
|
+
@first_child.nv.should == 1
|
95
|
+
@first_child.dv.should == 1
|
96
|
+
@first_child.snv.should == 2
|
97
|
+
@first_child.sdv.should == 1
|
98
|
+
@first_child.number.should == Float(@first_child.nv)/Float(@first_child.dv)
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should verify the parent values of the first child" do
|
102
|
+
parent = @first_child.parent
|
103
|
+
child = @first_child
|
104
|
+
parent.should == child.parent
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should verify the parent values of a child of the first child" do
|
108
|
+
parent = @first_child
|
109
|
+
child = @first_child.child_from_position(5)
|
110
|
+
parent.should == child.parent
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should get the child values from a given position" do
|
114
|
+
fifth_child = @root.child_from_position(5)
|
115
|
+
fifth_child.nv.should == 5
|
116
|
+
fifth_child.dv.should == 1
|
117
|
+
fifth_child.snv.should == 6
|
118
|
+
fifth_child.sdv.should == 1
|
119
|
+
fifth_child.number.should == Float(fifth_child.nv)/Float(fifth_child.dv)
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should get the next sibling from first child" do
|
123
|
+
next_sibling = @first_child.next_sibling
|
124
|
+
next_sibling.nv.should == 2
|
125
|
+
next_sibling.dv.should == 1
|
126
|
+
next_sibling.snv.should == 3
|
127
|
+
next_sibling.sdv.should == 1
|
128
|
+
next_sibling.number.should == Float(next_sibling.nv)/Float(next_sibling.dv)
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should get fifth sibling from first child" do
|
132
|
+
fifth_sibling = @first_child.sibling_from_position(5)
|
133
|
+
fifth_sibling.nv.should == 5
|
134
|
+
fifth_sibling.dv.should == 1
|
135
|
+
fifth_sibling.snv.should == 6
|
136
|
+
fifth_sibling.sdv.should == 1
|
137
|
+
fifth_sibling.number.should == Float(fifth_sibling.nv)/Float(fifth_sibling.dv)
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should verify two children of the first child" do
|
141
|
+
child_1_1 = @first_child.child_from_position(1)
|
142
|
+
child_1_1.nv.should == 3
|
143
|
+
child_1_1.dv.should == 2
|
144
|
+
child_1_1.snv.should == 5
|
145
|
+
child_1_1.sdv.should == 3
|
146
|
+
child_1_1.number.should == Float(child_1_1.nv)/Float(child_1_1.dv)
|
147
|
+
|
148
|
+
child_1_3 = @first_child.child_from_position(3)
|
149
|
+
|
150
|
+
child_1_3.nv.should == 7
|
151
|
+
child_1_3.dv.should == 4
|
152
|
+
child_1_3.snv.should == 9
|
153
|
+
child_1_3.sdv.should == 5
|
154
|
+
child_1_3.number.should == Float(child_1_3.nv)/Float(child_1_3.dv)
|
155
|
+
end
|
156
|
+
|
157
|
+
it "should verify the position of three rational numbers" do
|
158
|
+
child_1_1 = @first_child.child_from_position(1)
|
159
|
+
child_1_1.position.should == 1
|
160
|
+
child_1_3 = @first_child.child_from_position(3)
|
161
|
+
child_1_3.position.should == 3
|
162
|
+
fifth_child = @root.child_from_position(5)
|
163
|
+
fifth_child.position.should == 5
|
164
|
+
end
|
165
|
+
|
166
|
+
it "should verify comparison of rational numbers" do
|
167
|
+
child_1 = @first_child
|
168
|
+
child_1_1 = @first_child.child_from_position(1)
|
169
|
+
child_1_3 = @first_child.child_from_position(3)
|
170
|
+
child_2 = @first_child.next_sibling
|
171
|
+
|
172
|
+
child_1.should < child_1_1
|
173
|
+
child_1_1.should < child_1_3
|
174
|
+
child_1_3.should < child_2
|
175
|
+
child_2.should > child_1
|
176
|
+
child_2.should > child_1_1
|
177
|
+
child_2.should > child_1_3
|
178
|
+
child_1_1.should == child_1_1
|
179
|
+
@root.should == @root
|
180
|
+
child_2.should == child_2
|
181
|
+
child_1_1.should_not == child_1_3
|
182
|
+
child_1_1.should_not == child_1
|
183
|
+
child_1_1.should_not == @root
|
184
|
+
child_1.should_not == child_2
|
185
|
+
|
186
|
+
end
|
187
|
+
|
188
|
+
it "should set values directoy" do
|
189
|
+
a = RationalNumber.new
|
190
|
+
b = @first_child.child_from_position(3)
|
191
|
+
a.set_from_other(b)
|
192
|
+
b.should == a
|
193
|
+
end
|
194
|
+
|
195
|
+
it "should set values from other RationalNumber" do
|
196
|
+
a = RationalNumber.new
|
197
|
+
b = @first_child.child_from_position(3)
|
198
|
+
a.set_values(b.nv,b.dv,b.snv,b.sdv)
|
199
|
+
b.should == a
|
200
|
+
end
|
201
|
+
|
202
|
+
it "should check if the RationalNumber resonds to being a child of an given parent" do
|
203
|
+
child_1_4 = @first_child.child_from_position(4)
|
204
|
+
@first_child.is_child_of?(@root).should == true
|
205
|
+
child_1_4.is_child_of?(@root).should == false
|
206
|
+
child_1_4.is_child_of?(@first_child).should == true
|
207
|
+
child_1_4.is_child_of?(child_1_4).should == false # should return false for same object
|
208
|
+
end
|
209
|
+
|
210
|
+
it "should check if the RationalNumber responds to being a parent of a given child" do
|
211
|
+
child_1_4 = @first_child.child_from_position(4)
|
212
|
+
@root.is_parent_of?(@first_child).should == true
|
213
|
+
@root.is_parent_of?(child_1_4).should == false
|
214
|
+
@first_child.is_parent_of?(child_1_4).should == true
|
215
|
+
child_1_4.is_parent_of?(child_1_4).should == false # should return false for same object
|
216
|
+
end
|
217
|
+
|
218
|
+
it "should respons if the RationalNumber is a descendant of given parent" do
|
219
|
+
child_1_4 = @first_child.child_from_position(4)
|
220
|
+
child_1_4_9 = child_1_4.child_from_position(9)
|
221
|
+
child_1_4_9.is_descendant_of?(@root).should == true
|
222
|
+
child_1_4_9.is_descendant_of?(@first_child).should == true
|
223
|
+
child_1_4_9.is_descendant_of?(child_1_4).should == true
|
224
|
+
|
225
|
+
child_1_4.is_descendant_of?(@root).should == true
|
226
|
+
child_1_4.is_descendant_of?(@first_child).should == true
|
227
|
+
child_1_4.is_descendant_of?(child_1_4_9).should == false
|
228
|
+
|
229
|
+
@first_child.is_descendant_of?(@root).should == true
|
230
|
+
@first_child.is_descendant_of?(child_1_4).should == false
|
231
|
+
|
232
|
+
@root.is_descendant_of?(@root).should == false
|
233
|
+
@first_child.is_descendant_of?(@first_child).should == false
|
234
|
+
@root.is_descendant_of?(child_1_4_9).should == false
|
235
|
+
end
|
236
|
+
|
237
|
+
it "should generate a Hash from the rational number" do
|
238
|
+
child_1_4 = @first_child.child_from_position(4)
|
239
|
+
child_1_4.to_hash.should == {
|
240
|
+
:nv => child_1_4.nv,
|
241
|
+
:dv => child_1_4.dv,
|
242
|
+
:snv => child_1_4.snv,
|
243
|
+
:sdv => child_1_4.sdv,
|
244
|
+
:number => child_1_4.number
|
245
|
+
}
|
246
|
+
end
|
247
|
+
|
248
|
+
it "should generate a nice printable string for debugging purposes" do
|
249
|
+
child_1_4 = @first_child.child_from_position(4)
|
250
|
+
child_1_4.to_s.should == "RationalNumber: number: #{child_1_4.number} nv: #{child_1_4.nv} dv: #{child_1_4.dv} snv: #{child_1_4.snv} sdv: #{child_1_4.sdv}"
|
251
|
+
end
|
252
|
+
|
253
|
+
end # describe when using
|
254
|
+
end #describe RationalNumber
|