ntable 0.1.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.
@@ -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