From 4af94dc19cc1479fe2c8ed0446b2b30fe60fee12 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Thu, 30 Jan 2025 11:44:33 +0800 Subject: [PATCH 01/66] Rename Duke to Thoth --- README.md | 4 ++-- docs/README.md | 2 +- text-ui-test/runtest.bat | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index af0309a9e..58e1a6792 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Duke project template +# Thoth project template This is a project template for a greenfield Java project. It's named after the Java mascot _Duke_. Given below are instructions on how to use it. @@ -13,7 +13,7 @@ Prerequisites: JDK 17, update Intellij to the most recent version. 1. If there are any further prompts, accept the defaults. 1. Configure the project to use **JDK 17** (not other versions) as explained in [here](https://www.jetbrains.com/help/idea/sdk.html#set-up-jdk).
In the same dialog, set the **Project language level** field to the `SDK default` option. -1. After that, locate the `src/main/java/Duke.java` file, right-click it, and choose `Run Duke.main()` (if the code editor is showing compile errors, try restarting the IDE). If the setup is correct, you should see something like the below as the output: +1. After that, locate the `src/main/java/Thoth.java` file, right-click it, and choose `Run Thoth.main()` (if the code editor is showing compile errors, try restarting the IDE). If the setup is correct, you should see something like the below as the output: ``` Hello from ____ _ diff --git a/docs/README.md b/docs/README.md index 47b9f984f..6adfc0a3d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,4 +1,4 @@ -# Duke User Guide +# Thoth User Guide // Update the title above to match the actual product name diff --git a/text-ui-test/runtest.bat b/text-ui-test/runtest.bat index 087374464..3dac3dfd5 100644 --- a/text-ui-test/runtest.bat +++ b/text-ui-test/runtest.bat @@ -15,7 +15,7 @@ IF ERRORLEVEL 1 ( REM no error here, errorlevel == 0 REM run the program, feed commands from input.txt file and redirect the output to the ACTUAL.TXT -java -classpath ..\bin Duke < input.txt > ACTUAL.TXT +java -classpath ..\bin Thoth < input.txt > ACTUAL.TXT REM compare the output to the expected output FC ACTUAL.TXT EXPECTED.TXT From ac9118b5c611edf48c97972b1d8d42102bf301d8 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Thu, 30 Jan 2025 11:44:59 +0800 Subject: [PATCH 02/66] Add greet and exit --- src/main/java/Duke.java | 10 ---------- src/main/java/Thoth.java | 7 +++++++ 2 files changed, 7 insertions(+), 10 deletions(-) delete mode 100644 src/main/java/Duke.java create mode 100644 src/main/java/Thoth.java diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java deleted file mode 100644 index 5d313334c..000000000 --- a/src/main/java/Duke.java +++ /dev/null @@ -1,10 +0,0 @@ -public class Duke { - public static void main(String[] args) { - String logo = " ____ _ \n" - + "| _ \\ _ _| | _____ \n" - + "| | | | | | | |/ / _ \\\n" - + "| |_| | |_| | < __/\n" - + "|____/ \\__,_|_|\\_\\___|\n"; - System.out.println("Hello from\n" + logo); - } -} diff --git a/src/main/java/Thoth.java b/src/main/java/Thoth.java new file mode 100644 index 000000000..1c66e4b08 --- /dev/null +++ b/src/main/java/Thoth.java @@ -0,0 +1,7 @@ +public class Thoth { + public static void main(String[] args) { + System.out.println("Hello! I'm Thoth"); + System.out.println("What can I do for you?"); + System.out.println("Bye. Hope to see you again soon!"); + } +} From f5166821abf31ae0178c5804f3cbb378c5204e63 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Thu, 30 Jan 2025 12:06:01 +0800 Subject: [PATCH 03/66] Improve Thoth to echo command and exit when user input bye --- src/main/java/Thoth.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/main/java/Thoth.java b/src/main/java/Thoth.java index 1c66e4b08..eb80f03ca 100644 --- a/src/main/java/Thoth.java +++ b/src/main/java/Thoth.java @@ -1,7 +1,20 @@ +import java.util.Scanner; +import java.util.Arrays; + public class Thoth { public static void main(String[] args) { System.out.println("Hello! I'm Thoth"); System.out.println("What can I do for you?"); - System.out.println("Bye. Hope to see you again soon!"); + + String userInput = null; + while (true) { + userInput = new Scanner(System.in).nextLine(); + if (userInput.equals("bye")) { + System.out.println("Bye. Hope to see you again soon!"); + break; + } else { + System.out.println(userInput); + } + } } } From 1b3cf44b3128d49a2d940a15a0439d392b0b6125 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Thu, 30 Jan 2025 12:39:35 +0800 Subject: [PATCH 04/66] Add the ability to store text entered by the user and display them back when requested. --- src/main/java/Thoth.java | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/main/java/Thoth.java b/src/main/java/Thoth.java index eb80f03ca..ac9071a09 100644 --- a/src/main/java/Thoth.java +++ b/src/main/java/Thoth.java @@ -1,19 +1,32 @@ import java.util.Scanner; -import java.util.Arrays; public class Thoth { + public static final int MAX_TASKS = 100; + public static final String INDENT = "%4s"; + public static void main(String[] args) { + System.out.println("Hello! I'm Thoth"); System.out.println("What can I do for you?"); - String userInput = null; - while (true) { + String[] taskList = new String[MAX_TASKS]; + String userInput; + int listNumber = 1; + while (true) { userInput = new Scanner(System.in).nextLine(); if (userInput.equals("bye")) { - System.out.println("Bye. Hope to see you again soon!"); + System.out.printf(INDENT + "Bye. Hope to see you again soon!", ""); break; + } else if (userInput.equals("list")) { + for (int i = 0; i < listNumber; i++) { + if (taskList[i] != null) { + System.out.printf(INDENT + "%s%n", "", taskList[i]); + } + } } else { - System.out.println(userInput); + taskList[listNumber - 1] = listNumber + ". " + userInput; + System.out.printf(INDENT + "Added: %s%n", "", userInput); + listNumber++; } } } From 5b73d7d3d8f107572b01d080344b8851ce9bafc9 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Thu, 30 Jan 2025 19:35:23 +0800 Subject: [PATCH 05/66] Add the ability to mark tasks status as done and revert the status --- src/main/java/Thoth.java | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/main/java/Thoth.java b/src/main/java/Thoth.java index ac9071a09..d788c8f25 100644 --- a/src/main/java/Thoth.java +++ b/src/main/java/Thoth.java @@ -3,29 +3,51 @@ public class Thoth { public static final int MAX_TASKS = 100; public static final String INDENT = "%4s"; + public static final String EMPTY_BOX = "[ ]"; + public static final String MARKED_BOX = "[X]"; public static void main(String[] args) { - System.out.println("Hello! I'm Thoth"); System.out.println("What can I do for you?"); String[] taskList = new String[MAX_TASKS]; String userInput; + int listNumber = 1; + + // Create an endless loop for adding list while (true) { userInput = new Scanner(System.in).nextLine(); + // condition for the user to exit the program if (userInput.equals("bye")) { System.out.printf(INDENT + "Bye. Hope to see you again soon!", ""); break; + } else if (userInput.equals("list")) { for (int i = 0; i < listNumber; i++) { if (taskList[i] != null) { - System.out.printf(INDENT + "%s%n", "", taskList[i]); + System.out.printf(INDENT + "%d.%s%n", "", i + 1, taskList[i]); } } + + } else if (userInput.startsWith("mark")) { + String userInputNumber = userInput.replace("mark", "").trim(); + int index = Integer.parseInt(userInputNumber) - 1; + taskList[index] = taskList[index].replace(EMPTY_BOX, MARKED_BOX); + System.out.printf(INDENT + "Nice! I've marked this task as done:%n", ""); + System.out.printf(INDENT + "%s%n", "", taskList[index]); + + } else if (userInput.startsWith("unmark")) { + String userInputNumber = userInput.replace("unmark", "").trim(); + int index = Integer.parseInt(userInputNumber) - 1; + taskList[index] = taskList[index].replace(MARKED_BOX, EMPTY_BOX); + System.out.printf(INDENT + "OK, I've marked this task as not done yet:%n", ""); + System.out.printf(INDENT + "%s%n", "", taskList[index]); + } else { - taskList[listNumber - 1] = listNumber + ". " + userInput; + taskList[listNumber - 1] = EMPTY_BOX + " " + userInput; System.out.printf(INDENT + "Added: %s%n", "", userInput); + listNumber++; } } From b0187dc74b3ecdcc9a17ad265863a4a7406cc308 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Sat, 1 Feb 2025 14:37:46 +0800 Subject: [PATCH 06/66] Add a Task class to reperesent tasks --- src/main/java/Task.java | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/main/java/Task.java diff --git a/src/main/java/Task.java b/src/main/java/Task.java new file mode 100644 index 000000000..befe59353 --- /dev/null +++ b/src/main/java/Task.java @@ -0,0 +1,28 @@ +public class Task { + + //parameters for checking and unchecking tasks + public static final String EMPTY_BOX = "[ ]"; + public static final String MARKED_BOX = "[X]"; + + protected String description; + protected boolean isDone; + + public Task(String description) { + this.description = description; + this.isDone = false; + } + + public void markAsDone() { + this.isDone = true; + } + + public void markAsNotDone() { + this.isDone = false; + } + + public String getTaskString() { + String statusIcon = isDone ? MARKED_BOX : EMPTY_BOX; + return statusIcon + " " + description; + } + +} From 41bc78c0571899f7b05fafda4cd23c26bc40b29f Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Sat, 1 Feb 2025 14:38:38 +0800 Subject: [PATCH 07/66] Integrate Task class with Thoto class --- src/main/java/Thoth.java | 41 ++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/src/main/java/Thoth.java b/src/main/java/Thoth.java index d788c8f25..29208b851 100644 --- a/src/main/java/Thoth.java +++ b/src/main/java/Thoth.java @@ -1,55 +1,60 @@ import java.util.Scanner; public class Thoth { + // parameter for task array initialisation public static final int MAX_TASKS = 100; + // parameter for output indentation public static final String INDENT = "%4s"; - public static final String EMPTY_BOX = "[ ]"; - public static final String MARKED_BOX = "[X]"; public static void main(String[] args) { - System.out.println("Hello! I'm Thoth"); - System.out.println("What can I do for you?"); - - String[] taskList = new String[MAX_TASKS]; + printGreetingMessage(); + Task[] taskList = new Task[MAX_TASKS]; String userInput; - - int listNumber = 1; + int taskCount = 1; // Create an endless loop for adding list while (true) { userInput = new Scanner(System.in).nextLine(); - // condition for the user to exit the program + // exit condition if (userInput.equals("bye")) { System.out.printf(INDENT + "Bye. Hope to see you again soon!", ""); break; + // list tasks } else if (userInput.equals("list")) { - for (int i = 0; i < listNumber; i++) { + for (int i = 0; i < taskCount; i++) { if (taskList[i] != null) { - System.out.printf(INDENT + "%d.%s%n", "", i + 1, taskList[i]); + System.out.printf(INDENT + "%d.%s%n", "", i + 1, taskList[i].getTaskString()); } } + // mark tasks } else if (userInput.startsWith("mark")) { String userInputNumber = userInput.replace("mark", "").trim(); int index = Integer.parseInt(userInputNumber) - 1; - taskList[index] = taskList[index].replace(EMPTY_BOX, MARKED_BOX); + taskList[index].markAsDone(); System.out.printf(INDENT + "Nice! I've marked this task as done:%n", ""); - System.out.printf(INDENT + "%s%n", "", taskList[index]); + System.out.printf(INDENT + "%s%n", "", taskList[index].getTaskString()); + // unmark tasks } else if (userInput.startsWith("unmark")) { String userInputNumber = userInput.replace("unmark", "").trim(); int index = Integer.parseInt(userInputNumber) - 1; - taskList[index] = taskList[index].replace(MARKED_BOX, EMPTY_BOX); + taskList[index].markAsNotDone(); System.out.printf(INDENT + "OK, I've marked this task as not done yet:%n", ""); - System.out.printf(INDENT + "%s%n", "", taskList[index]); + System.out.printf(INDENT + "%s%n", "", taskList[index].getTaskString()); + // add tasks } else { - taskList[listNumber - 1] = EMPTY_BOX + " " + userInput; + taskList[taskCount - 1] = new Task(userInput); System.out.printf(INDENT + "Added: %s%n", "", userInput); - - listNumber++; + taskCount++; } } } + + private static void printGreetingMessage() { + System.out.println("Hello! I'm Thoth"); + System.out.println("What can I do for you?"); + } } From 9eaa586acc0cd8942a1ef480503d6ab121c4d7f9 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Sat, 1 Feb 2025 14:38:38 +0800 Subject: [PATCH 08/66] Integrate Task class with Thoth class --- src/main/java/Thoth.java | 41 ++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/src/main/java/Thoth.java b/src/main/java/Thoth.java index d788c8f25..29208b851 100644 --- a/src/main/java/Thoth.java +++ b/src/main/java/Thoth.java @@ -1,55 +1,60 @@ import java.util.Scanner; public class Thoth { + // parameter for task array initialisation public static final int MAX_TASKS = 100; + // parameter for output indentation public static final String INDENT = "%4s"; - public static final String EMPTY_BOX = "[ ]"; - public static final String MARKED_BOX = "[X]"; public static void main(String[] args) { - System.out.println("Hello! I'm Thoth"); - System.out.println("What can I do for you?"); - - String[] taskList = new String[MAX_TASKS]; + printGreetingMessage(); + Task[] taskList = new Task[MAX_TASKS]; String userInput; - - int listNumber = 1; + int taskCount = 1; // Create an endless loop for adding list while (true) { userInput = new Scanner(System.in).nextLine(); - // condition for the user to exit the program + // exit condition if (userInput.equals("bye")) { System.out.printf(INDENT + "Bye. Hope to see you again soon!", ""); break; + // list tasks } else if (userInput.equals("list")) { - for (int i = 0; i < listNumber; i++) { + for (int i = 0; i < taskCount; i++) { if (taskList[i] != null) { - System.out.printf(INDENT + "%d.%s%n", "", i + 1, taskList[i]); + System.out.printf(INDENT + "%d.%s%n", "", i + 1, taskList[i].getTaskString()); } } + // mark tasks } else if (userInput.startsWith("mark")) { String userInputNumber = userInput.replace("mark", "").trim(); int index = Integer.parseInt(userInputNumber) - 1; - taskList[index] = taskList[index].replace(EMPTY_BOX, MARKED_BOX); + taskList[index].markAsDone(); System.out.printf(INDENT + "Nice! I've marked this task as done:%n", ""); - System.out.printf(INDENT + "%s%n", "", taskList[index]); + System.out.printf(INDENT + "%s%n", "", taskList[index].getTaskString()); + // unmark tasks } else if (userInput.startsWith("unmark")) { String userInputNumber = userInput.replace("unmark", "").trim(); int index = Integer.parseInt(userInputNumber) - 1; - taskList[index] = taskList[index].replace(MARKED_BOX, EMPTY_BOX); + taskList[index].markAsNotDone(); System.out.printf(INDENT + "OK, I've marked this task as not done yet:%n", ""); - System.out.printf(INDENT + "%s%n", "", taskList[index]); + System.out.printf(INDENT + "%s%n", "", taskList[index].getTaskString()); + // add tasks } else { - taskList[listNumber - 1] = EMPTY_BOX + " " + userInput; + taskList[taskCount - 1] = new Task(userInput); System.out.printf(INDENT + "Added: %s%n", "", userInput); - - listNumber++; + taskCount++; } } } + + private static void printGreetingMessage() { + System.out.println("Hello! I'm Thoth"); + System.out.println("What can I do for you?"); + } } From c0e76798f30057ae4564a588e5bde33a1b6e8cd6 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Thu, 6 Feb 2025 20:40:13 +0800 Subject: [PATCH 09/66] Add taskManager class to refactor main code --- src/main/java/TaskManager.java | 25 +++++++++++++++++++++++++ src/main/java/UserInterface.java | 4 ++++ 2 files changed, 29 insertions(+) create mode 100644 src/main/java/TaskManager.java create mode 100644 src/main/java/UserInterface.java diff --git a/src/main/java/TaskManager.java b/src/main/java/TaskManager.java new file mode 100644 index 000000000..6512217cf --- /dev/null +++ b/src/main/java/TaskManager.java @@ -0,0 +1,25 @@ +// For Task commands +public class TaskManager { + public static final int MAX_TASKS = 100; + private Task[] taskList = new Task[MAX_TASKS]; + private int taskCount = 0; + + public void addTask(Task task) { + taskList[taskCount] = task; + taskCount++; + UserInterface.printMessage("Added: " + task.getTaskString()); + } + + public void markTaskAsDone(int taskId) { + taskList[taskId].markAsDone(); + + } + + public void printTaskList() { + UserInterface.printTask(taskList, taskCount); + } + + public void markTaskAsNotDone(int taskId) { + taskList[taskId].markAsNotDone(); + } +} diff --git a/src/main/java/UserInterface.java b/src/main/java/UserInterface.java new file mode 100644 index 000000000..0523001c8 --- /dev/null +++ b/src/main/java/UserInterface.java @@ -0,0 +1,4 @@ +package PACKAGE_NAME; + +public class UserInterface { +} From b87b63b29285d3e3ca69a7622c4f87e8189ba12a Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Thu, 6 Feb 2025 20:40:35 +0800 Subject: [PATCH 10/66] Add UserInterface class to refactor code --- src/main/java/UserInterface.java | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/main/java/UserInterface.java b/src/main/java/UserInterface.java index 0523001c8..b5b33f659 100644 --- a/src/main/java/UserInterface.java +++ b/src/main/java/UserInterface.java @@ -1,4 +1,33 @@ -package PACKAGE_NAME; +import java.util.Scanner; public class UserInterface { + private Scanner scanner; + public static final String INDENT = "%4s"; + + public UserInterface() { + scanner = new Scanner(System.in); + } + + public String readInput() { + return scanner.nextLine(); + } + + public void printGreetingMessage() { + System.out.println("Hello! I'm Thoth"); + System.out.println("What can I do for you?"); + } + + public static void printMessage(String message) { + System.out.println(message); + } + + public void printGoodbye() { + System.out.println("Bye. Hope to see you again soon!"); + } + + public static void printTask(Task[] task, int taskCount) { + for (int i = 0; i < taskCount; i++) { + System.out.println(task[i].toString()); + } + } } From c6821dc9afbacc44956b5c339701bcd2f89025da Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Thu, 6 Feb 2025 21:37:40 +0800 Subject: [PATCH 11/66] Update Getter function to get task description --- src/main/java/UserInterface.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/main/java/UserInterface.java b/src/main/java/UserInterface.java index b5b33f659..d42dee5a3 100644 --- a/src/main/java/UserInterface.java +++ b/src/main/java/UserInterface.java @@ -25,9 +25,21 @@ public void printGoodbye() { System.out.println("Bye. Hope to see you again soon!"); } + public static void printMarkAsDone(Task task) { + System.out.printf(INDENT + "Nice! I've marked this task as done:%n", ""); + System.out.printf(INDENT + "%s\n", "", task.getTaskString()); + } + + public static void printMarkAsUndone(Task task) { + System.out.printf(INDENT + "OK, I've marked this task as not done yet:%n", ""); + System.out.printf(INDENT + "%s\n", "", task.getTaskString()); + } + public static void printTask(Task[] task, int taskCount) { + int listIndex = 1; for (int i = 0; i < taskCount; i++) { - System.out.println(task[i].toString()); + System.out.printf(INDENT + "%d. %s%n", "", listIndex, task[i].getTaskString()); + listIndex++; } } } From d6a64d9cc8f5dfed881a7f3203315d5300f88b98 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Thu, 6 Feb 2025 21:42:42 +0800 Subject: [PATCH 12/66] Add getter funtion to get task Description --- src/main/java/Task.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/Task.java b/src/main/java/Task.java index befe59353..a74adb701 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -1,5 +1,4 @@ public class Task { - //parameters for checking and unchecking tasks public static final String EMPTY_BOX = "[ ]"; public static final String MARKED_BOX = "[X]"; @@ -25,4 +24,7 @@ public String getTaskString() { return statusIcon + " " + description; } + public String getDescription() { + return description; + } } From 04602e6852a3091c2ad2663e65f98fee6f6ca9cb Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Thu, 6 Feb 2025 21:44:40 +0800 Subject: [PATCH 13/66] Add getter function to get tasklist, taskcount Add method to mark task as not done --- src/main/java/TaskManager.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main/java/TaskManager.java b/src/main/java/TaskManager.java index 6512217cf..f8dad0acf 100644 --- a/src/main/java/TaskManager.java +++ b/src/main/java/TaskManager.java @@ -1,25 +1,27 @@ // For Task commands public class TaskManager { public static final int MAX_TASKS = 100; - private Task[] taskList = new Task[MAX_TASKS]; + private final Task[] taskList = new Task[MAX_TASKS]; private int taskCount = 0; public void addTask(Task task) { taskList[taskCount] = task; taskCount++; - UserInterface.printMessage("Added: " + task.getTaskString()); } public void markTaskAsDone(int taskId) { taskList[taskId].markAsDone(); + } + public void markTaskAsNotDone(int taskId) { + taskList[taskId].markAsNotDone(); } - public void printTaskList() { - UserInterface.printTask(taskList, taskCount); + public int getTaskCount() { + return taskCount; } - public void markTaskAsNotDone(int taskId) { - taskList[taskId].markAsNotDone(); + public Task[] getTaskList() { + return taskList; } } From b10d51224e94922841a8821b726e409d1ee05afd Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Thu, 6 Feb 2025 21:45:57 +0800 Subject: [PATCH 14/66] Refactor code with userinterface class and taskmanager class --- src/main/java/Thoth.java | 54 ++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 32 deletions(-) diff --git a/src/main/java/Thoth.java b/src/main/java/Thoth.java index 29208b851..69ccb980c 100644 --- a/src/main/java/Thoth.java +++ b/src/main/java/Thoth.java @@ -1,60 +1,50 @@ -import java.util.Scanner; public class Thoth { - // parameter for task array initialisation - public static final int MAX_TASKS = 100; - // parameter for output indentation - public static final String INDENT = "%4s"; public static void main(String[] args) { - printGreetingMessage(); - Task[] taskList = new Task[MAX_TASKS]; + // Create The task Manager and the User interface + TaskManager taskManager = new TaskManager(); + UserInterface ui = new UserInterface(); + + // Print Greeting. + ui.printGreetingMessage(); + + // String for user input String userInput; - int taskCount = 1; // Create an endless loop for adding list while (true) { - userInput = new Scanner(System.in).nextLine(); + userInput = ui.readInput(); // exit condition if (userInput.equals("bye")) { - System.out.printf(INDENT + "Bye. Hope to see you again soon!", ""); + ui.printGoodbye(); break; // list tasks } else if (userInput.equals("list")) { - for (int i = 0; i < taskCount; i++) { - if (taskList[i] != null) { - System.out.printf(INDENT + "%d.%s%n", "", i + 1, taskList[i].getTaskString()); - } - } + UserInterface.printTask(taskManager.getTaskList(), taskManager.getTaskCount()); // mark tasks } else if (userInput.startsWith("mark")) { - String userInputNumber = userInput.replace("mark", "").trim(); - int index = Integer.parseInt(userInputNumber) - 1; - taskList[index].markAsDone(); - System.out.printf(INDENT + "Nice! I've marked this task as done:%n", ""); - System.out.printf(INDENT + "%s%n", "", taskList[index].getTaskString()); + int taskIndex = Integer.parseInt(userInput.replace("mark", "").trim()) - 1; + taskManager.markTaskAsDone(taskIndex); + Task updatedTask = taskManager.getTaskList()[taskIndex]; + UserInterface.printMarkAsDone(updatedTask); // unmark tasks } else if (userInput.startsWith("unmark")) { - String userInputNumber = userInput.replace("unmark", "").trim(); - int index = Integer.parseInt(userInputNumber) - 1; - taskList[index].markAsNotDone(); - System.out.printf(INDENT + "OK, I've marked this task as not done yet:%n", ""); - System.out.printf(INDENT + "%s%n", "", taskList[index].getTaskString()); + int taskIndex = Integer.parseInt(userInput.replace("unmark", "").trim()) - 1; + taskManager.markTaskAsNotDone(taskIndex); + Task updatedTask = taskManager.getTaskList()[taskIndex]; + UserInterface.printMarkAsUndone(updatedTask); // add tasks } else { - taskList[taskCount - 1] = new Task(userInput); - System.out.printf(INDENT + "Added: %s%n", "", userInput); - taskCount++; + Task newTask = new Task(userInput); + taskManager.addTask(newTask); + UserInterface.printMessage(String.format(UserInterface.INDENT + "Added: %s", "", newTask.getDescription())); } } } - private static void printGreetingMessage() { - System.out.println("Hello! I'm Thoth"); - System.out.println("What can I do for you?"); - } } From 082dc2c86ded57093e4f32e08c44470ef5425512 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Fri, 7 Feb 2025 10:28:54 +0800 Subject: [PATCH 15/66] Add in Todo, Deadline and Event class for week 4 --- src/main/java/Deadline.java | 4 ++++ src/main/java/Event.java | 4 ++++ src/main/java/Todo.java | 4 ++++ 3 files changed, 12 insertions(+) create mode 100644 src/main/java/Deadline.java create mode 100644 src/main/java/Event.java create mode 100644 src/main/java/Todo.java diff --git a/src/main/java/Deadline.java b/src/main/java/Deadline.java new file mode 100644 index 000000000..1f4ae747a --- /dev/null +++ b/src/main/java/Deadline.java @@ -0,0 +1,4 @@ +package PACKAGE_NAME; + +public class Deadline { +} diff --git a/src/main/java/Event.java b/src/main/java/Event.java new file mode 100644 index 000000000..1483b4631 --- /dev/null +++ b/src/main/java/Event.java @@ -0,0 +1,4 @@ +package PACKAGE_NAME; + +public class Event { +} diff --git a/src/main/java/Todo.java b/src/main/java/Todo.java new file mode 100644 index 000000000..773e8288a --- /dev/null +++ b/src/main/java/Todo.java @@ -0,0 +1,4 @@ +package PACKAGE_NAME; + +public class Todo { +} From 302434811e0b855db81efb8fbad49703ab68974d Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Fri, 7 Feb 2025 10:30:24 +0800 Subject: [PATCH 16/66] Add in Dealine, Todo and Event Class for week 4 --- src/main/java/Deadline.java | 15 +++++++++++++-- src/main/java/Event.java | 14 ++++++++++++-- src/main/java/Todo.java | 14 ++++++++++++-- 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/src/main/java/Deadline.java b/src/main/java/Deadline.java index 1f4ae747a..9cb0cc769 100644 --- a/src/main/java/Deadline.java +++ b/src/main/java/Deadline.java @@ -1,4 +1,15 @@ -package PACKAGE_NAME; +public class Deadline extends Task { -public class Deadline { + protected String by; + + public Deadline(String description, String by) { + super(description); + this.by = by; + } + + @Override + public String toString() { + return "[D]" + super.toString() + " (by: " + by + ")"; + } } + diff --git a/src/main/java/Event.java b/src/main/java/Event.java index 1483b4631..bd028035a 100644 --- a/src/main/java/Event.java +++ b/src/main/java/Event.java @@ -1,4 +1,14 @@ -package PACKAGE_NAME; +public class Event extends Task { -public class Event { + protected String dateRange; + + public Event(String description, String dateRange) { + super(description); + this.dateRange = dateRange; + } + + @Override + public String toString() { + return "[E]" + super.toString() + " (from: " + dateRange + ")"; + } } diff --git a/src/main/java/Todo.java b/src/main/java/Todo.java index 773e8288a..817014c78 100644 --- a/src/main/java/Todo.java +++ b/src/main/java/Todo.java @@ -1,4 +1,14 @@ -package PACKAGE_NAME; +public class Todo extends Task { -public class Todo { + protected String by; + + public Todo(String description) { + super(description); + } + + @Override + public String getTaskString() { + return "[T]" + super.getTaskString(); + } } + From bee16afd44a275b06ca2c2cdf01c1d0143a9ddd2 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Fri, 7 Feb 2025 11:00:47 +0800 Subject: [PATCH 17/66] Add in mthod to print added tasks --- src/main/java/Event.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main/java/Event.java b/src/main/java/Event.java index bd028035a..dc39b5555 100644 --- a/src/main/java/Event.java +++ b/src/main/java/Event.java @@ -1,14 +1,16 @@ public class Event extends Task { - protected String dateRange; + protected String from; + protected String to; - public Event(String description, String dateRange) { + public Event(String description, String from, String to) { super(description); - this.dateRange = dateRange; + this.from = from; + this.to = to; } @Override - public String toString() { - return "[E]" + super.toString() + " (from: " + dateRange + ")"; + public String getTaskString() { + return "[E]" + super.getTaskString() + " (from: " + from + " to: " + to + ")"; } } From e73ef0e95b551a6fc0d0cb1d950ab5ca8e4fb734 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Fri, 7 Feb 2025 11:01:46 +0800 Subject: [PATCH 18/66] Update the overide to correctly overrides the correct parent method --- src/main/java/Deadline.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/Deadline.java b/src/main/java/Deadline.java index 9cb0cc769..71106eafb 100644 --- a/src/main/java/Deadline.java +++ b/src/main/java/Deadline.java @@ -8,8 +8,8 @@ public Deadline(String description, String by) { } @Override - public String toString() { - return "[D]" + super.toString() + " (by: " + by + ")"; + public String getTaskString() { + return "[D]" + super.getTaskString() + " (by: " + by + ")"; } } From ccf30e709a2dfb512d8d579c24b8ec78dd258463 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Fri, 7 Feb 2025 11:03:12 +0800 Subject: [PATCH 19/66] Add method to print added tasks --- src/main/java/UserInterface.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/UserInterface.java b/src/main/java/UserInterface.java index d42dee5a3..a8f9d6ffd 100644 --- a/src/main/java/UserInterface.java +++ b/src/main/java/UserInterface.java @@ -42,4 +42,9 @@ public static void printTask(Task[] task, int taskCount) { listIndex++; } } + public static void printAddedTask(Task task, int taskCount) { + System.out.printf(INDENT + "Got it. I've added this task:\n",""); + System.out.printf(INDENT + "%s\n", "", task.getTaskString()); + System.out.printf(INDENT + "Now you have %d tasks in the list.%n","", taskCount); + } } From ea9d7af461909829e0216c3efd4c0bf8b40a91b9 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Fri, 7 Feb 2025 11:03:43 +0800 Subject: [PATCH 20/66] Revert "Add in mthod to print added tasks" This reverts commit bee16afd44a275b06ca2c2cdf01c1d0143a9ddd2. --- src/main/java/Event.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/main/java/Event.java b/src/main/java/Event.java index dc39b5555..bd028035a 100644 --- a/src/main/java/Event.java +++ b/src/main/java/Event.java @@ -1,16 +1,14 @@ public class Event extends Task { - protected String from; - protected String to; + protected String dateRange; - public Event(String description, String from, String to) { + public Event(String description, String dateRange) { super(description); - this.from = from; - this.to = to; + this.dateRange = dateRange; } @Override - public String getTaskString() { - return "[E]" + super.getTaskString() + " (from: " + from + " to: " + to + ")"; + public String toString() { + return "[E]" + super.toString() + " (from: " + dateRange + ")"; } } From 73f6bd33d6986f29c77abdc2fa9390730b6e91b3 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Fri, 7 Feb 2025 11:04:47 +0800 Subject: [PATCH 21/66] Integrate Todo, Deadline and Event Class with Thoth --- src/main/java/Thoth.java | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/main/java/Thoth.java b/src/main/java/Thoth.java index 69ccb980c..eb3d2c487 100644 --- a/src/main/java/Thoth.java +++ b/src/main/java/Thoth.java @@ -38,7 +38,38 @@ public static void main(String[] args) { Task updatedTask = taskManager.getTaskList()[taskIndex]; UserInterface.printMarkAsUndone(updatedTask); - // add tasks + // mark as todo + } else if (userInput.startsWith("todo")) { + String description = userInput.replace("todo","").trim(); + Task newTask = new Todo(description); + taskManager.addTask(newTask); + UserInterface.printAddedTask(newTask,taskManager.getTaskCount()); + } else if (userInput.startsWith("deadline")) { + String[] parts = userInput.replace("deadline", "").trim().split(" /by "); + String description = parts[0]; + String by = (parts.length > 1) ? parts[1] : "No deadline specified"; + + Task newTask = new Deadline(description, by); + taskManager.addTask(newTask); + UserInterface.printAddedTask(newTask,taskManager.getTaskCount()); + } else if (userInput.startsWith("event")) { + String[] parts = userInput.replace("event", "").trim().split(" /from "); + String description = parts[0].trim(); // Extracts "meeting" + + String from = "No start time specified"; + String to = "No end time specified"; + + if (parts.length > 1) { + String[] timeParts = parts[1].split(" /to "); + from = timeParts[0].trim(); // Extracts "2pm" + if (timeParts.length > 1) { + to = timeParts[1].trim(); // Extracts "4pm" + } + } + + Task newTask = new Event(description, from, to); + taskManager.addTask(newTask); + UserInterface.printAddedTask(newTask, taskManager.getTaskCount()); } else { Task newTask = new Task(userInput); taskManager.addTask(newTask); From dc2ded15e60b3189a418ef1ff03f4b978eca9760 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Fri, 7 Feb 2025 11:07:53 +0800 Subject: [PATCH 22/66] Clean up code formats --- src/main/java/Event.java | 2 +- src/main/java/Thoth.java | 7 +++---- src/main/java/UserInterface.java | 7 ++++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/java/Event.java b/src/main/java/Event.java index bd028035a..c785024bb 100644 --- a/src/main/java/Event.java +++ b/src/main/java/Event.java @@ -2,7 +2,7 @@ public class Event extends Task { protected String dateRange; - public Event(String description, String dateRange) { + public Event(String description, String dateRange, String to) { super(description); this.dateRange = dateRange; } diff --git a/src/main/java/Thoth.java b/src/main/java/Thoth.java index eb3d2c487..04916fc29 100644 --- a/src/main/java/Thoth.java +++ b/src/main/java/Thoth.java @@ -1,4 +1,3 @@ - public class Thoth { public static void main(String[] args) { @@ -40,10 +39,10 @@ public static void main(String[] args) { // mark as todo } else if (userInput.startsWith("todo")) { - String description = userInput.replace("todo","").trim(); + String description = userInput.replace("todo", "").trim(); Task newTask = new Todo(description); taskManager.addTask(newTask); - UserInterface.printAddedTask(newTask,taskManager.getTaskCount()); + UserInterface.printAddedTask(newTask, taskManager.getTaskCount()); } else if (userInput.startsWith("deadline")) { String[] parts = userInput.replace("deadline", "").trim().split(" /by "); String description = parts[0]; @@ -51,7 +50,7 @@ public static void main(String[] args) { Task newTask = new Deadline(description, by); taskManager.addTask(newTask); - UserInterface.printAddedTask(newTask,taskManager.getTaskCount()); + UserInterface.printAddedTask(newTask, taskManager.getTaskCount()); } else if (userInput.startsWith("event")) { String[] parts = userInput.replace("event", "").trim().split(" /from "); String description = parts[0].trim(); // Extracts "meeting" diff --git a/src/main/java/UserInterface.java b/src/main/java/UserInterface.java index a8f9d6ffd..74ff9e33a 100644 --- a/src/main/java/UserInterface.java +++ b/src/main/java/UserInterface.java @@ -1,7 +1,7 @@ import java.util.Scanner; public class UserInterface { - private Scanner scanner; + private final Scanner scanner; public static final String INDENT = "%4s"; public UserInterface() { @@ -42,9 +42,10 @@ public static void printTask(Task[] task, int taskCount) { listIndex++; } } + public static void printAddedTask(Task task, int taskCount) { - System.out.printf(INDENT + "Got it. I've added this task:\n",""); + System.out.printf(INDENT + "Got it. I've added this task:\n", ""); System.out.printf(INDENT + "%s\n", "", task.getTaskString()); - System.out.printf(INDENT + "Now you have %d tasks in the list.%n","", taskCount); + System.out.printf(INDENT + "Now you have %d tasks in the list.%n", "", taskCount); } } From 965019d5e56ed9f581bdf8b134691c1cb2de6ec6 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Fri, 7 Feb 2025 15:43:18 +0800 Subject: [PATCH 23/66] COrrect wrong method used in event --- src/main/java/Event.java | 12 +++++++----- src/main/java/Thoth.java | 5 +++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/main/java/Event.java b/src/main/java/Event.java index c785024bb..d6854067e 100644 --- a/src/main/java/Event.java +++ b/src/main/java/Event.java @@ -1,14 +1,16 @@ public class Event extends Task { - protected String dateRange; + protected String to; + protected String from; - public Event(String description, String dateRange, String to) { + public Event(String description, String from, String to) { super(description); - this.dateRange = dateRange; + this.from = from; + this.to = to; } @Override - public String toString() { - return "[E]" + super.toString() + " (from: " + dateRange + ")"; + public String getTaskString() { + return "[E]" + super.getTaskString() + " (from: " + from +" to: " + to + ")"; } } diff --git a/src/main/java/Thoth.java b/src/main/java/Thoth.java index 04916fc29..46103c64f 100644 --- a/src/main/java/Thoth.java +++ b/src/main/java/Thoth.java @@ -43,6 +43,7 @@ public static void main(String[] args) { Task newTask = new Todo(description); taskManager.addTask(newTask); UserInterface.printAddedTask(newTask, taskManager.getTaskCount()); + } else if (userInput.startsWith("deadline")) { String[] parts = userInput.replace("deadline", "").trim().split(" /by "); String description = parts[0]; @@ -51,11 +52,12 @@ public static void main(String[] args) { Task newTask = new Deadline(description, by); taskManager.addTask(newTask); UserInterface.printAddedTask(newTask, taskManager.getTaskCount()); + } else if (userInput.startsWith("event")) { String[] parts = userInput.replace("event", "").trim().split(" /from "); String description = parts[0].trim(); // Extracts "meeting" - String from = "No start time specified"; + String from = "No end time specified"; String to = "No end time specified"; if (parts.length > 1) { @@ -65,7 +67,6 @@ public static void main(String[] args) { to = timeParts[1].trim(); // Extracts "4pm" } } - Task newTask = new Event(description, from, to); taskManager.addTask(newTask); UserInterface.printAddedTask(newTask, taskManager.getTaskCount()); From 19b5c20c7633f722706a2ead58b87106cf8f8cd8 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Fri, 7 Feb 2025 15:43:28 +0800 Subject: [PATCH 24/66] Revert "COrrect wrong method used in event" This reverts commit 965019d5e56ed9f581bdf8b134691c1cb2de6ec6. --- src/main/java/Event.java | 12 +++++------- src/main/java/Thoth.java | 5 ++--- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/main/java/Event.java b/src/main/java/Event.java index d6854067e..c785024bb 100644 --- a/src/main/java/Event.java +++ b/src/main/java/Event.java @@ -1,16 +1,14 @@ public class Event extends Task { - protected String to; - protected String from; + protected String dateRange; - public Event(String description, String from, String to) { + public Event(String description, String dateRange, String to) { super(description); - this.from = from; - this.to = to; + this.dateRange = dateRange; } @Override - public String getTaskString() { - return "[E]" + super.getTaskString() + " (from: " + from +" to: " + to + ")"; + public String toString() { + return "[E]" + super.toString() + " (from: " + dateRange + ")"; } } diff --git a/src/main/java/Thoth.java b/src/main/java/Thoth.java index 46103c64f..04916fc29 100644 --- a/src/main/java/Thoth.java +++ b/src/main/java/Thoth.java @@ -43,7 +43,6 @@ public static void main(String[] args) { Task newTask = new Todo(description); taskManager.addTask(newTask); UserInterface.printAddedTask(newTask, taskManager.getTaskCount()); - } else if (userInput.startsWith("deadline")) { String[] parts = userInput.replace("deadline", "").trim().split(" /by "); String description = parts[0]; @@ -52,12 +51,11 @@ public static void main(String[] args) { Task newTask = new Deadline(description, by); taskManager.addTask(newTask); UserInterface.printAddedTask(newTask, taskManager.getTaskCount()); - } else if (userInput.startsWith("event")) { String[] parts = userInput.replace("event", "").trim().split(" /from "); String description = parts[0].trim(); // Extracts "meeting" - String from = "No end time specified"; + String from = "No start time specified"; String to = "No end time specified"; if (parts.length > 1) { @@ -67,6 +65,7 @@ public static void main(String[] args) { to = timeParts[1].trim(); // Extracts "4pm" } } + Task newTask = new Event(description, from, to); taskManager.addTask(newTask); UserInterface.printAddedTask(newTask, taskManager.getTaskCount()); From 8515036e463eeed686fa7048447d91f6f7d3bbe0 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Fri, 7 Feb 2025 15:44:04 +0800 Subject: [PATCH 25/66] Reapply "COrrect wrong method used in event" This reverts commit 19b5c20c7633f722706a2ead58b87106cf8f8cd8. --- src/main/java/Event.java | 12 +++++++----- src/main/java/Thoth.java | 5 +++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/main/java/Event.java b/src/main/java/Event.java index c785024bb..d6854067e 100644 --- a/src/main/java/Event.java +++ b/src/main/java/Event.java @@ -1,14 +1,16 @@ public class Event extends Task { - protected String dateRange; + protected String to; + protected String from; - public Event(String description, String dateRange, String to) { + public Event(String description, String from, String to) { super(description); - this.dateRange = dateRange; + this.from = from; + this.to = to; } @Override - public String toString() { - return "[E]" + super.toString() + " (from: " + dateRange + ")"; + public String getTaskString() { + return "[E]" + super.getTaskString() + " (from: " + from +" to: " + to + ")"; } } diff --git a/src/main/java/Thoth.java b/src/main/java/Thoth.java index 04916fc29..46103c64f 100644 --- a/src/main/java/Thoth.java +++ b/src/main/java/Thoth.java @@ -43,6 +43,7 @@ public static void main(String[] args) { Task newTask = new Todo(description); taskManager.addTask(newTask); UserInterface.printAddedTask(newTask, taskManager.getTaskCount()); + } else if (userInput.startsWith("deadline")) { String[] parts = userInput.replace("deadline", "").trim().split(" /by "); String description = parts[0]; @@ -51,11 +52,12 @@ public static void main(String[] args) { Task newTask = new Deadline(description, by); taskManager.addTask(newTask); UserInterface.printAddedTask(newTask, taskManager.getTaskCount()); + } else if (userInput.startsWith("event")) { String[] parts = userInput.replace("event", "").trim().split(" /from "); String description = parts[0].trim(); // Extracts "meeting" - String from = "No start time specified"; + String from = "No end time specified"; String to = "No end time specified"; if (parts.length > 1) { @@ -65,7 +67,6 @@ public static void main(String[] args) { to = timeParts[1].trim(); // Extracts "4pm" } } - Task newTask = new Event(description, from, to); taskManager.addTask(newTask); UserInterface.printAddedTask(newTask, taskManager.getTaskCount()); From f23118b5f80a405c6a14d763e011b6afec081031 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Sat, 15 Feb 2025 09:57:28 +0800 Subject: [PATCH 26/66] Add in excpetion for mark and unmark --- src/main/java/Thoth.java | 57 +++++++++++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 12 deletions(-) diff --git a/src/main/java/Thoth.java b/src/main/java/Thoth.java index 46103c64f..e34fcc444 100644 --- a/src/main/java/Thoth.java +++ b/src/main/java/Thoth.java @@ -25,24 +25,57 @@ public static void main(String[] args) { // mark tasks } else if (userInput.startsWith("mark")) { - int taskIndex = Integer.parseInt(userInput.replace("mark", "").trim()) - 1; - taskManager.markTaskAsDone(taskIndex); - Task updatedTask = taskManager.getTaskList()[taskIndex]; - UserInterface.printMarkAsDone(updatedTask); + while (true) { + try { + int taskIndex = Integer.parseInt(userInput.replace("mark", "").trim()) - 1; + + if (taskIndex < 0 || taskIndex >= taskManager.getTaskCount()) { + System.out.println("Task number out of range! Enter a number between 1 and" + taskManager.getTaskCount()); + userInput = ui.readInput(); + continue; + } + + taskManager.markTaskAsDone(taskIndex); + Task updatedTask = taskManager.getTaskList()[taskIndex]; + UserInterface.printMarkAsDone(updatedTask); + break; + + } catch (NumberFormatException e) { + System.out.println("Please enter a number(integer)"); + } + + userInput = ui.readInput(); + } // unmark tasks } else if (userInput.startsWith("unmark")) { - int taskIndex = Integer.parseInt(userInput.replace("unmark", "").trim()) - 1; - taskManager.markTaskAsNotDone(taskIndex); - Task updatedTask = taskManager.getTaskList()[taskIndex]; - UserInterface.printMarkAsUndone(updatedTask); + while(true) { + try { + int taskIndex = Integer.parseInt(userInput.replace("unmark", "").trim()) - 1; + + if (taskIndex < 0 || taskIndex >= taskManager.getTaskCount()) { + System.out.println("Task number out of range! Enter a number between 1 and" + taskManager.getTaskCount()); + userInput = ui.readInput(); + continue; + } + + taskManager.markTaskAsNotDone(taskIndex); + Task updatedTask = taskManager.getTaskList()[taskIndex]; + UserInterface.printMarkAsUndone(updatedTask); + break; + + } catch (NumberFormatException e) { + System.out.println("Please enter a number(integer)"); + } + userInput = ui.readInput(); + } // mark as todo } else if (userInput.startsWith("todo")) { - String description = userInput.replace("todo", "").trim(); - Task newTask = new Todo(description); - taskManager.addTask(newTask); - UserInterface.printAddedTask(newTask, taskManager.getTaskCount()); + String description = userInput.replace("todo", "").trim(); + Task newTask = new Todo(description); + taskManager.addTask(newTask); + UserInterface.printAddedTask(newTask, taskManager.getTaskCount()); } else if (userInput.startsWith("deadline")) { String[] parts = userInput.replace("deadline", "").trim().split(" /by "); From 59a61c8a0ec5a8cf770b2ed28102415342faa95d Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Sat, 15 Feb 2025 10:15:02 +0800 Subject: [PATCH 27/66] Add in condition checks for dealine, event and todo --- src/main/java/Thoth.java | 64 +++++++++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 18 deletions(-) diff --git a/src/main/java/Thoth.java b/src/main/java/Thoth.java index e34fcc444..6c8dc8607 100644 --- a/src/main/java/Thoth.java +++ b/src/main/java/Thoth.java @@ -72,37 +72,65 @@ public static void main(String[] args) { // mark as todo } else if (userInput.startsWith("todo")) { + while (true) { String description = userInput.replace("todo", "").trim(); + + if (description.isEmpty()) { + System.out.println("Opps task description is empty"); + userInput = ui.readInput(); + continue; + } + Task newTask = new Todo(description); taskManager.addTask(newTask); UserInterface.printAddedTask(newTask, taskManager.getTaskCount()); + break; + } } else if (userInput.startsWith("deadline")) { - String[] parts = userInput.replace("deadline", "").trim().split(" /by "); - String description = parts[0]; - String by = (parts.length > 1) ? parts[1] : "No deadline specified"; + while (true) { + String[] parts = userInput.replace("deadline", "").trim().split(" /by "); + String description = parts[0]; + String by = (parts.length > 1) ? parts[1] : "No deadline specified"; + + if (description.isEmpty() || by.isEmpty()) { + System.out.println("Opps task description is empty"); + userInput = ui.readInput(); + continue; + } - Task newTask = new Deadline(description, by); - taskManager.addTask(newTask); - UserInterface.printAddedTask(newTask, taskManager.getTaskCount()); + Task newTask = new Deadline(description, by); + taskManager.addTask(newTask); + UserInterface.printAddedTask(newTask, taskManager.getTaskCount()); + break; + } } else if (userInput.startsWith("event")) { - String[] parts = userInput.replace("event", "").trim().split(" /from "); - String description = parts[0].trim(); // Extracts "meeting" + while (true) { + String[] parts = userInput.replace("event", "").trim().split(" /from "); + String description = parts[0].trim(); // Extracts "meeting" - String from = "No end time specified"; - String to = "No end time specified"; + String from = "No end time specified"; + String to = "No end time specified"; - if (parts.length > 1) { - String[] timeParts = parts[1].split(" /to "); - from = timeParts[0].trim(); // Extracts "2pm" - if (timeParts.length > 1) { - to = timeParts[1].trim(); // Extracts "4pm" + if (parts.length > 1) { + String[] timeParts = parts[1].split(" /to "); + from = timeParts[0].trim(); // Extracts "2pm" + if (timeParts.length > 1) { + to = timeParts[1].trim(); // Extracts "4pm" + } } + + if (from.isEmpty() || to.isEmpty() || description.isEmpty()) { + System.out.println("Opps you input is invalid please check your description or timeframe"); + userInput = ui.readInput(); + continue; + } + Task newTask = new Event(description, from, to); + taskManager.addTask(newTask); + UserInterface.printAddedTask(newTask, taskManager.getTaskCount()); + break; } - Task newTask = new Event(description, from, to); - taskManager.addTask(newTask); - UserInterface.printAddedTask(newTask, taskManager.getTaskCount()); } else { Task newTask = new Task(userInput); taskManager.addTask(newTask); From b09ddb273f530fddea7ed138cab302af1ae1da7c Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Sat, 15 Feb 2025 14:11:36 +0800 Subject: [PATCH 28/66] Orgnize project strucutre --- src/main/java/{ => thoth/logic}/TaskManager.java | 4 ++++ src/main/java/{ => thoth/main}/Thoth.java | 9 +++++++++ src/main/java/{ => thoth/tasks}/Deadline.java | 2 ++ src/main/java/{ => thoth/tasks}/Event.java | 2 ++ src/main/java/{ => thoth/tasks}/Task.java | 2 ++ src/main/java/{ => thoth/tasks}/Todo.java | 2 ++ src/main/java/{ => thoth/ui}/UserInterface.java | 4 ++++ 7 files changed, 25 insertions(+) rename src/main/java/{ => thoth/logic}/TaskManager.java (92%) rename src/main/java/{ => thoth/main}/Thoth.java (96%) rename src/main/java/{ => thoth/tasks}/Deadline.java (93%) rename src/main/java/{ => thoth/tasks}/Event.java (94%) rename src/main/java/{ => thoth/tasks}/Task.java (97%) rename src/main/java/{ => thoth/tasks}/Todo.java (91%) rename src/main/java/{ => thoth/ui}/UserInterface.java (97%) diff --git a/src/main/java/TaskManager.java b/src/main/java/thoth/logic/TaskManager.java similarity index 92% rename from src/main/java/TaskManager.java rename to src/main/java/thoth/logic/TaskManager.java index f8dad0acf..0472925d3 100644 --- a/src/main/java/TaskManager.java +++ b/src/main/java/thoth/logic/TaskManager.java @@ -1,3 +1,7 @@ +package thoth.logic; + +import thoth.tasks.Task; + // For Task commands public class TaskManager { public static final int MAX_TASKS = 100; diff --git a/src/main/java/Thoth.java b/src/main/java/thoth/main/Thoth.java similarity index 96% rename from src/main/java/Thoth.java rename to src/main/java/thoth/main/Thoth.java index 6c8dc8607..e4342c7d2 100644 --- a/src/main/java/Thoth.java +++ b/src/main/java/thoth/main/Thoth.java @@ -1,3 +1,12 @@ +package thoth.main; + +import thoth.logic.TaskManager; +import thoth.tasks.Deadline; +import thoth.tasks.Event; +import thoth.tasks.Task; +import thoth.tasks.Todo; +import thoth.ui.UserInterface; + public class Thoth { public static void main(String[] args) { diff --git a/src/main/java/Deadline.java b/src/main/java/thoth/tasks/Deadline.java similarity index 93% rename from src/main/java/Deadline.java rename to src/main/java/thoth/tasks/Deadline.java index 71106eafb..17833d9ce 100644 --- a/src/main/java/Deadline.java +++ b/src/main/java/thoth/tasks/Deadline.java @@ -1,3 +1,5 @@ +package thoth.tasks; + public class Deadline extends Task { protected String by; diff --git a/src/main/java/Event.java b/src/main/java/thoth/tasks/Event.java similarity index 94% rename from src/main/java/Event.java rename to src/main/java/thoth/tasks/Event.java index d6854067e..1bd60b764 100644 --- a/src/main/java/Event.java +++ b/src/main/java/thoth/tasks/Event.java @@ -1,3 +1,5 @@ +package thoth.tasks; + public class Event extends Task { protected String to; diff --git a/src/main/java/Task.java b/src/main/java/thoth/tasks/Task.java similarity index 97% rename from src/main/java/Task.java rename to src/main/java/thoth/tasks/Task.java index a74adb701..b04ea13f4 100644 --- a/src/main/java/Task.java +++ b/src/main/java/thoth/tasks/Task.java @@ -1,3 +1,5 @@ +package thoth.tasks; + public class Task { //parameters for checking and unchecking tasks public static final String EMPTY_BOX = "[ ]"; diff --git a/src/main/java/Todo.java b/src/main/java/thoth/tasks/Todo.java similarity index 91% rename from src/main/java/Todo.java rename to src/main/java/thoth/tasks/Todo.java index 817014c78..78943407d 100644 --- a/src/main/java/Todo.java +++ b/src/main/java/thoth/tasks/Todo.java @@ -1,3 +1,5 @@ +package thoth.tasks; + public class Todo extends Task { protected String by; diff --git a/src/main/java/UserInterface.java b/src/main/java/thoth/ui/UserInterface.java similarity index 97% rename from src/main/java/UserInterface.java rename to src/main/java/thoth/ui/UserInterface.java index 74ff9e33a..941863eed 100644 --- a/src/main/java/UserInterface.java +++ b/src/main/java/thoth/ui/UserInterface.java @@ -1,3 +1,7 @@ +package thoth.ui; + +import thoth.tasks.Task; + import java.util.Scanner; public class UserInterface { From 437ecc3f8810b5d3e570b88cb13f531418ac7a8f Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Thu, 20 Feb 2025 14:02:36 +0800 Subject: [PATCH 29/66] Add command class and parser class Refactor thoth class code into command and parser --- src/main/java/thoth/command/Command.java | 12 ++ .../java/thoth/command/DeadlineCommand.java | 22 +++ .../java/thoth/command/DefaultCommand.java | 18 +++ src/main/java/thoth/command/EventCommand.java | 24 ++++ src/main/java/thoth/command/ExitCommand.java | 16 +++ src/main/java/thoth/command/ListCommand.java | 12 ++ src/main/java/thoth/command/MarkCommand.java | 19 +++ src/main/java/thoth/command/TodoCommand.java | 20 +++ .../java/thoth/command/UnknownCommand.java | 16 +++ .../java/thoth/command/UnmarkCommand.java | 19 +++ src/main/java/thoth/main/Thoth.java | 126 +----------------- src/main/java/thoth/parser/Parser.java | 71 ++++++++++ src/main/java/thoth/ui/UserInterface.java | 5 + 13 files changed, 260 insertions(+), 120 deletions(-) create mode 100644 src/main/java/thoth/command/Command.java create mode 100644 src/main/java/thoth/command/DeadlineCommand.java create mode 100644 src/main/java/thoth/command/DefaultCommand.java create mode 100644 src/main/java/thoth/command/EventCommand.java create mode 100644 src/main/java/thoth/command/ExitCommand.java create mode 100644 src/main/java/thoth/command/ListCommand.java create mode 100644 src/main/java/thoth/command/MarkCommand.java create mode 100644 src/main/java/thoth/command/TodoCommand.java create mode 100644 src/main/java/thoth/command/UnknownCommand.java create mode 100644 src/main/java/thoth/command/UnmarkCommand.java create mode 100644 src/main/java/thoth/parser/Parser.java diff --git a/src/main/java/thoth/command/Command.java b/src/main/java/thoth/command/Command.java new file mode 100644 index 000000000..7f8da7390 --- /dev/null +++ b/src/main/java/thoth/command/Command.java @@ -0,0 +1,12 @@ +package thoth.command; + +import thoth.logic.TaskManager; +import thoth.ui.UserInterface; + +public abstract class Command { + public abstract void execute(TaskManager taskManager, UserInterface ui); + + public boolean isExit() { + return false; + } +} diff --git a/src/main/java/thoth/command/DeadlineCommand.java b/src/main/java/thoth/command/DeadlineCommand.java new file mode 100644 index 000000000..ca1666be2 --- /dev/null +++ b/src/main/java/thoth/command/DeadlineCommand.java @@ -0,0 +1,22 @@ +package thoth.command; + +import thoth.logic.TaskManager; +import thoth.tasks.Deadline; +import thoth.tasks.Task; +import thoth.ui.UserInterface; + +public class DeadlineCommand extends Command { + String description; + String by; + public DeadlineCommand(String description, String by) { + this.description = description; + this.by = by; + } + + @Override + public void execute(TaskManager taskManager, UserInterface ui) { + Task newTask = new Deadline(description, by); + taskManager.addTask(newTask); + UserInterface.printAddedTask(newTask, taskManager.getTaskCount()); + } +} diff --git a/src/main/java/thoth/command/DefaultCommand.java b/src/main/java/thoth/command/DefaultCommand.java new file mode 100644 index 000000000..d25c9c624 --- /dev/null +++ b/src/main/java/thoth/command/DefaultCommand.java @@ -0,0 +1,18 @@ +package thoth.command; + +import thoth.logic.TaskManager; +import thoth.tasks.Task; +import thoth.ui.UserInterface; + +public class DefaultCommand extends Command { + String userInput; + public DefaultCommand(String userInput) { + this.userInput = userInput; + } + @Override + public void execute(TaskManager taskManager, UserInterface ui) { + Task newTask = new Task(userInput); + taskManager.addTask(newTask); + UserInterface.printMessage(String.format(UserInterface.INDENT + "Added: %s", "", newTask.getDescription())); + } +} diff --git a/src/main/java/thoth/command/EventCommand.java b/src/main/java/thoth/command/EventCommand.java new file mode 100644 index 000000000..337b6f141 --- /dev/null +++ b/src/main/java/thoth/command/EventCommand.java @@ -0,0 +1,24 @@ +package thoth.command; + +import thoth.logic.TaskManager; +import thoth.tasks.Event; +import thoth.tasks.Task; +import thoth.ui.UserInterface; + +public class EventCommand extends Command { + String description; + String from; + String to; + public EventCommand(String description, String from, String to) { + this.description = description; + this.from = from; + this.to = to; + } + + @Override + public void execute(TaskManager taskManager, UserInterface ui) { + Task newTask = new Event(description, from, to); + taskManager.addTask(newTask); + UserInterface.printAddedTask(newTask, taskManager.getTaskCount()); + } +} diff --git a/src/main/java/thoth/command/ExitCommand.java b/src/main/java/thoth/command/ExitCommand.java new file mode 100644 index 000000000..34fcc365c --- /dev/null +++ b/src/main/java/thoth/command/ExitCommand.java @@ -0,0 +1,16 @@ +package thoth.command; + +import thoth.logic.TaskManager; +import thoth.ui.UserInterface; + +public class ExitCommand extends Command { + + @Override + public void execute(TaskManager taskManager, UserInterface ui) { + ui.printGoodbye(); + } + @Override + public boolean isExit() { + return true; + } +} diff --git a/src/main/java/thoth/command/ListCommand.java b/src/main/java/thoth/command/ListCommand.java new file mode 100644 index 000000000..0a060d52a --- /dev/null +++ b/src/main/java/thoth/command/ListCommand.java @@ -0,0 +1,12 @@ +package thoth.command; + +import thoth.logic.TaskManager; +import thoth.ui.UserInterface; + +public class ListCommand extends Command { + + @Override + public void execute(TaskManager taskManager, UserInterface ui) { + UserInterface.printTask(taskManager.getTaskList(), taskManager.getTaskCount()); + } +} diff --git a/src/main/java/thoth/command/MarkCommand.java b/src/main/java/thoth/command/MarkCommand.java new file mode 100644 index 000000000..2983362b5 --- /dev/null +++ b/src/main/java/thoth/command/MarkCommand.java @@ -0,0 +1,19 @@ +package thoth.command; + +import thoth.logic.TaskManager; +import thoth.tasks.Task; +import thoth.ui.UserInterface; + +public class MarkCommand extends Command{ + int taskIndex; + public MarkCommand(int taskIndex) { + this.taskIndex = taskIndex; + } + + @Override + public void execute(TaskManager taskManager, UserInterface ui) { + taskManager.markTaskAsDone(taskIndex); + Task updatedTask = taskManager.getTaskList()[taskIndex]; + UserInterface.printMarkAsUndone(updatedTask); + } +} diff --git a/src/main/java/thoth/command/TodoCommand.java b/src/main/java/thoth/command/TodoCommand.java new file mode 100644 index 000000000..b5936bb70 --- /dev/null +++ b/src/main/java/thoth/command/TodoCommand.java @@ -0,0 +1,20 @@ +package thoth.command; + +import thoth.logic.TaskManager; +import thoth.tasks.Task; +import thoth.tasks.Todo; +import thoth.ui.UserInterface; + +public class TodoCommand extends Command{ + String description; + public TodoCommand(String description) { + this.description = description; + } + + @Override + public void execute(TaskManager taskManager, UserInterface ui) { + Task newTask = new Todo(description); + taskManager.addTask(newTask); + UserInterface.printAddedTask(newTask, taskManager.getTaskCount()); + } +} diff --git a/src/main/java/thoth/command/UnknownCommand.java b/src/main/java/thoth/command/UnknownCommand.java new file mode 100644 index 000000000..17adde3b6 --- /dev/null +++ b/src/main/java/thoth/command/UnknownCommand.java @@ -0,0 +1,16 @@ +package thoth.command; + +import thoth.logic.TaskManager; +import thoth.ui.UserInterface; + +public class UnknownCommand extends Command{ + String message; + public UnknownCommand(String message) { + this.message = message; + } + + @Override + public void execute(TaskManager taskManager, UserInterface ui) { + UserInterface.printMessage(message); + } +} diff --git a/src/main/java/thoth/command/UnmarkCommand.java b/src/main/java/thoth/command/UnmarkCommand.java new file mode 100644 index 000000000..82eb7cc7f --- /dev/null +++ b/src/main/java/thoth/command/UnmarkCommand.java @@ -0,0 +1,19 @@ +package thoth.command; + +import thoth.logic.TaskManager; +import thoth.tasks.Task; +import thoth.ui.UserInterface; + +public class UnmarkCommand extends Command{ + int taskIndex; + public UnmarkCommand(int taskIndex) { + this.taskIndex = taskIndex; + } + + @Override + public void execute(TaskManager taskManager, UserInterface ui) { + taskManager.markTaskAsNotDone(taskIndex); + Task updatedTask = taskManager.getTaskList()[taskIndex]; + UserInterface.printMarkAsUndone(updatedTask); + } +} diff --git a/src/main/java/thoth/main/Thoth.java b/src/main/java/thoth/main/Thoth.java index e4342c7d2..9c5bf966b 100644 --- a/src/main/java/thoth/main/Thoth.java +++ b/src/main/java/thoth/main/Thoth.java @@ -1,6 +1,8 @@ package thoth.main; +import thoth.command.Command; import thoth.logic.TaskManager; +import thoth.parser.Parser; import thoth.tasks.Deadline; import thoth.tasks.Event; import thoth.tasks.Task; @@ -23,127 +25,11 @@ public static void main(String[] args) { // Create an endless loop for adding list while (true) { userInput = ui.readInput(); - // exit condition - if (userInput.equals("bye")) { - ui.printGoodbye(); - break; - - // list tasks - } else if (userInput.equals("list")) { - UserInterface.printTask(taskManager.getTaskList(), taskManager.getTaskCount()); - - // mark tasks - } else if (userInput.startsWith("mark")) { - while (true) { - try { - int taskIndex = Integer.parseInt(userInput.replace("mark", "").trim()) - 1; - - if (taskIndex < 0 || taskIndex >= taskManager.getTaskCount()) { - System.out.println("Task number out of range! Enter a number between 1 and" + taskManager.getTaskCount()); - userInput = ui.readInput(); - continue; - } - - taskManager.markTaskAsDone(taskIndex); - Task updatedTask = taskManager.getTaskList()[taskIndex]; - UserInterface.printMarkAsDone(updatedTask); - break; - - } catch (NumberFormatException e) { - System.out.println("Please enter a number(integer)"); - } - - userInput = ui.readInput(); - } - - // unmark tasks - } else if (userInput.startsWith("unmark")) { - while(true) { - try { - int taskIndex = Integer.parseInt(userInput.replace("unmark", "").trim()) - 1; - - if (taskIndex < 0 || taskIndex >= taskManager.getTaskCount()) { - System.out.println("Task number out of range! Enter a number between 1 and" + taskManager.getTaskCount()); - userInput = ui.readInput(); - continue; - } - - taskManager.markTaskAsNotDone(taskIndex); - Task updatedTask = taskManager.getTaskList()[taskIndex]; - UserInterface.printMarkAsUndone(updatedTask); - break; - - } catch (NumberFormatException e) { - System.out.println("Please enter a number(integer)"); - } - userInput = ui.readInput(); - } + Command command = Parser.parse(userInput); + command.execute(taskManager,ui); - // mark as todo - } else if (userInput.startsWith("todo")) { - while (true) { - String description = userInput.replace("todo", "").trim(); - - if (description.isEmpty()) { - System.out.println("Opps task description is empty"); - userInput = ui.readInput(); - continue; - } - - Task newTask = new Todo(description); - taskManager.addTask(newTask); - UserInterface.printAddedTask(newTask, taskManager.getTaskCount()); - break; - } - - } else if (userInput.startsWith("deadline")) { - while (true) { - String[] parts = userInput.replace("deadline", "").trim().split(" /by "); - String description = parts[0]; - String by = (parts.length > 1) ? parts[1] : "No deadline specified"; - - if (description.isEmpty() || by.isEmpty()) { - System.out.println("Opps task description is empty"); - userInput = ui.readInput(); - continue; - } - - Task newTask = new Deadline(description, by); - taskManager.addTask(newTask); - UserInterface.printAddedTask(newTask, taskManager.getTaskCount()); - break; - } - - } else if (userInput.startsWith("event")) { - while (true) { - String[] parts = userInput.replace("event", "").trim().split(" /from "); - String description = parts[0].trim(); // Extracts "meeting" - - String from = "No end time specified"; - String to = "No end time specified"; - - if (parts.length > 1) { - String[] timeParts = parts[1].split(" /to "); - from = timeParts[0].trim(); // Extracts "2pm" - if (timeParts.length > 1) { - to = timeParts[1].trim(); // Extracts "4pm" - } - } - - if (from.isEmpty() || to.isEmpty() || description.isEmpty()) { - System.out.println("Opps you input is invalid please check your description or timeframe"); - userInput = ui.readInput(); - continue; - } - Task newTask = new Event(description, from, to); - taskManager.addTask(newTask); - UserInterface.printAddedTask(newTask, taskManager.getTaskCount()); - break; - } - } else { - Task newTask = new Task(userInput); - taskManager.addTask(newTask); - UserInterface.printMessage(String.format(UserInterface.INDENT + "Added: %s", "", newTask.getDescription())); + if(command.isExit()) { + break; } } } diff --git a/src/main/java/thoth/parser/Parser.java b/src/main/java/thoth/parser/Parser.java new file mode 100644 index 000000000..96bd23efa --- /dev/null +++ b/src/main/java/thoth/parser/Parser.java @@ -0,0 +1,71 @@ +package thoth.parser; + +import thoth.command.Command; +import thoth.command.ExitCommand; +import thoth.command.DefaultCommand; +import thoth.command.UnknownCommand; +import thoth.command.ListCommand; +import thoth.command.TodoCommand; +import thoth.command.DeadlineCommand; +import thoth.command.MarkCommand; +import thoth.command.UnmarkCommand; +import thoth.command.EventCommand; + +public class Parser { + + public static Command parse(String userInput) { + userInput = userInput.trim(); + + if (userInput.equals("bye")) { + return new ExitCommand(); + }else if(userInput.equals("list")) { + return new ListCommand(); + }else if(userInput.startsWith("mark")) { + try { + int taskIndex = Integer.parseInt(userInput.replace("mark", "").trim()) - 1; + return new MarkCommand(taskIndex); + } catch (NumberFormatException e) { + return new UnknownCommand("Please enter a valid number for mark command."); + } + }else if(userInput.startsWith("unmark")) { + try { + int taskIndex = Integer.parseInt(userInput.replace("unmark", "").trim()) - 1; + return new UnmarkCommand(taskIndex); + } catch (NumberFormatException e) { + return new UnknownCommand("Please enter a valid number for unmark command."); + } + }else if(userInput.startsWith("todo")) { + String description = userInput.replace("todo", "").trim(); + if (description.isEmpty()) { + return new UnknownCommand("Oops task description is empty"); + } + return new TodoCommand(description); + }else if(userInput.startsWith("deadline")) { + String[] parts = userInput.replace("deadline", "").trim().split(" /by "); + String description = parts[0].trim(); + String by = (parts.length > 1) ? parts[1].trim() : ""; + if (description.isEmpty() || by.isEmpty()) { + return new UnknownCommand("Oops task description is empty or deadline not specified"); + } + return new DeadlineCommand(description, by); + }else if(userInput.startsWith("event")) { + String[] parts = userInput.replace("event", "").trim().split(" /from "); + String description = parts[0].trim(); // Extracts "meeting" + String from = ""; + String to = ""; + if (parts.length > 1) { + String[] timeParts = parts[1].split(" /to "); + from = timeParts[0].trim(); // Extracts "2pm" + if (timeParts.length > 1) { + to = timeParts[1].trim(); // Extracts "4pm" + } + } + if(description.isEmpty() || to.isEmpty() || from.isEmpty()) { + return new UnknownCommand("Oops task description is empty or time range not specified"); + } + return new EventCommand(description,from,to); + + } + return new DefaultCommand(userInput); + } +} diff --git a/src/main/java/thoth/ui/UserInterface.java b/src/main/java/thoth/ui/UserInterface.java index 941863eed..9b1f3f940 100644 --- a/src/main/java/thoth/ui/UserInterface.java +++ b/src/main/java/thoth/ui/UserInterface.java @@ -52,4 +52,9 @@ public static void printAddedTask(Task task, int taskCount) { System.out.printf(INDENT + "%s\n", "", task.getTaskString()); System.out.printf(INDENT + "Now you have %d tasks in the list.%n", "", taskCount); } + + public static void printErrorWrongFormat() { + System.out.printf(INDENT + "Please enter a valid number for the command.%n", ""); + } + } From d02632dd1cca2215487c5b2bc289c18e99e2a78b Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Thu, 20 Feb 2025 14:04:29 +0800 Subject: [PATCH 30/66] Delete redundent imports --- src/main/java/thoth/main/Thoth.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/java/thoth/main/Thoth.java b/src/main/java/thoth/main/Thoth.java index 9c5bf966b..73426f1d9 100644 --- a/src/main/java/thoth/main/Thoth.java +++ b/src/main/java/thoth/main/Thoth.java @@ -3,10 +3,6 @@ import thoth.command.Command; import thoth.logic.TaskManager; import thoth.parser.Parser; -import thoth.tasks.Deadline; -import thoth.tasks.Event; -import thoth.tasks.Task; -import thoth.tasks.Todo; import thoth.ui.UserInterface; public class Thoth { @@ -24,8 +20,11 @@ public static void main(String[] args) { // Create an endless loop for adding list while (true) { + userInput = ui.readInput(); + // extracts out the command from the user input Command command = Parser.parse(userInput); + // Executes the command parsed out command.execute(taskManager,ui); if(command.isExit()) { @@ -33,5 +32,4 @@ public static void main(String[] args) { } } } - } From 3fb4e7e79a62ff6de1420ab4da48596f56a459f1 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Thu, 20 Feb 2025 15:42:58 +0800 Subject: [PATCH 31/66] Change tasklist to arraylist --- src/main/java/thoth/command/MarkCommand.java | 2 +- .../java/thoth/command/UnmarkCommand.java | 2 +- src/main/java/thoth/logic/TaskManager.java | 26 ++++++++++++------- src/main/java/thoth/ui/UserInterface.java | 11 +++++--- 4 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/main/java/thoth/command/MarkCommand.java b/src/main/java/thoth/command/MarkCommand.java index 2983362b5..c9270c4ff 100644 --- a/src/main/java/thoth/command/MarkCommand.java +++ b/src/main/java/thoth/command/MarkCommand.java @@ -13,7 +13,7 @@ public MarkCommand(int taskIndex) { @Override public void execute(TaskManager taskManager, UserInterface ui) { taskManager.markTaskAsDone(taskIndex); - Task updatedTask = taskManager.getTaskList()[taskIndex]; + Task updatedTask = taskManager.getTaskList().get(taskIndex); UserInterface.printMarkAsUndone(updatedTask); } } diff --git a/src/main/java/thoth/command/UnmarkCommand.java b/src/main/java/thoth/command/UnmarkCommand.java index 82eb7cc7f..32e22dbd2 100644 --- a/src/main/java/thoth/command/UnmarkCommand.java +++ b/src/main/java/thoth/command/UnmarkCommand.java @@ -13,7 +13,7 @@ public UnmarkCommand(int taskIndex) { @Override public void execute(TaskManager taskManager, UserInterface ui) { taskManager.markTaskAsNotDone(taskIndex); - Task updatedTask = taskManager.getTaskList()[taskIndex]; + Task updatedTask = taskManager.getTaskList().get(taskIndex); UserInterface.printMarkAsUndone(updatedTask); } } diff --git a/src/main/java/thoth/logic/TaskManager.java b/src/main/java/thoth/logic/TaskManager.java index 0472925d3..feb41854d 100644 --- a/src/main/java/thoth/logic/TaskManager.java +++ b/src/main/java/thoth/logic/TaskManager.java @@ -1,31 +1,39 @@ package thoth.logic; import thoth.tasks.Task; +import java.util.ArrayList; +import java.util.List; // For Task commands public class TaskManager { - public static final int MAX_TASKS = 100; - private final Task[] taskList = new Task[MAX_TASKS]; - private int taskCount = 0; + + private final List taskList = new ArrayList<>(); public void addTask(Task task) { - taskList[taskCount] = task; - taskCount++; + taskList.add(task); } public void markTaskAsDone(int taskId) { - taskList[taskId].markAsDone(); + taskList.get(taskId).markAsDone(); } public void markTaskAsNotDone(int taskId) { - taskList[taskId].markAsNotDone(); + taskList.get(taskId).markAsNotDone(); } public int getTaskCount() { - return taskCount; + return taskList.size(); } - public Task[] getTaskList() { + public List getTaskList() { return taskList; } + + public Task removeTask(int taskId) { + return taskList.remove(taskId); + } + + public List getTask(int taskId) { + return taskList.subList(taskId, taskList.size()); + } } diff --git a/src/main/java/thoth/ui/UserInterface.java b/src/main/java/thoth/ui/UserInterface.java index 9b1f3f940..74694d332 100644 --- a/src/main/java/thoth/ui/UserInterface.java +++ b/src/main/java/thoth/ui/UserInterface.java @@ -2,6 +2,7 @@ import thoth.tasks.Task; +import java.util.List; import java.util.Scanner; public class UserInterface { @@ -39,10 +40,10 @@ public static void printMarkAsUndone(Task task) { System.out.printf(INDENT + "%s\n", "", task.getTaskString()); } - public static void printTask(Task[] task, int taskCount) { + public static void printTask(List task, int taskCount) { int listIndex = 1; for (int i = 0; i < taskCount; i++) { - System.out.printf(INDENT + "%d. %s%n", "", listIndex, task[i].getTaskString()); + System.out.printf(INDENT + "%d. %s%n", "", listIndex, task.get(i).getTaskString()); listIndex++; } } @@ -53,8 +54,10 @@ public static void printAddedTask(Task task, int taskCount) { System.out.printf(INDENT + "Now you have %d tasks in the list.%n", "", taskCount); } - public static void printErrorWrongFormat() { - System.out.printf(INDENT + "Please enter a valid number for the command.%n", ""); + public static void printDeleteTask(List task, int taskCount) { + System.out.printf(INDENT + "Noted. I've removed this task:\n", ""); + System.out.printf(INDENT + "%s\n", "", task.get(0).getTaskString()); + System.out.printf(INDENT + "Now you have %d tasks in the list.%n", "", taskCount); } } From 4ac766b8f2849882e49d72e0651fb086fb7c9670 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Thu, 20 Feb 2025 15:43:53 +0800 Subject: [PATCH 32/66] Add parser coditon to get command for delete Add deleteCommand class to delete tasks --- .../java/thoth/command/DeleteCommand.java | 17 ++++++++++++++++ src/main/java/thoth/parser/Parser.java | 20 +++++++++---------- 2 files changed, 26 insertions(+), 11 deletions(-) create mode 100644 src/main/java/thoth/command/DeleteCommand.java diff --git a/src/main/java/thoth/command/DeleteCommand.java b/src/main/java/thoth/command/DeleteCommand.java new file mode 100644 index 000000000..30964f05c --- /dev/null +++ b/src/main/java/thoth/command/DeleteCommand.java @@ -0,0 +1,17 @@ +package thoth.command; + +import thoth.logic.TaskManager; +import thoth.ui.UserInterface; + +public class DeleteCommand extends Command { + int taskIndex; + public DeleteCommand(int taskIndex) { + this.taskIndex = taskIndex; + } + + @Override + public void execute(TaskManager taskManager, UserInterface ui) { + UserInterface.printDeleteTask(taskManager.getTask(taskIndex), taskManager.getTaskCount() - 1); + taskManager.removeTask(taskIndex); + } +} diff --git a/src/main/java/thoth/parser/Parser.java b/src/main/java/thoth/parser/Parser.java index 96bd23efa..f2bc5f504 100644 --- a/src/main/java/thoth/parser/Parser.java +++ b/src/main/java/thoth/parser/Parser.java @@ -1,15 +1,6 @@ package thoth.parser; -import thoth.command.Command; -import thoth.command.ExitCommand; -import thoth.command.DefaultCommand; -import thoth.command.UnknownCommand; -import thoth.command.ListCommand; -import thoth.command.TodoCommand; -import thoth.command.DeadlineCommand; -import thoth.command.MarkCommand; -import thoth.command.UnmarkCommand; -import thoth.command.EventCommand; +import thoth.command.*; public class Parser { @@ -34,7 +25,14 @@ public static Command parse(String userInput) { } catch (NumberFormatException e) { return new UnknownCommand("Please enter a valid number for unmark command."); } - }else if(userInput.startsWith("todo")) { + }else if(userInput.startsWith("delete")) { + try { + int taskIndex = Integer.parseInt(userInput.replace("delete", "").trim()) - 1; + return new DeleteCommand(taskIndex); + } catch (NumberFormatException e) { + return new UnknownCommand("Please enter a valid number for delete command."); + } + } else if(userInput.startsWith("todo")) { String description = userInput.replace("todo", "").trim(); if (description.isEmpty()) { return new UnknownCommand("Oops task description is empty"); From 3e2ea062565e1fedf718ef273fd2777d7a9810bb Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Thu, 20 Feb 2025 18:53:23 +0800 Subject: [PATCH 33/66] Add abillity to write to data.txt file --- src/main/java/thoth/command/DeadlineCommand.java | 9 +++++++++ src/main/java/thoth/command/EventCommand.java | 8 ++++++++ src/main/java/thoth/command/TodoCommand.java | 8 ++++++++ src/main/java/thoth/storage/Storage.java | 4 ++++ 4 files changed, 29 insertions(+) create mode 100644 src/main/java/thoth/storage/Storage.java diff --git a/src/main/java/thoth/command/DeadlineCommand.java b/src/main/java/thoth/command/DeadlineCommand.java index ca1666be2..fd7aad623 100644 --- a/src/main/java/thoth/command/DeadlineCommand.java +++ b/src/main/java/thoth/command/DeadlineCommand.java @@ -1,10 +1,14 @@ package thoth.command; +import com.sun.source.util.TaskListener; import thoth.logic.TaskManager; +import thoth.storage.Storage; import thoth.tasks.Deadline; import thoth.tasks.Task; import thoth.ui.UserInterface; +import java.io.IOException; + public class DeadlineCommand extends Command { String description; String by; @@ -17,6 +21,11 @@ public DeadlineCommand(String description, String by) { public void execute(TaskManager taskManager, UserInterface ui) { Task newTask = new Deadline(description, by); taskManager.addTask(newTask); + try { + Storage.writeFile(newTask.getTaskString()); + } catch (IOException e) { + UserInterface.printMessage("Error writing to file: " + e.getMessage()); + } UserInterface.printAddedTask(newTask, taskManager.getTaskCount()); } } diff --git a/src/main/java/thoth/command/EventCommand.java b/src/main/java/thoth/command/EventCommand.java index 337b6f141..93ce82e54 100644 --- a/src/main/java/thoth/command/EventCommand.java +++ b/src/main/java/thoth/command/EventCommand.java @@ -1,10 +1,13 @@ package thoth.command; import thoth.logic.TaskManager; +import thoth.storage.Storage; import thoth.tasks.Event; import thoth.tasks.Task; import thoth.ui.UserInterface; +import java.io.IOException; + public class EventCommand extends Command { String description; String from; @@ -19,6 +22,11 @@ public EventCommand(String description, String from, String to) { public void execute(TaskManager taskManager, UserInterface ui) { Task newTask = new Event(description, from, to); taskManager.addTask(newTask); + try { + Storage.writeFile(newTask.getTaskString()); + } catch (IOException e) { + UserInterface.printMessage("Error writing to file: " + e.getMessage()); + } UserInterface.printAddedTask(newTask, taskManager.getTaskCount()); } } diff --git a/src/main/java/thoth/command/TodoCommand.java b/src/main/java/thoth/command/TodoCommand.java index b5936bb70..71fef91b9 100644 --- a/src/main/java/thoth/command/TodoCommand.java +++ b/src/main/java/thoth/command/TodoCommand.java @@ -1,10 +1,13 @@ package thoth.command; import thoth.logic.TaskManager; +import thoth.storage.Storage; import thoth.tasks.Task; import thoth.tasks.Todo; import thoth.ui.UserInterface; +import java.io.IOException; + public class TodoCommand extends Command{ String description; public TodoCommand(String description) { @@ -15,6 +18,11 @@ public TodoCommand(String description) { public void execute(TaskManager taskManager, UserInterface ui) { Task newTask = new Todo(description); taskManager.addTask(newTask); + try { + Storage.writeFile(newTask.getTaskString()); + } catch (IOException e) { + UserInterface.printMessage("Error writing to file: " + e.getMessage()); + } UserInterface.printAddedTask(newTask, taskManager.getTaskCount()); } } diff --git a/src/main/java/thoth/storage/Storage.java b/src/main/java/thoth/storage/Storage.java new file mode 100644 index 000000000..1f81e6a23 --- /dev/null +++ b/src/main/java/thoth/storage/Storage.java @@ -0,0 +1,4 @@ +package thoth.storage; + +public class Storage { +} From dcf7392bbd6a08b837efa25c1c8b199457d05869 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Thu, 20 Feb 2025 18:54:21 +0800 Subject: [PATCH 34/66] Add ability to rewrite data.txt file after modification --- data/data.txt | 3 +++ src/main/java/thoth/command/DeleteCommand.java | 8 ++++++++ src/main/java/thoth/command/MarkCommand.java | 8 ++++++++ src/main/java/thoth/command/UnmarkCommand.java | 8 ++++++++ 4 files changed, 27 insertions(+) create mode 100644 data/data.txt diff --git a/data/data.txt b/data/data.txt new file mode 100644 index 000000000..0e6798205 --- /dev/null +++ b/data/data.txt @@ -0,0 +1,3 @@ +[T][ ] eat +[D][ ] sleep (by: 15pm) +[E][ ] sleep and eat (from: 1am to: 6pm) diff --git a/src/main/java/thoth/command/DeleteCommand.java b/src/main/java/thoth/command/DeleteCommand.java index 30964f05c..97936fd38 100644 --- a/src/main/java/thoth/command/DeleteCommand.java +++ b/src/main/java/thoth/command/DeleteCommand.java @@ -1,8 +1,11 @@ package thoth.command; import thoth.logic.TaskManager; +import thoth.storage.Storage; import thoth.ui.UserInterface; +import java.io.IOException; + public class DeleteCommand extends Command { int taskIndex; public DeleteCommand(int taskIndex) { @@ -13,5 +16,10 @@ public DeleteCommand(int taskIndex) { public void execute(TaskManager taskManager, UserInterface ui) { UserInterface.printDeleteTask(taskManager.getTask(taskIndex), taskManager.getTaskCount() - 1); taskManager.removeTask(taskIndex); + try { + Storage.saveTasks(taskManager.getTaskList()); + } catch (IOException e) { + throw new RuntimeException(e); + } } } diff --git a/src/main/java/thoth/command/MarkCommand.java b/src/main/java/thoth/command/MarkCommand.java index c9270c4ff..87789de99 100644 --- a/src/main/java/thoth/command/MarkCommand.java +++ b/src/main/java/thoth/command/MarkCommand.java @@ -1,9 +1,12 @@ package thoth.command; import thoth.logic.TaskManager; +import thoth.storage.Storage; import thoth.tasks.Task; import thoth.ui.UserInterface; +import java.io.IOException; + public class MarkCommand extends Command{ int taskIndex; public MarkCommand(int taskIndex) { @@ -15,5 +18,10 @@ public void execute(TaskManager taskManager, UserInterface ui) { taskManager.markTaskAsDone(taskIndex); Task updatedTask = taskManager.getTaskList().get(taskIndex); UserInterface.printMarkAsUndone(updatedTask); + try { + Storage.saveTasks(taskManager.getTaskList()); + } catch (IOException e) { + throw new RuntimeException(e); + } } } diff --git a/src/main/java/thoth/command/UnmarkCommand.java b/src/main/java/thoth/command/UnmarkCommand.java index 32e22dbd2..df2304131 100644 --- a/src/main/java/thoth/command/UnmarkCommand.java +++ b/src/main/java/thoth/command/UnmarkCommand.java @@ -1,9 +1,12 @@ package thoth.command; import thoth.logic.TaskManager; +import thoth.storage.Storage; import thoth.tasks.Task; import thoth.ui.UserInterface; +import java.io.IOException; + public class UnmarkCommand extends Command{ int taskIndex; public UnmarkCommand(int taskIndex) { @@ -15,5 +18,10 @@ public void execute(TaskManager taskManager, UserInterface ui) { taskManager.markTaskAsNotDone(taskIndex); Task updatedTask = taskManager.getTaskList().get(taskIndex); UserInterface.printMarkAsUndone(updatedTask); + try { + Storage.saveTasks(taskManager.getTaskList()); + } catch (IOException e) { + throw new RuntimeException(e); + } } } From 2860ae816a66aad08f2dcce06c98ce83ae0525fa Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Thu, 20 Feb 2025 19:00:27 +0800 Subject: [PATCH 35/66] Add methods to create file, wirte file, savetasks and loadtasks with praseing logic from txt to task --- src/main/java/thoth/storage/Storage.java | 145 +++++++++++++++++++++++ 1 file changed, 145 insertions(+) diff --git a/src/main/java/thoth/storage/Storage.java b/src/main/java/thoth/storage/Storage.java index 1f81e6a23..df6e91af0 100644 --- a/src/main/java/thoth/storage/Storage.java +++ b/src/main/java/thoth/storage/Storage.java @@ -1,4 +1,149 @@ package thoth.storage; +import thoth.tasks.Deadline; +import thoth.tasks.Event; +import thoth.tasks.Task; +import thoth.tasks.Todo; + +import java.io.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; + + public class Storage { + + private static final String DEFAULT_FILE_PATH = "./data/data.txt"; + private static final int MIN_HEADER_SIZE = 7; + private static final int TYPE_INDEX = 1; + private static final int DONE_INDEX = 4; + + public static void createFile() throws IOException { + File file = new File(DEFAULT_FILE_PATH); + + // Ensure the parent directories exist (if there are any) + if (file.getParentFile() != null) { + file.getParentFile().mkdirs(); + } + // Create the file if it doesn't already exist + if (!file.exists()) { + file.createNewFile(); + } + } + public static void writeFile(String input) throws IOException { + try (FileWriter fw = new FileWriter(DEFAULT_FILE_PATH,true)) { + fw.append(input).append(System.lineSeparator()); + } + } + public static void saveTasks(List tasks) throws IOException { + try (FileWriter fw = new FileWriter(DEFAULT_FILE_PATH, false)) { + for (Task t : tasks) { + fw.write(t.getTaskString() + System.lineSeparator()); + } + } + } + public static List loadTasks() throws IOException { + List tasks = new ArrayList<>(); + File f = new File(DEFAULT_FILE_PATH); + if (!f.exists()) { + return tasks; // no file => no tasks + } + + try (Scanner s = new Scanner(f)) { + while (s.hasNextLine()) { + String line = s.nextLine().trim(); + Task t = parseLineToTask(line); + if (t != null) { + tasks.add(t); + } + } + } + + return tasks; + } + + private static Task parseLineToTask(String line) { + + if (line.length() < MIN_HEADER_SIZE) { + // Not in the expected format + return null; + } + + char taskType = line.charAt(TYPE_INDEX); // 'D', 'T', or 'E' + char doneChar = line.charAt(DONE_INDEX); // ' ' or 'X' + boolean isDone = (doneChar == 'X'); + + // The rest of the line, e.g. "sleep (by: 15pm)" + String content = line.substring(MIN_HEADER_SIZE).trim(); + + switch (taskType) { + case 'T': { + // e.g. "[T][X] eat" => content = "eat" + Todo todo = new Todo(content); + if (isDone) { + todo.markAsDone(); + } + return todo; + } + case 'D': { + // e.g. "[D][ ] sleep (by: 15pm)" => content = "sleep (by: 15pm)" + // Find "(by: " + int byIndex = content.indexOf("(by:"); + if (byIndex == -1) { + // Not well-formed, handle error or return a default + return null; + } + // description is everything before "(by:" + String description = content.substring(0, byIndex).trim(); + // "15pm)" => remove the trailing ")" + String byPart = content.substring(byIndex + 5).trim(); // skip "(by:" + if (byPart.endsWith(")")) { + byPart = byPart.substring(0, byPart.length() - 1).trim(); + } + + Deadline d = new Deadline(description, byPart); + if (isDone) { + d.markAsDone(); + } + return d; + } + case 'E': { + // e.g. "[E][ ] sleep and eat (from: 1am to: 6pm)" + // content might be "sleep and eat (from: 1am to: 6pm)" + // find "(from:" + int fromIndex = content.indexOf("(from:"); + if (fromIndex == -1) { + return null; + } + String description = content.substring(0, fromIndex).trim(); + // e.g. "1am to: 6pm)" + String fromPart = content.substring(fromIndex + 6).trim(); // skip "(from:" + + // parse fromPart => "1am to: 6pm)" + // find "to:" + int toIndex = fromPart.indexOf("to:"); + if (toIndex == -1) { + return null; + } + String fromTime = fromPart.substring(0, toIndex).trim(); // e.g. "1am" + String toPart = fromPart.substring(toIndex + 3).trim(); // e.g. "6pm)" + + // remove trailing ")" if present + if (toPart.endsWith(")")) { + toPart = toPart.substring(0, toPart.length() - 1).trim(); + } + + // Now create the event + Event e = new Event(description, fromTime, toPart); + if (isDone) { + e.markAsDone(); + } + return e; + } + default: + // Unknown task type + return null; + } + } + } From 112a61f2799a8e1afb06c7dadf3f8b07fd112e32 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Thu, 20 Feb 2025 19:02:04 +0800 Subject: [PATCH 36/66] Remove unused code --- .../java/thoth/command/DefaultCommand.java | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 src/main/java/thoth/command/DefaultCommand.java diff --git a/src/main/java/thoth/command/DefaultCommand.java b/src/main/java/thoth/command/DefaultCommand.java deleted file mode 100644 index d25c9c624..000000000 --- a/src/main/java/thoth/command/DefaultCommand.java +++ /dev/null @@ -1,18 +0,0 @@ -package thoth.command; - -import thoth.logic.TaskManager; -import thoth.tasks.Task; -import thoth.ui.UserInterface; - -public class DefaultCommand extends Command { - String userInput; - public DefaultCommand(String userInput) { - this.userInput = userInput; - } - @Override - public void execute(TaskManager taskManager, UserInterface ui) { - Task newTask = new Task(userInput); - taskManager.addTask(newTask); - UserInterface.printMessage(String.format(UserInterface.INDENT + "Added: %s", "", newTask.getDescription())); - } -} From 4e3f1f5d881d3a26696e1a9d80a940219edf2eaf Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Thu, 20 Feb 2025 19:02:51 +0800 Subject: [PATCH 37/66] Update parser to only handle tasks remove default condition --- src/main/java/thoth/parser/Parser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/thoth/parser/Parser.java b/src/main/java/thoth/parser/Parser.java index f2bc5f504..1e06f43d7 100644 --- a/src/main/java/thoth/parser/Parser.java +++ b/src/main/java/thoth/parser/Parser.java @@ -64,6 +64,6 @@ public static Command parse(String userInput) { return new EventCommand(description,from,to); } - return new DefaultCommand(userInput); + return new UnknownCommand("Oops me no understand you~"); } } From c65277229561b284dab2ca5511ecd3e3208b99f9 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Thu, 20 Feb 2025 19:03:31 +0800 Subject: [PATCH 38/66] Add remove task method --- src/main/java/thoth/logic/TaskManager.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/thoth/logic/TaskManager.java b/src/main/java/thoth/logic/TaskManager.java index feb41854d..34a95796c 100644 --- a/src/main/java/thoth/logic/TaskManager.java +++ b/src/main/java/thoth/logic/TaskManager.java @@ -29,8 +29,8 @@ public List getTaskList() { return taskList; } - public Task removeTask(int taskId) { - return taskList.remove(taskId); + public void removeTask(int taskId) { + taskList.remove(taskId); } public List getTask(int taskId) { From a9e399f7fa53e35c14d57517819f098c8e031ed2 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Thu, 20 Feb 2025 19:04:28 +0800 Subject: [PATCH 39/66] Add data file creation and load data from data file on startup --- src/main/java/thoth/main/Thoth.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/main/java/thoth/main/Thoth.java b/src/main/java/thoth/main/Thoth.java index 73426f1d9..fe449ad4d 100644 --- a/src/main/java/thoth/main/Thoth.java +++ b/src/main/java/thoth/main/Thoth.java @@ -3,8 +3,14 @@ import thoth.command.Command; import thoth.logic.TaskManager; import thoth.parser.Parser; +import thoth.storage.Storage; +import thoth.tasks.Task; import thoth.ui.UserInterface; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.List; + public class Thoth { public static void main(String[] args) { @@ -18,6 +24,18 @@ public static void main(String[] args) { // String for user input String userInput; + try { + Storage.createFile(); + List loadedTasks = Storage.loadTasks(); + // Put those tasks into the TaskManager + for (Task t : loadedTasks) { + taskManager.addTask(t); + } + } catch (IOException e) { + System.err.println("Could not load tasks: " + e.getMessage()); + } + + // Create an endless loop for adding list while (true) { From 4b70796890cc7ce0832fbce2ad6633bf8c6e904b Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Fri, 21 Feb 2025 15:43:23 +0800 Subject: [PATCH 40/66] Build JAR file --- src/main/java/META-INF/MANIFEST.MF | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 src/main/java/META-INF/MANIFEST.MF diff --git a/src/main/java/META-INF/MANIFEST.MF b/src/main/java/META-INF/MANIFEST.MF new file mode 100644 index 000000000..64e33456a --- /dev/null +++ b/src/main/java/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: thoth.main.Thoth + From 754d130be017112099b6102171500b06abd5d9c5 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Fri, 21 Feb 2025 15:43:47 +0800 Subject: [PATCH 41/66] Change file path to absolute path --- src/main/java/thoth/storage/Storage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/thoth/storage/Storage.java b/src/main/java/thoth/storage/Storage.java index df6e91af0..fd8dec912 100644 --- a/src/main/java/thoth/storage/Storage.java +++ b/src/main/java/thoth/storage/Storage.java @@ -13,7 +13,7 @@ public class Storage { - private static final String DEFAULT_FILE_PATH = "./data/data.txt"; + private static final String DEFAULT_FILE_PATH = "C:\\CS2113_IP\\data\\data.txt"; private static final int MIN_HEADER_SIZE = 7; private static final int TYPE_INDEX = 1; private static final int DONE_INDEX = 4; From 8ec23495d59c182d4a8ca25ae44b23179b4bcb65 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Fri, 21 Feb 2025 15:43:59 +0800 Subject: [PATCH 42/66] Input data --- data/data.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/data/data.txt b/data/data.txt index 0e6798205..7b2dada95 100644 --- a/data/data.txt +++ b/data/data.txt @@ -1,3 +1,6 @@ [T][ ] eat -[D][ ] sleep (by: 15pm) -[E][ ] sleep and eat (from: 1am to: 6pm) +[D][ ] sleep (by: 9pm) +[T][ ] eat +[T][ ] sleep +[T][ ] lol +[E][ ] Cheng Zhiyuan attend Cs2113 lecture Friday 21 Feb 2025 (from: 4 to: 6pm) From d05461cee8b4b61017ab7dae2c007b67fde74279 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Thu, 6 Mar 2025 19:33:54 +0800 Subject: [PATCH 43/66] Formate code to follow correct spacing --- .../java/thoth/command/DeadlineCommand.java | 1 + src/main/java/thoth/command/DeleteCommand.java | 1 + src/main/java/thoth/command/EventCommand.java | 1 + src/main/java/thoth/command/ExitCommand.java | 1 + src/main/java/thoth/command/MarkCommand.java | 3 ++- src/main/java/thoth/command/TodoCommand.java | 3 ++- .../java/thoth/command/UnknownCommand.java | 3 ++- src/main/java/thoth/command/UnmarkCommand.java | 3 ++- src/main/java/thoth/logic/TaskManager.java | 1 + src/main/java/thoth/main/Thoth.java | 4 ++-- src/main/java/thoth/parser/Parser.java | 18 +++++++++--------- src/main/java/thoth/storage/Storage.java | 9 ++++++--- src/main/java/thoth/tasks/Event.java | 2 +- 13 files changed, 31 insertions(+), 19 deletions(-) diff --git a/src/main/java/thoth/command/DeadlineCommand.java b/src/main/java/thoth/command/DeadlineCommand.java index fd7aad623..29396ca5b 100644 --- a/src/main/java/thoth/command/DeadlineCommand.java +++ b/src/main/java/thoth/command/DeadlineCommand.java @@ -12,6 +12,7 @@ public class DeadlineCommand extends Command { String description; String by; + public DeadlineCommand(String description, String by) { this.description = description; this.by = by; diff --git a/src/main/java/thoth/command/DeleteCommand.java b/src/main/java/thoth/command/DeleteCommand.java index 97936fd38..0f0163e93 100644 --- a/src/main/java/thoth/command/DeleteCommand.java +++ b/src/main/java/thoth/command/DeleteCommand.java @@ -8,6 +8,7 @@ public class DeleteCommand extends Command { int taskIndex; + public DeleteCommand(int taskIndex) { this.taskIndex = taskIndex; } diff --git a/src/main/java/thoth/command/EventCommand.java b/src/main/java/thoth/command/EventCommand.java index 93ce82e54..b595626aa 100644 --- a/src/main/java/thoth/command/EventCommand.java +++ b/src/main/java/thoth/command/EventCommand.java @@ -12,6 +12,7 @@ public class EventCommand extends Command { String description; String from; String to; + public EventCommand(String description, String from, String to) { this.description = description; this.from = from; diff --git a/src/main/java/thoth/command/ExitCommand.java b/src/main/java/thoth/command/ExitCommand.java index 34fcc365c..3a26fd703 100644 --- a/src/main/java/thoth/command/ExitCommand.java +++ b/src/main/java/thoth/command/ExitCommand.java @@ -9,6 +9,7 @@ public class ExitCommand extends Command { public void execute(TaskManager taskManager, UserInterface ui) { ui.printGoodbye(); } + @Override public boolean isExit() { return true; diff --git a/src/main/java/thoth/command/MarkCommand.java b/src/main/java/thoth/command/MarkCommand.java index 87789de99..4da4edb99 100644 --- a/src/main/java/thoth/command/MarkCommand.java +++ b/src/main/java/thoth/command/MarkCommand.java @@ -7,8 +7,9 @@ import java.io.IOException; -public class MarkCommand extends Command{ +public class MarkCommand extends Command { int taskIndex; + public MarkCommand(int taskIndex) { this.taskIndex = taskIndex; } diff --git a/src/main/java/thoth/command/TodoCommand.java b/src/main/java/thoth/command/TodoCommand.java index 71fef91b9..1ef908c4c 100644 --- a/src/main/java/thoth/command/TodoCommand.java +++ b/src/main/java/thoth/command/TodoCommand.java @@ -8,8 +8,9 @@ import java.io.IOException; -public class TodoCommand extends Command{ +public class TodoCommand extends Command { String description; + public TodoCommand(String description) { this.description = description; } diff --git a/src/main/java/thoth/command/UnknownCommand.java b/src/main/java/thoth/command/UnknownCommand.java index 17adde3b6..bed975f10 100644 --- a/src/main/java/thoth/command/UnknownCommand.java +++ b/src/main/java/thoth/command/UnknownCommand.java @@ -3,8 +3,9 @@ import thoth.logic.TaskManager; import thoth.ui.UserInterface; -public class UnknownCommand extends Command{ +public class UnknownCommand extends Command { String message; + public UnknownCommand(String message) { this.message = message; } diff --git a/src/main/java/thoth/command/UnmarkCommand.java b/src/main/java/thoth/command/UnmarkCommand.java index df2304131..92fa49639 100644 --- a/src/main/java/thoth/command/UnmarkCommand.java +++ b/src/main/java/thoth/command/UnmarkCommand.java @@ -7,8 +7,9 @@ import java.io.IOException; -public class UnmarkCommand extends Command{ +public class UnmarkCommand extends Command { int taskIndex; + public UnmarkCommand(int taskIndex) { this.taskIndex = taskIndex; } diff --git a/src/main/java/thoth/logic/TaskManager.java b/src/main/java/thoth/logic/TaskManager.java index 34a95796c..51b5a3bcf 100644 --- a/src/main/java/thoth/logic/TaskManager.java +++ b/src/main/java/thoth/logic/TaskManager.java @@ -1,6 +1,7 @@ package thoth.logic; import thoth.tasks.Task; + import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/thoth/main/Thoth.java b/src/main/java/thoth/main/Thoth.java index fe449ad4d..eec6268c5 100644 --- a/src/main/java/thoth/main/Thoth.java +++ b/src/main/java/thoth/main/Thoth.java @@ -43,9 +43,9 @@ public static void main(String[] args) { // extracts out the command from the user input Command command = Parser.parse(userInput); // Executes the command parsed out - command.execute(taskManager,ui); + command.execute(taskManager, ui); - if(command.isExit()) { + if (command.isExit()) { break; } } diff --git a/src/main/java/thoth/parser/Parser.java b/src/main/java/thoth/parser/Parser.java index 1e06f43d7..1f635fc5a 100644 --- a/src/main/java/thoth/parser/Parser.java +++ b/src/main/java/thoth/parser/Parser.java @@ -9,36 +9,36 @@ public static Command parse(String userInput) { if (userInput.equals("bye")) { return new ExitCommand(); - }else if(userInput.equals("list")) { + } else if (userInput.equals("list")) { return new ListCommand(); - }else if(userInput.startsWith("mark")) { + } else if (userInput.startsWith("mark")) { try { int taskIndex = Integer.parseInt(userInput.replace("mark", "").trim()) - 1; return new MarkCommand(taskIndex); } catch (NumberFormatException e) { return new UnknownCommand("Please enter a valid number for mark command."); } - }else if(userInput.startsWith("unmark")) { + } else if (userInput.startsWith("unmark")) { try { int taskIndex = Integer.parseInt(userInput.replace("unmark", "").trim()) - 1; return new UnmarkCommand(taskIndex); } catch (NumberFormatException e) { return new UnknownCommand("Please enter a valid number for unmark command."); } - }else if(userInput.startsWith("delete")) { + } else if (userInput.startsWith("delete")) { try { int taskIndex = Integer.parseInt(userInput.replace("delete", "").trim()) - 1; return new DeleteCommand(taskIndex); } catch (NumberFormatException e) { return new UnknownCommand("Please enter a valid number for delete command."); } - } else if(userInput.startsWith("todo")) { + } else if (userInput.startsWith("todo")) { String description = userInput.replace("todo", "").trim(); if (description.isEmpty()) { return new UnknownCommand("Oops task description is empty"); } return new TodoCommand(description); - }else if(userInput.startsWith("deadline")) { + } else if (userInput.startsWith("deadline")) { String[] parts = userInput.replace("deadline", "").trim().split(" /by "); String description = parts[0].trim(); String by = (parts.length > 1) ? parts[1].trim() : ""; @@ -46,7 +46,7 @@ public static Command parse(String userInput) { return new UnknownCommand("Oops task description is empty or deadline not specified"); } return new DeadlineCommand(description, by); - }else if(userInput.startsWith("event")) { + } else if (userInput.startsWith("event")) { String[] parts = userInput.replace("event", "").trim().split(" /from "); String description = parts[0].trim(); // Extracts "meeting" String from = ""; @@ -58,10 +58,10 @@ public static Command parse(String userInput) { to = timeParts[1].trim(); // Extracts "4pm" } } - if(description.isEmpty() || to.isEmpty() || from.isEmpty()) { + if (description.isEmpty() || to.isEmpty() || from.isEmpty()) { return new UnknownCommand("Oops task description is empty or time range not specified"); } - return new EventCommand(description,from,to); + return new EventCommand(description, from, to); } return new UnknownCommand("Oops me no understand you~"); diff --git a/src/main/java/thoth/storage/Storage.java b/src/main/java/thoth/storage/Storage.java index fd8dec912..c9753cfe3 100644 --- a/src/main/java/thoth/storage/Storage.java +++ b/src/main/java/thoth/storage/Storage.java @@ -15,7 +15,7 @@ public class Storage { private static final String DEFAULT_FILE_PATH = "C:\\CS2113_IP\\data\\data.txt"; private static final int MIN_HEADER_SIZE = 7; - private static final int TYPE_INDEX = 1; + private static final int TYPE_INDEX = 1; private static final int DONE_INDEX = 4; public static void createFile() throws IOException { @@ -30,11 +30,13 @@ public static void createFile() throws IOException { file.createNewFile(); } } + public static void writeFile(String input) throws IOException { - try (FileWriter fw = new FileWriter(DEFAULT_FILE_PATH,true)) { + try (FileWriter fw = new FileWriter(DEFAULT_FILE_PATH, true)) { fw.append(input).append(System.lineSeparator()); } } + public static void saveTasks(List tasks) throws IOException { try (FileWriter fw = new FileWriter(DEFAULT_FILE_PATH, false)) { for (Task t : tasks) { @@ -42,6 +44,7 @@ public static void saveTasks(List tasks) throws IOException { } } } + public static List loadTasks() throws IOException { List tasks = new ArrayList<>(); File f = new File(DEFAULT_FILE_PATH); @@ -76,7 +79,7 @@ private static Task parseLineToTask(String line) { // The rest of the line, e.g. "sleep (by: 15pm)" String content = line.substring(MIN_HEADER_SIZE).trim(); - switch (taskType) { + switch(taskType) { case 'T': { // e.g. "[T][X] eat" => content = "eat" Todo todo = new Todo(content); diff --git a/src/main/java/thoth/tasks/Event.java b/src/main/java/thoth/tasks/Event.java index 1bd60b764..2cac9a126 100644 --- a/src/main/java/thoth/tasks/Event.java +++ b/src/main/java/thoth/tasks/Event.java @@ -13,6 +13,6 @@ public Event(String description, String from, String to) { @Override public String getTaskString() { - return "[E]" + super.getTaskString() + " (from: " + from +" to: " + to + ")"; + return "[E]" + super.getTaskString() + " (from: " + from + " to: " + to + ")"; } } From ce91da0ebb3af2ac16eeac8fbd07ca53e2c740bc Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Thu, 6 Mar 2025 19:44:40 +0800 Subject: [PATCH 44/66] Add final else statment to catch unwated errors Remove magic literals --- src/main/java/thoth/parser/Parser.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main/java/thoth/parser/Parser.java b/src/main/java/thoth/parser/Parser.java index 1f635fc5a..5c1589382 100644 --- a/src/main/java/thoth/parser/Parser.java +++ b/src/main/java/thoth/parser/Parser.java @@ -4,6 +4,8 @@ public class Parser { + public static final int INDEX_OFFSET = 1; + public static Command parse(String userInput) { userInput = userInput.trim(); @@ -13,21 +15,21 @@ public static Command parse(String userInput) { return new ListCommand(); } else if (userInput.startsWith("mark")) { try { - int taskIndex = Integer.parseInt(userInput.replace("mark", "").trim()) - 1; + int taskIndex = Integer.parseInt(userInput.replace("mark", "").trim()) - INDEX_OFFSET; return new MarkCommand(taskIndex); } catch (NumberFormatException e) { return new UnknownCommand("Please enter a valid number for mark command."); } } else if (userInput.startsWith("unmark")) { try { - int taskIndex = Integer.parseInt(userInput.replace("unmark", "").trim()) - 1; + int taskIndex = Integer.parseInt(userInput.replace("unmark", "").trim()) - INDEX_OFFSET; return new UnmarkCommand(taskIndex); } catch (NumberFormatException e) { return new UnknownCommand("Please enter a valid number for unmark command."); } } else if (userInput.startsWith("delete")) { try { - int taskIndex = Integer.parseInt(userInput.replace("delete", "").trim()) - 1; + int taskIndex = Integer.parseInt(userInput.replace("delete", "").trim()) - INDEX_OFFSET; return new DeleteCommand(taskIndex); } catch (NumberFormatException e) { return new UnknownCommand("Please enter a valid number for delete command."); @@ -63,7 +65,8 @@ public static Command parse(String userInput) { } return new EventCommand(description, from, to); + }else { + return new UnknownCommand("Oops me no understand you~"); } - return new UnknownCommand("Oops me no understand you~"); } } From 618ce95718dec7f19b0753d67490b054927bc8f9 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Thu, 6 Mar 2025 20:35:57 +0800 Subject: [PATCH 45/66] Add FindCommand class Update Parser Class with FindCommand --- src/main/java/thoth/command/FindCommand.java | 40 ++++++++++++++++++++ src/main/java/thoth/parser/Parser.java | 6 ++- 2 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 src/main/java/thoth/command/FindCommand.java diff --git a/src/main/java/thoth/command/FindCommand.java b/src/main/java/thoth/command/FindCommand.java new file mode 100644 index 000000000..8f31dec7b --- /dev/null +++ b/src/main/java/thoth/command/FindCommand.java @@ -0,0 +1,40 @@ +package thoth.command; + +import thoth.logic.TaskManager; +import thoth.ui.UserInterface; +import thoth.tasks.Task; // Assuming tasks are represented by a Task class +import java.util.ArrayList; +import java.util.List; + +public class FindCommand extends Command { + String keyWord; + + public FindCommand(String keyWord) { + this.keyWord = keyWord; + } + + @Override + public void execute(TaskManager taskManager, UserInterface ui) { + List matchedTasks = new ArrayList<>(); + + // Retrieve the list of tasks from TaskManager + List tasks = taskManager.getTaskList(); + + // Search for tasks that contain the keyword (case-insensitive) + for (Task task : tasks) { + if (task.getTaskString().toLowerCase().contains(keyWord.toLowerCase())) { + matchedTasks.add(task); + } + } + + // Display the matching tasks or an appropriate message if none are found + if (matchedTasks.isEmpty()) { + UserInterface.printMessage("No matching tasks found for keyword: " + keyWord); + } else { + UserInterface.printMessage("Here are the matching tasks:"); + for (int i = 0; i < matchedTasks.size(); i++) { + UserInterface.printMessage((i + 1) + ". " + matchedTasks.get(i).getTaskString()); + } + } + } +} diff --git a/src/main/java/thoth/parser/Parser.java b/src/main/java/thoth/parser/Parser.java index 5c1589382..54ad0d6ae 100644 --- a/src/main/java/thoth/parser/Parser.java +++ b/src/main/java/thoth/parser/Parser.java @@ -64,8 +64,10 @@ public static Command parse(String userInput) { return new UnknownCommand("Oops task description is empty or time range not specified"); } return new EventCommand(description, from, to); - - }else { + } else if (userInput.startsWith("find")) { + String keyWord = userInput.replace("find", "").trim(); + return new FindCommand(keyWord); + } else { return new UnknownCommand("Oops me no understand you~"); } } From 370cc3f97fd4b55d0ef809bc63141f2eb6bdb026 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Thu, 6 Mar 2025 20:37:31 +0800 Subject: [PATCH 46/66] Update Absolute path to relative path --- data/data.txt | 7 ++----- src/main/java/thoth/storage/Storage.java | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/data/data.txt b/data/data.txt index 7b2dada95..657bc38e9 100644 --- a/data/data.txt +++ b/data/data.txt @@ -1,6 +1,3 @@ [T][ ] eat -[D][ ] sleep (by: 9pm) -[T][ ] eat -[T][ ] sleep -[T][ ] lol -[E][ ] Cheng Zhiyuan attend Cs2113 lecture Friday 21 Feb 2025 (from: 4 to: 6pm) +[T][ ] repet +[T][ ] sleep 2 diff --git a/src/main/java/thoth/storage/Storage.java b/src/main/java/thoth/storage/Storage.java index c9753cfe3..8e9e19756 100644 --- a/src/main/java/thoth/storage/Storage.java +++ b/src/main/java/thoth/storage/Storage.java @@ -13,7 +13,7 @@ public class Storage { - private static final String DEFAULT_FILE_PATH = "C:\\CS2113_IP\\data\\data.txt"; + private static final String DEFAULT_FILE_PATH = "data/data.txt"; private static final int MIN_HEADER_SIZE = 7; private static final int TYPE_INDEX = 1; private static final int DONE_INDEX = 4; From f82483d1f7341520e62e7dc42bbbe1fa6ee1ffad Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Thu, 6 Mar 2025 20:37:48 +0800 Subject: [PATCH 47/66] Remove unused import --- src/main/java/thoth/main/Thoth.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/thoth/main/Thoth.java b/src/main/java/thoth/main/Thoth.java index eec6268c5..8d796bc4d 100644 --- a/src/main/java/thoth/main/Thoth.java +++ b/src/main/java/thoth/main/Thoth.java @@ -7,7 +7,6 @@ import thoth.tasks.Task; import thoth.ui.UserInterface; -import java.io.FileNotFoundException; import java.io.IOException; import java.util.List; From fd0b686d24d27e3f9163ac2999defa5d0d70f57a Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Fri, 7 Mar 2025 10:27:44 +0800 Subject: [PATCH 48/66] Add javadoc comments --- src/main/java/thoth/logic/TaskManager.java | 43 +++++++++++++++++++++- src/main/java/thoth/parser/Parser.java | 22 ++++++++++- src/main/java/thoth/storage/Storage.java | 29 +++++++++++++++ src/main/java/thoth/tasks/Deadline.java | 11 ++++++ src/main/java/thoth/tasks/Event.java | 12 ++++++ src/main/java/thoth/tasks/Task.java | 20 ++++++++-- src/main/java/thoth/tasks/Todo.java | 10 +++++ 7 files changed, 141 insertions(+), 6 deletions(-) diff --git a/src/main/java/thoth/logic/TaskManager.java b/src/main/java/thoth/logic/TaskManager.java index 51b5a3bcf..62bee7585 100644 --- a/src/main/java/thoth/logic/TaskManager.java +++ b/src/main/java/thoth/logic/TaskManager.java @@ -1,3 +1,9 @@ +/** + * Manages a list of tasks. + *

+ * This class provides methods to add tasks, mark them as done or not done, remove tasks, + * and retrieve tasks or the task count. + */ package thoth.logic; import thoth.tasks.Task; @@ -5,35 +11,70 @@ import java.util.ArrayList; import java.util.List; -// For Task commands public class TaskManager { private final List taskList = new ArrayList<>(); + /** + * Add a new task to the task list. + * + * @param task is the task to be added + */ public void addTask(Task task) { taskList.add(task); } + /** + * Marks the task at the specific task index as done + * + * @param taskId the index of th task that needs to be mark as done + */ public void markTaskAsDone(int taskId) { taskList.get(taskId).markAsDone(); } + /** + * Marks the task at the specific task index as not done + * + * @param taskId the index of th task that needs to be mark as not done + */ public void markTaskAsNotDone(int taskId) { taskList.get(taskId).markAsNotDone(); } + /** + * Return the number of tasks in the task list + * + * @return the size of the task list + */ public int getTaskCount() { return taskList.size(); } + /** + * Return the complete list of tasks + * + * @return the list of tasks + */ public List getTaskList() { return taskList; } + /** + * Remove the task at the specific task index + * + * @param taskId the index of tht task to be removed + */ public void removeTask(int taskId) { taskList.remove(taskId); } + /** + * Return a sublist of tasks from the specified index to the end of the list + * + * @param taskId the tarting index for the sublist + * @return a list of tasks starting from the specified index + */ public List getTask(int taskId) { return taskList.subList(taskId, taskList.size()); } diff --git a/src/main/java/thoth/parser/Parser.java b/src/main/java/thoth/parser/Parser.java index 54ad0d6ae..17942d90a 100644 --- a/src/main/java/thoth/parser/Parser.java +++ b/src/main/java/thoth/parser/Parser.java @@ -1,11 +1,31 @@ +/** + * Provides functionality to parse user input into executable commands. + */ + package thoth.parser; -import thoth.command.*; +import thoth.command.Command; +import thoth.command.DeadlineCommand; +import thoth.command.EventCommand; +import thoth.command.MarkCommand; +import thoth.command.UnmarkCommand; +import thoth.command.ExitCommand; +import thoth.command.FindCommand; +import thoth.command.ListCommand; +import thoth.command.UnknownCommand; +import thoth.command.TodoCommand; +import thoth.command.DeleteCommand; public class Parser { public static final int INDEX_OFFSET = 1; + /** + * parse the user input into executable commands + * + * @param userInput the input string that the user types + * @return the corresponding command to the user input + */ public static Command parse(String userInput) { userInput = userInput.trim(); diff --git a/src/main/java/thoth/storage/Storage.java b/src/main/java/thoth/storage/Storage.java index 8e9e19756..a4f1879c6 100644 --- a/src/main/java/thoth/storage/Storage.java +++ b/src/main/java/thoth/storage/Storage.java @@ -18,6 +18,11 @@ public class Storage { private static final int TYPE_INDEX = 1; private static final int DONE_INDEX = 4; + /** + * Create a file to store data + * + * @throws IOException if an I/O error occurs while creating the file + */ public static void createFile() throws IOException { File file = new File(DEFAULT_FILE_PATH); @@ -31,12 +36,24 @@ public static void createFile() throws IOException { } } + /** + * Add a new line into the file with the user input + * + * @param input the string to be written to the file + * @throws IOException if an I/O error occurs while writing to this file + */ public static void writeFile(String input) throws IOException { try (FileWriter fw = new FileWriter(DEFAULT_FILE_PATH, true)) { fw.append(input).append(System.lineSeparator()); } } + /** + * Saves the list of tasks into the data file + * + * @param tasks the task list that is to be saved + * @throws IOException if an I/O error occurs while writing to this file + */ public static void saveTasks(List tasks) throws IOException { try (FileWriter fw = new FileWriter(DEFAULT_FILE_PATH, false)) { for (Task t : tasks) { @@ -45,6 +62,12 @@ public static void saveTasks(List tasks) throws IOException { } } + /** + * Load the task from the data file + * + * @return a list of tasks loaded from the file or an empty list if the file does not exist + * @throws IOException if an I/O error occurs while writing to this file + */ public static List loadTasks() throws IOException { List tasks = new ArrayList<>(); File f = new File(DEFAULT_FILE_PATH); @@ -65,6 +88,12 @@ public static List loadTasks() throws IOException { return tasks; } + /** + * Parses a line from the storage file and converts it into a Task object. + * + * @param line the line to be parsed + * @return the corresponding Task object, or null if the line is not in the expected format + */ private static Task parseLineToTask(String line) { if (line.length() < MIN_HEADER_SIZE) { diff --git a/src/main/java/thoth/tasks/Deadline.java b/src/main/java/thoth/tasks/Deadline.java index 17833d9ce..716883f4e 100644 --- a/src/main/java/thoth/tasks/Deadline.java +++ b/src/main/java/thoth/tasks/Deadline.java @@ -4,11 +4,22 @@ public class Deadline extends Task { protected String by; + /** + * Constructs a Deadline task with the specified description and deadline. + * + * @param description the description for the deadline task + * @param by the deadline for the task + */ public Deadline(String description, String by) { super(description); this.by = by; } + /** + * Return a String to representing the deadline task including it type and deadline + * + * @return the formatted string + */ @Override public String getTaskString() { return "[D]" + super.getTaskString() + " (by: " + by + ")"; diff --git a/src/main/java/thoth/tasks/Event.java b/src/main/java/thoth/tasks/Event.java index 2cac9a126..0ce021720 100644 --- a/src/main/java/thoth/tasks/Event.java +++ b/src/main/java/thoth/tasks/Event.java @@ -5,12 +5,24 @@ public class Event extends Task { protected String to; protected String from; + /** + * Constructs the Event Task with specified description, start and end time of the event + * + * @param description the description of the event + * @param from the starting time of the event + * @param to the ending time of the event + */ public Event(String description, String from, String to) { super(description); this.from = from; this.to = to; } + /** + * Return a string representing the event with its type and start and end timeframe + * + * @return the formatted task string + */ @Override public String getTaskString() { return "[E]" + super.getTaskString() + " (from: " + from + " to: " + to + ")"; diff --git a/src/main/java/thoth/tasks/Task.java b/src/main/java/thoth/tasks/Task.java index b04ea13f4..6049c89dc 100644 --- a/src/main/java/thoth/tasks/Task.java +++ b/src/main/java/thoth/tasks/Task.java @@ -8,25 +8,37 @@ public class Task { protected String description; protected boolean isDone; + /** + * Constructs a task with the description + * + * @param description the description for the task + */ public Task(String description) { this.description = description; this.isDone = false; } + /** + * mark task as done + */ public void markAsDone() { this.isDone = true; } + /** + * mark task as not done + */ public void markAsNotDone() { this.isDone = false; } + /** + * Returns a string representation of the task, including its completion status and description. + * + * @return the formatted task string + */ public String getTaskString() { String statusIcon = isDone ? MARKED_BOX : EMPTY_BOX; return statusIcon + " " + description; } - - public String getDescription() { - return description; - } } diff --git a/src/main/java/thoth/tasks/Todo.java b/src/main/java/thoth/tasks/Todo.java index 78943407d..898d733f2 100644 --- a/src/main/java/thoth/tasks/Todo.java +++ b/src/main/java/thoth/tasks/Todo.java @@ -4,10 +4,20 @@ public class Todo extends Task { protected String by; + /** + * constructs a todo tak with the specified description + * + * @param description the description of the todo task + */ public Todo(String description) { super(description); } + /** + * Returns a string representation of the todo task including its type + * + * @return a formatted task string with the type + */ @Override public String getTaskString() { return "[T]" + super.getTaskString(); From 237178f11a8cceedfeb9e4bbd7a266608324b664 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Thu, 13 Mar 2025 13:30:19 +0800 Subject: [PATCH 49/66] Update readme with basic user guide --- docs/README.md | 149 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 131 insertions(+), 18 deletions(-) diff --git a/docs/README.md b/docs/README.md index 6adfc0a3d..1269b25d3 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,30 +1,143 @@ # Thoth User Guide +Thoth Task Manager is a command-line application designed to help you manage your daily tasks efficiently. It supports adding todos, deadlines, and events, as well as marking tasks as done, unmarking them, deleting tasks, and searching for tasks. This README provides an overview of the application, installation instructions, usage details, and troubleshooting tips. -// Update the title above to match the actual product name +Thoth Task Manager enables you to manage three main types of tasks: -// Product screenshot goes here +- **Todos:** Simple tasks that need to be done. +- **Deadlines:** Tasks that must be completed by a specific date/time. +- **Events:** Tasks that occur within a specified time range. -// Product intro goes here +Users interact with the application via a command-line interface (CLI) by entering commands that the system parses and executes. Each command is processed through a central parser that maps user input to the corresponding functionality. -## Adding deadlines +When you start Thoth Task Manager, you will be greeted with a welcome message followed by a prompt where you can enter your commands. The application continuously listens for your input until you choose to exit. -// Describe the action and its outcome. +## Available Commands +### Exiting the Application: _bye_ -// Give examples of usage +The bye command terminates the application gracefully. It prints a goodbye message to indicate that the session is closing. -Example: `keyword (optional arguments)` +Syntax: ```bye``` +Sample output: ```Bye. Hope to see you again soon!``` -// A description of the expected outcome goes here +### Listing the Task Lists: _list_ +The list command prints the list of the users to the screen of the CLI software + +Syntax: ``` -expected output + list +``` +Example code: +``` + list +``` +Sample output: +``` + 1. [T][ ] eat + 2. [T][ ] sleep + 3. [T][ ] repeat +``` +### Adding a todo task : _todo_ +Syntax: +``` + todo TASK_DESCRIPTION +``` +Example code: +``` + todo work on CS2113 IP +``` +Sample output: +``` + Got it. I've added this task: + [T][ ] work on CS2113 IP + Now you have 4 tasks in the list. +``` +### Adding a deadline task : _deadline_ +Syntax: +``` + deadline TASK_DESCRIPTION /by DEADLINE_TIME +``` +Example code: +``` + deadline work on CS2113 IP /by tody 2359 +``` +Sample output: +``` + Got it. I've added this task: + [D][ ] work on CS2113 IP (by: today 2359) + Now you have 5 tasks in the list. +``` +### Adding a event task : _event_ +Syntax: +``` + event TASK_DESCRIPTION /from START_TIME /to END_TIME +``` +Example code: +``` + event work on CS2113 IP /from 13/03/2025 12 noon /to 13/03/2025 4 pm +``` +Sample output: +``` + Got it. I've added this task: + [E][ ] work on CS2113 IP (from: 13/03/2025 12 noon to: 13/03/2025 4 pm) + Now you have 6 tasks in the list. +``` +### Marking a task as Done: _mark_ +Syntax: +``` + mark TASK_LIST_INDEX +``` +Example code: +``` + mark 1 +``` +Sample Output: +``` + Nice! I've marked this task as done: + [T][X] eat +``` +### Marking a task as Not Done: _unmark_ +Syntax: +``` + unmark TASK_LIST_INDEX +``` +Example code: +``` + unmark 1 +``` +Sample Output: +``` + OK, I've marked this task as not done yet: + [T][ ] eat +``` +### Deleting a task from the task list: _delete_ +Syntax: +``` + detele TASK_LIST_INDEX +``` +Example code: +``` + delete 2 +``` +Sample Output: +``` + Noted. I've removed this task: + [T][ ] sleep + Now you have 5 tasks in the list. +``` +### Finding tasks with a string: _find_ +Syntax: +``` + find STRING_DESCRIPTION +``` +Example code: +``` + find CS2113 +``` +Sample Output: +``` + Here are the matching tasks: + 1. [T][ ] work on CS2113 IP + 2. [D][ ] work on CS2113 IP (by: today 2359) + 3. [E][ ] work on CS2113 IP (from: 13/03/2025 12 noon to: 13/03/2025 4 pm) ``` - -## Feature ABC - -// Feature details - - -## Feature XYZ - -// Feature details \ No newline at end of file From 923ec07840b79d1b54bcbb33f6ffc900540ca5aa Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Thu, 13 Mar 2025 13:30:39 +0800 Subject: [PATCH 50/66] Delete unused imports --- src/main/java/thoth/command/DeadlineCommand.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/thoth/command/DeadlineCommand.java b/src/main/java/thoth/command/DeadlineCommand.java index 29396ca5b..0e085578e 100644 --- a/src/main/java/thoth/command/DeadlineCommand.java +++ b/src/main/java/thoth/command/DeadlineCommand.java @@ -1,6 +1,5 @@ package thoth.command; -import com.sun.source.util.TaskListener; import thoth.logic.TaskManager; import thoth.storage.Storage; import thoth.tasks.Deadline; From 582659feb7670fa9f72330200f47f6adbb73c570 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Thu, 13 Mar 2025 13:31:21 +0800 Subject: [PATCH 51/66] Fixed bux of printing wrong user output --- src/main/java/thoth/command/MarkCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/thoth/command/MarkCommand.java b/src/main/java/thoth/command/MarkCommand.java index 4da4edb99..92b99bff2 100644 --- a/src/main/java/thoth/command/MarkCommand.java +++ b/src/main/java/thoth/command/MarkCommand.java @@ -18,7 +18,7 @@ public MarkCommand(int taskIndex) { public void execute(TaskManager taskManager, UserInterface ui) { taskManager.markTaskAsDone(taskIndex); Task updatedTask = taskManager.getTaskList().get(taskIndex); - UserInterface.printMarkAsUndone(updatedTask); + UserInterface.printMarkAsDone(updatedTask); try { Storage.saveTasks(taskManager.getTaskList()); } catch (IOException e) { From 3c1e59e59426ce888ad6f9a5aad4b6d9c7cab02e Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Thu, 13 Mar 2025 13:34:49 +0800 Subject: [PATCH 52/66] Update Readme --- docs/README.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index 1269b25d3..96917c01f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -16,8 +16,18 @@ When you start Thoth Task Manager, you will be greeted with a welcome message fo The bye command terminates the application gracefully. It prints a goodbye message to indicate that the session is closing. -Syntax: ```bye``` -Sample output: ```Bye. Hope to see you again soon!``` +Syntax: +``` + bye +``` +Example code: +``` + bye +``` +Sample output: +``` + Bye. Hope to see you again soon! +``` ### Listing the Task Lists: _list_ From b814be2e8a535804263796f00b815bb1788d90ec Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Thu, 13 Mar 2025 13:42:07 +0800 Subject: [PATCH 53/66] Update Readme with descriptions --- docs/README.md | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index 96917c01f..b4c9e475a 100644 --- a/docs/README.md +++ b/docs/README.md @@ -48,6 +48,8 @@ Sample output: 3. [T][ ] repeat ``` ### Adding a todo task : _todo_ +The `todo` command adds a new simple task without any associated deadline or time. + Syntax: ``` todo TASK_DESCRIPTION @@ -63,6 +65,8 @@ Sample output: Now you have 4 tasks in the list. ``` ### Adding a deadline task : _deadline_ +The `deadline` command creates a task with a deadline. Both a task description and a deadline time must be specified. + Syntax: ``` deadline TASK_DESCRIPTION /by DEADLINE_TIME @@ -78,6 +82,8 @@ Sample output: Now you have 5 tasks in the list. ``` ### Adding a event task : _event_ +The `event` command schedules a task that occurs during a specified time range. The task description, start and end time of the event must be specified. + Syntax: ``` event TASK_DESCRIPTION /from START_TIME /to END_TIME @@ -93,6 +99,8 @@ Sample output: Now you have 6 tasks in the list. ``` ### Marking a task as Done: _mark_ +The `mark` command sets a task's status to the done state. + Syntax: ``` mark TASK_LIST_INDEX @@ -107,6 +115,7 @@ Sample Output: [T][X] eat ``` ### Marking a task as Not Done: _unmark_ +The `unmark` command reverts a task's status back to the not done state. Syntax: ``` unmark TASK_LIST_INDEX @@ -121,6 +130,8 @@ Sample Output: [T][ ] eat ``` ### Deleting a task from the task list: _delete_ +The `delete` command removes a specified task from your list. + Syntax: ``` detele TASK_LIST_INDEX @@ -135,10 +146,12 @@ Sample Output: [T][ ] sleep Now you have 5 tasks in the list. ``` -### Finding tasks with a string: _find_ +### Finding tasks with a string: _find_ +The `find` command searches for tasks containing a specified keyword (case-insensitive) and displays the matching tasks. + Syntax: ``` - find STRING_DESCRIPTION + find KEYWORD ``` Example code: ``` From cfb6e7078a924282ffa2ad5eea8d8253ad67dd12 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Thu, 13 Mar 2025 13:49:53 +0800 Subject: [PATCH 54/66] Fixed Grammer error --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index b4c9e475a..755da9326 100644 --- a/docs/README.md +++ b/docs/README.md @@ -81,7 +81,7 @@ Sample output: [D][ ] work on CS2113 IP (by: today 2359) Now you have 5 tasks in the list. ``` -### Adding a event task : _event_ +### Adding an event task : _event_ The `event` command schedules a task that occurs during a specified time range. The task description, start and end time of the event must be specified. Syntax: From 181fc0e0b2f28d795d6f91870a3dcd42b1515f12 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Fri, 14 Mar 2025 09:36:30 +0800 Subject: [PATCH 55/66] Update data files --- data/data.txt | 6 ++++-- src/main/java/thoth/storage/Storage.java | 9 +++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/data/data.txt b/data/data.txt index 657bc38e9..064c337f7 100644 --- a/data/data.txt +++ b/data/data.txt @@ -1,3 +1,5 @@ [T][ ] eat -[T][ ] repet -[T][ ] sleep 2 +[T][ ] repeat +[T][ ] work on CS2113 IP +[D][ ] work on CS2113 IP (by: today 2359) +[E][ ] work on CS2113 IP (from: 13/03/2025 12 noon to: 13/03/2025 4 pm) diff --git a/src/main/java/thoth/storage/Storage.java b/src/main/java/thoth/storage/Storage.java index a4f1879c6..836c2e527 100644 --- a/src/main/java/thoth/storage/Storage.java +++ b/src/main/java/thoth/storage/Storage.java @@ -101,16 +101,15 @@ private static Task parseLineToTask(String line) { return null; } - char taskType = line.charAt(TYPE_INDEX); // 'D', 'T', or 'E' - char doneChar = line.charAt(DONE_INDEX); // ' ' or 'X' + char taskType = line.charAt(TYPE_INDEX); + char doneChar = line.charAt(DONE_INDEX); boolean isDone = (doneChar == 'X'); - // The rest of the line, e.g. "sleep (by: 15pm)" String content = line.substring(MIN_HEADER_SIZE).trim(); switch(taskType) { case 'T': { - // e.g. "[T][X] eat" => content = "eat" + Todo todo = new Todo(content); if (isDone) { todo.markAsDone(); @@ -118,8 +117,6 @@ private static Task parseLineToTask(String line) { return todo; } case 'D': { - // e.g. "[D][ ] sleep (by: 15pm)" => content = "sleep (by: 15pm)" - // Find "(by: " int byIndex = content.indexOf("(by:"); if (byIndex == -1) { // Not well-formed, handle error or return a default From b7f39a1f1a48bf7ea0854825472c9c6d4bab524f Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Fri, 14 Mar 2025 11:09:21 +0800 Subject: [PATCH 56/66] Add in javadoc headers --- .../java/thoth/command/UnmarkCommand.java | 2 +- src/main/java/thoth/ui/UserInterface.java | 47 +++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/main/java/thoth/command/UnmarkCommand.java b/src/main/java/thoth/command/UnmarkCommand.java index 92fa49639..66ca11d4f 100644 --- a/src/main/java/thoth/command/UnmarkCommand.java +++ b/src/main/java/thoth/command/UnmarkCommand.java @@ -9,7 +9,7 @@ public class UnmarkCommand extends Command { int taskIndex; - + public UnmarkCommand(int taskIndex) { this.taskIndex = taskIndex; } diff --git a/src/main/java/thoth/ui/UserInterface.java b/src/main/java/thoth/ui/UserInterface.java index 74694d332..d77f93c0a 100644 --- a/src/main/java/thoth/ui/UserInterface.java +++ b/src/main/java/thoth/ui/UserInterface.java @@ -9,37 +9,72 @@ public class UserInterface { private final Scanner scanner; public static final String INDENT = "%4s"; + /** + * Constructs a new UserInterface and initializes the input scanner. + */ public UserInterface() { scanner = new Scanner(System.in); } + /** + * Reads a line of input from the user. + * + * @return the input string entered by the user. + */ public String readInput() { return scanner.nextLine(); } + /** + * Prints the greeting message to the console. + */ public void printGreetingMessage() { System.out.println("Hello! I'm Thoth"); System.out.println("What can I do for you?"); } + /** + * Prints the specified message to the console. + * + * @param message the message to be printed. + */ public static void printMessage(String message) { System.out.println(message); } + /** + * Prints a goodbye message to the console. + */ public void printGoodbye() { System.out.println("Bye. Hope to see you again soon!"); } + /** + * Prints a message indicating that a task has been marked as done. + * + * @param task the task that has been marked as done. + */ public static void printMarkAsDone(Task task) { System.out.printf(INDENT + "Nice! I've marked this task as done:%n", ""); System.out.printf(INDENT + "%s\n", "", task.getTaskString()); } + /** + * Prints a message indicating that a task has been marked as not done. + * + * @param task the task that has been marked as not done. + */ public static void printMarkAsUndone(Task task) { System.out.printf(INDENT + "OK, I've marked this task as not done yet:%n", ""); System.out.printf(INDENT + "%s\n", "", task.getTaskString()); } + /** + * Prints the list of tasks to the console. + * + * @param task the list of tasks to be printed. + * @param taskCount the number of tasks to print. + */ public static void printTask(List task, int taskCount) { int listIndex = 1; for (int i = 0; i < taskCount; i++) { @@ -48,12 +83,24 @@ public static void printTask(List task, int taskCount) { } } + /** + * Prints a message indicating that a task has been added. + * + * @param task the task that has been added. + * @param taskCount the total number of tasks after the addition. + */ public static void printAddedTask(Task task, int taskCount) { System.out.printf(INDENT + "Got it. I've added this task:\n", ""); System.out.printf(INDENT + "%s\n", "", task.getTaskString()); System.out.printf(INDENT + "Now you have %d tasks in the list.%n", "", taskCount); } + /** + * Prints a message indicating that a task has been deleted. + * + * @param task the list of tasks from which the deleted task is assumed to be the first element. + * @param taskCount the total number of tasks remaining after deletion. + */ public static void printDeleteTask(List task, int taskCount) { System.out.printf(INDENT + "Noted. I've removed this task:\n", ""); System.out.printf(INDENT + "%s\n", "", task.get(0).getTaskString()); From b5abe0924db67a057f1b9084770b9ca2cc92f9d7 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Fri, 14 Mar 2025 11:44:49 +0800 Subject: [PATCH 57/66] Fix bug for out of bound task index --- src/main/java/thoth/command/FindCommand.java | 5 +++++ src/main/java/thoth/command/MarkCommand.java | 5 +++++ src/main/java/thoth/command/UnmarkCommand.java | 5 +++++ 3 files changed, 15 insertions(+) diff --git a/src/main/java/thoth/command/FindCommand.java b/src/main/java/thoth/command/FindCommand.java index 8f31dec7b..3fe91e053 100644 --- a/src/main/java/thoth/command/FindCommand.java +++ b/src/main/java/thoth/command/FindCommand.java @@ -15,6 +15,11 @@ public FindCommand(String keyWord) { @Override public void execute(TaskManager taskManager, UserInterface ui) { + if (keyWord.trim().isEmpty()) { + UserInterface.printMessage("Keyword cannot be empty. Please enter a valid keyword."); + return; + } + List matchedTasks = new ArrayList<>(); // Retrieve the list of tasks from TaskManager diff --git a/src/main/java/thoth/command/MarkCommand.java b/src/main/java/thoth/command/MarkCommand.java index 92b99bff2..a5e529fdf 100644 --- a/src/main/java/thoth/command/MarkCommand.java +++ b/src/main/java/thoth/command/MarkCommand.java @@ -16,6 +16,11 @@ public MarkCommand(int taskIndex) { @Override public void execute(TaskManager taskManager, UserInterface ui) { + if (taskIndex < 0 || taskIndex >= taskManager.getTaskList().size()) { + UserInterface.printMessage("Task index is out of bounds. Please enter a valid task number."); + return; + } + taskManager.markTaskAsDone(taskIndex); Task updatedTask = taskManager.getTaskList().get(taskIndex); UserInterface.printMarkAsDone(updatedTask); diff --git a/src/main/java/thoth/command/UnmarkCommand.java b/src/main/java/thoth/command/UnmarkCommand.java index 66ca11d4f..f8ff559b3 100644 --- a/src/main/java/thoth/command/UnmarkCommand.java +++ b/src/main/java/thoth/command/UnmarkCommand.java @@ -16,6 +16,11 @@ public UnmarkCommand(int taskIndex) { @Override public void execute(TaskManager taskManager, UserInterface ui) { + if (taskIndex < 0 || taskIndex >= taskManager.getTaskList().size()) { + UserInterface.printMessage("Task index is out of bounds. Please enter a valid task number."); + return; + } + taskManager.markTaskAsNotDone(taskIndex); Task updatedTask = taskManager.getTaskList().get(taskIndex); UserInterface.printMarkAsUndone(updatedTask); From e328d1dbf88d77c9c0dff8481fefcf29161d90f6 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Fri, 14 Mar 2025 11:50:39 +0800 Subject: [PATCH 58/66] update gitignore file --- .gitignore | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.gitignore b/.gitignore index 2873e189e..ed657028b 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,9 @@ bin/ /text-ui-test/ACTUAL.TXT text-ui-test/EXPECTED-UNIX.TXT + +#.class files +*.class + +#data.txt +/data/data.txt From cc0974dbe46ae8e42c0cbfb18bd1ae723b5fae3f Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Fri, 14 Mar 2025 16:26:05 +0800 Subject: [PATCH 59/66] Fix out of bound task index bug --- src/main/java/thoth/command/DeleteCommand.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/thoth/command/DeleteCommand.java b/src/main/java/thoth/command/DeleteCommand.java index 0f0163e93..22dc869b6 100644 --- a/src/main/java/thoth/command/DeleteCommand.java +++ b/src/main/java/thoth/command/DeleteCommand.java @@ -15,6 +15,10 @@ public DeleteCommand(int taskIndex) { @Override public void execute(TaskManager taskManager, UserInterface ui) { + if (taskIndex < 0 || taskIndex >= taskManager.getTaskList().size()) { + UserInterface.printMessage("Task index is out of bounds. Please enter a valid task number."); + return; + } UserInterface.printDeleteTask(taskManager.getTask(taskIndex), taskManager.getTaskCount() - 1); taskManager.removeTask(taskIndex); try { From ff3d1b7172a7740827a6021d514c7e629f921fb7 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Fri, 28 Mar 2025 00:36:08 +0800 Subject: [PATCH 60/66] Restructure code from packages to reduce redundency --- data/data.txt | 8 +- src/main/java/META-INF/MANIFEST.MF | 2 +- src/main/java/thoth/Storage.java | 92 +++++++++++++++++++ .../java/thoth/{logic => }/TaskManager.java | 4 +- src/main/java/thoth/{main => }/Thoth.java | 0 .../java/thoth/{ui => }/UserInterface.java | 0 src/main/java/thoth/command/Command.java | 4 +- .../exceptions/TaskParsingException.java | 7 ++ .../java/thoth/exceptions/ThothException.java | 7 ++ .../Storage.java => parser/TaskParser.java} | 91 +----------------- 10 files changed, 117 insertions(+), 98 deletions(-) create mode 100644 src/main/java/thoth/Storage.java rename src/main/java/thoth/{logic => }/TaskManager.java (96%) rename src/main/java/thoth/{main => }/Thoth.java (100%) rename src/main/java/thoth/{ui => }/UserInterface.java (100%) create mode 100644 src/main/java/thoth/exceptions/TaskParsingException.java create mode 100644 src/main/java/thoth/exceptions/ThothException.java rename src/main/java/thoth/{storage/Storage.java => parser/TaskParser.java} (51%) diff --git a/data/data.txt b/data/data.txt index 064c337f7..009e7be39 100644 --- a/data/data.txt +++ b/data/data.txt @@ -1,5 +1,3 @@ -[T][ ] eat -[T][ ] repeat -[T][ ] work on CS2113 IP -[D][ ] work on CS2113 IP (by: today 2359) -[E][ ] work on CS2113 IP (from: 13/03/2025 12 noon to: 13/03/2025 4 pm) +[E][X] work on CS2113 IP (from: 13/03/2025 12 noon to: 13/03/2025 4 pm) +[E][ ] sleep (from: now to: never) +[D][X] sleep (by: 11pm) diff --git a/src/main/java/META-INF/MANIFEST.MF b/src/main/java/META-INF/MANIFEST.MF index 64e33456a..0439442aa 100644 --- a/src/main/java/META-INF/MANIFEST.MF +++ b/src/main/java/META-INF/MANIFEST.MF @@ -1,3 +1,3 @@ Manifest-Version: 1.0 -Main-Class: thoth.main.Thoth +Main-Class: thoth.Thoth diff --git a/src/main/java/thoth/Storage.java b/src/main/java/thoth/Storage.java new file mode 100644 index 000000000..e7444f444 --- /dev/null +++ b/src/main/java/thoth/Storage.java @@ -0,0 +1,92 @@ +package thoth; + +import thoth.parser.TaskParser; +import thoth.tasks.Task; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; + + +public class Storage { + + private static final String DEFAULT_FILE_PATH = "data/data.txt"; + private static final int MIN_HEADER_SIZE = 7; + private static final int TYPE_INDEX = 1; + private static final int DONE_INDEX = 4; + + /** + * Create a file to store data + * + * @throws IOException if an I/O error occurs while creating the file + */ + public static void createFile() throws IOException { + File file = new File(DEFAULT_FILE_PATH); + + // Ensure the parent directories exist (if there are any) + if (file.getParentFile() != null) { + file.getParentFile().mkdirs(); + } + // Create the file if it doesn't already exist + if (!file.exists()) { + file.createNewFile(); + } + } + + /** + * Add a new line into the file with the user input + * + * @param input the string to be written to the file + * @throws IOException if an I/O error occurs while writing to this file + */ + public static void writeFile(String input) throws IOException { + try (FileWriter fw = new FileWriter(DEFAULT_FILE_PATH, true)) { + fw.append(input).append(System.lineSeparator()); + } + } + + /** + * Saves the list of tasks into the data file + * + * @param tasks the task list that is to be saved + * @throws IOException if an I/O error occurs while writing to this file + */ + public static void saveTasks(List tasks) throws IOException { + try (FileWriter fw = new FileWriter(DEFAULT_FILE_PATH, false)) { + for (Task t : tasks) { + fw.write(t.getTaskString() + System.lineSeparator()); + } + } + } + + /** + * Load the task from the data file + * + * @return a list of tasks loaded from the file or an empty list if the file does not exist + * @throws IOException if an I/O error occurs while writing to this file + */ + public static List loadTasks() throws IOException { + List tasks = new ArrayList<>(); + File f = new File(DEFAULT_FILE_PATH); + if (!f.exists()) { + return tasks; // no file => no tasks + } + + try (Scanner s = new Scanner(f)) { + while (s.hasNextLine()) { + String line = s.nextLine().trim(); + Task t = TaskParser.parseLineToTask(line); + if (t != null) { + tasks.add(t); + } + } + } + + return tasks; + } + + +} diff --git a/src/main/java/thoth/logic/TaskManager.java b/src/main/java/thoth/TaskManager.java similarity index 96% rename from src/main/java/thoth/logic/TaskManager.java rename to src/main/java/thoth/TaskManager.java index 62bee7585..364d75ed9 100644 --- a/src/main/java/thoth/logic/TaskManager.java +++ b/src/main/java/thoth/TaskManager.java @@ -4,7 +4,7 @@ * This class provides methods to add tasks, mark them as done or not done, remove tasks, * and retrieve tasks or the task count. */ -package thoth.logic; +package thoth; import thoth.tasks.Task; @@ -61,7 +61,7 @@ public List getTaskList() { } /** - * Remove the task at the specific task index + * Remove the task at the specific task index * * @param taskId the index of tht task to be removed */ diff --git a/src/main/java/thoth/main/Thoth.java b/src/main/java/thoth/Thoth.java similarity index 100% rename from src/main/java/thoth/main/Thoth.java rename to src/main/java/thoth/Thoth.java diff --git a/src/main/java/thoth/ui/UserInterface.java b/src/main/java/thoth/UserInterface.java similarity index 100% rename from src/main/java/thoth/ui/UserInterface.java rename to src/main/java/thoth/UserInterface.java diff --git a/src/main/java/thoth/command/Command.java b/src/main/java/thoth/command/Command.java index 7f8da7390..a9b06c8f8 100644 --- a/src/main/java/thoth/command/Command.java +++ b/src/main/java/thoth/command/Command.java @@ -1,7 +1,7 @@ package thoth.command; -import thoth.logic.TaskManager; -import thoth.ui.UserInterface; +import thoth.TaskManager; +import thoth.UserInterface; public abstract class Command { public abstract void execute(TaskManager taskManager, UserInterface ui); diff --git a/src/main/java/thoth/exceptions/TaskParsingException.java b/src/main/java/thoth/exceptions/TaskParsingException.java new file mode 100644 index 000000000..4e2bcb2da --- /dev/null +++ b/src/main/java/thoth/exceptions/TaskParsingException.java @@ -0,0 +1,7 @@ +package thoth.exceptions; + +public class TaskParsingException extends RuntimeException { + public TaskParsingException(String message) { + super(message); + } +} diff --git a/src/main/java/thoth/exceptions/ThothException.java b/src/main/java/thoth/exceptions/ThothException.java new file mode 100644 index 000000000..3756897f4 --- /dev/null +++ b/src/main/java/thoth/exceptions/ThothException.java @@ -0,0 +1,7 @@ +package thoth.exceptions; + +public class InvalidCommandException extends RuntimeException { + public InvalidCommandException(String message) { + super(message); + } +} diff --git a/src/main/java/thoth/storage/Storage.java b/src/main/java/thoth/parser/TaskParser.java similarity index 51% rename from src/main/java/thoth/storage/Storage.java rename to src/main/java/thoth/parser/TaskParser.java index 836c2e527..9a4b2ce12 100644 --- a/src/main/java/thoth/storage/Storage.java +++ b/src/main/java/thoth/parser/TaskParser.java @@ -1,100 +1,16 @@ -package thoth.storage; +package thoth.taskparser; import thoth.tasks.Deadline; import thoth.tasks.Event; import thoth.tasks.Task; import thoth.tasks.Todo; -import java.io.*; -import java.util.ArrayList; -import java.util.List; -import java.util.Scanner; - - -public class Storage { - - private static final String DEFAULT_FILE_PATH = "data/data.txt"; +public class TaskParser { private static final int MIN_HEADER_SIZE = 7; private static final int TYPE_INDEX = 1; private static final int DONE_INDEX = 4; - /** - * Create a file to store data - * - * @throws IOException if an I/O error occurs while creating the file - */ - public static void createFile() throws IOException { - File file = new File(DEFAULT_FILE_PATH); - - // Ensure the parent directories exist (if there are any) - if (file.getParentFile() != null) { - file.getParentFile().mkdirs(); - } - // Create the file if it doesn't already exist - if (!file.exists()) { - file.createNewFile(); - } - } - - /** - * Add a new line into the file with the user input - * - * @param input the string to be written to the file - * @throws IOException if an I/O error occurs while writing to this file - */ - public static void writeFile(String input) throws IOException { - try (FileWriter fw = new FileWriter(DEFAULT_FILE_PATH, true)) { - fw.append(input).append(System.lineSeparator()); - } - } - - /** - * Saves the list of tasks into the data file - * - * @param tasks the task list that is to be saved - * @throws IOException if an I/O error occurs while writing to this file - */ - public static void saveTasks(List tasks) throws IOException { - try (FileWriter fw = new FileWriter(DEFAULT_FILE_PATH, false)) { - for (Task t : tasks) { - fw.write(t.getTaskString() + System.lineSeparator()); - } - } - } - - /** - * Load the task from the data file - * - * @return a list of tasks loaded from the file or an empty list if the file does not exist - * @throws IOException if an I/O error occurs while writing to this file - */ - public static List loadTasks() throws IOException { - List tasks = new ArrayList<>(); - File f = new File(DEFAULT_FILE_PATH); - if (!f.exists()) { - return tasks; // no file => no tasks - } - - try (Scanner s = new Scanner(f)) { - while (s.hasNextLine()) { - String line = s.nextLine().trim(); - Task t = parseLineToTask(line); - if (t != null) { - tasks.add(t); - } - } - } - - return tasks; - } - - /** - * Parses a line from the storage file and converts it into a Task object. - * - * @param line the line to be parsed - * @return the corresponding Task object, or null if the line is not in the expected format - */ - private static Task parseLineToTask(String line) { + public static Task parseLineToTask(String line) { if (line.length() < MIN_HEADER_SIZE) { // Not in the expected format @@ -174,5 +90,4 @@ private static Task parseLineToTask(String line) { return null; } } - } From 58b644d48d7235a3aeb805eb625a7c8aec0539fd Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Fri, 28 Mar 2025 00:56:31 +0800 Subject: [PATCH 61/66] Add in Task Parser to load txt to tasks --- src/main/java/thoth/parser/TaskParser.java | 163 +++++++++++++-------- 1 file changed, 98 insertions(+), 65 deletions(-) diff --git a/src/main/java/thoth/parser/TaskParser.java b/src/main/java/thoth/parser/TaskParser.java index 9a4b2ce12..a52f92aa1 100644 --- a/src/main/java/thoth/parser/TaskParser.java +++ b/src/main/java/thoth/parser/TaskParser.java @@ -1,93 +1,126 @@ -package thoth.taskparser; +package thoth.parser; import thoth.tasks.Deadline; import thoth.tasks.Event; import thoth.tasks.Task; import thoth.tasks.Todo; +import thoth.exceptions.TaskParsingException; +/** + * Provides functionality to parse a line from the storage file into a Task object. + */ public class TaskParser { private static final int MIN_HEADER_SIZE = 7; private static final int TYPE_INDEX = 1; private static final int DONE_INDEX = 4; - public static Task parseLineToTask(String line) { - + /** + * Main method to parse a storage file line into a Task. + * + * @param line the storage file line. + * @return the corresponding Task object. + * @throws TaskParsingException if the line is not in the expected format. + */ + public static Task parseLineToTask(String line) throws TaskParsingException { if (line.length() < MIN_HEADER_SIZE) { - // Not in the expected format - return null; + throw new TaskParsingException("Line too short to parse: " + line); } char taskType = line.charAt(TYPE_INDEX); char doneChar = line.charAt(DONE_INDEX); boolean isDone = (doneChar == 'X'); - String content = line.substring(MIN_HEADER_SIZE).trim(); - switch(taskType) { - case 'T': { - - Todo todo = new Todo(content); - if (isDone) { - todo.markAsDone(); - } - return todo; + switch (taskType) { + case 'T': + return parseTodo(content, isDone); + case 'D': + return parseDeadline(content, isDone); + case 'E': + return parseEvent(content, isDone); + default: + throw new TaskParsingException("Unknown task type: " + taskType + " in line: " + line); } - case 'D': { - int byIndex = content.indexOf("(by:"); - if (byIndex == -1) { - // Not well-formed, handle error or return a default - return null; - } - // description is everything before "(by:" - String description = content.substring(0, byIndex).trim(); - // "15pm)" => remove the trailing ")" - String byPart = content.substring(byIndex + 5).trim(); // skip "(by:" - if (byPart.endsWith(")")) { - byPart = byPart.substring(0, byPart.length() - 1).trim(); - } + } - Deadline d = new Deadline(description, byPart); - if (isDone) { - d.markAsDone(); - } - return d; + /** + * Helper method to parse a Todo task. + * + * @param content the content of the task. + * @param isDone whether the task is marked as done. + * @return the Todo task. + * @throws TaskParsingException if the content is empty. + */ + private static Task parseTodo(String content, boolean isDone) throws TaskParsingException { + if (content.isEmpty()) { + throw new TaskParsingException("Todo description is empty."); } - case 'E': { - // e.g. "[E][ ] sleep and eat (from: 1am to: 6pm)" - // content might be "sleep and eat (from: 1am to: 6pm)" - // find "(from:" - int fromIndex = content.indexOf("(from:"); - if (fromIndex == -1) { - return null; - } - String description = content.substring(0, fromIndex).trim(); - // e.g. "1am to: 6pm)" - String fromPart = content.substring(fromIndex + 6).trim(); // skip "(from:" - - // parse fromPart => "1am to: 6pm)" - // find "to:" - int toIndex = fromPart.indexOf("to:"); - if (toIndex == -1) { - return null; - } - String fromTime = fromPart.substring(0, toIndex).trim(); // e.g. "1am" - String toPart = fromPart.substring(toIndex + 3).trim(); // e.g. "6pm)" + Todo todo = new Todo(content); + if (isDone) { + todo.markAsDone(); + } + return todo; + } - // remove trailing ")" if present - if (toPart.endsWith(")")) { - toPart = toPart.substring(0, toPart.length() - 1).trim(); - } + /** + * Helper method to parse a Deadline task. + * + * @param content the content of the task. + * @param isDone whether the task is marked as done. + * @return the Deadline task. + * @throws TaskParsingException if the '(by:' delimiter is missing or parts are empty. + */ + private static Task parseDeadline(String content, boolean isDone) throws TaskParsingException { + int byIndex = content.indexOf("(by:"); + if (byIndex == -1) { + throw new TaskParsingException("Deadline task is missing '(by:' section: " + content); + } + String description = content.substring(0, byIndex).trim(); + String byPart = content.substring(byIndex + 5).trim(); // skip "(by:" + if (byPart.endsWith(")")) { + byPart = byPart.substring(0, byPart.length() - 1).trim(); + } + if (description.isEmpty() || byPart.isEmpty()) { + throw new TaskParsingException("Deadline description or deadline time is empty: " + content); + } + Deadline deadline = new Deadline(description, byPart); + if (isDone) { + deadline.markAsDone(); + } + return deadline; + } - // Now create the event - Event e = new Event(description, fromTime, toPart); - if (isDone) { - e.markAsDone(); - } - return e; + /** + * Helper method to parse an Event task. + * + * @param content the content of the task. + * @param isDone whether the task is marked as done. + * @return the Event task. + * @throws TaskParsingException if the '(from:' or 'to:' delimiters are missing or parts are empty. + */ + private static Task parseEvent(String content, boolean isDone) throws TaskParsingException { + int fromIndex = content.indexOf("(from:"); + if (fromIndex == -1) { + throw new TaskParsingException("Event task is missing '(from:' section: " + content); } - default: - // Unknown task type - return null; + String description = content.substring(0, fromIndex).trim(); + String fromPart = content.substring(fromIndex + 6).trim(); // skip "(from:" + int toIndex = fromPart.indexOf("to:"); + if (toIndex == -1) { + throw new TaskParsingException("Event task is missing 'to:' section in: " + content); + } + String fromTime = fromPart.substring(0, toIndex).trim(); + String toPart = fromPart.substring(toIndex + 3).trim(); // skip "to:" + if (toPart.endsWith(")")) { + toPart = toPart.substring(0, toPart.length() - 1).trim(); + } + if (description.isEmpty() || fromTime.isEmpty() || toPart.isEmpty()) { + throw new TaskParsingException("Event description or time range is empty: " + content); + } + Event event = new Event(description, fromTime, toPart); + if (isDone) { + event.markAsDone(); } + return event; } } From 2182a764a2a148611102f6688412aaad327ffb1b Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Fri, 28 Mar 2025 00:57:03 +0800 Subject: [PATCH 62/66] Refactor parser class --- src/main/java/thoth/parser/Parser.java | 213 +++++++++++++++++-------- 1 file changed, 150 insertions(+), 63 deletions(-) diff --git a/src/main/java/thoth/parser/Parser.java b/src/main/java/thoth/parser/Parser.java index 17942d90a..a2cbcd3a8 100644 --- a/src/main/java/thoth/parser/Parser.java +++ b/src/main/java/thoth/parser/Parser.java @@ -1,7 +1,6 @@ /** * Provides functionality to parse user input into executable commands. */ - package thoth.parser; import thoth.command.Command; @@ -12,83 +11,171 @@ import thoth.command.ExitCommand; import thoth.command.FindCommand; import thoth.command.ListCommand; -import thoth.command.UnknownCommand; import thoth.command.TodoCommand; import thoth.command.DeleteCommand; +import thoth.exceptions.ThothException; + public class Parser { - public static final int INDEX_OFFSET = 1; + private static final int INDEX_OFFSET = 1; /** - * parse the user input into executable commands + * Parses the user input into the corresponding executable command. * - * @param userInput the input string that the user types - * @return the corresponding command to the user input + * @param userInput the input string provided by the user. + * @return the Command object corresponding to the user input. */ - public static Command parse(String userInput) { - userInput = userInput.trim(); + public static Command parse(String userInput) throws ThothException { + String commandWord = userInput.split(" ")[0].trim(); if (userInput.equals("bye")) { return new ExitCommand(); } else if (userInput.equals("list")) { return new ListCommand(); - } else if (userInput.startsWith("mark")) { - try { - int taskIndex = Integer.parseInt(userInput.replace("mark", "").trim()) - INDEX_OFFSET; - return new MarkCommand(taskIndex); - } catch (NumberFormatException e) { - return new UnknownCommand("Please enter a valid number for mark command."); - } - } else if (userInput.startsWith("unmark")) { - try { - int taskIndex = Integer.parseInt(userInput.replace("unmark", "").trim()) - INDEX_OFFSET; - return new UnmarkCommand(taskIndex); - } catch (NumberFormatException e) { - return new UnknownCommand("Please enter a valid number for unmark command."); - } - } else if (userInput.startsWith("delete")) { - try { - int taskIndex = Integer.parseInt(userInput.replace("delete", "").trim()) - INDEX_OFFSET; - return new DeleteCommand(taskIndex); - } catch (NumberFormatException e) { - return new UnknownCommand("Please enter a valid number for delete command."); - } - } else if (userInput.startsWith("todo")) { - String description = userInput.replace("todo", "").trim(); - if (description.isEmpty()) { - return new UnknownCommand("Oops task description is empty"); - } - return new TodoCommand(description); - } else if (userInput.startsWith("deadline")) { - String[] parts = userInput.replace("deadline", "").trim().split(" /by "); - String description = parts[0].trim(); - String by = (parts.length > 1) ? parts[1].trim() : ""; - if (description.isEmpty() || by.isEmpty()) { - return new UnknownCommand("Oops task description is empty or deadline not specified"); - } - return new DeadlineCommand(description, by); - } else if (userInput.startsWith("event")) { - String[] parts = userInput.replace("event", "").trim().split(" /from "); - String description = parts[0].trim(); // Extracts "meeting" - String from = ""; - String to = ""; - if (parts.length > 1) { - String[] timeParts = parts[1].split(" /to "); - from = timeParts[0].trim(); // Extracts "2pm" - if (timeParts.length > 1) { - to = timeParts[1].trim(); // Extracts "4pm" - } - } - if (description.isEmpty() || to.isEmpty() || from.isEmpty()) { - return new UnknownCommand("Oops task description is empty or time range not specified"); - } - return new EventCommand(description, from, to); - } else if (userInput.startsWith("find")) { - String keyWord = userInput.replace("find", "").trim(); - return new FindCommand(keyWord); + } else if (commandWord.equals("mark")) { + return parseMarkCommand(userInput); + } else if (commandWord.equals("unmark")) { + return parseUnmarkCommand(userInput); + } else if (commandWord.equals("delete")) { + return parseDeleteCommand(userInput); + } else if (commandWord.equals("todo")) { + return parseTodoCommand(userInput); + } else if (commandWord.equals("deadline")) { + return parseDeadlineCommand(userInput); + } else if (commandWord.equals("event")) { + return parseEventCommand(userInput); + } else if (commandWord.equals("find")) { + return parseFindCommand(userInput); } else { - return new UnknownCommand("Oops me no understand you~"); + throw new ThothException("Opps, me no understand that command: " + userInput); } } + + + /** + * Parses a command starting with "mark" and returns the corresponding MarkCommand. + * + * @param input the input string starting with "mark". + * @return a MarkCommand if the index is valid; otherwise, an UnknownCommand with an error message. + */ + private static Command parseMarkCommand(String input) throws ThothException { + String[] parts = input.split(" "); + if (parts.length < 2) { + throw new ThothException("Please provide a task number for the mark command."); + } + try { + // parts[1] should contain the number + int taskIndex = Integer.parseInt(parts[1].trim()) - Parser.INDEX_OFFSET; + return new MarkCommand(taskIndex); + } catch (NumberFormatException e) { + throw new ThothException("Please enter a valid task index for the mark command."); + } + } + + + /** + * Parses a command starting with "unmark" and returns the corresponding UnmarkCommand. + * + * @param input the input string starting with "unmark". + * @return an UnmarkCommand if the index is valid; otherwise, an UnknownCommand with an error message. + */ + private static Command parseUnmarkCommand(String input) { + String[] parts = input.split(" "); + if (parts.length < 2) { + throw new ThothException("Please provide a task index for the unmark command."); + } + try { + // parts[1] should contain the number + int taskIndex = Integer.parseInt(parts[1].trim()) - Parser.INDEX_OFFSET; + return new UnmarkCommand(taskIndex); + } catch (NumberFormatException e) { + throw new ThothException("Please enter a valid task index for unmark command."); + } + } + + /** + * Parses a command starting with "delete" and returns the corresponding DeleteCommand. + * + * @param input the input string starting with "delete". + * @return a DeleteCommand if the index is valid; otherwise, an UnknownCommand with an error message. + */ + private static Command parseDeleteCommand(String input) { + String[] parts = input.split(" "); + if (parts.length < 2) { + throw new ThothException("Please provide a task index for the delete command."); + } + try { + // parts[1] should contain the number + int taskIndex = Integer.parseInt(parts[1].trim()) - Parser.INDEX_OFFSET; + return new DeleteCommand(taskIndex); + } catch (NumberFormatException e) { + throw new ThothException("Please enter a valid task index for delete command."); + } + } + + /** + * Parses a command starting with "todo" and returns the corresponding TodoCommand. + * + * @param input the input string starting with "todo". + * @return a TodoCommand if the description is non-empty; otherwise, an UnknownCommand with an error message. + */ + private static Command parseTodoCommand(String input) { + String description = input.replace("todo", "").trim(); + if (description.isEmpty()) { + throw new ThothException("The description for the todo command is empty."); + } + return new TodoCommand(description); + } + + /** + * Parses a command starting with "deadline" and returns the corresponding DeadlineCommand. + * + * @param input the input string starting with "deadline". + * @return a DeadlineCommand if both description and deadline are provided; otherwise, an UnknownCommand with an error message. + */ + private static Command parseDeadlineCommand(String input) { + String[] parts = input.replace("deadline", "").trim().split(" /by "); + String description = parts[0].trim(); + String by = (parts.length > 1) ? parts[1].trim() : ""; + if (description.isEmpty() || by.isEmpty()) { + throw new ThothException("Oops task description is empty or time range not specified"); + } + return new DeadlineCommand(description, by); + } + + /** + * Parses a command starting with "event" and returns the corresponding EventCommand. + * + * @param input the input string starting with "event". + * @return an EventCommand if the description and time range are provided; otherwise, an UnknownCommand with an error message. + */ + private static Command parseEventCommand(String input) { + String[] parts = input.replace("event", "").trim().split(" /from "); + String description = parts[0].trim(); + String from = ""; + String to = ""; + if (parts.length > 1) { + String[] timeParts = parts[1].split(" /to "); + from = timeParts[0].trim(); + if (timeParts.length > 1) { + to = timeParts[1].trim(); + } + } + if (description.isEmpty() || from.isEmpty() || to.isEmpty()) { + throw new ThothException("Oops task description is empty or time range not specified"); + } + return new EventCommand(description, from, to); + } + + /** + * Parses a command starting with "find" and returns the corresponding FindCommand. + * + * @param input the input string starting with "find". + * @return a FindCommand with the provided keyword. + */ + private static Command parseFindCommand(String input) { + String keyWord = input.replace("find", "").trim(); + return new FindCommand(keyWord); + } } From 163f21472eabbf56f850357107d1753cc9895f57 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Fri, 28 Mar 2025 00:57:27 +0800 Subject: [PATCH 63/66] Add in Exceptions class --- src/main/java/thoth/exceptions/ThothException.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/thoth/exceptions/ThothException.java b/src/main/java/thoth/exceptions/ThothException.java index 3756897f4..af78231ec 100644 --- a/src/main/java/thoth/exceptions/ThothException.java +++ b/src/main/java/thoth/exceptions/ThothException.java @@ -1,7 +1,7 @@ package thoth.exceptions; -public class InvalidCommandException extends RuntimeException { - public InvalidCommandException(String message) { +public class ThothException extends RuntimeException { + public ThothException(String message) { super(message); } } From cdec0398bef37b7798b3abb74ebe55773af9e286 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Fri, 28 Mar 2025 00:57:54 +0800 Subject: [PATCH 64/66] Add in exception for storage to task parsing --- src/main/java/thoth/exceptions/TaskParsingException.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/thoth/exceptions/TaskParsingException.java b/src/main/java/thoth/exceptions/TaskParsingException.java index 4e2bcb2da..29e3d71ad 100644 --- a/src/main/java/thoth/exceptions/TaskParsingException.java +++ b/src/main/java/thoth/exceptions/TaskParsingException.java @@ -1,7 +1,7 @@ package thoth.exceptions; public class TaskParsingException extends RuntimeException { - public TaskParsingException(String message) { - super(message); - } + public TaskParsingException(String message) { + super(message); + } } From 0fe8a0d4b74de5fabc623da8909a4985da58bf78 Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Fri, 28 Mar 2025 00:58:50 +0800 Subject: [PATCH 65/66] update exceptions and cath --- src/main/java/thoth/Thoth.java | 30 +++++++++++-------- .../java/thoth/command/DeleteCommand.java | 10 +++---- src/main/java/thoth/command/MarkCommand.java | 11 ++++--- .../java/thoth/command/UnmarkCommand.java | 12 ++++---- 4 files changed, 33 insertions(+), 30 deletions(-) diff --git a/src/main/java/thoth/Thoth.java b/src/main/java/thoth/Thoth.java index 8d796bc4d..e203b2fee 100644 --- a/src/main/java/thoth/Thoth.java +++ b/src/main/java/thoth/Thoth.java @@ -1,11 +1,10 @@ -package thoth.main; +package thoth; import thoth.command.Command; -import thoth.logic.TaskManager; +import thoth.exceptions.TaskParsingException; +import thoth.exceptions.ThothException; import thoth.parser.Parser; -import thoth.storage.Storage; import thoth.tasks.Task; -import thoth.ui.UserInterface; import java.io.IOException; import java.util.List; @@ -30,7 +29,7 @@ public static void main(String[] args) { for (Task t : loadedTasks) { taskManager.addTask(t); } - } catch (IOException e) { + } catch (TaskParsingException | IOException e) { System.err.println("Could not load tasks: " + e.getMessage()); } @@ -38,15 +37,20 @@ public static void main(String[] args) { // Create an endless loop for adding list while (true) { - userInput = ui.readInput(); - // extracts out the command from the user input - Command command = Parser.parse(userInput); - // Executes the command parsed out - command.execute(taskManager, ui); - - if (command.isExit()) { - break; + try { + userInput = ui.readInput(); + // extracts out the command from the user input + Command command = Parser.parse(userInput); + // Executes the command parsed out + command.execute(taskManager, ui); + + if (command.isExit()) { + break; + } + } catch (ThothException e) { + ui.showError(e.getMessage()); } + } } } diff --git a/src/main/java/thoth/command/DeleteCommand.java b/src/main/java/thoth/command/DeleteCommand.java index 22dc869b6..b6fdde123 100644 --- a/src/main/java/thoth/command/DeleteCommand.java +++ b/src/main/java/thoth/command/DeleteCommand.java @@ -1,8 +1,9 @@ package thoth.command; -import thoth.logic.TaskManager; -import thoth.storage.Storage; -import thoth.ui.UserInterface; +import thoth.TaskManager; +import thoth.Storage; +import thoth.UserInterface; +import thoth.exceptions.ThothException; import java.io.IOException; @@ -16,8 +17,7 @@ public DeleteCommand(int taskIndex) { @Override public void execute(TaskManager taskManager, UserInterface ui) { if (taskIndex < 0 || taskIndex >= taskManager.getTaskList().size()) { - UserInterface.printMessage("Task index is out of bounds. Please enter a valid task number."); - return; + throw new ThothException("Task index out of range"); } UserInterface.printDeleteTask(taskManager.getTask(taskIndex), taskManager.getTaskCount() - 1); taskManager.removeTask(taskIndex); diff --git a/src/main/java/thoth/command/MarkCommand.java b/src/main/java/thoth/command/MarkCommand.java index a5e529fdf..f5eb3f453 100644 --- a/src/main/java/thoth/command/MarkCommand.java +++ b/src/main/java/thoth/command/MarkCommand.java @@ -1,9 +1,10 @@ package thoth.command; -import thoth.logic.TaskManager; -import thoth.storage.Storage; +import thoth.TaskManager; +import thoth.Storage; +import thoth.exceptions.ThothException; import thoth.tasks.Task; -import thoth.ui.UserInterface; +import thoth.UserInterface; import java.io.IOException; @@ -17,10 +18,8 @@ public MarkCommand(int taskIndex) { @Override public void execute(TaskManager taskManager, UserInterface ui) { if (taskIndex < 0 || taskIndex >= taskManager.getTaskList().size()) { - UserInterface.printMessage("Task index is out of bounds. Please enter a valid task number."); - return; + throw new ThothException("Task index out of range"); } - taskManager.markTaskAsDone(taskIndex); Task updatedTask = taskManager.getTaskList().get(taskIndex); UserInterface.printMarkAsDone(updatedTask); diff --git a/src/main/java/thoth/command/UnmarkCommand.java b/src/main/java/thoth/command/UnmarkCommand.java index f8ff559b3..0ef73cfde 100644 --- a/src/main/java/thoth/command/UnmarkCommand.java +++ b/src/main/java/thoth/command/UnmarkCommand.java @@ -1,15 +1,16 @@ package thoth.command; -import thoth.logic.TaskManager; -import thoth.storage.Storage; +import thoth.TaskManager; +import thoth.Storage; +import thoth.exceptions.ThothException; import thoth.tasks.Task; -import thoth.ui.UserInterface; +import thoth.UserInterface; import java.io.IOException; public class UnmarkCommand extends Command { int taskIndex; - + public UnmarkCommand(int taskIndex) { this.taskIndex = taskIndex; } @@ -17,8 +18,7 @@ public UnmarkCommand(int taskIndex) { @Override public void execute(TaskManager taskManager, UserInterface ui) { if (taskIndex < 0 || taskIndex >= taskManager.getTaskList().size()) { - UserInterface.printMessage("Task index is out of bounds. Please enter a valid task number."); - return; + throw new ThothException("Task index out of range"); } taskManager.markTaskAsNotDone(taskIndex); From 33efbacbae5a1eb846abbe1a1d947a21431cc86c Mon Sep 17 00:00:00 2001 From: Cheng-Zhiyuan Date: Fri, 28 Mar 2025 00:59:14 +0800 Subject: [PATCH 66/66] Reformat code --- src/main/java/thoth/UserInterface.java | 60 +++++++++++-------- .../java/thoth/command/DeadlineCommand.java | 6 +- src/main/java/thoth/command/EventCommand.java | 6 +- src/main/java/thoth/command/ExitCommand.java | 4 +- src/main/java/thoth/command/FindCommand.java | 5 +- src/main/java/thoth/command/ListCommand.java | 4 +- src/main/java/thoth/command/TodoCommand.java | 6 +- .../java/thoth/command/UnknownCommand.java | 4 +- 8 files changed, 52 insertions(+), 43 deletions(-) diff --git a/src/main/java/thoth/UserInterface.java b/src/main/java/thoth/UserInterface.java index d77f93c0a..c621d32a2 100644 --- a/src/main/java/thoth/UserInterface.java +++ b/src/main/java/thoth/UserInterface.java @@ -1,4 +1,4 @@ -package thoth.ui; +package thoth; import thoth.tasks.Task; @@ -6,8 +6,8 @@ import java.util.Scanner; public class UserInterface { - private final Scanner scanner; public static final String INDENT = "%4s"; + private final Scanner scanner; /** * Constructs a new UserInterface and initializes the input scanner. @@ -16,23 +16,6 @@ public UserInterface() { scanner = new Scanner(System.in); } - /** - * Reads a line of input from the user. - * - * @return the input string entered by the user. - */ - public String readInput() { - return scanner.nextLine(); - } - - /** - * Prints the greeting message to the console. - */ - public void printGreetingMessage() { - System.out.println("Hello! I'm Thoth"); - System.out.println("What can I do for you?"); - } - /** * Prints the specified message to the console. * @@ -42,13 +25,6 @@ public static void printMessage(String message) { System.out.println(message); } - /** - * Prints a goodbye message to the console. - */ - public void printGoodbye() { - System.out.println("Bye. Hope to see you again soon!"); - } - /** * Prints a message indicating that a task has been marked as done. * @@ -107,4 +83,36 @@ public static void printDeleteTask(List task, int taskCount) { System.out.printf(INDENT + "Now you have %d tasks in the list.%n", "", taskCount); } + /** + * Reads a line of input from the user. + * + * @return the input string entered by the user. + */ + public String readInput() { + return scanner.nextLine(); + } + + /** + * Prints the greeting message to the console. + */ + public void printGreetingMessage() { + System.out.println("Hello! I'm Thoth"); + System.out.println("What can I do for you?"); + } + + /** + * Prints a goodbye message to the console. + */ + public void printGoodbye() { + System.out.println("Bye. Hope to see you again soon!"); + } + + /** + * Prints the error message to the console. + * + * @param message the error message to be printed. + */ + public void showError(String message) { + System.out.println(message); + } } diff --git a/src/main/java/thoth/command/DeadlineCommand.java b/src/main/java/thoth/command/DeadlineCommand.java index 0e085578e..bf727af8c 100644 --- a/src/main/java/thoth/command/DeadlineCommand.java +++ b/src/main/java/thoth/command/DeadlineCommand.java @@ -1,10 +1,10 @@ package thoth.command; -import thoth.logic.TaskManager; -import thoth.storage.Storage; +import thoth.TaskManager; +import thoth.Storage; import thoth.tasks.Deadline; import thoth.tasks.Task; -import thoth.ui.UserInterface; +import thoth.UserInterface; import java.io.IOException; diff --git a/src/main/java/thoth/command/EventCommand.java b/src/main/java/thoth/command/EventCommand.java index b595626aa..7a6960b43 100644 --- a/src/main/java/thoth/command/EventCommand.java +++ b/src/main/java/thoth/command/EventCommand.java @@ -1,10 +1,10 @@ package thoth.command; -import thoth.logic.TaskManager; -import thoth.storage.Storage; +import thoth.TaskManager; +import thoth.Storage; import thoth.tasks.Event; import thoth.tasks.Task; -import thoth.ui.UserInterface; +import thoth.UserInterface; import java.io.IOException; diff --git a/src/main/java/thoth/command/ExitCommand.java b/src/main/java/thoth/command/ExitCommand.java index 3a26fd703..d9d98b463 100644 --- a/src/main/java/thoth/command/ExitCommand.java +++ b/src/main/java/thoth/command/ExitCommand.java @@ -1,7 +1,7 @@ package thoth.command; -import thoth.logic.TaskManager; -import thoth.ui.UserInterface; +import thoth.TaskManager; +import thoth.UserInterface; public class ExitCommand extends Command { diff --git a/src/main/java/thoth/command/FindCommand.java b/src/main/java/thoth/command/FindCommand.java index 3fe91e053..404047466 100644 --- a/src/main/java/thoth/command/FindCommand.java +++ b/src/main/java/thoth/command/FindCommand.java @@ -1,8 +1,9 @@ package thoth.command; -import thoth.logic.TaskManager; -import thoth.ui.UserInterface; +import thoth.TaskManager; +import thoth.UserInterface; import thoth.tasks.Task; // Assuming tasks are represented by a Task class + import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/thoth/command/ListCommand.java b/src/main/java/thoth/command/ListCommand.java index 0a060d52a..bcb685ddd 100644 --- a/src/main/java/thoth/command/ListCommand.java +++ b/src/main/java/thoth/command/ListCommand.java @@ -1,7 +1,7 @@ package thoth.command; -import thoth.logic.TaskManager; -import thoth.ui.UserInterface; +import thoth.TaskManager; +import thoth.UserInterface; public class ListCommand extends Command { diff --git a/src/main/java/thoth/command/TodoCommand.java b/src/main/java/thoth/command/TodoCommand.java index 1ef908c4c..689526e47 100644 --- a/src/main/java/thoth/command/TodoCommand.java +++ b/src/main/java/thoth/command/TodoCommand.java @@ -1,10 +1,10 @@ package thoth.command; -import thoth.logic.TaskManager; -import thoth.storage.Storage; +import thoth.TaskManager; +import thoth.Storage; import thoth.tasks.Task; import thoth.tasks.Todo; -import thoth.ui.UserInterface; +import thoth.UserInterface; import java.io.IOException; diff --git a/src/main/java/thoth/command/UnknownCommand.java b/src/main/java/thoth/command/UnknownCommand.java index bed975f10..97a42e0c3 100644 --- a/src/main/java/thoth/command/UnknownCommand.java +++ b/src/main/java/thoth/command/UnknownCommand.java @@ -1,7 +1,7 @@ package thoth.command; -import thoth.logic.TaskManager; -import thoth.ui.UserInterface; +import thoth.TaskManager; +import thoth.UserInterface; public class UnknownCommand extends Command { String message;