From ed3efe1f97da730965a4659f0349a7ec949328d4 Mon Sep 17 00:00:00 2001 From: aaronxujiachen <1943999635x@gmail.com> Date: Tue, 22 Aug 2023 18:27:33 +0800 Subject: [PATCH 01/23] Add Dude Level 0 --- src/main/java/Duke.java | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 5d313334c..f054cd699 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,10 +1,33 @@ public class Duke { - public static void main(String[] args) { - String logo = " ____ _ \n" - + "| _ \\ _ _| | _____ \n" - + "| | | | | | | |/ / _ \\\n" - + "| |_| | |_| | < __/\n" - + "|____/ \\__,_|_|\\_\\___|\n"; + + public static void drawLine() { // Draw horizontal lines + for (int i = 0; i < 30; i++) { + System.out.print("_"); + } + System.out.println(); + } + + public static void hiDude() { // Print logo and hello message + String logo = "### # \n" + + "# # # \n" + + "# # # # ### ## \n" + + "# # # # # # # ## \n" + + "# # # # # # ## \n" + + "### ### ### ## \n"; System.out.println("Hello from\n" + logo); + drawLine(); + System.out.println("Hello! I'm your best Dude"); + System.out.println("What can I do for you?"); + drawLine(); + } + + public static void byeDude() { // Print goodbye message + System.out.println("Bye. Hope to see you again soon!"); + drawLine(); + } + + public static void main(String[] args) { + hiDude(); + byeDude(); } } From c6302e9f2b7f829ec4087163c40fa9bc975a4697 Mon Sep 17 00:00:00 2001 From: aaronxujiachen <1943999635x@gmail.com> Date: Sat, 2 Sep 2023 11:55:30 +0800 Subject: [PATCH 02/23] Add Dude Level 1 --- src/main/java/Duke.java | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index f054cd699..c9e4e0dc4 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,3 +1,4 @@ +import java.util.Scanner; public class Duke { public static void drawLine() { // Draw horizontal lines @@ -16,11 +17,28 @@ public static void hiDude() { // Print logo and hello message + "### ### ### ## \n"; System.out.println("Hello from\n" + logo); drawLine(); - System.out.println("Hello! I'm your best Dude"); + System.out.println("Hello! I'm your best Dude."); System.out.println("What can I do for you?"); drawLine(); } + public static void echoDude() { // Echo the input + Scanner scan = new Scanner(System.in); + String echo = null; + + while(true) { + echo = scan.nextLine(); + drawLine(); + if(echo.equals("bye")) { + byeDude(); + break; + } else { + System.out.println(echo); + drawLine(); + } + } + } + public static void byeDude() { // Print goodbye message System.out.println("Bye. Hope to see you again soon!"); drawLine(); @@ -28,6 +46,6 @@ public static void byeDude() { // Print goodbye message public static void main(String[] args) { hiDude(); - byeDude(); + echoDude(); } } From 8d766a72234cc0433edf0b8c2e988bc032a87233 Mon Sep 17 00:00:00 2001 From: aaronxujiachen <1943999635x@gmail.com> Date: Sat, 2 Sep 2023 12:16:18 +0800 Subject: [PATCH 03/23] Add Dude Level 2 --- src/main/java/Duke.java | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index c9e4e0dc4..d1c06ab8e 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -17,23 +17,34 @@ public static void hiDude() { // Print logo and hello message + "### ### ### ## \n"; System.out.println("Hello from\n" + logo); drawLine(); - System.out.println("Hello! I'm your best Dude."); + System.out.println("Hello! I'm your best Dude:)"); System.out.println("What can I do for you?"); drawLine(); } - public static void echoDude() { // Echo the input + public static void storeDude() { // Add and list some tasks Scanner scan = new Scanner(System.in); - String echo = null; + String input = null; + String[] list = new String[100]; + int curPos = 0; // Initialise current position + int index = 1; // Set index for the list while(true) { - echo = scan.nextLine(); + input = scan.nextLine(); drawLine(); - if(echo.equals("bye")) { + if(input.equals("bye")) { byeDude(); break; + } else if(input.equals("list")) { + for(int i = 0; i < curPos; i++) { + System.out.println(index + ". " + list[index-1]); + index++; + } + drawLine(); } else { - System.out.println(echo); + list[curPos] = input; + curPos++; + System.out.println("added: " + input); drawLine(); } } @@ -46,6 +57,6 @@ public static void byeDude() { // Print goodbye message public static void main(String[] args) { hiDude(); - echoDude(); + storeDude(); } } From 6eb2ef3d248a1a501210024db37495fadced0b1a Mon Sep 17 00:00:00 2001 From: aaronxujiachen <1943999635x@gmail.com> Date: Sat, 2 Sep 2023 13:21:42 +0800 Subject: [PATCH 04/23] Add Dude Level 3 --- src/main/java/Duke.java | 64 ++++++++++++++++++++++++++++------------- src/main/java/Task.java | 13 +++++++++ 2 files changed, 57 insertions(+), 20 deletions(-) create mode 100644 src/main/java/Task.java diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index d1c06ab8e..41b839800 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,14 +1,16 @@ +import java.util.ArrayList; import java.util.Scanner; + public class Duke { - public static void drawLine() { // Draw horizontal lines + public static void drawLine() { for (int i = 0; i < 30; i++) { System.out.print("_"); } System.out.println(); } - public static void hiDude() { // Print logo and hello message + public static void hiDude() { String logo = "### # \n" + "# # # \n" + "# # # # ### ## \n" @@ -17,40 +19,62 @@ public static void hiDude() { // Print logo and hello message + "### ### ### ## \n"; System.out.println("Hello from\n" + logo); drawLine(); - System.out.println("Hello! I'm your best Dude:)"); + System.out.println("Hello! I'm your best Dude :)"); System.out.println("What can I do for you?"); drawLine(); } - public static void storeDude() { // Add and list some tasks + public static void storeDude() { Scanner scan = new Scanner(System.in); - String input = null; - String[] list = new String[100]; - int curPos = 0; // Initialise current position - int index = 1; // Set index for the list + String input = scan.nextLine(); + ArrayList tasks = new ArrayList<>(); + int curPos = 0; - while(true) { - input = scan.nextLine(); + while (!(input.isEmpty())) { drawLine(); - if(input.equals("bye")) { + if (input.equals("bye")) { byeDude(); break; - } else if(input.equals("list")) { - for(int i = 0; i < curPos; i++) { - System.out.println(index + ". " + list[index-1]); - index++; + } else if (input.equals("list")) { + System.out.println("Here are the tasks in your list:"); + for (int i = 0; i < curPos; i++) { + System.out.println((i + 1) + ". " + tasks.get(i).getStatusIcon() + " " + tasks.get(i).description); + } + } else if (input.startsWith("mark") || input.startsWith("unmark")) { + String[] arrOfInput = input.split(" ", 2); + if (arrOfInput.length < 2) { + System.out.println("Please specify the task index."); + } else { + try { + int index = Integer.parseInt(arrOfInput[1]) - 1; + if (index < 0 || index >= curPos) { + System.out.println("Task index out of range."); + } else { + if (input.startsWith("mark")) { + tasks.get(index).isDone = true; + System.out.println("Nice! I've marked this task as done:"); + } else { + tasks.get(index).isDone = false; + System.out.println("OK, I've marked this task as not done yet:"); + } + System.out.println(" " + tasks.get(index).getStatusIcon() + " " + tasks.get(index).description); + } + } catch (NumberFormatException e) { + System.out.println("Invalid task index format."); + } } - drawLine(); } else { - list[curPos] = input; - curPos++; System.out.println("added: " + input); - drawLine(); + tasks.add(new Task(input)); + curPos++; } + drawLine(); + input = scan.nextLine(); } + scan.close(); } - public static void byeDude() { // Print goodbye message + public static void byeDude() { System.out.println("Bye. Hope to see you again soon!"); drawLine(); } diff --git a/src/main/java/Task.java b/src/main/java/Task.java new file mode 100644 index 000000000..1aecde62c --- /dev/null +++ b/src/main/java/Task.java @@ -0,0 +1,13 @@ +public class Task { + protected String description; + protected boolean isDone; // protected => public + + public Task(String description) { + this.description = description; + this.isDone = false; + } + + public String getStatusIcon() { + return (isDone ? "[X]" : "[ ]"); // mark done task with X + } +} From 2cf44fb75b40bba16500f056170ecf035765b9f4 Mon Sep 17 00:00:00 2001 From: aaronxujiachen <1943999635x@gmail.com> Date: Sat, 2 Sep 2023 18:09:56 +0800 Subject: [PATCH 05/23] Tweak the code to comply with coding standard --- src/main/java/Duke.java | 26 ++++++++++++++++++-------- src/main/java/Task.java | 8 ++++++-- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 41b839800..bea61771b 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -3,6 +3,7 @@ public class Duke { + // Method to draw horizontal lines public static void drawLine() { for (int i = 0; i < 30; i++) { System.out.print("_"); @@ -10,13 +11,16 @@ public static void drawLine() { System.out.println(); } + // Method to print the logo and introductory message public static void hiDude() { + // Logo string String logo = "### # \n" + "# # # \n" + "# # # # ### ## \n" + "# # # # # # # ## \n" + "# # # # # # ## \n" + "### ### ### ## \n"; + System.out.println("Hello from\n" + logo); drawLine(); System.out.println("Hello! I'm your best Dude :)"); @@ -24,12 +28,15 @@ public static void hiDude() { drawLine(); } + // Method to handle the storage of tasks public static void storeDude() { + // Initialize Scanner and ArrayList for tasks Scanner scan = new Scanner(System.in); String input = scan.nextLine(); ArrayList tasks = new ArrayList<>(); - int curPos = 0; + int curPos = 0; // Variable to keep track of the current task position + // Main loop to process commands while (!(input.isEmpty())) { drawLine(); if (input.equals("bye")) { @@ -41,22 +48,21 @@ public static void storeDude() { System.out.println((i + 1) + ". " + tasks.get(i).getStatusIcon() + " " + tasks.get(i).description); } } else if (input.startsWith("mark") || input.startsWith("unmark")) { + // Split the input to separate command and task index String[] arrOfInput = input.split(" ", 2); if (arrOfInput.length < 2) { System.out.println("Please specify the task index."); } else { try { + // Convert user input index to zero-based index for ArrayList int index = Integer.parseInt(arrOfInput[1]) - 1; if (index < 0 || index >= curPos) { System.out.println("Task index out of range."); } else { - if (input.startsWith("mark")) { - tasks.get(index).isDone = true; - System.out.println("Nice! I've marked this task as done:"); - } else { - tasks.get(index).isDone = false; - System.out.println("OK, I've marked this task as not done yet:"); - } + // Mark or unmark the task + tasks.get(index).isDone = input.startsWith("mark"); + String message = input.startsWith("mark") ? "Nice! I've marked this task as done:" : "OK, I've marked this task as not done yet:"; + System.out.println(message); System.out.println(" " + tasks.get(index).getStatusIcon() + " " + tasks.get(index).description); } } catch (NumberFormatException e) { @@ -64,6 +70,7 @@ public static void storeDude() { } } } else { + // Add new task System.out.println("added: " + input); tasks.add(new Task(input)); curPos++; @@ -71,14 +78,17 @@ public static void storeDude() { drawLine(); input = scan.nextLine(); } + // Close the Scanner to prevent resource leak scan.close(); } + // Method to print the goodbye message public static void byeDude() { System.out.println("Bye. Hope to see you again soon!"); drawLine(); } + // Main method public static void main(String[] args) { hiDude(); storeDude(); diff --git a/src/main/java/Task.java b/src/main/java/Task.java index 1aecde62c..662995228 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -1,13 +1,17 @@ public class Task { + // Instance variables to store task description and status protected String description; - protected boolean isDone; // protected => public + protected boolean isDone; + // Constructor to initialize a task with a description public Task(String description) { this.description = description; this.isDone = false; } + // Method to get the status icon based on whether the task is done or not public String getStatusIcon() { - return (isDone ? "[X]" : "[ ]"); // mark done task with X + return (isDone ? "[X]" : "[ ]"); } } + From 79f86edf38b389e7f011e846bde67546620ff58f Mon Sep 17 00:00:00 2001 From: aaronxujiachen <1943999635x@gmail.com> Date: Sat, 9 Sep 2023 13:01:23 +0800 Subject: [PATCH 06/23] Add Dude Level 4 --- src/main/java/Deadline.java | 15 +++++++++++ src/main/java/Duke.java | 50 +++++++++++++++++++++++++------------ src/main/java/Event.java | 17 +++++++++++++ src/main/java/Task.java | 12 ++++++++- 4 files changed, 77 insertions(+), 17 deletions(-) create mode 100644 src/main/java/Deadline.java create mode 100644 src/main/java/Event.java diff --git a/src/main/java/Deadline.java b/src/main/java/Deadline.java new file mode 100644 index 000000000..1aeb77be0 --- /dev/null +++ b/src/main/java/Deadline.java @@ -0,0 +1,15 @@ +public class Deadline extends Task { + String by; + + // Constructor to initialize a deadline with a description and a due date + public Deadline(String description, String by) { + super(description); + this.by = by; + this.type = "[D]"; // Type [D] indicates this is a Deadline + } + + @Override + public String toString() { + return getType() + getStatusIcon() + " " + description + " (by: " + by + ")"; + } +} diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index bea61771b..e292dd368 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -13,7 +13,6 @@ public static void drawLine() { // Method to print the logo and introductory message public static void hiDude() { - // Logo string String logo = "### # \n" + "# # # \n" + "# # # # ### ## \n" @@ -30,40 +29,60 @@ public static void hiDude() { // Method to handle the storage of tasks public static void storeDude() { - // Initialize Scanner and ArrayList for tasks Scanner scan = new Scanner(System.in); - String input = scan.nextLine(); ArrayList tasks = new ArrayList<>(); - int curPos = 0; // Variable to keep track of the current task position - // Main loop to process commands - while (!(input.isEmpty())) { + String input = scan.nextLine(); + while (!input.isEmpty()) { drawLine(); + if (input.equals("bye")) { byeDude(); break; } else if (input.equals("list")) { System.out.println("Here are the tasks in your list:"); - for (int i = 0; i < curPos; i++) { - System.out.println((i + 1) + ". " + tasks.get(i).getStatusIcon() + " " + tasks.get(i).description); + for (int i = 0; i < tasks.size(); i++) { + System.out.println((i + 1) + ". " + tasks.get(i)); } + } else if (input.startsWith("todo")) { + String taskDescription = input.substring(5); + tasks.add(new Task(taskDescription)); + System.out.println("Got it. I've added this task:"); + System.out.println(" " + tasks.get(tasks.size() - 1)); + System.out.println("Now you have " + tasks.size() + " tasks in the list."); + } else if (input.startsWith("deadline")) { + String taskDescription = input.substring(9, input.indexOf("/by")).trim(); + String by = input.substring(input.indexOf("/by") + 4).trim(); + tasks.add(new Deadline(taskDescription, by)); + System.out.println("Got it. I've added this task:"); + System.out.println(" " + tasks.get(tasks.size() - 1)); + System.out.println("Now you have " + tasks.size() + " tasks in the list."); + } else if (input.startsWith("event")) { + String taskDescription = input.substring(6, input.indexOf("/from")).trim(); + String from = input.substring(input.indexOf("/from") + 6, input.indexOf("/to")).trim(); + String to = input.substring(input.indexOf("/to") + 4).trim(); + tasks.add(new Event(taskDescription, from, to)); + System.out.println("Got it. I've added this task:"); + System.out.println(" " + tasks.get(tasks.size() - 1)); + System.out.println("Now you have " + tasks.size() + " tasks in the list."); } else if (input.startsWith("mark") || input.startsWith("unmark")) { - // Split the input to separate command and task index String[] arrOfInput = input.split(" ", 2); if (arrOfInput.length < 2) { System.out.println("Please specify the task index."); } else { try { - // Convert user input index to zero-based index for ArrayList int index = Integer.parseInt(arrOfInput[1]) - 1; - if (index < 0 || index >= curPos) { + if (index < 0 || index >= tasks.size()) { // Here, replace curPos with tasks.size() System.out.println("Task index out of range."); } else { - // Mark or unmark the task tasks.get(index).isDone = input.startsWith("mark"); - String message = input.startsWith("mark") ? "Nice! I've marked this task as done:" : "OK, I've marked this task as not done yet:"; + String message = input.startsWith("mark") ? + "Nice! I've marked this task as done:" : + "OK, I've marked this task as not done yet:"; System.out.println(message); - System.out.println(" " + tasks.get(index).getStatusIcon() + " " + tasks.get(index).description); + + // This line is the modified part: Using toString to print the task. + System.out.println(" " + tasks.get(index).toString()); } } catch (NumberFormatException e) { System.out.println("Invalid task index format."); @@ -73,15 +92,14 @@ public static void storeDude() { // Add new task System.out.println("added: " + input); tasks.add(new Task(input)); - curPos++; } drawLine(); input = scan.nextLine(); } - // Close the Scanner to prevent resource leak scan.close(); } + // Method to print the goodbye message public static void byeDude() { System.out.println("Bye. Hope to see you again soon!"); diff --git a/src/main/java/Event.java b/src/main/java/Event.java new file mode 100644 index 000000000..e9285ef80 --- /dev/null +++ b/src/main/java/Event.java @@ -0,0 +1,17 @@ +public class Event extends Task { + String startDate; + String endDate; + + // Constructor to initialize an event with a description, start date, and end date + public Event(String description, String startDate, String endDate) { + super(description); + this.startDate = startDate; + this.endDate = endDate; + this.type = "[E]"; // Type [E] indicates this is an Event + } + + @Override + public String toString() { + return getType() + getStatusIcon() + " " + description + " (from: " + startDate + " to: " + endDate + ")"; + } +} diff --git a/src/main/java/Task.java b/src/main/java/Task.java index 662995228..fb1871ef0 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -2,16 +2,26 @@ public class Task { // Instance variables to store task description and status protected String description; protected boolean isDone; + protected String type; // Constructor to initialize a task with a description public Task(String description) { this.description = description; this.isDone = false; + this.type = "[T]"; // Default type is [T] + } + + public String getType() { + return type; } // Method to get the status icon based on whether the task is done or not public String getStatusIcon() { return (isDone ? "[X]" : "[ ]"); } -} + @Override + public String toString () { + return getType() + getStatusIcon() + " " + description; + } +} From c3104141f50ca68bf6791f2738e2bc7adbd68230 Mon Sep 17 00:00:00 2001 From: aaronxujiachen <1943999635x@gmail.com> Date: Sat, 9 Sep 2023 13:36:35 +0800 Subject: [PATCH 07/23] Improve Code Quality --- src/main/java/Duke.java | 118 ++++++++++++++++++++++++---------------- 1 file changed, 71 insertions(+), 47 deletions(-) diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index e292dd368..373dad00e 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -40,65 +40,89 @@ public static void storeDude() { byeDude(); break; } else if (input.equals("list")) { - System.out.println("Here are the tasks in your list:"); - for (int i = 0; i < tasks.size(); i++) { - System.out.println((i + 1) + ". " + tasks.get(i)); - } + listTasks(tasks); } else if (input.startsWith("todo")) { - String taskDescription = input.substring(5); - tasks.add(new Task(taskDescription)); - System.out.println("Got it. I've added this task:"); - System.out.println(" " + tasks.get(tasks.size() - 1)); - System.out.println("Now you have " + tasks.size() + " tasks in the list."); + addTodoTask(tasks, input); } else if (input.startsWith("deadline")) { - String taskDescription = input.substring(9, input.indexOf("/by")).trim(); - String by = input.substring(input.indexOf("/by") + 4).trim(); - tasks.add(new Deadline(taskDescription, by)); - System.out.println("Got it. I've added this task:"); - System.out.println(" " + tasks.get(tasks.size() - 1)); - System.out.println("Now you have " + tasks.size() + " tasks in the list."); + addDeadlineTask(tasks, input); } else if (input.startsWith("event")) { - String taskDescription = input.substring(6, input.indexOf("/from")).trim(); - String from = input.substring(input.indexOf("/from") + 6, input.indexOf("/to")).trim(); - String to = input.substring(input.indexOf("/to") + 4).trim(); - tasks.add(new Event(taskDescription, from, to)); - System.out.println("Got it. I've added this task:"); - System.out.println(" " + tasks.get(tasks.size() - 1)); - System.out.println("Now you have " + tasks.size() + " tasks in the list."); + addEventTask(tasks, input); } else if (input.startsWith("mark") || input.startsWith("unmark")) { - String[] arrOfInput = input.split(" ", 2); - if (arrOfInput.length < 2) { - System.out.println("Please specify the task index."); - } else { - try { - int index = Integer.parseInt(arrOfInput[1]) - 1; - if (index < 0 || index >= tasks.size()) { // Here, replace curPos with tasks.size() - System.out.println("Task index out of range."); - } else { - tasks.get(index).isDone = input.startsWith("mark"); - String message = input.startsWith("mark") ? - "Nice! I've marked this task as done:" : - "OK, I've marked this task as not done yet:"; - System.out.println(message); - - // This line is the modified part: Using toString to print the task. - System.out.println(" " + tasks.get(index).toString()); - } - } catch (NumberFormatException e) { - System.out.println("Invalid task index format."); - } - } + markOrUnmarkTask(tasks, input); } else { - // Add new task - System.out.println("added: " + input); - tasks.add(new Task(input)); + addGeneralTask(tasks, input); } + drawLine(); input = scan.nextLine(); } scan.close(); } + private static void listTasks(ArrayList tasks) { + System.out.println("Here are the tasks in your list:"); + for (int i = 0; i < tasks.size(); i++) { + System.out.println((i + 1) + ". " + tasks.get(i)); + } + } + + private static void addTodoTask(ArrayList tasks, String input) { + String taskDescription = input.substring(5); + tasks.add(new Task(taskDescription)); + printAddedTask(tasks); + } + + private static void addDeadlineTask(ArrayList tasks, String input) { + String taskDescription = input.substring(9, input.indexOf("/by")).trim(); + String by = input.substring(input.indexOf("/by") + 4).trim(); + tasks.add(new Deadline(taskDescription, by)); + printAddedTask(tasks); + } + + private static void addEventTask(ArrayList tasks, String input) { + String taskDescription = input.substring(6, input.indexOf("/from")).trim(); + String from = input.substring(input.indexOf("/from") + 6, input.indexOf("/to")).trim(); + String to = input.substring(input.indexOf("/to") + 4).trim(); + tasks.add(new Event(taskDescription, from, to)); + printAddedTask(tasks); + } + + private static void markOrUnmarkTask(ArrayList tasks, String input) { + String[] arrOfInput = input.split(" ", 2); + if (arrOfInput.length < 2) { + System.out.println("Please specify the task index."); + return; + } + + try { + int index = Integer.parseInt(arrOfInput[1]) - 1; + if (index < 0 || index >= tasks.size()) { + System.out.println("Task index out of range."); + return; + } + tasks.get(index).isDone = input.startsWith("mark"); + String message = input.startsWith("mark") ? + "Nice! I've marked this task as done:" : + "OK, I've marked this task as not done yet:"; + System.out.println(message); + System.out.println(" " + tasks.get(index)); + } catch (NumberFormatException e) { + System.out.println("Invalid task index format."); + } + } + + private static void addGeneralTask(ArrayList tasks, String input) { + System.out.println("added: " + input); + tasks.add(new Task(input)); + } + + private static void printAddedTask(ArrayList tasks) { + System.out.println("Got it. I've added this task:"); + System.out.println(" " + tasks.get(tasks.size() - 1)); + System.out.println("Now you have " + tasks.size() + (tasks.size() == 1 ? " task" : " tasks") + " in the list."); + } + + // Method to print the goodbye message public static void byeDude() { From dae8f4d6ba8e5f42ed5038f784eb25d9c3f4ac00 Mon Sep 17 00:00:00 2001 From: aaronxujiachen <1943999635x@gmail.com> Date: Thu, 14 Sep 2023 23:18:50 +0800 Subject: [PATCH 08/23] Rename Main Class --- src/main/java/{Duke.java => Dude.java} | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) rename src/main/java/{Duke.java => Dude.java} (99%) diff --git a/src/main/java/Duke.java b/src/main/java/Dude.java similarity index 99% rename from src/main/java/Duke.java rename to src/main/java/Dude.java index 373dad00e..f344a8295 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Dude.java @@ -1,7 +1,7 @@ import java.util.ArrayList; import java.util.Scanner; -public class Duke { +public class Dude { // Method to draw horizontal lines public static void drawLine() { @@ -136,3 +136,4 @@ public static void main(String[] args) { storeDude(); } } + From 507e70b2666e38f903d6c7c33612c2ff59611623 Mon Sep 17 00:00:00 2001 From: aaronxujiachen <1943999635x@gmail.com> Date: Sat, 16 Sep 2023 13:07:26 +0800 Subject: [PATCH 09/23] Add Dude Level 5 --- src/main/java/Dude.java | 98 ++++++++++++++++++++++---------- src/main/java/DudeException.java | 5 ++ 2 files changed, 74 insertions(+), 29 deletions(-) create mode 100644 src/main/java/DudeException.java diff --git a/src/main/java/Dude.java b/src/main/java/Dude.java index f344a8295..3a01d2a8d 100644 --- a/src/main/java/Dude.java +++ b/src/main/java/Dude.java @@ -36,21 +36,25 @@ public static void storeDude() { while (!input.isEmpty()) { drawLine(); - if (input.equals("bye")) { - byeDude(); - break; - } else if (input.equals("list")) { - listTasks(tasks); - } else if (input.startsWith("todo")) { - addTodoTask(tasks, input); - } else if (input.startsWith("deadline")) { - addDeadlineTask(tasks, input); - } else if (input.startsWith("event")) { - addEventTask(tasks, input); - } else if (input.startsWith("mark") || input.startsWith("unmark")) { - markOrUnmarkTask(tasks, input); - } else { - addGeneralTask(tasks, input); + try { + if (input.equals("bye")) { + byeDude(); + break; + } else if (input.equals("list")) { + listTasks(tasks); + } else if (input.startsWith("todo")) { + addTodoTask(tasks, input); + } else if (input.startsWith("deadline")) { + addDeadlineTask(tasks, input); + } else if (input.startsWith("event")) { + addEventTask(tasks, input); + } else if (input.startsWith("mark") || input.startsWith("unmark")) { + markOrUnmarkTask(tasks, input); + } else { + System.out.println("☹ OOPS!!! I'm sorry, but I don't know what that means :-("); + } + } catch (DudeException e) { + System.out.println(e.getMessage()); } drawLine(); @@ -59,6 +63,7 @@ public static void storeDude() { scan.close(); } + private static void listTasks(ArrayList tasks) { System.out.println("Here are the tasks in your list:"); for (int i = 0; i < tasks.size(); i++) { @@ -66,23 +71,63 @@ private static void listTasks(ArrayList tasks) { } } - private static void addTodoTask(ArrayList tasks, String input) { - String taskDescription = input.substring(5); + private static void addTodoTask(ArrayList tasks, String input) throws DudeException { + if (input.length() <= 5) { + throw new DudeException("☹ OOPS!!! The description of a todo cannot be empty."); + } + + String taskDescription = input.substring(5).trim(); + if (taskDescription.isEmpty()) { + throw new DudeException("☹ OOPS!!! The description of a todo cannot be empty."); + } tasks.add(new Task(taskDescription)); printAddedTask(tasks); } - private static void addDeadlineTask(ArrayList tasks, String input) { - String taskDescription = input.substring(9, input.indexOf("/by")).trim(); - String by = input.substring(input.indexOf("/by") + 4).trim(); + + private static void addDeadlineTask(ArrayList tasks, String input) throws DudeException { + int byIndex = input.indexOf("/by"); + if (byIndex == -1) { + throw new DudeException("☹ OOPS!!! Please specify a deadline using /by."); + } + + String taskDescription = input.substring(9, byIndex).trim(); + if (taskDescription.isEmpty()) { + throw new DudeException("☹ OOPS!!! The description of a deadline cannot be empty."); + } + + String by = input.substring(byIndex + 4).trim(); + if (by.isEmpty()) { + throw new DudeException("☹ OOPS!!! The deadline time cannot be empty."); + } + tasks.add(new Deadline(taskDescription, by)); printAddedTask(tasks); } - private static void addEventTask(ArrayList tasks, String input) { - String taskDescription = input.substring(6, input.indexOf("/from")).trim(); - String from = input.substring(input.indexOf("/from") + 6, input.indexOf("/to")).trim(); - String to = input.substring(input.indexOf("/to") + 4).trim(); + private static void addEventTask(ArrayList tasks, String input) throws DudeException { + int fromIndex = input.indexOf("/from"); + int toIndex = input.indexOf("/to"); + + if (fromIndex == -1 || toIndex == -1) { + throw new DudeException("☹ OOPS!!! Please specify event time using /from and /to."); + } + + String taskDescription = input.substring(6, fromIndex).trim(); + if (taskDescription.isEmpty()) { + throw new DudeException("☹ OOPS!!! The description of an event cannot be empty."); + } + + String from = input.substring(fromIndex + 6, toIndex).trim(); + if (from.isEmpty()) { + throw new DudeException("☹ OOPS!!! The start time of an event cannot be empty."); + } + + String to = input.substring(toIndex + 4).trim(); + if (to.isEmpty()) { + throw new DudeException("☹ OOPS!!! The end time of an event cannot be empty."); + } + tasks.add(new Event(taskDescription, from, to)); printAddedTask(tasks); } @@ -111,11 +156,6 @@ private static void markOrUnmarkTask(ArrayList tasks, String input) { } } - private static void addGeneralTask(ArrayList tasks, String input) { - System.out.println("added: " + input); - tasks.add(new Task(input)); - } - private static void printAddedTask(ArrayList tasks) { System.out.println("Got it. I've added this task:"); System.out.println(" " + tasks.get(tasks.size() - 1)); diff --git a/src/main/java/DudeException.java b/src/main/java/DudeException.java new file mode 100644 index 000000000..24e640665 --- /dev/null +++ b/src/main/java/DudeException.java @@ -0,0 +1,5 @@ +public class DudeException extends Exception { + public DudeException(String message) { + super(message); + } +} From 08a8f29dab881c3fc4c13a64a4fca2012cd44639 Mon Sep 17 00:00:00 2001 From: aaronxujiachen <1943999635x@gmail.com> Date: Sat, 16 Sep 2023 13:44:49 +0800 Subject: [PATCH 10/23] Organize All Classes Into A Package --- src/{main/java => dude}/Deadline.java | 4 +++- src/{main/java => dude}/Dude.java | 6 ++++-- src/{main/java => dude}/DudeException.java | 2 ++ src/{main/java => dude}/Event.java | 4 +++- src/{main/java => dude}/Task.java | 2 ++ 5 files changed, 14 insertions(+), 4 deletions(-) rename src/{main/java => dude}/Deadline.java (81%) rename src/{main/java => dude}/Dude.java (97%) rename src/{main/java => dude}/DudeException.java (89%) rename src/{main/java => dude}/Event.java (85%) rename src/{main/java => dude}/Task.java (98%) diff --git a/src/main/java/Deadline.java b/src/dude/Deadline.java similarity index 81% rename from src/main/java/Deadline.java rename to src/dude/Deadline.java index 1aeb77be0..45e1e24ba 100644 --- a/src/main/java/Deadline.java +++ b/src/dude/Deadline.java @@ -1,3 +1,5 @@ +package dude; + public class Deadline extends Task { String by; @@ -5,7 +7,7 @@ public class Deadline extends Task { public Deadline(String description, String by) { super(description); this.by = by; - this.type = "[D]"; // Type [D] indicates this is a Deadline + this.type = "[D]"; // Type [D] indicates this is a dude.Deadline } @Override diff --git a/src/main/java/Dude.java b/src/dude/Dude.java similarity index 97% rename from src/main/java/Dude.java rename to src/dude/Dude.java index 3a01d2a8d..dc29d223c 100644 --- a/src/main/java/Dude.java +++ b/src/dude/Dude.java @@ -1,3 +1,5 @@ +package dude; + import java.util.ArrayList; import java.util.Scanner; @@ -22,7 +24,7 @@ public static void hiDude() { System.out.println("Hello from\n" + logo); drawLine(); - System.out.println("Hello! I'm your best Dude :)"); + System.out.println("Hello! I'm your best dude.Dude :)"); System.out.println("What can I do for you?"); drawLine(); } @@ -142,7 +144,7 @@ private static void markOrUnmarkTask(ArrayList tasks, String input) { try { int index = Integer.parseInt(arrOfInput[1]) - 1; if (index < 0 || index >= tasks.size()) { - System.out.println("Task index out of range."); + System.out.println("dude.Task index out of range."); return; } tasks.get(index).isDone = input.startsWith("mark"); diff --git a/src/main/java/DudeException.java b/src/dude/DudeException.java similarity index 89% rename from src/main/java/DudeException.java rename to src/dude/DudeException.java index 24e640665..efc2c2369 100644 --- a/src/main/java/DudeException.java +++ b/src/dude/DudeException.java @@ -1,3 +1,5 @@ +package dude; + public class DudeException extends Exception { public DudeException(String message) { super(message); diff --git a/src/main/java/Event.java b/src/dude/Event.java similarity index 85% rename from src/main/java/Event.java rename to src/dude/Event.java index e9285ef80..9dd86d126 100644 --- a/src/main/java/Event.java +++ b/src/dude/Event.java @@ -1,3 +1,5 @@ +package dude; + public class Event extends Task { String startDate; String endDate; @@ -7,7 +9,7 @@ public Event(String description, String startDate, String endDate) { super(description); this.startDate = startDate; this.endDate = endDate; - this.type = "[E]"; // Type [E] indicates this is an Event + this.type = "[E]"; // Type [E] indicates this is an dude.Event } @Override diff --git a/src/main/java/Task.java b/src/dude/Task.java similarity index 98% rename from src/main/java/Task.java rename to src/dude/Task.java index fb1871ef0..1d5dbb0b1 100644 --- a/src/main/java/Task.java +++ b/src/dude/Task.java @@ -1,3 +1,5 @@ +package dude; + public class Task { // Instance variables to store task description and status protected String description; From 317108a29620018715b2622f9abe7a45a96ca429 Mon Sep 17 00:00:00 2001 From: aaronxujiachen <1943999635x@gmail.com> Date: Thu, 21 Sep 2023 00:11:01 +0800 Subject: [PATCH 11/23] Add Dude Level 6 --- src/dude/Dude.java | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/dude/Dude.java b/src/dude/Dude.java index dc29d223c..0a30483c9 100644 --- a/src/dude/Dude.java +++ b/src/dude/Dude.java @@ -52,6 +52,8 @@ public static void storeDude() { addEventTask(tasks, input); } else if (input.startsWith("mark") || input.startsWith("unmark")) { markOrUnmarkTask(tasks, input); + } else if (input.startsWith("delete")) { + deleteTask(tasks, input); } else { System.out.println("☹ OOPS!!! I'm sorry, but I don't know what that means :-("); } @@ -164,7 +166,28 @@ private static void printAddedTask(ArrayList tasks) { System.out.println("Now you have " + tasks.size() + (tasks.size() == 1 ? " task" : " tasks") + " in the list."); } + private static void deleteTask(ArrayList tasks, String input) { + String[] arrOfInput = input.split(" "); + if (arrOfInput.length < 2) { + System.out.println("Please specify the task index to delete."); + return; + } + try { + int index = Integer.parseInt(arrOfInput[1]) - 1; + if (index < 0 || index >= tasks.size()) { + System.out.println("Task index out of range."); + return; + } + + Task removedTask = tasks.remove(index); + System.out.println("Noted. I've removed this task:"); + System.out.println(" " + removedTask); + System.out.println("Now you have " + tasks.size() + (tasks.size() == 1 ? " task" : " tasks") + " in the list."); + } catch (NumberFormatException e) { + System.out.println("Invalid task index format."); + } + } // Method to print the goodbye message public static void byeDude() { From 898968db7fa4777dfa7994caf3c6ade9b0b722d4 Mon Sep 17 00:00:00 2001 From: aaronxujiachen <1943999635x@gmail.com> Date: Thu, 21 Sep 2023 12:09:47 +0800 Subject: [PATCH 12/23] Add Dude Level 7 --- data/duke.txt | 0 src/dude/Deadline.java | 21 ++++++++--- src/dude/Dude.java | 81 +++++++++++++++++++++++++++++++++++++++--- src/dude/Event.java | 29 ++++++++++----- src/dude/Task.java | 34 ++++++++++++------ 5 files changed, 139 insertions(+), 26 deletions(-) create mode 100644 data/duke.txt diff --git a/data/duke.txt b/data/duke.txt new file mode 100644 index 000000000..e69de29bb diff --git a/src/dude/Deadline.java b/src/dude/Deadline.java index 45e1e24ba..cd8e7f518 100644 --- a/src/dude/Deadline.java +++ b/src/dude/Deadline.java @@ -1,17 +1,30 @@ package dude; public class Deadline extends Task { - String by; + private String by; - // Constructor to initialize a deadline with a description and a due date public Deadline(String description, String by) { super(description); this.by = by; - this.type = "[D]"; // Type [D] indicates this is a dude.Deadline + this.type = "[D]"; + } + + @Override + public String toFileFormat() { + return super.toFileFormat() + " | " + by; + } + + public static Deadline fromFileFormat(String fileString) { + String[] parts = fileString.split("\\s\\|\\s"); + Deadline deadline = new Deadline(parts[2], parts[3]); + if (parts[1].equals("1")) { + deadline.markAsDone(); + } + return deadline; } @Override public String toString() { - return getType() + getStatusIcon() + " " + description + " (by: " + by + ")"; + return super.toString() + " (by: " + by + ")"; } } diff --git a/src/dude/Dude.java b/src/dude/Dude.java index 0a30483c9..b784275cf 100644 --- a/src/dude/Dude.java +++ b/src/dude/Dude.java @@ -2,9 +2,16 @@ import java.util.ArrayList; import java.util.Scanner; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.FileNotFoundException; public class Dude { + private static final String DIRECTORY_PATH = "./data"; + private static final String FILE_PATH = DIRECTORY_PATH + "/duke.txt"; + // Method to draw horizontal lines public static void drawLine() { for (int i = 0; i < 30; i++) { @@ -32,7 +39,8 @@ public static void hiDude() { // Method to handle the storage of tasks public static void storeDude() { Scanner scan = new Scanner(System.in); - ArrayList tasks = new ArrayList<>(); + setupFile(); + ArrayList tasks = loadFromFile(); String input = scan.nextLine(); while (!input.isEmpty()) { @@ -67,7 +75,6 @@ public static void storeDude() { scan.close(); } - private static void listTasks(ArrayList tasks) { System.out.println("Here are the tasks in your list:"); for (int i = 0; i < tasks.size(); i++) { @@ -86,9 +93,9 @@ private static void addTodoTask(ArrayList tasks, String input) throws Dude } tasks.add(new Task(taskDescription)); printAddedTask(tasks); + saveToFile(tasks); } - private static void addDeadlineTask(ArrayList tasks, String input) throws DudeException { int byIndex = input.indexOf("/by"); if (byIndex == -1) { @@ -107,6 +114,7 @@ private static void addDeadlineTask(ArrayList tasks, String input) throws tasks.add(new Deadline(taskDescription, by)); printAddedTask(tasks); + saveToFile(tasks); } private static void addEventTask(ArrayList tasks, String input) throws DudeException { @@ -134,6 +142,7 @@ private static void addEventTask(ArrayList tasks, String input) throws Dud tasks.add(new Event(taskDescription, from, to)); printAddedTask(tasks); + saveToFile(tasks); } private static void markOrUnmarkTask(ArrayList tasks, String input) { @@ -158,6 +167,8 @@ private static void markOrUnmarkTask(ArrayList tasks, String input) { } catch (NumberFormatException e) { System.out.println("Invalid task index format."); } + + saveToFile(tasks); } private static void printAddedTask(ArrayList tasks) { @@ -187,8 +198,71 @@ private static void deleteTask(ArrayList tasks, String input) { } catch (NumberFormatException e) { System.out.println("Invalid task index format."); } + + saveToFile(tasks); + } + + private static void setupFile() { + // Check if the directory exists, if not, create it + File directory = new File(DIRECTORY_PATH); + if (!directory.exists()) { + directory.mkdir(); + } + + // Check if the file exists, if not, create it + File file = new File(FILE_PATH); + if (!file.exists()) { + try { + file.createNewFile(); + } catch (IOException e) { + System.out.println("Error creating file: " + e.getMessage()); + } + } } + private static ArrayList loadFromFile() { + ArrayList tasks = new ArrayList<>(); + try { + File file = new File(FILE_PATH); + Scanner fileReader = new Scanner(file); + + while (fileReader.hasNextLine()) { + String line = fileReader.nextLine(); + // Assuming the first char denotes the type of task + char taskType = line.charAt(0); + switch (taskType) { + case 'T': + tasks.add(Task.fromFileFormat(line)); + break; + case 'D': + tasks.add(Deadline.fromFileFormat(line)); + break; + case 'E': + tasks.add(Event.fromFileFormat(line)); + break; + } + } + + fileReader.close(); + } catch (FileNotFoundException e) { + System.out.println("Error reading from file: " + e.getMessage()); + } + return tasks; + } + + private static void saveToFile(ArrayList tasks) { + try { + FileWriter fileWriter = new FileWriter(FILE_PATH); + for (Task task : tasks) { + fileWriter.write(task.toFileFormat() + "\n"); + } + fileWriter.close(); + } catch (IOException e) { + System.out.println("Error writing to file: " + e.getMessage()); + } + } + + // Method to print the goodbye message public static void byeDude() { System.out.println("Bye. Hope to see you again soon!"); @@ -201,4 +275,3 @@ public static void main(String[] args) { storeDude(); } } - diff --git a/src/dude/Event.java b/src/dude/Event.java index 9dd86d126..7872f4a1d 100644 --- a/src/dude/Event.java +++ b/src/dude/Event.java @@ -1,19 +1,32 @@ package dude; public class Event extends Task { - String startDate; - String endDate; + private String from; + private String to; - // Constructor to initialize an event with a description, start date, and end date - public Event(String description, String startDate, String endDate) { + public Event(String description, String from, String to) { super(description); - this.startDate = startDate; - this.endDate = endDate; - this.type = "[E]"; // Type [E] indicates this is an dude.Event + this.from = from; + this.to = to; + this.type = "[E]"; + } + + @Override + public String toFileFormat() { + return super.toFileFormat() + " | " + from + " | " + to; + } + + public static Event fromFileFormat(String fileString) { + String[] parts = fileString.split("\\s\\|\\s"); + Event event = new Event(parts[2], parts[3], parts[4]); + if (parts[1].equals("1")) { + event.markAsDone(); + } + return event; } @Override public String toString() { - return getType() + getStatusIcon() + " " + description + " (from: " + startDate + " to: " + endDate + ")"; + return super.toString() + " (from: " + from + " to: " + to + ")"; } } diff --git a/src/dude/Task.java b/src/dude/Task.java index 1d5dbb0b1..5870b4e0c 100644 --- a/src/dude/Task.java +++ b/src/dude/Task.java @@ -1,29 +1,43 @@ package dude; public class Task { - // Instance variables to store task description and status protected String description; protected boolean isDone; protected String type; - // Constructor to initialize a task with a description public Task(String description) { this.description = description; this.isDone = false; - this.type = "[T]"; // Default type is [T] + this.type = "[T]"; // Represents a generic task. } - public String getType() { - return type; - } - - // Method to get the status icon based on whether the task is done or not public String getStatusIcon() { return (isDone ? "[X]" : "[ ]"); } + public String getDescription() { + return description; + } + + public void markAsDone() { + isDone = true; + } + + public String toFileFormat() { + return type.charAt(1) + " | " + (isDone ? "1" : "0") + " | " + description; + } + + public static Task fromFileFormat(String fileString) { + String[] parts = fileString.split("\\s\\|\\s"); + Task task = new Task(parts[2]); + if (parts[1].equals("1")) { + task.markAsDone(); + } + return task; + } + @Override - public String toString () { - return getType() + getStatusIcon() + " " + description; + public String toString() { + return type + getStatusIcon() + " " + description; } } From 564c8ee43f5a7904c27dc1bcc1c5bce59c030d34 Mon Sep 17 00:00:00 2001 From: aaronxujiachen <1943999635x@gmail.com> Date: Thu, 21 Sep 2023 12:51:43 +0800 Subject: [PATCH 13/23] Revert "Add Dude Level 7" This reverts commit 898968db7fa4777dfa7994caf3c6ade9b0b722d4. --- data/duke.txt | 0 src/dude/Deadline.java | 21 +++-------- src/dude/Dude.java | 81 +++--------------------------------------- src/dude/Event.java | 29 +++++---------- src/dude/Task.java | 34 ++++++------------ 5 files changed, 26 insertions(+), 139 deletions(-) delete mode 100644 data/duke.txt diff --git a/data/duke.txt b/data/duke.txt deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/dude/Deadline.java b/src/dude/Deadline.java index cd8e7f518..45e1e24ba 100644 --- a/src/dude/Deadline.java +++ b/src/dude/Deadline.java @@ -1,30 +1,17 @@ package dude; public class Deadline extends Task { - private String by; + String by; + // Constructor to initialize a deadline with a description and a due date public Deadline(String description, String by) { super(description); this.by = by; - this.type = "[D]"; - } - - @Override - public String toFileFormat() { - return super.toFileFormat() + " | " + by; - } - - public static Deadline fromFileFormat(String fileString) { - String[] parts = fileString.split("\\s\\|\\s"); - Deadline deadline = new Deadline(parts[2], parts[3]); - if (parts[1].equals("1")) { - deadline.markAsDone(); - } - return deadline; + this.type = "[D]"; // Type [D] indicates this is a dude.Deadline } @Override public String toString() { - return super.toString() + " (by: " + by + ")"; + return getType() + getStatusIcon() + " " + description + " (by: " + by + ")"; } } diff --git a/src/dude/Dude.java b/src/dude/Dude.java index b784275cf..0a30483c9 100644 --- a/src/dude/Dude.java +++ b/src/dude/Dude.java @@ -2,16 +2,9 @@ import java.util.ArrayList; import java.util.Scanner; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.FileNotFoundException; public class Dude { - private static final String DIRECTORY_PATH = "./data"; - private static final String FILE_PATH = DIRECTORY_PATH + "/duke.txt"; - // Method to draw horizontal lines public static void drawLine() { for (int i = 0; i < 30; i++) { @@ -39,8 +32,7 @@ public static void hiDude() { // Method to handle the storage of tasks public static void storeDude() { Scanner scan = new Scanner(System.in); - setupFile(); - ArrayList tasks = loadFromFile(); + ArrayList tasks = new ArrayList<>(); String input = scan.nextLine(); while (!input.isEmpty()) { @@ -75,6 +67,7 @@ public static void storeDude() { scan.close(); } + private static void listTasks(ArrayList tasks) { System.out.println("Here are the tasks in your list:"); for (int i = 0; i < tasks.size(); i++) { @@ -93,9 +86,9 @@ private static void addTodoTask(ArrayList tasks, String input) throws Dude } tasks.add(new Task(taskDescription)); printAddedTask(tasks); - saveToFile(tasks); } + private static void addDeadlineTask(ArrayList tasks, String input) throws DudeException { int byIndex = input.indexOf("/by"); if (byIndex == -1) { @@ -114,7 +107,6 @@ private static void addDeadlineTask(ArrayList tasks, String input) throws tasks.add(new Deadline(taskDescription, by)); printAddedTask(tasks); - saveToFile(tasks); } private static void addEventTask(ArrayList tasks, String input) throws DudeException { @@ -142,7 +134,6 @@ private static void addEventTask(ArrayList tasks, String input) throws Dud tasks.add(new Event(taskDescription, from, to)); printAddedTask(tasks); - saveToFile(tasks); } private static void markOrUnmarkTask(ArrayList tasks, String input) { @@ -167,8 +158,6 @@ private static void markOrUnmarkTask(ArrayList tasks, String input) { } catch (NumberFormatException e) { System.out.println("Invalid task index format."); } - - saveToFile(tasks); } private static void printAddedTask(ArrayList tasks) { @@ -198,71 +187,8 @@ private static void deleteTask(ArrayList tasks, String input) { } catch (NumberFormatException e) { System.out.println("Invalid task index format."); } - - saveToFile(tasks); - } - - private static void setupFile() { - // Check if the directory exists, if not, create it - File directory = new File(DIRECTORY_PATH); - if (!directory.exists()) { - directory.mkdir(); - } - - // Check if the file exists, if not, create it - File file = new File(FILE_PATH); - if (!file.exists()) { - try { - file.createNewFile(); - } catch (IOException e) { - System.out.println("Error creating file: " + e.getMessage()); - } - } } - private static ArrayList loadFromFile() { - ArrayList tasks = new ArrayList<>(); - try { - File file = new File(FILE_PATH); - Scanner fileReader = new Scanner(file); - - while (fileReader.hasNextLine()) { - String line = fileReader.nextLine(); - // Assuming the first char denotes the type of task - char taskType = line.charAt(0); - switch (taskType) { - case 'T': - tasks.add(Task.fromFileFormat(line)); - break; - case 'D': - tasks.add(Deadline.fromFileFormat(line)); - break; - case 'E': - tasks.add(Event.fromFileFormat(line)); - break; - } - } - - fileReader.close(); - } catch (FileNotFoundException e) { - System.out.println("Error reading from file: " + e.getMessage()); - } - return tasks; - } - - private static void saveToFile(ArrayList tasks) { - try { - FileWriter fileWriter = new FileWriter(FILE_PATH); - for (Task task : tasks) { - fileWriter.write(task.toFileFormat() + "\n"); - } - fileWriter.close(); - } catch (IOException e) { - System.out.println("Error writing to file: " + e.getMessage()); - } - } - - // Method to print the goodbye message public static void byeDude() { System.out.println("Bye. Hope to see you again soon!"); @@ -275,3 +201,4 @@ public static void main(String[] args) { storeDude(); } } + diff --git a/src/dude/Event.java b/src/dude/Event.java index 7872f4a1d..9dd86d126 100644 --- a/src/dude/Event.java +++ b/src/dude/Event.java @@ -1,32 +1,19 @@ package dude; public class Event extends Task { - private String from; - private String to; + String startDate; + String endDate; - public Event(String description, String from, String to) { + // Constructor to initialize an event with a description, start date, and end date + public Event(String description, String startDate, String endDate) { super(description); - this.from = from; - this.to = to; - this.type = "[E]"; - } - - @Override - public String toFileFormat() { - return super.toFileFormat() + " | " + from + " | " + to; - } - - public static Event fromFileFormat(String fileString) { - String[] parts = fileString.split("\\s\\|\\s"); - Event event = new Event(parts[2], parts[3], parts[4]); - if (parts[1].equals("1")) { - event.markAsDone(); - } - return event; + this.startDate = startDate; + this.endDate = endDate; + this.type = "[E]"; // Type [E] indicates this is an dude.Event } @Override public String toString() { - return super.toString() + " (from: " + from + " to: " + to + ")"; + return getType() + getStatusIcon() + " " + description + " (from: " + startDate + " to: " + endDate + ")"; } } diff --git a/src/dude/Task.java b/src/dude/Task.java index 5870b4e0c..1d5dbb0b1 100644 --- a/src/dude/Task.java +++ b/src/dude/Task.java @@ -1,43 +1,29 @@ package dude; public class Task { + // Instance variables to store task description and status protected String description; protected boolean isDone; protected String type; + // Constructor to initialize a task with a description public Task(String description) { this.description = description; this.isDone = false; - this.type = "[T]"; // Represents a generic task. + this.type = "[T]"; // Default type is [T] } - public String getStatusIcon() { - return (isDone ? "[X]" : "[ ]"); - } - - public String getDescription() { - return description; - } - - public void markAsDone() { - isDone = true; - } - - public String toFileFormat() { - return type.charAt(1) + " | " + (isDone ? "1" : "0") + " | " + description; + public String getType() { + return type; } - public static Task fromFileFormat(String fileString) { - String[] parts = fileString.split("\\s\\|\\s"); - Task task = new Task(parts[2]); - if (parts[1].equals("1")) { - task.markAsDone(); - } - return task; + // Method to get the status icon based on whether the task is done or not + public String getStatusIcon() { + return (isDone ? "[X]" : "[ ]"); } @Override - public String toString() { - return type + getStatusIcon() + " " + description; + public String toString () { + return getType() + getStatusIcon() + " " + description; } } From 6a621166579bad9bf6eaf80ffa473e9003cb4cf5 Mon Sep 17 00:00:00 2001 From: aaronxujiachen <1943999635x@gmail.com> Date: Thu, 21 Sep 2023 14:17:56 +0800 Subject: [PATCH 14/23] Add Dude Level 7 --- data/duke.txt | 0 src/dude/Deadline.java | 21 ++++++++--- src/dude/Dude.java | 80 ++++++++++++++++++++++++++++++++++++++++-- src/dude/Event.java | 29 ++++++++++----- src/dude/Task.java | 34 ++++++++++++------ 5 files changed, 140 insertions(+), 24 deletions(-) create mode 100644 data/duke.txt diff --git a/data/duke.txt b/data/duke.txt new file mode 100644 index 000000000..e69de29bb diff --git a/src/dude/Deadline.java b/src/dude/Deadline.java index 45e1e24ba..cd8e7f518 100644 --- a/src/dude/Deadline.java +++ b/src/dude/Deadline.java @@ -1,17 +1,30 @@ package dude; public class Deadline extends Task { - String by; + private String by; - // Constructor to initialize a deadline with a description and a due date public Deadline(String description, String by) { super(description); this.by = by; - this.type = "[D]"; // Type [D] indicates this is a dude.Deadline + this.type = "[D]"; + } + + @Override + public String toFileFormat() { + return super.toFileFormat() + " | " + by; + } + + public static Deadline fromFileFormat(String fileString) { + String[] parts = fileString.split("\\s\\|\\s"); + Deadline deadline = new Deadline(parts[2], parts[3]); + if (parts[1].equals("1")) { + deadline.markAsDone(); + } + return deadline; } @Override public String toString() { - return getType() + getStatusIcon() + " " + description + " (by: " + by + ")"; + return super.toString() + " (by: " + by + ")"; } } diff --git a/src/dude/Dude.java b/src/dude/Dude.java index 0a30483c9..c2973d80e 100644 --- a/src/dude/Dude.java +++ b/src/dude/Dude.java @@ -2,9 +2,16 @@ import java.util.ArrayList; import java.util.Scanner; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.FileNotFoundException; public class Dude { + private static final String DIRECTORY_PATH = "./data"; + private static final String FILE_PATH = DIRECTORY_PATH + "/duke.txt"; + // Method to draw horizontal lines public static void drawLine() { for (int i = 0; i < 30; i++) { @@ -24,7 +31,7 @@ public static void hiDude() { System.out.println("Hello from\n" + logo); drawLine(); - System.out.println("Hello! I'm your best dude.Dude :)"); + System.out.println("Hello! I'm your best dude:)"); System.out.println("What can I do for you?"); drawLine(); } @@ -32,7 +39,8 @@ public static void hiDude() { // Method to handle the storage of tasks public static void storeDude() { Scanner scan = new Scanner(System.in); - ArrayList tasks = new ArrayList<>(); + setupFile(); + ArrayList tasks = loadFromFile(); String input = scan.nextLine(); while (!input.isEmpty()) { @@ -86,6 +94,7 @@ private static void addTodoTask(ArrayList tasks, String input) throws Dude } tasks.add(new Task(taskDescription)); printAddedTask(tasks); + saveToFile(tasks); } @@ -107,6 +116,7 @@ private static void addDeadlineTask(ArrayList tasks, String input) throws tasks.add(new Deadline(taskDescription, by)); printAddedTask(tasks); + saveToFile(tasks); } private static void addEventTask(ArrayList tasks, String input) throws DudeException { @@ -134,6 +144,7 @@ private static void addEventTask(ArrayList tasks, String input) throws Dud tasks.add(new Event(taskDescription, from, to)); printAddedTask(tasks); + saveToFile(tasks); } private static void markOrUnmarkTask(ArrayList tasks, String input) { @@ -158,6 +169,8 @@ private static void markOrUnmarkTask(ArrayList tasks, String input) { } catch (NumberFormatException e) { System.out.println("Invalid task index format."); } + + saveToFile(tasks); } private static void printAddedTask(ArrayList tasks) { @@ -187,8 +200,71 @@ private static void deleteTask(ArrayList tasks, String input) { } catch (NumberFormatException e) { System.out.println("Invalid task index format."); } + + saveToFile(tasks); + } + + private static void setupFile() { + // Check if the directory exists, if not, create it + File directory = new File(DIRECTORY_PATH); + if (!directory.exists()) { + directory.mkdir(); + } + + // Check if the file exists, if not, create it + File file = new File(FILE_PATH); + if (!file.exists()) { + try { + file.createNewFile(); + } catch (IOException e) { + System.out.println("Error creating file: " + e.getMessage()); + } + } + } + + private static ArrayList loadFromFile() { + ArrayList tasks = new ArrayList<>(); + try { + File file = new File(FILE_PATH); + Scanner fileReader = new Scanner(file); + + while (fileReader.hasNextLine()) { + String line = fileReader.nextLine(); + // Assuming the first char denotes the type of task + char taskType = line.charAt(0); + switch (taskType) { + case 'T': + tasks.add(Task.fromFileFormat(line)); + break; + case 'D': + tasks.add(Deadline.fromFileFormat(line)); + break; + case 'E': + tasks.add(Event.fromFileFormat(line)); + break; + } + } + + fileReader.close(); + } catch (FileNotFoundException e) { + System.out.println("Error reading from file: " + e.getMessage()); + } + return tasks; } + private static void saveToFile(ArrayList tasks) { + try { + FileWriter fileWriter = new FileWriter(FILE_PATH); + for (Task task : tasks) { + fileWriter.write(task.toFileFormat() + "\n"); + } + fileWriter.close(); + } catch (IOException e) { + System.out.println("Error writing to file: " + e.getMessage()); + } + } + + // Method to print the goodbye message public static void byeDude() { System.out.println("Bye. Hope to see you again soon!"); diff --git a/src/dude/Event.java b/src/dude/Event.java index 9dd86d126..7872f4a1d 100644 --- a/src/dude/Event.java +++ b/src/dude/Event.java @@ -1,19 +1,32 @@ package dude; public class Event extends Task { - String startDate; - String endDate; + private String from; + private String to; - // Constructor to initialize an event with a description, start date, and end date - public Event(String description, String startDate, String endDate) { + public Event(String description, String from, String to) { super(description); - this.startDate = startDate; - this.endDate = endDate; - this.type = "[E]"; // Type [E] indicates this is an dude.Event + this.from = from; + this.to = to; + this.type = "[E]"; + } + + @Override + public String toFileFormat() { + return super.toFileFormat() + " | " + from + " | " + to; + } + + public static Event fromFileFormat(String fileString) { + String[] parts = fileString.split("\\s\\|\\s"); + Event event = new Event(parts[2], parts[3], parts[4]); + if (parts[1].equals("1")) { + event.markAsDone(); + } + return event; } @Override public String toString() { - return getType() + getStatusIcon() + " " + description + " (from: " + startDate + " to: " + endDate + ")"; + return super.toString() + " (from: " + from + " to: " + to + ")"; } } diff --git a/src/dude/Task.java b/src/dude/Task.java index 1d5dbb0b1..5870b4e0c 100644 --- a/src/dude/Task.java +++ b/src/dude/Task.java @@ -1,29 +1,43 @@ package dude; public class Task { - // Instance variables to store task description and status protected String description; protected boolean isDone; protected String type; - // Constructor to initialize a task with a description public Task(String description) { this.description = description; this.isDone = false; - this.type = "[T]"; // Default type is [T] + this.type = "[T]"; // Represents a generic task. } - public String getType() { - return type; - } - - // Method to get the status icon based on whether the task is done or not public String getStatusIcon() { return (isDone ? "[X]" : "[ ]"); } + public String getDescription() { + return description; + } + + public void markAsDone() { + isDone = true; + } + + public String toFileFormat() { + return type.charAt(1) + " | " + (isDone ? "1" : "0") + " | " + description; + } + + public static Task fromFileFormat(String fileString) { + String[] parts = fileString.split("\\s\\|\\s"); + Task task = new Task(parts[2]); + if (parts[1].equals("1")) { + task.markAsDone(); + } + return task; + } + @Override - public String toString () { - return getType() + getStatusIcon() + " " + description; + public String toString() { + return type + getStatusIcon() + " " + description; } } From 12bfeb7d3aeab57fca7e7c445e1ab89e0d5cfba9 Mon Sep 17 00:00:00 2001 From: aaronxujiachen <1943999635x@gmail.com> Date: Thu, 28 Sep 2023 13:34:13 +0800 Subject: [PATCH 15/23] Refactor the code to make it more OOP --- data/{duke.txt => dude.txt} | 0 src/META-INF/MANIFEST.MF | 3 + src/dude/Deadline.java | 2 +- src/dude/Dude.java | 281 +++--------------------------------- src/dude/Event.java | 2 +- src/dude/Parser.java | 39 +++++ src/dude/Storage.java | 74 ++++++++++ src/dude/Task.java | 6 +- src/dude/TaskList.java | 114 +++++++++++++++ src/dude/Ui.java | 89 ++++++++++++ 10 files changed, 343 insertions(+), 267 deletions(-) rename data/{duke.txt => dude.txt} (100%) create mode 100644 src/META-INF/MANIFEST.MF create mode 100644 src/dude/Parser.java create mode 100644 src/dude/Storage.java create mode 100644 src/dude/TaskList.java create mode 100644 src/dude/Ui.java diff --git a/data/duke.txt b/data/dude.txt similarity index 100% rename from data/duke.txt rename to data/dude.txt diff --git a/src/META-INF/MANIFEST.MF b/src/META-INF/MANIFEST.MF new file mode 100644 index 000000000..c69259465 --- /dev/null +++ b/src/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: dude.Dude + diff --git a/src/dude/Deadline.java b/src/dude/Deadline.java index cd8e7f518..33c766326 100644 --- a/src/dude/Deadline.java +++ b/src/dude/Deadline.java @@ -18,7 +18,7 @@ public static Deadline fromFileFormat(String fileString) { String[] parts = fileString.split("\\s\\|\\s"); Deadline deadline = new Deadline(parts[2], parts[3]); if (parts[1].equals("1")) { - deadline.markAsDone(); + deadline.setDone(deadline.isDone); } return deadline; } diff --git a/src/dude/Dude.java b/src/dude/Dude.java index c2973d80e..211715fbe 100644 --- a/src/dude/Dude.java +++ b/src/dude/Dude.java @@ -1,280 +1,37 @@ package dude; import java.util.ArrayList; -import java.util.Scanner; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.FileNotFoundException; public class Dude { + private Storage storage; + private TaskList tasks; + private Ui ui; - private static final String DIRECTORY_PATH = "./data"; - private static final String FILE_PATH = DIRECTORY_PATH + "/duke.txt"; - - // Method to draw horizontal lines - public static void drawLine() { - for (int i = 0; i < 30; i++) { - System.out.print("_"); - } - System.out.println(); - } - - // Method to print the logo and introductory message - public static void hiDude() { - String logo = "### # \n" - + "# # # \n" - + "# # # # ### ## \n" - + "# # # # # # # ## \n" - + "# # # # # # ## \n" - + "### ### ### ## \n"; - - System.out.println("Hello from\n" + logo); - drawLine(); - System.out.println("Hello! I'm your best dude:)"); - System.out.println("What can I do for you?"); - drawLine(); - } - - // Method to handle the storage of tasks - public static void storeDude() { - Scanner scan = new Scanner(System.in); - setupFile(); - ArrayList tasks = loadFromFile(); - - String input = scan.nextLine(); - while (!input.isEmpty()) { - drawLine(); - - try { - if (input.equals("bye")) { - byeDude(); - break; - } else if (input.equals("list")) { - listTasks(tasks); - } else if (input.startsWith("todo")) { - addTodoTask(tasks, input); - } else if (input.startsWith("deadline")) { - addDeadlineTask(tasks, input); - } else if (input.startsWith("event")) { - addEventTask(tasks, input); - } else if (input.startsWith("mark") || input.startsWith("unmark")) { - markOrUnmarkTask(tasks, input); - } else if (input.startsWith("delete")) { - deleteTask(tasks, input); - } else { - System.out.println("☹ OOPS!!! I'm sorry, but I don't know what that means :-("); - } - } catch (DudeException e) { - System.out.println(e.getMessage()); - } - - drawLine(); - input = scan.nextLine(); - } - scan.close(); - } - - - private static void listTasks(ArrayList tasks) { - System.out.println("Here are the tasks in your list:"); - for (int i = 0; i < tasks.size(); i++) { - System.out.println((i + 1) + ". " + tasks.get(i)); - } - } - - private static void addTodoTask(ArrayList tasks, String input) throws DudeException { - if (input.length() <= 5) { - throw new DudeException("☹ OOPS!!! The description of a todo cannot be empty."); - } - - String taskDescription = input.substring(5).trim(); - if (taskDescription.isEmpty()) { - throw new DudeException("☹ OOPS!!! The description of a todo cannot be empty."); - } - tasks.add(new Task(taskDescription)); - printAddedTask(tasks); - saveToFile(tasks); - } - - - private static void addDeadlineTask(ArrayList tasks, String input) throws DudeException { - int byIndex = input.indexOf("/by"); - if (byIndex == -1) { - throw new DudeException("☹ OOPS!!! Please specify a deadline using /by."); - } - - String taskDescription = input.substring(9, byIndex).trim(); - if (taskDescription.isEmpty()) { - throw new DudeException("☹ OOPS!!! The description of a deadline cannot be empty."); - } - - String by = input.substring(byIndex + 4).trim(); - if (by.isEmpty()) { - throw new DudeException("☹ OOPS!!! The deadline time cannot be empty."); - } - - tasks.add(new Deadline(taskDescription, by)); - printAddedTask(tasks); - saveToFile(tasks); - } - - private static void addEventTask(ArrayList tasks, String input) throws DudeException { - int fromIndex = input.indexOf("/from"); - int toIndex = input.indexOf("/to"); - - if (fromIndex == -1 || toIndex == -1) { - throw new DudeException("☹ OOPS!!! Please specify event time using /from and /to."); - } - - String taskDescription = input.substring(6, fromIndex).trim(); - if (taskDescription.isEmpty()) { - throw new DudeException("☹ OOPS!!! The description of an event cannot be empty."); - } - - String from = input.substring(fromIndex + 6, toIndex).trim(); - if (from.isEmpty()) { - throw new DudeException("☹ OOPS!!! The start time of an event cannot be empty."); - } - - String to = input.substring(toIndex + 4).trim(); - if (to.isEmpty()) { - throw new DudeException("☹ OOPS!!! The end time of an event cannot be empty."); - } - - tasks.add(new Event(taskDescription, from, to)); - printAddedTask(tasks); - saveToFile(tasks); - } - - private static void markOrUnmarkTask(ArrayList tasks, String input) { - String[] arrOfInput = input.split(" ", 2); - if (arrOfInput.length < 2) { - System.out.println("Please specify the task index."); - return; - } - - try { - int index = Integer.parseInt(arrOfInput[1]) - 1; - if (index < 0 || index >= tasks.size()) { - System.out.println("dude.Task index out of range."); - return; - } - tasks.get(index).isDone = input.startsWith("mark"); - String message = input.startsWith("mark") ? - "Nice! I've marked this task as done:" : - "OK, I've marked this task as not done yet:"; - System.out.println(message); - System.out.println(" " + tasks.get(index)); - } catch (NumberFormatException e) { - System.out.println("Invalid task index format."); - } - - saveToFile(tasks); - } - - private static void printAddedTask(ArrayList tasks) { - System.out.println("Got it. I've added this task:"); - System.out.println(" " + tasks.get(tasks.size() - 1)); - System.out.println("Now you have " + tasks.size() + (tasks.size() == 1 ? " task" : " tasks") + " in the list."); - } - - private static void deleteTask(ArrayList tasks, String input) { - String[] arrOfInput = input.split(" "); - if (arrOfInput.length < 2) { - System.out.println("Please specify the task index to delete."); - return; - } - + public Dude(String filePath) { + ui = new Ui(); + storage = new Storage(filePath); try { - int index = Integer.parseInt(arrOfInput[1]) - 1; - if (index < 0 || index >= tasks.size()) { - System.out.println("Task index out of range."); - return; - } - - Task removedTask = tasks.remove(index); - System.out.println("Noted. I've removed this task:"); - System.out.println(" " + removedTask); - System.out.println("Now you have " + tasks.size() + (tasks.size() == 1 ? " task" : " tasks") + " in the list."); - } catch (NumberFormatException e) { - System.out.println("Invalid task index format."); + tasks = new TaskList(storage.loadFromFile(), storage, ui); + } catch (Exception e) { + // Display a generic error message or log the exception details + ui.showMessage("Error loading tasks from file: " + e.getMessage()); + tasks = new TaskList(new ArrayList<>(), storage, ui); } - - saveToFile(tasks); } - private static void setupFile() { - // Check if the directory exists, if not, create it - File directory = new File(DIRECTORY_PATH); - if (!directory.exists()) { - directory.mkdir(); - } - - // Check if the file exists, if not, create it - File file = new File(FILE_PATH); - if (!file.exists()) { + public void run() { + ui.showGreeting(); + while (true) { // Infinite loop since exit is handled in the Parser try { - file.createNewFile(); - } catch (IOException e) { - System.out.println("Error creating file: " + e.getMessage()); - } - } - } - - private static ArrayList loadFromFile() { - ArrayList tasks = new ArrayList<>(); - try { - File file = new File(FILE_PATH); - Scanner fileReader = new Scanner(file); - - while (fileReader.hasNextLine()) { - String line = fileReader.nextLine(); - // Assuming the first char denotes the type of task - char taskType = line.charAt(0); - switch (taskType) { - case 'T': - tasks.add(Task.fromFileFormat(line)); - break; - case 'D': - tasks.add(Deadline.fromFileFormat(line)); - break; - case 'E': - tasks.add(Event.fromFileFormat(line)); - break; - } - } - - fileReader.close(); - } catch (FileNotFoundException e) { - System.out.println("Error reading from file: " + e.getMessage()); - } - return tasks; - } - - private static void saveToFile(ArrayList tasks) { - try { - FileWriter fileWriter = new FileWriter(FILE_PATH); - for (Task task : tasks) { - fileWriter.write(task.toFileFormat() + "\n"); + String fullCommand = ui.readCommand(); + Parser.parse(fullCommand, tasks, ui, storage); + } catch (DudeException e) { + ui.showError(e.getMessage()); } - fileWriter.close(); - } catch (IOException e) { - System.out.println("Error writing to file: " + e.getMessage()); } } - - // Method to print the goodbye message - public static void byeDude() { - System.out.println("Bye. Hope to see you again soon!"); - drawLine(); - } - - // Main method public static void main(String[] args) { - hiDude(); - storeDude(); + new Dude("data/dude.txt").run(); } } - diff --git a/src/dude/Event.java b/src/dude/Event.java index 7872f4a1d..c61dbf34f 100644 --- a/src/dude/Event.java +++ b/src/dude/Event.java @@ -20,7 +20,7 @@ public static Event fromFileFormat(String fileString) { String[] parts = fileString.split("\\s\\|\\s"); Event event = new Event(parts[2], parts[3], parts[4]); if (parts[1].equals("1")) { - event.markAsDone(); + event.setDone(event.isDone); } return event; } diff --git a/src/dude/Parser.java b/src/dude/Parser.java new file mode 100644 index 000000000..81117566f --- /dev/null +++ b/src/dude/Parser.java @@ -0,0 +1,39 @@ +package dude; + +public class Parser { + + public static void parse(String input, TaskList tasks, Ui ui, Storage storage) throws DudeException { + String[] commandWords = input.split(" "); + String commandType = commandWords[0]; + + switch (commandType) { + case "bye": + ui.showFarewell(); + System.exit(0); + break; + case "list": + tasks.listTasks(); + break; + case "todo": + tasks.addTodoTask(input); + break; + case "deadline": + tasks.addDeadlineTask(input); + break; + case "event": + tasks.addEventTask(input); + break; + case "mark": + tasks.markOrUnmarkTask(input, true); // Mark as done + break; + case "unmark": + tasks.markOrUnmarkTask(input, false); // Mark as not done + break; + case "delete": + tasks.deleteTask(input); + break; + default: + throw new DudeException("I'm sorry, I don't know what that means :-("); + } + } +} diff --git a/src/dude/Storage.java b/src/dude/Storage.java new file mode 100644 index 000000000..8dd0d232f --- /dev/null +++ b/src/dude/Storage.java @@ -0,0 +1,74 @@ +package dude; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Scanner; + +public class Storage { + + private final String filePath; + + public Storage(String filePath) { + this.filePath = filePath; + } + + public void setupFile() { + // Check if the directory exists, if not, create it + File file = new File(filePath); + if (!file.getParentFile().exists()) { + file.getParentFile().mkdirs(); + } + + // Check if the file exists, if not, create it + if (!file.exists()) { + try { + file.createNewFile(); + } catch (IOException e) { + System.out.println("Error creating file: " + e.getMessage()); + } + } + } + + public ArrayList loadFromFile() { + ArrayList tasks = new ArrayList<>(); + try { + File file = new File(filePath); + Scanner fileReader = new Scanner(file); + + while (fileReader.hasNextLine()) { + String line = fileReader.nextLine(); + char taskType = line.charAt(0); + switch (taskType) { + case 'T': + tasks.add(Task.fromFileFormat(line)); + break; + case 'D': + tasks.add(Deadline.fromFileFormat(line)); + break; + case 'E': + tasks.add(Event.fromFileFormat(line)); + break; + } + } + + fileReader.close(); + } catch (IOException e) { + System.out.println("Error reading from file: " + e.getMessage()); + } + return tasks; + } + + public void saveToFile(ArrayList tasks) { + try { + FileWriter fileWriter = new FileWriter(filePath); + for (Task task : tasks) { + fileWriter.write(task.toFileFormat() + "\n"); + } + fileWriter.close(); + } catch (IOException e) { + System.out.println("Error writing to file: " + e.getMessage()); + } + } +} diff --git a/src/dude/Task.java b/src/dude/Task.java index 5870b4e0c..0dc864fed 100644 --- a/src/dude/Task.java +++ b/src/dude/Task.java @@ -19,8 +19,8 @@ public String getDescription() { return description; } - public void markAsDone() { - isDone = true; + public void setDone(boolean isDone) { + this.isDone = isDone; } public String toFileFormat() { @@ -31,7 +31,7 @@ public static Task fromFileFormat(String fileString) { String[] parts = fileString.split("\\s\\|\\s"); Task task = new Task(parts[2]); if (parts[1].equals("1")) { - task.markAsDone(); + task.setDone(true); } return task; } diff --git a/src/dude/TaskList.java b/src/dude/TaskList.java new file mode 100644 index 000000000..0e2da8573 --- /dev/null +++ b/src/dude/TaskList.java @@ -0,0 +1,114 @@ +package dude; + +import java.util.ArrayList; + +public class TaskList { + + private ArrayList tasks; + private Storage storage; + private Ui ui; + + public TaskList(ArrayList tasks, Storage storage, Ui ui) { + this.tasks = tasks; + this.storage = storage; + this.ui = ui; + } + + public void listTasks() { + if (tasks.isEmpty()) { + ui.showMessage("You have no tasks in your list!"); + } else { + ui.showTasks(tasks); + } + } + + public void addTodoTask(String input) throws DudeException { + validateInput(input, 5, "☹ OOPS!!! The description of a todo cannot be empty."); + + String taskDescription = input.substring(5).trim(); + Task newTask = new Task(taskDescription); + tasks.add(newTask); + + ui.showAddedTask(newTask, tasks.size()); + storage.saveToFile(tasks); + } + + public void addDeadlineTask(String input) throws DudeException { + validateInput(input, 9, "☹ OOPS!!! The description of a deadline cannot be empty."); + + int byIndex = input.indexOf("/by"); + if (byIndex == -1) { + throw new DudeException("☹ OOPS!!! Please specify a deadline using /by."); + } + + String taskDescription = input.substring(9, byIndex).trim(); + String by = input.substring(byIndex + 4).trim(); + + Deadline newDeadline = new Deadline(taskDescription, by); + tasks.add(newDeadline); + + ui.showAddedTask(newDeadline, tasks.size()); + storage.saveToFile(tasks); + } + + public void addEventTask(String input) throws DudeException { + validateInput(input, 6, "☹ OOPS!!! The description of an event cannot be empty."); + + int fromIndex = input.indexOf("/from"); + int toIndex = input.indexOf("/to"); + + if (fromIndex == -1 || toIndex == -1) { + throw new DudeException("☹ OOPS!!! Please specify event time using /from and /to."); + } + + String taskDescription = input.substring(6, fromIndex).trim(); + String from = input.substring(fromIndex + 6, toIndex).trim(); + String to = input.substring(toIndex + 4).trim(); + + Event newEvent = new Event(taskDescription, from, to); + tasks.add(newEvent); + + ui.showAddedTask(newEvent, tasks.size()); + storage.saveToFile(tasks); + } + + public void markOrUnmarkTask(String input, boolean mark) throws DudeException { + int index = parseTaskIndex(input); + Task task = tasks.get(index); + task.setDone(mark); + + ui.showMarkedTask(task, mark); + storage.saveToFile(tasks); + } + + public void deleteTask(String input) throws DudeException { + int index = parseTaskIndex(input); + Task removedTask = tasks.remove(index); + + ui.showRemovedTask(removedTask, tasks.size()); + storage.saveToFile(tasks); + } + + private int parseTaskIndex(String input) throws DudeException { + String[] arrOfInput = input.split(" "); + if (arrOfInput.length < 2) { + throw new DudeException("Please specify the task index."); + } + + try { + int index = Integer.parseInt(arrOfInput[1]) - 1; + if (index < 0 || index >= tasks.size()) { + throw new DudeException("Task index out of range."); + } + return index; + } catch (NumberFormatException e) { + throw new DudeException("Invalid task index format."); + } + } + + private void validateInput(String input, int minLength, String errorMessage) throws DudeException { + if (input.length() <= minLength || input.substring(minLength).trim().isEmpty()) { + throw new DudeException(errorMessage); + } + } +} diff --git a/src/dude/Ui.java b/src/dude/Ui.java new file mode 100644 index 000000000..2ce73ca7c --- /dev/null +++ b/src/dude/Ui.java @@ -0,0 +1,89 @@ +package dude; + +import java.util.ArrayList; +import java.util.Scanner; + +public class Ui { + private final Scanner scanner; + + public Ui() { + this.scanner = new Scanner(System.in); + } + + public void drawLine() { + for (int i = 0; i < 30; i++) { + System.out.print("_"); + } + System.out.println(); + } + + public void showGreeting() { + String logo = "### # \n" + + "# # # \n" + + "# # # # ### ## \n" + + "# # # # # # # ## \n" + + "# # # # # # ## \n" + + "### ### ### ## \n"; + + System.out.println("Hello from\n" + logo); + drawLine(); + System.out.println("Hello! I'm your best dude:)"); + System.out.println("What can I do for you?"); + drawLine(); + } + + public void showFarewell() { + drawLine(); + System.out.println("Bye. Hope to see you again soon!"); + drawLine(); + } + + public void showMessage(String message) { + drawLine(); + System.out.println(message); + drawLine(); + } + + public void showError(String message) { + drawLine(); + System.out.println("☹ OOPS!!! " + message); + drawLine(); + } + + public void showTasks(ArrayList tasks) { + drawLine(); + System.out.println("Here are the tasks in your list:"); + for (int i = 0; i < tasks.size(); i++) { + System.out.println((i + 1) + ". " + tasks.get(i)); + } + drawLine(); + } + + public void showAddedTask(Task task, int taskCount) { + drawLine(); + System.out.println("Got it. I've added this task:"); + System.out.println(" " + task); + System.out.println("Now you have " + taskCount + (taskCount == 1 ? " task" : " tasks") + " in the list."); + drawLine(); + } + + public void showRemovedTask(Task task, int taskCount) { + drawLine(); + System.out.println("Noted. I've removed this task:"); + System.out.println(" " + task); + System.out.println("Now you have " + taskCount + (taskCount == 1 ? " task" : " tasks") + " in the list."); + drawLine(); + } + + public void showMarkedTask(Task task, boolean isDone) { + drawLine(); + String message = isDone ? "Nice! I've marked this task as done:" : "OK, I've marked this task as not done yet:"; + System.out.println(message); + System.out.println(" " + task); + drawLine(); + } + + public String readCommand() { + return scanner.nextLine(); + } +} From c2b4e7c3ea6f6d4b838c456e101f83a8b4814f80 Mon Sep 17 00:00:00 2001 From: aaronxujiachen <1943999635x@gmail.com> Date: Sat, 30 Sep 2023 00:53:00 +0800 Subject: [PATCH 16/23] Add Dude Level 9 --- data/dude.txt | 3 +++ src/dude/Parser.java | 7 +++++++ src/dude/TaskList.java | 12 ++++++++++++ src/dude/Ui.java | 9 +++++++++ 4 files changed, 31 insertions(+) diff --git a/data/dude.txt b/data/dude.txt index e69de29bb..a07b82274 100644 --- a/data/dude.txt +++ b/data/dude.txt @@ -0,0 +1,3 @@ +T | 0 | borrow book +T | 0 | djkds +E | 0 | project meeting | Mon 2pm | 4pm diff --git a/src/dude/Parser.java b/src/dude/Parser.java index 81117566f..54a8f8f36 100644 --- a/src/dude/Parser.java +++ b/src/dude/Parser.java @@ -1,5 +1,7 @@ package dude; +import java.util.ArrayList; + public class Parser { public static void parse(String input, TaskList tasks, Ui ui, Storage storage) throws DudeException { @@ -32,6 +34,11 @@ public static void parse(String input, TaskList tasks, Ui ui, Storage storage) t case "delete": tasks.deleteTask(input); break; + case "find": + String keyword = input.substring(5).trim(); // Extract the search keyword + ArrayList matchingTasks = tasks.findTasksByKeyword(keyword); // Find matching tasks + ui.showFoundTasks(matchingTasks); // Display matching tasks + break; default: throw new DudeException("I'm sorry, I don't know what that means :-("); } diff --git a/src/dude/TaskList.java b/src/dude/TaskList.java index 0e2da8573..88c028fd1 100644 --- a/src/dude/TaskList.java +++ b/src/dude/TaskList.java @@ -106,6 +106,18 @@ private int parseTaskIndex(String input) throws DudeException { } } + public ArrayList findTasksByKeyword(String keyword) { + ArrayList matchingTasks = new ArrayList<>(); + + for (Task task : tasks) { + if (task.getDescription().toLowerCase().contains(keyword.toLowerCase())) { + matchingTasks.add(task); + } + } + + return matchingTasks; + } + private void validateInput(String input, int minLength, String errorMessage) throws DudeException { if (input.length() <= minLength || input.substring(minLength).trim().isEmpty()) { throw new DudeException(errorMessage); diff --git a/src/dude/Ui.java b/src/dude/Ui.java index 2ce73ca7c..cac9607ad 100644 --- a/src/dude/Ui.java +++ b/src/dude/Ui.java @@ -83,6 +83,15 @@ public void showMarkedTask(Task task, boolean isDone) { drawLine(); } + public void showFoundTasks(ArrayList matchingTasks) { + drawLine(); + System.out.println("Here are the matching tasks in your list:"); + for (int i = 0; i < matchingTasks.size(); i++) { + System.out.println((i + 1) + ". " + matchingTasks.get(i)); + } + drawLine(); + } + public String readCommand() { return scanner.nextLine(); } From 63adef54a0e1e346d2fbd9f2b057a677aa5d5911 Mon Sep 17 00:00:00 2001 From: aaronxujiachen <1943999635x@gmail.com> Date: Tue, 3 Oct 2023 00:50:52 +0800 Subject: [PATCH 17/23] Add Comments For Dude --- src/dude/Deadline.java | 26 +++++++++++++++ src/dude/Dude.java | 20 ++++++++++++ src/dude/DudeException.java | 10 ++++++ src/dude/Event.java | 27 ++++++++++++++++ src/dude/Parser.java | 13 ++++++++ src/dude/Storage.java | 25 +++++++++++++++ src/dude/Task.java | 40 +++++++++++++++++++++++ src/dude/TaskList.java | 64 +++++++++++++++++++++++++++++++++++++ src/dude/Ui.java | 57 +++++++++++++++++++++++++++++++++ 9 files changed, 282 insertions(+) diff --git a/src/dude/Deadline.java b/src/dude/Deadline.java index 33c766326..32a82ff56 100644 --- a/src/dude/Deadline.java +++ b/src/dude/Deadline.java @@ -1,19 +1,40 @@ package dude; +/** + * The `Deadline` class represents a task with a deadline, which has a description and a due date (by). + * It extends the `Task` class and provides additional fields and methods specific to deadline tasks. + */ public class Deadline extends Task { private String by; + /** + * Constructs a new `Deadline` task with the specified description and due date (by). + * + * @param description The description of the deadline task. + * @param by The due date of the deadline task. + */ public Deadline(String description, String by) { super(description); this.by = by; this.type = "[D]"; } + /** + * Converts the deadline task to a formatted string for saving to a file. + * + * @return A string representation of the deadline task in file format. + */ @Override public String toFileFormat() { return super.toFileFormat() + " | " + by; } + /** + * Creates a `Deadline` object from a string in file format. + * + * @param fileString A string containing the deadline task details in file format. + * @return A `Deadline` object parsed from the file string. + */ public static Deadline fromFileFormat(String fileString) { String[] parts = fileString.split("\\s\\|\\s"); Deadline deadline = new Deadline(parts[2], parts[3]); @@ -23,6 +44,11 @@ public static Deadline fromFileFormat(String fileString) { return deadline; } + /** + * Generates a string representation of the deadline task, including its description and due date. + * + * @return A string representing the deadline task. + */ @Override public String toString() { return super.toString() + " (by: " + by + ")"; diff --git a/src/dude/Dude.java b/src/dude/Dude.java index 211715fbe..23242a12f 100644 --- a/src/dude/Dude.java +++ b/src/dude/Dude.java @@ -2,11 +2,21 @@ import java.util.ArrayList; +/** + * The `Dude` class represents the main application class for the Dude task manager. + * It initializes the user interface, storage, and task list, and manages the main + * execution flow of the program. + */ public class Dude { private Storage storage; private TaskList tasks; private Ui ui; + /** + * Constructs a new `Dude` instance with the specified file path. + * + * @param filePath The file path for storing task data. + */ public Dude(String filePath) { ui = new Ui(); storage = new Storage(filePath); @@ -19,6 +29,10 @@ public Dude(String filePath) { } } + /** + * Runs the Dude application, displaying a greeting message and entering an + * infinite loop to process user commands until the user exits the program. + */ public void run() { ui.showGreeting(); while (true) { // Infinite loop since exit is handled in the Parser @@ -31,6 +45,12 @@ public void run() { } } + /** + * The entry point of the Dude application. Creates a new `Dude` instance with + * a specified data file path and starts the application by calling the `run` method. + * + * @param args Command-line arguments (not used in this application). + */ public static void main(String[] args) { new Dude("data/dude.txt").run(); } diff --git a/src/dude/DudeException.java b/src/dude/DudeException.java index efc2c2369..312511eac 100644 --- a/src/dude/DudeException.java +++ b/src/dude/DudeException.java @@ -1,6 +1,16 @@ package dude; +/** + * The `DudeException` class represents a custom exception that can be thrown to handle + * exceptional situations within the Dude application. + */ public class DudeException extends Exception { + + /** + * Constructs a new `DudeException` with the specified error message. + * + * @param message The error message associated with the exception. + */ public DudeException(String message) { super(message); } diff --git a/src/dude/Event.java b/src/dude/Event.java index c61dbf34f..735bb50ab 100644 --- a/src/dude/Event.java +++ b/src/dude/Event.java @@ -1,9 +1,20 @@ package dude; +/** + * The `Event` class represents an event task that has a description, start time (from), and end time (to). + * It extends the `Task` class and provides additional fields and methods specific to event tasks. + */ public class Event extends Task { private String from; private String to; + /** + * Constructs a new `Event` task with the specified description, start time (from), and end time (to). + * + * @param description The description of the event task. + * @param from The start time of the event. + * @param to The end time of the event. + */ public Event(String description, String from, String to) { super(description); this.from = from; @@ -11,11 +22,22 @@ public Event(String description, String from, String to) { this.type = "[E]"; } + /** + * Converts the event task to a formatted string for saving to a file. + * + * @return A string representation of the event task in file format. + */ @Override public String toFileFormat() { return super.toFileFormat() + " | " + from + " | " + to; } + /** + * Creates an `Event` object from a string in file format. + * + * @param fileString A string containing the event task details in file format. + * @return An `Event` object parsed from the file string. + */ public static Event fromFileFormat(String fileString) { String[] parts = fileString.split("\\s\\|\\s"); Event event = new Event(parts[2], parts[3], parts[4]); @@ -25,6 +47,11 @@ public static Event fromFileFormat(String fileString) { return event; } + /** + * Generates a string representation of the event task, including its description and time frame. + * + * @return A string representing the event task. + */ @Override public String toString() { return super.toString() + " (from: " + from + " to: " + to + ")"; diff --git a/src/dude/Parser.java b/src/dude/Parser.java index 81117566f..aad17f4bd 100644 --- a/src/dude/Parser.java +++ b/src/dude/Parser.java @@ -1,7 +1,20 @@ package dude; +/** + * The `Parser` class is responsible for parsing user input commands and executing the + * corresponding actions on the task list. + */ public class Parser { + /** + * Parses the user input command and performs the corresponding action on the task list. + * + * @param input The user input command to parse and execute. + * @param tasks The TaskList instance containing the list of tasks. + * @param ui The Ui instance for user interactions and output. + * @param storage The Storage instance for saving and loading tasks. + * @throws DudeException If there's an error during command parsing or execution. + */ public static void parse(String input, TaskList tasks, Ui ui, Storage storage) throws DudeException { String[] commandWords = input.split(" "); String commandType = commandWords[0]; diff --git a/src/dude/Storage.java b/src/dude/Storage.java index 8dd0d232f..919670f7d 100644 --- a/src/dude/Storage.java +++ b/src/dude/Storage.java @@ -6,14 +6,27 @@ import java.util.ArrayList; import java.util.Scanner; +/** + * The `Storage` class manages file input and output operations, responsible for + * saving tasks to a file and loading tasks from a file. + */ public class Storage { private final String filePath; + /** + * Constructs a `Storage` instance with the specified file path. + * + * @param filePath The path to the file used for storing tasks. + */ public Storage(String filePath) { this.filePath = filePath; } + /** + * Checks if the directory and file specified by the file path exist. If they + * don't exist, this method creates the necessary directory and file. + */ public void setupFile() { // Check if the directory exists, if not, create it File file = new File(filePath); @@ -31,6 +44,12 @@ public void setupFile() { } } + /** + * Loads tasks from the file specified by the file path and returns them as an + * ArrayList of tasks. + * + * @return An ArrayList containing the tasks loaded from the file. + */ public ArrayList loadFromFile() { ArrayList tasks = new ArrayList<>(); try { @@ -60,6 +79,12 @@ public ArrayList loadFromFile() { return tasks; } + /** + * Saves the provided ArrayList of tasks to the file specified by the file + * path. Each task is written to a separate line in the file. + * + * @param tasks The ArrayList of tasks to be saved to the file. + */ public void saveToFile(ArrayList tasks) { try { FileWriter fileWriter = new FileWriter(filePath); diff --git a/src/dude/Task.java b/src/dude/Task.java index 0dc864fed..7469f3b5a 100644 --- a/src/dude/Task.java +++ b/src/dude/Task.java @@ -1,32 +1,67 @@ package dude; +/** + * The `Task` class represents a generic task with a description and completion status. + * It serves as the base class for different types of tasks, such as deadlines and events. + */ public class Task { protected String description; protected boolean isDone; protected String type; + /** + * Constructs a new generic task with the specified description. + * + * @param description The description of the task. + */ public Task(String description) { this.description = description; this.isDone = false; this.type = "[T]"; // Represents a generic task. } + /** + * Returns a string representing the completion status of the task. + * + * @return A string containing "[X]" if the task is completed, "[ ]" otherwise. + */ public String getStatusIcon() { return (isDone ? "[X]" : "[ ]"); } + /** + * Retrieves the description of the task. + * + * @return The description of the task. + */ public String getDescription() { return description; } + /** + * Sets the completion status of the task. + * + * @param isDone True if the task is completed, false otherwise. + */ public void setDone(boolean isDone) { this.isDone = isDone; } + /** + * Converts the task to a formatted string for saving to a file. + * + * @return A string representation of the task in file format. + */ public String toFileFormat() { return type.charAt(1) + " | " + (isDone ? "1" : "0") + " | " + description; } + /** + * Creates a `Task` object from a string in file format. + * + * @param fileString A string containing the task details in file format. + * @return A `Task` object parsed from the file string. + */ public static Task fromFileFormat(String fileString) { String[] parts = fileString.split("\\s\\|\\s"); Task task = new Task(parts[2]); @@ -36,6 +71,11 @@ public static Task fromFileFormat(String fileString) { return task; } + /** + * Generates a string representation of the task, including its type, completion status, and description. + * + * @return A string representing the task. + */ @Override public String toString() { return type + getStatusIcon() + " " + description; diff --git a/src/dude/TaskList.java b/src/dude/TaskList.java index 0e2da8573..471bbdae6 100644 --- a/src/dude/TaskList.java +++ b/src/dude/TaskList.java @@ -2,18 +2,35 @@ import java.util.ArrayList; +import java.util.ArrayList; + +/** + * The `TaskList` class manages a list of tasks, providing operations to interact + * with the tasks such as listing, adding, marking, and deleting tasks. + */ public class TaskList { private ArrayList tasks; private Storage storage; private Ui ui; + /** + * Constructs a `TaskList` instance with the given list of tasks, storage, and user interface. + * + * @param tasks The ArrayList of tasks to manage. + * @param storage The Storage instance for saving and loading tasks. + * @param ui The Ui instance for user interactions. + */ public TaskList(ArrayList tasks, Storage storage, Ui ui) { this.tasks = tasks; this.storage = storage; this.ui = ui; } + /** + * Lists all tasks in the task list. If the list is empty, a message indicating no + * tasks are present is shown. + */ public void listTasks() { if (tasks.isEmpty()) { ui.showMessage("You have no tasks in your list!"); @@ -22,6 +39,12 @@ public void listTasks() { } } + /** + * Adds a todo task to the task list based on user input. + * + * @param input The input command specifying the todo task. + * @throws DudeException If the input validation or task addition fails. + */ public void addTodoTask(String input) throws DudeException { validateInput(input, 5, "☹ OOPS!!! The description of a todo cannot be empty."); @@ -33,6 +56,12 @@ public void addTodoTask(String input) throws DudeException { storage.saveToFile(tasks); } + /** + * Adds a deadline task to the task list based on user input. + * + * @param input The input command specifying the deadline task. + * @throws DudeException If the input validation or task addition fails. + */ public void addDeadlineTask(String input) throws DudeException { validateInput(input, 9, "☹ OOPS!!! The description of a deadline cannot be empty."); @@ -51,6 +80,12 @@ public void addDeadlineTask(String input) throws DudeException { storage.saveToFile(tasks); } + /** + * Adds an event task to the task list based on user input. + * + * @param input The input command specifying the event task. + * @throws DudeException If the input validation or task addition fails. + */ public void addEventTask(String input) throws DudeException { validateInput(input, 6, "☹ OOPS!!! The description of an event cannot be empty."); @@ -72,6 +107,13 @@ public void addEventTask(String input) throws DudeException { storage.saveToFile(tasks); } + /** + * Marks or unmarks a task as done based on user input. + * + * @param input The input command specifying the task to mark/unmark. + * @param mark True if the task should be marked as done, false if unmarked. + * @throws DudeException If the input validation or task marking fails. + */ public void markOrUnmarkTask(String input, boolean mark) throws DudeException { int index = parseTaskIndex(input); Task task = tasks.get(index); @@ -81,6 +123,12 @@ public void markOrUnmarkTask(String input, boolean mark) throws DudeException { storage.saveToFile(tasks); } + /** + * Deletes a task from the task list based on user input. + * + * @param input The input command specifying the task to delete. + * @throws DudeException If the input validation or task deletion fails. + */ public void deleteTask(String input) throws DudeException { int index = parseTaskIndex(input); Task removedTask = tasks.remove(index); @@ -89,6 +137,13 @@ public void deleteTask(String input) throws DudeException { storage.saveToFile(tasks); } + /** + * Parses the task index from user input and returns it. + * + * @param input The user input containing the task index. + * @return The parsed task index. + * @throws DudeException If the input format is invalid or the index is out of range. + */ private int parseTaskIndex(String input) throws DudeException { String[] arrOfInput = input.split(" "); if (arrOfInput.length < 2) { @@ -106,6 +161,15 @@ private int parseTaskIndex(String input) throws DudeException { } } + /** + * Validates the input against a minimum length and displays an error message if + * the input is invalid. + * + * @param input The input to validate. + * @param minLength The minimum length of the input. + * @param errorMessage The error message to display if validation fails. + * @throws DudeException If the input validation fails. + */ private void validateInput(String input, int minLength, String errorMessage) throws DudeException { if (input.length() <= minLength || input.substring(minLength).trim().isEmpty()) { throw new DudeException(errorMessage); diff --git a/src/dude/Ui.java b/src/dude/Ui.java index 2ce73ca7c..f16a133e6 100644 --- a/src/dude/Ui.java +++ b/src/dude/Ui.java @@ -3,13 +3,23 @@ import java.util.ArrayList; import java.util.Scanner; +/** + * The `Ui` class handles user interface interactions, including displaying messages, + * reading user input, and formatting output for the Dude task manager. + */ public class Ui { private final Scanner scanner; + /** + * Constructs a new `Ui` instance with a scanner for reading user input from the console. + */ public Ui() { this.scanner = new Scanner(System.in); } + /** + * Draws a horizontal line of underscores to visually separate sections of output. + */ public void drawLine() { for (int i = 0; i < 30; i++) { System.out.print("_"); @@ -17,6 +27,9 @@ public void drawLine() { System.out.println(); } + /** + * Displays a greeting message and the Dude logo when the application starts. + */ public void showGreeting() { String logo = "### # \n" + "# # # \n" @@ -32,24 +45,42 @@ public void showGreeting() { drawLine(); } + /** + * Displays a farewell message when the user exits the application. + */ public void showFarewell() { drawLine(); System.out.println("Bye. Hope to see you again soon!"); drawLine(); } + /** + * Displays a general message to the user with a horizontal line separator. + * + * @param message The message to display. + */ public void showMessage(String message) { drawLine(); System.out.println(message); drawLine(); } + /** + * Displays an error message with an "OOPS!!!" prefix and a horizontal line separator. + * + * @param message The error message to display. + */ public void showError(String message) { drawLine(); System.out.println("☹ OOPS!!! " + message); drawLine(); } + /** + * Displays a list of tasks with their descriptions and numbers. + * + * @param tasks The list of tasks to display. + */ public void showTasks(ArrayList tasks) { drawLine(); System.out.println("Here are the tasks in your list:"); @@ -59,6 +90,13 @@ public void showTasks(ArrayList tasks) { drawLine(); } + /** + * Displays a message confirming the addition of a new task and the current total + * number of tasks in the list. + * + * @param task The task that was added. + * @param taskCount The total number of tasks after adding the new task. + */ public void showAddedTask(Task task, int taskCount) { drawLine(); System.out.println("Got it. I've added this task:"); @@ -67,6 +105,13 @@ public void showAddedTask(Task task, int taskCount) { drawLine(); } + /** + * Displays a message confirming the removal of a task and the current total + * number of tasks in the list. + * + * @param task The task that was removed. + * @param taskCount The total number of tasks after removing the task. + */ public void showRemovedTask(Task task, int taskCount) { drawLine(); System.out.println("Noted. I've removed this task:"); @@ -75,6 +120,13 @@ public void showRemovedTask(Task task, int taskCount) { drawLine(); } + /** + * Displays a message confirming the marking of a task as done or not done, + * along with the task's status. + * + * @param task The task that was marked. + * @param isDone A boolean indicating whether the task is marked as done or not done. + */ public void showMarkedTask(Task task, boolean isDone) { drawLine(); String message = isDone ? "Nice! I've marked this task as done:" : "OK, I've marked this task as not done yet:"; @@ -83,6 +135,11 @@ public void showMarkedTask(Task task, boolean isDone) { drawLine(); } + /** + * Reads a command entered by the user from the console and returns it as a string. + * + * @return The user's input command. + */ public String readCommand() { return scanner.nextLine(); } From 64b08937fcc603e4c90264577204e97c56bdb6d9 Mon Sep 17 00:00:00 2001 From: aaronxujiachen <1943999635x@gmail.com> Date: Tue, 3 Oct 2023 09:38:45 +0800 Subject: [PATCH 18/23] Resolve Merge Conflict --- src/dude/TaskList.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/dude/TaskList.java b/src/dude/TaskList.java index f6c0dff05..78cac8823 100644 --- a/src/dude/TaskList.java +++ b/src/dude/TaskList.java @@ -2,8 +2,6 @@ import java.util.ArrayList; -import java.util.ArrayList; - /** * The `TaskList` class manages a list of tasks, providing operations to interact * with the tasks such as listing, adding, marking, and deleting tasks. From 85bb25c2a2e3ad6d9a3606dd0a86033a30f3d59c Mon Sep 17 00:00:00 2001 From: XuJiaChen_Aaron <57344818+aaronxujiachen@users.noreply.github.com> Date: Tue, 3 Oct 2023 18:15:23 +0800 Subject: [PATCH 19/23] Update README.md Userguide for Dude. --- README.md | 94 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 70 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 8715d4d91..6f3b04aa7 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,70 @@ -# Duke project template - -This is a project template for a greenfield Java project. It's named after the Java mascot _Duke_. Given below are instructions on how to use it. - -## Setting up in Intellij - -Prerequisites: JDK 11, update Intellij to the most recent version. - -1. Open Intellij (if you are not in the welcome screen, click `File` > `Close Project` to close the existing project first) -1. Open the project into Intellij as follows: - 1. Click `Open`. - 1. Select the project directory, and click `OK`. - 1. If there are any further prompts, accept the defaults. -1. Configure the project to use **JDK 11** (not other versions) as explained in [here](https://www.jetbrains.com/help/idea/sdk.html#set-up-jdk).
- In the same dialog, set the **Project language level** field to the `SDK default` option. -3. After that, locate the `src/main/java/Duke.java` file, right-click it, and choose `Run Duke.main()` (if the code editor is showing compile errors, try restarting the IDE). If the setup is correct, you should see something like the below as the output: - ``` - Hello from - ____ _ - | _ \ _ _| | _____ - | | | | | | | |/ / _ \ - | |_| | |_| | < __/ - |____/ \__,_|_|\_\___| - ``` +# Dude Chatbot User Guide + +Hello from + + /$$$$$$$ /$$ +| $$__ $$ | $$ +| $$ \ $$ /$$ /$$ /$$$$$$$ /$$$$$$ +| $$ | $$| $$ | $$ /$$__ $$ /$$__ $$ +| $$ | $$| $$ | $$| $$ | $$| $$$$$$$$ +| $$ | $$| $$ | $$| $$ | $$| $$_____/ +| $$$$$$$/| $$$$$$/| $$$$$$$| $$$$$$$ +|_______/ \______/ \_______/ \_______/ + +Welcome to Dude, your trusty task management chatbot. Dude helps you stay organized by keeping track of your tasks, whether they're to-dos, deadlines, or events. This user guide will provide you with the essential information to make the most of Dude's features. + + +## Getting Started + +To get started with Dude, follow these steps: + +1. Ensure you have Java Development Kit (JDK) 11 installed on your computer. +2. Make sure you have the latest version of IntelliJ IDEA installed. +3. Clone or download the Dude project repository. + +## Setting Up Dude in IntelliJ IDEA + +1. Open IntelliJ IDEA. +2. If you have an existing project open, close it. +3. Click on "File" > "Open" and select the Dude project directory. +4. Configure the project to use JDK 11: + - Click on "File" > "Project Structure." + - Under "Project," set the "Project SDK" to JDK 11. + - Set the "Project language level" to "SDK default." + +## Running Dude + +1. Locate the `Dude.java` file in the `src/main/java` directory of the Dude project. +2. Right-click on `Dude.java` and select "Run Dude.main()". +3. If everything is set up correctly, Dude will start, and you'll see a greeting message. + +## Using Dude + +Dude understands various commands to manage your tasks. Here are some essential commands: + +- `list`: List all tasks in your task list. +- `todo `: Add a to-do task. +- `deadline /by `: Add a deadline task. +- `event /from /to `: Add an event task. +- `mark `: Mark a task as done. +- `unmark `: Mark a task as not done. +- `delete `: Delete a task from the list. +- `find `: Find tasks containing a specific keyword. +- `bye`: Exit Dude. + +## Examples: + +- To add a to-do task: `todo Buy groceries` +- To add a deadline task: `deadline Submit report /by 2023-12-31` +- To add an event task: `event Team meeting /from 2023-09-30 /to 2023-10-01` +- To mark a task as done: `mark 1` +- To delete a task: `delete 2` +- To find tasks containing a keyword: `find book` + +Remember to replace ``, ``, ``, ``, ``, and `` with your specific task details. + +## Conclusion + +You're now ready to start using Dude to manage your tasks efficiently. If you have any questions or encounter issues, feel free to reach out to us. Dude is here to make task management a breeze! + +Happy tasking! From 0d42444a2bafe539654b2d2a129418bebdb73f65 Mon Sep 17 00:00:00 2001 From: XuJiaChen_Aaron <57344818+aaronxujiachen@users.noreply.github.com> Date: Tue, 3 Oct 2023 18:19:14 +0800 Subject: [PATCH 20/23] Update README.md --- README.md | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 6f3b04aa7..32075f9b3 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,13 @@ # Dude Chatbot User Guide Hello from - - /$$$$$$$ /$$ -| $$__ $$ | $$ -| $$ \ $$ /$$ /$$ /$$$$$$$ /$$$$$$ -| $$ | $$| $$ | $$ /$$__ $$ /$$__ $$ -| $$ | $$| $$ | $$| $$ | $$| $$$$$$$$ -| $$ | $$| $$ | $$| $$ | $$| $$_____/ -| $$$$$$$/| $$$$$$/| $$$$$$$| $$$$$$$ -|_______/ \______/ \_______/ \_______/ +### # +# # # +# # # # ### ## +# # # # # # # ## +# # # # # # ## +### ### ### ## Welcome to Dude, your trusty task management chatbot. Dude helps you stay organized by keeping track of your tasks, whether they're to-dos, deadlines, or events. This user guide will provide you with the essential information to make the most of Dude's features. From 76e80b4a39b13d1135983237199611db1a2386d8 Mon Sep 17 00:00:00 2001 From: XuJiaChen_Aaron <57344818+aaronxujiachen@users.noreply.github.com> Date: Tue, 3 Oct 2023 18:19:51 +0800 Subject: [PATCH 21/23] Update README.md --- README.md | 8 -------- 1 file changed, 8 deletions(-) diff --git a/README.md b/README.md index 32075f9b3..e72bbc584 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,5 @@ # Dude Chatbot User Guide -Hello from - -### # -# # # -# # # # ### ## -# # # # # # # ## -# # # # # # ## -### ### ### ## Welcome to Dude, your trusty task management chatbot. Dude helps you stay organized by keeping track of your tasks, whether they're to-dos, deadlines, or events. This user guide will provide you with the essential information to make the most of Dude's features. From a1189ae0bed6a7748e1083891526cfffe3d06684 Mon Sep 17 00:00:00 2001 From: aaronxujiachen <1943999635x@gmail.com> Date: Thu, 5 Oct 2023 23:24:53 +0800 Subject: [PATCH 22/23] Update UserGuide Website --- docs/README.md | 62 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 46 insertions(+), 16 deletions(-) diff --git a/docs/README.md b/docs/README.md index 8077118eb..95311ac3c 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,29 +1,59 @@ -# User Guide +# Dude Chatbot User Guide -## Features +Welcome to Dude, your trusty task management chatbot. Dude helps you stay organized by keeping track of your tasks, whether they're to-dos, deadlines, or events. This user guide will provide you with the essential information to make the most of Dude's features. -### Feature-ABC -Description of the feature. +## Getting Started -### Feature-XYZ +To get started with Dude, follow these steps: -Description of the feature. +1. Ensure you have Java Development Kit (JDK) 11 installed on your computer. +2. Make sure you have the latest version of IntelliJ IDEA installed. +3. Clone or download the Dude project repository. -## Usage +## Setting Up Dude in IntelliJ IDEA -### `Keyword` - Describe action +1. Open IntelliJ IDEA. +2. If you have an existing project open, close it. +3. Click on "File" > "Open" and select the Dude project directory. +4. Configure the project to use JDK 11: + - Click on "File" > "Project Structure." + - Under "Project," set the "Project SDK" to JDK 11. + - Set the "Project language level" to "SDK default." -Describe the action and its outcome. +## Running Dude -Example of usage: +1. Locate the `Dude.java` file in the `src/main/java` directory of the Dude project. +2. Right-click on `Dude.java` and select "Run Dude.main()". +3. If everything is set up correctly, Dude will start, and you'll see a greeting message. -`keyword (optional arguments)` +## Using Dude -Expected outcome: +Dude understands various commands to manage your tasks. Here are some essential commands: -Description of the outcome. +- `list`: List all tasks in your task list. +- `todo `: Add a to-do task. +- `deadline /by `: Add a deadline task. +- `event /from /to `: Add an event task. +- `mark `: Mark a task as done. +- `unmark `: Mark a task as not done. +- `delete `: Delete a task from the list. +- `find `: Find tasks containing a specific keyword. +- `bye`: Exit Dude. -``` -expected output -``` +## Examples: + +- To add a to-do task: `todo Buy groceries` +- To add a deadline task: `deadline Submit report /by 2023-12-31` +- To add an event task: `event Team meeting /from 2023-09-30 /to 2023-10-01` +- To mark a task as done: `mark 1` +- To delete a task: `delete 2` +- To find tasks containing a keyword: `find book` + +Remember to replace ``, ``, ``, ``, ``, and `` with your specific task details. + +## Conclusion + +You're now ready to start using Dude to manage your tasks efficiently. If you have any questions or encounter issues, feel free to reach out to us. Dude is here to make task management a breeze! + +Happy tasking! From c7dbfd931df0008417628f7e01da8b996c4261ab Mon Sep 17 00:00:00 2001 From: aaronxujiachen <1943999635x@gmail.com> Date: Fri, 6 Oct 2023 01:50:50 +0800 Subject: [PATCH 23/23] Change the Path of dude.txt --- data/dude.txt | 3 --- src/dude/Dude.java | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) delete mode 100644 data/dude.txt diff --git a/data/dude.txt b/data/dude.txt deleted file mode 100644 index a07b82274..000000000 --- a/data/dude.txt +++ /dev/null @@ -1,3 +0,0 @@ -T | 0 | borrow book -T | 0 | djkds -E | 0 | project meeting | Mon 2pm | 4pm diff --git a/src/dude/Dude.java b/src/dude/Dude.java index 23242a12f..a1f57b4bc 100644 --- a/src/dude/Dude.java +++ b/src/dude/Dude.java @@ -52,6 +52,6 @@ public void run() { * @param args Command-line arguments (not used in this application). */ public static void main(String[] args) { - new Dude("data/dude.txt").run(); + new Dude("dude.txt").run(); } }