0から始めるPython基礎講座

【Python入門】変数〜条件分岐まで確認テスト!

りっくん

こんにちは、りっくんです。

今回は、これまで学んだ変数〜条件分岐までの単元で学んだことをアウトプットするため
みなさんにとある課題を出そうと思います。

やっていくうちにわからないところが出てきたら、今までの講座を振り返って学び直していきましょう!

課題

これから2つの課題を課しますので、チャレンジしてみましょう。

解説

いかがでしたでしょうか?

この課題はプログラミングを学ぶ上でよく出題される小テストでして
変数やデータ型の理解、真偽値や繰り返し文の実装方法を再確認できるものとなっております。

では、各問題の回答と解説をいたします。

問題1

解答例

for i in range(1, 101):
    print(i, end=' ')
    if i % 10 == 0:
        print()

出力結果

一行ずつ解説していきます。

for i in range(1, 101):


最初の1行目はfor文の定義箇所となります。
for文は変数を用意して、オブジェクトを指定する必要がありましたよね。
そして、今回は1から100という明確な数値を指定する必要があるためrange関数を使用していきます。

for i in range(1, 101):
    print(i, end=' ')


2行目で出力していきますが、ここで初めて見るものがありますね。
print(I, end=’ ‘)の「end」という部分です。

print()メソッドはただ単に文字を出力するだけでなく、オプションを付与することで挙動が変わっていきます。

以下のように、endオプションを指定せずオブジェクトのみ指定すると

print(i)

<出力結果>

1
2
~省略~
9
10

11
12
~省略~…

といったように1~10まで横並びに出力、改行して11~20まで横並びに出力する処理が
実現できなくなってしまいます。

なのでend=’ ‘オプションが必要になってくるわけですね。

endオプションを指定してもカンマの間にスペースを入れなければ
挙動としては指定なしと変わらないため
end=’ (スペース)’を入れる必要があります。

その他のオプションについては以下にまとめております。

オプション名説明・解説
sepprint()メソッドで複数の要素をオブジェクトとして指定した時
各要素毎にsepで指定した文字を入れ込みます。
print(1, 2, 3, sep=’¥n’)と指定すると、出力時に1,2,3の間に
改行が挟み込まれます。
sep = separate(分ける)という意味
end出力されたオブジェクトの末尾の文字列を指定します。
上記の解答例ではprint(i, end=’ ‘)と指定しているため1ループ毎に改行して
出力することなく、連続で出力することができます。
※デフォルト(endを指定しない場合)では、改行が選択されます。
fileprint()で示したオブジェクトの出力結果をコンソール側に出すのではなく、
fileで指定したファイル内に結果を書き出します。
デフォルトではfile指定なしとして、コンソール上に出力されます。
fileを指定すると、コンソール上には結果が出力されません。
flush通常、print()メソッドはバッファを設けており
print()したいデータをある程度保持して、解放するといった特徴があります。
flush = Trueと指定してあげることにより、バッファを設けず即時出力することができます。

※バッファ:簡単にいうと「データのやり取りを行う際、プログラム内でデータを一時的に溜め込む記憶箇所」を指します。
⇨これによりゆとりが生まれ、処理が混雑することなくスムーズにできるわけです。
※後述します。

そして3〜4行目

    if i % 10 == 0:
        print()


今回、「10ずつ改行して出力しなさい」と指定されているため
改行する際の条件分岐を行うことが鍵となります。

if文にする際、言い換えると「変数iから10を割った時の余りが0であれば改行しますよ」と
命令を出せば良いため

四則演算でならった「%」を使って表現してあげれば良いです。
(%の意味がよくわからなければ復習しましょう!)

そして最後のprint()メソッド。
特にオプションを指定していなければ
1ループ毎に改行して文字を出力するのがprint()メソッドの特徴なので、それを利用します。

そうすることで「変数iから10を割った時の余りが0であれば改行する」という処理が実現できるわけです。

コラム -print(flush=True)の挙動について

問題1の模範解答をもとに、少し改良したソースコードを例として挙げます。
改良点として、timeモジュールといった時間を操る処理を追加して
timeモジュールのsleep()メソッドを使って0.5秒出力毎に遅延させます。

import time

for i in range(1,101):
    print(i, end='  ')
    time.sleep(0.5)
    if i % 10 == 0:
        print()


実際に実行してみましょう。
出力結果は問題1と同様ですが、こちらの場合は1~10までの要素が約5秒かけて一気に出力されています。

では1~10までの要素を1つずつ、0.5秒かけて順番に出力させるにはどうすれば良いか。

そこでprint()メソッドのオプション「flush=True」を使用するわけです。
オプションを追加したソースコードがこちらです。

import time

for i in range(1,101):
    print(i, end='  ', flush=True)
    time.sleep(0.5)
    if i % 10 == 0:
        print()


実際に実行してみましょう。
明らかに出力時の挙動が異なっており、「要素を1つずつ、0.5秒かけて出力する」というのも実現できましたね。

flushもそうですが、print()メソッドを使用する際は「ただ単に文字を出力するだけ」と捉えるだけでなく
end, sep, file, flushを使う必要があるかどうかを判断する必要があるわけです。

問題2

この問題でのポイントとして、while文内の処理からどのようにしてループを抜け出せるかというところにあります。

早速模範解答を掲載しますので確認していきましょう。

cnt = 1
while True:
    if cnt == 101:
        break
    if cnt <= 10:
        print(cnt, end='  ')
    else:
        print(cnt, end=' ')
    if cnt % 10 == 0:
        print()
    cnt = cnt + 1


まず、while文ではbreak文を使用しなければ無限ループに陥ってしまい
いつまで経っても処理が終わらないといった特徴があったかと思います。

for文を使用する際は必ず変数を用意してから繰り返し処理を行うといったものがありましたが、while文にはそれがありません。

ですので、自分で変数を準備してループを制御してあげる必要があるわけなのです。
それが1行目に記しております。

cnt = 1
while True:
    if cnt == 101:
        break


今回、変数名はcountを示す「cnt」として用意しました。
さらに1〜100までをループ処理していくために初期値として1と定めております。

cntが101に差し掛かった際にbreakすれば、ちょうどprint()メソッドで出力する数値は100で止まりますね。

ただ、このままだとcnt内の数値が1のままで
いつまで経っても101までには辿り着けません。

なので、while文内の処理の最後にcntを1増やす処理が必要になってくるわけです。
それが下記に示す処理内容となります。

    cnt = cnt + 1


そのほかは問題1が正しければ、それを流用する形で処理を組めば問題なさそうですね。

以上が解説となります。

最後に

確認テストお疲れ様でした。

テストを振り返ってみて、「まだまだ理解が及んでいないな」と感じるようでしたら再度振り返ってみてください。