プログラミング入門I
2024.11.18
while 文

Back to index page



  1. 本日の作業内容

  2. 前回の宿題について

    今回は内容に関しては基本的にはできているようでした.細かいことで気になる部分もありましたので,その辺りは後述します.ところで,解答用紙の番号や氏名などを自分の情報に書き換えていない人がちょっと増えてしまいました.まずは,そこを記入してからプログラムに臨みましょう.

    実行時エラー: b2442 b2451

    解答用紙名前間違い: b2442

    解答用紙番号間違い: b2416 b2442

    出力時番号間違い: b2408 b2429 b2442

    ハイフン行なし: b2416 b2451

    以下は例によって問題のあるプログラムの例です.参考にしてください.

    print('\n------------------------\n')
    print("#################################")
    print("#")
    print("# プログラミング入門Ⅰ 宿題 2024,11,11")
    print("# 学生番号: s246058")
    print("# 氏名: 安田 清兵衛")
    print("#")
    print("#################################")
    

    すみませんが,一向に直らないので今回は全世界にさらします.なんとかしてください.

    以下は,出力結果の英単語の綴りが間違っているものの,これでも一部です.しっかり確認するか,何度も言いますが,コピペしてください.

    print(f'Difference between the dry and wet bubles: {result} degree Celsius')
    

    print('Difference between the dry and wet bulbs: 0 degree Celusius')
    

    print(f'Temperture: {num1} degree Celsius')
    print(f'Defference between the dry and wet bulbs: {num2} degree Celsius')
    

    print(f'Temperatur: {num1} degree Celsius')
    

    print(f'Temperture: {tem} degree Celsiius')
    

    print(f'Humidty: {num4} %')
    

    if bulbs == 0:
        print(f'Humidy: 100%')
    elif 24 < tem < 31:
        print(f'Humidy: 92%')
    elif 19 < tem:
        print(f'Humidy: 91%')
    elif 16 < tem:
        print(f'Humidy: 90%')
    else:
        print(f'Humidy: 89%')
    

    print(f'Temperature: [num1] degree Celsius')
    print('Difference between the dry and wet bulbs: [num2] degree Celsius')
    

    上の例は f 文字列の基本である変数名を中カッコ { } でくくるということが理解できていないようです.実行結果は下のように当然おかしいので,自分で確認して直してください.

    Temperature: [num1] degree Celsius
    Difference between the dry and wet bulbs: [num2] degree Celsius
    

    if hot<=20:
        ran=0
    else:
        ran=random. randint(1, 9)
    

    湿度を求めるために利用する温度差ですが,問題では2通りの選択肢しかないようにしてプログラムが簡単になるようにしていたのですが,上の例では9通りになっています.

    if tem==15 or 16:
        hum=100 if diff==0 else 89
    elif tem==17 or 18 or 19:
        hum=100 if diff==0 else 90
    elif tem==20 or 21 or 22 or 23 or 24:
        hum=100 if diff==0 else 91
    elif tem==25 or 26 or 27 or 28 or 29 or 30:
        hum=100 if diff==0 else 92
    else:
        hum=None
    

    よくやる間違いの一つです.最初の if 文の条件式が必ず真になってしまいます.なぜなら比較演算子など無しに単に整数の 16 などがあると,それは 0 ではない値なので真です.結果も以下のように最初の89%が必ず出ます.自分で実行しても気づくはずなのですがね.

    Temperture: 20 degree Celsiius
    Difference between the dry wet bulbs: 1 degree Celsius
    Humidity: 89%
    

    if num2==1 and 25<=num2<=30:
        print(f'Temperature: {num1} degree Celsius \n Difference between the dry and wet bulbs:{num2}  Celsius \n Humidity: 92%' )
    elif  num2==1 and 20<=num2<=24:
         print(f'Temperature: {num1} degree Celsius \n Difference between the dry and wet bulbs:{num2}  Celsius \n Humidity: 91%' )
    elif num2==1 and 17<=num2<=19:
        print(f'Temperature: {num1} degree Celsius \n Difference between the dry and wet bulbs:{num2}  Celsius \n Humidity: 90%' )
    elif num2==1 and 15<=num2<=16:
        print(f'Temperature: {num1} degree Celsius \n Difference between the dry and wet bulbs:{num2}  Celsius \n Humidity: 89%' )
    else:
        print(f'Temperature: {num1} degree Celsius \n Difference between the dry and wet bulbs:{num2}  Celsius \n Humidity: 100%' )
    

    上のような長い行を作ることは推奨しません.条件を全部一緒くたにしようとするからこうなるとも言えますし,f 文字列を使用しないからこうなるとも言えます.上のものほどではないですが,今回 f 文字列を活用しないために文字数が多いプログラムが大量にありました.

    if num2==0:
        print('Humidity:100%')
    elif num1 in [15,16] and num2==1:
        print('Humidity:89%')
    elif num1 in [17,18,19] and num2==1:
        print('Humidity:90%')
    elif num1 in [20,21,22,23,24] and num2==1:
        print('Humidity:91%')
    elif num1 in [25,26,27,28,29,30] and num2==1:
        print('Humidity:92%')
    

    最初の if 文で変数 num が 2 の場合は終わりますので,そうでない場合が elif 以下に落ちてきます.なので,末尾の num2==1 は無駄です.

    if num2 == 0 :
        print('Difference between the dry and wet bulbs: 0 degree Celsius')
        print('Humidity: 100 %')
    elif num2 == 1 or num2 == 2 or num2 == 3 or num2 == 4 :
        if 25 <= num1 <= 30 :
            print('Difference between the dry and wet bulbs: 1 degree Celsius')
            print('Humidity: 92 %')
        elif 20 <= num1 <= 24 :
            print('Difference between the dry and wet bulbs: 1 degree Celsius')
            print('Humidity: 91 %')
        elif 17 <= num1 <= 19 :
            print('Difference between the dry and wet bulbs: 1 degree Celsius')
            print('Humidity: 90 %')
        elif 15 <= num1 <= 16 :
            print('Difference between the dry and wet bulbs: 1 degree Celsius')
            print('Humidity: 89 %')
    

    上のようなものが今回一番多かった例で,f 文字列を使用しないために print 文の文字数が多くなってしまっています.また,条件分けももうちょっと簡単にできます.例えば,最初の elif ですが,残りの条件を全部受け止めるので,単に else で十分です.

    if num2==1:
        print('Difference between the dry and wet bulbs: 0 degree Celsius')
        print('Humidity: 100 %')
    else:
        print('Difference between the dry and wet bulbs: 1 degree Celsius')
        if num1==15 or num1==16:
            print('Humidity: 89 %')
        elif num1==17 or num1==18 or num1==19:
            print('Humidity: 90 %')
        elif num1==20 or num1==21 or num1==22 or num1==23 or num1== 24:
            print('Humidity: 91 %')
        else:
            print('Humidity: 92 %')
    

    こちらも無駄に条件式の多い例です.連続する整数の特定の範囲で真偽を判定するので,== ではなく不等号を用いた比較演算子の方が簡単です.

    num1 = random.randint(15, 30)
    print(f'Temperature: {num1} degree Celsius')
    num2 = random.choices([0, 1], weights = [0.2, 0.8])[0]
    print(f'Difference between the dry and wet bulbs: {num2} degree Celsius')
    if num2 == 1:
        if 25 <= num2 <=30:
            print('Humidity: 92%')
        elif 20 <= num2 <= 24:
            print('Humidity: 91%')
        elif 17 <= num2 <= 19:
            print('Humidity: 90%')
        else:
             print('Humidity: 89%')
    else:
        print('Humidity: 100%')
    

    変数 num2 は値が 0 か 1 しか持ちません.そのため,最初の if 文が真のとき,内側の if や elfi はすべて偽になり, else の処理の実行となります.そのため,結果はおかしいものになります.自分で実行してみて気づくはずですが.

    上のようなうっかりミスを避けるためにはやはり変数名が大事になります.num1 や num2 ではその変数がどのような意味を持つのかが不明です.温度や温度差にふさわしい変数名を使用することで,混同が避けられる可能性が上がります.

    humidity_table =[
        [100,92],
        [100,92],
        [100,92],
        [100,92],
        [100,92],
        [100,92],
        [100,91],
        [100,91],
        [100,91],
        [100,91],
        [100,90],
        [100,90],
        [100,90],
        [100,89],
        [100,89],
        [100,89],]
    def get_humidity(dry_buld_temp,humidity_diff):
        if 15 <= dry_buld_temp <= 30 and humidity_diff in (0,1):
            return humidity_table[30 - dry_buld_temp][humidity_diff]
        else:
            return "Invalid input"
    dry_buld_temp = random.randint(15,30)
    humidity_diff = 0 if random.random() < 0.2 else 1
    humidity = get_humidity(dry_buld_temp,humidity_diff)
    print(f"Temperature: {dry_buld_temp} degree Celsius")
    print(f"Difference between the dry and wet bulbs: {humidity_diff} degree Celsius")
    print(f"Humidity: {humidity} %")
    

    こんな表を自分が用意するのなら,プログラミングの意味はありません.作業が大変でしょう.

    さて,以下のものは今回の絶対にやっちゃダメ!な例です.こちらも何度も言いますが,このように文字数や行数の多いプログラムを私が指示することはありません.だって面倒ですから.プログラミングは人間が楽をするためにあるのであって,大変な単純作業をするためのものではありません.

    if dry_bulb_temp == 30:
        if diff == 0:
            humidity = 100
        elif diff == 1:
            humidity = 92
    elif dry_bulb_temp == 29:
        if diff == 0:
            humidity = 100
        elif diff == 1:
            humidity = 92
    elif dry_bulb_temp == 28:
        if diff == 0:
            humidity = 100
        elif diff == 1:
            humidity = 92
    elif dry_bulb_temp == 27:
        if diff == 0:
            humidity = 100
        elif diff == 1:
            humidity = 92
    elif dry_bulb_temp == 26:
        if diff == 0:
            humidity = 100
        elif diff == 1:
            humidity = 92
    elif dry_bulb_temp == 25:
        if diff == 0:
            humidity = 100
        elif diff == 1:
            humidity = 91
    elif dry_bulb_temp == 24:
        if diff == 0:
            humidity = 100
        elif diff == 1:
            humidity = 91
    elif dry_bulb_temp == 23:
        if diff == 0:
            humidity = 100
        elif diff == 1:
            humidity = 91
    elif dry_bulb_temp == 22:
        if diff == 0:
            humidity = 100
        elif diff == 1:
            humidity = 91
    elif dry_bulb_temp == 21:
        if diff == 0:
            humidity = 100
        elif diff == 1:
            humidity = 91
    elif dry_bulb_temp == 20:
        if diff == 0:
            humidity = 100
        elif diff == 1:
            humidity = 90
    elif dry_bulb_temp == 19:
        if diff == 0:
            humidity = 100
        elif diff == 1:
            humidity = 90
    elif dry_bulb_temp == 18:
        if diff == 0:
            humidity = 100
        elif diff == 1:
            humidity = 90
    elif dry_bulb_temp == 17:
        if diff == 0:
            humidity = 100
        elif diff == 1:
            humidity = 89
    elif dry_bulb_temp == 16:
        if diff == 0:
            humidity = 100
        elif diff == 1:
            humidity = 89
    elif dry_bulb_temp == 15:
        if diff == 0:
            humidity = 100
        elif diff == 1:
            humidity = 89
    else:
        humidity = "不明な組み合わせ"
    

    if temperature == 15:
        humidity = 100 if difference == 0 else 89
    elif temperature == 16:
        humidity = 100 if difference == 0 else 89
    elif temperature == 17:
        humidity = 100 if difference == 0 else 90
    elif temperature == 18:
        humidity = 100 if difference == 0 else 90
    elif temperature == 19:
        humidity = 100 if difference == 0 else 90
    elif temperature == 20:
        humidity = 100 if difference == 0 else 91
    elif temperature == 21:
        humidity = 100 if difference == 0 else 91
    elif temperature == 22:
        humidity = 100 if difference == 0 else 91
    elif temperature == 23:
        humidity = 100 if difference == 0 else 91
    elif temperature == 24:
        humidity = 100 if difference == 0 else 91
    elif temperature == 25:
        humidity = 100 if difference == 0 else 92
    elif temperature == 26:
        humidity = 100 if difference == 0 else 92
    elif temperature == 27:
        humidity = 100 if difference == 0 else 92
    elif temperature == 28:
        humidity = 100 if difference == 0 else 92
    elif temperature == 29:
        humidity = 100 if difference == 0 else 92
    elif temperature == 30:
        humidity = 100 if difference == 0 else 92
    else:
        humidity = None
    

  3. 前回の復習

    授業の最初に if 文に関する確認テストを行います.実際の作業については授業の中で指示します.

  4. while 文

    今回からいよいよ反復処理を扱います.この反復処理こそがプログラムを作る最大の理由の一つです.反復処理というのは,同じ作業を変数の値を変えながら必要回数実行する処理で,いろいろな作業をどのように反復処理に落とし込むか,いわゆるアルゴリズムを考えることが,プログラミングの醍醐味です.

    初回の今回はまずは while 文ということで,変数の初期値,増分(場合によっては減分),実行条件を規定して,処理を繰り返すことが基本です.演習問題を通して学習していきましょう.

    1. while 文の基本
    2. 教科書の p.90にある以下の構成が while 文の基本ですが,実際には以下のように変数の値の規定が必要になることが大半です.

      式で使用する変数初期値の指定
      while 式:
          スイート(処理や増分指定)
      

      初期値や増分が間違っていると,無限ループや1度も実行しないプログラムになってしまいます.

    3. 累算代入演算子
    4. 一般的に代入演算子と呼ばれるもので,反復処理において非常に重要です.まず理解しておかなければいけないこととして,プログラミングは数学と異なる部分があり,例えば以下のような表現があります.

      a = a + 1
      

      数学的には認められない表現ですが,プログラミングでは等号の記号は等しいことではなく,代入ですので,上の式は変数 a に 1 を加えたものを新たに変数 a に代入するということで,結局は変数 a の値を 1 増やすという操作になります.このような処理があまりに多く使用されるので,その操作にはインクリメントという名前がついています.そのため,以下のように簡略化して表現することが行われます.

      a += 1
      

      このような代入演算子はすべての演算子に対して用意されていますので,下記を参考に今後も使いこなしてください.

      記号 意味 動作例 a = 5 の場合
      +=左辺の変数の値を右辺の値だけ増やすa += 5 → a の値は 10
      -=左辺の変数の値を右辺の値だけ減らすa -= 2 → a の値は 3
      *=左辺の変数の値を右辺の値倍するa *= 3 → a の値は 15
      /=左辺の変数の値を右辺の値分の 1 にする(実数)a /= 4 → a の値は 1.25
      //=左辺の変数の値を右辺の値分の 1 にする(整数)a //= 4 → a の値は 1
      %=左辺の変数の値を右辺の値で割った余りにするa %= 2 → a の値は 1

    5. 無限ループになってしまったら
    6. 反復処理のプログラムを作成している途中で間違って無限ループを作ってしまうことはよくあります.通常はキー操作の Ctrl + C 終了させることができますが,IDLEを使用して run module により実行したときにはそのキー操作ではちゃんと止まってはくれないときがあります.その場合にはIDLEの画面をクリックしていったん処理を止めて,ウィンドウ右上の赤い×ボタンをクリックして強制的に終了させるか,しばらく待って Python のプロセス自身がお亡くなりになった状態で,やはり×ボタンで終了させるしかないようです.


      図1 無限ループを走らせておいた場合にIDLE画面をクリックした状態


      図2 ×ボタンを押したら出てくるダイアローグ

      教科書の p.7 には Ctrl + Z Enter で止まるとありますが,それではどうやら止まらないようです.
  5. 演習

    今回の演習問題です.

  6. 本日のまとめ

  7. 宿題

    宿題が公開されるのは明日火曜日10:00の予定で,締切りは来週の月曜日11月25日の10:00です.レポート提出システムを使用します.

  8. 次回の予習範囲

    次回は教科書のp.102-114の範囲を学習しますので,予習をしてきてください.


目次ページに戻る