sciolyff 0.6.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/sciolyff +1 -1
- data/lib/sciolyff/interpreter/placing.rb +11 -0
- data/lib/sciolyff/interpreter/team.rb +10 -10
- data/lib/sciolyff/interpreter/tournament.rb +9 -3
- data/lib/sciolyff/placings.rb +17 -0
- data/lib/sciolyff/tournament.rb +11 -1
- data/lib/sciolyff.rb +0 -162
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 32773284dba3d9f67b630bd64bc1e42c60ca301a49da032c51a055101a8a96c5
|
4
|
+
data.tar.gz: dee4202db369a0d6968ffdd32b98be3a6e42edb49558a8a05855a1ea77c3d653
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: acab98c9051a82ed655f14551e185f4e69cc3f22c08af64ab2361d00759216b812a96f0eb247aa5add92ad3367d705c339dfbb2be67e44b6d4df588901611d69
|
7
|
+
data.tar.gz: ddcb26d4a7ab3a9f668ab1a95923183697857bb44e64942a63314b3336d57fd01c6275a2081e765ae0de66953527a15d5b6bc1637d62db5bfa06898da2a835eb
|
data/bin/sciolyff
CHANGED
@@ -46,6 +46,12 @@ module SciolyFF
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def points
|
49
|
+
return 0 unless considered_for_team_points?
|
50
|
+
|
51
|
+
isolated_points
|
52
|
+
end
|
53
|
+
|
54
|
+
def isolated_points
|
49
55
|
return @cache[:points] if @cache[:points]
|
50
56
|
|
51
57
|
n = event.competing_teams.count
|
@@ -60,6 +66,11 @@ module SciolyFF
|
|
60
66
|
end
|
61
67
|
|
62
68
|
def considered_for_team_points?
|
69
|
+
initially_considered_for_team_points? &&
|
70
|
+
!team.worst_placings_to_be_dropped.include?(self)
|
71
|
+
end
|
72
|
+
|
73
|
+
def initially_considered_for_team_points?
|
63
74
|
!(event.trial? || event.trialed? || exempt?)
|
64
75
|
end
|
65
76
|
|
@@ -61,21 +61,21 @@ module SciolyFF
|
|
61
61
|
def points
|
62
62
|
return @cache[:points] if @cache[:points]
|
63
63
|
|
64
|
-
|
64
|
+
@cache[:points] = placings.sum(&:points) + penalties.sum(&:points)
|
65
|
+
end
|
65
66
|
|
66
|
-
|
67
|
-
|
68
|
-
.sort!(&:points)
|
69
|
-
.reverse!
|
70
|
-
.drop!(@tournament.worst_placings_dropped)
|
71
|
-
end
|
67
|
+
def worst_placings_to_be_dropped
|
68
|
+
return [] if @tournament.worst_placings_dropped.zero?
|
72
69
|
|
73
|
-
|
74
|
-
|
70
|
+
placings
|
71
|
+
.select(&:initially_considered_for_team_points?)
|
72
|
+
.sort(&:points)
|
73
|
+
.reverse
|
74
|
+
.take(@tournament.worst_placings_dropped)
|
75
75
|
end
|
76
76
|
|
77
77
|
def trial_event_points
|
78
|
-
placings.select { |p| p.event.trial? }.sum(&:
|
78
|
+
placings.select { |p| p.event.trial? }.sum(&:isolated_points)
|
79
79
|
end
|
80
80
|
|
81
81
|
def medal_counts
|
@@ -53,13 +53,19 @@ module SciolyFF
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def worst_placings_dropped?
|
56
|
-
@rep
|
56
|
+
@rep.key? :'worst placings dropped'
|
57
57
|
end
|
58
58
|
|
59
59
|
def worst_placings_dropped
|
60
|
-
|
60
|
+
worst_placings_dropped? ? @rep[:'worst placings dropped'] : 0
|
61
|
+
end
|
62
|
+
|
63
|
+
def exempt_placings?
|
64
|
+
@rep.key? :'exempt placings'
|
65
|
+
end
|
61
66
|
|
62
|
-
|
67
|
+
def exempt_placings
|
68
|
+
exempt_placings? ? @rep[:'exempt placings'] : 0
|
63
69
|
end
|
64
70
|
|
65
71
|
def max_points_per_event(trial: false)
|
data/lib/sciolyff/placings.rb
CHANGED
@@ -69,6 +69,23 @@ module SciolyFF
|
|
69
69
|
end
|
70
70
|
end
|
71
71
|
|
72
|
+
def test_each_team_has_correct_number_of_exempt_placings
|
73
|
+
skip unless SciolyFF.rep.instance_of? Hash
|
74
|
+
skip unless SciolyFF.rep[:Tournament].instance_of? Hash
|
75
|
+
|
76
|
+
exempt_placings = SciolyFF.rep[:Tournament][:'exempt placings']
|
77
|
+
exempt_placings = 0 if exempt_placings.nil?
|
78
|
+
skip unless exempt_placings.instance_of? Integer
|
79
|
+
|
80
|
+
@placings.select { |p| p.instance_of?(Hash) && p[:'exempt'] }
|
81
|
+
.group_by { |p| p[:team] }
|
82
|
+
.each do |team_number, placings|
|
83
|
+
assert placings.count == exempt_placings,
|
84
|
+
"Team number #{team_number} has the incorrect number of exempt "\
|
85
|
+
"placings (#{placings.count} instead of #{exempt_placings})"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
72
89
|
def test_each_placing_has_valid_tie
|
73
90
|
@placings.select { |p| p.instance_of? Hash }.each do |placing|
|
74
91
|
next unless placing.key? :tie
|
data/lib/sciolyff/tournament.rb
CHANGED
@@ -23,7 +23,7 @@ module SciolyFF
|
|
23
23
|
|
24
24
|
def test_does_not_have_extra_info
|
25
25
|
info = Set.new %i[name location level division state year date]
|
26
|
-
info << :'short name'
|
26
|
+
info << :'short name' << :'worst placings dropped' << :'exempt placings'
|
27
27
|
assert Set.new(@tournament.keys).subset? info
|
28
28
|
end
|
29
29
|
|
@@ -74,5 +74,15 @@ module SciolyFF
|
|
74
74
|
skip unless @tournament.key? :date
|
75
75
|
assert_instance_of Date, @tournament[:date]
|
76
76
|
end
|
77
|
+
|
78
|
+
def test_has_valid_worst_placings_dropped
|
79
|
+
skip unless @tournament.key? :'worst placings dropped'
|
80
|
+
assert_instance_of Integer, @tournament[:'worst placings dropped']
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_has_valid_exempt_placings
|
84
|
+
skip unless @tournament.key? :'exempt placings'
|
85
|
+
assert_instance_of Integer, @tournament[:'exempt placings']
|
86
|
+
end
|
77
87
|
end
|
78
88
|
end
|
data/lib/sciolyff.rb
CHANGED
@@ -47,166 +47,4 @@ module SciolyFF
|
|
47
47
|
Doesn't give line numbers from original file? Yeah.
|
48
48
|
|
49
49
|
STRING
|
50
|
-
|
51
|
-
# Deprecated: Please use `SciolyFF::Interpreter` instead
|
52
|
-
#
|
53
|
-
# Wrapper class around a SciolyFF Ruby object representation with utility
|
54
|
-
# methods to help in displaying results
|
55
|
-
class Helper
|
56
|
-
attr_reader :rep, :tournament, :events_by_name, :teams_by_number
|
57
|
-
attr_reader :placings_by_event, :placings_by_team, :penalties_by_team
|
58
|
-
|
59
|
-
def initialize(rep)
|
60
|
-
warn 'Class `SciolyFF::Helper` is deprecated. '\
|
61
|
-
'Please use `SciolyFF::Interpreter` instead.'
|
62
|
-
|
63
|
-
@rep = rep
|
64
|
-
@exhibition_teams_count = rep[:Teams].count { |t| t[:exhibition] }
|
65
|
-
@exempt_placings_count = rep[:Placings].count { |p| p[:exempt] }
|
66
|
-
@team_points_cache = {}
|
67
|
-
|
68
|
-
@tournament = rep[:Tournament]
|
69
|
-
@events_by_name = index_array(rep[:Events], [:name])
|
70
|
-
@teams_by_number = index_array(rep[:Teams], [:number])
|
71
|
-
@placings_by_event = index_array(rep[:Placings], %i[event team])
|
72
|
-
@placings_by_team = index_array(rep[:Placings], %i[team event])
|
73
|
-
return unless rep[:Penalties]
|
74
|
-
|
75
|
-
@penalties_by_team = index_array(rep[:Penalties], [:team])
|
76
|
-
end
|
77
|
-
|
78
|
-
def nonexhibition_teams
|
79
|
-
@teams_by_number.reject { |_, t| t[:exhibition] }
|
80
|
-
end
|
81
|
-
|
82
|
-
def event_points(team_number, event_name)
|
83
|
-
placing = @placings_by_event[event_name][team_number]
|
84
|
-
number_of_teams = number_of_competing_teams(event_name)
|
85
|
-
|
86
|
-
if placing[:disqualified] then number_of_teams + 2
|
87
|
-
elsif placing[:participated] == false then number_of_teams + 1
|
88
|
-
elsif placing[:unknown] then number_of_teams - 1
|
89
|
-
elsif placing[:place].nil? then number_of_teams
|
90
|
-
else calculate_event_points(placing)
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
def team_points(team_number)
|
95
|
-
return @team_points_cache[team_number] if @team_points_cache[team_number]
|
96
|
-
|
97
|
-
@team_points_cache[team_number] = calculate_team_points(team_number)
|
98
|
-
end
|
99
|
-
|
100
|
-
def team_points_from_penalties(team_number)
|
101
|
-
if @penalties_by_team.nil? || @penalties_by_team[team_number].nil? then 0
|
102
|
-
else @penalties_by_team[team_number][:points]
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
def sort_teams_by_rank
|
107
|
-
@teams_by_number
|
108
|
-
.values
|
109
|
-
.sort do |a, b|
|
110
|
-
next 1 if a[:exhibition] && !b[:exhibition]
|
111
|
-
next -1 if !a[:exhibition] && b[:exhibition]
|
112
|
-
|
113
|
-
cmp = team_points(a[:number]) - team_points(b[:number])
|
114
|
-
cmp.zero? ? break_tie(a[:number], b[:number]) : cmp
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
def medal_counts(team_number)
|
119
|
-
(1..(nonexhibition_teams.count + 2)).map do |m|
|
120
|
-
@events_by_name
|
121
|
-
.values
|
122
|
-
.reject { |e| e[:trial] || e[:trialed] }
|
123
|
-
.count { |e| event_points(team_number, e[:name]) == m }
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
private
|
128
|
-
|
129
|
-
def index_array(arr, index_keys)
|
130
|
-
return arr.first if index_keys.empty?
|
131
|
-
|
132
|
-
indexed_hash = arr.group_by { |x| x[index_keys.first] }
|
133
|
-
|
134
|
-
indexed_hash.transform_values do |a|
|
135
|
-
index_array(a, index_keys.drop(1))
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
def number_of_competing_teams(event_name)
|
140
|
-
return @teams_by_number.count if @events_by_name[event_name][:trial]
|
141
|
-
|
142
|
-
nonexhibition_teams.count
|
143
|
-
end
|
144
|
-
|
145
|
-
def calculate_event_points(placing)
|
146
|
-
return placing[:place] if simple_placing?(placing)
|
147
|
-
|
148
|
-
# Points is place minus number of exhibition and exempt teams with a
|
149
|
-
# better place
|
150
|
-
placing[:place] -
|
151
|
-
@placings_by_event[placing[:event]]
|
152
|
-
.values
|
153
|
-
.select { |p| p[:place] && exhibition_or_exempt_placing?(p) }
|
154
|
-
.count { |p| p[:place] < placing[:place] }
|
155
|
-
end
|
156
|
-
|
157
|
-
def calculate_team_points(team_number)
|
158
|
-
@placings_by_team[team_number]
|
159
|
-
.values
|
160
|
-
.reject { |p| @events_by_name[p[:event]][:trial] }
|
161
|
-
.reject { |p| @events_by_name[p[:event]][:trialed] }
|
162
|
-
.reject { |p| p[:exempt] }
|
163
|
-
.sum { |p| event_points(team_number, p[:event]) } \
|
164
|
-
+ team_points_from_penalties(team_number)
|
165
|
-
end
|
166
|
-
|
167
|
-
def simple_placing?(placing)
|
168
|
-
@events_by_name[placing[:event]][:trial] ||
|
169
|
-
(@exhibition_teams_count.zero? && @exempt_placings_count.zero?)
|
170
|
-
end
|
171
|
-
|
172
|
-
def exhibition_or_exempt_placing?(placing)
|
173
|
-
@teams_by_number[placing[:team]][:exhibition] || placing[:exempt]
|
174
|
-
end
|
175
|
-
|
176
|
-
def break_tie(team_number_a, team_number_b)
|
177
|
-
medal_counts(team_number_a)
|
178
|
-
.zip(medal_counts(team_number_b))
|
179
|
-
.map { |count| count.last - count.first }
|
180
|
-
.find(proc { break_second_tie(team_number_a, team_number_b) },
|
181
|
-
&:nonzero?)
|
182
|
-
end
|
183
|
-
|
184
|
-
def break_second_tie(team_number_a, team_number_b)
|
185
|
-
cmp = points_from_trial(team_number_a) - points_from_trial(team_number_b)
|
186
|
-
cmp.zero? ? break_third_tie(team_number_a, team_number_b) : cmp
|
187
|
-
end
|
188
|
-
|
189
|
-
def break_third_tie(team_number_a, team_number_b)
|
190
|
-
medal_counts_from_trial(team_number_a)
|
191
|
-
.zip(medal_counts_from_trial(team_number_b))
|
192
|
-
.map { |count| count.last - count.first }
|
193
|
-
.find(proc { team_number_a <=> team_number_b }, &:nonzero?)
|
194
|
-
end
|
195
|
-
|
196
|
-
def points_from_trial(team_number)
|
197
|
-
@placings_by_team[team_number]
|
198
|
-
.values
|
199
|
-
.select { |p| @events_by_name[p[:event]][:trial] }
|
200
|
-
.sum { |p| event_points(team_number, p[:event]) }
|
201
|
-
end
|
202
|
-
|
203
|
-
def medal_counts_from_trial(team_number)
|
204
|
-
(1..(@teams_by_number.count + 2)).map do |m|
|
205
|
-
@events_by_name
|
206
|
-
.values
|
207
|
-
.select { |e| e[:trial] }
|
208
|
-
.count { |e| event_points(team_number, e[:name]) == m }
|
209
|
-
end
|
210
|
-
end
|
211
|
-
end
|
212
50
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sciolyff
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Em Zhan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-10-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|