sports 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Manifest.txt +0 -23
- data/README.md +0 -3
- data/Rakefile +1 -4
- data/lib/sports.rb +5 -71
- data/lib/sports/version.rb +1 -1
- metadata +4 -69
- data/lib/sports/config.rb +0 -40
- data/lib/sports/goal_parser_csv.rb +0 -28
- data/lib/sports/match_parser_csv.rb +0 -490
- data/lib/sports/match_status_parser.rb +0 -90
- data/lib/sports/name_helper.rb +0 -87
- data/lib/sports/season.rb +0 -199
- data/lib/sports/structs/country.rb +0 -26
- data/lib/sports/structs/goal.rb +0 -231
- data/lib/sports/structs/group.rb +0 -16
- data/lib/sports/structs/league.rb +0 -35
- data/lib/sports/structs/match.rb +0 -180
- data/lib/sports/structs/matchlist.rb +0 -215
- data/lib/sports/structs/round.rb +0 -23
- data/lib/sports/structs/standings.rb +0 -271
- data/lib/sports/structs/team.rb +0 -147
- data/lib/sports/structs/team_usage.rb +0 -84
- data/test/helper.rb +0 -12
- data/test/test_clubs.rb +0 -38
- data/test/test_csv_reader.rb +0 -30
- data/test/test_match.rb +0 -30
- data/test/test_match_status_parser.rb +0 -57
- data/test/test_name_helper.rb +0 -65
- data/test/test_season.rb +0 -141
data/lib/sports/structs/group.rb
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
module Sports
|
2
|
-
|
3
|
-
class Group
|
4
|
-
attr_reader :key, :name, :teams
|
5
|
-
|
6
|
-
def initialize( key: nil,
|
7
|
-
name:,
|
8
|
-
teams: )
|
9
|
-
@key = key ## e.g. A,B,C or 1,2,3, - note: always a string or nil
|
10
|
-
@name = name
|
11
|
-
@teams = teams
|
12
|
-
end
|
13
|
-
end # class Group
|
14
|
-
|
15
|
-
end # module Sports
|
16
|
-
|
@@ -1,35 +0,0 @@
|
|
1
|
-
|
2
|
-
module Sports
|
3
|
-
|
4
|
-
|
5
|
-
class League
|
6
|
-
attr_reader :key, :name, :country, :intl
|
7
|
-
attr_accessor :alt_names
|
8
|
-
|
9
|
-
## special import only attribs
|
10
|
-
attr_accessor :alt_names_auto ## auto-generated alt names
|
11
|
-
|
12
|
-
def initialize( key:, name:, alt_names: [], alt_names_auto: [],
|
13
|
-
country: nil, intl: false, clubs: true )
|
14
|
-
@key = key
|
15
|
-
@name = name
|
16
|
-
@alt_names = alt_names
|
17
|
-
@alt_names_auto = alt_names_auto
|
18
|
-
|
19
|
-
@country = country
|
20
|
-
@intl = intl
|
21
|
-
@clubs = clubs
|
22
|
-
end
|
23
|
-
|
24
|
-
def intl?() @intl == true; end
|
25
|
-
def national?() @intl == false; end
|
26
|
-
alias_method :domestic?, :national?
|
27
|
-
|
28
|
-
def clubs?() @clubs == true; end
|
29
|
-
def national_teams?() @clubs == false; end
|
30
|
-
alias_method :club?, :clubs?
|
31
|
-
alias_method :national_team?, :national_teams?
|
32
|
-
|
33
|
-
end # class League
|
34
|
-
|
35
|
-
end # module Sports
|
data/lib/sports/structs/match.rb
DELETED
@@ -1,180 +0,0 @@
|
|
1
|
-
|
2
|
-
module Sports
|
3
|
-
|
4
|
-
|
5
|
-
class Match
|
6
|
-
|
7
|
-
attr_reader :date,
|
8
|
-
:time,
|
9
|
-
:team1, :team2, ## todo/fix: use team1_name, team2_name or similar - for compat with db activerecord version? why? why not?
|
10
|
-
:score1, :score2, ## full time
|
11
|
-
:score1i, :score2i, ## half time (first (i) part)
|
12
|
-
:score1et, :score2et, ## extra time
|
13
|
-
:score1p, :score2p, ## penalty
|
14
|
-
:score1agg, :score2agg, ## full time (all legs) aggregated
|
15
|
-
:winner, # return 1,2,0 1 => team1, 2 => team2, 0 => draw/tie
|
16
|
-
:round, ## todo/fix: use round_num or similar - for compat with db activerecord version? why? why not?
|
17
|
-
:leg, ## e.g. '1','2','3','replay', etc. - use leg for marking **replay** too - keep/make leg numeric?! - why? why not?
|
18
|
-
:stage,
|
19
|
-
:group,
|
20
|
-
:status, ## e.g. replay, cancelled, awarded, abadoned, postponed, etc.
|
21
|
-
:conf1, :conf2, ## special case for mls e.g. conference1, conference2 (e.g. west, east, central)
|
22
|
-
:country1, :country2, ## special case for champions league etc. - uses FIFA country code
|
23
|
-
:comments,
|
24
|
-
:league ## (optinal) added as text for now (use struct?)
|
25
|
-
|
26
|
-
|
27
|
-
attr_accessor :goals ## todo/fix: make goals like all other attribs!!
|
28
|
-
|
29
|
-
def initialize( **kwargs )
|
30
|
-
@score1 = @score2 = nil ## full time
|
31
|
-
@score1i = @score2i = nil ## half time (first (i) part)
|
32
|
-
@score1et = @score2et = nil ## extra time
|
33
|
-
@score1p = @score2p = nil ## penalty
|
34
|
-
@score1agg = @score2agg = nil ## full time (all legs) aggregated
|
35
|
-
|
36
|
-
|
37
|
-
update( kwargs ) unless kwargs.empty?
|
38
|
-
end
|
39
|
-
|
40
|
-
def update( **kwargs )
|
41
|
-
## note: check with has_key? because value might be nil!!!
|
42
|
-
@date = kwargs[:date] if kwargs.has_key? :date
|
43
|
-
@time = kwargs[:time] if kwargs.has_key? :time
|
44
|
-
|
45
|
-
## todo/fix: use team1_name, team2_name or similar - for compat with db activerecord version? why? why not?
|
46
|
-
@team1 = kwargs[:team1] if kwargs.has_key? :team1
|
47
|
-
@team2 = kwargs[:team2] if kwargs.has_key? :team2
|
48
|
-
|
49
|
-
@conf1 = kwargs[:conf1] if kwargs.has_key? :conf1
|
50
|
-
@conf2 = kwargs[:conf2] if kwargs.has_key? :conf2
|
51
|
-
@country1 = kwargs[:country1] if kwargs.has_key? :country1
|
52
|
-
@country2 = kwargs[:country2] if kwargs.has_key? :country2
|
53
|
-
|
54
|
-
## note: round is a string!!! e.g. '1', '2' for matchday or 'Final', 'Semi-final', etc.
|
55
|
-
## todo: use to_s - why? why not?
|
56
|
-
@round = kwargs[:round] if kwargs.has_key? :round
|
57
|
-
@stage = kwargs[:stage] if kwargs.has_key? :stage
|
58
|
-
@leg = kwargs[:leg] if kwargs.has_key? :leg
|
59
|
-
@group = kwargs[:group] if kwargs.has_key? :group
|
60
|
-
@status = kwargs[:status] if kwargs.has_key? :status
|
61
|
-
@comments = kwargs[:comments] if kwargs.has_key? :comments
|
62
|
-
|
63
|
-
@league = kwargs[:league] if kwargs.has_key? :league
|
64
|
-
|
65
|
-
|
66
|
-
if kwargs.has_key?( :score ) ## check all-in-one score struct for convenience!!!
|
67
|
-
score = kwargs[:score]
|
68
|
-
if score.nil? ## reset all score attribs to nil!!
|
69
|
-
@score1 = nil
|
70
|
-
@score1i = nil
|
71
|
-
@score1et = nil
|
72
|
-
@score1p = nil
|
73
|
-
## @score1agg = nil
|
74
|
-
|
75
|
-
@score2 = nil
|
76
|
-
@score2i = nil
|
77
|
-
@score2et = nil
|
78
|
-
@score2p = nil
|
79
|
-
## @score2agg = nil
|
80
|
-
else
|
81
|
-
@score1 = score.score1
|
82
|
-
@score1i = score.score1i
|
83
|
-
@score1et = score.score1et
|
84
|
-
@score1p = score.score1p
|
85
|
-
## @score1agg = score.score1agg
|
86
|
-
|
87
|
-
@score2 = score.score2
|
88
|
-
@score2i = score.score2i
|
89
|
-
@score2et = score.score2et
|
90
|
-
@score2p = score.score2p
|
91
|
-
## @score2agg = score.score2agg
|
92
|
-
end
|
93
|
-
else
|
94
|
-
@score1 = kwargs[:score1] if kwargs.has_key? :score1
|
95
|
-
@score1i = kwargs[:score1i] if kwargs.has_key? :score1i
|
96
|
-
@score1et = kwargs[:score1et] if kwargs.has_key? :score1et
|
97
|
-
@score1p = kwargs[:score1p] if kwargs.has_key? :score1p
|
98
|
-
@score1agg = kwargs[:score1agg] if kwargs.has_key? :score1agg
|
99
|
-
|
100
|
-
@score2 = kwargs[:score2] if kwargs.has_key? :score2
|
101
|
-
@score2i = kwargs[:score2i] if kwargs.has_key? :score2i
|
102
|
-
@score2et = kwargs[:score2et] if kwargs.has_key? :score2et
|
103
|
-
@score2p = kwargs[:score2p] if kwargs.has_key? :score2p
|
104
|
-
@score2agg = kwargs[:score2agg] if kwargs.has_key? :score2agg
|
105
|
-
|
106
|
-
## note: (always) (auto-)convert scores to integers
|
107
|
-
@score1 = @score1.to_i if @score1
|
108
|
-
@score1i = @score1i.to_i if @score1i
|
109
|
-
@score1et = @score1et.to_i if @score1et
|
110
|
-
@score1p = @score1p.to_i if @score1p
|
111
|
-
@score1agg = @score1agg.to_i if @score1agg
|
112
|
-
|
113
|
-
@score2 = @score2.to_i if @score2
|
114
|
-
@score2i = @score2i.to_i if @score2i
|
115
|
-
@score2et = @score2et.to_i if @score2et
|
116
|
-
@score2p = @score2p.to_i if @score2p
|
117
|
-
@score2agg = @score2agg.to_i if @score2agg
|
118
|
-
end
|
119
|
-
|
120
|
-
## todo/fix:
|
121
|
-
## gr-greece/2014-15/G1.csv:
|
122
|
-
## G1,10/05/15,Niki Volos,OFI,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
123
|
-
##
|
124
|
-
|
125
|
-
## for now score1 and score2 must be present
|
126
|
-
## if @score1.nil? || @score2.nil?
|
127
|
-
## puts "** WARN: missing scores for match:"
|
128
|
-
## pp kwargs
|
129
|
-
## ## exit 1
|
130
|
-
## end
|
131
|
-
|
132
|
-
## todo/fix: auto-calculate winner
|
133
|
-
# return 1,2,0 1 => team1, 2 => team2, 0 => draw/tie
|
134
|
-
### calculate winner - use 1,2,0
|
135
|
-
##
|
136
|
-
## move winner calc to score class - why? why not?
|
137
|
-
if @score1 && @score2
|
138
|
-
if @score1 > @score2
|
139
|
-
@winner = 1
|
140
|
-
elsif @score2 > @score1
|
141
|
-
@winner = 2
|
142
|
-
elsif @score1 == @score2
|
143
|
-
@winner = 0
|
144
|
-
else
|
145
|
-
end
|
146
|
-
else
|
147
|
-
@winner = nil # unknown / undefined
|
148
|
-
end
|
149
|
-
|
150
|
-
self ## note - MUST return self for chaining
|
151
|
-
end
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
def over?() true; end ## for now all matches are over - in the future check date!!!
|
156
|
-
def complete?() true; end ## for now all scores are complete - in the future check scores; might be missing - not yet entered
|
157
|
-
|
158
|
-
|
159
|
-
def score
|
160
|
-
Score.new( @score1i, @score2i, ## half time (first (i) part)
|
161
|
-
@score1, @score2, ## full time
|
162
|
-
@score1et, @score2et, ## extra time
|
163
|
-
@score1p, @score2p ) ## penalty
|
164
|
-
end
|
165
|
-
|
166
|
-
|
167
|
-
####
|
168
|
-
## deprecated - use score.to_s and friends - why? why not?
|
169
|
-
# def score_str # pretty print (full time) scores; convenience method
|
170
|
-
# "#{@score1}-#{@score2}"
|
171
|
-
# end
|
172
|
-
|
173
|
-
# def scorei_str # pretty print (half time) scores; convenience method
|
174
|
-
# "#{@score1i}-#{@score2i}"
|
175
|
-
# end
|
176
|
-
end # class Match
|
177
|
-
|
178
|
-
end # module Sports
|
179
|
-
|
180
|
-
|
@@ -1,215 +0,0 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
module Sports
|
4
|
-
|
5
|
-
|
6
|
-
class Matchlist ## todo: find a better name - MatchStats, MatchFixtures, MatchSchedule, ...
|
7
|
-
## use MatchCache/Buffer/Summary/Snippet/Segment/List...
|
8
|
-
## or MatchAnalyzer/Checker/Proofer/Query - why? why not?
|
9
|
-
attr_reader :matches # count of matches
|
10
|
-
## :name,
|
11
|
-
## :goals, # count of (total) goals - use total_goals - why? why not?
|
12
|
-
## :teams, -- has its own reader
|
13
|
-
## :rounds # note: use if all teams have same match count
|
14
|
-
## add last_updated/updated or something - why? why not?
|
15
|
-
|
16
|
-
def initialize( matches )
|
17
|
-
@matches = matches
|
18
|
-
end
|
19
|
-
|
20
|
-
|
21
|
-
def usage
|
22
|
-
@usage ||= build_usage( @matches )
|
23
|
-
@usage
|
24
|
-
end
|
25
|
-
|
26
|
-
def team_usage() usage.team_usage; end
|
27
|
-
|
28
|
-
def teams
|
29
|
-
@team_names ||= team_usage.keys.sort
|
30
|
-
@team_names
|
31
|
-
end
|
32
|
-
|
33
|
-
def goals() usage.goals; end
|
34
|
-
|
35
|
-
## note: start_date and end_date might be nil / optional missing!!!!
|
36
|
-
def start_date?() usage.start_date?; end
|
37
|
-
def end_date?() usage.end_date?; end
|
38
|
-
|
39
|
-
def start_date() usage.start_date; end
|
40
|
-
def end_date() usage.end_date; end
|
41
|
-
|
42
|
-
def has_dates?() usage.has_dates?; end
|
43
|
-
def dates_str() usage.dates_str; end
|
44
|
-
def days() usage.days; end
|
45
|
-
|
46
|
-
|
47
|
-
def rounds() usage.rounds; end
|
48
|
-
|
49
|
-
## todo: add has_rounds? alias for rounds? too
|
50
|
-
## return true if all match_played in team_usage are the same
|
51
|
-
## e.g. assumes league with matchday rounds
|
52
|
-
def rounds?() usage.rounds?; end
|
53
|
-
|
54
|
-
def match_counts() usage.match_counts; end
|
55
|
-
def match_counts_str() usage.match_counts_str; end
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
def stage_usage
|
60
|
-
@stage_usage ||= build_stage_usage( @matches )
|
61
|
-
@stage_usage
|
62
|
-
end
|
63
|
-
|
64
|
-
def stages() stage_usage.keys; end ## note: returns empty array for stages for now - why? why not?
|
65
|
-
|
66
|
-
|
67
|
-
############################
|
68
|
-
# matchlist helpers
|
69
|
-
private
|
70
|
-
class StatLine
|
71
|
-
attr_reader :team_usage,
|
72
|
-
:matches,
|
73
|
-
:goals,
|
74
|
-
:rounds, ## keep rounds - why? why not?
|
75
|
-
:start_date,
|
76
|
-
:end_date
|
77
|
-
|
78
|
-
def teams() @team_usage.keys.sort; end ## (auto-)sort here always - why? why not?
|
79
|
-
|
80
|
-
def start_date?() @start_date.nil? == false; end
|
81
|
-
def end_date?() @end_date.nil? == false; end
|
82
|
-
|
83
|
-
def has_dates?() @start_date && @end_date; end
|
84
|
-
def dates_str
|
85
|
-
## note: start_date/end_date might be optional/missing
|
86
|
-
if has_dates?
|
87
|
-
"#{start_date.strftime( '%a %d %b %Y' )} - #{end_date.strftime( '%a %d %b %Y' )}"
|
88
|
-
else
|
89
|
-
"??? - ???"
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
def days() end_date.jd - start_date.jd; end
|
94
|
-
|
95
|
-
|
96
|
-
def rounds
|
97
|
-
rounds? ## note: use rounds? to calculate (cache) rounds
|
98
|
-
@rounds ## note: return number of rounds or nil (for uneven matches played by teams)
|
99
|
-
end
|
100
|
-
|
101
|
-
## todo: add has_rounds? alias for rounds? too
|
102
|
-
def rounds?
|
103
|
-
## return true if all match_played in team_usage are the same
|
104
|
-
## e.g. assumes league with matchday rounds
|
105
|
-
if @has_rounds.nil? ## check/todo: if undefined attribute is nil by default??
|
106
|
-
## check/calc rounds
|
107
|
-
## note: values => matches_played by team
|
108
|
-
if match_counts.size == 1
|
109
|
-
@rounds = match_counts[0][0]
|
110
|
-
else
|
111
|
-
@rounds = nil
|
112
|
-
end
|
113
|
-
@has_rounds = @rounds ? true : false
|
114
|
-
end
|
115
|
-
@has_rounds
|
116
|
-
end
|
117
|
-
|
118
|
-
|
119
|
-
def build_match_counts ## use/rename to matches_played - why? why not?
|
120
|
-
counts = Hash.new(0)
|
121
|
-
team_usage.values.each do |count|
|
122
|
-
counts[count] += 1
|
123
|
-
end
|
124
|
-
|
125
|
-
## sort (descending) highest usage value first (in returned array)
|
126
|
-
## e.g. [[32,8],[31,2]] ## 32 matches by 8 teams, 31 matches by 2 teams etc.
|
127
|
-
counts.sort_by {|count, usage| -count }
|
128
|
-
end
|
129
|
-
|
130
|
-
def match_counts
|
131
|
-
# match counts / nos played per team
|
132
|
-
@match_counts ||= build_match_counts
|
133
|
-
@match_counts
|
134
|
-
end
|
135
|
-
|
136
|
-
def match_counts_str
|
137
|
-
## pretty print / formatted match_counts
|
138
|
-
buf = String.new('')
|
139
|
-
match_counts.each_with_index do |rec,i|
|
140
|
-
buf << ' ' if i > 0 ## add (space) separator
|
141
|
-
buf << "#{rec[0]}×#{rec[1]}"
|
142
|
-
end
|
143
|
-
buf
|
144
|
-
end
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
def initialize
|
149
|
-
@matches = 0
|
150
|
-
@goals = 0
|
151
|
-
|
152
|
-
@start_date = nil
|
153
|
-
@end_date = nil
|
154
|
-
|
155
|
-
@team_usage = Hash.new(0)
|
156
|
-
|
157
|
-
@match_counts = nil
|
158
|
-
end
|
159
|
-
|
160
|
-
|
161
|
-
def update( match )
|
162
|
-
@matches += 1 ## match counter
|
163
|
-
|
164
|
-
if match.score1 && match.score2
|
165
|
-
@goals += match.score1
|
166
|
-
@goals += match.score2
|
167
|
-
|
168
|
-
## todo: add after extra time? if knock out (k.o.) - why? why not?
|
169
|
-
## make it a flag/opt?
|
170
|
-
end
|
171
|
-
|
172
|
-
@team_usage[ match.team1 ] += 1
|
173
|
-
@team_usage[ match.team2 ] += 1
|
174
|
-
|
175
|
-
if match.date
|
176
|
-
## return / store date as string as is - why? why not?
|
177
|
-
date = Date.strptime( match.date, '%Y-%m-%d' )
|
178
|
-
|
179
|
-
@start_date = date if @start_date.nil? || date < @start_date
|
180
|
-
@end_date = date if @end_date.nil? || date > @end_date
|
181
|
-
end
|
182
|
-
end
|
183
|
-
end # class StatLine
|
184
|
-
|
185
|
-
|
186
|
-
## collect total usage stats (for all matches)
|
187
|
-
def build_usage( matches )
|
188
|
-
stat = StatLine.new
|
189
|
-
matches.each do |match|
|
190
|
-
stat.update( match )
|
191
|
-
end
|
192
|
-
stat
|
193
|
-
end
|
194
|
-
|
195
|
-
## collect usage stats by stage (e.g. regular / playoff / etc.)
|
196
|
-
def build_stage_usage( matches )
|
197
|
-
stages = {}
|
198
|
-
|
199
|
-
matches.each do |match|
|
200
|
-
stage_key = if match.stage.nil?
|
201
|
-
'Regular' ## note: assume Regular stage if not defined (AND not explicit unknown)
|
202
|
-
else
|
203
|
-
match.stage
|
204
|
-
end
|
205
|
-
|
206
|
-
stages[ stage_key ] ||= StatLine.new
|
207
|
-
stages[ stage_key ].update( match )
|
208
|
-
end
|
209
|
-
|
210
|
-
stages
|
211
|
-
end
|
212
|
-
|
213
|
-
end # class Matchlist
|
214
|
-
|
215
|
-
end # module Sports
|
data/lib/sports/structs/round.rb
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
module Sports
|
2
|
-
|
3
|
-
class Round
|
4
|
-
attr_reader :name, :start_date, :end_date, :knockout
|
5
|
-
attr_accessor :num # note: make read & writable - why? why not?
|
6
|
-
|
7
|
-
def initialize( name:,
|
8
|
-
num: nil,
|
9
|
-
start_date: nil,
|
10
|
-
end_date: nil,
|
11
|
-
knockout: false,
|
12
|
-
auto: true )
|
13
|
-
@name = name
|
14
|
-
@num = num
|
15
|
-
@start_date = start_date
|
16
|
-
@end_date = end_date
|
17
|
-
@knockout = knockout
|
18
|
-
@auto = auto # auto-created (inline reference/header without proper definition before)
|
19
|
-
end
|
20
|
-
end # class Round
|
21
|
-
|
22
|
-
end # module Sports
|
23
|
-
|