Lesson06 ループ(2) while文

イメージ画像

もうひとつのループwhileを学ぼう

  • while ループ
    • 途中でスキップする continue
    • ループそのものを抜ける break
    • 無限ループ

今使うソースコードはここからまとめてダウロードできます。 ダウンロードfile_download

前回の復習

前回は for ループ文について学びました。これによって、繰り返しの処理をさせることができるようになりました。

前回出た重要キーワード

  • for 文
  • ループ変数
  • continue
  • break
  • ネスト
  • range(10,20) , range(10) ,range(1,10,3)
  • ループ変数のインクリメント
  • ループ変数はループの中で自動的に変化する変数のことでした。変数名は自由に付けられます
  • break は for ループを中止して抜ける場合に使いました。
  • continue は for 文の中で、スキップしてループは続けるものの、次のループに移るときに使いました。
  • ネストは入れ子のことで、if のように入れ子にできるのでした。

前回演習の3 FizzBuzzを100まで列記するプログラム

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
print("今から100までFizzBuzzのゲームをします。")

for suuzi in range(1,101):
    print(str(suuzi)+"番目の人: ",end="")
    if suuzi % 15 == 0:
        print("FizzBuzz")
    elif suuzi % 3 == 0:
        print("Fizz")
    elif suuzi % 5 == 0:
        print("Buzz")
    else:
        print(str(suuzi))

実行結果

 1
 2
 3
 4
 5
 6
 7
 8
 9
1番目の人: 1
2番目の人: 2
3番目の人: Fizz
4番目の人: 4
5番目の人: Buzz
…中略…
198番目の人: Fizz
199番目の人: 199
200番目の人: Buzz

1while ループ

この章のキーワード

  • while ループ
  • continue
  • break

1.1 whileループの使い方

while は for 文と同じように繰り返しを行うループです。for がループ変数を 1 ずつあるいは3 つずつ変化させるのに対して、while はもっと柔軟に変化させられます。
ループ変数が増えていくことをインクリメント(increment)すると言います。反対にループ変数が減ることをデクリメント(decrement)すると言います。for文ではループ変数が自動的にインクリメントしましたが、while文ではループ変数は必須ではなく、インクリメントするときは自分で増やさないといけません。

ループ処理はインデントしなければいけませんが、これも for 文と同じです。

基本構造

具体例

具体例2

1 から 10 までの整数を print 関数で列記するソース(lessson006_01.py)
1
2
3
4
i=0
while i <11:
    print(i)
    i= i+1

実行結果

 1
 2
 3
 4
 5
 6
 7
 8
 9
10 
11
0
1
2
3
4
5
6
7
8
9
10

for 文は while 文でも書けます。Lesson005で for 文で書いたコードを while で書き直してみましょう。

1 からある整数までの総和を for ループで求める( lessson006_02A.py )

 1
 2
 3
 4
 5
 6
 7
s = 0
for i in range(1,1001) : 
    print(str(i)+”回目のループ”)
    s = s + i    

print(“1000までの整数の和は”,’’)
print(str(s)+“です”)

1 からある整数までの総和を whileで求める( lessson006_02B.py )

 1
 2
 3
 4
 5
 6
 7
 8
s = 0
i = 1
while i < 1001 :
    print(str(i)+”回目のループ”)
    s = s + i
    i = i+1 # i += 1 
print(“1000までの整数の和は”,’’)
print(str(s)+“です”)

実行結果

 1
 2
 3
 4
 5
 6
 7
1回目のループ
2回目のループ
…中略…
999回目のループ
1000回目のループ
1000までの整数の和は
500500です

forループでは i は自動的に増えました。これをインクリメントといいます。
while は自動的にインクリメントされません。

1.2 continueとbreak

continue と break の使い方は for 文と同じです。

条件にあったときに break でループを抜ける( lesson006_03.py )

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
s = 0
i=1
while i < 1001 : print(str(i)+"回目のループ") if i >20 :
        break

    s = s + i
    i = i+1
    
print("whileでsは加算されて")
print(str(s)+"になりました")

実行結果

 1
 2
 3
 4
 5
 6
1回目のループ
2回目のループ
…中略…
20回目のループ
whileでsは加算されて
210になりました。

1.3 for文とwhile文の使い分け

さて、では for と while はどのように使い分けたらよいのでしょうか。while 文を使う典型的な例は、以下のような場合です。

3 秒間 while ループで処理する例( lesson006_04.py )

time関数は、time.time() でその関数が呼ばれた時の時刻を、返す関数です。正確に言うと、1970 年 1 月1 日0 時0 分0 秒から何秒経過したか、数字で返します。

このソースコードはmuエディターで実行すると正しく動きません。先生のデモを見てください。(ターミナルで実行します)

 1
 2
 3
 4
 5
 6
 7
 8
import time
start_time = time.time()
end_time = start_time +3

while time.time() < end_time :
    print(str(time.time()))

print("3秒経ちました")

実行結果

 1
 2
 3
 4
 5
 6
 7
 8
 9
10 
1620464242.3407645
…中略…
1620464245.3407645
1620464245.3407645
1620464245.3407645
1620464245.3407645
1620464245.3407645
1620464245.3407645
1620464245.3407645
3秒経ちました

つまりループ変数のインクリメントで対応できないような条件を扱うときは whileループを使います。例えば以下のような場合があるでしょう。

  • 一定時間たったら処理する
  • プログラムの利用者が正しい値を入力するまで入力をやり直させる
  • インターネットからダウンロードするのに時間がかかるファイルをダウンロードできるまで処理を続ける

人が正しく 10 以下の数字を入れるまで何度でも入力を促す( lesson006_05.py )

 1
 2
 3
 4
 5
 6
 7
num = 1000 #ひとまず初めのwhileが実行されるようにおおきな数をセットしておく
while num > 10 :
    print("10以下の数字を入力してください。")
    num = input()
    num = int(num)

print("正しい値の入力ありがとうございます")

実行結果

 1
 2
 3
 4
 5
 6
 7
10以下の数字を入力してください。
11
10以下の数字を入力してください。
21
10以下の数字を入力してください。
3
正しい値の入力ありがとうございます

1.4 無限ループ

while の条件にずっと終わらない条件を入れてるとループが終わりません。例えば下記のソースコードは永久にループが回り続けます。このようなループを無限ループと呼びます。

 1
 2
 3
 4
 5
 6
num = 10
while num > 1 :
     num = num + 1
print(str(num) + "です")

# このプログラムは暴走して永遠に終わりません。CtrlをおしながらCで強制終了させます。

もし、まちがって無限ループを作り、実行してしまった場合は、Ctrl ボタンをおしながら Cボタンを押し、強制的にプログラムを停止してください。

演習の時間

演習の解答はここからダウンロードできます。ダウンロードfile_download

演習1

ある変数はランダムに 1 から 100 までのいずれかの数をとる数だとします。
この変数を 10000 回作り、90 以上の数が何回でるか調べましょう。
enshu006_01.pyの名前で保存しましょう。
for 文でもかけますが、while で書いてみましょう。

期待される動作

1回目のループ:33
2番目のループ:28
・・・・
10000番目のループ:955
10000回のうち、90以上の数が出現した回数は1001回でした。

下記のソースコードのはてなを埋めてみましょう。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import random

i=0
count =0
while i < 10000 :
    i +=1
    num = random. ????
    print("ループ"+str(i)+"回目: "+str(num))
    if num >90 :
        count = ????

print("10000回のうち、90以上の数が出現した回数は"+str(count)+"回でした")

ヒント

count は何を保持する変数でしょうか?

演習2

この演習は for 文の演習です。while は使いません。

Turtle というモジュールは図形を描画する機能を提供するモジュールです。下記のようにカメのマークが画面を動いて線を引きます。

正方形を描画するソースコードは下記になります。turtleの中にある次の3つの関数を使います。

  • forward(200) は 200 ピクセルだけ線を引くという関数で、
  • left(90) は左回転(反時計回り)に 90° 回転する関数です。
  • done()は描画を終了する関数です。(これをかかないと描画後すぐにWindowが閉じてしまいます)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import turtle

turtle.forward(200)
turtle.left(90)
turtle.forward(200)
turtle.left(90)
turtle.forward(200)
turtle.left(90)
turtle.forward(200)
turtle.left(90)

turtle.done()

このソースをまずは for 文を使って簡潔に書き直してください。
enshu006_02_rec.py の名前で保存してください。

そのうえで、回転する left() の部分を書き換えて、三角形、星形(☆)や正六角形を描画してみましょう。
それぞれ、enshu006_02_tri.py、enshu006_02_star.py、 enshu006_02_hexa.pyの名前で保存してください。

注意)本演習はマシンに Python-Tk がインストールされていることが前提です。もしインストールされていなければ 以下のコマンドを打って、インストールしてください

1 sudo apt-get install python-tk

期待される動作

三角形の描画結果

正六角形の描画結果

星形の描画結果

大人のあなたへ

Lesson06までPythonというプログラミング言語を学んできて、たくさんの語彙が出てきました。単語や構文を覚えるのはまるで英語を学ぶようです。
人工言語であるプログラミング言語も英語も学び方は似ています。

さて、こんなことを考えたことはありませんか。自然言語である日本語や英語はたくさんの語彙が生まれては消えていきますが、プログラミング言語では語彙は増えるばかりだろうか?
そうだとすると誰も完璧にマスターできないのではないか?語彙や構文や最小の方がいいのではないか?
これは一理ある考え方です。今までたくさんのプログラミング言語が現れてきましたが、機能を追求していくと肥大化し、たくさんの語彙や構文が増えがちです。

逆にシンプルにするならどこまでシンプルになるんだろうか?と考えたことはありますか?
実はこれまで学んだifなども含めてwhileがあれば一通りの構文ができることが分かっています。
もし興味があれば『チューリングの考えるキカイ ~人工知能の父に学ぶコンピュータ・サイエンスの基礎』(技術評論社) とうい本を読んでみるといいでしょう。