basketball 0.0.15 → 0.0.16

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 27530180da34588494d04824d1fe1e9a6bfd4e0d94adc98afde3f659b070759c
4
- data.tar.gz: 4f8e961e2e8ac1bedd5d0869d5f5f8e0e2498cb24465ef0d4505f20d4219b7fc
3
+ metadata.gz: f5be10590a625ef061cb6f7a80379710013ec3625fe215fa65bfddeda35bb1f5
4
+ data.tar.gz: 5eff4fd535bddae0bf080f2fd0be83b4cdc8da7cc28c04667a1ec7cfd84f1f55
5
5
  SHA512:
6
- metadata.gz: bbb24ef7d1f192e39dd3e0740d60210e47fcdc041e6b69ec8d9a2897a39514dca775439c8c2894f228afc6ef8ebedf2005a83ea7b8817d00247a69e5e0ae2177
7
- data.tar.gz: 3c24e207c24e33c49baadb8bf13f8107a2bea9dc1d8bf6404601551635ef9a375f03f4b27da0b18118ef37eea55cda7d7e24b2572fd1649bc012d3a7081c9928
6
+ metadata.gz: 41e8aac1b7270794a5557b9e94b3b23bd0f5f7169c5c38f87401eaf12e6865efd4a1b8293a8cf6b6a41813ecc476750f538abc511ae4554e94c3cc732c6a5872
7
+ data.tar.gz: fd0fcc3117888b9c475efce63e5947de6f66950b3af98af9f4c551403749ab34fc6f989d3b48964bc29180be19c3af55931e5bb4ef67377f05dd83994ab82284
data/.rubocop.yml CHANGED
@@ -18,6 +18,9 @@ RSpec/ExampleLength:
18
18
  RSpec/NestedGroups:
19
19
  Max: 5
20
20
 
21
+ RSpec/MultipleExpectations:
22
+ Max: 2
23
+
21
24
  Metrics/ParameterLists:
22
25
  Max: 6
23
26
 
data/README.md CHANGED
@@ -14,7 +14,7 @@ Element | Description
14
14
  **Assessment** | When the Room needs to know who a Front Office wants to select, the Room will send the Front Office an Assessment. The Assessment is a report of where the team currently stands: players picked, players available, and round information.
15
15
  **Calendar** | Stores important boundary dates (exhibition start, exhibition end, season start, and season end).
16
16
  **Conference** | A collection of Divisions.
17
- **Coordinator Repository** | Understands how to save and load Coordinator objects from JSON files on disk.
17
+ **Coordinator Repository** | Understands how to save and load Coordinator objects.
18
18
  **Coordinator** | Object which can take a League, Calendar, Games, and an Arena and provide an iterable interface to enumerate through days and simulate games as results.
19
19
  **Detail** | Re-representation of a Result object but from a specific team's perspective.
20
20
  **Division** | A collection of teams.
@@ -34,13 +34,14 @@ Element | Description
34
34
  **Record** | Represents a team's overall record.
35
35
  **Regular** | Game that counts towards regular season record.
36
36
  **Result** | The outcome of a game (typically with a home and away score).
37
- **Room Repository** | Understands how to save and load Room objects from JSON files on disk.
37
+ **Room Repository** | Understands how to save and load Room objects.
38
38
  **Room** | Main object responsible for providing an iterable interface capable of executing a draft, pick by pick.
39
39
  **Scheduler** | Knows how to take a League and a year and generate a game-populated calendar.
40
40
  **Scout** | Knows how to stack rank lists of players.
41
41
  **Season** | Bounded context (sub-module) dealing with calendar and matchup generation.
42
42
  **Skip** | Result event emitted when a front office decides to skip a round.
43
43
  **Standings** | Synthesizes teams and results into team standings with win/loss records and more.
44
+ **Standings Repository** | Understands how to save and load Standings objects.
44
45
  **Store** | Interface for the underlying Repository persistence layer. While a Document Repository is mainly responsible for serialization/de-serialization, the store actually knows how to read/write the data.
45
46
  **Team Group** | Set of rosters that together form a cohesive league.
46
47
  **Team** | Member of a league and signs players. Has games assigned and played.
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Basketball
4
4
  module App
5
- # Knows how to flatten a League instance and rehydrate one from JSON and/or a Ruby hash.
5
+ # Knows how to flatten a League instances and rehydrate one from JSON and/or a Ruby hash.
6
6
  class LeagueRepository < DocumentRepository
7
7
  private
8
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Basketball
4
4
  module App
5
- # Can load and save Room objects to JSON files.
5
+ # Can load and save Room objects as JSON Documents.
6
6
  class RoomRepository < DocumentRepository
7
7
  PICK_EVENT = 'Pick'
8
8
  SKIP_EVENT = 'Skip'
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Basketball
4
+ module App
5
+ # Can load and save Standings objects as JSON Documents.
6
+ class StandingsRepository < DocumentRepository
7
+ private
8
+
9
+ def from_h(hash)
10
+ Season::Standings.new(
11
+ records: deserialize_records(hash[:records])
12
+ )
13
+ end
14
+
15
+ def to_h(standings)
16
+ {
17
+ id: standings.id,
18
+ records: serialize_records(standings.records)
19
+ }
20
+ end
21
+
22
+ # Serialization
23
+
24
+ def serialize_records(records)
25
+ (records || []).map do |record|
26
+ {
27
+ id: record.id,
28
+ details: serialize_details(record.details)
29
+ }
30
+ end
31
+ end
32
+
33
+ def serialize_details(details)
34
+ (details || []).map do |detail|
35
+ {
36
+ date: detail.date.to_s,
37
+ home: detail.home,
38
+ opponent: detail.opponent.id,
39
+ opponent_score: detail.opponent_score,
40
+ score: detail.score
41
+ }
42
+ end
43
+ end
44
+
45
+ # Deserialization
46
+
47
+ def deserialize_records(record_hashes)
48
+ (record_hashes || []).map do |record_hash|
49
+ Season::Record.new(
50
+ id: record_hash[:id],
51
+ details: deserialize_details(record_hash[:details])
52
+ )
53
+ end
54
+ end
55
+
56
+ def deserialize_details(detail_hashes)
57
+ (detail_hashes || []).map do |detail_hash|
58
+ Season::Detail.new(
59
+ date: Date.parse(detail_hash[:date]),
60
+ home: detail_hash[:home],
61
+ opponent: Season::Opponent.new(id: detail_hash[:opponent]),
62
+ opponent_score: detail_hash[:opponent_score].to_i,
63
+ score: detail_hash[:score].to_i
64
+ )
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -11,3 +11,4 @@ require_relative 'app/document_repository'
11
11
  require_relative 'app/coordinator_repository'
12
12
  require_relative 'app/league_repository'
13
13
  require_relative 'app/room_repository'
14
+ require_relative 'app/standings_repository'
@@ -8,7 +8,7 @@ module Basketball
8
8
  class DetailAlreadyAddedError < StandardError; end
9
9
  class OpponentNotFoundError < StandardError; end
10
10
 
11
- def initialize(id:)
11
+ def initialize(id:, details: [])
12
12
  super(id)
13
13
 
14
14
  @details_by_date = {}
@@ -53,9 +53,15 @@ module Basketball
53
53
  end
54
54
 
55
55
  def win_percentage
56
+ return 0 unless game_count.positive?
57
+
56
58
  (win_count.to_f / game_count).round(3)
57
59
  end
58
60
 
61
+ def win_percentage_display
62
+ format('%.3f', win_percentage)
63
+ end
64
+
59
65
  def game_count
60
66
  details.length
61
67
  end
@@ -69,17 +75,13 @@ module Basketball
69
75
  end
70
76
 
71
77
  def to_s
72
- "[#{super}] #{win_count}-#{loss_count} (#{win_percentage})"
78
+ "[#{super}] #{win_count}-#{loss_count} (#{win_percentage_display})"
73
79
  end
74
80
 
75
81
  def <=>(other)
76
82
  [win_count, win_percentage] <=> [other.win_count, other.win_percentage]
77
83
  end
78
84
 
79
- private
80
-
81
- attr_reader :details_by_date
82
-
83
85
  def add!(detail)
84
86
  raise DetailAlreadyAddedError, "#{detail} already added for date" if detail_for(detail.date)
85
87
 
@@ -87,6 +89,10 @@ module Basketball
87
89
 
88
90
  self
89
91
  end
92
+
93
+ private
94
+
95
+ attr_reader :details_by_date
90
96
  end
91
97
  end
92
98
  end
@@ -3,18 +3,29 @@
3
3
  module Basketball
4
4
  module Season
5
5
  # Represents a League with each team's win/loss details.
6
- class Standings
6
+ class Standings < Entity
7
7
  class TeamAlreadyRegisteredError < StandardError; end
8
8
  class TeamNotRegisteredError < StandardError; end
9
9
 
10
- def initialize
10
+ def initialize(records: [])
11
+ super()
12
+
11
13
  @records_by_id = {}
14
+
15
+ records.each { |record| add!(record) }
12
16
  end
13
17
 
14
- def register!(team)
15
- raise TeamAlreadyRegisteredError, "#{team} already registered!" if team?(team)
18
+ def add!(record)
19
+ raise ArgumentError, 'record is required' unless record
20
+ raise TeamAlreadyRegisteredError, "#{team} already registered!" if team?(record)
21
+
22
+ records_by_id[record.id] = record
16
23
 
17
- records_by_id[team.id] = Record.new(id: team.id)
24
+ self
25
+ end
26
+
27
+ def register!(team)
28
+ add!(Record.new(id: team.id))
18
29
 
19
30
  self
20
31
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Basketball
4
- VERSION = '0.0.15'
4
+ VERSION = '0.0.16'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: basketball
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.15
4
+ version: 0.0.16
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew Ruggio
@@ -40,6 +40,7 @@ files:
40
40
  - lib/basketball/app/in_memory_store.rb
41
41
  - lib/basketball/app/league_repository.rb
42
42
  - lib/basketball/app/room_repository.rb
43
+ - lib/basketball/app/standings_repository.rb
43
44
  - lib/basketball/draft.rb
44
45
  - lib/basketball/draft/assessment.rb
45
46
  - lib/basketball/draft/event.rb