From 3174bce0d90e390ca7a047411b9f91bae3340dbe Mon Sep 17 00:00:00 2001 From: Lim Yuh Ching <e0726103@u.nus.edu> Date: Tue, 5 Sep 2023 20:32:30 +0800 Subject: [PATCH 01/20] Level 0. Rename, Greet, Exit --- src/main/java/Duke.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 5d313334c..3cf79732d 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,10 +1,12 @@ public class Duke { public static void main(String[] args) { - String logo = " ____ _ \n" - + "| _ \\ _ _| | _____ \n" - + "| | | | | | | |/ / _ \\\n" - + "| |_| | |_| | < __/\n" - + "|____/ \\__,_|_|\\_\\___|\n"; - System.out.println("Hello from\n" + logo); + String intro = "Hello! I'm Wenny!\n" + + "How may I help you?\n"; + System.out.println(intro); + + bye(); + } + public static void bye() { + System.out.println("Bye. Hope to see you again soon!"); } } From 3015c0c66abaa07acf1c910baf8cc70628f3bd08 Mon Sep 17 00:00:00 2001 From: Lim Yuh Ching <e0726103@u.nus.edu> Date: Tue, 5 Sep 2023 20:47:19 +0800 Subject: [PATCH 02/20] Level 1. Echo --- src/main/java/Duke.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 3cf79732d..1580d6dd4 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,12 +1,20 @@ +import java.util.Scanner; public class Duke { public static void main(String[] args) { String intro = "Hello! I'm Wenny!\n" + "How may I help you?\n"; System.out.println(intro); - - bye(); + while (true) { + Scanner scanner = new Scanner(System.in); + String userInput = scanner.nextLine(); + System.out.println(userInput); + if (userInput.equals("bye")) { + bye(); + } + } } public static void bye() { System.out.println("Bye. Hope to see you again soon!"); + System.exit(0); } } From f21bf134b9d9e6ddc462559bab3df1c91b589e92 Mon Sep 17 00:00:00 2001 From: Lim Yuh Ching <e0726103@u.nus.edu> Date: Tue, 5 Sep 2023 21:25:28 +0800 Subject: [PATCH 03/20] Renamed Duke. Added greetings. --- src/main/java/Duke.java | 8 +++++++- src/main/java/List.java | 25 +++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 src/main/java/List.java diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 1580d6dd4..edc326408 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,15 +1,20 @@ import java.util.Scanner; public class Duke { public static void main(String[] args) { + // Greetings String intro = "Hello! I'm Wenny!\n" + "How may I help you?\n"; System.out.println(intro); + List list = new List(); while (true) { Scanner scanner = new Scanner(System.in); String userInput = scanner.nextLine(); - System.out.println(userInput); if (userInput.equals("bye")) { bye(); + } else if (userInput.equals("list")) { + list.print_list(); + } else { + list.add_to_list(userInput); } } } @@ -17,4 +22,5 @@ public static void bye() { System.out.println("Bye. Hope to see you again soon!"); System.exit(0); } + } diff --git a/src/main/java/List.java b/src/main/java/List.java new file mode 100644 index 000000000..fa482158f --- /dev/null +++ b/src/main/java/List.java @@ -0,0 +1,25 @@ +public class List { + private String[] list; + private int counter; + + public List() { + this.list = new String[100]; + this.counter = 0; + } + + public void print_list() { + if (this.counter == 0) { + System.out.println("No Entry"); + return; + } + for (int i=0; i<this.counter; i++) { + System.out.println((i+1) + ". " + this.list[i]); + } + } + + public void add_to_list(String arg) { + this.list[this.counter] = arg; + this.counter++; + System.out.println("added: " + arg); + } +} From 46b895f34772ae0839484d5bbd5f717f60e4f172 Mon Sep 17 00:00:00 2001 From: Lim Yuh Ching <e0726103@u.nus.edu> Date: Wed, 6 Sep 2023 00:12:53 +0800 Subject: [PATCH 04/20] Renamed list as tasks. Added isDone flag and markAsDone, markAsUndone functions. --- src/main/java/Duke.java | 13 ++++++++++--- src/main/java/List.java | 25 ------------------------ src/main/java/Task.java | 43 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 28 deletions(-) delete mode 100644 src/main/java/List.java create mode 100644 src/main/java/Task.java diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index edc326408..44cc575b9 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -5,16 +5,23 @@ public static void main(String[] args) { String intro = "Hello! I'm Wenny!\n" + "How may I help you?\n"; System.out.println(intro); - List list = new List(); + Task tasks = new Task(); while (true) { Scanner scanner = new Scanner(System.in); String userInput = scanner.nextLine(); if (userInput.equals("bye")) { bye(); } else if (userInput.equals("list")) { - list.print_list(); + tasks.print_tasks(); } else { - list.add_to_list(userInput); + String[] substr = userInput.split("\\s+"); + if (substr[0].equals("mark")) { + tasks.markAsDone(Integer.parseInt(substr[1])); + } else if (substr[0].equals("unmark")) { + tasks.markAsUndone(Integer.parseInt(substr[1])); + } else { + tasks.add_to_tasks(userInput); + } } } } diff --git a/src/main/java/List.java b/src/main/java/List.java deleted file mode 100644 index fa482158f..000000000 --- a/src/main/java/List.java +++ /dev/null @@ -1,25 +0,0 @@ -public class List { - private String[] list; - private int counter; - - public List() { - this.list = new String[100]; - this.counter = 0; - } - - public void print_list() { - if (this.counter == 0) { - System.out.println("No Entry"); - return; - } - for (int i=0; i<this.counter; i++) { - System.out.println((i+1) + ". " + this.list[i]); - } - } - - public void add_to_list(String arg) { - this.list[this.counter] = arg; - this.counter++; - System.out.println("added: " + arg); - } -} diff --git a/src/main/java/Task.java b/src/main/java/Task.java new file mode 100644 index 000000000..2ab22e3de --- /dev/null +++ b/src/main/java/Task.java @@ -0,0 +1,43 @@ +public class Task { + private String[] tasks; + private int taskCount; + private boolean[] isDone; + public Task() { + this.tasks = new String[100]; + this.taskCount = 0; + this.isDone = new boolean[100]; // False by default + } + + public void print_tasks() { + if (this.taskCount == 0) { + System.out.println("No Entry"); + return; + } + for (int i = 0; i<this.taskCount; i++) { + System.out.print((i+1) + "."); + if (isDone[i]) { + System.out.print("[X] "); + } else { + System.out.print("[ ] "); + } + System.out.println(this.tasks[i]); + } + } + + public void add_to_tasks(String details) { + this.tasks[this.taskCount] = details; + this.taskCount++; + System.out.println("added: " + details); + } + public void markAsDone(int number) { + isDone[number-1] = true; + System.out.println("Nice! I've market this task as done:"); + System.out.println("[X] " + tasks[number-1]); + } + + public void markAsUndone(int number) { + isDone[number-1] = false; + System.out.println("Nice! I've market this task as not done yet:"); + System.out.println("[ ] " + tasks[number-1]); + } +} From bbc2effa6f923ab5548ed334d6792457138e10b0 Mon Sep 17 00:00:00 2001 From: Lim Yuh Ching <e0726103@u.nus.edu> Date: Thu, 7 Sep 2023 01:10:56 +0800 Subject: [PATCH 05/20] Add ToDos, Events, Deadlines ToDos, Events, Deadlines are created as a subclass of Task. Moved addToTask and printTask from Task class to Main program. --- src/main/java/Deadlines.java | 18 +++++++ src/main/java/Duke.java | 92 ++++++++++++++++++++++++++++++------ src/main/java/Events.java | 31 ++++++++++++ src/main/java/Task.java | 55 +++++++++------------ src/main/java/ToDos.java | 10 ++++ src/main/java/Type.java | 3 ++ 6 files changed, 161 insertions(+), 48 deletions(-) create mode 100644 src/main/java/Deadlines.java create mode 100644 src/main/java/Events.java create mode 100644 src/main/java/ToDos.java create mode 100644 src/main/java/Type.java diff --git a/src/main/java/Deadlines.java b/src/main/java/Deadlines.java new file mode 100644 index 000000000..d07873fdd --- /dev/null +++ b/src/main/java/Deadlines.java @@ -0,0 +1,18 @@ +public class Deadlines extends Task { + String by; + public Deadlines(String description, String by) { + super(description); + this.by = by; + } + public String getBy() { + return by; + } + public void setBy(String by) { + this.by = by; + } + public String toString() { + return "[D]" + super.toString() + " (by: " + by + ")"; + } + + +} diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 44cc575b9..b945a6b4d 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,27 +1,89 @@ import java.util.Scanner; public class Duke { + private static Task[] tasks = new Task[100]; + private static int taskCount = 0; + + public static void addToTasks(String description, Type type) { + switch (type) { + case TODO: + tasks[taskCount] = new ToDos(description); + break; + case DEADLINE: + int i = description.indexOf("/"); + String by = description.substring(i+4); + description = description.substring(0, i).trim(); + tasks[taskCount] = new Deadlines(description, by); + break; + case EVENT: + int j = description.indexOf("/"); + int k = description.indexOf("/", j+1); + String from = description.substring(j+6, k).trim(); + String to = description.substring(k+4); + description = description.substring(0, j).trim(); + tasks[taskCount] = new Events(description, from, to); + break; + } + taskCount++; + System.out.println("\tGot it. I've added this task:"); + System.out.println("\t" + tasks[taskCount-1]); + System.out.println("\tNow you have " + taskCount + " task(s) in the list."); + } + public static void printTasks() { + if (taskCount == 0) { + System.out.println("\tYou do not have any task in the list."); + return; + } + System.out.println("\tHere are the tasks in your list:"); + for (int i=0; i<taskCount; i++) { + System.out.print("\t"); + System.out.print(i+1 + "."); + System.out.println(tasks[i]); + } + } + public static void markAsDone(int number) { + tasks[number-1].setDone(true); + System.out.println("\tNice! I've marked this task as done:"); + System.out.println("\t" + tasks[number-1]); + } + public static void markAsUndone(int number) { + tasks[number-1].setDone(false); + System.out.println("\tNice! I've marked this task as not done yet:"); + System.out.println("\t" + tasks[number-1]); + } + public static void main(String[] args) { // Greetings - String intro = "Hello! I'm Wenny!\n" - + "How may I help you?\n"; + String intro = "~~~~~~~~~~~~~~~~~~~\n" + + "Hello! I'm Wenny!\n" + + "How may I help you?\n" + + "~~~~~~~~~~~~~~~~~~~"; System.out.println(intro); - Task tasks = new Task(); while (true) { Scanner scanner = new Scanner(System.in); String userInput = scanner.nextLine(); - if (userInput.equals("bye")) { + String[] substr = userInput.split("\\s+"); + switch (substr[0]) { + case "bye": bye(); - } else if (userInput.equals("list")) { - tasks.print_tasks(); - } else { - String[] substr = userInput.split("\\s+"); - if (substr[0].equals("mark")) { - tasks.markAsDone(Integer.parseInt(substr[1])); - } else if (substr[0].equals("unmark")) { - tasks.markAsUndone(Integer.parseInt(substr[1])); - } else { - tasks.add_to_tasks(userInput); - } + break; + case "list": + printTasks(); + break; + case "mark": + markAsDone(Integer.parseInt(substr[1])); + break; + case "unmark": + markAsUndone(Integer.parseInt(substr[1])); + break; + case "todo": + addToTasks(userInput.substring(5), Type.TODO); + break; + case "deadline": + addToTasks(userInput.substring(9), Type.DEADLINE); + break; + case "event": + addToTasks(userInput.substring(6), Type.EVENT); + break; } } } diff --git a/src/main/java/Events.java b/src/main/java/Events.java new file mode 100644 index 000000000..a6c20c8da --- /dev/null +++ b/src/main/java/Events.java @@ -0,0 +1,31 @@ +public class Events extends Task { + String from; + String to; + + public Events(String description, String from, String to) { + super(description); + setFrom(from); + setTo(to); + } + + public String getFrom() { + return from; + } + + public void setFrom(String from) { + this.from = from; + } + + public String getTo() { + return to; + } + + public void setTo(String to) { + this.to = to; + } + + public String toString() { + return "[E]" + super.toString() + " (from: " + from + ", to: " + to + ")"; + } +} + diff --git a/src/main/java/Task.java b/src/main/java/Task.java index 2ab22e3de..9c2a8716c 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -1,43 +1,32 @@ public class Task { - private String[] tasks; - private int taskCount; - private boolean[] isDone; - public Task() { - this.tasks = new String[100]; - this.taskCount = 0; - this.isDone = new boolean[100]; // False by default + private String description; + private boolean isDone; + public Task(String description) { + setDescription(description); + setDone(false); } - public void print_tasks() { - if (this.taskCount == 0) { - System.out.println("No Entry"); - return; - } - for (int i = 0; i<this.taskCount; i++) { - System.out.print((i+1) + "."); - if (isDone[i]) { - System.out.print("[X] "); - } else { - System.out.print("[ ] "); - } - System.out.println(this.tasks[i]); - } + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; } - public void add_to_tasks(String details) { - this.tasks[this.taskCount] = details; - this.taskCount++; - System.out.println("added: " + details); + public boolean isDone() { + return isDone; } - public void markAsDone(int number) { - isDone[number-1] = true; - System.out.println("Nice! I've market this task as done:"); - System.out.println("[X] " + tasks[number-1]); + + public void setDone(boolean done) { + isDone = done; } - public void markAsUndone(int number) { - isDone[number-1] = false; - System.out.println("Nice! I've market this task as not done yet:"); - System.out.println("[ ] " + tasks[number-1]); + public String toString() { + String temp = "[ ]"; + if (isDone) { + temp = "[X]"; + } + return temp + " " + description; } } diff --git a/src/main/java/ToDos.java b/src/main/java/ToDos.java new file mode 100644 index 000000000..7aac2e775 --- /dev/null +++ b/src/main/java/ToDos.java @@ -0,0 +1,10 @@ +public class ToDos extends Task { + + public ToDos(String description) { + super(description); + } + + public String toString() { + return "[T]" + super.toString(); + } +} diff --git a/src/main/java/Type.java b/src/main/java/Type.java new file mode 100644 index 000000000..39d0667be --- /dev/null +++ b/src/main/java/Type.java @@ -0,0 +1,3 @@ +public enum Type { + TODO, DEADLINE, EVENT +} From aa3631e6cd4e528c82d125bdcc299d5f508a25f7 Mon Sep 17 00:00:00 2001 From: Lim Yuh Ching <e0726103@u.nus.edu> Date: Wed, 13 Sep 2023 15:13:57 +0800 Subject: [PATCH 06/20] Make changes to various variable name --- src/main/java/Duke.java | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index b945a6b4d..2b3c965b5 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -9,17 +9,17 @@ public static void addToTasks(String description, Type type) { tasks[taskCount] = new ToDos(description); break; case DEADLINE: - int i = description.indexOf("/"); - String by = description.substring(i+4); - description = description.substring(0, i).trim(); + String[] deadlineTokens = description.split("/by"); + description = deadlineTokens[0].trim(); + String by = deadlineTokens[1].trim(); tasks[taskCount] = new Deadlines(description, by); break; case EVENT: - int j = description.indexOf("/"); - int k = description.indexOf("/", j+1); - String from = description.substring(j+6, k).trim(); - String to = description.substring(k+4); - description = description.substring(0, j).trim(); + String[] eventTokens = description.split("/from"); + description = eventTokens[0].trim(); + eventTokens = eventTokens[1].split("/to"); + String from = eventTokens[0].trim(); + String to = eventTokens[1].trim(); tasks[taskCount] = new Events(description, from, to); break; } @@ -64,7 +64,7 @@ public static void main(String[] args) { String[] substr = userInput.split("\\s+"); switch (substr[0]) { case "bye": - bye(); + printByeMessage(); break; case "list": printTasks(); @@ -84,10 +84,12 @@ public static void main(String[] args) { case "event": addToTasks(userInput.substring(6), Type.EVENT); break; + default: + System.out.println("\tInvalid input, please try again"); } } } - public static void bye() { + public static void printByeMessage() { System.out.println("Bye. Hope to see you again soon!"); System.exit(0); } From 2e8d61b993b9164318c618422d2e99bef2e6b156 Mon Sep 17 00:00:00 2001 From: Lim Yuh Ching <e0726103@u.nus.edu> Date: Sat, 30 Sep 2023 02:28:20 +0800 Subject: [PATCH 07/20] Add Exceptions --- src/main/java/Deadlines.java | 2 + src/main/java/Duke.java | 84 +++++++++++++++++++++++++----------- src/main/java/Events.java | 2 +- src/main/java/Task.java | 9 ++-- src/main/java/ToDos.java | 1 + 5 files changed, 67 insertions(+), 31 deletions(-) diff --git a/src/main/java/Deadlines.java b/src/main/java/Deadlines.java index d07873fdd..b0a6dbd51 100644 --- a/src/main/java/Deadlines.java +++ b/src/main/java/Deadlines.java @@ -10,6 +10,8 @@ public String getBy() { public void setBy(String by) { this.by = by; } + + @Override public String toString() { return "[D]" + super.toString() + " (by: " + by + ")"; } diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 2b3c965b5..8b996b10f 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,3 +1,4 @@ +import javax.sound.midi.SysexMessage; import java.util.Scanner; public class Duke { private static Task[] tasks = new Task[100]; @@ -9,19 +10,29 @@ public static void addToTasks(String description, Type type) { tasks[taskCount] = new ToDos(description); break; case DEADLINE: - String[] deadlineTokens = description.split("/by"); - description = deadlineTokens[0].trim(); - String by = deadlineTokens[1].trim(); - tasks[taskCount] = new Deadlines(description, by); - break; + try { + String[] deadlineTokens = description.split("/by"); + description = deadlineTokens[0].trim(); + String by = deadlineTokens[1].trim(); + tasks[taskCount] = new Deadlines(description, by); + break; + } catch (IndexOutOfBoundsException e) { + System.out.println("\t/by could not be found"); + return; + } case EVENT: - String[] eventTokens = description.split("/from"); - description = eventTokens[0].trim(); - eventTokens = eventTokens[1].split("/to"); - String from = eventTokens[0].trim(); - String to = eventTokens[1].trim(); - tasks[taskCount] = new Events(description, from, to); - break; + try { + String[] eventTokens = description.split("/from"); + description = eventTokens[0].trim(); + eventTokens = eventTokens[1].split("/to"); + String from = eventTokens[0].trim(); + String to = eventTokens[1].trim(); + tasks[taskCount] = new Events(description, from, to); + break; + } catch (IndexOutOfBoundsException e) { + System.out.println("\tBoth /from and /to are required"); + return; + } } taskCount++; System.out.println("\tGot it. I've added this task:"); @@ -41,14 +52,22 @@ public static void printTasks() { } } public static void markAsDone(int number) { - tasks[number-1].setDone(true); - System.out.println("\tNice! I've marked this task as done:"); - System.out.println("\t" + tasks[number-1]); + try { + tasks[number-1].setDone(true); + System.out.println("\tNice! I've marked this task as done:"); + System.out.println("\t" + tasks[number-1]); + } catch (NullPointerException e) { + System.out.println("\tOops! task " + number + " does not exist"); + } } public static void markAsUndone(int number) { - tasks[number-1].setDone(false); - System.out.println("\tNice! I've marked this task as not done yet:"); - System.out.println("\t" + tasks[number-1]); + try { + tasks[number - 1].setDone(false); + System.out.println("\tNice! I've marked this task as not done yet:"); + System.out.println("\t" + tasks[number - 1]); + } catch (NullPointerException e) { + System.out.println("\tOops! task " + number + " does not exist"); + } } public static void main(String[] args) { @@ -61,7 +80,7 @@ public static void main(String[] args) { while (true) { Scanner scanner = new Scanner(System.in); String userInput = scanner.nextLine(); - String[] substr = userInput.split("\\s+"); + String[] substr = userInput.split("\\s+", 2); switch (substr[0]) { case "bye": printByeMessage(); @@ -76,14 +95,29 @@ public static void main(String[] args) { markAsUndone(Integer.parseInt(substr[1])); break; case "todo": - addToTasks(userInput.substring(5), Type.TODO); - break; + try { + addToTasks(substr[1], Type.TODO); + break; + } catch (ArrayIndexOutOfBoundsException e) { + System.out.println("\tDescription of a todo cannot be empty"); + break; + } case "deadline": - addToTasks(userInput.substring(9), Type.DEADLINE); - break; + try { + addToTasks(substr[1], Type.DEADLINE); + break; + } catch (ArrayIndexOutOfBoundsException e) { + System.out.println("\tDescription of a deadline cannot be empty"); + break; + } case "event": - addToTasks(userInput.substring(6), Type.EVENT); - break; + try { + addToTasks(substr[1], Type.EVENT); + break; + } catch (ArrayIndexOutOfBoundsException e) { + System.out.println("\tDescription of a event cannot be empty"); + break; + } default: System.out.println("\tInvalid input, please try again"); } diff --git a/src/main/java/Events.java b/src/main/java/Events.java index a6c20c8da..61a153ce4 100644 --- a/src/main/java/Events.java +++ b/src/main/java/Events.java @@ -23,7 +23,7 @@ public String getTo() { public void setTo(String to) { this.to = to; } - + @Override public String toString() { return "[E]" + super.toString() + " (from: " + from + ", to: " + to + ")"; } diff --git a/src/main/java/Task.java b/src/main/java/Task.java index 9c2a8716c..d7b6f7c1f 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -22,11 +22,10 @@ public void setDone(boolean done) { isDone = done; } + private String getStatus() { + return isDone() ? "[X]" : "[ ]"; + } public String toString() { - String temp = "[ ]"; - if (isDone) { - temp = "[X]"; - } - return temp + " " + description; + return getStatus() + " " + description; } } diff --git a/src/main/java/ToDos.java b/src/main/java/ToDos.java index 7aac2e775..379202e57 100644 --- a/src/main/java/ToDos.java +++ b/src/main/java/ToDos.java @@ -4,6 +4,7 @@ public ToDos(String description) { super(description); } + @Override public String toString() { return "[T]" + super.toString(); } From 4f314bf1868b6730af810560c7d36d7099fddd6d Mon Sep 17 00:00:00 2001 From: Lim Yuh Ching <e0726103@u.nus.edu> Date: Sat, 30 Sep 2023 02:29:52 +0800 Subject: [PATCH 08/20] Revert "Add Exceptions" This reverts commit 2e8d61b993b9164318c618422d2e99bef2e6b156. --- src/main/java/Deadlines.java | 2 - src/main/java/Duke.java | 84 +++++++++++------------------------- src/main/java/Events.java | 2 +- src/main/java/Task.java | 9 ++-- src/main/java/ToDos.java | 1 - 5 files changed, 31 insertions(+), 67 deletions(-) diff --git a/src/main/java/Deadlines.java b/src/main/java/Deadlines.java index b0a6dbd51..d07873fdd 100644 --- a/src/main/java/Deadlines.java +++ b/src/main/java/Deadlines.java @@ -10,8 +10,6 @@ public String getBy() { public void setBy(String by) { this.by = by; } - - @Override public String toString() { return "[D]" + super.toString() + " (by: " + by + ")"; } diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 8b996b10f..2b3c965b5 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,4 +1,3 @@ -import javax.sound.midi.SysexMessage; import java.util.Scanner; public class Duke { private static Task[] tasks = new Task[100]; @@ -10,29 +9,19 @@ public static void addToTasks(String description, Type type) { tasks[taskCount] = new ToDos(description); break; case DEADLINE: - try { - String[] deadlineTokens = description.split("/by"); - description = deadlineTokens[0].trim(); - String by = deadlineTokens[1].trim(); - tasks[taskCount] = new Deadlines(description, by); - break; - } catch (IndexOutOfBoundsException e) { - System.out.println("\t/by could not be found"); - return; - } + String[] deadlineTokens = description.split("/by"); + description = deadlineTokens[0].trim(); + String by = deadlineTokens[1].trim(); + tasks[taskCount] = new Deadlines(description, by); + break; case EVENT: - try { - String[] eventTokens = description.split("/from"); - description = eventTokens[0].trim(); - eventTokens = eventTokens[1].split("/to"); - String from = eventTokens[0].trim(); - String to = eventTokens[1].trim(); - tasks[taskCount] = new Events(description, from, to); - break; - } catch (IndexOutOfBoundsException e) { - System.out.println("\tBoth /from and /to are required"); - return; - } + String[] eventTokens = description.split("/from"); + description = eventTokens[0].trim(); + eventTokens = eventTokens[1].split("/to"); + String from = eventTokens[0].trim(); + String to = eventTokens[1].trim(); + tasks[taskCount] = new Events(description, from, to); + break; } taskCount++; System.out.println("\tGot it. I've added this task:"); @@ -52,22 +41,14 @@ public static void printTasks() { } } public static void markAsDone(int number) { - try { - tasks[number-1].setDone(true); - System.out.println("\tNice! I've marked this task as done:"); - System.out.println("\t" + tasks[number-1]); - } catch (NullPointerException e) { - System.out.println("\tOops! task " + number + " does not exist"); - } + tasks[number-1].setDone(true); + System.out.println("\tNice! I've marked this task as done:"); + System.out.println("\t" + tasks[number-1]); } public static void markAsUndone(int number) { - try { - tasks[number - 1].setDone(false); - System.out.println("\tNice! I've marked this task as not done yet:"); - System.out.println("\t" + tasks[number - 1]); - } catch (NullPointerException e) { - System.out.println("\tOops! task " + number + " does not exist"); - } + tasks[number-1].setDone(false); + System.out.println("\tNice! I've marked this task as not done yet:"); + System.out.println("\t" + tasks[number-1]); } public static void main(String[] args) { @@ -80,7 +61,7 @@ public static void main(String[] args) { while (true) { Scanner scanner = new Scanner(System.in); String userInput = scanner.nextLine(); - String[] substr = userInput.split("\\s+", 2); + String[] substr = userInput.split("\\s+"); switch (substr[0]) { case "bye": printByeMessage(); @@ -95,29 +76,14 @@ public static void main(String[] args) { markAsUndone(Integer.parseInt(substr[1])); break; case "todo": - try { - addToTasks(substr[1], Type.TODO); - break; - } catch (ArrayIndexOutOfBoundsException e) { - System.out.println("\tDescription of a todo cannot be empty"); - break; - } + addToTasks(userInput.substring(5), Type.TODO); + break; case "deadline": - try { - addToTasks(substr[1], Type.DEADLINE); - break; - } catch (ArrayIndexOutOfBoundsException e) { - System.out.println("\tDescription of a deadline cannot be empty"); - break; - } + addToTasks(userInput.substring(9), Type.DEADLINE); + break; case "event": - try { - addToTasks(substr[1], Type.EVENT); - break; - } catch (ArrayIndexOutOfBoundsException e) { - System.out.println("\tDescription of a event cannot be empty"); - break; - } + addToTasks(userInput.substring(6), Type.EVENT); + break; default: System.out.println("\tInvalid input, please try again"); } diff --git a/src/main/java/Events.java b/src/main/java/Events.java index 61a153ce4..a6c20c8da 100644 --- a/src/main/java/Events.java +++ b/src/main/java/Events.java @@ -23,7 +23,7 @@ public String getTo() { public void setTo(String to) { this.to = to; } - @Override + public String toString() { return "[E]" + super.toString() + " (from: " + from + ", to: " + to + ")"; } diff --git a/src/main/java/Task.java b/src/main/java/Task.java index d7b6f7c1f..9c2a8716c 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -22,10 +22,11 @@ public void setDone(boolean done) { isDone = done; } - private String getStatus() { - return isDone() ? "[X]" : "[ ]"; - } public String toString() { - return getStatus() + " " + description; + String temp = "[ ]"; + if (isDone) { + temp = "[X]"; + } + return temp + " " + description; } } diff --git a/src/main/java/ToDos.java b/src/main/java/ToDos.java index 379202e57..7aac2e775 100644 --- a/src/main/java/ToDos.java +++ b/src/main/java/ToDos.java @@ -4,7 +4,6 @@ public ToDos(String description) { super(description); } - @Override public String toString() { return "[T]" + super.toString(); } From 226c2292a934e23e524f1dbccbe4f3b3e772853b Mon Sep 17 00:00:00 2001 From: Lim Yuh Ching <e0726103@u.nus.edu> Date: Sat, 30 Sep 2023 02:37:14 +0800 Subject: [PATCH 09/20] Handled exceptions --- src/main/java/Duke.java | 90 ++++++++++++++++++++++++++++------------- 1 file changed, 62 insertions(+), 28 deletions(-) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 2b3c965b5..a70583927 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,3 +1,4 @@ +import javax.sound.midi.SysexMessage; import java.util.Scanner; public class Duke { private static Task[] tasks = new Task[100]; @@ -9,19 +10,29 @@ public static void addToTasks(String description, Type type) { tasks[taskCount] = new ToDos(description); break; case DEADLINE: - String[] deadlineTokens = description.split("/by"); - description = deadlineTokens[0].trim(); - String by = deadlineTokens[1].trim(); - tasks[taskCount] = new Deadlines(description, by); - break; + try { + String[] deadlineTokens = description.split("/by"); + description = deadlineTokens[0].trim(); + String by = deadlineTokens[1].trim(); + tasks[taskCount] = new Deadlines(description, by); + break; + } catch (IndexOutOfBoundsException e) { + System.out.println("\t/by could not be found"); + return; + } case EVENT: - String[] eventTokens = description.split("/from"); - description = eventTokens[0].trim(); - eventTokens = eventTokens[1].split("/to"); - String from = eventTokens[0].trim(); - String to = eventTokens[1].trim(); - tasks[taskCount] = new Events(description, from, to); - break; + try { + String[] eventTokens = description.split("/from"); + description = eventTokens[0].trim(); + eventTokens = eventTokens[1].split("/to"); + String from = eventTokens[0].trim(); + String to = eventTokens[1].trim(); + tasks[taskCount] = new Events(description, from, to); + break; + } catch (IndexOutOfBoundsException e) { + System.out.println("\tBoth /from and /to are required"); + return; + } } taskCount++; System.out.println("\tGot it. I've added this task:"); @@ -41,27 +52,35 @@ public static void printTasks() { } } public static void markAsDone(int number) { - tasks[number-1].setDone(true); - System.out.println("\tNice! I've marked this task as done:"); - System.out.println("\t" + tasks[number-1]); + try { + tasks[number-1].setDone(true); + System.out.println("\tNice! I've marked this task as done:"); + System.out.println("\t" + tasks[number-1]); + } catch (NullPointerException e) { + System.out.println("\tOops! task " + number + " does not exist"); + } } public static void markAsUndone(int number) { - tasks[number-1].setDone(false); - System.out.println("\tNice! I've marked this task as not done yet:"); - System.out.println("\t" + tasks[number-1]); + try { + tasks[number - 1].setDone(false); + System.out.println("\tNice! I've marked this task as not done yet:"); + System.out.println("\t" + tasks[number - 1]); + } catch (NullPointerException e) { + System.out.println("\tOops! task " + number + " does not exist"); + } } public static void main(String[] args) { // Greetings String intro = "~~~~~~~~~~~~~~~~~~~\n" - + "Hello! I'm Wenny!\n" - + "How may I help you?\n" - + "~~~~~~~~~~~~~~~~~~~"; + + "Hello! I'm Wenny!\n" + + "How may I help you?\n" + + "~~~~~~~~~~~~~~~~~~~"; System.out.println(intro); while (true) { Scanner scanner = new Scanner(System.in); String userInput = scanner.nextLine(); - String[] substr = userInput.split("\\s+"); + String[] substr = userInput.split("\\s+", 2); switch (substr[0]) { case "bye": printByeMessage(); @@ -76,14 +95,29 @@ public static void main(String[] args) { markAsUndone(Integer.parseInt(substr[1])); break; case "todo": - addToTasks(userInput.substring(5), Type.TODO); - break; + try { + addToTasks(substr[1], Type.TODO); + break; + } catch (ArrayIndexOutOfBoundsException e) { + System.out.println("\tDescription of a todo cannot be empty"); + break; + } case "deadline": - addToTasks(userInput.substring(9), Type.DEADLINE); - break; + try { + addToTasks(substr[1], Type.DEADLINE); + break; + } catch (ArrayIndexOutOfBoundsException e) { + System.out.println("\tDescription of a deadline cannot be empty"); + break; + } case "event": - addToTasks(userInput.substring(6), Type.EVENT); - break; + try { + addToTasks(substr[1], Type.EVENT); + break; + } catch (ArrayIndexOutOfBoundsException e) { + System.out.println("\tDescription of a event cannot be empty"); + break; + } default: System.out.println("\tInvalid input, please try again"); } From 111b4d19a35204cc53bd1340b67467c9c24a3ada Mon Sep 17 00:00:00 2001 From: Lim Yuh Ching <e0726103@u.nus.edu> Date: Sat, 30 Sep 2023 03:17:39 +0800 Subject: [PATCH 10/20] Add support for deleting tasks from the list --- src/main/java/Duke.java | 44 ++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index a70583927..d1acc5fbd 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,20 +1,21 @@ import javax.sound.midi.SysexMessage; +import java.util.ArrayList; import java.util.Scanner; public class Duke { - private static Task[] tasks = new Task[100]; + private static ArrayList<Task> tasks = new ArrayList<>(); private static int taskCount = 0; public static void addToTasks(String description, Type type) { switch (type) { case TODO: - tasks[taskCount] = new ToDos(description); + tasks.add(new ToDos(description)); break; case DEADLINE: try { String[] deadlineTokens = description.split("/by"); description = deadlineTokens[0].trim(); String by = deadlineTokens[1].trim(); - tasks[taskCount] = new Deadlines(description, by); + tasks.add(new Deadlines(description, by)); break; } catch (IndexOutOfBoundsException e) { System.out.println("\t/by could not be found"); @@ -27,7 +28,7 @@ public static void addToTasks(String description, Type type) { eventTokens = eventTokens[1].split("/to"); String from = eventTokens[0].trim(); String to = eventTokens[1].trim(); - tasks[taskCount] = new Events(description, from, to); + tasks.add(new Events(description, from, to)); break; } catch (IndexOutOfBoundsException e) { System.out.println("\tBoth /from and /to are required"); @@ -36,7 +37,7 @@ public static void addToTasks(String description, Type type) { } taskCount++; System.out.println("\tGot it. I've added this task:"); - System.out.println("\t" + tasks[taskCount-1]); + System.out.println("\t" + tasks.get(taskCount-1)); System.out.println("\tNow you have " + taskCount + " task(s) in the list."); } public static void printTasks() { @@ -48,24 +49,36 @@ public static void printTasks() { for (int i=0; i<taskCount; i++) { System.out.print("\t"); System.out.print(i+1 + "."); - System.out.println(tasks[i]); + System.out.println(tasks.get(i)); } } public static void markAsDone(int number) { try { - tasks[number-1].setDone(true); + tasks.get(number-1).setDone(true); System.out.println("\tNice! I've marked this task as done:"); - System.out.println("\t" + tasks[number-1]); - } catch (NullPointerException e) { + System.out.println("\t" + tasks.get(number-1)); + } catch (NullPointerException | IndexOutOfBoundsException e) { System.out.println("\tOops! task " + number + " does not exist"); } } public static void markAsUndone(int number) { try { - tasks[number - 1].setDone(false); - System.out.println("\tNice! I've marked this task as not done yet:"); - System.out.println("\t" + tasks[number - 1]); - } catch (NullPointerException e) { + tasks.get(number-1).setDone(false); + System.out.println("\tNice! I've marked this task as undone:"); + System.out.println("\t" + tasks.get(number-1)); + } catch (NullPointerException | IndexOutOfBoundsException e) { + System.out.println("\tOops! task " + number + " does not exist"); + } + } + + public static void deleteTask(int number) { + try { + System.out.println("\tNoted. I've removed this task:"); + System.out.println("\t" + tasks.get(number-1)); + tasks.remove(number-1); + taskCount--; + System.out.println("\tNow you have " + taskCount + " task(s) in the list."); + } catch (NullPointerException | IndexOutOfBoundsException e) { System.out.println("\tOops! task " + number + " does not exist"); } } @@ -118,13 +131,16 @@ public static void main(String[] args) { System.out.println("\tDescription of a event cannot be empty"); break; } + case "delete": + deleteTask(Integer.parseInt(substr[1])); + break; default: System.out.println("\tInvalid input, please try again"); } } } public static void printByeMessage() { - System.out.println("Bye. Hope to see you again soon!"); + System.out.println("\tBye. Hope to see you again soon!"); System.exit(0); } From 798021e5d18aa7be2371d5deef51ef5342c52887 Mon Sep 17 00:00:00 2001 From: Lim Yuh Ching <e0726103@u.nus.edu> Date: Tue, 3 Oct 2023 19:29:45 +0800 Subject: [PATCH 11/20] Add DataManager to save tasks to a text file --- src/main/java/DataManager.java | 96 ++++++++++++++++++++++++++++++++++ src/main/java/Deadlines.java | 8 ++- src/main/java/Duke.java | 46 ++++++++++------ src/main/java/Events.java | 7 +++ src/main/java/Task.java | 4 ++ src/main/java/ToDos.java | 5 ++ 6 files changed, 148 insertions(+), 18 deletions(-) create mode 100644 src/main/java/DataManager.java diff --git a/src/main/java/DataManager.java b/src/main/java/DataManager.java new file mode 100644 index 000000000..72937f452 --- /dev/null +++ b/src/main/java/DataManager.java @@ -0,0 +1,96 @@ +import com.sun.source.tree.AnnotationTree; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.Scanner; +public class DataManager { + private String filePath; + + public DataManager(String filePath) { + this.filePath = filePath; + } + + public ArrayList<Task> loadData(){ + ArrayList<Task> allTasks = new ArrayList<Task>(); + try { + File f = new File(filePath); + Scanner s = new Scanner(f); + while (s.hasNext()) { + String line = s.nextLine(); + String[] lineTokens = line.split("\\|", 3); + String taskType = lineTokens[0].trim(); + String completionStatus = lineTokens[1].trim(); + String description = lineTokens[2].trim(); + switch (taskType) { + case "T": + ToDos todo = new ToDos(description); + allTasks.add(todo); + if (completionStatus.equals("1")) { + todo.setDone(true); + } + break; + case "D": + String[] deadlineTokens = description.split("\\|"); + description = deadlineTokens[0].trim(); + String by = deadlineTokens[1].trim(); + Deadlines deadline = new Deadlines(description, by); + allTasks.add(deadline); + if (completionStatus.equals("1")) { + deadline.setDone(true); + } + break; + case "E": + String[] eventTokens = description.split("\\|"); + description = eventTokens[0].trim(); + String from = eventTokens[1].trim(); + String to = eventTokens[2].trim(); + Events event = new Events(description, from, to); + allTasks.add(event); + if (completionStatus.equals("1")) { + event.setDone(true); + } + break; + default: + System.out.println("\tUnknown task encountered. Skipping"); + break; + } + } + } catch (FileNotFoundException | ArrayIndexOutOfBoundsException e) { + System.out.println("\tFailed to read line"); + } + return allTasks; + } + + public void save(ArrayList<Task> tasks) { + try { + createFile(); + FileWriter fw = new FileWriter(filePath); + for (Task task : tasks) { + fw.write(task.toSave() + "\n"); + } + fw.close(); + } catch (IOException e) { + System.out.println("An error has occurred while saving"); + } + } + + public void createFile() { + try { + File f = new File(filePath); + if (f.exists()) { + return; + } + if (!f.getParentFile().exists()) { + f.getParentFile().mkdirs(); + } + f.createNewFile(); + } catch (IOException e) { + System.out.println("Cannot create file; reason: " + e.getMessage()); + } + } +} \ No newline at end of file diff --git a/src/main/java/Deadlines.java b/src/main/java/Deadlines.java index d07873fdd..cd29e0e85 100644 --- a/src/main/java/Deadlines.java +++ b/src/main/java/Deadlines.java @@ -10,9 +10,15 @@ public String getBy() { public void setBy(String by) { this.by = by; } + + @Override public String toString() { return "[D]" + super.toString() + " (by: " + by + ")"; } - + @Override + public String toSave() { + return "D | " + (this.isDone() ? "1" : "0") + " | " + this.getDescription() + + " | " + this.getBy(); + } } diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index a70583927..7bfff9c5f 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,20 +1,23 @@ -import javax.sound.midi.SysexMessage; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; import java.util.Scanner; +import java.io.File; public class Duke { - private static Task[] tasks = new Task[100]; - private static int taskCount = 0; + private static ArrayList<Task> tasks = new ArrayList<Task>(); public static void addToTasks(String description, Type type) { switch (type) { case TODO: - tasks[taskCount] = new ToDos(description); + tasks.add(new ToDos(description)); break; case DEADLINE: try { String[] deadlineTokens = description.split("/by"); description = deadlineTokens[0].trim(); String by = deadlineTokens[1].trim(); - tasks[taskCount] = new Deadlines(description, by); + tasks.add(new Deadlines(description, by)); break; } catch (IndexOutOfBoundsException e) { System.out.println("\t/by could not be found"); @@ -27,49 +30,50 @@ public static void addToTasks(String description, Type type) { eventTokens = eventTokens[1].split("/to"); String from = eventTokens[0].trim(); String to = eventTokens[1].trim(); - tasks[taskCount] = new Events(description, from, to); + tasks.add(new Events(description, from, to)); break; } catch (IndexOutOfBoundsException e) { System.out.println("\tBoth /from and /to are required"); return; } } - taskCount++; System.out.println("\tGot it. I've added this task:"); - System.out.println("\t" + tasks[taskCount-1]); - System.out.println("\tNow you have " + taskCount + " task(s) in the list."); + System.out.println("\t" + tasks.get(tasks.size()-1)); + System.out.println("\tNow you have " + tasks.size() + " task(s) in the list."); + //Append to file } public static void printTasks() { - if (taskCount == 0) { + if (tasks.isEmpty()) { System.out.println("\tYou do not have any task in the list."); return; } System.out.println("\tHere are the tasks in your list:"); - for (int i=0; i<taskCount; i++) { + for (int i=0; i<tasks.size(); i++) { System.out.print("\t"); System.out.print(i+1 + "."); - System.out.println(tasks[i]); + System.out.println(tasks.get(i)); } } public static void markAsDone(int number) { try { - tasks[number-1].setDone(true); + tasks.get(number - 1).setDone(true); System.out.println("\tNice! I've marked this task as done:"); - System.out.println("\t" + tasks[number-1]); + System.out.println("\t" + tasks.get(number - 1)); } catch (NullPointerException e) { System.out.println("\tOops! task " + number + " does not exist"); } } public static void markAsUndone(int number) { try { - tasks[number - 1].setDone(false); + tasks.get(number - 1).setDone(false); System.out.println("\tNice! I've marked this task as not done yet:"); - System.out.println("\t" + tasks[number - 1]); + System.out.println("\t" + tasks.get(number - 1)); } catch (NullPointerException e) { System.out.println("\tOops! task " + number + " does not exist"); } } + public static void main(String[] args) { // Greetings String intro = "~~~~~~~~~~~~~~~~~~~\n" @@ -77,6 +81,9 @@ public static void main(String[] args) { + "How may I help you?\n" + "~~~~~~~~~~~~~~~~~~~"; System.out.println(intro); + DataManager dataManager = new DataManager("./data/data.txt"); + tasks = dataManager.loadData(); + while (true) { Scanner scanner = new Scanner(System.in); String userInput = scanner.nextLine(); @@ -90,13 +97,16 @@ public static void main(String[] args) { break; case "mark": markAsDone(Integer.parseInt(substr[1])); + dataManager.save(tasks); break; case "unmark": markAsUndone(Integer.parseInt(substr[1])); + dataManager.save(tasks); break; case "todo": try { addToTasks(substr[1], Type.TODO); + dataManager.save(tasks); break; } catch (ArrayIndexOutOfBoundsException e) { System.out.println("\tDescription of a todo cannot be empty"); @@ -105,6 +115,7 @@ public static void main(String[] args) { case "deadline": try { addToTasks(substr[1], Type.DEADLINE); + dataManager.save(tasks); break; } catch (ArrayIndexOutOfBoundsException e) { System.out.println("\tDescription of a deadline cannot be empty"); @@ -113,6 +124,7 @@ public static void main(String[] args) { case "event": try { addToTasks(substr[1], Type.EVENT); + dataManager.save(tasks); break; } catch (ArrayIndexOutOfBoundsException e) { System.out.println("\tDescription of a event cannot be empty"); @@ -124,7 +136,7 @@ public static void main(String[] args) { } } public static void printByeMessage() { - System.out.println("Bye. Hope to see you again soon!"); + System.out.println("\tBye. Hope to see you again soon!"); System.exit(0); } diff --git a/src/main/java/Events.java b/src/main/java/Events.java index a6c20c8da..c1ed504a4 100644 --- a/src/main/java/Events.java +++ b/src/main/java/Events.java @@ -24,8 +24,15 @@ public void setTo(String to) { this.to = to; } + @Override public String toString() { return "[E]" + super.toString() + " (from: " + from + ", to: " + to + ")"; } + + @Override + public String toSave() { + return "E | " + (this.isDone() ? "1" : "0") + " | " + this.getDescription() + + " | " + this.getFrom() + " | " + this.getTo(); + } } diff --git a/src/main/java/Task.java b/src/main/java/Task.java index 9c2a8716c..ff4cdd94e 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -29,4 +29,8 @@ public String toString() { } return temp + " " + description; } + + public String toSave() { + return null; + } } diff --git a/src/main/java/ToDos.java b/src/main/java/ToDos.java index 7aac2e775..f070b3545 100644 --- a/src/main/java/ToDos.java +++ b/src/main/java/ToDos.java @@ -7,4 +7,9 @@ public ToDos(String description) { public String toString() { return "[T]" + super.toString(); } + + @Override + public String toSave() { + return "T | " + (this.isDone() ? "1" : "0") + " | " + this.getDescription(); + } } From 7beac69d24604af8fae512a84070cdb5e2d12bc9 Mon Sep 17 00:00:00 2001 From: Lim Yuh Ching <e0726103@u.nus.edu> Date: Wed, 4 Oct 2023 14:00:39 +0800 Subject: [PATCH 12/20] Divide code into smaller objects Create TaskList, Parser, Ui and Storage to split the code in Duke into different objects --- src/main/java/Command.java | 86 +++++++++ .../java/{Deadlines.java => Deadline.java} | 4 +- src/main/java/Duke.java | 167 +++--------------- src/main/java/DukeException.java | 12 ++ src/main/java/{Events.java => Event.java} | 4 +- src/main/java/META-INF/MANIFEST.MF | 3 + src/main/java/Parser.java | 15 ++ .../java/{DataManager.java => Storage.java} | 31 ++-- src/main/java/TaskList.java | 89 ++++++++++ src/main/java/{ToDos.java => ToDo.java} | 4 +- src/main/java/Ui.java | 89 ++++++++++ 11 files changed, 342 insertions(+), 162 deletions(-) create mode 100644 src/main/java/Command.java rename src/main/java/{Deadlines.java => Deadline.java} (83%) create mode 100644 src/main/java/DukeException.java rename src/main/java/{Events.java => Event.java} (87%) create mode 100644 src/main/java/META-INF/MANIFEST.MF create mode 100644 src/main/java/Parser.java rename src/main/java/{DataManager.java => Storage.java} (75%) create mode 100644 src/main/java/TaskList.java rename src/main/java/{ToDos.java => ToDo.java} (77%) create mode 100644 src/main/java/Ui.java diff --git a/src/main/java/Command.java b/src/main/java/Command.java new file mode 100644 index 000000000..50c99ea19 --- /dev/null +++ b/src/main/java/Command.java @@ -0,0 +1,86 @@ +public class Command { + + private String command; + private String arg; + private boolean isExit; + public Command(String command, String arg) { + this.command = command; + this.arg = arg; + this.isExit = false; + } + + public void setExit(boolean exit) { + isExit = exit; + } + + public boolean isExit() { + return isExit; + } + public void execute(TaskList taskList, Ui ui, Storage storage) throws DukeException{ + switch(this.command) { + case "bye": + setExit(true); + ui.showByeMessage(); + break; + case "list": + ui.showTasks(taskList); + break; + case "mark": + try { + taskList.markTask(this.arg, true); + storage.save(taskList); + ui.showMark(taskList, this.arg, true); + } catch (DukeException e) { + ui.showError(e); + } + break; + case "unmark": + try { + taskList.markTask(this.arg, false); + storage.save(taskList); + ui.showMark(taskList, this.arg, false); + } catch (DukeException e) { + ui.showError(e); + } + break; + case "todo": + try { + taskList.addTodo(this.arg); + storage.save(taskList); + ui.showAddTask(taskList); + } catch (DukeException e) { + ui.showError(e); + } + break; + case "deadline": + try { + taskList.addDeadline(this.arg); + storage.save(taskList); + ui.showAddTask(taskList); + } catch (DukeException e) { + ui.showError(e); + } + break; + case "event": + try { + taskList.addEvent(this.arg); + storage.save(taskList); + ui.showAddTask(taskList); + } catch (DukeException e) { + ui.showError(e); + } + break; + case "delete": + try { + Task removedTask = taskList.deleteTask(taskList, this.arg); + storage.save(taskList); + ui.showDeleteTask(taskList, removedTask); + } catch (DukeException e) { + ui.showError(e); + } + break; + default: + throw new DukeException("Invalid input, please try again"); + } + } +} diff --git a/src/main/java/Deadlines.java b/src/main/java/Deadline.java similarity index 83% rename from src/main/java/Deadlines.java rename to src/main/java/Deadline.java index cd29e0e85..060990d6d 100644 --- a/src/main/java/Deadlines.java +++ b/src/main/java/Deadline.java @@ -1,6 +1,6 @@ -public class Deadlines extends Task { +public class Deadline extends Task { String by; - public Deadlines(String description, String by) { + public Deadline(String description, String by) { super(description); this.by = by; } diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index f69cb3a05..1435577aa 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,154 +1,41 @@ import java.util.ArrayList; import java.util.Scanner; -import java.io.File; + public class Duke { - private static ArrayList<Task> tasks = new ArrayList<Task>(); - public static void addToTasks(String description, Type type) { - switch (type) { - case TODO: - tasks.add(new ToDos(description)); - break; - case DEADLINE: - try { - String[] deadlineTokens = description.split("/by"); - description = deadlineTokens[0].trim(); - String by = deadlineTokens[1].trim(); - tasks.add(new Deadlines(description, by)); - break; - } catch (IndexOutOfBoundsException e) { - System.out.println("\t/by could not be found"); - return; - } - case EVENT: - try { - String[] eventTokens = description.split("/from"); - description = eventTokens[0].trim(); - eventTokens = eventTokens[1].split("/to"); - String from = eventTokens[0].trim(); - String to = eventTokens[1].trim(); - tasks.add(new Events(description, from, to)); - break; - } catch (IndexOutOfBoundsException e) { - System.out.println("\tBoth /from and /to are required"); - return; - } - } - System.out.println("\tGot it. I've added this task:"); - System.out.println("\t" + tasks.get(tasks.size()-1)); - System.out.println("\tNow you have " + tasks.size() + " task(s) in the list."); + private Storage storage; + private TaskList taskList; + private Ui ui; - } - public static void printTasks() { - if (tasks.isEmpty()) { - System.out.println("\tYou do not have any task in the list."); - return; - } - System.out.println("\tHere are the tasks in your list:"); - for (int i=0; i<tasks.size(); i++) { - System.out.print("\t"); - System.out.print(i+1 + "."); - System.out.println(tasks.get(i)); - } - } - public static void markAsDone(int number) { - try { - tasks.get(number-1).setDone(true); - System.out.println("\tNice! I've marked this task as done:"); - System.out.println("\t" + tasks.get(number-1)); - } catch (NullPointerException | IndexOutOfBoundsException e) { - System.out.println("\tOops! task " + number + " does not exist"); - } - } - public static void markAsUndone(int number) { + public Duke(String filePath) { + ui = new Ui(); + storage = new Storage(filePath); try { - tasks.get(number-1).setDone(false); - System.out.println("\tNice! I've marked this task as undone:"); - System.out.println("\t" + tasks.get(number-1)); - } catch (NullPointerException | IndexOutOfBoundsException e) { - System.out.println("\tOops! task " + number + " does not exist"); + taskList = new TaskList(storage.load()); + } catch (DukeException e) { + ui.showError(e); + taskList = new TaskList(); } } - - public static void deleteTask(int number) { - try { - System.out.println("\tNoted. I've removed this task:"); - System.out.println("\t" + tasks.get(number-1)); - tasks.remove(number-1); - System.out.println("\tNow you have " + tasks.size() + " task(s) in the list."); - } catch (NullPointerException | IndexOutOfBoundsException e) { - System.out.println("\tOops! task " + number + " does not exist"); - } + public void run() { + Parser parser = new Parser(); + ui.showStartMessage(); + boolean isExit = false; + while (!isExit) { + try { + String fullCommand = ui.readCommand(); + Command c = parser.parse(fullCommand); + c.execute(taskList, ui, storage); + isExit = c.isExit(); + } catch (DukeException e) { + ui.showError(e); + } + } + System.exit(0); } - public static void main(String[] args) { - // Greetings - String intro = "~~~~~~~~~~~~~~~~~~~\n" - + "Hello! I'm Wenny!\n" - + "How may I help you?\n" - + "~~~~~~~~~~~~~~~~~~~"; - System.out.println(intro); - DataManager dataManager = new DataManager("./data/data.txt"); - tasks = dataManager.loadData(); - - while (true) { - Scanner scanner = new Scanner(System.in); - String userInput = scanner.nextLine(); - String[] substr = userInput.split("\\s+", 2); - switch (substr[0]) { - case "bye": - printByeMessage(); - break; - case "list": - printTasks(); - break; - case "mark": - markAsDone(Integer.parseInt(substr[1])); - dataManager.save(tasks); - break; - case "unmark": - markAsUndone(Integer.parseInt(substr[1])); - dataManager.save(tasks); - break; - case "todo": - try { - addToTasks(substr[1], Type.TODO); - dataManager.save(tasks); - break; - } catch (ArrayIndexOutOfBoundsException e) { - System.out.println("\tDescription of a todo cannot be empty"); - break; - } - case "deadline": - try { - addToTasks(substr[1], Type.DEADLINE); - dataManager.save(tasks); - break; - } catch (ArrayIndexOutOfBoundsException e) { - System.out.println("\tDescription of a deadline cannot be empty"); - break; - } - case "event": - try { - addToTasks(substr[1], Type.EVENT); - dataManager.save(tasks); - break; - } catch (ArrayIndexOutOfBoundsException e) { - System.out.println("\tDescription of a event cannot be empty"); - break; - } - case "delete": - deleteTask(Integer.parseInt(substr[1])); - break; - default: - System.out.println("\tInvalid input, please try again"); - } - } - } - public static void printByeMessage() { - System.out.println("\tBye. Hope to see you again soon!"); - System.exit(0); + new Duke("./data/data.txt").run(); } } diff --git a/src/main/java/DukeException.java b/src/main/java/DukeException.java new file mode 100644 index 000000000..97be7674c --- /dev/null +++ b/src/main/java/DukeException.java @@ -0,0 +1,12 @@ +public class DukeException extends Exception{ + String errorMessage; + public DukeException(String errorMessage) { + this.errorMessage = errorMessage; + } + + @Override + public String toString() { + return errorMessage; + } + +} diff --git a/src/main/java/Events.java b/src/main/java/Event.java similarity index 87% rename from src/main/java/Events.java rename to src/main/java/Event.java index c1ed504a4..33005e625 100644 --- a/src/main/java/Events.java +++ b/src/main/java/Event.java @@ -1,8 +1,8 @@ -public class Events extends Task { +public class Event extends Task { String from; String to; - public Events(String description, String from, String to) { + public Event(String description, String from, String to) { super(description); setFrom(from); setTo(to); diff --git a/src/main/java/META-INF/MANIFEST.MF b/src/main/java/META-INF/MANIFEST.MF new file mode 100644 index 000000000..9f37e4e0a --- /dev/null +++ b/src/main/java/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: Duke + diff --git a/src/main/java/Parser.java b/src/main/java/Parser.java new file mode 100644 index 000000000..a1cf67983 --- /dev/null +++ b/src/main/java/Parser.java @@ -0,0 +1,15 @@ +import java.util.Scanner; + +public class Parser { + + public Parser() { + } + + public Command parse(String fullCommand) { + String[] substr = fullCommand.split("\\s+", 2); + if (substr.length == 1) { + return new Command(substr[0], null); + } + return new Command(substr[0], substr[1]); + } +} diff --git a/src/main/java/DataManager.java b/src/main/java/Storage.java similarity index 75% rename from src/main/java/DataManager.java rename to src/main/java/Storage.java index 72937f452..63ed1e2b6 100644 --- a/src/main/java/DataManager.java +++ b/src/main/java/Storage.java @@ -1,21 +1,17 @@ -import com.sun.source.tree.AnnotationTree; - import java.io.File; import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; -import java.nio.charset.Charset; -import java.nio.file.Files; import java.util.ArrayList; import java.util.Scanner; -public class DataManager { +public class Storage { private String filePath; - public DataManager(String filePath) { + public Storage(String filePath) { this.filePath = filePath; } - public ArrayList<Task> loadData(){ + public ArrayList<Task> load() throws DukeException { ArrayList<Task> allTasks = new ArrayList<Task>(); try { File f = new File(filePath); @@ -28,7 +24,7 @@ public ArrayList<Task> loadData(){ String description = lineTokens[2].trim(); switch (taskType) { case "T": - ToDos todo = new ToDos(description); + ToDo todo = new ToDo(description); allTasks.add(todo); if (completionStatus.equals("1")) { todo.setDone(true); @@ -38,7 +34,7 @@ public ArrayList<Task> loadData(){ String[] deadlineTokens = description.split("\\|"); description = deadlineTokens[0].trim(); String by = deadlineTokens[1].trim(); - Deadlines deadline = new Deadlines(description, by); + Deadline deadline = new Deadline(description, by); allTasks.add(deadline); if (completionStatus.equals("1")) { deadline.setDone(true); @@ -49,7 +45,7 @@ public ArrayList<Task> loadData(){ description = eventTokens[0].trim(); String from = eventTokens[1].trim(); String to = eventTokens[2].trim(); - Events event = new Events(description, from, to); + Event event = new Event(description, from, to); allTasks.add(event); if (completionStatus.equals("1")) { event.setDone(true); @@ -60,13 +56,16 @@ public ArrayList<Task> loadData(){ break; } } - } catch (FileNotFoundException | ArrayIndexOutOfBoundsException e) { - System.out.println("\tFailed to read line"); + } catch (FileNotFoundException e) { + throw new DukeException("\tFailed to load file"); + } catch (ArrayIndexOutOfBoundsException e) { + throw new DukeException("\tFile is corrupted"); } return allTasks; } - public void save(ArrayList<Task> tasks) { + public void save(TaskList taskList) throws DukeException { + ArrayList<Task> tasks = taskList.getTasks(); try { createFile(); FileWriter fw = new FileWriter(filePath); @@ -75,11 +74,11 @@ public void save(ArrayList<Task> tasks) { } fw.close(); } catch (IOException e) { - System.out.println("An error has occurred while saving"); + throw new DukeException("An error has occurred while saving"); } } - public void createFile() { + public void createFile() throws DukeException { try { File f = new File(filePath); if (f.exists()) { @@ -90,7 +89,7 @@ public void createFile() { } f.createNewFile(); } catch (IOException e) { - System.out.println("Cannot create file; reason: " + e.getMessage()); + throw new DukeException("Cannot create file; reason: " + e.getMessage()); } } } \ No newline at end of file diff --git a/src/main/java/TaskList.java b/src/main/java/TaskList.java new file mode 100644 index 000000000..a22103fb7 --- /dev/null +++ b/src/main/java/TaskList.java @@ -0,0 +1,89 @@ +import java.util.ArrayList; + +public class TaskList { + + private ArrayList<Task> tasks; + public TaskList(ArrayList<Task> tasks) { + this.tasks = tasks; + } + public TaskList() { + this.tasks = new ArrayList<Task>(); + } + + public ArrayList<Task> getTasks() { + return tasks; + } + + public void add(Task task) { + this.tasks.add(task); + } + public void remove(Task task){ + this.tasks.remove(task); + } + + public void addTodo(String description) throws DukeException { + if (description.isBlank()) { + throw new DukeException("Description of a todo cannot be empty"); + } + tasks.add(new ToDo(description)); + } + + public void addDeadline(String description) throws DukeException { + if (description.isBlank()) { + throw new DukeException("Description of a deadline cannot be empty"); + } + try { + String[] deadlineTokens = description.split("/by"); + description = deadlineTokens[0].trim(); + String by = deadlineTokens[1].trim(); + Deadline deadline = new Deadline(description, by); + tasks.add(deadline); + } catch (ArrayIndexOutOfBoundsException e) { + throw new DukeException("Wrong format! Expected format: deadline [task] /by [time]"); + } + + } + + public void addEvent(String description) throws DukeException { + if (description.isBlank()) { + throw new DukeException("Description of a event cannot be empty"); + } + try { + String[] eventTokens = description.split("/from"); + description = eventTokens[0].trim(); + String[] fromAndToTokens = eventTokens[1].split("/to"); + String from = fromAndToTokens[0].trim(); + String to = fromAndToTokens[1].trim(); + Event event = new Event(description, from, to); + tasks.add(event); + } catch (ArrayIndexOutOfBoundsException e) { + throw new DukeException("Wrong format! Expected format: event [task] /from [time] /to [time]"); + } + + } + + public void markTask(String taskID, boolean isDone) throws DukeException { + try { + int index = Integer.parseInt(taskID); + tasks.get(index-1).setDone(isDone); + } catch (NullPointerException | NumberFormatException e) { + throw new DukeException("Oops! An integer taskID is expected"); + } catch (IndexOutOfBoundsException e) { + throw new DukeException("Oops! Task " + taskID + " does not exist"); + } + } + + public Task deleteTask(TaskList taskList, String taskID) throws DukeException { + ArrayList<Task> tasks = taskList.getTasks(); + try { + int index = Integer.parseInt(taskID); + Task removedTask = tasks.get(index-1); + tasks.remove(index-1); + return removedTask; + } catch (NullPointerException | NumberFormatException e) { + throw new DukeException("Oops! An integer taskID is expected"); + } catch (IndexOutOfBoundsException e) { + throw new DukeException("Oops! Task " + taskID + " does not exist"); + } + } +} diff --git a/src/main/java/ToDos.java b/src/main/java/ToDo.java similarity index 77% rename from src/main/java/ToDos.java rename to src/main/java/ToDo.java index f070b3545..3e088fa2d 100644 --- a/src/main/java/ToDos.java +++ b/src/main/java/ToDo.java @@ -1,6 +1,6 @@ -public class ToDos extends Task { +public class ToDo extends Task { - public ToDos(String description) { + public ToDo(String description) { super(description); } diff --git a/src/main/java/Ui.java b/src/main/java/Ui.java new file mode 100644 index 000000000..84a5f5838 --- /dev/null +++ b/src/main/java/Ui.java @@ -0,0 +1,89 @@ +import java.util.ArrayList; +import java.util.Scanner; + +public class Ui { + private static final String LINE_DIVIDER = "\t---------------------------------------"; + protected Scanner scanner; + + public Ui(){ + this.scanner = new Scanner(System.in); + } + + public void showStartMessage() { + String intro = "~~~~~~~~~~~~~~~~~~~\n" + + "Hello! I'm Wenny!\n" + + "How may I help you?\n" + + "~~~~~~~~~~~~~~~~~~~"; + System.out.println(intro); + } + + public void showByeMessage() { + showLine(); + System.out.println("\tBye. Hope to see you again soon!"); + showLine(); + } + public void showTasks(TaskList tasklist) { + ArrayList<Task> tasks = tasklist.getTasks(); + showLine(); + if (tasks.isEmpty()) { + System.out.println("\tYou do not have any task in the list."); + } else { + System.out.println("\tHere are the tasks in your list:"); + for (int i = 0; i < tasks.size(); i++) { + System.out.print("\t"); + System.out.print(i + 1 + "."); + System.out.println(tasks.get(i)); + } + } + showLine(); + } + + public void showAddTask(TaskList taskList) { + ArrayList<Task> tasks = taskList.getTasks(); + showLine(); + System.out.println("\tGot it. I've added this task:"); + System.out.println("\t" + tasks.get(tasks.size()-1)); + System.out.println("\tNow you have " + tasks.size() + " task(s) in the list."); + showLine(); + } + + public void showDeleteTask(TaskList taskList, Task removedTask) { + ArrayList<Task> tasks = taskList.getTasks(); + showLine(); + System.out.println("\tNoted. I've removed this task:"); + System.out.println("\t" + removedTask); + System.out.println("\tNow you have " + tasks.size() + " task(s) in the list."); + showLine(); + } + + public void showMark(TaskList taskList, String taskID, boolean isDone) { + ArrayList<Task> tasks = taskList.getTasks(); + int index = Integer.parseInt(taskID); + showLine(); + if (isDone) { + System.out.println("\tNice! I've marked this task as done:"); + } else { + System.out.println("\tNice! I've marked this task as undone:"); + } + System.out.println("\t" + tasks.get(index-1)); + showLine(); + } + + public void showLine() { + System.out.println(LINE_DIVIDER); + } + + public void showError(Exception e) { + showLine(); + System.out.println("\t" + e); + showLine(); + } + + public String readCommand() { + return scanner.nextLine(); + } + + public void showDeadlineError() { + + } +} From 02762e480467ee3100542897ba56b28a724166f4 Mon Sep 17 00:00:00 2001 From: Lim Yuh Ching <e0726103@u.nus.edu> Date: Wed, 4 Oct 2023 14:19:53 +0800 Subject: [PATCH 13/20] Create find command to match keyword with task --- src/main/java/Command.java | 12 +++++++++++- src/main/java/TaskList.java | 20 ++++++++++++++++++-- src/main/java/Ui.java | 15 +++++++++++++-- 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/main/java/Command.java b/src/main/java/Command.java index 50c99ea19..ebfb526d0 100644 --- a/src/main/java/Command.java +++ b/src/main/java/Command.java @@ -1,3 +1,5 @@ +import java.util.ArrayList; + public class Command { private String command; @@ -72,13 +74,21 @@ public void execute(TaskList taskList, Ui ui, Storage storage) throws DukeExcept break; case "delete": try { - Task removedTask = taskList.deleteTask(taskList, this.arg); + Task removedTask = taskList.deleteTask(this.arg); storage.save(taskList); ui.showDeleteTask(taskList, removedTask); } catch (DukeException e) { ui.showError(e); } break; + case "find": + try { + ArrayList<Task> matchingTasks = taskList.find(this.arg); + ui.showFind(matchingTasks); + } catch (DukeException e) { + ui.showError(e); + } + break; default: throw new DukeException("Invalid input, please try again"); } diff --git a/src/main/java/TaskList.java b/src/main/java/TaskList.java index a22103fb7..7a357b632 100644 --- a/src/main/java/TaskList.java +++ b/src/main/java/TaskList.java @@ -73,8 +73,7 @@ public void markTask(String taskID, boolean isDone) throws DukeException { } } - public Task deleteTask(TaskList taskList, String taskID) throws DukeException { - ArrayList<Task> tasks = taskList.getTasks(); + public Task deleteTask(String taskID) throws DukeException { try { int index = Integer.parseInt(taskID); Task removedTask = tasks.get(index-1); @@ -86,4 +85,21 @@ public Task deleteTask(TaskList taskList, String taskID) throws DukeException { throw new DukeException("Oops! Task " + taskID + " does not exist"); } } + + public ArrayList<Task> find(String keyword) throws DukeException { + if (keyword.isBlank()) { + throw new DukeException("Keyword cannot be empty"); + } + ArrayList<Task> matchingTasks = new ArrayList<Task>(); + for (Task task : tasks) { + String[] substrs = task.getDescription().split("\\s+"); + for (String substr : substrs) { + if (substr.equals(keyword)) { + matchingTasks.add(task); + break; + } + } + } + return matchingTasks; + } } diff --git a/src/main/java/Ui.java b/src/main/java/Ui.java index 84a5f5838..4521bdd75 100644 --- a/src/main/java/Ui.java +++ b/src/main/java/Ui.java @@ -83,7 +83,18 @@ public String readCommand() { return scanner.nextLine(); } - public void showDeadlineError() { - + public void showFind(ArrayList<Task> matchingTasks) { + showLine(); + if (matchingTasks.isEmpty()) { + System.out.println("\tKeyword does not match any task in the list."); + } else { + System.out.println("\tHere are the matching tasks in your list:"); + for (int i = 0; i < matchingTasks.size(); i++) { + System.out.print("\t"); + System.out.print(i + 1 + "."); + System.out.println(matchingTasks.get(i)); + } + } + showLine(); } } From 9df71858e0ab30360995c2f374bb25db813ab53f Mon Sep 17 00:00:00 2001 From: Lim Yuh Ching <e0726103@u.nus.edu> Date: Wed, 4 Oct 2023 16:13:40 +0800 Subject: [PATCH 14/20] Add Javadoc to most of the class --- src/main/java/Command.java | 27 +++++++++++++-- src/main/java/Deadline.java | 11 ++++-- src/main/java/Duke.java | 19 +++++++++++ src/main/java/DukeException.java | 7 ++++ src/main/java/Event.java | 11 ++++-- src/main/java/Parser.java | 11 ++++-- src/main/java/Storage.java | 27 +++++++++++++++ src/main/java/Task.java | 16 +++++---- src/main/java/TaskList.java | 57 ++++++++++++++++++++++++++++++++ src/main/java/ToDo.java | 10 +++++- src/main/java/Ui.java | 4 +++ 11 files changed, 185 insertions(+), 15 deletions(-) diff --git a/src/main/java/Command.java b/src/main/java/Command.java index ebfb526d0..a1d927d3a 100644 --- a/src/main/java/Command.java +++ b/src/main/java/Command.java @@ -1,10 +1,19 @@ import java.util.ArrayList; +/** + * Execute commands from the user. + */ public class Command { - private String command; private String arg; private boolean isExit; + + /** + * Constructor of a Command + * + * @param command Command to be executed + * @param arg Arguments of the given command + */ public Command(String command, String arg) { this.command = command; this.arg = arg; @@ -18,6 +27,20 @@ public void setExit(boolean exit) { public boolean isExit() { return isExit; } + + /** + * Execute the command given by the user + * Each command is handled by its corresponding method in {@code TaskList}. If there + * is any changes to the list of tasks, it will be saved into the file through {@code Storage}. + * Relevant information will be shown to the user through corresponding methods in {@code Ui}. + * A custom exceptions will be thrown if an invalid command is received or an invalid argument of + * the respective command. + * + * @param taskList TaskList object that contains a list of Tasks + * @param ui User interface object that handles the printing of information + * @param storage Storage object that saves the updated list into filepath + * @throws DukeException Custom Exception with customer error message + */ public void execute(TaskList taskList, Ui ui, Storage storage) throws DukeException{ switch(this.command) { case "bye": @@ -89,7 +112,7 @@ public void execute(TaskList taskList, Ui ui, Storage storage) throws DukeExcept ui.showError(e); } break; - default: + default: // Unknown command exception throw new DukeException("Invalid input, please try again"); } } diff --git a/src/main/java/Deadline.java b/src/main/java/Deadline.java index 060990d6d..72724cc11 100644 --- a/src/main/java/Deadline.java +++ b/src/main/java/Deadline.java @@ -11,14 +11,21 @@ public void setBy(String by) { this.by = by; } + /** + * Returns the format of the task to be printed out to user + * @return String representation of the task + */ @Override public String toString() { return "[D]" + super.toString() + " (by: " + by + ")"; } + /** + * Returns the format of the task to be saved into a file + * @return String representation of the task + */ @Override public String toSave() { - return "D | " + (this.isDone() ? "1" : "0") + " | " + this.getDescription() - + " | " + this.getBy(); + return "D | " + super.toSave() + " | " + by; } } diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 1435577aa..fa2208b4b 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,12 +1,24 @@ import java.util.ArrayList; import java.util.Scanner; +/** + * This is the main program of Duke. + * Duke is a chatbot for user track tasks such as todos, deadlines and events. + * User can add tasks, mark tasks as done, delete tasks or find tasks based on a keyword. + * These tasks are automatically saved in a file in ./data/data.txt whenever an operation + * on the TaskList is made. This file will be loaded on future start up of the chatbot + * + */ public class Duke { private Storage storage; private TaskList taskList; private Ui ui; + /** + * Constructor of Duke. Initialise User interface, Storage and TaskList instances. + * @param filePath Path to the file where tasks are to be loaded from and saved to. + */ public Duke(String filePath) { ui = new Ui(); storage = new Storage(filePath); @@ -17,6 +29,13 @@ public Duke(String filePath) { taskList = new TaskList(); } } + + /** + * To start up the chatbot. + * A greetings will be printed on the command line interface and the chatbot will + * await instructions from the user. The chatbot will run until an exit command is received. + * Any exception during the operation will produce an error message to notify the user + */ public void run() { Parser parser = new Parser(); ui.showStartMessage(); diff --git a/src/main/java/DukeException.java b/src/main/java/DukeException.java index 97be7674c..9e0c7d012 100644 --- a/src/main/java/DukeException.java +++ b/src/main/java/DukeException.java @@ -1,9 +1,16 @@ +/** + * Custom Exception for Duke + */ public class DukeException extends Exception{ String errorMessage; public DukeException(String errorMessage) { this.errorMessage = errorMessage; } + /** + * Format error message for printing to command line interface. + * @return Return the error message of the specific exception in String format. + */ @Override public String toString() { return errorMessage; diff --git a/src/main/java/Event.java b/src/main/java/Event.java index 33005e625..9e299cfa5 100644 --- a/src/main/java/Event.java +++ b/src/main/java/Event.java @@ -24,15 +24,22 @@ public void setTo(String to) { this.to = to; } + /** + * Returns the format of the task to be printed out to user + * @return String representation of the task + */ @Override public String toString() { return "[E]" + super.toString() + " (from: " + from + ", to: " + to + ")"; } + /** + * Returns the format of the task to be saved into a file + * @return String representation of the task + */ @Override public String toSave() { - return "E | " + (this.isDone() ? "1" : "0") + " | " + this.getDescription() - + " | " + this.getFrom() + " | " + this.getTo(); + return "E | " + super.toSave() + " | " + from + " | " + to; } } diff --git a/src/main/java/Parser.java b/src/main/java/Parser.java index a1cf67983..e9456c55b 100644 --- a/src/main/java/Parser.java +++ b/src/main/java/Parser.java @@ -1,10 +1,17 @@ -import java.util.Scanner; - +/** + * Parser object that handles splitting of command line arguments given by the user. + */ public class Parser { public Parser() { } + /** + * Split user input into command and argument of the command. + * + * @param fullCommand User input. + * @return Return a Command object for execution of the command. + */ public Command parse(String fullCommand) { String[] substr = fullCommand.split("\\s+", 2); if (substr.length == 1) { diff --git a/src/main/java/Storage.java b/src/main/java/Storage.java index 63ed1e2b6..da27b3f12 100644 --- a/src/main/java/Storage.java +++ b/src/main/java/Storage.java @@ -4,6 +4,10 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Scanner; + +/** + * Storage object that handles loading and saving of tasks into specified file + */ public class Storage { private String filePath; @@ -11,6 +15,14 @@ public Storage(String filePath) { this.filePath = filePath; } + /** + * This method attempts to load pre-existing tasks from the file specified by + * the filepath. It will read the text file line by line and extract the information + * based on a format specified by the program. + * + * @return A TaskList object that contains the tasks loaded from the file. + * @throws DukeException If the file cannot be found or is corrupted. + */ public ArrayList<Task> load() throws DukeException { ArrayList<Task> allTasks = new ArrayList<Task>(); try { @@ -64,6 +76,16 @@ public ArrayList<Task> load() throws DukeException { return allTasks; } + /** + * + * This method save the tasks in TaskList into the file specified by filepath. + * If the file specified by the filepath does not exist, it will create a new file as + * specified by the filepath. + * + * @param taskList TaskList object that contains the tasks. + * @throws DukeException If there is an error during the saving process due to corrupted + * data or invalid input. + */ public void save(TaskList taskList) throws DukeException { ArrayList<Task> tasks = taskList.getTasks(); try { @@ -78,6 +100,11 @@ public void save(TaskList taskList) throws DukeException { } } + /** + * This method create the file specified by the filepath. + * + * @throws DukeException If it fails to create the specified file. + */ public void createFile() throws DukeException { try { File f = new File(filePath); diff --git a/src/main/java/Task.java b/src/main/java/Task.java index ff4cdd94e..4bf169bc8 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -22,15 +22,19 @@ public void setDone(boolean done) { isDone = done; } + /** + * Returns the format of the task to be printed out to user + * @return String representation of the task + */ public String toString() { - String temp = "[ ]"; - if (isDone) { - temp = "[X]"; - } - return temp + " " + description; + return (isDone ? "[X]" : "[ ]") + " " + description; } + /** + * Returns the format of the task to be saved into a file + * @return String representation of the task + */ public String toSave() { - return null; + return (isDone ? "1" : "0") + " | " + description; } } diff --git a/src/main/java/TaskList.java b/src/main/java/TaskList.java index 7a357b632..e75a4aad3 100644 --- a/src/main/java/TaskList.java +++ b/src/main/java/TaskList.java @@ -1,5 +1,8 @@ import java.util.ArrayList; +/** + * A list of tasks. + */ public class TaskList { private ArrayList<Task> tasks; @@ -21,6 +24,14 @@ public void remove(Task task){ this.tasks.remove(task); } + /** + * This method attempts to add a Todo task into the TaskList. + * It will check whether the description of the task is empty before + * creating a ToDo object and add it into the TaskList. + * + * @param description Details regarding the todo task. + * @throws DukeException If the description of the todo task is empty. + */ public void addTodo(String description) throws DukeException { if (description.isBlank()) { throw new DukeException("Description of a todo cannot be empty"); @@ -28,6 +39,16 @@ public void addTodo(String description) throws DukeException { tasks.add(new ToDo(description)); } + /** + * This method attempts to add a deadline task into the TaskList. + * It will check whether the description of the task is empty before + * extracting the deadline of the task. It will then create a new Deadline + * object and add it into the TaskList. + * + * @param description Details regarding the deadline task. + * @throws DukeException If the description of the deadline task is empty + * or when the /by keyword is not provided. + */ public void addDeadline(String description) throws DukeException { if (description.isBlank()) { throw new DukeException("Description of a deadline cannot be empty"); @@ -44,6 +65,16 @@ public void addDeadline(String description) throws DukeException { } + /** + * This method attempts to add an event task to the TaskList. + * It will check whether the description of the task is empty before extracting + * the dates/time for from when the event start to when the event ends. It then + * creates a Event object and add it into the TaskList. + * + * @param description Details regarding the Event task. + * @throws DukeException If the description of the Event task is empty + * or when the /from and /to keywords are the provided. + */ public void addEvent(String description) throws DukeException { if (description.isBlank()) { throw new DukeException("Description of a event cannot be empty"); @@ -62,6 +93,15 @@ public void addEvent(String description) throws DukeException { } + /** + * This method attempts to mark a task in the TaskList + * It will check whether the task index provided by the user is valid before marking the task as + * the respective isDone argument. + * + * @param taskID Index of the task to be marked. + * @param isDone True to mark the task as done and False to mark the task as undone. + * @throws DukeException if task index is not found or task index in not an int. + */ public void markTask(String taskID, boolean isDone) throws DukeException { try { int index = Integer.parseInt(taskID); @@ -73,6 +113,14 @@ public void markTask(String taskID, boolean isDone) throws DukeException { } } + /** + * This method attempts to delete a task based on the task index from the TaskList + * It will check whether the task index provided by the user exist before deleting the task. + * + * @param taskID Index of task to be deleted. + * @return The removed task to be printed by Ui. + * @throws DukeException If task index is not an integer or task index does not exist. + */ public Task deleteTask(String taskID) throws DukeException { try { int index = Integer.parseInt(taskID); @@ -86,6 +134,15 @@ public Task deleteTask(String taskID) throws DukeException { } } + /** + * This method attempts to find the tasks with descriptions that matches the keyword provided + * It first check if the keyword provided is valid before going through the TaskList. For every + * task, it splits the description into substrings and compare word by word with the keyword. + * + * @param keyword Keyword to be searched for. + * @return A list of tasks that matches the keyword for Ui object to print. + * @throws DukeException If keyword is not a word or null. + */ public ArrayList<Task> find(String keyword) throws DukeException { if (keyword.isBlank()) { throw new DukeException("Keyword cannot be empty"); diff --git a/src/main/java/ToDo.java b/src/main/java/ToDo.java index 3e088fa2d..6bfbf268f 100644 --- a/src/main/java/ToDo.java +++ b/src/main/java/ToDo.java @@ -4,12 +4,20 @@ public ToDo(String description) { super(description); } + /** + * Returns the format of the task to be printed out to user + * @return String representation of the task + */ public String toString() { return "[T]" + super.toString(); } + /** + * Returns the format of the task to be saved into a file + * @return String representation of the task + */ @Override public String toSave() { - return "T | " + (this.isDone() ? "1" : "0") + " | " + this.getDescription(); + return "T | " + super.toSave(); } } diff --git a/src/main/java/Ui.java b/src/main/java/Ui.java index 4521bdd75..53cc36564 100644 --- a/src/main/java/Ui.java +++ b/src/main/java/Ui.java @@ -1,6 +1,10 @@ import java.util.ArrayList; import java.util.Scanner; +/** + * User interface object that handles the format and content of various outputs to the user + * through command line interface. + */ public class Ui { private static final String LINE_DIVIDER = "\t---------------------------------------"; protected Scanner scanner; From e1a286f0c0647a976ab56ad84427000da8ed0202 Mon Sep 17 00:00:00 2001 From: limyuhching <75166212+limyuhching@users.noreply.github.com> Date: Wed, 4 Oct 2023 17:00:55 +0800 Subject: [PATCH 15/20] Update README.md --- docs/README.md | 88 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 60 insertions(+), 28 deletions(-) diff --git a/docs/README.md b/docs/README.md index 8077118eb..d5d8dc137 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,29 +1,61 @@ -# User Guide - +# Wenny Task Manager User Guide +Wenny is your friendly task manager that helps you keep track of your endless numbers of to do tasks, deadlines and events. ## Features - -### Feature-ABC - -Description of the feature. - -### Feature-XYZ - -Description of the feature. - -## Usage - -### `Keyword` - Describe action - -Describe the action and its outcome. - -Example of usage: - -`keyword (optional arguments)` - -Expected outcome: - -Description of the outcome. - -``` -expected output -``` +Notes about the command format: +1. Words in UPPER_CASE are the parameters to be supplied by the user. +e.g. in todo DESCRIPTION, DESCRIPTION is a parameter which can be used as todo Homework. + +2. Extraneous parameters for commands that do not take in parameters (such as list and bye) will be ignored. +e.g. if the command specifies list 123, it will be interpreted as list. + +### List current tasks `list` +List all current tasks. +Format: `list` + +### Exit the program `bye` +Exit the program. +Format: `bye` + +### Add a to-do task `todo` +Add to-do task into the list. +Format: `list DESCRIPTION` +Example: +- `todo complete week 7 tasks` +- `todo sleep` + +### Add a deadline task `deadline` +Add a task with a deadline +Format: `deadline DESCRIPTION /by DEADLINE` +Example: +- `deadline complete week 8 tasks /by 12 Oct` + +### Add an event task `event` +Add an event into the task list +Format: `event DESCRIPTION /from START_TIME /to END_TIME` +Example: +- `event IA interview /from 7 Oct 2pm /to 7 Oct 4pm` +- +### Mark a task as done `mark` +Mark a task on the task list as done +Format: `mark TASK_NUMBER` +Exmaple: +- `mark 1` + +### Mark a task as undone `unmark` +Mark a task on the task list as undone +Format: `unmark TASK_NUMBER` +Exmaple: +- `unmark 1` + + +### Delete a task `delete` +Delete a task from the task list +Format: `delete TASK_NUMBER` +Exmaple: +- `delete 1` + +### Find the tasks that matches a certain keyword `find` +Find the tasks that matches a certain keyword +Format: `find KEYWORD` +Exmaple: +- `find John` From 119b4c951b40d642dba5f029e7725aa747e137e7 Mon Sep 17 00:00:00 2001 From: limyuhching <75166212+limyuhching@users.noreply.github.com> Date: Wed, 4 Oct 2023 17:12:05 +0800 Subject: [PATCH 16/20] Update README.md --- docs/README.md | 83 +++++++++++++++++++++++++++++++------------------- 1 file changed, 51 insertions(+), 32 deletions(-) diff --git a/docs/README.md b/docs/README.md index d5d8dc137..c4a655f89 100644 --- a/docs/README.md +++ b/docs/README.md @@ -3,59 +3,78 @@ Wenny is your friendly task manager that helps you keep track of your endless nu ## Features Notes about the command format: 1. Words in UPPER_CASE are the parameters to be supplied by the user. -e.g. in todo DESCRIPTION, DESCRIPTION is a parameter which can be used as todo Homework. +e.g. in todo DESCRIPTION, DESCRIPTION is a parameter which can be used as `todo Homework`. 2. Extraneous parameters for commands that do not take in parameters (such as list and bye) will be ignored. -e.g. if the command specifies list 123, it will be interpreted as list. +e.g. if the command specifies `list 123`, it will be interpreted as list. + +## List current tasks `list` -### List current tasks `list` List all current tasks. + Format: `list` -### Exit the program `bye` +## Exit the program `bye` + Exit the program. + Format: `bye` -### Add a to-do task `todo` +## Add a to-do task `todo` + Add to-do task into the list. + Format: `list DESCRIPTION` + Example: - `todo complete week 7 tasks` - `todo sleep` -### Add a deadline task `deadline` -Add a task with a deadline + +## Add a deadline task `deadline` +Add a task with a deadline. + Format: `deadline DESCRIPTION /by DEADLINE` + Example: -- `deadline complete week 8 tasks /by 12 Oct` +- `deadline complete week 8 tasks /by 12 Oct`. + + +## Add an event task `event` +Add an event into the task list. + +Format: `event DESCRIPTION /from START_TIME /to END_TIME`. + +Example: +- `event IA interview /from 7 Oct 2pm /to 7 Oct 4pm`. + +## Mark a task as done `mark` +Mark a task on the task list as done. +Format: `mark TASK_NUMBER`. -### Add an event task `event` -Add an event into the task list -Format: `event DESCRIPTION /from START_TIME /to END_TIME` Example: -- `event IA interview /from 7 Oct 2pm /to 7 Oct 4pm` -- -### Mark a task as done `mark` -Mark a task on the task list as done -Format: `mark TASK_NUMBER` -Exmaple: - `mark 1` -### Mark a task as undone `unmark` -Mark a task on the task list as undone -Format: `unmark TASK_NUMBER` -Exmaple: -- `unmark 1` +## Mark a task as undone `unmark` +Mark a task on the task list as undone. + +Format: `unmark TASK_NUMBER`. + +Example: +- `unmark 1`. -### Delete a task `delete` -Delete a task from the task list -Format: `delete TASK_NUMBER` -Exmaple: -- `delete 1` +## Delete a task `delete` +Delete a task from the task list. -### Find the tasks that matches a certain keyword `find` -Find the tasks that matches a certain keyword -Format: `find KEYWORD` -Exmaple: -- `find John` +Format: `delete TASK_NUMBER`. + +Example: +- `delete 1`. + +## Find the tasks that matches a certain keyword `find` +Find the tasks that matches a certain keyword . +Format: `find KEYWORD`. + +Example: +- `find John`. From 0a66c63f37375356e24dea6494321f8bf759cc9b Mon Sep 17 00:00:00 2001 From: Lim Yuh Ching <e0726103@u.nus.edu> Date: Wed, 4 Oct 2023 20:40:44 +0800 Subject: [PATCH 17/20] Minor UI changes --- src/main/java/Duke.java | 2 ++ src/main/java/Storage.java | 6 +++--- src/main/java/TaskList.java | 4 ++-- src/main/java/Ui.java | 18 ++++++++++++++---- 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index fa2208b4b..74c0df72b 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -22,8 +22,10 @@ public class Duke { public Duke(String filePath) { ui = new Ui(); storage = new Storage(filePath); + ui.showLoadingFile(); try { taskList = new TaskList(storage.load()); + ui.showFileLoaded(); } catch (DukeException e) { ui.showError(e); taskList = new TaskList(); diff --git a/src/main/java/Storage.java b/src/main/java/Storage.java index da27b3f12..870b5ac8e 100644 --- a/src/main/java/Storage.java +++ b/src/main/java/Storage.java @@ -64,14 +64,14 @@ public ArrayList<Task> load() throws DukeException { } break; default: - System.out.println("\tUnknown task encountered. Skipping"); + System.out.println("\tUnknown task encountered. Skipping."); break; } } } catch (FileNotFoundException e) { - throw new DukeException("\tFailed to load file"); + throw new DukeException("\tFailed to load file: file not found."); } catch (ArrayIndexOutOfBoundsException e) { - throw new DukeException("\tFile is corrupted"); + throw new DukeException("\tFailed to load file: file is corrupted."); } return allTasks; } diff --git a/src/main/java/TaskList.java b/src/main/java/TaskList.java index e75a4aad3..f38439456 100644 --- a/src/main/java/TaskList.java +++ b/src/main/java/TaskList.java @@ -60,7 +60,7 @@ public void addDeadline(String description) throws DukeException { Deadline deadline = new Deadline(description, by); tasks.add(deadline); } catch (ArrayIndexOutOfBoundsException e) { - throw new DukeException("Wrong format! Expected format: deadline [task] /by [time]"); + throw new DukeException("Wrong format! Expected format: deadline DESCRIPTION /by TIME"); } } @@ -88,7 +88,7 @@ public void addEvent(String description) throws DukeException { Event event = new Event(description, from, to); tasks.add(event); } catch (ArrayIndexOutOfBoundsException e) { - throw new DukeException("Wrong format! Expected format: event [task] /from [time] /to [time]"); + throw new DukeException("Wrong format! Expected format: event DESCRIPTION /from START_TIME /to END_TIME"); } } diff --git a/src/main/java/Ui.java b/src/main/java/Ui.java index 53cc36564..8d331128e 100644 --- a/src/main/java/Ui.java +++ b/src/main/java/Ui.java @@ -13,12 +13,22 @@ public Ui(){ this.scanner = new Scanner(System.in); } + public void showLoadingFile() { + showLine(); + System.out.println("\tLoading file......"); + showLine(); + } + + public void showFileLoaded() { + showLine(); + System.out.println("\tFile has been successfully loaded"); + showLine(); + } public void showStartMessage() { - String intro = "~~~~~~~~~~~~~~~~~~~\n" - + "Hello! I'm Wenny!\n" - + "How may I help you?\n" - + "~~~~~~~~~~~~~~~~~~~"; + showLine(); + String intro = "\tHello! I'm Wenny!\n\tHow may I help you?"; System.out.println(intro); + showLine(); } public void showByeMessage() { From 9cfe06ed27f804534c301ccb77b3d0b79db9ec6a Mon Sep 17 00:00:00 2001 From: Lim Yuh Ching <e0726103@u.nus.edu> Date: Wed, 4 Oct 2023 20:44:03 +0800 Subject: [PATCH 18/20] Minor UI changes --- src/main/java/Storage.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/Storage.java b/src/main/java/Storage.java index 870b5ac8e..ccea9c230 100644 --- a/src/main/java/Storage.java +++ b/src/main/java/Storage.java @@ -69,9 +69,9 @@ public ArrayList<Task> load() throws DukeException { } } } catch (FileNotFoundException e) { - throw new DukeException("\tFailed to load file: file not found."); + throw new DukeException("Failed to load file: file not found."); } catch (ArrayIndexOutOfBoundsException e) { - throw new DukeException("\tFailed to load file: file is corrupted."); + throw new DukeException("Failed to load file: file is corrupted."); } return allTasks; } From 96b87277b14e68157ddca3729b0934787410d44c Mon Sep 17 00:00:00 2001 From: Lim Yuh Ching <e0726103@u.nus.edu> Date: Wed, 4 Oct 2023 21:12:30 +0800 Subject: [PATCH 19/20] Handle exception when argument is missing --- src/main/java/Parser.java | 2 +- src/main/java/TaskList.java | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/main/java/Parser.java b/src/main/java/Parser.java index e9456c55b..dab652756 100644 --- a/src/main/java/Parser.java +++ b/src/main/java/Parser.java @@ -15,7 +15,7 @@ public Parser() { public Command parse(String fullCommand) { String[] substr = fullCommand.split("\\s+", 2); if (substr.length == 1) { - return new Command(substr[0], null); + return new Command(substr[0], ""); } return new Command(substr[0], substr[1]); } diff --git a/src/main/java/TaskList.java b/src/main/java/TaskList.java index f38439456..848e39a8a 100644 --- a/src/main/java/TaskList.java +++ b/src/main/java/TaskList.java @@ -33,10 +33,11 @@ public void remove(Task task){ * @throws DukeException If the description of the todo task is empty. */ public void addTodo(String description) throws DukeException { - if (description.isBlank()) { + if (description.isBlank()) { // Check if description is empty throw new DukeException("Description of a todo cannot be empty"); } tasks.add(new ToDo(description)); + } /** @@ -50,13 +51,13 @@ public void addTodo(String description) throws DukeException { * or when the /by keyword is not provided. */ public void addDeadline(String description) throws DukeException { - if (description.isBlank()) { - throw new DukeException("Description of a deadline cannot be empty"); - } try { String[] deadlineTokens = description.split("/by"); description = deadlineTokens[0].trim(); String by = deadlineTokens[1].trim(); + if (description.isBlank() | by.isBlank()) { // Check if description is empty + throw new DukeException("Wrong format! Expected format: deadline DESCRIPTION /by TIME"); + } Deadline deadline = new Deadline(description, by); tasks.add(deadline); } catch (ArrayIndexOutOfBoundsException e) { @@ -76,15 +77,16 @@ public void addDeadline(String description) throws DukeException { * or when the /from and /to keywords are the provided. */ public void addEvent(String description) throws DukeException { - if (description.isBlank()) { - throw new DukeException("Description of a event cannot be empty"); - } try { String[] eventTokens = description.split("/from"); description = eventTokens[0].trim(); String[] fromAndToTokens = eventTokens[1].split("/to"); String from = fromAndToTokens[0].trim(); String to = fromAndToTokens[1].trim(); + if (description.isBlank() | from.isBlank() | to.isBlank()) { // Check if format is correct + throw new DukeException("Wrong format! Expected format: " + + "event DESCRIPTION /from START_TIME /to END_TIME"); + } Event event = new Event(description, from, to); tasks.add(event); } catch (ArrayIndexOutOfBoundsException e) { From 7edd3e731fac8ac7b20930da3690640f9391dcfe Mon Sep 17 00:00:00 2001 From: limyuhching <75166212+limyuhching@users.noreply.github.com> Date: Sat, 7 Oct 2023 23:29:12 +0800 Subject: [PATCH 20/20] Update README.md --- docs/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/README.md b/docs/README.md index c4a655f89..2b1fd3586 100644 --- a/docs/README.md +++ b/docs/README.md @@ -50,6 +50,7 @@ Example: ## Mark a task as done `mark` Mark a task on the task list as done. + Format: `mark TASK_NUMBER`. Example: @@ -74,6 +75,7 @@ Example: ## Find the tasks that matches a certain keyword `find` Find the tasks that matches a certain keyword . + Format: `find KEYWORD`. Example: