ntable 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,130 @@
1
+ # -----------------------------------------------------------------------------
2
+ #
3
+ # Table slicing tests
4
+ #
5
+ # -----------------------------------------------------------------------------
6
+ # Copyright 2012 Daniel Azuma
7
+ #
8
+ # All rights reserved.
9
+ #
10
+ # Redistribution and use in source and binary forms, with or without
11
+ # modification, are permitted provided that the following conditions are met:
12
+ #
13
+ # * Redistributions of source code must retain the above copyright notice,
14
+ # this list of conditions and the following disclaimer.
15
+ # * Redistributions in binary form must reproduce the above copyright notice,
16
+ # this list of conditions and the following disclaimer in the documentation
17
+ # and/or other materials provided with the distribution.
18
+ # * Neither the name of the copyright holder, nor the names of any other
19
+ # contributors to this software, may be used to endorse or promote products
20
+ # derived from this software without specific prior written permission.
21
+ #
22
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32
+ # POSSIBILITY OF SUCH DAMAGE.
33
+ # -----------------------------------------------------------------------------
34
+ ;
35
+
36
+
37
+ require 'minitest/autorun'
38
+ require 'ntable'
39
+
40
+
41
+ module NTable
42
+ module Tests # :nodoc:
43
+
44
+ class TestSlice < ::MiniTest::Unit::TestCase # :nodoc:
45
+
46
+
47
+ def setup
48
+ @labeled_axis_2 = LabeledAxis.new([:one, :two])
49
+ @labeled_axis_3 = LabeledAxis.new([:red, :white, :blue])
50
+ @indexed_axis_2 = IndexedAxis.new(2)
51
+ @indexed_axis_10 = IndexedAxis.new(10,1)
52
+ @indexed_axis_0 = IndexedAxis.new(0)
53
+ end
54
+
55
+
56
+ def test_slice_of_no_axes
57
+ t1_ = Table.new(Structure.new)
58
+ t2_ = t1_.slice({})
59
+ assert_equal(t1_, t2_)
60
+ end
61
+
62
+
63
+ def test_nop_slice_1
64
+ t1_ = Table.new(Structure.new.add(@labeled_axis_2), :fill => 1)
65
+ t1s_ = t1_.slice({})
66
+ assert_equal(t1_, t1s_)
67
+ end
68
+
69
+
70
+ def test_nop_slice_2
71
+ t1_ = Table.new(Structure.new.add(@indexed_axis_10, :row).add(@labeled_axis_3, :column), :fill => 1)
72
+ t1s_ = t1_.slice({})
73
+ assert_equal(t1_, t1s_)
74
+ end
75
+
76
+
77
+ def test_slice_1_to_0_indexed
78
+ t1_ = Table.new(Structure.new.add(@indexed_axis_10, :row), :load => (2..11).to_a)
79
+ t1s_ = t1_.slice(:row => 3)
80
+ assert_equal(4, t1s_.get)
81
+ end
82
+
83
+
84
+ def test_slice_1_to_0_labeled
85
+ t1_ = Table.new(Structure.new.add(@labeled_axis_3, :col), :load => [2,3,4])
86
+ t1s_ = t1_.slice(:col => :white)
87
+ assert_equal(3, t1s_.get)
88
+ end
89
+
90
+
91
+ def test_slice_2_to_0
92
+ s1_ = Structure.new.add(@indexed_axis_10, :row).add(@labeled_axis_3, :col)
93
+ t1_ = Table.new(s1_, :load => (2..31).to_a)
94
+ t1s_ = t1_.slice(:row => 2, :col => :white)
95
+ assert_equal(6, t1s_.get)
96
+ end
97
+
98
+
99
+ def test_slice_2_to_1_major
100
+ s1_ = Structure.new.add(@indexed_axis_10, :row).add(@labeled_axis_3, :col)
101
+ t1_ = Table.new(s1_, :load => (2..31).to_a)
102
+ t1s_ = t1_.slice(:row => 2)
103
+ t2_ = Table.new(Structure.new.add(@labeled_axis_3, :col), :load => [5,6,7])
104
+ assert_equal(t2_, t1s_)
105
+ end
106
+
107
+
108
+ def test_slice_2_to_1_minor
109
+ s1_ = Structure.new.add(@indexed_axis_10, :row).add(@labeled_axis_3, :col)
110
+ t1_ = Table.new(s1_, :load => (2..31).to_a)
111
+ t1s_ = t1_.slice(:col => :white)
112
+ t2_ = Table.new(Structure.new.add(@indexed_axis_10, :row), :load => [3,6,9,12,15,18,21,24,27,30])
113
+ assert_equal(t2_, t1s_)
114
+ end
115
+
116
+
117
+ def test_shared_slice_1_to_0_indexed
118
+ t1_ = Table.new(Structure.new.add(@indexed_axis_10, :row), :load => (2..11).to_a)
119
+ t1s_ = t1_.shared_slice(:row => 3)
120
+ assert_equal(4, t1s_.get)
121
+ assert_equal(Table.new(Structure.new, :load => [4]), t1s_)
122
+ t1_.set!(3, :foo)
123
+ assert_equal(:foo, t1s_.get)
124
+ end
125
+
126
+
127
+ end
128
+
129
+ end
130
+ end
@@ -0,0 +1,202 @@
1
+ # -----------------------------------------------------------------------------
2
+ #
3
+ # Table structure tests
4
+ #
5
+ # -----------------------------------------------------------------------------
6
+ # Copyright 2012 Daniel Azuma
7
+ #
8
+ # All rights reserved.
9
+ #
10
+ # Redistribution and use in source and binary forms, with or without
11
+ # modification, are permitted provided that the following conditions are met:
12
+ #
13
+ # * Redistributions of source code must retain the above copyright notice,
14
+ # this list of conditions and the following disclaimer.
15
+ # * Redistributions in binary form must reproduce the above copyright notice,
16
+ # this list of conditions and the following disclaimer in the documentation
17
+ # and/or other materials provided with the distribution.
18
+ # * Neither the name of the copyright holder, nor the names of any other
19
+ # contributors to this software, may be used to endorse or promote products
20
+ # derived from this software without specific prior written permission.
21
+ #
22
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32
+ # POSSIBILITY OF SUCH DAMAGE.
33
+ # -----------------------------------------------------------------------------
34
+ ;
35
+
36
+
37
+ require 'minitest/autorun'
38
+ require 'ntable'
39
+
40
+
41
+ module NTable
42
+ module Tests # :nodoc:
43
+
44
+ class TestStructure < ::MiniTest::Unit::TestCase # :nodoc:
45
+
46
+
47
+ def setup
48
+ @labeled1 = LabeledAxis.new([:one, :two])
49
+ @labeled2 = LabeledAxis.new([:red, :white, :blue])
50
+ @indexed1 = IndexedAxis.new(10)
51
+ @indexed2 = IndexedAxis.new(15, 1)
52
+ @indexed3 = IndexedAxis.new(0)
53
+ end
54
+
55
+
56
+ def test_dim_for_various_adds
57
+ s_ = Structure.new
58
+ s_.add(@labeled1)
59
+ assert_equal(1, s_.dim)
60
+ s_.add(@indexed1)
61
+ assert_equal(2, s_.dim)
62
+ s_.add(@indexed1)
63
+ assert_equal(3, s_.dim)
64
+ end
65
+
66
+
67
+ def test_add_single_axis
68
+ s_ = Structure.new
69
+ s_.add(@labeled1, :first)
70
+ assert_equal(@labeled1, s_.axis_info(0).axis)
71
+ assert_equal(@labeled1, s_.axis_info(:first).axis)
72
+ assert_equal(0, s_.axis_info(:first).index)
73
+ assert_equal('first', s_.axis_info(0).name)
74
+ end
75
+
76
+
77
+ def test_add_multi_axis
78
+ s_ = Structure.new
79
+ s_.add(@labeled1, :first)
80
+ s_.add(@indexed1, :second)
81
+ s_.add(@indexed1)
82
+ assert_equal(@labeled1, s_.axis_info(0).axis)
83
+ assert_equal(@labeled1, s_.axis_info(:first).axis)
84
+ assert_equal(0, s_.axis_info(:first).index)
85
+ assert_equal('first', s_.axis_info(0).name)
86
+ assert_equal(@indexed1, s_.axis_info(1).axis)
87
+ assert_equal(@indexed1, s_.axis_info(:second).axis)
88
+ assert_equal(1, s_.axis_info(:second).index)
89
+ assert_equal('second', s_.axis_info(1).name)
90
+ assert_equal(@indexed1, s_.axis_info(2).axis)
91
+ assert_nil(s_.axis_info(2).name)
92
+ end
93
+
94
+
95
+ def test_remove_axis
96
+ s_ = Structure.new
97
+ s_.add(@labeled1, :first)
98
+ s_.add(@indexed1, :second)
99
+ s_.remove(:first)
100
+ assert_equal(1, s_.dim)
101
+ assert_equal(@indexed1, s_.axis_info(0).axis)
102
+ assert_equal(@indexed1, s_.axis_info(:second).axis)
103
+ assert_equal(0, s_.axis_info(:second).index)
104
+ assert_equal('second', s_.axis_info(0).name)
105
+ assert_nil(s_.axis_info(1))
106
+ assert_nil(s_.axis_info(:first))
107
+ end
108
+
109
+
110
+ def test_lock
111
+ s_ = Structure.new.add(@labeled1)
112
+ assert_equal(false, s_.locked?)
113
+ s_.lock!
114
+ assert_equal(true, s_.locked?)
115
+ end
116
+
117
+
118
+ def test_size_1
119
+ s_ = Structure.new.add(@labeled1).lock!
120
+ assert_equal(2, s_.size)
121
+ end
122
+
123
+
124
+ def test_size_2
125
+ s_ = Structure.new.add(@labeled1).add(@indexed1).add(@indexed2).lock!
126
+ assert_equal(300, s_.size)
127
+ end
128
+
129
+
130
+ def test_size_no_axes
131
+ s_ = Structure.new.lock!
132
+ assert_equal(1, s_.size)
133
+ end
134
+
135
+
136
+ def test_size_with_empty_axis
137
+ s_ = Structure.new.add(@labeled1).add(@indexed1).add(@indexed3).lock!
138
+ assert_equal(0, s_.size)
139
+ end
140
+
141
+
142
+ def test_offset_labeled1_array
143
+ s_ = Structure.new.add(@labeled1).lock!
144
+ assert_equal(0, s_._offset([:one]))
145
+ assert_equal(1, s_._offset([:two]))
146
+ assert_nil(s_._offset([:three]))
147
+ end
148
+
149
+
150
+ def test_offset_labeled1_hash
151
+ s_ = Structure.new.add(@labeled1, :first_label).lock!
152
+ assert_equal(0, s_._offset(:first_label => :one))
153
+ assert_equal(1, s_._offset(:first_label => :two))
154
+ assert_nil(s_._offset(:first_label => :three))
155
+ assert_nil(s_._offset(:second_label => :one))
156
+ end
157
+
158
+
159
+ def test_offset_labeled1_indexed1_array
160
+ s_ = Structure.new.add(@labeled1).add(@indexed1).lock!
161
+ assert_equal(2, s_._offset([:one, 2]))
162
+ assert_equal(13, s_._offset([:two, 3]))
163
+ assert_equal(10, s_._offset([:two]))
164
+ assert_nil(s_._offset([:three, 0]))
165
+ end
166
+
167
+
168
+ def test_offset_labeled1_indexed1_hash
169
+ s_ = Structure.new.add(@labeled1, :first_axis).add(@indexed1, :second_axis).lock!
170
+ assert_equal(2, s_._offset(:first_axis => :one, :second_axis => 2))
171
+ assert_equal(13, s_._offset(:first_axis => :two, :second_axis => 3))
172
+ assert_equal(5, s_._offset(:second_axis => 5))
173
+ assert_nil(s_._offset(:first_axis => :three))
174
+ assert_nil(s_._offset(:third_axis => :three))
175
+ end
176
+
177
+
178
+ def test_offset_no_axes
179
+ s_ = Structure.new.lock!
180
+ assert_equal(0, s_._offset([]))
181
+ assert_equal(0, s_._offset({}))
182
+ end
183
+
184
+
185
+ def test_empty_structure_equality
186
+ assert_equal(Structure.new, Structure.new)
187
+ end
188
+
189
+
190
+ def test_structure_equality
191
+ s1_ = Structure.new.add(@labeled1).add(@indexed1)
192
+ s2_ = Structure.new.add(@labeled1).add(@indexed1)
193
+ s3_ = Structure.new.add(@indexed1).add(@labeled1)
194
+ assert_equal(s1_, s2_)
195
+ refute_equal(s1_, s3_)
196
+ end
197
+
198
+
199
+ end
200
+
201
+ end
202
+ end
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ntable
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Daniel Azuma
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-09-02 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: NTable provides a convenient data structure for storing n-dimensional
15
+ tabular data. It works with zero-dimensional scalar values, arrays, tables, and
16
+ any arbitrary-dimensional hypertables. Each dimension is described by an axis object.
17
+ The "rows" in that dimension might be identified by numbers or names. You can perform
18
+ slice operations across any dimension, as well as reductions and dimensional decomposition.
19
+ Finally, serialization is provided via a custom JSON schema, as well as a simple
20
+ "hash of hashes" or "array of arrays" approach.
21
+ email: dazuma@gmail.com
22
+ executables: []
23
+ extensions: []
24
+ extra_rdoc_files:
25
+ - History.rdoc
26
+ - README.rdoc
27
+ files:
28
+ - lib/ntable/axis.rb
29
+ - lib/ntable/errors.rb
30
+ - lib/ntable/structure.rb
31
+ - lib/ntable/table.rb
32
+ - lib/ntable.rb
33
+ - test/tc_axes.rb
34
+ - test/tc_basic_values.rb
35
+ - test/tc_decompose.rb
36
+ - test/tc_enumeration.rb
37
+ - test/tc_json.rb
38
+ - test/tc_nested_object.rb
39
+ - test/tc_reduce.rb
40
+ - test/tc_slice.rb
41
+ - test/tc_structure.rb
42
+ - History.rdoc
43
+ - README.rdoc
44
+ - Version
45
+ homepage: http://github.com/dazuma/ntable
46
+ licenses: []
47
+ post_install_message:
48
+ rdoc_options: []
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ! '>='
55
+ - !ruby/object:Gem::Version
56
+ version: 1.9.2
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ! '>'
61
+ - !ruby/object:Gem::Version
62
+ version: 1.3.1
63
+ requirements: []
64
+ rubyforge_project: virtuoso
65
+ rubygems_version: 1.8.24
66
+ signing_key:
67
+ specification_version: 3
68
+ summary: NTable is an n-dimensional table data structure for Ruby.
69
+ test_files:
70
+ - test/tc_axes.rb
71
+ - test/tc_basic_values.rb
72
+ - test/tc_decompose.rb
73
+ - test/tc_enumeration.rb
74
+ - test/tc_json.rb
75
+ - test/tc_nested_object.rb
76
+ - test/tc_reduce.rb
77
+ - test/tc_slice.rb
78
+ - test/tc_structure.rb