From f2628624a681b87893c6c174972c0c735d8276bc Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Sat, 2 Mar 2024 05:25:59 +0800 Subject: [PATCH 01/52] Level 0. Rename, Greet, Exit --- src/main/java/Duke.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 5d313334c..5a6018c66 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -5,6 +5,11 @@ public static void main(String[] args) { + "| | | | | | | |/ / _ \\\n" + "| |_| | |_| | < __/\n" + "|____/ \\__,_|_|\\_\\___|\n"; - System.out.println("Hello from\n" + logo); + System.out.println("____________________________________________________________"); + System.out.println("Hello! I'm [Spark]"); + System.out.println("What can I do for you?"); + System.out.println("____________________________________________________________"); + System.out.println("Bye. Hope to see you again soon!"); + System.out.println("____________________________________________________________"); } } From ee06ba5029837617f3e0c67a9b7b84e0c8d742df Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Sat, 2 Mar 2024 05:29:22 +0800 Subject: [PATCH 02/52] [haowern98] ip Level 0. Rename, Greet, Exit --- src/main/java/Duke.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 5a6018c66..66a39e977 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,4 +1,4 @@ -public class Duke { +public class Duke { public static void main(String[] args) { String logo = " ____ _ \n" + "| _ \\ _ _| | _____ \n" From ca2b98faa630246f6534ce672c22572183a32a9d Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Thu, 7 Mar 2024 00:02:03 +0800 Subject: [PATCH 03/52] Level 0. Rename, Greet, Exit From 492a18e4c4a78a603d86763f8e7a5f4fd9cac5b8 Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Thu, 7 Mar 2024 00:25:48 +0800 Subject: [PATCH 04/52] Level 1. Echo --- src/main/java/Duke.java | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 66a39e977..66f392891 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,15 +1,29 @@ -public class Duke { +import java.util.Scanner; + +public class Duke { public static void main(String[] args) { + Scanner scanner = new Scanner(System.in); String logo = " ____ _ \n" + "| _ \\ _ _| | _____ \n" + "| | | | | | | |/ / _ \\\n" + "| |_| | |_| | < __/\n" + "|____/ \\__,_|_|\\_\\___|\n"; System.out.println("____________________________________________________________"); - System.out.println("Hello! I'm [Spark]"); + System.out.println("Hello! I'm [Sparky]"); System.out.println("What can I do for you?"); System.out.println("____________________________________________________________"); - System.out.println("Bye. Hope to see you again soon!"); - System.out.println("____________________________________________________________"); + + while (true) { + String input = scanner.nextLine().trim(); + System.out.println("____________________________________________________________"); + System.out.println(input); + System.out.println("____________________________________________________________"); + if (input.equalsIgnoreCase("bye")) { + System.out.println("Bye. Hope to see you again soon!"); + System.out.println("____________________________________________________________"); + break; + } + } + scanner.close(); } } From 81ef55c6bb28d22577aefbad184f7921e3f4b0f8 Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Thu, 7 Mar 2024 00:34:03 +0800 Subject: [PATCH 05/52] Level 2. Add, List --- src/main/java/Duke.java | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 66f392891..5f4d7853d 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -3,6 +3,9 @@ public class Duke { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); + String[] tasks = new String[100]; + int taskCount = 0; + String logo = " ____ _ \n" + "| _ \\ _ _| | _____ \n" + "| | | | | | | |/ / _ \\\n" @@ -16,13 +19,25 @@ public static void main(String[] args) { while (true) { String input = scanner.nextLine().trim(); System.out.println("____________________________________________________________"); - System.out.println(input); - System.out.println("____________________________________________________________"); if (input.equalsIgnoreCase("bye")) { System.out.println("Bye. Hope to see you again soon!"); System.out.println("____________________________________________________________"); break; + } else if (input.equalsIgnoreCase("list")) { + if (taskCount == 0) { + System.out.println("No tasks added yet."); + } else { + System.out.println("Tasks:"); + for (int i = 0; i < taskCount; i++) { + System.out.println((i + 1) + ". " + tasks[i]); + } + } + } else { + tasks[taskCount] = input; + taskCount++; + System.out.println("added: " + input); } + System.out.println("____________________________________________________________"); } scanner.close(); } From 3d218f716b23c75bb5acc43f82ba612786c40ce6 Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Thu, 7 Mar 2024 04:50:03 +0800 Subject: [PATCH 06/52] Level-3 : Mark as Done --- src/main/java/Duke.java | 97 +++++++++++++++++++++++++++++++++++------ 1 file changed, 84 insertions(+), 13 deletions(-) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 5f4d7853d..276e39d8b 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,16 +1,37 @@ import java.util.Scanner; +class Task { + protected String description; + protected boolean isDone; + + public Task(String description) { + this.description = description; + this.isDone = false; + } + + public String getStatusIcon() { + return (isDone ? "[X]" : "[ ]"); // mark done task with X + } + + public void markAsDone() { + this.isDone = true; + } + + public void markAsUndone() { + this.isDone = false; + } + + public String getDescription() { + return description; + } +} + public class Duke { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); - String[] tasks = new String[100]; + Task[] tasks = new Task[100]; int taskCount = 0; - String logo = " ____ _ \n" - + "| _ \\ _ _| | _____ \n" - + "| | | | | | | |/ / _ \\\n" - + "| |_| | |_| | < __/\n" - + "|____/ \\__,_|_|\\_\\___|\n"; System.out.println("____________________________________________________________"); System.out.println("Hello! I'm [Sparky]"); System.out.println("What can I do for you?"); @@ -19,23 +40,73 @@ public static void main(String[] args) { while (true) { String input = scanner.nextLine().trim(); System.out.println("____________________________________________________________"); + + // Handle the "bye" command if (input.equalsIgnoreCase("bye")) { - System.out.println("Bye. Hope to see you again soon!"); + System.out.println("Bye. Hope to see you again soooon!"); System.out.println("____________________________________________________________"); - break; - } else if (input.equalsIgnoreCase("list")) { + break; // Exit the loop + } + + // Handle the "list" command + if (input.equalsIgnoreCase("list")) { if (taskCount == 0) { System.out.println("No tasks added yet."); } else { - System.out.println("Tasks:"); + System.out.println("Here are the tasks in your list:"); for (int i = 0; i < taskCount; i++) { - System.out.println((i + 1) + ". " + tasks[i]); + System.out.println((i + 1) + "." + tasks[i].getStatusIcon() + " " + tasks[i].getDescription()); } } - } else { - tasks[taskCount] = input; + System.out.println("____________________________________________________________"); + continue; // Skip the rest of the loop and start over + } + + // Handle the "mark" command + if (input.startsWith("mark")) { + String[] parts = input.split(" "); + if (parts.length == 2) { + int index = Integer.parseInt(parts[1]) - 1; + if (index >= 0 && index < taskCount) { + tasks[index].markAsDone(); + System.out.println("Nice! I've marked this task as done:"); + System.out.println(" " + tasks[index].getStatusIcon() + " " + tasks[index].getDescription()); + } else { + System.out.println("Invalid task index."); + } + } else { + System.out.println("Invalid command format."); + } + System.out.println("____________________________________________________________"); + continue; // Skip the rest of the loop and start over + } + + // Handle the "unmark" command + if (input.startsWith("unmark")) { + String[] parts = input.split(" "); + if (parts.length == 2) { + int index = Integer.parseInt(parts[1]) - 1; + if (index >= 0 && index < taskCount) { + tasks[index].markAsUndone(); + System.out.println("OK, I've marked this task as not done yet:"); + System.out.println(" " + tasks[index].getStatusIcon() + " " + tasks[index].getDescription()); + } else { + System.out.println("Invalid task index."); + } + } else { + System.out.println("Invalid command format."); + } + System.out.println("____________________________________________________________"); + continue; // Skip the rest of the loop and start over + } + + // Default case for adding tasks + if (taskCount < tasks.length) { // Check if there's space for new tasks + tasks[taskCount] = new Task(input); taskCount++; System.out.println("added: " + input); + } else { + System.out.println("Task limit reached. Can't add more tasks."); } System.out.println("____________________________________________________________"); } From 46506cdd8177a464bec11ad2707890be497e73d0 Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Thu, 7 Mar 2024 05:50:22 +0800 Subject: [PATCH 07/52] A-CodingStandard Refractored code. --- src/main/java/Duke.java | 119 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 276e39d8b..57b4f7911 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -13,6 +13,22 @@ public String getStatusIcon() { return (isDone ? "[X]" : "[ ]"); // mark done task with X } + public void markAsDone() { + this.isDone = true;import java.util.Scanner; + +class Task { + protected String description; + protected boolean isDone; + + public Task(String description) { + this.description = description; + this.isDone = false; + } + + public String getStatusIcon() { + return (isDone ? "[X]" : "[ ]"); // Marks done task with X + } + public void markAsDone() { this.isDone = true; } @@ -26,6 +42,109 @@ public String getDescription() { } } +public class Duke { + public static void main(String[] args) { + Scanner scanner = new Scanner(System.in); + Task[] tasks = new Task[100]; + int taskCount = 0; + + System.out.println("____________________________________________________________"); + System.out.println("Hello! I'm [Sparky]"); + System.out.println("What can I do for you?"); + System.out.println("____________________________________________________________"); + + while (true) { + String input = scanner.nextLine().trim(); + System.out.println("____________________________________________________________"); + + // Handles the "bye" command + if (input.equalsIgnoreCase("bye")) { + System.out.println("Bye. Hope to see you again soooon!"); + System.out.println("____________________________________________________________"); + break; // Exit the loop + } + + // Handles the "list" command + if (input.equalsIgnoreCase("list")) { + if (taskCount == 0) { + System.out.println("No tasks added yet."); + } else { + System.out.println("Here are the tasks in your list:"); + for (int i = 0; i < taskCount; i++) { + System.out.println((i + 1) + "." + tasks[i].getStatusIcon() + " " + tasks[i].getDescription()); + } + } + System.out.println("____________________________________________________________"); + continue; // Skip the rest of the loop and start over + } + + // Handles the "mark" command + if (input.startsWith("mark")) { + String[] parts = input.split(" "); + + if (parts.length != 2) { + System.out.println("Invalid command format."); + } else { + int index = Integer.parseInt(parts[1]) - 1; + if (index >= 0 && index < taskCount) { + tasks[index].markAsDone(); + System.out.println("Nice! I've marked this task as done:"); + System.out.println(" " + tasks[index].getStatusIcon() + " " + tasks[index].getDescription()); + } else { + System.out.println("Invalid task index."); + } + } + + System.out.println("____________________________________________________________"); + continue; + } + + // Handles the "unmark" command + if (input.startsWith("unmark")) { + String[] parts = input.split(" "); + + if (parts.length != 2) { + System.out.println("Invalid command format."); + } else { + int index = Integer.parseInt(parts[1]) - 1; + if (index >= 0 && index < taskCount) { + tasks[index].markAsUndone(); + System.out.println("OK, I've marked this task as not done yet:"); + System.out.println(" " + tasks[index].getStatusIcon() + " " + tasks[index].getDescription()); + } else { + System.out.println("Invalid task index."); + } + } + + System.out.println("____________________________________________________________"); + continue; + } + + // Default case for adding tasks + if (taskCount < tasks.length) { // Checks if there's space for new tasks + tasks[taskCount] = new Task(input); + taskCount++; + System.out.println("added: " + input); + } else { + System.out.println("Task limit reached. Can't add more tasks."); + } + System.out.println("____________________________________________________________"); + } + scanner.close(); + } +} + + } + + public void markAsUndone() { + this.isDone = false; + } + + public String getDescription() { + return description; + } +} + public class Duke { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); From 68c0ab264d849c68da6a6b69a84f3ba988494635 Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Thu, 7 Mar 2024 14:22:43 +0800 Subject: [PATCH 08/52] Level 4. ToDos, Events, Deadlines --- src/main/java/Duke.java | 144 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 143 insertions(+), 1 deletion(-) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 57b4f7911..5292407f9 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -14,7 +14,149 @@ public String getStatusIcon() { } public void markAsDone() { - this.isDone = true;import java.util.Scanner; + this.isDone = true;import java.util.Scanner;// Duke.java +import java.util.Scanner; + +public class Duke { + public static void main(String[] args) { + Scanner scanner = new Scanner(System.in); + Task[] tasks = new Task[100]; + int taskCount = 0; + + System.out.println("____________________________________________________________"); + System.out.println("Hello! I'm [Sparky]"); + System.out.println("What can I do for you?"); + System.out.println("____________________________________________________________"); + + while (true) { + String input = scanner.nextLine().trim(); + System.out.println("____________________________________________________________"); + + // Handles the "bye" command + if (input.equalsIgnoreCase("bye")) { + System.out.println("Bye. Hope to see you again soooon!"); + System.out.println("____________________________________________________________"); + break; // Exit the loop + } + + // Handles the "list" command + if (input.equalsIgnoreCase("list")) { + if (taskCount == 0) { + System.out.println("No tasks added yet."); + } else { + System.out.println("Here are the tasks in your list:"); + for (int i = 0; i < taskCount; i++) { + System.out.println((i + 1) + "." + tasks[i]); + } + } + System.out.println("____________________________________________________________"); + continue; // Skip the rest of the loop and start over + } + + // Handles the "mark" command + if (input.startsWith("mark")) { + String[] parts = input.split(" "); + + if (parts.length != 2) { + System.out.println("Invalid command format."); + } else { + int index = Integer.parseInt(parts[1]) - 1; + if (index >= 0 && index < taskCount) { + tasks[index].markAsDone(); + System.out.println("Nice! I've marked this task as done:"); + System.out.println(" " + tasks[index].getStatusIcon() + " " + tasks[index].getDescription()); + } else { + System.out.println("Invalid task index."); + } + } + + System.out.println("____________________________________________________________"); + continue; + } + + // Handles the "unmark" command + if (input.startsWith("unmark")) { + String[] parts = input.split(" "); + + if (parts.length != 2) { + System.out.println("Invalid command format."); + } else { + int index = Integer.parseInt(parts[1]) - 1; + if (index >= 0 && index < taskCount) { + tasks[index].markAsUndone(); + System.out.println("OK, I've marked this task as not done yet:"); + System.out.println(" " + tasks[index].getStatusIcon() + " " + tasks[index].getDescription()); + } else { + System.out.println("Invalid task index."); + } + } + + System.out.println("____________________________________________________________"); + continue; + } + + // Handles adding tasks + if (input.startsWith("todo")) { + String description = input.substring(5).trim(); + tasks[taskCount] = new Todo(description); + taskCount++; + System.out.println("Got it. I've added this task:"); + System.out.println(" " + tasks[taskCount - 1]); + System.out.println("Now you have " + taskCount + " tasks in the list."); + System.out.println("____________________________________________________________"); + continue; + } + + if (input.startsWith("deadline")) { + String[] parts = input.split("/by"); + if (parts.length != 2) { + System.out.println("Invalid command format."); + System.out.println("____________________________________________________________"); + continue; + } + String description = parts[0].substring(9).trim(); + String by = parts[1].trim(); + tasks[taskCount] = new Deadline(description, by); + taskCount++; + System.out.println("Got it. I've added this task:"); + System.out.println(" " + tasks[taskCount - 1]); + System.out.println("Now you have " + taskCount + " tasks in the list."); + System.out.println("____________________________________________________________"); + continue; + } + + if (input.startsWith("event")) { + String[] parts = input.split("/from"); + if (parts.length != 2) { + System.out.println("Invalid command format."); + System.out.println("____________________________________________________________"); + continue; + } + String[] eventParts = parts[1].split("/to"); + if (eventParts.length != 2) { + System.out.println("Invalid command format."); + System.out.println("____________________________________________________________"); + continue; + } + String description = parts[0].substring(5).trim(); + String from = eventParts[0].trim(); + String to = eventParts[1].trim(); + tasks[taskCount] = new Event(description, from, to); + taskCount++; + System.out.println("Got it. I've added this task:"); + System.out.println(" " + tasks[taskCount - 1]); + System.out.println("Now you have " + taskCount + " tasks in the list."); + System.out.println("____________________________________________________________"); + continue; + } + + System.out.println("Sorry, I don't understand that command."); + System.out.println("____________________________________________________________"); + } + scanner.close(); + } +} + class Task { protected String description; From 7a1d824db409441c7c3bf9d5878267d671e576e0 Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Thu, 7 Mar 2024 14:24:08 +0800 Subject: [PATCH 09/52] Level 4. ToDos, Events, Deadlines --- src/main/java/Deadline.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/main/java/Deadline.java diff --git a/src/main/java/Deadline.java b/src/main/java/Deadline.java new file mode 100644 index 000000000..f82998636 --- /dev/null +++ b/src/main/java/Deadline.java @@ -0,0 +1,13 @@ +public class Deadline extends Task { + protected String by; + + public Deadline(String description, String by) { + super(description); + this.by = by; + } + + @Override + public String toString() { + return "[D]" + getStatusIcon() + " " + description + " (by: " + by + ")"; + } +} From a1e4afed429ab4e30f3ae5af22d4537e3e36c057 Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Thu, 7 Mar 2024 14:25:07 +0800 Subject: [PATCH 10/52] Level 4. ToDos, Events, Deadlines --- src/main/java/Event.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/main/java/Event.java diff --git a/src/main/java/Event.java b/src/main/java/Event.java new file mode 100644 index 000000000..4810084a2 --- /dev/null +++ b/src/main/java/Event.java @@ -0,0 +1,15 @@ +public class Event extends Task { + protected String from; + protected String to; + + public Event(String description, String from, String to) { + super(description); + this.from = from; + this.to = to; + } + + @Override + public String toString() { + return "[E]" + getStatusIcon() + " " + description + " (from: " + from + " to: " + to + ")"; + } +} From 16274a43ee8605c6b5b52092a02712252cff3735 Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Thu, 7 Mar 2024 14:26:11 +0800 Subject: [PATCH 11/52] Level 4. ToDos, Events, Deadlines --- src/main/java/Task.java | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 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..8d8275dc7 --- /dev/null +++ b/src/main/java/Task.java @@ -0,0 +1,38 @@ +public class Task { + protected String description; + protected boolean isDone; + + public Task(String description) { + this.description = description; + this.isDone = false; + } + + public String getStatusIcon() { + return (isDone ? "[X]" : "[ ]"); // mark done task with X + } + + public void markAsDone() { + this.isDone = true; + } + + public void markAsUndone() { + this.isDone = false; + } + + public String getDescription() { + return description; + } + + // Method to update the status icon based on task completion + public void updateStatusIcon() { + // If the task is done, mark it with [X], otherwise mark it with [ ] + String statusIcon = (isDone ? "[X]" : "[ ]"); + // Update the description with the new status icon + this.description = statusIcon + " " + description.substring(4); // Remove existing status icon before updating + } + + @Override + public String toString() { + return description; + } +} From 443a681f3804626534ced5c884e1945e1704d38c Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Thu, 7 Mar 2024 14:27:05 +0800 Subject: [PATCH 12/52] Level 4. ToDos, Events, Deadlines --- src/main/java/Todo.java | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/main/java/Todo.java diff --git a/src/main/java/Todo.java b/src/main/java/Todo.java new file mode 100644 index 000000000..876a001db --- /dev/null +++ b/src/main/java/Todo.java @@ -0,0 +1,10 @@ +public class Todo extends Task { + public Todo(String description) { + super(description); + } + + @Override + public String toString() { + return "[T]" + getStatusIcon() + " " + description; + } +} From f230d8d5b9819d318aaa54ef643726e0cf5935f2 Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Thu, 7 Mar 2024 14:34:06 +0800 Subject: [PATCH 13/52] Level 4. ToDos, Events, Deadlines --- src/main/java/Duke.java | 236 +--------------------------------------- 1 file changed, 1 insertion(+), 235 deletions(-) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 5292407f9..91bd6bba8 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,20 +1,4 @@ -import java.util.Scanner; - -class Task { - protected String description; - protected boolean isDone; - - public Task(String description) { - this.description = description; - this.isDone = false; - } - - public String getStatusIcon() { - return (isDone ? "[X]" : "[ ]"); // mark done task with X - } - - public void markAsDone() { - this.isDone = true;import java.util.Scanner;// Duke.java +// Duke.java import java.util.Scanner; public class Duke { @@ -156,221 +140,3 @@ public static void main(String[] args) { scanner.close(); } } - - -class Task { - protected String description; - protected boolean isDone; - - public Task(String description) { - this.description = description; - this.isDone = false; - } - - public String getStatusIcon() { - return (isDone ? "[X]" : "[ ]"); // Marks done task with X - } - - public void markAsDone() { - this.isDone = true; - } - - public void markAsUndone() { - this.isDone = false; - } - - public String getDescription() { - return description; - } -} - -public class Duke { - public static void main(String[] args) { - Scanner scanner = new Scanner(System.in); - Task[] tasks = new Task[100]; - int taskCount = 0; - - System.out.println("____________________________________________________________"); - System.out.println("Hello! I'm [Sparky]"); - System.out.println("What can I do for you?"); - System.out.println("____________________________________________________________"); - - while (true) { - String input = scanner.nextLine().trim(); - System.out.println("____________________________________________________________"); - - // Handles the "bye" command - if (input.equalsIgnoreCase("bye")) { - System.out.println("Bye. Hope to see you again soooon!"); - System.out.println("____________________________________________________________"); - break; // Exit the loop - } - - // Handles the "list" command - if (input.equalsIgnoreCase("list")) { - if (taskCount == 0) { - System.out.println("No tasks added yet."); - } else { - System.out.println("Here are the tasks in your list:"); - for (int i = 0; i < taskCount; i++) { - System.out.println((i + 1) + "." + tasks[i].getStatusIcon() + " " + tasks[i].getDescription()); - } - } - System.out.println("____________________________________________________________"); - continue; // Skip the rest of the loop and start over - } - - // Handles the "mark" command - if (input.startsWith("mark")) { - String[] parts = input.split(" "); - - if (parts.length != 2) { - System.out.println("Invalid command format."); - } else { - int index = Integer.parseInt(parts[1]) - 1; - if (index >= 0 && index < taskCount) { - tasks[index].markAsDone(); - System.out.println("Nice! I've marked this task as done:"); - System.out.println(" " + tasks[index].getStatusIcon() + " " + tasks[index].getDescription()); - } else { - System.out.println("Invalid task index."); - } - } - - System.out.println("____________________________________________________________"); - continue; - } - - // Handles the "unmark" command - if (input.startsWith("unmark")) { - String[] parts = input.split(" "); - - if (parts.length != 2) { - System.out.println("Invalid command format."); - } else { - int index = Integer.parseInt(parts[1]) - 1; - if (index >= 0 && index < taskCount) { - tasks[index].markAsUndone(); - System.out.println("OK, I've marked this task as not done yet:"); - System.out.println(" " + tasks[index].getStatusIcon() + " " + tasks[index].getDescription()); - } else { - System.out.println("Invalid task index."); - } - } - - System.out.println("____________________________________________________________"); - continue; - } - - // Default case for adding tasks - if (taskCount < tasks.length) { // Checks if there's space for new tasks - tasks[taskCount] = new Task(input); - taskCount++; - System.out.println("added: " + input); - } else { - System.out.println("Task limit reached. Can't add more tasks."); - } - System.out.println("____________________________________________________________"); - } - scanner.close(); - } -} - - } - - public void markAsUndone() { - this.isDone = false; - } - - public String getDescription() { - return description; - } -} - -public class Duke { - public static void main(String[] args) { - Scanner scanner = new Scanner(System.in); - Task[] tasks = new Task[100]; - int taskCount = 0; - - System.out.println("____________________________________________________________"); - System.out.println("Hello! I'm [Sparky]"); - System.out.println("What can I do for you?"); - System.out.println("____________________________________________________________"); - - while (true) { - String input = scanner.nextLine().trim(); - System.out.println("____________________________________________________________"); - - // Handle the "bye" command - if (input.equalsIgnoreCase("bye")) { - System.out.println("Bye. Hope to see you again soooon!"); - System.out.println("____________________________________________________________"); - break; // Exit the loop - } - - // Handle the "list" command - if (input.equalsIgnoreCase("list")) { - if (taskCount == 0) { - System.out.println("No tasks added yet."); - } else { - System.out.println("Here are the tasks in your list:"); - for (int i = 0; i < taskCount; i++) { - System.out.println((i + 1) + "." + tasks[i].getStatusIcon() + " " + tasks[i].getDescription()); - } - } - System.out.println("____________________________________________________________"); - continue; // Skip the rest of the loop and start over - } - - // Handle the "mark" command - if (input.startsWith("mark")) { - String[] parts = input.split(" "); - if (parts.length == 2) { - int index = Integer.parseInt(parts[1]) - 1; - if (index >= 0 && index < taskCount) { - tasks[index].markAsDone(); - System.out.println("Nice! I've marked this task as done:"); - System.out.println(" " + tasks[index].getStatusIcon() + " " + tasks[index].getDescription()); - } else { - System.out.println("Invalid task index."); - } - } else { - System.out.println("Invalid command format."); - } - System.out.println("____________________________________________________________"); - continue; // Skip the rest of the loop and start over - } - - // Handle the "unmark" command - if (input.startsWith("unmark")) { - String[] parts = input.split(" "); - if (parts.length == 2) { - int index = Integer.parseInt(parts[1]) - 1; - if (index >= 0 && index < taskCount) { - tasks[index].markAsUndone(); - System.out.println("OK, I've marked this task as not done yet:"); - System.out.println(" " + tasks[index].getStatusIcon() + " " + tasks[index].getDescription()); - } else { - System.out.println("Invalid task index."); - } - } else { - System.out.println("Invalid command format."); - } - System.out.println("____________________________________________________________"); - continue; // Skip the rest of the loop and start over - } - - // Default case for adding tasks - if (taskCount < tasks.length) { // Check if there's space for new tasks - tasks[taskCount] = new Task(input); - taskCount++; - System.out.println("added: " + input); - } else { - System.out.println("Task limit reached. Can't add more tasks."); - } - System.out.println("____________________________________________________________"); - } - scanner.close(); - } -} From 6378f3b178c997323446d6ab6bf04c7d1ef5f280 Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Thu, 7 Mar 2024 21:50:34 +0800 Subject: [PATCH 14/52] A-CodeQuality --- src/main/java/Duke.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 91bd6bba8..58acaa21c 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,4 +1,3 @@ -// Duke.java import java.util.Scanner; public class Duke { From 58efeb1a31aa5a836f7223858aaf23069520fbcf Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Thu, 7 Mar 2024 22:44:15 +0800 Subject: [PATCH 15/52] Level 5. Handle Errors Create DukeException.java --- src/main/java/DukeException.java | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 src/main/java/DukeException.java diff --git a/src/main/java/DukeException.java b/src/main/java/DukeException.java new file mode 100644 index 000000000..fe8837e3a --- /dev/null +++ b/src/main/java/DukeException.java @@ -0,0 +1,5 @@ +public class DukeException extends Exception { + public DukeException(String message) { + super(message); + } +} From f4533c74181601c02af570f7eba08a22df485c60 Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Thu, 7 Mar 2024 22:47:01 +0800 Subject: [PATCH 16/52] Level 5. Handle Errors Updated Duke to deal with errors. --- src/main/java/Duke.java | 200 ++++++++++++++++++---------------------- 1 file changed, 91 insertions(+), 109 deletions(-) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 58acaa21c..2880091a5 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -15,126 +15,108 @@ public static void main(String[] args) { String input = scanner.nextLine().trim(); System.out.println("____________________________________________________________"); - // Handles the "bye" command - if (input.equalsIgnoreCase("bye")) { - System.out.println("Bye. Hope to see you again soooon!"); - System.out.println("____________________________________________________________"); - break; // Exit the loop - } - - // Handles the "list" command - if (input.equalsIgnoreCase("list")) { - if (taskCount == 0) { - System.out.println("No tasks added yet."); - } else { - System.out.println("Here are the tasks in your list:"); - for (int i = 0; i < taskCount; i++) { - System.out.println((i + 1) + "." + tasks[i]); + try { + if (input.equalsIgnoreCase("bye")) { + System.out.println("Bye. Hope to see you again soooon!"); + System.out.println("____________________________________________________________"); + break; + } else if (input.equalsIgnoreCase("list")) { + if (taskCount == 0) { + System.out.println("No tasks added yet."); + } else { + System.out.println("Here are the tasks in your list:"); + for (int i = 0; i < taskCount; i++) { + System.out.println((i + 1) + "." + tasks[i]); + } + } + System.out.println("____________________________________________________________"); + } else if (input.startsWith("mark")) { + String[] parts = input.split(" "); + if (parts.length != 2) { + throw new DukeException("Invalid command format. Usage: mark "); } - } - System.out.println("____________________________________________________________"); - continue; // Skip the rest of the loop and start over - } - - // Handles the "mark" command - if (input.startsWith("mark")) { - String[] parts = input.split(" "); - - if (parts.length != 2) { - System.out.println("Invalid command format."); - } else { int index = Integer.parseInt(parts[1]) - 1; - if (index >= 0 && index < taskCount) { - tasks[index].markAsDone(); - System.out.println("Nice! I've marked this task as done:"); - System.out.println(" " + tasks[index].getStatusIcon() + " " + tasks[index].getDescription()); - } else { - System.out.println("Invalid task index."); + if (index < 0 || index >= taskCount) { + throw new DukeException("Invalid task number."); + } + tasks[index].markAsDone(); + System.out.println("Nice! I've marked this task as done:"); + System.out.println(" " + tasks[index].getStatusIcon() + " " + tasks[index].getDescription()); + System.out.println("____________________________________________________________"); + } else if (input.startsWith("unmark")) { + String[] parts = input.split(" "); + if (parts.length != 2) { + throw new DukeException("Invalid command format. Usage: unmark "); } - } - - System.out.println("____________________________________________________________"); - continue; - } - - // Handles the "unmark" command - if (input.startsWith("unmark")) { - String[] parts = input.split(" "); - - if (parts.length != 2) { - System.out.println("Invalid command format."); - } else { int index = Integer.parseInt(parts[1]) - 1; - if (index >= 0 && index < taskCount) { - tasks[index].markAsUndone(); - System.out.println("OK, I've marked this task as not done yet:"); - System.out.println(" " + tasks[index].getStatusIcon() + " " + tasks[index].getDescription()); - } else { - System.out.println("Invalid task index."); + if (index < 0 || index >= taskCount) { + throw new DukeException("Invalid task number."); } - } - - System.out.println("____________________________________________________________"); - continue; - } - - // Handles adding tasks - if (input.startsWith("todo")) { - String description = input.substring(5).trim(); - tasks[taskCount] = new Todo(description); - taskCount++; - System.out.println("Got it. I've added this task:"); - System.out.println(" " + tasks[taskCount - 1]); - System.out.println("Now you have " + taskCount + " tasks in the list."); - System.out.println("____________________________________________________________"); - continue; - } - - if (input.startsWith("deadline")) { - String[] parts = input.split("/by"); - if (parts.length != 2) { - System.out.println("Invalid command format."); + tasks[index].markAsUndone(); + System.out.println("OK, I've marked this task as not done yet:"); + System.out.println(" " + tasks[index].getStatusIcon() + " " + tasks[index].getDescription()); System.out.println("____________________________________________________________"); - continue; - } - String description = parts[0].substring(9).trim(); - String by = parts[1].trim(); - tasks[taskCount] = new Deadline(description, by); - taskCount++; - System.out.println("Got it. I've added this task:"); - System.out.println(" " + tasks[taskCount - 1]); - System.out.println("Now you have " + taskCount + " tasks in the list."); - System.out.println("____________________________________________________________"); - continue; - } - - if (input.startsWith("event")) { - String[] parts = input.split("/from"); - if (parts.length != 2) { - System.out.println("Invalid command format."); + } else if (input.startsWith("todo")) { + String description = input.substring(5).trim(); + if (description.isEmpty()) { + throw new DukeException("Sorry! The description of a todo can't be empty"); + } + tasks[taskCount] = new Todo(description); + taskCount++; + System.out.println("Got it. I've added this task:"); + System.out.println(" " + tasks[taskCount - 1]); + System.out.println("Now you have " + taskCount + " tasks in the list."); System.out.println("____________________________________________________________"); - continue; - } - String[] eventParts = parts[1].split("/to"); - if (eventParts.length != 2) { - System.out.println("Invalid command format."); + } else if (input.startsWith("deadline")) { + String[] parts = input.split("/by"); + if (parts.length != 2) { + throw new DukeException("Invalid command format. Usage: deadline /by "); + } + String description = parts[0].substring(9).trim(); + String by = parts[1].trim(); + if (description.isEmpty() || by.isEmpty()) { + throw new DukeException("OOPS!!! Both description and date cannot be empty."); + } + tasks[taskCount] = new Deadline(description, by); + taskCount++; + System.out.println("Got it. I've added this task:"); + System.out.println(" " + tasks[taskCount - 1]); + System.out.println("Now you have " + taskCount + " tasks in the list."); + System.out.println("____________________________________________________________"); + } else if (input.startsWith("event")) { + String[] parts = input.split("/from"); + if (parts.length != 2) { + throw new DukeException("Invalid command format. Usage: event /from /to "); + } + String[] eventParts = parts[1].split("/to"); + if (eventParts.length != 2) { + throw new DukeException("Invalid command format. Usage: event /from /to "); + } + String description = parts[0].substring(5).trim(); + String from = eventParts[0].trim(); + String to = eventParts[1].trim(); + if (description.isEmpty() || from.isEmpty() || to.isEmpty()) { + throw new DukeException("OOPS!!! All fields (description, start, end) must be provided."); + } + tasks[taskCount] = new Event(description, from, to); + taskCount++; + System.out.println("Got it. I've added this task:"); + System.out.println(" " + tasks[taskCount - 1]); + System.out.println("Now you have " + taskCount + " tasks in the list."); System.out.println("____________________________________________________________"); - continue; + } else { + throw new DukeException("Invalid command"); } - String description = parts[0].substring(5).trim(); - String from = eventParts[0].trim(); - String to = eventParts[1].trim(); - tasks[taskCount] = new Event(description, from, to); - taskCount++; - System.out.println("Got it. I've added this task:"); - System.out.println(" " + tasks[taskCount - 1]); - System.out.println("Now you have " + taskCount + " tasks in the list."); + } catch (DukeException e) { + System.out.println(e.getMessage()); + System.out.println("____________________________________________________________"); + } catch (NumberFormatException e) { + System.out.println("Invalid task number. Please enter a valid number."); + System.out.println("____________________________________________________________"); + } catch (StringIndexOutOfBoundsException e) { + System.out.println("Sorry! The description of a todo can't be empty"); System.out.println("____________________________________________________________"); - continue; } - - System.out.println("Sorry, I don't understand that command."); - System.out.println("____________________________________________________________"); } scanner.close(); } From 66017ad54fcfed0c3baef27aa1f5344d3dc783d0 Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Thu, 7 Mar 2024 23:05:20 +0800 Subject: [PATCH 17/52] Cleaned up code From 4dda9966e7429a939706fbf40b3fd7a29db0ed16 Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Thu, 7 Mar 2024 23:08:00 +0800 Subject: [PATCH 18/52] Added comments and cleaned up code --- src/main/java/Task.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/Task.java b/src/main/java/Task.java index 8d8275dc7..68381c23a 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -23,7 +23,7 @@ public String getDescription() { return description; } - // Method to update the status icon based on task completion + // The method to update status icon based on task completion public void updateStatusIcon() { // If the task is done, mark it with [X], otherwise mark it with [ ] String statusIcon = (isDone ? "[X]" : "[ ]"); From a0f892a919f888d815741bb73f9ed3a3b6a3831b Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Fri, 8 Mar 2024 04:57:40 +0800 Subject: [PATCH 19/52] Update Duke.java --- src/main/java/Duke.java | 93 +++++++++++++++++++++++------------------ 1 file changed, 52 insertions(+), 41 deletions(-) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 2880091a5..921549860 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,11 +1,11 @@ +import java.util.ArrayList; +import java.util.List; import java.util.Scanner; public class Duke { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); - Task[] tasks = new Task[100]; - int taskCount = 0; - + List tasks = new ArrayList<>(); // Using ArrayList to store tasks System.out.println("____________________________________________________________"); System.out.println("Hello! I'm [Sparky]"); System.out.println("What can I do for you?"); @@ -21,54 +21,41 @@ public static void main(String[] args) { System.out.println("____________________________________________________________"); break; } else if (input.equalsIgnoreCase("list")) { - if (taskCount == 0) { + if (tasks.isEmpty()) { System.out.println("No tasks added yet."); } else { System.out.println("Here are the tasks in your list:"); - for (int i = 0; i < taskCount; i++) { - System.out.println((i + 1) + "." + tasks[i]); + for (int i = 0; i < tasks.size(); i++) { + System.out.println((i + 1) + "." + tasks.get(i)); } } System.out.println("____________________________________________________________"); - } else if (input.startsWith("mark")) { - String[] parts = input.split(" "); - if (parts.length != 2) { - throw new DukeException("Invalid command format. Usage: mark "); - } - int index = Integer.parseInt(parts[1]) - 1; - if (index < 0 || index >= taskCount) { - throw new DukeException("Invalid task number."); - } - tasks[index].markAsDone(); - System.out.println("Nice! I've marked this task as done:"); - System.out.println(" " + tasks[index].getStatusIcon() + " " + tasks[index].getDescription()); - System.out.println("____________________________________________________________"); - } else if (input.startsWith("unmark")) { + } else if (input.startsWith("delete")) { String[] parts = input.split(" "); if (parts.length != 2) { - throw new DukeException("Invalid command format. Usage: unmark "); + throw new DukeException("Invalid command format. Usage: delete "); } int index = Integer.parseInt(parts[1]) - 1; - if (index < 0 || index >= taskCount) { + if (index < 0 || index >= tasks.size()) { throw new DukeException("Invalid task number."); } - tasks[index].markAsUndone(); - System.out.println("OK, I've marked this task as not done yet:"); - System.out.println(" " + tasks[index].getStatusIcon() + " " + tasks[index].getDescription()); + Task removedTask = tasks.remove(index); + System.out.println("Noted. I've removed this task:"); + System.out.println(" " + removedTask); + System.out.println("Now you have " + tasks.size() + " tasks in the list."); System.out.println("____________________________________________________________"); } else if (input.startsWith("todo")) { String description = input.substring(5).trim(); if (description.isEmpty()) { throw new DukeException("Sorry! The description of a todo can't be empty"); } - tasks[taskCount] = new Todo(description); - taskCount++; + tasks.add(new Todo(description)); System.out.println("Got it. I've added this task:"); - System.out.println(" " + tasks[taskCount - 1]); - System.out.println("Now you have " + taskCount + " tasks in the list."); + System.out.println(" " + tasks.get(tasks.size() - 1)); + System.out.println("Now you have " + tasks.size() + " tasks in the list."); System.out.println("____________________________________________________________"); } else if (input.startsWith("deadline")) { - String[] parts = input.split("/by"); + String[] parts = input.split("/by", 2); if (parts.length != 2) { throw new DukeException("Invalid command format. Usage: deadline /by "); } @@ -77,32 +64,56 @@ public static void main(String[] args) { if (description.isEmpty() || by.isEmpty()) { throw new DukeException("OOPS!!! Both description and date cannot be empty."); } - tasks[taskCount] = new Deadline(description, by); - taskCount++; + tasks.add(new Deadline(description, by)); System.out.println("Got it. I've added this task:"); - System.out.println(" " + tasks[taskCount - 1]); - System.out.println("Now you have " + taskCount + " tasks in the list."); + System.out.println(" " + tasks.get(tasks.size() - 1)); + System.out.println("Now you have " + tasks.size() + " tasks in the list."); System.out.println("____________________________________________________________"); } else if (input.startsWith("event")) { - String[] parts = input.split("/from"); + String[] parts = input.split("/from", 2); if (parts.length != 2) { throw new DukeException("Invalid command format. Usage: event /from /to "); } - String[] eventParts = parts[1].split("/to"); + String description = parts[0].substring(5).trim(); + String[] eventParts = parts[1].split("/to", 2); if (eventParts.length != 2) { throw new DukeException("Invalid command format. Usage: event /from /to "); } - String description = parts[0].substring(5).trim(); String from = eventParts[0].trim(); String to = eventParts[1].trim(); if (description.isEmpty() || from.isEmpty() || to.isEmpty()) { throw new DukeException("OOPS!!! All fields (description, start, end) must be provided."); } - tasks[taskCount] = new Event(description, from, to); - taskCount++; + tasks.add(new Event(description, from, to)); System.out.println("Got it. I've added this task:"); - System.out.println(" " + tasks[taskCount - 1]); - System.out.println("Now you have " + taskCount + " tasks in the list."); + System.out.println(" " + tasks.get(tasks.size() - 1)); + System.out.println("Now you have " + tasks.size() + " tasks in the list."); + System.out.println("____________________________________________________________"); + } else if (input.startsWith("mark")) { + String[] parts = input.split(" "); + if (parts.length != 2) { + throw new DukeException("Invalid command format. Usage: mark "); + } + int index = Integer.parseInt(parts[1]) - 1; + if (index < 0 || index >= tasks.size()) { + throw new DukeException("Invalid task number."); + } + tasks.get(index).markAsDone(); + System.out.println("Nice! I've marked this task as done:"); + System.out.println(" " + tasks.get(index).getStatusIcon() + " " + tasks.get(index).getDescription()); + System.out.println("____________________________________________________________"); + } else if (input.startsWith("unmark")) { + String[] parts = input.split(" "); + if (parts.length != 2) { + throw new DukeException("Invalid command format. Usage: unmark "); + } + int index = Integer.parseInt(parts[1]) - 1; + if (index < 0 || index >= tasks.size()) { + throw new DukeException("Invalid task number."); + } + tasks.get(index).markAsUndone(); + System.out.println("OK, I've marked this task as not done yet:"); + System.out.println(" " + tasks.get(index).getStatusIcon() + " " + tasks.get(index).getDescription()); System.out.println("____________________________________________________________"); } else { throw new DukeException("Invalid command"); From 046ee298bfda92cb76941366ac791774a3bf359d Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Fri, 8 Mar 2024 16:27:15 +0800 Subject: [PATCH 20/52] Update Deadline.java --- src/main/java/Deadline.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/Deadline.java b/src/main/java/Deadline.java index f82998636..ead1c3f75 100644 --- a/src/main/java/Deadline.java +++ b/src/main/java/Deadline.java @@ -6,6 +6,16 @@ public Deadline(String description, String by) { this.by = by; } + public Deadline(String description, String by, boolean isDone) { + super(description, isDone); + this.by = by; + } + + @Override + public String toFileString() { + return "D | " + (isDone ? 1 : 0) + " | " + description + " | " + by; + } + @Override public String toString() { return "[D]" + getStatusIcon() + " " + description + " (by: " + by + ")"; From 4899624d43963b82bb950e5883843880c07d973f Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Fri, 8 Mar 2024 16:28:04 +0800 Subject: [PATCH 21/52] Update Duke.java --- src/main/java/Duke.java | 112 +++++++++++++++++++++++++--------------- 1 file changed, 71 insertions(+), 41 deletions(-) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 2880091a5..beb6ce59f 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,11 +1,24 @@ +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 Duke { + private static final String FILE_PATH = "./data/duke.txt"; + public static void main(String[] args) { - Scanner scanner = new Scanner(System.in); - Task[] tasks = new Task[100]; - int taskCount = 0; + List tasks = new ArrayList<>(); // Using ArrayList to store tasks + + // Load tasks from file + try { + tasks = Storage.loadTasksFromFile(FILE_PATH); + } catch (IOException e) { + System.out.println("Error loading tasks from file: " + e.getMessage()); + } + Scanner scanner = new Scanner(System.in); System.out.println("____________________________________________________________"); System.out.println("Hello! I'm [Sparky]"); System.out.println("What can I do for you?"); @@ -21,54 +34,41 @@ public static void main(String[] args) { System.out.println("____________________________________________________________"); break; } else if (input.equalsIgnoreCase("list")) { - if (taskCount == 0) { + if (tasks.isEmpty()) { System.out.println("No tasks added yet."); } else { System.out.println("Here are the tasks in your list:"); - for (int i = 0; i < taskCount; i++) { - System.out.println((i + 1) + "." + tasks[i]); + for (int i = 0; i < tasks.size(); i++) { + System.out.println((i + 1) + "." + tasks.get(i)); } } System.out.println("____________________________________________________________"); - } else if (input.startsWith("mark")) { + } else if (input.startsWith("delete")) { String[] parts = input.split(" "); if (parts.length != 2) { - throw new DukeException("Invalid command format. Usage: mark "); + throw new DukeException("Invalid command format. Usage: delete "); } int index = Integer.parseInt(parts[1]) - 1; - if (index < 0 || index >= taskCount) { + if (index < 0 || index >= tasks.size()) { throw new DukeException("Invalid task number."); } - tasks[index].markAsDone(); - System.out.println("Nice! I've marked this task as done:"); - System.out.println(" " + tasks[index].getStatusIcon() + " " + tasks[index].getDescription()); - System.out.println("____________________________________________________________"); - } else if (input.startsWith("unmark")) { - String[] parts = input.split(" "); - if (parts.length != 2) { - throw new DukeException("Invalid command format. Usage: unmark "); - } - int index = Integer.parseInt(parts[1]) - 1; - if (index < 0 || index >= taskCount) { - throw new DukeException("Invalid task number."); - } - tasks[index].markAsUndone(); - System.out.println("OK, I've marked this task as not done yet:"); - System.out.println(" " + tasks[index].getStatusIcon() + " " + tasks[index].getDescription()); + Task removedTask = tasks.remove(index); + System.out.println("Noted. I've removed this task:"); + System.out.println(" " + removedTask); + System.out.println("Now you have " + tasks.size() + " tasks in the list."); System.out.println("____________________________________________________________"); } else if (input.startsWith("todo")) { String description = input.substring(5).trim(); if (description.isEmpty()) { throw new DukeException("Sorry! The description of a todo can't be empty"); } - tasks[taskCount] = new Todo(description); - taskCount++; + tasks.add(new Todo(description)); System.out.println("Got it. I've added this task:"); - System.out.println(" " + tasks[taskCount - 1]); - System.out.println("Now you have " + taskCount + " tasks in the list."); + System.out.println(" " + tasks.get(tasks.size() - 1)); + System.out.println("Now you have " + tasks.size() + " tasks in the list."); System.out.println("____________________________________________________________"); } else if (input.startsWith("deadline")) { - String[] parts = input.split("/by"); + String[] parts = input.split("/by", 2); if (parts.length != 2) { throw new DukeException("Invalid command format. Usage: deadline /by "); } @@ -77,36 +77,64 @@ public static void main(String[] args) { if (description.isEmpty() || by.isEmpty()) { throw new DukeException("OOPS!!! Both description and date cannot be empty."); } - tasks[taskCount] = new Deadline(description, by); - taskCount++; + tasks.add(new Deadline(description, by)); System.out.println("Got it. I've added this task:"); - System.out.println(" " + tasks[taskCount - 1]); - System.out.println("Now you have " + taskCount + " tasks in the list."); + System.out.println(" " + tasks.get(tasks.size() - 1)); + System.out.println("Now you have " + tasks.size() + " tasks in the list."); System.out.println("____________________________________________________________"); } else if (input.startsWith("event")) { - String[] parts = input.split("/from"); + String[] parts = input.split("/from", 2); if (parts.length != 2) { throw new DukeException("Invalid command format. Usage: event /from /to "); } - String[] eventParts = parts[1].split("/to"); + String description = parts[0].substring(5).trim(); + String[] eventParts = parts[1].split("/to", 2); if (eventParts.length != 2) { throw new DukeException("Invalid command format. Usage: event /from /to "); } - String description = parts[0].substring(5).trim(); String from = eventParts[0].trim(); String to = eventParts[1].trim(); if (description.isEmpty() || from.isEmpty() || to.isEmpty()) { throw new DukeException("OOPS!!! All fields (description, start, end) must be provided."); } - tasks[taskCount] = new Event(description, from, to); - taskCount++; + tasks.add(new Event(description, from, to)); System.out.println("Got it. I've added this task:"); - System.out.println(" " + tasks[taskCount - 1]); - System.out.println("Now you have " + taskCount + " tasks in the list."); + System.out.println(" " + tasks.get(tasks.size() - 1)); + System.out.println("Now you have " + tasks.size() + " tasks in the list."); + System.out.println("____________________________________________________________"); + } else if (input.startsWith("mark")) { + String[] parts = input.split(" "); + if (parts.length != 2) { + throw new DukeException("Invalid command format. Usage: mark "); + } + int index = Integer.parseInt(parts[1]) - 1; + if (index < 0 || index >= tasks.size()) { + throw new DukeException("Invalid task number."); + } + tasks.get(index).markAsDone(); + System.out.println("Nice! I've marked this task as done:"); + System.out.println(" " + tasks.get(index)); + System.out.println("____________________________________________________________"); + } else if (input.startsWith("unmark")) { + String[] parts = input.split(" "); + if (parts.length != 2) { + throw new DukeException("Invalid command format. Usage: unmark "); + } + int index = Integer.parseInt(parts[1]) - 1; + if (index < 0 || index >= tasks.size()) { + throw new DukeException("Invalid task number."); + } + tasks.get(index).markAsUndone(); + System.out.println("OK, I've marked this task as not done yet:"); + System.out.println(" " + tasks.get(index)); System.out.println("____________________________________________________________"); } else { throw new DukeException("Invalid command"); } + + // Save tasks to file after each change + Storage.saveTasksToFile(tasks, FILE_PATH); + } catch (DukeException e) { System.out.println(e.getMessage()); System.out.println("____________________________________________________________"); @@ -116,6 +144,8 @@ public static void main(String[] args) { } catch (StringIndexOutOfBoundsException e) { System.out.println("Sorry! The description of a todo can't be empty"); System.out.println("____________________________________________________________"); + } catch (IOException e) { + System.out.println("Error saving tasks to file: " + e.getMessage()); } } scanner.close(); From 831607a63c36c459cf67bb2857167bcb5571902a Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Fri, 8 Mar 2024 16:28:35 +0800 Subject: [PATCH 22/52] Update DukeException.java From 6a719fded319b389f09e92c8717d590527b8a8e9 Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Fri, 8 Mar 2024 16:29:04 +0800 Subject: [PATCH 23/52] Update Event.java --- src/main/java/Event.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/Event.java b/src/main/java/Event.java index 4810084a2..b4c8277de 100644 --- a/src/main/java/Event.java +++ b/src/main/java/Event.java @@ -8,6 +8,17 @@ public Event(String description, String from, String to) { this.to = to; } + public Event(String description, String from, String to, boolean isDone) { + super(description, isDone); + this.from = from; + this.to = to; + } + + @Override + public String toFileString() { + return "E | " + (isDone ? 1 : 0) + " | " + description + " | " + from + " | " + to; + } + @Override public String toString() { return "[E]" + getStatusIcon() + " " + description + " (from: " + from + " to: " + to + ")"; From 4cb7259d7232b1d32f4d903ec839f83b85f7fb22 Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Fri, 8 Mar 2024 16:29:44 +0800 Subject: [PATCH 24/52] Create Storage.java --- src/main/java/Storage.java | 51 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 src/main/java/Storage.java diff --git a/src/main/java/Storage.java b/src/main/java/Storage.java new file mode 100644 index 000000000..a538c631f --- /dev/null +++ b/src/main/java/Storage.java @@ -0,0 +1,51 @@ +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 { + public static List loadTasksFromFile(String filePath) throws IOException { + List tasks = new ArrayList<>(); + File file = new File(filePath); + if (file.exists()) { + Scanner scanner = new Scanner(file); + while (scanner.hasNextLine()) { + String line = scanner.nextLine(); + String[] parts = line.split(" \\| "); + String type = parts[0]; + boolean isDone = parts[1].equals("1"); + String description = parts[2]; + switch (type) { + case "T": + tasks.add(new Todo(description, isDone)); + break; + case "D": + String by = parts[3]; + tasks.add(new Deadline(description, by, isDone)); + break; + case "E": + String from = parts[3]; + String to = parts[4]; + tasks.add(new Event(description, from, to, isDone)); + break; + default: + break; + } + } + scanner.close(); + } + return tasks; + } + + public static void saveTasksToFile(List tasks, String filePath) throws IOException { + File file = new File(filePath); + file.getParentFile().mkdirs(); // Create parent directories if they don't exist + FileWriter writer = new FileWriter(file); + for (Task task : tasks) { + writer.write(task.toFileString() + "\n"); + } + writer.close(); + } +} From dc91d0f7f31a347b00b0d190c5be7daa184265bd Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Fri, 8 Mar 2024 16:31:15 +0800 Subject: [PATCH 25/52] Update Task.java --- src/main/java/Task.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/main/java/Task.java b/src/main/java/Task.java index 68381c23a..1ed434737 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -1,4 +1,4 @@ -public class Task { +public abstract class Task { protected String description; protected boolean isDone; @@ -7,6 +7,11 @@ public Task(String description) { this.isDone = false; } + public Task(String description, boolean isDone) { + this.description = description; + this.isDone = isDone; + } + public String getStatusIcon() { return (isDone ? "[X]" : "[ ]"); // mark done task with X } @@ -23,7 +28,9 @@ public String getDescription() { return description; } - // The method to update status icon based on task completion + public abstract String toFileString(); + + // Method to update the status icon based on task completion public void updateStatusIcon() { // If the task is done, mark it with [X], otherwise mark it with [ ] String statusIcon = (isDone ? "[X]" : "[ ]"); From 73a83f2ff31c4a80d9475e294c8b3cbbaf85080b Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Fri, 8 Mar 2024 16:31:32 +0800 Subject: [PATCH 26/52] Update Todo.java --- src/main/java/Todo.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/Todo.java b/src/main/java/Todo.java index 876a001db..666179849 100644 --- a/src/main/java/Todo.java +++ b/src/main/java/Todo.java @@ -3,6 +3,15 @@ public Todo(String description) { super(description); } + public Todo(String description, boolean isDone) { + super(description, isDone); + } + + @Override + public String toFileString() { + return "T | " + (isDone ? 1 : 0) + " | " + description; + } + @Override public String toString() { return "[T]" + getStatusIcon() + " " + description; From c6dce329e9aa5817ff4553a8cc159574ebfddd5a Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Fri, 8 Mar 2024 21:50:03 +0800 Subject: [PATCH 27/52] Update Deadline.java From 13986cb39dbfd3fbb02f3edd6b0c86882f99ee7f Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Fri, 8 Mar 2024 21:50:37 +0800 Subject: [PATCH 28/52] Create Parser.java --- src/main/java/Parser.java | 44 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 src/main/java/Parser.java diff --git a/src/main/java/Parser.java b/src/main/java/Parser.java new file mode 100644 index 000000000..a8d5f3429 --- /dev/null +++ b/src/main/java/Parser.java @@ -0,0 +1,44 @@ +public class Parser { + public static String parseCommand(String input) throws DukeException { + input = input.trim(); + String[] parts = input.split(" ", 2); + String command = parts[0].toLowerCase(); + return command; + } + + public static String[] parseDetails(String input) throws DukeException { + input = input.trim(); + String[] parts = input.split(" ", 2); + if (parts.length < 2) { + throw new DukeException("Missing task description!"); + } + return parts; + } + + public static String[] parseDeadlineDetails(String input) throws DukeException { + String[] parts = input.split("/by", 2); + if (parts.length < 2) { + throw new DukeException("Invalid command format. Usage: deadline /by "); + } + String[] details = new String[2]; + details[0] = parts[0].substring(9).trim(); + details[1] = parts[1].trim(); + return details; + } + + public static String[] parseEventDetails(String input) throws DukeException { + String[] parts = input.split("/from", 2); + if (parts.length < 2) { + throw new DukeException("Invalid command format. Usage: event /from /to "); + } + String[] eventParts = parts[1].split("/to", 2); + if (eventParts.length < 2) { + throw new DukeException("Invalid command format. Usage: event /from /to "); + } + String[] details = new String[3]; + details[0] = parts[0].substring(5).trim(); + details[1] = eventParts[0].trim(); + details[2] = eventParts[1].trim(); + return details; + } +} From f16d54cd16567b734129508487dd7452eaa2fca3 Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Fri, 8 Mar 2024 21:51:18 +0800 Subject: [PATCH 29/52] Create Ui.java --- src/main/java/Ui.java | 56 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 src/main/java/Ui.java diff --git a/src/main/java/Ui.java b/src/main/java/Ui.java new file mode 100644 index 000000000..76f4e7ed0 --- /dev/null +++ b/src/main/java/Ui.java @@ -0,0 +1,56 @@ +import java.util.List; + +public class Ui { + public void showWelcomeMessage() { + System.out.println("____________________________________________________________"); + System.out.println("Hello! I'm [Sparky]"); + System.out.println("What can I do for you?"); + System.out.println("____________________________________________________________"); + } + + public void showGoodbyeMessage() { + System.out.println("Bye. Hope to see you again soooon!"); + System.out.println("____________________________________________________________"); + } + + public void showTasks(List tasks) { + if (tasks.isEmpty()) { + System.out.println("No tasks added yet."); + } else { + System.out.println("Here are the tasks in your list:"); + for (int i = 0; i < tasks.size(); i++) { + System.out.println((i + 1) + "." + tasks.get(i)); + } + } + showLine(); + } + + public void showError(String errorMessage) { + System.out.println(errorMessage); + showLine(); + } + + public void showTaskRemovedMessage(Task task, int remainingTasks) { + System.out.println("Noted. I've removed this task:\n" + task + "\nNow you have " + remainingTasks + " tasks in the list."); + showLine(); + } + + public void showTaskAddedMessage(Task task, int totalTasks) { + System.out.println("Got it. I've added this task:\n" + task + "\nNow you have " + totalTasks + " tasks in the list."); + showLine(); + } + + public void showTaskMarkedDoneMessage(Task task) { + System.out.println("Nice! I've marked this task as done:\n" + task); + showLine(); + } + + public void showTaskMarkedUndoneMessage(Task task) { + System.out.println("OK, I've marked this task as not done yet:\n" + task); + showLine(); + } + + public void showLine() { + System.out.println("____________________________________________________________"); + } +} From 593b34b8812897abf552c58b55be4151806febdf Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Fri, 8 Mar 2024 21:51:47 +0800 Subject: [PATCH 30/52] Create TaskList.java --- src/main/java/TaskList.java | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 src/main/java/TaskList.java diff --git a/src/main/java/TaskList.java b/src/main/java/TaskList.java new file mode 100644 index 000000000..55dcb85c9 --- /dev/null +++ b/src/main/java/TaskList.java @@ -0,0 +1,30 @@ +import java.util.ArrayList; +import java.util.List; + +public class TaskList { + private List tasks; + + public TaskList() { + this.tasks = new ArrayList<>(); + } + + public void addTask(Task task) { + tasks.add(task); + } + + public Task removeTask(int index) { + return tasks.remove(index); + } + + public Task getTask(int index) { + return tasks.get(index); + } + + public int size() { + return tasks.size(); + } + + public List getAllTasks() { + return tasks; + } +} From d9d8b08f22744e7a9c88f7ba7bc7f977dd0e9f36 Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Fri, 8 Mar 2024 21:52:29 +0800 Subject: [PATCH 31/52] Update Duke.java --- src/main/java/Duke.java | 190 ++++++++++++++-------------------------- 1 file changed, 64 insertions(+), 126 deletions(-) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index beb6ce59f..610e1df1d 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,153 +1,91 @@ -import java.io.File; -import java.io.FileWriter; import java.io.IOException; +import java.util.Scanner; import java.util.ArrayList; import java.util.List; -import java.util.Scanner; public class Duke { private static final String FILE_PATH = "./data/duke.txt"; + private static final Ui ui = new Ui(); + private static final TaskList tasks = new TaskList(); public static void main(String[] args) { - List tasks = new ArrayList<>(); // Using ArrayList to store tasks - // Load tasks from file try { - tasks = Storage.loadTasksFromFile(FILE_PATH); + Storage.loadTasksFromFile(FILE_PATH, tasks); } catch (IOException e) { - System.out.println("Error loading tasks from file: " + e.getMessage()); + ui.showError("Error loading tasks from file: " + e.getMessage()); } Scanner scanner = new Scanner(System.in); - System.out.println("____________________________________________________________"); - System.out.println("Hello! I'm [Sparky]"); - System.out.println("What can I do for you?"); - System.out.println("____________________________________________________________"); + ui.showWelcomeMessage(); while (true) { - String input = scanner.nextLine().trim(); - System.out.println("____________________________________________________________"); + String input = scanner.nextLine(); + ui.showLine(); try { - if (input.equalsIgnoreCase("bye")) { - System.out.println("Bye. Hope to see you again soooon!"); - System.out.println("____________________________________________________________"); - break; - } else if (input.equalsIgnoreCase("list")) { - if (tasks.isEmpty()) { - System.out.println("No tasks added yet."); - } else { - System.out.println("Here are the tasks in your list:"); - for (int i = 0; i < tasks.size(); i++) { - System.out.println((i + 1) + "." + tasks.get(i)); + String command = Parser.parseCommand(input); + switch (command) { + case "bye": + ui.showGoodbyeMessage(); + Storage.saveTasksToFile(tasks, FILE_PATH); + scanner.close(); + return; + case "list": + ui.showTasks(tasks.getAllTasks()); + break; + case "delete": + String[] deleteDetails = Parser.parseDetails(input); + int deleteIndex = Integer.parseInt(deleteDetails[1]) - 1; + if (deleteIndex < 0 || deleteIndex >= tasks.size()) { + throw new DukeException("Invalid task number."); + } + Task removedTask = tasks.removeTask(deleteIndex); + ui.showTaskRemovedMessage(removedTask, tasks.size()); + break; + case "todo": + String[] todoDetails = Parser.parseDetails(input); + tasks.addTask(new Todo(todoDetails[1])); + ui.showTaskAddedMessage(tasks.getTask(tasks.size() - 1), tasks.size()); + break; + case "deadline": + String[] deadlineDetails = Parser.parseDeadlineDetails(input); + tasks.addTask(new Deadline(deadlineDetails[0], deadlineDetails[1])); + ui.showTaskAddedMessage(tasks.getTask(tasks.size() - 1), tasks.size()); + break; + case "event": + String[] eventDetails = Parser.parseEventDetails(input); + tasks.addTask(new Event(eventDetails[0], eventDetails[1], eventDetails[2])); + ui.showTaskAddedMessage(tasks.getTask(tasks.size() - 1), tasks.size()); + break; + case "mark": + String[] markDetails = Parser.parseDetails(input); + int markIndex = Integer.parseInt(markDetails[1]) - 1; + if (markIndex < 0 || markIndex >= tasks.size()) { + throw new DukeException("Invalid task number."); } - } - System.out.println("____________________________________________________________"); - } else if (input.startsWith("delete")) { - String[] parts = input.split(" "); - if (parts.length != 2) { - throw new DukeException("Invalid command format. Usage: delete "); - } - int index = Integer.parseInt(parts[1]) - 1; - if (index < 0 || index >= tasks.size()) { - throw new DukeException("Invalid task number."); - } - Task removedTask = tasks.remove(index); - System.out.println("Noted. I've removed this task:"); - System.out.println(" " + removedTask); - System.out.println("Now you have " + tasks.size() + " tasks in the list."); - System.out.println("____________________________________________________________"); - } else if (input.startsWith("todo")) { - String description = input.substring(5).trim(); - if (description.isEmpty()) { - throw new DukeException("Sorry! The description of a todo can't be empty"); - } - tasks.add(new Todo(description)); - System.out.println("Got it. I've added this task:"); - System.out.println(" " + tasks.get(tasks.size() - 1)); - System.out.println("Now you have " + tasks.size() + " tasks in the list."); - System.out.println("____________________________________________________________"); - } else if (input.startsWith("deadline")) { - String[] parts = input.split("/by", 2); - if (parts.length != 2) { - throw new DukeException("Invalid command format. Usage: deadline /by "); - } - String description = parts[0].substring(9).trim(); - String by = parts[1].trim(); - if (description.isEmpty() || by.isEmpty()) { - throw new DukeException("OOPS!!! Both description and date cannot be empty."); - } - tasks.add(new Deadline(description, by)); - System.out.println("Got it. I've added this task:"); - System.out.println(" " + tasks.get(tasks.size() - 1)); - System.out.println("Now you have " + tasks.size() + " tasks in the list."); - System.out.println("____________________________________________________________"); - } else if (input.startsWith("event")) { - String[] parts = input.split("/from", 2); - if (parts.length != 2) { - throw new DukeException("Invalid command format. Usage: event /from /to "); - } - String description = parts[0].substring(5).trim(); - String[] eventParts = parts[1].split("/to", 2); - if (eventParts.length != 2) { - throw new DukeException("Invalid command format. Usage: event /from /to "); - } - String from = eventParts[0].trim(); - String to = eventParts[1].trim(); - if (description.isEmpty() || from.isEmpty() || to.isEmpty()) { - throw new DukeException("OOPS!!! All fields (description, start, end) must be provided."); - } - tasks.add(new Event(description, from, to)); - System.out.println("Got it. I've added this task:"); - System.out.println(" " + tasks.get(tasks.size() - 1)); - System.out.println("Now you have " + tasks.size() + " tasks in the list."); - System.out.println("____________________________________________________________"); - } else if (input.startsWith("mark")) { - String[] parts = input.split(" "); - if (parts.length != 2) { - throw new DukeException("Invalid command format. Usage: mark "); - } - int index = Integer.parseInt(parts[1]) - 1; - if (index < 0 || index >= tasks.size()) { - throw new DukeException("Invalid task number."); - } - tasks.get(index).markAsDone(); - System.out.println("Nice! I've marked this task as done:"); - System.out.println(" " + tasks.get(index)); - System.out.println("____________________________________________________________"); - } else if (input.startsWith("unmark")) { - String[] parts = input.split(" "); - if (parts.length != 2) { - throw new DukeException("Invalid command format. Usage: unmark "); - } - int index = Integer.parseInt(parts[1]) - 1; - if (index < 0 || index >= tasks.size()) { - throw new DukeException("Invalid task number."); - } - tasks.get(index).markAsUndone(); - System.out.println("OK, I've marked this task as not done yet:"); - System.out.println(" " + tasks.get(index)); - System.out.println("____________________________________________________________"); - } else { - throw new DukeException("Invalid command"); + tasks.getTask(markIndex).markAsDone(); + ui.showTaskMarkedDoneMessage(tasks.getTask(markIndex)); + break; + case "unmark": + String[] unmarkDetails = Parser.parseDetails(input); + int unmarkIndex = Integer.parseInt(unmarkDetails[1]) - 1; + if (unmarkIndex < 0 || unmarkIndex >= tasks.size()) { + throw new DukeException("Invalid task number."); + } + tasks.getTask(unmarkIndex).markAsUndone(); + ui.showTaskMarkedUndoneMessage(tasks.getTask(unmarkIndex)); + break; + default: + throw new DukeException("Invalid command"); } - - // Save tasks to file after each change - Storage.saveTasksToFile(tasks, FILE_PATH); - } catch (DukeException e) { - System.out.println(e.getMessage()); - System.out.println("____________________________________________________________"); + ui.showError(e.getMessage()); } catch (NumberFormatException e) { - System.out.println("Invalid task number. Please enter a valid number."); - System.out.println("____________________________________________________________"); - } catch (StringIndexOutOfBoundsException e) { - System.out.println("Sorry! The description of a todo can't be empty"); - System.out.println("____________________________________________________________"); + ui.showError("Invalid task number. Please enter a valid number."); } catch (IOException e) { - System.out.println("Error saving tasks to file: " + e.getMessage()); + ui.showError("Error saving tasks to file: " + e.getMessage()); } } - scanner.close(); } } From cb8b0e5586b74114c8e0285b6bf7013f82b4eb29 Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Fri, 8 Mar 2024 21:53:27 +0800 Subject: [PATCH 32/52] Update Event.java From 7297c72c7bdaa67136d1b85df27405e27b99f582 Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Fri, 8 Mar 2024 21:54:02 +0800 Subject: [PATCH 33/52] Update Storage.java --- src/main/java/Storage.java | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/main/java/Storage.java b/src/main/java/Storage.java index a538c631f..be476382f 100644 --- a/src/main/java/Storage.java +++ b/src/main/java/Storage.java @@ -1,16 +1,12 @@ 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 { - public static List loadTasksFromFile(String filePath) throws IOException { - List tasks = new ArrayList<>(); + public static void loadTasksFromFile(String filePath, TaskList taskList) throws IOException { File file = new File(filePath); if (file.exists()) { - Scanner scanner = new Scanner(file); + java.util.Scanner scanner = new java.util.Scanner(file); while (scanner.hasNextLine()) { String line = scanner.nextLine(); String[] parts = line.split(" \\| "); @@ -19,16 +15,16 @@ public static List loadTasksFromFile(String filePath) throws IOException { String description = parts[2]; switch (type) { case "T": - tasks.add(new Todo(description, isDone)); + taskList.addTask(new Todo(description, isDone)); break; case "D": String by = parts[3]; - tasks.add(new Deadline(description, by, isDone)); + taskList.addTask(new Deadline(description, by, isDone)); break; case "E": String from = parts[3]; String to = parts[4]; - tasks.add(new Event(description, from, to, isDone)); + taskList.addTask(new Event(description, from, to, isDone)); break; default: break; @@ -36,14 +32,13 @@ public static List loadTasksFromFile(String filePath) throws IOException { } scanner.close(); } - return tasks; } - public static void saveTasksToFile(List tasks, String filePath) throws IOException { + public static void saveTasksToFile(TaskList taskList, String filePath) throws IOException { File file = new File(filePath); file.getParentFile().mkdirs(); // Create parent directories if they don't exist FileWriter writer = new FileWriter(file); - for (Task task : tasks) { + for (Task task : taskList.getAllTasks()) { writer.write(task.toFileString() + "\n"); } writer.close(); From e829ff09468f1f8e7b99757bca902c69c837bbbf Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Fri, 8 Mar 2024 21:54:25 +0800 Subject: [PATCH 34/52] Update Task.java From d0f8ae51d9168ef669814f1576fdc26b15c7689f Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Fri, 8 Mar 2024 21:55:08 +0800 Subject: [PATCH 35/52] Update Todo.java From 63598e7cb251fcf5a4a8fd334dca7074dfb2767d Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Fri, 8 Mar 2024 23:09:30 +0800 Subject: [PATCH 36/52] Update Duke.java --- src/main/java/Duke.java | 151 ++++++++++++++++++++++++++++++++++------ 1 file changed, 128 insertions(+), 23 deletions(-) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 610e1df1d..f9b4ad944 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,17 +1,19 @@ +import java.io.File; +import java.io.FileWriter; import java.io.IOException; -import java.util.Scanner; import java.util.ArrayList; import java.util.List; +import java.util.Scanner; public class Duke { private static final String FILE_PATH = "./data/duke.txt"; private static final Ui ui = new Ui(); - private static final TaskList tasks = new TaskList(); + private static final List tasks = new ArrayList<>(); public static void main(String[] args) { // Load tasks from file try { - Storage.loadTasksFromFile(FILE_PATH, tasks); + loadTasksFromFile(FILE_PATH); } catch (IOException e) { ui.showError("Error loading tasks from file: " + e.getMessage()); } @@ -24,57 +26,71 @@ public static void main(String[] args) { ui.showLine(); try { - String command = Parser.parseCommand(input); + String command = parseCommand(input); switch (command) { case "bye": ui.showGoodbyeMessage(); - Storage.saveTasksToFile(tasks, FILE_PATH); + saveTasksToFile(FILE_PATH); scanner.close(); return; case "list": - ui.showTasks(tasks.getAllTasks()); + showTasks(tasks); break; case "delete": - String[] deleteDetails = Parser.parseDetails(input); + String[] deleteDetails = parseDetails(input); int deleteIndex = Integer.parseInt(deleteDetails[1]) - 1; if (deleteIndex < 0 || deleteIndex >= tasks.size()) { throw new DukeException("Invalid task number."); } - Task removedTask = tasks.removeTask(deleteIndex); + Task removedTask = tasks.remove(deleteIndex); ui.showTaskRemovedMessage(removedTask, tasks.size()); break; case "todo": - String[] todoDetails = Parser.parseDetails(input); - tasks.addTask(new Todo(todoDetails[1])); - ui.showTaskAddedMessage(tasks.getTask(tasks.size() - 1), tasks.size()); + String[] todoDetails = parseDetails(input); + if (todoDetails.length < 2 || todoDetails[1].isEmpty()) { + throw new DukeException("The description of a todo cannot be empty."); + } + tasks.add(new Todo(todoDetails[1])); + ui.showTaskAddedMessage(tasks.get(tasks.size() - 1), tasks.size()); break; case "deadline": - String[] deadlineDetails = Parser.parseDeadlineDetails(input); - tasks.addTask(new Deadline(deadlineDetails[0], deadlineDetails[1])); - ui.showTaskAddedMessage(tasks.getTask(tasks.size() - 1), tasks.size()); + String[] deadlineDetails = parseDeadlineDetails(input); + if (deadlineDetails.length < 2 || deadlineDetails[1].isEmpty()) { + throw new DukeException("The description and date of a deadline cannot be empty."); + } + tasks.add(new Deadline(deadlineDetails[0], deadlineDetails[1])); + ui.showTaskAddedMessage(tasks.get(tasks.size() - 1), tasks.size()); break; case "event": - String[] eventDetails = Parser.parseEventDetails(input); - tasks.addTask(new Event(eventDetails[0], eventDetails[1], eventDetails[2])); - ui.showTaskAddedMessage(tasks.getTask(tasks.size() - 1), tasks.size()); + String[] eventDetails = parseEventDetails(input); + if (eventDetails.length < 3 || eventDetails[1].isEmpty() || eventDetails[2].isEmpty()) { + throw new DukeException("The description, start, and end of an event cannot be empty."); + } + tasks.add(new Event(eventDetails[0], eventDetails[1], eventDetails[2])); + ui.showTaskAddedMessage(tasks.get(tasks.size() - 1), tasks.size()); break; case "mark": - String[] markDetails = Parser.parseDetails(input); + String[] markDetails = parseDetails(input); int markIndex = Integer.parseInt(markDetails[1]) - 1; if (markIndex < 0 || markIndex >= tasks.size()) { throw new DukeException("Invalid task number."); } - tasks.getTask(markIndex).markAsDone(); - ui.showTaskMarkedDoneMessage(tasks.getTask(markIndex)); + tasks.get(markIndex).markAsDone(); + ui.showTaskMarkedDoneMessage(tasks.get(markIndex)); break; case "unmark": - String[] unmarkDetails = Parser.parseDetails(input); + String[] unmarkDetails = parseDetails(input); int unmarkIndex = Integer.parseInt(unmarkDetails[1]) - 1; if (unmarkIndex < 0 || unmarkIndex >= tasks.size()) { throw new DukeException("Invalid task number."); } - tasks.getTask(unmarkIndex).markAsUndone(); - ui.showTaskMarkedUndoneMessage(tasks.getTask(unmarkIndex)); + tasks.get(unmarkIndex).markAsUndone(); + ui.showTaskMarkedUndoneMessage(tasks.get(unmarkIndex)); + break; + case "find": + String keyword = input.substring(5).trim(); + List matchingTasks = findTasksByKeyword(keyword); + ui.showMatchingTasks(matchingTasks); break; default: throw new DukeException("Invalid command"); @@ -88,4 +104,93 @@ public static void main(String[] args) { } } } + + private static void loadTasksFromFile(String filePath) throws IOException { + File file = new File(filePath); + if (file.exists()) { + Scanner scanner = new Scanner(file); + while (scanner.hasNextLine()) { + String line = scanner.nextLine(); + String[] parts = line.split(" \\| "); + String type = parts[0]; + boolean isDone = parts[1].equals("1"); + String description = parts[2]; + switch (type) { + case "T": + tasks.add(new Todo(description, isDone)); + break; + case "D": + String by = parts[3]; + tasks.add(new Deadline(description, by, isDone)); + break; + case "E": + String from = parts[3]; + String to = parts[4]; + tasks.add(new Event(description, from, to, isDone)); + break; + default: + break; + } + } + scanner.close(); + } + } + + private static void saveTasksToFile(String filePath) throws IOException { + File file = new File(filePath); + file.getParentFile().mkdirs(); // Create parent directories if they don't exist + FileWriter writer = new FileWriter(file); + for (Task task : tasks) { + writer.write(task.toFileString() + "\n"); + } + writer.close(); + } + + private static String parseCommand(String input) { + return input.split(" ")[0]; + } + + private static String[] parseDetails(String input) { + return input.split(" ", 2); + } + + private static String[] parseDeadlineDetails(String input) throws DukeException { + String[] parts = input.split(" /by ", 2); + if (parts.length != 2 || parts[1].isEmpty()) { + throw new DukeException("Invalid deadline command format. Usage: deadline [description] /by [date]"); + } + return parts; + } + + private static String[] parseEventDetails(String input) throws DukeException { + String[] parts = input.split(" /from ", 2); + if (parts.length != 2 || parts[1].indexOf(" /to ") == -1) { + throw new DukeException("Invalid event command format. Usage: event [description] /from [start] /to [end]"); + } + String from = parts[1].split(" /to ", 2)[0]; + String to = parts[1].split(" /to ", 2)[1]; + return new String[]{parts[0], from, to}; + } + + private static List findTasksByKeyword(String keyword) { + List matchingTasks = new ArrayList<>(); + for (Task task : tasks) { + if (task.getDescription().contains(keyword)) { + matchingTasks.add(task); + } + } + return matchingTasks; + } + + private static void showTasks(List tasks) { + if (tasks.isEmpty()) { + System.out.println("No tasks added yet."); + } else { + System.out.println("Here are the tasks in your list:"); + for (int i = 0; i < tasks.size(); i++) { + System.out.println((i + 1) + "." + tasks.get(i)); + } + } + ui.showLine(); + } } From 019d8d33ae0f2b8a58fb8e45066f2ec1c04807c8 Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Fri, 8 Mar 2024 23:10:17 +0800 Subject: [PATCH 37/52] Update Event.java From 8316d651cf4ccd57e0979454a1c3c6097b5a997d Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Fri, 8 Mar 2024 23:10:36 +0800 Subject: [PATCH 38/52] Update Parser.java From 23a45e3a4c80a9ce2ca4afe231d8391fa82bf105 Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Fri, 8 Mar 2024 23:10:52 +0800 Subject: [PATCH 39/52] Update Storage.java From 75644bdf261388c28e4d754996a2fe377f08abfa Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Fri, 8 Mar 2024 23:11:09 +0800 Subject: [PATCH 40/52] Update Task.java From 03cd94eca78d74d9bec8df9086246c8a3c4eea45 Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Fri, 8 Mar 2024 23:11:34 +0800 Subject: [PATCH 41/52] Update TaskList.java From b46870e166cf3bd0146c9279553fdb3d522cdd7a Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Fri, 8 Mar 2024 23:12:06 +0800 Subject: [PATCH 42/52] Update Ui.java --- src/main/java/Ui.java | 42 ++++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/src/main/java/Ui.java b/src/main/java/Ui.java index 76f4e7ed0..71737bb0c 100644 --- a/src/main/java/Ui.java +++ b/src/main/java/Ui.java @@ -22,35 +22,53 @@ public void showTasks(List tasks) { System.out.println((i + 1) + "." + tasks.get(i)); } } - showLine(); + System.out.println("____________________________________________________________"); } public void showError(String errorMessage) { System.out.println(errorMessage); - showLine(); + System.out.println("____________________________________________________________"); } - public void showTaskRemovedMessage(Task task, int remainingTasks) { - System.out.println("Noted. I've removed this task:\n" + task + "\nNow you have " + remainingTasks + " tasks in the list."); - showLine(); + public void showTaskRemovedMessage(Task removedTask, int numTasks) { + System.out.println("Noted. I've removed this task:"); + System.out.println(" " + removedTask); + System.out.println("Now you have " + numTasks + " tasks in the list."); + System.out.println("____________________________________________________________"); } - public void showTaskAddedMessage(Task task, int totalTasks) { - System.out.println("Got it. I've added this task:\n" + task + "\nNow you have " + totalTasks + " tasks in the list."); - showLine(); + public void showTaskAddedMessage(Task addedTask, int numTasks) { + System.out.println("Got it. I've added this task:"); + System.out.println(" " + addedTask); + System.out.println("Now you have " + numTasks + " tasks in the list."); + System.out.println("____________________________________________________________"); } public void showTaskMarkedDoneMessage(Task task) { - System.out.println("Nice! I've marked this task as done:\n" + task); - showLine(); + System.out.println("Nice! I've marked this task as done:"); + System.out.println(" " + task); + System.out.println("____________________________________________________________"); } public void showTaskMarkedUndoneMessage(Task task) { - System.out.println("OK, I've marked this task as not done yet:\n" + task); - showLine(); + System.out.println("OK, I've marked this task as not done yet:"); + System.out.println(" " + task); + System.out.println("____________________________________________________________"); } public void showLine() { System.out.println("____________________________________________________________"); } + + public void showMatchingTasks(List tasks) { + if (tasks.isEmpty()) { + System.out.println("No matching tasks found."); + } else { + System.out.println("Here are the matching tasks in your list:"); + for (int i = 0; i < tasks.size(); i++) { + System.out.println((i + 1) + "." + tasks.get(i)); + } + } + System.out.println("____________________________________________________________"); + } } From 3ae30587dfd4111f50976834ea22e722492aab2a Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Fri, 8 Mar 2024 23:24:13 +0800 Subject: [PATCH 43/52] Update Duke.java --- src/main/java/Duke.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index f9b4ad944..5b311a81e 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,3 +1,16 @@ +/** + * Represents a task management program that allows users to manage their tasks. + * + *

Users can add different types of tasks including todos, deadlines, and events. + * They can also mark tasks as done, delete tasks, and search for tasks by keyword. + * + * @param FILE_PATH the file path where tasks are stored + * @param ui the user interface for displaying messages + * @param tasks the list of tasks currently managed by the program + * + * @throws DukeException if there is an error in processing user commands + * @throws IOException if there is an error in loading or saving tasks from/to file + */ import java.io.File; import java.io.FileWriter; import java.io.IOException; From f9a9490cd9e593273ca94489f295cb11fa1727df Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Fri, 8 Mar 2024 23:28:13 +0800 Subject: [PATCH 44/52] Update Deadline.java --- src/main/java/Deadline.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/Deadline.java b/src/main/java/Deadline.java index ead1c3f75..c9c31ae44 100644 --- a/src/main/java/Deadline.java +++ b/src/main/java/Deadline.java @@ -1,3 +1,14 @@ +/** + * Represents a task with a deadline. + * + * Deadline object contains information about a task that has a deadline, + * including its description and the date by which it should be completed. + * + * @param description the description of the task + * @param by the deadline of the task + * @return a Deadline object representing the task with the specified description and deadline + * @throws DukeException if there is an error in processing the task + */ public class Deadline extends Task { protected String by; From 3d4826799b33df6a55633a793aca035367566d5f Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Fri, 8 Mar 2024 23:30:11 +0800 Subject: [PATCH 45/52] Update DukeException.java --- src/main/java/DukeException.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/DukeException.java b/src/main/java/DukeException.java index fe8837e3a..8560768a5 100644 --- a/src/main/java/DukeException.java +++ b/src/main/java/DukeException.java @@ -1,3 +1,14 @@ +/** + * Exception thrown when an error occurs in Duke application. + * + * DukeException is thrown to indicate that an error has occurred during the execution + * of the Duke application. It contains the error message that provides information about + * the nature of the error. + + * @param message the error message describing the cause of the exception + * @return a DukeException object with the specified error message + * @throws DukeException if there is an error while creating the DukeException object + */ public class DukeException extends Exception { public DukeException(String message) { super(message); From 2c9db56bc44131271d1ebbb1ba6cc1b97964e805 Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Fri, 8 Mar 2024 23:32:09 +0800 Subject: [PATCH 46/52] Update Event.java --- src/main/java/Event.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/main/java/Event.java b/src/main/java/Event.java index b4c8277de..d24fac571 100644 --- a/src/main/java/Event.java +++ b/src/main/java/Event.java @@ -1,3 +1,16 @@ +/** + * Represents an event task in Duke. + * + * An Event object has information about an event task, including its description, + * start date, end date, and completion status. It provides methods to access and manipulate + * these attributes. + * + * @param description the description of the event task + * @param from the start date/time of the event + * @param to the end date/time of the event + * @return an Event object with the specified description, start date, and end date + * @throws NullPointerException if the description, start date, or end date is null + */ public class Event extends Task { protected String from; protected String to; From e751e5cbc17b3af60aa0f95b7430b0a44f88be20 Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Fri, 8 Mar 2024 23:35:15 +0800 Subject: [PATCH 47/52] Update Parser.java --- src/main/java/Parser.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/Parser.java b/src/main/java/Parser.java index a8d5f3429..5ac145c34 100644 --- a/src/main/java/Parser.java +++ b/src/main/java/Parser.java @@ -1,3 +1,7 @@ +/** + * The Parser class is responsible for parsing user input into commands and task details. + * It provides methods to parse commands, task descriptions, deadline details, and event details. + */ public class Parser { public static String parseCommand(String input) throws DukeException { input = input.trim(); From 384810c6761b7507162b3cdae47183e0c18bacd7 Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Fri, 8 Mar 2024 23:36:55 +0800 Subject: [PATCH 48/52] Update Storage.java --- src/main/java/Storage.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/Storage.java b/src/main/java/Storage.java index be476382f..aadd7a03a 100644 --- a/src/main/java/Storage.java +++ b/src/main/java/Storage.java @@ -1,3 +1,7 @@ +/** + * The Storage class is responsible for loading tasks from a file and saving tasks to a file. + * It provides methods to load tasks from a file into a TaskList object and save tasks from a TaskList object to a file. + */ import java.io.File; import java.io.FileWriter; import java.io.IOException; From 5f8a7e1c03637aae954bc295dbe616f40ce0330d Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Fri, 8 Mar 2024 23:38:59 +0800 Subject: [PATCH 49/52] Update Task.java --- src/main/java/Task.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/Task.java b/src/main/java/Task.java index 1ed434737..3b1a5fcf7 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -1,3 +1,8 @@ +/** + * The Task class represents a task in the task list. + * It is an abstract class that provides common functionality for different types of tasks. + * Each task has a description and a status indicating whether it is done or not. + */ public abstract class Task { protected String description; protected boolean isDone; From a72e61d6782d21dbe01b95182af4e62f7d8a6077 Mon Sep 17 00:00:00 2001 From: haowern98 <111697767+haowern98@users.noreply.github.com> Date: Fri, 8 Mar 2024 23:57:11 +0800 Subject: [PATCH 50/52] Update README.md --- docs/README.md | 74 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 64 insertions(+), 10 deletions(-) diff --git a/docs/README.md b/docs/README.md index 8077118eb..cbe33da77 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,28 +2,82 @@ ## Features -### Feature-ABC +### Add Task -Description of the feature. +Add tasks to the task list. Tasks can be todos, deadlines, or events. -### Feature-XYZ +### Delete Task + +Delete tasks from the task list. + +### Mark Task as Done + +Mark tasks as done in the task list. + +### List Tasks +View the list of tasks in the task list. + +### Find Task + +Search for tasks containing a specific keyword in the task list. -Description of the feature. ## Usage -### `Keyword` - Describe action +### `todo ` - Add Todo Task + +Adds a todo task to the task list. + +Example of usage: + +`todo read book` + +Expected outcome: + +The todo task "read book" is added to the task list. + +``` +Got it. I've added this task: + [T][ ] read book +Now you have X tasks in the list. + +``` + +### `event /from /to ` - Add Event Task -Describe the action and its outcome. +Adds an event task to the task list with a start and end time. -Example of usage: +Example of usage: -`keyword (optional arguments)` +`event project meeting /from 2pm /to 4pm` Expected outcome: -Description of the outcome. +The event task "project meeting" with a start time of "2pm" and end time of "4pm" is added to the task list. + +``` +Got it. I've added this task: + [E][ ] project meeting (from: 2pm to: 4pm) +Now you have X tasks in the list. ``` -expected output + +### `deadline /by ` - Add Deadline Task + +Adds a deadline task to the task list with a due date. + +Example of usage: + +`deadline return book /by June 6th` + +Expected outcome: + +The deadline task "return book" with a due date of "June 6th" is added to the task list. + +``` +Got it. I've added this task: + [D][ ] return book (by: June 6th) +Now you have X tasks in the list. + + ``` From 9120e9c4050485f8008d011c4ab6a894e14f49a3 Mon Sep 17 00:00:00 2001 From: haowern98 Date: Mon, 18 May 2026 17:44:12 +0800 Subject: [PATCH 51/52] Revise user guide --- docs/{README.md => UserGuide.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/{README.md => UserGuide.md} (100%) diff --git a/docs/README.md b/docs/UserGuide.md similarity index 100% rename from docs/README.md rename to docs/UserGuide.md From 0fd0bbe212556d172bc7d4ecea196965022dc387 Mon Sep 17 00:00:00 2001 From: haowern98 Date: Mon, 18 May 2026 17:44:38 +0800 Subject: [PATCH 52/52] Rewrite user guide --- docs/UserGuide.md | 195 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 161 insertions(+), 34 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index cbe33da77..57eabe000 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -1,83 +1,210 @@ # User Guide -## Features +## Introduction -### Add Task +Sparky is a command-line task manager for tracking todos, deadlines, and events. You can add tasks, list them, mark them as done, remove them, and search for them by keyword. -Add tasks to the task list. Tasks can be todos, deadlines, or events. +## Quick Start -### Delete Task +1. Start the application. +2. Enter commands one at a time in the terminal. +3. Use `bye` to exit the program. -Delete tasks from the task list. +## Command Summary -### Mark Task as Done +- `todo `: Adds a todo task +- `deadline /by `: Adds a deadline task +- `event /from /to `: Adds an event task +- `list`: Shows all tasks +- `mark `: Marks a task as done +- `unmark `: Marks a task as not done +- `delete `: Deletes a task +- `find `: Finds tasks containing a keyword +- `bye`: Exits the program -Mark tasks as done in the task list. +## Features -### List Tasks -View the list of tasks in the task list. +### Adding a todo: `todo` -### Find Task - -Search for tasks containing a specific keyword in the task list. - - -## Usage +Adds a todo task to the task list. -### `todo ` - Add Todo Task +Format: -Adds a todo task to the task list. +`todo ` -Example of usage: +Example: `todo read book` Expected outcome: -The todo task "read book" is added to the task list. - -``` +```text Got it. I've added this task: [T][ ] read book Now you have X tasks in the list. +``` + +### Adding a deadline: `deadline` + +Adds a deadline task with a due date. +Format: + +`deadline /by ` + +Example: + +`deadline return book /by June 6th` + +Expected outcome: + +```text +Got it. I've added this task: + [D][ ] return book (by: June 6th) +Now you have X tasks in the list. ``` -### `event /from /to ` - Add Event Task +### Adding an event: `event` -Adds an event task to the task list with a start and end time. +Adds an event task with a start time and end time. -Example of usage: +Format: + +`event /from /to ` + +Example: `event project meeting /from 2pm /to 4pm` Expected outcome: -The event task "project meeting" with a start time of "2pm" and end time of "4pm" is added to the task list. - -``` +```text Got it. I've added this task: [E][ ] project meeting (from: 2pm to: 4pm) Now you have X tasks in the list. - ``` -### `deadline /by ` - Add Deadline Task +### Listing tasks: `list` -Adds a deadline task to the task list with a due date. +Shows the tasks currently stored in the list. -Example of usage: +Format: -`deadline return book /by June 6th` +`list` + +Example: + +`list` Expected outcome: -The deadline task "return book" with a due date of "June 6th" is added to the task list. +```text +Here are the tasks in your list: +1.[T][ ] read book +2.[D][ ] return book (by: June 6th) +3.[E][ ] project meeting (from: 2pm to: 4pm) +``` + +### Marking a task: `mark` +Marks a task as done. + +Format: + +`mark ` + +Example: + +`mark 2` + +Expected outcome: + +```text +Nice! I've marked this task as done: + [D][X] return book (by: June 6th) ``` -Got it. I've added this task: + +### Unmarking a task: `unmark` + +Marks a task as not done. + +Format: + +`unmark ` + +Example: + +`unmark 2` + +Expected outcome: + +```text +OK, I've marked this task as not done yet: [D][ ] return book (by: June 6th) +``` + +### Deleting a task: `delete` + +Removes a task from the list. + +Format: + +`delete ` + +Example: + +`delete 1` + +Expected outcome: + +```text +Noted. I've removed this task: + [T][ ] read book Now you have X tasks in the list. +``` +### Finding tasks: `find` +Finds tasks whose descriptions contain a given keyword. + +Format: + +`find ` + +Example: + +`find book` + +Expected outcome: + +```text +Here are the matching tasks in your list: +1.[T][ ] read book +2.[D][ ] return book (by: June 6th) ``` + +### Exiting the program: `bye` + +Exits the application. + +Format: + +`bye` + +Example: + +`bye` + +Expected outcome: + +```text +Bye. Hope to see you again soooon! +``` + +## Notes + +- Task numbering is 1-based. +- Tasks are loaded from and saved to `./data/duke.txt`. +- The task list is saved when the program exits with `bye`. +- `find` performs substring matching on task descriptions. +- `find` is case-sensitive because it matches the stored task text directly.