-
Notifications
You must be signed in to change notification settings - Fork 25
Formative feedback #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
d51cc34
c976ca2
24a7bfc
33b5324
131945c
9666869
2d11eee
9a723c3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| Item 1 | ||
| Item 2 | ||
| Item 3 | ||
| Item 4 | ||
| Item 5 | ||
| Item 6 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| import os | ||
| import unittest | ||
| from unittest.mock import patch | ||
| from todo import add_task, list_tasks, remove_task, TASK_FILE | ||
|
|
||
| class TestTodoFunctions(unittest.TestCase): | ||
|
|
||
| def setUp(self): | ||
| """Ensure an empty task file before each test.""" | ||
| if os.path.exists(TASK_FILE): | ||
| os.remove(TASK_FILE) | ||
|
|
||
| def tearDown(self): | ||
| """Clean up the task file after each test.""" | ||
| if os.path.exists(TASK_FILE): | ||
| os.remove(TASK_FILE) | ||
|
|
||
| def test_add_task(self): | ||
| """Test that a task is added correctly.""" | ||
| add_task("First") | ||
| self.assertTrue(os.path.exists(TASK_FILE)) # Check if the file exists | ||
|
|
||
| with open(TASK_FILE, "r") as file: | ||
| tasks = file.readlines() | ||
|
|
||
| self.assertEqual(len(tasks), 1) # This checks that the numbers of tasks added is 1 (as only added one) | ||
| self.assertEqual(tasks[0].strip(), "First") # This checks that the task added is the same as the one that was added | ||
|
|
||
| def test_list_tasks(self): | ||
| """Test printing all the tasks.""" | ||
| add_task("First") | ||
| add_task("Second") | ||
|
|
||
| tasks = list_tasks() | ||
|
|
||
| self.assertIn("1. First", tasks) # Check if the first task is in the list | ||
| self.assertIn("2. Second", tasks) # Check if the second task is in the list | ||
|
|
||
| def test_remove_task(self): | ||
| """Test removing a task in the middle of the list.""" | ||
| add_task("First") | ||
| add_task("Second") | ||
| add_task("Third") | ||
|
|
||
| remove_task(2) | ||
|
|
||
| with open(TASK_FILE, "r") as file: | ||
| tasks = file.readlines() | ||
|
|
||
| self.assertEqual(len(tasks), 2) | ||
| self.assertEqual(tasks[1].strip(), "Third") # Check that the second task is now the third task because the middle task was removed | ||
|
|
||
| def test_remove_task_invalid_index(self): | ||
| """Test removing a task with an invalid index.""" | ||
| add_task("First") | ||
| with patch("builtins.print") as mock_print: | ||
| remove_task(5) # Invalid index out of range | ||
| mock_print.assert_called_with("Invalid task number. Please choose between 1 and 1.") | ||
|
|
||
| with open(TASK_FILE, "r") as file: | ||
| tasks = file.readlines() | ||
| self.assertEqual(len(tasks), 1) | ||
| self.assertEqual(tasks[0].strip(), "First") | ||
|
|
||
| if __name__ == "__main__": | ||
| unittest.main() |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,23 +1,67 @@ | ||
| """A command-line to-do list application that supports adding, listing, and removing tasks""" | ||
|
|
||
| import argparse | ||
| import os | ||
|
|
||
| TASK_FILE = ".tasks.txt" | ||
| NO_TASKS_FOUND_MSG = "No tasks found. Please add a task using -a or --add option." | ||
|
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice :-) |
||
|
|
||
| def add_task(task): | ||
| """Function: add_task | ||
|
|
||
| Input - a task to add to the list | ||
| Return - nothing | ||
| """ | ||
| """Add new task to task file""" | ||
| with open(TASK_FILE, "a", encoding="utf-8") as file: | ||
| file.write(task + "\n") | ||
|
|
||
| def list_tasks(): | ||
| return | ||
| """Read tasks from task file and return them as a numbered list""" | ||
|
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Try not to do multiple things in the same commit. The edits to the method comments should be separate to the addition of the remove_tasks function |
||
| if not os.path.exists(TASK_FILE): | ||
| return NO_TASKS_FOUND_MSG | ||
|
|
||
| with open(TASK_FILE, "r", encoding="utf-8") as file: | ||
| lines = [line.strip() for line in file if line.strip()] | ||
|
|
||
| if not lines: | ||
| return NO_TASKS_FOUND_MSG | ||
|
|
||
| numbered_tasks = [f"{idx + 1}. {line}" for idx, line in enumerate(lines)] | ||
| return "\n".join(numbered_tasks) | ||
|
|
||
| def remove_task(index): | ||
| return | ||
| """Remove a task by its number from the task file""" | ||
| if not os.path.exists(TASK_FILE): | ||
| print(NO_TASKS_FOUND_MSG) | ||
| return | ||
|
|
||
| # Read all non-empty lines from the file | ||
| # strip() to remove any leading/trailing whitespace | ||
| with open(TASK_FILE, "r", encoding="utf-8") as file: | ||
| tasks = [line.strip() for line in file if line.strip()] | ||
|
|
||
| if not tasks: | ||
| print("No tasks to remove.") | ||
| return | ||
|
|
||
| # Check for valid input from user | ||
| if index < 1 or index > len(tasks): | ||
| print(f"Invalid task number. Please choose between 1 and {len(tasks)}.") | ||
| return | ||
|
|
||
| # Remove the specified task | ||
| removed = tasks.pop(index - 1) | ||
|
|
||
| # Write remaining tasks back to the file | ||
| if tasks: | ||
| with open(TASK_FILE, "w", encoding="utf-8") as file: | ||
| file.write("\n".join(tasks) + "\n") | ||
| print(f"Task '{removed}' removed successfully.") | ||
| print("Remaining tasks:") | ||
| for i, task in enumerate(tasks, 1): | ||
|
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not call list tasks, rather than duplicate code? |
||
| print(f"{i}. {task}") | ||
| else: | ||
| os.remove(TASK_FILE) | ||
| print(f"Task '{removed}' removed. No tasks left. File deleted.") | ||
|
|
||
| def main(): | ||
| """Parse the command-line arguments and run the selected task operation""" | ||
| parser = argparse.ArgumentParser(description="Command-line Todo List") | ||
| parser.add_argument( | ||
| "-a", | ||
|
|
@@ -38,6 +82,7 @@ def main(): | |
|
|
||
| if args.add: | ||
| add_task(args.add) | ||
| print (f"Task '{args.add}' added successfully.") | ||
| elif args.list: | ||
| tasks = list_tasks() | ||
| print(tasks) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't add random files to the repo. It pollutes the software, so that someone cloning would then have your task list. See .gitignore to add these so you can't add them to the repo