-
Notifications
You must be signed in to change notification settings - Fork 2
/
BoxScoreService.scala
99 lines (89 loc) · 3.2 KB
/
BoxScoreService.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package io.innerproduct
package nba
import scala.concurrent.Future
object BoxScoreService {
/**
* The type of errors from validating a box score. You must replace with something more sensible
*/
type Error = Nothing
/**
* A [[BoxScoreLine]] summarizes a player's production in a game. This
* implementation uses just primitive types (String and Int). In a more
* sophisticated implementation we might want to define distinct types for
* these values, so that we don't, for example, confuse fieldGoalsMade and
* freeThrowsMade.
*/
final case class BoxScoreLine(
player: String,
fieldGoalsMade: Int,
fieldGoalsAttemped: Int,
threePointersMade: Int,
threePointersAttempted: Int,
freeThrowsMade: Int,
freeThrowsAttempted: Int,
offensiveRebounds: Int,
defensiveRebounds: Int,
assists: Int,
turnovers: Int,
steals: Int,
blocks: Int,
fouls: Int
) {
/**
* Total points scored by this player in this game
*/
val points =
(fieldGoalsMade * 2) + (threePointersMade * 3) + freeThrowsMade
/**
* Total rebounds by this player in this game
*/
val rebounds =
offensiveRebounds + defensiveRebounds
/**
* We could easily change [[BoxScoreLine]] so that incorrect box score line
* cannot be constructed, but we're assuming that we are receiving the data
* from an external source and we need to validate the input it has sent us.
* This method checks that the box score line is sensible. E.g. that
* fieldGoalsMade <= fieldGoalsAttempted and so on.
*/
def validate: Validated[Error, BoxScoreLine] =
???
}
final case class BoxScore(game: String, away: List[BoxScoreLine], home: List[BoxScoreLine]) {
/**
* Validate this [[BoxScore]]. In addition to validating the individual line
* each team much field at least 8 players, and hence at least 8 box score
* lines.
*/
def validate: Validated[Error, BoxScore] =
???
}
implicit val ec: scala.concurrent.ExecutionContext = scala.concurrent.ExecutionContext.global
def post(boxScore: BoxScore): Future[Either[List[Error], Unit]] = {
def printStatisticalLeaders(lines: List[BoxScoreLine]): Unit = {
val points = lines.sortBy(line => line.points).last.player
val rebounds = lines.sortBy(line => line.rebounds).last.player
val assists = lines.sortBy(line => line.assists).last.player
println(s"Points: ${points}")
println(s"Rebounds: ${rebounds}")
println(s"Assists: ${assists}")
}
Future {
if(math.random() < 0.2) throw new Exception("Out to lunch. Try again later.")
else boxScore.validate match {
case Validated.Success(b) =>
println("-----------------------------")
println(s"Box Score: ${b.game}")
println("-----------------------------")
println("Home Team Statistical Leaders")
printStatisticalLeaders(b.home)
println("-----------------------------")
println("Away Team Statistical Leaders")
printStatisticalLeaders(b.away)
println("-----------------------------")
Right(())
case Validated.Failure(e) => Left(e)
}
}
}
}