From 64320255bcf8f8546f440ddfc1a42811fbe6034b Mon Sep 17 00:00:00 2001 From: Incy <85068563+IncyBot@users.noreply.github.com> Date: Thu, 25 Jan 2024 20:52:47 +0800 Subject: [PATCH 01/16] Updated Name and added initial skeleton --- .vscode/settings.json | 3 +++ src/main/java/Duke.java | 10 ---------- src/main/java/Incy.java | 17 +++++++++++++++++ 3 files changed, 20 insertions(+), 10 deletions(-) create mode 100644 .vscode/settings.json delete mode 100644 src/main/java/Duke.java create mode 100644 src/main/java/Incy.java diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..c995aa5ce --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "java.debug.settings.onBuildFailureProceed": true +} \ No newline at end of file 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/Incy.java b/src/main/java/Incy.java new file mode 100644 index 000000000..548f1e92c --- /dev/null +++ b/src/main/java/Incy.java @@ -0,0 +1,17 @@ +public class Incy { + public static void main(String[] args) { + String logo = " ____ _ _ ___ _ _ \n" + + "(_ _)( \\( )/ __)( \\/ )\n" + + " _)(_ ) (( (__ \\ / \n" + + "(____)(_)\\_)\\___) (__) \n"; + + System.out.println("____________________________________________________________\n" + + "Hello! I'm\n" + logo + + "What can I do for you?\n" + + "____________________________________________________________" + ); + + System.out.println("Bye. Hope to see you again soon!" + + "\n____________________________________________________________"); + } +} From 6a1c87df7f0e43cd5ee09dc8496dcc1f54c1e784 Mon Sep 17 00:00:00 2001 From: Incy <85068563+IncyBot@users.noreply.github.com> Date: Thu, 1 Feb 2024 20:04:32 +0800 Subject: [PATCH 02/16] Added Echo --- src/main/java/Incy.java | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/main/java/Incy.java b/src/main/java/Incy.java index 548f1e92c..b97df19c3 100644 --- a/src/main/java/Incy.java +++ b/src/main/java/Incy.java @@ -1,9 +1,13 @@ +import java.util.Scanner; + public class Incy { public static void main(String[] args) { + Scanner scanner = new Scanner(System.in); + String input; String logo = " ____ _ _ ___ _ _ \n" - + "(_ _)( \\( )/ __)( \\/ )\n" - + " _)(_ ) (( (__ \\ / \n" - + "(____)(_)\\_)\\___) (__) \n"; + + "(_ _)( \\( )/ __)( \\/ )\n" + + " _)(_ ) (( (__ \\ / \n" + + "(____)(_)\\_)\\___) (__) \n"; System.out.println("____________________________________________________________\n" + "Hello! I'm\n" + logo @@ -11,7 +15,21 @@ public static void main(String[] args) { + "____________________________________________________________" ); - System.out.println("Bye. Hope to see you again soon!" - + "\n____________________________________________________________"); + while (true) { + input = scanner.nextLine(); + if (input.equals("bye")) { + break; + } + System.out.println("____________________________________________________________\n" + + input + + "\n____________________________________________________________" + ); + } + + System.out.println("____________________________________________________________\n" + + "Bye. Hope to see you again soon!" + + "\n____________________________________________________________" + ); + scanner.close(); } } From 91f8700c1c0eb2c9a479076e6dd879544d204810 Mon Sep 17 00:00:00 2001 From: Incy <85068563+IncyBot@users.noreply.github.com> Date: Thu, 1 Feb 2024 20:22:29 +0800 Subject: [PATCH 03/16] Level-2 Added Personality and the ability to store whatever text entered by the user and display them back to the user when requested. --- src/main/java/Incy.java | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/src/main/java/Incy.java b/src/main/java/Incy.java index b97df19c3..9a2dfbaaa 100644 --- a/src/main/java/Incy.java +++ b/src/main/java/Incy.java @@ -4,32 +4,54 @@ public class Incy { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); String input; + String[] tasks = new String[100]; + int taskCount = 0; String logo = " ____ _ _ ___ _ _ \n" + "(_ _)( \\( )/ __)( \\/ )\n" + " _)(_ ) (( (__ \\ / \n" + "(____)(_)\\_)\\___) (__) \n"; System.out.println("____________________________________________________________\n" - + "Hello! I'm\n" + logo - + "What can I do for you?\n" + + "Oi bruv! I'm\n" + logo + + "Wotcha need from me today?\n" + "____________________________________________________________" ); while (true) { input = scanner.nextLine(); - if (input.equals("bye")) { + if (input.equalsIgnoreCase("bye")) { break; + } else if (input.equalsIgnoreCase("list")) { + System.out.println("____________________________________________________________"); + if (taskCount == 0) { + System.out.println("Blimey, your list is empty, innit?"); + } else { + for (int i = 0; i < taskCount; i++) { + System.out.println((i + 1) + ". " + tasks[i]); + } + } + System.out.println("____________________________________________________________"); + } else { + if (taskCount >= tasks.length) { + System.out.println("____________________________________________________________\n" + + "Cor blimey! The list is full to the brim. Can't add more, sorry!" + + "\n____________________________________________________________" + ); + } else { + tasks[taskCount] = input; + taskCount++; + System.out.println("____________________________________________________________\n" + + "Sorted! Added: " + input + + "\n____________________________________________________________" + ); + } } - System.out.println("____________________________________________________________\n" - + input - + "\n____________________________________________________________" - ); } System.out.println("____________________________________________________________\n" - + "Bye. Hope to see you again soon!" + + "Cya later mate!" + "\n____________________________________________________________" ); scanner.close(); } -} +} \ No newline at end of file From b4c4501c5bbdff040bf61d95cf5f4bfab5bb0c36 Mon Sep 17 00:00:00 2001 From: Incy <85068563+IncyBot@users.noreply.github.com> Date: Thu, 1 Feb 2024 20:44:40 +0800 Subject: [PATCH 04/16] Level 3 Added the ability to mark tasks as done and the ability to change the status back to not done. --- src/main/java/Incy.java | 32 ++++++++++++++++++++++++++------ src/main/java/Task.java | 26 ++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 6 deletions(-) create mode 100644 src/main/java/Task.java diff --git a/src/main/java/Incy.java b/src/main/java/Incy.java index 9a2dfbaaa..b3c0e1478 100644 --- a/src/main/java/Incy.java +++ b/src/main/java/Incy.java @@ -4,19 +4,19 @@ public class Incy { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); String input; - String[] tasks = new String[100]; + Task[] tasks = new Task[100]; int taskCount = 0; String logo = " ____ _ _ ___ _ _ \n" + "(_ _)( \\( )/ __)( \\/ )\n" + " _)(_ ) (( (__ \\ / \n" + "(____)(_)\\_)\\___) (__) \n"; - + System.out.println("____________________________________________________________\n" + "Oi bruv! I'm\n" + logo + "Wotcha need from me today?\n" + "____________________________________________________________" ); - + while (true) { input = scanner.nextLine(); if (input.equalsIgnoreCase("bye")) { @@ -31,6 +31,26 @@ public static void main(String[] args) { } } System.out.println("____________________________________________________________"); + } else if (input.startsWith("mark ")) { + int index = Integer.parseInt(input.substring(5)) - 1; + if (index >= 0 && index < taskCount) { + tasks[index].markAsDone(); + System.out.println("____________________________________________________________\n" + + "Buzzin'! This one's sorted now:\n " + + tasks[index] + + "\n____________________________________________________________" + ); + } + } else if (input.startsWith("unmark ")) { + int index = Integer.parseInt(input.substring(7)) - 1; + if (index >= 0 && index < taskCount) { + tasks[index].markAsNotDone(); + System.out.println("____________________________________________________________\n" + + "No prob, flipped it back to not done, innit:\n " + + tasks[index] + + "\n____________________________________________________________" + ); + } } else { if (taskCount >= tasks.length) { System.out.println("____________________________________________________________\n" @@ -38,7 +58,7 @@ public static void main(String[] args) { + "\n____________________________________________________________" ); } else { - tasks[taskCount] = input; + tasks[taskCount] = new Task(input); taskCount++; System.out.println("____________________________________________________________\n" + "Sorted! Added: " + input @@ -47,11 +67,11 @@ public static void main(String[] args) { } } } - + System.out.println("____________________________________________________________\n" + "Cya later mate!" + "\n____________________________________________________________" ); scanner.close(); } -} \ No newline at end of file +} diff --git a/src/main/java/Task.java b/src/main/java/Task.java new file mode 100644 index 000000000..fd0e80ff8 --- /dev/null +++ b/src/main/java/Task.java @@ -0,0 +1,26 @@ +public class Task { + protected String description; + protected boolean isDone; + + public Task(String description) { + this.description = description; + this.isDone = false; + } + + public String getStatusIcon() { + return (isDone ? "[X]" : "[ ]"); + } + + public void markAsDone() { + isDone = true; + } + + public void markAsNotDone() { + isDone = false; + } + + @Override + public String toString() { + return getStatusIcon() + " " + description; + } +} From 2a071bc2051231dc2f4ad5fadb71d2c1d1ef1522 Mon Sep 17 00:00:00 2001 From: Incy <85068563+IncyBot@users.noreply.github.com> Date: Sat, 2 Mar 2024 13:18:28 +0800 Subject: [PATCH 05/16] New Logo complying with coding standard --- src/main/java/Incy.java | 137 +++++++++++++++++++-------------- src/main/java/build/Incy.class | Bin 0 -> 3241 bytes src/main/java/build/Task.class | Bin 0 -> 1138 bytes 3 files changed, 81 insertions(+), 56 deletions(-) create mode 100644 src/main/java/build/Incy.class create mode 100644 src/main/java/build/Task.class diff --git a/src/main/java/Incy.java b/src/main/java/Incy.java index b3c0e1478..3ac94e116 100644 --- a/src/main/java/Incy.java +++ b/src/main/java/Incy.java @@ -1,77 +1,102 @@ import java.util.Scanner; public class Incy { + public static final String ANSI_RESET = "\u001B[0m"; + public static final String ANSI_BLACK = "\u001B[30m"; + public static final String ANSI_RED = "\u001B[31m"; + public static final String ANSI_GREEN = "\u001B[32m"; + public static final String ANSI_YELLOW = "\u001B[33m"; + public static final String ANSI_BLUE = "\u001B[34m"; + public static final String ANSI_PURPLE = "\u001B[35m"; + public static final String ANSI_CYAN = "\u001B[36m"; + public static final String ANSI_WHITE = "\u001B[37m"; + + public static final String ANSI_BLACK_BACKGROUND = "\u001B[40m"; + public static final String ANSI_RED_BACKGROUND = "\u001B[41m"; + public static final String ANSI_GREEN_BACKGROUND = "\u001B[42m"; + public static final String ANSI_YELLOW_BACKGROUND = "\u001B[43m"; + public static final String ANSI_BLUE_BACKGROUND = "\u001B[44m"; + public static final String ANSI_PURPLE_BACKGROUND = "\u001B[45m"; + public static final String ANSI_CYAN_BACKGROUND = "\u001B[46m"; + public static final String ANSI_WHITE_BACKGROUND = "\u001B[47m"; + + public static final String LINE_STRING_TOP = ANSI_GREEN + "____________________________________________________________\n\n" ; + public static final String LINE_STRING_BOTTOM = ANSI_GREEN + "____________________________________________________________\n" + ANSI_BLUE ; + + public static void main(String[] args) { Scanner scanner = new Scanner(System.in); String input; Task[] tasks = new Task[100]; int taskCount = 0; - String logo = " ____ _ _ ___ _ _ \n" - + "(_ _)( \\( )/ __)( \\/ )\n" - + " _)(_ ) (( (__ \\ / \n" - + "(____)(_)\\_)\\___) (__) \n"; + String logo = " ▄▄ ▄▄▀▀ \n" + // + " ▄▄▀ ▄▀▀▀▀▀▀▀▀▀ \n" + // + " ▄▀▀▀ ▄▀▀▀▀▀▀▀▀▀ ▄\n" + // + " ▀▀▀▀▄ ▄▀▀▀▀▀▀▀▀ ▄▀▄▀▀\n" + // + " ▀▀▀▀▀▀▀▀▀▀▀ ▄▀▀▀▀ \n" + // + " ▀▀▀▀▀▀▀▀▀▀▀▀▀▄ ▄▀▀▀▄▀▀▀▀ \n" + // + " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▄▀▀▀▀▀▀▀ \n" + // + " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ▀▀▀ \n" + // + " ▄▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ \n" + // + " ▄▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▄▄▀▀▀▄▄ \n" + // + "▀▀▀▀▀ ▀▀▀▀▀▀▀▀▄▄▀▀▀▀▀▀▀▀▀▀ \n" + // + " ▀▀▀ ▄▄▀▀▀▀▀▀▀▀▀▀▀▀▀▀ \n" + // + " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀ \n" + // + " ▀ ▀▀▀▀▀ ▀ \n" + // + "\n"; - System.out.println("____________________________________________________________\n" - + "Oi bruv! I'm\n" + logo - + "Wotcha need from me today?\n" - + "____________________________________________________________" - ); + System.out.println(LINE_STRING_TOP + ANSI_CYAN + "Oi bruv! I'm\n" + logo + ANSI_CYAN + "Wotcha need from me today?\n" + LINE_STRING_BOTTOM); while (true) { input = scanner.nextLine(); - if (input.equalsIgnoreCase("bye")) { + if ("bye".equalsIgnoreCase(input)) { break; - } else if (input.equalsIgnoreCase("list")) { - System.out.println("____________________________________________________________"); - if (taskCount == 0) { - System.out.println("Blimey, your list is empty, innit?"); - } else { - for (int i = 0; i < taskCount; i++) { - System.out.println((i + 1) + ". " + tasks[i]); - } - } - System.out.println("____________________________________________________________"); + } else if ("list".equalsIgnoreCase(input)) { + handleListCommand(tasks, taskCount); } else if (input.startsWith("mark ")) { - int index = Integer.parseInt(input.substring(5)) - 1; - if (index >= 0 && index < taskCount) { - tasks[index].markAsDone(); - System.out.println("____________________________________________________________\n" - + "Buzzin'! This one's sorted now:\n " - + tasks[index] - + "\n____________________________________________________________" - ); - } + handleMarkCommand(input, tasks, taskCount, true); } else if (input.startsWith("unmark ")) { - int index = Integer.parseInt(input.substring(7)) - 1; - if (index >= 0 && index < taskCount) { - tasks[index].markAsNotDone(); - System.out.println("____________________________________________________________\n" - + "No prob, flipped it back to not done, innit:\n " - + tasks[index] - + "\n____________________________________________________________" - ); - } + handleMarkCommand(input, tasks, taskCount, false); } else { - if (taskCount >= tasks.length) { - System.out.println("____________________________________________________________\n" - + "Cor blimey! The list is full to the brim. Can't add more, sorry!" - + "\n____________________________________________________________" - ); - } else { - tasks[taskCount] = new Task(input); - taskCount++; - System.out.println("____________________________________________________________\n" - + "Sorted! Added: " + input - + "\n____________________________________________________________" - ); - } + handleAddTask(input, tasks, taskCount); + taskCount++; } } - System.out.println("____________________________________________________________\n" - + "Cya later mate!" - + "\n____________________________________________________________" - ); + System.out.println(LINE_STRING_TOP + ANSI_CYAN + "Cya later mate!\n" + LINE_STRING_BOTTOM); scanner.close(); } -} + + private static void handleListCommand(Task[] tasks, int taskCount) { + System.out.println(LINE_STRING_BOTTOM); + if (taskCount == 0) { + System.out.println(ANSI_RED + "Blimey, your list is empty, innit?\n"); + } else { + for (int i = 0; i < taskCount; i++) { + System.out.println(ANSI_CYAN + (i + 1) + ". " + tasks[i]); + } + } + System.out.println(LINE_STRING_BOTTOM); + } + + private static void handleMarkCommand(String input, Task[] tasks, int taskCount, boolean markAsDone) { + int index = Integer.parseInt(input.substring(markAsDone ? 5 : 7)) - 1; + if (index >= 0 && index < taskCount) { + if (markAsDone) { + tasks[index].markAsDone(); + } else { + tasks[index].markAsNotDone(); + } + System.out.println(LINE_STRING_TOP + ANSI_CYAN + "Done with this one:\n " + tasks[index] + "\n" + LINE_STRING_BOTTOM); + } + } + + private static void handleAddTask(String input, Task[] tasks, int taskCount) { + if (taskCount >= tasks.length) { + System.out.println(LINE_STRING_TOP + ANSI_RED + "The list is full. Can't add more tasks!\n" + LINE_STRING_BOTTOM); + } else { + tasks[taskCount] = new Task(input); + System.out.println(LINE_STRING_TOP + ANSI_CYAN + "Task added: " + input + "\n" + LINE_STRING_BOTTOM); + } + } +} \ No newline at end of file diff --git a/src/main/java/build/Incy.class b/src/main/java/build/Incy.class new file mode 100644 index 0000000000000000000000000000000000000000..ad4875810112300f12e89b2d08e3065e78bd9a85 GIT binary patch literal 3241 zcmb_e&36-36#u<6&7{KsZ6HATe5EZ-ASDP|palvI0?~e;sjWa2Cdq3%bTSiWCWWB* z$wFOtjyuuAIm)I-SIVMr%8`Xj7ybio+_`h-#^a&hH%V)e$bvX$&Uzx(mt zPmdNJ0yu%2DgtOw5Y*6!5JU52eO6DJx;2#?$zB#Yk0Er#ung}QLqjY+rXbAF;xm;z z!%Sv!x@8Hc2`W}8&@`;Zn#Z(c%C0903<1Mphz|OahMi1X#gdot9HAHbR48bc`?oM` ziq&M18?R#sj_U4A7*U2x{31P^SKsBO8k3ZGj8DXPJV{J)ndEU*66sf*^H_|>B>x2G zNlyIq(69J}d}%3v#X#bv2+c6Do*2!g0zO0@bXfH`Kgh%JTWC4ie*uETtT1z z0eo6T1Vb8zWgV;1v=i=0+Y%9~@GW7yLdcY?s>KmxG>l5d)fL8J+pF+4NZxUVg=YShR3s%39`y8+v9n%y4ofG4|}gNd{URa86Unj zej=Y2`QAG5TN^@I#dW-;;BDE!Z!mQDXQtmd4Qtk(5y{GNTRE0b={e7KsLnoLd3078 zE17;qxALZNI|glgrc~^Evf5Tq9upib7ex*Bl|@+N463R~>86=6JV7<7rR9w(W$Lag zTm|njbUxuzEmIYIz_9)4taO{J_=PrHqH{q$0XqKZ?nh&mzP8cKXl~qn5A1tdFyv^I zzkvocArC=oVhyyDm_iK4A3!;G7ftu5Z8hhAKxDX~Cm31Z+jtinS{oOz8JNfRJ@e=o zNfu0d rpk*7S%#81zi2}`>oV!NpWBFszA02=6{BaiV5SL0E@8W%Yh}ORWMRS92 literal 0 HcmV?d00001 diff --git a/src/main/java/build/Task.class b/src/main/java/build/Task.class new file mode 100644 index 0000000000000000000000000000000000000000..78809b37120d6cdaa36635ce91ca58908d1267b7 GIT binary patch literal 1138 zcmaKr-%b-j6vn^PmTp_N6blIW2N40=MX3t@Noq{6hDZW`{(cFZvbm}nL!M33ke%TND@Ym#i=MY zgnwB2aBwVLO-R1>d{4h2#0$mUG*U=g$k-T$O-SsBuud4R$s&zIY+ zlLHy-h=T@4vRt!U-xAIC*}`0ptC1mu%!vr zUN-JB^Q}@k)PZPjNqwYhVG0g=NVAkn;!y^Vv23AaoOwc+zy2bgf2!)T6!9ao)`hE8 za7Osj-D^h}(ccTd){x=+rc(7*v)u1pSEMI#=d39Q$oIPR(V&&P-R~eOqS2^&T9yg+ zhVRRu(hy-NLklZ}g}$B!m1^NRVdno*p2?^$+~@I&@kGUtFayrJgc(|1hd_MY<@*eu zR#;(lIp-J1S-ODb#4nKj!6CvuzUMj7BqfkU8Wu(v%ma$44q%m6Y6H%Z{fbon#y1S* z$G&qY)&?ZokB2eK5eqSU&Enz+511E~FvmheNIHq0H=7@t3*&c>^7Hut`rb+-{TS=V zS-)^q;bMnB;{3#fa}Mhg(|{>3>M$yB3UMrQEQW_D@M^kT;;V?Ke9G|d8CLNE)BgYj C_5Cye literal 0 HcmV?d00001 From adc3fc798f9caf7f84813bdf32e244024fbc856f Mon Sep 17 00:00:00 2001 From: Incy <85068563+IncyBot@users.noreply.github.com> Date: Sat, 2 Mar 2024 15:47:58 +0800 Subject: [PATCH 06/16] Moved Constants for Cleaner look and level 4 --- src/main/java/Constants.java | 41 ++++++++++++++ src/main/java/Deadline.java | 13 +++++ src/main/java/Event.java | 15 +++++ src/main/java/Incy.java | 105 ++++++++++++++++++----------------- src/main/java/Task.java | 6 +- src/main/java/Todo.java | 10 ++++ 6 files changed, 136 insertions(+), 54 deletions(-) create mode 100644 src/main/java/Constants.java 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/Constants.java b/src/main/java/Constants.java new file mode 100644 index 000000000..20dae3d89 --- /dev/null +++ b/src/main/java/Constants.java @@ -0,0 +1,41 @@ +public class Constants { + public static final String ANSI_RESET = "\u001B[0m"; + public static final String ANSI_BLACK = "\u001B[30m"; + public static final String ANSI_RED = "\u001B[31m"; + public static final String ANSI_GREEN = "\u001B[32m"; + public static final String ANSI_YELLOW = "\u001B[33m"; + public static final String ANSI_BLUE = "\u001B[34m"; + public static final String ANSI_PURPLE = "\u001B[35m"; + public static final String ANSI_CYAN = "\u001B[36m"; + public static final String ANSI_WHITE = "\u001B[37m"; + + public static final String ANSI_BLACK_BACKGROUND = "\u001B[40m"; + public static final String ANSI_RED_BACKGROUND = "\u001B[41m"; + public static final String ANSI_GREEN_BACKGROUND = "\u001B[42m"; + public static final String ANSI_YELLOW_BACKGROUND = "\u001B[43m"; + public static final String ANSI_BLUE_BACKGROUND = "\u001B[44m"; + public static final String ANSI_PURPLE_BACKGROUND = "\u001B[45m"; + public static final String ANSI_CYAN_BACKGROUND = "\u001B[46m"; + public static final String ANSI_WHITE_BACKGROUND = "\u001B[47m"; + + public static final String LINE_STRING_TOP = ANSI_GREEN + "____________________________________________________________\n\n" ; + public static final String LINE_STRING_BOTTOM = ANSI_GREEN + "____________________________________________________________\n" + ANSI_BLUE ; + + public static final Integer MAX_TASKS = 100; + + public static final String LOGO = " ▄▄ ▄▄▀▀ \n" + // + " ▄▄▀ ▄▀▀▀▀▀▀▀▀▀ \n" + // + " ▄▀▀▀ ▄▀▀▀▀▀▀▀▀▀ ▄\n" + // + " ▀▀▀▀▄ ▄▀▀▀▀▀▀▀▀ ▄▀▄▀▀\n" + // + " ▀▀▀▀▀▀▀▀▀▀▀ ▄▀▀▀▀ \n" + // + " ▀▀▀▀▀▀▀▀▀▀▀▀▀▄ ▄▀▀▀▄▀▀▀▀ \n" + // + " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▄▀▀▀▀▀▀▀ \n" + // + " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ▀▀▀ \n" + // + " ▄▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ \n" + // + " ▄▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▄▄▀▀▀▄▄ \n" + // + "▀▀▀▀▀ ▀▀▀▀▀▀▀▀▄▄▀▀▀▀▀▀▀▀▀▀ \n" + // + " ▀▀▀ ▄▄▀▀▀▀▀▀▀▀▀▀▀▀▀▀ \n" + // + " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀ \n" + // + " ▀ ▀▀▀▀▀ ▀ \n" + // + "\n"; +} diff --git a/src/main/java/Deadline.java b/src/main/java/Deadline.java new file mode 100644 index 000000000..0ee665368 --- /dev/null +++ b/src/main/java/Deadline.java @@ -0,0 +1,13 @@ +public class Deadline extends Task { + private String by; + + public Deadline(String description, String by) { + super(description); + this.by = by; + } + + @Override + public String toString() { + return "[D]" + super.getStatusIcon() + " " + description + " (by: " + by + ")"; + } +} \ No newline at end of file diff --git a/src/main/java/Event.java b/src/main/java/Event.java new file mode 100644 index 000000000..ac4d239cf --- /dev/null +++ b/src/main/java/Event.java @@ -0,0 +1,15 @@ +public class Event extends Task { + private String start; + private String end; + + public Event(String description, String start, String end) { + super(description); + this.start = start; + this.end = end; + } + + @Override + public String toString() { + return "[E]" + super.getStatusIcon() + " " + description + " (from: " + start + " to: " + end + ")"; + } +} \ No newline at end of file diff --git a/src/main/java/Incy.java b/src/main/java/Incy.java index 3ac94e116..04ebb3ffa 100644 --- a/src/main/java/Incy.java +++ b/src/main/java/Incy.java @@ -1,51 +1,16 @@ import java.util.Scanner; public class Incy { - public static final String ANSI_RESET = "\u001B[0m"; - public static final String ANSI_BLACK = "\u001B[30m"; - public static final String ANSI_RED = "\u001B[31m"; - public static final String ANSI_GREEN = "\u001B[32m"; - public static final String ANSI_YELLOW = "\u001B[33m"; - public static final String ANSI_BLUE = "\u001B[34m"; - public static final String ANSI_PURPLE = "\u001B[35m"; - public static final String ANSI_CYAN = "\u001B[36m"; - public static final String ANSI_WHITE = "\u001B[37m"; - public static final String ANSI_BLACK_BACKGROUND = "\u001B[40m"; - public static final String ANSI_RED_BACKGROUND = "\u001B[41m"; - public static final String ANSI_GREEN_BACKGROUND = "\u001B[42m"; - public static final String ANSI_YELLOW_BACKGROUND = "\u001B[43m"; - public static final String ANSI_BLUE_BACKGROUND = "\u001B[44m"; - public static final String ANSI_PURPLE_BACKGROUND = "\u001B[45m"; - public static final String ANSI_CYAN_BACKGROUND = "\u001B[46m"; - public static final String ANSI_WHITE_BACKGROUND = "\u001B[47m"; - - public static final String LINE_STRING_TOP = ANSI_GREEN + "____________________________________________________________\n\n" ; - public static final String LINE_STRING_BOTTOM = ANSI_GREEN + "____________________________________________________________\n" + ANSI_BLUE ; public static void main(String[] args) { Scanner scanner = new Scanner(System.in); String input; - Task[] tasks = new Task[100]; + Task[] tasks = new Task[Constants.MAX_TASKS]; int taskCount = 0; - String logo = " ▄▄ ▄▄▀▀ \n" + // - " ▄▄▀ ▄▀▀▀▀▀▀▀▀▀ \n" + // - " ▄▀▀▀ ▄▀▀▀▀▀▀▀▀▀ ▄\n" + // - " ▀▀▀▀▄ ▄▀▀▀▀▀▀▀▀ ▄▀▄▀▀\n" + // - " ▀▀▀▀▀▀▀▀▀▀▀ ▄▀▀▀▀ \n" + // - " ▀▀▀▀▀▀▀▀▀▀▀▀▀▄ ▄▀▀▀▄▀▀▀▀ \n" + // - " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▄▀▀▀▀▀▀▀ \n" + // - " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ▀▀▀ \n" + // - " ▄▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ \n" + // - " ▄▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▄▄▀▀▀▄▄ \n" + // - "▀▀▀▀▀ ▀▀▀▀▀▀▀▀▄▄▀▀▀▀▀▀▀▀▀▀ \n" + // - " ▀▀▀ ▄▄▀▀▀▀▀▀▀▀▀▀▀▀▀▀ \n" + // - " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀ \n" + // - " ▀ ▀▀▀▀▀ ▀ \n" + // - "\n"; - System.out.println(LINE_STRING_TOP + ANSI_CYAN + "Oi bruv! I'm\n" + logo + ANSI_CYAN + "Wotcha need from me today?\n" + LINE_STRING_BOTTOM); + System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_CYAN + "Oi bruv! I'm\n" + Constants.LOGO + Constants.ANSI_CYAN + "Wotcha need from me today?\n" + Constants.LINE_STRING_BOTTOM); while (true) { input = scanner.nextLine(); @@ -58,25 +23,24 @@ public static void main(String[] args) { } else if (input.startsWith("unmark ")) { handleMarkCommand(input, tasks, taskCount, false); } else { - handleAddTask(input, tasks, taskCount); - taskCount++; + taskCount = handleAddTask(input, tasks, taskCount); } } - System.out.println(LINE_STRING_TOP + ANSI_CYAN + "Cya later mate!\n" + LINE_STRING_BOTTOM); + System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_CYAN + "Cya later mate!\n" + Constants.LINE_STRING_BOTTOM); scanner.close(); } private static void handleListCommand(Task[] tasks, int taskCount) { - System.out.println(LINE_STRING_BOTTOM); + System.out.println(Constants.LINE_STRING_BOTTOM); if (taskCount == 0) { - System.out.println(ANSI_RED + "Blimey, your list is empty, innit?\n"); + System.out.println(Constants.ANSI_RED + "Blimey, your list is empty, innit?"); } else { for (int i = 0; i < taskCount; i++) { - System.out.println(ANSI_CYAN + (i + 1) + ". " + tasks[i]); + System.out.println(Constants.ANSI_CYAN + (i + 1) + ". " + tasks[i]); } } - System.out.println(LINE_STRING_BOTTOM); + System.out.println(Constants.LINE_STRING_BOTTOM); } private static void handleMarkCommand(String input, Task[] tasks, int taskCount, boolean markAsDone) { @@ -87,16 +51,57 @@ private static void handleMarkCommand(String input, Task[] tasks, int taskCount, } else { tasks[index].markAsNotDone(); } - System.out.println(LINE_STRING_TOP + ANSI_CYAN + "Done with this one:\n " + tasks[index] + "\n" + LINE_STRING_BOTTOM); + System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_CYAN + "Done with this one:\n " + tasks[index] + "\n" + Constants.LINE_STRING_BOTTOM); } } - private static void handleAddTask(String input, Task[] tasks, int taskCount) { + private static int handleAddTask(String input, Task[] tasks, int taskCount) { + String[] parts = input.split(" ", 2); + String command = parts[0]; + String taskInfo = parts.length > 1 ? parts[1] : ""; + if (taskCount >= tasks.length) { - System.out.println(LINE_STRING_TOP + ANSI_RED + "The list is full. Can't add more tasks!\n" + LINE_STRING_BOTTOM); - } else { - tasks[taskCount] = new Task(input); - System.out.println(LINE_STRING_TOP + ANSI_CYAN + "Task added: " + input + "\n" + LINE_STRING_BOTTOM); + System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_RED + "The list is full. Can't add more tasks!\n" + Constants.LINE_STRING_BOTTOM); + return taskCount; + } + + Task newTask = null; + + switch (command.toLowerCase()) { + case "todo": + newTask = new Todo(taskInfo); + break; + case "deadline": + String[] deadlineParts = taskInfo.split(" /by ", 2); + if (deadlineParts.length < 2) { + System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_RED + "Error: Invalid deadline format. Please use 'deadline [task] /by [date/time]'.\n" + Constants.LINE_STRING_BOTTOM); + return taskCount; + } + newTask = new Deadline(deadlineParts[0], deadlineParts[1]); + break; + case "event": + String[] eventParts = taskInfo.split(" /from ", 2); + String[] eventTime = eventParts.length > 1 ? eventParts[1].split(" /to ", 2) : new String[0]; + if (eventParts.length < 2 || eventTime.length < 2) { + System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_RED + "Error: Invalid event format. Please use 'event [task] /from [start time] /to [end time]'.\n" + Constants.LINE_STRING_BOTTOM); + return taskCount; + } + newTask = new Event(eventParts[0], eventTime[0], eventTime[1]); + break; + default: + newTask = new Todo(input); + } + + if (newTask != null) { + tasks[taskCount] = newTask; + System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_CYAN + "Sorted! Your task's in the bag, innit mate:\n" + + " " + newTask + "\n" + + "You're now juggling " + (taskCount + 1) + " tasks on your list, innit.\n" + + Constants.LINE_STRING_BOTTOM); + + return taskCount + 1; } + return taskCount; } + } \ No newline at end of file diff --git a/src/main/java/Task.java b/src/main/java/Task.java index fd0e80ff8..79bec595a 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -1,4 +1,4 @@ -public class Task { +public abstract class Task { protected String description; protected boolean isDone; @@ -20,7 +20,5 @@ public void markAsNotDone() { } @Override - public String toString() { - return getStatusIcon() + " " + description; - } + public abstract String toString(); } diff --git a/src/main/java/Todo.java b/src/main/java/Todo.java new file mode 100644 index 000000000..7c58cc21f --- /dev/null +++ b/src/main/java/Todo.java @@ -0,0 +1,10 @@ +public class Todo extends Task { + public Todo(String description) { + super(description); + } + + @Override + public String toString() { + return "[T]" + super.getStatusIcon() + " " + description; + } +} \ No newline at end of file From 0ade6124bb4ba1b3a4319c800ee4d69ebc0dbaeb Mon Sep 17 00:00:00 2001 From: Incy <85068563+IncyBot@users.noreply.github.com> Date: Sat, 2 Mar 2024 17:55:31 +0800 Subject: [PATCH 07/16] A-CodeQuality --- src/main/java/Incy.java | 157 ++++++++++++++++++++++++---------------- src/main/java/Task.java | 12 +-- 2 files changed, 98 insertions(+), 71 deletions(-) diff --git a/src/main/java/Incy.java b/src/main/java/Incy.java index 04ebb3ffa..2463925a7 100644 --- a/src/main/java/Incy.java +++ b/src/main/java/Incy.java @@ -2,36 +2,53 @@ public class Incy { - - public static void main(String[] args) { Scanner scanner = new Scanner(System.in); - String input; - Task[] tasks = new Task[Constants.MAX_TASKS]; - int taskCount = 0; + TaskManager taskManager = new TaskManager(); - System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_CYAN + "Oi bruv! I'm\n" + Constants.LOGO + Constants.ANSI_CYAN + "Wotcha need from me today?\n" + Constants.LINE_STRING_BOTTOM); + printWelcomeMessage(); while (true) { - input = scanner.nextLine(); + String input = scanner.nextLine(); if ("bye".equalsIgnoreCase(input)) { break; - } else if ("list".equalsIgnoreCase(input)) { - handleListCommand(tasks, taskCount); - } else if (input.startsWith("mark ")) { - handleMarkCommand(input, tasks, taskCount, true); - } else if (input.startsWith("unmark ")) { - handleMarkCommand(input, tasks, taskCount, false); - } else { - taskCount = handleAddTask(input, tasks, taskCount); } + processInput(input, taskManager); } - System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_CYAN + "Cya later mate!\n" + Constants.LINE_STRING_BOTTOM); + printGoodbyeMessage(); scanner.close(); } - private static void handleListCommand(Task[] tasks, int taskCount) { + private static void printWelcomeMessage() { + System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_CYAN + + "Oi bruv! I'm\n" + Constants.LOGO + + "Wotcha need from me today?\n" + Constants.LINE_STRING_BOTTOM); + } + + private static void printGoodbyeMessage() { + System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_CYAN + + "Cya later mate!\n" + Constants.LINE_STRING_BOTTOM); + } + + private static void processInput(String input, TaskManager taskManager) { + if ("list".equalsIgnoreCase(input)) { + taskManager.handleListCommand(); + } else if (input.startsWith("mark ")) { + taskManager.handleMarkCommand(input, true); + } else if (input.startsWith("unmark ")) { + taskManager.handleMarkCommand(input, false); + } else { + taskManager.handleAddTask(input); + } + } +} + +class TaskManager { + private Task[] tasks = new Task[Constants.MAX_TASKS]; + private int taskCount = 0; + + void handleListCommand() { System.out.println(Constants.LINE_STRING_BOTTOM); if (taskCount == 0) { System.out.println(Constants.ANSI_RED + "Blimey, your list is empty, innit?"); @@ -43,65 +60,79 @@ private static void handleListCommand(Task[] tasks, int taskCount) { System.out.println(Constants.LINE_STRING_BOTTOM); } - private static void handleMarkCommand(String input, Task[] tasks, int taskCount, boolean markAsDone) { + void handleMarkCommand(String input, boolean markAsDone) { int index = Integer.parseInt(input.substring(markAsDone ? 5 : 7)) - 1; - if (index >= 0 && index < taskCount) { - if (markAsDone) { - tasks[index].markAsDone(); - } else { - tasks[index].markAsNotDone(); - } - System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_CYAN + "Done with this one:\n " + tasks[index] + "\n" + Constants.LINE_STRING_BOTTOM); + if (isValidIndex(index)) { + tasks[index].setDone(markAsDone); + System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_CYAN + "Smashed it, this one's sorted!:\n " + tasks[index] + "\n" + Constants.LINE_STRING_BOTTOM); + } + } + + private boolean isValidIndex(int index) { + return index >= 0 && index < taskCount; + } + + void handleAddTask(String input) { + if (taskCount >= tasks.length) { + System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_RED + "The list chocked a block, mate. Can't shove more stuff in it!\n" + Constants.LINE_STRING_BOTTOM); + return; + } + + Task newTask = TaskFactory.createTask(input); + if (newTask != null) { + tasks[taskCount++] = newTask; + printTaskAddedMessage(newTask); } } - private static int handleAddTask(String input, Task[] tasks, int taskCount) { + private void printTaskAddedMessage(Task task) { + System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_CYAN + + "Sorted! Your task's in the bag, innit mate:\n" + + " " + task + "\n" + + "You're now juggling " + taskCount + " tasks on your list, innit.\n" + + Constants.LINE_STRING_BOTTOM); + } +} + +class TaskFactory { + static Task createTask(String input) { String[] parts = input.split(" ", 2); String command = parts[0]; String taskInfo = parts.length > 1 ? parts[1] : ""; - - if (taskCount >= tasks.length) { - System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_RED + "The list is full. Can't add more tasks!\n" + Constants.LINE_STRING_BOTTOM); - return taskCount; - } - - Task newTask = null; - + switch (command.toLowerCase()) { case "todo": - newTask = new Todo(taskInfo); - break; + return new Todo(taskInfo); case "deadline": - String[] deadlineParts = taskInfo.split(" /by ", 2); - if (deadlineParts.length < 2) { - System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_RED + "Error: Invalid deadline format. Please use 'deadline [task] /by [date/time]'.\n" + Constants.LINE_STRING_BOTTOM); - return taskCount; - } - newTask = new Deadline(deadlineParts[0], deadlineParts[1]); - break; + return createDeadline(taskInfo); case "event": - String[] eventParts = taskInfo.split(" /from ", 2); - String[] eventTime = eventParts.length > 1 ? eventParts[1].split(" /to ", 2) : new String[0]; - if (eventParts.length < 2 || eventTime.length < 2) { - System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_RED + "Error: Invalid event format. Please use 'event [task] /from [start time] /to [end time]'.\n" + Constants.LINE_STRING_BOTTOM); - return taskCount; - } - newTask = new Event(eventParts[0], eventTime[0], eventTime[1]); - break; + return createEvent(taskInfo); default: - newTask = new Todo(input); + return new Todo(input); } - - if (newTask != null) { - tasks[taskCount] = newTask; - System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_CYAN + "Sorted! Your task's in the bag, innit mate:\n" - + " " + newTask + "\n" - + "You're now juggling " + (taskCount + 1) + " tasks on your list, innit.\n" - + Constants.LINE_STRING_BOTTOM); - - return taskCount + 1; + } + + private static Task createDeadline(String taskInfo) { + String[] deadlineParts = taskInfo.split(" /by ", 2); + if (deadlineParts.length < 2) { + printFormatError("You've mucked up the deadline format. Do it like 'deadline [task] /by [date/time]', yeah?"); + return null; } - return taskCount; + return new Deadline(deadlineParts[0], deadlineParts[1]); + } + + private static Task createEvent(String taskInfo) { + String[] eventParts = taskInfo.split(" /from ", 2); + String[] eventTime = eventParts.length > 1 ? eventParts[1].split(" /to ", 2) : new String[0]; + if (eventParts.length < 2 || eventTime.length < 2) { + printFormatError("You've bungled the event format. It's gotta be 'event [task] /from [start time] /to [end time]', innit?"); + return null; + } + return new Event(eventParts[0], eventTime[0], eventTime[1]); + } + + private static void printFormatError(String errorMessage) { + System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_RED + "Error: " + errorMessage + "\n" + + Constants.LINE_STRING_BOTTOM); } - } \ No newline at end of file diff --git a/src/main/java/Task.java b/src/main/java/Task.java index 79bec595a..744507afc 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -2,21 +2,17 @@ public abstract class Task { protected String description; protected boolean isDone; - public Task(String description) { + Task(String description) { this.description = description; this.isDone = false; } - public String getStatusIcon() { + String getStatusIcon() { return (isDone ? "[X]" : "[ ]"); } - public void markAsDone() { - isDone = true; - } - - public void markAsNotDone() { - isDone = false; + public void setDone(boolean done) { + isDone = done; } @Override From 754411a5b554e0e72bb05d14d79d2b1dba8ffceb Mon Sep 17 00:00:00 2001 From: Incy <85068563+IncyBot@users.noreply.github.com> Date: Sat, 2 Mar 2024 18:05:16 +0800 Subject: [PATCH 08/16] Added exceptions --- src/main/java/Incy.java | 42 ++++++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/src/main/java/Incy.java b/src/main/java/Incy.java index 2463925a7..66bfd48ef 100644 --- a/src/main/java/Incy.java +++ b/src/main/java/Incy.java @@ -32,14 +32,18 @@ private static void printGoodbyeMessage() { } private static void processInput(String input, TaskManager taskManager) { - if ("list".equalsIgnoreCase(input)) { - taskManager.handleListCommand(); - } else if (input.startsWith("mark ")) { - taskManager.handleMarkCommand(input, true); - } else if (input.startsWith("unmark ")) { - taskManager.handleMarkCommand(input, false); - } else { - taskManager.handleAddTask(input); + try { + if ("list".equalsIgnoreCase(input)) { + taskManager.handleListCommand(); + } else if (input.startsWith("mark ")) { + taskManager.handleMarkCommand(input, true); + } else if (input.startsWith("unmark ")) { + taskManager.handleMarkCommand(input, false); + } else { + taskManager.handleAddTask(input); + } + } catch (IncyException e) { + System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_RED + e.getMessage() + "\n" + Constants.LINE_STRING_BOTTOM); } } } @@ -72,17 +76,15 @@ private boolean isValidIndex(int index) { return index >= 0 && index < taskCount; } - void handleAddTask(String input) { + void handleAddTask(String input) throws IncyException { if (taskCount >= tasks.length) { System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_RED + "The list chocked a block, mate. Can't shove more stuff in it!\n" + Constants.LINE_STRING_BOTTOM); return; } Task newTask = TaskFactory.createTask(input); - if (newTask != null) { - tasks[taskCount++] = newTask; - printTaskAddedMessage(newTask); - } + tasks[taskCount++] = newTask; + printTaskAddedMessage(newTask); } private void printTaskAddedMessage(Task task) { @@ -94,21 +96,31 @@ private void printTaskAddedMessage(Task task) { } } + +class IncyException extends Exception { + public IncyException(String message) { + super(message); + } +} + class TaskFactory { - static Task createTask(String input) { + static Task createTask(String input) throws IncyException { String[] parts = input.split(" ", 2); String command = parts[0]; String taskInfo = parts.length > 1 ? parts[1] : ""; switch (command.toLowerCase()) { case "todo": + if (taskInfo.isEmpty()) { + throw new IncyException("Oi! You can't have a todo with no description!"); + } return new Todo(taskInfo); case "deadline": return createDeadline(taskInfo); case "event": return createEvent(taskInfo); default: - return new Todo(input); + throw new IncyException("Hol' up bruv, I dun get what that means..."); } } From 597f2fa3e42c129899a2fda1b8a1c62bc8b763bf Mon Sep 17 00:00:00 2001 From: Incy <85068563+IncyBot@users.noreply.github.com> Date: Tue, 5 Mar 2024 16:55:40 +0800 Subject: [PATCH 09/16] Added delete Functionality --- src/main/java/Incy.java | 73 +++++++++++++++++++++++++++-------------- 1 file changed, 49 insertions(+), 24 deletions(-) diff --git a/src/main/java/Incy.java b/src/main/java/Incy.java index 66bfd48ef..50276caee 100644 --- a/src/main/java/Incy.java +++ b/src/main/java/Incy.java @@ -1,3 +1,4 @@ +import java.util.ArrayList; import java.util.Scanner; public class Incy { @@ -21,14 +22,11 @@ public static void main(String[] args) { } private static void printWelcomeMessage() { - System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_CYAN + - "Oi bruv! I'm\n" + Constants.LOGO + - "Wotcha need from me today?\n" + Constants.LINE_STRING_BOTTOM); + System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_CYAN + "Oi bruv! I'm\n" + Constants.LOGO + Constants.ANSI_CYAN + "Wotcha need from me today?\n" + Constants.LINE_STRING_BOTTOM); } private static void printGoodbyeMessage() { - System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_CYAN + - "Cya later mate!\n" + Constants.LINE_STRING_BOTTOM); + System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_CYAN + "Cya later mate!\n" + Constants.LINE_STRING_BOTTOM); } private static void processInput(String input, TaskManager taskManager) { @@ -39,6 +37,8 @@ private static void processInput(String input, TaskManager taskManager) { taskManager.handleMarkCommand(input, true); } else if (input.startsWith("unmark ")) { taskManager.handleMarkCommand(input, false); + } else if (input.startsWith("delete ")) { + taskManager.handleDeleteCommand(input); } else { taskManager.handleAddTask(input); } @@ -49,54 +49,79 @@ private static void processInput(String input, TaskManager taskManager) { } class TaskManager { - private Task[] tasks = new Task[Constants.MAX_TASKS]; - private int taskCount = 0; + private ArrayList tasks = new ArrayList<>(); void handleListCommand() { System.out.println(Constants.LINE_STRING_BOTTOM); - if (taskCount == 0) { + if (tasks.isEmpty()) { System.out.println(Constants.ANSI_RED + "Blimey, your list is empty, innit?"); } else { - for (int i = 0; i < taskCount; i++) { - System.out.println(Constants.ANSI_CYAN + (i + 1) + ". " + tasks[i]); + int index = 1; + for (Task task : tasks) { + System.out.println(Constants.ANSI_CYAN + index++ + ". " + task); } } System.out.println(Constants.LINE_STRING_BOTTOM); } - void handleMarkCommand(String input, boolean markAsDone) { + void handleMarkCommand(String input, boolean markAsDone) throws IncyException { + if (tasks.isEmpty()) { + throw new IncyException("Nah, mate, nothin' to tick off, yer list's empty!"); + } + int index = Integer.parseInt(input.substring(markAsDone ? 5 : 7)) - 1; - if (isValidIndex(index)) { - tasks[index].setDone(markAsDone); - System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_CYAN + "Smashed it, this one's sorted!:\n " + tasks[index] + "\n" + Constants.LINE_STRING_BOTTOM); + if (!isValidIndex(index)) { + throw new IncyException("Gimme a legit number, will ya? That one's not on."); } + + tasks.get(index).setDone(markAsDone); + System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_CYAN + "Banging! This one's sorted!:\n " + tasks.get(index) + "\n" + Constants.LINE_STRING_BOTTOM); } private boolean isValidIndex(int index) { - return index >= 0 && index < taskCount; + return index >= 0 && index < tasks.size(); } void handleAddTask(String input) throws IncyException { - if (taskCount >= tasks.length) { - System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_RED + "The list chocked a block, mate. Can't shove more stuff in it!\n" + Constants.LINE_STRING_BOTTOM); - return; + Task newTask = TaskFactory.createTask(input); + if (newTask != null) { + tasks.add(newTask); + printTaskAddedMessage(newTask); } + } - Task newTask = TaskFactory.createTask(input); - tasks[taskCount++] = newTask; - printTaskAddedMessage(newTask); + void handleDeleteCommand(String input) throws IncyException { + if (tasks.isEmpty()) { + throw new IncyException("Oi, nothin' to bin 'ere, yer list's bare!"); + } + + int index = Integer.parseInt(input.substring(7)) - 1; + if (!isValidIndex(index)) { + throw new IncyException("That ain't a legit number, try again with a proper one, yeah?"); + } + + Task deletedTask = tasks.get(index); + removeTaskAt(index); + System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_CYAN + + "Safe! I've dashed this task:\n" + + " " + deletedTask + "\n" + + "Now you've got " + tasks.size() + " tasks on your plate.\n" + + Constants.LINE_STRING_BOTTOM); + } + + private void removeTaskAt(int index) { + tasks.remove(index); } private void printTaskAddedMessage(Task task) { System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_CYAN + "Sorted! Your task's in the bag, innit mate:\n" + " " + task + "\n" + - "You're now juggling " + taskCount + " tasks on your list, innit.\n" + + "You're now juggling " + tasks.size() + " tasks on your list, innit.\n" + Constants.LINE_STRING_BOTTOM); } } - class IncyException extends Exception { public IncyException(String message) { super(message); @@ -120,7 +145,7 @@ static Task createTask(String input) throws IncyException { case "event": return createEvent(taskInfo); default: - throw new IncyException("Hol' up bruv, I dun get what that means..."); + throw new IncyException("Hol' up bruv, I dun get what that means..., try typin 'todo', 'deadline', or 'event' first, yeah?"); } } From 3a618e489a47c5e56baa50ba33599199d2cf902e Mon Sep 17 00:00:00 2001 From: Incy <85068563+IncyBot@users.noreply.github.com> Date: Tue, 5 Mar 2024 18:01:12 +0800 Subject: [PATCH 10/16] Added Save Functionality --- src/main/java/Constants.java | 3 ++ src/main/java/Deadline.java | 5 ++ src/main/java/Event.java | 5 ++ src/main/java/Incy.java | 95 +++++++++++++++++++++++++++++++++++- src/main/java/Task.java | 5 +- src/main/java/Todo.java | 5 ++ 6 files changed, 116 insertions(+), 2 deletions(-) diff --git a/src/main/java/Constants.java b/src/main/java/Constants.java index 20dae3d89..9f8c09fad 100644 --- a/src/main/java/Constants.java +++ b/src/main/java/Constants.java @@ -23,6 +23,9 @@ public class Constants { public static final Integer MAX_TASKS = 100; + public static final String DATA_FOLDER = "data"; + public static final String DATA_FILE = "incy_tasks.txt"; + public static final String LOGO = " ▄▄ ▄▄▀▀ \n" + // " ▄▄▀ ▄▀▀▀▀▀▀▀▀▀ \n" + // " ▄▀▀▀ ▄▀▀▀▀▀▀▀▀▀ ▄\n" + // diff --git a/src/main/java/Deadline.java b/src/main/java/Deadline.java index 0ee665368..fbc05b6c1 100644 --- a/src/main/java/Deadline.java +++ b/src/main/java/Deadline.java @@ -10,4 +10,9 @@ public Deadline(String description, String by) { public String toString() { return "[D]" + super.getStatusIcon() + " " + description + " (by: " + by + ")"; } + + @Override + public String toFileString() { + return "D | " + (isDone ? "1" : "0") + " | " + description + " | " + by; + } } \ No newline at end of file diff --git a/src/main/java/Event.java b/src/main/java/Event.java index ac4d239cf..0b4076602 100644 --- a/src/main/java/Event.java +++ b/src/main/java/Event.java @@ -12,4 +12,9 @@ public Event(String description, String start, String end) { public String toString() { return "[E]" + super.getStatusIcon() + " " + description + " (from: " + start + " to: " + end + ")"; } + + @Override + public String toFileString() { + return "E | " + (isDone ? "1" : "0") + " | " + description + " | " + start + " | " + end; + } } \ No newline at end of file diff --git a/src/main/java/Incy.java b/src/main/java/Incy.java index 50276caee..c6b6a8c94 100644 --- a/src/main/java/Incy.java +++ b/src/main/java/Incy.java @@ -1,12 +1,24 @@ +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Scanner; public class Incy { + + public static void main(String[] args) { Scanner scanner = new Scanner(System.in); TaskManager taskManager = new TaskManager(); + ensureDataFolderExists(); + taskManager.loadTasksFromFile(); + printWelcomeMessage(); while (true) { @@ -17,10 +29,22 @@ public static void main(String[] args) { processInput(input, taskManager); } + taskManager.saveTasksToFile(); printGoodbyeMessage(); scanner.close(); } + private static void ensureDataFolderExists() { + Path dataFolderPath = Paths.get(Constants.DATA_FOLDER); + if (!Files.exists(dataFolderPath)) { + try { + Files.createDirectory(dataFolderPath); + } catch (IOException e) { + System.err.println("Failed to create data folder: " + e.getMessage()); + } + } + } + private static void printWelcomeMessage() { System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_CYAN + "Oi bruv! I'm\n" + Constants.LOGO + Constants.ANSI_CYAN + "Wotcha need from me today?\n" + Constants.LINE_STRING_BOTTOM); } @@ -120,6 +144,38 @@ private void printTaskAddedMessage(Task task) { "You're now juggling " + tasks.size() + " tasks on your list, innit.\n" + Constants.LINE_STRING_BOTTOM); } + + void loadTasksFromFile() { + Path dataFilePath = Paths.get(Constants.DATA_FOLDER, Constants.DATA_FILE); + if (Files.exists(dataFilePath)) { + try { + Scanner scanner = new Scanner(dataFilePath); + while (scanner.hasNextLine()) { + String line = scanner.nextLine(); + Task task = TaskFactory.createTaskFromLine(line); + if (task != null) { + tasks.add(task); + } + } + scanner.close(); + } catch (IOException e) { + TaskFactory.printFormatError("Failed to load tasks from file: " + e.getMessage()); + } + } + } + + void saveTasksToFile() { + Path dataFilePath = Paths.get(Constants.DATA_FOLDER, Constants.DATA_FILE); + try { + FileWriter writer = new FileWriter(dataFilePath.toFile()); + for (Task task : tasks) { + writer.write(task.toFileString() + "\n"); + } + writer.close(); + } catch (IOException e) { + TaskFactory.printFormatError("Failed to save tasks to file: " + e.getMessage()); + } + } } class IncyException extends Exception { @@ -149,6 +205,27 @@ static Task createTask(String input) throws IncyException { } } + static Task createTaskFromLine(String line) { + String[] parts = line.split(" \\| ", 2); + if (parts.length < 2) { + return null; + } + + String typeCode = parts[0]; + String taskData = parts[1]; + + switch (typeCode) { + case "T": + return new Todo(taskData); + case "D": + return createDeadlineFromLine(taskData); + case "E": + return createEventFromLine(taskData); + default: + return null; + } + } + private static Task createDeadline(String taskInfo) { String[] deadlineParts = taskInfo.split(" /by ", 2); if (deadlineParts.length < 2) { @@ -168,7 +245,23 @@ private static Task createEvent(String taskInfo) { return new Event(eventParts[0], eventTime[0], eventTime[1]); } - private static void printFormatError(String errorMessage) { + private static Deadline createDeadlineFromLine(String line) { + String[] parts = line.split(" \\| ", 3); + if (parts.length < 3) { + return null; + } + return new Deadline(parts[1], parts[2]); + } + + private static Event createEventFromLine(String line) { + String[] parts = line.split(" \\| ", 4); + if (parts.length < 4) { + return null; + } + return new Event(parts[1], parts[2], parts[3]); + } + + static void printFormatError(String errorMessage) { System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_RED + "Error: " + errorMessage + "\n" + Constants.LINE_STRING_BOTTOM); } diff --git a/src/main/java/Task.java b/src/main/java/Task.java index 744507afc..a4eb4f5d1 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -1,3 +1,4 @@ + public abstract class Task { protected String description; protected boolean isDone; @@ -17,4 +18,6 @@ public void setDone(boolean done) { @Override public abstract String toString(); -} + + public abstract String toFileString(); +} \ No newline at end of file diff --git a/src/main/java/Todo.java b/src/main/java/Todo.java index 7c58cc21f..a17521f5f 100644 --- a/src/main/java/Todo.java +++ b/src/main/java/Todo.java @@ -7,4 +7,9 @@ public Todo(String description) { public String toString() { return "[T]" + super.getStatusIcon() + " " + description; } + + @Override + public String toFileString() { + return "T | " + (isDone ? "1" : "0") + " | " + description; + } } \ No newline at end of file From fc705931dd51d89dbffe69d74958a0a5adbb95a2 Mon Sep 17 00:00:00 2001 From: Incy <85068563+IncyBot@users.noreply.github.com> Date: Tue, 5 Mar 2024 18:14:29 +0800 Subject: [PATCH 11/16] Updated Readme --- CONTRIBUTORS.md | 9 ---- README.md | 113 +++++++++++++++++++++++++++++++--------- src/main/java/Incy.java | 5 +- 3 files changed, 92 insertions(+), 35 deletions(-) delete mode 100644 CONTRIBUTORS.md diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md deleted file mode 100644 index 8e359a014..000000000 --- a/CONTRIBUTORS.md +++ /dev/null @@ -1,9 +0,0 @@ -# Contributors - -Display | Name | Github Profile | Homepage ----|:---:|:---:|:---: -![](https://avatars0.githubusercontent.com/u/22460123?s=100) | Jeffry Lum | [Github](https://github.com/j-lum/) | [Homepage](https://se.kasugano.moe) -![](https://avatars0.githubusercontent.com/u/1673303?s=100) | Damith C. Rajapakse | [Github](https://github.com/damithc/) | [Homepage](https://www.comp.nus.edu.sg/~damithch/) -# I would like to join this list. How can I help the project - -For more information, please refer to our [contributor's guide](https://oss-generic.github.io/process/). diff --git a/README.md b/README.md index 8715d4d91..5054ca107 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,89 @@ -# Duke project template - -This is a project template for a greenfield Java project. It's named after the Java mascot _Duke_. Given below are instructions on how to use it. - -## Setting up in Intellij - -Prerequisites: JDK 11, update Intellij to the most recent version. - -1. Open Intellij (if you are not in the welcome screen, click `File` > `Close Project` to close the existing project first) -1. Open the project into Intellij as follows: - 1. Click `Open`. - 1. Select the project directory, and click `OK`. - 1. If there are any further prompts, accept the defaults. -1. Configure the project to use **JDK 11** (not other versions) as explained in [here](https://www.jetbrains.com/help/idea/sdk.html#set-up-jdk).
- In the same dialog, set the **Project language level** field to the `SDK default` option. -3. After that, locate the `src/main/java/Duke.java` file, right-click it, and choose `Run Duke.main()` (if the code editor is showing compile errors, try restarting the IDE). If the setup is correct, you should see something like the below as the output: - ``` - Hello from - ____ _ - | _ \ _ _| | _____ - | | | | | | | |/ / _ \ - | |_| | |_| | < __/ - |____/ \__,_|_|\_\___| - ``` +# Incy - The British Task Manager + +Incy is a British command-line task management application! It allows you to add, mark, unmark, delete, and list tasks of various types: ToDos, Deadlines, and Events. + +## Features + +- Add ToDos, Deadlines, and Events tasks +- Mark tasks as done +- Unmark tasks as not done +- Delete tasks +- List all tasks +- Automatically save and load tasks from a file + +## Installation + +1. Make sure you have Java installed on your system. +2. Clone the repository or download the source code. + +## Usage + +1. Navigate to the project directory in your terminal. +2. Compile the Java files using the following command: + +``` +javac *.java +``` + +3. Run the application with: + +``` +java Incy +``` + +4. Incy will greet you and prompt you to enter commands. + +### Commands + +- `todo [description]`: Add a new ToDo task with the given description. +- `deadline [description] /by [date/time]`: Add a new Deadline task with the given description and due date/time. +- `event [description] /from [start time] /to [end time]`: Add a new Event task with the given description, start time, and end time. +- `list`: List all tasks in the task list. +- `mark [index]`: Mark the task at the given index as done. +- `unmark [index]`: Mark the task at the given index as not done. +- `delete [index]`: Delete the task at the given index. +- `bye`: Exit the application. + +**Note:** Indices for mark, unmark, and delete commands start from 1. + +### Task Storage + +Incy automatically saves your tasks to a file named `incy_tasks.txt` in the `data` folder within the project directory. If the `data` folder doesn't exist, it will be created automatically. If the `incy_tasks.txt` file doesn't exist, a new file will be created when you add your first task. + +### File Format + +The task data is stored in the `incy_tasks.txt` file using the following format: + +``` +T | 0 | read book +D | 1 | return book | June 6th +E | 0 | project meeting | Aug 6th 2-4pm | Aug 6th 6-8pm +``` + +- `T` represents a ToDo task, `D` represents a Deadline task, and `E` represents an Event task. +- The second value (`0` or `1`) indicates whether the task is done or not. +- The remaining values represent the task description and additional details (due date for Deadlines, start and end times for Events). + +If the file becomes corrupted or contains invalid data, Incy will skip the corrupted lines and load the valid tasks. + +## Code Structure + +The application is structured into the following classes: + +- `Incy`: The main class that handles user input and interaction. +- `TaskManager`: Manages the task list and handles commands related to tasks. +- `TaskFactory`: Responsible for creating tasks from user input and file data. +- `Task`: Abstract base class for different task types. +- `Todo`: Represents a ToDo task. +- `Deadline`: Represents a Deadline task. +- `Event`: Represents an Event task. +- `IncyException`: Custom exception class used for handling errors. +- `Constants`: Contains constant values used throughout the application. + +## Dependencies + +This application has no external dependencies and only uses the built-in Java libraries. + +## Contributing + +Contributions to Incy are welcome! If you find any bugs or have suggestions for improvements, please open an issue or submit a pull request. \ No newline at end of file diff --git a/src/main/java/Incy.java b/src/main/java/Incy.java index c6b6a8c94..14547d900 100644 --- a/src/main/java/Incy.java +++ b/src/main/java/Incy.java @@ -10,8 +10,6 @@ public class Incy { - - public static void main(String[] args) { Scanner scanner = new Scanner(System.in); TaskManager taskManager = new TaskManager(); @@ -100,6 +98,7 @@ void handleMarkCommand(String input, boolean markAsDone) throws IncyException { tasks.get(index).setDone(markAsDone); System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_CYAN + "Banging! This one's sorted!:\n " + tasks.get(index) + "\n" + Constants.LINE_STRING_BOTTOM); + saveTasksToFile(); } private boolean isValidIndex(int index) { @@ -111,6 +110,7 @@ void handleAddTask(String input) throws IncyException { if (newTask != null) { tasks.add(newTask); printTaskAddedMessage(newTask); + saveTasksToFile(); } } @@ -131,6 +131,7 @@ void handleDeleteCommand(String input) throws IncyException { " " + deletedTask + "\n" + "Now you've got " + tasks.size() + " tasks on your plate.\n" + Constants.LINE_STRING_BOTTOM); + saveTasksToFile(); } private void removeTaskAt(int index) { From b1aaf7497af995875603b477cc844e5d98fd5289 Mon Sep 17 00:00:00 2001 From: Incy <85068563+IncyBot@users.noreply.github.com> Date: Fri, 8 Mar 2024 00:37:15 +0800 Subject: [PATCH 12/16] Taught The Chatbot How to Understand DATES --- data/incy_tasks.txt | 1 + src/main/java/Deadline.java | 15 +++++++--- src/main/java/Event.java | 23 +++++++++++---- src/main/java/Incy.java | 57 +++++++++++++++++++++++++++++++++---- src/main/java/Task.java | 1 - 5 files changed, 81 insertions(+), 16 deletions(-) create mode 100644 data/incy_tasks.txt diff --git a/data/incy_tasks.txt b/data/incy_tasks.txt new file mode 100644 index 000000000..cc48c499c --- /dev/null +++ b/data/incy_tasks.txt @@ -0,0 +1 @@ +D | 0 | return book | 2019-10-20 1800 diff --git a/src/main/java/Deadline.java b/src/main/java/Deadline.java index fbc05b6c1..9ebbd5d92 100644 --- a/src/main/java/Deadline.java +++ b/src/main/java/Deadline.java @@ -1,18 +1,25 @@ +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + public class Deadline extends Task { - private String by; + private LocalDateTime by; public Deadline(String description, String by) { super(description); - this.by = by; + this.by = LocalDateTime.parse(by, DateTimeFormatter.ofPattern("yyyy-MM-dd HHmm")); + } + + public LocalDateTime getBy() { + return by; } @Override public String toString() { - return "[D]" + super.getStatusIcon() + " " + description + " (by: " + by + ")"; + return "[D]" + super.getStatusIcon() + " " + description + " (by: " + by.format(DateTimeFormatter.ofPattern("MMM dd yyyy, hh:mm a")) + ")"; } @Override public String toFileString() { - return "D | " + (isDone ? "1" : "0") + " | " + description + " | " + by; + return "D | " + (isDone ? "1" : "0") + " | " + description + " | " + by.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HHmm")); } } \ No newline at end of file diff --git a/src/main/java/Event.java b/src/main/java/Event.java index 0b4076602..99ca89c0d 100644 --- a/src/main/java/Event.java +++ b/src/main/java/Event.java @@ -1,20 +1,31 @@ +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + public class Event extends Task { - private String start; - private String end; + private LocalDateTime start; + private LocalDateTime end; public Event(String description, String start, String end) { super(description); - this.start = start; - this.end = end; + this.start = LocalDateTime.parse(start, DateTimeFormatter.ofPattern("yyyy-MM-dd HHmm")); + this.end = LocalDateTime.parse(end, DateTimeFormatter.ofPattern("yyyy-MM-dd HHmm")); + } + + public LocalDateTime getStart() { + return start; + } + + public LocalDateTime getEnd() { + return end; } @Override public String toString() { - return "[E]" + super.getStatusIcon() + " " + description + " (from: " + start + " to: " + end + ")"; + return "[E]" + super.getStatusIcon() + " " + description + " (from: " + start.format(DateTimeFormatter.ofPattern("MMM dd yyyy, hh:mm a")) + " to: " + end.format(DateTimeFormatter.ofPattern("MMM dd yyyy, hh:mm a")) + ")"; } @Override public String toFileString() { - return "E | " + (isDone ? "1" : "0") + " | " + description + " | " + start + " | " + end; + return "E | " + (isDone ? "1" : "0") + " | " + description + " | " + start.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HHmm")) + " | " + end.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HHmm")); } } \ No newline at end of file diff --git a/src/main/java/Incy.java b/src/main/java/Incy.java index 14547d900..87ae0cd8a 100644 --- a/src/main/java/Incy.java +++ b/src/main/java/Incy.java @@ -7,6 +7,10 @@ import java.nio.file.Paths; import java.util.ArrayList; import java.util.Scanner; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; public class Incy { @@ -61,6 +65,8 @@ private static void processInput(String input, TaskManager taskManager) { taskManager.handleMarkCommand(input, false); } else if (input.startsWith("delete ")) { taskManager.handleDeleteCommand(input); + } else if (input.startsWith("list by ")) { + taskManager.handleListByDateCommand(input); } else { taskManager.handleAddTask(input); } @@ -134,6 +140,37 @@ void handleDeleteCommand(String input) throws IncyException { saveTasksToFile(); } + void handleListByDateCommand(String input) throws IncyException { + String dateString = input.substring(9).trim(); + LocalDate date; + try { + date = LocalDate.parse(dateString, DateTimeFormatter.ofPattern("yyyy-MM-dd")); + } catch (DateTimeParseException e) { + throw new IncyException("Invalid date format, mate. Use 'yyyy-MM-dd' format."); + } + System.out.println(Constants.LINE_STRING_BOTTOM); + boolean found = false; + for (Task task : tasks) { + if (task instanceof Deadline) { + Deadline deadline = (Deadline) task; + if (deadline.getBy().toLocalDate().equals(date)) { + System.out.println(Constants.ANSI_CYAN + "- " + deadline); + found = true; + } + } else if (task instanceof Event) { + Event event = (Event) task; + if (event.getStart().toLocalDate().equals(date) || event.getEnd().toLocalDate().equals(date)) { + System.out.println(Constants.ANSI_CYAN + "- " + event); + found = true; + } + } + } + if (!found) { + System.out.println(Constants.ANSI_RED + "No tasks found for the specified date, bruv."); + } + System.out.println(Constants.LINE_STRING_BOTTOM); + } + private void removeTaskAt(int index) { tasks.remove(index); } @@ -230,20 +267,30 @@ static Task createTaskFromLine(String line) { private static Task createDeadline(String taskInfo) { String[] deadlineParts = taskInfo.split(" /by ", 2); if (deadlineParts.length < 2) { - printFormatError("You've mucked up the deadline format. Do it like 'deadline [task] /by [date/time]', yeah?"); + printFormatError("You've mucked up the deadline format. Do it like 'deadline [task] /by [yyyy-MM-dd HHmm]', yeah?"); + return null; + } + try { + return new Deadline(deadlineParts[0], deadlineParts[1]); + } catch (DateTimeParseException e) { + printFormatError("Invalid date format for deadline. Use 'yyyy-MM-dd HHmm' format, mate."); return null; } - return new Deadline(deadlineParts[0], deadlineParts[1]); } - + private static Task createEvent(String taskInfo) { String[] eventParts = taskInfo.split(" /from ", 2); String[] eventTime = eventParts.length > 1 ? eventParts[1].split(" /to ", 2) : new String[0]; if (eventParts.length < 2 || eventTime.length < 2) { - printFormatError("You've bungled the event format. It's gotta be 'event [task] /from [start time] /to [end time]', innit?"); + printFormatError("You've bungled the event format. It's gotta be 'event [task] /from [yyyy-MM-dd HHmm] /to [yyyy-MM-dd HHmm]', innit?"); + return null; + } + try { + return new Event(eventParts[0], eventTime[0], eventTime[1]); + } catch (DateTimeParseException e) { + printFormatError("Invalid date format for event. Use 'yyyy-MM-dd HHmm' format, mate."); return null; } - return new Event(eventParts[0], eventTime[0], eventTime[1]); } private static Deadline createDeadlineFromLine(String line) { diff --git a/src/main/java/Task.java b/src/main/java/Task.java index a4eb4f5d1..da8199462 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -1,4 +1,3 @@ - public abstract class Task { protected String description; protected boolean isDone; From 355ec3bbf27e16fdcb2b56049e522103897f34d4 Mon Sep 17 00:00:00 2001 From: Incy <85068563+IncyBot@users.noreply.github.com> Date: Fri, 8 Mar 2024 00:49:00 +0800 Subject: [PATCH 13/16] Added Find Function --- data/incy_tasks.txt | 1 + src/main/java/Incy.java | 22 ++++++++++++++++++++++ src/main/java/Task.java | 4 +++- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/data/incy_tasks.txt b/data/incy_tasks.txt index cc48c499c..72ffa84c4 100644 --- a/data/incy_tasks.txt +++ b/data/incy_tasks.txt @@ -1 +1,2 @@ D | 0 | return book | 2019-10-20 1800 +T | 0 | book borrow diff --git a/src/main/java/Incy.java b/src/main/java/Incy.java index 87ae0cd8a..af48f0a15 100644 --- a/src/main/java/Incy.java +++ b/src/main/java/Incy.java @@ -67,6 +67,8 @@ private static void processInput(String input, TaskManager taskManager) { taskManager.handleDeleteCommand(input); } else if (input.startsWith("list by ")) { taskManager.handleListByDateCommand(input); + } else if (input.startsWith("find ")) { + taskManager.handleFindCommand(input); } else { taskManager.handleAddTask(input); } @@ -140,6 +142,26 @@ void handleDeleteCommand(String input) throws IncyException { saveTasksToFile(); } + void handleFindCommand(String input) throws IncyException { + if (input.length() <= 5) { + throw new IncyException("Oi, you forgot to tell me what to find, mate!"); + } + String keyword = input.substring(5).trim().toLowerCase(); + System.out.println(Constants.LINE_STRING_TOP); + boolean found = false; + int index = 1; + for (Task task : tasks) { + if (task.getDescription().toLowerCase().contains(keyword)) { + System.out.println(Constants.ANSI_CYAN + " " + index++ + ". " + task); + found = true; + } + } + if (!found) { + System.out.println(Constants.ANSI_RED + "No tasks found with the keyword '" + keyword + "', bruv."); + } + System.out.println(Constants.LINE_STRING_BOTTOM); + } + void handleListByDateCommand(String input) throws IncyException { String dateString = input.substring(9).trim(); LocalDate date; diff --git a/src/main/java/Task.java b/src/main/java/Task.java index da8199462..f5e33060d 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -6,7 +6,9 @@ public abstract class Task { this.description = description; this.isDone = false; } - + public String getDescription() { + return description; + } String getStatusIcon() { return (isDone ? "[X]" : "[ ]"); } From 7f0c3e2592597548f77dadcfd655032e3dfc21f0 Mon Sep 17 00:00:00 2001 From: Incy <85068563+IncyBot@users.noreply.github.com> Date: Fri, 8 Mar 2024 00:52:50 +0800 Subject: [PATCH 14/16] Removed Data Folder --- data/incy_tasks.txt | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 data/incy_tasks.txt diff --git a/data/incy_tasks.txt b/data/incy_tasks.txt deleted file mode 100644 index 72ffa84c4..000000000 --- a/data/incy_tasks.txt +++ /dev/null @@ -1,2 +0,0 @@ -D | 0 | return book | 2019-10-20 1800 -T | 0 | book borrow From 207c371f05838ee52c82ff54c1c8e559a7fa51bc Mon Sep 17 00:00:00 2001 From: Incy <85068563+IncyBot@users.noreply.github.com> Date: Fri, 8 Mar 2024 01:32:52 +0800 Subject: [PATCH 15/16] Added JavaDoc comments to the code. --- src/main/java/Constants.java | 4 + src/main/java/Deadline.java | 22 +++ src/main/java/Event.java | 28 +++ src/main/java/Incy.java | 299 ++++--------------------------- src/main/java/IncyException.java | 14 ++ src/main/java/Task.java | 31 ++++ src/main/java/TaskFactory.java | 141 +++++++++++++++ src/main/java/TaskManager.java | 231 ++++++++++++++++++++++++ src/main/java/Todo.java | 17 ++ 9 files changed, 519 insertions(+), 268 deletions(-) create mode 100644 src/main/java/IncyException.java create mode 100644 src/main/java/TaskFactory.java create mode 100644 src/main/java/TaskManager.java diff --git a/src/main/java/Constants.java b/src/main/java/Constants.java index 9f8c09fad..bcba3489b 100644 --- a/src/main/java/Constants.java +++ b/src/main/java/Constants.java @@ -1,3 +1,7 @@ +/** + * The Constants class holds constant values used throughout the application. + */ + public class Constants { public static final String ANSI_RESET = "\u001B[0m"; public static final String ANSI_BLACK = "\u001B[30m"; diff --git a/src/main/java/Deadline.java b/src/main/java/Deadline.java index 9ebbd5d92..5434e3bf3 100644 --- a/src/main/java/Deadline.java +++ b/src/main/java/Deadline.java @@ -1,23 +1,45 @@ +/** + * The Deadline class represents a task with a deadline. + * It extends the Task class and adds a deadline date and time. + */ + import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; public class Deadline extends Task { private LocalDateTime by; + /** + * Constructs a new Deadline object with the given description and deadline. + * @param description The task description + * @param by The deadline date and time in the format "yyyy-MM-dd HHmm" + */ public Deadline(String description, String by) { super(description); this.by = LocalDateTime.parse(by, DateTimeFormatter.ofPattern("yyyy-MM-dd HHmm")); } + /** + * Gets the deadline date and time. + * @return The deadline date and time + */ public LocalDateTime getBy() { return by; } + /** + * Returns a string representation of the Deadline task. + * @return The string representation + */ @Override public String toString() { return "[D]" + super.getStatusIcon() + " " + description + " (by: " + by.format(DateTimeFormatter.ofPattern("MMM dd yyyy, hh:mm a")) + ")"; } + /** + * Returns a string representation of the Deadline task suitable for writing to a file. + * @return The string representation + */ @Override public String toFileString() { return "D | " + (isDone ? "1" : "0") + " | " + description + " | " + by.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HHmm")); diff --git a/src/main/java/Event.java b/src/main/java/Event.java index 99ca89c0d..15d71a6eb 100644 --- a/src/main/java/Event.java +++ b/src/main/java/Event.java @@ -1,3 +1,8 @@ +/** + * The Event class represents a task with a start and end time. + * It extends the Task class and adds start and end date and time properties. + */ + import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; @@ -5,25 +10,48 @@ public class Event extends Task { private LocalDateTime start; private LocalDateTime end; + /** + * Constructs a new Event object with the given description, start time, and end time. + * @param description The task description + * @param start The start date and time in the format "yyyy-MM-dd HHmm" + * @param end The end date and time in the format "yyyy-MM-dd HHmm" + */ public Event(String description, String start, String end) { super(description); this.start = LocalDateTime.parse(start, DateTimeFormatter.ofPattern("yyyy-MM-dd HHmm")); this.end = LocalDateTime.parse(end, DateTimeFormatter.ofPattern("yyyy-MM-dd HHmm")); } + + /** + * Gets the start date and time. + * @return The start date and time + */ public LocalDateTime getStart() { return start; } + /** + * Gets the end date and time. + * @return The end date and time + */ public LocalDateTime getEnd() { return end; } + /** + * Returns a string representation of the Event task. + * @return The string representation + */ @Override public String toString() { return "[E]" + super.getStatusIcon() + " " + description + " (from: " + start.format(DateTimeFormatter.ofPattern("MMM dd yyyy, hh:mm a")) + " to: " + end.format(DateTimeFormatter.ofPattern("MMM dd yyyy, hh:mm a")) + ")"; } + /** + * Returns a string representation of the Event task suitable for writing to a file. + * @return The string representation + */ @Override public String toFileString() { return "E | " + (isDone ? "1" : "0") + " | " + description + " | " + start.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HHmm")) + " | " + end.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HHmm")); diff --git a/src/main/java/Incy.java b/src/main/java/Incy.java index af48f0a15..a2708c3c2 100644 --- a/src/main/java/Incy.java +++ b/src/main/java/Incy.java @@ -1,19 +1,22 @@ -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileWriter; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.ArrayList; import java.util.Scanner; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.time.format.DateTimeParseException; -public class Incy { +/** + * The Incy class is the main entry point of the application. + * It handles user input, manages tasks, and interacts with the TaskManager class. + */ +public class Incy { + /** + * The main method of the application. + * It initializes the TaskManager, loads tasks from file, processes user input, + * saves tasks to file, and handles the application's lifecycle. + * + * @param args The command-line arguments (not used) + */ public static void main(String[] args) { Scanner scanner = new Scanner(System.in); TaskManager taskManager = new TaskManager(); @@ -36,6 +39,10 @@ public static void main(String[] args) { scanner.close(); } + /** + * Ensures that the data folder exists, creating it if necessary. + */ + private static void ensureDataFolderExists() { Path dataFolderPath = Paths.get(Constants.DATA_FOLDER); if (!Files.exists(dataFolderPath)) { @@ -47,14 +54,29 @@ private static void ensureDataFolderExists() { } } + /** + * Prints the welcome message to the console. + */ + private static void printWelcomeMessage() { System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_CYAN + "Oi bruv! I'm\n" + Constants.LOGO + Constants.ANSI_CYAN + "Wotcha need from me today?\n" + Constants.LINE_STRING_BOTTOM); } + /** + * Prints the goodbye message to the console. + */ + private static void printGoodbyeMessage() { System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_CYAN + "Cya later mate!\n" + Constants.LINE_STRING_BOTTOM); } + /** + * Processes the user input and delegates the appropriate action to the TaskManager. + * + * @param input The user input string + * @param taskManager The TaskManager instance + */ + private static void processInput(String input, TaskManager taskManager) { try { if ("list".equalsIgnoreCase(input)) { @@ -77,262 +99,3 @@ private static void processInput(String input, TaskManager taskManager) { } } } - -class TaskManager { - private ArrayList tasks = new ArrayList<>(); - - void handleListCommand() { - System.out.println(Constants.LINE_STRING_BOTTOM); - if (tasks.isEmpty()) { - System.out.println(Constants.ANSI_RED + "Blimey, your list is empty, innit?"); - } else { - int index = 1; - for (Task task : tasks) { - System.out.println(Constants.ANSI_CYAN + index++ + ". " + task); - } - } - System.out.println(Constants.LINE_STRING_BOTTOM); - } - - void handleMarkCommand(String input, boolean markAsDone) throws IncyException { - if (tasks.isEmpty()) { - throw new IncyException("Nah, mate, nothin' to tick off, yer list's empty!"); - } - - int index = Integer.parseInt(input.substring(markAsDone ? 5 : 7)) - 1; - if (!isValidIndex(index)) { - throw new IncyException("Gimme a legit number, will ya? That one's not on."); - } - - tasks.get(index).setDone(markAsDone); - System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_CYAN + "Banging! This one's sorted!:\n " + tasks.get(index) + "\n" + Constants.LINE_STRING_BOTTOM); - saveTasksToFile(); - } - - private boolean isValidIndex(int index) { - return index >= 0 && index < tasks.size(); - } - - void handleAddTask(String input) throws IncyException { - Task newTask = TaskFactory.createTask(input); - if (newTask != null) { - tasks.add(newTask); - printTaskAddedMessage(newTask); - saveTasksToFile(); - } - } - - void handleDeleteCommand(String input) throws IncyException { - if (tasks.isEmpty()) { - throw new IncyException("Oi, nothin' to bin 'ere, yer list's bare!"); - } - - int index = Integer.parseInt(input.substring(7)) - 1; - if (!isValidIndex(index)) { - throw new IncyException("That ain't a legit number, try again with a proper one, yeah?"); - } - - Task deletedTask = tasks.get(index); - removeTaskAt(index); - System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_CYAN + - "Safe! I've dashed this task:\n" + - " " + deletedTask + "\n" + - "Now you've got " + tasks.size() + " tasks on your plate.\n" + - Constants.LINE_STRING_BOTTOM); - saveTasksToFile(); - } - - void handleFindCommand(String input) throws IncyException { - if (input.length() <= 5) { - throw new IncyException("Oi, you forgot to tell me what to find, mate!"); - } - String keyword = input.substring(5).trim().toLowerCase(); - System.out.println(Constants.LINE_STRING_TOP); - boolean found = false; - int index = 1; - for (Task task : tasks) { - if (task.getDescription().toLowerCase().contains(keyword)) { - System.out.println(Constants.ANSI_CYAN + " " + index++ + ". " + task); - found = true; - } - } - if (!found) { - System.out.println(Constants.ANSI_RED + "No tasks found with the keyword '" + keyword + "', bruv."); - } - System.out.println(Constants.LINE_STRING_BOTTOM); - } - - void handleListByDateCommand(String input) throws IncyException { - String dateString = input.substring(9).trim(); - LocalDate date; - try { - date = LocalDate.parse(dateString, DateTimeFormatter.ofPattern("yyyy-MM-dd")); - } catch (DateTimeParseException e) { - throw new IncyException("Invalid date format, mate. Use 'yyyy-MM-dd' format."); - } - System.out.println(Constants.LINE_STRING_BOTTOM); - boolean found = false; - for (Task task : tasks) { - if (task instanceof Deadline) { - Deadline deadline = (Deadline) task; - if (deadline.getBy().toLocalDate().equals(date)) { - System.out.println(Constants.ANSI_CYAN + "- " + deadline); - found = true; - } - } else if (task instanceof Event) { - Event event = (Event) task; - if (event.getStart().toLocalDate().equals(date) || event.getEnd().toLocalDate().equals(date)) { - System.out.println(Constants.ANSI_CYAN + "- " + event); - found = true; - } - } - } - if (!found) { - System.out.println(Constants.ANSI_RED + "No tasks found for the specified date, bruv."); - } - System.out.println(Constants.LINE_STRING_BOTTOM); - } - - private void removeTaskAt(int index) { - tasks.remove(index); - } - - private void printTaskAddedMessage(Task task) { - System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_CYAN + - "Sorted! Your task's in the bag, innit mate:\n" + - " " + task + "\n" + - "You're now juggling " + tasks.size() + " tasks on your list, innit.\n" + - Constants.LINE_STRING_BOTTOM); - } - - void loadTasksFromFile() { - Path dataFilePath = Paths.get(Constants.DATA_FOLDER, Constants.DATA_FILE); - if (Files.exists(dataFilePath)) { - try { - Scanner scanner = new Scanner(dataFilePath); - while (scanner.hasNextLine()) { - String line = scanner.nextLine(); - Task task = TaskFactory.createTaskFromLine(line); - if (task != null) { - tasks.add(task); - } - } - scanner.close(); - } catch (IOException e) { - TaskFactory.printFormatError("Failed to load tasks from file: " + e.getMessage()); - } - } - } - - void saveTasksToFile() { - Path dataFilePath = Paths.get(Constants.DATA_FOLDER, Constants.DATA_FILE); - try { - FileWriter writer = new FileWriter(dataFilePath.toFile()); - for (Task task : tasks) { - writer.write(task.toFileString() + "\n"); - } - writer.close(); - } catch (IOException e) { - TaskFactory.printFormatError("Failed to save tasks to file: " + e.getMessage()); - } - } -} - -class IncyException extends Exception { - public IncyException(String message) { - super(message); - } -} - -class TaskFactory { - static Task createTask(String input) throws IncyException { - String[] parts = input.split(" ", 2); - String command = parts[0]; - String taskInfo = parts.length > 1 ? parts[1] : ""; - - switch (command.toLowerCase()) { - case "todo": - if (taskInfo.isEmpty()) { - throw new IncyException("Oi! You can't have a todo with no description!"); - } - return new Todo(taskInfo); - case "deadline": - return createDeadline(taskInfo); - case "event": - return createEvent(taskInfo); - default: - throw new IncyException("Hol' up bruv, I dun get what that means..., try typin 'todo', 'deadline', or 'event' first, yeah?"); - } - } - - static Task createTaskFromLine(String line) { - String[] parts = line.split(" \\| ", 2); - if (parts.length < 2) { - return null; - } - - String typeCode = parts[0]; - String taskData = parts[1]; - - switch (typeCode) { - case "T": - return new Todo(taskData); - case "D": - return createDeadlineFromLine(taskData); - case "E": - return createEventFromLine(taskData); - default: - return null; - } - } - - private static Task createDeadline(String taskInfo) { - String[] deadlineParts = taskInfo.split(" /by ", 2); - if (deadlineParts.length < 2) { - printFormatError("You've mucked up the deadline format. Do it like 'deadline [task] /by [yyyy-MM-dd HHmm]', yeah?"); - return null; - } - try { - return new Deadline(deadlineParts[0], deadlineParts[1]); - } catch (DateTimeParseException e) { - printFormatError("Invalid date format for deadline. Use 'yyyy-MM-dd HHmm' format, mate."); - return null; - } - } - - private static Task createEvent(String taskInfo) { - String[] eventParts = taskInfo.split(" /from ", 2); - String[] eventTime = eventParts.length > 1 ? eventParts[1].split(" /to ", 2) : new String[0]; - if (eventParts.length < 2 || eventTime.length < 2) { - printFormatError("You've bungled the event format. It's gotta be 'event [task] /from [yyyy-MM-dd HHmm] /to [yyyy-MM-dd HHmm]', innit?"); - return null; - } - try { - return new Event(eventParts[0], eventTime[0], eventTime[1]); - } catch (DateTimeParseException e) { - printFormatError("Invalid date format for event. Use 'yyyy-MM-dd HHmm' format, mate."); - return null; - } - } - - private static Deadline createDeadlineFromLine(String line) { - String[] parts = line.split(" \\| ", 3); - if (parts.length < 3) { - return null; - } - return new Deadline(parts[1], parts[2]); - } - - private static Event createEventFromLine(String line) { - String[] parts = line.split(" \\| ", 4); - if (parts.length < 4) { - return null; - } - return new Event(parts[1], parts[2], parts[3]); - } - - static void printFormatError(String errorMessage) { - System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_RED + "Error: " + errorMessage + "\n" + - Constants.LINE_STRING_BOTTOM); - } -} \ No newline at end of file diff --git a/src/main/java/IncyException.java b/src/main/java/IncyException.java new file mode 100644 index 000000000..f774afd76 --- /dev/null +++ b/src/main/java/IncyException.java @@ -0,0 +1,14 @@ +/** + * The IncyException class represents an exception that occurs within the Incy application. + */ + +public class IncyException extends Exception { + /** + * Constructs a new IncyException with the specified message. + * + * @param message The exception message + */ + public IncyException(String message) { + super(message); + } +} \ No newline at end of file diff --git a/src/main/java/Task.java b/src/main/java/Task.java index f5e33060d..e216ca958 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -1,24 +1,55 @@ +/** + * The Task class is an abstract base class representing a task. + * It provides common properties and methods for tasks. + */ + public abstract class Task { protected String description; protected boolean isDone; + /** + * Constructs a new Task object with the given description. + * @param description The task description + */ Task(String description) { this.description = description; this.isDone = false; } + + /** + * Gets the task description. + * @return The task description + */ public String getDescription() { return description; } + + /** + * Gets a string representing the task status icon (done or not done). + * @return The task status icon string + */ String getStatusIcon() { return (isDone ? "[X]" : "[ ]"); } + /** + * Sets the task as done or not done. + * @param done A boolean indicating whether the task is done or not + */ public void setDone(boolean done) { isDone = done; } + /** + * Returns a string representation of the task. + * @return The string representation + */ @Override public abstract String toString(); + /** + * Returns a string representation of the task suitable for writing to a file. + * @return The string representation + */ public abstract String toFileString(); } \ No newline at end of file diff --git a/src/main/java/TaskFactory.java b/src/main/java/TaskFactory.java new file mode 100644 index 000000000..afded27a2 --- /dev/null +++ b/src/main/java/TaskFactory.java @@ -0,0 +1,141 @@ +/** + * The TaskFactory class is responsible for creating Task objects from user input + * and handling the parsing of task data from file. + */ + +import java.time.format.DateTimeParseException; + +public class TaskFactory { + /** + * Creates a Task object based on the user input. + * + * @param input The user input string containing the task type and details + * @return The created Task object, or null if the input is invalid + * @throws IncyException If the task type or format is invalid + */ + static Task createTask(String input) throws IncyException { + String[] parts = input.split(" ", 2); + String command = parts[0]; + String taskInfo = parts.length > 1 ? parts[1] : ""; + + switch (command.toLowerCase()) { + case "todo": + if (taskInfo.isEmpty()) { + throw new IncyException("Oi! You can't have a todo with no description!"); + } + return new Todo(taskInfo); + case "deadline": + return createDeadline(taskInfo); + case "event": + return createEvent(taskInfo); + default: + throw new IncyException("Hol' up bruv, I dun get what that means..., try typin 'todo', 'deadline', or 'event' first, yeah?"); + } + } + + /** + * Creates a Task object from a line in the data file. + * + * @param line The line from the data file containing the task data + * @return The created Task object, or null if the line is invalid + */ + static Task createTaskFromLine(String line) { + String[] parts = line.split(" \\| ", 3); + if (parts.length < 3) { + return null; + } + String typeCode = parts[0]; + boolean isDone = parts[1].equals("1"); + String taskData = parts[2]; + switch (typeCode) { + case "T": + Todo todo = new Todo(taskData); + todo.setDone(isDone); + return todo; + case "D": + return createDeadlineFromLine(taskData, isDone); + case "E": + return createEventFromLine(taskData, isDone); + default: + return null; + } + } + + /** + * Creates a Deadline object from the user input string. + * @param taskInfo The user input string containing the task description and deadline + * @return The created Deadline object, or null if the input is invalid + */ + private static Task createDeadline(String taskInfo) { + String[] deadlineParts = taskInfo.split(" /by ", 2); + if (deadlineParts.length < 2) { + printFormatError("You've mucked up the deadline format. Do it like 'deadline [task] /by [yyyy-MM-dd HHmm]', yeah?"); + return null; + } + try { + return new Deadline(deadlineParts[0], deadlineParts[1]); + } catch (DateTimeParseException e) { + printFormatError("Invalid date format for deadline. Use 'yyyy-MM-dd HHmm' format, mate."); + return null; + } + } + + /** + * Creates an Event object from the user input string. + * @param taskInfo The user input string containing the task description and event details + * @return The created Event object, or null if the input is invalid + */ + private static Task createEvent(String taskInfo) { + String[] eventParts = taskInfo.split(" /from ", 2); + String[] eventTime = eventParts.length > 1 ? eventParts[1].split(" /to ", 2) : new String[0]; + if (eventParts.length < 2 || eventTime.length < 2) { + printFormatError("You've bungled the event format. It's gotta be 'event [task] /from [yyyy-MM-dd HHmm] /to [yyyy-MM-dd HHmm]', innit?"); + return null; + } + try { + return new Event(eventParts[0], eventTime[0], eventTime[1]); + } catch (DateTimeParseException e) { + printFormatError("Invalid date format for event. Use 'yyyy-MM-dd HHmm' format, mate."); + return null; + } + } + + /** + * Creates a Deadline object from a line in the data file. + * @param line The line from the data file representing a Deadline task + * @return The created Deadline object, or null if the line is invalid + */ + private static Deadline createDeadlineFromLine(String line, boolean isDone) { + String[] parts = line.split(" \\| ", 2); + if (parts.length < 2) { + return null; + } + Deadline deadline = new Deadline(parts[0], parts[1]); + deadline.setDone(isDone); + return deadline; + } + + /** + * Creates an Event object from a line in the data file. + * @param line The line from the data file representing an Event task + * @return The created Event object, or null if the line is invalid + */ + private static Event createEventFromLine(String line, boolean isDone) { + String[] parts = line.split(" \\| ", 3); + if (parts.length < 3) { + return null; + } + Event event = new Event(parts[0], parts[1], parts[2]); + event.setDone(isDone); + return event; + } + + /** + * Prints a format error message to the console. + * @param errorMessage The error message to print + */ + static void printFormatError(String errorMessage) { + System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_RED + "Error: " + errorMessage + "\n" + + Constants.LINE_STRING_BOTTOM); + } +} diff --git a/src/main/java/TaskManager.java b/src/main/java/TaskManager.java new file mode 100644 index 000000000..55e6143c0 --- /dev/null +++ b/src/main/java/TaskManager.java @@ -0,0 +1,231 @@ +/** + * The TaskManager class manages the list of tasks and handles various commands + * related to tasks, such as listing, marking, deleting, finding, and adding tasks. + */ + +import java.util.ArrayList; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.util.Scanner; + +public class TaskManager { + private ArrayList tasks = new ArrayList<>(); + + /** + * Handles the "list" command, displaying all tasks in the list. + */ + void handleListCommand() { + System.out.println(Constants.LINE_STRING_BOTTOM); + if (tasks.isEmpty()) { + System.out.println(Constants.ANSI_RED + "Blimey, your list is empty, innit?"); + } else { + int index = 1; + for (Task task : tasks) { + System.out.println(Constants.ANSI_CYAN + index++ + ". " + task); + } + } + System.out.println(Constants.LINE_STRING_BOTTOM); + } + + /** + * Handles the "mark" and "unmark" commands, marking or unmarking a task as done. + * + * @param input The user input string containing the command and task index + * @param markAsDone A flag indicating whether to mark the task as done (true) or undone (false) + * @throws IncyException If the task index is invalid or the list is empty + */ + void handleMarkCommand(String input, boolean markAsDone) throws IncyException { + if (tasks.isEmpty()) { + throw new IncyException("Nah, mate, nothin' to tick off, yer list's empty!"); + } + + int index = Integer.parseInt(input.substring(markAsDone ? 5 : 7)) - 1; + if (!isValidIndex(index)) { + throw new IncyException("Gimme a legit number, will ya? That one's not on."); + } + + tasks.get(index).setDone(markAsDone); + System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_CYAN + "Banging! This one's sorted!:\n " + tasks.get(index) + "\n" + Constants.LINE_STRING_BOTTOM); + saveTasksToFile(); + } + + /** + * Checks if the given index is a valid index within the tasks list. + * + * @param index The index to check + * @return true if the index is valid, false otherwise + */ + private boolean isValidIndex(int index) { + return index >= 0 && index < tasks.size(); + } + + /** + * Handles the "todo", "deadline", and "event" commands, adding a new task to the list. + * + * @param input The user input string containing the command and task details + * @throws IncyException If the task format is invalid + */ + void handleAddTask(String input) throws IncyException { + Task newTask = TaskFactory.createTask(input); + if (newTask != null) { + tasks.add(newTask); + printTaskAddedMessage(newTask); + saveTasksToFile(); + } + } + + /** + * Handles the "delete" command, removing a task from the list. + * + * @param input The user input string containing the command and task index + * @throws IncyException If the task index is invalid or the list is empty + */ + void handleDeleteCommand(String input) throws IncyException { + if (tasks.isEmpty()) { + throw new IncyException("Oi, nothin' to bin 'ere, yer list's bare!"); + } + + int index = Integer.parseInt(input.substring(7)) - 1; + if (!isValidIndex(index)) { + throw new IncyException("That ain't a legit number, try again with a proper one, yeah?"); + } + + Task deletedTask = tasks.get(index); + removeTaskAt(index); + System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_CYAN + + "Safe! I've dashed this task:\n" + + " " + deletedTask + "\n" + + "Now you've got " + tasks.size() + " tasks on your plate.\n" + + Constants.LINE_STRING_BOTTOM); + saveTasksToFile(); + } + + /** + * Handles the "find" command, searching for tasks containing a given keyword. + * + * @param input The user input string containing the command and keyword + * @throws IncyException If the keyword is missing + */ + void handleFindCommand(String input) throws IncyException { + if (input.length() <= 5) { + throw new IncyException("Oi, you forgot to tell me what to find, mate!"); + } + String keyword = input.substring(5).trim().toLowerCase(); + System.out.println(Constants.LINE_STRING_TOP); + boolean found = false; + int index = 1; + for (Task task : tasks) { + if (task.getDescription().toLowerCase().contains(keyword)) { + System.out.println(Constants.ANSI_CYAN + " " + index++ + ". " + task); + found = true; + } + } + if (!found) { + System.out.println(Constants.ANSI_RED + "No tasks found with the keyword '" + keyword + "', bruv."); + } + System.out.println(Constants.LINE_STRING_BOTTOM); + } + + /** + * Handles the "list by" command, listing tasks for a specific date. + * + * @param input The user input string containing the command and date + * @throws IncyException If the date format is invalid + */ + void handleListByDateCommand(String input) throws IncyException { + String dateString = input.substring(9).trim(); + LocalDate date; + try { + date = LocalDate.parse(dateString, DateTimeFormatter.ofPattern("yyyy-MM-dd")); + } catch (DateTimeParseException e) { + throw new IncyException("Invalid date format, mate. Use 'yyyy-MM-dd' format."); + } + System.out.println(Constants.LINE_STRING_BOTTOM); + boolean found = false; + for (Task task : tasks) { + if (task instanceof Deadline) { + Deadline deadline = (Deadline) task; + if (deadline.getBy().toLocalDate().equals(date)) { + System.out.println(Constants.ANSI_CYAN + "- " + deadline); + found = true; + } + } else if (task instanceof Event) { + Event event = (Event) task; + if (event.getStart().toLocalDate().equals(date) || event.getEnd().toLocalDate().equals(date)) { + System.out.println(Constants.ANSI_CYAN + "- " + event); + found = true; + } + } + } + if (!found) { + System.out.println(Constants.ANSI_RED + "No tasks found for the specified date, bruv."); + } + System.out.println(Constants.LINE_STRING_BOTTOM); + } + + /** + * Removes the task at the given index from the tasks list. + * + * @param index The index of the task to remove + */ + private void removeTaskAt(int index) { + tasks.remove(index); + } + + /** + * Prints a message indicating that a task has been added to the list. + * + * @param task The task that was added + */ + private void printTaskAddedMessage(Task task) { + System.out.println(Constants.LINE_STRING_TOP + Constants.ANSI_CYAN + + "Sorted! Your task's in the bag, innit mate:\n" + + " " + task + "\n" + + "You're now juggling " + tasks.size() + " tasks on your list, innit.\n" + + Constants.LINE_STRING_BOTTOM); + } + + /** + * Loads tasks from the data file and populates the tasks list. + */ + void loadTasksFromFile() { + Path dataFilePath = Paths.get(Constants.DATA_FOLDER, Constants.DATA_FILE); + if (Files.exists(dataFilePath)) { + try { + Scanner scanner = new Scanner(dataFilePath); + while (scanner.hasNextLine()) { + String line = scanner.nextLine(); + Task task = TaskFactory.createTaskFromLine(line); + if (task != null) { + tasks.add(task); + } + } + scanner.close(); + } catch (IOException e) { + TaskFactory.printFormatError("Failed to load tasks from file: " + e.getMessage()); + } + } + } + + /** + * Saves the tasks list to the data file. + */ + void saveTasksToFile() { + Path dataFilePath = Paths.get(Constants.DATA_FOLDER, Constants.DATA_FILE); + try { + FileWriter writer = new FileWriter(dataFilePath.toFile()); + for (Task task : tasks) { + writer.write(task.toFileString() + "\n"); + } + writer.close(); + } catch (IOException e) { + TaskFactory.printFormatError("Failed to save tasks to file: " + e.getMessage()); + } + } +} \ No newline at end of file diff --git a/src/main/java/Todo.java b/src/main/java/Todo.java index a17521f5f..90a59e02f 100644 --- a/src/main/java/Todo.java +++ b/src/main/java/Todo.java @@ -1,13 +1,30 @@ +/** + * The Todo class represents a simple todo task. + * It extends the Task class and does not add any additional properties. + */ + public class Todo extends Task { + /** + * Constructs a new Todo object with the given description. + * @param description The task description + */ public Todo(String description) { super(description); } + /** + * Returns a string representation of the Todo task. + * @return The string representation + */ @Override public String toString() { return "[T]" + super.getStatusIcon() + " " + description; } + /** + * Returns a string representation of the Todo task suitable for writing to a file. + * @return The string representation + */ @Override public String toFileString() { return "T | " + (isDone ? "1" : "0") + " | " + description; From 15d7208b6ed11addbad8a2fc7225ad04b9472998 Mon Sep 17 00:00:00 2001 From: Incy <85068563+IncyBot@users.noreply.github.com> Date: Fri, 8 Mar 2024 01:49:25 +0800 Subject: [PATCH 16/16] Added Description for A-UserGuide --- README.md | 202 ++++++++++++++++++++++++++++++++++++------------- docs/README.md | 186 +++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 322 insertions(+), 66 deletions(-) diff --git a/README.md b/README.md index 5054ca107..39dbda449 100644 --- a/README.md +++ b/README.md @@ -1,89 +1,187 @@ # Incy - The British Task Manager -Incy is a British command-line task management application! It allows you to add, mark, unmark, delete, and list tasks of various types: ToDos, Deadlines, and Events. +## Introduction +Welcome to Incy, your friendly neighborhood task manager! Incy is a command-line application designed to help you stay organized and manage your tasks with ease. Whether you need to keep track of simple to-dos, important deadlines, or upcoming events, Incy has got you covered. + +## Getting Started +### Prerequisites +Before you start using Incy, make sure you have the following: +- Java Development Kit (JDK) installed on your computer +- Basic understanding of command-line interfaces + +### Installation +1. Visit the Incy repository on GitHub: [Incy Repository](https://github.com/IncyBot/ip) +2. Click on the "Code" button and select "Download ZIP" to download the source code as a ZIP file. +3. Extract the ZIP file to a directory of your choice. +4. Open a terminal or command prompt and navigate to the directory where you extracted the source code. + +### Running Incy +1. In the terminal, compile the Java source files by running the following command: + ``` + javac *.java + ``` +2. Once the compilation is successful, you can run Incy using the following command: + ``` + java Incy + ``` +3. Incy will greet you with a friendly message and display the command prompt, ready for you to start managing your tasks. ## Features +Incy offers a range of features to help you stay on top of your tasks: -- Add ToDos, Deadlines, and Events tasks -- Mark tasks as done -- Unmark tasks as not done -- Delete tasks -- List all tasks -- Automatically save and load tasks from a file +### Adding Tasks +Incy supports three types of tasks: to-dos, deadlines, and events. Here's how you can add each type of task: -## Installation +#### To-Do +To add a to-do task, use the following command: +``` +todo [description] +``` +Replace `[description]` with a brief description of your to-do task. -1. Make sure you have Java installed on your system. -2. Clone the repository or download the source code. +Example: +``` +todo Buy groceries +``` -## Usage +#### Deadline +To add a deadline task, use the following command: +``` +deadline [description] /by [date/time] +``` +Replace `[description]` with a brief description of your deadline task, and `[date/time]` with the due date and time of the deadline. -1. Navigate to the project directory in your terminal. -2. Compile the Java files using the following command: +Example: +``` +deadline Submit project report /by 2023-06-30 17:00 +``` +#### Event +To add an event task, use the following command: ``` -javac *.java +event [description] /from [start time] /to [end time] ``` +Replace `[description]` with a brief description of your event task, `[start time]` with the start date and time of the event, and `[end time]` with the end date and time of the event. -3. Run the application with: +Example: +``` +event Team meeting /from 2023-07-01 14:00 /to 2023-07-01 16:00 +``` +### Listing Tasks +To view all your tasks, simply use the `list` command: ``` -java Incy +list ``` +Incy will display a numbered list of all your tasks, along with their details such as task type, description, and due date/time (if applicable). -4. Incy will greet you and prompt you to enter commands. +### Marking Tasks as Done +When you complete a task, you can mark it as done using the `mark` command followed by the task index: +``` +mark [index] +``` +Replace `[index]` with the number corresponding to the task you want to mark as done. -### Commands +Example: +``` +mark 2 +``` -- `todo [description]`: Add a new ToDo task with the given description. -- `deadline [description] /by [date/time]`: Add a new Deadline task with the given description and due date/time. -- `event [description] /from [start time] /to [end time]`: Add a new Event task with the given description, start time, and end time. -- `list`: List all tasks in the task list. -- `mark [index]`: Mark the task at the given index as done. -- `unmark [index]`: Mark the task at the given index as not done. -- `delete [index]`: Delete the task at the given index. -- `bye`: Exit the application. +### Unmarking Tasks +If you accidentally marked a task as done or need to reopen a task, you can use the `unmark` command followed by the task index: +``` +unmark [index] +``` +Replace `[index]` with the number corresponding to the task you want to unmark. -**Note:** Indices for mark, unmark, and delete commands start from 1. +Example: +``` +unmark 3 +``` -### Task Storage +### Deleting Tasks +To remove a task from your list, use the `delete` command followed by the task index: +``` +delete [index] +``` +Replace `[index]` with the number corresponding to the task you want to delete. -Incy automatically saves your tasks to a file named `incy_tasks.txt` in the `data` folder within the project directory. If the `data` folder doesn't exist, it will be created automatically. If the `incy_tasks.txt` file doesn't exist, a new file will be created when you add your first task. +Example: +``` +delete 1 +``` + +### Finding Tasks +If you have a long list of tasks and want to quickly find specific tasks, you can use the `find` command followed by a keyword: +``` +find [keyword] +``` +Replace `[keyword]` with the word or phrase you want to search for in your task descriptions. + +Example: +``` +find project +``` +Incy will display a list of tasks that contain the specified keyword in their descriptions. -### File Format +### Listing Tasks by Date +To view tasks scheduled for a specific date, use the `list by` command followed by the date: +``` +list by [date] +``` +Replace `[date]` with the desired date in the format `yyyy-MM-dd`. -The task data is stored in the `incy_tasks.txt` file using the following format: +Example: +``` +list by 2023-06-30 +``` +Incy will display a list of tasks scheduled for the specified date. +### Exiting Incy +When you're done managing your tasks and want to exit Incy, simply type `bye`: ``` -T | 0 | read book -D | 1 | return book | June 6th -E | 0 | project meeting | Aug 6th 2-4pm | Aug 6th 6-8pm +bye ``` +Incy will save your tasks and bid you farewell. + +## Data Persistence +Incy automatically saves your tasks to a file named `incy_tasks.txt` located in the `data` folder within the project directory. This ensures that your tasks are preserved even after you exit the application. -- `T` represents a ToDo task, `D` represents a Deadline task, and `E` represents an Event task. -- The second value (`0` or `1`) indicates whether the task is done or not. -- The remaining values represent the task description and additional details (due date for Deadlines, start and end times for Events). +When you start Incy, it loads the tasks from the `incy_tasks.txt` file, allowing you to pick up where you left off. -If the file becomes corrupted or contains invalid data, Incy will skip the corrupted lines and load the valid tasks. +If the `data` folder or the `incy_tasks.txt` file doesn't exist, Incy will create them automatically when you add your first task. -## Code Structure +## Error Handling +Incy is designed to handle common errors gracefully. If you enter an invalid command or provide incorrect input, Incy will display an appropriate error message and prompt you to try again. -The application is structured into the following classes: +If the `incy_tasks.txt` file becomes corrupted or contains invalid data, Incy will skip the corrupted lines and load only the valid tasks. -- `Incy`: The main class that handles user input and interaction. -- `TaskManager`: Manages the task list and handles commands related to tasks. -- `TaskFactory`: Responsible for creating tasks from user input and file data. -- `Task`: Abstract base class for different task types. -- `Todo`: Represents a ToDo task. -- `Deadline`: Represents a Deadline task. -- `Event`: Represents an Event task. -- `IncyException`: Custom exception class used for handling errors. +## Customization +Incy's source code is well-structured and modular, making it easy to customize and extend its functionality. The main classes in the project are: + +- `Incy`: The entry point of the application, handling user input and interaction. +- `TaskManager`: Manages the task list and provides methods for adding, marking, unmarking, deleting, and listing tasks. +- `TaskFactory`: Responsible for creating task objects based on user input and file data. +- `Task`: An abstract base class representing a generic task. +- `Todo`, `Deadline`, `Event`: Concrete classes extending the `Task` class, representing specific types of tasks. +- `IncyException`: A custom exception class for handling Incy-specific errors. - `Constants`: Contains constant values used throughout the application. -## Dependencies +Feel free to explore the source code and make modifications to suit your specific needs. + +## Troubleshooting +If you encounter any issues while using Incy, consider the following troubleshooting steps: + +1. Make sure you have Java Development Kit (JDK) installed and properly set up on your computer. +2. Verify that you are running Incy from the correct directory where the source code files are located. +3. Check that you have the necessary permissions to read from and write to the `data` folder and `incy_tasks.txt` file. +4. If you encounter any error messages, carefully read the message and refer to the relevant section in this user guide for guidance. + +If the issue persists, feel free to open an issue on the Incy GitHub repository, providing detailed information about the problem you encountered. -This application has no external dependencies and only uses the built-in Java libraries. +## Conclusion +Incy is a user-friendly and efficient task manager designed to simplify your life. With its intuitive commands and seamless data persistence, Incy helps you stay organized and on top of your tasks. -## Contributing +So, go ahead and give Incy a try! Let it be your trusted companion in tackling your tasks and achieving your goals. -Contributions to Incy are welcome! If you find any bugs or have suggestions for improvements, please open an issue or submit a pull request. \ No newline at end of file +Happy task managing with Incy! \ No newline at end of file diff --git a/docs/README.md b/docs/README.md index 8077118eb..39dbda449 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,29 +1,187 @@ -# User Guide +# Incy - The British Task Manager -## Features +## Introduction +Welcome to Incy, your friendly neighborhood task manager! Incy is a command-line application designed to help you stay organized and manage your tasks with ease. Whether you need to keep track of simple to-dos, important deadlines, or upcoming events, Incy has got you covered. -### Feature-ABC +## Getting Started +### Prerequisites +Before you start using Incy, make sure you have the following: +- Java Development Kit (JDK) installed on your computer +- Basic understanding of command-line interfaces -Description of the feature. +### Installation +1. Visit the Incy repository on GitHub: [Incy Repository](https://github.com/IncyBot/ip) +2. Click on the "Code" button and select "Download ZIP" to download the source code as a ZIP file. +3. Extract the ZIP file to a directory of your choice. +4. Open a terminal or command prompt and navigate to the directory where you extracted the source code. -### Feature-XYZ +### Running Incy +1. In the terminal, compile the Java source files by running the following command: + ``` + javac *.java + ``` +2. Once the compilation is successful, you can run Incy using the following command: + ``` + java Incy + ``` +3. Incy will greet you with a friendly message and display the command prompt, ready for you to start managing your tasks. -Description of the feature. +## Features +Incy offers a range of features to help you stay on top of your tasks: -## Usage +### Adding Tasks +Incy supports three types of tasks: to-dos, deadlines, and events. Here's how you can add each type of task: -### `Keyword` - Describe action +#### To-Do +To add a to-do task, use the following command: +``` +todo [description] +``` +Replace `[description]` with a brief description of your to-do task. + +Example: +``` +todo Buy groceries +``` + +#### Deadline +To add a deadline task, use the following command: +``` +deadline [description] /by [date/time] +``` +Replace `[description]` with a brief description of your deadline task, and `[date/time]` with the due date and time of the deadline. + +Example: +``` +deadline Submit project report /by 2023-06-30 17:00 +``` + +#### Event +To add an event task, use the following command: +``` +event [description] /from [start time] /to [end time] +``` +Replace `[description]` with a brief description of your event task, `[start time]` with the start date and time of the event, and `[end time]` with the end date and time of the event. + +Example: +``` +event Team meeting /from 2023-07-01 14:00 /to 2023-07-01 16:00 +``` -Describe the action and its outcome. +### Listing Tasks +To view all your tasks, simply use the `list` command: +``` +list +``` +Incy will display a numbered list of all your tasks, along with their details such as task type, description, and due date/time (if applicable). -Example of usage: +### Marking Tasks as Done +When you complete a task, you can mark it as done using the `mark` command followed by the task index: +``` +mark [index] +``` +Replace `[index]` with the number corresponding to the task you want to mark as done. -`keyword (optional arguments)` +Example: +``` +mark 2 +``` -Expected outcome: +### Unmarking Tasks +If you accidentally marked a task as done or need to reopen a task, you can use the `unmark` command followed by the task index: +``` +unmark [index] +``` +Replace `[index]` with the number corresponding to the task you want to unmark. -Description of the outcome. +Example: +``` +unmark 3 +``` + +### Deleting Tasks +To remove a task from your list, use the `delete` command followed by the task index: +``` +delete [index] +``` +Replace `[index]` with the number corresponding to the task you want to delete. +Example: ``` -expected output +delete 1 ``` + +### Finding Tasks +If you have a long list of tasks and want to quickly find specific tasks, you can use the `find` command followed by a keyword: +``` +find [keyword] +``` +Replace `[keyword]` with the word or phrase you want to search for in your task descriptions. + +Example: +``` +find project +``` +Incy will display a list of tasks that contain the specified keyword in their descriptions. + +### Listing Tasks by Date +To view tasks scheduled for a specific date, use the `list by` command followed by the date: +``` +list by [date] +``` +Replace `[date]` with the desired date in the format `yyyy-MM-dd`. + +Example: +``` +list by 2023-06-30 +``` +Incy will display a list of tasks scheduled for the specified date. + +### Exiting Incy +When you're done managing your tasks and want to exit Incy, simply type `bye`: +``` +bye +``` +Incy will save your tasks and bid you farewell. + +## Data Persistence +Incy automatically saves your tasks to a file named `incy_tasks.txt` located in the `data` folder within the project directory. This ensures that your tasks are preserved even after you exit the application. + +When you start Incy, it loads the tasks from the `incy_tasks.txt` file, allowing you to pick up where you left off. + +If the `data` folder or the `incy_tasks.txt` file doesn't exist, Incy will create them automatically when you add your first task. + +## Error Handling +Incy is designed to handle common errors gracefully. If you enter an invalid command or provide incorrect input, Incy will display an appropriate error message and prompt you to try again. + +If the `incy_tasks.txt` file becomes corrupted or contains invalid data, Incy will skip the corrupted lines and load only the valid tasks. + +## Customization +Incy's source code is well-structured and modular, making it easy to customize and extend its functionality. The main classes in the project are: + +- `Incy`: The entry point of the application, handling user input and interaction. +- `TaskManager`: Manages the task list and provides methods for adding, marking, unmarking, deleting, and listing tasks. +- `TaskFactory`: Responsible for creating task objects based on user input and file data. +- `Task`: An abstract base class representing a generic task. +- `Todo`, `Deadline`, `Event`: Concrete classes extending the `Task` class, representing specific types of tasks. +- `IncyException`: A custom exception class for handling Incy-specific errors. +- `Constants`: Contains constant values used throughout the application. + +Feel free to explore the source code and make modifications to suit your specific needs. + +## Troubleshooting +If you encounter any issues while using Incy, consider the following troubleshooting steps: + +1. Make sure you have Java Development Kit (JDK) installed and properly set up on your computer. +2. Verify that you are running Incy from the correct directory where the source code files are located. +3. Check that you have the necessary permissions to read from and write to the `data` folder and `incy_tasks.txt` file. +4. If you encounter any error messages, carefully read the message and refer to the relevant section in this user guide for guidance. + +If the issue persists, feel free to open an issue on the Incy GitHub repository, providing detailed information about the problem you encountered. + +## Conclusion +Incy is a user-friendly and efficient task manager designed to simplify your life. With its intuitive commands and seamless data persistence, Incy helps you stay organized and on top of your tasks. + +So, go ahead and give Incy a try! Let it be your trusted companion in tackling your tasks and achieving your goals. + +Happy task managing with Incy! \ No newline at end of file