Coverage for src/task_manager.py: 100%
47 statements
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-22 03:09 +0000
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-22 03:09 +0000
1"""
2Task Manager module for managing tasks in a simple task management system.
4This module provides the core functionality for managing tasks, including:
5- Adding new tasks with title, description, and optional due date
6- Retrieving tasks by ID
7- Updating existing tasks
8- Deleting tasks
9- Listing all tasks or filtering by completion status
10- Marking tasks as completed
12Example:
13 >>> from task_manager import TaskManager, Task
14 >>> manager = TaskManager()
15 >>> task = manager.add_task("Write docs", "Document the codebase")
16 >>> manager.mark_completed(task.id)
17 >>> tasks = manager.list_tasks()
18"""
20from dataclasses import dataclass
21from datetime import datetime
22from typing import Dict, List, Optional
25@dataclass
26class Task:
27 """
28 A task in the task management system.
30 Attributes:
31 id (int): Unique identifier for the task
32 title (str): Title of the task
33 description (str): Detailed description of the task
34 due_date (Optional[datetime]): Optional due date for the task
35 completed (bool): Whether the task is completed
36 """
38 id: int
39 title: str
40 description: str
41 due_date: Optional[datetime] = None
42 completed: bool = False
45class TaskManager:
46 """
47 Manages tasks in the task management system.
49 This class provides methods for creating, retrieving, updating,
50 and deleting tasks, as well as listing tasks and marking them as completed.
51 """
53 def __init__(self) -> None:
54 """Initialize an empty task manager."""
55 self._tasks: Dict[int, Task] = {}
56 self._next_id: int = 1
58 def add_task(
59 self, title: str, description: str, due_date: Optional[datetime] = None
60 ) -> Task:
61 """
62 Add a new task to the manager.
64 Args:
65 title: The title of the task
66 description: A detailed description of the task
67 due_date: Optional due date for the task
69 Returns:
70 The newly created task
72 Raises:
73 ValueError: If title or description are empty
74 """
75 if not title or not description:
76 raise ValueError("Title and description are required")
78 task = Task(
79 id=self._next_id,
80 title=title,
81 description=description,
82 due_date=due_date,
83 )
84 self._tasks[task.id] = task
85 self._next_id += 1
86 return task
88 def get_task(self, task_id: int) -> Task:
89 """
90 Get a task by its ID.
92 Args:
93 task_id: The ID of the task to retrieve
95 Returns:
96 The requested task
98 Raises:
99 KeyError: If the task ID doesn't exist
100 """
101 if task_id not in self._tasks:
102 raise KeyError(f"Task with ID {task_id} not found")
103 return self._tasks[task_id]
105 def update_task(
106 self,
107 task_id: int,
108 title: Optional[str] = None,
109 description: Optional[str] = None,
110 due_date: Optional[datetime] = None,
111 ) -> Task:
112 """
113 Update an existing task.
115 Args:
116 task_id: The ID of the task to update
117 title: New title (optional)
118 description: New description (optional)
119 due_date: New due date (optional)
121 Returns:
122 The updated task
124 Raises:
125 KeyError: If the task ID doesn't exist
126 """
127 task = self.get_task(task_id)
128 if title is not None:
129 task.title = title
130 if description is not None:
131 task.description = description
132 if due_date is not None:
133 task.due_date = due_date
134 return task
136 def delete_task(self, task_id: int) -> None:
137 """
138 Delete a task by its ID.
140 Args:
141 task_id: The ID of the task to delete
143 Raises:
144 KeyError: If the task ID doesn't exist
145 """
146 if task_id not in self._tasks:
147 raise KeyError(f"Task with ID {task_id} not found")
148 del self._tasks[task_id]
150 def list_tasks(self, include_completed: bool = True) -> List[Task]:
151 """
152 List all tasks, optionally filtering by completion status.
154 Args:
155 include_completed: Whether to include completed tasks
157 Returns:
158 A list of tasks matching the filter criteria
159 """
160 tasks = list(self._tasks.values())
161 if not include_completed:
162 tasks = [task for task in tasks if not task.completed]
163 return tasks
165 def mark_completed(self, task_id: int) -> Task:
166 """
167 Mark a task as completed.
169 Args:
170 task_id: The ID of the task to mark as completed
172 Returns:
173 The updated task
175 Raises:
176 KeyError: If the task ID doesn't exist
177 """
178 task = self.get_task(task_id)
179 task.completed = True
180 return task