《06》制御構造(2)if 文〈Python 2.x 版〉
実録:はじめてのプログラミング《記事一覧》
《06》制御構造(2)if 文
関連記事
今日の進捗
Comment | |
---|---|
本人:野中 | OmniGraffleだと資料を使い回したいときに便利というのを実感する1日でした。 |
担当:本間 | 今日のテクは、私が伊藤さんから教わったもののひとつです。ほかにも教わったことはたくさんあるけど、焦らずに少しずつしっかりと身につけていこうね。(^^) |
スケール課題(2)if 文
引き続き、関数 scale が完成するまでの過程を紹介します。
《step 2》引数に指定した値と同じ数の文字 "." を出力するとともに、5つおきに "+" を出力します。
まず、step 2 の動作を確認します。
def step2(): for e in range(11): print "%2d"%e, scale(e) >>> step2() 0 1 . 2 .. 3 ... 4 .... 5 ....+ 6 ....+. 7 ....+.. 8 ....+... 9 ....+.... 10 ....+....+
すると、引数に指定した値と同じ数の "." を出力するとともに、5つおきに "+" を出力するのが分かります。
さらに、ここに至るまでの過程を段階的に示します。まず、
def scale(n): # step 2A s = "" for e in range(n): if e%5==0: s += "+" s += "." return s
if に続く条件式 e%5==0 を満たすときだけ、"." の代わりに "+" を連結します。この条件式を満たすのは、変数 e の値が5の倍数になるときだけです。すると、5つおきに "+" を出力するはずです。ところが、
>>> print 6,scale(6) 6 +.....+.
この結果には、いくつかの問題があります。
何が問題か
ここで、if 文の流れを図解すると、次のようになります。
ある条件を満たすときには、if ブロック内にあるコードを一度だけ実行します。そのため、条件式 e%5==0 を満たすとき、つまり変数 e の値が5の倍数になるときだけ、"." の代わりに "+" を連結します。
ところが、if ブロックを抜けた後で、それに続くコードを実行するため、さらに "." を連結します。ステップ2の実行結果として、末尾に "." が出力されたのは、そのためです。また、先頭に "+" が出力されるのも考えものです。そこで、これらの問題に対処すると、
def scale(n, offset=1): # step 2B s = "" for e in range(offset, n+1): if e%5==0: s += "+" else: s += "." return s
第2引数 offset には、規定値として =1 を設定しています。そのため、この引数を省略して scale(n) を呼び出すと、scale(n,1) を呼び出したものと見なされます。ステップ2の実行結果として、scale(0) のとき何も出力されないのは、そのためです。
ある条件を満たさないときには、else ブロック内にあるコードを一度だけ実行します。そのため、条件式 e%5==0 を満たさないとき、つまり変数 e の値が5の倍数でないときには、"." を連結します。その結果として、"." または "+" のどちらか一方だけが連結されて、step2 で示した結果が得られます。
何が問題か
次に進む前に、ここで少しコードに手を加えて、その動作を確認します。
def scale(n, offset=1): # step 2C s = "" for e in range(offset, n+1): c = "." if e%5==0: c = "+" s += c return s
一時変数 c を用意して、これで出力したい文字列を管理します。すると、変数 c の値が何か(実現方法)とは無関係に、文字列を連結する部分のコードを記述できる(抽象化)ようになります。