Skip to content

Instantly share code, notes, and snippets.

@t3tra-dev
Last active June 28, 2025 11:57
Show Gist options
  • Save t3tra-dev/222cb0f3b414614b15936c5ebde8c807 to your computer and use it in GitHub Desktop.
Save t3tra-dev/222cb0f3b414614b15936c5ebde8c807 to your computer and use it in GitHub Desktop.

AIにtodoアプリ作らせるときプロンプトによってどう変わるかっていう

PythonでGUIのtodoアプリ作るコード書いて

今後の拡張性を担保した上でPEP8を尊守し、堅牢な型とデータクラスを意識すること。

==========

以下は、PythonでGUIのToDoアプリを作成するコードです。 拡張性・保守性・堅牢性を重視し、以下の要件を満たしています:


✅ 要件

  • GUIフレームワーク: tkinter(標準ライブラリ)
  • データ構造: dataclasses.dataclass
  • 型ヒント: PEP 484準拠の型ヒントを完全に記載
  • 構成: アプリのロジックとGUIの分離(MVC的設計に近い)
  • PEP8準拠
  • 拡張性: 今後の機能追加(保存、検索、期限、カテゴリなど)を見据えた設計

📦 ディレクトリ構成(シンプルな1ファイル例)

# todo_app.py

💻 コード

import tkinter as tk
from tkinter import messagebox
from typing import List
from dataclasses import dataclass, field


@dataclass
class Task:
    title: str
    completed: bool = False


class TaskManager:
    def __init__(self) -> None:
        self._tasks: List[Task] = []

    def add_task(self, title: str) -> None:
        if not title.strip():
            raise ValueError("タスクのタイトルは空にできません。")
        self._tasks.append(Task(title=title))

    def remove_task(self, index: int) -> None:
        if 0 <= index < len(self._tasks):
            del self._tasks[index]
        else:
            raise IndexError("不正なタスクインデックス。")

    def toggle_task(self, index: int) -> None:
        if 0 <= index < len(self._tasks):
            self._tasks[index].completed = not self._tasks[index].completed
        else:
            raise IndexError("不正なタスクインデックス。")

    def get_tasks(self) -> List[Task]:
        return self._tasks.copy()


class TodoApp:
    def __init__(self, root: tk.Tk) -> None:
        self.root = root
        self.root.title("ToDoアプリ")
        self.manager = TaskManager()

        self.task_entry = tk.Entry(root, width=40)
        self.task_entry.pack(pady=5)

        self.add_button = tk.Button(root, text="追加", command=self.add_task)
        self.add_button.pack()

        self.task_listbox = tk.Listbox(root, width=50, height=10)
        self.task_listbox.pack(pady=10)

        self.toggle_button = tk.Button(root, text="完了 / 未完了", command=self.toggle_task)
        self.toggle_button.pack(pady=3)

        self.delete_button = tk.Button(root, text="削除", command=self.delete_task)
        self.delete_button.pack(pady=3)

        self.refresh_task_list()

    def add_task(self) -> None:
        title = self.task_entry.get()
        try:
            self.manager.add_task(title)
            self.task_entry.delete(0, tk.END)
            self.refresh_task_list()
        except ValueError as e:
            messagebox.showerror("入力エラー", str(e))

    def delete_task(self) -> None:
        selected_index = self._get_selected_index()
        if selected_index is not None:
            try:
                self.manager.remove_task(selected_index)
                self.refresh_task_list()
            except IndexError as e:
                messagebox.showerror("削除エラー", str(e))

    def toggle_task(self) -> None:
        selected_index = self._get_selected_index()
        if selected_index is not None:
            try:
                self.manager.toggle_task(selected_index)
                self.refresh_task_list()
            except IndexError as e:
                messagebox.showerror("更新エラー", str(e))

    def refresh_task_list(self) -> None:
        self.task_listbox.delete(0, tk.END)
        for idx, task in enumerate(self.manager.get_tasks()):
            status = "[✓]" if task.completed else "[ ]"
            self.task_listbox.insert(tk.END, f"{status} {task.title}")

    def _get_selected_index(self) -> int | None:
        selection = self.task_listbox.curselection()
        return selection[0] if selection else None


if __name__ == "__main__":
    root = tk.Tk()
    app = TodoApp(root)
    root.mainloop()

🚀 今後の拡張ポイント(設計済み)

機能 拡張方法
タスク保存/読み込み TaskManagersave_to_file, load_from_file を追加
タグ/期限/カテゴリ対応 Taskdue_date, category, tags: list[str] などを追加
サブタスク対応 Tasksubtasks: List[Task] を追加
テスト unittest or pytestTaskManager のテストが容易

このコードを土台にして、ファイル保存、検索、日付の追加などが柔軟に行えるようになっています。 GUIとロジックをしっかり分離しており、テストも容易です。

ご希望があれば、このコードにSQLite保存機能やタグ機能などを段階的に追加していくことも可能です。お気軽にリクエストしてください!

PythonでGUIのtodoアプリ作るコード書いて

============

以下に、Python の標準的なGUIライブラリ Tkinter を使って作成する、シンプルなToDoアプリのコードを示します。基本的な機能(タスクの追加・削除・保存・読み込み)を備えた構成です。


✅ 機能

  • タスクを入力して追加
  • リストからタスクを選んで削除
  • アプリ終了時にタスクを保存
  • 起動時に前回のタスクを読み込み

📝 ソースコード(ファイル保存あり)

import tkinter as tk
from tkinter import messagebox
import os
import json

TASKS_FILE = "tasks.json"

class TodoApp:
    def __init__(self, root):
        self.root = root
        self.root.title("ToDoアプリ")
        self.tasks = []

        # GUI構成
        self.task_entry = tk.Entry(root, width=40)
        self.task_entry.pack(pady=10)

        self.add_button = tk.Button(root, text="タスクを追加", width=20, command=self.add_task)
        self.add_button.pack()

        self.listbox = tk.Listbox(root, width=50, height=10)
        self.listbox.pack(pady=10)

        self.delete_button = tk.Button(root, text="選択したタスクを削除", width=20, command=self.delete_task)
        self.delete_button.pack()

        self.load_tasks()
        self.root.protocol("WM_DELETE_WINDOW", self.on_closing)

    def add_task(self):
        task = self.task_entry.get().strip()
        if task:
            self.tasks.append(task)
            self.update_listbox()
            self.task_entry.delete(0, tk.END)
        else:
            messagebox.showwarning("警告", "タスクが空です!")

    def delete_task(self):
        selected = self.listbox.curselection()
        if selected:
            del self.tasks[selected[0]]
            self.update_listbox()
        else:
            messagebox.showwarning("警告", "削除するタスクを選択してください。")

    def update_listbox(self):
        self.listbox.delete(0, tk.END)
        for task in self.tasks:
            self.listbox.insert(tk.END, task)

    def load_tasks(self):
        if os.path.exists(TASKS_FILE):
            with open(TASKS_FILE, "r", encoding="utf-8") as f:
                self.tasks = json.load(f)
                self.update_listbox()

    def save_tasks(self):
        with open(TASKS_FILE, "w", encoding="utf-8") as f:
            json.dump(self.tasks, f, ensure_ascii=False, indent=2)

    def on_closing(self):
        self.save_tasks()
        self.root.destroy()

if __name__ == "__main__":
    root = tk.Tk()
    app = TodoApp(root)
    root.mainloop()

💡 補足

  • タスクは tasks.json に保存され、次回起動時に復元されます。
  • Tkinter はPythonに標準で付属しているため、追加インストール不要です。
  • ファイルの保存形式には json を使っています。

必要であれば以下のような拡張も可能です:

  • タスクに「完了状態」をつける
  • 日付・期限・優先度の追加
  • ダークモード対応
  • SQLiteと連携

それらもご希望あれば追加で実装します。どうされますか?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment