opr-calc 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 434b7eba4789fd454564da8db982a45cbc31c5ce
4
- data.tar.gz: 71bbf74562b830a636202be0c0e100785c125b6a
3
+ metadata.gz: bc4b64c17002cc19c3c9ccda154fdeecd1a57043
4
+ data.tar.gz: e1aa8b1a9fd828b2d3a76fce85f3c0a7d961b2cb
5
5
  SHA512:
6
- metadata.gz: bc786e92a7d323d21ab2cacd40b7a05379453215b238754d45d2a490f17bb9473c1ea9067ad0d9140432c4c4e2737d600c55e3f96b78380ba7abe0a6939f6ab1
7
- data.tar.gz: 58a190ddaf8aa3b405b5e80127f66a28f1682f3df4cc907d7976bb9f05c9b1252e50b752538f61dab2a00e6a54a66fab70d676358de3a6c5a6e0da8c6b0ed133
6
+ metadata.gz: d1d6b5e73181e786af4e61bfa0c8f4976c0aa371daded216bd2306de6c2847984d01da721c4f82bad26c5a0995044c2c20bcc09306d7e65ec28305f5a0b0a2fb
7
+ data.tar.gz: a76ab942d81c005e258c71e7a0eb3e71fbee67836c430c055da23a724b63ece9e7faf7bd22e8c003ed67d9c7dd014982946f4591c3f275182b26a86f4acfe279
@@ -1,325 +1,20 @@
1
- #!/usr/bin/env ruby
2
-
3
1
  =begin
4
- opr-calc is a tool for calculating OPR and other scouting stats for FRC teams.
5
- Copyright (C) 2014 Kristofer Rye and Christopher Cooper
2
+ opr-calc is a tool for calculating OPR and other scouting stats for FRC teams.
3
+ Copyright (C) 2014 Kristofer Rye and Christopher Cooper
6
4
 
7
- This program is free software: you can redistribute it and/or modify
8
- it under the terms of the GNU General Public License as published by
9
- the Free Software Foundation, either version 3 of the License, or
10
- (at your option) any later version.
5
+ This program is free software: you can redistribute it and/or modify
6
+ it under the terms of the GNU General Public License as published by
7
+ the Free Software Foundation, either version 3 of the License, or
8
+ (at your option) any later version.
11
9
 
12
- This program is distributed in the hope that it will be useful,
13
- but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- GNU General Public License for more details.
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU General Public License for more details.
16
14
 
17
- You should have received a copy of the GNU General Public License
18
- along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+ You should have received a copy of the GNU General Public License
16
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
19
17
  =end
20
18
 
21
- require 'matrix'
22
-
23
- # Props to http://rosettacode.org/wiki/Cholesky_decomposition#Ruby :L
24
- class Matrix
25
- # Returns whether or not the Matrix is symmetric (http://en.wikipedia.org/wiki/Symmetric_matrix)
26
- def symmetric?
27
-
28
- # Matrices can't be symmetric if they're not square.
29
- return false if not square?
30
-
31
- (0...row_size).each do |i|
32
- (0..i).each do |j|
33
- return false if self[i,j] != self[j,i]
34
- end
35
- end
36
-
37
- true
38
- end
39
-
40
- def cholesky_factor
41
- # We need a symmetric matrix for Cholesky.
42
- raise ArgumentError, "You must provide symmetric matrix" unless symmetric?
43
-
44
- # Make a new matrix to return
45
- l = Array.new(row_size) { Array.new(row_size, 0) }
46
-
47
- (0...row_size).each do |k|
48
- (0...row_size).each do |i|
49
- if i == k
50
- sum = (0..k-1).inject(0.0) {|sum, j| sum + l[k][j] ** 2}
51
- val = Math.sqrt(self[k,k] - sum)
52
- l[k][k] = val
53
- elsif i > k
54
- sum = (0..k-1).inject(0.0) {|sum, j| sum + l[i][j] * l[k][j]}
55
- val = (self[k,i] - sum) / l[k][k]
56
- l[i][k] = val
57
- end
58
- end
59
- end
60
-
61
- Matrix[*l]
62
- end
63
-
64
- # A helpful debug function for Matrices
65
- def output
66
- (0..self.row_size - 1).each do |row_number|
67
- (0..self.column_size - 1).each do |column_number|
68
- printf("%8.4f ", self[row_number, column_number])
69
- end
70
- printf("\n")
71
- end
72
- self
73
- end
74
- end
75
-
76
-
77
-
78
- class ScoreSet
79
- attr_reader :ared, :ablue, :scorered, :scoreblue
80
-
81
- def ared=(value)
82
- @ared = value
83
- @opr_recalc = @dpr_recalc = @ccwm_recalc = true
84
- end
85
- def ablue=(value)
86
- @ablue = value
87
- @opr_recalc = @dpr_recalc = @ccwm_recalc = true
88
- end
89
- def scorered=(value)
90
- @scorered = value
91
- @opr_recalc = @dpr_recalc = @ccwm_recalc = true
92
- end
93
- def scoreblue=(value)
94
- @scoreblue = value
95
- @opr_recalc = @dpr_recalc = @ccwm_recalc = true
96
- end
97
-
98
- def initialize(ared, ablue, scorered, scoreblue)
99
- @ared = ared
100
- @ablue = ablue
101
- @scorered = scorered
102
- @scoreblue = scoreblue
103
- end
104
-
105
- # A generic function for smooshing two matrices (one red, one blue).
106
- # Each should have the same dimensions.
107
- def alliance_smooshey(redmatrix, bluematrix)
108
- throw ArgumentError "Matrices must have same dimensions" unless (redmatrix.row_size == bluematrix.row_size) && (redmatrix.column_size == bluematrix.column_size)
109
-
110
- # Then we just pull the column and row size from the red matrix because we can.
111
- column_count = redmatrix.column_size
112
- row_count = redmatrix.row_size
113
-
114
- # Use a block function to generate the new matrix
115
- matrix = Matrix.build(row_count * 2, column_count) do
116
- |row, column|
117
-
118
- # note: no need to alternate, instead put all red, then all blue
119
- if row < row_count # first half = red
120
- redmatrix[row, column]
121
- else # second half = blue
122
- bluematrix[row - row_count, column]
123
- end
124
- end
125
- # This will end up looking like as follows:
126
-
127
- # [[red[0]],
128
- # [red[1]],
129
- # [red[2]],
130
- # ...
131
- # [red[n]],
132
- # [blue[0]],
133
- # [blue[1]],
134
- # [blue[2]],
135
- # ...
136
- # [blue[n]]]
137
- return matrix
138
- end
139
-
140
- private :alliance_smooshey
141
-
142
- # Solve equation of form [l][x] = [s] for [x]
143
- # l must be a lower triangular matrix.
144
- # Based off of algorithm given at http://en.wikipedia.org/wiki/Triangular_matrix#Forward_and_back_substitution
145
- def forward_substitute(l, s)
146
- raise "l must be a lower triangular matrix" unless l.lower_triangular?
147
-
148
- x = Array.new s.row_size
149
-
150
- x.size.times do |i|
151
- x[i] = s[i, 0]
152
- i.times do |j|
153
- x[i] -= l[i, j] * x[j]
154
- end
155
- x[i] /= l[i, i]
156
- end
157
-
158
- Matrix.column_vector x
159
- end
160
-
161
- # Solve equation of form [u][x] = [s] for [x]
162
- # u must be a upper triangular matrix.
163
- def back_substitute(u, s)
164
- raise "u must be an upper triangular matrix" unless u.upper_triangular?
165
-
166
- x = Array.new s.row_size
167
-
168
- (x.size - 1).downto 0 do |i|
169
- x[i] = s[i, 0]
170
- (i + 1).upto(x.size - 1) do |j|
171
- x[i] -= u[i, j] * x[j]
172
- end
173
- x[i] /= u[i, i]
174
- end
175
-
176
- Matrix.column_vector x
177
- end
178
-
179
- private :forward_substitute, :back_substitute
180
-
181
- =begin
182
- base matrix equation: [A][OPR] = [SCORE]
183
- define [A]^t to be [A] transpose
184
- define [P] to be [A]^t[A]
185
- define [S] to be [A]^t[SCORE]
186
- equation is now [P][OPR] = [S]
187
- refactor [P] as [L][L]^t using cholesky
188
- [L] is a lower triangular matrix and [L]^t an upper
189
- Therefore [L][L]^t[OPR] = [S]
190
- define [Y] = [L]^t[OPR]
191
- equation is now [L][Y] = [S]
192
- find [Y] through forward substitution
193
- find [OPR] through back substitution
194
- =end
195
-
196
- def opr_calculate(a, score)
197
- p = a.t * a
198
- s = a.t * score
199
-
200
- l = p.cholesky_factor
201
-
202
- # l.output
203
- # l.t.output
204
-
205
- y = forward_substitute l, s
206
- back_substitute l.t, y
207
- end
208
-
209
- # Offensive power rating: the average amount of points that a team contributes to their alliance's score
210
- # This is high for a good team
211
- def opr(recalc = false)
212
- if !@opr || recalc || @opr_recalc
213
- a = alliance_smooshey @ared, @ablue
214
- score = alliance_smooshey @scorered, @scoreblue
215
-
216
- @opr = opr_calculate a, score
217
- @opr_recalc = false
218
- end
219
- @opr
220
- end
221
-
222
- # Defensive power rating: the average amount of points that a team lets the other alliance score
223
- # This is low for a good team
224
- def dpr(recalc = false)
225
- if !@dpr || recalc || @dpr_recalc
226
- a = alliance_smooshey @ared, @ablue
227
- score = alliance_smooshey @scoreblue, @scorered # intentionally swapped, that's how dpr works
228
-
229
- @dpr = opr_calculate a, score
230
- @dpr_recalc = false
231
- end
232
- @dpr
233
- end
234
-
235
- # Calculated contribution to winning margin: the average amount of points that a team contributes to their alliance's winning margin
236
- # This is high for a good team
237
- def ccwm(recalc = false)
238
- if !@ccwm || recalc || @ccwm_recalc
239
- a = alliance_smooshey @ared, @ablue
240
-
241
- red_wm = Matrix.build(@scorered.row_size, @scorered.column_size) do |row, column|
242
- @scorered[row, column] - @scoreblue[row, column]
243
- end
244
- blue_wm = Matrix.build(@scoreblue.row_size, @scoreblue.column_size) do |row, column|
245
- @scoreblue[row, column] - @scorered[row, column]
246
- end
247
-
248
- score = alliance_smooshey red_wm, blue_wm
249
-
250
- @ccwm = opr_calculate a, score
251
- @ccwm_recalc = false
252
- end
253
- @ccwm
254
- end
255
-
256
- end
257
-
258
-
259
- def test_stuff
260
- # Team 0 opr: 0
261
- # Team 1 opr: 1
262
- # Team 2 opr: 2
263
- # ...
264
-
265
- # I don't think any team is every playing on both blue and red at the same time, but I might be wrong
266
-
267
- # 0 1 2 3 4 5 6 7 8 9
268
- test_ared = Matrix[[1, 0, 1, 0, 1, 0, 0, 0, 0, 0],
269
- [0, 1, 0, 1, 0, 1, 0, 0, 0, 0],
270
- [0, 0, 0, 0, 1, 1, 1, 0, 0, 0],
271
- [0, 0, 0, 0, 0, 0, 0, 1, 1, 1],
272
- [0, 1, 0, 0, 0, 1, 1, 0, 0, 0],
273
- [1, 0, 0, 1, 0, 0, 1, 0, 0, 0]]
274
-
275
- # 0 1 2 3 4 5 6 7 8 9
276
- test_ablue = Matrix[[0, 0, 1, 0, 0, 0, 0, 1, 0, 1],
277
- [1, 0, 0, 0, 1, 0, 0, 0, 1, 0],
278
- [1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
279
- [0, 0, 1, 0, 0, 1, 1, 0, 0, 0],
280
- [0, 0, 0, 1, 0, 0, 0, 0, 1, 1],
281
- [0, 1, 0, 0, 1, 0, 0, 1, 0, 0]]
282
-
283
-
284
- test_scorered = Matrix[[6],
285
- [9],
286
- [15],
287
- [24],
288
- [12],
289
- [9]]
290
-
291
- test_scoreblue = Matrix[[18],
292
- [12],
293
- [3],
294
- [13],
295
- [20],
296
- [12]]
297
-
298
- test_expectedopr = Matrix[[0],
299
- [1],
300
- [2],
301
- [3],
302
- [4],
303
- [5],
304
- [6],
305
- [7],
306
- [8],
307
- [9]]
308
-
309
- test = ScoreSet.new test_ared, test_ablue, test_scorered, test_scoreblue
310
-
311
- puts "Expected OPR:"
312
- test_expectedopr.output
313
- puts "Actual OPR:"
314
- test.opr.output
315
-
316
- puts "DPR:"
317
- test.dpr.output
318
-
319
- puts "CCWM:"
320
- test.ccwm.output
321
- puts "CCWM by OPR - DPR:"
322
- (test.opr - test.dpr).output
323
-
324
- return true
325
- end
19
+ require "opr-calc/matrix.rb"
20
+ require "opr-calc/score_set.rb"
@@ -0,0 +1,75 @@
1
+ =begin
2
+ opr-calc is a tool for calculating OPR and other scouting stats for FRC teams.
3
+ Copyright (C) 2014 Kristofer Rye and Christopher Cooper
4
+
5
+ This program is free software: you can redistribute it and/or modify
6
+ it under the terms of the GNU General Public License as published by
7
+ the Free Software Foundation, either version 3 of the License, or
8
+ (at your option) any later version.
9
+
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU General Public License for more details.
14
+
15
+ You should have received a copy of the GNU General Public License
16
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ =end
18
+
19
+ require "matrix"
20
+
21
+ # Props to http://rosettacode.org/wiki/Cholesky_decomposition#Ruby :L
22
+ class Matrix
23
+ # Returns whether or not the Matrix is symmetric (http://en.wikipedia.org/wiki/Symmetric_matrix).
24
+ def symmetric?
25
+ # Matrices can't be symmetric if they're not square.
26
+ return false unless square?
27
+
28
+ (0...row_size).each do |i|
29
+ (0..i).each do |j|
30
+ return false if self[i,j] != self[j,i]
31
+ end
32
+ end
33
+
34
+ true
35
+ end
36
+
37
+ # Determines the [L] matrix through Cholesky decomposition.
38
+ # To obtain [L]*, just transpose the matrix, it should work.
39
+ def cholesky_factor
40
+ # We need a symmetric matrix for Cholesky decomposition.
41
+ raise ArgumentError, "must provide a symmetric matrix" unless symmetric?
42
+
43
+ # Make a new matrix to return.
44
+ l = Array.new(row_size) { Array.new(row_size, 0) }
45
+
46
+ (0...row_size).each do |k|
47
+ (0...row_size).each do |i|
48
+ if i == k
49
+ sum = (0..k-1).inject(0.0) { |sum, j| sum + l[k][j] ** 2 }
50
+ val = Math.sqrt(self[k,k] - sum)
51
+ l[k][k] = val
52
+ elsif i > k
53
+ sum = (0..k-1).inject(0.0) { |sum, j| sum + l[i][j] * l[k][j] }
54
+ val = (self[k,i] - sum) / l[k][k]
55
+ l[i][k] = val
56
+ end
57
+ end
58
+ end
59
+
60
+ Matrix[*l]
61
+ end
62
+
63
+ # A helpful debug function for Matrices.
64
+ def output
65
+ (0..self.row_size - 1).each do |row_number|
66
+ (0..self.column_size - 1).each do |column_number|
67
+ printf("%8.4f ", self[row_number, column_number])
68
+ end
69
+
70
+ printf("\n")
71
+ end
72
+
73
+ self
74
+ end
75
+ end
@@ -0,0 +1,213 @@
1
+ =begin
2
+ opr-calc is a tool for calculating OPR and other scouting stats for FRC teams.
3
+ Copyright (C) 2014 Kristofer Rye and Christopher Cooper
4
+
5
+ This program is free software: you can redistribute it and/or modify
6
+ it under the terms of the GNU General Public License as published by
7
+ the Free Software Foundation, either version 3 of the License, or
8
+ (at your option) any later version.
9
+
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU General Public License for more details.
14
+
15
+ You should have received a copy of the GNU General Public License
16
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ =end
18
+
19
+ module OPRCalc
20
+ class ScoreSet
21
+ attr_reader :ared, :ablue, :scorered, :scoreblue
22
+
23
+ def ared=(value)
24
+ @ared = value
25
+ @opr_recalc = @dpr_recalc = @ccwm_recalc = true
26
+ end
27
+
28
+ def ablue=(value)
29
+ @ablue = value
30
+ @opr_recalc = @dpr_recalc = @ccwm_recalc = true
31
+ end
32
+
33
+ def scorered=(value)
34
+ @scorered = value
35
+ @opr_recalc = @dpr_recalc = @ccwm_recalc = true
36
+ end
37
+
38
+ def scoreblue=(value)
39
+ @scoreblue = value
40
+ @opr_recalc = @dpr_recalc = @ccwm_recalc = true
41
+ end
42
+
43
+ def initialize(ared, ablue, scorered, scoreblue)
44
+ raise TypeError, "ared must be a Matrix" unless ared.is_a? Matrix
45
+ raise TypeError, "ablue must be a Matrix" unless ablue.is_a? Matrix
46
+ raise TypeError, "scorered must be a Matrix" unless scorered.is_a? Matrix
47
+ raise TypeError, "scoreblue must be a Matrix" unless scoreblue.is_a? Matrix
48
+
49
+ @ared = ared
50
+ @ablue = ablue
51
+ @scorered = scorered
52
+ @scoreblue = scoreblue
53
+ end
54
+
55
+ # A generic function for smooshing two matrices (one red, one blue).
56
+ # Each should have the same dimensions.
57
+ def alliance_smooshey(redmatrix, bluematrix)
58
+ throw ArgumentError "Matrices must have same dimensions" unless (redmatrix.row_size == bluematrix.row_size) && (redmatrix.column_size == bluematrix.column_size)
59
+
60
+ # Then we just pull the column and row size from the red matrix because we can.
61
+ column_count = redmatrix.column_size
62
+ row_count = redmatrix.row_size
63
+
64
+ # Use a block function to generate the new matrix.
65
+ matrix = Matrix.build(row_count * 2, column_count) do
66
+ |row, column|
67
+
68
+ # note: no need to alternate, instead put all red, then all blue.
69
+ if row < row_count # first half = red
70
+ redmatrix[row, column]
71
+ else # second half = blue
72
+ bluematrix[row - row_count, column]
73
+ end
74
+ end
75
+
76
+ # This will end up looking like as follows:
77
+
78
+ # [[red[0]],
79
+ # [red[1]],
80
+ # [red[2]],
81
+ # ...
82
+ # [red[n]],
83
+ # [blue[0]],
84
+ # [blue[1]],
85
+ # [blue[2]],
86
+ # ...
87
+ # [blue[n]]]
88
+ return matrix
89
+ end
90
+
91
+ private :alliance_smooshey
92
+
93
+ # Solve equation of form [l][x] = [s] for [x]
94
+ # l must be a lower triangular matrix.
95
+ # Based off of algorithm given at `http://en.wikipedia.org/wiki/Triangular_matrix#Forward_and_back_substitution`.
96
+ def forward_substitute(l, s)
97
+ raise "l must be a lower triangular matrix" unless l.lower_triangular?
98
+
99
+ x = Array.new s.row_size
100
+
101
+ x.size.times do |i|
102
+ x[i] = s[i, 0]
103
+
104
+ i.times do |j|
105
+ x[i] -= l[i, j] * x[j]
106
+ end
107
+
108
+ x[i] /= l[i, i]
109
+ end
110
+
111
+ Matrix.column_vector x
112
+ end
113
+
114
+ # Solve equation of form [u][x] = [s] for [x]
115
+ # u must be a upper triangular matrix.
116
+ def back_substitute(u, s)
117
+ raise "u must be an upper triangular matrix" unless u.upper_triangular?
118
+
119
+ x = Array.new s.row_size
120
+
121
+ (x.size - 1).downto 0 do |i|
122
+ x[i] = s[i, 0]
123
+
124
+ (i + 1).upto(x.size - 1) do |j|
125
+ x[i] -= u[i, j] * x[j]
126
+ end
127
+
128
+ x[i] /= u[i, i]
129
+ end
130
+
131
+ Matrix.column_vector x
132
+ end
133
+
134
+ private :forward_substitute, :back_substitute
135
+
136
+ # base matrix equation: [A][OPR] = [SCORE]
137
+ # define [A]^t to be [A] transpose
138
+ # define [P] to be [A]^t[A]
139
+ # define [S] to be [A]^t[SCORE]
140
+ # equation is now [P][OPR] = [S]
141
+ # refactor [P] as [L][L]^t using cholesky
142
+ # [L] is a lower triangular matrix and [L]^t an upper
143
+ # Therefore [L][L]^t[OPR] = [S]
144
+ # define [Y] = [L]^t[OPR]
145
+ # equation is now [L][Y] = [S]
146
+ # find [Y] through forward substitution
147
+ # find [OPR] through back substitution
148
+
149
+ def opr_calculate(a, score)
150
+ p = a.t * a
151
+ s = a.t * score
152
+
153
+ l = p.cholesky_factor
154
+
155
+ # l.output
156
+ # l.t.output
157
+
158
+ y = forward_substitute l, s
159
+ back_substitute l.t, y
160
+ end
161
+
162
+ # Offensive power rating: the average amount of points that a team contributes to their alliance's score.
163
+ # This is high for a good team.
164
+ def opr(recalc = false)
165
+ if !@opr || recalc || @opr_recalc
166
+ a = alliance_smooshey @ared, @ablue
167
+ score = alliance_smooshey @scorered, @scoreblue
168
+
169
+ @opr = opr_calculate a, score
170
+ @opr_recalc = false
171
+ end
172
+
173
+ @opr
174
+ end
175
+
176
+ # Defensive power rating: the average amount of points that a team lets the other alliance score.
177
+ # This is low for a good team.
178
+ def dpr(recalc = false)
179
+ if !@dpr || recalc || @dpr_recalc
180
+ a = alliance_smooshey @ared, @ablue
181
+ score = alliance_smooshey @scoreblue, @scorered # intentionally swapped, that's how dpr works.
182
+
183
+ @dpr = opr_calculate a, score
184
+ @dpr_recalc = false
185
+ end
186
+
187
+ @dpr
188
+ end
189
+
190
+ # Calculated contribution to winning margin: the average amount of points that a team contributes to their alliance's winning margin.
191
+ # This is high for a good team.
192
+ def ccwm(recalc = false)
193
+ if !@ccwm || recalc || @ccwm_recalc
194
+ a = alliance_smooshey @ared, @ablue
195
+
196
+ red_wm = Matrix.build(@scorered.row_size, @scorered.column_size) do |row, column|
197
+ @scorered[row, column] - @scoreblue[row, column]
198
+ end
199
+
200
+ blue_wm = Matrix.build(@scoreblue.row_size, @scoreblue.column_size) do |row, column|
201
+ @scoreblue[row, column] - @scorered[row, column]
202
+ end
203
+
204
+ score = alliance_smooshey red_wm, blue_wm
205
+
206
+ @ccwm = opr_calculate a, score
207
+ @ccwm_recalc = false
208
+ end
209
+
210
+ @ccwm
211
+ end
212
+ end
213
+ end
metadata CHANGED
@@ -1,16 +1,45 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opr-calc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kristofer Rye
8
8
  - Christopher Cooper
9
+ - Sam Craig
9
10
  autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
12
13
  date: 2014-01-25 00:00:00.000000000 Z
13
- dependencies: []
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: minitest
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - '>='
27
+ - !ruby/object:Gem::Version
28
+ version: '0'
29
+ - !ruby/object:Gem::Dependency
30
+ name: rake
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - '>='
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ type: :development
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - '>='
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
14
43
  description:
15
44
  email:
16
45
  executables: []
@@ -18,6 +47,8 @@ extensions: []
18
47
  extra_rdoc_files: []
19
48
  files:
20
49
  - lib/opr-calc.rb
50
+ - lib/opr-calc/matrix.rb
51
+ - lib/opr-calc/score_set.rb
21
52
  homepage: https://github.com/team461WBI/opr-calc
22
53
  licenses:
23
54
  - GPL-3.0
@@ -38,7 +69,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
38
69
  version: '0'
39
70
  requirements: []
40
71
  rubyforge_project:
41
- rubygems_version: 2.0.14
72
+ rubygems_version: 2.1.11
42
73
  signing_key:
43
74
  specification_version: 4
44
75
  summary: A tool for calculating OPR and other scouting stats for FRC teams.