僕のメモ帳

僕のメモ帳です。

Goの勉強 肥満度判定BMI計算をしてみよう 改造編 ~for文を使ってエラー処理してみよう~

こんばんわ。たかしです。

さて、この前作成したBMI計算のソースコードを、for文使って正しい値が入力されないともう一回入力を促すつくりに変えてしまいましょう。

※今日からブログの書き方を「はてな記法」に変えました。出力結果や、Goの中身が読みやすくなっているかと思います。(そして、今までと違ってめちゃくちゃ書きやすいです。笑)

前回の記事はこちらです。
bokunomemocho.hatenablog.com


for文って何?

そういえば、前回さらっとif文の説明をせずに使ってしまいましたが、for文くらいは使い方の勉強の意味でまとめておきます。

for文についての説明は、Go言語のマニュアルを参考にしました。
golang.org

 

まず、for文というのは、特定の条件まで処理を繰り返したいときに利用するものです。構造はこのようになります。

①初期化、終了条件、計算式の構造

for init; condition; post { }

利用例

for i := 0 ; i < 5 ; i++{
    num++
}

②終了条件の構造

for condition { }

利用例

for _, value := range array {
   num += value
}

③無限ループ

for { }

利用例

for {
   num++
   if num > 10 {
        break
    }
}

 
利用条件に応じて①~③のパターンから選択して使っていくようですね。
あと、調べていて知ったのですが、Go言語にはwhileは存在しないようです。ループはforで書くんですって。
  

早速コードを改造しよう!

今のソースコードには、標準入力から入力された値が「a」などでもエラー判定はしてくれるけれども、再入力できるわけでもなくそのまま進んでしまうという問題点がありましたね。これを正しい値が入力されるまで処理を継続させましょうか。

まずは、身長だけに設定を入れてみましょう。

// 身長を入力
for {
    fmt.Printf("身長を入力してください:")
    _, err1 := fmt.Scan(&height) 

    // エラー判定
    if err1 != nil {
        fmt.Print("数字で入力してください!\n")
    }else{
        // 正しく入力されたらループを抜ける
        break
    }
} 

身長に変な値が入力されたら再入力を行わせて、正しく入力されたらbreakして処理を抜けるようにしました。

では、実行してみましょう。

$ go build bmi3.go
$ ./bmi3
身長を入力してください:a
数字で入力してください!
身長を入力してください:a
数字で入力してください!
身長を入力してください:178
体重を入力してください:98
BMI = 30.930438, 適正体重 = 69.704800, 肥満度 = 141 

身長が正しく入力されるまでしつこく入力を迫るプログラムになっていますね。

このプログラムだと、正しく入力されるまで処理が終了しないという問題があるので、例えば身長を5回正しく入力しなかったらエラー終了するようにしてみましょうか。
まず、exitを使うので取り込むパッケージに"os"を増やします。

// パッケージ取り込み
import (
    "fmt"
    "math"
    "os"

続いて、for文の中で5回処理を間違えたら異常終了するようにします。

count := 0

// 身長を入力
for {
    fmt.Printf("身長を入力してください:")
    _, err1 := fmt.Scan(&height)

    // エラー判定
    if err1 != nil {
        fmt.Print("数字で入力してください!\n")
        count++
        if count == 5 {
            fmt.Print("ちゃんと入力してくれないので処理終了しますね>。\n")
            os.Exit(1)
        }
    }else{
        // 正しく入力されたらループを抜ける
        break
    }
}

さあ、実行してみましょう!

$ go build bmi3.go
$ ./bmi3
身長を入力してください:a
数字で入力してください!
身長を入力してください:a
数字で入力してください!
身長を入力してください:a
数字で入力してください!
身長を入力してください:a
数字で入力してください!
身長を入力してください:a
数字で入力してください!
ちゃんと入力してくれないので処理終了しますね。 

おー!なんて冷たい!笑
クソLINE送り付けてしまったときの女子の返信のような文字が表示されましたね!笑

では、体重にも適用させましょうか。

count = 0
// 体重を入力
for {
        fmt.Printf("体重を入力してください:")
        _, err2 := fmt.Scan(&weight)

        // エラー判定
        if err2 != nil {
            fmt.Print("数字で入力してください!\n")
            count++
            if count == 5 {
                fmt.Print("ちゃんと入力してくれないので処理終了しますね>。\n")
                os.Exit(1)
            }
        }else{
            // 正しく入力されたらループを抜ける
            break
    }
}

さあ、実行してみましょう!

$ go build bmi3.go
$ ./bmi3
身長を入力してください:a
数字で入力してください!
身長を入力してください:a
数字で入力してください!
身長を入力してください:a
数字で入力してください!
身長を入力してください:a
数字で入力してください!
身長を入力してください:178
体重を入力してください:b
数字で入力してください!
体重を入力してください:b
数字で入力してください!
体重を入力してください:b
数字で入力してください!
体重を入力してください:b
数字で入力してください!
体重を入力してください:98
BMI = 30.930438, 適正体重 = 69.704800, 肥満度 = 141
$
$
$ ./bmi3
身長を入力してください:a
数字で入力してください!
身長を入力してください:a
数字で入力してください!
身長を入力してください:a
数字で入力してください!
身長を入力してください:a
数字で入力してください!
身長を入力してください:178
体重を入力してください:b
数字で入力してください!
体重を入力してください:b
数字で入力してください!
体重を入力してください:b
数字で入力してください!
体重を入力してください:b
数字で入力してください!
体重を入力してください:b
数字で入力してください!
ちゃんと入力してくれないので処理終了しますね。

すばらしい!身長も体重も4回までは許容して、5回間違えるとちゃんと終了するようになりました。

今回はfor文の使い方を学ぶために、for文の解説、そして実際の利用例としてBMI計算のソースコードでfor文を使ってみました。

次回は、for文などを使って長くなってしまったmainの中身を関数化してみましょう編でもやろうかと思います。
ではまたお会いしましょう。

ここまでのソースコード

今回までのソースコードはこんな感じになっています。
はてな記法に変えたので、今後はちゃんとソースも載せるようにしますね。

// パッケージ名
package main

// パッケージ取り込み
import (
        "fmt"
        "math"
        "os"
)

// 体重と身長を指定
var weight float64
var height float64

// mainの定義
func main() {
        count := 0
        // 身長を入力
        for {
                fmt.Printf("身長を入力してください:")
                _, err1 := fmt.Scan(&height)

                // エラー判定
                if err1 != nil {
                    fmt.Print("数字で入力してください!\n")
                    count++
                    if count == 5 {
                        fmt.Print("ちゃんと入力してくれないので処理終了しますね 。\n")
                        os.Exit(1)
                    }
                }else{
                    // 正しく入力されたらループを抜ける
                    break
            }
        }

        count = 0
        // 体重を入力
        for {
                fmt.Printf("体重を入力してください:")
                _, err2 := fmt.Scan(&weight)

                // エラー判定
                if err2 != nil {
                    fmt.Print("数字で入力してください!\n")
                    count++
                    if count == 5 {
                        fmt.Print("ちゃんと入力してくれないので処理終了しますね 。\n")
                        os.Exit(1)
                    }
                }else{
                    // 正しく入力されたらループを抜ける
                    break
            }
        }

        var hm = height / 100.0 // 身長をmにする
        var bmi = weight / math.Pow(hm, 2) // BMIの計算
        var bestW = math.Pow(hm, 2) * 22.0 // 適正体重の計算
        var per = weight / bestW * 100 // 肥満度の計算

        // 結果表示
        fmt.Printf("BMI = %f, 適正体重 = %f, 肥満度 = %.0f\n", bmi, bestW, per)
}