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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 64f19b6f05fc3a19ae643aa8c783561f094ddd93959021b77eda3ad437ec9f6d
4
- data.tar.gz: e0359c5b02d570f75d068ae5d4b0dd2965d0bece8acfa7451b6cc29acfe19cb7
3
+ metadata.gz: 32773284dba3d9f67b630bd64bc1e42c60ca301a49da032c51a055101a8a96c5
4
+ data.tar.gz: dee4202db369a0d6968ffdd32b98be3a6e42edb49558a8a05855a1ea77c3d653
5
5
  SHA512:
6
- metadata.gz: dfacd78064019cebf1be0d4cf7351965eb6dd134d2457a1f00d8ed26babb535c94d292d90b9cb6f21f04350faa8b9d96745bdb61d05b8c00806e8a4fbde57df6
7
- data.tar.gz: 51e0a6fd2deaa74b1f0692e7a39a4d2712bef21f3a4f92b322d205219ac58d2dd0102ba438c2a6b085850d2d23885ee1d95386f67c81c5c66d355b4c7bef2db0
6
+ metadata.gz: acab98c9051a82ed655f14551e185f4e69cc3f22c08af64ab2361d00759216b812a96f0eb247aa5add92ad3367d705c339dfbb2be67e44b6d4df588901611d69
7
+ data.tar.gz: ddcb26d4a7ab3a9f668ab1a95923183697857bb44e64942a63314b3336d57fd01c6275a2081e765ae0de66953527a15d5b6bc1637d62db5bfa06898da2a835eb
data/bin/sciolyff CHANGED
@@ -6,7 +6,7 @@ require 'yaml'
6
6
  require 'sciolyff'
7
7
 
8
8
  opts = Optimist.options do
9
- version 'sciolyff 0.6.0'
9
+ version 'sciolyff 0.7.0'
10
10
  banner <<~STRING
11
11
  Checks if a given file is in the Scioly File Format
12
12
 
@@ -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
- counted_placings = placings.select(&:considered_for_team_points?)
64
+ @cache[:points] = placings.sum(&:points) + penalties.sum(&:points)
65
+ end
65
66
 
66
- if @tournament.worst_placings_dropped?
67
- counted_placings
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
- @cache[:points] =
74
- counted_placings.sum(&:points) + penalties.sum(&:points)
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(&:points)
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[:'worst placings dropped'].instance_of? Integer
56
+ @rep.key? :'worst placings dropped'
57
57
  end
58
58
 
59
59
  def worst_placings_dropped
60
- return 0 unless @rep[:'worst placings dropped']
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
- @rep[:'worst placings dropped']
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)
@@ -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
@@ -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.6.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-08-26 00:00:00.000000000 Z
11
+ date: 2019-10-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest