sportdb-structs 0.1.1 → 0.1.2

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.
@@ -1,84 +1,84 @@
1
-
2
- module Sports
3
-
4
-
5
- class TeamUsage
6
-
7
- class TeamUsageLine ## nested class
8
- attr_accessor :team,
9
- :matches, ## number of matches (played),
10
- :seasons, ## (optianl) array of seasons, use seasons.size for count
11
- :levels ## (optional) hash of levels (holds mapping level to TeamUsageLine)
12
-
13
- def initialize( team )
14
- @team = team
15
-
16
- @matches = 0
17
- @seasons = []
18
- @levels = {}
19
- end
20
- end # (nested) class TeamUsageLine
21
-
22
-
23
-
24
- def initialize( opts={} )
25
- @lines = {} # StandingsLines cached by team name/key
26
- end
27
-
28
-
29
- def update( matches, season: '?', level: nil )
30
- ## convenience - update all matches at once
31
- matches.each_with_index do |match,i| # note: index(i) starts w/ zero (0)
32
- update_match( match, season: season, level: level )
33
- end
34
- self # note: return self to allow chaining
35
- end
36
-
37
- def to_a
38
- ## return lines; sort
39
-
40
- # build array from hash
41
- ary = []
42
- @lines.each do |k,v|
43
- ary << v
44
- end
45
-
46
- ## for now sort just by name (a-z)
47
- ary.sort! do |l,r|
48
- ## note: reverse order (thus, change l,r to r,l)
49
- l.team <=> r.team
50
- end
51
-
52
- ary
53
- end # to_a
54
-
55
-
56
- private
57
- def update_match( m, season: '?', level: nil ) ## add a match
58
-
59
- line1 = @lines[ m.team1 ] ||= TeamUsageLine.new( m.team1 )
60
- line2 = @lines[ m.team2 ] ||= TeamUsageLine.new( m.team2 )
61
-
62
- line1.matches +=1
63
- line2.matches +=1
64
-
65
- ## include season if not seen before (allow season in multiple files!!!)
66
- line1.seasons << season unless line1.seasons.include?( season )
67
- line2.seasons << season unless line2.seasons.include?( season )
68
-
69
- if level
70
- line1_level = line1.levels[ level ] ||= TeamUsageLine.new( m.team1 )
71
- line2_level = line2.levels[ level ] ||= TeamUsageLine.new( m.team2 )
72
-
73
- line1_level.matches +=1
74
- line2_level.matches +=1
75
-
76
- line1_level.seasons << season unless line1_level.seasons.include?( season )
77
- line2_level.seasons << season unless line2_level.seasons.include?( season )
78
- end
79
- end # method update_match
80
-
81
-
82
- end # class TeamUsage
83
-
84
- end # module Sports
1
+
2
+ module Sports
3
+
4
+
5
+ class TeamUsage
6
+
7
+ class TeamUsageLine ## nested class
8
+ attr_accessor :team,
9
+ :matches, ## number of matches (played),
10
+ :seasons, ## (optianl) array of seasons, use seasons.size for count
11
+ :levels ## (optional) hash of levels (holds mapping level to TeamUsageLine)
12
+
13
+ def initialize( team )
14
+ @team = team
15
+
16
+ @matches = 0
17
+ @seasons = []
18
+ @levels = {}
19
+ end
20
+ end # (nested) class TeamUsageLine
21
+
22
+
23
+
24
+ def initialize( opts={} )
25
+ @lines = {} # StandingsLines cached by team name/key
26
+ end
27
+
28
+
29
+ def update( matches, season: '?', level: nil )
30
+ ## convenience - update all matches at once
31
+ matches.each_with_index do |match,i| # note: index(i) starts w/ zero (0)
32
+ update_match( match, season: season, level: level )
33
+ end
34
+ self # note: return self to allow chaining
35
+ end
36
+
37
+ def to_a
38
+ ## return lines; sort
39
+
40
+ # build array from hash
41
+ ary = []
42
+ @lines.each do |k,v|
43
+ ary << v
44
+ end
45
+
46
+ ## for now sort just by name (a-z)
47
+ ary.sort! do |l,r|
48
+ ## note: reverse order (thus, change l,r to r,l)
49
+ l.team <=> r.team
50
+ end
51
+
52
+ ary
53
+ end # to_a
54
+
55
+
56
+ private
57
+ def update_match( m, season: '?', level: nil ) ## add a match
58
+
59
+ line1 = @lines[ m.team1 ] ||= TeamUsageLine.new( m.team1 )
60
+ line2 = @lines[ m.team2 ] ||= TeamUsageLine.new( m.team2 )
61
+
62
+ line1.matches +=1
63
+ line2.matches +=1
64
+
65
+ ## include season if not seen before (allow season in multiple files!!!)
66
+ line1.seasons << season unless line1.seasons.include?( season )
67
+ line2.seasons << season unless line2.seasons.include?( season )
68
+
69
+ if level
70
+ line1_level = line1.levels[ level ] ||= TeamUsageLine.new( m.team1 )
71
+ line2_level = line2.levels[ level ] ||= TeamUsageLine.new( m.team2 )
72
+
73
+ line1_level.matches +=1
74
+ line2_level.matches +=1
75
+
76
+ line1_level.seasons << season unless line1_level.seasons.include?( season )
77
+ line2_level.seasons << season unless line2_level.seasons.include?( season )
78
+ end
79
+ end # method update_match
80
+
81
+
82
+ end # class TeamUsage
83
+
84
+ end # module Sports
@@ -4,7 +4,7 @@ module SportDb
4
4
  module Structs
5
5
  MAJOR = 0 ## todo: namespace inside version or something - why? why not??
6
6
  MINOR = 1
7
- PATCH = 1
7
+ PATCH = 2
8
8
  VERSION = [MAJOR,MINOR,PATCH].join('.')
9
9
 
10
10
  def self.version
@@ -1,13 +1,13 @@
1
- ## note: use the local version of sportdb gems
2
- $LOAD_PATH.unshift( File.expand_path( '../date-formats/lib' ))
3
- $LOAD_PATH.unshift( File.expand_path( '../score-formats/lib' ))
4
- $LOAD_PATH.unshift( File.expand_path( '../sportdb-langs/lib' ))
5
-
6
-
7
- ## minitest setup
8
- require 'minitest/autorun'
9
-
10
-
11
- ## our own code
12
- require 'sportdb/structs'
13
-
1
+ ## note: use the local version of sportdb gems
2
+ $LOAD_PATH.unshift( File.expand_path( '../date-formats/lib' ))
3
+ $LOAD_PATH.unshift( File.expand_path( '../score-formats/lib' ))
4
+ $LOAD_PATH.unshift( File.expand_path( '../sportdb-langs/lib' ))
5
+
6
+
7
+ ## minitest setup
8
+ require 'minitest/autorun'
9
+
10
+
11
+ ## our own code
12
+ require 'sportdb/structs'
13
+
@@ -1,57 +1,57 @@
1
- ###
2
- # to run use
3
- # ruby -I ./lib -I ./test test/test_match_status_parser.rb
4
-
5
-
6
- require 'helper'
7
-
8
-
9
- class TestMatchStatusParser < MiniTest::Test
10
-
11
- Status = SportDb::Status
12
- StatusParser = SportDb::StatusParser
13
-
14
- def test_find
15
- [['awarded [cancelled] canceled [ddd]', Status::CANCELLED],
16
- ['awarded [bbb; canceled] canceled [awarded; comments] eeee', Status::AWARDED],
17
- ['aaa bbb ccc ddd eeee', nil],
18
- ].each do |rec|
19
- line = rec[0]
20
- status_exp = rec[1]
21
- puts "line (before): >#{line}<"
22
- status = StatusParser.find!( line )
23
- puts "status: >#{status}<"
24
- puts "line (after): >#{line}<"
25
- puts
26
-
27
- if status_exp.nil?
28
- assert_nil status
29
- else
30
- assert_equal status_exp, status
31
- end
32
- end
33
- end # method test_find
34
-
35
- def test_parse
36
- [['cancelled ddd', Status::CANCELLED],
37
- ['CANCELLED', Status::CANCELLED],
38
- ['can.', Status::CANCELLED],
39
- ['awarded; comments', Status::AWARDED],
40
- ['awd. - comments', Status::AWARDED],
41
- ['aaa bbb ccc ddd eeee', nil],
42
- ].each do |rec|
43
- str = rec[0]
44
- status_exp = rec[1]
45
- status = StatusParser.parse( str )
46
-
47
- if status_exp.nil? ## for "silencing" minitest warning - Use assert_nil if expecting nil
48
- assert_nil status
49
- else
50
- assert_equal status_exp, status
51
- end
52
- end
53
- end
54
-
55
- end # class TestMatchStatusParser
56
-
57
-
1
+ ###
2
+ # to run use
3
+ # ruby -I ./lib -I ./test test/test_match_status_parser.rb
4
+
5
+
6
+ require 'helper'
7
+
8
+
9
+ class TestMatchStatusParser < MiniTest::Test
10
+
11
+ Status = SportDb::Status
12
+ StatusParser = SportDb::StatusParser
13
+
14
+ def test_find
15
+ [['awarded [cancelled] canceled [ddd]', Status::CANCELLED],
16
+ ['awarded [bbb; canceled] canceled [awarded; comments] eeee', Status::AWARDED],
17
+ ['aaa bbb ccc ddd eeee', nil],
18
+ ].each do |rec|
19
+ line = rec[0]
20
+ status_exp = rec[1]
21
+ puts "line (before): >#{line}<"
22
+ status = StatusParser.find!( line )
23
+ puts "status: >#{status}<"
24
+ puts "line (after): >#{line}<"
25
+ puts
26
+
27
+ if status_exp.nil?
28
+ assert_nil status
29
+ else
30
+ assert_equal status_exp, status
31
+ end
32
+ end
33
+ end # method test_find
34
+
35
+ def test_parse
36
+ [['cancelled ddd', Status::CANCELLED],
37
+ ['CANCELLED', Status::CANCELLED],
38
+ ['can.', Status::CANCELLED],
39
+ ['awarded; comments', Status::AWARDED],
40
+ ['awd. - comments', Status::AWARDED],
41
+ ['aaa bbb ccc ddd eeee', nil],
42
+ ].each do |rec|
43
+ str = rec[0]
44
+ status_exp = rec[1]
45
+ status = StatusParser.parse( str )
46
+
47
+ if status_exp.nil? ## for "silencing" minitest warning - Use assert_nil if expecting nil
48
+ assert_nil status
49
+ else
50
+ assert_equal status_exp, status
51
+ end
52
+ end
53
+ end
54
+
55
+ end # class TestMatchStatusParser
56
+
57
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sportdb-structs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gerald Bauer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-15 00:00:00.000000000 Z
11
+ date: 2020-11-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: alphabets
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: 0.1.1
55
+ - !ruby/object:Gem::Dependency
56
+ name: season-formats
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 0.0.1
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: 0.0.1
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: csvreader
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -84,30 +98,36 @@ dependencies:
84
98
  name: rdoc
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
- - - "~>"
101
+ - - ">="
88
102
  - !ruby/object:Gem::Version
89
103
  version: '4.0'
104
+ - - "<"
105
+ - !ruby/object:Gem::Version
106
+ version: '7'
90
107
  type: :development
91
108
  prerelease: false
92
109
  version_requirements: !ruby/object:Gem::Requirement
93
110
  requirements:
94
- - - "~>"
111
+ - - ">="
95
112
  - !ruby/object:Gem::Version
96
113
  version: '4.0'
114
+ - - "<"
115
+ - !ruby/object:Gem::Version
116
+ version: '7'
97
117
  - !ruby/object:Gem::Dependency
98
118
  name: hoe
99
119
  requirement: !ruby/object:Gem::Requirement
100
120
  requirements:
101
121
  - - "~>"
102
122
  - !ruby/object:Gem::Version
103
- version: '3.16'
123
+ version: '3.22'
104
124
  type: :development
105
125
  prerelease: false
106
126
  version_requirements: !ruby/object:Gem::Requirement
107
127
  requirements:
108
128
  - - "~>"
109
129
  - !ruby/object:Gem::Version
110
- version: '3.16'
130
+ version: '3.22'
111
131
  description: sportdb-structs - sport data structures for matches, scores, leagues,
112
132
  seasons, rounds, groups, teams, clubs and more
113
133
  email: opensport@googlegroups.com
@@ -128,7 +148,6 @@ files:
128
148
  - lib/sportdb/structs/match_parser_csv.rb
129
149
  - lib/sportdb/structs/match_status_parser.rb
130
150
  - lib/sportdb/structs/name_helper.rb
131
- - lib/sportdb/structs/season.rb
132
151
  - lib/sportdb/structs/structs/country.rb
133
152
  - lib/sportdb/structs/structs/goal.rb
134
153
  - lib/sportdb/structs/structs/group.rb
@@ -146,7 +165,6 @@ files:
146
165
  - test/test_match.rb
147
166
  - test/test_match_status_parser.rb
148
167
  - test/test_name_helper.rb
149
- - test/test_season.rb
150
168
  homepage: https://github.com/sportdb/sport.db
151
169
  licenses:
152
170
  - Public Domain
@@ -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