import webbrowser class TaskAlreadyExistsError(Exception): """Exception raised when a task already exists in the list.""" def __init__(self, message): super().__init__(message) class TaskNotFoundError(Exception): """Exception raised when a task is not found in the list.""" def __init__(self, message): super().__init__(message) class ToDo: """Class representing a to-do list.""" def __init__(self) -> None: """Initialize an empty to-do list. Which is a dictionary""" self.tasks = {} def add_task(self, task:str, deadline:str) -> str: """Add a new task to the list. Args: task (str): The task description. deadline (str): The deadline in dd-mm-yy format. Returns: str: A confirmation message indicating that the task has been added. Raises: TaskAlreadyExistsError: If the task already exists in the list. TypeError: If the task parameter is not a string. ValueError: If the task parameter is an empty string. """ if not isinstance(task, str): raise TypeError("Task must be a string.") if not task: raise ValueError("Task cannot be an empty string.") if task in self.tasks.keys(): raise TaskAlreadyExistsError(f"{task} already exists in the list.") else: self.tasks[task] = {'status':False, 'deadline':deadline} print(self.tasks) return f"Task has been added to the list." def finish_task(self, task:str) -> str: """ Mark a task as finished and open a web page for celebration. Args: task (str): The task to mark as finished. Returns: str: A message confirming that the task has been marked as finished. Raises: TypeError: If the task is not a string. TaskNotFoundError: If the task does not exist in the list. """ try: if not isinstance(task, str): raise TypeError("Task must be a string.") self.tasks[task]['status'] = True webbrowser.open("well_done.html") return "Task finished" except Exception: raise TaskNotFoundError("No such task in the list.") def remove_task(self, task:str) ->str: """ Remove a task from the task list. Args: task (str): The task to remove. Returns: str: A message confirming that the task has been removed. Raises: TypeError: If the task is not a string. TaskNotFoundError: If the task does not exist in the list. """ try: if not isinstance(task, str): raise TypeError("Task must be a string.") del self.tasks[task] return "Task removed" except Exception: raise TaskNotFoundError("No such task in the list.") def update_task(self, task:str, new_deadline:str) -> str: """ Update the status and deadline of a task. Args: task (str): The task to update. new_deadline (str): The new deadline for the task in dd-mm-yy format. Returns: str: A message confirming that the task has been updated. Raises: TypeError: If the task is not a string. TaskNotFoundError: If the task does not exist in the list. """ try: if not isinstance(task, str): raise TypeError("Task must be a string.") self.tasks[task] = {'status': False, 'deadline': new_deadline} return "Task updated" except Exception: raise TaskNotFoundError("No such task in the list.") def view_tasks(self) -> list: """View the tasks in the list. Returns: list: A list of task descriptions and their status or completion. Raises: TaskNotFoundError: If there are no tasks in the list. """ try: task_list = [] for task in self.tasks: if self.tasks[task]['status'] == False: task_list.append(f"{task} by {self.tasks[task]['deadline']}") if self.tasks[task]['status'] == True: task_list.append(f"{task} finished") return task_list except Exception: raise TaskNotFoundError("There are no tasks in the list.") if __name__ == "__main__": app = ToDo() while True: print("-------------------------------") print() print("1. Add task") print("2. View tasks") print("3. delete task") print("4. update task") print("5. finish task") print("6. exit app") print() print("-------------------------------") choice = int(input("Enter your choice: ")) if choice == 1: task = input("Enter task: ") deadline = input("Enter task deadline: ") try: message = app.add_task(task, deadline) print(message) except TypeError as e: print(e) except ValueError as e: print(e) except TaskAlreadyExistsError as e: print(e) elif choice == 2: try: print("-------------------------------") task_list = app.view_tasks() for task in task_list: print(task) print("-------------------------------") except TaskNotFoundError as e: print(e) elif choice == 3: try: task = input("Enter the task you want to remove: ") message = app.remove_task(task) print(message) except TypeError as e: print(e) except TaskNotFoundError as e: print(e) elif choice == 4: try: task = input("Enter the task you want to update: ") deadline = input("What is the new deadline? ") message = app.update_task(task,deadline) print(message) except TypeError as e: print(e) except TaskNotFoundError as e: print(e) elif choice == 5: try: task = input("Enter the task you have finised: ") message = app.finish_task(task) print(message) except TypeError as e: print(e) except TaskNotFoundError as e: print(e) elif choice == 6: print("Thanks for using") break else: print("Invalid choice!")