4日目のゴール
4日目のテーマは
「JSON保存アプリを“整理されたアプリの形”にすること」 です。
1〜3日目で、あなたはすでに
JSON を使ってデータを保存できる
複数データを扱える
検索・更新・削除ができる
という「機能」は手に入れました。
4日目は、その機能を
読みやすく・直しやすく・壊れにくい構造に組み立て直す日 です。
ここからが「中級編らしさ」が本格的に出てきます。
コードの“整理の仕方”を学ぶと、一気にプロっぽくなります。
4日目で目指すアプリのイメージ
「ToDo JSONアプリ」を“ちゃんとした設計”にする
題材は、前回までに作ってきた
JSON 保存型の ToDo アプリです。
やりたいことは変わりません。
タスクを追加する
タスクを一覧表示する
タスクの完了状態を変える
タスクを削除する
JSON に保存して、次回起動時に復元する
4日目で変えるのは「コードの形」です。
データ管理(JSON 読み書き)
データ操作(追加・検索・更新・削除)
アプリの流れ(メニュー・入力・表示)
この3つを意識して分けていきます。
まずは「ごちゃっとした書き方」をイメージする
ありがちな“全部 main に書く”スタイル
よくあるパターンは、こんな感じです。
ファイルを開いて JSON を読み込むコードが main にベタ書き
タスク追加の処理も main の中に直接書く
更新・削除も main の while の中に全部書く
動きはしますが、こうなると
どこを直せばいいか分かりにくい
同じようなコードが何度も出てくる
バグが出たときに追いかけづらい
という状態になります。
4日目では、これを
「役割ごとに関数に分ける」ことで解消します。
データ管理担当:JSONの読み書きをまとめる
JSON は「アプリの外にあるデータベース」
まずは、JSON の読み書きだけを担当する部分を
きれいに切り出します。
import json
import os
FILENAME = "tasks.json"
def load_tasks():
if not os.path.exists(FILENAME):
return []
with open(FILENAME, "r", encoding="utf-8") as f:
return json.load(f)
def save_tasks(tasks):
with open(FILENAME, "w", encoding="utf-8") as f:
json.dump(tasks, f, ensure_ascii=False, indent=2)
Pythonここで深掘りしたいポイントは三つです。
一つ目は、ファイル名を FILENAME として一箇所にまとめていることです。
もしファイル名を変えたくなっても、ここだけ直せば済みます。
二つ目は、load_tasks の中で「ファイルがなければ空リストを返す」としていることです。
これにより、初回起動時でもエラーにならず、
「タスクがまだない状態」として自然に動き始めます。
三つ目は、他のコードは JSON の存在を意識しなくてよくなることです。
「タスクを読みたいときは load_tasks を呼ぶ」
「保存したいときは save_tasks を呼ぶ」
というインターフェースだけ覚えておけばよくなります。
データ操作担当:タスクをどう扱うかをまとめる
「タスクをどう持つか」をはっきりさせる
タスクの形はこうでした。
task = {
"title": "本を30分読む",
"done": False
}
Python複数のタスクはリストで持ちます。
tasks = [
{"title": "本を30分読む", "done": False},
{"title": "メールを整理する", "done": True}
]
Pythonこの tasks に対して行う操作を
専用の関数としてまとめていきます。
追加・検索・更新・削除を関数にする
タスク追加はこう書けます。
def add_task(tasks, title):
task = {"title": title, "done": False}
tasks.append(task)
return True
Pythonここでは、画面表示は一切していません。
「タスクを追加する」という“事実”だけを担当しています。
タスク検索はこうです。
def find_task(tasks, title):
for task in tasks:
if task["title"] == title:
return task
return None
Python見つかったらそのタスク(辞書)を返し、
見つからなければ None を返します。
完了状態の更新は、検索を使ってこう書けます。
def update_task(tasks, title, done):
task = find_task(tasks, title)
if task is None:
return False
task["done"] = done
return True
Pythonここで重要なのは、
更新処理は「検索してから値を変えるだけ」
というシンプルな構造になっていることです。
削除はこうです。
def delete_task(tasks, title):
for i, task in enumerate(tasks):
if task["title"] == title:
del tasks[i]
return True
return False
Pythonenumerate を使ってインデックスを取り出し、
そのインデックスを使って削除しています。
ここまでの関数に共通しているのは、
画面表示を一切しない
成功したかどうかを True / False で返す
という「データ操作に徹している」という点です。
表示担当:タスクをどう見せるかをまとめる
「見せ方」は別の関数にする
タスク一覧の表示は、こう切り出します。
def show_tasks(tasks):
if not tasks:
print("タスクはありません。")
return
print("=== タスク一覧 ===")
for task in tasks:
mark = "✔" if task["done"] else "✗"
print(f"{mark} {task['title']}")
Pythonここでは、
「どこから来た tasks か」は気にしていません。
全タスクでも、フィルタ済みのタスクでも、tasks がリストであれば同じように表示できます。
この「表示関数は、渡されたものをただ表示するだけ」という設計が
後で機能を増やすときに効いてきます。
アプリの流れ担当:main を“司令塔”にする
main は「何をするか」を決めるだけにする
ここまでで、
JSON 読み書き
タスクの追加・検索・更新・削除
タスクの表示
が、それぞれ関数として用意できました。
最後に、アプリ全体の流れを管理する main を書きます。
def main():
tasks = load_tasks()
print("JSONファイルから読み込みました。")
while True:
print("\n=== メニュー ===")
print("1: タスク追加")
print("2: タスク一覧表示")
print("3: 完了状態を変更")
print("4: タスク削除")
print("0: 終了")
choice = input("番号を選んでください: ")
if choice == "1":
title = input("タスク名: ")
add_task(tasks, title)
save_tasks(tasks)
print("追加しました。")
elif choice == "2":
show_tasks(tasks)
elif choice == "3":
title = input("変更するタスク名: ")
done_text = input("完了なら1、未完了なら0: ")
done = (done_text == "1")
if update_task(tasks, title, done):
save_tasks(tasks)
print("更新しました。")
else:
print("タスクが見つかりません。")
elif choice == "4":
title = input("削除するタスク名: ")
if delete_task(tasks, title):
save_tasks(tasks)
print("削除しました。")
else:
print("タスクが見つかりません。")
elif choice == "0":
save_tasks(tasks)
print("終了します。")
break
else:
print("正しい番号を入力してください。")
Python最後に、エントリーポイントを書きます。
if __name__ == "__main__":
main()
Python全体コードを通して眺めてみる
「役割ごとにまとまっている」感覚をつかむ
4日目時点の完成形は、こうなります。
import json
import os
FILENAME = "tasks.json"
def load_tasks():
if not os.path.exists(FILENAME):
return []
with open(FILENAME, "r", encoding="utf-8") as f:
return json.load(f)
def save_tasks(tasks):
with open(FILENAME, "w", encoding="utf-8") as f:
json.dump(tasks, f, ensure_ascii=False, indent=2)
def add_task(tasks, title):
task = {"title": title, "done": False}
tasks.append(task)
return True
def find_task(tasks, title):
for task in tasks:
if task["title"] == title:
return task
return None
def update_task(tasks, title, done):
task = find_task(tasks, title)
if task is None:
return False
task["done"] = done
return True
def delete_task(tasks, title):
for i, task in enumerate(tasks):
if task["title"] == title:
del tasks[i]
return True
return False
def show_tasks(tasks):
if not tasks:
print("タスクはありません。")
return
print("=== タスク一覧 ===")
for task in tasks:
mark = "✔" if task["done"] else "✗"
print(f"{mark} {task['title']}")
def main():
tasks = load_tasks()
print("JSONファイルから読み込みました。")
while True:
print("\n=== メニュー ===")
print("1: タスク追加")
print("2: タスク一覧表示")
print("3: 完了状態を変更")
print("4: タスク削除")
print("0: 終了")
choice = input("番号を選んでください: ")
if choice == "1":
title = input("タスク名: ")
add_task(tasks, title)
save_tasks(tasks)
print("追加しました。")
elif choice == "2":
show_tasks(tasks)
elif choice == "3":
title = input("変更するタスク名: ")
done_text = input("完了なら1、未完了なら0: ")
done = (done_text == "1")
if update_task(tasks, title, done):
save_tasks(tasks)
print("更新しました。")
else:
print("タスクが見つかりません。")
elif choice == "4":
title = input("削除するタスク名: ")
if delete_task(tasks, title):
save_tasks(tasks)
print("削除しました。")
else:
print("タスクが見つかりません。")
elif choice == "0":
save_tasks(tasks)
print("終了します。")
break
else:
print("正しい番号を入力してください。")
if __name__ == "__main__":
main()
Pythonここまで来ると、
JSON の読み書きは load/save にまとまっている
タスクの操作は add/find/update/delete にまとまっている
アプリの流れは main にまとまっている
という「三層構造」がはっきり見えてくるはずです。
4日目で絶対に押さえてほしい本質
「機能」だけでなく「構造」を設計する
今日の一番大事なポイントは、
同じことをするコードでも
“どう分けて書くか”で、アプリの質が変わる
ということです。
JSON を扱う技術そのものは、1〜3日目でほぼ出揃っています。
4日目は、それを「アプリとして長く付き合える形」にする日です。
データ管理(JSON)
データ操作(ビジネスロジック)
アプリの流れ(UI・メニュー)
この三つを意識して分ける感覚は、
この先どんな言語・どんなフレームワークを使っても役に立ちます。
もし「ここをもっとクラスで書いてみたい」
「ファイルを分けてモジュール化してみたい」
と思ったら、それはもう次のステップに進むサインです。
そこから先も、一緒に組み立てていけます。

