From 7d4a3b6a2dc023e75b749621d28c3b4524bca363 Mon Sep 17 00:00:00 2001 From: dannytayjy Date: Thu, 19 Aug 2021 19:39:57 +0800 Subject: [PATCH 01/16] Implement Level-1: Greet, Echo, Exit --- src/main/java/Duke.java | 44 +++++++++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 5d313334cc..8a76180b71 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,10 +1,42 @@ +import java.util.Scanner; + public class Duke { public static void main(String[] args) { - String logo = " ____ _ \n" - + "| _ \\ _ _| | _____ \n" - + "| | | | | | | |/ / _ \\\n" - + "| |_| | |_| | < __/\n" - + "|____/ \\__,_|_|\\_\\___|\n"; - System.out.println("Hello from\n" + logo); + echo(greetMessage()); + + Scanner sc = new Scanner(System.in); + String inputCommand = ""; + + do { + System.out.print("Enter command: \t"); + inputCommand = sc.nextLine().trim(); + + switch (inputCommand) { + case "bye": + echo(exitMessage()); + break; + default: + echo("\t" + inputCommand); + break; + } + } while (!inputCommand.equals("bye")); + } + + private static String greetMessage() { + return "\t" + "Hello! I'm Duke" + System.lineSeparator() + + "\t" + "What can I do for you?"; + } + + private static String exitMessage() { + return "\t" + "Bye. Hope to see you again soon!"; + } + + private static void echo(String message) { + String horizontalLine = "\t" + + "____________________________________________________________"; + String nextLine = System.lineSeparator(); + String echoMessage = horizontalLine + nextLine + + message + nextLine + horizontalLine; + System.out.println(echoMessage); } } From 103b9a998b539a15a50f6fa998c552973ea73d96 Mon Sep 17 00:00:00 2001 From: dannytayjy Date: Thu, 19 Aug 2021 19:51:24 +0800 Subject: [PATCH 02/16] Implement Level-2: Add, List --- src/main/java/Duke.java | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 8a76180b71..230231c12a 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,7 +1,11 @@ +import java.util.ArrayList; +import java.util.List; import java.util.Scanner; public class Duke { public static void main(String[] args) { + List commandsList = new ArrayList(); + echo(greetMessage()); Scanner sc = new Scanner(System.in); @@ -15,8 +19,12 @@ public static void main(String[] args) { case "bye": echo(exitMessage()); break; + case "list": + echo(displayCommandsList(commandsList)); + break; default: - echo("\t" + inputCommand); + commandsList.add(inputCommand); + echo(addedCommandMessage(inputCommand)); break; } } while (!inputCommand.equals("bye")); @@ -31,6 +39,25 @@ private static String exitMessage() { return "\t" + "Bye. Hope to see you again soon!"; } + + private static String addedCommandMessage(String inputCommand) { + return "\t" + "added: " + inputCommand; + } + + private static String displayCommandsList(List commandsList) { + String result = ""; + + for (int i = 0; i < commandsList.size(); i++) { + if (i != 0) { + result += System.lineSeparator(); + } + + result += "\t" + (i + 1) + ". " + commandsList.get(i); + } + + return result; + } + private static void echo(String message) { String horizontalLine = "\t" + "____________________________________________________________"; From a48639ac5f3f80437871a1db233b92664c57498d Mon Sep 17 00:00:00 2001 From: dannytayjy Date: Thu, 19 Aug 2021 21:23:46 +0800 Subject: [PATCH 03/16] Implement Level-3: Mark task as Done --- src/main/java/Duke.java | 42 +++++++++++++++++++++++++++-------------- src/main/java/Task.java | 26 +++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 14 deletions(-) create mode 100644 src/main/java/Task.java diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 230231c12a..83e9fefd25 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -4,30 +4,38 @@ public class Duke { public static void main(String[] args) { - List commandsList = new ArrayList(); + List tasksList = new ArrayList(); echo(greetMessage()); Scanner sc = new Scanner(System.in); - String inputCommand = ""; + String commandLine = ""; do { System.out.print("Enter command: \t"); - inputCommand = sc.nextLine().trim(); + commandLine = sc.nextLine().trim(); + String[] command = commandLine.split(" ", 2); - switch (inputCommand) { + switch (command[0]) { case "bye": echo(exitMessage()); break; case "list": - echo(displayCommandsList(commandsList)); + echo(displayTasksList(tasksList)); + break; + case "done": + int taskNum = Integer.parseInt(command[1]); + tasksList.get(taskNum - 1).setDone(); + Task task = tasksList.get(taskNum - 1); + echo(taskDoneMessage(task)); break; default: - commandsList.add(inputCommand); - echo(addedCommandMessage(inputCommand)); + Task newTask = new Task(commandLine); + tasksList.add(newTask); + echo(taskAddedMessage(newTask)); break; } - } while (!inputCommand.equals("bye")); + } while (!commandLine.equals("bye")); } private static String greetMessage() { @@ -40,19 +48,25 @@ private static String exitMessage() { } - private static String addedCommandMessage(String inputCommand) { - return "\t" + "added: " + inputCommand; + private static String taskAddedMessage(Task newTask) { + return "\t" + "added: " + newTask.getDescription(); + } + + private static String taskDoneMessage(Task task) { + return "\t" + "Nice! I've marked this task as done:" + + System.lineSeparator() + "\t\t" + task.toString(); } - private static String displayCommandsList(List commandsList) { - String result = ""; + private static String displayTasksList(List tasksList) { + String result = "\t" + "Here are the tasks in your list:" + + System.lineSeparator(); - for (int i = 0; i < commandsList.size(); i++) { + for (int i = 0; i < tasksList.size(); i++) { if (i != 0) { result += System.lineSeparator(); } - result += "\t" + (i + 1) + ". " + commandsList.get(i); + result += "\t\t" + (i + 1) + "." + "\t" + tasksList.get(i).toString(); } return result; diff --git a/src/main/java/Task.java b/src/main/java/Task.java new file mode 100644 index 0000000000..e4b1324f6f --- /dev/null +++ b/src/main/java/Task.java @@ -0,0 +1,26 @@ +public class Task { + private String description; + private boolean isDone; + + public Task(String description) { + this.description = description; + this.isDone = false; + } + + public String getStatusIcon() { + return (isDone ? "[X]" : "[ ]"); // mark done task with X + } + + public String getDescription() { + return description; + } + + public void setDone() { + this.isDone = true; + } + + @Override + public String toString() { + return getStatusIcon() + " " + description; + } +} From 5ae82e548ebe71761b3b449625161ff9b4916e47 Mon Sep 17 00:00:00 2001 From: dannytayjy Date: Thu, 19 Aug 2021 22:10:54 +0800 Subject: [PATCH 04/16] Implement Level-4: ToDo, Event, Deadline and TaskType Enum --- src/main/java/Deadline.java | 15 ++++ src/main/java/Duke.java | 114 +++++++++++++++++++++------- src/main/java/Event.java | 15 ++++ src/main/java/Task.java | 10 ++- src/main/java/TaskType.java | 21 +++++ src/main/java/TaskWithDateTime.java | 20 +++++ src/main/java/ToDo.java | 10 +++ 7 files changed, 174 insertions(+), 31 deletions(-) create mode 100644 src/main/java/Deadline.java create mode 100644 src/main/java/Event.java create mode 100644 src/main/java/TaskType.java create mode 100644 src/main/java/TaskWithDateTime.java create mode 100644 src/main/java/ToDo.java diff --git a/src/main/java/Deadline.java b/src/main/java/Deadline.java new file mode 100644 index 0000000000..c212256a4b --- /dev/null +++ b/src/main/java/Deadline.java @@ -0,0 +1,15 @@ +public class Deadline extends TaskWithDateTime { + public Deadline(TaskType taskType, String taskDescription, String dateTime) { + super(taskType, taskDescription, dateTime); + } + + @Override + public String dateTimeDetails() { + return "(by: " + super.getDateTime() +")"; + } + + @Override + public String toString() { + return "[" + TaskType.DEADLINE.getAbbr() + "]" + super.toString(); + } +} diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 83e9fefd25..e682feebb0 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -21,55 +21,115 @@ public static void main(String[] args) { echo(exitMessage()); break; case "list": - echo(displayTasksList(tasksList)); + displayTasksList(tasksList); break; case "done": - int taskNum = Integer.parseInt(command[1]); - tasksList.get(taskNum - 1).setDone(); - Task task = tasksList.get(taskNum - 1); - echo(taskDoneMessage(task)); + markDone(command, tasksList); + break; + case "todo": + addToDoTask(command, tasksList); + break; + case "deadline": + addDeadlineTask(command, tasksList); + break; + case "event": + addEventTask(command, tasksList); break; default: - Task newTask = new Task(commandLine); - tasksList.add(newTask); - echo(taskAddedMessage(newTask)); break; } } while (!commandLine.equals("bye")); } - private static String greetMessage() { - return "\t" + "Hello! I'm Duke" + System.lineSeparator() + - "\t" + "What can I do for you?"; + static void displayTasksList(List tasksList) { + String response = "\t" + "Here are the tasks in your list:" + + System.lineSeparator(); + + for (int i = 0; i < tasksList.size(); i++) { + if (i != 0) { + response += System.lineSeparator(); + } + + response += "\t\t" + (i + 1) + "." + "\t" + tasksList.get(i).toString(); + } + + echo(response); } - private static String exitMessage() { - return "\t" + "Bye. Hope to see you again soon!"; + static void markDone(String[] command, List tasksList) { + int taskNum = Integer.parseInt(command[1]); + + if (taskNum <= tasksList.size()) { + tasksList.get(taskNum - 1).setDone(); + Task taskDone = tasksList.get(taskNum - 1); + + String response = taskDoneMessage() + System.lineSeparator() + + "\t\t" + taskDone; + echo(response); + } } + static void addToDoTask(String[] command, List tasksList) { + Task newToDoTask = new ToDo(TaskType.TODO, command[1]); + tasksList.add(newToDoTask); - private static String taskAddedMessage(Task newTask) { - return "\t" + "added: " + newTask.getDescription(); + String response = taskAddedMessage() + System.lineSeparator() + + "\t\t" + newToDoTask + System.lineSeparator() + + numOfTasksInList(tasksList); + echo(response); } - private static String taskDoneMessage(Task task) { - return "\t" + "Nice! I've marked this task as done:" + - System.lineSeparator() + "\t\t" + task.toString(); + static void addDeadlineTask(String[] command, List tasksList) { + String[] deadlineTaskDetails = command[1].split("/", 2); + + if (deadlineTaskDetails.length == 2) { + Task newDeadlineTask = new Deadline(TaskType.DEADLINE, + deadlineTaskDetails[0], deadlineTaskDetails[1]); + tasksList.add(newDeadlineTask); + + String response = taskAddedMessage() + System.lineSeparator() + + "\t\t" + newDeadlineTask + System.lineSeparator() + + numOfTasksInList(tasksList); + echo(response); + } } - private static String displayTasksList(List tasksList) { - String result = "\t" + "Here are the tasks in your list:" - + System.lineSeparator(); + static void addEventTask(String[] command, List tasksList) { + String[] eventTaskDetails = command[1].split("/", 2); - for (int i = 0; i < tasksList.size(); i++) { - if (i != 0) { - result += System.lineSeparator(); - } + if (eventTaskDetails.length == 2) { + Task newEventTask = new Event(TaskType.EVENT, + eventTaskDetails[0], eventTaskDetails[1]); + tasksList.add(newEventTask); - result += "\t\t" + (i + 1) + "." + "\t" + tasksList.get(i).toString(); + String response = taskAddedMessage() + System.lineSeparator() + + "\t\t" + newEventTask + System.lineSeparator() + + numOfTasksInList(tasksList); + echo(response); } + } + + private static String greetMessage() { + return "\t" + "Hello! I'm Duke" + System.lineSeparator() + + "\t" + "What can I do for you?"; + } + + private static String exitMessage() { + return "\t" + "Bye. Hope to see you again soon!"; + } + + private static String taskAddedMessage() { + return "\t" + "Got it. I've added this task:"; + } + + private static String numOfTasksInList(List tasksList) { + return "\t" + "Now you have " + tasksList.size() + + (tasksList.size() > 1 ? " tasks" : " task") + + " in the list."; + } - return result; + private static String taskDoneMessage() { + return "\t" + "Nice! I've marked this task as done:"; } private static void echo(String message) { diff --git a/src/main/java/Event.java b/src/main/java/Event.java new file mode 100644 index 0000000000..747a751b2c --- /dev/null +++ b/src/main/java/Event.java @@ -0,0 +1,15 @@ +public class Event extends TaskWithDateTime { + public Event(TaskType taskType, String taskDescription, String dateTime) { + super(taskType, taskDescription, dateTime); + } + + @Override + public String dateTimeDetails() { + return "(at: " + super.getDateTime() +")"; + } + + @Override + public String toString() { + return "[" + TaskType.EVENT.getAbbr() + "]" + super.toString(); + } +} diff --git a/src/main/java/Task.java b/src/main/java/Task.java index e4b1324f6f..e651685676 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -1,8 +1,10 @@ -public class Task { - private String description; - private boolean isDone; +public abstract class Task { + protected TaskType type; + protected String description; + protected boolean isDone; - public Task(String description) { + public Task(TaskType type, String description) { + this.type = type; this.description = description; this.isDone = false; } diff --git a/src/main/java/TaskType.java b/src/main/java/TaskType.java new file mode 100644 index 0000000000..0d42f84dc3 --- /dev/null +++ b/src/main/java/TaskType.java @@ -0,0 +1,21 @@ +public enum TaskType { + TODO("todo", "T"), + DEADLINE("deadline", "D"), + EVENT("event", "E"); + + private final String label; + private final String abbr; + + TaskType(String label, String abbr) { + this.label = label; + this.abbr = abbr; + } + + public String getLabel() { + return label; + } + + public String getAbbr() { + return abbr; + } +} diff --git a/src/main/java/TaskWithDateTime.java b/src/main/java/TaskWithDateTime.java new file mode 100644 index 0000000000..eeb92c9bf5 --- /dev/null +++ b/src/main/java/TaskWithDateTime.java @@ -0,0 +1,20 @@ +public abstract class TaskWithDateTime extends Task { + protected String dateTime; + + public TaskWithDateTime(TaskType type, String description, String dateTime) { + super(type, description); + this.dateTime = dateTime; + } + + protected String getDateTime() { + String[] dateTimeParts = dateTime.split(" ", 2); + return dateTimeParts[1]; + } + + public abstract String dateTimeDetails(); + + @Override + public String toString() { + return super.toString() + dateTimeDetails(); + } +} diff --git a/src/main/java/ToDo.java b/src/main/java/ToDo.java new file mode 100644 index 0000000000..1341f07c64 --- /dev/null +++ b/src/main/java/ToDo.java @@ -0,0 +1,10 @@ +public class ToDo extends Task { + public ToDo(TaskType type, String description) { + super(type, description); + } + + @Override + public String toString() { + return "[" + TaskType.TODO.getAbbr() + "]" + super.toString(); + } +} From 5c3a321a9abb09308da4da8266ce6185dc2b3a5c Mon Sep 17 00:00:00 2001 From: dannytayjy Date: Thu, 19 Aug 2021 22:29:20 +0800 Subject: [PATCH 05/16] Update Duke.java: Edit print output --- src/main/java/Duke.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index e682feebb0..b5821d9b3d 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -15,6 +15,7 @@ public static void main(String[] args) { System.out.print("Enter command: \t"); commandLine = sc.nextLine().trim(); String[] command = commandLine.split(" ", 2); + System.out.println(); switch (command[0]) { case "bye": From 3f58e09d590e45420a5b1e00f026cb5702c33c3f Mon Sep 17 00:00:00 2001 From: dannytayjy Date: Thu, 19 Aug 2021 22:30:52 +0800 Subject: [PATCH 06/16] Implement A-TextUiTesting: Update EXPECTED.TXT and input.txt --- text-ui-test/EXPECTED.TXT | 95 ++++++++++++++++++++++++++++++++++++--- text-ui-test/input.txt | 13 ++++++ 2 files changed, 101 insertions(+), 7 deletions(-) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 657e74f6e7..d95ef9dca2 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,7 +1,88 @@ -Hello from - ____ _ -| _ \ _ _| | _____ -| | | | | | | |/ / _ \ -| |_| | |_| | < __/ -|____/ \__,_|_|\_\___| - + ____________________________________________________________ + Hello! I'm Duke + What can I do for you? + ____________________________________________________________ +Enter command: + ____________________________________________________________ + Got it. I've added this task: + [T][ ] read book + Now you have 1 task in the list. + ____________________________________________________________ +Enter command: + ____________________________________________________________ + Nice! I've marked this task as done: + [T][X] read book + ____________________________________________________________ +Enter command: + ____________________________________________________________ + Got it. I've added this task: + [D][ ] return book (by: June 6th) + Now you have 2 tasks in the list. + ____________________________________________________________ +Enter command: + ____________________________________________________________ + Got it. I've added this task: + [E][ ] project meeting (at: Aug 6th 2-4pm) + Now you have 3 tasks in the list. + ____________________________________________________________ +Enter command: + ____________________________________________________________ + Got it. I've added this task: + [T][ ] join sports club + Now you have 4 tasks in the list. + ____________________________________________________________ +Enter command: + ____________________________________________________________ + Here are the tasks in your list: + 1. [T][X] read book + 2. [D][ ] return book (by: June 6th) + 3. [E][ ] project meeting (at: Aug 6th 2-4pm) + 4. [T][ ] join sports club + ____________________________________________________________ +Enter command: + ____________________________________________________________ + Nice! I've marked this task as done: + [T][X] join sports club + ____________________________________________________________ +Enter command: + ____________________________________________________________ + Got it. I've added this task: + [T][ ] borrow book + Now you have 5 tasks in the list. + ____________________________________________________________ +Enter command: + ____________________________________________________________ + Here are the tasks in your list: + 1. [T][X] read book + 2. [D][ ] return book (by: June 6th) + 3. [E][ ] project meeting (at: Aug 6th 2-4pm) + 4. [T][X] join sports club + 5. [T][ ] borrow book + ____________________________________________________________ +Enter command: + ____________________________________________________________ + Got it. I've added this task: + [D][ ] return book (by: Sunday) + Now you have 6 tasks in the list. + ____________________________________________________________ +Enter command: + ____________________________________________________________ + Got it. I've added this task: + [E][ ] project meeting (at: Mon 2-4pm) + Now you have 7 tasks in the list. + ____________________________________________________________ +Enter command: + ____________________________________________________________ + Here are the tasks in your list: + 1. [T][X] read book + 2. [D][ ] return book (by: June 6th) + 3. [E][ ] project meeting (at: Aug 6th 2-4pm) + 4. [T][X] join sports club + 5. [T][ ] borrow book + 6. [D][ ] return book (by: Sunday) + 7. [E][ ] project meeting (at: Mon 2-4pm) + ____________________________________________________________ +Enter command: + ____________________________________________________________ + Bye. Hope to see you again soon! + ____________________________________________________________ diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index e69de29bb2..0e3b9235b0 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -0,0 +1,13 @@ +todo read book +done 1 +deadline return book /by June 6th +event project meeting /at Aug 6th 2-4pm +todo join sports club +list +done 4 +todo borrow book +list +deadline return book /by Sunday +event project meeting /at Mon 2-4pm +list +bye \ No newline at end of file From b71fe73570c1e9b56ed129a3515f8057929eccea Mon Sep 17 00:00:00 2001 From: dannytayjy Date: Thu, 19 Aug 2021 23:05:08 +0800 Subject: [PATCH 07/16] Implement Level-5: Handle errors via Exception Handling --- src/main/java/Duke.java | 157 +++++++++++++++++++++---------- src/main/java/DukeException.java | 5 + 2 files changed, 111 insertions(+), 51 deletions(-) create mode 100644 src/main/java/DukeException.java diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index b5821d9b3d..6b2cd52a13 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -22,91 +22,146 @@ public static void main(String[] args) { echo(exitMessage()); break; case "list": - displayTasksList(tasksList); + try { + displayTasksList(tasksList); + } catch (DukeException e) { + echo(e.getMessage()); + } break; case "done": - markDone(command, tasksList); + try { + markDone(command, tasksList); + } catch (DukeException e) { + echo(e.getMessage()); + } break; case "todo": - addToDoTask(command, tasksList); + try { + addToDoTask(command, tasksList); + } catch (DukeException e) { + echo(e.getMessage()); + } break; case "deadline": - addDeadlineTask(command, tasksList); + try { + addDeadlineTask(command, tasksList); + } catch (DukeException e) { + echo(e.getMessage()); + } break; case "event": - addEventTask(command, tasksList); + try { + addEventTask(command, tasksList); + } catch (DukeException e) { + echo(e.getMessage()); + } break; default: + try { + throw new DukeException("☹ OOPS!!! I'm sorry, but I don't know what that means!"); + } catch (DukeException e) { + echo(e.getMessage()); + } break; } } while (!commandLine.equals("bye")); } - static void displayTasksList(List tasksList) { - String response = "\t" + "Here are the tasks in your list:" + - System.lineSeparator(); + static void displayTasksList(List tasksList) throws DukeException { + if (tasksList.size() != 0) { + String response = "\t" + "Here are the tasks in your list:" + + System.lineSeparator(); - for (int i = 0; i < tasksList.size(); i++) { - if (i != 0) { - response += System.lineSeparator(); + for (int i = 0; i < tasksList.size(); i++) { + if (i != 0) { + response += System.lineSeparator(); + } + + response += "\t\t" + (i + 1) + "." + "\t" + tasksList.get(i).toString(); } - response += "\t\t" + (i + 1) + "." + "\t" + tasksList.get(i).toString(); + echo(response); + } else { + throw new DukeException("There are no tasks in your list!"); } - - echo(response); } - static void markDone(String[] command, List tasksList) { - int taskNum = Integer.parseInt(command[1]); + static void markDone(String[] command, List tasksList) throws DukeException { + if (command.length == 2) { + int taskNum = Integer.parseInt(command[1]); - if (taskNum <= tasksList.size()) { - tasksList.get(taskNum - 1).setDone(); - Task taskDone = tasksList.get(taskNum - 1); + if (taskNum <= tasksList.size()) { + tasksList.get(taskNum - 1).setDone(); + Task taskDone = tasksList.get(taskNum - 1); - String response = taskDoneMessage() + System.lineSeparator() + - "\t\t" + taskDone; - echo(response); + String response = taskDoneMessage() + System.lineSeparator() + + "\t\t" + taskDone; + echo(response); + } else { + throw new DukeException("☹ Please select a valid task number to be marked as done."); + } + } else { + throw new DukeException("☹ Please select the task number to be marked as done."); } } - static void addToDoTask(String[] command, List tasksList) { - Task newToDoTask = new ToDo(TaskType.TODO, command[1]); - tasksList.add(newToDoTask); - - String response = taskAddedMessage() + System.lineSeparator() + - "\t\t" + newToDoTask + System.lineSeparator() + - numOfTasksInList(tasksList); - echo(response); - } - - static void addDeadlineTask(String[] command, List tasksList) { - String[] deadlineTaskDetails = command[1].split("/", 2); - - if (deadlineTaskDetails.length == 2) { - Task newDeadlineTask = new Deadline(TaskType.DEADLINE, - deadlineTaskDetails[0], deadlineTaskDetails[1]); - tasksList.add(newDeadlineTask); + static void addToDoTask(String[] command, List tasksList) throws DukeException { + if (command.length == 2) { + Task newToDoTask = new ToDo(TaskType.TODO, command[1]); + tasksList.add(newToDoTask); String response = taskAddedMessage() + System.lineSeparator() + - "\t\t" + newDeadlineTask + System.lineSeparator() + + "\t\t" + newToDoTask + System.lineSeparator() + numOfTasksInList(tasksList); echo(response); + } else { + throw new DukeException("☹ OOPS!!! The description of a todo cannot be empty."); } } - static void addEventTask(String[] command, List tasksList) { - String[] eventTaskDetails = command[1].split("/", 2); - - if (eventTaskDetails.length == 2) { - Task newEventTask = new Event(TaskType.EVENT, - eventTaskDetails[0], eventTaskDetails[1]); - tasksList.add(newEventTask); + static void addDeadlineTask(String[] command, List tasksList) throws DukeException { + if (command.length == 2) { + String[] deadlineTaskDetails = command[1].split("/", 2); + + if (deadlineTaskDetails.length == 2) { + Task newDeadlineTask = new Deadline(TaskType.DEADLINE, + deadlineTaskDetails[0], deadlineTaskDetails[1]); + tasksList.add(newDeadlineTask); + + String response = taskAddedMessage() + System.lineSeparator() + + "\t\t" + newDeadlineTask + System.lineSeparator() + + numOfTasksInList(tasksList); + echo(response); + } else { + throw new DukeException("☹ OOPS!!! The description and/or " + + "specific date/time of a deadline is not valid."); + } + } else { + throw new DukeException("☹ OOPS!!! The description and " + + "specific date/time of a deadline cannot be empty."); + } + } - String response = taskAddedMessage() + System.lineSeparator() + - "\t\t" + newEventTask + System.lineSeparator() + - numOfTasksInList(tasksList); - echo(response); + static void addEventTask(String[] command, List tasksList) throws DukeException { + if (command.length == 2) { + String[] eventTaskDetails = command[1].split("/", 2); + + if (eventTaskDetails.length == 2) { + Task newEventTask = new Event(TaskType.EVENT, + eventTaskDetails[0], eventTaskDetails[1]); + tasksList.add(newEventTask); + + String response = taskAddedMessage() + System.lineSeparator() + + "\t\t" + newEventTask + System.lineSeparator() + + numOfTasksInList(tasksList); + echo(response); + } else { + throw new DukeException("☹ OOPS!!! The description and/or " + + "specific date/time of a deadline is not valid."); + } + } else { + throw new DukeException("☹ OOPS!!! The description and " + + "specific date/time of an event cannot be empty."); } } diff --git a/src/main/java/DukeException.java b/src/main/java/DukeException.java new file mode 100644 index 0000000000..31f5a63d16 --- /dev/null +++ b/src/main/java/DukeException.java @@ -0,0 +1,5 @@ +public class DukeException extends Exception { + public DukeException(String errorMessage) { + super(errorMessage); + } +} From 7c277bc52a944e5f1eae73fffc87e6a0281bb7b7 Mon Sep 17 00:00:00 2001 From: dannytayjy Date: Thu, 19 Aug 2021 23:17:22 +0800 Subject: [PATCH 08/16] Implement Level-6: Delete task --- src/main/java/Duke.java | 115 +++++++++++++++++++--------- src/main/java/Task.java | 16 ++-- src/main/java/TaskWithDateTime.java | 4 +- src/main/java/ToDo.java | 4 +- 4 files changed, 90 insertions(+), 49 deletions(-) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 6b2cd52a13..310e268c2f 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -12,10 +12,9 @@ public static void main(String[] args) { String commandLine = ""; do { - System.out.print("Enter command: \t"); + System.out.println("Enter command: \t"); commandLine = sc.nextLine().trim(); String[] command = commandLine.split(" ", 2); - System.out.println(); switch (command[0]) { case "bye": @@ -35,6 +34,13 @@ public static void main(String[] args) { echo(e.getMessage()); } break; + case "delete": + try { + deleteTask(command, tasksList); + } catch (DukeException e) { + echo(e.getMessage()); + } + break; case "todo": try { addToDoTask(command, tasksList); @@ -58,7 +64,7 @@ public static void main(String[] args) { break; default: try { - throw new DukeException("☹ OOPS!!! I'm sorry, but I don't know what that means!"); + throw new DukeException("\t" + "☹ OOPS!!! I'm sorry, but I don't know what that means!"); } catch (DukeException e) { echo(e.getMessage()); } @@ -69,12 +75,11 @@ public static void main(String[] args) { static void displayTasksList(List tasksList) throws DukeException { if (tasksList.size() != 0) { - String response = "\t" + "Here are the tasks in your list:" + - System.lineSeparator(); + String response = "\t" + "Here are the tasks in your list:" + "\n"; for (int i = 0; i < tasksList.size(); i++) { if (i != 0) { - response += System.lineSeparator(); + response += "\n"; } response += "\t\t" + (i + 1) + "." + "\t" + tasksList.get(i).toString(); @@ -82,7 +87,7 @@ static void displayTasksList(List tasksList) throws DukeException { echo(response); } else { - throw new DukeException("There are no tasks in your list!"); + throw new DukeException("\t" + "There are no tasks in your list!"); } } @@ -94,14 +99,36 @@ static void markDone(String[] command, List tasksList) throws DukeExceptio tasksList.get(taskNum - 1).setDone(); Task taskDone = tasksList.get(taskNum - 1); - String response = taskDoneMessage() + System.lineSeparator() + + String response = doneTaskMessage() + "\n" + "\t\t" + taskDone; echo(response); } else { - throw new DukeException("☹ Please select a valid task number to be marked as done."); + throw new DukeException("\t" + "☹ Please select a valid task number to be marked as done."); + } + + } else { + throw new DukeException("\t" + "☹ Please select the task number to be marked as done."); + } + } + + static void deleteTask(String[] command, List tasksList) throws DukeException { + if (command.length == 2) { + int taskNum = Integer.parseInt(command[1]); + + if (taskNum <= tasksList.size()) { + Task taskToDelete = tasksList.get(taskNum - 1); + tasksList.remove(taskToDelete); + + String response = deleteTaskMessage() + "\n" + + "\t\t" + taskToDelete + "\n" + + numOfTasksInList(tasksList); + echo(response); + } else { + throw new DukeException("\t" + "☹ Please select a valid task number to be deleted."); } + } else { - throw new DukeException("☹ Please select the task number to be marked as done."); + throw new DukeException("\t" + "☹ Please select the task number to be deleted."); } } @@ -110,12 +137,12 @@ static void addToDoTask(String[] command, List tasksList) throws DukeExcep Task newToDoTask = new ToDo(TaskType.TODO, command[1]); tasksList.add(newToDoTask); - String response = taskAddedMessage() + System.lineSeparator() + - "\t\t" + newToDoTask + System.lineSeparator() + + String response = addTaskMessage() + "\n" + + "\t\t" + newToDoTask + "\n" + numOfTasksInList(tasksList); echo(response); } else { - throw new DukeException("☹ OOPS!!! The description of a todo cannot be empty."); + throw new DukeException("\t" + "☹ OOPS!!! The description of a todo cannot be empty."); } } @@ -128,16 +155,13 @@ static void addDeadlineTask(String[] command, List tasksList) throws DukeE deadlineTaskDetails[0], deadlineTaskDetails[1]); tasksList.add(newDeadlineTask); - String response = taskAddedMessage() + System.lineSeparator() + - "\t\t" + newDeadlineTask + System.lineSeparator() + + String response = addTaskMessage() + "\n" + + "\t\t" + newDeadlineTask + "\n" + numOfTasksInList(tasksList); echo(response); - } else { - throw new DukeException("☹ OOPS!!! The description and/or " + - "specific date/time of a deadline is not valid."); } } else { - throw new DukeException("☹ OOPS!!! The description and " + + throw new DukeException("\t" + "☹ OOPS!!! The description and/or " + "specific date/time of a deadline cannot be empty."); } } @@ -151,47 +175,68 @@ static void addEventTask(String[] command, List tasksList) throws DukeExce eventTaskDetails[0], eventTaskDetails[1]); tasksList.add(newEventTask); - String response = taskAddedMessage() + System.lineSeparator() + - "\t\t" + newEventTask + System.lineSeparator() + + String response = addTaskMessage() + "\n" + + "\t\t" + newEventTask + "\n" + numOfTasksInList(tasksList); echo(response); - } else { - throw new DukeException("☹ OOPS!!! The description and/or " + - "specific date/time of a deadline is not valid."); } } else { - throw new DukeException("☹ OOPS!!! The description and " + + throw new DukeException("☹ OOPS!!! The description and/or " + "specific date/time of an event cannot be empty."); } } private static String greetMessage() { - return "\t" + "Hello! I'm Duke" + System.lineSeparator() + - "\t" + "What can I do for you?"; + return "\t" + "Hello! I'm Duke, your Personal Assistant Chatbot." + "\n" + + "\t" + "What can I do for you?\n\n" + + instructions(); + } + + private static String instructions() { + return "\t" + "Menu Options:" + "\n" + + "\t\t" + "1." + "\t" + "list" + "\n" + + "\t\t\t" + "[List the tasks in your list]" + "\n" + + "\t\t" + "2." + "\t" + "todo ABC" + "\n" + + "\t\t\t" + "[Add a todo task, ABC, into your list]" + "\n" + + "\t\t" + "3." + "\t" + "deadline ABC /by XYZ" + "\n" + + "\t\t\t" + "[Add a deadline task, ABC, into your list." + + " Specify the date/time, XYZ, it needs to be completed by.]" + "\n" + + "\t\t" + "4." + "\t" + "event ABC /at XYZ" + "\n" + + "\t\t\t" + "[Add an event task, ABC, into your list." + + " Specify the start and end date/time, XYZ.]" + "\n" + + "\t\t" + "5." + "\t" + "done N" + "\n" + + "\t\t\t" + "[Mark a task number, N, as done]" + "\n" + + "\t\t" + "6." + "\t" + "delete N" + "\n" + + "\t\t\t" + "[Delete a task number, N, from your list]" + "\n" + + "\t\t" + "7." + "\t" + "bye" + "\n" + + "\t\t\t" + "[Exit the chatbot]"; } private static String exitMessage() { return "\t" + "Bye. Hope to see you again soon!"; } - private static String taskAddedMessage() { + public static String addTaskMessage() { return "\t" + "Got it. I've added this task:"; } + private static String doneTaskMessage() { + return "\t" + "Nice! I've marked this task as done:"; + } + + private static String deleteTaskMessage() { + return "\t" + "Noted. I've removed this task:"; + } + private static String numOfTasksInList(List tasksList) { return "\t" + "Now you have " + tasksList.size() + (tasksList.size() > 1 ? " tasks" : " task") + " in the list."; } - private static String taskDoneMessage() { - return "\t" + "Nice! I've marked this task as done:"; - } - private static void echo(String message) { - String horizontalLine = "\t" + - "____________________________________________________________"; - String nextLine = System.lineSeparator(); + String horizontalLine = "\t" + "------------------------------------------------------------"; + String nextLine = "\n"; String echoMessage = horizontalLine + nextLine + message + nextLine + horizontalLine; System.out.println(echoMessage); diff --git a/src/main/java/Task.java b/src/main/java/Task.java index e651685676..c24dae1acb 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -1,11 +1,11 @@ public abstract class Task { - protected TaskType type; - protected String description; + protected TaskType taskType; + protected String taskDescription; protected boolean isDone; - public Task(TaskType type, String description) { - this.type = type; - this.description = description; + public Task(TaskType taskType, String taskDescription) { + this.taskType = taskType; + this.taskDescription = taskDescription; this.isDone = false; } @@ -13,16 +13,12 @@ public String getStatusIcon() { return (isDone ? "[X]" : "[ ]"); // mark done task with X } - public String getDescription() { - return description; - } - public void setDone() { this.isDone = true; } @Override public String toString() { - return getStatusIcon() + " " + description; + return getStatusIcon() + " " + taskDescription; } } diff --git a/src/main/java/TaskWithDateTime.java b/src/main/java/TaskWithDateTime.java index eeb92c9bf5..2955b6ef49 100644 --- a/src/main/java/TaskWithDateTime.java +++ b/src/main/java/TaskWithDateTime.java @@ -1,8 +1,8 @@ public abstract class TaskWithDateTime extends Task { protected String dateTime; - public TaskWithDateTime(TaskType type, String description, String dateTime) { - super(type, description); + public TaskWithDateTime(TaskType taskType, String taskDescription, String dateTime) { + super(taskType, taskDescription); this.dateTime = dateTime; } diff --git a/src/main/java/ToDo.java b/src/main/java/ToDo.java index 1341f07c64..e922f4d97e 100644 --- a/src/main/java/ToDo.java +++ b/src/main/java/ToDo.java @@ -1,6 +1,6 @@ public class ToDo extends Task { - public ToDo(TaskType type, String description) { - super(type, description); + public ToDo(TaskType taskType, String taskDescription) { + super(taskType, taskDescription); } @Override From 73492fc022c3ee2d66eebf1c77bfbbaaa4b7e881 Mon Sep 17 00:00:00 2001 From: dannytayjy Date: Thu, 26 Aug 2021 10:33:36 +0800 Subject: [PATCH 09/16] Implement Level-7: Save tasks to text file --- src/main/java/Command.java | 17 + src/main/java/Deadline.java | 12 +- src/main/java/Duke.java | 476 +++++++++++++++++----------- src/main/java/Event.java | 10 +- src/main/java/Print.java | 69 ++++ src/main/java/ResponseMessage.java | 46 +++ src/main/java/Storage.java | 34 ++ src/main/java/Task.java | 34 +- src/main/java/TaskWithDateTime.java | 17 +- src/main/java/ToDo.java | 10 +- 10 files changed, 520 insertions(+), 205 deletions(-) create mode 100644 src/main/java/Command.java create mode 100644 src/main/java/Print.java create mode 100644 src/main/java/ResponseMessage.java create mode 100644 src/main/java/Storage.java diff --git a/src/main/java/Command.java b/src/main/java/Command.java new file mode 100644 index 0000000000..e718a769fd --- /dev/null +++ b/src/main/java/Command.java @@ -0,0 +1,17 @@ +public class Command { + private String type; + private String details; + + public Command(String type, String details) { + this.type = type; + this.details = details; + } + + public String getType() { + return type; + } + + public String getDetails() { + return details; + } +} diff --git a/src/main/java/Deadline.java b/src/main/java/Deadline.java index c212256a4b..15fd984e14 100644 --- a/src/main/java/Deadline.java +++ b/src/main/java/Deadline.java @@ -1,15 +1,19 @@ public class Deadline extends TaskWithDateTime { - public Deadline(TaskType taskType, String taskDescription, String dateTime) { - super(taskType, taskDescription, dateTime); + public Deadline(TaskType type, String description, String dateTime) { + super(type, description, dateTime); + } + + public Deadline(TaskType type, String description, String dateTime, boolean isDone) { + super(type, description, dateTime, isDone); } @Override public String dateTimeDetails() { - return "(by: " + super.getDateTime() +")"; + return "(by: " + super.getDateTime() + ")"; } @Override public String toString() { - return "[" + TaskType.DEADLINE.getAbbr() + "]" + super.toString(); + return "[" + TaskType.DEADLINE.getAbbr() + "] " + super.toString(); } } diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 310e268c2f..c2d71305f8 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,244 +1,362 @@ +import java.io.*; import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class Duke { public static void main(String[] args) { - List tasksList = new ArrayList(); + String pathName = "data"; + String fileName = "tasks.txt"; - echo(greetMessage()); + try { + File dataDirectory = Storage.initialiseDirectory(pathName); + File dataFile = Storage.initialiseFile(dataDirectory, fileName); - Scanner sc = new Scanner(System.in); - String commandLine = ""; + List tasksList = new ArrayList(); - do { - System.out.println("Enter command: \t"); - commandLine = sc.nextLine().trim(); - String[] command = commandLine.split(" ", 2); + Print.printProgramStartMessage(); - switch (command[0]) { - case "bye": - echo(exitMessage()); - break; - case "list": - try { + Scanner sc = new Scanner(System.in); + String commandLine = ""; + + readTasksFromFile(dataFile, tasksList); + + do { + System.out.println("ENTER COMMAND:"); + System.out.print("\t"); + commandLine = sc.nextLine().trim(); + String[] commandLineParts = commandLine.split("\\s+", 2); + + Command command; + + if (commandLineParts.length == 2) { + command = new Command(commandLineParts[0], commandLineParts[1]); + } else { + command = new Command(commandLineParts[0], ""); + } + + try { + switch (command.getType()) { + case "bye": + Print.printResponse(ResponseMessage.exitMessage()); + break; + case "list": displayTasksList(tasksList); - } catch (DukeException e) { - echo(e.getMessage()); - } - break; - case "done": - try { + break; + case "done": markDone(command, tasksList); - } catch (DukeException e) { - echo(e.getMessage()); - } - break; - case "delete": - try { + saveTasksToFile(dataFile, tasksList); + break; + case "delete": deleteTask(command, tasksList); - } catch (DukeException e) { - echo(e.getMessage()); - } - break; - case "todo": - try { + saveTasksToFile(dataFile, tasksList); + break; + case "todo": addToDoTask(command, tasksList); - } catch (DukeException e) { - echo(e.getMessage()); - } - break; - case "deadline": - try { + saveTasksToFile(dataFile, tasksList); + break; + case "deadline": addDeadlineTask(command, tasksList); - } catch (DukeException e) { - echo(e.getMessage()); - } - break; - case "event": - try { + saveTasksToFile(dataFile, tasksList); + break; + case "event": addEventTask(command, tasksList); - } catch (DukeException e) { - echo(e.getMessage()); + saveTasksToFile(dataFile, tasksList); + break; + default: + throw new DukeException("Invalid command. Please try again!"); } + } catch (DukeException e) { + Print.printErrorMessage(e.getMessage()); + } + } while (!commandLine.equals("bye")); + } catch (DukeException | IOException e) { + Print.printErrorMessage(e.getMessage()); + } + } + + static void readTasksFromFile(File dataFile, List tasksList) { + try { + FileReader fr = new FileReader(dataFile); + BufferedReader br = new BufferedReader(fr); + String line; + + while ((line = br.readLine()) != null) { + String[] task = line.trim().split("\\|"); + String taskType = task[0].trim(); + boolean isTaskDone = Boolean.parseBoolean(task[1].trim()); + String taskDescription = task[2].trim(); + String taskDateTime = ""; + + switch (taskType) { + case "T": + Task todoTask = readToDoTask(isTaskDone, taskDescription); + tasksList.add(todoTask); break; - default: - try { - throw new DukeException("\t" + "☹ OOPS!!! I'm sorry, but I don't know what that means!"); - } catch (DukeException e) { - echo(e.getMessage()); - } + case "D": + taskDateTime = task[3].trim(); + Task deadlineTask = readDeadlineTask(isTaskDone, taskDescription, taskDateTime); + tasksList.add(deadlineTask); + break; + case "E": + taskDateTime = task[3].trim(); + Task eventTask = readEventTask(isTaskDone, taskDescription, taskDateTime); + tasksList.add(eventTask); break; + } } - } while (!commandLine.equals("bye")); + + fr.close(); + } catch (IOException e) { + Print.printErrorMessage(e.getMessage()); + } } - static void displayTasksList(List tasksList) throws DukeException { - if (tasksList.size() != 0) { - String response = "\t" + "Here are the tasks in your list:" + "\n"; + static Task readToDoTask(boolean isDone, String description) { + return new ToDo(TaskType.TODO, description, isDone); + } + + static Task readDeadlineTask(boolean isDone, String description, String dateTime) { + return new Deadline(TaskType.DEADLINE, description, dateTime, isDone); + } + + static Task readEventTask(boolean isDone, String description, String dateTime) { + return new Event(TaskType.EVENT, description, dateTime, isDone); + } + + static void saveTasksToFile(File dataFile, List taskList) { + try { + FileWriter fileWriter = new FileWriter(dataFile,false); + String taskDetails = ""; + + for (int i = 0; i < taskList.size(); i++) { + Task task = taskList.get(i); - for (int i = 0; i < tasksList.size(); i++) { - if (i != 0) { - response += "\n"; + TaskType type = task.getType(); + boolean isDone = task.isDone(); + String description = task.getDescription(); + String dateTime; + + if (type == TaskType.TODO) { + dateTime = ""; + } else { + dateTime = ((TaskWithDateTime) task).getDateTime(); } - response += "\t\t" + (i + 1) + "." + "\t" + tasksList.get(i).toString(); + taskDetails = taskDetailsSaveFormat(type, isDone, description, dateTime); + fileWriter.write(taskDetails + System.lineSeparator()); } - echo(response); + fileWriter.close(); + } catch (IOException e) { + Print.printErrorMessage(e.getMessage()); + } + } + + static String taskDetailsSaveFormat(TaskType type, boolean isDone, String description, String dateTime) { + if (dateTime.equals("")) { + return type.getAbbr() + " | " + (isDone ? "1" : "0") + " | " + description; + } else { + return type.getAbbr() + " | " + (isDone ? "1" : "0") + " | " + description + " | " + dateTime; + } + } + + static void displayTasksList(List tasksList) throws DukeException { + if (tasksList.size() != 0) { + String response = ResponseMessage.tasksInYourListMessage(tasksList); + Print.printResponse(response); } else { - throw new DukeException("\t" + "There are no tasks in your list!"); + throw new DukeException("There are no tasks in your list."); } } - static void markDone(String[] command, List tasksList) throws DukeException { - if (command.length == 2) { - int taskNum = Integer.parseInt(command[1]); + static void markDone(Command command, List tasksList) throws DukeException { + String commandDetails = command.getDetails(); - if (taskNum <= tasksList.size()) { - tasksList.get(taskNum - 1).setDone(); - Task taskDone = tasksList.get(taskNum - 1); + if (commandDetails.trim().length() > 0) { + try { + int taskNum = Integer.parseInt(commandDetails); - String response = doneTaskMessage() + "\n" + - "\t\t" + taskDone; - echo(response); - } else { - throw new DukeException("\t" + "☹ Please select a valid task number to be marked as done."); - } + if (taskNum >= 1 && taskNum <= tasksList.size()) { + tasksList.get(taskNum - 1).setDone(); + Task taskDone = tasksList.get(taskNum - 1); + String response = ResponseMessage.taskDoneMessage(taskDone); + Print.printResponse(response); + } else { + throw new DukeException("Please enter a valid task number to be marked as done."); + } + } catch (NumberFormatException e) { + throw new DukeException("Please enter a valid task number to be marked as done."); + } } else { - throw new DukeException("\t" + "☹ Please select the task number to be marked as done."); + throw new DukeException("Please enter a task number to be marked as done."); } } - static void deleteTask(String[] command, List tasksList) throws DukeException { - if (command.length == 2) { - int taskNum = Integer.parseInt(command[1]); + static void deleteTask(Command command, List tasksList) throws DukeException { + String commandDetails = command.getDetails(); - if (taskNum <= tasksList.size()) { - Task taskToDelete = tasksList.get(taskNum - 1); - tasksList.remove(taskToDelete); + if (commandDetails.trim().length() > 0) { + try { + int taskNum = Integer.parseInt(commandDetails); - String response = deleteTaskMessage() + "\n" + - "\t\t" + taskToDelete + "\n" + - numOfTasksInList(tasksList); - echo(response); - } else { - throw new DukeException("\t" + "☹ Please select a valid task number to be deleted."); - } + if (taskNum >= 1 && taskNum <= tasksList.size()) { + Task taskToDelete = tasksList.get(taskNum - 1); + tasksList.remove(taskToDelete); + String response = ResponseMessage.taskDeletedMessage(taskToDelete) + + System.lineSeparator() + ResponseMessage.numOfTasksInList(tasksList); + Print.printResponse(response); + } else { + throw new DukeException("Please enter a valid task number to be deleted."); + } + } catch (NumberFormatException e) { + throw new DukeException("Please enter a valid task number to be deleted."); + } } else { - throw new DukeException("\t" + "☹ Please select the task number to be deleted."); + throw new DukeException("Please enter a task number to be deleted."); } } - static void addToDoTask(String[] command, List tasksList) throws DukeException { - if (command.length == 2) { - Task newToDoTask = new ToDo(TaskType.TODO, command[1]); + static void addToDoTask(Command command, List tasksList) throws DukeException { + String commandDetails = command.getDetails(); + + if (commandDetails.trim().length() > 0) { + Task newToDoTask = new ToDo(TaskType.TODO, commandDetails); tasksList.add(newToDoTask); - String response = addTaskMessage() + "\n" + - "\t\t" + newToDoTask + "\n" + - numOfTasksInList(tasksList); - echo(response); + String response = ResponseMessage.taskAddedMessage(newToDoTask) + + System.lineSeparator() + ResponseMessage.numOfTasksInList(tasksList); + Print.printResponse(response); } else { - throw new DukeException("\t" + "☹ OOPS!!! The description of a todo cannot be empty."); + throw new DukeException("The description of a todo cannot be empty."); } } - static void addDeadlineTask(String[] command, List tasksList) throws DukeException { - if (command.length == 2) { - String[] deadlineTaskDetails = command[1].split("/", 2); + static void addDeadlineTask(Command command, List tasksList) throws DukeException { + String commandDetails = command.getDetails(); + + if (commandDetails.trim().length() > 0) { + String[] deadlineTaskDetails = commandDetails.split("/", 2); if (deadlineTaskDetails.length == 2) { - Task newDeadlineTask = new Deadline(TaskType.DEADLINE, - deadlineTaskDetails[0], deadlineTaskDetails[1]); - tasksList.add(newDeadlineTask); - - String response = addTaskMessage() + "\n" + - "\t\t" + newDeadlineTask + "\n" + - numOfTasksInList(tasksList); - echo(response); + if (deadlineTaskDetails[0].trim().length() > 0) { + if (deadlineTaskDetails[1].trim().startsWith("by")) { + String description = deadlineTaskDetails[0].trim(); + String beforeDateTime = deadlineTaskDetails[1].trim(); + String[] beforeDateTimeParts = beforeDateTime.split("\\s+", 2); + + if (beforeDateTimeParts.length == 2) { + Task newDeadlineTask = new Deadline(TaskType.DEADLINE, + description, beforeDateTimeParts[1]); + tasksList.add(newDeadlineTask); + + String response = ResponseMessage.taskAddedMessage(newDeadlineTask) + + System.lineSeparator() + ResponseMessage.numOfTasksInList(tasksList); + Print.printResponse(response); + } else { + throw new DukeException("The date/time of a deadline cannot be empty." + + System.lineSeparator() + "\t" + + "[Note: Enter /by before specifying the date/time]"); + } + } else { + throw new DukeException("The date/time of a deadline is not valid." + + System.lineSeparator() + "\t" + + "[Note: Enter /by before specifying the date/time]"); + } + } else { + if (deadlineTaskDetails[1].trim().startsWith("by")) { + String beforeDateTime = deadlineTaskDetails[1].trim(); + String[] beforeDateTimeParts = beforeDateTime.split("\\s+", 2); + + if (beforeDateTimeParts.length == 2) { + throw new DukeException("The description of a deadline cannot be empty."); + } else { + throw new DukeException("The description of a deadline cannot be empty." + + System.lineSeparator() + "\t" + + "☹ The date/time of a deadline cannot be empty." + + System.lineSeparator() + "\t" + + "[Note: Enter /by before specifying the date/time]"); + } + } else { + throw new DukeException("The description of a deadline cannot be empty." + + System.lineSeparator() + "\t" + + "☹ The date/time of a deadline is not valid." + + System.lineSeparator() + "\t" + + "[Note: Enter /by before specifying the date/time]"); + } + } + } else { + throw new DukeException("The date/time of a deadline cannot be empty." + + System.lineSeparator() + "\t" + + "[Note: Enter /by before specifying the date/time]"); } } else { - throw new DukeException("\t" + "☹ OOPS!!! The description and/or " + - "specific date/time of a deadline cannot be empty."); + throw new DukeException("The description and date/time of a deadline cannot be empty."); } } - static void addEventTask(String[] command, List tasksList) throws DukeException { - if (command.length == 2) { - String[] eventTaskDetails = command[1].split("/", 2); + static void addEventTask(Command command, List tasksList) throws DukeException { + String commandDetails = command.getDetails(); + + if (commandDetails.trim().length() > 0) { + String[] eventTaskDetails = commandDetails.split("/", 2); if (eventTaskDetails.length == 2) { - Task newEventTask = new Event(TaskType.EVENT, - eventTaskDetails[0], eventTaskDetails[1]); - tasksList.add(newEventTask); - - String response = addTaskMessage() + "\n" + - "\t\t" + newEventTask + "\n" + - numOfTasksInList(tasksList); - echo(response); + if (eventTaskDetails[0].trim().length() > 0) { + if (eventTaskDetails[1].trim().startsWith("at")) { + String description = eventTaskDetails[0].trim(); + String startEndDateTime = eventTaskDetails[1].trim(); + String[] startEndDateTimeParts = startEndDateTime.split("\\s+", 2); + + if (startEndDateTimeParts.length == 2) { + Task newEventTask = new Event(TaskType.EVENT, + description, startEndDateTimeParts[1]); + tasksList.add(newEventTask); + + String response = ResponseMessage.taskAddedMessage(newEventTask) + + System.lineSeparator() + ResponseMessage.numOfTasksInList(tasksList); + Print.printResponse(response); + } else { + throw new DukeException("The date/time of an event cannot be empty." + + System.lineSeparator() + "\t" + + "[Note: Enter /at before specifying the date/time.]"); + } + } else { + throw new DukeException("The date/time of an event is not valid." + + System.lineSeparator() + "\t" + + "[Note: Enter /at before specifying the date/time]"); + } + } else { + if (eventTaskDetails[1].trim().startsWith("at")) { + String startEndDateTime = eventTaskDetails[1].trim(); + String[] startEndDateTimeParts = startEndDateTime.split("\\s+", 2); + + if (startEndDateTimeParts.length == 2) { + throw new DukeException("The description of an event cannot be empty."); + } else { + throw new DukeException("The description of an event cannot be empty." + + System.lineSeparator() + "\t" + + "☹ The date/time of an event cannot be empty." + + System.lineSeparator() + "\t" + + "[Note: Enter /at before specifying the date/time]"); + } + } else { + throw new DukeException("The description of an event cannot be empty." + + System.lineSeparator() + "\t" + + "☹ The date/time of an event is not valid." + + System.lineSeparator() + "\t" + + "[Note: Enter /at before specifying the date/time]"); + } + } + } else { + throw new DukeException("The date/time of an event cannot be empty." + + System.lineSeparator() + "\t" + + "[Note: Enter /at before specifying the date/time]"); } } else { - throw new DukeException("☹ OOPS!!! The description and/or " + - "specific date/time of an event cannot be empty."); + throw new DukeException("The description and date/time of an event cannot be empty."); } } - - private static String greetMessage() { - return "\t" + "Hello! I'm Duke, your Personal Assistant Chatbot." + "\n" + - "\t" + "What can I do for you?\n\n" + - instructions(); - } - - private static String instructions() { - return "\t" + "Menu Options:" + "\n" + - "\t\t" + "1." + "\t" + "list" + "\n" + - "\t\t\t" + "[List the tasks in your list]" + "\n" + - "\t\t" + "2." + "\t" + "todo ABC" + "\n" + - "\t\t\t" + "[Add a todo task, ABC, into your list]" + "\n" + - "\t\t" + "3." + "\t" + "deadline ABC /by XYZ" + "\n" + - "\t\t\t" + "[Add a deadline task, ABC, into your list." + - " Specify the date/time, XYZ, it needs to be completed by.]" + "\n" + - "\t\t" + "4." + "\t" + "event ABC /at XYZ" + "\n" + - "\t\t\t" + "[Add an event task, ABC, into your list." + - " Specify the start and end date/time, XYZ.]" + "\n" + - "\t\t" + "5." + "\t" + "done N" + "\n" + - "\t\t\t" + "[Mark a task number, N, as done]" + "\n" + - "\t\t" + "6." + "\t" + "delete N" + "\n" + - "\t\t\t" + "[Delete a task number, N, from your list]" + "\n" + - "\t\t" + "7." + "\t" + "bye" + "\n" + - "\t\t\t" + "[Exit the chatbot]"; - } - - private static String exitMessage() { - return "\t" + "Bye. Hope to see you again soon!"; - } - - public static String addTaskMessage() { - return "\t" + "Got it. I've added this task:"; - } - - private static String doneTaskMessage() { - return "\t" + "Nice! I've marked this task as done:"; - } - - private static String deleteTaskMessage() { - return "\t" + "Noted. I've removed this task:"; - } - - private static String numOfTasksInList(List tasksList) { - return "\t" + "Now you have " + tasksList.size() + - (tasksList.size() > 1 ? " tasks" : " task") + - " in the list."; - } - - private static void echo(String message) { - String horizontalLine = "\t" + "------------------------------------------------------------"; - String nextLine = "\n"; - String echoMessage = horizontalLine + nextLine + - message + nextLine + horizontalLine; - System.out.println(echoMessage); - } } diff --git a/src/main/java/Event.java b/src/main/java/Event.java index 747a751b2c..ea35048b47 100644 --- a/src/main/java/Event.java +++ b/src/main/java/Event.java @@ -1,6 +1,10 @@ public class Event extends TaskWithDateTime { - public Event(TaskType taskType, String taskDescription, String dateTime) { - super(taskType, taskDescription, dateTime); + public Event(TaskType type, String description, String dateTime) { + super(type, description, dateTime); + } + + public Event(TaskType type, String description, String dateTime, boolean isDone) { + super(type, description, dateTime, isDone); } @Override @@ -10,6 +14,6 @@ public String dateTimeDetails() { @Override public String toString() { - return "[" + TaskType.EVENT.getAbbr() + "]" + super.toString(); + return "[" + TaskType.EVENT.getAbbr() + "] " + super.toString(); } } diff --git a/src/main/java/Print.java b/src/main/java/Print.java new file mode 100644 index 0000000000..2d0bb1d534 --- /dev/null +++ b/src/main/java/Print.java @@ -0,0 +1,69 @@ +public class Print { + static void printProgramStartMessage() { + printHorizontalLine(); + printGreetMessage(); + printMenuOptions(); + printHorizontalLine(); + } + + static void printResponse(String message) { + printHorizontalLine(); + System.out.println(message); + printHorizontalLine(); + } + + static void printErrorMessage(String message) { + printHorizontalLine(); + System.out.println("ERROR MESSAGE:"); + System.out.println("\t" + "☹ " + message); + printHorizontalLine(); + } + + private static void printHorizontalLine() { + String horizontalLine = "____________________________________________________________"; + System.out.println(horizontalLine); + } + + private static void printGreetMessage() { + String message = "\t" + "Hello! I'm Duke, your Personal Assistant Chatbot." + + System.lineSeparator() + + "\t" + "What can I do for you?" + + System.lineSeparator(); + System.out.println(message); + } + + private static void printMenuOptions() { + String format = "%-25s%s%n"; + + String menuOption1 = "\t" + "list:"; + String menuOption1Info = "List the tasks in your list"; + + String menuOption2 = "\t" + "todo ABC:"; + String menuOption2Info = "Add a todo [T] task, ABC, into your list"; + + String menuOption3 = "\t" + "deadline ABC /by XYZ:"; + String menuOption3Info = "Add a deadline [D] task, ABC, into your list " + + "and specify the date/time, XYZ, it needs to be completed by"; + + String menuOption4 = "\t" + "event ABC /at XYZ:"; + String menuOption4Info = "Add an event [E] task, ABC, into your list " + + "and specify the start and end date/time, XYZ"; + + String menuOption5 = "\t" + "done N:"; + String menuOption5Info = "Mark a task number, N, as done"; + + String menuOption6 = "\t" + "delete N:"; + String menuOption6Info = "Delete a task number, N, from your list"; + + String menuOption7 = "\t" + "bye:"; + String menuOption7Info = "Exit the chatbot"; + + System.out.printf(format, menuOption1, menuOption1Info); + System.out.printf(format, menuOption2, menuOption2Info); + System.out.printf(format, menuOption3, menuOption3Info); + System.out.printf(format, menuOption4, menuOption4Info); + System.out.printf(format, menuOption5, menuOption5Info); + System.out.printf(format, menuOption6, menuOption6Info); + System.out.printf(format, menuOption7, menuOption7Info); + } +} diff --git a/src/main/java/ResponseMessage.java b/src/main/java/ResponseMessage.java new file mode 100644 index 0000000000..b31724dfbc --- /dev/null +++ b/src/main/java/ResponseMessage.java @@ -0,0 +1,46 @@ +import java.util.List; + +public class ResponseMessage { + static String exitMessage() { + return "\t" + "Bye. Hope to see you again soon!"; + } + + static String taskAddedMessage(Task task) { + return "\t" + "Got it. I've added this task:" + + System.lineSeparator() + "\t\t" + task; + } + + static String taskDeletedMessage(Task task) { + return "\t" + "Noted. I've removed this task:" + + System.lineSeparator() + "\t\t" + task; + } + + static String taskDoneMessage(Task task) { + return "\t" + "Nice! I've marked this task as done:" + + System.lineSeparator() + "\t\t" + task; + } + + static String tasksInYourListMessage(List tasksList) { + String response = "\t" + "Here are the tasks in your list:" + + System.lineSeparator() + + "\t" + "[Legend: T = todo, D = deadline, E = event]" + + System.lineSeparator() + + System.lineSeparator(); + + for (int i = 0; i < tasksList.size(); i++) { + if (i != 0) { + response += System.lineSeparator(); + } + + response += "\t\t" + (i + 1) + "." + "\t" + tasksList.get(i).toString(); + } + + return response; + } + + static String numOfTasksInList(List tasksList) { + return "\t" + "Now you have " + tasksList.size() + + (tasksList.size() > 1 ? " tasks" : " task") + + " in the list."; + } +} diff --git a/src/main/java/Storage.java b/src/main/java/Storage.java new file mode 100644 index 0000000000..8ef081881f --- /dev/null +++ b/src/main/java/Storage.java @@ -0,0 +1,34 @@ +import java.io.File; +import java.io.IOException; + +public class Storage { + static File initialiseDirectory(String pathName) throws DukeException { + File directory = new File(pathName); + boolean hasDirectory = directory.exists(); + + if (!hasDirectory) { + hasDirectory = directory.mkdir(); + } + + if (hasDirectory) { + return directory; + } else { + throw new DukeException("\t" + "Unable to initialise directory"); + } + } + + static File initialiseFile(File directory, String fileName) throws IOException { + File file = new File(directory + "/" + fileName); + boolean hasFile = file.exists(); + + if (!hasFile) { + hasFile = file.createNewFile(); + } + + if (hasFile) { + return file; + } else { + throw new IOException("\t" + "Unable to initialise file"); + } + } +} diff --git a/src/main/java/Task.java b/src/main/java/Task.java index c24dae1acb..623115cb69 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -1,16 +1,32 @@ public abstract class Task { - protected TaskType taskType; - protected String taskDescription; - protected boolean isDone; + private TaskType type; + private String description; + private boolean isDone; - public Task(TaskType taskType, String taskDescription) { - this.taskType = taskType; - this.taskDescription = taskDescription; - this.isDone = false; + public Task(TaskType type, String description) { + this(type, description, false); + } + + public Task(TaskType type, String description, boolean isDone) { + this.type = type; + this.description = description; + this.isDone = isDone; + } + + public TaskType getType() { + return type; + } + + public String getDescription() { + return description; + } + + public boolean isDone() { + return isDone; } public String getStatusIcon() { - return (isDone ? "[X]" : "[ ]"); // mark done task with X + return (isDone ? "[✔]" : "[ ]"); // mark done task with ✔ } public void setDone() { @@ -19,6 +35,6 @@ public void setDone() { @Override public String toString() { - return getStatusIcon() + " " + taskDescription; + return getStatusIcon() + " " + description; } } diff --git a/src/main/java/TaskWithDateTime.java b/src/main/java/TaskWithDateTime.java index 2955b6ef49..3e898da83a 100644 --- a/src/main/java/TaskWithDateTime.java +++ b/src/main/java/TaskWithDateTime.java @@ -1,20 +1,23 @@ public abstract class TaskWithDateTime extends Task { - protected String dateTime; + private String dateTime; - public TaskWithDateTime(TaskType taskType, String taskDescription, String dateTime) { - super(taskType, taskDescription); + public TaskWithDateTime(TaskType type, String description, String dateTime) { + this(type, description, dateTime, false); + } + + public TaskWithDateTime(TaskType type, String description, String dateTime, boolean isDone) { + super(type, description, isDone); this.dateTime = dateTime; } - protected String getDateTime() { - String[] dateTimeParts = dateTime.split(" ", 2); - return dateTimeParts[1]; + public String getDateTime() { + return dateTime; } public abstract String dateTimeDetails(); @Override public String toString() { - return super.toString() + dateTimeDetails(); + return super.toString() + " " + dateTimeDetails(); } } diff --git a/src/main/java/ToDo.java b/src/main/java/ToDo.java index e922f4d97e..0d7b99c550 100644 --- a/src/main/java/ToDo.java +++ b/src/main/java/ToDo.java @@ -1,10 +1,14 @@ public class ToDo extends Task { - public ToDo(TaskType taskType, String taskDescription) { - super(taskType, taskDescription); + public ToDo(TaskType type, String description) { + super(type, description); + } + + public ToDo(TaskType type, String description, boolean isDone) { + super(type, description, isDone); } @Override public String toString() { - return "[" + TaskType.TODO.getAbbr() + "]" + super.toString(); + return "[" + TaskType.TODO.getAbbr() + "] " + super.toString(); } } From 0a46d995213a8bfa7f2facfb31a73a804347628c Mon Sep 17 00:00:00 2001 From: dannytayjy Date: Thu, 26 Aug 2021 11:07:50 +0800 Subject: [PATCH 10/16] Implement Level-8: Teach Duke to understand dates and times --- src/main/java/Deadline.java | 12 ++- src/main/java/Duke.java | 12 ++- src/main/java/Event.java | 12 ++- src/main/java/Task.java | 38 ++++++-- src/main/java/TaskWithDateTime.java | 129 ++++++++++++++++++++++++++-- 5 files changed, 176 insertions(+), 27 deletions(-) diff --git a/src/main/java/Deadline.java b/src/main/java/Deadline.java index c212256a4b..eec759e9e8 100644 --- a/src/main/java/Deadline.java +++ b/src/main/java/Deadline.java @@ -1,15 +1,19 @@ public class Deadline extends TaskWithDateTime { - public Deadline(TaskType taskType, String taskDescription, String dateTime) { - super(taskType, taskDescription, dateTime); + public Deadline(TaskType type, String description, String dateTimeInput) { + super(type, description, dateTimeInput); + } + + public Deadline(TaskType type, String description, String dateTimeInput, boolean isDone) { + super(type, description, dateTimeInput, isDone); } @Override public String dateTimeDetails() { - return "(by: " + super.getDateTime() +")"; + return "(by: " + super.getDateTimeOutput() + ")"; } @Override public String toString() { - return "[" + TaskType.DEADLINE.getAbbr() + "]" + super.toString(); + return "[" + TaskType.DEADLINE.getAbbr() + "] " + super.toString(); } } diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 310e268c2f..8de1ac374a 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -151,8 +151,12 @@ static void addDeadlineTask(String[] command, List tasksList) throws DukeE String[] deadlineTaskDetails = command[1].split("/", 2); if (deadlineTaskDetails.length == 2) { + String description = deadlineTaskDetails[0].trim(); + String beforeDateTime = deadlineTaskDetails[1].trim(); + String[] beforeDateTimeParts = beforeDateTime.split("\\s+", 2); + Task newDeadlineTask = new Deadline(TaskType.DEADLINE, - deadlineTaskDetails[0], deadlineTaskDetails[1]); + description, beforeDateTimeParts[1]); tasksList.add(newDeadlineTask); String response = addTaskMessage() + "\n" + @@ -171,8 +175,12 @@ static void addEventTask(String[] command, List tasksList) throws DukeExce String[] eventTaskDetails = command[1].split("/", 2); if (eventTaskDetails.length == 2) { + String description = eventTaskDetails[0].trim(); + String startEndDateTime = eventTaskDetails[1].trim(); + String[] startEndDateTimeParts = startEndDateTime.split("\\s+", 2); + Task newEventTask = new Event(TaskType.EVENT, - eventTaskDetails[0], eventTaskDetails[1]); + description, startEndDateTimeParts[1]); tasksList.add(newEventTask); String response = addTaskMessage() + "\n" + diff --git a/src/main/java/Event.java b/src/main/java/Event.java index 747a751b2c..28361542db 100644 --- a/src/main/java/Event.java +++ b/src/main/java/Event.java @@ -1,15 +1,19 @@ public class Event extends TaskWithDateTime { - public Event(TaskType taskType, String taskDescription, String dateTime) { - super(taskType, taskDescription, dateTime); + public Event(TaskType type, String description, String dateTimeInput) { + super(type, description, dateTimeInput); + } + + public Event(TaskType type, String description, String dateTimeInput, boolean isDone) { + super(type, description, dateTimeInput, isDone); } @Override public String dateTimeDetails() { - return "(at: " + super.getDateTime() +")"; + return "(at: " + super.getDateTimeOutput() +")"; } @Override public String toString() { - return "[" + TaskType.EVENT.getAbbr() + "]" + super.toString(); + return "[" + TaskType.EVENT.getAbbr() + "] " + super.toString(); } } diff --git a/src/main/java/Task.java b/src/main/java/Task.java index c24dae1acb..d53b67e603 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -1,24 +1,44 @@ public abstract class Task { - protected TaskType taskType; - protected String taskDescription; - protected boolean isDone; + private final TaskType type; + private final String description; + private boolean isDone; - public Task(TaskType taskType, String taskDescription) { - this.taskType = taskType; - this.taskDescription = taskDescription; - this.isDone = false; + public Task(TaskType type, String description) { + this(type, description, false); + } + + public Task(TaskType type, String description, boolean isDone) { + this.type = type; + this.description = description; + this.isDone = isDone; + } + + public TaskType getType() { + return type; + } + + public String getDescription() { + return description; + } + + public boolean isDone() { + return isDone; } public String getStatusIcon() { - return (isDone ? "[X]" : "[ ]"); // mark done task with X + return (isDone ? "[✔]" : "[ ]"); // mark done task with ✔ } public void setDone() { this.isDone = true; } + public boolean isOnDate(String specificDateStr) { + return false; + } + @Override public String toString() { - return getStatusIcon() + " " + taskDescription; + return getStatusIcon() + " " + description; } } diff --git a/src/main/java/TaskWithDateTime.java b/src/main/java/TaskWithDateTime.java index 2955b6ef49..3bbf0a8e29 100644 --- a/src/main/java/TaskWithDateTime.java +++ b/src/main/java/TaskWithDateTime.java @@ -1,20 +1,133 @@ +import java.time.LocalDate; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; + public abstract class TaskWithDateTime extends Task { - protected String dateTime; + private final String dateTimeInput; + private final String dateInput; + private final String timeInput; + private LocalDate date; + private LocalTime time; + private String dateTimeOutput; // DateTime (of the task) to be printed + + public TaskWithDateTime(TaskType type, String description, String dateTimeInput) { + this(type, description, dateTimeInput, false); + } + + public TaskWithDateTime(TaskType type, String description, String dateTimeInput, boolean isDone) { + super(type, description, isDone); + this.dateTimeInput = dateTimeInput; + + boolean isTimeInputProper = true; + + String[] dateTimeInputParts = dateTimeInput.split("\\s+", 2); + + if (dateTimeInputParts.length == 2) { + dateInput = dateTimeInputParts[0]; + timeInput = dateTimeInputParts[1]; + } else { + dateInput = dateTimeInputParts[0]; + timeInput = ""; + } + + try { + date = LocalDate.parse(dateInput); + } catch (Exception e) { + date = null; + } + + if (!timeInput.equals("")) { + try { + int timeInputInInt = Integer.parseInt(timeInput); + + if ((timeInputInInt < 0 || timeInputInInt > 2359)) { + isTimeInputProper = false; + time = null; + } else { + if (timeInput.length() != 4) { + isTimeInputProper = false; + time = null; + } else { + int hour = timeInputInInt / 100; + int min = timeInputInInt - (hour * 100); + + String timeInputInTimeFormat = ""; - public TaskWithDateTime(TaskType taskType, String taskDescription, String dateTime) { - super(taskType, taskDescription); - this.dateTime = dateTime; + if (hour < 10) { + timeInputInTimeFormat += "0" + hour; + } else { + timeInputInTimeFormat += hour; + } + + if (min < 10) { + timeInputInTimeFormat += ":" + "0" + min; + } else { + timeInputInTimeFormat += ":" + min; + } + + DateTimeFormatter timeFormatter = DateTimeFormatter.ISO_LOCAL_TIME; + time = LocalTime.parse(timeInputInTimeFormat, timeFormatter); + } + } + } catch (Exception e) { + time = null; + } + } else { + time = null; + } + + dateTimeOutput = ""; + + if (date == null && time == null) { + dateTimeOutput = dateTimeInput; + } else { + if (date != null) { + dateTimeOutput += date.format(DateTimeFormatter.ofPattern("MMM d yyyy")); + } else { + dateTimeOutput += dateInput; + } + + if (time != null) { + dateTimeOutput += ", " + time.format(DateTimeFormatter.ofPattern("hh:mm a")); + } else { + if (!timeInput.equals("")) { + if (isTimeInputProper) { + dateTimeOutput += ", " + timeInput; + } else { + dateTimeOutput += ", " + timeInput + " [Note: Invalid time format]"; + } + } + } + } } - protected String getDateTime() { - String[] dateTimeParts = dateTime.split(" ", 2); - return dateTimeParts[1]; + public String getDateTimeInput() { + return dateTimeInput; + } + + public String getDateTimeOutput() { + return dateTimeOutput; } public abstract String dateTimeDetails(); + @Override + public boolean isOnDate(String specificDateStr) { + try { + LocalDate dateToSearch = LocalDate.parse(specificDateStr); + + if (this.date != null) { + return this.date.equals(dateToSearch); + } else { + return this.dateInput.equals(specificDateStr); + } + } catch (Exception e) { + return this.dateInput.equals(specificDateStr); + } + } + @Override public String toString() { - return super.toString() + dateTimeDetails(); + return super.toString() + " " + dateTimeDetails(); } } From 0f100beb6b1b14d1ff7b306af129438da1625364 Mon Sep 17 00:00:00 2001 From: dannytayjy Date: Sun, 29 Aug 2021 11:32:50 +0800 Subject: [PATCH 11/16] Implement A-MoreOOP: Make the code more OOP --- data/tasks.txt | 1 + src/main/java/Duke.java | 239 +++++++++------------------- src/main/java/Parser.java | 15 ++ src/main/java/Print.java | 73 --------- src/main/java/ResponseMessage.java | 96 ----------- src/main/java/Storage.java | 81 +++++++++- src/main/java/Task.java | 6 +- src/main/java/TaskList.java | 33 ++++ src/main/java/TaskWithDateTime.java | 12 +- src/main/java/Ui.java | 177 ++++++++++++++++++++ 10 files changed, 389 insertions(+), 344 deletions(-) create mode 100644 data/tasks.txt create mode 100644 src/main/java/Parser.java delete mode 100644 src/main/java/Print.java delete mode 100644 src/main/java/ResponseMessage.java create mode 100644 src/main/java/TaskList.java create mode 100644 src/main/java/Ui.java diff --git a/data/tasks.txt b/data/tasks.txt new file mode 100644 index 0000000000..0a052014f7 --- /dev/null +++ b/data/tasks.txt @@ -0,0 +1 @@ +D | 0 | test | 2021-08-31 diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index a197a754dc..0097d3adf0 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,191 +1,103 @@ -import java.io.*; -import java.util.ArrayList; -import java.util.List; -import java.util.Scanner; +import java.io.File; +import java.io.IOException; public class Duke { + private Parser parser; + private Storage storage; + private TaskList tasks; + private Ui ui; + + public Duke(String pathName, String fileName) { + parser = new Parser(); + storage = new Storage(pathName, fileName); + tasks = new TaskList(); + ui = new Ui(); + } + public static void main(String[] args) { - String pathName = "data"; - String fileName = "tasks.txt"; + new Duke("data", "tasks.txt").run(); + } + public void run() { try { - File dataDirectory = Storage.initialiseDirectory(pathName); - File dataFile = Storage.initialiseFile(dataDirectory, fileName); - - List tasksList = new ArrayList(); - - Print.printProgramStartMessage(); + File dataDirectory = storage.initialiseDirectory(); + File dataFile = storage.initialiseFile(dataDirectory); - Scanner sc = new Scanner(System.in); - String commandLine = ""; + ui.greet(); + storage.loadTasksFromFile(dataFile, tasks); - readTasksFromFile(dataFile, tasksList); + String commandLine; do { - System.out.println("ENTER COMMAND:"); - System.out.print("\t"); - commandLine = sc.nextLine().trim(); - String[] commandLineParts = commandLine.split("\\s+", 2); - - Command command; - - if (commandLineParts.length == 2) { - command = new Command(commandLineParts[0], commandLineParts[1]); - } else { - command = new Command(commandLineParts[0], ""); - } + commandLine = ui.readCommand(); + Command command = parser.parseInput(commandLine); try { switch (command.getType()) { case "bye": - Print.printResponse(ResponseMessage.exitMessage()); + ui.exit(); break; case "list": - displayTasksList(tasksList); + displayTasksList(tasks); break; case "done": - markDone(command, tasksList); - saveTasksToFile(dataFile, tasksList); + markDone(command, tasks); + storage.saveTasksToFile(dataFile, tasks); break; case "delete": - deleteTask(command, tasksList); - saveTasksToFile(dataFile, tasksList); + deleteTask(command, tasks); + storage.saveTasksToFile(dataFile, tasks); break; case "todo": - addToDoTask(command, tasksList); - saveTasksToFile(dataFile, tasksList); + addToDoTask(command, tasks); + storage.saveTasksToFile(dataFile, tasks); break; case "deadline": - addDeadlineTask(command, tasksList); - saveTasksToFile(dataFile, tasksList); + addDeadlineTask(command, tasks); + storage.saveTasksToFile(dataFile, tasks); break; case "event": - addEventTask(command, tasksList); - saveTasksToFile(dataFile, tasksList); + addEventTask(command, tasks); + storage.saveTasksToFile(dataFile, tasks); break; case "print": - printTasksOnDate(command, tasksList); + printTasksOnDate(command, tasks); break; default: throw new DukeException("INVALID COMMAND. Please try again!"); } } catch (DukeException e) { - Print.printErrorMessage(e.getMessage()); + ui.displayError(e.getMessage()); } } while (!commandLine.equals("bye")); - } catch (DukeException | IOException e) { - Print.printErrorMessage(e.getMessage()); - } - } - - static void readTasksFromFile(File dataFile, List tasksList) { - try { - FileReader fr = new FileReader(dataFile); - BufferedReader br = new BufferedReader(fr); - String line; - - while ((line = br.readLine()) != null) { - String[] task = line.trim().split("\\|"); - String type = task[0].trim(); - boolean isdone = Boolean.parseBoolean(task[1].trim()); - String description = task[2].trim(); - String dateTime = ""; - - switch (type) { - case "T": - Task todoTask = readToDoTask(isdone, description); - tasksList.add(todoTask); - break; - case "D": - dateTime = task[3].trim(); - Task deadlineTask = readDeadlineTask(isdone, description, dateTime); - tasksList.add(deadlineTask); - break; - case "E": - dateTime = task[3].trim(); - Task eventTask = readEventTask(isdone, description, dateTime); - tasksList.add(eventTask); - break; - } - } - fr.close(); - } catch (IOException e) { - Print.printErrorMessage(e.getMessage()); - } - } - - static Task readToDoTask(boolean isDone, String description) { - return new ToDo(TaskType.TODO, description, isDone); - } - - static Task readDeadlineTask(boolean isDone, String description, String dateTime) { - return new Deadline(TaskType.DEADLINE, description, dateTime, isDone); - } - - static Task readEventTask(boolean isDone, String description, String dateTime) { - return new Event(TaskType.EVENT, description, dateTime, isDone); - } - - static void saveTasksToFile(File dataFile, List taskList) { - try { - FileWriter fileWriter = new FileWriter(dataFile,false); - String taskDetails = ""; - - for (int i = 0; i < taskList.size(); i++) { - Task task = taskList.get(i); - - TaskType type = task.getType(); - boolean isDone = task.isDone(); - String description = task.getDescription(); - String dateTime; - - if (type == TaskType.TODO) { - dateTime = ""; - } else { - dateTime = ((TaskWithDateTime) task).getDateTimeInput(); - } - - taskDetails = taskDetailsSaveFormat(type, isDone, description, dateTime); - fileWriter.write(taskDetails + System.lineSeparator()); - } - - fileWriter.close(); - } catch (IOException e) { - Print.printErrorMessage(e.getMessage()); - } - } - - static String taskDetailsSaveFormat(TaskType type, boolean isDone, String description, String dateTime) { - if (dateTime.equals("")) { - return type.getAbbr() + " | " + (isDone ? "1" : "0") + " | " + description; - } else { - return type.getAbbr() + " | " + (isDone ? "1" : "0") + " | " + description + " | " + dateTime; + } catch (DukeException | IOException e) { + ui.displayError(e.getMessage()); } } - static void displayTasksList(List tasksList) throws DukeException { - if (tasksList.size() != 0) { - String response = ResponseMessage.tasksInYourListMessage(tasksList); - Print.printResponse(response); + public void displayTasksList(TaskList tasks) throws DukeException { + if (tasks.size() != 0) { + String response = ui.tasksInYourList(tasks); + ui.displayResponse(response); } else { throw new DukeException("There are no tasks in your list!"); } } - static void markDone(Command command, List tasksList) throws DukeException { + public void markDone(Command command, TaskList tasks) throws DukeException { String commandDetails = command.getDetails(); if (commandDetails.trim().length() > 0) { try { int taskNum = Integer.parseInt(commandDetails); - if (taskNum >= 1 && taskNum <= tasksList.size()) { - tasksList.get(taskNum - 1).setDone(); - Task taskDone = tasksList.get(taskNum - 1); + if (taskNum >= 1 && taskNum <= tasks.size()) { + tasks.get(taskNum - 1).setDone(); + Task taskDone = tasks.get(taskNum - 1); - String response = ResponseMessage.taskDoneMessage(taskDone); - Print.printResponse(response); + String response = ui.taskDoneMessage(taskDone); + ui.displayResponse(response); } else { throw new DukeException("Please enter a valid task number to be marked as done!"); } @@ -197,20 +109,19 @@ static void markDone(Command command, List tasksList) throws DukeException } } - static void deleteTask(Command command, List tasksList) throws DukeException { + public void deleteTask(Command command, TaskList tasks) throws DukeException { String commandDetails = command.getDetails(); if (commandDetails.trim().length() > 0) { try { int taskNum = Integer.parseInt(commandDetails); - if (taskNum >= 1 && taskNum <= tasksList.size()) { - Task taskToDelete = tasksList.get(taskNum - 1); - tasksList.remove(taskToDelete); + if (taskNum >= 1 && taskNum <= tasks.size()) { + Task taskDeleted = tasks.remove(taskNum - 1); - String response = ResponseMessage.taskDeletedMessage(taskToDelete) - + System.lineSeparator() + ResponseMessage.numOfTasksInList(tasksList); - Print.printResponse(response); + String response = ui.taskDeletedMessage(taskDeleted) + + System.lineSeparator() + ui.numOfTasksInList(tasks); + ui.displayResponse(response); } else { throw new DukeException("Please enter a valid task number to be deleted!"); } @@ -222,22 +133,22 @@ static void deleteTask(Command command, List tasksList) throws DukeExcepti } } - static void addToDoTask(Command command, List tasksList) throws DukeException { + public void addToDoTask(Command command, TaskList tasks) throws DukeException { String commandDetails = command.getDetails(); if (commandDetails.trim().length() > 0) { Task newToDoTask = new ToDo(TaskType.TODO, commandDetails); - tasksList.add(newToDoTask); + tasks.add(newToDoTask); - String response = ResponseMessage.taskAddedMessage(newToDoTask) - + System.lineSeparator() + ResponseMessage.numOfTasksInList(tasksList); - Print.printResponse(response); + String response = ui.taskAddedMessage(newToDoTask) + + System.lineSeparator() + ui.numOfTasksInList(tasks); + ui.displayResponse(response); } else { throw new DukeException("The description of a todo cannot be empty!"); } } - static void addDeadlineTask(Command command, List tasksList) throws DukeException { + public void addDeadlineTask(Command command, TaskList tasks) throws DukeException { String commandDetails = command.getDetails(); if (commandDetails.trim().length() > 0) { @@ -253,11 +164,11 @@ static void addDeadlineTask(Command command, List tasksList) throws DukeEx if (beforeDateTimeParts.length == 2) { Task newDeadlineTask = new Deadline(TaskType.DEADLINE, description, beforeDateTimeParts[1]); - tasksList.add(newDeadlineTask); + tasks.add(newDeadlineTask); - String response = ResponseMessage.taskAddedMessage(newDeadlineTask) - + System.lineSeparator() + ResponseMessage.numOfTasksInList(tasksList); - Print.printResponse(response); + String response = ui.taskAddedMessage(newDeadlineTask) + + System.lineSeparator() + ui.numOfTasksInList(tasks); + ui.displayResponse(response); } else { throw new DukeException("INCOMPLETE COMMAND" + System.lineSeparator() + "\t" @@ -312,7 +223,7 @@ static void addDeadlineTask(Command command, List tasksList) throws DukeEx } } - static void addEventTask(Command command, List tasksList) throws DukeException { + public void addEventTask(Command command, TaskList tasks) throws DukeException { String commandDetails = command.getDetails(); if (commandDetails.trim().length() > 0) { @@ -328,11 +239,11 @@ static void addEventTask(Command command, List tasksList) throws DukeExcep if (startEndDateTimeParts.length == 2) { Task newEventTask = new Event(TaskType.EVENT, description, startEndDateTimeParts[1]); - tasksList.add(newEventTask); + tasks.add(newEventTask); - String response = ResponseMessage.taskAddedMessage(newEventTask) - + System.lineSeparator() + ResponseMessage.numOfTasksInList(tasksList); - Print.printResponse(response); + String response = ui.taskAddedMessage(newEventTask) + + System.lineSeparator() + ui.numOfTasksInList(tasks); + ui.displayResponse(response); } else { throw new DukeException("INCOMPLETE COMMAND" + System.lineSeparator() + "\t" @@ -387,8 +298,8 @@ static void addEventTask(Command command, List tasksList) throws DukeExcep } } - static void printTasksOnDate(Command command, List tasksList) throws DukeException { - if (tasksList.size() != 0) { + public void printTasksOnDate(Command command, TaskList tasks) throws DukeException { + if (tasks.size() != 0) { String commandDetails = command.getDetails(); if (commandDetails.trim().length() > 0) { @@ -396,8 +307,8 @@ static void printTasksOnDate(Command command, List tasksList) throws DukeE String[] specificDateParts = commandDetails.split("\\s+", 2); if (specificDateParts.length == 2) { - String response = ResponseMessage.tasksOnDateMessage(specificDateParts[1], tasksList); - Print.printResponse(response); + String response = ui.tasksOnDate(specificDateParts[1], tasks); + ui.displayResponse(response); } else { throw new DukeException("INCOMPLETE COMMAND" + System.lineSeparator() + "\t" diff --git a/src/main/java/Parser.java b/src/main/java/Parser.java new file mode 100644 index 0000000000..2d193eb635 --- /dev/null +++ b/src/main/java/Parser.java @@ -0,0 +1,15 @@ +public class Parser { + public Command parseInput(String commandLine) { + String[] commandLineParts = commandLine.split("\\s+", 2); + + Command command; + + if (commandLineParts.length == 2) { + command = new Command(commandLineParts[0], commandLineParts[1]); + } else { + command = new Command(commandLineParts[0], ""); + } + + return command; + } +} diff --git a/src/main/java/Print.java b/src/main/java/Print.java deleted file mode 100644 index 1f229253ab..0000000000 --- a/src/main/java/Print.java +++ /dev/null @@ -1,73 +0,0 @@ -public class Print { - static void printProgramStartMessage() { - printHorizontalLine(); - printGreetMessage(); - printMenuOptions(); - printHorizontalLine(); - } - - static void printResponse(String message) { - printHorizontalLine(); - System.out.println(message); - printHorizontalLine(); - } - - static void printErrorMessage(String message) { - printHorizontalLine(); - System.out.println("ERROR MESSAGE:"); - System.out.println("\t" + "☹ " + message); - printHorizontalLine(); - } - - private static void printHorizontalLine() { - String horizontalLine = "____________________________________________________________"; - System.out.println(horizontalLine); - } - - private static void printGreetMessage() { - String message = "\t" + "Hello! I'm Duke, your Personal Assistant Chatbot." - + System.lineSeparator() - + "\t" + "What can I do for you?" - + System.lineSeparator(); - System.out.println(message); - } - - private static void printMenuOptions() { - String format = "%-25s%s%n"; - - String menuOption1 = "\t" + "list:"; - String menuOption1Info = "List the tasks in your list"; - - String menuOption2 = "\t" + "todo ABC:"; - String menuOption2Info = "Add a todo [T] task, ABC, into your list"; - - String menuOption3 = "\t" + "deadline ABC /by XYZ:"; - String menuOption3Info = "Add a deadline [D] task, ABC, into your list " - + "and specify the date/time, XYZ, it needs to be completed by"; - - String menuOption4 = "\t" + "event ABC /at XYZ:"; - String menuOption4Info = "Add an event [E] task, ABC, into your list " - + "and specify the start and end date/time, XYZ"; - - String menuOption5 = "\t" + "done N:"; - String menuOption5Info = "Mark a task number, N, as done"; - - String menuOption6 = "\t" + "delete N:"; - String menuOption6Info = "Delete a task number, N, from your list"; - - String menuOption7 = "\t" + "print /on yyyy-mm-dd:"; - String menuOption7Info = "Print deadlines/events on a specific date"; - - String menuOption8 = "\t" + "bye:"; - String menuOption8Info = "Exit the chatbot"; - - System.out.printf(format, menuOption1, menuOption1Info); - System.out.printf(format, menuOption2, menuOption2Info); - System.out.printf(format, menuOption3, menuOption3Info); - System.out.printf(format, menuOption4, menuOption4Info); - System.out.printf(format, menuOption5, menuOption5Info); - System.out.printf(format, menuOption6, menuOption6Info); - System.out.printf(format, menuOption7, menuOption7Info); - System.out.printf(format, menuOption8, menuOption8Info); - } -} diff --git a/src/main/java/ResponseMessage.java b/src/main/java/ResponseMessage.java deleted file mode 100644 index 1680471bd1..0000000000 --- a/src/main/java/ResponseMessage.java +++ /dev/null @@ -1,96 +0,0 @@ -import java.time.LocalDate; -import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.List; - -public class ResponseMessage { - static String exitMessage() { - return "\t" + "Bye. Hope to see you again soon!"; - } - - static String taskAddedMessage(Task task) { - return "\t" + "Got it. I've added this task:" - + System.lineSeparator() + "\t\t" + task; - } - - static String taskDeletedMessage(Task task) { - return "\t" + "Noted. I've removed this task:" - + System.lineSeparator() + "\t\t" + task; - } - - static String taskDoneMessage(Task task) { - return "\t" + "Nice! I've marked this task as done:" - + System.lineSeparator() + "\t\t" + task; - } - - static String numOfTasksInList(List tasksList) { - return "\t" + "Now you have " + tasksList.size() - + (tasksList.size() > 1 ? " tasks" : " task") - + " in the list."; - } - - static String tasksInYourListMessage(List tasksList) { - String response = "\t" + "Here are the tasks in your list:" - + System.lineSeparator() - + "\t" + "[Legend: T = todo, D = deadline, E = event]" - + System.lineSeparator() - + System.lineSeparator(); - - for (int i = 0; i < tasksList.size(); i++) { - if (i != 0) { - response += System.lineSeparator(); - } - - response += "\t\t" + (i + 1) + "." + "\t" + tasksList.get(i).toString(); - } - - return response; - } - - static String tasksOnDateMessage(String specificDate, List tasksList) { - List tasksToPrintList = new ArrayList(); - - for (int i = 0; i < tasksList.size(); i++) { - if (tasksList.get(i).isOnDate(specificDate)) { - tasksToPrintList.add(tasksList.get(i)); - } - } - - String response = ""; - - if (tasksToPrintList.size() != 0) { - response = "\t" + "Here are the tasks on this date (" - + displaySpecificDate(specificDate) + "):" - + System.lineSeparator() - + "\t" + "[Legend: T = todo, D = deadline, E = event]" - + System.lineSeparator() - + System.lineSeparator(); - - for (int i = 0; i < tasksToPrintList.size(); i++) { - if (i != 0) { - response += System.lineSeparator(); - } - - response += "\t\t" + "-" + "\t" + tasksToPrintList.get(i).toString(); - } - } else { - response = "\t" + "There are no tasks on this date."; - } - - return response; - } - - static String displaySpecificDate(String specificDate) { - LocalDate date = null; - String displayDate = ""; - - try { - date = LocalDate.parse(specificDate); - displayDate = date.format(DateTimeFormatter.ofPattern("MMM d yyyy")); - } catch (Exception e) { - displayDate = specificDate; - } - - return displayDate; - } -} diff --git a/src/main/java/Storage.java b/src/main/java/Storage.java index 8ef081881f..b50dc3fae0 100644 --- a/src/main/java/Storage.java +++ b/src/main/java/Storage.java @@ -1,8 +1,15 @@ -import java.io.File; -import java.io.IOException; +import java.io.*; public class Storage { - static File initialiseDirectory(String pathName) throws DukeException { + private final String pathName; + private final String fileName; + + public Storage(String pathName, String fileName) { + this.pathName = pathName; + this.fileName = fileName; + } + + public File initialiseDirectory() throws DukeException { File directory = new File(pathName); boolean hasDirectory = directory.exists(); @@ -17,7 +24,7 @@ static File initialiseDirectory(String pathName) throws DukeException { } } - static File initialiseFile(File directory, String fileName) throws IOException { + public File initialiseFile(File directory) throws IOException { File file = new File(directory + "/" + fileName); boolean hasFile = file.exists(); @@ -31,4 +38,70 @@ static File initialiseFile(File directory, String fileName) throws IOException { throw new IOException("\t" + "Unable to initialise file"); } } + + public void loadTasksFromFile(File dataFile, TaskList tasks) throws IOException { + FileReader fileReader = new FileReader(dataFile); + BufferedReader bufferedReader = new BufferedReader(fileReader); + String line; + + while ((line = bufferedReader.readLine()) != null) { + String[] task = line.trim().split("\\|"); + String type = task[0].trim(); + boolean isDone = Boolean.parseBoolean(task[1].trim()); + String description = task[2].trim(); + String dateTime; + + switch (type) { + case "T": + Task todoTask = new ToDo(TaskType.TODO, description, isDone); + tasks.add(todoTask); + break; + case "D": + dateTime = task[3].trim(); + Task deadlineTask = new Deadline(TaskType.DEADLINE, description, dateTime, isDone); + tasks.add(deadlineTask); + break; + case "E": + dateTime = task[3].trim(); + Task eventTask = new Event(TaskType.EVENT, description, dateTime, isDone); + tasks.add(eventTask); + break; + } + } + + bufferedReader.close(); + } + + public void saveTasksToFile(File dataFile, TaskList tasks) throws IOException { + FileWriter fileWriter = new FileWriter(dataFile,false); + BufferedWriter bufferedWriter = new BufferedWriter(fileWriter); + + for (int i = 0; i < tasks.size(); i++) { + Task task = tasks.get(i); + + TaskType type = task.getType(); + boolean isDone = task.isDone(); + String description = task.getDescription(); + String dateTime; + + if (type == TaskType.TODO) { + dateTime = ""; + } else { + dateTime = ((TaskWithDateTime) task).getDateTimeInput(); + } + + String taskDetails = taskDetailsSaveFormat(type, isDone, description, dateTime); + bufferedWriter.write(taskDetails + System.lineSeparator()); + } + + bufferedWriter.close(); + } + + private String taskDetailsSaveFormat(TaskType type, boolean isDone, String description, String dateTime) { + if (dateTime.equals("")) { + return type.getAbbr() + " | " + (isDone ? "1" : "0") + " | " + description; + } else { + return type.getAbbr() + " | " + (isDone ? "1" : "0") + " | " + description + " | " + dateTime; + } + } } diff --git a/src/main/java/Task.java b/src/main/java/Task.java index ed6d72b930..82f4a41ae0 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -1,8 +1,6 @@ -import java.time.LocalDate; - public abstract class Task { - private final TaskType type; - private final String description; + private TaskType type; + private String description; private boolean isDone; public Task(TaskType type, String description) { diff --git a/src/main/java/TaskList.java b/src/main/java/TaskList.java new file mode 100644 index 0000000000..28837a863e --- /dev/null +++ b/src/main/java/TaskList.java @@ -0,0 +1,33 @@ +import java.util.ArrayList; +import java.util.List; + +public class TaskList { + private List tasks; + + public TaskList() { + tasks = new ArrayList(); + } + + public int size() { + return tasks.size(); + } + + public Task get(int index) { + return tasks.get(index); + } + + public void add(Task task) { + tasks.add(task); + } + + public Task remove(int index) { + Task task = tasks.get(index); + tasks.remove(task); + return task; + } + + public Task remove(Task task) { + tasks.remove(task); + return task; + } +} diff --git a/src/main/java/TaskWithDateTime.java b/src/main/java/TaskWithDateTime.java index 3bbf0a8e29..4897126942 100644 --- a/src/main/java/TaskWithDateTime.java +++ b/src/main/java/TaskWithDateTime.java @@ -3,9 +3,9 @@ import java.time.format.DateTimeFormatter; public abstract class TaskWithDateTime extends Task { - private final String dateTimeInput; - private final String dateInput; - private final String timeInput; + private String dateTimeInput; + private String dateInput; + private String timeInput; private LocalDate date; private LocalTime time; private String dateTimeOutput; // DateTime (of the task) to be printed @@ -17,7 +17,10 @@ public TaskWithDateTime(TaskType type, String description, String dateTimeInput) public TaskWithDateTime(TaskType type, String description, String dateTimeInput, boolean isDone) { super(type, description, isDone); this.dateTimeInput = dateTimeInput; + processDateTimeInput(); + } + private void processDateTimeInput() { boolean isTimeInputProper = true; String[] dateTimeInputParts = dateTimeInput.split("\\s+", 2); @@ -30,12 +33,14 @@ public TaskWithDateTime(TaskType type, String description, String dateTimeInput, timeInput = ""; } + // Process dateInput try { date = LocalDate.parse(dateInput); } catch (Exception e) { date = null; } + // Process timeInput if (!timeInput.equals("")) { try { int timeInputInInt = Integer.parseInt(timeInput); @@ -76,6 +81,7 @@ public TaskWithDateTime(TaskType type, String description, String dateTimeInput, time = null; } + // Generate dateTimeOutput dateTimeOutput = ""; if (date == null && time == null) { diff --git a/src/main/java/Ui.java b/src/main/java/Ui.java new file mode 100644 index 0000000000..c339906f8e --- /dev/null +++ b/src/main/java/Ui.java @@ -0,0 +1,177 @@ +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.Scanner; + +public class Ui { + public String readCommand() { + Scanner sc = new Scanner(System.in); + System.out.println("ENTER COMMAND:"); + System.out.print("\t"); + return sc.nextLine().trim(); + } + + public void greet() { + displayLine(); + displayWelcomeMessage(); + displayMenuOptions(); + displayLine(); + } + + public void exit() { + String message = "\t" + "Bye. Hope to see you again soon!"; + displayResponse(message); + } + + public void displayResponse(String message) { + displayLine(); + System.out.println(message); + displayLine(); + } + + public void displayError(String message) { + displayLine(); + System.out.println("ERROR MESSAGE:"); + System.out.println("\t" + "☹ " + message); + displayLine(); + } + + private void displayLine() { + String horizontalLine = "____________________________________________________________"; + System.out.println(horizontalLine); + } + + private void displayWelcomeMessage() { + String message = "\t" + "Hello! I'm Duke, your Personal Assistant ChatBot." + + System.lineSeparator() + + "\t" + "What can I do for you?" + + System.lineSeparator(); + System.out.println(message); + } + + private void displayMenuOptions() { + String format = "%-25s%s%n"; + + String menuOption1 = "\t" + "list:"; + String menuOption1Info = "List the tasks in your list"; + + String menuOption2 = "\t" + "todo ABC:"; + String menuOption2Info = "Add a todo [T] task, ABC, into your list"; + + String menuOption3 = "\t" + "deadline ABC /by XYZ:"; + String menuOption3Info = "Add a deadline [D] task, ABC, into your list " + + "and specify the date/time, XYZ, it needs to be completed by"; + + String menuOption4 = "\t" + "event ABC /at XYZ:"; + String menuOption4Info = "Add an event [E] task, ABC, into your list " + + "and specify the start and end date/time, XYZ"; + + String menuOption5 = "\t" + "done N:"; + String menuOption5Info = "Mark a task number, N, as done"; + + String menuOption6 = "\t" + "delete N:"; + String menuOption6Info = "Delete a task number, N, from your list"; + + String menuOption7 = "\t" + "print /on yyyy-mm-dd:"; + String menuOption7Info = "Print deadlines/events on a specific date"; + + String menuOption8 = "\t" + "bye:"; + String menuOption8Info = "Exit the ChatBot"; + + System.out.printf(format, menuOption1, menuOption1Info); + System.out.printf(format, menuOption2, menuOption2Info); + System.out.printf(format, menuOption3, menuOption3Info); + System.out.printf(format, menuOption4, menuOption4Info); + System.out.printf(format, menuOption5, menuOption5Info); + System.out.printf(format, menuOption6, menuOption6Info); + System.out.printf(format, menuOption7, menuOption7Info); + System.out.printf(format, menuOption8, menuOption8Info); + } + + public String taskAddedMessage(Task task) { + return "\t" + "Got it. I've added this task:" + + System.lineSeparator() + "\t\t" + task; + } + + public String taskDeletedMessage(Task task) { + return "\t" + "Noted. I've removed this task:" + + System.lineSeparator() + "\t\t" + task; + } + + public String taskDoneMessage(Task task) { + return "\t" + "Nice! I've marked this task as done:" + + System.lineSeparator() + "\t\t" + task; + } + + public String numOfTasksInList(TaskList tasks) { + return "\t" + "Now you have " + tasks.size() + + (tasks.size() > 1 ? " tasks" : " task") + + " in the list."; + } + + public String tasksInYourList(TaskList tasks) { + StringBuilder response = new StringBuilder("\t" + "Here are the tasks in your list:" + + System.lineSeparator() + + "\t" + "[Legend: T = todo, D = deadline, E = event]" + + System.lineSeparator() + + System.lineSeparator()); + + for (int i = 0; i < tasks.size(); i++) { + if (i != 0) { + response.append(System.lineSeparator()); + } + + response.append("\t\t").append(i + 1).append(".") + .append("\t").append(tasks.get(i).toString()); + } + + return response.toString(); + } + + public String tasksOnDate(String dateStr, TaskList tasks) { + TaskList tasksToPrint = new TaskList(); + + for (int i = 0; i < tasks.size(); i++) { + if (tasks.get(i).isOnDate(dateStr)) { + tasksToPrint.add(tasks.get(i)); + } + } + + StringBuilder response; + + if (tasksToPrint.size() != 0) { + response = new StringBuilder("\t" + "Here are the tasks on this date (" + + processDateStr(dateStr) + "):" + + System.lineSeparator() + + "\t" + "[Legend: T = todo, D = deadline, E = event]" + + System.lineSeparator() + + System.lineSeparator()); + + for (int i = 0; i < tasksToPrint.size(); i++) { + if (i != 0) { + response.append(System.lineSeparator()); + } + + response.append("\t\t").append(i + 1).append(".") + .append("\t").append(tasksToPrint.get(i).toString()); + } + } else { + response = new StringBuilder("\t" + "There are no tasks on this date."); + } + + return response.toString(); + } + + private String processDateStr(String dateStr) { + LocalDate date; + String processedDateStr; + + try { + date = LocalDate.parse(dateStr); + processedDateStr = date.format(DateTimeFormatter.ofPattern("MMM d yyyy")); + } catch (Exception e) { + processedDateStr = dateStr; + } + + return processedDateStr; + } +} From d89b0c1cac359b9ce7ddf44587bafd53ea4c5628 Mon Sep 17 00:00:00 2001 From: dannytayjy Date: Mon, 30 Aug 2021 23:38:58 +0800 Subject: [PATCH 12/16] Update A-MoreOOP: Make the code more OOP --- src/main/java/AddCommand.java | 15 ++ src/main/java/AddDeadlineCommand.java | 31 +++ src/main/java/AddEventCommand.java | 31 +++ src/main/java/AddToDoCommand.java | 26 ++ src/main/java/Command.java | 18 +- src/main/java/Deadline.java | 2 +- src/main/java/DeleteCommand.java | 32 +++ src/main/java/DoneCommand.java | 32 +++ src/main/java/Duke.java | 330 ++------------------------ src/main/java/Event.java | 2 +- src/main/java/ExitCommand.java | 11 + src/main/java/ListCommand.java | 23 ++ src/main/java/Parser.java | 237 +++++++++++++++++- src/main/java/PrintCommand.java | 30 +++ src/main/java/Storage.java | 50 ++-- src/main/java/TaskWithDateTime.java | 16 +- src/main/java/Ui.java | 44 ++-- 17 files changed, 555 insertions(+), 375 deletions(-) create mode 100644 src/main/java/AddCommand.java create mode 100644 src/main/java/AddDeadlineCommand.java create mode 100644 src/main/java/AddEventCommand.java create mode 100644 src/main/java/AddToDoCommand.java create mode 100644 src/main/java/DeleteCommand.java create mode 100644 src/main/java/DoneCommand.java create mode 100644 src/main/java/ExitCommand.java create mode 100644 src/main/java/ListCommand.java create mode 100644 src/main/java/PrintCommand.java diff --git a/src/main/java/AddCommand.java b/src/main/java/AddCommand.java new file mode 100644 index 0000000000..0efd266c92 --- /dev/null +++ b/src/main/java/AddCommand.java @@ -0,0 +1,15 @@ +public abstract class AddCommand extends Command { + private String taskDescription; + + public AddCommand(String type, String taskDescription) { + super(type); + this.taskDescription = taskDescription; + } + + public String getTaskDescription() { + return taskDescription; + } + + @Override + public abstract void execute(TaskList taskList, Ui ui, Storage storage); +} diff --git a/src/main/java/AddDeadlineCommand.java b/src/main/java/AddDeadlineCommand.java new file mode 100644 index 0000000000..ed75e4f376 --- /dev/null +++ b/src/main/java/AddDeadlineCommand.java @@ -0,0 +1,31 @@ +import java.io.IOException; + +public class AddDeadlineCommand extends AddCommand { + private String taskDateTime; + + public AddDeadlineCommand(String type, String taskInfo) { + super(type, taskInfo.split("/", 2)[0]); + + String taskByDateTime = taskInfo.split("/", 2)[1]; + taskDateTime = taskByDateTime.split("\\s+", 2)[1]; + } + + @Override + public void execute(TaskList taskList, Ui ui, Storage storage) { + try { + addDeadlineTask(taskList, ui); + storage.saveTasksToFile(taskList); + } catch (DukeException | IOException e) { + ui.displayError(e.getMessage()); + } + } + + public void addDeadlineTask(TaskList taskList, Ui ui) throws DukeException { + Task newDeadlineTask = new Deadline(TaskType.DEADLINE, super.getTaskDescription(), taskDateTime); + taskList.add(newDeadlineTask); + + String response = ui.taskAddedMessage(newDeadlineTask) + + System.lineSeparator() + ui.getNumOfTasksInList(taskList); + ui.displayResponse(response); + } +} diff --git a/src/main/java/AddEventCommand.java b/src/main/java/AddEventCommand.java new file mode 100644 index 0000000000..f7999beeea --- /dev/null +++ b/src/main/java/AddEventCommand.java @@ -0,0 +1,31 @@ +import java.io.IOException; + +public class AddEventCommand extends AddCommand { + private String taskDateTime; + + public AddEventCommand(String type, String taskInfo) { + super(type, taskInfo.split("/", 2)[0]); + + String taskAtDateTime = taskInfo.split("/", 2)[1]; + taskDateTime = taskAtDateTime.split("\\s+", 2)[1]; + } + + @Override + public void execute(TaskList taskList, Ui ui, Storage storage) { + try { + addEventTask(taskList, ui); + storage.saveTasksToFile(taskList); + } catch (DukeException | IOException e) { + ui.displayError(e.getMessage()); + } + } + + public void addEventTask(TaskList taskList, Ui ui) throws DukeException { + Task newEventTask = new Event(TaskType.EVENT, super.getTaskDescription(), taskDateTime); + taskList.add(newEventTask); + + String response = ui.taskAddedMessage(newEventTask) + + System.lineSeparator() + ui.getNumOfTasksInList(taskList); + ui.displayResponse(response); + } +} diff --git a/src/main/java/AddToDoCommand.java b/src/main/java/AddToDoCommand.java new file mode 100644 index 0000000000..d001130fae --- /dev/null +++ b/src/main/java/AddToDoCommand.java @@ -0,0 +1,26 @@ +import java.io.IOException; + +public class AddToDoCommand extends AddCommand { + public AddToDoCommand(String type, String taskDescription) { + super(type, taskDescription); + } + + @Override + public void execute(TaskList taskList, Ui ui, Storage storage) { + try { + addToDoTask(taskList, ui); + storage.saveTasksToFile(taskList); + } catch (DukeException | IOException e) { + ui.displayError(e.getMessage()); + } + } + + public void addToDoTask(TaskList taskList, Ui ui) throws DukeException { + Task newToDoTask = new ToDo(TaskType.TODO, super.getTaskDescription()); + taskList.add(newToDoTask); + + String response = ui.taskAddedMessage(newToDoTask) + + System.lineSeparator() + ui.getNumOfTasksInList(taskList); + ui.displayResponse(response); + } +} diff --git a/src/main/java/Command.java b/src/main/java/Command.java index e718a769fd..22aff0d753 100644 --- a/src/main/java/Command.java +++ b/src/main/java/Command.java @@ -1,17 +1,23 @@ -public class Command { +public abstract class Command { private String type; - private String details; + private boolean isExit; - public Command(String type, String details) { + public Command(String type) { this.type = type; - this.details = details; + this.isExit = false; } public String getType() { return type; } - public String getDetails() { - return details; + public boolean isExit() { + return isExit; } + + public void setExit() { + this.isExit = true; + } + + public abstract void execute(TaskList taskList, Ui ui, Storage storage); } diff --git a/src/main/java/Deadline.java b/src/main/java/Deadline.java index eec759e9e8..2b04cd0d9d 100644 --- a/src/main/java/Deadline.java +++ b/src/main/java/Deadline.java @@ -8,7 +8,7 @@ public Deadline(TaskType type, String description, String dateTimeInput, boolean } @Override - public String dateTimeDetails() { + public String dateTimeInfo() { return "(by: " + super.getDateTimeOutput() + ")"; } diff --git a/src/main/java/DeleteCommand.java b/src/main/java/DeleteCommand.java new file mode 100644 index 0000000000..8fdfcf2aa9 --- /dev/null +++ b/src/main/java/DeleteCommand.java @@ -0,0 +1,32 @@ +import java.io.IOException; + +public class DeleteCommand extends Command { + private int taskNum; + + public DeleteCommand(String type, int taskNum) { + super(type); + this.taskNum = taskNum; + } + + @Override + public void execute(TaskList taskList, Ui ui, Storage storage) { + try { + deleteTask(taskList, ui); + storage.saveTasksToFile(taskList); + } catch (DukeException | IOException e) { + ui.displayError(e.getMessage()); + } + } + + public void deleteTask(TaskList taskList, Ui ui) throws DukeException { + if (taskNum >= 1 && taskNum <= taskList.size()) { + Task taskDeleted = taskList.remove(taskNum - 1); + + String response = ui.taskDeletedMessage(taskDeleted) + + System.lineSeparator() + ui.getNumOfTasksInList(taskList); + ui.displayResponse(response); + } else { + throw new DukeException("Task not found. Please try again!"); + } + } +} diff --git a/src/main/java/DoneCommand.java b/src/main/java/DoneCommand.java new file mode 100644 index 0000000000..4288e5c749 --- /dev/null +++ b/src/main/java/DoneCommand.java @@ -0,0 +1,32 @@ +import java.io.IOException; + +public class DoneCommand extends Command { + private int taskNum; + + public DoneCommand(String type, int taskNum) { + super(type); + this.taskNum = taskNum; + } + + @Override + public void execute(TaskList taskList, Ui ui, Storage storage) { + try { + markDone(taskList, ui); + storage.saveTasksToFile(taskList); + } catch (DukeException | IOException e) { + ui.displayError(e.getMessage()); + } + } + + public void markDone(TaskList tasks, Ui ui) throws DukeException { + if (taskNum >= 1 && taskNum <= tasks.size()) { + Task taskDone = tasks.get(taskNum - 1); + taskDone.setDone(); + + String response = ui.taskDoneMessage(taskDone); + ui.displayResponse(response); + } else { + throw new DukeException("Task not found. Please try again!"); + } + } +} diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 0097d3adf0..6e9ea3bfb2 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,333 +1,43 @@ -import java.io.File; import java.io.IOException; public class Duke { + private Ui ui; private Parser parser; private Storage storage; - private TaskList tasks; - private Ui ui; + private TaskList taskList; public Duke(String pathName, String fileName) { - parser = new Parser(); - storage = new Storage(pathName, fileName); - tasks = new TaskList(); ui = new Ui(); - } - - public static void main(String[] args) { - new Duke("data", "tasks.txt").run(); - } + parser = new Parser(); - public void run() { try { - File dataDirectory = storage.initialiseDirectory(); - File dataFile = storage.initialiseFile(dataDirectory); - - ui.greet(); - storage.loadTasksFromFile(dataFile, tasks); - - String commandLine; - - do { - commandLine = ui.readCommand(); - Command command = parser.parseInput(commandLine); - - try { - switch (command.getType()) { - case "bye": - ui.exit(); - break; - case "list": - displayTasksList(tasks); - break; - case "done": - markDone(command, tasks); - storage.saveTasksToFile(dataFile, tasks); - break; - case "delete": - deleteTask(command, tasks); - storage.saveTasksToFile(dataFile, tasks); - break; - case "todo": - addToDoTask(command, tasks); - storage.saveTasksToFile(dataFile, tasks); - break; - case "deadline": - addDeadlineTask(command, tasks); - storage.saveTasksToFile(dataFile, tasks); - break; - case "event": - addEventTask(command, tasks); - storage.saveTasksToFile(dataFile, tasks); - break; - case "print": - printTasksOnDate(command, tasks); - break; - default: - throw new DukeException("INVALID COMMAND. Please try again!"); - } - } catch (DukeException e) { - ui.displayError(e.getMessage()); - } - } while (!commandLine.equals("bye")); - + storage = new Storage(pathName, fileName); + taskList = storage.loadTasksFromFile(); } catch (DukeException | IOException e) { ui.displayError(e.getMessage()); + taskList = new TaskList(); } } - public void displayTasksList(TaskList tasks) throws DukeException { - if (tasks.size() != 0) { - String response = ui.tasksInYourList(tasks); - ui.displayResponse(response); - } else { - throw new DukeException("There are no tasks in your list!"); - } - } - - public void markDone(Command command, TaskList tasks) throws DukeException { - String commandDetails = command.getDetails(); - - if (commandDetails.trim().length() > 0) { - try { - int taskNum = Integer.parseInt(commandDetails); - - if (taskNum >= 1 && taskNum <= tasks.size()) { - tasks.get(taskNum - 1).setDone(); - Task taskDone = tasks.get(taskNum - 1); - - String response = ui.taskDoneMessage(taskDone); - ui.displayResponse(response); - } else { - throw new DukeException("Please enter a valid task number to be marked as done!"); - } - } catch (NumberFormatException e) { - throw new DukeException("Please enter a valid task number to be marked as done!"); - } - } else { - throw new DukeException("Please enter a task number to be marked as done!"); - } + public static void main(String[] args) { + new Duke("data", "tasks.txt").run(); } - public void deleteTask(Command command, TaskList tasks) throws DukeException { - String commandDetails = command.getDetails(); + public void run() { + ui.displayWelcome(); + boolean isExit = false; - if (commandDetails.trim().length() > 0) { + while (!isExit) { try { - int taskNum = Integer.parseInt(commandDetails); - - if (taskNum >= 1 && taskNum <= tasks.size()) { - Task taskDeleted = tasks.remove(taskNum - 1); - - String response = ui.taskDeletedMessage(taskDeleted) - + System.lineSeparator() + ui.numOfTasksInList(tasks); - ui.displayResponse(response); - } else { - throw new DukeException("Please enter a valid task number to be deleted!"); - } - } catch (NumberFormatException e) { - throw new DukeException("Please enter a valid task number to be deleted!"); - } - } else { - throw new DukeException("Please enter a task number to be deleted!"); - } - } - - public void addToDoTask(Command command, TaskList tasks) throws DukeException { - String commandDetails = command.getDetails(); - - if (commandDetails.trim().length() > 0) { - Task newToDoTask = new ToDo(TaskType.TODO, commandDetails); - tasks.add(newToDoTask); - - String response = ui.taskAddedMessage(newToDoTask) - + System.lineSeparator() + ui.numOfTasksInList(tasks); - ui.displayResponse(response); - } else { - throw new DukeException("The description of a todo cannot be empty!"); - } - } - - public void addDeadlineTask(Command command, TaskList tasks) throws DukeException { - String commandDetails = command.getDetails(); - - if (commandDetails.trim().length() > 0) { - String[] deadlineTaskDetails = commandDetails.split("/", 2); - - if (deadlineTaskDetails.length == 2) { - if (deadlineTaskDetails[0].trim().length() > 0) { - if (deadlineTaskDetails[1].trim().startsWith("by")) { - String description = deadlineTaskDetails[0].trim(); - String beforeDateTime = deadlineTaskDetails[1].trim(); - String[] beforeDateTimeParts = beforeDateTime.split("\\s+", 2); - - if (beforeDateTimeParts.length == 2) { - Task newDeadlineTask = new Deadline(TaskType.DEADLINE, - description, beforeDateTimeParts[1]); - tasks.add(newDeadlineTask); - - String response = ui.taskAddedMessage(newDeadlineTask) - + System.lineSeparator() + ui.numOfTasksInList(tasks); - ui.displayResponse(response); - } else { - throw new DukeException("INCOMPLETE COMMAND" - + System.lineSeparator() + "\t" - + "The date/time of a deadline cannot be empty!" - + System.lineSeparator() + "\t" - + "[Note: Enter /by before specifying the date/time]"); - } - } else { - throw new DukeException("WRONG COMMAND" - + System.lineSeparator() + "\t" - + "Enter /by before specifying the date!"); - } - } else { - if (deadlineTaskDetails[1].trim().startsWith("by")) { - String beforeDateTime = deadlineTaskDetails[1].trim(); - String[] beforeDateTimeParts = beforeDateTime.split("\\s+", 2); - - if (beforeDateTimeParts.length == 2) { - throw new DukeException("INCOMPLETE COMMAND" - + System.lineSeparator() + "\t" - + "The description of a deadline cannot be empty!"); - } else { - throw new DukeException("INCOMPLETE COMMAND" - + System.lineSeparator() + "\t" - + "The description of a deadline cannot be empty!" - + System.lineSeparator() + "\t" - + "The date/time of a deadline cannot be empty!" - + System.lineSeparator() + "\t" - + "[Note: Enter /by before specifying the date/time]"); - } - } else { - throw new DukeException("INCOMPLETE & WRONG COMMAND" - + System.lineSeparator() + "\t" - + "The description of a deadline cannot be empty!" - + System.lineSeparator() + "\t" - + "Enter /by before specifying the date/time!"); - } - } - } else { - throw new DukeException("INCOMPLETE COMMAND" - + System.lineSeparator() + "\t" - + "The date/time of a deadline cannot be empty!" - + System.lineSeparator() + "\t" - + "[Note: Enter /by before specifying the date/time]"); - } - } else { - throw new DukeException("INCOMPLETE COMMAND" - + System.lineSeparator() + "\t" - + "The description and date/time of a deadline cannot be empty!" - + System.lineSeparator() + "\t" - + "[Note: Enter /by before specifying the date/time]"); - } - } - - public void addEventTask(Command command, TaskList tasks) throws DukeException { - String commandDetails = command.getDetails(); - - if (commandDetails.trim().length() > 0) { - String[] eventTaskDetails = commandDetails.split("/", 2); - - if (eventTaskDetails.length == 2) { - if (eventTaskDetails[0].trim().length() > 0) { - if (eventTaskDetails[1].trim().startsWith("at")) { - String description = eventTaskDetails[0].trim(); - String startEndDateTime = eventTaskDetails[1].trim(); - String[] startEndDateTimeParts = startEndDateTime.split("\\s+", 2); - - if (startEndDateTimeParts.length == 2) { - Task newEventTask = new Event(TaskType.EVENT, - description, startEndDateTimeParts[1]); - tasks.add(newEventTask); - - String response = ui.taskAddedMessage(newEventTask) - + System.lineSeparator() + ui.numOfTasksInList(tasks); - ui.displayResponse(response); - } else { - throw new DukeException("INCOMPLETE COMMAND" - + System.lineSeparator() + "\t" - + "The date/time of an event cannot be empty!" - + System.lineSeparator() + "\t" - + "[Note: Enter /at before specifying the date/time]"); - } - } else { - throw new DukeException("WRONG COMMAND" - + System.lineSeparator() + "\t" - + "Enter /at before specifying the date!"); - } - } else { - if (eventTaskDetails[1].trim().startsWith("at")) { - String startEndDateTime = eventTaskDetails[1].trim(); - String[] startEndDateTimeParts = startEndDateTime.split("\\s+", 2); - - if (startEndDateTimeParts.length == 2) { - throw new DukeException("INCOMPLETE COMMAND" - + System.lineSeparator() + "\t" - + "The description of an event cannot be empty!"); - } else { - throw new DukeException("INCOMPLETE COMMAND" - + System.lineSeparator() + "\t" - + "The description of an event cannot be empty!" - + System.lineSeparator() + "\t" - + "The date/time of an event cannot be empty!" - + System.lineSeparator() + "\t" - + "[Note: Enter /at before specifying the date/time]"); - } - } else { - throw new DukeException("INCOMPLETE & WRONG COMMAND" - + System.lineSeparator() + "\t" - + "The description of an event cannot be empty!" - + System.lineSeparator() + "\t" - + "Enter /at before specifying the date/time!"); - } - } - } else { - throw new DukeException("INCOMPLETE COMMAND" - + System.lineSeparator() + "\t" - + "The date/time of an event cannot be empty!" - + System.lineSeparator() + "\t" - + "[Note: Enter /at before specifying the date/time]"); - } - } else { - throw new DukeException("INCOMPLETE COMMAND" - + System.lineSeparator() + "\t" - + "The description and date/time of an event cannot be empty!" - + System.lineSeparator() + "\t" - + "[Note: Enter /at before specifying the date/time]"); - } - } - - public void printTasksOnDate(Command command, TaskList tasks) throws DukeException { - if (tasks.size() != 0) { - String commandDetails = command.getDetails(); - - if (commandDetails.trim().length() > 0) { - if (commandDetails.trim().startsWith("/on")) { - String[] specificDateParts = commandDetails.split("\\s+", 2); - - if (specificDateParts.length == 2) { - String response = ui.tasksOnDate(specificDateParts[1], tasks); - ui.displayResponse(response); - } else { - throw new DukeException("INCOMPLETE COMMAND" - + System.lineSeparator() + "\t" - + "The date is not specified!" - + System.lineSeparator() + "\t" - + "[Note: Enter /on before specifying the date]"); - } - } else { - throw new DukeException("WRONG COMMAND" - + System.lineSeparator() + "\t" - + "Enter /on before specifying the date!"); - } - } else { - throw new DukeException("INCOMPLETE COMMAND" - + System.lineSeparator() + "\t" - + "Enter /on before specifying the date!"); + String commandLine = ui.readCommand(); + Command command = parser.parse(commandLine); + command.execute(taskList, ui, storage); + isExit = command.isExit(); + } catch (DukeException e) { + ui.displayError(e.getMessage()); + } finally { + ui.displayLine(); } - } else { - throw new DukeException("There are no tasks in your list!"); } } } diff --git a/src/main/java/Event.java b/src/main/java/Event.java index 28361542db..15efe8b711 100644 --- a/src/main/java/Event.java +++ b/src/main/java/Event.java @@ -8,7 +8,7 @@ public Event(TaskType type, String description, String dateTimeInput, boolean is } @Override - public String dateTimeDetails() { + public String dateTimeInfo() { return "(at: " + super.getDateTimeOutput() +")"; } diff --git a/src/main/java/ExitCommand.java b/src/main/java/ExitCommand.java new file mode 100644 index 0000000000..ef0dced0ad --- /dev/null +++ b/src/main/java/ExitCommand.java @@ -0,0 +1,11 @@ +public class ExitCommand extends Command { + public ExitCommand(String type) { + super(type); + } + + @Override + public void execute(TaskList taskList, Ui ui, Storage storage) { + setExit(); + ui.exit(); + } +} diff --git a/src/main/java/ListCommand.java b/src/main/java/ListCommand.java new file mode 100644 index 0000000000..7fcee75a60 --- /dev/null +++ b/src/main/java/ListCommand.java @@ -0,0 +1,23 @@ +public class ListCommand extends Command { + public ListCommand(String type) { + super(type); + } + + @Override + public void execute(TaskList taskList, Ui ui, Storage storage) { + try { + displayTasksList(taskList, ui); + } catch (DukeException e) { + ui.displayError(e.getMessage()); + } + } + + public void displayTasksList(TaskList taskList, Ui ui) throws DukeException { + if (taskList.size() != 0) { + String response = ui.getTasksInList(taskList); + ui.displayResponse(response); + } else { + throw new DukeException("There are no tasks in your list!"); + } + } +} diff --git a/src/main/java/Parser.java b/src/main/java/Parser.java index 2d193eb635..1c4ef5a540 100644 --- a/src/main/java/Parser.java +++ b/src/main/java/Parser.java @@ -1,15 +1,242 @@ public class Parser { - public Command parseInput(String commandLine) { + public Command parse(String commandLine) throws DukeException { String[] commandLineParts = commandLine.split("\\s+", 2); - Command command; + String commandType; + String commandInfo; if (commandLineParts.length == 2) { - command = new Command(commandLineParts[0], commandLineParts[1]); - } else { - command = new Command(commandLineParts[0], ""); + commandType = commandLineParts[0]; + commandInfo = commandLineParts[1]; + + // If user inputs extra text after "bye" or "list" commands + if ((commandType.equals("bye") || commandType.equals("list")) && !commandInfo.equals("")) { + throw new DukeException("INVALID COMMAND. Please try again!"); + } + } else { // for "bye" and "list" commands + commandType = commandLineParts[0]; + commandInfo = ""; + } + + Command command; + int taskNum; + String taskDescription; + String taskDetails; + String date; + + switch (commandType) { + case "bye": + command = new ExitCommand(commandType); + break; + case "list": + command = new ListCommand(commandType); + break; + case "done": + taskNum = getTaskNumFromCommand(commandInfo); + command = new DoneCommand(commandType, taskNum); + break; + case "delete": + taskNum = getTaskNumFromCommand(commandInfo); + command = new DeleteCommand(commandType, taskNum); + break; + case "todo": + taskDescription = getTaskDescriptionFromToDoCommand(commandInfo); + command = new AddToDoCommand(commandType, taskDescription); + break; + case "deadline": + taskDetails = getTaskInfoFromDeadlineCommand(commandInfo); + command = new AddDeadlineCommand(commandType, taskDetails); + break; + case "event": + taskDetails = getTaskInfoFromEventCommand(commandInfo); + command = new AddEventCommand(commandType, taskDetails); + break; + case "print": + date = getDateFromPrintCommand(commandInfo); + command = new PrintCommand(commandType, date); + break; + default: + throw new DukeException("INVALID COMMAND. Please try again!"); } return command; } + + private int getTaskNumFromCommand(String commandInfo) throws DukeException { + if (commandInfo.trim().length() > 0) { + try { + return Integer.parseInt(commandInfo); + } catch (NumberFormatException e) { + throw new DukeException("Please enter a valid task number to be marked as done!"); + } + } else { + throw new DukeException("Please enter a task number to be marked as done!"); + } + } + + private String getTaskDescriptionFromToDoCommand(String commandInfo) throws DukeException { + if (commandInfo.trim().length() > 0) { + return commandInfo; + } else { + throw new DukeException("The description of a todo cannot be empty!"); + } + } + + private String getTaskInfoFromDeadlineCommand(String commandInfo) throws DukeException { + if (commandInfo.trim().length() > 0) { + String[] deadlineTaskDetails = commandInfo.split("/", 2); + + if (deadlineTaskDetails.length == 2) { + if (deadlineTaskDetails[0].trim().length() > 0) { + if (deadlineTaskDetails[1].trim().startsWith("by")) { + String beforeDateTime = deadlineTaskDetails[1].trim(); + String[] beforeDateTimeParts = beforeDateTime.split("\\s+", 2); + + if (beforeDateTimeParts.length == 2) { + return commandInfo; + } else { + throw new DukeException("INCOMPLETE COMMAND" + + System.lineSeparator() + "\t" + + "The date/time of a deadline cannot be empty!" + + System.lineSeparator() + "\t" + + "[Note: Enter /by before specifying the date/time]"); + } + } else { + throw new DukeException("WRONG COMMAND" + + System.lineSeparator() + "\t" + + "Enter /by before specifying the date!"); + } + } else { + if (deadlineTaskDetails[1].trim().startsWith("by")) { + String beforeDateTime = deadlineTaskDetails[1].trim(); + String[] beforeDateTimeParts = beforeDateTime.split("\\s+", 2); + + if (beforeDateTimeParts.length == 2) { + throw new DukeException("INCOMPLETE COMMAND" + + System.lineSeparator() + "\t" + + "The description of a deadline cannot be empty!"); + } else { + throw new DukeException("INCOMPLETE COMMAND" + + System.lineSeparator() + "\t" + + "The description of a deadline cannot be empty!" + + System.lineSeparator() + "\t" + + "The date/time of a deadline cannot be empty!" + + System.lineSeparator() + "\t" + + "[Note: Enter /by before specifying the date/time]"); + } + } else { + throw new DukeException("INCOMPLETE & WRONG COMMAND" + + System.lineSeparator() + "\t" + + "The description of a deadline cannot be empty!" + + System.lineSeparator() + "\t" + + "Enter /by before specifying the date/time!"); + } + } + } else { + throw new DukeException("INCOMPLETE COMMAND" + + System.lineSeparator() + "\t" + + "The date/time of a deadline cannot be empty!" + + System.lineSeparator() + "\t" + + "[Note: Enter /by before specifying the date/time]"); + } + } else { + throw new DukeException("INCOMPLETE COMMAND" + + System.lineSeparator() + "\t" + + "The description and date/time of a deadline cannot be empty!" + + System.lineSeparator() + "\t" + + "[Note: Enter /by before specifying the date/time]"); + } + } + + private String getTaskInfoFromEventCommand(String commandInfo) throws DukeException { + if (commandInfo.trim().length() > 0) { + String[] eventTaskDetails = commandInfo.split("/", 2); + + if (eventTaskDetails.length == 2) { + if (eventTaskDetails[0].trim().length() > 0) { + if (eventTaskDetails[1].trim().startsWith("at")) { + String startEndDateTime = eventTaskDetails[1].trim(); + String[] startEndDateTimeParts = startEndDateTime.split("\\s+", 2); + + if (startEndDateTimeParts.length == 2) { + return commandInfo; + } else { + throw new DukeException("INCOMPLETE COMMAND" + + System.lineSeparator() + "\t" + + "The date/time of an event cannot be empty!" + + System.lineSeparator() + "\t" + + "[Note: Enter /at before specifying the date/time]"); + } + } else { + throw new DukeException("WRONG COMMAND" + + System.lineSeparator() + "\t" + + "Enter /at before specifying the date!"); + } + } else { + if (eventTaskDetails[1].trim().startsWith("at")) { + String startEndDateTime = eventTaskDetails[1].trim(); + String[] startEndDateTimeParts = startEndDateTime.split("\\s+", 2); + + if (startEndDateTimeParts.length == 2) { + throw new DukeException("INCOMPLETE COMMAND" + + System.lineSeparator() + "\t" + + "The description of an event cannot be empty!"); + } else { + throw new DukeException("INCOMPLETE COMMAND" + + System.lineSeparator() + "\t" + + "The description of an event cannot be empty!" + + System.lineSeparator() + "\t" + + "The date/time of an event cannot be empty!" + + System.lineSeparator() + "\t" + + "[Note: Enter /at before specifying the date/time]"); + } + } else { + throw new DukeException("INCOMPLETE & WRONG COMMAND" + + System.lineSeparator() + "\t" + + "The description of an event cannot be empty!" + + System.lineSeparator() + "\t" + + "Enter /at before specifying the date/time!"); + } + } + } else { + throw new DukeException("INCOMPLETE COMMAND" + + System.lineSeparator() + "\t" + + "The date/time of an event cannot be empty!" + + System.lineSeparator() + "\t" + + "[Note: Enter /at before specifying the date/time]"); + } + } else { + throw new DukeException("INCOMPLETE COMMAND" + + System.lineSeparator() + "\t" + + "The description and date/time of an event cannot be empty!" + + System.lineSeparator() + "\t" + + "[Note: Enter /at before specifying the date/time]"); + } + } + + private String getDateFromPrintCommand(String commandInfo) throws DukeException { + if (commandInfo.trim().length() > 0) { + if (commandInfo.trim().startsWith("/on")) { + String[] specificDateParts = commandInfo.split("\\s+", 2); + + if (specificDateParts.length == 2) { + return specificDateParts[1]; + } else { + throw new DukeException("INCOMPLETE COMMAND" + + System.lineSeparator() + "\t" + + "The date is not specified!" + + System.lineSeparator() + "\t" + + "[Note: Enter /on before specifying the date]"); + } + } else { + throw new DukeException("WRONG COMMAND" + + System.lineSeparator() + "\t" + + "Enter /on before specifying the date!"); + } + } else { + throw new DukeException("INCOMPLETE COMMAND" + + System.lineSeparator() + "\t" + + "Enter /on before specifying the date!"); + } + } } diff --git a/src/main/java/PrintCommand.java b/src/main/java/PrintCommand.java new file mode 100644 index 0000000000..0307ddba95 --- /dev/null +++ b/src/main/java/PrintCommand.java @@ -0,0 +1,30 @@ +public class PrintCommand extends Command { + private String date; + + public PrintCommand(String type, String date) { + super(type); + this.date = date; + } + + public String getDate() { + return date; + } + + @Override + public void execute(TaskList taskList, Ui ui, Storage storage) { + try { + printTasksOnDate(taskList, ui); + } catch (DukeException e) { + ui.displayError(e.getMessage()); + } + } + + public void printTasksOnDate(TaskList taskList, Ui ui) throws DukeException { + if (taskList.size() != 0) { + String response = ui.getTasksOnDate(date, taskList); + ui.displayResponse(response); + } else { + throw new DukeException("There are no tasks on this date!"); + } + } +} diff --git a/src/main/java/Storage.java b/src/main/java/Storage.java index b50dc3fae0..f6c98b4eff 100644 --- a/src/main/java/Storage.java +++ b/src/main/java/Storage.java @@ -1,15 +1,19 @@ import java.io.*; public class Storage { - private final String pathName; - private final String fileName; + private String pathName; + private String fileName; + private File dataDirectory; + private File dataFile; - public Storage(String pathName, String fileName) { + public Storage(String pathName, String fileName) throws DukeException, IOException { this.pathName = pathName; this.fileName = fileName; + dataDirectory = initialiseDirectory(); + dataFile = initialiseFile(dataDirectory); } - public File initialiseDirectory() throws DukeException { + private File initialiseDirectory() throws DukeException { File directory = new File(pathName); boolean hasDirectory = directory.exists(); @@ -24,7 +28,7 @@ public File initialiseDirectory() throws DukeException { } } - public File initialiseFile(File directory) throws IOException { + private File initialiseFile(File directory) throws IOException { File file = new File(directory + "/" + fileName); boolean hasFile = file.exists(); @@ -39,45 +43,49 @@ public File initialiseFile(File directory) throws IOException { } } - public void loadTasksFromFile(File dataFile, TaskList tasks) throws IOException { + public TaskList loadTasksFromFile() throws IOException { + TaskList taskList = new TaskList(); + FileReader fileReader = new FileReader(dataFile); BufferedReader bufferedReader = new BufferedReader(fileReader); String line; while ((line = bufferedReader.readLine()) != null) { - String[] task = line.trim().split("\\|"); - String type = task[0].trim(); - boolean isDone = Boolean.parseBoolean(task[1].trim()); - String description = task[2].trim(); + String[] taskDetails = line.trim().split("\\|"); + String type = taskDetails[0].trim(); + boolean isDone = Boolean.parseBoolean(taskDetails[1].trim()); + String description = taskDetails[2].trim(); String dateTime; switch (type) { case "T": Task todoTask = new ToDo(TaskType.TODO, description, isDone); - tasks.add(todoTask); + taskList.add(todoTask); break; case "D": - dateTime = task[3].trim(); + dateTime = taskDetails[3].trim(); Task deadlineTask = new Deadline(TaskType.DEADLINE, description, dateTime, isDone); - tasks.add(deadlineTask); + taskList.add(deadlineTask); break; case "E": - dateTime = task[3].trim(); + dateTime = taskDetails[3].trim(); Task eventTask = new Event(TaskType.EVENT, description, dateTime, isDone); - tasks.add(eventTask); + taskList.add(eventTask); break; } } bufferedReader.close(); + + return taskList; } - public void saveTasksToFile(File dataFile, TaskList tasks) throws IOException { + public void saveTasksToFile(TaskList taskList) throws IOException { FileWriter fileWriter = new FileWriter(dataFile,false); BufferedWriter bufferedWriter = new BufferedWriter(fileWriter); - for (int i = 0; i < tasks.size(); i++) { - Task task = tasks.get(i); + for (int i = 0; i < taskList.size(); i++) { + Task task = taskList.get(i); TaskType type = task.getType(); boolean isDone = task.isDone(); @@ -90,14 +98,14 @@ public void saveTasksToFile(File dataFile, TaskList tasks) throws IOException { dateTime = ((TaskWithDateTime) task).getDateTimeInput(); } - String taskDetails = taskDetailsSaveFormat(type, isDone, description, dateTime); - bufferedWriter.write(taskDetails + System.lineSeparator()); + String taskToSave = taskSaveFormat(type, isDone, description, dateTime); + bufferedWriter.write(taskToSave + System.lineSeparator()); } bufferedWriter.close(); } - private String taskDetailsSaveFormat(TaskType type, boolean isDone, String description, String dateTime) { + private String taskSaveFormat(TaskType type, boolean isDone, String description, String dateTime) { if (dateTime.equals("")) { return type.getAbbr() + " | " + (isDone ? "1" : "0") + " | " + description; } else { diff --git a/src/main/java/TaskWithDateTime.java b/src/main/java/TaskWithDateTime.java index 4897126942..43a4b6a234 100644 --- a/src/main/java/TaskWithDateTime.java +++ b/src/main/java/TaskWithDateTime.java @@ -115,25 +115,25 @@ public String getDateTimeOutput() { return dateTimeOutput; } - public abstract String dateTimeDetails(); + public abstract String dateTimeInfo(); @Override - public boolean isOnDate(String specificDateStr) { + public boolean isOnDate(String dateStr) { try { - LocalDate dateToSearch = LocalDate.parse(specificDateStr); + LocalDate dateToSearch = LocalDate.parse(dateStr); - if (this.date != null) { - return this.date.equals(dateToSearch); + if (date != null) { + return date.equals(dateToSearch); } else { - return this.dateInput.equals(specificDateStr); + return dateInput.equals(dateStr); } } catch (Exception e) { - return this.dateInput.equals(specificDateStr); + return dateInput.equals(dateStr); } } @Override public String toString() { - return super.toString() + " " + dateTimeDetails(); + return super.toString() + " " + dateTimeInfo(); } } diff --git a/src/main/java/Ui.java b/src/main/java/Ui.java index c339906f8e..1ee3dc99d8 100644 --- a/src/main/java/Ui.java +++ b/src/main/java/Ui.java @@ -10,32 +10,30 @@ public String readCommand() { return sc.nextLine().trim(); } - public void greet() { + public void exit() { + String message = "\t" + "Bye. Hope to see you again soon!"; + displayResponse(message); + } + + public void displayWelcome() { displayLine(); displayWelcomeMessage(); displayMenuOptions(); displayLine(); } - public void exit() { - String message = "\t" + "Bye. Hope to see you again soon!"; - displayResponse(message); - } - public void displayResponse(String message) { displayLine(); System.out.println(message); - displayLine(); } public void displayError(String message) { displayLine(); System.out.println("ERROR MESSAGE:"); System.out.println("\t" + "☹ " + message); - displayLine(); } - private void displayLine() { + public void displayLine() { String horizontalLine = "____________________________________________________________"; System.out.println(horizontalLine); } @@ -102,43 +100,43 @@ public String taskDoneMessage(Task task) { + System.lineSeparator() + "\t\t" + task; } - public String numOfTasksInList(TaskList tasks) { - return "\t" + "Now you have " + tasks.size() - + (tasks.size() > 1 ? " tasks" : " task") + public String getNumOfTasksInList(TaskList taskList) { + return "\t" + "Now you have " + taskList.size() + + (taskList.size() > 1 ? " tasks" : " task") + " in the list."; } - public String tasksInYourList(TaskList tasks) { + public String getTasksInList(TaskList taskList) { StringBuilder response = new StringBuilder("\t" + "Here are the tasks in your list:" + System.lineSeparator() + "\t" + "[Legend: T = todo, D = deadline, E = event]" + System.lineSeparator() + System.lineSeparator()); - for (int i = 0; i < tasks.size(); i++) { + for (int i = 0; i < taskList.size(); i++) { if (i != 0) { response.append(System.lineSeparator()); } response.append("\t\t").append(i + 1).append(".") - .append("\t").append(tasks.get(i).toString()); + .append("\t").append(taskList.get(i).toString()); } return response.toString(); } - public String tasksOnDate(String dateStr, TaskList tasks) { - TaskList tasksToPrint = new TaskList(); + public String getTasksOnDate(String dateStr, TaskList taskList) { + TaskList taskOnDateList = new TaskList(); - for (int i = 0; i < tasks.size(); i++) { - if (tasks.get(i).isOnDate(dateStr)) { - tasksToPrint.add(tasks.get(i)); + for (int i = 0; i < taskList.size(); i++) { + if (taskList.get(i).isOnDate(dateStr)) { + taskOnDateList.add(taskList.get(i)); } } StringBuilder response; - if (tasksToPrint.size() != 0) { + if (taskOnDateList.size() != 0) { response = new StringBuilder("\t" + "Here are the tasks on this date (" + processDateStr(dateStr) + "):" + System.lineSeparator() @@ -146,13 +144,13 @@ public String tasksOnDate(String dateStr, TaskList tasks) { + System.lineSeparator() + System.lineSeparator()); - for (int i = 0; i < tasksToPrint.size(); i++) { + for (int i = 0; i < taskOnDateList.size(); i++) { if (i != 0) { response.append(System.lineSeparator()); } response.append("\t\t").append(i + 1).append(".") - .append("\t").append(tasksToPrint.get(i).toString()); + .append("\t").append(taskOnDateList.get(i).toString()); } } else { response = new StringBuilder("\t" + "There are no tasks on this date."); From 942e26ca6ac2f20add48662ca83a18986241c92d Mon Sep 17 00:00:00 2001 From: dannytayjy Date: Tue, 31 Aug 2021 07:54:59 +0800 Subject: [PATCH 13/16] Implement A-Packages and fix bugs --- data/tasks.txt | 11 +++++++++- src/main/java/{ => duke}/Duke.java | 4 ++++ src/main/java/{ => duke}/DukeException.java | 2 ++ src/main/java/{ => duke}/Parser.java | 22 ++++++++++++++----- src/main/java/{ => duke}/Storage.java | 18 +++++++++++++-- src/main/java/{ => duke}/TaskList.java | 4 ++++ src/main/java/{ => duke}/Ui.java | 6 ++++- .../java/{ => duke/command}/AddCommand.java | 6 +++++ .../command}/AddDeadlineCommand.java | 16 +++++++++++--- .../{ => duke/command}/AddEventCommand.java | 16 +++++++++++--- .../{ => duke/command}/AddToDoCommand.java | 10 +++++++++ src/main/java/{ => duke/command}/Command.java | 6 +++++ .../{ => duke/command}/DeleteCommand.java | 10 ++++++++- .../java/{ => duke/command}/DoneCommand.java | 14 +++++++++--- .../java/{ => duke/command}/ExitCommand.java | 6 +++++ .../java/{ => duke/command}/ListCommand.java | 7 ++++++ .../java/{ => duke/command}/PrintCommand.java | 7 ++++++ src/main/java/{ => duke/task}/Deadline.java | 2 ++ src/main/java/{ => duke/task}/Event.java | 2 ++ src/main/java/{ => duke/task}/Task.java | 4 +++- src/main/java/{ => duke/task}/TaskType.java | 2 ++ .../{ => duke/task}/TaskWithDateTime.java | 14 +++++++++--- src/main/java/{ => duke/task}/ToDo.java | 2 ++ 23 files changed, 168 insertions(+), 23 deletions(-) rename src/main/java/{ => duke}/Duke.java (96%) rename src/main/java/{ => duke}/DukeException.java (89%) rename src/main/java/{ => duke}/Parser.java (94%) rename src/main/java/{ => duke}/Storage.java (89%) rename src/main/java/{ => duke}/TaskList.java (93%) rename src/main/java/{ => duke}/Ui.java (97%) rename src/main/java/{ => duke/command}/AddCommand.java (82%) rename src/main/java/{ => duke/command}/AddDeadlineCommand.java (70%) rename src/main/java/{ => duke/command}/AddEventCommand.java (70%) rename src/main/java/{ => duke/command}/AddToDoCommand.java (82%) rename src/main/java/{ => duke/command}/Command.java (84%) rename src/main/java/{ => duke/command}/DeleteCommand.java (83%) rename src/main/java/{ => duke/command}/DoneCommand.java (70%) rename src/main/java/{ => duke/command}/ExitCommand.java (74%) rename src/main/java/{ => duke/command}/ListCommand.java (85%) rename src/main/java/{ => duke/command}/PrintCommand.java (87%) rename src/main/java/{ => duke/task}/Deadline.java (96%) rename src/main/java/{ => duke/task}/Event.java (96%) rename src/main/java/{ => duke/task}/Task.java (93%) rename src/main/java/{ => duke/task}/TaskType.java (95%) rename src/main/java/{ => duke/task}/TaskWithDateTime.java (90%) rename src/main/java/{ => duke/task}/ToDo.java (94%) diff --git a/data/tasks.txt b/data/tasks.txt index 0a052014f7..1a5db500c6 100644 --- a/data/tasks.txt +++ b/data/tasks.txt @@ -1 +1,10 @@ -D | 0 | test | 2021-08-31 +D | 1 | CS2105 Assignment 0 | 2021-08-29 2359 +D | 1 | PC1201 Test 1 (First Mock Test) | 2021-09-02 1400 +D | 1 | CS2103 Week 4 Quiz | 2021-08-30 2359 +D | 0 | CS3240 Week 4 Quiz | 2021-08-31 2000 +T | 0 | Vacuum room floor +T | 0 | Change bedsheet +T | 0 | Download files from LumiNUS +T | 0 | CS2103 Week 3 Deliverables (JUnit) +T | 0 | CS2103 Week 3 Deliverables (Jar) +T | 0 | CS2103 Week 3 Deliverables (Javadocs) diff --git a/src/main/java/Duke.java b/src/main/java/duke/Duke.java similarity index 96% rename from src/main/java/Duke.java rename to src/main/java/duke/Duke.java index 6e9ea3bfb2..fbdc0b3e76 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/duke/Duke.java @@ -1,3 +1,7 @@ +package duke; + +import duke.command.Command; + import java.io.IOException; public class Duke { diff --git a/src/main/java/DukeException.java b/src/main/java/duke/DukeException.java similarity index 89% rename from src/main/java/DukeException.java rename to src/main/java/duke/DukeException.java index 31f5a63d16..3c1763dfd2 100644 --- a/src/main/java/DukeException.java +++ b/src/main/java/duke/DukeException.java @@ -1,3 +1,5 @@ +package duke; + public class DukeException extends Exception { public DukeException(String errorMessage) { super(errorMessage); diff --git a/src/main/java/Parser.java b/src/main/java/duke/Parser.java similarity index 94% rename from src/main/java/Parser.java rename to src/main/java/duke/Parser.java index 1c4ef5a540..3be840116a 100644 --- a/src/main/java/Parser.java +++ b/src/main/java/duke/Parser.java @@ -1,3 +1,15 @@ +package duke; + +import duke.command.AddDeadlineCommand; +import duke.command.AddEventCommand; +import duke.command.AddToDoCommand; +import duke.command.Command; +import duke.command.DeleteCommand; +import duke.command.DoneCommand; +import duke.command.ExitCommand; +import duke.command.ListCommand; +import duke.command.PrintCommand; + public class Parser { public Command parse(String commandLine) throws DukeException { String[] commandLineParts = commandLine.split("\\s+", 2); @@ -21,7 +33,7 @@ public Command parse(String commandLine) throws DukeException { Command command; int taskNum; String taskDescription; - String taskDetails; + String taskInfo; String date; switch (commandType) { @@ -44,12 +56,12 @@ public Command parse(String commandLine) throws DukeException { command = new AddToDoCommand(commandType, taskDescription); break; case "deadline": - taskDetails = getTaskInfoFromDeadlineCommand(commandInfo); - command = new AddDeadlineCommand(commandType, taskDetails); + taskInfo = getTaskInfoFromDeadlineCommand(commandInfo); + command = new AddDeadlineCommand(commandType, taskInfo); break; case "event": - taskDetails = getTaskInfoFromEventCommand(commandInfo); - command = new AddEventCommand(commandType, taskDetails); + taskInfo = getTaskInfoFromEventCommand(commandInfo); + command = new AddEventCommand(commandType, taskInfo); break; case "print": date = getDateFromPrintCommand(commandInfo); diff --git a/src/main/java/Storage.java b/src/main/java/duke/Storage.java similarity index 89% rename from src/main/java/Storage.java rename to src/main/java/duke/Storage.java index f6c98b4eff..515cec5651 100644 --- a/src/main/java/Storage.java +++ b/src/main/java/duke/Storage.java @@ -1,4 +1,18 @@ -import java.io.*; +package duke; + +import duke.task.Deadline; +import duke.task.Event; +import duke.task.Task; +import duke.task.TaskType; +import duke.task.TaskWithDateTime; +import duke.task.ToDo; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; public class Storage { private String pathName; @@ -53,7 +67,7 @@ public TaskList loadTasksFromFile() throws IOException { while ((line = bufferedReader.readLine()) != null) { String[] taskDetails = line.trim().split("\\|"); String type = taskDetails[0].trim(); - boolean isDone = Boolean.parseBoolean(taskDetails[1].trim()); + boolean isDone = (Integer.parseInt(taskDetails[1].trim()) == 1); String description = taskDetails[2].trim(); String dateTime; diff --git a/src/main/java/TaskList.java b/src/main/java/duke/TaskList.java similarity index 93% rename from src/main/java/TaskList.java rename to src/main/java/duke/TaskList.java index 28837a863e..36103926f5 100644 --- a/src/main/java/TaskList.java +++ b/src/main/java/duke/TaskList.java @@ -1,3 +1,7 @@ +package duke; + +import duke.task.Task; + import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/Ui.java b/src/main/java/duke/Ui.java similarity index 97% rename from src/main/java/Ui.java rename to src/main/java/duke/Ui.java index 1ee3dc99d8..24e2cf74e9 100644 --- a/src/main/java/Ui.java +++ b/src/main/java/duke/Ui.java @@ -1,3 +1,7 @@ +package duke; + +import duke.task.Task; + import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.Scanner; @@ -39,7 +43,7 @@ public void displayLine() { } private void displayWelcomeMessage() { - String message = "\t" + "Hello! I'm Duke, your Personal Assistant ChatBot." + String message = "\t" + "Hello! I'm duke.Duke, your Personal Assistant ChatBot." + System.lineSeparator() + "\t" + "What can I do for you?" + System.lineSeparator(); diff --git a/src/main/java/AddCommand.java b/src/main/java/duke/command/AddCommand.java similarity index 82% rename from src/main/java/AddCommand.java rename to src/main/java/duke/command/AddCommand.java index 0efd266c92..94563aa171 100644 --- a/src/main/java/AddCommand.java +++ b/src/main/java/duke/command/AddCommand.java @@ -1,3 +1,9 @@ +package duke.command; + +import duke.Storage; +import duke.TaskList; +import duke.Ui; + public abstract class AddCommand extends Command { private String taskDescription; diff --git a/src/main/java/AddDeadlineCommand.java b/src/main/java/duke/command/AddDeadlineCommand.java similarity index 70% rename from src/main/java/AddDeadlineCommand.java rename to src/main/java/duke/command/AddDeadlineCommand.java index ed75e4f376..5d61fda0fd 100644 --- a/src/main/java/AddDeadlineCommand.java +++ b/src/main/java/duke/command/AddDeadlineCommand.java @@ -1,13 +1,23 @@ +package duke.command; + +import duke.DukeException; +import duke.Storage; +import duke.TaskList; +import duke.Ui; +import duke.task.Deadline; +import duke.task.Task; +import duke.task.TaskType; + import java.io.IOException; public class AddDeadlineCommand extends AddCommand { private String taskDateTime; public AddDeadlineCommand(String type, String taskInfo) { - super(type, taskInfo.split("/", 2)[0]); + super(type, taskInfo.split("/", 2)[0].trim()); - String taskByDateTime = taskInfo.split("/", 2)[1]; - taskDateTime = taskByDateTime.split("\\s+", 2)[1]; + String taskByDateTime = taskInfo.split("/", 2)[1].trim(); + taskDateTime = taskByDateTime.split("\\s+", 2)[1].trim(); } @Override diff --git a/src/main/java/AddEventCommand.java b/src/main/java/duke/command/AddEventCommand.java similarity index 70% rename from src/main/java/AddEventCommand.java rename to src/main/java/duke/command/AddEventCommand.java index f7999beeea..77868bc835 100644 --- a/src/main/java/AddEventCommand.java +++ b/src/main/java/duke/command/AddEventCommand.java @@ -1,13 +1,23 @@ +package duke.command; + +import duke.DukeException; +import duke.Storage; +import duke.TaskList; +import duke.Ui; +import duke.task.Event; +import duke.task.Task; +import duke.task.TaskType; + import java.io.IOException; public class AddEventCommand extends AddCommand { private String taskDateTime; public AddEventCommand(String type, String taskInfo) { - super(type, taskInfo.split("/", 2)[0]); + super(type, taskInfo.split("/", 2)[0].trim()); - String taskAtDateTime = taskInfo.split("/", 2)[1]; - taskDateTime = taskAtDateTime.split("\\s+", 2)[1]; + String taskAtDateTime = taskInfo.split("/", 2)[1].trim(); + taskDateTime = taskAtDateTime.split("\\s+", 2)[1].trim(); } @Override diff --git a/src/main/java/AddToDoCommand.java b/src/main/java/duke/command/AddToDoCommand.java similarity index 82% rename from src/main/java/AddToDoCommand.java rename to src/main/java/duke/command/AddToDoCommand.java index d001130fae..01ff2c7f42 100644 --- a/src/main/java/AddToDoCommand.java +++ b/src/main/java/duke/command/AddToDoCommand.java @@ -1,3 +1,13 @@ +package duke.command; + +import duke.DukeException; +import duke.Storage; +import duke.TaskList; +import duke.Ui; +import duke.task.Task; +import duke.task.TaskType; +import duke.task.ToDo; + import java.io.IOException; public class AddToDoCommand extends AddCommand { diff --git a/src/main/java/Command.java b/src/main/java/duke/command/Command.java similarity index 84% rename from src/main/java/Command.java rename to src/main/java/duke/command/Command.java index 22aff0d753..8e8a98c22c 100644 --- a/src/main/java/Command.java +++ b/src/main/java/duke/command/Command.java @@ -1,3 +1,9 @@ +package duke.command; + +import duke.Storage; +import duke.TaskList; +import duke.Ui; + public abstract class Command { private String type; private boolean isExit; diff --git a/src/main/java/DeleteCommand.java b/src/main/java/duke/command/DeleteCommand.java similarity index 83% rename from src/main/java/DeleteCommand.java rename to src/main/java/duke/command/DeleteCommand.java index 8fdfcf2aa9..11c751f0ee 100644 --- a/src/main/java/DeleteCommand.java +++ b/src/main/java/duke/command/DeleteCommand.java @@ -1,3 +1,11 @@ +package duke.command; + +import duke.DukeException; +import duke.Storage; +import duke.TaskList; +import duke.Ui; +import duke.task.Task; + import java.io.IOException; public class DeleteCommand extends Command { @@ -19,7 +27,7 @@ public void execute(TaskList taskList, Ui ui, Storage storage) { } public void deleteTask(TaskList taskList, Ui ui) throws DukeException { - if (taskNum >= 1 && taskNum <= taskList.size()) { + if (taskNum > 0 && taskNum <= taskList.size()) { Task taskDeleted = taskList.remove(taskNum - 1); String response = ui.taskDeletedMessage(taskDeleted) diff --git a/src/main/java/DoneCommand.java b/src/main/java/duke/command/DoneCommand.java similarity index 70% rename from src/main/java/DoneCommand.java rename to src/main/java/duke/command/DoneCommand.java index 4288e5c749..f160d8d8f7 100644 --- a/src/main/java/DoneCommand.java +++ b/src/main/java/duke/command/DoneCommand.java @@ -1,3 +1,11 @@ +package duke.command; + +import duke.DukeException; +import duke.Storage; +import duke.TaskList; +import duke.Ui; +import duke.task.Task; + import java.io.IOException; public class DoneCommand extends Command { @@ -18,9 +26,9 @@ public void execute(TaskList taskList, Ui ui, Storage storage) { } } - public void markDone(TaskList tasks, Ui ui) throws DukeException { - if (taskNum >= 1 && taskNum <= tasks.size()) { - Task taskDone = tasks.get(taskNum - 1); + public void markDone(TaskList taskList, Ui ui) throws DukeException { + if (taskNum > 0 && taskNum <= taskList.size()) { + Task taskDone = taskList.get(taskNum - 1); taskDone.setDone(); String response = ui.taskDoneMessage(taskDone); diff --git a/src/main/java/ExitCommand.java b/src/main/java/duke/command/ExitCommand.java similarity index 74% rename from src/main/java/ExitCommand.java rename to src/main/java/duke/command/ExitCommand.java index ef0dced0ad..7a50222f26 100644 --- a/src/main/java/ExitCommand.java +++ b/src/main/java/duke/command/ExitCommand.java @@ -1,3 +1,9 @@ +package duke.command; + +import duke.Storage; +import duke.TaskList; +import duke.Ui; + public class ExitCommand extends Command { public ExitCommand(String type) { super(type); diff --git a/src/main/java/ListCommand.java b/src/main/java/duke/command/ListCommand.java similarity index 85% rename from src/main/java/ListCommand.java rename to src/main/java/duke/command/ListCommand.java index 7fcee75a60..8a766bcf8e 100644 --- a/src/main/java/ListCommand.java +++ b/src/main/java/duke/command/ListCommand.java @@ -1,3 +1,10 @@ +package duke.command; + +import duke.DukeException; +import duke.Storage; +import duke.TaskList; +import duke.Ui; + public class ListCommand extends Command { public ListCommand(String type) { super(type); diff --git a/src/main/java/PrintCommand.java b/src/main/java/duke/command/PrintCommand.java similarity index 87% rename from src/main/java/PrintCommand.java rename to src/main/java/duke/command/PrintCommand.java index 0307ddba95..6da46261d8 100644 --- a/src/main/java/PrintCommand.java +++ b/src/main/java/duke/command/PrintCommand.java @@ -1,3 +1,10 @@ +package duke.command; + +import duke.DukeException; +import duke.Storage; +import duke.TaskList; +import duke.Ui; + public class PrintCommand extends Command { private String date; diff --git a/src/main/java/Deadline.java b/src/main/java/duke/task/Deadline.java similarity index 96% rename from src/main/java/Deadline.java rename to src/main/java/duke/task/Deadline.java index 2b04cd0d9d..c96d1d10ad 100644 --- a/src/main/java/Deadline.java +++ b/src/main/java/duke/task/Deadline.java @@ -1,3 +1,5 @@ +package duke.task; + public class Deadline extends TaskWithDateTime { public Deadline(TaskType type, String description, String dateTimeInput) { super(type, description, dateTimeInput); diff --git a/src/main/java/Event.java b/src/main/java/duke/task/Event.java similarity index 96% rename from src/main/java/Event.java rename to src/main/java/duke/task/Event.java index 15efe8b711..6fe37aa42b 100644 --- a/src/main/java/Event.java +++ b/src/main/java/duke/task/Event.java @@ -1,3 +1,5 @@ +package duke.task; + public class Event extends TaskWithDateTime { public Event(TaskType type, String description, String dateTimeInput) { super(type, description, dateTimeInput); diff --git a/src/main/java/Task.java b/src/main/java/duke/task/Task.java similarity index 93% rename from src/main/java/Task.java rename to src/main/java/duke/task/Task.java index 82f4a41ae0..f59e90ae91 100644 --- a/src/main/java/Task.java +++ b/src/main/java/duke/task/Task.java @@ -1,3 +1,5 @@ +package duke.task; + public abstract class Task { private TaskType type; private String description; @@ -33,7 +35,7 @@ public void setDone() { this.isDone = true; } - public boolean isOnDate(String specificDateStr) { + public boolean isOnDate(String dateStr) { return false; } diff --git a/src/main/java/TaskType.java b/src/main/java/duke/task/TaskType.java similarity index 95% rename from src/main/java/TaskType.java rename to src/main/java/duke/task/TaskType.java index 0d42f84dc3..c655eb9e64 100644 --- a/src/main/java/TaskType.java +++ b/src/main/java/duke/task/TaskType.java @@ -1,3 +1,5 @@ +package duke.task; + public enum TaskType { TODO("todo", "T"), DEADLINE("deadline", "D"), diff --git a/src/main/java/TaskWithDateTime.java b/src/main/java/duke/task/TaskWithDateTime.java similarity index 90% rename from src/main/java/TaskWithDateTime.java rename to src/main/java/duke/task/TaskWithDateTime.java index 43a4b6a234..2c324835d5 100644 --- a/src/main/java/TaskWithDateTime.java +++ b/src/main/java/duke/task/TaskWithDateTime.java @@ -1,3 +1,5 @@ +package duke.task; + import java.time.LocalDate; import java.time.LocalTime; import java.time.format.DateTimeFormatter; @@ -26,11 +28,17 @@ private void processDateTimeInput() { String[] dateTimeInputParts = dateTimeInput.split("\\s+", 2); if (dateTimeInputParts.length == 2) { - dateInput = dateTimeInputParts[0]; - timeInput = dateTimeInputParts[1]; + dateInput = dateTimeInputParts[0].trim(); + timeInput = dateTimeInputParts[1].trim(); + + // Omit any additional whitespaces in between date and time inputs + dateTimeInput = dateInput + " " + timeInput; } else { - dateInput = dateTimeInputParts[0]; + dateInput = dateTimeInputParts[0].trim(); timeInput = ""; + + // Omit any additional whitespaces that comes with date input + dateTimeInput = dateInput; } // Process dateInput diff --git a/src/main/java/ToDo.java b/src/main/java/duke/task/ToDo.java similarity index 94% rename from src/main/java/ToDo.java rename to src/main/java/duke/task/ToDo.java index 0d7b99c550..a531387b28 100644 --- a/src/main/java/ToDo.java +++ b/src/main/java/duke/task/ToDo.java @@ -1,3 +1,5 @@ +package duke.task; + public class ToDo extends Task { public ToDo(TaskType type, String description) { super(type, description); From 765d73ce8d001c002f000ba5649aaf67b8df3852 Mon Sep 17 00:00:00 2001 From: dannytayjy Date: Thu, 9 Sep 2021 19:41:32 +0800 Subject: [PATCH 14/16] Add JavaDoc comments --- src/main/java/duke/Duke.java | 15 +++++ src/main/java/duke/DukeException.java | 7 ++ src/main/java/duke/Parser.java | 40 ++++++++++++ src/main/java/duke/Storage.java | 42 +++++++++++- src/main/java/duke/TaskList.java | 30 +++++++++ src/main/java/duke/Ui.java | 65 +++++++++++++++++++ src/main/java/duke/command/AddCommand.java | 19 ++++++ .../java/duke/command/AddDeadlineCommand.java | 20 ++++++ .../java/duke/command/AddEventCommand.java | 20 ++++++ .../java/duke/command/AddToDoCommand.java | 21 ++++++ src/main/java/duke/command/Command.java | 7 +- src/main/java/duke/command/DeleteCommand.java | 22 ++++++- src/main/java/duke/command/DoneCommand.java | 20 ++++++ src/main/java/duke/command/ExitCommand.java | 13 ++++ src/main/java/duke/command/ListCommand.java | 19 ++++++ src/main/java/duke/command/PrintCommand.java | 24 +++++++ src/main/java/duke/task/Deadline.java | 26 ++++++++ src/main/java/duke/task/Event.java | 27 ++++++++ src/main/java/duke/task/Task.java | 45 +++++++++++++ src/main/java/duke/task/TaskType.java | 16 +++++ src/main/java/duke/task/TaskWithDateTime.java | 38 +++++++++++ src/main/java/duke/task/ToDo.java | 19 ++++++ 22 files changed, 551 insertions(+), 4 deletions(-) diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index fbdc0b3e76..6bc85ada50 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -4,12 +4,20 @@ import java.io.IOException; +/** + * The driver class that runs the program + */ public class Duke { private Ui ui; private Parser parser; private Storage storage; private TaskList taskList; + /** + * Initializes an instance of Duke class. + * @param pathName Folder name of the storage file + * @param fileName Name of the storage file + */ public Duke(String pathName, String fileName) { ui = new Ui(); parser = new Parser(); @@ -23,10 +31,17 @@ public Duke(String pathName, String fileName) { } } + /** + * Starts the execution of the program. + * @param args Command line arguments + */ public static void main(String[] args) { new Duke("data", "tasks.txt").run(); } + /** + * Executes the program. + */ public void run() { ui.displayWelcome(); boolean isExit = false; diff --git a/src/main/java/duke/DukeException.java b/src/main/java/duke/DukeException.java index 3c1763dfd2..27ac300f88 100644 --- a/src/main/java/duke/DukeException.java +++ b/src/main/java/duke/DukeException.java @@ -1,6 +1,13 @@ package duke; +/** + * A class to handle any exceptions during the program execution + */ public class DukeException extends Exception { + /** + * Initializes and instance of DukeException class. + * @param errorMessage The error message. + */ public DukeException(String errorMessage) { super(errorMessage); } diff --git a/src/main/java/duke/Parser.java b/src/main/java/duke/Parser.java index 3be840116a..ed2049f930 100644 --- a/src/main/java/duke/Parser.java +++ b/src/main/java/duke/Parser.java @@ -10,7 +10,17 @@ import duke.command.ListCommand; import duke.command.PrintCommand; +/** + * A class that contaisn methods to parse command line strings + */ public class Parser { + /** + * Parses a command line string input on screen to get the details + * of the Command object + * @param commandLine The command line string to parse + * @return The Command object + * @throws DukeException If the command line string is not valid + */ public Command parse(String commandLine) throws DukeException { String[] commandLineParts = commandLine.split("\\s+", 2); @@ -74,6 +84,12 @@ public Command parse(String commandLine) throws DukeException { return command; } + /** + * Gets task number from the command information. + * @param commandInfo The command information + * @return The task number + * @throws DukeException If the information is not valid + */ private int getTaskNumFromCommand(String commandInfo) throws DukeException { if (commandInfo.trim().length() > 0) { try { @@ -86,6 +102,12 @@ private int getTaskNumFromCommand(String commandInfo) throws DukeException { } } + /** + * Gets task description from ToDo command information. + * @param commandInfo The ToDo command information + * @return The task description + * @throws DukeException If the information is not valid + */ private String getTaskDescriptionFromToDoCommand(String commandInfo) throws DukeException { if (commandInfo.trim().length() > 0) { return commandInfo; @@ -94,6 +116,12 @@ private String getTaskDescriptionFromToDoCommand(String commandInfo) throws Duke } } + /** + * + * @param commandInfo + * @return + * @throws DukeException + */ private String getTaskInfoFromDeadlineCommand(String commandInfo) throws DukeException { if (commandInfo.trim().length() > 0) { String[] deadlineTaskDetails = commandInfo.split("/", 2); @@ -160,6 +188,12 @@ private String getTaskInfoFromDeadlineCommand(String commandInfo) throws DukeExc } } + /** + * + * @param commandInfo + * @return + * @throws DukeException + */ private String getTaskInfoFromEventCommand(String commandInfo) throws DukeException { if (commandInfo.trim().length() > 0) { String[] eventTaskDetails = commandInfo.split("/", 2); @@ -226,6 +260,12 @@ private String getTaskInfoFromEventCommand(String commandInfo) throws DukeExcept } } + /** + * + * @param commandInfo + * @return + * @throws DukeException + */ private String getDateFromPrintCommand(String commandInfo) throws DukeException { if (commandInfo.trim().length() > 0) { if (commandInfo.trim().startsWith("/on")) { diff --git a/src/main/java/duke/Storage.java b/src/main/java/duke/Storage.java index 515cec5651..110c5394d4 100644 --- a/src/main/java/duke/Storage.java +++ b/src/main/java/duke/Storage.java @@ -13,13 +13,24 @@ import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; +import java.util.Queue; +/** + * A class that contains methods to read from and write to the storage file + */ public class Storage { private String pathName; private String fileName; private File dataDirectory; private File dataFile; + /** + * Initializes an instance of Storage class. + * @param pathName Path of the file + * @param fileName Name of the file + * @throws DukeExceptio If initializing the directory fails + * @throws IOException If initializing the file fails + */ public Storage(String pathName, String fileName) throws DukeException, IOException { this.pathName = pathName; this.fileName = fileName; @@ -27,6 +38,11 @@ public Storage(String pathName, String fileName) throws DukeException, IOExcepti dataFile = initialiseFile(dataDirectory); } + /** + * Creates the directory for the storage file if the directory does not exist. + * @return The File object + * @throws DukeException If the directory cannot be created + */ private File initialiseDirectory() throws DukeException { File directory = new File(pathName); boolean hasDirectory = directory.exists(); @@ -42,6 +58,12 @@ private File initialiseDirectory() throws DukeException { } } + /** + * Creates the storage file if it does not exist. + * @param directory The directory of the storage file + * @return The File object + * @throws IOException If the file cannot be created + */ private File initialiseFile(File directory) throws IOException { File file = new File(directory + "/" + fileName); boolean hasFile = file.exists(); @@ -57,6 +79,11 @@ private File initialiseFile(File directory) throws IOException { } } + /** + * Loads tasks from the storage file. + * @return The list of tasks + * @throws IOException If the tasks cannot be loaded + */ public TaskList loadTasksFromFile() throws IOException { TaskList taskList = new TaskList(); @@ -94,6 +121,11 @@ public TaskList loadTasksFromFile() throws IOException { return taskList; } + /** + * Saves the tasks to the storage file. + * @param taskList The list of tasks to be saved + * @throws IOException If the tasks cannot be saved + */ public void saveTasksToFile(TaskList taskList) throws IOException { FileWriter fileWriter = new FileWriter(dataFile,false); BufferedWriter bufferedWriter = new BufferedWriter(fileWriter); @@ -118,7 +150,15 @@ public void saveTasksToFile(TaskList taskList) throws IOException { bufferedWriter.close(); } - +` + /** + * Creates and returns the formatted task details to be saved. + * @param type Type of task + * @param isDone Flag to indicate if the task has been completed + * @param description The task description + * @param dateTime The date/time of the task + * @return The formatted task details + */ private String taskSaveFormat(TaskType type, boolean isDone, String description, String dateTime) { if (dateTime.equals("")) { return type.getAbbr() + " | " + (isDone ? "1" : "0") + " | " + description; diff --git a/src/main/java/duke/TaskList.java b/src/main/java/duke/TaskList.java index 36103926f5..085e0e8b63 100644 --- a/src/main/java/duke/TaskList.java +++ b/src/main/java/duke/TaskList.java @@ -5,31 +5,61 @@ import java.util.ArrayList; import java.util.List; +/** + * A class representing the task collection + */ public class TaskList { private List tasks; + /** + * Initializes an instance of TaskList class. + * Creates an ArrayList of tasks. + */ public TaskList() { tasks = new ArrayList(); } + /** + * Returns the number of tasks. + * @return The number of tasks + */ public int size() { return tasks.size(); } + /** + * Returns the Task object at a given index of the list of tasks. + * @param index The list index at which the Task has to be accessed + * @return The Task object + */ public Task get(int index) { return tasks.get(index); } + /** + * Adds a new Task + * @param task The Task to be added + */ public void add(Task task) { tasks.add(task); } + /** + * Removes a Task from the list at a given index. + * @param index The index at which the Task is to be removed + * @return The removed Task object + */ public Task remove(int index) { Task task = tasks.get(index); tasks.remove(task); return task; } + /** + * Removes a Task from the list. + * @param task The Task object to be removed + * @return The removed Task object + */ public Task remove(Task task) { tasks.remove(task); return task; diff --git a/src/main/java/duke/Ui.java b/src/main/java/duke/Ui.java index 24e2cf74e9..7e7ec4e6bb 100644 --- a/src/main/java/duke/Ui.java +++ b/src/main/java/duke/Ui.java @@ -6,7 +6,13 @@ import java.time.format.DateTimeFormatter; import java.util.Scanner; +/** + * A class that contains methods to handle i/o operations through screen + */ public class Ui { + /** + * Reads command line string from the user. + */ public String readCommand() { Scanner sc = new Scanner(System.in); System.out.println("ENTER COMMAND:"); @@ -14,11 +20,17 @@ public String readCommand() { return sc.nextLine().trim(); } + /** + * Displays goodbye message on exiting. + */ public void exit() { String message = "\t" + "Bye. Hope to see you again soon!"; displayResponse(message); } + /** + * Greets the user with a welcome message. + */ public void displayWelcome() { displayLine(); displayWelcomeMessage(); @@ -26,22 +38,36 @@ public void displayWelcome() { displayLine(); } + /** + * Displays a message with proper formatting. + * @param message Message to be displayed + */ public void displayResponse(String message) { displayLine(); System.out.println(message); } + /** + * Dis[lays an error message with proper formatting + * @param message Error message to be displayed + */ public void displayError(String message) { displayLine(); System.out.println("ERROR MESSAGE:"); System.out.println("\t" + "☹ " + message); } + /** + * Displays a line to seoarate different parts of a message + */ public void displayLine() { String horizontalLine = "____________________________________________________________"; System.out.println(horizontalLine); } + /** + * Displays welcome message with proper formatting. + */ private void displayWelcomeMessage() { String message = "\t" + "Hello! I'm duke.Duke, your Personal Assistant ChatBot." + System.lineSeparator() @@ -50,6 +76,9 @@ private void displayWelcomeMessage() { System.out.println(message); } + /** + * Displays the menu of options. + */ private void displayMenuOptions() { String format = "%-25s%s%n"; @@ -89,27 +118,52 @@ private void displayMenuOptions() { System.out.printf(format, menuOption8, menuOption8Info); } + /** + * Displays a message when a new task is added. + * @param task The task added + * @return + */ public String taskAddedMessage(Task task) { return "\t" + "Got it. I've added this task:" + System.lineSeparator() + "\t\t" + task; } + /** + * Displays a message when a task is removed + * @param task The task removed + * @return + */ public String taskDeletedMessage(Task task) { return "\t" + "Noted. I've removed this task:" + System.lineSeparator() + "\t\t" + task; } + /** + * Displays a message when a task has been executed. + * @param task The task executed + * @return + */ public String taskDoneMessage(Task task) { return "\t" + "Nice! I've marked this task as done:" + System.lineSeparator() + "\t\t" + task; } + /** + * Gets a message containing the number of tasks. + * @param taskList List of tasks + * @return a string containing size of the list of tasks. + */ public String getNumOfTasksInList(TaskList taskList) { return "\t" + "Now you have " + taskList.size() + (taskList.size() > 1 ? " tasks" : " task") + " in the list."; } + /** + * Gets a message containing the list of tasks. + * @param taskList List of tasks + * @return a string containing the list of tasks + */ public String getTasksInList(TaskList taskList) { StringBuilder response = new StringBuilder("\t" + "Here are the tasks in your list:" + System.lineSeparator() @@ -129,6 +183,12 @@ public String getTasksInList(TaskList taskList) { return response.toString(); } + /** + * Gets a message containing the list of tasks on a specified date. + * @param dateStr The date corresponding which the tasks have to be found. + * @param taskList List of all tasks + * @return a string containing the list of tasks on the given date + */ public String getTasksOnDate(String dateStr, TaskList taskList) { TaskList taskOnDateList = new TaskList(); @@ -163,6 +223,11 @@ public String getTasksOnDate(String dateStr, TaskList taskList) { return response.toString(); } + /** + * Converts a given date from local format to "mmm d yyyy" format. + * @param dateStr A string containing date in local format + * @return A string containing date in "mmm d yyyy" format + */ private String processDateStr(String dateStr) { LocalDate date; String processedDateStr; diff --git a/src/main/java/duke/command/AddCommand.java b/src/main/java/duke/command/AddCommand.java index 94563aa171..1d5faf7c7d 100644 --- a/src/main/java/duke/command/AddCommand.java +++ b/src/main/java/duke/command/AddCommand.java @@ -4,18 +4,37 @@ import duke.TaskList; import duke.Ui; +/** + * An abstract class to represent add command operation + */ public abstract class AddCommand extends Command { private String taskDescription; + /** + * Initializes the instance of AddCommand with task type and description. + * @param type Type of task + * @param taskDescription: Task description + */ public AddCommand(String type, String taskDescription) { super(type); this.taskDescription = taskDescription; } + /** + * Returns task description. + * @return Task description + */ public String getTaskDescription() { return taskDescription; } + /** + * An abstract method to execute an AddCommand task. + * The method will be implemented in the derived classes. + * @param taskList List of tasks + * @param ui An instance of a class to handle i/o operations + * @param storage An instance of a class to read from and write to file + */ @Override public abstract void execute(TaskList taskList, Ui ui, Storage storage); } diff --git a/src/main/java/duke/command/AddDeadlineCommand.java b/src/main/java/duke/command/AddDeadlineCommand.java index 5d61fda0fd..14005c505b 100644 --- a/src/main/java/duke/command/AddDeadlineCommand.java +++ b/src/main/java/duke/command/AddDeadlineCommand.java @@ -10,9 +10,17 @@ import java.io.IOException; +/** + * A class that contains methods to add a Deadline command + */ public class AddDeadlineCommand extends AddCommand { private String taskDateTime; + /** + * Initializes an instance of AddDeadlineCommand class. + * @param type Type of task + * @param taskInfo Further information about the task + */ public AddDeadlineCommand(String type, String taskInfo) { super(type, taskInfo.split("/", 2)[0].trim()); @@ -20,6 +28,12 @@ public AddDeadlineCommand(String type, String taskInfo) { taskDateTime = taskByDateTime.split("\\s+", 2)[1].trim(); } + /** + * Executes the task + * @param taskList List of tasks + * @param ui An object to handle i/o operations through screen + * @param storage An object to read from and write to file + */ @Override public void execute(TaskList taskList, Ui ui, Storage storage) { try { @@ -30,6 +44,12 @@ public void execute(TaskList taskList, Ui ui, Storage storage) { } } + /** + * + * @param taskList List of tasks + * @param ui An object to handle i/o operations through screen + * @throws DukeException Any exception found + */ public void addDeadlineTask(TaskList taskList, Ui ui) throws DukeException { Task newDeadlineTask = new Deadline(TaskType.DEADLINE, super.getTaskDescription(), taskDateTime); taskList.add(newDeadlineTask); diff --git a/src/main/java/duke/command/AddEventCommand.java b/src/main/java/duke/command/AddEventCommand.java index 77868bc835..5d6eea2884 100644 --- a/src/main/java/duke/command/AddEventCommand.java +++ b/src/main/java/duke/command/AddEventCommand.java @@ -10,9 +10,17 @@ import java.io.IOException; +/** + * A class that contains methods to add Event tasks + */ public class AddEventCommand extends AddCommand { private String taskDateTime; + /** + * Initializes an instance of AddEventCommand class + * @param type Type of task + * @param taskInfo Further information about the task + */ public AddEventCommand(String type, String taskInfo) { super(type, taskInfo.split("/", 2)[0].trim()); @@ -20,6 +28,12 @@ public AddEventCommand(String type, String taskInfo) { taskDateTime = taskAtDateTime.split("\\s+", 2)[1].trim(); } + /** + * Executes an Event task + * @param taskList List of tasks + * @param ui An object to handle i/o operations through screen + * @param storage An object to read from and write to file + */ @Override public void execute(TaskList taskList, Ui ui, Storage storage) { try { @@ -30,6 +44,12 @@ public void execute(TaskList taskList, Ui ui, Storage storage) { } } + /** + * Adds an Event task + * @param taskList List of tasks + * @param ui An object to handle i/o operations through screen + * @throws DukeException Any exception + */ public void addEventTask(TaskList taskList, Ui ui) throws DukeException { Task newEventTask = new Event(TaskType.EVENT, super.getTaskDescription(), taskDateTime); taskList.add(newEventTask); diff --git a/src/main/java/duke/command/AddToDoCommand.java b/src/main/java/duke/command/AddToDoCommand.java index 01ff2c7f42..a6e23164cc 100644 --- a/src/main/java/duke/command/AddToDoCommand.java +++ b/src/main/java/duke/command/AddToDoCommand.java @@ -10,11 +10,26 @@ import java.io.IOException; +/** + * A class that contains methods to add ToDo tasks to task list and a storage file. + */ public class AddToDoCommand extends AddCommand { + /** + * Initializes an instance of AddToDoComman task. + * @param type Type of task + * @param taskDescription Task description + */ public AddToDoCommand(String type, String taskDescription) { super(type, taskDescription); } + /** + * Executes the operation of adding a new ToDo task to the list and + * saving it to the file. + * @param taskList The task list + * @param ui An object to handle i/o operations through screen + * @param storage An object to read from and write to storage file. + */ @Override public void execute(TaskList taskList, Ui ui, Storage storage) { try { @@ -25,6 +40,12 @@ public void execute(TaskList taskList, Ui ui, Storage storage) { } } + /** + * Creates a new ToDo task and adds it to the task list. + * @param taskList The task list + * @param ui An object to handle i/o operations through screen + * @throws DukeException If a new ToDo task cannot be created + */ public void addToDoTask(TaskList taskList, Ui ui) throws DukeException { Task newToDoTask = new ToDo(TaskType.TODO, super.getTaskDescription()); taskList.add(newToDoTask); diff --git a/src/main/java/duke/command/Command.java b/src/main/java/duke/command/Command.java index 8e8a98c22c..99b7f178cb 100644 --- a/src/main/java/duke/command/Command.java +++ b/src/main/java/duke/command/Command.java @@ -4,9 +4,12 @@ import duke.TaskList; import duke.Ui; +/** + * An abstract class representing the command. + */ public abstract class Command { - private String type; - private boolean isExit; + private String type; // Type of command + private boolean isExit; // If the user wants to exit public Command(String type) { this.type = type; diff --git a/src/main/java/duke/command/DeleteCommand.java b/src/main/java/duke/command/DeleteCommand.java index 11c751f0ee..7fc9ce055b 100644 --- a/src/main/java/duke/command/DeleteCommand.java +++ b/src/main/java/duke/command/DeleteCommand.java @@ -8,14 +8,28 @@ import java.io.IOException; +/** + * A class that contaisn methods to delete a task + */ public class DeleteCommand extends Command { private int taskNum; + /** + * Initializes an instance of DeleteCommand class with task type and task number. + * @param type Task type + * @param taskNum Task number + */ public DeleteCommand(String type, int taskNum) { super(type); this.taskNum = taskNum; } + /** + * Executes deleting the task from the task list, and updating the storage file. + * @param taskList The task list + * @param ui An object to handle i/o operations through screen + * @param storage An object to read from and write to storage file + */ @Override public void execute(TaskList taskList, Ui ui, Storage storage) { try { @@ -26,6 +40,12 @@ public void execute(TaskList taskList, Ui ui, Storage storage) { } } + /** + * Deletes a task from the task list. + * @param taskList The task list + * @param ui An object to handle i/o operations through screen + * @throws DukeException If the task number is not valid + */ public void deleteTask(TaskList taskList, Ui ui) throws DukeException { if (taskNum > 0 && taskNum <= taskList.size()) { Task taskDeleted = taskList.remove(taskNum - 1); @@ -37,4 +57,4 @@ public void deleteTask(TaskList taskList, Ui ui) throws DukeException { throw new DukeException("Task not found. Please try again!"); } } -} +} \ No newline at end of file diff --git a/src/main/java/duke/command/DoneCommand.java b/src/main/java/duke/command/DoneCommand.java index f160d8d8f7..7199e94375 100644 --- a/src/main/java/duke/command/DoneCommand.java +++ b/src/main/java/duke/command/DoneCommand.java @@ -8,14 +8,28 @@ import java.io.IOException; +/** + * A class that contains methods to handle Done command + */ public class DoneCommand extends Command { private int taskNum; + /** + * Initializes an instanceof Done class with task type and task number. + * @param type Type of task + * @param taskNum Task number + */ public DoneCommand(String type, int taskNum) { super(type); this.taskNum = taskNum; } + /** + * Executes the command of marking a task done, and updates the storage file. + * @param taskList The task list + * @param ui An object to handle i/o operations through screen + * @param storage An object to read from and write to storage file + */ @Override public void execute(TaskList taskList, Ui ui, Storage storage) { try { @@ -26,6 +40,12 @@ public void execute(TaskList taskList, Ui ui, Storage storage) { } } + /** + * Marks the task as done. + * @param taskList The task list + * @param ui An object to handle i/o operations through screen + * @throws DukeException If the task number is not valid + */ public void markDone(TaskList taskList, Ui ui) throws DukeException { if (taskNum > 0 && taskNum <= taskList.size()) { Task taskDone = taskList.get(taskNum - 1); diff --git a/src/main/java/duke/command/ExitCommand.java b/src/main/java/duke/command/ExitCommand.java index 7a50222f26..807a918c92 100644 --- a/src/main/java/duke/command/ExitCommand.java +++ b/src/main/java/duke/command/ExitCommand.java @@ -4,11 +4,24 @@ import duke.TaskList; import duke.Ui; +/** + * A class to handle clean up operations on exiting the program + */ public class ExitCommand extends Command { + /** + * Initializes an instance of ExitCommand class. + * @param type Type of command (Exit) + */ public ExitCommand(String type) { super(type); } + /** + * Executes clean up operations on exiting the program. + * @param taskList The task list + * @param ui An object to handle i/o operations through screen + * @param storage An object to read from and write to storage file + */ @Override public void execute(TaskList taskList, Ui ui, Storage storage) { setExit(); diff --git a/src/main/java/duke/command/ListCommand.java b/src/main/java/duke/command/ListCommand.java index 8a766bcf8e..fdb93d7a1a 100644 --- a/src/main/java/duke/command/ListCommand.java +++ b/src/main/java/duke/command/ListCommand.java @@ -5,11 +5,24 @@ import duke.TaskList; import duke.Ui; +/** + * A class to handle the command of listing the tasks + */ public class ListCommand extends Command { + /** + * Initializes an instance of ListCommand class. + * @param type Type of task (List) + */ public ListCommand(String type) { super(type); } + /** + * Executes the command of listing the tasks. + * @param taskList The task list + * @param ui An object to handle i/o operations through screen + * @param storage An object to read from and write to the storage file + */ @Override public void execute(TaskList taskList, Ui ui, Storage storage) { try { @@ -19,6 +32,12 @@ public void execute(TaskList taskList, Ui ui, Storage storage) { } } + /** + * Displays the tasks in proper format. + * @param taskList The task list + * @param ui An object to handle i/o operations through screen + * @throws DukeException If the task list is empty + */ public void displayTasksList(TaskList taskList, Ui ui) throws DukeException { if (taskList.size() != 0) { String response = ui.getTasksInList(taskList); diff --git a/src/main/java/duke/command/PrintCommand.java b/src/main/java/duke/command/PrintCommand.java index 6da46261d8..04bef46ca8 100644 --- a/src/main/java/duke/command/PrintCommand.java +++ b/src/main/java/duke/command/PrintCommand.java @@ -5,18 +5,36 @@ import duke.TaskList; import duke.Ui; +/** + * A class to handle print command to print tasks corresponding to a given date. + */ public class PrintCommand extends Command { private String date; + /** + * Initializes an instance of PrintCommand class. + * @param type Type of command + * @param date The specified date + */ public PrintCommand(String type, String date) { super(type); this.date = date; } + /** + * Returns the specified date correspondign to which the tasks are to be printed + * @return The specified date + */ public String getDate() { return date; } + /** + * Executes the command of printing tasks corresponding to the given date. + * @param taskList The task list + * @param ui An object to handle i/o operations through screen + * @param storage An object to read from and write to the storage file + */ @Override public void execute(TaskList taskList, Ui ui, Storage storage) { try { @@ -26,6 +44,12 @@ public void execute(TaskList taskList, Ui ui, Storage storage) { } } + /** + * Prints tasks corresponding to the given date. + * @param taskList The task list + * @param ui An object to handle i/o operations through screen + * @throws DukeException If no task on the given date is found + */ public void printTasksOnDate(TaskList taskList, Ui ui) throws DukeException { if (taskList.size() != 0) { String response = ui.getTasksOnDate(date, taskList); diff --git a/src/main/java/duke/task/Deadline.java b/src/main/java/duke/task/Deadline.java index c96d1d10ad..6f5996e2bb 100644 --- a/src/main/java/duke/task/Deadline.java +++ b/src/main/java/duke/task/Deadline.java @@ -1,19 +1,45 @@ package duke.task; +/** + * A class to handle Deadline tasks + */ public class Deadline extends TaskWithDateTime { + /** + * Initializes an instance of Deadline class with task type, task description, + * and the date/time by which the task has to be completed. + * @param type Type of task + * @param description Task description + * @param dateTimeInput Date/time by whuch the tas has to be completed + */ public Deadline(TaskType type, String description, String dateTimeInput) { super(type, description, dateTimeInput); } + /** + * Initializes an instance of Deadline class with task type, task description, + * date/time by which the task has to be completed and whether the task has been done. + * @param type Type of task + * @param description Task description + * @param dateTimeInput Date/time by whuch the tas has to be completed + * @param isDone A flag to indicate if the task has been done + */ public Deadline(TaskType type, String description, String dateTimeInput, boolean isDone) { super(type, description, dateTimeInput, isDone); } + /** + * Gets the date/time information by which the task is to be completed. + * @return Date/time information + */ @Override public String dateTimeInfo() { return "(by: " + super.getDateTimeOutput() + ")"; } + /** + * Gets a string representation of the task. + * @return A string representation of the task + */ @Override public String toString() { return "[" + TaskType.DEADLINE.getAbbr() + "] " + super.toString(); diff --git a/src/main/java/duke/task/Event.java b/src/main/java/duke/task/Event.java index 6fe37aa42b..1c92f5443c 100644 --- a/src/main/java/duke/task/Event.java +++ b/src/main/java/duke/task/Event.java @@ -1,19 +1,46 @@ package duke.task; +/** + * A class to handle Event tasks + */ public class Event extends TaskWithDateTime { + /** + * Initializes an instance of Event class with task type, description, + * and the date/time at which the task is to be performed. + * @param type Type of task + * @param description Task description + * @param dateTimeInput Date/time at which the task is to be performed + */ public Event(TaskType type, String description, String dateTimeInput) { super(type, description, dateTimeInput); } + /** + * Initializes an instance of Event class with task type, description, + * date/time at which the task is to be performed and whether the task + * has been completed. + * @param type Type of task + * @param description Task description + * @param dateTimeInput Date/time at which the task is to be performed + * @param isDone A flag to indicate if the task has been completed + */ public Event(TaskType type, String description, String dateTimeInput, boolean isDone) { super(type, description, dateTimeInput, isDone); } + /** + * Gets date/time info of the task in output format. + * @return date/time info + */ @Override public String dateTimeInfo() { return "(at: " + super.getDateTimeOutput() +")"; } + /** + * Gets a string representation of a task with date/time. + * @return A string representation of the task + */ @Override public String toString() { return "[" + TaskType.EVENT.getAbbr() + "] " + super.toString(); diff --git a/src/main/java/duke/task/Task.java b/src/main/java/duke/task/Task.java index f59e90ae91..2ebbd72f6b 100644 --- a/src/main/java/duke/task/Task.java +++ b/src/main/java/duke/task/Task.java @@ -1,44 +1,89 @@ package duke.task; +/** + * An abstract class that represents tasks + */ public abstract class Task { private TaskType type; private String description; private boolean isDone; + /** + * Initializes an instance of Task class with task type and description. + * @param type Type of task + * @param description Task description + */ public Task(TaskType type, String description) { + // By default, assume that the task has not been completed. this(type, description, false); } + /** + * Initializes an instance of Task class with task type, description and + * a flag to indicate if the task has been completed. + * @param type Type of task + * @param description Task description + * @param isDone Flag to indicate if the task has been completed + */ public Task(TaskType type, String description, boolean isDone) { this.type = type; this.description = description; this.isDone = isDone; } + /** + * Gets the type of task. + * @return Type of task + */ public TaskType getType() { return type; } + /** + * Gets the task description. + * @return String containign the task description + */ public String getDescription() { return description; } + /** + * Gets a flag to indicate if the task has been completed. + * @return The boolean flag + */ public boolean isDone() { return isDone; } + /** + * Gets status icon for the task. + * @return The string representation of the status icon + */ public String getStatusIcon() { return (isDone ? "[✔]" : "[ ]"); // mark done task with ✔ } + /** + * Sets the isDone flag to true to indicate tat the task has been completed. + */ public void setDone() { this.isDone = true; } + /** + * Finds if the task is on a specified date. + * The function will be overridden in derived classes. + * @param dateStr The date by which the task is to be completed + * @return False because, by default, a task is not on a specified date + */ public boolean isOnDate(String dateStr) { return false; } + /** + * Gets a description of the task. + * @return A string containign description of the task + */ @Override public String toString() { return getStatusIcon() + " " + description; diff --git a/src/main/java/duke/task/TaskType.java b/src/main/java/duke/task/TaskType.java index c655eb9e64..5d56a87583 100644 --- a/src/main/java/duke/task/TaskType.java +++ b/src/main/java/duke/task/TaskType.java @@ -1,5 +1,8 @@ package duke.task; +/** + * An enumeration for different commands + */ public enum TaskType { TODO("todo", "T"), DEADLINE("deadline", "D"), @@ -8,15 +11,28 @@ public enum TaskType { private final String label; private final String abbr; + /** + * Initializes an instance of TaskType enumeration. + * @param label Label of the enumeration (task type) + * @param abbr Abbreviation of the enumeration (task type) + */ TaskType(String label, String abbr) { this.label = label; this.abbr = abbr; } + /** + * Gets the label of the task type. + * @return Label + */ public String getLabel() { return label; } + /** + * Gets the abbreviation of the task type. + * @return Abbreviation + */ public String getAbbr() { return abbr; } diff --git a/src/main/java/duke/task/TaskWithDateTime.java b/src/main/java/duke/task/TaskWithDateTime.java index 2c324835d5..9910961244 100644 --- a/src/main/java/duke/task/TaskWithDateTime.java +++ b/src/main/java/duke/task/TaskWithDateTime.java @@ -4,6 +4,9 @@ import java.time.LocalTime; import java.time.format.DateTimeFormatter; +/** + * A class that represents tasks on a date/time + */ public abstract class TaskWithDateTime extends Task { private String dateTimeInput; private String dateInput; @@ -12,16 +15,34 @@ public abstract class TaskWithDateTime extends Task { private LocalTime time; private String dateTimeOutput; // DateTime (of the task) to be printed + /** + * Initializes an instance of TaskWithDateTime class with task type, description, and date/time. + * @param type Type of task + * @param description Task description + * @param dateTimeInput The input date/time by which the task has to be completed + */ public TaskWithDateTime(TaskType type, String description, String dateTimeInput) { this(type, description, dateTimeInput, false); } + /** + * Initializes an instance of TaskWithDateTime class with task type, description, + * date/time, and whether the task has been completed. + * @param type Type of task + * @param description Task description + * @param dateTimeInput The input date/time by which the task has to be completed + * @param isDone A flag to indicate if the task has been completed + */ public TaskWithDateTime(TaskType type, String description, String dateTimeInput, boolean isDone) { super(type, description, isDone); this.dateTimeInput = dateTimeInput; processDateTimeInput(); } + /** + * Processes the input date/time string to find the specific details of the + * date and time of the task. + */ private void processDateTimeInput() { boolean isTimeInputProper = true; @@ -115,16 +136,29 @@ private void processDateTimeInput() { } } + /** + * Gets input date/time string. + * @return Inout date/time string + */ public String getDateTimeInput() { return dateTimeInput; } + /** + * Gets the date/time information in output format. + * @return Output date/time string + */ public String getDateTimeOutput() { return dateTimeOutput; } public abstract String dateTimeInfo(); + /** + * Finds if the date/time of a task is equal to a specified date/time. + * @param dateStr The specified date/time + * @return A flag to indicate if the date/time of the task is same as the given value + */ @Override public boolean isOnDate(String dateStr) { try { @@ -140,6 +174,10 @@ public boolean isOnDate(String dateStr) { } } + /** + * Gets a string representation of the date/time info. + * @return A string representation of the date/time info + */ @Override public String toString() { return super.toString() + " " + dateTimeInfo(); diff --git a/src/main/java/duke/task/ToDo.java b/src/main/java/duke/task/ToDo.java index a531387b28..e96ef2da92 100644 --- a/src/main/java/duke/task/ToDo.java +++ b/src/main/java/duke/task/ToDo.java @@ -1,14 +1,33 @@ package duke.task; +/** + * A class that represents to do tasks + */ public class ToDo extends Task { + /** + * Initializes an instance of ToDo class with task type and description. + * @param type Type of task + * @param description Task description + */ public ToDo(TaskType type, String description) { super(type, description); } + /** + * Initializes an instance of ToDo class with task type, description and + * whether the task has been completed. + * @param type Type of task + * @param description Task description + * @param isDone A flag to indicate if the task has been completed + */ public ToDo(TaskType type, String description, boolean isDone) { super(type, description, isDone); } + /** + * Gets a string representation of the ToDo task. + * @return A string representation of the ToDo task. + */ @Override public String toString() { return "[" + TaskType.TODO.getAbbr() + "] " + super.toString(); From 483a8112cfab044a352d06917af98d0425101611 Mon Sep 17 00:00:00 2001 From: dannytayjy Date: Thu, 9 Sep 2021 19:51:13 +0800 Subject: [PATCH 15/16] Update Ui.java to amend String in displayWelcomeMessage --- src/main/java/duke/Ui.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/duke/Ui.java b/src/main/java/duke/Ui.java index 24e2cf74e9..0f1b140486 100644 --- a/src/main/java/duke/Ui.java +++ b/src/main/java/duke/Ui.java @@ -43,7 +43,7 @@ public void displayLine() { } private void displayWelcomeMessage() { - String message = "\t" + "Hello! I'm duke.Duke, your Personal Assistant ChatBot." + String message = "\t" + "Hello! I'm Duke, your Personal Assistant ChatBot." + System.lineSeparator() + "\t" + "What can I do for you?" + System.lineSeparator(); From 4fa286f3ee88ea9d967784b5b4d0b7b8af147deb Mon Sep 17 00:00:00 2001 From: dannytayjy Date: Thu, 16 Sep 2021 17:19:22 +0800 Subject: [PATCH 16/16] Add JUnit tests --- src/test/java/duke/DukeTest.java | 4 ++++ src/test/java/task/DeadlineTest.java | 19 +++++++++++++++++++ src/test/java/task/EventTest.java | 16 ++++++++++++++++ src/test/java/task/ToDoTest.java | 16 ++++++++++++++++ 4 files changed, 55 insertions(+) create mode 100644 src/test/java/duke/DukeTest.java create mode 100644 src/test/java/task/DeadlineTest.java create mode 100644 src/test/java/task/EventTest.java create mode 100644 src/test/java/task/ToDoTest.java diff --git a/src/test/java/duke/DukeTest.java b/src/test/java/duke/DukeTest.java new file mode 100644 index 0000000000..7e6f6756cb --- /dev/null +++ b/src/test/java/duke/DukeTest.java @@ -0,0 +1,4 @@ +package duke; + +public class DukeTest { +} diff --git a/src/test/java/task/DeadlineTest.java b/src/test/java/task/DeadlineTest.java new file mode 100644 index 0000000000..ee4c0556a8 --- /dev/null +++ b/src/test/java/task/DeadlineTest.java @@ -0,0 +1,19 @@ +package task; + +import duke.task.Deadline; +import duke.task.Task; +import duke.task.TaskType; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class DeadlineTest { + @Test + public void toStringTest() { + Task deadlineOne = new Deadline(TaskType.DEADLINE,"CS2100 Lab 4", "2021-09-14"); + assertEquals("[D] [ ] CS2100 Lab 4 (by: Sep 14 2021)", deadlineOne.toString()); + + Task deadlineTwo = new Deadline(TaskType.DEADLINE,"CS2100 Assignment 1", "2021-09-15 1300"); + assertEquals("[D] [ ] CS2100 Assignment 1 (by: Sep 15 2021, 01:00 PM)", deadlineTwo.toString()); + } +} diff --git a/src/test/java/task/EventTest.java b/src/test/java/task/EventTest.java new file mode 100644 index 0000000000..302b73411e --- /dev/null +++ b/src/test/java/task/EventTest.java @@ -0,0 +1,16 @@ +package task; + +import duke.task.Event; +import duke.task.Task; +import duke.task.TaskType; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class EventTest { + @Test + public void toStringTest() { + Task event = new Event(TaskType.EVENT, "CS2103 tP Meeting", "2021-09-14 2100"); + assertEquals("[E] [ ] CS2103 tP Meeting (at: Sep 14 2021, 09:00 PM)", event.toString()); + } +} diff --git a/src/test/java/task/ToDoTest.java b/src/test/java/task/ToDoTest.java new file mode 100644 index 0000000000..7e8a9aba97 --- /dev/null +++ b/src/test/java/task/ToDoTest.java @@ -0,0 +1,16 @@ +package task; + +import duke.task.Task; +import duke.task.TaskType; +import duke.task.ToDo; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class ToDoTest { + @Test + public void toStringTest() { + Task toDo = new ToDo(TaskType.TODO,"Vacuum room floor"); + assertEquals("[T] [ ] Vacuum room floor", toDo.toString()); + } +}