sportdb-structs 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,231 +1,231 @@
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
-
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
+
@@ -34,7 +34,7 @@ class Match
34
34
  @score1agg = @score2agg = nil ## full time (all legs) aggregated
35
35
 
36
36
 
37
- update( kwargs ) unless kwargs.empty?
37
+ update( **kwargs ) unless kwargs.empty?
38
38
  end
39
39
 
40
40
  def update( **kwargs )