sciolyff 0.10.0 → 0.11.0

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.
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'sciolyff/validator/checker'
4
4
  require 'sciolyff/validator/sections'
5
+ require 'sciolyff/validator/canonical'
5
6
 
6
7
  module SciolyFF
7
8
  # Checks for one team in the Teams section of a SciolyFF file
@@ -25,6 +26,7 @@ module SciolyFF
25
26
 
26
27
  def initialize(rep)
27
28
  initialize_teams_info(rep[:Teams])
29
+ @subdivisions = rep[:Subdivisions]&.map { |s| s[:name] } || []
28
30
  @placings = rep[:Placings].group_by { |p| p[:team] }
29
31
  @exempt = rep[:Tournament][:'exempt placings'] || 0
30
32
  end
@@ -45,6 +47,14 @@ module SciolyFF
45
47
  'as another team from the same school'
46
48
  end
47
49
 
50
+ def suffix_needed?(team, logger)
51
+ rep = [team[:school], team[:city], team[:state]]
52
+ return true unless team[:suffix] && @schools[rep].count == 1
53
+
54
+ logger.warn "team number #{team[:number]} may have unnecessary "\
55
+ "suffix: #{team[:suffix]}"
56
+ end
57
+
48
58
  def unambiguous_cities_per_school?(team, logger)
49
59
  return true unless @schools.keys.find do |other|
50
60
  team[:city].nil? && !other[1].nil? &&
@@ -64,18 +74,35 @@ module SciolyFF
64
74
  "exempt placings (#{count} insteand of #{@exempt})"
65
75
  end
66
76
 
77
+ def matching_subdivision?(team, logger)
78
+ sub = team[:subdivision]
79
+ return true if sub.nil? || @subdivisions.include?(sub)
80
+
81
+ logger.error "'subdivision: #{sub}' does not match any name in "\
82
+ 'section Subdivisions'
83
+ end
84
+
67
85
  def in_a_subdivision_if_possible?(team, logger)
68
- return true unless @subdivisions && !team[:subdivision]
86
+ return true unless !@subdivisions.empty? && !team[:subdivision]
69
87
 
70
88
  logger.warn "missing subdivision for 'team: #{team[:number]}'"
71
89
  end
72
90
 
91
+ include Validator::Canonical
92
+
93
+ def in_canonical_list?(team, logger)
94
+ rep = [team[:school], team[:city], team[:state]]
95
+ return true if canonical?(rep, 'schools.csv', logger)
96
+
97
+ location = rep[1..-1].compact.join ', '
98
+ logger.warn "non-canonical school: #{team[:school]} in #{location}"
99
+ end
100
+
73
101
  private
74
102
 
75
103
  def initialize_teams_info(teams)
76
104
  @numbers = teams.map { |t| t[:number] }
77
105
  @schools = teams.group_by { |t| [t[:school], t[:city], t[:state]] }
78
- @subdivisions = teams.find { |t| t[:subdivision] }
79
106
  end
80
107
  end
81
108
  end
@@ -16,6 +16,7 @@ module SciolyFF
16
16
  }.freeze
17
17
 
18
18
  OPTIONAL = {
19
+ Subdivisions: Array,
19
20
  Penalties: Array
20
21
  }.freeze
21
22
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'sciolyff/validator/checker'
4
4
  require 'sciolyff/validator/sections'
5
+ require 'sciolyff/validator/range'
5
6
 
6
7
  module SciolyFF
7
8
  # Checks for Tournament section of a SciolyFF file
@@ -19,6 +20,10 @@ module SciolyFF
19
20
  OPTIONAL = {
20
21
  name: String,
21
22
  state: String,
23
+ medals: Integer,
24
+ trophies: Integer,
25
+ bids: Integer,
26
+ 'bids per school': Integer,
22
27
  'short name': String,
23
28
  'worst placings dropped': Integer,
24
29
  'exempt placings': Integer,
@@ -29,6 +34,9 @@ module SciolyFF
29
34
 
30
35
  def initialize(rep)
31
36
  @maximum_place = rep[:Teams].count { |t| !t[:exhibition] }
37
+ @schools_count = rep[:Teams].uniq do |t|
38
+ [t[:school], t[:city], t[:state]]
39
+ end.count
32
40
  end
33
41
 
34
42
  def name_for_not_states_or_nationals?(tournament, logger)
@@ -46,6 +54,34 @@ module SciolyFF
46
54
  "('level: #{tournament[:level]}' is not Nationals)"
47
55
  end
48
56
 
57
+ def bids_for_regionals_or_states?(tournament, logger)
58
+ level = tournament[:level]
59
+
60
+ if %w[Regionals States].include?(level)
61
+ return true if tournament.key? :bids
62
+
63
+ logger.error "field 'bids:' required for level: #{level}"
64
+ else
65
+ return true unless tournament.key? :bids
66
+
67
+ logger.error "bids: does not make sense for level: #{level}"
68
+ end
69
+ end
70
+
71
+ def bids_per_school_positive?(tournament, logger)
72
+ bids = tournament[:'bids per school']
73
+ return true if bids.nil? || tournament[:'bids per school'].positive?
74
+
75
+ logger.error "'bids per school: #{bids}' is not positive"
76
+ end
77
+
78
+ def bids_per_school_relevant?(tournament, logger)
79
+ return true unless tournament[:'bids per school'] &&
80
+ !tournament.key?(:bids)
81
+
82
+ logger.error "field 'bids per school:' not relevant without field 'bids:'"
83
+ end
84
+
49
85
  def short_name_is_relevant?(tournament, logger)
50
86
  return true unless tournament[:'short name'] && !tournament[:name]
51
87
 
@@ -61,12 +97,23 @@ module SciolyFF
61
97
  "is longer than normal 'name: #{tournament[:name]}'"
62
98
  end
63
99
 
100
+ include Validator::Range
101
+
64
102
  def maximum_place_within_range?(tournament, logger)
65
- return true if tournament[:'maximum place'].nil? ||
66
- tournament[:'maximum place'].between?(1, @maximum_place)
103
+ within_range?(tournament, :'maximum place', logger, 1, @maximum_place)
104
+ end
105
+
106
+ def medals_within_range?(tournament, logger)
107
+ max = [@maximum_place, tournament[:'maximum place']].compact.min
108
+ within_range?(tournament, :medals, logger, 1, max)
109
+ end
110
+
111
+ def trophies_within_range?(tournament, logger)
112
+ within_range?(tournament, :trophies, logger, 1, @maximum_place)
113
+ end
67
114
 
68
- logger.error "custom 'maximum place: #{tournament[:'maximum place']}' "\
69
- "is not within range [1, #{@maximum_place}]"
115
+ def bids_within_range?(tournament, logger)
116
+ within_range?(tournament, :bids, logger, 1, @schools_count)
70
117
  end
71
118
  end
72
119
  end
data/sciolyff.gemspec CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |s|
9
9
  s.license = 'MIT'
10
10
  s.name = 'sciolyff'
11
11
  s.summary = 'A file format for Science Olympiad tournament results.'
12
- s.version = '0.10.0'
12
+ s.version = '0.11.0'
13
13
  s.executables << 'sciolyff'
14
14
  s.add_runtime_dependency 'erubi', '~> 1.9'
15
15
  s.add_runtime_dependency 'optimist', '~> 3.0'
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.10.0
4
+ version: 0.11.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: 2020-04-14 00:00:00.000000000 Z
11
+ date: 2020-05-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: erubi
@@ -64,9 +64,12 @@ files:
64
64
  - bin/sciolyff
65
65
  - lib/sciolyff.rb
66
66
  - lib/sciolyff/interpreter.rb
67
+ - lib/sciolyff/interpreter/bids.rb
67
68
  - lib/sciolyff/interpreter/event.rb
68
69
  - lib/sciolyff/interpreter/html.rb
69
70
  - lib/sciolyff/interpreter/html/helpers.rb
71
+ - lib/sciolyff/interpreter/html/main.css
72
+ - lib/sciolyff/interpreter/html/main.js
70
73
  - lib/sciolyff/interpreter/html/template.html.erb
71
74
  - lib/sciolyff/interpreter/model.rb
72
75
  - lib/sciolyff/interpreter/penalty.rb
@@ -77,13 +80,16 @@ files:
77
80
  - lib/sciolyff/interpreter/tiebreaks.rb
78
81
  - lib/sciolyff/interpreter/tournament.rb
79
82
  - lib/sciolyff/validator.rb
83
+ - lib/sciolyff/validator/canonical.rb
80
84
  - lib/sciolyff/validator/checker.rb
81
85
  - lib/sciolyff/validator/events.rb
82
86
  - lib/sciolyff/validator/logger.rb
83
87
  - lib/sciolyff/validator/penalties.rb
84
88
  - lib/sciolyff/validator/placings.rb
89
+ - lib/sciolyff/validator/range.rb
85
90
  - lib/sciolyff/validator/raws.rb
86
91
  - lib/sciolyff/validator/sections.rb
92
+ - lib/sciolyff/validator/subdivisions.rb
87
93
  - lib/sciolyff/validator/teams.rb
88
94
  - lib/sciolyff/validator/top_level.rb
89
95
  - lib/sciolyff/validator/tournament.rb