Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Trading Card Score Aggregator

trading_card_score_aggregator.livemd

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")