BMI 体型判定

生田 陸人
LuaGate エンジニア / 現役エンジニア
編集 LuaGate編集部

BMI 体型判定 とは

身長と体重から BMI を計算し、4 段階で体型を判定する関数を書く。本レッスンでは、BMI 体型判定 の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。

BMI 体型判定

本レッスンでは、これまで学んだ if / elif / else を実用的なシナリオで使ってみます。お題は BMI (Body Mass Index, 体格指数) の判定です。身長 (m) と体重 (kg) を受け取り、weight / (height ** 2) で BMI を求めて、世界保健機関 (WHO) が定義する 4 段階のラベルを返します。実数の計算、四則演算、複数の境界値の扱いと、条件分岐の総合演習として最適のテーマです。

Python で計算したら if で区分する」 — これがデータ分析や業務アプリの定番フローです。

BMI とは何か

BMI は身長と体重の比率から肥満度を測る数値で、BMI = 体重 / 身長 ^ 2 で計算します。身長の単位はメートル、体重はキログラムです。例えば身長 1.70 m、体重 65 kg なら、65 / (1.70 ** 2) で約 22.49 になります。WHO の区分は次の通りです。

  • BMI が 18.5 未満 — "underweight"
  • 18.5 以上 25 未満 — "normal"
  • 25 以上 30 未満 — "overweight"
  • 30 以上 — "obese"

境界値はすべて「以上 / 未満」で定義されています。18.5"normal"25"overweight"30"obese" に入る点を間違えないようにしましょう。

境界値の挙動はバグの巣窟です。仕様書を読み返してから書き始めるのが安全です。

文法を確認する

Python でべき乗を計算するときは ** 演算子を使います。1.70 ** 22.89 です。整数除算 // ではなく、通常の除算 / を使う点にも注意します。今回は浮動小数点の結果が必要なので、/ 一択です。

Python

def bmi_value(height, weight): return weight / (height ** 2)

この補助関数で BMI を計算し、その結果を if / elif / else で区分すれば判定が完成します。Pythonif は比較を 連鎖 できる便利な機能を持ちますが、今回は素直に <<= を使い分ければ十分です。

動きを追ってみる

bmi_judge(1.70, 65) の流れを追うと、65 / (1.70 ** 2) で約 22.49 が出るので、18.5 <= 22.49 < 25 の枝に入り "normal" を返します。bmi_judge(1.60, 80) なら BMI が約 31.25"obese"bmi_judge(1.80, 55) なら約 16.98"underweight" です。

Python

def bmi_judge(height, weight): bmi = weight / (height ** 2) if bmi < 18.5: return "underweight" elif bmi < 25: return "normal" elif bmi < 30: return "overweight" else: return "obese"
diagram (will load when visible)

よくある間違い

  1. 境界値の取り扱いミスbmi < 18.5bmi <= 18.5 を混同すると、18.5 ちょうどのときの結果が変わります。仕様では 18.5"normal" なので bmi < 18.5 が正しいです。
  2. *** の取り違えheight * 2 は身長を 2 倍にするだけで、二乗にはなりません。べき乗は **、または pow(height, 2) を使います。
  3. 割り算の単位ミス — 身長を cm で渡してしまうと結果が極端に小さくなります。今回の問題ではメートルを期待します。

浮動小数点演算には微小な誤差が乗ることがあります。BMI の判定くらいなら問題ありませんが、お金の計算には decimal.Decimal を使うのが鉄則です。

やってみよう

関数 bmi_judge(height, weight) を完成させてください。引数の height はメートル、weight はキログラムです。"underweight", "normal", "overweight", "obese" のいずれかを文字列で返します。テストには境界値 18.52530 のケースも含まれます。実装後は、入力値が 0 以下のときに "invalid" を返すガード節を冒頭に足してみると、前回のガード節レッスンの復習になります。

よくある質問

Q. このトピックは Python 以外の言語でも同じ書き方ですか?

A. 考え方は他言語と共通ですが、構文や標準ライブラリは異なります。Python はインデントでブロックを表し、コロン + 改行で構造を作るのが特徴です。他言語に移行する際は基本概念を維持しつつ、構文の差分を意識して書き換えると混乱が少ないです。

Q. 実行してエラーが出た場合の対処は?

A. エラーメッセージの最後の行(TypeError や NameError などの型)から原因と該当行を確認します。Python はトレースバックが下から上に読むと「呼び出し元 → 内部」の順で辿れます。print や IDE のデバッガで途中の変数を確認すると原因が見えてきます。

Q. 次のステップで何を学ぶべきですか?

A. 本レッスンの内容を理解できたら、本文の「やってみよう」を実装し、章末クイズに進むのがおすすめです。さらに自分のミニアプリ(電卓・todo・スコア集計など)に応用するとスキルが定着します。詰まったら本文の H2 セクションに戻って読み返してください。

次のレッスン

次は FizzBuzz で、身長と体重から BMI を計算し、4 段階で体型を判定する関数を書く を学びます。

事前確認 — 進む前に次の 3 つができることを確認しましょう。

  1. BMI 判定 の要点を自分の言葉で説明できる
  2. このレッスンの最小コード (または操作手順) を見ずに書ける
  3. 練習問題やクイズで間違えた箇所を読み直して理解した

理解度チェック (30 秒)

Q. BMI 判定 とは何か、1 文で説明してください。

この章のポイント

A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。

関連レッスン

要件

  1. BMI = weight / (height ** 2) で計算する
  2. 閾値 18.5 / 25 / 30 で 4 段階に分岐する
  3. 境界値はその閾値以上のクラスに入る (18.5 は normal、25 は overweight、30 は obese)

入出力例

test-cases.txt

bmi_judge(1.7, 65)"normal" bmi_judge(1.8, 55)"underweight" bmi_judge(1.6, 80)"obese" bmi_judge(1.7, 75)"overweight" bmi_judge(2, 74)"normal" bmi_judge(2, 120)"obese"

ヒント

main.py
main.py
学習モード

メモ

BMI 体型判定

⌘S で保存