プログラミング基礎講座第6回

条件分岐:条件により処理を変える「if-else」

講座全体の概要

プログラミング基礎講座の第6回の後半です。講座全体の概要は以下の記事ゼロから始めるプログラミング基礎講座 第1回【講座の概要・目的】をご覧ください。

前半の記事はこちら。

前半の内容

前半はif文での基本の条件分岐を学習しました。後半はこれを発展させたif-else文と、複合条件ネストについて学習していきます。また、もう1つの条件分岐switch文についても簡単に紹介します。

準備として、Visual Studio で新しいプロジェクトを作成しましょう。名前は「BasicCourse6_2」とします。

if-else文について

前半で学習した単純なif文では条件を満たした場合のみ処理を行い、満たさなかった場合はなにもできませんでした。これから学習するif-else文では条件を満たした場合と、満たさなかった場合にそれぞれ異なる処理を行うことができます。

if-else文の構文は下記の通りです。各処理ブロックには複数の処理を記述でき、ブロックごとにまったく異なる処理が行えます。[ ]はその部分が省略可能であることを表しています。


if (条件式1) { 処理ブロック1 }
[else if (条件式2) { 処理ブロック2 }]
[else if (条件式3) { 処理ブロック3 }]
            ・
            ・
            ・
[else { 処理ブロックn }]

分岐条件の評価順序について

分岐の条件判定は上から、条件式1、条件式2、条件式3、・・・と評価されて、最初に条件を満たした部分の処理ブロックが実行されます。複数の条件を満たしていた場合でも、処理が行われるのは1つだけとなります。

else ifは複数記述が可能です。また、elseは最後に1つだけ記述可能で、それまでのいずれの条件も満たさなかった場合に処理ブロックが実行されます。elseを省略すると、いずれの条件も満たさなかった場合は何も処理が実行されません。

if-else文の具体例

説明だけだとわかりづらいと思いますので、以下に具体例を記載します。実際にプログラミングをして、デバッグ実行で動作を確認してみてください。ちなみに、連続で何度も実行したい場合は、ブラウザの更新ボタンを押すことで可能です。

Index.cshtml.csの抜粋

namespace BasicCourse6_2.Pages
{
    public class IndexModel : PageModel
    {
        private readonly ILogger<IndexModel> _logger;

        public IndexModel(ILogger<IndexModel> logger)
        {
            _logger = logger;
        }

        public int ParentNumber { get; set; }

        public int ChildNumber { get; set; }

        public string JudgedResult { get; set; }

        public void OnGet()
        {
            ParentNumber = RandomNumberGenerator.GetInt32(1, 14);
            ChildNumber = RandomNumberGenerator.GetInt32(1, 14);

            if (ChildNumber > ParentNumber)
            {
                JudgedResult = "ハイ";
            }
            else if ((ChildNumber < ParentNumber))
            {
                JudgedResult = "ロー";
            }
            else
            {
                JudgedResult = "ドロー";
            }
        }
    }
}
Index.cshtml

@page
@model IndexModel
@using static IndexModel
@{
    ViewData["Title"] = "Home page";
}

<div class="text-center">
    <h1>子の数字 を 親の数字 と大小比較した結果を表示する</h1>
    <form method="post">
        <div class="form-group form-row justify-content-md-around">
            <div class="form-inline">
                <label asp-for="ParentNumber" class="col-form-label">親の数字</label>
                <input asp-for="ParentNumber" type="text" class="form-control" readonly="readonly" />
            </div>
            <div class="form-inline">
                <label asp-for="ChildNumber" class="col-form-label">子の数字</label>
                <input asp-for="ChildNumber" type="text" class="form-control" readonly="readonly" />
            </div>
        </div>
        <div class="form-group form-row justify-content-md-around">
            <div class="form-inline">
                <label asp-for="JudgedResult" class="col-form-label">結果</label>
                <input asp-for="JudgedResult" class="form-control" type="text" readonly="readonly" />
            </div>
        </div>
    </form>
</div>
if-elseの実行結果 子が大きい場合
if-elseの実行結果 子が小さい場合
if-elseの実行結果 親と子が同じ場合

どうでしょうか? 実際にデバッグ実行で1行ずつ見ていけば、動作が理解できると思います。

続いて、複合条件とネストというものについて説明していきますが、準備として画面からの入力を受け付けて処理できるようにしていきたいと思います。

これから作成するプログラムの仕様説明

1.画面の初期表示時
1-1.初期表示時の画面イメージは以下の通りとする。
初期表示の画面イメージ
1-2.1~13の整数から1つをランダムに生成し、親の数字とする。
1-3.同じく1~13の整数から1つをランダムに生成し、子の数字とする。
1-4.親の数字を表示する。
1-5.ハイかローを選択するラジオボタンを表示し、入力必須とする。また、初期値は選択なしとする。
1-6.コールボタンを表示し、使用可能な状態とする。
2.コールボタンクリック時
2-1.ボタンクリック後の画面イメージは以下の通りとする。
コールボタンクリック後の画面イメージ
2-2.コールボタンを使用不可の状態とする。
2-3.子の数字を表示する。
2-4.「ハイ」が選択されていた場合、結果を以下の様に表示する。
2-4-1.子の数字 > 親の数字 の場合、”当たり”と表示する。
2-4-2.子の数字 < 親の数字 の場合、”はずれ”と表示する。
2-4-3.子の数字 = 親の数字 の場合、”引き分け”と表示する。
2-5.「ロー」が選択されていた場合、結果を以下の様に表示する。
2-5-1.子の数字 > 親の数字 の場合、”はずれ”と表示する。
2-5-2.子の数字 < 親の数字 の場合、”当たり”と表示する。
2-5-3.子の数字 = 親の数字 の場合、”引き分け”と表示する。
2-6.「ハイ」、「ロー」のいずれも選択されていなかった場合、BadRequest(ステータスコード=400)エラーとする。(ブラウザで必須チェックが行われるため、本来はありえない。)

ハイ・ローの入力を行うラジオボタンとコールを行うボタンを追加

いきなり難しそうな仕様を書きましたが、ちょっと仕事を意識して簡易的な仕様書風にしてみました。これから実際にプログラミングしていきますが、いくつかの段階に分けて徐々に進めていきたいと思います。

まずは入力用の新しい2つの項目を追加しましょう。それにあわせてデザインも変更します。以下のコードを参照してプログラミングしてください。

Index.cshtml.csの抜粋

namespace BasicCourse6_2.Pages
{
    public class IndexModel : PageModel
    {
                中略

        public int ParentNumber { get; set; }
        public int ChildNumber { get; set; }
        public string JudgedResult { get; set; }
        public int HighOrLow { get; set; }         // ラジオボタン用にこれを追加。

        public void OnGet()
        {
                中略
        }
    }
}

ラジオボタンの入力を数値で受け取れるようにしています。ハイの時は1、ローの時は2となることを想定しています。

Index.cshtml

@page
@model IndexModel
@using static IndexModel
@{
    ViewData["Title"] = "Home page";
}

<div class="text-center">
    <h1>ハイ&ロー</h1>
    <form method="post">
        <div class="form-group w-100">
            <div class="form-inline form-row mb-2">
                <label asp-for="ParentNumber" class="col-form-label col-sm-2 offset-sm-3 justify-content-end">親の数字</label>
                <input asp-for="ParentNumber" type="text" class="form-control col-sm-2" readonly="readonly" />
            </div>
        </div>

        @* ラジオボタンの追加部分 *@
        <div class="form-group w-100 justify-content-center">
            <div class="form-row w-100">
                <label asp-for="HighOrLow" class="col-form-label col-12 justify-content-center">ハイかローを選択してコールしてください。</label>
            </div>
            <div class="form-check form-check-inline justify-content-center mb-2">
                <div class="mx-3">
                    <input class="form-check-input" asp-for="HighOrLow" type="radio" value=1 id="radioHigh" required />
                    <label class="form-check-label" for="radioHigh">ハイ</label>
                </div>
                <div>
                    <input class="form-check-input" asp-for="HighOrLow" type="radio" value=2 id="radioLow" required />
                    <label class="form-check-label" for="radioLow">ロー</label>
                </div>
            </div>
        </div>

        @* ボタンの追加部分 *@
        <div class="row m-0 w-100 mt-3 mb-5">
            <input class="btn btn-primary col-sm-2 offset-sm-5" type="submit" value="コール">
        </div>

        @* コール後に表示する項目はページ下部に移動 *@
        <div class="form-group w-100">
            <div class="form-inline form-row mb-2">
                <label asp-for="ChildNumber" class="col-form-label col-sm-2 offset-sm-3 justify-content-end">子の数字</label>
                <input asp-for="ChildNumber" type="text" class="form-control col-sm-2" readonly="readonly" />
            </div>
            <div class="form-inline form-row mb-2">
                <label asp-for="JudgedResult" class="col-form-label col-sm-2 offset-sm-3 justify-content-end">結果</label>
                <input asp-for="JudgedResult" class="form-control col-sm-2" type="text" readonly="readonly" />
            </div>
        </div>
    </form>
</div>

こちらは変更点が多いですが、classの指定はBootstrapを使用した見た目の調整なので、あまり気にせずにコピペしてもらっても結構です。

ラジオボタンはidを自分で指定しています。選択肢ごとに別のidを付けてラベルと関連付けるため、このようにしています。また、「required」を指定することでブラウザが必須入力のチェックを行ってくれます。

プログラミングができたら実行してみましょう。非表示にするべき部分も表示されているはずです。また、コールボタンを押すと数字が0になってしまうと思います。次はここを直していきましょう。

非表示部分に「hidden」を指定

Index.cshtml.csの抜粋

namespace BasicCourse6_2.Pages
{
    public class IndexModel : PageModel
    {
                中略

        public int ParentNumber { get; set; }
        public int ChildNumber { get; set; }
        public string JudgedResult { get; set; }
        public int HighOrLow { get; set; }
        public bool ChildIsHidden { get; set; }         // 子の数字と結果を非表示にするか制御するために追加。

        public void OnGet()
        {
            ChildIsHidden = true;         // 初期表示では非表示にしたいので、trueを設定。

                中略
        }
    }
}

ページを表示する時に最初に処理されるのは「OnGet()」でしたね。ここに、初期表示時に子の数字と結果を非表示にする処理を記述していきます。

しかし、Index.cshtml.csでは見た目に関する処理(HTMLを操作する処理)ができません。そのため、ChildIsHiddenがtrueの時には関連の項目を非表示とするように、以下のIndex.cshtmlでChildIsHiddenを参照して見た目を制御します。

Index.cshtmlの抜粋

<div class="text-center">
    <h1>ハイ&ロー</h1>
    <form method="post">

                中略

        @{
            string hiddenAttribute = string.Empty;
            if (Model.ChildIsHidden)
            {
                hiddenAttribute = "hidden=\"hidden\"";
            }
        }
        <div class="form-group w-100" @hiddenAttribute>
            <div class="form-inline form-row mb-2">
                <label asp-for="ChildNumber" class="col-form-label col-sm-2 offset-sm-3 justify-content-end">子の数字</label>
                <input asp-for="ChildNumber" type="text" class="form-control col-sm-2" readonly="readonly" />
            </div>
            <div class="form-inline form-row mb-2">
                <label asp-for="JudgedResult" class="col-form-label col-sm-2 offset-sm-3 justify-content-end">結果</label>
                <input asp-for="JudgedResult" class="form-control col-sm-2" type="text" readonly="readonly" />
            </div>
        </div>
    </form>
</div>

「子の数字」と「結果」を非表示にしたいので、その2つの要素を囲んでいる親要素のdivに


hidden="hidden"(右辺は省略できるので「hidden」とだけ記述することも可能)

を指定します。これは単にHTMLの記述方法です。

ただし今回は、「ChildIsHidden」プロパティがtrueの場合のみ指定したいので、その制御をC#で記述します。以下のように「@{ }」で囲むことでC#のコードが記述できます。


        @{
            string hiddenAttribute = string.Empty;
            if (Model.ChildIsHidden)
            {
                hiddenAttribute = "hidden=\"hidden\"";
            }
        }

ここでは「hiddenAttribute」という変数を宣言して、if文で条件分岐して文字列を設定しています。条件式の部分がプロパティを参照していますが、今までと違って何かを比較する条件にはなっていません。

ChildIsHiddenというプロパティの型はbool型です。実は、条件式とはbool型になるものであれば何でも指定できます。意味はありませんが、trueとかfalseをそのまま指定することもできます。

今までのような比較する条件式も、条件を満たす場合にはtrue、満たさない場合はfalseというbool型の値に変換されているのです。

エスケープ文字(エスケープシーケンス)

プログラムやHTMLなどでは特別な意味をもつ特殊文字というものがあります。下の部分に注目してください。


                hiddenAttribute = "hidden=\"hidden\"";

本来設定したい文字列は


hidden="hidden"

です。しかし、「"」(ダブルクォーテーション)はほとんどのプログラミング言語では文字列を表すための特別な意味を持っています。

この特殊文字を文字列の一部として記述したい場合は、特別な意味を取り除いて、ただの文字として明示する必要があります。そのために用いるのがエスケープ文字です。エスケープシーケンスとも言います。言語によって異なる場合もありますが、ほとんどの場合は¥記号と組み合わせたものがエスケープ文字として使われます。

今回の例ですと、「¥"」がエスケープ文字で、特別な意味のないただの「"」だということを表しています。

C#で宣言した変数をHTMLに埋め込む

C#部分でhiddenAttribute変数にHTMLに埋め込みたい文字列を設定できました。条件に該当しない場合は初期値のままで空文字です。あとは以下の部分でHTMLに埋め込みます。


        <div class="form-group w-100" @hiddenAttribute>

C#の変数をHTML部分で参照する時には「@」を付けて記述します。Index.cshtml.csの中で宣言した変数やプロパティは「Model.」も付ける必要がありましたが、自分自身のファイル(Index.cshtml)で宣言した変数は「@変数名」で参照できます。

ここまでできたら、実行して非表示になることを確認してください。

続きは・・・

だいぶ長くなってきてしまいましたね。HTMLとCSSの知識がないと、覚えることが多くて大変ですよね。プログラミング学習といってHTML、CSSから始める方も多いようですが、それ自体はプログラミングとは言えず、時間をかけてそれだけを学習するようなものではないんですよね。JavaScriptやPHP、もちろんC#も含むプログラミングをする中で必要な部分だけ一緒に覚えていくものだと思います。実際、私が企業で勤めていた時にも、HTMLやCSSは必要なので自分で調べて使っていましたが、特にまとまった学習時間を取ったことはないです。

さて、前後半で決着をつけるのは厳しくなってしまいました。続きは休憩を挟んでからの延長戦としましょう。お疲れさまでした。

プログラミング基礎講座第6回条件分岐:特定の条件に合う時だけ処理する「if」前のページ

条件分岐:複合条件の指定とネスト次のページプログラミング基礎講座第6回

コメント
  1. この記事へのコメントはありません。

  1. この記事へのトラックバックはありません。

CAPTCHA


ピックアップ

  1. 4Kディスプレイで作業効率UP #3
  2. 4kdisplay for video

最近の記事

  1. recommended pc
  2. おすすめ動画配信サービス3選
  3. 4kdisplay for video
  4. オブジェクト指向の基本概念
  5. basic-knowledge-of-web-app
PAGE TOP