wildfalcon-skating-system 0.0.1 → 0.0.2

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.
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: