sportdb-structs 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,10 +1,8 @@
1
1
 
2
2
  module Sports
3
3
 
4
- ##
5
- ## todo/fix: remove self.create in structs!!! use just new!!!
6
4
 
7
- class Team
5
+ class Team # shared base for clubs AND natinal_teams
8
6
  ## todo: use just names for alt_names - why? why not?
9
7
  attr_accessor :key, :name, :alt_names,
10
8
  :code, ## code == abbreviation e.g. ARS etc.
@@ -20,18 +18,36 @@ class Team
20
18
  def key
21
19
  ## note: auto-generate key "on-the-fly" if missing for now - why? why not?
22
20
  ## note: quick hack - auto-generate key, that is, remove all non-ascii chars and downcase
23
- @key || @name.downcase.gsub( /[^a-z]/, '' )
21
+ ## fix update - allow numbers (0-9)
22
+ ## add dash(-) plus parens () too!! for (-1999) or (1999-2011) or such
23
+ ## add umlauts too for now - plus add more later!!!
24
+ ##
25
+ ## fix- add more (all) diacritics!!!
26
+ ## GÍ Gøta (1926-2008)
27
+ ## FC Suðuroy
28
+ ## fix - remove dash(-) if not followed or preceded by year (four digits)!!!
29
+ ##
30
+ ## use new (autogen)key rule
31
+ ## - 1st unaccent, 2nd downcase, 3rd remove space et al
32
+ ## use keygen or autokey function or such - why? why not?
33
+
34
+ ## cache autokey generation (elg. use ||= NOT ||) - why? why not?
35
+
36
+ @key ||= begin
37
+ unaccent( @name ).downcase.gsub( /[^a-z0-9()-]/, '' )
38
+ end
39
+ @key
24
40
  end
25
41
 
26
42
 
27
43
  ## special import only attribs
28
- attr_accessor :alt_names_auto ## auto-generated alt names
29
44
  attr_accessor :wikipedia # wikipedia page name (for english (en))
30
45
 
31
46
 
32
47
  def historic?() @year_end ? true : false; end
33
48
  alias_method :past?, :historic?
34
49
 
50
+
35
51
  def wikipedia?() @wikipedia; end
36
52
  def wikipedia_url
37
53
  if @wikipedia
@@ -48,52 +64,17 @@ class Team
48
64
 
49
65
  def initialize( **kwargs )
50
66
  @alt_names = []
51
- @alt_names_auto = []
52
-
53
- update( kwargs ) unless kwargs.empty?
67
+
68
+ update( **kwargs ) unless kwargs.empty?
54
69
  end
55
70
 
56
71
  def update( **kwargs )
57
- @key = kwargs[:key] if kwargs.has_key? :key
58
- @name = kwargs[:name] if kwargs.has_key? :name
59
- @code = kwargs[:code] if kwargs.has_key? :code
60
- @alt_names = kwargs[:alt_names] if kwargs.has_key? :alt_names
72
+ @key = kwargs[:key] if kwargs.has_key?( :key )
73
+ @name = kwargs[:name] if kwargs.has_key?( :name )
74
+ @code = kwargs[:code] if kwargs.has_key?( :code )
75
+ @alt_names = kwargs[:alt_names] if kwargs.has_key?( :alt_names )
61
76
  self ## note - MUST return self for chaining
62
77
  end
63
-
64
-
65
-
66
- ##############################
67
- ## helper methods for import only??
68
- ## check for duplicates
69
- include SportDb::NameHelper
70
-
71
- def duplicates?
72
- names = [name] + alt_names + alt_names_auto
73
- names = names.map { |name| normalize( sanitize(name) ) }
74
-
75
- names.size != names.uniq.size
76
- end
77
-
78
- def duplicates
79
- names = [name] + alt_names + alt_names_auto
80
-
81
- ## calculate (count) frequency and select if greater than one
82
- names.reduce( {} ) do |h,name|
83
- norm = normalize( sanitize(name) )
84
- h[norm] ||= []
85
- h[norm] << name; h
86
- end.select { |norm,names| names.size > 1 }
87
- end
88
-
89
-
90
- def add_variants( name_or_names )
91
- names = name_or_names.is_a?(Array) ? name_or_names : [name_or_names]
92
- names.each do |name|
93
- name = sanitize( name )
94
- self.alt_names_auto += variants( name )
95
- end
96
- end
97
78
  end # class Team
98
79
 
99
80
 
@@ -108,6 +89,15 @@ class NationalTeam < Team
108
89
  self ## note - MUST return self for chaining
109
90
  end
110
91
 
92
+ def pretty_print( printer )
93
+ buf = String.new
94
+ buf << "<NationalTeam: #{@name}"
95
+ ## use code from country or from team ???
96
+ buf << " (#{@code})"
97
+ buf << ">"
98
+
99
+ printer.text( buf )
100
+ end
111
101
  end # class NationalTeam
112
102
 
113
103
 
@@ -116,7 +106,8 @@ end # class NationalTeam
116
106
  # district, geos, year_end, country, etc.
117
107
 
118
108
  class Club < Team
119
- attr_accessor :ground
109
+ attr_accessor :address,
110
+ :ground
120
111
 
121
112
  attr_accessor :a, :b
122
113
  def a?() @a == nil; end ## is a (1st) team / club (i)? if a is NOT set
@@ -136,12 +127,22 @@ class Club < Team
136
127
 
137
128
  def update( **kwargs )
138
129
  super
139
- @city = kwargs[:city] if kwargs.has_key? :city
130
+ @city = kwargs[:city] if kwargs.has_key?( :city )
140
131
  ## todo/fix: use city struct - why? why not?
141
132
  ## todo/fix: add country too or report unused keywords / attributes - why? why not?
142
133
 
143
134
  self ## note - MUST return self for chaining
144
135
  end
136
+
137
+
138
+ def pretty_print( printer )
139
+ buf = String.new
140
+ buf << "<Club: #{@name}"
141
+ buf << " (#{@country.code})" if @country
142
+ buf << ">"
143
+
144
+ printer.text( buf )
145
+ end
145
146
  end # class Club
146
147
 
147
148
  end # module Sports
@@ -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
@@ -3,8 +3,8 @@ module SportDb
3
3
  module Module
4
4
  module Structs
5
5
  MAJOR = 0 ## todo: namespace inside version or something - why? why not??
6
- MINOR = 1
7
- PATCH = 2
6
+ MINOR = 2
7
+ PATCH = 0
8
8
  VERSION = [MAJOR,MINOR,PATCH].join('.')
9
9
 
10
10
  def self.version
@@ -12,11 +12,11 @@ module SportDb
12
12
  end
13
13
 
14
14
  def self.banner
15
- "sportdb-structs/#{VERSION} on Ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]"
15
+ "sportdb-structs/#{VERSION} on Ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}] in (#{root})"
16
16
  end
17
17
 
18
18
  def self.root
19
- File.expand_path( File.dirname(File.dirname(File.dirname(__FILE__))) )
19
+ File.expand_path( File.dirname(File.dirname(File.dirname(File.dirname(__FILE__)))) )
20
20
  end
21
21
 
22
22
  end # module Structs
@@ -72,6 +72,45 @@ require 'sportdb/structs/structs/matchlist'
72
72
  require 'sportdb/structs/structs/standings'
73
73
  require 'sportdb/structs/structs/team_usage'
74
74
 
75
+ require 'sportdb/structs/structs/ground'
76
+
77
+
78
+ ##
79
+ ## todo/fix - move "inline" player to structs/player file !!!!
80
+
81
+ module Sports
82
+ ### note - own classes for National(Squad)Player and
83
+ ## Club(Squad)Player and such in use
84
+
85
+ class Player
86
+ attr_reader :name,
87
+ :pos, # position (g/d/m/f) for now
88
+ :nat, # nationality
89
+ :height, # in cm!! (integer) expected
90
+ :birthdate,
91
+ :birthplace
92
+
93
+ attr_accessor :alt_names
94
+
95
+ def initialize( name:,
96
+ pos: nil,
97
+ nat: nil,
98
+ height: nil,
99
+ birthdate: nil,
100
+ birthplace: nil )
101
+ @name = name
102
+ @alt_names = []
103
+ @pos = pos
104
+ @nat = nat
105
+ @height = height
106
+ @birthdate = birthdate
107
+ @birthplace = birthplace
108
+ end
109
+ end # class Player
110
+ end # module Sports
111
+
112
+
113
+
75
114
 
76
115
  require 'sportdb/structs/match_status_parser'
77
116
  require 'sportdb/structs/match_parser_csv'
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.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gerald Bauer
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-11-22 00:00:00.000000000 Z
11
+ date: 2024-06-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: alphabets
@@ -120,17 +120,17 @@ dependencies:
120
120
  requirements:
121
121
  - - "~>"
122
122
  - !ruby/object:Gem::Version
123
- version: '3.22'
123
+ version: '4.1'
124
124
  type: :development
125
125
  prerelease: false
126
126
  version_requirements: !ruby/object:Gem::Requirement
127
127
  requirements:
128
128
  - - "~>"
129
129
  - !ruby/object:Gem::Version
130
- version: '3.22'
130
+ version: '4.1'
131
131
  description: sportdb-structs - sport data structures for matches, scores, leagues,
132
132
  seasons, rounds, groups, teams, clubs and more
133
- email: opensport@googlegroups.com
133
+ email: gerald.bauer@gmail.com
134
134
  executables: []
135
135
  extensions: []
136
136
  extra_rdoc_files:
@@ -150,6 +150,7 @@ files:
150
150
  - lib/sportdb/structs/name_helper.rb
151
151
  - lib/sportdb/structs/structs/country.rb
152
152
  - lib/sportdb/structs/structs/goal.rb
153
+ - lib/sportdb/structs/structs/ground.rb
153
154
  - lib/sportdb/structs/structs/group.rb
154
155
  - lib/sportdb/structs/structs/league.rb
155
156
  - lib/sportdb/structs/structs/match.rb
@@ -159,17 +160,11 @@ files:
159
160
  - lib/sportdb/structs/structs/team.rb
160
161
  - lib/sportdb/structs/structs/team_usage.rb
161
162
  - lib/sportdb/structs/version.rb
162
- - test/helper.rb
163
- - test/test_clubs.rb
164
- - test/test_csv_reader.rb
165
- - test/test_match.rb
166
- - test/test_match_status_parser.rb
167
- - test/test_name_helper.rb
168
163
  homepage: https://github.com/sportdb/sport.db
169
164
  licenses:
170
165
  - Public Domain
171
166
  metadata: {}
172
- post_install_message:
167
+ post_install_message:
173
168
  rdoc_options:
174
169
  - "--main"
175
170
  - README.md
@@ -186,9 +181,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
186
181
  - !ruby/object:Gem::Version
187
182
  version: '0'
188
183
  requirements: []
189
- rubyforge_project:
190
- rubygems_version: 2.5.2
191
- signing_key:
184
+ rubygems_version: 3.4.10
185
+ signing_key:
192
186
  specification_version: 4
193
187
  summary: sportdb-structs - sport data structures for matches, scores, leagues, seasons,
194
188
  rounds, groups, teams, clubs and more
data/test/helper.rb DELETED
@@ -1,13 +0,0 @@
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
-
data/test/test_clubs.rb DELETED
@@ -1,38 +0,0 @@
1
- ###
2
- # to run use
3
- # ruby -I ./lib -I ./test test/test_clubs.rb
4
-
5
-
6
- require 'helper'
7
-
8
- class TestClubs < MiniTest::Test
9
-
10
- Club = Sports::Club
11
-
12
-
13
- def test_new
14
- club = Club.new( name: 'Rapid Wien' )
15
-
16
- assert_equal 'Rapid Wien', club.name
17
- assert_equal ['Rapid Wien'], club.names
18
- end
19
-
20
- def test_duplicates
21
- club = Club.new
22
- club.name = 'Rapid Wien'
23
-
24
- assert_equal false, club.duplicates?
25
- duplicates = {}
26
- assert_equal duplicates, club.duplicates
27
-
28
- club.alt_names_auto += ['Rapid', 'Rapid Wien', 'SK Rapid Wien']
29
-
30
- pp club
31
-
32
- assert_equal true, club.duplicates?
33
- duplicates = {'rapidwien'=>['Rapid Wien','Rapid Wien']}
34
- pp club.duplicates
35
- assert_equal duplicates, club.duplicates
36
- end
37
-
38
- end # class TestClubs
@@ -1,30 +0,0 @@
1
- ###
2
- # to run use
3
- # ruby -I ./lib -I ./test test/test_csv_reader.rb
4
-
5
-
6
- require 'helper'
7
-
8
-
9
- class TestCsvReader < MiniTest::Test
10
-
11
- def test_parse
12
- recs = parse_csv( <<TXT )
13
- ### World Countries
14
-
15
- Key, Code, Name
16
- af, AFG, Afghanistan
17
- al, ALB, Albania
18
- dz, ALG, Algeria
19
- as, ASA, American Samoa (US)
20
- TXT
21
-
22
- pp recs
23
- assert_equal [{ 'Key' => 'af', 'Code' => 'AFG', 'Name' => 'Afghanistan'},
24
- { 'Key' => 'al', 'Code' => 'ALB', 'Name' => 'Albania'},
25
- { 'Key' => 'dz', 'Code' => 'ALG', 'Name' => 'Algeria'},
26
- { 'Key' => 'as', 'Code' => 'ASA', 'Name' => 'American Samoa (US)'},
27
- ], recs[0..3]
28
- end
29
-
30
- end # class TestCsvReader
data/test/test_match.rb DELETED
@@ -1,30 +0,0 @@
1
- # encoding: utf-8
2
-
3
- ###
4
- # to run use
5
- # ruby -I ./lib -I ./test test/test_match.rb
6
-
7
-
8
- require 'helper'
9
-
10
- class TestMatch < MiniTest::Test
11
-
12
- Match = Sports::Match
13
-
14
-
15
- def test_round
16
- m = Match.new( team1: 'Team 1',
17
- team2: 'Team 2',
18
- round: 3 )
19
- pp m
20
- assert_equal 3, m.round
21
- assert_nil m.score1
22
- assert_nil m.score2
23
-
24
- m = Match.new
25
- m.update( round: 4 )
26
- pp m
27
- assert_equal 4, m.round
28
- end # method test_round
29
-
30
- end # class TestMatch
@@ -1,57 +0,0 @@
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
-