chore(growth): move nil logic to scorer behaviour
All checks were successful
continuous-integration/drone/pr Build is passing

Handle `nil` measurement in `Growth.Score.Scorer`.
This commit is contained in:
João Paulo Dubas 2024-06-11 14:53:19 +00:00
parent 7fab746ea8
commit 0d7a4cc9c3
Signed by: joao.dubas
SSH Key Fingerprint: SHA256:V1mixgOGRc/YMhGx/DNkOSmJxgA2vHNrDZEk3wt/kOA
3 changed files with 31 additions and 22 deletions

View File

@ -23,7 +23,7 @@ defmodule Growth.Calc.Centile do
alias Growth.Calc.ZScore alias Growth.Calc.ZScore
@spec compute(number(), ZScore.l(), ZScore.m(), ZScore.s()) :: number() | :na | nil @spec compute(number(), ZScore.l(), ZScore.m(), ZScore.s()) :: number() | :na
@doc """ @doc """
Compute the centile for a given measurement (`y`) and the Box-Cox values: power (`l`), median (`m`), and Compute the centile for a given measurement (`y`) and the Box-Cox values: power (`l`), median (`m`), and
coefficient of variation (`s`). coefficient of variation (`s`).
@ -36,10 +36,6 @@ defmodule Growth.Calc.Centile do
19.0 19.0
""" """
def compute(nil, _, _, _) do
nil
end
def compute(y, l, m, s) do def compute(y, l, m, s) do
zscore = ZScore.raw(y, l, m, s) zscore = ZScore.raw(y, l, m, s)

View File

@ -34,7 +34,7 @@ defmodule Growth.Calc.ZScore do
""" """
@type s :: number() @type s :: number()
@spec compute(number(), l(), m(), s()) :: Growth.measure() @spec compute(number(), l(), m(), s()) :: number()
@doc """ @doc """
Compute the adjusted z-score for a given measurement (`y`) and the Box-Cox values: power (`l`), median (`m`), and Compute the adjusted z-score for a given measurement (`y`) and the Box-Cox values: power (`l`), median (`m`), and
coefficient of variation (`s`). coefficient of variation (`s`).
@ -49,11 +49,6 @@ defmodule Growth.Calc.ZScore do
1.4698319520484722 1.4698319520484722
""" """
def compute(nil, _, _, _) do
nil
end
def compute(y, l, m, s) do def compute(y, l, m, s) do
y y
|> raw(l, m, s) |> raw(l, m, s)

View File

@ -25,7 +25,7 @@ defmodule Growth.Score.Scorer do
growth growth
|> lms(indicator) |> lms(indicator)
|> Enum.map(fn {precision, {l, m, s}} -> |> Enum.map(fn {precision, {l, m, s}} ->
{precision, {z_score(indicator, growth, l, m, s), centile(indicator, growth, l, m, s)}} {precision, scores(indicator, growth, l, m, s)}
end) end)
%{growth | results: [Map.new([{indicator.measure_name(), result}]) | growth.results]} %{growth | results: [Map.new([{indicator.measure_name(), result}]) | growth.results]}
@ -58,23 +58,41 @@ defmodule Growth.Score.Scorer do
|> Enum.reject(&is_nil/1) |> Enum.reject(&is_nil/1)
end end
@spec z_score(module(), Growth.t(), ZScore.l(), ZScore.m(), ZScore.s()) :: number() @spec scores(module(), Growth.t(), ZScore.l(), ZScore.m(), ZScore.s()) ::
{Growth.measure(), number() | :na, nil}
@doc """
Calculate the z-score and centile of an indicator measurement.
"""
def scores(indicator, growth, l, m, s) do
measure = Map.get(growth, indicator.measure_name())
{
z_score(measure, l, m, s),
centile(measure, l, m, s)
}
end
@spec z_score(Growth.measure(), ZScore.l(), ZScore.m(), ZScore.s()) :: Growth.measure()
@doc """ @doc """
Check `Growth.Calc.ZScore.compute/4`. Check `Growth.Calc.ZScore.compute/4`.
""" """
def z_score(indicator, growth, l, m, s) do def z_score(nil, _, _, _) do
growth nil
|> Map.get(indicator.measure_name())
|> ZScore.compute(l, m, s)
end end
@spec centile(module(), Growth.t(), ZScore.l(), ZScore.m(), ZScore.s()) :: number() | :na def z_score(value, l, m, s) do
ZScore.compute(value, l, m, s)
end
@spec centile(Growth.measure(), ZScore.l(), ZScore.m(), ZScore.s()) :: number() | :na | nil
@doc """ @doc """
Check `Growth.Calc.Centile.compute/4`. Check `Growth.Calc.Centile.compute/4`.
""" """
def centile(indicator, growth, l, m, s) do def centile(nil, _, _, _) do
growth nil
|> Map.get(indicator.measure_name()) end
|> Centile.compute(l, m, s)
def centile(value, l, m, s) do
Centile.compute(value, l, m, s)
end end
end end