From ab3b2874d7f3b4adc0ad2496069c4acd86475033 Mon Sep 17 00:00:00 2001 From: BevLow Date: Mon, 19 Aug 2024 21:35:56 +0800 Subject: [PATCH 01/50] Commit change in Bot Name --- src/main/java/ChattyCharlie.java | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/main/java/ChattyCharlie.java diff --git a/src/main/java/ChattyCharlie.java b/src/main/java/ChattyCharlie.java new file mode 100644 index 000000000..591d3da46 --- /dev/null +++ b/src/main/java/ChattyCharlie.java @@ -0,0 +1,10 @@ +public class ChattyCharlie { + public static void main(String[] args) { + String logo = " ____ _ \n" + + "| _ \\ _ _| | _____ \n" + + "| | | | | | | |/ / _ \\\n" + + "| |_| | |_| | < __/\n" + + "|____/ \\__,_|_|\\_\\___|\n"; + System.out.println("Hello from\n" + logo); + } +} From 85bd6a569c46f91325be10e3d5fd4cf3cf1d4c66 Mon Sep 17 00:00:00 2001 From: BevLow Date: Mon, 19 Aug 2024 21:39:25 +0800 Subject: [PATCH 02/50] Commit change Logo --- src/main/java/ChattyCharlie.java | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/main/java/ChattyCharlie.java b/src/main/java/ChattyCharlie.java index 591d3da46..7d0486292 100644 --- a/src/main/java/ChattyCharlie.java +++ b/src/main/java/ChattyCharlie.java @@ -1,10 +1,17 @@ public class ChattyCharlie { public static void main(String[] args) { - String logo = " ____ _ \n" - + "| _ \\ _ _| | _____ \n" - + "| | | | | | | |/ / _ \\\n" - + "| |_| | |_| | < __/\n" - + "|____/ \\__,_|_|\\_\\___|\n"; + String logo = " ____________________________________________________________\n" + + " _____ \n" + + " / \\ \n" + + " | O O | \n" + + " | \\___/ | \n" + + " \\_____/ \n" + + " /\\_____/\\ \n" + + " | | \n" + + " | | \n" + + " |_______| \n" + + " \n" + + "____________________________________________________________\n"; System.out.println("Hello from\n" + logo); } } From afcf4e7e488bcc0cfb7b3f93929a9ca2ee8cfbc9 Mon Sep 17 00:00:00 2001 From: BevLow Date: Mon, 19 Aug 2024 21:40:02 +0800 Subject: [PATCH 03/50] Commit change text --- src/main/java/ChattyCharlie.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/ChattyCharlie.java b/src/main/java/ChattyCharlie.java index 7d0486292..a1b662968 100644 --- a/src/main/java/ChattyCharlie.java +++ b/src/main/java/ChattyCharlie.java @@ -12,6 +12,12 @@ public static void main(String[] args) { + " |_______| \n" + " \n" + "____________________________________________________________\n"; - System.out.println("Hello from\n" + logo); + String greeting = "Hello! I'm ChattyCharlie\n" + + "What can I do for you?\n" + + "____________________________________________________________\n"; + + String farewell = "Bye. Hope to see you again soon!"; + + System.out.println(logo + greeting + farewell); } } From 5c3cc13d2ec89a21fec623a1131788ad86934a23 Mon Sep 17 00:00:00 2001 From: BevLow Date: Mon, 19 Aug 2024 21:43:02 +0800 Subject: [PATCH 04/50] Commit Final Version --- src/main/java/ChattyCharlie.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/ChattyCharlie.java b/src/main/java/ChattyCharlie.java index a1b662968..002eaacd9 100644 --- a/src/main/java/ChattyCharlie.java +++ b/src/main/java/ChattyCharlie.java @@ -13,10 +13,10 @@ public static void main(String[] args) { + " \n" + "____________________________________________________________\n"; String greeting = "Hello! I'm ChattyCharlie\n" - + "What can I do for you?\n" + + "What can I help you with today?\n" + "____________________________________________________________\n"; - String farewell = "Bye. Hope to see you again soon!"; + String farewell = "Bye. Have a pleasant day today!"; System.out.println(logo + greeting + farewell); } From 9e97cefc06429dc739a38b309fc91f50c5f78e25 Mon Sep 17 00:00:00 2001 From: BevLow Date: Mon, 19 Aug 2024 21:46:11 +0800 Subject: [PATCH 05/50] Commit Final Version --- src/main/java/ChattyCharlie.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ChattyCharlie.java b/src/main/java/ChattyCharlie.java index 002eaacd9..72ac71045 100644 --- a/src/main/java/ChattyCharlie.java +++ b/src/main/java/ChattyCharlie.java @@ -16,7 +16,7 @@ public static void main(String[] args) { + "What can I help you with today?\n" + "____________________________________________________________\n"; - String farewell = "Bye. Have a pleasant day today!"; + String farewell = "Bye, have a pleasant day today!"; System.out.println(logo + greeting + farewell); } From eb4b65ec82941584b5a977d063455818c8e8475e Mon Sep 17 00:00:00 2001 From: BevLow Date: Thu, 29 Aug 2024 23:48:56 +0800 Subject: [PATCH 06/50] added an echo function --- src/main/java/Duke.java | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 src/main/java/Duke.java diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java deleted file mode 100644 index 5d313334c..000000000 --- a/src/main/java/Duke.java +++ /dev/null @@ -1,10 +0,0 @@ -public class Duke { - public static void main(String[] args) { - String logo = " ____ _ \n" - + "| _ \\ _ _| | _____ \n" - + "| | | | | | | |/ / _ \\\n" - + "| |_| | |_| | < __/\n" - + "|____/ \\__,_|_|\\_\\___|\n"; - System.out.println("Hello from\n" + logo); - } -} From 9fbf0c6d6bbfa707a79195db772262a6cca03971 Mon Sep 17 00:00:00 2001 From: BevLow Date: Thu, 29 Aug 2024 23:51:59 +0800 Subject: [PATCH 07/50] Commit Echo Function and Gitignore Class --- .gitignore | 3 +++ src/main/java/ChattyCharlie.java | 41 +++++++++++++++++++++++++------- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 2873e189e..79f351811 100644 --- a/.gitignore +++ b/.gitignore @@ -13,5 +13,8 @@ src/main/resources/docs/ *.iml bin/ +# Ignore compiled .class files +*.class + /text-ui-test/ACTUAL.TXT text-ui-test/EXPECTED-UNIX.TXT diff --git a/src/main/java/ChattyCharlie.java b/src/main/java/ChattyCharlie.java index 72ac71045..ea93cff32 100644 --- a/src/main/java/ChattyCharlie.java +++ b/src/main/java/ChattyCharlie.java @@ -1,7 +1,29 @@ +import java.util.Scanner; + public class ChattyCharlie { + + public static void Echo() { //Echo as a function + String line; + String you = "User: "; + //make the scanner + Scanner in = new Scanner(System.in); + //accept an insert + while (true) { + System.out.print(you); + line = in.nextLine(); + + //if the line contains bye, it signals the end + if (line.contains("Bye") || line.contains("bye")) { + break; + } + + String response = "Input: "; + System.out.println(response + line); + } + } + public static void main(String[] args) { - String logo = " ____________________________________________________________\n" - + " _____ \n" + String logo = " _____ \n" + " / \\ \n" + " | O O | \n" + " | \\___/ | \n" @@ -10,14 +32,17 @@ public static void main(String[] args) { + " | | \n" + " | | \n" + " |_______| \n" - + " \n" - + "____________________________________________________________\n"; - String greeting = "Hello! I'm ChattyCharlie\n" - + "What can I help you with today?\n" - + "____________________________________________________________\n"; + + " \n"; + String charlie = "Charlie: "; + + String greeting = "Hello! I'm ChattyCharlie, your friendly companion.\n" + + " What can I help you with today?\n" ; String farewell = "Bye, have a pleasant day today!"; - System.out.println(logo + greeting + farewell); + System.out.println(logo + charlie+ greeting); + Echo(); + System.out.println(charlie + farewell); + } } From 89920ccb703d6b41e7ebaea2d4d512ff9049dcb6 Mon Sep 17 00:00:00 2001 From: BevLow Date: Thu, 29 Aug 2024 23:57:18 +0800 Subject: [PATCH 08/50] Commit update Echo --- src/main/java/ChattyCharlie.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ChattyCharlie.java b/src/main/java/ChattyCharlie.java index ea93cff32..77e0ef134 100644 --- a/src/main/java/ChattyCharlie.java +++ b/src/main/java/ChattyCharlie.java @@ -17,7 +17,7 @@ public static void Echo() { //Echo as a function break; } - String response = "Input: "; + String response = "Output: "; System.out.println(response + line); } } From b31dc7b29479f546557f0ab6c59d443df08121cb Mon Sep 17 00:00:00 2001 From: BevLow Date: Fri, 30 Aug 2024 01:16:21 +0800 Subject: [PATCH 09/50] Commit update Echo --- src/main/java/ChattyCharlie.java | 59 ++++++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 10 deletions(-) diff --git a/src/main/java/ChattyCharlie.java b/src/main/java/ChattyCharlie.java index 77e0ef134..9198e8aa9 100644 --- a/src/main/java/ChattyCharlie.java +++ b/src/main/java/ChattyCharlie.java @@ -2,11 +2,45 @@ public class ChattyCharlie { - public static void Echo() { //Echo as a function + public static class List { + private String[] list; + private int size; + + //constructor + public List() { + list = new String[100]; + size = 0; + } + + //Method to add an item to the list + public void add(String text) { + //add the text into the list + list[size] = text; + //account for the item + size++; + } + + //To print list + public void toPrint() { + //print all + System.out.println("ToDo List:"); + for (int i = 0; i < size; i++) { + int number = i+1; + System.out.println(" " + number + ". " + list[i]); + } + } + } + + public static void toDoMaker() { //Echo as a function String line; - String you = "User: "; + String you = "User: "; + //make the scanner Scanner in = new Scanner(System.in); + + //create an instance of list class + List toDo = new List(); + //accept an insert while (true) { System.out.print(you); @@ -16,9 +50,14 @@ public static void Echo() { //Echo as a function if (line.contains("Bye") || line.contains("bye")) { break; } - - String response = "Output: "; - System.out.println(response + line); + //add or print + if (line.equals("list")) { + toDo.toPrint(); + } else { + //add the item + toDo.add(line); + System.out.println(" Added: " + line); + } } } @@ -33,15 +72,15 @@ public static void main(String[] args) { + " | | \n" + " |_______| \n" + " \n"; - String charlie = "Charlie: "; + String charlie = "Smarty: "; - String greeting = "Hello! I'm ChattyCharlie, your friendly companion.\n" - + " What can I help you with today?\n" ; + String greeting = "Hello! I'm SmartTasker, your consistent buddy.\n" + + " What shall we do today?\n" ; - String farewell = "Bye, have a pleasant day today!"; + String farewell = "All the best in clearing your list!"; System.out.println(logo + charlie+ greeting); - Echo(); + toDoMaker(); System.out.println(charlie + farewell); } From dced9db5f17ceb5223ecff31189464e8c6b5bf95 Mon Sep 17 00:00:00 2001 From: BevLow Date: Fri, 30 Aug 2024 01:18:24 +0800 Subject: [PATCH 10/50] Added A tasklist maker --- src/main/java/ChattyCharlie.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/ChattyCharlie.java b/src/main/java/ChattyCharlie.java index 9198e8aa9..5e1f9d25a 100644 --- a/src/main/java/ChattyCharlie.java +++ b/src/main/java/ChattyCharlie.java @@ -72,9 +72,9 @@ public static void main(String[] args) { + " | | \n" + " |_______| \n" + " \n"; - String charlie = "Smarty: "; + String charlie = "Charlie: "; - String greeting = "Hello! I'm SmartTasker, your consistent buddy.\n" + String greeting = "Hello! I'm ChattyCharlie, your consistent buddy.\n" + " What shall we do today?\n" ; String farewell = "All the best in clearing your list!"; From 7014334507c952b8c2f3114b72a27d06e93ece67 Mon Sep 17 00:00:00 2001 From: BevLow Date: Fri, 30 Aug 2024 02:10:32 +0800 Subject: [PATCH 11/50] Mark as Done Algo added. Created a Task Class and the List class is modified. Added some new features. --- src/main/java/ChattyCharlie.java | 114 +++++++++++++++++++++++++++++-- 1 file changed, 108 insertions(+), 6 deletions(-) diff --git a/src/main/java/ChattyCharlie.java b/src/main/java/ChattyCharlie.java index 5e1f9d25a..5a78c8a6d 100644 --- a/src/main/java/ChattyCharlie.java +++ b/src/main/java/ChattyCharlie.java @@ -2,35 +2,104 @@ public class ChattyCharlie { + //TASK CLASS + public static class Task{ + protected String description; + protected boolean isDone; + + //constructor + public Task(String description) { + this.description = description; + this.isDone = false; + } + + //check if its marked as done + public String getStatusIcon() { + return (isDone ? "X" : " "); + } + + //to toggle the task + public void marked() { + this.isDone = true; //change the variable + } + + public void unmarked() { + this.isDone = false; //change the variable + } + } + + + //LIST CLASS public static class List { - private String[] list; + //make a list of task + private Task[] list; private int size; //constructor public List() { - list = new String[100]; + list = new Task[100]; size = 0; } //Method to add an item to the list public void add(String text) { + //create an instance for Task + Task newTask = new Task(text); //add the text into the list - list[size] = text; + list[size] = newTask; //account for the item size++; } + //To mark + public void mark(int index) { + if (index >= 0 && index < size) { + list[index].marked(); + int remainingTask = countUnmarkedTasks(); + System.out.println(" Well Done! 1 task down, " + remainingTask + " to go."); + System.out.println(" [" + list[index].getStatusIcon() + "] " + list[index].description); + } else { + System.out.println(" Invalid task number."); + } + } + + //To unmark + public void unmark(int index) { + if (index >= 0 && index < size) { + list[index].unmarked(); + int remainingTask = countUnmarkedTasks(); + System.out.println(" Hmmm, not quite done yet, " + remainingTask + " to go."); + System.out.println(" [" + list[index].getStatusIcon() + "] " + list[index].description); + } else { + System.out.println(" Invalid task number."); + } + } + //To print list - public void toPrint() { + public void toPrintList() { //print all + int remainingTask = countUnmarkedTasks(); System.out.println("ToDo List:"); + System.out.println("pending Task: " + remainingTask); for (int i = 0; i < size; i++) { int number = i+1; - System.out.println(" " + number + ". " + list[i]); + System.out.println(" " + number + ".[" +list[i].getStatusIcon() + "] " + list[i].description); } } + + // Method to count how many tasks are unmarked + public int countUnmarkedTasks() { + int count = 0; + for (int i = 0; i < size; i++) { + if (!list[i].isDone) { + count++; + } + } + return count; + } } + //MAIN ALGO public static void toDoMaker() { //Echo as a function String line; String you = "User: "; @@ -52,7 +121,40 @@ public static void toDoMaker() { //Echo as a function } //add or print if (line.equals("list")) { - toDo.toPrint(); + toDo.toPrintList(); + } else if (line.startsWith("mark ")) { + //trim to get the task name + String taskDescription = line.substring(5).trim(); + boolean found = false; + + //loop to find + for(int index = 0; index < toDo.size; index++) + { + if(toDo.list[index].description.equals(taskDescription)) { + toDo.mark(index); + found = true; + break; + } + } + if(!found) { + System.out.println(" Invalid task description."); + } + } else if (line.startsWith("unmark ")) { + String taskDescription = line.substring(7).trim(); + boolean found = false; + + //loop to find + for(int index = 0; index < toDo.size; index++) + { + if(toDo.list[index].description.equals(taskDescription)) { + toDo.unmark(index); + found = true; + break; + } + } + if(!found) { + System.out.println(" Invalid task description."); + } } else { //add the item toDo.add(line); From 2076ea4bc827c9903473d7b2b2ab43e7540ff181 Mon Sep 17 00:00:00 2001 From: BevLow Date: Fri, 30 Aug 2024 02:14:13 +0800 Subject: [PATCH 12/50] Mark as Done Algo added. Created a Task Class and the List class is modified. Added some new features. --- src/main/java/ChattyCharlie.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ChattyCharlie.java b/src/main/java/ChattyCharlie.java index 5a78c8a6d..a30bc23f3 100644 --- a/src/main/java/ChattyCharlie.java +++ b/src/main/java/ChattyCharlie.java @@ -137,7 +137,7 @@ public static void toDoMaker() { //Echo as a function } } if(!found) { - System.out.println(" Invalid task description."); + System.out.println(" Invalid task description"); } } else if (line.startsWith("unmark ")) { String taskDescription = line.substring(7).trim(); From 258892c18f2d6b08505381b858d251c295507c05 Mon Sep 17 00:00:00 2001 From: BevLow Date: Fri, 30 Aug 2024 13:08:28 +0800 Subject: [PATCH 13/50] Add coding standards --- src/main/java/ChattyCharlie.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/ChattyCharlie.java b/src/main/java/ChattyCharlie.java index a30bc23f3..0a47292cb 100644 --- a/src/main/java/ChattyCharlie.java +++ b/src/main/java/ChattyCharlie.java @@ -19,11 +19,11 @@ public String getStatusIcon() { } //to toggle the task - public void marked() { + public void markTask() { this.isDone = true; //change the variable } - public void unmarked() { + public void unmarkTask() { this.isDone = false; //change the variable } } @@ -42,7 +42,7 @@ public List() { } //Method to add an item to the list - public void add(String text) { + public void addTask(String text) { //create an instance for Task Task newTask = new Task(text); //add the text into the list @@ -54,7 +54,7 @@ public void add(String text) { //To mark public void mark(int index) { if (index >= 0 && index < size) { - list[index].marked(); + list[index].markTask(); int remainingTask = countUnmarkedTasks(); System.out.println(" Well Done! 1 task down, " + remainingTask + " to go."); System.out.println(" [" + list[index].getStatusIcon() + "] " + list[index].description); @@ -66,7 +66,7 @@ public void mark(int index) { //To unmark public void unmark(int index) { if (index >= 0 && index < size) { - list[index].unmarked(); + list[index].unmarkTask(); int remainingTask = countUnmarkedTasks(); System.out.println(" Hmmm, not quite done yet, " + remainingTask + " to go."); System.out.println(" [" + list[index].getStatusIcon() + "] " + list[index].description); @@ -157,7 +157,7 @@ public static void toDoMaker() { //Echo as a function } } else { //add the item - toDo.add(line); + toDo.addTask(line); System.out.println(" Added: " + line); } } From 50d89a65afb3d8e1f7f2df181a3e32f2ce334ad9 Mon Sep 17 00:00:00 2001 From: BevLow Date: Fri, 30 Aug 2024 14:46:59 +0800 Subject: [PATCH 14/50] Add coding standards --- src/main/java/ChattyCharlie.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/ChattyCharlie.java b/src/main/java/ChattyCharlie.java index 0a47292cb..851b5b3a7 100644 --- a/src/main/java/ChattyCharlie.java +++ b/src/main/java/ChattyCharlie.java @@ -14,7 +14,7 @@ public Task(String description) { } //check if its marked as done - public String getStatusIcon() { + public String getMarkedStatus() { return (isDone ? "X" : " "); } @@ -57,7 +57,7 @@ public void mark(int index) { list[index].markTask(); int remainingTask = countUnmarkedTasks(); System.out.println(" Well Done! 1 task down, " + remainingTask + " to go."); - System.out.println(" [" + list[index].getStatusIcon() + "] " + list[index].description); + System.out.println(" [" + list[index].getMarkedStatus() + "] " + list[index].description); } else { System.out.println(" Invalid task number."); } @@ -69,7 +69,7 @@ public void unmark(int index) { list[index].unmarkTask(); int remainingTask = countUnmarkedTasks(); System.out.println(" Hmmm, not quite done yet, " + remainingTask + " to go."); - System.out.println(" [" + list[index].getStatusIcon() + "] " + list[index].description); + System.out.println(" [" + list[index].getMarkedStatus() + "] " + list[index].description); } else { System.out.println(" Invalid task number."); } @@ -83,7 +83,7 @@ public void toPrintList() { System.out.println("pending Task: " + remainingTask); for (int i = 0; i < size; i++) { int number = i+1; - System.out.println(" " + number + ".[" +list[i].getStatusIcon() + "] " + list[i].description); + System.out.println(" " + number + ".[" +list[i].getMarkedStatus() + "] " + list[i].description); } } From f67a83fdddfef6443a5c8e9c13bc623032fbb625 Mon Sep 17 00:00:00 2001 From: BevLow Date: Wed, 4 Sep 2024 16:52:57 +0800 Subject: [PATCH 15/50] Add Level-4 --- src/main/java/ChattyCharlie.java | 250 +++++++++++-------------------- src/main/java/CommandType.java | 9 ++ src/main/java/Deadline.java | 19 +++ src/main/java/List.java | 94 ++++++++++++ src/main/java/Task.java | 39 +++++ src/main/java/Todo.java | 20 +++ 6 files changed, 268 insertions(+), 163 deletions(-) create mode 100644 src/main/java/CommandType.java create mode 100644 src/main/java/Deadline.java create mode 100644 src/main/java/List.java create mode 100644 src/main/java/Task.java create mode 100644 src/main/java/Todo.java diff --git a/src/main/java/ChattyCharlie.java b/src/main/java/ChattyCharlie.java index 851b5b3a7..7b10319a6 100644 --- a/src/main/java/ChattyCharlie.java +++ b/src/main/java/ChattyCharlie.java @@ -2,105 +2,8 @@ public class ChattyCharlie { - //TASK CLASS - public static class Task{ - protected String description; - protected boolean isDone; - - //constructor - public Task(String description) { - this.description = description; - this.isDone = false; - } - - //check if its marked as done - public String getMarkedStatus() { - return (isDone ? "X" : " "); - } - - //to toggle the task - public void markTask() { - this.isDone = true; //change the variable - } - - public void unmarkTask() { - this.isDone = false; //change the variable - } - } - - - //LIST CLASS - public static class List { - //make a list of task - private Task[] list; - private int size; - - //constructor - public List() { - list = new Task[100]; - size = 0; - } - - //Method to add an item to the list - public void addTask(String text) { - //create an instance for Task - Task newTask = new Task(text); - //add the text into the list - list[size] = newTask; - //account for the item - size++; - } - - //To mark - public void mark(int index) { - if (index >= 0 && index < size) { - list[index].markTask(); - int remainingTask = countUnmarkedTasks(); - System.out.println(" Well Done! 1 task down, " + remainingTask + " to go."); - System.out.println(" [" + list[index].getMarkedStatus() + "] " + list[index].description); - } else { - System.out.println(" Invalid task number."); - } - } - - //To unmark - public void unmark(int index) { - if (index >= 0 && index < size) { - list[index].unmarkTask(); - int remainingTask = countUnmarkedTasks(); - System.out.println(" Hmmm, not quite done yet, " + remainingTask + " to go."); - System.out.println(" [" + list[index].getMarkedStatus() + "] " + list[index].description); - } else { - System.out.println(" Invalid task number."); - } - } - - //To print list - public void toPrintList() { - //print all - int remainingTask = countUnmarkedTasks(); - System.out.println("ToDo List:"); - System.out.println("pending Task: " + remainingTask); - for (int i = 0; i < size; i++) { - int number = i+1; - System.out.println(" " + number + ".[" +list[i].getMarkedStatus() + "] " + list[i].description); - } - } - - // Method to count how many tasks are unmarked - public int countUnmarkedTasks() { - int count = 0; - for (int i = 0; i < size; i++) { - if (!list[i].isDone) { - count++; - } - } - return count; - } - } - //MAIN ALGO - public static void toDoMaker() { //Echo as a function + public static void ScheduleMaker() { //Echo as a function String line; String you = "User: "; @@ -108,82 +11,103 @@ public static void toDoMaker() { //Echo as a function Scanner in = new Scanner(System.in); //create an instance of list class - List toDo = new List(); + List list = new List(); //accept an insert while (true) { + //takes in an input System.out.print(you); line = in.nextLine(); - //if the line contains bye, it signals the end - if (line.contains("Bye") || line.contains("bye")) { - break; - } - //add or print - if (line.equals("list")) { - toDo.toPrintList(); - } else if (line.startsWith("mark ")) { - //trim to get the task name - String taskDescription = line.substring(5).trim(); - boolean found = false; - - //loop to find - for(int index = 0; index < toDo.size; index++) - { - if(toDo.list[index].description.equals(taskDescription)) { - toDo.mark(index); - found = true; - break; - } - } - if(!found) { - System.out.println(" Invalid task description"); - } - } else if (line.startsWith("unmark ")) { - String taskDescription = line.substring(7).trim(); - boolean found = false; - - //loop to find - for(int index = 0; index < toDo.size; index++) - { - if(toDo.list[index].description.equals(taskDescription)) { - toDo.unmark(index); - found = true; - break; + //get the first word to see the command type + String firstWord = line.split(" ")[0]; + + //make the string a command + CommandType command = CommandType.valueOf(firstWord.toUpperCase()); + + //start the different command types + switch (command) { + case TODO: + String todoDescription = line.substring(5).trim(); + list.addTask(new Todo(todoDescription)); + System.out.println(" Added todo: " + todoDescription); + break; + + case DEADLINE: + String[] deadlineParts = line.substring(9).trim().split(" by "); + if (deadlineParts.length == 2) { //make sure that the string is only split into 2 + String deadlineDescription = deadlineParts[0].trim(); + String by = deadlineParts[1].trim(); + list.addTask(new Deadline(deadlineDescription, by)); + System.out.println(" Added deadline: " + deadlineDescription + " (by: " + by + ")"); } - } - if(!found) { - System.out.println(" Invalid task description."); - } - } else { - //add the item - toDo.addTask(line); - System.out.println(" Added: " + line); + break; + + case EVENT: + String[] eventParts = line.substring(6).trim().split("from"); + String description = eventParts[0].trim(); + //further split the array into the start and end times + String[] eventTimes = eventParts[1].trim().split(" to "); + String startTime = eventTimes[0].trim(); + String endTime = eventTimes[1].trim(); + + //add the event + list.addTask(new Event(description, startTime, endTime)); + System.out.println(" Added event: " + description + " (from: " + startTime + ", to: " + endTime + ")"); + + break; + + case MARK: + String markIndex = line.substring(5).trim(); + int markNo = Integer.parseInt(markIndex) -1; //convert to array + //mark it + list.mark(markNo); + break; + + case UNMARK: + String unmarkIndex = line.substring(7).trim(); + int unmarkNo = Integer.parseInt(unmarkIndex) -1; //convert to array + //mark it + list.unmark(unmarkNo); + break; + + case BYE: + return; //just exit + + case LIST: + list.printList(); + break; + + default: + //add the item + list.addTask(new Task(line, CommandType.TODO)); //for cases without label, it is a Todo as well + System.out.println(" Added: " + line); + break; } } } - public static void main(String[] args) { - String logo = " _____ \n" - + " / \\ \n" - + " | O O | \n" - + " | \\___/ | \n" - + " \\_____/ \n" - + " /\\_____/\\ \n" - + " | | \n" - + " | | \n" - + " |_______| \n" - + " \n"; - String charlie = "Charlie: "; - - String greeting = "Hello! I'm ChattyCharlie, your consistent buddy.\n" - + " What shall we do today?\n" ; - - String farewell = "All the best in clearing your list!"; - - System.out.println(logo + charlie+ greeting); - toDoMaker(); - System.out.println(charlie + farewell); + public static void main (String[]args){ + String logo = " _____ \n" + + " / \\ \n" + + " | O O | \n" + + " | \\___/ | \n" + + " \\_____/ \n" + + " /\\_____/\\ \n" + + " | | \n" + + " | | \n" + + " |_______| \n" + + " \n"; + String charlie = "Charlie: "; + + String greeting = "Hello! I'm ChattyCharlie, your consistent buddy.\n" + + " What shall we do today?\n"; + + String farewell = "All the best in clearing your list!"; + + System.out.println(logo + charlie + greeting); + ScheduleMaker(); + System.out.println(charlie + farewell); } } diff --git a/src/main/java/CommandType.java b/src/main/java/CommandType.java new file mode 100644 index 000000000..11ac0c293 --- /dev/null +++ b/src/main/java/CommandType.java @@ -0,0 +1,9 @@ +public enum CommandType { + TODO, + DEADLINE, + EVENT, + MARK, + UNMARK, + BYE, + LIST +} \ No newline at end of file diff --git a/src/main/java/Deadline.java b/src/main/java/Deadline.java new file mode 100644 index 000000000..74c95fa8e --- /dev/null +++ b/src/main/java/Deadline.java @@ -0,0 +1,19 @@ +//Deadline Class +public class Deadline extends Task { + protected String by; + + public Deadline(String description, String by) { + super(description, CommandType.DEADLINE); + this.by = by; + } + public void setBy(String by) { + this.by = by; + } + public String getBy() { + return by; + } + @Override + public String toString() { + return "[D]" + super.toString() + " (by: " + by + ")"; + } +} \ No newline at end of file diff --git a/src/main/java/List.java b/src/main/java/List.java new file mode 100644 index 000000000..6afd48823 --- /dev/null +++ b/src/main/java/List.java @@ -0,0 +1,94 @@ + //LIST CLASS + public class List { + //make a list of task + private Task[] list; + private int size; + + //constructor + public List() { + list = new Task[100]; + size = 0; + } + + //Method to add an item to the list + public void addTask(Task task) { + //add the text into the list + list[size] = task; + //account for the item + size++; + } + + public Task[] getList() { + return this.list; + } + + public int getSize() { + return size; + } + + //To mark + public void mark(int index) { + if (index >= 0 && index < size) { + list[index].markTask(); + int remainingTask = countUnmarkedTasks(); + System.out.println(" Well Done! 1 task down, " + remainingTask + " to go."); + System.out.println(" [" + list[index].getMarkedStatus() + "] " + list[index].description); + } else { + System.out.println(" Invalid task number."); + } + } + + //To unmark + public void unmark(int index) { + if (index >= 0 && index < size) { + list[index].unmarkTask(); + int remainingTask = countUnmarkedTasks(); + System.out.println(" Hmmm, not quite done yet, " + remainingTask + " to go."); + System.out.println(" [" + list[index].getMarkedStatus() + "] " + list[index].description); + } else { + System.out.println(" Invalid task number."); + } + } + + //To print list + public void printList() { + //print all + int remainingTask = countUnmarkedTasks(); + System.out.println("ToDo List:"); + System.out.println("pending Task: " + remainingTask); + for (int i = 0; i < size; i++) { + int number = i+1; + Task task = list[i]; + //use a switch to determine + switch (task.getType()) { + case TODO: + Todo todoTask = (Todo) task; + System.out.println(" " + number + ".[T][" + todoTask.getMarkedStatus() + "] " + todoTask.description); + break; + + case DEADLINE: + Deadline deadlineTask = (Deadline) task; + System.out.println(" " + number + ".[D][" + deadlineTask.getMarkedStatus() + "] " + deadlineTask.description + " (by: " + deadlineTask.by + ")"); + break; + + case EVENT: + Event eventTask = (Event) task; + System.out.println(" " + number + ".[E][" + eventTask.getMarkedStatus() + "] " + eventTask.description + " (from: " + eventTask.start + " to: " + eventTask.end + ")"); + break; + default: + break; + } + } + } + + // Method to count how many tasks are unmarked + public int countUnmarkedTasks() { + int count = 0; + for (int i = 0; i < size; i++) { + if (!list[i].isDone) { + count++; + } + } + return count; + } + } \ No newline at end of file diff --git a/src/main/java/Task.java b/src/main/java/Task.java new file mode 100644 index 000000000..942e066dd --- /dev/null +++ b/src/main/java/Task.java @@ -0,0 +1,39 @@ +//TASK CLASS +public class Task { + protected String description; + protected boolean isDone; + protected CommandType type; + + //constructor + public Task(String description, CommandType type) { + this.description = description; + this.isDone = false; + this.type = type; + } + + //check if its marked as done + public String getMarkedStatus() { + return (isDone ? "X" : " "); + } + + public CommandType getType() { + return type; + } + + public String getDescription() { + return this.description; + } + + //to toggle the task + public void markTask() { + this.isDone = true; //change the variable + } + + public void unmarkTask() { + this.isDone = false; //change the variable + } + + public String toString() { + return "[" + getMarkedStatus() + "] " + description; + } +} \ No newline at end of file diff --git a/src/main/java/Todo.java b/src/main/java/Todo.java new file mode 100644 index 000000000..b20048308 --- /dev/null +++ b/src/main/java/Todo.java @@ -0,0 +1,20 @@ +//todo class +public class Todo extends Task { + protected boolean isDone; + + public Todo(String description) { + super(description, CommandType.TODO); + isDone = false; + } + public void setDone(boolean done) { + isDone = done; + } + public boolean isDone() { + return isDone; + } + + @Override + public String toString() { + return "[T]" + super.toString(); + } +} From 1e1bb0ce99104ff8895c7488e87a05ad40f47070 Mon Sep 17 00:00:00 2001 From: BevLow Date: Wed, 4 Sep 2024 17:20:44 +0800 Subject: [PATCH 16/50] Add Level-4-bugfixes --- src/main/java/ChattyCharlie.java | 16 ++++++++++++---- src/main/java/Constants.java | 4 ++++ src/main/java/Event.java | 33 ++++++++++++++++++++++++++++++++ src/main/java/List.java | 18 ++++++++--------- 4 files changed, 58 insertions(+), 13 deletions(-) create mode 100644 src/main/java/Constants.java create mode 100644 src/main/java/Event.java diff --git a/src/main/java/ChattyCharlie.java b/src/main/java/ChattyCharlie.java index 7b10319a6..76215c782 100644 --- a/src/main/java/ChattyCharlie.java +++ b/src/main/java/ChattyCharlie.java @@ -18,6 +18,7 @@ public static void ScheduleMaker() { //Echo as a function //takes in an input System.out.print(you); line = in.nextLine(); + System.out.println(Constants.LINE); //get the first word to see the command type String firstWord = line.split(" ")[0]; @@ -30,7 +31,8 @@ public static void ScheduleMaker() { //Echo as a function case TODO: String todoDescription = line.substring(5).trim(); list.addTask(new Todo(todoDescription)); - System.out.println(" Added todo: " + todoDescription); + System.out.println(Constants.SPACE + "Added todo: " + todoDescription); + System.out.println(Constants.LINE); break; case DEADLINE: @@ -39,7 +41,8 @@ public static void ScheduleMaker() { //Echo as a function String deadlineDescription = deadlineParts[0].trim(); String by = deadlineParts[1].trim(); list.addTask(new Deadline(deadlineDescription, by)); - System.out.println(" Added deadline: " + deadlineDescription + " (by: " + by + ")"); + System.out.println(Constants.SPACE + "Added deadline: " + deadlineDescription + " (by: " + by + ")"); + System.out.println(Constants.LINE); } break; @@ -53,7 +56,8 @@ public static void ScheduleMaker() { //Echo as a function //add the event list.addTask(new Event(description, startTime, endTime)); - System.out.println(" Added event: " + description + " (from: " + startTime + ", to: " + endTime + ")"); + System.out.println(Constants.SPACE + "Added event: " + description + " (from: " + startTime + ", to: " + endTime + ")"); + System.out.println(Constants.LINE); break; @@ -62,6 +66,7 @@ public static void ScheduleMaker() { //Echo as a function int markNo = Integer.parseInt(markIndex) -1; //convert to array //mark it list.mark(markNo); + System.out.println(Constants.LINE); break; case UNMARK: @@ -69,6 +74,7 @@ public static void ScheduleMaker() { //Echo as a function int unmarkNo = Integer.parseInt(unmarkIndex) -1; //convert to array //mark it list.unmark(unmarkNo); + System.out.println(Constants.LINE); break; case BYE: @@ -76,12 +82,14 @@ public static void ScheduleMaker() { //Echo as a function case LIST: list.printList(); + System.out.println(Constants.LINE); break; default: //add the item list.addTask(new Task(line, CommandType.TODO)); //for cases without label, it is a Todo as well - System.out.println(" Added: " + line); + System.out.println(Constants.SPACE + "Added: " + line); + System.out.println(Constants.LINE); break; } } diff --git a/src/main/java/Constants.java b/src/main/java/Constants.java new file mode 100644 index 000000000..eff97fb38 --- /dev/null +++ b/src/main/java/Constants.java @@ -0,0 +1,4 @@ +public class Constants { + public static final String SPACE = " "; + public static final String LINE = "------------"; +} \ No newline at end of file diff --git a/src/main/java/Event.java b/src/main/java/Event.java new file mode 100644 index 000000000..ee987a046 --- /dev/null +++ b/src/main/java/Event.java @@ -0,0 +1,33 @@ +//Events +public class Event extends Task { + protected String start; + protected String end; + + public Event(String description, String start, String end) { + super(description, CommandType.EVENT); + this.start = start; + this.end = end; + } + + public void setStart(String start) { + this.start = start; + } + + public String getStart() { + return start; + } + + + public void setEnd(String end) { + this.end = end; + } + + public String getEnd() { + return end; + } + + @Override + public String toString() { + return "[E]" + super.toString() + " (from: " + start + " to: " + end + ")"; + } +} \ No newline at end of file diff --git a/src/main/java/List.java b/src/main/java/List.java index 6afd48823..2e3379f86 100644 --- a/src/main/java/List.java +++ b/src/main/java/List.java @@ -31,10 +31,10 @@ public void mark(int index) { if (index >= 0 && index < size) { list[index].markTask(); int remainingTask = countUnmarkedTasks(); - System.out.println(" Well Done! 1 task down, " + remainingTask + " to go."); - System.out.println(" [" + list[index].getMarkedStatus() + "] " + list[index].description); + System.out.println(Constants.SPACE + "Well Done! 1 task down, " + remainingTask + " to go."); + System.out.println(Constants.SPACE+ "[" + list[index].getMarkedStatus() + "] " + list[index].description); } else { - System.out.println(" Invalid task number."); + System.out.println(Constants.SPACE+ "Invalid task number."); } } @@ -43,10 +43,10 @@ public void unmark(int index) { if (index >= 0 && index < size) { list[index].unmarkTask(); int remainingTask = countUnmarkedTasks(); - System.out.println(" Hmmm, not quite done yet, " + remainingTask + " to go."); - System.out.println(" [" + list[index].getMarkedStatus() + "] " + list[index].description); + System.out.println(Constants.SPACE + "Hmmm, not quite done yet, " + remainingTask + " to go."); + System.out.println(Constants.SPACE + "[" + list[index].getMarkedStatus() + "] " + list[index].description); } else { - System.out.println(" Invalid task number."); + System.out.println(Constants.SPACE + "Invalid task number."); } } @@ -63,17 +63,17 @@ public void printList() { switch (task.getType()) { case TODO: Todo todoTask = (Todo) task; - System.out.println(" " + number + ".[T][" + todoTask.getMarkedStatus() + "] " + todoTask.description); + System.out.println(Constants.SPACE + number + ".[T][" + todoTask.getMarkedStatus() + "] " + todoTask.description); break; case DEADLINE: Deadline deadlineTask = (Deadline) task; - System.out.println(" " + number + ".[D][" + deadlineTask.getMarkedStatus() + "] " + deadlineTask.description + " (by: " + deadlineTask.by + ")"); + System.out.println(Constants.SPACE + number + ".[D][" + deadlineTask.getMarkedStatus() + "] " + deadlineTask.description + " (by: " + deadlineTask.by + ")"); break; case EVENT: Event eventTask = (Event) task; - System.out.println(" " + number + ".[E][" + eventTask.getMarkedStatus() + "] " + eventTask.description + " (from: " + eventTask.start + " to: " + eventTask.end + ")"); + System.out.println(Constants.SPACE + number + ".[E][" + eventTask.getMarkedStatus() + "] " + eventTask.description + " (from: " + eventTask.start + " to: " + eventTask.end + ")"); break; default: break; From 0085d8fe3174c03e27f9e863a27c2709004276fc Mon Sep 17 00:00:00 2001 From: BevLow Date: Wed, 4 Sep 2024 17:27:07 +0800 Subject: [PATCH 17/50] Add Level-4-bugfixes --- src/main/java/ChattyCharlie.java | 23 +++-------------------- src/main/java/Constants.java | 17 +++++++++++++++++ 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/main/java/ChattyCharlie.java b/src/main/java/ChattyCharlie.java index 76215c782..adba26efb 100644 --- a/src/main/java/ChattyCharlie.java +++ b/src/main/java/ChattyCharlie.java @@ -96,26 +96,9 @@ public static void ScheduleMaker() { //Echo as a function } public static void main (String[]args){ - String logo = " _____ \n" - + " / \\ \n" - + " | O O | \n" - + " | \\___/ | \n" - + " \\_____/ \n" - + " /\\_____/\\ \n" - + " | | \n" - + " | | \n" - + " |_______| \n" - + " \n"; - String charlie = "Charlie: "; - - String greeting = "Hello! I'm ChattyCharlie, your consistent buddy.\n" - + " What shall we do today?\n"; - - String farewell = "All the best in clearing your list!"; - - System.out.println(logo + charlie + greeting); - ScheduleMaker(); - System.out.println(charlie + farewell); + System.out.println(Constants.LOGO + Constants.CHARLIE + Constants.GREETING); + ScheduleMaker(); + System.out.println(Constants.CHARLIE + Constants.FAREWELL); } } diff --git a/src/main/java/Constants.java b/src/main/java/Constants.java index eff97fb38..e9d508363 100644 --- a/src/main/java/Constants.java +++ b/src/main/java/Constants.java @@ -1,4 +1,21 @@ public class Constants { + public static final String LOGO = " _____ \n" + + " / \\ \n" + + " | O O | \n" + + " | \\___/ | \n" + + " \\_____/ \n" + + " /\\_____/\\ \n" + + " | | \n" + + " | | \n" + + " |_______| \n" + + " \n"; + public static final String CHARLIE = "Charlie: "; + + public static final String GREETING = "Hello! I'm ChattyCharlie, your consistent buddy.\n" + + " What shall we do today?\n"; + + public static final String FAREWELL = "All the best in clearing your list!"; + public static final String SPACE = " "; public static final String LINE = "------------"; } \ No newline at end of file From 01ea11fbe704153c0dae2d58356f87b2581f661d Mon Sep 17 00:00:00 2001 From: BevLow Date: Thu, 5 Sep 2024 13:50:07 +0800 Subject: [PATCH 18/50] Add A-TextIuTesting --- src/main/java/ChattyCharlie.java | 6 ++- src/main/java/List.java | 29 ++++++----- text-ui-test/EXPECTED.TXT | 84 +++++++++++++++++++++++++++++--- text-ui-test/input.txt | 12 +++++ text-ui-test/runtest.bat | 2 +- 5 files changed, 111 insertions(+), 22 deletions(-) diff --git a/src/main/java/ChattyCharlie.java b/src/main/java/ChattyCharlie.java index adba26efb..511a5a1ba 100644 --- a/src/main/java/ChattyCharlie.java +++ b/src/main/java/ChattyCharlie.java @@ -41,7 +41,8 @@ public static void ScheduleMaker() { //Echo as a function String deadlineDescription = deadlineParts[0].trim(); String by = deadlineParts[1].trim(); list.addTask(new Deadline(deadlineDescription, by)); - System.out.println(Constants.SPACE + "Added deadline: " + deadlineDescription + " (by: " + by + ")"); + System.out.println(Constants.SPACE + "Added deadline: " + + deadlineDescription + " (by: " + by + ")"); System.out.println(Constants.LINE); } break; @@ -56,7 +57,8 @@ public static void ScheduleMaker() { //Echo as a function //add the event list.addTask(new Event(description, startTime, endTime)); - System.out.println(Constants.SPACE + "Added event: " + description + " (from: " + startTime + ", to: " + endTime + ")"); + System.out.println(Constants.SPACE + "Added event: " + description + + " (from: " + startTime + ", to: " + endTime + ")"); System.out.println(Constants.LINE); break; diff --git a/src/main/java/List.java b/src/main/java/List.java index 2e3379f86..8f5668dc1 100644 --- a/src/main/java/List.java +++ b/src/main/java/List.java @@ -1,25 +1,25 @@ //LIST CLASS public class List { //make a list of task - private Task[] list; + private Task[] tasks; private int size; //constructor public List() { - list = new Task[100]; + tasks = new Task[100]; size = 0; } //Method to add an item to the list public void addTask(Task task) { //add the text into the list - list[size] = task; + tasks[size] = task; //account for the item size++; } public Task[] getList() { - return this.list; + return this.tasks; } public int getSize() { @@ -29,10 +29,10 @@ public int getSize() { //To mark public void mark(int index) { if (index >= 0 && index < size) { - list[index].markTask(); + tasks[index].markTask(); int remainingTask = countUnmarkedTasks(); System.out.println(Constants.SPACE + "Well Done! 1 task down, " + remainingTask + " to go."); - System.out.println(Constants.SPACE+ "[" + list[index].getMarkedStatus() + "] " + list[index].description); + System.out.println(Constants.SPACE+ "[" + tasks[index].getMarkedStatus() + "] " + tasks[index].description); } else { System.out.println(Constants.SPACE+ "Invalid task number."); } @@ -41,10 +41,10 @@ public void mark(int index) { //To unmark public void unmark(int index) { if (index >= 0 && index < size) { - list[index].unmarkTask(); + tasks[index].unmarkTask(); int remainingTask = countUnmarkedTasks(); System.out.println(Constants.SPACE + "Hmmm, not quite done yet, " + remainingTask + " to go."); - System.out.println(Constants.SPACE + "[" + list[index].getMarkedStatus() + "] " + list[index].description); + System.out.println(Constants.SPACE + "[" + tasks[index].getMarkedStatus() + "] " + tasks[index].description); } else { System.out.println(Constants.SPACE + "Invalid task number."); } @@ -58,22 +58,25 @@ public void printList() { System.out.println("pending Task: " + remainingTask); for (int i = 0; i < size; i++) { int number = i+1; - Task task = list[i]; + Task task = tasks[i]; //use a switch to determine switch (task.getType()) { case TODO: Todo todoTask = (Todo) task; - System.out.println(Constants.SPACE + number + ".[T][" + todoTask.getMarkedStatus() + "] " + todoTask.description); + System.out.println(Constants.SPACE + number + ".[T][" + todoTask.getMarkedStatus() + "] " + + todoTask.description); break; case DEADLINE: Deadline deadlineTask = (Deadline) task; - System.out.println(Constants.SPACE + number + ".[D][" + deadlineTask.getMarkedStatus() + "] " + deadlineTask.description + " (by: " + deadlineTask.by + ")"); + System.out.println(Constants.SPACE + number + ".[D][" + deadlineTask.getMarkedStatus() + "] " + + deadlineTask.description + " (by: " + deadlineTask.by + ")"); break; case EVENT: Event eventTask = (Event) task; - System.out.println(Constants.SPACE + number + ".[E][" + eventTask.getMarkedStatus() + "] " + eventTask.description + " (from: " + eventTask.start + " to: " + eventTask.end + ")"); + System.out.println(Constants.SPACE + number + ".[E][" + eventTask.getMarkedStatus() + "] " + + eventTask.description + " (from: " + eventTask.start + " to: " + eventTask.end + ")"); break; default: break; @@ -85,7 +88,7 @@ public void printList() { public int countUnmarkedTasks() { int count = 0; for (int i = 0; i < size; i++) { - if (!list[i].isDone) { + if (!tasks[i].isDone) { count++; } } diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 657e74f6e..096ca103b 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,7 +1,79 @@ -Hello from - ____ _ -| _ \ _ _| | _____ -| | | | | | | |/ / _ \ -| |_| | |_| | < __/ -|____/ \__,_|_|\_\___| + _____ + / \ + | O O | + | \___/ | + \_____/ + /\_____/\ + | | + | | + |_______| +Charlie: Hello! I'm ChattyCharlie, your consistent buddy. + What shall we do today? + +User: todo read book +------------ + Added todo: read book +------------ +User: deadline return book by 30th October +------------ + Added deadline: return book (by: 30th October) +------------ +User: event project meetings from 10th August 4pm to 6pm +------------ + Added event: project meetings (from: 10th August 4pm, to: 6pm) +------------ +User: todo run 10km +------------ + Added todo: run 10km +------------ +User: list +------------ +ToDo List: +pending Task: 4 + 1.[T][ ] read book + 2.[D][ ] return book (by: 30th October) + 3.[E][ ] project meetings (from: 10th August 4pm to: 6pm) + 4.[T][ ] run 10km +------------ +User: mark 1 +------------ + Well Done! 1 task down, 3 to go. + [X] read book +------------ +User: mark 3 +------------ + Well Done! 1 task down, 2 to go. + [X] project meetings +------------ +User: list +------------ +ToDo List: +pending Task: 2 + 1.[T][X] read book + 2.[D][ ] return book (by: 30th October) + 3.[E][X] project meetings (from: 10th August 4pm to: 6pm) + 4.[T][ ] run 10km +------------ +User: unmark 1 +------------ + Hmmm, not quite done yet, 3 to go. + [ ] read book +------------ +User: deadline do cs2113 coding by Sunday +------------ + Added deadline: do cs2113 coding (by: Sunday) +------------ +User: list +------------ +ToDo List: +pending Task: 4 + 1.[T][ ] read book + 2.[D][ ] return book (by: 30th October) + 3.[E][X] project meetings (from: 10th August 4pm to: 6pm) + 4.[T][ ] run 10km + 5.[D][ ] do cs2113 coding (by: Sunday) +------------ +User: bye +------------ +Charlie: All the best in clearing your list! \ No newline at end of file diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index e69de29bb..f7bdae954 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -0,0 +1,12 @@ +todo read book +deadline return book by 30th October +event project meeting from 10th August 4pm to 6pm +todo Run 10km +list +mark 1 +mark 3 +list +unmark 1 +deadline do cs2113 coding by Sunday +list +bye diff --git a/text-ui-test/runtest.bat b/text-ui-test/runtest.bat index 087374464..94d6a5778 100644 --- a/text-ui-test/runtest.bat +++ b/text-ui-test/runtest.bat @@ -15,7 +15,7 @@ IF ERRORLEVEL 1 ( REM no error here, errorlevel == 0 REM run the program, feed commands from input.txt file and redirect the output to the ACTUAL.TXT -java -classpath ..\bin Duke < input.txt > ACTUAL.TXT +java -classpath ..\bin ChattyCharlie < input.txt > ACTUAL.TXT REM compare the output to the expected output FC ACTUAL.TXT EXPECTED.TXT From 9893111ff843fbe27914abb9cbb8fbe43739cc81 Mon Sep 17 00:00:00 2001 From: BevLow Date: Thu, 5 Sep 2024 14:23:18 +0800 Subject: [PATCH 19/50] Add A-CodeQuality --- src/main/java/ChattyCharlie.java | 51 ++++++++++++------- src/main/java/List.java | 18 +++---- .../{Constants.java => StringDesign.java} | 4 +- 3 files changed, 45 insertions(+), 28 deletions(-) rename src/main/java/{Constants.java => StringDesign.java} (85%) diff --git a/src/main/java/ChattyCharlie.java b/src/main/java/ChattyCharlie.java index 511a5a1ba..e9bd2c139 100644 --- a/src/main/java/ChattyCharlie.java +++ b/src/main/java/ChattyCharlie.java @@ -5,7 +5,6 @@ public class ChattyCharlie { //MAIN ALGO public static void ScheduleMaker() { //Echo as a function String line; - String you = "User: "; //make the scanner Scanner in = new Scanner(System.in); @@ -16,9 +15,9 @@ public static void ScheduleMaker() { //Echo as a function //accept an insert while (true) { //takes in an input - System.out.print(you); + System.out.print(StringDesign.YOU); line = in.nextLine(); - System.out.println(Constants.LINE); + System.out.println(StringDesign.LINE); //get the first word to see the command type String firstWord = line.split(" ")[0]; @@ -29,25 +28,32 @@ public static void ScheduleMaker() { //Echo as a function //start the different command types switch (command) { case TODO: + //remove the words todo String todoDescription = line.substring(5).trim(); + //add the todo task list.addTask(new Todo(todoDescription)); - System.out.println(Constants.SPACE + "Added todo: " + todoDescription); - System.out.println(Constants.LINE); + //print + System.out.println(StringDesign.SPACE + "Added todo: " + todoDescription); + System.out.println(StringDesign.LINE); break; case DEADLINE: + //remove the deadline word and split into description and deadline time String[] deadlineParts = line.substring(9).trim().split(" by "); if (deadlineParts.length == 2) { //make sure that the string is only split into 2 String deadlineDescription = deadlineParts[0].trim(); String by = deadlineParts[1].trim(); + //add the deadline task list.addTask(new Deadline(deadlineDescription, by)); - System.out.println(Constants.SPACE + "Added deadline: " + //print + System.out.println(StringDesign.SPACE + "Added deadline: " + deadlineDescription + " (by: " + by + ")"); - System.out.println(Constants.LINE); + System.out.println(StringDesign.LINE); } break; case EVENT: + //remove the event word and split into the description and event times String[] eventParts = line.substring(6).trim().split("from"); String description = eventParts[0].trim(); //further split the array into the start and end times @@ -55,28 +61,35 @@ public static void ScheduleMaker() { //Echo as a function String startTime = eventTimes[0].trim(); String endTime = eventTimes[1].trim(); - //add the event + //add the event task list.addTask(new Event(description, startTime, endTime)); - System.out.println(Constants.SPACE + "Added event: " + description + //print + System.out.println(StringDesign.SPACE + "Added event: " + description + " (from: " + startTime + ", to: " + endTime + ")"); - System.out.println(Constants.LINE); + System.out.println(StringDesign.LINE); break; case MARK: + //remove the mark word String markIndex = line.substring(5).trim(); + //convert the string number into an int int markNo = Integer.parseInt(markIndex) -1; //convert to array //mark it list.mark(markNo); - System.out.println(Constants.LINE); + //print + System.out.println(StringDesign.LINE); break; case UNMARK: + //remove the unmark word String unmarkIndex = line.substring(7).trim(); - int unmarkNo = Integer.parseInt(unmarkIndex) -1; //convert to array + //convert the string no into a int + int unmarkNo = Integer.parseInt(unmarkIndex) -1; //mark it list.unmark(unmarkNo); - System.out.println(Constants.LINE); + //print + System.out.println(StringDesign.LINE); break; case BYE: @@ -84,23 +97,25 @@ public static void ScheduleMaker() { //Echo as a function case LIST: list.printList(); - System.out.println(Constants.LINE); + //print + System.out.println(StringDesign.LINE); break; default: //add the item list.addTask(new Task(line, CommandType.TODO)); //for cases without label, it is a Todo as well - System.out.println(Constants.SPACE + "Added: " + line); - System.out.println(Constants.LINE); + //print + System.out.println(StringDesign.SPACE + "Added: " + line); + System.out.println(StringDesign.LINE); break; } } } public static void main (String[]args){ - System.out.println(Constants.LOGO + Constants.CHARLIE + Constants.GREETING); + System.out.println(StringDesign.LOGO + StringDesign.CHARLIE + StringDesign.GREETING); ScheduleMaker(); - System.out.println(Constants.CHARLIE + Constants.FAREWELL); + System.out.println(StringDesign.CHARLIE + StringDesign.FAREWELL); } } diff --git a/src/main/java/List.java b/src/main/java/List.java index 8f5668dc1..c1f7b70a8 100644 --- a/src/main/java/List.java +++ b/src/main/java/List.java @@ -31,10 +31,10 @@ public void mark(int index) { if (index >= 0 && index < size) { tasks[index].markTask(); int remainingTask = countUnmarkedTasks(); - System.out.println(Constants.SPACE + "Well Done! 1 task down, " + remainingTask + " to go."); - System.out.println(Constants.SPACE+ "[" + tasks[index].getMarkedStatus() + "] " + tasks[index].description); + System.out.println(StringDesign.SPACE + "Well Done! 1 task down, " + remainingTask + " to go."); + System.out.println(StringDesign.SPACE+ "[" + tasks[index].getMarkedStatus() + "] " + tasks[index].description); } else { - System.out.println(Constants.SPACE+ "Invalid task number."); + System.out.println(StringDesign.SPACE+ "Invalid task number."); } } @@ -43,10 +43,10 @@ public void unmark(int index) { if (index >= 0 && index < size) { tasks[index].unmarkTask(); int remainingTask = countUnmarkedTasks(); - System.out.println(Constants.SPACE + "Hmmm, not quite done yet, " + remainingTask + " to go."); - System.out.println(Constants.SPACE + "[" + tasks[index].getMarkedStatus() + "] " + tasks[index].description); + System.out.println(StringDesign.SPACE + "Hmmm, not quite done yet, " + remainingTask + " to go."); + System.out.println(StringDesign.SPACE + "[" + tasks[index].getMarkedStatus() + "] " + tasks[index].description); } else { - System.out.println(Constants.SPACE + "Invalid task number."); + System.out.println(StringDesign.SPACE + "Invalid task number."); } } @@ -63,19 +63,19 @@ public void printList() { switch (task.getType()) { case TODO: Todo todoTask = (Todo) task; - System.out.println(Constants.SPACE + number + ".[T][" + todoTask.getMarkedStatus() + "] " + System.out.println(StringDesign.SPACE + number + ".[T][" + todoTask.getMarkedStatus() + "] " + todoTask.description); break; case DEADLINE: Deadline deadlineTask = (Deadline) task; - System.out.println(Constants.SPACE + number + ".[D][" + deadlineTask.getMarkedStatus() + "] " + System.out.println(StringDesign.SPACE + number + ".[D][" + deadlineTask.getMarkedStatus() + "] " + deadlineTask.description + " (by: " + deadlineTask.by + ")"); break; case EVENT: Event eventTask = (Event) task; - System.out.println(Constants.SPACE + number + ".[E][" + eventTask.getMarkedStatus() + "] " + System.out.println(StringDesign.SPACE + number + ".[E][" + eventTask.getMarkedStatus() + "] " + eventTask.description + " (from: " + eventTask.start + " to: " + eventTask.end + ")"); break; default: diff --git a/src/main/java/Constants.java b/src/main/java/StringDesign.java similarity index 85% rename from src/main/java/Constants.java rename to src/main/java/StringDesign.java index e9d508363..ab803ad44 100644 --- a/src/main/java/Constants.java +++ b/src/main/java/StringDesign.java @@ -1,4 +1,5 @@ -public class Constants { +public class StringDesign { + //this class is for all my Strings and designs public static final String LOGO = " _____ \n" + " / \\ \n" + " | O O | \n" @@ -18,4 +19,5 @@ public class Constants { public static final String SPACE = " "; public static final String LINE = "------------"; + public static final String YOU = "User: "; } \ No newline at end of file From 0573acf2f32089456e862b03ab527c5cf34d1c58 Mon Sep 17 00:00:00 2001 From: BevLow Date: Thu, 5 Sep 2024 15:16:44 +0800 Subject: [PATCH 20/50] Add A-CodeQuality --- src/main/java/ChattyCharlie.java | 150 +++++++++++++++---------------- src/main/java/List.java | 36 ++++---- 2 files changed, 88 insertions(+), 98 deletions(-) diff --git a/src/main/java/ChattyCharlie.java b/src/main/java/ChattyCharlie.java index e9bd2c139..606876f35 100644 --- a/src/main/java/ChattyCharlie.java +++ b/src/main/java/ChattyCharlie.java @@ -27,87 +27,79 @@ public static void ScheduleMaker() { //Echo as a function //start the different command types switch (command) { - case TODO: - //remove the words todo - String todoDescription = line.substring(5).trim(); - //add the todo task - list.addTask(new Todo(todoDescription)); + case TODO: + //remove the words todo + String todoDescription = line.substring(5).trim(); + //add the todo task + list.addTask(new Todo(todoDescription)); + //print + System.out.println(StringDesign.SPACE + "Added todo: " + todoDescription); + System.out.println(StringDesign.LINE); + break; + case DEADLINE: + //remove the deadline word and split into description and deadline time + String[] deadlineParts = line.substring(9).trim().split(" by "); + if (deadlineParts.length == 2) { //make sure that the string is only split into 2 + String deadlineDescription = deadlineParts[0].trim(); + String by = deadlineParts[1].trim(); + //add the deadline task + list.addTask(new Deadline(deadlineDescription, by)); //print - System.out.println(StringDesign.SPACE + "Added todo: " + todoDescription); + System.out.println(StringDesign.SPACE + "Added deadline: " + + deadlineDescription + " (by: " + by + ")"); System.out.println(StringDesign.LINE); - break; - - case DEADLINE: - //remove the deadline word and split into description and deadline time - String[] deadlineParts = line.substring(9).trim().split(" by "); - if (deadlineParts.length == 2) { //make sure that the string is only split into 2 - String deadlineDescription = deadlineParts[0].trim(); - String by = deadlineParts[1].trim(); - //add the deadline task - list.addTask(new Deadline(deadlineDescription, by)); - //print - System.out.println(StringDesign.SPACE + "Added deadline: " - + deadlineDescription + " (by: " + by + ")"); - System.out.println(StringDesign.LINE); - } - break; - - case EVENT: - //remove the event word and split into the description and event times - String[] eventParts = line.substring(6).trim().split("from"); - String description = eventParts[0].trim(); - //further split the array into the start and end times - String[] eventTimes = eventParts[1].trim().split(" to "); - String startTime = eventTimes[0].trim(); - String endTime = eventTimes[1].trim(); - - //add the event task - list.addTask(new Event(description, startTime, endTime)); - //print - System.out.println(StringDesign.SPACE + "Added event: " + description - + " (from: " + startTime + ", to: " + endTime + ")"); - System.out.println(StringDesign.LINE); - - break; - - case MARK: - //remove the mark word - String markIndex = line.substring(5).trim(); - //convert the string number into an int - int markNo = Integer.parseInt(markIndex) -1; //convert to array - //mark it - list.mark(markNo); - //print - System.out.println(StringDesign.LINE); - break; - - case UNMARK: - //remove the unmark word - String unmarkIndex = line.substring(7).trim(); - //convert the string no into a int - int unmarkNo = Integer.parseInt(unmarkIndex) -1; - //mark it - list.unmark(unmarkNo); - //print - System.out.println(StringDesign.LINE); - break; - - case BYE: - return; //just exit - - case LIST: - list.printList(); - //print - System.out.println(StringDesign.LINE); - break; - - default: - //add the item - list.addTask(new Task(line, CommandType.TODO)); //for cases without label, it is a Todo as well - //print - System.out.println(StringDesign.SPACE + "Added: " + line); - System.out.println(StringDesign.LINE); - break; + } + break; + case EVENT: + //remove the event word and split into the description and event times + String[] eventParts = line.substring(6).trim().split("from"); + String description = eventParts[0].trim(); + //further split the array into the start and end times + String[] eventTimes = eventParts[1].trim().split(" to "); + String startTime = eventTimes[0].trim(); + String endTime = eventTimes[1].trim(); + + //add the event task + list.addTask(new Event(description, startTime, endTime)); + //print + System.out.println(StringDesign.SPACE + "Added event: " + description + + " (from: " + startTime + ", to: " + endTime + ")"); + System.out.println(StringDesign.LINE); + break; + case MARK: + //remove the mark word + String markIndex = line.substring(5).trim(); + //convert the string number into an int + int markNo = Integer.parseInt(markIndex) -1; //convert to array + //mark it + list.mark(markNo); + //print + System.out.println(StringDesign.LINE); + break; + case UNMARK: + //remove the unmark word + String unmarkIndex = line.substring(7).trim(); + //convert the string no into a int + int unmarkNo = Integer.parseInt(unmarkIndex) -1; + //mark it + list.unmark(unmarkNo); + //print + System.out.println(StringDesign.LINE); + break; + case BYE: + return; //just exit + case LIST: + list.printList(); + //print + System.out.println(StringDesign.LINE); + break; + default: + //add the item + list.addTask(new Task(line, CommandType.TODO)); //for cases without label, it is a Todo as well + //print + System.out.println(StringDesign.SPACE + "Added: " + line); + System.out.println(StringDesign.LINE); + break; } } } diff --git a/src/main/java/List.java b/src/main/java/List.java index c1f7b70a8..609714477 100644 --- a/src/main/java/List.java +++ b/src/main/java/List.java @@ -61,25 +61,23 @@ public void printList() { Task task = tasks[i]; //use a switch to determine switch (task.getType()) { - case TODO: - Todo todoTask = (Todo) task; - System.out.println(StringDesign.SPACE + number + ".[T][" + todoTask.getMarkedStatus() + "] " - + todoTask.description); - break; - - case DEADLINE: - Deadline deadlineTask = (Deadline) task; - System.out.println(StringDesign.SPACE + number + ".[D][" + deadlineTask.getMarkedStatus() + "] " - + deadlineTask.description + " (by: " + deadlineTask.by + ")"); - break; - - case EVENT: - Event eventTask = (Event) task; - System.out.println(StringDesign.SPACE + number + ".[E][" + eventTask.getMarkedStatus() + "] " - + eventTask.description + " (from: " + eventTask.start + " to: " + eventTask.end + ")"); - break; - default: - break; + case TODO: + Todo todoTask = (Todo) task; + System.out.println(StringDesign.SPACE + number + ".[T][" + todoTask.getMarkedStatus() + "] " + + todoTask.description); + break; + case DEADLINE: + Deadline deadlineTask = (Deadline) task; + System.out.println(StringDesign.SPACE + number + ".[D][" + deadlineTask.getMarkedStatus() + "] " + + deadlineTask.description + " (by: " + deadlineTask.by + ")"); + break; + case EVENT: + Event eventTask = (Event) task; + System.out.println(StringDesign.SPACE + number + ".[E][" + eventTask.getMarkedStatus() + "] " + + eventTask.description + " (from: " + eventTask.start + " to: " + eventTask.end + ")"); + break; + default: + break; } } } From 2361592dab94192f3fb569086131839620fb6610 Mon Sep 17 00:00:00 2001 From: BevLow Date: Wed, 11 Sep 2024 01:54:08 +0800 Subject: [PATCH 21/50] Add Level-5 --- src/main/java/CharlieExceptions.java | 18 +++ src/main/java/ChattyCharlie.java | 210 ++++++++++++++++----------- 2 files changed, 144 insertions(+), 84 deletions(-) create mode 100644 src/main/java/CharlieExceptions.java diff --git a/src/main/java/CharlieExceptions.java b/src/main/java/CharlieExceptions.java new file mode 100644 index 000000000..0e9f53a76 --- /dev/null +++ b/src/main/java/CharlieExceptions.java @@ -0,0 +1,18 @@ +public class CharlieExceptions extends Exception{ + public CharlieExceptions(String message){ + super(message); + } + + // Static factory methods for common exceptions + public static CharlieExceptions missingDescription(CommandType command) { + return new CharlieExceptions("Oop, the task for " + command + " cannot be empty."); + } + + public static CharlieExceptions missingDeadline() { + return new CharlieExceptions("When is this due?"); + } + + public static CharlieExceptions missingTimes() { + return new CharlieExceptions("Your event is missing or incomplete!"); + } +} diff --git a/src/main/java/ChattyCharlie.java b/src/main/java/ChattyCharlie.java index 606876f35..e3be84928 100644 --- a/src/main/java/ChattyCharlie.java +++ b/src/main/java/ChattyCharlie.java @@ -3,108 +3,150 @@ public class ChattyCharlie { //MAIN ALGO - public static void ScheduleMaker() { //Echo as a function - String line; - + public static void ScheduleMaker() throws CharlieExceptions { //Echo as a function + String line = null; //make the scanner Scanner in = new Scanner(System.in); //create an instance of list class List list = new List(); - + CommandType command = null; //accept an insert while (true) { - //takes in an input - System.out.print(StringDesign.YOU); - line = in.nextLine(); - System.out.println(StringDesign.LINE); - - //get the first word to see the command type - String firstWord = line.split(" ")[0]; - - //make the string a command - CommandType command = CommandType.valueOf(firstWord.toUpperCase()); - - //start the different command types - switch (command) { - case TODO: - //remove the words todo - String todoDescription = line.substring(5).trim(); - //add the todo task - list.addTask(new Todo(todoDescription)); - //print - System.out.println(StringDesign.SPACE + "Added todo: " + todoDescription); + try { + //takes in an input + System.out.print(StringDesign.YOU); + line = in.nextLine(); System.out.println(StringDesign.LINE); - break; - case DEADLINE: - //remove the deadline word and split into description and deadline time - String[] deadlineParts = line.substring(9).trim().split(" by "); - if (deadlineParts.length == 2) { //make sure that the string is only split into 2 - String deadlineDescription = deadlineParts[0].trim(); - String by = deadlineParts[1].trim(); - //add the deadline task + + //get the first word to see the command type + String firstWord = line.split(" ")[0]; + + command = CommandType.valueOf(firstWord.toUpperCase()); + + //start the different command types + switch (command) { + case TODO: + //remove the words todo + String todoDescription = line.substring(4).trim(); + + // Check if the description is empty + if (todoDescription.isEmpty()) { + throw CharlieExceptions.missingDescription(command); + } + + //add the todo task + list.addTask(new Todo(todoDescription)); + //print + System.out.println(StringDesign.SPACE + "Added todo: " + todoDescription); + System.out.println(StringDesign.LINE); + break; + case DEADLINE: + //remove the deadline word and split into description and deadline time + String[] deadlineParts = line.substring(8).trim().split(" by "); + String deadlineDescription; + String by; + + //handle errors + if (deadlineParts[0].isEmpty()) { + throw CharlieExceptions.missingDescription(command); + } else if (deadlineParts.length < 2) { + throw CharlieExceptions.missingDeadline(); + } else { + deadlineDescription = deadlineParts[0].trim(); + } + + by = deadlineParts[1].trim(); + list.addTask(new Deadline(deadlineDescription, by)); + System.out.println(StringDesign.SPACE + "Added deadline: " + deadlineDescription + " (by: " + by + ")"); + System.out.println(StringDesign.LINE); + break; + case EVENT: + //remove the event word and split into the description and event times + String[] eventParts = line.substring(5).trim().split("from"); + String description; + String startTime; + String endTime; + + // Error handling for Events + if (eventParts[0].isEmpty()) { //no description + throw CharlieExceptions.missingDescription(command); + } else if (eventParts.length < 2) { //no from + throw CharlieExceptions.missingTimes(); + } else { + description = eventParts[0].trim(); + } + + String[] eventTimes = eventParts[1].trim().split(" to "); + + if (eventTimes.length < 2) { + throw CharlieExceptions.missingTimes(); //change this to no end date + } + + if (eventTimes[0].isEmpty() || eventTimes[1].isEmpty()) { + throw CharlieExceptions.missingTimes(); + } else { + startTime = eventTimes[0].trim(); + endTime = eventTimes[1].trim(); + } + + //add the event task + list.addTask(new Event(description, startTime, endTime)); + //print + System.out.println(StringDesign.SPACE + "Added event: " + description + + " (from: " + startTime + ", to: " + endTime + ")"); + System.out.println(StringDesign.LINE); + break; + case MARK: + //remove the mark word + String markIndex = line.substring(4).trim(); + //convert the string number into an int + int markNo = Integer.parseInt(markIndex) -1; //convert to array + //mark it + list.mark(markNo); + //print + System.out.println(StringDesign.LINE); + break; + case UNMARK: + //remove the unmark word + String unmarkIndex = line.substring(6).trim(); + //convert the string no into a int + int unmarkNo = Integer.parseInt(unmarkIndex) -1; + //mark it + list.unmark(unmarkNo); //print - System.out.println(StringDesign.SPACE + "Added deadline: " - + deadlineDescription + " (by: " + by + ")"); System.out.println(StringDesign.LINE); + break; + case BYE: + return; //just exit + case LIST: + list.printList(); + //print + System.out.println(StringDesign.LINE); + break; + default: + //add the item + list.addTask(new Task(line, CommandType.TODO)); //for cases without label, it is a Todo as well + //print + System.out.println(StringDesign.SPACE + "Added: " + line); + System.out.println(StringDesign.LINE); + break; } - break; - case EVENT: - //remove the event word and split into the description and event times - String[] eventParts = line.substring(6).trim().split("from"); - String description = eventParts[0].trim(); - //further split the array into the start and end times - String[] eventTimes = eventParts[1].trim().split(" to "); - String startTime = eventTimes[0].trim(); - String endTime = eventTimes[1].trim(); - - //add the event task - list.addTask(new Event(description, startTime, endTime)); - //print - System.out.println(StringDesign.SPACE + "Added event: " + description - + " (from: " + startTime + ", to: " + endTime + ")"); - System.out.println(StringDesign.LINE); - break; - case MARK: - //remove the mark word - String markIndex = line.substring(5).trim(); - //convert the string number into an int - int markNo = Integer.parseInt(markIndex) -1; //convert to array - //mark it - list.mark(markNo); - //print - System.out.println(StringDesign.LINE); - break; - case UNMARK: - //remove the unmark word - String unmarkIndex = line.substring(7).trim(); - //convert the string no into a int - int unmarkNo = Integer.parseInt(unmarkIndex) -1; - //mark it - list.unmark(unmarkNo); - //print - System.out.println(StringDesign.LINE); - break; - case BYE: - return; //just exit - case LIST: - list.printList(); - //print + } catch (CharlieExceptions e) { + // Handle custom exceptions and prompt for new input + System.out.println(e.getMessage()); System.out.println(StringDesign.LINE); - break; - default: - //add the item - list.addTask(new Task(line, CommandType.TODO)); //for cases without label, it is a Todo as well - //print - System.out.println(StringDesign.SPACE + "Added: " + line); + continue; // Continue to ask for input after throwing exception + } catch (IllegalArgumentException e) { + System.out.println("Oop, did you make a typo?"); System.out.println(StringDesign.LINE); - break; + continue; } } } - public static void main (String[]args){ + public static void main (String[]args) throws CharlieExceptions{ System.out.println(StringDesign.LOGO + StringDesign.CHARLIE + StringDesign.GREETING); ScheduleMaker(); System.out.println(StringDesign.CHARLIE + StringDesign.FAREWELL); From f5fcf141fd0e5029f5ce017a251f4941427c2835 Mon Sep 17 00:00:00 2001 From: BevLow Date: Wed, 11 Sep 2024 01:58:11 +0800 Subject: [PATCH 22/50] Add Level-5-MasterBranch --- src/main/java/ChattyCharlie.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/ChattyCharlie.java b/src/main/java/ChattyCharlie.java index 606876f35..59e9d84bc 100644 --- a/src/main/java/ChattyCharlie.java +++ b/src/main/java/ChattyCharlie.java @@ -53,16 +53,16 @@ public static void ScheduleMaker() { //Echo as a function case EVENT: //remove the event word and split into the description and event times String[] eventParts = line.substring(6).trim().split("from"); - String description = eventParts[0].trim(); + String eventDescription = eventParts[0].trim(); //further split the array into the start and end times String[] eventTimes = eventParts[1].trim().split(" to "); String startTime = eventTimes[0].trim(); String endTime = eventTimes[1].trim(); //add the event task - list.addTask(new Event(description, startTime, endTime)); + list.addTask(new Event(eventDescription, startTime, endTime)); //print - System.out.println(StringDesign.SPACE + "Added event: " + description + System.out.println(StringDesign.SPACE + "Added event: " + eventDescription + " (from: " + startTime + ", to: " + endTime + ")"); System.out.println(StringDesign.LINE); break; From 1996a83fe5e29656692b9019968680419f9c8bd6 Mon Sep 17 00:00:00 2001 From: BevLow Date: Wed, 11 Sep 2024 02:09:22 +0800 Subject: [PATCH 23/50] Add Level-5-MasterBranch --- src/main/java/ChattyCharlie.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/ChattyCharlie.java b/src/main/java/ChattyCharlie.java index 59e9d84bc..606876f35 100644 --- a/src/main/java/ChattyCharlie.java +++ b/src/main/java/ChattyCharlie.java @@ -53,16 +53,16 @@ public static void ScheduleMaker() { //Echo as a function case EVENT: //remove the event word and split into the description and event times String[] eventParts = line.substring(6).trim().split("from"); - String eventDescription = eventParts[0].trim(); + String description = eventParts[0].trim(); //further split the array into the start and end times String[] eventTimes = eventParts[1].trim().split(" to "); String startTime = eventTimes[0].trim(); String endTime = eventTimes[1].trim(); //add the event task - list.addTask(new Event(eventDescription, startTime, endTime)); + list.addTask(new Event(description, startTime, endTime)); //print - System.out.println(StringDesign.SPACE + "Added event: " + eventDescription + System.out.println(StringDesign.SPACE + "Added event: " + description + " (from: " + startTime + ", to: " + endTime + ")"); System.out.println(StringDesign.LINE); break; From 166d83b99b8dbed8807ff214f01324d4cf85fc3f Mon Sep 17 00:00:00 2001 From: BevLow Date: Wed, 11 Sep 2024 02:09:55 +0800 Subject: [PATCH 24/50] Add Level-5-MasterBranch --- src/main/java/ChattyCharlie.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ChattyCharlie.java b/src/main/java/ChattyCharlie.java index 606876f35..a714843e7 100644 --- a/src/main/java/ChattyCharlie.java +++ b/src/main/java/ChattyCharlie.java @@ -53,7 +53,7 @@ public static void ScheduleMaker() { //Echo as a function case EVENT: //remove the event word and split into the description and event times String[] eventParts = line.substring(6).trim().split("from"); - String description = eventParts[0].trim(); + String Description = eventParts[0].trim(); //further split the array into the start and end times String[] eventTimes = eventParts[1].trim().split(" to "); String startTime = eventTimes[0].trim(); From 9f1bc2c9b5968f142dcb895a810968cb319fb2c9 Mon Sep 17 00:00:00 2001 From: BevLow Date: Wed, 11 Sep 2024 02:10:05 +0800 Subject: [PATCH 25/50] Add Level-5-MasterBranch --- src/main/java/ChattyCharlie.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ChattyCharlie.java b/src/main/java/ChattyCharlie.java index a714843e7..606876f35 100644 --- a/src/main/java/ChattyCharlie.java +++ b/src/main/java/ChattyCharlie.java @@ -53,7 +53,7 @@ public static void ScheduleMaker() { //Echo as a function case EVENT: //remove the event word and split into the description and event times String[] eventParts = line.substring(6).trim().split("from"); - String Description = eventParts[0].trim(); + String description = eventParts[0].trim(); //further split the array into the start and end times String[] eventTimes = eventParts[1].trim().split(" to "); String startTime = eventTimes[0].trim(); From 56d0e22e778cd7a58b5844e52b36b7359cd4fc4c Mon Sep 17 00:00:00 2001 From: BevLow Date: Fri, 13 Sep 2024 00:55:13 +0800 Subject: [PATCH 26/50] Add A-Packages --- .../CharlieExceptions.java | 2 ++ .../{ => ChattyCharlie}/ChattyCharlie.java | 11 +++++----- .../java/{ => ChattyCharlie}/CommandType.java | 2 ++ src/main/java/{ => ChattyCharlie}/List.java | 21 ++++++++++++------- .../{ => ChattyCharlie}/StringDesign.java | 2 ++ .../{ => ChattyCharlie/Task}/Deadline.java | 4 ++++ .../java/{ => ChattyCharlie/Task}/Event.java | 4 ++++ .../java/{ => ChattyCharlie/Task}/Task.java | 10 ++++++++- .../java/{ => ChattyCharlie/Task}/Todo.java | 4 ++++ text-ui-test/runtest.bat | 4 ++-- 10 files changed, 49 insertions(+), 15 deletions(-) rename src/main/java/{ => ChattyCharlie}/CharlieExceptions.java (96%) rename src/main/java/{ => ChattyCharlie}/ChattyCharlie.java (95%) rename src/main/java/{ => ChattyCharlie}/CommandType.java (80%) rename src/main/java/{ => ChattyCharlie}/List.java (82%) rename src/main/java/{ => ChattyCharlie}/StringDesign.java (97%) rename src/main/java/{ => ChattyCharlie/Task}/Deadline.java (87%) rename src/main/java/{ => ChattyCharlie/Task}/Event.java (91%) rename src/main/java/{ => ChattyCharlie/Task}/Task.java (83%) rename src/main/java/{ => ChattyCharlie/Task}/Todo.java (86%) diff --git a/src/main/java/CharlieExceptions.java b/src/main/java/ChattyCharlie/CharlieExceptions.java similarity index 96% rename from src/main/java/CharlieExceptions.java rename to src/main/java/ChattyCharlie/CharlieExceptions.java index 0e9f53a76..399222da6 100644 --- a/src/main/java/CharlieExceptions.java +++ b/src/main/java/ChattyCharlie/CharlieExceptions.java @@ -1,3 +1,5 @@ +package ChattyCharlie; + public class CharlieExceptions extends Exception{ public CharlieExceptions(String message){ super(message); diff --git a/src/main/java/ChattyCharlie.java b/src/main/java/ChattyCharlie/ChattyCharlie.java similarity index 95% rename from src/main/java/ChattyCharlie.java rename to src/main/java/ChattyCharlie/ChattyCharlie.java index e3be84928..b78ea89b3 100644 --- a/src/main/java/ChattyCharlie.java +++ b/src/main/java/ChattyCharlie/ChattyCharlie.java @@ -1,3 +1,9 @@ +package ChattyCharlie; + +import ChattyCharlie.Task.Deadline; +import ChattyCharlie.Task.Event; +import ChattyCharlie.Task.Todo; + import java.util.Scanner; public class ChattyCharlie { @@ -126,11 +132,6 @@ public static void ScheduleMaker() throws CharlieExceptions { //Echo as a functi System.out.println(StringDesign.LINE); break; default: - //add the item - list.addTask(new Task(line, CommandType.TODO)); //for cases without label, it is a Todo as well - //print - System.out.println(StringDesign.SPACE + "Added: " + line); - System.out.println(StringDesign.LINE); break; } } catch (CharlieExceptions e) { diff --git a/src/main/java/CommandType.java b/src/main/java/ChattyCharlie/CommandType.java similarity index 80% rename from src/main/java/CommandType.java rename to src/main/java/ChattyCharlie/CommandType.java index 11ac0c293..867fb1665 100644 --- a/src/main/java/CommandType.java +++ b/src/main/java/ChattyCharlie/CommandType.java @@ -1,3 +1,5 @@ +package ChattyCharlie; + public enum CommandType { TODO, DEADLINE, diff --git a/src/main/java/List.java b/src/main/java/ChattyCharlie/List.java similarity index 82% rename from src/main/java/List.java rename to src/main/java/ChattyCharlie/List.java index 609714477..6c18f2d21 100644 --- a/src/main/java/List.java +++ b/src/main/java/ChattyCharlie/List.java @@ -1,4 +1,11 @@ - //LIST CLASS +package ChattyCharlie; + +import ChattyCharlie.Task.Deadline; +import ChattyCharlie.Task.Event; +import ChattyCharlie.Task.Task; +import ChattyCharlie.Task.Todo; + +//LIST CLASS public class List { //make a list of task private Task[] tasks; @@ -32,7 +39,7 @@ public void mark(int index) { tasks[index].markTask(); int remainingTask = countUnmarkedTasks(); System.out.println(StringDesign.SPACE + "Well Done! 1 task down, " + remainingTask + " to go."); - System.out.println(StringDesign.SPACE+ "[" + tasks[index].getMarkedStatus() + "] " + tasks[index].description); + System.out.println(StringDesign.SPACE+ "[" + tasks[index].getMarkedStatus() + "] " + tasks[index].getDescription()); } else { System.out.println(StringDesign.SPACE+ "Invalid task number."); } @@ -44,7 +51,7 @@ public void unmark(int index) { tasks[index].unmarkTask(); int remainingTask = countUnmarkedTasks(); System.out.println(StringDesign.SPACE + "Hmmm, not quite done yet, " + remainingTask + " to go."); - System.out.println(StringDesign.SPACE + "[" + tasks[index].getMarkedStatus() + "] " + tasks[index].description); + System.out.println(StringDesign.SPACE + "[" + tasks[index].getMarkedStatus() + "] " + tasks[index].getDescription()); } else { System.out.println(StringDesign.SPACE + "Invalid task number."); } @@ -64,17 +71,17 @@ public void printList() { case TODO: Todo todoTask = (Todo) task; System.out.println(StringDesign.SPACE + number + ".[T][" + todoTask.getMarkedStatus() + "] " - + todoTask.description); + + todoTask.getDescription()); break; case DEADLINE: Deadline deadlineTask = (Deadline) task; System.out.println(StringDesign.SPACE + number + ".[D][" + deadlineTask.getMarkedStatus() + "] " - + deadlineTask.description + " (by: " + deadlineTask.by + ")"); + + deadlineTask.getDescription() + " (by: " + deadlineTask.getBy() + ")"); break; case EVENT: Event eventTask = (Event) task; System.out.println(StringDesign.SPACE + number + ".[E][" + eventTask.getMarkedStatus() + "] " - + eventTask.description + " (from: " + eventTask.start + " to: " + eventTask.end + ")"); + + eventTask.getDescription() + " (from: " + eventTask.getStart() + " to: " + eventTask.getEnd() + ")"); break; default: break; @@ -86,7 +93,7 @@ public void printList() { public int countUnmarkedTasks() { int count = 0; for (int i = 0; i < size; i++) { - if (!tasks[i].isDone) { + if (!tasks[i].getIsDoneStatus()) { count++; } } diff --git a/src/main/java/StringDesign.java b/src/main/java/ChattyCharlie/StringDesign.java similarity index 97% rename from src/main/java/StringDesign.java rename to src/main/java/ChattyCharlie/StringDesign.java index ab803ad44..7a1f32aaa 100644 --- a/src/main/java/StringDesign.java +++ b/src/main/java/ChattyCharlie/StringDesign.java @@ -1,3 +1,5 @@ +package ChattyCharlie; + public class StringDesign { //this class is for all my Strings and designs public static final String LOGO = " _____ \n" diff --git a/src/main/java/Deadline.java b/src/main/java/ChattyCharlie/Task/Deadline.java similarity index 87% rename from src/main/java/Deadline.java rename to src/main/java/ChattyCharlie/Task/Deadline.java index 74c95fa8e..45aaeef1e 100644 --- a/src/main/java/Deadline.java +++ b/src/main/java/ChattyCharlie/Task/Deadline.java @@ -1,3 +1,7 @@ +package ChattyCharlie.Task; + +import ChattyCharlie.CommandType; + //Deadline Class public class Deadline extends Task { protected String by; diff --git a/src/main/java/Event.java b/src/main/java/ChattyCharlie/Task/Event.java similarity index 91% rename from src/main/java/Event.java rename to src/main/java/ChattyCharlie/Task/Event.java index ee987a046..e731c1215 100644 --- a/src/main/java/Event.java +++ b/src/main/java/ChattyCharlie/Task/Event.java @@ -1,3 +1,7 @@ +package ChattyCharlie.Task; + +import ChattyCharlie.CommandType; + //Events public class Event extends Task { protected String start; diff --git a/src/main/java/Task.java b/src/main/java/ChattyCharlie/Task/Task.java similarity index 83% rename from src/main/java/Task.java rename to src/main/java/ChattyCharlie/Task/Task.java index 942e066dd..cd00cd8b6 100644 --- a/src/main/java/Task.java +++ b/src/main/java/ChattyCharlie/Task/Task.java @@ -1,5 +1,9 @@ +package ChattyCharlie.Task; + +import ChattyCharlie.CommandType; + //TASK CLASS -public class Task { +public abstract class Task { protected String description; protected boolean isDone; protected CommandType type; @@ -16,6 +20,10 @@ public String getMarkedStatus() { return (isDone ? "X" : " "); } + public boolean getIsDoneStatus() { + return this.isDone; + } + public CommandType getType() { return type; } diff --git a/src/main/java/Todo.java b/src/main/java/ChattyCharlie/Task/Todo.java similarity index 86% rename from src/main/java/Todo.java rename to src/main/java/ChattyCharlie/Task/Todo.java index b20048308..891fcc843 100644 --- a/src/main/java/Todo.java +++ b/src/main/java/ChattyCharlie/Task/Todo.java @@ -1,3 +1,7 @@ +package ChattyCharlie.Task; + +import ChattyCharlie.CommandType; + //todo class public class Todo extends Task { protected boolean isDone; diff --git a/text-ui-test/runtest.bat b/text-ui-test/runtest.bat index 94d6a5778..27a5b7e7e 100644 --- a/text-ui-test/runtest.bat +++ b/text-ui-test/runtest.bat @@ -7,7 +7,7 @@ REM delete output from previous run if exist ACTUAL.TXT del ACTUAL.TXT REM compile the code into the bin folder -javac -cp ..\src\main\java -Xlint:none -d ..\bin ..\src\main\java\*.java +javac -cp ..\src\main\java -Xlint:none -d ..\bin ..\src\main\java\ChattyCharlie\*.java ..\src\main\java\ChattyCharlie\Task\*.java IF ERRORLEVEL 1 ( echo ********** BUILD FAILURE ********** exit /b 1 @@ -15,7 +15,7 @@ IF ERRORLEVEL 1 ( REM no error here, errorlevel == 0 REM run the program, feed commands from input.txt file and redirect the output to the ACTUAL.TXT -java -classpath ..\bin ChattyCharlie < input.txt > ACTUAL.TXT +java -classpath ..\bin ChattyCharlie.ChattyCharlie < input.txt > ACTUAL.TXT REM compare the output to the expected output FC ACTUAL.TXT EXPECTED.TXT From 3b757652e67efd64c3a2da469078f0bdb38efbcc Mon Sep 17 00:00:00 2001 From: BevLow Date: Wed, 18 Sep 2024 11:28:19 +0800 Subject: [PATCH 27/50] Add Level-5-bug fixes --- .../CharlieExceptions.java | 2 +- .../ChattyCharlie.java | 13 ++++++------- .../CommandType.java | 2 +- .../java/{ChattyCharlie => chattycharlie}/List.java | 10 +++++----- .../StringDesign.java | 2 +- .../Task => chattycharlie/task}/Deadline.java | 4 ++-- .../Task => chattycharlie/task}/Event.java | 4 ++-- .../Task => chattycharlie/task}/Task.java | 4 ++-- .../Task => chattycharlie/task}/Todo.java | 4 ++-- 9 files changed, 22 insertions(+), 23 deletions(-) rename src/main/java/{ChattyCharlie => chattycharlie}/CharlieExceptions.java (96%) rename src/main/java/{ChattyCharlie => chattycharlie}/ChattyCharlie.java (96%) rename src/main/java/{ChattyCharlie => chattycharlie}/CommandType.java (81%) rename src/main/java/{ChattyCharlie => chattycharlie}/List.java (95%) rename src/main/java/{ChattyCharlie => chattycharlie}/StringDesign.java (97%) rename src/main/java/{ChattyCharlie/Task => chattycharlie/task}/Deadline.java (87%) rename src/main/java/{ChattyCharlie/Task => chattycharlie/task}/Event.java (91%) rename src/main/java/{ChattyCharlie/Task => chattycharlie/task}/Task.java (93%) rename src/main/java/{ChattyCharlie/Task => chattycharlie/task}/Todo.java (87%) diff --git a/src/main/java/ChattyCharlie/CharlieExceptions.java b/src/main/java/chattycharlie/CharlieExceptions.java similarity index 96% rename from src/main/java/ChattyCharlie/CharlieExceptions.java rename to src/main/java/chattycharlie/CharlieExceptions.java index 399222da6..cbb9e27e7 100644 --- a/src/main/java/ChattyCharlie/CharlieExceptions.java +++ b/src/main/java/chattycharlie/CharlieExceptions.java @@ -1,4 +1,4 @@ -package ChattyCharlie; +package chattycharlie; public class CharlieExceptions extends Exception{ public CharlieExceptions(String message){ diff --git a/src/main/java/ChattyCharlie/ChattyCharlie.java b/src/main/java/chattycharlie/ChattyCharlie.java similarity index 96% rename from src/main/java/ChattyCharlie/ChattyCharlie.java rename to src/main/java/chattycharlie/ChattyCharlie.java index b78ea89b3..f6462642f 100644 --- a/src/main/java/ChattyCharlie/ChattyCharlie.java +++ b/src/main/java/chattycharlie/ChattyCharlie.java @@ -1,15 +1,14 @@ -package ChattyCharlie; +package chattycharlie; -import ChattyCharlie.Task.Deadline; -import ChattyCharlie.Task.Event; -import ChattyCharlie.Task.Todo; +import chattycharlie.task.Deadline; +import chattycharlie.task.Event; +import chattycharlie.task.Todo; import java.util.Scanner; public class ChattyCharlie { - //MAIN ALGO - public static void ScheduleMaker() throws CharlieExceptions { //Echo as a function + public static void scheduleMaker() throws CharlieExceptions { //Echo as a function String line = null; //make the scanner Scanner in = new Scanner(System.in); @@ -149,7 +148,7 @@ public static void ScheduleMaker() throws CharlieExceptions { //Echo as a functi public static void main (String[]args) throws CharlieExceptions{ System.out.println(StringDesign.LOGO + StringDesign.CHARLIE + StringDesign.GREETING); - ScheduleMaker(); + scheduleMaker(); System.out.println(StringDesign.CHARLIE + StringDesign.FAREWELL); } diff --git a/src/main/java/ChattyCharlie/CommandType.java b/src/main/java/chattycharlie/CommandType.java similarity index 81% rename from src/main/java/ChattyCharlie/CommandType.java rename to src/main/java/chattycharlie/CommandType.java index 867fb1665..3eb29b546 100644 --- a/src/main/java/ChattyCharlie/CommandType.java +++ b/src/main/java/chattycharlie/CommandType.java @@ -1,4 +1,4 @@ -package ChattyCharlie; +package chattycharlie; public enum CommandType { TODO, diff --git a/src/main/java/ChattyCharlie/List.java b/src/main/java/chattycharlie/List.java similarity index 95% rename from src/main/java/ChattyCharlie/List.java rename to src/main/java/chattycharlie/List.java index 6c18f2d21..d5fe3c453 100644 --- a/src/main/java/ChattyCharlie/List.java +++ b/src/main/java/chattycharlie/List.java @@ -1,9 +1,9 @@ -package ChattyCharlie; +package chattycharlie; -import ChattyCharlie.Task.Deadline; -import ChattyCharlie.Task.Event; -import ChattyCharlie.Task.Task; -import ChattyCharlie.Task.Todo; +import chattycharlie.task.Deadline; +import chattycharlie.task.Event; +import chattycharlie.task.Task; +import chattycharlie.task.Todo; //LIST CLASS public class List { diff --git a/src/main/java/ChattyCharlie/StringDesign.java b/src/main/java/chattycharlie/StringDesign.java similarity index 97% rename from src/main/java/ChattyCharlie/StringDesign.java rename to src/main/java/chattycharlie/StringDesign.java index 7a1f32aaa..bc499bce5 100644 --- a/src/main/java/ChattyCharlie/StringDesign.java +++ b/src/main/java/chattycharlie/StringDesign.java @@ -1,4 +1,4 @@ -package ChattyCharlie; +package chattycharlie; public class StringDesign { //this class is for all my Strings and designs diff --git a/src/main/java/ChattyCharlie/Task/Deadline.java b/src/main/java/chattycharlie/task/Deadline.java similarity index 87% rename from src/main/java/ChattyCharlie/Task/Deadline.java rename to src/main/java/chattycharlie/task/Deadline.java index 45aaeef1e..4b0f5c496 100644 --- a/src/main/java/ChattyCharlie/Task/Deadline.java +++ b/src/main/java/chattycharlie/task/Deadline.java @@ -1,6 +1,6 @@ -package ChattyCharlie.Task; +package chattycharlie.task; -import ChattyCharlie.CommandType; +import chattycharlie.CommandType; //Deadline Class public class Deadline extends Task { diff --git a/src/main/java/ChattyCharlie/Task/Event.java b/src/main/java/chattycharlie/task/Event.java similarity index 91% rename from src/main/java/ChattyCharlie/Task/Event.java rename to src/main/java/chattycharlie/task/Event.java index e731c1215..fa1c4e981 100644 --- a/src/main/java/ChattyCharlie/Task/Event.java +++ b/src/main/java/chattycharlie/task/Event.java @@ -1,6 +1,6 @@ -package ChattyCharlie.Task; +package chattycharlie.task; -import ChattyCharlie.CommandType; +import chattycharlie.CommandType; //Events public class Event extends Task { diff --git a/src/main/java/ChattyCharlie/Task/Task.java b/src/main/java/chattycharlie/task/Task.java similarity index 93% rename from src/main/java/ChattyCharlie/Task/Task.java rename to src/main/java/chattycharlie/task/Task.java index cd00cd8b6..9772d80b3 100644 --- a/src/main/java/ChattyCharlie/Task/Task.java +++ b/src/main/java/chattycharlie/task/Task.java @@ -1,6 +1,6 @@ -package ChattyCharlie.Task; +package chattycharlie.task; -import ChattyCharlie.CommandType; +import chattycharlie.CommandType; //TASK CLASS public abstract class Task { diff --git a/src/main/java/ChattyCharlie/Task/Todo.java b/src/main/java/chattycharlie/task/Todo.java similarity index 87% rename from src/main/java/ChattyCharlie/Task/Todo.java rename to src/main/java/chattycharlie/task/Todo.java index 891fcc843..1e7c06871 100644 --- a/src/main/java/ChattyCharlie/Task/Todo.java +++ b/src/main/java/chattycharlie/task/Todo.java @@ -1,6 +1,6 @@ -package ChattyCharlie.Task; +package chattycharlie.task; -import ChattyCharlie.CommandType; +import chattycharlie.CommandType; //todo class public class Todo extends Task { From b63bd200978cc7dd96440a45c18f14544bbbe083 Mon Sep 17 00:00:00 2001 From: BevLow Date: Fri, 20 Sep 2024 10:16:03 +0800 Subject: [PATCH 28/50] Add Level-6+A-Collections --- src/main/java/META-INF/MANIFEST.MF | 3 ++ .../java/chattycharlie/CharlieExceptions.java | 8 ++++ .../java/chattycharlie/ChattyCharlie.java | 11 ++++++ src/main/java/chattycharlie/CommandType.java | 3 +- src/main/java/chattycharlie/List.java | 38 ++++++++++++++----- src/main/java/chattycharlie/task/Task.java | 1 + 6 files changed, 53 insertions(+), 11 deletions(-) create mode 100644 src/main/java/META-INF/MANIFEST.MF diff --git a/src/main/java/META-INF/MANIFEST.MF b/src/main/java/META-INF/MANIFEST.MF new file mode 100644 index 000000000..2056cd354 --- /dev/null +++ b/src/main/java/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: chattycharlie.ChattyCharlie + diff --git a/src/main/java/chattycharlie/CharlieExceptions.java b/src/main/java/chattycharlie/CharlieExceptions.java index cbb9e27e7..ca11e8917 100644 --- a/src/main/java/chattycharlie/CharlieExceptions.java +++ b/src/main/java/chattycharlie/CharlieExceptions.java @@ -17,4 +17,12 @@ public static CharlieExceptions missingDeadline() { public static CharlieExceptions missingTimes() { return new CharlieExceptions("Your event is missing or incomplete!"); } + + public static CharlieExceptions missingDelete() { + return new CharlieExceptions("You forgot to specify which task."); + } + + public static CharlieExceptions deleteIndexOutOfBound() { + return new CharlieExceptions("Did you make a typo, that task does not exist!"); + } } diff --git a/src/main/java/chattycharlie/ChattyCharlie.java b/src/main/java/chattycharlie/ChattyCharlie.java index f6462642f..430cb2fe1 100644 --- a/src/main/java/chattycharlie/ChattyCharlie.java +++ b/src/main/java/chattycharlie/ChattyCharlie.java @@ -130,6 +130,17 @@ public static void scheduleMaker() throws CharlieExceptions { //Echo as a functi //print System.out.println(StringDesign.LINE); break; + case DELETE: + String deleteIndex = line.substring(7).trim(); + if (deleteIndex == null) { + throw CharlieExceptions.missingDelete(); + } + int deleteNo = Integer.parseInt(deleteIndex) - 1; + if(deleteNo > list.getSize() || deleteNo < 0) { + throw CharlieExceptions.deleteIndexOutOfBound(); + } + //delete the task + list.delete(deleteNo); default: break; } diff --git a/src/main/java/chattycharlie/CommandType.java b/src/main/java/chattycharlie/CommandType.java index 3eb29b546..d19500521 100644 --- a/src/main/java/chattycharlie/CommandType.java +++ b/src/main/java/chattycharlie/CommandType.java @@ -7,5 +7,6 @@ public enum CommandType { MARK, UNMARK, BYE, - LIST + LIST, + DELETE } \ No newline at end of file diff --git a/src/main/java/chattycharlie/List.java b/src/main/java/chattycharlie/List.java index d5fe3c453..da99b36d0 100644 --- a/src/main/java/chattycharlie/List.java +++ b/src/main/java/chattycharlie/List.java @@ -1,5 +1,7 @@ package chattycharlie; +import java.sql.SQLOutput; +import java.util.ArrayList; import chattycharlie.task.Deadline; import chattycharlie.task.Event; import chattycharlie.task.Task; @@ -8,24 +10,24 @@ //LIST CLASS public class List { //make a list of task - private Task[] tasks; + private ArrayList tasks; private int size; //constructor public List() { - tasks = new Task[100]; + tasks = new ArrayList(); size = 0; } //Method to add an item to the list public void addTask(Task task) { //add the text into the list - tasks[size] = task; + tasks.add(task); //account for the item size++; } - public Task[] getList() { + public ArrayList getList() { return this.tasks; } @@ -36,10 +38,10 @@ public int getSize() { //To mark public void mark(int index) { if (index >= 0 && index < size) { - tasks[index].markTask(); + tasks.get(index).markTask(); int remainingTask = countUnmarkedTasks(); System.out.println(StringDesign.SPACE + "Well Done! 1 task down, " + remainingTask + " to go."); - System.out.println(StringDesign.SPACE+ "[" + tasks[index].getMarkedStatus() + "] " + tasks[index].getDescription()); + System.out.println(StringDesign.SPACE+ "[" + tasks.get(index).getType() + "][" + tasks.get(index).getMarkedStatus() + "] " + tasks.get(index).getDescription()); } else { System.out.println(StringDesign.SPACE+ "Invalid task number."); } @@ -48,15 +50,31 @@ public void mark(int index) { //To unmark public void unmark(int index) { if (index >= 0 && index < size) { - tasks[index].unmarkTask(); + tasks.get(index).unmarkTask(); int remainingTask = countUnmarkedTasks(); System.out.println(StringDesign.SPACE + "Hmmm, not quite done yet, " + remainingTask + " to go."); - System.out.println(StringDesign.SPACE + "[" + tasks[index].getMarkedStatus() + "] " + tasks[index].getDescription()); + System.out.println(StringDesign.SPACE + "[" + tasks.get(index).getType() + "][" + tasks.get(index).getMarkedStatus() + "] " + tasks.get(index).getDescription()); } else { System.out.println(StringDesign.SPACE + "Invalid task number."); } } + //To delete + public void delete(int index) { + if (index >= 0 && index < size) { + int remainingTask; + if(tasks.get(index).getIsDoneStatus()) { + remainingTask = countUnmarkedTasks(); + } else { + remainingTask = countUnmarkedTasks() -1; + } + System.out.println(StringDesign.SPACE + "Task is removed." + " Pending task: " + remainingTask); + System.out.println(StringDesign.SPACE + "[" + tasks.get(index).getType() + "][" + tasks.get(index).getMarkedStatus() + "] " + tasks.get(index).getDescription()); + tasks.remove(index); + size--; + } + } + //To print list public void printList() { //print all @@ -65,7 +83,7 @@ public void printList() { System.out.println("pending Task: " + remainingTask); for (int i = 0; i < size; i++) { int number = i+1; - Task task = tasks[i]; + Task task = tasks.get(i); //use a switch to determine switch (task.getType()) { case TODO: @@ -93,7 +111,7 @@ public void printList() { public int countUnmarkedTasks() { int count = 0; for (int i = 0; i < size; i++) { - if (!tasks[i].getIsDoneStatus()) { + if (!tasks.get(i).getIsDoneStatus()) { count++; } } diff --git a/src/main/java/chattycharlie/task/Task.java b/src/main/java/chattycharlie/task/Task.java index 9772d80b3..692c3235d 100644 --- a/src/main/java/chattycharlie/task/Task.java +++ b/src/main/java/chattycharlie/task/Task.java @@ -41,6 +41,7 @@ public void unmarkTask() { this.isDone = false; //change the variable } + public String toString() { return "[" + getMarkedStatus() + "] " + description; } From 79a8871eafb51f6feb92bb3e38c6ecd034f6132c Mon Sep 17 00:00:00 2001 From: BevLow Date: Fri, 20 Sep 2024 11:06:04 +0800 Subject: [PATCH 29/50] Add Level-6+A-Collections --- src/main/java/chattycharlie/ChattyCharlie.java | 2 ++ src/main/java/chattycharlie/List.java | 3 +-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/chattycharlie/ChattyCharlie.java b/src/main/java/chattycharlie/ChattyCharlie.java index 430cb2fe1..7dfdbe4d3 100644 --- a/src/main/java/chattycharlie/ChattyCharlie.java +++ b/src/main/java/chattycharlie/ChattyCharlie.java @@ -15,6 +15,8 @@ public static void scheduleMaker() throws CharlieExceptions { //Echo as a functi //create an instance of list class List list = new List(); + // import the file to list + CommandType command = null; //accept an insert while (true) { diff --git a/src/main/java/chattycharlie/List.java b/src/main/java/chattycharlie/List.java index da99b36d0..8984866cd 100644 --- a/src/main/java/chattycharlie/List.java +++ b/src/main/java/chattycharlie/List.java @@ -1,11 +1,10 @@ package chattycharlie; -import java.sql.SQLOutput; -import java.util.ArrayList; import chattycharlie.task.Deadline; import chattycharlie.task.Event; import chattycharlie.task.Task; import chattycharlie.task.Todo; +import java.util.ArrayList; //LIST CLASS public class List { From 3d1361d279b12f6ba19508dc058e0767e5cea3a4 Mon Sep 17 00:00:00 2001 From: BevLow Date: Sun, 22 Sep 2024 14:20:51 +0800 Subject: [PATCH 30/50] Add Level-7 --- .../java/chattycharlie/ChattyCharlie.java | 9 +- src/main/java/chattycharlie/List.java | 117 ++++++++++++++++-- src/main/java/chattycharlie/task/Task.java | 1 + src/main/java/chattycharlie/task/Todo.java | 2 - 4 files changed, 115 insertions(+), 14 deletions(-) diff --git a/src/main/java/chattycharlie/ChattyCharlie.java b/src/main/java/chattycharlie/ChattyCharlie.java index f6462642f..2f45084d6 100644 --- a/src/main/java/chattycharlie/ChattyCharlie.java +++ b/src/main/java/chattycharlie/ChattyCharlie.java @@ -10,13 +10,17 @@ public class ChattyCharlie { public static void scheduleMaker() throws CharlieExceptions { //Echo as a function String line = null; + CommandType command = null; //make the scanner Scanner in = new Scanner(System.in); //create an instance of list class List list = new List(); - CommandType command = null; - //accept an insert + + //read in the file + list.readTaskFromFile("text.txt"); + + while (true) { try { //takes in an input @@ -124,6 +128,7 @@ public static void scheduleMaker() throws CharlieExceptions { //Echo as a functi System.out.println(StringDesign.LINE); break; case BYE: + list.saveTasksToFile("text.txt"); return; //just exit case LIST: list.printList(); diff --git a/src/main/java/chattycharlie/List.java b/src/main/java/chattycharlie/List.java index d5fe3c453..169e7a470 100644 --- a/src/main/java/chattycharlie/List.java +++ b/src/main/java/chattycharlie/List.java @@ -4,6 +4,11 @@ import chattycharlie.task.Event; import chattycharlie.task.Task; import chattycharlie.task.Todo; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Scanner; //LIST CLASS public class List { @@ -36,10 +41,11 @@ public int getSize() { //To mark public void mark(int index) { if (index >= 0 && index < size) { - tasks[index].markTask(); + Task task = tasks[index]; + task.markTask(); int remainingTask = countUnmarkedTasks(); System.out.println(StringDesign.SPACE + "Well Done! 1 task down, " + remainingTask + " to go."); - System.out.println(StringDesign.SPACE+ "[" + tasks[index].getMarkedStatus() + "] " + tasks[index].getDescription()); + System.out.println(StringDesign.SPACE+ task); } else { System.out.println(StringDesign.SPACE+ "Invalid task number."); } @@ -48,10 +54,11 @@ public void mark(int index) { //To unmark public void unmark(int index) { if (index >= 0 && index < size) { - tasks[index].unmarkTask(); + Task task = tasks[index]; + task.unmarkTask(); int remainingTask = countUnmarkedTasks(); System.out.println(StringDesign.SPACE + "Hmmm, not quite done yet, " + remainingTask + " to go."); - System.out.println(StringDesign.SPACE + "[" + tasks[index].getMarkedStatus() + "] " + tasks[index].getDescription()); + System.out.println(StringDesign.SPACE + task); } else { System.out.println(StringDesign.SPACE + "Invalid task number."); } @@ -70,18 +77,15 @@ public void printList() { switch (task.getType()) { case TODO: Todo todoTask = (Todo) task; - System.out.println(StringDesign.SPACE + number + ".[T][" + todoTask.getMarkedStatus() + "] " - + todoTask.getDescription()); + System.out.println(StringDesign.SPACE + number + todoTask); break; case DEADLINE: Deadline deadlineTask = (Deadline) task; - System.out.println(StringDesign.SPACE + number + ".[D][" + deadlineTask.getMarkedStatus() + "] " - + deadlineTask.getDescription() + " (by: " + deadlineTask.getBy() + ")"); + System.out.println(StringDesign.SPACE + number + deadlineTask); break; case EVENT: Event eventTask = (Event) task; - System.out.println(StringDesign.SPACE + number + ".[E][" + eventTask.getMarkedStatus() + "] " - + eventTask.getDescription() + " (from: " + eventTask.getStart() + " to: " + eventTask.getEnd() + ")"); + System.out.println(StringDesign.SPACE + number + eventTask); break; default: break; @@ -99,4 +103,97 @@ public int countUnmarkedTasks() { } return count; } + + //read in a file + public void readTaskFromFile(String filename) { + File file = new File(filename); + + try { + Scanner scanner = new Scanner(file); + + while (scanner.hasNextLine()) { + String taskText = scanner.nextLine(); + //create task object from the text line + parseTaskFromText(taskText); + } + scanner.close(); + System.out.println(StringDesign.CHARLIE + "Task have been loaded from: " + filename); + } catch (FileNotFoundException e) { + System.out.println("Oh first time here? Welcome to a life of Productivity, lets start!"); + } + } + + // converting text to task + public void parseTaskFromText(String taskText) { + taskText = taskText.trim(); //trim away the formatting + char taskType = taskText.charAt(1); //get the commandType + boolean isMarked = taskText.charAt(4) == 'X'; //get status for marked + String description; + if (taskType == 'T') { + description = taskText.substring(7).trim(); + } else { + int parenIndex = taskText.indexOf('('); + description = taskText.substring(7, parenIndex).trim(); // Get description before '(' + } + Task task; + switch (taskType) { + case 'T': + task = new Todo(description); + if (isMarked) { + task.markTask(); + } + addTask(task); + break; + case 'D': + String by = taskText.substring(taskText.indexOf("(by: ") + 5, taskText.length() - 1).trim(); + task = new Deadline(description, by); // Add Deadline task + //check if its marked + if(isMarked) { + task.markTask(); + } + addTask(task); + break; + case 'E': + String eventInfo = taskText.substring(taskText.indexOf("(from: ") + 7, taskText.length() - 1).trim(); + String[] eventTimes = eventInfo.split(" to: "); + if (eventTimes.length == 2) { + String startTime = eventTimes[0].trim(); + String endTime = eventTimes[1].trim(); + task = new Event(description, startTime, endTime); // Add Event task + if (isMarked) { + task.markTask(); + } + addTask(task); + } else { + System.out.println("Invalid event time format: " + taskText); + } + break; + default: + throw new IllegalArgumentException("Unknown task type"); + } + } + + //to save a file (called before the program ends) + public void saveTasksToFile(String filename) { + File file = new File(filename); + + try { + FileWriter writer = new FileWriter(file); + + for (Task task : tasks) { + if (task != null) { + writer.write(taskToString(task) + "\n"); + } + } + + writer.close(); + System.out.println(StringDesign.CHARLIE + "We saved your file in: " + filename); + } catch (IOException e) { + System.out.println("An error has occured when saving tasks"); + } + } + + public String taskToString(Task task) { + return StringDesign.SPACE + task; + } } \ No newline at end of file diff --git a/src/main/java/chattycharlie/task/Task.java b/src/main/java/chattycharlie/task/Task.java index 9772d80b3..58998502b 100644 --- a/src/main/java/chattycharlie/task/Task.java +++ b/src/main/java/chattycharlie/task/Task.java @@ -44,4 +44,5 @@ public void unmarkTask() { public String toString() { return "[" + getMarkedStatus() + "] " + description; } + } \ No newline at end of file diff --git a/src/main/java/chattycharlie/task/Todo.java b/src/main/java/chattycharlie/task/Todo.java index 1e7c06871..f3a967b8c 100644 --- a/src/main/java/chattycharlie/task/Todo.java +++ b/src/main/java/chattycharlie/task/Todo.java @@ -4,11 +4,9 @@ //todo class public class Todo extends Task { - protected boolean isDone; public Todo(String description) { super(description, CommandType.TODO); - isDone = false; } public void setDone(boolean done) { isDone = done; From 91f00e25886c0cfafe6c9f11734f3746488ec62f Mon Sep 17 00:00:00 2001 From: BevLow Date: Sun, 22 Sep 2024 14:50:00 +0800 Subject: [PATCH 31/50] Add Level-7-bug-fixes --- src/main/java/chattycharlie/List.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/chattycharlie/List.java b/src/main/java/chattycharlie/List.java index a0df6a518..99ba9081e 100644 --- a/src/main/java/chattycharlie/List.java +++ b/src/main/java/chattycharlie/List.java @@ -45,7 +45,7 @@ public void mark(int index) { tasks.get(index).markTask(); int remainingTask = countUnmarkedTasks(); System.out.println(StringDesign.SPACE + "Well Done! 1 task down, " + remainingTask + " to go."); - System.out.println(StringDesign.SPACE+ "[" + tasks.get(index).getType() + "][" + tasks.get(index).getMarkedStatus() + "] " + tasks.get(index).getDescription()); + System.out.println(StringDesign.SPACE+ tasks.get(index).toString()); } else { System.out.println(StringDesign.SPACE+ "Invalid task number."); } @@ -57,7 +57,7 @@ public void unmark(int index) { tasks.get(index).unmarkTask(); int remainingTask = countUnmarkedTasks(); System.out.println(StringDesign.SPACE + "Hmmm, not quite done yet, " + remainingTask + " to go."); - System.out.println(StringDesign.SPACE + "[" + tasks.get(index).getType() + "][" + tasks.get(index).getMarkedStatus() + "] " + tasks.get(index).getDescription()); + System.out.println(StringDesign.SPACE + tasks.get(index).toString()); } else { System.out.println(StringDesign.SPACE + "Invalid task number."); } @@ -73,7 +73,7 @@ public void delete(int index) { remainingTask = countUnmarkedTasks() -1; } System.out.println(StringDesign.SPACE + "Task is removed." + " Pending task: " + remainingTask); - System.out.println(StringDesign.SPACE + "[" + tasks.get(index).getType() + "][" + tasks.get(index).getMarkedStatus() + "] " + tasks.get(index).getDescription()); + System.out.println(StringDesign.SPACE + tasks.get(index).toString()); tasks.remove(index); size--; } From e7f658875021c3a01c5a6fa573e1a50ebe75bc93 Mon Sep 17 00:00:00 2001 From: BevLow Date: Sun, 22 Sep 2024 14:52:25 +0800 Subject: [PATCH 32/50] Add A-collections --- src/main/java/chattycharlie/List.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/chattycharlie/List.java b/src/main/java/chattycharlie/List.java index 8984866cd..85981cbca 100644 --- a/src/main/java/chattycharlie/List.java +++ b/src/main/java/chattycharlie/List.java @@ -40,7 +40,7 @@ public void mark(int index) { tasks.get(index).markTask(); int remainingTask = countUnmarkedTasks(); System.out.println(StringDesign.SPACE + "Well Done! 1 task down, " + remainingTask + " to go."); - System.out.println(StringDesign.SPACE+ "[" + tasks.get(index).getType() + "][" + tasks.get(index).getMarkedStatus() + "] " + tasks.get(index).getDescription()); + System.out.println(StringDesign.SPACE+ tasks.get(index).toString()); } else { System.out.println(StringDesign.SPACE+ "Invalid task number."); } @@ -52,7 +52,7 @@ public void unmark(int index) { tasks.get(index).unmarkTask(); int remainingTask = countUnmarkedTasks(); System.out.println(StringDesign.SPACE + "Hmmm, not quite done yet, " + remainingTask + " to go."); - System.out.println(StringDesign.SPACE + "[" + tasks.get(index).getType() + "][" + tasks.get(index).getMarkedStatus() + "] " + tasks.get(index).getDescription()); + System.out.println(StringDesign.SPACE + tasks.get(index).toString()); } else { System.out.println(StringDesign.SPACE + "Invalid task number."); } @@ -68,7 +68,7 @@ public void delete(int index) { remainingTask = countUnmarkedTasks() -1; } System.out.println(StringDesign.SPACE + "Task is removed." + " Pending task: " + remainingTask); - System.out.println(StringDesign.SPACE + "[" + tasks.get(index).getType() + "][" + tasks.get(index).getMarkedStatus() + "] " + tasks.get(index).getDescription()); + System.out.println(StringDesign.SPACE + tasks.get(index).toString()); tasks.remove(index); size--; } From 2a63fdc9e1828c210a015fb52c799ca51429b33c Mon Sep 17 00:00:00 2001 From: BevLow Date: Sun, 22 Sep 2024 15:09:19 +0800 Subject: [PATCH 33/50] Add A-Exceptions --- src/main/java/CharlieExceptions.java | 8 ++++++++ src/main/java/ChattyCharlie.java | 14 ++++++++++++-- src/main/java/List.java | 4 ++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/main/java/CharlieExceptions.java b/src/main/java/CharlieExceptions.java index 0e9f53a76..bdf4d6ad8 100644 --- a/src/main/java/CharlieExceptions.java +++ b/src/main/java/CharlieExceptions.java @@ -15,4 +15,12 @@ public static CharlieExceptions missingDeadline() { public static CharlieExceptions missingTimes() { return new CharlieExceptions("Your event is missing or incomplete!"); } + + public static CharlieExceptions alreadyMarked() { + return new CharlieExceptions("Your task is already marked!"); + } + + public static CharlieExceptions alreadyUnmarked() { + return new CharlieExceptions("Your task is already unmarked!"); + } } diff --git a/src/main/java/ChattyCharlie.java b/src/main/java/ChattyCharlie.java index e3be84928..e74db3f20 100644 --- a/src/main/java/ChattyCharlie.java +++ b/src/main/java/ChattyCharlie.java @@ -103,8 +103,13 @@ public static void ScheduleMaker() throws CharlieExceptions { //Echo as a functi String markIndex = line.substring(4).trim(); //convert the string number into an int int markNo = Integer.parseInt(markIndex) -1; //convert to array + Task markedTask = list.getTasks(markNo); //mark it - list.mark(markNo); + if (markedTask.getMarkedStatus().equals(" ")) { + list.mark(markNo); + } else { + throw CharlieExceptions.alreadyMarked(); + } //print System.out.println(StringDesign.LINE); break; @@ -114,7 +119,12 @@ public static void ScheduleMaker() throws CharlieExceptions { //Echo as a functi //convert the string no into a int int unmarkNo = Integer.parseInt(unmarkIndex) -1; //mark it - list.unmark(unmarkNo); + Task unmarkedTask = list.getTasks(unmarkNo); + if (unmarkedTask.getMarkedStatus().equals("X")) { + list.unmark(unmarkNo); + } else { + throw CharlieExceptions.alreadyUnmarked(); + } //print System.out.println(StringDesign.LINE); break; diff --git a/src/main/java/List.java b/src/main/java/List.java index 609714477..18bd60bf9 100644 --- a/src/main/java/List.java +++ b/src/main/java/List.java @@ -18,6 +18,10 @@ public void addTask(Task task) { size++; } + public Task getTasks(int index) { + return this.tasks[index]; + } + public Task[] getList() { return this.tasks; } From 6c8dfc5b0a13593b4f46c5880f91d1ec133efb0b Mon Sep 17 00:00:00 2001 From: BevLow Date: Sun, 22 Sep 2024 15:17:55 +0800 Subject: [PATCH 34/50] Add A-Exceptions --- META-INF/MANIFEST.MF | 2 ++ src/main/java/META-INF/MANIFEST.MF | 3 +++ 2 files changed, 5 insertions(+) create mode 100644 META-INF/MANIFEST.MF create mode 100644 src/main/java/META-INF/MANIFEST.MF diff --git a/META-INF/MANIFEST.MF b/META-INF/MANIFEST.MF new file mode 100644 index 000000000..59499bce4 --- /dev/null +++ b/META-INF/MANIFEST.MF @@ -0,0 +1,2 @@ +Manifest-Version: 1.0 + diff --git a/src/main/java/META-INF/MANIFEST.MF b/src/main/java/META-INF/MANIFEST.MF new file mode 100644 index 000000000..14eba55a4 --- /dev/null +++ b/src/main/java/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: ChattyCharlie + From 3be8c65e0eb300f0bbbd76a5c3a79f8f85aa0cac Mon Sep 17 00:00:00 2001 From: BevLow Date: Fri, 27 Sep 2024 01:45:19 +0800 Subject: [PATCH 35/50] Add A-MoreOOP --- .../java/chattycharlie/CharlieExceptions.java | 6 +- .../java/chattycharlie/ChattyCharlie.java | 183 +++------------ src/main/java/chattycharlie/List.java | 214 ------------------ src/main/java/chattycharlie/TaskList.java | 124 ++++++++++ .../chattycharlie/commands/ByeCommand.java | 20 ++ .../java/chattycharlie/commands/Command.java | 14 ++ .../commands/CommandFactory.java | 28 +++ .../{ => commands}/CommandType.java | 2 +- .../commands/DeadlineCommand.java | 32 +++ .../chattycharlie/commands/DeleteCommand.java | 20 ++ .../chattycharlie/commands/EventCommand.java | 46 ++++ .../chattycharlie/commands/ListCommand.java | 13 ++ .../chattycharlie/commands/MarkCommand.java | 20 ++ .../chattycharlie/commands/TodoCommand.java | 28 +++ .../chattycharlie/commands/UnmarkCommand.java | 20 ++ .../java/chattycharlie/task/Deadline.java | 2 +- src/main/java/chattycharlie/task/Event.java | 2 +- src/main/java/chattycharlie/task/Task.java | 2 +- src/main/java/chattycharlie/task/Todo.java | 2 +- .../userinteractions/Parser.java | 10 + .../userinteractions/Storage.java | 113 +++++++++ .../{ => userinteractions}/StringDesign.java | 2 +- .../chattycharlie/userinteractions/Ui.java | 59 +++++ 23 files changed, 587 insertions(+), 375 deletions(-) delete mode 100644 src/main/java/chattycharlie/List.java create mode 100644 src/main/java/chattycharlie/TaskList.java create mode 100644 src/main/java/chattycharlie/commands/ByeCommand.java create mode 100644 src/main/java/chattycharlie/commands/Command.java create mode 100644 src/main/java/chattycharlie/commands/CommandFactory.java rename src/main/java/chattycharlie/{ => commands}/CommandType.java (78%) create mode 100644 src/main/java/chattycharlie/commands/DeadlineCommand.java create mode 100644 src/main/java/chattycharlie/commands/DeleteCommand.java create mode 100644 src/main/java/chattycharlie/commands/EventCommand.java create mode 100644 src/main/java/chattycharlie/commands/ListCommand.java create mode 100644 src/main/java/chattycharlie/commands/MarkCommand.java create mode 100644 src/main/java/chattycharlie/commands/TodoCommand.java create mode 100644 src/main/java/chattycharlie/commands/UnmarkCommand.java create mode 100644 src/main/java/chattycharlie/userinteractions/Parser.java create mode 100644 src/main/java/chattycharlie/userinteractions/Storage.java rename src/main/java/chattycharlie/{ => userinteractions}/StringDesign.java (95%) create mode 100644 src/main/java/chattycharlie/userinteractions/Ui.java diff --git a/src/main/java/chattycharlie/CharlieExceptions.java b/src/main/java/chattycharlie/CharlieExceptions.java index ca11e8917..209ecc054 100644 --- a/src/main/java/chattycharlie/CharlieExceptions.java +++ b/src/main/java/chattycharlie/CharlieExceptions.java @@ -1,5 +1,7 @@ package chattycharlie; +import chattycharlie.commands.CommandType; + public class CharlieExceptions extends Exception{ public CharlieExceptions(String message){ super(message); @@ -22,7 +24,7 @@ public static CharlieExceptions missingDelete() { return new CharlieExceptions("You forgot to specify which task."); } - public static CharlieExceptions deleteIndexOutOfBound() { - return new CharlieExceptions("Did you make a typo, that task does not exist!"); + public static CharlieExceptions cannotIdentifyCommandType() { + return new CharlieExceptions("Cannot identify command type."); } } diff --git a/src/main/java/chattycharlie/ChattyCharlie.java b/src/main/java/chattycharlie/ChattyCharlie.java index 0a2d8298d..304302854 100644 --- a/src/main/java/chattycharlie/ChattyCharlie.java +++ b/src/main/java/chattycharlie/ChattyCharlie.java @@ -1,171 +1,48 @@ package chattycharlie; -import chattycharlie.task.Deadline; -import chattycharlie.task.Event; -import chattycharlie.task.Todo; - -import java.util.Scanner; +import chattycharlie.commands.*; +import chattycharlie.userinteractions. *; public class ChattyCharlie { + private Ui ui; + private TaskList taskList; + private Storage storage; + + public ChattyCharlie(String filePath) { + ui = new Ui(); + storage = new Storage(filePath); + try{ + taskList = new TaskList(storage.load()); + } catch (CharlieExceptions e) { + ui.displayError("First Time here, Welcome to a life of productivity!"); + taskList = new TaskList(); + } + } - public static void scheduleMaker() throws CharlieExceptions { //Echo as a function - String line = null; - CommandType command = null; - //make the scanner - Scanner in = new Scanner(System.in); - - //create an instance of list class - List list = new List(); - - //read in the file - list.readTaskFromFile("text.txt"); - + public void run() { //Echo as a function + ui.displayGreetings(); + Parser parser = new Parser(); + boolean isExit = false; - while (true) { + while (!isExit) { try { - //takes in an input - System.out.print(StringDesign.YOU); - line = in.nextLine(); - System.out.println(StringDesign.LINE); - - //get the first word to see the command type - String firstWord = line.split(" ")[0]; - - command = CommandType.valueOf(firstWord.toUpperCase()); - - //start the different command types - switch (command) { - case TODO: - //remove the words todo - String todoDescription = line.substring(4).trim(); + String line = ui.getUserInput(); + CommandType commandType = parser.getCommand(line); - // Check if the description is empty - if (todoDescription.isEmpty()) { - throw CharlieExceptions.missingDescription(command); - } + Command command = CommandFactory.createCommand(commandType, line); + command.execute(taskList, ui, storage); - //add the todo task - list.addTask(new Todo(todoDescription)); - //print - System.out.println(StringDesign.SPACE + "Added todo: " + todoDescription); - System.out.println(StringDesign.LINE); - break; - case DEADLINE: - //remove the deadline word and split into description and deadline time - String[] deadlineParts = line.substring(8).trim().split(" by "); - String deadlineDescription; - String by; + isExit = command.isExit(); - //handle errors - if (deadlineParts[0].isEmpty()) { - throw CharlieExceptions.missingDescription(command); - } else if (deadlineParts.length < 2) { - throw CharlieExceptions.missingDeadline(); - } else { - deadlineDescription = deadlineParts[0].trim(); - } - - by = deadlineParts[1].trim(); - - list.addTask(new Deadline(deadlineDescription, by)); - System.out.println(StringDesign.SPACE + "Added deadline: " + deadlineDescription + " (by: " + by + ")"); - System.out.println(StringDesign.LINE); - break; - case EVENT: - //remove the event word and split into the description and event times - String[] eventParts = line.substring(5).trim().split("from"); - String description; - String startTime; - String endTime; - - // Error handling for Events - if (eventParts[0].isEmpty()) { //no description - throw CharlieExceptions.missingDescription(command); - } else if (eventParts.length < 2) { //no from - throw CharlieExceptions.missingTimes(); - } else { - description = eventParts[0].trim(); - } - - String[] eventTimes = eventParts[1].trim().split(" to "); - - if (eventTimes.length < 2) { - throw CharlieExceptions.missingTimes(); //change this to no end date - } - - if (eventTimes[0].isEmpty() || eventTimes[1].isEmpty()) { - throw CharlieExceptions.missingTimes(); - } else { - startTime = eventTimes[0].trim(); - endTime = eventTimes[1].trim(); - } - - //add the event task - list.addTask(new Event(description, startTime, endTime)); - //print - System.out.println(StringDesign.SPACE + "Added event: " + description - + " (from: " + startTime + ", to: " + endTime + ")"); - System.out.println(StringDesign.LINE); - break; - case MARK: - //remove the mark word - String markIndex = line.substring(4).trim(); - //convert the string number into an int - int markNo = Integer.parseInt(markIndex) -1; //convert to array - //mark it - list.mark(markNo); - //print - System.out.println(StringDesign.LINE); - break; - case UNMARK: - //remove the unmark word - String unmarkIndex = line.substring(6).trim(); - //convert the string no into a int - int unmarkNo = Integer.parseInt(unmarkIndex) -1; - //mark it - list.unmark(unmarkNo); - //print - System.out.println(StringDesign.LINE); - break; - case BYE: - list.saveTasksToFile("text.txt"); - return; //just exit - case LIST: - list.printList(); - //print - System.out.println(StringDesign.LINE); - break; - case DELETE: - String deleteIndex = line.substring(7).trim(); - if (deleteIndex == null) { - throw CharlieExceptions.missingDelete(); - } - int deleteNo = Integer.parseInt(deleteIndex) - 1; - if(deleteNo > list.getSize() || deleteNo < 0) { - throw CharlieExceptions.deleteIndexOutOfBound(); - } - //delete the task - list.delete(deleteNo); - default: - break; - } } catch (CharlieExceptions e) { - // Handle custom exceptions and prompt for new input - System.out.println(e.getMessage()); - System.out.println(StringDesign.LINE); - continue; // Continue to ask for input after throwing exception + ui.displayError(e.getMessage()); } catch (IllegalArgumentException e) { - System.out.println("Oop, did you make a typo?"); - System.out.println(StringDesign.LINE); - continue; + ui.displayError("Oop, did you make a typo?"); } } } - public static void main (String[]args) throws CharlieExceptions{ - System.out.println(StringDesign.LOGO + StringDesign.CHARLIE + StringDesign.GREETING); - scheduleMaker(); - System.out.println(StringDesign.CHARLIE + StringDesign.FAREWELL); - + public static void main (String[]args){ + new ChattyCharlie("data/tasks.txt").run(); } } diff --git a/src/main/java/chattycharlie/List.java b/src/main/java/chattycharlie/List.java deleted file mode 100644 index 99ba9081e..000000000 --- a/src/main/java/chattycharlie/List.java +++ /dev/null @@ -1,214 +0,0 @@ -package chattycharlie; - -import chattycharlie.task.Deadline; -import chattycharlie.task.Event; -import chattycharlie.task.Task; -import chattycharlie.task.Todo; -import java.util.ArrayList; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileWriter; -import java.io.IOException; -import java.util.Scanner; - -//LIST CLASS - public class List { - //make a list of task - private ArrayList tasks; - private int size; - - //constructor - public List() { - tasks = new ArrayList(); - size = 0; - } - - //Method to add an item to the list - public void addTask(Task task) { - //add the text into the list - tasks.add(task); - //account for the item - size++; - } - - public ArrayList getList() { - return this.tasks; - } - - public int getSize() { - return size; - } - - //To mark - public void mark(int index) { - if (index >= 0 && index < size) { - tasks.get(index).markTask(); - int remainingTask = countUnmarkedTasks(); - System.out.println(StringDesign.SPACE + "Well Done! 1 task down, " + remainingTask + " to go."); - System.out.println(StringDesign.SPACE+ tasks.get(index).toString()); - } else { - System.out.println(StringDesign.SPACE+ "Invalid task number."); - } - } - - //To unmark - public void unmark(int index) { - if (index >= 0 && index < size) { - tasks.get(index).unmarkTask(); - int remainingTask = countUnmarkedTasks(); - System.out.println(StringDesign.SPACE + "Hmmm, not quite done yet, " + remainingTask + " to go."); - System.out.println(StringDesign.SPACE + tasks.get(index).toString()); - } else { - System.out.println(StringDesign.SPACE + "Invalid task number."); - } - } - - //To delete - public void delete(int index) { - if (index >= 0 && index < size) { - int remainingTask; - if(tasks.get(index).getIsDoneStatus()) { - remainingTask = countUnmarkedTasks(); - } else { - remainingTask = countUnmarkedTasks() -1; - } - System.out.println(StringDesign.SPACE + "Task is removed." + " Pending task: " + remainingTask); - System.out.println(StringDesign.SPACE + tasks.get(index).toString()); - tasks.remove(index); - size--; - } - } - - //To print list - public void printList() { - //print all - int remainingTask = countUnmarkedTasks(); - System.out.println("ToDo List:"); - System.out.println("pending Task: " + remainingTask); - for (int i = 0; i < size; i++) { - int number = i+1; - Task task = tasks.get(i); - //use a switch to determine - switch (task.getType()) { - case TODO: - Todo todoTask = (Todo) task; - System.out.println(StringDesign.SPACE + number + todoTask); - break; - case DEADLINE: - Deadline deadlineTask = (Deadline) task; - System.out.println(StringDesign.SPACE + number + deadlineTask); - break; - case EVENT: - Event eventTask = (Event) task; - System.out.println(StringDesign.SPACE + number + eventTask); - break; - default: - break; - } - } - } - - // Method to count how many tasks are unmarked - public int countUnmarkedTasks() { - int count = 0; - for (int i = 0; i < size; i++) { - if (!tasks.get(i).getIsDoneStatus()) { - count++; - } - } - return count; - } - - //read in a file - public void readTaskFromFile(String filename) { - File file = new File(filename); - - try { - Scanner scanner = new Scanner(file); - - while (scanner.hasNextLine()) { - String taskText = scanner.nextLine(); - //create task object from the text line - parseTaskFromText(taskText); - } - scanner.close(); - System.out.println(StringDesign.CHARLIE + "Task have been loaded from: " + filename); - } catch (FileNotFoundException e) { - System.out.println("Oh first time here? Welcome to a life of Productivity, lets start!"); - } - } - - // converting text to task - public void parseTaskFromText(String taskText) { - taskText = taskText.trim(); //trim away the formatting - char taskType = taskText.charAt(1); //get the commandType - boolean isMarked = taskText.charAt(4) == 'X'; //get status for marked - String description; - if (taskType == 'T') { - description = taskText.substring(7).trim(); - } else { - int parenIndex = taskText.indexOf('('); - description = taskText.substring(7, parenIndex).trim(); // Get description before '(' - } - Task task; - switch (taskType) { - case 'T': - task = new Todo(description); - if (isMarked) { - task.markTask(); - } - addTask(task); - break; - case 'D': - String by = taskText.substring(taskText.indexOf("(by: ") + 5, taskText.length() - 1).trim(); - task = new Deadline(description, by); // Add Deadline task - //check if its marked - if(isMarked) { - task.markTask(); - } - addTask(task); - break; - case 'E': - String eventInfo = taskText.substring(taskText.indexOf("(from: ") + 7, taskText.length() - 1).trim(); - String[] eventTimes = eventInfo.split(" to: "); - if (eventTimes.length == 2) { - String startTime = eventTimes[0].trim(); - String endTime = eventTimes[1].trim(); - task = new Event(description, startTime, endTime); // Add Event task - if (isMarked) { - task.markTask(); - } - addTask(task); - } else { - System.out.println("Invalid event time format: " + taskText); - } - break; - default: - throw new IllegalArgumentException("Unknown task type"); - } - } - - //to save a file (called before the program ends) - public void saveTasksToFile(String filename) { - File file = new File(filename); - - try { - FileWriter writer = new FileWriter(file); - - for (Task task : tasks) { - if (task != null) { - writer.write(taskToString(task) + "\n"); - } - } - - writer.close(); - System.out.println(StringDesign.CHARLIE + "We saved your file in: " + filename); - } catch (IOException e) { - System.out.println("An error has occured when saving tasks"); - } - } - - public String taskToString(Task task) { - return StringDesign.SPACE + task; - } - } \ No newline at end of file diff --git a/src/main/java/chattycharlie/TaskList.java b/src/main/java/chattycharlie/TaskList.java new file mode 100644 index 000000000..38000bdeb --- /dev/null +++ b/src/main/java/chattycharlie/TaskList.java @@ -0,0 +1,124 @@ +package chattycharlie; + +import chattycharlie.userinteractions.Ui; +import chattycharlie.task.Deadline; +import chattycharlie.task.Event; +import chattycharlie.task.Task; +import chattycharlie.task.Todo; +import java.util.ArrayList; + +//LIST CLASS + public class TaskList { + private ArrayList tasks; + private int size; + + //constructor + public TaskList() { + tasks = new ArrayList(); + size = 0; + } + + public TaskList(TaskList list){ + this.tasks = list.tasks; + this.size = list.size; + } + + //Method to add an item to the list + public void addTask(Task task) { + tasks.add(task); + size++; + } + + public ArrayList getList() { + return this.tasks; + } + + public Task getTask(int index) { + return this.tasks.get(index); + } + + public int getSize() { + return size; + } + + //To mark + public void markTask(int index) { + Ui ui = new Ui(); + if (index >= 0 && index < size) { + tasks.get(index).markTask(); + int remainingTask = countUnmarkedTasks(); + ui.displayMarkingText("yay, 1 down!", remainingTask); + } else { + ui.displayError("Invalid task number."); + } + } + + //To unmark + public void unmarkTask(int index) { + Ui ui = new Ui(); + if (index >= 0 && index < size) { + tasks.get(index).unmarkTask(); + int remainingTask = countUnmarkedTasks(); + ui.displayMarkingText("Hmmm, not quite done yet,", remainingTask); + } else { + ui.displayError("Invalid task number."); + } + } + + //To delete + public void deleteTask(int index) { + Ui ui = new Ui(); + if (index >= 0 && index < size) { + int remainingTask; + if(tasks.get(index).getIsDoneStatus()) { + remainingTask = countUnmarkedTasks(); + } else { + remainingTask = countUnmarkedTasks() -1; + } + ui.displayDeletedTask("Task is removed. Pending task: ", remainingTask); + ui.displayTask(tasks.get(index)); + tasks.remove(index); + size--; + } + } + + //To print list + public void printList() { + int remainingTask = countUnmarkedTasks(); + Ui ui = new Ui(); + ui.displayListHeader(remainingTask); + for (int i = 0; i < size; i++) { + int number = i+1; + Task task = tasks.get(i); + //use a switch to determine + switch (task.getType()) { + case TODO: + Todo todoTask = (Todo) task; + ui.displayTaskInList(todoTask, number); + break; + case DEADLINE: + Deadline deadlineTask = (Deadline) task; + ui.displayTaskInList(deadlineTask, number); + break; + case EVENT: + Event eventTask = (Event) task; + ui.displayTaskInList(eventTask, number); + break; + default: + break; + } + } + ui.displayLine(); + } + + // Method to count how many tasks are unmarked + public int countUnmarkedTasks() { + int count = 0; + for (int i = 0; i < size; i++) { + if (!tasks.get(i).getIsDoneStatus()) { + count++; + } + } + return count; + } + } \ No newline at end of file diff --git a/src/main/java/chattycharlie/commands/ByeCommand.java b/src/main/java/chattycharlie/commands/ByeCommand.java new file mode 100644 index 000000000..b0293abbc --- /dev/null +++ b/src/main/java/chattycharlie/commands/ByeCommand.java @@ -0,0 +1,20 @@ +package chattycharlie.commands; + +import chattycharlie.userinteractions.Storage; +import chattycharlie.TaskList; +import chattycharlie.userinteractions.StringDesign; +import chattycharlie.userinteractions.Ui; + +public class ByeCommand implements Command { + + @Override + public void execute(TaskList taskList, Ui ui, Storage storage) { + storage.saveTasks(taskList); + System.out.println(StringDesign.CHARLIE + StringDesign.FAREWELL); + } + + @Override + public boolean isExit() { + return true; // This command causes the loop to exit + } +} diff --git a/src/main/java/chattycharlie/commands/Command.java b/src/main/java/chattycharlie/commands/Command.java new file mode 100644 index 000000000..f2e06bf71 --- /dev/null +++ b/src/main/java/chattycharlie/commands/Command.java @@ -0,0 +1,14 @@ +package chattycharlie.commands; + +import chattycharlie.CharlieExceptions; +import chattycharlie.userinteractions.Storage; +import chattycharlie.TaskList; +import chattycharlie.userinteractions.Ui; + +public interface Command { + void execute(TaskList taskList, Ui ui, Storage storage) throws CharlieExceptions; + + default boolean isExit() { + return false; // Default behavior: most commands are not exit commands + } +} diff --git a/src/main/java/chattycharlie/commands/CommandFactory.java b/src/main/java/chattycharlie/commands/CommandFactory.java new file mode 100644 index 000000000..d3ab83d0f --- /dev/null +++ b/src/main/java/chattycharlie/commands/CommandFactory.java @@ -0,0 +1,28 @@ +package chattycharlie.commands; + +import chattycharlie.CharlieExceptions; + +public class CommandFactory { + public static Command createCommand(CommandType commandType, String line) throws CharlieExceptions { + switch (commandType) { + case TODO: + return new TodoCommand(line); + case DEADLINE: + return new DeadlineCommand(line); + case EVENT: + return new EventCommand(line); + case MARK: + return new MarkCommand(line); + case UNMARK: + return new UnmarkCommand(line); + case BYE: + return new ByeCommand(); + case LIST: + return new ListCommand(); + case DELETE: + return new DeleteCommand(line); + default: + throw CharlieExceptions.cannotIdentifyCommandType(); //change this + } + } +} diff --git a/src/main/java/chattycharlie/CommandType.java b/src/main/java/chattycharlie/commands/CommandType.java similarity index 78% rename from src/main/java/chattycharlie/CommandType.java rename to src/main/java/chattycharlie/commands/CommandType.java index d19500521..5f746bc93 100644 --- a/src/main/java/chattycharlie/CommandType.java +++ b/src/main/java/chattycharlie/commands/CommandType.java @@ -1,4 +1,4 @@ -package chattycharlie; +package chattycharlie.commands; public enum CommandType { TODO, diff --git a/src/main/java/chattycharlie/commands/DeadlineCommand.java b/src/main/java/chattycharlie/commands/DeadlineCommand.java new file mode 100644 index 000000000..6846449f5 --- /dev/null +++ b/src/main/java/chattycharlie/commands/DeadlineCommand.java @@ -0,0 +1,32 @@ +package chattycharlie.commands; + +import chattycharlie.CharlieExceptions; +import chattycharlie.userinteractions.Storage; +import chattycharlie.TaskList; +import chattycharlie.userinteractions.Ui; +import chattycharlie.task.Deadline; +import chattycharlie.task.Task; + +public class DeadlineCommand implements Command { + private String description; + private String by; + + public DeadlineCommand(String line) throws CharlieExceptions { + String[] deadlineParts = line.substring(8).trim().split(" by "); + if (deadlineParts[0].isEmpty()) { + throw CharlieExceptions.missingDescription(CommandType.DEADLINE); + } else if (deadlineParts.length < 2) { + throw CharlieExceptions.missingDeadline(); + } else { + this.description = deadlineParts[0].trim(); + } + this.by = deadlineParts[1].trim(); + } + + @Override + public void execute(TaskList taskList, Ui ui, Storage storage) { + Task deadlineTask = new Deadline(description, by); + taskList.addTask(deadlineTask); + ui.displayTaskAdded(deadlineTask); + } +} diff --git a/src/main/java/chattycharlie/commands/DeleteCommand.java b/src/main/java/chattycharlie/commands/DeleteCommand.java new file mode 100644 index 000000000..73435b5c0 --- /dev/null +++ b/src/main/java/chattycharlie/commands/DeleteCommand.java @@ -0,0 +1,20 @@ +package chattycharlie.commands; + +import chattycharlie.CharlieExceptions; +import chattycharlie.userinteractions.Storage; +import chattycharlie.TaskList; +import chattycharlie.userinteractions.Ui; + +public class DeleteCommand implements Command { + private int toDeleteIndex; + + public DeleteCommand(String line) throws CharlieExceptions { + String toDeleteIndex = line.substring(7).trim(); + this.toDeleteIndex = Integer.parseInt(toDeleteIndex) - 1; + } + + @Override + public void execute(TaskList taskList, Ui ui, Storage storage) { + taskList.deleteTask(toDeleteIndex); + } +} diff --git a/src/main/java/chattycharlie/commands/EventCommand.java b/src/main/java/chattycharlie/commands/EventCommand.java new file mode 100644 index 000000000..dc7279aa5 --- /dev/null +++ b/src/main/java/chattycharlie/commands/EventCommand.java @@ -0,0 +1,46 @@ +package chattycharlie.commands; + +import chattycharlie.CharlieExceptions; +import chattycharlie.userinteractions.Storage; +import chattycharlie.TaskList; +import chattycharlie.userinteractions.Ui; +import chattycharlie.task.Event; +import chattycharlie.task.Task; + +public class EventCommand implements Command{ + private String description; + private String from; + private String to; + + public EventCommand(String line) throws CharlieExceptions { + String[] eventParts = line.substring(5).trim().split("from"); + + if (eventParts[0].isEmpty()) { //no description + throw CharlieExceptions.missingDescription(CommandType.EVENT); + } else if (eventParts.length < 2) { //no from + throw CharlieExceptions.missingTimes(); + } else { + description = eventParts[0].trim(); + } + + String[] eventTimes = eventParts[1].trim().split(" to "); + + if (eventTimes.length < 2) { + throw CharlieExceptions.missingTimes(); //change this to no end date + } + + if (eventTimes[0].isEmpty() || eventTimes[1].isEmpty()) { + throw CharlieExceptions.missingTimes(); + } else { + from = eventTimes[0].trim(); + to = eventTimes[1].trim(); + } + } + + @Override + public void execute(TaskList taskList, Ui ui, Storage storage) { + Task eventTask = new Event(description, from, to); + taskList.addTask(eventTask); + ui.displayTaskAdded(eventTask); + } +} diff --git a/src/main/java/chattycharlie/commands/ListCommand.java b/src/main/java/chattycharlie/commands/ListCommand.java new file mode 100644 index 000000000..10684024b --- /dev/null +++ b/src/main/java/chattycharlie/commands/ListCommand.java @@ -0,0 +1,13 @@ +package chattycharlie.commands; + +import chattycharlie.CharlieExceptions; +import chattycharlie.userinteractions.Storage; +import chattycharlie.TaskList; +import chattycharlie.userinteractions.Ui; + +public class ListCommand implements Command { + @Override + public void execute(TaskList taskList, Ui ui, Storage storage) throws CharlieExceptions { + ui.displayList(taskList); + } +} diff --git a/src/main/java/chattycharlie/commands/MarkCommand.java b/src/main/java/chattycharlie/commands/MarkCommand.java new file mode 100644 index 000000000..296f94404 --- /dev/null +++ b/src/main/java/chattycharlie/commands/MarkCommand.java @@ -0,0 +1,20 @@ +package chattycharlie.commands; + +import chattycharlie.userinteractions.Storage; +import chattycharlie.TaskList; +import chattycharlie.userinteractions.Ui; + +public class MarkCommand implements Command { + private int toMarkIndex; + + public MarkCommand(String line) { + String toMarkIndex = line.substring(4).trim(); + this.toMarkIndex = Integer.parseInt(toMarkIndex) - 1; + } + + @Override + public void execute(TaskList taskList, Ui ui, Storage storage) { + taskList.unmarkTask(toMarkIndex); + ui.displayTask(taskList.getTask(toMarkIndex)); + } +} diff --git a/src/main/java/chattycharlie/commands/TodoCommand.java b/src/main/java/chattycharlie/commands/TodoCommand.java new file mode 100644 index 000000000..3d69547de --- /dev/null +++ b/src/main/java/chattycharlie/commands/TodoCommand.java @@ -0,0 +1,28 @@ +package chattycharlie.commands; + +import chattycharlie.CharlieExceptions; +import chattycharlie.userinteractions.Storage; +import chattycharlie.TaskList; +import chattycharlie.userinteractions.Ui; +import chattycharlie.task.Task; +import chattycharlie.task.Todo; + +public class TodoCommand implements Command{ + private String description; + + public TodoCommand(String line) throws CharlieExceptions { + String text = line.substring(4).trim(); + if (text.isEmpty()) { + throw CharlieExceptions.missingDescription(CommandType.TODO); + } else { + this.description = text; + } + } + + @Override + public void execute(TaskList taskList, Ui ui, Storage storage){ + Task todoTask = new Todo(description); + taskList.addTask(todoTask); + ui.displayTaskAdded(todoTask); + } +} diff --git a/src/main/java/chattycharlie/commands/UnmarkCommand.java b/src/main/java/chattycharlie/commands/UnmarkCommand.java new file mode 100644 index 000000000..d000c2aff --- /dev/null +++ b/src/main/java/chattycharlie/commands/UnmarkCommand.java @@ -0,0 +1,20 @@ +package chattycharlie.commands; + +import chattycharlie.userinteractions.Storage; +import chattycharlie.TaskList; +import chattycharlie.userinteractions.Ui; + +public class UnmarkCommand implements Command { + private int toUnmarkIndex; + + public UnmarkCommand(String line) { + String toUnmarkIndex = line.substring(4).trim(); + this.toUnmarkIndex = Integer.parseInt(toUnmarkIndex) - 1; + } + + @Override + public void execute(TaskList taskList, Ui ui, Storage storage) { + taskList.markTask(toUnmarkIndex); + ui.displayTask(taskList.getTask(toUnmarkIndex)); + } +} diff --git a/src/main/java/chattycharlie/task/Deadline.java b/src/main/java/chattycharlie/task/Deadline.java index 4b0f5c496..cca1f9f54 100644 --- a/src/main/java/chattycharlie/task/Deadline.java +++ b/src/main/java/chattycharlie/task/Deadline.java @@ -1,6 +1,6 @@ package chattycharlie.task; -import chattycharlie.CommandType; +import chattycharlie.commands.CommandType; //Deadline Class public class Deadline extends Task { diff --git a/src/main/java/chattycharlie/task/Event.java b/src/main/java/chattycharlie/task/Event.java index fa1c4e981..5f84380d7 100644 --- a/src/main/java/chattycharlie/task/Event.java +++ b/src/main/java/chattycharlie/task/Event.java @@ -1,6 +1,6 @@ package chattycharlie.task; -import chattycharlie.CommandType; +import chattycharlie.commands.CommandType; //Events public class Event extends Task { diff --git a/src/main/java/chattycharlie/task/Task.java b/src/main/java/chattycharlie/task/Task.java index 3d77e221a..02ced1f18 100644 --- a/src/main/java/chattycharlie/task/Task.java +++ b/src/main/java/chattycharlie/task/Task.java @@ -1,6 +1,6 @@ package chattycharlie.task; -import chattycharlie.CommandType; +import chattycharlie.commands.CommandType; //TASK CLASS public abstract class Task { diff --git a/src/main/java/chattycharlie/task/Todo.java b/src/main/java/chattycharlie/task/Todo.java index f3a967b8c..1fe13eb67 100644 --- a/src/main/java/chattycharlie/task/Todo.java +++ b/src/main/java/chattycharlie/task/Todo.java @@ -1,6 +1,6 @@ package chattycharlie.task; -import chattycharlie.CommandType; +import chattycharlie.commands.CommandType; //todo class public class Todo extends Task { diff --git a/src/main/java/chattycharlie/userinteractions/Parser.java b/src/main/java/chattycharlie/userinteractions/Parser.java new file mode 100644 index 000000000..c2ea37038 --- /dev/null +++ b/src/main/java/chattycharlie/userinteractions/Parser.java @@ -0,0 +1,10 @@ +package chattycharlie.userinteractions; + +import chattycharlie.commands.CommandType; + +public class Parser { + public CommandType getCommand(String input) { + String firstWord = input.split(" ")[0]; + return CommandType.valueOf(firstWord.toUpperCase()); + } +} diff --git a/src/main/java/chattycharlie/userinteractions/Storage.java b/src/main/java/chattycharlie/userinteractions/Storage.java new file mode 100644 index 000000000..cbc5bff3d --- /dev/null +++ b/src/main/java/chattycharlie/userinteractions/Storage.java @@ -0,0 +1,113 @@ +package chattycharlie.userinteractions; + +import chattycharlie.CharlieExceptions; +import chattycharlie.TaskList; +import chattycharlie.task.Deadline; +import chattycharlie.task.Event; +import chattycharlie.task.Task; +import chattycharlie.task.Todo; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Scanner; + +public class Storage { + private String filePath; + + public Storage(String filePath) { + this.filePath = filePath; + } + public TaskList load() throws CharlieExceptions { + TaskList list = new TaskList(); + File file = new File(filePath); + + try { + Scanner scanner = new Scanner(file); + + while (scanner.hasNextLine()) { + String taskText = scanner.nextLine(); + Task task = parseTask(taskText); + if (task != null) { + list.addTask(task); + } + } + scanner.close(); + System.out.println(StringDesign.CHARLIE + "Task have been loaded from: " + filePath); + } catch (FileNotFoundException e) { + System.out.println("Oh first time here? Welcome to a life of Productivity, lets start!"); + } + + return list; + } + + public Task parseTask(String taskText) { + taskText = taskText.trim(); //trim away the formatting + char taskType = taskText.charAt(1); //get the commandType + boolean isMarked = taskText.charAt(4) == 'X'; //get status for marked + String description; + if (taskType == 'T') { + description = taskText.substring(7).trim(); + } else { + int parenIndex = taskText.indexOf('('); + description = taskText.substring(7, parenIndex).trim(); // Get description before '(' + } + Task task; + switch (taskType) { + case 'T': + task = new Todo(description); + if (isMarked) { + task.markTask(); + } + return task; + case 'D': + String by = taskText.substring(taskText.indexOf("(by: ") + 5, taskText.length() - 1).trim(); + task = new Deadline(description, by); // Add Deadline task + //check if its marked + if(isMarked) { + task.markTask(); + } + return task; + case 'E': + String eventInfo = taskText.substring(taskText.indexOf("(from: ") + 7, taskText.length() - 1).trim(); + String[] eventTimes = eventInfo.split(" to: "); + if (eventTimes.length == 2) { + String startTime = eventTimes[0].trim(); + String endTime = eventTimes[1].trim(); + task = new Event(description, startTime, endTime); // Add Event task + if (isMarked) { + task.markTask(); + } + return task; + } else { + System.out.println("Invalid event time format: " + taskText); + } + break; + default: + throw new IllegalArgumentException("Unknown task type"); + } + return null; + } + + //to save a file (called before the program ends) + public void saveTasks(TaskList list) { + try { + FileWriter writer = new FileWriter(filePath); + for (int i = 0; i < list.getSize(); i++) { + Task task = list.getTask(i); + if (task != null) { + writer.write(taskToString(task) + "\n"); + } + } + writer.close(); + System.out.println(StringDesign.CHARLIE + "We saved your file in: " + filePath); + } catch (IOException e) { + System.out.println("An error has occurred when saving tasks: " + e.getMessage()); + } + } + + public String taskToString(Task task) { + return task.toString(); + } +} diff --git a/src/main/java/chattycharlie/StringDesign.java b/src/main/java/chattycharlie/userinteractions/StringDesign.java similarity index 95% rename from src/main/java/chattycharlie/StringDesign.java rename to src/main/java/chattycharlie/userinteractions/StringDesign.java index bc499bce5..a5ab00dec 100644 --- a/src/main/java/chattycharlie/StringDesign.java +++ b/src/main/java/chattycharlie/userinteractions/StringDesign.java @@ -1,4 +1,4 @@ -package chattycharlie; +package chattycharlie.userinteractions; public class StringDesign { //this class is for all my Strings and designs diff --git a/src/main/java/chattycharlie/userinteractions/Ui.java b/src/main/java/chattycharlie/userinteractions/Ui.java new file mode 100644 index 000000000..7f21ab134 --- /dev/null +++ b/src/main/java/chattycharlie/userinteractions/Ui.java @@ -0,0 +1,59 @@ +package chattycharlie.userinteractions; + +import chattycharlie.TaskList; +import chattycharlie.task.Task; + +import java.util.Scanner; + +public class Ui { + + public String getUserInput() { + Scanner scanner = new Scanner(System.in); + + System.out.print(StringDesign.YOU); + String userInput = scanner.nextLine(); + System.out.println(StringDesign.LINE); + return userInput; + } + + public void displayGreetings(){ + System.out.println(StringDesign.LOGO + StringDesign.CHARLIE + StringDesign.GREETING); + } + + public void displayTaskAdded(Task task) { + System.out.println(StringDesign.SPACE + "Added todo: " + task + System.lineSeparator() + StringDesign.LINE); + } + + public void displayTask(Task task) { + System.out.println(StringDesign.SPACE + task + System.lineSeparator() + StringDesign.LINE); + } + + public void displayList(TaskList list) { + list.printList(); + } + + public void displayTaskInList(Task task, int number) { + System.out.println(StringDesign.SPACE + number +". " + task); + } + + public void displayError(String error) { + System.out.println(error + System.lineSeparator() + StringDesign.LINE); + } + + public void displayMarkingText(String line, int remainingTask) { + System.out.println(StringDesign.SPACE + line + " " + remainingTask + "to go!"); + } + + public void displayDeletedTask(String line, int remainingTask) { + System.out.println(StringDesign.SPACE + line + " " + remainingTask + "to go!"); + } + + public void displayListHeader(int remainingTask) { + System.out.println("ToDo List:"); + System.out.println("pending Task: " + remainingTask); + } + + public void displayLine() { + System.out.println(StringDesign.LINE); + } +} From adabff1028f299146539f4517ad4ae7ec8a4b303 Mon Sep 17 00:00:00 2001 From: BevLow Date: Wed, 2 Oct 2024 00:08:57 +0800 Subject: [PATCH 36/50] Add Level-8 --- .../commands/CommandFactory.java | 2 + .../chattycharlie/commands/CommandType.java | 3 +- .../chattycharlie/commands/MarkCommand.java | 2 +- .../chattycharlie/commands/PrintCommand.java | 52 +++++++++++++++++++ .../java/chattycharlie/task/Deadline.java | 20 ++++--- src/main/java/chattycharlie/task/Event.java | 41 ++++++++------- src/main/java/chattycharlie/task/Task.java | 6 +++ src/main/java/chattycharlie/task/Todo.java | 5 ++ .../userinteractions/Storage.java | 6 +-- .../chattycharlie/userinteractions/Ui.java | 12 +++-- 10 files changed, 114 insertions(+), 35 deletions(-) create mode 100644 src/main/java/chattycharlie/commands/PrintCommand.java diff --git a/src/main/java/chattycharlie/commands/CommandFactory.java b/src/main/java/chattycharlie/commands/CommandFactory.java index d3ab83d0f..f3319c2d6 100644 --- a/src/main/java/chattycharlie/commands/CommandFactory.java +++ b/src/main/java/chattycharlie/commands/CommandFactory.java @@ -21,6 +21,8 @@ public static Command createCommand(CommandType commandType, String line) throws return new ListCommand(); case DELETE: return new DeleteCommand(line); + case PRINT: + return new PrintCommand(line); default: throw CharlieExceptions.cannotIdentifyCommandType(); //change this } diff --git a/src/main/java/chattycharlie/commands/CommandType.java b/src/main/java/chattycharlie/commands/CommandType.java index 5f746bc93..9020311ce 100644 --- a/src/main/java/chattycharlie/commands/CommandType.java +++ b/src/main/java/chattycharlie/commands/CommandType.java @@ -8,5 +8,6 @@ public enum CommandType { UNMARK, BYE, LIST, - DELETE + DELETE, + PRINT } \ No newline at end of file diff --git a/src/main/java/chattycharlie/commands/MarkCommand.java b/src/main/java/chattycharlie/commands/MarkCommand.java index 296f94404..215a6ecf2 100644 --- a/src/main/java/chattycharlie/commands/MarkCommand.java +++ b/src/main/java/chattycharlie/commands/MarkCommand.java @@ -14,7 +14,7 @@ public MarkCommand(String line) { @Override public void execute(TaskList taskList, Ui ui, Storage storage) { - taskList.unmarkTask(toMarkIndex); + taskList.markTask(toMarkIndex); ui.displayTask(taskList.getTask(toMarkIndex)); } } diff --git a/src/main/java/chattycharlie/commands/PrintCommand.java b/src/main/java/chattycharlie/commands/PrintCommand.java new file mode 100644 index 000000000..277081c48 --- /dev/null +++ b/src/main/java/chattycharlie/commands/PrintCommand.java @@ -0,0 +1,52 @@ +package chattycharlie.commands; +import chattycharlie.CharlieExceptions; +import chattycharlie.TaskList; +import chattycharlie.task.Deadline; +import chattycharlie.task.Event; +import chattycharlie.task.Task; +import chattycharlie.userinteractions.Storage; +import chattycharlie.userinteractions.Ui; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; + +public class PrintCommand implements Command{ + private LocalDate time; + + public PrintCommand(String line) { + String timeText = line.substring(6).trim(); + this.time = LocalDate.parse(timeText, DateTimeFormatter.ofPattern("yyyy-MM-dd")); + } + + @Override + public void execute(TaskList taskList, Ui ui, Storage storage) throws CharlieExceptions { + int count = 1; + ui.displayTimeList(); + for(int i = 0; i < taskList.getSize(); i++ ) { + Task task = taskList.getTask(i); + CommandType command = task.getType(); + + switch (command) { + case DEADLINE: + Deadline deadlineTask = (Deadline) task; + if(time.equals(deadlineTask.getBy())) { + ui.displayTaskInList(deadlineTask, count); + count++; + } + break; + case EVENT: + Event eventTask = (Event) task; + if(time.equals(eventTask.getStartDate())) { + ui.displayTaskInList(eventTask, count); + count++; + } + break; + default: + break; + } + } + if(count == 1) { + ui.displayError("No task found for date: " + time.format(DateTimeFormatter.ofPattern("dd/MM/yyyy"))); + } + } +} diff --git a/src/main/java/chattycharlie/task/Deadline.java b/src/main/java/chattycharlie/task/Deadline.java index cca1f9f54..82c01df7c 100644 --- a/src/main/java/chattycharlie/task/Deadline.java +++ b/src/main/java/chattycharlie/task/Deadline.java @@ -1,23 +1,29 @@ package chattycharlie.task; import chattycharlie.commands.CommandType; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; //Deadline Class public class Deadline extends Task { - protected String by; + protected LocalDate by; public Deadline(String description, String by) { super(description, CommandType.DEADLINE); - this.by = by; + this.by = LocalDate.parse(by, DateTimeFormatter.ofPattern("yyyy-MM-dd")); } - public void setBy(String by) { - this.by = by; - } - public String getBy() { + + public LocalDate getBy() { return by; } + @Override public String toString() { - return "[D]" + super.toString() + " (by: " + by + ")"; + return "[D]" + super.toString() + " (by: " + by.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")) + ")"; + } + + @Override + public String toSaveFormat() { + return "[D]" + super.toSaveFormat() + " (by: " + by.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + ")"; } } \ No newline at end of file diff --git a/src/main/java/chattycharlie/task/Event.java b/src/main/java/chattycharlie/task/Event.java index 5f84380d7..426e016e1 100644 --- a/src/main/java/chattycharlie/task/Event.java +++ b/src/main/java/chattycharlie/task/Event.java @@ -1,37 +1,40 @@ package chattycharlie.task; import chattycharlie.commands.CommandType; +import java.time.LocalDate; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; //Events public class Event extends Task { - protected String start; - protected String end; + protected LocalDate startDate; + protected LocalDate endDate; + protected LocalTime startTime; + protected LocalTime endTime; public Event(String description, String start, String end) { super(description, CommandType.EVENT); - this.start = start; - this.end = end; + String[] startParts = start.split(" "); + String[] endParts = end.split(" "); + this.startDate = LocalDate.parse(startParts[0], DateTimeFormatter.ofPattern("yyyy-MM-dd")); + this.startTime = LocalTime.parse(startParts[1], DateTimeFormatter.ofPattern("HH:mm")); + this.endDate = LocalDate.parse(endParts[0], DateTimeFormatter.ofPattern("yyyy-MM-dd")); + this.endTime = LocalTime.parse(endParts[1], DateTimeFormatter.ofPattern("HH:mm")); } - public void setStart(String start) { - this.start = start; + public LocalDate getStartDate() { + return startDate; } - public String getStart() { - return start; - } - - - public void setEnd(String end) { - this.end = end; - } - - public String getEnd() { - return end; + @Override + public String toString() { + return "[E]" + super.toString() + " (from: " + startDate.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")) + " " + startTime + " to: " + + endDate.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")) + " " + endTime + ")"; } @Override - public String toString() { - return "[E]" + super.toString() + " (from: " + start + " to: " + end + ")"; + public String toSaveFormat() { + return "[E]" + super.toSaveFormat() + " (from: " + startDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + " " + startTime + " to: " + + endDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + " " + endTime + ")"; } } \ No newline at end of file diff --git a/src/main/java/chattycharlie/task/Task.java b/src/main/java/chattycharlie/task/Task.java index 02ced1f18..67a944f10 100644 --- a/src/main/java/chattycharlie/task/Task.java +++ b/src/main/java/chattycharlie/task/Task.java @@ -2,6 +2,8 @@ import chattycharlie.commands.CommandType; +import java.time.LocalDate; + //TASK CLASS public abstract class Task { protected String description; @@ -46,4 +48,8 @@ public String toString() { return "[" + getMarkedStatus() + "] " + description; } + public String toSaveFormat() { + return "[" + getMarkedStatus() + "] " + description; + } + } \ No newline at end of file diff --git a/src/main/java/chattycharlie/task/Todo.java b/src/main/java/chattycharlie/task/Todo.java index 1fe13eb67..83629a2b3 100644 --- a/src/main/java/chattycharlie/task/Todo.java +++ b/src/main/java/chattycharlie/task/Todo.java @@ -19,4 +19,9 @@ public boolean isDone() { public String toString() { return "[T]" + super.toString(); } + + @Override + public String toSaveFormat() { + return "[T]" + super.toSaveFormat(); + } } diff --git a/src/main/java/chattycharlie/userinteractions/Storage.java b/src/main/java/chattycharlie/userinteractions/Storage.java index cbc5bff3d..eded1373a 100644 --- a/src/main/java/chattycharlie/userinteractions/Storage.java +++ b/src/main/java/chattycharlie/userinteractions/Storage.java @@ -97,7 +97,7 @@ public void saveTasks(TaskList list) { for (int i = 0; i < list.getSize(); i++) { Task task = list.getTask(i); if (task != null) { - writer.write(taskToString(task) + "\n"); + writer.write(taskToSave(task) + "\n"); } } writer.close(); @@ -107,7 +107,7 @@ public void saveTasks(TaskList list) { } } - public String taskToString(Task task) { - return task.toString(); + public String taskToSave(Task task) { + return task.toSaveFormat(); } } diff --git a/src/main/java/chattycharlie/userinteractions/Ui.java b/src/main/java/chattycharlie/userinteractions/Ui.java index 7f21ab134..87596219a 100644 --- a/src/main/java/chattycharlie/userinteractions/Ui.java +++ b/src/main/java/chattycharlie/userinteractions/Ui.java @@ -21,7 +21,7 @@ public void displayGreetings(){ } public void displayTaskAdded(Task task) { - System.out.println(StringDesign.SPACE + "Added todo: " + task + System.lineSeparator() + StringDesign.LINE); + System.out.println(StringDesign.SPACE + "Added task: " + task + System.lineSeparator() + StringDesign.LINE); } public void displayTask(Task task) { @@ -41,19 +41,23 @@ public void displayError(String error) { } public void displayMarkingText(String line, int remainingTask) { - System.out.println(StringDesign.SPACE + line + " " + remainingTask + "to go!"); + System.out.println(StringDesign.SPACE + line + remainingTask + " to go!"); } public void displayDeletedTask(String line, int remainingTask) { - System.out.println(StringDesign.SPACE + line + " " + remainingTask + "to go!"); + System.out.println(StringDesign.SPACE + line + remainingTask + " to go!"); } public void displayListHeader(int remainingTask) { - System.out.println("ToDo List:"); + System.out.println("Task List:"); System.out.println("pending Task: " + remainingTask); } public void displayLine() { System.out.println(StringDesign.LINE); } + + public void displayTimeList() { + System.out.println("Tasks found:"); + } } From 7ce61692bada0640747c77c250471509a8884495 Mon Sep 17 00:00:00 2001 From: BevLow Date: Wed, 2 Oct 2024 00:21:14 +0800 Subject: [PATCH 37/50] Add Level-9 --- .../commands/CommandFactory.java | 2 ++ .../chattycharlie/commands/CommandType.java | 3 +- .../chattycharlie/commands/FindCommand.java | 34 +++++++++++++++++++ .../chattycharlie/commands/PrintCommand.java | 2 +- .../chattycharlie/userinteractions/Ui.java | 2 +- 5 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 src/main/java/chattycharlie/commands/FindCommand.java diff --git a/src/main/java/chattycharlie/commands/CommandFactory.java b/src/main/java/chattycharlie/commands/CommandFactory.java index f3319c2d6..c8d31acce 100644 --- a/src/main/java/chattycharlie/commands/CommandFactory.java +++ b/src/main/java/chattycharlie/commands/CommandFactory.java @@ -23,6 +23,8 @@ public static Command createCommand(CommandType commandType, String line) throws return new DeleteCommand(line); case PRINT: return new PrintCommand(line); + case FIND: + return new FindCommand(line); default: throw CharlieExceptions.cannotIdentifyCommandType(); //change this } diff --git a/src/main/java/chattycharlie/commands/CommandType.java b/src/main/java/chattycharlie/commands/CommandType.java index 9020311ce..564b73631 100644 --- a/src/main/java/chattycharlie/commands/CommandType.java +++ b/src/main/java/chattycharlie/commands/CommandType.java @@ -9,5 +9,6 @@ public enum CommandType { BYE, LIST, DELETE, - PRINT + PRINT, + FIND } \ No newline at end of file diff --git a/src/main/java/chattycharlie/commands/FindCommand.java b/src/main/java/chattycharlie/commands/FindCommand.java new file mode 100644 index 000000000..d94509d44 --- /dev/null +++ b/src/main/java/chattycharlie/commands/FindCommand.java @@ -0,0 +1,34 @@ +package chattycharlie.commands; + +import chattycharlie.CharlieExceptions; +import chattycharlie.TaskList; +import chattycharlie.task.Task; +import chattycharlie.userinteractions.Storage; +import chattycharlie.userinteractions.Ui; + +import java.time.format.DateTimeFormatter; + +public class FindCommand implements Command { + private String itemToBeFound; + + public FindCommand(String line) { + this.itemToBeFound = line.substring(5); + } + + @Override + public void execute(TaskList taskList, Ui ui, Storage storage) throws CharlieExceptions { + int count = 1; + ui.displaySearchList(); + for(int i = 0; i < taskList.getSize(); i++) { + Task task = taskList.getTask(i); + if(task.getDescription().contains(itemToBeFound)) { + ui.displayTaskInList(task, count); + count++; + } + } + if(count == 1) { + ui.displayError("No task found that contains: " + itemToBeFound ); + } + } + +} diff --git a/src/main/java/chattycharlie/commands/PrintCommand.java b/src/main/java/chattycharlie/commands/PrintCommand.java index 277081c48..bbb91827b 100644 --- a/src/main/java/chattycharlie/commands/PrintCommand.java +++ b/src/main/java/chattycharlie/commands/PrintCommand.java @@ -21,7 +21,7 @@ public PrintCommand(String line) { @Override public void execute(TaskList taskList, Ui ui, Storage storage) throws CharlieExceptions { int count = 1; - ui.displayTimeList(); + ui.displaySearchList(); for(int i = 0; i < taskList.getSize(); i++ ) { Task task = taskList.getTask(i); CommandType command = task.getType(); diff --git a/src/main/java/chattycharlie/userinteractions/Ui.java b/src/main/java/chattycharlie/userinteractions/Ui.java index 87596219a..b81e45e0e 100644 --- a/src/main/java/chattycharlie/userinteractions/Ui.java +++ b/src/main/java/chattycharlie/userinteractions/Ui.java @@ -57,7 +57,7 @@ public void displayLine() { System.out.println(StringDesign.LINE); } - public void displayTimeList() { + public void displaySearchList() { System.out.println("Tasks found:"); } } From 562d87d2557f7de1ea9db279b000133099449da4 Mon Sep 17 00:00:00 2001 From: BevLow Date: Wed, 2 Oct 2024 00:54:39 +0800 Subject: [PATCH 38/50] Add A-JavaDoc --- .../java/chattycharlie/ChattyCharlie.java | 15 ++ src/main/java/chattycharlie/TaskList.java | 242 +++++++++++------- .../chattycharlie/commands/UnmarkCommand.java | 2 +- 3 files changed, 164 insertions(+), 95 deletions(-) diff --git a/src/main/java/chattycharlie/ChattyCharlie.java b/src/main/java/chattycharlie/ChattyCharlie.java index 304302854..af457b715 100644 --- a/src/main/java/chattycharlie/ChattyCharlie.java +++ b/src/main/java/chattycharlie/ChattyCharlie.java @@ -3,11 +3,21 @@ import chattycharlie.commands.*; import chattycharlie.userinteractions. *; +/** + * Represents the main chatbot application. A ChattyCharlie object corresponds to + * a personal task management assistant capable of adding, listing, and managing user tasks. + */ public class ChattyCharlie { private Ui ui; private TaskList taskList; private Storage storage; + /** + * Constructs a ChattyCharlie object and initializes its user interface, + * storage, and task list. Attempts to load tasks from the specified file path. + * + * @param filePath The path of the file where tasks are saved and loaded from. + */ public ChattyCharlie(String filePath) { ui = new Ui(); storage = new Storage(filePath); @@ -19,6 +29,11 @@ public ChattyCharlie(String filePath) { } } + /** + * Starts the chatbot and handles the user interactions using a loop until the user decides to exit. + * Displays greeting, listens for user inputs, and processes the commands accordingly. + */ + public void run() { //Echo as a function ui.displayGreetings(); Parser parser = new Parser(); diff --git a/src/main/java/chattycharlie/TaskList.java b/src/main/java/chattycharlie/TaskList.java index 38000bdeb..5a0b9f91e 100644 --- a/src/main/java/chattycharlie/TaskList.java +++ b/src/main/java/chattycharlie/TaskList.java @@ -7,118 +7,172 @@ import chattycharlie.task.Todo; import java.util.ArrayList; -//LIST CLASS - public class TaskList { - private ArrayList tasks; - private int size; +/** + * Represents a list of tasks that the user inputs. A TaskList object allows + * users to add, delete, mark, unmark, and view tasks, providing the core functionality for the task list. + */ +public class TaskList { + private ArrayList tasks; + private int size; - //constructor - public TaskList() { - tasks = new ArrayList(); - size = 0; - } + /** + * Contructs an empty TaskList object with no task + */ + public TaskList() { + tasks = new ArrayList(); + size = 0; + } - public TaskList(TaskList list){ - this.tasks = list.tasks; - this.size = list.size; - } + /** + * Constructs a TaskList object based on an existing TaskList object. + * Copies the tasks in the provided list into this new list. + * + * @param list is the existing TaskList to copy tasks from + */ + public TaskList(TaskList list){ + this.tasks = list.tasks; + this.size = list.size; + } - //Method to add an item to the list - public void addTask(Task task) { - tasks.add(task); - size++; - } + /** + * Adds a task to the list. + * + * @param task The task to be added to the list. + */ + public void addTask(Task task) { + tasks.add(task); + size++; + } - public ArrayList getList() { - return this.tasks; - } + /** + * Returns the list of tasks. + * + * @return An ArrayList containing all the task in the list. + */ + public ArrayList getList() { + return this.tasks; + } - public Task getTask(int index) { - return this.tasks.get(index); - } + /** + * Retrieves a specific task by its index. + * + * @param index The index of the task to retrieve. + * @return The task at the specified index. + */ + public Task getTask(int index) { + return this.tasks.get(index); + } - public int getSize() { - return size; - } + /** + * Return the number of task currently in the list. + * + * @return The size of the list. + */ + public int getSize() { + return size; + } - //To mark - public void markTask(int index) { - Ui ui = new Ui(); - if (index >= 0 && index < size) { - tasks.get(index).markTask(); - int remainingTask = countUnmarkedTasks(); - ui.displayMarkingText("yay, 1 down!", remainingTask); - } else { - ui.displayError("Invalid task number."); - } + /** + * Marks a task as done, if the index is valid. + * If the index is not valid, it displays an error message. + * + * @param index The index of the task to be marked + */ + public void markTask(int index) { + Ui ui = new Ui(); + if (index >= 0 && index < size) { + tasks.get(index).markTask(); + int remainingTask = countUnmarkedTasks(); + ui.displayMarkingText("yay, 1 down!", remainingTask); + } else { + ui.displayError("Invalid task number."); } + } - //To unmark - public void unmarkTask(int index) { - Ui ui = new Ui(); - if (index >= 0 && index < size) { - tasks.get(index).unmarkTask(); - int remainingTask = countUnmarkedTasks(); - ui.displayMarkingText("Hmmm, not quite done yet,", remainingTask); - } else { - ui.displayError("Invalid task number."); - } + /** + * Unmarks a task as not done, if the index is valid. + * If the index is not valid, it displays an error message. + * + * @param index The index of the task to be unmarked + */ + public void unmarkTask(int index) { + Ui ui = new Ui(); + if (index >= 0 && index < size) { + tasks.get(index).unmarkTask(); + int remainingTask = countUnmarkedTasks(); + ui.displayMarkingText("Hmmm, not quite done yet,", remainingTask); + } else { + ui.displayError("Invalid task number."); } + } - //To delete + /** + * Deletes a task, if the index is valid. + * If the index is not valid, it displays an error message. + * Once deleted, it displays the count of remaining task left. + * + * @param index The index of the task to be deleted. + */ public void deleteTask(int index) { Ui ui = new Ui(); - if (index >= 0 && index < size) { - int remainingTask; - if(tasks.get(index).getIsDoneStatus()) { - remainingTask = countUnmarkedTasks(); - } else { - remainingTask = countUnmarkedTasks() -1; - } - ui.displayDeletedTask("Task is removed. Pending task: ", remainingTask); - ui.displayTask(tasks.get(index)); - tasks.remove(index); - size--; + if (index >= 0 && index < size) { + int remainingTask; + if(tasks.get(index).getIsDoneStatus()) { + remainingTask = countUnmarkedTasks(); + } else { + remainingTask = countUnmarkedTasks() -1; } + ui.displayDeletedTask("Task is removed. Pending task: ", remainingTask); + ui.displayTask(tasks.get(index)); + tasks.remove(index); + size--; + } } - //To print list - public void printList() { - int remainingTask = countUnmarkedTasks(); - Ui ui = new Ui(); - ui.displayListHeader(remainingTask); - for (int i = 0; i < size; i++) { - int number = i+1; - Task task = tasks.get(i); - //use a switch to determine - switch (task.getType()) { - case TODO: - Todo todoTask = (Todo) task; - ui.displayTaskInList(todoTask, number); - break; - case DEADLINE: - Deadline deadlineTask = (Deadline) task; - ui.displayTaskInList(deadlineTask, number); - break; - case EVENT: - Event eventTask = (Event) task; - ui.displayTaskInList(eventTask, number); - break; - default: - break; - } + /** + * Prints all task in the task list, with all the details. + * Displays a list header, followed by the number of task left unmarked and then the list of tasks. + * + */ + public void printList() { + int remainingTask = countUnmarkedTasks(); + Ui ui = new Ui(); + ui.displayListHeader(remainingTask); + for (int i = 0; i < size; i++) { + int number = i+1; + Task task = tasks.get(i); + switch (task.getType()) { + case TODO: + Todo todoTask = (Todo) task; + ui.displayTaskInList(todoTask, number); + break; + case DEADLINE: + Deadline deadlineTask = (Deadline) task; + ui.displayTaskInList(deadlineTask, number); + break; + case EVENT: + Event eventTask = (Event) task; + ui.displayTaskInList(eventTask, number); + break; + default: + break; } - ui.displayLine(); } + ui.displayLine(); + } - // Method to count how many tasks are unmarked - public int countUnmarkedTasks() { - int count = 0; - for (int i = 0; i < size; i++) { - if (!tasks.get(i).getIsDoneStatus()) { - count++; - } + /** + * Counts the number of tasks that are currently unmarked. + * + * @return The number of unmarked tasks. + */ + public int countUnmarkedTasks() { + int count = 0; + for (int i = 0; i < size; i++) { + if (!tasks.get(i).getIsDoneStatus()) { + count++; } - return count; } - } \ No newline at end of file + return count; + } +} \ No newline at end of file diff --git a/src/main/java/chattycharlie/commands/UnmarkCommand.java b/src/main/java/chattycharlie/commands/UnmarkCommand.java index d000c2aff..4ee574c75 100644 --- a/src/main/java/chattycharlie/commands/UnmarkCommand.java +++ b/src/main/java/chattycharlie/commands/UnmarkCommand.java @@ -14,7 +14,7 @@ public UnmarkCommand(String line) { @Override public void execute(TaskList taskList, Ui ui, Storage storage) { - taskList.markTask(toUnmarkIndex); + taskList.unmarkTask(toUnmarkIndex); ui.displayTask(taskList.getTask(toUnmarkIndex)); } } From 9d6381c5b0ab5bfbdb732729578a9525018c876e Mon Sep 17 00:00:00 2001 From: BevLow Date: Wed, 2 Oct 2024 16:11:48 +0800 Subject: [PATCH 39/50] Add A-JavaDoc-fixes --- .../java/chattycharlie/CharlieExceptions.java | 36 +++++++++-- .../chattycharlie/commands/ByeCommand.java | 18 +++++- .../java/chattycharlie/commands/Command.java | 20 ++++++ .../commands/CommandFactory.java | 14 +++++ .../chattycharlie/commands/CommandType.java | 4 ++ .../commands/DeadlineCommand.java | 19 ++++++ .../chattycharlie/commands/DeleteCommand.java | 19 ++++++ .../chattycharlie/commands/EventCommand.java | 19 ++++++ .../chattycharlie/commands/FindCommand.java | 21 ++++++- .../chattycharlie/commands/ListCommand.java | 14 +++++ .../chattycharlie/commands/MarkCommand.java | 19 ++++++ .../chattycharlie/commands/PrintCommand.java | 21 +++++++ .../chattycharlie/commands/TodoCommand.java | 19 ++++++ .../chattycharlie/commands/UnmarkCommand.java | 19 ++++++ .../java/chattycharlie/task/Deadline.java | 27 +++++++- src/main/java/chattycharlie/task/Event.java | 28 ++++++++- src/main/java/chattycharlie/task/Task.java | 51 +++++++++++++-- src/main/java/chattycharlie/task/Todo.java | 26 +++++--- .../userinteractions/Parser.java | 12 ++++ .../userinteractions/Storage.java | 34 ++++++++-- .../userinteractions/StringDesign.java | 30 ++++++++- .../chattycharlie/userinteractions/Ui.java | 63 +++++++++++++++++++ 22 files changed, 505 insertions(+), 28 deletions(-) diff --git a/src/main/java/chattycharlie/CharlieExceptions.java b/src/main/java/chattycharlie/CharlieExceptions.java index 209ecc054..bf1372709 100644 --- a/src/main/java/chattycharlie/CharlieExceptions.java +++ b/src/main/java/chattycharlie/CharlieExceptions.java @@ -2,28 +2,54 @@ import chattycharlie.commands.CommandType; +/** + * Represents all the exceptions used in ChattyCharlie task management + * This class extends {@link Exception} to handle specific error scenarios + */ public class CharlieExceptions extends Exception{ + + /** + * Constructs a new CharlieExceptions with the specified detail message. + * + * @param message the message to describe the exception + */ public CharlieExceptions(String message){ super(message); } - // Static factory methods for common exceptions + /** + * Creates an exception indicating that a description is missing fro the given command type + * + * @param command the type of command that is missing a description + * @return a CharlieExceptions instance with a specified missing error + */ public static CharlieExceptions missingDescription(CommandType command) { return new CharlieExceptions("Oop, the task for " + command + " cannot be empty."); } + /** + * Creates an exception indicating that a deadline is missing for a deadline task type. + * + * @return a CharlieExceptions instance with a specific error message. + */ public static CharlieExceptions missingDeadline() { return new CharlieExceptions("When is this due?"); } + /** + * Creates an exception indicating that the time is missing for a event task type. + * + * @return a CharlieExceptions instance with a specific error message. + */ public static CharlieExceptions missingTimes() { return new CharlieExceptions("Your event is missing or incomplete!"); } - public static CharlieExceptions missingDelete() { - return new CharlieExceptions("You forgot to specify which task."); - } - + /** + * Creates an exception indicating that the command type cannot be identified. + * + * @return a CharlieExceptions instance with a specific error message. + */ public static CharlieExceptions cannotIdentifyCommandType() { return new CharlieExceptions("Cannot identify command type."); } diff --git a/src/main/java/chattycharlie/commands/ByeCommand.java b/src/main/java/chattycharlie/commands/ByeCommand.java index b0293abbc..5791703ef 100644 --- a/src/main/java/chattycharlie/commands/ByeCommand.java +++ b/src/main/java/chattycharlie/commands/ByeCommand.java @@ -5,16 +5,32 @@ import chattycharlie.userinteractions.StringDesign; import chattycharlie.userinteractions.Ui; +/** + * Represents the command to exit the ChattyCharlie programme. + * This command will save the tasks to storage and display a farewell to the user + */ public class ByeCommand implements Command { + /** + * Executes the ByeCommand, which saves the tasks to storage and displays a farewell message. + * + * @param taskList the list of tasks to be saved. + * @param ui the user interface for interacting with the user. + * @param storage the storage system used to save tasks. + */ @Override public void execute(TaskList taskList, Ui ui, Storage storage) { storage.saveTasks(taskList); System.out.println(StringDesign.CHARLIE + StringDesign.FAREWELL); } + /** + * Indicates that this command will cause the application to exit. + * + * @return true since the ByeCommand is intended to terminate the application. + */ @Override public boolean isExit() { - return true; // This command causes the loop to exit + return true; } } diff --git a/src/main/java/chattycharlie/commands/Command.java b/src/main/java/chattycharlie/commands/Command.java index f2e06bf71..f292d9220 100644 --- a/src/main/java/chattycharlie/commands/Command.java +++ b/src/main/java/chattycharlie/commands/Command.java @@ -5,9 +5,29 @@ import chattycharlie.TaskList; import chattycharlie.userinteractions.Ui; +/** + * Represents a command that can be executed by ChattyCharlie. + * Implementations of this interface should define specific commands for the task management system. + */ public interface Command { + /** + * Executes the command with the given task list, user interface, and storage. + * + * @param taskList the list of tasks to be managed. + * @param ui the user interface to interact with the user. + * @param storage the storage system to save and load tasks. + * @throws CharlieExceptions if an error occurs during the execution of the command. + */ void execute(TaskList taskList, Ui ui, Storage storage) throws CharlieExceptions; + /** + * Determines if this command is an exit command. + * The default implementation returns false as + * most commands do not cause the application to exit. + * + * @return true if the command causes the application to exit, which is only the Bye Command + * false otherwise. + */ default boolean isExit() { return false; // Default behavior: most commands are not exit commands } diff --git a/src/main/java/chattycharlie/commands/CommandFactory.java b/src/main/java/chattycharlie/commands/CommandFactory.java index c8d31acce..cfbc658fd 100644 --- a/src/main/java/chattycharlie/commands/CommandFactory.java +++ b/src/main/java/chattycharlie/commands/CommandFactory.java @@ -2,7 +2,21 @@ import chattycharlie.CharlieExceptions; +/** + * Represents a factory for creating different types of commands for the ChattyCharlie system. + * The CommandFactory class provides a method to create instances of commands base on + * the given command type in the user input + */ public class CommandFactory { + + /** + * Creates a command instance based on the provided CommandType and user input line. + * + * @param commandType the type of command to create. + * @param line the user input line associated with the command type. + * @return the instance of the command to be executed. + * @throws CharlieExceptions if the command type cannot be identified. + */ public static Command createCommand(CommandType commandType, String line) throws CharlieExceptions { switch (commandType) { case TODO: diff --git a/src/main/java/chattycharlie/commands/CommandType.java b/src/main/java/chattycharlie/commands/CommandType.java index 564b73631..815ac1803 100644 --- a/src/main/java/chattycharlie/commands/CommandType.java +++ b/src/main/java/chattycharlie/commands/CommandType.java @@ -1,5 +1,9 @@ package chattycharlie.commands; +/** + * Represents the different types of commands that can be executed by ChattyCharlie. + * Each enum value corresponds to a specific command type. + */ public enum CommandType { TODO, DEADLINE, diff --git a/src/main/java/chattycharlie/commands/DeadlineCommand.java b/src/main/java/chattycharlie/commands/DeadlineCommand.java index 6846449f5..88ac7881b 100644 --- a/src/main/java/chattycharlie/commands/DeadlineCommand.java +++ b/src/main/java/chattycharlie/commands/DeadlineCommand.java @@ -7,10 +7,21 @@ import chattycharlie.task.Deadline; import chattycharlie.task.Task; +/** + * Represents the command to be executed with the user inputs a deadline task. + * This command will create a deadline task and save it to the task list + */ public class DeadlineCommand implements Command { private String description; private String by; + /** + * Constructs a DeadlineCommand from the provided user input line. + * Parses the input to extract the task description and deadline time. + * + * @param line the input line containing the command and task details. + * @throws CharlieExceptions if the description or deadline time is missing. + */ public DeadlineCommand(String line) throws CharlieExceptions { String[] deadlineParts = line.substring(8).trim().split(" by "); if (deadlineParts[0].isEmpty()) { @@ -23,6 +34,14 @@ public DeadlineCommand(String line) throws CharlieExceptions { this.by = deadlineParts[1].trim(); } + /** + * Executes the DeadlineCommand by adding the deadline task to the task list, + * displaying a confirmation message to the user, and saving the updated task list. + * + * @param taskList the list of tasks to add the new deadline task to. + * @param ui the user interface to display output to the user. + * @param storage the storage system to save the updated task list. + */ @Override public void execute(TaskList taskList, Ui ui, Storage storage) { Task deadlineTask = new Deadline(description, by); diff --git a/src/main/java/chattycharlie/commands/DeleteCommand.java b/src/main/java/chattycharlie/commands/DeleteCommand.java index 73435b5c0..d54cd034a 100644 --- a/src/main/java/chattycharlie/commands/DeleteCommand.java +++ b/src/main/java/chattycharlie/commands/DeleteCommand.java @@ -5,14 +5,33 @@ import chattycharlie.TaskList; import chattycharlie.userinteractions.Ui; +/** + * Represents the command to delete a task from the task list. + * This command takes an index as input and removes the corresponding task. + */ public class DeleteCommand implements Command { private int toDeleteIndex; + /** + * Constructs a DeleteCommand using the provided input line. + * Parses the input to determine which task index to delete. + * + * @param line the input line containing the task index to delete. + * @throws CharlieExceptions if the index provided is not a valid integer. + */ public DeleteCommand(String line) throws CharlieExceptions { String toDeleteIndex = line.substring(7).trim(); this.toDeleteIndex = Integer.parseInt(toDeleteIndex) - 1; } + /** + * Executes the DeleteCommand by deleting the task at the specified index + * from the task list. + * + * @param taskList the list of tasks from which a task will be deleted. + * @param ui the user interface for displaying output to the user. + * @param storage the storage system to save changes made to the task list. + */ @Override public void execute(TaskList taskList, Ui ui, Storage storage) { taskList.deleteTask(toDeleteIndex); diff --git a/src/main/java/chattycharlie/commands/EventCommand.java b/src/main/java/chattycharlie/commands/EventCommand.java index dc7279aa5..510dfe981 100644 --- a/src/main/java/chattycharlie/commands/EventCommand.java +++ b/src/main/java/chattycharlie/commands/EventCommand.java @@ -7,11 +7,22 @@ import chattycharlie.task.Event; import chattycharlie.task.Task; +/** + * Represents the command to be executed when the user inputs an event task. + * This command creates an event task and adds it to the task list. + */ public class EventCommand implements Command{ private String description; private String from; private String to; + /** + * Constructs an EventCommand from the provided user input line. + * Parses the input to extract the task description, start time, and end time. + * + * @param line the input line containing the command and event task details. + * @throws CharlieExceptions if the description or event times are missing or incomplete. + */ public EventCommand(String line) throws CharlieExceptions { String[] eventParts = line.substring(5).trim().split("from"); @@ -37,6 +48,14 @@ public EventCommand(String line) throws CharlieExceptions { } } + /** + * Executes the EventCommand by adding the event task to the task list, + * displaying a confirmation message to the user, and saving the updated task list. + * + * @param taskList the list of tasks to add the new event task to. + * @param ui the user interface to display output to the user. + * @param storage the storage system to save the updated task list. + */ @Override public void execute(TaskList taskList, Ui ui, Storage storage) { Task eventTask = new Event(description, from, to); diff --git a/src/main/java/chattycharlie/commands/FindCommand.java b/src/main/java/chattycharlie/commands/FindCommand.java index d94509d44..583c34dfd 100644 --- a/src/main/java/chattycharlie/commands/FindCommand.java +++ b/src/main/java/chattycharlie/commands/FindCommand.java @@ -6,15 +6,32 @@ import chattycharlie.userinteractions.Storage; import chattycharlie.userinteractions.Ui; -import java.time.format.DateTimeFormatter; - +/** + * Represents the command to find a task based on a search keyword. + * This command searches through the task list and displays any matching tasks. + */ public class FindCommand implements Command { private String itemToBeFound; + /** + * Constructs a FindCommand using the provided input line. + * Extracts the keyword to be searched in the task list. + * + * @param line the input line containing the command and keyword to search for. + */ public FindCommand(String line) { this.itemToBeFound = line.substring(5); } + /** + * Executes the FindCommand by searching the task list for tasks that contain + * the specified keyword and displaying the matching tasks to the user. + * + * @param taskList the list of tasks to search. + * @param ui the user interface for displaying search results. + * @param storage the storage system (not used in this command). + * @throws CharlieExceptions if an error occurs during the command execution. + */ @Override public void execute(TaskList taskList, Ui ui, Storage storage) throws CharlieExceptions { int count = 1; diff --git a/src/main/java/chattycharlie/commands/ListCommand.java b/src/main/java/chattycharlie/commands/ListCommand.java index 10684024b..54ccc6c9f 100644 --- a/src/main/java/chattycharlie/commands/ListCommand.java +++ b/src/main/java/chattycharlie/commands/ListCommand.java @@ -5,7 +5,21 @@ import chattycharlie.TaskList; import chattycharlie.userinteractions.Ui; +/** + * Represents the command to list all tasks. + * This command displays the entire task list to the user. + */ public class ListCommand implements Command { + + /** + * Executes the ListCommand by displaying the entire list of tasks + * to the user through the user interface. + * + * @param taskList the list of tasks to be displayed. + * @param ui the user interface for displaying the task list. + * @param storage the storage system (not used in this command). + * @throws CharlieExceptions if an error occurs during the command execution. + */ @Override public void execute(TaskList taskList, Ui ui, Storage storage) throws CharlieExceptions { ui.displayList(taskList); diff --git a/src/main/java/chattycharlie/commands/MarkCommand.java b/src/main/java/chattycharlie/commands/MarkCommand.java index 215a6ecf2..5cba27124 100644 --- a/src/main/java/chattycharlie/commands/MarkCommand.java +++ b/src/main/java/chattycharlie/commands/MarkCommand.java @@ -4,14 +4,33 @@ import chattycharlie.TaskList; import chattycharlie.userinteractions.Ui; +/** + * Represents the command to mark a task as completed. + * This command marks a task at the specified index in the task list. + */ public class MarkCommand implements Command { private int toMarkIndex; + /** + * Constructs a MarkCommand using the provided input line. + * Extracts the task index that needs to be marked as completed. + * + * @param line the input line containing the command and task index to mark as completed. + * @throws NumberFormatException if the index provided is not a valid integer. + */ public MarkCommand(String line) { String toMarkIndex = line.substring(4).trim(); this.toMarkIndex = Integer.parseInt(toMarkIndex) - 1; } + /** + * Executes the MarkCommand by marking the task at the specified index + * in the task list and displaying the updated task to the user. + * + * @param taskList the list of tasks where a task will be marked as completed. + * @param ui the user interface for displaying the updated task. + * @param storage the storage system to save the updated task list. + */ @Override public void execute(TaskList taskList, Ui ui, Storage storage) { taskList.markTask(toMarkIndex); diff --git a/src/main/java/chattycharlie/commands/PrintCommand.java b/src/main/java/chattycharlie/commands/PrintCommand.java index bbb91827b..19f0ef9fc 100644 --- a/src/main/java/chattycharlie/commands/PrintCommand.java +++ b/src/main/java/chattycharlie/commands/PrintCommand.java @@ -9,15 +9,36 @@ import java.time.LocalDate; import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +/** + * Represents the command to print tasks based on a specific date. + * This command searches the task list for any tasks that match the provided date. + */ public class PrintCommand implements Command{ private LocalDate time; + /** + * Constructs a PrintCommand using the provided input line. + * Parses the input to extract the date to filter tasks by. + * + * @param line the input line containing the command and the date to filter tasks. + * @throws DateTimeParseException if the provided date is not in the correct format. + */ public PrintCommand(String line) { String timeText = line.substring(6).trim(); this.time = LocalDate.parse(timeText, DateTimeFormatter.ofPattern("yyyy-MM-dd")); } + /** + * Executes the PrintCommand by searching for and displaying tasks that + * match the specified date. It looks for deadlines and events that match the given date. + * + * @param taskList the list of tasks to search. + * @param ui the user interface for displaying the search results. + * @param storage the storage system (not used in this command). + * @throws CharlieExceptions if an error occurs during the command execution. + */ @Override public void execute(TaskList taskList, Ui ui, Storage storage) throws CharlieExceptions { int count = 1; diff --git a/src/main/java/chattycharlie/commands/TodoCommand.java b/src/main/java/chattycharlie/commands/TodoCommand.java index 3d69547de..aae7024e3 100644 --- a/src/main/java/chattycharlie/commands/TodoCommand.java +++ b/src/main/java/chattycharlie/commands/TodoCommand.java @@ -7,9 +7,20 @@ import chattycharlie.task.Task; import chattycharlie.task.Todo; +/** + * Represents the command to add a to-do task to the task list. + * This command creates a new to-do task and adds it to the list of tasks. + */ public class TodoCommand implements Command{ private String description; + /** + * Constructs a TodoCommand using the provided input line. + * Parses the input to extract the description of the to-do task. + * + * @param line the input line containing the command and task description. + * @throws CharlieExceptions if the to-do description is missing. + */ public TodoCommand(String line) throws CharlieExceptions { String text = line.substring(4).trim(); if (text.isEmpty()) { @@ -19,6 +30,14 @@ public TodoCommand(String line) throws CharlieExceptions { } } + /** + * Executes the TodoCommand by adding the to-do task to the task list, + * displaying a confirmation message to the user, and saving the updated task list. + * + * @param taskList the list of tasks to add the new to-do task to. + * @param ui the user interface for displaying output to the user. + * @param storage the storage system to save the updated task list. + */ @Override public void execute(TaskList taskList, Ui ui, Storage storage){ Task todoTask = new Todo(description); diff --git a/src/main/java/chattycharlie/commands/UnmarkCommand.java b/src/main/java/chattycharlie/commands/UnmarkCommand.java index 4ee574c75..807b239a4 100644 --- a/src/main/java/chattycharlie/commands/UnmarkCommand.java +++ b/src/main/java/chattycharlie/commands/UnmarkCommand.java @@ -4,14 +4,33 @@ import chattycharlie.TaskList; import chattycharlie.userinteractions.Ui; +/** + * Represents the command to unmark a task as incomplete. + * This command unmarks a task at the specified index in the task list. + */ public class UnmarkCommand implements Command { private int toUnmarkIndex; + /** + * Constructs an UnmarkCommand using the provided input line. + * Extracts the task index that needs to be unmarked as incomplete. + * + * @param line the input line containing the command and task index to unmark. + * @throws NumberFormatException if the index provided is not a valid integer. + */ public UnmarkCommand(String line) { String toUnmarkIndex = line.substring(4).trim(); this.toUnmarkIndex = Integer.parseInt(toUnmarkIndex) - 1; } + /** + * Executes the UnmarkCommand by unmarking the task at the specified index + * in the task list and displaying the updated task to the user. + * + * @param taskList the list of tasks where a task will be unmarked as incomplete. + * @param ui the user interface for displaying the updated task. + * @param storage the storage system to save the updated task list. + */ @Override public void execute(TaskList taskList, Ui ui, Storage storage) { taskList.unmarkTask(toUnmarkIndex); diff --git a/src/main/java/chattycharlie/task/Deadline.java b/src/main/java/chattycharlie/task/Deadline.java index 82c01df7c..a933f2ac4 100644 --- a/src/main/java/chattycharlie/task/Deadline.java +++ b/src/main/java/chattycharlie/task/Deadline.java @@ -4,24 +4,49 @@ import java.time.LocalDate; import java.time.format.DateTimeFormatter; -//Deadline Class +/** + * Represents a deadline task, a task with a specified deadline. + * A Deadline task has a description and a date by which it must be completed. + */ public class Deadline extends Task { protected LocalDate by; + /** + * Constructs a Deadline task with the specified description and due date. + * + * @param description the description of the deadline task. + * @param by the due date for the task in yyyy-MM-dd format. + */ public Deadline(String description, String by) { super(description, CommandType.DEADLINE); this.by = LocalDate.parse(by, DateTimeFormatter.ofPattern("yyyy-MM-dd")); } + /** + * Gets the due date of the deadline task. + * + * @return the due date as a LocalDate. + */ public LocalDate getBy() { return by; } + /** + * Returns a string representation of the deadline task, including its marked status, + * description, and due date. + * + * @return a string representation of the deadline task. + */ @Override public String toString() { return "[D]" + super.toString() + " (by: " + by.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")) + ")"; } + /** + * Returns a string representation of the deadline task in a format suitable for saving. + * + * @return a string representation of the deadline task formatted for saving. + */ @Override public String toSaveFormat() { return "[D]" + super.toSaveFormat() + " (by: " + by.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + ")"; diff --git a/src/main/java/chattycharlie/task/Event.java b/src/main/java/chattycharlie/task/Event.java index 426e016e1..2f4cd3c78 100644 --- a/src/main/java/chattycharlie/task/Event.java +++ b/src/main/java/chattycharlie/task/Event.java @@ -5,13 +5,23 @@ import java.time.LocalTime; import java.time.format.DateTimeFormatter; -//Events +/** + * Represents an event task with a specific start and end date and time. + * An Event task has a description, a start date and time, and an end date and time. + */ public class Event extends Task { protected LocalDate startDate; protected LocalDate endDate; protected LocalTime startTime; protected LocalTime endTime; + /** + * Constructs an Event task with the specified description, start time, and end time. + * + * @param description the description of the event task. + * @param start the start date and time in yyyy-MM-dd HH:mm format. + * @param end the end date and time in yyyy-MM-dd HH:mm format. + */ public Event(String description, String start, String end) { super(description, CommandType.EVENT); String[] startParts = start.split(" "); @@ -22,16 +32,32 @@ public Event(String description, String start, String end) { this.endTime = LocalTime.parse(endParts[1], DateTimeFormatter.ofPattern("HH:mm")); } + /** + * Gets the start date of the event task. + * + * @return the start date as a LocalDate. + */ public LocalDate getStartDate() { return startDate; } + /** + * Returns a string representation of the event task, including its marked status, + * description, start date and time, and end date and time. + * + * @return a string representation of the event task. + */ @Override public String toString() { return "[E]" + super.toString() + " (from: " + startDate.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")) + " " + startTime + " to: " + endDate.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")) + " " + endTime + ")"; } + /** + * Returns a string representation of the event task in a format suitable for saving. + * + * @return a string representation of the event task formatted for saving. + */ @Override public String toSaveFormat() { return "[E]" + super.toSaveFormat() + " (from: " + startDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + " " + startTime + " to: " diff --git a/src/main/java/chattycharlie/task/Task.java b/src/main/java/chattycharlie/task/Task.java index 67a944f10..f8ebc02e8 100644 --- a/src/main/java/chattycharlie/task/Task.java +++ b/src/main/java/chattycharlie/task/Task.java @@ -4,50 +4,91 @@ import java.time.LocalDate; -//TASK CLASS +/** + * Represents an abstract task in the ChattyCharlie application. + * Each task has a description, a status indicating if it's done, and a command type. + */ public abstract class Task { protected String description; protected boolean isDone; protected CommandType type; - //constructor + /** + * Constructs a Task with the specified description and type. + * + * @param description the description of the task. + * @param type the command type associated with the task. + */ public Task(String description, CommandType type) { this.description = description; this.isDone = false; this.type = type; } - //check if its marked as done + /** + * Gets the marked status of the task. + * + * @return "X" if the task is done, otherwise a blank space. + */ public String getMarkedStatus() { return (isDone ? "X" : " "); } + /** + * Gets the done status of the task. + * + * @return true if the task is done, false otherwise. + */ public boolean getIsDoneStatus() { return this.isDone; } + /** + * Gets the command type of the task. + * + * @return the CommandType of the task. + */ public CommandType getType() { return type; } + /** + * Gets the description of the task. + * + * @return the description of the task. + */ public String getDescription() { return this.description; } - //to toggle the task + /** + * Marks the task as done. + */ public void markTask() { this.isDone = true; //change the variable } + /** + * Unmarks the task, setting it as incomplete. + */ public void unmarkTask() { this.isDone = false; //change the variable } - + /** + * Returns a string representation of the task, including its marked status and description. + * + * @return a string representation of the task. + */ public String toString() { return "[" + getMarkedStatus() + "] " + description; } + /** + * Returns a string representation of the task in a format suitable for saving. + * + * @return a string representation of the task formatted for saving. + */ public String toSaveFormat() { return "[" + getMarkedStatus() + "] " + description; } diff --git a/src/main/java/chattycharlie/task/Todo.java b/src/main/java/chattycharlie/task/Todo.java index 83629a2b3..c59470e95 100644 --- a/src/main/java/chattycharlie/task/Todo.java +++ b/src/main/java/chattycharlie/task/Todo.java @@ -2,24 +2,36 @@ import chattycharlie.commands.CommandType; -//todo class +/** + * Represents a simple to-do task without any date or time constraints. + * A Todo task has only a description and a completion status. + */ public class Todo extends Task { + /** + * Constructs a Todo task with the specified description. + * + * @param description the description of the to-do task. + */ public Todo(String description) { super(description, CommandType.TODO); } - public void setDone(boolean done) { - isDone = done; - } - public boolean isDone() { - return isDone; - } + /** + * Returns a string representation of the to-do task, including its marked status and description. + * + * @return a string representation of the to-do task. + */ @Override public String toString() { return "[T]" + super.toString(); } + /** + * Returns a string representation of the to-do task in a format suitable for saving. + * + * @return a string representation of the to-do task formatted for saving. + */ @Override public String toSaveFormat() { return "[T]" + super.toSaveFormat(); diff --git a/src/main/java/chattycharlie/userinteractions/Parser.java b/src/main/java/chattycharlie/userinteractions/Parser.java index c2ea37038..491cc7acd 100644 --- a/src/main/java/chattycharlie/userinteractions/Parser.java +++ b/src/main/java/chattycharlie/userinteractions/Parser.java @@ -2,7 +2,19 @@ import chattycharlie.commands.CommandType; +/** + * Represents a parser that interprets user input and determines the command type. + * The Parser class helps to extract the command from user input. + */ public class Parser { + + /** + * Parses the user input to determine the command type. + * + * @param input the user input as a string. + * @return the corresponding CommandType for the given input. + * @throws IllegalArgumentException if the input does not match any known command. + */ public CommandType getCommand(String input) { String firstWord = input.split(" ")[0]; return CommandType.valueOf(firstWord.toUpperCase()); diff --git a/src/main/java/chattycharlie/userinteractions/Storage.java b/src/main/java/chattycharlie/userinteractions/Storage.java index eded1373a..259e70861 100644 --- a/src/main/java/chattycharlie/userinteractions/Storage.java +++ b/src/main/java/chattycharlie/userinteractions/Storage.java @@ -13,12 +13,28 @@ import java.io.IOException; import java.util.Scanner; +/** + * Represents the storage system for saving and loading tasks. + * The Storage class handles reading from and writing to the file specified by the user. + */ public class Storage { private String filePath; + /** + * Constructs a Storage object with the specified file path. + * + * @param filePath the path of the file used for saving and loading tasks. + */ public Storage(String filePath) { this.filePath = filePath; } + + /** + * Loads tasks from the storage file into a TaskList. + * + * @return a TaskList containing all tasks read from the storage file. + * @throws CharlieExceptions if an error occurs while loading the tasks. + */ public TaskList load() throws CharlieExceptions { TaskList list = new TaskList(); File file = new File(filePath); @@ -42,6 +58,13 @@ public TaskList load() throws CharlieExceptions { return list; } + /** + * Parses a string representing a task and returns the corresponding Task object. + * + * @param taskText the string representing a task. + * @return the corresponding Task object, or null if the task cannot be parsed. + * @throws IllegalArgumentException if the task type is unknown. + */ public Task parseTask(String taskText) { taskText = taskText.trim(); //trim away the formatting char taskType = taskText.charAt(1); //get the commandType @@ -90,14 +113,18 @@ public Task parseTask(String taskText) { return null; } - //to save a file (called before the program ends) + /** + * Saves all tasks from the TaskList to the storage file. + * + * @param list the TaskList containing tasks to be saved. + */ public void saveTasks(TaskList list) { try { FileWriter writer = new FileWriter(filePath); for (int i = 0; i < list.getSize(); i++) { Task task = list.getTask(i); if (task != null) { - writer.write(taskToSave(task) + "\n"); + writer.write(task.toSaveFormat() + "\n"); } } writer.close(); @@ -107,7 +134,4 @@ public void saveTasks(TaskList list) { } } - public String taskToSave(Task task) { - return task.toSaveFormat(); - } } diff --git a/src/main/java/chattycharlie/userinteractions/StringDesign.java b/src/main/java/chattycharlie/userinteractions/StringDesign.java index a5ab00dec..87a208724 100644 --- a/src/main/java/chattycharlie/userinteractions/StringDesign.java +++ b/src/main/java/chattycharlie/userinteractions/StringDesign.java @@ -1,7 +1,14 @@ package chattycharlie.userinteractions; +/** + * Represents the string designs and constants used in the ChattyCharlie application. + * The StringDesign class provides static string values for user interface elements. + */ public class StringDesign { - //this class is for all my Strings and designs + + /** + * The logo of ChattyCharlie, represented as an ASCII art string. + */ public static final String LOGO = " _____ \n" + " / \\ \n" + " | O O | \n" @@ -12,14 +19,35 @@ public class StringDesign { + " | | \n" + " |_______| \n" + " \n"; + + /** + * The prefix used for messages from ChattyCharlie. + */ public static final String CHARLIE = "Charlie: "; + /** + * The greeting message displayed when ChattyCharlie starts. + */ public static final String GREETING = "Hello! I'm ChattyCharlie, your consistent buddy.\n" + " What shall we do today?\n"; + /** + * The farewell message displayed when ChattyCharlie ends. + */ public static final String FAREWELL = "All the best in clearing your list!"; + /** + * A constant space string used for spacing purposes in the user interface. + */ public static final String SPACE = " "; + + /** + * A constant line string used to separate sections in the user interface. + */ public static final String LINE = "------------"; + + /** + * The prefix used for messages from the user. + */ public static final String YOU = "User: "; } \ No newline at end of file diff --git a/src/main/java/chattycharlie/userinteractions/Ui.java b/src/main/java/chattycharlie/userinteractions/Ui.java index b81e45e0e..6d336ee6b 100644 --- a/src/main/java/chattycharlie/userinteractions/Ui.java +++ b/src/main/java/chattycharlie/userinteractions/Ui.java @@ -5,8 +5,17 @@ import java.util.Scanner; +/** + * Represents the user interface for interacting with the user. + * The Ui class handles input from the user and displays messages. + */ public class Ui { + /** + * Gets the user's input from the console. + * + * @return the user's input as a string. + */ public String getUserInput() { Scanner scanner = new Scanner(System.in); @@ -16,47 +25,101 @@ public String getUserInput() { return userInput; } + /** + * Displays the greeting message and logo when ChattyCharlie starts. + */ public void displayGreetings(){ System.out.println(StringDesign.LOGO + StringDesign.CHARLIE + StringDesign.GREETING); } + /** + * Displays a message indicating that a task has been added. + * + * @param task the task that has been added. + */ public void displayTaskAdded(Task task) { System.out.println(StringDesign.SPACE + "Added task: " + task + System.lineSeparator() + StringDesign.LINE); } + /** + * Displays the details of a given task. + * + * @param task the task to be displayed. + */ public void displayTask(Task task) { System.out.println(StringDesign.SPACE + task + System.lineSeparator() + StringDesign.LINE); } + /** + * Displays the entire list of tasks. + * + * @param list the TaskList containing all tasks. + */ public void displayList(TaskList list) { list.printList(); } + /** + * Displays a task as part of a list with its corresponding index number. + * + * @param task the task to be displayed. + * @param number the index number of the task in the list. + */ public void displayTaskInList(Task task, int number) { System.out.println(StringDesign.SPACE + number +". " + task); } + /** + * Displays an error message. + * + * @param error the error message to be displayed. + */ public void displayError(String error) { System.out.println(error + System.lineSeparator() + StringDesign.LINE); } + /** + * Displays a message indicating that the task has been marked or unamrked and + * the number of remaining tasks after marking or unmarking a task. + * + * @param line the message to be displayed. + * @param remainingTask the number of tasks remaining. + */ public void displayMarkingText(String line, int remainingTask) { System.out.println(StringDesign.SPACE + line + remainingTask + " to go!"); } + /** + * Displays a message indicating that a task has been deleted along with the number of remaining tasks. + * + * @param line the message to be displayed. + * @param remainingTask the number of tasks remaining. + */ public void displayDeletedTask(String line, int remainingTask) { System.out.println(StringDesign.SPACE + line + remainingTask + " to go!"); } + /** + * Displays the header for the task list, including the number of remaining tasks. + * + * @param remainingTask the number of tasks remaining. + */ public void displayListHeader(int remainingTask) { System.out.println("Task List:"); System.out.println("pending Task: " + remainingTask); } + /** + * Displays a line separator. + */ public void displayLine() { System.out.println(StringDesign.LINE); } + /** + * Displays the header for a task list with a specified parameter for the tasks in the list. + * Used in the command PRINT and FIND + */ public void displaySearchList() { System.out.println("Tasks found:"); } From 769a80bf718186d8b64d12c7e977892effa3c29c Mon Sep 17 00:00:00 2001 From: BevLow Date: Fri, 4 Oct 2024 14:45:58 +0800 Subject: [PATCH 40/50] Add A-UserGuide --- docs/README.md | 143 ++++++++++++++++-- docs/img.png | Bin 0 -> 15563 bytes .../java/chattycharlie/ChattyCharlie.java | 2 +- src/main/java/chattycharlie/TaskList.java | 4 +- .../chattycharlie/commands/UnmarkCommand.java | 2 +- .../userinteractions/Parser.java | 2 +- 6 files changed, 135 insertions(+), 18 deletions(-) create mode 100644 docs/img.png diff --git a/docs/README.md b/docs/README.md index 47b9f984f..e0fe8bbac 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,30 +1,147 @@ -# Duke User Guide +# Chatty Charlie User Guide -// Update the title above to match the actual product name -// Product screenshot goes here +[img.png](img.png) -// Product intro goes here +Chatty Charlie is a desktop app for managing tasks, optimized for use via a Command Line Interface (CLI) while still having the benefits of a Graphical User Interface (GUI). +If you can type fast, AB3 can track your task faster than traditional GUI apps. ## Adding deadlines +Add a task that has a specific deadline. You provide the task description along with a deadline date. -// Describe the action and its outcome. +Format: deadline TASK_DESCRIPTION by DATE -// Give examples of usage +Example: `deadline Submit project report by 2024-10-15` -Example: `keyword (optional arguments)` +When the command is successfully executed, it will add the task to your task list with the specified deadline. For example: -// A description of the expected outcome goes here +``` +------------ + Added task: [D][ ] make a box (by: 04/10/2024) +------------ +``` + +## Adding todos + +Adds a simple task without a specific deadline. + +Format: todo TASK_DESCRIPTION + +Example: `todo Buy groceries` +When the command is successfully executed, it will add the task to your list. For example: ``` -expected output +------------ + Added task: [T][ ] Buy groceries +------------ ``` -## Feature ABC +## Adding events +Add an event that takes place at a specific date and time. + +Format: event TASK_DESCRIPTION from START_DATE START_TIME to END_DATE ENDTIME + +Example: `event Team meeting from 2024-10-01 15:00 to 2024-10-01 18:00` + +When the command is successfully executed, it will add the task to your list. For example: +``` +------------ +Added task: [E][ ] Team meeting (from: 01/10/2024 15:00 to: 01/10/2024 18:00) +------------ +``` -// Feature details +## Marking a task as done +Mark a task as completed. You need to provide the task number from the task list. +Format: mark TASK_NUMBER + +Example: `mark 1` + +When the command is successfully executed, it will mark your task with an X. For example: +``` +------------ + yay, 1 down! 4 to go! + [D][X] make a box (by: 11/12/1999) +------------ +``` + +## Marking a task as undone +Mark a task as incompleted. You need to provide the task number from the task list. + +Format: unmark TASK_NUMBER + +Example: `unmark 1` + +When the command is successfully executed, it will unmark the task, removing the X. For example: +``` +------------ + Hmmm, not quite done yet, 4 to go! + [D][ ] make a box (by: 04/10/2024) +------------ +``` -## Feature XYZ +## Deleting a task +Deletes a task from the task list. You need to provide the task number. -// Feature details \ No newline at end of file +Format: delete TASK_NUMBER + +Example: `delete 1` + +When the command is successfully executed, the specified task will be removed from the list. For example: +``` +------------ + Task is removed. Pending task: 4 to go! + [D][X] make a box (by: 11/12/1999) +------------ +``` + +## Finding tasks containing the same keyword +Finds tasks in the list that contain a specific keyword. + +Format: find KEYWORD + +Example: `find book` + +When the command is successfully executed, all tasks containing the keyword will be listed. For example: +``` +------------ +Tasks found: + 1. [T][ ] buy a book + 2. [D][ ] read a book (by: 02/10/2024) + 3. [E][ ] book fair (from: 05/10/2024 15:00 to: 07/10/2024 15:00) +------------ +``` + +## Printing the whole list of task +Displays all tasks currently in the task list. + +Format: list + +When the command is successfully executed, all tasks will be printed. For example: +``` +------------ +Task List: +pending Task: 5 + 1. [T][ ] buy a book + 2. [D][ ] read a book (by: 02/10/2024) + 3. [E][ ] book fair (from: 05/10/2024 15:00 to: 07/10/2024 15:00) + 4. [T][ ] make a box + 5. [E][ ] go for a run (from: 08/10/2024 07:00 to: 08/10/2024 08:00) +------------ +``` + +## Printing the list of deadlines and events due or happening on a specified date +Displays all task that is occuring or due on the same date + +Format: print DATE + +Example: `print 2024-10-05` + +When the command is successfully executed, all relevant tasks for the given date will be listed. For example: +``` +------------ +Tasks found: + 1. [E][ ] book fair (from: 05/10/2024 15:00 to: 07/10/2024 15:00) + 2. [D][ ] read a book (by: 05/10/2024) +------------ +``` \ No newline at end of file diff --git a/docs/img.png b/docs/img.png new file mode 100644 index 0000000000000000000000000000000000000000..6f738657dc173058900ac2d1fb2980dcc78f1b3e GIT binary patch literal 15563 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 0 && index < size) { tasks.get(index).markTask(); int remainingTask = countUnmarkedTasks(); - ui.displayMarkingText("yay, 1 down!", remainingTask); + ui.displayMarkingText("yay, 1 down! ", remainingTask); } else { ui.displayError("Invalid task number."); } @@ -100,7 +100,7 @@ public void unmarkTask(int index) { if (index >= 0 && index < size) { tasks.get(index).unmarkTask(); int remainingTask = countUnmarkedTasks(); - ui.displayMarkingText("Hmmm, not quite done yet,", remainingTask); + ui.displayMarkingText("Hmmm, not quite done yet, ", remainingTask); } else { ui.displayError("Invalid task number."); } diff --git a/src/main/java/chattycharlie/commands/UnmarkCommand.java b/src/main/java/chattycharlie/commands/UnmarkCommand.java index 807b239a4..b2abf4678 100644 --- a/src/main/java/chattycharlie/commands/UnmarkCommand.java +++ b/src/main/java/chattycharlie/commands/UnmarkCommand.java @@ -19,7 +19,7 @@ public class UnmarkCommand implements Command { * @throws NumberFormatException if the index provided is not a valid integer. */ public UnmarkCommand(String line) { - String toUnmarkIndex = line.substring(4).trim(); + String toUnmarkIndex = line.substring(6).trim(); this.toUnmarkIndex = Integer.parseInt(toUnmarkIndex) - 1; } diff --git a/src/main/java/chattycharlie/userinteractions/Parser.java b/src/main/java/chattycharlie/userinteractions/Parser.java index 491cc7acd..d3f111bd9 100644 --- a/src/main/java/chattycharlie/userinteractions/Parser.java +++ b/src/main/java/chattycharlie/userinteractions/Parser.java @@ -16,7 +16,7 @@ public class Parser { * @throws IllegalArgumentException if the input does not match any known command. */ public CommandType getCommand(String input) { - String firstWord = input.split(" ")[0]; + String firstWord = input.trim().split(" ")[0]; return CommandType.valueOf(firstWord.toUpperCase()); } } From 95f37b66bfc38ab4973a2e8c74fa5f5a5eae3041 Mon Sep 17 00:00:00 2001 From: BevLow Date: Sat, 5 Oct 2024 12:56:52 +0800 Subject: [PATCH 41/50] Add A-UserGuide-fixes --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index e0fe8bbac..ed49d1df5 100644 --- a/docs/README.md +++ b/docs/README.md @@ -4,7 +4,7 @@ [img.png](img.png) Chatty Charlie is a desktop app for managing tasks, optimized for use via a Command Line Interface (CLI) while still having the benefits of a Graphical User Interface (GUI). -If you can type fast, AB3 can track your task faster than traditional GUI apps. +If you can type fast, Chatty Charlie can track your task faster than traditional GUI apps. ## Adding deadlines Add a task that has a specific deadline. You provide the task description along with a deadline date. From e2cc91e4fef746486e5b5d32675da12ac3273146 Mon Sep 17 00:00:00 2001 From: BevLow Date: Wed, 9 Oct 2024 12:27:53 +0800 Subject: [PATCH 42/50] Add A-Jar2.0 --- src/main/java/META-INF/MANIFEST.MF | 2 +- src/main/java/chattycharlie/List.java | 4 +++- src/main/java/chattycharlie/task/Event.java | 4 ++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/META-INF/MANIFEST.MF b/src/main/java/META-INF/MANIFEST.MF index 14eba55a4..2056cd354 100644 --- a/src/main/java/META-INF/MANIFEST.MF +++ b/src/main/java/META-INF/MANIFEST.MF @@ -1,3 +1,3 @@ Manifest-Version: 1.0 -Main-Class: ChattyCharlie +Main-Class: chattycharlie.ChattyCharlie diff --git a/src/main/java/chattycharlie/List.java b/src/main/java/chattycharlie/List.java index 85981cbca..291cfd462 100644 --- a/src/main/java/chattycharlie/List.java +++ b/src/main/java/chattycharlie/List.java @@ -4,6 +4,8 @@ import chattycharlie.task.Event; import chattycharlie.task.Task; import chattycharlie.task.Todo; +import chattycharlie.userinteractions.StringDesign; + import java.util.ArrayList; //LIST CLASS @@ -98,7 +100,7 @@ public void printList() { case EVENT: Event eventTask = (Event) task; System.out.println(StringDesign.SPACE + number + ".[E][" + eventTask.getMarkedStatus() + "] " - + eventTask.getDescription() + " (from: " + eventTask.getStart() + " to: " + eventTask.getEnd() + ")"); + + eventTask.getDescription() + " (from: " + eventTask.getStartDate() + " to: " + eventTask.getEndDate() + ")"); break; default: break; diff --git a/src/main/java/chattycharlie/task/Event.java b/src/main/java/chattycharlie/task/Event.java index 2f4cd3c78..25261adfe 100644 --- a/src/main/java/chattycharlie/task/Event.java +++ b/src/main/java/chattycharlie/task/Event.java @@ -63,4 +63,8 @@ public String toSaveFormat() { return "[E]" + super.toSaveFormat() + " (from: " + startDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + " " + startTime + " to: " + endDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + " " + endTime + ")"; } + + public LocalDate getEndDate() { + return endDate; + } } \ No newline at end of file From 8dc1a2020a1394f4193e2b8e0f5361c2f4b9ac69 Mon Sep 17 00:00:00 2001 From: BevLow Date: Wed, 9 Oct 2024 13:14:17 +0800 Subject: [PATCH 43/50] Add A-Formatting-Fixes --- .../java/chattycharlie/ChattyCharlie.java | 8 +- src/main/java/chattycharlie/List.java | 121 ------------------ src/main/java/chattycharlie/TaskList.java | 4 +- .../java/chattycharlie/commands/Command.java | 4 +- .../chattycharlie/commands/CommandType.java | 2 +- .../java/chattycharlie/task/Deadline.java | 2 +- src/main/java/chattycharlie/task/Event.java | 12 +- src/main/java/chattycharlie/task/Task.java | 5 +- src/main/java/chattycharlie/task/Todo.java | 1 + .../userinteractions/StringDesign.java | 2 +- 10 files changed, 22 insertions(+), 139 deletions(-) delete mode 100644 src/main/java/chattycharlie/List.java diff --git a/src/main/java/chattycharlie/ChattyCharlie.java b/src/main/java/chattycharlie/ChattyCharlie.java index 26f64ddf8..07b5e258f 100644 --- a/src/main/java/chattycharlie/ChattyCharlie.java +++ b/src/main/java/chattycharlie/ChattyCharlie.java @@ -1,7 +1,11 @@ package chattycharlie; -import chattycharlie.commands.*; -import chattycharlie.userinteractions. *; +import chattycharlie.userinteractions.Storage; +import chattycharlie.userinteractions.Ui; +import chattycharlie.userinteractions.Parser; +import chattycharlie.commands.CommandType; +import chattycharlie.commands.Command; +import chattycharlie.commands.CommandFactory; /** * Represents the main chatbot application. A ChattyCharlie object corresponds to diff --git a/src/main/java/chattycharlie/List.java b/src/main/java/chattycharlie/List.java deleted file mode 100644 index 291cfd462..000000000 --- a/src/main/java/chattycharlie/List.java +++ /dev/null @@ -1,121 +0,0 @@ -package chattycharlie; - -import chattycharlie.task.Deadline; -import chattycharlie.task.Event; -import chattycharlie.task.Task; -import chattycharlie.task.Todo; -import chattycharlie.userinteractions.StringDesign; - -import java.util.ArrayList; - -//LIST CLASS - public class List { - //make a list of task - private ArrayList tasks; - private int size; - - //constructor - public List() { - tasks = new ArrayList(); - size = 0; - } - - //Method to add an item to the list - public void addTask(Task task) { - //add the text into the list - tasks.add(task); - //account for the item - size++; - } - - public ArrayList getList() { - return this.tasks; - } - - public int getSize() { - return size; - } - - //To mark - public void mark(int index) { - if (index >= 0 && index < size) { - tasks.get(index).markTask(); - int remainingTask = countUnmarkedTasks(); - System.out.println(StringDesign.SPACE + "Well Done! 1 task down, " + remainingTask + " to go."); - System.out.println(StringDesign.SPACE+ tasks.get(index).toString()); - } else { - System.out.println(StringDesign.SPACE+ "Invalid task number."); - } - } - - //To unmark - public void unmark(int index) { - if (index >= 0 && index < size) { - tasks.get(index).unmarkTask(); - int remainingTask = countUnmarkedTasks(); - System.out.println(StringDesign.SPACE + "Hmmm, not quite done yet, " + remainingTask + " to go."); - System.out.println(StringDesign.SPACE + tasks.get(index).toString()); - } else { - System.out.println(StringDesign.SPACE + "Invalid task number."); - } - } - - //To delete - public void delete(int index) { - if (index >= 0 && index < size) { - int remainingTask; - if(tasks.get(index).getIsDoneStatus()) { - remainingTask = countUnmarkedTasks(); - } else { - remainingTask = countUnmarkedTasks() -1; - } - System.out.println(StringDesign.SPACE + "Task is removed." + " Pending task: " + remainingTask); - System.out.println(StringDesign.SPACE + tasks.get(index).toString()); - tasks.remove(index); - size--; - } - } - - //To print list - public void printList() { - //print all - int remainingTask = countUnmarkedTasks(); - System.out.println("ToDo List:"); - System.out.println("pending Task: " + remainingTask); - for (int i = 0; i < size; i++) { - int number = i+1; - Task task = tasks.get(i); - //use a switch to determine - switch (task.getType()) { - case TODO: - Todo todoTask = (Todo) task; - System.out.println(StringDesign.SPACE + number + ".[T][" + todoTask.getMarkedStatus() + "] " - + todoTask.getDescription()); - break; - case DEADLINE: - Deadline deadlineTask = (Deadline) task; - System.out.println(StringDesign.SPACE + number + ".[D][" + deadlineTask.getMarkedStatus() + "] " - + deadlineTask.getDescription() + " (by: " + deadlineTask.getBy() + ")"); - break; - case EVENT: - Event eventTask = (Event) task; - System.out.println(StringDesign.SPACE + number + ".[E][" + eventTask.getMarkedStatus() + "] " - + eventTask.getDescription() + " (from: " + eventTask.getStartDate() + " to: " + eventTask.getEndDate() + ")"); - break; - default: - break; - } - } - } - - // Method to count how many tasks are unmarked - public int countUnmarkedTasks() { - int count = 0; - for (int i = 0; i < size; i++) { - if (!tasks.get(i).getIsDoneStatus()) { - count++; - } - } - return count; - } - } \ No newline at end of file diff --git a/src/main/java/chattycharlie/TaskList.java b/src/main/java/chattycharlie/TaskList.java index 34519a373..b39020d8e 100644 --- a/src/main/java/chattycharlie/TaskList.java +++ b/src/main/java/chattycharlie/TaskList.java @@ -155,7 +155,7 @@ public void printList() { ui.displayTaskInList(eventTask, number); break; default: - break; + break; } } ui.displayLine(); @@ -175,4 +175,4 @@ public int countUnmarkedTasks() { } return count; } -} \ No newline at end of file +} diff --git a/src/main/java/chattycharlie/commands/Command.java b/src/main/java/chattycharlie/commands/Command.java index f292d9220..1d904972e 100644 --- a/src/main/java/chattycharlie/commands/Command.java +++ b/src/main/java/chattycharlie/commands/Command.java @@ -25,8 +25,8 @@ public interface Command { * The default implementation returns false as * most commands do not cause the application to exit. * - * @return true if the command causes the application to exit, which is only the Bye Command - * false otherwise. + * @return true if the command causes the application to exit, + * which is only the Bye Command, false otherwise. */ default boolean isExit() { return false; // Default behavior: most commands are not exit commands diff --git a/src/main/java/chattycharlie/commands/CommandType.java b/src/main/java/chattycharlie/commands/CommandType.java index 815ac1803..2f2b078eb 100644 --- a/src/main/java/chattycharlie/commands/CommandType.java +++ b/src/main/java/chattycharlie/commands/CommandType.java @@ -15,4 +15,4 @@ public enum CommandType { DELETE, PRINT, FIND -} \ No newline at end of file +} diff --git a/src/main/java/chattycharlie/task/Deadline.java b/src/main/java/chattycharlie/task/Deadline.java index a933f2ac4..f4bba3258 100644 --- a/src/main/java/chattycharlie/task/Deadline.java +++ b/src/main/java/chattycharlie/task/Deadline.java @@ -51,4 +51,4 @@ public String toString() { public String toSaveFormat() { return "[D]" + super.toSaveFormat() + " (by: " + by.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + ")"; } -} \ No newline at end of file +} diff --git a/src/main/java/chattycharlie/task/Event.java b/src/main/java/chattycharlie/task/Event.java index 25261adfe..51e39fb64 100644 --- a/src/main/java/chattycharlie/task/Event.java +++ b/src/main/java/chattycharlie/task/Event.java @@ -49,8 +49,9 @@ public LocalDate getStartDate() { */ @Override public String toString() { - return "[E]" + super.toString() + " (from: " + startDate.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")) + " " + startTime + " to: " - + endDate.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")) + " " + endTime + ")"; + return "[E]" + super.toString() + " (from: " + startDate.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")) + " " + + startTime + " to: " + endDate.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")) + " " + + endTime + ")"; } /** @@ -60,11 +61,12 @@ public String toString() { */ @Override public String toSaveFormat() { - return "[E]" + super.toSaveFormat() + " (from: " + startDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + " " + startTime + " to: " - + endDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + " " + endTime + ")"; + return "[E]" + super.toSaveFormat() + " (from: " + startDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + + " " + startTime + " to: " + endDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + + " " + endTime + ")"; } public LocalDate getEndDate() { return endDate; } -} \ No newline at end of file +} diff --git a/src/main/java/chattycharlie/task/Task.java b/src/main/java/chattycharlie/task/Task.java index f8ebc02e8..1eb2ada0e 100644 --- a/src/main/java/chattycharlie/task/Task.java +++ b/src/main/java/chattycharlie/task/Task.java @@ -2,8 +2,6 @@ import chattycharlie.commands.CommandType; -import java.time.LocalDate; - /** * Represents an abstract task in the ChattyCharlie application. * Each task has a description, a status indicating if it's done, and a command type. @@ -92,5 +90,4 @@ public String toString() { public String toSaveFormat() { return "[" + getMarkedStatus() + "] " + description; } - -} \ No newline at end of file +} diff --git a/src/main/java/chattycharlie/task/Todo.java b/src/main/java/chattycharlie/task/Todo.java index c59470e95..2efcc2db6 100644 --- a/src/main/java/chattycharlie/task/Todo.java +++ b/src/main/java/chattycharlie/task/Todo.java @@ -37,3 +37,4 @@ public String toSaveFormat() { return "[T]" + super.toSaveFormat(); } } + diff --git a/src/main/java/chattycharlie/userinteractions/StringDesign.java b/src/main/java/chattycharlie/userinteractions/StringDesign.java index 87a208724..9781e5366 100644 --- a/src/main/java/chattycharlie/userinteractions/StringDesign.java +++ b/src/main/java/chattycharlie/userinteractions/StringDesign.java @@ -50,4 +50,4 @@ public class StringDesign { * The prefix used for messages from the user. */ public static final String YOU = "User: "; -} \ No newline at end of file +} From 2fa2497759c00d6143281e2f42e43b403f13ab64 Mon Sep 17 00:00:00 2001 From: BevLow Date: Wed, 9 Oct 2024 13:25:31 +0800 Subject: [PATCH 44/50] Add A-added Gradle Checks --- build.gradle | 25 ++ config/checkstyle/checkstyle.xml | 287 +++++++++++++++++++++++ config/checkstyle/suppressions.xml | 10 + gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 43453 bytes gradle/wrapper/gradle-wrapper.properties | 7 + gradlew | 249 ++++++++++++++++++++ gradlew.bat | 92 ++++++++ 7 files changed, 670 insertions(+) create mode 100644 build.gradle create mode 100644 config/checkstyle/checkstyle.xml create mode 100644 config/checkstyle/suppressions.xml create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100644 gradlew create mode 100644 gradlew.bat diff --git a/build.gradle b/build.gradle new file mode 100644 index 000000000..169e5db7e --- /dev/null +++ b/build.gradle @@ -0,0 +1,25 @@ +plugins { + id 'java' + id 'application' + id 'checkstyle' // Checkstyle plugin added +} + +group 'com.example' +version '1.0-SNAPSHOT' + +repositories { + mavenCentral() +} + +dependencies { + testImplementation 'org.junit.jupiter:junit-jupiter:5.9.0' +} + +application { + mainClass = 'chattycharlie.ChattyCharlie' // Updated to reflect your main class +} + +checkstyle { + toolVersion = '10.2' // Specifying Checkstyle version 10.2 + config = resources.text.fromFile('config/checkstyle/checkstyle.xml') +} diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml new file mode 100644 index 000000000..c35db7c7e --- /dev/null +++ b/config/checkstyle/checkstyle.xml @@ -0,0 +1,287 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/checkstyle/suppressions.xml b/config/checkstyle/suppressions.xml new file mode 100644 index 000000000..135ea49ee --- /dev/null +++ b/config/checkstyle/suppressions.xml @@ -0,0 +1,10 @@ + + + + + + + + \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..e6441136f3d4ba8a0da8d277868979cfbc8ad796 GIT binary patch literal 43453 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 yu?e%!_ptzGB|8GrCfu%p?(_ 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
NnX)EH+Nua)3Y(c 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 '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 000000000..25da30dbd --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega From b32e1fe4d37890ec3007ecc39ec5a463d08c535c Mon Sep 17 00:00:00 2001 From: BevLow Date: Wed, 9 Oct 2024 16:05:33 +0800 Subject: [PATCH 45/50] Add Bug-Fixes --- .../java/chattycharlie/CharlieExceptions.java | 22 ++++++++++-- .../java/chattycharlie/ChattyCharlie.java | 3 +- src/main/java/chattycharlie/TaskList.java | 20 +++++++---- .../chattycharlie/commands/ByeCommand.java | 3 +- .../commands/DeadlineCommand.java | 11 +++--- .../chattycharlie/commands/DeleteCommand.java | 8 +++-- .../chattycharlie/commands/EventCommand.java | 22 ++++++------ .../chattycharlie/commands/MarkCommand.java | 13 ++++--- .../chattycharlie/commands/PrintCommand.java | 12 ++++--- .../chattycharlie/commands/UnmarkCommand.java | 13 ++++--- .../java/chattycharlie/task/Deadline.java | 36 +++++++++++++++---- src/main/java/chattycharlie/task/Event.java | 31 ++++++++++++---- .../userinteractions/Storage.java | 34 +++++++++++------- .../chattycharlie/userinteractions/Ui.java | 4 +++ 14 files changed, 164 insertions(+), 68 deletions(-) diff --git a/src/main/java/chattycharlie/CharlieExceptions.java b/src/main/java/chattycharlie/CharlieExceptions.java index bf1372709..059a66cdb 100644 --- a/src/main/java/chattycharlie/CharlieExceptions.java +++ b/src/main/java/chattycharlie/CharlieExceptions.java @@ -1,6 +1,9 @@ package chattycharlie; import chattycharlie.commands.CommandType; +import chattycharlie.userinteractions.Storage; + +import java.io.IOException; /** * Represents all the exceptions used in ChattyCharlie task management @@ -33,7 +36,8 @@ public static CharlieExceptions missingDescription(CommandType command) { * @return a CharlieExceptions instance with a specific error message. */ public static CharlieExceptions missingDeadline() { - return new CharlieExceptions("When is this due?"); + return new CharlieExceptions("Missing deadline, please retype with deadline in " + + "format: by YYYY-MM-DD HH:MM."); } /** @@ -42,7 +46,13 @@ public static CharlieExceptions missingDeadline() { * @return a CharlieExceptions instance with a specific error message. */ public static CharlieExceptions missingTimes() { - return new CharlieExceptions("Your event is missing or incomplete!"); + return new CharlieExceptions("Missing times, please retype with the " + + " format: from YYYY-MM-DD HH:MM to YYYY-MM-DD HH:MM"); + } + + public static CharlieExceptions missingDates() { + return new CharlieExceptions("Missing Dates, please retype with the " + + " format: from YYYY-MM-DD HH:MM to YYYY-MM-DD HH:MM"); } /** @@ -53,4 +63,12 @@ public static CharlieExceptions missingTimes() { public static CharlieExceptions cannotIdentifyCommandType() { return new CharlieExceptions("Cannot identify command type."); } + + public static CharlieExceptions indexOutOfBounds(int index) { + return new CharlieExceptions("Index " + (index + 1) + " does not exist, please try again."); + } + + public static CharlieExceptions invalidFormat(String line) { + return new CharlieExceptions("Wrong Format, retry with this: " + line); + } } diff --git a/src/main/java/chattycharlie/ChattyCharlie.java b/src/main/java/chattycharlie/ChattyCharlie.java index 07b5e258f..27818cbde 100644 --- a/src/main/java/chattycharlie/ChattyCharlie.java +++ b/src/main/java/chattycharlie/ChattyCharlie.java @@ -18,7 +18,8 @@ public class ChattyCharlie { /** * Constructs a ChattyCharlie object and initializes its user interface, - * storage, and task list. Attempts to load tasks from the specified file path. + * storage, and task list. Attempts to load tasks from the specified file path, + * if there is no file, it creates a new directory and then the file. * * @param filePath The path of the file where tasks are saved and loaded from. */ diff --git a/src/main/java/chattycharlie/TaskList.java b/src/main/java/chattycharlie/TaskList.java index b39020d8e..670431f4f 100644 --- a/src/main/java/chattycharlie/TaskList.java +++ b/src/main/java/chattycharlie/TaskList.java @@ -59,8 +59,12 @@ public ArrayList getList() { * @param index The index of the task to retrieve. * @return The task at the specified index. */ - public Task getTask(int index) { - return this.tasks.get(index); + public Task getTask(int index) throws CharlieExceptions { + if (index >= 0 && index < tasks.size()) { + return tasks.get(index); + } else { + throw CharlieExceptions.indexOutOfBounds(index); + } } /** @@ -78,14 +82,14 @@ public int getSize() { * * @param index The index of the task to be marked */ - public void markTask(int index) { + public void markTask(int index) throws CharlieExceptions { Ui ui = new Ui(); if (index >= 0 && index < size) { tasks.get(index).markTask(); int remainingTask = countUnmarkedTasks(); ui.displayMarkingText("yay, 1 down! ", remainingTask); } else { - ui.displayError("Invalid task number."); + throw CharlieExceptions.indexOutOfBounds(index); } } @@ -95,14 +99,14 @@ public void markTask(int index) { * * @param index The index of the task to be unmarked */ - public void unmarkTask(int index) { + public void unmarkTask(int index) throws CharlieExceptions { Ui ui = new Ui(); if (index >= 0 && index < size) { tasks.get(index).unmarkTask(); int remainingTask = countUnmarkedTasks(); ui.displayMarkingText("Hmmm, not quite done yet, ", remainingTask); } else { - ui.displayError("Invalid task number."); + throw CharlieExceptions.indexOutOfBounds(index); } } @@ -113,7 +117,7 @@ public void unmarkTask(int index) { * * @param index The index of the task to be deleted. */ - public void deleteTask(int index) { + public void deleteTask(int index) throws CharlieExceptions { Ui ui = new Ui(); if (index >= 0 && index < size) { int remainingTask; @@ -126,6 +130,8 @@ public void deleteTask(int index) { ui.displayTask(tasks.get(index)); tasks.remove(index); size--; + } else { + throw CharlieExceptions.indexOutOfBounds(index); } } diff --git a/src/main/java/chattycharlie/commands/ByeCommand.java b/src/main/java/chattycharlie/commands/ByeCommand.java index 5791703ef..c1a1ecf07 100644 --- a/src/main/java/chattycharlie/commands/ByeCommand.java +++ b/src/main/java/chattycharlie/commands/ByeCommand.java @@ -1,5 +1,6 @@ package chattycharlie.commands; +import chattycharlie.CharlieExceptions; import chattycharlie.userinteractions.Storage; import chattycharlie.TaskList; import chattycharlie.userinteractions.StringDesign; @@ -19,7 +20,7 @@ public class ByeCommand implements Command { * @param storage the storage system used to save tasks. */ @Override - public void execute(TaskList taskList, Ui ui, Storage storage) { + public void execute(TaskList taskList, Ui ui, Storage storage) throws CharlieExceptions { storage.saveTasks(taskList); System.out.println(StringDesign.CHARLIE + StringDesign.FAREWELL); } diff --git a/src/main/java/chattycharlie/commands/DeadlineCommand.java b/src/main/java/chattycharlie/commands/DeadlineCommand.java index 88ac7881b..3d255746a 100644 --- a/src/main/java/chattycharlie/commands/DeadlineCommand.java +++ b/src/main/java/chattycharlie/commands/DeadlineCommand.java @@ -20,17 +20,18 @@ public class DeadlineCommand implements Command { * Parses the input to extract the task description and deadline time. * * @param line the input line containing the command and task details. - * @throws CharlieExceptions if the description or deadline time is missing. + * @throws CharlieExceptions if the description or deadline is missing or invalid format. */ public DeadlineCommand(String line) throws CharlieExceptions { String[] deadlineParts = line.substring(8).trim().split(" by "); + if (deadlineParts[0].isEmpty()) { throw CharlieExceptions.missingDescription(CommandType.DEADLINE); - } else if (deadlineParts.length < 2) { + } else if (deadlineParts.length < 2 || deadlineParts[1].trim().isEmpty()) { throw CharlieExceptions.missingDeadline(); - } else { - this.description = deadlineParts[0].trim(); } + + this.description = deadlineParts[0].trim(); this.by = deadlineParts[1].trim(); } @@ -43,7 +44,7 @@ public DeadlineCommand(String line) throws CharlieExceptions { * @param storage the storage system to save the updated task list. */ @Override - public void execute(TaskList taskList, Ui ui, Storage storage) { + public void execute(TaskList taskList, Ui ui, Storage storage) throws CharlieExceptions { Task deadlineTask = new Deadline(description, by); taskList.addTask(deadlineTask); ui.displayTaskAdded(deadlineTask); diff --git a/src/main/java/chattycharlie/commands/DeleteCommand.java b/src/main/java/chattycharlie/commands/DeleteCommand.java index d54cd034a..703cad977 100644 --- a/src/main/java/chattycharlie/commands/DeleteCommand.java +++ b/src/main/java/chattycharlie/commands/DeleteCommand.java @@ -21,7 +21,11 @@ public class DeleteCommand implements Command { */ public DeleteCommand(String line) throws CharlieExceptions { String toDeleteIndex = line.substring(7).trim(); - this.toDeleteIndex = Integer.parseInt(toDeleteIndex) - 1; + try { + this.toDeleteIndex = Integer.parseInt(toDeleteIndex) - 1; + } catch (NumberFormatException e) { + throw CharlieExceptions.invalidFormat("delete INDEX"); + } } /** @@ -33,7 +37,7 @@ public DeleteCommand(String line) throws CharlieExceptions { * @param storage the storage system to save changes made to the task list. */ @Override - public void execute(TaskList taskList, Ui ui, Storage storage) { + public void execute(TaskList taskList, Ui ui, Storage storage) throws CharlieExceptions { taskList.deleteTask(toDeleteIndex); } } diff --git a/src/main/java/chattycharlie/commands/EventCommand.java b/src/main/java/chattycharlie/commands/EventCommand.java index 510dfe981..ff2b24624 100644 --- a/src/main/java/chattycharlie/commands/EventCommand.java +++ b/src/main/java/chattycharlie/commands/EventCommand.java @@ -21,31 +21,29 @@ public class EventCommand implements Command{ * Parses the input to extract the task description, start time, and end time. * * @param line the input line containing the command and event task details. - * @throws CharlieExceptions if the description or event times are missing or incomplete. + * @throws CharlieExceptions if the description or dates or times are missing/ */ public EventCommand(String line) throws CharlieExceptions { String[] eventParts = line.substring(5).trim().split("from"); - if (eventParts[0].isEmpty()) { //no description + if (eventParts[0].isEmpty()) { throw CharlieExceptions.missingDescription(CommandType.EVENT); - } else if (eventParts.length < 2) { //no from - throw CharlieExceptions.missingTimes(); } else { description = eventParts[0].trim(); } + if (eventParts.length < 2) { + throw CharlieExceptions.missingDates(); + } + String[] eventTimes = eventParts[1].trim().split(" to "); if (eventTimes.length < 2) { - throw CharlieExceptions.missingTimes(); //change this to no end date - } - - if (eventTimes[0].isEmpty() || eventTimes[1].isEmpty()) { throw CharlieExceptions.missingTimes(); - } else { - from = eventTimes[0].trim(); - to = eventTimes[1].trim(); } + + from = eventTimes[0].trim(); + to = eventTimes[1].trim(); } /** @@ -57,7 +55,7 @@ public EventCommand(String line) throws CharlieExceptions { * @param storage the storage system to save the updated task list. */ @Override - public void execute(TaskList taskList, Ui ui, Storage storage) { + public void execute(TaskList taskList, Ui ui, Storage storage) throws CharlieExceptions { Task eventTask = new Event(description, from, to); taskList.addTask(eventTask); ui.displayTaskAdded(eventTask); diff --git a/src/main/java/chattycharlie/commands/MarkCommand.java b/src/main/java/chattycharlie/commands/MarkCommand.java index 5cba27124..7085bce6e 100644 --- a/src/main/java/chattycharlie/commands/MarkCommand.java +++ b/src/main/java/chattycharlie/commands/MarkCommand.java @@ -1,5 +1,6 @@ package chattycharlie.commands; +import chattycharlie.CharlieExceptions; import chattycharlie.userinteractions.Storage; import chattycharlie.TaskList; import chattycharlie.userinteractions.Ui; @@ -16,11 +17,15 @@ public class MarkCommand implements Command { * Extracts the task index that needs to be marked as completed. * * @param line the input line containing the command and task index to mark as completed. - * @throws NumberFormatException if the index provided is not a valid integer. + * @throws CharlieExceptions if the index provided is not a valid integer. */ - public MarkCommand(String line) { + public MarkCommand(String line) throws CharlieExceptions { String toMarkIndex = line.substring(4).trim(); - this.toMarkIndex = Integer.parseInt(toMarkIndex) - 1; + try { + this.toMarkIndex = Integer.parseInt(toMarkIndex) - 1; + } catch (NumberFormatException e) { + throw CharlieExceptions.invalidFormat("mark INDEX"); + } } /** @@ -32,7 +37,7 @@ public MarkCommand(String line) { * @param storage the storage system to save the updated task list. */ @Override - public void execute(TaskList taskList, Ui ui, Storage storage) { + public void execute(TaskList taskList, Ui ui, Storage storage) throws CharlieExceptions { taskList.markTask(toMarkIndex); ui.displayTask(taskList.getTask(toMarkIndex)); } diff --git a/src/main/java/chattycharlie/commands/PrintCommand.java b/src/main/java/chattycharlie/commands/PrintCommand.java index 19f0ef9fc..d68f6a93b 100644 --- a/src/main/java/chattycharlie/commands/PrintCommand.java +++ b/src/main/java/chattycharlie/commands/PrintCommand.java @@ -23,11 +23,15 @@ public class PrintCommand implements Command{ * Parses the input to extract the date to filter tasks by. * * @param line the input line containing the command and the date to filter tasks. - * @throws DateTimeParseException if the provided date is not in the correct format. + * @throws CharlieExceptions if the provided date is not in the correct format. */ - public PrintCommand(String line) { + public PrintCommand(String line) throws CharlieExceptions { String timeText = line.substring(6).trim(); - this.time = LocalDate.parse(timeText, DateTimeFormatter.ofPattern("yyyy-MM-dd")); + try { + this.time = LocalDate.parse(timeText, DateTimeFormatter.ofPattern("yyyy-MM-dd")); + } catch (Exception e) { + throw CharlieExceptions.invalidFormat("print YYYY-MM-DD"); + } } /** @@ -50,7 +54,7 @@ public void execute(TaskList taskList, Ui ui, Storage storage) throws CharlieExc switch (command) { case DEADLINE: Deadline deadlineTask = (Deadline) task; - if(time.equals(deadlineTask.getBy())) { + if(time.equals(deadlineTask.getByDate())) { ui.displayTaskInList(deadlineTask, count); count++; } diff --git a/src/main/java/chattycharlie/commands/UnmarkCommand.java b/src/main/java/chattycharlie/commands/UnmarkCommand.java index b2abf4678..12417754c 100644 --- a/src/main/java/chattycharlie/commands/UnmarkCommand.java +++ b/src/main/java/chattycharlie/commands/UnmarkCommand.java @@ -1,5 +1,6 @@ package chattycharlie.commands; +import chattycharlie.CharlieExceptions; import chattycharlie.userinteractions.Storage; import chattycharlie.TaskList; import chattycharlie.userinteractions.Ui; @@ -16,11 +17,15 @@ public class UnmarkCommand implements Command { * Extracts the task index that needs to be unmarked as incomplete. * * @param line the input line containing the command and task index to unmark. - * @throws NumberFormatException if the index provided is not a valid integer. + * @throws CharlieExceptions if the index provided is not a valid integer. */ - public UnmarkCommand(String line) { + public UnmarkCommand(String line) throws CharlieExceptions { String toUnmarkIndex = line.substring(6).trim(); - this.toUnmarkIndex = Integer.parseInt(toUnmarkIndex) - 1; + try { + this.toUnmarkIndex = Integer.parseInt(toUnmarkIndex) - 1; + } catch (NumberFormatException e) { + throw CharlieExceptions.invalidFormat("unmark INDEX"); + } } /** @@ -32,7 +37,7 @@ public UnmarkCommand(String line) { * @param storage the storage system to save the updated task list. */ @Override - public void execute(TaskList taskList, Ui ui, Storage storage) { + public void execute(TaskList taskList, Ui ui, Storage storage) throws CharlieExceptions { taskList.unmarkTask(toUnmarkIndex); ui.displayTask(taskList.getTask(toUnmarkIndex)); } diff --git a/src/main/java/chattycharlie/task/Deadline.java b/src/main/java/chattycharlie/task/Deadline.java index f4bba3258..67544e559 100644 --- a/src/main/java/chattycharlie/task/Deadline.java +++ b/src/main/java/chattycharlie/task/Deadline.java @@ -1,7 +1,9 @@ package chattycharlie.task; +import chattycharlie.CharlieExceptions; import chattycharlie.commands.CommandType; import java.time.LocalDate; +import java.time.LocalTime; import java.time.format.DateTimeFormatter; /** @@ -9,7 +11,8 @@ * A Deadline task has a description and a date by which it must be completed. */ public class Deadline extends Task { - protected LocalDate by; + protected LocalDate byDate; + protected LocalTime byTime; /** * Constructs a Deadline task with the specified description and due date. @@ -17,9 +20,26 @@ public class Deadline extends Task { * @param description the description of the deadline task. * @param by the due date for the task in yyyy-MM-dd format. */ - public Deadline(String description, String by) { + public Deadline(String description, String by) throws CharlieExceptions { super(description, CommandType.DEADLINE); - this.by = LocalDate.parse(by, DateTimeFormatter.ofPattern("yyyy-MM-dd")); + DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm"); + try { + String[] byParts = by.split(" "); + + if (byParts.length != 2) { + throw CharlieExceptions.invalidFormat("deadline DESCRIPTION by DATE TIME"); // Validation for format + } + + if (!byParts[1].matches("\\d{2}:\\d{2}")) { + throw CharlieExceptions.invalidFormat("Time format should be HH:mm (e.g., 14:00)"); + } + + this.byDate = LocalDate.parse(byParts[0], dateFormatter); + this.byTime = LocalTime.parse(byParts[1], timeFormatter); + } catch (CharlieExceptions e) { + throw CharlieExceptions.invalidFormat("Invalid deadline format. Expected format: 'yyyy-MM-dd HH:mm'"); + } } /** @@ -27,8 +47,8 @@ public Deadline(String description, String by) { * * @return the due date as a LocalDate. */ - public LocalDate getBy() { - return by; + public LocalDate getByDate() { + return byDate; } /** @@ -39,7 +59,8 @@ public LocalDate getBy() { */ @Override public String toString() { - return "[D]" + super.toString() + " (by: " + by.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")) + ")"; + return "[D]" + super.toString() + " (by: " + byDate.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")) + + " " + byTime + ")"; } /** @@ -49,6 +70,7 @@ public String toString() { */ @Override public String toSaveFormat() { - return "[D]" + super.toSaveFormat() + " (by: " + by.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + ")"; + return "[D]" + super.toSaveFormat() + " (by: " + byDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + + " " + byTime + ")"; } } diff --git a/src/main/java/chattycharlie/task/Event.java b/src/main/java/chattycharlie/task/Event.java index 51e39fb64..1b2802369 100644 --- a/src/main/java/chattycharlie/task/Event.java +++ b/src/main/java/chattycharlie/task/Event.java @@ -1,5 +1,6 @@ package chattycharlie.task; +import chattycharlie.CharlieExceptions; import chattycharlie.commands.CommandType; import java.time.LocalDate; import java.time.LocalTime; @@ -22,14 +23,30 @@ public class Event extends Task { * @param start the start date and time in yyyy-MM-dd HH:mm format. * @param end the end date and time in yyyy-MM-dd HH:mm format. */ - public Event(String description, String start, String end) { + public Event(String description, String start, String end) throws CharlieExceptions { super(description, CommandType.EVENT); - String[] startParts = start.split(" "); - String[] endParts = end.split(" "); - this.startDate = LocalDate.parse(startParts[0], DateTimeFormatter.ofPattern("yyyy-MM-dd")); - this.startTime = LocalTime.parse(startParts[1], DateTimeFormatter.ofPattern("HH:mm")); - this.endDate = LocalDate.parse(endParts[0], DateTimeFormatter.ofPattern("yyyy-MM-dd")); - this.endTime = LocalTime.parse(endParts[1], DateTimeFormatter.ofPattern("HH:mm")); + DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm"); + try { + String[] startParts = start.split(" "); + String[] endParts = end.split(" "); + + if (startParts.length != 2 || endParts.length != 2) { + throw CharlieExceptions.invalidFormat("Invalid event format. Expected format: 'yyyy-MM-dd HH:mm'"); + } + + if (!startParts[1].matches("\\d{2}:\\d{2}") || !endParts[1].matches("\\d{2}:\\d{2}")) { + throw CharlieExceptions.invalidFormat("HH:mm (e.g., 14:00)"); + } + + this.startDate = LocalDate.parse(startParts[0], dateFormatter); + this.startTime = LocalTime.parse(startParts[1], timeFormatter); + this.endDate = LocalDate.parse(endParts[0], dateFormatter); + this.endTime = LocalTime.parse(endParts[1], timeFormatter); + } catch (CharlieExceptions e) { + throw CharlieExceptions.invalidFormat("event DESCRIPTION from START_DATE START_TIME " + + "to END_DATE END_TIME"); + } } /** diff --git a/src/main/java/chattycharlie/userinteractions/Storage.java b/src/main/java/chattycharlie/userinteractions/Storage.java index 259e70861..993100b59 100644 --- a/src/main/java/chattycharlie/userinteractions/Storage.java +++ b/src/main/java/chattycharlie/userinteractions/Storage.java @@ -40,19 +40,29 @@ public TaskList load() throws CharlieExceptions { File file = new File(filePath); try { - Scanner scanner = new Scanner(file); + File directory = new File("data"); + if (directory != null && !directory.exists()) { + directory.mkdir(); + } - while (scanner.hasNextLine()) { - String taskText = scanner.nextLine(); - Task task = parseTask(taskText); - if (task != null) { - list.addTask(task); + if (!file.exists()) { + file.createNewFile(); + System.out.println("Oh first time here? Welcome to a life of Productivity, let's start!"); + } else { + Scanner scanner = new Scanner(file); + + while (scanner.hasNextLine()) { + String taskText = scanner.nextLine(); + Task task = parseTask(taskText); + if (task != null) { + list.addTask(task); + } } + scanner.close(); + System.out.println(StringDesign.CHARLIE + "Task have been loaded from: " + filePath); } - scanner.close(); - System.out.println(StringDesign.CHARLIE + "Task have been loaded from: " + filePath); - } catch (FileNotFoundException e) { - System.out.println("Oh first time here? Welcome to a life of Productivity, lets start!"); + } catch (IOException e) { + throw new CharlieExceptions("Error loading or creating file: " + e.getMessage()); } return list; @@ -65,7 +75,7 @@ public TaskList load() throws CharlieExceptions { * @return the corresponding Task object, or null if the task cannot be parsed. * @throws IllegalArgumentException if the task type is unknown. */ - public Task parseTask(String taskText) { + public Task parseTask(String taskText) throws CharlieExceptions { taskText = taskText.trim(); //trim away the formatting char taskType = taskText.charAt(1); //get the commandType boolean isMarked = taskText.charAt(4) == 'X'; //get status for marked @@ -118,7 +128,7 @@ public Task parseTask(String taskText) { * * @param list the TaskList containing tasks to be saved. */ - public void saveTasks(TaskList list) { + public void saveTasks(TaskList list) throws CharlieExceptions { try { FileWriter writer = new FileWriter(filePath); for (int i = 0; i < list.getSize(); i++) { diff --git a/src/main/java/chattycharlie/userinteractions/Ui.java b/src/main/java/chattycharlie/userinteractions/Ui.java index 6d336ee6b..84fce0291 100644 --- a/src/main/java/chattycharlie/userinteractions/Ui.java +++ b/src/main/java/chattycharlie/userinteractions/Ui.java @@ -123,4 +123,8 @@ public void displayLine() { public void displaySearchList() { System.out.println("Tasks found:"); } + + public void displayText(String line) { + System.out.println(StringDesign.SPACE + line + System.lineSeparator() + StringDesign.LINE); + } } From 4b1bc2ed3792e4836fe908d07c7a39a3d1c97120 Mon Sep 17 00:00:00 2001 From: BevLow Date: Wed, 9 Oct 2024 16:19:58 +0800 Subject: [PATCH 46/50] Add Bug-Fixes --- META-INF/MANIFEST.MF | 1 + src/main/java/chattycharlie/CharlieExceptions.java | 3 --- src/main/java/chattycharlie/TaskList.java | 3 ++- src/main/java/chattycharlie/commands/DeadlineCommand.java | 1 + src/main/java/chattycharlie/commands/DeleteCommand.java | 1 + src/main/java/chattycharlie/commands/EventCommand.java | 1 + src/main/java/chattycharlie/commands/FindCommand.java | 1 + src/main/java/chattycharlie/commands/ListCommand.java | 1 + src/main/java/chattycharlie/commands/MarkCommand.java | 1 + src/main/java/chattycharlie/commands/PrintCommand.java | 2 +- src/main/java/chattycharlie/commands/TodoCommand.java | 3 ++- src/main/java/chattycharlie/commands/UnmarkCommand.java | 1 + src/main/java/chattycharlie/userinteractions/Storage.java | 1 - 13 files changed, 13 insertions(+), 7 deletions(-) diff --git a/META-INF/MANIFEST.MF b/META-INF/MANIFEST.MF index 59499bce4..2056cd354 100644 --- a/META-INF/MANIFEST.MF +++ b/META-INF/MANIFEST.MF @@ -1,2 +1,3 @@ Manifest-Version: 1.0 +Main-Class: chattycharlie.ChattyCharlie diff --git a/src/main/java/chattycharlie/CharlieExceptions.java b/src/main/java/chattycharlie/CharlieExceptions.java index 059a66cdb..62e423bd0 100644 --- a/src/main/java/chattycharlie/CharlieExceptions.java +++ b/src/main/java/chattycharlie/CharlieExceptions.java @@ -1,9 +1,6 @@ package chattycharlie; import chattycharlie.commands.CommandType; -import chattycharlie.userinteractions.Storage; - -import java.io.IOException; /** * Represents all the exceptions used in ChattyCharlie task management diff --git a/src/main/java/chattycharlie/TaskList.java b/src/main/java/chattycharlie/TaskList.java index 670431f4f..f55b92721 100644 --- a/src/main/java/chattycharlie/TaskList.java +++ b/src/main/java/chattycharlie/TaskList.java @@ -1,5 +1,6 @@ package chattycharlie; +import chattycharlie.userinteractions.Storage; import chattycharlie.userinteractions.Ui; import chattycharlie.task.Deadline; import chattycharlie.task.Event; @@ -14,7 +15,7 @@ public class TaskList { private ArrayList tasks; private int size; - + Storage storage; /** * Contructs an empty TaskList object with no task */ diff --git a/src/main/java/chattycharlie/commands/DeadlineCommand.java b/src/main/java/chattycharlie/commands/DeadlineCommand.java index 3d255746a..0cbd7af86 100644 --- a/src/main/java/chattycharlie/commands/DeadlineCommand.java +++ b/src/main/java/chattycharlie/commands/DeadlineCommand.java @@ -45,6 +45,7 @@ public DeadlineCommand(String line) throws CharlieExceptions { */ @Override public void execute(TaskList taskList, Ui ui, Storage storage) throws CharlieExceptions { + storage.saveTasks(taskList); Task deadlineTask = new Deadline(description, by); taskList.addTask(deadlineTask); ui.displayTaskAdded(deadlineTask); diff --git a/src/main/java/chattycharlie/commands/DeleteCommand.java b/src/main/java/chattycharlie/commands/DeleteCommand.java index 703cad977..ca15f5bab 100644 --- a/src/main/java/chattycharlie/commands/DeleteCommand.java +++ b/src/main/java/chattycharlie/commands/DeleteCommand.java @@ -38,6 +38,7 @@ public DeleteCommand(String line) throws CharlieExceptions { */ @Override public void execute(TaskList taskList, Ui ui, Storage storage) throws CharlieExceptions { + storage.saveTasks(taskList); taskList.deleteTask(toDeleteIndex); } } diff --git a/src/main/java/chattycharlie/commands/EventCommand.java b/src/main/java/chattycharlie/commands/EventCommand.java index ff2b24624..856fc7c1b 100644 --- a/src/main/java/chattycharlie/commands/EventCommand.java +++ b/src/main/java/chattycharlie/commands/EventCommand.java @@ -56,6 +56,7 @@ public EventCommand(String line) throws CharlieExceptions { */ @Override public void execute(TaskList taskList, Ui ui, Storage storage) throws CharlieExceptions { + storage.saveTasks(taskList); Task eventTask = new Event(description, from, to); taskList.addTask(eventTask); ui.displayTaskAdded(eventTask); diff --git a/src/main/java/chattycharlie/commands/FindCommand.java b/src/main/java/chattycharlie/commands/FindCommand.java index 583c34dfd..de7672881 100644 --- a/src/main/java/chattycharlie/commands/FindCommand.java +++ b/src/main/java/chattycharlie/commands/FindCommand.java @@ -34,6 +34,7 @@ public FindCommand(String line) { */ @Override public void execute(TaskList taskList, Ui ui, Storage storage) throws CharlieExceptions { + storage.saveTasks(taskList); int count = 1; ui.displaySearchList(); for(int i = 0; i < taskList.getSize(); i++) { diff --git a/src/main/java/chattycharlie/commands/ListCommand.java b/src/main/java/chattycharlie/commands/ListCommand.java index 54ccc6c9f..32c73c0a9 100644 --- a/src/main/java/chattycharlie/commands/ListCommand.java +++ b/src/main/java/chattycharlie/commands/ListCommand.java @@ -22,6 +22,7 @@ public class ListCommand implements Command { */ @Override public void execute(TaskList taskList, Ui ui, Storage storage) throws CharlieExceptions { + storage.saveTasks(taskList); ui.displayList(taskList); } } diff --git a/src/main/java/chattycharlie/commands/MarkCommand.java b/src/main/java/chattycharlie/commands/MarkCommand.java index 7085bce6e..dbf465328 100644 --- a/src/main/java/chattycharlie/commands/MarkCommand.java +++ b/src/main/java/chattycharlie/commands/MarkCommand.java @@ -38,6 +38,7 @@ public MarkCommand(String line) throws CharlieExceptions { */ @Override public void execute(TaskList taskList, Ui ui, Storage storage) throws CharlieExceptions { + storage.saveTasks(taskList); taskList.markTask(toMarkIndex); ui.displayTask(taskList.getTask(toMarkIndex)); } diff --git a/src/main/java/chattycharlie/commands/PrintCommand.java b/src/main/java/chattycharlie/commands/PrintCommand.java index d68f6a93b..d95ad4cc0 100644 --- a/src/main/java/chattycharlie/commands/PrintCommand.java +++ b/src/main/java/chattycharlie/commands/PrintCommand.java @@ -9,7 +9,6 @@ import java.time.LocalDate; import java.time.format.DateTimeFormatter; -import java.time.format.DateTimeParseException; /** * Represents the command to print tasks based on a specific date. @@ -45,6 +44,7 @@ public PrintCommand(String line) throws CharlieExceptions { */ @Override public void execute(TaskList taskList, Ui ui, Storage storage) throws CharlieExceptions { + storage.saveTasks(taskList); int count = 1; ui.displaySearchList(); for(int i = 0; i < taskList.getSize(); i++ ) { diff --git a/src/main/java/chattycharlie/commands/TodoCommand.java b/src/main/java/chattycharlie/commands/TodoCommand.java index aae7024e3..aec5fbb7e 100644 --- a/src/main/java/chattycharlie/commands/TodoCommand.java +++ b/src/main/java/chattycharlie/commands/TodoCommand.java @@ -39,7 +39,8 @@ public TodoCommand(String line) throws CharlieExceptions { * @param storage the storage system to save the updated task list. */ @Override - public void execute(TaskList taskList, Ui ui, Storage storage){ + public void execute(TaskList taskList, Ui ui, Storage storage) throws CharlieExceptions { + storage.saveTasks(taskList); Task todoTask = new Todo(description); taskList.addTask(todoTask); ui.displayTaskAdded(todoTask); diff --git a/src/main/java/chattycharlie/commands/UnmarkCommand.java b/src/main/java/chattycharlie/commands/UnmarkCommand.java index 12417754c..9a503f608 100644 --- a/src/main/java/chattycharlie/commands/UnmarkCommand.java +++ b/src/main/java/chattycharlie/commands/UnmarkCommand.java @@ -38,6 +38,7 @@ public UnmarkCommand(String line) throws CharlieExceptions { */ @Override public void execute(TaskList taskList, Ui ui, Storage storage) throws CharlieExceptions { + storage.saveTasks(taskList); taskList.unmarkTask(toUnmarkIndex); ui.displayTask(taskList.getTask(toUnmarkIndex)); } diff --git a/src/main/java/chattycharlie/userinteractions/Storage.java b/src/main/java/chattycharlie/userinteractions/Storage.java index 993100b59..76ffc2c2b 100644 --- a/src/main/java/chattycharlie/userinteractions/Storage.java +++ b/src/main/java/chattycharlie/userinteractions/Storage.java @@ -8,7 +8,6 @@ import chattycharlie.task.Todo; import java.io.File; -import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; import java.util.Scanner; From c9478f82ba1caa043a4b8ea48d31f091a5f174c9 Mon Sep 17 00:00:00 2001 From: BevLow Date: Wed, 9 Oct 2024 17:06:46 +0800 Subject: [PATCH 47/50] Add Fix User-Guide --- docs/README.md | 113 +++++++++++++++++++++++------ docs/{img.png => images/Intro.png} | Bin 2 files changed, 89 insertions(+), 24 deletions(-) rename docs/{img.png => images/Intro.png} (100%) diff --git a/docs/README.md b/docs/README.md index ed49d1df5..ef0dba736 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,17 +1,38 @@ # Chatty Charlie User Guide +![Starting Image](images/img.png) +**Chatty Charlie** is a desktop app for managing tasks, optimized for use via a Command Line Interface (CLI) while still having the benefits of a Graphical User Interface (GUI). +If you can type fast, Chatty Charlie can track your task faster than traditional GUI apps. -[img.png](img.png) +## Quick Start +1. Ensure you have **Java 17** or above installed on your computer. +2. Download the latest `.jar` file from [here](https://github.com/Bev-low/ip/releases. +3. Copy the file to the folder you want to use as the home folder for Chatty Charlie. +4. Open a command terminal, `cd` into the folder you put the jar file in, and use the command `java -jar ip.jar` to run the application. -Chatty Charlie is a desktop app for managing tasks, optimized for use via a Command Line Interface (CLI) while still having the benefits of a Graphical User Interface (GUI). -If you can type fast, Chatty Charlie can track your task faster than traditional GUI apps. +5. A GUI similar to the image below should appear in a few seconds. +![Starting Image](images/img.png) + +6. Type the command in the command box and press Enter to execute it. +### Some example commands you can try: +- `list` : Lists all tasks +- `todo Buy a book` : Adds a todo task with task description Buy a book to the task list. + +7. Refer to the [Features](#features) below for details of each Command. + +--- -## Adding deadlines +## Features + +### Adding a deadline task Add a task that has a specific deadline. You provide the task description along with a deadline date. -Format: deadline TASK_DESCRIPTION by DATE +Format: `deadline DESCRIPTION by DATE TIME` +- **DESCRIPTION**: Task description +- **DATE**: The deadline date in format `YYYY-MM-DD` +- **TIME**: The deadline time in format `HH:MM` -Example: `deadline Submit project report by 2024-10-15` +Example: `deadline make a box by 2024-10-15 15:00` When the command is successfully executed, it will add the task to your task list with the specified deadline. For example: @@ -21,11 +42,12 @@ When the command is successfully executed, it will add the task to your task lis ------------ ``` -## Adding todos +### Adding a todo task Adds a simple task without a specific deadline. -Format: todo TASK_DESCRIPTION +Format: `todo DESCRIPTION` +- **DESCRIPTION**: Task description Example: `todo Buy groceries` @@ -36,12 +58,17 @@ When the command is successfully executed, it will add the task to your list. Fo ------------ ``` -## Adding events +### Adding an event task Add an event that takes place at a specific date and time. -Format: event TASK_DESCRIPTION from START_DATE START_TIME to END_DATE ENDTIME +Format: `event DESCRIPTION from START_DATE START_TIME to END_DATE ENDTIME` +- **DESCRIPTION**: Task description +- **START_DATE**: The start date of the event in format `YYYY-MM-DD` +- **START_TIME**: The start time of the event in format `HH:MM` +- **END_DATE**: The end date of the event in format `YYYY-MM-DD` +- **END_TIME**: The end time of the event in format `HH:MM` -Example: `event Team meeting from 2024-10-01 15:00 to 2024-10-01 18:00` + Example: `event Team meeting from 2024-10-01 15:00 to 2024-10-01 18:00` When the command is successfully executed, it will add the task to your list. For example: ``` @@ -50,10 +77,13 @@ Added task: [E][ ] Team meeting (from: 01/10/2024 15:00 to: 01/10/2024 18:00) ------------ ``` -## Marking a task as done +### Marking a task Mark a task as completed. You need to provide the task number from the task list. -Format: mark TASK_NUMBER +Format: `mark TASK_NUMBER` +- **TASK-NUMBER**: The task index that you want to mark as completed. +- The index is shown on the task list. + Example: `mark 1` @@ -65,10 +95,12 @@ When the command is successfully executed, it will mark your task with an X. For ------------ ``` -## Marking a task as undone +### Unmarking a task Mark a task as incompleted. You need to provide the task number from the task list. -Format: unmark TASK_NUMBER +Format: `unmark TASK_NUMBER` +- **TASK-NUMBER**: The task index that you want to mark as not completed. +- The index is shown on the task list. Example: `unmark 1` @@ -80,10 +112,12 @@ When the command is successfully executed, it will unmark the task, removing the ------------ ``` -## Deleting a task +### Deleting a task Deletes a task from the task list. You need to provide the task number. -Format: delete TASK_NUMBER +Format: `delete TASK_NUMBER` +- **TASK-NUMBER**: The task index that you want to delete. +- The index is shown on the task list. Example: `delete 1` @@ -95,10 +129,11 @@ When the command is successfully executed, the specified task will be removed fr ------------ ``` -## Finding tasks containing the same keyword +### Finding specific tasks Finds tasks in the list that contain a specific keyword. -Format: find KEYWORD +Format: `find KEYWORD` +- **KEYWORD**: It is a `STRING` variable that you want to search for in your list. Example: `find book` @@ -112,10 +147,10 @@ Tasks found: ------------ ``` -## Printing the whole list of task +### List all tasks Displays all tasks currently in the task list. -Format: list +Format: `list` When the command is successfully executed, all tasks will be printed. For example: ``` @@ -130,10 +165,11 @@ pending Task: 5 ------------ ``` -## Printing the list of deadlines and events due or happening on a specified date +### List tasks with specific timeline Displays all task that is occuring or due on the same date -Format: print DATE +Format: `print DATE` +- **DATE**: The date of tasks you want to find associated to it. Example: `print 2024-10-05` @@ -144,4 +180,33 @@ Tasks found: 1. [E][ ] book fair (from: 05/10/2024 15:00 to: 07/10/2024 15:00) 2. [D][ ] read a book (by: 05/10/2024) ------------ -``` \ No newline at end of file +``` + +### Exit +Displays all task that is occuring or due on the same date + +Format: `bye` + +When the command is successfully executed, all relevant tasks for the given date will be listed. For example: +``` +------------ +Charlie: We saved your file in: data/tasks.txt +Charlie: All the best in clearing your list! +``` + +--- + +## Command Summary + +| Command | Description | Format | +|--------------|------------------------------------------------------------|----------------------------------------| +| **Deadline** | Adds a deadline task. | `deadline DESCRIPTION by DATE TIME` | +| **Todo** | Adds a todo task. | `todo DESCRIPTION` | +| **Event** | Adds a event task. | `event DESCRIPTION from START_DATE START_TIME to END_DATE ENDTIME` | +| **Mark** | Mark a task as completed. | `mark TASK_NUMBER` | +| **Unmark** | Mark a task as incompleted. | `unmark TASK_NUMBER` | +| **Delete** | Deletes a task from the task list. | `delete TASK_NUMBER` | +| **Find** | Finds tasks in the list that contain a specific keyword. | `find KEYWORD` | +| **List** | Displays all tasks currently in the task list. | `list` | +| **Print** | Displays all task that is occuring or due on the same date | `print DATE` | +| **Bye** | Exits the application. | `bye` | diff --git a/docs/img.png b/docs/images/Intro.png similarity index 100% rename from docs/img.png rename to docs/images/Intro.png From 0f6e5f17c99694e7ade91ab8e835d2f1e82704dc Mon Sep 17 00:00:00 2001 From: BevLow Date: Wed, 9 Oct 2024 18:33:56 +0800 Subject: [PATCH 48/50] Add Fix user-guide --- docs/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index ef0dba736..12d9409c5 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,5 +1,5 @@ # Chatty Charlie User Guide -![Starting Image](images/img.png) +![Starting Image](./images/intro.png) **Chatty Charlie** is a desktop app for managing tasks, optimized for use via a Command Line Interface (CLI) while still having the benefits of a Graphical User Interface (GUI). If you can type fast, Chatty Charlie can track your task faster than traditional GUI apps. @@ -11,7 +11,7 @@ If you can type fast, Chatty Charlie can track your task faster than traditional 4. Open a command terminal, `cd` into the folder you put the jar file in, and use the command `java -jar ip.jar` to run the application. 5. A GUI similar to the image below should appear in a few seconds. -![Starting Image](images/img.png) +![Starting Image](./images/intro.png) 6. Type the command in the command box and press Enter to execute it. ### Some example commands you can try: From 56dd5089875e4e0643913fa92008d8b940f9aa93 Mon Sep 17 00:00:00 2001 From: BevLow Date: Wed, 9 Oct 2024 20:01:03 +0800 Subject: [PATCH 49/50] Add Fix user-guide --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 12d9409c5..1564aa4b1 100644 --- a/docs/README.md +++ b/docs/README.md @@ -6,7 +6,7 @@ If you can type fast, Chatty Charlie can track your task faster than traditional ## Quick Start 1. Ensure you have **Java 17** or above installed on your computer. -2. Download the latest `.jar` file from [here](https://github.com/Bev-low/ip/releases. +2. Download the latest `.jar` file from [here](https://github.com/Bev-low/ip/releases). 3. Copy the file to the folder you want to use as the home folder for Chatty Charlie. 4. Open a command terminal, `cd` into the folder you put the jar file in, and use the command `java -jar ip.jar` to run the application. From 2b98a0b27be5cd75c6f6d40d4f7b5648bf3ea67f Mon Sep 17 00:00:00 2001 From: BevLow Date: Wed, 9 Oct 2024 20:29:16 +0800 Subject: [PATCH 50/50] Add Updating ReadMe.md --- README.md | 16 +++++----------- .../java/chattycharlie/commands/ByeCommand.java | 1 + .../chattycharlie/userinteractions/Storage.java | 1 - 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 90aa7f092..a40c15043 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# Duke project template +# Chatty Charlie -This is a project template for a greenfield Java project. It's named after the Java mascot _Duke_. Given below are instructions on how to use it. +This is a command line terminal task tracker application. Given below are instructions on how to use it. ## Setting up in Intellij @@ -13,12 +13,6 @@ Prerequisites: JDK 17, update Intellij to the most recent version. 1. If there are any further prompts, accept the defaults. 1. Configure the project to use **JDK 17** (not other versions) as explained in [here](https://www.jetbrains.com/help/idea/sdk.html#set-up-jdk).
In the same dialog, set the **Project language level** field to the `SDK default` option. -3. After that, locate the `src/main/java/Duke.java` file, right-click it, and choose `Run Duke.main()` (if the code editor is showing compile errors, try restarting the IDE). If the setup is correct, you should see something like the below as the output: - ``` - Hello from - ____ _ - | _ \ _ _| | _____ - | | | | | | | |/ / _ \ - | |_| | |_| | < __/ - |____/ \__,_|_|\_\___| - ``` +3. After that, locate the `src/main/java/chattycharlie/ChattyCharlie.java` file, right-click it, and choose `Run ChattyCharlie.main()` (if the code editor is showing compile errors, try restarting the IDE). If the setup is correct, you should see something like the below as the output: + +![Starting Image](./docs/images/intro.png) diff --git a/src/main/java/chattycharlie/commands/ByeCommand.java b/src/main/java/chattycharlie/commands/ByeCommand.java index c1a1ecf07..cca133b0d 100644 --- a/src/main/java/chattycharlie/commands/ByeCommand.java +++ b/src/main/java/chattycharlie/commands/ByeCommand.java @@ -22,6 +22,7 @@ public class ByeCommand implements Command { @Override public void execute(TaskList taskList, Ui ui, Storage storage) throws CharlieExceptions { storage.saveTasks(taskList); + System.out.println(StringDesign.CHARLIE + "We saved your file in: data/tasks.txt"); System.out.println(StringDesign.CHARLIE + StringDesign.FAREWELL); } diff --git a/src/main/java/chattycharlie/userinteractions/Storage.java b/src/main/java/chattycharlie/userinteractions/Storage.java index 76ffc2c2b..672bebf9a 100644 --- a/src/main/java/chattycharlie/userinteractions/Storage.java +++ b/src/main/java/chattycharlie/userinteractions/Storage.java @@ -137,7 +137,6 @@ public void saveTasks(TaskList list) throws CharlieExceptions { } } writer.close(); - System.out.println(StringDesign.CHARLIE + "We saved your file in: " + filePath); } catch (IOException e) { System.out.println("An error has occurred when saving tasks: " + e.getMessage()); }