7日目のゴールと今日やること
7日目のテーマは
「while と終了条件を“機能ごとに増やしても、破綻しない形でまとめきる”こと」です。
ここまでであなたは、
- 単純な繰り返し入力
- 空文字・重複・最大件数・最大回数
- メニュー構造(外側 while と内側 while)
- エラー時のやり直しと終了条件の分離
まで来ています。
7日目では、仕上げとして
- 「検索」機能
- 「削除」機能
を追加しつつ、
- while を増やしても、終了条件が迷子にならない書き方
- 「どの while が、どこまでを担当しているか」を意識した設計
を確認していきます。
全体像:機能が増えても「外側の while」は変えない
まずはメニューを拡張したイメージ
今日のメニューは、こういう感じにします。
1: メモを追加する
2: メモ一覧を見る
3: メモを検索する
4: メモを削除する
5: 終了する
ここで大事なのは、
「メニューの選択肢が増えても、外側の while の“役割”は変えない」
ということです。
外側の while の責任は、あくまで
「ユーザーに次にやりたいことを選んでもらう」
「終了を選んだらアプリ全体を終わらせる」
だけです。
外側の while(アプリ全体)のコード
まずは骨組みだけ書いてみる
def ask_menu_choice():
while True:
print("==== メニュー ====")
print("1: メモを追加する")
print("2: メモ一覧を見る")
print("3: メモを検索する")
print("4: メモを削除する")
print("5: 終了する")
choice = input("番号を入力してください:").strip()
if choice in ("1", "2", "3", "4", "5"):
return choice
print("不正な入力です。1〜5 の番号を入力してください。")
memos = []
running = True
while running:
choice = ask_menu_choice()
if choice == "1":
add_memos(memos, max_memos=20)
elif choice == "2":
show_memos(memos)
elif choice == "3":
search_memos(memos)
elif choice == "4":
delete_memo(memos)
elif choice == "5":
print("アプリを終了します")
running = False
Pythonここでの終了条件は、たったひとつです。
choice が “5” のとき、running = False にして外側の while を終わらせる。
それ以外は「どの機能を呼ぶか」を決めているだけ。
外側の while に、余計な終了条件を増やさないのがポイントです。
メモ追加機能の while と終了条件の整理
add_memos の役割を言葉で決める
add_memos の責任は、
「メモ追加モードの中で、繰り返し入力を管理する」
「このモードをいつ終わるかを決める」
です。アプリ全体を終わらせる責任はありません。
コードと終了条件
def add_memos(memos, max_memos=20):
print("メモ追加モードです。終了 / end でメモ追加を終わります。")
print(f"現在 {len(memos)} 件 / 最大 {max_memos} 件")
while True:
raw = input("メモを入力してください:")
text = raw.strip()
normalized = text.lower()
if normalized in ("終了", "end"):
print("メモ追加モードを終了します")
break
if text == "":
print("空のメモは保存しません")
continue
if len(text) > 50:
print("50文字を超えています。もう少し短くしてください。")
continue
if text in memos:
print("同じメモがすでに登録されています")
continue
if len(memos) >= max_memos:
print("メモの最大件数に達しました。これ以上追加できません。")
break
memos.append(text)
print(f"追加しました(現在 {len(memos)} 件 / 最大 {max_memos} 件)")
Pythonこの while の終了条件は、はっきり 2 種類です。
ユーザー終了条件:終了 / end と入力されたら break。
アプリ終了条件:最大件数に達したら break。
それ以外は「やり直し条件」(continue)です。
ここで意識してほしいのは、
「この while は“メモ追加モードの中だけ”を担当している」
ということ。
アプリ全体の終了は、外側の while に任せています。
メモ一覧表示は「while を持たない」機能
show_memos の責任は“表示だけ”
一覧表示は、繰り返し入力ではないので while は不要です。
def show_memos(memos):
print("==== メモ一覧 ====")
if not memos:
print("まだメモがありません")
return
for i, memo in enumerate(memos, start=1):
print(f"{i}: {memo}")
ここには終了条件はありません。
「やることを一回やって終わる」だけの関数です。
こういう“単発処理”と、
“繰り返し処理(while が必要なもの)”を
頭の中で分けておくと、設計が楽になります。
検索機能の while と終了条件
search_memos の仕様を日本語で決める
検索機能のルールを先に言葉にします。
検索キーワードを入力してもらう。
空文字なら「検索をやめる」。
キーワードを含むメモだけを表示する。
検索が終わったら、メニューに戻る。
ここでは「繰り返し検索するかどうか」をどうするか、選べます。
今回はシンプルに「1 回検索したら終わり」にします。
コードと終了条件
def search_memos(memos):
if not memos:
print("検索できるメモがまだありません")
return
keyword = input("検索キーワードを入力してください(空 Enter でキャンセル):").strip()
if keyword == "":
print("検索をキャンセルしました")
return
print(f"「{keyword}」を含むメモを検索します")
hits = []
for i, memo in enumerate(memos, start=1):
if keyword in memo:
hits.append((i, memo))
if not hits:
print("該当するメモはありませんでした")
return
print("=== 検索結果 ===")
for index, memo in hits:
print(f"{index}: {memo}")
Pythonここには while はありません。
終了条件はすべて「return」で表現されています。
メモがない → すぐ return。
キーワードが空 → すぐ return。
ヒットがない → 結果を出して return。
この関数の責任は
「1 回の検索を完了させること」だけなので、
while は不要、終了条件は return で十分です。
削除機能の while と終了条件
delete_memo の仕様を日本語で整理する
削除は、少しだけ複雑です。
メモ一覧を番号付きで表示する。
削除したい番号を入力してもらう。
空 Enter なら削除モードをやめる。
数字でない入力や範囲外の番号なら、やり直してもらう。
正しい番号なら、そのメモを削除して、削除結果を表示する。
ここでは「削除モードの中で、番号入力を繰り返す」ために while を使います。
コードと終了条件
def delete_memo(memos):
if not memos:
print("削除できるメモがまだありません")
return
while True:
print("==== メモ一覧(削除用) ====")
for i, memo in enumerate(memos, start=1):
print(f"{i}: {memo}")
raw = input("削除したい番号を入力してください(空 Enter で削除モード終了):").strip()
if raw == "":
print("削除モードを終了します")
break
if not raw.isdigit():
print("数字を入力してください")
continue
index = int(raw)
if not (1 <= index <= len(memos)):
print(f"1〜{len(memos)} の範囲で入力してください")
continue
deleted = memos.pop(index - 1)
print(f"削除しました: {deleted}")
if not memos:
print("すべてのメモが削除されました。削除モードを終了します。")
break
Pythonこの while の終了条件を整理すると、こうなります。
ユーザー終了条件:空 Enter で break。
アプリ終了条件:メモが 0 件になったら break。
やり直し条件:数字でない、範囲外の番号 → continue。
ここでも、
「この while は“削除モードの中だけ”を担当している」
という意識が大事です。
アプリ全体の終了は、やはり外側の while の責任です。
7日目で一番大事な視点:while と終了条件の“責任範囲”
ここまでのコードを、責任範囲で整理してみます。
外側の while(アプリ全体)
アプリを続けるか、終わるかだけを決める。
終了条件は「メニューで終了が選ばれたとき」だけ。
add_memos の while(メモ追加モード)
メモ追加の繰り返しを管理する。
終了条件は「終了コマンド」か「最大件数」。
delete_memo の while(削除モード)
削除対象番号の入力を繰り返す。
終了条件は「空 Enter」か「メモが空になったとき」。
ask_menu_choice の while(メニュー入力)
正しいメニュー番号が入力されるまで繰り返す。
終了条件は「1〜5 のどれかが入力されたとき」。
search_memos / show_memos
単発処理。while は持たず、必要なところで return。
こうやって見ると、
「どの while が、どこまでを担当しているか」
がはっきり分かれているのが見えると思います。
これが、7日目で一番確認してほしい感覚です。
7日目のまとめ:あなたがもうできていること
ここまで来たあなたは、もう
while を書ける人
ではなく
while と終了条件でアプリの構造を組み立てられる人
になりつつあります。
今日の本質を一言で言うと、
「while と終了条件は“機能ごと・階層ごと”に責任範囲を分けて設計する」
です。
1つの巨大な while に全部詰め込むのではなく、
外側の while:アプリ全体の流れ
内側の while:モードごとの繰り返し
関数内の return:その機能の終わり
というふうに、
“どこで終わるか”を丁寧に分割してあげる。
ここまで意識できていれば、
この先、GUI アプリでも Web アプリでも、
「ループと終了条件」で迷子になることは、かなり減ります。
もし余力があれば、
検索を「何度も続けられるモード」にする
削除後に「続けるか?」を聞いてみる
など、自分なりに while と終了条件をいじってみてください。
そこから先は、もう「練習」ではなく「設計遊び」です。


