wildfalcon-skating-system 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -3,5 +3,182 @@ Skating System
3
3
 
4
4
  Provides an implementation of the skating system used for scoring dance comeptitions, as well as a few other types of competition.
5
5
 
6
+ The skating system is as follows:
7
+
8
+
9
+ ********* The Marking of Adjudicators' Cards
10
+ 1.
11
+ In all rounds each judge must vote for the number of couples
12
+ demanded by the Chairman of Adjudicators.
13
+
14
+ 2.
15
+ In the Final round each judge shall place all the competing
16
+ couples in order of merit in each of the dances.
17
+
18
+ 3.
19
+ In the Final round the judge shall mark his first couple 1, his
20
+ second couple 2, his third 3, and so on in each of the dances.
21
+
22
+ 4.
23
+ A judge must not tie couples for any place in the Final of any dance.
24
+
25
+ Note:
26
+
27
+ Number of Couples to Dance in a Final
28
+
29
+ 1.
30
+ In the Final round the open system of marking shall be used.
31
+
32
+ 2.
33
+ When judges are instructed to select six couples for a
34
+ Final and six couples are clearly chosen only that number
35
+ shall dance. The same procedure would be observed if the
36
+ Chairman's instructions were for any other number.
37
+
38
+ 3.
39
+ If it is intended that six couples shall dance in a Final
40
+ and through a tie more couples qualify for consideration
41
+ the number to dance shall be decided by the Chairman. The
42
+ same procedure would be observed if it is intended to have
43
+ a Final of any other number.
44
+
45
+ ********* The Allocation of Positions in Each Dance
46
+ 5.
47
+ The winner of a particular dance is the couple who is placed
48
+ first by an absolute majority of judges; second, the couple who
49
+ is placed second or higher by an absolute majority. The
50
+ remaining positions are allocated in a similar way.
51
+
52
+ If More that One Couple have a Majority for the Same Position
53
+
54
+ 6.
55
+ The couple with the largest majority shall be allocated the
56
+ position under review, and the couple with the next largest
57
+ majority, the following position.
58
+
59
+ Note:
60
+
61
+ If the position under review is the "2nd" and two couples have a
62
+ majority of "2nd and higher" places, the couple with the larger
63
+ majority shall be placed "2nd" and the other couple "3rd".
64
+
65
+ We now examine the remaining competitors' markings, and the
66
+ couple with the largest majority of "3rd and higher" places
67
+ shall be allocated the next position, which in this example, is
68
+ the "4th".
69
+
70
+ If none of the remaining couples has a majority of "3rd and
71
+ higher" places, then include the "4th" places (and, if
72
+ necessary, lower places).
73
+
74
+ ********* If Two or More Couples have an Equal Majority for the Same Position
75
+ 7.
76
+ a) If such majorities are equal, then the lowest total of marks
77
+ given by those judges who form the majority, shall determine the
78
+ allocation of the position under review.
79
+
80
+ Note:
81
+
82
+ If the position under review is the "2nd" and two couples have a
83
+ similar majority of "2nd and higher" places, the couple with the
84
+ lower total of marks given by those judges who form the
85
+ majority, shall be allocated the "2nd" position and the other
86
+ couple the "3rd".
87
+
88
+ b) If the totals of the marks are equal, then the next lower
89
+ place (or places, if necessary), in respect of the particular
90
+ couples concerned, must be included.
91
+
92
+ Note:
93
+
94
+ It should be noted that only the couples who have a majority for
95
+ the position under review (say, for example, the "2nd" position)
96
+ must be considered at this stage, and only their "3rd" places
97
+ (and, if necessary, lower places) should be referred to, until
98
+ the "2nd" position has been allocated.
99
+
100
+ A definite result will eventually be obtained unless the
101
+ remaining markings are exactly the same, and should the latter
102
+ be the case, there will, of course, be a tie for "2nd"
103
+ position. If two couples were concerned, they would be allocated
104
+ "2 1/2" each.
105
+
106
+
107
+ ********* If No Couple receives a Majority for the Position Under Review
108
+ 8.
109
+ If no couple receives a majority of "Firsts" then the winner is
110
+ the couple who are placed "2nd and higher" by a majority of
111
+ judges.
112
+
113
+ If no couple receives a majority of "1st" and "2nd" places, then
114
+ the "3rd" places (and if necessary, lower places) must be
115
+ included. (Subject to Rules 6 and 7).
116
+
117
+ The "2nd" and other places should be calculated in a similar
118
+ way.
119
+
120
+ ********* Compilation of the Final Summary
121
+ 9.
122
+ When all the dances have been concluded, the order ascertained
123
+ for each dance shall be carried to another sheet, showing the
124
+ position achieved by each couple in each dance. The first in
125
+ each dance shall be given one mark, the second two, and so
126
+ on. These place marks shall be added up and the couple with the
127
+ lowest aggregate shall be the winner.
128
+
129
+
130
+ ********* If there is a Tie for a Place in the Final Summary
131
+ 10.
132
+ a) If this results in a tie for first place, the winner shall be
133
+ the couple who has actually won the greater number of dances.
134
+
135
+ b) If there is a tie for the "2nd" place, the "2nd" prize shall
136
+ be awarded to the couple who has obtained "2nd and higher" in
137
+ the greatest number of dances. If the couples have obtained the
138
+ same number of "2nd and higher" place marks, then add the "2nd
139
+ and higher" place marks together and the couple with the lowest
140
+ total should be awarded second prize.
141
+
142
+ Note:
143
+
144
+ If more than two couples tie for second place, the second prize
145
+ shall be awarded to the couple who has obtained the most "2nd
146
+ and higher" place marks. Still only considering the remaining
147
+ "tied" couples, the "3rd" prize is awarded to the couple who has
148
+ won the most "3rd and higher" place marks.
149
+
150
+ c) If there is a tie for any remaining places they shall be
151
+ decided on similar principles.
152
+
153
+ 11.
154
+
155
+ If after applying Rules 9 and 10 this still results in a tie,
156
+ then treat the judges' marks of the "tied" couples over all
157
+ dances, as for an individual dance (Rules 5 to 8). If this still
158
+ results in a tie, there shall be at the discretion of the
159
+ organizers of the competition, either a re-dance or the prizes
160
+ for the places under review shall be divided.
161
+
162
+ a) If the tie is for first place, a majority of "1st" marks to
163
+ the credit of either of the "tied" couples (4 dances-5
164
+ judges-majority 11) would win. If neither of the "tied" couples
165
+ receive a majority of "firsts" see Rule 8.
166
+
167
+ b) If the tie is for second place, a majority of "2nd and
168
+ higher" marks to the credit of either of the "tied" couples
169
+ would be necessary. If neither of the "tied" couples obtain a
170
+ majority of "2nd and higher" marks see Rule 8.
171
+
172
+ c) The "3rd" or any other "tied" places should be decided on similar principles.
173
+
174
+ d) If 3 (or more) couples tie for a place under Rule 10 (say,
175
+ 2nd place) Rule 11 is applied to all couples concerned in the
176
+ tie, and the best couple is awarded the "2nd" place. Rule 10 is
177
+ now applied to the remaining "tied" couples for consideration of
178
+ the place now under review, which is the "3rd". However, if they
179
+ now tie for "3rd" under Rule 10, then Rule 11 is again applied
180
+ to these "tied" couples, commencing this time with the "3rd and
181
+ higher" judges's marks in the individual dances.
182
+
6
183
  It is distributed under the MIT Licence, see licence.txt for the details
7
184
 
@@ -1,4 +1,5 @@
1
1
  require 'skating_system/performance_results'
2
+ require 'skating_system/ranking'
2
3
  require 'skating_system/scorer'
3
4
 
4
5
  module SkatingSystem
@@ -15,10 +15,26 @@ module SkatingSystem
15
15
  end
16
16
  end
17
17
 
18
+ def ranking
19
+ return @ranking if @ranking
20
+ @ranking =SkatingSystem::Ranking.new
21
+ @marks.each do |entree, data|
22
+ @ranking.add(data[:result], entree)
23
+ end
24
+ @ranking
25
+ end
26
+
27
+ def [](key)
28
+ @marks[key]
29
+ end
30
+
31
+
32
+
33
+ private
18
34
  def sum_marks(entree, position)
19
35
  sum=0
20
36
  @marks[entree].each do |judge, place|
21
- sum += place if place <= position
37
+ sum += place if place <= position
22
38
  end
23
39
  sum
24
40
  end
@@ -37,7 +53,7 @@ module SkatingSystem
37
53
  sorted_candidate = candidates(place).sort do |entree1, entree2|
38
54
  comparator = @tally[entree2][place] <=> @tally[entree1][place]
39
55
  if comparator==0
40
- comparator = sum_marks(entree2, place) <=> sum_marks(entree1, place)
56
+ comparator = sum_marks(entree1, place) <=> sum_marks(entree2, place)
41
57
  end
42
58
  comparator
43
59
  end
@@ -59,12 +75,7 @@ module SkatingSystem
59
75
  end
60
76
  candidates
61
77
  end
62
-
63
- def [](key)
64
- @marks[key]
65
- end
66
-
67
- private
78
+
68
79
  #Tallys the number of judges who marked each entree in each place or heigher
69
80
  # and writes the results to @tally
70
81
  # eg given the results
@@ -0,0 +1,34 @@
1
+ module SkatingSystem
2
+ class Ranking
3
+ attr_accessor :rank_table
4
+
5
+ def initialize
6
+ @rank_table={ }
7
+ end
8
+
9
+ #Ads a new result to this ranking
10
+ def add(place, competitor)
11
+ raise "too many couples in higher placings" if places_higher_than(place) >= place
12
+
13
+ competitors = @rank_table[place] || []
14
+ competitors << competitor
15
+ @rank_table[place] = competitors
16
+ end
17
+
18
+ def place_for(competitor)
19
+ rank_table.each do |key, value|
20
+ return key if value.include?(competitor)
21
+ end
22
+ raise "Unkown competitor"
23
+ end
24
+
25
+ def places_higher_than(place)
26
+ higher_placings = 0
27
+ 1.upto(place-1) do |p|
28
+ higher_placings += @rank_table[p] ? @rank_table[p].size : 0
29
+ end
30
+ return higher_placings
31
+ end
32
+
33
+ end
34
+ end
@@ -58,156 +58,50 @@ describe SkatingSystem::PerformanceResults, "tallying the marks" do
58
58
  it "should know how many 3rd or better places entree3 got" do
59
59
  @performance_resuts[@entree3][3].should be(3)
60
60
  end
61
-
62
61
  end
63
- #
64
- #
65
- #describe "scoring a final that can be decided on just rule 5" do
66
- # before(:all) do
67
- # @performance_resuts = PerformanceResults.new
68
- #
69
- # @judge1 = mock_model(Judge)
70
- # @judge2 = mock_model(Judge)
71
- # @judge3 = mock_model(Judge)
72
- #
73
- # @entree1 = mock_model(Entree)
74
- # @entree2 = mock_model(Entree)
75
- # @entree3 = mock_model(Entree)
76
- #
77
- # # A B C 1 2 3
78
- # # 1 1 1 3 2 2 3 1
79
- # # 2 2 3 2 0 2 3 2
80
- # # 3 3 2 3 0 1 3 3
81
- # @couples_marks = { @entree1=>{@judge1=>1, @judge2=>1, @judge3=>3 },
82
- # @entree2=>{@judge1=>2, @judge2=>3, @judge3=>2 },
83
- # @entree3=>{@judge1=>3, @judge2=>2, @judge3=>3 }}
84
- #
85
- # @performance_resuts.score(@couples_marks)
86
- # end
87
- #
88
- # it "should list entree 1 as first place" do
89
- # @performance_resuts[@entree1][:result].should be(1)
90
- # end
91
- #
92
- # it "should list entree 2 as second place" do
93
- # @performance_resuts[@entree2][:result].should be(2)
94
- # end
95
- #
96
- # it "should list entree 3 as third place" do
97
- # @performance_resuts[@entree3][:result].should be(3)
98
- # end
99
- #end
100
- #
101
- #
102
- #describe "scoring a final that requires rule 6" do
103
- #
104
- # before(:all) do
105
- # @performance_resuts = PerformanceResults.new
106
- #
107
- # @judgea = mock_model(Judge)
108
- # @judgeb = mock_model(Judge)
109
- # @judgec = mock_model(Judge)
110
- # @judged = mock_model(Judge)
111
- # @judgee = mock_model(Judge)
112
- #
113
- # @entree1 = mock_model(Entree, :number=>1)
114
- # @entree2 = mock_model(Entree, :number=>2)
115
- # @entree3 = mock_model(Entree, :number=>3)
116
- # @entree4 = mock_model(Entree, :number=>4)
117
- # @entree5 = mock_model(Entree, :number=>5)
118
- #
119
- # # A B C D E 1 2 3 4 5
120
- # # 1 1 1 1 5 5 3 1
121
- # # 2 4 2 4 1 2 1 3 3
122
- # # 3 2 4 2 2 1 1 4 2
123
- # # 4 3 5 3 4 4 2 5
124
- # # 5 5 3 5 3 3 3 4
125
- #
126
- # @couples_marks = {
127
- # @entree1=>{@judgea=>1, @judgeb=>1, @judgec=>1, @judged=>5, @judgee=>5 },
128
- # @entree2=>{@judgea=>4, @judgeb=>2, @judgec=>4, @judged=>1, @judgee=>2 },
129
- # @entree3=>{@judgea=>2, @judgeb=>4, @judgec=>2, @judged=>2, @judgee=>1 },
130
- # @entree4=>{@judgea=>3, @judgeb=>5, @judgec=>3, @judged=>4, @judgee=>4 },
131
- # @entree5=>{@judgea=>5, @judgeb=>3, @judgec=>5, @judged=>3, @judgee=>3 }
132
- # }
133
- #
134
- # @performance_resuts.score(@couples_marks)
135
- # end
136
- #
137
- # it "should list entree 1 as first place" do
138
- # @performance_resuts[@entree1][:result].should be(1)
139
- # end
140
- #
141
- # it "should list entree 2 as third place" do
142
- # @performance_resuts[@entree2][:result].should be(3)
143
- # end
144
- #
145
- # it "should list entree 3 as second place" do
146
- # @performance_resuts[@entree3][:result].should be(2)
147
- # end
148
- #
149
- # it "should list entree 4 as fifth place" do
150
- # @performance_resuts[@entree4][:result].should be(5)
151
- # end
152
- #
153
- # it "should list entree 5 as forth place" do
154
- # @performance_resuts[@entree5][:result].should be(4)
155
- # end
156
- #end
157
- #
158
- #
159
- #describe "scoring a final that requires rule 7" do
160
- #
161
- # before(:all) do
162
- # @performance_resuts = PerformanceResults.new
163
- #
164
- # @judgea = mock_model(Judge)
165
- # @judgeb = mock_model(Judge)
166
- # @judgec = mock_model(Judge)
167
- # @judged = mock_model(Judge)
168
- # @judgee = mock_model(Judge)
169
- #
170
- # @entree1 = mock_model(Entree, :number=>1)
171
- # @entree2 = mock_model(Entree, :number=>2)
172
- # @entree3 = mock_model(Entree, :number=>3)
173
- # @entree4 = mock_model(Entree, :number=>4)
174
- # @entree5 = mock_model(Entree, :number=>5)
175
- #
176
- # # A B C D E 1 2 3 4 5
177
- # # 1 1 1 1 5 5 3 1
178
- # # 2 2 4 3 2 2 3 3
179
- # # 3 4 2 4 1 1 2 3 2
180
- # # 4 3 5 2 4 4 1 2 5
181
- # # 5 5 3 5 3 3 3 4
182
- #
183
- # @couples_marks = {
184
- # @entree1=>{@judgea=>1, @judgeb=>1, @judgec=>1, @judged=>5, @judgee=>5 },
185
- # @entree3=>{@judgea=>2, @judgeb=>3, @judgec=>4, @judged=>2, @judgee=>2 },
186
- # @entree2=>{@judgea=>4, @judgeb=>2, @judgec=>4, @judged=>1, @judgee=>1 },
187
- # @entree4=>{@judgea=>3, @judgeb=>5, @judgec=>2, @judged=>4, @judgee=>4 },
188
- # @entree5=>{@judgea=>5, @judgeb=>3, @judgec=>5, @judged=>3, @judgee=>3 }
189
- # }
190
- #
191
- # @performance_resuts.score(@couples_marks)
192
- # end
193
- #
194
- # it "should list entree 1 as first place" do
195
- # @performance_resuts[@entree1][:result].should be(1)
196
- # end
197
- #
198
- # it "should list entree 2 as third place" do
199
- # @performance_resuts[@entree2][:result].should be(3)
200
- # end
201
- #
202
- # it "should list entree 3 as second place" do
203
- # @performance_resuts[@entree3][:result].should be(2)
204
- # end
205
- #
206
- # it "should list entree 4 as fifth place" do
207
- # @performance_resuts[@entree4][:result].should be(5)
208
- # end
209
- #
210
- # it "should list entree 5 as forth place" do
211
- # @performance_resuts[@entree5][:result].should be(4)
212
- # end
213
- #end
62
+
63
+ describe SkatingSystem::PerformanceResults, "getting the rankings" do
64
+ before(:each) do
65
+ @performance_resuts = SkatingSystem::PerformanceResults.new
66
+
67
+ @judge1 = mock("Judge")
68
+ @judge2 = mock("Judge")
69
+ @judge3 = mock("Judge")
70
+
71
+ @entree1 = mock("Entree")
72
+ @entree2 = mock("Entree")
73
+ @entree3 = mock("Entree")
74
+
75
+ # A B C 1 2 3
76
+ # 1 1 1 3 2 2 3 1
77
+ # 2 2 3 2 0 2 3 2
78
+ # 3 3 2 3 0 1 3 3
79
+ @couples_marks = { @entree1=>{@judge1=>1, @judge2=>1, @judge3=>3 },
80
+ @entree2=>{@judge1=>2, @judge2=>3, @judge3=>2 },
81
+ @entree3=>{@judge1=>3, @judge2=>2, @judge3=>3 }}
82
+
83
+ SkatingSystem::Ranking.stub!(:new).and_return(@ranking = mock(SkatingSystem::Ranking))
84
+ @ranking.stub!(:add)
85
+
86
+ @performance_resuts.score(@couples_marks)
87
+ end
88
+
89
+ it "should return a Ranking when asked for one" do
90
+ @performance_resuts.ranking.should be(@ranking)
91
+ end
92
+
93
+ it "should add couple 1 to the ranking in first place" do
94
+ @ranking.should_receive(:add).with(1, @entree1)
95
+ @performance_resuts.ranking
96
+ end
97
+
98
+ it "should add couple 2 to the ranking in second place" do
99
+ @ranking.should_receive(:add).with(2, @entree2)
100
+ @performance_resuts.ranking
101
+ end
102
+
103
+ it "should add couple 3 to the ranking in third place" do
104
+ @ranking.should_receive(:add).with(3, @entree3)
105
+ @performance_resuts.ranking
106
+ end
107
+ end
@@ -0,0 +1,61 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe SkatingSystem::Ranking do
4
+ before(:each) do
5
+ @ranking = SkatingSyatem::Ranking.new
6
+ end
7
+ end
8
+
9
+
10
+ describe SkatingSystem::Ranking, "adding new results" do
11
+
12
+ before(:each) do
13
+ @ranking = SkatingSystem::Ranking.new
14
+ end
15
+
16
+ it "should put an entry in first place when they are entered in first place" do
17
+ entree = mock("Entree")
18
+ @ranking.add(1, entree)
19
+ @ranking.place_for(entree).should be(1)
20
+ end
21
+
22
+ it "should put both entries in first place when entered in first place, even if there is already a first place" do
23
+ entree1 = mock("Entree")
24
+ entree2 = mock("Entree")
25
+ @ranking.add(1, entree1)
26
+ @ranking.add(1, entree2)
27
+ @ranking.place_for(entree1).should be(1)
28
+ @ranking.place_for(entree2).should be(1)
29
+ end
30
+
31
+ it "should put an entry in second place when entred in second place" do
32
+ entree = mock("Entree")
33
+ @ranking.add(2, entree)
34
+ @ranking.place_for(entree).should be(2)
35
+ end
36
+
37
+ it "should put both in second place when netered in second place, even if there is already a second place" do
38
+ entree1 = mock("Entree")
39
+ entree2 = mock("Entree")
40
+ @ranking.add(2, entree1)
41
+ @ranking.add(2, entree2)
42
+ @ranking.place_for(entree1).should be(2)
43
+ @ranking.place_for(entree2).should be(2)
44
+ end
45
+
46
+ it "should not allow an entry in second place if there are two first places" do
47
+ entree1 = mock("Entree")
48
+ entree2 = mock("Entree")
49
+ entree3 = mock("Entree")
50
+ @ranking.add(1, entree1)
51
+ @ranking.add(1, entree2)
52
+ lambda{ @ranking.add(2, entree3)}.should raise_error
53
+ end
54
+
55
+ it "should reise an exception if asked about an unknown entree" do
56
+ lambda{ @ranking.place_for(mock("Entree"))}.should raise_error
57
+ end
58
+
59
+
60
+
61
+ end
@@ -2,7 +2,9 @@ dir = File.dirname(__FILE__)
2
2
  lib_path = File.expand_path("#{dir}/../lib")
3
3
  $LOAD_PATH.unshift lib_path unless $LOAD_PATH.include?(lib_path)
4
4
 
5
+ require 'rubygems'
5
6
  require 'skating_system'
7
+ require 'ruby-debug'
6
8
 
7
9
  Spec::Runner.configure do |config|
8
10
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wildfalcon-skating-system
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Laurie Young
@@ -25,10 +25,12 @@ files:
25
25
  - lib/skating_system.rb
26
26
  - lib/skating_system/scorer.rb
27
27
  - lib/skating_system/performance_results.rb
28
+ - lib/skating_system/ranking.rb
28
29
  - spec/spec.opts
29
30
  - spec/spec_helper.rb
30
31
  - spec/spec/scorer_spec.rb
31
32
  - spec/spec/performance_results_spec.rb
33
+ - spec/spec/ranking_spec.rb
32
34
  - README
33
35
  has_rdoc: true
34
36
  homepage: