はじめに
今回は、Pythonのオブジェクト指向プログラミングを用いた「タスク管理アプリ」のサンプルコードを解説します。このプログラムでは、継承やポリモーフィズム、**ファイル操作(JSON形式)**を使って、以下の機能を実現しています。
- タスクの追加、削除、検索、編集
- 優先度付きタスク、期限付きタスクの管理
- タスクの保存と読み込み(JSONファイルを使用)
- コマンドラインインターフェース(CLI)
Pythonのオブジェクト指向の基本から、実際のアプリケーションへの応用までを学べる内容になっています。
プログラムの全体像
import json
from datetime import datetime
# 基底クラス:タスク
class Task:
"""タスクを表す基本クラス"""
def __init__(self, name, details):
self.name = name # タスクの名前
self.details = details # タスクの詳細
def display(self):
"""タスク情報を表示する"""
return f"[タスク] 名前: {self.name}, 詳細: {self.details}"
# 派生クラス:優先度付きタスク
class PriorityTask(Task):
"""優先度付きタスクを表すクラス"""
def __init__(self, name, details, priority):
super().__init__(name, details)
self.priority = priority # タスクの優先度
def display(self):
"""タスク情報を表示する(優先度付き)"""
return f"[優先度付きタスク] 名前: {self.name}, 詳細: {self.details}, 優先度: {self.priority}"
# 派生クラス:期限付きタスク
class DeadlineTask(Task):
"""期限付きタスクを表すクラス"""
def __init__(self, name, details, deadline):
super().__init__(name, details)
self.deadline = deadline # タスクの期限
def display(self):
"""タスク情報を表示する(期限付き)"""
return f"[期限付きタスク] 名前: {self.name}, 詳細: {self.details}, 期限: {self.deadline}"
# タスク管理クラス
class TaskManager:
"""タスクを管理するクラス"""
def __init__(self):
self.tasks = [] # タスクのリスト
def add_task(self, task):
"""タスクを追加する"""
self.tasks.append(task)
print(f"タスクを追加しました: {task.display()}")
def remove_task(self, name):
"""タスクを名前で削除する"""
for task in self.tasks:
if task.name == name:
self.tasks.remove(task)
print(f"タスクを削除しました: {task.display()}")
return
print("該当するタスクが見つかりません。")
def search_task(self, name):
"""タスクを名前で検索する"""
for task in self.tasks:
if task.name == name:
print(f"タスクが見つかりました: {task.display()}")
return task
print("該当するタスクが見つかりません。")
return None
def edit_task(self, name, new_details):
"""タスクの詳細を編集する"""
task = self.search_task(name)
if task:
task.details = new_details
print(f"タスクを編集しました: {task.display()}")
def list_tasks(self):
"""全タスクを表示する"""
if not self.tasks:
print("タスクはありません。")
for task in self.tasks:
print(task.display())
def save_to_file(self, filename="tasks.json"):
"""タスクをJSONファイルに保存する"""
with open(filename, "w", encoding="utf-8") as file:
json.dump([self._task_to_dict(task) for task in self.tasks], file, ensure_ascii=False, indent=4)
print(f"タスクをファイルに保存しました: {filename}")
def load_from_file(self, filename="tasks.json"):
"""JSONファイルからタスクを読み込む"""
try:
with open(filename, "r", encoding="utf-8") as file:
tasks_data = json.load(file)
self.tasks = [self._dict_to_task(data) for data in tasks_data]
print(f"ファイルからタスクを読み込みました: {filename}")
except FileNotFoundError:
print("ファイルが見つかりません。新しいリストを作成します。")
def _task_to_dict(self, task):
"""タスクオブジェクトを辞書形式に変換する(内部用)"""
if isinstance(task, PriorityTask):
return {"type": "PriorityTask", "name": task.name, "details": task.details, "priority": task.priority}
elif isinstance(task, DeadlineTask):
return {"type": "DeadlineTask", "name": task.name, "details": task.details, "deadline": task.deadline}
else:
return {"type": "Task", "name": task.name, "details": task.details}
def _dict_to_task(self, data):
"""辞書形式をタスクオブジェクトに変換する(内部用)"""
if data["type"] == "PriorityTask":
return PriorityTask(data["name"], data["details"], data["priority"])
elif data["type"] == "DeadlineTask":
return DeadlineTask(data["name"], data["details"], data["deadline"])
else:
return Task(data["name"], data["details"])
# CLIインターフェース
def main():
manager = TaskManager()
manager.load_from_file()
while True:
print("\nタスク管理アプリ")
print("1. タスクを追加")
print("2. タスクを削除")
print("3. タスクを検索")
print("4. タスクを編集")
print("5. 全タスクを表示")
print("6. タスクを保存")
print("7. 終了")
choice = input("選択してください: ")
if choice == "1":
name = input("タスク名: ")
details = input("タスク詳細: ")
print("1. 通常タスク\n2. 優先度付きタスク\n3. 期限付きタスク")
task_type = input("タスクタイプを選択してください: ")
if task_type == "1":
task = Task(name, details)
elif task_type == "2":
priority = input("優先度を入力してください: ")
task = PriorityTask(name, details, priority)
elif task_type == "3":
deadline = input("期限を入力してください (YYYY-MM-DD): ")
try:
datetime.strptime(deadline, "%Y-%m-%d") # 期限の形式を確認
task = DeadlineTask(name, details, deadline)
except ValueError:
print("不正な日付形式です。タスクを追加できませんでした。")
continue
else:
print("無効なタスクタイプです。")
continue
manager.add_task(task)
elif choice == "2":
name = input("削除するタスク名: ")
manager.remove_task(name)
elif choice == "3":
name = input("検索するタスク名: ")
manager.search_task(name)
elif choice == "4":
name = input("編集するタスク名: ")
new_details = input("新しい詳細: ")
manager.edit_task(name, new_details)
elif choice == "5":
manager.list_tasks()
elif choice == "6":
manager.save_to_file()
elif choice == "7":
manager.save_to_file()
print("終了します。")
break
else:
print("無効な選択です。")
if __name__ == "__main__":
main()
プログラムの全体構成
このプログラムは以下の4つのパートで構成されています。
- Task, PriorityTask, DeadlineTask クラス
- タスクの基本情報を管理するクラス群
- TaskManager クラス
- タスクの追加、削除、検索、編集、保存、読み込みを管理
- JSON ファイル操作
- タスクをJSON形式で保存、読み込み
- CLI (Command Line Interface)
- コマンドラインから操作できるユーザーインターフェース
クラス設計
1. Task クラス
Task
クラスは 基底クラス であり、すべてのタスクの基本情報を管理します。
class Task:
"""タスクを表す基本クラス"""
def __init__(self, name, details):
self.name = name # タスクの名前
self.details = details # タスクの詳細
def display(self):
"""タスク情報を表示する"""
return f"[タスク] 名前: {self.name}, 詳細: {self.details}"
ポイント
__init__
メソッドを使用して、名前(name) と 詳細(details) を初期化display()
メソッドでタスクの情報を表示
2. PriorityTask クラス
PriorityTask
クラスは、Task
クラスを継承して 優先度付きタスク を表現しています。
class PriorityTask(Task):
"""優先度付きタスクを表すクラス"""
def __init__(self, name, details, priority):
super().__init__(name, details)
self.priority = priority # タスクの優先度
def display(self):
"""タスク情報を表示する(優先度付き)"""
return f"[優先度付きタスク] 名前: {self.name}, 詳細: {self.details}, 優先度: {self.priority}"
ポイント
- 継承 を使用して
Task
クラスのプロパティを引き継いでいます。 super().__init__(name, details)
で親クラスのコンストラクタを呼び出しています。- 優先度を表す
priority
属性を追加。
3. DeadlineTask クラス
DeadlineTask
クラスは、Task
クラスを継承して 期限付きタスク を表現しています。
class DeadlineTask(Task):
"""期限付きタスクを表すクラス"""
def __init__(self, name, details, deadline):
super().__init__(name, details)
self.deadline = deadline # タスクの期限
def display(self):
"""タスク情報を表示する(期限付き)"""
return f"[期限付きタスク] 名前: {self.name}, 詳細: {self.details}, 期限: {self.deadline}"
ポイント
- 期限を表す
deadline
属性を追加。 display()
メソッドで期限を含めた情報を表示。
4. TaskManager クラス
TaskManager
クラスは、タスクの管理を担当する 管理クラス です。
class TaskManager:
"""タスクを管理するクラス"""
def __init__(self):
self.tasks = [] # タスクのリスト
機能
- 追加:
add_task()
メソッド - 削除:
remove_task()
メソッド - 検索:
search_task()
メソッド - 編集:
edit_task()
メソッド - 表示:
list_tasks()
メソッド - 保存:
save_to_file()
メソッド - 読み込み:
load_from_file()
メソッド
JSONを使ったファイル操作
保存機能
def save_to_file(self, filename="tasks.json"):
"""タスクをJSONファイルに保存する"""
with open(filename, "w", encoding="utf-8") as file:
json.dump([self._task_to_dict(task) for task in self.tasks], file, ensure_ascii=False, indent=4)
print(f"タスクをファイルに保存しました: {filename}")
json.dump()
を使用してタスクを JSON 形式で保存します。_task_to_dict()
メソッドでタスクオブジェクトを辞書形式に変換しています。
読み込み機能
def load_from_file(self, filename="tasks.json"):
"""JSONファイルからタスクを読み込む"""
try:
with open(filename, "r", encoding="utf-8") as file:
tasks_data = json.load(file)
self.tasks = [self._dict_to_task(data) for data in tasks_data]
print(f"ファイルからタスクを読み込みました: {filename}")
except FileNotFoundError:
print("ファイルが見つかりません。新しいリストを作成します。")
json.load()
を使用して JSON ファイルからタスクを読み込みます。_dict_to_task()
メソッドで辞書をタスクオブジェクトに戻しています。
コマンドラインインターフェース (CLI)
def main():
manager = TaskManager()
manager.load_from_file()
while True:
print("\nタスク管理アプリ")
print("1. タスクを追加")
print("2. タスクを削除")
print("3. タスクを検索")
print("4. タスクを編集")
print("5. 全タスクを表示")
print("6. タスクを保存")
print("7. 終了")
choice = input("選択してください: ")
- ユーザーがタスクを操作するためのインターフェースを提供しています。
- コマンドラインからタスクの追加、削除、検索、編集、保存、読み込みが可能。
まとめ
- オブジェクト指向プログラミングの 継承 や ポリモーフィズム を活用
Task
,PriorityTask
,DeadlineTask
の クラス設計 を応用- JSONファイル操作 によりデータの保存と読み込みを実現
- CLIインターフェース で操作性を向上
Pythonのオブジェクト指向設計を理解するのに最適な例です。ぜひ、コードを動かしながら学習してみてください。