BMI 体型判定
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 ** 2 は 2.89 です。整数除算 // ではなく、通常の除算 / を使う点にも注意します。今回は浮動小数点の結果が必要なので、/ 一択です。
Python
def bmi_value(height, weight):
return weight / (height ** 2)この補助関数で BMI を計算し、その結果を if / elif / else で区分すれば判定が完成します。Python の if は比較を 連鎖 できる便利な機能を持ちますが、今回は素直に < と <= を使い分ければ十分です。
動きを追ってみる
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"よくある間違い
- 境界値の取り扱いミス —
bmi < 18.5とbmi <= 18.5を混同すると、18.5ちょうどのときの結果が変わります。仕様では18.5は"normal"なのでbmi < 18.5が正しいです。 **と*の取り違え —height * 2は身長を 2 倍にするだけで、二乗にはなりません。べき乗は**、またはpow(height, 2)を使います。- 割り算の単位ミス — 身長を cm で渡してしまうと結果が極端に小さくなります。今回の問題ではメートルを期待します。
浮動小数点演算には微小な誤差が乗ることがあります。BMI の判定くらいなら問題ありませんが、お金の計算には
decimal.Decimalを使うのが鉄則です。
やってみよう
関数 bmi_judge(height, weight) を完成させてください。引数の height はメートル、weight はキログラムです。"underweight", "normal", "overweight", "obese" のいずれかを文字列で返します。テストには境界値 18.5、25、30 のケースも含まれます。実装後は、入力値が 0 以下のときに "invalid" を返すガード節を冒頭に足してみると、前回のガード節レッスンの復習になります。
よくある質問
Q. このトピックは Python 以外の言語でも同じ書き方ですか?
A. 考え方は他言語と共通ですが、構文や標準ライブラリは異なります。Python はインデントでブロックを表し、コロン + 改行で構造を作るのが特徴です。他言語に移行する際は基本概念を維持しつつ、構文の差分を意識して書き換えると混乱が少ないです。
Q. 実行してエラーが出た場合の対処は?
A. エラーメッセージの最後の行(TypeError や NameError などの型)から原因と該当行を確認します。Python はトレースバックが下から上に読むと「呼び出し元 → 内部」の順で辿れます。print や IDE のデバッガで途中の変数を確認すると原因が見えてきます。
Q. 次のステップで何を学ぶべきですか?
A. 本レッスンの内容を理解できたら、本文の「やってみよう」を実装し、章末クイズに進むのがおすすめです。さらに自分のミニアプリ(電卓・todo・スコア集計など)に応用するとスキルが定着します。詰まったら本文の H2 セクションに戻って読み返してください。
次のレッスン
次は FizzBuzz で、身長と体重から BMI を計算し、4 段階で体型を判定する関数を書く を学びます。
事前確認 — 進む前に次の 3 つができることを確認しましょう。
- BMI 判定 の要点を自分の言葉で説明できる
- このレッスンの最小コード (または操作手順) を見ずに書ける
- 練習問題やクイズで間違えた箇所を読み直して理解した
理解度チェック (30 秒)
Q. BMI 判定 とは何か、1 文で説明してください。
A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。
関連レッスン
要件
- BMI = weight / (height ** 2) で計算する
- 閾値 18.5 / 25 / 30 で 4 段階に分岐する
- 境界値はその閾値以上のクラスに入る (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"