From 288af6dbf1b8792fe943858a66c9602e4b32ffae Mon Sep 17 00:00:00 2001 From: JinbaoAlex Date: Thu, 6 Feb 2025 20:38:51 +0800 Subject: [PATCH 01/21] Level-0 --- src/main/java/Duke.java | 10 ---------- src/main/java/Volkov.java | 11 +++++++++++ 2 files changed, 11 insertions(+), 10 deletions(-) delete mode 100644 src/main/java/Duke.java create mode 100644 src/main/java/Volkov.java diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java deleted file mode 100644 index 5d313334c..000000000 --- a/src/main/java/Duke.java +++ /dev/null @@ -1,10 +0,0 @@ -public class Duke { - public static void main(String[] args) { - String logo = " ____ _ \n" - + "| _ \\ _ _| | _____ \n" - + "| | | | | | | |/ / _ \\\n" - + "| |_| | |_| | < __/\n" - + "|____/ \\__,_|_|\\_\\___|\n"; - System.out.println("Hello from\n" + logo); - } -} diff --git a/src/main/java/Volkov.java b/src/main/java/Volkov.java new file mode 100644 index 000000000..713d759f3 --- /dev/null +++ b/src/main/java/Volkov.java @@ -0,0 +1,11 @@ +public class Volkov { + public static void main(String[] args) { + String logo = "____________________________________________________________\n" + + "Hello! I'm Volkov\n" + + "What can I do for you?\n" + + "____________________________________________________________\n" + + "Bye. Hope to see you again soon!\n" + + "____________________________________________________________\n"; + System.out.println(logo); + } +} From df3b9c38aba15d8c26389605de2e2717bd7d3ca2 Mon Sep 17 00:00:00 2001 From: JinbaoAlex Date: Thu, 6 Feb 2025 20:45:22 +0800 Subject: [PATCH 02/21] Level-1 Echo --- src/main/java/Volkov.java | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/src/main/java/Volkov.java b/src/main/java/Volkov.java index 713d759f3..71020ece5 100644 --- a/src/main/java/Volkov.java +++ b/src/main/java/Volkov.java @@ -1,11 +1,27 @@ +import java.util.Scanner; + public class Volkov { + public static String basicResponse(String msg) { + return " ____________________________________________________________\n" + + " " + msg + "\n" + + " ____________________________________________________________\n"; + } + public static void main(String[] args) { - String logo = "____________________________________________________________\n" - + "Hello! I'm Volkov\n" - + "What can I do for you?\n" - + "____________________________________________________________\n" - + "Bye. Hope to see you again soon!\n" - + "____________________________________________________________\n"; - System.out.println(logo); + String opening = " ____________________________________________________________\n" + + " Hello! I'm Volkov\n" + + " What can I do for you?\n" + + " ____________________________________________________________\n"; + System.out.println(opening); + + Scanner sc = new Scanner(System.in); + String command = sc.nextLine(); + while(!command.equals("bye")) { + String reply = basicResponse(command); + System.out.println(reply); + command = sc.nextLine(); + } + String end = basicResponse("Bye. Hope to see you again soon!"); + System.out.println(end); } } From 2477cf43f5e77d2c0d7460d458cbcce89a7f6e36 Mon Sep 17 00:00:00 2001 From: JinbaoAlex Date: Thu, 6 Feb 2025 22:04:54 +0800 Subject: [PATCH 03/21] Level-2 Added ability to store whatever text entered by the user and display them back to the user when requested --- src/main/java/Volkov.java | 45 ++++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/src/main/java/Volkov.java b/src/main/java/Volkov.java index 71020ece5..6b76ce45f 100644 --- a/src/main/java/Volkov.java +++ b/src/main/java/Volkov.java @@ -1,9 +1,11 @@ import java.util.Scanner; public class Volkov { + private static String[] storeText = new String[100]; + private static int storeTextIndex = 0; public static String basicResponse(String msg) { return " ____________________________________________________________\n" - + " " + msg + "\n" + + msg + "\n" + " ____________________________________________________________\n"; } @@ -15,13 +17,40 @@ public static void main(String[] args) { System.out.println(opening); Scanner sc = new Scanner(System.in); - String command = sc.nextLine(); - while(!command.equals("bye")) { - String reply = basicResponse(command); - System.out.println(reply); - command = sc.nextLine(); + + while (true) { + boolean shouldBreak = false; + String input = sc.nextLine(); + + switch (input) { + case "bye": + System.out.println(basicResponse(" Bye. Hope to see you again soon!")); + shouldBreak = true; + break; + case "list": + StringBuilder sb = new StringBuilder(); + boolean first = true; + for (int i = 0; i < storeTextIndex; i++) { +// reply = reply + " " + storeText[i] + "\n"; + if (first) { + first = false; + } else { + sb.append("\n"); + } + sb.append(storeText[i]); + } + System.out.println(basicResponse(sb.toString())); + break; + default: + String reply = basicResponse(" " + input); + System.out.println(reply); + storeText[storeTextIndex] = (storeTextIndex + 1) + ". " + input; + storeTextIndex++; + } + + if (shouldBreak) { + break; + } } - String end = basicResponse("Bye. Hope to see you again soon!"); - System.out.println(end); } } From 55f740f38bdd457fe41721371364893ee51a7a96 Mon Sep 17 00:00:00 2001 From: JinbaoAlex Date: Fri, 7 Feb 2025 00:08:28 +0800 Subject: [PATCH 04/21] Level-3 and A-Classes Added the ability to mark tasks as done, the ability to change the status back to not done, and Task class --- src/main/java/Task.java | 28 +++++++++++++++ src/main/java/Volkov.java | 74 +++++++++++++++++++++------------------ 2 files changed, 68 insertions(+), 34 deletions(-) create mode 100644 src/main/java/Task.java diff --git a/src/main/java/Task.java b/src/main/java/Task.java new file mode 100644 index 000000000..f49891636 --- /dev/null +++ b/src/main/java/Task.java @@ -0,0 +1,28 @@ +public class Task { + protected String description; + protected boolean isDone; + + public Task(String description) { + this.description = description; + this.isDone = false; + } + + public void markAsDone() { + isDone = true; + } + + public void unmarkAsDone() { + isDone = false; + } + + @Override + public String toString() { + String mark; + if (isDone) { + mark = "[X] "; + } else { + mark = "[ ] "; + } + return mark + description; + } +} diff --git a/src/main/java/Volkov.java b/src/main/java/Volkov.java index 6b76ce45f..db61581e1 100644 --- a/src/main/java/Volkov.java +++ b/src/main/java/Volkov.java @@ -1,9 +1,9 @@ import java.util.Scanner; public class Volkov { - private static String[] storeText = new String[100]; - private static int storeTextIndex = 0; - public static String basicResponse(String msg) { + private static Task[] listOfTasks = new Task[100]; + private static int storeTaskIndex = 0; + public static String formatResponse(String msg) { return " ____________________________________________________________\n" + msg + "\n" + " ____________________________________________________________\n"; @@ -11,45 +11,51 @@ public static String basicResponse(String msg) { public static void main(String[] args) { String opening = " ____________________________________________________________\n" - + " Hello! I'm Volkov\n" - + " What can I do for you?\n" + + " Hello! I'm Volkov\n" + + " What can I do for you?\n" + " ____________________________________________________________\n"; System.out.println(opening); Scanner sc = new Scanner(System.in); while (true) { - boolean shouldBreak = false; - String input = sc.nextLine(); + String input = sc.next(); - switch (input) { - case "bye": - System.out.println(basicResponse(" Bye. Hope to see you again soon!")); - shouldBreak = true; - break; - case "list": - StringBuilder sb = new StringBuilder(); - boolean first = true; - for (int i = 0; i < storeTextIndex; i++) { -// reply = reply + " " + storeText[i] + "\n"; - if (first) { - first = false; - } else { - sb.append("\n"); - } - sb.append(storeText[i]); - } - System.out.println(basicResponse(sb.toString())); - break; - default: - String reply = basicResponse(" " + input); - System.out.println(reply); - storeText[storeTextIndex] = (storeTextIndex + 1) + ". " + input; - storeTextIndex++; - } - - if (shouldBreak) { + if (input.equals("bye")) { + System.out.println(formatResponse(" Bye. Hope to see you again soon!")); break; + } else if (input.equals("list")) { + StringBuilder sb = new StringBuilder(); + boolean first = true; + for (int i = 0; i < storeTaskIndex; i++) { + if (first) { + first = false; + } else { + sb.append("\n"); + } + sb.append(" " + listOfTasks[i]); + } + System.out.println(formatResponse(sb.toString())); + } else if (input.equals("mark")) { + int taskNo = sc.nextInt() - 1; + sc.nextLine(); + listOfTasks[taskNo].markAsDone(); + String reply = " Nice! I've marked this task as done:\n" + + " " + listOfTasks[taskNo].toString(); + System.out.println(formatResponse(reply)); + } else if (input.equals("unmark")) { + int taskNo = sc.nextInt() - 1; + sc.nextLine(); + listOfTasks[taskNo].unmarkAsDone(); + String reply = " OK, I've marked this task as not done yet:\n" + + " " + listOfTasks[taskNo].toString(); + System.out.println(formatResponse(reply)); + } else { + String reply = formatResponse(" " + input); + System.out.println(reply); + Task t = new Task(input); + listOfTasks[storeTaskIndex] = t; + storeTaskIndex++; } } } From 8b981b34b703c1fcdf741df107a5a9a31bda92f3 Mon Sep 17 00:00:00 2001 From: JinbaoAlex Date: Fri, 7 Feb 2025 00:32:57 +0800 Subject: [PATCH 05/21] Level-3 and A-Classes Added the ability to mark tasks as done, the ability to change the status back to not done, and Task class --- src/main/java/Volkov.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/main/java/Volkov.java b/src/main/java/Volkov.java index db61581e1..3fbd474ad 100644 --- a/src/main/java/Volkov.java +++ b/src/main/java/Volkov.java @@ -19,7 +19,7 @@ public static void main(String[] args) { Scanner sc = new Scanner(System.in); while (true) { - String input = sc.next(); + String input = sc.nextLine(); if (input.equals("bye")) { System.out.println(formatResponse(" Bye. Hope to see you again soon!")); @@ -36,16 +36,14 @@ public static void main(String[] args) { sb.append(" " + listOfTasks[i]); } System.out.println(formatResponse(sb.toString())); - } else if (input.equals("mark")) { - int taskNo = sc.nextInt() - 1; - sc.nextLine(); + } else if (input.startsWith("mark")) { + int taskNo = Integer.parseInt(input.substring(5)); listOfTasks[taskNo].markAsDone(); String reply = " Nice! I've marked this task as done:\n" + " " + listOfTasks[taskNo].toString(); System.out.println(formatResponse(reply)); - } else if (input.equals("unmark")) { - int taskNo = sc.nextInt() - 1; - sc.nextLine(); + } else if (input.startsWith("unmark")) { + int taskNo = Integer.parseInt(input.substring(7)); listOfTasks[taskNo].unmarkAsDone(); String reply = " OK, I've marked this task as not done yet:\n" + " " + listOfTasks[taskNo].toString(); From dc2fcfeadf2cbffd9e09881d97bcbb0cf71a3263 Mon Sep 17 00:00:00 2001 From: JinbaoAlex Date: Fri, 7 Feb 2025 09:45:32 +0800 Subject: [PATCH 06/21] Level-4 Add support for tracking todos, deadlines, and events as tasks --- src/main/java/Deadline.java | 13 +++++++++++++ src/main/java/Event.java | 15 ++++++++++++++ src/main/java/Todo.java | 11 +++++++++++ src/main/java/Volkov.java | 39 +++++++++++++++++++++++++++++++++++-- 4 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 src/main/java/Deadline.java create mode 100644 src/main/java/Event.java create mode 100644 src/main/java/Todo.java diff --git a/src/main/java/Deadline.java b/src/main/java/Deadline.java new file mode 100644 index 000000000..f63242684 --- /dev/null +++ b/src/main/java/Deadline.java @@ -0,0 +1,13 @@ +public class Deadline extends Task { + protected String deadline; + + public Deadline(String description, String deadline) { + super(description); + this.deadline = deadline; + } + + @Override + public String toString() { + return "[D]" + super.toString() + " (by:" + deadline + ")"; + } +} diff --git a/src/main/java/Event.java b/src/main/java/Event.java new file mode 100644 index 000000000..acae3d8a8 --- /dev/null +++ b/src/main/java/Event.java @@ -0,0 +1,15 @@ +public class Event extends Task { + protected String startDate; + protected String endDate; + + public Event(String description, String startDate, String endDate) { + super(description); + this.startDate = startDate; + this.endDate = endDate; + } + + @Override + public String toString() { + return "[E]" + super.toString() + " (from:" + startDate + " to: " + endDate + ")"; + } +} diff --git a/src/main/java/Todo.java b/src/main/java/Todo.java new file mode 100644 index 000000000..931cfd4f9 --- /dev/null +++ b/src/main/java/Todo.java @@ -0,0 +1,11 @@ +public class Todo extends Task { + + public Todo(String description) { + super(description); + } + + @Override + public String toString() { + return "[T]" + super.toString(); + } +} diff --git a/src/main/java/Volkov.java b/src/main/java/Volkov.java index 3fbd474ad..41d923e2a 100644 --- a/src/main/java/Volkov.java +++ b/src/main/java/Volkov.java @@ -9,6 +9,15 @@ public static String formatResponse(String msg) { + " ____________________________________________________________\n"; } + public static String formatTaskMsg(Task t) { + listOfTasks[storeTaskIndex] = t; + storeTaskIndex++; + String msg = " Got it. I've added this task:\n" + + " " + t.toString() + "\n" + + " Now you have " + storeTaskIndex + " tasks in the list."; + return formatResponse(msg); + } + public static void main(String[] args) { String opening = " ____________________________________________________________\n" + " Hello! I'm Volkov\n" @@ -24,30 +33,56 @@ public static void main(String[] args) { if (input.equals("bye")) { System.out.println(formatResponse(" Bye. Hope to see you again soon!")); break; + } else if (input.equals("list")) { StringBuilder sb = new StringBuilder(); boolean first = true; + sb.append(" Here are the tasks in your list:\n"); for (int i = 0; i < storeTaskIndex; i++) { if (first) { first = false; } else { sb.append("\n"); } - sb.append(" " + listOfTasks[i]); + sb.append(" ").append(i + 1).append(".").append(listOfTasks[i]); } System.out.println(formatResponse(sb.toString())); + } else if (input.startsWith("mark")) { - int taskNo = Integer.parseInt(input.substring(5)); + int taskNo = Integer.parseInt(input.substring(5)) - 1; listOfTasks[taskNo].markAsDone(); String reply = " Nice! I've marked this task as done:\n" + " " + listOfTasks[taskNo].toString(); System.out.println(formatResponse(reply)); + } else if (input.startsWith("unmark")) { int taskNo = Integer.parseInt(input.substring(7)); listOfTasks[taskNo].unmarkAsDone(); String reply = " OK, I've marked this task as not done yet:\n" + " " + listOfTasks[taskNo].toString(); System.out.println(formatResponse(reply)); + + } else if (input.startsWith("todo")) { + String taskDesc = input.substring(5); + Todo t = new Todo(taskDesc); + System.out.println(formatTaskMsg(t)); + + } else if (input.startsWith("deadline")) { + int indexOfDeadline = input.indexOf(" /by"); + String taskDesc = input.substring(9, indexOfDeadline); + String deadline = input.substring(indexOfDeadline + 4); + Deadline t = new Deadline(taskDesc, deadline); + System.out.println(formatTaskMsg(t)); + + } else if (input.startsWith("event")) { + int indexOfStartDate = input.indexOf(" /from"); + int indexOfEndDate = input.indexOf(" /to"); + String taskDesc = input.substring(6, indexOfStartDate); + String startDate = input.substring(indexOfStartDate + 6, indexOfEndDate); + String endDate = input.substring(indexOfEndDate + 4); + Event t = new Event(taskDesc, startDate, endDate); + System.out.println(formatTaskMsg(t)); + } else { String reply = formatResponse(" " + input); System.out.println(reply); From 9067561fa77357f39aaf606cdf31513386bf20c2 Mon Sep 17 00:00:00 2001 From: JinbaoAlex Date: Fri, 7 Feb 2025 15:29:20 +0800 Subject: [PATCH 07/21] improved code quality, added tags to past commits --- src/main/java/Volkov.java | 155 ++++++++++++++++++++++++-------------- 1 file changed, 99 insertions(+), 56 deletions(-) diff --git a/src/main/java/Volkov.java b/src/main/java/Volkov.java index 41d923e2a..382b3bd31 100644 --- a/src/main/java/Volkov.java +++ b/src/main/java/Volkov.java @@ -2,7 +2,28 @@ public class Volkov { private static Task[] listOfTasks = new Task[100]; - private static int storeTaskIndex = 0; + private static int listOfTasksIndex = 0; + + private static final int MARK_CMD_LENGTH = 5; + private static final int UNMARK_CMD_LENGTH = 7; + private static final int TODO_CMD_LENGTH = 5; + private static final int DEADLINE_CMD_LENGTH = 9; + private static final int EVENT_CMD_LENGTH = 6; + private static final int DEADLINE_BY_LENGTH = 4; + private static final int EVENT_FROM_LENGTH = 6; + private static final int EVENT_TO_LENGTH = 4; + + private static final String BYE_COMMAND = "bye"; + private static final String LIST_COMMAND = "list"; + private static final String MARK_COMMAND = "mark"; + private static final String UNMARK_COMMAND = "unmark"; + private static final String TODO_COMMAND = "todo"; + private static final String DEADLINE_COMMAND = "deadline"; + private static final String EVENT_COMMAND = "event"; + private static final String BY_KEYWORD = " /by"; + private static final String FROM_KEYWORD = " /from"; + private static final String TO_KEYWORD = " /to"; + public static String formatResponse(String msg) { return " ____________________________________________________________\n" + msg + "\n" @@ -10,14 +31,67 @@ public static String formatResponse(String msg) { } public static String formatTaskMsg(Task t) { - listOfTasks[storeTaskIndex] = t; - storeTaskIndex++; + listOfTasks[listOfTasksIndex] = t; + listOfTasksIndex++; String msg = " Got it. I've added this task:\n" + " " + t.toString() + "\n" - + " Now you have " + storeTaskIndex + " tasks in the list."; + + " Now you have " + listOfTasksIndex + " tasks in the list."; return formatResponse(msg); } + public static void doByeCommand() { + System.out.println(formatResponse(" Bye. Hope to see you again soon!")); + } + + public static void doListCommand() { + StringBuilder sb = new StringBuilder(); + sb.append(" Here are the tasks in your list:"); + for (int i = 0; i < listOfTasksIndex; i++) { + sb.append("\n ").append(i + 1).append(".").append(listOfTasks[i]); + } + System.out.println(formatResponse(sb.toString())); + } + + public static void doMarkCommand(String input) { + int taskNo = Integer.parseInt(input.substring(MARK_CMD_LENGTH)) - 1; + listOfTasks[taskNo].markAsDone(); + String reply = " Nice! I've marked this task as done:\n" + + " " + listOfTasks[taskNo].toString(); + System.out.println(formatResponse(reply)); + } + + public static void doUnmarkCommand(String input) { + int taskNo = Integer.parseInt(input.substring(UNMARK_CMD_LENGTH)) - 1; + listOfTasks[taskNo].unmarkAsDone(); + String reply = " OK, I've marked this task as not done yet:\n" + + " " + listOfTasks[taskNo].toString(); + System.out.println(formatResponse(reply)); + } + + public static void doTodoCommand(String input) { + String taskDesc = input.substring(TODO_CMD_LENGTH); + Todo t = new Todo(taskDesc); + System.out.println(formatTaskMsg(t)); + } + + public static void doDeadlineCommand(String input) { + int indexOfDeadline = input.indexOf(BY_KEYWORD); + String taskDesc = input.substring(DEADLINE_CMD_LENGTH, indexOfDeadline); + String deadline = input.substring(indexOfDeadline + DEADLINE_BY_LENGTH); + Deadline t = new Deadline(taskDesc, deadline); + System.out.println(formatTaskMsg(t)); + } + + public static void doEventCommand(String input) { + int indexOfStartDate = input.indexOf(FROM_KEYWORD); + int indexOfEndDate = input.indexOf(TO_KEYWORD); + String taskDesc = input.substring(EVENT_CMD_LENGTH, indexOfStartDate); + String startDate = input.substring(indexOfStartDate + EVENT_FROM_LENGTH, indexOfEndDate); + String endDate = input.substring(indexOfEndDate + EVENT_TO_LENGTH); + Event t = new Event(taskDesc, startDate, endDate); + System.out.println(formatTaskMsg(t)); + } + public static void main(String[] args) { String opening = " ____________________________________________________________\n" + " Hello! I'm Volkov\n" @@ -30,65 +104,34 @@ public static void main(String[] args) { while (true) { String input = sc.nextLine(); - if (input.equals("bye")) { - System.out.println(formatResponse(" Bye. Hope to see you again soon!")); + if (input.equals(BYE_COMMAND)) { + doByeCommand(); break; - } else if (input.equals("list")) { - StringBuilder sb = new StringBuilder(); - boolean first = true; - sb.append(" Here are the tasks in your list:\n"); - for (int i = 0; i < storeTaskIndex; i++) { - if (first) { - first = false; - } else { - sb.append("\n"); - } - sb.append(" ").append(i + 1).append(".").append(listOfTasks[i]); - } - System.out.println(formatResponse(sb.toString())); - - } else if (input.startsWith("mark")) { - int taskNo = Integer.parseInt(input.substring(5)) - 1; - listOfTasks[taskNo].markAsDone(); - String reply = " Nice! I've marked this task as done:\n" - + " " + listOfTasks[taskNo].toString(); - System.out.println(formatResponse(reply)); - - } else if (input.startsWith("unmark")) { - int taskNo = Integer.parseInt(input.substring(7)); - listOfTasks[taskNo].unmarkAsDone(); - String reply = " OK, I've marked this task as not done yet:\n" - + " " + listOfTasks[taskNo].toString(); - System.out.println(formatResponse(reply)); - - } else if (input.startsWith("todo")) { - String taskDesc = input.substring(5); - Todo t = new Todo(taskDesc); - System.out.println(formatTaskMsg(t)); - - } else if (input.startsWith("deadline")) { - int indexOfDeadline = input.indexOf(" /by"); - String taskDesc = input.substring(9, indexOfDeadline); - String deadline = input.substring(indexOfDeadline + 4); - Deadline t = new Deadline(taskDesc, deadline); - System.out.println(formatTaskMsg(t)); - - } else if (input.startsWith("event")) { - int indexOfStartDate = input.indexOf(" /from"); - int indexOfEndDate = input.indexOf(" /to"); - String taskDesc = input.substring(6, indexOfStartDate); - String startDate = input.substring(indexOfStartDate + 6, indexOfEndDate); - String endDate = input.substring(indexOfEndDate + 4); - Event t = new Event(taskDesc, startDate, endDate); - System.out.println(formatTaskMsg(t)); + } else if (input.equals(LIST_COMMAND)) { + doListCommand(); + + } else if (input.startsWith(MARK_COMMAND)) { + doMarkCommand(input); + + } else if (input.startsWith(UNMARK_COMMAND)) { + doUnmarkCommand(input); + + } else if (input.startsWith(TODO_COMMAND)) { + doTodoCommand(input); + + } else if (input.startsWith(DEADLINE_COMMAND)) { + doDeadlineCommand(input); + + } else if (input.startsWith(EVENT_COMMAND)) { + doEventCommand(input); } else { String reply = formatResponse(" " + input); System.out.println(reply); Task t = new Task(input); - listOfTasks[storeTaskIndex] = t; - storeTaskIndex++; + listOfTasks[listOfTasksIndex] = t; + listOfTasksIndex++; } } } From 95b59f44aec7c9fa90e307aba4bd459538206ca1 Mon Sep 17 00:00:00 2001 From: JinbaoAlex Date: Fri, 14 Feb 2025 12:58:36 +0800 Subject: [PATCH 08/21] A-Exceptions Added exception handling for mark and unmark commands --- src/main/java/Volkov.java | 43 +++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/src/main/java/Volkov.java b/src/main/java/Volkov.java index 382b3bd31..254d3adab 100644 --- a/src/main/java/Volkov.java +++ b/src/main/java/Volkov.java @@ -53,19 +53,35 @@ public static void doListCommand() { } public static void doMarkCommand(String input) { - int taskNo = Integer.parseInt(input.substring(MARK_CMD_LENGTH)) - 1; - listOfTasks[taskNo].markAsDone(); - String reply = " Nice! I've marked this task as done:\n" - + " " + listOfTasks[taskNo].toString(); - System.out.println(formatResponse(reply)); + try { + int taskNo = Integer.parseInt(input.substring(MARK_CMD_LENGTH)) - 1; + listOfTasks[taskNo].markAsDone(); + String reply = " Nice! I've marked this task as done:\n" + + " " + listOfTasks[taskNo].toString(); + System.out.println(formatResponse(reply)); + } catch (NullPointerException e) { + String reply = " Task number not found, reenter with correct task number:"; + System.out.println(formatResponse(reply)); + } catch (NumberFormatException e) { + String reply = " No task number detected, reenter with correct task number:"; + System.out.println(formatResponse(reply)); + } } public static void doUnmarkCommand(String input) { - int taskNo = Integer.parseInt(input.substring(UNMARK_CMD_LENGTH)) - 1; - listOfTasks[taskNo].unmarkAsDone(); - String reply = " OK, I've marked this task as not done yet:\n" - + " " + listOfTasks[taskNo].toString(); - System.out.println(formatResponse(reply)); + try { + int taskNo = Integer.parseInt(input.substring(UNMARK_CMD_LENGTH)) - 1; + listOfTasks[taskNo].unmarkAsDone(); + String reply = " OK, I've marked this task as not done yet:\n" + + " " + listOfTasks[taskNo].toString(); + System.out.println(formatResponse(reply)); + } catch (NullPointerException e) { + String reply = " Task number not found, reenter with correct task number:"; + System.out.println(formatResponse(reply)); + } catch (NumberFormatException e) { + String reply = " No task number detected, reenter with correct task number:"; + System.out.println(formatResponse(reply)); + } } public static void doTodoCommand(String input) { @@ -127,11 +143,8 @@ public static void main(String[] args) { doEventCommand(input); } else { - String reply = formatResponse(" " + input); - System.out.println(reply); - Task t = new Task(input); - listOfTasks[listOfTasksIndex] = t; - listOfTasksIndex++; + String reply = " Unknown command received, reenter command:\n"; + System.out.println(formatResponse(reply)); } } } From ed07bac9c086abe46562acc706da72644867b904 Mon Sep 17 00:00:00 2001 From: JinbaoAlex Date: Fri, 14 Feb 2025 15:10:47 +0800 Subject: [PATCH 09/21] Level-5 Handling errors in mark/unmark and todo/deadline/event --- src/main/java/Deadline.java | 2 +- src/main/java/Event.java | 2 +- src/main/java/MissingDescription.java | 5 ++ src/main/java/MissingKeyword.java | 5 ++ src/main/java/Volkov.java | 74 +++++++++++++++++++-------- 5 files changed, 65 insertions(+), 23 deletions(-) create mode 100644 src/main/java/MissingDescription.java create mode 100644 src/main/java/MissingKeyword.java diff --git a/src/main/java/Deadline.java b/src/main/java/Deadline.java index f63242684..9ca80ab44 100644 --- a/src/main/java/Deadline.java +++ b/src/main/java/Deadline.java @@ -8,6 +8,6 @@ public Deadline(String description, String deadline) { @Override public String toString() { - return "[D]" + super.toString() + " (by:" + deadline + ")"; + return "[D]" + super.toString() + " (by: " + deadline + ")"; } } diff --git a/src/main/java/Event.java b/src/main/java/Event.java index acae3d8a8..ce5450149 100644 --- a/src/main/java/Event.java +++ b/src/main/java/Event.java @@ -10,6 +10,6 @@ public Event(String description, String startDate, String endDate) { @Override public String toString() { - return "[E]" + super.toString() + " (from:" + startDate + " to: " + endDate + ")"; + return "[E]" + super.toString() + " (from: " + startDate + " to: " + endDate + ")"; } } diff --git a/src/main/java/MissingDescription.java b/src/main/java/MissingDescription.java new file mode 100644 index 000000000..7a2076be2 --- /dev/null +++ b/src/main/java/MissingDescription.java @@ -0,0 +1,5 @@ +public class MissingDescription extends RuntimeException { + public MissingDescription(String message) { + super(message); + } +} diff --git a/src/main/java/MissingKeyword.java b/src/main/java/MissingKeyword.java new file mode 100644 index 000000000..9ba9d6caa --- /dev/null +++ b/src/main/java/MissingKeyword.java @@ -0,0 +1,5 @@ +public class MissingKeyword extends RuntimeException { + public MissingKeyword(String message) { + super(message); + } +} diff --git a/src/main/java/Volkov.java b/src/main/java/Volkov.java index 254d3adab..42756582a 100644 --- a/src/main/java/Volkov.java +++ b/src/main/java/Volkov.java @@ -7,8 +7,8 @@ public class Volkov { private static final int MARK_CMD_LENGTH = 5; private static final int UNMARK_CMD_LENGTH = 7; private static final int TODO_CMD_LENGTH = 5; - private static final int DEADLINE_CMD_LENGTH = 9; - private static final int EVENT_CMD_LENGTH = 6; + private static final int DEADLINE_CMD_LENGTH = 8; + private static final int EVENT_CMD_LENGTH = 5; private static final int DEADLINE_BY_LENGTH = 4; private static final int EVENT_FROM_LENGTH = 6; private static final int EVENT_TO_LENGTH = 4; @@ -20,9 +20,9 @@ public class Volkov { private static final String TODO_COMMAND = "todo"; private static final String DEADLINE_COMMAND = "deadline"; private static final String EVENT_COMMAND = "event"; - private static final String BY_KEYWORD = " /by"; - private static final String FROM_KEYWORD = " /from"; - private static final String TO_KEYWORD = " /to"; + private static final String BY_KEYWORD = "/by"; + private static final String FROM_KEYWORD = "/from"; + private static final String TO_KEYWORD = "/to"; public static String formatResponse(String msg) { return " ____________________________________________________________\n" @@ -85,27 +85,59 @@ public static void doUnmarkCommand(String input) { } public static void doTodoCommand(String input) { - String taskDesc = input.substring(TODO_CMD_LENGTH); - Todo t = new Todo(taskDesc); - System.out.println(formatTaskMsg(t)); + try { + String taskDesc = input.substring(TODO_CMD_LENGTH); + if (taskDesc.trim().isEmpty()) { + throw new MissingDescription("MISSING DESCRIPTION, reenter with description"); + } + Todo t = new Todo(taskDesc); + System.out.println(formatTaskMsg(t)); + } catch (MissingDescription e) { + System.out.println(formatResponse(" " + e.getMessage())); + } } public static void doDeadlineCommand(String input) { - int indexOfDeadline = input.indexOf(BY_KEYWORD); - String taskDesc = input.substring(DEADLINE_CMD_LENGTH, indexOfDeadline); - String deadline = input.substring(indexOfDeadline + DEADLINE_BY_LENGTH); - Deadline t = new Deadline(taskDesc, deadline); - System.out.println(formatTaskMsg(t)); + try { + int indexOfDeadline = input.indexOf(BY_KEYWORD); + if (indexOfDeadline == -1) { + throw new MissingKeyword("MISSING '/by' keyword"); + } + String taskDesc = input.substring(DEADLINE_CMD_LENGTH, indexOfDeadline - 1).trim(); + if (taskDesc.trim().isEmpty()) { + throw new MissingDescription("MISSING DESCRIPTION, reenter with description"); + } + String deadline = input.substring(indexOfDeadline - 1 + DEADLINE_BY_LENGTH).trim(); + Deadline t = new Deadline(taskDesc, deadline); + System.out.println(formatTaskMsg(t)); + } catch (MissingDescription | MissingKeyword e) { + System.out.println(formatResponse(" " + e.getMessage())); + } } public static void doEventCommand(String input) { - int indexOfStartDate = input.indexOf(FROM_KEYWORD); - int indexOfEndDate = input.indexOf(TO_KEYWORD); - String taskDesc = input.substring(EVENT_CMD_LENGTH, indexOfStartDate); - String startDate = input.substring(indexOfStartDate + EVENT_FROM_LENGTH, indexOfEndDate); - String endDate = input.substring(indexOfEndDate + EVENT_TO_LENGTH); - Event t = new Event(taskDesc, startDate, endDate); - System.out.println(formatTaskMsg(t)); + try { + int indexOfStartDate = input.indexOf(FROM_KEYWORD); + if (indexOfStartDate == -1) { + throw new MissingKeyword("MISSING '/from' keyword"); + } + int indexOfEndDate = input.indexOf(TO_KEYWORD); + if (indexOfEndDate == -1) { + throw new MissingKeyword("MISSING '/to' keyword"); + } + String taskDesc = input.substring(EVENT_CMD_LENGTH, indexOfStartDate - 1).trim(); + + if (taskDesc.trim().isEmpty()) { + throw new MissingDescription("MISSING DESCRIPTION, reenter with description"); + } + + String startDate = input.substring(indexOfStartDate - 1 + EVENT_FROM_LENGTH, indexOfEndDate - 1).trim(); + String endDate = input.substring(indexOfEndDate - 1 + EVENT_TO_LENGTH).trim(); + Event t = new Event(taskDesc, startDate, endDate); + System.out.println(formatTaskMsg(t)); + } catch (MissingDescription | MissingKeyword e) { + System.out.println(formatResponse(" " + e.getMessage())); + } } public static void main(String[] args) { @@ -143,7 +175,7 @@ public static void main(String[] args) { doEventCommand(input); } else { - String reply = " Unknown command received, reenter command:\n"; + String reply = " Unknown command received, reenter command:"; System.out.println(formatResponse(reply)); } } From 02d80d23d5c3d565787373240c151e2810a92a9c Mon Sep 17 00:00:00 2001 From: JinbaoAlex Date: Thu, 20 Feb 2025 22:58:57 +0800 Subject: [PATCH 10/21] Level-6 added delete command --- src/main/java/Volkov.java | 45 +++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/src/main/java/Volkov.java b/src/main/java/Volkov.java index 42756582a..63c4a7e83 100644 --- a/src/main/java/Volkov.java +++ b/src/main/java/Volkov.java @@ -1,11 +1,14 @@ +import java.util.ArrayList; import java.util.Scanner; public class Volkov { - private static Task[] listOfTasks = new Task[100]; - private static int listOfTasksIndex = 0; +// private static Task[] listOfTasks = new Task[100]; +// private static int listOfTasksIndex = 0; + private static ArrayList listOfTasks = new ArrayList<>(); private static final int MARK_CMD_LENGTH = 5; private static final int UNMARK_CMD_LENGTH = 7; + private static final int DELETE_CMD_LENGTH = 7; private static final int TODO_CMD_LENGTH = 5; private static final int DEADLINE_CMD_LENGTH = 8; private static final int EVENT_CMD_LENGTH = 5; @@ -17,6 +20,7 @@ public class Volkov { private static final String LIST_COMMAND = "list"; private static final String MARK_COMMAND = "mark"; private static final String UNMARK_COMMAND = "unmark"; + private static final String DELETE_COMMAND = "delete"; private static final String TODO_COMMAND = "todo"; private static final String DEADLINE_COMMAND = "deadline"; private static final String EVENT_COMMAND = "event"; @@ -31,11 +35,10 @@ public static String formatResponse(String msg) { } public static String formatTaskMsg(Task t) { - listOfTasks[listOfTasksIndex] = t; - listOfTasksIndex++; + listOfTasks.add(t); String msg = " Got it. I've added this task:\n" + " " + t.toString() + "\n" - + " Now you have " + listOfTasksIndex + " tasks in the list."; + + " Now you have " + listOfTasks.size() + " tasks in the list."; return formatResponse(msg); } @@ -46,8 +49,8 @@ public static void doByeCommand() { public static void doListCommand() { StringBuilder sb = new StringBuilder(); sb.append(" Here are the tasks in your list:"); - for (int i = 0; i < listOfTasksIndex; i++) { - sb.append("\n ").append(i + 1).append(".").append(listOfTasks[i]); + for (int i = 0; i < listOfTasks.size(); i++) { + sb.append("\n ").append(i + 1).append(".").append(listOfTasks.get(i)); } System.out.println(formatResponse(sb.toString())); } @@ -55,9 +58,9 @@ public static void doListCommand() { public static void doMarkCommand(String input) { try { int taskNo = Integer.parseInt(input.substring(MARK_CMD_LENGTH)) - 1; - listOfTasks[taskNo].markAsDone(); + listOfTasks.get(taskNo).markAsDone(); String reply = " Nice! I've marked this task as done:\n" - + " " + listOfTasks[taskNo].toString(); + + " " + listOfTasks.get(taskNo).toString(); System.out.println(formatResponse(reply)); } catch (NullPointerException e) { String reply = " Task number not found, reenter with correct task number:"; @@ -71,9 +74,26 @@ public static void doMarkCommand(String input) { public static void doUnmarkCommand(String input) { try { int taskNo = Integer.parseInt(input.substring(UNMARK_CMD_LENGTH)) - 1; - listOfTasks[taskNo].unmarkAsDone(); + listOfTasks.get(taskNo).unmarkAsDone(); String reply = " OK, I've marked this task as not done yet:\n" - + " " + listOfTasks[taskNo].toString(); + + " " + listOfTasks.get(taskNo).toString(); + System.out.println(formatResponse(reply)); + } catch (NullPointerException e) { + String reply = " Task number not found, reenter with correct task number:"; + System.out.println(formatResponse(reply)); + } catch (NumberFormatException e) { + String reply = " No task number detected, reenter with correct task number:"; + System.out.println(formatResponse(reply)); + } + } + + public static void doDeleteCommand(String input) { + try { + int taskNo = Integer.parseInt(input.substring(DELETE_CMD_LENGTH)) - 1; + listOfTasks.remove(taskNo); + String reply = " Noted. I've removed this task::\n" + + " " + listOfTasks.get(taskNo).toString() + + " Now you have " + listOfTasks.size() + " tasks in the list."; System.out.println(formatResponse(reply)); } catch (NullPointerException e) { String reply = " Task number not found, reenter with correct task number:"; @@ -165,6 +185,9 @@ public static void main(String[] args) { } else if (input.startsWith(UNMARK_COMMAND)) { doUnmarkCommand(input); + } else if (input.startsWith(DELETE_COMMAND)) { + doDeleteCommand(input); + } else if (input.startsWith(TODO_COMMAND)) { doTodoCommand(input); From fe957b7233999109ab71fcc15259acc339378354 Mon Sep 17 00:00:00 2001 From: JinbaoAlex Date: Fri, 21 Feb 2025 14:48:53 +0800 Subject: [PATCH 11/21] Level-7 added ability to save and load data --- src/main/java/Deadline.java | 4 ++ src/main/java/Event.java | 4 ++ src/main/java/Task.java | 17 ++++-- src/main/java/Todo.java | 4 ++ src/main/java/Volkov.java | 115 +++++++++++++++++++++++++++++++----- 5 files changed, 125 insertions(+), 19 deletions(-) diff --git a/src/main/java/Deadline.java b/src/main/java/Deadline.java index 9ca80ab44..9435746df 100644 --- a/src/main/java/Deadline.java +++ b/src/main/java/Deadline.java @@ -6,6 +6,10 @@ public Deadline(String description, String deadline) { this.deadline = deadline; } + public String txtSave() { + return "[D]" + super.txtSave() + "|" + deadline; + } + @Override public String toString() { return "[D]" + super.toString() + " (by: " + deadline + ")"; diff --git a/src/main/java/Event.java b/src/main/java/Event.java index ce5450149..b11539633 100644 --- a/src/main/java/Event.java +++ b/src/main/java/Event.java @@ -8,6 +8,10 @@ public Event(String description, String startDate, String endDate) { this.endDate = endDate; } + public String txtSave() { + return "[D]" + super.txtSave() + "|" + startDate + "|" + endDate; + } + @Override public String toString() { return "[E]" + super.toString() + " (from: " + startDate + " to: " + endDate + ")"; diff --git a/src/main/java/Task.java b/src/main/java/Task.java index f49891636..0d83ed6cc 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -15,14 +15,21 @@ public void unmarkAsDone() { isDone = false; } - @Override - public String toString() { - String mark; + public String getMark() { if (isDone) { - mark = "[X] "; + return "[X] "; } else { - mark = "[ ] "; + return "[ ] "; } + } + + public String txtSave() { + return getMark() + description; + } + + @Override + public String toString() { + String mark = getMark(); return mark + description; } } diff --git a/src/main/java/Todo.java b/src/main/java/Todo.java index 931cfd4f9..869fab1fa 100644 --- a/src/main/java/Todo.java +++ b/src/main/java/Todo.java @@ -4,6 +4,10 @@ public Todo(String description) { super(description); } + public String txtSave() { + return "[T]" + super.txtSave(); + } + @Override public String toString() { return "[T]" + super.toString(); diff --git a/src/main/java/Volkov.java b/src/main/java/Volkov.java index 42756582a..86867e2ab 100644 --- a/src/main/java/Volkov.java +++ b/src/main/java/Volkov.java @@ -1,8 +1,13 @@ +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Scanner; +import java.io.File; +import java.io.FileWriter; public class Volkov { - private static Task[] listOfTasks = new Task[100]; - private static int listOfTasksIndex = 0; + private static ArrayList listOfTasks = new ArrayList<>(); private static final int MARK_CMD_LENGTH = 5; private static final int UNMARK_CMD_LENGTH = 7; @@ -31,11 +36,10 @@ public static String formatResponse(String msg) { } public static String formatTaskMsg(Task t) { - listOfTasks[listOfTasksIndex] = t; - listOfTasksIndex++; + listOfTasks.add(t); String msg = " Got it. I've added this task:\n" + " " + t.toString() + "\n" - + " Now you have " + listOfTasksIndex + " tasks in the list."; + + " Now you have " + listOfTasks.size() + " tasks in the list."; return formatResponse(msg); } @@ -46,8 +50,8 @@ public static void doByeCommand() { public static void doListCommand() { StringBuilder sb = new StringBuilder(); sb.append(" Here are the tasks in your list:"); - for (int i = 0; i < listOfTasksIndex; i++) { - sb.append("\n ").append(i + 1).append(".").append(listOfTasks[i]); + for (int i = 0; i < listOfTasks.size(); i++) { + sb.append("\n ").append(i + 1).append(".").append(listOfTasks.get(i)); } System.out.println(formatResponse(sb.toString())); } @@ -55,9 +59,9 @@ public static void doListCommand() { public static void doMarkCommand(String input) { try { int taskNo = Integer.parseInt(input.substring(MARK_CMD_LENGTH)) - 1; - listOfTasks[taskNo].markAsDone(); + listOfTasks.get(taskNo).markAsDone(); String reply = " Nice! I've marked this task as done:\n" - + " " + listOfTasks[taskNo].toString(); + + " " + listOfTasks.get(taskNo).toString(); System.out.println(formatResponse(reply)); } catch (NullPointerException e) { String reply = " Task number not found, reenter with correct task number:"; @@ -71,9 +75,9 @@ public static void doMarkCommand(String input) { public static void doUnmarkCommand(String input) { try { int taskNo = Integer.parseInt(input.substring(UNMARK_CMD_LENGTH)) - 1; - listOfTasks[taskNo].unmarkAsDone(); + listOfTasks.get(taskNo).unmarkAsDone(); String reply = " OK, I've marked this task as not done yet:\n" - + " " + listOfTasks[taskNo].toString(); + + " " + listOfTasks.get(taskNo).toString(); System.out.println(formatResponse(reply)); } catch (NullPointerException e) { String reply = " Task number not found, reenter with correct task number:"; @@ -140,12 +144,94 @@ public static void doEventCommand(String input) { } } - public static void main(String[] args) { - String opening = " ____________________________________________________________\n" + public static void saveFile() { + String fileName = "./data/volkov.txt"; + + try { + File f = new File(fileName); + + File parentDir = f.getParentFile(); + if (!parentDir.exists()) { + if (parentDir.mkdirs()) { + System.out.println(formatResponse(" Folder missing, new folder created")); + } + } + + if (f.createNewFile()) { + System.out.println(formatResponse(" No file present, new file created")); + } + + FileWriter fw = new FileWriter(fileName); + for (Task task : listOfTasks) { + fw.write(task.txtSave() + "\n"); + } + fw.close(); + + } catch (IOException e) { + System.out.println("Something went wrong: " + e.getMessage()); + } + } + + public static void loadFile() { + + String fileName = "./data/volkov.txt"; + + String newUserOpening = " ____________________________________________________________\n" + " Hello! I'm Volkov\n" + " What can I do for you?\n" + " ____________________________________________________________\n"; - System.out.println(opening); + + String returnUserOpening = " ____________________________________________________________\n" + + " Welcome back!\n" + + " What can Volkov do for you?\n" + + " ____________________________________________________________\n"; + + File f = new File(fileName); + if (f.exists()) { + System.out.println(returnUserOpening); + } else { + System.out.println(newUserOpening); + } + + try { + Scanner s = new Scanner(f); + while (s.hasNextLine()) { + String taskString = s.nextLine(); + + if (taskString.startsWith("[T]")) { + Task t = new Todo(taskString.substring(7).trim()); + if (taskString.contains("[X]")) { + t.markAsDone(); + } + listOfTasks.add(t); + } else if (taskString.startsWith("[D]")) { + String[] descAndDate = taskString.substring(7).split("\\|"); + String desc = descAndDate[0].trim(); + String date = descAndDate[1].trim(); + Task t = new Deadline(desc, date); + if (taskString.contains("[X]")) { + t.markAsDone(); + } + listOfTasks.add(t); + } else if (taskString.startsWith("[E]")) { + String[] descAndDate = taskString.substring(7).split("\\|"); + String desc = descAndDate[0].trim(); + String start = descAndDate[1].trim(); + String end = descAndDate[2].trim(); + Task t = new Event(desc, start, end); + if (taskString.contains("[X]")) { + t.markAsDone(); + } + listOfTasks.add(t); + } + } + } catch (FileNotFoundException e) { + + } + } + + public static void main(String[] args) { + loadFile(); Scanner sc = new Scanner(System.in); @@ -179,5 +265,6 @@ public static void main(String[] args) { System.out.println(formatResponse(reply)); } } + saveFile(); } } From ab17569f190860ebbfb55667f07ca8b24aa2c5bd Mon Sep 17 00:00:00 2001 From: JinbaoAlex Date: Sat, 22 Feb 2025 21:35:02 +0800 Subject: [PATCH 12/21] FIxed mistakes in delete and save commands --- src/main/java/Event.java | 2 +- src/main/java/Volkov.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/Event.java b/src/main/java/Event.java index b11539633..b107dd848 100644 --- a/src/main/java/Event.java +++ b/src/main/java/Event.java @@ -9,7 +9,7 @@ public Event(String description, String startDate, String endDate) { } public String txtSave() { - return "[D]" + super.txtSave() + "|" + startDate + "|" + endDate; + return "[E]" + super.txtSave() + "|" + startDate + "|" + endDate; } @Override diff --git a/src/main/java/Volkov.java b/src/main/java/Volkov.java index 67fdef98b..7e05d3365 100644 --- a/src/main/java/Volkov.java +++ b/src/main/java/Volkov.java @@ -93,11 +93,11 @@ public static void doUnmarkCommand(String input) { public static void doDeleteCommand(String input) { try { int taskNo = Integer.parseInt(input.substring(DELETE_CMD_LENGTH)) - 1; - listOfTasks.remove(taskNo); String reply = " Noted. I've removed this task::\n" + " " + listOfTasks.get(taskNo).toString() - + " Now you have " + listOfTasks.size() + " tasks in the list."; + + " Now you have " + (listOfTasks.size()-1) + " tasks in the list."; System.out.println(formatResponse(reply)); + listOfTasks.remove(taskNo); } catch (NullPointerException e) { String reply = " Task number not found, reenter with correct task number:"; System.out.println(formatResponse(reply)); From 83911f6536b2fc80a65754e9fca6684bae42780f Mon Sep 17 00:00:00 2001 From: JinbaoAlex Date: Thu, 13 Mar 2025 11:02:23 +0800 Subject: [PATCH 13/21] A-MoreOOP Refactor code for oop with Ui, Storage, Parser, Tasklist, and Commands classes --- src/main/java/ByeCommand.java | 10 + src/main/java/Commands.java | 7 + src/main/java/DeadlineCommand.java | 15 ++ src/main/java/DeleteCommand.java | 24 +++ src/main/java/EventCommand.java | 17 ++ src/main/java/ListCommand.java | 13 ++ src/main/java/MarkCommand.java | 24 +++ src/main/java/MissingCommand.java | 11 ++ src/main/java/Parser.java | 111 +++++++++++ src/main/java/Storage.java | 91 +++++++++ src/main/java/TaskList.java | 25 +++ src/main/java/TodoCommand.java | 13 ++ src/main/java/Ui.java | 44 +++++ src/main/java/UnmarkCommand.java | 22 +++ src/main/java/Volkov.java | 298 ++--------------------------- 15 files changed, 443 insertions(+), 282 deletions(-) create mode 100644 src/main/java/ByeCommand.java create mode 100644 src/main/java/Commands.java create mode 100644 src/main/java/DeadlineCommand.java create mode 100644 src/main/java/DeleteCommand.java create mode 100644 src/main/java/EventCommand.java create mode 100644 src/main/java/ListCommand.java create mode 100644 src/main/java/MarkCommand.java create mode 100644 src/main/java/MissingCommand.java create mode 100644 src/main/java/Parser.java create mode 100644 src/main/java/Storage.java create mode 100644 src/main/java/TaskList.java create mode 100644 src/main/java/TodoCommand.java create mode 100644 src/main/java/Ui.java create mode 100644 src/main/java/UnmarkCommand.java diff --git a/src/main/java/ByeCommand.java b/src/main/java/ByeCommand.java new file mode 100644 index 000000000..8ad2a15aa --- /dev/null +++ b/src/main/java/ByeCommand.java @@ -0,0 +1,10 @@ +public class ByeCommand extends Commands { + + public void execute(TaskList tasks, Ui ui, Storage storage) { + new Ui().formatResponse(" Bye. Hope to see you again soon!"); + } + + public boolean isExit() { + return true; + } +} diff --git a/src/main/java/Commands.java b/src/main/java/Commands.java new file mode 100644 index 000000000..3f5dc9595 --- /dev/null +++ b/src/main/java/Commands.java @@ -0,0 +1,7 @@ +public abstract class Commands { + public void execute(TaskList tasks, Ui ui, Storage storage) {} + + public boolean isExit() { + return false; + } +} diff --git a/src/main/java/DeadlineCommand.java b/src/main/java/DeadlineCommand.java new file mode 100644 index 000000000..1514c7ed9 --- /dev/null +++ b/src/main/java/DeadlineCommand.java @@ -0,0 +1,15 @@ +public class DeadlineCommand extends Commands { + private final String taskDesc; + private final String deadline; + + DeadlineCommand(String taskDesc, String deadline) { + this.taskDesc = taskDesc; + this.deadline = deadline; + } + + public void execute(TaskList tasks, Ui ui, Storage storage) { + Deadline t = new Deadline(taskDesc, deadline); + tasks.addTask(t); + ui.formatTaskMsg(t, tasks); + } +} diff --git a/src/main/java/DeleteCommand.java b/src/main/java/DeleteCommand.java new file mode 100644 index 000000000..9c6c5f202 --- /dev/null +++ b/src/main/java/DeleteCommand.java @@ -0,0 +1,24 @@ +public class DeleteCommand extends Commands { + private final int taskNo; + + DeleteCommand(int taskNo) { + this.taskNo = taskNo; + } + + public void execute(TaskList tasks, Ui ui, Storage storage) { + try { + String reply = " Noted. I've removed this task::\n" + + " " + tasks.getTask(taskNo).toString() + + " Now you have " + (tasks.size()-1) + " tasks in the list."; + ui.formatResponse(reply); + tasks.removeTask(taskNo); + } catch (NullPointerException | IndexOutOfBoundsException e) { + String reply = " Task number not found, reenter with correct task number:"; + new MissingCommand(reply).execute(tasks, ui, storage); + } catch (NumberFormatException e) { + String reply = " No task number detected, reenter with correct task number:"; + new MissingCommand(reply).execute(tasks, ui, storage); + } + + } +} diff --git a/src/main/java/EventCommand.java b/src/main/java/EventCommand.java new file mode 100644 index 000000000..e94344f5f --- /dev/null +++ b/src/main/java/EventCommand.java @@ -0,0 +1,17 @@ +public class EventCommand extends Commands { + private final String taskDesc; + private final String startDate; + private final String endDate; + + EventCommand(String taskDesc, String startDate, String endDate) { + this.taskDesc = taskDesc; + this.startDate = startDate; + this.endDate = endDate; + } + + public void execute(TaskList tasks, Ui ui, Storage storage) { + Event t = new Event(taskDesc, startDate, endDate); + tasks.addTask(t); + ui.formatTaskMsg(t, tasks); + } +} diff --git a/src/main/java/ListCommand.java b/src/main/java/ListCommand.java new file mode 100644 index 000000000..d90b89cb8 --- /dev/null +++ b/src/main/java/ListCommand.java @@ -0,0 +1,13 @@ +public class ListCommand extends Commands { + + public void execute(TaskList tasks, Ui ui, Storage storage) { + StringBuilder sb = new StringBuilder(); + sb.append(" Here are the tasks in your list:"); + for (int i = 0; i < tasks.size(); i++) { + sb.append("\n ").append(i + 1).append(".").append(tasks.getTask(i)); + } + ui.formatResponse(sb.toString()); + } + + +} diff --git a/src/main/java/MarkCommand.java b/src/main/java/MarkCommand.java new file mode 100644 index 000000000..0e59a5c33 --- /dev/null +++ b/src/main/java/MarkCommand.java @@ -0,0 +1,24 @@ +public class MarkCommand extends Commands { + private final int taskNo; + + MarkCommand(int taskNo) { + this.taskNo = taskNo; + } + + public void execute(TaskList tasks, Ui ui, Storage storage) { + try { + tasks.getTask(taskNo).markAsDone(); + String reply = " Nice! I've marked this task as done:\n" + + " " + tasks.getTask(taskNo).toString(); + ui.formatResponse(reply); + } catch (NullPointerException e) { + String reply = " Task number not found, reenter with correct task number:"; + new MissingCommand(reply).execute(tasks, ui, storage); + } catch (NumberFormatException e) { + String reply = " No task number detected, reenter with correct task number:"; + new MissingCommand(reply).execute(tasks, ui, storage); + } + } + + +} diff --git a/src/main/java/MissingCommand.java b/src/main/java/MissingCommand.java new file mode 100644 index 000000000..72a36dde4 --- /dev/null +++ b/src/main/java/MissingCommand.java @@ -0,0 +1,11 @@ +public class MissingCommand extends Commands{ + private final String reply; + + MissingCommand(String reply){ + this.reply = reply; + } + + public void execute(TaskList tasks, Ui ui, Storage storage) { + new Ui().formatResponse(" " + reply); + } +} diff --git a/src/main/java/Parser.java b/src/main/java/Parser.java new file mode 100644 index 000000000..07b433ed5 --- /dev/null +++ b/src/main/java/Parser.java @@ -0,0 +1,111 @@ +public class Parser { + private static final int MARK_CMD_LENGTH = 5; + private static final int UNMARK_CMD_LENGTH = 7; + private static final int DELETE_CMD_LENGTH = 7; + + private static final int TODO_CMD_LENGTH = 5; + private static final int DEADLINE_CMD_LENGTH = 8; + private static final int EVENT_CMD_LENGTH = 5; + private static final int DEADLINE_BY_LENGTH = 4; + private static final int EVENT_FROM_LENGTH = 6; + private static final int EVENT_TO_LENGTH = 4; + + private static final String BYE_COMMAND = "bye"; + private static final String LIST_COMMAND = "list"; + private static final String MARK_COMMAND = "mark"; + private static final String UNMARK_COMMAND = "unmark"; + private static final String DELETE_COMMAND = "delete"; + private static final String TODO_COMMAND = "todo"; + private static final String DEADLINE_COMMAND = "deadline"; + private static final String EVENT_COMMAND = "event"; + private static final String BY_KEYWORD = "/by"; + private static final String FROM_KEYWORD = "/from"; + private static final String TO_KEYWORD = "/to"; + + public static Commands parse(String input) { + if (input.startsWith(BYE_COMMAND)) { + return new ByeCommand(); + } else if (input.startsWith(LIST_COMMAND)) { + return new ListCommand(); + + } else if (input.startsWith(MARK_COMMAND)) { + int taskNo = Integer.parseInt(input.substring(MARK_CMD_LENGTH)) - 1; + return new MarkCommand(taskNo); + + } else if (input.startsWith(UNMARK_COMMAND)) { + int taskNo = Integer.parseInt(input.substring(UNMARK_CMD_LENGTH)) - 1; + return new UnmarkCommand(taskNo); + + } else if (input.startsWith(DELETE_COMMAND)) { + int taskNo = Integer.parseInt(input.substring(DELETE_CMD_LENGTH)) - 1; + return new DeleteCommand(taskNo); + + } else if (input.startsWith(TODO_COMMAND)) { + try { + String taskDesc = input.substring(TODO_CMD_LENGTH); + if (taskDesc.trim().isEmpty()) { + throw new MissingDescription("MISSING DESCRIPTION, reenter with description"); + } + return new TodoCommand(taskDesc); + } catch (MissingDescription e) { + return new MissingCommand(" " + e.getMessage()); + } catch (IndexOutOfBoundsException e) { + return new MissingCommand(" " + "MISSING DESCRIPTION, reenter with description"); + } + + } else if (input.startsWith(DEADLINE_COMMAND)) { + try { + int indexOfDeadline = input.indexOf(BY_KEYWORD); + if (indexOfDeadline == -1) { + throw new MissingKeyword("MISSING '/by' keyword"); + } + String taskDesc = input.substring(DEADLINE_CMD_LENGTH, indexOfDeadline - 1).trim(); + if (taskDesc.trim().isEmpty()) { + throw new MissingDescription("MISSING DESCRIPTION, reenter with description"); + } + String deadline = input.substring(indexOfDeadline - 1 + DEADLINE_BY_LENGTH).trim(); + if (deadline.trim().isEmpty()) { + throw new MissingDescription("MISSING DEADLINE, reenter with deadline"); + } + return new DeadlineCommand(taskDesc, deadline); + } catch (MissingDescription | MissingKeyword e) { + return new MissingCommand(" " + e.getMessage()); + } catch (IndexOutOfBoundsException e) { + return new MissingCommand(" " + "MISSING DESCRIPTION, reenter with description"); + } + + } else if (input.startsWith(EVENT_COMMAND)) { + try { + int indexOfStartDate = input.indexOf(FROM_KEYWORD); + if (indexOfStartDate == -1) { + throw new MissingKeyword("MISSING '/from' keyword"); + } + int indexOfEndDate = input.indexOf(TO_KEYWORD); + if (indexOfEndDate == -1) { + throw new MissingKeyword("MISSING '/to' keyword"); + } + String taskDesc = input.substring(EVENT_CMD_LENGTH, indexOfStartDate - 1).trim(); + if (taskDesc.trim().isEmpty()) { + throw new MissingDescription("MISSING DESCRIPTION, reenter with description"); + } + + String startDate = input.substring(indexOfStartDate - 1 + EVENT_FROM_LENGTH, indexOfEndDate - 1).trim(); + if (startDate.trim().isEmpty()) { + throw new MissingDescription("MISSING DESCRIPTION, reenter with description"); + } + String endDate = input.substring(indexOfEndDate - 1 + EVENT_TO_LENGTH).trim(); + if (endDate.trim().isEmpty()) { + throw new MissingDescription("MISSING DESCRIPTION, reenter with description"); + } + return new EventCommand(taskDesc, startDate, endDate); + } catch (MissingDescription | MissingKeyword e) { + return new MissingCommand(" " + e.getMessage()); + } catch (IndexOutOfBoundsException e) { + return new MissingCommand(" " + "MISSING DESCRIPTION, reenter with description"); + } + + } else { + return new MissingCommand("Unknown command received, reenter command:"); + } + } +} diff --git a/src/main/java/Storage.java b/src/main/java/Storage.java new file mode 100644 index 000000000..ce6ce356c --- /dev/null +++ b/src/main/java/Storage.java @@ -0,0 +1,91 @@ +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Scanner; + +public class Storage { + private final String filePath; + Ui ui; + + Storage(String filePath, Ui ui) { + this.filePath = filePath; + this.ui = ui; + } + + public void saveFile(TaskList taskList) { + try { + File f = new File(filePath); + + File parentDir = f.getParentFile(); + if (!parentDir.exists()) { + if (parentDir.mkdirs()) { + ui.formatResponse(" Folder missing, new folder created"); + } + } + + if (f.createNewFile()) { + ui.formatResponse(" No file present, new file created"); + } + + FileWriter fw = new FileWriter(filePath); + for (Task task : taskList.getList()) { + fw.write(task.txtSave() + "\n"); + } + fw.close(); + + } catch (IOException e) { + System.out.println("Something went wrong: " + e.getMessage()); + } + } + + public TaskList loadFile() { + TaskList taskList = new TaskList(); + + File f = new File(filePath); + if (f.exists()) { + ui.returnUserGreet(); + } else { + ui.newUserGreet(); + } + + try { + Scanner s = new Scanner(f); + while (s.hasNextLine()) { + String taskString = s.nextLine(); + + if (taskString.startsWith("[T]")) { + Task t = new Todo(taskString.substring(7).trim()); + if (taskString.contains("[X]")) { + t.markAsDone(); + } + taskList.addTask(t); + } else if (taskString.startsWith("[D]")) { + String[] descAndDate = taskString.substring(7).split("\\|"); + String desc = descAndDate[0].trim(); + String date = descAndDate[1].trim(); + Task t = new Deadline(desc, date); + if (taskString.contains("[X]")) { + t.markAsDone(); + } + taskList.addTask(t); + } else if (taskString.startsWith("[E]")) { + String[] descAndDate = taskString.substring(7).split("\\|"); + String desc = descAndDate[0].trim(); + String start = descAndDate[1].trim(); + String end = descAndDate[2].trim(); + Task t = new Event(desc, start, end); + if (taskString.contains("[X]")) { + t.markAsDone(); + } + taskList.addTask(t); + } + } + } catch (FileNotFoundException e) { + + } + return taskList; + } +} + + diff --git a/src/main/java/TaskList.java b/src/main/java/TaskList.java new file mode 100644 index 000000000..8b537d219 --- /dev/null +++ b/src/main/java/TaskList.java @@ -0,0 +1,25 @@ +import java.util.ArrayList; + +public class TaskList { + private static final ArrayList listOfTasks = new ArrayList<>(); + + public ArrayList getList() { + return listOfTasks; + } + + public void addTask(Task task) { + listOfTasks.add(task); + } + + public void removeTask(int index) { + listOfTasks.remove(index); + } + + public Task getTask(int index) { + return listOfTasks.get(index); + } + + public int size() { + return listOfTasks.size(); + } +} diff --git a/src/main/java/TodoCommand.java b/src/main/java/TodoCommand.java new file mode 100644 index 000000000..8c9cade47 --- /dev/null +++ b/src/main/java/TodoCommand.java @@ -0,0 +1,13 @@ +public class TodoCommand extends Commands { + private final String taskDesc; + + TodoCommand(String taskDesc) { + this.taskDesc = taskDesc; + } + + public void execute(TaskList tasks, Ui ui, Storage storage) { + Todo t = new Todo(taskDesc); + tasks.addTask(t); + ui.formatTaskMsg(t, tasks); + } +} diff --git a/src/main/java/Ui.java b/src/main/java/Ui.java new file mode 100644 index 000000000..ab6b0220f --- /dev/null +++ b/src/main/java/Ui.java @@ -0,0 +1,44 @@ +import java.util.Scanner; + +public class Ui { + private Scanner sc = new Scanner(System.in); + + private final String newUserOpening = " ____________________________________________________________\n" + + " Hello! I'm Volkov\n" + + " What can I do for you?\n" + + " ____________________________________________________________\n"; + + private final String returnUserOpening = " ____________________________________________________________\n" + + " Welcome back!\n" + + " What can Volkov do for you?\n" + + " ____________________________________________________________\n"; + + public void formatResponse(String msg) { + System.out.println(formatResponseString(msg)); + } + + public String formatResponseString(String msg) { + return " ____________________________________________________________\n" + + msg + "\n" + + " ____________________________________________________________\n"; + } + + public void formatTaskMsg(Task t, TaskList tasks) { + String msg = " Got it. I've added this task:\n" + + " " + t.toString() + "\n" + + " Now you have " + tasks.size() + " tasks in the list."; + System.out.println(formatResponseString(msg)); + } + + public String readCommand() { + return sc.nextLine(); + } + + public void newUserGreet() { + System.out.println(newUserOpening); + } + + public void returnUserGreet() { + System.out.println(returnUserOpening); + } +} diff --git a/src/main/java/UnmarkCommand.java b/src/main/java/UnmarkCommand.java new file mode 100644 index 000000000..5d07a2d49 --- /dev/null +++ b/src/main/java/UnmarkCommand.java @@ -0,0 +1,22 @@ +public class UnmarkCommand extends Commands { + private final int taskNo; + + UnmarkCommand(int taskNo) { + this.taskNo = taskNo; + } + + public void execute(TaskList tasks, Ui ui, Storage storage) { + try { + tasks.getTask(taskNo).unmarkAsDone(); + String reply = " OK, I've marked this task as not done yet:\n" + + " " + tasks.getTask(taskNo).toString(); + ui.formatResponse(reply); + } catch (NullPointerException e) { + String reply = " Task number not found, reenter with correct task number:"; + new MissingCommand(reply).execute(tasks, ui, storage); + } catch (NumberFormatException e) { + String reply = " No task number detected, reenter with correct task number:"; + new MissingCommand(reply).execute(tasks, ui, storage); + } + } +} diff --git a/src/main/java/Volkov.java b/src/main/java/Volkov.java index 7e05d3365..4a03f39a4 100644 --- a/src/main/java/Volkov.java +++ b/src/main/java/Volkov.java @@ -1,292 +1,26 @@ -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Scanner; -import java.io.File; -import java.io.FileWriter; - public class Volkov { - private static ArrayList listOfTasks = new ArrayList<>(); - - private static final int MARK_CMD_LENGTH = 5; - private static final int UNMARK_CMD_LENGTH = 7; - private static final int DELETE_CMD_LENGTH = 7; - private static final int TODO_CMD_LENGTH = 5; - private static final int DEADLINE_CMD_LENGTH = 8; - private static final int EVENT_CMD_LENGTH = 5; - private static final int DEADLINE_BY_LENGTH = 4; - private static final int EVENT_FROM_LENGTH = 6; - private static final int EVENT_TO_LENGTH = 4; - - private static final String BYE_COMMAND = "bye"; - private static final String LIST_COMMAND = "list"; - private static final String MARK_COMMAND = "mark"; - private static final String UNMARK_COMMAND = "unmark"; - private static final String DELETE_COMMAND = "delete"; - private static final String TODO_COMMAND = "todo"; - private static final String DEADLINE_COMMAND = "deadline"; - private static final String EVENT_COMMAND = "event"; - private static final String BY_KEYWORD = "/by"; - private static final String FROM_KEYWORD = "/from"; - private static final String TO_KEYWORD = "/to"; - - public static String formatResponse(String msg) { - return " ____________________________________________________________\n" - + msg + "\n" - + " ____________________________________________________________\n"; - } - - public static String formatTaskMsg(Task t) { - listOfTasks.add(t); - String msg = " Got it. I've added this task:\n" - + " " + t.toString() + "\n" - + " Now you have " + listOfTasks.size() + " tasks in the list."; - return formatResponse(msg); - } - - public static void doByeCommand() { - System.out.println(formatResponse(" Bye. Hope to see you again soon!")); - } - - public static void doListCommand() { - StringBuilder sb = new StringBuilder(); - sb.append(" Here are the tasks in your list:"); - for (int i = 0; i < listOfTasks.size(); i++) { - sb.append("\n ").append(i + 1).append(".").append(listOfTasks.get(i)); - } - System.out.println(formatResponse(sb.toString())); - } - - public static void doMarkCommand(String input) { - try { - int taskNo = Integer.parseInt(input.substring(MARK_CMD_LENGTH)) - 1; - listOfTasks.get(taskNo).markAsDone(); - String reply = " Nice! I've marked this task as done:\n" - + " " + listOfTasks.get(taskNo).toString(); - System.out.println(formatResponse(reply)); - } catch (NullPointerException e) { - String reply = " Task number not found, reenter with correct task number:"; - System.out.println(formatResponse(reply)); - } catch (NumberFormatException e) { - String reply = " No task number detected, reenter with correct task number:"; - System.out.println(formatResponse(reply)); - } - } - - public static void doUnmarkCommand(String input) { - try { - int taskNo = Integer.parseInt(input.substring(UNMARK_CMD_LENGTH)) - 1; - listOfTasks.get(taskNo).unmarkAsDone(); - String reply = " OK, I've marked this task as not done yet:\n" - + " " + listOfTasks.get(taskNo).toString(); - System.out.println(formatResponse(reply)); - } catch (NullPointerException e) { - String reply = " Task number not found, reenter with correct task number:"; - System.out.println(formatResponse(reply)); - } catch (NumberFormatException e) { - String reply = " No task number detected, reenter with correct task number:"; - System.out.println(formatResponse(reply)); - } - } - - public static void doDeleteCommand(String input) { - try { - int taskNo = Integer.parseInt(input.substring(DELETE_CMD_LENGTH)) - 1; - String reply = " Noted. I've removed this task::\n" - + " " + listOfTasks.get(taskNo).toString() - + " Now you have " + (listOfTasks.size()-1) + " tasks in the list."; - System.out.println(formatResponse(reply)); - listOfTasks.remove(taskNo); - } catch (NullPointerException e) { - String reply = " Task number not found, reenter with correct task number:"; - System.out.println(formatResponse(reply)); - } catch (NumberFormatException e) { - String reply = " No task number detected, reenter with correct task number:"; - System.out.println(formatResponse(reply)); - } - } - - public static void doTodoCommand(String input) { - try { - String taskDesc = input.substring(TODO_CMD_LENGTH); - if (taskDesc.trim().isEmpty()) { - throw new MissingDescription("MISSING DESCRIPTION, reenter with description"); - } - Todo t = new Todo(taskDesc); - System.out.println(formatTaskMsg(t)); - } catch (MissingDescription e) { - System.out.println(formatResponse(" " + e.getMessage())); - } - } - - public static void doDeadlineCommand(String input) { - try { - int indexOfDeadline = input.indexOf(BY_KEYWORD); - if (indexOfDeadline == -1) { - throw new MissingKeyword("MISSING '/by' keyword"); - } - String taskDesc = input.substring(DEADLINE_CMD_LENGTH, indexOfDeadline - 1).trim(); - if (taskDesc.trim().isEmpty()) { - throw new MissingDescription("MISSING DESCRIPTION, reenter with description"); - } - String deadline = input.substring(indexOfDeadline - 1 + DEADLINE_BY_LENGTH).trim(); - Deadline t = new Deadline(taskDesc, deadline); - System.out.println(formatTaskMsg(t)); - } catch (MissingDescription | MissingKeyword e) { - System.out.println(formatResponse(" " + e.getMessage())); - } - } - - public static void doEventCommand(String input) { - try { - int indexOfStartDate = input.indexOf(FROM_KEYWORD); - if (indexOfStartDate == -1) { - throw new MissingKeyword("MISSING '/from' keyword"); - } - int indexOfEndDate = input.indexOf(TO_KEYWORD); - if (indexOfEndDate == -1) { - throw new MissingKeyword("MISSING '/to' keyword"); - } - String taskDesc = input.substring(EVENT_CMD_LENGTH, indexOfStartDate - 1).trim(); - - if (taskDesc.trim().isEmpty()) { - throw new MissingDescription("MISSING DESCRIPTION, reenter with description"); - } + private final Storage storage; + private final TaskList tasks; + private final Ui ui; - String startDate = input.substring(indexOfStartDate - 1 + EVENT_FROM_LENGTH, indexOfEndDate - 1).trim(); - String endDate = input.substring(indexOfEndDate - 1 + EVENT_TO_LENGTH).trim(); - Event t = new Event(taskDesc, startDate, endDate); - System.out.println(formatTaskMsg(t)); - } catch (MissingDescription | MissingKeyword e) { - System.out.println(formatResponse(" " + e.getMessage())); - } + public Volkov(String filePath) { + ui = new Ui(); + storage = new Storage("./data/volkov.txt", ui); + this.tasks = storage.loadFile(); } - public static void saveFile() { - String fileName = "./data/volkov.txt"; - - try { - File f = new File(fileName); - - File parentDir = f.getParentFile(); - if (!parentDir.exists()) { - if (parentDir.mkdirs()) { - System.out.println(formatResponse(" Folder missing, new folder created")); - } - } - - if (f.createNewFile()) { - System.out.println(formatResponse(" No file present, new file created")); - } - - FileWriter fw = new FileWriter(fileName); - for (Task task : listOfTasks) { - fw.write(task.txtSave() + "\n"); - } - fw.close(); - - } catch (IOException e) { - System.out.println("Something went wrong: " + e.getMessage()); - } - } - - public static void loadFile() { - - String fileName = "./data/volkov.txt"; - - String newUserOpening = " ____________________________________________________________\n" - + " Hello! I'm Volkov\n" - + " What can I do for you?\n" - + " ____________________________________________________________\n"; - - String returnUserOpening = " ____________________________________________________________\n" - + " Welcome back!\n" - + " What can Volkov do for you?\n" - + " ____________________________________________________________\n"; - - File f = new File(fileName); - if (f.exists()) { - System.out.println(returnUserOpening); - } else { - System.out.println(newUserOpening); - } - - try { - Scanner s = new Scanner(f); - while (s.hasNextLine()) { - String taskString = s.nextLine(); - - if (taskString.startsWith("[T]")) { - Task t = new Todo(taskString.substring(7).trim()); - if (taskString.contains("[X]")) { - t.markAsDone(); - } - listOfTasks.add(t); - } else if (taskString.startsWith("[D]")) { - String[] descAndDate = taskString.substring(7).split("\\|"); - String desc = descAndDate[0].trim(); - String date = descAndDate[1].trim(); - Task t = new Deadline(desc, date); - if (taskString.contains("[X]")) { - t.markAsDone(); - } - listOfTasks.add(t); - } else if (taskString.startsWith("[E]")) { - String[] descAndDate = taskString.substring(7).split("\\|"); - String desc = descAndDate[0].trim(); - String start = descAndDate[1].trim(); - String end = descAndDate[2].trim(); - Task t = new Event(desc, start, end); - if (taskString.contains("[X]")) { - t.markAsDone(); - } - listOfTasks.add(t); - } - } - } catch (FileNotFoundException e) { - + public void run() { + boolean isExit = false; + while (!isExit) { + String fullCommand = ui.readCommand(); + Commands c = Parser.parse(fullCommand); + c.execute(tasks, ui, storage); + isExit = c.isExit(); } + storage.saveFile(tasks); } public static void main(String[] args) { - loadFile(); - - Scanner sc = new Scanner(System.in); - - while (true) { - String input = sc.nextLine(); - - if (input.equals(BYE_COMMAND)) { - doByeCommand(); - break; - - } else if (input.equals(LIST_COMMAND)) { - doListCommand(); - - } else if (input.startsWith(MARK_COMMAND)) { - doMarkCommand(input); - - } else if (input.startsWith(UNMARK_COMMAND)) { - doUnmarkCommand(input); - - } else if (input.startsWith(DELETE_COMMAND)) { - doDeleteCommand(input); - - } else if (input.startsWith(TODO_COMMAND)) { - doTodoCommand(input); - - } else if (input.startsWith(DEADLINE_COMMAND)) { - doDeadlineCommand(input); - - } else if (input.startsWith(EVENT_COMMAND)) { - doEventCommand(input); - - } else { - String reply = " Unknown command received, reenter command:"; - System.out.println(formatResponse(reply)); - } - } - saveFile(); + new Volkov("data/tasks.txt").run(); } } From b90a9f5fdda5e95d7c3cc84c2c300c9dee9bddea Mon Sep 17 00:00:00 2001 From: JinbaoAlex Date: Thu, 13 Mar 2025 11:48:12 +0800 Subject: [PATCH 14/21] Level-8 Date and Times --- src/main/java/Deadline.java | 18 +++++++++++++++++- src/main/java/Event.java | 21 ++++++++++++++++++++- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/main/java/Deadline.java b/src/main/java/Deadline.java index 9435746df..c7876892d 100644 --- a/src/main/java/Deadline.java +++ b/src/main/java/Deadline.java @@ -1,9 +1,20 @@ +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; + public class Deadline extends Task { protected String deadline; + protected LocalDate deadlineLocalDate; public Deadline(String description, String deadline) { super(description); this.deadline = deadline; + try { + this.deadlineLocalDate = LocalDate.parse(deadline); + } catch (DateTimeParseException e) { + this.deadlineLocalDate = null; + } + } public String txtSave() { @@ -12,6 +23,11 @@ public String txtSave() { @Override public String toString() { - return "[D]" + super.toString() + " (by: " + deadline + ")"; + if (deadlineLocalDate != null) { + String deadlineFormatted = deadlineLocalDate.format(DateTimeFormatter.ofPattern("MMM d yyyy")); + return "[D]" + super.toString() + " (by: " + deadlineFormatted + ")"; + } else { + return "[D]" + super.toString() + " (by: " + deadline + ")"; + } } } diff --git a/src/main/java/Event.java b/src/main/java/Event.java index b107dd848..098add80a 100644 --- a/src/main/java/Event.java +++ b/src/main/java/Event.java @@ -1,11 +1,24 @@ +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; + public class Event extends Task { protected String startDate; protected String endDate; + protected LocalDate startLocalDate; + protected LocalDate endLocalDate; public Event(String description, String startDate, String endDate) { super(description); this.startDate = startDate; this.endDate = endDate; + try { + this.startLocalDate = LocalDate.parse(startDate); + this.endLocalDate = LocalDate.parse(endDate); + } catch (DateTimeParseException e) { + this.startLocalDate = null; + this.endLocalDate = null; + } } public String txtSave() { @@ -14,6 +27,12 @@ public String txtSave() { @Override public String toString() { - return "[E]" + super.toString() + " (from: " + startDate + " to: " + endDate + ")"; + if (startLocalDate != null && endLocalDate != null) { + String startDateFormatted = startLocalDate.format(DateTimeFormatter.ofPattern("MMM d yyyy")); + String endDateFormatted = endLocalDate.format(DateTimeFormatter.ofPattern("MMM d yyyy")); + return "[E]" + super.toString() + " (from: " + startDateFormatted + " to: " + endDateFormatted + ")"; + } else { + return "[E]" + super.toString() + " (from: " + startDate + " to: " + endDate + ")"; + } } } From c2a95b177b5f8ddbec22826da53ebb53fbd03951 Mon Sep 17 00:00:00 2001 From: JinbaoAlex Date: Thu, 13 Mar 2025 12:03:48 +0800 Subject: [PATCH 15/21] Level-9 Added find feature --- src/main/java/FindCommand.java | 20 ++++++++++++++++++++ src/main/java/Parser.java | 6 ++++++ src/main/java/Task.java | 4 ++++ 3 files changed, 30 insertions(+) create mode 100644 src/main/java/FindCommand.java diff --git a/src/main/java/FindCommand.java b/src/main/java/FindCommand.java new file mode 100644 index 000000000..1e8fd0bbd --- /dev/null +++ b/src/main/java/FindCommand.java @@ -0,0 +1,20 @@ +public class FindCommand extends Commands { + private final String searchTerm; + + FindCommand(String searchTerm) { + this.searchTerm = searchTerm; + } + + public void execute(TaskList tasks, Ui ui, Storage storage) { + StringBuilder sb = new StringBuilder(); + sb.append(" Here are the matching tasks in your list:"); + int count = 1; + for (int i = 0; i < tasks.size(); i++) { + if (tasks.getTask(i).find(searchTerm)) { + sb.append("\n ").append(count).append(".").append(tasks.getTask(i)); + count++; + } + } + ui.formatResponse(sb.toString()); + } +} diff --git a/src/main/java/Parser.java b/src/main/java/Parser.java index 07b433ed5..e194db7e3 100644 --- a/src/main/java/Parser.java +++ b/src/main/java/Parser.java @@ -1,4 +1,5 @@ public class Parser { + private static final int FIND_CMD_LENGTH = 5; private static final int MARK_CMD_LENGTH = 5; private static final int UNMARK_CMD_LENGTH = 7; private static final int DELETE_CMD_LENGTH = 7; @@ -12,6 +13,7 @@ public class Parser { private static final String BYE_COMMAND = "bye"; private static final String LIST_COMMAND = "list"; + private static final String FIND_COMMAND = "find"; private static final String MARK_COMMAND = "mark"; private static final String UNMARK_COMMAND = "unmark"; private static final String DELETE_COMMAND = "delete"; @@ -28,6 +30,10 @@ public static Commands parse(String input) { } else if (input.startsWith(LIST_COMMAND)) { return new ListCommand(); + } else if (input.startsWith(FIND_COMMAND)) { + String searchTerm = input.substring(MARK_CMD_LENGTH); + return new FindCommand(searchTerm); + } else if (input.startsWith(MARK_COMMAND)) { int taskNo = Integer.parseInt(input.substring(MARK_CMD_LENGTH)) - 1; return new MarkCommand(taskNo); diff --git a/src/main/java/Task.java b/src/main/java/Task.java index 0d83ed6cc..d0160cca1 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -23,6 +23,10 @@ public String getMark() { } } + public boolean find(String searchTerm) { + return this.description.contains(searchTerm); + } + public String txtSave() { return getMark() + description; } From fca55c57e90927eb3bc42deb196b79f91051615c Mon Sep 17 00:00:00 2001 From: JinbaoAlex Date: Fri, 14 Mar 2025 10:48:36 +0800 Subject: [PATCH 16/21] A-JavaDoc Added JavaDoc comments for most methods and classes --- src/main/java/ByeCommand.java | 15 +++++++++++++++ src/main/java/Commands.java | 22 ++++++++++++++++++++++ src/main/java/Deadline.java | 10 ++++++++++ src/main/java/DeadlineCommand.java | 15 +++++++++++++++ src/main/java/DeleteCommand.java | 12 ++++++++++++ src/main/java/Event.java | 10 ++++++++++ src/main/java/EventCommand.java | 15 +++++++++++++++ src/main/java/ListCommand.java | 14 ++++++++++++-- src/main/java/MarkCommand.java | 15 +++++++++++++++ src/main/java/MissingCommand.java | 14 ++++++++++++++ src/main/java/Parser.java | 14 ++++++++++++++ src/main/java/Storage.java | 22 ++++++++++++++++++++++ src/main/java/Task.java | 22 ++++++++++++++++++++++ src/main/java/TaskList.java | 6 ++++++ src/main/java/Todo.java | 10 ++++++++++ src/main/java/TodoCommand.java | 14 ++++++++++++++ src/main/java/Ui.java | 29 ++++++++++++++++++++++++++++- src/main/java/UnmarkCommand.java | 15 +++++++++++++++ src/main/java/Volkov.java | 7 +++++++ 19 files changed, 278 insertions(+), 3 deletions(-) diff --git a/src/main/java/ByeCommand.java b/src/main/java/ByeCommand.java index 8ad2a15aa..256e71ebf 100644 --- a/src/main/java/ByeCommand.java +++ b/src/main/java/ByeCommand.java @@ -1,9 +1,24 @@ +/** + * Represents the command to exit the program + */ public class ByeCommand extends Commands { + /** + * Executes the exit command by displaying a farewell message to the user. + * + * @param tasks The {@code TaskList} containing all tasks. + * @param ui The {@code Ui} for user interaction. + * @param storage The {@code Storage} for file operations. + */ public void execute(TaskList tasks, Ui ui, Storage storage) { new Ui().formatResponse(" Bye. Hope to see you again soon!"); } + /** + * Returns boolean true to indicate the exiting of the program + * + * @return {@code true} + */ public boolean isExit() { return true; } diff --git a/src/main/java/Commands.java b/src/main/java/Commands.java index 3f5dc9595..eae21798c 100644 --- a/src/main/java/Commands.java +++ b/src/main/java/Commands.java @@ -1,6 +1,28 @@ +/** + * Represents an abstract command to be executed in the main body. + * Subclasses of {@code Commands} implements methods with specific behavior + * relevant to their respective commands + */ public abstract class Commands { + /** + * Executes the command with the task list, user interface, and storage. + *

+ * Exact implementations depends on the relevant command. + * + * @param tasks The {@code TaskList} containing all tasks. + * @param ui The {@code Ui} object handling user interactions. + * @param storage The {@code Storage} object for file operations. + */ public void execute(TaskList tasks, Ui ui, Storage storage) {} + /** + * Determines whether this command is an exit command. + *

+ * Defaults to {@code false}, and only exit commands + * would override this method to return {@code true}. + * + * @return {@code true} if the command should terminate the program, otherwise {@code false}. + */ public boolean isExit() { return false; } diff --git a/src/main/java/Deadline.java b/src/main/java/Deadline.java index 9435746df..31a93b6b0 100644 --- a/src/main/java/Deadline.java +++ b/src/main/java/Deadline.java @@ -6,10 +6,20 @@ public Deadline(String description, String deadline) { this.deadline = deadline; } + /** + * {@inheritDoc} + * This method is inherited from {@link Task}. + * @return A string representation of the task, its description, and deadline date + */ public String txtSave() { return "[D]" + super.txtSave() + "|" + deadline; } + /** + * {@inheritDoc} + * This method is inherited from {@link Task}. + * @return A formatted string representing the task. + */ @Override public String toString() { return "[D]" + super.toString() + " (by: " + deadline + ")"; diff --git a/src/main/java/DeadlineCommand.java b/src/main/java/DeadlineCommand.java index 1514c7ed9..035b449ae 100644 --- a/src/main/java/DeadlineCommand.java +++ b/src/main/java/DeadlineCommand.java @@ -1,3 +1,10 @@ +/** + * Represents the command to add a deadline task + *

+ * The {@code DeadlineCommand} creates a new {@code Deadline} task + * with a specified description and a deadline date, + * and adds it to the {@code TaskList}. + */ public class DeadlineCommand extends Commands { private final String taskDesc; private final String deadline; @@ -7,6 +14,14 @@ public class DeadlineCommand extends Commands { this.deadline = deadline; } + /** + * Executes the deadline command by creating a {@code Deadline} object, + * adds it to the taskList and displays a confirmation message. + * + * @param tasks The {@code TaskList} containing all tasks. + * @param ui The {@code Ui} for user interaction. + * @param storage The {@code Storage} for file operations. + */ public void execute(TaskList tasks, Ui ui, Storage storage) { Deadline t = new Deadline(taskDesc, deadline); tasks.addTask(t); diff --git a/src/main/java/DeleteCommand.java b/src/main/java/DeleteCommand.java index 9c6c5f202..e70b7ca81 100644 --- a/src/main/java/DeleteCommand.java +++ b/src/main/java/DeleteCommand.java @@ -1,3 +1,6 @@ +/** + * Represents the command to delete a task based on its taskNo from the tasklist + */ public class DeleteCommand extends Commands { private final int taskNo; @@ -5,6 +8,15 @@ public class DeleteCommand extends Commands { this.taskNo = taskNo; } + /** + * Executes the delete command by removing the specified task from the task list. + * Displays a confirmation message when successfully deleted. + * If the task number is invalid, an error message is displayed instead. + * + * @param tasks The {@code TaskList} containing all tasks. + * @param ui The {@code Ui} for user interaction. + * @param storage The {@code Storage} for file operations. + */ public void execute(TaskList tasks, Ui ui, Storage storage) { try { String reply = " Noted. I've removed this task::\n" diff --git a/src/main/java/Event.java b/src/main/java/Event.java index b107dd848..c72b4dec9 100644 --- a/src/main/java/Event.java +++ b/src/main/java/Event.java @@ -8,10 +8,20 @@ public Event(String description, String startDate, String endDate) { this.endDate = endDate; } + /** + * {@inheritDoc} + * This method is inherited from {@link Task}. + * @return A string representation of the task, its description, and start and end dates. + */ public String txtSave() { return "[E]" + super.txtSave() + "|" + startDate + "|" + endDate; } + /** + * {@inheritDoc} + * This method is inherited from {@link Task}. + * @return A formatted string representing the task. + */ @Override public String toString() { return "[E]" + super.toString() + " (from: " + startDate + " to: " + endDate + ")"; diff --git a/src/main/java/EventCommand.java b/src/main/java/EventCommand.java index e94344f5f..6d4071ea8 100644 --- a/src/main/java/EventCommand.java +++ b/src/main/java/EventCommand.java @@ -1,3 +1,10 @@ +/** + * Represents the command to add an event task. + *

+ * The {@code EventCommand} creates a new {@code Event} task with + * a specified description and a start and end date, + * and adds it to the {@code TaskList}. + */ public class EventCommand extends Commands { private final String taskDesc; private final String startDate; @@ -9,6 +16,14 @@ public class EventCommand extends Commands { this.endDate = endDate; } + /** + * Executes the command by creating a new {@code Event} object, + * adds it to the task list, and displays a confirmation message. + * + * @param tasks The {@code TaskList} containing all tasks. + * @param ui The {@code Ui} for user interaction. + * @param storage The {@code Storage} for file operations. + */ public void execute(TaskList tasks, Ui ui, Storage storage) { Event t = new Event(taskDesc, startDate, endDate); tasks.addTask(t); diff --git a/src/main/java/ListCommand.java b/src/main/java/ListCommand.java index d90b89cb8..9a18ffd50 100644 --- a/src/main/java/ListCommand.java +++ b/src/main/java/ListCommand.java @@ -1,5 +1,17 @@ +/** + * Represents the command to list all tasks in the task list. + *

+ * The {@code ListCommand} retrieves and displays all tasks currently stored in the {@code TaskList}. + */ public class ListCommand extends Commands { + /** + * Executes the command by iterating through and printing every task in the {@code TaskList}. + * + * @param tasks The {@code TaskList} containing all tasks. + * @param ui The {@code Ui} for user interaction. + * @param storage The {@code Storage} for file operations. + */ public void execute(TaskList tasks, Ui ui, Storage storage) { StringBuilder sb = new StringBuilder(); sb.append(" Here are the tasks in your list:"); @@ -8,6 +20,4 @@ public void execute(TaskList tasks, Ui ui, Storage storage) { } ui.formatResponse(sb.toString()); } - - } diff --git a/src/main/java/MarkCommand.java b/src/main/java/MarkCommand.java index 0e59a5c33..7933ca845 100644 --- a/src/main/java/MarkCommand.java +++ b/src/main/java/MarkCommand.java @@ -1,3 +1,9 @@ +/** + * Represents the command to mark a task as done. + *

+ * The {@code MarkCommand} updates the specified task number's + * task's status as done and displays a confirmation message to the user. + */ public class MarkCommand extends Commands { private final int taskNo; @@ -5,6 +11,15 @@ public class MarkCommand extends Commands { this.taskNo = taskNo; } + /** + * Executes the command by marking the specified task as done. + * Displays a confirmation message when successful, or an error + * message if the task number is invalid. + * + * @param tasks The {@code TaskList} containing all tasks. + * @param ui The {@code Ui} for user interaction. + * @param storage The {@code Storage} for file operations. + */ public void execute(TaskList tasks, Ui ui, Storage storage) { try { tasks.getTask(taskNo).markAsDone(); diff --git a/src/main/java/MissingCommand.java b/src/main/java/MissingCommand.java index 72a36dde4..787481674 100644 --- a/src/main/java/MissingCommand.java +++ b/src/main/java/MissingCommand.java @@ -1,3 +1,10 @@ +/** + * Represents a command for handling unrecognized or incomplete commands. + *

+ * The {@code MissingCommand} is used when a user enters an invalid command + * or lacks relevant parameters. It then displays an error message to + * guide the user in correcting this. + */ public class MissingCommand extends Commands{ private final String reply; @@ -5,6 +12,13 @@ public class MissingCommand extends Commands{ this.reply = reply; } + /** + * Executes the command by displaying the provided error message to the user. + * + * @param tasks The {@code TaskList} containing all tasks. + * @param ui The {@code Ui} for user interaction. + * @param storage The {@code Storage} for file operations. + */ public void execute(TaskList tasks, Ui ui, Storage storage) { new Ui().formatResponse(" " + reply); } diff --git a/src/main/java/Parser.java b/src/main/java/Parser.java index 07b433ed5..bc9e3e86f 100644 --- a/src/main/java/Parser.java +++ b/src/main/java/Parser.java @@ -1,3 +1,7 @@ +/** + * The {@code Parser} class deals with making sense of the user command, + * then maps it to the respective commands. + */ public class Parser { private static final int MARK_CMD_LENGTH = 5; private static final int UNMARK_CMD_LENGTH = 7; @@ -22,6 +26,16 @@ public class Parser { private static final String FROM_KEYWORD = "/from"; private static final String TO_KEYWORD = "/to"; + /** + * Parses the given user input and returns the corresponding command. + *

+ * This method identifies the relevant command by checking the input string + * against predetermined command keywords and extracts the respective necessary + * parameters, using which to return an appropriate {@code Commands} object. + * + * @param input The user input to parse. + * @return A {@code Commands} object representing the parsed command. + */ public static Commands parse(String input) { if (input.startsWith(BYE_COMMAND)) { return new ByeCommand(); diff --git a/src/main/java/Storage.java b/src/main/java/Storage.java index ce6ce356c..cb28404c6 100644 --- a/src/main/java/Storage.java +++ b/src/main/java/Storage.java @@ -4,6 +4,10 @@ import java.io.IOException; import java.util.Scanner; +/** + * The {@code Storage} class deals with the loading + * and saving of tasks in a local txt file. + */ public class Storage { private final String filePath; Ui ui; @@ -13,6 +17,14 @@ public class Storage { this.ui = ui; } + /** + * Saves the current list of tasks to a txt file. + *

+ * If the file or directory does not exist, it will be created first. + * Tasks are saved in a format to ease the load process + * + * @param taskList The list of tasks to be saved. + */ public void saveFile(TaskList taskList) { try { File f = new File(filePath); @@ -39,6 +51,16 @@ public void saveFile(TaskList taskList) { } } + /** + * Attempts to load tasks from the txt file into a new {@code TaskList}. + *

+ * If the file exists, it greets the user as a returning user, + * reads, parses and loads the tasks from the txt file to a new {@code TaskList} + * which then gets returned. Otherwise, it greets the user as a new user + * and returns an empty {@code TaskList}. + * + * @return A {@code TaskList} containing the loaded tasks. + */ public TaskList loadFile() { TaskList taskList = new TaskList(); diff --git a/src/main/java/Task.java b/src/main/java/Task.java index 0d83ed6cc..df5a95412 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -1,3 +1,9 @@ +/** + * Represents a generic task with a description and completion status. + *

+ * The {@code Task} class provides methods to mark the task as done, + * unmark it, retrieve its status, and formatting for displaying or saving. + */ public class Task { protected String description; protected boolean isDone; @@ -15,6 +21,11 @@ public void unmarkAsDone() { isDone = false; } + /** + * Returns the string formatting that represents the completion status of the task. + * + * @return A string "[X] " if the task is done, "[ ] " if not. + */ public String getMark() { if (isDone) { return "[X] "; @@ -23,10 +34,21 @@ public String getMark() { } } + /** + * Returns the string formatting used for saving of the task's information + * + * @return A string representation of the task and its information + */ public String txtSave() { return getMark() + description; } + /** + * Returns a string representation of the task, + * including its type, completion status and description. + * + * @return A formatted string representing the task. + */ @Override public String toString() { String mark = getMark(); diff --git a/src/main/java/TaskList.java b/src/main/java/TaskList.java index 8b537d219..f4191d2c5 100644 --- a/src/main/java/TaskList.java +++ b/src/main/java/TaskList.java @@ -1,3 +1,9 @@ +/** + * Contains the list of tasks + *

+ * The {@code TaskList} class provides methods to add, remove, retrieve, + * and access the number of tasks stored in an {@code ArrayList}. + */ import java.util.ArrayList; public class TaskList { diff --git a/src/main/java/Todo.java b/src/main/java/Todo.java index 869fab1fa..309ec1531 100644 --- a/src/main/java/Todo.java +++ b/src/main/java/Todo.java @@ -4,10 +4,20 @@ public Todo(String description) { super(description); } + /** + * {@inheritDoc} + * This method is inherited from {@link Task}. + * @return A string representation of the task and its description + */ public String txtSave() { return "[T]" + super.txtSave(); } + /** + * {@inheritDoc} + * This method is inherited from {@link Task}. + * @return A formatted string representing the task. + */ @Override public String toString() { return "[T]" + super.toString(); diff --git a/src/main/java/TodoCommand.java b/src/main/java/TodoCommand.java index 8c9cade47..109bf35b9 100644 --- a/src/main/java/TodoCommand.java +++ b/src/main/java/TodoCommand.java @@ -1,3 +1,9 @@ +/** + * Represents a command to add a new to-do task. + *

+ * The {@code TodoCommand} creates a new to-do task with a specified description + * and adds it to the task list.

+ */ public class TodoCommand extends Commands { private final String taskDesc; @@ -5,6 +11,14 @@ public class TodoCommand extends Commands { this.taskDesc = taskDesc; } + /** + * Executes the command by creating a new {@code Todo} object, + * adds it to the task list, and displays a confirmation message. + * + * @param tasks The {@code TaskList} containing all tasks. + * @param ui The {@code Ui} for user interaction. + * @param storage The {@code Storage} for file operations. + */ public void execute(TaskList tasks, Ui ui, Storage storage) { Todo t = new Todo(taskDesc); tasks.addTask(t); diff --git a/src/main/java/Ui.java b/src/main/java/Ui.java index ab6b0220f..daa8fbd41 100644 --- a/src/main/java/Ui.java +++ b/src/main/java/Ui.java @@ -1,5 +1,9 @@ import java.util.Scanner; - +/** + * The {@code Ui} class deals with interactions with the + * user by handling the formatting of responses, + * reading user input, and displaying greeting messages. + */ public class Ui { private Scanner sc = new Scanner(System.in); @@ -13,16 +17,33 @@ public class Ui { + " What can Volkov do for you?\n" + " ____________________________________________________________\n"; + /** + * Prints a formatted response. + * + * @param msg The message to be displayed after formatting. + */ public void formatResponse(String msg) { System.out.println(formatResponseString(msg)); } + /** + * Formats a given message. + * + * @param msg The message to be formatted. + * @return A formatted string of the given message + */ public String formatResponseString(String msg) { return " ____________________________________________________________\n" + msg + "\n" + " ____________________________________________________________\n"; } + /** + * Prints the formatted message for when a new task is added. + *

+ * @param t The task that was added. + * @param tasks The task list that the task is added to. + */ public void formatTaskMsg(Task t, TaskList tasks) { String msg = " Got it. I've added this task:\n" + " " + t.toString() + "\n" @@ -34,10 +55,16 @@ public String readCommand() { return sc.nextLine(); } + /** + * Displays the new user greeting message. + */ public void newUserGreet() { System.out.println(newUserOpening); } + /** + * Displays the returning user greeting message. + */ public void returnUserGreet() { System.out.println(returnUserOpening); } diff --git a/src/main/java/UnmarkCommand.java b/src/main/java/UnmarkCommand.java index 5d07a2d49..0770f43d9 100644 --- a/src/main/java/UnmarkCommand.java +++ b/src/main/java/UnmarkCommand.java @@ -1,3 +1,9 @@ +/** + * Represents the command to mark a task as not done. + *

+ * The {@code UnmarkCommand} updates the specified task number's + * task's status as not done and displays a confirmation message to the user. + */ public class UnmarkCommand extends Commands { private final int taskNo; @@ -5,6 +11,15 @@ public class UnmarkCommand extends Commands { this.taskNo = taskNo; } + /** + * Executes the command by marking the specified task as not done. + * Displays a confirmation message when successful, or an error + * message if the task number is invalid. + * + * @param tasks The {@code TaskList} containing all tasks. + * @param ui The {@code Ui} for user interaction. + * @param storage The {@code Storage} for file operations. + */ public void execute(TaskList tasks, Ui ui, Storage storage) { try { tasks.getTask(taskNo).unmarkAsDone(); diff --git a/src/main/java/Volkov.java b/src/main/java/Volkov.java index 4a03f39a4..39821a409 100644 --- a/src/main/java/Volkov.java +++ b/src/main/java/Volkov.java @@ -1,3 +1,6 @@ +/** + * The main code for the Volkov application that handles the overall workflow. + */ public class Volkov { private final Storage storage; private final TaskList tasks; @@ -9,6 +12,10 @@ public Volkov(String filePath) { this.tasks = storage.loadFile(); } + /** + * Main application loop for processing user commands. This keeps + * running until the user exits the program. + */ public void run() { boolean isExit = false; while (!isExit) { From 7e2666d746d0f1753f1840b1431023de864a0192 Mon Sep 17 00:00:00 2001 From: JinbaoAlex Date: Fri, 14 Mar 2025 13:04:51 +0800 Subject: [PATCH 17/21] Added more javadoc comments --- src/main/java/Deadline.java | 6 ++++++ src/main/java/Event.java | 6 ++++++ src/main/java/FindCommand.java | 13 +++++++++++++ src/main/java/Todo.java | 6 ++++++ 4 files changed, 31 insertions(+) diff --git a/src/main/java/Deadline.java b/src/main/java/Deadline.java index db7aab8e0..6e62d7ae5 100644 --- a/src/main/java/Deadline.java +++ b/src/main/java/Deadline.java @@ -2,6 +2,12 @@ import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; +/** + * Represents a deadline task with a description, completion status, and deadline date. + *

+ * The {@code Deadline} class provides methods to mark the task as done, + * unmark it, retrieve its status, and formatting for displaying or saving. + */ public class Deadline extends Task { protected String deadline; protected LocalDate deadlineLocalDate; diff --git a/src/main/java/Event.java b/src/main/java/Event.java index 547c04c7b..dbecc1b1f 100644 --- a/src/main/java/Event.java +++ b/src/main/java/Event.java @@ -2,6 +2,12 @@ import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; +/** + * Represents an event task with a description, completion status, and start and end dates. + *

+ * The {@code Event} class provides methods to mark the task as done, + * unmark it, retrieve its status, and formatting for displaying or saving. + */ public class Event extends Task { protected String startDate; protected String endDate; diff --git a/src/main/java/FindCommand.java b/src/main/java/FindCommand.java index 1e8fd0bbd..e88d74926 100644 --- a/src/main/java/FindCommand.java +++ b/src/main/java/FindCommand.java @@ -1,3 +1,8 @@ +/** + * Represents the command to search for tasks + *

+ * The {@code FindCommand} finds the task the user wishes to search for in the {@code TaskList}. + */ public class FindCommand extends Commands { private final String searchTerm; @@ -5,6 +10,14 @@ public class FindCommand extends Commands { this.searchTerm = searchTerm; } + /** + * Executes the command by iterating through and printing every task in the {@code TaskList} + * that matches the searchTerm. + * + * @param tasks The {@code TaskList} containing all tasks. + * @param ui The {@code Ui} for user interaction. + * @param storage The {@code Storage} for file operations. + */ public void execute(TaskList tasks, Ui ui, Storage storage) { StringBuilder sb = new StringBuilder(); sb.append(" Here are the matching tasks in your list:"); diff --git a/src/main/java/Todo.java b/src/main/java/Todo.java index 309ec1531..990c72eb7 100644 --- a/src/main/java/Todo.java +++ b/src/main/java/Todo.java @@ -1,3 +1,9 @@ +/** + * Represents a todo task with a description and completion status. + *

+ * The {@code Todo} class provides methods to mark the task as done, + * unmark it, retrieve its status, and formatting for displaying or saving. + */ public class Todo extends Task { public Todo(String description) { From ace02c74a8f74e212a2390fe9465f2435fa63640 Mon Sep 17 00:00:00 2001 From: JinbaoAlex Date: Fri, 14 Mar 2025 14:03:13 +0800 Subject: [PATCH 18/21] added some additional exception handling --- src/main/java/MarkCommand.java | 2 +- src/main/java/Parser.java | 2 +- src/main/java/UnmarkCommand.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/MarkCommand.java b/src/main/java/MarkCommand.java index 7933ca845..f82f7ac64 100644 --- a/src/main/java/MarkCommand.java +++ b/src/main/java/MarkCommand.java @@ -26,7 +26,7 @@ public void execute(TaskList tasks, Ui ui, Storage storage) { String reply = " Nice! I've marked this task as done:\n" + " " + tasks.getTask(taskNo).toString(); ui.formatResponse(reply); - } catch (NullPointerException e) { + } catch (NullPointerException | IndexOutOfBoundsException e) { String reply = " Task number not found, reenter with correct task number:"; new MissingCommand(reply).execute(tasks, ui, storage); } catch (NumberFormatException e) { diff --git a/src/main/java/Parser.java b/src/main/java/Parser.java index 44da91d25..21f90d611 100644 --- a/src/main/java/Parser.java +++ b/src/main/java/Parser.java @@ -45,7 +45,7 @@ public static Commands parse(String input) { return new ListCommand(); } else if (input.startsWith(FIND_COMMAND)) { - String searchTerm = input.substring(MARK_CMD_LENGTH); + String searchTerm = input.substring(FIND_CMD_LENGTH); return new FindCommand(searchTerm); } else if (input.startsWith(MARK_COMMAND)) { diff --git a/src/main/java/UnmarkCommand.java b/src/main/java/UnmarkCommand.java index 0770f43d9..ad22ab090 100644 --- a/src/main/java/UnmarkCommand.java +++ b/src/main/java/UnmarkCommand.java @@ -26,7 +26,7 @@ public void execute(TaskList tasks, Ui ui, Storage storage) { String reply = " OK, I've marked this task as not done yet:\n" + " " + tasks.getTask(taskNo).toString(); ui.formatResponse(reply); - } catch (NullPointerException e) { + } catch (NullPointerException | IndexOutOfBoundsException e) { String reply = " Task number not found, reenter with correct task number:"; new MissingCommand(reply).execute(tasks, ui, storage); } catch (NumberFormatException e) { From 6d4f7794cb9af5ba002c2935dde9a752140a847e Mon Sep 17 00:00:00 2001 From: JinbaoAlex Date: Fri, 14 Mar 2025 21:47:24 +0800 Subject: [PATCH 19/21] updated userguide and customised the chatbot's message --- docs/README.md | 153 ++++++++++++++++++++++++++++--- src/main/java/ByeCommand.java | 2 +- src/main/java/DeleteCommand.java | 6 +- src/main/java/FindCommand.java | 2 +- src/main/java/ListCommand.java | 2 +- src/main/java/MarkCommand.java | 2 +- src/main/java/Ui.java | 6 +- src/main/java/UnmarkCommand.java | 2 +- 8 files changed, 150 insertions(+), 25 deletions(-) diff --git a/docs/README.md b/docs/README.md index 47b9f984f..19d39cd3f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,30 +1,155 @@ -# Duke User Guide +# Volkov User Guide -// Update the title above to match the actual product name +Volkov is a command-line task manager that allows you to add 3 different types of tasks, +set their relevant dates, and track your progress with simple commands. +Your tasks are saved automatically, allowing you to revisit whenever you need to. -// Product screenshot goes here +## Adding a Todo Task: `todo` +Adds a todo task for Volkov to remember. -// Product intro goes here +**Format:** +`todo DESCRIPTION` +**Examples:** +``` +todo buy groceries +``` +**Expected Outcome:** +``` + ____________________________________________________________ + Roger. Task has been added to the list: + [T][ ] buy groceries + You now have 1 tasks in the list. + ____________________________________________________________ + +``` + +## Adding a Deadline Task: `deadline` +Adds a deadline task for Volkov to remember. + +**Format:** +`deadline DESCRIPTION /by DATE` +**Examples:** +``` +deadline do homework /by 2025-03-14 +``` +**Expected Outcome:** +``` + ____________________________________________________________ + Roger. Task has been added to the list: + [D][ ] do homework (by: Mar 14 2025) + You now have 2 tasks in the list. + ____________________________________________________________ +``` -## Adding deadlines +## Adding an Event Task: `event` +Adds an event task for Volkov to remember. -// Describe the action and its outcome. +**Format:** +`event DESCRIPTION /from STARTDATE /to ENDDATE` +**Examples:** +``` +event open house /from 2025-02-16 /to 2025-02-18 +``` +**Expected Outcome:** +``` + ____________________________________________________________ + Roger. Task has been added to the list: + [E][ ] open house (from: Feb 16 2025 to: Feb 18 2025) + You now have 3 tasks in the list. + ____________________________________________________________ +``` + +## Mark a task as done: `mark` +Marks a task as completed in Volkov's task list. + +**Format:** +`mark TASKNO` +**Examples:** +``` +mark 1 +``` +**Expected Outcome:** +``` + ____________________________________________________________ + Roger. This task has been marked as done: + [T][X] buy groceries + ____________________________________________________________ +``` -// Give examples of usage +## Mark a task as notdone: `unmark` +Marks a task as uncompleted in Volkov's task list. -Example: `keyword (optional arguments)` +**Format:** +`unmark TASKNO` +**Examples:** +``` +unmark 1 +``` +**Expected Outcome:** +``` + ____________________________________________________________ + Roger. This task has been marked as not done yet: + [T][ ] buy groceries + ____________________________________________________________ +``` -// A description of the expected outcome goes here +## Delete a task: `delete` +Removes a task from Volkov's task list. +**Format:** +`delete TASKNO` +**Examples:** +``` +delete 2 +``` +**Expected Outcome:** ``` -expected output + ____________________________________________________________ + Roger. Task has been removed: + [D][ ] do homework (by: Mar 14 2025) + You now have 2 tasks in the list. + ____________________________________________________________ ``` -## Feature ABC +## List all tasks: `list` +Lists all tasks in Volkov's task list. -// Feature details +**Format:** +`list` +**Expected Outcome:** +``` + ____________________________________________________________ + These are all the tasks in your list: + 1.[T][ ] buy groceries + 2.[E][ ] open house (from: Feb 16 2025 to: Feb 18 2025) + ____________________________________________________________ +``` +## Find a task: `find` +Finds the tasks in Volkov's task list that match the query -## Feature XYZ +**Format:** +`find SEARCHTERM` +**Examples:** +``` +find groceries +``` +**Expected Outcome:** +``` + ____________________________________________________________ + These are the tasks that match you search query: + 1.[T][ ] buy groceries + ____________________________________________________________ +``` + +## Exit Program: `bye` +Saves the task list on the hard disk and closes the program -// Feature details \ No newline at end of file +**Format:** +`bye` +**Expected Outcome:** +``` + ____________________________________________________________ + See you again soon! Service terminated. + ____________________________________________________________ +``` diff --git a/src/main/java/ByeCommand.java b/src/main/java/ByeCommand.java index 256e71ebf..1498397ce 100644 --- a/src/main/java/ByeCommand.java +++ b/src/main/java/ByeCommand.java @@ -11,7 +11,7 @@ public class ByeCommand extends Commands { * @param storage The {@code Storage} for file operations. */ public void execute(TaskList tasks, Ui ui, Storage storage) { - new Ui().formatResponse(" Bye. Hope to see you again soon!"); + new Ui().formatResponse(" See you again soon! Service terminated."); } /** diff --git a/src/main/java/DeleteCommand.java b/src/main/java/DeleteCommand.java index e70b7ca81..51509ebcb 100644 --- a/src/main/java/DeleteCommand.java +++ b/src/main/java/DeleteCommand.java @@ -19,9 +19,9 @@ public class DeleteCommand extends Commands { */ public void execute(TaskList tasks, Ui ui, Storage storage) { try { - String reply = " Noted. I've removed this task::\n" - + " " + tasks.getTask(taskNo).toString() - + " Now you have " + (tasks.size()-1) + " tasks in the list."; + String reply = " Roger. Task has been removed:\n" + + " " + tasks.getTask(taskNo).toString() + "\n" + + " You now have " + (tasks.size()-1) + " tasks in the list."; ui.formatResponse(reply); tasks.removeTask(taskNo); } catch (NullPointerException | IndexOutOfBoundsException e) { diff --git a/src/main/java/FindCommand.java b/src/main/java/FindCommand.java index e88d74926..a4657e8e7 100644 --- a/src/main/java/FindCommand.java +++ b/src/main/java/FindCommand.java @@ -20,7 +20,7 @@ public class FindCommand extends Commands { */ public void execute(TaskList tasks, Ui ui, Storage storage) { StringBuilder sb = new StringBuilder(); - sb.append(" Here are the matching tasks in your list:"); + sb.append(" These are the tasks that match you search query:"); int count = 1; for (int i = 0; i < tasks.size(); i++) { if (tasks.getTask(i).find(searchTerm)) { diff --git a/src/main/java/ListCommand.java b/src/main/java/ListCommand.java index 9a18ffd50..b5abb0a3a 100644 --- a/src/main/java/ListCommand.java +++ b/src/main/java/ListCommand.java @@ -14,7 +14,7 @@ public class ListCommand extends Commands { */ public void execute(TaskList tasks, Ui ui, Storage storage) { StringBuilder sb = new StringBuilder(); - sb.append(" Here are the tasks in your list:"); + sb.append(" These are all the tasks in your list:"); for (int i = 0; i < tasks.size(); i++) { sb.append("\n ").append(i + 1).append(".").append(tasks.getTask(i)); } diff --git a/src/main/java/MarkCommand.java b/src/main/java/MarkCommand.java index f82f7ac64..2f32d0e11 100644 --- a/src/main/java/MarkCommand.java +++ b/src/main/java/MarkCommand.java @@ -23,7 +23,7 @@ public class MarkCommand extends Commands { public void execute(TaskList tasks, Ui ui, Storage storage) { try { tasks.getTask(taskNo).markAsDone(); - String reply = " Nice! I've marked this task as done:\n" + String reply = " Roger. This task has been marked as done:\n" + " " + tasks.getTask(taskNo).toString(); ui.formatResponse(reply); } catch (NullPointerException | IndexOutOfBoundsException e) { diff --git a/src/main/java/Ui.java b/src/main/java/Ui.java index daa8fbd41..507ca6b6a 100644 --- a/src/main/java/Ui.java +++ b/src/main/java/Ui.java @@ -8,7 +8,7 @@ public class Ui { private Scanner sc = new Scanner(System.in); private final String newUserOpening = " ____________________________________________________________\n" - + " Hello! I'm Volkov\n" + + " Greetings user. I'm Volkov, your task manager\n" + " What can I do for you?\n" + " ____________________________________________________________\n"; @@ -45,9 +45,9 @@ public String formatResponseString(String msg) { * @param tasks The task list that the task is added to. */ public void formatTaskMsg(Task t, TaskList tasks) { - String msg = " Got it. I've added this task:\n" + String msg = " Roger. Task has been added to the list:\n" + " " + t.toString() + "\n" - + " Now you have " + tasks.size() + " tasks in the list."; + + " You now have " + tasks.size() + " tasks in the list."; System.out.println(formatResponseString(msg)); } diff --git a/src/main/java/UnmarkCommand.java b/src/main/java/UnmarkCommand.java index ad22ab090..cfd3c6d55 100644 --- a/src/main/java/UnmarkCommand.java +++ b/src/main/java/UnmarkCommand.java @@ -23,7 +23,7 @@ public class UnmarkCommand extends Commands { public void execute(TaskList tasks, Ui ui, Storage storage) { try { tasks.getTask(taskNo).unmarkAsDone(); - String reply = " OK, I've marked this task as not done yet:\n" + String reply = " Roger. This task has been marked as not done yet:\n" + " " + tasks.getTask(taskNo).toString(); ui.formatResponse(reply); } catch (NullPointerException | IndexOutOfBoundsException e) { From 3f539fc5767ff9c9fbfb638d43776f5095dafc1e Mon Sep 17 00:00:00 2001 From: JinbaoAlex Date: Fri, 14 Mar 2025 22:04:25 +0800 Subject: [PATCH 20/21] added summary table for the user guide --- docs/README.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 19d39cd3f..6c0693b6d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,7 +1,7 @@ # Volkov User Guide Volkov is a command-line task manager that allows you to add 3 different types of tasks, -set their relevant dates, and track your progress with simple commands. +set their relevant dates, and track your progress with simple commands. Your tasks are saved automatically, allowing you to revisit whenever you need to. ## Adding a Todo Task: `todo` @@ -153,3 +153,17 @@ Saves the task list on the hard disk and closes the program See you again soon! Service terminated. ____________________________________________________________ ``` + +### Command Summary + +| Action | Format and Examples | +|--------------|--------------------------------------------------------------------------------------------------------------| +| **Todo** | `todo DESCRIPTION`
e.g., `todo buy groceries` | +| **Deadline** | `deadline DESCRIPTION /by DATE`
e.g., `deadline do homework /by 2025-03-14` | +| **Event** | `event DESCRIPTION /from STARTDATE /to ENDDATE`
e.g., `event open house /from 2025-02-16 /to 2025-02-18` | +| **Mark** | `mark TASKNO`
e.g., `mark 1` | +| **Unmark** | `unmark TASKNO`
e.g., `unmark 1` | +| **Delete** | `delete TASKNO`
e.g., `delete 1` | +| **List** | `list` | +| **Find** | `find SEARCHTERM`
e.g., `find groceries` | +| **Bye** | `bye` | From 1bcf83b5f1c90c7670c8d7e6d50383c01734673a Mon Sep 17 00:00:00 2001 From: JinbaoAlex Date: Fri, 14 Mar 2025 22:07:39 +0800 Subject: [PATCH 21/21] add A-UserGuide tag --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 6c0693b6d..58563f389 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,7 +1,7 @@ # Volkov User Guide Volkov is a command-line task manager that allows you to add 3 different types of tasks, -set their relevant dates, and track your progress with simple commands. +set their relevant dates, and track your progress on the tasks with simple commands. Your tasks are saved automatically, allowing you to revisit whenever you need to. ## Adding a Todo Task: `todo`