*Run the BMI calculator app and learn how to
install it to your phone’s home screen. Read
on to learn how you can create an app just like it, without knowing
how to code.*

Body mass index (BMI) is a simple way of assessing a person’s height in relation to his or her weight. It is defined as the body weight divided by the square of the body height.

This sample app is a BMI calculator. As can be expected, creating a BMI calculator using Calcapp is straight-forward. To make things more interesting, though, we’ll explore a number of additional features in this blog post, including the ability to select what units to use (US customary units or metric units) and expressing the calculated BMI as a color.

Here’s a screenshot:

Run the app here. This app is available as the
*Sample: Body mass index (BMI)* template in Calcapp Creator
and you are encouraged to experiment with it as you read this blog
post.

## Selecting the units to use

The first field of the app, **Units**, is a text
drop-down field allowing the user to select what units to use, US
customary units (the **US customary** value) or metric
units (the **Metric** value). Other parts of the app
reference this drop-down field to determine what fields to make
visible and what calculations to perform.

## Entering the weight

Next are two fields, **WeightMetric** and
**WeightUs** for entering a person’s weight, using US
customary and metric units, respectively. Both use steppers to make it easy to
experiment with different values. **WeightMetric** has
this formula associated with its *Visible* property:

```
Units =
"Metric"
```

…and **WeightUs** has this formula associated with its
*Visible* property:

```
Units = "US
customary"
```

These two formulas ensure that the weight expressed in kilograms is
only displayed if the user elects to use metric units and that the
weight expressed in pounds is only displayed if the user wants to use
US customary units. (To associate a property with a formula, press
the **fx** button displayed next to it in the
inspector.)

Next is a hidden
field named **WeightInKg**, which holds the weight
in kilograms, regardless of what units the user has opted to work
with. (This field is referenced by the field performing the BMI
calculation.)

Here’s the formula of the **WeightInKg** field:

```
IF(Units = "US
customary", CONVERT(WeightUs, "lbm", "kg"), WeightMetric)
```

The IF formula function is used to select a different formula depending on the units selected by the user. If the user opted for US customary units, the CONVERT function is used to do the conversion. Otherwise, the metric value entered by the user is used as-is.

## Entering the height

If the user prefers working with metric units, he or she is expected
to enter the height in centimeters into the
**HeightMetric** field, which has an associated stepper.
As can be expected, the *Visible* formula of this field reads
as follows:

```
Units =
"Metric"
```

Using US customary units, a person’s height is traditionally
specified as a height in whole feet, to which a height in whole
inches is added. As such, two fields are required to express the
height using US customary units, **HeightUsFt** and
**HeightUsIn**. Both have associated steppers. As one
feet is made up of 12 inches, it doesn’t make sense to specify a
value for the **HeightUsIn** field greater than 11,
meaning that 11 is set as the maximum value for the stepper.

Both the **HeightUsFt** and **HeightUsIn**
fields have the following formula associated with their
*Visible* properties:

```
Units = "US
customary"
```

As with the weight, the height is converted to a metric unit using a
hidden field, here named **HeightInM**. It holds the
height in meters. Here’s its formula:

```
IF(Units = "US
customary", CONVERT(HeightUsFt, "ft", "m") + CONVERT(HeightUsIn,
"in", "m"), CONVERT(HeightMetric, "cm", "m"))
```

Again, the CONVERT formula function is used to do the conversion. The converted height in feet is simply added to the converted height in inches if US customary units are used. Otherwise, the entered height in centimeters is converted to meters.

## Calculating the results

The results are presented in a different section aptly named
*Results*. This is normally done by creating a new group,
which is given a label. Here, though, we have simply added a text box
above the fields representing the result. The reason is that text
boxes enable us greater control over the appearance, including what
fonts to use, their sizes and what text alignment to use.

A hidden field named **CalculatedBmi** is used to
calculate the BMI. Its formula is straight-forward:

```
WeightInKg /
HeightInM^2
```

It references the hidden fields we defined earlier, which hold the
weight in kilograms and the height in meters. The circumflex symbol
(`^`

) should
be read as *to the power of* and thus denotes exponentiation.

BMI can be used to categorize a person as being *underweight*,
*normal*, *overweight* and *obese* using
commonly-accepted ranges. The **Category** hidden text
field uses this formula to determine the category:

```
IF(CalculatedBmi
< 18.5, "underweight", IF(CalculatedBmi < 25, "normal",
IF(CalculatedBmi < 30, "overweight", "obese")))
```

Finally, the visible text field **Bmi** joins the
calculated BMI value together with the calculated category:

```
CalculatedBmi.FormattedValue &
" (" & Category & ")"
```

`FormattedValue`

denotes
a read-only property by that name belonging to a number field. It
returns a text string representing the formatted value of the number
field (taking into account things like the minimum and maximum number
of decimal places to use). `&`

joins that formatted
value together with an opening parenthesis, the calculated category
and, finally, a closing parenthesis.

The end result is that the calculated BMI is presented as a text string like the following:

*25.38 (overweight)*

## Color-coding the body mass index

The background color of the **Bmi** field changes to
reflect the calculated BMI: blue for underweight, green for normal,
yellow for overweight and red for obese.

All colors can be set
through formulas, so setting a color for the **Bmi**
field simply involves associating a formula with its
*BackgroundColor* property. A simple of way of achieving our
goal would be to use this formula:

```
IF(Category =
"underweight", COLOR("Blue 400"), IF(Category = "normal",
COLOR("Green 400"), IF(Category = "overweight", COLOR("Yellow 400"),
IF(Category = "obese", COLOR("Red 400")))))
```

This formula uses four distinct colors depending on the assigned
category. It’s simple to reason about, but wouldn’t it be more
interesting if the selected color varied using a far greater number
of steps? Instead of only using four colors (using a *discrete
formula*), we’ll instead use a potentially infinite number of
color variations (using a *continuous formula*).

To achieve this, we’ll need to use Calcapp’s HSL function. HSL stands for Hue, Saturation, Lightness and enables us to set the hue separately from the saturation and lightness. The hue is given as the first parameter, the saturation as the second parameter and the lightness as the third parameter. The last two parameters should be in the range 0 through 100 and we’ll somewhat arbitrarily choose the number 60 for both of them.

The hue parameter should be in the range 0 through 360 and can be likened to a color wheel. 0 is red, 120 is green, 240 is blue and 360 is (again) red.

To derive the proper hue, we first need to convert the BMI to a ratio, where a BMI of 0 to 18.5 corresponds to the ratio 0 and a BMI of 30 and above corresponds to a ratio of 1.

This is achieved using a hidden field named **BmiRatio**
which uses this formula:

```
(MIN(30, MAX(18.5,
CalculatedBmi)) - 18.5) / (30 - 18.5)
```

The MIN and MAX functions are used to constrain the
**Bmi** value to a value between 18.5 and 30
(inclusive). We then subtract 18.5 from the result and divide the
resulting value to arrive at the ratio.

Through experimentation, we determined that a hue value of 210 represents the blue color we want to use for a BMI of 18.5 and a hue value of 0 represents the red color we want to use for a BMI of 30.

The value of the **BmiRatio** field is 0 for a BMI of
18.5 and 1 for a BMI of 30, though. To achieve what we want, we’ll
need to invert the ratio by substracting it from 1. Putting it all
together, that enables us to write this formula for the
*BackgroundColor* property of the **Bmi** field:

```
HSL((1 - BmiRatio)
* 210, 60, 60)
```

Finally, the reset button is grayed-out if there are no values to
reset. To achieve this, the following formula is associated with the
*Enabled* property of the button:

`ISDEFINED(Bmi)`