Trading Card Score Aggregator
TeamScores module
defmodule TeamScores do
@moduledoc """
Module for `TeamScores` that models a basic trading card score aggregator.
"""
@typedoc "A trading card with name, team, and score."
@type trading_card() :: %{name: String.t(), team: String.t(), score: integer()}
@doc """
Given a list of trading cards, calculate the total score for a given team
## Examples
iex> TeamScores.aggregate_team_score([%{name: "Player A", team: "Team X", score: 10}], "Team X") == 10
"""
@spec aggregate_team_score([trading_card()], String.t()) :: integer
def aggregate_team_score(cards, team_name) do
cards
|> Enum.reduce(0, fn team_card, team_score ->
aggregate_score(team_card, team_score, team_name)
end)
end
@spec aggregate_score(trading_card(), String.t(), integer) :: integer
defp aggregate_score(%{team: team} = team_card, team_score, team_name)
when team == team_name do
team_score + Map.get(team_card, :score, 0)
end
defp aggregate_score(_team_card, team_score, _team_name), do: team_score
end
ExUnit for aggregate team score functionality
ExUnit.start(autorun: false)
defmodule TeamScoresTest do
use ExUnit.Case
doctest TeamScores
describe "aggregate_team_score/2" do
test "calculates the total score for a specified team" do
cards = [
%{name: "Player A", team: "Team X", score: 10},
%{name: "Player B", team: "Team Y", score: 20},
%{name: "Player C", team: "Team X", score: 15},
%{name: "Player D", team: "Team Z", score: 5}
]
assert TeamScores.aggregate_team_score(cards, "Team X") == 25
assert TeamScores.aggregate_team_score(cards, "Team Y") == 20
assert TeamScores.aggregate_team_score(cards, "Team Z") == 5
end
test "The score for a team that is not inside of card list should be 0" do
cards = [
%{name: "Player B", team: "Team Y", score: 20},
%{name: "Player D", team: "Team Z", score: 5}
]
assert TeamScores.aggregate_team_score(cards, "Team X") == 0
end
test "The score should be 0 for an empty list of cards" do
assert TeamScores.aggregate_team_score([], "Team X") == 0
end
test "Return 0 if the team name is empty" do
cards = [
%{name: "Player B", team: "Team Y", score: 20}
]
assert TeamScores.aggregate_team_score(cards, "") == 0
end
end
end
ExUnit.run()
Evaluate team scores
cards = [
%{name: "Player A", team: "Team X", score: 10},
%{name: "Player B", team: "Team Y", score: 20},
%{name: "Player C", team: "Team X", score: 5},
%{name: "Player D", team: "Team Z", score: 15}
]
TeamScores.aggregate_team_score(cards, "Team X")