Coverage for src/cli.py: 0%

81 statements  

« prev     ^ index     » next       coverage.py v7.9.1, created at 2025-06-22 03:09 +0000

1""" 

2Command-line interface for the Task Manager application. 

3 

4This module provides a menu-driven interface for: 

5- Adding new tasks 

6- Listing all tasks 

7- Marking tasks as completed 

8- Deleting tasks 

9 

10The interface is user-friendly and handles input validation. 

11""" 

12 

13from datetime import datetime 

14from typing import Optional 

15 

16from src.task_manager import Task, TaskManager 

17 

18 

19def print_task(task: Task) -> None: 

20 """ 

21 Print a task's details in a formatted way. 

22 

23 Args: 

24 task: The task to print 

25 """ 

26 status = "✓" if task.completed else " " 

27 due_date = task.due_date.strftime("%Y-%m-%d") if task.due_date else "No due date" 

28 print(f"\n[{status}] Task {task.id}: {task.title}") 

29 print(f"Description: {task.description}") 

30 print(f"Due date: {due_date}") 

31 

32 

33def parse_date(date_str: str) -> Optional[datetime]: 

34 """ 

35 Parse a date string into a datetime object. 

36 

37 Args: 

38 date_str: Date string in YYYY-MM-DD format 

39 

40 Returns: 

41 Parsed datetime object or None if the string is empty 

42 """ 

43 if not date_str: 

44 return None 

45 try: 

46 return datetime.strptime(date_str, "%Y-%m-%d") 

47 except ValueError: 

48 print("Invalid date format. Please use YYYY-MM-DD") 

49 return None 

50 

51 

52def add_task(manager: TaskManager) -> None: 

53 """ 

54 Add a new task through user input. 

55 

56 Args: 

57 manager: The task manager instance 

58 """ 

59 print("\nAdd a new task:") 

60 title = input("Title: ").strip() 

61 description = input("Description: ").strip() 

62 date_str = input("Due date (YYYY-MM-DD, or press Enter to skip): ").strip() 

63 

64 due_date = parse_date(date_str) 

65 if due_date is None and date_str: 

66 return 

67 

68 try: 

69 task = manager.add_task(title, description, due_date) 

70 print("\nTask added successfully!") 

71 print_task(task) 

72 except ValueError as e: 

73 print(f"\nError: {e}") 

74 

75 

76def list_tasks(manager: TaskManager) -> None: 

77 """ 

78 List all tasks in the manager. 

79 

80 Args: 

81 manager: The task manager instance 

82 """ 

83 include_completed = input("\nInclude completed tasks? (y/N): ").lower() == "y" 

84 tasks = manager.list_tasks(include_completed) 

85 

86 if not tasks: 

87 print("\nNo tasks found.") 

88 return 

89 

90 print("\nTasks:") 

91 for task in tasks: 

92 print_task(task) 

93 

94 

95def mark_completed(manager: TaskManager) -> None: 

96 """ 

97 Mark a task as completed through user input. 

98 

99 Args: 

100 manager: The task manager instance 

101 """ 

102 try: 

103 task_id = int(input("\nEnter task ID to mark as completed: ")) 

104 task = manager.mark_completed(task_id) 

105 print("\nTask marked as completed:") 

106 print_task(task) 

107 except ValueError: 

108 print("\nError: Invalid task ID") 

109 except KeyError as e: 

110 print(f"\nError: {e}") 

111 

112 

113def delete_task(manager: TaskManager) -> None: 

114 """ 

115 Delete a task through user input. 

116 

117 Args: 

118 manager: The task manager instance 

119 """ 

120 try: 

121 task_id = int(input("\nEnter task ID to delete: ")) 

122 manager.delete_task(task_id) 

123 print("\nTask deleted successfully!") 

124 except ValueError: 

125 print("\nError: Invalid task ID") 

126 except KeyError as e: 

127 print(f"\nError: {e}") 

128 

129 

130def print_menu() -> None: 

131 """Print the main menu options.""" 

132 print("\nTask Manager Menu:") 

133 print("1. Add task") 

134 print("2. List tasks") 

135 print("3. Mark task as completed") 

136 print("4. Delete task") 

137 print("5. Exit") 

138 

139 

140def main() -> None: 

141 """Run the main function. 

142 

143 Main entry point for the CLI application. 

144 """ 

145 manager = TaskManager() 

146 actions = { 

147 "1": add_task, 

148 "2": list_tasks, 

149 "3": mark_completed, 

150 "4": delete_task, 

151 } 

152 

153 while True: 

154 print_menu() 

155 choice = input("\nEnter your choice (1-5): ") 

156 

157 if choice == "5": 

158 print("\nGoodbye!") 

159 break 

160 

161 action = actions.get(choice) 

162 if action: 

163 action(manager) 

164 else: 

165 print("\nInvalid choice. Please try again.") 

166 

167 

168if __name__ == "__main__": 

169 main()