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

1""" 

2Task Manager module for managing tasks in a simple task management system. 

3 

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 

11 

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""" 

19 

20from dataclasses import dataclass 

21from datetime import datetime 

22from typing import Dict, List, Optional 

23 

24 

25@dataclass 

26class Task: 

27 """ 

28 A task in the task management system. 

29 

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 """ 

37 

38 id: int 

39 title: str 

40 description: str 

41 due_date: Optional[datetime] = None 

42 completed: bool = False 

43 

44 

45class TaskManager: 

46 """ 

47 Manages tasks in the task management system. 

48 

49 This class provides methods for creating, retrieving, updating, 

50 and deleting tasks, as well as listing tasks and marking them as completed. 

51 """ 

52 

53 def __init__(self) -> None: 

54 """Initialize an empty task manager.""" 

55 self._tasks: Dict[int, Task] = {} 

56 self._next_id: int = 1 

57 

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. 

63 

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 

68 

69 Returns: 

70 The newly created task 

71 

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") 

77 

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 

87 

88 def get_task(self, task_id: int) -> Task: 

89 """ 

90 Get a task by its ID. 

91 

92 Args: 

93 task_id: The ID of the task to retrieve 

94 

95 Returns: 

96 The requested task 

97 

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] 

104 

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. 

114 

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) 

120 

121 Returns: 

122 The updated task 

123 

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 

135 

136 def delete_task(self, task_id: int) -> None: 

137 """ 

138 Delete a task by its ID. 

139 

140 Args: 

141 task_id: The ID of the task to delete 

142 

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] 

149 

150 def list_tasks(self, include_completed: bool = True) -> List[Task]: 

151 """ 

152 List all tasks, optionally filtering by completion status. 

153 

154 Args: 

155 include_completed: Whether to include completed tasks 

156 

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 

164 

165 def mark_completed(self, task_id: int) -> Task: 

166 """ 

167 Mark a task as completed. 

168 

169 Args: 

170 task_id: The ID of the task to mark as completed 

171 

172 Returns: 

173 The updated task 

174 

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