sports 0.1.0 → 0.2.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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +1 -0
- data/Manifest.txt +0 -23
- data/README.md +3 -7
- data/Rakefile +4 -7
- data/lib/sports/version.rb +2 -2
- data/lib/sports.rb +5 -72
- metadata +20 -80
- 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/season.rb
DELETED
@@ -1,199 +0,0 @@
|
|
1
|
-
|
2
|
-
### note: make Season like Date a "top-level" / "generic" class
|
3
|
-
|
4
|
-
|
5
|
-
class Season
|
6
|
-
##
|
7
|
-
## todo: add (optional) start_date and end_date - why? why not?
|
8
|
-
|
9
|
-
## todo/todo/todo/check/check/check !!!
|
10
|
-
## todo: add a kernel Seaons e.g. Season('2011/12')
|
11
|
-
## forward to Season.convert( *args ) - why? why not?
|
12
|
-
|
13
|
-
## todo: add unicode - too - why? why not? see wikipedia pages, for example
|
14
|
-
|
15
|
-
YYYY_YYYY_RE = %r{^ ## e.g. 2011-2012 or 2011/2012
|
16
|
-
(\d{4})
|
17
|
-
[/-]
|
18
|
-
(\d{4})
|
19
|
-
$
|
20
|
-
}x
|
21
|
-
YYYY_YY_RE = %r{^ ## e.g. 2011-12 or 2011/12
|
22
|
-
(\d{4})
|
23
|
-
[/-]
|
24
|
-
(\d{2})
|
25
|
-
$
|
26
|
-
}x
|
27
|
-
YYYY_Y_RE = %r{^ ## e.g. 2011-2 or 2011/2
|
28
|
-
(\d{4})
|
29
|
-
[/-]
|
30
|
-
(\d{1})
|
31
|
-
$
|
32
|
-
}x
|
33
|
-
YYYY_RE = %r{^ ## e.g. 2011
|
34
|
-
(\d{4})
|
35
|
-
$
|
36
|
-
}x
|
37
|
-
|
38
|
-
|
39
|
-
def self.parse( str )
|
40
|
-
new( *_parse( str ))
|
41
|
-
end
|
42
|
-
|
43
|
-
def self._parse( str ) ## "internal" parse helper
|
44
|
-
if str =~ YYYY_YYYY_RE ## e.g. 2011/2012
|
45
|
-
[$1.to_i, $2.to_i]
|
46
|
-
elsif str =~ YYYY_YY_RE ## e.g. 2011/12
|
47
|
-
fst = $1.to_i
|
48
|
-
snd = $2.to_i
|
49
|
-
snd_exp = '%02d' % [(fst+1) % 100] ## double check: e.g 00 == 00, 01==01 etc.
|
50
|
-
raise ArgumentError, "[Season.parse] invalid year in season >>#{str}<<; expected #{snd_exp} but got #{$2}" if snd_exp != $2
|
51
|
-
[fst, fst+1]
|
52
|
-
elsif str =~ YYYY_Y_RE ## e.g. 2011/2
|
53
|
-
fst = $1.to_i
|
54
|
-
snd = $2.to_i
|
55
|
-
snd_exp = '%d' % [(fst+1) % 10] ## double check: e.g 0 == 0, 1==1 etc.
|
56
|
-
raise ArgumentError, "[Season.parse] invalid year in season >>#{str}<<; expected #{snd_exp} but got #{$2}" if snd_exp != $2
|
57
|
-
[fst, fst+1]
|
58
|
-
elsif str =~ YYYY_RE ## e.g. 2011
|
59
|
-
[$1.to_i]
|
60
|
-
else
|
61
|
-
raise ArgumentError, "[Season.parse] unkown season format >>#{str}<<; sorry cannot parse"
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
|
66
|
-
def self.convert( *args ) ## note: used by Kernel method Season()
|
67
|
-
if args.size == 1 && args[0].is_a?( Season )
|
68
|
-
args[0] # pass through / along as is 1:1
|
69
|
-
elsif args.size == 1 && args[0].is_a?( String )
|
70
|
-
parse( args[0] )
|
71
|
-
elsif args.size == 1 && args[0].is_a?( Integer ) && args[0] > 9999
|
72
|
-
## note: allow convenience "hack" such as:
|
73
|
-
# 202021 or 2020_21 => '2020/21' or
|
74
|
-
# 2020_1 or 2020_1 => '2020/21' or
|
75
|
-
# 20202021 or 2020_2021 => '2020/21'
|
76
|
-
str = args[0].to_s
|
77
|
-
parse( "#{str[0..3]}/#{str[4..-1]}" )
|
78
|
-
else ## assume all integer args e.g. 2020 or 2020, 2021 and such
|
79
|
-
new( *args ) ## try conversion with new
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
|
84
|
-
attr_reader :start_year,
|
85
|
-
:end_year
|
86
|
-
|
87
|
-
def initialize( *args ) ## change args to years - why? why not?
|
88
|
-
if args.size == 1 && args[0].is_a?( Integer )
|
89
|
-
@start_year = args[0]
|
90
|
-
@end_year = args[0]
|
91
|
-
elsif args.size == 2 && args[0].is_a?( Integer ) &&
|
92
|
-
args[1].is_a?( Integer )
|
93
|
-
@start_year = args[0]
|
94
|
-
@end_year = args[1]
|
95
|
-
end_year_exp = @start_year+1
|
96
|
-
raise ArgumentError, "[Season] invalid year in season >>#{to_s}<<; expected #{end_year_exp} but got #{@end_year}" if end_year_exp != @end_year
|
97
|
-
else
|
98
|
-
pp args
|
99
|
-
raise ArgumentError, "[Season] expected season start year (integer) with opt. end year"
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
## convenience helper - move to sportdb or such - remove - why - why not???
|
106
|
-
def start_date ## generate "generic / syntetic start date" - keep helper - why? why not?
|
107
|
-
if year?
|
108
|
-
Date.new( start_year, 1, 1 )
|
109
|
-
else
|
110
|
-
Date.new( start_year 1, 7 )
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
|
115
|
-
## single-year season e.g. 2011 if start_year is end_year - todo - find a better name?
|
116
|
-
def year?() @start_year == @end_year; end
|
117
|
-
|
118
|
-
def prev
|
119
|
-
if year?
|
120
|
-
Season.new( @start_year-1 )
|
121
|
-
else
|
122
|
-
Season.new( @start_year-1, @end_year-1 )
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
def next
|
127
|
-
if year?
|
128
|
-
Season.new( @start_year+1 )
|
129
|
-
else
|
130
|
-
Season.new( @start_year+1, @end_year+1 )
|
131
|
-
end
|
132
|
-
end
|
133
|
-
alias_method :succ, :next ## add support for ranges
|
134
|
-
|
135
|
-
|
136
|
-
include Comparable
|
137
|
-
def <=>(other)
|
138
|
-
## todo/fix/fix: check if other is_a?( Season )!!!
|
139
|
-
## what to return if other type/class ??
|
140
|
-
## note: check special edge case - year season and other e.g.
|
141
|
-
## 2010 <=> 2010/2011
|
142
|
-
|
143
|
-
res = @start_year <=> other.start_year
|
144
|
-
res = @end_year <=> other.end_year if res == 0
|
145
|
-
res
|
146
|
-
end
|
147
|
-
|
148
|
-
|
149
|
-
def to_formatted_s( format=:default, sep: '/' )
|
150
|
-
if year?
|
151
|
-
'%d' % @start_year
|
152
|
-
else
|
153
|
-
case format
|
154
|
-
when :default, :short, :s ## e.g. 1999/00 or 2019/20
|
155
|
-
"%d#{sep}%02d" % [@start_year, @end_year % 100]
|
156
|
-
when :long, :l ## e.g. 1999/2000 or 2019/2020
|
157
|
-
"%d#{sep}%d" % [@start_year, @end_year]
|
158
|
-
else
|
159
|
-
raise ArgumentError, "[Season.to_s] unsupported format >#{format}<"
|
160
|
-
end
|
161
|
-
end
|
162
|
-
end
|
163
|
-
alias_method :to_s, :to_formatted_s
|
164
|
-
|
165
|
-
def key() to_s( :short ); end
|
166
|
-
alias_method :to_key, :key
|
167
|
-
alias_method :name, :key
|
168
|
-
alias_method :title, :key
|
169
|
-
|
170
|
-
alias_method :inspect, :key ## note: add inspect debug support change debug output to string!!
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
def to_path( format=:default )
|
175
|
-
case format
|
176
|
-
when :default, :short, :s ## e.g. 1999-00 or 2019-20
|
177
|
-
to_s( :short, sep: '-' )
|
178
|
-
when :long, :l ## e.g. 1999-2000 or 2019-2000
|
179
|
-
to_s( :long, sep: '-' )
|
180
|
-
when :archive, :decade, :d ## e.g. 1990s/1999-00 or 2010s/2019-20
|
181
|
-
"%3d0s/%s" % [@start_year / 10, to_s( :short, sep: '-' )]
|
182
|
-
when :century, :c ## e.g. 1900s/1990-00 or 2000s/2019-20
|
183
|
-
"%2d00s/%s" % [@start_year / 100, to_s( :short, sep: '-' )]
|
184
|
-
else
|
185
|
-
raise ArgumentError, "[Season.to_path] unsupported format >#{format}<"
|
186
|
-
end
|
187
|
-
end # method to_path
|
188
|
-
alias_method :directory, :to_path ## keep "legacy" directory alias - why? why not?
|
189
|
-
alias_method :path, :to_path
|
190
|
-
|
191
|
-
end # class Season
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
### note: add a convenience "shortcut" season kernel method conversion method
|
196
|
-
## use like Season( '2012/3' ) or such
|
197
|
-
module Kernel
|
198
|
-
def Season( *args ) Season.convert( *args ); end
|
199
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
module Sports
|
2
|
-
|
3
|
-
##
|
4
|
-
# note: check that shape/structure/fields/attributes match
|
5
|
-
# the ActiveRecord model !!!!
|
6
|
-
|
7
|
-
class Country
|
8
|
-
|
9
|
-
## note: is read-only/immutable for now - why? why not?
|
10
|
-
## add cities (array/list) - why? why not?
|
11
|
-
attr_reader :key, :name, :code, :tags
|
12
|
-
attr_accessor :alt_names
|
13
|
-
|
14
|
-
def initialize( key: nil, name:, code:, tags: [] )
|
15
|
-
## note: auto-generate key "on-the-fly" if missing for now - why? why not?
|
16
|
-
## note: quick hack - auto-generate key, that is, remove all non-ascii chars and downcase
|
17
|
-
@key = key || name.downcase.gsub( /[^a-z]/, '' )
|
18
|
-
@name, @code = name, code
|
19
|
-
@alt_names = []
|
20
|
-
@tags = tags
|
21
|
-
end
|
22
|
-
|
23
|
-
end # class Country
|
24
|
-
|
25
|
-
end # module Sports
|
26
|
-
|
data/lib/sports/structs/goal.rb
DELETED
@@ -1,231 +0,0 @@
|
|
1
|
-
|
2
|
-
module Sports
|
3
|
-
|
4
|
-
|
5
|
-
## "free-standing" goal event - for import/export in separate event / goal datafiles
|
6
|
-
## returned by CsvGoalParser and others
|
7
|
-
class GoalEvent
|
8
|
-
|
9
|
-
def self.build( row ) ## rename to parse or such - why? why not?
|
10
|
-
|
11
|
-
## split match_id
|
12
|
-
team_str, more_str = row['Match'].split( '|' )
|
13
|
-
team1_str, team2_str = team_str.split( ' - ' )
|
14
|
-
|
15
|
-
more_str = more_str.strip
|
16
|
-
team1_str = team1_str.strip
|
17
|
-
team2_str = team2_str.strip
|
18
|
-
|
19
|
-
# check if more_str is a date otherwise assume round
|
20
|
-
date_fmt = if more_str =~ /^[A-Z]{3} [0-9]{1,2}$/i ## Apr 4
|
21
|
-
'%b %d'
|
22
|
-
elsif more_str =~ /^[A-Z]{3} [0-9]{1,2} [0-9]{4}$/i ## Apr 4 2019
|
23
|
-
'%b %d %Y'
|
24
|
-
else
|
25
|
-
nil
|
26
|
-
end
|
27
|
-
|
28
|
-
if date_fmt
|
29
|
-
date = Date.strptime( more_str, date_fmt )
|
30
|
-
round = nil
|
31
|
-
else
|
32
|
-
date = nil
|
33
|
-
round = more_str
|
34
|
-
end
|
35
|
-
|
36
|
-
|
37
|
-
values = row['Score'].split('-')
|
38
|
-
values = values.map { |value| value.strip }
|
39
|
-
score1 = values[0].to_i
|
40
|
-
score2 = values[1].to_i
|
41
|
-
|
42
|
-
minute = nil
|
43
|
-
offset = nil
|
44
|
-
if m=%r{([0-9]+)
|
45
|
-
(?:[ ]+
|
46
|
-
\+([0-9]+)
|
47
|
-
)?
|
48
|
-
['.]
|
49
|
-
$}x.match( row['Minute'])
|
50
|
-
minute = m[1].to_i
|
51
|
-
offset = m[2] ? m[2].to_i : nil
|
52
|
-
else
|
53
|
-
puts "!! ERROR - unsupported minute (goal) format >#{row['Minute']}<"
|
54
|
-
exit 1
|
55
|
-
end
|
56
|
-
|
57
|
-
attributes = {
|
58
|
-
team1: team1_str,
|
59
|
-
team2: team2_str,
|
60
|
-
date: date,
|
61
|
-
round: round,
|
62
|
-
score1: score1,
|
63
|
-
score2: score2,
|
64
|
-
minute: minute,
|
65
|
-
offset: offset,
|
66
|
-
player: row['Player'],
|
67
|
-
owngoal: ['(og)', '(o.g.)'].include?( row['Extra']),
|
68
|
-
penalty: ['(pen)', '(pen.)'].include?( row['Extra']),
|
69
|
-
notes: (row['Notes'].nil? || row['Notes'].empty?) ? nil : row['Notes']
|
70
|
-
}
|
71
|
-
|
72
|
-
new( **attributes )
|
73
|
-
end
|
74
|
-
|
75
|
-
|
76
|
-
## match id
|
77
|
-
attr_reader :team1,
|
78
|
-
:team2,
|
79
|
-
:round, ## optional
|
80
|
-
:date ## optional
|
81
|
-
|
82
|
-
## main attributes
|
83
|
-
attr_reader :score1,
|
84
|
-
:score2,
|
85
|
-
:player,
|
86
|
-
:minute,
|
87
|
-
:offset,
|
88
|
-
:owngoal,
|
89
|
-
:penalty,
|
90
|
-
:notes
|
91
|
-
|
92
|
-
|
93
|
-
## todo/check: or just use match.hash or such if match mapping known - why? why not?
|
94
|
-
def match_id
|
95
|
-
if round
|
96
|
-
"#{@team1} - #{@team2} | #{@round}"
|
97
|
-
else
|
98
|
-
"#{@team1} - #{@team2} | #{@date}"
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
|
103
|
-
def owngoal?() @owngoal==true; end
|
104
|
-
def penalty?() @penalty==true; end
|
105
|
-
|
106
|
-
def initialize( team1:,
|
107
|
-
team2:,
|
108
|
-
round: nil,
|
109
|
-
date: nil,
|
110
|
-
score1:,
|
111
|
-
score2:,
|
112
|
-
player:,
|
113
|
-
minute:,
|
114
|
-
offset: nil,
|
115
|
-
owngoal: false,
|
116
|
-
penalty: false,
|
117
|
-
notes: nil
|
118
|
-
)
|
119
|
-
@team1 = team1
|
120
|
-
@team2 = team2
|
121
|
-
@round = round
|
122
|
-
@date = date
|
123
|
-
|
124
|
-
@score1 = score1
|
125
|
-
@score2 = score2
|
126
|
-
@player = player
|
127
|
-
@minute = minute
|
128
|
-
@offset = offset
|
129
|
-
@owngoal = owngoal
|
130
|
-
@penalty = penalty
|
131
|
-
@notes = notes
|
132
|
-
end
|
133
|
-
|
134
|
-
|
135
|
-
## note: lets you use normalize teams or such acts like a Match struct
|
136
|
-
def update( **kwargs )
|
137
|
-
## todo/fix: use team1_name, team2_name or similar - for compat with db activerecord version? why? why not?
|
138
|
-
@team1 = kwargs[:team1] if kwargs.has_key? :team1
|
139
|
-
@team2 = kwargs[:team2] if kwargs.has_key? :team2
|
140
|
-
end
|
141
|
-
end # class GoalEvent
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
class Goal ### nested (non-freestanding) inside match (match is parent)
|
147
|
-
def self.build( events ) ## check/todo - rename to build_from_event/row or such - why? why not?
|
148
|
-
## build an array of goal structs from (csv) recs
|
149
|
-
recs = []
|
150
|
-
|
151
|
-
last_score1 = 0
|
152
|
-
last_score2 = 0
|
153
|
-
|
154
|
-
events.each do |event|
|
155
|
-
|
156
|
-
if last_score1+1 == event.score1 && last_score2 == event.score2
|
157
|
-
team = 1
|
158
|
-
elsif last_score2+1 == event.score2 && last_score1 == event.score1
|
159
|
-
team = 2
|
160
|
-
else
|
161
|
-
puts "!! ERROR - unexpected score advance (one goal at a time expected):"
|
162
|
-
puts " #{last_score1}-#{last_score2}=> #{event.score1}-#{event.score2}"
|
163
|
-
exit 1
|
164
|
-
end
|
165
|
-
|
166
|
-
last_score1 = event.score1
|
167
|
-
last_score2 = event.score2
|
168
|
-
|
169
|
-
|
170
|
-
attributes = {
|
171
|
-
score1: event.score1,
|
172
|
-
score2: event.score2,
|
173
|
-
team: team,
|
174
|
-
minute: event.minute,
|
175
|
-
offset: event.offset,
|
176
|
-
player: event.player,
|
177
|
-
owngoal: event.owngoal,
|
178
|
-
penalty: event.penalty,
|
179
|
-
notes: event.notes
|
180
|
-
}
|
181
|
-
|
182
|
-
recs << Goal.new( **attributes )
|
183
|
-
end
|
184
|
-
|
185
|
-
recs
|
186
|
-
end
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
attr_reader :score1,
|
191
|
-
:score2,
|
192
|
-
:team,
|
193
|
-
:player,
|
194
|
-
:minute,
|
195
|
-
:offset,
|
196
|
-
:owngoal,
|
197
|
-
:penalty,
|
198
|
-
:notes
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
def owngoal?() @owngoal==true; end
|
203
|
-
def penalty?() @penalty==true; end
|
204
|
-
def team1?() @team == 1; end
|
205
|
-
def team2?() @team == 2; end
|
206
|
-
|
207
|
-
def initialize( score1:,
|
208
|
-
score2:,
|
209
|
-
team:,
|
210
|
-
player:,
|
211
|
-
minute:,
|
212
|
-
offset: nil,
|
213
|
-
owngoal: false,
|
214
|
-
penalty: false,
|
215
|
-
notes: nil
|
216
|
-
)
|
217
|
-
@score1 = score1
|
218
|
-
@score2 = score2
|
219
|
-
@team = team # 1 or 2
|
220
|
-
@player = player
|
221
|
-
@minute = minute
|
222
|
-
@offset = offset
|
223
|
-
@owngoal = owngoal
|
224
|
-
@penalty = penalty
|
225
|
-
@notes = notes
|
226
|
-
end
|
227
|
-
end # class Goal
|
228
|
-
|
229
|
-
|
230
|
-
end # module Sports
|
231
|
-
|
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
|
-
|