wip(growth): implement results for bmi
Some checks failed
continuous-integration/drone/pr Build is failing

This implementation should be made generic for all other scores.
This commit is contained in:
João Paulo Dubas 2024-06-10 19:09:35 +00:00
parent 28f0546bcb
commit 06b35cbceb
Signed by: joao.dubas
SSH Key Fingerprint: SHA256:V1mixgOGRc/YMhGx/DNkOSmJxgA2vHNrDZEk3wt/kOA

View File

@ -2,4 +2,70 @@ defmodule Growth.Score.BMI do
@moduledoc """
Calculate z-score for body mass index for age.
"""
alias Growth.Calc.Centile
alias Growth.Calc.ZScore
@spec result(Growth.t()) :: Growth.t()
@doc """
Calculate z-score and centile values and add them to the growth measurement results.
"""
def result(%Growth{bmi: nil} = measure) do
measure
end
def result(%Growth{results: results} = measure) do
result =
measure
|> lms()
|> Enum.map(fn {precision, {l, m, s}} ->
{precision, {z_score(measure.bmi, l, m, s), centile(measure.bmi, l, m, s)}}
end)
%{measure | results: [%{bmi: result} | results]}
end
@spec lms(Growth.t()) :: [{String.t(), {number(), number(), number()}}]
@doc """
Get the fitted values of Box-Cox:
* power (`l`)
* median (`m`)
* coefficient of variation (`s`)
"""
def lms(%Growth{} = measure) do
[
{measure.gender, "day", measure.age_in_days},
{measure.gender, "week", measure.age_in_weeks},
{measure.gender, "month", measure.age_in_months}
]
|> Enum.map(fn {_, precision, _} = key ->
case :ets.lookup(__MODULE__, key) do
[{^key, %{l: l, m: m, s: s}} | _] ->
{precision, {l, m, s}}
_ ->
nil
end
end)
|> Enum.reject(&is_nil/1)
end
@spec z_score(number(), number(), number(), number()) :: number()
@doc """
Check `Growth.Calc.ZScore.compute/4`.
"""
def z_score(value, l, m, s) do
ZScore.compute(value, l, m, s)
end
@spec centile(number(), number(), number(), number()) :: number() | :na
@doc """
Check `Growth.Calc.Centile.compute/4`.
"""
def centile(value, l, m, s) do
Centile.compute(value, l, m, s)
end
end