4日目のゴールと今日やること
4日目のテーマは
「while と終了条件を“1か所に閉じ込めて”、コードをきれいに整理すること」です。
ここまでであなたは、
終了と入力で終わる
空文字や重複をスキップする
最大件数・最大回数で終わる
ユーザー都合とアプリ都合の終了条件を分けて考える
というところまで来ています。
今日はそこから一歩進んで、
終了条件を関数にまとめる
「続けるかどうか」をフラグで表現する
while の中身を“読みやすく分割する”
という「整理の仕方」を学びます。
まずは“ごちゃっとした while” をあえて書いてみる
条件が増えると while はすぐに読みにくくなる
例えば、こんな仕様を全部入れたとします。
終了 / end で終わる
空文字はスキップ
重複はスキップ
メモは最大 5 件まで
入力チャンスは最大 10 回まで
素直に全部書くと、こうなります。
memos = []
max_memos = 5
max_trials = 10
trial_count = 0
while True:
print(f"{trial_count + 1} 回目の入力(最大 {max_trials} 回)")
raw = input("メモを入力してください(終了 / end で終わり):")
text = raw.strip()
normalized = text.lower()
trial_count += 1
if normalized == "終了" or normalized == "end":
print("ユーザーによって終了されました")
break
if text == "":
print("空のメモは保存しません")
if trial_count >= max_trials:
print("入力回数の上限に達したので終了します")
break
continue
if text in memos:
print("同じメモがすでに登録されています")
if trial_count >= max_trials:
print("入力回数の上限に達したので終了します")
break
continue
memos.append(text)
if len(memos) >= max_memos:
print("メモの最大件数に達したので終了します")
break
if trial_count >= max_trials:
print("入力回数の上限に達したので終了します")
break
print("入力されたメモ一覧:")
for memo in memos:
print("-", memo)
Python動きとしては正しいですが、
正直、かなり“ギュウギュウ詰め”です。
ここから「整理する」というのが、4日目のテーマです。
終了条件を“関数に追い出す”という発想
日本語でやりたいことをもう一度整理する
やりたいことを、あえて日本語だけで書き直します。
ユーザーが終了コマンドを入力したら終わり。
メモ数が上限に達したら終わり。
入力回数が上限に達したら終わり。
これを while の中にベタ書きするのではなく、
「終了すべきかどうかを判定する関数」にまとめます。
should_stop という関数を作る
def should_stop(normalized_text, memos, max_memos, trial_count, max_trials):
if normalized_text == "終了" or normalized_text == "end":
print("ユーザーによって終了されました")
return True
if len(memos) >= max_memos:
print("メモの最大件数に達したので終了します")
return True
if trial_count >= max_trials:
print("入力回数の上限に達したので終了します")
return True
return False
Pythonこの関数は、
終了すべきなら True
まだ続けてよいなら False
を返します。
「終了条件」という考え方を、
一つの関数に“閉じ込めた”イメージです。
while の中から「終了判定」を追い出した形
本体のループがかなりスッキリする
さっきの関数を使って、
メインの while を書き直します。
def should_stop(normalized_text, memos, max_memos, trial_count, max_trials):
if normalized_text == "終了" or normalized_text == "end":
print("ユーザーによって終了されました")
return True
if len(memos) >= max_memos:
print("メモの最大件数に達したので終了します")
return True
if trial_count >= max_trials:
print("入力回数の上限に達したので終了します")
return True
return False
memos = []
max_memos = 5
max_trials = 10
trial_count = 0
while True:
print(f"{trial_count + 1} 回目の入力(最大 {max_trials} 回)")
raw = input("メモを入力してください(終了 / end で終わり):")
text = raw.strip()
normalized = text.lower()
trial_count += 1
if should_stop(normalized, memos, max_memos, trial_count, max_trials):
break
if text == "":
print("空のメモは保存しません")
continue
if text in memos:
print("同じメモがすでに登録されています")
continue
memos.append(text)
print("入力されたメモ一覧:")
for memo in memos:
print("-", memo)
Pythonwhile の中を眺めると、
だいぶ“見通し”が良くなっているのが分かると思います。
終了条件は should_stop(...) に任せる。
入力チェック(空文字・重複)は while の中で見る。
メモを追加する処理もはっきり見える。
「何がどこで行われているか」が、
かなりクリアになりました。
深掘り:関数にすることで何が嬉しいのか
1つの場所に「終了のルール」が集まる
終了条件を関数にまとめると、
終了のルールを変えたいときに、見る場所が 1 か所で済む
というメリットがあります。
例えば、
「終了コマンドを ‘quit’ も許可したい」
「最大件数のメッセージを変えたい」
となったとき、should_stop だけを見ればよくなります。
while の中をあちこち探してif ... break を探す必要がなくなるわけです。
テストしやすくなる
もう一つ、実務的なメリットとしては、
should_stop だけを単体でテストできる
という点があります。
例えば、Python の対話モードで、
should_stop("終了", [], 5, 0, 10)
should_stop("end", [], 5, 0, 10)
should_stop("hello", ["a", "b", "c", "d", "e"], 5, 3, 10)
Pythonなどを試して、
True / False の返り値を確認できます。
「終了条件」というロジックを、
while から切り離して“部品”として扱えるようになる。
これが関数化の大きな意味です。
フラグ変数で「続けるかどうか」を表現するパターン
while True をやめて「フラグで回す」
もう一つ、整理の仕方として
「フラグ変数を使う」という方法があります。
例えば、こういう書き方です。
memos = []
max_memos = 5
max_trials = 10
trial_count = 0
running = True
while running:
print(f"{trial_count + 1} 回目の入力(最大 {max_trials} 回)")
raw = input("メモを入力してください(終了 / end で終わり):")
text = raw.strip()
normalized = text.lower()
trial_count += 1
if normalized == "終了" or normalized == "end":
print("ユーザーによって終了されました")
running = False
continue
if len(memos) >= max_memos:
print("メモの最大件数に達したので終了します")
running = False
continue
if trial_count >= max_trials:
print("入力回数の上限に達したので終了します")
running = False
continue
if text == "":
print("空のメモは保存しません")
continue
if text in memos:
print("同じメモがすでに登録されています")
continue
memos.append(text)
print("入力されたメモ一覧:")
for memo in memos:
print("-", memo)
Pythonここでは、
running が True の間だけ while が回る
終了したくなったら running = False にする
というスタイルです。
break とフラグの違いを整理する
break は「その場でループを抜ける」。
フラグは「次の条件チェックでループが止まるようにする」。
どちらも「ループを終わらせる」手段ですが、
書き味が少し違います。
個人的には、
終了条件が少ない → break で十分
終了条件が多い → 関数化 or フラグで整理
という使い分けがしっくりきます。
while の“責務”を意識して分割する
while に全部押し込まない
4日目で一番伝えたいのは、ここです。
while の中に、
全部のロジックを押し込まない。
終了条件は関数にまとめる。
入力チェックは別の関数にしてもいい。
フラグで「続けるかどうか」を表現してもいい。
例えば、こんな分割もできます。
def is_empty(text):
return text == ""
def is_duplicate(text, memos):
return text in memos
Pythonとしておいて、
if is_empty(text):
print("空のメモは保存しません")
continue
if is_duplicate(text, memos):
print("同じメモがすでに登録されています")
continue
Pythonと書く。
こうすると、
「何を判定しているのか」が
関数名だけで伝わるようになります。
4日目の流れを言葉でまとめる
今日やったことを、コードではなく「考え方」で整理します。
終了条件が増えると、while の中はすぐにごちゃごちゃする。
そのままでも動くけれど、読みづらく、変更しづらい。
そこで、
終了条件を should_stop のような関数にまとめる。
while の中では「終了すべきか?」だけを聞く。
あるいは、
running のようなフラグで「続けるかどうか」を表現する。
さらに、
空文字チェックや重複チェックも、
小さな関数に分けることができる。
こうして、
while は「入力の流れ」を書く場所。
終了条件は「終わるルール」を書く場所。
入力チェックは「入力の妥当性」を書く場所。
というふうに、
“役割ごとに場所を分ける”という発想が出てきます。
今日いちばん深く理解してほしいこと
4日目の本質は、
「while の中に“全部”を書かなくていい。
終了条件やチェック処理は、関数やフラグに“逃がして”いい」
ということです。
終了条件を関数にまとめると、
ルールを変えたいときに迷子にならない。
フラグで「続けるかどうか」を表現すると、
ループの意図が読みやすくなる。
あなたはもう、
「while が書ける人」から一歩進んで、
「while を設計できる人」 に近づいています。
5日目以降は、このメモアプリに
「保存先(ファイル)」や「日付」などを足していきながら、
今の設計力をさらに使っていく流れにしていきましょう。


