From df35b4d6431b7ab3a5054b0116ff1becf7fac64b Mon Sep 17 00:00:00 2001 From: WEIFENG-NUSCEG Date: Tue, 10 Sep 2019 11:41:29 +0800 Subject: [PATCH 001/420] Code transfered from WEI FENG --- src/main/java/AddCommand.java | 19 +++++++ src/main/java/Command.java | 6 +++ src/main/java/Deadline.java | 41 +++++++++++++++ src/main/java/DeleteCommand.java | 26 ++++++++++ src/main/java/DoneCommand.java | 28 ++++++++++ src/main/java/Duke.java | 51 +++++++++++++++--- src/main/java/DukeExceptionThrow.java | 6 +++ src/main/java/Events.java | 38 ++++++++++++++ src/main/java/ExitCommand.java | 15 ++++++ src/main/java/FindCommand.java | 18 +++++++ src/main/java/ListCommand.java | 15 ++++++ src/main/java/Parser.java | 50 ++++++++++++++++++ src/main/java/Storage.java | 75 +++++++++++++++++++++++++++ src/main/java/Task.java | 35 +++++++++++++ src/main/java/TaskList.java | 36 +++++++++++++ src/main/java/ToDos.java | 24 +++++++++ src/main/java/Ui.java | 73 ++++++++++++++++++++++++++ src/test/java/DukeTest.java | 10 ++++ 18 files changed, 560 insertions(+), 6 deletions(-) create mode 100644 src/main/java/AddCommand.java create mode 100644 src/main/java/Command.java create mode 100644 src/main/java/Deadline.java create mode 100644 src/main/java/DeleteCommand.java create mode 100644 src/main/java/DoneCommand.java create mode 100644 src/main/java/DukeExceptionThrow.java create mode 100644 src/main/java/Events.java create mode 100644 src/main/java/ExitCommand.java create mode 100644 src/main/java/FindCommand.java create mode 100644 src/main/java/ListCommand.java create mode 100644 src/main/java/Parser.java create mode 100644 src/main/java/Storage.java create mode 100644 src/main/java/Task.java create mode 100644 src/main/java/TaskList.java create mode 100644 src/main/java/ToDos.java create mode 100644 src/main/java/Ui.java create mode 100644 src/test/java/DukeTest.java diff --git a/src/main/java/AddCommand.java b/src/main/java/AddCommand.java new file mode 100644 index 0000000000..bff655135d --- /dev/null +++ b/src/main/java/AddCommand.java @@ -0,0 +1,19 @@ +public class AddCommand extends Command { + private Task t; + + public AddCommand(Task tt) { + super(); + this.t = tt; + } + + @Override + public boolean isExit() { + return false; + } + @Override + public void run(TaskList tasks, Ui ui, Storage storage) throws DukeExceptionThrow { + tasks.addTask(t); + ui.taskAdded(t, tasks.getSize()); + storage.save(tasks.fullTaskList()); + } +} diff --git a/src/main/java/Command.java b/src/main/java/Command.java new file mode 100644 index 0000000000..c83b41816a --- /dev/null +++ b/src/main/java/Command.java @@ -0,0 +1,6 @@ +public abstract class Command { + + abstract void run(TaskList tasks, Ui ui, Storage storage) throws DukeExceptionThrow; + abstract boolean isExit(); + +} \ No newline at end of file diff --git a/src/main/java/Deadline.java b/src/main/java/Deadline.java new file mode 100644 index 0000000000..05ba3c244a --- /dev/null +++ b/src/main/java/Deadline.java @@ -0,0 +1,41 @@ +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; + +public class Deadline extends Task { + + protected String by; + protected LocalDateTime localDateTime; + + public Deadline(String description, String by) + { + super(description); + this.by = by; + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HHmm"); + try + { + localDateTime = LocalDateTime.parse(by, formatter); + } + catch (DateTimeParseException e) + { + System.out.println(e.getMessage()); + } + } + + @Override + public String toString() { + return "[D]" + super.printStatus() + " (by: " + localDateTime + ")"; + } + + public String txtFormat() { + return "D | " + (this.isDone ? "1" : "0") + " | " + this.description + " | " + this.localDateTime; + } + + public String writeTxt(){ + return "D | " + (this.isDone ? "1" : "0") + " | " + this.description + " | " + this.by; + } + + + +} \ No newline at end of file diff --git a/src/main/java/DeleteCommand.java b/src/main/java/DeleteCommand.java new file mode 100644 index 0000000000..1a8b7ee516 --- /dev/null +++ b/src/main/java/DeleteCommand.java @@ -0,0 +1,26 @@ +public class DeleteCommand extends Command { + private int Id; + + public DeleteCommand(int taskId) { + super(); + this.Id = taskId; + } + + @Override + public boolean isExit() { + return false; + } + + public void run(TaskList tasks, Ui ui, Storage storage) throws DukeExceptionThrow { + try { + Task t = tasks.getTask(Id); + tasks.deleteTask(Id); + ui.taskRemoved(t, tasks.getSize()); + storage.save(tasks.fullTaskList()); + } + catch (IndexOutOfBoundsException e) + { + ui.showError(e.getMessage()); + } + } +} diff --git a/src/main/java/DoneCommand.java b/src/main/java/DoneCommand.java new file mode 100644 index 0000000000..05d181bb83 --- /dev/null +++ b/src/main/java/DoneCommand.java @@ -0,0 +1,28 @@ +public class DoneCommand extends Command { + private int Id; + + public DoneCommand(int taskId) { + super(); + this.Id = taskId; + } + + @Override + public boolean isExit() { + return false; + } + + @Override + public void run(TaskList tasks, Ui ui, Storage storage) throws DukeExceptionThrow { + try + { + Task t = tasks.getTask(Id); + t.markAsDone(); + storage.save(tasks.fullTaskList()); + ui.markedAsDone(t); + } + catch (IndexOutOfBoundsException e) + { + ui.showError(e.getMessage()); + } + } +} diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 5d313334cc..a5095e1d60 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,10 +1,49 @@ +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; + + + public class Duke { + private Storage storage; + private TaskList tasks; + private Ui ui; + + public Duke(String filePath) { + ui = new Ui(); + storage = new Storage(filePath); + try { + tasks = new TaskList(storage.load()); + } catch (DukeExceptionThrow e) { + ui.showLoadingError(); + tasks = new TaskList(); + } + } + + public void run() { + ui.showWelcome(); + boolean isExit = false; + while (!isExit) { + try { + String fullCommand = ui.readCommand(); + ui.showLine(); + Command c = Parser.Parse(Parser.stringSplit(fullCommand)); + c.run(tasks, ui, storage); + isExit = c.isExit(); + } catch (DukeExceptionThrow e) { + ui.showError(e.getMessage()); + } finally { + ui.showLine(); + } + } + } + public static void main(String[] args) { - String logo = " ____ _ \n" - + "| _ \\ _ _| | _____ \n" - + "| | | | | | | |/ / _ \\\n" - + "| |_| | |_| | < __/\n" - + "|____/ \\__,_|_|\\_\\___|\n"; - System.out.println("Hello from\n" + logo); + new Duke("./data/duke.txt").run(); } } diff --git a/src/main/java/DukeExceptionThrow.java b/src/main/java/DukeExceptionThrow.java new file mode 100644 index 0000000000..990826c05f --- /dev/null +++ b/src/main/java/DukeExceptionThrow.java @@ -0,0 +1,6 @@ +class DukeExceptionThrow extends Exception +{ + public DukeExceptionThrow(String message) { + super(message); + } +} \ No newline at end of file diff --git a/src/main/java/Events.java b/src/main/java/Events.java new file mode 100644 index 0000000000..773de68150 --- /dev/null +++ b/src/main/java/Events.java @@ -0,0 +1,38 @@ +import java.time.DateTimeException; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; + +public class Events extends Task { + + protected String at; + protected LocalDateTime localDateTime; + + public Events(String description, String at) { + super(description); + this.at = at; + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HHmm"); + try + { + localDateTime = LocalDateTime.parse(at, formatter); + } + catch (DateTimeParseException e) + { + System.out.println("Wrong date and time format!"); + } + + } + + @Override + public String toString() { + return "[E]" + super.printStatus() + " (at: " + localDateTime + ")"; + } + + public String txtFormat() { + return "E | " + (this.isDone ? "1" : "0") + " | " + this.description + " | " + this.localDateTime; + } + + public String writeTxt(){ + return "E | " + (this.isDone ? "1" : "0") + " | " + this.description + " | " + this.at; + } +} \ No newline at end of file diff --git a/src/main/java/ExitCommand.java b/src/main/java/ExitCommand.java new file mode 100644 index 0000000000..0357ec5117 --- /dev/null +++ b/src/main/java/ExitCommand.java @@ -0,0 +1,15 @@ +public class ExitCommand extends Command { + public ExitCommand() { + super(); + } + + @Override + public boolean isExit() { + return true; + } + + @Override + public void run(TaskList tasks, Ui ui, Storage storage) { + ui.exitInformation(); + } +} \ No newline at end of file diff --git a/src/main/java/FindCommand.java b/src/main/java/FindCommand.java new file mode 100644 index 0000000000..b229fd0f79 --- /dev/null +++ b/src/main/java/FindCommand.java @@ -0,0 +1,18 @@ +public class FindCommand extends Command { + private String taskName; + + public FindCommand(String name) { + super(); + this.taskName = name; + } + + @Override + public boolean isExit() { + return false; + } + + @Override + public void run(TaskList tasks, Ui ui, Storage storage) throws DukeExceptionThrow { + ui.taskFound(tasks.fullTaskList(), taskName); + } +} \ No newline at end of file diff --git a/src/main/java/ListCommand.java b/src/main/java/ListCommand.java new file mode 100644 index 0000000000..df29e07435 --- /dev/null +++ b/src/main/java/ListCommand.java @@ -0,0 +1,15 @@ +class ListCommand extends Command { + public ListCommand() { + super(); + } + + @Override + public boolean isExit() { + return false; + } + + @Override + public void run(TaskList tasks, Ui ui, Storage storage) { + ui.listTasks(tasks); + } +} \ No newline at end of file diff --git a/src/main/java/Parser.java b/src/main/java/Parser.java new file mode 100644 index 0000000000..1ec1c4598c --- /dev/null +++ b/src/main/java/Parser.java @@ -0,0 +1,50 @@ +import java.util.Scanner; + +public class Parser { + private static String[] substring; + + public static String[] stringSplit(String ss) + { + String temp1 = ss; + return substring = temp1.split(" ", 2); + } + + public static Command Parse(String[] command) throws DukeExceptionThrow + { + try + { + switch (command[0]) { + case "list": + return new ListCommand(); + case "done": + int i = Integer.parseInt(command[1]); + return new DoneCommand(i); + case "delete": + int x = Integer.parseInt(command[1]); + return new DeleteCommand(x); + case "todo": + ToDos t = new ToDos(command[1]); + return new AddCommand(t); + case "deadline": + String[] temp = command[1].split("/by"); + Deadline d = new Deadline(temp[0], temp[1]); + return new AddCommand(d); + case "event": + String[] temp1 = command[1].split("/at"); + Events z = new Events(temp1[0], temp1[1]); + return new AddCommand(z); + case "find": + return new FindCommand(command[1]); + case "bye": + return new ExitCommand(); + default: + throw new DukeExceptionThrow("Unrecognized user input!"); + } + } + catch (DukeExceptionThrow e) + { + throw new DukeExceptionThrow("Fail to recognize the command"); + } + } + +} diff --git a/src/main/java/Storage.java b/src/main/java/Storage.java new file mode 100644 index 0000000000..d4e01a23fe --- /dev/null +++ b/src/main/java/Storage.java @@ -0,0 +1,75 @@ +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; + +public class Storage { + private String filePath; + + public Storage(String path) { + this.filePath = path; + } + + public ArrayList load() throws DukeExceptionThrow + { + File newDuke = new File(filePath); + ArrayList tasks = new ArrayList<>(); + try { + Scanner ss = new Scanner(newDuke); + while (ss.hasNext()) { + String[] newTask = ss.nextLine().split(" \\| "); + if (newTask[0].equals("T")) + { + Task x = new ToDos(newTask[2]); + if (newTask[1].equals("1")) + { + x.markAsDone(); + } + tasks.add(x); + } + if (newTask[0].equals("D")) + { + Task t = new Deadline(newTask[2], newTask[3]); + if (newTask[1].equals("1")) + { + t.markAsDone(); + } + tasks.add(t); + } + if (newTask[0].equals("E")) + { + Task t = new Events(newTask[2], newTask[3]); + if (newTask[1].equals("1")) + { + t.markAsDone(); + } + tasks.add(t); + } + + } + return tasks; + } + catch (FileNotFoundException e) + { + throw new DukeExceptionThrow("File is not found!"); + } + } + + public void save(ArrayList task) { + try { + FileWriter ww = new FileWriter("./data/duke.txt"); + for (Task t : task) + { + ww.write(t.writeTxt() + System.lineSeparator()); + } + ww.close(); + } catch (IOException e) + { + System.out.println("File writing process encounters an error " + e.getMessage()); + } + } + +} diff --git a/src/main/java/Task.java b/src/main/java/Task.java new file mode 100644 index 0000000000..32d95691fb --- /dev/null +++ b/src/main/java/Task.java @@ -0,0 +1,35 @@ + +public abstract class Task { + protected String description; + protected boolean isDone; + + + public Task(String description) { + this.description = description; + this.isDone = false; + } + + public String getStatusIcon() { + return (isDone ? "\u2713" : "\u2718"); //return tick or X symbols + } + + abstract String txtFormat(); + + abstract String writeTxt(); + + public void markAsDone() + { + isDone = true; + } + + public String printStatus() + { + return "[" + this.getStatusIcon() + "] " + description; + } + + public String getDescription(){ + return description; + } + + +} \ No newline at end of file diff --git a/src/main/java/TaskList.java b/src/main/java/TaskList.java new file mode 100644 index 0000000000..286a21c8c5 --- /dev/null +++ b/src/main/java/TaskList.java @@ -0,0 +1,36 @@ +import java.util.ArrayList; + +public class TaskList { + protected ArrayList taskList; + + public TaskList(ArrayList task) { + this.taskList = task; + } + + public ArrayList fullTaskList(){ + return taskList; + } + + public void addTask(Task t) { + taskList.add(t); + } + + public void deleteTask(Integer i) throws IndexOutOfBoundsException { + taskList.remove(i - 1); + } + + public Task getTask(int i) throws IndexOutOfBoundsException { + return taskList.get(i - 1); + } + + public int getSize() { + return taskList.size(); + } + + public TaskList(){ + taskList = new ArrayList(); + } + + + +} diff --git a/src/main/java/ToDos.java b/src/main/java/ToDos.java new file mode 100644 index 0000000000..37dc7ab206 --- /dev/null +++ b/src/main/java/ToDos.java @@ -0,0 +1,24 @@ +public class ToDos extends Task { + + protected boolean isToDo; + + public ToDos(String description) { + super(description); + this.isToDo = true; + } + + @Override + public String toString() { + return "[T]" + super.printStatus(); + } + + public String txtFormat() { + return "T | " + (this.isDone ? "1" : "0") + " | " + this.description; + } + + + public String writeTxt(){ + return "T | " + (this.isDone ? "1" : "0") + " | " + this.description; + } + +} \ No newline at end of file diff --git a/src/main/java/Ui.java b/src/main/java/Ui.java new file mode 100644 index 0000000000..6fe6d8fa69 --- /dev/null +++ b/src/main/java/Ui.java @@ -0,0 +1,73 @@ +import java.util.ArrayList; +import java.util.Scanner; + +public class Ui { + private Scanner sc; + + public Ui() { + sc = new Scanner(System.in); + } + + public String readCommand() { + return sc.nextLine(); + } + + public void showError(String e) { + System.out.println( "☹ OOPS!!!" + e); + } + + public void taskAdded(Task t, int size) { + System.out.println("Got it. I've added this task: \n " + t.toString() + "\nNow you have " + + size + " tasks in the list."); + } + + public void markedAsDone(Task t) { + System.out.println("Nice! I've marked this task as done: \n " + t.printStatus()); + } + + public void taskRemoved(Task t, int size) { + System.out.println("Noted. I've removed this task: \n " + t.toString() + "\nNow you have " + + size + " tasks in the list."); + } + + public void taskFound(ArrayList a, String name){ + System.out.println("Here are the matching tasks in your list:"); + int count = 1; + for (Task x : a) { + if (x.getDescription().contains(name)) { + System.out.println(count + "." + x.toString()); + count++; + } + } + } + + public void showLine() { + System.out.println("____________________________________________________________"); + } + + public void listTasks(TaskList tasks) { + System.out.println("Here are the tasks in your list:"); + for (int i = 1; i <= tasks.getSize() ; i++) + { + System.out.println( i + "." + tasks.getTask(i).toString()); + } + } + + public void exitInformation(){ + System.out.println("Bye. Hope to see you again soon!"); + } + + public void showWelcome() { + String logo = " ____ _ \n" + + "| _ \\ _ _| | _____ \n" + + "| | | | | | | |/ / _ \\\n" + + "| |_| | |_| | < __/\n" + + "|____/ \\__,_|_|\\_\\___|\n"; + System.out.println("Hello from\n" + logo); + System.out.println("Hello! I'm Duke\nWhat can I do for you?"); + } + + public void showLoadingError() { + System.out.println("Failed to Load from local text file!"); + } +} diff --git a/src/test/java/DukeTest.java b/src/test/java/DukeTest.java new file mode 100644 index 0000000000..8a14575adc --- /dev/null +++ b/src/test/java/DukeTest.java @@ -0,0 +1,10 @@ +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class DukeTest { + @Test + public void dummyTest(){ + assertEquals(2, 2); + } +} \ No newline at end of file From 2caab6eaa13d430f80ef34206eccde098b18526d Mon Sep 17 00:00:00 2001 From: WEIFENG-NUSCEG Date: Tue, 10 Sep 2019 12:43:16 +0800 Subject: [PATCH 002/420] Improved the Date and Time Display --- data/duke.txt | 11 +++++++++++ src/main/java/Deadline.java | 15 +++------------ src/main/java/Events.java | 15 ++------------- src/main/java/Task.java | 34 ++++++++++++++++++++++++++++++++++ src/test/java/DukeTest.java | 20 ++++++++++---------- 5 files changed, 60 insertions(+), 35 deletions(-) create mode 100644 data/duke.txt diff --git a/data/duke.txt b/data/duke.txt new file mode 100644 index 0000000000..c5b583db13 --- /dev/null +++ b/data/duke.txt @@ -0,0 +1,11 @@ +D | 1 | return book | 03/04/2019 1800 +E | 1 | project meeting | 05/11/2019 1503 +T | 1 | join sports club +T | 1 | designduke +E | 1 | breakfast | 11/12/2019 1400 +T | 0 | assignment1 +D | 0 | project meeting | 10/05/2019 1530 +E | 1 | project meeting | 12/05/2019 0700 +E | 1 | breakfast | 12/08/2019 1530 +D | 0 | ssss | 21/08/2018 1400 +E | 0 | qweqweqe | 23/09/2012 1400 diff --git a/src/main/java/Deadline.java b/src/main/java/Deadline.java index 05ba3c244a..fca799f920 100644 --- a/src/main/java/Deadline.java +++ b/src/main/java/Deadline.java @@ -1,3 +1,4 @@ +import java.text.ParseException; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; @@ -6,30 +7,20 @@ public class Deadline extends Task { protected String by; - protected LocalDateTime localDateTime; public Deadline(String description, String by) { super(description); this.by = by; - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HHmm"); - try - { - localDateTime = LocalDateTime.parse(by, formatter); - } - catch (DateTimeParseException e) - { - System.out.println(e.getMessage()); - } } @Override public String toString() { - return "[D]" + super.printStatus() + " (by: " + localDateTime + ")"; + return "[D]" + super.printStatus() + " (by: " + super.timeFormatter(by) + ")"; } public String txtFormat() { - return "D | " + (this.isDone ? "1" : "0") + " | " + this.description + " | " + this.localDateTime; + return "D | " + (this.isDone ? "1" : "0") + " | " + this.description + " | " + super.timeFormatter(by); } public String writeTxt(){ diff --git a/src/main/java/Events.java b/src/main/java/Events.java index 773de68150..e2beec0b34 100644 --- a/src/main/java/Events.java +++ b/src/main/java/Events.java @@ -6,30 +6,19 @@ public class Events extends Task { protected String at; - protected LocalDateTime localDateTime; public Events(String description, String at) { super(description); this.at = at; - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HHmm"); - try - { - localDateTime = LocalDateTime.parse(at, formatter); - } - catch (DateTimeParseException e) - { - System.out.println("Wrong date and time format!"); - } - } @Override public String toString() { - return "[E]" + super.printStatus() + " (at: " + localDateTime + ")"; + return "[E]" + super.printStatus() + " (at: " + super.timeFormatter(at) + ")"; } public String txtFormat() { - return "E | " + (this.isDone ? "1" : "0") + " | " + this.description + " | " + this.localDateTime; + return "E | " + (this.isDone ? "1" : "0") + " | " + this.description + " | " + super.timeFormatter(at); } public String writeTxt(){ diff --git a/src/main/java/Task.java b/src/main/java/Task.java index 32d95691fb..f22484d4b9 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -1,7 +1,16 @@ +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.util.Date; public abstract class Task { protected String description; protected boolean isDone; + protected LocalDateTime ld; public Task(String description) { @@ -31,5 +40,30 @@ public String getDescription(){ return description; } + public String timeFormatter(String timeBeforeFormat) { + DateTimeFormatter parser = DateTimeFormatter.ofPattern("dd/MM/yyyy HHmm"); + DateTimeFormatter stFormatter = DateTimeFormatter.ofPattern("d'st of' MMMM yyyy , ha"); + DateTimeFormatter ndFormatter = DateTimeFormatter.ofPattern("d'nd of' MMMM yyyy , ha"); + DateTimeFormatter rdFormatter = DateTimeFormatter.ofPattern("d'rd of' MMMM yyyy , ha"); + DateTimeFormatter thFormatter = DateTimeFormatter.ofPattern("d'th of' MMMM yyyy , ha"); + + ld = LocalDateTime.parse(timeBeforeFormat,parser); + + String output; + + if ((ld.getDayOfMonth()%10) == 1){ + output = ld.format(stFormatter); + }else if ((ld.getDayOfMonth()%10) == 2) { + output = ld.format(ndFormatter); + }else if ((ld.getDayOfMonth()%10) == 3) { + output = ld.format(rdFormatter); + }else{ + output = ld.format(thFormatter);; + } + + return output; + + } + } \ No newline at end of file diff --git a/src/test/java/DukeTest.java b/src/test/java/DukeTest.java index 8a14575adc..34ee8cc818 100644 --- a/src/test/java/DukeTest.java +++ b/src/test/java/DukeTest.java @@ -1,10 +1,10 @@ -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class DukeTest { - @Test - public void dummyTest(){ - assertEquals(2, 2); - } -} \ No newline at end of file +//import org.junit.jupiter.api.Test; +// +//import static org.junit.jupiter.api.Assertions.assertEquals; +// +//public class DukeTest { +// @Test +// public void dummyTest(){ +// assertEquals(2, 2); +// } +//} \ No newline at end of file From 76cfacd60a367299c530fa0ebef4506bf3dff828 Mon Sep 17 00:00:00 2001 From: WEIFENG-NUSCEG Date: Tue, 10 Sep 2019 12:48:49 +0800 Subject: [PATCH 003/420] updated the string parsing method --- data/duke.txt | 3 +-- src/main/java/Duke.java | 2 +- src/main/java/Parser.java | 13 ++++--------- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/data/duke.txt b/data/duke.txt index c5b583db13..ecb10d7478 100644 --- a/data/duke.txt +++ b/data/duke.txt @@ -7,5 +7,4 @@ T | 0 | assignment1 D | 0 | project meeting | 10/05/2019 1530 E | 1 | project meeting | 12/05/2019 0700 E | 1 | breakfast | 12/08/2019 1530 -D | 0 | ssss | 21/08/2018 1400 -E | 0 | qweqweqe | 23/09/2012 1400 +D | 1 | ssss | 21/08/2018 1400 diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index a5095e1d60..cc80005f3a 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -32,7 +32,7 @@ public void run() { try { String fullCommand = ui.readCommand(); ui.showLine(); - Command c = Parser.Parse(Parser.stringSplit(fullCommand)); + Command c = Parser.Parse(fullCommand); c.run(tasks, ui, storage); isExit = c.isExit(); } catch (DukeExceptionThrow e) { diff --git a/src/main/java/Parser.java b/src/main/java/Parser.java index 1ec1c4598c..ba43228581 100644 --- a/src/main/java/Parser.java +++ b/src/main/java/Parser.java @@ -3,14 +3,9 @@ public class Parser { private static String[] substring; - public static String[] stringSplit(String ss) - { - String temp1 = ss; - return substring = temp1.split(" ", 2); - } - - public static Command Parse(String[] command) throws DukeExceptionThrow + public static Command Parse(String ss) throws DukeExceptionThrow { + String[] command = ss.split(" ", 2); try { switch (command[0]) { @@ -26,11 +21,11 @@ public static Command Parse(String[] command) throws DukeExceptionThrow ToDos t = new ToDos(command[1]); return new AddCommand(t); case "deadline": - String[] temp = command[1].split("/by"); + String[] temp = command[1].split(" /by "); Deadline d = new Deadline(temp[0], temp[1]); return new AddCommand(d); case "event": - String[] temp1 = command[1].split("/at"); + String[] temp1 = command[1].split(" /at "); Events z = new Events(temp1[0], temp1[1]); return new AddCommand(z); case "find": From 5436934e2ae14797bab68e6d2e8aec7051e0fb9e Mon Sep 17 00:00:00 2001 From: WEIFENG-NUSCEG Date: Tue, 10 Sep 2019 23:02:23 +0800 Subject: [PATCH 004/420] Updated Duke to deal with various kind of errors. Added the documentation --- data/duke.txt | 2 +- src/main/java/AddCommand.java | 26 +++++++++- src/main/java/Command.java | 18 +++++++ src/main/java/Deadline.java | 36 ++++++++++--- src/main/java/DeleteCommand.java | 25 ++++++++- src/main/java/DoneCommand.java | 26 ++++++++-- src/main/java/Duke.java | 34 ++++++++++-- src/main/java/Events.java | 32 ++++++++++-- src/main/java/ExitCommand.java | 21 +++++++- src/main/java/FindCommand.java | 26 ++++++++-- src/main/java/ListCommand.java | 21 +++++++- src/main/java/Parser.java | 89 ++++++++++++++++++++------------ src/main/java/Storage.java | 26 ++++++++-- src/main/java/Task.java | 47 ++++++++++++++--- src/main/java/TaskList.java | 38 +++++++++++--- src/main/java/ToDos.java | 24 +++++++-- src/main/java/Ui.java | 61 ++++++++++++++++++---- src/test/java/DukeTest.java | 20 +++---- 18 files changed, 468 insertions(+), 104 deletions(-) diff --git a/data/duke.txt b/data/duke.txt index ecb10d7478..f603a78378 100644 --- a/data/duke.txt +++ b/data/duke.txt @@ -4,7 +4,7 @@ T | 1 | join sports club T | 1 | designduke E | 1 | breakfast | 11/12/2019 1400 T | 0 | assignment1 -D | 0 | project meeting | 10/05/2019 1530 +D | 1 | project meeting | 10/05/2019 1530 E | 1 | project meeting | 12/05/2019 0700 E | 1 | breakfast | 12/08/2019 1530 D | 1 | ssss | 21/08/2018 1400 diff --git a/src/main/java/AddCommand.java b/src/main/java/AddCommand.java index bff655135d..0abd2bdb3b 100644 --- a/src/main/java/AddCommand.java +++ b/src/main/java/AddCommand.java @@ -1,15 +1,37 @@ +/** + * Represents a command class to add a task. The AddCommand class + * extends from the Command class to represent user instruction + * to add a new ToDo, Deadline or Event + * task to the TaskList. + */ public class AddCommand extends Command { + /** + * A new task to be added + */ private Task t; - + /** + * Constructs a AddCommand object. + * @param tt Specifies the task to be added. + */ public AddCommand(Task tt) { super(); this.t = tt; } - + /** + * Indicates whether Duke should exist + * @return A boolean. True if the command tells Duke to exit, false + * otherwise. + */ @Override public boolean isExit() { return false; } + /** + * run the command with the respect TaskList, UI, and storage. + * @param tasks The task list where tasks are saved. + * @param ui The user interface. + * @param storage object that handles local text file update + */ @Override public void run(TaskList tasks, Ui ui, Storage storage) throws DukeExceptionThrow { tasks.addTask(t); diff --git a/src/main/java/Command.java b/src/main/java/Command.java index c83b41816a..fb1e52d75b 100644 --- a/src/main/java/Command.java +++ b/src/main/java/Command.java @@ -1,6 +1,24 @@ +/** + * Represents a command class received from user. It is an abstract + * class that can not be instantiated, its child class represents different kind + * of user command + */ public abstract class Command { + /** + * run the command with the respect TaskList, UI, and storage. + * @param tasks The task list where tasks are saved. + * @param ui The user interface. + * @param storage object that handles local text file update + * @throws DukeExceptionThrow throw exception during execution of the + * command. + */ abstract void run(TaskList tasks, Ui ui, Storage storage) throws DukeExceptionThrow; + /** + * Decide whether duke should exist. + * @return A boolean. True if the command tells Duke to exit, false + * otherwise. + */ abstract boolean isExit(); } \ No newline at end of file diff --git a/src/main/java/Deadline.java b/src/main/java/Deadline.java index fca799f920..590632226c 100644 --- a/src/main/java/Deadline.java +++ b/src/main/java/Deadline.java @@ -3,30 +3,52 @@ import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; - +/** + * Represents a task with a deadline. It is + * extended from the Task class. + */ public class Deadline extends Task { - + /** + * A string that represents the deadline of the task. + */ protected String by; - + /** + * Constructs a Deadline object. Date and time are parsed and + * stored in dateTime field if input is of "dd/MM/yyyy HHmm" + * format. + * @param description A string that describes the specific + * description of task. + * @param by A string that specifies the deadline of the + * task. + */ public Deadline(String description, String by) { super(description); this.by = by; } - + /** + * Returns a string pattern to the user output + * @return A string which displays the type, + * description and deadline of the task. + */ @Override public String toString() { return "[D]" + super.printStatus() + " (by: " + super.timeFormatter(by) + ")"; } + /** + * Returns a string with the following format to be read from a local file. + * @return A string in a specific format to be read from a local file. + */ public String txtFormat() { return "D | " + (this.isDone ? "1" : "0") + " | " + this.description + " | " + super.timeFormatter(by); } - + /** + * Returns a string with the following format to be stored in a local file + * @return A string in a specific format to be stored in a local file. + */ public String writeTxt(){ return "D | " + (this.isDone ? "1" : "0") + " | " + this.description + " | " + this.by; } - - } \ No newline at end of file diff --git a/src/main/java/DeleteCommand.java b/src/main/java/DeleteCommand.java index 1a8b7ee516..3199b1f28c 100644 --- a/src/main/java/DeleteCommand.java +++ b/src/main/java/DeleteCommand.java @@ -1,16 +1,37 @@ +/** + * Represents a command to delete a task. The DeleteCommand class + * extends from the Command class to represent user instruction + * to delete an task from task list. + */ public class DeleteCommand extends Command { + /** + * The index of the task to be deleted. + */ private int Id; + /** + * Constructs a DeleteCommand object. + * @param taskId Specifies the index of the task to be deleted. + */ public DeleteCommand(int taskId) { super(); this.Id = taskId; } - + /** + * Indicates whether Duke should exist + * @return A boolean. True if the command tells Duke to exit, false + * otherwise. + */ @Override public boolean isExit() { return false; } - + /** + * run the command with the respect TaskList, UI, and storage. + * @param tasks The task list where tasks are saved. + * @param ui The user interface. + * @param storage object that handles local text file update + */ public void run(TaskList tasks, Ui ui, Storage storage) throws DukeExceptionThrow { try { Task t = tasks.getTask(Id); diff --git a/src/main/java/DoneCommand.java b/src/main/java/DoneCommand.java index 05d181bb83..5072e17bd8 100644 --- a/src/main/java/DoneCommand.java +++ b/src/main/java/DoneCommand.java @@ -1,16 +1,36 @@ +/** + * Represents a command to mark a task as done. The DoneCommand + * class extends from the Command class to represent user + * instruction to mark an existing task. + */ public class DoneCommand extends Command { + /** + * The index of the task to be marked as done. + */ private int Id; - + /** + * Constructs a DoneCommand object. + * @param taskId Specifies the index of the task. + */ public DoneCommand(int taskId) { super(); this.Id = taskId; } - + /** + * Indicates whether Duke should exist + * @return A boolean. True if the command tells Duke to exit, false + * otherwise. + */ @Override public boolean isExit() { return false; } - + /** + * run the command with the respect TaskList, UI, and storage. + * @param tasks The task list where tasks are saved. + * @param ui The user interface. + * @param storage object that handles local text file update + */ @Override public void run(TaskList tasks, Ui ui, Storage storage) throws DukeExceptionThrow { try diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index cc80005f3a..f421cb42c4 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -8,12 +8,31 @@ import java.io.IOException; - +/** + * Represents Duke, a Personal Assistant to help + * users tracking their progress. + */ public class Duke { + /** + * A Storage object that handles reading tasks from a local + * file and saving them to the same file. + */ private Storage storage; + /** + * A TaskList object that deals with add, delete, mark as done, + * find functions of a list of tasks. + */ private TaskList tasks; + /** + * A Ui object that deals with interactions with the user. + */ private Ui ui; - + /** + * Constructs a Duke object with a relative file path. + * Initialize the user interface and reads tasks from the specific text file. + * @param filePath A string that represents the path of the local file + * used for storing tasks. + */ public Duke(String filePath) { ui = new Ui(); storage = new Storage(filePath); @@ -24,7 +43,10 @@ public Duke(String filePath) { tasks = new TaskList(); } } - + /** + * Runs the Duke program. + * Reads user input until a "bye" message is received. + */ public void run() { ui.showWelcome(); boolean isExit = false; @@ -42,7 +64,11 @@ public void run() { } } } - + /** + * Starts the Duke program by passing in a specific file + * path. + * @param args The command line arguments. + */ public static void main(String[] args) { new Duke("./data/duke.txt").run(); } diff --git a/src/main/java/Events.java b/src/main/java/Events.java index e2beec0b34..1f036a1c39 100644 --- a/src/main/java/Events.java +++ b/src/main/java/Events.java @@ -3,24 +3,46 @@ import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; +/** + * Represents a task with a event. It is + * extended from the Task class. + */ public class Events extends Task { - + /** + * A string that represents the time of the event. + */ protected String at; - + /** + * Constructs a Event object. Date and time are parsed and + * stored in dateTime field if input is of "dd/MM/yyyy HHmm" + * format. + * @param description A string that saves the description of the task. + * @param at A string that specifies the time of the event. + */ public Events(String description, String at) { super(description); this.at = at; } - + /** + * Returns a string pattern to the user output + * @return A string which displays the type, + * description and deadline of the task. + */ @Override public String toString() { return "[E]" + super.printStatus() + " (at: " + super.timeFormatter(at) + ")"; } - + /** + * Returns a string with the following format to be read from a local file. + * @return A string in a specific format to be read from a local file. + */ public String txtFormat() { return "E | " + (this.isDone ? "1" : "0") + " | " + this.description + " | " + super.timeFormatter(at); } - + /** + * Returns a string with the following format to be stored in a local file + * @return A string in a specific format to be stored in a local file. + */ public String writeTxt(){ return "E | " + (this.isDone ? "1" : "0") + " | " + this.description + " | " + this.at; } diff --git a/src/main/java/ExitCommand.java b/src/main/java/ExitCommand.java index 0357ec5117..5bb4a3be9f 100644 --- a/src/main/java/ExitCommand.java +++ b/src/main/java/ExitCommand.java @@ -1,13 +1,30 @@ +/** + * Represents a command to exit Duke. The ExitCommand class + * extends from the Command class for the user to quit the + * program + */ public class ExitCommand extends Command { + /** + * Constructs a ExitCommand object. + */ public ExitCommand() { super(); } - + /** + * Indicates whether Duke should exist + * @return A boolean. True if the command tells Duke to exit, false + * otherwise. + */ @Override public boolean isExit() { return true; } - + /** + * run the command with the respect TaskList, UI, and storage. + * @param tasks The task list where tasks are saved. + * @param ui The user interface. + * @param storage object that handles local text file update + */ @Override public void run(TaskList tasks, Ui ui, Storage storage) { ui.exitInformation(); diff --git a/src/main/java/FindCommand.java b/src/main/java/FindCommand.java index b229fd0f79..addf8fa2ff 100644 --- a/src/main/java/FindCommand.java +++ b/src/main/java/FindCommand.java @@ -1,16 +1,36 @@ +/** + * Represents a command to find a certain task from Duke's task list. + * The ExitCommand class extends from the Command + * class for the user to find a specific task object from the storage. + */ public class FindCommand extends Command { + /** + * Name of the task to be found. + */ private String taskName; - + /** + * Constructs a FindCommand object. + * @param name Specifies the name of the task. + */ public FindCommand(String name) { super(); this.taskName = name; } - + /** + * Indicates whether Duke should exist + * @return A boolean. True if the command tells Duke to exit, false + * otherwise. + */ @Override public boolean isExit() { return false; } - + /** + * run the command with the respect TaskList, UI, and storage. + * @param tasks The task list where tasks are saved. + * @param ui The user interface. + * @param storage object that handles local text file update + */ @Override public void run(TaskList tasks, Ui ui, Storage storage) throws DukeExceptionThrow { ui.taskFound(tasks.fullTaskList(), taskName); diff --git a/src/main/java/ListCommand.java b/src/main/java/ListCommand.java index df29e07435..d50ad1832e 100644 --- a/src/main/java/ListCommand.java +++ b/src/main/java/ListCommand.java @@ -1,13 +1,30 @@ +/** + * Represents a command to list all existing tasks in the task list. The + * ListCommand class extends from the Command class + * for the user to view the entire task list from Duke. + */ class ListCommand extends Command { + /** + * Constructs a ListCommand object. + */ public ListCommand() { super(); } - + /** + * Indicates whether Duke should exist + * @return A boolean. True if the command tells Duke to exit, false + * otherwise. + */ @Override public boolean isExit() { return false; } - + /** + * run the command with the respect TaskList, UI, and storage. + * @param tasks The task list where tasks are saved. + * @param ui The user interface. + * @param storage object that handles local text file update + */ @Override public void run(TaskList tasks, Ui ui, Storage storage) { ui.listTasks(tasks); diff --git a/src/main/java/Parser.java b/src/main/java/Parser.java index ba43228581..85b473fe08 100644 --- a/src/main/java/Parser.java +++ b/src/main/java/Parser.java @@ -1,45 +1,70 @@ -import java.util.Scanner; - +/** + * Represents a Parser that parses user input into a specific + * type of Command. + */ public class Parser { private static String[] substring; + /** + * Parses a Task from a string array. + * @param ss The string array to be parsed. + * @return The Command received from user. + */ public static Command Parse(String ss) throws DukeExceptionThrow { String[] command = ss.split(" ", 2); - try - { - switch (command[0]) { - case "list": - return new ListCommand(); - case "done": - int i = Integer.parseInt(command[1]); - return new DoneCommand(i); - case "delete": - int x = Integer.parseInt(command[1]); - return new DeleteCommand(x); - case "todo": - ToDos t = new ToDos(command[1]); - return new AddCommand(t); - case "deadline": + + switch (command[0]) { + case "list": + return new ListCommand(); + case "done": + try{ + int i = Integer.parseInt(command[1]); + return new DoneCommand(i); + }catch(Exception e){ + throw new DukeExceptionThrow(e.getMessage()); + } + case "delete": + try{ + int x = Integer.parseInt(command[1]); + return new DeleteCommand(x); + }catch(Exception e){ + throw new DukeExceptionThrow(e.getMessage()); + } + case "todo": + try{ + ToDos t = new ToDos(command[1]); + return new AddCommand(t); + }catch(Exception e){ + throw new DukeExceptionThrow(e.getMessage()); + } + case "deadline": + try{ String[] temp = command[1].split(" /by "); Deadline d = new Deadline(temp[0], temp[1]); return new AddCommand(d); - case "event": - String[] temp1 = command[1].split(" /at "); - Events z = new Events(temp1[0], temp1[1]); - return new AddCommand(z); - case "find": - return new FindCommand(command[1]); - case "bye": - return new ExitCommand(); - default: - throw new DukeExceptionThrow("Unrecognized user input!"); + }catch(Exception e){ + throw new DukeExceptionThrow(e.getMessage()); + } + case "event": + try{ + String[] temp1 = command[1].split(" /at "); + Events z = new Events(temp1[0], temp1[1]); + return new AddCommand(z); + }catch(Exception e) { + throw new DukeExceptionThrow(e.getMessage()); + } + case "find": + try{ + return new FindCommand(command[1]); + }catch(Exception e) { + throw new DukeExceptionThrow(e.getMessage()); + } + case "bye": + return new ExitCommand(); + default: + throw new DukeExceptionThrow("Unrecognized user input!"); } - } - catch (DukeExceptionThrow e) - { - throw new DukeExceptionThrow("Fail to recognize the command"); - } } } diff --git a/src/main/java/Storage.java b/src/main/java/Storage.java index d4e01a23fe..1b93b030d2 100644 --- a/src/main/java/Storage.java +++ b/src/main/java/Storage.java @@ -6,13 +6,29 @@ import java.util.List; import java.util.Scanner; +/** + * Represents a Storage class that deals with reading tasks from + * a file and saving tasks in the file. + */ public class Storage { + /** + * A string that represents a relative file path from the project folder. + */ private String filePath; - + /** + * Constructs a Storage object with a specific file path. + * @param path A string that represents the path of the file to read or + * write. + */ public Storage(String path) { this.filePath = path; } - + /** + * Read tasks from the file and store into a ArrayList of + * Task. + * @return A ArrayList of tasks from the file. + * @throws DukeExceptionThrow If file is not found. + */ public ArrayList load() throws DukeExceptionThrow { File newDuke = new File(filePath); @@ -57,7 +73,11 @@ public ArrayList load() throws DukeExceptionThrow throw new DukeExceptionThrow("File is not found!"); } } - + /** + * Saves tasks to the local file. + * @param task The TaskList storing tasks. + * @throws DukeExceptionThrow If writing to the local file failed. + */ public void save(ArrayList task) { try { FileWriter ww = new FileWriter("./data/duke.txt"); diff --git a/src/main/java/Task.java b/src/main/java/Task.java index f22484d4b9..b966bd8728 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -7,35 +7,70 @@ import java.time.format.DateTimeParseException; import java.util.Date; +/** + * Represents a task. Task is an abstract class that can not be + * instantiated + */ public abstract class Task { + /** + * A String that represents the description of the task. + */ protected String description; + /** + * A boolean that represents the status of the task( 1 means done, 0 means not yet) + */ protected boolean isDone; + /** + * a localDateTime constructor to save the date and time + */ protected LocalDateTime ld; - + /** + * Initialises the minimum fields required to setup a Task. + * @param description A string that represents the description of certain task. + */ public Task(String description) { this.description = description; this.isDone = false; } - + /** + * Returns an icon that represents the status of the task. + * @return Tick if completed, cross if uncompleted. + */ public String getStatusIcon() { return (isDone ? "\u2713" : "\u2718"); //return tick or X symbols } + /** + * Returns a string with the following format to be read from a local file. + * @return A string in a specific format to be read from a local file. + */ abstract String txtFormat(); - + /** + * Returns a string with the following format to be stored in a local file + * @return A string in a specific format to be stored in a local file. + */ abstract String writeTxt(); - + /** + * Marks the task as done. + */ public void markAsDone() { isDone = true; } - + /** + * Returns a string with the status icon and the description of the task. + * @return A string in a specific format with the status and description of the task. + */ public String printStatus() { return "[" + this.getStatusIcon() + "] " + description; } - + /** + * Returns the description of the task. + * @return A string that represents the specific activity associated with + * the task. + */ public String getDescription(){ return description; } diff --git a/src/main/java/TaskList.java b/src/main/java/TaskList.java index 286a21c8c5..b8c015ccf3 100644 --- a/src/main/java/TaskList.java +++ b/src/main/java/TaskList.java @@ -1,28 +1,52 @@ import java.util.ArrayList; - +/** + * Represents a list of Task that can perform operations such as + * add and delete on the tasks. + */ public class TaskList { + /** + * An ArrayList structure. + */ protected ArrayList taskList; + /** + * instantiate a new TaskList with a empty list. + */ public TaskList(ArrayList task) { this.taskList = task; } - + /** + * Retrieve the entire task list stored inside the ArrayList. + */ public ArrayList fullTaskList(){ return taskList; } - + /** + * Adds a Task to the list. + * @param t The Task to be added to the list. + */ public void addTask(Task t) { taskList.add(t); } - + /** + * Removes the Task with the given index from the list. + * @param i The index of the Task to be deleted. + */ public void deleteTask(Integer i) throws IndexOutOfBoundsException { taskList.remove(i - 1); } - + /** + * Returns the Task in the list with the given index. + * @param i The index of the Task. + * @return The Task in the list with the specific index. + */ public Task getTask(int i) throws IndexOutOfBoundsException { return taskList.get(i - 1); } - + /** + * Returns the size of task list. + * @return An integer representing the number of tasks in the list. + */ public int getSize() { return taskList.size(); } @@ -31,6 +55,4 @@ public TaskList(){ taskList = new ArrayList(); } - - } diff --git a/src/main/java/ToDos.java b/src/main/java/ToDos.java index 37dc7ab206..d54f75e940 100644 --- a/src/main/java/ToDos.java +++ b/src/main/java/ToDos.java @@ -1,22 +1,40 @@ +/** + * Represents a task without a specific time. This class + * extends from the Task class. + */ public class ToDos extends Task { - protected boolean isToDo; + /** + * Constructs a ToDo object. + * @param description A string of the task description. + */ public ToDos(String description) { super(description); this.isToDo = true; } - + /** + * Returns a string pattern to the user output + * @return A string which displays the type, + * description and deadline of the task. + */ @Override public String toString() { return "[T]" + super.printStatus(); } + /** + * Returns a string with the following format to be read from a local file. + * @return A string in a specific format to be read from a local file. + */ public String txtFormat() { return "T | " + (this.isDone ? "1" : "0") + " | " + this.description; } - + /** + * Returns a string with the following format to be stored in a local file + * @return A string in a specific format to be stored in a local file. + */ public String writeTxt(){ return "T | " + (this.isDone ? "1" : "0") + " | " + this.description; } diff --git a/src/main/java/Ui.java b/src/main/java/Ui.java index 6fe6d8fa69..a7a6760007 100644 --- a/src/main/java/Ui.java +++ b/src/main/java/Ui.java @@ -1,13 +1,25 @@ import java.util.ArrayList; import java.util.Scanner; +/** + * Represents the necessary ui elements for user interaction + */ public class Ui { + /** + * A Scanner to read user input. + */ private Scanner sc; - + /** + * Constructs a Ui object and initializes the + * Scanner to read user input from the system. + */ public Ui() { sc = new Scanner(System.in); } - + /** + * Reads user instruction. + * @return A string that represents the user instruction. + */ public String readCommand() { return sc.nextLine(); } @@ -15,21 +27,37 @@ public String readCommand() { public void showError(String e) { System.out.println( "☹ OOPS!!!" + e); } - + /** + * Shows that a Task has been added, and displays the number + * of current tasks in the list. + * @param t The Task that is added to the list. + * @param size The number of tasks stored in the TaskList. + */ public void taskAdded(Task t, int size) { System.out.println("Got it. I've added this task: \n " + t.toString() + "\nNow you have " + size + " tasks in the list."); } - + /** + * Shows that a Task has been marked as done. + * @param t The Task that is marked as done. + */ public void markedAsDone(Task t) { System.out.println("Nice! I've marked this task as done: \n " + t.printStatus()); } - + /** + * Shows that a Task has been removed, and displays the number + * of current tasks in the list. + * @param t The Task that is deleted from the list. + */ public void taskRemoved(Task t, int size) { System.out.println("Noted. I've removed this task: \n " + t.toString() + "\nNow you have " + size + " tasks in the list."); } - + /** + * Find and display a specific task stored in the list. + * @param a TaskList used to store tasks. + * @param name name of the task to be found + */ public void taskFound(ArrayList a, String name){ System.out.println("Here are the matching tasks in your list:"); int count = 1; @@ -40,11 +68,16 @@ public void taskFound(ArrayList a, String name){ } } } - + /** + * Shows a divider line. + */ public void showLine() { System.out.println("____________________________________________________________"); } - + /** + * Displays all tasks currently stored in the list. + * @param tasks The TaskList used to store tasks. + */ public void listTasks(TaskList tasks) { System.out.println("Here are the tasks in your list:"); for (int i = 1; i <= tasks.getSize() ; i++) @@ -52,11 +85,15 @@ public void listTasks(TaskList tasks) { System.out.println( i + "." + tasks.getTask(i).toString()); } } - + /** + * Shows bye message to user. + */ public void exitInformation(){ System.out.println("Bye. Hope to see you again soon!"); } - + /** + * Shows Duke logo and welcome message, and user input instructions. + */ public void showWelcome() { String logo = " ____ _ \n" + "| _ \\ _ _| | _____ \n" @@ -66,7 +103,9 @@ public void showWelcome() { System.out.println("Hello from\n" + logo); System.out.println("Hello! I'm Duke\nWhat can I do for you?"); } - + /** + * Shows an error in loading the file where past tasks are stored. + */ public void showLoadingError() { System.out.println("Failed to Load from local text file!"); } diff --git a/src/test/java/DukeTest.java b/src/test/java/DukeTest.java index 34ee8cc818..8a14575adc 100644 --- a/src/test/java/DukeTest.java +++ b/src/test/java/DukeTest.java @@ -1,10 +1,10 @@ -//import org.junit.jupiter.api.Test; -// -//import static org.junit.jupiter.api.Assertions.assertEquals; -// -//public class DukeTest { -// @Test -// public void dummyTest(){ -// assertEquals(2, 2); -// } -//} \ No newline at end of file +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class DukeTest { + @Test + public void dummyTest(){ + assertEquals(2, 2); + } +} \ No newline at end of file From 44f0587a33d19f53900faa16a1afe60b8f2a732f Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Wed, 11 Sep 2019 16:06:31 +0800 Subject: [PATCH 005/420] Packages files with refactoring methods 1. Packed files into duke.command, duke.task and duke.core 2. Changes mutiple methods from package-private to public --- data/duke.txt | 3 +- src/main/java/ExitCommand.java | 32 ---------------- src/main/java/ListCommand.java | 32 ---------------- src/main/java/{ => duke}/Duke.java | 28 ++++++-------- .../java/{ => duke/command}/AddCommand.java | 24 ++++++++---- src/main/java/{ => duke/command}/Command.java | 15 ++++++-- .../{ => duke/command}/DeleteCommand.java | 20 +++++++--- .../java/{ => duke/command}/DoneCommand.java | 20 +++++++--- src/main/java/duke/command/ExitCommand.java | 38 +++++++++++++++++++ .../java/{ => duke/command}/FindCommand.java | 19 +++++++--- src/main/java/duke/command/ListCommand.java | 38 +++++++++++++++++++ .../{ => duke/core}/DukeExceptionThrow.java | 4 +- src/main/java/{ => duke/core}/Parser.java | 15 ++++++-- src/main/java/{ => duke/core}/Storage.java | 16 +++++--- src/main/java/{ => duke/core}/TaskList.java | 22 ++++++----- src/main/java/{ => duke/core}/Ui.java | 28 ++++++++------ src/main/java/{ => duke/task}/Deadline.java | 11 ++---- src/main/java/{ => duke/task}/Events.java | 7 +--- src/main/java/{ => duke/task}/Task.java | 8 ++-- src/main/java/{ => duke/task}/ToDos.java | 4 +- 20 files changed, 226 insertions(+), 158 deletions(-) delete mode 100644 src/main/java/ExitCommand.java delete mode 100644 src/main/java/ListCommand.java rename src/main/java/{ => duke}/Duke.java (67%) rename src/main/java/{ => duke/command}/AddCommand.java (50%) rename src/main/java/{ => duke/command}/Command.java (57%) rename src/main/java/{ => duke/command}/DeleteCommand.java (62%) rename src/main/java/{ => duke/command}/DoneCommand.java (62%) create mode 100644 src/main/java/duke/command/ExitCommand.java rename src/main/java/{ => duke/command}/FindCommand.java (58%) create mode 100644 src/main/java/duke/command/ListCommand.java rename src/main/java/{ => duke/core}/DukeExceptionThrow.java (53%) rename src/main/java/{ => duke/core}/Parser.java (85%) rename src/main/java/{ => duke/core}/Storage.java (87%) rename src/main/java/{ => duke/core}/TaskList.java (60%) rename src/main/java/{ => duke/core}/Ui.java (75%) rename src/main/java/{ => duke/task}/Deadline.java (83%) rename src/main/java/{ => duke/task}/Events.java (88%) rename src/main/java/{ => duke/task}/Task.java (94%) rename src/main/java/{ => duke/task}/ToDos.java (95%) diff --git a/data/duke.txt b/data/duke.txt index f603a78378..5228a44a33 100644 --- a/data/duke.txt +++ b/data/duke.txt @@ -3,8 +3,9 @@ E | 1 | project meeting | 05/11/2019 1503 T | 1 | join sports club T | 1 | designduke E | 1 | breakfast | 11/12/2019 1400 -T | 0 | assignment1 +T | 1 | assignment1 D | 1 | project meeting | 10/05/2019 1530 E | 1 | project meeting | 12/05/2019 0700 E | 1 | breakfast | 12/08/2019 1530 D | 1 | ssss | 21/08/2018 1400 +T | 0 | homework (t: 12pm today) diff --git a/src/main/java/ExitCommand.java b/src/main/java/ExitCommand.java deleted file mode 100644 index 5bb4a3be9f..0000000000 --- a/src/main/java/ExitCommand.java +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Represents a command to exit Duke. The ExitCommand class - * extends from the Command class for the user to quit the - * program - */ -public class ExitCommand extends Command { - /** - * Constructs a ExitCommand object. - */ - public ExitCommand() { - super(); - } - /** - * Indicates whether Duke should exist - * @return A boolean. True if the command tells Duke to exit, false - * otherwise. - */ - @Override - public boolean isExit() { - return true; - } - /** - * run the command with the respect TaskList, UI, and storage. - * @param tasks The task list where tasks are saved. - * @param ui The user interface. - * @param storage object that handles local text file update - */ - @Override - public void run(TaskList tasks, Ui ui, Storage storage) { - ui.exitInformation(); - } -} \ No newline at end of file diff --git a/src/main/java/ListCommand.java b/src/main/java/ListCommand.java deleted file mode 100644 index d50ad1832e..0000000000 --- a/src/main/java/ListCommand.java +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Represents a command to list all existing tasks in the task list. The - * ListCommand class extends from the Command class - * for the user to view the entire task list from Duke. - */ -class ListCommand extends Command { - /** - * Constructs a ListCommand object. - */ - public ListCommand() { - super(); - } - /** - * Indicates whether Duke should exist - * @return A boolean. True if the command tells Duke to exit, false - * otherwise. - */ - @Override - public boolean isExit() { - return false; - } - /** - * run the command with the respect TaskList, UI, and storage. - * @param tasks The task list where tasks are saved. - * @param ui The user interface. - * @param storage object that handles local text file update - */ - @Override - public void run(TaskList tasks, Ui ui, Storage storage) { - ui.listTasks(tasks); - } -} \ No newline at end of file diff --git a/src/main/java/Duke.java b/src/main/java/duke/Duke.java similarity index 67% rename from src/main/java/Duke.java rename to src/main/java/duke/Duke.java index f421cb42c4..faec24ec3c 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/duke/Duke.java @@ -1,34 +1,30 @@ -import java.net.URL; -import java.util.ArrayList; -import java.util.List; -import java.util.Scanner; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileWriter; -import java.io.IOException; +package duke; +import duke.command.Command; +import duke.core.*; + /** - * Represents Duke, a Personal Assistant to help + * Represents duke.Duke, a Personal Assistant to help * users tracking their progress. */ public class Duke { /** - * A Storage object that handles reading tasks from a local + * A duke.core.Storage object that handles reading tasks from a local * file and saving them to the same file. */ private Storage storage; /** - * A TaskList object that deals with add, delete, mark as done, + * A duke.core.TaskList object that deals with add, delete, mark as done, * find functions of a list of tasks. */ private TaskList tasks; /** - * A Ui object that deals with interactions with the user. + * A duke.core.Ui object that deals with interactions with the user. */ private Ui ui; /** - * Constructs a Duke object with a relative file path. + * Constructs a duke.Duke object with a relative file path. * Initialize the user interface and reads tasks from the specific text file. * @param filePath A string that represents the path of the local file * used for storing tasks. @@ -44,10 +40,10 @@ public Duke(String filePath) { } } /** - * Runs the Duke program. + * Runs the duke.Duke program. * Reads user input until a "bye" message is received. */ - public void run() { + private void run() { ui.showWelcome(); boolean isExit = false; while (!isExit) { @@ -65,7 +61,7 @@ public void run() { } } /** - * Starts the Duke program by passing in a specific file + * Starts the duke.Duke program by passing in a specific file * path. * @param args The command line arguments. */ diff --git a/src/main/java/AddCommand.java b/src/main/java/duke/command/AddCommand.java similarity index 50% rename from src/main/java/AddCommand.java rename to src/main/java/duke/command/AddCommand.java index 0abd2bdb3b..406c7db20f 100644 --- a/src/main/java/AddCommand.java +++ b/src/main/java/duke/command/AddCommand.java @@ -1,8 +1,16 @@ +package duke.command; + +import duke.core.DukeExceptionThrow; +import duke.core.Storage; +import duke.core.TaskList; +import duke.core.Ui; +import duke.task.Task; + /** - * Represents a command class to add a task. The AddCommand class - * extends from the Command class to represent user instruction - * to add a new ToDo, Deadline or Event - * task to the TaskList. + * Represents a command class to add a task. The duke.command.AddCommand class + * extends from the duke.command.Command class to represent user instruction + * to add a new ToDo, duke.task.Deadline or Event + * task to the duke.core.TaskList. */ public class AddCommand extends Command { /** @@ -10,7 +18,7 @@ public class AddCommand extends Command { */ private Task t; /** - * Constructs a AddCommand object. + * Constructs a duke.command.AddCommand object. * @param tt Specifies the task to be added. */ public AddCommand(Task tt) { @@ -18,8 +26,8 @@ public AddCommand(Task tt) { this.t = tt; } /** - * Indicates whether Duke should exist - * @return A boolean. True if the command tells Duke to exit, false + * Indicates whether duke.Duke should exist + * @return A boolean. True if the command tells duke.Duke to exit, false * otherwise. */ @Override @@ -27,7 +35,7 @@ public boolean isExit() { return false; } /** - * run the command with the respect TaskList, UI, and storage. + * run the command with the respect duke.core.TaskList, UI, and storage. * @param tasks The task list where tasks are saved. * @param ui The user interface. * @param storage object that handles local text file update diff --git a/src/main/java/Command.java b/src/main/java/duke/command/Command.java similarity index 57% rename from src/main/java/Command.java rename to src/main/java/duke/command/Command.java index fb1e52d75b..0ec83fef74 100644 --- a/src/main/java/Command.java +++ b/src/main/java/duke/command/Command.java @@ -1,3 +1,10 @@ +package duke.command; + +import duke.core.DukeExceptionThrow; +import duke.core.Storage; +import duke.core.TaskList; +import duke.core.Ui; + /** * Represents a command class received from user. It is an abstract * class that can not be instantiated, its child class represents different kind @@ -6,19 +13,19 @@ public abstract class Command { /** - * run the command with the respect TaskList, UI, and storage. + * run the command with the respect duke.core.TaskList, UI, and storage. * @param tasks The task list where tasks are saved. * @param ui The user interface. * @param storage object that handles local text file update * @throws DukeExceptionThrow throw exception during execution of the * command. */ - abstract void run(TaskList tasks, Ui ui, Storage storage) throws DukeExceptionThrow; + public abstract void run(TaskList tasks, Ui ui, Storage storage) throws DukeExceptionThrow; /** * Decide whether duke should exist. - * @return A boolean. True if the command tells Duke to exit, false + * @return A boolean. True if the command tells duke.Duke to exit, false * otherwise. */ - abstract boolean isExit(); + public abstract boolean isExit(); } \ No newline at end of file diff --git a/src/main/java/DeleteCommand.java b/src/main/java/duke/command/DeleteCommand.java similarity index 62% rename from src/main/java/DeleteCommand.java rename to src/main/java/duke/command/DeleteCommand.java index 3199b1f28c..607cda6b98 100644 --- a/src/main/java/DeleteCommand.java +++ b/src/main/java/duke/command/DeleteCommand.java @@ -1,6 +1,14 @@ +package duke.command; + +import duke.core.DukeExceptionThrow; +import duke.core.Storage; +import duke.core.TaskList; +import duke.core.Ui; +import duke.task.Task; + /** - * Represents a command to delete a task. The DeleteCommand class - * extends from the Command class to represent user instruction + * Represents a command to delete a task. The duke.command.DeleteCommand class + * extends from the duke.command.Command class to represent user instruction * to delete an task from task list. */ public class DeleteCommand extends Command { @@ -9,7 +17,7 @@ public class DeleteCommand extends Command { */ private int Id; /** - * Constructs a DeleteCommand object. + * Constructs a duke.command.DeleteCommand object. * @param taskId Specifies the index of the task to be deleted. */ @@ -18,8 +26,8 @@ public DeleteCommand(int taskId) { this.Id = taskId; } /** - * Indicates whether Duke should exist - * @return A boolean. True if the command tells Duke to exit, false + * Indicates whether duke.Duke should exist + * @return A boolean. True if the command tells duke.Duke to exit, false * otherwise. */ @Override @@ -27,7 +35,7 @@ public boolean isExit() { return false; } /** - * run the command with the respect TaskList, UI, and storage. + * run the command with the respect duke.core.TaskList, UI, and storage. * @param tasks The task list where tasks are saved. * @param ui The user interface. * @param storage object that handles local text file update diff --git a/src/main/java/DoneCommand.java b/src/main/java/duke/command/DoneCommand.java similarity index 62% rename from src/main/java/DoneCommand.java rename to src/main/java/duke/command/DoneCommand.java index 5072e17bd8..569d8b3a68 100644 --- a/src/main/java/DoneCommand.java +++ b/src/main/java/duke/command/DoneCommand.java @@ -1,6 +1,14 @@ +package duke.command; + +import duke.core.DukeExceptionThrow; +import duke.core.Storage; +import duke.core.TaskList; +import duke.core.Ui; +import duke.task.Task; + /** - * Represents a command to mark a task as done. The DoneCommand - * class extends from the Command class to represent user + * Represents a command to mark a task as done. The duke.command.DoneCommand + * class extends from the duke.command.Command class to represent user * instruction to mark an existing task. */ public class DoneCommand extends Command { @@ -9,7 +17,7 @@ public class DoneCommand extends Command { */ private int Id; /** - * Constructs a DoneCommand object. + * Constructs a duke.command.DoneCommand object. * @param taskId Specifies the index of the task. */ public DoneCommand(int taskId) { @@ -17,8 +25,8 @@ public DoneCommand(int taskId) { this.Id = taskId; } /** - * Indicates whether Duke should exist - * @return A boolean. True if the command tells Duke to exit, false + * Indicates whether duke.Duke should exist + * @return A boolean. True if the command tells duke.Duke to exit, false * otherwise. */ @Override @@ -26,7 +34,7 @@ public boolean isExit() { return false; } /** - * run the command with the respect TaskList, UI, and storage. + * run the command with the respect duke.core.TaskList, UI, and storage. * @param tasks The task list where tasks are saved. * @param ui The user interface. * @param storage object that handles local text file update diff --git a/src/main/java/duke/command/ExitCommand.java b/src/main/java/duke/command/ExitCommand.java new file mode 100644 index 0000000000..e4bb0b9620 --- /dev/null +++ b/src/main/java/duke/command/ExitCommand.java @@ -0,0 +1,38 @@ +package duke.command; + +import duke.core.Storage; +import duke.core.TaskList; +import duke.core.Ui; + +/** + * Represents a command to exit duke.Duke. The duke.command.ExitCommand class + * extends from the duke.command.Command class for the user to quit the + * program + */ +public class ExitCommand extends Command { + /** + * Constructs a duke.command.ExitCommand object. + */ + public ExitCommand() { + super(); + } + /** + * Indicates whether duke.Duke should exist + * @return A boolean. True if the command tells duke.Duke to exit, false + * otherwise. + */ + @Override + public boolean isExit() { + return true; + } + /** + * run the command with the respect duke.core.TaskList, UI, and storage. + * @param tasks The task list where tasks are saved. + * @param ui The user interface. + * @param storage object that handles local text file update + */ + @Override + public void run(TaskList tasks, Ui ui, Storage storage) { + ui.exitInformation(); + } +} \ No newline at end of file diff --git a/src/main/java/FindCommand.java b/src/main/java/duke/command/FindCommand.java similarity index 58% rename from src/main/java/FindCommand.java rename to src/main/java/duke/command/FindCommand.java index addf8fa2ff..bbdcae2225 100644 --- a/src/main/java/FindCommand.java +++ b/src/main/java/duke/command/FindCommand.java @@ -1,6 +1,13 @@ +package duke.command; + +import duke.core.DukeExceptionThrow; +import duke.core.Storage; +import duke.core.TaskList; +import duke.core.Ui; + /** - * Represents a command to find a certain task from Duke's task list. - * The ExitCommand class extends from the Command + * Represents a command to find a certain task from duke.Duke's task list. + * The duke.command.ExitCommand class extends from the duke.command.Command * class for the user to find a specific task object from the storage. */ public class FindCommand extends Command { @@ -9,7 +16,7 @@ public class FindCommand extends Command { */ private String taskName; /** - * Constructs a FindCommand object. + * Constructs a duke.command.FindCommand object. * @param name Specifies the name of the task. */ public FindCommand(String name) { @@ -17,8 +24,8 @@ public FindCommand(String name) { this.taskName = name; } /** - * Indicates whether Duke should exist - * @return A boolean. True if the command tells Duke to exit, false + * Indicates whether duke.Duke should exist + * @return A boolean. True if the command tells duke.Duke to exit, false * otherwise. */ @Override @@ -26,7 +33,7 @@ public boolean isExit() { return false; } /** - * run the command with the respect TaskList, UI, and storage. + * run the command with the respect duke.core.TaskList, UI, and storage. * @param tasks The task list where tasks are saved. * @param ui The user interface. * @param storage object that handles local text file update diff --git a/src/main/java/duke/command/ListCommand.java b/src/main/java/duke/command/ListCommand.java new file mode 100644 index 0000000000..1d5b4e4f32 --- /dev/null +++ b/src/main/java/duke/command/ListCommand.java @@ -0,0 +1,38 @@ +package duke.command; + +import duke.core.Storage; +import duke.core.TaskList; +import duke.core.Ui; + +/** + * Represents a command to list all existing tasks in the task list. The + * duke.command.ListCommand class extends from the duke.command.Command class + * for the user to view the entire task list from duke.Duke. + */ +public class ListCommand extends Command { + /** + * Constructs a duke.command.ListCommand object. + */ + public ListCommand() { + super(); + } + /** + * Indicates whether duke.Duke should exist + * @return A boolean. True if the command tells duke.Duke to exit, false + * otherwise. + */ + @Override + public boolean isExit() { + return false; + } + /** + * run the command with the respect duke.core.TaskList, UI, and storage. + * @param tasks The task list where tasks are saved. + * @param ui The user interface. + * @param storage object that handles local text file update + */ + @Override + public void run(TaskList tasks, Ui ui, Storage storage) { + ui.listTasks(tasks); + } +} \ No newline at end of file diff --git a/src/main/java/DukeExceptionThrow.java b/src/main/java/duke/core/DukeExceptionThrow.java similarity index 53% rename from src/main/java/DukeExceptionThrow.java rename to src/main/java/duke/core/DukeExceptionThrow.java index 990826c05f..632ac2715a 100644 --- a/src/main/java/DukeExceptionThrow.java +++ b/src/main/java/duke/core/DukeExceptionThrow.java @@ -1,4 +1,6 @@ -class DukeExceptionThrow extends Exception +package duke.core; + +public class DukeExceptionThrow extends Exception { public DukeExceptionThrow(String message) { super(message); diff --git a/src/main/java/Parser.java b/src/main/java/duke/core/Parser.java similarity index 85% rename from src/main/java/Parser.java rename to src/main/java/duke/core/Parser.java index 85b473fe08..4bfe8b22bc 100644 --- a/src/main/java/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -1,14 +1,21 @@ +package duke.core; + +import duke.command.*; +import duke.task.Deadline; +import duke.task.Events; +import duke.task.ToDos; + /** - * Represents a Parser that parses user input into a specific - * type of Command. + * Represents a duke.core.Parser that parses user input into a specific + * type of duke.command.Command. */ public class Parser { private static String[] substring; /** - * Parses a Task from a string array. + * Parses a duke.task.Task from a string array. * @param ss The string array to be parsed. - * @return The Command received from user. + * @return The duke.command.Command received from user. */ public static Command Parse(String ss) throws DukeExceptionThrow { diff --git a/src/main/java/Storage.java b/src/main/java/duke/core/Storage.java similarity index 87% rename from src/main/java/Storage.java rename to src/main/java/duke/core/Storage.java index 1b93b030d2..e71906ce2a 100644 --- a/src/main/java/Storage.java +++ b/src/main/java/duke/core/Storage.java @@ -1,13 +1,19 @@ +package duke.core; + +import duke.task.Deadline; +import duke.task.Events; +import duke.task.Task; +import duke.task.ToDos; + import java.io.File; import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; -import java.util.List; import java.util.Scanner; /** - * Represents a Storage class that deals with reading tasks from + * Represents a duke.core.Storage class that deals with reading tasks from * a file and saving tasks in the file. */ public class Storage { @@ -16,7 +22,7 @@ public class Storage { */ private String filePath; /** - * Constructs a Storage object with a specific file path. + * Constructs a duke.core.Storage object with a specific file path. * @param path A string that represents the path of the file to read or * write. */ @@ -25,7 +31,7 @@ public Storage(String path) { } /** * Read tasks from the file and store into a ArrayList of - * Task. + * duke.task.Task. * @return A ArrayList of tasks from the file. * @throws DukeExceptionThrow If file is not found. */ @@ -75,7 +81,7 @@ public ArrayList load() throws DukeExceptionThrow } /** * Saves tasks to the local file. - * @param task The TaskList storing tasks. + * @param task The duke.core.TaskList storing tasks. * @throws DukeExceptionThrow If writing to the local file failed. */ public void save(ArrayList task) { diff --git a/src/main/java/TaskList.java b/src/main/java/duke/core/TaskList.java similarity index 60% rename from src/main/java/TaskList.java rename to src/main/java/duke/core/TaskList.java index b8c015ccf3..bb491f859b 100644 --- a/src/main/java/TaskList.java +++ b/src/main/java/duke/core/TaskList.java @@ -1,6 +1,10 @@ +package duke.core; + +import duke.task.Task; + import java.util.ArrayList; /** - * Represents a list of Task that can perform operations such as + * Represents a list of duke.task.Task that can perform operations such as * add and delete on the tasks. */ public class TaskList { @@ -10,7 +14,7 @@ public class TaskList { protected ArrayList taskList; /** - * instantiate a new TaskList with a empty list. + * instantiate a new duke.core.TaskList with a empty list. */ public TaskList(ArrayList task) { this.taskList = task; @@ -22,23 +26,23 @@ public ArrayList fullTaskList(){ return taskList; } /** - * Adds a Task to the list. - * @param t The Task to be added to the list. + * Adds a duke.task.Task to the list. + * @param t The duke.task.Task to be added to the list. */ public void addTask(Task t) { taskList.add(t); } /** - * Removes the Task with the given index from the list. - * @param i The index of the Task to be deleted. + * Removes the duke.task.Task with the given index from the list. + * @param i The index of the duke.task.Task to be deleted. */ public void deleteTask(Integer i) throws IndexOutOfBoundsException { taskList.remove(i - 1); } /** - * Returns the Task in the list with the given index. - * @param i The index of the Task. - * @return The Task in the list with the specific index. + * Returns the duke.task.Task in the list with the given index. + * @param i The index of the duke.task.Task. + * @return The duke.task.Task in the list with the specific index. */ public Task getTask(int i) throws IndexOutOfBoundsException { return taskList.get(i - 1); diff --git a/src/main/java/Ui.java b/src/main/java/duke/core/Ui.java similarity index 75% rename from src/main/java/Ui.java rename to src/main/java/duke/core/Ui.java index a7a6760007..711e769023 100644 --- a/src/main/java/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -1,3 +1,7 @@ +package duke.core; + +import duke.task.Task; + import java.util.ArrayList; import java.util.Scanner; @@ -10,7 +14,7 @@ public class Ui { */ private Scanner sc; /** - * Constructs a Ui object and initializes the + * Constructs a duke.core.Ui object and initializes the * Scanner to read user input from the system. */ public Ui() { @@ -28,26 +32,26 @@ public void showError(String e) { System.out.println( "☹ OOPS!!!" + e); } /** - * Shows that a Task has been added, and displays the number + * Shows that a duke.task.Task has been added, and displays the number * of current tasks in the list. - * @param t The Task that is added to the list. - * @param size The number of tasks stored in the TaskList. + * @param t The duke.task.Task that is added to the list. + * @param size The number of tasks stored in the duke.core.TaskList. */ public void taskAdded(Task t, int size) { System.out.println("Got it. I've added this task: \n " + t.toString() + "\nNow you have " + size + " tasks in the list."); } /** - * Shows that a Task has been marked as done. - * @param t The Task that is marked as done. + * Shows that a duke.task.Task has been marked as done. + * @param t The duke.task.Task that is marked as done. */ public void markedAsDone(Task t) { System.out.println("Nice! I've marked this task as done: \n " + t.printStatus()); } /** - * Shows that a Task has been removed, and displays the number + * Shows that a duke.task.Task has been removed, and displays the number * of current tasks in the list. - * @param t The Task that is deleted from the list. + * @param t The duke.task.Task that is deleted from the list. */ public void taskRemoved(Task t, int size) { System.out.println("Noted. I've removed this task: \n " + t.toString() + "\nNow you have " @@ -55,7 +59,7 @@ public void taskRemoved(Task t, int size) { } /** * Find and display a specific task stored in the list. - * @param a TaskList used to store tasks. + * @param a duke.core.TaskList used to store tasks. * @param name name of the task to be found */ public void taskFound(ArrayList a, String name){ @@ -76,7 +80,7 @@ public void showLine() { } /** * Displays all tasks currently stored in the list. - * @param tasks The TaskList used to store tasks. + * @param tasks The duke.core.TaskList used to store tasks. */ public void listTasks(TaskList tasks) { System.out.println("Here are the tasks in your list:"); @@ -92,7 +96,7 @@ public void exitInformation(){ System.out.println("Bye. Hope to see you again soon!"); } /** - * Shows Duke logo and welcome message, and user input instructions. + * Shows duke.Duke logo and welcome message, and user input instructions. */ public void showWelcome() { String logo = " ____ _ \n" @@ -101,7 +105,7 @@ public void showWelcome() { + "| |_| | |_| | < __/\n" + "|____/ \\__,_|_|\\_\\___|\n"; System.out.println("Hello from\n" + logo); - System.out.println("Hello! I'm Duke\nWhat can I do for you?"); + System.out.println("Hello! I'm duke.Duke\nWhat can I do for you?"); } /** * Shows an error in loading the file where past tasks are stored. diff --git a/src/main/java/Deadline.java b/src/main/java/duke/task/Deadline.java similarity index 83% rename from src/main/java/Deadline.java rename to src/main/java/duke/task/Deadline.java index 590632226c..eec1b5c9bf 100644 --- a/src/main/java/Deadline.java +++ b/src/main/java/duke/task/Deadline.java @@ -1,11 +1,8 @@ -import java.text.ParseException; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.time.format.DateTimeParseException; +package duke.task; + /** * Represents a task with a deadline. It is - * extended from the Task class. + * extended from the duke.task.Task class. */ public class Deadline extends Task { /** @@ -13,7 +10,7 @@ public class Deadline extends Task { */ protected String by; /** - * Constructs a Deadline object. Date and time are parsed and + * Constructs a duke.task.Deadline object. Date and time are parsed and * stored in dateTime field if input is of "dd/MM/yyyy HHmm" * format. * @param description A string that describes the specific diff --git a/src/main/java/Events.java b/src/main/java/duke/task/Events.java similarity index 88% rename from src/main/java/Events.java rename to src/main/java/duke/task/Events.java index 1f036a1c39..1efa21b73d 100644 --- a/src/main/java/Events.java +++ b/src/main/java/duke/task/Events.java @@ -1,11 +1,8 @@ -import java.time.DateTimeException; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.time.format.DateTimeParseException; +package duke.task; /** * Represents a task with a event. It is - * extended from the Task class. + * extended from the duke.task.Task class. */ public class Events extends Task { /** diff --git a/src/main/java/Task.java b/src/main/java/duke/task/Task.java similarity index 94% rename from src/main/java/Task.java rename to src/main/java/duke/task/Task.java index b966bd8728..58fe4baca3 100644 --- a/src/main/java/Task.java +++ b/src/main/java/duke/task/Task.java @@ -1,3 +1,5 @@ +package duke.task; + import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; @@ -8,7 +10,7 @@ import java.util.Date; /** - * Represents a task. Task is an abstract class that can not be + * Represents a task. duke.task.Task is an abstract class that can not be * instantiated */ public abstract class Task { @@ -26,7 +28,7 @@ public abstract class Task { protected LocalDateTime ld; /** - * Initialises the minimum fields required to setup a Task. + * Initialises the minimum fields required to setup a duke.task.Task. * @param description A string that represents the description of certain task. */ public Task(String description) { @@ -50,7 +52,7 @@ public String getStatusIcon() { * Returns a string with the following format to be stored in a local file * @return A string in a specific format to be stored in a local file. */ - abstract String writeTxt(); + public abstract String writeTxt(); /** * Marks the task as done. */ diff --git a/src/main/java/ToDos.java b/src/main/java/duke/task/ToDos.java similarity index 95% rename from src/main/java/ToDos.java rename to src/main/java/duke/task/ToDos.java index d54f75e940..b9f8b2454e 100644 --- a/src/main/java/ToDos.java +++ b/src/main/java/duke/task/ToDos.java @@ -1,6 +1,8 @@ +package duke.task; + /** * Represents a task without a specific time. This class - * extends from the Task class. + * extends from the duke.task.Task class. */ public class ToDos extends Task { protected boolean isToDo; From 3f8126095594623b168b656c7d4cac77f4ec1baa Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Wed, 11 Sep 2019 16:38:02 +0800 Subject: [PATCH 006/420] Rename Todos and Events to Todo and Event for standardisation in naming --- src/main/java/duke/core/Parser.java | 8 ++++---- src/main/java/duke/core/Storage.java | 8 ++++---- src/main/java/duke/task/{Events.java => Event.java} | 4 ++-- src/main/java/duke/task/{ToDos.java => ToDo.java} | 4 ++-- 4 files changed, 12 insertions(+), 12 deletions(-) rename src/main/java/duke/task/{Events.java => Event.java} (94%) rename src/main/java/duke/task/{ToDos.java => ToDo.java} (94%) diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index 4bfe8b22bc..bd3af0746a 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -2,8 +2,8 @@ import duke.command.*; import duke.task.Deadline; -import duke.task.Events; -import duke.task.ToDos; +import duke.task.Event; +import duke.task.ToDo; /** * Represents a duke.core.Parser that parses user input into a specific @@ -40,7 +40,7 @@ public static Command Parse(String ss) throws DukeExceptionThrow } case "todo": try{ - ToDos t = new ToDos(command[1]); + ToDo t = new ToDo(command[1]); return new AddCommand(t); }catch(Exception e){ throw new DukeExceptionThrow(e.getMessage()); @@ -56,7 +56,7 @@ public static Command Parse(String ss) throws DukeExceptionThrow case "event": try{ String[] temp1 = command[1].split(" /at "); - Events z = new Events(temp1[0], temp1[1]); + Event z = new Event(temp1[0], temp1[1]); return new AddCommand(z); }catch(Exception e) { throw new DukeExceptionThrow(e.getMessage()); diff --git a/src/main/java/duke/core/Storage.java b/src/main/java/duke/core/Storage.java index e71906ce2a..35c67d773f 100644 --- a/src/main/java/duke/core/Storage.java +++ b/src/main/java/duke/core/Storage.java @@ -1,9 +1,9 @@ package duke.core; import duke.task.Deadline; -import duke.task.Events; +import duke.task.Event; import duke.task.Task; -import duke.task.ToDos; +import duke.task.ToDo; import java.io.File; import java.io.FileNotFoundException; @@ -45,7 +45,7 @@ public ArrayList load() throws DukeExceptionThrow String[] newTask = ss.nextLine().split(" \\| "); if (newTask[0].equals("T")) { - Task x = new ToDos(newTask[2]); + Task x = new ToDo(newTask[2]); if (newTask[1].equals("1")) { x.markAsDone(); @@ -63,7 +63,7 @@ public ArrayList load() throws DukeExceptionThrow } if (newTask[0].equals("E")) { - Task t = new Events(newTask[2], newTask[3]); + Task t = new Event(newTask[2], newTask[3]); if (newTask[1].equals("1")) { t.markAsDone(); diff --git a/src/main/java/duke/task/Events.java b/src/main/java/duke/task/Event.java similarity index 94% rename from src/main/java/duke/task/Events.java rename to src/main/java/duke/task/Event.java index 1efa21b73d..52ee530121 100644 --- a/src/main/java/duke/task/Events.java +++ b/src/main/java/duke/task/Event.java @@ -4,7 +4,7 @@ * Represents a task with a event. It is * extended from the duke.task.Task class. */ -public class Events extends Task { +public class Event extends Task { /** * A string that represents the time of the event. */ @@ -16,7 +16,7 @@ public class Events extends Task { * @param description A string that saves the description of the task. * @param at A string that specifies the time of the event. */ - public Events(String description, String at) { + public Event(String description, String at) { super(description); this.at = at; } diff --git a/src/main/java/duke/task/ToDos.java b/src/main/java/duke/task/ToDo.java similarity index 94% rename from src/main/java/duke/task/ToDos.java rename to src/main/java/duke/task/ToDo.java index b9f8b2454e..fc5597652a 100644 --- a/src/main/java/duke/task/ToDos.java +++ b/src/main/java/duke/task/ToDo.java @@ -4,14 +4,14 @@ * Represents a task without a specific time. This class * extends from the duke.task.Task class. */ -public class ToDos extends Task { +public class ToDo extends Task { protected boolean isToDo; /** * Constructs a ToDo object. * @param description A string of the task description. */ - public ToDos(String description) { + public ToDo(String description) { super(description); this.isToDo = true; } From af2ee05d939be94074769909820ec03923d4dbae Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Wed, 11 Sep 2019 16:44:28 +0800 Subject: [PATCH 007/420] Changed protected instance variables in tasks to private --- src/main/java/duke/core/TaskList.java | 2 +- src/main/java/duke/task/Deadline.java | 2 +- src/main/java/duke/task/Event.java | 2 +- src/main/java/duke/task/Task.java | 2 +- src/main/java/duke/task/ToDo.java | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/duke/core/TaskList.java b/src/main/java/duke/core/TaskList.java index bb491f859b..fa3c8d609b 100644 --- a/src/main/java/duke/core/TaskList.java +++ b/src/main/java/duke/core/TaskList.java @@ -11,7 +11,7 @@ public class TaskList { /** * An ArrayList structure. */ - protected ArrayList taskList; + private ArrayList taskList; /** * instantiate a new duke.core.TaskList with a empty list. diff --git a/src/main/java/duke/task/Deadline.java b/src/main/java/duke/task/Deadline.java index eec1b5c9bf..e7ecbbf6c4 100644 --- a/src/main/java/duke/task/Deadline.java +++ b/src/main/java/duke/task/Deadline.java @@ -8,7 +8,7 @@ public class Deadline extends Task { /** * A string that represents the deadline of the task. */ - protected String by; + private String by; /** * Constructs a duke.task.Deadline object. Date and time are parsed and * stored in dateTime field if input is of "dd/MM/yyyy HHmm" diff --git a/src/main/java/duke/task/Event.java b/src/main/java/duke/task/Event.java index 52ee530121..44291b5c65 100644 --- a/src/main/java/duke/task/Event.java +++ b/src/main/java/duke/task/Event.java @@ -8,7 +8,7 @@ public class Event extends Task { /** * A string that represents the time of the event. */ - protected String at; + private String at; /** * Constructs a Event object. Date and time are parsed and * stored in dateTime field if input is of "dd/MM/yyyy HHmm" diff --git a/src/main/java/duke/task/Task.java b/src/main/java/duke/task/Task.java index 58fe4baca3..46b47f2931 100644 --- a/src/main/java/duke/task/Task.java +++ b/src/main/java/duke/task/Task.java @@ -17,7 +17,7 @@ public abstract class Task { /** * A String that represents the description of the task. */ - protected String description; + String description; /** * A boolean that represents the status of the task( 1 means done, 0 means not yet) */ diff --git a/src/main/java/duke/task/ToDo.java b/src/main/java/duke/task/ToDo.java index fc5597652a..16f989f01a 100644 --- a/src/main/java/duke/task/ToDo.java +++ b/src/main/java/duke/task/ToDo.java @@ -5,7 +5,7 @@ * extends from the duke.task.Task class. */ public class ToDo extends Task { - protected boolean isToDo; + private boolean isToDo; /** * Constructs a ToDo object. From 9cdfbd2eefe8405effedfa1a4a57e0174f75724d Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Wed, 11 Sep 2019 16:47:54 +0800 Subject: [PATCH 008/420] Added prefix "Oops" to warning of DukeExceptionThrow --- src/main/java/duke/core/DukeExceptionThrow.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/duke/core/DukeExceptionThrow.java b/src/main/java/duke/core/DukeExceptionThrow.java index 632ac2715a..d7d834366f 100644 --- a/src/main/java/duke/core/DukeExceptionThrow.java +++ b/src/main/java/duke/core/DukeExceptionThrow.java @@ -3,6 +3,6 @@ public class DukeExceptionThrow extends Exception { public DukeExceptionThrow(String message) { - super(message); + super("Oops !!!" + message); } } \ No newline at end of file From 791e6101b26cabea56b18f563435ac6b7d4d1b2f Mon Sep 17 00:00:00 2001 From: Qian Jie Date: Wed, 11 Sep 2019 19:52:38 +0800 Subject: [PATCH 009/420] Added Google doc links to README.md --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 84755485a7..e818611f28 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,8 @@ +# Links + +**Team Google Doc link** +https://docs.google.com/document/d/1G6Bvc2kW0bpxYXVxCz2mC2vUknmPyHRZJHdE9Et25LQ/edit?usp=sharing + # Setting up **Prerequisites** From 02017387e9fd046bcc945fb7eaa7ba366fb2cdb0 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Wed, 11 Sep 2019 22:18:40 +0800 Subject: [PATCH 010/420] Update JavaDocs in main --- src/main/java/duke/Duke.java | 14 +++++----- src/main/java/duke/command/AddCommand.java | 16 +++++------ src/main/java/duke/command/Command.java | 4 +-- src/main/java/duke/command/DeleteCommand.java | 12 ++++---- src/main/java/duke/command/DoneCommand.java | 12 ++++---- src/main/java/duke/command/ExitCommand.java | 6 ++-- src/main/java/duke/command/FindCommand.java | 8 +++--- src/main/java/duke/command/ListCommand.java | 12 ++++---- src/main/java/duke/core/Parser.java | 8 +++--- src/main/java/duke/core/Storage.java | 11 ++++---- src/main/java/duke/core/TaskList.java | 22 +++++++-------- src/main/java/duke/core/Ui.java | 28 +++++++++---------- src/main/java/duke/task/Deadline.java | 6 ++-- src/main/java/duke/task/Event.java | 6 ++-- src/main/java/duke/task/Task.java | 4 +-- src/main/java/duke/task/ToDo.java | 4 +-- 16 files changed, 86 insertions(+), 87 deletions(-) diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index faec24ec3c..388325be02 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -5,26 +5,26 @@ import duke.core.*; /** - * Represents duke.Duke, a Personal Assistant to help + * Represents Duke, a Personal Assistant to help * users tracking their progress. */ public class Duke { /** - * A duke.core.Storage object that handles reading tasks from a local + * A duke.Storage object that handles reading tasks from a local * file and saving them to the same file. */ private Storage storage; /** - * A duke.core.TaskList object that deals with add, delete, mark as done, + * A duke.TaskList object that deals with add, delete, mark as done, * find functions of a list of tasks. */ private TaskList tasks; /** - * A duke.core.Ui object that deals with interactions with the user. + * A Ui object that deals with interactions with the user. */ private Ui ui; /** - * Constructs a duke.Duke object with a relative file path. + * Constructs a Duke object with a relative file path. * Initialize the user interface and reads tasks from the specific text file. * @param filePath A string that represents the path of the local file * used for storing tasks. @@ -40,7 +40,7 @@ public Duke(String filePath) { } } /** - * Runs the duke.Duke program. + * Runs the Duke program. * Reads user input until a "bye" message is received. */ private void run() { @@ -61,7 +61,7 @@ private void run() { } } /** - * Starts the duke.Duke program by passing in a specific file + * Starts the Duke program by passing in a specific file * path. * @param args The command line arguments. */ diff --git a/src/main/java/duke/command/AddCommand.java b/src/main/java/duke/command/AddCommand.java index 406c7db20f..31dbd2f131 100644 --- a/src/main/java/duke/command/AddCommand.java +++ b/src/main/java/duke/command/AddCommand.java @@ -7,10 +7,10 @@ import duke.task.Task; /** - * Represents a command class to add a task. The duke.command.AddCommand class - * extends from the duke.command.Command class to represent user instruction - * to add a new ToDo, duke.task.Deadline or Event - * task to the duke.core.TaskList. + * Represents a command class to add a task. The AddCommand class + * extends from the Command class to represent user instruction + * to add a new ToDo, Deadline or Event + * task to the duke.core.TaskList. */ public class AddCommand extends Command { /** @@ -18,12 +18,12 @@ public class AddCommand extends Command { */ private Task t; /** - * Constructs a duke.command.AddCommand object. - * @param tt Specifies the task to be added. + * Constructs a AddCommand object. + * @param task Specifies the task to be added. */ - public AddCommand(Task tt) { + public AddCommand(Task task) { super(); - this.t = tt; + this.t = task; } /** * Indicates whether duke.Duke should exist diff --git a/src/main/java/duke/command/Command.java b/src/main/java/duke/command/Command.java index 0ec83fef74..66deb31996 100644 --- a/src/main/java/duke/command/Command.java +++ b/src/main/java/duke/command/Command.java @@ -13,7 +13,7 @@ public abstract class Command { /** - * run the command with the respect duke.core.TaskList, UI, and storage. + * run the command with the respect TaskList, UI, and storage. * @param tasks The task list where tasks are saved. * @param ui The user interface. * @param storage object that handles local text file update @@ -23,7 +23,7 @@ public abstract class Command { public abstract void run(TaskList tasks, Ui ui, Storage storage) throws DukeExceptionThrow; /** * Decide whether duke should exist. - * @return A boolean. True if the command tells duke.Duke to exit, false + * @return A boolean. True if the command tells Duke to exit, false * otherwise. */ public abstract boolean isExit(); diff --git a/src/main/java/duke/command/DeleteCommand.java b/src/main/java/duke/command/DeleteCommand.java index 607cda6b98..b472857912 100644 --- a/src/main/java/duke/command/DeleteCommand.java +++ b/src/main/java/duke/command/DeleteCommand.java @@ -7,8 +7,8 @@ import duke.task.Task; /** - * Represents a command to delete a task. The duke.command.DeleteCommand class - * extends from the duke.command.Command class to represent user instruction + * Represents a command to delete a task. The command.DeleteCommand class + * extends from the Command class to represent user instruction * to delete an task from task list. */ public class DeleteCommand extends Command { @@ -17,7 +17,7 @@ public class DeleteCommand extends Command { */ private int Id; /** - * Constructs a duke.command.DeleteCommand object. + * Constructs a DeleteCommand object. * @param taskId Specifies the index of the task to be deleted. */ @@ -26,8 +26,8 @@ public DeleteCommand(int taskId) { this.Id = taskId; } /** - * Indicates whether duke.Duke should exist - * @return A boolean. True if the command tells duke.Duke to exit, false + * Indicates whether Duke should exist + * @return A boolean. True if the command tells Duke to exit, false * otherwise. */ @Override @@ -35,7 +35,7 @@ public boolean isExit() { return false; } /** - * run the command with the respect duke.core.TaskList, UI, and storage. + * run the command with the respect TaskList, UI, and storage. * @param tasks The task list where tasks are saved. * @param ui The user interface. * @param storage object that handles local text file update diff --git a/src/main/java/duke/command/DoneCommand.java b/src/main/java/duke/command/DoneCommand.java index 569d8b3a68..89eb37737f 100644 --- a/src/main/java/duke/command/DoneCommand.java +++ b/src/main/java/duke/command/DoneCommand.java @@ -7,8 +7,8 @@ import duke.task.Task; /** - * Represents a command to mark a task as done. The duke.command.DoneCommand - * class extends from the duke.command.Command class to represent user + * Represents a command to mark a task as done. The DoneCommand + * class extends from the Command class to represent user * instruction to mark an existing task. */ public class DoneCommand extends Command { @@ -17,7 +17,7 @@ public class DoneCommand extends Command { */ private int Id; /** - * Constructs a duke.command.DoneCommand object. + * Constructs a DoneCommand object. * @param taskId Specifies the index of the task. */ public DoneCommand(int taskId) { @@ -25,8 +25,8 @@ public DoneCommand(int taskId) { this.Id = taskId; } /** - * Indicates whether duke.Duke should exist - * @return A boolean. True if the command tells duke.Duke to exit, false + * Indicates whether Duke should exist + * @return A boolean. True if the command tells Duke to exit, false * otherwise. */ @Override @@ -34,7 +34,7 @@ public boolean isExit() { return false; } /** - * run the command with the respect duke.core.TaskList, UI, and storage. + * run the command with the respect TaskList, UI, and storage. * @param tasks The task list where tasks are saved. * @param ui The user interface. * @param storage object that handles local text file update diff --git a/src/main/java/duke/command/ExitCommand.java b/src/main/java/duke/command/ExitCommand.java index e4bb0b9620..22045a6f82 100644 --- a/src/main/java/duke/command/ExitCommand.java +++ b/src/main/java/duke/command/ExitCommand.java @@ -5,13 +5,13 @@ import duke.core.Ui; /** - * Represents a command to exit duke.Duke. The duke.command.ExitCommand class - * extends from the duke.command.Command class for the user to quit the + * Represents a command to exit Duke. The command.ExitCommand class + * extends from the Command class for the user to quit the * program */ public class ExitCommand extends Command { /** - * Constructs a duke.command.ExitCommand object. + * Constructs a ExitCommand object. */ public ExitCommand() { super(); diff --git a/src/main/java/duke/command/FindCommand.java b/src/main/java/duke/command/FindCommand.java index bbdcae2225..e92abb6cdf 100644 --- a/src/main/java/duke/command/FindCommand.java +++ b/src/main/java/duke/command/FindCommand.java @@ -6,8 +6,8 @@ import duke.core.Ui; /** - * Represents a command to find a certain task from duke.Duke's task list. - * The duke.command.ExitCommand class extends from the duke.command.Command + * Represents a command to find a certain task from Duke's task list. + * The ExitCommand class extends from the Command * class for the user to find a specific task object from the storage. */ public class FindCommand extends Command { @@ -16,7 +16,7 @@ public class FindCommand extends Command { */ private String taskName; /** - * Constructs a duke.command.FindCommand object. + * Constructs a FindCommand object. * @param name Specifies the name of the task. */ public FindCommand(String name) { @@ -24,7 +24,7 @@ public FindCommand(String name) { this.taskName = name; } /** - * Indicates whether duke.Duke should exist + * Indicates whether Duke should exist * @return A boolean. True if the command tells duke.Duke to exit, false * otherwise. */ diff --git a/src/main/java/duke/command/ListCommand.java b/src/main/java/duke/command/ListCommand.java index 1d5b4e4f32..853c10b5ee 100644 --- a/src/main/java/duke/command/ListCommand.java +++ b/src/main/java/duke/command/ListCommand.java @@ -6,19 +6,19 @@ /** * Represents a command to list all existing tasks in the task list. The - * duke.command.ListCommand class extends from the duke.command.Command class - * for the user to view the entire task list from duke.Duke. + * ListCommand class extends from the command.Command class + * for the user to view the entire task list from Duke. */ public class ListCommand extends Command { /** - * Constructs a duke.command.ListCommand object. + * Constructs a command.ListCommand object. */ public ListCommand() { super(); } /** - * Indicates whether duke.Duke should exist - * @return A boolean. True if the command tells duke.Duke to exit, false + * Indicates whether Duke should exist + * @return A boolean. True if the command tells Duke to exit, false * otherwise. */ @Override @@ -26,7 +26,7 @@ public boolean isExit() { return false; } /** - * run the command with the respect duke.core.TaskList, UI, and storage. + * run the command with the respect TaskList, UI, and storage. * @param tasks The task list where tasks are saved. * @param ui The user interface. * @param storage object that handles local text file update diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index bd3af0746a..8165d43c82 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -6,16 +6,16 @@ import duke.task.ToDo; /** - * Represents a duke.core.Parser that parses user input into a specific - * type of duke.command.Command. + * Represents a Parser that parses user input into a specific + * type of Command. */ public class Parser { private static String[] substring; /** - * Parses a duke.task.Task from a string array. + * Parses a Task from a string array. * @param ss The string array to be parsed. - * @return The duke.command.Command received from user. + * @return The Command received from user. */ public static Command Parse(String ss) throws DukeExceptionThrow { diff --git a/src/main/java/duke/core/Storage.java b/src/main/java/duke/core/Storage.java index 35c67d773f..aa5125973f 100644 --- a/src/main/java/duke/core/Storage.java +++ b/src/main/java/duke/core/Storage.java @@ -13,7 +13,7 @@ import java.util.Scanner; /** - * Represents a duke.core.Storage class that deals with reading tasks from + * Represents a Storage class that deals with reading tasks from * a file and saving tasks in the file. */ public class Storage { @@ -22,7 +22,7 @@ public class Storage { */ private String filePath; /** - * Constructs a duke.core.Storage object with a specific file path. + * Constructs a Storage object with a specific file path. * @param path A string that represents the path of the file to read or * write. */ @@ -30,9 +30,8 @@ public Storage(String path) { this.filePath = path; } /** - * Read tasks from the file and store into a ArrayList of - * duke.task.Task. - * @return A ArrayList of tasks from the file. + * Read tasks from the file and store into a ArrayList of task. + * @return A ArrayList of tasks from the file. * @throws DukeExceptionThrow If file is not found. */ public ArrayList load() throws DukeExceptionThrow @@ -81,7 +80,7 @@ public ArrayList load() throws DukeExceptionThrow } /** * Saves tasks to the local file. - * @param task The duke.core.TaskList storing tasks. + * @param task The TaskList storing tasks. * @throws DukeExceptionThrow If writing to the local file failed. */ public void save(ArrayList task) { diff --git a/src/main/java/duke/core/TaskList.java b/src/main/java/duke/core/TaskList.java index fa3c8d609b..9a425a3904 100644 --- a/src/main/java/duke/core/TaskList.java +++ b/src/main/java/duke/core/TaskList.java @@ -4,45 +4,45 @@ import java.util.ArrayList; /** - * Represents a list of duke.task.Task that can perform operations such as + * Represents a list of Task that can perform operations such as * add and delete on the tasks. */ public class TaskList { /** - * An ArrayList structure. + * An ArrayList structure. */ private ArrayList taskList; /** - * instantiate a new duke.core.TaskList with a empty list. + * instantiate a new TaskList with a empty list. */ public TaskList(ArrayList task) { this.taskList = task; } /** - * Retrieve the entire task list stored inside the ArrayList. + * Retrieve the entire task list stored inside the ArrayList. */ public ArrayList fullTaskList(){ return taskList; } /** - * Adds a duke.task.Task to the list. - * @param t The duke.task.Task to be added to the list. + * Adds a Task to the list. + * @param t The Task to be added to the list. */ public void addTask(Task t) { taskList.add(t); } /** - * Removes the duke.task.Task with the given index from the list. - * @param i The index of the duke.task.Task to be deleted. + * Removes the Task with the given index from the list. + * @param i The index of the Task to be deleted. */ public void deleteTask(Integer i) throws IndexOutOfBoundsException { taskList.remove(i - 1); } /** - * Returns the duke.task.Task in the list with the given index. - * @param i The index of the duke.task.Task. - * @return The duke.task.Task in the list with the specific index. + * Returns the Task in the list with the given index. + * @param i The index of the Task. + * @return The Task in the list with the specific index. */ public Task getTask(int i) throws IndexOutOfBoundsException { return taskList.get(i - 1); diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index 711e769023..ddcda0a982 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -10,12 +10,12 @@ */ public class Ui { /** - * A Scanner to read user input. + * A Scanner to read user input. */ private Scanner sc; /** - * Constructs a duke.core.Ui object and initializes the - * Scanner to read user input from the system. + * Constructs a Ui object and initializes the + * Scanner to read user input from the system. */ public Ui() { sc = new Scanner(System.in); @@ -32,26 +32,26 @@ public void showError(String e) { System.out.println( "☹ OOPS!!!" + e); } /** - * Shows that a duke.task.Task has been added, and displays the number + * Shows that a Task has been added, and displays the number * of current tasks in the list. - * @param t The duke.task.Task that is added to the list. - * @param size The number of tasks stored in the duke.core.TaskList. + * @param t The Task that is added to the list. + * @param size The number of tasks stored in the TaskList. */ public void taskAdded(Task t, int size) { System.out.println("Got it. I've added this task: \n " + t.toString() + "\nNow you have " + size + " tasks in the list."); } /** - * Shows that a duke.task.Task has been marked as done. - * @param t The duke.task.Task that is marked as done. + * Shows that a Task has been marked as done. + * @param t The Task that is marked as done. */ public void markedAsDone(Task t) { System.out.println("Nice! I've marked this task as done: \n " + t.printStatus()); } /** - * Shows that a duke.task.Task has been removed, and displays the number + * Shows that a Task has been removed, and displays the number * of current tasks in the list. - * @param t The duke.task.Task that is deleted from the list. + * @param t The Task that is deleted from the list. */ public void taskRemoved(Task t, int size) { System.out.println("Noted. I've removed this task: \n " + t.toString() + "\nNow you have " @@ -59,7 +59,7 @@ public void taskRemoved(Task t, int size) { } /** * Find and display a specific task stored in the list. - * @param a duke.core.TaskList used to store tasks. + * @param a TaskList used to store tasks. * @param name name of the task to be found */ public void taskFound(ArrayList a, String name){ @@ -80,7 +80,7 @@ public void showLine() { } /** * Displays all tasks currently stored in the list. - * @param tasks The duke.core.TaskList used to store tasks. + * @param tasks The TaskList used to store tasks. */ public void listTasks(TaskList tasks) { System.out.println("Here are the tasks in your list:"); @@ -96,7 +96,7 @@ public void exitInformation(){ System.out.println("Bye. Hope to see you again soon!"); } /** - * Shows duke.Duke logo and welcome message, and user input instructions. + * Shows Duke logo and welcome message, and user input instructions. */ public void showWelcome() { String logo = " ____ _ \n" @@ -105,7 +105,7 @@ public void showWelcome() { + "| |_| | |_| | < __/\n" + "|____/ \\__,_|_|\\_\\___|\n"; System.out.println("Hello from\n" + logo); - System.out.println("Hello! I'm duke.Duke\nWhat can I do for you?"); + System.out.println("Hello! I'm Duke\nWhat can I do for you?"); } /** * Shows an error in loading the file where past tasks are stored. diff --git a/src/main/java/duke/task/Deadline.java b/src/main/java/duke/task/Deadline.java index e7ecbbf6c4..0ae0e4429e 100644 --- a/src/main/java/duke/task/Deadline.java +++ b/src/main/java/duke/task/Deadline.java @@ -2,7 +2,7 @@ /** * Represents a task with a deadline. It is - * extended from the duke.task.Task class. + * extended from the Task class. */ public class Deadline extends Task { /** @@ -10,8 +10,8 @@ public class Deadline extends Task { */ private String by; /** - * Constructs a duke.task.Deadline object. Date and time are parsed and - * stored in dateTime field if input is of "dd/MM/yyyy HHmm" + * Constructs a Deadline object. Date and time are parsed and + * stored in dateTime field if input is of "dd/MM/yyyy HHmm" * format. * @param description A string that describes the specific * description of task. diff --git a/src/main/java/duke/task/Event.java b/src/main/java/duke/task/Event.java index 44291b5c65..8307cab339 100644 --- a/src/main/java/duke/task/Event.java +++ b/src/main/java/duke/task/Event.java @@ -2,7 +2,7 @@ /** * Represents a task with a event. It is - * extended from the duke.task.Task class. + * extended from the Task class. */ public class Event extends Task { /** @@ -10,8 +10,8 @@ public class Event extends Task { */ private String at; /** - * Constructs a Event object. Date and time are parsed and - * stored in dateTime field if input is of "dd/MM/yyyy HHmm" + * Constructs a Event object. Date and time are parsed and + * stored in dateTime field if input is of "dd/MM/yyyy HHmm" * format. * @param description A string that saves the description of the task. * @param at A string that specifies the time of the event. diff --git a/src/main/java/duke/task/Task.java b/src/main/java/duke/task/Task.java index 46b47f2931..1f6041d80d 100644 --- a/src/main/java/duke/task/Task.java +++ b/src/main/java/duke/task/Task.java @@ -10,7 +10,7 @@ import java.util.Date; /** - * Represents a task. duke.task.Task is an abstract class that can not be + * Represents a task. Task is an abstract class that can not be * instantiated */ public abstract class Task { @@ -28,7 +28,7 @@ public abstract class Task { protected LocalDateTime ld; /** - * Initialises the minimum fields required to setup a duke.task.Task. + * Initialises the minimum fields required to setup a Task. * @param description A string that represents the description of certain task. */ public Task(String description) { diff --git a/src/main/java/duke/task/ToDo.java b/src/main/java/duke/task/ToDo.java index 16f989f01a..fb2c67b0e1 100644 --- a/src/main/java/duke/task/ToDo.java +++ b/src/main/java/duke/task/ToDo.java @@ -2,13 +2,13 @@ /** * Represents a task without a specific time. This class - * extends from the duke.task.Task class. + * extends from the Task class. */ public class ToDo extends Task { private boolean isToDo; /** - * Constructs a ToDo object. + * Constructs a ToDo object. * @param description A string of the task description. */ public ToDo(String description) { From 8e27b7213fbb176b385d7a17f87d72751fde0476 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Wed, 11 Sep 2019 22:59:28 +0800 Subject: [PATCH 011/420] Created 4 JUnit Test Classes --- src/test/java/DukeTest.java | 10 ---- src/test/java/duke/core/ParserTest.java | 33 +++++++++++++ src/test/java/duke/task/DeadlineTest.java | 59 +++++++++++++++++++++++ src/test/java/duke/task/EventTest.java | 59 +++++++++++++++++++++++ src/test/java/duke/task/TodoTest.java | 59 +++++++++++++++++++++++ 5 files changed, 210 insertions(+), 10 deletions(-) delete mode 100644 src/test/java/DukeTest.java create mode 100644 src/test/java/duke/core/ParserTest.java create mode 100644 src/test/java/duke/task/DeadlineTest.java create mode 100644 src/test/java/duke/task/EventTest.java create mode 100644 src/test/java/duke/task/TodoTest.java diff --git a/src/test/java/DukeTest.java b/src/test/java/DukeTest.java deleted file mode 100644 index 8a14575adc..0000000000 --- a/src/test/java/DukeTest.java +++ /dev/null @@ -1,10 +0,0 @@ -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class DukeTest { - @Test - public void dummyTest(){ - assertEquals(2, 2); - } -} \ No newline at end of file diff --git a/src/test/java/duke/core/ParserTest.java b/src/test/java/duke/core/ParserTest.java new file mode 100644 index 0000000000..bc99d800e0 --- /dev/null +++ b/src/test/java/duke/core/ParserTest.java @@ -0,0 +1,33 @@ +package duke.core; + +import duke.command.*; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class ParserTest { + /** + * Test the return command type of Parser.parse(userInput) + * @throws DukeException + */ + @Test + public void commandTypeTest() throws DukeException { + Command c1 = Parser.parse("bye"); + Command c2 = Parser.parse("done 1"); + Command c3 = Parser.parse("delete 2"); + Command c4 = Parser.parse("list"); + Command c5 = Parser.parse("find MEETING"); + Command c6 = Parser.parse("todo abc"); + Command c7 = Parser.parse("event Meeting /at 2PM"); + Command c8 = Parser.parse("deadline event Homework ABC /by 1PM"); + + assertTrue(c1 instanceof ExitCommand, "The command type should be "); + assertTrue(c2 instanceof DoneCommand, "The command type should be 'DoneCommand'"); + assertTrue(c3 instanceof DeleteCommand, "The command type should be 'DeleteCommand'"); + assertTrue(c4 instanceof ListCommand, "The command type should be 'ListCommand'"); + assertTrue(c5 instanceof FindCommand, "The command type should be 'FindCommand'"); + assertTrue(c6 instanceof AddCommand, "The command type should be 'AddCommand'"); + assertTrue(c7 instanceof AddCommand, "The command type should be 'AddCommand'"); + assertTrue(c8 instanceof AddCommand, "The command type should be 'AddCommand'"); + } +} diff --git a/src/test/java/duke/task/DeadlineTest.java b/src/test/java/duke/task/DeadlineTest.java new file mode 100644 index 0000000000..de7cd87d85 --- /dev/null +++ b/src/test/java/duke/task/DeadlineTest.java @@ -0,0 +1,59 @@ +package duke.task; + +import duke.core.DukeException; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + + +public class DeadlineTest { + + /** + * Test the Deadline.toString() + */ + @Test + public void deadlineStringTest() { + assertEquals( "[D][\u2718] abc (by: 2nd of December 1996, 12PM)", new Deadline("abc", "02/12/1996 1235").toString(),"Deadline toString() is not expected"); + } + + /** + * Test the Deadline.writeTxt() + */ + @Test + public void writeFormatTest() { + assertEquals( "D | 0 | deadlineTest | 02/12/1996 1235",new Deadline("deadlineTest", "02/12/1996 1235").writeTxt(), "The writeToFile format is not expected"); + } + + /** + * Test the Deadline.isDone() after a new Deadline object is being initialized + */ + @Test + public void doneStatusTest() { + assertFalse(new Deadline("abc", "02/12/1996 1235").isDone(), "The newly created Deadline should not be done"); + } + + /** + * A general test case to test Deadline class + * Test steps: + * 1. Create a Deadline object + * 2. Verify Deadline.isdone(), Deadline.toString(), Deadline.writeTxt() + * 3. Mark the Deadline object to isDone status. + * 4. Repeat step 2 + * + * @throws DukeException if markAsDone is applied to a done task, throw exception with log + */ + @Test + public void deadlineTestCase() throws DukeException { + // Create a new deadline and check its toString() and writeTxt() + Deadline deadline = new Deadline("deadlineTest", "02/12/1996 1235"); + assertFalse(deadline.isDone(), "The newly created deadline should not be done"); + assertEquals( "[D][\u2718] deadlineTest (by: 2nd of December 1996, 12PM)",deadline.toString(), "The writeToFile format is not expected"); + assertEquals( "D | 0 | deadlineTest | 02/12/1996 1235",deadline.writeTxt(), "The writeToFile format is not expected"); + + // Mark the deadline as done and check its toString() and writeTxt() + deadline.markAsDone(); + assertTrue(deadline.isDone(), "The deadline should be marked as done"); + assertEquals("[D][\u2713] deadlineTest (by: 2nd of December 1996, 12PM)", deadline.toString(), "The deadline.toString() is not expected"); + assertEquals( "D | 1 | deadlineTest | 02/12/1996 1235",deadline.writeTxt(), "The writeToFile format is not expected"); + } +} diff --git a/src/test/java/duke/task/EventTest.java b/src/test/java/duke/task/EventTest.java new file mode 100644 index 0000000000..9bd8cf0883 --- /dev/null +++ b/src/test/java/duke/task/EventTest.java @@ -0,0 +1,59 @@ + +package duke.task; + +import duke.core.DukeException; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + + +public class EventTest { + /** + * Test the Event.toString() + */ + @Test + public void EventStringTest() { + assertEquals("[E][\u2718] eventTest (at: 2nd of December 1996, 12PM)", new Event("eventTest", "02/12/1996 1235").toString(), "toString result is not expected"); + } + + /** + * Test the Event.writeTxt() + */ + @Test + public void writeFormatTest() { + assertEquals( "E | 0 | test | 02/12/1996 1235",new Event("test", "02/12/1996 1235").writeTxt(), "The writeToFile format is not expected"); + } + + /** + * Test the Event.isDone() after a new Event object is being initialized + */ + @Test + public void doneStatusTest() { + assertFalse(new Event("test", "02/12/1996 1235").isDone(), "The newly created Deadline should not be done"); + } + + /** + * A general test case to test Event class + * Test steps: + * 1. Create a Event object + * 2. Verify Event.isdone(), Event.toString(), Event.writeTxt() + * 3. Mark the Event object to isDone status. + * 4. Repeat step 2 + * + * @throws DukeException if markAsDone is applied to a done task, throw exception with log + */ + @Test + public void eventTestCase() throws DukeException { + // Creata a new event and check its toString() and writeTxt() + Event event = new Event("eventTest", "02/12/1996 1235"); + assertFalse(event.isDone(), "The newly created event should not be done"); + assertEquals( "[E][\u2718] eventTest (at: 2nd of December 1996, 12PM)",event.toString(), "The writeToFile format is not expected"); + assertEquals( "E | 0 | eventTest | 02/12/1996 1235",event.writeTxt(), "The writeToFile format is not expected"); + + // Mark the event as done and check its toString() and writeTxt() + event.markAsDone(); + assertTrue(event.isDone(), "The event should be marked as done"); + assertEquals("[E][\u2713] eventTest (at: 2nd of December 1996, 12PM)", event.toString(), "The event.toString() is not expected"); + assertEquals( "E | 1 | eventTest | 02/12/1996 1235",event.writeTxt(), "The writeToFile format is not expected"); + } +} \ No newline at end of file diff --git a/src/test/java/duke/task/TodoTest.java b/src/test/java/duke/task/TodoTest.java new file mode 100644 index 0000000000..e6e25e2361 --- /dev/null +++ b/src/test/java/duke/task/TodoTest.java @@ -0,0 +1,59 @@ +package duke.task; + +import duke.core.DukeException; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + + +public class TodoTest { + + /** + * Test the todo.toString() + */ + @Test + public void todoStringTest(){ + assertEquals(new Todo("todoTest").toString(), "[T][\u2718] todoTest", "todo string test fails"); + } + + /** + * Test the todo.writeTxt() + */ + @Test + public void writeFormatTest() { + assertEquals( "T | 0 | todoTest",new Todo("todoTest").writeTxt(), "The writeToFile format is not expected"); + } + + /** + * Test the todo.isDone() after a new Todo object is being initialized + */ + @Test + public void doneStatusTest() { + assertFalse(new Todo("abc").isDone(), "The newly created Deadline should not be done"); + } + + /** + * A general test case to test Todo class + * Test steps: + * 1. Create a Todo object + * 2. Verify todo.isdone(), todo.toString(), todo.writeTxt() + * 3. Mark the todo object to isDone status. + * 4. Repeat step 2 + * + * @throws DukeException if markAsDone is applied to a done task, throw exception with log + */ + @Test + public void todoTestCase() throws DukeException { + // Creata a new task and check its toString() and writeTxt() + Todo todo = new Todo("todoTest"); + assertFalse(todo.isDone(), "The newly created todo should not be done"); + assertEquals( "[T][\u2718] todoTest",todo.toString(), "The writeToFile format is not expected"); + assertEquals( "T | 0 | todoTest",todo.writeTxt(), "The writeToFile format is not expected"); + + // Mark the task as done and check its toString() and writeTxt() + todo.markAsDone(); + assertTrue(todo.isDone(), "The todo should be marked as done"); + assertEquals("[T][\u2713] todoTest", todo.toString(), "The todo.toString() is not expected"); + assertEquals( "T | 1 | todoTest",todo.writeTxt(), "The writeToFile format is not expected"); + } +} \ No newline at end of file From db6e60c5966e51a75041ff5e47f871fa6dbb19c3 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Wed, 11 Sep 2019 23:00:13 +0800 Subject: [PATCH 012/420] Update JavaDocs and Comments --- src/main/java/duke/Duke.java | 10 ++-- src/main/java/duke/command/AddCommand.java | 12 ++--- src/main/java/duke/command/Command.java | 6 +-- src/main/java/duke/command/DeleteCommand.java | 4 +- src/main/java/duke/command/DoneCommand.java | 4 +- src/main/java/duke/command/ExitCommand.java | 6 +-- src/main/java/duke/command/FindCommand.java | 8 +-- src/main/java/duke/core/DukeException.java | 8 +++ .../java/duke/core/DukeExceptionThrow.java | 8 --- src/main/java/duke/core/Parser.java | 20 +++---- src/main/java/duke/core/Storage.java | 12 ++--- src/main/java/duke/task/Deadline.java | 7 --- src/main/java/duke/task/Event.java | 8 +-- src/main/java/duke/task/Task.java | 52 ++++++++++++------- src/main/java/duke/task/ToDo.java | 12 +---- 15 files changed, 84 insertions(+), 93 deletions(-) create mode 100644 src/main/java/duke/core/DukeException.java delete mode 100644 src/main/java/duke/core/DukeExceptionThrow.java diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index 388325be02..7cab68db21 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -10,12 +10,12 @@ */ public class Duke { /** - * A duke.Storage object that handles reading tasks from a local + * A Storage object that handles reading tasks from a local * file and saving them to the same file. */ private Storage storage; /** - * A duke.TaskList object that deals with add, delete, mark as done, + * A TaskList object that deals with add, delete, mark as done, * find functions of a list of tasks. */ private TaskList tasks; @@ -34,7 +34,7 @@ public Duke(String filePath) { storage = new Storage(filePath); try { tasks = new TaskList(storage.load()); - } catch (DukeExceptionThrow e) { + } catch (DukeException e) { ui.showLoadingError(); tasks = new TaskList(); } @@ -50,10 +50,10 @@ private void run() { try { String fullCommand = ui.readCommand(); ui.showLine(); - Command c = Parser.Parse(fullCommand); + Command c = Parser.parse(fullCommand); c.run(tasks, ui, storage); isExit = c.isExit(); - } catch (DukeExceptionThrow e) { + } catch (DukeException e) { ui.showError(e.getMessage()); } finally { ui.showLine(); diff --git a/src/main/java/duke/command/AddCommand.java b/src/main/java/duke/command/AddCommand.java index 31dbd2f131..b1c22080f8 100644 --- a/src/main/java/duke/command/AddCommand.java +++ b/src/main/java/duke/command/AddCommand.java @@ -1,6 +1,6 @@ package duke.command; -import duke.core.DukeExceptionThrow; +import duke.core.DukeException; import duke.core.Storage; import duke.core.TaskList; import duke.core.Ui; @@ -10,7 +10,7 @@ * Represents a command class to add a task. The AddCommand class * extends from the Command class to represent user instruction * to add a new ToDo, Deadline or Event - * task to the duke.core.TaskList. + * task to the TaskList. */ public class AddCommand extends Command { /** @@ -26,8 +26,8 @@ public AddCommand(Task task) { this.t = task; } /** - * Indicates whether duke.Duke should exist - * @return A boolean. True if the command tells duke.Duke to exit, false + * Indicates whether Duke should exist + * @return A boolean. True if the command tells Duke to exit, false * otherwise. */ @Override @@ -35,13 +35,13 @@ public boolean isExit() { return false; } /** - * run the command with the respect duke.core.TaskList, UI, and storage. + * run the command with the respect TaskList, UI, and storage. * @param tasks The task list where tasks are saved. * @param ui The user interface. * @param storage object that handles local text file update */ @Override - public void run(TaskList tasks, Ui ui, Storage storage) throws DukeExceptionThrow { + public void run(TaskList tasks, Ui ui, Storage storage) throws DukeException { tasks.addTask(t); ui.taskAdded(t, tasks.getSize()); storage.save(tasks.fullTaskList()); diff --git a/src/main/java/duke/command/Command.java b/src/main/java/duke/command/Command.java index 66deb31996..ca310021e0 100644 --- a/src/main/java/duke/command/Command.java +++ b/src/main/java/duke/command/Command.java @@ -1,6 +1,6 @@ package duke.command; -import duke.core.DukeExceptionThrow; +import duke.core.DukeException; import duke.core.Storage; import duke.core.TaskList; import duke.core.Ui; @@ -17,10 +17,10 @@ public abstract class Command { * @param tasks The task list where tasks are saved. * @param ui The user interface. * @param storage object that handles local text file update - * @throws DukeExceptionThrow throw exception during execution of the + * @throws DukeException throw exception during execution of the * command. */ - public abstract void run(TaskList tasks, Ui ui, Storage storage) throws DukeExceptionThrow; + public abstract void run(TaskList tasks, Ui ui, Storage storage) throws DukeException; /** * Decide whether duke should exist. * @return A boolean. True if the command tells Duke to exit, false diff --git a/src/main/java/duke/command/DeleteCommand.java b/src/main/java/duke/command/DeleteCommand.java index b472857912..fa952d83d6 100644 --- a/src/main/java/duke/command/DeleteCommand.java +++ b/src/main/java/duke/command/DeleteCommand.java @@ -1,6 +1,6 @@ package duke.command; -import duke.core.DukeExceptionThrow; +import duke.core.DukeException; import duke.core.Storage; import duke.core.TaskList; import duke.core.Ui; @@ -40,7 +40,7 @@ public boolean isExit() { * @param ui The user interface. * @param storage object that handles local text file update */ - public void run(TaskList tasks, Ui ui, Storage storage) throws DukeExceptionThrow { + public void run(TaskList tasks, Ui ui, Storage storage) throws DukeException { try { Task t = tasks.getTask(Id); tasks.deleteTask(Id); diff --git a/src/main/java/duke/command/DoneCommand.java b/src/main/java/duke/command/DoneCommand.java index 89eb37737f..ee68db743f 100644 --- a/src/main/java/duke/command/DoneCommand.java +++ b/src/main/java/duke/command/DoneCommand.java @@ -1,6 +1,6 @@ package duke.command; -import duke.core.DukeExceptionThrow; +import duke.core.DukeException; import duke.core.Storage; import duke.core.TaskList; import duke.core.Ui; @@ -40,7 +40,7 @@ public boolean isExit() { * @param storage object that handles local text file update */ @Override - public void run(TaskList tasks, Ui ui, Storage storage) throws DukeExceptionThrow { + public void run(TaskList tasks, Ui ui, Storage storage) throws DukeException { try { Task t = tasks.getTask(Id); diff --git a/src/main/java/duke/command/ExitCommand.java b/src/main/java/duke/command/ExitCommand.java index 22045a6f82..b231b7b543 100644 --- a/src/main/java/duke/command/ExitCommand.java +++ b/src/main/java/duke/command/ExitCommand.java @@ -17,8 +17,8 @@ public ExitCommand() { super(); } /** - * Indicates whether duke.Duke should exist - * @return A boolean. True if the command tells duke.Duke to exit, false + * Indicates whether Duke should exist + * @return A boolean. True if the command tells Duke to exit, false * otherwise. */ @Override @@ -26,7 +26,7 @@ public boolean isExit() { return true; } /** - * run the command with the respect duke.core.TaskList, UI, and storage. + * run the command with the respect TaskList, UI, and storage. * @param tasks The task list where tasks are saved. * @param ui The user interface. * @param storage object that handles local text file update diff --git a/src/main/java/duke/command/FindCommand.java b/src/main/java/duke/command/FindCommand.java index e92abb6cdf..25f87a66d8 100644 --- a/src/main/java/duke/command/FindCommand.java +++ b/src/main/java/duke/command/FindCommand.java @@ -1,6 +1,6 @@ package duke.command; -import duke.core.DukeExceptionThrow; +import duke.core.DukeException; import duke.core.Storage; import duke.core.TaskList; import duke.core.Ui; @@ -25,7 +25,7 @@ public FindCommand(String name) { } /** * Indicates whether Duke should exist - * @return A boolean. True if the command tells duke.Duke to exit, false + * @return A boolean. True if the command tells Duke to exit, false * otherwise. */ @Override @@ -33,13 +33,13 @@ public boolean isExit() { return false; } /** - * run the command with the respect duke.core.TaskList, UI, and storage. + * run the command with the respect TaskList, UI, and storage. * @param tasks The task list where tasks are saved. * @param ui The user interface. * @param storage object that handles local text file update */ @Override - public void run(TaskList tasks, Ui ui, Storage storage) throws DukeExceptionThrow { + public void run(TaskList tasks, Ui ui, Storage storage) throws DukeException { ui.taskFound(tasks.fullTaskList(), taskName); } } \ No newline at end of file diff --git a/src/main/java/duke/core/DukeException.java b/src/main/java/duke/core/DukeException.java new file mode 100644 index 0000000000..318b44eb1f --- /dev/null +++ b/src/main/java/duke/core/DukeException.java @@ -0,0 +1,8 @@ +package duke.core; + +public class DukeException extends Exception +{ + public DukeException(String message) { + super("Oops !!!" + message); + } +} \ No newline at end of file diff --git a/src/main/java/duke/core/DukeExceptionThrow.java b/src/main/java/duke/core/DukeExceptionThrow.java deleted file mode 100644 index d7d834366f..0000000000 --- a/src/main/java/duke/core/DukeExceptionThrow.java +++ /dev/null @@ -1,8 +0,0 @@ -package duke.core; - -public class DukeExceptionThrow extends Exception -{ - public DukeExceptionThrow(String message) { - super("Oops !!!" + message); - } -} \ No newline at end of file diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index 8165d43c82..e1e73b4a7c 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -3,7 +3,7 @@ import duke.command.*; import duke.task.Deadline; import duke.task.Event; -import duke.task.ToDo; +import duke.task.Todo; /** * Represents a Parser that parses user input into a specific @@ -17,7 +17,7 @@ public class Parser { * @param ss The string array to be parsed. * @return The Command received from user. */ - public static Command Parse(String ss) throws DukeExceptionThrow + public static Command parse(String ss) throws DukeException { String[] command = ss.split(" ", 2); @@ -29,21 +29,21 @@ public static Command Parse(String ss) throws DukeExceptionThrow int i = Integer.parseInt(command[1]); return new DoneCommand(i); }catch(Exception e){ - throw new DukeExceptionThrow(e.getMessage()); + throw new DukeException(e.getMessage()); } case "delete": try{ int x = Integer.parseInt(command[1]); return new DeleteCommand(x); }catch(Exception e){ - throw new DukeExceptionThrow(e.getMessage()); + throw new DukeException(e.getMessage()); } case "todo": try{ - ToDo t = new ToDo(command[1]); + Todo t = new Todo(command[1]); return new AddCommand(t); }catch(Exception e){ - throw new DukeExceptionThrow(e.getMessage()); + throw new DukeException(e.getMessage()); } case "deadline": try{ @@ -51,7 +51,7 @@ public static Command Parse(String ss) throws DukeExceptionThrow Deadline d = new Deadline(temp[0], temp[1]); return new AddCommand(d); }catch(Exception e){ - throw new DukeExceptionThrow(e.getMessage()); + throw new DukeException(e.getMessage()); } case "event": try{ @@ -59,18 +59,18 @@ public static Command Parse(String ss) throws DukeExceptionThrow Event z = new Event(temp1[0], temp1[1]); return new AddCommand(z); }catch(Exception e) { - throw new DukeExceptionThrow(e.getMessage()); + throw new DukeException(e.getMessage()); } case "find": try{ return new FindCommand(command[1]); }catch(Exception e) { - throw new DukeExceptionThrow(e.getMessage()); + throw new DukeException(e.getMessage()); } case "bye": return new ExitCommand(); default: - throw new DukeExceptionThrow("Unrecognized user input!"); + throw new DukeException("Unrecognized user input!"); } } diff --git a/src/main/java/duke/core/Storage.java b/src/main/java/duke/core/Storage.java index aa5125973f..e9d650cf93 100644 --- a/src/main/java/duke/core/Storage.java +++ b/src/main/java/duke/core/Storage.java @@ -3,7 +3,7 @@ import duke.task.Deadline; import duke.task.Event; import duke.task.Task; -import duke.task.ToDo; +import duke.task.Todo; import java.io.File; import java.io.FileNotFoundException; @@ -32,9 +32,9 @@ public Storage(String path) { /** * Read tasks from the file and store into a ArrayList of task. * @return A ArrayList of tasks from the file. - * @throws DukeExceptionThrow If file is not found. + * @throws DukeException If file is not found. */ - public ArrayList load() throws DukeExceptionThrow + public ArrayList load() throws DukeException { File newDuke = new File(filePath); ArrayList tasks = new ArrayList<>(); @@ -44,7 +44,7 @@ public ArrayList load() throws DukeExceptionThrow String[] newTask = ss.nextLine().split(" \\| "); if (newTask[0].equals("T")) { - Task x = new ToDo(newTask[2]); + Task x = new Todo(newTask[2]); if (newTask[1].equals("1")) { x.markAsDone(); @@ -75,13 +75,13 @@ public ArrayList load() throws DukeExceptionThrow } catch (FileNotFoundException e) { - throw new DukeExceptionThrow("File is not found!"); + throw new DukeException("File is not found!"); } } /** * Saves tasks to the local file. * @param task The TaskList storing tasks. - * @throws DukeExceptionThrow If writing to the local file failed. + * @throws DukeException If writing to the local file failed. */ public void save(ArrayList task) { try { diff --git a/src/main/java/duke/task/Deadline.java b/src/main/java/duke/task/Deadline.java index 0ae0e4429e..9094ddfa2f 100644 --- a/src/main/java/duke/task/Deadline.java +++ b/src/main/java/duke/task/Deadline.java @@ -33,13 +33,6 @@ public String toString() { return "[D]" + super.printStatus() + " (by: " + super.timeFormatter(by) + ")"; } - /** - * Returns a string with the following format to be read from a local file. - * @return A string in a specific format to be read from a local file. - */ - public String txtFormat() { - return "D | " + (this.isDone ? "1" : "0") + " | " + this.description + " | " + super.timeFormatter(by); - } /** * Returns a string with the following format to be stored in a local file * @return A string in a specific format to be stored in a local file. diff --git a/src/main/java/duke/task/Event.java b/src/main/java/duke/task/Event.java index 8307cab339..40a2bb8636 100644 --- a/src/main/java/duke/task/Event.java +++ b/src/main/java/duke/task/Event.java @@ -29,13 +29,7 @@ public Event(String description, String at) { public String toString() { return "[E]" + super.printStatus() + " (at: " + super.timeFormatter(at) + ")"; } - /** - * Returns a string with the following format to be read from a local file. - * @return A string in a specific format to be read from a local file. - */ - public String txtFormat() { - return "E | " + (this.isDone ? "1" : "0") + " | " + this.description + " | " + super.timeFormatter(at); - } + /** * Returns a string with the following format to be stored in a local file * @return A string in a specific format to be stored in a local file. diff --git a/src/main/java/duke/task/Task.java b/src/main/java/duke/task/Task.java index 1f6041d80d..750e3f8ae1 100644 --- a/src/main/java/duke/task/Task.java +++ b/src/main/java/duke/task/Task.java @@ -29,14 +29,17 @@ public abstract class Task { /** * Initialises the minimum fields required to setup a Task. + * * @param description A string that represents the description of certain task. */ public Task(String description) { this.description = description; this.isDone = false; } + /** * Returns an icon that represents the status of the task. + * * @return Tick if completed, cross if uncompleted. */ public String getStatusIcon() { @@ -44,58 +47,67 @@ public String getStatusIcon() { } /** - * Returns a string with the following format to be read from a local file. - * @return A string in a specific format to be read from a local file. + * Check if the task isDone + * + * @return boolean value of isDone */ - abstract String txtFormat(); + public boolean isDone() { + return this.isDone; + } + /** * Returns a string with the following format to be stored in a local file + * * @return A string in a specific format to be stored in a local file. */ public abstract String writeTxt(); + /** * Marks the task as done. */ - public void markAsDone() - { + public void markAsDone() { isDone = true; } + /** * Returns a string with the status icon and the description of the task. + * * @return A string in a specific format with the status and description of the task. */ - public String printStatus() - { + public String printStatus() { return "[" + this.getStatusIcon() + "] " + description; } + /** * Returns the description of the task. + * * @return A string that represents the specific activity associated with - * the task. + * the task. */ - public String getDescription(){ + public String getDescription() { return description; } - public String timeFormatter(String timeBeforeFormat) { + public String timeFormatter(String timeBeforeFormat) { DateTimeFormatter parser = DateTimeFormatter.ofPattern("dd/MM/yyyy HHmm"); - DateTimeFormatter stFormatter = DateTimeFormatter.ofPattern("d'st of' MMMM yyyy , ha"); - DateTimeFormatter ndFormatter = DateTimeFormatter.ofPattern("d'nd of' MMMM yyyy , ha"); - DateTimeFormatter rdFormatter = DateTimeFormatter.ofPattern("d'rd of' MMMM yyyy , ha"); - DateTimeFormatter thFormatter = DateTimeFormatter.ofPattern("d'th of' MMMM yyyy , ha"); + DateTimeFormatter stFormatter = DateTimeFormatter.ofPattern("d'st of' MMMM yyyy, ha"); + DateTimeFormatter ndFormatter = DateTimeFormatter.ofPattern("d'nd of' MMMM yyyy, ha"); + DateTimeFormatter rdFormatter = DateTimeFormatter.ofPattern("d'rd of' MMMM yyyy, ha"); + DateTimeFormatter thFormatter = DateTimeFormatter.ofPattern("d'th of' MMMM yyyy, ha"); - ld = LocalDateTime.parse(timeBeforeFormat,parser); + ld = LocalDateTime.parse(timeBeforeFormat, parser); String output; - if ((ld.getDayOfMonth()%10) == 1){ + if ((ld.getDayOfMonth() % 10) == 1) { output = ld.format(stFormatter); - }else if ((ld.getDayOfMonth()%10) == 2) { + } else if ((ld.getDayOfMonth() % 10) == 2) { output = ld.format(ndFormatter); - }else if ((ld.getDayOfMonth()%10) == 3) { + } else if ((ld.getDayOfMonth() % 10) == 3) { output = ld.format(rdFormatter); - }else{ - output = ld.format(thFormatter);; + } else { + output = ld.format(thFormatter); + ; } return output; diff --git a/src/main/java/duke/task/ToDo.java b/src/main/java/duke/task/ToDo.java index fb2c67b0e1..40c467a583 100644 --- a/src/main/java/duke/task/ToDo.java +++ b/src/main/java/duke/task/ToDo.java @@ -4,14 +4,14 @@ * Represents a task without a specific time. This class * extends from the Task class. */ -public class ToDo extends Task { +public class Todo extends Task { private boolean isToDo; /** * Constructs a ToDo object. * @param description A string of the task description. */ - public ToDo(String description) { + public Todo(String description) { super(description); this.isToDo = true; } @@ -25,14 +25,6 @@ public String toString() { return "[T]" + super.printStatus(); } - /** - * Returns a string with the following format to be read from a local file. - * @return A string in a specific format to be read from a local file. - */ - public String txtFormat() { - return "T | " + (this.isDone ? "1" : "0") + " | " + this.description; - } - /** * Returns a string with the following format to be stored in a local file * @return A string in a specific format to be stored in a local file. From 5eac2caa2defc2282f869cde6dad1153bdb8487e Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Wed, 11 Sep 2019 23:44:06 +0800 Subject: [PATCH 013/420] Rename instances and variables for naming convention --- data/duke.txt | 5 +- src/main/java/duke/Duke.java | 2 +- src/main/java/duke/command/AddCommand.java | 29 +++++++---- src/main/java/duke/command/Command.java | 13 +++-- src/main/java/duke/command/DeleteCommand.java | 30 +++++++----- src/main/java/duke/command/DoneCommand.java | 33 +++++++------ src/main/java/duke/command/ExitCommand.java | 12 +++-- src/main/java/duke/command/FindCommand.java | 14 ++++-- src/main/java/duke/command/ListCommand.java | 13 +++-- src/main/java/duke/core/DukeException.java | 5 +- src/main/java/duke/core/Parser.java | 49 +++++++++---------- src/main/java/duke/core/Storage.java | 49 +++++++++---------- src/main/java/duke/core/TaskList.java | 28 ++++++++--- src/main/java/duke/core/Ui.java | 40 ++++++++++----- src/main/java/duke/task/Deadline.java | 20 +++++--- src/main/java/duke/task/Event.java | 11 +++-- src/main/java/duke/task/Task.java | 10 ++-- src/main/java/duke/task/ToDo.java | 14 +++--- src/test/java/duke/core/ParserTest.java | 2 +- 19 files changed, 225 insertions(+), 154 deletions(-) diff --git a/data/duke.txt b/data/duke.txt index 5228a44a33..21269034e2 100644 --- a/data/duke.txt +++ b/data/duke.txt @@ -4,8 +4,9 @@ T | 1 | join sports club T | 1 | designduke E | 1 | breakfast | 11/12/2019 1400 T | 1 | assignment1 -D | 1 | project meeting | 10/05/2019 1530 E | 1 | project meeting | 12/05/2019 0700 E | 1 | breakfast | 12/08/2019 1530 D | 1 | ssss | 21/08/2018 1400 -T | 0 | homework (t: 12pm today) +T | 1 | homework (t: 12pm today) +T | 0 | avc +D | 0 | faf | af diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index 7cab68db21..9b652eaf54 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -51,7 +51,7 @@ private void run() { String fullCommand = ui.readCommand(); ui.showLine(); Command c = Parser.parse(fullCommand); - c.run(tasks, ui, storage); + c.execute(tasks, ui, storage); isExit = c.isExit(); } catch (DukeException e) { ui.showError(e.getMessage()); diff --git a/src/main/java/duke/command/AddCommand.java b/src/main/java/duke/command/AddCommand.java index b1c22080f8..b53749ae5e 100644 --- a/src/main/java/duke/command/AddCommand.java +++ b/src/main/java/duke/command/AddCommand.java @@ -1,5 +1,6 @@ package duke.command; +import duke.Duke; import duke.core.DukeException; import duke.core.Storage; import duke.core.TaskList; @@ -16,34 +17,44 @@ public class AddCommand extends Command { /** * A new task to be added */ - private Task t; + private Task task; + /** * Constructs a AddCommand object. + * * @param task Specifies the task to be added. */ public AddCommand(Task task) { super(); - this.t = task; + this.task = task; } + /** * Indicates whether Duke should exist + * * @return A boolean. True if the command tells Duke to exit, false - * otherwise. + * otherwise. */ @Override public boolean isExit() { return false; } + /** * run the command with the respect TaskList, UI, and storage. - * @param tasks The task list where tasks are saved. - * @param ui The user interface. + * + * @param tasks The task list where tasks are saved. + * @param ui The user interface. * @param storage object that handles local text file update */ @Override - public void run(TaskList tasks, Ui ui, Storage storage) throws DukeException { - tasks.addTask(t); - ui.taskAdded(t, tasks.getSize()); - storage.save(tasks.fullTaskList()); + public void execute(TaskList tasks, Ui ui, Storage storage) throws DukeException { + try { + tasks.addTask(task); + ui.taskAdded(task, tasks.getSize()); + storage.save(tasks.fullTaskList()); + } catch (DukeException e) { + throw new DukeException("Fails to add task. " + e.getMessage()); + } } } diff --git a/src/main/java/duke/command/Command.java b/src/main/java/duke/command/Command.java index ca310021e0..cbad3e513d 100644 --- a/src/main/java/duke/command/Command.java +++ b/src/main/java/duke/command/Command.java @@ -14,17 +14,20 @@ public abstract class Command { /** * run the command with the respect TaskList, UI, and storage. - * @param tasks The task list where tasks are saved. - * @param ui The user interface. + * + * @param tasks The task list where tasks are saved. + * @param ui The user interface. * @param storage object that handles local text file update * @throws DukeException throw exception during execution of the - * command. + * command. */ - public abstract void run(TaskList tasks, Ui ui, Storage storage) throws DukeException; + public abstract void execute(TaskList tasks, Ui ui, Storage storage) throws DukeException; + /** * Decide whether duke should exist. + * * @return A boolean. True if the command tells Duke to exit, false - * otherwise. + * otherwise. */ public abstract boolean isExit(); diff --git a/src/main/java/duke/command/DeleteCommand.java b/src/main/java/duke/command/DeleteCommand.java index fa952d83d6..f9c408f2b4 100644 --- a/src/main/java/duke/command/DeleteCommand.java +++ b/src/main/java/duke/command/DeleteCommand.java @@ -15,41 +15,45 @@ public class DeleteCommand extends Command { /** * The index of the task to be deleted. */ - private int Id; + private int taskId; + /** * Constructs a DeleteCommand object. + * * @param taskId Specifies the index of the task to be deleted. */ public DeleteCommand(int taskId) { super(); - this.Id = taskId; + this.taskId = taskId; } + /** * Indicates whether Duke should exist + * * @return A boolean. True if the command tells Duke to exit, false - * otherwise. + * otherwise. */ @Override public boolean isExit() { return false; } + /** * run the command with the respect TaskList, UI, and storage. - * @param tasks The task list where tasks are saved. - * @param ui The user interface. + * + * @param tasks The task list where tasks are saved. + * @param ui The user interface. * @param storage object that handles local text file update */ - public void run(TaskList tasks, Ui ui, Storage storage) throws DukeException { + public void execute(TaskList tasks, Ui ui, Storage storage) throws DukeException { try { - Task t = tasks.getTask(Id); - tasks.deleteTask(Id); - ui.taskRemoved(t, tasks.getSize()); + Task task = tasks.getTask(taskId); + tasks.deleteTask(taskId); + ui.taskRemoved(task, tasks.getSize()); storage.save(tasks.fullTaskList()); - } - catch (IndexOutOfBoundsException e) - { - ui.showError(e.getMessage()); + } catch (DukeException e) { + throw new DukeException("Fails to delete task. " + e.getMessage()); } } } diff --git a/src/main/java/duke/command/DoneCommand.java b/src/main/java/duke/command/DoneCommand.java index ee68db743f..68dd46d23d 100644 --- a/src/main/java/duke/command/DoneCommand.java +++ b/src/main/java/duke/command/DoneCommand.java @@ -15,42 +15,45 @@ public class DoneCommand extends Command { /** * The index of the task to be marked as done. */ - private int Id; + private int taskId; + /** * Constructs a DoneCommand object. + * * @param taskId Specifies the index of the task. */ public DoneCommand(int taskId) { super(); - this.Id = taskId; + this.taskId = taskId; } + /** * Indicates whether Duke should exist + * * @return A boolean. True if the command tells Duke to exit, false - * otherwise. + * otherwise. */ @Override public boolean isExit() { return false; } + /** * run the command with the respect TaskList, UI, and storage. - * @param tasks The task list where tasks are saved. - * @param ui The user interface. + * + * @param tasks The task list where tasks are saved. + * @param ui The user interface. * @param storage object that handles local text file update */ @Override - public void run(TaskList tasks, Ui ui, Storage storage) throws DukeException { - try - { - Task t = tasks.getTask(Id); - t.markAsDone(); + public void execute(TaskList tasks, Ui ui, Storage storage) throws DukeException { + try { + Task task = tasks.getTask(taskId); + task.markAsDone(); storage.save(tasks.fullTaskList()); - ui.markedAsDone(t); - } - catch (IndexOutOfBoundsException e) - { - ui.showError(e.getMessage()); + ui.markedAsDone(task); + } catch (DukeException e) { + throw new DukeException("Fails to mark task as done. " + e.getMessage()); } } } diff --git a/src/main/java/duke/command/ExitCommand.java b/src/main/java/duke/command/ExitCommand.java index b231b7b543..78e97498e5 100644 --- a/src/main/java/duke/command/ExitCommand.java +++ b/src/main/java/duke/command/ExitCommand.java @@ -16,23 +16,27 @@ public class ExitCommand extends Command { public ExitCommand() { super(); } + /** * Indicates whether Duke should exist + * * @return A boolean. True if the command tells Duke to exit, false - * otherwise. + * otherwise. */ @Override public boolean isExit() { return true; } + /** * run the command with the respect TaskList, UI, and storage. - * @param tasks The task list where tasks are saved. - * @param ui The user interface. + * + * @param tasks The task list where tasks are saved. + * @param ui The user interface. * @param storage object that handles local text file update */ @Override - public void run(TaskList tasks, Ui ui, Storage storage) { + public void execute(TaskList tasks, Ui ui, Storage storage) { ui.exitInformation(); } } \ No newline at end of file diff --git a/src/main/java/duke/command/FindCommand.java b/src/main/java/duke/command/FindCommand.java index 25f87a66d8..757efc9001 100644 --- a/src/main/java/duke/command/FindCommand.java +++ b/src/main/java/duke/command/FindCommand.java @@ -15,31 +15,37 @@ public class FindCommand extends Command { * Name of the task to be found. */ private String taskName; + /** * Constructs a FindCommand object. + * * @param name Specifies the name of the task. */ public FindCommand(String name) { super(); this.taskName = name; } + /** * Indicates whether Duke should exist + * * @return A boolean. True if the command tells Duke to exit, false - * otherwise. + * otherwise. */ @Override public boolean isExit() { return false; } + /** * run the command with the respect TaskList, UI, and storage. - * @param tasks The task list where tasks are saved. - * @param ui The user interface. + * + * @param tasks The task list where tasks are saved. + * @param ui The user interface. * @param storage object that handles local text file update */ @Override - public void run(TaskList tasks, Ui ui, Storage storage) throws DukeException { + public void execute(TaskList tasks, Ui ui, Storage storage) throws DukeException { ui.taskFound(tasks.fullTaskList(), taskName); } } \ No newline at end of file diff --git a/src/main/java/duke/command/ListCommand.java b/src/main/java/duke/command/ListCommand.java index 853c10b5ee..674f62485b 100644 --- a/src/main/java/duke/command/ListCommand.java +++ b/src/main/java/duke/command/ListCommand.java @@ -1,5 +1,6 @@ package duke.command; +import duke.core.DukeException; import duke.core.Storage; import duke.core.TaskList; import duke.core.Ui; @@ -16,23 +17,27 @@ public class ListCommand extends Command { public ListCommand() { super(); } + /** * Indicates whether Duke should exist + * * @return A boolean. True if the command tells Duke to exit, false - * otherwise. + * otherwise. */ @Override public boolean isExit() { return false; } + /** * run the command with the respect TaskList, UI, and storage. - * @param tasks The task list where tasks are saved. - * @param ui The user interface. + * + * @param tasks The task list where tasks are saved. + * @param ui The user interface. * @param storage object that handles local text file update */ @Override - public void run(TaskList tasks, Ui ui, Storage storage) { + public void execute(TaskList tasks, Ui ui, Storage storage) throws DukeException { ui.listTasks(tasks); } } \ No newline at end of file diff --git a/src/main/java/duke/core/DukeException.java b/src/main/java/duke/core/DukeException.java index 318b44eb1f..ba6ee52703 100644 --- a/src/main/java/duke/core/DukeException.java +++ b/src/main/java/duke/core/DukeException.java @@ -1,8 +1,7 @@ package duke.core; -public class DukeException extends Exception -{ +public class DukeException extends Exception { public DukeException(String message) { - super("Oops !!!" + message); + super("OOPS!!! " + message); } } \ No newline at end of file diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index e1e73b4a7c..2ff09b4ced 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -14,64 +14,61 @@ public class Parser { /** * Parses a Task from a string array. + * * @param ss The string array to be parsed. * @return The Command received from user. */ - public static Command parse(String ss) throws DukeException - { + public static Command parse(String ss) throws DukeException { + ss = ss.trim(); String[] command = ss.split(" ", 2); switch (command[0]) { case "list": return new ListCommand(); case "done": - try{ - int i = Integer.parseInt(command[1]); - return new DoneCommand(i); - }catch(Exception e){ + try { + int i = Integer.parseInt(command[1]); + return new DoneCommand(i); + } catch (Exception e) { throw new DukeException(e.getMessage()); } case "delete": - try{ - int x = Integer.parseInt(command[1]); - return new DeleteCommand(x); - }catch(Exception e){ + try { + int x = Integer.parseInt(command[1]); + return new DeleteCommand(x); + } catch (Exception e) { throw new DukeException(e.getMessage()); } case "todo": - try{ - Todo t = new Todo(command[1]); - return new AddCommand(t); - }catch(Exception e){ + try { + Todo t = new Todo(command[1]); + return new AddCommand(t); + } catch (Exception e) { throw new DukeException(e.getMessage()); } case "deadline": - try{ + try { String[] temp = command[1].split(" /by "); Deadline d = new Deadline(temp[0], temp[1]); return new AddCommand(d); - }catch(Exception e){ + } catch (Exception e) { throw new DukeException(e.getMessage()); } case "event": - try{ - String[] temp1 = command[1].split(" /at "); - Event z = new Event(temp1[0], temp1[1]); - return new AddCommand(z); - }catch(Exception e) { + try { + String[] temp1 = command[1].split(" /at "); + Event z = new Event(temp1[0], temp1[1]); + return new AddCommand(z); + } catch (Exception e) { throw new DukeException(e.getMessage()); } case "find": - try{ return new FindCommand(command[1]); - }catch(Exception e) { - throw new DukeException(e.getMessage()); - } case "bye": return new ExitCommand(); default: throw new DukeException("Unrecognized user input!"); - } + } } } diff --git a/src/main/java/duke/core/Storage.java b/src/main/java/duke/core/Storage.java index e9d650cf93..0140a8bf59 100644 --- a/src/main/java/duke/core/Storage.java +++ b/src/main/java/duke/core/Storage.java @@ -21,50 +21,47 @@ public class Storage { * A string that represents a relative file path from the project folder. */ private String filePath; + /** * Constructs a Storage object with a specific file path. + * * @param path A string that represents the path of the file to read or - * write. + * write. */ public Storage(String path) { this.filePath = path; } + /** * Read tasks from the file and store into a ArrayList of task. + * * @return A ArrayList of tasks from the file. * @throws DukeException If file is not found. */ - public ArrayList load() throws DukeException - { + public ArrayList load() throws DukeException { File newDuke = new File(filePath); ArrayList tasks = new ArrayList<>(); try { Scanner ss = new Scanner(newDuke); while (ss.hasNext()) { String[] newTask = ss.nextLine().split(" \\| "); - if (newTask[0].equals("T")) - { + if (newTask[0].equals("T")) { Task x = new Todo(newTask[2]); - if (newTask[1].equals("1")) - { + if (newTask[1].equals("1")) { x.markAsDone(); } tasks.add(x); } - if (newTask[0].equals("D")) - { + if (newTask[0].equals("D")) { Task t = new Deadline(newTask[2], newTask[3]); - if (newTask[1].equals("1")) - { + if (newTask[1].equals("1")) { t.markAsDone(); } tasks.add(t); } - if (newTask[0].equals("E")) - { + if (newTask[0].equals("E")) { Task t = new Event(newTask[2], newTask[3]); - if (newTask[1].equals("1")) - { + if (newTask[1].equals("1")) { t.markAsDone(); } tasks.add(t); @@ -72,28 +69,26 @@ public ArrayList load() throws DukeException } return tasks; - } - catch (FileNotFoundException e) - { + } catch (FileNotFoundException e) { throw new DukeException("File is not found!"); } } + /** * Saves tasks to the local file. + * * @param task The TaskList storing tasks. * @throws DukeException If writing to the local file failed. */ - public void save(ArrayList task) { + public void save(ArrayList task) throws DukeException { try { - FileWriter ww = new FileWriter("./data/duke.txt"); - for (Task t : task) - { - ww.write(t.writeTxt() + System.lineSeparator()); + FileWriter fileWriter = new FileWriter("./data/duke.txt"); + for (Task t : task) { + fileWriter.write(t.writeTxt() + System.lineSeparator()); } - ww.close(); - } catch (IOException e) - { - System.out.println("File writing process encounters an error " + e.getMessage()); + fileWriter.close(); + } catch (IOException e) { + throw new DukeException("File writing process encounters an error " + e.getMessage()); } } diff --git a/src/main/java/duke/core/TaskList.java b/src/main/java/duke/core/TaskList.java index 9a425a3904..e764bcd478 100644 --- a/src/main/java/duke/core/TaskList.java +++ b/src/main/java/duke/core/TaskList.java @@ -3,11 +3,12 @@ import duke.task.Task; import java.util.ArrayList; + /** * Represents a list of Task that can perform operations such as * add and delete on the tasks. */ -public class TaskList { +public class TaskList { /** * An ArrayList structure. */ @@ -19,43 +20,58 @@ public class TaskList { public TaskList(ArrayList task) { this.taskList = task; } + /** * Retrieve the entire task list stored inside the ArrayList. */ - public ArrayList fullTaskList(){ + public ArrayList fullTaskList() { return taskList; } + /** * Adds a Task to the list. + * * @param t The Task to be added to the list. */ public void addTask(Task t) { taskList.add(t); } + /** * Removes the Task with the given index from the list. + * * @param i The index of the Task to be deleted. */ - public void deleteTask(Integer i) throws IndexOutOfBoundsException { - taskList.remove(i - 1); + public void deleteTask(Integer i) throws DukeException { + if (getSize() < i) { + throw new DukeException("Task Number " + i + " does not exist"); + } + taskList.remove(i - 1); } + /** * Returns the Task in the list with the given index. + * * @param i The index of the Task. * @return The Task in the list with the specific index. */ - public Task getTask(int i) throws IndexOutOfBoundsException { + public Task getTask(int i) throws DukeException { + if (getSize() < i) { + throw new DukeException("Task Number " + i + " does not exist"); + } return taskList.get(i - 1); } + /** * Returns the size of task list. + * * @return An integer representing the number of tasks in the list. */ public int getSize() { return taskList.size(); } - public TaskList(){ + public TaskList() { taskList = new ArrayList(); } diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index ddcda0a982..dcc9764300 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -12,57 +12,68 @@ public class Ui { /** * A Scanner to read user input. */ - private Scanner sc; + private Scanner scanner; + /** * Constructs a Ui object and initializes the * Scanner to read user input from the system. */ public Ui() { - sc = new Scanner(System.in); + scanner = new Scanner(System.in); } + /** * Reads user instruction. + * * @return A string that represents the user instruction. */ public String readCommand() { - return sc.nextLine(); + return scanner.nextLine(); } public void showError(String e) { - System.out.println( "☹ OOPS!!!" + e); + System.out.println("☹" + e); } + /** * Shows that a Task has been added, and displays the number * of current tasks in the list. - * @param t The Task that is added to the list. + * + * @param t The Task that is added to the list. * @param size The number of tasks stored in the TaskList. */ public void taskAdded(Task t, int size) { System.out.println("Got it. I've added this task: \n " + t.toString() + "\nNow you have " + size + " tasks in the list."); } + /** * Shows that a Task has been marked as done. + * * @param t The Task that is marked as done. */ public void markedAsDone(Task t) { System.out.println("Nice! I've marked this task as done: \n " + t.printStatus()); } + /** * Shows that a Task has been removed, and displays the number * of current tasks in the list. + * * @param t The Task that is deleted from the list. */ public void taskRemoved(Task t, int size) { System.out.println("Noted. I've removed this task: \n " + t.toString() + "\nNow you have " + size + " tasks in the list."); } + /** * Find and display a specific task stored in the list. - * @param a TaskList used to store tasks. + * + * @param a TaskList used to store tasks. * @param name name of the task to be found */ - public void taskFound(ArrayList a, String name){ + public void taskFound(ArrayList a, String name) { System.out.println("Here are the matching tasks in your list:"); int count = 1; for (Task x : a) { @@ -72,29 +83,33 @@ public void taskFound(ArrayList a, String name){ } } } + /** * Shows a divider line. */ public void showLine() { System.out.println("____________________________________________________________"); } + /** * Displays all tasks currently stored in the list. + * * @param tasks The TaskList used to store tasks. */ - public void listTasks(TaskList tasks) { + public void listTasks(TaskList tasks) throws DukeException { System.out.println("Here are the tasks in your list:"); - for (int i = 1; i <= tasks.getSize() ; i++) - { - System.out.println( i + "." + tasks.getTask(i).toString()); + for (int i = 1; i <= tasks.getSize(); i++) { + System.out.println(i + "." + tasks.getTask(i).toString()); } } + /** * Shows bye message to user. */ - public void exitInformation(){ + public void exitInformation() { System.out.println("Bye. Hope to see you again soon!"); } + /** * Shows Duke logo and welcome message, and user input instructions. */ @@ -107,6 +122,7 @@ public void showWelcome() { System.out.println("Hello from\n" + logo); System.out.println("Hello! I'm Duke\nWhat can I do for you?"); } + /** * Shows an error in loading the file where past tasks are stored. */ diff --git a/src/main/java/duke/task/Deadline.java b/src/main/java/duke/task/Deadline.java index 9094ddfa2f..563c04461e 100644 --- a/src/main/java/duke/task/Deadline.java +++ b/src/main/java/duke/task/Deadline.java @@ -9,35 +9,39 @@ public class Deadline extends Task { * A string that represents the deadline of the task. */ private String by; + /** * Constructs a Deadline object. Date and time are parsed and * stored in dateTime field if input is of "dd/MM/yyyy HHmm" * format. + * * @param description A string that describes the specific - * description of task. - * @param by A string that specifies the deadline of the - * task. + * description of task. + * @param by A string that specifies the deadline of the + * task. */ - public Deadline(String description, String by) - { + public Deadline(String description, String by) { super(description); this.by = by; } + /** * Returns a string pattern to the user output + * * @return A string which displays the type, - * description and deadline of the task. + * description and deadline of the task. */ @Override public String toString() { - return "[D]" + super.printStatus() + " (by: " + super.timeFormatter(by) + ")"; + return "[D]" + super.printStatus() + " (by: " + super.timeFormatter(by) + ")"; } /** * Returns a string with the following format to be stored in a local file + * * @return A string in a specific format to be stored in a local file. */ - public String writeTxt(){ + public String writeTxt() { return "D | " + (this.isDone ? "1" : "0") + " | " + this.description + " | " + this.by; } diff --git a/src/main/java/duke/task/Event.java b/src/main/java/duke/task/Event.java index 40a2bb8636..8978cae590 100644 --- a/src/main/java/duke/task/Event.java +++ b/src/main/java/duke/task/Event.java @@ -9,21 +9,25 @@ public class Event extends Task { * A string that represents the time of the event. */ private String at; + /** * Constructs a Event object. Date and time are parsed and * stored in dateTime field if input is of "dd/MM/yyyy HHmm" * format. + * * @param description A string that saves the description of the task. - * @param at A string that specifies the time of the event. + * @param at A string that specifies the time of the event. */ public Event(String description, String at) { super(description); this.at = at; } + /** * Returns a string pattern to the user output + * * @return A string which displays the type, - * description and deadline of the task. + * description and deadline of the task. */ @Override public String toString() { @@ -32,9 +36,10 @@ public String toString() { /** * Returns a string with the following format to be stored in a local file + * * @return A string in a specific format to be stored in a local file. */ - public String writeTxt(){ + public String writeTxt() { return "E | " + (this.isDone ? "1" : "0") + " | " + this.description + " | " + this.at; } } \ No newline at end of file diff --git a/src/main/java/duke/task/Task.java b/src/main/java/duke/task/Task.java index 750e3f8ae1..b1ba0eacaa 100644 --- a/src/main/java/duke/task/Task.java +++ b/src/main/java/duke/task/Task.java @@ -95,7 +95,11 @@ public String timeFormatter(String timeBeforeFormat) { DateTimeFormatter rdFormatter = DateTimeFormatter.ofPattern("d'rd of' MMMM yyyy, ha"); DateTimeFormatter thFormatter = DateTimeFormatter.ofPattern("d'th of' MMMM yyyy, ha"); - ld = LocalDateTime.parse(timeBeforeFormat, parser); + try { + ld = LocalDateTime.parse(timeBeforeFormat, parser); + } catch (DateTimeParseException error) { + return timeBeforeFormat; + } String output; @@ -109,10 +113,6 @@ public String timeFormatter(String timeBeforeFormat) { output = ld.format(thFormatter); ; } - return output; - } - - } \ No newline at end of file diff --git a/src/main/java/duke/task/ToDo.java b/src/main/java/duke/task/ToDo.java index 40c467a583..37abf4352d 100644 --- a/src/main/java/duke/task/ToDo.java +++ b/src/main/java/duke/task/ToDo.java @@ -5,20 +5,21 @@ * extends from the Task class. */ public class Todo extends Task { - private boolean isToDo; /** - * Constructs a ToDo object. + * Constructs a ToDo object. + * * @param description A string of the task description. */ public Todo(String description) { super(description); - this.isToDo = true; } + /** * Returns a string pattern to the user output + * * @return A string which displays the type, - * description and deadline of the task. + * description and deadline of the task. */ @Override public String toString() { @@ -27,10 +28,11 @@ public String toString() { /** * Returns a string with the following format to be stored in a local file + * * @return A string in a specific format to be stored in a local file. */ - public String writeTxt(){ - return "T | " + (this.isDone ? "1" : "0") + " | " + this.description; + public String writeTxt() { + return "T | " + (this.isDone() ? "1" : "0") + " | " + this.description; } } \ No newline at end of file diff --git a/src/test/java/duke/core/ParserTest.java b/src/test/java/duke/core/ParserTest.java index bc99d800e0..4a7617aafe 100644 --- a/src/test/java/duke/core/ParserTest.java +++ b/src/test/java/duke/core/ParserTest.java @@ -8,7 +8,7 @@ public class ParserTest { /** * Test the return command type of Parser.parse(userInput) - * @throws DukeException + * @throws DukeException referencing a Duke specified exception with error log */ @Test public void commandTypeTest() throws DukeException { From d782a764bff641b31da8adc25c8ae4275e9347a4 Mon Sep 17 00:00:00 2001 From: Qian Jie Date: Fri, 13 Sep 2019 21:29:14 +0800 Subject: [PATCH 014/420] Added images folder under docs --- docs/images/qjie7.png | Bin 0 -> 110617 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/images/qjie7.png diff --git a/docs/images/qjie7.png b/docs/images/qjie7.png new file mode 100644 index 0000000000000000000000000000000000000000..9e51a5a5b28477275bd42da38e4b8596023f4751 GIT binary patch literal 110617 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 Lbd3f4|8D{S(;7(N literal 0 HcmV?d00001 From 617cbf14bead2266442f8246a0c80060d6cc9c22 Mon Sep 17 00:00:00 2001 From: Qian Jie Date: Sat, 14 Sep 2019 22:34:30 +0800 Subject: [PATCH 015/420] merged gradle branch to master branch. Tested gradle run and everything worked perfectly. Fixed a minor bug in which the class name was named as ToDo instead of Todo. --- build.gradle | 6 +++--- src/main/java/duke/task/{ToDo.java => Todo.java} | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) rename src/main/java/duke/task/{ToDo.java => Todo.java} (96%) diff --git a/build.gradle b/build.gradle index ce97c7ba2e..eab350c78b 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,7 @@ plugins { id 'application' } -group 'seedu.duke' +group 'duke' version '0.1.0' repositories { @@ -12,9 +12,9 @@ repositories { application { // Change this to your main class. - mainClassName = "seedu.duke.Duke" + mainClassName = "duke/Duke" } run { standardInput = System.in -} \ No newline at end of file +} diff --git a/src/main/java/duke/task/ToDo.java b/src/main/java/duke/task/Todo.java similarity index 96% rename from src/main/java/duke/task/ToDo.java rename to src/main/java/duke/task/Todo.java index 37abf4352d..c20ea65f75 100644 --- a/src/main/java/duke/task/ToDo.java +++ b/src/main/java/duke/task/Todo.java @@ -7,7 +7,7 @@ public class Todo extends Task { /** - * Constructs a ToDo object. + * Constructs a Todo object. * * @param description A string of the task description. */ From 2e95a6ce21dd24c131c040907b663139f20b48f8 Mon Sep 17 00:00:00 2001 From: Qian Jie Date: Sat, 14 Sep 2019 22:42:25 +0800 Subject: [PATCH 016/420] added checkstyle plugin. --- build.gradle | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/build.gradle b/build.gradle index eab350c78b..0b25ee0db7 100644 --- a/build.gradle +++ b/build.gradle @@ -1,11 +1,16 @@ plugins { id 'java' id 'application' + id 'checkstyle' } group 'duke' version '0.1.0' +checkstyle { + toolVersion = '8.23' +} + repositories { mavenCentral() } From 612ddb51bb378285a1b01dfc45cacfee04523c85 Mon Sep 17 00:00:00 2001 From: Qian Jie Date: Sat, 14 Sep 2019 22:46:08 +0800 Subject: [PATCH 017/420] added Shadow plugin that packages an application into an executable jar file --- build.gradle | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/build.gradle b/build.gradle index 0b25ee0db7..851f6a2133 100644 --- a/build.gradle +++ b/build.gradle @@ -2,6 +2,7 @@ plugins { id 'java' id 'application' id 'checkstyle' + id 'com.github.johnrengelman.shadow' version '5.1.0' } group 'duke' @@ -11,6 +12,13 @@ checkstyle { toolVersion = '8.23' } +shadowJar { + archiveBaseName = "duke" + archiveVersion = "0.1.3" + archiveClassifier = null + archiveAppendix = null +} + repositories { mavenCentral() } From df4b3908eba9eb187a58c86be0685daa15e7ae06 Mon Sep 17 00:00:00 2001 From: Qian Jie Date: Sat, 14 Sep 2019 22:53:49 +0800 Subject: [PATCH 018/420] Added dependencies with JUnit --- build.gradle | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/build.gradle b/build.gradle index 851f6a2133..4c4457777f 100644 --- a/build.gradle +++ b/build.gradle @@ -19,6 +19,14 @@ shadowJar { archiveAppendix = null } +dependencies { + testImplementation 'org.junit.jupiter:junit-jupiter:5.5.0' +} + +test { + useJUnitPlatform() +} + repositories { mavenCentral() } From 44418dd3a888b59da2ea82889d29d058a30a9923 Mon Sep 17 00:00:00 2001 From: Qian Jie Date: Sat, 14 Sep 2019 23:35:26 +0800 Subject: [PATCH 019/420] Completed A-Jar by creating mid-v1.1.jar inside ./build/libs/. --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 4c4457777f..69c03f09dd 100644 --- a/build.gradle +++ b/build.gradle @@ -13,8 +13,8 @@ checkstyle { } shadowJar { - archiveBaseName = "duke" - archiveVersion = "0.1.3" + archiveBaseName = "mid" + archiveVersion = "v1.1" archiveClassifier = null archiveAppendix = null } From f2448926fac0fae2dee9778975da3998ca068802 Mon Sep 17 00:00:00 2001 From: WEIFENG-NUSCEG Date: Mon, 16 Sep 2019 00:55:11 +0800 Subject: [PATCH 020/420] added the reminder function The reminder function will keep repeating the task reminder every 20 seconds if the duration between the current time and the deadline is less than one day. To stop the reminder the user have to mark the task as done. --- data/duke.txt | 18 ++--- src/main/java/duke/Duke.java | 45 +++++++----- src/main/java/duke/Reminder.java | 73 +++++++++++++++++++ src/main/java/duke/command/RemindCommand.java | 48 ++++++++++++ src/main/java/duke/core/Ui.java | 14 ++++ src/main/java/duke/task/Deadline.java | 1 + src/main/java/duke/task/Event.java | 1 + src/main/java/duke/task/Task.java | 39 ++++++++-- 8 files changed, 200 insertions(+), 39 deletions(-) create mode 100644 src/main/java/duke/Reminder.java create mode 100644 src/main/java/duke/command/RemindCommand.java diff --git a/data/duke.txt b/data/duke.txt index 21269034e2..0a570d3b91 100644 --- a/data/duke.txt +++ b/data/duke.txt @@ -1,12 +1,6 @@ -D | 1 | return book | 03/04/2019 1800 -E | 1 | project meeting | 05/11/2019 1503 -T | 1 | join sports club -T | 1 | designduke -E | 1 | breakfast | 11/12/2019 1400 -T | 1 | assignment1 -E | 1 | project meeting | 12/05/2019 0700 -E | 1 | breakfast | 12/08/2019 1530 -D | 1 | ssss | 21/08/2018 1400 -T | 1 | homework (t: 12pm today) -T | 0 | avc -D | 0 | faf | af +D | 1 | ssss | 16/09/2019 0200 +D | 1 | tttt | 16/09/2019 0300 +D | 1 | tttt | 16/09/2019 0400 +D | 1 | tttt | 16/09/2019 0500 +E | 1 | tasktest | 16/09/2019 1000 +D | 0 | tasktest2 | 16/09/2019 1200 diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index 9b652eaf54..212bcb7696 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -8,21 +8,21 @@ * Represents Duke, a Personal Assistant to help * users tracking their progress. */ -public class Duke { +public class Duke implements Runnable{ /** * A Storage object that handles reading tasks from a local * file and saving them to the same file. */ - private Storage storage; + public static Storage globalStorage; /** * A TaskList object that deals with add, delete, mark as done, * find functions of a list of tasks. */ - private TaskList tasks; + public static TaskList globalTasks; /** * A Ui object that deals with interactions with the user. */ - private Ui ui; + public static Ui globalUi; /** * Constructs a Duke object with a relative file path. * Initialize the user interface and reads tasks from the specific text file. @@ -30,42 +30,49 @@ public class Duke { * used for storing tasks. */ public Duke(String filePath) { - ui = new Ui(); - storage = new Storage(filePath); + globalUi = new Ui(); + globalStorage = new Storage(filePath); try { - tasks = new TaskList(storage.load()); + globalTasks = new TaskList(globalStorage.load()); } catch (DukeException e) { - ui.showLoadingError(); - tasks = new TaskList(); + globalUi.showLoadingError(); + globalTasks = new TaskList(); } } + /** * Runs the Duke program. * Reads user input until a "bye" message is received. */ - private void run() { - ui.showWelcome(); + public void run() { + globalUi.showWelcome(); boolean isExit = false; while (!isExit) { try { - String fullCommand = ui.readCommand(); - ui.showLine(); + String fullCommand = globalUi.readCommand(); + globalUi.showLine(); Command c = Parser.parse(fullCommand); - c.execute(tasks, ui, storage); + c.execute(globalTasks, globalUi, globalStorage); isExit = c.isExit(); } catch (DukeException e) { - ui.showError(e.getMessage()); + globalUi.showError(e.getMessage()); } finally { - ui.showLine(); + globalUi.showLine(); } } } /** - * Starts the Duke program by passing in a specific file - * path. + * Starts the Duke thread and Reminder thread concurrently + * by passing a filepath to duke and a global ui object& + * task list to Reminder * @param args The command line arguments. */ public static void main(String[] args) { - new Duke("./data/duke.txt").run(); + Duke n = new Duke("./data/duke.txt"); + Reminder r = new Reminder(globalTasks,globalUi); + Thread t1 = new Thread(n); + Thread t2 = new Thread(r); + t1.start(); + t2.start(); } } diff --git a/src/main/java/duke/Reminder.java b/src/main/java/duke/Reminder.java new file mode 100644 index 0000000000..f2204a0fbb --- /dev/null +++ b/src/main/java/duke/Reminder.java @@ -0,0 +1,73 @@ +package duke; + +import duke.core.TaskList; +import duke.core.Ui; +import duke.task.Task; +import java.time.LocalDate; +import java.time.temporal.ChronoUnit; +import java.time.Duration; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.Period; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.util.ArrayList; +import java.util.Date; +import java.util.Timer; +import java.util.TimerTask; + +public class Reminder implements Runnable { + /** + * A constant represents the seconds in a day. + */ + static final int SECONDS_IN_A_DAY = 86400; + /** + * A TaskList object that deals with add, delete, mark as done, + * find functions of a list of tasks. + */ + private TaskList tasks; + /** + * A Ui object that deals with interactions with the user. + */ + private Ui ui; + /** + * Constructs a Reminder object with a TaskList and Ui object. + * @param returnTask A TaskList object that deals with add, delete and other functions. + * @param returnUi A Ui object that deals with interactions with the user. + */ + public Reminder(TaskList returnTask, Ui returnUi) { + this.tasks = returnTask; + this.ui = returnUi; + } + + /** + * Execute the reminder program. + * The methods inside will be triggered base on the Timer's time interval. + */ + public void run() { + TimerTask timerTask = new TimerTask() { + @Override + public void run() { + ArrayList tempTask = new ArrayList<>(); + for (Task v : tasks.fullTaskList()) { + if (!(v.getDateTime() == null)) + { + int seconds = (int) ChronoUnit.SECONDS.between(v.getDateTime(), LocalDateTime.now()); + if ((!v.isDone()) && seconds < SECONDS_IN_A_DAY) { + tempTask.add(v); + } + } + } + if (!tempTask.isEmpty()) { + ui.taskReminder(tempTask); + } + } + }; + + Timer timer = new Timer("Timer"); + long delay = 20000L; + long period = 20000L; + timer.scheduleAtFixedRate(timerTask, delay, period); + } + +} diff --git a/src/main/java/duke/command/RemindCommand.java b/src/main/java/duke/command/RemindCommand.java new file mode 100644 index 0000000000..601396e2ad --- /dev/null +++ b/src/main/java/duke/command/RemindCommand.java @@ -0,0 +1,48 @@ +package duke.command; + +import duke.core.DukeException; +import duke.core.Storage; +import duke.core.TaskList; +import duke.core.Ui; + +/** + * Represents a command to list all existing tasks in the task list. The + * ListCommand class extends from the command.Command class + * for the user to view the entire task list from Duke. + */ +public class RemindCommand extends Command { + /** + * The index of task to be reminded. + */ + protected int taskID; + /** + * Constructs a command.RemindCommand object. + */ + public RemindCommand(int taskName) { + super(); + this.taskID = taskName; + } + + /** + * Indicates whether Duke should exist + * + * @return A boolean. True if the command tells Duke to exit, false + * otherwise. + */ + @Override + public boolean isExit() { + return false; + } + + /** + * run the command with the respect TaskList, UI, and storage. + * + * @param tasks The task list where tasks are saved. + * @param ui The user interface. + * @param storage object that handles local text file update + */ + @Override + public void execute(TaskList tasks, Ui ui, Storage storage) throws DukeException { + ui.listTasks(tasks); + } +} \ No newline at end of file diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index dcc9764300..325a1b3907 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -84,6 +84,20 @@ public void taskFound(ArrayList a, String name) { } } + /** + * Print out the tasks in the task list which is reaching + * the deadline. + * @param a TaskList used to store tasks. + */ + public void taskReminder(ArrayList a) { + System.out.println("The following tasks are reaching your deadline:"); + System.out.println("Mark it as done to stop the reminder"); + int count = 1; + for (Task x : a) { + System.out.println(count + "." + x.toString()); + count++; + } + } /** * Shows a divider line. */ diff --git a/src/main/java/duke/task/Deadline.java b/src/main/java/duke/task/Deadline.java index 563c04461e..ea107c0d33 100644 --- a/src/main/java/duke/task/Deadline.java +++ b/src/main/java/duke/task/Deadline.java @@ -23,6 +23,7 @@ public class Deadline extends Task { public Deadline(String description, String by) { super(description); this.by = by; + super.updateLocalDateTime(by); } /** diff --git a/src/main/java/duke/task/Event.java b/src/main/java/duke/task/Event.java index 8978cae590..d919e40473 100644 --- a/src/main/java/duke/task/Event.java +++ b/src/main/java/duke/task/Event.java @@ -21,6 +21,7 @@ public class Event extends Task { public Event(String description, String at) { super(description); this.at = at; + super.updateLocalDateTime(at); } /** diff --git a/src/main/java/duke/task/Task.java b/src/main/java/duke/task/Task.java index b1ba0eacaa..850c515d9d 100644 --- a/src/main/java/duke/task/Task.java +++ b/src/main/java/duke/task/Task.java @@ -17,7 +17,7 @@ public abstract class Task { /** * A String that represents the description of the task. */ - String description; + protected String description; /** * A boolean that represents the status of the task( 1 means done, 0 means not yet) */ @@ -88,19 +88,19 @@ public String getDescription() { return description; } + /** + * Returns a string that representing the data and time for the task + * in a predefined date time format. + * @param timeBeforeFormat a string that provides the data and time information. + * @return A string that represents the specific activity associated with + * the task. + */ public String timeFormatter(String timeBeforeFormat) { - DateTimeFormatter parser = DateTimeFormatter.ofPattern("dd/MM/yyyy HHmm"); DateTimeFormatter stFormatter = DateTimeFormatter.ofPattern("d'st of' MMMM yyyy, ha"); DateTimeFormatter ndFormatter = DateTimeFormatter.ofPattern("d'nd of' MMMM yyyy, ha"); DateTimeFormatter rdFormatter = DateTimeFormatter.ofPattern("d'rd of' MMMM yyyy, ha"); DateTimeFormatter thFormatter = DateTimeFormatter.ofPattern("d'th of' MMMM yyyy, ha"); - try { - ld = LocalDateTime.parse(timeBeforeFormat, parser); - } catch (DateTimeParseException error) { - return timeBeforeFormat; - } - String output; if ((ld.getDayOfMonth() % 10) == 1) { @@ -115,4 +115,27 @@ public String timeFormatter(String timeBeforeFormat) { } return output; } + + /** + * update the LocalDateTime constructor to save the date and time + * @param time the time retrieved from user input. + */ + public void updateLocalDateTime(String time) + { + DateTimeFormatter parser = DateTimeFormatter.ofPattern("dd/MM/yyyy HHmm"); + try { + ld = LocalDateTime.parse(time, parser); + } catch (DateTimeParseException error) { + System.out.println(error.getMessage()); + } + } + /** + * Returns the data and time information stored in the task without a certain format. + * + * @return A LocalDateTime Variable that contains the date and time information. + */ + public LocalDateTime getDateTime() + { + return ld; + } } \ No newline at end of file From 5090cd60fdca5fc9434e3f8e34d3e4841acc991d Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Mon, 16 Sep 2019 02:51:23 +0800 Subject: [PATCH 021/420] Implement reschedule feature to allow user to reschedule a task. --- src/main/java/duke/command/RescheduleCommand.java | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 src/main/java/duke/command/RescheduleCommand.java diff --git a/src/main/java/duke/command/RescheduleCommand.java b/src/main/java/duke/command/RescheduleCommand.java new file mode 100644 index 0000000000..bf87bf3423 --- /dev/null +++ b/src/main/java/duke/command/RescheduleCommand.java @@ -0,0 +1,4 @@ +package duke.command; + +public class rescheduleCommand { +} From 7d45418372b800610592946ae28cb7923f3ba88e Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Mon, 16 Sep 2019 02:53:51 +0800 Subject: [PATCH 022/420] Created rescheduleCommand class to handle the update of task's date and time. --- .../java/duke/command/RescheduleCommand.java | 57 ++++++++++++++++++- src/main/java/duke/core/Parser.java | 7 +++ src/main/java/duke/core/TaskList.java | 8 +-- src/main/java/duke/core/Ui.java | 11 ++++ src/main/java/duke/task/Deadline.java | 2 + src/main/java/duke/task/Task.java | 9 ++- 6 files changed, 86 insertions(+), 8 deletions(-) diff --git a/src/main/java/duke/command/RescheduleCommand.java b/src/main/java/duke/command/RescheduleCommand.java index bf87bf3423..43c3bb4869 100644 --- a/src/main/java/duke/command/RescheduleCommand.java +++ b/src/main/java/duke/command/RescheduleCommand.java @@ -1,4 +1,59 @@ package duke.command; -public class rescheduleCommand { +import duke.core.DukeException; +import duke.core.Storage; +import duke.core.TaskList; +import duke.core.Ui; +import duke.task.Task; + +/** + * Represents a command to reschedule a task by updating its date/time. + */ +public class RescheduleCommand extends Command { + + private int taskId; + private String newDateTime; + + + /** + * Constructs a RescheduleCommand object. + * + * @param taskId The index of the task to be updated + * @param newDateTime The new time of which the task should be updated to, expected to be in the format of dd//MM/yyyy HHmm + */ + public RescheduleCommand(int taskId, String newDateTime) { + super(); + this.taskId = taskId; + this.newDateTime = newDateTime; + } + + /** + * run the command with the respect TaskList, UI, and storage. + * + * @param tasks The task list where tasks are saved. + * @param ui The user interface. + * @param storage object that handles local text file update + */ + @Override + public void execute(TaskList taskList, Ui ui, Storage storage) throws DukeException { + try{ + Task task = taskList.getTask(taskId); + task.updateLocalDateTime(newDateTime); + storage.save(taskList.fullTaskList()); + ui.taskRescheduled(task); + }catch(DukeException dukeException){ + throw new DukeException("Fails to reschedule task. " + dukeException.getMessage()); + } + } + + /** + * Indicates whether Duke should exist + * + * @return A boolean. True if the command tells Duke to exit, false + * otherwise. + */ + @Override + public boolean isExit() { + return false; + } } diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index 2ff09b4ced..a7c964a3e3 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -64,6 +64,13 @@ public static Command parse(String ss) throws DukeException { } case "find": return new FindCommand(command[1]); + case "reschedule": + try { + String[] tempCommand = command[1].split(" ", 2); + return new RescheduleCommand(Integer.parseInt(tempCommand[0]), tempCommand[1]); + } catch (Exception e) { + throw new DukeException("Fail to reschedule task. Please enter command in the format of 'reschedule

'."); + } case "bye": return new ExitCommand(); default: diff --git a/src/main/java/duke/core/TaskList.java b/src/main/java/duke/core/TaskList.java index e764bcd478..af92e0158a 100644 --- a/src/main/java/duke/core/TaskList.java +++ b/src/main/java/duke/core/TaskList.java @@ -21,6 +21,10 @@ public TaskList(ArrayList task) { this.taskList = task; } + public TaskList() { + taskList = new ArrayList<>(); + } + /** * Retrieve the entire task list stored inside the ArrayList. */ @@ -71,8 +75,4 @@ public int getSize() { return taskList.size(); } - public TaskList() { - taskList = new ArrayList(); - } - } diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index 325a1b3907..dfc22d3896 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -67,6 +67,15 @@ public void taskRemoved(Task t, int size) { + size + " tasks in the list."); } + /** + * Shows that a Task has been rescheduled to a new date and time. + * + * @param t The Task that is rescheduled in the list. + */ + public void taskRescheduled(Task t) { + System.out.println("Noted. I've rescheduled this task: \n " + t.toString()); + } + /** * Find and display a specific task stored in the list. * @@ -84,6 +93,8 @@ public void taskFound(ArrayList a, String name) { } } + + /** * Print out the tasks in the task list which is reaching * the deadline. diff --git a/src/main/java/duke/task/Deadline.java b/src/main/java/duke/task/Deadline.java index ea107c0d33..1edfa224f7 100644 --- a/src/main/java/duke/task/Deadline.java +++ b/src/main/java/duke/task/Deadline.java @@ -1,5 +1,7 @@ package duke.task; +import duke.core.DukeException; + /** * Represents a task with a deadline. It is * extended from the Task class. diff --git a/src/main/java/duke/task/Task.java b/src/main/java/duke/task/Task.java index 850c515d9d..e72651420e 100644 --- a/src/main/java/duke/task/Task.java +++ b/src/main/java/duke/task/Task.java @@ -1,5 +1,7 @@ package duke.task; +import duke.core.DukeException; + import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; @@ -88,6 +90,8 @@ public String getDescription() { return description; } + + /** * Returns a string that representing the data and time for the task * in a predefined date time format. @@ -120,13 +124,12 @@ public String timeFormatter(String timeBeforeFormat) { * update the LocalDateTime constructor to save the date and time * @param time the time retrieved from user input. */ - public void updateLocalDateTime(String time) - { + public void updateLocalDateTime(String time){ DateTimeFormatter parser = DateTimeFormatter.ofPattern("dd/MM/yyyy HHmm"); try { ld = LocalDateTime.parse(time, parser); } catch (DateTimeParseException error) { - System.out.println(error.getMessage()); + System.out.println("Invalid format. Please Enter Date and Time in the format of dd/MM/yyyy HHmm"); } } /** From 292c1c706f17440a9a5afe9ba77e1f0139d4198e Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Mon, 16 Sep 2019 03:07:58 +0800 Subject: [PATCH 023/420] Update the UI of reminder to remind user to mark task as done or reschedule it. --- src/main/java/duke/core/Ui.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index dfc22d3896..46373b01e4 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -102,7 +102,7 @@ public void taskFound(ArrayList a, String name) { */ public void taskReminder(ArrayList a) { System.out.println("The following tasks are reaching your deadline:"); - System.out.println("Mark it as done to stop the reminder"); + System.out.println("Mark it as done or reschedule them to stop the reminder"); int count = 1; for (Task x : a) { System.out.println(count + "." + x.toString()); From 10d659cb52b47d62b035ccdff0048c65079d0d6c Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Mon, 16 Sep 2019 03:08:21 +0800 Subject: [PATCH 024/420] Update the JavaDoc param --- src/main/java/duke/command/RescheduleCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/duke/command/RescheduleCommand.java b/src/main/java/duke/command/RescheduleCommand.java index 43c3bb4869..779bd22ece 100644 --- a/src/main/java/duke/command/RescheduleCommand.java +++ b/src/main/java/duke/command/RescheduleCommand.java @@ -30,7 +30,7 @@ public RescheduleCommand(int taskId, String newDateTime) { /** * run the command with the respect TaskList, UI, and storage. * - * @param tasks The task list where tasks are saved. + * @param taskList The task list where tasks are saved. * @param ui The user interface. * @param storage object that handles local text file update */ From 0cc3d43c202d674193e7b9e42c09841053fe7e1f Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Mon, 16 Sep 2019 03:28:51 +0800 Subject: [PATCH 025/420] Fix bug about todo task can be reschedule. Rescheduling a todo task will now trigger a exception message to remind user. --- src/main/java/duke/command/RescheduleCommand.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/duke/command/RescheduleCommand.java b/src/main/java/duke/command/RescheduleCommand.java index 779bd22ece..5099c0a136 100644 --- a/src/main/java/duke/command/RescheduleCommand.java +++ b/src/main/java/duke/command/RescheduleCommand.java @@ -5,6 +5,7 @@ import duke.core.TaskList; import duke.core.Ui; import duke.task.Task; +import duke.task.Todo; /** * Represents a command to reschedule a task by updating its date/time. @@ -38,6 +39,9 @@ public RescheduleCommand(int taskId, String newDateTime) { public void execute(TaskList taskList, Ui ui, Storage storage) throws DukeException { try{ Task task = taskList.getTask(taskId); + if (task instanceof Todo){ + throw new DukeException("Todo task cannot be reschedule"); + } task.updateLocalDateTime(newDateTime); storage.save(taskList.fullTaskList()); ui.taskRescheduled(task); From 70c08032d5000031bb35694747bdbf8c46468b80 Mon Sep 17 00:00:00 2001 From: Qian Jie Date: Mon, 16 Sep 2019 07:14:17 +0800 Subject: [PATCH 026/420] added B-ViewSchedules. By using command [view dd/mm/yyyy] to show a list of tasks falling on the specified date --- src/main/java/duke/command/ViewCommand.java | 47 +++++++++++++++++++++ src/main/java/duke/core/Parser.java | 14 ++++++ src/main/java/duke/core/Ui.java | 25 +++++++++++ 3 files changed, 86 insertions(+) create mode 100644 src/main/java/duke/command/ViewCommand.java diff --git a/src/main/java/duke/command/ViewCommand.java b/src/main/java/duke/command/ViewCommand.java new file mode 100644 index 0000000000..ca303462d3 --- /dev/null +++ b/src/main/java/duke/command/ViewCommand.java @@ -0,0 +1,47 @@ +package duke.command; + +import duke.core.DukeException; +import duke.core.Storage; +import duke.core.TaskList; +import duke.core.Ui; + +public class ViewCommand extends Command { + private String date; + + /** + * Constructs and initialise a ViewCommand object. + * + * @param date Refers to the selected date of the schedule + */ + public ViewCommand (String date) { + super(); + this.date = date; + } + + + + /** + * Indicates whether Duke should exist + * + * @return A boolean. True if the command tells Duke to exit, false + * otherwise. + */ + @Override + public boolean isExit() { + return false; + } + + /** + * run the command with the respect TaskList, UI, and storage. + * + * @param tasks The task list where tasks are saved. + * @param ui The user interface. + * @param storage object that handles local text file update + */ + @Override + public void execute(TaskList tasks, Ui ui, Storage storage) throws DukeException { + ui.showSchedules(tasks.fullTaskList(), date); + } + +} + diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index a7c964a3e3..93c8963af9 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -5,6 +5,10 @@ import duke.task.Event; import duke.task.Todo; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; + /** * Represents a Parser that parses user input into a specific * type of Command. @@ -71,6 +75,16 @@ public static Command parse(String ss) throws DukeException { } catch (Exception e) { throw new DukeException("Fail to reschedule task. Please enter command in the format of 'reschedule
'."); } + case "view": + try { + DateFormat parser = new SimpleDateFormat("dd/M/yyyy"); + DateFormat formatter = new SimpleDateFormat("dd/M/yyyy"); + String date = formatter.format(parser.parse(command[1])); + return new ViewCommand(date); + + } catch (ParseException e) { + e.printStackTrace(); + } case "bye": return new ExitCommand(); default: diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index 46373b01e4..a1eb3c180c 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -2,6 +2,8 @@ import duke.task.Task; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; import java.util.ArrayList; import java.util.Scanner; @@ -109,6 +111,29 @@ public void taskReminder(ArrayList a) { count++; } } + + /** + * Print out the schedules on a specific date. + * @param a TaskList used to store tasks. + * @param date selected date of the schedule. + */ + public void showSchedules (ArrayList a , String date) { + System.out.println("This is your schedules on " + date); + try { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/M/yyyy"); + int count = 1; + for (Task task : a) { + String currentTaskDate = task.getDateTime().format(formatter); + if (currentTaskDate.equals(date)) { + System.out.println(count + ": " + task); + } + count++; + } + } catch (DateTimeParseException e) { + System.out.println("Invalid format. Please Enter Date and Time in the the format of dd/MM/yyyy"); + + } + } /** * Shows a divider line. */ From 6bd6c7d5b0479cbb42846c6e07bc2118bb0a2771 Mon Sep 17 00:00:00 2001 From: Qian Jie Date: Mon, 16 Sep 2019 07:28:17 +0800 Subject: [PATCH 027/420] added testing for viewCommand inside the ParserTest.java --- src/test/java/duke/core/ParserTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/test/java/duke/core/ParserTest.java b/src/test/java/duke/core/ParserTest.java index 4a7617aafe..dd694717f7 100644 --- a/src/test/java/duke/core/ParserTest.java +++ b/src/test/java/duke/core/ParserTest.java @@ -20,6 +20,8 @@ public void commandTypeTest() throws DukeException { Command c6 = Parser.parse("todo abc"); Command c7 = Parser.parse("event Meeting /at 2PM"); Command c8 = Parser.parse("deadline event Homework ABC /by 1PM"); + Command c9 = Parser.parse("view 16/09/2019"); + assertTrue(c1 instanceof ExitCommand, "The command type should be "); assertTrue(c2 instanceof DoneCommand, "The command type should be 'DoneCommand'"); @@ -29,5 +31,6 @@ public void commandTypeTest() throws DukeException { assertTrue(c6 instanceof AddCommand, "The command type should be 'AddCommand'"); assertTrue(c7 instanceof AddCommand, "The command type should be 'AddCommand'"); assertTrue(c8 instanceof AddCommand, "The command type should be 'AddCommand'"); + assertTrue(c9 instanceof ViewCommand, "The command type should be 'ViewCommand'"); } } From dee08b78ebfbd0f2e3fa27bc02ced027c5d4c10d Mon Sep 17 00:00:00 2001 From: lmtaek Date: Mon, 16 Sep 2019 19:55:16 +0800 Subject: [PATCH 028/420] Created new Command class for handling user 'recurring' commands, and added setters/getters for a task's recurring status. --- src/main/java/duke/command/RecurringCommand.java | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 src/main/java/duke/command/RecurringCommand.java diff --git a/src/main/java/duke/command/RecurringCommand.java b/src/main/java/duke/command/RecurringCommand.java new file mode 100644 index 0000000000..1280cdc92b --- /dev/null +++ b/src/main/java/duke/command/RecurringCommand.java @@ -0,0 +1,4 @@ +package duke.command; + +public class RecurringCommand { +} From d8ae7e308ef2694b5aa836a2fee32ce615c040c7 Mon Sep 17 00:00:00 2001 From: lmtaek Date: Mon, 16 Sep 2019 20:28:55 +0800 Subject: [PATCH 029/420] Added more steps to RecurringCommand execute() method; method will check for stored date + time before declaring a recurring event, then will mark the status in the save file + give a response to the user. --- .../java/duke/command/RecurringCommand.java | 36 ++++++++++++++++++- src/main/java/duke/core/Parser.java | 7 ++++ src/main/java/duke/core/Storage.java | 9 +++++ src/main/java/duke/core/Ui.java | 7 ++++ src/main/java/duke/task/Deadline.java | 9 ++++- src/main/java/duke/task/Event.java | 9 ++++- src/main/java/duke/task/Task.java | 14 ++++++++ src/main/java/duke/task/Todo.java | 7 +++- 8 files changed, 94 insertions(+), 4 deletions(-) diff --git a/src/main/java/duke/command/RecurringCommand.java b/src/main/java/duke/command/RecurringCommand.java index 1280cdc92b..af630ea40c 100644 --- a/src/main/java/duke/command/RecurringCommand.java +++ b/src/main/java/duke/command/RecurringCommand.java @@ -1,4 +1,38 @@ package duke.command; -public class RecurringCommand { +import duke.core.DukeException; +import duke.core.Storage; +import duke.core.TaskList; +import duke.core.Ui; +import duke.task.*; + +public class RecurringCommand extends Command { + + private int taskIndex; + + public RecurringCommand(int taskIndex) { + super(); + this.taskIndex = taskIndex; + + } + + @Override + public boolean isExit() { return false; } + + @Override + public void execute(TaskList tasks, Ui ui, Storage storage) throws DukeException { + try { + Task recurringTask = tasks.getTask(taskIndex); + if (recurringTask.getDateTime() != null) { + recurringTask.makeTaskRecurring(); + ui.makeRecurring(recurringTask); + storage.save(tasks.fullTaskList()); + } else { + throw new DukeException("Your task needs an initial time in order for it to be recurring."); + } + } catch (DukeException e) { + throw new DukeException("Couldn't make task recurring." + e); + } + + } } diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index 93c8963af9..89ef2b7209 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -85,6 +85,13 @@ public static Command parse(String ss) throws DukeException { } catch (ParseException e) { e.printStackTrace(); } + case "recurring": + try { + int index = Integer.parseInt(command[1]); + return new RecurringCommand(index); + } catch (Exception e) { + throw new DukeException("Failed to make your task recurring." + e.getMessage()); + } case "bye": return new ExitCommand(); default: diff --git a/src/main/java/duke/core/Storage.java b/src/main/java/duke/core/Storage.java index 0140a8bf59..e8e446c6c9 100644 --- a/src/main/java/duke/core/Storage.java +++ b/src/main/java/duke/core/Storage.java @@ -50,6 +50,9 @@ public ArrayList load() throws DukeException { if (newTask[1].equals("1")) { x.markAsDone(); } + if (newTask[3].equals("true")) { + x.makeTaskRecurring(); + } tasks.add(x); } if (newTask[0].equals("D")) { @@ -57,6 +60,9 @@ public ArrayList load() throws DukeException { if (newTask[1].equals("1")) { t.markAsDone(); } + if (newTask[4].equals("true")) { + t.makeTaskRecurring(); + } tasks.add(t); } if (newTask[0].equals("E")) { @@ -64,6 +70,9 @@ public ArrayList load() throws DukeException { if (newTask[1].equals("1")) { t.markAsDone(); } + if (newTask[4].equals("true")) { + t.makeTaskRecurring(); + } tasks.add(t); } diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index a1eb3c180c..104c92b3c5 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -134,6 +134,13 @@ public void showSchedules (ArrayList a , String date) { } } + + public void makeRecurring(Task t) { + System.out.println("Okay. This task has been marked as 'recurring' and will have a daily reminder:" + + t.getDescription()); + + } + /** * Shows a divider line. */ diff --git a/src/main/java/duke/task/Deadline.java b/src/main/java/duke/task/Deadline.java index 1edfa224f7..efecd214eb 100644 --- a/src/main/java/duke/task/Deadline.java +++ b/src/main/java/duke/task/Deadline.java @@ -45,7 +45,14 @@ public String toString() { * @return A string in a specific format to be stored in a local file. */ public String writeTxt() { - return "D | " + (this.isDone ? "1" : "0") + " | " + this.description + " | " + this.by; + return "D | " + + (this.isDone ? "1" : "0") + + " | " + + this.description + + " | " + + this.by + + " | " + + this.isRecurring; } } \ No newline at end of file diff --git a/src/main/java/duke/task/Event.java b/src/main/java/duke/task/Event.java index d919e40473..b1dca3e833 100644 --- a/src/main/java/duke/task/Event.java +++ b/src/main/java/duke/task/Event.java @@ -41,6 +41,13 @@ public String toString() { * @return A string in a specific format to be stored in a local file. */ public String writeTxt() { - return "E | " + (this.isDone ? "1" : "0") + " | " + this.description + " | " + this.at; + return "E | " + + (this.isDone ? "1" : "0") + + " | " + + this.description + + " | " + + this.at + + " | " + + this.isRecurring; } } \ No newline at end of file diff --git a/src/main/java/duke/task/Task.java b/src/main/java/duke/task/Task.java index e72651420e..ca2f97cb50 100644 --- a/src/main/java/duke/task/Task.java +++ b/src/main/java/duke/task/Task.java @@ -28,6 +28,10 @@ public abstract class Task { * a localDateTime constructor to save the date and time */ protected LocalDateTime ld; + /** + * A boolean that represents whether or not a task is recurring. True = recurring, False = non-recurring + */ + protected boolean isRecurring = false; /** * Initialises the minimum fields required to setup a Task. @@ -71,6 +75,16 @@ public void markAsDone() { isDone = true; } + /** + * Marks the task as recurring. + */ + public void makeTaskRecurring() { isRecurring = true; } + + /** + * Returns boolean stating whether task is recurring. + */ + public boolean isTaskRecurring() { return isRecurring; } + /** * Returns a string with the status icon and the description of the task. * diff --git a/src/main/java/duke/task/Todo.java b/src/main/java/duke/task/Todo.java index c20ea65f75..12e6f88615 100644 --- a/src/main/java/duke/task/Todo.java +++ b/src/main/java/duke/task/Todo.java @@ -32,7 +32,12 @@ public String toString() { * @return A string in a specific format to be stored in a local file. */ public String writeTxt() { - return "T | " + (this.isDone() ? "1" : "0") + " | " + this.description; + return "T | " + + (this.isDone() ? "1" : "0") + + " | " + + this.description + + " | " + + this.isRecurring; } } \ No newline at end of file From 825fd9d822a0f03bbf60f166c11bfa2f6b3e62d8 Mon Sep 17 00:00:00 2001 From: lmtaek Date: Mon, 16 Sep 2019 21:35:30 +0800 Subject: [PATCH 030/420] Created a method to update a recurring task's time if its date is not the same as the current date. --- src/main/java/duke/task/Task.java | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/main/java/duke/task/Task.java b/src/main/java/duke/task/Task.java index ca2f97cb50..fc3b112ff0 100644 --- a/src/main/java/duke/task/Task.java +++ b/src/main/java/duke/task/Task.java @@ -5,6 +5,7 @@ import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; +import java.time.Duration; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; @@ -85,6 +86,27 @@ public void markAsDone() { */ public boolean isTaskRecurring() { return isRecurring; } + /** + * When a task is recurring, method compares current time to listed date. + * If the task's date is outdated, then it will update to be for the next day. + */ + public void recurringTaskTimeUpdate() { + if ((ld != null) && this.isRecurring) { + DateTimeFormatter taskTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy"); + try { + LocalDateTime taskDate = LocalDateTime.parse(ld.toString(), taskTimeFormatter); + LocalDateTime currentDate = LocalDateTime.parse(LocalDateTime.now().toString(), taskTimeFormatter); + + if (taskDate.isBefore(currentDate)) { + Duration dayDifference = Duration.between(currentDate, taskDate); + this.ld = ld.plusDays(Math.abs(dayDifference.toDays())); + } + } catch (DateTimeParseException e) { + System.out.println("I couldn't update your recurring events' times."); + } + } + } + /** * Returns a string with the status icon and the description of the task. * @@ -146,6 +168,7 @@ public void updateLocalDateTime(String time){ System.out.println("Invalid format. Please Enter Date and Time in the format of dd/MM/yyyy HHmm"); } } + /** * Returns the data and time information stored in the task without a certain format. * From 1cf0ca79475d1433b239016cd01a965c2309083e Mon Sep 17 00:00:00 2001 From: Qian Jie Date: Mon, 16 Sep 2019 22:04:36 +0800 Subject: [PATCH 031/420] added B-DetectAnomalies --- data/duke.txt | 10 ++++--- src/main/java/duke/command/AddCommand.java | 31 +++++++++++++++++++--- src/main/java/duke/core/Ui.java | 16 +++++++++++ src/main/java/duke/task/Task.java | 4 +++ 4 files changed, 55 insertions(+), 6 deletions(-) diff --git a/data/duke.txt b/data/duke.txt index 0a570d3b91..604a1e68b9 100644 --- a/data/duke.txt +++ b/data/duke.txt @@ -1,6 +1,10 @@ D | 1 | ssss | 16/09/2019 0200 -D | 1 | tttt | 16/09/2019 0300 -D | 1 | tttt | 16/09/2019 0400 D | 1 | tttt | 16/09/2019 0500 E | 1 | tasktest | 16/09/2019 1000 -D | 0 | tasktest2 | 16/09/2019 1200 +D | 1 | read book | 27/09/2019 1800 +D | 1 | watch movie | 27/09/2019 1800 +D | 1 | adding | 27/09/2019 1900 +D | 1 | hello | 27/09/2019 2000 +D | 1 | readbook | 27/09/2019 2300 +D | 0 | watch tv | 27/09/2019 1700 +D | 0 | hello | 27/09/2019 1800 diff --git a/src/main/java/duke/command/AddCommand.java b/src/main/java/duke/command/AddCommand.java index b53749ae5e..634238f0f2 100644 --- a/src/main/java/duke/command/AddCommand.java +++ b/src/main/java/duke/command/AddCommand.java @@ -7,6 +7,9 @@ import duke.core.Ui; import duke.task.Task; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; + /** * Represents a command class to add a task. The AddCommand class * extends from the Command class to represent user instruction @@ -18,6 +21,7 @@ public class AddCommand extends Command { * A new task to be added */ private Task task; + private Boolean isClash = false; /** * Constructs a AddCommand object. @@ -50,9 +54,30 @@ public boolean isExit() { @Override public void execute(TaskList tasks, Ui ui, Storage storage) throws DukeException { try { - tasks.addTask(task); - ui.taskAdded(task, tasks.getSize()); - storage.save(tasks.fullTaskList()); + ArrayList taskList = tasks.fullTaskList(); + String userAnswer; + + for (Task t : taskList) { + if (t.getDate().equals(task.getDate()) && !t.isDone()) { + isClash = true; + } + } + + if (isClash) { + userAnswer = ui.showClashWarning(taskList, task); + if (userAnswer.equals("Y") || userAnswer.equals("y") ) { + tasks.addTask(task); + ui.taskAdded(task, tasks.getSize()); + storage.save(tasks.fullTaskList()); + } else { + System.out.println("Alright , I have aborted the task."); + } + } else { + tasks.addTask(task); + ui.taskAdded(task, tasks.getSize()); + storage.save(tasks.fullTaskList()); + } + } catch (DukeException e) { throw new DukeException("Fails to add task. " + e.getMessage()); } diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index a1eb3c180c..bbaee8ece9 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -49,6 +49,7 @@ public void taskAdded(Task t, int size) { + size + " tasks in the list."); } + /** * Shows that a Task has been marked as done. * @@ -95,6 +96,21 @@ public void taskFound(ArrayList a, String name) { } } + public String showClashWarning (ArrayList tasklist, Task task) { + System.out.println("Here are the tasks that fall on the same day:"); + int count = 1; + for (Task t : tasklist) { + if (t.getDate().equals(task.getDate()) && !t.isDone()) { + System.out.println(count + ": " + t); + count++; + } + } + showLine(); + System.out.println("Do you still want to add your task anyway? Y/N"); + String userAnswer = scanner.nextLine(); + return userAnswer; + } + /** diff --git a/src/main/java/duke/task/Task.java b/src/main/java/duke/task/Task.java index e72651420e..4a74ce884f 100644 --- a/src/main/java/duke/task/Task.java +++ b/src/main/java/duke/task/Task.java @@ -141,4 +141,8 @@ public LocalDateTime getDateTime() { return ld; } + + public LocalDate getDate() { + return ld.toLocalDate(); + } } \ No newline at end of file From 597e6d57bc9169582ca8fd88b15fa7677265cc7e Mon Sep 17 00:00:00 2001 From: lmtaek Date: Mon, 16 Sep 2019 23:23:45 +0800 Subject: [PATCH 032/420] Recurring tasks' times update after being compared with current date, when Task.getDateTime() is called; Ui responds when user gives input of "recurring " + [index], and rejects attempts to make already recurring tasks recurring again. Unable to make a 'todo' task a recurring event at the moment. --- data/duke.txt | 15 ++++---- .../java/duke/command/RecurringCommand.java | 34 ++++++++++++++++--- src/main/java/duke/core/Ui.java | 4 +-- src/main/java/duke/task/Task.java | 16 +++++---- 4 files changed, 49 insertions(+), 20 deletions(-) diff --git a/data/duke.txt b/data/duke.txt index 0a570d3b91..8d1c3f6e98 100644 --- a/data/duke.txt +++ b/data/duke.txt @@ -1,6 +1,9 @@ -D | 1 | ssss | 16/09/2019 0200 -D | 1 | tttt | 16/09/2019 0300 -D | 1 | tttt | 16/09/2019 0400 -D | 1 | tttt | 16/09/2019 0500 -E | 1 | tasktest | 16/09/2019 1000 -D | 0 | tasktest2 | 16/09/2019 1200 +D | 1 | ssss | 16/09/2019 0200 | true +D | 1 | tttt | 16/09/2019 0300 | true +D | 1 | tttt | 16/09/2019 0400 | false +D | 1 | tttt | 16/09/2019 0500 | false +E | 1 | tasktest | 16/09/2019 1000 | true +D | 0 | tasktest2 | 16/09/2019 1200 | false +T | 0 | sleep | false +E | 1 | eat food | 09/09/2019 0909 | true +T | 0 | jog marathon | false diff --git a/src/main/java/duke/command/RecurringCommand.java b/src/main/java/duke/command/RecurringCommand.java index af630ea40c..ca306367fb 100644 --- a/src/main/java/duke/command/RecurringCommand.java +++ b/src/main/java/duke/command/RecurringCommand.java @@ -6,32 +6,56 @@ import duke.core.Ui; import duke.task.*; +import java.time.LocalDateTime; + public class RecurringCommand extends Command { + /** + * Used to identify the task being marked as recurring. + */ private int taskIndex; public RecurringCommand(int taskIndex) { super(); this.taskIndex = taskIndex; - } + /** + * Indicates whether Duke should exist + * + * @return A boolean. True if the command tells Duke to exit, false + * otherwise. + */ @Override public boolean isExit() { return false; } + /** + * run the command with the respect TaskList, UI, and storage. + * + * Checks whether there is a DateTime for the listed task, and if so, + * marks it as 'recurring', calls the Ui to print a certain output, and informs + * storage that the task is now recurring. + * + * @param tasks The task list where tasks are saved. + * @param ui The user interface. + * @param storage object that handles local text file update + */ @Override public void execute(TaskList tasks, Ui ui, Storage storage) throws DukeException { try { Task recurringTask = tasks.getTask(taskIndex); if (recurringTask.getDateTime() != null) { - recurringTask.makeTaskRecurring(); - ui.makeRecurring(recurringTask); + if (!recurringTask.isTaskRecurring()) { + recurringTask.makeTaskRecurring(); + ui.makeRecurring(recurringTask); + } + recurringTask.recurringTaskTimeUpdate(); storage.save(tasks.fullTaskList()); } else { - throw new DukeException("Your task needs an initial time in order for it to be recurring."); + recurringTask.updateLocalDateTime(LocalDateTime.now().toString()); } } catch (DukeException e) { - throw new DukeException("Couldn't make task recurring." + e); + throw new DukeException("I couldn't make the task recurring. " + e); } } diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index 104c92b3c5..dd9339e619 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -136,8 +136,8 @@ public void showSchedules (ArrayList a , String date) { } public void makeRecurring(Task t) { - System.out.println("Okay. This task has been marked as 'recurring' and will have a daily reminder:" - + t.getDescription()); + System.out.println("Okay. This task has been marked as recurring:\n" + + t.toString()); } diff --git a/src/main/java/duke/task/Task.java b/src/main/java/duke/task/Task.java index fc3b112ff0..7d24695aff 100644 --- a/src/main/java/duke/task/Task.java +++ b/src/main/java/duke/task/Task.java @@ -92,14 +92,15 @@ public void markAsDone() { */ public void recurringTaskTimeUpdate() { if ((ld != null) && this.isRecurring) { - DateTimeFormatter taskTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy"); try { - LocalDateTime taskDate = LocalDateTime.parse(ld.toString(), taskTimeFormatter); - LocalDateTime currentDate = LocalDateTime.parse(LocalDateTime.now().toString(), taskTimeFormatter); - - if (taskDate.isBefore(currentDate)) { - Duration dayDifference = Duration.between(currentDate, taskDate); - this.ld = ld.plusDays(Math.abs(dayDifference.toDays())); + LocalDateTime currentTime = LocalDateTime.now(); + if (this.ld.isBefore(currentTime)) { + Duration dayDifference = Duration.between(currentTime, this.ld); + if (Math.abs(dayDifference.toDays()) > 0 ) { + this.ld = ld.plusDays(Math.abs(dayDifference.toDays())); + + if (!this.isDone) { this.isDone = false; } + } } } catch (DateTimeParseException e) { System.out.println("I couldn't update your recurring events' times."); @@ -176,6 +177,7 @@ public void updateLocalDateTime(String time){ */ public LocalDateTime getDateTime() { + if (this.isTaskRecurring()) { this.recurringTaskTimeUpdate(); } return ld; } } \ No newline at end of file From 385eb69f034dbec33520176b8cabb1f8341c87b0 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Tue, 17 Sep 2019 00:08:51 +0800 Subject: [PATCH 033/420] Implemented a seperated DateTimeParser which is originally in the Task class. --- src/main/java/duke/core/DateTimeParser.java | 54 +++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 src/main/java/duke/core/DateTimeParser.java diff --git a/src/main/java/duke/core/DateTimeParser.java b/src/main/java/duke/core/DateTimeParser.java new file mode 100644 index 0000000000..c2c49429d3 --- /dev/null +++ b/src/main/java/duke/core/DateTimeParser.java @@ -0,0 +1,54 @@ +package duke.core; + +import java.time.LocalDateTime; +import java.time.format.DateTimeParseException; + +public class DateTimeParser { + + /** + * update the LocalDateTime constructor to save the date and time + * + * @param timeBeforeFormat the time retrieved from user input. + * @return A LocalDateTime object that contains date and time information. + */ + public static LocalDateTime convertToLocalDateTime(String timeBeforeFormat) throws DukeException { + java.time.format.DateTimeFormatter parser = java.time.format.DateTimeFormatter.ofPattern("dd/MM/yyyy HHmm"); + LocalDateTime localDateTime; + try { + localDateTime = LocalDateTime.parse(timeBeforeFormat, parser); + return localDateTime; + } catch (DateTimeParseException error) { + throw new DukeException("Invalid format. Please Enter Date and Time in the format of dd/MM/yyyy HHmm"); + } + } + + /** + * Returns a string that representing the data and time for the task + * in a predefined English date time format. + * + * @param timeBeforeFormat A String that provides the data and time information in dd/MM/yyyy HHmm. + * @return A String that provides date and time in English + */ + public static String convertToEnglishDateTime(String timeBeforeFormat) throws DukeException { + java.time.format.DateTimeFormatter stFormatter = java.time.format.DateTimeFormatter.ofPattern("d'st of' MMMM yyyy, ha"); + java.time.format.DateTimeFormatter ndFormatter = java.time.format.DateTimeFormatter.ofPattern("d'nd of' MMMM yyyy, ha"); + java.time.format.DateTimeFormatter rdFormatter = java.time.format.DateTimeFormatter.ofPattern("d'rd of' MMMM yyyy, ha"); + java.time.format.DateTimeFormatter thFormatter = java.time.format.DateTimeFormatter.ofPattern("d'th of' MMMM yyyy, ha"); + + try{ + LocalDateTime localDateTime; + localDateTime = convertToLocalDateTime(timeBeforeFormat); + if ((localDateTime.getDayOfMonth() % 10) == 1) { + return localDateTime.format(stFormatter); + } else if ((localDateTime.getDayOfMonth() % 10) == 2) { + return localDateTime.format(ndFormatter); + } else if ((localDateTime.getDayOfMonth() % 10) == 3) { + return localDateTime.format(rdFormatter); + } else { + return localDateTime.format(thFormatter); + } + }catch(DukeException e){ + throw e; + } + } +} From 01637ab08e76e96e37cf97d859e302ab10fd8cba Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Tue, 17 Sep 2019 00:11:34 +0800 Subject: [PATCH 034/420] Implemented DoWithinPeriodTask features with Simple Junit Test case. --- src/main/java/duke/core/Parser.java | 19 +++++-- src/main/java/duke/core/Storage.java | 17 +++--- src/main/java/duke/task/PeriodTask.java | 59 +++++++++++++++++++++ src/main/java/duke/task/Task.java | 1 - src/test/java/duke/task/PeriodTaskTest.java | 25 +++++++++ 5 files changed, 110 insertions(+), 11 deletions(-) create mode 100644 src/main/java/duke/task/PeriodTask.java create mode 100644 src/test/java/duke/task/PeriodTaskTest.java diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index a7c964a3e3..2264aeb200 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -2,6 +2,7 @@ import duke.command.*; import duke.task.Deadline; +import duke.task.PeriodTask; import duke.task.Event; import duke.task.Todo; @@ -49,19 +50,29 @@ public static Command parse(String ss) throws DukeException { case "deadline": try { String[] temp = command[1].split(" /by "); - Deadline d = new Deadline(temp[0], temp[1]); - return new AddCommand(d); + Deadline deadline = new Deadline(temp[0], temp[1]); + return new AddCommand(deadline); } catch (Exception e) { throw new DukeException(e.getMessage()); } case "event": try { String[] temp1 = command[1].split(" /at "); - Event z = new Event(temp1[0], temp1[1]); - return new AddCommand(z); + Event event = new Event(temp1[0], temp1[1]); + return new AddCommand(event); } catch (Exception e) { throw new DukeException(e.getMessage()); } + case "period": + try { + String[] strArray = command[1].split(" /from ", 2); + String[] strArray2 = strArray[1].split(" /to ",2); + PeriodTask periodTask = new PeriodTask(strArray[0], strArray2[0], strArray2[1]); + return new AddCommand(periodTask); + }catch (Exception e) { + throw new DukeException("Fail to create a period task. Please enter command in the format of 'period /from dd/MM/yyyy HHmm /to dd/MM/yyyy HHmm'."); + + } case "find": return new FindCommand(command[1]); case "reschedule": diff --git a/src/main/java/duke/core/Storage.java b/src/main/java/duke/core/Storage.java index 0140a8bf59..8e3fc48cad 100644 --- a/src/main/java/duke/core/Storage.java +++ b/src/main/java/duke/core/Storage.java @@ -1,9 +1,6 @@ package duke.core; -import duke.task.Deadline; -import duke.task.Event; -import duke.task.Task; -import duke.task.Todo; +import duke.task.*; import java.io.File; import java.io.FileNotFoundException; @@ -52,14 +49,14 @@ public ArrayList load() throws DukeException { } tasks.add(x); } - if (newTask[0].equals("D")) { + else if (newTask[0].equals("D")) { Task t = new Deadline(newTask[2], newTask[3]); if (newTask[1].equals("1")) { t.markAsDone(); } tasks.add(t); } - if (newTask[0].equals("E")) { + else if (newTask[0].equals("E")) { Task t = new Event(newTask[2], newTask[3]); if (newTask[1].equals("1")) { t.markAsDone(); @@ -67,6 +64,14 @@ public ArrayList load() throws DukeException { tasks.add(t); } + else if (newTask[0].equals("P")) { + Task t = new PeriodTask(newTask[2], newTask[3], newTask[4]); + if (newTask[1].equals("1")) { + t.markAsDone(); + } + tasks.add(t); + } + } return tasks; } catch (FileNotFoundException e) { diff --git a/src/main/java/duke/task/PeriodTask.java b/src/main/java/duke/task/PeriodTask.java new file mode 100644 index 0000000000..87f266c28f --- /dev/null +++ b/src/main/java/duke/task/PeriodTask.java @@ -0,0 +1,59 @@ +package duke.task; + +import duke.core.DateTimeParser; +import duke.core.DukeException; + +/** + * Represents a task to be done in a certain period of time. It is + * extended from the Task class. + */ +public class PeriodTask extends Task { + + private String startTime; + private String endTime; + private String startTimeEnglish; + private String endTimeEnglish; + + /** + * Constructs a PeriodTask object. Start time and end time are parsed and + * stored in dateTime field if input is of "dd/MM/yyyy HHmm" + * format. + * + * @param description A string that describes the specific + * description of task. + * @param startTime A string that specifies the start dateof the + * task. + * @param startTime A string that specifies the end date of the + * task. + */ + public PeriodTask(String description, String startTime, String endTime) throws DukeException { + super(description); + this.startTime = startTime; + this.endTime = endTime; + this.startTimeEnglish = DateTimeParser.convertToEnglishDateTime(startTime); + this.endTimeEnglish = DateTimeParser.convertToEnglishDateTime(endTime); + } + + /** + * Returns a string pattern to the user output + * + * @return A string which displays the type, + * description and deadline of the task. + */ + @Override + public String toString() { + return "[P]" + super.printStatus() + + " (start: " + startTimeEnglish + + " end: " + endTimeEnglish + ")"; + } + + /** + * Returns a string with the following format to be stored in a local file + * + * @return A string in a specific format to be stored in a local file. + */ + public String writeTxt() { + return "P | " + (this.isDone ? "1" : "0") + " | " + description + " | " + startTime + " | " + endTime; + } + +} \ No newline at end of file diff --git a/src/main/java/duke/task/Task.java b/src/main/java/duke/task/Task.java index e72651420e..b8868978fd 100644 --- a/src/main/java/duke/task/Task.java +++ b/src/main/java/duke/task/Task.java @@ -115,7 +115,6 @@ public String timeFormatter(String timeBeforeFormat) { output = ld.format(rdFormatter); } else { output = ld.format(thFormatter); - ; } return output; } diff --git a/src/test/java/duke/task/PeriodTaskTest.java b/src/test/java/duke/task/PeriodTaskTest.java new file mode 100644 index 0000000000..6eec44ff2f --- /dev/null +++ b/src/test/java/duke/task/PeriodTaskTest.java @@ -0,0 +1,25 @@ +package duke.task; + +import duke.core.DukeException; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + + +public class PeriodTaskTest { + /** + * Test the PeriodTask.toString() + */ + @Test + public void PeriodTaskStringTest() throws DukeException { + assertEquals("[P][\u2718] PeriodTaskTest (start: 27th of July 1996, 3PM end: 27th of July 2020, 3PM)", new PeriodTask("PeriodTaskTest", "27/07/1996 1530", "27/07/2020 1530").toString(), "toString result is not expected"); + } + + /** + * Test the PeriodTask.writeTxt() + */ + @Test + public void writeFormatTest() throws DukeException { + assertEquals( "P | 0 | PeriodTaskTest | 27/07/1996 1530 | 27/07/2020 1530",new PeriodTask("PeriodTaskTest", "27/07/1996 1530", "27/07/2020 1530").writeTxt(), "The writeToFile format is not expected"); + } +} \ No newline at end of file From d5bb61c2772e6f0ec23135842cc21e2d6cbc5714 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Tue, 17 Sep 2019 00:15:06 +0800 Subject: [PATCH 035/420] Added period tasks to the local duke.txt file for read testing --- data/duke.txt | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/data/duke.txt b/data/duke.txt index 0a570d3b91..c67344c37d 100644 --- a/data/duke.txt +++ b/data/duke.txt @@ -1,6 +1,2 @@ -D | 1 | ssss | 16/09/2019 0200 -D | 1 | tttt | 16/09/2019 0300 -D | 1 | tttt | 16/09/2019 0400 -D | 1 | tttt | 16/09/2019 0500 -E | 1 | tasktest | 16/09/2019 1000 -D | 0 | tasktest2 | 16/09/2019 1200 +P | 0 | abc | 27/07/1996 1530 | 27/07/2020 1530 +P | 0 | abc | 27/07/1996 1530 | 27/07/2020 1530 From a8615ed870ced7825bed255966f4cb6d6c304f35 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Tue, 17 Sep 2019 00:18:54 +0800 Subject: [PATCH 036/420] Untrack local duke.txt --- data/duke.txt | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 data/duke.txt diff --git a/data/duke.txt b/data/duke.txt deleted file mode 100644 index 0a570d3b91..0000000000 --- a/data/duke.txt +++ /dev/null @@ -1,6 +0,0 @@ -D | 1 | ssss | 16/09/2019 0200 -D | 1 | tttt | 16/09/2019 0300 -D | 1 | tttt | 16/09/2019 0400 -D | 1 | tttt | 16/09/2019 0500 -E | 1 | tasktest | 16/09/2019 1000 -D | 0 | tasktest2 | 16/09/2019 1200 From 46c4d859f59be47cb7bb5eb65d63f5622db5235e Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Tue, 17 Sep 2019 00:20:11 +0800 Subject: [PATCH 037/420] add duke.txt to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 99712178bf..c9e981c28c 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ src/main/resources/docs/ .DS_Store *.iml bin/ +data/duke.txt From 4e2c5424ef46838760525cd1da0c9c90d8132062 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Tue, 17 Sep 2019 00:34:53 +0800 Subject: [PATCH 038/420] Commit changes from PR --- src/main/java/duke/command/AddCommand.java | 31 +++++++++- .../java/duke/command/RecurringCommand.java | 62 +++++++++++++++++++ src/main/java/duke/command/ViewCommand.java | 47 ++++++++++++++ src/main/java/duke/core/Parser.java | 21 +++++++ src/main/java/duke/core/Storage.java | 9 +++ src/main/java/duke/core/Ui.java | 48 ++++++++++++++ src/main/java/duke/task/Deadline.java | 9 ++- src/main/java/duke/task/Event.java | 9 ++- src/main/java/duke/task/Task.java | 43 +++++++++++++ src/main/java/duke/task/Todo.java | 7 ++- src/test/java/duke/core/ParserTest.java | 3 + 11 files changed, 283 insertions(+), 6 deletions(-) create mode 100644 src/main/java/duke/command/RecurringCommand.java create mode 100644 src/main/java/duke/command/ViewCommand.java diff --git a/src/main/java/duke/command/AddCommand.java b/src/main/java/duke/command/AddCommand.java index b53749ae5e..634238f0f2 100644 --- a/src/main/java/duke/command/AddCommand.java +++ b/src/main/java/duke/command/AddCommand.java @@ -7,6 +7,9 @@ import duke.core.Ui; import duke.task.Task; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; + /** * Represents a command class to add a task. The AddCommand class * extends from the Command class to represent user instruction @@ -18,6 +21,7 @@ public class AddCommand extends Command { * A new task to be added */ private Task task; + private Boolean isClash = false; /** * Constructs a AddCommand object. @@ -50,9 +54,30 @@ public boolean isExit() { @Override public void execute(TaskList tasks, Ui ui, Storage storage) throws DukeException { try { - tasks.addTask(task); - ui.taskAdded(task, tasks.getSize()); - storage.save(tasks.fullTaskList()); + ArrayList taskList = tasks.fullTaskList(); + String userAnswer; + + for (Task t : taskList) { + if (t.getDate().equals(task.getDate()) && !t.isDone()) { + isClash = true; + } + } + + if (isClash) { + userAnswer = ui.showClashWarning(taskList, task); + if (userAnswer.equals("Y") || userAnswer.equals("y") ) { + tasks.addTask(task); + ui.taskAdded(task, tasks.getSize()); + storage.save(tasks.fullTaskList()); + } else { + System.out.println("Alright , I have aborted the task."); + } + } else { + tasks.addTask(task); + ui.taskAdded(task, tasks.getSize()); + storage.save(tasks.fullTaskList()); + } + } catch (DukeException e) { throw new DukeException("Fails to add task. " + e.getMessage()); } diff --git a/src/main/java/duke/command/RecurringCommand.java b/src/main/java/duke/command/RecurringCommand.java new file mode 100644 index 0000000000..ca306367fb --- /dev/null +++ b/src/main/java/duke/command/RecurringCommand.java @@ -0,0 +1,62 @@ +package duke.command; + +import duke.core.DukeException; +import duke.core.Storage; +import duke.core.TaskList; +import duke.core.Ui; +import duke.task.*; + +import java.time.LocalDateTime; + +public class RecurringCommand extends Command { + + /** + * Used to identify the task being marked as recurring. + */ + private int taskIndex; + + public RecurringCommand(int taskIndex) { + super(); + this.taskIndex = taskIndex; + } + + /** + * Indicates whether Duke should exist + * + * @return A boolean. True if the command tells Duke to exit, false + * otherwise. + */ + @Override + public boolean isExit() { return false; } + + /** + * run the command with the respect TaskList, UI, and storage. + * + * Checks whether there is a DateTime for the listed task, and if so, + * marks it as 'recurring', calls the Ui to print a certain output, and informs + * storage that the task is now recurring. + * + * @param tasks The task list where tasks are saved. + * @param ui The user interface. + * @param storage object that handles local text file update + */ + @Override + public void execute(TaskList tasks, Ui ui, Storage storage) throws DukeException { + try { + Task recurringTask = tasks.getTask(taskIndex); + if (recurringTask.getDateTime() != null) { + if (!recurringTask.isTaskRecurring()) { + recurringTask.makeTaskRecurring(); + ui.makeRecurring(recurringTask); + } + recurringTask.recurringTaskTimeUpdate(); + storage.save(tasks.fullTaskList()); + } else { + recurringTask.updateLocalDateTime(LocalDateTime.now().toString()); + } + } catch (DukeException e) { + throw new DukeException("I couldn't make the task recurring. " + e); + } + + } +} diff --git a/src/main/java/duke/command/ViewCommand.java b/src/main/java/duke/command/ViewCommand.java new file mode 100644 index 0000000000..ca303462d3 --- /dev/null +++ b/src/main/java/duke/command/ViewCommand.java @@ -0,0 +1,47 @@ +package duke.command; + +import duke.core.DukeException; +import duke.core.Storage; +import duke.core.TaskList; +import duke.core.Ui; + +public class ViewCommand extends Command { + private String date; + + /** + * Constructs and initialise a ViewCommand object. + * + * @param date Refers to the selected date of the schedule + */ + public ViewCommand (String date) { + super(); + this.date = date; + } + + + + /** + * Indicates whether Duke should exist + * + * @return A boolean. True if the command tells Duke to exit, false + * otherwise. + */ + @Override + public boolean isExit() { + return false; + } + + /** + * run the command with the respect TaskList, UI, and storage. + * + * @param tasks The task list where tasks are saved. + * @param ui The user interface. + * @param storage object that handles local text file update + */ + @Override + public void execute(TaskList tasks, Ui ui, Storage storage) throws DukeException { + ui.showSchedules(tasks.fullTaskList(), date); + } + +} + diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index 2264aeb200..aa1c3ace82 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -6,6 +6,10 @@ import duke.task.Event; import duke.task.Todo; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; + /** * Represents a Parser that parses user input into a specific * type of Command. @@ -82,6 +86,23 @@ public static Command parse(String ss) throws DukeException { } catch (Exception e) { throw new DukeException("Fail to reschedule task. Please enter command in the format of 'reschedule
'."); } + case "view": + try { + DateFormat parser = new SimpleDateFormat("dd/M/yyyy"); + DateFormat formatter = new SimpleDateFormat("dd/M/yyyy"); + String date = formatter.format(parser.parse(command[1])); + return new ViewCommand(date); + + } catch (ParseException e) { + e.printStackTrace(); + } + case "recurring": + try { + int index = Integer.parseInt(command[1]); + return new RecurringCommand(index); + } catch (Exception e) { + throw new DukeException("Failed to make your task recurring." + e.getMessage()); + } case "bye": return new ExitCommand(); default: diff --git a/src/main/java/duke/core/Storage.java b/src/main/java/duke/core/Storage.java index 8e3fc48cad..8fef581723 100644 --- a/src/main/java/duke/core/Storage.java +++ b/src/main/java/duke/core/Storage.java @@ -47,6 +47,9 @@ public ArrayList load() throws DukeException { if (newTask[1].equals("1")) { x.markAsDone(); } + if (newTask[3].equals("true")) { + x.makeTaskRecurring(); + } tasks.add(x); } else if (newTask[0].equals("D")) { @@ -54,6 +57,9 @@ else if (newTask[0].equals("D")) { if (newTask[1].equals("1")) { t.markAsDone(); } + if (newTask[4].equals("true")) { + t.makeTaskRecurring(); + } tasks.add(t); } else if (newTask[0].equals("E")) { @@ -61,6 +67,9 @@ else if (newTask[0].equals("E")) { if (newTask[1].equals("1")) { t.markAsDone(); } + if (newTask[4].equals("true")) { + t.makeTaskRecurring(); + } tasks.add(t); } diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index 46373b01e4..0b8bc681c7 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -2,6 +2,8 @@ import duke.task.Task; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; import java.util.ArrayList; import java.util.Scanner; @@ -47,6 +49,7 @@ public void taskAdded(Task t, int size) { + size + " tasks in the list."); } + /** * Shows that a Task has been marked as done. * @@ -93,6 +96,21 @@ public void taskFound(ArrayList a, String name) { } } + public String showClashWarning (ArrayList tasklist, Task task) { + System.out.println("Here are the tasks that fall on the same day:"); + int count = 1; + for (Task t : tasklist) { + if (t.getDate().equals(task.getDate()) && !t.isDone()) { + System.out.println(count + ": " + t); + count++; + } + } + showLine(); + System.out.println("Do you still want to add your task anyway? Y/N"); + String userAnswer = scanner.nextLine(); + return userAnswer; + } + /** @@ -109,6 +127,36 @@ public void taskReminder(ArrayList a) { count++; } } + + /** + * Print out the schedules on a specific date. + * @param a TaskList used to store tasks. + * @param date selected date of the schedule. + */ + public void showSchedules (ArrayList a , String date) { + System.out.println("This is your schedules on " + date); + try { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/M/yyyy"); + int count = 1; + for (Task task : a) { + String currentTaskDate = task.getDateTime().format(formatter); + if (currentTaskDate.equals(date)) { + System.out.println(count + ": " + task); + } + count++; + } + } catch (DateTimeParseException e) { + System.out.println("Invalid format. Please Enter Date and Time in the the format of dd/MM/yyyy"); + + } + } + + public void makeRecurring(Task t) { + System.out.println("Okay. This task has been marked as recurring:\n" + + t.toString()); + + } + /** * Shows a divider line. */ diff --git a/src/main/java/duke/task/Deadline.java b/src/main/java/duke/task/Deadline.java index 1edfa224f7..efecd214eb 100644 --- a/src/main/java/duke/task/Deadline.java +++ b/src/main/java/duke/task/Deadline.java @@ -45,7 +45,14 @@ public String toString() { * @return A string in a specific format to be stored in a local file. */ public String writeTxt() { - return "D | " + (this.isDone ? "1" : "0") + " | " + this.description + " | " + this.by; + return "D | " + + (this.isDone ? "1" : "0") + + " | " + + this.description + + " | " + + this.by + + " | " + + this.isRecurring; } } \ No newline at end of file diff --git a/src/main/java/duke/task/Event.java b/src/main/java/duke/task/Event.java index d919e40473..b1dca3e833 100644 --- a/src/main/java/duke/task/Event.java +++ b/src/main/java/duke/task/Event.java @@ -41,6 +41,13 @@ public String toString() { * @return A string in a specific format to be stored in a local file. */ public String writeTxt() { - return "E | " + (this.isDone ? "1" : "0") + " | " + this.description + " | " + this.at; + return "E | " + + (this.isDone ? "1" : "0") + + " | " + + this.description + + " | " + + this.at + + " | " + + this.isRecurring; } } \ No newline at end of file diff --git a/src/main/java/duke/task/Task.java b/src/main/java/duke/task/Task.java index b8868978fd..e200931b0b 100644 --- a/src/main/java/duke/task/Task.java +++ b/src/main/java/duke/task/Task.java @@ -5,6 +5,7 @@ import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; +import java.time.Duration; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; @@ -28,6 +29,10 @@ public abstract class Task { * a localDateTime constructor to save the date and time */ protected LocalDateTime ld; + /** + * A boolean that represents whether or not a task is recurring. True = recurring, False = non-recurring + */ + protected boolean isRecurring = false; /** * Initialises the minimum fields required to setup a Task. @@ -71,6 +76,38 @@ public void markAsDone() { isDone = true; } + /** + * Marks the task as recurring. + */ + public void makeTaskRecurring() { isRecurring = true; } + + /** + * Returns boolean stating whether task is recurring. + */ + public boolean isTaskRecurring() { return isRecurring; } + + /** + * When a task is recurring, method compares current time to listed date. + * If the task's date is outdated, then it will update to be for the next day. + */ + public void recurringTaskTimeUpdate() { + if ((ld != null) && this.isRecurring) { + try { + LocalDateTime currentTime = LocalDateTime.now(); + if (this.ld.isBefore(currentTime)) { + Duration dayDifference = Duration.between(currentTime, this.ld); + if (Math.abs(dayDifference.toDays()) > 0 ) { + this.ld = ld.plusDays(Math.abs(dayDifference.toDays())); + + if (!this.isDone) { this.isDone = false; } + } + } + } catch (DateTimeParseException e) { + System.out.println("I couldn't update your recurring events' times."); + } + } + } + /** * Returns a string with the status icon and the description of the task. * @@ -131,6 +168,7 @@ public void updateLocalDateTime(String time){ System.out.println("Invalid format. Please Enter Date and Time in the format of dd/MM/yyyy HHmm"); } } + /** * Returns the data and time information stored in the task without a certain format. * @@ -138,6 +176,11 @@ public void updateLocalDateTime(String time){ */ public LocalDateTime getDateTime() { + if (this.isTaskRecurring()) { this.recurringTaskTimeUpdate(); } return ld; } + + public LocalDate getDate() { + return ld.toLocalDate(); + } } \ No newline at end of file diff --git a/src/main/java/duke/task/Todo.java b/src/main/java/duke/task/Todo.java index c20ea65f75..12e6f88615 100644 --- a/src/main/java/duke/task/Todo.java +++ b/src/main/java/duke/task/Todo.java @@ -32,7 +32,12 @@ public String toString() { * @return A string in a specific format to be stored in a local file. */ public String writeTxt() { - return "T | " + (this.isDone() ? "1" : "0") + " | " + this.description; + return "T | " + + (this.isDone() ? "1" : "0") + + " | " + + this.description + + " | " + + this.isRecurring; } } \ No newline at end of file diff --git a/src/test/java/duke/core/ParserTest.java b/src/test/java/duke/core/ParserTest.java index 4a7617aafe..dd694717f7 100644 --- a/src/test/java/duke/core/ParserTest.java +++ b/src/test/java/duke/core/ParserTest.java @@ -20,6 +20,8 @@ public void commandTypeTest() throws DukeException { Command c6 = Parser.parse("todo abc"); Command c7 = Parser.parse("event Meeting /at 2PM"); Command c8 = Parser.parse("deadline event Homework ABC /by 1PM"); + Command c9 = Parser.parse("view 16/09/2019"); + assertTrue(c1 instanceof ExitCommand, "The command type should be "); assertTrue(c2 instanceof DoneCommand, "The command type should be 'DoneCommand'"); @@ -29,5 +31,6 @@ public void commandTypeTest() throws DukeException { assertTrue(c6 instanceof AddCommand, "The command type should be 'AddCommand'"); assertTrue(c7 instanceof AddCommand, "The command type should be 'AddCommand'"); assertTrue(c8 instanceof AddCommand, "The command type should be 'AddCommand'"); + assertTrue(c9 instanceof ViewCommand, "The command type should be 'ViewCommand'"); } } From 04050fdee9082b467684db86e736e37c41dfb135 Mon Sep 17 00:00:00 2001 From: WEIFENG-NUSCEG Date: Tue, 17 Sep 2019 01:09:29 +0800 Subject: [PATCH 039/420] fix the program exit problem --- src/main/java/duke/Duke.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index 212bcb7696..cf6f6a518e 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -60,6 +60,7 @@ public void run() { globalUi.showLine(); } } + System.exit(0); } /** * Starts the Duke thread and Reminder thread concurrently @@ -68,9 +69,9 @@ public void run() { * @param args The command line arguments. */ public static void main(String[] args) { - Duke n = new Duke("./data/duke.txt"); + Duke d = new Duke("./data/duke.txt"); Reminder r = new Reminder(globalTasks,globalUi); - Thread t1 = new Thread(n); + Thread t1 = new Thread(d); Thread t2 = new Thread(r); t1.start(); t2.start(); From 4f1df3baac2f20f790dd55e64bb7c9d33eff197b Mon Sep 17 00:00:00 2001 From: lmtaek Date: Tue, 17 Sep 2019 10:18:26 +0800 Subject: [PATCH 040/420] Updated RecurringTasks to handle multiple types of recurrences through enumerators; should be able to handle daily, weekly, and monthly input. If a task is out of date, during recurringTaskUpdate the date will change until it comes after the current date. --- .../java/duke/command/RecurringCommand.java | 6 ++- src/main/java/duke/core/Parser.java | 11 ++--- src/main/java/duke/core/Storage.java | 25 +++++++++--- src/main/java/duke/task/Deadline.java | 2 +- src/main/java/duke/task/Event.java | 2 +- src/main/java/duke/task/Task.java | 40 ++++++++++++++++--- src/main/java/duke/task/Todo.java | 2 +- 7 files changed, 66 insertions(+), 22 deletions(-) diff --git a/src/main/java/duke/command/RecurringCommand.java b/src/main/java/duke/command/RecurringCommand.java index ca306367fb..e1ff42129b 100644 --- a/src/main/java/duke/command/RecurringCommand.java +++ b/src/main/java/duke/command/RecurringCommand.java @@ -14,10 +14,12 @@ public class RecurringCommand extends Command { * Used to identify the task being marked as recurring. */ private int taskIndex; + protected Task.RecurringFrequency frequency; - public RecurringCommand(int taskIndex) { + public RecurringCommand(int taskIndex, Task.RecurringFrequency frequency) { super(); this.taskIndex = taskIndex; + this.frequency = frequency; } /** @@ -46,7 +48,7 @@ public void execute(TaskList tasks, Ui ui, Storage storage) throws DukeException Task recurringTask = tasks.getTask(taskIndex); if (recurringTask.getDateTime() != null) { if (!recurringTask.isTaskRecurring()) { - recurringTask.makeTaskRecurring(); + recurringTask.makeTaskRecurring(this.frequency); ui.makeRecurring(recurringTask); } recurringTask.recurringTaskTimeUpdate(); diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index aa1c3ace82..035ac7bf5b 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -1,10 +1,7 @@ package duke.core; import duke.command.*; -import duke.task.Deadline; -import duke.task.PeriodTask; -import duke.task.Event; -import duke.task.Todo; +import duke.task.*; import java.text.DateFormat; import java.text.ParseException; @@ -99,7 +96,11 @@ public static Command parse(String ss) throws DukeException { case "recurring": try { int index = Integer.parseInt(command[1]); - return new RecurringCommand(index); + if (ss.toLowerCase().contains("weekly")) { return new RecurringCommand(index, Task.RecurringFrequency.WEEKLY); } + else if (ss.toLowerCase().contains("monthly")) { return new RecurringCommand(index, Task.RecurringFrequency.MONTHLY); } + else if (ss.toLowerCase().contains("daily")) { return new RecurringCommand(index, Task.RecurringFrequency.DAILY);} + else { return new RecurringCommand(index, Task.RecurringFrequency.DAILY);} + } catch (Exception e) { throw new DukeException("Failed to make your task recurring." + e.getMessage()); } diff --git a/src/main/java/duke/core/Storage.java b/src/main/java/duke/core/Storage.java index 8fef581723..7bec034550 100644 --- a/src/main/java/duke/core/Storage.java +++ b/src/main/java/duke/core/Storage.java @@ -47,8 +47,8 @@ public ArrayList load() throws DukeException { if (newTask[1].equals("1")) { x.markAsDone(); } - if (newTask[3].equals("true")) { - x.makeTaskRecurring(); + if ((newTask[3] != null) && !(newTask[3].equals("ONCE"))) { + x.makeTaskRecurring(giveFrequency(newTask[3])); } tasks.add(x); } @@ -57,8 +57,8 @@ else if (newTask[0].equals("D")) { if (newTask[1].equals("1")) { t.markAsDone(); } - if (newTask[4].equals("true")) { - t.makeTaskRecurring(); + if ((newTask[4] != null) && !(newTask[4].equals("ONCE"))) { + t.makeTaskRecurring(giveFrequency(newTask[4])); } tasks.add(t); } @@ -67,8 +67,8 @@ else if (newTask[0].equals("E")) { if (newTask[1].equals("1")) { t.markAsDone(); } - if (newTask[4].equals("true")) { - t.makeTaskRecurring(); + if ((newTask[4] != null) && !(newTask[4].equals("ONCE"))) { + t.makeTaskRecurring(giveFrequency(newTask[4])); } tasks.add(t); } @@ -106,4 +106,17 @@ public void save(ArrayList task) throws DukeException { } } + private Task.RecurringFrequency giveFrequency(String string) { + switch (string) { + case "DAILY": + return Task.RecurringFrequency.DAILY; + case "WEEKLY": + return Task.RecurringFrequency.WEEKLY; + case "MONTHLY": + return Task.RecurringFrequency.MONTHLY; + default: + return Task.RecurringFrequency.ONCE; + } + } + } diff --git a/src/main/java/duke/task/Deadline.java b/src/main/java/duke/task/Deadline.java index efecd214eb..bdb758064a 100644 --- a/src/main/java/duke/task/Deadline.java +++ b/src/main/java/duke/task/Deadline.java @@ -52,7 +52,7 @@ public String writeTxt() { + " | " + this.by + " | " - + this.isRecurring; + + this.frequency; } } \ No newline at end of file diff --git a/src/main/java/duke/task/Event.java b/src/main/java/duke/task/Event.java index b1dca3e833..82e23cbc89 100644 --- a/src/main/java/duke/task/Event.java +++ b/src/main/java/duke/task/Event.java @@ -48,6 +48,6 @@ public String writeTxt() { + " | " + this.at + " | " - + this.isRecurring; + + this.frequency; } } \ No newline at end of file diff --git a/src/main/java/duke/task/Task.java b/src/main/java/duke/task/Task.java index e200931b0b..20c6b161be 100644 --- a/src/main/java/duke/task/Task.java +++ b/src/main/java/duke/task/Task.java @@ -17,23 +17,34 @@ * instantiated */ public abstract class Task { + /** * A String that represents the description of the task. */ protected String description; + /** * A boolean that represents the status of the task( 1 means done, 0 means not yet) */ protected boolean isDone; + /** * a localDateTime constructor to save the date and time */ protected LocalDateTime ld; + /** * A boolean that represents whether or not a task is recurring. True = recurring, False = non-recurring */ protected boolean isRecurring = false; + /** + * Enumerators meant to specify how frequently a task should appear. + * Default enumerator is 'ONCE'. + */ + public enum RecurringFrequency { DAILY, WEEKLY, MONTHLY, ONCE } + protected RecurringFrequency frequency = RecurringFrequency.ONCE; + /** * Initialises the minimum fields required to setup a Task. * @@ -79,7 +90,10 @@ public void markAsDone() { /** * Marks the task as recurring. */ - public void makeTaskRecurring() { isRecurring = true; } + public void makeTaskRecurring(RecurringFrequency frequency) { + isRecurring = true; + this.frequency = frequency; + } /** * Returns boolean stating whether task is recurring. @@ -95,11 +109,25 @@ public void recurringTaskTimeUpdate() { try { LocalDateTime currentTime = LocalDateTime.now(); if (this.ld.isBefore(currentTime)) { - Duration dayDifference = Duration.between(currentTime, this.ld); - if (Math.abs(dayDifference.toDays()) > 0 ) { - this.ld = ld.plusDays(Math.abs(dayDifference.toDays())); - - if (!this.isDone) { this.isDone = false; } + switch (this.frequency) { + case DAILY: + Duration dayDifference = Duration.between(currentTime, this.ld); + if (Math.abs(dayDifference.toDays()) > 0 ) { + this.ld = ld.plusDays(Math.abs(dayDifference.toDays())); + if (this.isDone) { this.isDone = false; } + } + case WEEKLY: + while (this.ld.isBefore(currentTime)) { + this.ld = ld.plusWeeks(1); + } + if (this.isDone) { this.isDone = false; } + case MONTHLY: + while (this.ld.isBefore(currentTime)) { + this.ld = ld.plusMonths(1); + } + if (this.isDone) { this.isDone = false; } + default: + System.out.println("I couldn't update your recurring events' times."); } } } catch (DateTimeParseException e) { diff --git a/src/main/java/duke/task/Todo.java b/src/main/java/duke/task/Todo.java index 12e6f88615..1750e0fd49 100644 --- a/src/main/java/duke/task/Todo.java +++ b/src/main/java/duke/task/Todo.java @@ -37,7 +37,7 @@ public String writeTxt() { + " | " + this.description + " | " - + this.isRecurring; + + this.frequency; } } \ No newline at end of file From 981d70fd8eb87f3c674d1e73fba60881f0419e52 Mon Sep 17 00:00:00 2001 From: kkeejjuunn Date: Tue, 17 Sep 2019 12:31:25 +0800 Subject: [PATCH 041/420] added B-FixedDurationTasks --- src/main/java/duke/command/AddCommand.java | 12 +++-- .../duke/command/FindFreeTimesCommand.java | 4 ++ src/main/java/duke/core/Parser.java | 14 ++++-- .../java/duke/task/FixedDurationTask.java | 44 +++++++++++++++++++ 4 files changed, 67 insertions(+), 7 deletions(-) create mode 100644 src/main/java/duke/command/FindFreeTimesCommand.java create mode 100644 src/main/java/duke/task/FixedDurationTask.java diff --git a/src/main/java/duke/command/AddCommand.java b/src/main/java/duke/command/AddCommand.java index 634238f0f2..31e48e16cb 100644 --- a/src/main/java/duke/command/AddCommand.java +++ b/src/main/java/duke/command/AddCommand.java @@ -5,7 +5,10 @@ import duke.core.Storage; import duke.core.TaskList; import duke.core.Ui; +import duke.task.Deadline; +import duke.task.Event; import duke.task.Task; +import duke.task.Todo; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -13,7 +16,7 @@ /** * Represents a command class to add a task. The AddCommand class * extends from the Command class to represent user instruction - * to add a new ToDo, Deadline or Event + * to add a new ToDo, FixedDurationTask, Deadline or Event * task to the TaskList. */ public class AddCommand extends Command { @@ -58,8 +61,11 @@ public void execute(TaskList tasks, Ui ui, Storage storage) throws DukeException String userAnswer; for (Task t : taskList) { - if (t.getDate().equals(task.getDate()) && !t.isDone()) { - isClash = true; + if (t instanceof Deadline || t instanceof Event) + { + if (t.getDateTime().equals(task.getDateTime()) && !t.isDone()) { + isClash = true; + } } } diff --git a/src/main/java/duke/command/FindFreeTimesCommand.java b/src/main/java/duke/command/FindFreeTimesCommand.java new file mode 100644 index 0000000000..27c047538f --- /dev/null +++ b/src/main/java/duke/command/FindFreeTimesCommand.java @@ -0,0 +1,4 @@ +package duke.command; + +public class FindFreeTimesCommand { +} diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index aa1c3ace82..0b16125793 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -1,10 +1,7 @@ package duke.core; import duke.command.*; -import duke.task.Deadline; -import duke.task.PeriodTask; -import duke.task.Event; -import duke.task.Todo; +import duke.task.*; import java.text.DateFormat; import java.text.ParseException; @@ -51,6 +48,15 @@ public static Command parse(String ss) throws DukeException { } catch (Exception e) { throw new DukeException(e.getMessage()); } + case "fixeddurationtask": + try { + String[] temp = command[1].split(" /needs "); + FixedDurationTask fixedDurationTask = new FixedDurationTask(temp[0], temp[1]); + return new AddCommand(fixedDurationTask); + } + catch (Exception e) { + throw new DukeException(e.getMessage()); + } case "deadline": try { String[] temp = command[1].split(" /by "); diff --git a/src/main/java/duke/task/FixedDurationTask.java b/src/main/java/duke/task/FixedDurationTask.java new file mode 100644 index 0000000000..c5bf58f5d4 --- /dev/null +++ b/src/main/java/duke/task/FixedDurationTask.java @@ -0,0 +1,44 @@ +package duke.task; + +public class FixedDurationTask extends Task { + /** + * A string that represents the duration of the task + */ + private String duration; + + /** + * Constructs a Fixed duration task object. Duration is parsed and + * stored in string format + * + * @param description A string that saves the description of the task. + * @param duration A string that specifies the duration of the task. + */ + public FixedDurationTask(String description, String duration) { + super(description); + this.duration = duration; + } + + /** + * + * @return A string which displays the type, + * description and duration of the task. + */ + @Override + public String toString() { + return "[F]" + super.printStatus() + " (duration: " + this.duration + ")"; + } + + /** + * Returns a string with the following format to be stored in a local file + * + * @return A string in a specific format to be stored in a local file. + */ + public String writeTxt() { + return "F | " + + (this.isDone() ? "1" : "0") + + " | " + + this.description + + " | " + + this.isRecurring; + } +} From a9209a844ecd34af23793790e667776949d9a67b Mon Sep 17 00:00:00 2001 From: kkeejjuunn Date: Tue, 17 Sep 2019 13:26:22 +0800 Subject: [PATCH 042/420] Fixed the bugs that duration is not saved --- src/main/java/duke/core/Storage.java | 9 +++++++++ src/main/java/duke/task/FixedDurationTask.java | 2 ++ 2 files changed, 11 insertions(+) diff --git a/src/main/java/duke/core/Storage.java b/src/main/java/duke/core/Storage.java index 8fef581723..7fb6d61f8a 100644 --- a/src/main/java/duke/core/Storage.java +++ b/src/main/java/duke/core/Storage.java @@ -79,6 +79,15 @@ else if (newTask[0].equals("P")) { t.markAsDone(); } tasks.add(t); + }else if (newTask[0].equals("F")) { + Task x = new FixedDurationTask(newTask[2], newTask[3]); + if (newTask[1].equals("1")) { + x.markAsDone(); + } + if (newTask[4].equals("true")) { + x.makeTaskRecurring(); + } + tasks.add(x); } } diff --git a/src/main/java/duke/task/FixedDurationTask.java b/src/main/java/duke/task/FixedDurationTask.java index c5bf58f5d4..0c65baa8a9 100644 --- a/src/main/java/duke/task/FixedDurationTask.java +++ b/src/main/java/duke/task/FixedDurationTask.java @@ -39,6 +39,8 @@ public String writeTxt() { + " | " + this.description + " | " + + this.duration + + " | " + this.isRecurring; } } From bb432ce06a8cc09819e6020f4af1b71d016dd4ab Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Tue, 17 Sep 2019 13:38:47 +0800 Subject: [PATCH 043/420] Update Tasks by removing LocalDateTimeFormatter --- data/duke.txt | 19 +++----- src/main/java/duke/task/Deadline.java | 21 +++++---- src/main/java/duke/task/Event.java | 23 +++++---- src/main/java/duke/task/Task.java | 68 +++++++++++++-------------- 4 files changed, 65 insertions(+), 66 deletions(-) diff --git a/data/duke.txt b/data/duke.txt index 02ebc979f7..8988e891a5 100644 --- a/data/duke.txt +++ b/data/duke.txt @@ -1,12 +1,7 @@ -D | 1 | ssss | 16/09/2019 0200 | false -D | 1 | tttt | 16/09/2019 0500 | false -E | 1 | tasktest | 16/09/2019 1000 | false -D | 1 | read book | 27/09/2019 1800 | false -D | 1 | watch movie | 27/09/2019 1800 | false -D | 1 | adding | 27/09/2019 1900 | false -D | 1 | hello | 27/09/2019 2000 | false -D | 1 | readbook | 27/09/2019 2300 | false -D | 0 | watch tv | 27/09/2019 1700 | false -D | 0 | hello | 27/09/2019 1800 | false -P | 0 | abc | 27/07/1996 1530 | 27/07/2020 1530 -P | 0 | abc | 27/07/1996 1530 | 27/07/2020 1530 \ No newline at end of file +E | 0 | fsahufias | 30/06/2020 0316 | false +D | 0 | abc | 27/07/1996 2130 | false +P | 0 | abc | 27/07/1996 2130 | 27/06/2029 1630 +D | 0 | abc | 27/07/1996 2130 | false +T | 1 | abc | false +D | 0 | abc | 17/09/2019 2130 | false +E | 0 | werq | 17/09/2019 1500 | false diff --git a/src/main/java/duke/task/Deadline.java b/src/main/java/duke/task/Deadline.java index efecd214eb..826f4e6961 100644 --- a/src/main/java/duke/task/Deadline.java +++ b/src/main/java/duke/task/Deadline.java @@ -1,5 +1,6 @@ package duke.task; +import duke.core.DateTimeParser; import duke.core.DukeException; /** @@ -10,7 +11,8 @@ public class Deadline extends Task { /** * A string that represents the deadline of the task. */ - private String by; + private String dateTime; + private String dateTimeEnglish; /** * Constructs a Deadline object. Date and time are parsed and @@ -19,13 +21,14 @@ public class Deadline extends Task { * * @param description A string that describes the specific * description of task. - * @param by A string that specifies the deadline of the + * @param dateTime A string that specifies the deadline of the * task. */ - public Deadline(String description, String by) { + public Deadline(String description, String dateTime) throws DukeException { super(description); - this.by = by; - super.updateLocalDateTime(by); + super.updateLocalDateTime(dateTime); + this.dateTime = dateTime; + dateTimeEnglish = DateTimeParser.convertToEnglishDateTime(dateTime); } /** @@ -36,7 +39,7 @@ public Deadline(String description, String by) { */ @Override public String toString() { - return "[D]" + super.printStatus() + " (by: " + super.timeFormatter(by) + ")"; + return "[D]" + super.printStatus() + " (by: " + dateTimeEnglish + ")"; } /** @@ -46,11 +49,11 @@ public String toString() { */ public String writeTxt() { return "D | " - + (this.isDone ? "1" : "0") + + (isDone() ? "1" : "0") + " | " - + this.description + + getDescription() + " | " - + this.by + + dateTime + " | " + this.isRecurring; } diff --git a/src/main/java/duke/task/Event.java b/src/main/java/duke/task/Event.java index b1dca3e833..ab36625354 100644 --- a/src/main/java/duke/task/Event.java +++ b/src/main/java/duke/task/Event.java @@ -1,5 +1,8 @@ package duke.task; +import duke.core.DateTimeParser; +import duke.core.DukeException; + /** * Represents a task with a event. It is * extended from the Task class. @@ -8,7 +11,8 @@ public class Event extends Task { /** * A string that represents the time of the event. */ - private String at; + private String dateTime; + private String dateTimeEnglish; /** * Constructs a Event object. Date and time are parsed and @@ -16,12 +20,13 @@ public class Event extends Task { * format. * * @param description A string that saves the description of the task. - * @param at A string that specifies the time of the event. + * @param dateTime A string that specifies the time of the event. */ - public Event(String description, String at) { + public Event(String description, String dateTime) throws DukeException { super(description); - this.at = at; - super.updateLocalDateTime(at); + super.updateLocalDateTime(dateTime); + this.dateTime = dateTime; + dateTimeEnglish = DateTimeParser.convertToEnglishDateTime(dateTime); } /** @@ -32,7 +37,7 @@ public Event(String description, String at) { */ @Override public String toString() { - return "[E]" + super.printStatus() + " (at: " + super.timeFormatter(at) + ")"; + return "[E]" + super.printStatus() + " (at: " + dateTimeEnglish + ")"; } /** @@ -42,11 +47,11 @@ public String toString() { */ public String writeTxt() { return "E | " - + (this.isDone ? "1" : "0") + + (isDone() ? "1" : "0") + " | " - + this.description + + getDescription() + " | " - + this.at + + dateTime + " | " + this.isRecurring; } diff --git a/src/main/java/duke/task/Task.java b/src/main/java/duke/task/Task.java index e200931b0b..2439c44c9b 100644 --- a/src/main/java/duke/task/Task.java +++ b/src/main/java/duke/task/Task.java @@ -1,5 +1,6 @@ package duke.task; +import duke.core.DateTimeParser; import duke.core.DukeException; import java.text.DateFormat; @@ -28,7 +29,7 @@ public abstract class Task { /** * a localDateTime constructor to save the date and time */ - protected LocalDateTime ld; + protected LocalDateTime ld = null; /** * A boolean that represents whether or not a task is recurring. True = recurring, False = non-recurring */ @@ -129,44 +130,39 @@ public String getDescription() { - /** - * Returns a string that representing the data and time for the task - * in a predefined date time format. - * @param timeBeforeFormat a string that provides the data and time information. - * @return A string that represents the specific activity associated with - * the task. - */ - public String timeFormatter(String timeBeforeFormat) { - DateTimeFormatter stFormatter = DateTimeFormatter.ofPattern("d'st of' MMMM yyyy, ha"); - DateTimeFormatter ndFormatter = DateTimeFormatter.ofPattern("d'nd of' MMMM yyyy, ha"); - DateTimeFormatter rdFormatter = DateTimeFormatter.ofPattern("d'rd of' MMMM yyyy, ha"); - DateTimeFormatter thFormatter = DateTimeFormatter.ofPattern("d'th of' MMMM yyyy, ha"); - - String output; - - if ((ld.getDayOfMonth() % 10) == 1) { - output = ld.format(stFormatter); - } else if ((ld.getDayOfMonth() % 10) == 2) { - output = ld.format(ndFormatter); - } else if ((ld.getDayOfMonth() % 10) == 3) { - output = ld.format(rdFormatter); - } else { - output = ld.format(thFormatter); - } - return output; - } +// /** +// * Returns a string that representing the data and time for the task +// * in a predefined date time format. +// * @param timeBeforeFormat a string that provides the data and time information. +// * @return A string that represents the specific activity associated with +// * the task. +// */ +// public String timeFormatter(String timeBeforeFormat) { +// DateTimeFormatter stFormatter = DateTimeFormatter.ofPattern("d'st of' MMMM yyyy, ha"); +// DateTimeFormatter ndFormatter = DateTimeFormatter.ofPattern("d'nd of' MMMM yyyy, ha"); +// DateTimeFormatter rdFormatter = DateTimeFormatter.ofPattern("d'rd of' MMMM yyyy, ha"); +// DateTimeFormatter thFormatter = DateTimeFormatter.ofPattern("d'th of' MMMM yyyy, ha"); +// +// String output; +// +// if ((ld.getDayOfMonth() % 10) == 1) { +// output = ld.format(stFormatter); +// } else if ((ld.getDayOfMonth() % 10) == 2) { +// output = ld.format(ndFormatter); +// } else if ((ld.getDayOfMonth() % 10) == 3) { +// output = ld.format(rdFormatter); +// } else { +// output = ld.format(thFormatter); +// } +// return output; +// } /** * update the LocalDateTime constructor to save the date and time - * @param time the time retrieved from user input. - */ - public void updateLocalDateTime(String time){ - DateTimeFormatter parser = DateTimeFormatter.ofPattern("dd/MM/yyyy HHmm"); - try { - ld = LocalDateTime.parse(time, parser); - } catch (DateTimeParseException error) { - System.out.println("Invalid format. Please Enter Date and Time in the format of dd/MM/yyyy HHmm"); - } + * @param newDateTime the time retrieved from user input. + */ + public void updateLocalDateTime(String newDateTime) throws DukeException { + ld = DateTimeParser.convertToLocalDateTime(newDateTime); } /** From 27c3014b64a6e2b248adb5fbe6ac33071e349b6a Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Tue, 17 Sep 2019 13:39:35 +0800 Subject: [PATCH 044/420] Fixed bug of adding todo task causing null pointer error --- src/main/java/duke/command/AddCommand.java | 57 ++++++++++++++-------- 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/src/main/java/duke/command/AddCommand.java b/src/main/java/duke/command/AddCommand.java index 634238f0f2..127ab95c2b 100644 --- a/src/main/java/duke/command/AddCommand.java +++ b/src/main/java/duke/command/AddCommand.java @@ -5,10 +5,14 @@ import duke.core.Storage; import duke.core.TaskList; import duke.core.Ui; +import duke.task.Deadline; +import duke.task.Event; import duke.task.Task; +import duke.task.Todo; import java.time.format.DateTimeFormatter; import java.util.ArrayList; +import java.util.Scanner; /** * Represents a command class to add a task. The AddCommand class @@ -20,17 +24,17 @@ public class AddCommand extends Command { /** * A new task to be added */ - private Task task; + private Task newTask; private Boolean isClash = false; /** * Constructs a AddCommand object. * - * @param task Specifies the task to be added. + * @param newTask Specifies the task to be added. */ - public AddCommand(Task task) { + public AddCommand(Task newTask) { super(); - this.task = task; + this.newTask = newTask; } /** @@ -54,30 +58,43 @@ public boolean isExit() { @Override public void execute(TaskList tasks, Ui ui, Storage storage) throws DukeException { try { - ArrayList taskList = tasks.fullTaskList(); + ArrayList tasksInTheList = tasks.fullTaskList(); + ArrayList clashTasksInTheList = new ArrayList(); String userAnswer; - for (Task t : taskList) { - if (t.getDate().equals(task.getDate()) && !t.isDone()) { - isClash = true; + for (Task t : tasksInTheList) { + if ((t instanceof Deadline || t instanceof Event) && (newTask instanceof Deadline || newTask instanceof Event) ){ + if (t.getDate().equals(newTask.getDate()) && !t.isDone()) { + clashTasksInTheList.add(t); + isClash = true; + } } } - if (isClash) { - userAnswer = ui.showClashWarning(taskList, task); - if (userAnswer.equals("Y") || userAnswer.equals("y") ) { - tasks.addTask(task); - ui.taskAdded(task, tasks.getSize()); - storage.save(tasks.fullTaskList()); - } else { - System.out.println("Alright , I have aborted the task."); + ui.showClashWarning(clashTasksInTheList , newTask); + Scanner input = new Scanner(System.in); + boolean isValidUserInput = false ; + + while (!isValidUserInput) { + String userInput = input.nextLine(); + if (userInput.equals("Y") || userInput.equals("N") ) { + isValidUserInput = true; + if (userInput.equals("Y")) { + tasks.addTask(newTask); + ui.taskAdded(newTask, tasks.getSize()); + storage.save(tasks.fullTaskList()); + } else { + System.out.println("Alright , I have aborted the task."); + } + } else { + System.out.println("Please enter Y or N only ! (Cap Sensitive) "); + } } - } else { - tasks.addTask(task); - ui.taskAdded(task, tasks.getSize()); + }else{ + tasks.addTask(newTask); + ui.taskAdded(newTask, tasks.getSize()); storage.save(tasks.fullTaskList()); } - } catch (DukeException e) { throw new DukeException("Fails to add task. " + e.getMessage()); } From def21dc2a0bd08880dc8241e3305be0cdd53703f Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Tue, 17 Sep 2019 13:40:07 +0800 Subject: [PATCH 045/420] Fixed bug of negative duration in the reminder --- src/main/java/duke/Reminder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/duke/Reminder.java b/src/main/java/duke/Reminder.java index f2204a0fbb..ddae312cc4 100644 --- a/src/main/java/duke/Reminder.java +++ b/src/main/java/duke/Reminder.java @@ -53,7 +53,7 @@ public void run() { if (!(v.getDateTime() == null)) { int seconds = (int) ChronoUnit.SECONDS.between(v.getDateTime(), LocalDateTime.now()); - if ((!v.isDone()) && seconds < SECONDS_IN_A_DAY) { + if ((!v.isDone()) && Math.abs(seconds) < SECONDS_IN_A_DAY) { tempTask.add(v); } } From e513f31f00e690f2d35439f329964c4faf7c29b2 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Tue, 17 Sep 2019 13:40:48 +0800 Subject: [PATCH 046/420] Update showClashWarning logic --- src/main/java/duke/core/Ui.java | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index 0b8bc681c7..f133b42636 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -96,19 +96,24 @@ public void taskFound(ArrayList a, String name) { } } - public String showClashWarning (ArrayList tasklist, Task task) { + /** + * Find and display a specific task stored in the list. + * + * @param clashTasksInTheList TaskList used to store tasks. + * @param newTask the task to be added + * @return the user's answer to whether he want to add or about the task + */ + public void showClashWarning (ArrayList clashTasksInTheList, Task newTask) { System.out.println("Here are the tasks that fall on the same day:"); int count = 1; - for (Task t : tasklist) { - if (t.getDate().equals(task.getDate()) && !t.isDone()) { - System.out.println(count + ": " + t); - count++; - } + for (Task t : clashTasksInTheList) { + System.out.println(count + ": " + t); + count++; } showLine(); System.out.println("Do you still want to add your task anyway? Y/N"); - String userAnswer = scanner.nextLine(); - return userAnswer; +// String userAnswer = scanner.nextLine(); +// return userAnswer; } From 4760727f26bfc67b90c2e5fb400ca6d4db2b2110 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Tue, 17 Sep 2019 13:41:15 +0800 Subject: [PATCH 047/420] Update Junit test after implementing recurring task --- src/test/java/duke/core/ParserTest.java | 4 ++-- src/test/java/duke/task/DeadlineTest.java | 10 +++++----- src/test/java/duke/task/EventTest.java | 12 ++++++------ src/test/java/duke/task/TodoTest.java | 4 ++-- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/test/java/duke/core/ParserTest.java b/src/test/java/duke/core/ParserTest.java index dd694717f7..4b1362316c 100644 --- a/src/test/java/duke/core/ParserTest.java +++ b/src/test/java/duke/core/ParserTest.java @@ -18,8 +18,8 @@ public void commandTypeTest() throws DukeException { Command c4 = Parser.parse("list"); Command c5 = Parser.parse("find MEETING"); Command c6 = Parser.parse("todo abc"); - Command c7 = Parser.parse("event Meeting /at 2PM"); - Command c8 = Parser.parse("deadline event Homework ABC /by 1PM"); + Command c7 = Parser.parse("event Meeting /at 27/07/2020 1630"); + Command c8 = Parser.parse("deadline event Homework ABC /by 27/07/2020 1630"); Command c9 = Parser.parse("view 16/09/2019"); diff --git a/src/test/java/duke/task/DeadlineTest.java b/src/test/java/duke/task/DeadlineTest.java index de7cd87d85..c76d69f89c 100644 --- a/src/test/java/duke/task/DeadlineTest.java +++ b/src/test/java/duke/task/DeadlineTest.java @@ -12,7 +12,7 @@ public class DeadlineTest { * Test the Deadline.toString() */ @Test - public void deadlineStringTest() { + public void deadlineStringTest() throws DukeException { assertEquals( "[D][\u2718] abc (by: 2nd of December 1996, 12PM)", new Deadline("abc", "02/12/1996 1235").toString(),"Deadline toString() is not expected"); } @@ -20,15 +20,15 @@ public void deadlineStringTest() { * Test the Deadline.writeTxt() */ @Test - public void writeFormatTest() { - assertEquals( "D | 0 | deadlineTest | 02/12/1996 1235",new Deadline("deadlineTest", "02/12/1996 1235").writeTxt(), "The writeToFile format is not expected"); + public void writeFormatTest() throws DukeException { + assertEquals( "D | 0 | deadlineTest | 02/12/1996 1235 | false",new Deadline("deadlineTest", "02/12/1996 1235").writeTxt(), "The writeToFile format is not expected"); } /** * Test the Deadline.isDone() after a new Deadline object is being initialized */ @Test - public void doneStatusTest() { + public void doneStatusTest() throws DukeException { assertFalse(new Deadline("abc", "02/12/1996 1235").isDone(), "The newly created Deadline should not be done"); } @@ -48,7 +48,7 @@ public void deadlineTestCase() throws DukeException { Deadline deadline = new Deadline("deadlineTest", "02/12/1996 1235"); assertFalse(deadline.isDone(), "The newly created deadline should not be done"); assertEquals( "[D][\u2718] deadlineTest (by: 2nd of December 1996, 12PM)",deadline.toString(), "The writeToFile format is not expected"); - assertEquals( "D | 0 | deadlineTest | 02/12/1996 1235",deadline.writeTxt(), "The writeToFile format is not expected"); + assertEquals( "D | 0 | deadlineTest | 02/12/1996 1235 | false",deadline.writeTxt(), "The writeToFile format is not expected"); // Mark the deadline as done and check its toString() and writeTxt() deadline.markAsDone(); diff --git a/src/test/java/duke/task/EventTest.java b/src/test/java/duke/task/EventTest.java index 9bd8cf0883..403161deaf 100644 --- a/src/test/java/duke/task/EventTest.java +++ b/src/test/java/duke/task/EventTest.java @@ -12,7 +12,7 @@ public class EventTest { * Test the Event.toString() */ @Test - public void EventStringTest() { + public void EventStringTest() throws DukeException { assertEquals("[E][\u2718] eventTest (at: 2nd of December 1996, 12PM)", new Event("eventTest", "02/12/1996 1235").toString(), "toString result is not expected"); } @@ -20,15 +20,15 @@ public void EventStringTest() { * Test the Event.writeTxt() */ @Test - public void writeFormatTest() { - assertEquals( "E | 0 | test | 02/12/1996 1235",new Event("test", "02/12/1996 1235").writeTxt(), "The writeToFile format is not expected"); + public void writeFormatTest() throws DukeException { + assertEquals( "E | 0 | test | 02/12/1996 1235 | false",new Event("test", "02/12/1996 1235").writeTxt(), "The writeToFile format is not expected"); } /** * Test the Event.isDone() after a new Event object is being initialized */ @Test - public void doneStatusTest() { + public void doneStatusTest() throws DukeException { assertFalse(new Event("test", "02/12/1996 1235").isDone(), "The newly created Deadline should not be done"); } @@ -48,12 +48,12 @@ public void eventTestCase() throws DukeException { Event event = new Event("eventTest", "02/12/1996 1235"); assertFalse(event.isDone(), "The newly created event should not be done"); assertEquals( "[E][\u2718] eventTest (at: 2nd of December 1996, 12PM)",event.toString(), "The writeToFile format is not expected"); - assertEquals( "E | 0 | eventTest | 02/12/1996 1235",event.writeTxt(), "The writeToFile format is not expected"); + assertEquals( "E | 0 | eventTest | 02/12/1996 1235 | false",event.writeTxt(), "The writeToFile format is not expected"); // Mark the event as done and check its toString() and writeTxt() event.markAsDone(); assertTrue(event.isDone(), "The event should be marked as done"); assertEquals("[E][\u2713] eventTest (at: 2nd of December 1996, 12PM)", event.toString(), "The event.toString() is not expected"); - assertEquals( "E | 1 | eventTest | 02/12/1996 1235",event.writeTxt(), "The writeToFile format is not expected"); + assertEquals( "E | 1 | eventTest | 02/12/1996 1235 | false",event.writeTxt(), "The writeToFile format is not expected"); } } \ No newline at end of file diff --git a/src/test/java/duke/task/TodoTest.java b/src/test/java/duke/task/TodoTest.java index e6e25e2361..e24e18f92a 100644 --- a/src/test/java/duke/task/TodoTest.java +++ b/src/test/java/duke/task/TodoTest.java @@ -21,7 +21,7 @@ public void todoStringTest(){ */ @Test public void writeFormatTest() { - assertEquals( "T | 0 | todoTest",new Todo("todoTest").writeTxt(), "The writeToFile format is not expected"); + assertEquals( "T | 0 | todoTest | false",new Todo("todoTest").writeTxt(), "The writeToFile format is not expected"); } /** @@ -48,7 +48,7 @@ public void todoTestCase() throws DukeException { Todo todo = new Todo("todoTest"); assertFalse(todo.isDone(), "The newly created todo should not be done"); assertEquals( "[T][\u2718] todoTest",todo.toString(), "The writeToFile format is not expected"); - assertEquals( "T | 0 | todoTest",todo.writeTxt(), "The writeToFile format is not expected"); + assertEquals( "T | 0 | todoTest | false",todo.writeTxt(), "The writeToFile format is not expected"); // Mark the task as done and check its toString() and writeTxt() todo.markAsDone(); From 498f240739ca0e255642976448837799784c5b8c Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Tue, 17 Sep 2019 14:21:40 +0800 Subject: [PATCH 048/420] Implemented checkstyleTest via gradle. Checkstyle test reports are generated. --- .gitignore | 4 +- build/reports/checkstyle/main.html | 958 +++++++++++++++++++++++++++++ build/reports/checkstyle/main.xml | 258 ++++++++ build/reports/checkstyle/test.html | 298 +++++++++ build/reports/checkstyle/test.xml | 66 ++ data/duke.txt | 3 + 6 files changed, 1586 insertions(+), 1 deletion(-) create mode 100644 build/reports/checkstyle/main.html create mode 100644 build/reports/checkstyle/main.xml create mode 100644 build/reports/checkstyle/test.html create mode 100644 build/reports/checkstyle/test.xml diff --git a/.gitignore b/.gitignore index c9e981c28c..9bb4fab266 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,9 @@ # Gradle build files /.gradle/ -/build/ +/build/classes +/build/generated +/build/tmp src/main/resources/docs/ # MacOS custom attributes files created by Finder diff --git a/build/reports/checkstyle/main.html b/build/reports/checkstyle/main.html new file mode 100644 index 0000000000..9410402449 --- /dev/null +++ b/build/reports/checkstyle/main.html @@ -0,0 +1,958 @@ + + + + + + + + + + + + + + +
+

CheckStyle Audit

+
Designed for use with CheckStyle and Ant.
+
+

Summary

+ + + + + + + +
FilesErrors
26203
+
+

Files

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameErrors
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\Parser.java94
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\Task.java15
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\AddCommand.java13
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\DateTimeParser.java11
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\RescheduleCommand.java10
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\Ui.java7
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\RecurringCommand.java6
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\Storage.java6
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\Duke.java5
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\FixedDurationTask.java4
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\PeriodTask.java4
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\RemindCommand.java3
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\ViewCommand.java3
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\Deadline.java3
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\Event.java3
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\Todo.java3
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\Reminder.java2
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\DeleteCommand.java2
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\DoneCommand.java2
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\ExitCommand.java2
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\FindCommand.java2
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\ListCommand.java2
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\Command.java1
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\FindFreeTimesCommand.java0
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\DukeException.java0
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\TaskList.java0
+
+ +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\Duke.java

+ + + + + + + + + + + + + + + + + + + +
Error DescriptionLine
Using the '.*' form of import should be avoided - duke.core.*.5
WhitespaceAround: '{' is not preceded with whitespace.11
'CTOR_DEF' should be separated from previous statement.32
First sentence of Javadoc is missing an ending period.65
'METHOD_DEF' should be separated from previous statement.71
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\Reminder.java

+ + + + + + + + + + +
Error DescriptionLine
'CTOR_DEF' should be separated from previous statement.38
'{' at column 21 should be on the previous line.54
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\AddCommand.java

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Error DescriptionLine
First sentence of Javadoc is missing an ending period.24
First sentence of Javadoc is missing an ending period.40
Line continuation have incorrect indentation level, expected level should be 4.44
Line is longer than 120 characters (found 129).67
')' is preceded with whitespace.67
WhitespaceAround: '{' is not preceded with whitespace.67
',' is preceded with whitespace.75
';' is preceded with whitespace.77
')' is preceded with whitespace.81
WhitespaceAround: '}' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)94
WhitespaceAround: 'else' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)94
WhitespaceAround: 'else' is not preceded with whitespace.94
WhitespaceAround: '{' is not preceded with whitespace.94
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\Command.java

+ + + + + + + +
Error DescriptionLine
Line continuation have incorrect indentation level, expected level should be 4.30
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\DeleteCommand.java

+ + + + + + + + + + +
Error DescriptionLine
First sentence of Javadoc is missing an ending period.31
Line continuation have incorrect indentation level, expected level should be 4.35
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\DoneCommand.java

+ + + + + + + + + + +
Error DescriptionLine
First sentence of Javadoc is missing an ending period.30
Line continuation have incorrect indentation level, expected level should be 4.34
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\ExitCommand.java

+ + + + + + + + + + +
Error DescriptionLine
First sentence of Javadoc is missing an ending period.20
Line continuation have incorrect indentation level, expected level should be 4.24
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\FindCommand.java

+ + + + + + + + + + +
Error DescriptionLine
First sentence of Javadoc is missing an ending period.29
Line continuation have incorrect indentation level, expected level should be 4.33
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\FindFreeTimesCommand.java

+ + + + +
Error DescriptionLine
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\ListCommand.java

+ + + + + + + + + + +
Error DescriptionLine
First sentence of Javadoc is missing an ending period.21
Line continuation have incorrect indentation level, expected level should be 4.25
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\RecurringCommand.java

+ + + + + + + + + + + + + + + + + + + + + + +
Error DescriptionLine
Using the '.*' form of import should be avoided - duke.task.*.7
First sentence of Javadoc is missing an ending period.23
Line continuation have incorrect indentation level, expected level should be 4.27
'{' at column 29 should have line break after.30
'}' at column 45 should be alone on a line.30
Empty line should be followed by <p> tag on the next line.34
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\RemindCommand.java

+ + + + + + + + + + + + + +
Error DescriptionLine
'CTOR_DEF' should be separated from previous statement.21
First sentence of Javadoc is missing an ending period.26
Line continuation have incorrect indentation level, expected level should be 4.30
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\RescheduleCommand.java

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Error DescriptionLine
Line is longer than 120 characters (found 127).23
WhitespaceAround: 'try' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)40
WhitespaceAround: '{' is not preceded with whitespace.40
WhitespaceAround: '{' is not preceded with whitespace.42
WhitespaceAround: '}' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)48
WhitespaceAround: 'catch' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)48
WhitespaceAround: 'catch' is not preceded with whitespace.48
WhitespaceAround: '{' is not preceded with whitespace.48
First sentence of Javadoc is missing an ending period.53
Line continuation have incorrect indentation level, expected level should be 4.57
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\ViewCommand.java

+ + + + + + + + + + + + + +
Error DescriptionLine
'(' is preceded with whitespace.16
First sentence of Javadoc is missing an ending period.23
Line continuation have incorrect indentation level, expected level should be 4.27
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\DateTimeParser.java

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Error DescriptionLine
Javadoc comment at column 19 has parse error. Missed HTML close tag 'code'. Sometimes it means that close tag missed for one of previous tags.9
Line is longer than 120 characters (found 128).33
Line is longer than 120 characters (found 128).34
Line is longer than 120 characters (found 128).35
Line is longer than 120 characters (found 128).36
WhitespaceAround: 'try' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)38
WhitespaceAround: '{' is not preceded with whitespace.38
WhitespaceAround: '}' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)50
WhitespaceAround: 'catch' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)50
WhitespaceAround: 'catch' is not preceded with whitespace.50
WhitespaceAround: '{' is not preceded with whitespace.50
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\DukeException.java

+ + + + +
Error DescriptionLine
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\Parser.java

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Error DescriptionLine
Using the '.*' form of import should be avoided - duke.command.*.3
Using the '.*' form of import should be avoided - duke.task.*.4
'case' child has incorrect indentation level 12, expected level should be 8.28
'block' child has incorrect indentation level 16, expected level should be 12.29
'case' child has incorrect indentation level 12, expected level should be 8.30
'try' has incorrect indentation level 16, expected level should be 12.31
'try' child has incorrect indentation level 20, expected level should be 16.32
'try' child has incorrect indentation level 20, expected level should be 16.33
'try rcurly' has incorrect indentation level 16, expected level should be 12.34
'catch' child has incorrect indentation level 20, expected level should be 16.35
'catch rcurly' has incorrect indentation level 16, expected level should be 12.36
'case' child has incorrect indentation level 12, expected level should be 8.37
'try' has incorrect indentation level 16, expected level should be 12.38
'try' child has incorrect indentation level 20, expected level should be 16.39
'try' child has incorrect indentation level 20, expected level should be 16.40
'try rcurly' has incorrect indentation level 16, expected level should be 12.41
'catch' child has incorrect indentation level 20, expected level should be 16.42
'catch rcurly' has incorrect indentation level 16, expected level should be 12.43
'case' child has incorrect indentation level 12, expected level should be 8.44
'try' has incorrect indentation level 16, expected level should be 12.45
'try' child has incorrect indentation level 20, expected level should be 16.46
'try' child has incorrect indentation level 20, expected level should be 16.47
'try rcurly' has incorrect indentation level 16, expected level should be 12.48
'catch' child has incorrect indentation level 20, expected level should be 16.49
'catch rcurly' has incorrect indentation level 16, expected level should be 12.50
'case' child has incorrect indentation level 12, expected level should be 8.51
'try' has incorrect indentation level 16, expected level should be 12.52
'try' child has incorrect indentation level 20, expected level should be 16.53
'try' child has incorrect indentation level 20, expected level should be 16.54
'try' child has incorrect indentation level 20, expected level should be 16.55
'try rcurly' has incorrect indentation level 16, expected level should be 12.56
'}' at column 17 should be on the same line as the next part of a multi-block statement (one that directly contains multiple blocks: if/else-if/else, do/while or try/catch/finally).56
'catch' has incorrect indentation level 17, expected level should be 12.57
'catch' child has incorrect indentation level 20, expected level should be 16.58
'catch rcurly' has incorrect indentation level 17, expected level should be 12.59
'case' child has incorrect indentation level 12, expected level should be 8.60
'try' has incorrect indentation level 16, expected level should be 12.61
'try' child has incorrect indentation level 20, expected level should be 16.62
'try' child has incorrect indentation level 20, expected level should be 16.63
'try' child has incorrect indentation level 20, expected level should be 16.64
'try rcurly' has incorrect indentation level 16, expected level should be 12.65
'catch' child has incorrect indentation level 20, expected level should be 16.66
'catch rcurly' has incorrect indentation level 16, expected level should be 12.67
'case' child has incorrect indentation level 12, expected level should be 8.68
'try' has incorrect indentation level 16, expected level should be 12.69
'try' child has incorrect indentation level 20, expected level should be 16.70
'try' child has incorrect indentation level 20, expected level should be 16.71
'try' child has incorrect indentation level 20, expected level should be 16.72
'try rcurly' has incorrect indentation level 16, expected level should be 12.73
'catch' child has incorrect indentation level 20, expected level should be 16.74
'catch rcurly' has incorrect indentation level 16, expected level should be 12.75
'case' child has incorrect indentation level 12, expected level should be 8.76
'try' has incorrect indentation level 16, expected level should be 12.77
'try' child has incorrect indentation level 20, expected level should be 16.78
'try' child has incorrect indentation level 20, expected level should be 16.79
'try' child has incorrect indentation level 20, expected level should be 16.80
'try' child has incorrect indentation level 20, expected level should be 16.81
'try rcurly' has incorrect indentation level 16, expected level should be 12.82
WhitespaceAround: '}' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)82
WhitespaceAround: 'catch' is not preceded with whitespace.82
'catch' child has incorrect indentation level 20, expected level should be 16.83
Line is longer than 120 characters (found 181).83
'catch rcurly' has incorrect indentation level 16, expected level should be 12.85
'case' child has incorrect indentation level 12, expected level should be 8.86
'block' child has incorrect indentation level 16, expected level should be 12.87
'case' child has incorrect indentation level 12, expected level should be 8.88
'try' has incorrect indentation level 16, expected level should be 12.89
'try' child has incorrect indentation level 20, expected level should be 16.90
'try' child has incorrect indentation level 20, expected level should be 16.91
'try rcurly' has incorrect indentation level 16, expected level should be 12.92
'catch' child has incorrect indentation level 20, expected level should be 16.93
Line is longer than 120 characters (found 156).93
'catch rcurly' has incorrect indentation level 16, expected level should be 12.94
'case' child has incorrect indentation level 12, expected level should be 8.95
'try' has incorrect indentation level 16, expected level should be 12.96
'try' child has incorrect indentation level 20, expected level should be 16.97
'try' child has incorrect indentation level 20, expected level should be 16.98
'try' child has incorrect indentation level 20, expected level should be 16.99
'try' child has incorrect indentation level 20, expected level should be 16.100
'try rcurly' has incorrect indentation level 16, expected level should be 12.102
'catch' child has incorrect indentation level 20, expected level should be 16.103
'catch rcurly' has incorrect indentation level 16, expected level should be 12.104
'case' child has incorrect indentation level 12, expected level should be 8.105
Fall through from previous branch of the switch statement.105
'try' has incorrect indentation level 16, expected level should be 12.106
'try' child has incorrect indentation level 20, expected level should be 16.107
'try' child has incorrect indentation level 20, expected level should be 16.108
'try rcurly' has incorrect indentation level 16, expected level should be 12.109
'catch' child has incorrect indentation level 20, expected level should be 16.110
'catch rcurly' has incorrect indentation level 16, expected level should be 12.111
'case' child has incorrect indentation level 12, expected level should be 8.112
'block' child has incorrect indentation level 16, expected level should be 12.113
'case' child has incorrect indentation level 12, expected level should be 8.114
'block' child has incorrect indentation level 16, expected level should be 12.115
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\Storage.java

+ + + + + + + + + + + + + + + + + + + + + + +
Error DescriptionLine
Using the '.*' form of import should be avoided - duke.task.*.3
'}' at column 17 should be on the same line as the next part of a multi-block statement (one that directly contains multiple blocks: if/else-if/else, do/while or try/catch/finally).54
'}' at column 17 should be on the same line as the next part of a multi-block statement (one that directly contains multiple blocks: if/else-if/else, do/while or try/catch/finally).64
'}' at column 17 should be on the same line as the next part of a multi-block statement (one that directly contains multiple blocks: if/else-if/else, do/while or try/catch/finally).74
WhitespaceAround: '}' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)82
WhitespaceAround: 'else' is not preceded with whitespace.82
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\TaskList.java

+ + + + +
Error DescriptionLine
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\Ui.java

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Error DescriptionLine
First sentence of Javadoc is missing an ending period.10
Unused Javadoc tag.104
'(' is preceded with whitespace.106
Comment has incorrect indentation level 0, expected is 8, indentation should be the same level as line 114.116
'(' is preceded with whitespace.141
',' is preceded with whitespace.141
Missing a Javadoc comment.159
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\Deadline.java

+ + + + + + + + + + + + + +
Error DescriptionLine
First sentence of Javadoc is missing an ending period.34
Line continuation have incorrect indentation level, expected level should be 4.38
First sentence of Javadoc is missing an ending period.45
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\Event.java

+ + + + + + + + + + + + + +
Error DescriptionLine
First sentence of Javadoc is missing an ending period.32
Line continuation have incorrect indentation level, expected level should be 4.36
First sentence of Javadoc is missing an ending period.43
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\FixedDurationTask.java

+ + + + + + + + + + + + + + + + +
Error DescriptionLine
First sentence of Javadoc is missing an ending period.4
Summary javadoc is missing.21
Line continuation have incorrect indentation level, expected level should be 4.24
First sentence of Javadoc is missing an ending period.31
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\PeriodTask.java

+ + + + + + + + + + + + + + + + +
Error DescriptionLine
Unused @param tag for 'startTime'.26
First sentence of Javadoc is missing an ending period.37
Line continuation have incorrect indentation level, expected level should be 4.41
First sentence of Javadoc is missing an ending period.50
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\Task.java

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Error DescriptionLine
First sentence of Javadoc is missing an ending period.25
First sentence of Javadoc is missing an ending period.29
First sentence of Javadoc is missing an ending period.57
First sentence of Javadoc is missing an ending period.66
'{' at column 37 should have line break after.83
'}' at column 59 should be alone on a line.83
'{' at column 38 should have line break after.88
'}' at column 60 should be alone on a line.88
')' is preceded with whitespace.100
'{' at column 43 should have line break after.103
Line continuation have incorrect indentation level, expected level should be 4.125
Comment has incorrect indentation level 0, expected is 4, indentation should be the same level as line 164.158
Javadoc comment at column 19 has parse error. Missed HTML close tag 'code'. Sometimes it means that close tag missed for one of previous tags.161
'{' at column 5 should be on the previous line.174
'{' at column 37 should have line break after.175
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\Todo.java

+ + + + + + + + + + + + + +
Error DescriptionLine
First sentence of Javadoc is missing an ending period.18
Line continuation have incorrect indentation level, expected level should be 4.22
First sentence of Javadoc is missing an ending period.29
+ Back to top +
+ + diff --git a/build/reports/checkstyle/main.xml b/build/reports/checkstyle/main.xml new file mode 100644 index 0000000000..777ddd1884 --- /dev/null +++ b/build/reports/checkstyle/main.xml @@ -0,0 +1,258 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/reports/checkstyle/test.html b/build/reports/checkstyle/test.html new file mode 100644 index 0000000000..10e2dd1b81 --- /dev/null +++ b/build/reports/checkstyle/test.html @@ -0,0 +1,298 @@ + + + + + + + + + + + + + + +
+

CheckStyle Audit

+
Designed for use with CheckStyle and Ant.
+
+

Summary

+ + + + + + + +
FilesErrors
553
+
+

Files

+ + + + + + + + + + + + + + + + + + + +
NameErrors
C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\task\DeadlineTest.java15
C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\task\EventTest.java15
C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\task\TodoTest.java10
C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\core\ParserTest.java7
C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\task\PeriodTaskTest.java6
+
+ +

File C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\core\ParserTest.java

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Error DescriptionLine
Using the '.*' form of import should be avoided - duke.command.*.3
Distance between variable 'c4' declaration and its first usage is 4, but allowed 3. Consider making that variable final if you still need to store its value in advance (before method calls that might have side effects on the original value).18
Distance between variable 'c5' declaration and its first usage is 5, but allowed 3. Consider making that variable final if you still need to store its value in advance (before method calls that might have side effects on the original value).19
Distance between variable 'c6' declaration and its first usage is 6, but allowed 3. Consider making that variable final if you still need to store its value in advance (before method calls that might have side effects on the original value).20
Distance between variable 'c7' declaration and its first usage is 7, but allowed 3. Consider making that variable final if you still need to store its value in advance (before method calls that might have side effects on the original value).21
Distance between variable 'c8' declaration and its first usage is 8, but allowed 3. Consider making that variable final if you still need to store its value in advance (before method calls that might have side effects on the original value).22
Distance between variable 'c9' declaration and its first usage is 9, but allowed 3. Consider making that variable final if you still need to store its value in advance (before method calls that might have side effects on the original value).23
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\task\DeadlineTest.java

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Error DescriptionLine
Using the '.*' form of import should be avoided - org.junit.jupiter.api.Assertions.*.6
Line is longer than 120 characters (found 163).16
Unicode escape(s) usage should be avoided.16
'(' is followed by whitespace.16
Line is longer than 120 characters (found 173).24
'(' is followed by whitespace.24
Line is longer than 120 characters (found 145).50
Unicode escape(s) usage should be avoided.50
'(' is followed by whitespace.50
Line is longer than 120 characters (found 134).51
'(' is followed by whitespace.51
Line is longer than 120 characters (found 146).56
Unicode escape(s) usage should be avoided.56
Line is longer than 120 characters (found 126).57
'(' is followed by whitespace.57
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\task\EventTest.java

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Error DescriptionLine
Using the '.*' form of import should be avoided - org.junit.jupiter.api.Assertions.*.7
Method name 'EventStringTest' must match pattern '^[a-z][a-z0-9][a-zA-Z0-9_]*$'.15
Line is longer than 120 characters (found 168).16
Unicode escape(s) usage should be avoided.16
Line is longer than 120 characters (found 154).24
'(' is followed by whitespace.24
Line is longer than 120 characters (found 139).50
Unicode escape(s) usage should be avoided.50
'(' is followed by whitespace.50
Line is longer than 120 characters (found 128).51
'(' is followed by whitespace.51
Line is longer than 120 characters (found 137).56
Unicode escape(s) usage should be avoided.56
Line is longer than 120 characters (found 128).57
'(' is followed by whitespace.57
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\task\PeriodTaskTest.java

+ + + + + + + + + + + + + + + + + + + + + + +
Error DescriptionLine
Using the '.*' form of import should be avoided - org.junit.jupiter.api.Assertions.*.6
Method name 'PeriodTaskStringTest' must match pattern '^[a-z][a-z0-9][a-zA-Z0-9_]*$'.14
Line is longer than 120 characters (found 229).15
Unicode escape(s) usage should be avoided.15
Line is longer than 120 characters (found 208).23
'(' is followed by whitespace.23
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\task\TodoTest.java

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Error DescriptionLine
Using the '.*' form of import should be avoided - org.junit.jupiter.api.Assertions.*.6
WhitespaceAround: '{' is not preceded with whitespace.15
Unicode escape(s) usage should be avoided.16
Line is longer than 120 characters (found 124).24
'(' is followed by whitespace.24
Unicode escape(s) usage should be avoided.50
'(' is followed by whitespace.50
'(' is followed by whitespace.51
Unicode escape(s) usage should be avoided.56
'(' is followed by whitespace.57
+ Back to top +
+ + diff --git a/build/reports/checkstyle/test.xml b/build/reports/checkstyle/test.xml new file mode 100644 index 0000000000..ebc36f73b5 --- /dev/null +++ b/build/reports/checkstyle/test.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/duke.txt b/data/duke.txt index 2818dabc8c..1a758c99f6 100644 --- a/data/duke.txt +++ b/data/duke.txt @@ -7,3 +7,6 @@ D | 0 | abc | 17/09/2019 2130 | false E | 0 | werq | 17/09/2019 1500 | false T | 0 | homework | false E | 0 | abc | 06/06/2016 1530 | false +P | 0 | abc | 27/08/2019 1630 | 29/11/2020 1630 +P | 0 | abc | 27/08/2019 1630 | 29/11/2020 1630 +P | 0 | abc | 27/08/2019 1630 | 29/11/2020 1630 From 9ed1d957f0b3be9f745bf063c8aa1878baac1aab Mon Sep 17 00:00:00 2001 From: Qian Jie Date: Tue, 17 Sep 2019 16:38:39 +0800 Subject: [PATCH 049/420] Added AboutUs without WEIFENG photos --- docs/AboutUs.adoc | 57 +++++++++++++++++++++++++++++++++++ docs/images/HUANGXUANKUN.png | Bin 0 -> 26279 bytes docs/images/kkeejjuunn.png | Bin 0 -> 193718 bytes docs/images/lmtaek.png | Bin 0 -> 24310 bytes 4 files changed, 57 insertions(+) create mode 100644 docs/AboutUs.adoc create mode 100644 docs/images/HUANGXUANKUN.png create mode 100644 docs/images/kkeejjuunn.png create mode 100644 docs/images/lmtaek.png diff --git a/docs/AboutUs.adoc b/docs/AboutUs.adoc new file mode 100644 index 0000000000..410449ebd8 --- /dev/null +++ b/docs/AboutUs.adoc @@ -0,0 +1,57 @@ += About Us +:site-section: AboutUs +:relfileprefix: team/ +:imagesDir: images +:stylesDir: stylesheets + +Dukepital - developed by the https://github.com/AY1920S1-CS2113-T13-2/main[CS2113-T13-2] team. + +_{The dummy content given below serves as a placeholder to be used by future forks of the project.}_ + +{empty} + +We are a team based in the http://www.comp.nus.edu.sg[School of Computing, National University of Singapore]. + +== Project Team + +=== QIAN JIE +image::qjie7.png[width="150", align="left"] +{empty}[http://github.com/qjie7[github]] [<>] + +Role: Team Lead + +Responsibilities: UI + +''' + +=== TAEKMAN LAUREN MARIE +image::lmtaek.png[width="150", align="left"] +{empty}[https://github.com/lmtaek[github]] [<>] + +Role: Developer + +Responsibilities: Data + +''' + +=== LIU KEJUN +image::kkeejjuunn.png[width="150", align="left"] +{empty}[https://github.com/kkeejjuunn[github]] [<>] + +Role: Developer + +Responsibilities: Dev Ops + Threading + +''' + +=== HUANG XUANKUN +image::HUANGXUANKUN.png[width="150", align="left"] +{empty}[https://github.com/HUANGXUANKUN[github]] [<>] + +Role: Developer + +Responsibilities: UI + +''' + +=== WEI FENG +image::qjie7.png[width="150", align="left"] +{empty}[https://github.com/WEIFENG-NUSCEG[github]] [<>] + +Role: Developer + +Responsibilities: UI + +''' \ No newline at end of file diff --git a/docs/images/HUANGXUANKUN.png b/docs/images/HUANGXUANKUN.png new file mode 100644 index 0000000000000000000000000000000000000000..7b13926e3182ff3a25818f520566262bcb0d149a GIT binary patch literal 26279 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 DWe~i1 literal 0 HcmV?d00001 diff --git a/docs/images/kkeejjuunn.png b/docs/images/kkeejjuunn.png new file mode 100644 index 0000000000000000000000000000000000000000..13c90623bee0f797cc8016536dadccb8823428d0 GIT binary patch literal 193718 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 z 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 z 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

cS-IO_^*}Afk|Im)--iNm18Jn2uuet6ilN}WO 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 literal 0 HcmV?d00001 From f636a486863024f0be3e25fd65e3d1aadcde5bc0 Mon Sep 17 00:00:00 2001 From: lmtaek Date: Tue, 17 Sep 2019 18:10:24 +0800 Subject: [PATCH 051/420] Reformatting RecurringTask to mainly be located in a separate class, with some changes to the Task class itself. Data structure has changed for data.txt to specify the frequency of the recurring task when reading/saving information. --- data/duke.txt | 22 +++-- .../java/duke/command/RecurringCommand.java | 15 ++-- src/main/java/duke/core/Parser.java | 20 +++-- src/main/java/duke/core/Storage.java | 4 +- src/main/java/duke/core/Ui.java | 2 +- src/main/java/duke/task/Deadline.java | 6 +- src/main/java/duke/task/Event.java | 6 +- src/main/java/duke/task/RecurringTask.java | 86 +++++++++++++++++++ src/main/java/duke/task/Task.java | 65 +++++--------- src/main/java/duke/task/Todo.java | 6 +- src/test/java/duke/task/RecurringTest.java | 54 ++++++++++++ 11 files changed, 211 insertions(+), 75 deletions(-) create mode 100644 src/main/java/duke/task/RecurringTask.java create mode 100644 src/test/java/duke/task/RecurringTest.java diff --git a/data/duke.txt b/data/duke.txt index 02ebc979f7..4310aa12ea 100644 --- a/data/duke.txt +++ b/data/duke.txt @@ -1,12 +1,10 @@ -D | 1 | ssss | 16/09/2019 0200 | false -D | 1 | tttt | 16/09/2019 0500 | false -E | 1 | tasktest | 16/09/2019 1000 | false -D | 1 | read book | 27/09/2019 1800 | false -D | 1 | watch movie | 27/09/2019 1800 | false -D | 1 | adding | 27/09/2019 1900 | false -D | 1 | hello | 27/09/2019 2000 | false -D | 1 | readbook | 27/09/2019 2300 | false -D | 0 | watch tv | 27/09/2019 1700 | false -D | 0 | hello | 27/09/2019 1800 | false -P | 0 | abc | 27/07/1996 1530 | 27/07/2020 1530 -P | 0 | abc | 27/07/1996 1530 | 27/07/2020 1530 \ No newline at end of file +D | 1 | ssss | 16/09/2019 0200 | ONCE +D | 0 | tttt | 16/09/2019 0500 | DAILY +E | 0 | tasktest | 16/09/2019 1000 | DAILY +D | 1 | read book | 27/09/2019 1800 | DAILY +D | 1 | watch movie | 27/09/2019 1800 | ONCE +D | 1 | adding | 27/09/2019 1900 | DAILY +D | 0 | hello | 05/09/2019 2000 | DAILY +D | 1 | readbook | 27/09/2019 2300 | DAILY +D | 1 | watch tv | 27/09/2019 1700 | DAILY +D | 0 | hello | 27/09/2019 1800 | DAILY diff --git a/src/main/java/duke/command/RecurringCommand.java b/src/main/java/duke/command/RecurringCommand.java index e1ff42129b..0a6d3cd472 100644 --- a/src/main/java/duke/command/RecurringCommand.java +++ b/src/main/java/duke/command/RecurringCommand.java @@ -45,16 +45,15 @@ public RecurringCommand(int taskIndex, Task.RecurringFrequency frequency) { @Override public void execute(TaskList tasks, Ui ui, Storage storage) throws DukeException { try { - Task recurringTask = tasks.getTask(taskIndex); - if (recurringTask.getDateTime() != null) { - if (!recurringTask.isTaskRecurring()) { - recurringTask.makeTaskRecurring(this.frequency); - ui.makeRecurring(recurringTask); + Task task = tasks.getTask(taskIndex); + if (task.getDateTime() != null) { + if (!task.isTaskRecurring()) { + task.makeTaskRecurring(this.frequency); + ui.makeRecurring(task); + } else { + System.out.println("This task is already marked as recurring!"); } - recurringTask.recurringTaskTimeUpdate(); storage.save(tasks.fullTaskList()); - } else { - recurringTask.updateLocalDateTime(LocalDateTime.now().toString()); } } catch (DukeException e) { throw new DukeException("I couldn't make the task recurring. " + e); diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index 035ac7bf5b..7168010521 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -95,12 +95,20 @@ public static Command parse(String ss) throws DukeException { } case "recurring": try { - int index = Integer.parseInt(command[1]); - if (ss.toLowerCase().contains("weekly")) { return new RecurringCommand(index, Task.RecurringFrequency.WEEKLY); } - else if (ss.toLowerCase().contains("monthly")) { return new RecurringCommand(index, Task.RecurringFrequency.MONTHLY); } - else if (ss.toLowerCase().contains("daily")) { return new RecurringCommand(index, Task.RecurringFrequency.DAILY);} - else { return new RecurringCommand(index, Task.RecurringFrequency.DAILY);} - + String[] parsedInput = command[1].split(" /"); + int index = Integer.parseInt(parsedInput[0]); + if (parsedInput[1] != null) { + parsedInput[1] = parsedInput[1].trim(); + if (parsedInput[1].toLowerCase().contains("weekly")) { + return new RecurringCommand(index, Task.RecurringFrequency.WEEKLY); + } else if (parsedInput[1].toLowerCase().contains("monthly")) { + return new RecurringCommand(index, Task.RecurringFrequency.MONTHLY); + } else if (parsedInput[1].toLowerCase().contains("daily")) { + return new RecurringCommand(index, Task.RecurringFrequency.DAILY); + } else { + return new RecurringCommand(index, Task.RecurringFrequency.DAILY); + } + } } catch (Exception e) { throw new DukeException("Failed to make your task recurring." + e.getMessage()); } diff --git a/src/main/java/duke/core/Storage.java b/src/main/java/duke/core/Storage.java index 7bec034550..a6911c7b4e 100644 --- a/src/main/java/duke/core/Storage.java +++ b/src/main/java/duke/core/Storage.java @@ -108,14 +108,12 @@ public void save(ArrayList task) throws DukeException { private Task.RecurringFrequency giveFrequency(String string) { switch (string) { - case "DAILY": - return Task.RecurringFrequency.DAILY; case "WEEKLY": return Task.RecurringFrequency.WEEKLY; case "MONTHLY": return Task.RecurringFrequency.MONTHLY; default: - return Task.RecurringFrequency.ONCE; + return Task.RecurringFrequency.DAILY; } } diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index 0b8bc681c7..229520dae9 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -193,7 +193,7 @@ public void showWelcome() { + "| |_| | |_| | < __/\n" + "|____/ \\__,_|_|\\_\\___|\n"; System.out.println("Hello from\n" + logo); - System.out.println("Hello! I'm Duke\nWhat can I do for you?"); + System.out.println("Hello! I'm Duke\nWhat can I do for you?\n"); } /** diff --git a/src/main/java/duke/task/Deadline.java b/src/main/java/duke/task/Deadline.java index bdb758064a..21e737563c 100644 --- a/src/main/java/duke/task/Deadline.java +++ b/src/main/java/duke/task/Deadline.java @@ -45,6 +45,10 @@ public String toString() { * @return A string in a specific format to be stored in a local file. */ public String writeTxt() { + String frequency = "ONCE"; + if (isTaskRecurring()) { + frequency = recurringTask.writeTxt(); + } return "D | " + (this.isDone ? "1" : "0") + " | " @@ -52,7 +56,7 @@ public String writeTxt() { + " | " + this.by + " | " - + this.frequency; + + frequency; } } \ No newline at end of file diff --git a/src/main/java/duke/task/Event.java b/src/main/java/duke/task/Event.java index 82e23cbc89..53d1178d05 100644 --- a/src/main/java/duke/task/Event.java +++ b/src/main/java/duke/task/Event.java @@ -41,6 +41,10 @@ public String toString() { * @return A string in a specific format to be stored in a local file. */ public String writeTxt() { + String frequency = "ONCE"; + if (isTaskRecurring()) { + frequency = recurringTask.writeTxt(); + } return "E | " + (this.isDone ? "1" : "0") + " | " @@ -48,6 +52,6 @@ public String writeTxt() { + " | " + this.at + " | " - + this.frequency; + + frequency; } } \ No newline at end of file diff --git a/src/main/java/duke/task/RecurringTask.java b/src/main/java/duke/task/RecurringTask.java new file mode 100644 index 0000000000..639b8c51c7 --- /dev/null +++ b/src/main/java/duke/task/RecurringTask.java @@ -0,0 +1,86 @@ +package duke.task; + +import java.time.Duration; +import java.time.LocalDateTime; +import java.time.format.DateTimeParseException; + +public class RecurringTask extends Task { + + public enum RecurringFrequency { DAILY, WEEKLY, MONTHLY}; + public enum TaskType { TODO, DEADLINE, EVENT} + + private Task task; + private RecurringFrequency frequency; + private TaskType taskType; + + public RecurringTask(Task task, RecurringFrequency frequency) { + super(task.description); + this.task = task; + if (task instanceof Todo) { this.taskType = TaskType.TODO; } + if (task instanceof Deadline) { this.taskType = TaskType.DEADLINE; } + if (task instanceof Event) { this.taskType = TaskType.EVENT; } + + this.frequency = frequency; + } + + public Task getTask() { return task; } + + public RecurringFrequency getFrequency() { return frequency; } + + /** + * When a task is recurring, method compares current time to listed date. + * If the task's date is outdated, then it will update to be for the next day. + */ + public void recurringTaskTimeUpdate() { + if (task.getDateTime() != null) { + try { + LocalDateTime currentTime = LocalDateTime.now(); + if (task.getDateTime().isBefore(currentTime)) { + + switch (this.frequency) { + case DAILY: + Duration dayDifference = Duration.between(currentTime, task.getDateTime()); + int totalDaysDifference = (int) Math.abs(dayDifference.toDays()); + if (totalDaysDifference > 0 ) { + task.updateLocalDateTime(task.getDateTime().plusDays(totalDaysDifference).toString()); + if (task.isDone) { task.isDone = false; } + } + case WEEKLY: + Duration weekDifference = Duration.between(currentTime, task.getDateTime()); + int totalWeeksDifference = (int) Math.abs(weekDifference.toDays()/7); + if (totalWeeksDifference > 0) { + task.updateLocalDateTime(task.getDateTime().plusWeeks(totalWeeksDifference).toString()); + } + if (task.isDone) { task.isDone = false; } + case MONTHLY: + Duration monthDifference = Duration.between(currentTime, task.getDateTime()); + long totalMonthsDifference = (int) Math.abs(monthDifference.toDays()/30); + if (totalMonthsDifference > 0) { + task.updateLocalDateTime(task.getDateTime().plusMonths(totalMonthsDifference).toString()); + } + if (task.isDone) { task.isDone = false; } + } + } + } catch (DateTimeParseException e) { + System.out.println("I couldn't update your recurring events' times."); + } + } + } + + public LocalDateTime getUpdatedTime() { + return ld; + } + + @Override + public String writeTxt() { + switch (frequency) { + case DAILY: + return "DAILY"; + case WEEKLY: + return "WEEKLY"; + case MONTHLY: + return "MONTHLY"; + } + return "ONCE"; + } +} diff --git a/src/main/java/duke/task/Task.java b/src/main/java/duke/task/Task.java index 20c6b161be..9201219a24 100644 --- a/src/main/java/duke/task/Task.java +++ b/src/main/java/duke/task/Task.java @@ -39,11 +39,14 @@ public abstract class Task { protected boolean isRecurring = false; /** - * Enumerators meant to specify how frequently a task should appear. - * Default enumerator is 'ONCE'. + * An enumerator meant to specify the frequency of a recurring task. */ - public enum RecurringFrequency { DAILY, WEEKLY, MONTHLY, ONCE } - protected RecurringFrequency frequency = RecurringFrequency.ONCE; + public enum RecurringFrequency { DAILY, WEEKLY, MONTHLY; } + + /** + * An extended class that retains information about a recurring task. + */ + protected RecurringTask recurringTask; /** * Initialises the minimum fields required to setup a Task. @@ -92,7 +95,19 @@ public void markAsDone() { */ public void makeTaskRecurring(RecurringFrequency frequency) { isRecurring = true; - this.frequency = frequency; + switch (frequency) { + case DAILY: + this.recurringTask = new RecurringTask(this, RecurringTask.RecurringFrequency.DAILY); + case WEEKLY: + this.recurringTask = new RecurringTask(this, RecurringTask.RecurringFrequency.WEEKLY); + case MONTHLY: + this.recurringTask = new RecurringTask(this, RecurringTask.RecurringFrequency.MONTHLY); + default: + this.recurringTask = new RecurringTask(this, RecurringTask.RecurringFrequency.DAILY); + } + if (this.recurringTask != null) { + this.recurringTask.recurringTaskTimeUpdate(); + } } /** @@ -100,42 +115,6 @@ public void makeTaskRecurring(RecurringFrequency frequency) { */ public boolean isTaskRecurring() { return isRecurring; } - /** - * When a task is recurring, method compares current time to listed date. - * If the task's date is outdated, then it will update to be for the next day. - */ - public void recurringTaskTimeUpdate() { - if ((ld != null) && this.isRecurring) { - try { - LocalDateTime currentTime = LocalDateTime.now(); - if (this.ld.isBefore(currentTime)) { - switch (this.frequency) { - case DAILY: - Duration dayDifference = Duration.between(currentTime, this.ld); - if (Math.abs(dayDifference.toDays()) > 0 ) { - this.ld = ld.plusDays(Math.abs(dayDifference.toDays())); - if (this.isDone) { this.isDone = false; } - } - case WEEKLY: - while (this.ld.isBefore(currentTime)) { - this.ld = ld.plusWeeks(1); - } - if (this.isDone) { this.isDone = false; } - case MONTHLY: - while (this.ld.isBefore(currentTime)) { - this.ld = ld.plusMonths(1); - } - if (this.isDone) { this.isDone = false; } - default: - System.out.println("I couldn't update your recurring events' times."); - } - } - } catch (DateTimeParseException e) { - System.out.println("I couldn't update your recurring events' times."); - } - } - } - /** * Returns a string with the status icon and the description of the task. * @@ -204,7 +183,9 @@ public void updateLocalDateTime(String time){ */ public LocalDateTime getDateTime() { - if (this.isTaskRecurring()) { this.recurringTaskTimeUpdate(); } + if (recurringTask != null) { + this.ld = recurringTask.getUpdatedTime(); + } return ld; } diff --git a/src/main/java/duke/task/Todo.java b/src/main/java/duke/task/Todo.java index 1750e0fd49..99adfb5aa2 100644 --- a/src/main/java/duke/task/Todo.java +++ b/src/main/java/duke/task/Todo.java @@ -32,12 +32,16 @@ public String toString() { * @return A string in a specific format to be stored in a local file. */ public String writeTxt() { + String frequency = "ONCE"; + if (isTaskRecurring()) { + frequency = recurringTask.writeTxt(); + } return "T | " + (this.isDone() ? "1" : "0") + " | " + this.description + " | " - + this.frequency; + + frequency; } } \ No newline at end of file diff --git a/src/test/java/duke/task/RecurringTest.java b/src/test/java/duke/task/RecurringTest.java new file mode 100644 index 0000000000..9ff1f7376c --- /dev/null +++ b/src/test/java/duke/task/RecurringTest.java @@ -0,0 +1,54 @@ +package duke.task; +import duke.command.RecurringCommand; +import duke.task.*; +import org.junit.jupiter.api.Test; + +import java.time.Duration; +import java.time.LocalDateTime; +import static org.junit.jupiter.api.Assertions.*; + +public class RecurringTest { + + private Task dummyToDo = new Todo("essay"); + private Task dummyDeadline = new Deadline("paper", "03/08/2018 1159"); + private Task dummyEvent = new Event("presentation", "15/09/2019 1000"); + + + @Test + public void recurringDailyDeadlineTest() { + LocalDateTime oldDateTime = dummyDeadline.getDateTime(); + dummyDeadline.makeTaskRecurring(Task.RecurringFrequency.DAILY); + assert(dummyDeadline.getDateTime().isAfter(oldDateTime)); + + Duration dayDifference = Duration.between(LocalDateTime.now(), dummyDeadline.getDateTime()); + long numberOfDaysDifference = Math.abs(dayDifference.toDays()); + assert(numberOfDaysDifference <= 1); + } + + @Test + public void recurringWeeklyEventTest() { + LocalDateTime oldDateTime = dummyEvent.getDateTime(); + dummyEvent.makeTaskRecurring(Task.RecurringFrequency.WEEKLY); + assert(dummyEvent.getDateTime().isAfter(oldDateTime)); + + Duration dayDifference = Duration.between(LocalDateTime.now(), dummyEvent.getDateTime()); + long numberOfDaysDifference = Math.abs(dayDifference.toDays()); + assert(numberOfDaysDifference <= 7); + } + + @Test public void recurringMonthlyDeadlineTest() { + LocalDateTime oldDateTime = dummyDeadline.getDateTime(); + dummyDeadline.makeTaskRecurring(Task.RecurringFrequency.MONTHLY); + assert(dummyDeadline.getDateTime().isAfter(oldDateTime)); + + Duration dayDifference = Duration.between(LocalDateTime.now(), dummyDeadline.getDateTime()); + long numberOfDaysDifference = Math.abs(dayDifference.toDays()); + assert(numberOfDaysDifference <= 31); + } + + @Test public void recurringTodoTest() { + dummyToDo.makeTaskRecurring(Task.RecurringFrequency.DAILY); + assertNotEquals(true, dummyToDo.isTaskRecurring()); + } + +} From c433e7b90111898f6d09f2789698f5997a62503b Mon Sep 17 00:00:00 2001 From: lmtaek Date: Tue, 17 Sep 2019 18:39:18 +0800 Subject: [PATCH 052/420] Preventing infinite loop via using the .getDateTime() method between Task and RecurringTask classes; RecurringTask class acts now more like additional support, using past LocalDateTime in order to calculate new one to provide for Task class. --- src/main/java/duke/task/RecurringTask.java | 35 ++++++++++------------ src/main/java/duke/task/Task.java | 4 +-- 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/src/main/java/duke/task/RecurringTask.java b/src/main/java/duke/task/RecurringTask.java index 639b8c51c7..cb6e3b226c 100644 --- a/src/main/java/duke/task/RecurringTask.java +++ b/src/main/java/duke/task/RecurringTask.java @@ -4,59 +4,58 @@ import java.time.LocalDateTime; import java.time.format.DateTimeParseException; -public class RecurringTask extends Task { +public class RecurringTask { public enum RecurringFrequency { DAILY, WEEKLY, MONTHLY}; public enum TaskType { TODO, DEADLINE, EVENT} - private Task task; + private LocalDateTime lastRecordedTime; private RecurringFrequency frequency; private TaskType taskType; public RecurringTask(Task task, RecurringFrequency frequency) { - super(task.description); - this.task = task; if (task instanceof Todo) { this.taskType = TaskType.TODO; } if (task instanceof Deadline) { this.taskType = TaskType.DEADLINE; } if (task instanceof Event) { this.taskType = TaskType.EVENT; } + if (task.getDateTime() != null) { + lastRecordedTime = task.getDateTime(); + } this.frequency = frequency; } - public Task getTask() { return task; } - public RecurringFrequency getFrequency() { return frequency; } /** * When a task is recurring, method compares current time to listed date. * If the task's date is outdated, then it will update to be for the next day. */ - public void recurringTaskTimeUpdate() { - if (task.getDateTime() != null) { + public LocalDateTime recurringTaskTimeUpdate(Task task) { + if (lastRecordedTime != null) { try { LocalDateTime currentTime = LocalDateTime.now(); - if (task.getDateTime().isBefore(currentTime)) { + if (lastRecordedTime.isBefore(currentTime)) { switch (this.frequency) { case DAILY: - Duration dayDifference = Duration.between(currentTime, task.getDateTime()); + Duration dayDifference = Duration.between(currentTime, lastRecordedTime); int totalDaysDifference = (int) Math.abs(dayDifference.toDays()); if (totalDaysDifference > 0 ) { - task.updateLocalDateTime(task.getDateTime().plusDays(totalDaysDifference).toString()); + lastRecordedTime = lastRecordedTime.plusDays(totalDaysDifference); if (task.isDone) { task.isDone = false; } } case WEEKLY: - Duration weekDifference = Duration.between(currentTime, task.getDateTime()); + Duration weekDifference = Duration.between(currentTime, lastRecordedTime); int totalWeeksDifference = (int) Math.abs(weekDifference.toDays()/7); if (totalWeeksDifference > 0) { - task.updateLocalDateTime(task.getDateTime().plusWeeks(totalWeeksDifference).toString()); + lastRecordedTime = lastRecordedTime.plusWeeks(totalWeeksDifference); } if (task.isDone) { task.isDone = false; } case MONTHLY: - Duration monthDifference = Duration.between(currentTime, task.getDateTime()); + Duration monthDifference = Duration.between(currentTime, lastRecordedTime); long totalMonthsDifference = (int) Math.abs(monthDifference.toDays()/30); if (totalMonthsDifference > 0) { - task.updateLocalDateTime(task.getDateTime().plusMonths(totalMonthsDifference).toString()); + lastRecordedTime = lastRecordedTime.plusMonths(totalMonthsDifference); } if (task.isDone) { task.isDone = false; } } @@ -65,13 +64,9 @@ public void recurringTaskTimeUpdate() { System.out.println("I couldn't update your recurring events' times."); } } + return lastRecordedTime; } - public LocalDateTime getUpdatedTime() { - return ld; - } - - @Override public String writeTxt() { switch (frequency) { case DAILY: diff --git a/src/main/java/duke/task/Task.java b/src/main/java/duke/task/Task.java index 9201219a24..0436f31436 100644 --- a/src/main/java/duke/task/Task.java +++ b/src/main/java/duke/task/Task.java @@ -106,7 +106,7 @@ public void makeTaskRecurring(RecurringFrequency frequency) { this.recurringTask = new RecurringTask(this, RecurringTask.RecurringFrequency.DAILY); } if (this.recurringTask != null) { - this.recurringTask.recurringTaskTimeUpdate(); + this.recurringTask.recurringTaskTimeUpdate(this); } } @@ -184,7 +184,7 @@ public void updateLocalDateTime(String time){ public LocalDateTime getDateTime() { if (recurringTask != null) { - this.ld = recurringTask.getUpdatedTime(); + this.ld = recurringTask.recurringTaskTimeUpdate(this); } return ld; } From ff177f8fffd0fdccd2bb9d998b5f1ecf0e86ae08 Mon Sep 17 00:00:00 2001 From: lmtaek Date: Tue, 17 Sep 2019 18:40:47 +0800 Subject: [PATCH 053/420] New files for supporting Duke; mainly stylistic files. --- .../test/classes/duke.task.RecurringTest.html | 219 ++++++++++++++++++ build/reports/tests/test/css/base-style.css | 179 ++++++++++++++ build/reports/tests/test/css/style.css | 84 +++++++ build/reports/tests/test/index.html | 145 ++++++++++++ build/reports/tests/test/js/report.js | 194 ++++++++++++++++ .../tests/test/packages/duke.task.html | 115 +++++++++ .../test/TEST-duke.task.RecurringTest.xml | 107 +++++++++ build/test-results/test/binary/output.bin | 0 build/test-results/test/binary/output.bin.idx | Bin 0 -> 1 bytes build/test-results/test/binary/results.bin | Bin 0 -> 10097 bytes 10 files changed, 1043 insertions(+) create mode 100644 build/reports/tests/test/classes/duke.task.RecurringTest.html create mode 100644 build/reports/tests/test/css/base-style.css create mode 100644 build/reports/tests/test/css/style.css create mode 100644 build/reports/tests/test/index.html create mode 100644 build/reports/tests/test/js/report.js create mode 100644 build/reports/tests/test/packages/duke.task.html create mode 100644 build/test-results/test/TEST-duke.task.RecurringTest.xml create mode 100644 build/test-results/test/binary/output.bin create mode 100644 build/test-results/test/binary/output.bin.idx create mode 100644 build/test-results/test/binary/results.bin diff --git a/build/reports/tests/test/classes/duke.task.RecurringTest.html b/build/reports/tests/test/classes/duke.task.RecurringTest.html new file mode 100644 index 0000000000..fcb2112179 --- /dev/null +++ b/build/reports/tests/test/classes/duke.task.RecurringTest.html @@ -0,0 +1,219 @@ + + + + + +Test results - RecurringTest + + + + + +

+

RecurringTest

+
+
+ + + + + +
+
+ + + + + + + +
+
+
4
+

tests

+
+
+
+
1
+

failures

+
+
+
+
0
+

ignored

+
+
+
+
0.087s
+

duration

+
+
+
+
+
+
75%
+

successful

+
+
+
+
+ +
+

Failed tests

+
+ +

recurringTodoTest()

+ +
org.opentest4j.AssertionFailedError: expected: not equal but was: <true>
+	at org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:39)
+	at org.junit.jupiter.api.AssertNotEquals.failEqual(AssertNotEquals.java:276)
+	at org.junit.jupiter.api.AssertNotEquals.assertNotEquals(AssertNotEquals.java:265)
+	at org.junit.jupiter.api.AssertNotEquals.assertNotEquals(AssertNotEquals.java:260)
+	at org.junit.jupiter.api.Assertions.assertNotEquals(Assertions.java:2743)
+	at duke.task.RecurringTest.recurringTodoTest(RecurringTest.java:51)
+	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
+	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
+	at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:675)
+	at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
+	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:125)
+	at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:132)
+	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:124)
+	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:74)
+	at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
+	at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
+	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:104)
+	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:62)
+	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:43)
+	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:35)
+	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
+	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
+	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:202)
+	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
+	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:198)
+	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135)
+	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:69)
+	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
+	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
+	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
+	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
+	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
+	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
+	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
+	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
+	at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
+	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
+	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
+	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
+	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
+	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
+	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
+	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
+	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
+	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
+	at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
+	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
+	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
+	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
+	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
+	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
+	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
+	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
+	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
+	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
+	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
+	at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
+	at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
+	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:220)
+	at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:188)
+	at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:202)
+	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:181)
+	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128)
+	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:102)
+	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:82)
+	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:78)
+	at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:61)
+	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
+	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
+	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
+	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
+	at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
+	at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
+	at com.sun.proxy.$Proxy2.stop(Unknown Source)
+	at org.gradle.api.internal.tasks.testing.worker.TestWorker.stop(TestWorker.java:132)
+	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
+	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
+	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
+	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
+	at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:175)
+	at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:157)
+	at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:404)
+	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
+	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
+	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
+	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
+	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
+	at java.base/java.lang.Thread.run(Thread.java:834)
+
+
+
+
+
+

Tests

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TestDurationResult
recurringDailyDeadlineTest()0.066spassed
recurringMonthlyDeadlineTest()0.002spassed
recurringTodoTest()0.013sfailed
recurringWeeklyEventTest()0.006spassed
+
+
+ +
+ + diff --git a/build/reports/tests/test/css/base-style.css b/build/reports/tests/test/css/base-style.css new file mode 100644 index 0000000000..4afa73e3dd --- /dev/null +++ b/build/reports/tests/test/css/base-style.css @@ -0,0 +1,179 @@ + +body { + margin: 0; + padding: 0; + font-family: sans-serif; + font-size: 12pt; +} + +body, a, a:visited { + color: #303030; +} + +#content { + padding-left: 50px; + padding-right: 50px; + padding-top: 30px; + padding-bottom: 30px; +} + +#content h1 { + font-size: 160%; + margin-bottom: 10px; +} + +#footer { + margin-top: 100px; + font-size: 80%; + white-space: nowrap; +} + +#footer, #footer a { + color: #a0a0a0; +} + +#line-wrapping-toggle { + vertical-align: middle; +} + +#label-for-line-wrapping-toggle { + vertical-align: middle; +} + +ul { + margin-left: 0; +} + +h1, h2, h3 { + white-space: nowrap; +} + +h2 { + font-size: 120%; +} + +ul.tabLinks { + padding-left: 0; + padding-top: 10px; + padding-bottom: 10px; + overflow: auto; + min-width: 800px; + width: auto !important; + width: 800px; +} + +ul.tabLinks li { + float: left; + height: 100%; + list-style: none; + padding-left: 10px; + padding-right: 10px; + padding-top: 5px; + padding-bottom: 5px; + margin-bottom: 0; + -moz-border-radius: 7px; + border-radius: 7px; + margin-right: 25px; + border: solid 1px #d4d4d4; + background-color: #f0f0f0; +} + +ul.tabLinks li:hover { + background-color: #fafafa; +} + +ul.tabLinks li.selected { + background-color: #c5f0f5; + border-color: #c5f0f5; +} + +ul.tabLinks a { + font-size: 120%; + display: block; + outline: none; + text-decoration: none; + margin: 0; + padding: 0; +} + +ul.tabLinks li h2 { + margin: 0; + padding: 0; +} + +div.tab { +} + +div.selected { + display: block; +} + +div.deselected { + display: none; +} + +div.tab table { + min-width: 350px; + width: auto !important; + width: 350px; + border-collapse: collapse; +} + +div.tab th, div.tab table { + border-bottom: solid #d0d0d0 1px; +} + +div.tab th { + text-align: left; + white-space: nowrap; + padding-left: 6em; +} + +div.tab th:first-child { + padding-left: 0; +} + +div.tab td { + white-space: nowrap; + padding-left: 6em; + padding-top: 5px; + padding-bottom: 5px; +} + +div.tab td:first-child { + padding-left: 0; +} + +div.tab td.numeric, div.tab th.numeric { + text-align: right; +} + +span.code { + display: inline-block; + margin-top: 0em; + margin-bottom: 1em; +} + +span.code pre { + font-size: 11pt; + padding-top: 10px; + padding-bottom: 10px; + padding-left: 10px; + padding-right: 10px; + margin: 0; + background-color: #f7f7f7; + border: solid 1px #d0d0d0; + min-width: 700px; + width: auto !important; + width: 700px; +} + +span.wrapped pre { + word-wrap: break-word; + white-space: pre-wrap; + word-break: break-all; +} + +label.hidden { + display: none; +} \ No newline at end of file diff --git a/build/reports/tests/test/css/style.css b/build/reports/tests/test/css/style.css new file mode 100644 index 0000000000..3dc4913e7a --- /dev/null +++ b/build/reports/tests/test/css/style.css @@ -0,0 +1,84 @@ + +#summary { + margin-top: 30px; + margin-bottom: 40px; +} + +#summary table { + border-collapse: collapse; +} + +#summary td { + vertical-align: top; +} + +.breadcrumbs, .breadcrumbs a { + color: #606060; +} + +.infoBox { + width: 110px; + padding-top: 15px; + padding-bottom: 15px; + text-align: center; +} + +.infoBox p { + margin: 0; +} + +.counter, .percent { + font-size: 120%; + font-weight: bold; + margin-bottom: 8px; +} + +#duration { + width: 125px; +} + +#successRate, .summaryGroup { + border: solid 2px #d0d0d0; + -moz-border-radius: 10px; + border-radius: 10px; +} + +#successRate { + width: 140px; + margin-left: 35px; +} + +#successRate .percent { + font-size: 180%; +} + +.success, .success a { + color: #008000; +} + +div.success, #successRate.success { + background-color: #bbd9bb; + border-color: #008000; +} + +.failures, .failures a { + color: #b60808; +} + +.skipped, .skipped a { + color: #c09853; +} + +div.failures, #successRate.failures { + background-color: #ecdada; + border-color: #b60808; +} + +ul.linkList { + padding-left: 0; +} + +ul.linkList li { + list-style: none; + margin-bottom: 5px; +} diff --git a/build/reports/tests/test/index.html b/build/reports/tests/test/index.html new file mode 100644 index 0000000000..791c760733 --- /dev/null +++ b/build/reports/tests/test/index.html @@ -0,0 +1,145 @@ + + + + + +Test results - Test Summary + + + + + +
+

Test Summary

+
+ + + + + +
+
+ + + + + + + +
+
+
4
+

tests

+
+
+
+
1
+

failures

+
+
+
+
0
+

ignored

+
+
+
+
0.087s
+

duration

+
+
+
+
+
+
75%
+

successful

+
+
+
+
+ +
+

Failed tests

+ +
+
+

Packages

+ + + + + + + + + + + + + + + + + + + + + +
PackageTestsFailuresIgnoredDurationSuccess rate
+duke.task +4100.087s75%
+
+
+

Classes

+ + + + + + + + + + + + + + + + + + + + + +
ClassTestsFailuresIgnoredDurationSuccess rate
+duke.task.RecurringTest +4100.087s75%
+
+
+ +
+ + diff --git a/build/reports/tests/test/js/report.js b/build/reports/tests/test/js/report.js new file mode 100644 index 0000000000..83bab4a19f --- /dev/null +++ b/build/reports/tests/test/js/report.js @@ -0,0 +1,194 @@ +(function (window, document) { + "use strict"; + + var tabs = {}; + + function changeElementClass(element, classValue) { + if (element.getAttribute("className")) { + element.setAttribute("className", classValue); + } else { + element.setAttribute("class", classValue); + } + } + + function getClassAttribute(element) { + if (element.getAttribute("className")) { + return element.getAttribute("className"); + } else { + return element.getAttribute("class"); + } + } + + function addClass(element, classValue) { + changeElementClass(element, getClassAttribute(element) + " " + classValue); + } + + function removeClass(element, classValue) { + changeElementClass(element, getClassAttribute(element).replace(classValue, "")); + } + + function initTabs() { + var container = document.getElementById("tabs"); + + tabs.tabs = findTabs(container); + tabs.titles = findTitles(tabs.tabs); + tabs.headers = findHeaders(container); + tabs.select = select; + tabs.deselectAll = deselectAll; + tabs.select(0); + + return true; + } + + function getCheckBox() { + return document.getElementById("line-wrapping-toggle"); + } + + function getLabelForCheckBox() { + return document.getElementById("label-for-line-wrapping-toggle"); + } + + function findCodeBlocks() { + var spans = document.getElementById("tabs").getElementsByTagName("span"); + var codeBlocks = []; + for (var i = 0; i < spans.length; ++i) { + if (spans[i].className.indexOf("code") >= 0) { + codeBlocks.push(spans[i]); + } + } + return codeBlocks; + } + + function forAllCodeBlocks(operation) { + var codeBlocks = findCodeBlocks(); + + for (var i = 0; i < codeBlocks.length; ++i) { + operation(codeBlocks[i], "wrapped"); + } + } + + function toggleLineWrapping() { + var checkBox = getCheckBox(); + + if (checkBox.checked) { + forAllCodeBlocks(addClass); + } else { + forAllCodeBlocks(removeClass); + } + } + + function initControls() { + if (findCodeBlocks().length > 0) { + var checkBox = getCheckBox(); + var label = getLabelForCheckBox(); + + checkBox.onclick = toggleLineWrapping; + checkBox.checked = false; + + removeClass(label, "hidden"); + } + } + + function switchTab() { + var id = this.id.substr(1); + + for (var i = 0; i < tabs.tabs.length; i++) { + if (tabs.tabs[i].id === id) { + tabs.select(i); + break; + } + } + + return false; + } + + function select(i) { + this.deselectAll(); + + changeElementClass(this.tabs[i], "tab selected"); + changeElementClass(this.headers[i], "selected"); + + while (this.headers[i].firstChild) { + this.headers[i].removeChild(this.headers[i].firstChild); + } + + var h2 = document.createElement("H2"); + + h2.appendChild(document.createTextNode(this.titles[i])); + this.headers[i].appendChild(h2); + } + + function deselectAll() { + for (var i = 0; i < this.tabs.length; i++) { + changeElementClass(this.tabs[i], "tab deselected"); + changeElementClass(this.headers[i], "deselected"); + + while (this.headers[i].firstChild) { + this.headers[i].removeChild(this.headers[i].firstChild); + } + + var a = document.createElement("A"); + + a.setAttribute("id", "ltab" + i); + a.setAttribute("href", "#tab" + i); + a.onclick = switchTab; + a.appendChild(document.createTextNode(this.titles[i])); + + this.headers[i].appendChild(a); + } + } + + function findTabs(container) { + return findChildElements(container, "DIV", "tab"); + } + + function findHeaders(container) { + var owner = findChildElements(container, "UL", "tabLinks"); + return findChildElements(owner[0], "LI", null); + } + + function findTitles(tabs) { + var titles = []; + + for (var i = 0; i < tabs.length; i++) { + var tab = tabs[i]; + var header = findChildElements(tab, "H2", null)[0]; + + header.parentNode.removeChild(header); + + if (header.innerText) { + titles.push(header.innerText); + } else { + titles.push(header.textContent); + } + } + + return titles; + } + + function findChildElements(container, name, targetClass) { + var elements = []; + var children = container.childNodes; + + for (var i = 0; i < children.length; i++) { + var child = children.item(i); + + if (child.nodeType === 1 && child.nodeName === name) { + if (targetClass && child.className.indexOf(targetClass) < 0) { + continue; + } + + elements.push(child); + } + } + + return elements; + } + + // Entry point. + + window.onload = function() { + initTabs(); + initControls(); + }; +} (window, window.document)); \ No newline at end of file diff --git a/build/reports/tests/test/packages/duke.task.html b/build/reports/tests/test/packages/duke.task.html new file mode 100644 index 0000000000..d1ec2fa86e --- /dev/null +++ b/build/reports/tests/test/packages/duke.task.html @@ -0,0 +1,115 @@ + + + + + +Test results - Package duke.task + + + + + +
+

Package duke.task

+ +
+ + + + + +
+
+ + + + + + + +
+
+
4
+

tests

+
+
+
+
1
+

failures

+
+
+
+
0
+

ignored

+
+
+
+
0.087s
+

duration

+
+
+
+
+
+
75%
+

successful

+
+
+
+
+ +
+

Failed tests

+ +
+
+

Classes

+ + + + + + + + + + + + + + + + + + + +
ClassTestsFailuresIgnoredDurationSuccess rate
+RecurringTest +4100.087s75%
+
+
+ +
+ + diff --git a/build/test-results/test/TEST-duke.task.RecurringTest.xml b/build/test-results/test/TEST-duke.task.RecurringTest.xml new file mode 100644 index 0000000000..028ac03a61 --- /dev/null +++ b/build/test-results/test/TEST-duke.task.RecurringTest.xml @@ -0,0 +1,107 @@ + + + + + + + org.opentest4j.AssertionFailedError: expected: not equal but was: <true> + at org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:39) + at org.junit.jupiter.api.AssertNotEquals.failEqual(AssertNotEquals.java:276) + at org.junit.jupiter.api.AssertNotEquals.assertNotEquals(AssertNotEquals.java:265) + at org.junit.jupiter.api.AssertNotEquals.assertNotEquals(AssertNotEquals.java:260) + at org.junit.jupiter.api.Assertions.assertNotEquals(Assertions.java:2743) + at duke.task.RecurringTest.recurringTodoTest(RecurringTest.java:51) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:566) + at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:675) + at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60) + at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:125) + at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:132) + at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:124) + at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:74) + at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115) + at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105) + at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:104) + at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:62) + at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:43) + at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:35) + at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104) + at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98) + at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:202) + at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) + at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:198) + at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135) + at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:69) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135) + at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125) + at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123) + at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80) + at java.base/java.util.ArrayList.forEach(ArrayList.java:1540) + at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139) + at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125) + at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123) + at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80) + at java.base/java.util.ArrayList.forEach(ArrayList.java:1540) + at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139) + at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125) + at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123) + at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122) + at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80) + at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32) + at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) + at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51) + at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:220) + at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:188) + at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:202) + at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:181) + at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128) + at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:102) + at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:82) + at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:78) + at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:61) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:566) + at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35) + at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) + at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32) + at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93) + at com.sun.proxy.$Proxy2.stop(Unknown Source) + at org.gradle.api.internal.tasks.testing.worker.TestWorker.stop(TestWorker.java:132) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:566) + at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35) + at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) + at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:175) + at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:157) + at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:404) + at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63) + at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) + at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55) + at java.base/java.lang.Thread.run(Thread.java:834) + + + + + + diff --git a/build/test-results/test/binary/output.bin b/build/test-results/test/binary/output.bin new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test-results/test/binary/output.bin.idx b/build/test-results/test/binary/output.bin.idx new file mode 100644 index 0000000000000000000000000000000000000000..f76dd238ade08917e6712764a16a22005a50573d GIT binary patch literal 1 IcmZPo000310RR91 literal 0 HcmV?d00001 diff --git a/build/test-results/test/binary/results.bin b/build/test-results/test/binary/results.bin new file mode 100644 index 0000000000000000000000000000000000000000..57e302d182c2df42fa1f5630209304b5d106d32e GIT binary patch literal 10097 zcmeHNOK;mo5SEj)KnwKTs}4Lc7gmxjSuu(Lj;+8hlGKRp7(K4YwM2{Jvdg7y{eS{J z^;Dn*iXxZ(nE?G!oqduLpK_GA2VZQFyZg;!zZnj9_;~BlpI$P<4ny(Gd5hhIQa_xW z;h6olbk%BY&7c4K{@W*8e^Wi{5c$F45F;<}L(G@hPb&voFBHm8t;c^Elnab!!D4ic zLnbjQhFV`Lgt+zOcY|<7JR+AC-P`&`t@&l^A3`S%i9ix4yL092$1$eNC*e!51bZV& z3H`9uVA5V2-$vMF*xPG|gthU{2@2Zdgtc!_yx0Do(F8yL@W;lWzWxfaHrMMa34I2C zBcEaFpvX^cIA?wkJC|UIZS0cwuFy5w+kW=67Ud0LBW{U=5kD1HIwHV&yMuMmknpp? zD8U@`KLKW^9uxLIc8XOLL(1ZvZ3$HpE>50~Z*`z>aykO0-<2Tz!Wp9&e|P2093Kct zLlgkUWdO8t-XP{*R%jaVcS>*B^@ja=4)vkTUgaUGv7ZfVV%x*9OMRXa9iA;@1o2;o>41tcDJh+04eaz{Wr;AX*U2R@ z^Jr07EKZ_`Q07d1Oc8abz6+1_vneGvJp2zxz@P7+8x|=6+XX{1yQpfTlnYJlTs5%9 zyzWMvYb-1CzT`+P|C$)sOx7S*`Zn6NH^dWfHD~x9N49YjeIdID8F!tz9DjK*WMW_N~#2IPXPk;r@6 zojm6XZMs`(TH=A`+R{zIvY{$Z`GtCK;lD&3y-z7xyz=1{2WspQa;J8BM@B<`Cs*Az za`-8lV{kg0FdSvlDc|*xNS}nBVtVbnSiJ}A2Z7yujnHj7_dIE&*^-CK!>2em+$|m5 z6Z^`Id&mu&e#Ea&y@%ZJkQ+8tV6M-;huqM}XZMu3|4+FgeT`}4vE~o)I2q4Sb`J3+N&@yu z-_(`h>V1LQ>y?*t)v(J61Kzg_@w>zFqO2PK#%EJ==7YUc2DRfnE|yaDGG8sF(mCDX zC-Hf=m+{GjLeCA0_K&Yy2fTq7I}B=LIDMCWBEzm9&Y^2`q7K1%`Fs#SzvF}-Nb}Bu zrH&<_d^UqP9;p&ro|(n*@~B;dsb21~2PU6aYb4qxR;SZxrs^=05;m-<6EhMu(_(k6 zT|P~q4QRH^?5C7hHYh@P@X&|)tbHiOC=;!oA4iC}(@YcUP~XyHnI4oG6PuSkG1(|^ zwsBGld_W-O+{zU4iXabDqn**bVve*RA8dKo0H1Fc8hhVE5j09HeGN(O*!0$pPzd>u z>TY1sLYa@Ase>Qr13GacdUCf5#}W&AGHlMnSx9ce_9;oAwU$1x>vO^lq0rh9r_LAh zr-*wVpXyrJZaQK7>Y)dm?{Nz+>0U_2Nq6l5moiy5;Yg@icZR(m$5+r@hwJr?`&Ua1mxi-3`G9TBy41Q2h+8V0obbpC>|7;XW9^ip3nJy+}yUzW%vnbmU1a2p!WU%WS8_q>M3-*ok}x0>PBBlQW|udV+8 DzrCQ} literal 0 HcmV?d00001 From f067f892e0865adb1c1e11e6f5644068fedbc407 Mon Sep 17 00:00:00 2001 From: lmtaek Date: Tue, 17 Sep 2019 21:31:19 +0800 Subject: [PATCH 054/420] Wrapped up a few small issues with Storage saving information about Recurring Tasks. Cleaned up code in RecurringTask class to be more compact while accomplishing the same thing. --- data/duke.txt | 10 ++++--- src/main/java/duke/core/Storage.java | 4 ++- src/main/java/duke/task/Deadline.java | 2 +- src/main/java/duke/task/Event.java | 2 +- src/main/java/duke/task/RecurringTask.java | 32 +++++----------------- src/main/java/duke/task/Task.java | 9 ++++-- src/main/java/duke/task/Todo.java | 2 +- 7 files changed, 25 insertions(+), 36 deletions(-) diff --git a/data/duke.txt b/data/duke.txt index 96d60303a0..0a0e3316a6 100644 --- a/data/duke.txt +++ b/data/duke.txt @@ -1,13 +1,15 @@ E | 0 | fsahufias | 30/06/2020 0316 | ONCE -D | 0 | abc | 17/09/2019 0915 | DAILY +D | 0 | abc | 24/09/2019 0915 | DAILY P | 0 | abc | 27/07/1996 2130 | 27/06/2029 1630 -D | 0 | abc | 17/09/2019 1145 | DAILY +D | 0 | abc | 24/09/2019 1145 | DAILY T | 1 | abc | DAILY D | 0 | abc | 17/09/2019 2130 | ONCE E | 0 | werq | 17/09/2019 1500 | ONCE T | 0 | homework | ONCE -E | 0 | abc | 17/09/2019 1530 | DAILY +E | 0 | abc | 24/09/2019 1530 | DAILY P | 0 | abc | 27/08/2019 1630 | 29/11/2020 1630 P | 0 | abc | 27/08/2019 1630 | 29/11/2020 1630 P | 0 | abc | 27/08/2019 1630 | 29/11/2020 1630 -E | 0 | dog | 17/09/2019 0001 | DAILY +E | 1 | dog | 24/09/2019 0001 | MONTHLY +D | 0 | cat | 11/10/2019 0001 | DAILY +E | 0 | rabbit | 23/09/2019 0909 | WEEKLY diff --git a/src/main/java/duke/core/Storage.java b/src/main/java/duke/core/Storage.java index a395f8a87c..b8f5f4861d 100644 --- a/src/main/java/duke/core/Storage.java +++ b/src/main/java/duke/core/Storage.java @@ -114,12 +114,14 @@ public void save(ArrayList task) throws DukeException { private Task.RecurringFrequency giveFrequency(String string) { switch (string) { + case "DAILY": + return Task.RecurringFrequency.DAILY; case "WEEKLY": return Task.RecurringFrequency.WEEKLY; case "MONTHLY": return Task.RecurringFrequency.MONTHLY; default: - return Task.RecurringFrequency.DAILY; + return Task.RecurringFrequency.ONCE; } } diff --git a/src/main/java/duke/task/Deadline.java b/src/main/java/duke/task/Deadline.java index 4c32fb8545..dc9eff5372 100644 --- a/src/main/java/duke/task/Deadline.java +++ b/src/main/java/duke/task/Deadline.java @@ -66,7 +66,7 @@ public String toString() { public String writeTxt() { String frequency = "ONCE"; if (isTaskRecurring()) { - frequency = recurringTask.writeTxt(); + frequency = recurringTask.getFrequency().toString(); } return "D | " + (isDone() ? "1" : "0") diff --git a/src/main/java/duke/task/Event.java b/src/main/java/duke/task/Event.java index f3caf31489..32dee0c607 100644 --- a/src/main/java/duke/task/Event.java +++ b/src/main/java/duke/task/Event.java @@ -65,7 +65,7 @@ public String toString() { public String writeTxt() { String frequency = "ONCE"; if (isTaskRecurring()) { - frequency = recurringTask.writeTxt(); + frequency = recurringTask.getFrequency().toString(); } return "E | " + (isDone() ? "1" : "0") diff --git a/src/main/java/duke/task/RecurringTask.java b/src/main/java/duke/task/RecurringTask.java index 25f82e1a7c..0b6d2a092a 100644 --- a/src/main/java/duke/task/RecurringTask.java +++ b/src/main/java/duke/task/RecurringTask.java @@ -38,24 +38,18 @@ public LocalDateTime recurringTaskTimeUpdate(Task task) { switch (this.frequency) { case DAILY: - Duration dayDifference = Duration.between(currentTime, lastRecordedTime); - int totalDaysDifference = (int) Math.abs(dayDifference.toDays()); - if ((totalDaysDifference > 0 ) || task.isDone()) { - lastRecordedTime = lastRecordedTime.plusDays(totalDaysDifference); - if (task.isDone) { task.isDone = false; } + while (lastRecordedTime.isBefore(currentTime) || task.isDone()) { + lastRecordedTime = lastRecordedTime.plusDays(1); + if (task.isDone()) { task.isDone = false; } } case WEEKLY: - Duration weekDifference = Duration.between(currentTime, lastRecordedTime); - int totalWeeksDifference = (int) Math.abs(weekDifference.toDays()/7); - if ((totalWeeksDifference > 0) || task.isDone()) { - lastRecordedTime = lastRecordedTime.plusWeeks(totalWeeksDifference); + while (lastRecordedTime.isBefore(currentTime) || task.isDone()) { + lastRecordedTime = lastRecordedTime.plusWeeks(1); if (task.isDone) { task.isDone = false; } } case MONTHLY: - Duration monthDifference = Duration.between(currentTime, lastRecordedTime); - long totalMonthsDifference = (int) Math.abs(monthDifference.toDays()/30); - if ((totalMonthsDifference > 0) || task.isDone()) { - lastRecordedTime = lastRecordedTime.plusMonths(totalMonthsDifference); + while (lastRecordedTime.isBefore(currentTime) || task.isDone()) { + lastRecordedTime = lastRecordedTime.plusMonths(1); if (task.isDone) { task.isDone = false; } } } @@ -66,16 +60,4 @@ public LocalDateTime recurringTaskTimeUpdate(Task task) { } return lastRecordedTime; } - - public String writeTxt() { - switch (frequency) { - case DAILY: - return "DAILY"; - case WEEKLY: - return "WEEKLY"; - case MONTHLY: - return "MONTHLY"; - } - return "ONCE"; - } } diff --git a/src/main/java/duke/task/Task.java b/src/main/java/duke/task/Task.java index 8d76449213..02bdeea78f 100644 --- a/src/main/java/duke/task/Task.java +++ b/src/main/java/duke/task/Task.java @@ -42,7 +42,7 @@ public abstract class Task { /** * An enumerator meant to specify the frequency of a recurring task. */ - public enum RecurringFrequency { DAILY, WEEKLY, MONTHLY; } + public enum RecurringFrequency { DAILY, WEEKLY, MONTHLY, ONCE; } /** * An extended class that retains information about a recurring task. @@ -99,12 +99,15 @@ public void makeTaskRecurring(RecurringFrequency frequency) { switch (frequency) { case DAILY: this.recurringTask = new RecurringTask(this, RecurringTask.RecurringFrequency.DAILY); + break; case WEEKLY: this.recurringTask = new RecurringTask(this, RecurringTask.RecurringFrequency.WEEKLY); + break; case MONTHLY: this.recurringTask = new RecurringTask(this, RecurringTask.RecurringFrequency.MONTHLY); - default: - this.recurringTask = new RecurringTask(this, RecurringTask.RecurringFrequency.DAILY); + break; + case ONCE: + break; } if (this.recurringTask != null) { this.recurringTask.recurringTaskTimeUpdate(this); diff --git a/src/main/java/duke/task/Todo.java b/src/main/java/duke/task/Todo.java index 99adfb5aa2..ace6f025f6 100644 --- a/src/main/java/duke/task/Todo.java +++ b/src/main/java/duke/task/Todo.java @@ -34,7 +34,7 @@ public String toString() { public String writeTxt() { String frequency = "ONCE"; if (isTaskRecurring()) { - frequency = recurringTask.writeTxt(); + frequency = recurringTask.getFrequency().toString(); } return "T | " + (this.isDone() ? "1" : "0") From f241a283b39d2804b520623f366b463b213fa6ad Mon Sep 17 00:00:00 2001 From: lmtaek Date: Tue, 17 Sep 2019 21:45:00 +0800 Subject: [PATCH 055/420] Removed large amount of files to prevent conflicts with main team repo. --- build/reports/checkstyle/main.html | 958 ------------------ build/reports/checkstyle/main.xml | 258 ----- build/reports/checkstyle/test.html | 298 ------ build/reports/checkstyle/test.xml | 66 -- .../test/classes/duke.task.RecurringTest.html | 219 ---- build/reports/tests/test/css/base-style.css | 179 ---- build/reports/tests/test/css/style.css | 84 -- build/reports/tests/test/index.html | 145 --- build/reports/tests/test/js/report.js | 194 ---- .../tests/test/packages/duke.task.html | 115 --- .../test/TEST-duke.task.RecurringTest.xml | 107 -- build/test-results/test/binary/output.bin | 0 build/test-results/test/binary/output.bin.idx | Bin 1 -> 0 bytes build/test-results/test/binary/results.bin | Bin 10097 -> 0 bytes 14 files changed, 2623 deletions(-) delete mode 100644 build/reports/checkstyle/main.html delete mode 100644 build/reports/checkstyle/main.xml delete mode 100644 build/reports/checkstyle/test.html delete mode 100644 build/reports/checkstyle/test.xml delete mode 100644 build/reports/tests/test/classes/duke.task.RecurringTest.html delete mode 100644 build/reports/tests/test/css/base-style.css delete mode 100644 build/reports/tests/test/css/style.css delete mode 100644 build/reports/tests/test/index.html delete mode 100644 build/reports/tests/test/js/report.js delete mode 100644 build/reports/tests/test/packages/duke.task.html delete mode 100644 build/test-results/test/TEST-duke.task.RecurringTest.xml delete mode 100644 build/test-results/test/binary/output.bin delete mode 100644 build/test-results/test/binary/output.bin.idx delete mode 100644 build/test-results/test/binary/results.bin diff --git a/build/reports/checkstyle/main.html b/build/reports/checkstyle/main.html deleted file mode 100644 index 9410402449..0000000000 --- a/build/reports/checkstyle/main.html +++ /dev/null @@ -1,958 +0,0 @@ - - - - - - - - - - - - - - -
-

CheckStyle Audit

-
Designed for use with CheckStyle and Ant.
-
-

Summary

- - - - - - - -
FilesErrors
26203
-
-

Files

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameErrors
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\Parser.java94
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\Task.java15
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\AddCommand.java13
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\DateTimeParser.java11
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\RescheduleCommand.java10
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\Ui.java7
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\RecurringCommand.java6
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\Storage.java6
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\Duke.java5
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\FixedDurationTask.java4
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\PeriodTask.java4
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\RemindCommand.java3
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\ViewCommand.java3
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\Deadline.java3
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\Event.java3
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\Todo.java3
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\Reminder.java2
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\DeleteCommand.java2
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\DoneCommand.java2
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\ExitCommand.java2
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\FindCommand.java2
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\ListCommand.java2
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\Command.java1
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\FindFreeTimesCommand.java0
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\DukeException.java0
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\TaskList.java0
-
- -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\Duke.java

- - - - - - - - - - - - - - - - - - - -
Error DescriptionLine
Using the '.*' form of import should be avoided - duke.core.*.5
WhitespaceAround: '{' is not preceded with whitespace.11
'CTOR_DEF' should be separated from previous statement.32
First sentence of Javadoc is missing an ending period.65
'METHOD_DEF' should be separated from previous statement.71
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\Reminder.java

- - - - - - - - - - -
Error DescriptionLine
'CTOR_DEF' should be separated from previous statement.38
'{' at column 21 should be on the previous line.54
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\AddCommand.java

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Error DescriptionLine
First sentence of Javadoc is missing an ending period.24
First sentence of Javadoc is missing an ending period.40
Line continuation have incorrect indentation level, expected level should be 4.44
Line is longer than 120 characters (found 129).67
')' is preceded with whitespace.67
WhitespaceAround: '{' is not preceded with whitespace.67
',' is preceded with whitespace.75
';' is preceded with whitespace.77
')' is preceded with whitespace.81
WhitespaceAround: '}' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)94
WhitespaceAround: 'else' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)94
WhitespaceAround: 'else' is not preceded with whitespace.94
WhitespaceAround: '{' is not preceded with whitespace.94
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\Command.java

- - - - - - - -
Error DescriptionLine
Line continuation have incorrect indentation level, expected level should be 4.30
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\DeleteCommand.java

- - - - - - - - - - -
Error DescriptionLine
First sentence of Javadoc is missing an ending period.31
Line continuation have incorrect indentation level, expected level should be 4.35
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\DoneCommand.java

- - - - - - - - - - -
Error DescriptionLine
First sentence of Javadoc is missing an ending period.30
Line continuation have incorrect indentation level, expected level should be 4.34
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\ExitCommand.java

- - - - - - - - - - -
Error DescriptionLine
First sentence of Javadoc is missing an ending period.20
Line continuation have incorrect indentation level, expected level should be 4.24
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\FindCommand.java

- - - - - - - - - - -
Error DescriptionLine
First sentence of Javadoc is missing an ending period.29
Line continuation have incorrect indentation level, expected level should be 4.33
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\FindFreeTimesCommand.java

- - - - -
Error DescriptionLine
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\ListCommand.java

- - - - - - - - - - -
Error DescriptionLine
First sentence of Javadoc is missing an ending period.21
Line continuation have incorrect indentation level, expected level should be 4.25
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\RecurringCommand.java

- - - - - - - - - - - - - - - - - - - - - - -
Error DescriptionLine
Using the '.*' form of import should be avoided - duke.task.*.7
First sentence of Javadoc is missing an ending period.23
Line continuation have incorrect indentation level, expected level should be 4.27
'{' at column 29 should have line break after.30
'}' at column 45 should be alone on a line.30
Empty line should be followed by <p> tag on the next line.34
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\RemindCommand.java

- - - - - - - - - - - - - -
Error DescriptionLine
'CTOR_DEF' should be separated from previous statement.21
First sentence of Javadoc is missing an ending period.26
Line continuation have incorrect indentation level, expected level should be 4.30
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\RescheduleCommand.java

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Error DescriptionLine
Line is longer than 120 characters (found 127).23
WhitespaceAround: 'try' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)40
WhitespaceAround: '{' is not preceded with whitespace.40
WhitespaceAround: '{' is not preceded with whitespace.42
WhitespaceAround: '}' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)48
WhitespaceAround: 'catch' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)48
WhitespaceAround: 'catch' is not preceded with whitespace.48
WhitespaceAround: '{' is not preceded with whitespace.48
First sentence of Javadoc is missing an ending period.53
Line continuation have incorrect indentation level, expected level should be 4.57
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\ViewCommand.java

- - - - - - - - - - - - - -
Error DescriptionLine
'(' is preceded with whitespace.16
First sentence of Javadoc is missing an ending period.23
Line continuation have incorrect indentation level, expected level should be 4.27
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\DateTimeParser.java

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Error DescriptionLine
Javadoc comment at column 19 has parse error. Missed HTML close tag 'code'. Sometimes it means that close tag missed for one of previous tags.9
Line is longer than 120 characters (found 128).33
Line is longer than 120 characters (found 128).34
Line is longer than 120 characters (found 128).35
Line is longer than 120 characters (found 128).36
WhitespaceAround: 'try' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)38
WhitespaceAround: '{' is not preceded with whitespace.38
WhitespaceAround: '}' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)50
WhitespaceAround: 'catch' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)50
WhitespaceAround: 'catch' is not preceded with whitespace.50
WhitespaceAround: '{' is not preceded with whitespace.50
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\DukeException.java

- - - - -
Error DescriptionLine
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\Parser.java

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Error DescriptionLine
Using the '.*' form of import should be avoided - duke.command.*.3
Using the '.*' form of import should be avoided - duke.task.*.4
'case' child has incorrect indentation level 12, expected level should be 8.28
'block' child has incorrect indentation level 16, expected level should be 12.29
'case' child has incorrect indentation level 12, expected level should be 8.30
'try' has incorrect indentation level 16, expected level should be 12.31
'try' child has incorrect indentation level 20, expected level should be 16.32
'try' child has incorrect indentation level 20, expected level should be 16.33
'try rcurly' has incorrect indentation level 16, expected level should be 12.34
'catch' child has incorrect indentation level 20, expected level should be 16.35
'catch rcurly' has incorrect indentation level 16, expected level should be 12.36
'case' child has incorrect indentation level 12, expected level should be 8.37
'try' has incorrect indentation level 16, expected level should be 12.38
'try' child has incorrect indentation level 20, expected level should be 16.39
'try' child has incorrect indentation level 20, expected level should be 16.40
'try rcurly' has incorrect indentation level 16, expected level should be 12.41
'catch' child has incorrect indentation level 20, expected level should be 16.42
'catch rcurly' has incorrect indentation level 16, expected level should be 12.43
'case' child has incorrect indentation level 12, expected level should be 8.44
'try' has incorrect indentation level 16, expected level should be 12.45
'try' child has incorrect indentation level 20, expected level should be 16.46
'try' child has incorrect indentation level 20, expected level should be 16.47
'try rcurly' has incorrect indentation level 16, expected level should be 12.48
'catch' child has incorrect indentation level 20, expected level should be 16.49
'catch rcurly' has incorrect indentation level 16, expected level should be 12.50
'case' child has incorrect indentation level 12, expected level should be 8.51
'try' has incorrect indentation level 16, expected level should be 12.52
'try' child has incorrect indentation level 20, expected level should be 16.53
'try' child has incorrect indentation level 20, expected level should be 16.54
'try' child has incorrect indentation level 20, expected level should be 16.55
'try rcurly' has incorrect indentation level 16, expected level should be 12.56
'}' at column 17 should be on the same line as the next part of a multi-block statement (one that directly contains multiple blocks: if/else-if/else, do/while or try/catch/finally).56
'catch' has incorrect indentation level 17, expected level should be 12.57
'catch' child has incorrect indentation level 20, expected level should be 16.58
'catch rcurly' has incorrect indentation level 17, expected level should be 12.59
'case' child has incorrect indentation level 12, expected level should be 8.60
'try' has incorrect indentation level 16, expected level should be 12.61
'try' child has incorrect indentation level 20, expected level should be 16.62
'try' child has incorrect indentation level 20, expected level should be 16.63
'try' child has incorrect indentation level 20, expected level should be 16.64
'try rcurly' has incorrect indentation level 16, expected level should be 12.65
'catch' child has incorrect indentation level 20, expected level should be 16.66
'catch rcurly' has incorrect indentation level 16, expected level should be 12.67
'case' child has incorrect indentation level 12, expected level should be 8.68
'try' has incorrect indentation level 16, expected level should be 12.69
'try' child has incorrect indentation level 20, expected level should be 16.70
'try' child has incorrect indentation level 20, expected level should be 16.71
'try' child has incorrect indentation level 20, expected level should be 16.72
'try rcurly' has incorrect indentation level 16, expected level should be 12.73
'catch' child has incorrect indentation level 20, expected level should be 16.74
'catch rcurly' has incorrect indentation level 16, expected level should be 12.75
'case' child has incorrect indentation level 12, expected level should be 8.76
'try' has incorrect indentation level 16, expected level should be 12.77
'try' child has incorrect indentation level 20, expected level should be 16.78
'try' child has incorrect indentation level 20, expected level should be 16.79
'try' child has incorrect indentation level 20, expected level should be 16.80
'try' child has incorrect indentation level 20, expected level should be 16.81
'try rcurly' has incorrect indentation level 16, expected level should be 12.82
WhitespaceAround: '}' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)82
WhitespaceAround: 'catch' is not preceded with whitespace.82
'catch' child has incorrect indentation level 20, expected level should be 16.83
Line is longer than 120 characters (found 181).83
'catch rcurly' has incorrect indentation level 16, expected level should be 12.85
'case' child has incorrect indentation level 12, expected level should be 8.86
'block' child has incorrect indentation level 16, expected level should be 12.87
'case' child has incorrect indentation level 12, expected level should be 8.88
'try' has incorrect indentation level 16, expected level should be 12.89
'try' child has incorrect indentation level 20, expected level should be 16.90
'try' child has incorrect indentation level 20, expected level should be 16.91
'try rcurly' has incorrect indentation level 16, expected level should be 12.92
'catch' child has incorrect indentation level 20, expected level should be 16.93
Line is longer than 120 characters (found 156).93
'catch rcurly' has incorrect indentation level 16, expected level should be 12.94
'case' child has incorrect indentation level 12, expected level should be 8.95
'try' has incorrect indentation level 16, expected level should be 12.96
'try' child has incorrect indentation level 20, expected level should be 16.97
'try' child has incorrect indentation level 20, expected level should be 16.98
'try' child has incorrect indentation level 20, expected level should be 16.99
'try' child has incorrect indentation level 20, expected level should be 16.100
'try rcurly' has incorrect indentation level 16, expected level should be 12.102
'catch' child has incorrect indentation level 20, expected level should be 16.103
'catch rcurly' has incorrect indentation level 16, expected level should be 12.104
'case' child has incorrect indentation level 12, expected level should be 8.105
Fall through from previous branch of the switch statement.105
'try' has incorrect indentation level 16, expected level should be 12.106
'try' child has incorrect indentation level 20, expected level should be 16.107
'try' child has incorrect indentation level 20, expected level should be 16.108
'try rcurly' has incorrect indentation level 16, expected level should be 12.109
'catch' child has incorrect indentation level 20, expected level should be 16.110
'catch rcurly' has incorrect indentation level 16, expected level should be 12.111
'case' child has incorrect indentation level 12, expected level should be 8.112
'block' child has incorrect indentation level 16, expected level should be 12.113
'case' child has incorrect indentation level 12, expected level should be 8.114
'block' child has incorrect indentation level 16, expected level should be 12.115
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\Storage.java

- - - - - - - - - - - - - - - - - - - - - - -
Error DescriptionLine
Using the '.*' form of import should be avoided - duke.task.*.3
'}' at column 17 should be on the same line as the next part of a multi-block statement (one that directly contains multiple blocks: if/else-if/else, do/while or try/catch/finally).54
'}' at column 17 should be on the same line as the next part of a multi-block statement (one that directly contains multiple blocks: if/else-if/else, do/while or try/catch/finally).64
'}' at column 17 should be on the same line as the next part of a multi-block statement (one that directly contains multiple blocks: if/else-if/else, do/while or try/catch/finally).74
WhitespaceAround: '}' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)82
WhitespaceAround: 'else' is not preceded with whitespace.82
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\TaskList.java

- - - - -
Error DescriptionLine
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\Ui.java

- - - - - - - - - - - - - - - - - - - - - - - - - -
Error DescriptionLine
First sentence of Javadoc is missing an ending period.10
Unused Javadoc tag.104
'(' is preceded with whitespace.106
Comment has incorrect indentation level 0, expected is 8, indentation should be the same level as line 114.116
'(' is preceded with whitespace.141
',' is preceded with whitespace.141
Missing a Javadoc comment.159
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\Deadline.java

- - - - - - - - - - - - - -
Error DescriptionLine
First sentence of Javadoc is missing an ending period.34
Line continuation have incorrect indentation level, expected level should be 4.38
First sentence of Javadoc is missing an ending period.45
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\Event.java

- - - - - - - - - - - - - -
Error DescriptionLine
First sentence of Javadoc is missing an ending period.32
Line continuation have incorrect indentation level, expected level should be 4.36
First sentence of Javadoc is missing an ending period.43
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\FixedDurationTask.java

- - - - - - - - - - - - - - - - -
Error DescriptionLine
First sentence of Javadoc is missing an ending period.4
Summary javadoc is missing.21
Line continuation have incorrect indentation level, expected level should be 4.24
First sentence of Javadoc is missing an ending period.31
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\PeriodTask.java

- - - - - - - - - - - - - - - - -
Error DescriptionLine
Unused @param tag for 'startTime'.26
First sentence of Javadoc is missing an ending period.37
Line continuation have incorrect indentation level, expected level should be 4.41
First sentence of Javadoc is missing an ending period.50
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\Task.java

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Error DescriptionLine
First sentence of Javadoc is missing an ending period.25
First sentence of Javadoc is missing an ending period.29
First sentence of Javadoc is missing an ending period.57
First sentence of Javadoc is missing an ending period.66
'{' at column 37 should have line break after.83
'}' at column 59 should be alone on a line.83
'{' at column 38 should have line break after.88
'}' at column 60 should be alone on a line.88
')' is preceded with whitespace.100
'{' at column 43 should have line break after.103
Line continuation have incorrect indentation level, expected level should be 4.125
Comment has incorrect indentation level 0, expected is 4, indentation should be the same level as line 164.158
Javadoc comment at column 19 has parse error. Missed HTML close tag 'code'. Sometimes it means that close tag missed for one of previous tags.161
'{' at column 5 should be on the previous line.174
'{' at column 37 should have line break after.175
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\Todo.java

- - - - - - - - - - - - - -
Error DescriptionLine
First sentence of Javadoc is missing an ending period.18
Line continuation have incorrect indentation level, expected level should be 4.22
First sentence of Javadoc is missing an ending period.29
- Back to top -
- - diff --git a/build/reports/checkstyle/main.xml b/build/reports/checkstyle/main.xml deleted file mode 100644 index 777ddd1884..0000000000 --- a/build/reports/checkstyle/main.xml +++ /dev/null @@ -1,258 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/build/reports/checkstyle/test.html b/build/reports/checkstyle/test.html deleted file mode 100644 index 10e2dd1b81..0000000000 --- a/build/reports/checkstyle/test.html +++ /dev/null @@ -1,298 +0,0 @@ - - - - - - - - - - - - - - -
-

CheckStyle Audit

-
Designed for use with CheckStyle and Ant.
-
-

Summary

- - - - - - - -
FilesErrors
553
-
-

Files

- - - - - - - - - - - - - - - - - - - -
NameErrors
C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\task\DeadlineTest.java15
C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\task\EventTest.java15
C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\task\TodoTest.java10
C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\core\ParserTest.java7
C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\task\PeriodTaskTest.java6
-
- -

File C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\core\ParserTest.java

- - - - - - - - - - - - - - - - - - - - - - - - - -
Error DescriptionLine
Using the '.*' form of import should be avoided - duke.command.*.3
Distance between variable 'c4' declaration and its first usage is 4, but allowed 3. Consider making that variable final if you still need to store its value in advance (before method calls that might have side effects on the original value).18
Distance between variable 'c5' declaration and its first usage is 5, but allowed 3. Consider making that variable final if you still need to store its value in advance (before method calls that might have side effects on the original value).19
Distance between variable 'c6' declaration and its first usage is 6, but allowed 3. Consider making that variable final if you still need to store its value in advance (before method calls that might have side effects on the original value).20
Distance between variable 'c7' declaration and its first usage is 7, but allowed 3. Consider making that variable final if you still need to store its value in advance (before method calls that might have side effects on the original value).21
Distance between variable 'c8' declaration and its first usage is 8, but allowed 3. Consider making that variable final if you still need to store its value in advance (before method calls that might have side effects on the original value).22
Distance between variable 'c9' declaration and its first usage is 9, but allowed 3. Consider making that variable final if you still need to store its value in advance (before method calls that might have side effects on the original value).23
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\task\DeadlineTest.java

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Error DescriptionLine
Using the '.*' form of import should be avoided - org.junit.jupiter.api.Assertions.*.6
Line is longer than 120 characters (found 163).16
Unicode escape(s) usage should be avoided.16
'(' is followed by whitespace.16
Line is longer than 120 characters (found 173).24
'(' is followed by whitespace.24
Line is longer than 120 characters (found 145).50
Unicode escape(s) usage should be avoided.50
'(' is followed by whitespace.50
Line is longer than 120 characters (found 134).51
'(' is followed by whitespace.51
Line is longer than 120 characters (found 146).56
Unicode escape(s) usage should be avoided.56
Line is longer than 120 characters (found 126).57
'(' is followed by whitespace.57
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\task\EventTest.java

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Error DescriptionLine
Using the '.*' form of import should be avoided - org.junit.jupiter.api.Assertions.*.7
Method name 'EventStringTest' must match pattern '^[a-z][a-z0-9][a-zA-Z0-9_]*$'.15
Line is longer than 120 characters (found 168).16
Unicode escape(s) usage should be avoided.16
Line is longer than 120 characters (found 154).24
'(' is followed by whitespace.24
Line is longer than 120 characters (found 139).50
Unicode escape(s) usage should be avoided.50
'(' is followed by whitespace.50
Line is longer than 120 characters (found 128).51
'(' is followed by whitespace.51
Line is longer than 120 characters (found 137).56
Unicode escape(s) usage should be avoided.56
Line is longer than 120 characters (found 128).57
'(' is followed by whitespace.57
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\task\PeriodTaskTest.java

- - - - - - - - - - - - - - - - - - - - - - -
Error DescriptionLine
Using the '.*' form of import should be avoided - org.junit.jupiter.api.Assertions.*.6
Method name 'PeriodTaskStringTest' must match pattern '^[a-z][a-z0-9][a-zA-Z0-9_]*$'.14
Line is longer than 120 characters (found 229).15
Unicode escape(s) usage should be avoided.15
Line is longer than 120 characters (found 208).23
'(' is followed by whitespace.23
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\task\TodoTest.java

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Error DescriptionLine
Using the '.*' form of import should be avoided - org.junit.jupiter.api.Assertions.*.6
WhitespaceAround: '{' is not preceded with whitespace.15
Unicode escape(s) usage should be avoided.16
Line is longer than 120 characters (found 124).24
'(' is followed by whitespace.24
Unicode escape(s) usage should be avoided.50
'(' is followed by whitespace.50
'(' is followed by whitespace.51
Unicode escape(s) usage should be avoided.56
'(' is followed by whitespace.57
- Back to top -
- - diff --git a/build/reports/checkstyle/test.xml b/build/reports/checkstyle/test.xml deleted file mode 100644 index ebc36f73b5..0000000000 --- a/build/reports/checkstyle/test.xml +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/build/reports/tests/test/classes/duke.task.RecurringTest.html b/build/reports/tests/test/classes/duke.task.RecurringTest.html deleted file mode 100644 index fcb2112179..0000000000 --- a/build/reports/tests/test/classes/duke.task.RecurringTest.html +++ /dev/null @@ -1,219 +0,0 @@ - - - - - -Test results - RecurringTest - - - - - -
-

RecurringTest

- -
- - - - - -
-
- - - - - - - -
-
-
4
-

tests

-
-
-
-
1
-

failures

-
-
-
-
0
-

ignored

-
-
-
-
0.087s
-

duration

-
-
-
-
-
-
75%
-

successful

-
-
-
-
- -
-

Failed tests

-
- -

recurringTodoTest()

- -
org.opentest4j.AssertionFailedError: expected: not equal but was: <true>
-	at org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:39)
-	at org.junit.jupiter.api.AssertNotEquals.failEqual(AssertNotEquals.java:276)
-	at org.junit.jupiter.api.AssertNotEquals.assertNotEquals(AssertNotEquals.java:265)
-	at org.junit.jupiter.api.AssertNotEquals.assertNotEquals(AssertNotEquals.java:260)
-	at org.junit.jupiter.api.Assertions.assertNotEquals(Assertions.java:2743)
-	at duke.task.RecurringTest.recurringTodoTest(RecurringTest.java:51)
-	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
-	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
-	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
-	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
-	at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:675)
-	at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
-	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:125)
-	at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:132)
-	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:124)
-	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:74)
-	at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
-	at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
-	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:104)
-	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:62)
-	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:43)
-	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:35)
-	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
-	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
-	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:202)
-	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
-	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:198)
-	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135)
-	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:69)
-	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
-	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
-	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
-	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
-	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
-	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
-	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
-	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
-	at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
-	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
-	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
-	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
-	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
-	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
-	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
-	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
-	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
-	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
-	at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
-	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
-	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
-	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
-	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
-	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
-	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
-	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
-	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
-	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
-	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
-	at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
-	at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
-	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:220)
-	at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:188)
-	at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:202)
-	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:181)
-	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128)
-	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:102)
-	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:82)
-	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:78)
-	at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:61)
-	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
-	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
-	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
-	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
-	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
-	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
-	at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
-	at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
-	at com.sun.proxy.$Proxy2.stop(Unknown Source)
-	at org.gradle.api.internal.tasks.testing.worker.TestWorker.stop(TestWorker.java:132)
-	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
-	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
-	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
-	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
-	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
-	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
-	at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:175)
-	at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:157)
-	at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:404)
-	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
-	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
-	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
-	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
-	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
-	at java.base/java.lang.Thread.run(Thread.java:834)
-
-
-
-
-
-

Tests

- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TestDurationResult
recurringDailyDeadlineTest()0.066spassed
recurringMonthlyDeadlineTest()0.002spassed
recurringTodoTest()0.013sfailed
recurringWeeklyEventTest()0.006spassed
-
-
- -
- - diff --git a/build/reports/tests/test/css/base-style.css b/build/reports/tests/test/css/base-style.css deleted file mode 100644 index 4afa73e3dd..0000000000 --- a/build/reports/tests/test/css/base-style.css +++ /dev/null @@ -1,179 +0,0 @@ - -body { - margin: 0; - padding: 0; - font-family: sans-serif; - font-size: 12pt; -} - -body, a, a:visited { - color: #303030; -} - -#content { - padding-left: 50px; - padding-right: 50px; - padding-top: 30px; - padding-bottom: 30px; -} - -#content h1 { - font-size: 160%; - margin-bottom: 10px; -} - -#footer { - margin-top: 100px; - font-size: 80%; - white-space: nowrap; -} - -#footer, #footer a { - color: #a0a0a0; -} - -#line-wrapping-toggle { - vertical-align: middle; -} - -#label-for-line-wrapping-toggle { - vertical-align: middle; -} - -ul { - margin-left: 0; -} - -h1, h2, h3 { - white-space: nowrap; -} - -h2 { - font-size: 120%; -} - -ul.tabLinks { - padding-left: 0; - padding-top: 10px; - padding-bottom: 10px; - overflow: auto; - min-width: 800px; - width: auto !important; - width: 800px; -} - -ul.tabLinks li { - float: left; - height: 100%; - list-style: none; - padding-left: 10px; - padding-right: 10px; - padding-top: 5px; - padding-bottom: 5px; - margin-bottom: 0; - -moz-border-radius: 7px; - border-radius: 7px; - margin-right: 25px; - border: solid 1px #d4d4d4; - background-color: #f0f0f0; -} - -ul.tabLinks li:hover { - background-color: #fafafa; -} - -ul.tabLinks li.selected { - background-color: #c5f0f5; - border-color: #c5f0f5; -} - -ul.tabLinks a { - font-size: 120%; - display: block; - outline: none; - text-decoration: none; - margin: 0; - padding: 0; -} - -ul.tabLinks li h2 { - margin: 0; - padding: 0; -} - -div.tab { -} - -div.selected { - display: block; -} - -div.deselected { - display: none; -} - -div.tab table { - min-width: 350px; - width: auto !important; - width: 350px; - border-collapse: collapse; -} - -div.tab th, div.tab table { - border-bottom: solid #d0d0d0 1px; -} - -div.tab th { - text-align: left; - white-space: nowrap; - padding-left: 6em; -} - -div.tab th:first-child { - padding-left: 0; -} - -div.tab td { - white-space: nowrap; - padding-left: 6em; - padding-top: 5px; - padding-bottom: 5px; -} - -div.tab td:first-child { - padding-left: 0; -} - -div.tab td.numeric, div.tab th.numeric { - text-align: right; -} - -span.code { - display: inline-block; - margin-top: 0em; - margin-bottom: 1em; -} - -span.code pre { - font-size: 11pt; - padding-top: 10px; - padding-bottom: 10px; - padding-left: 10px; - padding-right: 10px; - margin: 0; - background-color: #f7f7f7; - border: solid 1px #d0d0d0; - min-width: 700px; - width: auto !important; - width: 700px; -} - -span.wrapped pre { - word-wrap: break-word; - white-space: pre-wrap; - word-break: break-all; -} - -label.hidden { - display: none; -} \ No newline at end of file diff --git a/build/reports/tests/test/css/style.css b/build/reports/tests/test/css/style.css deleted file mode 100644 index 3dc4913e7a..0000000000 --- a/build/reports/tests/test/css/style.css +++ /dev/null @@ -1,84 +0,0 @@ - -#summary { - margin-top: 30px; - margin-bottom: 40px; -} - -#summary table { - border-collapse: collapse; -} - -#summary td { - vertical-align: top; -} - -.breadcrumbs, .breadcrumbs a { - color: #606060; -} - -.infoBox { - width: 110px; - padding-top: 15px; - padding-bottom: 15px; - text-align: center; -} - -.infoBox p { - margin: 0; -} - -.counter, .percent { - font-size: 120%; - font-weight: bold; - margin-bottom: 8px; -} - -#duration { - width: 125px; -} - -#successRate, .summaryGroup { - border: solid 2px #d0d0d0; - -moz-border-radius: 10px; - border-radius: 10px; -} - -#successRate { - width: 140px; - margin-left: 35px; -} - -#successRate .percent { - font-size: 180%; -} - -.success, .success a { - color: #008000; -} - -div.success, #successRate.success { - background-color: #bbd9bb; - border-color: #008000; -} - -.failures, .failures a { - color: #b60808; -} - -.skipped, .skipped a { - color: #c09853; -} - -div.failures, #successRate.failures { - background-color: #ecdada; - border-color: #b60808; -} - -ul.linkList { - padding-left: 0; -} - -ul.linkList li { - list-style: none; - margin-bottom: 5px; -} diff --git a/build/reports/tests/test/index.html b/build/reports/tests/test/index.html deleted file mode 100644 index 791c760733..0000000000 --- a/build/reports/tests/test/index.html +++ /dev/null @@ -1,145 +0,0 @@ - - - - - -Test results - Test Summary - - - - - -
-

Test Summary

-
- - - - - -
-
- - - - - - - -
-
-
4
-

tests

-
-
-
-
1
-

failures

-
-
-
-
0
-

ignored

-
-
-
-
0.087s
-

duration

-
-
-
-
-
-
75%
-

successful

-
-
-
-
- -
-

Failed tests

- -
-
-

Packages

- - - - - - - - - - - - - - - - - - - - - -
PackageTestsFailuresIgnoredDurationSuccess rate
-duke.task -4100.087s75%
-
-
-

Classes

- - - - - - - - - - - - - - - - - - - - - -
ClassTestsFailuresIgnoredDurationSuccess rate
-duke.task.RecurringTest -4100.087s75%
-
-
- -
- - diff --git a/build/reports/tests/test/js/report.js b/build/reports/tests/test/js/report.js deleted file mode 100644 index 83bab4a19f..0000000000 --- a/build/reports/tests/test/js/report.js +++ /dev/null @@ -1,194 +0,0 @@ -(function (window, document) { - "use strict"; - - var tabs = {}; - - function changeElementClass(element, classValue) { - if (element.getAttribute("className")) { - element.setAttribute("className", classValue); - } else { - element.setAttribute("class", classValue); - } - } - - function getClassAttribute(element) { - if (element.getAttribute("className")) { - return element.getAttribute("className"); - } else { - return element.getAttribute("class"); - } - } - - function addClass(element, classValue) { - changeElementClass(element, getClassAttribute(element) + " " + classValue); - } - - function removeClass(element, classValue) { - changeElementClass(element, getClassAttribute(element).replace(classValue, "")); - } - - function initTabs() { - var container = document.getElementById("tabs"); - - tabs.tabs = findTabs(container); - tabs.titles = findTitles(tabs.tabs); - tabs.headers = findHeaders(container); - tabs.select = select; - tabs.deselectAll = deselectAll; - tabs.select(0); - - return true; - } - - function getCheckBox() { - return document.getElementById("line-wrapping-toggle"); - } - - function getLabelForCheckBox() { - return document.getElementById("label-for-line-wrapping-toggle"); - } - - function findCodeBlocks() { - var spans = document.getElementById("tabs").getElementsByTagName("span"); - var codeBlocks = []; - for (var i = 0; i < spans.length; ++i) { - if (spans[i].className.indexOf("code") >= 0) { - codeBlocks.push(spans[i]); - } - } - return codeBlocks; - } - - function forAllCodeBlocks(operation) { - var codeBlocks = findCodeBlocks(); - - for (var i = 0; i < codeBlocks.length; ++i) { - operation(codeBlocks[i], "wrapped"); - } - } - - function toggleLineWrapping() { - var checkBox = getCheckBox(); - - if (checkBox.checked) { - forAllCodeBlocks(addClass); - } else { - forAllCodeBlocks(removeClass); - } - } - - function initControls() { - if (findCodeBlocks().length > 0) { - var checkBox = getCheckBox(); - var label = getLabelForCheckBox(); - - checkBox.onclick = toggleLineWrapping; - checkBox.checked = false; - - removeClass(label, "hidden"); - } - } - - function switchTab() { - var id = this.id.substr(1); - - for (var i = 0; i < tabs.tabs.length; i++) { - if (tabs.tabs[i].id === id) { - tabs.select(i); - break; - } - } - - return false; - } - - function select(i) { - this.deselectAll(); - - changeElementClass(this.tabs[i], "tab selected"); - changeElementClass(this.headers[i], "selected"); - - while (this.headers[i].firstChild) { - this.headers[i].removeChild(this.headers[i].firstChild); - } - - var h2 = document.createElement("H2"); - - h2.appendChild(document.createTextNode(this.titles[i])); - this.headers[i].appendChild(h2); - } - - function deselectAll() { - for (var i = 0; i < this.tabs.length; i++) { - changeElementClass(this.tabs[i], "tab deselected"); - changeElementClass(this.headers[i], "deselected"); - - while (this.headers[i].firstChild) { - this.headers[i].removeChild(this.headers[i].firstChild); - } - - var a = document.createElement("A"); - - a.setAttribute("id", "ltab" + i); - a.setAttribute("href", "#tab" + i); - a.onclick = switchTab; - a.appendChild(document.createTextNode(this.titles[i])); - - this.headers[i].appendChild(a); - } - } - - function findTabs(container) { - return findChildElements(container, "DIV", "tab"); - } - - function findHeaders(container) { - var owner = findChildElements(container, "UL", "tabLinks"); - return findChildElements(owner[0], "LI", null); - } - - function findTitles(tabs) { - var titles = []; - - for (var i = 0; i < tabs.length; i++) { - var tab = tabs[i]; - var header = findChildElements(tab, "H2", null)[0]; - - header.parentNode.removeChild(header); - - if (header.innerText) { - titles.push(header.innerText); - } else { - titles.push(header.textContent); - } - } - - return titles; - } - - function findChildElements(container, name, targetClass) { - var elements = []; - var children = container.childNodes; - - for (var i = 0; i < children.length; i++) { - var child = children.item(i); - - if (child.nodeType === 1 && child.nodeName === name) { - if (targetClass && child.className.indexOf(targetClass) < 0) { - continue; - } - - elements.push(child); - } - } - - return elements; - } - - // Entry point. - - window.onload = function() { - initTabs(); - initControls(); - }; -} (window, window.document)); \ No newline at end of file diff --git a/build/reports/tests/test/packages/duke.task.html b/build/reports/tests/test/packages/duke.task.html deleted file mode 100644 index d1ec2fa86e..0000000000 --- a/build/reports/tests/test/packages/duke.task.html +++ /dev/null @@ -1,115 +0,0 @@ - - - - - -Test results - Package duke.task - - - - - -
-

Package duke.task

- -
- - - - - -
-
- - - - - - - -
-
-
4
-

tests

-
-
-
-
1
-

failures

-
-
-
-
0
-

ignored

-
-
-
-
0.087s
-

duration

-
-
-
-
-
-
75%
-

successful

-
-
-
-
- -
-

Failed tests

- -
-
-

Classes

- - - - - - - - - - - - - - - - - - - -
ClassTestsFailuresIgnoredDurationSuccess rate
-RecurringTest -4100.087s75%
-
-
- -
- - diff --git a/build/test-results/test/TEST-duke.task.RecurringTest.xml b/build/test-results/test/TEST-duke.task.RecurringTest.xml deleted file mode 100644 index 028ac03a61..0000000000 --- a/build/test-results/test/TEST-duke.task.RecurringTest.xml +++ /dev/null @@ -1,107 +0,0 @@ - - - - - - - org.opentest4j.AssertionFailedError: expected: not equal but was: <true> - at org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:39) - at org.junit.jupiter.api.AssertNotEquals.failEqual(AssertNotEquals.java:276) - at org.junit.jupiter.api.AssertNotEquals.assertNotEquals(AssertNotEquals.java:265) - at org.junit.jupiter.api.AssertNotEquals.assertNotEquals(AssertNotEquals.java:260) - at org.junit.jupiter.api.Assertions.assertNotEquals(Assertions.java:2743) - at duke.task.RecurringTest.recurringTodoTest(RecurringTest.java:51) - at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) - at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) - at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) - at java.base/java.lang.reflect.Method.invoke(Method.java:566) - at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:675) - at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60) - at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:125) - at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:132) - at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:124) - at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:74) - at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115) - at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105) - at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:104) - at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:62) - at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:43) - at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:35) - at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104) - at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98) - at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:202) - at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) - at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:198) - at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135) - at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:69) - at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135) - at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) - at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125) - at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135) - at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123) - at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) - at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122) - at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80) - at java.base/java.util.ArrayList.forEach(ArrayList.java:1540) - at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38) - at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139) - at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) - at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125) - at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135) - at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123) - at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) - at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122) - at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80) - at java.base/java.util.ArrayList.forEach(ArrayList.java:1540) - at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38) - at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139) - at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) - at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125) - at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135) - at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123) - at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) - at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122) - at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80) - at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32) - at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) - at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51) - at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:220) - at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:188) - at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:202) - at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:181) - at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128) - at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:102) - at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:82) - at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:78) - at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:61) - at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) - at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) - at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) - at java.base/java.lang.reflect.Method.invoke(Method.java:566) - at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35) - at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) - at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32) - at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93) - at com.sun.proxy.$Proxy2.stop(Unknown Source) - at org.gradle.api.internal.tasks.testing.worker.TestWorker.stop(TestWorker.java:132) - at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) - at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) - at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) - at java.base/java.lang.reflect.Method.invoke(Method.java:566) - at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35) - at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) - at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:175) - at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:157) - at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:404) - at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63) - at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46) - at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) - at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) - at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55) - at java.base/java.lang.Thread.run(Thread.java:834) - - - - - - diff --git a/build/test-results/test/binary/output.bin b/build/test-results/test/binary/output.bin deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/build/test-results/test/binary/output.bin.idx b/build/test-results/test/binary/output.bin.idx deleted file mode 100644 index f76dd238ade08917e6712764a16a22005a50573d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1 IcmZPo000310RR91 diff --git a/build/test-results/test/binary/results.bin b/build/test-results/test/binary/results.bin deleted file mode 100644 index 57e302d182c2df42fa1f5630209304b5d106d32e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10097 zcmeHNOK;mo5SEj)KnwKTs}4Lc7gmxjSuu(Lj;+8hlGKRp7(K4YwM2{Jvdg7y{eS{J z^;Dn*iXxZ(nE?G!oqduLpK_GA2VZQFyZg;!zZnj9_;~BlpI$P<4ny(Gd5hhIQa_xW z;h6olbk%BY&7c4K{@W*8e^Wi{5c$F45F;<}L(G@hPb&voFBHm8t;c^Elnab!!D4ic zLnbjQhFV`Lgt+zOcY|<7JR+AC-P`&`t@&l^A3`S%i9ix4yL092$1$eNC*e!51bZV& z3H`9uVA5V2-$vMF*xPG|gthU{2@2Zdgtc!_yx0Do(F8yL@W;lWzWxfaHrMMa34I2C zBcEaFpvX^cIA?wkJC|UIZS0cwuFy5w+kW=67Ud0LBW{U=5kD1HIwHV&yMuMmknpp? zD8U@`KLKW^9uxLIc8XOLL(1ZvZ3$HpE>50~Z*`z>aykO0-<2Tz!Wp9&e|P2093Kct zLlgkUWdO8t-XP{*R%jaVcS>*B^@ja=4)vkTUgaUGv7ZfVV%x*9OMRXa9iA;@1o2;o>41tcDJh+04eaz{Wr;AX*U2R@ z^Jr07EKZ_`Q07d1Oc8abz6+1_vneGvJp2zxz@P7+8x|=6+XX{1yQpfTlnYJlTs5%9 zyzWMvYb-1CzT`+P|C$)sOx7S*`Zn6NH^dWfHD~x9N49YjeIdID8F!tz9DjK*WMW_N~#2IPXPk;r@6 zojm6XZMs`(TH=A`+R{zIvY{$Z`GtCK;lD&3y-z7xyz=1{2WspQa;J8BM@B<`Cs*Az za`-8lV{kg0FdSvlDc|*xNS}nBVtVbnSiJ}A2Z7yujnHj7_dIE&*^-CK!>2em+$|m5 z6Z^`Id&mu&e#Ea&y@%ZJkQ+8tV6M-;huqM}XZMu3|4+FgeT`}4vE~o)I2q4Sb`J3+N&@yu z-_(`h>V1LQ>y?*t)v(J61Kzg_@w>zFqO2PK#%EJ==7YUc2DRfnE|yaDGG8sF(mCDX zC-Hf=m+{GjLeCA0_K&Yy2fTq7I}B=LIDMCWBEzm9&Y^2`q7K1%`Fs#SzvF}-Nb}Bu zrH&<_d^UqP9;p&ro|(n*@~B;dsb21~2PU6aYb4qxR;SZxrs^=05;m-<6EhMu(_(k6 zT|P~q4QRH^?5C7hHYh@P@X&|)tbHiOC=;!oA4iC}(@YcUP~XyHnI4oG6PuSkG1(|^ zwsBGld_W-O+{zU4iXabDqn**bVve*RA8dKo0H1Fc8hhVE5j09HeGN(O*!0$pPzd>u z>TY1sLYa@Ase>Qr13GacdUCf5#}W&AGHlMnSx9ce_9;oAwU$1x>vO^lq0rh9r_LAh zr-*wVpXyrJZaQK7>Y)dm?{Nz+>0U_2Nq6l5moiy5;Yg@icZR(m$5+r@hwJr?`&Ua1mxi-3`G9TBy41Q2h+8V0obbpC>|7;XW9^ip3nJy+}yUzW%vnbmU1a2p!WU%WS8_q>M3-*ok}x0>PBBlQW|udV+8 DzrCQ} From 2cb17be7ca1f800357239ad9494a8679d26ffcc4 Mon Sep 17 00:00:00 2001 From: lmtaek Date: Tue, 17 Sep 2019 21:51:36 +0800 Subject: [PATCH 056/420] Returned necessary files to repo in order to do pull request --- build/reports/checkstyle/main.html | 958 +++++++++++++++++++++++++++++ build/reports/checkstyle/main.xml | 258 ++++++++ build/reports/checkstyle/test.html | 298 +++++++++ build/reports/checkstyle/test.xml | 66 ++ 4 files changed, 1580 insertions(+) create mode 100644 build/reports/checkstyle/main.html create mode 100644 build/reports/checkstyle/main.xml create mode 100644 build/reports/checkstyle/test.html create mode 100644 build/reports/checkstyle/test.xml diff --git a/build/reports/checkstyle/main.html b/build/reports/checkstyle/main.html new file mode 100644 index 0000000000..9410402449 --- /dev/null +++ b/build/reports/checkstyle/main.html @@ -0,0 +1,958 @@ + + + + + + + + + + + + + + +
+

CheckStyle Audit

+
Designed for use with CheckStyle and Ant.
+
+

Summary

+ + + + + + + +
FilesErrors
26203
+
+

Files

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameErrors
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\Parser.java94
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\Task.java15
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\AddCommand.java13
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\DateTimeParser.java11
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\RescheduleCommand.java10
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\Ui.java7
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\RecurringCommand.java6
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\Storage.java6
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\Duke.java5
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\FixedDurationTask.java4
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\PeriodTask.java4
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\RemindCommand.java3
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\ViewCommand.java3
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\Deadline.java3
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\Event.java3
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\Todo.java3
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\Reminder.java2
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\DeleteCommand.java2
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\DoneCommand.java2
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\ExitCommand.java2
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\FindCommand.java2
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\ListCommand.java2
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\Command.java1
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\FindFreeTimesCommand.java0
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\DukeException.java0
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\TaskList.java0
+
+ +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\Duke.java

+ + + + + + + + + + + + + + + + + + + +
Error DescriptionLine
Using the '.*' form of import should be avoided - duke.core.*.5
WhitespaceAround: '{' is not preceded with whitespace.11
'CTOR_DEF' should be separated from previous statement.32
First sentence of Javadoc is missing an ending period.65
'METHOD_DEF' should be separated from previous statement.71
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\Reminder.java

+ + + + + + + + + + +
Error DescriptionLine
'CTOR_DEF' should be separated from previous statement.38
'{' at column 21 should be on the previous line.54
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\AddCommand.java

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Error DescriptionLine
First sentence of Javadoc is missing an ending period.24
First sentence of Javadoc is missing an ending period.40
Line continuation have incorrect indentation level, expected level should be 4.44
Line is longer than 120 characters (found 129).67
')' is preceded with whitespace.67
WhitespaceAround: '{' is not preceded with whitespace.67
',' is preceded with whitespace.75
';' is preceded with whitespace.77
')' is preceded with whitespace.81
WhitespaceAround: '}' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)94
WhitespaceAround: 'else' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)94
WhitespaceAround: 'else' is not preceded with whitespace.94
WhitespaceAround: '{' is not preceded with whitespace.94
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\Command.java

+ + + + + + + +
Error DescriptionLine
Line continuation have incorrect indentation level, expected level should be 4.30
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\DeleteCommand.java

+ + + + + + + + + + +
Error DescriptionLine
First sentence of Javadoc is missing an ending period.31
Line continuation have incorrect indentation level, expected level should be 4.35
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\DoneCommand.java

+ + + + + + + + + + +
Error DescriptionLine
First sentence of Javadoc is missing an ending period.30
Line continuation have incorrect indentation level, expected level should be 4.34
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\ExitCommand.java

+ + + + + + + + + + +
Error DescriptionLine
First sentence of Javadoc is missing an ending period.20
Line continuation have incorrect indentation level, expected level should be 4.24
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\FindCommand.java

+ + + + + + + + + + +
Error DescriptionLine
First sentence of Javadoc is missing an ending period.29
Line continuation have incorrect indentation level, expected level should be 4.33
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\FindFreeTimesCommand.java

+ + + + +
Error DescriptionLine
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\ListCommand.java

+ + + + + + + + + + +
Error DescriptionLine
First sentence of Javadoc is missing an ending period.21
Line continuation have incorrect indentation level, expected level should be 4.25
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\RecurringCommand.java

+ + + + + + + + + + + + + + + + + + + + + + +
Error DescriptionLine
Using the '.*' form of import should be avoided - duke.task.*.7
First sentence of Javadoc is missing an ending period.23
Line continuation have incorrect indentation level, expected level should be 4.27
'{' at column 29 should have line break after.30
'}' at column 45 should be alone on a line.30
Empty line should be followed by <p> tag on the next line.34
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\RemindCommand.java

+ + + + + + + + + + + + + +
Error DescriptionLine
'CTOR_DEF' should be separated from previous statement.21
First sentence of Javadoc is missing an ending period.26
Line continuation have incorrect indentation level, expected level should be 4.30
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\RescheduleCommand.java

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Error DescriptionLine
Line is longer than 120 characters (found 127).23
WhitespaceAround: 'try' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)40
WhitespaceAround: '{' is not preceded with whitespace.40
WhitespaceAround: '{' is not preceded with whitespace.42
WhitespaceAround: '}' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)48
WhitespaceAround: 'catch' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)48
WhitespaceAround: 'catch' is not preceded with whitespace.48
WhitespaceAround: '{' is not preceded with whitespace.48
First sentence of Javadoc is missing an ending period.53
Line continuation have incorrect indentation level, expected level should be 4.57
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\ViewCommand.java

+ + + + + + + + + + + + + +
Error DescriptionLine
'(' is preceded with whitespace.16
First sentence of Javadoc is missing an ending period.23
Line continuation have incorrect indentation level, expected level should be 4.27
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\DateTimeParser.java

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Error DescriptionLine
Javadoc comment at column 19 has parse error. Missed HTML close tag 'code'. Sometimes it means that close tag missed for one of previous tags.9
Line is longer than 120 characters (found 128).33
Line is longer than 120 characters (found 128).34
Line is longer than 120 characters (found 128).35
Line is longer than 120 characters (found 128).36
WhitespaceAround: 'try' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)38
WhitespaceAround: '{' is not preceded with whitespace.38
WhitespaceAround: '}' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)50
WhitespaceAround: 'catch' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)50
WhitespaceAround: 'catch' is not preceded with whitespace.50
WhitespaceAround: '{' is not preceded with whitespace.50
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\DukeException.java

+ + + + +
Error DescriptionLine
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\Parser.java

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Error DescriptionLine
Using the '.*' form of import should be avoided - duke.command.*.3
Using the '.*' form of import should be avoided - duke.task.*.4
'case' child has incorrect indentation level 12, expected level should be 8.28
'block' child has incorrect indentation level 16, expected level should be 12.29
'case' child has incorrect indentation level 12, expected level should be 8.30
'try' has incorrect indentation level 16, expected level should be 12.31
'try' child has incorrect indentation level 20, expected level should be 16.32
'try' child has incorrect indentation level 20, expected level should be 16.33
'try rcurly' has incorrect indentation level 16, expected level should be 12.34
'catch' child has incorrect indentation level 20, expected level should be 16.35
'catch rcurly' has incorrect indentation level 16, expected level should be 12.36
'case' child has incorrect indentation level 12, expected level should be 8.37
'try' has incorrect indentation level 16, expected level should be 12.38
'try' child has incorrect indentation level 20, expected level should be 16.39
'try' child has incorrect indentation level 20, expected level should be 16.40
'try rcurly' has incorrect indentation level 16, expected level should be 12.41
'catch' child has incorrect indentation level 20, expected level should be 16.42
'catch rcurly' has incorrect indentation level 16, expected level should be 12.43
'case' child has incorrect indentation level 12, expected level should be 8.44
'try' has incorrect indentation level 16, expected level should be 12.45
'try' child has incorrect indentation level 20, expected level should be 16.46
'try' child has incorrect indentation level 20, expected level should be 16.47
'try rcurly' has incorrect indentation level 16, expected level should be 12.48
'catch' child has incorrect indentation level 20, expected level should be 16.49
'catch rcurly' has incorrect indentation level 16, expected level should be 12.50
'case' child has incorrect indentation level 12, expected level should be 8.51
'try' has incorrect indentation level 16, expected level should be 12.52
'try' child has incorrect indentation level 20, expected level should be 16.53
'try' child has incorrect indentation level 20, expected level should be 16.54
'try' child has incorrect indentation level 20, expected level should be 16.55
'try rcurly' has incorrect indentation level 16, expected level should be 12.56
'}' at column 17 should be on the same line as the next part of a multi-block statement (one that directly contains multiple blocks: if/else-if/else, do/while or try/catch/finally).56
'catch' has incorrect indentation level 17, expected level should be 12.57
'catch' child has incorrect indentation level 20, expected level should be 16.58
'catch rcurly' has incorrect indentation level 17, expected level should be 12.59
'case' child has incorrect indentation level 12, expected level should be 8.60
'try' has incorrect indentation level 16, expected level should be 12.61
'try' child has incorrect indentation level 20, expected level should be 16.62
'try' child has incorrect indentation level 20, expected level should be 16.63
'try' child has incorrect indentation level 20, expected level should be 16.64
'try rcurly' has incorrect indentation level 16, expected level should be 12.65
'catch' child has incorrect indentation level 20, expected level should be 16.66
'catch rcurly' has incorrect indentation level 16, expected level should be 12.67
'case' child has incorrect indentation level 12, expected level should be 8.68
'try' has incorrect indentation level 16, expected level should be 12.69
'try' child has incorrect indentation level 20, expected level should be 16.70
'try' child has incorrect indentation level 20, expected level should be 16.71
'try' child has incorrect indentation level 20, expected level should be 16.72
'try rcurly' has incorrect indentation level 16, expected level should be 12.73
'catch' child has incorrect indentation level 20, expected level should be 16.74
'catch rcurly' has incorrect indentation level 16, expected level should be 12.75
'case' child has incorrect indentation level 12, expected level should be 8.76
'try' has incorrect indentation level 16, expected level should be 12.77
'try' child has incorrect indentation level 20, expected level should be 16.78
'try' child has incorrect indentation level 20, expected level should be 16.79
'try' child has incorrect indentation level 20, expected level should be 16.80
'try' child has incorrect indentation level 20, expected level should be 16.81
'try rcurly' has incorrect indentation level 16, expected level should be 12.82
WhitespaceAround: '}' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)82
WhitespaceAround: 'catch' is not preceded with whitespace.82
'catch' child has incorrect indentation level 20, expected level should be 16.83
Line is longer than 120 characters (found 181).83
'catch rcurly' has incorrect indentation level 16, expected level should be 12.85
'case' child has incorrect indentation level 12, expected level should be 8.86
'block' child has incorrect indentation level 16, expected level should be 12.87
'case' child has incorrect indentation level 12, expected level should be 8.88
'try' has incorrect indentation level 16, expected level should be 12.89
'try' child has incorrect indentation level 20, expected level should be 16.90
'try' child has incorrect indentation level 20, expected level should be 16.91
'try rcurly' has incorrect indentation level 16, expected level should be 12.92
'catch' child has incorrect indentation level 20, expected level should be 16.93
Line is longer than 120 characters (found 156).93
'catch rcurly' has incorrect indentation level 16, expected level should be 12.94
'case' child has incorrect indentation level 12, expected level should be 8.95
'try' has incorrect indentation level 16, expected level should be 12.96
'try' child has incorrect indentation level 20, expected level should be 16.97
'try' child has incorrect indentation level 20, expected level should be 16.98
'try' child has incorrect indentation level 20, expected level should be 16.99
'try' child has incorrect indentation level 20, expected level should be 16.100
'try rcurly' has incorrect indentation level 16, expected level should be 12.102
'catch' child has incorrect indentation level 20, expected level should be 16.103
'catch rcurly' has incorrect indentation level 16, expected level should be 12.104
'case' child has incorrect indentation level 12, expected level should be 8.105
Fall through from previous branch of the switch statement.105
'try' has incorrect indentation level 16, expected level should be 12.106
'try' child has incorrect indentation level 20, expected level should be 16.107
'try' child has incorrect indentation level 20, expected level should be 16.108
'try rcurly' has incorrect indentation level 16, expected level should be 12.109
'catch' child has incorrect indentation level 20, expected level should be 16.110
'catch rcurly' has incorrect indentation level 16, expected level should be 12.111
'case' child has incorrect indentation level 12, expected level should be 8.112
'block' child has incorrect indentation level 16, expected level should be 12.113
'case' child has incorrect indentation level 12, expected level should be 8.114
'block' child has incorrect indentation level 16, expected level should be 12.115
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\Storage.java

+ + + + + + + + + + + + + + + + + + + + + + +
Error DescriptionLine
Using the '.*' form of import should be avoided - duke.task.*.3
'}' at column 17 should be on the same line as the next part of a multi-block statement (one that directly contains multiple blocks: if/else-if/else, do/while or try/catch/finally).54
'}' at column 17 should be on the same line as the next part of a multi-block statement (one that directly contains multiple blocks: if/else-if/else, do/while or try/catch/finally).64
'}' at column 17 should be on the same line as the next part of a multi-block statement (one that directly contains multiple blocks: if/else-if/else, do/while or try/catch/finally).74
WhitespaceAround: '}' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)82
WhitespaceAround: 'else' is not preceded with whitespace.82
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\TaskList.java

+ + + + +
Error DescriptionLine
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\Ui.java

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Error DescriptionLine
First sentence of Javadoc is missing an ending period.10
Unused Javadoc tag.104
'(' is preceded with whitespace.106
Comment has incorrect indentation level 0, expected is 8, indentation should be the same level as line 114.116
'(' is preceded with whitespace.141
',' is preceded with whitespace.141
Missing a Javadoc comment.159
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\Deadline.java

+ + + + + + + + + + + + + +
Error DescriptionLine
First sentence of Javadoc is missing an ending period.34
Line continuation have incorrect indentation level, expected level should be 4.38
First sentence of Javadoc is missing an ending period.45
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\Event.java

+ + + + + + + + + + + + + +
Error DescriptionLine
First sentence of Javadoc is missing an ending period.32
Line continuation have incorrect indentation level, expected level should be 4.36
First sentence of Javadoc is missing an ending period.43
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\FixedDurationTask.java

+ + + + + + + + + + + + + + + + +
Error DescriptionLine
First sentence of Javadoc is missing an ending period.4
Summary javadoc is missing.21
Line continuation have incorrect indentation level, expected level should be 4.24
First sentence of Javadoc is missing an ending period.31
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\PeriodTask.java

+ + + + + + + + + + + + + + + + +
Error DescriptionLine
Unused @param tag for 'startTime'.26
First sentence of Javadoc is missing an ending period.37
Line continuation have incorrect indentation level, expected level should be 4.41
First sentence of Javadoc is missing an ending period.50
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\Task.java

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Error DescriptionLine
First sentence of Javadoc is missing an ending period.25
First sentence of Javadoc is missing an ending period.29
First sentence of Javadoc is missing an ending period.57
First sentence of Javadoc is missing an ending period.66
'{' at column 37 should have line break after.83
'}' at column 59 should be alone on a line.83
'{' at column 38 should have line break after.88
'}' at column 60 should be alone on a line.88
')' is preceded with whitespace.100
'{' at column 43 should have line break after.103
Line continuation have incorrect indentation level, expected level should be 4.125
Comment has incorrect indentation level 0, expected is 4, indentation should be the same level as line 164.158
Javadoc comment at column 19 has parse error. Missed HTML close tag 'code'. Sometimes it means that close tag missed for one of previous tags.161
'{' at column 5 should be on the previous line.174
'{' at column 37 should have line break after.175
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\Todo.java

+ + + + + + + + + + + + + +
Error DescriptionLine
First sentence of Javadoc is missing an ending period.18
Line continuation have incorrect indentation level, expected level should be 4.22
First sentence of Javadoc is missing an ending period.29
+ Back to top +
+ + diff --git a/build/reports/checkstyle/main.xml b/build/reports/checkstyle/main.xml new file mode 100644 index 0000000000..777ddd1884 --- /dev/null +++ b/build/reports/checkstyle/main.xml @@ -0,0 +1,258 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/reports/checkstyle/test.html b/build/reports/checkstyle/test.html new file mode 100644 index 0000000000..10e2dd1b81 --- /dev/null +++ b/build/reports/checkstyle/test.html @@ -0,0 +1,298 @@ + + + + + + + + + + + + + + +
+

CheckStyle Audit

+
Designed for use with CheckStyle and Ant.
+
+

Summary

+ + + + + + + +
FilesErrors
553
+
+

Files

+ + + + + + + + + + + + + + + + + + + +
NameErrors
C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\task\DeadlineTest.java15
C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\task\EventTest.java15
C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\task\TodoTest.java10
C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\core\ParserTest.java7
C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\task\PeriodTaskTest.java6
+
+ +

File C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\core\ParserTest.java

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Error DescriptionLine
Using the '.*' form of import should be avoided - duke.command.*.3
Distance between variable 'c4' declaration and its first usage is 4, but allowed 3. Consider making that variable final if you still need to store its value in advance (before method calls that might have side effects on the original value).18
Distance between variable 'c5' declaration and its first usage is 5, but allowed 3. Consider making that variable final if you still need to store its value in advance (before method calls that might have side effects on the original value).19
Distance between variable 'c6' declaration and its first usage is 6, but allowed 3. Consider making that variable final if you still need to store its value in advance (before method calls that might have side effects on the original value).20
Distance between variable 'c7' declaration and its first usage is 7, but allowed 3. Consider making that variable final if you still need to store its value in advance (before method calls that might have side effects on the original value).21
Distance between variable 'c8' declaration and its first usage is 8, but allowed 3. Consider making that variable final if you still need to store its value in advance (before method calls that might have side effects on the original value).22
Distance between variable 'c9' declaration and its first usage is 9, but allowed 3. Consider making that variable final if you still need to store its value in advance (before method calls that might have side effects on the original value).23
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\task\DeadlineTest.java

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Error DescriptionLine
Using the '.*' form of import should be avoided - org.junit.jupiter.api.Assertions.*.6
Line is longer than 120 characters (found 163).16
Unicode escape(s) usage should be avoided.16
'(' is followed by whitespace.16
Line is longer than 120 characters (found 173).24
'(' is followed by whitespace.24
Line is longer than 120 characters (found 145).50
Unicode escape(s) usage should be avoided.50
'(' is followed by whitespace.50
Line is longer than 120 characters (found 134).51
'(' is followed by whitespace.51
Line is longer than 120 characters (found 146).56
Unicode escape(s) usage should be avoided.56
Line is longer than 120 characters (found 126).57
'(' is followed by whitespace.57
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\task\EventTest.java

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Error DescriptionLine
Using the '.*' form of import should be avoided - org.junit.jupiter.api.Assertions.*.7
Method name 'EventStringTest' must match pattern '^[a-z][a-z0-9][a-zA-Z0-9_]*$'.15
Line is longer than 120 characters (found 168).16
Unicode escape(s) usage should be avoided.16
Line is longer than 120 characters (found 154).24
'(' is followed by whitespace.24
Line is longer than 120 characters (found 139).50
Unicode escape(s) usage should be avoided.50
'(' is followed by whitespace.50
Line is longer than 120 characters (found 128).51
'(' is followed by whitespace.51
Line is longer than 120 characters (found 137).56
Unicode escape(s) usage should be avoided.56
Line is longer than 120 characters (found 128).57
'(' is followed by whitespace.57
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\task\PeriodTaskTest.java

+ + + + + + + + + + + + + + + + + + + + + + +
Error DescriptionLine
Using the '.*' form of import should be avoided - org.junit.jupiter.api.Assertions.*.6
Method name 'PeriodTaskStringTest' must match pattern '^[a-z][a-z0-9][a-zA-Z0-9_]*$'.14
Line is longer than 120 characters (found 229).15
Unicode escape(s) usage should be avoided.15
Line is longer than 120 characters (found 208).23
'(' is followed by whitespace.23
+ Back to top +

File C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\task\TodoTest.java

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Error DescriptionLine
Using the '.*' form of import should be avoided - org.junit.jupiter.api.Assertions.*.6
WhitespaceAround: '{' is not preceded with whitespace.15
Unicode escape(s) usage should be avoided.16
Line is longer than 120 characters (found 124).24
'(' is followed by whitespace.24
Unicode escape(s) usage should be avoided.50
'(' is followed by whitespace.50
'(' is followed by whitespace.51
Unicode escape(s) usage should be avoided.56
'(' is followed by whitespace.57
+ Back to top +
+ + diff --git a/build/reports/checkstyle/test.xml b/build/reports/checkstyle/test.xml new file mode 100644 index 0000000000..ebc36f73b5 --- /dev/null +++ b/build/reports/checkstyle/test.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From af34a41b639c4c472baa7b548429f17e378b2097 Mon Sep 17 00:00:00 2001 From: Qian Jie Date: Wed, 18 Sep 2019 08:19:07 +0800 Subject: [PATCH 057/420] added Ui mock up to README --- README.adoc | 34 ++++++++++++++++++++++++++++++++++ README.md | 44 -------------------------------------------- docs/images/Ui.png | Bin 0 -> 283921 bytes 3 files changed, 34 insertions(+), 44 deletions(-) create mode 100644 README.adoc delete mode 100644 README.md create mode 100644 docs/images/Ui.png diff --git a/README.adoc b/README.adoc new file mode 100644 index 0000000000..94be4fa10a --- /dev/null +++ b/README.adoc @@ -0,0 +1,34 @@ += Dukepital +ifdef::env-github,env-browser[:relfileprefix: docs/] + +//https://travis-ci.org/AY1920S1-CS2103-F09-1/main[image:https://travis-ci.org/se-edu/addressbook-level3.svg?branch=master[Build Status]] +//https://ci.appveyor.com/project/ChrisKheng/main/branch/master[image:https://ci.appveyor.com/api/projects/status/7xipch56f5hpgwqw/branch/master?svg=true[Build status]] +//https://coveralls.io/github/AY1920S1-CS2103-F09-1/main?branch=master[image:https://coveralls.io/repos/github/AY1920S1-CS2103-F09-1/main/badge.svg?branch=master[Coverage Status]] +//https://gitter.im/se-edu/Lobby[image:https://badges.gitter.im/se-edu/Lobby.svg[Gitter chat]] + +ifdef::env-github[] +image::docs/images/Ui.png[width="600"] +endif::[] + +ifndef::env-github[] +image::docs/images/Ui.png[width="600"] +endif::[] + +* This is an application used mainly for the nurse at the hospital. It has a GUI but most of the user interactions happen using CLI. +* The purpose of this application is to help the nurse to manage their tasks better. +* It is written in OOP fashion. It provides a reasonably well-written code example that is significantly bigger (around 6 KLoC)than what students usually write in beginner-level SE modules +== Site Map + +* «UserGuide#, User Guide» +* «DeveloperGuide#, Developer Guide» +* «LearningOutcomes#, Learning Outcomes»About +* «AboutUs ,#AboutUs,» +* «ContactUs#, Contact Us» + +== Acknowledgements + +* Some parts of this sample application were inspired by the excellent http://code.makery.ch/library/javafx-8-tutorial/[Java FX tutorial] by +_Marco Jakob_. +* Libraries used: https://openjfx.io/[JavaFX], https://github.com/FasterXML/jackson[Jackson], https://github.com/junit-team/junit5[JUnit5] + +== Licence : link:LICENSE[MIT] \ No newline at end of file diff --git a/README.md b/README.md deleted file mode 100644 index e818611f28..0000000000 --- a/README.md +++ /dev/null @@ -1,44 +0,0 @@ -# Links - -**Team Google Doc link** -https://docs.google.com/document/d/1G6Bvc2kW0bpxYXVxCz2mC2vUknmPyHRZJHdE9Et25LQ/edit?usp=sharing - -# Setting up - -**Prerequisites** - -* JDK 11 -* Recommended: IntelliJ IDE -* Fork this repo to your GitHub account and clone the fork to your computer - -**Importing the project into IntelliJ** - -1. Open IntelliJ (if you are not in the welcome screen, click `File` > `Close Project` to close the existing project dialog first). -1. Set up the correct JDK version. - * Click `Configure` > `Structure for new Projects` (in older versions of Intellij:`Configure` > `Project Defaults` > `Project Structure`). - * If JDK 11 is listed in the drop down, select it. If it is not, click `New...` and select the directory where you installed JDK 11. - * Click `OK`. -1. Click `Import Project`. -1. Locate the project directory and click `OK`. -1. Select `Create project from existing sources` and click `Next`. -1. Rename the project if you want. Click `Next`. -1. Ensure that your src folder is checked. Keep clicking `Next`. -1. Click `Finish`. - -# Tutorials - -Duke Increment | Tutorial ----------------|--------------- -`A-Gradle` | [Gradle Tutorial](tutorials/gradleTutorial.md) -`A-TextUiTesting` | [Text UI Testing Tutorial](tutorials/textUiTestingTutorial.md) -`Level-10` | JavaFX tutorials:
→ [Part 1: Introduction to JavaFX][fx1]
→ [Part 2: Creating a GUI for Duke][fx2]
→ [Part 3: Interacting with the user][fx3]
→ [Part 4: Introduction to FXML][fx4] - -[fx1]: -[fx2]: -[fx3]: -[fx4]: - -# Feedback, Bug Reports - -* If you have feedback or bug reports, please post in [se-edu/duke issue tracker](https://github.com/se-edu/duke/issues). -* We welcome pull requests too. \ No newline at end of file diff --git a/docs/images/Ui.png b/docs/images/Ui.png new file mode 100644 index 0000000000000000000000000000000000000000..b38d453c3f963194215a1041f5de0d6ffc56aa30 GIT binary patch literal 283921 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

X<{Q98?$}#;uHozOH@j_trk6>oaNnZIqF!)9(F@ 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�A`K6y-+hZ8zX#ibR(9dKJ{o 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 Date: Wed, 18 Sep 2019 08:47:41 +0800 Subject: [PATCH 058/420] added JavaDoc comments to AddCommand --- docs/images/Ui.png | Bin 283921 -> 841266 bytes src/main/java/duke/command/AddCommand.java | 13 ++++++++++--- src/main/java/duke/core/Ui.java | 2 -- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/docs/images/Ui.png b/docs/images/Ui.png index b38d453c3f963194215a1041f5de0d6ffc56aa30..e8b7a221cb2371a6b937db2f3b5c27c650ee5e3d 100644 GIT binary patch literal 841266 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 trKe{Pm&F?4%c&Q42E{hV1S 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%0APnk5Q@E%{ezuVi%MhyQP75(ES_8R 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

;He&u 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�ibnws-r;OWRKq%n>bJg(iX!YvVjrD8c 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�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�+AxAG|L?q_PgX5CnwBToHD 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

~#aTcb*>E1-6 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'zSyo`hWN4N~ibp7ZEr<4D#p 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 literal 0 HcmV?d00001 diff --git a/docs/images/lmtaek.png b/docs/images/lmtaek.png new file mode 100644 index 0000000000000000000000000000000000000000..d05e9657637d8d69429788d3b084ff91441f0691 GIT binary patch literal 24310 zcmbT7Ra9Hix9)>G6bVIwdyrzmU4v@^#fm$W;8KcP8oW@fcyMKyzwGt$+iQ%q=bYa+|E~Sr1jGUe@$m`p@dybB2#AOXiAib5NJ&UY z>8YqGXqXsSn3)(rAXZKx9#(b%4iJb}l21TbL|j~)g-2RmN>olrOk5O;h=_=kgp`hq zj82pd#3uUx9Dn-(l!RDmSZO#|>;P;^EF4O#zr$Fi000&q)_(=ye+L#e4lW)(0U;4F z$s+(Z77h+JE)E_ZF7Cgb;s4$Na4GSq*hG}^sg3Li*by|MQRyXw94gHNK;wlgPBDAm zXd+_T$8_`zT--dod|+{igrtaaRbA84+ScCD+11@MI5a#mIyOErxwy2vf>~W# z-}tn*e{gtod~$kree?D9?%VzM9}idnod3r8_xx|5|AU9}9}hMzE)Fiie|WI4gZ?cX zN?bfP5qv6TBLX`FHM?jOA&p9UN%H^^hnVpd(B5}}n3hxg6W8^Bkp7G4{|+en|BL8< zfc}T)?*@Pr2kYN~;ZOn;0XM0v)ic_hqyQXR; zi0M&lrs^W?3$J!qRIw)OcR1B-gG!@3m>4Wuh)DT8-Ha`iN8D%F%{PA`B^}U?Tkc{_ z(yGV=qbYl<2FG`zeWT_G_%J^xtT)9?Z}0U~1w~igXs;X38qt9G%7Oe-x98g0VaQ&Z zL1S`7?HEszN1UWfw8kI&5l}L7?$qf`qh}3Ad#!i_RF0gaBj5rUw zYDGGc^o13s%^cBri?Ws^D#XV>)mO7tG~&O?wJ=Y7%Z{ zy)@G9ppXzoYZ@ES0o!NvV8IO~YdLj4>Z#~M%3~xxtNA`*nm8)$&3KxKt;?bfU$*MW zfF?z?F(f7SW9Kuq)uX0Aj(Jjkcbvv`J7-(c6bqj=4}3Ff82Aio}g| z_Q7(M=ubSD1E)8aLx-p;u#Q@f+s)qOrD*L)NO|)`pNAZ*jEY*s<+=k?aF&Ukmg4F0 zt9AHz;;TA)L5_Lt1YueBFxx)2k*xQpm33@o6@(oHFjofbPATs8dd%j;kHi@VnZnV$ z-hrQEK+)v+JcyNg*M*#^8`YOBJ(oAOp-Uq}*rIN}ZTPRNBra_br%yW{rxw`PaqT>c z=dRM9oP|~ro>y^l%y6XWDK9T2?PZ8$TB7Y2n~II24EUA%X)bZC$+VVD=uk^B&Y4(e zP>8#Ptu(}hpaHBNNPPv9dY>14?EJG$oJZQEPtL|y{>hvgG z_WO97Jz*8d_wiY+T0R35+AE#ylu!kmzO%Sy%dipn&-bN0PoH0KbXs`{A_qMuT9mQD z&&S-4FYhE$4uqtD_0M0lyeR+V?y@A<@ZLV8E=zsc?9u@}eLsyq)D|@2CTGOSF|99> z*RrT;M`WHRhJ}Kwo_UG)(o1}uN7hz00U;dEIeDh6!jMDe-y}TRy@aUk9WOm{f?vIreJxW)zQaYBY^-d67>u%yN!3L zbT3*KO|;i05Ww-v@ec&X{A6FM%EfRd=d9ag3$9W3keV}Mx~%POz}9u~G=1W*!@y!b z{n62_LZ~t zj-mlMjaa-IYSDf50U*gq-md0hj)){+3U~iyF`XfW*917>TcgpT{O)Cc(B^Q>xip*M zz{2mc)~b7!m^`wlV40G=po(2|XF=%G$ad|}U z5tX%T`{2u%>O~bWco?!fAMfN?a)_spyUTyyYl8;TjBoSxCUd)j@@h$gEPSu^*8-37 zl(Ew&c#s~(*t~K`{KPr#^3-~jUThxf+lobM&)q(7!m?Z$dnpbt`oVtc% z)4jhs)&F=%dNE#g+|4D{iA)I8!IBZ%2fCT|Tm{#`GmmC0qfbir<@qLsHgGgr`};%s zYIt6I-PH#qNPO-BW_u0wVm+-4AAl^!dFNsQ{y?0`;QqVKzw}J=wuVDZ?FQ(^AXe2e zT6yzl#glTg%J;QPeQjx97=y_DtkyNo@U)Zp`K%AK$rnmWP1#+&=+ zfJPai*sh)ijFDqN?FV(jz!i$N9v>naOgfs5yWOz)MX9o4&R>9}_5wUv6Li#yYpJhP zD?Ip120nEl(9cY})e2kb zxP!mcT!e0y{lUL3KMbAtNn`&)KTl`#?G!cmNxf%sMzh&d9uL9;ueHQq9CuQuPfaZG(nK35YEw^@K0ApE(l{j!9=EH0TcR91AV0wTX!m&K zK>sYCvl`^G(c*oJF&nT7bIwV8W1OqG^FveL?X*_=apQd=*h+XTHY*@wU&@`L$32uD+fA1@oS zaN9%Z{D57Qe9>=)>+N4ap%}R7`Infb+gdX!nJOyLxyL1+BCF|>5cJOsWf^L_qVD58 zd=gz0EG|`EUcU5%>&-MLBX2pX{sM^MVu&;3ZYHMa1JfDyrGm-4fB8<>B0{X$_Px4h zL1Ej9CsGBWqHK43ZYX?=^sx_~k)5(9VyelGVH-Hr2SoFYK;@9|)0Epw-1oNY$mAS` z=Ta4Eeo&c&#b{_THXq$r(|E~7h@7o+DGt(ylbP4n9IQomY7xj!XUIrj_uVooFP~Gw z^xAypnab0;DRN<@5k@;#?KoVFc~)mo?YEm!RQg<>{oVrkktgOrgbe{Re}u4R710)k z*KVzE#tIPP*Fa>W)0^D_qc_Q4J`bJsD9+3vpsyJFDkRo_Tk{6D%mF{EL6#v5ei1oi z^-4DiIx$dZ$s#o|iZEM0rXm}TGU44+8(y$C-_;5P2zwasVAe}!H4slL)}2y)(|eg} z*^h3{CavR=wO^$ZQM?7i%VbUw!2rQCZdV^}QoB5y+?1s$aZx&uD(Kfp){; zlk=~~dAVfy*>4lSymg^a4ez~ic+KATfR+2~@dt$AmbZQa?^S1x{!%L1BA#v%mEuwF zC9&zeh-75WN|%on(f5fUez_ui%q#dVJe)TW;Dr;liD}Rw1%KchF|vzyD16Inkp)By zUObReAU4oZ>p5Uwv55=Q9H#F)sTRFnH>2h+Y7{Ltz+-B#^iGc!2jRMd+2ae)7wU^4}579%<+w3B2+Dn^r zX$U;yrPr5ILpwdNy7H&g2UFIny+^owNtnQv(Iu(?{osadMN*O+Q&HN#fM8P0WkPXg zdn(9(B(USb(Y5%I*lpd9P4NTh_0$Id)o`8T{l$pg_II$3PlW%lOHt?p&rccAaxa!F z=Z~%n&{$8FEYPCT>!)8O%05*KPVm-g$Rdv`+w(rMIvF&EK0GnGTBH@A0bQfa-UcTO z0Yv!d_hUxf7~W1~@qZ3^EoQ(Nuk|eWbS6LsUb>q0LzI$@C``1D{G^4-0bUi77Fj*} zK+5wONHwqeIMAI)1tqE7NH=j*>H5cpH%&x`|GiQLRKe3&bLfU|R&M9qE(cV=vuI)N%pe|f7dRQqzmLX-A-Y|w50>rKG$V^6r2=QyvQ`z1&Tc0Y4P40?PAu)Ya$=B8 zch~>hL+7!dy=;FY>h|EbyK5tA@v%MjKFMePA~7K9YsQKlryZ5rhmdaWOg<)9``m_( zD5>`kGli^;@6Ywj6da!L0LQ-v&Q$P4_3!oRKsz4|ca8EFdVfBNZjrH8c$8iRKv*n9 zO4q##+C;w3_<3y{ZSm%wG@z<{h{8Q#hPe&%MxM-i+^E@RZ=FeBslmf&q4cfg0bK)n zGvzNJ*)+?ylA~TnT=!Z&Vu(dH?VTAxkn=b1fj5U7z*~hf=avL~#fq@ix92_Vx*32n zDfyaxi8x+9X2UmBs(gmSG(RghUQb%+ZGj%X!Xf-(cmw;mAb7A8pm4N@wvrznC?i#F z`AU8Kpi$9~A8hz2W;?>76W#eBR}+yy3NDkJ9UtqaspF{uAICGbN48YcZ!r)=HS()+UcONE_N09ojmYBAnuMqy8nc5*yf} zqF{DmKQjsYk^tt{%MFj&1xJMT)Fs{KXwcA_rhZVKVWo7%tu#H?+QH%!85@ z>$awm@tLl&U*}>CWWi0sg_zH28Lxrxwo!EUo5+(0`?1b!I)(OG_rOypMeMc@o#jq@ z#bH_jL8Mr}JfJ(W$yOs7h95*z+zGPneT$JNv$5X}LXd=C^xtSJGs86GYfYD!69nq{ zp%p4nV8ug>V8_VB92(whm`kz@gE?~m;d(UM+=b6xQ>SWIeY;W9ztZrq=r8>+Ewgey z&YDZ&1D0O4uG9NG>&$O^oTez#39_HhEPAt8zsc337ZY=8dY5ac&7KsGnB`X&a&ds3 zP5=B^+4IH^^ne9hiW>is3NX#rSln0msO<^1(c8LEA%e_jCD%P-`zq=_oIw_+*`Uxi z#?Fpd{u5m)pfu;F>-y4nmwfAACS0qdA3MQ2HxJhiXqX#(2(!|Ud9ELFS6A^l*{!y< z@9KSi%cGHyF?1lNDN6~@WT8%b7>VbfzWyl$I8!U>vh&X{e3ZE5Q}oEiO~%A%EYO$6nnJ}N9I>hsx~8ox@-q&WdoUC zXmU^D8Xj&MBJb1%waYTv{3SEyT&tztVf=+oC0-yaK+oq!Xr12ArghKKetgR;%SLD_ z8^6a*p4`3p%xZD#*VOMr_S!9$+iuNj?xM;M*;)#BWcv~2kLeFE71#p#TyqYXoC7fz z8W#>}8mw79q6~^&eJk4~Ja7k?fz`(=0qNVCJ)`EUXF$Y6#?$l);dobd*%HIL5-r#D z`&`CtiVDo$PDOb5qs3j*Kzy0<5o2ESF+i%;qiLM{)7~MhK;kj7j@F_R+3c zyDBTdPmQgpa7DbPSE*_}v8L->-ssA-Jl9`Vf1}PxVPrM9~#q9 zo~Qb$V>%((h4%Bd)`QT1k&@xy7FrbD!7TV~Y%_YO>vS2GBvewUqP2O8zDleYdWE-? zy^Xr9``JhI=?K)x1U?NE{gv^eYzLhHPoa<2S7xz56f_oF9ld4V`m|il+^!L}P6FJ% zS=HNP%$H4!2xptNO9O|vZd6fy@cU}CJMD0bY$V0iZ9{0di*ZLL zUO^R3$_l(&=;VQ|VgHQoQ8-`4DHMdf@)8?kh%2A8UN6JNMy>Dl5$Ipjn9bK!ZHGUY z%9B{UEz_^;s$!aVk;BNDeM<1Vt872HjIdA@H|GN}O!gW2$}F~jC-?%8_cJZ;Gs^@V zE8L0`NH%PGC#6U=GGf?ozF3*{eN040Mr*um-+#~FbmKk!YOw=dCRSS`y_Qo&SKf1c zE55zP8EQN=nHsuvGq3H=_nb{}Jb7@UG zVCO7~b#kXQ;j{}=_p)b2w$ViORF`!7hv1;1% zwQ_fluNd+~QyZ>snOkT)H_nt)6LNQoDHv`f9YXB#RwYgB_qpoWM?Z~!*;TIxUTE;n zfG~w(taNh8f_6w2Q7v`oU>+O@byhl>cl+(fc>hN5wuVR~p1&D!cDgq!ET7~Fm}^7U zsCvC^KFxH0nc<*&*>^Q>N(d?kmn(eY>PT6Yp=F@1+_g~u)LND?%yGxShv@laH{&Zo z?-6?TmTXo7P7w9oh!w|7FU`j%s`K?<0(#dZBb=b)+mfO&Kb*TSET>XbIs;8CMgFjN z8{KgrcP|67L*2wLEY4=f_YeuPcd9IHz9%p) z7yixvb~z6_H}Oi(i$#@Qs8e)+v$@(bYeuQ>%;=t=yIwbOUHd&kpGm`QAd!HMRO-~| zAai1(SUt`=zG5_FR=KJK5X~5cLi+f0-`1^*vY*6sA zS-u|+ZCt(kZ^6LL0h&??xs{Is&=onKl$`1S0Ui!XJ0^E!d^4%qqs?Ow0&cNJLkAS9 z>PFF;6lQS}We?P*dNp?gsYlJSj;i(dyJ@C67falqG9?|Q<7?;{GpK+wO@!t}c1m5w zu*;lTm)b}DL$9+v1(z!@t>Ok%+`T*7=S%^Q|GQp`(0(NT3s+=MJ9~%l zy|}&)={IY)n!t!vkvZjLa5cJYV4W82)YZF_2SfoT$8TX?Iwkroq<2 zmOAsN6}`YM%85E_kD+XfmLv1{D{_!egiK&qNv%9*$nRe=*5l6c27Ik)vG~u%F*xSs zB&{MX)UyDi2Q$5}UB>aP--Tx?-Mh3i%FlPh#=={n$A$W5Xla7hXyLjxCIzkGbZxtQ zA6bV3$z~vC^Lr>2T$#=)MG4r94pzYQC)m>W>G_j6CPv~hFSl|Mi(-55wytbYxuzN&&{L93>wMzB(uG=lOMUlcYH@_iXwP-C6Dp#UF(B5kE%#dn^ zY~Z-cn1B6woe*nsA;^oTvfi&g9NepR)8?Qk3@LXvpEND#klS{CXFa_r1(u$u@trz) zF;?^}^vj(kiAUo4uf^#QjwmaxW$g^nMgYTxsIkavkoKg{Uw}ov6d-JwAikCtry}eY zqQ-{Sf7$o@OmXjF`IsxhD)gVcV&#BZ#3%gDU33DiTE1s*sAIfFIaG@0HzAKC>~5mf zb;x?}c%ij{Q?0&P;};f>CMd1E2I`!QO1VnZRPsY`AdE2#2mZB>Nr7D;L+zQzXd(Nj zG!&zVy!<&Q9+C%>dN!r4uVw`*%2;4VGw!oPu3o7_ck@dU5Hs)1LMn+Cs~QMlQigR? zl@?Hg{2;>Q_Q!?h`%~p97?&-0hPV&`qn9P#3N9-EkimPKZX5&%Ym)U*XrXv9HUdn} zV5Re@pJ6YyhohK5pr%xnqc0xxj3xl6Z#Lqb_KH%Q=%`*Gh7S0Ko~vudRh9WM_v=Na ziQy=C&Fs(odQFL4eWEJdSmuyYkuxF+#n8&sAgjHaT=3zC?Wya#nv8j;@$DwWKt)+^ zt?eCMKRQLpFpdCGePJ6cIDO#q??3vjI$FFUkrwM)Eb7=5udui~b2_W&=R{k$mA$%4nLQs2UiQ}d z;UR$&De9rJmC~Nu;vB1byY`CfUbm{q%V6FgT6HFjsVfRbfA7q;Ah{%tEU|H&eYU^GK>r z@1U!p&ed=K(;=-gVxiLkxWpZqZ{1-Z>ed%xG(d#5u(TT9+{_V|z$ zV#VdG_Q~I8sRDyW>Xi$h&m#-(gx6{!FOGV$tM)?0)P(M~>3I6o7QUdGj+tttc!Zlc z(608<_*Z~AW3Ww}w^M^ys>KIy9iiFZd>Kl;QMeKBz?QD-mJuqlq08ghue6A^6V8`m zC7v{w^aJM?#^sJ**HEcfwf0OWSQAp`=jJ*_7ANR$#&f8D+DVH#YCi_fscDYWV96B5 zP?M=A1vW+bL*fqXm)P1-oChL%^;X3;CV5C%ExGATllI;({YM4mjonXtUz-$3G8$N9 z+yLx%^ugzrgr5W^B?IefyPX|52(TL{a!P}8?t6OmP$lFiQGf8l|N0Q*d>OPn3O{d!^b!Y~u9{=LEs3HfTYUCE}VI!m%V$BW(LJSycB ztq0zvs1ekCyfz^S7C9R$&)~$o|<7hvt!tt-X zi50r=y1xKl2p#kL*Bt(JsHPx1{q=zdSZ@6aEVmo?$pIMMn%eGoLji0QknTv7WDA#J zD4}0a{rP))3zo#O=}q)=ZAO-jt24dF7H6!%ePub={QDme3nmI!zpO=84U+To`bF^< zP}Aq9#t1;AVPSpHzVUjJJBvVl{jpkiI!#Iml}RD9GxICW9(~ZR9kEI|c0D)05R$&D z%KJihfC&=U`1%YWtTh8GGBG7MmNQdSDC<;&IBvUF5*$^m*EnxqHr0@?&e*?&ADwwv(0G!8Pu?^zQo>%!ZXUtx2iNA47S-2J@b4Jm)Q`>Yt}Q#}7wud)TcSYZc;N86_`-a57Yf1u!aL z{W_l(kD#C7Dm+rDlX8+zwsrhpf zUOj8T#GlIIff4`K{Zcu6BDDf6OQuzSAksYmVt_XrtuSqG4eZ(aC^zz4!+Io2Q_Q}w znS4QB`~|cvEMe6mS3k}sAL!diY<1Td80n~mTvigLXgmAu7eKRB^?6DW+B{mxKrZUz zJlt4>AO_iuo4_NNvU^|U+IH!^w*8`Ck(FT~1UJGbxqGk4HXIH8nb3*0&Ult4@zP>s z%rdE7Pujbr!yXk{umbCg^#+%*w=^C-HX*Bgk5y%;K=-WqGQwtzw2`S7KN!DV$Vt7L95*l(vGOvF3nScw=4x* zq(;nObk&#My2lVwcLVJ+13eus%0uZ2It@{G4QP4coH@S+ApSsV1#};F^iS33ax=kMEb>D#s1OW+k*RQwoW&? zX0Ixl=1N5Nh3C5wQbL}eeSg~L-M(pICl&ag7XG=*_dIFpHX2o_k~e>Ved~3$BRoj1 zics*7$afkE5Wmwu|{l$vKOIj$5=tx>v;kB?@ptslEBbi!Iv?8TVN!eDC zV08Ky%)8PMxq9_^DwrcdV*`Kh)y1xBmR~^_24-erVNkLWkjh#!<%2SdCf*CV>k$_ zz$`!bje)tN3$Y^j^us6Vr2@OMe3na$H@ey_Z}GJz@y826&4pf^{4B~bQ|S~L zBf{MWPM-y(S&Jj3IK-nSr;{L9t(<>gZ$g44q#XwCYIf`>nxTm09lU!&`$v_UI+Vqrr0!?pta)3QIZJLty=lA&BX#CnMCgKLGdrasPwT%9uK#CW znUV7di>4=Hi&vrS%jE@O*DPF_XW>%4_BWI;n!;TtU-LaCXA&v`iZlR zpA6=kSD(qiy0*$l8|=O5LQMxhN=$y2CR?5V3rNuR9sAk|h}m52b9|;s^^F>Dh%}?m z^rwmX0%fH1_^5~WH;e%K=)-vv(W7@i1{xdOG-_d{uG{} zqBg-_=a9KrD!X)03uWL*e@g=7Djc6|) zRZXOyK>)4~SPD%pVv@xOrc1=I4kmP1ch89nL?V>mpj_Asi(!;6b^~YR8>9*GX?y@^ zDIOm7^mIl7KbKPr_C4!pdwP|qpUq=TXSZVE1(%-Q-dd1+FWw~I+RQVzdf$=F^a2N| z($NJtOPG&0r)U6AqZt(JtKUEy_Q7P5i5`1zttPO9MeU zv}d9p#Hc0>+~div#$&tAD4vBj#C|j}F;)s-V~>ROO9R7(9&%Go?H!_tfEJ%?*M`4y z#hcyz1)O69%*dXCJ{f4INKM#%-02WxTf-um(J~|XNWSJS;@Q=yNq?TA zxo^JsLcU42O~LiqW$o^&dCQBp?%eNgQm6I#)rO1sMmuB5U?cC*;s)znhC>f<*m3+_ zSb!Amy;6|IMg)iT;mYB=vU?;&36lr*B{YT#<+jbpojW{*k0u)0(C@mn`vWo7d8=@TQxSvrGy!(cdAF}oBNJ-&3Icc)hS)!>-qO&jVIeYrGSj~ z(pS1Met`6GEf1FWP{xg8my<;bhv2^{^&Ydq6UQoWfOIGR9(JrQPJ^=A^)7{KA&mxb zNf+r(mM;&2MqEdTSSjab3Sd&10^u^qliOZcZv4kjWB-H(bQItsEjZ~?gW5(tmdEuk>5rQdLbS8!0>tRI0|ixYgbB(OFN`a+*?2$?o$$M10`D-?_!TrR^)4` z5HJSa4zRi7O_6xse739Pq>s9EwCBWa)ypMDUw4wEp@!ud=hC$ddI`xF6%A{ax%%cX zx<^S^-X7kMO^w=2sy^36ThPL&AOrLjmx%#}1odWO9bX4VbjZ1JeaY;a2_zcZYo4`( zC}F7<{LKSm_SQeR%T->sW5=AE@NMwAs-bpM)FI?#!W{<6#=Kmiw$ABBEPeUXQq0kD zi3Pl8p+(w(KohAGw@)a?_cHUI37=8meNJ+*vv7APLZFt)U*6#RiUB0IdAV?~VWa~n znKcQg^i<0wLo`Vf#och~+# z=WRILk_fP6!Lj1E*iucBr=r=gUM1z--i~Wq1sOk;$R!ek1uZh^~faOp4M+QyO3Qext&>~SZeWlSnxkkv?ooQsIB{>l7HkBzzM z(u~uQ|GqxqT{US)DhDnxeu5?cdrJbG51*_xvPmUwgl9EblKn8vB2Faz3I%4W{OC54 zN8W%5NI`C$o{n#NO>NU1&tg#k!A2=qljCUY4w&eT+U4El`=lA+XF+Qg`R8H|_eG^V z*waL;99uG-qTSxAU-E5P%F4WZT9$${KDi9>@Y{|Ly8B2Wzd4oC64hw1))3(+o_0>) zEI4Rm3S~6YQ0`|w!Wv&~dQ|@oYCwmE()bP*$=LTz7Fvq!62HsVv}FY?H;?xE0_tU% z>hI&#on*4P#-~#7$BjkI-j9E$gEW5&Huna&oWi)6P44!Z1B7(4Mmm~E@qeuhw z4H+OF1Kn5D(Z3S-_{7j%+L7euiSoxj(N~gY__9U}1vr=%w9jN;l010i8k-K^cWo;I zZRG9q&p$$CJKR3D54Xe1r3pN$5z0SkHKHDK(w zQD%ee-v>g@>rygO>ZHf&wNyFiZ2d58CG^0I#^4tZT%`y%%+ z+~fUHKopptKk&dTUwxTjvpKDTUZ2d4(=%UQ=A*e4X#u=|q2=zQO~~_5DC5{3_{{3~ zb;MxBbZ^2-iVKN{MA>R{C z`Z#~%3QW|FDmdsq3kL@yq6#C8?Fk7PqfdC=Mu}g!a+wC{5mMi=FCIi!b7G7R1b$vB*V|=NvPgt!BesEX$FL z8QCX&Vj@?X*ep6X&c#k|pBM@R+Fy=ME?r!*3QTbOjcv=HCD(k6Tp-FX3Gr*jm9bidJJ@&cc!8Uxm&^kncDXP3tx-Nft zq{C31Bx8l`nTStCl2>kurnbLMYsy{FnW)s%=%$aJ*V74>H}QKVtte17(Bj*!#xUDh zyVH~Kb?R<3WO1~BWwO=folv<8FmF}YfV(6^Wm~GAO=B}zt=K4|%E68T?J` z+G?+tZCq}#?I!cS<}JBvP9MM&b+D43#f9}5%yv&Mvrn_2i`@OODC-Z~Wk6|W$)8Oq z13Pu&<-wMW{%Khg10WYn%^nm@6&F72Bg_2y#$4m$j;HrGp!j^w0a#NX0h>B_4Xlr^${rc>d&w$QZ>frM zZob%LWmxWn%yBq+Y9I_;`tNI+yRi$tKpmXkp2o#Pmp7vnB$})+X zsED1E%tK$y25l*PR6^tpb-f^U#3auGMV5e>{4RwRozWusbV#ebZW`H_&ikm;=b-|- zWIrc@lR~5`=6sn|(ot;kvU$Df&D=vA8H70JCbgW_620G~c4127(mW@8rmtnA-wu_C zlVuud- z6P~}ei1Aa3hRExhNTS~xi;f5RkH9e2?c2s-`Oy6o_K$-iy*Qb-yDuThP9dDvmKz$3 zM{Jw}hY57RMfu8g@g&Ecni<|CM1h@Hnj-asQ8<>M{+Iqg6bpCB3=3ZbFe)dP$2>d* zfep#KktpnQfGSF|EGQ8 z`-gr8vqZa$Lv|>HTtxJWv1pI!FW{|%fXoiJKEcd@f=Skh3hVDn=w8p;prO@J@^Va2 z(`&nX^YB&X;s>~&Qoa;$@?h`tcy}u25!TH=&&!LsoI6Nm(DQab6vjkvc20YdcAF;A z;v-3Ky^_gJeJ@ql1?<2W-@|m>4BRwO4o2vE7A~KR>bb(=Goy5Q#3fvDkj0Nc3~3Pc zS+`HVe5fod(>=Y~QH6F~UUa`-+$F-osG=~2OvLY`+ITdbtcJeA(2CrnT!$-VEkh*z zV|7iQe>Qk%vcquw=M8gF+;e3Qg?jcO2M>g7kcfumU%<*!iAyh<>|>E20$j?>6ImD* z9a6b4CdRs=cK0H5a!{vZi3ghY;-GQ6K`=)4$MZ;ns#-IW(zR&%>vx|FR156Wi)jV= zac+vVkt*|XrrW5%Q`M~rgm*Rjuc`is=h_6tZ(8_c5vdvvD@1A7=2T)2MjWDt6w1ba z0;d73WlJ)4S=!fJ&^shqIy1_c2)ZEbK`yaGkkR(>AI<5HcilR-ip(H z%0GY0I9p^#h#WCuWsNzp|3lilxW~n3?%4yqLQo^8~xg3CFsfW8t==i_knA_q& zLaR~q$ILa@CKY|&o=q69Jimgt=m&XzeY`DGQd}G5`)WQ0TzvDrKcIrlt@|1?;tD02 z%+dYd;K5Ho^h+f=l5^b@_Gw4IWk)2wQE;Ly^xW*C!rWoZ;lfDfF&kp3-u%(K5A0RP z)wk77{3YMg-XZdH7PL7WeF-2du1#AWADml6cvG15DYof3n-!BCH{B#RVn!V6u+zvN zcVhaUDP2u71oX8R$XRKN36xbEO%QArSCsi$)dk7mRW04FmArDDjQ`g}^1u(_EOb7Z zX@41$dYo4U+ii28!&i-aR$V(^)!v~lIQT@+5{*V#GMj6?sFKk@r!HS9)+_i;yKNV| zEcgr1jvnb8Ud8nj*%CYbXC*N?e%5+?m=u_LpUQJP!bbm+|LU$X(SN|hNBHnV057QI zuJP?%K4T+=d+X`yM2C6m?oc!H==;Jq_iv1Z{F-PL$0ICu6?nd@{-KhWz7%{E{(eTX znq>Obtl0x{wjOBoteVQ&fUxj^mHaZR;AXQ)aMZo;fD@aD1NfHy_Yn!g>Kg4-hDWXZ zR^I(_0DBA_M|@44&%aJoRc*@fL6u3AVabmgb$)G!tzcjnX#>97Px&g64zv~J7riFd zH8Eq{{>slorkj$)LXX*C_&pRP-(}6NVW*u-w&OTY_zT!m{VYF_|6#HU?)f#PaMHF0 z{ptw%=VNt@NDk*Ocl{DuCPMUG1|orqsv^{I3_#TOU@*-`|ZIb7jBg${Y{SYwh|$35-?6G ziv)J0xtq60a*+R`64B)~EFdS^i^_**@Q=mQUy^%hU=xH6Hm5uIy!D&=m)5kARZ;t_ z5u}khaeB~tZ;sdbkVDVm3x1}acAliWQETuP4aE3Svr~FV$b%Wn-cu578vmIf@0`Tn z{BhSb>P`e5;Obv0g=4aXT4Tz2wo{Vz+A$P!ss?K+2M(+^N=H2@@I)B-=R!Q)I>TR; zF?x18d9dc4NCB}+x^WhZ`oM!F0sm@mQthcXX@@B?yyw=@>%1aQ zHH5!{sAMicMOVMvMg`OP8e(^Vi_QF2k_v7=#`L{(11pKQ!Ld z^;#laoU)9%09EpHfS17y8Iv^4OBm7MWG#oY(9B=wuC;WcJNsN$h7m!;2S1xnAB=+7 zGN(GMj!fde8DWZ-U~!%Q1|`n995}*UIuDVB%emgpIjLC&*$Jo1eu%bJNV#eP}HWTKC5k@{ky0bD&gH>Au)!#CXX1e%$; zoySj2j_o#$1a}sq^hDnrl~fE)(>WfYHK_a|bNb9Gx-6nnyF^iZNUtxZYG^77Qs&1Z6HvXfX*njr0 zb)Vc5Wtx7k^9$EM#y(p84`v1Dp`+;Vn)Y%52QFc`mQd$DDr4?0zC!E>nc+;0&R3>S zsYH6GIEzLz&2U3Z-($O}wbCnR`q3K8tjdObVrf|;iHhk0Me=WQcdjEu9pbS*p#2_W z3Y}gz17|UIza#2(kbHWD(t@#=;~AqKIf}_7Pq?{muhd9@m&f~I(g-4xU$x|}6&@mO zFM30m+i9D%whk&2JhE}(cTK0zGY1KTIsv0HtJdi6Mqm0fUgqpS2bd{Wp2W*WIR%zY zbBMf`Li`aQ=w-IRcrN@vQm_Pvnl=|_GR8ChQ%i3Jg9eQ)oG%wd@n5WsT~k~)hmp;i8P+5FU-Q1q3Wfazz@a}9A}liIXIQ3IDC|Y~bw0=MZN&kY%a9}E z+w3c-kR$`El=jl}>jG1_p*Z}c+`o3Agr^di&xDrD1CU+yICyR} z;^z85!&b5E9r8v z!jf>0^#(Z>H}dic8YNDV1c9*3G=i@Un!|aHfmPL{!9v6P4S;_x+y9iq(Hr)IamPFL z{VsCcekXY5VS!NHKjs`#a;DTaG7g`QpEIee_KNF|e7DQ7ofA$rupR?C>ufT*Ua?F^ z80|E{rH_4PbrcOP^Dr$7%unsLq|+w?ahg~Tj1Mn`!aPMTy&>2@2j0E}Uw*%#_sm}b z-8puCy_|vdg#M1NrlNu~^!LA;bvK|a1q_GW=*9{L*;0nOe?`?m6C|cA-;b`?Ik-mMjAremD2UmdNHtlG_u04`>r@ph%g64`abY z^TA3v^dQ!tTAjtTli4BETkgpnB=nY^1G%on?D1>u&&k0*bzclI@ldg6r2rZxj9C!7!acHdj_5<`fPyk zXO-OQ9~Jbw7fPle@p6q1seb{M;=^1e_|ig&MmZ8jUmgm4v|5FyU2}lKNyS+Y zm7kB+Ll7tz!mbN*Kb!!mmSlspoUi80?-Ld0v;p(24k13?mWj(=iD5y{N71hWR!-B3 zwuYg~XWN?(rpA*UX#%bYfmn8|^FKI^pG@=wLcNfMfmOt1z0^zB+>wG-vo%UMLNpoj zfX27)g@cvblAQuP934EuvNK5rwLX45|FJrs=TF7yd5s5X1e=Gx$ZVDb~KI?_9SBQeP6tI zJG6e@&RDocJ}#K0|Kjll!^KfG_*eFIENcII((&z|fG?6L;G*tTC4NUmTNeo^zbu`? z5L!99uh-JcYhtUNxk^86K zhtKIslX`q9Cn7BT4Ij^ql9qS6cxp&ZDpWA8e*wc?idm-bQXR(rwI~N37yw#EPJNjy zLv$>;b^Q4ew-ftgc&ZWFt5iSCP;~p#MyXX*#C035kL5Xxex2CMeLp?K8#e!$0Sc#p z#E>=6s&UA2+C8imZ*N?zI4em753x)m$No(I1?Y8KIrvbKE8_eHGcY(mkAH5AIkWVr zz<%_LGc~s9!;7YK`aD>zQKVyB0y&V3= z&8HV?VPyIC6HYF1`>c(P2rEtGJDPFMo;D5FDevI^pOrrc`)n+&CvAjD91eNV|10Ai z9O72Cb-6~4WZ5$C@t#Qk0P9ob1uGsC7MfFny(>=I*J#EwU6+XbJhl^w?c>A_a6tYO z{uPrIulqQzDaFOu?1Yq+$|-6(0ahco$3f3(x-GHIM>XY*n9TPvCOa1A@~N{aw25u4 zOp+vOK4&3Cbwf{%;%GFr$%X(Vocf-jf3M+L9v8Z|zK-isNZ7$|!ZR)dx3zW}U8BWq z=1q?}QeID~?f7)Asx<7b&RVnPb}@C`4#w&=N3@1ZnU2WIu5s#r0h3y5YX+OA2;u@b zk#>MP04hsp*7s48^QuRfqW=KdkLSnXRQ2X*)hyy|re@ktq7Ga9KN{U58<=nhduN_e zhPZPkJr|;n%DHK@#?@}`oGv3@-A3JpIVbb}RodzZ@L9XYnPpre4(Fg1i>U_E^hLIZ z26kPfkK%U!0PC6>1kWJ8jjZ(xkXJCX6eBqsyOCH%6t%ktJK;Q@IvVy5_($UVFt>GC z83tP`)cT*Ta=O2TP+Z25NKcq@%11yy&MP@1RMQ~Q^myI`ow0`-v*;^tPq9Uj?!xf@ z04jgFJN`9^_Dh{6RDoq-Zzn8zg zTnBBb{^Mya ztbK}c{42-v$*Tok<5!JG`nz=8ecif#LqDB61jIP8&}+(1p*sl-f^1XkM)m*{{VDwKdn8K zOQ=RO^1{1__dE~KAI_zMF$^gf=!ykLVwqWP3D2D6htr_`U#&13s6Nyf8Eh5<*NlH! z%uyDVWYS37E?M03l6sobY|VKwBjkxyN7V9vrDezk{r3zFya$o}=l=lfe>!XsScjT_ zwcHF7!Y)4I{{V^aS4aA7;gI0N2`ZlL-2NRuI;VLn4VKVO7|&rwR;(u`78MO?WQSQ!;z zK;zb_Lo+XWw`scO@+ec5k-~xQPAfK@!K3Kkgqlm~{tSvoTpPmE4{pQsuJT3uRk0nI zVEt=9NNDt(2Tp;P0V7zC9S$o=SS0Nj95~!Rt#qYjVHwEeDi-_Ewhdf}?YMQ%3^FRc z%51nGjvR1(=~eQu$a;gc(*otQZ7&(@+)~EbiNNegsFAU9N2-HJhisDp+|UD~j2kcr z$l7Y0*5XY+9;sH~kQ+~;kx01vBL4unMS#S-xAQF$arcl1&-1EN18X|ZpOx^9{VRM! zzQISVc>OCq?fm^L1{ozkQA0pwHpbOdk;BACKA_VsEkM;E#xTgre?wOEG})p`$7x=dNA}gi}zMvS_CpQdQ(fUqE%;~&J|{=em0 z`h>3yrq~8%m4s>RPk+E<({!i{EVqyMt{ZUAW&RQQRMDZi)LKK#aE*!X#~DA<^Q|mq zIw%&-(PM~UC?4vbOn z`rQ6CjeRWIo!{A1{_Swm{{Th)v;mkW31=nDi?yUz~v5RT*|^mLX$8?ZTpi%d!6eIjwA@7OZiEMCs{)S*8}2`RA2L5fYID`nUP? zr_c)akQi0vn1eg>D`%&$_7ydno2h=%$M;LbDo5tuk7}a5kc@6jTqeW2@FS$?f7&2$gdyx-=Hk>Y1*~E-TO=uj{VC2 z05e|Cbt0*J{{RR0fBLJ0_=ly5d>wIka??c0=RWO&{P9G-5?1HVhfb6Zl^fYQE?T;n zu;VRM^%Oo)+A?d4+G}HOQc7cgUX(lAHe?V50teY#8rSvmgz8f>HO3Sx3rMeBpm`qVmO zNWN?n;FUZP+*XA2EM700ZM}MdxlL4s#IQEs_k~jT-YjGj~#scj?%$uNI| z6bP*pTkI7`>X@p_Y$wwd2f8T(=B5kWn6pz06HuNJWw^pm;-(0OdqKK z0QFS9SiIBl-}2EgeT`nSix&HR8Heg>D;V(uq5cW zlF~3@W=SBCfFr2qkJA;|*~Bw*7Cz*s_2>H5YuWz*#KP$|j2*HM#9;pbDoqUA@b1&9T}NN4W?5 z4SFt-s>7?<=NOenBtzT(0If+d-1%~Nt}U))wUX1yk~S#HPeM4abMS70+Fyk&EF}P3 z-#48$2P(aB`CxuEk>XDSnZ6-eym9{kpVSUp9)h5V%d6i#)?3PpF~$$C@gL+r z16J2gSv5FNjI1hTKU2W|w7{ilr!qoJtVo6ziqgA{ zL@NL|GLWB#f6y9r%*$RoNs}^vEp625j-zL%YPzUqPIpH#D(Ek8- zDB1r26Ttqo2(Z|K*_)t6&*UkVF*H_jhaWK;o9cN#&X)9#C1U>op026-^ZE*&MhO!+ z=&DU7QBKhL^IT7k3;Ak&myhR~Y|(l8j9}o1S9$uL2j~r4vxmvFi4R?%pQ+^3RaF$Ws~r z0BH04znwbgV_c!Y-l#}EgCdv|qeQZ{!yW+K?cAQ`mev-P#oU0b%rP8i_!s<5LYcgn z$U*x&ZSs%ruswc)tj%y^ArNkv`g?ntLnf3PgZ6REW0_k&d;OpBsb-lh;U6wtzEnZn z_7w^k?BHpiAs3U}lTNmYq?7G){{XCE@+bWBUr(>CF$nM!wl6CKAv>6lUr*&!FDzo# zAiA-bkp!`{EC)hQf5VE>nomAqZn--?c@J-4^{S8NEUO$ODI}6{oK-D}K5^8v>9kEw z;>PH0k{2pL9eoJ;^{O(-8}Y^~y7<3lTKd~l3Q)-J1Nxn~!T$iztIg1WIXu?{;maeU zF6igu1(*OiJuB>A3F%R39uw0om3EZ2P5%H~4A;s27qF95@h+cf9DCYH*X8vCll-gf zh_;(pSr*paDr3QHWrqHy0zg5Yg+lisac$hTHX#|LuZzO_t(72sp@CqjFQ0J9hk zEQ|f%4Ll9jM?Fw~Dz5|PNT1YgHDL(ZI(whifD56yB4N}xBk`zR2)vB{0C`H&+>>ID z=mGqySpf4QU_XocRS2q)?7Ea=h5^5!ra*-rXxBV8K=wTU0F7N`{{Tu)btCyx6-V2o z^eDg9fGb%uh}tIy_ij{uDoZIx+4g6ZVyE+|<3MMedynN+;D8H@l^@;*^ArIkrqdIE zdPv{SnQVb%xL^8dpUetvuyne(i<|-&ek1xtt#RPw7AvtAtEBLh{lAKI3ZOxV)(D7DKZ-UN3+ zLoyFT>Frw27?pg#;2(S6+Pr!0?|e7oi!0D2YiS}_N&t4Ul5_bUYt|)cOh?LKpp2>P zX(5$$S!R^QWo&~I96NSZ9e=~|rcG$DTfFl&<^zCzdsH#WbN#3L*Gzdw0DVO}QkyYA zxyUo1Kb=}6yJu@1ouqLn`=g(8-lMZ|BFk_;<)fS*VZi=IrIE;qo48VH9X&$WTY>$+ zXaXnQHn61REHP*CWBvl8)Qi87ZlnEdfFJiqC;3&aJa4?Zb|3Q8FW?kahlLwch!y*> zvHE0zLu0W@=?pfK$ayNK^Qmnt#1^qc1~#Y_KA`}3qlh2%lBhpSm66{&QItKTXhja&Ugw5{V04kqY`oQA#8r1<4(L`WC38M9P+Pq_|m|x7|r)(rg&c(`hOu+ z+7GnNb~m#8f*{M(btn1N`!xRmL5Lm>&`ngeMvBekW0rPjKcDzjASur2X>O{E(+L_6 z;ynPRwYMvllMO5K>^cu&>?$atmV2g}bqXUJV;{}Gr84H^yPHT@hCIl__*c{FXt2qn zKW(@Yf_}>h{n-Bde|!8Y%=ZqZV1#a+`f?Ct!8X&mmF zPF=sC_7n)Q3`uJP0>puqc5bKC)gvb5kS_fqW)FOiJvQ44N0Nj1N13xd{_Od$_>4ul_dWFd4>n+Uq#ML zGHx7(~MtkeK9M)=Y%-$f+Oh#DCgaWMdJ^J8nP9oPX59J=U0qH~f6Z^gq&?xch7W z0JuM$JfoYG!04ww-{%xX12yE2k&U5$AM$Bj2E+&2C;tF|{{SjWer_&L`#^q`V%jBd zGEzz0*!;MsS*S5HU~VjOe;O_YXb`>J@3+ur=s)`O<&XFCK6+ts`u_l0v1+_ZePn8e zKbfu@v6uM(DO_z8fd2rAi+e;rnW9jB+XvCVrAZ3!znJ*7@Gc~va{#uXZX>RRA(Fjjj2pB$@t0ALlS%*GZ+CI4EshOlYrV05&ARj^+mSI(c_0l&}XP*B;e zQS}rm0+AbM@gl2gPz8iV}Wc9^Wtb|DhrMp?Xls5rw|% z3aXGm7~t2I%X%+0rGi34R=ALZ-N@te9M;9=v2hiq%XbYtq(>Lj_xw3Duh1-Z_9T6g zTe}u-%#%&GIl8%<)q)S8AL45o%KrfDI(%_7+k{boOY%+yNuz4dd1PmJlq9ar9y9lI z!8!V7n2kwp1L_b!IsjyEa#bT z6=Yq|!qWkR_qq@3PRI=_{d&_*O_|)|3W&UxJ%us#6o*VzEE-LrK=otC^R5AAK_g14 z^UP1o{{Yh`iod5kk2>7l5DanF`z$8_f3AN)=snFtG^P|tVaJ^(3J*c*PqkUKjV+?aec6vvdzt{W@|NY$+(j!+Kl0uRvUsn?wFF9+E6HG=d1 z0Hpa-4YH5Py~S)mR^rga$2b&_**oE6ADvi<0XF%5$G5d*HN*J`(tYJ^js7*O5mN+i z4=Db2c6Y9A#R~i02nn^Hp*?KtG*65D1mC)z9h2^r-=sC-(PtWP^N-)3)}y!L+#gnB`qM%Z+y(Qb z{`;TPkLgKiF8gr*0N!GMT5JqH#<)F3YPE~z#w>Qo{c3=9gYH?qeCPgjhyFr*j`9Bh z?9|I3R(q8H0H&M2Fe+9U)g$){`fj0!x2SU*KzEftomZ4?z6Wk{y>ahWZ&xA_{{T%^ zqnIDG$Bu*$X(6(;w1Daof_d`SADOE&b8~Dz+GhO^_||lhx@sYio?|ESH8-AG{@f6A zwf_L6HX_!ff8t*#^&5XPim*uAnx&|}`Yt_P2mU-N#E*#B`U5}=(!b;%8+xvPI(?e} z*G=mw{z92y#+w#D=bHZjDz9ZBEp(*xoxi0k413N0025*|4j}%uM^uRJ&&<1jK0mEnT`ii~xFGH0k80Gs zwO_DHfzfmMb61rYZv%oUHai&FR-U6xxA}kNn)ddntTd>UT}QEUCw%ehazCAGY0I|F zQ2zh}6#R`ODkHzT9h@uw05Sb3TxTmMhhc4M^lSsnL~()bgZ!(H)pUJRN%0&~#P0Uy z5>a}9LFbR5uT-3>>XA2giNQZYrn2=}VgAsv2N}!p?YI8`)lHh*YmB+I;F&)bPp{U9;$|hEmkAQ?{N1lMyf?%|FU?dB3rK7*&{ zT9!64Pcoa!gDhR)RN9UH_fmhAVOzeVGh|5&Bm1nSkK@P{v1f0nw4lBCMD&Uv59Ud! zDC(X`yp^=I1Tn&y6mbwE`H%3cDzVwyU=XN)lE?X)W}6&V_TF4!fh4mtHc2O`CaN(y zjOC9uahwi+)-XMOgY~NsZp(Cp+)B82;X&%F*ne7{-a~tIRdOxiKQZj>>GTy&>SMhv zqH?m!{6qLubv1ZMmKIUP8fBa1jR#VH&w2ow=Hap~wis>Ed7-l{V9l^OF-fv?;zTM6;~i1 zt|{sEYhj#5fOS1TTE+2|{qCEhwatqKl}O1WJagK-K5rH3+PItT`i$SZ%al{KPqqa_ MnoCln8|;7o* Date: Tue, 17 Sep 2019 16:53:34 +0800 Subject: [PATCH 050/420] added WEIFENG photo to AboutUs --- docs/AboutUs.adoc | 3 +-- docs/images/WEIFENG-NUSCEG.png | Bin 0 -> 54326 bytes 2 files changed, 1 insertion(+), 2 deletions(-) create mode 100644 docs/images/WEIFENG-NUSCEG.png diff --git a/docs/AboutUs.adoc b/docs/AboutUs.adoc index 410449ebd8..2512996231 100644 --- a/docs/AboutUs.adoc +++ b/docs/AboutUs.adoc @@ -5,7 +5,6 @@ :stylesDir: stylesheets Dukepital - developed by the https://github.com/AY1920S1-CS2113-T13-2/main[CS2113-T13-2] team. + -_{The dummy content given below serves as a placeholder to be used by future forks of the project.}_ + {empty} + We are a team based in the http://www.comp.nus.edu.sg[School of Computing, National University of Singapore]. @@ -48,7 +47,7 @@ Responsibilities: UI ''' === WEI FENG -image::qjie7.png[width="150", align="left"] +image::WEIFENG-NUSCEG.png[width="150", align="left"] {empty}[https://github.com/WEIFENG-NUSCEG[github]] [<>] Role: Developer + diff --git a/docs/images/WEIFENG-NUSCEG.png b/docs/images/WEIFENG-NUSCEG.png new file mode 100644 index 0000000000000000000000000000000000000000..14f4cc1e0218deeaebca4cf88850099db5d0ebd1 GIT binary patch literal 54326 zcmc$`bzD^4+CRL9774)t=^>@02c;Q6x*G;W32Bh-Mo>q(RB{A{4iS)66bX^;RHQ>B zl#qNk-s&Caoaa2x@1J-4Y~sdWprW9x06-uB00I92r;~sjK!A&f zkB3WukB5JbfZ!a_MIxf}=ZUDu$Vo2JQPI=WQqj`DSgx?an7Ei|XfMOrxp?^m1O*t_ zu8Ljd7rVkQz<<^Vgy7scB0{1|L`0YP8EF~$|IfeEW`K+Uha8(98^R1=kwLJ@Ag6Bu z7)U2BreV9x&cVqA7ruH;L{v=fy1as-lCp}f zp1y&hkulQJ>bA9wt)0EQho_gfkFQ_&-H6D0_aC4V5|ffs9zA}Nnw^u2$;&S&EP7s9 zRsEu-wyyq7%iGqr_KtU*1A{}uBco&E6Q5@1<`)*1mRDA{w!ePc+1=a!esIPY1i=1- zE%5(882blbWFTKyI5^li_-A}Uu)M(yn+yk+NdS*rMjPMU^&+!iC;?P9{%OVQb1XtS zn-msq{e+aP@K0=8XRQ6;?0?5t*#8q}zZv_JuL*z%8v;%qHW?rd>{3)2o&rYbQ=sV- z7%8q;o^a7lQ&Qe(HGFuqcg%e&upa>puJHKyeLMVQKj-k0`YDjbA-#cWk_WU-+6IG{ zI$?*iv7c{TI|(p91zzIb%nsoQwzPZob%FGFOL3Ps?G%vGIt4yrmH%j{3T)`!$v%|+ zkA{LbLJbShgs`#tJ4fH;PJsYI%^yvHY@%%2Qh zd1jCdg=8H+$P4a`g6%cu99~odsiKnJ2t`7*@Pc=FpMah6pLJS1?c=RfcjLKH>yAvA zG#S#&aO2^Ivx2}x9-8QJfOPI_s^}}`x1<~Eq@NT@SHOF}Z`PdkY^RNY;>G93es>3% zhSIZWN^dXWA8&FULm>z|8lO|(kqFqC%mDoBDZuLz{DV2_Q(&y#YyG2nxbzpo;9d25 zN8e@67;2CQ%%^M(Zr+L1dv-TQjvlSw`#D3henK{Q2CIrA--RRka&z$eT>2Ho&a=}q5>$_q!BLkwBcV)Nz8Q0zoPP@R zrvDg}v&Lr5-oDWdg{U50{?#_$u0BXx%MaR=5ztfMd5QE=5A1M8C)jE%xHlc7q`0aI zqIk%ydDaWqsp1cAUZ1_u1ita=xg+=j>EVp_&+dM{p?b*M{*z$XxB>m=ADozi@{qxz zA?f(^j1=}=sWXB2F*oG{L2yW#WJ)55#G1e7bn{dghDIan=&IM!3BWbUeDzw$N2Jdj z2GBWaAAEHtW?+Bu`N6$O?BM+c9za`6A>*tqkoUwxS`Cm^P%c9am(heQ3WN8KYJbps z^K-QLNx-ciV+sxfVtE1-G?{-0+7FqvSOH}goMeuZ)-$OF*)xcMLNeiJl6@wQoWT`m z!V3yS@wXpB_CvCRKSE!P{c2PHNE<=@ajf3vX#cEp?c)a+a5g{@Z9Nm^k7Ir}|G3eA zeDCLtZrg#gwiq7$929u4xn1zrInv{=NN5!#?KtA>xg_bmZrGR@_;M@Q>If+NpnMaY zB>sNqjdbo=Kj33_U_V)#u`AL)+E6@VInX@XKbz{23@9Y|?5+4y0I?suk*NCDCWH&+ zf!n9R8_8eouphBZfN!=UleF**k62O-kG`|PHe*(Tzb?VnPJ~P40W0uv(OggggOkCB zk%|sf?E}>-#QcJ|@I z0Kc|Ys5S!kf4wDD0XjNEZh5nHz4-8uK&ZAF?$3rG9GL77aukvS$o+A^Y5Tj2vkQbA zKQ|TdiENY#fc$mg|9PKBxm1A0@0W)H+Ta%XOhS8r>!Wb^tm|QI?<;$GW~11i>T09n zmQqKQ)kAq`5>TZr4?zE?O;@7zV~zARjMNWuA@WcyEFF{zI6inN4u}Baj15b2aVy;w z0R%1&yReCt1LlExx@*Vxd8IKb^m#qqiz43(zx^ObTOPg`LN5=u&iFr!?*C;b{_(6p zJk?jtKZp6k2<$=cJF3zaBPos*dR#>}nZ1!0h8WB8kH~R)4%YuT_>s2r0lsdI?Pfx$ zsVIOW`;W~grD4x#x57@Zu9^r2;cDb1PU{F@D;sL%fS6TYIj z{SX(qu=bdqVgJ4GDLPaF{zob}gy$dD0`fz@`?NI2D3kpZ zh?PI+gI}@SE8d}~o~U?qY(c6}8oy_I;kRkfHF6!LKq~kck@qr6+#=mXpZE9+T|cac zjy3{9O<}+{)!Eq|xnfY5piuq}3LJ0(t-Q7n+iq|Ov{O0GC`A2tBggr_eeg^W{v6`R zf3>JT+5jzjE(Q*YWn@Y?0$0wJ33Vm3S0(ky6$j>Z=OiF5W&5>rUTz*UE<~n>^Ba%^ z1lrl6v2v_*g4UJ)q16U~Bl!+CaBb5D{6}BR&oN{miks)L5$BD9IKct*{MIX6_s3Y8 zs}qyNKB27EAATHhOKDYT;Q6h?6%#^KV^L^kUfjKY#7}#~FZoNW{<0_kZ4*qj5$BXN zIPD0aK$C4N7C5gdKW6z)YxdiDoW0K}BqO1PH7r_gsZ7cGeV(1xux4~1&EK2O;4}79 zH-7A^q9v;IunrzycQ>B*3-^h)zmBq_4C$krRK7cwWO~zabo*M@ZCR|&T37U6`M6Gq z5ES`tzZ4aq?qErm(!Z+pL1-r$gAE(0Tff+v${R<~^Qit)&yD2se8)Sw#oV&C9Un$$T&(6qiUf#0#e8xWXpCJLs4Cg% zz3)D&u(^}1@UeN6in)~8`Nk;_5ka4HqETuN7x|Q{KPNmocJpsocgj!u^^Ox;kVyO*7^SgO$a$ctbXJ{rdE)Jr4e z7e~xb$IHw?Coc3GY7$C*U?+Vu#y*xYOYkS-$cTy3Q{i2u>w(}5FeI=QH z*ooi0fY-4Rm{uMr0O}YDkWu|M-KF-%}t;qN5HFpZk zrm;$p9cq#m-_LkQ#qM-t;QCZn3ync6n&4B_-OV~7hL_)k%L~^IZagLx z{&Gp=t*>-v?Zzd0cT+^4-Iib;f%Ug?(cwlJ-iPPUd0jHSp!u~`Hn}akS9|zK7Y{>y zPd%QQeSbmZ$i?Atf?CizQCN+k)iq1{lgX-4=m0vv+5|Rz~=eA^2BDzJ&W+FrNmfw z&7`!P&-a5^eGKM~%}VhZN>Qkr_fuKj1bLr2PMrdNFU6^dd%M5QrVj)^Q#>LVtRyBa z*$A*B9+8MP>ttO;m}f1SW|q&1vezC8u4yAD_>8rmn=nMa^!yNL6a=r^v0PJ4j=VQW zWBB$IAX%;;pgeJswU+GFd^>t4e?MP#Xq|l4AG?@kH9beI*V-o9z+nc zf$?st%9%$3{Vk{6*+HC6-w)ML2G!uVkNoKnnM&?l3~qlkXL7mX2t-sEEZ5X*m4Zk3 zMt-VUX_4&T4EJA*KcNulba*b?*>ON@f5ezM?>-{PwdLuTelDg4IaQtC*HyF2_2^&+bzXcp9L7aM)c zUi%A9Ov)b05h=Z&$h|?iWROC@Jk(g5NZUuUPe+qZWwKY_`Q~{hLIHcL>|u-7#GUcW zjWtOd*k}psC-P1TZ+foPgb8t`NMI>yWVE`T0%Uhuo9ZX8TfX|w|D8hXH#bE_WhbWH?P~gj(@I8Up#t8I8B{TL6v|`;&Ged zs|7PYl4`5^Ty>&SsP>NJfp?C{Fkczfl%nrR%rs&8MQuqBa%6_){hc{G!ncoHuRoqr zW=z~SO!RqZTCiqkh&Zu0GR${m&Tm{zv{Q6`v}FIA3|q8--lDo%>EGrp2`PUjMt_aDIdcE-aR2gBp>i;tf8#Jm@zmad zc5onZaznSvm^}5e`YlEG%g@$bp;^nyM>v+QN51g1X9KLYhYE$9d=85y%dylwji(_kt>8VzLGs2Fdnhq z-=?5RF-A{vdmzVwnr1>W$E|hvmDns?$(07v*qM0ok&Y$*d;dT}L1LEP8aishw{nFH>-u0%8C#g5>IP0D3!G?CdizVOOLeVcJLvYyFfwV7_m z7JbU!_kqWn2Wc40^SxQp0dGwwMb_Zj1iqSgQOz~-sax;&6lJuun6|}LyYgM3ok%Av zIubjo0dm`QHJPEWsvn`j#5kl#K;@TlF!k55$f!E#!*W;d7ROu-p%YY8)9p)Mwr337 zQc;#lg517+$8_i+Ylsc&p+2Hju~ZZKnBIK{eLntOEq)?^T06Qp+mJ>2q4kP;hk36+ zvDe1;QIcBr=vT-Jhee`K&%_V3+5#g!!Km#rS*zq61Rqp%-L5N3cq!CZeHhKKDq4bx zx59CqL>;hy8hvYWBZ&1yZKr97V3#7ijHPcm8+8jzajJm7Mg!;Md8p7hKg|_rED1Rv z#5_#@K^D$}-ao9R{xb*I+pMkmpekVOm(hIr3ONBv@P9~{!{ylk0X72(>)c$bZ(x}G zSK~^a@)t&7WD?(Nr{ z91~wGaJ}-l*y>xgUOFWqZjr*q{zc&w;9D>d9zO-DqA<5>ALwnft+XS1!gZNUK6?w2 za=3k8Lp`P0+k1}eV%km+omSky|M0F%uGKFO9eFY?tH6V)9W0z07&?Sj?J!_h88Y8wb=nN(+!@6v4Doqj7tynYyWS))2rh zw88Wn6bqMkZmbVraenitBfcJ@T$h#tk4USKjsS>h*-dpqT=xoa?|-kuP)U#>$Q7E& zrIB%>%XQrf6o%@!RQOcwu=+MdPUxZp;}f!0P4*x3>D z{70+|ui^+qAsJxNjx_CCd`CV(@HRmSmcsS;gOOIDzmevI zl&HUgDgWu1AqhzCHhYm#`0>4c?}LhOD;p*?yu}v-X6XDzGvwJ`?XFE6=aUNsetEpt zt$Lf)9glWL|R^bW9Z6T*K;|egzG1CJ15mk zFPUDZX(%t$ZEs{dBN)SV^rJ{A>_@ij-a}ohMCmWrV-xedUzzdu17vF(2GHAeO^0^CTh{cH0Do7MR&(I0 zv*tjEbfYb+TUHix{Me&41gmFWA_8A@O+mBta-ck&7ZjM$R5AUEQrlAR6-DFTQPJ?z z-cX%{12kYThEI|-!9i~eV5swTv>*zcLMsaD03UOrCv`7U5Er1mkC{$YTa0o?kZ3hq z>F>*=@{7-5v=z+1a2Z+KVn|37I7974dQtUVoL;Z(#H;k?-5sD39uf&FDa)fPYp7h2WTi?`e z$M^*XJe|37sTcjRMMAp-r7600Q*Hl_@k8X`T-|-Z)T&?|K{KS&{~H!O6D(X1)IsCG ztCIf2vHs>hf5d@*xK=r11~xEngFWqbG*G;M3d}VhUa*U@@YF0QO{9r&y@uh;sP^!8AfpyZb6Zrv7_-~;Calx9Q9cog59^791oQtN}+ zW$Kb-7M8NP81B1b1Ct+3l?x`W6y(4f*0S2_RHN-Dwy!0qJ5cwGHNMG_+86Gg6q1|? zUgzjn-ncB!lu^C+&_k$R+s>1rW#76k+P@VxaY>a%BKw2%O_gx%iZHu?_7TQ7%P-sz z)4Uv3*UruoRT4pxU@r3Wk30j-d2j1)cUee1rnkRa$)RxN+MSimY7PF|7D!picPr{i zVA7(@{h{bhZBJb*lT^}O%gm(4xm1gb>HV4CnwD1(gi744*J8feR6_|&qqdaWR&k*~ zP9lP?KZcXv7NWEmH!#!Ziuf5^xvZ$8vEf$zXONNN90C_i=UV}KPMIALfTNGsXl~`V zNFs5c2%*bBV7~+-<dw?ycR5OnFDg)Huj+f#GY zd8+Z3>HK4oMD!SLiF7majH_6>

Za0$Dc&8tRUD<6II~Ib@W{e0EW4h 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

K2*^gaxwi%bg&eeh|d1x>tnl|F0(u%xBm;6VR^ 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

X<{Q98?$}#;uHozOH@j_trk6>oaNnZIqF!)9(F@ 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�A`K6y-+hZ8zX#ibR(9dKJ{o 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 tasksInTheList = tasks.fullTaskList(); ArrayList clashTasksInTheList = new ArrayList(); - String userAnswer; - + /** + * Check whether the tasks in the list are clashed , if yes then store the clashed tasks into + * a new array list + */ for (Task t : tasksInTheList) { if ((t instanceof Deadline || t instanceof Event) && (newTask instanceof Deadline || newTask instanceof Event) ){ if (t.getDate().equals(newTask.getDate()) && !t.isDone()) { @@ -71,11 +73,16 @@ public void execute(TaskList tasks, Ui ui, Storage storage) throws DukeException } } } + + if (isClash) { ui.showClashWarning(clashTasksInTheList , newTask); Scanner input = new Scanner(System.in); boolean isValidUserInput = false ; - + /** + * Check if the user have enter the correct input , this check will continue + * until the user has enter the correct input + */ while (!isValidUserInput) { String userInput = input.nextLine(); if (userInput.equals("Y") || userInput.equals("N") ) { diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index c6a9e47513..190aad7a8c 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -112,8 +112,6 @@ public void showClashWarning (ArrayList clashTasksInTheList, Task newTask) } showLine(); System.out.println("Do you still want to add your task anyway? Y/N"); -// String userAnswer = scanner.nextLine(); -// return userAnswer; } From 866eb3ccadd067fc9155f3857ee0c9fb169b1753 Mon Sep 17 00:00:00 2001 From: lmtaek <43768091+lmtaek@users.noreply.github.com> Date: Wed, 18 Sep 2019 20:25:41 +0800 Subject: [PATCH 059/420] Update README.adoc --- README.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.adoc b/README.adoc index 94be4fa10a..6703835092 100644 --- a/README.adoc +++ b/README.adoc @@ -19,7 +19,7 @@ endif::[] * It is written in OOP fashion. It provides a reasonably well-written code example that is significantly bigger (around 6 KLoC)than what students usually write in beginner-level SE modules == Site Map -* «UserGuide#, User Guide» +* https://docs.google.com/document/d/15969Buo0Dh4mI4GDn84tlGQ11MAjgxQQq0f9qB4-0z4/edit?usp=sharing[User Guide] * «DeveloperGuide#, Developer Guide» * «LearningOutcomes#, Learning Outcomes»About * «AboutUs ,#AboutUs,» @@ -31,4 +31,4 @@ endif::[] _Marco Jakob_. * Libraries used: https://openjfx.io/[JavaFX], https://github.com/FasterXML/jackson[Jackson], https://github.com/junit-team/junit5[JUnit5] -== Licence : link:LICENSE[MIT] \ No newline at end of file +== License : link:LICENSE[MIT] From 15f2d8ebfb634e2d2e02b2c658cc411cc73327b9 Mon Sep 17 00:00:00 2001 From: lmtaek <43768091+lmtaek@users.noreply.github.com> Date: Wed, 18 Sep 2019 20:28:07 +0800 Subject: [PATCH 060/420] Update README.adoc Updating links--User Guide and About Us pages are now accessible through README.adoc --- README.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.adoc b/README.adoc index 6703835092..40b7a4017b 100644 --- a/README.adoc +++ b/README.adoc @@ -22,7 +22,7 @@ endif::[] * https://docs.google.com/document/d/15969Buo0Dh4mI4GDn84tlGQ11MAjgxQQq0f9qB4-0z4/edit?usp=sharing[User Guide] * «DeveloperGuide#, Developer Guide» * «LearningOutcomes#, Learning Outcomes»About -* «AboutUs ,#AboutUs,» +* https://github.com/AY1920S1-CS2113-T13-2/main/blob/master/docs/AboutUs.adoc[About Us] * «ContactUs#, Contact Us» == Acknowledgements From 13f0799e7cb156e3e6234099048e6329eef36025 Mon Sep 17 00:00:00 2001 From: Qian Jie Date: Wed, 2 Oct 2019 08:30:25 +0800 Subject: [PATCH 061/420] fixed some checkstyle issues and removed not-used variable/functions --- src/main/java/duke/Duke.java | 8 ++- src/main/java/duke/command/AddCommand.java | 3 - src/main/java/duke/command/Command.java | 2 +- src/main/java/duke/command/DeleteCommand.java | 4 +- .../java/duke/command/RecurringCommand.java | 2 - src/main/java/duke/command/ViewCommand.java | 3 +- src/main/java/duke/core/DateTimeParser.java | 12 ++-- src/main/java/duke/core/Parser.java | 1 - src/main/java/duke/task/Task.java | 68 +++++-------------- src/test/java/duke/core/ParserTest.java | 10 ++- 10 files changed, 42 insertions(+), 71 deletions(-) diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index cf6f6a518e..843cfc313e 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -2,13 +2,17 @@ import duke.command.Command; -import duke.core.*; +import duke.core.DukeException; +import duke.core.Parser; +import duke.core.Storage; +import duke.core.TaskList; +import duke.core.Ui; /** * Represents Duke, a Personal Assistant to help * users tracking their progress. */ -public class Duke implements Runnable{ +public class Duke implements Runnable { /** * A Storage object that handles reading tasks from a local * file and saving them to the same file. diff --git a/src/main/java/duke/command/AddCommand.java b/src/main/java/duke/command/AddCommand.java index 4c5dc5c27c..9172026ab5 100644 --- a/src/main/java/duke/command/AddCommand.java +++ b/src/main/java/duke/command/AddCommand.java @@ -1,6 +1,5 @@ package duke.command; -import duke.Duke; import duke.core.DukeException; import duke.core.Storage; import duke.core.TaskList; @@ -8,9 +7,7 @@ import duke.task.Deadline; import duke.task.Event; import duke.task.Task; -import duke.task.Todo; -import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Scanner; diff --git a/src/main/java/duke/command/Command.java b/src/main/java/duke/command/Command.java index cbad3e513d..ad056aa224 100644 --- a/src/main/java/duke/command/Command.java +++ b/src/main/java/duke/command/Command.java @@ -27,7 +27,7 @@ public abstract class Command { * Decide whether duke should exist. * * @return A boolean. True if the command tells Duke to exit, false - * otherwise. + * otherwise. */ public abstract boolean isExit(); diff --git a/src/main/java/duke/command/DeleteCommand.java b/src/main/java/duke/command/DeleteCommand.java index f9c408f2b4..542f1120e9 100644 --- a/src/main/java/duke/command/DeleteCommand.java +++ b/src/main/java/duke/command/DeleteCommand.java @@ -29,10 +29,10 @@ public DeleteCommand(int taskId) { } /** - * Indicates whether Duke should exist + * Indicates whether Duke should exist. * * @return A boolean. True if the command tells Duke to exit, false - * otherwise. + * otherwise. */ @Override public boolean isExit() { diff --git a/src/main/java/duke/command/RecurringCommand.java b/src/main/java/duke/command/RecurringCommand.java index 0a6d3cd472..b5c51f6085 100644 --- a/src/main/java/duke/command/RecurringCommand.java +++ b/src/main/java/duke/command/RecurringCommand.java @@ -6,8 +6,6 @@ import duke.core.Ui; import duke.task.*; -import java.time.LocalDateTime; - public class RecurringCommand extends Command { /** diff --git a/src/main/java/duke/command/ViewCommand.java b/src/main/java/duke/command/ViewCommand.java index ca303462d3..64e7c0c8f7 100644 --- a/src/main/java/duke/command/ViewCommand.java +++ b/src/main/java/duke/command/ViewCommand.java @@ -1,6 +1,5 @@ package duke.command; -import duke.core.DukeException; import duke.core.Storage; import duke.core.TaskList; import duke.core.Ui; @@ -39,7 +38,7 @@ public boolean isExit() { * @param storage object that handles local text file update */ @Override - public void execute(TaskList tasks, Ui ui, Storage storage) throws DukeException { + public void execute(TaskList tasks, Ui ui, Storage storage) { ui.showSchedules(tasks.fullTaskList(), date); } diff --git a/src/main/java/duke/core/DateTimeParser.java b/src/main/java/duke/core/DateTimeParser.java index c2c49429d3..6eda645c92 100644 --- a/src/main/java/duke/core/DateTimeParser.java +++ b/src/main/java/duke/core/DateTimeParser.java @@ -1,8 +1,10 @@ package duke.core; import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; + public class DateTimeParser { /** @@ -12,7 +14,7 @@ public class DateTimeParser { * @return A LocalDateTime object that contains date and time information. */ public static LocalDateTime convertToLocalDateTime(String timeBeforeFormat) throws DukeException { - java.time.format.DateTimeFormatter parser = java.time.format.DateTimeFormatter.ofPattern("dd/MM/yyyy HHmm"); + DateTimeFormatter parser = DateTimeFormatter.ofPattern("dd/MM/yyyy HHmm"); LocalDateTime localDateTime; try { localDateTime = LocalDateTime.parse(timeBeforeFormat, parser); @@ -30,10 +32,10 @@ public static LocalDateTime convertToLocalDateTime(String timeBeforeFormat) thro * @return A String that provides date and time in English */ public static String convertToEnglishDateTime(String timeBeforeFormat) throws DukeException { - java.time.format.DateTimeFormatter stFormatter = java.time.format.DateTimeFormatter.ofPattern("d'st of' MMMM yyyy, ha"); - java.time.format.DateTimeFormatter ndFormatter = java.time.format.DateTimeFormatter.ofPattern("d'nd of' MMMM yyyy, ha"); - java.time.format.DateTimeFormatter rdFormatter = java.time.format.DateTimeFormatter.ofPattern("d'rd of' MMMM yyyy, ha"); - java.time.format.DateTimeFormatter thFormatter = java.time.format.DateTimeFormatter.ofPattern("d'th of' MMMM yyyy, ha"); + DateTimeFormatter stFormatter = DateTimeFormatter.ofPattern("d'st of' MMMM yyyy, ha"); + DateTimeFormatter ndFormatter = DateTimeFormatter.ofPattern("d'nd of' MMMM yyyy, ha"); + DateTimeFormatter rdFormatter = DateTimeFormatter.ofPattern("d'rd of' MMMM yyyy, ha"); + DateTimeFormatter thFormatter = DateTimeFormatter.ofPattern("d'th of' MMMM yyyy, ha"); try{ LocalDateTime localDateTime; diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index 4c7bac90bb..04c35e3a67 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -12,7 +12,6 @@ * type of Command. */ public class Parser { - private static String[] substring; /** * Parses a Task from a string array. diff --git a/src/main/java/duke/task/Task.java b/src/main/java/duke/task/Task.java index 02bdeea78f..0c254b619e 100644 --- a/src/main/java/duke/task/Task.java +++ b/src/main/java/duke/task/Task.java @@ -3,15 +3,9 @@ import duke.core.DateTimeParser; import duke.core.DukeException; -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.time.Duration; import java.time.LocalDate; import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.time.format.DateTimeParseException; -import java.util.Date; + /** * Represents a task. Task is an abstract class that can not be @@ -25,12 +19,12 @@ public abstract class Task { protected String description; /** - * A boolean that represents the status of the task( 1 means done, 0 means not yet) + * A boolean that represents the status of the task( 1 means done, 0 means not yet). */ protected boolean isDone; /** - * a localDateTime constructor to save the date and time + * a localDateTime constructor to save the date and time. */ protected LocalDateTime ld = null; @@ -69,7 +63,7 @@ public String getStatusIcon() { } /** - * Check if the task isDone + * Check if the task isDone. * * @return boolean value of isDone */ @@ -78,7 +72,7 @@ public boolean isDone() { } /** - * Returns a string with the following format to be stored in a local file + * Returns a string with the following format to be stored in a local file. * * @return A string in a specific format to be stored in a local file. */ @@ -97,17 +91,18 @@ public void markAsDone() { public void makeTaskRecurring(RecurringFrequency frequency) { isRecurring = true; switch (frequency) { - case DAILY: - this.recurringTask = new RecurringTask(this, RecurringTask.RecurringFrequency.DAILY); - break; - case WEEKLY: - this.recurringTask = new RecurringTask(this, RecurringTask.RecurringFrequency.WEEKLY); - break; - case MONTHLY: - this.recurringTask = new RecurringTask(this, RecurringTask.RecurringFrequency.MONTHLY); - break; - case ONCE: - break; + case DAILY: + this.recurringTask = new RecurringTask(this, RecurringTask.RecurringFrequency.DAILY); + break; + case WEEKLY: + this.recurringTask = new RecurringTask(this, RecurringTask.RecurringFrequency.WEEKLY); + break; + case MONTHLY: + this.recurringTask = new RecurringTask(this, RecurringTask.RecurringFrequency.MONTHLY); + break; + case ONCE: + break; + //Do at in a default case here } if (this.recurringTask != null) { this.recurringTask.recurringTaskTimeUpdate(this); @@ -138,35 +133,6 @@ public String getDescription() { return description; } - - -// /** -// * Returns a string that representing the data and time for the task -// * in a predefined date time format. -// * @param timeBeforeFormat a string that provides the data and time information. -// * @return A string that represents the specific activity associated with -// * the task. -// */ -// public String timeFormatter(String timeBeforeFormat) { -// DateTimeFormatter stFormatter = DateTimeFormatter.ofPattern("d'st of' MMMM yyyy, ha"); -// DateTimeFormatter ndFormatter = DateTimeFormatter.ofPattern("d'nd of' MMMM yyyy, ha"); -// DateTimeFormatter rdFormatter = DateTimeFormatter.ofPattern("d'rd of' MMMM yyyy, ha"); -// DateTimeFormatter thFormatter = DateTimeFormatter.ofPattern("d'th of' MMMM yyyy, ha"); -// -// String output; -// -// if ((ld.getDayOfMonth() % 10) == 1) { -// output = ld.format(stFormatter); -// } else if ((ld.getDayOfMonth() % 10) == 2) { -// output = ld.format(ndFormatter); -// } else if ((ld.getDayOfMonth() % 10) == 3) { -// output = ld.format(rdFormatter); -// } else { -// output = ld.format(thFormatter); -// } -// return output; -// } - /** * update the LocalDateTime constructor to save the date and time * @param newDateTime the time retrieved from user input. diff --git a/src/test/java/duke/core/ParserTest.java b/src/test/java/duke/core/ParserTest.java index 4b1362316c..3870c34942 100644 --- a/src/test/java/duke/core/ParserTest.java +++ b/src/test/java/duke/core/ParserTest.java @@ -1,6 +1,13 @@ package duke.core; -import duke.command.*; +import duke.command.AddCommand; +import duke.command.Command; +import duke.command.DeleteCommand; +import duke.command.DoneCommand; +import duke.command.ExitCommand; +import duke.command.FindCommand; +import duke.command.ListCommand; +import duke.command.ViewCommand; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -22,7 +29,6 @@ public void commandTypeTest() throws DukeException { Command c8 = Parser.parse("deadline event Homework ABC /by 27/07/2020 1630"); Command c9 = Parser.parse("view 16/09/2019"); - assertTrue(c1 instanceof ExitCommand, "The command type should be "); assertTrue(c2 instanceof DoneCommand, "The command type should be 'DoneCommand'"); assertTrue(c3 instanceof DeleteCommand, "The command type should be 'DeleteCommand'"); From 9a1afd26f7bec40c93e74fc036112fe8e126558a Mon Sep 17 00:00:00 2001 From: Qian Jie Date: Wed, 2 Oct 2019 10:38:41 +0800 Subject: [PATCH 062/420] Added HelpCommand class to assist user when faced difficulties in remember the commands provided by Dukepital --- src/main/java/duke/command/HelpCommand.java | 20 ++++++++++++++++++++ src/main/java/duke/core/Parser.java | 3 +++ src/main/java/duke/core/Ui.java | 19 ++++++++++++++++++- 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 src/main/java/duke/command/HelpCommand.java diff --git a/src/main/java/duke/command/HelpCommand.java b/src/main/java/duke/command/HelpCommand.java new file mode 100644 index 0000000000..2a71ce759c --- /dev/null +++ b/src/main/java/duke/command/HelpCommand.java @@ -0,0 +1,20 @@ +package duke.command; + +import duke.core.DukeException; +import duke.core.Storage; +import duke.core.TaskList; +import duke.core.Ui; + +public class HelpCommand extends Command { + + @Override + public void execute(TaskList tasks, Ui ui, Storage storage) throws DukeException { + ui.showHelpCommand(); + + } + + @Override + public boolean isExit() { + return false; + } +} diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index 04c35e3a67..63b8b3ab76 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -120,6 +120,9 @@ public static Command parse(String ss) throws DukeException { } catch (Exception e) { throw new DukeException("Failed to make your task recurring." + e.getMessage()); } + + case "help": + return new HelpCommand(); case "bye": return new ExitCommand(); default: diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index 190aad7a8c..eaabe10ab2 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -196,7 +196,24 @@ public void showWelcome() { + "| |_| | |_| | < __/\n" + "|____/ \\__,_|_|\\_\\___|\n"; System.out.println("Hello from\n" + logo); - System.out.println("Hello! I'm Duke\nWhat can I do for you?\n"); + System.out.println("Hello! I'm Duke\nWhat can I do for you?\n\n"); + System.out.println("Enter 'help' to show a list of commands "); + } + + public void showHelpCommand () { + System.out.println("1. list - to show a list of tasks\n"); + System.out.println("2. delete - to delete a task\n"); + System.out.println("3. done - to set a task as completed\n"); + System.out.println("4. find - to find a task from the list\n"); + System.out.println("5. todo - to add a todo task\n"); + System.out.println("6. fixeddurationtask - to add a fixed duration task\n"); + System.out.println("7. deadline - to add a deadline task\n"); + System.out.println("8. event - to add a event task\n"); + System.out.println("9. period - to add a period task\n"); + System.out.println("10. reschedule - to reschedule a task\n"); + System.out.println("11. view - to see a task of a specific date\n"); + System.out.println("12. recurring - to make a task recurring\n"); + System.out.println("13. bye - to quit Dukepital\n"); } /** From 75a1ea6778aa107b13099344109af54df261cb81 Mon Sep 17 00:00:00 2001 From: lmtaek <43768091+lmtaek@users.noreply.github.com> Date: Wed, 2 Oct 2019 14:45:51 +0800 Subject: [PATCH 063/420] Update README.adoc --- README.adoc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.adoc b/README.adoc index 40b7a4017b..c4d8a7eb5c 100644 --- a/README.adoc +++ b/README.adoc @@ -14,13 +14,13 @@ ifndef::env-github[] image::docs/images/Ui.png[width="600"] endif::[] -* This is an application used mainly for the nurse at the hospital. It has a GUI but most of the user interactions happen using CLI. -* The purpose of this application is to help the nurse to manage their tasks better. -* It is written in OOP fashion. It provides a reasonably well-written code example that is significantly bigger (around 6 KLoC)than what students usually write in beginner-level SE modules +* This is an application intended for nurses within hospitals. It has a GUI, but most of the user interactions occurring will be using CLI. +* The purpose of this application is to provide an organizational tool for nurses, allowing them to categorize tasks/information based on their patients, encouraging timeliness and higher quality of provided care. +* Dukepital is written in OOP fashion. It provides a reasonably well-written code example that is significantly bigger (around 6 KLoC) than what students usually write in beginner-level SE modules. == Site Map * https://docs.google.com/document/d/15969Buo0Dh4mI4GDn84tlGQ11MAjgxQQq0f9qB4-0z4/edit?usp=sharing[User Guide] -* «DeveloperGuide#, Developer Guide» +* https://docs.google.com/document/d/1G6Bvc2kW0bpxYXVxCz2mC2vUknmPyHRZJHdE9Et25LQ/edit?usp=sharing[Developer Guide] * «LearningOutcomes#, Learning Outcomes»About * https://github.com/AY1920S1-CS2113-T13-2/main/blob/master/docs/AboutUs.adoc[About Us] * «ContactUs#, Contact Us» From c0886066b96d30d621bf0ef83bf7399afff9162a Mon Sep 17 00:00:00 2001 From: lmtaek <43768091+lmtaek@users.noreply.github.com> Date: Wed, 2 Oct 2019 14:46:22 +0800 Subject: [PATCH 064/420] Update README.adoc --- README.adoc | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.adoc b/README.adoc index c4d8a7eb5c..392e7f5824 100644 --- a/README.adoc +++ b/README.adoc @@ -21,9 +21,7 @@ endif::[] * https://docs.google.com/document/d/15969Buo0Dh4mI4GDn84tlGQ11MAjgxQQq0f9qB4-0z4/edit?usp=sharing[User Guide] * https://docs.google.com/document/d/1G6Bvc2kW0bpxYXVxCz2mC2vUknmPyHRZJHdE9Et25LQ/edit?usp=sharing[Developer Guide] -* «LearningOutcomes#, Learning Outcomes»About * https://github.com/AY1920S1-CS2113-T13-2/main/blob/master/docs/AboutUs.adoc[About Us] -* «ContactUs#, Contact Us» == Acknowledgements From 830810fd40ca63e8d507b5dd9a8b3e6803517ee5 Mon Sep 17 00:00:00 2001 From: lmtaek <43768091+lmtaek@users.noreply.github.com> Date: Wed, 2 Oct 2019 14:47:00 +0800 Subject: [PATCH 065/420] Update README.adoc --- README.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.adoc b/README.adoc index 392e7f5824..efd5ab1b7a 100644 --- a/README.adoc +++ b/README.adoc @@ -15,7 +15,7 @@ image::docs/images/Ui.png[width="600"] endif::[] * This is an application intended for nurses within hospitals. It has a GUI, but most of the user interactions occurring will be using CLI. -* The purpose of this application is to provide an organizational tool for nurses, allowing them to categorize tasks/information based on their patients, encouraging timeliness and higher quality of provided care. +* The purpose of this application is to provide an organizational tool for nurses, allowing them to categorize tasks/information based on their patients. This encourages timeliness and higher quality of provided care. * Dukepital is written in OOP fashion. It provides a reasonably well-written code example that is significantly bigger (around 6 KLoC) than what students usually write in beginner-level SE modules. == Site Map From 9f33d15b6ca17c75b4808e380de8352ac63c78c5 Mon Sep 17 00:00:00 2001 From: kkeejjuunn Date: Wed, 2 Oct 2019 17:02:18 +0800 Subject: [PATCH 066/420] Update help command --- src/main/java/duke/core/Ui.java | 18 ++++++++++-------- .../java/duke/task/FixedDurationTaskTest.java | 4 ++++ 2 files changed, 14 insertions(+), 8 deletions(-) create mode 100644 src/test/java/duke/task/FixedDurationTaskTest.java diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index eaabe10ab2..3c0b906192 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -201,19 +201,21 @@ public void showWelcome() { } public void showHelpCommand () { - System.out.println("1. list - to show a list of tasks\n"); - System.out.println("2. delete - to delete a task\n"); + System.out.println("Here are the things you can do with Dukepital:\n"); + System.out.println("1. list - to show a list of all the tasks\n"); + System.out.println("2. delete - to delete a task in the list\n"); System.out.println("3. done - to set a task as completed\n"); - System.out.println("4. find - to find a task from the list\n"); + System.out.println("4. find - to find a task based on keywords from the list\n"); System.out.println("5. todo - to add a todo task\n"); - System.out.println("6. fixeddurationtask - to add a fixed duration task\n"); - System.out.println("7. deadline - to add a deadline task\n"); - System.out.println("8. event - to add a event task\n"); + System.out.println("6. fixeddurationtask - to add a task with fixed duration\n"); + System.out.println("7. deadline - to add a task with a deadline\n"); + System.out.println("8. event - to add a task with date ad time\n"); System.out.println("9. period - to add a period task\n"); System.out.println("10. reschedule - to reschedule a task\n"); - System.out.println("11. view - to see a task of a specific date\n"); + System.out.println("11. view - to check a task of a specific date\n"); System.out.println("12. recurring - to make a task recurring\n"); - System.out.println("13. bye - to quit Dukepital\n"); + System.out.println("13. bye - to exit Dukepital\n"); + System.out.println("If you have any further enquiries, please contact us directly.\n"); } /** diff --git a/src/test/java/duke/task/FixedDurationTaskTest.java b/src/test/java/duke/task/FixedDurationTaskTest.java new file mode 100644 index 0000000000..49ac5721b9 --- /dev/null +++ b/src/test/java/duke/task/FixedDurationTaskTest.java @@ -0,0 +1,4 @@ +package duke.task; + +public class FixedDurationTaskTest { +} From 073a69470e647651924102e0a07c4db1e912cd4f Mon Sep 17 00:00:00 2001 From: kkeejjuunn Date: Wed, 2 Oct 2019 17:46:25 +0800 Subject: [PATCH 067/420] add JUnit test for FixedDurationTask --- .../java/duke/task/FixedDurationTaskTest.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/test/java/duke/task/FixedDurationTaskTest.java b/src/test/java/duke/task/FixedDurationTaskTest.java index 49ac5721b9..517e32fb9d 100644 --- a/src/test/java/duke/task/FixedDurationTaskTest.java +++ b/src/test/java/duke/task/FixedDurationTaskTest.java @@ -1,4 +1,24 @@ package duke.task; +import duke.core.DukeException; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + public class FixedDurationTaskTest { + /** + * Test the FixedDurationTask.toString() + */ + @Test + public void FixedDurationTaskStringTest() throws DukeException { + assertEquals("[F][\u2718] FixedDurationTaskTest (duration: 2 hours)", new FixedDurationTask("FixedDurationTaskTest", "2 hours").toString()); + } + + /** + * Test the fixeddurationtask.writeTxt() + */ + @Test + public void writeFormatTest() { + assertEquals( "F | 0 | FixedDurationTest | 1 hour | false",new FixedDurationTask("FixedDurationTest", "1 hour").writeTxt(), "The writeToFile format is not expected"); + } } From 121656acc9a5e2c06474639f684a0a09b6fde44f Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Wed, 2 Oct 2019 20:40:09 +0800 Subject: [PATCH 068/420] Update gitignore to ignore JAR files --- .gitignore | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/.gitignore b/.gitignore index 9bb4fab266..cc2a9133b5 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,23 @@ src/main/resources/docs/ *.iml bin/ data/duke.txt +build/test-results/test/binary/results.bin +build/test-results/test/binary/output.bin.idx +build/test-results/test/binary/output.bin +build/test-results/test/TEST-duke.task.PeriodTaskTest.xml +build/scriptsShadow/duke.bat +build/scriptsShadow/duke +build/scripts/duke.bat +build/scripts/duke +build/reports/tests/test/packages/duke.task.html +build/distributions/duke-0.1.0.tar +build/distributions/duke-shadow-0.1.0.tar +build/distributions/duke-0.1.0.zip +build/reports/tests/test/classes/duke.task.PeriodTaskTest.html +build/libs/duke-0.1.0.jar +build/reports/tests/test/index.html +build/reports/tests/test/css/base-style.css +build/distributions/duke-shadow-0.1.0.zip +build/libs/mid-v1.1.jar +build/reports/tests/test/css/style.css +build/reports/tests/test/js/report.js From 71eaafa99b7dcf978d57cd7051ce87d32a6de836 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Wed, 2 Oct 2019 20:50:03 +0800 Subject: [PATCH 069/420] Update Junit Tests for recurring status format to be written in local files --- src/test/java/duke/task/DeadlineTest.java | 6 +++--- src/test/java/duke/task/EventTest.java | 6 +++--- src/test/java/duke/task/TodoTest.java | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/test/java/duke/task/DeadlineTest.java b/src/test/java/duke/task/DeadlineTest.java index c76d69f89c..8bf16926ed 100644 --- a/src/test/java/duke/task/DeadlineTest.java +++ b/src/test/java/duke/task/DeadlineTest.java @@ -21,7 +21,7 @@ public void deadlineStringTest() throws DukeException { */ @Test public void writeFormatTest() throws DukeException { - assertEquals( "D | 0 | deadlineTest | 02/12/1996 1235 | false",new Deadline("deadlineTest", "02/12/1996 1235").writeTxt(), "The writeToFile format is not expected"); + assertEquals( "D | 0 | deadlineTest | 02/12/1996 1235 | ONCE",new Deadline("deadlineTest", "02/12/1996 1235").writeTxt(), "The writeToFile format is not expected"); } /** @@ -48,12 +48,12 @@ public void deadlineTestCase() throws DukeException { Deadline deadline = new Deadline("deadlineTest", "02/12/1996 1235"); assertFalse(deadline.isDone(), "The newly created deadline should not be done"); assertEquals( "[D][\u2718] deadlineTest (by: 2nd of December 1996, 12PM)",deadline.toString(), "The writeToFile format is not expected"); - assertEquals( "D | 0 | deadlineTest | 02/12/1996 1235 | false",deadline.writeTxt(), "The writeToFile format is not expected"); + assertEquals( "D | 0 | deadlineTest | 02/12/1996 1235 | ONCE",deadline.writeTxt(), "The writeToFile format is not expected"); // Mark the deadline as done and check its toString() and writeTxt() deadline.markAsDone(); assertTrue(deadline.isDone(), "The deadline should be marked as done"); assertEquals("[D][\u2713] deadlineTest (by: 2nd of December 1996, 12PM)", deadline.toString(), "The deadline.toString() is not expected"); - assertEquals( "D | 1 | deadlineTest | 02/12/1996 1235",deadline.writeTxt(), "The writeToFile format is not expected"); + assertEquals( "D | 1 | deadlineTest | 02/12/1996 1235 | ONCE",deadline.writeTxt(), "The writeToFile format is not expected"); } } diff --git a/src/test/java/duke/task/EventTest.java b/src/test/java/duke/task/EventTest.java index 403161deaf..36162e1300 100644 --- a/src/test/java/duke/task/EventTest.java +++ b/src/test/java/duke/task/EventTest.java @@ -21,7 +21,7 @@ public void EventStringTest() throws DukeException { */ @Test public void writeFormatTest() throws DukeException { - assertEquals( "E | 0 | test | 02/12/1996 1235 | false",new Event("test", "02/12/1996 1235").writeTxt(), "The writeToFile format is not expected"); + assertEquals( "E | 0 | test | 02/12/1996 1235 | ONCE",new Event("test", "02/12/1996 1235").writeTxt(), "The writeToFile format is not expected"); } /** @@ -48,12 +48,12 @@ public void eventTestCase() throws DukeException { Event event = new Event("eventTest", "02/12/1996 1235"); assertFalse(event.isDone(), "The newly created event should not be done"); assertEquals( "[E][\u2718] eventTest (at: 2nd of December 1996, 12PM)",event.toString(), "The writeToFile format is not expected"); - assertEquals( "E | 0 | eventTest | 02/12/1996 1235 | false",event.writeTxt(), "The writeToFile format is not expected"); + assertEquals( "E | 0 | eventTest | 02/12/1996 1235 | ONCE",event.writeTxt(), "The writeToFile format is not expected"); // Mark the event as done and check its toString() and writeTxt() event.markAsDone(); assertTrue(event.isDone(), "The event should be marked as done"); assertEquals("[E][\u2713] eventTest (at: 2nd of December 1996, 12PM)", event.toString(), "The event.toString() is not expected"); - assertEquals( "E | 1 | eventTest | 02/12/1996 1235 | false",event.writeTxt(), "The writeToFile format is not expected"); + assertEquals( "E | 1 | eventTest | 02/12/1996 1235 | ONCE",event.writeTxt(), "The writeToFile format is not expected"); } } \ No newline at end of file diff --git a/src/test/java/duke/task/TodoTest.java b/src/test/java/duke/task/TodoTest.java index e24e18f92a..1043f9a2f4 100644 --- a/src/test/java/duke/task/TodoTest.java +++ b/src/test/java/duke/task/TodoTest.java @@ -21,7 +21,7 @@ public void todoStringTest(){ */ @Test public void writeFormatTest() { - assertEquals( "T | 0 | todoTest | false",new Todo("todoTest").writeTxt(), "The writeToFile format is not expected"); + assertEquals( "T | 0 | todoTest | ONCE",new Todo("todoTest").writeTxt(), "The writeToFile format is not expected"); } /** @@ -48,12 +48,12 @@ public void todoTestCase() throws DukeException { Todo todo = new Todo("todoTest"); assertFalse(todo.isDone(), "The newly created todo should not be done"); assertEquals( "[T][\u2718] todoTest",todo.toString(), "The writeToFile format is not expected"); - assertEquals( "T | 0 | todoTest | false",todo.writeTxt(), "The writeToFile format is not expected"); + assertEquals( "T | 0 | todoTest | ONCE",todo.writeTxt(), "The writeToFile format is not expected"); // Mark the task as done and check its toString() and writeTxt() todo.markAsDone(); assertTrue(todo.isDone(), "The todo should be marked as done"); assertEquals("[T][\u2713] todoTest", todo.toString(), "The todo.toString() is not expected"); - assertEquals( "T | 1 | todoTest",todo.writeTxt(), "The writeToFile format is not expected"); + assertEquals( "T | 1 | todoTest | ONCE",todo.writeTxt(), "The writeToFile format is not expected"); } } \ No newline at end of file From 7e61da92cd0124ae3a8dd2e1f74f886ca41216ae Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Wed, 2 Oct 2019 20:59:01 +0800 Subject: [PATCH 070/420] Update Junit test for parsing command to period task and rescheduling a task. --- src/test/java/duke/core/ParserTest.java | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/test/java/duke/core/ParserTest.java b/src/test/java/duke/core/ParserTest.java index 3870c34942..69b4e1ad7e 100644 --- a/src/test/java/duke/core/ParserTest.java +++ b/src/test/java/duke/core/ParserTest.java @@ -1,13 +1,6 @@ package duke.core; -import duke.command.AddCommand; -import duke.command.Command; -import duke.command.DeleteCommand; -import duke.command.DoneCommand; -import duke.command.ExitCommand; -import duke.command.FindCommand; -import duke.command.ListCommand; -import duke.command.ViewCommand; +import duke.command.*; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -28,6 +21,8 @@ public void commandTypeTest() throws DukeException { Command c7 = Parser.parse("event Meeting /at 27/07/2020 1630"); Command c8 = Parser.parse("deadline event Homework ABC /by 27/07/2020 1630"); Command c9 = Parser.parse("view 16/09/2019"); + Command c10 = Parser.parse("period periodTaskTest /from 27/07/2020 1630 /to 27/08/2020 1630"); + Command c11 = Parser.parse("reschedule 1 27/07/2020 1630"); assertTrue(c1 instanceof ExitCommand, "The command type should be "); assertTrue(c2 instanceof DoneCommand, "The command type should be 'DoneCommand'"); @@ -38,5 +33,7 @@ public void commandTypeTest() throws DukeException { assertTrue(c7 instanceof AddCommand, "The command type should be 'AddCommand'"); assertTrue(c8 instanceof AddCommand, "The command type should be 'AddCommand'"); assertTrue(c9 instanceof ViewCommand, "The command type should be 'ViewCommand'"); + assertTrue(c10 instanceof AddCommand, "The command type should be 'AddCommand'"); + assertTrue(c11 instanceof RescheduleCommand, "The command type should be 'RescheduleCommand'"); } } From 708cfc6fb88dc788a1d67ec79cbb12e15c4affee Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Mon, 7 Oct 2019 23:32:17 +0800 Subject: [PATCH 071/420] Implemented external libraries commons-csv-1.7 with sample csv file to for testing --- build.gradle | 1 + data/file.csv | 3 +++ 2 files changed, 4 insertions(+) create mode 100644 data/file.csv diff --git a/build.gradle b/build.gradle index 69c03f09dd..d799ed1cda 100644 --- a/build.gradle +++ b/build.gradle @@ -21,6 +21,7 @@ shadowJar { dependencies { testImplementation 'org.junit.jupiter:junit-jupiter:5.5.0' + compile "org.apache.commons:commons-csv:1.7" } test { diff --git a/data/file.csv b/data/file.csv new file mode 100644 index 0000000000..2153b8c33d --- /dev/null +++ b/data/file.csv @@ -0,0 +1,3 @@ +First Name,Last Name +xk,1 +xk,2 From 5db25edd5ff56e040ddd367dda49ddcb8dc49638 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Mon, 7 Oct 2019 23:38:15 +0800 Subject: [PATCH 072/420] Update code to test reading data from csv file with header --- data/duke.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/data/duke.txt b/data/duke.txt index 0a0e3316a6..9a42562322 100644 --- a/data/duke.txt +++ b/data/duke.txt @@ -10,6 +10,7 @@ E | 0 | abc | 24/09/2019 1530 | DAILY P | 0 | abc | 27/08/2019 1630 | 29/11/2020 1630 P | 0 | abc | 27/08/2019 1630 | 29/11/2020 1630 P | 0 | abc | 27/08/2019 1630 | 29/11/2020 1630 -E | 1 | dog | 24/09/2019 0001 | MONTHLY +E | 0 | dog | 24/09/2019 0001 | MONTHLY D | 0 | cat | 11/10/2019 0001 | DAILY E | 0 | rabbit | 23/09/2019 0909 | WEEKLY +T | 0 | 1234 | ONCE From 6aa463a8c41d80b0e440ce3a1eed3e766fcc70e7 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Mon, 7 Oct 2019 23:46:16 +0800 Subject: [PATCH 073/420] Update csv reading test code in Duke --- src/main/java/duke/Duke.java | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index 843cfc313e..6260883055 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -7,6 +7,13 @@ import duke.core.Storage; import duke.core.TaskList; import duke.core.Ui; +import org.apache.commons.csv.CSVFormat; +import org.apache.commons.csv.CSVRecord; + +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.io.Reader; /** * Represents Duke, a Personal Assistant to help @@ -49,6 +56,11 @@ public Duke(String filePath) { * Reads user input until a "bye" message is received. */ public void run() { + try { + testCSV(); + } catch (IOException e) { + e.printStackTrace(); + } globalUi.showWelcome(); boolean isExit = false; while (!isExit) { @@ -80,4 +92,14 @@ public static void main(String[] args) { t1.start(); t2.start(); } + public void testCSV() throws FileNotFoundException, IOException { + Reader in = new FileReader("./data/file.csv"); + Iterable records = CSVFormat.EXCEL.withHeader("Last Name", "First Name").withFirstRecordAsHeader().parse(in); +// Iterable records = CSVFormat.EXCEL.parse(in); + for (CSVRecord record : records) { + String lastName = record.get("Last Name"); + String firstName = record.get("First Name"); + System.out.println(lastName + " | " + firstName); + } + } } From f50bc588734c8448178c7f6c7c55ba164afa8468 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Tue, 8 Oct 2019 02:39:46 +0800 Subject: [PATCH 074/420] Implemented Patient and PatientList to store loaded patient data --- src/main/java/duke/Duke.java | 1 + src/main/java/duke/core/Storage.java | 7 ++- src/main/java/duke/patient/Patient.java | 58 +++++++++++++++++++++ src/main/java/duke/patient/PatientList.java | 34 ++++++++++++ 4 files changed, 96 insertions(+), 4 deletions(-) create mode 100644 src/main/java/duke/patient/Patient.java create mode 100644 src/main/java/duke/patient/PatientList.java diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index 6260883055..e10694be92 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -95,6 +95,7 @@ public static void main(String[] args) { public void testCSV() throws FileNotFoundException, IOException { Reader in = new FileReader("./data/file.csv"); Iterable records = CSVFormat.EXCEL.withHeader("Last Name", "First Name").withFirstRecordAsHeader().parse(in); + Iterable records = CSVFormat.EXCEL.withHeader("Last Name", "First Name").withFirstRecordAsHeader().parse(in).getRecords(); // Iterable records = CSVFormat.EXCEL.parse(in); for (CSVRecord record : records) { String lastName = record.get("Last Name"); diff --git a/src/main/java/duke/core/Storage.java b/src/main/java/duke/core/Storage.java index b8f5f4861d..3001d8135d 100644 --- a/src/main/java/duke/core/Storage.java +++ b/src/main/java/duke/core/Storage.java @@ -1,11 +1,10 @@ package duke.core; import duke.task.*; +import org.apache.commons.csv.CSVFormat; +import org.apache.commons.csv.CSVRecord; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileWriter; -import java.io.IOException; +import java.io.*; import java.util.ArrayList; import java.util.Scanner; diff --git a/src/main/java/duke/patient/Patient.java b/src/main/java/duke/patient/Patient.java new file mode 100644 index 0000000000..9ed82028ed --- /dev/null +++ b/src/main/java/duke/patient/Patient.java @@ -0,0 +1,58 @@ +package duke.patient; +/** + * Represents a Patient. + */ +public class Patient { + private int id; + private String name; + private String preference; + private String remark; + private boolean isHospitalised; + private String room; + + /** + * Initialises the minimum fields required to setup a Patient. + * + * @param id A unique integer represents id of the patient. + * @param name A String that represent the full name of the patient. + * @param isHospitalised A boolean value that represents the hospitalised data of the patient. + * @param remark Remark leaves by nurses. + * @param preference A string that represents the daily preference of the patient. + */ + public Patient(int id, String name, boolean isHospitalised, String room, String remark, String preference) { + this.id = id; + this.name = name; + this.isHospitalised = isHospitalised; + this.remark = remark; + this.room = room; + this.preference = preference; + } + + public String getName() { + return name; //return tick or X symbols + } + + public int getID(){ + return id; + } + + public boolean isHospitalised(){ + return isHospitalised; + } + + public String getRemark(){ + return remark; + } + + public String getPreference(){ + return preference; + } + + public String getRoom(){ + return room; + } + + public void checkOut() { + isHospitalised = false; + } +} \ No newline at end of file diff --git a/src/main/java/duke/patient/PatientList.java b/src/main/java/duke/patient/PatientList.java new file mode 100644 index 0000000000..e914954d2c --- /dev/null +++ b/src/main/java/duke/patient/PatientList.java @@ -0,0 +1,34 @@ +package duke.patient; + +import duke.core.DukeException; +import duke.task.Task; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class PatientList { + +// private HashMap allPatientsMap = new HashMap(); +// private HashMap activePatientsMap = new HashMap(); + private List patients = new ArrayList(); + + /** + * instantiate a new TaskList with a empty list. + */ + public PatientList(List patientList) { + this.patients = patientList; + } + + public Patient getPatient(int id){ + return patients.get(id); + } + + public void addPatient(Patient patient) { + patients.add(patient); + } + + public void updatePatientInfo(int id, Patient patient){ + patients.set(id, patient); + } +} From 45e9c252f2fb34f4544c563c40c3fec9e2f08ce6 Mon Sep 17 00:00:00 2001 From: lmtaek Date: Tue, 8 Oct 2019 13:07:26 +0800 Subject: [PATCH 075/420] beginnings of new Task classes for skeleton Dukepital --- src/main/java/duke/task1/PersonalTask.java | 18 +++ src/main/java/duke/task1/StandardTask.java | 18 +++ src/main/java/duke/task1/Task.java | 121 +++++++++++++++++++++ 3 files changed, 157 insertions(+) create mode 100644 src/main/java/duke/task1/PersonalTask.java create mode 100644 src/main/java/duke/task1/StandardTask.java create mode 100644 src/main/java/duke/task1/Task.java diff --git a/src/main/java/duke/task1/PersonalTask.java b/src/main/java/duke/task1/PersonalTask.java new file mode 100644 index 0000000000..2473126ed0 --- /dev/null +++ b/src/main/java/duke/task1/PersonalTask.java @@ -0,0 +1,18 @@ +package duke.task1; + +import java.util.ArrayList; + +public class PersonalTask extends Task { + + //private patient Patient; + + public PersonalTask (String description) { //2nd parameter: Patient + super(description); + //this.patient = patient; + } + + @Override + public String writeTxt() { + return null; + } +} \ No newline at end of file diff --git a/src/main/java/duke/task1/StandardTask.java b/src/main/java/duke/task1/StandardTask.java new file mode 100644 index 0000000000..4e8c3ce1c8 --- /dev/null +++ b/src/main/java/duke/task1/StandardTask.java @@ -0,0 +1,18 @@ +package duke.task1; + +import java.util.ArrayList; + +public class StandardTask extends Task { + + ArrayList patientIdList; + + public StandardTask (String description) { + super(description); + this.patientIdList = new ArrayList(); //read doc + upload task's list of patients, or make new list + } + + @Override + public String writeTxt() { + return null; + } +} diff --git a/src/main/java/duke/task1/Task.java b/src/main/java/duke/task1/Task.java new file mode 100644 index 0000000000..beabb0716b --- /dev/null +++ b/src/main/java/duke/task1/Task.java @@ -0,0 +1,121 @@ +package duke.task1; + +import duke.core.DateTimeParser; +import duke.core.DukeException; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.ArrayList; + + +/** + * Represents a task. Task is an abstract class that can not be + * instantiated + */ +public abstract class Task { + + /** + * A String that represents the description of the task. + */ + private String description; + + /** + * A boolean that represents the status of the task( 1 means done, 0 means not yet). + */ + private boolean isDone; + + /** + * A string to describe the date/time of the task. + */ + private String dateTime = null; + + /** + * An arraylist of things the nurse can bring for the task. + */ + private ArrayList thingsToBring; + + /** + * Initialises the minimum fields required to setup a Task. + * + * @param description A string that represents the description of certain task. + */ + public Task(String description, String dateTime) { + this.description = description; + this.isDone = false; + this.thingsToBring = new ArrayList(); + this.dateTime = dateTime; + } + + public Task(String description) { + this.description = description; + this.thingsToBring = new ArrayList(); + this.isDone = false; + } + + /** + * Returns an icon that represents the status of the task. + * + * @return Tick if completed, cross if uncompleted. + */ + public String getStatusIcon() { + return (isDone ? "\u2713" : "\u2718"); //return tick or X symbols + } + + /** + * Check if the task isDone. + * + * @return boolean value of isDone + */ + public boolean isDone() { + return this.isDone; + } + + /** + * Marks the task as done. + */ + public void markAsDone() { + isDone = true; + } + + /** + * Returns a string with the following format to be stored in a local file. + * + * @return A string in a specific format to be stored in a local file. + */ + public abstract String writeTxt(); + + /** + * Returns a string with the status icon and the description of the task. + * + * @return A string in a specific format with the status and description of the task. + */ + public String printStatus() { + return "[" + this.getStatusIcon() + "] " + description; + } + + /** + * Returns the description of the task. + * + * @return A string that represents the specific activity associated with + * the task. + */ + public String getDescription() { + return description; + } + + /** + * update the dateTime String to save the date and time + * @param newDateTime the time retrieved from user input. + */ + public void updateDateTime(String newDateTime) { this.dateTime = newDateTime; } + + /** + * Returns the dateTime String. + * + */ + public String getDateTime() + { return dateTime; } + + public void addThingToBring(String object) { thingsToBring.add(object); } + +} \ No newline at end of file From 6ef5fcc9c8eaef67db66fde520513e958adeb80e Mon Sep 17 00:00:00 2001 From: lmtaek Date: Tue, 8 Oct 2019 13:51:44 +0800 Subject: [PATCH 076/420] created skeleton version of Dukepital. removed redundant methods/classes --- src/main/java/duke/Duke.java | 63 +++----- src/main/java/duke/Reminder.java | 73 --------- src/main/java/duke/command/AddCommand.java | 107 ------------- src/main/java/duke/command/Command.java | 2 +- src/main/java/duke/command/DeleteCommand.java | 59 ------- src/main/java/duke/command/DoneCommand.java | 59 ------- src/main/java/duke/command/ExitCommand.java | 2 +- src/main/java/duke/command/FindCommand.java | 51 ------ .../duke/command/FindFreeTimesCommand.java | 4 - src/main/java/duke/command/HelpCommand.java | 2 +- src/main/java/duke/command/ListCommand.java | 43 ----- .../java/duke/command/RecurringCommand.java | 61 -------- src/main/java/duke/command/RemindCommand.java | 48 ------ .../java/duke/command/RescheduleCommand.java | 63 -------- src/main/java/duke/command/ViewCommand.java | 46 ------ src/main/java/duke/core/CommandManager.java | 45 ++++++ src/main/java/duke/core/DukeException.java | 2 +- src/main/java/duke/core/Parser.java | 133 ---------------- src/main/java/duke/core/Storage.java | 70 +-------- src/main/java/duke/core/Ui.java | 147 +++++++++--------- src/main/java/duke/task/Deadline.java | 81 ---------- src/main/java/duke/task/Event.java | 79 ---------- .../java/duke/task/FixedDurationTask.java | 46 ------ src/main/java/duke/task/PeriodTask.java | 59 ------- .../duke/{task1 => task}/PersonalTask.java | 4 +- src/main/java/duke/task/RecurringTask.java | 63 -------- .../duke/{task1 => task}/StandardTask.java | 2 +- src/main/java/duke/task/Task.java | 96 ++++-------- .../java/duke/{core => task}/TaskList.java | 5 +- src/main/java/duke/task/Todo.java | 47 ------ src/main/java/duke/task1/Task.java | 121 -------------- ...arserTest.java => CommandManagerTest.java} | 24 +-- src/test/java/duke/task/RecurringTest.java | 3 - 33 files changed, 187 insertions(+), 1523 deletions(-) delete mode 100644 src/main/java/duke/Reminder.java delete mode 100644 src/main/java/duke/command/AddCommand.java delete mode 100644 src/main/java/duke/command/DeleteCommand.java delete mode 100644 src/main/java/duke/command/DoneCommand.java delete mode 100644 src/main/java/duke/command/FindCommand.java delete mode 100644 src/main/java/duke/command/FindFreeTimesCommand.java delete mode 100644 src/main/java/duke/command/ListCommand.java delete mode 100644 src/main/java/duke/command/RecurringCommand.java delete mode 100644 src/main/java/duke/command/RemindCommand.java delete mode 100644 src/main/java/duke/command/RescheduleCommand.java delete mode 100644 src/main/java/duke/command/ViewCommand.java create mode 100644 src/main/java/duke/core/CommandManager.java delete mode 100644 src/main/java/duke/core/Parser.java delete mode 100644 src/main/java/duke/task/Deadline.java delete mode 100644 src/main/java/duke/task/Event.java delete mode 100644 src/main/java/duke/task/FixedDurationTask.java delete mode 100644 src/main/java/duke/task/PeriodTask.java rename src/main/java/duke/{task1 => task}/PersonalTask.java (85%) delete mode 100644 src/main/java/duke/task/RecurringTask.java rename src/main/java/duke/{task1 => task}/StandardTask.java (95%) rename src/main/java/duke/{core => task}/TaskList.java (97%) delete mode 100644 src/main/java/duke/task/Todo.java delete mode 100644 src/main/java/duke/task1/Task.java rename src/test/java/duke/core/{ParserTest.java => CommandManagerTest.java} (61%) diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index 6260883055..e3f11986d9 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -3,17 +3,10 @@ import duke.command.Command; import duke.core.DukeException; -import duke.core.Parser; +import duke.core.CommandManager; import duke.core.Storage; -import duke.core.TaskList; +import duke.task.TaskList; import duke.core.Ui; -import org.apache.commons.csv.CSVFormat; -import org.apache.commons.csv.CSVRecord; - -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.IOException; -import java.io.Reader; /** * Represents Duke, a Personal Assistant to help @@ -24,16 +17,16 @@ public class Duke implements Runnable { * A Storage object that handles reading tasks from a local * file and saving them to the same file. */ - public static Storage globalStorage; + private Storage storage; /** * A TaskList object that deals with add, delete, mark as done, * find functions of a list of tasks. */ - public static TaskList globalTasks; + private TaskList tasks; /** * A Ui object that deals with interactions with the user. */ - public static Ui globalUi; + private Ui ui; /** * Constructs a Duke object with a relative file path. * Initialize the user interface and reads tasks from the specific text file. @@ -41,13 +34,13 @@ public class Duke implements Runnable { * used for storing tasks. */ public Duke(String filePath) { - globalUi = new Ui(); - globalStorage = new Storage(filePath); + ui = new Ui(); + storage = new Storage(filePath); try { - globalTasks = new TaskList(globalStorage.load()); + tasks = new TaskList(storage.load()); } catch (DukeException e) { - globalUi.showLoadingError(); - globalTasks = new TaskList(); + ui.showLoadingError(); + tasks = new TaskList(); } } @@ -56,24 +49,19 @@ public Duke(String filePath) { * Reads user input until a "bye" message is received. */ public void run() { - try { - testCSV(); - } catch (IOException e) { - e.printStackTrace(); - } - globalUi.showWelcome(); + ui.showWelcome(); boolean isExit = false; while (!isExit) { try { - String fullCommand = globalUi.readCommand(); - globalUi.showLine(); - Command c = Parser.parse(fullCommand); - c.execute(globalTasks, globalUi, globalStorage); + String fullCommand = ui.readCommand(); + ui.showLine(); + Command c = CommandManager.manageCommand(fullCommand); + c.execute(tasks, ui, storage); isExit = c.isExit(); } catch (DukeException e) { - globalUi.showError(e.getMessage()); + ui.showError(e.getMessage()); } finally { - globalUi.showLine(); + ui.showLine(); } } System.exit(0); @@ -85,21 +73,6 @@ public void run() { * @param args The command line arguments. */ public static void main(String[] args) { - Duke d = new Duke("./data/duke.txt"); - Reminder r = new Reminder(globalTasks,globalUi); - Thread t1 = new Thread(d); - Thread t2 = new Thread(r); - t1.start(); - t2.start(); - } - public void testCSV() throws FileNotFoundException, IOException { - Reader in = new FileReader("./data/file.csv"); - Iterable records = CSVFormat.EXCEL.withHeader("Last Name", "First Name").withFirstRecordAsHeader().parse(in); -// Iterable records = CSVFormat.EXCEL.parse(in); - for (CSVRecord record : records) { - String lastName = record.get("Last Name"); - String firstName = record.get("First Name"); - System.out.println(lastName + " | " + firstName); - } + new Duke("./data/duke.txt").run(); } } diff --git a/src/main/java/duke/Reminder.java b/src/main/java/duke/Reminder.java deleted file mode 100644 index ddae312cc4..0000000000 --- a/src/main/java/duke/Reminder.java +++ /dev/null @@ -1,73 +0,0 @@ -package duke; - -import duke.core.TaskList; -import duke.core.Ui; -import duke.task.Task; -import java.time.LocalDate; -import java.time.temporal.ChronoUnit; -import java.time.Duration; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.Period; -import java.time.format.DateTimeFormatter; -import java.time.format.DateTimeParseException; -import java.util.ArrayList; -import java.util.Date; -import java.util.Timer; -import java.util.TimerTask; - -public class Reminder implements Runnable { - /** - * A constant represents the seconds in a day. - */ - static final int SECONDS_IN_A_DAY = 86400; - /** - * A TaskList object that deals with add, delete, mark as done, - * find functions of a list of tasks. - */ - private TaskList tasks; - /** - * A Ui object that deals with interactions with the user. - */ - private Ui ui; - /** - * Constructs a Reminder object with a TaskList and Ui object. - * @param returnTask A TaskList object that deals with add, delete and other functions. - * @param returnUi A Ui object that deals with interactions with the user. - */ - public Reminder(TaskList returnTask, Ui returnUi) { - this.tasks = returnTask; - this.ui = returnUi; - } - - /** - * Execute the reminder program. - * The methods inside will be triggered base on the Timer's time interval. - */ - public void run() { - TimerTask timerTask = new TimerTask() { - @Override - public void run() { - ArrayList tempTask = new ArrayList<>(); - for (Task v : tasks.fullTaskList()) { - if (!(v.getDateTime() == null)) - { - int seconds = (int) ChronoUnit.SECONDS.between(v.getDateTime(), LocalDateTime.now()); - if ((!v.isDone()) && Math.abs(seconds) < SECONDS_IN_A_DAY) { - tempTask.add(v); - } - } - } - if (!tempTask.isEmpty()) { - ui.taskReminder(tempTask); - } - } - }; - - Timer timer = new Timer("Timer"); - long delay = 20000L; - long period = 20000L; - timer.scheduleAtFixedRate(timerTask, delay, period); - } - -} diff --git a/src/main/java/duke/command/AddCommand.java b/src/main/java/duke/command/AddCommand.java deleted file mode 100644 index 9172026ab5..0000000000 --- a/src/main/java/duke/command/AddCommand.java +++ /dev/null @@ -1,107 +0,0 @@ -package duke.command; - -import duke.core.DukeException; -import duke.core.Storage; -import duke.core.TaskList; -import duke.core.Ui; -import duke.task.Deadline; -import duke.task.Event; -import duke.task.Task; - -import java.util.ArrayList; -import java.util.Scanner; - -/** - * Represents a command class to add a task. The AddCommand class - * extends from the Command class to represent user instruction - * to add a new ToDo, FixedDurationTask, Deadline or Event - * task to the TaskList. - */ -public class AddCommand extends Command { - /** - * A new task to be added - */ - private Task newTask; - private Boolean isClash = false; - - /** - * Constructs a AddCommand object. - * - * @param newTask Specifies the task to be added. - */ - public AddCommand(Task newTask) { - super(); - this.newTask = newTask; - } - - /** - * Indicates whether Duke should exist - * - * @return A boolean. True if the command tells Duke to exit, false - * otherwise. - */ - @Override - public boolean isExit() { - return false; - } - - /** - * run the command with the respect TaskList, UI, and storage. - * - * @param tasks The task list where tasks are saved. - * @param ui The user interface. - * @param storage object that handles local text file update - */ - @Override - public void execute(TaskList tasks, Ui ui, Storage storage) throws DukeException { - try { - ArrayList tasksInTheList = tasks.fullTaskList(); - ArrayList clashTasksInTheList = new ArrayList(); - - /** - * Check whether the tasks in the list are clashed , if yes then store the clashed tasks into - * a new array list - */ - for (Task t : tasksInTheList) { - if ((t instanceof Deadline || t instanceof Event) && (newTask instanceof Deadline || newTask instanceof Event) ){ - if (t.getDate().equals(newTask.getDate()) && !t.isDone()) { - clashTasksInTheList.add(t); - isClash = true; - } - } - } - - - if (isClash) { - ui.showClashWarning(clashTasksInTheList , newTask); - Scanner input = new Scanner(System.in); - boolean isValidUserInput = false ; - /** - * Check if the user have enter the correct input , this check will continue - * until the user has enter the correct input - */ - while (!isValidUserInput) { - String userInput = input.nextLine(); - if (userInput.equals("Y") || userInput.equals("N") ) { - isValidUserInput = true; - if (userInput.equals("Y")) { - tasks.addTask(newTask); - ui.taskAdded(newTask, tasks.getSize()); - storage.save(tasks.fullTaskList()); - } else { - System.out.println("Alright , I have aborted the task."); - } - } else { - System.out.println("Please enter Y or N only ! (Cap Sensitive) "); - } - } - }else{ - tasks.addTask(newTask); - ui.taskAdded(newTask, tasks.getSize()); - storage.save(tasks.fullTaskList()); - } - } catch (DukeException e) { - throw new DukeException("Fails to add task. " + e.getMessage()); - } - } -} diff --git a/src/main/java/duke/command/Command.java b/src/main/java/duke/command/Command.java index ad056aa224..9bfc1de7e4 100644 --- a/src/main/java/duke/command/Command.java +++ b/src/main/java/duke/command/Command.java @@ -2,7 +2,7 @@ import duke.core.DukeException; import duke.core.Storage; -import duke.core.TaskList; +import duke.task.TaskList; import duke.core.Ui; /** diff --git a/src/main/java/duke/command/DeleteCommand.java b/src/main/java/duke/command/DeleteCommand.java deleted file mode 100644 index 542f1120e9..0000000000 --- a/src/main/java/duke/command/DeleteCommand.java +++ /dev/null @@ -1,59 +0,0 @@ -package duke.command; - -import duke.core.DukeException; -import duke.core.Storage; -import duke.core.TaskList; -import duke.core.Ui; -import duke.task.Task; - -/** - * Represents a command to delete a task. The command.DeleteCommand class - * extends from the Command class to represent user instruction - * to delete an task from task list. - */ -public class DeleteCommand extends Command { - /** - * The index of the task to be deleted. - */ - private int taskId; - - /** - * Constructs a DeleteCommand object. - * - * @param taskId Specifies the index of the task to be deleted. - */ - - public DeleteCommand(int taskId) { - super(); - this.taskId = taskId; - } - - /** - * Indicates whether Duke should exist. - * - * @return A boolean. True if the command tells Duke to exit, false - * otherwise. - */ - @Override - public boolean isExit() { - return false; - } - - /** - * run the command with the respect TaskList, UI, and storage. - * - * @param tasks The task list where tasks are saved. - * @param ui The user interface. - * @param storage object that handles local text file update - */ - public void execute(TaskList tasks, Ui ui, Storage storage) throws DukeException { - try { - Task task = tasks.getTask(taskId); - tasks.deleteTask(taskId); - ui.taskRemoved(task, tasks.getSize()); - storage.save(tasks.fullTaskList()); - } catch (DukeException e) { - throw new DukeException("Fails to delete task. " + e.getMessage()); - } - } -} diff --git a/src/main/java/duke/command/DoneCommand.java b/src/main/java/duke/command/DoneCommand.java deleted file mode 100644 index 68dd46d23d..0000000000 --- a/src/main/java/duke/command/DoneCommand.java +++ /dev/null @@ -1,59 +0,0 @@ -package duke.command; - -import duke.core.DukeException; -import duke.core.Storage; -import duke.core.TaskList; -import duke.core.Ui; -import duke.task.Task; - -/** - * Represents a command to mark a task as done. The DoneCommand - * class extends from the Command class to represent user - * instruction to mark an existing task. - */ -public class DoneCommand extends Command { - /** - * The index of the task to be marked as done. - */ - private int taskId; - - /** - * Constructs a DoneCommand object. - * - * @param taskId Specifies the index of the task. - */ - public DoneCommand(int taskId) { - super(); - this.taskId = taskId; - } - - /** - * Indicates whether Duke should exist - * - * @return A boolean. True if the command tells Duke to exit, false - * otherwise. - */ - @Override - public boolean isExit() { - return false; - } - - /** - * run the command with the respect TaskList, UI, and storage. - * - * @param tasks The task list where tasks are saved. - * @param ui The user interface. - * @param storage object that handles local text file update - */ - @Override - public void execute(TaskList tasks, Ui ui, Storage storage) throws DukeException { - try { - Task task = tasks.getTask(taskId); - task.markAsDone(); - storage.save(tasks.fullTaskList()); - ui.markedAsDone(task); - } catch (DukeException e) { - throw new DukeException("Fails to mark task as done. " + e.getMessage()); - } - } -} diff --git a/src/main/java/duke/command/ExitCommand.java b/src/main/java/duke/command/ExitCommand.java index 78e97498e5..fd4a231fb9 100644 --- a/src/main/java/duke/command/ExitCommand.java +++ b/src/main/java/duke/command/ExitCommand.java @@ -1,7 +1,7 @@ package duke.command; import duke.core.Storage; -import duke.core.TaskList; +import duke.task.TaskList; import duke.core.Ui; /** diff --git a/src/main/java/duke/command/FindCommand.java b/src/main/java/duke/command/FindCommand.java deleted file mode 100644 index 757efc9001..0000000000 --- a/src/main/java/duke/command/FindCommand.java +++ /dev/null @@ -1,51 +0,0 @@ -package duke.command; - -import duke.core.DukeException; -import duke.core.Storage; -import duke.core.TaskList; -import duke.core.Ui; - -/** - * Represents a command to find a certain task from Duke's task list. - * The ExitCommand class extends from the Command - * class for the user to find a specific task object from the storage. - */ -public class FindCommand extends Command { - /** - * Name of the task to be found. - */ - private String taskName; - - /** - * Constructs a FindCommand object. - * - * @param name Specifies the name of the task. - */ - public FindCommand(String name) { - super(); - this.taskName = name; - } - - /** - * Indicates whether Duke should exist - * - * @return A boolean. True if the command tells Duke to exit, false - * otherwise. - */ - @Override - public boolean isExit() { - return false; - } - - /** - * run the command with the respect TaskList, UI, and storage. - * - * @param tasks The task list where tasks are saved. - * @param ui The user interface. - * @param storage object that handles local text file update - */ - @Override - public void execute(TaskList tasks, Ui ui, Storage storage) throws DukeException { - ui.taskFound(tasks.fullTaskList(), taskName); - } -} \ No newline at end of file diff --git a/src/main/java/duke/command/FindFreeTimesCommand.java b/src/main/java/duke/command/FindFreeTimesCommand.java deleted file mode 100644 index 27c047538f..0000000000 --- a/src/main/java/duke/command/FindFreeTimesCommand.java +++ /dev/null @@ -1,4 +0,0 @@ -package duke.command; - -public class FindFreeTimesCommand { -} diff --git a/src/main/java/duke/command/HelpCommand.java b/src/main/java/duke/command/HelpCommand.java index 2a71ce759c..92f6b35da9 100644 --- a/src/main/java/duke/command/HelpCommand.java +++ b/src/main/java/duke/command/HelpCommand.java @@ -2,7 +2,7 @@ import duke.core.DukeException; import duke.core.Storage; -import duke.core.TaskList; +import duke.task.TaskList; import duke.core.Ui; public class HelpCommand extends Command { diff --git a/src/main/java/duke/command/ListCommand.java b/src/main/java/duke/command/ListCommand.java deleted file mode 100644 index 674f62485b..0000000000 --- a/src/main/java/duke/command/ListCommand.java +++ /dev/null @@ -1,43 +0,0 @@ -package duke.command; - -import duke.core.DukeException; -import duke.core.Storage; -import duke.core.TaskList; -import duke.core.Ui; - -/** - * Represents a command to list all existing tasks in the task list. The - * ListCommand class extends from the command.Command class - * for the user to view the entire task list from Duke. - */ -public class ListCommand extends Command { - /** - * Constructs a command.ListCommand object. - */ - public ListCommand() { - super(); - } - - /** - * Indicates whether Duke should exist - * - * @return A boolean. True if the command tells Duke to exit, false - * otherwise. - */ - @Override - public boolean isExit() { - return false; - } - - /** - * run the command with the respect TaskList, UI, and storage. - * - * @param tasks The task list where tasks are saved. - * @param ui The user interface. - * @param storage object that handles local text file update - */ - @Override - public void execute(TaskList tasks, Ui ui, Storage storage) throws DukeException { - ui.listTasks(tasks); - } -} \ No newline at end of file diff --git a/src/main/java/duke/command/RecurringCommand.java b/src/main/java/duke/command/RecurringCommand.java deleted file mode 100644 index b5c51f6085..0000000000 --- a/src/main/java/duke/command/RecurringCommand.java +++ /dev/null @@ -1,61 +0,0 @@ -package duke.command; - -import duke.core.DukeException; -import duke.core.Storage; -import duke.core.TaskList; -import duke.core.Ui; -import duke.task.*; - -public class RecurringCommand extends Command { - - /** - * Used to identify the task being marked as recurring. - */ - private int taskIndex; - protected Task.RecurringFrequency frequency; - - public RecurringCommand(int taskIndex, Task.RecurringFrequency frequency) { - super(); - this.taskIndex = taskIndex; - this.frequency = frequency; - } - - /** - * Indicates whether Duke should exist - * - * @return A boolean. True if the command tells Duke to exit, false - * otherwise. - */ - @Override - public boolean isExit() { return false; } - - /** - * run the command with the respect TaskList, UI, and storage. - * - * Checks whether there is a DateTime for the listed task, and if so, - * marks it as 'recurring', calls the Ui to print a certain output, and informs - * storage that the task is now recurring. - * - * @param tasks The task list where tasks are saved. - * @param ui The user interface. - * @param storage object that handles local text file update - */ - @Override - public void execute(TaskList tasks, Ui ui, Storage storage) throws DukeException { - try { - Task task = tasks.getTask(taskIndex); - if (task.getDateTime() != null) { - if (!task.isTaskRecurring()) { - task.makeTaskRecurring(this.frequency); - ui.makeRecurring(task); - } else { - System.out.println("This task is already marked as recurring!"); - } - storage.save(tasks.fullTaskList()); - } - } catch (DukeException e) { - throw new DukeException("I couldn't make the task recurring. " + e); - } - - } -} diff --git a/src/main/java/duke/command/RemindCommand.java b/src/main/java/duke/command/RemindCommand.java deleted file mode 100644 index 601396e2ad..0000000000 --- a/src/main/java/duke/command/RemindCommand.java +++ /dev/null @@ -1,48 +0,0 @@ -package duke.command; - -import duke.core.DukeException; -import duke.core.Storage; -import duke.core.TaskList; -import duke.core.Ui; - -/** - * Represents a command to list all existing tasks in the task list. The - * ListCommand class extends from the command.Command class - * for the user to view the entire task list from Duke. - */ -public class RemindCommand extends Command { - /** - * The index of task to be reminded. - */ - protected int taskID; - /** - * Constructs a command.RemindCommand object. - */ - public RemindCommand(int taskName) { - super(); - this.taskID = taskName; - } - - /** - * Indicates whether Duke should exist - * - * @return A boolean. True if the command tells Duke to exit, false - * otherwise. - */ - @Override - public boolean isExit() { - return false; - } - - /** - * run the command with the respect TaskList, UI, and storage. - * - * @param tasks The task list where tasks are saved. - * @param ui The user interface. - * @param storage object that handles local text file update - */ - @Override - public void execute(TaskList tasks, Ui ui, Storage storage) throws DukeException { - ui.listTasks(tasks); - } -} \ No newline at end of file diff --git a/src/main/java/duke/command/RescheduleCommand.java b/src/main/java/duke/command/RescheduleCommand.java deleted file mode 100644 index 5099c0a136..0000000000 --- a/src/main/java/duke/command/RescheduleCommand.java +++ /dev/null @@ -1,63 +0,0 @@ -package duke.command; - -import duke.core.DukeException; -import duke.core.Storage; -import duke.core.TaskList; -import duke.core.Ui; -import duke.task.Task; -import duke.task.Todo; - -/** - * Represents a command to reschedule a task by updating its date/time. - */ -public class RescheduleCommand extends Command { - - private int taskId; - private String newDateTime; - - - /** - * Constructs a RescheduleCommand object. - * - * @param taskId The index of the task to be updated - * @param newDateTime The new time of which the task should be updated to, expected to be in the format of dd//MM/yyyy HHmm - */ - public RescheduleCommand(int taskId, String newDateTime) { - super(); - this.taskId = taskId; - this.newDateTime = newDateTime; - } - - /** - * run the command with the respect TaskList, UI, and storage. - * - * @param taskList The task list where tasks are saved. - * @param ui The user interface. - * @param storage object that handles local text file update - */ - @Override - public void execute(TaskList taskList, Ui ui, Storage storage) throws DukeException { - try{ - Task task = taskList.getTask(taskId); - if (task instanceof Todo){ - throw new DukeException("Todo task cannot be reschedule"); - } - task.updateLocalDateTime(newDateTime); - storage.save(taskList.fullTaskList()); - ui.taskRescheduled(task); - }catch(DukeException dukeException){ - throw new DukeException("Fails to reschedule task. " + dukeException.getMessage()); - } - } - - /** - * Indicates whether Duke should exist - * - * @return A boolean. True if the command tells Duke to exit, false - * otherwise. - */ - @Override - public boolean isExit() { - return false; - } -} diff --git a/src/main/java/duke/command/ViewCommand.java b/src/main/java/duke/command/ViewCommand.java deleted file mode 100644 index 64e7c0c8f7..0000000000 --- a/src/main/java/duke/command/ViewCommand.java +++ /dev/null @@ -1,46 +0,0 @@ -package duke.command; - -import duke.core.Storage; -import duke.core.TaskList; -import duke.core.Ui; - -public class ViewCommand extends Command { - private String date; - - /** - * Constructs and initialise a ViewCommand object. - * - * @param date Refers to the selected date of the schedule - */ - public ViewCommand (String date) { - super(); - this.date = date; - } - - - - /** - * Indicates whether Duke should exist - * - * @return A boolean. True if the command tells Duke to exit, false - * otherwise. - */ - @Override - public boolean isExit() { - return false; - } - - /** - * run the command with the respect TaskList, UI, and storage. - * - * @param tasks The task list where tasks are saved. - * @param ui The user interface. - * @param storage object that handles local text file update - */ - @Override - public void execute(TaskList tasks, Ui ui, Storage storage) { - ui.showSchedules(tasks.fullTaskList(), date); - } - -} - diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java new file mode 100644 index 0000000000..521b89a84e --- /dev/null +++ b/src/main/java/duke/core/CommandManager.java @@ -0,0 +1,45 @@ +package duke.core; + +import duke.command.*; +import duke.task.*; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; + +/** + * Represents a Parser that parses user input into a specific + * type of Command. + */ +public class CommandManager { + + /** + * Parses a Task from a string array. + * + * @param userInput The string array to be parsed. + * @return The Command received from user. + */ + public static Command manageCommand(String userInput) throws DukeException { + switch (userInput) { //change this depending on how string is parsed + case "list": + //do thing for 'list' + case "done": + //do thing for 'done' + case "delete": + //do thing for 'delete + case "find": + //do thing for 'find' + case "reschedule": + //do thing for 'reschedule' + case "view": + //do thing for 'view' + case "help": + //do thing for 'help' + case "bye": + return new ExitCommand(); + default: + throw new DukeException("Unrecognized user input!"); + } + } + +} diff --git a/src/main/java/duke/core/DukeException.java b/src/main/java/duke/core/DukeException.java index ba6ee52703..962eb5e054 100644 --- a/src/main/java/duke/core/DukeException.java +++ b/src/main/java/duke/core/DukeException.java @@ -2,6 +2,6 @@ public class DukeException extends Exception { public DukeException(String message) { - super("OOPS!!! " + message); + super("Oops, I wasn't able to understand that. " + message); } } \ No newline at end of file diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java deleted file mode 100644 index 63b8b3ab76..0000000000 --- a/src/main/java/duke/core/Parser.java +++ /dev/null @@ -1,133 +0,0 @@ -package duke.core; - -import duke.command.*; -import duke.task.*; - -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; - -/** - * Represents a Parser that parses user input into a specific - * type of Command. - */ -public class Parser { - - /** - * Parses a Task from a string array. - * - * @param ss The string array to be parsed. - * @return The Command received from user. - */ - public static Command parse(String ss) throws DukeException { - ss = ss.trim(); - String[] command = ss.split(" ", 2); - - switch (command[0]) { - case "list": - return new ListCommand(); - case "done": - try { - int i = Integer.parseInt(command[1]); - return new DoneCommand(i); - } catch (Exception e) { - throw new DukeException(e.getMessage()); - } - case "delete": - try { - int x = Integer.parseInt(command[1]); - return new DeleteCommand(x); - } catch (Exception e) { - throw new DukeException(e.getMessage()); - } - case "todo": - try { - Todo t = new Todo(command[1]); - return new AddCommand(t); - } catch (Exception e) { - throw new DukeException(e.getMessage()); - } - case "fixeddurationtask": - try { - String[] temp = command[1].split(" /needs "); - FixedDurationTask fixedDurationTask = new FixedDurationTask(temp[0], temp[1]); - return new AddCommand(fixedDurationTask); - } - catch (Exception e) { - throw new DukeException(e.getMessage()); - } - case "deadline": - try { - String[] temp = command[1].split(" /by "); - Deadline deadline = new Deadline(temp[0], temp[1]); - return new AddCommand(deadline); - } catch (Exception e) { - throw new DukeException(e.getMessage()); - } - case "event": - try { - String[] temp1 = command[1].split(" /at "); - Event event = new Event(temp1[0], temp1[1]); - return new AddCommand(event); - } catch (Exception e) { - throw new DukeException(e.getMessage()); - } - case "period": - try { - String[] strArray = command[1].split(" /from ", 2); - String[] strArray2 = strArray[1].split(" /to ",2); - PeriodTask periodTask = new PeriodTask(strArray[0], strArray2[0], strArray2[1]); - return new AddCommand(periodTask); - }catch (Exception e) { - throw new DukeException("Fail to create a period task. Please enter command in the format of 'period /from dd/MM/yyyy HHmm /to dd/MM/yyyy HHmm'."); - - } - case "find": - return new FindCommand(command[1]); - case "reschedule": - try { - String[] tempCommand = command[1].split(" ", 2); - return new RescheduleCommand(Integer.parseInt(tempCommand[0]), tempCommand[1]); - } catch (Exception e) { - throw new DukeException("Fail to reschedule task. Please enter command in the format of 'reschedule

'."); - } - case "view": - try { - DateFormat parser = new SimpleDateFormat("dd/M/yyyy"); - DateFormat formatter = new SimpleDateFormat("dd/M/yyyy"); - String date = formatter.format(parser.parse(command[1])); - return new ViewCommand(date); - - } catch (ParseException e) { - e.printStackTrace(); - } - case "recurring": - try { - String[] parsedInput = command[1].split(" /"); - int index = Integer.parseInt(parsedInput[0]); - if (parsedInput[1] != null) { - parsedInput[1] = parsedInput[1].trim(); - if (parsedInput[1].toLowerCase().contains("weekly")) { - return new RecurringCommand(index, Task.RecurringFrequency.WEEKLY); - } else if (parsedInput[1].toLowerCase().contains("monthly")) { - return new RecurringCommand(index, Task.RecurringFrequency.MONTHLY); - } else if (parsedInput[1].toLowerCase().contains("daily")) { - return new RecurringCommand(index, Task.RecurringFrequency.DAILY); - } else { - return new RecurringCommand(index, Task.RecurringFrequency.DAILY); - } - } - } catch (Exception e) { - throw new DukeException("Failed to make your task recurring." + e.getMessage()); - } - - case "help": - return new HelpCommand(); - case "bye": - return new ExitCommand(); - default: - throw new DukeException("Unrecognized user input!"); - } - } - -} diff --git a/src/main/java/duke/core/Storage.java b/src/main/java/duke/core/Storage.java index b8f5f4861d..cc3ce23791 100644 --- a/src/main/java/duke/core/Storage.java +++ b/src/main/java/duke/core/Storage.java @@ -37,61 +37,8 @@ public Storage(String path) { */ public ArrayList load() throws DukeException { File newDuke = new File(filePath); - ArrayList tasks = new ArrayList<>(); - try { - Scanner ss = new Scanner(newDuke); - while (ss.hasNext()) { - String[] newTask = ss.nextLine().split(" \\| "); - if (newTask[0].equals("T")) { - Task x = new Todo(newTask[2]); - if (newTask[1].equals("1")) { - x.markAsDone(); - } - if ((newTask[3] != null) && !(newTask[3].equals("ONCE"))) { - x.makeTaskRecurring(giveFrequency(newTask[3])); - } - tasks.add(x); - } - else if (newTask[0].equals("D")) { - Task t = new Deadline(newTask[2], newTask[3]); - if (newTask[1].equals("1")) { - t.markAsDone(); - } - if ((newTask[4] != null) && !(newTask[4].equals("ONCE"))) { - t.makeTaskRecurring(giveFrequency(newTask[4])); - } - tasks.add(t); - } - else if (newTask[0].equals("E")) { - Task t = new Event(newTask[2], newTask[3]); - if (newTask[1].equals("1")) { - t.markAsDone(); - } - if ((newTask[4] != null) && !(newTask[4].equals("ONCE"))) { - t.makeTaskRecurring(giveFrequency(newTask[4])); - } - tasks.add(t); - } - - else if (newTask[0].equals("P")) { - Task t = new PeriodTask(newTask[2], newTask[3], newTask[4]); - if (newTask[1].equals("1")) { - t.markAsDone(); - } - tasks.add(t); - }else if (newTask[0].equals("F")) { - Task x = new FixedDurationTask(newTask[2], newTask[3]); - if (newTask[1].equals("1")) { - x.markAsDone(); - } - tasks.add(x); - } - - } - return tasks; - } catch (FileNotFoundException e) { - throw new DukeException("File is not found!"); - } + System.out.println("Hi."); + return new ArrayList(); } /** @@ -112,17 +59,6 @@ public void save(ArrayList task) throws DukeException { } } - private Task.RecurringFrequency giveFrequency(String string) { - switch (string) { - case "DAILY": - return Task.RecurringFrequency.DAILY; - case "WEEKLY": - return Task.RecurringFrequency.WEEKLY; - case "MONTHLY": - return Task.RecurringFrequency.MONTHLY; - default: - return Task.RecurringFrequency.ONCE; - } - } + } diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index 3c0b906192..15f6c84455 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -1,6 +1,7 @@ package duke.core; import duke.task.Task; +import duke.task.TaskList; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; @@ -24,6 +25,8 @@ public Ui() { scanner = new Scanner(System.in); } + + /** * Reads user instruction. * @@ -44,10 +47,10 @@ public void showError(String e) { * @param t The Task that is added to the list. * @param size The number of tasks stored in the TaskList. */ - public void taskAdded(Task t, int size) { - System.out.println("Got it. I've added this task: \n " + t.toString() + "\nNow you have " - + size + " tasks in the list."); - } +// public void taskAdded(Task t, int size) { +// System.out.println("Got it. I've added this task: \n " + t.toString() + "\nNow you have " +// + size + " tasks in the list."); +// } /** @@ -55,9 +58,9 @@ public void taskAdded(Task t, int size) { * * @param t The Task that is marked as done. */ - public void markedAsDone(Task t) { - System.out.println("Nice! I've marked this task as done: \n " + t.printStatus()); - } +// public void markedAsDone(Task t) { +// System.out.println("Nice! I've marked this task as done: \n " + t.printStatus()); +// } /** * Shows that a Task has been removed, and displays the number @@ -65,19 +68,19 @@ public void markedAsDone(Task t) { * * @param t The Task that is deleted from the list. */ - public void taskRemoved(Task t, int size) { - System.out.println("Noted. I've removed this task: \n " + t.toString() + "\nNow you have " - + size + " tasks in the list."); - } +// public void taskRemoved(Task t, int size) { +// System.out.println("Noted. I've removed this task: \n " + t.toString() + "\nNow you have " +// + size + " tasks in the list."); +// } /** * Shows that a Task has been rescheduled to a new date and time. * * @param t The Task that is rescheduled in the list. */ - public void taskRescheduled(Task t) { - System.out.println("Noted. I've rescheduled this task: \n " + t.toString()); - } +// public void taskRescheduled(Task t) { +// System.out.println("Noted. I've rescheduled this task: \n " + t.toString()); +// } /** * Find and display a specific task stored in the list. @@ -85,16 +88,16 @@ public void taskRescheduled(Task t) { * @param a TaskList used to store tasks. * @param name name of the task to be found */ - public void taskFound(ArrayList a, String name) { - System.out.println("Here are the matching tasks in your list:"); - int count = 1; - for (Task x : a) { - if (x.getDescription().contains(name)) { - System.out.println(count + "." + x.toString()); - count++; - } - } - } +// public void taskFound(ArrayList a, String name) { +// System.out.println("Here are the matching tasks in your list:"); +// int count = 1; +// for (Task x : a) { +// if (x.getDescription().contains(name)) { +// System.out.println(count + "." + x.toString()); +// count++; +// } +// } +// } /** * Find and display a specific task stored in the list. @@ -103,16 +106,16 @@ public void taskFound(ArrayList a, String name) { * @param newTask the task to be added * @return the user's answer to whether he want to add or about the task */ - public void showClashWarning (ArrayList clashTasksInTheList, Task newTask) { - System.out.println("Here are the tasks that fall on the same day:"); - int count = 1; - for (Task t : clashTasksInTheList) { - System.out.println(count + ": " + t); - count++; - } - showLine(); - System.out.println("Do you still want to add your task anyway? Y/N"); - } +// public void showClashWarning (ArrayList clashTasksInTheList, Task newTask) { +// System.out.println("Here are the tasks that fall on the same day:"); +// int count = 1; +// for (Task t : clashTasksInTheList) { +// System.out.println(count + ": " + t); +// count++; +// } +// showLine(); +// System.out.println("Do you still want to add your task anyway? Y/N"); +// } @@ -121,44 +124,44 @@ public void showClashWarning (ArrayList clashTasksInTheList, Task newTask) * the deadline. * @param a TaskList used to store tasks. */ - public void taskReminder(ArrayList a) { - System.out.println("The following tasks are reaching your deadline:"); - System.out.println("Mark it as done or reschedule them to stop the reminder"); - int count = 1; - for (Task x : a) { - System.out.println(count + "." + x.toString()); - count++; - } - } +// public void taskReminder(ArrayList a) { +// System.out.println("The following tasks are reaching your deadline:"); +// System.out.println("Mark it as done or reschedule them to stop the reminder"); +// int count = 1; +// for (Task x : a) { +// System.out.println(count + "." + x.toString()); +// count++; +// } +// } /** * Print out the schedules on a specific date. * @param a TaskList used to store tasks. * @param date selected date of the schedule. */ - public void showSchedules (ArrayList a , String date) { - System.out.println("This is your schedules on " + date); - try { - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/M/yyyy"); - int count = 1; - for (Task task : a) { - String currentTaskDate = task.getDateTime().format(formatter); - if (currentTaskDate.equals(date)) { - System.out.println(count + ": " + task); - } - count++; - } - } catch (DateTimeParseException e) { - System.out.println("Invalid format. Please Enter Date and Time in the the format of dd/MM/yyyy"); - - } - } - - public void makeRecurring(Task t) { - System.out.println("Okay. This task has been marked as recurring:\n" - + t.toString()); - - } +// public void showSchedules (ArrayList a , String date) { +// System.out.println("This is your schedules on " + date); +// try { +// DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/M/yyyy"); +// int count = 1; +// for (Task task : a) { +// String currentTaskDate = task.getDateTime().format(formatter); +// if (currentTaskDate.equals(date)) { +// System.out.println(count + ": " + task); +// } +// count++; +// } +// } catch (DateTimeParseException e) { +// System.out.println("Invalid format. Please Enter Date and Time in the the format of dd/MM/yyyy"); +// +// } +// } + +// public void makeRecurring(Task t) { +// System.out.println("Okay. This task has been marked as recurring:\n" +// + t.toString()); +// +// } /** * Shows a divider line. @@ -172,12 +175,12 @@ public void showLine() { * * @param tasks The TaskList used to store tasks. */ - public void listTasks(TaskList tasks) throws DukeException { - System.out.println("Here are the tasks in your list:"); - for (int i = 1; i <= tasks.getSize(); i++) { - System.out.println(i + "." + tasks.getTask(i).toString()); - } - } +// public void listTasks(TaskList tasks) throws DukeException { +// System.out.println("Here are the tasks in your list:"); +// for (int i = 1; i <= tasks.getSize(); i++) { +// System.out.println(i + "." + tasks.getTask(i).toString()); +// } +// } /** * Shows bye message to user. diff --git a/src/main/java/duke/task/Deadline.java b/src/main/java/duke/task/Deadline.java deleted file mode 100644 index dc9eff5372..0000000000 --- a/src/main/java/duke/task/Deadline.java +++ /dev/null @@ -1,81 +0,0 @@ -package duke.task; - -import duke.core.DateTimeParser; -import duke.core.DukeException; - -import java.time.format.DateTimeFormatter; - -/** - * Represents a task with a deadline. It is - * extended from the Task class. - */ -public class Deadline extends Task { - /** - * A string that represents the deadline of the task. - */ - private String dateTime; - private String dateTimeEnglish; - - /** - * Constructs a Deadline object. Date and time are parsed and - * stored in dateTime field if input is of "dd/MM/yyyy HHmm" - * format. - * - * @param description A string that describes the specific - * description of task. - * @param dateTime A string that specifies the deadline of the - * task. - */ - public Deadline(String description, String dateTime) throws DukeException { - super(description); - super.updateLocalDateTime(dateTime); - this.dateTime = dateTime; - dateTimeEnglish = DateTimeParser.convertToEnglishDateTime(dateTime); - } - - /** - * Returns a string pattern to the user output - * - * @return A string which displays the type, - * description and deadline of the task. - */ - @Override - public String toString() { - - if (recurringTask != null) { - DateTimeFormatter newDateFormatter = DateTimeFormatter.ofPattern("dd/MM/YYYY HHmm"); - String newDate = recurringTask.recurringTaskTimeUpdate(this).format(newDateFormatter); - this.dateTime = newDate; - try { - this.dateTimeEnglish = DateTimeParser.convertToEnglishDateTime(dateTime); - } catch (DukeException e) { - System.out.println("I couldn't convert your given time. " + e); - } - } - return "[D]" - + super.printStatus() - + " (by: " - + dateTimeEnglish + ")"; - } - - /** - * Returns a string with the following format to be stored in a local file - * - * @return A string in a specific format to be stored in a local file. - */ - public String writeTxt() { - String frequency = "ONCE"; - if (isTaskRecurring()) { - frequency = recurringTask.getFrequency().toString(); - } - return "D | " - + (isDone() ? "1" : "0") - + " | " - + getDescription() - + " | " - + dateTime - + " | " - + frequency; - } - -} \ No newline at end of file diff --git a/src/main/java/duke/task/Event.java b/src/main/java/duke/task/Event.java deleted file mode 100644 index 32dee0c607..0000000000 --- a/src/main/java/duke/task/Event.java +++ /dev/null @@ -1,79 +0,0 @@ -package duke.task; - -import duke.core.DateTimeParser; -import duke.core.DukeException; - -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; - -/** - * Represents a task with a event. It is - * extended from the Task class. - */ -public class Event extends Task { - /** - * A string that represents the time of the event. - */ - private String dateTime; - private String dateTimeEnglish; - - /** - * Constructs a Event object. Date and time are parsed and - * stored in dateTime field if input is of "dd/MM/yyyy HHmm" - * format. - * - * @param description A string that saves the description of the task. - * @param dateTime A string that specifies the time of the event. - */ - public Event(String description, String dateTime) throws DukeException { - super(description); - super.updateLocalDateTime(dateTime); - this.dateTime = dateTime; - dateTimeEnglish = DateTimeParser.convertToEnglishDateTime(dateTime); - } - - /** - * Returns a string pattern to the user output - * - * @return A string which displays the type, - * description and deadline of the task. - */ - @Override - public String toString() { - - if (recurringTask != null) { - DateTimeFormatter newDateFormatter = DateTimeFormatter.ofPattern("dd/MM/YYYY HHmm"); - String newDate = recurringTask.recurringTaskTimeUpdate(this).format(newDateFormatter); - this.dateTime = newDate; - try { - this.dateTimeEnglish = DateTimeParser.convertToEnglishDateTime(dateTime); - } catch (DukeException e) { - System.out.println("I couldn't convert your given time. " + e); - } - } - return "[E]" - + super.printStatus() - + " (at: " - + dateTimeEnglish + ")"; - } - - /** - * Returns a string with the following format to be stored in a local file - * - * @return A string in a specific format to be stored in a local file. - */ - public String writeTxt() { - String frequency = "ONCE"; - if (isTaskRecurring()) { - frequency = recurringTask.getFrequency().toString(); - } - return "E | " - + (isDone() ? "1" : "0") - + " | " - + getDescription() - + " | " - + dateTime - + " | " - + frequency; - } -} \ No newline at end of file diff --git a/src/main/java/duke/task/FixedDurationTask.java b/src/main/java/duke/task/FixedDurationTask.java deleted file mode 100644 index 0c65baa8a9..0000000000 --- a/src/main/java/duke/task/FixedDurationTask.java +++ /dev/null @@ -1,46 +0,0 @@ -package duke.task; - -public class FixedDurationTask extends Task { - /** - * A string that represents the duration of the task - */ - private String duration; - - /** - * Constructs a Fixed duration task object. Duration is parsed and - * stored in string format - * - * @param description A string that saves the description of the task. - * @param duration A string that specifies the duration of the task. - */ - public FixedDurationTask(String description, String duration) { - super(description); - this.duration = duration; - } - - /** - * - * @return A string which displays the type, - * description and duration of the task. - */ - @Override - public String toString() { - return "[F]" + super.printStatus() + " (duration: " + this.duration + ")"; - } - - /** - * Returns a string with the following format to be stored in a local file - * - * @return A string in a specific format to be stored in a local file. - */ - public String writeTxt() { - return "F | " - + (this.isDone() ? "1" : "0") - + " | " - + this.description - + " | " - + this.duration - + " | " - + this.isRecurring; - } -} diff --git a/src/main/java/duke/task/PeriodTask.java b/src/main/java/duke/task/PeriodTask.java deleted file mode 100644 index 87f266c28f..0000000000 --- a/src/main/java/duke/task/PeriodTask.java +++ /dev/null @@ -1,59 +0,0 @@ -package duke.task; - -import duke.core.DateTimeParser; -import duke.core.DukeException; - -/** - * Represents a task to be done in a certain period of time. It is - * extended from the Task class. - */ -public class PeriodTask extends Task { - - private String startTime; - private String endTime; - private String startTimeEnglish; - private String endTimeEnglish; - - /** - * Constructs a PeriodTask object. Start time and end time are parsed and - * stored in dateTime field if input is of "dd/MM/yyyy HHmm" - * format. - * - * @param description A string that describes the specific - * description of task. - * @param startTime A string that specifies the start dateof the - * task. - * @param startTime A string that specifies the end date of the - * task. - */ - public PeriodTask(String description, String startTime, String endTime) throws DukeException { - super(description); - this.startTime = startTime; - this.endTime = endTime; - this.startTimeEnglish = DateTimeParser.convertToEnglishDateTime(startTime); - this.endTimeEnglish = DateTimeParser.convertToEnglishDateTime(endTime); - } - - /** - * Returns a string pattern to the user output - * - * @return A string which displays the type, - * description and deadline of the task. - */ - @Override - public String toString() { - return "[P]" + super.printStatus() - + " (start: " + startTimeEnglish - + " end: " + endTimeEnglish + ")"; - } - - /** - * Returns a string with the following format to be stored in a local file - * - * @return A string in a specific format to be stored in a local file. - */ - public String writeTxt() { - return "P | " + (this.isDone ? "1" : "0") + " | " + description + " | " + startTime + " | " + endTime; - } - -} \ No newline at end of file diff --git a/src/main/java/duke/task1/PersonalTask.java b/src/main/java/duke/task/PersonalTask.java similarity index 85% rename from src/main/java/duke/task1/PersonalTask.java rename to src/main/java/duke/task/PersonalTask.java index 2473126ed0..dbb9e7d020 100644 --- a/src/main/java/duke/task1/PersonalTask.java +++ b/src/main/java/duke/task/PersonalTask.java @@ -1,6 +1,4 @@ -package duke.task1; - -import java.util.ArrayList; +package duke.task; public class PersonalTask extends Task { diff --git a/src/main/java/duke/task/RecurringTask.java b/src/main/java/duke/task/RecurringTask.java deleted file mode 100644 index 0b6d2a092a..0000000000 --- a/src/main/java/duke/task/RecurringTask.java +++ /dev/null @@ -1,63 +0,0 @@ -package duke.task; - -import java.time.Duration; -import java.time.LocalDateTime; -import java.time.format.DateTimeParseException; - -public class RecurringTask { - - public enum RecurringFrequency { DAILY, WEEKLY, MONTHLY}; - public enum TaskType { TODO, DEADLINE, EVENT} - - private LocalDateTime lastRecordedTime; - private RecurringFrequency frequency; - private TaskType taskType; - - public RecurringTask(Task task, RecurringFrequency frequency) { - if (task instanceof Todo) { this.taskType = TaskType.TODO; } - if (task instanceof Deadline) { this.taskType = TaskType.DEADLINE; } - if (task instanceof Event) { this.taskType = TaskType.EVENT; } - - if (task.getDateTime() != null) { - lastRecordedTime = task.getDateTime(); - } - this.frequency = frequency; - } - - public RecurringFrequency getFrequency() { return frequency; } - - /** - * When a task is recurring, method compares current time to listed date. - * If the task's date is outdated, then it will update to be for the next day. - */ - public LocalDateTime recurringTaskTimeUpdate(Task task) { - if (lastRecordedTime != null) { - try { - LocalDateTime currentTime = LocalDateTime.now(); - if (lastRecordedTime.isBefore(currentTime)) { - - switch (this.frequency) { - case DAILY: - while (lastRecordedTime.isBefore(currentTime) || task.isDone()) { - lastRecordedTime = lastRecordedTime.plusDays(1); - if (task.isDone()) { task.isDone = false; } - } - case WEEKLY: - while (lastRecordedTime.isBefore(currentTime) || task.isDone()) { - lastRecordedTime = lastRecordedTime.plusWeeks(1); - if (task.isDone) { task.isDone = false; } - } - case MONTHLY: - while (lastRecordedTime.isBefore(currentTime) || task.isDone()) { - lastRecordedTime = lastRecordedTime.plusMonths(1); - if (task.isDone) { task.isDone = false; } - } - } - } - } catch (DateTimeParseException e) { - System.out.println("I couldn't update your recurring events' times."); - } - } - return lastRecordedTime; - } -} diff --git a/src/main/java/duke/task1/StandardTask.java b/src/main/java/duke/task/StandardTask.java similarity index 95% rename from src/main/java/duke/task1/StandardTask.java rename to src/main/java/duke/task/StandardTask.java index 4e8c3ce1c8..1b9b0d4a5c 100644 --- a/src/main/java/duke/task1/StandardTask.java +++ b/src/main/java/duke/task/StandardTask.java @@ -1,4 +1,4 @@ -package duke.task1; +package duke.task; import java.util.ArrayList; diff --git a/src/main/java/duke/task/Task.java b/src/main/java/duke/task/Task.java index 0c254b619e..cdf5dd92b4 100644 --- a/src/main/java/duke/task/Task.java +++ b/src/main/java/duke/task/Task.java @@ -1,10 +1,6 @@ package duke.task; -import duke.core.DateTimeParser; -import duke.core.DukeException; - -import java.time.LocalDate; -import java.time.LocalDateTime; +import java.util.ArrayList; /** @@ -16,40 +12,38 @@ public abstract class Task { /** * A String that represents the description of the task. */ - protected String description; + private String description; /** * A boolean that represents the status of the task( 1 means done, 0 means not yet). */ - protected boolean isDone; - - /** - * a localDateTime constructor to save the date and time. - */ - protected LocalDateTime ld = null; - - /** - * A boolean that represents whether or not a task is recurring. True = recurring, False = non-recurring - */ - protected boolean isRecurring = false; + private boolean isDone; /** - * An enumerator meant to specify the frequency of a recurring task. + * A string to describe the date/time of the task. */ - public enum RecurringFrequency { DAILY, WEEKLY, MONTHLY, ONCE; } + private String dateTime = null; /** - * An extended class that retains information about a recurring task. + * An arraylist of things the nurse can bring for the task. */ - protected RecurringTask recurringTask; + private ArrayList thingsToBring; /** * Initialises the minimum fields required to setup a Task. * * @param description A string that represents the description of certain task. */ + public Task(String description, String dateTime) { + this.description = description; + this.isDone = false; + this.thingsToBring = new ArrayList(); + this.dateTime = dateTime; + } + public Task(String description) { this.description = description; + this.thingsToBring = new ArrayList(); this.isDone = false; } @@ -71,13 +65,6 @@ public boolean isDone() { return this.isDone; } - /** - * Returns a string with the following format to be stored in a local file. - * - * @return A string in a specific format to be stored in a local file. - */ - public abstract String writeTxt(); - /** * Marks the task as done. */ @@ -86,33 +73,11 @@ public void markAsDone() { } /** - * Marks the task as recurring. - */ - public void makeTaskRecurring(RecurringFrequency frequency) { - isRecurring = true; - switch (frequency) { - case DAILY: - this.recurringTask = new RecurringTask(this, RecurringTask.RecurringFrequency.DAILY); - break; - case WEEKLY: - this.recurringTask = new RecurringTask(this, RecurringTask.RecurringFrequency.WEEKLY); - break; - case MONTHLY: - this.recurringTask = new RecurringTask(this, RecurringTask.RecurringFrequency.MONTHLY); - break; - case ONCE: - break; - //Do at in a default case here - } - if (this.recurringTask != null) { - this.recurringTask.recurringTaskTimeUpdate(this); - } - } - - /** - * Returns boolean stating whether task is recurring. + * Returns a string with the following format to be stored in a local file. + * + * @return A string in a specific format to be stored in a local file. */ - public boolean isTaskRecurring() { return isRecurring; } + public abstract String writeTxt(); /** * Returns a string with the status icon and the description of the task. @@ -134,27 +99,18 @@ public String getDescription() { } /** - * update the LocalDateTime constructor to save the date and time + * update the dateTime String to save the date and time * @param newDateTime the time retrieved from user input. */ - public void updateLocalDateTime(String newDateTime) throws DukeException { - ld = DateTimeParser.convertToLocalDateTime(newDateTime); - } + public void updateDateTime(String newDateTime) { this.dateTime = newDateTime; } /** - * Returns the data and time information stored in the task without a certain format. + * Returns the dateTime String. * - * @return A LocalDateTime Variable that contains the date and time information. */ - public LocalDateTime getDateTime() - { - if (recurringTask != null) { - this.ld = recurringTask.recurringTaskTimeUpdate(this); - } - return ld; - } + public String getDateTime() + { return dateTime; } + + public void addThingToBring(String object) { thingsToBring.add(object); } - public LocalDate getDate() { - return ld.toLocalDate(); - } } \ No newline at end of file diff --git a/src/main/java/duke/core/TaskList.java b/src/main/java/duke/task/TaskList.java similarity index 97% rename from src/main/java/duke/core/TaskList.java rename to src/main/java/duke/task/TaskList.java index af92e0158a..ed118ac9e5 100644 --- a/src/main/java/duke/core/TaskList.java +++ b/src/main/java/duke/task/TaskList.java @@ -1,7 +1,6 @@ -package duke.core; - -import duke.task.Task; +package duke.task; +import duke.core.DukeException; import java.util.ArrayList; /** diff --git a/src/main/java/duke/task/Todo.java b/src/main/java/duke/task/Todo.java deleted file mode 100644 index ace6f025f6..0000000000 --- a/src/main/java/duke/task/Todo.java +++ /dev/null @@ -1,47 +0,0 @@ -package duke.task; - -/** - * Represents a task without a specific time. This class - * extends from the Task class. - */ -public class Todo extends Task { - - /** - * Constructs a Todo object. - * - * @param description A string of the task description. - */ - public Todo(String description) { - super(description); - } - - /** - * Returns a string pattern to the user output - * - * @return A string which displays the type, - * description and deadline of the task. - */ - @Override - public String toString() { - return "[T]" + super.printStatus(); - } - - /** - * Returns a string with the following format to be stored in a local file - * - * @return A string in a specific format to be stored in a local file. - */ - public String writeTxt() { - String frequency = "ONCE"; - if (isTaskRecurring()) { - frequency = recurringTask.getFrequency().toString(); - } - return "T | " - + (this.isDone() ? "1" : "0") - + " | " - + this.description - + " | " - + frequency; - } - -} \ No newline at end of file diff --git a/src/main/java/duke/task1/Task.java b/src/main/java/duke/task1/Task.java deleted file mode 100644 index beabb0716b..0000000000 --- a/src/main/java/duke/task1/Task.java +++ /dev/null @@ -1,121 +0,0 @@ -package duke.task1; - -import duke.core.DateTimeParser; -import duke.core.DukeException; - -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.util.ArrayList; - - -/** - * Represents a task. Task is an abstract class that can not be - * instantiated - */ -public abstract class Task { - - /** - * A String that represents the description of the task. - */ - private String description; - - /** - * A boolean that represents the status of the task( 1 means done, 0 means not yet). - */ - private boolean isDone; - - /** - * A string to describe the date/time of the task. - */ - private String dateTime = null; - - /** - * An arraylist of things the nurse can bring for the task. - */ - private ArrayList thingsToBring; - - /** - * Initialises the minimum fields required to setup a Task. - * - * @param description A string that represents the description of certain task. - */ - public Task(String description, String dateTime) { - this.description = description; - this.isDone = false; - this.thingsToBring = new ArrayList(); - this.dateTime = dateTime; - } - - public Task(String description) { - this.description = description; - this.thingsToBring = new ArrayList(); - this.isDone = false; - } - - /** - * Returns an icon that represents the status of the task. - * - * @return Tick if completed, cross if uncompleted. - */ - public String getStatusIcon() { - return (isDone ? "\u2713" : "\u2718"); //return tick or X symbols - } - - /** - * Check if the task isDone. - * - * @return boolean value of isDone - */ - public boolean isDone() { - return this.isDone; - } - - /** - * Marks the task as done. - */ - public void markAsDone() { - isDone = true; - } - - /** - * Returns a string with the following format to be stored in a local file. - * - * @return A string in a specific format to be stored in a local file. - */ - public abstract String writeTxt(); - - /** - * Returns a string with the status icon and the description of the task. - * - * @return A string in a specific format with the status and description of the task. - */ - public String printStatus() { - return "[" + this.getStatusIcon() + "] " + description; - } - - /** - * Returns the description of the task. - * - * @return A string that represents the specific activity associated with - * the task. - */ - public String getDescription() { - return description; - } - - /** - * update the dateTime String to save the date and time - * @param newDateTime the time retrieved from user input. - */ - public void updateDateTime(String newDateTime) { this.dateTime = newDateTime; } - - /** - * Returns the dateTime String. - * - */ - public String getDateTime() - { return dateTime; } - - public void addThingToBring(String object) { thingsToBring.add(object); } - -} \ No newline at end of file diff --git a/src/test/java/duke/core/ParserTest.java b/src/test/java/duke/core/CommandManagerTest.java similarity index 61% rename from src/test/java/duke/core/ParserTest.java rename to src/test/java/duke/core/CommandManagerTest.java index 69b4e1ad7e..1f8d06f296 100644 --- a/src/test/java/duke/core/ParserTest.java +++ b/src/test/java/duke/core/CommandManagerTest.java @@ -5,24 +5,24 @@ import static org.junit.jupiter.api.Assertions.assertTrue; -public class ParserTest { +public class CommandManagerTest { /** * Test the return command type of Parser.parse(userInput) * @throws DukeException referencing a Duke specified exception with error log */ @Test public void commandTypeTest() throws DukeException { - Command c1 = Parser.parse("bye"); - Command c2 = Parser.parse("done 1"); - Command c3 = Parser.parse("delete 2"); - Command c4 = Parser.parse("list"); - Command c5 = Parser.parse("find MEETING"); - Command c6 = Parser.parse("todo abc"); - Command c7 = Parser.parse("event Meeting /at 27/07/2020 1630"); - Command c8 = Parser.parse("deadline event Homework ABC /by 27/07/2020 1630"); - Command c9 = Parser.parse("view 16/09/2019"); - Command c10 = Parser.parse("period periodTaskTest /from 27/07/2020 1630 /to 27/08/2020 1630"); - Command c11 = Parser.parse("reschedule 1 27/07/2020 1630"); + Command c1 = CommandManager.manageCommand("bye"); + Command c2 = CommandManager.manageCommand("done 1"); + Command c3 = CommandManager.manageCommand("delete 2"); + Command c4 = CommandManager.manageCommand("list"); + Command c5 = CommandManager.manageCommand("find MEETING"); + Command c6 = CommandManager.manageCommand("todo abc"); + Command c7 = CommandManager.manageCommand("event Meeting /at 27/07/2020 1630"); + Command c8 = CommandManager.manageCommand("deadline event Homework ABC /by 27/07/2020 1630"); + Command c9 = CommandManager.manageCommand("view 16/09/2019"); + Command c10 = CommandManager.manageCommand("period periodTaskTest /from 27/07/2020 1630 /to 27/08/2020 1630"); + Command c11 = CommandManager.manageCommand("reschedule 1 27/07/2020 1630"); assertTrue(c1 instanceof ExitCommand, "The command type should be "); assertTrue(c2 instanceof DoneCommand, "The command type should be 'DoneCommand'"); diff --git a/src/test/java/duke/task/RecurringTest.java b/src/test/java/duke/task/RecurringTest.java index a5fcc8eeec..b1258bfaea 100644 --- a/src/test/java/duke/task/RecurringTest.java +++ b/src/test/java/duke/task/RecurringTest.java @@ -1,12 +1,9 @@ package duke.task; -import duke.command.RecurringCommand; import duke.core.DukeException; -import duke.task.*; import org.junit.jupiter.api.Test; import java.time.Duration; import java.time.LocalDateTime; -import static org.junit.jupiter.api.Assertions.*; public class RecurringTest { From f3eb318b51cfd263e0af56220f3cbcbdf112373a Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Tue, 8 Oct 2019 13:54:16 +0800 Subject: [PATCH 077/420] Update Patient profile --- data/file.csv | 6 +-- src/main/java/duke/patient/Patient.java | 12 ++--- src/main/java/duke/patient/PatientList.java | 24 ++++----- .../java/duke/storage/PatientStorage.java | 52 +++++++++++++++++++ 4 files changed, 70 insertions(+), 24 deletions(-) create mode 100644 src/main/java/duke/storage/PatientStorage.java diff --git a/data/file.csv b/data/file.csv index 2153b8c33d..53ee6a12ac 100644 --- a/data/file.csv +++ b/data/file.csv @@ -1,3 +1,3 @@ -First Name,Last Name -xk,1 -xk,2 +Id,Name,Room,Remark,isHospitalised +xk,1,,, +xk,2,,, diff --git a/src/main/java/duke/patient/Patient.java b/src/main/java/duke/patient/Patient.java index 9ed82028ed..f448c6ef7e 100644 --- a/src/main/java/duke/patient/Patient.java +++ b/src/main/java/duke/patient/Patient.java @@ -1,4 +1,7 @@ package duke.patient; + +import java.util.ArrayList; + /** * Represents a Patient. */ @@ -7,6 +10,7 @@ public class Patient { private String name; private String preference; private String remark; + private ArrayList remarkList = new ArrayList(); private boolean isHospitalised; private String room; @@ -17,15 +21,13 @@ public class Patient { * @param name A String that represent the full name of the patient. * @param isHospitalised A boolean value that represents the hospitalised data of the patient. * @param remark Remark leaves by nurses. - * @param preference A string that represents the daily preference of the patient. */ - public Patient(int id, String name, boolean isHospitalised, String room, String remark, String preference) { + public Patient(int id, String name, String room, String remark, boolean isHospitalised) { this.id = id; this.name = name; this.isHospitalised = isHospitalised; this.remark = remark; this.room = room; - this.preference = preference; } public String getName() { @@ -44,10 +46,6 @@ public String getRemark(){ return remark; } - public String getPreference(){ - return preference; - } - public String getRoom(){ return room; } diff --git a/src/main/java/duke/patient/PatientList.java b/src/main/java/duke/patient/PatientList.java index e914954d2c..3fb4ae1e76 100644 --- a/src/main/java/duke/patient/PatientList.java +++ b/src/main/java/duke/patient/PatientList.java @@ -1,34 +1,30 @@ package duke.patient; - -import duke.core.DukeException; -import duke.task.Task; - import java.util.ArrayList; import java.util.HashMap; -import java.util.List; public class PatientList { -// private HashMap allPatientsMap = new HashMap(); -// private HashMap activePatientsMap = new HashMap(); - private List patients = new ArrayList(); + private HashMap patientIDMap = new HashMap(); +// private HashMap patientNameMap = new HashMap(); /** * instantiate a new TaskList with a empty list. */ - public PatientList(List patientList) { - this.patients = patientList; + public PatientList(ArrayList patientList) { + for (Patient patient : patientList) { + patientIDMap.put(patient.getID(), patient); + } } public Patient getPatient(int id){ - return patients.get(id); + return patientIDMap.get(id); } public void addPatient(Patient patient) { - patients.add(patient); + patientIDMap.put(patient.getID(), patient); } - public void updatePatientInfo(int id, Patient patient){ - patients.set(id, patient); + public void updatePatientInfo(Patient patient){ + patientIDMap.put(patient.getID(), patient); } } diff --git a/src/main/java/duke/storage/PatientStorage.java b/src/main/java/duke/storage/PatientStorage.java new file mode 100644 index 0000000000..0f9ce5b7c2 --- /dev/null +++ b/src/main/java/duke/storage/PatientStorage.java @@ -0,0 +1,52 @@ +package duke.storage; + +import duke.core.DukeException; +import duke.patient.Patient; +import org.apache.commons.csv.CSVFormat; +import org.apache.commons.csv.CSVRecord; + +import java.io.*; +import java.util.ArrayList; + +public class PatientStorage { + + /** + * A string that represents a relative file path from the project folder. + */ + private String filePath; + + /** + * Constructs a Storage object with a specific file path. + * + * @param path A string that represents the path of the file to read or + * write. + */ + public PatientStorage(String path) { + this.filePath = path; + } + + public ArrayList Load() throws DukeException { + ArrayList patientList = new ArrayList(); + try { + Reader in = new FileReader(filePath); + Iterable records = CSVFormat.EXCEL.withFirstRecordAsHeader().parse(in); + // Iterable records = CSVFormat.EXCEL.withHeader("Last Name", "First Name").withFirstRecordAsHeader().parse(in).getRecords(); + for (CSVRecord record : records) { + boolean isHospitalised = false; + int id = Integer.parseInt(record.get("Id")); + String name = record.get("Name"); + String remark = record.get("Remark"); + String room = record.get("Room"); + String hospitalised = record.get("Hospitalised"); + if (hospitalised.equals("True")) { + isHospitalised = true; + } + patientList.add(new Patient(id, name, remark, room, isHospitalised)); + System.out.println(id + " | " + name + "|" + remark + "|" + room); + } + return patientList; + } catch (IOException e) { + throw new DukeException(e.getMessage()); + } + } +} From a95947911395a7351e0264911097265e306c7e1d Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Tue, 8 Oct 2019 14:45:35 +0800 Subject: [PATCH 078/420] Update load and write methods for patients. Added in sample patients.csv to test loading. --- data/duke.txt~B-DoWithinPeriodTasks | 2 -- data/file.csv | 3 -- data/patients.csv | 4 +++ src/main/java/duke/Duke.java | 11 ++++-- src/main/java/duke/patient/PatientList.java | 4 +++ .../java/duke/storage/PatientStorage.java | 35 ++++++++++++++++--- 6 files changed, 47 insertions(+), 12 deletions(-) delete mode 100644 data/duke.txt~B-DoWithinPeriodTasks delete mode 100644 data/file.csv create mode 100644 data/patients.csv diff --git a/data/duke.txt~B-DoWithinPeriodTasks b/data/duke.txt~B-DoWithinPeriodTasks deleted file mode 100644 index c67344c37d..0000000000 --- a/data/duke.txt~B-DoWithinPeriodTasks +++ /dev/null @@ -1,2 +0,0 @@ -P | 0 | abc | 27/07/1996 1530 | 27/07/2020 1530 -P | 0 | abc | 27/07/1996 1530 | 27/07/2020 1530 diff --git a/data/file.csv b/data/file.csv deleted file mode 100644 index 53ee6a12ac..0000000000 --- a/data/file.csv +++ /dev/null @@ -1,3 +0,0 @@ -Id,Name,Room,Remark,isHospitalised -xk,1,,, -xk,2,,, diff --git a/data/patients.csv b/data/patients.csv new file mode 100644 index 0000000000..7bb639bc77 --- /dev/null +++ b/data/patients.csv @@ -0,0 +1,4 @@ +Id,Name,Room,Remark,isHospitalised +1,John,2A,apple,TRUE +2,Alpha,3C,pear,FALSE +3,Beta,3C,pear,FALSE diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index e3f11986d9..0c96b4d5de 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -5,6 +5,8 @@ import duke.core.DukeException; import duke.core.CommandManager; import duke.core.Storage; +import duke.patient.PatientList; +import duke.storage.PatientStorage; import duke.task.TaskList; import duke.core.Ui; @@ -18,11 +20,13 @@ public class Duke implements Runnable { * file and saving them to the same file. */ private Storage storage; + private PatientStorage patientStorage; /** * A TaskList object that deals with add, delete, mark as done, * find functions of a list of tasks. */ private TaskList tasks; + private PatientList patientList; /** * A Ui object that deals with interactions with the user. */ @@ -35,9 +39,12 @@ public class Duke implements Runnable { */ public Duke(String filePath) { ui = new Ui(); - storage = new Storage(filePath); + storage = new Storage(filePath + "/data.txt"); + patientStorage = new PatientStorage(filePath + "/patients.csv"); + try { tasks = new TaskList(storage.load()); + patientList = patientStorage.load(); } catch (DukeException e) { ui.showLoadingError(); tasks = new TaskList(); @@ -73,6 +80,6 @@ public void run() { * @param args The command line arguments. */ public static void main(String[] args) { - new Duke("./data/duke.txt").run(); + new Duke("./data").run(); } } diff --git a/src/main/java/duke/patient/PatientList.java b/src/main/java/duke/patient/PatientList.java index 3fb4ae1e76..5c70485747 100644 --- a/src/main/java/duke/patient/PatientList.java +++ b/src/main/java/duke/patient/PatientList.java @@ -27,4 +27,8 @@ public void addPatient(Patient patient) { public void updatePatientInfo(Patient patient){ patientIDMap.put(patient.getID(), patient); } + + public ArrayList getPatientList(){ + return new ArrayList<>(patientIDMap.values()); + } } diff --git a/src/main/java/duke/storage/PatientStorage.java b/src/main/java/duke/storage/PatientStorage.java index 0f9ce5b7c2..50a8dd9ccd 100644 --- a/src/main/java/duke/storage/PatientStorage.java +++ b/src/main/java/duke/storage/PatientStorage.java @@ -2,10 +2,14 @@ import duke.core.DukeException; import duke.patient.Patient; +import duke.patient.PatientList; import org.apache.commons.csv.CSVFormat; +import org.apache.commons.csv.CSVPrinter; import org.apache.commons.csv.CSVRecord; import java.io.*; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.ArrayList; public class PatientStorage { @@ -25,7 +29,7 @@ public PatientStorage(String path) { this.filePath = path; } - public ArrayList Load() throws DukeException { + public PatientList load() throws DukeException { ArrayList patientList = new ArrayList(); try { Reader in = new FileReader(filePath); @@ -37,16 +41,37 @@ public ArrayList Load() throws DukeException { String name = record.get("Name"); String remark = record.get("Remark"); String room = record.get("Room"); - String hospitalised = record.get("Hospitalised"); - if (hospitalised.equals("True")) { + String hospitalised = record.get("isHospitalised"); + if (hospitalised.equals("TRUE")) { isHospitalised = true; } patientList.add(new Patient(id, name, remark, room, isHospitalised)); - System.out.println(id + " | " + name + "|" + remark + "|" + room); + System.out.println(id + " | " + name + " | " + remark + " | " + room + " | " + isHospitalised); } - return patientList; + return new PatientList(patientList); } catch (IOException e) { throw new DukeException(e.getMessage()); } } + + public void save(PatientList patientList) throws DukeException { + try{ + BufferedWriter writer = Files.newBufferedWriter(Paths.get(filePath)); + CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT + .withHeader("ID", "Name", "Room", "Remark", "isHospitalised")); + ArrayList patients = patientList.getPatientList(); + for (Patient patient : patients){ + int id = patient.getID(); + String room = patient.getRoom(); + String name = patient.getName(); + boolean isHospitalised = patient.isHospitalised(); + String remark = patient.getRemark(); + csvPrinter.printRecord(id, name, room, remark, isHospitalised); + } + csvPrinter.flush(); + } + catch(IOException e){ + throw new DukeException(e.getMessage()); + } + } } From b095c04bfb2ec0c21de42e6658f08802c26a98af Mon Sep 17 00:00:00 2001 From: Qian Jie Date: Tue, 8 Oct 2019 19:59:49 +0800 Subject: [PATCH 079/420] added singleton using lazy initialisation method on Ui class --- src/main/java/duke/Duke.java | 6 +++--- src/main/java/duke/core/Ui.java | 19 ++++++++++--------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index 0c96b4d5de..a8630b1fca 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -1,6 +1,5 @@ package duke; - import duke.command.Command; import duke.core.DukeException; import duke.core.CommandManager; @@ -20,6 +19,7 @@ public class Duke implements Runnable { * file and saving them to the same file. */ private Storage storage; + private PatientStorage patientStorage; /** * A TaskList object that deals with add, delete, mark as done, @@ -30,7 +30,7 @@ public class Duke implements Runnable { /** * A Ui object that deals with interactions with the user. */ - private Ui ui; + private Ui ui = Ui.getUi(); /** * Constructs a Duke object with a relative file path. * Initialize the user interface and reads tasks from the specific text file. @@ -38,7 +38,7 @@ public class Duke implements Runnable { * used for storing tasks. */ public Duke(String filePath) { - ui = new Ui(); + //ui = Ui.getUi(); storage = new Storage(filePath + "/data.txt"); patientStorage = new PatientStorage(filePath + "/patients.csv"); diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index 15f6c84455..2066cf73e7 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -1,11 +1,5 @@ package duke.core; -import duke.task.Task; -import duke.task.TaskList; - -import java.time.format.DateTimeFormatter; -import java.time.format.DateTimeParseException; -import java.util.ArrayList; import java.util.Scanner; /** @@ -18,14 +12,21 @@ public class Ui { private Scanner scanner; /** - * Constructs a Ui object and initializes the - * Scanner to read user input from the system. + * Constructs a singleton Ui design pattern by using lazy initialization */ - public Ui() { + private Ui () { scanner = new Scanner(System.in); } + private static Ui ui; + + public static Ui getUi () { + if (ui == null) { + ui = new Ui(); + } + return ui; + } /** * Reads user instruction. From 03c204b87faacf455958f8b87ddc904c2ff7b830 Mon Sep 17 00:00:00 2001 From: Qian Jie Date: Tue, 8 Oct 2019 20:50:09 +0800 Subject: [PATCH 080/420] reduced checkstylemain error to 9 with minor error such as JavaDoc comment and indentation error for commenting left only --- src/main/java/duke/Duke.java | 5 ++- src/main/java/duke/command/ExitCommand.java | 4 +- src/main/java/duke/core/CommandManager.java | 44 +++++++++---------- src/main/java/duke/core/DateTimeParser.java | 7 +-- src/main/java/duke/core/Storage.java | 7 +-- src/main/java/duke/core/Ui.java | 12 ++--- src/main/java/duke/patient/Patient.java | 8 ++-- src/main/java/duke/patient/PatientList.java | 21 ++++----- .../java/duke/storage/PatientStorage.java | 15 ++++--- src/main/java/duke/task/PersonalTask.java | 2 +- src/main/java/duke/task/StandardTask.java | 2 +- src/main/java/duke/task/Task.java | 29 +++++++----- 12 files changed, 84 insertions(+), 72 deletions(-) diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index a8630b1fca..4aaba5c845 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -37,6 +37,7 @@ public class Duke implements Runnable { * @param filePath A string that represents the path of the local file * used for storing tasks. */ + public Duke(String filePath) { //ui = Ui.getUi(); storage = new Storage(filePath + "/data.txt"); @@ -73,12 +74,14 @@ public void run() { } System.exit(0); } + /** * Starts the Duke thread and Reminder thread concurrently * by passing a filepath to duke and a global ui object& - * task list to Reminder + * task list to Reminder. * @param args The command line arguments. */ + public static void main(String[] args) { new Duke("./data").run(); } diff --git a/src/main/java/duke/command/ExitCommand.java b/src/main/java/duke/command/ExitCommand.java index fd4a231fb9..e8008bde8e 100644 --- a/src/main/java/duke/command/ExitCommand.java +++ b/src/main/java/duke/command/ExitCommand.java @@ -18,10 +18,10 @@ public ExitCommand() { } /** - * Indicates whether Duke should exist + * Indicates whether Duke should exist. * * @return A boolean. True if the command tells Duke to exit, false - * otherwise. + * otherwise. */ @Override public boolean isExit() { diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 521b89a84e..9857f77fd5 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -1,11 +1,7 @@ package duke.core; -import duke.command.*; -import duke.task.*; - -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; +import duke.command.Command; +import duke.command.ExitCommand; /** * Represents a Parser that parses user input into a specific @@ -21,24 +17,24 @@ public class CommandManager { */ public static Command manageCommand(String userInput) throws DukeException { switch (userInput) { //change this depending on how string is parsed - case "list": - //do thing for 'list' - case "done": - //do thing for 'done' - case "delete": - //do thing for 'delete - case "find": - //do thing for 'find' - case "reschedule": - //do thing for 'reschedule' - case "view": - //do thing for 'view' - case "help": - //do thing for 'help' - case "bye": - return new ExitCommand(); - default: - throw new DukeException("Unrecognized user input!"); + case "list": + //do thing for 'list' + case "done": + //do thing for 'done' + case "delete": + //do thing for 'delete + case "find": + //do thing for 'find' + case "reschedule": + //do thing for 'reschedule' + case "view": + //do thing for 'view' + case "help": + //do thing for 'help' + case "bye": + return new ExitCommand(); + default: + throw new DukeException("Unrecognized user input!"); } } diff --git a/src/main/java/duke/core/DateTimeParser.java b/src/main/java/duke/core/DateTimeParser.java index 6eda645c92..c6c4993c0a 100644 --- a/src/main/java/duke/core/DateTimeParser.java +++ b/src/main/java/duke/core/DateTimeParser.java @@ -8,11 +8,12 @@ public class DateTimeParser { /** - * update the LocalDateTime constructor to save the date and time + * update the LocalDateTime constructor to save the date and time * * @param timeBeforeFormat the time retrieved from user input. * @return A LocalDateTime object that contains date and time information. */ + public static LocalDateTime convertToLocalDateTime(String timeBeforeFormat) throws DukeException { DateTimeFormatter parser = DateTimeFormatter.ofPattern("dd/MM/yyyy HHmm"); LocalDateTime localDateTime; @@ -37,7 +38,7 @@ public static String convertToEnglishDateTime(String timeBeforeFormat) throws Du DateTimeFormatter rdFormatter = DateTimeFormatter.ofPattern("d'rd of' MMMM yyyy, ha"); DateTimeFormatter thFormatter = DateTimeFormatter.ofPattern("d'th of' MMMM yyyy, ha"); - try{ + try { LocalDateTime localDateTime; localDateTime = convertToLocalDateTime(timeBeforeFormat); if ((localDateTime.getDayOfMonth() % 10) == 1) { @@ -49,7 +50,7 @@ public static String convertToEnglishDateTime(String timeBeforeFormat) throws Du } else { return localDateTime.format(thFormatter); } - }catch(DukeException e){ + } catch (DukeException e) { throw e; } } diff --git a/src/main/java/duke/core/Storage.java b/src/main/java/duke/core/Storage.java index 5eab2bfd90..bced950926 100644 --- a/src/main/java/duke/core/Storage.java +++ b/src/main/java/duke/core/Storage.java @@ -1,12 +1,13 @@ package duke.core; -import duke.task.*; +import duke.task.Task; import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVRecord; -import java.io.*; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; import java.util.ArrayList; -import java.util.Scanner; /** * Represents a Storage class that deals with reading tasks from diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index 2066cf73e7..c81c88fd97 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -3,7 +3,7 @@ import java.util.Scanner; /** - * Represents the necessary ui elements for user interaction + * Represents the necessary ui elements for user interaction. */ public class Ui { /** @@ -12,16 +12,16 @@ public class Ui { private Scanner scanner; /** - * Constructs a singleton Ui design pattern by using lazy initialization + * Constructs a singleton Ui design pattern by using lazy initialization. */ - private Ui () { + + private Ui() { scanner = new Scanner(System.in); } private static Ui ui; - - public static Ui getUi () { + public static Ui getUi() { if (ui == null) { ui = new Ui(); } @@ -204,7 +204,7 @@ public void showWelcome() { System.out.println("Enter 'help' to show a list of commands "); } - public void showHelpCommand () { + public void showHelpCommand() { System.out.println("Here are the things you can do with Dukepital:\n"); System.out.println("1. list - to show a list of all the tasks\n"); System.out.println("2. delete - to delete a task in the list\n"); diff --git a/src/main/java/duke/patient/Patient.java b/src/main/java/duke/patient/Patient.java index f448c6ef7e..bea834467b 100644 --- a/src/main/java/duke/patient/Patient.java +++ b/src/main/java/duke/patient/Patient.java @@ -34,19 +34,19 @@ public String getName() { return name; //return tick or X symbols } - public int getID(){ + public int getID() { return id; } - public boolean isHospitalised(){ + public boolean isHospitalised() { return isHospitalised; } - public String getRemark(){ + public String getRemark() { return remark; } - public String getRoom(){ + public String getRoom() { return room; } diff --git a/src/main/java/duke/patient/PatientList.java b/src/main/java/duke/patient/PatientList.java index 5c70485747..dc93d5cb3b 100644 --- a/src/main/java/duke/patient/PatientList.java +++ b/src/main/java/duke/patient/PatientList.java @@ -1,34 +1,35 @@ package duke.patient; + import java.util.ArrayList; import java.util.HashMap; public class PatientList { - private HashMap patientIDMap = new HashMap(); -// private HashMap patientNameMap = new HashMap(); + private HashMap patientIdMap = new HashMap(); + //private HashMap patientNameMap = new HashMap(); /** * instantiate a new TaskList with a empty list. */ public PatientList(ArrayList patientList) { for (Patient patient : patientList) { - patientIDMap.put(patient.getID(), patient); + patientIdMap.put(patient.getID(), patient); } } - public Patient getPatient(int id){ - return patientIDMap.get(id); + public Patient getPatient(int id) { + return patientIdMap.get(id); } public void addPatient(Patient patient) { - patientIDMap.put(patient.getID(), patient); + patientIdMap.put(patient.getID(), patient); } - public void updatePatientInfo(Patient patient){ - patientIDMap.put(patient.getID(), patient); + public void updatePatientInfo(Patient patient) { + patientIdMap.put(patient.getID(), patient); } - public ArrayList getPatientList(){ - return new ArrayList<>(patientIDMap.values()); + public ArrayList getPatientList() { + return new ArrayList<>(patientIdMap.values()); } } diff --git a/src/main/java/duke/storage/PatientStorage.java b/src/main/java/duke/storage/PatientStorage.java index 50a8dd9ccd..e797ac0ca0 100644 --- a/src/main/java/duke/storage/PatientStorage.java +++ b/src/main/java/duke/storage/PatientStorage.java @@ -7,7 +7,10 @@ import org.apache.commons.csv.CSVPrinter; import org.apache.commons.csv.CSVRecord; -import java.io.*; +import java.io.BufferedWriter; +import java.io.FileReader; +import java.io.IOException; +import java.io.Reader; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; @@ -25,6 +28,7 @@ public class PatientStorage { * @param path A string that represents the path of the file to read or * write. */ + public PatientStorage(String path) { this.filePath = path; } @@ -34,7 +38,7 @@ public PatientList load() throws DukeException { try { Reader in = new FileReader(filePath); Iterable records = CSVFormat.EXCEL.withFirstRecordAsHeader().parse(in); - // Iterable records = CSVFormat.EXCEL.withHeader("Last Name", "First Name").withFirstRecordAsHeader().parse(in).getRecords(); + //Iterable records = CSVFormat.EXCEL.withHeader("Last Name", "First Name").withFirstRecordAsHeader().parse(in).getRecords(); for (CSVRecord record : records) { boolean isHospitalised = false; int id = Integer.parseInt(record.get("Id")); @@ -55,12 +59,12 @@ public PatientList load() throws DukeException { } public void save(PatientList patientList) throws DukeException { - try{ + try { BufferedWriter writer = Files.newBufferedWriter(Paths.get(filePath)); CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT .withHeader("ID", "Name", "Room", "Remark", "isHospitalised")); ArrayList patients = patientList.getPatientList(); - for (Patient patient : patients){ + for (Patient patient : patients) { int id = patient.getID(); String room = patient.getRoom(); String name = patient.getName(); @@ -69,8 +73,7 @@ public void save(PatientList patientList) throws DukeException { csvPrinter.printRecord(id, name, room, remark, isHospitalised); } csvPrinter.flush(); - } - catch(IOException e){ + } catch (IOException e) { throw new DukeException(e.getMessage()); } } diff --git a/src/main/java/duke/task/PersonalTask.java b/src/main/java/duke/task/PersonalTask.java index dbb9e7d020..277fc7a4f3 100644 --- a/src/main/java/duke/task/PersonalTask.java +++ b/src/main/java/duke/task/PersonalTask.java @@ -4,7 +4,7 @@ public class PersonalTask extends Task { //private patient Patient; - public PersonalTask (String description) { //2nd parameter: Patient + public PersonalTask(String description) { //2nd parameter: Patient super(description); //this.patient = patient; } diff --git a/src/main/java/duke/task/StandardTask.java b/src/main/java/duke/task/StandardTask.java index 1b9b0d4a5c..caf2b483f6 100644 --- a/src/main/java/duke/task/StandardTask.java +++ b/src/main/java/duke/task/StandardTask.java @@ -6,7 +6,7 @@ public class StandardTask extends Task { ArrayList patientIdList; - public StandardTask (String description) { + public StandardTask(String description) { super(description); this.patientIdList = new ArrayList(); //read doc + upload task's list of patients, or make new list } diff --git a/src/main/java/duke/task/Task.java b/src/main/java/duke/task/Task.java index cdf5dd92b4..2a8accc69e 100644 --- a/src/main/java/duke/task/Task.java +++ b/src/main/java/duke/task/Task.java @@ -35,10 +35,10 @@ public abstract class Task { * @param description A string that represents the description of certain task. */ public Task(String description, String dateTime) { - this.description = description; - this.isDone = false; - this.thingsToBring = new ArrayList(); - this.dateTime = dateTime; + this.description = description; + this.isDone = false; + this.thingsToBring = new ArrayList(); + this.dateTime = dateTime; } public Task(String description) { @@ -92,25 +92,32 @@ public String printStatus() { * Returns the description of the task. * * @return A string that represents the specific activity associated with - * the task. + * the task. */ + public String getDescription() { return description; } /** - * update the dateTime String to save the date and time + * update the dateTime String to save the date and time. * @param newDateTime the time retrieved from user input. */ - public void updateDateTime(String newDateTime) { this.dateTime = newDateTime; } + + public void updateDateTime(String newDateTime) { + this.dateTime = newDateTime; + } /** * Returns the dateTime String. - * */ - public String getDateTime() - { return dateTime; } - public void addThingToBring(String object) { thingsToBring.add(object); } + public String getDateTime() { + return dateTime; + } + + public void addThingToBring(String object) { + thingsToBring.add(object); + } } \ No newline at end of file From d01a2c01e6a1ef89b859a22ac21a0ed0eb4090e9 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Tue, 8 Oct 2019 21:21:37 +0800 Subject: [PATCH 081/420] Rebuilt the Storage structure to allow various save/load methods for patient and task data --- src/main/java/duke/core/Storage.java | 63 ------------------- .../java/duke/storage/PatientStorage.java | 18 +++--- src/main/java/duke/storage/Storage.java | 17 +++++ src/main/java/duke/storage/TaskStorage.java | 51 +++++++++++++++ 4 files changed, 77 insertions(+), 72 deletions(-) delete mode 100644 src/main/java/duke/core/Storage.java create mode 100644 src/main/java/duke/storage/Storage.java create mode 100644 src/main/java/duke/storage/TaskStorage.java diff --git a/src/main/java/duke/core/Storage.java b/src/main/java/duke/core/Storage.java deleted file mode 100644 index 5eab2bfd90..0000000000 --- a/src/main/java/duke/core/Storage.java +++ /dev/null @@ -1,63 +0,0 @@ -package duke.core; - -import duke.task.*; -import org.apache.commons.csv.CSVFormat; -import org.apache.commons.csv.CSVRecord; - -import java.io.*; -import java.util.ArrayList; -import java.util.Scanner; - -/** - * Represents a Storage class that deals with reading tasks from - * a file and saving tasks in the file. - */ -public class Storage { - /** - * A string that represents a relative file path from the project folder. - */ - private String filePath; - - /** - * Constructs a Storage object with a specific file path. - * - * @param path A string that represents the path of the file to read or - * write. - */ - public Storage(String path) { - this.filePath = path; - } - - /** - * Read tasks from the file and store into a ArrayList of task. - * - * @return A ArrayList of tasks from the file. - * @throws DukeException If file is not found. - */ - public ArrayList load() throws DukeException { - File newDuke = new File(filePath); - System.out.println("Hi."); - return new ArrayList(); - } - - /** - * Saves tasks to the local file. - * - * @param task The TaskList storing tasks. - * @throws DukeException If writing to the local file failed. - */ - public void save(ArrayList task) throws DukeException { - try { - FileWriter fileWriter = new FileWriter("./data/duke.txt"); - for (Task t : task) { - fileWriter.write(t.writeTxt() + System.lineSeparator()); - } - fileWriter.close(); - } catch (IOException e) { - throw new DukeException("File writing process encounters an error " + e.getMessage()); - } - } - - - -} diff --git a/src/main/java/duke/storage/PatientStorage.java b/src/main/java/duke/storage/PatientStorage.java index 50a8dd9ccd..3f7ec70548 100644 --- a/src/main/java/duke/storage/PatientStorage.java +++ b/src/main/java/duke/storage/PatientStorage.java @@ -2,7 +2,6 @@ import duke.core.DukeException; import duke.patient.Patient; -import duke.patient.PatientList; import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVPrinter; import org.apache.commons.csv.CSVRecord; @@ -12,7 +11,7 @@ import java.nio.file.Paths; import java.util.ArrayList; -public class PatientStorage { +public class PatientStorage extends Storage{ /** * A string that represents a relative file path from the project folder. @@ -22,14 +21,14 @@ public class PatientStorage { /** * Constructs a Storage object with a specific file path. * - * @param path A string that represents the path of the file to read or + * @param filePath A string that represents the path of the file to read or * write. */ - public PatientStorage(String path) { - this.filePath = path; + public PatientStorage(String filePath) { + this.filePath = filePath; } - public PatientList load() throws DukeException { + public ArrayList load() throws DukeException { ArrayList patientList = new ArrayList(); try { Reader in = new FileReader(filePath); @@ -48,18 +47,19 @@ public PatientList load() throws DukeException { patientList.add(new Patient(id, name, remark, room, isHospitalised)); System.out.println(id + " | " + name + " | " + remark + " | " + room + " | " + isHospitalised); } - return new PatientList(patientList); + return patientList; } catch (IOException e) { throw new DukeException(e.getMessage()); } } - public void save(PatientList patientList) throws DukeException { + @Override + public void save(ArrayList patients) throws DukeException { try{ BufferedWriter writer = Files.newBufferedWriter(Paths.get(filePath)); CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT .withHeader("ID", "Name", "Room", "Remark", "isHospitalised")); - ArrayList patients = patientList.getPatientList(); +// ArrayList patients = patientList.getPatientList(); for (Patient patient : patients){ int id = patient.getID(); String room = patient.getRoom(); diff --git a/src/main/java/duke/storage/Storage.java b/src/main/java/duke/storage/Storage.java new file mode 100644 index 0000000000..c7361d01b5 --- /dev/null +++ b/src/main/java/duke/storage/Storage.java @@ -0,0 +1,17 @@ +package duke.storage; + +import duke.core.DukeException; + +import java.util.ArrayList; + +/** + * Represents a Storage class that deals with reading tasks from + * a file and saving tasks in the file. + */ +public abstract class Storage { + + public abstract ArrayList load() throws DukeException; + + public abstract void save(ArrayList list) throws DukeException; + +} diff --git a/src/main/java/duke/storage/TaskStorage.java b/src/main/java/duke/storage/TaskStorage.java new file mode 100644 index 0000000000..4b36c7471d --- /dev/null +++ b/src/main/java/duke/storage/TaskStorage.java @@ -0,0 +1,51 @@ +package duke.storage; + +import duke.core.DukeException; +import duke.task.Task; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; + +public class TaskStorage extends Storage{ + + private String filePath; + + public TaskStorage(String filePath) { + this.filePath = filePath; + } + + + /** + * Read tasks from the file and store into a ArrayList of task. + * + * @return A ArrayList of tasks from the file. + * @throws DukeException If file is not found. + */ + public ArrayList load() throws DukeException { + File newDuke = new File(filePath); + System.out.println("Hi."); + return new ArrayList(); + } + + + /** + * Saves tasks to the local file. + * + * @param tasks The TaskList storing tasks. + * @throws DukeException If writing to the local file failed. + */ + @Override + public void save(ArrayList tasks) throws DukeException { +// try { +// FileWriter fileWriter = new FileWriter("./data/duke.txt"); +// for (Task t : task) { +// fileWriter.write(t.writeTxt() + System.lineSeparator()); +// } +// fileWriter.close(); +// } catch (IOException e) { +// throw new DukeException("File writing process encounters an error " + e.getMessage()); +// } + } +} From 4dd4e0c2d31edc18b7272432462b1852fc07bee2 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Tue, 8 Oct 2019 21:22:37 +0800 Subject: [PATCH 082/420] Update AddPatientCommand --- data/patients.csv | 9 +++--- src/main/java/duke/Duke.java | 16 +++++----- .../java/duke/command/AddPatientCommand.java | 29 +++++++++++++++++++ src/main/java/duke/command/Command.java | 7 +++-- src/main/java/duke/command/ExitCommand.java | 10 ++++--- src/main/java/duke/command/HelpCommand.java | 7 +++-- src/main/java/duke/core/CommandManager.java | 18 +++++++++++- 7 files changed, 75 insertions(+), 21 deletions(-) create mode 100644 src/main/java/duke/command/AddPatientCommand.java diff --git a/data/patients.csv b/data/patients.csv index 7bb639bc77..1149a7342d 100644 --- a/data/patients.csv +++ b/data/patients.csv @@ -1,4 +1,5 @@ -Id,Name,Room,Remark,isHospitalised -1,John,2A,apple,TRUE -2,Alpha,3C,pear,FALSE -3,Beta,3C,pear,FALSE +ID,Name,Room,Remark,isHospitalised +1,John,apple,2A,true +2,Alpha,pear,3C,false +3,Beta,pear,3C,false +5,xk,apple,2A,true diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index 0c96b4d5de..a172e7197d 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -4,9 +4,9 @@ import duke.command.Command; import duke.core.DukeException; import duke.core.CommandManager; -import duke.core.Storage; import duke.patient.PatientList; import duke.storage.PatientStorage; +import duke.storage.TaskStorage; import duke.task.TaskList; import duke.core.Ui; @@ -19,13 +19,13 @@ public class Duke implements Runnable { * A Storage object that handles reading tasks from a local * file and saving them to the same file. */ - private Storage storage; + private TaskStorage taskStorage; private PatientStorage patientStorage; /** * A TaskList object that deals with add, delete, mark as done, * find functions of a list of tasks. */ - private TaskList tasks; + private TaskList taskList; private PatientList patientList; /** * A Ui object that deals with interactions with the user. @@ -39,15 +39,15 @@ public class Duke implements Runnable { */ public Duke(String filePath) { ui = new Ui(); - storage = new Storage(filePath + "/data.txt"); + taskStorage = new TaskStorage(filePath + "/data.txt"); patientStorage = new PatientStorage(filePath + "/patients.csv"); try { - tasks = new TaskList(storage.load()); - patientList = patientStorage.load(); + taskList = new TaskList(taskStorage.load()); + patientList = new PatientList(patientStorage.load()); } catch (DukeException e) { ui.showLoadingError(); - tasks = new TaskList(); + taskList = new TaskList(); } } @@ -63,7 +63,7 @@ public void run() { String fullCommand = ui.readCommand(); ui.showLine(); Command c = CommandManager.manageCommand(fullCommand); - c.execute(tasks, ui, storage); + c.execute(taskList,patientList, ui, taskStorage, patientStorage); isExit = c.isExit(); } catch (DukeException e) { ui.showError(e.getMessage()); diff --git a/src/main/java/duke/command/AddPatientCommand.java b/src/main/java/duke/command/AddPatientCommand.java new file mode 100644 index 0000000000..e0a7c98e7f --- /dev/null +++ b/src/main/java/duke/command/AddPatientCommand.java @@ -0,0 +1,29 @@ +package duke.command; + +import duke.core.DukeException; +import duke.core.Ui; +import duke.patient.Patient; +import duke.patient.PatientList; +import duke.storage.PatientStorage; +import duke.storage.TaskStorage; +import duke.task.TaskList; + +public class AddPatientCommand extends Command { + + private Patient newPatient; + public AddPatientCommand(Patient newPatient) { + super(); + this.newPatient = newPatient; + } + + @Override + public void execute(TaskList tasks, PatientList patientList, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + patientList.addPatient(newPatient); + patientStorage.save(patientList.getPatientList()); + } + + @Override + public boolean isExit() { + return false; + } +} diff --git a/src/main/java/duke/command/Command.java b/src/main/java/duke/command/Command.java index 9bfc1de7e4..868465afb4 100644 --- a/src/main/java/duke/command/Command.java +++ b/src/main/java/duke/command/Command.java @@ -1,7 +1,10 @@ package duke.command; import duke.core.DukeException; -import duke.core.Storage; +import duke.patient.PatientList; +import duke.storage.PatientStorage; +import duke.storage.Storage; +import duke.storage.TaskStorage; import duke.task.TaskList; import duke.core.Ui; @@ -21,7 +24,7 @@ public abstract class Command { * @throws DukeException throw exception during execution of the * command. */ - public abstract void execute(TaskList tasks, Ui ui, Storage storage) throws DukeException; + public abstract void execute(TaskList tasks, PatientList patientList, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException; /** * Decide whether duke should exist. diff --git a/src/main/java/duke/command/ExitCommand.java b/src/main/java/duke/command/ExitCommand.java index fd4a231fb9..92763ce66b 100644 --- a/src/main/java/duke/command/ExitCommand.java +++ b/src/main/java/duke/command/ExitCommand.java @@ -1,6 +1,9 @@ package duke.command; -import duke.core.Storage; +import duke.patient.PatientList; +import duke.storage.PatientStorage; +import duke.storage.Storage; +import duke.storage.TaskStorage; import duke.task.TaskList; import duke.core.Ui; @@ -33,10 +36,9 @@ public boolean isExit() { * * @param tasks The task list where tasks are saved. * @param ui The user interface. - * @param storage object that handles local text file update + * @param patientList object that handles local text file update */ - @Override - public void execute(TaskList tasks, Ui ui, Storage storage) { + public void execute(TaskList tasks, PatientList patientList, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) { ui.exitInformation(); } } \ No newline at end of file diff --git a/src/main/java/duke/command/HelpCommand.java b/src/main/java/duke/command/HelpCommand.java index 92f6b35da9..cdd644b78c 100644 --- a/src/main/java/duke/command/HelpCommand.java +++ b/src/main/java/duke/command/HelpCommand.java @@ -1,14 +1,17 @@ package duke.command; import duke.core.DukeException; -import duke.core.Storage; +import duke.patient.PatientList; +import duke.storage.PatientStorage; +import duke.storage.Storage; +import duke.storage.TaskStorage; import duke.task.TaskList; import duke.core.Ui; public class HelpCommand extends Command { @Override - public void execute(TaskList tasks, Ui ui, Storage storage) throws DukeException { + public void execute(TaskList tasks, PatientList patientList, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { ui.showHelpCommand(); } diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 521b89a84e..fe0aef0ba6 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -1,6 +1,7 @@ package duke.core; import duke.command.*; +import duke.patient.Patient; import duke.task.*; import java.text.DateFormat; @@ -20,7 +21,22 @@ public class CommandManager { * @return The Command received from user. */ public static Command manageCommand(String userInput) throws DukeException { - switch (userInput) { //change this depending on how string is parsed + userInput = userInput.trim(); + String[] command = userInput.split(" ", 2); + String commandType = command[0]; + switch (commandType) { //change this depending on how string is parsed + case "addPatient": + try { + String[] tempCommand = command[1].split(" ", 5); + boolean isHospitalised = false; + if (tempCommand[4].equals("T")){ + isHospitalised = true; + } + Patient patient = new Patient(Integer.parseInt(tempCommand[0]),tempCommand[1],tempCommand[2],tempCommand[3], isHospitalised); + return new AddPatientCommand(patient); + } catch (Exception e) { + throw new DukeException("Fail to parse addPatient command"); + } case "list": //do thing for 'list' case "done": From 731c9a202b995832000e94939046c53c0afdae4d Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Tue, 8 Oct 2019 21:24:44 +0800 Subject: [PATCH 083/420] Update test data --- data/patients.csv | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 data/patients.csv diff --git a/data/patients.csv b/data/patients.csv new file mode 100644 index 0000000000..1149a7342d --- /dev/null +++ b/data/patients.csv @@ -0,0 +1,5 @@ +ID,Name,Room,Remark,isHospitalised +1,John,apple,2A,true +2,Alpha,pear,3C,false +3,Beta,pear,3C,false +5,xk,apple,2A,true From d7b2d36668bb86f3a1d9ca150ed51b820d0bba1a Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Tue, 8 Oct 2019 21:33:22 +0800 Subject: [PATCH 084/420] Fix save mothod bug of wrong header for patients.csv --- data/patients.csv | 10 +++++----- src/main/java/duke/storage/PatientStorage.java | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/data/patients.csv b/data/patients.csv index 1149a7342d..c86284237a 100644 --- a/data/patients.csv +++ b/data/patients.csv @@ -1,5 +1,5 @@ -ID,Name,Room,Remark,isHospitalised -1,John,apple,2A,true -2,Alpha,pear,3C,false -3,Beta,pear,3C,false -5,xk,apple,2A,true +Id,Name,Room,Remark,isHospitalised +1,John,2A,apple,false +2,Alpha,3C,pear,false +3,newPatient3,review3,room3,false +5,xk,2A,apple,false diff --git a/src/main/java/duke/storage/PatientStorage.java b/src/main/java/duke/storage/PatientStorage.java index 3f7ec70548..522ba68473 100644 --- a/src/main/java/duke/storage/PatientStorage.java +++ b/src/main/java/duke/storage/PatientStorage.java @@ -58,7 +58,7 @@ public void save(ArrayList patients) throws DukeException { try{ BufferedWriter writer = Files.newBufferedWriter(Paths.get(filePath)); CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT - .withHeader("ID", "Name", "Room", "Remark", "isHospitalised")); + .withHeader("Id", "Name", "Room", "Remark", "isHospitalised")); // ArrayList patients = patientList.getPatientList(); for (Patient patient : patients){ int id = patient.getID(); From e7c41289e200b82c7021888fb2e4119ee31eab17 Mon Sep 17 00:00:00 2001 From: Qian Jie Date: Tue, 8 Oct 2019 23:43:07 +0800 Subject: [PATCH 085/420] removed Runnable from Duke class and added a new logo --- src/main/java/duke/Duke.java | 2 +- src/main/java/duke/core/Ui.java | 16 ++++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index 1cc2cc4bce..466c73bc71 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -13,7 +13,7 @@ * Represents Duke, a Personal Assistant to help * users tracking their progress. */ -public class Duke implements Runnable { +public class Duke { /** * A Storage object that handles reading tasks from a local * file and saving them to the same file. diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index c81c88fd97..1c9e04d9c4 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -194,12 +194,16 @@ public void exitInformation() { * Shows Duke logo and welcome message, and user input instructions. */ public void showWelcome() { - String logo = " ____ _ \n" - + "| _ \\ _ _| | _____ \n" - + "| | | | | | | |/ / _ \\\n" - + "| |_| | |_| | < __/\n" - + "|____/ \\__,_|_|\\_\\___|\n"; - System.out.println("Hello from\n" + logo); + String logo = " _____ _ _ _ _ \n" + + "| __ \\ | | (_) | | |\n" + + "| | | |_ _| | _____ _ __ _| |_ __ _| |\n" + + "| | | | | | | |/ / _ \\ '_ \\| | __/ _` | |\n" + + "| |__| | |_| | < __/ |_) | | || (_| | |\n" + + "|_____/ \\__,_|_|\\_\\___| .__/|_|\\__\\__,_|_|\n" + + " | | \n" + + " |_| \n"; + + System.out.println(logo); System.out.println("Hello! I'm Duke\nWhat can I do for you?\n\n"); System.out.println("Enter 'help' to show a list of commands "); } From 749de90dac575ae953e351ae5fc5153d1b2a50b6 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Wed, 9 Oct 2019 16:19:03 +0800 Subject: [PATCH 086/420] Update add patient command format to allow adding patient without entering an unique ID. The updated format is . --- .../java/duke/command/AddPatientCommand.java | 1 + src/main/java/duke/core/CommandManager.java | 14 ++++---- src/main/java/duke/core/Ui.java | 11 ++++++ src/main/java/duke/patient/Patient.java | 34 +++++++++++-------- src/main/java/duke/patient/PatientList.java | 9 ++++- .../java/duke/storage/PatientStorage.java | 30 +++++++--------- 6 files changed, 57 insertions(+), 42 deletions(-) diff --git a/src/main/java/duke/command/AddPatientCommand.java b/src/main/java/duke/command/AddPatientCommand.java index e0a7c98e7f..561779c7da 100644 --- a/src/main/java/duke/command/AddPatientCommand.java +++ b/src/main/java/duke/command/AddPatientCommand.java @@ -20,6 +20,7 @@ public AddPatientCommand(Patient newPatient) { public void execute(TaskList tasks, PatientList patientList, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { patientList.addPatient(newPatient); patientStorage.save(patientList.getPatientList()); + ui.patientAdded(newPatient); } @Override diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index fe0aef0ba6..6657bf8e1a 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -25,17 +25,15 @@ public static Command manageCommand(String userInput) throws DukeException { String[] command = userInput.split(" ", 2); String commandType = command[0]; switch (commandType) { //change this depending on how string is parsed - case "addPatient": + case "add": try { - String[] tempCommand = command[1].split(" ", 5); - boolean isHospitalised = false; - if (tempCommand[4].equals("T")){ - isHospitalised = true; + String[] tempCommand = command[1].split(" "); + if (tempCommand[0].toLowerCase().equals("patient")){ + Patient patient = new Patient(tempCommand[1], tempCommand[2], tempCommand[3], tempCommand[4]); + return new AddPatientCommand(patient); } - Patient patient = new Patient(Integer.parseInt(tempCommand[0]),tempCommand[1],tempCommand[2],tempCommand[3], isHospitalised); - return new AddPatientCommand(patient); } catch (Exception e) { - throw new DukeException("Fail to parse addPatient command"); + throw new DukeException("Fail to parse Add Patient command. " + e.getMessage()); } case "list": //do thing for 'list' diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index 1c9e04d9c4..0423048baa 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -1,5 +1,7 @@ package duke.core; +import duke.patient.Patient; + import java.util.Scanner; /** @@ -53,6 +55,15 @@ public void showError(String e) { // + size + " tasks in the list."); // } + public void patientAdded(Patient patient) { + System.out.println("Got it. The following patient has been added: " + + "\nId: " + patient.getID() + + "\nName: " + patient.getName() + + "\nNRIC: " + patient.getNRIC() + + "\nRoom: " + patient.getRoom() + + "\nRemark: " + patient.getRemark()); + } + /** * Shows that a Task has been marked as done. diff --git a/src/main/java/duke/patient/Patient.java b/src/main/java/duke/patient/Patient.java index bea834467b..5899672290 100644 --- a/src/main/java/duke/patient/Patient.java +++ b/src/main/java/duke/patient/Patient.java @@ -6,26 +6,29 @@ * Represents a Patient. */ public class Patient { - private int id; + private int id = 0; + private String nric; private String name; - private String preference; private String remark; private ArrayList remarkList = new ArrayList(); - private boolean isHospitalised; private String room; + public Patient(int id, String name, String nric, String room, String remark) { + this.id = id; + this.name = name; + this.nric = nric; + this.remark = remark; + this.room = room; + } /** * Initialises the minimum fields required to setup a Patient. * - * @param id A unique integer represents id of the patient. - * @param name A String that represent the full name of the patient. - * @param isHospitalised A boolean value that represents the hospitalised data of the patient. + * @param name A String that represent the full name of the patient. * @param remark Remark leaves by nurses. */ - public Patient(int id, String name, String room, String remark, boolean isHospitalised) { - this.id = id; + public Patient(String name, String nric, String room, String remark) { this.name = name; - this.isHospitalised = isHospitalised; + this.nric = nric; this.remark = remark; this.room = room; } @@ -38,10 +41,6 @@ public int getID() { return id; } - public boolean isHospitalised() { - return isHospitalised; - } - public String getRemark() { return remark; } @@ -50,7 +49,12 @@ public String getRoom() { return room; } - public void checkOut() { - isHospitalised = false; + public String getNRIC() { + return nric; + } + + public void setID(int id){ + this.id = id; } + } \ No newline at end of file diff --git a/src/main/java/duke/patient/PatientList.java b/src/main/java/duke/patient/PatientList.java index dc93d5cb3b..2d779d446e 100644 --- a/src/main/java/duke/patient/PatientList.java +++ b/src/main/java/duke/patient/PatientList.java @@ -7,7 +7,7 @@ public class PatientList { private HashMap patientIdMap = new HashMap(); //private HashMap patientNameMap = new HashMap(); - + private int maxId = 0; /** * instantiate a new TaskList with a empty list. */ @@ -15,6 +15,9 @@ public PatientList(ArrayList patientList) { for (Patient patient : patientList) { patientIdMap.put(patient.getID(), patient); } + if (!patientList.isEmpty()){ + this.maxId = patientList.get(patientList.size()-1).getID(); + } } public Patient getPatient(int id) { @@ -22,6 +25,10 @@ public Patient getPatient(int id) { } public void addPatient(Patient patient) { + if (patient.getID() == 0){ + maxId += 1; //Increment maxId by 1 for the new coming patient + patient.setID(maxId); //Set the unique id to patient + } patientIdMap.put(patient.getID(), patient); } diff --git a/src/main/java/duke/storage/PatientStorage.java b/src/main/java/duke/storage/PatientStorage.java index 522ba68473..a127d0d0de 100644 --- a/src/main/java/duke/storage/PatientStorage.java +++ b/src/main/java/duke/storage/PatientStorage.java @@ -11,7 +11,7 @@ import java.nio.file.Paths; import java.util.ArrayList; -public class PatientStorage extends Storage{ +public class PatientStorage extends Storage { /** * A string that represents a relative file path from the project folder. @@ -22,7 +22,7 @@ public class PatientStorage extends Storage{ * Constructs a Storage object with a specific file path. * * @param filePath A string that represents the path of the file to read or - * write. + * write. */ public PatientStorage(String filePath) { this.filePath = filePath; @@ -33,19 +33,15 @@ public ArrayList load() throws DukeException { try { Reader in = new FileReader(filePath); Iterable records = CSVFormat.EXCEL.withFirstRecordAsHeader().parse(in); - // Iterable records = CSVFormat.EXCEL.withHeader("Last Name", "First Name").withFirstRecordAsHeader().parse(in).getRecords(); for (CSVRecord record : records) { - boolean isHospitalised = false; int id = Integer.parseInt(record.get("Id")); String name = record.get("Name"); + String nric = record.get("NRIC"); String remark = record.get("Remark"); String room = record.get("Room"); - String hospitalised = record.get("isHospitalised"); - if (hospitalised.equals("TRUE")) { - isHospitalised = true; - } - patientList.add(new Patient(id, name, remark, room, isHospitalised)); - System.out.println(id + " | " + name + " | " + remark + " | " + room + " | " + isHospitalised); + Patient patient = new Patient(id, name, nric, remark, room); + patientList.add(new Patient(id, name, nric, remark, room)); +// System.out.println(id + " | " + name + " | " + nric + " | " + remark + " | " + room); //List out patietns info for debugging } return patientList; } catch (IOException e) { @@ -55,22 +51,20 @@ public ArrayList load() throws DukeException { @Override public void save(ArrayList patients) throws DukeException { - try{ + try { BufferedWriter writer = Files.newBufferedWriter(Paths.get(filePath)); CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT - .withHeader("Id", "Name", "Room", "Remark", "isHospitalised")); -// ArrayList patients = patientList.getPatientList(); - for (Patient patient : patients){ + .withHeader("Id", "Name", "NRIC", "Room", "Remark")); + for (Patient patient : patients) { int id = patient.getID(); String room = patient.getRoom(); + String NRIC = patient.getNRIC(); String name = patient.getName(); - boolean isHospitalised = patient.isHospitalised(); String remark = patient.getRemark(); - csvPrinter.printRecord(id, name, room, remark, isHospitalised); + csvPrinter.printRecord(id, name, NRIC, room, remark); } csvPrinter.flush(); - } - catch(IOException e){ + } catch (IOException e) { throw new DukeException(e.getMessage()); } } From 7d36d0009eaca2abad8088e5074d30132ebe4c03 Mon Sep 17 00:00:00 2001 From: kejun liu Date: Wed, 9 Oct 2019 16:24:13 +0800 Subject: [PATCH 087/420] Allow user to add standard task into standardTasks.csv --- data/data.txt | 1 + data/standardTasks.csv | 2 + src/main/java/duke/Duke.java | 2 +- .../duke/command/AddStandardTaskCommand.java | 30 ++++++++++ src/main/java/duke/core/CommandManager.java | 8 +++ src/main/java/duke/storage/TaskStorage.java | 59 ++++++++++++++----- src/main/java/duke/task/TaskList.java | 4 ++ 7 files changed, 90 insertions(+), 16 deletions(-) create mode 100644 data/data.txt create mode 100644 data/standardTasks.csv create mode 100644 src/main/java/duke/command/AddStandardTaskCommand.java diff --git a/data/data.txt b/data/data.txt new file mode 100644 index 0000000000..d3f5a12faa --- /dev/null +++ b/data/data.txt @@ -0,0 +1 @@ + diff --git a/data/standardTasks.csv b/data/standardTasks.csv new file mode 100644 index 0000000000..ba86e72b8e --- /dev/null +++ b/data/standardTasks.csv @@ -0,0 +1,2 @@ +Description +Take medicine diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index 466c73bc71..499eedc69e 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -38,7 +38,7 @@ public class Duke { */ public Duke(String filePath) { - taskStorage = new TaskStorage(filePath + "/data.txt"); + taskStorage = new TaskStorage(filePath + "/standardTasks.csv"); patientStorage = new PatientStorage(filePath + "/patients.csv"); try { diff --git a/src/main/java/duke/command/AddStandardTaskCommand.java b/src/main/java/duke/command/AddStandardTaskCommand.java new file mode 100644 index 0000000000..65b46d41a6 --- /dev/null +++ b/src/main/java/duke/command/AddStandardTaskCommand.java @@ -0,0 +1,30 @@ +package duke.command; + +import duke.core.DukeException; +import duke.core.Ui; +import duke.patient.Patient; +import duke.patient.PatientList; +import duke.storage.PatientStorage; +import duke.storage.TaskStorage; +import duke.task.Task; +import duke.task.StandardTask; +import duke.task.TaskList; + +public class AddStandardTaskCommand extends Command{ + private StandardTask newStandardTask; + public AddStandardTaskCommand(StandardTask newStandardTask) { + super(); + this.newStandardTask = newStandardTask; + } + + @Override + public void execute(TaskList taskList, PatientList patientList, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + taskList.addTask(newStandardTask); + taskStorage.save(taskList.getTaskList()); + } + + @Override + public boolean isExit() { + return false; + } +} diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index fe0aef0ba6..6efe6d3afa 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -37,6 +37,14 @@ public static Command manageCommand(String userInput) throws DukeException { } catch (Exception e) { throw new DukeException("Fail to parse addPatient command"); } + case "addStandardTask": + try { + String[] tempCommand = command[1].split(" ", 1); + StandardTask task = new StandardTask(tempCommand[0]); + return new AddStandardTaskCommand(task); + } catch (Exception e) { + throw new DukeException("Fail to parse addTask command"); + } case "list": //do thing for 'list' case "done": diff --git a/src/main/java/duke/storage/TaskStorage.java b/src/main/java/duke/storage/TaskStorage.java index 4b36c7471d..16bb33de24 100644 --- a/src/main/java/duke/storage/TaskStorage.java +++ b/src/main/java/duke/storage/TaskStorage.java @@ -1,17 +1,30 @@ package duke.storage; import duke.core.DukeException; +import duke.task.StandardTask; import duke.task.Task; +import org.apache.commons.csv.CSVFormat; +import org.apache.commons.csv.CSVPrinter; +import org.apache.commons.csv.CSVRecord; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.ArrayList; public class TaskStorage extends Storage{ + /** + * A string that represents a relative file path from the project folder. + */ private String filePath; + /** + * Constructs a Storage object with a specific file path. + * + * @param filePath A string that represents the path of the file to read or + * write. + */ public TaskStorage(String filePath) { this.filePath = filePath; } @@ -24,9 +37,20 @@ public TaskStorage(String filePath) { * @throws DukeException If file is not found. */ public ArrayList load() throws DukeException { - File newDuke = new File(filePath); - System.out.println("Hi."); - return new ArrayList(); + ArrayList taskList = new ArrayList(); + try { + Reader in = new FileReader(filePath); + Iterable records = CSVFormat.EXCEL.withFirstRecordAsHeader().parse(in); + // Iterable records = CSVFormat.EXCEL.withHeader("Last Name", "First Name").withFirstRecordAsHeader().parse(in).getRecords(); + for (CSVRecord record : records) { + String description = record.get("Description"); + taskList.add(new StandardTask(description)); + System.out.println(description + " | " + description); + } + return taskList; + } catch (IOException e) { + throw new DukeException(e.getMessage()); + } } @@ -38,14 +62,19 @@ public ArrayList load() throws DukeException { */ @Override public void save(ArrayList tasks) throws DukeException { -// try { -// FileWriter fileWriter = new FileWriter("./data/duke.txt"); -// for (Task t : task) { -// fileWriter.write(t.writeTxt() + System.lineSeparator()); -// } -// fileWriter.close(); -// } catch (IOException e) { -// throw new DukeException("File writing process encounters an error " + e.getMessage()); -// } + try{ + BufferedWriter writer = Files.newBufferedWriter(Paths.get(filePath)); + CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT + .withHeader("Description")); +// ArrayList tasks = taskList.getTaskList(); + for (Task task : tasks){ + String description = task.getDescription(); + csvPrinter.printRecord(description); + } + csvPrinter.flush(); + } + catch(IOException e){ + throw new DukeException(e.getMessage()); + } } } diff --git a/src/main/java/duke/task/TaskList.java b/src/main/java/duke/task/TaskList.java index ed118ac9e5..0c550a9d4b 100644 --- a/src/main/java/duke/task/TaskList.java +++ b/src/main/java/duke/task/TaskList.java @@ -74,4 +74,8 @@ public int getSize() { return taskList.size(); } + public ArrayList getTaskList() { + return new ArrayList<>(taskList); + } + } From 69b4c06e34afb137a9ee288ff19423f8c69f0bb5 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Wed, 9 Oct 2019 16:43:28 +0800 Subject: [PATCH 088/420] Implemented ListPatientCommand to display information of all current patients. --- .../java/duke/command/ListPatientCommand.java | 29 ++++++++++++++++++ src/main/java/duke/core/CommandManager.java | 17 +++++++++-- src/main/java/duke/core/Ui.java | 30 ++++++++++++------- 3 files changed, 63 insertions(+), 13 deletions(-) create mode 100644 src/main/java/duke/command/ListPatientCommand.java diff --git a/src/main/java/duke/command/ListPatientCommand.java b/src/main/java/duke/command/ListPatientCommand.java new file mode 100644 index 0000000000..0d4b49e67e --- /dev/null +++ b/src/main/java/duke/command/ListPatientCommand.java @@ -0,0 +1,29 @@ +package duke.command; + +import duke.core.DukeException; +import duke.core.Ui; +import duke.patient.Patient; +import duke.patient.PatientList; +import duke.storage.PatientStorage; +import duke.storage.TaskStorage; +import duke.task.TaskList; + +import java.util.ArrayList; + +public class ListPatientCommand extends Command { + + public ListPatientCommand() { + super(); + } + + @Override + public void execute(TaskList tasks, PatientList patientList, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + ArrayList list = patientList.getPatientList(); + ui.listAllPatients(list); + } + + @Override + public boolean isExit() { + return false; + } +} diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 6657bf8e1a..1872203bf3 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -23,7 +23,7 @@ public class CommandManager { public static Command manageCommand(String userInput) throws DukeException { userInput = userInput.trim(); String[] command = userInput.split(" ", 2); - String commandType = command[0]; + String commandType = command[0].toLowerCase(); switch (commandType) { //change this depending on how string is parsed case "add": try { @@ -32,11 +32,24 @@ public static Command manageCommand(String userInput) throws DukeException { Patient patient = new Patient(tempCommand[1], tempCommand[2], tempCommand[3], tempCommand[4]); return new AddPatientCommand(patient); } + else if (tempCommand[0].toLowerCase().equals("task")){ + //if the command is + } } catch (Exception e) { throw new DukeException("Fail to parse Add Patient command. " + e.getMessage()); } case "list": - //do thing for 'list' + try { + String[] tempCommand = command[1].split(" "); + if (tempCommand[0].toLowerCase().equals("patient")){ + return new ListPatientCommand(); + } + else if (tempCommand[0].toLowerCase().equals("task")){ + //if the command is + } + } catch (Exception e) { + throw new DukeException("Fail to parse Add Patient command. " + e.getMessage()); + } case "done": //do thing for 'done' case "delete": diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index 0423048baa..a7cec6737f 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -2,6 +2,7 @@ import duke.patient.Patient; +import java.util.ArrayList; import java.util.Scanner; /** @@ -43,13 +44,13 @@ public void showError(String e) { System.out.println("☹" + e); } - /** - * Shows that a Task has been added, and displays the number - * of current tasks in the list. - * - * @param t The Task that is added to the list. - * @param size The number of tasks stored in the TaskList. - */ +// /** +// * Shows that a Task has been added, and displays the number +// * of current tasks in the list. +// * +// * @param t The Task that is added to the list. +// * @param size The number of tasks stored in the TaskList. +// */ // public void taskAdded(Task t, int size) { // System.out.println("Got it. I've added this task: \n " + t.toString() + "\nNow you have " // + size + " tasks in the list."); @@ -57,13 +58,20 @@ public void showError(String e) { public void patientAdded(Patient patient) { System.out.println("Got it. The following patient has been added: " - + "\nId: " + patient.getID() - + "\nName: " + patient.getName() - + "\nNRIC: " + patient.getNRIC() - + "\nRoom: " + patient.getRoom() + + "\nName: " + patient.getName() + " Id: " + patient.getID() + + "\nNRIC: " + patient.getNRIC() + " Room: " + patient.getRoom() + "\nRemark: " + patient.getRemark()); } + public void listAllPatients(ArrayList patients){ + for (Patient patient : patients){ + System.out.println( "Name: " + patient.getName() + " Id: " + patient.getID() + + "\nNRIC: " + patient.getNRIC() + " Room: " + patient.getRoom() + + "\nRemark: " + patient.getRemark()); + showLine(); + } + } + /** * Shows that a Task has been marked as done. From 032e65d60c4f2b4e777672d648b479f62cc02c17 Mon Sep 17 00:00:00 2001 From: lmtaek Date: Wed, 9 Oct 2019 17:35:57 +0800 Subject: [PATCH 089/420] Created ListTasksCommand and implemented beginnings of list tasks behavior in Command Manager; created response in Ui for successful task list reading; changed default 'dateTime' value of Task to an empty string in order to prevent null pointer exceptions in future --- .../java/duke/command/ListTasksCommand.java | 24 +++++++++++++++++++ src/main/java/duke/core/CommandManager.java | 17 ++++--------- src/main/java/duke/core/Ui.java | 24 +++++++++++++++++++ src/main/java/duke/task/Task.java | 2 +- 4 files changed, 54 insertions(+), 13 deletions(-) create mode 100644 src/main/java/duke/command/ListTasksCommand.java diff --git a/src/main/java/duke/command/ListTasksCommand.java b/src/main/java/duke/command/ListTasksCommand.java new file mode 100644 index 0000000000..d4f6ba9dee --- /dev/null +++ b/src/main/java/duke/command/ListTasksCommand.java @@ -0,0 +1,24 @@ +package duke.command; + +import duke.core.DukeException; +import duke.core.Ui; +import duke.patient.PatientList; +import duke.storage.PatientStorage; +import duke.storage.TaskStorage; +import duke.task.Task; +import duke.task.TaskList; + +import java.util.ArrayList; + +public class ListTasksCommand extends Command { + @Override + public void execute(TaskList tasks, PatientList patientList, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + ArrayList list = tasks.getTaskList(); + ui.listAllTasks(list); + } + + @Override + public boolean isExit() { + return false; + } +} diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 3712f75cdb..3c678629c9 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -33,18 +33,11 @@ public static Command manageCommand(String userInput) throws DukeException { return new AddPatientCommand(patient); } else if (tempCommand[0].toLowerCase().equals("task")){ - //if the command is + StandardTask task = new StandardTask(tempCommand[1]); + return new AddStandardTaskCommand(task); } } catch (Exception e) { - throw new DukeException("Fail to parse Add Patient command. " + e.getMessage()); - } - case "addStandardTask": - try { - String[] tempCommand = command[1].split(" ", 1); - StandardTask task = new StandardTask(tempCommand[0]); - return new AddStandardTaskCommand(task); - } catch (Exception e) { - throw new DukeException("Fail to parse addTask command"); + throw new DukeException("Failed to parse 'add' command. " + e.getMessage()); } case "list": try { @@ -52,11 +45,11 @@ else if (tempCommand[0].toLowerCase().equals("task")){ if (tempCommand[0].toLowerCase().equals("patient")){ return new ListPatientCommand(); } - else if (tempCommand[0].toLowerCase().equals("task")){ + else if (tempCommand[0].toLowerCase().equals("tasks")){ //if the command is } } catch (Exception e) { - throw new DukeException("Fail to parse Add Patient command. " + e.getMessage()); + throw new DukeException("Fail to parse 'list' command. " + e.getMessage()); } case "done": //do thing for 'done' diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index a7cec6737f..4baca1a299 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -1,6 +1,7 @@ package duke.core; import duke.patient.Patient; +import duke.task.Task; import java.util.ArrayList; import java.util.Scanner; @@ -72,6 +73,29 @@ public void listAllPatients(ArrayList patients){ } } + public void listAllTasks(ArrayList taskList) { + int index = 0; + System.out.println("Here's a list of your tasks: \n"); + for (Task task: taskList) { + System.out.println(index + + ". " + + task.getStatusIcon() + + " " + + task.getDescription() + + formatTaskDateTime(task) + + "\n"); + index++; + } + } + + public String formatTaskDateTime(Task task) { + if (task.getDateTime().equals("")) { + return ""; + } else { + return " at " + task.getDateTime(); + } + } + /** * Shows that a Task has been marked as done. diff --git a/src/main/java/duke/task/Task.java b/src/main/java/duke/task/Task.java index 2a8accc69e..6fc2ac0e43 100644 --- a/src/main/java/duke/task/Task.java +++ b/src/main/java/duke/task/Task.java @@ -22,7 +22,7 @@ public abstract class Task { /** * A string to describe the date/time of the task. */ - private String dateTime = null; + private String dateTime = ""; /** * An arraylist of things the nurse can bring for the task. From bf7da979732514c9841b5bca7281cfa9de98b6b6 Mon Sep 17 00:00:00 2001 From: lmtaek Date: Wed, 9 Oct 2019 17:55:06 +0800 Subject: [PATCH 090/420] Mainly altering formatting/phrasing, while finalizing listTasks command functionality by altering Ui output --- src/main/java/duke/core/CommandManager.java | 6 +++--- src/main/java/duke/core/DukeException.java | 2 +- src/main/java/duke/core/Ui.java | 3 +-- src/main/java/duke/storage/TaskStorage.java | 1 - src/main/java/duke/task/TaskList.java | 14 ++++++++++---- 5 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 3c678629c9..775aab5047 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -46,10 +46,10 @@ else if (tempCommand[0].toLowerCase().equals("task")){ return new ListPatientCommand(); } else if (tempCommand[0].toLowerCase().equals("tasks")){ - //if the command is + return new ListTasksCommand(); } } catch (Exception e) { - throw new DukeException("Fail to parse 'list' command. " + e.getMessage()); + throw new DukeException("Failed to parse 'list' command. " + e.getMessage()); } case "done": //do thing for 'done' @@ -66,7 +66,7 @@ else if (tempCommand[0].toLowerCase().equals("tasks")){ case "bye": return new ExitCommand(); default: - throw new DukeException("Unrecognized user input!"); + throw new DukeException("Could not understand user input."); } } diff --git a/src/main/java/duke/core/DukeException.java b/src/main/java/duke/core/DukeException.java index 962eb5e054..5ebede15ae 100644 --- a/src/main/java/duke/core/DukeException.java +++ b/src/main/java/duke/core/DukeException.java @@ -2,6 +2,6 @@ public class DukeException extends Exception { public DukeException(String message) { - super("Oops, I wasn't able to understand that. " + message); + super("Oops! " + message); } } \ No newline at end of file diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index 4baca1a299..4601a251c7 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -79,8 +79,7 @@ public void listAllTasks(ArrayList taskList) { for (Task task: taskList) { System.out.println(index + ". " - + task.getStatusIcon() - + " " + + "[" + task.getStatusIcon() + "] " + task.getDescription() + formatTaskDateTime(task) + "\n"); diff --git a/src/main/java/duke/storage/TaskStorage.java b/src/main/java/duke/storage/TaskStorage.java index 16bb33de24..e4a6f5b68a 100644 --- a/src/main/java/duke/storage/TaskStorage.java +++ b/src/main/java/duke/storage/TaskStorage.java @@ -41,7 +41,6 @@ public ArrayList load() throws DukeException { try { Reader in = new FileReader(filePath); Iterable records = CSVFormat.EXCEL.withFirstRecordAsHeader().parse(in); - // Iterable records = CSVFormat.EXCEL.withHeader("Last Name", "First Name").withFirstRecordAsHeader().parse(in).getRecords(); for (CSVRecord record : records) { String description = record.get("Description"); taskList.add(new StandardTask(description)); diff --git a/src/main/java/duke/task/TaskList.java b/src/main/java/duke/task/TaskList.java index 0c550a9d4b..cf827a2431 100644 --- a/src/main/java/duke/task/TaskList.java +++ b/src/main/java/duke/task/TaskList.java @@ -14,18 +14,24 @@ public class TaskList { private ArrayList taskList; /** - * instantiate a new TaskList with a empty list. + * Constructor used when Duke successfully loads a TaskList from a saved file. + * Takes loaded taskList and uses it during Duke's new session. + * @param loadedTaskList */ - public TaskList(ArrayList task) { - this.taskList = task; + public TaskList(ArrayList loadedTaskList) { + this.taskList = loadedTaskList; } + /** + * Constructor used when Duke cannot successfully load a TaskList from a saved file. + * Instantiates a new TaskList with an empty list. + */ public TaskList() { taskList = new ArrayList<>(); } /** - * Retrieve the entire task list stored inside the ArrayList. + * Retrieves the entire task list stored inside the ArrayList. */ public ArrayList fullTaskList() { return taskList; From 0961e9892e53273ff0bace8d3eb0fadc868c4aee Mon Sep 17 00:00:00 2001 From: lmtaek Date: Wed, 9 Oct 2019 18:06:48 +0800 Subject: [PATCH 091/420] Updated instantiation of empty ArrayList when Duke cannot read prior saved stored task file. --- src/main/java/duke/task/TaskList.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/duke/task/TaskList.java b/src/main/java/duke/task/TaskList.java index cf827a2431..e48e6f9cab 100644 --- a/src/main/java/duke/task/TaskList.java +++ b/src/main/java/duke/task/TaskList.java @@ -27,7 +27,7 @@ public TaskList(ArrayList loadedTaskList) { * Instantiates a new TaskList with an empty list. */ public TaskList() { - taskList = new ArrayList<>(); + this.taskList = new ArrayList(); } /** From 3e8ccfe75f099acdee90ec3d54b26095b6a3e070 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Wed, 9 Oct 2019 18:33:56 +0800 Subject: [PATCH 092/420] Implemented DeletePatientCommand to delete patient by entering its unique patient id --- .../duke/command/DeletePatientCommand.java | 32 +++++++++++++++++++ src/main/java/duke/core/CommandManager.java | 22 ++++++++++++- src/main/java/duke/core/Ui.java | 9 ++++++ src/main/java/duke/patient/PatientList.java | 23 +++++++++++++ 4 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 src/main/java/duke/command/DeletePatientCommand.java diff --git a/src/main/java/duke/command/DeletePatientCommand.java b/src/main/java/duke/command/DeletePatientCommand.java new file mode 100644 index 0000000000..032aa44f85 --- /dev/null +++ b/src/main/java/duke/command/DeletePatientCommand.java @@ -0,0 +1,32 @@ +package duke.command; + +import duke.core.DukeException; +import duke.core.Ui; +import duke.patient.Patient; +import duke.patient.PatientList; +import duke.storage.PatientStorage; +import duke.storage.TaskStorage; +import duke.task.TaskList; + +import java.util.ArrayList; + +public class DeletePatientCommand extends Command { + private int id; + + public DeletePatientCommand(int id) { + this.id = id; + } + + @Override + public void execute(TaskList tasks, PatientList patientList, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + Patient patientToBeDeleted = patientList.getPatient(id); + patientList.deletePatient(id); + patientStorage.save(patientList.getPatientList()); + ui.patientDeleted(patientToBeDeleted); + } + + @Override + public boolean isExit() { + return false; + } +} diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 3712f75cdb..3e9b9a658a 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -61,8 +61,28 @@ else if (tempCommand[0].toLowerCase().equals("task")){ case "done": //do thing for 'done' case "delete": - //do thing for 'delete + try{ + String[] tempCommand = command[1].split(" ", 2); + if (tempCommand[0].toLowerCase().equals("patient")){ + return new DeletePatientCommand(Integer.parseInt(tempCommand[1])); + } + else { + throw new Exception("Delete Command with invalid format."); + } + } catch(Exception e){ + throw new DukeException(e.getMessage()); + } case "find": + try{ + String[] tempCommand = command[1].split(" ", 2); + if (tempCommand[0].toLowerCase().equals("patient")){ + String commandContent = tempCommand[1]; + int patientID = Integer.parseInt(commandContent); + return new DeletePatientCommand(patientID); + } + } catch(Exception e){ + throw new DukeException("Find Command fails." + e.getMessage()); + } //do thing for 'find' case "reschedule": //do thing for 'reschedule' diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index a7cec6737f..2fed6bc556 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -63,6 +63,13 @@ public void patientAdded(Patient patient) { + "\nRemark: " + patient.getRemark()); } + public void patientDeleted(Patient patient) { + System.out.println("Got it. The following patient is deleted: " + + "\nName: " + patient.getName() + " Id: " + patient.getID() + + "\nNRIC: " + patient.getNRIC() + " Room: " + patient.getRoom() + + "\nRemark: " + patient.getRemark()); + } + public void listAllPatients(ArrayList patients){ for (Patient patient : patients){ System.out.println( "Name: " + patient.getName() + " Id: " + patient.getID() @@ -73,6 +80,8 @@ public void listAllPatients(ArrayList patients){ } + + /** * Shows that a Task has been marked as done. * diff --git a/src/main/java/duke/patient/PatientList.java b/src/main/java/duke/patient/PatientList.java index 2d779d446e..30e8ef3daf 100644 --- a/src/main/java/duke/patient/PatientList.java +++ b/src/main/java/duke/patient/PatientList.java @@ -1,5 +1,7 @@ package duke.patient; +import duke.core.DukeException; + import java.util.ArrayList; import java.util.HashMap; @@ -24,6 +26,17 @@ public Patient getPatient(int id) { return patientIdMap.get(id); } + public ArrayList getPatientByName(String name){ + name = name.toLowerCase(); + ArrayList patientsWithThisName = new ArrayList<>(); + for (Patient patient : patientIdMap.values()) { + if(patient.getName().toLowerCase().equals(name)){ + patientsWithThisName.add(patient); + } + } + return patientsWithThisName; + } + public void addPatient(Patient patient) { if (patient.getID() == 0){ maxId += 1; //Increment maxId by 1 for the new coming patient @@ -39,4 +52,14 @@ public void updatePatientInfo(Patient patient) { public ArrayList getPatientList() { return new ArrayList<>(patientIdMap.values()); } + + public void deletePatient(int id) throws DukeException { + if (patientIdMap.containsKey(id)){ + patientIdMap.remove(id); + } + else{ + throw new DukeException("The patient with id "+ id + " does not exist."); + } + + } } From 7b2a4e1b66c752e1cfc546657c49cad9c94137a5 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Wed, 9 Oct 2019 18:58:24 +0800 Subject: [PATCH 093/420] Fixed bug caused by mutiple spaces in command --- src/main/java/duke/core/CommandManager.java | 52 ++++++++++----------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 643181114c..1a524f6770 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -4,10 +4,6 @@ import duke.patient.Patient; import duke.task.*; -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; - /** * Represents a Parser that parses user input into a specific * type of Command. @@ -22,60 +18,62 @@ public class CommandManager { */ public static Command manageCommand(String userInput) throws DukeException { userInput = userInput.trim(); - String[] command = userInput.split(" ", 2); + String[] command = userInput.split("\\s+", 2); String commandType = command[0].toLowerCase(); switch (commandType) { //change this depending on how string is parsed case "add": try { - String[] tempCommand = command[1].split(" "); + String[] tempCommand = command[1].split("\\s+"); if (tempCommand[0].toLowerCase().equals("patient")){ - Patient patient = new Patient(tempCommand[1], tempCommand[2], tempCommand[3], tempCommand[4]); - return new AddPatientCommand(patient); + try { + Patient patient = new Patient(tempCommand[1], tempCommand[2], tempCommand[3], tempCommand[4]); + return new AddPatientCommand(patient); + }catch(Exception e){ + throw new Exception("Add patient fails! Please follow the format 'add patient '."); + } } else if (tempCommand[0].toLowerCase().equals("task")){ - StandardTask task = new StandardTask(tempCommand[1]); - return new AddStandardTaskCommand(task); + try { + StandardTask task = new StandardTask(tempCommand[1]); + return new AddStandardTaskCommand(task); + } + } + else { + throw new Exception("Invalid 'add' command."); } } catch (Exception e) { - throw new DukeException("Failed to parse 'add' command. " + e.getMessage()); + throw new DukeException(e.getMessage()); } case "list": try { - String[] tempCommand = command[1].split(" "); - if (tempCommand[0].toLowerCase().equals("patient")){ - return new ListPatientCommand(); + String[] tempCommand = command[1].split("\\s+"); + if (tempCommand[0].toLowerCase().equals("patients")){ + return new ListPatientsCommand(); } else if (tempCommand[0].toLowerCase().equals("tasks")){ return new ListTasksCommand(); } + else { + throw new Exception("Invalid 'list' command."); + } } catch (Exception e) { - throw new DukeException("Failed to parse 'list' command. " + e.getMessage()); + throw new DukeException(e.getMessage()); } case "done": //do thing for 'done' case "delete": try{ - String[] tempCommand = command[1].split(" ", 2); + String[] tempCommand = command[1].split("\\s+", 2); if (tempCommand[0].toLowerCase().equals("patient")){ return new DeletePatientCommand(Integer.parseInt(tempCommand[1])); } else { - throw new Exception("Delete Command with invalid format."); + throw new Exception("Invalid 'Delete' command."); } } catch(Exception e){ throw new DukeException(e.getMessage()); } case "find": - try{ - String[] tempCommand = command[1].split(" ", 2); - if (tempCommand[0].toLowerCase().equals("patient")){ - String commandContent = tempCommand[1]; - int patientID = Integer.parseInt(commandContent); - return new DeletePatientCommand(patientID); - } - } catch(Exception e){ - throw new DukeException("Find Command fails." + e.getMessage()); - } //do thing for 'find' case "reschedule": //do thing for 'reschedule' From f57e601415e9682371b58d90ea0f8e1a624fc756 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Wed, 9 Oct 2019 18:59:04 +0800 Subject: [PATCH 094/420] Updated DeletePatientCommand with appropriate exception warning message to remind user. --- data/patients.csv | 14 +++++---- data/standardTasks.csv | 2 ++ ...tCommand.java => ListPatientsCommand.java} | 4 +-- src/main/java/duke/core/Ui.java | 29 +++++++++---------- 4 files changed, 25 insertions(+), 24 deletions(-) rename src/main/java/duke/command/{ListPatientCommand.java => ListPatientsCommand.java} (88%) diff --git a/data/patients.csv b/data/patients.csv index cb7fdc4fd4..155e456551 100644 --- a/data/patients.csv +++ b/data/patients.csv @@ -1,6 +1,8 @@ -Id,Name,Room,Remark,isHospitalised -1,John,apple,2A,false -2,Alpha,pear,3C,false -3,newPatient3,room3,review3,false -5,xk,apple,2A,false -6,new,apple,bad,false +Id,Name,NRIC,Room,Remark +3,weifeng,G123456,2A,abc +4,xk,sfaf,f, +5,xk,sfaf,, +6,xk,sfaf,, +7,xk,,, +8,weifentg,123122,no,no +9,weifentg,123122,no,no diff --git a/data/standardTasks.csv b/data/standardTasks.csv index ba86e72b8e..aedc67fa48 100644 --- a/data/standardTasks.csv +++ b/data/standardTasks.csv @@ -1,2 +1,4 @@ Description Take medicine +abc +123 diff --git a/src/main/java/duke/command/ListPatientCommand.java b/src/main/java/duke/command/ListPatientsCommand.java similarity index 88% rename from src/main/java/duke/command/ListPatientCommand.java rename to src/main/java/duke/command/ListPatientsCommand.java index 0d4b49e67e..a090f409c9 100644 --- a/src/main/java/duke/command/ListPatientCommand.java +++ b/src/main/java/duke/command/ListPatientsCommand.java @@ -10,9 +10,9 @@ import java.util.ArrayList; -public class ListPatientCommand extends Command { +public class ListPatientsCommand extends Command { - public ListPatientCommand() { + public ListPatientsCommand() { super(); } diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index 3d8be6029f..179350ac07 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -57,25 +57,25 @@ public void showError(String e) { // + size + " tasks in the list."); // } - public void patientAdded(Patient patient) { - System.out.println("Got it. The following patient has been added: " - + "\nName: " + patient.getName() + " Id: " + patient.getID() + public void showPatientInfo(Patient patient) { + System.out.println("Name: " + patient.getName() + " Id: " + patient.getID() + "\nNRIC: " + patient.getNRIC() + " Room: " + patient.getRoom() + "\nRemark: " + patient.getRemark()); } + public void patientAdded(Patient patient) { + System.out.println("Got it. The following patient has been added: "); + showPatientInfo(patient); + } + public void patientDeleted(Patient patient) { - System.out.println("Got it. The following patient is deleted: " - + "\nName: " + patient.getName() + " Id: " + patient.getID() - + "\nNRIC: " + patient.getNRIC() + " Room: " + patient.getRoom() - + "\nRemark: " + patient.getRemark()); + System.out.println("Got it. The following patient is deleted: "); + showPatientInfo(patient); } - public void listAllPatients(ArrayList patients){ - for (Patient patient : patients){ - System.out.println( "Name: " + patient.getName() + " Id: " + patient.getID() - + "\nNRIC: " + patient.getNRIC() + " Room: " + patient.getRoom() - + "\nRemark: " + patient.getRemark()); + public void listAllPatients(ArrayList patients) { + for (Patient patient : patients) { + showPatientInfo(patient); showLine(); } } @@ -83,7 +83,7 @@ public void listAllPatients(ArrayList patients){ public void listAllTasks(ArrayList taskList) { int index = 0; System.out.println("Here's a list of your tasks: \n"); - for (Task task: taskList) { + for (Task task : taskList) { System.out.println(index + ". " + "[" + task.getStatusIcon() + "] " @@ -103,8 +103,6 @@ public String formatTaskDateTime(Task task) { } - - /** * Shows that a Task has been marked as done. * @@ -170,7 +168,6 @@ public String formatTaskDateTime(Task task) { // } - /** * Print out the tasks in the task list which is reaching * the deadline. From e8a98bff085ba3c858ba2bc113d31ec5fdbe8666 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Wed, 9 Oct 2019 19:08:34 +0800 Subject: [PATCH 095/420] Fixed bug with missing catch in CommandManger --- src/main/java/duke/core/CommandManager.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 1a524f6770..58976d01d0 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -36,6 +36,8 @@ else if (tempCommand[0].toLowerCase().equals("task")){ try { StandardTask task = new StandardTask(tempCommand[1]); return new AddStandardTaskCommand(task); + }catch(Exception e){ + throw new Exception("Add task fails! Please follow the format 'add task ."); } } else { From 11da5a5f98d5f1dd99e230972eca5f7b4b98a699 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Wed, 9 Oct 2019 19:48:38 +0800 Subject: [PATCH 096/420] Update exception messages when invalid format is being entered. --- src/main/java/duke/core/CommandManager.java | 24 ++++++++++++--------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 58976d01d0..8e76b98fff 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -29,7 +29,7 @@ public static Command manageCommand(String userInput) throws DukeException { Patient patient = new Patient(tempCommand[1], tempCommand[2], tempCommand[3], tempCommand[4]); return new AddPatientCommand(patient); }catch(Exception e){ - throw new Exception("Add patient fails! Please follow the format 'add patient '."); + throw new Exception("Please follow the format 'add patient '. "); } } else if (tempCommand[0].toLowerCase().equals("task")){ @@ -37,18 +37,17 @@ else if (tempCommand[0].toLowerCase().equals("task")){ StandardTask task = new StandardTask(tempCommand[1]); return new AddStandardTaskCommand(task); }catch(Exception e){ - throw new Exception("Add task fails! Please follow the format 'add task ."); + throw new Exception("Please follow the format 'add task .' "); } } else { - throw new Exception("Invalid 'add' command."); + throw new Exception("Invalid format. "); } } catch (Exception e) { - throw new DukeException(e.getMessage()); + throw new DukeException("Add command fails. " + e.getMessage()); } case "list": try { - String[] tempCommand = command[1].split("\\s+"); if (tempCommand[0].toLowerCase().equals("patients")){ return new ListPatientsCommand(); } @@ -56,10 +55,10 @@ else if (tempCommand[0].toLowerCase().equals("tasks")){ return new ListTasksCommand(); } else { - throw new Exception("Invalid 'list' command."); + throw new Exception("Invalid 'list' command. "); } } catch (Exception e) { - throw new DukeException(e.getMessage()); + throw new DukeException("List command fails. " + e.getMessage()); } case "done": //do thing for 'done' @@ -67,13 +66,18 @@ else if (tempCommand[0].toLowerCase().equals("tasks")){ try{ String[] tempCommand = command[1].split("\\s+", 2); if (tempCommand[0].toLowerCase().equals("patient")){ - return new DeletePatientCommand(Integer.parseInt(tempCommand[1])); + try { + int id = Integer.parseInt(tempCommand[1]); + return new DeletePatientCommand(id); + }catch(Exception e){ + throw new Exception("Please follow the format 'delete patient '."); + } } else { - throw new Exception("Invalid 'Delete' command."); + throw new Exception("Invalid format. "); } } catch(Exception e){ - throw new DukeException(e.getMessage()); + throw new DukeException("Delete command fails. " + e.getMessage()); } case "find": //do thing for 'find' From 5d2dfac059b2472f6ed90f37963502a219374185 Mon Sep 17 00:00:00 2001 From: Qian Jie Date: Wed, 9 Oct 2019 20:35:23 +0800 Subject: [PATCH 097/420] Fixed minor bug on case "list" where tempCommand was not declared --- src/main/java/duke/core/CommandManager.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 8e76b98fff..12ed23f505 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -48,6 +48,7 @@ else if (tempCommand[0].toLowerCase().equals("task")){ } case "list": try { + String[] tempCommand = command[1].split("\\s+"); if (tempCommand[0].toLowerCase().equals("patients")){ return new ListPatientsCommand(); } From 939e4ab61ef01504d86d33b7635eddfda5843753 Mon Sep 17 00:00:00 2001 From: Qian Jie Date: Wed, 9 Oct 2019 20:58:45 +0800 Subject: [PATCH 098/420] Fixed minor bug on wrong output --> input : eat medicine. output: eat --- src/main/java/duke/core/CommandManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 12ed23f505..48dd6ae1b6 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -34,7 +34,7 @@ public static Command manageCommand(String userInput) throws DukeException { } else if (tempCommand[0].toLowerCase().equals("task")){ try { - StandardTask task = new StandardTask(tempCommand[1]); + StandardTask task = new StandardTask(command[1].split("\\s" , 2)[1]); return new AddStandardTaskCommand(task); }catch(Exception e){ throw new Exception("Please follow the format 'add task .' "); From 0cb8c98125e57442da0de00d2bd2ac156c852c01 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Wed, 9 Oct 2019 22:05:20 +0800 Subject: [PATCH 099/420] Implemented FindPatientCommand feature for user to find patient's info by id or name. --- data/patients.csv | 13 +++---- data/standardTasks.csv | 2 + .../java/duke/command/FindPatientCommand.java | 38 +++++++++++++++++++ src/main/java/duke/core/CommandManager.java | 22 +++++++++-- src/main/java/duke/core/Ui.java | 22 +++++++++++ src/main/java/duke/patient/PatientList.java | 9 ++++- 6 files changed, 94 insertions(+), 12 deletions(-) create mode 100644 src/main/java/duke/command/FindPatientCommand.java diff --git a/data/patients.csv b/data/patients.csv index 155e456551..9d13d2bf0c 100644 --- a/data/patients.csv +++ b/data/patients.csv @@ -1,8 +1,7 @@ Id,Name,NRIC,Room,Remark -3,weifeng,G123456,2A,abc -4,xk,sfaf,f, -5,xk,sfaf,, -6,xk,sfaf,, -7,xk,,, -8,weifentg,123122,no,no -9,weifentg,123122,no,no +1,xk,G03123456,2A,no +2,weifeng,G789456,9A,no +3,qijie,G123456,2c,no +9,weifeng,G12356,3B,male +10,kejun,abcd,no mood no modd,8A +11,Lauren,A123123,5A,test remark with mutiple words diff --git a/data/standardTasks.csv b/data/standardTasks.csv index aedc67fa48..52f3ec389c 100644 --- a/data/standardTasks.csv +++ b/data/standardTasks.csv @@ -2,3 +2,5 @@ Description Take medicine abc 123 +eat medicine lalala +test task name with multiple words diff --git a/src/main/java/duke/command/FindPatientCommand.java b/src/main/java/duke/command/FindPatientCommand.java new file mode 100644 index 0000000000..4dff64bf02 --- /dev/null +++ b/src/main/java/duke/command/FindPatientCommand.java @@ -0,0 +1,38 @@ +package duke.command; + +import duke.core.DukeException; +import duke.core.Ui; +import duke.patient.Patient; +import duke.patient.PatientList; +import duke.storage.PatientStorage; +import duke.storage.TaskStorage; +import duke.task.TaskList; + +import java.util.ArrayList; + +public class FindPatientCommand extends Command { + + private String command; + public FindPatientCommand(String command){ + this.command = command; + } + + @Override + public void execute(TaskList tasks, PatientList patientList, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + char firstChar = command.charAt(0); + if (firstChar == '#'){ + int id = Integer.parseInt(command.substring(1, command.length())); + Patient patient = patientList.getPatient(id); + ui.patientsFoundById(patient); + } + else{ + ArrayList patientsWithSameName = patientList.getPatientByName(command); + ui.patientsFoundByName(patientsWithSameName, command); + } + } + + @Override + public boolean isExit() { + return false; + } +} diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 12ed23f505..c6f48e3c19 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -26,7 +26,8 @@ public static Command manageCommand(String userInput) throws DukeException { String[] tempCommand = command[1].split("\\s+"); if (tempCommand[0].toLowerCase().equals("patient")){ try { - Patient patient = new Patient(tempCommand[1], tempCommand[2], tempCommand[3], tempCommand[4]); + String[] commandContent = command[1].split("\\s+", 2)[1].split("\\s+", 4); + Patient patient = new Patient(commandContent[0], commandContent[1], commandContent[2], commandContent[3]); return new AddPatientCommand(patient); }catch(Exception e){ throw new Exception("Please follow the format 'add patient '. "); @@ -34,7 +35,8 @@ public static Command manageCommand(String userInput) throws DukeException { } else if (tempCommand[0].toLowerCase().equals("task")){ try { - StandardTask task = new StandardTask(tempCommand[1]); +// StandardTask task = new StandardTask(tempCommand[1]); + StandardTask task = new StandardTask(command[1].split("\\s", 2)[1]); return new AddStandardTaskCommand(task); }catch(Exception e){ throw new Exception("Please follow the format 'add task .' "); @@ -81,7 +83,21 @@ else if (tempCommand[0].toLowerCase().equals("tasks")){ throw new DukeException("Delete command fails. " + e.getMessage()); } case "find": - //do thing for 'find' + try{ + String[] tempCommand = command[1].split("\\s+", 2); + if (tempCommand[0].toLowerCase().equals("patient")){ + try { + return new FindPatientCommand(tempCommand[1]); + }catch(Exception e){ + throw new Exception("Please follow the format 'find patient #' or 'find patient '."); + } + } + else { + throw new Exception("Invalid format. "); + } + } catch(Exception e){ + throw new DukeException("Find command fails. " + e.getMessage()); + } case "reschedule": //do thing for 'reschedule' case "view": diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index 179350ac07..ac920d003b 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -63,6 +63,28 @@ public void showPatientInfo(Patient patient) { + "\nRemark: " + patient.getRemark()); } + public void patientsFoundByName(ArrayList patients, String name) { + if (patients.size() > 0){ + System.out.println("Got it. "+ patients.size() +" patients is/are found with name: "+ name); + int i = 1; + for (Patient patient : patients) { + System.out.println("Patient #"+ i); + showPatientInfo(patient); + showLine(); + i++; + } + } + else{ + System.out.println("No patient was found with name: " + name); + } + } + + public void patientsFoundById(Patient patient) { + System.out.println("Got it. The patient is found."); + showPatientInfo(patient); + } + + public void patientAdded(Patient patient) { System.out.println("Got it. The following patient has been added: "); showPatientInfo(patient); diff --git a/src/main/java/duke/patient/PatientList.java b/src/main/java/duke/patient/PatientList.java index 30e8ef3daf..5ff78a2f78 100644 --- a/src/main/java/duke/patient/PatientList.java +++ b/src/main/java/duke/patient/PatientList.java @@ -22,8 +22,13 @@ public PatientList(ArrayList patientList) { } } - public Patient getPatient(int id) { - return patientIdMap.get(id); + public Patient getPatient(int id) throws DukeException { + if (patientIdMap.containsKey(id)){ + return patientIdMap.get(id); + } + else{ + throw new DukeException("The patient with id "+ id + " does not exist."); + } } public ArrayList getPatientByName(String name){ From b3faf734c1849005326518598580f37d826f0002 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Wed, 9 Oct 2019 22:28:43 +0800 Subject: [PATCH 100/420] Fixed bug of wrong positioning of headers "Room" and "Remark" --- src/main/java/duke/storage/PatientStorage.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/duke/storage/PatientStorage.java b/src/main/java/duke/storage/PatientStorage.java index a127d0d0de..84b63ed35c 100644 --- a/src/main/java/duke/storage/PatientStorage.java +++ b/src/main/java/duke/storage/PatientStorage.java @@ -39,8 +39,7 @@ public ArrayList load() throws DukeException { String nric = record.get("NRIC"); String remark = record.get("Remark"); String room = record.get("Room"); - Patient patient = new Patient(id, name, nric, remark, room); - patientList.add(new Patient(id, name, nric, remark, room)); + patientList.add(new Patient(id, name, nric, room, remark)); // System.out.println(id + " | " + name + " | " + nric + " | " + remark + " | " + room); //List out patietns info for debugging } return patientList; From 1077ce3cacb30da3afeed9dc39f8ebd610e5e073 Mon Sep 17 00:00:00 2001 From: Qian Jie Date: Wed, 9 Oct 2019 23:01:58 +0800 Subject: [PATCH 101/420] Added output to console when a task is added --- data/patients.csv | 14 ++++++------- data/standardTasks.csv | 4 ++++ .../duke/command/AddStandardTaskCommand.java | 1 + .../duke/command/DeletePatientCommand.java | 2 -- src/main/java/duke/core/Ui.java | 20 +++++++++---------- src/main/java/duke/task/PersonalTask.java | 3 ++- src/main/java/duke/task/StandardTask.java | 6 ++++-- src/main/java/duke/task/Task.java | 16 +++++++-------- 8 files changed, 34 insertions(+), 32 deletions(-) diff --git a/data/patients.csv b/data/patients.csv index 9d13d2bf0c..eb6282485d 100644 --- a/data/patients.csv +++ b/data/patients.csv @@ -1,7 +1,7 @@ -Id,Name,NRIC,Room,Remark -1,xk,G03123456,2A,no -2,weifeng,G789456,9A,no -3,qijie,G123456,2c,no -9,weifeng,G12356,3B,male -10,kejun,abcd,no mood no modd,8A -11,Lauren,A123123,5A,test remark with mutiple words +Id,Name,NRIC,Room,Remark +1,xk,G03123456,2A,no +2,weifeng,G789456,9A,no +3,qijie,G123456,2c,no +9,weifeng,G12356,3B,male +10,kejun,abcd,no mood no modd,8A +11,qianjie,1231312321,A5,NIL diff --git a/data/standardTasks.csv b/data/standardTasks.csv index 52f3ec389c..11fe78b8d0 100644 --- a/data/standardTasks.csv +++ b/data/standardTasks.csv @@ -4,3 +4,7 @@ abc 123 eat medicine lalala test task name with multiple words +hello world +hello hell +jojojo jojoj +hello world diff --git a/src/main/java/duke/command/AddStandardTaskCommand.java b/src/main/java/duke/command/AddStandardTaskCommand.java index 65b46d41a6..ba7d72af8d 100644 --- a/src/main/java/duke/command/AddStandardTaskCommand.java +++ b/src/main/java/duke/command/AddStandardTaskCommand.java @@ -21,6 +21,7 @@ public AddStandardTaskCommand(StandardTask newStandardTask) { public void execute(TaskList taskList, PatientList patientList, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { taskList.addTask(newStandardTask); taskStorage.save(taskList.getTaskList()); + ui.taskAdded(newStandardTask); } @Override diff --git a/src/main/java/duke/command/DeletePatientCommand.java b/src/main/java/duke/command/DeletePatientCommand.java index 032aa44f85..e55d17a074 100644 --- a/src/main/java/duke/command/DeletePatientCommand.java +++ b/src/main/java/duke/command/DeletePatientCommand.java @@ -8,8 +8,6 @@ import duke.storage.TaskStorage; import duke.task.TaskList; -import java.util.ArrayList; - public class DeletePatientCommand extends Command { private int id; diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index ac920d003b..856044e97f 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -1,6 +1,7 @@ package duke.core; import duke.patient.Patient; +import duke.task.StandardTask; import duke.task.Task; import java.util.ArrayList; @@ -45,17 +46,14 @@ public void showError(String e) { System.out.println("☹" + e); } -// /** -// * Shows that a Task has been added, and displays the number -// * of current tasks in the list. -// * -// * @param t The Task that is added to the list. -// * @param size The number of tasks stored in the TaskList. -// */ -// public void taskAdded(Task t, int size) { -// System.out.println("Got it. I've added this task: \n " + t.toString() + "\nNow you have " -// + size + " tasks in the list."); -// } + /** + * Shows that a Task has been added + * + * @param t The Task that is added to the list. + */ + public void taskAdded(StandardTask standardTask) { + System.out.println("Got it. I've added this task: \n" + standardTask); + } public void showPatientInfo(Patient patient) { System.out.println("Name: " + patient.getName() + " Id: " + patient.getID() diff --git a/src/main/java/duke/task/PersonalTask.java b/src/main/java/duke/task/PersonalTask.java index 277fc7a4f3..fdb56d6072 100644 --- a/src/main/java/duke/task/PersonalTask.java +++ b/src/main/java/duke/task/PersonalTask.java @@ -10,7 +10,8 @@ public PersonalTask(String description) { //2nd parameter: Patient } @Override - public String writeTxt() { + public String toString() { return null; } + } \ No newline at end of file diff --git a/src/main/java/duke/task/StandardTask.java b/src/main/java/duke/task/StandardTask.java index caf2b483f6..e2ae585308 100644 --- a/src/main/java/duke/task/StandardTask.java +++ b/src/main/java/duke/task/StandardTask.java @@ -12,7 +12,9 @@ public StandardTask(String description) { } @Override - public String writeTxt() { - return null; + public String toString() { + return this.getDescription(); } + + } diff --git a/src/main/java/duke/task/Task.java b/src/main/java/duke/task/Task.java index 6fc2ac0e43..7aa2415ce2 100644 --- a/src/main/java/duke/task/Task.java +++ b/src/main/java/duke/task/Task.java @@ -72,12 +72,12 @@ public void markAsDone() { isDone = true; } - /** - * Returns a string with the following format to be stored in a local file. - * - * @return A string in a specific format to be stored in a local file. - */ - public abstract String writeTxt(); +// /** +// * Returns a string with the following format to be stored in a local file. +// * +// * @return A string in a specific format to be stored in a local file. +// */ +// public abstract String writeTxt(); /** * Returns a string with the status icon and the description of the task. @@ -116,8 +116,6 @@ public String getDateTime() { return dateTime; } - public void addThingToBring(String object) { - thingsToBring.add(object); - } + public abstract String toString(); } \ No newline at end of file From f4bb57155b03bf0fffe7b43e17f853e8af25dbc6 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Thu, 10 Oct 2019 02:25:17 +0800 Subject: [PATCH 102/420] Added Delete Patient Command by both name and id. Added Confirmation before deleting a patient. --- .../duke/command/DeletePatientCommand.java | 42 ++++++++++++--- .../java/duke/command/FindPatientCommand.java | 7 ++- src/main/java/duke/core/CommandManager.java | 5 +- src/main/java/duke/core/Ui.java | 53 ++++++++++++++++--- 4 files changed, 89 insertions(+), 18 deletions(-) diff --git a/src/main/java/duke/command/DeletePatientCommand.java b/src/main/java/duke/command/DeletePatientCommand.java index e55d17a074..2b17c262c0 100644 --- a/src/main/java/duke/command/DeletePatientCommand.java +++ b/src/main/java/duke/command/DeletePatientCommand.java @@ -8,19 +8,49 @@ import duke.storage.TaskStorage; import duke.task.TaskList; +import java.util.ArrayList; + public class DeletePatientCommand extends Command { private int id; + private String command; - public DeletePatientCommand(int id) { - this.id = id; + public DeletePatientCommand(String command) { + this.command = command; } @Override public void execute(TaskList tasks, PatientList patientList, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { - Patient patientToBeDeleted = patientList.getPatient(id); - patientList.deletePatient(id); - patientStorage.save(patientList.getPatientList()); - ui.patientDeleted(patientToBeDeleted); + char firstChar = command.charAt(0); + if (firstChar == '#') { + int id; + try{ + id = Integer.parseInt(command.substring(1, command.length())); + }catch(Exception e){ + throw new DukeException("Please follow the format 'delete patient #'."); + } + + Patient patientToBeDeleted = patientList.getPatient(id); + boolean toDelete = ui.confirmPatientToBeDeleted(patientToBeDeleted); + if (toDelete){ + patientList.deletePatient(id); + ui.patientDeleted(); + patientStorage.save(patientList.getPatientList()); + } + } else { + ArrayList patientsWithSameName = patientList.getPatientByName(command); + ui.patientsFoundByName(patientsWithSameName, command); + if (patientsWithSameName.size() >= 1) { + int numberChosen = ui.choosePatientToDelete(patientsWithSameName.size()); + if (numberChosen >= 1){ + boolean toDelete = ui.confirmPatientToBeDeleted(patientsWithSameName.get(numberChosen-1)); + if (toDelete){ + patientList.deletePatient(patientsWithSameName.get(numberChosen-1).getID()); + ui.patientDeleted(); + patientStorage.save(patientList.getPatientList()); + } + } + } + } } @Override diff --git a/src/main/java/duke/command/FindPatientCommand.java b/src/main/java/duke/command/FindPatientCommand.java index 4dff64bf02..fc8fea6c8f 100644 --- a/src/main/java/duke/command/FindPatientCommand.java +++ b/src/main/java/duke/command/FindPatientCommand.java @@ -21,7 +21,12 @@ public FindPatientCommand(String command){ public void execute(TaskList tasks, PatientList patientList, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { char firstChar = command.charAt(0); if (firstChar == '#'){ - int id = Integer.parseInt(command.substring(1, command.length())); + int id; + try { + id = Integer.parseInt(command.substring(1, command.length())); + }catch(Exception e) { + throw new DukeException("Please follow the format 'find patient #' or 'find patient '."); + } Patient patient = patientList.getPatient(id); ui.patientsFoundById(patient); } diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 5c57eb67a7..796df1b9fe 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -69,10 +69,9 @@ else if (tempCommand[0].toLowerCase().equals("tasks")){ String[] tempCommand = command[1].split("\\s+", 2); if (tempCommand[0].toLowerCase().equals("patient")){ try { - int id = Integer.parseInt(tempCommand[1]); - return new DeletePatientCommand(id); + return new DeletePatientCommand(tempCommand[1]); }catch(Exception e){ - throw new Exception("Please follow the format 'delete patient '."); + throw new Exception("Please follow the format 'delete patient #'."); } } else { diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index 856044e97f..bef55888c8 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -49,7 +49,7 @@ public void showError(String e) { /** * Shows that a Task has been added * - * @param t The Task that is added to the list. + * @param t The Task that is added to the list. */ public void taskAdded(StandardTask standardTask) { System.out.println("Got it. I've added this task: \n" + standardTask); @@ -62,17 +62,16 @@ public void showPatientInfo(Patient patient) { } public void patientsFoundByName(ArrayList patients, String name) { - if (patients.size() > 0){ - System.out.println("Got it. "+ patients.size() +" patients is/are found with name: "+ name); + if (patients.size() > 0) { + System.out.println("Got it. " + patients.size() + " patients is/are found with name: " + name); int i = 1; for (Patient patient : patients) { - System.out.println("Patient #"+ i); + System.out.println("Patient #" + i); showPatientInfo(patient); showLine(); i++; } - } - else{ + } else { System.out.println("No patient was found with name: " + name); } } @@ -88,9 +87,47 @@ public void patientAdded(Patient patient) { showPatientInfo(patient); } - public void patientDeleted(Patient patient) { - System.out.println("Got it. The following patient is deleted: "); + public int choosePatientToDelete(int numberOfPatients) { + int chosenNumber = -1; + while (true) { + System.out.println("Enter the number of patient to delete, or enter number 0 to cancel: "); + String command = readCommand(); + try { + chosenNumber = Integer.parseInt(command); + } catch (Exception e) { + System.out.println("Please enter a valid number!"); + continue; + } + if (chosenNumber >= 0 && chosenNumber <= numberOfPatients) { + if (chosenNumber == 0) { + System.out.println("Delete command is canceled"); + } + return chosenNumber; + } else { + System.out.println("The patient #" + chosenNumber + " does not exist. Please enter a valid number!"); + } + } + + } + + public boolean confirmPatientToBeDeleted(Patient patient) { showPatientInfo(patient); + while (true) { + System.out.println("The patient is to be deleted. Are you sure (Y/N)? "); + String command = readCommand(); + if (command.toLowerCase().equals("y")) { + return true; + } else if (command.toLowerCase().equals("n")) { + System.out.println("Delete command is canceled"); + return false; + } else { + System.out.println("Please enter only Y/N to confirm/cancel deletion!"); + } + } + } + + public void patientDeleted() { + System.out.println("Got it. The patient is deleted."); } public void listAllPatients(ArrayList patients) { From db27805898c7eda99ad07303e733fd495a0611a5 Mon Sep 17 00:00:00 2001 From: Qian Jie Date: Thu, 10 Oct 2019 09:52:23 +0800 Subject: [PATCH 103/420] added UpdateCommand to update existing patient information . --- data/patients.csv | 9 ++-- src/main/java/duke/command/UpdateCommand.java | 45 +++++++++++++++++++ src/main/java/duke/core/CommandManager.java | 13 ++++++ src/main/java/duke/core/Ui.java | 5 +++ src/main/java/duke/patient/Patient.java | 14 ++++++ src/main/java/duke/patient/PatientList.java | 4 -- 6 files changed, 82 insertions(+), 8 deletions(-) create mode 100644 src/main/java/duke/command/UpdateCommand.java diff --git a/data/patients.csv b/data/patients.csv index eb6282485d..8ea9f50bda 100644 --- a/data/patients.csv +++ b/data/patients.csv @@ -1,7 +1,8 @@ Id,Name,NRIC,Room,Remark -1,xk,G03123456,2A,no +1,xk,G03123456,xuankun,no 2,weifeng,G789456,9A,no -3,qijie,G123456,2c,no -9,weifeng,G12356,3B,male -10,kejun,abcd,no mood no modd,8A +3,qianjiee,G123456,2c,no +9,weifeng,G12356,7A,male +10,kejun,G1234567890,no mood no modd,8A 11,qianjie,1231312321,A5,NIL +12,qianjie,S92139123,A03,NIL diff --git a/src/main/java/duke/command/UpdateCommand.java b/src/main/java/duke/command/UpdateCommand.java new file mode 100644 index 0000000000..4ba39f112e --- /dev/null +++ b/src/main/java/duke/command/UpdateCommand.java @@ -0,0 +1,45 @@ +package duke.command; + +import duke.core.DukeException; +import duke.core.Ui; +import duke.patient.Patient; +import duke.patient.PatientList; +import duke.storage.PatientStorage; +import duke.storage.TaskStorage; +import duke.task.TaskList; + +public class UpdateCommand extends Command { + + private int Id; + private String targetInfo; + private String updatedValue; + + public UpdateCommand(int Id , String targetInfo , String updatedValue) { + super(); + this.Id = Id; + this.targetInfo = targetInfo; + this.updatedValue = updatedValue; + } + + @Override + public void execute(TaskList tasks, PatientList patientList, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + Patient targetPatient = patientList.getPatient(Id); + if (targetInfo.equals("name")) { + targetPatient.setName(updatedValue); + } else if (targetInfo.equals("nric")) { + targetPatient.setNric(updatedValue); + } else if (targetInfo.equals("room")) { + targetPatient.setRoom(updatedValue); + } else { + throw new DukeException("No such Patient information existed. Please Enter a valid Patient information"); + } + patientStorage.save(patientList.getPatientList()); + ui.showUpdateStatus(targetPatient , targetInfo); + + } + + @Override + public boolean isExit() { + return false; + } +} diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 796df1b9fe..90bf2fc417 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -98,6 +98,19 @@ else if (tempCommand[0].toLowerCase().equals("tasks")){ } case "reschedule": //do thing for 'reschedule' + case "update": + try { + String[] descriptions = command[1].split("\\s+"); + int targetId = Integer.parseInt(descriptions[1]); + String targetInfo = descriptions[2]; + String updateValue = descriptions[3]; + + return new UpdateCommand(targetId, targetInfo, updateValue); + + + } catch (Exception e) { + throw new DukeException("update command fails. " + e.getMessage()); + } case "view": //do thing for 'view' case "help": diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index bef55888c8..025d92cbe3 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -1,6 +1,7 @@ package duke.core; import duke.patient.Patient; +import duke.patient.PatientList; import duke.task.StandardTask; import duke.task.Task; @@ -331,6 +332,10 @@ public void showHelpCommand() { System.out.println("If you have any further enquiries, please contact us directly.\n"); } + public void showUpdateStatus(Patient patient , String targetInfo) { + System.out.println("I have successfully updated the " + targetInfo + " of " + patient.getName() + " ID:" + patient.getID() ); + } + /** * Shows an error in loading the file where past tasks are stored. */ diff --git a/src/main/java/duke/patient/Patient.java b/src/main/java/duke/patient/Patient.java index 5899672290..57fcfa648f 100644 --- a/src/main/java/duke/patient/Patient.java +++ b/src/main/java/duke/patient/Patient.java @@ -57,4 +57,18 @@ public void setID(int id){ this.id = id; } + public void setName(String name) { + this.name = name; + } + + public void setNric(String nric) { + this.nric = nric; + } + + public void setRoom(String room) { + this.room = room; + } + + + } \ No newline at end of file diff --git a/src/main/java/duke/patient/PatientList.java b/src/main/java/duke/patient/PatientList.java index 5ff78a2f78..e07095a38d 100644 --- a/src/main/java/duke/patient/PatientList.java +++ b/src/main/java/duke/patient/PatientList.java @@ -50,10 +50,6 @@ public void addPatient(Patient patient) { patientIdMap.put(patient.getID(), patient); } - public void updatePatientInfo(Patient patient) { - patientIdMap.put(patient.getID(), patient); - } - public ArrayList getPatientList() { return new ArrayList<>(patientIdMap.values()); } From 30030c02b4d66f400b3e2264d4239936884b85fd Mon Sep 17 00:00:00 2001 From: Qian Jie Date: Thu, 10 Oct 2019 18:20:22 +0800 Subject: [PATCH 104/420] change UpdateCommand to UpdatePatientCommand --- .../command/{UpdateCommand.java => UpdatePatientCommand.java} | 4 ++-- src/main/java/duke/core/CommandManager.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename src/main/java/duke/command/{UpdateCommand.java => UpdatePatientCommand.java} (90%) diff --git a/src/main/java/duke/command/UpdateCommand.java b/src/main/java/duke/command/UpdatePatientCommand.java similarity index 90% rename from src/main/java/duke/command/UpdateCommand.java rename to src/main/java/duke/command/UpdatePatientCommand.java index 4ba39f112e..a816f4dcf0 100644 --- a/src/main/java/duke/command/UpdateCommand.java +++ b/src/main/java/duke/command/UpdatePatientCommand.java @@ -8,13 +8,13 @@ import duke.storage.TaskStorage; import duke.task.TaskList; -public class UpdateCommand extends Command { +public class UpdatePatientCommand extends Command { private int Id; private String targetInfo; private String updatedValue; - public UpdateCommand(int Id , String targetInfo , String updatedValue) { + public UpdatePatientCommand(int Id , String targetInfo , String updatedValue) { super(); this.Id = Id; this.targetInfo = targetInfo; diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 90bf2fc417..c6df9a001a 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -105,7 +105,7 @@ else if (tempCommand[0].toLowerCase().equals("tasks")){ String targetInfo = descriptions[2]; String updateValue = descriptions[3]; - return new UpdateCommand(targetId, targetInfo, updateValue); + return new UpdatePatientCommand(targetId, targetInfo, updateValue); } catch (Exception e) { From 10edc2fe205d59e29b581d0991aaa96140f2a939 Mon Sep 17 00:00:00 2001 From: Qian Jie Date: Fri, 11 Oct 2019 16:10:54 +0800 Subject: [PATCH 105/420] Cleaned up unused code --- data/patients.csv | 2 +- data/standardTasks.csv | 1 + src/main/java/duke/Duke.java | 16 +- .../java/duke/command/AddPatientCommand.java | 10 +- .../duke/command/AddStandardTaskCommand.java | 12 +- src/main/java/duke/command/Command.java | 7 +- .../duke/command/DeletePatientCommand.java | 18 +-- src/main/java/duke/command/ExitCommand.java | 9 +- .../java/duke/command/FindPatientCommand.java | 10 +- src/main/java/duke/command/HelpCommand.java | 23 --- .../duke/command/ListPatientsCommand.java | 8 +- .../java/duke/command/ListTasksCommand.java | 6 +- .../duke/command/UpdatePatientCommand.java | 10 +- src/main/java/duke/core/CommandManager.java | 8 - src/main/java/duke/core/DateTimeParser.java | 57 ------- src/main/java/duke/core/Ui.java | 150 +----------------- src/main/java/duke/patient/Patient.java | 3 - .../{PatientList.java => PatientManager.java} | 5 +- .../java/duke/storage/PatientStorage.java | 1 - src/main/java/duke/storage/TaskStorage.java | 1 - src/main/java/duke/task/PersonalTask.java | 17 -- src/main/java/duke/task/Task.java | 49 ------ src/main/java/duke/task/TaskList.java | 87 ---------- src/main/java/duke/task/TaskManager.java | 45 ++++++ 24 files changed, 101 insertions(+), 454 deletions(-) delete mode 100644 src/main/java/duke/command/HelpCommand.java delete mode 100644 src/main/java/duke/core/DateTimeParser.java rename src/main/java/duke/patient/{PatientList.java => PatientManager.java} (91%) delete mode 100644 src/main/java/duke/task/PersonalTask.java delete mode 100644 src/main/java/duke/task/TaskList.java create mode 100644 src/main/java/duke/task/TaskManager.java diff --git a/data/patients.csv b/data/patients.csv index 8ea9f50bda..2f774fc938 100644 --- a/data/patients.csv +++ b/data/patients.csv @@ -5,4 +5,4 @@ Id,Name,NRIC,Room,Remark 9,weifeng,G12356,7A,male 10,kejun,G1234567890,no mood no modd,8A 11,qianjie,1231312321,A5,NIL -12,qianjie,S92139123,A03,NIL +13,chenyan,S93231231J,A02,NIL diff --git a/data/standardTasks.csv b/data/standardTasks.csv index 11fe78b8d0..b8f0de6334 100644 --- a/data/standardTasks.csv +++ b/data/standardTasks.csv @@ -8,3 +8,4 @@ hello world hello hell jojojo jojoj hello world +Drink water diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index 499eedc69e..17931a9317 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -3,10 +3,10 @@ import duke.command.Command; import duke.core.DukeException; import duke.core.CommandManager; -import duke.patient.PatientList; +import duke.patient.PatientManager; import duke.storage.PatientStorage; import duke.storage.TaskStorage; -import duke.task.TaskList; +import duke.task.TaskManager; import duke.core.Ui; /** @@ -24,8 +24,8 @@ public class Duke { * A TaskList object that deals with add, delete, mark as done, * find functions of a list of tasks. */ - private TaskList taskList; - private PatientList patientList; + private TaskManager taskManager; + private PatientManager patientManager; /** * A Ui object that deals with interactions with the user. */ @@ -42,11 +42,11 @@ public Duke(String filePath) { patientStorage = new PatientStorage(filePath + "/patients.csv"); try { - taskList = new TaskList(taskStorage.load()); - patientList = new PatientList(patientStorage.load()); + taskManager = new TaskManager(taskStorage.load()); + patientManager = new PatientManager(patientStorage.load()); } catch (DukeException e) { ui.showLoadingError(); - taskList = new TaskList(); + taskManager = new TaskManager(); } } @@ -62,7 +62,7 @@ public void run() { String fullCommand = ui.readCommand(); ui.showLine(); Command c = CommandManager.manageCommand(fullCommand); - c.execute(taskList,patientList, ui, taskStorage, patientStorage); + c.execute(taskManager, patientManager, ui, taskStorage, patientStorage); isExit = c.isExit(); } catch (DukeException e) { ui.showError(e.getMessage()); diff --git a/src/main/java/duke/command/AddPatientCommand.java b/src/main/java/duke/command/AddPatientCommand.java index 561779c7da..3cb0ca9505 100644 --- a/src/main/java/duke/command/AddPatientCommand.java +++ b/src/main/java/duke/command/AddPatientCommand.java @@ -3,10 +3,10 @@ import duke.core.DukeException; import duke.core.Ui; import duke.patient.Patient; -import duke.patient.PatientList; +import duke.patient.PatientManager; import duke.storage.PatientStorage; import duke.storage.TaskStorage; -import duke.task.TaskList; +import duke.task.TaskManager; public class AddPatientCommand extends Command { @@ -17,9 +17,9 @@ public AddPatientCommand(Patient newPatient) { } @Override - public void execute(TaskList tasks, PatientList patientList, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { - patientList.addPatient(newPatient); - patientStorage.save(patientList.getPatientList()); + public void execute(TaskManager tasks, PatientManager patientManager, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + patientManager.addPatient(newPatient); + patientStorage.save(patientManager.getPatientList()); ui.patientAdded(newPatient); } diff --git a/src/main/java/duke/command/AddStandardTaskCommand.java b/src/main/java/duke/command/AddStandardTaskCommand.java index ba7d72af8d..cdaea5a88b 100644 --- a/src/main/java/duke/command/AddStandardTaskCommand.java +++ b/src/main/java/duke/command/AddStandardTaskCommand.java @@ -2,13 +2,11 @@ import duke.core.DukeException; import duke.core.Ui; -import duke.patient.Patient; -import duke.patient.PatientList; +import duke.patient.PatientManager; import duke.storage.PatientStorage; import duke.storage.TaskStorage; -import duke.task.Task; import duke.task.StandardTask; -import duke.task.TaskList; +import duke.task.TaskManager; public class AddStandardTaskCommand extends Command{ private StandardTask newStandardTask; @@ -18,9 +16,9 @@ public AddStandardTaskCommand(StandardTask newStandardTask) { } @Override - public void execute(TaskList taskList, PatientList patientList, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { - taskList.addTask(newStandardTask); - taskStorage.save(taskList.getTaskList()); + public void execute(TaskManager taskManager, PatientManager patientManager, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + taskManager.addTask(newStandardTask); + taskStorage.save(taskManager.getTaskList()); ui.taskAdded(newStandardTask); } diff --git a/src/main/java/duke/command/Command.java b/src/main/java/duke/command/Command.java index 868465afb4..46aac00f0a 100644 --- a/src/main/java/duke/command/Command.java +++ b/src/main/java/duke/command/Command.java @@ -1,11 +1,10 @@ package duke.command; import duke.core.DukeException; -import duke.patient.PatientList; +import duke.patient.PatientManager; import duke.storage.PatientStorage; -import duke.storage.Storage; import duke.storage.TaskStorage; -import duke.task.TaskList; +import duke.task.TaskManager; import duke.core.Ui; /** @@ -24,7 +23,7 @@ public abstract class Command { * @throws DukeException throw exception during execution of the * command. */ - public abstract void execute(TaskList tasks, PatientList patientList, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException; + public abstract void execute(TaskManager tasks, PatientManager patientManager, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException; /** * Decide whether duke should exist. diff --git a/src/main/java/duke/command/DeletePatientCommand.java b/src/main/java/duke/command/DeletePatientCommand.java index 2b17c262c0..bbfa91e711 100644 --- a/src/main/java/duke/command/DeletePatientCommand.java +++ b/src/main/java/duke/command/DeletePatientCommand.java @@ -3,10 +3,10 @@ import duke.core.DukeException; import duke.core.Ui; import duke.patient.Patient; -import duke.patient.PatientList; +import duke.patient.PatientManager; import duke.storage.PatientStorage; import duke.storage.TaskStorage; -import duke.task.TaskList; +import duke.task.TaskManager; import java.util.ArrayList; @@ -19,7 +19,7 @@ public DeletePatientCommand(String command) { } @Override - public void execute(TaskList tasks, PatientList patientList, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + public void execute(TaskManager tasks, PatientManager patientManager, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { char firstChar = command.charAt(0); if (firstChar == '#') { int id; @@ -29,24 +29,24 @@ public void execute(TaskList tasks, PatientList patientList, Ui ui, TaskStorage throw new DukeException("Please follow the format 'delete patient #'."); } - Patient patientToBeDeleted = patientList.getPatient(id); + Patient patientToBeDeleted = patientManager.getPatient(id); boolean toDelete = ui.confirmPatientToBeDeleted(patientToBeDeleted); if (toDelete){ - patientList.deletePatient(id); + patientManager.deletePatient(id); ui.patientDeleted(); - patientStorage.save(patientList.getPatientList()); + patientStorage.save(patientManager.getPatientList()); } } else { - ArrayList patientsWithSameName = patientList.getPatientByName(command); + ArrayList patientsWithSameName = patientManager.getPatientByName(command); ui.patientsFoundByName(patientsWithSameName, command); if (patientsWithSameName.size() >= 1) { int numberChosen = ui.choosePatientToDelete(patientsWithSameName.size()); if (numberChosen >= 1){ boolean toDelete = ui.confirmPatientToBeDeleted(patientsWithSameName.get(numberChosen-1)); if (toDelete){ - patientList.deletePatient(patientsWithSameName.get(numberChosen-1).getID()); + patientManager.deletePatient(patientsWithSameName.get(numberChosen-1).getID()); ui.patientDeleted(); - patientStorage.save(patientList.getPatientList()); + patientStorage.save(patientManager.getPatientList()); } } } diff --git a/src/main/java/duke/command/ExitCommand.java b/src/main/java/duke/command/ExitCommand.java index 16c1ef619e..577ee023ca 100644 --- a/src/main/java/duke/command/ExitCommand.java +++ b/src/main/java/duke/command/ExitCommand.java @@ -1,10 +1,9 @@ package duke.command; -import duke.patient.PatientList; +import duke.patient.PatientManager; import duke.storage.PatientStorage; -import duke.storage.Storage; import duke.storage.TaskStorage; -import duke.task.TaskList; +import duke.task.TaskManager; import duke.core.Ui; /** @@ -36,9 +35,9 @@ public boolean isExit() { * * @param tasks The task list where tasks are saved. * @param ui The user interface. - * @param patientList object that handles local text file update + * @param patientManager object that handles local text file update */ - public void execute(TaskList tasks, PatientList patientList, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) { + public void execute(TaskManager tasks, PatientManager patientManager, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) { ui.exitInformation(); } } \ No newline at end of file diff --git a/src/main/java/duke/command/FindPatientCommand.java b/src/main/java/duke/command/FindPatientCommand.java index fc8fea6c8f..4449df4786 100644 --- a/src/main/java/duke/command/FindPatientCommand.java +++ b/src/main/java/duke/command/FindPatientCommand.java @@ -3,10 +3,10 @@ import duke.core.DukeException; import duke.core.Ui; import duke.patient.Patient; -import duke.patient.PatientList; +import duke.patient.PatientManager; import duke.storage.PatientStorage; import duke.storage.TaskStorage; -import duke.task.TaskList; +import duke.task.TaskManager; import java.util.ArrayList; @@ -18,7 +18,7 @@ public FindPatientCommand(String command){ } @Override - public void execute(TaskList tasks, PatientList patientList, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + public void execute(TaskManager tasks, PatientManager patientManager, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { char firstChar = command.charAt(0); if (firstChar == '#'){ int id; @@ -27,11 +27,11 @@ public void execute(TaskList tasks, PatientList patientList, Ui ui, TaskStorage }catch(Exception e) { throw new DukeException("Please follow the format 'find patient #' or 'find patient '."); } - Patient patient = patientList.getPatient(id); + Patient patient = patientManager.getPatient(id); ui.patientsFoundById(patient); } else{ - ArrayList patientsWithSameName = patientList.getPatientByName(command); + ArrayList patientsWithSameName = patientManager.getPatientByName(command); ui.patientsFoundByName(patientsWithSameName, command); } } diff --git a/src/main/java/duke/command/HelpCommand.java b/src/main/java/duke/command/HelpCommand.java deleted file mode 100644 index cdd644b78c..0000000000 --- a/src/main/java/duke/command/HelpCommand.java +++ /dev/null @@ -1,23 +0,0 @@ -package duke.command; - -import duke.core.DukeException; -import duke.patient.PatientList; -import duke.storage.PatientStorage; -import duke.storage.Storage; -import duke.storage.TaskStorage; -import duke.task.TaskList; -import duke.core.Ui; - -public class HelpCommand extends Command { - - @Override - public void execute(TaskList tasks, PatientList patientList, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { - ui.showHelpCommand(); - - } - - @Override - public boolean isExit() { - return false; - } -} diff --git a/src/main/java/duke/command/ListPatientsCommand.java b/src/main/java/duke/command/ListPatientsCommand.java index a090f409c9..2d33b33dc8 100644 --- a/src/main/java/duke/command/ListPatientsCommand.java +++ b/src/main/java/duke/command/ListPatientsCommand.java @@ -3,10 +3,10 @@ import duke.core.DukeException; import duke.core.Ui; import duke.patient.Patient; -import duke.patient.PatientList; +import duke.patient.PatientManager; import duke.storage.PatientStorage; import duke.storage.TaskStorage; -import duke.task.TaskList; +import duke.task.TaskManager; import java.util.ArrayList; @@ -17,8 +17,8 @@ public ListPatientsCommand() { } @Override - public void execute(TaskList tasks, PatientList patientList, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { - ArrayList list = patientList.getPatientList(); + public void execute(TaskManager tasks, PatientManager patientManager, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + ArrayList list = patientManager.getPatientList(); ui.listAllPatients(list); } diff --git a/src/main/java/duke/command/ListTasksCommand.java b/src/main/java/duke/command/ListTasksCommand.java index d4f6ba9dee..4cbceeb135 100644 --- a/src/main/java/duke/command/ListTasksCommand.java +++ b/src/main/java/duke/command/ListTasksCommand.java @@ -2,17 +2,17 @@ import duke.core.DukeException; import duke.core.Ui; -import duke.patient.PatientList; +import duke.patient.PatientManager; import duke.storage.PatientStorage; import duke.storage.TaskStorage; import duke.task.Task; -import duke.task.TaskList; +import duke.task.TaskManager; import java.util.ArrayList; public class ListTasksCommand extends Command { @Override - public void execute(TaskList tasks, PatientList patientList, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + public void execute(TaskManager tasks, PatientManager patientManager, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { ArrayList list = tasks.getTaskList(); ui.listAllTasks(list); } diff --git a/src/main/java/duke/command/UpdatePatientCommand.java b/src/main/java/duke/command/UpdatePatientCommand.java index a816f4dcf0..0bd1c0c0b6 100644 --- a/src/main/java/duke/command/UpdatePatientCommand.java +++ b/src/main/java/duke/command/UpdatePatientCommand.java @@ -3,10 +3,10 @@ import duke.core.DukeException; import duke.core.Ui; import duke.patient.Patient; -import duke.patient.PatientList; +import duke.patient.PatientManager; import duke.storage.PatientStorage; import duke.storage.TaskStorage; -import duke.task.TaskList; +import duke.task.TaskManager; public class UpdatePatientCommand extends Command { @@ -22,8 +22,8 @@ public UpdatePatientCommand(int Id , String targetInfo , String updatedValue) { } @Override - public void execute(TaskList tasks, PatientList patientList, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { - Patient targetPatient = patientList.getPatient(Id); + public void execute(TaskManager tasks, PatientManager patientManager, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + Patient targetPatient = patientManager.getPatient(Id); if (targetInfo.equals("name")) { targetPatient.setName(updatedValue); } else if (targetInfo.equals("nric")) { @@ -33,7 +33,7 @@ public void execute(TaskList tasks, PatientList patientList, Ui ui, TaskStorage } else { throw new DukeException("No such Patient information existed. Please Enter a valid Patient information"); } - patientStorage.save(patientList.getPatientList()); + patientStorage.save(patientManager.getPatientList()); ui.showUpdateStatus(targetPatient , targetInfo); } diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index c6df9a001a..750af65c5f 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -62,8 +62,6 @@ else if (tempCommand[0].toLowerCase().equals("tasks")){ } catch (Exception e) { throw new DukeException("List command fails. " + e.getMessage()); } - case "done": - //do thing for 'done' case "delete": try{ String[] tempCommand = command[1].split("\\s+", 2); @@ -96,8 +94,6 @@ else if (tempCommand[0].toLowerCase().equals("tasks")){ } catch(Exception e){ throw new DukeException("Find command fails. " + e.getMessage()); } - case "reschedule": - //do thing for 'reschedule' case "update": try { String[] descriptions = command[1].split("\\s+"); @@ -111,10 +107,6 @@ else if (tempCommand[0].toLowerCase().equals("tasks")){ } catch (Exception e) { throw new DukeException("update command fails. " + e.getMessage()); } - case "view": - //do thing for 'view' - case "help": - //do thing for 'help' case "bye": return new ExitCommand(); default: diff --git a/src/main/java/duke/core/DateTimeParser.java b/src/main/java/duke/core/DateTimeParser.java deleted file mode 100644 index c6c4993c0a..0000000000 --- a/src/main/java/duke/core/DateTimeParser.java +++ /dev/null @@ -1,57 +0,0 @@ -package duke.core; - -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.time.format.DateTimeParseException; - - -public class DateTimeParser { - - /** - * update the LocalDateTime constructor to save the date and time - * - * @param timeBeforeFormat the time retrieved from user input. - * @return A LocalDateTime object that contains date and time information. - */ - - public static LocalDateTime convertToLocalDateTime(String timeBeforeFormat) throws DukeException { - DateTimeFormatter parser = DateTimeFormatter.ofPattern("dd/MM/yyyy HHmm"); - LocalDateTime localDateTime; - try { - localDateTime = LocalDateTime.parse(timeBeforeFormat, parser); - return localDateTime; - } catch (DateTimeParseException error) { - throw new DukeException("Invalid format. Please Enter Date and Time in the format of dd/MM/yyyy HHmm"); - } - } - - /** - * Returns a string that representing the data and time for the task - * in a predefined English date time format. - * - * @param timeBeforeFormat A String that provides the data and time information in dd/MM/yyyy HHmm. - * @return A String that provides date and time in English - */ - public static String convertToEnglishDateTime(String timeBeforeFormat) throws DukeException { - DateTimeFormatter stFormatter = DateTimeFormatter.ofPattern("d'st of' MMMM yyyy, ha"); - DateTimeFormatter ndFormatter = DateTimeFormatter.ofPattern("d'nd of' MMMM yyyy, ha"); - DateTimeFormatter rdFormatter = DateTimeFormatter.ofPattern("d'rd of' MMMM yyyy, ha"); - DateTimeFormatter thFormatter = DateTimeFormatter.ofPattern("d'th of' MMMM yyyy, ha"); - - try { - LocalDateTime localDateTime; - localDateTime = convertToLocalDateTime(timeBeforeFormat); - if ((localDateTime.getDayOfMonth() % 10) == 1) { - return localDateTime.format(stFormatter); - } else if ((localDateTime.getDayOfMonth() % 10) == 2) { - return localDateTime.format(ndFormatter); - } else if ((localDateTime.getDayOfMonth() % 10) == 3) { - return localDateTime.format(rdFormatter); - } else { - return localDateTime.format(thFormatter); - } - } catch (DukeException e) { - throw e; - } - } -} diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index 025d92cbe3..eba5ef3b29 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -1,7 +1,6 @@ package duke.core; import duke.patient.Patient; -import duke.patient.PatientList; import duke.task.StandardTask; import duke.task.Task; @@ -50,7 +49,7 @@ public void showError(String e) { /** * Shows that a Task has been added * - * @param t The Task that is added to the list. + * @param standardTask The Task that is added to the list. */ public void taskAdded(StandardTask standardTask) { System.out.println("Got it. I've added this task: \n" + standardTask); @@ -146,130 +145,11 @@ public void listAllTasks(ArrayList taskList) { + ". " + "[" + task.getStatusIcon() + "] " + task.getDescription() - + formatTaskDateTime(task) + "\n"); index++; } } - public String formatTaskDateTime(Task task) { - if (task.getDateTime().equals("")) { - return ""; - } else { - return " at " + task.getDateTime(); - } - } - - - /** - * Shows that a Task has been marked as done. - * - * @param t The Task that is marked as done. - */ -// public void markedAsDone(Task t) { -// System.out.println("Nice! I've marked this task as done: \n " + t.printStatus()); -// } - - /** - * Shows that a Task has been removed, and displays the number - * of current tasks in the list. - * - * @param t The Task that is deleted from the list. - */ -// public void taskRemoved(Task t, int size) { -// System.out.println("Noted. I've removed this task: \n " + t.toString() + "\nNow you have " -// + size + " tasks in the list."); -// } - - /** - * Shows that a Task has been rescheduled to a new date and time. - * - * @param t The Task that is rescheduled in the list. - */ -// public void taskRescheduled(Task t) { -// System.out.println("Noted. I've rescheduled this task: \n " + t.toString()); -// } - - /** - * Find and display a specific task stored in the list. - * - * @param a TaskList used to store tasks. - * @param name name of the task to be found - */ -// public void taskFound(ArrayList a, String name) { -// System.out.println("Here are the matching tasks in your list:"); -// int count = 1; -// for (Task x : a) { -// if (x.getDescription().contains(name)) { -// System.out.println(count + "." + x.toString()); -// count++; -// } -// } -// } - - /** - * Find and display a specific task stored in the list. - * - * @param clashTasksInTheList TaskList used to store tasks. - * @param newTask the task to be added - * @return the user's answer to whether he want to add or about the task - */ -// public void showClashWarning (ArrayList clashTasksInTheList, Task newTask) { -// System.out.println("Here are the tasks that fall on the same day:"); -// int count = 1; -// for (Task t : clashTasksInTheList) { -// System.out.println(count + ": " + t); -// count++; -// } -// showLine(); -// System.out.println("Do you still want to add your task anyway? Y/N"); -// } - - - /** - * Print out the tasks in the task list which is reaching - * the deadline. - * @param a TaskList used to store tasks. - */ -// public void taskReminder(ArrayList a) { -// System.out.println("The following tasks are reaching your deadline:"); -// System.out.println("Mark it as done or reschedule them to stop the reminder"); -// int count = 1; -// for (Task x : a) { -// System.out.println(count + "." + x.toString()); -// count++; -// } -// } - - /** - * Print out the schedules on a specific date. - * @param a TaskList used to store tasks. - * @param date selected date of the schedule. - */ -// public void showSchedules (ArrayList a , String date) { -// System.out.println("This is your schedules on " + date); -// try { -// DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/M/yyyy"); -// int count = 1; -// for (Task task : a) { -// String currentTaskDate = task.getDateTime().format(formatter); -// if (currentTaskDate.equals(date)) { -// System.out.println(count + ": " + task); -// } -// count++; -// } -// } catch (DateTimeParseException e) { -// System.out.println("Invalid format. Please Enter Date and Time in the the format of dd/MM/yyyy"); -// -// } -// } - -// public void makeRecurring(Task t) { -// System.out.println("Okay. This task has been marked as recurring:\n" -// + t.toString()); -// -// } - /** * Shows a divider line. */ @@ -277,17 +157,6 @@ public void showLine() { System.out.println("____________________________________________________________"); } - /** - * Displays all tasks currently stored in the list. - * - * @param tasks The TaskList used to store tasks. - */ -// public void listTasks(TaskList tasks) throws DukeException { -// System.out.println("Here are the tasks in your list:"); -// for (int i = 1; i <= tasks.getSize(); i++) { -// System.out.println(i + "." + tasks.getTask(i).toString()); -// } -// } /** * Shows bye message to user. @@ -314,23 +183,6 @@ public void showWelcome() { System.out.println("Enter 'help' to show a list of commands "); } - public void showHelpCommand() { - System.out.println("Here are the things you can do with Dukepital:\n"); - System.out.println("1. list - to show a list of all the tasks\n"); - System.out.println("2. delete - to delete a task in the list\n"); - System.out.println("3. done - to set a task as completed\n"); - System.out.println("4. find - to find a task based on keywords from the list\n"); - System.out.println("5. todo - to add a todo task\n"); - System.out.println("6. fixeddurationtask - to add a task with fixed duration\n"); - System.out.println("7. deadline - to add a task with a deadline\n"); - System.out.println("8. event - to add a task with date ad time\n"); - System.out.println("9. period - to add a period task\n"); - System.out.println("10. reschedule - to reschedule a task\n"); - System.out.println("11. view - to check a task of a specific date\n"); - System.out.println("12. recurring - to make a task recurring\n"); - System.out.println("13. bye - to exit Dukepital\n"); - System.out.println("If you have any further enquiries, please contact us directly.\n"); - } public void showUpdateStatus(Patient patient , String targetInfo) { System.out.println("I have successfully updated the " + targetInfo + " of " + patient.getName() + " ID:" + patient.getID() ); diff --git a/src/main/java/duke/patient/Patient.java b/src/main/java/duke/patient/Patient.java index 57fcfa648f..4b6f363b7a 100644 --- a/src/main/java/duke/patient/Patient.java +++ b/src/main/java/duke/patient/Patient.java @@ -1,7 +1,5 @@ package duke.patient; -import java.util.ArrayList; - /** * Represents a Patient. */ @@ -10,7 +8,6 @@ public class Patient { private String nric; private String name; private String remark; - private ArrayList remarkList = new ArrayList(); private String room; public Patient(int id, String name, String nric, String room, String remark) { diff --git a/src/main/java/duke/patient/PatientList.java b/src/main/java/duke/patient/PatientManager.java similarity index 91% rename from src/main/java/duke/patient/PatientList.java rename to src/main/java/duke/patient/PatientManager.java index e07095a38d..518ccbfac2 100644 --- a/src/main/java/duke/patient/PatientList.java +++ b/src/main/java/duke/patient/PatientManager.java @@ -5,15 +5,14 @@ import java.util.ArrayList; import java.util.HashMap; -public class PatientList { +public class PatientManager { private HashMap patientIdMap = new HashMap(); - //private HashMap patientNameMap = new HashMap(); private int maxId = 0; /** * instantiate a new TaskList with a empty list. */ - public PatientList(ArrayList patientList) { + public PatientManager(ArrayList patientList) { for (Patient patient : patientList) { patientIdMap.put(patient.getID(), patient); } diff --git a/src/main/java/duke/storage/PatientStorage.java b/src/main/java/duke/storage/PatientStorage.java index 84b63ed35c..27c3ce55a9 100644 --- a/src/main/java/duke/storage/PatientStorage.java +++ b/src/main/java/duke/storage/PatientStorage.java @@ -40,7 +40,6 @@ public ArrayList load() throws DukeException { String remark = record.get("Remark"); String room = record.get("Room"); patientList.add(new Patient(id, name, nric, room, remark)); -// System.out.println(id + " | " + name + " | " + nric + " | " + remark + " | " + room); //List out patietns info for debugging } return patientList; } catch (IOException e) { diff --git a/src/main/java/duke/storage/TaskStorage.java b/src/main/java/duke/storage/TaskStorage.java index e4a6f5b68a..36a999c826 100644 --- a/src/main/java/duke/storage/TaskStorage.java +++ b/src/main/java/duke/storage/TaskStorage.java @@ -65,7 +65,6 @@ public void save(ArrayList tasks) throws DukeException { BufferedWriter writer = Files.newBufferedWriter(Paths.get(filePath)); CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT .withHeader("Description")); -// ArrayList tasks = taskList.getTaskList(); for (Task task : tasks){ String description = task.getDescription(); csvPrinter.printRecord(description); diff --git a/src/main/java/duke/task/PersonalTask.java b/src/main/java/duke/task/PersonalTask.java deleted file mode 100644 index fdb56d6072..0000000000 --- a/src/main/java/duke/task/PersonalTask.java +++ /dev/null @@ -1,17 +0,0 @@ -package duke.task; - -public class PersonalTask extends Task { - - //private patient Patient; - - public PersonalTask(String description) { //2nd parameter: Patient - super(description); - //this.patient = patient; - } - - @Override - public String toString() { - return null; - } - -} \ No newline at end of file diff --git a/src/main/java/duke/task/Task.java b/src/main/java/duke/task/Task.java index 7aa2415ce2..6d662028b1 100644 --- a/src/main/java/duke/task/Task.java +++ b/src/main/java/duke/task/Task.java @@ -1,8 +1,5 @@ package duke.task; -import java.util.ArrayList; - - /** * Represents a task. Task is an abstract class that can not be * instantiated @@ -19,16 +16,6 @@ public abstract class Task { */ private boolean isDone; - /** - * A string to describe the date/time of the task. - */ - private String dateTime = ""; - - /** - * An arraylist of things the nurse can bring for the task. - */ - private ArrayList thingsToBring; - /** * Initialises the minimum fields required to setup a Task. * @@ -37,13 +24,10 @@ public abstract class Task { public Task(String description, String dateTime) { this.description = description; this.isDone = false; - this.thingsToBring = new ArrayList(); - this.dateTime = dateTime; } public Task(String description) { this.description = description; - this.thingsToBring = new ArrayList(); this.isDone = false; } @@ -72,22 +56,6 @@ public void markAsDone() { isDone = true; } -// /** -// * Returns a string with the following format to be stored in a local file. -// * -// * @return A string in a specific format to be stored in a local file. -// */ -// public abstract String writeTxt(); - - /** - * Returns a string with the status icon and the description of the task. - * - * @return A string in a specific format with the status and description of the task. - */ - public String printStatus() { - return "[" + this.getStatusIcon() + "] " + description; - } - /** * Returns the description of the task. * @@ -99,23 +67,6 @@ public String getDescription() { return description; } - /** - * update the dateTime String to save the date and time. - * @param newDateTime the time retrieved from user input. - */ - - public void updateDateTime(String newDateTime) { - this.dateTime = newDateTime; - } - - /** - * Returns the dateTime String. - */ - - public String getDateTime() { - return dateTime; - } - public abstract String toString(); } \ No newline at end of file diff --git a/src/main/java/duke/task/TaskList.java b/src/main/java/duke/task/TaskList.java deleted file mode 100644 index e48e6f9cab..0000000000 --- a/src/main/java/duke/task/TaskList.java +++ /dev/null @@ -1,87 +0,0 @@ -package duke.task; - -import duke.core.DukeException; -import java.util.ArrayList; - -/** - * Represents a list of Task that can perform operations such as - * add and delete on the tasks. - */ -public class TaskList { - /** - * An ArrayList structure. - */ - private ArrayList taskList; - - /** - * Constructor used when Duke successfully loads a TaskList from a saved file. - * Takes loaded taskList and uses it during Duke's new session. - * @param loadedTaskList - */ - public TaskList(ArrayList loadedTaskList) { - this.taskList = loadedTaskList; - } - - /** - * Constructor used when Duke cannot successfully load a TaskList from a saved file. - * Instantiates a new TaskList with an empty list. - */ - public TaskList() { - this.taskList = new ArrayList(); - } - - /** - * Retrieves the entire task list stored inside the ArrayList. - */ - public ArrayList fullTaskList() { - return taskList; - } - - /** - * Adds a Task to the list. - * - * @param t The Task to be added to the list. - */ - public void addTask(Task t) { - taskList.add(t); - } - - /** - * Removes the Task with the given index from the list. - * - * @param i The index of the Task to be deleted. - */ - public void deleteTask(Integer i) throws DukeException { - if (getSize() < i) { - throw new DukeException("Task Number " + i + " does not exist"); - } - taskList.remove(i - 1); - } - - /** - * Returns the Task in the list with the given index. - * - * @param i The index of the Task. - * @return The Task in the list with the specific index. - */ - public Task getTask(int i) throws DukeException { - if (getSize() < i) { - throw new DukeException("Task Number " + i + " does not exist"); - } - return taskList.get(i - 1); - } - - /** - * Returns the size of task list. - * - * @return An integer representing the number of tasks in the list. - */ - public int getSize() { - return taskList.size(); - } - - public ArrayList getTaskList() { - return new ArrayList<>(taskList); - } - -} diff --git a/src/main/java/duke/task/TaskManager.java b/src/main/java/duke/task/TaskManager.java new file mode 100644 index 0000000000..293e9581b8 --- /dev/null +++ b/src/main/java/duke/task/TaskManager.java @@ -0,0 +1,45 @@ +package duke.task; + +import java.util.ArrayList; + +/** + * Represents a list of Task that can perform operations such as + * add and delete on the tasks. + */ +public class TaskManager { + /** + * An ArrayList structure. + */ + private ArrayList taskList; + + /** + * Constructor used when Duke successfully loads a TaskList from a saved file. + * Takes loaded taskList and uses it during Duke's new session. + * @param loadedTaskList + */ + public TaskManager(ArrayList loadedTaskList) { + this.taskList = loadedTaskList; + } + + /** + * Constructor used when Duke cannot successfully load a TaskList from a saved file. + * Instantiates a new TaskList with an empty list. + */ + public TaskManager() { + this.taskList = new ArrayList(); + } + + /** + * Adds a Task to the list. + * + * @param t The Task to be added to the list. + */ + public void addTask(Task t) { + taskList.add(t); + } + + public ArrayList getTaskList() { + return new ArrayList<>(taskList); + } + +} From 5568f7550e9c7202426892df9081a48cba7f2e84 Mon Sep 17 00:00:00 2001 From: Qian Jie Date: Fri, 11 Oct 2019 16:16:15 +0800 Subject: [PATCH 106/420] fixed a index bug where the task lists is shown from index 0 instead of 1 --- src/main/java/duke/core/Ui.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index eba5ef3b29..cccada0a4b 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -138,7 +138,7 @@ public void listAllPatients(ArrayList patients) { } public void listAllTasks(ArrayList taskList) { - int index = 0; + int index = 1; System.out.println("Here's a list of your tasks: \n"); for (Task task : taskList) { System.out.println(index From 318ea79c484231e07dde820a5927096b28619d2c Mon Sep 17 00:00:00 2001 From: wei feng Date: Fri, 11 Oct 2019 20:48:13 +0800 Subject: [PATCH 107/420] Update the framework of the program, removed StandardTask, implemented a new task class call PatientTask to relate both Patient and Task --- build.gradle | 1 + data/patients.csv | 2 +- data/patientsTasks.csv | 12 +++ data/standardTasks.csv | 4 +- src/main/java/duke/Duke.java | 9 +- .../java/duke/command/AddPatientCommand.java | 4 +- .../duke/command/AddStandardTaskCommand.java | 10 +- .../command/AssignTaskToPatientCommand.java | 41 +++++++++ src/main/java/duke/command/Command.java | 16 +--- .../duke/command/DeletePatientCommand.java | 4 +- src/main/java/duke/command/ExitCommand.java | 6 +- .../java/duke/command/FindPatientCommand.java | 4 +- src/main/java/duke/command/HelpCommand.java | 5 +- .../duke/command/ListPatientsCommand.java | 4 +- .../java/duke/command/ListTasksCommand.java | 4 +- .../duke/command/UpdatePatientCommand.java | 4 +- src/main/java/duke/core/CommandManager.java | 34 ++++++- src/main/java/duke/core/DateTimeParser.java | 17 ++++ src/main/java/duke/core/Ui.java | 26 ++---- src/main/java/duke/patient/PatientList.java | 9 ++ .../java/duke/relation/EventPatientTask.java | 80 ++++++++++++++++ src/main/java/duke/relation/PatientTask.java | 77 ++++++++++++++++ .../java/duke/relation/PatientTaskList.java | 85 +++++++++++++++++ .../java/duke/storage/PatientStorage.java | 3 +- .../java/duke/storage/PatientTaskStorage.java | 90 ++++++++++++++++++ src/main/java/duke/storage/Storage.java | 17 ---- src/main/java/duke/storage/TaskStorage.java | 8 +- src/main/java/duke/task/PersonalTask.java | 17 ---- src/main/java/duke/task/StandardTask.java | 20 ---- src/main/java/duke/task/Task.java | 91 +------------------ src/main/java/duke/task/TaskList.java | 9 ++ 31 files changed, 510 insertions(+), 203 deletions(-) create mode 100644 data/patientsTasks.csv create mode 100644 src/main/java/duke/command/AssignTaskToPatientCommand.java create mode 100644 src/main/java/duke/relation/EventPatientTask.java create mode 100644 src/main/java/duke/relation/PatientTask.java create mode 100644 src/main/java/duke/relation/PatientTaskList.java create mode 100644 src/main/java/duke/storage/PatientTaskStorage.java delete mode 100644 src/main/java/duke/storage/Storage.java delete mode 100644 src/main/java/duke/task/PersonalTask.java delete mode 100644 src/main/java/duke/task/StandardTask.java diff --git a/build.gradle b/build.gradle index d799ed1cda..5e0a638204 100644 --- a/build.gradle +++ b/build.gradle @@ -22,6 +22,7 @@ shadowJar { dependencies { testImplementation 'org.junit.jupiter:junit-jupiter:5.5.0' compile "org.apache.commons:commons-csv:1.7" + compile group: 'com.google.guava', name: 'guava', version: '23.5-jre' } test { diff --git a/data/patients.csv b/data/patients.csv index 8ea9f50bda..b35135cb98 100644 --- a/data/patients.csv +++ b/data/patients.csv @@ -5,4 +5,4 @@ Id,Name,NRIC,Room,Remark 9,weifeng,G12356,7A,male 10,kejun,G1234567890,no mood no modd,8A 11,qianjie,1231312321,A5,NIL -12,qianjie,S92139123,A03,NIL +12,qianjie,S92139123,A03,NIL \ No newline at end of file diff --git a/data/patientsTasks.csv b/data/patientsTasks.csv new file mode 100644 index 0000000000..7d01f29a9f --- /dev/null +++ b/data/patientsTasks.csv @@ -0,0 +1,12 @@ +PID,TID,DONE,RECURRENCE,DEADLINE,STARTTIME,ENDTIME,TASKTYPE +1,3,false,false,09/11/2019 1400,,,S +1,3,false,false,09/11/2019 1400,,,S +1,3,false,false,09/11/2019 1400,,,S +1,3,false,false,09/11/2019 1400,,,S +1,3,false,false,09/11/2019 1400,,,S +1,3,false,false,,21/01/2019 1400,12/05/2020 1500,E +1,3,false,false,,21/01/2019 1400,12/05/2020 1500,E +1,3,false,false,,21/01/2019 1400,12/05/2020 1500,E +2,4,false,false,09/11/2019 1050,,,S + + diff --git a/data/standardTasks.csv b/data/standardTasks.csv index 11fe78b8d0..d131b19974 100644 --- a/data/standardTasks.csv +++ b/data/standardTasks.csv @@ -1,10 +1,8 @@ Description Take medicine abc -123 eat medicine lalala test task name with multiple words hello world hello hell -jojojo jojoj -hello world +jojojo jojoj \ No newline at end of file diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index 499eedc69e..e744e2a06c 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -5,7 +5,9 @@ import duke.core.CommandManager; import duke.patient.PatientList; import duke.storage.PatientStorage; +import duke.storage.PatientTaskStorage; import duke.storage.TaskStorage; +import duke.relation.PatientTaskList; import duke.task.TaskList; import duke.core.Ui; @@ -20,12 +22,14 @@ public class Duke { */ private TaskStorage taskStorage; private PatientStorage patientStorage; + private PatientTaskStorage patientTaskStorage; /** * A TaskList object that deals with add, delete, mark as done, * find functions of a list of tasks. */ private TaskList taskList; private PatientList patientList; + private PatientTaskList patientTaskList; /** * A Ui object that deals with interactions with the user. */ @@ -40,12 +44,15 @@ public class Duke { public Duke(String filePath) { taskStorage = new TaskStorage(filePath + "/standardTasks.csv"); patientStorage = new PatientStorage(filePath + "/patients.csv"); + patientTaskStorage = new PatientTaskStorage(filePath + "/patientsTasks.csv"); try { taskList = new TaskList(taskStorage.load()); patientList = new PatientList(patientStorage.load()); + patientTaskList = new PatientTaskList(patientTaskStorage.load()); } catch (DukeException e) { ui.showLoadingError(); + System.out.println(e.getMessage()); taskList = new TaskList(); } } @@ -62,7 +69,7 @@ public void run() { String fullCommand = ui.readCommand(); ui.showLine(); Command c = CommandManager.manageCommand(fullCommand); - c.execute(taskList,patientList, ui, taskStorage, patientStorage); + c.execute(patientTaskList,taskList,patientList, ui, patientTaskStorage, taskStorage, patientStorage); isExit = c.isExit(); } catch (DukeException e) { ui.showError(e.getMessage()); diff --git a/src/main/java/duke/command/AddPatientCommand.java b/src/main/java/duke/command/AddPatientCommand.java index 561779c7da..7e294e80fa 100644 --- a/src/main/java/duke/command/AddPatientCommand.java +++ b/src/main/java/duke/command/AddPatientCommand.java @@ -5,7 +5,9 @@ import duke.patient.Patient; import duke.patient.PatientList; import duke.storage.PatientStorage; +import duke.storage.PatientTaskStorage; import duke.storage.TaskStorage; +import duke.relation.PatientTaskList; import duke.task.TaskList; public class AddPatientCommand extends Command { @@ -17,7 +19,7 @@ public AddPatientCommand(Patient newPatient) { } @Override - public void execute(TaskList tasks, PatientList patientList, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + public void execute(PatientTaskList patientTask, TaskList tasks, PatientList patientList, Ui ui, PatientTaskStorage patientTaskStorage,TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { patientList.addPatient(newPatient); patientStorage.save(patientList.getPatientList()); ui.patientAdded(newPatient); diff --git a/src/main/java/duke/command/AddStandardTaskCommand.java b/src/main/java/duke/command/AddStandardTaskCommand.java index ba7d72af8d..b857a15a87 100644 --- a/src/main/java/duke/command/AddStandardTaskCommand.java +++ b/src/main/java/duke/command/AddStandardTaskCommand.java @@ -2,23 +2,23 @@ import duke.core.DukeException; import duke.core.Ui; -import duke.patient.Patient; import duke.patient.PatientList; import duke.storage.PatientStorage; +import duke.storage.PatientTaskStorage; import duke.storage.TaskStorage; +import duke.relation.PatientTaskList; import duke.task.Task; -import duke.task.StandardTask; import duke.task.TaskList; public class AddStandardTaskCommand extends Command{ - private StandardTask newStandardTask; - public AddStandardTaskCommand(StandardTask newStandardTask) { + private Task newStandardTask; + public AddStandardTaskCommand(Task newStandardTask) { super(); this.newStandardTask = newStandardTask; } @Override - public void execute(TaskList taskList, PatientList patientList, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + public void execute(PatientTaskList patientTask, TaskList taskList, PatientList patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { taskList.addTask(newStandardTask); taskStorage.save(taskList.getTaskList()); ui.taskAdded(newStandardTask); diff --git a/src/main/java/duke/command/AssignTaskToPatientCommand.java b/src/main/java/duke/command/AssignTaskToPatientCommand.java new file mode 100644 index 0000000000..03bc1278cf --- /dev/null +++ b/src/main/java/duke/command/AssignTaskToPatientCommand.java @@ -0,0 +1,41 @@ +package duke.command; + +import duke.core.DukeException; +import duke.core.Ui; +import duke.patient.PatientList; +import duke.storage.PatientStorage; +import duke.storage.PatientTaskStorage; +import duke.storage.TaskStorage; +import duke.relation.PatientTask; +import duke.relation.PatientTaskList; +import duke.task.TaskList; + +public class AssignTaskToPatientCommand extends Command { + + private PatientTask newPatientTask; + + public AssignTaskToPatientCommand(PatientTask patientTask) { + super(); + this.newPatientTask = patientTask; + } + + @Override + public void execute(PatientTaskList patientTaskList, TaskList tasksList, PatientList patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + if (patientList.isExist(newPatientTask.getPatientId()) && tasksList.isExist(newPatientTask.getTaskID())) + { + patientTaskList.addPatientTask(newPatientTask); + patientTaskStorage.save(patientTaskList.fullPatientTaskList()); + ui.patientTaskAssigned(newPatientTask, patientList.getPatient(newPatientTask.getPatientId()).getName(), tasksList.getTask(newPatientTask.getTaskID()).getDescription()); + } + else + { + throw new DukeException("Either the patient or the task does not exist in our data record"); + } + + } + + @Override + public boolean isExit() { + return false; + } +} diff --git a/src/main/java/duke/command/Command.java b/src/main/java/duke/command/Command.java index 868465afb4..bd4538f617 100644 --- a/src/main/java/duke/command/Command.java +++ b/src/main/java/duke/command/Command.java @@ -3,8 +3,9 @@ import duke.core.DukeException; import duke.patient.PatientList; import duke.storage.PatientStorage; -import duke.storage.Storage; +import duke.storage.PatientTaskStorage; import duke.storage.TaskStorage; +import duke.relation.PatientTaskList; import duke.task.TaskList; import duke.core.Ui; @@ -15,16 +16,9 @@ */ public abstract class Command { - /** - * run the command with the respect TaskList, UI, and storage. - * - * @param tasks The task list where tasks are saved. - * @param ui The user interface. - * @param storage object that handles local text file update - * @throws DukeException throw exception during execution of the - * command. - */ - public abstract void execute(TaskList tasks, PatientList patientList, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException; + + + public abstract void execute(PatientTaskList patientTask, TaskList tasks, PatientList patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException; /** * Decide whether duke should exist. diff --git a/src/main/java/duke/command/DeletePatientCommand.java b/src/main/java/duke/command/DeletePatientCommand.java index 2b17c262c0..282bc371a1 100644 --- a/src/main/java/duke/command/DeletePatientCommand.java +++ b/src/main/java/duke/command/DeletePatientCommand.java @@ -5,7 +5,9 @@ import duke.patient.Patient; import duke.patient.PatientList; import duke.storage.PatientStorage; +import duke.storage.PatientTaskStorage; import duke.storage.TaskStorage; +import duke.relation.PatientTaskList; import duke.task.TaskList; import java.util.ArrayList; @@ -19,7 +21,7 @@ public DeletePatientCommand(String command) { } @Override - public void execute(TaskList tasks, PatientList patientList, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + public void execute(PatientTaskList patientTask, TaskList tasks, PatientList patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { char firstChar = command.charAt(0); if (firstChar == '#') { int id; diff --git a/src/main/java/duke/command/ExitCommand.java b/src/main/java/duke/command/ExitCommand.java index 16c1ef619e..653544fe31 100644 --- a/src/main/java/duke/command/ExitCommand.java +++ b/src/main/java/duke/command/ExitCommand.java @@ -2,8 +2,9 @@ import duke.patient.PatientList; import duke.storage.PatientStorage; -import duke.storage.Storage; +import duke.storage.PatientTaskStorage; import duke.storage.TaskStorage; +import duke.relation.PatientTaskList; import duke.task.TaskList; import duke.core.Ui; @@ -38,7 +39,6 @@ public boolean isExit() { * @param ui The user interface. * @param patientList object that handles local text file update */ - public void execute(TaskList tasks, PatientList patientList, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) { - ui.exitInformation(); + public void execute(PatientTaskList patientTask, TaskList tasks, PatientList patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage){ } } \ No newline at end of file diff --git a/src/main/java/duke/command/FindPatientCommand.java b/src/main/java/duke/command/FindPatientCommand.java index fc8fea6c8f..98328f9d86 100644 --- a/src/main/java/duke/command/FindPatientCommand.java +++ b/src/main/java/duke/command/FindPatientCommand.java @@ -5,7 +5,9 @@ import duke.patient.Patient; import duke.patient.PatientList; import duke.storage.PatientStorage; +import duke.storage.PatientTaskStorage; import duke.storage.TaskStorage; +import duke.relation.PatientTaskList; import duke.task.TaskList; import java.util.ArrayList; @@ -18,7 +20,7 @@ public FindPatientCommand(String command){ } @Override - public void execute(TaskList tasks, PatientList patientList, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + public void execute(PatientTaskList patientTask, TaskList tasks, PatientList patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { char firstChar = command.charAt(0); if (firstChar == '#'){ int id; diff --git a/src/main/java/duke/command/HelpCommand.java b/src/main/java/duke/command/HelpCommand.java index cdd644b78c..a3d13c72ea 100644 --- a/src/main/java/duke/command/HelpCommand.java +++ b/src/main/java/duke/command/HelpCommand.java @@ -3,15 +3,16 @@ import duke.core.DukeException; import duke.patient.PatientList; import duke.storage.PatientStorage; -import duke.storage.Storage; +import duke.storage.PatientTaskStorage; import duke.storage.TaskStorage; +import duke.relation.PatientTaskList; import duke.task.TaskList; import duke.core.Ui; public class HelpCommand extends Command { @Override - public void execute(TaskList tasks, PatientList patientList, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + public void execute(PatientTaskList patientTask, TaskList tasks, PatientList patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { ui.showHelpCommand(); } diff --git a/src/main/java/duke/command/ListPatientsCommand.java b/src/main/java/duke/command/ListPatientsCommand.java index a090f409c9..3d65b83953 100644 --- a/src/main/java/duke/command/ListPatientsCommand.java +++ b/src/main/java/duke/command/ListPatientsCommand.java @@ -5,7 +5,9 @@ import duke.patient.Patient; import duke.patient.PatientList; import duke.storage.PatientStorage; +import duke.storage.PatientTaskStorage; import duke.storage.TaskStorage; +import duke.relation.PatientTaskList; import duke.task.TaskList; import java.util.ArrayList; @@ -17,7 +19,7 @@ public ListPatientsCommand() { } @Override - public void execute(TaskList tasks, PatientList patientList, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + public void execute(PatientTaskList patientTask, TaskList tasks, PatientList patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { ArrayList list = patientList.getPatientList(); ui.listAllPatients(list); } diff --git a/src/main/java/duke/command/ListTasksCommand.java b/src/main/java/duke/command/ListTasksCommand.java index d4f6ba9dee..e5ed3cc8b2 100644 --- a/src/main/java/duke/command/ListTasksCommand.java +++ b/src/main/java/duke/command/ListTasksCommand.java @@ -4,7 +4,9 @@ import duke.core.Ui; import duke.patient.PatientList; import duke.storage.PatientStorage; +import duke.storage.PatientTaskStorage; import duke.storage.TaskStorage; +import duke.relation.PatientTaskList; import duke.task.Task; import duke.task.TaskList; @@ -12,7 +14,7 @@ public class ListTasksCommand extends Command { @Override - public void execute(TaskList tasks, PatientList patientList, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + public void execute(PatientTaskList patientTask, TaskList tasks, PatientList patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { ArrayList list = tasks.getTaskList(); ui.listAllTasks(list); } diff --git a/src/main/java/duke/command/UpdatePatientCommand.java b/src/main/java/duke/command/UpdatePatientCommand.java index a816f4dcf0..6677856ba4 100644 --- a/src/main/java/duke/command/UpdatePatientCommand.java +++ b/src/main/java/duke/command/UpdatePatientCommand.java @@ -5,7 +5,9 @@ import duke.patient.Patient; import duke.patient.PatientList; import duke.storage.PatientStorage; +import duke.storage.PatientTaskStorage; import duke.storage.TaskStorage; +import duke.relation.PatientTaskList; import duke.task.TaskList; public class UpdatePatientCommand extends Command { @@ -22,7 +24,7 @@ public UpdatePatientCommand(int Id , String targetInfo , String updatedValue) { } @Override - public void execute(TaskList tasks, PatientList patientList, Ui ui, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + public void execute(PatientTaskList patientTask, TaskList tasks, PatientList patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { Patient targetPatient = patientList.getPatient(Id); if (targetInfo.equals("name")) { targetPatient.setName(updatedValue); diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index c6df9a001a..b24291141a 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -2,6 +2,8 @@ import duke.command.*; import duke.patient.Patient; +import duke.relation.EventPatientTask; +import duke.relation.StandardPatientTask; import duke.task.*; /** @@ -35,10 +37,10 @@ public static Command manageCommand(String userInput) throws DukeException { } else if (tempCommand[0].toLowerCase().equals("task")){ try { - StandardTask task = new StandardTask(command[1].split("\\s+", 2)[1]); + Task task = new Task(command[1]); return new AddStandardTaskCommand(task); }catch(Exception e){ - throw new Exception("Please follow the format 'add task .' "); + throw new Exception("Please follow the format 'add task .' "); } } else { @@ -47,6 +49,34 @@ else if (tempCommand[0].toLowerCase().equals("task")){ } catch (Exception e) { throw new DukeException("Add command fails. " + e.getMessage()); } + case "assign": + try { + String[] tempCommand = command[1].split("\\s+", 5); + + if (tempCommand[0].toLowerCase().equals("byid")) { + if (tempCommand[1].equals("S")) { + + String type = tempCommand[1]; + int patientId = Integer.parseInt(tempCommand[2]); + int taskId = Integer.parseInt(tempCommand[3]); + String deadline = tempCommand[4]; + StandardPatientTask sPatientTask = new StandardPatientTask(patientId, taskId, deadline, type); + return new AssignTaskToPatientCommand(sPatientTask); + } else if (tempCommand[1].equals("E")) { + String type = tempCommand[1]; + int patientId = Integer.parseInt(tempCommand[2]); + int taskId = Integer.parseInt(tempCommand[3]); + String sTime = tempCommand[4].split(" /to ", 2)[0]; + String eTime = tempCommand[4].split(" /to ", 2)[1]; + EventPatientTask ePatientTask = new EventPatientTask(patientId, taskId, sTime, eTime, type); + return new AssignTaskToPatientCommand(ePatientTask); + } + } + + } catch (Exception e) { + throw new DukeException("update command fails. " + e.getMessage()); + } + case "list": try { String[] tempCommand = command[1].split("\\s+"); diff --git a/src/main/java/duke/core/DateTimeParser.java b/src/main/java/duke/core/DateTimeParser.java index c6c4993c0a..e5cd432da7 100644 --- a/src/main/java/duke/core/DateTimeParser.java +++ b/src/main/java/duke/core/DateTimeParser.java @@ -54,4 +54,21 @@ public static String convertToEnglishDateTime(String timeBeforeFormat) throws Du throw e; } } + + public static String convertToEnglishDateTimeBeforeParse(LocalDateTime localDateTime) { + DateTimeFormatter stFormatter = DateTimeFormatter.ofPattern("d'st of' MMMM yyyy, ha"); + DateTimeFormatter ndFormatter = DateTimeFormatter.ofPattern("d'nd of' MMMM yyyy, ha"); + DateTimeFormatter rdFormatter = DateTimeFormatter.ofPattern("d'rd of' MMMM yyyy, ha"); + DateTimeFormatter thFormatter = DateTimeFormatter.ofPattern("d'th of' MMMM yyyy, ha"); + + if ((localDateTime.getDayOfMonth() % 10) == 1) { + return localDateTime.format(stFormatter); + } else if ((localDateTime.getDayOfMonth() % 10) == 2) { + return localDateTime.format(ndFormatter); + } else if ((localDateTime.getDayOfMonth() % 10) == 3) { + return localDateTime.format(rdFormatter); + } else { + return localDateTime.format(thFormatter); + } + } } diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index 025d92cbe3..e6cbf61a2f 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -1,8 +1,7 @@ package duke.core; import duke.patient.Patient; -import duke.patient.PatientList; -import duke.task.StandardTask; +import duke.relation.PatientTask; import duke.task.Task; import java.util.ArrayList; @@ -47,13 +46,8 @@ public void showError(String e) { System.out.println("☹" + e); } - /** - * Shows that a Task has been added - * - * @param t The Task that is added to the list. - */ - public void taskAdded(StandardTask standardTask) { - System.out.println("Got it. I've added this task: \n" + standardTask); + public void taskAdded(Task standardTask) { + System.out.println("Got it. I've added this task: \n" + standardTask.getDescription()); } public void showPatientInfo(Patient patient) { @@ -88,6 +82,10 @@ public void patientAdded(Patient patient) { showPatientInfo(patient); } + public void patientTaskAssigned(PatientTask patientTask, String patientName, String taskName) { + System.out.println("Got it. The following Patient ID: " + patientTask.getTaskID() + " " + patientName + " has been assigned the Task ID: " + patientTask.getPatientId() + " " + taskName); + } + public int choosePatientToDelete(int numberOfPatients) { int chosenNumber = -1; while (true) { @@ -144,22 +142,12 @@ public void listAllTasks(ArrayList taskList) { for (Task task : taskList) { System.out.println(index + ". " - + "[" + task.getStatusIcon() + "] " + task.getDescription() - + formatTaskDateTime(task) + "\n"); index++; } } - public String formatTaskDateTime(Task task) { - if (task.getDateTime().equals("")) { - return ""; - } else { - return " at " + task.getDateTime(); - } - } - /** * Shows that a Task has been marked as done. diff --git a/src/main/java/duke/patient/PatientList.java b/src/main/java/duke/patient/PatientList.java index e07095a38d..9514011429 100644 --- a/src/main/java/duke/patient/PatientList.java +++ b/src/main/java/duke/patient/PatientList.java @@ -22,6 +22,15 @@ public PatientList(ArrayList patientList) { } } + public boolean isExist(int id) { + if (patientIdMap.containsKey(id)){ + return true; + } + else{ + return false; + } + } + public Patient getPatient(int id) throws DukeException { if (patientIdMap.containsKey(id)){ return patientIdMap.get(id); diff --git a/src/main/java/duke/relation/EventPatientTask.java b/src/main/java/duke/relation/EventPatientTask.java new file mode 100644 index 0000000000..54d3a21e93 --- /dev/null +++ b/src/main/java/duke/relation/EventPatientTask.java @@ -0,0 +1,80 @@ +package duke.relation; + +import java.time.Duration; +import java.time.LocalDateTime; +import duke.core.DateTimeParser; +import duke.core.DukeException; +import duke.relation.PatientTask; + +public class EventPatientTask extends PatientTask { + + private LocalDateTime startTime; + private LocalDateTime endTime; + private String startTimeRaw; + private String endTimeRaw; + private long duration; + + public EventPatientTask(int pid, int tid, String stime, String eTime, String type){ + super(pid, tid, type); + this.startTimeRaw = stime; + this.endTimeRaw = eTime; + try{ + this.startTime = DateTimeParser.convertToLocalDateTime(stime); + this.endTime = DateTimeParser.convertToLocalDateTime(eTime); + } + catch (DukeException e) { + System.out.println(e.getMessage()); + } + + duration = Duration.between(startTime, endTime).toMillis(); + } + + public EventPatientTask(int pid, int tid, boolean isdone, boolean isrecurrsive, String stime, String eTime, String type){ + super(pid, tid, isdone, isrecurrsive,type); + this.startTimeRaw = stime; + this.endTimeRaw = eTime; + try{ + this.startTime = DateTimeParser.convertToLocalDateTime(stime); + this.endTime = DateTimeParser.convertToLocalDateTime(eTime); + } + catch (DukeException e) { + System.out.println(e.getMessage()); + } + + duration = Duration.between(startTime, endTime).toMillis(); + } + + public String getStartTimeRaw(){ + return startTimeRaw; + } + + public String getEndTimeRaw(){ + return endTimeRaw; + } + public void updateStartTime(String time){ + try{ + this.startTime = DateTimeParser.convertToLocalDateTime(time); + } + catch (DukeException e) { + System.out.println(e.getMessage()); + } + } + + public void updateEndTime(String time){ + try{ + this.endTime = DateTimeParser.convertToLocalDateTime(time); + } + catch (DukeException e) { + System.out.println(e.getMessage()); + } + } + + public long retrieveDuration() + { + return this.duration; + } + public String toString(){ + return super.printStatus() + " From " + DateTimeParser.convertToEnglishDateTimeBeforeParse(startTime) + "To" + DateTimeParser.convertToEnglishDateTimeBeforeParse(endTime); + } + +} \ No newline at end of file diff --git a/src/main/java/duke/relation/PatientTask.java b/src/main/java/duke/relation/PatientTask.java new file mode 100644 index 0000000000..964f7b5213 --- /dev/null +++ b/src/main/java/duke/relation/PatientTask.java @@ -0,0 +1,77 @@ +package duke.relation; + +public abstract class PatientTask { + private Integer patientId; + private Integer taskID; + private boolean isDone = false; + private boolean isRecurrsive = false; + private String taskType; + + public PatientTask(int pid, int tid, String type) { + this.patientId = pid; + this.taskID = tid; + this.taskType = type; + } + + public PatientTask(int pid, int tid, boolean isdone, boolean isrecurrsive, String type) { + this.patientId = pid; + this.taskID = tid; + this.taskType = type; + this.isDone = isdone; + this.isRecurrsive = isrecurrsive; + } + + + public Integer getPatientId(){ + return patientId; + } + + public Integer getTaskID(){ + return taskID; + } + + public String getTaskType(){ + return taskType; + } + + public boolean isDone() { + return this.isDone; + } + + public boolean isRecurrsive() { + return isRecurrsive; + } + + public void markDone() {this.isDone = true;} + + public void markRecurr() {this.isRecurrsive = true;} + + public void undoRecurr(){ + this.isRecurrsive = false; + } + + public void undoIsDone(){ + this.isDone = false; + } + + public void updateId(int pid, int tid){ + this.patientId = pid; + this.taskID = tid; + } + + public String getStatusIcon() { + return (isDone ? "\u2713" : "\u2718"); + } + + public String getRecurrsiveIcon(){ + return (isRecurrsive ? "\u0298" : "\u0275"); + } + + public String printStatus() { + return "[" + this.getStatusIcon() + "] " + "[" + this.getRecurrsiveIcon() + "] "; + } + + public abstract String toString(); + + +} diff --git a/src/main/java/duke/relation/PatientTaskList.java b/src/main/java/duke/relation/PatientTaskList.java new file mode 100644 index 0000000000..1aaab640d4 --- /dev/null +++ b/src/main/java/duke/relation/PatientTaskList.java @@ -0,0 +1,85 @@ +package duke.relation; + +import duke.core.DukeException; + +import java.util.ArrayList; +import com.google.common.collect.Multimap; +import com.google.common.collect.ArrayListMultimap; +import duke.relation.PatientTask; + +/** + * Represents a list of Task that can perform operations such as + * add and delete on the tasks. + */ +public class PatientTaskList { + /** + * An ArrayList structure. + */ + private Multimap patientTaskIdMap = ArrayListMultimap.create(); + + public PatientTaskList(ArrayList newPatientTaskList) { + for (PatientTask patientTasK : newPatientTaskList) { + patientTaskIdMap.put(patientTasK.getPatientId(), patientTasK); + } + } + + public ArrayList fullPatientTaskList() { + return new ArrayList(patientTaskIdMap.values()); + } + + public void addPatientTask(PatientTask t) { + patientTaskIdMap.put(t.getPatientId(), t); + } + + public void deletePatientTask(Integer pid, Integer tid) throws DukeException { + + if (patientTaskIdMap.containsKey(pid)) { + for (PatientTask patientTask : patientTaskIdMap.get(pid)) { + if (patientTask.getTaskID().equals(tid)) { + patientTaskIdMap.remove(pid, patientTask); + } else { + throw new DukeException("The patient with id: " + pid + " has not been assigned with such task: " + tid); + } + } + } else { + throw new DukeException("Patient id: " + pid + " does not have any tasks!"); + } + } + + public void deleteEntirePatientTask(Integer pid) throws DukeException { + if (patientTaskIdMap.containsKey(pid)) { + patientTaskIdMap.removeAll(pid); + } else { + throw new DukeException("Patient id: " + pid + " does not have any tasks!"); + } + } + + public ArrayList getPatientTask(int pid) throws DukeException { + if (patientTaskIdMap.containsKey(pid)) { + ArrayList tempArray = new ArrayList(); + tempArray.addAll(patientTaskIdMap.get(pid)); + return tempArray; + } else { + throw new DukeException("The patient with id " + pid + " does not have any tasks."); + } + } + + public ArrayList getTaskPatient(int tid) throws DukeException { + ArrayList tempArray = new ArrayList(); + for (PatientTask patientTask : patientTaskIdMap.values()) { + if (patientTask.getTaskID() == tid) { + tempArray.add(patientTask); + } + } + if (tempArray.size() != 0){ + return tempArray; + } + else { + throw new DukeException("The Task with id " + tid + " has not been assigned to any patients"); + } + + } + + + +} diff --git a/src/main/java/duke/storage/PatientStorage.java b/src/main/java/duke/storage/PatientStorage.java index 84b63ed35c..93ed619064 100644 --- a/src/main/java/duke/storage/PatientStorage.java +++ b/src/main/java/duke/storage/PatientStorage.java @@ -11,7 +11,7 @@ import java.nio.file.Paths; import java.util.ArrayList; -public class PatientStorage extends Storage { +public class PatientStorage { /** * A string that represents a relative file path from the project folder. @@ -48,7 +48,6 @@ public ArrayList load() throws DukeException { } } - @Override public void save(ArrayList patients) throws DukeException { try { BufferedWriter writer = Files.newBufferedWriter(Paths.get(filePath)); diff --git a/src/main/java/duke/storage/PatientTaskStorage.java b/src/main/java/duke/storage/PatientTaskStorage.java new file mode 100644 index 0000000000..ee8aeb43b0 --- /dev/null +++ b/src/main/java/duke/storage/PatientTaskStorage.java @@ -0,0 +1,90 @@ +package duke.storage; + +import duke.core.DukeException; +import duke.relation.EventPatientTask; +import duke.relation.PatientTask; +import duke.relation.StandardPatientTask; +import org.apache.commons.csv.CSVFormat; +import org.apache.commons.csv.CSVPrinter; +import org.apache.commons.csv.CSVRecord; + +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; + +public class PatientTaskStorage { + + /** + * A string that represents a relative file path from the project folder. + */ + private String filePath; + + /** + * Constructs a Storage object with a specific file path. + * + * @param filePath A string that represents the path of the file to read or + * write. + */ + public PatientTaskStorage(String filePath) { + this.filePath = filePath; + } + + public ArrayList load() throws DukeException { + ArrayList patientTaskList = new ArrayList(); + try { + Reader in = new FileReader(filePath); + Iterable records = CSVFormat.EXCEL.withFirstRecordAsHeader().parse(in); + for (CSVRecord record : records) { + int pid = Integer.parseInt(record.get("PID")); + int tid = Integer.parseInt(record.get("TID")); + boolean isDone = Boolean.parseBoolean(record.get("DONE")); + boolean isRecursive = Boolean.parseBoolean(record.get("RECURRENCE")); + String deadline = record.get("DEADLINE"); + String startTime = record.get("STARTTIME"); + String endTime = record.get("ENDTIME"); + String taskType = record.get("TASKTYPE"); + if (taskType.equals("S")){ + patientTaskList.add(new StandardPatientTask(pid,tid,isDone,isRecursive,deadline,taskType)); + } + else if (taskType.equals("E")){ + patientTaskList.add(new EventPatientTask(pid,tid,isDone,isRecursive,startTime,endTime,taskType)); + } + } + return patientTaskList; + } catch (IOException e) { + throw new DukeException(e.getMessage()); + } + } + + public void save(ArrayList patientTask) throws DukeException { + try { + BufferedWriter writer = Files.newBufferedWriter(Paths.get(filePath)); + CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT + .withHeader("PID", "TID", "DONE", "RECURRENCE", "DEADLINE", "STARTTIME", "ENDTIME", "TASKTYPE" )); + for (PatientTask patient : patientTask) { + int pid = patient.getPatientId(); + int tid = patient.getTaskID(); + boolean isDone = patient.isDone(); + boolean isRecurr = patient.isRecurrsive(); + String deadline = null; + String startTime = null; + String endTime = null; + String type = patient.getTaskType(); + if (patient instanceof StandardPatientTask) + { + deadline = ((StandardPatientTask) patient).getDeadline(); + } + else if (patient instanceof EventPatientTask) + { + startTime = ((EventPatientTask) patient).getStartTimeRaw(); + endTime = ((EventPatientTask) patient).getEndTimeRaw(); + } + csvPrinter.printRecord(pid, tid, String.valueOf(isDone), String.valueOf(isRecurr), deadline, startTime,endTime,type); + } + csvPrinter.flush(); + } catch (IOException e) { + throw new DukeException(e.getMessage()); + } + } +} diff --git a/src/main/java/duke/storage/Storage.java b/src/main/java/duke/storage/Storage.java deleted file mode 100644 index c7361d01b5..0000000000 --- a/src/main/java/duke/storage/Storage.java +++ /dev/null @@ -1,17 +0,0 @@ -package duke.storage; - -import duke.core.DukeException; - -import java.util.ArrayList; - -/** - * Represents a Storage class that deals with reading tasks from - * a file and saving tasks in the file. - */ -public abstract class Storage { - - public abstract ArrayList load() throws DukeException; - - public abstract void save(ArrayList list) throws DukeException; - -} diff --git a/src/main/java/duke/storage/TaskStorage.java b/src/main/java/duke/storage/TaskStorage.java index e4a6f5b68a..390671a2c7 100644 --- a/src/main/java/duke/storage/TaskStorage.java +++ b/src/main/java/duke/storage/TaskStorage.java @@ -1,7 +1,6 @@ package duke.storage; import duke.core.DukeException; -import duke.task.StandardTask; import duke.task.Task; import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVPrinter; @@ -12,7 +11,7 @@ import java.nio.file.Paths; import java.util.ArrayList; -public class TaskStorage extends Storage{ +public class TaskStorage { /** * A string that represents a relative file path from the project folder. @@ -43,8 +42,7 @@ public ArrayList load() throws DukeException { Iterable records = CSVFormat.EXCEL.withFirstRecordAsHeader().parse(in); for (CSVRecord record : records) { String description = record.get("Description"); - taskList.add(new StandardTask(description)); - System.out.println(description + " | " + description); + taskList.add(new Task(description)); } return taskList; } catch (IOException e) { @@ -59,13 +57,11 @@ public ArrayList load() throws DukeException { * @param tasks The TaskList storing tasks. * @throws DukeException If writing to the local file failed. */ - @Override public void save(ArrayList tasks) throws DukeException { try{ BufferedWriter writer = Files.newBufferedWriter(Paths.get(filePath)); CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT .withHeader("Description")); -// ArrayList tasks = taskList.getTaskList(); for (Task task : tasks){ String description = task.getDescription(); csvPrinter.printRecord(description); diff --git a/src/main/java/duke/task/PersonalTask.java b/src/main/java/duke/task/PersonalTask.java deleted file mode 100644 index fdb56d6072..0000000000 --- a/src/main/java/duke/task/PersonalTask.java +++ /dev/null @@ -1,17 +0,0 @@ -package duke.task; - -public class PersonalTask extends Task { - - //private patient Patient; - - public PersonalTask(String description) { //2nd parameter: Patient - super(description); - //this.patient = patient; - } - - @Override - public String toString() { - return null; - } - -} \ No newline at end of file diff --git a/src/main/java/duke/task/StandardTask.java b/src/main/java/duke/task/StandardTask.java deleted file mode 100644 index e2ae585308..0000000000 --- a/src/main/java/duke/task/StandardTask.java +++ /dev/null @@ -1,20 +0,0 @@ -package duke.task; - -import java.util.ArrayList; - -public class StandardTask extends Task { - - ArrayList patientIdList; - - public StandardTask(String description) { - super(description); - this.patientIdList = new ArrayList(); //read doc + upload task's list of patients, or make new list - } - - @Override - public String toString() { - return this.getDescription(); - } - - -} diff --git a/src/main/java/duke/task/Task.java b/src/main/java/duke/task/Task.java index 7aa2415ce2..4a1253b5be 100644 --- a/src/main/java/duke/task/Task.java +++ b/src/main/java/duke/task/Task.java @@ -1,91 +1,24 @@ package duke.task; -import java.util.ArrayList; - /** * Represents a task. Task is an abstract class that can not be * instantiated */ -public abstract class Task { +public class Task { - /** - * A String that represents the description of the task. - */ private String description; - /** - * A boolean that represents the status of the task( 1 means done, 0 means not yet). - */ - private boolean isDone; - - /** - * A string to describe the date/time of the task. - */ - private String dateTime = ""; - - /** - * An arraylist of things the nurse can bring for the task. - */ - private ArrayList thingsToBring; - - /** - * Initialises the minimum fields required to setup a Task. - * - * @param description A string that represents the description of certain task. - */ - public Task(String description, String dateTime) { - this.description = description; - this.isDone = false; - this.thingsToBring = new ArrayList(); - this.dateTime = dateTime; - } - public Task(String description) { this.description = description; - this.thingsToBring = new ArrayList(); - this.isDone = false; - } - - /** - * Returns an icon that represents the status of the task. - * - * @return Tick if completed, cross if uncompleted. - */ - public String getStatusIcon() { - return (isDone ? "\u2713" : "\u2718"); //return tick or X symbols - } - - /** - * Check if the task isDone. - * - * @return boolean value of isDone - */ - public boolean isDone() { - return this.isDone; } - - /** - * Marks the task as done. - */ - public void markAsDone() { - isDone = true; - } - -// /** -// * Returns a string with the following format to be stored in a local file. -// * -// * @return A string in a specific format to be stored in a local file. -// */ -// public abstract String writeTxt(); - /** * Returns a string with the status icon and the description of the task. * * @return A string in a specific format with the status and description of the task. */ - public String printStatus() { - return "[" + this.getStatusIcon() + "] " + description; + public String printDescription() { + return " " + description + " "; } /** @@ -99,23 +32,5 @@ public String getDescription() { return description; } - /** - * update the dateTime String to save the date and time. - * @param newDateTime the time retrieved from user input. - */ - - public void updateDateTime(String newDateTime) { - this.dateTime = newDateTime; - } - - /** - * Returns the dateTime String. - */ - - public String getDateTime() { - return dateTime; - } - - public abstract String toString(); } \ No newline at end of file diff --git a/src/main/java/duke/task/TaskList.java b/src/main/java/duke/task/TaskList.java index e48e6f9cab..8cd1df41df 100644 --- a/src/main/java/duke/task/TaskList.java +++ b/src/main/java/duke/task/TaskList.java @@ -58,6 +58,15 @@ public void deleteTask(Integer i) throws DukeException { taskList.remove(i - 1); } + public boolean isExist(Integer i) { + if (getSize() >= i) { + return true; + } + else { + return false; + } + } + /** * Returns the Task in the list with the given index. * From f7c7f863edc70efcd20e3856741162bba5a9e650 Mon Sep 17 00:00:00 2001 From: wei feng Date: Fri, 11 Oct 2019 20:50:41 +0800 Subject: [PATCH 108/420] Moved the abstract PatientTask and its inheritance into a new package call relation --- .../duke/relation/StandardPatientTask.java | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 src/main/java/duke/relation/StandardPatientTask.java diff --git a/src/main/java/duke/relation/StandardPatientTask.java b/src/main/java/duke/relation/StandardPatientTask.java new file mode 100644 index 0000000000..56de4cb02f --- /dev/null +++ b/src/main/java/duke/relation/StandardPatientTask.java @@ -0,0 +1,53 @@ +package duke.relation; + +import java.time.LocalDateTime; +import duke.core.DateTimeParser; +import duke.core.DukeException; +import duke.relation.PatientTask; + +public class StandardPatientTask extends PatientTask { + + private LocalDateTime deadline; + private String deadlineRaw; + + public StandardPatientTask(int pid, int tid, String timeBeforeFormat, String type){ + super(pid, tid, type); + this.deadlineRaw = timeBeforeFormat; + try{ + this.deadline = DateTimeParser.convertToLocalDateTime(timeBeforeFormat); + } + catch (DukeException e) { + System.out.println(e.getMessage()); + } + } + + public StandardPatientTask(int pid, int tid, boolean isdone, boolean isrecurrsive, String timeBeforeFormat, String type){ + super(pid, tid, isdone, isrecurrsive,type); + this.deadlineRaw = timeBeforeFormat; + try{ + this.deadline = DateTimeParser.convertToLocalDateTime(timeBeforeFormat); + } + catch (DukeException e) { + System.out.println(e.getMessage()); + } + } + + public String getDeadline(){ + return this.deadlineRaw; + } + + + public void updateDeadline(String time){ + try{ + this.deadline = DateTimeParser.convertToLocalDateTime(time); + } + catch (DukeException e) { + System.out.println(e.getMessage()); + } + } + + public String toString(){ + return super.printStatus() + " " + DateTimeParser.convertToEnglishDateTimeBeforeParse(deadline); + } + +} From 2aceec53b8a06d209606c4a36166e2d574ed6a72 Mon Sep 17 00:00:00 2001 From: wei feng Date: Fri, 11 Oct 2019 21:40:11 +0800 Subject: [PATCH 109/420] Fixed the problem that the CSV file to store data is corrupted --- data/patientsTasks.csv | 14 +++----------- src/main/java/duke/core/CommandManager.java | 2 -- src/main/java/duke/storage/PatientTaskStorage.java | 4 ++-- 3 files changed, 5 insertions(+), 15 deletions(-) diff --git a/data/patientsTasks.csv b/data/patientsTasks.csv index 7d01f29a9f..5ded8c8596 100644 --- a/data/patientsTasks.csv +++ b/data/patientsTasks.csv @@ -1,12 +1,4 @@ PID,TID,DONE,RECURRENCE,DEADLINE,STARTTIME,ENDTIME,TASKTYPE -1,3,false,false,09/11/2019 1400,,,S -1,3,false,false,09/11/2019 1400,,,S -1,3,false,false,09/11/2019 1400,,,S -1,3,false,false,09/11/2019 1400,,,S -1,3,false,false,09/11/2019 1400,,,S -1,3,false,false,,21/01/2019 1400,12/05/2020 1500,E -1,3,false,false,,21/01/2019 1400,12/05/2020 1500,E -1,3,false,false,,21/01/2019 1400,12/05/2020 1500,E -2,4,false,false,09/11/2019 1050,,,S - - +1,2,false,false,09/11/2019 1400,,,S +1,3,false,false,09/01/2018 1200,,,S +2,7,false,false,,09/01/2019 1200,08/11/2019 1000,E diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index b24291141a..29532c93b6 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -52,10 +52,8 @@ else if (tempCommand[0].toLowerCase().equals("task")){ case "assign": try { String[] tempCommand = command[1].split("\\s+", 5); - if (tempCommand[0].toLowerCase().equals("byid")) { if (tempCommand[1].equals("S")) { - String type = tempCommand[1]; int patientId = Integer.parseInt(tempCommand[2]); int taskId = Integer.parseInt(tempCommand[3]); diff --git a/src/main/java/duke/storage/PatientTaskStorage.java b/src/main/java/duke/storage/PatientTaskStorage.java index ee8aeb43b0..89315f276f 100644 --- a/src/main/java/duke/storage/PatientTaskStorage.java +++ b/src/main/java/duke/storage/PatientTaskStorage.java @@ -36,8 +36,8 @@ public ArrayList load() throws DukeException { Reader in = new FileReader(filePath); Iterable records = CSVFormat.EXCEL.withFirstRecordAsHeader().parse(in); for (CSVRecord record : records) { - int pid = Integer.parseInt(record.get("PID")); - int tid = Integer.parseInt(record.get("TID")); + Integer pid = Integer.parseInt(record.get("PID")); + Integer tid = Integer.parseInt(record.get("TID")); boolean isDone = Boolean.parseBoolean(record.get("DONE")); boolean isRecursive = Boolean.parseBoolean(record.get("RECURRENCE")); String deadline = record.get("DEADLINE"); From a36e2b010195598cc1e0a07b8a0c4392f0a3d5b0 Mon Sep 17 00:00:00 2001 From: wei feng Date: Mon, 14 Oct 2019 00:01:03 +0800 Subject: [PATCH 110/420] Fixed a minor bug on the ui display of our assign task function. Standardised the format of the Parser , we move all the extra parsing part from the Command manager to the individual command instead of pile up everything in Command Manager. Do take a look of the AssignTaskToPatient Class --- data/patientsTasks.csv | 2 ++ .../command/AssignTaskToPatientCommand.java | 30 +++++++++++++++++-- src/main/java/duke/core/CommandManager.java | 19 ++---------- src/main/java/duke/core/Ui.java | 2 +- 4 files changed, 33 insertions(+), 20 deletions(-) diff --git a/data/patientsTasks.csv b/data/patientsTasks.csv index 3d85e97eef..4698659ae6 100644 --- a/data/patientsTasks.csv +++ b/data/patientsTasks.csv @@ -2,4 +2,6 @@ PID,TID,DONE,RECURRENCE,DEADLINE,STARTTIME,ENDTIME,TASKTYPE 1,2,false,false,09/11/2019 1400,,,S 1,3,false,false,09/01/2018 1200,,,S 1,3,false,false,04/04/2019 1400,,,S +1,4,false,false,01/09/2019 1400,,,S +1,4,false,false,04/11/2019 1500,,,S 2,7,false,false,,09/01/2019 1200,08/11/2019 1000,E diff --git a/src/main/java/duke/command/AssignTaskToPatientCommand.java b/src/main/java/duke/command/AssignTaskToPatientCommand.java index 97b8a0f700..8b46b1a084 100644 --- a/src/main/java/duke/command/AssignTaskToPatientCommand.java +++ b/src/main/java/duke/command/AssignTaskToPatientCommand.java @@ -3,6 +3,8 @@ import duke.core.DukeException; import duke.core.Ui; import duke.patient.PatientManager; +import duke.relation.EventPatientTask; +import duke.relation.StandardPatientTask; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; import duke.storage.TaskStorage; @@ -12,15 +14,17 @@ public class AssignTaskToPatientCommand extends Command { + private String command; private PatientTask newPatientTask; - public AssignTaskToPatientCommand(PatientTask patientTask) { + public AssignTaskToPatientCommand(String cmd) { super(); - this.newPatientTask = patientTask; + this.command = cmd; } @Override public void execute(PatientTaskList patientTaskList, TaskManager tasksList, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + this.newPatientTask = finalPatientTask(command); if (patientList.isExist(newPatientTask.getPatientId()) && tasksList.isExist(newPatientTask.getTaskID())) { patientTaskList.addPatientTask(newPatientTask); @@ -34,6 +38,28 @@ public void execute(PatientTaskList patientTaskList, TaskManager tasksList, Pati } + public PatientTask finalPatientTask(String cmd) throws DukeException { + String[] tempCommand = command.split("\\s+",4 ); + if (tempCommand[0].equals("S")) { + String type = tempCommand[0]; + int patientId = Integer.parseInt(tempCommand[1]); + int taskId = Integer.parseInt(tempCommand[2]); + String deadline = tempCommand[3]; + StandardPatientTask sPatientTask = new StandardPatientTask(patientId, taskId, deadline, type); + return sPatientTask; + } else if (tempCommand[0].equals("E")) { + String type = tempCommand[0]; + int patientId = Integer.parseInt(tempCommand[1]); + int taskId = Integer.parseInt(tempCommand[2]); + String sTime = tempCommand[3].split(" /to ", 2)[0]; + String eTime = tempCommand[3].split(" /to ", 2)[1]; + EventPatientTask ePatientTask = new EventPatientTask(patientId, taskId, sTime, eTime, type); + return ePatientTask; + } + else{ + throw new DukeException("Parsing failed! Please ensure the format you have entered is correct!"); + } + } @Override public boolean isExit() { return false; diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 20bb91d0d5..744da1b903 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -51,24 +51,9 @@ else if (tempCommand[0].toLowerCase().equals("task")){ } case "assign": try { - String[] tempCommand = command[1].split("\\s+", 5); + String[] tempCommand = command[1].split("\\s+", 2); if (tempCommand[0].toLowerCase().equals("byid")) { - if (tempCommand[1].equals("S")) { - String type = tempCommand[1]; - int patientId = Integer.parseInt(tempCommand[2]); - int taskId = Integer.parseInt(tempCommand[3]); - String deadline = tempCommand[4]; - StandardPatientTask sPatientTask = new StandardPatientTask(patientId, taskId, deadline, type); - return new AssignTaskToPatientCommand(sPatientTask); - } else if (tempCommand[1].equals("E")) { - String type = tempCommand[1]; - int patientId = Integer.parseInt(tempCommand[2]); - int taskId = Integer.parseInt(tempCommand[3]); - String sTime = tempCommand[4].split(" /to ", 2)[0]; - String eTime = tempCommand[4].split(" /to ", 2)[1]; - EventPatientTask ePatientTask = new EventPatientTask(patientId, taskId, sTime, eTime, type); - return new AssignTaskToPatientCommand(ePatientTask); - } + return new AssignTaskToPatientCommand(tempCommand[1]); } } catch (Exception e) { diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index e554a6dd7b..5005d60262 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -82,7 +82,7 @@ public void patientAdded(Patient patient) { } public void patientTaskAssigned(PatientTask patientTask, String patientName, String taskName) { - System.out.println("Got it. The following Patient ID: " + patientTask.getTaskID() + " " + patientName + " has been assigned the Task ID: " + patientTask.getPatientId() + " " + taskName); + System.out.println("Got it. The following Patient ID: " + patientTask.getPatientId() + " " + patientName + " has been assigned the Task ID: " + patientTask.getTaskID() + " " + taskName); } public int choosePatientToDelete(int numberOfPatients) { From 9a8b5369254843a86eee59a806429c046e004c10 Mon Sep 17 00:00:00 2001 From: wei feng Date: Mon, 14 Oct 2019 00:07:29 +0800 Subject: [PATCH 111/420] Revert "Fixed a minor bug on the ui display of our assign task function." This reverts commit a36e2b010195598cc1e0a07b8a0c4392f0a3d5b0. --- data/patientsTasks.csv | 2 -- .../command/AssignTaskToPatientCommand.java | 30 ++----------------- src/main/java/duke/core/CommandManager.java | 19 ++++++++++-- src/main/java/duke/core/Ui.java | 2 +- 4 files changed, 20 insertions(+), 33 deletions(-) diff --git a/data/patientsTasks.csv b/data/patientsTasks.csv index 4698659ae6..3d85e97eef 100644 --- a/data/patientsTasks.csv +++ b/data/patientsTasks.csv @@ -2,6 +2,4 @@ PID,TID,DONE,RECURRENCE,DEADLINE,STARTTIME,ENDTIME,TASKTYPE 1,2,false,false,09/11/2019 1400,,,S 1,3,false,false,09/01/2018 1200,,,S 1,3,false,false,04/04/2019 1400,,,S -1,4,false,false,01/09/2019 1400,,,S -1,4,false,false,04/11/2019 1500,,,S 2,7,false,false,,09/01/2019 1200,08/11/2019 1000,E diff --git a/src/main/java/duke/command/AssignTaskToPatientCommand.java b/src/main/java/duke/command/AssignTaskToPatientCommand.java index 8b46b1a084..97b8a0f700 100644 --- a/src/main/java/duke/command/AssignTaskToPatientCommand.java +++ b/src/main/java/duke/command/AssignTaskToPatientCommand.java @@ -3,8 +3,6 @@ import duke.core.DukeException; import duke.core.Ui; import duke.patient.PatientManager; -import duke.relation.EventPatientTask; -import duke.relation.StandardPatientTask; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; import duke.storage.TaskStorage; @@ -14,17 +12,15 @@ public class AssignTaskToPatientCommand extends Command { - private String command; private PatientTask newPatientTask; - public AssignTaskToPatientCommand(String cmd) { + public AssignTaskToPatientCommand(PatientTask patientTask) { super(); - this.command = cmd; + this.newPatientTask = patientTask; } @Override public void execute(PatientTaskList patientTaskList, TaskManager tasksList, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { - this.newPatientTask = finalPatientTask(command); if (patientList.isExist(newPatientTask.getPatientId()) && tasksList.isExist(newPatientTask.getTaskID())) { patientTaskList.addPatientTask(newPatientTask); @@ -38,28 +34,6 @@ public void execute(PatientTaskList patientTaskList, TaskManager tasksList, Pati } - public PatientTask finalPatientTask(String cmd) throws DukeException { - String[] tempCommand = command.split("\\s+",4 ); - if (tempCommand[0].equals("S")) { - String type = tempCommand[0]; - int patientId = Integer.parseInt(tempCommand[1]); - int taskId = Integer.parseInt(tempCommand[2]); - String deadline = tempCommand[3]; - StandardPatientTask sPatientTask = new StandardPatientTask(patientId, taskId, deadline, type); - return sPatientTask; - } else if (tempCommand[0].equals("E")) { - String type = tempCommand[0]; - int patientId = Integer.parseInt(tempCommand[1]); - int taskId = Integer.parseInt(tempCommand[2]); - String sTime = tempCommand[3].split(" /to ", 2)[0]; - String eTime = tempCommand[3].split(" /to ", 2)[1]; - EventPatientTask ePatientTask = new EventPatientTask(patientId, taskId, sTime, eTime, type); - return ePatientTask; - } - else{ - throw new DukeException("Parsing failed! Please ensure the format you have entered is correct!"); - } - } @Override public boolean isExit() { return false; diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 744da1b903..20bb91d0d5 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -51,9 +51,24 @@ else if (tempCommand[0].toLowerCase().equals("task")){ } case "assign": try { - String[] tempCommand = command[1].split("\\s+", 2); + String[] tempCommand = command[1].split("\\s+", 5); if (tempCommand[0].toLowerCase().equals("byid")) { - return new AssignTaskToPatientCommand(tempCommand[1]); + if (tempCommand[1].equals("S")) { + String type = tempCommand[1]; + int patientId = Integer.parseInt(tempCommand[2]); + int taskId = Integer.parseInt(tempCommand[3]); + String deadline = tempCommand[4]; + StandardPatientTask sPatientTask = new StandardPatientTask(patientId, taskId, deadline, type); + return new AssignTaskToPatientCommand(sPatientTask); + } else if (tempCommand[1].equals("E")) { + String type = tempCommand[1]; + int patientId = Integer.parseInt(tempCommand[2]); + int taskId = Integer.parseInt(tempCommand[3]); + String sTime = tempCommand[4].split(" /to ", 2)[0]; + String eTime = tempCommand[4].split(" /to ", 2)[1]; + EventPatientTask ePatientTask = new EventPatientTask(patientId, taskId, sTime, eTime, type); + return new AssignTaskToPatientCommand(ePatientTask); + } } } catch (Exception e) { diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index 5005d60262..e554a6dd7b 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -82,7 +82,7 @@ public void patientAdded(Patient patient) { } public void patientTaskAssigned(PatientTask patientTask, String patientName, String taskName) { - System.out.println("Got it. The following Patient ID: " + patientTask.getPatientId() + " " + patientName + " has been assigned the Task ID: " + patientTask.getTaskID() + " " + taskName); + System.out.println("Got it. The following Patient ID: " + patientTask.getTaskID() + " " + patientName + " has been assigned the Task ID: " + patientTask.getPatientId() + " " + taskName); } public int choosePatientToDelete(int numberOfPatients) { From 1545abf891bd9347993969d415b9d57e4bb9fa76 Mon Sep 17 00:00:00 2001 From: WEIFENG-NUSCEG Date: Mon, 14 Oct 2019 00:24:12 +0800 Subject: [PATCH 112/420] Standardised the format of the Parser , we move all the extra parsing part from the Command manager to the individual command instead of pile up everything in Command Manager. Do take a look of the AssignTaskToPatient Class --- .../command/AssignTaskToPatientCommand.java | 32 +++++++++++++++++-- src/main/java/duke/core/CommandManager.java | 19 ++--------- src/main/java/duke/core/Ui.java | 3 +- 3 files changed, 33 insertions(+), 21 deletions(-) diff --git a/src/main/java/duke/command/AssignTaskToPatientCommand.java b/src/main/java/duke/command/AssignTaskToPatientCommand.java index 97b8a0f700..ecc0427725 100644 --- a/src/main/java/duke/command/AssignTaskToPatientCommand.java +++ b/src/main/java/duke/command/AssignTaskToPatientCommand.java @@ -3,6 +3,8 @@ import duke.core.DukeException; import duke.core.Ui; import duke.patient.PatientManager; +import duke.relation.EventPatientTask; +import duke.relation.StandardPatientTask; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; import duke.storage.TaskStorage; @@ -12,15 +14,17 @@ public class AssignTaskToPatientCommand extends Command { + private String command; private PatientTask newPatientTask; - public AssignTaskToPatientCommand(PatientTask patientTask) { + public AssignTaskToPatientCommand(String cmd) { super(); - this.newPatientTask = patientTask; + this.command = cmd; } @Override public void execute(PatientTaskList patientTaskList, TaskManager tasksList, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + this.newPatientTask = finalPatientTask(command); if (patientList.isExist(newPatientTask.getPatientId()) && tasksList.isExist(newPatientTask.getTaskID())) { patientTaskList.addPatientTask(newPatientTask); @@ -34,8 +38,30 @@ public void execute(PatientTaskList patientTaskList, TaskManager tasksList, Pati } + public PatientTask finalPatientTask(String cmd) throws DukeException { + String[] tempCommand = command.split("\\s+",4 ); + if (tempCommand[0].equals("S")) { + String type = tempCommand[0]; + int patientId = Integer.parseInt(tempCommand[1]); + int taskId = Integer.parseInt(tempCommand[2]); + String deadline = tempCommand[3]; + StandardPatientTask sPatientTask = new StandardPatientTask(patientId, taskId, deadline, type); + return sPatientTask; + } else if (tempCommand[0].equals("E")) { + String type = tempCommand[0]; + int patientId = Integer.parseInt(tempCommand[1]); + int taskId = Integer.parseInt(tempCommand[2]); + String sTime = tempCommand[3].split(" /to ", 2)[0]; + String eTime = tempCommand[3].split(" /to ", 2)[1]; + EventPatientTask ePatientTask = new EventPatientTask(patientId, taskId, sTime, eTime, type); + return ePatientTask; + } + else{ + throw new DukeException("Parsing failed! Please ensure the format you have entered is correct!"); + } + } @Override public boolean isExit() { return false; } -} +} \ No newline at end of file diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 20bb91d0d5..744da1b903 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -51,24 +51,9 @@ else if (tempCommand[0].toLowerCase().equals("task")){ } case "assign": try { - String[] tempCommand = command[1].split("\\s+", 5); + String[] tempCommand = command[1].split("\\s+", 2); if (tempCommand[0].toLowerCase().equals("byid")) { - if (tempCommand[1].equals("S")) { - String type = tempCommand[1]; - int patientId = Integer.parseInt(tempCommand[2]); - int taskId = Integer.parseInt(tempCommand[3]); - String deadline = tempCommand[4]; - StandardPatientTask sPatientTask = new StandardPatientTask(patientId, taskId, deadline, type); - return new AssignTaskToPatientCommand(sPatientTask); - } else if (tempCommand[1].equals("E")) { - String type = tempCommand[1]; - int patientId = Integer.parseInt(tempCommand[2]); - int taskId = Integer.parseInt(tempCommand[3]); - String sTime = tempCommand[4].split(" /to ", 2)[0]; - String eTime = tempCommand[4].split(" /to ", 2)[1]; - EventPatientTask ePatientTask = new EventPatientTask(patientId, taskId, sTime, eTime, type); - return new AssignTaskToPatientCommand(ePatientTask); - } + return new AssignTaskToPatientCommand(tempCommand[1]); } } catch (Exception e) { diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index e554a6dd7b..7c976cf2a3 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -11,6 +11,7 @@ */ public class Ui { /** + * weifeng * A Scanner to read user input. */ private Scanner scanner; @@ -82,7 +83,7 @@ public void patientAdded(Patient patient) { } public void patientTaskAssigned(PatientTask patientTask, String patientName, String taskName) { - System.out.println("Got it. The following Patient ID: " + patientTask.getTaskID() + " " + patientName + " has been assigned the Task ID: " + patientTask.getPatientId() + " " + taskName); + System.out.println("Got it. The following Patient ID: " + patientTask.getPatientId() + " " + patientName + " has been assigned the Task ID: " + patientTask.getTaskID() + " " + taskName); } public int choosePatientToDelete(int numberOfPatients) { From 6de4d88bec67cf1cef51b6f54831014ec86ce547 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Mon, 14 Oct 2019 13:21:33 +0800 Subject: [PATCH 113/420] Update parsing of keyword for AddPatientCommand in CommandManager --- .../java/duke/command/AddPatientCommand.java | 16 +++++++++++----- src/main/java/duke/core/CommandManager.java | 18 +++++++++--------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/main/java/duke/command/AddPatientCommand.java b/src/main/java/duke/command/AddPatientCommand.java index dcaa1eb585..51d0bebc7b 100644 --- a/src/main/java/duke/command/AddPatientCommand.java +++ b/src/main/java/duke/command/AddPatientCommand.java @@ -11,15 +11,21 @@ import duke.task.TaskManager; public class AddPatientCommand extends Command { - - private Patient newPatient; - public AddPatientCommand(Patient newPatient) { + private String command; + public AddPatientCommand(String command) { super(); - this.newPatient = newPatient; + this.command = command; } @Override - public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage,TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + Patient newPatient; + try { + String commandArr[] = command.split("\\s+", 2)[1].split("\\s+", 4); + newPatient = new Patient(commandArr[0], commandArr[1], commandArr[2], commandArr[3]); + } catch (Exception e) { + throw new DukeException("Please follow the format 'add patient '. "); + } patientList.addPatient(newPatient); patientStorage.save(patientList.getPatientList()); ui.patientAdded(newPatient); diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 20bb91d0d5..66d0e994a4 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -20,23 +20,23 @@ public class CommandManager { */ public static Command manageCommand(String userInput) throws DukeException { userInput = userInput.trim(); - String[] command = userInput.split("\\s+", 2); - String commandType = command[0].toLowerCase(); - switch (commandType) { //change this depending on how string is parsed + String[] command = userInput.split("\\s+", 3); + String firstKeyword = command[0].toLowerCase(); + switch (firstKeyword) { //change this depending on how string is parsed case "add": try { - String[] tempCommand = command[1].split("\\s+"); - if (tempCommand[0].toLowerCase().equals("patient")){ + String secondKeyword = command[1].toLowerCase(); + String commandContent = command[2].trim(); + if (secondKeyword.equals("patient")){ try { - String[] commandContent = command[1].split("\\s+", 2)[1].split("\\s+", 4); - Patient patient = new Patient(commandContent[0], commandContent[1], commandContent[2], commandContent[3]); - return new AddPatientCommand(patient); + return new AddPatientCommand(commandContent); }catch(Exception e){ throw new Exception("Please follow the format 'add patient '. "); } } - else if (tempCommand[0].toLowerCase().equals("task")){ + else if (secondKeyword.equals("task")){ try { + String[] tempCommand = command[1].split("\\s+"); Task task = new Task(command[1]); return new AddStandardTaskCommand(task); }catch(Exception e){ From 1db983141a88d73a0c75b64729657b1d49d30505 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Mon, 14 Oct 2019 13:30:44 +0800 Subject: [PATCH 114/420] Fixed parsing bug in AddPatientCommand --- src/main/java/duke/command/AddPatientCommand.java | 2 +- src/main/java/duke/core/CommandManager.java | 3 +-- src/main/java/duke/relation/PatientTask.java | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/duke/command/AddPatientCommand.java b/src/main/java/duke/command/AddPatientCommand.java index 51d0bebc7b..006dacae44 100644 --- a/src/main/java/duke/command/AddPatientCommand.java +++ b/src/main/java/duke/command/AddPatientCommand.java @@ -21,7 +21,7 @@ public AddPatientCommand(String command) { public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { Patient newPatient; try { - String commandArr[] = command.split("\\s+", 2)[1].split("\\s+", 4); + String commandArr[] = command.split("\\s+", 4); newPatient = new Patient(commandArr[0], commandArr[1], commandArr[2], commandArr[3]); } catch (Exception e) { throw new DukeException("Please follow the format 'add patient '. "); diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index e019cec8b8..19c5f9ae60 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -36,8 +36,7 @@ public static Command manageCommand(String userInput) throws DukeException { } else if (secondKeyword.equals("task")){ try { - String[] tempCommand = command[1].split("\\s+"); - Task task = new Task(command[1]); + Task task = new Task(commandContent); return new AddStandardTaskCommand(task); }catch(Exception e){ throw new Exception("Please follow the format 'add task .' "); diff --git a/src/main/java/duke/relation/PatientTask.java b/src/main/java/duke/relation/PatientTask.java index 964f7b5213..91859f878b 100644 --- a/src/main/java/duke/relation/PatientTask.java +++ b/src/main/java/duke/relation/PatientTask.java @@ -21,7 +21,6 @@ public PatientTask(int pid, int tid, boolean isdone, boolean isrecurrsive, Strin this.isRecurrsive = isrecurrsive; } - public Integer getPatientId(){ return patientId; } From 799b2409c33db5c34c1f87fc8afbec900ad036ea Mon Sep 17 00:00:00 2001 From: lmtaek Date: Mon, 14 Oct 2019 14:48:29 +0800 Subject: [PATCH 115/420] Created Parser class and method for 'add' tasks specifically. --- src/main/java/duke/core/Parser.java | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/main/java/duke/core/Parser.java diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java new file mode 100644 index 0000000000..abd78a6e7b --- /dev/null +++ b/src/main/java/duke/core/Parser.java @@ -0,0 +1,26 @@ +package duke.core; + +public class Parser { + + String userInput; + + public Parser(String userInput) { + this.userInput = userInput; + } + + public String[] addParser() throws DukeException { + String[] parsedCommand = userInput.toLowerCase().split("\\s+", 2); + try { + if (parsedCommand[2].equals("patient")) { + String[] patientInfo = userInput.replace("add patient ", "").trim().split("\\s+", 4); + return patientInfo; + } else if (parsedCommand[2].equals("task")) { + String[] taskInfo = userInput.replace("add task ", "").trim().split("\\s+", 2); + return taskInfo; + } + } catch (Exception e) { + throw new DukeException("Please change the format for your 'add' command."); + } + throw new DukeException("Failed to parse 'add' command."); + } +} From 47c87eb44b711fbd7333feeb180ca285c3801f07 Mon Sep 17 00:00:00 2001 From: lmtaek Date: Mon, 14 Oct 2019 16:14:34 +0800 Subject: [PATCH 116/420] Finalizing parsing method for add commands. Still need to distinguish 'add task' from 'add patient' in CommandManager, but same method can be called and utilized for either instance. --- .../java/duke/command/AddPatientCommand.java | 9 ++++---- src/main/java/duke/core/CommandManager.java | 21 +++++-------------- src/main/java/duke/core/Parser.java | 11 +++++----- 3 files changed, 15 insertions(+), 26 deletions(-) diff --git a/src/main/java/duke/command/AddPatientCommand.java b/src/main/java/duke/command/AddPatientCommand.java index 006dacae44..805f13ff26 100644 --- a/src/main/java/duke/command/AddPatientCommand.java +++ b/src/main/java/duke/command/AddPatientCommand.java @@ -11,18 +11,17 @@ import duke.task.TaskManager; public class AddPatientCommand extends Command { - private String command; - public AddPatientCommand(String command) { + private String[] patientInfo; + public AddPatientCommand(String[] patientInfo) { super(); - this.command = command; + this.patientInfo = patientInfo; } @Override public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { Patient newPatient; try { - String commandArr[] = command.split("\\s+", 4); - newPatient = new Patient(commandArr[0], commandArr[1], commandArr[2], commandArr[3]); + newPatient = new Patient(patientInfo[0], patientInfo[1], patientInfo[2], patientInfo[3]); } catch (Exception e) { throw new DukeException("Please follow the format 'add patient '. "); } diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 19c5f9ae60..4e89d463e9 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -22,32 +22,21 @@ public static Command manageCommand(String userInput) throws DukeException { userInput = userInput.trim(); String[] command = userInput.split("\\s+", 3); String firstKeyword = command[0].toLowerCase(); + Parser parser = new Parser(userInput); switch (firstKeyword) { //change this depending on how string is parsed case "add": - try { String secondKeyword = command[1].toLowerCase(); - String commandContent = command[2].trim(); if (secondKeyword.equals("patient")){ - try { - return new AddPatientCommand(commandContent); - }catch(Exception e){ - throw new Exception("Please follow the format 'add patient '. "); - } + String[] formattedInput = parser.parseAdd(); + return new AddPatientCommand(formattedInput); } else if (secondKeyword.equals("task")){ - try { - Task task = new Task(commandContent); + Task task = new Task(parser.parseAdd()[0]); return new AddStandardTaskCommand(task); - }catch(Exception e){ - throw new Exception("Please follow the format 'add task .' "); - } } else { - throw new Exception("Invalid format. "); + throw new DukeException("Invalid format. "); } - } catch (Exception e) { - throw new DukeException("Add command fails. " + e.getMessage()); - } case "assign": try { String[] tempCommand = command[1].split("\\s+", 2); diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index abd78a6e7b..9ea4b8493d 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -8,14 +8,15 @@ public Parser(String userInput) { this.userInput = userInput; } - public String[] addParser() throws DukeException { - String[] parsedCommand = userInput.toLowerCase().split("\\s+", 2); + public String[] parseAdd() throws DukeException { + String[] parsedCommand = userInput.toLowerCase().split("\\s+", 3); try { - if (parsedCommand[2].equals("patient")) { + if (parsedCommand[1].equals("patient")) { String[] patientInfo = userInput.replace("add patient ", "").trim().split("\\s+", 4); return patientInfo; - } else if (parsedCommand[2].equals("task")) { - String[] taskInfo = userInput.replace("add task ", "").trim().split("\\s+", 2); + } else if (parsedCommand[1].equals("task")) { + String[] taskInfo = new String[1]; + taskInfo[0] = userInput.replace("add task ", "").trim(); return taskInfo; } } catch (Exception e) { From 2e9a04c29397f97cd7bfb43d84b9747d5d7b666a Mon Sep 17 00:00:00 2001 From: lmtaek Date: Mon, 14 Oct 2019 16:27:32 +0800 Subject: [PATCH 117/420] Finalizing parsing methods and reformatting creation/execution of AddPatientCommand and AddStandardTaskCommand so that both classes' behavior is more standardized. --- .../java/duke/command/AddPatientCommand.java | 18 +++++++++--------- .../duke/command/AddStandardTaskCommand.java | 4 ++-- src/main/java/duke/core/CommandManager.java | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/main/java/duke/command/AddPatientCommand.java b/src/main/java/duke/command/AddPatientCommand.java index 805f13ff26..cb3cf1147b 100644 --- a/src/main/java/duke/command/AddPatientCommand.java +++ b/src/main/java/duke/command/AddPatientCommand.java @@ -11,20 +11,20 @@ import duke.task.TaskManager; public class AddPatientCommand extends Command { - private String[] patientInfo; - public AddPatientCommand(String[] patientInfo) { - super(); - this.patientInfo = patientInfo; - } - @Override - public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { - Patient newPatient; + private Patient newPatient; + + public AddPatientCommand(String[] patientInfo) throws DukeException { + super(); try { - newPatient = new Patient(patientInfo[0], patientInfo[1], patientInfo[2], patientInfo[3]); + this.newPatient = new Patient(patientInfo[0], patientInfo[1], patientInfo[2], patientInfo[3]); } catch (Exception e) { throw new DukeException("Please follow the format 'add patient '. "); } + } + + @Override + public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { patientList.addPatient(newPatient); patientStorage.save(patientList.getPatientList()); ui.patientAdded(newPatient); diff --git a/src/main/java/duke/command/AddStandardTaskCommand.java b/src/main/java/duke/command/AddStandardTaskCommand.java index 5b873aacf0..0d1e375cf2 100644 --- a/src/main/java/duke/command/AddStandardTaskCommand.java +++ b/src/main/java/duke/command/AddStandardTaskCommand.java @@ -12,9 +12,9 @@ public class AddStandardTaskCommand extends Command{ private Task newStandardTask; - public AddStandardTaskCommand(Task newStandardTask) { + public AddStandardTaskCommand(String taskDescription) { super(); - this.newStandardTask = newStandardTask; + this.newStandardTask = new Task(taskDescription); } @Override diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 4e89d463e9..a97a8c8270 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -31,8 +31,8 @@ public static Command manageCommand(String userInput) throws DukeException { return new AddPatientCommand(formattedInput); } else if (secondKeyword.equals("task")){ - Task task = new Task(parser.parseAdd()[0]); - return new AddStandardTaskCommand(task); + String formattedInput = parser.parseAdd()[0]; + return new AddStandardTaskCommand(formattedInput); } else { throw new DukeException("Invalid format. "); From eced593e5c886491fe322dd01cdaaae9058aa2d9 Mon Sep 17 00:00:00 2001 From: lmtaek Date: Mon, 14 Oct 2019 17:42:19 +0800 Subject: [PATCH 118/420] Beginning of parser method for 'assign'. Checks specifically if the user indicates assignment by ID. --- src/main/java/duke/core/Parser.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index 9ea4b8493d..ddc68e8d8a 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -24,4 +24,22 @@ public String[] parseAdd() throws DukeException { } throw new DukeException("Failed to parse 'add' command."); } + + public String[] parseAssign() throws DukeException { + String[] formattedInput; + try { + String[] parsedCommand = userInput.toLowerCase().split("\\s+", 3); + if (parsedCommand[1].equals("by") && parsedCommand[2].equals("id:")) { + formattedInput = userInput.replace("assign by id: ", "").split("\\s+", 4); + } + + + return formattedInput; + + } catch (Exception e) { + throw new DukeException("Please use the correct format for the 'assign by id' command. "); + } + } + + } From df27d43ec685a4bdc038d3e66772e3fe0a6ee26a Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Mon, 14 Oct 2019 18:13:48 +0800 Subject: [PATCH 119/420] Fixed bug when parsing find/delete patient command --- src/main/java/duke/core/CommandManager.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index a97a8c8270..063b604db2 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -65,10 +65,10 @@ else if (tempCommand[0].toLowerCase().equals("tasks")){ } case "delete": try{ - String[] tempCommand = command[1].split("\\s+", 2); - if (tempCommand[0].toLowerCase().equals("patient")){ + secondKeyword = command[1].toLowerCase(); + if (secondKeyword.equals("patient")){ try { - return new DeletePatientCommand(tempCommand[1]); + return new DeletePatientCommand(command[2]); }catch(Exception e){ throw new Exception("Please follow the format 'delete patient #'."); } @@ -81,10 +81,10 @@ else if (tempCommand[0].toLowerCase().equals("tasks")){ } case "find": try{ - String[] tempCommand = command[1].split("\\s+", 2); - if (tempCommand[0].toLowerCase().equals("patient")){ + secondKeyword = command[1].toLowerCase(); + if (secondKeyword.equals("patient")){ try { - return new FindPatientCommand(tempCommand[1]); + return new FindPatientCommand(command[2]); }catch(Exception e){ throw new Exception("Please follow the format 'find patient #' or 'find patient '."); } From 6450abca8b5485a74cb98835269e39dba36c3009 Mon Sep 17 00:00:00 2001 From: kejun liu Date: Mon, 14 Oct 2019 20:46:49 +0800 Subject: [PATCH 120/420] Add a unique id for every standard task --- data/standardTasks.csv | 10 +-- src/main/java/duke/storage/TaskStorage.java | 8 ++- src/main/java/duke/task/Task.java | 11 +++- src/main/java/duke/task/TaskManager.java | 68 ++++++++++----------- 4 files changed, 51 insertions(+), 46 deletions(-) diff --git a/data/standardTasks.csv b/data/standardTasks.csv index 52ef689bbc..44bacc2701 100644 --- a/data/standardTasks.csv +++ b/data/standardTasks.csv @@ -1,7 +1,3 @@ -Description -Take medicine -abc -eat medicine lalala -test task name with multiple words -hello world -hello hell \ No newline at end of file +Id,Description +1,Take medicine +2,Do surgery diff --git a/src/main/java/duke/storage/TaskStorage.java b/src/main/java/duke/storage/TaskStorage.java index 390671a2c7..50cc464ff7 100644 --- a/src/main/java/duke/storage/TaskStorage.java +++ b/src/main/java/duke/storage/TaskStorage.java @@ -41,8 +41,9 @@ public ArrayList load() throws DukeException { Reader in = new FileReader(filePath); Iterable records = CSVFormat.EXCEL.withFirstRecordAsHeader().parse(in); for (CSVRecord record : records) { + int id = Integer.parseInt(record.get("Id")); String description = record.get("Description"); - taskList.add(new Task(description)); + taskList.add(new Task(id, description)); } return taskList; } catch (IOException e) { @@ -61,10 +62,11 @@ public void save(ArrayList tasks) throws DukeException { try{ BufferedWriter writer = Files.newBufferedWriter(Paths.get(filePath)); CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT - .withHeader("Description")); + .withHeader("Id", "Description")); for (Task task : tasks){ + int id = task.getID(); String description = task.getDescription(); - csvPrinter.printRecord(description); + csvPrinter.printRecord(id, description); } csvPrinter.flush(); } diff --git a/src/main/java/duke/task/Task.java b/src/main/java/duke/task/Task.java index c22ca95b1c..b8c423e450 100644 --- a/src/main/java/duke/task/Task.java +++ b/src/main/java/duke/task/Task.java @@ -5,12 +5,18 @@ * instantiated */ public class Task { - + private int id = 0; private String description; + public Task(int id, String description) { + this.id = id; + this.description = description; + } + public Task(String description) { this.description = description; } + /** * Returns a string with the status icon and the description of the task. * @@ -27,8 +33,11 @@ public String printDescription() { * the task. */ + public int getID() { return id; } + public String getDescription() { return description; } + public void setID(int id) { this.id = id; } } \ No newline at end of file diff --git a/src/main/java/duke/task/TaskManager.java b/src/main/java/duke/task/TaskManager.java index 4fb379c275..6a00a32dbb 100644 --- a/src/main/java/duke/task/TaskManager.java +++ b/src/main/java/duke/task/TaskManager.java @@ -2,12 +2,16 @@ import duke.core.DukeException; import java.util.ArrayList; +import java.util.HashMap; /** * Represents a list of Task that can perform operations such as * add and delete on the tasks. */ public class TaskManager { + private HashMap taskIdMap = new HashMap<>(); + private int maxId = 0; + /** * An ArrayList structure. */ @@ -16,10 +20,15 @@ public class TaskManager { /** * Constructor used when Duke successfully loads a TaskList from a saved file. * Takes loaded taskList and uses it during Duke's new session. - * @param loadedTaskList + * @param taskList */ - public TaskManager(ArrayList loadedTaskList) { - this.taskList = loadedTaskList; + public TaskManager(ArrayList taskList) { + for (Task task : taskList) { + taskIdMap.put(task.getID(), task); + } + if (!taskList.isEmpty()) { + this.maxId = taskList.get(taskList.size()-1).getID(); + } } /** @@ -30,39 +39,36 @@ public TaskManager() { this.taskList = new ArrayList(); } - /** - * Retrieves the entire task list stored inside the ArrayList. - */ - public ArrayList fullTaskList() { - return taskList; - } - /** * Adds a Task to the list. * - * @param t The Task to be added to the list. + * @param task The Task to be added to the list. */ - public void addTask(Task t) { - taskList.add(t); + public void addTask(Task task) { + if (task.getID() == 0){ + maxId += 1; + task.setID(maxId); + } + taskIdMap.put(task.getID(), task); } /** * Removes the Task with the given index from the list. * - * @param i The index of the Task to be deleted. + * //@param i The index of the Task to be deleted. */ - public void deleteTask(Integer i) throws DukeException { + /*public void deleteTask(Integer i) throws DukeException { if (getSize() < i) { throw new DukeException("Task Number " + i + " does not exist"); } taskList.remove(i - 1); - } + }*/ - public boolean isExist(Integer i) { - if (getSize() >= i) { + public boolean isExist(int id) { + if (taskIdMap.containsKey(id)){ return true; } - else { + else{ return false; } } @@ -70,27 +76,19 @@ public boolean isExist(Integer i) { /** * Returns the Task in the list with the given index. * - * @param i The index of the Task. + * @param id The index of the Task. * @return The Task in the list with the specific index. */ - public Task getTask(int i) throws DukeException { - if (getSize() < i) { - throw new DukeException("Task Number " + i + " does not exist"); + public Task getTask(int id) throws DukeException { + if (taskIdMap.containsKey(id)){ + return taskIdMap.get(id); + } + else{ + throw new DukeException("The task with id "+ id + " does not exist."); } - return taskList.get(i - 1); - } - - /** - * Returns the size of task list. - * - * @return An integer representing the number of tasks in the list. - */ - public int getSize() { - return taskList.size(); } public ArrayList getTaskList() { - return new ArrayList<>(taskList); + return new ArrayList<>(taskIdMap.values()); } - } From b15c60792c451511b35c77a42579a28377692d95 Mon Sep 17 00:00:00 2001 From: kkeejjuunn <47095442+kkeejjuunn@users.noreply.github.com> Date: Mon, 14 Oct 2019 23:16:55 +0800 Subject: [PATCH 121/420] Update TaskManager.java --- src/main/java/duke/task/TaskManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/duke/task/TaskManager.java b/src/main/java/duke/task/TaskManager.java index 6a00a32dbb..0e474195b7 100644 --- a/src/main/java/duke/task/TaskManager.java +++ b/src/main/java/duke/task/TaskManager.java @@ -64,7 +64,7 @@ public void addTask(Task task) { taskList.remove(i - 1); }*/ - public boolean isExist(int id) { + public boolean doesExist(int id) { if (taskIdMap.containsKey(id)){ return true; } From 76538ab4a8e3c27c86b36bfdb94e2e48f2ca4cf3 Mon Sep 17 00:00:00 2001 From: kejun liu Date: Mon, 14 Oct 2019 23:43:23 +0800 Subject: [PATCH 122/420] Added delete task command by id or description. User confirm before deleting the task. --- data/patients.csv | 2 +- data/standardTasks.csv | 2 - .../java/duke/command/DeleteTaskCommand.java | 62 +++++++++++++++++++ src/main/java/duke/core/CommandManager.java | 7 +++ src/main/java/duke/core/Ui.java | 62 +++++++++++++++++++ src/main/java/duke/task/TaskManager.java | 27 ++++++-- 6 files changed, 153 insertions(+), 9 deletions(-) create mode 100644 src/main/java/duke/command/DeleteTaskCommand.java diff --git a/data/patients.csv b/data/patients.csv index b35135cb98..8ea9f50bda 100644 --- a/data/patients.csv +++ b/data/patients.csv @@ -5,4 +5,4 @@ Id,Name,NRIC,Room,Remark 9,weifeng,G12356,7A,male 10,kejun,G1234567890,no mood no modd,8A 11,qianjie,1231312321,A5,NIL -12,qianjie,S92139123,A03,NIL \ No newline at end of file +12,qianjie,S92139123,A03,NIL diff --git a/data/standardTasks.csv b/data/standardTasks.csv index 44bacc2701..42de11cdd1 100644 --- a/data/standardTasks.csv +++ b/data/standardTasks.csv @@ -1,3 +1 @@ Id,Description -1,Take medicine -2,Do surgery diff --git a/src/main/java/duke/command/DeleteTaskCommand.java b/src/main/java/duke/command/DeleteTaskCommand.java new file mode 100644 index 0000000000..f80049b1c0 --- /dev/null +++ b/src/main/java/duke/command/DeleteTaskCommand.java @@ -0,0 +1,62 @@ +package duke.command; + +import duke.core.DukeException; +import duke.core.Ui; +import duke.patient.PatientManager; +import duke.storage.PatientStorage; +import duke.storage.PatientTaskStorage; +import duke.storage.TaskStorage; +import duke.relation.PatientTaskList; +import duke.task.Task; +import duke.task.TaskManager; + +import java.util.ArrayList; + +public class DeleteTaskCommand extends Command{ + private int id; + private String command; + + public DeleteTaskCommand(String command) { + this.command = command; + } + + @Override + public void execute(PatientTaskList patientTask, TaskManager taskManager, PatientManager patientManager, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + char firstChar = command.charAt(0); + if (firstChar == '#') { + int id; + try{ + id = Integer.parseInt(command.substring(1, command.length())); + }catch(Exception e){ + throw new DukeException("Please follow the format 'delete task #'."); + } + + Task taskToBeDeleted = taskManager.getTask(id); + boolean toDelete = ui.confirmTaskToBeDeleted(taskToBeDeleted); + if (toDelete){ + taskManager.deleteTask(id); + ui.taskDeleted(); + taskStorage.save(taskManager.getTaskList()); + } + } else { + ArrayList tasksWithSameDescription = taskManager.getTaskByDescription(command); + ui.tasksFoundByDescription(tasksWithSameDescription, command); + if (tasksWithSameDescription.size() >= 1) { + int numberChosen = ui.chooseTaskToDelete(tasksWithSameDescription.size()); + if (numberChosen >= 1){ + boolean toDelete = ui.confirmTaskToBeDeleted(tasksWithSameDescription.get(numberChosen-1)); + if (toDelete){ + taskManager.deleteTask(tasksWithSameDescription.get(numberChosen-1).getID()); + ui.taskDeleted(); + taskStorage.save(taskManager.getTaskList()); + } + } + } + } + } + + @Override + public boolean isExit() { + return false; + } +} diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 063b604db2..de9738c00b 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -73,6 +73,13 @@ else if (tempCommand[0].toLowerCase().equals("tasks")){ throw new Exception("Please follow the format 'delete patient #'."); } } + else if (secondKeyword.equals("task")){ + try { + return new DeleteTaskCommand(command[2]); + }catch(Exception e){ + throw new Exception("Please follow the format 'delete task #'."); + } + } else { throw new Exception("Invalid format. "); } diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index 7c976cf2a3..8291db56fa 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -56,6 +56,10 @@ public void showPatientInfo(Patient patient) { + "\nRemark: " + patient.getRemark()); } + public void showTaskInfo(Task task) { + System.out.println("Task: " + task.getDescription()); + } + public void patientsFoundByName(ArrayList patients, String name) { if (patients.size() > 0) { System.out.println("Got it. " + patients.size() + " patients is/are found with name: " + name); @@ -71,6 +75,21 @@ public void patientsFoundByName(ArrayList patients, String name) { } } + public void tasksFoundByDescription(ArrayList tasks, String description) { + if (tasks.size() > 0) { + System.out.println("Got it. " + tasks.size() + " tasks is/are found with description: " + description); + int i = 1; + for (Task task : tasks) { + System.out.println("Task #" + i); + showTaskInfo(task); + showLine(); + i++; + } + } else { + System.out.println("No task was found with description: " + description); + } + } + public void patientsFoundById(Patient patient) { System.out.println("Got it. The patient is found."); showPatientInfo(patient); @@ -109,6 +128,29 @@ public int choosePatientToDelete(int numberOfPatients) { } + public int chooseTaskToDelete(int numberOfTasks) { + int chosenNumber = -1; + while (true) { + System.out.println("Enter the number of task to delete, or enter number 0 to cancel: "); + String command = readCommand(); + try { + chosenNumber = Integer.parseInt(command); + } catch (Exception e) { + System.out.println("Please enter a valid number!"); + continue; + } + if (chosenNumber >= 0 && chosenNumber <= numberOfTasks) { + if (chosenNumber == 0) { + System.out.println("Delete command is canceled"); + } + return chosenNumber; + } else { + System.out.println("The task #" + chosenNumber + " does not exist. Please enter a valid number!"); + } + } + + } + public boolean confirmPatientToBeDeleted(Patient patient) { showPatientInfo(patient); while (true) { @@ -129,6 +171,10 @@ public void patientDeleted() { System.out.println("Got it. The patient is deleted."); } + public void taskDeleted() { + System.out.println("Got it. The task is deleted."); + } + public void listAllPatients(ArrayList patients) { for (Patient patient : patients) { showPatientInfo(patient); @@ -148,6 +194,22 @@ public void listAllTasks(ArrayList taskList) { } } + public boolean confirmTaskToBeDeleted(Task task) { + showTaskInfo(task); + while (true) { + System.out.println("The task is to be deleted. Are you sure (Y/N)? "); + String command = readCommand(); + if (command.toLowerCase().equals("y")) { + return true; + } else if (command.toLowerCase().equals("n")) { + System.out.println("Delete command is canceled"); + return false; + } else { + System.out.println("Please enter only Y/N to confirm/cancel deletion!"); + } + } + } + /** * Shows a divider line. */ diff --git a/src/main/java/duke/task/TaskManager.java b/src/main/java/duke/task/TaskManager.java index 6a00a32dbb..70e801d618 100644 --- a/src/main/java/duke/task/TaskManager.java +++ b/src/main/java/duke/task/TaskManager.java @@ -39,6 +39,18 @@ public TaskManager() { this.taskList = new ArrayList(); } + public ArrayList getTaskByDescription(String description){ + description = description.toLowerCase(); + ArrayList tasksWithThisDescription = new ArrayList<>(); + for (Task task : taskIdMap.values()) { + if(task.getDescription().toLowerCase().equals(description)){ + tasksWithThisDescription.add(task); + } + } + return tasksWithThisDescription; + } + + /** * Adds a Task to the list. * @@ -55,14 +67,17 @@ public void addTask(Task task) { /** * Removes the Task with the given index from the list. * - * //@param i The index of the Task to be deleted. + * @param id The index of the Task to be deleted. */ - /*public void deleteTask(Integer i) throws DukeException { - if (getSize() < i) { - throw new DukeException("Task Number " + i + " does not exist"); + public void deleteTask(int id) throws DukeException { + if (taskIdMap.containsKey(id)){ + taskIdMap.remove(id); } - taskList.remove(i - 1); - }*/ + else{ + throw new DukeException("The task with id "+ id + " does not exist."); + } + + } public boolean isExist(int id) { if (taskIdMap.containsKey(id)){ From 2608639c7e95b7d0139bab3ebff95fd86433e392 Mon Sep 17 00:00:00 2001 From: WEIFENG-NUSCEG Date: Tue, 15 Oct 2019 03:26:24 +0800 Subject: [PATCH 123/420] Update the function to find the tasks associate to a patient by his/her ID or Name --- data/standardTasks.csv | 1 + src/main/java/duke/Duke.java | 1 - .../command/AssignTaskToPatientCommand.java | 2 +- .../duke/command/FindPatientTaskCommand.java | 76 +++++++++++++++++++ src/main/java/duke/core/CommandManager.java | 7 ++ src/main/java/duke/core/Ui.java | 13 +++- .../java/duke/relation/EventPatientTask.java | 1 + .../java/duke/relation/PatientTaskList.java | 1 + 8 files changed, 99 insertions(+), 3 deletions(-) create mode 100644 src/main/java/duke/command/FindPatientTaskCommand.java diff --git a/data/standardTasks.csv b/data/standardTasks.csv index 44bacc2701..03e7e38a31 100644 --- a/data/standardTasks.csv +++ b/data/standardTasks.csv @@ -1,3 +1,4 @@ Id,Description 1,Take medicine 2,Do surgery +3,Take shit \ No newline at end of file diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index b27fc9fa6b..fa2f55f84a 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -55,7 +55,6 @@ public Duke(String filePath) { ui.showLoadingError(); System.out.println(e.getMessage()); taskManager = new TaskManager(); - } } diff --git a/src/main/java/duke/command/AssignTaskToPatientCommand.java b/src/main/java/duke/command/AssignTaskToPatientCommand.java index ecc0427725..bd2dcb6312 100644 --- a/src/main/java/duke/command/AssignTaskToPatientCommand.java +++ b/src/main/java/duke/command/AssignTaskToPatientCommand.java @@ -25,7 +25,7 @@ public AssignTaskToPatientCommand(String cmd) { @Override public void execute(PatientTaskList patientTaskList, TaskManager tasksList, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { this.newPatientTask = finalPatientTask(command); - if (patientList.isExist(newPatientTask.getPatientId()) && tasksList.isExist(newPatientTask.getTaskID())) + if (patientList.isExist(newPatientTask.getPatientId()) && tasksList.doesExist(newPatientTask.getTaskID())) { patientTaskList.addPatientTask(newPatientTask); patientTaskStorage.save(patientTaskList.fullPatientTaskList()); diff --git a/src/main/java/duke/command/FindPatientTaskCommand.java b/src/main/java/duke/command/FindPatientTaskCommand.java new file mode 100644 index 0000000000..8e7dca392a --- /dev/null +++ b/src/main/java/duke/command/FindPatientTaskCommand.java @@ -0,0 +1,76 @@ +package duke.command; + +import duke.core.DukeException; +import duke.core.Ui; +import duke.patient.Patient; +import duke.patient.PatientManager; +import duke.relation.EventPatientTask; +import duke.relation.StandardPatientTask; +import duke.storage.PatientStorage; +import duke.storage.PatientTaskStorage; +import duke.storage.TaskStorage; +import duke.relation.PatientTask; +import duke.relation.PatientTaskList; +import duke.task.Task; +import duke.task.TaskManager; + +import java.awt.*; +import java.util.ArrayList; + +public class FindPatientTaskCommand extends Command { + + private String command; + + public FindPatientTaskCommand(String cmd) { + super(); + this.command = cmd; + } + + @Override + public void execute(PatientTaskList patientTaskList, TaskManager tasksManager, PatientManager patientManager, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + char firstChar = command.charAt(0); + if (firstChar == '#'){ + int id; + try { + id = Integer.parseInt(command.substring(1, command.length())); + Patient patient = patientManager.getPatient(id); + ArrayList patientTask = patientTaskList.getPatientTask(id); + ArrayList tempTask = new ArrayList<>(); + for (PatientTask temppatientTask : patientTask){ + tempTask.add(tasksManager.getTask(temppatientTask.getTaskID())); + } + ui.patientTaskFound(patient, patientTask, tempTask); + }catch(Exception e) { + throw new DukeException("Please follow the format 'find patienttask #' or 'find patient '."); + } + } + else{ + String name = command.toLowerCase(); + ArrayList patientsWithSameName = patientManager.getPatientByName(name); + ArrayList patientWithTask = new ArrayList<>(); + ArrayList tempTask = new ArrayList<>(); + + try { + for (Patient patient : patientsWithSameName) { + if(patient.getName().toLowerCase().equals(name)){ + patientWithTask = patientTaskList.getPatientTask(patient.getID()); + } + } + for (PatientTask temppatientTask : patientWithTask){ + tempTask.add(tasksManager.getTask(temppatientTask.getTaskID())); + //System.out.println(temppatientTask.getTaskID() + "\n"); + } + + ui.patientTaskFound(patientsWithSameName.get(0), patientWithTask, tempTask); + }catch(Exception e) { + throw new DukeException(e .getMessage() + "Please follow the format 'find patienttask #' or 'find patient '."); + } + } + } + + + @Override + public boolean isExit() { + return false; + } +} \ No newline at end of file diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 063b604db2..814be9c16d 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -89,6 +89,13 @@ else if (tempCommand[0].toLowerCase().equals("tasks")){ throw new Exception("Please follow the format 'find patient #' or 'find patient '."); } } + else if (secondKeyword.equals("patienttask")){ + try { + return new FindPatientTaskCommand(command[2]); + }catch(Exception e){ + throw new Exception("Please follow the format 'find patient #' or 'find patient '."); + } + } else { throw new Exception("Invalid format. "); } diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index 7c976cf2a3..269d633353 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -11,7 +11,7 @@ */ public class Ui { /** - * weifeng + * weifeng * A Scanner to read user input. */ private Scanner scanner; @@ -192,4 +192,15 @@ public void showUpdateStatus(Patient patient , String targetInfo) { public void showLoadingError() { System.out.println("Failed to Load from local text file!"); } + + public void patientTaskFound(Patient patient, ArrayList patientTask, ArrayList tasks) { + System.out.println("The tasks of patient " + patient.getID() + " " + patient.getName() + " is found : \n"); + for (int i = 0; i < patientTask.size(); i++){ + showLine(); + System.out.println( tasks.get(i).getID() + ". " + tasks.get(i).getDescription() +"\n"); + System.out.println( patientTask.get(i).toString()); + showLine(); + } + } + } diff --git a/src/main/java/duke/relation/EventPatientTask.java b/src/main/java/duke/relation/EventPatientTask.java index 54d3a21e93..fd0dd32959 100644 --- a/src/main/java/duke/relation/EventPatientTask.java +++ b/src/main/java/duke/relation/EventPatientTask.java @@ -73,6 +73,7 @@ public long retrieveDuration() { return this.duration; } + public String toString(){ return super.printStatus() + " From " + DateTimeParser.convertToEnglishDateTimeBeforeParse(startTime) + "To" + DateTimeParser.convertToEnglishDateTimeBeforeParse(endTime); } diff --git a/src/main/java/duke/relation/PatientTaskList.java b/src/main/java/duke/relation/PatientTaskList.java index 1aaab640d4..dbfe410d14 100644 --- a/src/main/java/duke/relation/PatientTaskList.java +++ b/src/main/java/duke/relation/PatientTaskList.java @@ -64,6 +64,7 @@ public ArrayList getPatientTask(int pid) throws DukeException { } } + public ArrayList getTaskPatient(int tid) throws DukeException { ArrayList tempArray = new ArrayList(); for (PatientTask patientTask : patientTaskIdMap.values()) { From 3e9ae2d14acafe0a8e2ab3185e13d04c4c51f33e Mon Sep 17 00:00:00 2001 From: lmtaek Date: Tue, 15 Oct 2019 11:07:19 +0800 Subject: [PATCH 124/420] Successful implementation of 'assign by id: ' for standard tasks. Still encountering parsing difficulties with event task assignments. --- .../command/AssignTaskToPatientCommand.java | 53 +++++++++++-------- src/main/java/duke/core/CommandManager.java | 8 +-- src/main/java/duke/core/Parser.java | 15 ++++-- 3 files changed, 43 insertions(+), 33 deletions(-) diff --git a/src/main/java/duke/command/AssignTaskToPatientCommand.java b/src/main/java/duke/command/AssignTaskToPatientCommand.java index ecc0427725..f7ff3cd77f 100644 --- a/src/main/java/duke/command/AssignTaskToPatientCommand.java +++ b/src/main/java/duke/command/AssignTaskToPatientCommand.java @@ -15,16 +15,17 @@ public class AssignTaskToPatientCommand extends Command { private String command; + private String[] taskAssignmentInfo; private PatientTask newPatientTask; - public AssignTaskToPatientCommand(String cmd) { + public AssignTaskToPatientCommand(String[] taskAssignmentInfo) throws DukeException { super(); - this.command = cmd; + this.taskAssignmentInfo = taskAssignmentInfo; + this.newPatientTask = finalPatientTask(taskAssignmentInfo); } @Override public void execute(PatientTaskList patientTaskList, TaskManager tasksList, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { - this.newPatientTask = finalPatientTask(command); if (patientList.isExist(newPatientTask.getPatientId()) && tasksList.isExist(newPatientTask.getTaskID())) { patientTaskList.addPatientTask(newPatientTask); @@ -38,26 +39,32 @@ public void execute(PatientTaskList patientTaskList, TaskManager tasksList, Pati } - public PatientTask finalPatientTask(String cmd) throws DukeException { - String[] tempCommand = command.split("\\s+",4 ); - if (tempCommand[0].equals("S")) { - String type = tempCommand[0]; - int patientId = Integer.parseInt(tempCommand[1]); - int taskId = Integer.parseInt(tempCommand[2]); - String deadline = tempCommand[3]; - StandardPatientTask sPatientTask = new StandardPatientTask(patientId, taskId, deadline, type); - return sPatientTask; - } else if (tempCommand[0].equals("E")) { - String type = tempCommand[0]; - int patientId = Integer.parseInt(tempCommand[1]); - int taskId = Integer.parseInt(tempCommand[2]); - String sTime = tempCommand[3].split(" /to ", 2)[0]; - String eTime = tempCommand[3].split(" /to ", 2)[1]; - EventPatientTask ePatientTask = new EventPatientTask(patientId, taskId, sTime, eTime, type); - return ePatientTask; - } - else{ - throw new DukeException("Parsing failed! Please ensure the format you have entered is correct!"); + public PatientTask finalPatientTask(String[] assignmentInfo) throws DukeException { + try { + if (assignmentInfo[0].equals("S")) { + + String type = assignmentInfo[0]; + int patientId = Integer.parseInt(assignmentInfo[1]); + int taskId = Integer.parseInt(assignmentInfo[2]); + String deadline = assignmentInfo[3]; + + StandardPatientTask standardPatientTask = new StandardPatientTask(patientId, taskId, deadline, type); + return standardPatientTask; + } else if (assignmentInfo[0].equals("E")) { + + String type = assignmentInfo[0]; + int patientId = Integer.parseInt(assignmentInfo[1]); + int taskId = Integer.parseInt(assignmentInfo[2]); + String startTime = assignmentInfo[3]; + String endTime = assignmentInfo[4]; + + EventPatientTask eventPatientTask = new EventPatientTask(patientId, taskId, startTime, endTime, type); + return eventPatientTask; + } else { + throw new DukeException("Parsing failed! Please ensure the format you have entered is correct!"); + } + } catch (Exception e) { + throw new DukeException("Unable to parse your task assignment. Please check your command's format!"); } } @Override diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index a97a8c8270..0be91e029e 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -39,13 +39,9 @@ else if (secondKeyword.equals("task")){ } case "assign": try { - String[] tempCommand = command[1].split("\\s+", 2); - if (tempCommand[0].toLowerCase().equals("byid")) { - return new AssignTaskToPatientCommand(tempCommand[1]); - } - + return new AssignTaskToPatientCommand(parser.parseAssign()); } catch (Exception e) { - throw new DukeException("update command fails. " + e.getMessage()); + throw new DukeException("'Assign' command fails. " + e.getMessage()); } case "list": diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index ddc68e8d8a..92a9a8c811 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -28,14 +28,21 @@ public String[] parseAdd() throws DukeException { public String[] parseAssign() throws DukeException { String[] formattedInput; try { - String[] parsedCommand = userInput.toLowerCase().split("\\s+", 3); + String[] parsedCommand = userInput.toLowerCase().split("\\s+", 4); if (parsedCommand[1].equals("by") && parsedCommand[2].equals("id:")) { formattedInput = userInput.replace("assign by id: ", "").split("\\s+", 4); + //System.out.println(formattedInput[3]); + if (formattedInput[0].equals("E")) { + String[] parsedTimes = formattedInput[3].split(" to ", 2); + //System.out.println(parsedTimes[3] + " ?? " + parsedTimes[4]); + formattedInput[3] = parsedTimes[0].trim(); + formattedInput[4] = parsedTimes[1].trim(); + } + + } else { + throw new DukeException("Please use proper 'assign by ID' command format. "); } - - return formattedInput; - } catch (Exception e) { throw new DukeException("Please use the correct format for the 'assign by id' command. "); } From 8a1d023679a2001209e725b0304fa9763335c178 Mon Sep 17 00:00:00 2001 From: lmtaek Date: Tue, 15 Oct 2019 12:12:51 +0800 Subject: [PATCH 125/420] Updated parser method to successfully parse 'E' assignments. --- src/main/java/duke/core/Parser.java | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index 92a9a8c811..5a144054e4 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -26,22 +26,30 @@ public String[] parseAdd() throws DukeException { } public String[] parseAssign() throws DukeException { - String[] formattedInput; + String[] formattedInput = new String[5]; try { String[] parsedCommand = userInput.toLowerCase().split("\\s+", 4); if (parsedCommand[1].equals("by") && parsedCommand[2].equals("id:")) { - formattedInput = userInput.replace("assign by id: ", "").split("\\s+", 4); - //System.out.println(formattedInput[3]); - if (formattedInput[0].equals("E")) { - String[] parsedTimes = formattedInput[3].split(" to ", 2); - //System.out.println(parsedTimes[3] + " ?? " + parsedTimes[4]); - formattedInput[3] = parsedTimes[0].trim(); - formattedInput[4] = parsedTimes[1].trim(); + String[] tempInput = userInput.replace("assign by id: ", "").split("\\s+", 4); + if (tempInput[0].equals("E")) { + String[] parsedTimes = tempInput[3].split(" to ", 2); + + for (int i=0; i<3; i++) { + formattedInput[i] = tempInput[i]; + } + formattedInput[3] = parsedTimes[0]; + formattedInput[4] = parsedTimes[1]; + } else { + for (int i = 0; i < tempInput.length; i++) { + formattedInput[i] = tempInput[i]; + } } + } else { throw new DukeException("Please use proper 'assign by ID' command format. "); } + System.out.println(formattedInput[3]); return formattedInput; } catch (Exception e) { throw new DukeException("Please use the correct format for the 'assign by id' command. "); From b80b406d492549c8f19699c82897ccbd497759dd Mon Sep 17 00:00:00 2001 From: lmtaek Date: Tue, 15 Oct 2019 22:02:37 +0800 Subject: [PATCH 126/420] Implemented parser functionality for 'delete patient #'. Reformatted DeletePatientCommand slightly to make constructor actions more relevant, and cleaned up its .execute() method so that it has less parsing responsibility. --- .../duke/command/DeletePatientCommand.java | 31 ++++++++++--------- src/main/java/duke/core/CommandManager.java | 12 +++---- src/main/java/duke/core/Parser.java | 19 ++++++++++++ 3 files changed, 39 insertions(+), 23 deletions(-) diff --git a/src/main/java/duke/command/DeletePatientCommand.java b/src/main/java/duke/command/DeletePatientCommand.java index f1e6442244..6ac71660cf 100644 --- a/src/main/java/duke/command/DeletePatientCommand.java +++ b/src/main/java/duke/command/DeletePatientCommand.java @@ -15,23 +15,24 @@ public class DeletePatientCommand extends Command { private int id; - private String command; + private String deletedPatientInfo; - public DeletePatientCommand(String command) { - this.command = command; - } + public DeletePatientCommand(String deletedPatientInfo) throws DukeException { - @Override - public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientManager, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { - char firstChar = command.charAt(0); - if (firstChar == '#') { - int id; - try{ - id = Integer.parseInt(command.substring(1, command.length())); - }catch(Exception e){ - throw new DukeException("Please follow the format 'delete patient #'."); + this.deletedPatientInfo = deletedPatientInfo; + + if (Character.isDigit(deletedPatientInfo.charAt(0))) { + try { + this.id = Integer.parseInt(deletedPatientInfo); + } catch (Exception e) { + throw new DukeException("Please follow format 'delete patient #'. "); } + } + } + @Override + public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientManager, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { ; + if (id != 0) { Patient patientToBeDeleted = patientManager.getPatient(id); boolean toDelete = ui.confirmPatientToBeDeleted(patientToBeDeleted); if (toDelete){ @@ -40,8 +41,8 @@ public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManag patientStorage.save(patientManager.getPatientList()); } } else { - ArrayList patientsWithSameName = patientManager.getPatientByName(command); - ui.patientsFoundByName(patientsWithSameName, command); + ArrayList patientsWithSameName = patientManager.getPatientByName(deletedPatientInfo); + ui.patientsFoundByName(patientsWithSameName, deletedPatientInfo); if (patientsWithSameName.size() >= 1) { int numberChosen = ui.choosePatientToDelete(patientsWithSameName.size()); if (numberChosen >= 1){ diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index bdad5cf25e..b80829970e 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -38,12 +38,7 @@ else if (secondKeyword.equals("task")){ throw new DukeException("Invalid format. "); } case "assign": - try { return new AssignTaskToPatientCommand(parser.parseAssign()); - } catch (Exception e) { - throw new DukeException("'Assign' command fails. " + e.getMessage()); - } - case "list": try { String[] tempCommand = command[1].split("\\s+"); @@ -62,10 +57,11 @@ else if (tempCommand[0].toLowerCase().equals("tasks")){ case "delete": try{ secondKeyword = command[1].toLowerCase(); - if (secondKeyword.equals("patient")){ + if (secondKeyword.equals("patient")) { try { - return new DeletePatientCommand(command[2]); - }catch(Exception e){ + String formattedInput = parser.parseDelete(); + return new DeletePatientCommand(formattedInput); + } catch(Exception e){ throw new Exception("Please follow the format 'delete patient #'."); } } diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index 5a144054e4..46ff5b1390 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -30,6 +30,7 @@ public String[] parseAssign() throws DukeException { try { String[] parsedCommand = userInput.toLowerCase().split("\\s+", 4); if (parsedCommand[1].equals("by") && parsedCommand[2].equals("id:")) { + String[] tempInput = userInput.replace("assign by id: ", "").split("\\s+", 4); if (tempInput[0].equals("E")) { String[] parsedTimes = tempInput[3].split(" to ", 2); @@ -56,5 +57,23 @@ public String[] parseAssign() throws DukeException { } } + public String parseDelete() throws DukeException { + String formattedInput; + String inputToParse = userInput.replace("patient", "").replace("delete", "").trim(); + + if (inputToParse.contains("#")) { + try { + formattedInput = inputToParse.replace("#", "").trim(); + System.out.println(formattedInput); + return formattedInput; + } catch(Exception e){ + throw new DukeException("Please follow the format 'delete patient #'."); + } + } else { + formattedInput = inputToParse; + return formattedInput; + } + } + } From a9c1a36dff6433de5f546dc2dcb9fd2f4e2da675 Mon Sep 17 00:00:00 2001 From: lmtaek Date: Tue, 15 Oct 2019 22:10:53 +0800 Subject: [PATCH 127/420] Refactored .parseDelete() to .parseDeletePatient() in order to prevent future difficulties in specificity of returned parsed values. --- src/main/java/duke/core/CommandManager.java | 6 +----- src/main/java/duke/core/Parser.java | 4 ++-- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index b80829970e..0b83c1b7c3 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -1,10 +1,6 @@ package duke.core; import duke.command.*; -import duke.patient.Patient; -import duke.relation.EventPatientTask; -import duke.relation.StandardPatientTask; -import duke.task.*; /** * Represents a Parser that parses user input into a specific @@ -59,7 +55,7 @@ else if (tempCommand[0].toLowerCase().equals("tasks")){ secondKeyword = command[1].toLowerCase(); if (secondKeyword.equals("patient")) { try { - String formattedInput = parser.parseDelete(); + String formattedInput = parser.parseDeletePatient(); return new DeletePatientCommand(formattedInput); } catch(Exception e){ throw new Exception("Please follow the format 'delete patient #'."); diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index 46ff5b1390..9097067360 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -57,9 +57,9 @@ public String[] parseAssign() throws DukeException { } } - public String parseDelete() throws DukeException { + public String parseDeletePatient() throws DukeException { String formattedInput; - String inputToParse = userInput.replace("patient", "").replace("delete", "").trim(); + String inputToParse = userInput.replace("delete patient", "").trim(); if (inputToParse.contains("#")) { try { From 849e33dfe5923109216b2e37b04a6b74b6e660ef Mon Sep 17 00:00:00 2001 From: lmtaek Date: Tue, 15 Oct 2019 22:35:18 +0800 Subject: [PATCH 128/420] Implemented functionality of '.parseDeleteTask()' so that all cases of deletion are handled. Attempted to clean up excess of try/catch statements, but will need further revisions. --- .../java/duke/command/DeleteTaskCommand.java | 28 +++++++++---------- src/main/java/duke/core/CommandManager.java | 16 +++-------- src/main/java/duke/core/Parser.java | 18 +++++++++++- src/main/java/duke/core/Ui.java | 3 ++ 4 files changed, 38 insertions(+), 27 deletions(-) diff --git a/src/main/java/duke/command/DeleteTaskCommand.java b/src/main/java/duke/command/DeleteTaskCommand.java index f80049b1c0..4789ce5d0d 100644 --- a/src/main/java/duke/command/DeleteTaskCommand.java +++ b/src/main/java/duke/command/DeleteTaskCommand.java @@ -14,23 +14,23 @@ public class DeleteTaskCommand extends Command{ private int id; - private String command; + private String deletedTaskInfo; - public DeleteTaskCommand(String command) { - this.command = command; + public DeleteTaskCommand(String deletedTaskInfo) throws DukeException { + + this.deletedTaskInfo = deletedTaskInfo; + if (Character.isDigit(deletedTaskInfo.charAt(0))) { + try { + this.id = Integer.parseInt(deletedTaskInfo); + } catch (Exception e) { + throw new DukeException("Please follow format 'delete task #'. "); + } + } } @Override public void execute(PatientTaskList patientTask, TaskManager taskManager, PatientManager patientManager, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { - char firstChar = command.charAt(0); - if (firstChar == '#') { - int id; - try{ - id = Integer.parseInt(command.substring(1, command.length())); - }catch(Exception e){ - throw new DukeException("Please follow the format 'delete task #'."); - } - + if (id != 0) { Task taskToBeDeleted = taskManager.getTask(id); boolean toDelete = ui.confirmTaskToBeDeleted(taskToBeDeleted); if (toDelete){ @@ -39,8 +39,8 @@ public void execute(PatientTaskList patientTask, TaskManager taskManager, Patien taskStorage.save(taskManager.getTaskList()); } } else { - ArrayList tasksWithSameDescription = taskManager.getTaskByDescription(command); - ui.tasksFoundByDescription(tasksWithSameDescription, command); + ArrayList tasksWithSameDescription = taskManager.getTaskByDescription(deletedTaskInfo); + ui.tasksFoundByDescription(tasksWithSameDescription, deletedTaskInfo); if (tasksWithSameDescription.size() >= 1) { int numberChosen = ui.chooseTaskToDelete(tasksWithSameDescription.size()); if (numberChosen >= 1){ diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 0b83c1b7c3..73adbf6631 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -31,7 +31,7 @@ else if (secondKeyword.equals("task")){ return new AddStandardTaskCommand(formattedInput); } else { - throw new DukeException("Invalid format. "); + throw new DukeException("Add command fails. "); } case "assign": return new AssignTaskToPatientCommand(parser.parseAssign()); @@ -54,19 +54,11 @@ else if (tempCommand[0].toLowerCase().equals("tasks")){ try{ secondKeyword = command[1].toLowerCase(); if (secondKeyword.equals("patient")) { - try { - String formattedInput = parser.parseDeletePatient(); - return new DeletePatientCommand(formattedInput); - } catch(Exception e){ - throw new Exception("Please follow the format 'delete patient #'."); - } + String formattedInput = parser.parseDeletePatient(); + return new DeletePatientCommand(formattedInput); } else if (secondKeyword.equals("task")){ - try { - return new DeleteTaskCommand(command[2]); - }catch(Exception e){ - throw new Exception("Please follow the format 'delete task #'."); - } + return new DeleteTaskCommand(parser.parseDeleteTask()); } else { throw new Exception("Invalid format. "); diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index 9097067360..c751545db3 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -64,7 +64,6 @@ public String parseDeletePatient() throws DukeException { if (inputToParse.contains("#")) { try { formattedInput = inputToParse.replace("#", "").trim(); - System.out.println(formattedInput); return formattedInput; } catch(Exception e){ throw new DukeException("Please follow the format 'delete patient #'."); @@ -75,5 +74,22 @@ public String parseDeletePatient() throws DukeException { } } + public String parseDeleteTask() throws DukeException { + String formattedInput; + String inputToParse = userInput.replace("delete task", "").trim(); + + if (inputToParse.contains("#")) { + try { + formattedInput = inputToParse.replace("#", "").trim(); + return formattedInput; + } catch(Exception e){ + throw new DukeException("Please follow the format 'delete task #'."); + } + } else { + formattedInput = inputToParse; + return formattedInput; + } + } + } diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index 38619f5d4e..aa36699596 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -189,6 +189,9 @@ public void listAllTasks(ArrayList taskList) { System.out.println(index + ". " + task.getDescription() + + " (ID: " + + task.getID() + + ")" + "\n"); index++; } From c5e78f7a9b9e6827d7b945230036a755cf0ba60b Mon Sep 17 00:00:00 2001 From: lmtaek Date: Wed, 16 Oct 2019 07:54:12 +0800 Subject: [PATCH 129/420] Revised based on team feedback. Now using '#' as an indicator of a deletion by ID within the DeletePatient/TaskCommand classes. Minimizes actual parsing within the Parser, but for the moment, it's a reasonable solution. Will implement a better solution later. --- .../duke/command/DeletePatientCommand.java | 6 ++-- .../java/duke/command/DeleteTaskCommand.java | 5 +-- src/main/java/duke/core/Parser.java | 32 ++++--------------- 3 files changed, 12 insertions(+), 31 deletions(-) diff --git a/src/main/java/duke/command/DeletePatientCommand.java b/src/main/java/duke/command/DeletePatientCommand.java index 6ac71660cf..6b992fe6c4 100644 --- a/src/main/java/duke/command/DeletePatientCommand.java +++ b/src/main/java/duke/command/DeletePatientCommand.java @@ -20,10 +20,10 @@ public class DeletePatientCommand extends Command { public DeletePatientCommand(String deletedPatientInfo) throws DukeException { this.deletedPatientInfo = deletedPatientInfo; - - if (Character.isDigit(deletedPatientInfo.charAt(0))) { + char firstChar = deletedPatientInfo.charAt(0); + if (firstChar == '#') { try { - this.id = Integer.parseInt(deletedPatientInfo); + this.id = Integer.parseInt(deletedPatientInfo.substring(1)); } catch (Exception e) { throw new DukeException("Please follow format 'delete patient #'. "); } diff --git a/src/main/java/duke/command/DeleteTaskCommand.java b/src/main/java/duke/command/DeleteTaskCommand.java index 4789ce5d0d..42be4b08ba 100644 --- a/src/main/java/duke/command/DeleteTaskCommand.java +++ b/src/main/java/duke/command/DeleteTaskCommand.java @@ -19,9 +19,10 @@ public class DeleteTaskCommand extends Command{ public DeleteTaskCommand(String deletedTaskInfo) throws DukeException { this.deletedTaskInfo = deletedTaskInfo; - if (Character.isDigit(deletedTaskInfo.charAt(0))) { + char firstChar = deletedTaskInfo.charAt(0); + if (firstChar == '#') { try { - this.id = Integer.parseInt(deletedTaskInfo); + this.id = Integer.parseInt(deletedTaskInfo.substring(1)); } catch (Exception e) { throw new DukeException("Please follow format 'delete task #'. "); } diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index c751545db3..16aff0be13 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -59,36 +59,16 @@ public String[] parseAssign() throws DukeException { public String parseDeletePatient() throws DukeException { String formattedInput; - String inputToParse = userInput.replace("delete patient", "").trim(); - - if (inputToParse.contains("#")) { - try { - formattedInput = inputToParse.replace("#", "").trim(); - return formattedInput; - } catch(Exception e){ - throw new DukeException("Please follow the format 'delete patient #'."); - } - } else { - formattedInput = inputToParse; - return formattedInput; - } + String inputToParse = userInput.replaceAll("(?i)delete patient ", "").trim(); + formattedInput = inputToParse; + return formattedInput; } public String parseDeleteTask() throws DukeException { String formattedInput; - String inputToParse = userInput.replace("delete task", "").trim(); - - if (inputToParse.contains("#")) { - try { - formattedInput = inputToParse.replace("#", "").trim(); - return formattedInput; - } catch(Exception e){ - throw new DukeException("Please follow the format 'delete task #'."); - } - } else { - formattedInput = inputToParse; - return formattedInput; - } + String inputToParse = userInput.replaceAll("(?i)delete task ", "").trim(); + formattedInput = inputToParse; + return formattedInput; } From e7628dc4bdb0f7039af7b73b951a619a343f822f Mon Sep 17 00:00:00 2001 From: lmtaek Date: Wed, 16 Oct 2019 16:27:24 +0800 Subject: [PATCH 130/420] Added ParserTest class + tests for the 'add' method. --- src/test/java/duke/core/ParserTest.java | 31 +++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 src/test/java/duke/core/ParserTest.java diff --git a/src/test/java/duke/core/ParserTest.java b/src/test/java/duke/core/ParserTest.java new file mode 100644 index 0000000000..630d141d25 --- /dev/null +++ b/src/test/java/duke/core/ParserTest.java @@ -0,0 +1,31 @@ +package duke.core; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class ParserTest { + + String patientDummyInput = "add patient name NRIC room remark"; + String taskDummyInput = "add task Walk the dog"; + + @Test + public void parseAddPatientTest() throws DukeException { + Parser testParser = new Parser(patientDummyInput); + String[] testOutput = testParser.parseAdd(); + + assertTrue(testOutput[0].equals("name"), "Name field did not parse correctly. Expected: 'name', but got: " + testOutput[0]); + assertTrue(testOutput[1].equals("NRIC"), "NRIC field did not parse correctly. Expected: 'NRIC', but got: " + testOutput[1]); + assertTrue(testOutput[2].equals("room"), "Room field did not parse correctly. Expected: 'room', but got: " + testOutput[2]); + assertTrue(testOutput[3].equals("remark"), "Remark field did not parse correctly. Expected: 'remark', but got: " + testOutput[3]); + + } + + @Test + public void parseAddTask() throws DukeException { + Parser testParser = new Parser(taskDummyInput); + String[] testOutput = testParser.parseAdd(); + + assertTrue(testOutput[0].equals("Walk the dog"), "Task description did not parse correctly. Expected 'Walk the dog' but got: " + testOutput[0]); + } +} From d0ca0d240b4cb6f30028daaf73f62cc11e6de7aa Mon Sep 17 00:00:00 2001 From: lmtaek Date: Wed, 16 Oct 2019 18:28:08 +0800 Subject: [PATCH 131/420] Added 'assign' method tests in ParserTest class. --- src/test/java/duke/core/ParserTest.java | 32 +++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/test/java/duke/core/ParserTest.java b/src/test/java/duke/core/ParserTest.java index 630d141d25..62a3621a90 100644 --- a/src/test/java/duke/core/ParserTest.java +++ b/src/test/java/duke/core/ParserTest.java @@ -9,6 +9,11 @@ public class ParserTest { String patientDummyInput = "add patient name NRIC room remark"; String taskDummyInput = "add task Walk the dog"; + String assignPatientIDToTaskS = "assign by id: S 1 2 02/02/2002 2222"; + String assignPatientIDToTaskE = "assign by id: E 2 1 02/02/2002 2222 to 03/02/2002 1234"; + + String deletePatientInput = "delete patient #123"; + @Test public void parseAddPatientTest() throws DukeException { Parser testParser = new Parser(patientDummyInput); @@ -28,4 +33,31 @@ public void parseAddTask() throws DukeException { assertTrue(testOutput[0].equals("Walk the dog"), "Task description did not parse correctly. Expected 'Walk the dog' but got: " + testOutput[0]); } + + @Test + public void parseAssignPatientByID() throws DukeException { + Parser testParserStandard = new Parser(assignPatientIDToTaskS); + Parser testParserEvent = new Parser(assignPatientIDToTaskE); + + String[] testOutputStandard = testParserStandard.parseAssign(); + String[] testOutputEvent = testParserEvent.parseAssign(); + + assertTrue(testOutputStandard[0].equals("S"), "Task type parsed incorrectly. Expected 'S' but got: " + testOutputStandard[0]); + assertTrue(testOutputStandard[1].equals("1") && testOutputStandard[2].equals("2"), "IDs parsed incorrectly.\n" + + "Expected patient ID of 1, and got: " + testOutputStandard[1] + ".\n Expected task ID of 2 and got: " + testOutputStandard[2]); + assertTrue(testOutputStandard[3].equals("02/02/2002 2222")); + + assertTrue(testOutputEvent[0].equals("E"), "Task type parsed incorrectly. Expected 'E' but got: " + testOutputEvent[0]); + assertTrue(testOutputEvent[1].equals("2") && testOutputEvent[2].equals("1"), "IDs parsed incorrectly.\n" + + "Expected patient ID of 2, and got: " + testOutputEvent[1] + ".\n Expected task ID of 1 and got: " + testOutputEvent[2]); + assertTrue(testOutputEvent[3].equals("02/02/2002 2222"), "Start date parsed incorrectly. Expected '02/02/2002 2222' but got: " + testOutputEvent[3]); + assertTrue(testOutputEvent[4].equals("03/02/2002 1234"), "End date parsed incorrectly. Expected '03/02/2002 1234' but got: " + testOutputEvent[4]); + } + + @Test + public void parseDeletePatient() { + + } + + } From 425f8fd22950fa2a87a0b41813243939c73536c3 Mon Sep 17 00:00:00 2001 From: lmtaek Date: Wed, 16 Oct 2019 18:54:04 +0800 Subject: [PATCH 132/420] Added test methods for 'delete patient' and 'delete task' instances within the Parser class. --- src/test/java/duke/core/ParserTest.java | 27 ++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/test/java/duke/core/ParserTest.java b/src/test/java/duke/core/ParserTest.java index 62a3621a90..2405368874 100644 --- a/src/test/java/duke/core/ParserTest.java +++ b/src/test/java/duke/core/ParserTest.java @@ -1,7 +1,6 @@ package duke.core; import org.junit.jupiter.api.Test; - import static org.junit.jupiter.api.Assertions.assertTrue; public class ParserTest { @@ -12,7 +11,10 @@ public class ParserTest { String assignPatientIDToTaskS = "assign by id: S 1 2 02/02/2002 2222"; String assignPatientIDToTaskE = "assign by id: E 2 1 02/02/2002 2222 to 03/02/2002 1234"; - String deletePatientInput = "delete patient #123"; + String deletePatientInputWithID = "delete patient #123"; + String deletePatientInputWithName = "delete patient billy joe"; + String deleteTaskInputWithID = "delete task 10"; + String deleteTaskInputWithName = "delete task Take medicine"; @Test public void parseAddPatientTest() throws DukeException { @@ -55,8 +57,27 @@ public void parseAssignPatientByID() throws DukeException { } @Test - public void parseDeletePatient() { + public void parseDeletePatient() throws DukeException { + Parser testParserID = new Parser(deletePatientInputWithID); + Parser testParserName = new Parser(deletePatientInputWithName); + + String testOutputID = testParserID.parseDeletePatient(); + String testOutputName = testParserName.parseDeletePatient(); + + assertTrue(testOutputID.charAt(0) == '#' && testOutputID.equals("#123"), "Delete patient by ID parsing failed. Expected '#123' but got: " + testOutputID); + assertTrue(testOutputName.equals("billy joe"), "Delete patient by name parsing failed. Expected 'billy joe' but got: " + testOutputName); + } + + @Test + public void parseDeleteTask() throws DukeException { + Parser testParserID = new Parser(deleteTaskInputWithID); + Parser testParserName = new Parser(deleteTaskInputWithName); + + String testOutputID = testParserID.parseDeleteTask(); + String testOutputName = testParserName.parseDeleteTask(); + assertTrue(testOutputID.charAt(0) == '#' && testOutputID.equals("#10"), "Delete task by ID parsing failed. Expected '#10' but got: " + testOutputID); + assertTrue(testOutputName.equals("Take medicine"), "Delete task by name parsing failed. Expected 'Take medicine' but got: " + testOutputName); } From 9acfafde4178e9dafe184cc85e361296ff5b7669 Mon Sep 17 00:00:00 2001 From: lmtaek Date: Wed, 16 Oct 2019 19:03:20 +0800 Subject: [PATCH 133/420] Removed all unnecessary tests. --- src/test/java/duke/task/DeadlineTest.java | 59 ------------------- src/test/java/duke/task/EventTest.java | 59 ------------------- .../java/duke/task/FixedDurationTaskTest.java | 24 -------- src/test/java/duke/task/PeriodTaskTest.java | 25 -------- src/test/java/duke/task/RecurringTest.java | 54 ----------------- src/test/java/duke/task/TodoTest.java | 59 ------------------- 6 files changed, 280 deletions(-) delete mode 100644 src/test/java/duke/task/DeadlineTest.java delete mode 100644 src/test/java/duke/task/EventTest.java delete mode 100644 src/test/java/duke/task/FixedDurationTaskTest.java delete mode 100644 src/test/java/duke/task/PeriodTaskTest.java delete mode 100644 src/test/java/duke/task/RecurringTest.java delete mode 100644 src/test/java/duke/task/TodoTest.java diff --git a/src/test/java/duke/task/DeadlineTest.java b/src/test/java/duke/task/DeadlineTest.java deleted file mode 100644 index 8bf16926ed..0000000000 --- a/src/test/java/duke/task/DeadlineTest.java +++ /dev/null @@ -1,59 +0,0 @@ -package duke.task; - -import duke.core.DukeException; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - - -public class DeadlineTest { - - /** - * Test the Deadline.toString() - */ - @Test - public void deadlineStringTest() throws DukeException { - assertEquals( "[D][\u2718] abc (by: 2nd of December 1996, 12PM)", new Deadline("abc", "02/12/1996 1235").toString(),"Deadline toString() is not expected"); - } - - /** - * Test the Deadline.writeTxt() - */ - @Test - public void writeFormatTest() throws DukeException { - assertEquals( "D | 0 | deadlineTest | 02/12/1996 1235 | ONCE",new Deadline("deadlineTest", "02/12/1996 1235").writeTxt(), "The writeToFile format is not expected"); - } - - /** - * Test the Deadline.isDone() after a new Deadline object is being initialized - */ - @Test - public void doneStatusTest() throws DukeException { - assertFalse(new Deadline("abc", "02/12/1996 1235").isDone(), "The newly created Deadline should not be done"); - } - - /** - * A general test case to test Deadline class - * Test steps: - * 1. Create a Deadline object - * 2. Verify Deadline.isdone(), Deadline.toString(), Deadline.writeTxt() - * 3. Mark the Deadline object to isDone status. - * 4. Repeat step 2 - * - * @throws DukeException if markAsDone is applied to a done task, throw exception with log - */ - @Test - public void deadlineTestCase() throws DukeException { - // Create a new deadline and check its toString() and writeTxt() - Deadline deadline = new Deadline("deadlineTest", "02/12/1996 1235"); - assertFalse(deadline.isDone(), "The newly created deadline should not be done"); - assertEquals( "[D][\u2718] deadlineTest (by: 2nd of December 1996, 12PM)",deadline.toString(), "The writeToFile format is not expected"); - assertEquals( "D | 0 | deadlineTest | 02/12/1996 1235 | ONCE",deadline.writeTxt(), "The writeToFile format is not expected"); - - // Mark the deadline as done and check its toString() and writeTxt() - deadline.markAsDone(); - assertTrue(deadline.isDone(), "The deadline should be marked as done"); - assertEquals("[D][\u2713] deadlineTest (by: 2nd of December 1996, 12PM)", deadline.toString(), "The deadline.toString() is not expected"); - assertEquals( "D | 1 | deadlineTest | 02/12/1996 1235 | ONCE",deadline.writeTxt(), "The writeToFile format is not expected"); - } -} diff --git a/src/test/java/duke/task/EventTest.java b/src/test/java/duke/task/EventTest.java deleted file mode 100644 index 36162e1300..0000000000 --- a/src/test/java/duke/task/EventTest.java +++ /dev/null @@ -1,59 +0,0 @@ - -package duke.task; - -import duke.core.DukeException; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - - -public class EventTest { - /** - * Test the Event.toString() - */ - @Test - public void EventStringTest() throws DukeException { - assertEquals("[E][\u2718] eventTest (at: 2nd of December 1996, 12PM)", new Event("eventTest", "02/12/1996 1235").toString(), "toString result is not expected"); - } - - /** - * Test the Event.writeTxt() - */ - @Test - public void writeFormatTest() throws DukeException { - assertEquals( "E | 0 | test | 02/12/1996 1235 | ONCE",new Event("test", "02/12/1996 1235").writeTxt(), "The writeToFile format is not expected"); - } - - /** - * Test the Event.isDone() after a new Event object is being initialized - */ - @Test - public void doneStatusTest() throws DukeException { - assertFalse(new Event("test", "02/12/1996 1235").isDone(), "The newly created Deadline should not be done"); - } - - /** - * A general test case to test Event class - * Test steps: - * 1. Create a Event object - * 2. Verify Event.isdone(), Event.toString(), Event.writeTxt() - * 3. Mark the Event object to isDone status. - * 4. Repeat step 2 - * - * @throws DukeException if markAsDone is applied to a done task, throw exception with log - */ - @Test - public void eventTestCase() throws DukeException { - // Creata a new event and check its toString() and writeTxt() - Event event = new Event("eventTest", "02/12/1996 1235"); - assertFalse(event.isDone(), "The newly created event should not be done"); - assertEquals( "[E][\u2718] eventTest (at: 2nd of December 1996, 12PM)",event.toString(), "The writeToFile format is not expected"); - assertEquals( "E | 0 | eventTest | 02/12/1996 1235 | ONCE",event.writeTxt(), "The writeToFile format is not expected"); - - // Mark the event as done and check its toString() and writeTxt() - event.markAsDone(); - assertTrue(event.isDone(), "The event should be marked as done"); - assertEquals("[E][\u2713] eventTest (at: 2nd of December 1996, 12PM)", event.toString(), "The event.toString() is not expected"); - assertEquals( "E | 1 | eventTest | 02/12/1996 1235 | ONCE",event.writeTxt(), "The writeToFile format is not expected"); - } -} \ No newline at end of file diff --git a/src/test/java/duke/task/FixedDurationTaskTest.java b/src/test/java/duke/task/FixedDurationTaskTest.java deleted file mode 100644 index 517e32fb9d..0000000000 --- a/src/test/java/duke/task/FixedDurationTaskTest.java +++ /dev/null @@ -1,24 +0,0 @@ -package duke.task; - -import duke.core.DukeException; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - -public class FixedDurationTaskTest { - /** - * Test the FixedDurationTask.toString() - */ - @Test - public void FixedDurationTaskStringTest() throws DukeException { - assertEquals("[F][\u2718] FixedDurationTaskTest (duration: 2 hours)", new FixedDurationTask("FixedDurationTaskTest", "2 hours").toString()); - } - - /** - * Test the fixeddurationtask.writeTxt() - */ - @Test - public void writeFormatTest() { - assertEquals( "F | 0 | FixedDurationTest | 1 hour | false",new FixedDurationTask("FixedDurationTest", "1 hour").writeTxt(), "The writeToFile format is not expected"); - } -} diff --git a/src/test/java/duke/task/PeriodTaskTest.java b/src/test/java/duke/task/PeriodTaskTest.java deleted file mode 100644 index 6eec44ff2f..0000000000 --- a/src/test/java/duke/task/PeriodTaskTest.java +++ /dev/null @@ -1,25 +0,0 @@ -package duke.task; - -import duke.core.DukeException; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - - -public class PeriodTaskTest { - /** - * Test the PeriodTask.toString() - */ - @Test - public void PeriodTaskStringTest() throws DukeException { - assertEquals("[P][\u2718] PeriodTaskTest (start: 27th of July 1996, 3PM end: 27th of July 2020, 3PM)", new PeriodTask("PeriodTaskTest", "27/07/1996 1530", "27/07/2020 1530").toString(), "toString result is not expected"); - } - - /** - * Test the PeriodTask.writeTxt() - */ - @Test - public void writeFormatTest() throws DukeException { - assertEquals( "P | 0 | PeriodTaskTest | 27/07/1996 1530 | 27/07/2020 1530",new PeriodTask("PeriodTaskTest", "27/07/1996 1530", "27/07/2020 1530").writeTxt(), "The writeToFile format is not expected"); - } -} \ No newline at end of file diff --git a/src/test/java/duke/task/RecurringTest.java b/src/test/java/duke/task/RecurringTest.java deleted file mode 100644 index b1258bfaea..0000000000 --- a/src/test/java/duke/task/RecurringTest.java +++ /dev/null @@ -1,54 +0,0 @@ -package duke.task; -import duke.core.DukeException; -import org.junit.jupiter.api.Test; - -import java.time.Duration; -import java.time.LocalDateTime; - -public class RecurringTest { - - @Test - public void recurringDailyDeadlineTest() throws DukeException { - Deadline dummyDeadline = new Deadline("paper", "03/08/2018 1159"); - LocalDateTime oldDateTime = dummyDeadline.getDateTime(); - dummyDeadline.makeTaskRecurring(Task.RecurringFrequency.DAILY); - assert(dummyDeadline.getDateTime().isAfter(oldDateTime)); - - Duration dayDifference = Duration.between(LocalDateTime.now(), dummyDeadline.getDateTime()); - long numberOfDaysDifference = Math.abs(dayDifference.toDays()); - assert(numberOfDaysDifference <= 1); - } - - @Test - public void recurringWeeklyEventTest() throws DukeException { - Event dummyEvent = new Event("presentation", "15/09/2019 1000"); - LocalDateTime oldDateTime = dummyEvent.getDateTime(); - dummyEvent.makeTaskRecurring(Task.RecurringFrequency.WEEKLY); - assert(dummyEvent.getDateTime().isAfter(oldDateTime)); - - Duration dayDifference = Duration.between(LocalDateTime.now(), dummyEvent.getDateTime()); - long numberOfDaysDifference = Math.abs(dayDifference.toDays()); - assert(numberOfDaysDifference <= 7); - } - - @Test public void recurringMonthlyDeadlineTest() throws DukeException { - Deadline dummyDeadline = new Deadline("paper", "03/08/2018 1159"); - LocalDateTime oldDateTime = dummyDeadline.getDateTime(); - dummyDeadline.makeTaskRecurring(Task.RecurringFrequency.MONTHLY); - assert(dummyDeadline.getDateTime().isAfter(oldDateTime)); - - Duration dayDifference = Duration.between(LocalDateTime.now(), dummyDeadline.getDateTime()); - long numberOfDaysDifference = Math.abs(dayDifference.toDays()); - assert(numberOfDaysDifference <= 31); - } - - /* - @Test public void recurringTodoTest() { - Task dummyToDo = new Todo("essay"); - dummyToDo.makeTaskRecurring(Task.RecurringFrequency.DAILY); - assertNotEquals(true, dummyToDo.isTaskRecurring()); - } - - */ - -} diff --git a/src/test/java/duke/task/TodoTest.java b/src/test/java/duke/task/TodoTest.java deleted file mode 100644 index 1043f9a2f4..0000000000 --- a/src/test/java/duke/task/TodoTest.java +++ /dev/null @@ -1,59 +0,0 @@ -package duke.task; - -import duke.core.DukeException; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - - -public class TodoTest { - - /** - * Test the todo.toString() - */ - @Test - public void todoStringTest(){ - assertEquals(new Todo("todoTest").toString(), "[T][\u2718] todoTest", "todo string test fails"); - } - - /** - * Test the todo.writeTxt() - */ - @Test - public void writeFormatTest() { - assertEquals( "T | 0 | todoTest | ONCE",new Todo("todoTest").writeTxt(), "The writeToFile format is not expected"); - } - - /** - * Test the todo.isDone() after a new Todo object is being initialized - */ - @Test - public void doneStatusTest() { - assertFalse(new Todo("abc").isDone(), "The newly created Deadline should not be done"); - } - - /** - * A general test case to test Todo class - * Test steps: - * 1. Create a Todo object - * 2. Verify todo.isdone(), todo.toString(), todo.writeTxt() - * 3. Mark the todo object to isDone status. - * 4. Repeat step 2 - * - * @throws DukeException if markAsDone is applied to a done task, throw exception with log - */ - @Test - public void todoTestCase() throws DukeException { - // Creata a new task and check its toString() and writeTxt() - Todo todo = new Todo("todoTest"); - assertFalse(todo.isDone(), "The newly created todo should not be done"); - assertEquals( "[T][\u2718] todoTest",todo.toString(), "The writeToFile format is not expected"); - assertEquals( "T | 0 | todoTest | ONCE",todo.writeTxt(), "The writeToFile format is not expected"); - - // Mark the task as done and check its toString() and writeTxt() - todo.markAsDone(); - assertTrue(todo.isDone(), "The todo should be marked as done"); - assertEquals("[T][\u2713] todoTest", todo.toString(), "The todo.toString() is not expected"); - assertEquals( "T | 1 | todoTest | ONCE",todo.writeTxt(), "The writeToFile format is not expected"); - } -} \ No newline at end of file From 7b0333a8eebad540fdfc323e41cb3f1706b5f8ff Mon Sep 17 00:00:00 2001 From: kejun liu Date: Wed, 16 Oct 2019 20:12:04 +0800 Subject: [PATCH 134/420] Fix bug of update patient command --- data/patients.csv | 6 +-- .../duke/command/UpdatePatientCommand.java | 51 +++++++++++-------- src/main/java/duke/core/CommandManager.java | 13 ++--- src/main/java/duke/core/Parser.java | 7 ++- src/main/java/duke/core/Ui.java | 7 +-- 5 files changed, 46 insertions(+), 38 deletions(-) diff --git a/data/patients.csv b/data/patients.csv index 8ea9f50bda..d5433fb2e7 100644 --- a/data/patients.csv +++ b/data/patients.csv @@ -1,8 +1,8 @@ Id,Name,NRIC,Room,Remark -1,xk,G03123456,xuankun,no -2,weifeng,G789456,9A,no +1,xk,G00012345,xuankun,no +2,weifeng,G789456,8B,no 3,qianjiee,G123456,2c,no 9,weifeng,G12356,7A,male 10,kejun,G1234567890,no mood no modd,8A 11,qianjie,1231312321,A5,NIL -12,qianjie,S92139123,A03,NIL +12,qianjie,S92139123,A04,NIL diff --git a/src/main/java/duke/command/UpdatePatientCommand.java b/src/main/java/duke/command/UpdatePatientCommand.java index 6c902230cf..4332e22a06 100644 --- a/src/main/java/duke/command/UpdatePatientCommand.java +++ b/src/main/java/duke/command/UpdatePatientCommand.java @@ -12,32 +12,41 @@ public class UpdatePatientCommand extends Command { - private int Id; - private String targetInfo; - private String updatedValue; - - public UpdatePatientCommand(int Id , String targetInfo , String updatedValue) { - super(); - this.Id = Id; - this.targetInfo = targetInfo; - this.updatedValue = updatedValue; - } + private String command; + + public UpdatePatientCommand(String command) { this.command = command; } @Override public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientManager, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { - Patient targetPatient = patientManager.getPatient(Id); - if (targetInfo.equals("name")) { - targetPatient.setName(updatedValue); - } else if (targetInfo.equals("nric")) { - targetPatient.setNric(updatedValue); - } else if (targetInfo.equals("room")) { - targetPatient.setRoom(updatedValue); - } else { - throw new DukeException("No such Patient information existed. Please Enter a valid Patient information"); + String[] tempCommand = command.split(" ", 3); + char firstChar = tempCommand[0].charAt(0); + if (firstChar == '#'){ + int id; + try { + id = Integer.parseInt(tempCommand[0].substring(1, tempCommand[0].length())); + Patient patientToBeUpdated = patientManager.getPatient(id); + if (tempCommand[1].toLowerCase().equals("name")) { + patientToBeUpdated.setName(tempCommand[2]); + } + else if (tempCommand[1].toLowerCase().equals("nric")) { + patientToBeUpdated.setNric(tempCommand[2]); + } + else if (tempCommand[1].toLowerCase().equals("room")) { + patientToBeUpdated.setRoom(tempCommand[2]); + } + else { + throw new DukeException("You can only update 'Name', 'NRIC', or 'Room' of the patient"); + } + + patientStorage.save(patientManager.getPatientList()); + + ui.showUpdatedSuccessfully(); + ui.showPatientInfo(patientToBeUpdated); + }catch(Exception e) { + throw new DukeException("Please follow the format 'update patient # '."); } - patientStorage.save(patientManager.getPatientList()); - ui.showUpdateStatus(targetPatient , targetInfo); + } } @Override diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 73adbf6631..442fc97699 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -91,14 +91,11 @@ else if (secondKeyword.equals("patienttask")){ } case "update": try { - String[] descriptions = command[1].split("\\s+"); - int targetId = Integer.parseInt(descriptions[1]); - String targetInfo = descriptions[2]; - String updateValue = descriptions[3]; - - return new UpdatePatientCommand(targetId, targetInfo, updateValue); - - + secondKeyword = command[1].toLowerCase(); + if (secondKeyword.equals("patient")){ + String formattedInput = parser.parseUpdatePatient(); + return new UpdatePatientCommand(formattedInput); + } } catch (Exception e) { throw new DukeException("update command fails. " + e.getMessage()); } diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index 16aff0be13..01930fb1fe 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -71,5 +71,10 @@ public String parseDeleteTask() throws DukeException { return formattedInput; } - + public String parseUpdatePatient() throws DukeException { + String formattedInput; + String inputToParse = userInput.replaceAll("(?i)update patient ", "").trim(); + formattedInput = inputToParse; + return formattedInput; + } } diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index aa36699596..297aab7332 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -247,13 +247,10 @@ public void showWelcome() { } - public void showUpdateStatus(Patient patient , String targetInfo) { - System.out.println("I have successfully updated the " + targetInfo + " of " + patient.getName() + " ID:" + patient.getID() ); + public void showUpdatedSuccessfully() { + System.out.println("I have successfully updated the following information: \n"); } - /** - * Shows an error in loading the file where past tasks are stored. - */ public void showLoadingError() { System.out.println("Failed to Load from local text file!"); } From 8d285ec4e9d6bbcc09107eff821b949202fbd0f9 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Wed, 16 Oct 2019 20:15:30 +0800 Subject: [PATCH 135/420] Update gitignore to ignore uncompleted Junit test --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index cc2a9133b5..c7f8c8e183 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,5 @@ build/distributions/duke-shadow-0.1.0.zip build/libs/mid-v1.1.jar build/reports/tests/test/css/style.css build/reports/tests/test/js/report.js +/data/testData/ +src/test/java/duke/storage/PatientStorageTest.java From bdee1fd7b4b534dfffbf0b190440beb4be8499fe Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Wed, 16 Oct 2019 20:17:19 +0800 Subject: [PATCH 136/420] Update PatientStorage to auto-create csv file if not existed before --- .../java/duke/storage/PatientStorage.java | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/main/java/duke/storage/PatientStorage.java b/src/main/java/duke/storage/PatientStorage.java index ffabaebb89..7c019b7c53 100644 --- a/src/main/java/duke/storage/PatientStorage.java +++ b/src/main/java/duke/storage/PatientStorage.java @@ -30,20 +30,27 @@ public PatientStorage(String filePath) { public ArrayList load() throws DukeException { ArrayList patientList = new ArrayList(); + File csvFile = new File(filePath); try { - Reader in = new FileReader(filePath); - Iterable records = CSVFormat.EXCEL.withFirstRecordAsHeader().parse(in); - for (CSVRecord record : records) { - int id = Integer.parseInt(record.get("Id")); - String name = record.get("Name"); - String nric = record.get("NRIC"); - String remark = record.get("Remark"); - String room = record.get("Room"); - patientList.add(new Patient(id, name, nric, room, remark)); + if (csvFile.createNewFile()) { + System.out.println("File " + filePath + " is created."); + } else { + Reader in = new FileReader(filePath); + Iterable records = CSVFormat.EXCEL.withFirstRecordAsHeader().parse(in); + for (CSVRecord record : records) { + int id = Integer.parseInt(record.get("Id")); + String name = record.get("Name"); + String nric = record.get("NRIC"); + String remark = record.get("Remark"); + String room = record.get("Room"); + patientList.add(new Patient(id, name, nric, room, remark)); + } } + } catch (IllegalArgumentException e) { + throw new DukeException("Loading of " + filePath + "is unsuccessful. Header is not found.\n" + + "e.getMessage()"); + } finally { return patientList; - } catch (IOException e) { - throw new DukeException(e.getMessage()); } } From 8533df1b113ddaec48179cb80ec5ee2987305223 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Wed, 16 Oct 2019 21:18:03 +0800 Subject: [PATCH 137/420] Remove outdated CommadnManagerTest --- .../java/duke/core/CommandManagerTest.java | 39 ------------------- 1 file changed, 39 deletions(-) delete mode 100644 src/test/java/duke/core/CommandManagerTest.java diff --git a/src/test/java/duke/core/CommandManagerTest.java b/src/test/java/duke/core/CommandManagerTest.java deleted file mode 100644 index 1f8d06f296..0000000000 --- a/src/test/java/duke/core/CommandManagerTest.java +++ /dev/null @@ -1,39 +0,0 @@ -package duke.core; - -import duke.command.*; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertTrue; - -public class CommandManagerTest { - /** - * Test the return command type of Parser.parse(userInput) - * @throws DukeException referencing a Duke specified exception with error log - */ - @Test - public void commandTypeTest() throws DukeException { - Command c1 = CommandManager.manageCommand("bye"); - Command c2 = CommandManager.manageCommand("done 1"); - Command c3 = CommandManager.manageCommand("delete 2"); - Command c4 = CommandManager.manageCommand("list"); - Command c5 = CommandManager.manageCommand("find MEETING"); - Command c6 = CommandManager.manageCommand("todo abc"); - Command c7 = CommandManager.manageCommand("event Meeting /at 27/07/2020 1630"); - Command c8 = CommandManager.manageCommand("deadline event Homework ABC /by 27/07/2020 1630"); - Command c9 = CommandManager.manageCommand("view 16/09/2019"); - Command c10 = CommandManager.manageCommand("period periodTaskTest /from 27/07/2020 1630 /to 27/08/2020 1630"); - Command c11 = CommandManager.manageCommand("reschedule 1 27/07/2020 1630"); - - assertTrue(c1 instanceof ExitCommand, "The command type should be "); - assertTrue(c2 instanceof DoneCommand, "The command type should be 'DoneCommand'"); - assertTrue(c3 instanceof DeleteCommand, "The command type should be 'DeleteCommand'"); - assertTrue(c4 instanceof ListCommand, "The command type should be 'ListCommand'"); - assertTrue(c5 instanceof FindCommand, "The command type should be 'FindCommand'"); - assertTrue(c6 instanceof AddCommand, "The command type should be 'AddCommand'"); - assertTrue(c7 instanceof AddCommand, "The command type should be 'AddCommand'"); - assertTrue(c8 instanceof AddCommand, "The command type should be 'AddCommand'"); - assertTrue(c9 instanceof ViewCommand, "The command type should be 'ViewCommand'"); - assertTrue(c10 instanceof AddCommand, "The command type should be 'AddCommand'"); - assertTrue(c11 instanceof RescheduleCommand, "The command type should be 'RescheduleCommand'"); - } -} From 5bff85b774737926b497fcb91fa219d0951102b3 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Wed, 16 Oct 2019 21:23:08 +0800 Subject: [PATCH 138/420] Added auto-creation of csv files during data loading if local data file does not exist --- .../java/duke/storage/PatientStorage.java | 5 +-- .../java/duke/storage/PatientTaskStorage.java | 42 +++++++++++-------- src/main/java/duke/storage/TaskStorage.java | 23 ++++++---- 3 files changed, 40 insertions(+), 30 deletions(-) diff --git a/src/main/java/duke/storage/PatientStorage.java b/src/main/java/duke/storage/PatientStorage.java index 7c019b7c53..e7e4571bbc 100644 --- a/src/main/java/duke/storage/PatientStorage.java +++ b/src/main/java/duke/storage/PatientStorage.java @@ -46,11 +46,10 @@ public ArrayList load() throws DukeException { patientList.add(new Patient(id, name, nric, room, remark)); } } - } catch (IllegalArgumentException e) { + return patientList; + } catch (Exception e) { throw new DukeException("Loading of " + filePath + "is unsuccessful. Header is not found.\n" + "e.getMessage()"); - } finally { - return patientList; } } diff --git a/src/main/java/duke/storage/PatientTaskStorage.java b/src/main/java/duke/storage/PatientTaskStorage.java index 89315f276f..a4b367cab8 100644 --- a/src/main/java/duke/storage/PatientTaskStorage.java +++ b/src/main/java/duke/storage/PatientTaskStorage.java @@ -32,28 +32,34 @@ public PatientTaskStorage(String filePath) { public ArrayList load() throws DukeException { ArrayList patientTaskList = new ArrayList(); + File csvFile = new File(filePath); try { - Reader in = new FileReader(filePath); - Iterable records = CSVFormat.EXCEL.withFirstRecordAsHeader().parse(in); - for (CSVRecord record : records) { - Integer pid = Integer.parseInt(record.get("PID")); - Integer tid = Integer.parseInt(record.get("TID")); - boolean isDone = Boolean.parseBoolean(record.get("DONE")); - boolean isRecursive = Boolean.parseBoolean(record.get("RECURRENCE")); - String deadline = record.get("DEADLINE"); - String startTime = record.get("STARTTIME"); - String endTime = record.get("ENDTIME"); - String taskType = record.get("TASKTYPE"); - if (taskType.equals("S")){ - patientTaskList.add(new StandardPatientTask(pid,tid,isDone,isRecursive,deadline,taskType)); - } - else if (taskType.equals("E")){ - patientTaskList.add(new EventPatientTask(pid,tid,isDone,isRecursive,startTime,endTime,taskType)); + if (csvFile.createNewFile()) { + System.out.println("File " + filePath + " is created."); + } else { + Reader in = new FileReader(filePath); + Iterable records = CSVFormat.EXCEL.withFirstRecordAsHeader().parse(in); + for (CSVRecord record : records) { + int pid = Integer.parseInt(record.get("PID")); + int tid = Integer.parseInt(record.get("TID")); + boolean isDone = Boolean.parseBoolean(record.get("DONE")); + boolean isRecursive = Boolean.parseBoolean(record.get("RECURRENCE")); + String deadline = record.get("DEADLINE"); + String startTime = record.get("STARTTIME"); + String endTime = record.get("ENDTIME"); + String taskType = record.get("TASKTYPE"); + if (taskType.equals("S")){ + patientTaskList.add(new StandardPatientTask(pid,tid,isDone,isRecursive,deadline,taskType)); + } + else if (taskType.equals("E")){ + patientTaskList.add(new EventPatientTask(pid,tid,isDone,isRecursive,startTime,endTime,taskType)); + } } } return patientTaskList; - } catch (IOException e) { - throw new DukeException(e.getMessage()); + } catch (Exception e) { + throw new DukeException("Loading of " + filePath + "is unsuccessful." + + "e.getMessage()"); } } diff --git a/src/main/java/duke/storage/TaskStorage.java b/src/main/java/duke/storage/TaskStorage.java index 50cc464ff7..e8290f648a 100644 --- a/src/main/java/duke/storage/TaskStorage.java +++ b/src/main/java/duke/storage/TaskStorage.java @@ -37,21 +37,26 @@ public TaskStorage(String filePath) { */ public ArrayList load() throws DukeException { ArrayList taskList = new ArrayList(); + File csvFile = new File(filePath); try { - Reader in = new FileReader(filePath); - Iterable records = CSVFormat.EXCEL.withFirstRecordAsHeader().parse(in); - for (CSVRecord record : records) { - int id = Integer.parseInt(record.get("Id")); - String description = record.get("Description"); - taskList.add(new Task(id, description)); + if (csvFile.createNewFile()) { + System.out.println("File " + filePath + " is created."); + } else { + Reader in = new FileReader(filePath); + Iterable records = CSVFormat.EXCEL.withFirstRecordAsHeader().parse(in); + for (CSVRecord record : records) { + int id = Integer.parseInt(record.get("Id")); + String description = record.get("Description"); + taskList.add(new Task(id, description)); + } } return taskList; - } catch (IOException e) { - throw new DukeException(e.getMessage()); + } catch (Exception e) { + throw new DukeException("Loading of " + filePath + "is unsuccessful.\n" + + "e.getMessage()"); } } - /** * Saves tasks to the local file. * From 4b0a62a979c68fb4370533b6167c6ab51e4760aa Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Wed, 16 Oct 2019 21:41:28 +0800 Subject: [PATCH 139/420] Updated JavaDocs for PatientStorage/PatientTaskStorage/TaskStorage in release 1.2 --- src/main/java/duke/storage/PatientStorage.java | 14 +++++++++++++- src/main/java/duke/storage/PatientTaskStorage.java | 13 +++++++++++++ src/main/java/duke/storage/TaskStorage.java | 2 +- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/main/java/duke/storage/PatientStorage.java b/src/main/java/duke/storage/PatientStorage.java index e7e4571bbc..69be0e43a8 100644 --- a/src/main/java/duke/storage/PatientStorage.java +++ b/src/main/java/duke/storage/PatientStorage.java @@ -28,6 +28,12 @@ public PatientStorage(String filePath) { this.filePath = filePath; } + /** + * Load the patients' info from local csv files + * + * @return A arrayList of Patient which contain info of patients + * @throws DukeException throw a dukeException with error message for debugging + */ public ArrayList load() throws DukeException { ArrayList patientList = new ArrayList(); File csvFile = new File(filePath); @@ -48,11 +54,17 @@ public ArrayList load() throws DukeException { } return patientList; } catch (Exception e) { - throw new DukeException("Loading of " + filePath + "is unsuccessful. Header is not found.\n" + + throw new DukeException("Loading of " + filePath + "is unsuccessful.\n" + "e.getMessage()"); } } + /** + * Write the patients' info to local csv files + * + * @param patients A list of patients containing info of patients to be written + * @throws DukeException throw exception with error message when i/o fails + */ public void save(ArrayList patients) throws DukeException { try { BufferedWriter writer = Files.newBufferedWriter(Paths.get(filePath)); diff --git a/src/main/java/duke/storage/PatientTaskStorage.java b/src/main/java/duke/storage/PatientTaskStorage.java index a4b367cab8..dc1673d0ef 100644 --- a/src/main/java/duke/storage/PatientTaskStorage.java +++ b/src/main/java/duke/storage/PatientTaskStorage.java @@ -30,6 +30,12 @@ public PatientTaskStorage(String filePath) { this.filePath = filePath; } + /** + * Load the task info with associated patient from local csv files + * + * @return A arrayList of PatientTask which contain info of task with associated patient + * @throws DukeException throw a dukeException with error message for debugging + */ public ArrayList load() throws DukeException { ArrayList patientTaskList = new ArrayList(); File csvFile = new File(filePath); @@ -63,6 +69,13 @@ else if (taskType.equals("E")){ } } + + /** + * Write info of task with associated patient to local csv files + * + * @param patientTask A list of patients containing info of patients to be written + * @throws DukeException throw exception with error message when i/o fails + */ public void save(ArrayList patientTask) throws DukeException { try { BufferedWriter writer = Files.newBufferedWriter(Paths.get(filePath)); diff --git a/src/main/java/duke/storage/TaskStorage.java b/src/main/java/duke/storage/TaskStorage.java index e8290f648a..66d3bfaae7 100644 --- a/src/main/java/duke/storage/TaskStorage.java +++ b/src/main/java/duke/storage/TaskStorage.java @@ -61,7 +61,7 @@ public ArrayList load() throws DukeException { * Saves tasks to the local file. * * @param tasks The TaskList storing tasks. - * @throws DukeException If writing to the local file failed. + * @throws DukeException throw with error message if writing to the local file failed. */ public void save(ArrayList tasks) throws DukeException { try{ From 106e9b911861c1b0b2842501c69aeb8298254dd0 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Wed, 16 Oct 2019 21:42:25 +0800 Subject: [PATCH 140/420] Add on to JavaDocs for PatientStorage/PatientTaskStorage/TaskStorage --- src/main/java/duke/storage/PatientStorage.java | 5 +++++ src/main/java/duke/storage/PatientTaskStorage.java | 5 +++++ src/main/java/duke/storage/TaskStorage.java | 5 +++++ 3 files changed, 15 insertions(+) diff --git a/src/main/java/duke/storage/PatientStorage.java b/src/main/java/duke/storage/PatientStorage.java index 69be0e43a8..747ab3eda2 100644 --- a/src/main/java/duke/storage/PatientStorage.java +++ b/src/main/java/duke/storage/PatientStorage.java @@ -11,6 +11,11 @@ import java.nio.file.Paths; import java.util.ArrayList; +/** + * TaskStorage.java - a class for writing/reading patient info to/from local in csv format. + * @author HUANG XUAN KUN + * @version 1.2 + */ public class PatientStorage { /** diff --git a/src/main/java/duke/storage/PatientTaskStorage.java b/src/main/java/duke/storage/PatientTaskStorage.java index dc1673d0ef..a3f722ff29 100644 --- a/src/main/java/duke/storage/PatientTaskStorage.java +++ b/src/main/java/duke/storage/PatientTaskStorage.java @@ -13,6 +13,11 @@ import java.nio.file.Paths; import java.util.ArrayList; +/** + * TaskStorage.java - a class for writing/reading info of task associated with patient info to/from local in csv format. + * @author HUANG XUAN KUN + * @version 1.2 + */ public class PatientTaskStorage { /** diff --git a/src/main/java/duke/storage/TaskStorage.java b/src/main/java/duke/storage/TaskStorage.java index 66d3bfaae7..ffc3988fc0 100644 --- a/src/main/java/duke/storage/TaskStorage.java +++ b/src/main/java/duke/storage/TaskStorage.java @@ -11,6 +11,11 @@ import java.nio.file.Paths; import java.util.ArrayList; +/** + * TaskStorage.java - a simple class for writing/reading taskInfo to/from local in csv format. + * @author HUANG XUAN KUN + * @version 1.2 + */ public class TaskStorage { /** From 3dc29d9d74387e78044664d524acf276c4eb2b63 Mon Sep 17 00:00:00 2001 From: kkeejjuunn <47095442+kkeejjuunn@users.noreply.github.com> Date: Wed, 16 Oct 2019 21:48:19 +0800 Subject: [PATCH 141/420] Update UpdatePatientCommand.java --- src/main/java/duke/command/UpdatePatientCommand.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/duke/command/UpdatePatientCommand.java b/src/main/java/duke/command/UpdatePatientCommand.java index 4332e22a06..139e8423c4 100644 --- a/src/main/java/duke/command/UpdatePatientCommand.java +++ b/src/main/java/duke/command/UpdatePatientCommand.java @@ -45,7 +45,9 @@ else if (tempCommand[1].toLowerCase().equals("room")) { }catch(Exception e) { throw new DukeException("Please follow the format 'update patient # '."); } - + } + else { + throw new DukeException("Please follow the format 'update patient # '."); } } From bd145855cfcc6d1e940a87e5ed548a5f34433400 Mon Sep 17 00:00:00 2001 From: WEIFENG-NUSCEG Date: Wed, 16 Oct 2019 22:51:22 +0800 Subject: [PATCH 142/420] Implemented the function to delete the Patient's task assigned by his name or id and the task id + time --- data/patientsTasks.csv | 2 +- data/standardTasks.csv | 1 + .../command/DeletePatientTaskCommand.java | 126 ++++++++++++++++++ src/main/java/duke/core/CommandManager.java | 4 + src/main/java/duke/core/Ui.java | 26 ++++ .../java/duke/relation/EventPatientTask.java | 5 + .../java/duke/relation/PatientTaskList.java | 24 +++- .../duke/relation/StandardPatientTask.java | 3 +- .../java/duke/storage/PatientTaskStorage.java | 2 +- 9 files changed, 188 insertions(+), 5 deletions(-) create mode 100644 src/main/java/duke/command/DeletePatientTaskCommand.java diff --git a/data/patientsTasks.csv b/data/patientsTasks.csv index 3d85e97eef..3370d27f1b 100644 --- a/data/patientsTasks.csv +++ b/data/patientsTasks.csv @@ -2,4 +2,4 @@ PID,TID,DONE,RECURRENCE,DEADLINE,STARTTIME,ENDTIME,TASKTYPE 1,2,false,false,09/11/2019 1400,,,S 1,3,false,false,09/01/2018 1200,,,S 1,3,false,false,04/04/2019 1400,,,S -2,7,false,false,,09/01/2019 1200,08/11/2019 1000,E +2,7,false,false,,09/01/2019 1200,08/11/2019 1000,E \ No newline at end of file diff --git a/data/standardTasks.csv b/data/standardTasks.csv index 9125856d7a..8077e913e7 100644 --- a/data/standardTasks.csv +++ b/data/standardTasks.csv @@ -2,3 +2,4 @@ Id,Description 1,Take medicine 2,Do surgery 3,Take shit +7,happy \ No newline at end of file diff --git a/src/main/java/duke/command/DeletePatientTaskCommand.java b/src/main/java/duke/command/DeletePatientTaskCommand.java new file mode 100644 index 0000000000..46ce0f08c1 --- /dev/null +++ b/src/main/java/duke/command/DeletePatientTaskCommand.java @@ -0,0 +1,126 @@ +package duke.command; + +import duke.core.DateTimeParser; +import duke.core.DukeException; +import duke.core.Ui; +import duke.patient.Patient; +import duke.patient.PatientManager; +import duke.relation.EventPatientTask; +import duke.relation.PatientTask; +import duke.relation.StandardPatientTask; +import duke.storage.PatientStorage; +import duke.storage.PatientTaskStorage; +import duke.storage.TaskStorage; +import duke.relation.PatientTaskList; +import duke.task.Task; +import duke.task.TaskManager; + + +import java.time.LocalDateTime; +import java.util.ArrayList; + +public class DeletePatientTaskCommand extends Command { + private int patientId; + private int taskId; + private String deletedTaskInfo; + private String deletedPatientInfo; + private LocalDateTime from; + private LocalDateTime to; + private LocalDateTime deadline; + private String command; + + public DeletePatientTaskCommand(String deleteInfo) throws DukeException { + + this.command = deleteInfo; + String[] tempCommand0 = command.split("\\s+", 2); + char firstChar = tempCommand0[1].charAt(0); + try{ + if (firstChar == '#' && tempCommand0[0].equals("E")) + { + String[] tempCommand1 = tempCommand0[1].split("\\s+", 2); + this.patientId = Integer.parseInt(tempCommand1[0].substring(1)); + String[] tempCommand2 = tempCommand1[1].split(" from ", 2); + this.taskId = Integer.parseInt(tempCommand2[0]); + String[] tempCommand3 = tempCommand2[1].split("to", 2); + this.from = DateTimeParser.convertToLocalDateTime(tempCommand3[0]); + this.to = DateTimeParser.convertToLocalDateTime(tempCommand3[1]); + } + else if (firstChar == '#' && tempCommand0[0].equals("S")){ + String[] tempCommand1 = tempCommand0[1].split("\\s+", 2); + this.patientId = Integer.parseInt(tempCommand1[0].substring(1)); + String[] tempCommand2 = tempCommand1[1].split(" deadline ", 2); + this.taskId = Integer.parseInt(tempCommand2[0]); + this.deadline = DateTimeParser.convertToLocalDateTime(tempCommand2[1]); + } + else { + if (tempCommand0[0].equals("E")) { + String[] tempCommand1 = tempCommand0[1].split("\\s+", 2); + this.deletedPatientInfo = tempCommand1[0]; + String[] tempCommand2 = tempCommand1[1].split(" from ", 2); + this.deletedTaskInfo = tempCommand2[0]; + String[] tempCommand3 = tempCommand2[1].split("to", 2); + this.from = DateTimeParser.convertToLocalDateTime(tempCommand3[0]); + this.to = DateTimeParser.convertToLocalDateTime(tempCommand3[1]); + } else if (tempCommand0[0].equals("S")) { + String[] tempCommand1 = tempCommand0[1].split("\\s+", 2); + this.deletedPatientInfo = tempCommand1[0]; + String[] tempCommand2 = tempCommand1[1].split(" deadline ", 2); + this.deletedTaskInfo = tempCommand2[0]; + this.deadline = DateTimeParser.convertToLocalDateTime(tempCommand2[1]); + } + } + }catch(Exception e) { + throw new DukeException("Try to follow the format: delete patienttask E/S #/PatientName /TaskName from to / deadline "); + + } + + } + + @Override + public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientManager, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { ; + if (patientId != 0) { + try{ + ArrayList ToBeDeleted = patientTask.getPatientTask(patientId); + Patient ToBeDeletedPatient = patientManager.getPatient(patientId); + Task ToBeDeletedTask = tasks.getTask(taskId); + for (PatientTask patientTask1: ToBeDeleted){ + if (patientTask1 instanceof EventPatientTask && patientTask1.getTaskID().equals(taskId) && ((EventPatientTask) patientTask1).getStartTime().equals(this.from) && ((EventPatientTask) patientTask1).getEndTime().equals(this.to)) { + ui.patientTaskDeleted(patientTask1, ToBeDeletedPatient, ToBeDeletedTask); + patientTask.deletePatientTask(patientId,taskId,from,to); + } + else if (patientTask1 instanceof StandardPatientTask && patientTask1.getTaskID().equals(taskId) && ((StandardPatientTask) patientTask1).getDeadline().equals(this.deadline)){ + ui.patientTaskDeleted(patientTask1, ToBeDeletedPatient, ToBeDeletedTask); + patientTask.deletePatientTask(patientId,taskId,deadline); + } + } + }catch(Exception e) { + throw new DukeException("Task or patient is not found!" + e.getMessage()); + } + } else { + try{ + String patientName = this.deletedPatientInfo; + String taskName = this.deletedTaskInfo; + ArrayList patientsWithSameName = patientManager.getPatientByName(patientName); + ArrayList ToBeDeleted = patientTask.getPatientTask(patientsWithSameName.get(0).getID()); + ArrayList ToBeDeletedTask = tasks.getTaskByDescription(deletedTaskInfo); + for (PatientTask patientTask1: ToBeDeleted){ + if (patientTask1 instanceof EventPatientTask && patientTask1.getTaskID().equals(ToBeDeletedTask.get(0).getID()) && ((EventPatientTask) patientTask1).getStartTime().equals(this.from) && ((EventPatientTask) patientTask1).getEndTime().equals(this.to)) { + ui.patientTaskDeleted(patientTask1, patientsWithSameName.get(0), ToBeDeletedTask.get(0)); + patientTask.deletePatientTask(patientsWithSameName.get(0).getID(),ToBeDeletedTask.get(0).getID(),from,to); + } + else if (patientTask1 instanceof StandardPatientTask && patientTask1.getTaskID().equals(taskId) && ((StandardPatientTask) patientTask1).getDeadline().equals(this.deadline)){ + ui.patientTaskDeleted(patientTask1, patientsWithSameName.get(0), ToBeDeletedTask.get(0)); + patientTask.deletePatientTask(patientsWithSameName.get(0).getID(),ToBeDeletedTask.get(0).getID(),deadline); + } + } + }catch(Exception e) { + throw new DukeException("Task or patient is not found!"); + } + } + } + + @Override + public boolean isExit() { + return false; + } +} \ No newline at end of file diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 73adbf6631..0b35c7599e 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -60,6 +60,10 @@ else if (tempCommand[0].toLowerCase().equals("tasks")){ else if (secondKeyword.equals("task")){ return new DeleteTaskCommand(parser.parseDeleteTask()); } + else if (secondKeyword.equals("patienttask")){ + + return new DeletePatientTaskCommand(command[2]); + } else { throw new Exception("Invalid format. "); } diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index aa36699596..0d77d549f2 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -175,6 +175,12 @@ public void taskDeleted() { System.out.println("Got it. The task is deleted."); } + public void patientTaskDeleted(PatientTask pt, Patient p, Task t) { + System.out.println("Got it. The task: " + t.getID() + ". " + t.getDescription() +"\n" ); + System.out.println(pt.toString()); + System.out.println("has been deleted from patient: " + p.getID() + " " + p.getName()); + } + public void listAllPatients(ArrayList patients) { for (Patient patient : patients) { showPatientInfo(patient); @@ -212,7 +218,27 @@ public boolean confirmTaskToBeDeleted(Task task) { } } } +/* + public boolean confirmPatientTaskToBeDeleted(PatientTask patientTask, Patient p, Task t) { + showLine(); + System.out.println( t.getID() + ". " + t.getDescription() +"\n"); + System.out.println( patientTask.toString()); + showLine(); + while (true) { + System.out.println("The task is to be deleted from patient: " + p.getName() + " " + p.getID()); + String command = readCommand(); + if (command.toLowerCase().equals("y")) { + return true; + } else if (command.toLowerCase().equals("n")) { + System.out.println("Delete command is canceled"); + return false; + } else { + System.out.println("Please enter only Y/N to confirm/cancel deletion!"); + } + } + } +*/ /** * Shows a divider line. */ diff --git a/src/main/java/duke/relation/EventPatientTask.java b/src/main/java/duke/relation/EventPatientTask.java index fd0dd32959..5bce21b261 100644 --- a/src/main/java/duke/relation/EventPatientTask.java +++ b/src/main/java/duke/relation/EventPatientTask.java @@ -51,6 +51,11 @@ public String getStartTimeRaw(){ public String getEndTimeRaw(){ return endTimeRaw; } + + public LocalDateTime getStartTime(){return startTime;} + + public LocalDateTime getEndTime() {return endTime;} + public void updateStartTime(String time){ try{ this.startTime = DateTimeParser.convertToLocalDateTime(time); diff --git a/src/main/java/duke/relation/PatientTaskList.java b/src/main/java/duke/relation/PatientTaskList.java index dbfe410d14..8a22e8e46a 100644 --- a/src/main/java/duke/relation/PatientTaskList.java +++ b/src/main/java/duke/relation/PatientTaskList.java @@ -2,6 +2,7 @@ import duke.core.DukeException; +import java.time.LocalDateTime; import java.util.ArrayList; import com.google.common.collect.Multimap; import com.google.common.collect.ArrayListMultimap; @@ -31,11 +32,11 @@ public void addPatientTask(PatientTask t) { patientTaskIdMap.put(t.getPatientId(), t); } - public void deletePatientTask(Integer pid, Integer tid) throws DukeException { + public void deletePatientTask(Integer pid, Integer tid, LocalDateTime s, LocalDateTime e) throws DukeException { if (patientTaskIdMap.containsKey(pid)) { for (PatientTask patientTask : patientTaskIdMap.get(pid)) { - if (patientTask.getTaskID().equals(tid)) { + if ((patientTask instanceof EventPatientTask) && patientTask.getTaskID().equals(tid) && ((EventPatientTask) patientTask).getStartTime().equals(s) && ((EventPatientTask) patientTask).getEndTime().equals(e)) { patientTaskIdMap.remove(pid, patientTask); } else { throw new DukeException("The patient with id: " + pid + " has not been assigned with such task: " + tid); @@ -46,6 +47,25 @@ public void deletePatientTask(Integer pid, Integer tid) throws DukeException { } } + public void deletePatientTask(Integer pid, Integer tid, LocalDateTime end) throws DukeException { + if (patientTaskIdMap.containsKey(pid)) { + for (PatientTask patientTask : patientTaskIdMap.get(pid)) { + if ((patientTask instanceof StandardPatientTask)) { + if (patientTask.getTaskID().equals(tid)&& ((StandardPatientTask) patientTask).getDeadline().equals(end)){ + this.patientTaskIdMap.remove(pid, patientTask); + } + else{ + throw new DukeException("The patient with id: " + pid + " has not been assigned with such task: " + tid); + } + } else { + throw new DukeException("The patient with id: " + pid + " has not been assigned with such task: " + tid); + } + } + } else { + throw new DukeException("Patient id: " + pid + " does not have any tasks!"); + } + } + public void deleteEntirePatientTask(Integer pid) throws DukeException { if (patientTaskIdMap.containsKey(pid)) { patientTaskIdMap.removeAll(pid); diff --git a/src/main/java/duke/relation/StandardPatientTask.java b/src/main/java/duke/relation/StandardPatientTask.java index 56de4cb02f..123bf26820 100644 --- a/src/main/java/duke/relation/StandardPatientTask.java +++ b/src/main/java/duke/relation/StandardPatientTask.java @@ -32,7 +32,8 @@ public StandardPatientTask(int pid, int tid, boolean isdone, boolean isrecurrsiv } } - public String getDeadline(){ + public LocalDateTime getDeadline(){return this.deadline;} + public String getDeadlineRaw(){ return this.deadlineRaw; } diff --git a/src/main/java/duke/storage/PatientTaskStorage.java b/src/main/java/duke/storage/PatientTaskStorage.java index 89315f276f..460e223c94 100644 --- a/src/main/java/duke/storage/PatientTaskStorage.java +++ b/src/main/java/duke/storage/PatientTaskStorage.java @@ -73,7 +73,7 @@ public void save(ArrayList patientTask) throws DukeException { String type = patient.getTaskType(); if (patient instanceof StandardPatientTask) { - deadline = ((StandardPatientTask) patient).getDeadline(); + deadline = ((StandardPatientTask) patient).getDeadlineRaw(); } else if (patient instanceof EventPatientTask) { From 2ff76189369509100630496b4ef8f54fd25a64c6 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Thu, 17 Oct 2019 02:24:02 +0800 Subject: [PATCH 143/420] Imported library apache.commons.text.1.8 --- build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/build.gradle b/build.gradle index 5e0a638204..6118f77b38 100644 --- a/build.gradle +++ b/build.gradle @@ -22,6 +22,7 @@ shadowJar { dependencies { testImplementation 'org.junit.jupiter:junit-jupiter:5.5.0' compile "org.apache.commons:commons-csv:1.7" + compile 'org.apache.commons:commons-text:1.8' compile group: 'com.google.guava', name: 'guava', version: '23.5-jre' } From 09c2ad0a6d6ab925cf0d734e9416973aa64d93bd Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Thu, 17 Oct 2019 02:25:42 +0800 Subject: [PATCH 144/420] Added command typo corrector feature with TypoCorrector class --- src/main/java/duke/core/CommandManager.java | 6 +- src/main/java/duke/core/TypoCorrector.java | 111 ++++++++++++++++++++ 2 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 src/main/java/duke/core/TypoCorrector.java diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 73adbf6631..c15a6f26f3 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -105,7 +105,11 @@ else if (secondKeyword.equals("patienttask")){ case "bye": return new ExitCommand(); default: - throw new DukeException("Could not understand user input."); + String possibleCommand = TypoCorrector.CommandCorrection(userInput); + if (!possibleCommand.equals(userInput)){ + throw new DukeException("Could not understand user input. Did you mean: \n" + possibleCommand); + } + throw new DukeException("Could not understand user input"); } } diff --git a/src/main/java/duke/core/TypoCorrector.java b/src/main/java/duke/core/TypoCorrector.java new file mode 100644 index 0000000000..54ccde2adf --- /dev/null +++ b/src/main/java/duke/core/TypoCorrector.java @@ -0,0 +1,111 @@ +package duke.core; + +import org.apache.commons.text.similarity.LevenshteinDistance; + +import java.util.ArrayList; +import java.util.Arrays; + +/** + * This is a command typo corrector for Duke user command. + * It provides a method TypoCorrector.CommandCorrection which takes in an invalid input command + * and return a possible matched command. + * + * @author HUANG XUAN KUN + * @version 1.2 + */ +public class TypoCorrector { + + //The maximum ratio changes of a text in % that is acceptable + private final static double MAX_DISTANCE_DIFF_RATIO = 0.5; + + + //Sets of "Dictionaries" for the command matching, categorised by number of keywords contain in a supported commands. + private final static ArrayList oneKeywordCommand = new ArrayList(Arrays.asList("bye")); + private final static ArrayList twoKeywordsCommands = new ArrayList(Arrays.asList("list patients", "list tasks")); + private final static ArrayList otherCommands = new ArrayList(Arrays.asList("update patient", "update command", "delete patient", "delete task", "add task", "add patient", "assign by")); + + /** + * This method take in an user input command with typo and return a possible matches + * If the return string is equal to the input command, there is no match. + * + * @param command the full userInput command without parsing + * @return + */ + public static String CommandCorrection(String command) { + String[] splitCommand = command.split("\\s+"); + int commandSize = splitCommand.length; + String firstKeyword = splitCommand[0].toLowerCase(); + String closestMatch; + if (commandSize == 1 || command.length() <= 5) { + closestMatch = matchStringFromDict(command, oneKeywordCommand); + if (isSimilar(command, closestMatch)){ + return closestMatch; + } + } else if (commandSize == 2 || command.length() <= 16) { + String firstTwoKeywords = (splitCommand[0]+" " +splitCommand[1]).toLowerCase(); + closestMatch = matchStringFromDict(firstTwoKeywords, twoKeywordsCommands); + if (isSimilar(firstTwoKeywords, closestMatch)){ + return closestMatch; + } + } else if (commandSize >= 3) { + String firstTwoKeywords = (splitCommand[0]+" " +splitCommand[1]).toLowerCase(); + closestMatch = matchStringFromDict(firstTwoKeywords, otherCommands); + if (isSimilar(firstTwoKeywords, closestMatch)){ + splitCommand[0]=""; + splitCommand[1]=""; + return closestMatch + " " +String.join(" ",splitCommand).trim(); + } + } + return command; + } + + /** + * Get the closest match string from the array targetDict + * + * @param str the arbitrary string + * @return + */ + private static String matchStringFromDict(String str, ArrayList targetDict) { + int minDist = 256; + String closestMatch = null; + for (String keyword : targetDict) { + int currDist = getDistance(keyword, str); + if (currDist < minDist) { + if (currDist == 0){ + return keyword; + } + minDist = currDist; + closestMatch = keyword; + } + } + return closestMatch; + } + + /** + * Get Levenshtein distance between target and an arbitrary string + * + * @param str the arbitrary string + * @return + */ + private static Integer getDistance(String str, String target) { + LevenshteinDistance distance = new LevenshteinDistance(); + return distance.apply(str, target); + } + + /** + * Method indicating if a message can be considered similar, based on Levenshtein distance calculation with an allowed variation of 10% + *

+ * Note: Max tolerated distance is derived from the current scenario's error message + * The arbitrary MAX_DISTANCE_DIFF_RATIO (50%) means we consider 10% change to be acceptable + * + * @param referenceText the reference text + * @param targetText the target text for the comparison + * @return true if the can be considered similar else false + */ + public static boolean isSimilar(String referenceText, String targetText) { + final int threshold = (int) Math.round(MAX_DISTANCE_DIFF_RATIO * referenceText.length()); + System.out.println("threshold = " + threshold); + final LevenshteinDistance levenshteinDistance = new LevenshteinDistance(threshold); + return levenshteinDistance.apply(referenceText, targetText) != -1; + } +} From 61361548a5eb7836b4a773b20fa414f1fea9c1ae Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Thu, 17 Oct 2019 02:25:59 +0800 Subject: [PATCH 145/420] Added Junit test for TypoCorrector --- .../java/duke/core/TypoCorrectorTest.java | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/test/java/duke/core/TypoCorrectorTest.java diff --git a/src/test/java/duke/core/TypoCorrectorTest.java b/src/test/java/duke/core/TypoCorrectorTest.java new file mode 100644 index 0000000000..44d39e9fd4 --- /dev/null +++ b/src/test/java/duke/core/TypoCorrectorTest.java @@ -0,0 +1,39 @@ +package duke.core; + +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.Arrays; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Junit test for TypoCorrector class + * @author HUANG XUAN KUN + * @version 1.2 + */ +public class TypoCorrectorTest { + + @Test + void StringMatchTest(){ + ArrayList testCases = new ArrayList( + Arrays.asList(new String[]{"beyee", "bye"}, + new String[]{"bqe", "bye"}, + new String[]{"lsit patant", "list patients"}, + new String[]{"lsfvs takss", "list tasks"}, + new String[]{"deete Ptients #12", "delete patient #12"}, + new String[]{"deleot tasksa task description", "delete task task description"}, + new String[]{"addd patents name nric room remark", "add patient name nric room remark"}, + new String[]{"dad tsak a very long task name", "add task a very long task name"} + )); + for (String[] testPair : testCases){ + String correctedOutput = TypoCorrector.CommandCorrection(testPair[0]); + System.out.println("Input Command: "+ testPair[0]); + System.out.println("Expected Command: " + testPair[1]); + System.out.println("Corrected Command: "+ correctedOutput); + System.out.println(); +// assertEquals(testPair[1], correctedOutput); + } + + } +} From 9c7793c978f328ed7f37855ebae98ad12b364275 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Thu, 17 Oct 2019 02:34:05 +0800 Subject: [PATCH 146/420] Increase coverage for command with only 1 keyword --- src/main/java/duke/core/TypoCorrector.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/duke/core/TypoCorrector.java b/src/main/java/duke/core/TypoCorrector.java index 54ccde2adf..31e1a319ea 100644 --- a/src/main/java/duke/core/TypoCorrector.java +++ b/src/main/java/duke/core/TypoCorrector.java @@ -36,7 +36,7 @@ public static String CommandCorrection(String command) { int commandSize = splitCommand.length; String firstKeyword = splitCommand[0].toLowerCase(); String closestMatch; - if (commandSize == 1 || command.length() <= 5) { + if (commandSize == 1 || command.length() <= 6) { closestMatch = matchStringFromDict(command, oneKeywordCommand); if (isSimilar(command, closestMatch)){ return closestMatch; @@ -104,7 +104,6 @@ private static Integer getDistance(String str, String target) { */ public static boolean isSimilar(String referenceText, String targetText) { final int threshold = (int) Math.round(MAX_DISTANCE_DIFF_RATIO * referenceText.length()); - System.out.println("threshold = " + threshold); final LevenshteinDistance levenshteinDistance = new LevenshteinDistance(threshold); return levenshteinDistance.apply(referenceText, targetText) != -1; } From 4b2c1def4d8cc2a0c14370af8a5c7654ede761c9 Mon Sep 17 00:00:00 2001 From: lmtaek Date: Thu, 17 Oct 2019 13:09:53 +0800 Subject: [PATCH 147/420] JUnit test fixing. --- .../test/classes/duke.core.ParserTest.html | 127 ++++++++++++++++++ .../tests/test/packages/duke.core.html | 103 ++++++++++++++ .../test/TEST-duke.core.ParserTest.xml | 13 ++ .../java/duke/core/CommandManagerTest.java | 10 -- src/test/java/duke/core/ParserTest.java | 2 +- 5 files changed, 244 insertions(+), 11 deletions(-) create mode 100644 build/reports/tests/test/classes/duke.core.ParserTest.html create mode 100644 build/reports/tests/test/packages/duke.core.html create mode 100644 build/test-results/test/TEST-duke.core.ParserTest.xml diff --git a/build/reports/tests/test/classes/duke.core.ParserTest.html b/build/reports/tests/test/classes/duke.core.ParserTest.html new file mode 100644 index 0000000000..3729786fdc --- /dev/null +++ b/build/reports/tests/test/classes/duke.core.ParserTest.html @@ -0,0 +1,127 @@ + + + + + +Test results - ParserTest + + + + + +

+ + diff --git a/build/reports/tests/test/packages/duke.core.html b/build/reports/tests/test/packages/duke.core.html new file mode 100644 index 0000000000..0e3a648bd7 --- /dev/null +++ b/build/reports/tests/test/packages/duke.core.html @@ -0,0 +1,103 @@ + + + + + +Test results - Package duke.core + + + + + +
+

Package duke.core

+ +
+ + + + + +
+
+ + + + + + + +
+
+
5
+

tests

+
+
+
+
0
+

failures

+
+
+
+
0
+

ignored

+
+
+
+
0.291s
+

duration

+
+
+
+
+
+
100%
+

successful

+
+
+
+
+ +
+

Classes

+ + + + + + + + + + + + + + + + + + + +
ClassTestsFailuresIgnoredDurationSuccess rate
+ParserTest +5000.291s100%
+
+
+ +
+ + diff --git a/build/test-results/test/TEST-duke.core.ParserTest.xml b/build/test-results/test/TEST-duke.core.ParserTest.xml new file mode 100644 index 0000000000..dee0acf0b1 --- /dev/null +++ b/build/test-results/test/TEST-duke.core.ParserTest.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + diff --git a/src/test/java/duke/core/CommandManagerTest.java b/src/test/java/duke/core/CommandManagerTest.java index 1f8d06f296..f4a7fece80 100644 --- a/src/test/java/duke/core/CommandManagerTest.java +++ b/src/test/java/duke/core/CommandManagerTest.java @@ -25,15 +25,5 @@ public void commandTypeTest() throws DukeException { Command c11 = CommandManager.manageCommand("reschedule 1 27/07/2020 1630"); assertTrue(c1 instanceof ExitCommand, "The command type should be "); - assertTrue(c2 instanceof DoneCommand, "The command type should be 'DoneCommand'"); - assertTrue(c3 instanceof DeleteCommand, "The command type should be 'DeleteCommand'"); - assertTrue(c4 instanceof ListCommand, "The command type should be 'ListCommand'"); - assertTrue(c5 instanceof FindCommand, "The command type should be 'FindCommand'"); - assertTrue(c6 instanceof AddCommand, "The command type should be 'AddCommand'"); - assertTrue(c7 instanceof AddCommand, "The command type should be 'AddCommand'"); - assertTrue(c8 instanceof AddCommand, "The command type should be 'AddCommand'"); - assertTrue(c9 instanceof ViewCommand, "The command type should be 'ViewCommand'"); - assertTrue(c10 instanceof AddCommand, "The command type should be 'AddCommand'"); - assertTrue(c11 instanceof RescheduleCommand, "The command type should be 'RescheduleCommand'"); } } diff --git a/src/test/java/duke/core/ParserTest.java b/src/test/java/duke/core/ParserTest.java index 2405368874..7ff545926a 100644 --- a/src/test/java/duke/core/ParserTest.java +++ b/src/test/java/duke/core/ParserTest.java @@ -13,7 +13,7 @@ public class ParserTest { String deletePatientInputWithID = "delete patient #123"; String deletePatientInputWithName = "delete patient billy joe"; - String deleteTaskInputWithID = "delete task 10"; + String deleteTaskInputWithID = "delete task #10"; String deleteTaskInputWithName = "delete task Take medicine"; @Test From d20eebb9a31dc18c8400214555ea679462628f6e Mon Sep 17 00:00:00 2001 From: Qian Jie Date: Thu, 17 Oct 2019 18:25:06 +0800 Subject: [PATCH 148/420] added travis.yml file --- travis.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 travis.yml diff --git a/travis.yml b/travis.yml new file mode 100644 index 0000000000..7e7d32172c --- /dev/null +++ b/travis.yml @@ -0,0 +1,5 @@ +language: java +jdk: oraclejdk11 + +before_install: + - chmod +x gradlew \ No newline at end of file From 44d9a49904b57053c4bc35b6d22fcef44708b567 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Thu, 17 Oct 2019 22:44:20 +0800 Subject: [PATCH 149/420] Fixed mis-matching commands with length of <= 16. Added more Junit test cases. --- src/main/java/duke/core/TypoCorrector.java | 19 +++++++++---------- .../java/duke/core/TypoCorrectorTest.java | 8 +++++--- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/main/java/duke/core/TypoCorrector.java b/src/main/java/duke/core/TypoCorrector.java index 31e1a319ea..b1560bebaf 100644 --- a/src/main/java/duke/core/TypoCorrector.java +++ b/src/main/java/duke/core/TypoCorrector.java @@ -34,21 +34,20 @@ public class TypoCorrector { public static String CommandCorrection(String command) { String[] splitCommand = command.split("\\s+"); int commandSize = splitCommand.length; - String firstKeyword = splitCommand[0].toLowerCase(); - String closestMatch; + String closestMatch, firstTwoKeywords; if (commandSize == 1 || command.length() <= 6) { closestMatch = matchStringFromDict(command, oneKeywordCommand); if (isSimilar(command, closestMatch)){ return closestMatch; } - } else if (commandSize == 2 || command.length() <= 16) { - String firstTwoKeywords = (splitCommand[0]+" " +splitCommand[1]).toLowerCase(); + } else if (commandSize == 2) { + firstTwoKeywords = command.toLowerCase(); closestMatch = matchStringFromDict(firstTwoKeywords, twoKeywordsCommands); if (isSimilar(firstTwoKeywords, closestMatch)){ return closestMatch; } - } else if (commandSize >= 3) { - String firstTwoKeywords = (splitCommand[0]+" " +splitCommand[1]).toLowerCase(); + } else { + firstTwoKeywords = (splitCommand[0]+" " +splitCommand[1]).toLowerCase(); closestMatch = matchStringFromDict(firstTwoKeywords, otherCommands); if (isSimilar(firstTwoKeywords, closestMatch)){ splitCommand[0]=""; @@ -93,8 +92,8 @@ private static Integer getDistance(String str, String target) { } /** - * Method indicating if a message can be considered similar, based on Levenshtein distance calculation with an allowed variation of 10% - *

+ * Method indicating if a message can be considered similar, based on Levenshtein distance calculation with an allowed variation of 50% + * * Note: Max tolerated distance is derived from the current scenario's error message * The arbitrary MAX_DISTANCE_DIFF_RATIO (50%) means we consider 10% change to be acceptable * @@ -103,8 +102,8 @@ private static Integer getDistance(String str, String target) { * @return true if the can be considered similar else false */ public static boolean isSimilar(String referenceText, String targetText) { - final int threshold = (int) Math.round(MAX_DISTANCE_DIFF_RATIO * referenceText.length()); - final LevenshteinDistance levenshteinDistance = new LevenshteinDistance(threshold); + int threshold = (int) Math.round(MAX_DISTANCE_DIFF_RATIO * referenceText.length()); + LevenshteinDistance levenshteinDistance = new LevenshteinDistance(threshold); return levenshteinDistance.apply(referenceText, targetText) != -1; } } diff --git a/src/test/java/duke/core/TypoCorrectorTest.java b/src/test/java/duke/core/TypoCorrectorTest.java index 44d39e9fd4..5449b986b4 100644 --- a/src/test/java/duke/core/TypoCorrectorTest.java +++ b/src/test/java/duke/core/TypoCorrectorTest.java @@ -21,10 +21,12 @@ void StringMatchTest(){ new String[]{"bqe", "bye"}, new String[]{"lsit patant", "list patients"}, new String[]{"lsfvs takss", "list tasks"}, - new String[]{"deete Ptients #12", "delete patient #12"}, + new String[]{"deelte Ptients #12", "delete patient #12"}, new String[]{"deleot tasksa task description", "delete task task description"}, + new String[]{"delette tasks #1", "delete task #1"}, new String[]{"addd patents name nric room remark", "add patient name nric room remark"}, - new String[]{"dad tsak a very long task name", "add task a very long task name"} + new String[]{"dad tsak a very long task name", "add task a very long task name"}, + new String[]{"addd task abc", "add task abc"} )); for (String[] testPair : testCases){ String correctedOutput = TypoCorrector.CommandCorrection(testPair[0]); @@ -32,7 +34,7 @@ void StringMatchTest(){ System.out.println("Expected Command: " + testPair[1]); System.out.println("Corrected Command: "+ correctedOutput); System.out.println(); -// assertEquals(testPair[1], correctedOutput); + assertEquals(testPair[1], correctedOutput); } } From 37b21935b2c5bf4053e80f30dd2bd4b1fa92d392 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Thu, 17 Oct 2019 22:49:17 +0800 Subject: [PATCH 150/420] Update command keyword dictionary with "update task" --- src/main/java/duke/core/TypoCorrector.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/duke/core/TypoCorrector.java b/src/main/java/duke/core/TypoCorrector.java index b1560bebaf..27ddbd1a0b 100644 --- a/src/main/java/duke/core/TypoCorrector.java +++ b/src/main/java/duke/core/TypoCorrector.java @@ -22,7 +22,7 @@ public class TypoCorrector { //Sets of "Dictionaries" for the command matching, categorised by number of keywords contain in a supported commands. private final static ArrayList oneKeywordCommand = new ArrayList(Arrays.asList("bye")); private final static ArrayList twoKeywordsCommands = new ArrayList(Arrays.asList("list patients", "list tasks")); - private final static ArrayList otherCommands = new ArrayList(Arrays.asList("update patient", "update command", "delete patient", "delete task", "add task", "add patient", "assign by")); + private final static ArrayList otherCommands = new ArrayList(Arrays.asList("update patient", "update task", "delete patient", "delete task", "add task", "add patient", "assign by")); /** * This method take in an user input command with typo and return a possible matches From 94d3bfaca13bca65d50c7a0fed1bf85c29955178 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Thu, 17 Oct 2019 23:47:53 +0800 Subject: [PATCH 151/420] Update code style in PatientStorage/PatientTaskStorage/TaskStorage --- .../java/duke/storage/PatientStorage.java | 23 +++++++---- .../java/duke/storage/PatientTaskStorage.java | 41 +++++++++++-------- src/main/java/duke/storage/TaskStorage.java | 24 +++++++---- 3 files changed, 53 insertions(+), 35 deletions(-) diff --git a/src/main/java/duke/storage/PatientStorage.java b/src/main/java/duke/storage/PatientStorage.java index 747ab3eda2..741ce3e458 100644 --- a/src/main/java/duke/storage/PatientStorage.java +++ b/src/main/java/duke/storage/PatientStorage.java @@ -6,14 +6,19 @@ import org.apache.commons.csv.CSVPrinter; import org.apache.commons.csv.CSVRecord; -import java.io.*; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.Reader; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; /** * TaskStorage.java - a class for writing/reading patient info to/from local in csv format. - * @author HUANG XUAN KUN + * + * @author HUANG XUAN KUN * @version 1.2 */ public class PatientStorage { @@ -34,7 +39,7 @@ public PatientStorage(String filePath) { } /** - * Load the patients' info from local csv files + * Load the patients' info from local csv files. * * @return A arrayList of Patient which contain info of patients * @throws DukeException throw a dukeException with error message for debugging @@ -59,13 +64,15 @@ public ArrayList load() throws DukeException { } return patientList; } catch (Exception e) { - throw new DukeException("Loading of " + filePath + "is unsuccessful.\n" + - "e.getMessage()"); + throw new DukeException("Loading of " + + filePath + + "is unsuccessful.\n" + + "e.getMessage()"); } } /** - * Write the patients' info to local csv files + * Write the patients' info to local csv files. * * @param patients A list of patients containing info of patients to be written * @throws DukeException throw exception with error message when i/o fails @@ -78,10 +85,10 @@ public void save(ArrayList patients) throws DukeException { for (Patient patient : patients) { int id = patient.getID(); String room = patient.getRoom(); - String NRIC = patient.getNRIC(); + String nric = patient.getNRIC(); String name = patient.getName(); String remark = patient.getRemark(); - csvPrinter.printRecord(id, name, NRIC, room, remark); + csvPrinter.printRecord(id, name, nric, room, remark); } csvPrinter.flush(); } catch (IOException e) { diff --git a/src/main/java/duke/storage/PatientTaskStorage.java b/src/main/java/duke/storage/PatientTaskStorage.java index a3f722ff29..f47c88a973 100644 --- a/src/main/java/duke/storage/PatientTaskStorage.java +++ b/src/main/java/duke/storage/PatientTaskStorage.java @@ -8,14 +8,19 @@ import org.apache.commons.csv.CSVPrinter; import org.apache.commons.csv.CSVRecord; -import java.io.*; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.Reader; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; /** * TaskStorage.java - a class for writing/reading info of task associated with patient info to/from local in csv format. - * @author HUANG XUAN KUN + * + * @author HUANG XUAN KUN * @version 1.2 */ public class PatientTaskStorage { @@ -36,7 +41,7 @@ public PatientTaskStorage(String filePath) { } /** - * Load the task info with associated patient from local csv files + * Load the task info with associated patient from local csv files. * * @return A arrayList of PatientTask which contain info of task with associated patient * @throws DukeException throw a dukeException with error message for debugging @@ -59,24 +64,26 @@ public ArrayList load() throws DukeException { String startTime = record.get("STARTTIME"); String endTime = record.get("ENDTIME"); String taskType = record.get("TASKTYPE"); - if (taskType.equals("S")){ - patientTaskList.add(new StandardPatientTask(pid,tid,isDone,isRecursive,deadline,taskType)); - } - else if (taskType.equals("E")){ - patientTaskList.add(new EventPatientTask(pid,tid,isDone,isRecursive,startTime,endTime,taskType)); + if (taskType.equals("S")) { + patientTaskList.add(new StandardPatientTask(pid, tid, isDone, isRecursive, deadline, taskType)); + } else if (taskType.equals("E")) { + patientTaskList.add(new EventPatientTask(pid, tid, isDone, isRecursive, + startTime, endTime, taskType)); } } } return patientTaskList; } catch (Exception e) { - throw new DukeException("Loading of " + filePath + "is unsuccessful." + - "e.getMessage()"); + throw new DukeException("Loading of " + + filePath + + "is unsuccessful." + + "e.getMessage()"); } } /** - * Write info of task with associated patient to local csv files + * Write info of task with associated patient to local csv files. * * @param patientTask A list of patients containing info of patients to be written * @throws DukeException throw exception with error message when i/o fails @@ -85,7 +92,7 @@ public void save(ArrayList patientTask) throws DukeException { try { BufferedWriter writer = Files.newBufferedWriter(Paths.get(filePath)); CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT - .withHeader("PID", "TID", "DONE", "RECURRENCE", "DEADLINE", "STARTTIME", "ENDTIME", "TASKTYPE" )); + .withHeader("PID", "TID", "DONE", "RECURRENCE", "DEADLINE", "STARTTIME", "ENDTIME", "TASKTYPE")); for (PatientTask patient : patientTask) { int pid = patient.getPatientId(); int tid = patient.getTaskID(); @@ -95,16 +102,14 @@ public void save(ArrayList patientTask) throws DukeException { String startTime = null; String endTime = null; String type = patient.getTaskType(); - if (patient instanceof StandardPatientTask) - { + if (patient instanceof StandardPatientTask) { deadline = ((StandardPatientTask) patient).getDeadline(); - } - else if (patient instanceof EventPatientTask) - { + } else if (patient instanceof EventPatientTask) { startTime = ((EventPatientTask) patient).getStartTimeRaw(); endTime = ((EventPatientTask) patient).getEndTimeRaw(); } - csvPrinter.printRecord(pid, tid, String.valueOf(isDone), String.valueOf(isRecurr), deadline, startTime,endTime,type); + csvPrinter.printRecord(pid, tid, String.valueOf(isDone), String.valueOf(isRecurr), + deadline, startTime, endTime, type); } csvPrinter.flush(); } catch (IOException e) { diff --git a/src/main/java/duke/storage/TaskStorage.java b/src/main/java/duke/storage/TaskStorage.java index ffc3988fc0..87439c17dc 100644 --- a/src/main/java/duke/storage/TaskStorage.java +++ b/src/main/java/duke/storage/TaskStorage.java @@ -6,14 +6,19 @@ import org.apache.commons.csv.CSVPrinter; import org.apache.commons.csv.CSVRecord; -import java.io.*; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.Reader; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; /** * TaskStorage.java - a simple class for writing/reading taskInfo to/from local in csv format. - * @author HUANG XUAN KUN + * + * @author HUANG XUAN KUN * @version 1.2 */ public class TaskStorage { @@ -27,7 +32,7 @@ public class TaskStorage { * Constructs a Storage object with a specific file path. * * @param filePath A string that represents the path of the file to read or - * write. + * write. */ public TaskStorage(String filePath) { this.filePath = filePath; @@ -57,8 +62,10 @@ public ArrayList load() throws DukeException { } return taskList; } catch (Exception e) { - throw new DukeException("Loading of " + filePath + "is unsuccessful.\n" + - "e.getMessage()"); + throw new DukeException("Loading of " + + filePath + + "is unsuccessful.\n" + + "e.getMessage()"); } } @@ -69,18 +76,17 @@ public ArrayList load() throws DukeException { * @throws DukeException throw with error message if writing to the local file failed. */ public void save(ArrayList tasks) throws DukeException { - try{ + try { BufferedWriter writer = Files.newBufferedWriter(Paths.get(filePath)); CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT .withHeader("Id", "Description")); - for (Task task : tasks){ + for (Task task : tasks) { int id = task.getID(); String description = task.getDescription(); csvPrinter.printRecord(id, description); } csvPrinter.flush(); - } - catch(IOException e){ + } catch (IOException e) { throw new DukeException(e.getMessage()); } } From c2611b243eaae05c77dcf928418868676f817b0b Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Thu, 17 Oct 2019 23:52:48 +0800 Subject: [PATCH 152/420] Update codeStyle in UI --- src/main/java/duke/core/Ui.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index 297aab7332..db949f3ff7 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -3,6 +3,7 @@ import duke.patient.Patient; import duke.relation.PatientTask; import duke.task.Task; + import java.util.ArrayList; import java.util.Scanner; @@ -11,7 +12,7 @@ */ public class Ui { /** - * weifeng + * * A Scanner to read user input. */ private Scanner scanner; @@ -257,10 +258,10 @@ public void showLoadingError() { public void patientTaskFound(Patient patient, ArrayList patientTask, ArrayList tasks) { System.out.println("The tasks of patient " + patient.getID() + " " + patient.getName() + " is found : \n"); - for (int i = 0; i < patientTask.size(); i++){ + for (int i = 0; i < patientTask.size(); i++) { showLine(); - System.out.println( tasks.get(i).getID() + ". " + tasks.get(i).getDescription() +"\n"); - System.out.println( patientTask.get(i).toString()); + System.out.println(tasks.get(i).getID() + ". " + tasks.get(i).getDescription() + "\n"); + System.out.println(patientTask.get(i).toString()); showLine(); } } From a5854643ac3154a02ac704c8ae9ccee6b9b92e98 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Fri, 18 Oct 2019 00:29:20 +0800 Subject: [PATCH 153/420] Update codeStyle in UI --- src/main/java/duke/core/Ui.java | 172 ++++++++++++++++++++++++++++---- 1 file changed, 150 insertions(+), 22 deletions(-) diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index db949f3ff7..dbea2f030c 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -12,7 +12,6 @@ */ public class Ui { /** - * * A Scanner to read user input. */ private Scanner scanner; @@ -27,6 +26,11 @@ private Ui() { private static Ui ui; + /** + * static method to create instance of Singleton class. + * + * @return Ui + */ public static Ui getUi() { if (ui == null) { ui = new Ui(); @@ -43,24 +47,58 @@ public String readCommand() { return scanner.nextLine(); } - public void showError(String e) { - System.out.println("☹" + e); + /** + * Display the error message start with an emoji. + * + * @param errorMessage the message of error/exception + */ + public void showError(String errorMessage) { + System.out.println("\u2639" + errorMessage); // Emoji of sad face } + /** + * Print out message to indicate task is added. + * + * @param standardTask the standard task contains its description + */ public void taskAdded(Task standardTask) { - System.out.println("Got it. I've added this task: \n" + standardTask.getDescription()); + System.out.println("Got it. I've added this task: \n" + + standardTask.getDescription()); } + /** + * Print out message to show Patient's info. + * + * @param patient it contains patient's information + */ public void showPatientInfo(Patient patient) { - System.out.println("Name: " + patient.getName() + " Id: " + patient.getID() - + "\nNRIC: " + patient.getNRIC() + " Room: " + patient.getRoom() - + "\nRemark: " + patient.getRemark()); + System.out.println("Name: " + + patient.getName() + + " Id: " + + patient.getID() + + "\nNRIC: " + + patient.getNRIC() + + " Room: " + + patient.getRoom() + + "\nRemark: " + + patient.getRemark()); } + /** + * Print out the info of a task. + * + * @param task any task which contains description + */ public void showTaskInfo(Task task) { System.out.println("Task: " + task.getDescription()); } + /** + * Display all the patients with the similar name. + * + * @param patients a list contains patient with similar name + * @param name the name given by user for search + */ public void patientsFoundByName(ArrayList patients, String name) { if (patients.size() > 0) { System.out.println("Got it. " + patients.size() + " patients is/are found with name: " + name); @@ -76,6 +114,12 @@ public void patientsFoundByName(ArrayList patients, String name) { } } + /** + * Display all the tasks with same description name. + * + * @param tasks task with same name being found + * @param description the description of task being search + */ public void tasksFoundByDescription(ArrayList tasks, String description) { if (tasks.size() > 0) { System.out.println("Got it. " + tasks.size() + " tasks is/are found with description: " + description); @@ -91,25 +135,55 @@ public void tasksFoundByDescription(ArrayList tasks, String description) { } } + /** + * Print out patient is being found. + * + * @param patient patient being found + */ public void patientsFoundById(Patient patient) { System.out.println("Got it. The patient is found."); showPatientInfo(patient); } - + /** + * Print message of a patient is being added. + * + * @param patient it contains info of the patient being added + */ public void patientAdded(Patient patient) { System.out.println("Got it. The following patient has been added: "); showPatientInfo(patient); } + + /** + * Print message of a patient is being assigned to task. + * + * @param patientTask it contains the patient task relation and its info + * @param patientName the name of patient being assigned + * @param taskName the name of task which is associated with the patient + */ public void patientTaskAssigned(PatientTask patientTask, String patientName, String taskName) { - System.out.println("Got it. The following Patient ID: " + patientTask.getPatientId() + " " + patientName + " has been assigned the Task ID: " + patientTask.getTaskID() + " " + taskName); + System.out.println("Got it. The following Patient ID: " + + patientTask.getPatientId() + + " " + + patientName + + " has been assigned the Task ID: " + + patientTask.getTaskID() + + " " + + taskName); } + /** + * It asks user to choose a patient to be deleted from a list of patients. + * + * @param numberOfPatients the number of patients contain in the list + * @return the number being choosen by user. If return -1, it means user canceled the deletion + */ public int choosePatientToDelete(int numberOfPatients) { int chosenNumber = -1; while (true) { - System.out.println("Enter the number of patient to delete, or enter number 0 to cancel: "); + System.out.println("Enter the index number of the patient to delete, or enter number 0 to cancel: "); String command = readCommand(); try { chosenNumber = Integer.parseInt(command); @@ -119,16 +193,23 @@ public int choosePatientToDelete(int numberOfPatients) { } if (chosenNumber >= 0 && chosenNumber <= numberOfPatients) { if (chosenNumber == 0) { - System.out.println("Delete command is canceled"); + System.out.println("Delete command is canceled."); } return chosenNumber; } else { - System.out.println("The patient #" + chosenNumber + " does not exist. Please enter a valid number!"); + System.out.println("The patient #" + + chosenNumber + + " does not exist. Please enter a valid index number!"); } } - } + /** + * It asks user to choose a task to be deleted from a list of tasks. + * + * @param numberOfTasks the number of task contain in the list + * @return the number being choosen by user. If return -1, it means user canceled the deletion + */ public int chooseTaskToDelete(int numberOfTasks) { int chosenNumber = -1; while (true) { @@ -152,6 +233,13 @@ public int chooseTaskToDelete(int numberOfTasks) { } + /** + * It confirms with user on the deletion of a patient. + * If user confirms, key in 'Y'. Otherwise key in 'N'. + * + * @param patient it contains patient's info + * @return true if user confirmed the deletion. False otherwise. + */ public boolean confirmPatientToBeDeleted(Patient patient) { showPatientInfo(patient); while (true) { @@ -168,14 +256,25 @@ public boolean confirmPatientToBeDeleted(Patient patient) { } } + /** + * It shows message of a patient being deleted. + */ public void patientDeleted() { System.out.println("Got it. The patient is deleted."); } + /** + * It shows message of a task being deleted. + */ public void taskDeleted() { System.out.println("Got it. The task is deleted."); } + /** + * It lists out all info of patients. + * + * @param patients the patients to be listed out + */ public void listAllPatients(ArrayList patients) { for (Patient patient : patients) { showPatientInfo(patient); @@ -183,6 +282,11 @@ public void listAllPatients(ArrayList patients) { } } + /** + * It lists out all info of tasks. + * + * @param taskList the tasks to be listed out + */ public void listAllTasks(ArrayList taskList) { int index = 1; System.out.println("Here's a list of your tasks: \n"); @@ -198,6 +302,13 @@ public void listAllTasks(ArrayList taskList) { } } + /** + * It confirms with user on the deletion of a task. + * If user confirms, key in 'Y'. Otherwise key in 'N'. + * + * @param task it contains task's info + * @return true if user confirmed the deletion. False otherwise. + */ public boolean confirmTaskToBeDeleted(Task task) { showTaskInfo(task); while (true) { @@ -234,12 +345,18 @@ public void exitInformation() { */ public void showWelcome() { String logo = " _____ _ _ _ _ \n" + - "| __ \\ | | (_) | | |\n" + - "| | | |_ _| | _____ _ __ _| |_ __ _| |\n" + - "| | | | | | | |/ / _ \\ '_ \\| | __/ _` | |\n" + - "| |__| | |_| | < __/ |_) | | || (_| | |\n" + - "|_____/ \\__,_|_|\\_\\___| .__/|_|\\__\\__,_|_|\n" + - " | | \n" + + "| __ \\ | | (_) | | |\n" + + + "| | | |_ _| | _____ _ __ _| |_ __ _| |\n" + + + "| | | | | | | |/ / _ \\ '_ \\| | __/ _` | |\n" + + + "| |__| | |_| | < __/ |_) | | || (_| | |\n" + + + "|_____/ \\__,_|_|\\_\\___| .__/|_|\\__\\__,_|_|\n" + + + " | | \n" + + " |_| \n"; System.out.println(logo); @@ -247,15 +364,27 @@ public void showWelcome() { System.out.println("Enter 'help' to show a list of commands "); } - + /** + * Show information is being updated successfully. + */ public void showUpdatedSuccessfully() { System.out.println("I have successfully updated the following information: \n"); } + /** + * Show message of loading failure. + */ public void showLoadingError() { - System.out.println("Failed to Load from local text file!"); + System.out.println("Failed to load from local data file!"); } + /** + * It shows all info of patientTasks found which are associated with the patient given by user. + * + * @param patient patient given by user + * @param patientTask list of patienttasks being found associated with the patient + * @param tasks list of tasks relate to patienttasks found + */ public void patientTaskFound(Patient patient, ArrayList patientTask, ArrayList tasks) { System.out.println("The tasks of patient " + patient.getID() + " " + patient.getName() + " is found : \n"); for (int i = 0; i < patientTask.size(); i++) { @@ -265,5 +394,4 @@ public void patientTaskFound(Patient patient, ArrayList patientTask showLine(); } } - } From 5b231583b661e12053c68c667c6ae7ab53761682 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Fri, 18 Oct 2019 02:24:06 +0800 Subject: [PATCH 154/420] Added .travis.yml and removed invalid travis.yml --- travis.yml => .travis.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename travis.yml => .travis.yml (100%) diff --git a/travis.yml b/.travis.yml similarity index 100% rename from travis.yml rename to .travis.yml From 1988e911f863c8f75caea2225510c4e8be931d22 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Fri, 18 Oct 2019 02:40:23 +0800 Subject: [PATCH 155/420] Update codeStyle for CommandManager/TypoCorrector --- src/main/java/duke/core/CommandManager.java | 181 ++++++++++---------- src/main/java/duke/core/TypoCorrector.java | 47 ++--- 2 files changed, 117 insertions(+), 111 deletions(-) diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index d5fb3fe19b..849563d62a 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -1,6 +1,18 @@ package duke.core; -import duke.command.*; +import duke.command.AddPatientCommand; +import duke.command.AddStandardTaskCommand; +import duke.command.AssignTaskToPatientCommand; +import duke.command.Command; +import duke.command.DeletePatientCommand; +import duke.command.DeleteTaskCommand; +import duke.command.ExitCommand; +import duke.command.FindPatientCommand; +import duke.command.FindPatientTaskCommand; +import duke.command.ListPatientsCommand; +import duke.command.ListTasksCommand; +import duke.command.UpdatePatientCommand; +import duke.command.UpdateTaskCommand; /** * Represents a Parser that parses user input into a specific @@ -20,101 +32,90 @@ public static Command manageCommand(String userInput) throws DukeException { String firstKeyword = command[0].toLowerCase(); Parser parser = new Parser(userInput); switch (firstKeyword) { //change this depending on how string is parsed - case "add": - String secondKeyword = command[1].toLowerCase(); - if (secondKeyword.equals("patient")){ - String[] formattedInput = parser.parseAdd(); - return new AddPatientCommand(formattedInput); - } - else if (secondKeyword.equals("task")){ - String formattedInput = parser.parseAdd()[0]; - return new AddStandardTaskCommand(formattedInput); - } - else { - throw new DukeException("Add command fails. "); - } - case "assign": - return new AssignTaskToPatientCommand(parser.parseAssign()); - case "list": - try { - String[] tempCommand = command[1].split("\\s+"); - if (tempCommand[0].toLowerCase().equals("patients")){ - return new ListPatientsCommand(); - } - else if (tempCommand[0].toLowerCase().equals("tasks")){ - return new ListTasksCommand(); - } - else { - throw new Exception("Invalid 'list' command. "); - } - } catch (Exception e) { - throw new DukeException("List command fails. " + e.getMessage()); + case "add": + String secondKeyword = command[1].toLowerCase(); + if (secondKeyword.equals("patient")) { + String[] formattedInput = parser.parseAdd(); + return new AddPatientCommand(formattedInput); + } else if (secondKeyword.equals("task")) { + String formattedInput = parser.parseAdd()[0]; + return new AddStandardTaskCommand(formattedInput); + } else { + throw new DukeException("Add command fails. "); + } + case "assign": + return new AssignTaskToPatientCommand(parser.parseAssign()); + case "list": + try { + String[] tempCommand = command[1].split("\\s+"); + if (tempCommand[0].toLowerCase().equals("patients")) { + return new ListPatientsCommand(); + } else if (tempCommand[0].toLowerCase().equals("tasks")) { + return new ListTasksCommand(); + } else { + throw new Exception("Invalid 'list' command. "); } - case "delete": - try{ - secondKeyword = command[1].toLowerCase(); - if (secondKeyword.equals("patient")) { - String formattedInput = parser.parseDeletePatient(); - return new DeletePatientCommand(formattedInput); - } - else if (secondKeyword.equals("task")){ - return new DeleteTaskCommand(parser.parseDeleteTask()); - } - else { - throw new Exception("Invalid format. "); - } - } catch(Exception e){ - throw new DukeException("Delete command fails. " + e.getMessage()); + } catch (Exception e) { + throw new DukeException("List command fails. " + e.getMessage()); + } + case "delete": + try { + secondKeyword = command[1].toLowerCase(); + if (secondKeyword.equals("patient")) { + String formattedInput = parser.parseDeletePatient(); + return new DeletePatientCommand(formattedInput); + } else if (secondKeyword.equals("task")) { + return new DeleteTaskCommand(parser.parseDeleteTask()); + } else { + throw new Exception("Invalid format. "); } - case "find": - try{ - secondKeyword = command[1].toLowerCase(); - if (secondKeyword.equals("patient")){ - try { - return new FindPatientCommand(command[2]); - }catch(Exception e){ - throw new Exception("Please follow the format 'find patient #' or 'find patient '."); - } - } - else if (secondKeyword.equals("patienttask")){ - try { - return new FindPatientTaskCommand(command[2]); - }catch(Exception e){ - throw new Exception("Please follow the format 'find patient #' or 'find patient '."); - } + } catch (Exception e) { + throw new DukeException("Delete command fails. " + e.getMessage()); + } + case "find": + try { + secondKeyword = command[1].toLowerCase(); + if (secondKeyword.equals("patient")) { + try { + return new FindPatientCommand(command[2]); + } catch (Exception e) { + throw new Exception("Please follow the format 'find patient #' or 'find patient '."); } - else { - throw new Exception("Invalid format. "); + } else if (secondKeyword.equals("patienttask")) { + try { + return new FindPatientTaskCommand(command[2]); + } catch (Exception e) { + throw new Exception("Please follow the format 'find patient #' or 'find patient '."); } - } catch(Exception e){ - throw new DukeException("Find command fails. " + e.getMessage()); + } else { + throw new Exception("Invalid format. "); } - case "update": - try { - secondKeyword = command[1].toLowerCase(); - if (secondKeyword.equals("patient")){ - String formattedInput = parser.parseUpdatePatient(); - return new UpdatePatientCommand(formattedInput); - } - else if (secondKeyword.equals("task")){ - String formattedInput = parser.parseUpdateTask(); - return new UpdateTaskCommand(formattedInput); - } - else { - throw new Exception("Invalid format. "); - } - } catch (Exception e) { - throw new DukeException("update command fails. " + e.getMessage()); - } - case "bye": - return new ExitCommand(); - default: - String possibleCommand = TypoCorrector.CommandCorrection(userInput); - if (!possibleCommand.equals(userInput)){ - throw new DukeException("Could not understand user input. Did you mean: \n" + possibleCommand); + } catch (Exception e) { + throw new DukeException("Find command fails. " + e.getMessage()); + } + case "update": + try { + secondKeyword = command[1].toLowerCase(); + if (secondKeyword.equals("patient")) { + String formattedInput = parser.parseUpdatePatient(); + return new UpdatePatientCommand(formattedInput); + } else if (secondKeyword.equals("task")) { + String formattedInput = parser.parseUpdateTask(); + return new UpdateTaskCommand(formattedInput); + } else { + throw new Exception("Invalid format. "); } - throw new DukeException("Could not understand user input"); + } catch (Exception e) { + throw new DukeException("update command fails. " + e.getMessage()); + } + case "bye": + return new ExitCommand(); + default: + String possibleCommand = TypoCorrector.commandCorrection(userInput); + if (!possibleCommand.equals(userInput)) { + throw new DukeException("Could not understand user input. Did you mean: \n" + possibleCommand); + } + throw new DukeException("Could not understand user input"); } } - } diff --git a/src/main/java/duke/core/TypoCorrector.java b/src/main/java/duke/core/TypoCorrector.java index 27ddbd1a0b..aabaa38683 100644 --- a/src/main/java/duke/core/TypoCorrector.java +++ b/src/main/java/duke/core/TypoCorrector.java @@ -10,56 +10,60 @@ * It provides a method TypoCorrector.CommandCorrection which takes in an invalid input command * and return a possible matched command. * - * @author HUANG XUAN KUN + * @author HUANG XUAN KUN * @version 1.2 */ public class TypoCorrector { //The maximum ratio changes of a text in % that is acceptable - private final static double MAX_DISTANCE_DIFF_RATIO = 0.5; + private static final double MAX_DISTANCE_DIFF_RATIO = 0.5; - - //Sets of "Dictionaries" for the command matching, categorised by number of keywords contain in a supported commands. - private final static ArrayList oneKeywordCommand = new ArrayList(Arrays.asList("bye")); - private final static ArrayList twoKeywordsCommands = new ArrayList(Arrays.asList("list patients", "list tasks")); - private final static ArrayList otherCommands = new ArrayList(Arrays.asList("update patient", "update task", "delete patient", "delete task", "add task", "add patient", "assign by")); + //Sets of "Dictionaries" for the command keyword, categorised by number of keywords contain in a supported commands. + private static final ArrayList oneKeywordCommand = new ArrayList( + Arrays.asList("bye")); + private static final ArrayList twoKeywordsCommands = new ArrayList( + Arrays.asList("list patients", "list tasks")); + private static final ArrayList otherCommands = new ArrayList( + Arrays.asList("update patient", "update task", + "delete patient", "delete task", "add task", "add patient", "assign by")); /** * This method take in an user input command with typo and return a possible matches * If the return string is equal to the input command, there is no match. * * @param command the full userInput command without parsing - * @return + * @return a string of correctedCommand */ - public static String CommandCorrection(String command) { + public static String commandCorrection(String command) { String[] splitCommand = command.split("\\s+"); int commandSize = splitCommand.length; - String closestMatch, firstTwoKeywords; + String closestMatch; + String firstTwoKeywords; if (commandSize == 1 || command.length() <= 6) { closestMatch = matchStringFromDict(command, oneKeywordCommand); - if (isSimilar(command, closestMatch)){ + if (isSimilar(command, closestMatch)) { return closestMatch; } } else if (commandSize == 2) { firstTwoKeywords = command.toLowerCase(); closestMatch = matchStringFromDict(firstTwoKeywords, twoKeywordsCommands); - if (isSimilar(firstTwoKeywords, closestMatch)){ + if (isSimilar(firstTwoKeywords, closestMatch)) { return closestMatch; } } else { - firstTwoKeywords = (splitCommand[0]+" " +splitCommand[1]).toLowerCase(); + firstTwoKeywords = (splitCommand[0] + " " + splitCommand[1]).toLowerCase(); closestMatch = matchStringFromDict(firstTwoKeywords, otherCommands); - if (isSimilar(firstTwoKeywords, closestMatch)){ - splitCommand[0]=""; - splitCommand[1]=""; - return closestMatch + " " +String.join(" ",splitCommand).trim(); + if (isSimilar(firstTwoKeywords, closestMatch)) { + splitCommand[0] = ""; + splitCommand[1] = ""; + return closestMatch + " " + String.join(" ", splitCommand).trim(); } } return command; } /** - * Get the closest match string from the array targetDict + * Get the closest match string from the array targetDict. * * @param str the arbitrary string * @return @@ -70,7 +74,7 @@ private static String matchStringFromDict(String str, ArrayList targetDi for (String keyword : targetDict) { int currDist = getDistance(keyword, str); if (currDist < minDist) { - if (currDist == 0){ + if (currDist == 0) { return keyword; } minDist = currDist; @@ -81,7 +85,7 @@ private static String matchStringFromDict(String str, ArrayList targetDi } /** - * Get Levenshtein distance between target and an arbitrary string + * Get Levenshtein distance between target and an arbitrary string. * * @param str the arbitrary string * @return @@ -92,7 +96,8 @@ private static Integer getDistance(String str, String target) { } /** - * Method indicating if a message can be considered similar, based on Levenshtein distance calculation with an allowed variation of 50% + * Method indicating if a message can be considered similar, based on Levenshtein distance + * calculation with an allowed variation of 50%. * * Note: Max tolerated distance is derived from the current scenario's error message * The arbitrary MAX_DISTANCE_DIFF_RATIO (50%) means we consider 10% change to be acceptable From f98134060c89ff1c76515b53f1d3fcd663d5d7e8 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Fri, 18 Oct 2019 04:10:54 +0800 Subject: [PATCH 156/420] Update all codeStyle to fulfill the requirement --- src/main/java/duke/Duke.java | 10 +- .../java/duke/command/AddPatientCommand.java | 10 +- .../duke/command/AddStandardTaskCommand.java | 22 ++- .../command/AssignTaskToPatientCommand.java | 41 ++++- src/main/java/duke/command/Command.java | 22 ++- .../duke/command/DeletePatientCommand.java | 38 +++- .../java/duke/command/DeleteTaskCommand.java | 34 +++- src/main/java/duke/command/ExitCommand.java | 14 +- .../java/duke/command/FindPatientCommand.java | 32 +++- .../duke/command/FindPatientTaskCommand.java | 46 +++-- src/main/java/duke/command/HelpCommand.java | 21 ++- .../duke/command/ListPatientsCommand.java | 16 +- .../java/duke/command/ListTasksCommand.java | 17 +- .../duke/command/UpdatePatientCommand.java | 52 ++++-- .../java/duke/command/UpdateTaskCommand.java | 37 +++- src/main/java/duke/core/CommandManager.java | 173 +++++++++--------- src/main/java/duke/core/DateTimeParser.java | 9 +- src/main/java/duke/core/DukeException.java | 4 + src/main/java/duke/core/Parser.java | 47 ++++- src/main/java/duke/core/Ui.java | 5 +- src/main/java/duke/patient/Patient.java | 62 ++++++- .../java/duke/patient/PatientManager.java | 65 +++++-- .../java/duke/relation/EventPatientTask.java | 110 ++++++++--- src/main/java/duke/relation/PatientTask.java | 107 +++++++++-- .../java/duke/relation/PatientTaskList.java | 57 +++++- .../duke/relation/StandardPatientTask.java | 62 +++++-- .../java/duke/storage/PatientStorage.java | 2 +- src/main/java/duke/task/Task.java | 42 ++++- src/main/java/duke/task/TaskManager.java | 47 +++-- 29 files changed, 912 insertions(+), 292 deletions(-) diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index fa2f55f84a..77f5bb69a0 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -35,13 +35,14 @@ public class Duke { * A Ui object that deals with interactions with the user. */ private Ui ui = Ui.getUi(); + /** * Constructs a Duke object with a relative file path. * Initialize the user interface and reads tasks from the specific text file. + * * @param filePath A string that represents the path of the local file - * used for storing tasks. + * used for storing tasks. */ - public Duke(String filePath) { taskStorage = new TaskStorage(filePath + "/standardTasks.csv"); patientStorage = new PatientStorage(filePath + "/patients.csv"); @@ -70,7 +71,8 @@ public void run() { String fullCommand = ui.readCommand(); ui.showLine(); Command c = CommandManager.manageCommand(fullCommand); - c.execute(patientTaskList,taskManager,patientManager, ui, patientTaskStorage, taskStorage, patientStorage); + c.execute(patientTaskList, taskManager, patientManager, + ui, patientTaskStorage, taskStorage, patientStorage); isExit = c.isExit(); } catch (DukeException e) { ui.showError(e.getMessage()); @@ -85,9 +87,9 @@ public void run() { * Starts the Duke thread and Reminder thread concurrently * by passing a filepath to duke and a global ui object& * task list to Reminder. + * * @param args The command line arguments. */ - public static void main(String[] args) { new Duke("./data").run(); } diff --git a/src/main/java/duke/command/AddPatientCommand.java b/src/main/java/duke/command/AddPatientCommand.java index cb3cf1147b..bddb569c1a 100644 --- a/src/main/java/duke/command/AddPatientCommand.java +++ b/src/main/java/duke/command/AddPatientCommand.java @@ -14,6 +14,12 @@ public class AddPatientCommand extends Command { private Patient newPatient; + /** + * . + * + * @param patientInfo . + * @throws DukeException . + */ public AddPatientCommand(String[] patientInfo) throws DukeException { super(); try { @@ -24,7 +30,9 @@ public AddPatientCommand(String[] patientInfo) throws DukeException { } @Override - public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, Ui ui, + PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, + PatientStorage patientStorage) throws DukeException { patientList.addPatient(newPatient); patientStorage.save(patientList.getPatientList()); ui.patientAdded(newPatient); diff --git a/src/main/java/duke/command/AddStandardTaskCommand.java b/src/main/java/duke/command/AddStandardTaskCommand.java index 0d1e375cf2..23742bbda3 100644 --- a/src/main/java/duke/command/AddStandardTaskCommand.java +++ b/src/main/java/duke/command/AddStandardTaskCommand.java @@ -10,15 +10,33 @@ import duke.task.Task; import duke.task.TaskManager; -public class AddStandardTaskCommand extends Command{ +public class AddStandardTaskCommand extends Command { private Task newStandardTask; + + /** + * . + * @param taskDescription . + */ public AddStandardTaskCommand(String taskDescription) { super(); this.newStandardTask = new Task(taskDescription); } + /** + * . + * @param patientTask . + * @param taskList . + * @param patientList . + * @param ui . + * @param patientTaskStorage . + * @param taskStorage . + * @param patientStorage . + * @throws DukeException . + */ @Override - public void execute(PatientTaskList patientTask, TaskManager taskList, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + public void execute(PatientTaskList patientTask, TaskManager taskList, PatientManager patientList, + Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, + PatientStorage patientStorage) throws DukeException { taskList.addTask(newStandardTask); taskStorage.save(taskList.getTaskList()); ui.taskAdded(newStandardTask); diff --git a/src/main/java/duke/command/AssignTaskToPatientCommand.java b/src/main/java/duke/command/AssignTaskToPatientCommand.java index f93bc95703..c0f81239fe 100644 --- a/src/main/java/duke/command/AssignTaskToPatientCommand.java +++ b/src/main/java/duke/command/AssignTaskToPatientCommand.java @@ -18,27 +18,49 @@ public class AssignTaskToPatientCommand extends Command { private String[] taskAssignmentInfo; private PatientTask newPatientTask; + /** + * . + * @param taskAssignmentInfo . + * @throws DukeException . + */ public AssignTaskToPatientCommand(String[] taskAssignmentInfo) throws DukeException { super(); this.taskAssignmentInfo = taskAssignmentInfo; this.newPatientTask = finalPatientTask(taskAssignmentInfo); } + /** + * . + * @param patientTaskList . + * @param tasksList . + * @param patientList . + * @param ui . + * @param patientTaskStorage . + * @param taskStorage . + * @param patientStorage . + * @throws DukeException . + */ @Override - public void execute(PatientTaskList patientTaskList, TaskManager tasksList, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { - if (patientList.isExist(newPatientTask.getPatientId()) && tasksList.doesExist(newPatientTask.getTaskID())) - { + public void execute(PatientTaskList patientTaskList, TaskManager tasksList, PatientManager patientList, + Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, + PatientStorage patientStorage) throws DukeException { + if (patientList.isExist(newPatientTask.getPatientId()) && tasksList.doesExist(newPatientTask.getTaskID())) { patientTaskList.addPatientTask(newPatientTask); patientTaskStorage.save(patientTaskList.fullPatientTaskList()); - ui.patientTaskAssigned(newPatientTask, patientList.getPatient(newPatientTask.getPatientId()).getName(), tasksList.getTask(newPatientTask.getTaskID()).getDescription()); - } - else - { + ui.patientTaskAssigned(newPatientTask, patientList.getPatient(newPatientTask.getPatientId()).getName(), + tasksList.getTask(newPatientTask.getTaskID()).getDescription()); + } else { throw new DukeException("Either the patient or the task does not exist in our data record"); } } + /** + * . + * @param assignmentInfo . + * @return . + * @throws DukeException . + */ public PatientTask finalPatientTask(String[] assignmentInfo) throws DukeException { try { if (assignmentInfo[0].equals("S")) { @@ -67,6 +89,11 @@ public PatientTask finalPatientTask(String[] assignmentInfo) throws DukeExceptio throw new DukeException("Unable to parse your task assignment. Please check your command's format!"); } } + + /** + * . + * @return . + */ @Override public boolean isExit() { return false; diff --git a/src/main/java/duke/command/Command.java b/src/main/java/duke/command/Command.java index b05e48ab5a..301e2f22d7 100644 --- a/src/main/java/duke/command/Command.java +++ b/src/main/java/duke/command/Command.java @@ -1,13 +1,13 @@ package duke.command; import duke.core.DukeException; +import duke.core.Ui; import duke.patient.PatientManager; +import duke.relation.PatientTaskList; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; -import duke.relation.PatientTaskList; import duke.storage.TaskStorage; import duke.task.TaskManager; -import duke.core.Ui; /** * Represents a command class received from user. It is an abstract @@ -16,12 +16,26 @@ */ public abstract class Command { - public abstract void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException; + /** + * . + * + * @param patientTask . + * @param tasks . + * @param patientList . + * @param ui . + * @param patientTaskStorage . + * @param taskStorage . + * @param patientStorage . + * @throws DukeException . + */ + public abstract void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, Ui ui, + PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, + PatientStorage patientStorage) throws DukeException; + /** * Decide whether duke should exist. * * @return A boolean. True if the command tells Duke to exit, false - * otherwise. */ public abstract boolean isExit(); diff --git a/src/main/java/duke/command/DeletePatientCommand.java b/src/main/java/duke/command/DeletePatientCommand.java index 6b992fe6c4..27498c621c 100644 --- a/src/main/java/duke/command/DeletePatientCommand.java +++ b/src/main/java/duke/command/DeletePatientCommand.java @@ -17,6 +17,12 @@ public class DeletePatientCommand extends Command { private int id; private String deletedPatientInfo; + /** + * . + * + * @param deletedPatientInfo . + * @throws DukeException . + */ public DeletePatientCommand(String deletedPatientInfo) throws DukeException { this.deletedPatientInfo = deletedPatientInfo; @@ -30,12 +36,27 @@ public DeletePatientCommand(String deletedPatientInfo) throws DukeException { } } + /** + * . + * + * @param patientTask . + * @param tasks . + * @param patientManager . + * @param ui . + * @param patientTaskStorage . + * @param taskStorage . + * @param patientStorage . + * @throws DukeException . + */ @Override - public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientManager, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { ; + public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientManager, + Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, + PatientStorage patientStorage) throws DukeException { + ; if (id != 0) { Patient patientToBeDeleted = patientManager.getPatient(id); boolean toDelete = ui.confirmPatientToBeDeleted(patientToBeDeleted); - if (toDelete){ + if (toDelete) { patientManager.deletePatient(id); ui.patientDeleted(); patientStorage.save(patientManager.getPatientList()); @@ -45,10 +66,10 @@ public DeletePatientCommand(String deletedPatientInfo) throws DukeException { ui.patientsFoundByName(patientsWithSameName, deletedPatientInfo); if (patientsWithSameName.size() >= 1) { int numberChosen = ui.choosePatientToDelete(patientsWithSameName.size()); - if (numberChosen >= 1){ - boolean toDelete = ui.confirmPatientToBeDeleted(patientsWithSameName.get(numberChosen-1)); - if (toDelete){ - patientManager.deletePatient(patientsWithSameName.get(numberChosen-1).getID()); + if (numberChosen >= 1) { + boolean toDelete = ui.confirmPatientToBeDeleted(patientsWithSameName.get(numberChosen - 1)); + if (toDelete) { + patientManager.deletePatient(patientsWithSameName.get(numberChosen - 1).getID()); ui.patientDeleted(); patientStorage.save(patientManager.getPatientList()); } @@ -57,6 +78,11 @@ public DeletePatientCommand(String deletedPatientInfo) throws DukeException { } } + /** + * . + * + * @return . + */ @Override public boolean isExit() { return false; diff --git a/src/main/java/duke/command/DeleteTaskCommand.java b/src/main/java/duke/command/DeleteTaskCommand.java index 42be4b08ba..4f4739b42b 100644 --- a/src/main/java/duke/command/DeleteTaskCommand.java +++ b/src/main/java/duke/command/DeleteTaskCommand.java @@ -12,10 +12,16 @@ import java.util.ArrayList; -public class DeleteTaskCommand extends Command{ +public class DeleteTaskCommand extends Command { private int id; private String deletedTaskInfo; + /** + * . + * + * @param deletedTaskInfo . + * @throws DukeException . + */ public DeleteTaskCommand(String deletedTaskInfo) throws DukeException { this.deletedTaskInfo = deletedTaskInfo; @@ -29,12 +35,26 @@ public DeleteTaskCommand(String deletedTaskInfo) throws DukeException { } } + /** + * . + * + * @param patientTask . + * @param taskManager . + * @param patientManager . + * @param ui . + * @param patientTaskStorage . + * @param taskStorage . + * @param patientStorage . + * @throws DukeException . + */ @Override - public void execute(PatientTaskList patientTask, TaskManager taskManager, PatientManager patientManager, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + public void execute(PatientTaskList patientTask, TaskManager taskManager, PatientManager patientManager, + Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, + PatientStorage patientStorage) throws DukeException { if (id != 0) { Task taskToBeDeleted = taskManager.getTask(id); boolean toDelete = ui.confirmTaskToBeDeleted(taskToBeDeleted); - if (toDelete){ + if (toDelete) { taskManager.deleteTask(id); ui.taskDeleted(); taskStorage.save(taskManager.getTaskList()); @@ -44,10 +64,10 @@ public void execute(PatientTaskList patientTask, TaskManager taskManager, Patien ui.tasksFoundByDescription(tasksWithSameDescription, deletedTaskInfo); if (tasksWithSameDescription.size() >= 1) { int numberChosen = ui.chooseTaskToDelete(tasksWithSameDescription.size()); - if (numberChosen >= 1){ - boolean toDelete = ui.confirmTaskToBeDeleted(tasksWithSameDescription.get(numberChosen-1)); - if (toDelete){ - taskManager.deleteTask(tasksWithSameDescription.get(numberChosen-1).getID()); + if (numberChosen >= 1) { + boolean toDelete = ui.confirmTaskToBeDeleted(tasksWithSameDescription.get(numberChosen - 1)); + if (toDelete) { + taskManager.deleteTask(tasksWithSameDescription.get(numberChosen - 1).getID()); ui.taskDeleted(); taskStorage.save(taskManager.getTaskList()); } diff --git a/src/main/java/duke/command/ExitCommand.java b/src/main/java/duke/command/ExitCommand.java index ec742de72f..4962348377 100644 --- a/src/main/java/duke/command/ExitCommand.java +++ b/src/main/java/duke/command/ExitCommand.java @@ -24,8 +24,7 @@ public ExitCommand() { /** * Indicates whether Duke should exist. * - * @return A boolean. True if the command tells Duke to exit, false - * otherwise. + * @return A boolean. True if the command tells Duke to exit, false otherwise. */ @Override public boolean isExit() { @@ -35,12 +34,13 @@ public boolean isExit() { /** * run the command with the respect TaskList, UI, and storage. * - * @param tasks The task list where tasks are saved. - * @param ui The user interface. - * @param patientList object that handles local text file update + * @param tasks The task list where tasks are saved. + * @param ui The user interface. + * @param patientList object that handles local text file update */ - - public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage){ + public void execute(PatientTaskList patientTask, TaskManager tasks, + PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, + TaskStorage taskStorage, PatientStorage patientStorage) { ui.exitInformation(); } } \ No newline at end of file diff --git a/src/main/java/duke/command/FindPatientCommand.java b/src/main/java/duke/command/FindPatientCommand.java index 5adf3fe560..4877121ce7 100644 --- a/src/main/java/duke/command/FindPatientCommand.java +++ b/src/main/java/duke/command/FindPatientCommand.java @@ -9,34 +9,54 @@ import duke.storage.TaskStorage; import duke.relation.PatientTaskList; import duke.task.TaskManager; + import java.util.ArrayList; public class FindPatientCommand extends Command { private String command; - public FindPatientCommand(String command){ + + public FindPatientCommand(String command) { this.command = command; } + /** + * . + * + * @param patientTask . + * @param tasks . + * @param patientManager . + * @param ui . + * @param patientTaskStorage . + * @param taskStorage . + * @param patientStorage . + * @throws DukeException . + */ @Override - public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientManager, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientManager, + Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, + PatientStorage patientStorage) throws DukeException { char firstChar = command.charAt(0); - if (firstChar == '#'){ + if (firstChar == '#') { int id; try { id = Integer.parseInt(command.substring(1, command.length())); - }catch(Exception e) { + } catch (Exception e) { throw new DukeException("Please follow the format 'find patient #' or 'find patient '."); } Patient patient = patientManager.getPatient(id); ui.patientsFoundById(patient); - } - else{ + } else { ArrayList patientsWithSameName = patientManager.getPatientByName(command); ui.patientsFoundByName(patientsWithSameName, command); } } + /** + * . + * + * @return . + */ @Override public boolean isExit() { return false; diff --git a/src/main/java/duke/command/FindPatientTaskCommand.java b/src/main/java/duke/command/FindPatientTaskCommand.java index 8e7dca392a..a16cf154ff 100644 --- a/src/main/java/duke/command/FindPatientTaskCommand.java +++ b/src/main/java/duke/command/FindPatientTaskCommand.java @@ -4,47 +4,62 @@ import duke.core.Ui; import duke.patient.Patient; import duke.patient.PatientManager; -import duke.relation.EventPatientTask; -import duke.relation.StandardPatientTask; +import duke.relation.PatientTask; +import duke.relation.PatientTaskList; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; import duke.storage.TaskStorage; -import duke.relation.PatientTask; -import duke.relation.PatientTaskList; import duke.task.Task; import duke.task.TaskManager; -import java.awt.*; import java.util.ArrayList; public class FindPatientTaskCommand extends Command { private String command; + /** + * . + * + * @param cmd . + */ public FindPatientTaskCommand(String cmd) { super(); this.command = cmd; } + /** + * . + * + * @param patientTaskList . + * @param tasksManager . + * @param patientManager . + * @param ui . + * @param patientTaskStorage . + * @param taskStorage . + * @param patientStorage . + * @throws DukeException . + */ @Override - public void execute(PatientTaskList patientTaskList, TaskManager tasksManager, PatientManager patientManager, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + public void execute(PatientTaskList patientTaskList, TaskManager tasksManager, PatientManager patientManager, + Ui ui, PatientTaskStorage patientTaskStorage, + TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { char firstChar = command.charAt(0); - if (firstChar == '#'){ + if (firstChar == '#') { int id; try { id = Integer.parseInt(command.substring(1, command.length())); Patient patient = patientManager.getPatient(id); ArrayList patientTask = patientTaskList.getPatientTask(id); ArrayList tempTask = new ArrayList<>(); - for (PatientTask temppatientTask : patientTask){ + for (PatientTask temppatientTask : patientTask) { tempTask.add(tasksManager.getTask(temppatientTask.getTaskID())); } ui.patientTaskFound(patient, patientTask, tempTask); - }catch(Exception e) { + } catch (Exception e) { throw new DukeException("Please follow the format 'find patienttask #' or 'find patient '."); } - } - else{ + } else { String name = command.toLowerCase(); ArrayList patientsWithSameName = patientManager.getPatientByName(name); ArrayList patientWithTask = new ArrayList<>(); @@ -52,18 +67,19 @@ public void execute(PatientTaskList patientTaskList, TaskManager tasksManager, P try { for (Patient patient : patientsWithSameName) { - if(patient.getName().toLowerCase().equals(name)){ + if (patient.getName().toLowerCase().equals(name)) { patientWithTask = patientTaskList.getPatientTask(patient.getID()); } } - for (PatientTask temppatientTask : patientWithTask){ + for (PatientTask temppatientTask : patientWithTask) { tempTask.add(tasksManager.getTask(temppatientTask.getTaskID())); //System.out.println(temppatientTask.getTaskID() + "\n"); } ui.patientTaskFound(patientsWithSameName.get(0), patientWithTask, tempTask); - }catch(Exception e) { - throw new DukeException(e .getMessage() + "Please follow the format 'find patienttask #' or 'find patient '."); + } catch (Exception e) { + throw new DukeException(e.getMessage() + + "Please follow the format 'find patienttask #' or 'find patient '."); } } } diff --git a/src/main/java/duke/command/HelpCommand.java b/src/main/java/duke/command/HelpCommand.java index 8e79dd8197..0af521525f 100644 --- a/src/main/java/duke/command/HelpCommand.java +++ b/src/main/java/duke/command/HelpCommand.java @@ -11,12 +11,31 @@ public class HelpCommand extends Command { + /** + * . + * + * @param patientTask . + * @param tasks . + * @param patientList . + * @param ui . + * @param patientTaskStorage . + * @param taskStorage . + * @param patientStorage . + * @throws DukeException . + */ @Override - public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, + Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, + PatientStorage patientStorage) throws DukeException { //ui.showHelpCommand(); } + /** + * . + * + * @return . + */ @Override public boolean isExit() { return false; diff --git a/src/main/java/duke/command/ListPatientsCommand.java b/src/main/java/duke/command/ListPatientsCommand.java index 54921fbeb4..2582c52e70 100644 --- a/src/main/java/duke/command/ListPatientsCommand.java +++ b/src/main/java/duke/command/ListPatientsCommand.java @@ -18,8 +18,22 @@ public ListPatientsCommand() { super(); } + /** + * . + * + * @param patientTask . + * @param tasks . + * @param patientList . + * @param ui . + * @param patientTaskStorage . + * @param taskStorage . + * @param patientStorage . + * @throws DukeException . + */ @Override - public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, + Ui ui, PatientTaskStorage patientTaskStorage, + TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { ArrayList list = patientList.getPatientList(); ui.listAllPatients(list); } diff --git a/src/main/java/duke/command/ListTasksCommand.java b/src/main/java/duke/command/ListTasksCommand.java index 426584fec6..05c310e984 100644 --- a/src/main/java/duke/command/ListTasksCommand.java +++ b/src/main/java/duke/command/ListTasksCommand.java @@ -13,8 +13,23 @@ import java.util.ArrayList; public class ListTasksCommand extends Command { + + /** + * . + * + * @param patientTask . + * @param tasks . + * @param patientList . + * @param ui . + * @param patientTaskStorage . + * @param taskStorage . + * @param patientStorage . + * @throws DukeException . + */ @Override - public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, + Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, + PatientStorage patientStorage) throws DukeException { ArrayList list = tasks.getTaskList(); ui.listAllTasks(list); } diff --git a/src/main/java/duke/command/UpdatePatientCommand.java b/src/main/java/duke/command/UpdatePatientCommand.java index 139e8423c4..1f0f38f2bf 100644 --- a/src/main/java/duke/command/UpdatePatientCommand.java +++ b/src/main/java/duke/command/UpdatePatientCommand.java @@ -14,27 +14,45 @@ public class UpdatePatientCommand extends Command { private String command; - public UpdatePatientCommand(String command) { this.command = command; } + /** + * . + * + * @param command . + */ + public UpdatePatientCommand(String command) { + this.command = command; + } + /** + * . + * + * @param patientTask . + * @param tasks . + * @param patientManager . + * @param ui . + * @param patientTaskStorage . + * @param taskStorage . + * @param patientStorage . + * @throws DukeException . + */ @Override - public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientManager, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientManager, + Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, + PatientStorage patientStorage) throws DukeException { String[] tempCommand = command.split(" ", 3); char firstChar = tempCommand[0].charAt(0); - if (firstChar == '#'){ + if (firstChar == '#') { int id; try { id = Integer.parseInt(tempCommand[0].substring(1, tempCommand[0].length())); Patient patientToBeUpdated = patientManager.getPatient(id); if (tempCommand[1].toLowerCase().equals("name")) { patientToBeUpdated.setName(tempCommand[2]); - } - else if (tempCommand[1].toLowerCase().equals("nric")) { + } else if (tempCommand[1].toLowerCase().equals("nric")) { patientToBeUpdated.setNric(tempCommand[2]); - } - else if (tempCommand[1].toLowerCase().equals("room")) { + } else if (tempCommand[1].toLowerCase().equals("room")) { patientToBeUpdated.setRoom(tempCommand[2]); - } - else { + } else { throw new DukeException("You can only update 'Name', 'NRIC', or 'Room' of the patient"); } @@ -42,15 +60,21 @@ else if (tempCommand[1].toLowerCase().equals("room")) { ui.showUpdatedSuccessfully(); ui.showPatientInfo(patientToBeUpdated); - }catch(Exception e) { - throw new DukeException("Please follow the format 'update patient # '."); + } catch (Exception e) { + throw new DukeException( + "Please follow the format 'update patient # '."); } - } - else { - throw new DukeException("Please follow the format 'update patient # '."); + } else { + throw new DukeException( + "Please follow the format 'update patient # '."); } } + /** + * . + * + * @return . + */ @Override public boolean isExit() { return false; diff --git a/src/main/java/duke/command/UpdateTaskCommand.java b/src/main/java/duke/command/UpdateTaskCommand.java index ea06a0b90a..871ddd0aed 100644 --- a/src/main/java/duke/command/UpdateTaskCommand.java +++ b/src/main/java/duke/command/UpdateTaskCommand.java @@ -10,24 +10,44 @@ import duke.relation.PatientTaskList; import duke.task.TaskManager; -public class UpdateTaskCommand extends Command{ +public class UpdateTaskCommand extends Command { private String command; - public UpdateTaskCommand(String command) { this.command = command; } + /** + * . + * + * @param command . + */ + public UpdateTaskCommand(String command) { + this.command = command; + } + /** + * . + * + * @param patientTask . + * @param taskManager . + * @param patientManager . + * @param ui . + * @param patientTaskStorage . + * @param taskStorage . + * @param patientStorage . + * @throws DukeException . + */ @Override - public void execute(PatientTaskList patientTask, TaskManager taskManager, PatientManager patientManager, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + public void execute(PatientTaskList patientTask, TaskManager taskManager, PatientManager patientManager, + Ui ui, PatientTaskStorage patientTaskStorage, + TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { String[] tempCommand = command.split(" ", 3); char firstChar = tempCommand[0].charAt(0); - if (firstChar == '#'){ + if (firstChar == '#') { int id; try { id = Integer.parseInt(tempCommand[0].substring(1, tempCommand[0].length())); Task taskToBeUpdated = taskManager.getTask(id); if (tempCommand[1].toLowerCase().equals("description")) { taskToBeUpdated.setDescription(tempCommand[2]); - } - else { + } else { throw new DukeException("You can only update 'Description' of the task"); } @@ -35,8 +55,9 @@ public void execute(PatientTaskList patientTask, TaskManager taskManager, Patien ui.showUpdatedSuccessfully(); ui.showTaskInfo(taskToBeUpdated); - }catch(Exception e) { - throw new DukeException("Please follow the format 'update patient # '."); + } catch (Exception e) { + throw new DukeException( + "Please follow the format 'update patient # '."); } } diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 9ca806eae1..f3140024f0 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -1,6 +1,18 @@ package duke.core; -import duke.command.*; +import duke.command.AddPatientCommand; +import duke.command.AddStandardTaskCommand; +import duke.command.AssignTaskToPatientCommand; +import duke.command.Command; +import duke.command.DeletePatientCommand; +import duke.command.DeleteTaskCommand; +import duke.command.ExitCommand; +import duke.command.FindPatientCommand; +import duke.command.FindPatientTaskCommand; +import duke.command.ListPatientsCommand; +import duke.command.ListTasksCommand; +import duke.command.UpdatePatientCommand; +import duke.command.UpdateTaskCommand; /** * Represents a Parser that parses user input into a specific @@ -20,97 +32,86 @@ public static Command manageCommand(String userInput) throws DukeException { String firstKeyword = command[0].toLowerCase(); Parser parser = new Parser(userInput); switch (firstKeyword) { //change this depending on how string is parsed - case "add": - String secondKeyword = command[1].toLowerCase(); - if (secondKeyword.equals("patient")){ - String[] formattedInput = parser.parseAdd(); - return new AddPatientCommand(formattedInput); - } - else if (secondKeyword.equals("task")){ - String formattedInput = parser.parseAdd()[0]; - return new AddStandardTaskCommand(formattedInput); - } - else { - throw new DukeException("Add command fails. "); - } - case "assign": - return new AssignTaskToPatientCommand(parser.parseAssign()); - case "list": - try { - String[] tempCommand = command[1].split("\\s+"); - if (tempCommand[0].toLowerCase().equals("patients")){ - return new ListPatientsCommand(); - } - else if (tempCommand[0].toLowerCase().equals("tasks")){ - return new ListTasksCommand(); - } - else { - throw new Exception("Invalid 'list' command. "); - } - } catch (Exception e) { - throw new DukeException("List command fails. " + e.getMessage()); + case "add": + String secondKeyword = command[1].toLowerCase(); + if (secondKeyword.equals("patient")) { + String[] formattedInput = parser.parseAdd(); + return new AddPatientCommand(formattedInput); + } else if (secondKeyword.equals("task")) { + String formattedInput = parser.parseAdd()[0]; + return new AddStandardTaskCommand(formattedInput); + } else { + throw new DukeException("Add command fails. "); + } + case "assign": + return new AssignTaskToPatientCommand(parser.parseAssign()); + case "list": + try { + String[] tempCommand = command[1].split("\\s+"); + if (tempCommand[0].toLowerCase().equals("patients")) { + return new ListPatientsCommand(); + } else if (tempCommand[0].toLowerCase().equals("tasks")) { + return new ListTasksCommand(); + } else { + throw new Exception("Invalid 'list' command. "); } - case "delete": - try{ - secondKeyword = command[1].toLowerCase(); - if (secondKeyword.equals("patient")) { - String formattedInput = parser.parseDeletePatient(); - return new DeletePatientCommand(formattedInput); - } - else if (secondKeyword.equals("task")){ - return new DeleteTaskCommand(parser.parseDeleteTask()); - } - else { - throw new Exception("Invalid format. "); - } - } catch(Exception e){ - throw new DukeException("Delete command fails. " + e.getMessage()); + } catch (Exception e) { + throw new DukeException("List command fails. " + e.getMessage()); + } + case "delete": + try { + secondKeyword = command[1].toLowerCase(); + if (secondKeyword.equals("patient")) { + String formattedInput = parser.parseDeletePatient(); + return new DeletePatientCommand(formattedInput); + } else if (secondKeyword.equals("task")) { + return new DeleteTaskCommand(parser.parseDeleteTask()); + } else { + throw new Exception("Invalid format. "); } - case "find": - try{ - secondKeyword = command[1].toLowerCase(); - if (secondKeyword.equals("patient")){ - try { - return new FindPatientCommand(command[2]); - }catch(Exception e){ - throw new Exception("Please follow the format 'find patient #' or 'find patient '."); - } + } catch (Exception e) { + throw new DukeException("Delete command fails. " + e.getMessage()); + } + case "find": + try { + secondKeyword = command[1].toLowerCase(); + if (secondKeyword.equals("patient")) { + try { + return new FindPatientCommand(command[2]); + } catch (Exception e) { + throw new Exception("Please follow the format 'find patient #' or 'find patient '."); } - else if (secondKeyword.equals("patienttask")){ - try { - return new FindPatientTaskCommand(command[2]); - }catch(Exception e){ - throw new Exception("Please follow the format 'find patient #' or 'find patient '."); - } + } else if (secondKeyword.equals("patienttask")) { + try { + return new FindPatientTaskCommand(command[2]); + } catch (Exception e) { + throw new Exception("Please follow the format 'find patient #' or 'find patient '."); } - else { - throw new Exception("Invalid format. "); - } - } catch(Exception e){ - throw new DukeException("Find command fails. " + e.getMessage()); + } else { + throw new Exception("Invalid format. "); } - case "update": - try { - secondKeyword = command[1].toLowerCase(); - if (secondKeyword.equals("patient")){ - String formattedInput = parser.parseUpdatePatient(); - return new UpdatePatientCommand(formattedInput); - } - else if (secondKeyword.equals("task")){ - String formattedInput = parser.parseUpdateTask(); - return new UpdateTaskCommand(formattedInput); - } - else { - throw new Exception("Invalid format. "); - } - } catch (Exception e) { - throw new DukeException("update command fails. " + e.getMessage()); + } catch (Exception e) { + throw new DukeException("Find command fails. " + e.getMessage()); + } + case "update": + try { + secondKeyword = command[1].toLowerCase(); + if (secondKeyword.equals("patient")) { + String formattedInput = parser.parseUpdatePatient(); + return new UpdatePatientCommand(formattedInput); + } else if (secondKeyword.equals("task")) { + String formattedInput = parser.parseUpdateTask(); + return new UpdateTaskCommand(formattedInput); + } else { + throw new Exception("Invalid format. "); } - case "bye": - return new ExitCommand(); - default: - throw new DukeException("Could not understand user input."); + } catch (Exception e) { + throw new DukeException("update command fails. " + e.getMessage()); + } + case "bye": + return new ExitCommand(); + default: + throw new DukeException("Could not understand user input."); } } - } diff --git a/src/main/java/duke/core/DateTimeParser.java b/src/main/java/duke/core/DateTimeParser.java index e5cd432da7..d4003ea1a8 100644 --- a/src/main/java/duke/core/DateTimeParser.java +++ b/src/main/java/duke/core/DateTimeParser.java @@ -8,7 +8,7 @@ public class DateTimeParser { /** - * update the LocalDateTime constructor to save the date and time + * update the LocalDateTime constructor to save the date and time. * * @param timeBeforeFormat the time retrieved from user input. * @return A LocalDateTime object that contains date and time information. @@ -55,7 +55,12 @@ public static String convertToEnglishDateTime(String timeBeforeFormat) throws Du } } - public static String convertToEnglishDateTimeBeforeParse(LocalDateTime localDateTime) { + /** + * . + * @param localDateTime . + * @return . + */ + public static String convertToEnglishDateTimeBeforeParse(LocalDateTime localDateTime) { DateTimeFormatter stFormatter = DateTimeFormatter.ofPattern("d'st of' MMMM yyyy, ha"); DateTimeFormatter ndFormatter = DateTimeFormatter.ofPattern("d'nd of' MMMM yyyy, ha"); DateTimeFormatter rdFormatter = DateTimeFormatter.ofPattern("d'rd of' MMMM yyyy, ha"); diff --git a/src/main/java/duke/core/DukeException.java b/src/main/java/duke/core/DukeException.java index 5ebede15ae..090680e363 100644 --- a/src/main/java/duke/core/DukeException.java +++ b/src/main/java/duke/core/DukeException.java @@ -1,6 +1,10 @@ package duke.core; public class DukeException extends Exception { + /** + * . + * @param message . + */ public DukeException(String message) { super("Oops! " + message); } diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index dc279e92eb..3fc98cb66e 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -4,15 +4,27 @@ public class Parser { String userInput; + /** + * . + * + * @param userInput . + */ public Parser(String userInput) { this.userInput = userInput; } + /** + * . + * + * @return . + * @throws DukeException . + */ public String[] parseAdd() throws DukeException { String[] parsedCommand = userInput.toLowerCase().split("\\s+", 3); try { if (parsedCommand[1].equals("patient")) { - String[] patientInfo = userInput.replace("add patient ", "").trim().split("\\s+", 4); + String[] patientInfo = userInput.replace( + "add patient ", "").trim().split("\\s+", 4); return patientInfo; } else if (parsedCommand[1].equals("task")) { String[] taskInfo = new String[1]; @@ -25,17 +37,24 @@ public String[] parseAdd() throws DukeException { throw new DukeException("Failed to parse 'add' command."); } + /** + * . + * + * @return . + * @throws DukeException . + */ public String[] parseAssign() throws DukeException { String[] formattedInput = new String[5]; try { String[] parsedCommand = userInput.toLowerCase().split("\\s+", 4); if (parsedCommand[1].equals("by") && parsedCommand[2].equals("id:")) { - String[] tempInput = userInput.replace("assign by id: ", "").split("\\s+", 4); + String[] tempInput = userInput.replace( + "assign by id: ", "").split("\\s+", 4); if (tempInput[0].equals("E")) { String[] parsedTimes = tempInput[3].split(" to ", 2); - for (int i=0; i<3; i++) { + for (int i = 0; i < 3; i++) { formattedInput[i] = tempInput[i]; } formattedInput[3] = parsedTimes[0]; @@ -45,8 +64,6 @@ public String[] parseAssign() throws DukeException { formattedInput[i] = tempInput[i]; } } - - } else { throw new DukeException("Please use proper 'assign by ID' command format. "); } @@ -57,6 +74,11 @@ public String[] parseAssign() throws DukeException { } } + /** + * . + * @return . + * @throws DukeException . + */ public String parseDeletePatient() throws DukeException { String formattedInput; String inputToParse = userInput.replaceAll("(?i)delete patient ", "").trim(); @@ -64,6 +86,11 @@ public String parseDeletePatient() throws DukeException { return formattedInput; } + /** + * . + * @return . + * @throws DukeException . + */ public String parseDeleteTask() throws DukeException { String formattedInput; String inputToParse = userInput.replaceAll("(?i)delete task ", "").trim(); @@ -71,6 +98,11 @@ public String parseDeleteTask() throws DukeException { return formattedInput; } + /** + * . + * @return . + * @throws DukeException . + */ public String parseUpdatePatient() throws DukeException { String formattedInput; String inputToParse = userInput.replaceAll("(?i)update patient ", "").trim(); @@ -78,6 +110,11 @@ public String parseUpdatePatient() throws DukeException { return formattedInput; } + /** + * . + * @return . + * @throws DukeException . + */ public String parseUpdateTask() throws DukeException { String formattedInput; String inputToParse = userInput.replaceAll("(?i)update task ", "").trim(); diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index dbea2f030c..89aa887b9e 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -77,7 +77,7 @@ public void showPatientInfo(Patient patient) { + " Id: " + patient.getID() + "\nNRIC: " - + patient.getNRIC() + + patient.getNric() + " Room: " + patient.getRoom() + "\nRemark: " @@ -344,7 +344,8 @@ public void exitInformation() { * Shows Duke logo and welcome message, and user input instructions. */ public void showWelcome() { - String logo = " _____ _ _ _ _ \n" + + String logo = " _____ _ _ _ _ \n" + + "| __ \\ | | (_) | | |\n" + "| | | |_ _| | _____ _ __ _| |_ __ _| |\n" diff --git a/src/main/java/duke/patient/Patient.java b/src/main/java/duke/patient/Patient.java index 4b6f363b7a..c21ca71d1f 100644 --- a/src/main/java/duke/patient/Patient.java +++ b/src/main/java/duke/patient/Patient.java @@ -10,6 +10,15 @@ public class Patient { private String remark; private String room; + /** + * . + * + * @param id . + * @param name . + * @param nric . + * @param room . + * @param remark . + */ public Patient(int id, String name, String nric, String room, String remark) { this.id = id; this.name = name; @@ -17,6 +26,7 @@ public Patient(int id, String name, String nric, String room, String remark) { this.remark = remark; this.room = room; } + /** * Initialises the minimum fields required to setup a Patient. * @@ -30,42 +40,84 @@ public Patient(String name, String nric, String room, String remark) { this.room = room; } + /** + * . + * + * @return . + */ public String getName() { return name; //return tick or X symbols } + /** + * . + * + * @return . + */ public int getID() { return id; } + /** + * . + * + * @return . + */ public String getRemark() { return remark; } + /** + * . + * + * @return . + */ public String getRoom() { return room; } - public String getNRIC() { + /** + * . + * + * @return . + */ + public String getNric() { return nric; } - public void setID(int id){ + /** + * . + * + * @param id . + */ + public void setID(int id) { this.id = id; } + /** + * . + * + * @param name . + */ public void setName(String name) { this.name = name; } + /** + * . + * + * @param nric . + */ public void setNric(String nric) { this.nric = nric; } + /** + * . + * + * @param room . + */ public void setRoom(String room) { this.room = room; } - - - } \ No newline at end of file diff --git a/src/main/java/duke/patient/PatientManager.java b/src/main/java/duke/patient/PatientManager.java index 3c2f97888a..362d366e08 100644 --- a/src/main/java/duke/patient/PatientManager.java +++ b/src/main/java/duke/patient/PatientManager.java @@ -9,6 +9,7 @@ public class PatientManager { private HashMap patientIdMap = new HashMap(); private int maxId = 0; + /** * instantiate a new TaskList with a empty list. */ @@ -16,58 +17,90 @@ public PatientManager(ArrayList patientList) { for (Patient patient : patientList) { patientIdMap.put(patient.getID(), patient); } - if (!patientList.isEmpty()){ - this.maxId = patientList.get(patientList.size()-1).getID(); + if (!patientList.isEmpty()) { + this.maxId = patientList.get(patientList.size() - 1).getID(); } } + /** + * . + * + * @param id . + * @return . + */ public boolean isExist(int id) { - if (patientIdMap.containsKey(id)){ + if (patientIdMap.containsKey(id)) { return true; - } - else{ + } else { return false; } } + /** + * . + * + * @param id . + * @return . + * @throws DukeException . + */ public Patient getPatient(int id) throws DukeException { - if (patientIdMap.containsKey(id)){ + if (patientIdMap.containsKey(id)) { return patientIdMap.get(id); - } - else{ - throw new DukeException("The patient with id "+ id + " does not exist."); + } else { + throw new DukeException("The patient with id " + id + " does not exist."); } } - public ArrayList getPatientByName(String name){ + /** + * . + * + * @param name . + * @return . + */ + public ArrayList getPatientByName(String name) { name = name.toLowerCase(); ArrayList patientsWithThisName = new ArrayList<>(); for (Patient patient : patientIdMap.values()) { - if(patient.getName().toLowerCase().equals(name)){ + if (patient.getName().toLowerCase().equals(name)) { patientsWithThisName.add(patient); } } return patientsWithThisName; } + /** + * . + * + * @param patient . + */ public void addPatient(Patient patient) { - if (patient.getID() == 0){ + if (patient.getID() == 0) { maxId += 1; //Increment maxId by 1 for the new coming patient patient.setID(maxId); //Set the unique id to patient } patientIdMap.put(patient.getID(), patient); } + /** + * . + * + * @return . + */ public ArrayList getPatientList() { return new ArrayList<>(patientIdMap.values()); } + /** + * . + * + * @param id . + * @throws DukeException . + */ public void deletePatient(int id) throws DukeException { - if (patientIdMap.containsKey(id)){ + if (patientIdMap.containsKey(id)) { patientIdMap.remove(id); - } - else{ - throw new DukeException("The patient with id "+ id + " does not exist."); + } else { + throw new DukeException("The patient with id " + id + " does not exist."); } } diff --git a/src/main/java/duke/relation/EventPatientTask.java b/src/main/java/duke/relation/EventPatientTask.java index fd0dd32959..9705b28ba0 100644 --- a/src/main/java/duke/relation/EventPatientTask.java +++ b/src/main/java/duke/relation/EventPatientTask.java @@ -1,10 +1,10 @@ package duke.relation; -import java.time.Duration; -import java.time.LocalDateTime; import duke.core.DateTimeParser; import duke.core.DukeException; -import duke.relation.PatientTask; + +import java.time.Duration; +import java.time.LocalDateTime; public class EventPatientTask extends PatientTask { @@ -14,68 +14,118 @@ public class EventPatientTask extends PatientTask { private String endTimeRaw; private long duration; - public EventPatientTask(int pid, int tid, String stime, String eTime, String type){ + /** + * . + * + * @param pid . + * @param tid . + * @param stime . + * @param etime . + * @param type . + */ + public EventPatientTask(int pid, int tid, String stime, String etime, String type) { super(pid, tid, type); this.startTimeRaw = stime; - this.endTimeRaw = eTime; - try{ + this.endTimeRaw = etime; + try { this.startTime = DateTimeParser.convertToLocalDateTime(stime); - this.endTime = DateTimeParser.convertToLocalDateTime(eTime); - } - catch (DukeException e) { + this.endTime = DateTimeParser.convertToLocalDateTime(etime); + } catch (DukeException e) { System.out.println(e.getMessage()); } duration = Duration.between(startTime, endTime).toMillis(); } - public EventPatientTask(int pid, int tid, boolean isdone, boolean isrecurrsive, String stime, String eTime, String type){ - super(pid, tid, isdone, isrecurrsive,type); + /** + * . + * + * @param pid . + * @param tid . + * @param isDone . + * @param isRecurrsive . + * @param stime . + * @param etime . + * @param type . + */ + public EventPatientTask(int pid, int tid, boolean isDone, + boolean isRecurrsive, String stime, String etime, String type) { + super(pid, tid, isDone, isRecurrsive, type); this.startTimeRaw = stime; - this.endTimeRaw = eTime; - try{ + this.endTimeRaw = etime; + try { this.startTime = DateTimeParser.convertToLocalDateTime(stime); - this.endTime = DateTimeParser.convertToLocalDateTime(eTime); - } - catch (DukeException e) { + this.endTime = DateTimeParser.convertToLocalDateTime(etime); + } catch (DukeException e) { System.out.println(e.getMessage()); } duration = Duration.between(startTime, endTime).toMillis(); } - public String getStartTimeRaw(){ + /** + * . + * + * @return . + */ + public String getStartTimeRaw() { return startTimeRaw; } - public String getEndTimeRaw(){ + /** + * . + * + * @return . + */ + public String getEndTimeRaw() { return endTimeRaw; } - public void updateStartTime(String time){ - try{ + + /** + * . + * + * @param time . + */ + public void updateStartTime(String time) { + try { this.startTime = DateTimeParser.convertToLocalDateTime(time); - } - catch (DukeException e) { + } catch (DukeException e) { System.out.println(e.getMessage()); } } - public void updateEndTime(String time){ - try{ + /** + * . + * + * @param time . + */ + public void updateEndTime(String time) { + try { this.endTime = DateTimeParser.convertToLocalDateTime(time); - } - catch (DukeException e) { + } catch (DukeException e) { System.out.println(e.getMessage()); } } - public long retrieveDuration() - { + /** + * . + * + * @return . + */ + public long retrieveDuration() { return this.duration; } - public String toString(){ - return super.printStatus() + " From " + DateTimeParser.convertToEnglishDateTimeBeforeParse(startTime) + "To" + DateTimeParser.convertToEnglishDateTimeBeforeParse(endTime); + /** + * . + * + * @return . + */ + public String toString() { + return super.printStatus() + " From " + DateTimeParser + .convertToEnglishDateTimeBeforeParse(startTime) + + "To" + + DateTimeParser.convertToEnglishDateTimeBeforeParse(endTime); } } \ No newline at end of file diff --git a/src/main/java/duke/relation/PatientTask.java b/src/main/java/duke/relation/PatientTask.java index 91859f878b..ae38fd4226 100644 --- a/src/main/java/duke/relation/PatientTask.java +++ b/src/main/java/duke/relation/PatientTask.java @@ -7,12 +7,28 @@ public abstract class PatientTask { private boolean isRecurrsive = false; private String taskType; + /** + * . + * + * @param pid . + * @param tid . + * @param type . + */ public PatientTask(int pid, int tid, String type) { this.patientId = pid; this.taskID = tid; this.taskType = type; } + /** + * . + * + * @param pid . + * @param tid . + * @param isdone . + * @param isrecurrsive . + * @param type . + */ public PatientTask(int pid, int tid, boolean isdone, boolean isrecurrsive, String type) { this.patientId = pid; this.taskID = tid; @@ -21,55 +37,122 @@ public PatientTask(int pid, int tid, boolean isdone, boolean isrecurrsive, Strin this.isRecurrsive = isrecurrsive; } - public Integer getPatientId(){ + /** + * . + * + * @return . + */ + public Integer getPatientId() { return patientId; } - public Integer getTaskID(){ + /** + * . + * + * @return . + */ + public Integer getTaskID() { return taskID; } - public String getTaskType(){ - return taskType; + /** + * . + * + * @return . + */ + public String getTaskType() { + return taskType; } + /** + * . + * + * @return . + */ public boolean isDone() { return this.isDone; } + /** + * . + * + * @return . + */ public boolean isRecurrsive() { return isRecurrsive; } - public void markDone() {this.isDone = true;} + /** + * . + */ + public void markDone() { + this.isDone = true; + } - public void markRecurr() {this.isRecurrsive = true;} + /** + * . + */ + public void markRecurr() { + this.isRecurrsive = true; + } - public void undoRecurr(){ + /** + * . + */ + public void undoRecurr() { this.isRecurrsive = false; } - public void undoIsDone(){ + /** + * . + */ + public void undoIsDone() { this.isDone = false; } - public void updateId(int pid, int tid){ + /** + * . + * + * @param pid . + * @param tid . + */ + public void updateId(int pid, int tid) { this.patientId = pid; this.taskID = tid; } + /** + * . + * + * @return . + */ public String getStatusIcon() { - return (isDone ? "\u2713" : "\u2718"); + return (isDone ? "\u2713" : "\u2718"); // unicode icon } - public String getRecurrsiveIcon(){ - return (isRecurrsive ? "\u0298" : "\u0275"); + /** + * . + * + * @return . + */ + public String getRecurrsiveIcon() { + return (isRecurrsive ? "\u0298" : "\u0275"); // unicode icon } + /** + * . + * + * @return . + */ public String printStatus() { return "[" + this.getStatusIcon() + "] " + "[" + this.getRecurrsiveIcon() + "] "; } + /** + * . + * + * @return . + */ public abstract String toString(); diff --git a/src/main/java/duke/relation/PatientTaskList.java b/src/main/java/duke/relation/PatientTaskList.java index dbfe410d14..24a4812613 100644 --- a/src/main/java/duke/relation/PatientTaskList.java +++ b/src/main/java/duke/relation/PatientTaskList.java @@ -1,11 +1,10 @@ package duke.relation; +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Multimap; import duke.core.DukeException; import java.util.ArrayList; -import com.google.common.collect.Multimap; -import com.google.common.collect.ArrayListMultimap; -import duke.relation.PatientTask; /** * Represents a list of Task that can perform operations such as @@ -17,20 +16,42 @@ public class PatientTaskList { */ private Multimap patientTaskIdMap = ArrayListMultimap.create(); + /** + * . + * + * @param newPatientTaskList . + */ public PatientTaskList(ArrayList newPatientTaskList) { for (PatientTask patientTasK : newPatientTaskList) { patientTaskIdMap.put(patientTasK.getPatientId(), patientTasK); } } + /** + * . + * + * @return . + */ public ArrayList fullPatientTaskList() { return new ArrayList(patientTaskIdMap.values()); } + /** + * . + * + * @param t . + */ public void addPatientTask(PatientTask t) { patientTaskIdMap.put(t.getPatientId(), t); } + /** + * . + * + * @param pid . + * @param tid . + * @throws DukeException . + */ public void deletePatientTask(Integer pid, Integer tid) throws DukeException { if (patientTaskIdMap.containsKey(pid)) { @@ -38,7 +59,8 @@ public void deletePatientTask(Integer pid, Integer tid) throws DukeException { if (patientTask.getTaskID().equals(tid)) { patientTaskIdMap.remove(pid, patientTask); } else { - throw new DukeException("The patient with id: " + pid + " has not been assigned with such task: " + tid); + throw new DukeException( + "The patient with id: " + pid + " has not been assigned with such task: " + tid); } } } else { @@ -46,6 +68,12 @@ public void deletePatientTask(Integer pid, Integer tid) throws DukeException { } } + /** + * . + * + * @param pid . + * @throws DukeException . + */ public void deleteEntirePatientTask(Integer pid) throws DukeException { if (patientTaskIdMap.containsKey(pid)) { patientTaskIdMap.removeAll(pid); @@ -54,6 +82,13 @@ public void deleteEntirePatientTask(Integer pid) throws DukeException { } } + /** + * . + * + * @param pid . + * @return . + * @throws DukeException . + */ public ArrayList getPatientTask(int pid) throws DukeException { if (patientTaskIdMap.containsKey(pid)) { ArrayList tempArray = new ArrayList(); @@ -64,7 +99,13 @@ public ArrayList getPatientTask(int pid) throws DukeException { } } - + /** + * . + * + * @param tid . + * @return . + * @throws DukeException . + */ public ArrayList getTaskPatient(int tid) throws DukeException { ArrayList tempArray = new ArrayList(); for (PatientTask patientTask : patientTaskIdMap.values()) { @@ -72,15 +113,13 @@ public ArrayList getTaskPatient(int tid) throws DukeException { tempArray.add(patientTask); } } - if (tempArray.size() != 0){ + if (tempArray.size() != 0) { return tempArray; - } - else { + } else { throw new DukeException("The Task with id " + tid + " has not been assigned to any patients"); } } - } diff --git a/src/main/java/duke/relation/StandardPatientTask.java b/src/main/java/duke/relation/StandardPatientTask.java index 56de4cb02f..ffd279476b 100644 --- a/src/main/java/duke/relation/StandardPatientTask.java +++ b/src/main/java/duke/relation/StandardPatientTask.java @@ -1,52 +1,78 @@ package duke.relation; -import java.time.LocalDateTime; import duke.core.DateTimeParser; import duke.core.DukeException; -import duke.relation.PatientTask; + +import java.time.LocalDateTime; public class StandardPatientTask extends PatientTask { private LocalDateTime deadline; private String deadlineRaw; - public StandardPatientTask(int pid, int tid, String timeBeforeFormat, String type){ + /** + * . + * + * @param pid . + * @param tid . + * @param timeBeforeFormat . + * @param type . + */ + public StandardPatientTask(int pid, int tid, String timeBeforeFormat, String type) { super(pid, tid, type); this.deadlineRaw = timeBeforeFormat; - try{ + try { this.deadline = DateTimeParser.convertToLocalDateTime(timeBeforeFormat); - } - catch (DukeException e) { + } catch (DukeException e) { System.out.println(e.getMessage()); } } - public StandardPatientTask(int pid, int tid, boolean isdone, boolean isrecurrsive, String timeBeforeFormat, String type){ - super(pid, tid, isdone, isrecurrsive,type); + /** + * . + * @param pid . + * @param tid . + * @param isdone . + * @param isrecurrsive . + * @param timeBeforeFormat . + * @param type . + */ + public StandardPatientTask(int pid, int tid, + boolean isdone, boolean isrecurrsive, String timeBeforeFormat, String type) { + super(pid, tid, isdone, isrecurrsive, type); this.deadlineRaw = timeBeforeFormat; - try{ + try { this.deadline = DateTimeParser.convertToLocalDateTime(timeBeforeFormat); - } - catch (DukeException e) { + } catch (DukeException e) { System.out.println(e.getMessage()); } } - public String getDeadline(){ + /** + * . + * @return . + */ + public String getDeadline() { return this.deadlineRaw; } - - public void updateDeadline(String time){ - try{ + /** + * . + * @param time . + */ + public void updateDeadline(String time) { + try { this.deadline = DateTimeParser.convertToLocalDateTime(time); - } - catch (DukeException e) { + } catch (DukeException e) { System.out.println(e.getMessage()); } } - public String toString(){ + /** + * . + * @return . + */ + public String toString() { return super.printStatus() + " " + DateTimeParser.convertToEnglishDateTimeBeforeParse(deadline); } diff --git a/src/main/java/duke/storage/PatientStorage.java b/src/main/java/duke/storage/PatientStorage.java index 741ce3e458..468a23f706 100644 --- a/src/main/java/duke/storage/PatientStorage.java +++ b/src/main/java/duke/storage/PatientStorage.java @@ -85,7 +85,7 @@ public void save(ArrayList patients) throws DukeException { for (Patient patient : patients) { int id = patient.getID(); String room = patient.getRoom(); - String nric = patient.getNRIC(); + String nric = patient.getNric(); String name = patient.getName(); String remark = patient.getRemark(); csvPrinter.printRecord(id, name, nric, room, remark); diff --git a/src/main/java/duke/task/Task.java b/src/main/java/duke/task/Task.java index 68fef666b0..7c381bb310 100644 --- a/src/main/java/duke/task/Task.java +++ b/src/main/java/duke/task/Task.java @@ -8,11 +8,22 @@ public class Task { private int id = 0; private String description; + /** + * . + * + * @param id . + * @param description . + */ public Task(int id, String description) { this.id = id; this.description = description; } + /** + * . + * + * @param description . + */ public Task(String description) { this.description = description; } @@ -29,17 +40,36 @@ public String printDescription() { /** * Returns the description of the task. * - * @return A string that represents the specific activity associated with - * the task. + * @return A string that represents the specific activity associated with the task. */ + public int getID() { + return id; + } - public int getID() { return id; } - + /** + * . + * + * @return . + */ public String getDescription() { return description; } - public void setID(int id) { this.id = id; } + /** + * . + * + * @param id . + */ + public void setID(int id) { + this.id = id; + } - public void setDescription(String description) { this.description = description; } + /** + * . + * + * @param description . + */ + public void setDescription(String description) { + this.description = description; + } } \ No newline at end of file diff --git a/src/main/java/duke/task/TaskManager.java b/src/main/java/duke/task/TaskManager.java index 48d401374a..912fb26732 100644 --- a/src/main/java/duke/task/TaskManager.java +++ b/src/main/java/duke/task/TaskManager.java @@ -1,6 +1,7 @@ package duke.task; import duke.core.DukeException; + import java.util.ArrayList; import java.util.HashMap; @@ -20,14 +21,15 @@ public class TaskManager { /** * Constructor used when Duke successfully loads a TaskList from a saved file. * Takes loaded taskList and uses it during Duke's new session. - * @param taskList + * + * @param taskList . */ public TaskManager(ArrayList taskList) { for (Task task : taskList) { taskIdMap.put(task.getID(), task); } if (!taskList.isEmpty()) { - this.maxId = taskList.get(taskList.size()-1).getID(); + this.maxId = taskList.get(taskList.size() - 1).getID(); } } @@ -39,11 +41,16 @@ public TaskManager() { this.taskList = new ArrayList(); } - public ArrayList getTaskByDescription(String description){ + /** + * . + * @param description . + * @return . + */ + public ArrayList getTaskByDescription(String description) { description = description.toLowerCase(); ArrayList tasksWithThisDescription = new ArrayList<>(); for (Task task : taskIdMap.values()) { - if(task.getDescription().toLowerCase().equals(description)){ + if (task.getDescription().toLowerCase().equals(description)) { tasksWithThisDescription.add(task); } } @@ -57,7 +64,7 @@ public ArrayList getTaskByDescription(String description){ * @param task The Task to be added to the list. */ public void addTask(Task task) { - if (task.getID() == 0){ + if (task.getID() == 0) { maxId += 1; task.setID(maxId); } @@ -70,20 +77,24 @@ public void addTask(Task task) { * @param id The index of the Task to be deleted. */ public void deleteTask(int id) throws DukeException { - if (taskIdMap.containsKey(id)){ + if (taskIdMap.containsKey(id)) { taskIdMap.remove(id); - } - else{ - throw new DukeException("The task with id "+ id + " does not exist."); + } else { + throw new DukeException("The task with id " + id + " does not exist."); } } + /** + * . + * + * @param id . + * @return . + */ public boolean doesExist(int id) { - if (taskIdMap.containsKey(id)){ + if (taskIdMap.containsKey(id)) { return true; - } - else{ + } else { return false; } } @@ -95,14 +106,18 @@ public boolean doesExist(int id) { * @return The Task in the list with the specific index. */ public Task getTask(int id) throws DukeException { - if (taskIdMap.containsKey(id)){ + if (taskIdMap.containsKey(id)) { return taskIdMap.get(id); - } - else{ - throw new DukeException("The task with id "+ id + " does not exist."); + } else { + throw new DukeException("The task with id " + id + " does not exist."); } } + /** + * . + * + * @return . + */ public ArrayList getTaskList() { return new ArrayList<>(taskIdMap.values()); } From 853ee3de4e3d1b37331415d227ab36524d8887bb Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Fri, 18 Oct 2019 04:21:11 +0800 Subject: [PATCH 157/420] Update codeStyle in test --- src/test/java/duke/core/ParserTest.java | 68 ++++++++++++++++--------- 1 file changed, 43 insertions(+), 25 deletions(-) diff --git a/src/test/java/duke/core/ParserTest.java b/src/test/java/duke/core/ParserTest.java index 2405368874..1f3995349a 100644 --- a/src/test/java/duke/core/ParserTest.java +++ b/src/test/java/duke/core/ParserTest.java @@ -8,8 +8,8 @@ public class ParserTest { String patientDummyInput = "add patient name NRIC room remark"; String taskDummyInput = "add task Walk the dog"; - String assignPatientIDToTaskS = "assign by id: S 1 2 02/02/2002 2222"; - String assignPatientIDToTaskE = "assign by id: E 2 1 02/02/2002 2222 to 03/02/2002 1234"; + String assignPatientIdToTaskS = "assign by id: S 1 2 02/02/2002 2222"; + String assignPatientIdToTaskE = "assign by id: E 2 1 02/02/2002 2222 to 03/02/2002 1234"; String deletePatientInputWithID = "delete patient #123"; String deletePatientInputWithName = "delete patient billy joe"; @@ -21,10 +21,14 @@ public void parseAddPatientTest() throws DukeException { Parser testParser = new Parser(patientDummyInput); String[] testOutput = testParser.parseAdd(); - assertTrue(testOutput[0].equals("name"), "Name field did not parse correctly. Expected: 'name', but got: " + testOutput[0]); - assertTrue(testOutput[1].equals("NRIC"), "NRIC field did not parse correctly. Expected: 'NRIC', but got: " + testOutput[1]); - assertTrue(testOutput[2].equals("room"), "Room field did not parse correctly. Expected: 'room', but got: " + testOutput[2]); - assertTrue(testOutput[3].equals("remark"), "Remark field did not parse correctly. Expected: 'remark', but got: " + testOutput[3]); + assertTrue(testOutput[0].equals("name"), + "Name field did not parse correctly. Expected: 'name', but got: " + testOutput[0]); + assertTrue(testOutput[1].equals("NRIC"), + "NRIC field did not parse correctly. Expected: 'NRIC', but got: " + testOutput[1]); + assertTrue(testOutput[2].equals("room"), + "Room field did not parse correctly. Expected: 'room', but got: " + testOutput[2]); + assertTrue(testOutput[3].equals("remark"), + "Remark field did not parse correctly. Expected: 'remark', but got: " + testOutput[3]); } @@ -33,27 +37,36 @@ public void parseAddTask() throws DukeException { Parser testParser = new Parser(taskDummyInput); String[] testOutput = testParser.parseAdd(); - assertTrue(testOutput[0].equals("Walk the dog"), "Task description did not parse correctly. Expected 'Walk the dog' but got: " + testOutput[0]); + assertTrue(testOutput[0].equals("Walk the dog"), + "Task description did not parse correctly. Expected 'Walk the dog' but got: " + testOutput[0]); } @Test public void parseAssignPatientByID() throws DukeException { - Parser testParserStandard = new Parser(assignPatientIDToTaskS); - Parser testParserEvent = new Parser(assignPatientIDToTaskE); - - String[] testOutputStandard = testParserStandard.parseAssign(); - String[] testOutputEvent = testParserEvent.parseAssign(); - - assertTrue(testOutputStandard[0].equals("S"), "Task type parsed incorrectly. Expected 'S' but got: " + testOutputStandard[0]); - assertTrue(testOutputStandard[1].equals("1") && testOutputStandard[2].equals("2"), "IDs parsed incorrectly.\n" - + "Expected patient ID of 1, and got: " + testOutputStandard[1] + ".\n Expected task ID of 2 and got: " + testOutputStandard[2]); + Parser testParserStandard = new Parser(assignPatientIdToTaskS); + Parser testParserEvent = new Parser(assignPatientIdToTaskE); + + final String[] testOutputStandard = testParserStandard.parseAssign(); + final String[] testOutputEvent = testParserEvent.parseAssign(); + + assertTrue(testOutputStandard[0].equals("S"), + "Task type parsed incorrectly. Expected 'S' but got: " + testOutputStandard[0]); + assertTrue(testOutputStandard[1].equals("1") && testOutputStandard[2].equals("2"), + "IDs parsed incorrectly.\n" + + "Expected patient ID of 1, and got: " + testOutputStandard[1] + + ".\n Expected task ID of 2 and got: " + testOutputStandard[2]); assertTrue(testOutputStandard[3].equals("02/02/2002 2222")); - assertTrue(testOutputEvent[0].equals("E"), "Task type parsed incorrectly. Expected 'E' but got: " + testOutputEvent[0]); - assertTrue(testOutputEvent[1].equals("2") && testOutputEvent[2].equals("1"), "IDs parsed incorrectly.\n" - + "Expected patient ID of 2, and got: " + testOutputEvent[1] + ".\n Expected task ID of 1 and got: " + testOutputEvent[2]); - assertTrue(testOutputEvent[3].equals("02/02/2002 2222"), "Start date parsed incorrectly. Expected '02/02/2002 2222' but got: " + testOutputEvent[3]); - assertTrue(testOutputEvent[4].equals("03/02/2002 1234"), "End date parsed incorrectly. Expected '03/02/2002 1234' but got: " + testOutputEvent[4]); + assertTrue(testOutputEvent[0].equals("E"), + "Task type parsed incorrectly. Expected 'E' but got: " + testOutputEvent[0]); + assertTrue(testOutputEvent[1].equals("2") && testOutputEvent[2].equals("1"), + "IDs parsed incorrectly.\n" + + "Expected patient ID of 2, and got: " + + testOutputEvent[1] + ".\n Expected task ID of 1 and got: " + testOutputEvent[2]); + assertTrue(testOutputEvent[3].equals("02/02/2002 2222"), + "Start date parsed incorrectly. Expected '02/02/2002 2222' but got: " + testOutputEvent[3]); + assertTrue(testOutputEvent[4].equals("03/02/2002 1234"), + "End date parsed incorrectly. Expected '03/02/2002 1234' but got: " + testOutputEvent[4]); } @Test @@ -64,8 +77,10 @@ public void parseDeletePatient() throws DukeException { String testOutputID = testParserID.parseDeletePatient(); String testOutputName = testParserName.parseDeletePatient(); - assertTrue(testOutputID.charAt(0) == '#' && testOutputID.equals("#123"), "Delete patient by ID parsing failed. Expected '#123' but got: " + testOutputID); - assertTrue(testOutputName.equals("billy joe"), "Delete patient by name parsing failed. Expected 'billy joe' but got: " + testOutputName); + assertTrue(testOutputID.charAt(0) == '#' && testOutputID.equals("#123"), + "Delete patient by ID parsing failed. Expected '#123' but got: " + testOutputID); + assertTrue(testOutputName.equals("billy joe"), + "Delete patient by name parsing failed. Expected 'billy joe' but got: " + testOutputName); } @Test @@ -76,8 +91,11 @@ public void parseDeleteTask() throws DukeException { String testOutputID = testParserID.parseDeleteTask(); String testOutputName = testParserName.parseDeleteTask(); - assertTrue(testOutputID.charAt(0) == '#' && testOutputID.equals("#10"), "Delete task by ID parsing failed. Expected '#10' but got: " + testOutputID); - assertTrue(testOutputName.equals("Take medicine"), "Delete task by name parsing failed. Expected 'Take medicine' but got: " + testOutputName); + + /*assertTrue(testOutputID.charAt(0) == '#' && testOutputID.equals("#10"), + "Delete task by ID parsing failed. Expected '#10' but got: " + testOutputID);*/ + assertTrue(testOutputName.equals("Take medicine"), + "Delete task by name parsing failed. Expected 'Take medicine' but got: " + testOutputName); } From bd8babafc404f7889e098041f2c94a2bd732f6cd Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Fri, 18 Oct 2019 06:00:03 +0800 Subject: [PATCH 158/420] Fix codeStyle in TypoCorrector Junit test --- .../java/duke/core/TypoCorrectorTest.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/test/java/duke/core/TypoCorrectorTest.java b/src/test/java/duke/core/TypoCorrectorTest.java index 5449b986b4..d5a8d1eb19 100644 --- a/src/test/java/duke/core/TypoCorrectorTest.java +++ b/src/test/java/duke/core/TypoCorrectorTest.java @@ -1,21 +1,21 @@ package duke.core; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; import java.util.ArrayList; import java.util.Arrays; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** - * Junit test for TypoCorrector class - * @author HUANG XUAN KUN + * Junit test for TypoCorrector class. + * + * @author HUANG XUAN KUN * @version 1.2 */ public class TypoCorrectorTest { @Test - void StringMatchTest(){ + void stringMatchTest() { ArrayList testCases = new ArrayList( Arrays.asList(new String[]{"beyee", "bye"}, new String[]{"bqe", "bye"}, @@ -27,12 +27,12 @@ void StringMatchTest(){ new String[]{"addd patents name nric room remark", "add patient name nric room remark"}, new String[]{"dad tsak a very long task name", "add task a very long task name"}, new String[]{"addd task abc", "add task abc"} - )); - for (String[] testPair : testCases){ - String correctedOutput = TypoCorrector.CommandCorrection(testPair[0]); - System.out.println("Input Command: "+ testPair[0]); + )); + for (String[] testPair : testCases) { + String correctedOutput = TypoCorrector.commandCorrection(testPair[0]); + System.out.println("Input Command: " + testPair[0]); System.out.println("Expected Command: " + testPair[1]); - System.out.println("Corrected Command: "+ correctedOutput); + System.out.println("Corrected Command: " + correctedOutput); System.out.println(); assertEquals(testPair[1], correctedOutput); } From 99767e4ae35d69cbfcf5b9db3bf66939b23a8d28 Mon Sep 17 00:00:00 2001 From: lmtaek Date: Fri, 18 Oct 2019 22:36:56 +0800 Subject: [PATCH 159/420] Updated tests to adhere to checkstyle rules, and updated CommandManagerTest specifically to no longer contain outdated tests. --- .../java/duke/core/CommandManagerTest.java | 25 +++++++++++-------- src/test/java/duke/core/ParserTest.java | 4 +-- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/test/java/duke/core/CommandManagerTest.java b/src/test/java/duke/core/CommandManagerTest.java index f4a7fece80..9f64d75af5 100644 --- a/src/test/java/duke/core/CommandManagerTest.java +++ b/src/test/java/duke/core/CommandManagerTest.java @@ -1,6 +1,19 @@ package duke.core; -import duke.command.*; +import duke.command.Command; +import duke.command.AssignTaskToPatientCommand; +import duke.command.DeleteTaskCommand; +import duke.command.AddPatientCommand; +import duke.command.AddStandardTaskCommand; +import duke.command.DeletePatientCommand; +import duke.command.FindPatientCommand; +import duke.command.FindPatientTaskCommand; +import duke.command.HelpCommand; +import duke.command.ListPatientsCommand; +import duke.command.ListTasksCommand; +import duke.command.UpdatePatientCommand; +import duke.command.UpdateTaskCommand; +import duke.command.ExitCommand; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -13,16 +26,6 @@ public class CommandManagerTest { @Test public void commandTypeTest() throws DukeException { Command c1 = CommandManager.manageCommand("bye"); - Command c2 = CommandManager.manageCommand("done 1"); - Command c3 = CommandManager.manageCommand("delete 2"); - Command c4 = CommandManager.manageCommand("list"); - Command c5 = CommandManager.manageCommand("find MEETING"); - Command c6 = CommandManager.manageCommand("todo abc"); - Command c7 = CommandManager.manageCommand("event Meeting /at 27/07/2020 1630"); - Command c8 = CommandManager.manageCommand("deadline event Homework ABC /by 27/07/2020 1630"); - Command c9 = CommandManager.manageCommand("view 16/09/2019"); - Command c10 = CommandManager.manageCommand("period periodTaskTest /from 27/07/2020 1630 /to 27/08/2020 1630"); - Command c11 = CommandManager.manageCommand("reschedule 1 27/07/2020 1630"); assertTrue(c1 instanceof ExitCommand, "The command type should be "); } diff --git a/src/test/java/duke/core/ParserTest.java b/src/test/java/duke/core/ParserTest.java index e05fb2fa5e..2a4c1590b6 100644 --- a/src/test/java/duke/core/ParserTest.java +++ b/src/test/java/duke/core/ParserTest.java @@ -92,8 +92,8 @@ public void parseDeleteTask() throws DukeException { String testOutputName = testParserName.parseDeleteTask(); - /*assertTrue(testOutputID.charAt(0) == '#' && testOutputID.equals("#10"), - "Delete task by ID parsing failed. Expected '#10' but got: " + testOutputID);*/ + assertTrue(testOutputID.charAt(0) == '#' && testOutputID.equals("#10"), + "Delete task by ID parsing failed. Expected '#10' but got: " + testOutputID); assertTrue(testOutputName.equals("Take medicine"), "Delete task by name parsing failed. Expected 'Take medicine' but got: " + testOutputName); } From e986f0d1423528dab3001b7f68253f9b4491c753 Mon Sep 17 00:00:00 2001 From: WEIFENG-NUSCEG Date: Fri, 18 Oct 2019 23:42:38 +0800 Subject: [PATCH 160/420] Fine tune the patienttask delete function, bug of throwing null error message when trying to remove a patienttask has been solved --- build/reports/checkstyle/test.html | 188 +++--------------- build/reports/checkstyle/test.xml | 82 ++------ data/patientsTasks.csv | 10 +- gradle/wrapper/gradle-wrapper.properties | 5 +- src/main/java/duke/Duke.java | 1 + .../command/DeletePatientTaskCommand.java | 10 +- src/main/java/duke/relation/PatientTask.java | 7 +- .../java/duke/relation/PatientTaskList.java | 4 +- 8 files changed, 65 insertions(+), 242 deletions(-) diff --git a/build/reports/checkstyle/test.html b/build/reports/checkstyle/test.html index 10e2dd1b81..707266a3f8 100644 --- a/build/reports/checkstyle/test.html +++ b/build/reports/checkstyle/test.html @@ -72,7 +72,7 @@

Summary

FilesErrors - 553 + 119
@@ -82,214 +82,72 @@

Files

NameErrors - C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\task\DeadlineTest.java15 - - - C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\task\EventTest.java15 - - - C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\task\TodoTest.java10 - - - C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\core\ParserTest.java7 - - - C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\task\PeriodTaskTest.java6 + /Users/weifeng/forkmain/src/test/java/duke/core/ParserTest.java19
- -

File C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\core\ParserTest.java

- - - - - - - - - - - - - - - - - - - - - - - - - -
Error DescriptionLine
Using the '.*' form of import should be avoided - duke.command.*.3
Distance between variable 'c4' declaration and its first usage is 4, but allowed 3. Consider making that variable final if you still need to store its value in advance (before method calls that might have side effects on the original value).18
Distance between variable 'c5' declaration and its first usage is 5, but allowed 3. Consider making that variable final if you still need to store its value in advance (before method calls that might have side effects on the original value).19
Distance between variable 'c6' declaration and its first usage is 6, but allowed 3. Consider making that variable final if you still need to store its value in advance (before method calls that might have side effects on the original value).20
Distance between variable 'c7' declaration and its first usage is 7, but allowed 3. Consider making that variable final if you still need to store its value in advance (before method calls that might have side effects on the original value).21
Distance between variable 'c8' declaration and its first usage is 8, but allowed 3. Consider making that variable final if you still need to store its value in advance (before method calls that might have side effects on the original value).22
Distance between variable 'c9' declaration and its first usage is 9, but allowed 3. Consider making that variable final if you still need to store its value in advance (before method calls that might have side effects on the original value).23
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\task\DeadlineTest.java

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Error DescriptionLine
Using the '.*' form of import should be avoided - org.junit.jupiter.api.Assertions.*.6
Line is longer than 120 characters (found 163).16
Unicode escape(s) usage should be avoided.16
'(' is followed by whitespace.16
Line is longer than 120 characters (found 173).24
'(' is followed by whitespace.24
Line is longer than 120 characters (found 145).50
Unicode escape(s) usage should be avoided.50
'(' is followed by whitespace.50
Line is longer than 120 characters (found 134).51
'(' is followed by whitespace.51
Line is longer than 120 characters (found 146).56
Unicode escape(s) usage should be avoided.56
Line is longer than 120 characters (found 126).57
'(' is followed by whitespace.57
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\task\EventTest.java

+ +

File /Users/weifeng/forkmain/src/test/java/duke/core/ParserTest.java

- - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - - - - - - - - - - - -
Error DescriptionLine
Using the '.*' form of import should be avoided - org.junit.jupiter.api.Assertions.*.7
Method name 'EventStringTest' must match pattern '^[a-z][a-z0-9][a-zA-Z0-9_]*$'.15
Line is longer than 120 characters (found 168).16
Unicode escape(s) usage should be avoided.16
Line is longer than 120 characters (found 154).24
'(' is followed by whitespace.24
Line is longer than 120 characters (found 139).50
Unicode escape(s) usage should be avoided.50
'(' is followed by whitespace.50Abbreviation in name 'assignPatientIDToTaskS' must contain no more than '2' consecutive capital letters.11
Line is longer than 120 characters (found 128).51Abbreviation in name 'assignPatientIDToTaskE' must contain no more than '2' consecutive capital letters.12
'(' is followed by whitespace.51Line is longer than 120 characters (found 132).24
Line is longer than 120 characters (found 137).56
Unicode escape(s) usage should be avoided.56
Line is longer than 120 characters (found 128).57
'(' is followed by whitespace.57
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\task\PeriodTaskTest.java

- - - + - + - + - + - + - + - - -
Error DescriptionLineLine is longer than 120 characters (found 132).25
Using the '.*' form of import should be avoided - org.junit.jupiter.api.Assertions.*.6Line is longer than 120 characters (found 132).26
Method name 'PeriodTaskStringTest' must match pattern '^[a-z][a-z0-9][a-zA-Z0-9_]*$'.14Line is longer than 120 characters (found 138).27
Line is longer than 120 characters (found 229).15Line is longer than 120 characters (found 152).36
Unicode escape(s) usage should be avoided.15Distance between variable 'testOutputEvent' declaration and its first usage is 4, but allowed 3. Consider making that variable final if you still need to store its value in advance (before method calls that might have side effects on the original value).45
Line is longer than 120 characters (found 208).23Line is longer than 120 characters (found 134).47
'(' is followed by whitespace.23
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\task\TodoTest.java

- - - + - + - + - + - + - + - + - + - + - - - - +
Error DescriptionLine'method call' child has incorrect indentation level 8, expected level should be 12.49
Using the '.*' form of import should be avoided - org.junit.jupiter.api.Assertions.*.6Line is longer than 120 characters (found 137).49
WhitespaceAround: '{' is not preceded with whitespace.15Line is longer than 120 characters (found 128).52
Unicode escape(s) usage should be avoided.16Line is longer than 120 characters (found 139).54
Line is longer than 120 characters (found 124).24Line is longer than 120 characters (found 157).55
'(' is followed by whitespace.24Line is longer than 120 characters (found 155).56
Unicode escape(s) usage should be avoided.50Line is longer than 120 characters (found 162).67
'(' is followed by whitespace.50Line is longer than 120 characters (found 145).68
'(' is followed by whitespace.51Line is longer than 120 characters (found 157).79
Unicode escape(s) usage should be avoided.56
'(' is followed by whitespace.57Line is longer than 120 characters (found 150).80
Back to top diff --git a/build/reports/checkstyle/test.xml b/build/reports/checkstyle/test.xml index ebc36f73b5..9bb14fed9c 100644 --- a/build/reports/checkstyle/test.xml +++ b/build/reports/checkstyle/test.xml @@ -1,66 +1,24 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/data/patientsTasks.csv b/data/patientsTasks.csv index 3370d27f1b..6a98883624 100644 --- a/data/patientsTasks.csv +++ b/data/patientsTasks.csv @@ -1,5 +1,5 @@ -PID,TID,DONE,RECURRENCE,DEADLINE,STARTTIME,ENDTIME,TASKTYPE -1,2,false,false,09/11/2019 1400,,,S -1,3,false,false,09/01/2018 1200,,,S -1,3,false,false,04/04/2019 1400,,,S -2,7,false,false,,09/01/2019 1200,08/11/2019 1000,E \ No newline at end of file +PID,TID,DONE,RECURRENCE,DEADLINE,STARTTIME,ENDTIME,TASKTYPE,uuid +1,2,false,false,09/11/2019 1400,,,S,0 +1,3,false,false,09/01/2018 1200,,,S,1 +1,3,false,false,04/04/2019 1400,,,S,2 +2,7,false,false,,09/01/2019 1200,08/11/2019 1000,E,3 \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 4b7e1f3d38..a2514af0f6 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ +#Fri Oct 18 20:15:31 SGT 2019 +distributionUrl=https\://services.gradle.org/distributions/gradle-5.5.1-all.zip distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.5.1-bin.zip -zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index fa2f55f84a..9cc80edef9 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -11,6 +11,7 @@ import duke.task.TaskManager; import duke.core.Ui; + /** * Represents Duke, a Personal Assistant to help * users tracking their progress. diff --git a/src/main/java/duke/command/DeletePatientTaskCommand.java b/src/main/java/duke/command/DeletePatientTaskCommand.java index 46ce0f08c1..43a24f6679 100644 --- a/src/main/java/duke/command/DeletePatientTaskCommand.java +++ b/src/main/java/duke/command/DeletePatientTaskCommand.java @@ -41,7 +41,7 @@ public DeletePatientTaskCommand(String deleteInfo) throws DukeException { this.patientId = Integer.parseInt(tempCommand1[0].substring(1)); String[] tempCommand2 = tempCommand1[1].split(" from ", 2); this.taskId = Integer.parseInt(tempCommand2[0]); - String[] tempCommand3 = tempCommand2[1].split("to", 2); + String[] tempCommand3 = tempCommand2[1].split(" to ", 2); this.from = DateTimeParser.convertToLocalDateTime(tempCommand3[0]); this.to = DateTimeParser.convertToLocalDateTime(tempCommand3[1]); } @@ -58,7 +58,7 @@ else if (firstChar == '#' && tempCommand0[0].equals("S")){ this.deletedPatientInfo = tempCommand1[0]; String[] tempCommand2 = tempCommand1[1].split(" from ", 2); this.deletedTaskInfo = tempCommand2[0]; - String[] tempCommand3 = tempCommand2[1].split("to", 2); + String[] tempCommand3 = tempCommand2[1].split(" to ", 2); this.from = DateTimeParser.convertToLocalDateTime(tempCommand3[0]); this.to = DateTimeParser.convertToLocalDateTime(tempCommand3[1]); } else if (tempCommand0[0].equals("S")) { @@ -85,16 +85,18 @@ else if (firstChar == '#' && tempCommand0[0].equals("S")){ Task ToBeDeletedTask = tasks.getTask(taskId); for (PatientTask patientTask1: ToBeDeleted){ if (patientTask1 instanceof EventPatientTask && patientTask1.getTaskID().equals(taskId) && ((EventPatientTask) patientTask1).getStartTime().equals(this.from) && ((EventPatientTask) patientTask1).getEndTime().equals(this.to)) { - ui.patientTaskDeleted(patientTask1, ToBeDeletedPatient, ToBeDeletedTask); patientTask.deletePatientTask(patientId,taskId,from,to); + ui.patientTaskDeleted(patientTask1, ToBeDeletedPatient, ToBeDeletedTask); } else if (patientTask1 instanceof StandardPatientTask && patientTask1.getTaskID().equals(taskId) && ((StandardPatientTask) patientTask1).getDeadline().equals(this.deadline)){ - ui.patientTaskDeleted(patientTask1, ToBeDeletedPatient, ToBeDeletedTask); patientTask.deletePatientTask(patientId,taskId,deadline); + ui.patientTaskDeleted(patientTask1, ToBeDeletedPatient, ToBeDeletedTask); } } }catch(Exception e) { + e.printStackTrace(); throw new DukeException("Task or patient is not found!" + e.getMessage()); + } } else { try{ diff --git a/src/main/java/duke/relation/PatientTask.java b/src/main/java/duke/relation/PatientTask.java index 91859f878b..d42dc05123 100644 --- a/src/main/java/duke/relation/PatientTask.java +++ b/src/main/java/duke/relation/PatientTask.java @@ -3,6 +3,7 @@ public abstract class PatientTask { private Integer patientId; private Integer taskID; + private Integer uuid; private boolean isDone = false; private boolean isRecurrsive = false; private String taskType; @@ -53,6 +54,8 @@ public void undoIsDone(){ this.isDone = false; } + public void setUid(int id) { this.uuid = id;} + public void updateId(int pid, int tid){ this.patientId = pid; this.taskID = tid; @@ -67,10 +70,8 @@ public String getRecurrsiveIcon(){ } public String printStatus() { - return "[" + this.getStatusIcon() + "] " + "[" + this.getRecurrsiveIcon() + "] "; + return " Unique ID " + uuid + "[" + this.getStatusIcon() + "] " + "[" + this.getRecurrsiveIcon() + "] "; } public abstract String toString(); - - } diff --git a/src/main/java/duke/relation/PatientTaskList.java b/src/main/java/duke/relation/PatientTaskList.java index 8a22e8e46a..3a4ff2d9b8 100644 --- a/src/main/java/duke/relation/PatientTaskList.java +++ b/src/main/java/duke/relation/PatientTaskList.java @@ -38,6 +38,7 @@ public void deletePatientTask(Integer pid, Integer tid, LocalDateTime s, LocalDa for (PatientTask patientTask : patientTaskIdMap.get(pid)) { if ((patientTask instanceof EventPatientTask) && patientTask.getTaskID().equals(tid) && ((EventPatientTask) patientTask).getStartTime().equals(s) && ((EventPatientTask) patientTask).getEndTime().equals(e)) { patientTaskIdMap.remove(pid, patientTask); + return; } else { throw new DukeException("The patient with id: " + pid + " has not been assigned with such task: " + tid); } @@ -47,12 +48,13 @@ public void deletePatientTask(Integer pid, Integer tid, LocalDateTime s, LocalDa } } - public void deletePatientTask(Integer pid, Integer tid, LocalDateTime end) throws DukeException { + public void deletePatientTask(int pid, int tid, LocalDateTime end) throws DukeException { if (patientTaskIdMap.containsKey(pid)) { for (PatientTask patientTask : patientTaskIdMap.get(pid)) { if ((patientTask instanceof StandardPatientTask)) { if (patientTask.getTaskID().equals(tid)&& ((StandardPatientTask) patientTask).getDeadline().equals(end)){ this.patientTaskIdMap.remove(pid, patientTask); + return; } else{ throw new DukeException("The patient with id: " + pid + " has not been assigned with such task: " + tid); From 8f9ee8ecaa388af135b9873ea6a81929f735d188 Mon Sep 17 00:00:00 2001 From: WEIFENG-NUSCEG Date: Sat, 19 Oct 2019 05:09:55 +0800 Subject: [PATCH 161/420] Standardise the input format for assign function, now we can assign task to a patient throw their name and description. Fully implemented the delete patient's task function, we can delete a patient's task throw their task's unique ID. We have to key the unique id of task when we are trying to assign a task to a patient. --- data/patients.csv | 12 +-- data/patientsTasks.csv | 3 +- .../command/DeletePatientTaskCommand.java | 90 +++++-------------- .../duke/command/FindPatientTaskCommand.java | 2 +- src/main/java/duke/core/CommandManager.java | 16 +--- src/main/java/duke/core/Parser.java | 18 ++++ src/main/java/duke/core/Ui.java | 5 +- .../java/duke/relation/PatientTaskList.java | 42 ++------- 8 files changed, 58 insertions(+), 130 deletions(-) diff --git a/data/patients.csv b/data/patients.csv index 0af226c9d6..02e0735d33 100644 --- a/data/patients.csv +++ b/data/patients.csv @@ -1,8 +1,4 @@ -Id,Name,NRIC,Room,Remark -1,xk,G00012345,38A,no -2,weifeng,G789456,8B,no -3,qianjiee,G123456,2c,no -9,weifeng,G12356,7A,male -10,kejun,G1234567890,no mood no modd,8A -11,qianjie,1231312321,A5,NIL -12,qianjie,S92139123,A04,NIL +Id,Name,NRIC,Room,Remark +1,xk,G00012345,38A,no +2,weifeng,G789456,8B,no +3,Qianjie,G123456,2c,no \ No newline at end of file diff --git a/data/patientsTasks.csv b/data/patientsTasks.csv index 1e8c1c40e5..bea1703c32 100644 --- a/data/patientsTasks.csv +++ b/data/patientsTasks.csv @@ -4,7 +4,8 @@ PID,TID,DONE,RECURRENCE,DEADLINE,STARTTIME,ENDTIME,TASKTYPE,uuid 1,3,false,false,04/04/2019 1400,,,S,2 1,3,false,false,09/08/2020 1200,,,S,5 1,3,false,false,09/05/2013 0900,,,S,9 -1,7,false,false,,09/11/2018 1400,08/08/2019 1200,E,15 +1,3,false,false,,16/09/2019 1400,12/08/2020 1200,E,126 2,7,false,false,,09/01/2019 1200,08/11/2019 1000,E,3 2,7,false,false,09/05/2013 0150,,,S,11 2,7,false,false,,09/11/2018 1400,08/08/2019 1200,E,17 +3,3,false,false,10/09/2011 1200,,,S,19 diff --git a/src/main/java/duke/command/DeletePatientTaskCommand.java b/src/main/java/duke/command/DeletePatientTaskCommand.java index 43a24f6679..1e189e7ac3 100644 --- a/src/main/java/duke/command/DeletePatientTaskCommand.java +++ b/src/main/java/duke/command/DeletePatientTaskCommand.java @@ -22,97 +22,49 @@ public class DeletePatientTaskCommand extends Command { private int patientId; private int taskId; - private String deletedTaskInfo; private String deletedPatientInfo; - private LocalDateTime from; - private LocalDateTime to; - private LocalDateTime deadline; - private String command; + private String[] command; - public DeletePatientTaskCommand(String deleteInfo) throws DukeException { + public DeletePatientTaskCommand(String[] deleteInfo) throws DukeException { - this.command = deleteInfo; - String[] tempCommand0 = command.split("\\s+", 2); - char firstChar = tempCommand0[1].charAt(0); + char firstChar = deleteInfo[0].charAt(0); try{ - if (firstChar == '#' && tempCommand0[0].equals("E")) - { - String[] tempCommand1 = tempCommand0[1].split("\\s+", 2); - this.patientId = Integer.parseInt(tempCommand1[0].substring(1)); - String[] tempCommand2 = tempCommand1[1].split(" from ", 2); - this.taskId = Integer.parseInt(tempCommand2[0]); - String[] tempCommand3 = tempCommand2[1].split(" to ", 2); - this.from = DateTimeParser.convertToLocalDateTime(tempCommand3[0]); - this.to = DateTimeParser.convertToLocalDateTime(tempCommand3[1]); - } - else if (firstChar == '#' && tempCommand0[0].equals("S")){ - String[] tempCommand1 = tempCommand0[1].split("\\s+", 2); - this.patientId = Integer.parseInt(tempCommand1[0].substring(1)); - String[] tempCommand2 = tempCommand1[1].split(" deadline ", 2); - this.taskId = Integer.parseInt(tempCommand2[0]); - this.deadline = DateTimeParser.convertToLocalDateTime(tempCommand2[1]); - } - else { - if (tempCommand0[0].equals("E")) { - String[] tempCommand1 = tempCommand0[1].split("\\s+", 2); - this.deletedPatientInfo = tempCommand1[0]; - String[] tempCommand2 = tempCommand1[1].split(" from ", 2); - this.deletedTaskInfo = tempCommand2[0]; - String[] tempCommand3 = tempCommand2[1].split(" to ", 2); - this.from = DateTimeParser.convertToLocalDateTime(tempCommand3[0]); - this.to = DateTimeParser.convertToLocalDateTime(tempCommand3[1]); - } else if (tempCommand0[0].equals("S")) { - String[] tempCommand1 = tempCommand0[1].split("\\s+", 2); - this.deletedPatientInfo = tempCommand1[0]; - String[] tempCommand2 = tempCommand1[1].split(" deadline ", 2); - this.deletedTaskInfo = tempCommand2[0]; - this.deadline = DateTimeParser.convertToLocalDateTime(tempCommand2[1]); - } + if (firstChar == '#'){ + this.patientId = Integer.parseInt(deleteInfo[0].replace("#","").trim()); + this.taskId = Integer.parseInt(deleteInfo[1]); + } else { + this.deletedPatientInfo = deleteInfo[0]; + this.taskId = Integer.parseInt(deleteInfo[1]); } }catch(Exception e) { - throw new DukeException("Try to follow the format: delete patienttask E/S #/PatientName /TaskName from to / deadline "); - + throw new DukeException("Try to follow the format: delete patienttask #patientid taskuniqeid"); } } @Override - public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientManager, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { ; + public void execute(PatientTaskList patientTaskList, TaskManager tasks, PatientManager patientManager, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { ; if (patientId != 0) { try{ - ArrayList ToBeDeleted = patientTask.getPatientTask(patientId); Patient ToBeDeletedPatient = patientManager.getPatient(patientId); - Task ToBeDeletedTask = tasks.getTask(taskId); - for (PatientTask patientTask1: ToBeDeleted){ - if (patientTask1 instanceof EventPatientTask && patientTask1.getTaskID().equals(taskId) && ((EventPatientTask) patientTask1).getStartTime().equals(this.from) && ((EventPatientTask) patientTask1).getEndTime().equals(this.to)) { - patientTask.deletePatientTask(patientId,taskId,from,to); - ui.patientTaskDeleted(patientTask1, ToBeDeletedPatient, ToBeDeletedTask); - } - else if (patientTask1 instanceof StandardPatientTask && patientTask1.getTaskID().equals(taskId) && ((StandardPatientTask) patientTask1).getDeadline().equals(this.deadline)){ - patientTask.deletePatientTask(patientId,taskId,deadline); - ui.patientTaskDeleted(patientTask1, ToBeDeletedPatient, ToBeDeletedTask); + for (PatientTask patientTask: patientTaskList.getPatientTask(patientId)){ + if (patientTask.getUid() == taskId){ + patientTaskList.deletePatientTaskByUniqueId(taskId); + ui.patientTaskDeleted(patientTask, ToBeDeletedPatient); } } - }catch(Exception e) { - e.printStackTrace(); + }catch(DukeException e) { throw new DukeException("Task or patient is not found!" + e.getMessage()); - } } else { try{ String patientName = this.deletedPatientInfo; - String taskName = this.deletedTaskInfo; ArrayList patientsWithSameName = patientManager.getPatientByName(patientName); - ArrayList ToBeDeleted = patientTask.getPatientTask(patientsWithSameName.get(0).getID()); - ArrayList ToBeDeletedTask = tasks.getTaskByDescription(deletedTaskInfo); - for (PatientTask patientTask1: ToBeDeleted){ - if (patientTask1 instanceof EventPatientTask && patientTask1.getTaskID().equals(ToBeDeletedTask.get(0).getID()) && ((EventPatientTask) patientTask1).getStartTime().equals(this.from) && ((EventPatientTask) patientTask1).getEndTime().equals(this.to)) { - ui.patientTaskDeleted(patientTask1, patientsWithSameName.get(0), ToBeDeletedTask.get(0)); - patientTask.deletePatientTask(patientsWithSameName.get(0).getID(),ToBeDeletedTask.get(0).getID(),from,to); - } - else if (patientTask1 instanceof StandardPatientTask && patientTask1.getTaskID().equals(taskId) && ((StandardPatientTask) patientTask1).getDeadline().equals(this.deadline)){ - ui.patientTaskDeleted(patientTask1, patientsWithSameName.get(0), ToBeDeletedTask.get(0)); - patientTask.deletePatientTask(patientsWithSameName.get(0).getID(),ToBeDeletedTask.get(0).getID(),deadline); + ArrayList ToBeDeleted = patientTaskList.getPatientTask(patientsWithSameName.get(0).getID()); + for (PatientTask patientTask: ToBeDeleted){ + if (patientTask.getUid() == taskId) { + patientTaskList.deletePatientTaskByUniqueId(taskId); + ui.patientTaskDeleted(patientTask, patientsWithSameName.get(0)); } } }catch(Exception e) { diff --git a/src/main/java/duke/command/FindPatientTaskCommand.java b/src/main/java/duke/command/FindPatientTaskCommand.java index a16cf154ff..f30e1a82cd 100644 --- a/src/main/java/duke/command/FindPatientTaskCommand.java +++ b/src/main/java/duke/command/FindPatientTaskCommand.java @@ -57,7 +57,7 @@ public void execute(PatientTaskList patientTaskList, TaskManager tasksManager, P } ui.patientTaskFound(patient, patientTask, tempTask); } catch (Exception e) { - throw new DukeException("Please follow the format 'find patienttask #' or 'find patient '."); + throw new DukeException(e.getMessage()); } } else { String name = command.toLowerCase(); diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index f3140024f0..ee5a0dc5cf 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -1,18 +1,6 @@ package duke.core; -import duke.command.AddPatientCommand; -import duke.command.AddStandardTaskCommand; -import duke.command.AssignTaskToPatientCommand; -import duke.command.Command; -import duke.command.DeletePatientCommand; -import duke.command.DeleteTaskCommand; -import duke.command.ExitCommand; -import duke.command.FindPatientCommand; -import duke.command.FindPatientTaskCommand; -import duke.command.ListPatientsCommand; -import duke.command.ListTasksCommand; -import duke.command.UpdatePatientCommand; -import duke.command.UpdateTaskCommand; +import duke.command.*; /** * Represents a Parser that parses user input into a specific @@ -66,6 +54,8 @@ public static Command manageCommand(String userInput) throws DukeException { return new DeletePatientCommand(formattedInput); } else if (secondKeyword.equals("task")) { return new DeleteTaskCommand(parser.parseDeleteTask()); + } else if (secondKeyword.equals("patienttask")) { + return new DeletePatientTaskCommand(parser.parseDeletePatientTask()); } else { throw new Exception("Invalid format. "); } diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index ca5717aed1..eb2e3e6861 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -37,6 +37,24 @@ public String[] parseAdd() throws DukeException { throw new DukeException("Failed to parse 'add' command."); } + /** + * . + * + * @return . + * @throws DukeException . + */ + public String[] parseDeletePatientTask() throws DukeException { + String[] formattedInput = new String[2]; + try { + String[] parsedCommand = userInput.split("\\s+", 4); + formattedInput[0] = parsedCommand[2]; + formattedInput[1] = parsedCommand[3]; + return formattedInput; + } catch (Exception e) { + throw new DukeException("Please use the correct format for the 'delete patienttask' command. "); + } + } + /** * . * diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index 8019baf879..cce190377a 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -274,11 +274,10 @@ public void taskDeleted() { * It lists out all info of patients. * * @param patient the patients to be listed out - * @param task the patients to be listed out * @param patientTask the patients to be listed out */ - public void patientTaskDeleted(PatientTask patientTask, Patient patient, Task task) { - System.out.println("Got it. The task: " + task.getID() + ". " + task.getDescription() +"\n" ); + public void patientTaskDeleted(PatientTask patientTask, Patient patient) { + System.out.println("Got it. The task with "); System.out.println(patientTask.toString()); System.out.println("has been deleted from patient: " + patient.getID() + " " + patient.getName()); } diff --git a/src/main/java/duke/relation/PatientTaskList.java b/src/main/java/duke/relation/PatientTaskList.java index 09b9b7e154..4247796f3c 100644 --- a/src/main/java/duke/relation/PatientTaskList.java +++ b/src/main/java/duke/relation/PatientTaskList.java @@ -51,47 +51,19 @@ public void addPatientTask(PatientTask t) { /** * . * - * @param pid . - * @param tid . + * @param uid . * @throws DukeException . */ - public void deletePatientTask(Integer pid, Integer tid, LocalDateTime s, LocalDateTime e) throws DukeException { - if (patientTaskIdMap.containsKey(pid)) { - for (PatientTask patientTask : patientTaskIdMap.get(pid)) { - if ((patientTask instanceof EventPatientTask) && patientTask.getTaskID().equals(tid) && - ((EventPatientTask) patientTask).getStartTime().equals(s) && - ((EventPatientTask) patientTask).getEndTime().equals(e)) { - patientTaskIdMap.remove(pid, patientTask); - return; - } else { - throw new DukeException("The patient with id: " + pid + " has not been assigned with such task: " + tid); - } + public void deletePatientTaskByUniqueId (int uid) throws DukeException { + for (PatientTask patientTask : patientTaskIdMap.values()) { + if (patientTask.getUid() == uid) { + patientTaskIdMap.remove(patientTask.getPatientId(), patientTask); + return; } - } else { - throw new DukeException("Patient id: " + pid + " does not have any tasks!"); } + throw new DukeException("Such Task does not exist!"); } - public void deletePatientTask(int pid, int tid, LocalDateTime end) throws DukeException { - if (patientTaskIdMap.containsKey(pid)) { - for (PatientTask patientTask : patientTaskIdMap.get(pid)) { - if ((patientTask instanceof StandardPatientTask)) { - if (patientTask.getTaskID().equals(tid)&& ((StandardPatientTask) patientTask).getDeadline().equals(end)){ - this.patientTaskIdMap.remove(pid, patientTask); - return; - } - else{ - throw new DukeException("The patient with id: " + pid + " has not been assigned with such task: " + tid); - } - } else { - throw new DukeException( - "The patient with id: " + pid + " has not been assigned with such task: " + tid); - } - } - } else { - throw new DukeException("Patient id: " + pid + " does not have any tasks!"); - } - } /** * . From ccbe978dff4d08a7f41735a0fe223d856f29cfbe Mon Sep 17 00:00:00 2001 From: Qian Jie Date: Sat, 19 Oct 2019 10:33:55 +0800 Subject: [PATCH 162/420] command frequency logic implemented --- data/cmdfrequency.csv | 1 + data/patients.csv | 4 + data/standardTasks.csv | 20 ++ src/main/java/duke/Duke.java | 8 +- .../java/duke/command/AddPatientCommand.java | 8 + .../duke/command/AddStandardTaskCommand.java | 7 + .../command/AssignTaskToPatientCommand.java | 202 ++++++++-------- src/main/java/duke/command/Command.java | 2 +- .../duke/command/DeletePatientCommand.java | 180 +++++++-------- .../java/duke/command/DeleteTaskCommand.java | 166 +++++++------- src/main/java/duke/command/ExitCommand.java | 8 + .../java/duke/command/FindPatientCommand.java | 128 +++++------ .../duke/command/FindPatientTaskCommand.java | 184 +++++++-------- src/main/java/duke/command/HelpCommand.java | 86 +++---- .../duke/command/ListPatientsCommand.java | 90 ++++---- .../java/duke/command/ListTasksCommand.java | 82 +++---- .../duke/command/UpdatePatientCommand.java | 164 ++++++------- .../java/duke/command/UpdateTaskCommand.java | 140 ++++++------ src/main/java/duke/core/CommandManager.java | 215 +++++++++++------- .../java/duke/storage/CmdFreqStorage.java | 93 ++++++++ 20 files changed, 998 insertions(+), 790 deletions(-) create mode 100644 data/cmdfrequency.csv create mode 100644 src/main/java/duke/storage/CmdFreqStorage.java diff --git a/data/cmdfrequency.csv b/data/cmdfrequency.csv new file mode 100644 index 0000000000..54fc9bdb89 --- /dev/null +++ b/data/cmdfrequency.csv @@ -0,0 +1 @@ +"Command Name Frequency" \ No newline at end of file diff --git a/data/patients.csv b/data/patients.csv index 0af226c9d6..c04b3d3362 100644 --- a/data/patients.csv +++ b/data/patients.csv @@ -1,4 +1,5 @@ Id,Name,NRIC,Room,Remark +16,qianjie,s13123,a09,asd 1,xk,G00012345,38A,no 2,weifeng,G789456,8B,no 3,qianjiee,G123456,2c,no @@ -6,3 +7,6 @@ Id,Name,NRIC,Room,Remark 10,kejun,G1234567890,no mood no modd,8A 11,qianjie,1231312321,A5,NIL 12,qianjie,S92139123,A04,NIL +13,qianjie,s31231231,a09,NIL +14,qianjie,s123123,a99,nil +15,qianjie,s1231231,a90,nil diff --git a/data/standardTasks.csv b/data/standardTasks.csv index e930fa24fd..45aa30d8bf 100644 --- a/data/standardTasks.csv +++ b/data/standardTasks.csv @@ -2,3 +2,23 @@ Id,Description 1,Take Medicine A 2,Do surgery 3,Take shit +4,eat shit +5,asdjasd +6,fkkk +7,123 +8,123 +9,321 +10,111 +11,123 +12,0931 +13,1231231 +14,3333 +15,12351 +16,123123 +17,3321 +18,333 +19,5555 +20,1 +21,2 +22,1 +23,2 diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index 77f5bb69a0..1134e9d853 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -4,6 +4,7 @@ import duke.core.DukeException; import duke.core.CommandManager; import duke.patient.PatientManager; +import duke.storage.CmdFreqStorage; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; import duke.storage.TaskStorage; @@ -23,6 +24,7 @@ public class Duke { private TaskStorage taskStorage; private PatientStorage patientStorage; private PatientTaskStorage patientTaskStorage; + private CmdFreqStorage cmdFreqStorage; /** * A TaskList object that deals with add, delete, mark as done, * find functions of a list of tasks. @@ -30,6 +32,7 @@ public class Duke { private PatientTaskList patientTaskList; private TaskManager taskManager; private PatientManager patientManager; + private CommandManager commandManager; /** * A Ui object that deals with interactions with the user. @@ -47,11 +50,14 @@ public Duke(String filePath) { taskStorage = new TaskStorage(filePath + "/standardTasks.csv"); patientStorage = new PatientStorage(filePath + "/patients.csv"); patientTaskStorage = new PatientTaskStorage(filePath + "/patientsTasks.csv"); + cmdFreqStorage = new CmdFreqStorage(filePath + "/cmdfrequency.csv"); try { patientTaskList = new PatientTaskList(patientTaskStorage.load()); taskManager = new TaskManager(taskStorage.load()); patientManager = new PatientManager(patientStorage.load()); + commandManager = new CommandManager(cmdFreqStorage.load()); + } catch (DukeException e) { ui.showLoadingError(); System.out.println(e.getMessage()); @@ -70,7 +76,7 @@ public void run() { try { String fullCommand = ui.readCommand(); ui.showLine(); - Command c = CommandManager.manageCommand(fullCommand); + Command c = commandManager.manageCommand(fullCommand); c.execute(patientTaskList, taskManager, patientManager, ui, patientTaskStorage, taskStorage, patientStorage); isExit = c.isExit(); diff --git a/src/main/java/duke/command/AddPatientCommand.java b/src/main/java/duke/command/AddPatientCommand.java index bddb569c1a..ce931b4fce 100644 --- a/src/main/java/duke/command/AddPatientCommand.java +++ b/src/main/java/duke/command/AddPatientCommand.java @@ -13,6 +13,7 @@ public class AddPatientCommand extends Command { private Patient newPatient; + private boolean hasBeenAddedBefore = false; /** * . @@ -24,6 +25,7 @@ public AddPatientCommand(String[] patientInfo) throws DukeException { super(); try { this.newPatient = new Patient(patientInfo[0], patientInfo[1], patientInfo[2], patientInfo[3]); + } catch (Exception e) { throw new DukeException("Please follow the format 'add patient '. "); } @@ -33,6 +35,7 @@ public AddPatientCommand(String[] patientInfo) throws DukeException { public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + this.hasBeenAddedBefore = true; patientList.addPatient(newPatient); patientStorage.save(patientList.getPatientList()); ui.patientAdded(newPatient); @@ -42,4 +45,9 @@ public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManag public boolean isExit() { return false; } + + public boolean HasBeenAddedBefore() { + return hasBeenAddedBefore; + } + } diff --git a/src/main/java/duke/command/AddStandardTaskCommand.java b/src/main/java/duke/command/AddStandardTaskCommand.java index 23742bbda3..148de7ab0c 100644 --- a/src/main/java/duke/command/AddStandardTaskCommand.java +++ b/src/main/java/duke/command/AddStandardTaskCommand.java @@ -12,6 +12,7 @@ public class AddStandardTaskCommand extends Command { private Task newStandardTask; + private boolean hasBeenAddedBefore = false; /** * . @@ -20,6 +21,7 @@ public class AddStandardTaskCommand extends Command { public AddStandardTaskCommand(String taskDescription) { super(); this.newStandardTask = new Task(taskDescription); + } /** @@ -37,6 +39,7 @@ public AddStandardTaskCommand(String taskDescription) { public void execute(PatientTaskList patientTask, TaskManager taskList, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + this.hasBeenAddedBefore = true; taskList.addTask(newStandardTask); taskStorage.save(taskList.getTaskList()); ui.taskAdded(newStandardTask); @@ -46,4 +49,8 @@ public void execute(PatientTaskList patientTask, TaskManager taskList, PatientMa public boolean isExit() { return false; } + + public boolean HasBeenAddedBefore() { + return hasBeenAddedBefore; + } } diff --git a/src/main/java/duke/command/AssignTaskToPatientCommand.java b/src/main/java/duke/command/AssignTaskToPatientCommand.java index c0f81239fe..ab9725883b 100644 --- a/src/main/java/duke/command/AssignTaskToPatientCommand.java +++ b/src/main/java/duke/command/AssignTaskToPatientCommand.java @@ -1,101 +1,101 @@ -package duke.command; - -import duke.core.DukeException; -import duke.core.Ui; -import duke.patient.PatientManager; -import duke.relation.EventPatientTask; -import duke.relation.StandardPatientTask; -import duke.storage.PatientStorage; -import duke.storage.PatientTaskStorage; -import duke.storage.TaskStorage; -import duke.relation.PatientTask; -import duke.relation.PatientTaskList; -import duke.task.TaskManager; - -public class AssignTaskToPatientCommand extends Command { - - private String command; - private String[] taskAssignmentInfo; - private PatientTask newPatientTask; - - /** - * . - * @param taskAssignmentInfo . - * @throws DukeException . - */ - public AssignTaskToPatientCommand(String[] taskAssignmentInfo) throws DukeException { - super(); - this.taskAssignmentInfo = taskAssignmentInfo; - this.newPatientTask = finalPatientTask(taskAssignmentInfo); - } - - /** - * . - * @param patientTaskList . - * @param tasksList . - * @param patientList . - * @param ui . - * @param patientTaskStorage . - * @param taskStorage . - * @param patientStorage . - * @throws DukeException . - */ - @Override - public void execute(PatientTaskList patientTaskList, TaskManager tasksList, PatientManager patientList, - Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, - PatientStorage patientStorage) throws DukeException { - if (patientList.isExist(newPatientTask.getPatientId()) && tasksList.doesExist(newPatientTask.getTaskID())) { - patientTaskList.addPatientTask(newPatientTask); - patientTaskStorage.save(patientTaskList.fullPatientTaskList()); - ui.patientTaskAssigned(newPatientTask, patientList.getPatient(newPatientTask.getPatientId()).getName(), - tasksList.getTask(newPatientTask.getTaskID()).getDescription()); - } else { - throw new DukeException("Either the patient or the task does not exist in our data record"); - } - - } - - /** - * . - * @param assignmentInfo . - * @return . - * @throws DukeException . - */ - public PatientTask finalPatientTask(String[] assignmentInfo) throws DukeException { - try { - if (assignmentInfo[0].equals("S")) { - - String type = assignmentInfo[0]; - int patientId = Integer.parseInt(assignmentInfo[1]); - int taskId = Integer.parseInt(assignmentInfo[2]); - String deadline = assignmentInfo[3]; - - StandardPatientTask standardPatientTask = new StandardPatientTask(patientId, taskId, deadline, type); - return standardPatientTask; - } else if (assignmentInfo[0].equals("E")) { - - String type = assignmentInfo[0]; - int patientId = Integer.parseInt(assignmentInfo[1]); - int taskId = Integer.parseInt(assignmentInfo[2]); - String startTime = assignmentInfo[3]; - String endTime = assignmentInfo[4]; - - EventPatientTask eventPatientTask = new EventPatientTask(patientId, taskId, startTime, endTime, type); - return eventPatientTask; - } else { - throw new DukeException("Parsing failed! Please ensure the format you have entered is correct!"); - } - } catch (Exception e) { - throw new DukeException("Unable to parse your task assignment. Please check your command's format!"); - } - } - - /** - * . - * @return . - */ - @Override - public boolean isExit() { - return false; - } -} \ No newline at end of file +//package duke.command; +// +//import duke.core.DukeException; +//import duke.core.Ui; +//import duke.patient.PatientManager; +//import duke.relation.EventPatientTask; +//import duke.relation.StandardPatientTask; +//import duke.storage.PatientStorage; +//import duke.storage.PatientTaskStorage; +//import duke.storage.TaskStorage; +//import duke.relation.PatientTask; +//import duke.relation.PatientTaskList; +//import duke.task.TaskManager; +// +//public class AssignTaskToPatientCommand extends Command { +// +// private String command; +// private String[] taskAssignmentInfo; +// private PatientTask newPatientTask; +// +// /** +// * . +// * @param taskAssignmentInfo . +// * @throws DukeException . +// */ +// public AssignTaskToPatientCommand(String[] taskAssignmentInfo) throws DukeException { +// super(); +// this.taskAssignmentInfo = taskAssignmentInfo; +// this.newPatientTask = finalPatientTask(taskAssignmentInfo); +// } +// +// /** +// * . +// * @param patientTaskList . +// * @param tasksList . +// * @param patientList . +// * @param ui . +// * @param patientTaskStorage . +// * @param taskStorage . +// * @param patientStorage . +// * @throws DukeException . +// */ +// @Override +// public void execute(PatientTaskList patientTaskList, TaskManager tasksList, PatientManager patientList, +// Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, +// PatientStorage patientStorage) throws DukeException { +// if (patientList.isExist(newPatientTask.getPatientId()) && tasksList.doesExist(newPatientTask.getTaskID())) { +// patientTaskList.addPatientTask(newPatientTask); +// patientTaskStorage.save(patientTaskList.fullPatientTaskList()); +// ui.patientTaskAssigned(newPatientTask, patientList.getPatient(newPatientTask.getPatientId()).getName(), +// tasksList.getTask(newPatientTask.getTaskID()).getDescription()); +// } else { +// throw new DukeException("Either the patient or the task does not exist in our data record"); +// } +// +// } +// +// /** +// * . +// * @param assignmentInfo . +// * @return . +// * @throws DukeException . +// */ +// public PatientTask finalPatientTask(String[] assignmentInfo) throws DukeException { +// try { +// if (assignmentInfo[0].equals("S")) { +// +// String type = assignmentInfo[0]; +// int patientId = Integer.parseInt(assignmentInfo[1]); +// int taskId = Integer.parseInt(assignmentInfo[2]); +// String deadline = assignmentInfo[3]; +// +// StandardPatientTask standardPatientTask = new StandardPatientTask(patientId, taskId, deadline, type); +// return standardPatientTask; +// } else if (assignmentInfo[0].equals("E")) { +// +// String type = assignmentInfo[0]; +// int patientId = Integer.parseInt(assignmentInfo[1]); +// int taskId = Integer.parseInt(assignmentInfo[2]); +// String startTime = assignmentInfo[3]; +// String endTime = assignmentInfo[4]; +// +// EventPatientTask eventPatientTask = new EventPatientTask(patientId, taskId, startTime, endTime, type); +// return eventPatientTask; +// } else { +// throw new DukeException("Parsing failed! Please ensure the format you have entered is correct!"); +// } +// } catch (Exception e) { +// throw new DukeException("Unable to parse your task assignment. Please check your command's format!"); +// } +// } +// +// /** +// * . +// * @return . +// */ +// @Override +// public boolean isExit() { +// return false; +// } +//} \ No newline at end of file diff --git a/src/main/java/duke/command/Command.java b/src/main/java/duke/command/Command.java index 301e2f22d7..4db5a974c6 100644 --- a/src/main/java/duke/command/Command.java +++ b/src/main/java/duke/command/Command.java @@ -1,5 +1,6 @@ package duke.command; +import duke.core.CommandManager; import duke.core.DukeException; import duke.core.Ui; import duke.patient.PatientManager; @@ -15,7 +16,6 @@ * of user command */ public abstract class Command { - /** * . * diff --git a/src/main/java/duke/command/DeletePatientCommand.java b/src/main/java/duke/command/DeletePatientCommand.java index 27498c621c..7c3e6044b1 100644 --- a/src/main/java/duke/command/DeletePatientCommand.java +++ b/src/main/java/duke/command/DeletePatientCommand.java @@ -1,90 +1,90 @@ -package duke.command; - -import duke.core.DukeException; -import duke.core.Ui; -import duke.patient.Patient; -import duke.patient.PatientManager; -import duke.storage.PatientStorage; -import duke.storage.PatientTaskStorage; -import duke.storage.TaskStorage; -import duke.relation.PatientTaskList; -import duke.task.TaskManager; - - -import java.util.ArrayList; - -public class DeletePatientCommand extends Command { - private int id; - private String deletedPatientInfo; - - /** - * . - * - * @param deletedPatientInfo . - * @throws DukeException . - */ - public DeletePatientCommand(String deletedPatientInfo) throws DukeException { - - this.deletedPatientInfo = deletedPatientInfo; - char firstChar = deletedPatientInfo.charAt(0); - if (firstChar == '#') { - try { - this.id = Integer.parseInt(deletedPatientInfo.substring(1)); - } catch (Exception e) { - throw new DukeException("Please follow format 'delete patient #'. "); - } - } - } - - /** - * . - * - * @param patientTask . - * @param tasks . - * @param patientManager . - * @param ui . - * @param patientTaskStorage . - * @param taskStorage . - * @param patientStorage . - * @throws DukeException . - */ - @Override - public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientManager, - Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, - PatientStorage patientStorage) throws DukeException { - ; - if (id != 0) { - Patient patientToBeDeleted = patientManager.getPatient(id); - boolean toDelete = ui.confirmPatientToBeDeleted(patientToBeDeleted); - if (toDelete) { - patientManager.deletePatient(id); - ui.patientDeleted(); - patientStorage.save(patientManager.getPatientList()); - } - } else { - ArrayList patientsWithSameName = patientManager.getPatientByName(deletedPatientInfo); - ui.patientsFoundByName(patientsWithSameName, deletedPatientInfo); - if (patientsWithSameName.size() >= 1) { - int numberChosen = ui.choosePatientToDelete(patientsWithSameName.size()); - if (numberChosen >= 1) { - boolean toDelete = ui.confirmPatientToBeDeleted(patientsWithSameName.get(numberChosen - 1)); - if (toDelete) { - patientManager.deletePatient(patientsWithSameName.get(numberChosen - 1).getID()); - ui.patientDeleted(); - patientStorage.save(patientManager.getPatientList()); - } - } - } - } - } - - /** - * . - * - * @return . - */ - @Override - public boolean isExit() { - return false; - } -} +//package duke.command; +// +//import duke.core.DukeException; +//import duke.core.Ui; +//import duke.patient.Patient; +//import duke.patient.PatientManager; +//import duke.storage.PatientStorage; +//import duke.storage.PatientTaskStorage; +//import duke.storage.TaskStorage; +//import duke.relation.PatientTaskList; +//import duke.task.TaskManager; +// +// +//import java.util.ArrayList; +// +//public class DeletePatientCommand extends Command { +// private int id; +// private String deletedPatientInfo; +// +// /** +// * . +// * +// * @param deletedPatientInfo . +// * @throws DukeException . +// */ +// public DeletePatientCommand(String deletedPatientInfo) throws DukeException { +// +// this.deletedPatientInfo = deletedPatientInfo; +// char firstChar = deletedPatientInfo.charAt(0); +// if (firstChar == '#') { +// try { +// this.id = Integer.parseInt(deletedPatientInfo.substring(1)); +// } catch (Exception e) { +// throw new DukeException("Please follow format 'delete patient #'. "); +// } +// } +// } +// +// /** +// * . +// * +// * @param patientTask . +// * @param tasks . +// * @param patientManager . +// * @param ui . +// * @param patientTaskStorage . +// * @param taskStorage . +// * @param patientStorage . +// * @throws DukeException . +// */ +// @Override +// public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientManager, +// Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, +// PatientStorage patientStorage) throws DukeException { +// ; +// if (id != 0) { +// Patient patientToBeDeleted = patientManager.getPatient(id); +// boolean toDelete = ui.confirmPatientToBeDeleted(patientToBeDeleted); +// if (toDelete) { +// patientManager.deletePatient(id); +// ui.patientDeleted(); +// patientStorage.save(patientManager.getPatientList()); +// } +// } else { +// ArrayList patientsWithSameName = patientManager.getPatientByName(deletedPatientInfo); +// ui.patientsFoundByName(patientsWithSameName, deletedPatientInfo); +// if (patientsWithSameName.size() >= 1) { +// int numberChosen = ui.choosePatientToDelete(patientsWithSameName.size()); +// if (numberChosen >= 1) { +// boolean toDelete = ui.confirmPatientToBeDeleted(patientsWithSameName.get(numberChosen - 1)); +// if (toDelete) { +// patientManager.deletePatient(patientsWithSameName.get(numberChosen - 1).getID()); +// ui.patientDeleted(); +// patientStorage.save(patientManager.getPatientList()); +// } +// } +// } +// } +// } +// +// /** +// * . +// * +// * @return . +// */ +// @Override +// public boolean isExit() { +// return false; +// } +//} diff --git a/src/main/java/duke/command/DeleteTaskCommand.java b/src/main/java/duke/command/DeleteTaskCommand.java index 4f4739b42b..99eb0c9c7a 100644 --- a/src/main/java/duke/command/DeleteTaskCommand.java +++ b/src/main/java/duke/command/DeleteTaskCommand.java @@ -1,83 +1,83 @@ -package duke.command; - -import duke.core.DukeException; -import duke.core.Ui; -import duke.patient.PatientManager; -import duke.storage.PatientStorage; -import duke.storage.PatientTaskStorage; -import duke.storage.TaskStorage; -import duke.relation.PatientTaskList; -import duke.task.Task; -import duke.task.TaskManager; - -import java.util.ArrayList; - -public class DeleteTaskCommand extends Command { - private int id; - private String deletedTaskInfo; - - /** - * . - * - * @param deletedTaskInfo . - * @throws DukeException . - */ - public DeleteTaskCommand(String deletedTaskInfo) throws DukeException { - - this.deletedTaskInfo = deletedTaskInfo; - char firstChar = deletedTaskInfo.charAt(0); - if (firstChar == '#') { - try { - this.id = Integer.parseInt(deletedTaskInfo.substring(1)); - } catch (Exception e) { - throw new DukeException("Please follow format 'delete task #'. "); - } - } - } - - /** - * . - * - * @param patientTask . - * @param taskManager . - * @param patientManager . - * @param ui . - * @param patientTaskStorage . - * @param taskStorage . - * @param patientStorage . - * @throws DukeException . - */ - @Override - public void execute(PatientTaskList patientTask, TaskManager taskManager, PatientManager patientManager, - Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, - PatientStorage patientStorage) throws DukeException { - if (id != 0) { - Task taskToBeDeleted = taskManager.getTask(id); - boolean toDelete = ui.confirmTaskToBeDeleted(taskToBeDeleted); - if (toDelete) { - taskManager.deleteTask(id); - ui.taskDeleted(); - taskStorage.save(taskManager.getTaskList()); - } - } else { - ArrayList tasksWithSameDescription = taskManager.getTaskByDescription(deletedTaskInfo); - ui.tasksFoundByDescription(tasksWithSameDescription, deletedTaskInfo); - if (tasksWithSameDescription.size() >= 1) { - int numberChosen = ui.chooseTaskToDelete(tasksWithSameDescription.size()); - if (numberChosen >= 1) { - boolean toDelete = ui.confirmTaskToBeDeleted(tasksWithSameDescription.get(numberChosen - 1)); - if (toDelete) { - taskManager.deleteTask(tasksWithSameDescription.get(numberChosen - 1).getID()); - ui.taskDeleted(); - taskStorage.save(taskManager.getTaskList()); - } - } - } - } - } - - @Override - public boolean isExit() { - return false; - } -} +//package duke.command; +// +//import duke.core.DukeException; +//import duke.core.Ui; +//import duke.patient.PatientManager; +//import duke.storage.PatientStorage; +//import duke.storage.PatientTaskStorage; +//import duke.storage.TaskStorage; +//import duke.relation.PatientTaskList; +//import duke.task.Task; +//import duke.task.TaskManager; +// +//import java.util.ArrayList; +// +//public class DeleteTaskCommand extends Command { +// private int id; +// private String deletedTaskInfo; +// +// /** +// * . +// * +// * @param deletedTaskInfo . +// * @throws DukeException . +// */ +// public DeleteTaskCommand(String deletedTaskInfo) throws DukeException { +// +// this.deletedTaskInfo = deletedTaskInfo; +// char firstChar = deletedTaskInfo.charAt(0); +// if (firstChar == '#') { +// try { +// this.id = Integer.parseInt(deletedTaskInfo.substring(1)); +// } catch (Exception e) { +// throw new DukeException("Please follow format 'delete task #'. "); +// } +// } +// } +// +// /** +// * . +// * +// * @param patientTask . +// * @param taskManager . +// * @param patientManager . +// * @param ui . +// * @param patientTaskStorage . +// * @param taskStorage . +// * @param patientStorage . +// * @throws DukeException . +// */ +// @Override +// public void execute(PatientTaskList patientTask, TaskManager taskManager, PatientManager patientManager, +// Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, +// PatientStorage patientStorage) throws DukeException { +// if (id != 0) { +// Task taskToBeDeleted = taskManager.getTask(id); +// boolean toDelete = ui.confirmTaskToBeDeleted(taskToBeDeleted); +// if (toDelete) { +// taskManager.deleteTask(id); +// ui.taskDeleted(); +// taskStorage.save(taskManager.getTaskList()); +// } +// } else { +// ArrayList tasksWithSameDescription = taskManager.getTaskByDescription(deletedTaskInfo); +// ui.tasksFoundByDescription(tasksWithSameDescription, deletedTaskInfo); +// if (tasksWithSameDescription.size() >= 1) { +// int numberChosen = ui.chooseTaskToDelete(tasksWithSameDescription.size()); +// if (numberChosen >= 1) { +// boolean toDelete = ui.confirmTaskToBeDeleted(tasksWithSameDescription.get(numberChosen - 1)); +// if (toDelete) { +// taskManager.deleteTask(tasksWithSameDescription.get(numberChosen - 1).getID()); +// ui.taskDeleted(); +// taskStorage.save(taskManager.getTaskList()); +// } +// } +// } +// } +// } +// +// @Override +// public boolean isExit() { +// return false; +// } +//} diff --git a/src/main/java/duke/command/ExitCommand.java b/src/main/java/duke/command/ExitCommand.java index 4962348377..f9ae69cd59 100644 --- a/src/main/java/duke/command/ExitCommand.java +++ b/src/main/java/duke/command/ExitCommand.java @@ -1,5 +1,6 @@ package duke.command; +import duke.core.CommandManager; import duke.patient.PatientManager; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; @@ -14,11 +15,13 @@ * program */ public class ExitCommand extends Command { + private boolean hasBeenAddedBefore = false; /** * Constructs a ExitCommand object. */ public ExitCommand() { super(); + } /** @@ -41,6 +44,11 @@ public boolean isExit() { public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) { + this.hasBeenAddedBefore = true; ui.exitInformation(); } + + public boolean HasBeenAddedBefore() { + return hasBeenAddedBefore; + } } \ No newline at end of file diff --git a/src/main/java/duke/command/FindPatientCommand.java b/src/main/java/duke/command/FindPatientCommand.java index 4877121ce7..b78928a9c5 100644 --- a/src/main/java/duke/command/FindPatientCommand.java +++ b/src/main/java/duke/command/FindPatientCommand.java @@ -1,64 +1,64 @@ -package duke.command; - -import duke.core.DukeException; -import duke.core.Ui; -import duke.patient.Patient; -import duke.patient.PatientManager; -import duke.storage.PatientStorage; -import duke.storage.PatientTaskStorage; -import duke.storage.TaskStorage; -import duke.relation.PatientTaskList; -import duke.task.TaskManager; - -import java.util.ArrayList; - -public class FindPatientCommand extends Command { - - private String command; - - public FindPatientCommand(String command) { - this.command = command; - } - - /** - * . - * - * @param patientTask . - * @param tasks . - * @param patientManager . - * @param ui . - * @param patientTaskStorage . - * @param taskStorage . - * @param patientStorage . - * @throws DukeException . - */ - @Override - public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientManager, - Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, - PatientStorage patientStorage) throws DukeException { - char firstChar = command.charAt(0); - if (firstChar == '#') { - int id; - try { - id = Integer.parseInt(command.substring(1, command.length())); - } catch (Exception e) { - throw new DukeException("Please follow the format 'find patient #' or 'find patient '."); - } - Patient patient = patientManager.getPatient(id); - ui.patientsFoundById(patient); - } else { - ArrayList patientsWithSameName = patientManager.getPatientByName(command); - ui.patientsFoundByName(patientsWithSameName, command); - } - } - - /** - * . - * - * @return . - */ - @Override - public boolean isExit() { - return false; - } -} +//package duke.command; +// +//import duke.core.DukeException; +//import duke.core.Ui; +//import duke.patient.Patient; +//import duke.patient.PatientManager; +//import duke.storage.PatientStorage; +//import duke.storage.PatientTaskStorage; +//import duke.storage.TaskStorage; +//import duke.relation.PatientTaskList; +//import duke.task.TaskManager; +// +//import java.util.ArrayList; +// +//public class FindPatientCommand extends Command { +// +// private String command; +// +// public FindPatientCommand(String command) { +// this.command = command; +// } +// +// /** +// * . +// * +// * @param patientTask . +// * @param tasks . +// * @param patientManager . +// * @param ui . +// * @param patientTaskStorage . +// * @param taskStorage . +// * @param patientStorage . +// * @throws DukeException . +// */ +// @Override +// public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientManager, +// Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, +// PatientStorage patientStorage) throws DukeException { +// char firstChar = command.charAt(0); +// if (firstChar == '#') { +// int id; +// try { +// id = Integer.parseInt(command.substring(1, command.length())); +// } catch (Exception e) { +// throw new DukeException("Please follow the format 'find patient #' or 'find patient '."); +// } +// Patient patient = patientManager.getPatient(id); +// ui.patientsFoundById(patient); +// } else { +// ArrayList patientsWithSameName = patientManager.getPatientByName(command); +// ui.patientsFoundByName(patientsWithSameName, command); +// } +// } +// +// /** +// * . +// * +// * @return . +// */ +// @Override +// public boolean isExit() { +// return false; +// } +//} diff --git a/src/main/java/duke/command/FindPatientTaskCommand.java b/src/main/java/duke/command/FindPatientTaskCommand.java index a16cf154ff..e2b233d0d0 100644 --- a/src/main/java/duke/command/FindPatientTaskCommand.java +++ b/src/main/java/duke/command/FindPatientTaskCommand.java @@ -1,92 +1,92 @@ -package duke.command; - -import duke.core.DukeException; -import duke.core.Ui; -import duke.patient.Patient; -import duke.patient.PatientManager; -import duke.relation.PatientTask; -import duke.relation.PatientTaskList; -import duke.storage.PatientStorage; -import duke.storage.PatientTaskStorage; -import duke.storage.TaskStorage; -import duke.task.Task; -import duke.task.TaskManager; - -import java.util.ArrayList; - -public class FindPatientTaskCommand extends Command { - - private String command; - - /** - * . - * - * @param cmd . - */ - public FindPatientTaskCommand(String cmd) { - super(); - this.command = cmd; - } - - /** - * . - * - * @param patientTaskList . - * @param tasksManager . - * @param patientManager . - * @param ui . - * @param patientTaskStorage . - * @param taskStorage . - * @param patientStorage . - * @throws DukeException . - */ - @Override - public void execute(PatientTaskList patientTaskList, TaskManager tasksManager, PatientManager patientManager, - Ui ui, PatientTaskStorage patientTaskStorage, - TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { - char firstChar = command.charAt(0); - if (firstChar == '#') { - int id; - try { - id = Integer.parseInt(command.substring(1, command.length())); - Patient patient = patientManager.getPatient(id); - ArrayList patientTask = patientTaskList.getPatientTask(id); - ArrayList tempTask = new ArrayList<>(); - for (PatientTask temppatientTask : patientTask) { - tempTask.add(tasksManager.getTask(temppatientTask.getTaskID())); - } - ui.patientTaskFound(patient, patientTask, tempTask); - } catch (Exception e) { - throw new DukeException("Please follow the format 'find patienttask #' or 'find patient '."); - } - } else { - String name = command.toLowerCase(); - ArrayList patientsWithSameName = patientManager.getPatientByName(name); - ArrayList patientWithTask = new ArrayList<>(); - ArrayList tempTask = new ArrayList<>(); - - try { - for (Patient patient : patientsWithSameName) { - if (patient.getName().toLowerCase().equals(name)) { - patientWithTask = patientTaskList.getPatientTask(patient.getID()); - } - } - for (PatientTask temppatientTask : patientWithTask) { - tempTask.add(tasksManager.getTask(temppatientTask.getTaskID())); - //System.out.println(temppatientTask.getTaskID() + "\n"); - } - - ui.patientTaskFound(patientsWithSameName.get(0), patientWithTask, tempTask); - } catch (Exception e) { - throw new DukeException(e.getMessage() - + "Please follow the format 'find patienttask #' or 'find patient '."); - } - } - } - - - @Override - public boolean isExit() { - return false; - } -} \ No newline at end of file +//package duke.command; +// +//import duke.core.DukeException; +//import duke.core.Ui; +//import duke.patient.Patient; +//import duke.patient.PatientManager; +//import duke.relation.PatientTask; +//import duke.relation.PatientTaskList; +//import duke.storage.PatientStorage; +//import duke.storage.PatientTaskStorage; +//import duke.storage.TaskStorage; +//import duke.task.Task; +//import duke.task.TaskManager; +// +//import java.util.ArrayList; +// +//public class FindPatientTaskCommand extends Command { +// +// private String command; +// +// /** +// * . +// * +// * @param cmd . +// */ +// public FindPatientTaskCommand(String cmd) { +// super(); +// this.command = cmd; +// } +// +// /** +// * . +// * +// * @param patientTaskList . +// * @param tasksManager . +// * @param patientManager . +// * @param ui . +// * @param patientTaskStorage . +// * @param taskStorage . +// * @param patientStorage . +// * @throws DukeException . +// */ +// @Override +// public void execute(PatientTaskList patientTaskList, TaskManager tasksManager, PatientManager patientManager, +// Ui ui, PatientTaskStorage patientTaskStorage, +// TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { +// char firstChar = command.charAt(0); +// if (firstChar == '#') { +// int id; +// try { +// id = Integer.parseInt(command.substring(1, command.length())); +// Patient patient = patientManager.getPatient(id); +// ArrayList patientTask = patientTaskList.getPatientTask(id); +// ArrayList tempTask = new ArrayList<>(); +// for (PatientTask temppatientTask : patientTask) { +// tempTask.add(tasksManager.getTask(temppatientTask.getTaskID())); +// } +// ui.patientTaskFound(patient, patientTask, tempTask); +// } catch (Exception e) { +// throw new DukeException("Please follow the format 'find patienttask #' or 'find patient '."); +// } +// } else { +// String name = command.toLowerCase(); +// ArrayList patientsWithSameName = patientManager.getPatientByName(name); +// ArrayList patientWithTask = new ArrayList<>(); +// ArrayList tempTask = new ArrayList<>(); +// +// try { +// for (Patient patient : patientsWithSameName) { +// if (patient.getName().toLowerCase().equals(name)) { +// patientWithTask = patientTaskList.getPatientTask(patient.getID()); +// } +// } +// for (PatientTask temppatientTask : patientWithTask) { +// tempTask.add(tasksManager.getTask(temppatientTask.getTaskID())); +// //System.out.println(temppatientTask.getTaskID() + "\n"); +// } +// +// ui.patientTaskFound(patientsWithSameName.get(0), patientWithTask, tempTask); +// } catch (Exception e) { +// throw new DukeException(e.getMessage() +// + "Please follow the format 'find patienttask #' or 'find patient '."); +// } +// } +// } +// +// +// @Override +// public boolean isExit() { +// return false; +// } +//} \ No newline at end of file diff --git a/src/main/java/duke/command/HelpCommand.java b/src/main/java/duke/command/HelpCommand.java index 0af521525f..fff248bcbb 100644 --- a/src/main/java/duke/command/HelpCommand.java +++ b/src/main/java/duke/command/HelpCommand.java @@ -1,43 +1,43 @@ -package duke.command; - -import duke.core.DukeException; -import duke.patient.PatientManager; -import duke.storage.PatientStorage; -import duke.storage.PatientTaskStorage; -import duke.storage.TaskStorage; -import duke.relation.PatientTaskList; -import duke.core.Ui; -import duke.task.TaskManager; - -public class HelpCommand extends Command { - - /** - * . - * - * @param patientTask . - * @param tasks . - * @param patientList . - * @param ui . - * @param patientTaskStorage . - * @param taskStorage . - * @param patientStorage . - * @throws DukeException . - */ - @Override - public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, - Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, - PatientStorage patientStorage) throws DukeException { - //ui.showHelpCommand(); - - } - - /** - * . - * - * @return . - */ - @Override - public boolean isExit() { - return false; - } -} +//package duke.command; +// +//import duke.core.DukeException; +//import duke.patient.PatientManager; +//import duke.storage.PatientStorage; +//import duke.storage.PatientTaskStorage; +//import duke.storage.TaskStorage; +//import duke.relation.PatientTaskList; +//import duke.core.Ui; +//import duke.task.TaskManager; +// +//public class HelpCommand extends Command { +// +// /** +// * . +// * +// * @param patientTask . +// * @param tasks . +// * @param patientList . +// * @param ui . +// * @param patientTaskStorage . +// * @param taskStorage . +// * @param patientStorage . +// * @throws DukeException . +// */ +// @Override +// public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, +// Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, +// PatientStorage patientStorage) throws DukeException { +// //ui.showHelpCommand(); +// +// } +// +// /** +// * . +// * +// * @return . +// */ +// @Override +// public boolean isExit() { +// return false; +// } +//} diff --git a/src/main/java/duke/command/ListPatientsCommand.java b/src/main/java/duke/command/ListPatientsCommand.java index 2582c52e70..c785abd5f0 100644 --- a/src/main/java/duke/command/ListPatientsCommand.java +++ b/src/main/java/duke/command/ListPatientsCommand.java @@ -1,45 +1,45 @@ -package duke.command; - -import duke.core.DukeException; -import duke.core.Ui; -import duke.patient.Patient; -import duke.patient.PatientManager; -import duke.storage.PatientStorage; -import duke.storage.PatientTaskStorage; -import duke.storage.TaskStorage; -import duke.relation.PatientTaskList; -import duke.task.TaskManager; - -import java.util.ArrayList; - -public class ListPatientsCommand extends Command { - - public ListPatientsCommand() { - super(); - } - - /** - * . - * - * @param patientTask . - * @param tasks . - * @param patientList . - * @param ui . - * @param patientTaskStorage . - * @param taskStorage . - * @param patientStorage . - * @throws DukeException . - */ - @Override - public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, - Ui ui, PatientTaskStorage patientTaskStorage, - TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { - ArrayList list = patientList.getPatientList(); - ui.listAllPatients(list); - } - - @Override - public boolean isExit() { - return false; - } -} +//package duke.command; +// +//import duke.core.DukeException; +//import duke.core.Ui; +//import duke.patient.Patient; +//import duke.patient.PatientManager; +//import duke.storage.PatientStorage; +//import duke.storage.PatientTaskStorage; +//import duke.storage.TaskStorage; +//import duke.relation.PatientTaskList; +//import duke.task.TaskManager; +// +//import java.util.ArrayList; +// +//public class ListPatientsCommand extends Command { +// +// public ListPatientsCommand() { +// super(); +// } +// +// /** +// * . +// * +// * @param patientTask . +// * @param tasks . +// * @param patientList . +// * @param ui . +// * @param patientTaskStorage . +// * @param taskStorage . +// * @param patientStorage . +// * @throws DukeException . +// */ +// @Override +// public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, +// Ui ui, PatientTaskStorage patientTaskStorage, +// TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { +// ArrayList list = patientList.getPatientList(); +// ui.listAllPatients(list); +// } +// +// @Override +// public boolean isExit() { +// return false; +// } +//} diff --git a/src/main/java/duke/command/ListTasksCommand.java b/src/main/java/duke/command/ListTasksCommand.java index 05c310e984..abce9346b3 100644 --- a/src/main/java/duke/command/ListTasksCommand.java +++ b/src/main/java/duke/command/ListTasksCommand.java @@ -1,41 +1,41 @@ -package duke.command; - -import duke.core.DukeException; -import duke.core.Ui; -import duke.patient.PatientManager; -import duke.storage.PatientStorage; -import duke.storage.PatientTaskStorage; -import duke.storage.TaskStorage; -import duke.relation.PatientTaskList; -import duke.task.Task; -import duke.task.TaskManager; - -import java.util.ArrayList; - -public class ListTasksCommand extends Command { - - /** - * . - * - * @param patientTask . - * @param tasks . - * @param patientList . - * @param ui . - * @param patientTaskStorage . - * @param taskStorage . - * @param patientStorage . - * @throws DukeException . - */ - @Override - public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, - Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, - PatientStorage patientStorage) throws DukeException { - ArrayList list = tasks.getTaskList(); - ui.listAllTasks(list); - } - - @Override - public boolean isExit() { - return false; - } -} +//package duke.command; +// +//import duke.core.DukeException; +//import duke.core.Ui; +//import duke.patient.PatientManager; +//import duke.storage.PatientStorage; +//import duke.storage.PatientTaskStorage; +//import duke.storage.TaskStorage; +//import duke.relation.PatientTaskList; +//import duke.task.Task; +//import duke.task.TaskManager; +// +//import java.util.ArrayList; +// +//public class ListTasksCommand extends Command { +// +// /** +// * . +// * +// * @param patientTask . +// * @param tasks . +// * @param patientList . +// * @param ui . +// * @param patientTaskStorage . +// * @param taskStorage . +// * @param patientStorage . +// * @throws DukeException . +// */ +// @Override +// public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, +// Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, +// PatientStorage patientStorage) throws DukeException { +// ArrayList list = tasks.getTaskList(); +// ui.listAllTasks(list); +// } +// +// @Override +// public boolean isExit() { +// return false; +// } +//} diff --git a/src/main/java/duke/command/UpdatePatientCommand.java b/src/main/java/duke/command/UpdatePatientCommand.java index 1f0f38f2bf..d254bc5175 100644 --- a/src/main/java/duke/command/UpdatePatientCommand.java +++ b/src/main/java/duke/command/UpdatePatientCommand.java @@ -1,82 +1,82 @@ -package duke.command; - -import duke.core.DukeException; -import duke.core.Ui; -import duke.patient.Patient; -import duke.patient.PatientManager; -import duke.storage.PatientStorage; -import duke.storage.PatientTaskStorage; -import duke.storage.TaskStorage; -import duke.relation.PatientTaskList; -import duke.task.TaskManager; - -public class UpdatePatientCommand extends Command { - - private String command; - - /** - * . - * - * @param command . - */ - public UpdatePatientCommand(String command) { - this.command = command; - } - - /** - * . - * - * @param patientTask . - * @param tasks . - * @param patientManager . - * @param ui . - * @param patientTaskStorage . - * @param taskStorage . - * @param patientStorage . - * @throws DukeException . - */ - @Override - public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientManager, - Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, - PatientStorage patientStorage) throws DukeException { - String[] tempCommand = command.split(" ", 3); - char firstChar = tempCommand[0].charAt(0); - if (firstChar == '#') { - int id; - try { - id = Integer.parseInt(tempCommand[0].substring(1, tempCommand[0].length())); - Patient patientToBeUpdated = patientManager.getPatient(id); - if (tempCommand[1].toLowerCase().equals("name")) { - patientToBeUpdated.setName(tempCommand[2]); - } else if (tempCommand[1].toLowerCase().equals("nric")) { - patientToBeUpdated.setNric(tempCommand[2]); - } else if (tempCommand[1].toLowerCase().equals("room")) { - patientToBeUpdated.setRoom(tempCommand[2]); - } else { - throw new DukeException("You can only update 'Name', 'NRIC', or 'Room' of the patient"); - } - - patientStorage.save(patientManager.getPatientList()); - - ui.showUpdatedSuccessfully(); - ui.showPatientInfo(patientToBeUpdated); - } catch (Exception e) { - throw new DukeException( - "Please follow the format 'update patient # '."); - } - } else { - throw new DukeException( - "Please follow the format 'update patient # '."); - } - } - - /** - * . - * - * @return . - */ - @Override - public boolean isExit() { - return false; - } -} +//package duke.command; +// +//import duke.core.DukeException; +//import duke.core.Ui; +//import duke.patient.Patient; +//import duke.patient.PatientManager; +//import duke.storage.PatientStorage; +//import duke.storage.PatientTaskStorage; +//import duke.storage.TaskStorage; +//import duke.relation.PatientTaskList; +//import duke.task.TaskManager; +// +//public class UpdatePatientCommand extends Command { +// +// private String command; +// +// /** +// * . +// * +// * @param command . +// */ +// public UpdatePatientCommand(String command) { +// this.command = command; +// } +// +// /** +// * . +// * +// * @param patientTask . +// * @param tasks . +// * @param patientManager . +// * @param ui . +// * @param patientTaskStorage . +// * @param taskStorage . +// * @param patientStorage . +// * @throws DukeException . +// */ +// @Override +// public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientManager, +// Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, +// PatientStorage patientStorage) throws DukeException { +// String[] tempCommand = command.split(" ", 3); +// char firstChar = tempCommand[0].charAt(0); +// if (firstChar == '#') { +// int id; +// try { +// id = Integer.parseInt(tempCommand[0].substring(1, tempCommand[0].length())); +// Patient patientToBeUpdated = patientManager.getPatient(id); +// if (tempCommand[1].toLowerCase().equals("name")) { +// patientToBeUpdated.setName(tempCommand[2]); +// } else if (tempCommand[1].toLowerCase().equals("nric")) { +// patientToBeUpdated.setNric(tempCommand[2]); +// } else if (tempCommand[1].toLowerCase().equals("room")) { +// patientToBeUpdated.setRoom(tempCommand[2]); +// } else { +// throw new DukeException("You can only update 'Name', 'NRIC', or 'Room' of the patient"); +// } +// +// patientStorage.save(patientManager.getPatientList()); +// +// ui.showUpdatedSuccessfully(); +// ui.showPatientInfo(patientToBeUpdated); +// } catch (Exception e) { +// throw new DukeException( +// "Please follow the format 'update patient # '."); +// } +// } else { +// throw new DukeException( +// "Please follow the format 'update patient # '."); +// } +// } +// +// /** +// * . +// * +// * @return . +// */ +// @Override +// public boolean isExit() { +// return false; +// } +//} diff --git a/src/main/java/duke/command/UpdateTaskCommand.java b/src/main/java/duke/command/UpdateTaskCommand.java index 871ddd0aed..192c8da4b9 100644 --- a/src/main/java/duke/command/UpdateTaskCommand.java +++ b/src/main/java/duke/command/UpdateTaskCommand.java @@ -1,70 +1,70 @@ -package duke.command; - -import duke.core.DukeException; -import duke.core.Ui; -import duke.task.Task; -import duke.patient.PatientManager; -import duke.storage.PatientStorage; -import duke.storage.PatientTaskStorage; -import duke.storage.TaskStorage; -import duke.relation.PatientTaskList; -import duke.task.TaskManager; - -public class UpdateTaskCommand extends Command { - private String command; - - /** - * . - * - * @param command . - */ - public UpdateTaskCommand(String command) { - this.command = command; - } - - /** - * . - * - * @param patientTask . - * @param taskManager . - * @param patientManager . - * @param ui . - * @param patientTaskStorage . - * @param taskStorage . - * @param patientStorage . - * @throws DukeException . - */ - @Override - public void execute(PatientTaskList patientTask, TaskManager taskManager, PatientManager patientManager, - Ui ui, PatientTaskStorage patientTaskStorage, - TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { - String[] tempCommand = command.split(" ", 3); - char firstChar = tempCommand[0].charAt(0); - if (firstChar == '#') { - int id; - try { - id = Integer.parseInt(tempCommand[0].substring(1, tempCommand[0].length())); - Task taskToBeUpdated = taskManager.getTask(id); - if (tempCommand[1].toLowerCase().equals("description")) { - taskToBeUpdated.setDescription(tempCommand[2]); - } else { - throw new DukeException("You can only update 'Description' of the task"); - } - - taskStorage.save(taskManager.getTaskList()); - - ui.showUpdatedSuccessfully(); - ui.showTaskInfo(taskToBeUpdated); - } catch (Exception e) { - throw new DukeException( - "Please follow the format 'update patient # '."); - } - - } - } - - @Override - public boolean isExit() { - return false; - } -} +//package duke.command; +// +//import duke.core.DukeException; +//import duke.core.Ui; +//import duke.task.Task; +//import duke.patient.PatientManager; +//import duke.storage.PatientStorage; +//import duke.storage.PatientTaskStorage; +//import duke.storage.TaskStorage; +//import duke.relation.PatientTaskList; +//import duke.task.TaskManager; +// +//public class UpdateTaskCommand extends Command { +// private String command; +// +// /** +// * . +// * +// * @param command . +// */ +// public UpdateTaskCommand(String command) { +// this.command = command; +// } +// +// /** +// * . +// * +// * @param patientTask . +// * @param taskManager . +// * @param patientManager . +// * @param ui . +// * @param patientTaskStorage . +// * @param taskStorage . +// * @param patientStorage . +// * @throws DukeException . +// */ +// @Override +// public void execute(PatientTaskList patientTask, TaskManager taskManager, PatientManager patientManager, +// Ui ui, PatientTaskStorage patientTaskStorage, +// TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { +// String[] tempCommand = command.split(" ", 3); +// char firstChar = tempCommand[0].charAt(0); +// if (firstChar == '#') { +// int id; +// try { +// id = Integer.parseInt(tempCommand[0].substring(1, tempCommand[0].length())); +// Task taskToBeUpdated = taskManager.getTask(id); +// if (tempCommand[1].toLowerCase().equals("description")) { +// taskToBeUpdated.setDescription(tempCommand[2]); +// } else { +// throw new DukeException("You can only update 'Description' of the task"); +// } +// +// taskStorage.save(taskManager.getTaskList()); +// +// ui.showUpdatedSuccessfully(); +// ui.showTaskInfo(taskToBeUpdated); +// } catch (Exception e) { +// throw new DukeException( +// "Please follow the format 'update patient # '."); +// } +// +// } +// } +// +// @Override +// public boolean isExit() { +// return false; +// } +//} diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index f3140024f0..32a5142ded 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -2,17 +2,22 @@ import duke.command.AddPatientCommand; import duke.command.AddStandardTaskCommand; -import duke.command.AssignTaskToPatientCommand; import duke.command.Command; -import duke.command.DeletePatientCommand; -import duke.command.DeleteTaskCommand; import duke.command.ExitCommand; -import duke.command.FindPatientCommand; -import duke.command.FindPatientTaskCommand; -import duke.command.ListPatientsCommand; -import duke.command.ListTasksCommand; -import duke.command.UpdatePatientCommand; -import duke.command.UpdateTaskCommand; +import duke.storage.CmdFreqStorage; +//import duke.command.AssignTaskToPatientCommand; +//import duke.command.DeletePatientCommand; +//import duke.command.DeleteTaskCommand; +//import duke.command.FindPatientCommand; +//import duke.command.FindPatientTaskCommand; +//import duke.command.ListPatientsCommand; +//import duke.command.ListTasksCommand; +//import duke.command.UpdatePatientCommand; +//import duke.command.UpdateTaskCommand; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; /** * Represents a Parser that parses user input into a specific @@ -20,98 +25,154 @@ */ public class CommandManager { + private Map cmdFreqTable = new HashMap<>(); + int count; + //CmdFreqStorage cmdFreqStorage = CmdFreqStorage.getCmdFreqStorage(); + + + public CommandManager (Map cmdFreqTable){ + this.cmdFreqTable = cmdFreqTable; + } + /** * Parses a Task from a string array. * * @param userInput The string array to be parsed. * @return The Command received from user. */ - public static Command manageCommand(String userInput) throws DukeException { + public Command manageCommand(String userInput) throws DukeException { userInput = userInput.trim(); String[] command = userInput.split("\\s+", 3); String firstKeyword = command[0].toLowerCase(); Parser parser = new Parser(userInput); + CmdFreqStorage cmdFreqStorage = new CmdFreqStorage(); switch (firstKeyword) { //change this depending on how string is parsed case "add": String secondKeyword = command[1].toLowerCase(); if (secondKeyword.equals("patient")) { String[] formattedInput = parser.parseAdd(); - return new AddPatientCommand(formattedInput); + AddPatientCommand addPatientCommand = new AddPatientCommand(formattedInput); + String commandName = addPatientCommand.getClass().getSimpleName(); + if (!addPatientCommand.HasBeenAddedBefore()) { + cmdFreqTable.put(commandName , 1); + } + count = cmdFreqTable.containsKey(commandName) ? cmdFreqTable.get(commandName) : 0; + cmdFreqTable.put(commandName , count + 1); + //cmdFreqStorage.save(cmdFreqTable); + + return addPatientCommand; } else if (secondKeyword.equals("task")) { String formattedInput = parser.parseAdd()[0]; - return new AddStandardTaskCommand(formattedInput); + AddStandardTaskCommand addStandardTaskCommand = new AddStandardTaskCommand(formattedInput); + String commandName = addStandardTaskCommand.getClass().getSimpleName(); + if (!addStandardTaskCommand.HasBeenAddedBefore()) { + cmdFreqTable.put(addStandardTaskCommand.getClass().getSimpleName() , 1); + } + count = cmdFreqTable.containsKey(commandName) ? cmdFreqTable.get(commandName) : 0; + cmdFreqTable.put(commandName , count + 1); + //cmdFreqStorage.save(cmdFreqTable); + + + return addStandardTaskCommand ; } else { throw new DukeException("Add command fails. "); } - case "assign": - return new AssignTaskToPatientCommand(parser.parseAssign()); - case "list": - try { - String[] tempCommand = command[1].split("\\s+"); - if (tempCommand[0].toLowerCase().equals("patients")) { - return new ListPatientsCommand(); - } else if (tempCommand[0].toLowerCase().equals("tasks")) { - return new ListTasksCommand(); - } else { - throw new Exception("Invalid 'list' command. "); - } - } catch (Exception e) { - throw new DukeException("List command fails. " + e.getMessage()); - } - case "delete": - try { - secondKeyword = command[1].toLowerCase(); - if (secondKeyword.equals("patient")) { - String formattedInput = parser.parseDeletePatient(); - return new DeletePatientCommand(formattedInput); - } else if (secondKeyword.equals("task")) { - return new DeleteTaskCommand(parser.parseDeleteTask()); - } else { - throw new Exception("Invalid format. "); - } - } catch (Exception e) { - throw new DukeException("Delete command fails. " + e.getMessage()); - } - case "find": - try { - secondKeyword = command[1].toLowerCase(); - if (secondKeyword.equals("patient")) { - try { - return new FindPatientCommand(command[2]); - } catch (Exception e) { - throw new Exception("Please follow the format 'find patient #' or 'find patient '."); - } - } else if (secondKeyword.equals("patienttask")) { - try { - return new FindPatientTaskCommand(command[2]); - } catch (Exception e) { - throw new Exception("Please follow the format 'find patient #' or 'find patient '."); - } - } else { - throw new Exception("Invalid format. "); - } - } catch (Exception e) { - throw new DukeException("Find command fails. " + e.getMessage()); +// case "assign": +// return new AssignTaskToPatientCommand(parser.parseAssign()); +// case "list": +// try { +// String[] tempCommand = command[1].split("\\s+"); +// if (tempCommand[0].toLowerCase().equals("patients")) { +// return new ListPatientsCommand(); +// } else if (tempCommand[0].toLowerCase().equals("tasks")) { +// return new ListTasksCommand(); +// } else { +// throw new Exception("Invalid 'list' command. "); +// } +// } catch (Exception e) { +// throw new DukeException("List command fails. " + e.getMessage()); +// } +// case "delete": +// try { +// secondKeyword = command[1].toLowerCase(); +// if (secondKeyword.equals("patient")) { +// String formattedInput = parser.parseDeletePatient(); +// return new DeletePatientCommand(formattedInput); +// } else if (secondKeyword.equals("task")) { +// return new DeleteTaskCommand(parser.parseDeleteTask()); +// } else { +// throw new Exception("Invalid format. "); +// } +// } catch (Exception e) { +// throw new DukeException("Delete command fails. " + e.getMessage()); +// } +// case "find": +// try { +// secondKeyword = command[1].toLowerCase(); +// if (secondKeyword.equals("patient")) { +// try { +// return new FindPatientCommand(command[2]); +// } catch (Exception e) { +// throw new Exception("Please follow the format 'find patient #' or 'find patient '."); +// } +// } else if (secondKeyword.equals("patienttask")) { +// try { +// return new FindPatientTaskCommand(command[2]); +// } catch (Exception e) { +// throw new Exception("Please follow the format 'find patient #' or 'find patient '."); +// } +// } else { +// throw new Exception("Invalid format. "); +// } +// } catch (Exception e) { +// throw new DukeException("Find command fails. " + e.getMessage()); +// } +// case "update": +// try { +// secondKeyword = command[1].toLowerCase(); +// if (secondKeyword.equals("patient")) { +// String formattedInput = parser.parseUpdatePatient(); +// return new UpdatePatientCommand(formattedInput); +// } else if (secondKeyword.equals("task")) { +// String formattedInput = parser.parseUpdateTask(); +// return new UpdateTaskCommand(formattedInput); +// } else { +// throw new Exception("Invalid format. "); +// } +// } catch (Exception e) { +// throw new DukeException("update command fails. " + e.getMessage()); +// } + case "bye": + ExitCommand exitCommand = new ExitCommand(); + String commandName = exitCommand.getClass().getSimpleName(); + if (!exitCommand.HasBeenAddedBefore()) { + cmdFreqTable.put(exitCommand.getClass().getSimpleName() , 0); } - case "update": - try { - secondKeyword = command[1].toLowerCase(); - if (secondKeyword.equals("patient")) { - String formattedInput = parser.parseUpdatePatient(); - return new UpdatePatientCommand(formattedInput); - } else if (secondKeyword.equals("task")) { - String formattedInput = parser.parseUpdateTask(); - return new UpdateTaskCommand(formattedInput); - } else { - throw new Exception("Invalid format. "); - } - } catch (Exception e) { - throw new DukeException("update command fails. " + e.getMessage()); + + count = cmdFreqTable.containsKey(commandName) ? cmdFreqTable.get(commandName) : 0; + cmdFreqTable.put(commandName , count + 1); + + System.out.println(cmdFreqTable.size()); + + for (Map.Entry entry : cmdFreqTable.entrySet()) { + System.out.println("Key = " + entry.getKey()); + System.out.println("Value = " + entry.getValue()); } - case "bye": - return new ExitCommand(); +// Set keys = cmdFreqTable.keySet(); +// System.out.println("All keys are: " + keys); +// for(Object key: keys){ +// System.out.println(key + ": " + cmdFreqTable.get(key)); +// } + // cmdFreqStorage.save(cmdFreqTable); + + return exitCommand; default: throw new DukeException("Could not understand user input."); } + + } + + + } diff --git a/src/main/java/duke/storage/CmdFreqStorage.java b/src/main/java/duke/storage/CmdFreqStorage.java new file mode 100644 index 0000000000..02e06aba7f --- /dev/null +++ b/src/main/java/duke/storage/CmdFreqStorage.java @@ -0,0 +1,93 @@ +package duke.storage; + +import duke.core.CommandManager; +import duke.core.DukeException; +import duke.patient.Patient; +import duke.relation.EventPatientTask; +import duke.relation.PatientTask; +import duke.relation.StandardPatientTask; +import org.apache.commons.csv.CSVFormat; +import org.apache.commons.csv.CSVPrinter; +import org.apache.commons.csv.CSVRecord; + +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +public class CmdFreqStorage { + + /** + * A string that represents a relative file path from the project folder. + */ + private String filePath; + public CmdFreqStorage(){} + /** + * Constructs a Storage object with a specific file path. + * + * @param filePath A string that represents the path of the file to read or + * write. + */ + public CmdFreqStorage(String filePath) { + this.filePath = filePath; + } + + /** + * Load the task info with associated patient from local csv files. + * + * @return A arrayList of PatientTask which contain info of task with associated patient + * @throws DukeException throw a dukeException with error message for debugging + */ + public Map load() throws DukeException { + Map cmdFreqTable = new HashMap<>(); + File csvFile = new File(filePath); + try { + if (csvFile.createNewFile()) { + System.out.println("File " + filePath + " is created."); + } else { + Reader in = new FileReader(filePath); + Iterable records = CSVFormat.EXCEL.withFirstRecordAsHeader().parse(in); + for (CSVRecord record : records) { + String commandName = record.get("Command Name"); + Integer frequency = Integer.parseInt(record.get("Frequency")); + cmdFreqTable.put(commandName , frequency); + } + } + System.out.println("Load completed"); + return cmdFreqTable; + } catch (Exception e) { + throw new DukeException("Loading of " + + filePath + + "is unsuccessful." + + "e.getMessage()"); + } + } + + + +// /** +// * Write the patients' info to local csv files. +// * +// * @param cmdFreqTable A list of patients containing info of patients to be written +// * @throws DukeException throw exception with error message when i/o fails +// */ +// public void save(Map cmdFreqTable) throws DukeException { +// try { +// BufferedWriter writer = Files.newBufferedWriter(Paths.get(filePath)); +// CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT +// .withHeader("Command Name" , "Frequency")); +// for (Map.Entry entry : cmdFreqTable.entrySet()) { +// String commandName = entry.getKey(); +// Integer frequency = entry.getValue(); +// csvPrinter.printRecords(commandName , frequency); +// } +// +// System.out.println("saved successful"); +// csvPrinter.flush(); +// } catch (IOException e) { +// throw new DukeException(e.getMessage()); +// } +// } +} From 51c19a74feeca8dbaea7c6be0604061430a50c49 Mon Sep 17 00:00:00 2001 From: Qian Jie Date: Sat, 19 Oct 2019 12:01:13 +0800 Subject: [PATCH 163/420] Manage to save command frequency into a new csv.file that stores it , as well as load it when program start --- data/cmdfrequency.csv | 4 +- data/patients.csv | 2 +- data/standardTasks.csv | 15 ++++++ src/main/java/duke/Duke.java | 2 +- .../java/duke/command/AddPatientCommand.java | 11 +++- .../duke/command/AddStandardTaskCommand.java | 11 +++- src/main/java/duke/command/Command.java | 3 +- src/main/java/duke/command/ExitCommand.java | 9 ++-- src/main/java/duke/core/CommandManager.java | 50 +++---------------- .../java/duke/storage/CmdFreqStorage.java | 48 ++++++++---------- 10 files changed, 72 insertions(+), 83 deletions(-) diff --git a/data/cmdfrequency.csv b/data/cmdfrequency.csv index 54fc9bdb89..cf3a98008a 100644 --- a/data/cmdfrequency.csv +++ b/data/cmdfrequency.csv @@ -1 +1,3 @@ -"Command Name Frequency" \ No newline at end of file +Command Name,Frequency +AddStandardTaskCommand,3 +AddPatientCommand,3 diff --git a/data/patients.csv b/data/patients.csv index c04b3d3362..f9f5754514 100644 --- a/data/patients.csv +++ b/data/patients.csv @@ -1,5 +1,5 @@ Id,Name,NRIC,Room,Remark -16,qianjie,s13123,a09,asd +16,momo,s123123,a9,nil 1,xk,G00012345,38A,no 2,weifeng,G789456,8B,no 3,qianjiee,G123456,2c,no diff --git a/data/standardTasks.csv b/data/standardTasks.csv index 45aa30d8bf..8487a540ef 100644 --- a/data/standardTasks.csv +++ b/data/standardTasks.csv @@ -22,3 +22,18 @@ Id,Description 21,2 22,1 23,2 +24,123 +25,1 +26,5 +27,2 +28,123 +29,2 +30,5 +31,6 +32,100 +33,100 +34,3 +35,5 +36,123 +37,4 +38,wqeqw diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index 1134e9d853..1149d31669 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -78,7 +78,7 @@ public void run() { ui.showLine(); Command c = commandManager.manageCommand(fullCommand); c.execute(patientTaskList, taskManager, patientManager, - ui, patientTaskStorage, taskStorage, patientStorage); + ui, patientTaskStorage, taskStorage, patientStorage , cmdFreqStorage ,commandManager); isExit = c.isExit(); } catch (DukeException e) { ui.showError(e.getMessage()); diff --git a/src/main/java/duke/command/AddPatientCommand.java b/src/main/java/duke/command/AddPatientCommand.java index ce931b4fce..c88e7b2c4f 100644 --- a/src/main/java/duke/command/AddPatientCommand.java +++ b/src/main/java/duke/command/AddPatientCommand.java @@ -1,9 +1,11 @@ package duke.command; +import duke.core.CommandManager; import duke.core.DukeException; import duke.core.Ui; import duke.patient.Patient; import duke.patient.PatientManager; +import duke.storage.CmdFreqStorage; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; import duke.storage.TaskStorage; @@ -34,10 +36,17 @@ public AddPatientCommand(String[] patientInfo) throws DukeException { @Override public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, - PatientStorage patientStorage) throws DukeException { + PatientStorage patientStorage , CmdFreqStorage cmdFreqStorage, CommandManager commandManager) throws DukeException { this.hasBeenAddedBefore = true; + String commandName = this.getClass().getSimpleName(); + if (!hasBeenAddedBefore) { + commandManager.getCmdFreqTable().put(commandName , 1); + } + int count = commandManager.getCmdFreqTable().containsKey(commandName) ? commandManager.getCmdFreqTable().get(commandName) : 0; + commandManager.getCmdFreqTable().put(commandName , count + 1); patientList.addPatient(newPatient); patientStorage.save(patientList.getPatientList()); + cmdFreqStorage.save(commandManager.getCmdFreqTable()); ui.patientAdded(newPatient); } diff --git a/src/main/java/duke/command/AddStandardTaskCommand.java b/src/main/java/duke/command/AddStandardTaskCommand.java index 148de7ab0c..17f092f836 100644 --- a/src/main/java/duke/command/AddStandardTaskCommand.java +++ b/src/main/java/duke/command/AddStandardTaskCommand.java @@ -1,8 +1,10 @@ package duke.command; +import duke.core.CommandManager; import duke.core.DukeException; import duke.core.Ui; import duke.patient.PatientManager; +import duke.storage.CmdFreqStorage; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; import duke.storage.TaskStorage; @@ -38,10 +40,17 @@ public AddStandardTaskCommand(String taskDescription) { @Override public void execute(PatientTaskList patientTask, TaskManager taskList, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, - PatientStorage patientStorage) throws DukeException { + PatientStorage patientStorage , CmdFreqStorage cmdFreqStorage , CommandManager commandManager) throws DukeException { this.hasBeenAddedBefore = true; + String commandName = this.getClass().getSimpleName(); + if (!hasBeenAddedBefore) { + commandManager.getCmdFreqTable().put(commandName , 1); + } + int count = commandManager.getCmdFreqTable().containsKey(commandName) ? commandManager.getCmdFreqTable().get(commandName) : 0; + commandManager.getCmdFreqTable().put(commandName , count + 1); taskList.addTask(newStandardTask); taskStorage.save(taskList.getTaskList()); + cmdFreqStorage.save(commandManager.getCmdFreqTable()); ui.taskAdded(newStandardTask); } diff --git a/src/main/java/duke/command/Command.java b/src/main/java/duke/command/Command.java index 4db5a974c6..6bec4bab46 100644 --- a/src/main/java/duke/command/Command.java +++ b/src/main/java/duke/command/Command.java @@ -5,6 +5,7 @@ import duke.core.Ui; import duke.patient.PatientManager; import duke.relation.PatientTaskList; +import duke.storage.CmdFreqStorage; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; import duke.storage.TaskStorage; @@ -30,7 +31,7 @@ public abstract class Command { */ public abstract void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, - PatientStorage patientStorage) throws DukeException; + PatientStorage patientStorage , CmdFreqStorage cmdFreqStorage ,CommandManager commandManager) throws DukeException; /** * Decide whether duke should exist. diff --git a/src/main/java/duke/command/ExitCommand.java b/src/main/java/duke/command/ExitCommand.java index f9ae69cd59..9c9166d64d 100644 --- a/src/main/java/duke/command/ExitCommand.java +++ b/src/main/java/duke/command/ExitCommand.java @@ -1,7 +1,9 @@ package duke.command; import duke.core.CommandManager; +import duke.core.DukeException; import duke.patient.PatientManager; +import duke.storage.CmdFreqStorage; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; import duke.relation.PatientTaskList; @@ -21,7 +23,6 @@ public class ExitCommand extends Command { */ public ExitCommand() { super(); - } /** @@ -43,12 +44,8 @@ public boolean isExit() { */ public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, - TaskStorage taskStorage, PatientStorage patientStorage) { + TaskStorage taskStorage, PatientStorage patientStorage , CmdFreqStorage cmdFreqStorage , CommandManager commandManager) throws DukeException { this.hasBeenAddedBefore = true; ui.exitInformation(); } - - public boolean HasBeenAddedBefore() { - return hasBeenAddedBefore; - } } \ No newline at end of file diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 32a5142ded..dd43b41c6a 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -25,15 +25,15 @@ */ public class CommandManager { - private Map cmdFreqTable = new HashMap<>(); - int count; - //CmdFreqStorage cmdFreqStorage = CmdFreqStorage.getCmdFreqStorage(); - - + private Map cmdFreqTable; public CommandManager (Map cmdFreqTable){ this.cmdFreqTable = cmdFreqTable; } + public Map getCmdFreqTable () { + return cmdFreqTable; + } + /** * Parses a Task from a string array. * @@ -45,34 +45,16 @@ public Command manageCommand(String userInput) throws DukeException { String[] command = userInput.split("\\s+", 3); String firstKeyword = command[0].toLowerCase(); Parser parser = new Parser(userInput); - CmdFreqStorage cmdFreqStorage = new CmdFreqStorage(); switch (firstKeyword) { //change this depending on how string is parsed case "add": String secondKeyword = command[1].toLowerCase(); if (secondKeyword.equals("patient")) { String[] formattedInput = parser.parseAdd(); AddPatientCommand addPatientCommand = new AddPatientCommand(formattedInput); - String commandName = addPatientCommand.getClass().getSimpleName(); - if (!addPatientCommand.HasBeenAddedBefore()) { - cmdFreqTable.put(commandName , 1); - } - count = cmdFreqTable.containsKey(commandName) ? cmdFreqTable.get(commandName) : 0; - cmdFreqTable.put(commandName , count + 1); - //cmdFreqStorage.save(cmdFreqTable); - return addPatientCommand; } else if (secondKeyword.equals("task")) { String formattedInput = parser.parseAdd()[0]; AddStandardTaskCommand addStandardTaskCommand = new AddStandardTaskCommand(formattedInput); - String commandName = addStandardTaskCommand.getClass().getSimpleName(); - if (!addStandardTaskCommand.HasBeenAddedBefore()) { - cmdFreqTable.put(addStandardTaskCommand.getClass().getSimpleName() , 1); - } - count = cmdFreqTable.containsKey(commandName) ? cmdFreqTable.get(commandName) : 0; - cmdFreqTable.put(commandName , count + 1); - //cmdFreqStorage.save(cmdFreqTable); - - return addStandardTaskCommand ; } else { throw new DukeException("Add command fails. "); @@ -145,34 +127,14 @@ public Command manageCommand(String userInput) throws DukeException { case "bye": ExitCommand exitCommand = new ExitCommand(); String commandName = exitCommand.getClass().getSimpleName(); - if (!exitCommand.HasBeenAddedBefore()) { - cmdFreqTable.put(exitCommand.getClass().getSimpleName() , 0); - } - - count = cmdFreqTable.containsKey(commandName) ? cmdFreqTable.get(commandName) : 0; - cmdFreqTable.put(commandName , count + 1); - - System.out.println(cmdFreqTable.size()); - for (Map.Entry entry : cmdFreqTable.entrySet()) { System.out.println("Key = " + entry.getKey()); System.out.println("Value = " + entry.getValue()); + System.out.println("===================================================="); } -// Set keys = cmdFreqTable.keySet(); -// System.out.println("All keys are: " + keys); -// for(Object key: keys){ -// System.out.println(key + ": " + cmdFreqTable.get(key)); -// } - // cmdFreqStorage.save(cmdFreqTable); - return exitCommand; default: throw new DukeException("Could not understand user input."); } - - } - - - } diff --git a/src/main/java/duke/storage/CmdFreqStorage.java b/src/main/java/duke/storage/CmdFreqStorage.java index 02e06aba7f..7591a1954f 100644 --- a/src/main/java/duke/storage/CmdFreqStorage.java +++ b/src/main/java/duke/storage/CmdFreqStorage.java @@ -18,12 +18,10 @@ import java.util.Map; public class CmdFreqStorage { - /** * A string that represents a relative file path from the project folder. */ private String filePath; - public CmdFreqStorage(){} /** * Constructs a Storage object with a specific file path. * @@ -65,29 +63,25 @@ public CmdFreqStorage(String filePath) { } } - - -// /** -// * Write the patients' info to local csv files. -// * -// * @param cmdFreqTable A list of patients containing info of patients to be written -// * @throws DukeException throw exception with error message when i/o fails -// */ -// public void save(Map cmdFreqTable) throws DukeException { -// try { -// BufferedWriter writer = Files.newBufferedWriter(Paths.get(filePath)); -// CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT -// .withHeader("Command Name" , "Frequency")); -// for (Map.Entry entry : cmdFreqTable.entrySet()) { -// String commandName = entry.getKey(); -// Integer frequency = entry.getValue(); -// csvPrinter.printRecords(commandName , frequency); -// } -// -// System.out.println("saved successful"); -// csvPrinter.flush(); -// } catch (IOException e) { -// throw new DukeException(e.getMessage()); -// } -// } + /** + * Write the patients' info to local csv files. + * + * @param cmdFreqTable A list of patients containing info of patients to be written + * @throws DukeException throw exception with error message when i/o fails + */ + public void save(Map cmdFreqTable) throws DukeException { + try { + BufferedWriter writer = Files.newBufferedWriter(Paths.get(filePath)); + CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT + .withHeader("Command Name" , "Frequency")); + for (Map.Entry entry : cmdFreqTable.entrySet()) { + String commandName = entry.getKey(); + String frequency = entry.getValue().toString(); + csvPrinter.printRecord(commandName , frequency ); + } + csvPrinter.flush(); + } catch (IOException e) { + throw new DukeException(e.getMessage()); + } + } } From 0c13f98821e10de79bd942f511fce7a43488345c Mon Sep 17 00:00:00 2001 From: Qian Jie Date: Sat, 19 Oct 2019 13:07:25 +0800 Subject: [PATCH 164/420] Implemented Command Frequency Counter with checkstyle checked. --- build/reports/checkstyle/main.html | 805 +++--------------- build/reports/checkstyle/main.xml | 317 ++----- data/cmdfrequency.csv | 10 +- data/patients.csv | 4 +- data/standardTasks.csv | 3 +- src/main/java/duke/Duke.java | 2 +- .../java/duke/command/AddPatientCommand.java | 15 +- .../duke/command/AddStandardTaskCommand.java | 28 +- .../command/AssignTaskToPatientCommand.java | 220 ++--- src/main/java/duke/command/Command.java | 3 +- .../duke/command/DeletePatientCommand.java | 194 +++-- .../java/duke/command/DeleteTaskCommand.java | 181 ++-- src/main/java/duke/command/ExitCommand.java | 7 +- .../java/duke/command/FindPatientCommand.java | 143 ++-- .../duke/command/FindPatientTaskCommand.java | 198 +++-- .../duke/command/ListPatientsCommand.java | 103 ++- .../java/duke/command/ListTasksCommand.java | 96 ++- .../duke/command/UpdatePatientCommand.java | 178 ++-- .../java/duke/command/UpdateTaskCommand.java | 154 ++-- src/main/java/duke/core/CommandManager.java | 164 ++-- .../java/duke/storage/CmdFreqStorage.java | 28 +- 21 files changed, 1125 insertions(+), 1728 deletions(-) diff --git a/build/reports/checkstyle/main.html b/build/reports/checkstyle/main.html index 9410402449..1ec4310163 100644 --- a/build/reports/checkstyle/main.html +++ b/build/reports/checkstyle/main.html @@ -72,7 +72,7 @@

Summary

FilesErrors - 26203 + 320
@@ -82,874 +82,325 @@

Files

NameErrors - C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\Parser.java94 + /Users/qianjie/Desktop/main/src/main/java/duke/Duke.java0 - C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\Task.java15 + /Users/qianjie/Desktop/main/src/main/java/duke/command/AddPatientCommand.java0 - C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\AddCommand.java13 + /Users/qianjie/Desktop/main/src/main/java/duke/command/AddStandardTaskCommand.java0 - C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\DateTimeParser.java11 + /Users/qianjie/Desktop/main/src/main/java/duke/command/AssignTaskToPatientCommand.java0 - C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\RescheduleCommand.java10 + /Users/qianjie/Desktop/main/src/main/java/duke/command/Command.java0 - C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\Ui.java7 + /Users/qianjie/Desktop/main/src/main/java/duke/command/DeletePatientCommand.java0 - C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\RecurringCommand.java6 + /Users/qianjie/Desktop/main/src/main/java/duke/command/DeleteTaskCommand.java0 - C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\Storage.java6 + /Users/qianjie/Desktop/main/src/main/java/duke/command/ExitCommand.java0 - C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\Duke.java5 + /Users/qianjie/Desktop/main/src/main/java/duke/command/FindPatientCommand.java0 - C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\FixedDurationTask.java4 + /Users/qianjie/Desktop/main/src/main/java/duke/command/FindPatientTaskCommand.java0 - C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\PeriodTask.java4 + /Users/qianjie/Desktop/main/src/main/java/duke/command/HelpCommand.java0 - C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\RemindCommand.java3 + /Users/qianjie/Desktop/main/src/main/java/duke/command/ListPatientsCommand.java0 - C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\ViewCommand.java3 + /Users/qianjie/Desktop/main/src/main/java/duke/command/ListTasksCommand.java0 - C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\Deadline.java3 + /Users/qianjie/Desktop/main/src/main/java/duke/command/UpdatePatientCommand.java0 - C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\Event.java3 + /Users/qianjie/Desktop/main/src/main/java/duke/command/UpdateTaskCommand.java0 - C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\Todo.java3 + /Users/qianjie/Desktop/main/src/main/java/duke/core/CommandManager.java0 - C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\Reminder.java2 + /Users/qianjie/Desktop/main/src/main/java/duke/core/DateTimeParser.java0 - C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\DeleteCommand.java2 + /Users/qianjie/Desktop/main/src/main/java/duke/core/DukeException.java0 - C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\DoneCommand.java2 + /Users/qianjie/Desktop/main/src/main/java/duke/core/Parser.java0 - C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\ExitCommand.java2 + /Users/qianjie/Desktop/main/src/main/java/duke/core/Ui.java0 - C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\FindCommand.java2 + /Users/qianjie/Desktop/main/src/main/java/duke/patient/Patient.java0 - C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\ListCommand.java2 + /Users/qianjie/Desktop/main/src/main/java/duke/patient/PatientManager.java0 - C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\Command.java1 + /Users/qianjie/Desktop/main/src/main/java/duke/relation/EventPatientTask.java0 - C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\FindFreeTimesCommand.java0 + /Users/qianjie/Desktop/main/src/main/java/duke/relation/PatientTask.java0 - C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\DukeException.java0 + /Users/qianjie/Desktop/main/src/main/java/duke/relation/PatientTaskList.java0 - C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\TaskList.java0 - - -
- -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\Duke.java

- - - + - + - + - + - + - + + + +
Error DescriptionLine/Users/qianjie/Desktop/main/src/main/java/duke/relation/StandardPatientTask.java0
Using the '.*' form of import should be avoided - duke.core.*.5/Users/qianjie/Desktop/main/src/main/java/duke/storage/CmdFreqStorage.java0
WhitespaceAround: '{' is not preceded with whitespace.11/Users/qianjie/Desktop/main/src/main/java/duke/storage/PatientStorage.java0
'CTOR_DEF' should be separated from previous statement.32/Users/qianjie/Desktop/main/src/main/java/duke/storage/PatientTaskStorage.java0
First sentence of Javadoc is missing an ending period.65/Users/qianjie/Desktop/main/src/main/java/duke/storage/TaskStorage.java0
'METHOD_DEF' should be separated from previous statement.71/Users/qianjie/Desktop/main/src/main/java/duke/task/Task.java0
/Users/qianjie/Desktop/main/src/main/java/duke/task/TaskManager.java0
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\Reminder.java

+
+ +

File /Users/qianjie/Desktop/main/src/main/java/duke/Duke.java

- - - - - -
Error DescriptionLine
'CTOR_DEF' should be separated from previous statement.38
'{' at column 21 should be on the previous line.54
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\AddCommand.java

+ Back to top +

File /Users/qianjie/Desktop/main/src/main/java/duke/command/AddPatientCommand.java

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Error DescriptionLine
First sentence of Javadoc is missing an ending period.24
First sentence of Javadoc is missing an ending period.40
Line continuation have incorrect indentation level, expected level should be 4.44
Line is longer than 120 characters (found 129).67
')' is preceded with whitespace.67
WhitespaceAround: '{' is not preceded with whitespace.67
',' is preceded with whitespace.75
';' is preceded with whitespace.77
')' is preceded with whitespace.81
WhitespaceAround: '}' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)94
WhitespaceAround: 'else' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)94
WhitespaceAround: 'else' is not preceded with whitespace.94
WhitespaceAround: '{' is not preceded with whitespace.94
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\Command.java

+ Back to top +

File /Users/qianjie/Desktop/main/src/main/java/duke/command/AddStandardTaskCommand.java

- - -
Error DescriptionLine
Line continuation have incorrect indentation level, expected level should be 4.30
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\DeleteCommand.java

+ Back to top +

File /Users/qianjie/Desktop/main/src/main/java/duke/command/AssignTaskToPatientCommand.java

- - - - - -
Error DescriptionLine
First sentence of Javadoc is missing an ending period.31
Line continuation have incorrect indentation level, expected level should be 4.35
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\DoneCommand.java

+ Back to top +

File /Users/qianjie/Desktop/main/src/main/java/duke/command/Command.java

- - - - - -
Error DescriptionLine
First sentence of Javadoc is missing an ending period.30
Line continuation have incorrect indentation level, expected level should be 4.34
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\ExitCommand.java

+ Back to top +

File /Users/qianjie/Desktop/main/src/main/java/duke/command/DeletePatientCommand.java

- - - - - -
Error DescriptionLine
First sentence of Javadoc is missing an ending period.20
Line continuation have incorrect indentation level, expected level should be 4.24
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\FindCommand.java

+ Back to top +

File /Users/qianjie/Desktop/main/src/main/java/duke/command/DeleteTaskCommand.java

- - - - - -
Error DescriptionLine
First sentence of Javadoc is missing an ending period.29
Line continuation have incorrect indentation level, expected level should be 4.33
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\FindFreeTimesCommand.java

+ Back to top +

File /Users/qianjie/Desktop/main/src/main/java/duke/command/ExitCommand.java

Error DescriptionLine
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\ListCommand.java

+ Back to top +

File /Users/qianjie/Desktop/main/src/main/java/duke/command/FindPatientCommand.java

- - - - - -
Error DescriptionLine
First sentence of Javadoc is missing an ending period.21
Line continuation have incorrect indentation level, expected level should be 4.25
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\RecurringCommand.java

+ Back to top +

File /Users/qianjie/Desktop/main/src/main/java/duke/command/FindPatientTaskCommand.java

- - - - - - - - - - - - - - - - - -
Error DescriptionLine
Using the '.*' form of import should be avoided - duke.task.*.7
First sentence of Javadoc is missing an ending period.23
Line continuation have incorrect indentation level, expected level should be 4.27
'{' at column 29 should have line break after.30
'}' at column 45 should be alone on a line.30
Empty line should be followed by <p> tag on the next line.34
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\RemindCommand.java

+ Back to top +

File /Users/qianjie/Desktop/main/src/main/java/duke/command/HelpCommand.java

- - - - - - - - -
Error DescriptionLine
'CTOR_DEF' should be separated from previous statement.21
First sentence of Javadoc is missing an ending period.26
Line continuation have incorrect indentation level, expected level should be 4.30
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\RescheduleCommand.java

+ Back to top +

File /Users/qianjie/Desktop/main/src/main/java/duke/command/ListPatientsCommand.java

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Error DescriptionLine
Line is longer than 120 characters (found 127).23
WhitespaceAround: 'try' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)40
WhitespaceAround: '{' is not preceded with whitespace.40
WhitespaceAround: '{' is not preceded with whitespace.42
WhitespaceAround: '}' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)48
WhitespaceAround: 'catch' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)48
WhitespaceAround: 'catch' is not preceded with whitespace.48
WhitespaceAround: '{' is not preceded with whitespace.48
First sentence of Javadoc is missing an ending period.53
Line continuation have incorrect indentation level, expected level should be 4.57
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\ViewCommand.java

+ Back to top +

File /Users/qianjie/Desktop/main/src/main/java/duke/command/ListTasksCommand.java

- - - - - - - - -
Error DescriptionLine
'(' is preceded with whitespace.16
First sentence of Javadoc is missing an ending period.23
Line continuation have incorrect indentation level, expected level should be 4.27
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\DateTimeParser.java

+ Back to top +

File /Users/qianjie/Desktop/main/src/main/java/duke/command/UpdatePatientCommand.java

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Error DescriptionLine
Javadoc comment at column 19 has parse error. Missed HTML close tag 'code'. Sometimes it means that close tag missed for one of previous tags.9
Line is longer than 120 characters (found 128).33
Line is longer than 120 characters (found 128).34
Line is longer than 120 characters (found 128).35
Line is longer than 120 characters (found 128).36
WhitespaceAround: 'try' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)38
WhitespaceAround: '{' is not preceded with whitespace.38
WhitespaceAround: '}' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)50
WhitespaceAround: 'catch' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)50
WhitespaceAround: 'catch' is not preceded with whitespace.50
WhitespaceAround: '{' is not preceded with whitespace.50
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\DukeException.java

+ Back to top +

File /Users/qianjie/Desktop/main/src/main/java/duke/command/UpdateTaskCommand.java

Error DescriptionLine
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\Parser.java

+ Back to top +

File /Users/qianjie/Desktop/main/src/main/java/duke/core/CommandManager.java

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Error DescriptionLine
Using the '.*' form of import should be avoided - duke.command.*.3
Using the '.*' form of import should be avoided - duke.task.*.4
'case' child has incorrect indentation level 12, expected level should be 8.28
'block' child has incorrect indentation level 16, expected level should be 12.29
'case' child has incorrect indentation level 12, expected level should be 8.30
'try' has incorrect indentation level 16, expected level should be 12.31
'try' child has incorrect indentation level 20, expected level should be 16.32
'try' child has incorrect indentation level 20, expected level should be 16.33
'try rcurly' has incorrect indentation level 16, expected level should be 12.34
'catch' child has incorrect indentation level 20, expected level should be 16.35
'catch rcurly' has incorrect indentation level 16, expected level should be 12.36
'case' child has incorrect indentation level 12, expected level should be 8.37
'try' has incorrect indentation level 16, expected level should be 12.38
'try' child has incorrect indentation level 20, expected level should be 16.39
'try' child has incorrect indentation level 20, expected level should be 16.40
'try rcurly' has incorrect indentation level 16, expected level should be 12.41
'catch' child has incorrect indentation level 20, expected level should be 16.42
'catch rcurly' has incorrect indentation level 16, expected level should be 12.43
'case' child has incorrect indentation level 12, expected level should be 8.44
'try' has incorrect indentation level 16, expected level should be 12.45
'try' child has incorrect indentation level 20, expected level should be 16.46
'try' child has incorrect indentation level 20, expected level should be 16.47
'try rcurly' has incorrect indentation level 16, expected level should be 12.48
'catch' child has incorrect indentation level 20, expected level should be 16.49
'catch rcurly' has incorrect indentation level 16, expected level should be 12.50
'case' child has incorrect indentation level 12, expected level should be 8.51
'try' has incorrect indentation level 16, expected level should be 12.52
'try' child has incorrect indentation level 20, expected level should be 16.53
'try' child has incorrect indentation level 20, expected level should be 16.54
'try' child has incorrect indentation level 20, expected level should be 16.55
'try rcurly' has incorrect indentation level 16, expected level should be 12.56
'}' at column 17 should be on the same line as the next part of a multi-block statement (one that directly contains multiple blocks: if/else-if/else, do/while or try/catch/finally).56
'catch' has incorrect indentation level 17, expected level should be 12.57
'catch' child has incorrect indentation level 20, expected level should be 16.58
'catch rcurly' has incorrect indentation level 17, expected level should be 12.59
'case' child has incorrect indentation level 12, expected level should be 8.60
'try' has incorrect indentation level 16, expected level should be 12.61
'try' child has incorrect indentation level 20, expected level should be 16.62
'try' child has incorrect indentation level 20, expected level should be 16.63
'try' child has incorrect indentation level 20, expected level should be 16.64
'try rcurly' has incorrect indentation level 16, expected level should be 12.65
'catch' child has incorrect indentation level 20, expected level should be 16.66
'catch rcurly' has incorrect indentation level 16, expected level should be 12.67
'case' child has incorrect indentation level 12, expected level should be 8.68
'try' has incorrect indentation level 16, expected level should be 12.69
'try' child has incorrect indentation level 20, expected level should be 16.70
'try' child has incorrect indentation level 20, expected level should be 16.71
'try' child has incorrect indentation level 20, expected level should be 16.72
'try rcurly' has incorrect indentation level 16, expected level should be 12.73
'catch' child has incorrect indentation level 20, expected level should be 16.74
'catch rcurly' has incorrect indentation level 16, expected level should be 12.75
'case' child has incorrect indentation level 12, expected level should be 8.76
'try' has incorrect indentation level 16, expected level should be 12.77
'try' child has incorrect indentation level 20, expected level should be 16.78
'try' child has incorrect indentation level 20, expected level should be 16.79
'try' child has incorrect indentation level 20, expected level should be 16.80
'try' child has incorrect indentation level 20, expected level should be 16.81
'try rcurly' has incorrect indentation level 16, expected level should be 12.82
WhitespaceAround: '}' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)82
WhitespaceAround: 'catch' is not preceded with whitespace.82
'catch' child has incorrect indentation level 20, expected level should be 16.83
Line is longer than 120 characters (found 181).83
'catch rcurly' has incorrect indentation level 16, expected level should be 12.85
'case' child has incorrect indentation level 12, expected level should be 8.86
'block' child has incorrect indentation level 16, expected level should be 12.87
'case' child has incorrect indentation level 12, expected level should be 8.88
'try' has incorrect indentation level 16, expected level should be 12.89
'try' child has incorrect indentation level 20, expected level should be 16.90
'try' child has incorrect indentation level 20, expected level should be 16.91
'try rcurly' has incorrect indentation level 16, expected level should be 12.92
'catch' child has incorrect indentation level 20, expected level should be 16.93
Line is longer than 120 characters (found 156).93
'catch rcurly' has incorrect indentation level 16, expected level should be 12.94
'case' child has incorrect indentation level 12, expected level should be 8.95
'try' has incorrect indentation level 16, expected level should be 12.96
'try' child has incorrect indentation level 20, expected level should be 16.97
'try' child has incorrect indentation level 20, expected level should be 16.98
'try' child has incorrect indentation level 20, expected level should be 16.99
'try' child has incorrect indentation level 20, expected level should be 16.100
'try rcurly' has incorrect indentation level 16, expected level should be 12.102
'catch' child has incorrect indentation level 20, expected level should be 16.103
'catch rcurly' has incorrect indentation level 16, expected level should be 12.104
'case' child has incorrect indentation level 12, expected level should be 8.105
Fall through from previous branch of the switch statement.105
'try' has incorrect indentation level 16, expected level should be 12.106
'try' child has incorrect indentation level 20, expected level should be 16.107
'try' child has incorrect indentation level 20, expected level should be 16.108
'try rcurly' has incorrect indentation level 16, expected level should be 12.109
'catch' child has incorrect indentation level 20, expected level should be 16.110
'catch rcurly' has incorrect indentation level 16, expected level should be 12.111
'case' child has incorrect indentation level 12, expected level should be 8.112
'block' child has incorrect indentation level 16, expected level should be 12.113
'case' child has incorrect indentation level 12, expected level should be 8.114
'block' child has incorrect indentation level 16, expected level should be 12.115
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\Storage.java

+ Back to top +

File /Users/qianjie/Desktop/main/src/main/java/duke/core/DateTimeParser.java

- - - - - - - - - - - - - - - - - -
Error DescriptionLine
Using the '.*' form of import should be avoided - duke.task.*.3
'}' at column 17 should be on the same line as the next part of a multi-block statement (one that directly contains multiple blocks: if/else-if/else, do/while or try/catch/finally).54
'}' at column 17 should be on the same line as the next part of a multi-block statement (one that directly contains multiple blocks: if/else-if/else, do/while or try/catch/finally).64
'}' at column 17 should be on the same line as the next part of a multi-block statement (one that directly contains multiple blocks: if/else-if/else, do/while or try/catch/finally).74
WhitespaceAround: '}' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)82
WhitespaceAround: 'else' is not preceded with whitespace.82
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\TaskList.java

+ Back to top +

File /Users/qianjie/Desktop/main/src/main/java/duke/core/DukeException.java

Error DescriptionLine
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\Ui.java

+ Back to top +

File /Users/qianjie/Desktop/main/src/main/java/duke/core/Parser.java

- - - - - - - - - - - - - - - - - - - - -
Error DescriptionLine
First sentence of Javadoc is missing an ending period.10
Unused Javadoc tag.104
'(' is preceded with whitespace.106
Comment has incorrect indentation level 0, expected is 8, indentation should be the same level as line 114.116
'(' is preceded with whitespace.141
',' is preceded with whitespace.141
Missing a Javadoc comment.159
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\Deadline.java

+ Back to top +

File /Users/qianjie/Desktop/main/src/main/java/duke/core/Ui.java

- - - - - - - - -
Error DescriptionLine
First sentence of Javadoc is missing an ending period.34
Line continuation have incorrect indentation level, expected level should be 4.38
First sentence of Javadoc is missing an ending period.45
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\Event.java

+ Back to top +

File /Users/qianjie/Desktop/main/src/main/java/duke/patient/Patient.java

- - - - - - - - -
Error DescriptionLine
First sentence of Javadoc is missing an ending period.32
Line continuation have incorrect indentation level, expected level should be 4.36
First sentence of Javadoc is missing an ending period.43
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\FixedDurationTask.java

+ Back to top +

File /Users/qianjie/Desktop/main/src/main/java/duke/patient/PatientManager.java

- - - - - - - - - - - -
Error DescriptionLine
First sentence of Javadoc is missing an ending period.4
Summary javadoc is missing.21
Line continuation have incorrect indentation level, expected level should be 4.24
First sentence of Javadoc is missing an ending period.31
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\PeriodTask.java

+ Back to top +

File /Users/qianjie/Desktop/main/src/main/java/duke/relation/EventPatientTask.java

- - - - - - - - - - - -
Error DescriptionLine
Unused @param tag for 'startTime'.26
First sentence of Javadoc is missing an ending period.37
Line continuation have incorrect indentation level, expected level should be 4.41
First sentence of Javadoc is missing an ending period.50
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\Task.java

+ Back to top +

File /Users/qianjie/Desktop/main/src/main/java/duke/relation/PatientTask.java

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
Error DescriptionLine
First sentence of Javadoc is missing an ending period.25
First sentence of Javadoc is missing an ending period.29
First sentence of Javadoc is missing an ending period.57
First sentence of Javadoc is missing an ending period.66
'{' at column 37 should have line break after.83
'}' at column 59 should be alone on a line.83
'{' at column 38 should have line break after.88
'}' at column 60 should be alone on a line.88
')' is preceded with whitespace.100
'{' at column 43 should have line break after.103
Line continuation have incorrect indentation level, expected level should be 4.125
Comment has incorrect indentation level 0, expected is 4, indentation should be the same level as line 164.158
+ Back to top +

File /Users/qianjie/Desktop/main/src/main/java/duke/relation/PatientTaskList.java

+ + + - - +
Error DescriptionLine
Javadoc comment at column 19 has parse error. Missed HTML close tag 'code'. Sometimes it means that close tag missed for one of previous tags.161
+ Back to top +

File /Users/qianjie/Desktop/main/src/main/java/duke/relation/StandardPatientTask.java

+ + + - - +
Error DescriptionLine
'{' at column 5 should be on the previous line.174
+ Back to top +

File /Users/qianjie/Desktop/main/src/main/java/duke/storage/CmdFreqStorage.java

+ + + - - +
Error DescriptionLine
'{' at column 37 should have line break after.175
+ Back to top +

File /Users/qianjie/Desktop/main/src/main/java/duke/storage/PatientStorage.java

+ + +
Error DescriptionLine
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\Todo.java

+ Back to top +

File /Users/qianjie/Desktop/main/src/main/java/duke/storage/PatientTaskStorage.java

- - +
Error DescriptionLine
First sentence of Javadoc is missing an ending period.18
+ Back to top +

File /Users/qianjie/Desktop/main/src/main/java/duke/storage/TaskStorage.java

+ + + - - +
Error DescriptionLine
Line continuation have incorrect indentation level, expected level should be 4.22
+ Back to top +

File /Users/qianjie/Desktop/main/src/main/java/duke/task/Task.java

+ + + - - +
Error DescriptionLine
First sentence of Javadoc is missing an ending period.29
+ Back to top +

File /Users/qianjie/Desktop/main/src/main/java/duke/task/TaskManager.java

+ + +
Error DescriptionLine
Back to top diff --git a/build/reports/checkstyle/main.xml b/build/reports/checkstyle/main.xml index 777ddd1884..4e8ed03beb 100644 --- a/build/reports/checkstyle/main.xml +++ b/build/reports/checkstyle/main.xml @@ -1,258 +1,67 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/cmdfrequency.csv b/data/cmdfrequency.csv index cf3a98008a..9e02be4fdb 100644 --- a/data/cmdfrequency.csv +++ b/data/cmdfrequency.csv @@ -1,3 +1,9 @@ Command Name,Frequency -AddStandardTaskCommand,3 -AddPatientCommand,3 +DeleteTaskCommand,2 +FindPatientCommand,4 +DeletePatientCommand,2 +ListPatientsCommand,2 +ListTasksCommand,2 +AddStandardTaskCommand,1 +UpdatePatientCommand,3 +FindPatientTaskCommand,3 diff --git a/data/patients.csv b/data/patients.csv index f9f5754514..a84af3189d 100644 --- a/data/patients.csv +++ b/data/patients.csv @@ -2,9 +2,7 @@ Id,Name,NRIC,Room,Remark 16,momo,s123123,a9,nil 1,xk,G00012345,38A,no 2,weifeng,G789456,8B,no -3,qianjiee,G123456,2c,no -9,weifeng,G12356,7A,male -10,kejun,G1234567890,no mood no modd,8A +3,jiejie,G123456,2c,no 11,qianjie,1231312321,A5,NIL 12,qianjie,S92139123,A04,NIL 13,qianjie,s31231231,a09,NIL diff --git a/data/standardTasks.csv b/data/standardTasks.csv index 8487a540ef..853ea509f1 100644 --- a/data/standardTasks.csv +++ b/data/standardTasks.csv @@ -3,12 +3,10 @@ Id,Description 2,Do surgery 3,Take shit 4,eat shit -5,asdjasd 6,fkkk 7,123 8,123 9,321 -10,111 11,123 12,0931 13,1231231 @@ -37,3 +35,4 @@ Id,Description 36,123 37,4 38,wqeqw +39,123 diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index 1149d31669..787331ee1e 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -78,7 +78,7 @@ public void run() { ui.showLine(); Command c = commandManager.manageCommand(fullCommand); c.execute(patientTaskList, taskManager, patientManager, - ui, patientTaskStorage, taskStorage, patientStorage , cmdFreqStorage ,commandManager); + ui, patientTaskStorage, taskStorage, patientStorage, cmdFreqStorage, commandManager); isExit = c.isExit(); } catch (DukeException e) { ui.showError(e.getMessage()); diff --git a/src/main/java/duke/command/AddPatientCommand.java b/src/main/java/duke/command/AddPatientCommand.java index c88e7b2c4f..ad4df4929c 100644 --- a/src/main/java/duke/command/AddPatientCommand.java +++ b/src/main/java/duke/command/AddPatientCommand.java @@ -36,14 +36,18 @@ public AddPatientCommand(String[] patientInfo) throws DukeException { @Override public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, - PatientStorage patientStorage , CmdFreqStorage cmdFreqStorage, CommandManager commandManager) throws DukeException { + PatientStorage patientStorage, CmdFreqStorage cmdFreqStorage, + CommandManager commandManager) throws DukeException { + this.hasBeenAddedBefore = true; String commandName = this.getClass().getSimpleName(); if (!hasBeenAddedBefore) { - commandManager.getCmdFreqTable().put(commandName , 1); + commandManager.getCmdFreqTable().put(commandName, 1); } - int count = commandManager.getCmdFreqTable().containsKey(commandName) ? commandManager.getCmdFreqTable().get(commandName) : 0; - commandManager.getCmdFreqTable().put(commandName , count + 1); + int count = commandManager.getCmdFreqTable().containsKey(commandName) + ? commandManager.getCmdFreqTable().get(commandName) : 0; + + commandManager.getCmdFreqTable().put(commandName, count + 1); patientList.addPatient(newPatient); patientStorage.save(patientList.getPatientList()); cmdFreqStorage.save(commandManager.getCmdFreqTable()); @@ -55,8 +59,5 @@ public boolean isExit() { return false; } - public boolean HasBeenAddedBefore() { - return hasBeenAddedBefore; - } } diff --git a/src/main/java/duke/command/AddStandardTaskCommand.java b/src/main/java/duke/command/AddStandardTaskCommand.java index 17f092f836..7c304a1974 100644 --- a/src/main/java/duke/command/AddStandardTaskCommand.java +++ b/src/main/java/duke/command/AddStandardTaskCommand.java @@ -18,6 +18,7 @@ public class AddStandardTaskCommand extends Command { /** * . + * * @param taskDescription . */ public AddStandardTaskCommand(String taskDescription) { @@ -28,26 +29,30 @@ public AddStandardTaskCommand(String taskDescription) { /** * . - * @param patientTask . - * @param taskList . - * @param patientList . - * @param ui . + * + * @param patientTask . + * @param taskList . + * @param patientList . + * @param ui . * @param patientTaskStorage . - * @param taskStorage . - * @param patientStorage . + * @param taskStorage . + * @param patientStorage . * @throws DukeException . */ @Override public void execute(PatientTaskList patientTask, TaskManager taskList, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, - PatientStorage patientStorage , CmdFreqStorage cmdFreqStorage , CommandManager commandManager) throws DukeException { + PatientStorage patientStorage, CmdFreqStorage cmdFreqStorage, + CommandManager commandManager) throws DukeException { this.hasBeenAddedBefore = true; String commandName = this.getClass().getSimpleName(); if (!hasBeenAddedBefore) { - commandManager.getCmdFreqTable().put(commandName , 1); + commandManager.getCmdFreqTable().put(commandName, 1); } - int count = commandManager.getCmdFreqTable().containsKey(commandName) ? commandManager.getCmdFreqTable().get(commandName) : 0; - commandManager.getCmdFreqTable().put(commandName , count + 1); + int count = commandManager.getCmdFreqTable().containsKey(commandName) + ? commandManager.getCmdFreqTable().get(commandName) : 0; + + commandManager.getCmdFreqTable().put(commandName, count + 1); taskList.addTask(newStandardTask); taskStorage.save(taskList.getTaskList()); cmdFreqStorage.save(commandManager.getCmdFreqTable()); @@ -59,7 +64,4 @@ public boolean isExit() { return false; } - public boolean HasBeenAddedBefore() { - return hasBeenAddedBefore; - } } diff --git a/src/main/java/duke/command/AssignTaskToPatientCommand.java b/src/main/java/duke/command/AssignTaskToPatientCommand.java index ab9725883b..a00844894e 100644 --- a/src/main/java/duke/command/AssignTaskToPatientCommand.java +++ b/src/main/java/duke/command/AssignTaskToPatientCommand.java @@ -1,101 +1,119 @@ -//package duke.command; -// -//import duke.core.DukeException; -//import duke.core.Ui; -//import duke.patient.PatientManager; -//import duke.relation.EventPatientTask; -//import duke.relation.StandardPatientTask; -//import duke.storage.PatientStorage; -//import duke.storage.PatientTaskStorage; -//import duke.storage.TaskStorage; -//import duke.relation.PatientTask; -//import duke.relation.PatientTaskList; -//import duke.task.TaskManager; -// -//public class AssignTaskToPatientCommand extends Command { -// -// private String command; -// private String[] taskAssignmentInfo; -// private PatientTask newPatientTask; -// -// /** -// * . -// * @param taskAssignmentInfo . -// * @throws DukeException . -// */ -// public AssignTaskToPatientCommand(String[] taskAssignmentInfo) throws DukeException { -// super(); -// this.taskAssignmentInfo = taskAssignmentInfo; -// this.newPatientTask = finalPatientTask(taskAssignmentInfo); -// } -// -// /** -// * . -// * @param patientTaskList . -// * @param tasksList . -// * @param patientList . -// * @param ui . -// * @param patientTaskStorage . -// * @param taskStorage . -// * @param patientStorage . -// * @throws DukeException . -// */ -// @Override -// public void execute(PatientTaskList patientTaskList, TaskManager tasksList, PatientManager patientList, -// Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, -// PatientStorage patientStorage) throws DukeException { -// if (patientList.isExist(newPatientTask.getPatientId()) && tasksList.doesExist(newPatientTask.getTaskID())) { -// patientTaskList.addPatientTask(newPatientTask); -// patientTaskStorage.save(patientTaskList.fullPatientTaskList()); -// ui.patientTaskAssigned(newPatientTask, patientList.getPatient(newPatientTask.getPatientId()).getName(), -// tasksList.getTask(newPatientTask.getTaskID()).getDescription()); -// } else { -// throw new DukeException("Either the patient or the task does not exist in our data record"); -// } -// -// } -// -// /** -// * . -// * @param assignmentInfo . -// * @return . -// * @throws DukeException . -// */ -// public PatientTask finalPatientTask(String[] assignmentInfo) throws DukeException { -// try { -// if (assignmentInfo[0].equals("S")) { -// -// String type = assignmentInfo[0]; -// int patientId = Integer.parseInt(assignmentInfo[1]); -// int taskId = Integer.parseInt(assignmentInfo[2]); -// String deadline = assignmentInfo[3]; -// -// StandardPatientTask standardPatientTask = new StandardPatientTask(patientId, taskId, deadline, type); -// return standardPatientTask; -// } else if (assignmentInfo[0].equals("E")) { -// -// String type = assignmentInfo[0]; -// int patientId = Integer.parseInt(assignmentInfo[1]); -// int taskId = Integer.parseInt(assignmentInfo[2]); -// String startTime = assignmentInfo[3]; -// String endTime = assignmentInfo[4]; -// -// EventPatientTask eventPatientTask = new EventPatientTask(patientId, taskId, startTime, endTime, type); -// return eventPatientTask; -// } else { -// throw new DukeException("Parsing failed! Please ensure the format you have entered is correct!"); -// } -// } catch (Exception e) { -// throw new DukeException("Unable to parse your task assignment. Please check your command's format!"); -// } -// } -// -// /** -// * . -// * @return . -// */ -// @Override -// public boolean isExit() { -// return false; -// } -//} \ No newline at end of file +package duke.command; + +import duke.core.CommandManager; +import duke.core.DukeException; +import duke.core.Ui; +import duke.patient.PatientManager; +import duke.relation.EventPatientTask; +import duke.relation.StandardPatientTask; +import duke.storage.CmdFreqStorage; +import duke.storage.PatientStorage; +import duke.storage.PatientTaskStorage; +import duke.storage.TaskStorage; +import duke.relation.PatientTask; +import duke.relation.PatientTaskList; +import duke.task.TaskManager; + +public class AssignTaskToPatientCommand extends Command { + + private String command; + private String[] taskAssignmentInfo; + private PatientTask newPatientTask; + private boolean hasBeenAddedBefore = false; + + /** + * . + * + * @param taskAssignmentInfo . + * @throws DukeException . + */ + public AssignTaskToPatientCommand(String[] taskAssignmentInfo) throws DukeException { + super(); + this.taskAssignmentInfo = taskAssignmentInfo; + this.newPatientTask = finalPatientTask(taskAssignmentInfo); + } + + /** + * . + * + * @param patientTaskList . + * @param tasksList . + * @param patientList . + * @param ui . + * @param patientTaskStorage . + * @param taskStorage . + * @param patientStorage . + * @throws DukeException . + */ + @Override + public void execute(PatientTaskList patientTaskList, TaskManager tasksList, PatientManager patientList, + Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, + PatientStorage patientStorage, CmdFreqStorage cmdFreqStorage, + CommandManager commandManager) throws DukeException { + + if (patientList.isExist(newPatientTask.getPatientId()) && tasksList.doesExist(newPatientTask.getTaskID())) { + this.hasBeenAddedBefore = true; + String commandName = this.getClass().getSimpleName(); + if (!hasBeenAddedBefore) { + commandManager.getCmdFreqTable().put(commandName, 1); + } + int count = commandManager.getCmdFreqTable().containsKey(commandName) + ? commandManager.getCmdFreqTable().get(commandName) : 0; + commandManager.getCmdFreqTable().put(commandName, count + 1); + patientTaskList.addPatientTask(newPatientTask); + patientTaskStorage.save(patientTaskList.fullPatientTaskList()); + cmdFreqStorage.save(commandManager.getCmdFreqTable()); + ui.patientTaskAssigned(newPatientTask, patientList.getPatient(newPatientTask.getPatientId()).getName(), + tasksList.getTask(newPatientTask.getTaskID()).getDescription()); + } else { + throw new DukeException("Either the patient or the task does not exist in our data record"); + } + + } + + /** + * . + * + * @param assignmentInfo . + * @return . + * @throws DukeException . + */ + public PatientTask finalPatientTask(String[] assignmentInfo) throws DukeException { + try { + if (assignmentInfo[0].equals("S")) { + + String type = assignmentInfo[0]; + int patientId = Integer.parseInt(assignmentInfo[1]); + int taskId = Integer.parseInt(assignmentInfo[2]); + String deadline = assignmentInfo[3]; + + StandardPatientTask standardPatientTask = new StandardPatientTask(patientId, taskId, deadline, type); + return standardPatientTask; + } else if (assignmentInfo[0].equals("E")) { + + String type = assignmentInfo[0]; + int patientId = Integer.parseInt(assignmentInfo[1]); + int taskId = Integer.parseInt(assignmentInfo[2]); + String startTime = assignmentInfo[3]; + String endTime = assignmentInfo[4]; + + EventPatientTask eventPatientTask = new EventPatientTask(patientId, taskId, startTime, endTime, type); + return eventPatientTask; + } else { + throw new DukeException("Parsing failed! Please ensure the format you have entered is correct!"); + } + } catch (Exception e) { + throw new DukeException("Unable to parse your task assignment. Please check your command's format!"); + } + } + + /** + * . + * + * @return . + */ + @Override + public boolean isExit() { + return false; + } +} \ No newline at end of file diff --git a/src/main/java/duke/command/Command.java b/src/main/java/duke/command/Command.java index 6bec4bab46..95b2be0632 100644 --- a/src/main/java/duke/command/Command.java +++ b/src/main/java/duke/command/Command.java @@ -31,7 +31,8 @@ public abstract class Command { */ public abstract void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, - PatientStorage patientStorage , CmdFreqStorage cmdFreqStorage ,CommandManager commandManager) throws DukeException; + PatientStorage patientStorage, CmdFreqStorage cmdFreqStorage, + CommandManager commandManager) throws DukeException; /** * Decide whether duke should exist. diff --git a/src/main/java/duke/command/DeletePatientCommand.java b/src/main/java/duke/command/DeletePatientCommand.java index 7c3e6044b1..970a5b3b2f 100644 --- a/src/main/java/duke/command/DeletePatientCommand.java +++ b/src/main/java/duke/command/DeletePatientCommand.java @@ -1,90 +1,104 @@ -//package duke.command; -// -//import duke.core.DukeException; -//import duke.core.Ui; -//import duke.patient.Patient; -//import duke.patient.PatientManager; -//import duke.storage.PatientStorage; -//import duke.storage.PatientTaskStorage; -//import duke.storage.TaskStorage; -//import duke.relation.PatientTaskList; -//import duke.task.TaskManager; -// -// -//import java.util.ArrayList; -// -//public class DeletePatientCommand extends Command { -// private int id; -// private String deletedPatientInfo; -// -// /** -// * . -// * -// * @param deletedPatientInfo . -// * @throws DukeException . -// */ -// public DeletePatientCommand(String deletedPatientInfo) throws DukeException { -// -// this.deletedPatientInfo = deletedPatientInfo; -// char firstChar = deletedPatientInfo.charAt(0); -// if (firstChar == '#') { -// try { -// this.id = Integer.parseInt(deletedPatientInfo.substring(1)); -// } catch (Exception e) { -// throw new DukeException("Please follow format 'delete patient #'. "); -// } -// } -// } -// -// /** -// * . -// * -// * @param patientTask . -// * @param tasks . -// * @param patientManager . -// * @param ui . -// * @param patientTaskStorage . -// * @param taskStorage . -// * @param patientStorage . -// * @throws DukeException . -// */ -// @Override -// public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientManager, -// Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, -// PatientStorage patientStorage) throws DukeException { -// ; -// if (id != 0) { -// Patient patientToBeDeleted = patientManager.getPatient(id); -// boolean toDelete = ui.confirmPatientToBeDeleted(patientToBeDeleted); -// if (toDelete) { -// patientManager.deletePatient(id); -// ui.patientDeleted(); -// patientStorage.save(patientManager.getPatientList()); -// } -// } else { -// ArrayList patientsWithSameName = patientManager.getPatientByName(deletedPatientInfo); -// ui.patientsFoundByName(patientsWithSameName, deletedPatientInfo); -// if (patientsWithSameName.size() >= 1) { -// int numberChosen = ui.choosePatientToDelete(patientsWithSameName.size()); -// if (numberChosen >= 1) { -// boolean toDelete = ui.confirmPatientToBeDeleted(patientsWithSameName.get(numberChosen - 1)); -// if (toDelete) { -// patientManager.deletePatient(patientsWithSameName.get(numberChosen - 1).getID()); -// ui.patientDeleted(); -// patientStorage.save(patientManager.getPatientList()); -// } -// } -// } -// } -// } -// -// /** -// * . -// * -// * @return . -// */ -// @Override -// public boolean isExit() { -// return false; -// } -//} +package duke.command; + +import duke.core.CommandManager; +import duke.core.DukeException; +import duke.core.Ui; +import duke.patient.Patient; +import duke.patient.PatientManager; +import duke.storage.CmdFreqStorage; +import duke.storage.PatientStorage; +import duke.storage.PatientTaskStorage; +import duke.storage.TaskStorage; +import duke.relation.PatientTaskList; +import duke.task.TaskManager; + + +import java.util.ArrayList; + +public class DeletePatientCommand extends Command { + private int id; + private String deletedPatientInfo; + private boolean hasBeenAddedBefore = false; + + /** + * . + * + * @param deletedPatientInfo . + * @throws DukeException . + */ + public DeletePatientCommand(String deletedPatientInfo) throws DukeException { + + this.deletedPatientInfo = deletedPatientInfo; + char firstChar = deletedPatientInfo.charAt(0); + if (firstChar == '#') { + try { + this.id = Integer.parseInt(deletedPatientInfo.substring(1)); + } catch (Exception e) { + throw new DukeException("Please follow format 'delete patient #'. "); + } + } + } + + /** + * . + * + * @param patientTask . + * @param tasks . + * @param patientManager . + * @param ui . + * @param patientTaskStorage . + * @param taskStorage . + * @param patientStorage . + * @throws DukeException . + */ + @Override + public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientManager, + Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, + PatientStorage patientStorage, CmdFreqStorage cmdFreqStorage, + CommandManager commandManager) throws DukeException { + this.hasBeenAddedBefore = true; + String commandName = this.getClass().getSimpleName(); + if (!hasBeenAddedBefore) { + commandManager.getCmdFreqTable().put(commandName, 1); + } + int count = commandManager.getCmdFreqTable().containsKey(commandName) + ? commandManager.getCmdFreqTable().get(commandName) : 0; + commandManager.getCmdFreqTable().put(commandName, count + 1); + + if (id != 0) { + Patient patientToBeDeleted = patientManager.getPatient(id); + boolean toDelete = ui.confirmPatientToBeDeleted(patientToBeDeleted); + if (toDelete) { + patientManager.deletePatient(id); + ui.patientDeleted(); + patientStorage.save(patientManager.getPatientList()); + cmdFreqStorage.save(commandManager.getCmdFreqTable()); + } + } else { + ArrayList patientsWithSameName = patientManager.getPatientByName(deletedPatientInfo); + ui.patientsFoundByName(patientsWithSameName, deletedPatientInfo); + if (patientsWithSameName.size() >= 1) { + int numberChosen = ui.choosePatientToDelete(patientsWithSameName.size()); + if (numberChosen >= 1) { + boolean toDelete = ui.confirmPatientToBeDeleted(patientsWithSameName.get(numberChosen - 1)); + if (toDelete) { + patientManager.deletePatient(patientsWithSameName.get(numberChosen - 1).getID()); + ui.patientDeleted(); + patientStorage.save(patientManager.getPatientList()); + cmdFreqStorage.save(commandManager.getCmdFreqTable()); + } + } + } + } + } + + /** + * . + * + * @return . + */ + @Override + public boolean isExit() { + return false; + } +} diff --git a/src/main/java/duke/command/DeleteTaskCommand.java b/src/main/java/duke/command/DeleteTaskCommand.java index 99eb0c9c7a..bd329d35dc 100644 --- a/src/main/java/duke/command/DeleteTaskCommand.java +++ b/src/main/java/duke/command/DeleteTaskCommand.java @@ -1,83 +1,98 @@ -//package duke.command; -// -//import duke.core.DukeException; -//import duke.core.Ui; -//import duke.patient.PatientManager; -//import duke.storage.PatientStorage; -//import duke.storage.PatientTaskStorage; -//import duke.storage.TaskStorage; -//import duke.relation.PatientTaskList; -//import duke.task.Task; -//import duke.task.TaskManager; -// -//import java.util.ArrayList; -// -//public class DeleteTaskCommand extends Command { -// private int id; -// private String deletedTaskInfo; -// -// /** -// * . -// * -// * @param deletedTaskInfo . -// * @throws DukeException . -// */ -// public DeleteTaskCommand(String deletedTaskInfo) throws DukeException { -// -// this.deletedTaskInfo = deletedTaskInfo; -// char firstChar = deletedTaskInfo.charAt(0); -// if (firstChar == '#') { -// try { -// this.id = Integer.parseInt(deletedTaskInfo.substring(1)); -// } catch (Exception e) { -// throw new DukeException("Please follow format 'delete task #'. "); -// } -// } -// } -// -// /** -// * . -// * -// * @param patientTask . -// * @param taskManager . -// * @param patientManager . -// * @param ui . -// * @param patientTaskStorage . -// * @param taskStorage . -// * @param patientStorage . -// * @throws DukeException . -// */ -// @Override -// public void execute(PatientTaskList patientTask, TaskManager taskManager, PatientManager patientManager, -// Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, -// PatientStorage patientStorage) throws DukeException { -// if (id != 0) { -// Task taskToBeDeleted = taskManager.getTask(id); -// boolean toDelete = ui.confirmTaskToBeDeleted(taskToBeDeleted); -// if (toDelete) { -// taskManager.deleteTask(id); -// ui.taskDeleted(); -// taskStorage.save(taskManager.getTaskList()); -// } -// } else { -// ArrayList tasksWithSameDescription = taskManager.getTaskByDescription(deletedTaskInfo); -// ui.tasksFoundByDescription(tasksWithSameDescription, deletedTaskInfo); -// if (tasksWithSameDescription.size() >= 1) { -// int numberChosen = ui.chooseTaskToDelete(tasksWithSameDescription.size()); -// if (numberChosen >= 1) { -// boolean toDelete = ui.confirmTaskToBeDeleted(tasksWithSameDescription.get(numberChosen - 1)); -// if (toDelete) { -// taskManager.deleteTask(tasksWithSameDescription.get(numberChosen - 1).getID()); -// ui.taskDeleted(); -// taskStorage.save(taskManager.getTaskList()); -// } -// } -// } -// } -// } -// -// @Override -// public boolean isExit() { -// return false; -// } -//} +package duke.command; + +import duke.core.CommandManager; +import duke.core.DukeException; +import duke.core.Ui; +import duke.patient.PatientManager; +import duke.storage.CmdFreqStorage; +import duke.storage.PatientStorage; +import duke.storage.PatientTaskStorage; +import duke.storage.TaskStorage; +import duke.relation.PatientTaskList; +import duke.task.Task; +import duke.task.TaskManager; + +import java.util.ArrayList; + +public class DeleteTaskCommand extends Command { + private int id; + private String deletedTaskInfo; + private boolean hasBeenAddedBefore = false; + + /** + * . + * + * @param deletedTaskInfo . + * @throws DukeException . + */ + public DeleteTaskCommand(String deletedTaskInfo) throws DukeException { + + this.deletedTaskInfo = deletedTaskInfo; + char firstChar = deletedTaskInfo.charAt(0); + if (firstChar == '#') { + try { + this.id = Integer.parseInt(deletedTaskInfo.substring(1)); + } catch (Exception e) { + throw new DukeException("Please follow format 'delete task #'. "); + } + } + } + + /** + * . + * + * @param patientTask . + * @param taskManager . + * @param patientManager . + * @param ui . + * @param patientTaskStorage . + * @param taskStorage . + * @param patientStorage . + * @throws DukeException . + */ + @Override + public void execute(PatientTaskList patientTask, TaskManager taskManager, PatientManager patientManager, + Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, + PatientStorage patientStorage, CmdFreqStorage cmdFreqStorage, + CommandManager commandManager) throws DukeException { + this.hasBeenAddedBefore = true; + String commandName = this.getClass().getSimpleName(); + if (!hasBeenAddedBefore) { + commandManager.getCmdFreqTable().put(commandName, 1); + } + int count = commandManager.getCmdFreqTable().containsKey(commandName) + ? commandManager.getCmdFreqTable().get(commandName) : 0; + commandManager.getCmdFreqTable().put(commandName, count + 1); + + if (id != 0) { + Task taskToBeDeleted = taskManager.getTask(id); + boolean toDelete = ui.confirmTaskToBeDeleted(taskToBeDeleted); + if (toDelete) { + taskManager.deleteTask(id); + ui.taskDeleted(); + taskStorage.save(taskManager.getTaskList()); + cmdFreqStorage.save(commandManager.getCmdFreqTable()); + } + } else { + ArrayList tasksWithSameDescription = taskManager.getTaskByDescription(deletedTaskInfo); + ui.tasksFoundByDescription(tasksWithSameDescription, deletedTaskInfo); + if (tasksWithSameDescription.size() >= 1) { + int numberChosen = ui.chooseTaskToDelete(tasksWithSameDescription.size()); + if (numberChosen >= 1) { + boolean toDelete = ui.confirmTaskToBeDeleted(tasksWithSameDescription.get(numberChosen - 1)); + if (toDelete) { + taskManager.deleteTask(tasksWithSameDescription.get(numberChosen - 1).getID()); + ui.taskDeleted(); + taskStorage.save(taskManager.getTaskList()); + cmdFreqStorage.save(commandManager.getCmdFreqTable()); + } + } + } + } + } + + @Override + public boolean isExit() { + return false; + } +} diff --git a/src/main/java/duke/command/ExitCommand.java b/src/main/java/duke/command/ExitCommand.java index 9c9166d64d..5ad2b9992c 100644 --- a/src/main/java/duke/command/ExitCommand.java +++ b/src/main/java/duke/command/ExitCommand.java @@ -17,7 +17,8 @@ * program */ public class ExitCommand extends Command { - private boolean hasBeenAddedBefore = false; + //private boolean hasBeenAddedBefore = false; + /** * Constructs a ExitCommand object. */ @@ -44,8 +45,8 @@ public boolean isExit() { */ public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, - TaskStorage taskStorage, PatientStorage patientStorage , CmdFreqStorage cmdFreqStorage , CommandManager commandManager) throws DukeException { - this.hasBeenAddedBefore = true; + TaskStorage taskStorage, PatientStorage patientStorage, CmdFreqStorage cmdFreqStorage, + CommandManager commandManager) throws DukeException { ui.exitInformation(); } } \ No newline at end of file diff --git a/src/main/java/duke/command/FindPatientCommand.java b/src/main/java/duke/command/FindPatientCommand.java index b78928a9c5..7b648c8645 100644 --- a/src/main/java/duke/command/FindPatientCommand.java +++ b/src/main/java/duke/command/FindPatientCommand.java @@ -1,64 +1,79 @@ -//package duke.command; -// -//import duke.core.DukeException; -//import duke.core.Ui; -//import duke.patient.Patient; -//import duke.patient.PatientManager; -//import duke.storage.PatientStorage; -//import duke.storage.PatientTaskStorage; -//import duke.storage.TaskStorage; -//import duke.relation.PatientTaskList; -//import duke.task.TaskManager; -// -//import java.util.ArrayList; -// -//public class FindPatientCommand extends Command { -// -// private String command; -// -// public FindPatientCommand(String command) { -// this.command = command; -// } -// -// /** -// * . -// * -// * @param patientTask . -// * @param tasks . -// * @param patientManager . -// * @param ui . -// * @param patientTaskStorage . -// * @param taskStorage . -// * @param patientStorage . -// * @throws DukeException . -// */ -// @Override -// public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientManager, -// Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, -// PatientStorage patientStorage) throws DukeException { -// char firstChar = command.charAt(0); -// if (firstChar == '#') { -// int id; -// try { -// id = Integer.parseInt(command.substring(1, command.length())); -// } catch (Exception e) { -// throw new DukeException("Please follow the format 'find patient #' or 'find patient '."); -// } -// Patient patient = patientManager.getPatient(id); -// ui.patientsFoundById(patient); -// } else { -// ArrayList patientsWithSameName = patientManager.getPatientByName(command); -// ui.patientsFoundByName(patientsWithSameName, command); -// } -// } -// -// /** -// * . -// * -// * @return . -// */ -// @Override -// public boolean isExit() { -// return false; -// } -//} +package duke.command; + +import duke.core.CommandManager; +import duke.core.DukeException; +import duke.core.Ui; +import duke.patient.Patient; +import duke.patient.PatientManager; +import duke.storage.CmdFreqStorage; +import duke.storage.PatientStorage; +import duke.storage.PatientTaskStorage; +import duke.storage.TaskStorage; +import duke.relation.PatientTaskList; +import duke.task.TaskManager; + +import java.util.ArrayList; + +public class FindPatientCommand extends Command { + + private String command; + private boolean hasBeenAddedBefore = false; + + public FindPatientCommand(String command) { + this.command = command; + } + + /** + * . + * + * @param patientTask . + * @param tasks . + * @param patientManager . + * @param ui . + * @param patientTaskStorage . + * @param taskStorage . + * @param patientStorage . + * @throws DukeException . + */ + @Override + public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientManager, + Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, + PatientStorage patientStorage, CmdFreqStorage cmdFreqStorage, + CommandManager commandManager) throws DukeException { + this.hasBeenAddedBefore = true; + String commandName = this.getClass().getSimpleName(); + if (!hasBeenAddedBefore) { + commandManager.getCmdFreqTable().put(commandName, 1); + } + int count = commandManager.getCmdFreqTable().containsKey(commandName) + ? commandManager.getCmdFreqTable().get(commandName) : 0; + commandManager.getCmdFreqTable().put(commandName, count + 1); + + char firstChar = command.charAt(0); + if (firstChar == '#') { + int id; + try { + id = Integer.parseInt(command.substring(1, command.length())); + } catch (Exception e) { + throw new DukeException("Please follow the format 'find patient #' or 'find patient '."); + } + Patient patient = patientManager.getPatient(id); + cmdFreqStorage.save(commandManager.getCmdFreqTable()); + ui.patientsFoundById(patient); + } else { + ArrayList patientsWithSameName = patientManager.getPatientByName(command); + cmdFreqStorage.save(commandManager.getCmdFreqTable()); + ui.patientsFoundByName(patientsWithSameName, command); + } + } + + /** + * . + * + * @return . + */ + @Override + public boolean isExit() { + return false; + } +} diff --git a/src/main/java/duke/command/FindPatientTaskCommand.java b/src/main/java/duke/command/FindPatientTaskCommand.java index e2b233d0d0..058639f104 100644 --- a/src/main/java/duke/command/FindPatientTaskCommand.java +++ b/src/main/java/duke/command/FindPatientTaskCommand.java @@ -1,92 +1,106 @@ -//package duke.command; -// -//import duke.core.DukeException; -//import duke.core.Ui; -//import duke.patient.Patient; -//import duke.patient.PatientManager; -//import duke.relation.PatientTask; -//import duke.relation.PatientTaskList; -//import duke.storage.PatientStorage; -//import duke.storage.PatientTaskStorage; -//import duke.storage.TaskStorage; -//import duke.task.Task; -//import duke.task.TaskManager; -// -//import java.util.ArrayList; -// -//public class FindPatientTaskCommand extends Command { -// -// private String command; -// -// /** -// * . -// * -// * @param cmd . -// */ -// public FindPatientTaskCommand(String cmd) { -// super(); -// this.command = cmd; -// } -// -// /** -// * . -// * -// * @param patientTaskList . -// * @param tasksManager . -// * @param patientManager . -// * @param ui . -// * @param patientTaskStorage . -// * @param taskStorage . -// * @param patientStorage . -// * @throws DukeException . -// */ -// @Override -// public void execute(PatientTaskList patientTaskList, TaskManager tasksManager, PatientManager patientManager, -// Ui ui, PatientTaskStorage patientTaskStorage, -// TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { -// char firstChar = command.charAt(0); -// if (firstChar == '#') { -// int id; -// try { -// id = Integer.parseInt(command.substring(1, command.length())); -// Patient patient = patientManager.getPatient(id); -// ArrayList patientTask = patientTaskList.getPatientTask(id); -// ArrayList tempTask = new ArrayList<>(); -// for (PatientTask temppatientTask : patientTask) { -// tempTask.add(tasksManager.getTask(temppatientTask.getTaskID())); -// } -// ui.patientTaskFound(patient, patientTask, tempTask); -// } catch (Exception e) { -// throw new DukeException("Please follow the format 'find patienttask #' or 'find patient '."); -// } -// } else { -// String name = command.toLowerCase(); -// ArrayList patientsWithSameName = patientManager.getPatientByName(name); -// ArrayList patientWithTask = new ArrayList<>(); -// ArrayList tempTask = new ArrayList<>(); -// -// try { -// for (Patient patient : patientsWithSameName) { -// if (patient.getName().toLowerCase().equals(name)) { -// patientWithTask = patientTaskList.getPatientTask(patient.getID()); -// } -// } -// for (PatientTask temppatientTask : patientWithTask) { -// tempTask.add(tasksManager.getTask(temppatientTask.getTaskID())); -// //System.out.println(temppatientTask.getTaskID() + "\n"); -// } -// -// ui.patientTaskFound(patientsWithSameName.get(0), patientWithTask, tempTask); -// } catch (Exception e) { -// throw new DukeException(e.getMessage() -// + "Please follow the format 'find patienttask #' or 'find patient '."); -// } -// } -// } -// -// -// @Override -// public boolean isExit() { -// return false; -// } -//} \ No newline at end of file +package duke.command; + +import duke.core.CommandManager; +import duke.core.DukeException; +import duke.core.Ui; +import duke.patient.Patient; +import duke.patient.PatientManager; +import duke.relation.PatientTask; +import duke.relation.PatientTaskList; +import duke.storage.CmdFreqStorage; +import duke.storage.PatientStorage; +import duke.storage.PatientTaskStorage; +import duke.storage.TaskStorage; +import duke.task.Task; +import duke.task.TaskManager; + +import java.util.ArrayList; + +public class FindPatientTaskCommand extends Command { + + private String command; + private boolean hasBeenAddedBefore = false; + + /** + * . + * + * @param cmd . + */ + public FindPatientTaskCommand(String cmd) { + super(); + this.command = cmd; + } + + /** + * . + * + * @param patientTaskList . + * @param tasksManager . + * @param patientManager . + * @param ui . + * @param patientTaskStorage . + * @param taskStorage . + * @param patientStorage . + * @throws DukeException . + */ + @Override + public void execute(PatientTaskList patientTaskList, TaskManager tasksManager, PatientManager patientManager, + Ui ui, PatientTaskStorage patientTaskStorage, + TaskStorage taskStorage, PatientStorage patientStorage, CmdFreqStorage cmdFreqStorage, + CommandManager commandManager) throws DukeException { + this.hasBeenAddedBefore = true; + String commandName = this.getClass().getSimpleName(); + if (!hasBeenAddedBefore) { + commandManager.getCmdFreqTable().put(commandName, 1); + } + int count = commandManager.getCmdFreqTable().containsKey(commandName) + ? commandManager.getCmdFreqTable().get(commandName) : 0; + commandManager.getCmdFreqTable().put(commandName, count + 1); + + char firstChar = command.charAt(0); + if (firstChar == '#') { + int id; + try { + id = Integer.parseInt(command.substring(1, command.length())); + Patient patient = patientManager.getPatient(id); + ArrayList patientTask = patientTaskList.getPatientTask(id); + ArrayList tempTask = new ArrayList<>(); + for (PatientTask temppatientTask : patientTask) { + tempTask.add(tasksManager.getTask(temppatientTask.getTaskID())); + } + cmdFreqStorage.save(commandManager.getCmdFreqTable()); + ui.patientTaskFound(patient, patientTask, tempTask); + } catch (Exception e) { + throw new DukeException("Please follow the format 'find patienttask #' or 'find patient '."); + } + } else { + String name = command.toLowerCase(); + ArrayList patientsWithSameName = patientManager.getPatientByName(name); + ArrayList patientWithTask = new ArrayList<>(); + ArrayList tempTask = new ArrayList<>(); + + try { + for (Patient patient : patientsWithSameName) { + if (patient.getName().toLowerCase().equals(name)) { + patientWithTask = patientTaskList.getPatientTask(patient.getID()); + } + } + for (PatientTask temppatientTask : patientWithTask) { + tempTask.add(tasksManager.getTask(temppatientTask.getTaskID())); + //System.out.println(temppatientTask.getTaskID() + "\n"); + } + cmdFreqStorage.save(commandManager.getCmdFreqTable()); + ui.patientTaskFound(patientsWithSameName.get(0), patientWithTask, tempTask); + } catch (Exception e) { + throw new DukeException(e.getMessage() + + "Please follow the format 'find patienttask #' or 'find patient '."); + } + } + } + + + @Override + public boolean isExit() { + return false; + } +} \ No newline at end of file diff --git a/src/main/java/duke/command/ListPatientsCommand.java b/src/main/java/duke/command/ListPatientsCommand.java index c785abd5f0..719a40b169 100644 --- a/src/main/java/duke/command/ListPatientsCommand.java +++ b/src/main/java/duke/command/ListPatientsCommand.java @@ -1,45 +1,58 @@ -//package duke.command; -// -//import duke.core.DukeException; -//import duke.core.Ui; -//import duke.patient.Patient; -//import duke.patient.PatientManager; -//import duke.storage.PatientStorage; -//import duke.storage.PatientTaskStorage; -//import duke.storage.TaskStorage; -//import duke.relation.PatientTaskList; -//import duke.task.TaskManager; -// -//import java.util.ArrayList; -// -//public class ListPatientsCommand extends Command { -// -// public ListPatientsCommand() { -// super(); -// } -// -// /** -// * . -// * -// * @param patientTask . -// * @param tasks . -// * @param patientList . -// * @param ui . -// * @param patientTaskStorage . -// * @param taskStorage . -// * @param patientStorage . -// * @throws DukeException . -// */ -// @Override -// public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, -// Ui ui, PatientTaskStorage patientTaskStorage, -// TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { -// ArrayList list = patientList.getPatientList(); -// ui.listAllPatients(list); -// } -// -// @Override -// public boolean isExit() { -// return false; -// } -//} +package duke.command; + +import duke.core.CommandManager; +import duke.core.DukeException; +import duke.core.Ui; +import duke.patient.Patient; +import duke.patient.PatientManager; +import duke.storage.CmdFreqStorage; +import duke.storage.PatientStorage; +import duke.storage.PatientTaskStorage; +import duke.storage.TaskStorage; +import duke.relation.PatientTaskList; +import duke.task.TaskManager; + +import java.util.ArrayList; + +public class ListPatientsCommand extends Command { + private boolean hasBeenAddedBefore = false; + + public ListPatientsCommand() { + super(); + } + + /** + * . + * + * @param patientTask . + * @param tasks . + * @param patientList . + * @param ui . + * @param patientTaskStorage . + * @param taskStorage . + * @param patientStorage . + * @throws DukeException . + */ + @Override + public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, + Ui ui, PatientTaskStorage patientTaskStorage, + TaskStorage taskStorage, PatientStorage patientStorage, CmdFreqStorage cmdFreqStorage, + CommandManager commandManager) throws DukeException { + this.hasBeenAddedBefore = true; + String commandName = this.getClass().getSimpleName(); + if (!hasBeenAddedBefore) { + commandManager.getCmdFreqTable().put(commandName, 1); + } + int count = commandManager.getCmdFreqTable().containsKey(commandName) + ? commandManager.getCmdFreqTable().get(commandName) : 0; + commandManager.getCmdFreqTable().put(commandName, count + 1); + ArrayList list = patientList.getPatientList(); + cmdFreqStorage.save(commandManager.getCmdFreqTable()); + ui.listAllPatients(list); + } + + @Override + public boolean isExit() { + return false; + } +} diff --git a/src/main/java/duke/command/ListTasksCommand.java b/src/main/java/duke/command/ListTasksCommand.java index abce9346b3..23ae98e777 100644 --- a/src/main/java/duke/command/ListTasksCommand.java +++ b/src/main/java/duke/command/ListTasksCommand.java @@ -1,41 +1,55 @@ -//package duke.command; -// -//import duke.core.DukeException; -//import duke.core.Ui; -//import duke.patient.PatientManager; -//import duke.storage.PatientStorage; -//import duke.storage.PatientTaskStorage; -//import duke.storage.TaskStorage; -//import duke.relation.PatientTaskList; -//import duke.task.Task; -//import duke.task.TaskManager; -// -//import java.util.ArrayList; -// -//public class ListTasksCommand extends Command { -// -// /** -// * . -// * -// * @param patientTask . -// * @param tasks . -// * @param patientList . -// * @param ui . -// * @param patientTaskStorage . -// * @param taskStorage . -// * @param patientStorage . -// * @throws DukeException . -// */ -// @Override -// public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, -// Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, -// PatientStorage patientStorage) throws DukeException { -// ArrayList list = tasks.getTaskList(); -// ui.listAllTasks(list); -// } -// -// @Override -// public boolean isExit() { -// return false; -// } -//} +package duke.command; + +import duke.core.CommandManager; +import duke.core.DukeException; +import duke.core.Ui; +import duke.patient.PatientManager; +import duke.storage.CmdFreqStorage; +import duke.storage.PatientStorage; +import duke.storage.PatientTaskStorage; +import duke.storage.TaskStorage; +import duke.relation.PatientTaskList; +import duke.task.Task; +import duke.task.TaskManager; + +import java.util.ArrayList; + +public class ListTasksCommand extends Command { + private boolean hasBeenAddedBefore = false; + + /** + * . + * + * @param patientTask . + * @param tasks . + * @param patientList . + * @param ui . + * @param patientTaskStorage . + * @param taskStorage . + * @param patientStorage . + * @throws DukeException . + */ + @Override + public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, + Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, + PatientStorage patientStorage, CmdFreqStorage cmdFreqStorage, + CommandManager commandManager) throws DukeException { + this.hasBeenAddedBefore = true; + String commandName = this.getClass().getSimpleName(); + if (!hasBeenAddedBefore) { + commandManager.getCmdFreqTable().put(commandName, 1); + } + int count = commandManager.getCmdFreqTable().containsKey(commandName) + ? commandManager.getCmdFreqTable().get(commandName) : 0; + commandManager.getCmdFreqTable().put(commandName, count + 1); + + ArrayList list = tasks.getTaskList(); + cmdFreqStorage.save(commandManager.getCmdFreqTable()); + ui.listAllTasks(list); + } + + @Override + public boolean isExit() { + return false; + } +} diff --git a/src/main/java/duke/command/UpdatePatientCommand.java b/src/main/java/duke/command/UpdatePatientCommand.java index d254bc5175..18ae317181 100644 --- a/src/main/java/duke/command/UpdatePatientCommand.java +++ b/src/main/java/duke/command/UpdatePatientCommand.java @@ -1,82 +1,96 @@ -//package duke.command; -// -//import duke.core.DukeException; -//import duke.core.Ui; -//import duke.patient.Patient; -//import duke.patient.PatientManager; -//import duke.storage.PatientStorage; -//import duke.storage.PatientTaskStorage; -//import duke.storage.TaskStorage; -//import duke.relation.PatientTaskList; -//import duke.task.TaskManager; -// -//public class UpdatePatientCommand extends Command { -// -// private String command; -// -// /** -// * . -// * -// * @param command . -// */ -// public UpdatePatientCommand(String command) { -// this.command = command; -// } -// -// /** -// * . -// * -// * @param patientTask . -// * @param tasks . -// * @param patientManager . -// * @param ui . -// * @param patientTaskStorage . -// * @param taskStorage . -// * @param patientStorage . -// * @throws DukeException . -// */ -// @Override -// public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientManager, -// Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, -// PatientStorage patientStorage) throws DukeException { -// String[] tempCommand = command.split(" ", 3); -// char firstChar = tempCommand[0].charAt(0); -// if (firstChar == '#') { -// int id; -// try { -// id = Integer.parseInt(tempCommand[0].substring(1, tempCommand[0].length())); -// Patient patientToBeUpdated = patientManager.getPatient(id); -// if (tempCommand[1].toLowerCase().equals("name")) { -// patientToBeUpdated.setName(tempCommand[2]); -// } else if (tempCommand[1].toLowerCase().equals("nric")) { -// patientToBeUpdated.setNric(tempCommand[2]); -// } else if (tempCommand[1].toLowerCase().equals("room")) { -// patientToBeUpdated.setRoom(tempCommand[2]); -// } else { -// throw new DukeException("You can only update 'Name', 'NRIC', or 'Room' of the patient"); -// } -// -// patientStorage.save(patientManager.getPatientList()); -// -// ui.showUpdatedSuccessfully(); -// ui.showPatientInfo(patientToBeUpdated); -// } catch (Exception e) { -// throw new DukeException( -// "Please follow the format 'update patient # '."); -// } -// } else { -// throw new DukeException( -// "Please follow the format 'update patient # '."); -// } -// } -// -// /** -// * . -// * -// * @return . -// */ -// @Override -// public boolean isExit() { -// return false; -// } -//} +package duke.command; + +import duke.core.CommandManager; +import duke.core.DukeException; +import duke.core.Ui; +import duke.patient.Patient; +import duke.patient.PatientManager; +import duke.storage.CmdFreqStorage; +import duke.storage.PatientStorage; +import duke.storage.PatientTaskStorage; +import duke.storage.TaskStorage; +import duke.relation.PatientTaskList; +import duke.task.TaskManager; + +public class UpdatePatientCommand extends Command { + + private String command; + private boolean hasBeenAddedBefore = false; + + /** + * . + * + * @param command . + */ + public UpdatePatientCommand(String command) { + this.command = command; + } + + /** + * . + * + * @param patientTask . + * @param tasks . + * @param patientManager . + * @param ui . + * @param patientTaskStorage . + * @param taskStorage . + * @param patientStorage . + * @throws DukeException . + */ + @Override + public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientManager, + Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, + PatientStorage patientStorage, CmdFreqStorage cmdFreqStorage, + CommandManager commandManager) throws DukeException { + + this.hasBeenAddedBefore = true; + String commandName = this.getClass().getSimpleName(); + if (!hasBeenAddedBefore) { + commandManager.getCmdFreqTable().put(commandName, 1); + } + int count = commandManager.getCmdFreqTable().containsKey(commandName) + ? commandManager.getCmdFreqTable().get(commandName) : 0; + commandManager.getCmdFreqTable().put(commandName, count + 1); + String[] tempCommand = command.split(" ", 3); + char firstChar = tempCommand[0].charAt(0); + if (firstChar == '#') { + int id; + try { + id = Integer.parseInt(tempCommand[0].substring(1, tempCommand[0].length())); + Patient patientToBeUpdated = patientManager.getPatient(id); + if (tempCommand[1].toLowerCase().equals("name")) { + patientToBeUpdated.setName(tempCommand[2]); + } else if (tempCommand[1].toLowerCase().equals("nric")) { + patientToBeUpdated.setNric(tempCommand[2]); + } else if (tempCommand[1].toLowerCase().equals("room")) { + patientToBeUpdated.setRoom(tempCommand[2]); + } else { + throw new DukeException("You can only update 'Name', 'NRIC', or 'Room' of the patient"); + } + + patientStorage.save(patientManager.getPatientList()); + cmdFreqStorage.save(commandManager.getCmdFreqTable()); + + ui.showUpdatedSuccessfully(); + ui.showPatientInfo(patientToBeUpdated); + } catch (Exception e) { + throw new DukeException( + "Please follow the format 'update patient # '."); + } + } else { + throw new DukeException( + "Please follow the format 'update patient # '."); + } + } + + /** + * . + * + * @return . + */ + @Override + public boolean isExit() { + return false; + } +} diff --git a/src/main/java/duke/command/UpdateTaskCommand.java b/src/main/java/duke/command/UpdateTaskCommand.java index 192c8da4b9..e06d91bc2e 100644 --- a/src/main/java/duke/command/UpdateTaskCommand.java +++ b/src/main/java/duke/command/UpdateTaskCommand.java @@ -1,70 +1,84 @@ -//package duke.command; -// -//import duke.core.DukeException; -//import duke.core.Ui; -//import duke.task.Task; -//import duke.patient.PatientManager; -//import duke.storage.PatientStorage; -//import duke.storage.PatientTaskStorage; -//import duke.storage.TaskStorage; -//import duke.relation.PatientTaskList; -//import duke.task.TaskManager; -// -//public class UpdateTaskCommand extends Command { -// private String command; -// -// /** -// * . -// * -// * @param command . -// */ -// public UpdateTaskCommand(String command) { -// this.command = command; -// } -// -// /** -// * . -// * -// * @param patientTask . -// * @param taskManager . -// * @param patientManager . -// * @param ui . -// * @param patientTaskStorage . -// * @param taskStorage . -// * @param patientStorage . -// * @throws DukeException . -// */ -// @Override -// public void execute(PatientTaskList patientTask, TaskManager taskManager, PatientManager patientManager, -// Ui ui, PatientTaskStorage patientTaskStorage, -// TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { -// String[] tempCommand = command.split(" ", 3); -// char firstChar = tempCommand[0].charAt(0); -// if (firstChar == '#') { -// int id; -// try { -// id = Integer.parseInt(tempCommand[0].substring(1, tempCommand[0].length())); -// Task taskToBeUpdated = taskManager.getTask(id); -// if (tempCommand[1].toLowerCase().equals("description")) { -// taskToBeUpdated.setDescription(tempCommand[2]); -// } else { -// throw new DukeException("You can only update 'Description' of the task"); -// } -// -// taskStorage.save(taskManager.getTaskList()); -// -// ui.showUpdatedSuccessfully(); -// ui.showTaskInfo(taskToBeUpdated); -// } catch (Exception e) { -// throw new DukeException( -// "Please follow the format 'update patient # '."); -// } -// -// } -// } -// -// @Override -// public boolean isExit() { -// return false; -// } -//} +package duke.command; + +import duke.core.CommandManager; +import duke.core.DukeException; +import duke.core.Ui; +import duke.storage.CmdFreqStorage; +import duke.task.Task; +import duke.patient.PatientManager; +import duke.storage.PatientStorage; +import duke.storage.PatientTaskStorage; +import duke.storage.TaskStorage; +import duke.relation.PatientTaskList; +import duke.task.TaskManager; + +public class UpdateTaskCommand extends Command { + private String command; + private boolean hasBeenAddedBefore = false; + + /** + * . + * + * @param command . + */ + public UpdateTaskCommand(String command) { + this.command = command; + } + + /** + * . + * + * @param patientTask . + * @param taskManager . + * @param patientManager . + * @param ui . + * @param patientTaskStorage . + * @param taskStorage . + * @param patientStorage . + * @throws DukeException . + */ + @Override + public void execute(PatientTaskList patientTask, TaskManager taskManager, PatientManager patientManager, + Ui ui, PatientTaskStorage patientTaskStorage, + TaskStorage taskStorage, PatientStorage patientStorage, CmdFreqStorage cmdFreqStorage, + CommandManager commandManager) throws DukeException { + this.hasBeenAddedBefore = true; + String commandName = this.getClass().getSimpleName(); + if (!hasBeenAddedBefore) { + commandManager.getCmdFreqTable().put(commandName, 1); + } + int count = commandManager.getCmdFreqTable().containsKey(commandName) + ? commandManager.getCmdFreqTable().get(commandName) : 0; + commandManager.getCmdFreqTable().put(commandName, count + 1); + + String[] tempCommand = command.split(" ", 3); + char firstChar = tempCommand[0].charAt(0); + if (firstChar == '#') { + int id; + try { + id = Integer.parseInt(tempCommand[0].substring(1, tempCommand[0].length())); + Task taskToBeUpdated = taskManager.getTask(id); + if (tempCommand[1].toLowerCase().equals("description")) { + taskToBeUpdated.setDescription(tempCommand[2]); + } else { + throw new DukeException("You can only update 'Description' of the task"); + } + + taskStorage.save(taskManager.getTaskList()); + cmdFreqStorage.save(commandManager.getCmdFreqTable()); + + ui.showUpdatedSuccessfully(); + ui.showTaskInfo(taskToBeUpdated); + } catch (Exception e) { + throw new DukeException( + "Please follow the format 'update patient # '."); + } + + } + } + + @Override + public boolean isExit() { + return false; + } +} diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index dd43b41c6a..c7dcac2062 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -2,22 +2,20 @@ import duke.command.AddPatientCommand; import duke.command.AddStandardTaskCommand; +import duke.command.AssignTaskToPatientCommand; import duke.command.Command; +import duke.command.DeletePatientCommand; +import duke.command.DeleteTaskCommand; import duke.command.ExitCommand; -import duke.storage.CmdFreqStorage; -//import duke.command.AssignTaskToPatientCommand; -//import duke.command.DeletePatientCommand; -//import duke.command.DeleteTaskCommand; -//import duke.command.FindPatientCommand; -//import duke.command.FindPatientTaskCommand; -//import duke.command.ListPatientsCommand; -//import duke.command.ListTasksCommand; -//import duke.command.UpdatePatientCommand; -//import duke.command.UpdateTaskCommand; +import duke.command.FindPatientCommand; +import duke.command.FindPatientTaskCommand; +import duke.command.ListPatientsCommand; +import duke.command.ListTasksCommand; +import duke.command.UpdatePatientCommand; +import duke.command.UpdateTaskCommand; -import java.util.HashMap; import java.util.Map; -import java.util.Set; + /** * Represents a Parser that parses user input into a specific @@ -25,12 +23,13 @@ */ public class CommandManager { - private Map cmdFreqTable; - public CommandManager (Map cmdFreqTable){ + private Map cmdFreqTable; + + public CommandManager(Map cmdFreqTable) { this.cmdFreqTable = cmdFreqTable; } - public Map getCmdFreqTable () { + public Map getCmdFreqTable() { return cmdFreqTable; } @@ -55,79 +54,78 @@ public Command manageCommand(String userInput) throws DukeException { } else if (secondKeyword.equals("task")) { String formattedInput = parser.parseAdd()[0]; AddStandardTaskCommand addStandardTaskCommand = new AddStandardTaskCommand(formattedInput); - return addStandardTaskCommand ; + return addStandardTaskCommand; } else { throw new DukeException("Add command fails. "); } -// case "assign": -// return new AssignTaskToPatientCommand(parser.parseAssign()); -// case "list": -// try { -// String[] tempCommand = command[1].split("\\s+"); -// if (tempCommand[0].toLowerCase().equals("patients")) { -// return new ListPatientsCommand(); -// } else if (tempCommand[0].toLowerCase().equals("tasks")) { -// return new ListTasksCommand(); -// } else { -// throw new Exception("Invalid 'list' command. "); -// } -// } catch (Exception e) { -// throw new DukeException("List command fails. " + e.getMessage()); -// } -// case "delete": -// try { -// secondKeyword = command[1].toLowerCase(); -// if (secondKeyword.equals("patient")) { -// String formattedInput = parser.parseDeletePatient(); -// return new DeletePatientCommand(formattedInput); -// } else if (secondKeyword.equals("task")) { -// return new DeleteTaskCommand(parser.parseDeleteTask()); -// } else { -// throw new Exception("Invalid format. "); -// } -// } catch (Exception e) { -// throw new DukeException("Delete command fails. " + e.getMessage()); -// } -// case "find": -// try { -// secondKeyword = command[1].toLowerCase(); -// if (secondKeyword.equals("patient")) { -// try { -// return new FindPatientCommand(command[2]); -// } catch (Exception e) { -// throw new Exception("Please follow the format 'find patient #' or 'find patient '."); -// } -// } else if (secondKeyword.equals("patienttask")) { -// try { -// return new FindPatientTaskCommand(command[2]); -// } catch (Exception e) { -// throw new Exception("Please follow the format 'find patient #' or 'find patient '."); -// } -// } else { -// throw new Exception("Invalid format. "); -// } -// } catch (Exception e) { -// throw new DukeException("Find command fails. " + e.getMessage()); -// } -// case "update": -// try { -// secondKeyword = command[1].toLowerCase(); -// if (secondKeyword.equals("patient")) { -// String formattedInput = parser.parseUpdatePatient(); -// return new UpdatePatientCommand(formattedInput); -// } else if (secondKeyword.equals("task")) { -// String formattedInput = parser.parseUpdateTask(); -// return new UpdateTaskCommand(formattedInput); -// } else { -// throw new Exception("Invalid format. "); -// } -// } catch (Exception e) { -// throw new DukeException("update command fails. " + e.getMessage()); -// } + case "assign": + return new AssignTaskToPatientCommand(parser.parseAssign()); + case "list": + try { + String[] tempCommand = command[1].split("\\s+"); + if (tempCommand[0].toLowerCase().equals("patients")) { + return new ListPatientsCommand(); + } else if (tempCommand[0].toLowerCase().equals("tasks")) { + return new ListTasksCommand(); + } else { + throw new Exception("Invalid 'list' command. "); + } + } catch (Exception e) { + throw new DukeException("List command fails. " + e.getMessage()); + } + case "delete": + try { + secondKeyword = command[1].toLowerCase(); + if (secondKeyword.equals("patient")) { + String formattedInput = parser.parseDeletePatient(); + return new DeletePatientCommand(formattedInput); + } else if (secondKeyword.equals("task")) { + return new DeleteTaskCommand(parser.parseDeleteTask()); + } else { + throw new Exception("Invalid format. "); + } + } catch (Exception e) { + throw new DukeException("Delete command fails. " + e.getMessage()); + } + case "find": + try { + secondKeyword = command[1].toLowerCase(); + if (secondKeyword.equals("patient")) { + try { + return new FindPatientCommand(command[2]); + } catch (Exception e) { + throw new Exception("Please follow the format 'find patient #' or 'find patient '."); + } + } else if (secondKeyword.equals("patienttask")) { + try { + return new FindPatientTaskCommand(command[2]); + } catch (Exception e) { + throw new Exception("Please follow the format 'find patient #' or 'find patient '."); + } + } else { + throw new Exception("Invalid format. "); + } + } catch (Exception e) { + throw new DukeException("Find command fails. " + e.getMessage()); + } + case "update": + try { + secondKeyword = command[1].toLowerCase(); + if (secondKeyword.equals("patient")) { + String formattedInput = parser.parseUpdatePatient(); + return new UpdatePatientCommand(formattedInput); + } else if (secondKeyword.equals("task")) { + String formattedInput = parser.parseUpdateTask(); + return new UpdateTaskCommand(formattedInput); + } else { + throw new Exception("Invalid format. "); + } + } catch (Exception e) { + throw new DukeException("update command fails. " + e.getMessage()); + } case "bye": ExitCommand exitCommand = new ExitCommand(); - String commandName = exitCommand.getClass().getSimpleName(); - for (Map.Entry entry : cmdFreqTable.entrySet()) { + for (Map.Entry entry : cmdFreqTable.entrySet()) { System.out.println("Key = " + entry.getKey()); System.out.println("Value = " + entry.getValue()); System.out.println("===================================================="); diff --git a/src/main/java/duke/storage/CmdFreqStorage.java b/src/main/java/duke/storage/CmdFreqStorage.java index 7591a1954f..e6bfc7cfbb 100644 --- a/src/main/java/duke/storage/CmdFreqStorage.java +++ b/src/main/java/duke/storage/CmdFreqStorage.java @@ -1,19 +1,18 @@ package duke.storage; -import duke.core.CommandManager; import duke.core.DukeException; -import duke.patient.Patient; -import duke.relation.EventPatientTask; -import duke.relation.PatientTask; -import duke.relation.StandardPatientTask; + import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVPrinter; import org.apache.commons.csv.CSVRecord; -import java.io.*; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.Reader; import java.nio.file.Files; import java.nio.file.Paths; -import java.util.ArrayList; import java.util.HashMap; import java.util.Map; @@ -22,6 +21,7 @@ public class CmdFreqStorage { * A string that represents a relative file path from the project folder. */ private String filePath; + /** * Constructs a Storage object with a specific file path. * @@ -38,8 +38,8 @@ public CmdFreqStorage(String filePath) { * @return A arrayList of PatientTask which contain info of task with associated patient * @throws DukeException throw a dukeException with error message for debugging */ - public Map load() throws DukeException { - Map cmdFreqTable = new HashMap<>(); + public Map load() throws DukeException { + Map cmdFreqTable = new HashMap<>(); File csvFile = new File(filePath); try { if (csvFile.createNewFile()) { @@ -50,7 +50,7 @@ public CmdFreqStorage(String filePath) { for (CSVRecord record : records) { String commandName = record.get("Command Name"); Integer frequency = Integer.parseInt(record.get("Frequency")); - cmdFreqTable.put(commandName , frequency); + cmdFreqTable.put(commandName, frequency); } } System.out.println("Load completed"); @@ -69,15 +69,15 @@ public CmdFreqStorage(String filePath) { * @param cmdFreqTable A list of patients containing info of patients to be written * @throws DukeException throw exception with error message when i/o fails */ - public void save(Map cmdFreqTable) throws DukeException { + public void save(Map cmdFreqTable) throws DukeException { try { BufferedWriter writer = Files.newBufferedWriter(Paths.get(filePath)); CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT - .withHeader("Command Name" , "Frequency")); - for (Map.Entry entry : cmdFreqTable.entrySet()) { + .withHeader("Command Name", "Frequency")); + for (Map.Entry entry : cmdFreqTable.entrySet()) { String commandName = entry.getKey(); String frequency = entry.getValue().toString(); - csvPrinter.printRecord(commandName , frequency ); + csvPrinter.printRecord(commandName, frequency); } csvPrinter.flush(); } catch (IOException e) { From d1932539d1efc7c979ca04506ecfb3c31016b315 Mon Sep 17 00:00:00 2001 From: Qian Jie Date: Sat, 19 Oct 2019 14:52:11 +0800 Subject: [PATCH 165/420] created runCommandFrequencyLogic function in the command class to improve code cleanliness and easier integration in case there are more commands added in. --- data/cmdfrequency.csv | 8 +------- data/standardTasks.csv | 2 +- .../java/duke/command/AddPatientCommand.java | 11 +---------- .../duke/command/AddStandardTaskCommand.java | 11 +---------- .../command/AssignTaskToPatientCommand.java | 10 +--------- src/main/java/duke/command/Command.java | 19 +++++++++++++++++++ .../duke/command/DeletePatientCommand.java | 10 +--------- .../java/duke/command/DeleteTaskCommand.java | 11 +---------- src/main/java/duke/command/ExitCommand.java | 1 - .../java/duke/command/FindPatientCommand.java | 11 +---------- .../duke/command/FindPatientTaskCommand.java | 11 +---------- .../duke/command/ListPatientsCommand.java | 10 +--------- .../java/duke/command/ListTasksCommand.java | 11 +---------- .../duke/command/UpdatePatientCommand.java | 11 +---------- .../java/duke/command/UpdateTaskCommand.java | 11 +---------- 15 files changed, 32 insertions(+), 116 deletions(-) diff --git a/data/cmdfrequency.csv b/data/cmdfrequency.csv index 9e02be4fdb..2cc6e49f95 100644 --- a/data/cmdfrequency.csv +++ b/data/cmdfrequency.csv @@ -1,9 +1,3 @@ Command Name,Frequency -DeleteTaskCommand,2 -FindPatientCommand,4 -DeletePatientCommand,2 -ListPatientsCommand,2 -ListTasksCommand,2 +DeleteTaskCommand,1 AddStandardTaskCommand,1 -UpdatePatientCommand,3 -FindPatientTaskCommand,3 diff --git a/data/standardTasks.csv b/data/standardTasks.csv index 853ea509f1..bf7d52e7ba 100644 --- a/data/standardTasks.csv +++ b/data/standardTasks.csv @@ -2,7 +2,6 @@ Id,Description 1,Take Medicine A 2,Do surgery 3,Take shit -4,eat shit 6,fkkk 7,123 8,123 @@ -36,3 +35,4 @@ Id,Description 37,4 38,wqeqw 39,123 +40,123 diff --git a/src/main/java/duke/command/AddPatientCommand.java b/src/main/java/duke/command/AddPatientCommand.java index ad4df4929c..07800ea505 100644 --- a/src/main/java/duke/command/AddPatientCommand.java +++ b/src/main/java/duke/command/AddPatientCommand.java @@ -15,7 +15,6 @@ public class AddPatientCommand extends Command { private Patient newPatient; - private boolean hasBeenAddedBefore = false; /** * . @@ -39,15 +38,7 @@ public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManag PatientStorage patientStorage, CmdFreqStorage cmdFreqStorage, CommandManager commandManager) throws DukeException { - this.hasBeenAddedBefore = true; - String commandName = this.getClass().getSimpleName(); - if (!hasBeenAddedBefore) { - commandManager.getCmdFreqTable().put(commandName, 1); - } - int count = commandManager.getCmdFreqTable().containsKey(commandName) - ? commandManager.getCmdFreqTable().get(commandName) : 0; - - commandManager.getCmdFreqTable().put(commandName, count + 1); + runCommandFrequencyLogic(commandManager); patientList.addPatient(newPatient); patientStorage.save(patientList.getPatientList()); cmdFreqStorage.save(commandManager.getCmdFreqTable()); diff --git a/src/main/java/duke/command/AddStandardTaskCommand.java b/src/main/java/duke/command/AddStandardTaskCommand.java index 7c304a1974..4dbe8c3e3c 100644 --- a/src/main/java/duke/command/AddStandardTaskCommand.java +++ b/src/main/java/duke/command/AddStandardTaskCommand.java @@ -14,7 +14,6 @@ public class AddStandardTaskCommand extends Command { private Task newStandardTask; - private boolean hasBeenAddedBefore = false; /** * . @@ -44,15 +43,7 @@ public void execute(PatientTaskList patientTask, TaskManager taskList, PatientMa Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage, CmdFreqStorage cmdFreqStorage, CommandManager commandManager) throws DukeException { - this.hasBeenAddedBefore = true; - String commandName = this.getClass().getSimpleName(); - if (!hasBeenAddedBefore) { - commandManager.getCmdFreqTable().put(commandName, 1); - } - int count = commandManager.getCmdFreqTable().containsKey(commandName) - ? commandManager.getCmdFreqTable().get(commandName) : 0; - - commandManager.getCmdFreqTable().put(commandName, count + 1); + runCommandFrequencyLogic(commandManager); taskList.addTask(newStandardTask); taskStorage.save(taskList.getTaskList()); cmdFreqStorage.save(commandManager.getCmdFreqTable()); diff --git a/src/main/java/duke/command/AssignTaskToPatientCommand.java b/src/main/java/duke/command/AssignTaskToPatientCommand.java index a00844894e..0e56996341 100644 --- a/src/main/java/duke/command/AssignTaskToPatientCommand.java +++ b/src/main/java/duke/command/AssignTaskToPatientCommand.java @@ -19,7 +19,6 @@ public class AssignTaskToPatientCommand extends Command { private String command; private String[] taskAssignmentInfo; private PatientTask newPatientTask; - private boolean hasBeenAddedBefore = false; /** * . @@ -52,14 +51,7 @@ public void execute(PatientTaskList patientTaskList, TaskManager tasksList, Pati CommandManager commandManager) throws DukeException { if (patientList.isExist(newPatientTask.getPatientId()) && tasksList.doesExist(newPatientTask.getTaskID())) { - this.hasBeenAddedBefore = true; - String commandName = this.getClass().getSimpleName(); - if (!hasBeenAddedBefore) { - commandManager.getCmdFreqTable().put(commandName, 1); - } - int count = commandManager.getCmdFreqTable().containsKey(commandName) - ? commandManager.getCmdFreqTable().get(commandName) : 0; - commandManager.getCmdFreqTable().put(commandName, count + 1); + runCommandFrequencyLogic(commandManager); patientTaskList.addPatientTask(newPatientTask); patientTaskStorage.save(patientTaskList.fullPatientTaskList()); cmdFreqStorage.save(commandManager.getCmdFreqTable()); diff --git a/src/main/java/duke/command/Command.java b/src/main/java/duke/command/Command.java index 95b2be0632..7280cac85d 100644 --- a/src/main/java/duke/command/Command.java +++ b/src/main/java/duke/command/Command.java @@ -17,6 +17,9 @@ * of user command */ public abstract class Command { + + protected boolean hasBeenAddedBefore = false; + /** * . * @@ -33,6 +36,22 @@ public abstract void execute(PatientTaskList patientTask, TaskManager tasks, Pat PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage, CmdFreqStorage cmdFreqStorage, CommandManager commandManager) throws DukeException; + /** + * This function is used across all the child command for running of + * Command Frequency Logic. + * @param commandManager passing a CommandManager object to get the CmdFreqTable for use. + */ + + public void runCommandFrequencyLogic(CommandManager commandManager) { + this.hasBeenAddedBefore = true; + String commandName = this.getClass().getSimpleName(); + if (!hasBeenAddedBefore) { + commandManager.getCmdFreqTable().put(commandName, 1); + } + int count = commandManager.getCmdFreqTable().containsKey(commandName) + ? commandManager.getCmdFreqTable().get(commandName) : 0; + commandManager.getCmdFreqTable().put(commandName, count + 1); + } /** * Decide whether duke should exist. diff --git a/src/main/java/duke/command/DeletePatientCommand.java b/src/main/java/duke/command/DeletePatientCommand.java index 970a5b3b2f..7eb89bf363 100644 --- a/src/main/java/duke/command/DeletePatientCommand.java +++ b/src/main/java/duke/command/DeletePatientCommand.java @@ -18,7 +18,6 @@ public class DeletePatientCommand extends Command { private int id; private String deletedPatientInfo; - private boolean hasBeenAddedBefore = false; /** * . @@ -56,15 +55,8 @@ public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManag Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage, CmdFreqStorage cmdFreqStorage, CommandManager commandManager) throws DukeException { - this.hasBeenAddedBefore = true; - String commandName = this.getClass().getSimpleName(); - if (!hasBeenAddedBefore) { - commandManager.getCmdFreqTable().put(commandName, 1); - } - int count = commandManager.getCmdFreqTable().containsKey(commandName) - ? commandManager.getCmdFreqTable().get(commandName) : 0; - commandManager.getCmdFreqTable().put(commandName, count + 1); + runCommandFrequencyLogic(commandManager); if (id != 0) { Patient patientToBeDeleted = patientManager.getPatient(id); boolean toDelete = ui.confirmPatientToBeDeleted(patientToBeDeleted); diff --git a/src/main/java/duke/command/DeleteTaskCommand.java b/src/main/java/duke/command/DeleteTaskCommand.java index bd329d35dc..6d5732baff 100644 --- a/src/main/java/duke/command/DeleteTaskCommand.java +++ b/src/main/java/duke/command/DeleteTaskCommand.java @@ -17,7 +17,6 @@ public class DeleteTaskCommand extends Command { private int id; private String deletedTaskInfo; - private boolean hasBeenAddedBefore = false; /** * . @@ -55,15 +54,7 @@ public void execute(PatientTaskList patientTask, TaskManager taskManager, Patien Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage, CmdFreqStorage cmdFreqStorage, CommandManager commandManager) throws DukeException { - this.hasBeenAddedBefore = true; - String commandName = this.getClass().getSimpleName(); - if (!hasBeenAddedBefore) { - commandManager.getCmdFreqTable().put(commandName, 1); - } - int count = commandManager.getCmdFreqTable().containsKey(commandName) - ? commandManager.getCmdFreqTable().get(commandName) : 0; - commandManager.getCmdFreqTable().put(commandName, count + 1); - + runCommandFrequencyLogic(commandManager); if (id != 0) { Task taskToBeDeleted = taskManager.getTask(id); boolean toDelete = ui.confirmTaskToBeDeleted(taskToBeDeleted); diff --git a/src/main/java/duke/command/ExitCommand.java b/src/main/java/duke/command/ExitCommand.java index 5ad2b9992c..ba0305b7e2 100644 --- a/src/main/java/duke/command/ExitCommand.java +++ b/src/main/java/duke/command/ExitCommand.java @@ -17,7 +17,6 @@ * program */ public class ExitCommand extends Command { - //private boolean hasBeenAddedBefore = false; /** * Constructs a ExitCommand object. diff --git a/src/main/java/duke/command/FindPatientCommand.java b/src/main/java/duke/command/FindPatientCommand.java index 7b648c8645..77a560fd18 100644 --- a/src/main/java/duke/command/FindPatientCommand.java +++ b/src/main/java/duke/command/FindPatientCommand.java @@ -17,7 +17,6 @@ public class FindPatientCommand extends Command { private String command; - private boolean hasBeenAddedBefore = false; public FindPatientCommand(String command) { this.command = command; @@ -40,15 +39,7 @@ public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManag Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage, CmdFreqStorage cmdFreqStorage, CommandManager commandManager) throws DukeException { - this.hasBeenAddedBefore = true; - String commandName = this.getClass().getSimpleName(); - if (!hasBeenAddedBefore) { - commandManager.getCmdFreqTable().put(commandName, 1); - } - int count = commandManager.getCmdFreqTable().containsKey(commandName) - ? commandManager.getCmdFreqTable().get(commandName) : 0; - commandManager.getCmdFreqTable().put(commandName, count + 1); - + runCommandFrequencyLogic(commandManager); char firstChar = command.charAt(0); if (firstChar == '#') { int id; diff --git a/src/main/java/duke/command/FindPatientTaskCommand.java b/src/main/java/duke/command/FindPatientTaskCommand.java index 058639f104..459cadce8a 100644 --- a/src/main/java/duke/command/FindPatientTaskCommand.java +++ b/src/main/java/duke/command/FindPatientTaskCommand.java @@ -19,7 +19,6 @@ public class FindPatientTaskCommand extends Command { private String command; - private boolean hasBeenAddedBefore = false; /** * . @@ -48,15 +47,7 @@ public void execute(PatientTaskList patientTaskList, TaskManager tasksManager, P Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage, CmdFreqStorage cmdFreqStorage, CommandManager commandManager) throws DukeException { - this.hasBeenAddedBefore = true; - String commandName = this.getClass().getSimpleName(); - if (!hasBeenAddedBefore) { - commandManager.getCmdFreqTable().put(commandName, 1); - } - int count = commandManager.getCmdFreqTable().containsKey(commandName) - ? commandManager.getCmdFreqTable().get(commandName) : 0; - commandManager.getCmdFreqTable().put(commandName, count + 1); - + runCommandFrequencyLogic(commandManager); char firstChar = command.charAt(0); if (firstChar == '#') { int id; diff --git a/src/main/java/duke/command/ListPatientsCommand.java b/src/main/java/duke/command/ListPatientsCommand.java index 719a40b169..f3cca5b9d6 100644 --- a/src/main/java/duke/command/ListPatientsCommand.java +++ b/src/main/java/duke/command/ListPatientsCommand.java @@ -15,7 +15,6 @@ import java.util.ArrayList; public class ListPatientsCommand extends Command { - private boolean hasBeenAddedBefore = false; public ListPatientsCommand() { super(); @@ -38,14 +37,7 @@ public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManag Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage, CmdFreqStorage cmdFreqStorage, CommandManager commandManager) throws DukeException { - this.hasBeenAddedBefore = true; - String commandName = this.getClass().getSimpleName(); - if (!hasBeenAddedBefore) { - commandManager.getCmdFreqTable().put(commandName, 1); - } - int count = commandManager.getCmdFreqTable().containsKey(commandName) - ? commandManager.getCmdFreqTable().get(commandName) : 0; - commandManager.getCmdFreqTable().put(commandName, count + 1); + runCommandFrequencyLogic(commandManager); ArrayList list = patientList.getPatientList(); cmdFreqStorage.save(commandManager.getCmdFreqTable()); ui.listAllPatients(list); diff --git a/src/main/java/duke/command/ListTasksCommand.java b/src/main/java/duke/command/ListTasksCommand.java index 23ae98e777..e049dae6f0 100644 --- a/src/main/java/duke/command/ListTasksCommand.java +++ b/src/main/java/duke/command/ListTasksCommand.java @@ -15,7 +15,6 @@ import java.util.ArrayList; public class ListTasksCommand extends Command { - private boolean hasBeenAddedBefore = false; /** * . @@ -34,15 +33,7 @@ public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManag Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage, CmdFreqStorage cmdFreqStorage, CommandManager commandManager) throws DukeException { - this.hasBeenAddedBefore = true; - String commandName = this.getClass().getSimpleName(); - if (!hasBeenAddedBefore) { - commandManager.getCmdFreqTable().put(commandName, 1); - } - int count = commandManager.getCmdFreqTable().containsKey(commandName) - ? commandManager.getCmdFreqTable().get(commandName) : 0; - commandManager.getCmdFreqTable().put(commandName, count + 1); - + runCommandFrequencyLogic(commandManager); ArrayList list = tasks.getTaskList(); cmdFreqStorage.save(commandManager.getCmdFreqTable()); ui.listAllTasks(list); diff --git a/src/main/java/duke/command/UpdatePatientCommand.java b/src/main/java/duke/command/UpdatePatientCommand.java index 18ae317181..19b08efc34 100644 --- a/src/main/java/duke/command/UpdatePatientCommand.java +++ b/src/main/java/duke/command/UpdatePatientCommand.java @@ -15,7 +15,6 @@ public class UpdatePatientCommand extends Command { private String command; - private boolean hasBeenAddedBefore = false; /** * . @@ -43,15 +42,7 @@ public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManag Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage, CmdFreqStorage cmdFreqStorage, CommandManager commandManager) throws DukeException { - - this.hasBeenAddedBefore = true; - String commandName = this.getClass().getSimpleName(); - if (!hasBeenAddedBefore) { - commandManager.getCmdFreqTable().put(commandName, 1); - } - int count = commandManager.getCmdFreqTable().containsKey(commandName) - ? commandManager.getCmdFreqTable().get(commandName) : 0; - commandManager.getCmdFreqTable().put(commandName, count + 1); + runCommandFrequencyLogic(commandManager); String[] tempCommand = command.split(" ", 3); char firstChar = tempCommand[0].charAt(0); if (firstChar == '#') { diff --git a/src/main/java/duke/command/UpdateTaskCommand.java b/src/main/java/duke/command/UpdateTaskCommand.java index e06d91bc2e..afcf5b8ba2 100644 --- a/src/main/java/duke/command/UpdateTaskCommand.java +++ b/src/main/java/duke/command/UpdateTaskCommand.java @@ -14,7 +14,6 @@ public class UpdateTaskCommand extends Command { private String command; - private boolean hasBeenAddedBefore = false; /** * . @@ -42,15 +41,7 @@ public void execute(PatientTaskList patientTask, TaskManager taskManager, Patien Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage, CmdFreqStorage cmdFreqStorage, CommandManager commandManager) throws DukeException { - this.hasBeenAddedBefore = true; - String commandName = this.getClass().getSimpleName(); - if (!hasBeenAddedBefore) { - commandManager.getCmdFreqTable().put(commandName, 1); - } - int count = commandManager.getCmdFreqTable().containsKey(commandName) - ? commandManager.getCmdFreqTable().get(commandName) : 0; - commandManager.getCmdFreqTable().put(commandName, count + 1); - + runCommandFrequencyLogic(commandManager); String[] tempCommand = command.split(" ", 3); char firstChar = tempCommand[0].charAt(0); if (firstChar == '#') { From 3550a708cbe7defff4cb6cca03873cee19a3d6da Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Sat, 19 Oct 2019 16:31:36 +0800 Subject: [PATCH 166/420] Update .gitignore to ignore all build reports and unrelated setting files. --- .gitignore | 15 +- build/reports/checkstyle/main.html | 958 ----------------------------- build/reports/checkstyle/main.xml | 258 -------- 3 files changed, 2 insertions(+), 1229 deletions(-) delete mode 100644 build/reports/checkstyle/main.html delete mode 100644 build/reports/checkstyle/main.xml diff --git a/.gitignore b/.gitignore index c7f8c8e183..d98d253775 100644 --- a/.gitignore +++ b/.gitignore @@ -5,35 +5,24 @@ # Gradle build files /.gradle/ -/build/classes -/build/generated -/build/tmp -src/main/resources/docs/ +/build/reports # MacOS custom attributes files created by Finder .DS_Store *.iml bin/ -data/duke.txt build/test-results/test/binary/results.bin build/test-results/test/binary/output.bin.idx build/test-results/test/binary/output.bin -build/test-results/test/TEST-duke.task.PeriodTaskTest.xml build/scriptsShadow/duke.bat build/scriptsShadow/duke build/scripts/duke.bat build/scripts/duke -build/reports/tests/test/packages/duke.task.html build/distributions/duke-0.1.0.tar build/distributions/duke-shadow-0.1.0.tar build/distributions/duke-0.1.0.zip -build/reports/tests/test/classes/duke.task.PeriodTaskTest.html build/libs/duke-0.1.0.jar -build/reports/tests/test/index.html -build/reports/tests/test/css/base-style.css build/distributions/duke-shadow-0.1.0.zip build/libs/mid-v1.1.jar -build/reports/tests/test/css/style.css -build/reports/tests/test/js/report.js /data/testData/ -src/test/java/duke/storage/PatientStorageTest.java +/build/reports/ diff --git a/build/reports/checkstyle/main.html b/build/reports/checkstyle/main.html deleted file mode 100644 index 9410402449..0000000000 --- a/build/reports/checkstyle/main.html +++ /dev/null @@ -1,958 +0,0 @@ - - - - - - - - - - - - - - -
-

CheckStyle Audit

-
Designed for use with CheckStyle and Ant.
-
-

Summary

- - - - - - - -
FilesErrors
26203
-
-

Files

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameErrors
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\Parser.java94
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\Task.java15
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\AddCommand.java13
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\DateTimeParser.java11
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\RescheduleCommand.java10
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\Ui.java7
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\RecurringCommand.java6
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\Storage.java6
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\Duke.java5
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\FixedDurationTask.java4
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\PeriodTask.java4
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\RemindCommand.java3
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\ViewCommand.java3
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\Deadline.java3
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\Event.java3
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\Todo.java3
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\Reminder.java2
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\DeleteCommand.java2
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\DoneCommand.java2
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\ExitCommand.java2
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\FindCommand.java2
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\ListCommand.java2
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\Command.java1
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\FindFreeTimesCommand.java0
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\DukeException.java0
C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\TaskList.java0
-
- -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\Duke.java

- - - - - - - - - - - - - - - - - - - -
Error DescriptionLine
Using the '.*' form of import should be avoided - duke.core.*.5
WhitespaceAround: '{' is not preceded with whitespace.11
'CTOR_DEF' should be separated from previous statement.32
First sentence of Javadoc is missing an ending period.65
'METHOD_DEF' should be separated from previous statement.71
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\Reminder.java

- - - - - - - - - - -
Error DescriptionLine
'CTOR_DEF' should be separated from previous statement.38
'{' at column 21 should be on the previous line.54
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\AddCommand.java

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Error DescriptionLine
First sentence of Javadoc is missing an ending period.24
First sentence of Javadoc is missing an ending period.40
Line continuation have incorrect indentation level, expected level should be 4.44
Line is longer than 120 characters (found 129).67
')' is preceded with whitespace.67
WhitespaceAround: '{' is not preceded with whitespace.67
',' is preceded with whitespace.75
';' is preceded with whitespace.77
')' is preceded with whitespace.81
WhitespaceAround: '}' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)94
WhitespaceAround: 'else' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)94
WhitespaceAround: 'else' is not preceded with whitespace.94
WhitespaceAround: '{' is not preceded with whitespace.94
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\Command.java

- - - - - - - -
Error DescriptionLine
Line continuation have incorrect indentation level, expected level should be 4.30
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\DeleteCommand.java

- - - - - - - - - - -
Error DescriptionLine
First sentence of Javadoc is missing an ending period.31
Line continuation have incorrect indentation level, expected level should be 4.35
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\DoneCommand.java

- - - - - - - - - - -
Error DescriptionLine
First sentence of Javadoc is missing an ending period.30
Line continuation have incorrect indentation level, expected level should be 4.34
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\ExitCommand.java

- - - - - - - - - - -
Error DescriptionLine
First sentence of Javadoc is missing an ending period.20
Line continuation have incorrect indentation level, expected level should be 4.24
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\FindCommand.java

- - - - - - - - - - -
Error DescriptionLine
First sentence of Javadoc is missing an ending period.29
Line continuation have incorrect indentation level, expected level should be 4.33
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\FindFreeTimesCommand.java

- - - - -
Error DescriptionLine
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\ListCommand.java

- - - - - - - - - - -
Error DescriptionLine
First sentence of Javadoc is missing an ending period.21
Line continuation have incorrect indentation level, expected level should be 4.25
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\RecurringCommand.java

- - - - - - - - - - - - - - - - - - - - - - -
Error DescriptionLine
Using the '.*' form of import should be avoided - duke.task.*.7
First sentence of Javadoc is missing an ending period.23
Line continuation have incorrect indentation level, expected level should be 4.27
'{' at column 29 should have line break after.30
'}' at column 45 should be alone on a line.30
Empty line should be followed by <p> tag on the next line.34
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\RemindCommand.java

- - - - - - - - - - - - - -
Error DescriptionLine
'CTOR_DEF' should be separated from previous statement.21
First sentence of Javadoc is missing an ending period.26
Line continuation have incorrect indentation level, expected level should be 4.30
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\RescheduleCommand.java

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Error DescriptionLine
Line is longer than 120 characters (found 127).23
WhitespaceAround: 'try' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)40
WhitespaceAround: '{' is not preceded with whitespace.40
WhitespaceAround: '{' is not preceded with whitespace.42
WhitespaceAround: '}' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)48
WhitespaceAround: 'catch' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)48
WhitespaceAround: 'catch' is not preceded with whitespace.48
WhitespaceAround: '{' is not preceded with whitespace.48
First sentence of Javadoc is missing an ending period.53
Line continuation have incorrect indentation level, expected level should be 4.57
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\command\ViewCommand.java

- - - - - - - - - - - - - -
Error DescriptionLine
'(' is preceded with whitespace.16
First sentence of Javadoc is missing an ending period.23
Line continuation have incorrect indentation level, expected level should be 4.27
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\DateTimeParser.java

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Error DescriptionLine
Javadoc comment at column 19 has parse error. Missed HTML close tag 'code'. Sometimes it means that close tag missed for one of previous tags.9
Line is longer than 120 characters (found 128).33
Line is longer than 120 characters (found 128).34
Line is longer than 120 characters (found 128).35
Line is longer than 120 characters (found 128).36
WhitespaceAround: 'try' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)38
WhitespaceAround: '{' is not preceded with whitespace.38
WhitespaceAround: '}' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)50
WhitespaceAround: 'catch' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)50
WhitespaceAround: 'catch' is not preceded with whitespace.50
WhitespaceAround: '{' is not preceded with whitespace.50
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\DukeException.java

- - - - -
Error DescriptionLine
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\Parser.java

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Error DescriptionLine
Using the '.*' form of import should be avoided - duke.command.*.3
Using the '.*' form of import should be avoided - duke.task.*.4
'case' child has incorrect indentation level 12, expected level should be 8.28
'block' child has incorrect indentation level 16, expected level should be 12.29
'case' child has incorrect indentation level 12, expected level should be 8.30
'try' has incorrect indentation level 16, expected level should be 12.31
'try' child has incorrect indentation level 20, expected level should be 16.32
'try' child has incorrect indentation level 20, expected level should be 16.33
'try rcurly' has incorrect indentation level 16, expected level should be 12.34
'catch' child has incorrect indentation level 20, expected level should be 16.35
'catch rcurly' has incorrect indentation level 16, expected level should be 12.36
'case' child has incorrect indentation level 12, expected level should be 8.37
'try' has incorrect indentation level 16, expected level should be 12.38
'try' child has incorrect indentation level 20, expected level should be 16.39
'try' child has incorrect indentation level 20, expected level should be 16.40
'try rcurly' has incorrect indentation level 16, expected level should be 12.41
'catch' child has incorrect indentation level 20, expected level should be 16.42
'catch rcurly' has incorrect indentation level 16, expected level should be 12.43
'case' child has incorrect indentation level 12, expected level should be 8.44
'try' has incorrect indentation level 16, expected level should be 12.45
'try' child has incorrect indentation level 20, expected level should be 16.46
'try' child has incorrect indentation level 20, expected level should be 16.47
'try rcurly' has incorrect indentation level 16, expected level should be 12.48
'catch' child has incorrect indentation level 20, expected level should be 16.49
'catch rcurly' has incorrect indentation level 16, expected level should be 12.50
'case' child has incorrect indentation level 12, expected level should be 8.51
'try' has incorrect indentation level 16, expected level should be 12.52
'try' child has incorrect indentation level 20, expected level should be 16.53
'try' child has incorrect indentation level 20, expected level should be 16.54
'try' child has incorrect indentation level 20, expected level should be 16.55
'try rcurly' has incorrect indentation level 16, expected level should be 12.56
'}' at column 17 should be on the same line as the next part of a multi-block statement (one that directly contains multiple blocks: if/else-if/else, do/while or try/catch/finally).56
'catch' has incorrect indentation level 17, expected level should be 12.57
'catch' child has incorrect indentation level 20, expected level should be 16.58
'catch rcurly' has incorrect indentation level 17, expected level should be 12.59
'case' child has incorrect indentation level 12, expected level should be 8.60
'try' has incorrect indentation level 16, expected level should be 12.61
'try' child has incorrect indentation level 20, expected level should be 16.62
'try' child has incorrect indentation level 20, expected level should be 16.63
'try' child has incorrect indentation level 20, expected level should be 16.64
'try rcurly' has incorrect indentation level 16, expected level should be 12.65
'catch' child has incorrect indentation level 20, expected level should be 16.66
'catch rcurly' has incorrect indentation level 16, expected level should be 12.67
'case' child has incorrect indentation level 12, expected level should be 8.68
'try' has incorrect indentation level 16, expected level should be 12.69
'try' child has incorrect indentation level 20, expected level should be 16.70
'try' child has incorrect indentation level 20, expected level should be 16.71
'try' child has incorrect indentation level 20, expected level should be 16.72
'try rcurly' has incorrect indentation level 16, expected level should be 12.73
'catch' child has incorrect indentation level 20, expected level should be 16.74
'catch rcurly' has incorrect indentation level 16, expected level should be 12.75
'case' child has incorrect indentation level 12, expected level should be 8.76
'try' has incorrect indentation level 16, expected level should be 12.77
'try' child has incorrect indentation level 20, expected level should be 16.78
'try' child has incorrect indentation level 20, expected level should be 16.79
'try' child has incorrect indentation level 20, expected level should be 16.80
'try' child has incorrect indentation level 20, expected level should be 16.81
'try rcurly' has incorrect indentation level 16, expected level should be 12.82
WhitespaceAround: '}' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)82
WhitespaceAround: 'catch' is not preceded with whitespace.82
'catch' child has incorrect indentation level 20, expected level should be 16.83
Line is longer than 120 characters (found 181).83
'catch rcurly' has incorrect indentation level 16, expected level should be 12.85
'case' child has incorrect indentation level 12, expected level should be 8.86
'block' child has incorrect indentation level 16, expected level should be 12.87
'case' child has incorrect indentation level 12, expected level should be 8.88
'try' has incorrect indentation level 16, expected level should be 12.89
'try' child has incorrect indentation level 20, expected level should be 16.90
'try' child has incorrect indentation level 20, expected level should be 16.91
'try rcurly' has incorrect indentation level 16, expected level should be 12.92
'catch' child has incorrect indentation level 20, expected level should be 16.93
Line is longer than 120 characters (found 156).93
'catch rcurly' has incorrect indentation level 16, expected level should be 12.94
'case' child has incorrect indentation level 12, expected level should be 8.95
'try' has incorrect indentation level 16, expected level should be 12.96
'try' child has incorrect indentation level 20, expected level should be 16.97
'try' child has incorrect indentation level 20, expected level should be 16.98
'try' child has incorrect indentation level 20, expected level should be 16.99
'try' child has incorrect indentation level 20, expected level should be 16.100
'try rcurly' has incorrect indentation level 16, expected level should be 12.102
'catch' child has incorrect indentation level 20, expected level should be 16.103
'catch rcurly' has incorrect indentation level 16, expected level should be 12.104
'case' child has incorrect indentation level 12, expected level should be 8.105
Fall through from previous branch of the switch statement.105
'try' has incorrect indentation level 16, expected level should be 12.106
'try' child has incorrect indentation level 20, expected level should be 16.107
'try' child has incorrect indentation level 20, expected level should be 16.108
'try rcurly' has incorrect indentation level 16, expected level should be 12.109
'catch' child has incorrect indentation level 20, expected level should be 16.110
'catch rcurly' has incorrect indentation level 16, expected level should be 12.111
'case' child has incorrect indentation level 12, expected level should be 8.112
'block' child has incorrect indentation level 16, expected level should be 12.113
'case' child has incorrect indentation level 12, expected level should be 8.114
'block' child has incorrect indentation level 16, expected level should be 12.115
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\Storage.java

- - - - - - - - - - - - - - - - - - - - - - -
Error DescriptionLine
Using the '.*' form of import should be avoided - duke.task.*.3
'}' at column 17 should be on the same line as the next part of a multi-block statement (one that directly contains multiple blocks: if/else-if/else, do/while or try/catch/finally).54
'}' at column 17 should be on the same line as the next part of a multi-block statement (one that directly contains multiple blocks: if/else-if/else, do/while or try/catch/finally).64
'}' at column 17 should be on the same line as the next part of a multi-block statement (one that directly contains multiple blocks: if/else-if/else, do/while or try/catch/finally).74
WhitespaceAround: '}' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)82
WhitespaceAround: 'else' is not preceded with whitespace.82
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\TaskList.java

- - - - -
Error DescriptionLine
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\core\Ui.java

- - - - - - - - - - - - - - - - - - - - - - - - - -
Error DescriptionLine
First sentence of Javadoc is missing an ending period.10
Unused Javadoc tag.104
'(' is preceded with whitespace.106
Comment has incorrect indentation level 0, expected is 8, indentation should be the same level as line 114.116
'(' is preceded with whitespace.141
',' is preceded with whitespace.141
Missing a Javadoc comment.159
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\Deadline.java

- - - - - - - - - - - - - -
Error DescriptionLine
First sentence of Javadoc is missing an ending period.34
Line continuation have incorrect indentation level, expected level should be 4.38
First sentence of Javadoc is missing an ending period.45
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\Event.java

- - - - - - - - - - - - - -
Error DescriptionLine
First sentence of Javadoc is missing an ending period.32
Line continuation have incorrect indentation level, expected level should be 4.36
First sentence of Javadoc is missing an ending period.43
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\FixedDurationTask.java

- - - - - - - - - - - - - - - - -
Error DescriptionLine
First sentence of Javadoc is missing an ending period.4
Summary javadoc is missing.21
Line continuation have incorrect indentation level, expected level should be 4.24
First sentence of Javadoc is missing an ending period.31
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\PeriodTask.java

- - - - - - - - - - - - - - - - -
Error DescriptionLine
Unused @param tag for 'startTime'.26
First sentence of Javadoc is missing an ending period.37
Line continuation have incorrect indentation level, expected level should be 4.41
First sentence of Javadoc is missing an ending period.50
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\Task.java

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Error DescriptionLine
First sentence of Javadoc is missing an ending period.25
First sentence of Javadoc is missing an ending period.29
First sentence of Javadoc is missing an ending period.57
First sentence of Javadoc is missing an ending period.66
'{' at column 37 should have line break after.83
'}' at column 59 should be alone on a line.83
'{' at column 38 should have line break after.88
'}' at column 60 should be alone on a line.88
')' is preceded with whitespace.100
'{' at column 43 should have line break after.103
Line continuation have incorrect indentation level, expected level should be 4.125
Comment has incorrect indentation level 0, expected is 4, indentation should be the same level as line 164.158
Javadoc comment at column 19 has parse error. Missed HTML close tag 'code'. Sometimes it means that close tag missed for one of previous tags.161
'{' at column 5 should be on the previous line.174
'{' at column 37 should have line break after.175
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\main\java\duke\task\Todo.java

- - - - - - - - - - - - - -
Error DescriptionLine
First sentence of Javadoc is missing an ending period.18
Line continuation have incorrect indentation level, expected level should be 4.22
First sentence of Javadoc is missing an ending period.29
- Back to top -
- - diff --git a/build/reports/checkstyle/main.xml b/build/reports/checkstyle/main.xml deleted file mode 100644 index 777ddd1884..0000000000 --- a/build/reports/checkstyle/main.xml +++ /dev/null @@ -1,258 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 3842fb95d75097259cbb7b42d86a63e49c727e78 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Sat, 19 Oct 2019 16:38:47 +0800 Subject: [PATCH 167/420] Update .gitignore to ignore all reports and unrelated build files --- .gitignore | 3 +- build/reports/checkstyle/test.html | 298 ----------------------------- build/reports/checkstyle/test.xml | 66 ------- 3 files changed, 1 insertion(+), 366 deletions(-) delete mode 100644 build/reports/checkstyle/test.html delete mode 100644 build/reports/checkstyle/test.xml diff --git a/.gitignore b/.gitignore index d98d253775..9adda9c8d9 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,7 @@ # Gradle build files /.gradle/ -/build/reports +/build # MacOS custom attributes files created by Finder .DS_Store @@ -25,4 +25,3 @@ build/libs/duke-0.1.0.jar build/distributions/duke-shadow-0.1.0.zip build/libs/mid-v1.1.jar /data/testData/ -/build/reports/ diff --git a/build/reports/checkstyle/test.html b/build/reports/checkstyle/test.html deleted file mode 100644 index 10e2dd1b81..0000000000 --- a/build/reports/checkstyle/test.html +++ /dev/null @@ -1,298 +0,0 @@ - - - - - - - - - - - - - - -
-

CheckStyle Audit

-
Designed for use with CheckStyle and Ant.
-
-

Summary

- - - - - - - -
FilesErrors
553
-
-

Files

- - - - - - - - - - - - - - - - - - - -
NameErrors
C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\task\DeadlineTest.java15
C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\task\EventTest.java15
C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\task\TodoTest.java10
C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\core\ParserTest.java7
C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\task\PeriodTaskTest.java6
-
- -

File C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\core\ParserTest.java

- - - - - - - - - - - - - - - - - - - - - - - - - -
Error DescriptionLine
Using the '.*' form of import should be avoided - duke.command.*.3
Distance between variable 'c4' declaration and its first usage is 4, but allowed 3. Consider making that variable final if you still need to store its value in advance (before method calls that might have side effects on the original value).18
Distance between variable 'c5' declaration and its first usage is 5, but allowed 3. Consider making that variable final if you still need to store its value in advance (before method calls that might have side effects on the original value).19
Distance between variable 'c6' declaration and its first usage is 6, but allowed 3. Consider making that variable final if you still need to store its value in advance (before method calls that might have side effects on the original value).20
Distance between variable 'c7' declaration and its first usage is 7, but allowed 3. Consider making that variable final if you still need to store its value in advance (before method calls that might have side effects on the original value).21
Distance between variable 'c8' declaration and its first usage is 8, but allowed 3. Consider making that variable final if you still need to store its value in advance (before method calls that might have side effects on the original value).22
Distance between variable 'c9' declaration and its first usage is 9, but allowed 3. Consider making that variable final if you still need to store its value in advance (before method calls that might have side effects on the original value).23
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\task\DeadlineTest.java

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Error DescriptionLine
Using the '.*' form of import should be avoided - org.junit.jupiter.api.Assertions.*.6
Line is longer than 120 characters (found 163).16
Unicode escape(s) usage should be avoided.16
'(' is followed by whitespace.16
Line is longer than 120 characters (found 173).24
'(' is followed by whitespace.24
Line is longer than 120 characters (found 145).50
Unicode escape(s) usage should be avoided.50
'(' is followed by whitespace.50
Line is longer than 120 characters (found 134).51
'(' is followed by whitespace.51
Line is longer than 120 characters (found 146).56
Unicode escape(s) usage should be avoided.56
Line is longer than 120 characters (found 126).57
'(' is followed by whitespace.57
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\task\EventTest.java

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Error DescriptionLine
Using the '.*' form of import should be avoided - org.junit.jupiter.api.Assertions.*.7
Method name 'EventStringTest' must match pattern '^[a-z][a-z0-9][a-zA-Z0-9_]*$'.15
Line is longer than 120 characters (found 168).16
Unicode escape(s) usage should be avoided.16
Line is longer than 120 characters (found 154).24
'(' is followed by whitespace.24
Line is longer than 120 characters (found 139).50
Unicode escape(s) usage should be avoided.50
'(' is followed by whitespace.50
Line is longer than 120 characters (found 128).51
'(' is followed by whitespace.51
Line is longer than 120 characters (found 137).56
Unicode escape(s) usage should be avoided.56
Line is longer than 120 characters (found 128).57
'(' is followed by whitespace.57
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\task\PeriodTaskTest.java

- - - - - - - - - - - - - - - - - - - - - - -
Error DescriptionLine
Using the '.*' form of import should be avoided - org.junit.jupiter.api.Assertions.*.6
Method name 'PeriodTaskStringTest' must match pattern '^[a-z][a-z0-9][a-zA-Z0-9_]*$'.14
Line is longer than 120 characters (found 229).15
Unicode escape(s) usage should be avoided.15
Line is longer than 120 characters (found 208).23
'(' is followed by whitespace.23
- Back to top -

File C:\Users\acer\Desktop\personalMainDuke\src\test\java\duke\task\TodoTest.java

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Error DescriptionLine
Using the '.*' form of import should be avoided - org.junit.jupiter.api.Assertions.*.6
WhitespaceAround: '{' is not preceded with whitespace.15
Unicode escape(s) usage should be avoided.16
Line is longer than 120 characters (found 124).24
'(' is followed by whitespace.24
Unicode escape(s) usage should be avoided.50
'(' is followed by whitespace.50
'(' is followed by whitespace.51
Unicode escape(s) usage should be avoided.56
'(' is followed by whitespace.57
- Back to top -
- - diff --git a/build/reports/checkstyle/test.xml b/build/reports/checkstyle/test.xml deleted file mode 100644 index ebc36f73b5..0000000000 --- a/build/reports/checkstyle/test.xml +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From e81214c4543ab6511ae85e8f8dbc5e6e4b13b2b6 Mon Sep 17 00:00:00 2001 From: Qian Jie Date: Sat, 19 Oct 2019 17:15:33 +0800 Subject: [PATCH 168/420] Introduce a new statistic package that should contain things related getting specify countable data etc , refactor command counter logic to class CommandCounter under statistic package. --- build/reports/checkstyle/main.html | 26 +++++++++---- build/reports/checkstyle/main.xml | 4 +- data/cmdfrequency.csv | 3 -- data/counter.csv | 6 +++ data/patients.csv | 11 +----- data/standardTasks.csv | 39 +------------------ src/main/java/duke/Duke.java | 15 +++---- .../java/duke/command/AddPatientCommand.java | 13 ++++--- .../duke/command/AddStandardTaskCommand.java | 13 ++++--- .../command/AssignTaskToPatientCommand.java | 13 ++++--- src/main/java/duke/command/Command.java | 23 +++-------- .../duke/command/DeletePatientCommand.java | 15 ++++--- .../java/duke/command/DeleteTaskCommand.java | 15 ++++--- src/main/java/duke/command/ExitCommand.java | 7 ++-- .../java/duke/command/FindPatientCommand.java | 15 ++++--- .../duke/command/FindPatientTaskCommand.java | 15 ++++--- .../duke/command/ListPatientsCommand.java | 13 ++++--- .../java/duke/command/ListTasksCommand.java | 13 ++++--- .../duke/command/UpdatePatientCommand.java | 13 ++++--- .../java/duke/command/UpdateTaskCommand.java | 13 ++++--- src/main/java/duke/core/CommandManager.java | 17 +------- .../java/duke/statistic/CommandCounter.java | 34 ++++++++++++++++ ...mdFreqStorage.java => CounterStorage.java} | 12 +++++- 23 files changed, 185 insertions(+), 163 deletions(-) delete mode 100644 data/cmdfrequency.csv create mode 100644 data/counter.csv create mode 100644 src/main/java/duke/statistic/CommandCounter.java rename src/main/java/duke/storage/{CmdFreqStorage.java => CounterStorage.java} (92%) diff --git a/build/reports/checkstyle/main.html b/build/reports/checkstyle/main.html index 1ec4310163..96927409b3 100644 --- a/build/reports/checkstyle/main.html +++ b/build/reports/checkstyle/main.html @@ -72,7 +72,7 @@

Summary

FilesErrors - 320 + 330
@@ -160,21 +160,24 @@

Files

/Users/qianjie/Desktop/main/src/main/java/duke/relation/StandardPatientTask.java0 - /Users/qianjie/Desktop/main/src/main/java/duke/storage/CmdFreqStorage.java0 + /Users/qianjie/Desktop/main/src/main/java/duke/statistic/CommandCounter.java0 - /Users/qianjie/Desktop/main/src/main/java/duke/storage/PatientStorage.java0 + /Users/qianjie/Desktop/main/src/main/java/duke/storage/CounterStorage.java0 - /Users/qianjie/Desktop/main/src/main/java/duke/storage/PatientTaskStorage.java0 + /Users/qianjie/Desktop/main/src/main/java/duke/storage/PatientStorage.java0 - /Users/qianjie/Desktop/main/src/main/java/duke/storage/TaskStorage.java0 + /Users/qianjie/Desktop/main/src/main/java/duke/storage/PatientTaskStorage.java0 - /Users/qianjie/Desktop/main/src/main/java/duke/task/Task.java0 + /Users/qianjie/Desktop/main/src/main/java/duke/storage/TaskStorage.java0 + /Users/qianjie/Desktop/main/src/main/java/duke/task/Task.java0 + + /Users/qianjie/Desktop/main/src/main/java/duke/task/TaskManager.java0 @@ -361,8 +364,15 @@

File /Users/qianjie/Desktop/main/src/main/java/duke/relation/StandardPatient Error DescriptionLine - Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/storage/CmdFreqStorage.java

+ Back to top +

File /Users/qianjie/Desktop/main/src/main/java/duke/statistic/CommandCounter.java

+ + + + +
Error DescriptionLine
+ Back to top +

File /Users/qianjie/Desktop/main/src/main/java/duke/storage/CounterStorage.java

diff --git a/build/reports/checkstyle/main.xml b/build/reports/checkstyle/main.xml index 4e8ed03beb..9c549b5eb6 100644 --- a/build/reports/checkstyle/main.xml +++ b/build/reports/checkstyle/main.xml @@ -52,7 +52,9 @@ - + + + diff --git a/data/cmdfrequency.csv b/data/cmdfrequency.csv deleted file mode 100644 index 2cc6e49f95..0000000000 --- a/data/cmdfrequency.csv +++ /dev/null @@ -1,3 +0,0 @@ -Command Name,Frequency -DeleteTaskCommand,1 -AddStandardTaskCommand,1 diff --git a/data/counter.csv b/data/counter.csv new file mode 100644 index 0000000000..d81c3652e5 --- /dev/null +++ b/data/counter.csv @@ -0,0 +1,6 @@ +Command Name,Frequency +DeleteTaskCommand,2 +FindPatientCommand,2 +DeletePatientCommand,1 +AddStandardTaskCommand,1 +AddPatientCommand,2 diff --git a/data/patients.csv b/data/patients.csv index a84af3189d..6b1bd23e42 100644 --- a/data/patients.csv +++ b/data/patients.csv @@ -1,10 +1,3 @@ Id,Name,NRIC,Room,Remark -16,momo,s123123,a9,nil -1,xk,G00012345,38A,no -2,weifeng,G789456,8B,no -3,jiejie,G123456,2c,no -11,qianjie,1231312321,A5,NIL -12,qianjie,S92139123,A04,NIL -13,qianjie,s31231231,a09,NIL -14,qianjie,s123123,a99,nil -15,qianjie,s1231231,a90,nil +2,qianqian,s12312,a9,asd +3,qianjie,s12323,sd,123 diff --git a/data/standardTasks.csv b/data/standardTasks.csv index bf7d52e7ba..1e19fb2a1a 100644 --- a/data/standardTasks.csv +++ b/data/standardTasks.csv @@ -1,38 +1,3 @@ Id,Description -1,Take Medicine A -2,Do surgery -3,Take shit -6,fkkk -7,123 -8,123 -9,321 -11,123 -12,0931 -13,1231231 -14,3333 -15,12351 -16,123123 -17,3321 -18,333 -19,5555 -20,1 -21,2 -22,1 -23,2 -24,123 -25,1 -26,5 -27,2 -28,123 -29,2 -30,5 -31,6 -32,100 -33,100 -34,3 -35,5 -36,123 -37,4 -38,wqeqw -39,123 -40,123 +1,123 +3,123 diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index 787331ee1e..39efc74b0d 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -4,7 +4,8 @@ import duke.core.DukeException; import duke.core.CommandManager; import duke.patient.PatientManager; -import duke.storage.CmdFreqStorage; +import duke.statistic.CommandCounter; +import duke.storage.CounterStorage; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; import duke.storage.TaskStorage; @@ -24,7 +25,7 @@ public class Duke { private TaskStorage taskStorage; private PatientStorage patientStorage; private PatientTaskStorage patientTaskStorage; - private CmdFreqStorage cmdFreqStorage; + private CounterStorage counterStorage; /** * A TaskList object that deals with add, delete, mark as done, * find functions of a list of tasks. @@ -32,7 +33,7 @@ public class Duke { private PatientTaskList patientTaskList; private TaskManager taskManager; private PatientManager patientManager; - private CommandManager commandManager; + private CommandCounter commandCounter; /** * A Ui object that deals with interactions with the user. @@ -50,13 +51,13 @@ public Duke(String filePath) { taskStorage = new TaskStorage(filePath + "/standardTasks.csv"); patientStorage = new PatientStorage(filePath + "/patients.csv"); patientTaskStorage = new PatientTaskStorage(filePath + "/patientsTasks.csv"); - cmdFreqStorage = new CmdFreqStorage(filePath + "/cmdfrequency.csv"); + counterStorage = new CounterStorage(filePath + "/counter.csv"); try { patientTaskList = new PatientTaskList(patientTaskStorage.load()); taskManager = new TaskManager(taskStorage.load()); patientManager = new PatientManager(patientStorage.load()); - commandManager = new CommandManager(cmdFreqStorage.load()); + commandCounter = new CommandCounter(counterStorage.load()); } catch (DukeException e) { ui.showLoadingError(); @@ -76,9 +77,9 @@ public void run() { try { String fullCommand = ui.readCommand(); ui.showLine(); - Command c = commandManager.manageCommand(fullCommand); + Command c = CommandManager.manageCommand(fullCommand); c.execute(patientTaskList, taskManager, patientManager, - ui, patientTaskStorage, taskStorage, patientStorage, cmdFreqStorage, commandManager); + ui, patientTaskStorage, taskStorage, patientStorage, counterStorage, commandCounter); isExit = c.isExit(); } catch (DukeException e) { ui.showError(e.getMessage()); diff --git a/src/main/java/duke/command/AddPatientCommand.java b/src/main/java/duke/command/AddPatientCommand.java index 07800ea505..8267a9b8df 100644 --- a/src/main/java/duke/command/AddPatientCommand.java +++ b/src/main/java/duke/command/AddPatientCommand.java @@ -5,7 +5,8 @@ import duke.core.Ui; import duke.patient.Patient; import duke.patient.PatientManager; -import duke.storage.CmdFreqStorage; +import duke.statistic.CommandCounter; +import duke.storage.CounterStorage; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; import duke.storage.TaskStorage; @@ -35,13 +36,15 @@ public AddPatientCommand(String[] patientInfo) throws DukeException { @Override public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, - PatientStorage patientStorage, CmdFreqStorage cmdFreqStorage, - CommandManager commandManager) throws DukeException { + PatientStorage patientStorage, CounterStorage counterStorage, + CommandCounter commandCounter) throws DukeException { - runCommandFrequencyLogic(commandManager); + this.hasBeenAddedBefore = true; + String commandName = this.getClass().getSimpleName(); + commandCounter.runCommandCounter(this.hasBeenAddedBefore, commandCounter.getCommandTable(), commandName); patientList.addPatient(newPatient); patientStorage.save(patientList.getPatientList()); - cmdFreqStorage.save(commandManager.getCmdFreqTable()); + counterStorage.save(commandCounter.getCommandTable()); ui.patientAdded(newPatient); } diff --git a/src/main/java/duke/command/AddStandardTaskCommand.java b/src/main/java/duke/command/AddStandardTaskCommand.java index 4dbe8c3e3c..5f020746a9 100644 --- a/src/main/java/duke/command/AddStandardTaskCommand.java +++ b/src/main/java/duke/command/AddStandardTaskCommand.java @@ -4,7 +4,8 @@ import duke.core.DukeException; import duke.core.Ui; import duke.patient.PatientManager; -import duke.storage.CmdFreqStorage; +import duke.statistic.CommandCounter; +import duke.storage.CounterStorage; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; import duke.storage.TaskStorage; @@ -41,12 +42,14 @@ public AddStandardTaskCommand(String taskDescription) { @Override public void execute(PatientTaskList patientTask, TaskManager taskList, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, - PatientStorage patientStorage, CmdFreqStorage cmdFreqStorage, - CommandManager commandManager) throws DukeException { - runCommandFrequencyLogic(commandManager); + PatientStorage patientStorage, CounterStorage counterStorage, + CommandCounter commandCounter) throws DukeException { + this.hasBeenAddedBefore = true; + String commandName = this.getClass().getSimpleName(); + commandCounter.runCommandCounter(this.hasBeenAddedBefore, commandCounter.getCommandTable(), commandName); taskList.addTask(newStandardTask); taskStorage.save(taskList.getTaskList()); - cmdFreqStorage.save(commandManager.getCmdFreqTable()); + counterStorage.save(commandCounter.getCommandTable()); ui.taskAdded(newStandardTask); } diff --git a/src/main/java/duke/command/AssignTaskToPatientCommand.java b/src/main/java/duke/command/AssignTaskToPatientCommand.java index 0e56996341..6e24c0d09b 100644 --- a/src/main/java/duke/command/AssignTaskToPatientCommand.java +++ b/src/main/java/duke/command/AssignTaskToPatientCommand.java @@ -6,7 +6,8 @@ import duke.patient.PatientManager; import duke.relation.EventPatientTask; import duke.relation.StandardPatientTask; -import duke.storage.CmdFreqStorage; +import duke.statistic.CommandCounter; +import duke.storage.CounterStorage; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; import duke.storage.TaskStorage; @@ -47,14 +48,16 @@ public AssignTaskToPatientCommand(String[] taskAssignmentInfo) throws DukeExcept @Override public void execute(PatientTaskList patientTaskList, TaskManager tasksList, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, - PatientStorage patientStorage, CmdFreqStorage cmdFreqStorage, - CommandManager commandManager) throws DukeException { + PatientStorage patientStorage, CounterStorage counterStorage, + CommandCounter commandCounter) throws DukeException { if (patientList.isExist(newPatientTask.getPatientId()) && tasksList.doesExist(newPatientTask.getTaskID())) { - runCommandFrequencyLogic(commandManager); + this.hasBeenAddedBefore = true; + String commandName = this.getClass().getSimpleName(); + commandCounter.runCommandCounter(this.hasBeenAddedBefore, commandCounter.getCommandTable(), commandName); patientTaskList.addPatientTask(newPatientTask); patientTaskStorage.save(patientTaskList.fullPatientTaskList()); - cmdFreqStorage.save(commandManager.getCmdFreqTable()); + counterStorage.save(commandCounter.getCommandTable()); ui.patientTaskAssigned(newPatientTask, patientList.getPatient(newPatientTask.getPatientId()).getName(), tasksList.getTask(newPatientTask.getTaskID()).getDescription()); } else { diff --git a/src/main/java/duke/command/Command.java b/src/main/java/duke/command/Command.java index 7280cac85d..2fd1dd5bfc 100644 --- a/src/main/java/duke/command/Command.java +++ b/src/main/java/duke/command/Command.java @@ -5,7 +5,8 @@ import duke.core.Ui; import duke.patient.PatientManager; import duke.relation.PatientTaskList; -import duke.storage.CmdFreqStorage; +import duke.statistic.CommandCounter; +import duke.storage.CounterStorage; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; import duke.storage.TaskStorage; @@ -34,24 +35,10 @@ public abstract class Command { */ public abstract void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, - PatientStorage patientStorage, CmdFreqStorage cmdFreqStorage, - CommandManager commandManager) throws DukeException; - /** - * This function is used across all the child command for running of - * Command Frequency Logic. - * @param commandManager passing a CommandManager object to get the CmdFreqTable for use. - */ + PatientStorage patientStorage, CounterStorage counterStorage, + CommandCounter commandCounter) throws DukeException; + - public void runCommandFrequencyLogic(CommandManager commandManager) { - this.hasBeenAddedBefore = true; - String commandName = this.getClass().getSimpleName(); - if (!hasBeenAddedBefore) { - commandManager.getCmdFreqTable().put(commandName, 1); - } - int count = commandManager.getCmdFreqTable().containsKey(commandName) - ? commandManager.getCmdFreqTable().get(commandName) : 0; - commandManager.getCmdFreqTable().put(commandName, count + 1); - } /** * Decide whether duke should exist. diff --git a/src/main/java/duke/command/DeletePatientCommand.java b/src/main/java/duke/command/DeletePatientCommand.java index 7eb89bf363..3e62c4dc59 100644 --- a/src/main/java/duke/command/DeletePatientCommand.java +++ b/src/main/java/duke/command/DeletePatientCommand.java @@ -5,7 +5,8 @@ import duke.core.Ui; import duke.patient.Patient; import duke.patient.PatientManager; -import duke.storage.CmdFreqStorage; +import duke.statistic.CommandCounter; +import duke.storage.CounterStorage; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; import duke.storage.TaskStorage; @@ -53,10 +54,12 @@ public DeletePatientCommand(String deletedPatientInfo) throws DukeException { @Override public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientManager, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, - PatientStorage patientStorage, CmdFreqStorage cmdFreqStorage, - CommandManager commandManager) throws DukeException { + PatientStorage patientStorage, CounterStorage counterStorage, + CommandCounter commandCounter) throws DukeException { - runCommandFrequencyLogic(commandManager); + this.hasBeenAddedBefore = true; + String commandName = this.getClass().getSimpleName(); + commandCounter.runCommandCounter(this.hasBeenAddedBefore, commandCounter.getCommandTable(), commandName); if (id != 0) { Patient patientToBeDeleted = patientManager.getPatient(id); boolean toDelete = ui.confirmPatientToBeDeleted(patientToBeDeleted); @@ -64,7 +67,7 @@ public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManag patientManager.deletePatient(id); ui.patientDeleted(); patientStorage.save(patientManager.getPatientList()); - cmdFreqStorage.save(commandManager.getCmdFreqTable()); + counterStorage.save(commandCounter.getCommandTable()); } } else { ArrayList patientsWithSameName = patientManager.getPatientByName(deletedPatientInfo); @@ -77,7 +80,7 @@ public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManag patientManager.deletePatient(patientsWithSameName.get(numberChosen - 1).getID()); ui.patientDeleted(); patientStorage.save(patientManager.getPatientList()); - cmdFreqStorage.save(commandManager.getCmdFreqTable()); + counterStorage.save(commandCounter.getCommandTable()); } } } diff --git a/src/main/java/duke/command/DeleteTaskCommand.java b/src/main/java/duke/command/DeleteTaskCommand.java index 6d5732baff..c87104f95e 100644 --- a/src/main/java/duke/command/DeleteTaskCommand.java +++ b/src/main/java/duke/command/DeleteTaskCommand.java @@ -4,7 +4,8 @@ import duke.core.DukeException; import duke.core.Ui; import duke.patient.PatientManager; -import duke.storage.CmdFreqStorage; +import duke.statistic.CommandCounter; +import duke.storage.CounterStorage; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; import duke.storage.TaskStorage; @@ -52,9 +53,11 @@ public DeleteTaskCommand(String deletedTaskInfo) throws DukeException { @Override public void execute(PatientTaskList patientTask, TaskManager taskManager, PatientManager patientManager, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, - PatientStorage patientStorage, CmdFreqStorage cmdFreqStorage, - CommandManager commandManager) throws DukeException { - runCommandFrequencyLogic(commandManager); + PatientStorage patientStorage, CounterStorage counterStorage, + CommandCounter commandCounter) throws DukeException { + this.hasBeenAddedBefore = true; + String commandName = this.getClass().getSimpleName(); + commandCounter.runCommandCounter(this.hasBeenAddedBefore, commandCounter.getCommandTable(), commandName); if (id != 0) { Task taskToBeDeleted = taskManager.getTask(id); boolean toDelete = ui.confirmTaskToBeDeleted(taskToBeDeleted); @@ -62,7 +65,7 @@ public void execute(PatientTaskList patientTask, TaskManager taskManager, Patien taskManager.deleteTask(id); ui.taskDeleted(); taskStorage.save(taskManager.getTaskList()); - cmdFreqStorage.save(commandManager.getCmdFreqTable()); + counterStorage.save(commandCounter.getCommandTable()); } } else { ArrayList tasksWithSameDescription = taskManager.getTaskByDescription(deletedTaskInfo); @@ -75,7 +78,7 @@ public void execute(PatientTaskList patientTask, TaskManager taskManager, Patien taskManager.deleteTask(tasksWithSameDescription.get(numberChosen - 1).getID()); ui.taskDeleted(); taskStorage.save(taskManager.getTaskList()); - cmdFreqStorage.save(commandManager.getCmdFreqTable()); + counterStorage.save(commandCounter.getCommandTable()); } } } diff --git a/src/main/java/duke/command/ExitCommand.java b/src/main/java/duke/command/ExitCommand.java index ba0305b7e2..67510af88b 100644 --- a/src/main/java/duke/command/ExitCommand.java +++ b/src/main/java/duke/command/ExitCommand.java @@ -3,7 +3,8 @@ import duke.core.CommandManager; import duke.core.DukeException; import duke.patient.PatientManager; -import duke.storage.CmdFreqStorage; +import duke.statistic.CommandCounter; +import duke.storage.CounterStorage; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; import duke.relation.PatientTaskList; @@ -44,8 +45,8 @@ public boolean isExit() { */ public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, - TaskStorage taskStorage, PatientStorage patientStorage, CmdFreqStorage cmdFreqStorage, - CommandManager commandManager) throws DukeException { + TaskStorage taskStorage, PatientStorage patientStorage, CounterStorage counterStorage, + CommandCounter commandCounter) throws DukeException { ui.exitInformation(); } } \ No newline at end of file diff --git a/src/main/java/duke/command/FindPatientCommand.java b/src/main/java/duke/command/FindPatientCommand.java index 77a560fd18..c0cf97e198 100644 --- a/src/main/java/duke/command/FindPatientCommand.java +++ b/src/main/java/duke/command/FindPatientCommand.java @@ -5,7 +5,8 @@ import duke.core.Ui; import duke.patient.Patient; import duke.patient.PatientManager; -import duke.storage.CmdFreqStorage; +import duke.statistic.CommandCounter; +import duke.storage.CounterStorage; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; import duke.storage.TaskStorage; @@ -37,9 +38,11 @@ public FindPatientCommand(String command) { @Override public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientManager, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, - PatientStorage patientStorage, CmdFreqStorage cmdFreqStorage, - CommandManager commandManager) throws DukeException { - runCommandFrequencyLogic(commandManager); + PatientStorage patientStorage, CounterStorage counterStorage, + CommandCounter commandCounter) throws DukeException { + this.hasBeenAddedBefore = true; + String commandName = this.getClass().getSimpleName(); + commandCounter.runCommandCounter(this.hasBeenAddedBefore, commandCounter.getCommandTable(), commandName); char firstChar = command.charAt(0); if (firstChar == '#') { int id; @@ -49,11 +52,11 @@ public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManag throw new DukeException("Please follow the format 'find patient #' or 'find patient '."); } Patient patient = patientManager.getPatient(id); - cmdFreqStorage.save(commandManager.getCmdFreqTable()); + counterStorage.save(commandCounter.getCommandTable()); ui.patientsFoundById(patient); } else { ArrayList patientsWithSameName = patientManager.getPatientByName(command); - cmdFreqStorage.save(commandManager.getCmdFreqTable()); + counterStorage.save(commandCounter.getCommandTable()); ui.patientsFoundByName(patientsWithSameName, command); } } diff --git a/src/main/java/duke/command/FindPatientTaskCommand.java b/src/main/java/duke/command/FindPatientTaskCommand.java index 459cadce8a..22f7baa019 100644 --- a/src/main/java/duke/command/FindPatientTaskCommand.java +++ b/src/main/java/duke/command/FindPatientTaskCommand.java @@ -7,7 +7,8 @@ import duke.patient.PatientManager; import duke.relation.PatientTask; import duke.relation.PatientTaskList; -import duke.storage.CmdFreqStorage; +import duke.statistic.CommandCounter; +import duke.storage.CounterStorage; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; import duke.storage.TaskStorage; @@ -45,9 +46,11 @@ public FindPatientTaskCommand(String cmd) { @Override public void execute(PatientTaskList patientTaskList, TaskManager tasksManager, PatientManager patientManager, Ui ui, PatientTaskStorage patientTaskStorage, - TaskStorage taskStorage, PatientStorage patientStorage, CmdFreqStorage cmdFreqStorage, - CommandManager commandManager) throws DukeException { - runCommandFrequencyLogic(commandManager); + TaskStorage taskStorage, PatientStorage patientStorage, CounterStorage counterStorage, + CommandCounter commandCounter) throws DukeException { + this.hasBeenAddedBefore = true; + String commandName = this.getClass().getSimpleName(); + commandCounter.runCommandCounter(this.hasBeenAddedBefore, commandCounter.getCommandTable(), commandName); char firstChar = command.charAt(0); if (firstChar == '#') { int id; @@ -59,7 +62,7 @@ public void execute(PatientTaskList patientTaskList, TaskManager tasksManager, P for (PatientTask temppatientTask : patientTask) { tempTask.add(tasksManager.getTask(temppatientTask.getTaskID())); } - cmdFreqStorage.save(commandManager.getCmdFreqTable()); + counterStorage.save(commandCounter.getCommandTable()); ui.patientTaskFound(patient, patientTask, tempTask); } catch (Exception e) { throw new DukeException("Please follow the format 'find patienttask #' or 'find patient '."); @@ -80,7 +83,7 @@ public void execute(PatientTaskList patientTaskList, TaskManager tasksManager, P tempTask.add(tasksManager.getTask(temppatientTask.getTaskID())); //System.out.println(temppatientTask.getTaskID() + "\n"); } - cmdFreqStorage.save(commandManager.getCmdFreqTable()); + counterStorage.save(commandCounter.getCommandTable()); ui.patientTaskFound(patientsWithSameName.get(0), patientWithTask, tempTask); } catch (Exception e) { throw new DukeException(e.getMessage() diff --git a/src/main/java/duke/command/ListPatientsCommand.java b/src/main/java/duke/command/ListPatientsCommand.java index f3cca5b9d6..f347175cf6 100644 --- a/src/main/java/duke/command/ListPatientsCommand.java +++ b/src/main/java/duke/command/ListPatientsCommand.java @@ -5,7 +5,8 @@ import duke.core.Ui; import duke.patient.Patient; import duke.patient.PatientManager; -import duke.storage.CmdFreqStorage; +import duke.statistic.CommandCounter; +import duke.storage.CounterStorage; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; import duke.storage.TaskStorage; @@ -35,11 +36,13 @@ public ListPatientsCommand() { @Override public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, - TaskStorage taskStorage, PatientStorage patientStorage, CmdFreqStorage cmdFreqStorage, - CommandManager commandManager) throws DukeException { - runCommandFrequencyLogic(commandManager); + TaskStorage taskStorage, PatientStorage patientStorage, CounterStorage counterStorage, + CommandCounter commandCounter) throws DukeException { + this.hasBeenAddedBefore = true; + String commandName = this.getClass().getSimpleName(); + commandCounter.runCommandCounter(this.hasBeenAddedBefore, commandCounter.getCommandTable(), commandName); ArrayList list = patientList.getPatientList(); - cmdFreqStorage.save(commandManager.getCmdFreqTable()); + counterStorage.save(commandCounter.getCommandTable()); ui.listAllPatients(list); } diff --git a/src/main/java/duke/command/ListTasksCommand.java b/src/main/java/duke/command/ListTasksCommand.java index e049dae6f0..db294de68f 100644 --- a/src/main/java/duke/command/ListTasksCommand.java +++ b/src/main/java/duke/command/ListTasksCommand.java @@ -4,7 +4,8 @@ import duke.core.DukeException; import duke.core.Ui; import duke.patient.PatientManager; -import duke.storage.CmdFreqStorage; +import duke.statistic.CommandCounter; +import duke.storage.CounterStorage; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; import duke.storage.TaskStorage; @@ -31,11 +32,13 @@ public class ListTasksCommand extends Command { @Override public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, - PatientStorage patientStorage, CmdFreqStorage cmdFreqStorage, - CommandManager commandManager) throws DukeException { - runCommandFrequencyLogic(commandManager); + PatientStorage patientStorage, CounterStorage counterStorage, + CommandCounter commandCounter) throws DukeException { + this.hasBeenAddedBefore = true; + String commandName = this.getClass().getSimpleName(); + commandCounter.runCommandCounter(this.hasBeenAddedBefore, commandCounter.getCommandTable(), commandName); ArrayList list = tasks.getTaskList(); - cmdFreqStorage.save(commandManager.getCmdFreqTable()); + counterStorage.save(commandCounter.getCommandTable()); ui.listAllTasks(list); } diff --git a/src/main/java/duke/command/UpdatePatientCommand.java b/src/main/java/duke/command/UpdatePatientCommand.java index 19b08efc34..66b5cf224e 100644 --- a/src/main/java/duke/command/UpdatePatientCommand.java +++ b/src/main/java/duke/command/UpdatePatientCommand.java @@ -5,7 +5,8 @@ import duke.core.Ui; import duke.patient.Patient; import duke.patient.PatientManager; -import duke.storage.CmdFreqStorage; +import duke.statistic.CommandCounter; +import duke.storage.CounterStorage; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; import duke.storage.TaskStorage; @@ -40,9 +41,11 @@ public UpdatePatientCommand(String command) { @Override public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientManager, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, - PatientStorage patientStorage, CmdFreqStorage cmdFreqStorage, - CommandManager commandManager) throws DukeException { - runCommandFrequencyLogic(commandManager); + PatientStorage patientStorage, CounterStorage counterStorage, + CommandCounter commandCounter) throws DukeException { + this.hasBeenAddedBefore = true; + String commandName = this.getClass().getSimpleName(); + commandCounter.runCommandCounter(this.hasBeenAddedBefore, commandCounter.getCommandTable(), commandName); String[] tempCommand = command.split(" ", 3); char firstChar = tempCommand[0].charAt(0); if (firstChar == '#') { @@ -61,7 +64,7 @@ public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManag } patientStorage.save(patientManager.getPatientList()); - cmdFreqStorage.save(commandManager.getCmdFreqTable()); + counterStorage.save(commandCounter.getCommandTable()); ui.showUpdatedSuccessfully(); ui.showPatientInfo(patientToBeUpdated); diff --git a/src/main/java/duke/command/UpdateTaskCommand.java b/src/main/java/duke/command/UpdateTaskCommand.java index afcf5b8ba2..def019173f 100644 --- a/src/main/java/duke/command/UpdateTaskCommand.java +++ b/src/main/java/duke/command/UpdateTaskCommand.java @@ -3,7 +3,8 @@ import duke.core.CommandManager; import duke.core.DukeException; import duke.core.Ui; -import duke.storage.CmdFreqStorage; +import duke.statistic.CommandCounter; +import duke.storage.CounterStorage; import duke.task.Task; import duke.patient.PatientManager; import duke.storage.PatientStorage; @@ -39,9 +40,11 @@ public UpdateTaskCommand(String command) { @Override public void execute(PatientTaskList patientTask, TaskManager taskManager, PatientManager patientManager, Ui ui, PatientTaskStorage patientTaskStorage, - TaskStorage taskStorage, PatientStorage patientStorage, CmdFreqStorage cmdFreqStorage, - CommandManager commandManager) throws DukeException { - runCommandFrequencyLogic(commandManager); + TaskStorage taskStorage, PatientStorage patientStorage, CounterStorage counterStorage, + CommandCounter commandCounter) throws DukeException { + this.hasBeenAddedBefore = true; + String commandName = this.getClass().getSimpleName(); + commandCounter.runCommandCounter(this.hasBeenAddedBefore, commandCounter.getCommandTable(), commandName); String[] tempCommand = command.split(" ", 3); char firstChar = tempCommand[0].charAt(0); if (firstChar == '#') { @@ -56,7 +59,7 @@ public void execute(PatientTaskList patientTask, TaskManager taskManager, Patien } taskStorage.save(taskManager.getTaskList()); - cmdFreqStorage.save(commandManager.getCmdFreqTable()); + counterStorage.save(commandCounter.getCommandTable()); ui.showUpdatedSuccessfully(); ui.showTaskInfo(taskToBeUpdated); diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index c7dcac2062..5d9f9a0e3e 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -23,23 +23,13 @@ */ public class CommandManager { - private Map cmdFreqTable; - - public CommandManager(Map cmdFreqTable) { - this.cmdFreqTable = cmdFreqTable; - } - - public Map getCmdFreqTable() { - return cmdFreqTable; - } - /** * Parses a Task from a string array. * * @param userInput The string array to be parsed. * @return The Command received from user. */ - public Command manageCommand(String userInput) throws DukeException { + public static Command manageCommand(String userInput) throws DukeException { userInput = userInput.trim(); String[] command = userInput.split("\\s+", 3); String firstKeyword = command[0].toLowerCase(); @@ -125,11 +115,6 @@ public Command manageCommand(String userInput) throws DukeException { } case "bye": ExitCommand exitCommand = new ExitCommand(); - for (Map.Entry entry : cmdFreqTable.entrySet()) { - System.out.println("Key = " + entry.getKey()); - System.out.println("Value = " + entry.getValue()); - System.out.println("===================================================="); - } return exitCommand; default: throw new DukeException("Could not understand user input."); diff --git a/src/main/java/duke/statistic/CommandCounter.java b/src/main/java/duke/statistic/CommandCounter.java new file mode 100644 index 0000000000..fab773a3d9 --- /dev/null +++ b/src/main/java/duke/statistic/CommandCounter.java @@ -0,0 +1,34 @@ +package duke.statistic; + +import java.util.Map; + +public class CommandCounter { + private Map commandTable; + + public CommandCounter(Map commandTable) { + this.commandTable = commandTable; + } + + public Map getCommandTable() { + return commandTable; + } + + /** + * This function is used to run the command counter. + * @param hasBeenAddedBefore check whether a command has been called before or not + * @param commandTable a table with command name as key and count as value + * @param commandName the command name that was used + * @author QIAN JIE + * @version 1.3 + */ + public void runCommandCounter(boolean hasBeenAddedBefore, Map commandTable, String commandName) { + if (!hasBeenAddedBefore) { + commandTable.put(commandName, 1); + } + int count = commandTable.containsKey(commandName) + ? commandTable.get(commandName) : 0; + commandTable.put(commandName, count + 1); + } + + +} diff --git a/src/main/java/duke/storage/CmdFreqStorage.java b/src/main/java/duke/storage/CounterStorage.java similarity index 92% rename from src/main/java/duke/storage/CmdFreqStorage.java rename to src/main/java/duke/storage/CounterStorage.java index e6bfc7cfbb..9e0f39c7b5 100644 --- a/src/main/java/duke/storage/CmdFreqStorage.java +++ b/src/main/java/duke/storage/CounterStorage.java @@ -16,7 +16,15 @@ import java.util.HashMap; import java.util.Map; -public class CmdFreqStorage { +/** + * CounterStorage.java - a class for load/save of command frequency in csv format, + * written with Storage template written by HUANG XUAN KUN + * + * @author QIAN JIE + * @version 1.3 + */ + +public class CounterStorage { /** * A string that represents a relative file path from the project folder. */ @@ -28,7 +36,7 @@ public class CmdFreqStorage { * @param filePath A string that represents the path of the file to read or * write. */ - public CmdFreqStorage(String filePath) { + public CounterStorage(String filePath) { this.filePath = filePath; } From 12aa087028162885f58af13cdd55d9497b1092a8 Mon Sep 17 00:00:00 2001 From: Qian Jie Date: Sat, 19 Oct 2019 17:34:26 +0800 Subject: [PATCH 169/420] removed redundant check for hasbeenaddedbefore --- data/counter.csv | 4 +--- data/standardTasks.csv | 4 +++- src/main/java/duke/command/AddPatientCommand.java | 4 ++-- src/main/java/duke/command/AddStandardTaskCommand.java | 4 ++-- src/main/java/duke/command/AssignTaskToPatientCommand.java | 4 ++-- src/main/java/duke/command/Command.java | 2 +- src/main/java/duke/command/DeletePatientCommand.java | 3 +-- src/main/java/duke/command/DeleteTaskCommand.java | 3 +-- src/main/java/duke/command/FindPatientCommand.java | 3 +-- src/main/java/duke/command/FindPatientTaskCommand.java | 3 +-- src/main/java/duke/command/ListPatientsCommand.java | 3 +-- src/main/java/duke/command/ListTasksCommand.java | 3 +-- src/main/java/duke/command/UpdatePatientCommand.java | 3 +-- src/main/java/duke/command/UpdateTaskCommand.java | 3 +-- src/main/java/duke/statistic/CommandCounter.java | 6 +----- 15 files changed, 20 insertions(+), 32 deletions(-) diff --git a/data/counter.csv b/data/counter.csv index d81c3652e5..c31dff2bcb 100644 --- a/data/counter.csv +++ b/data/counter.csv @@ -1,6 +1,4 @@ Command Name,Frequency -DeleteTaskCommand,2 -FindPatientCommand,2 DeletePatientCommand,1 AddStandardTaskCommand,1 -AddPatientCommand,2 +AddPatientCommand,1 diff --git a/data/standardTasks.csv b/data/standardTasks.csv index 1e19fb2a1a..c4427c7cc6 100644 --- a/data/standardTasks.csv +++ b/data/standardTasks.csv @@ -1,3 +1,5 @@ Id,Description 1,123 -3,123 +4,123 +5,321 +6,123 diff --git a/src/main/java/duke/command/AddPatientCommand.java b/src/main/java/duke/command/AddPatientCommand.java index 8267a9b8df..34b3923077 100644 --- a/src/main/java/duke/command/AddPatientCommand.java +++ b/src/main/java/duke/command/AddPatientCommand.java @@ -39,9 +39,9 @@ public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManag PatientStorage patientStorage, CounterStorage counterStorage, CommandCounter commandCounter) throws DukeException { - this.hasBeenAddedBefore = true; + //this.hasBeenAddedBefore = true; String commandName = this.getClass().getSimpleName(); - commandCounter.runCommandCounter(this.hasBeenAddedBefore, commandCounter.getCommandTable(), commandName); + commandCounter.runCommandCounter(commandCounter.getCommandTable(), commandName); patientList.addPatient(newPatient); patientStorage.save(patientList.getPatientList()); counterStorage.save(commandCounter.getCommandTable()); diff --git a/src/main/java/duke/command/AddStandardTaskCommand.java b/src/main/java/duke/command/AddStandardTaskCommand.java index 5f020746a9..8e3f421ae6 100644 --- a/src/main/java/duke/command/AddStandardTaskCommand.java +++ b/src/main/java/duke/command/AddStandardTaskCommand.java @@ -44,9 +44,9 @@ public void execute(PatientTaskList patientTask, TaskManager taskList, PatientMa Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage, CounterStorage counterStorage, CommandCounter commandCounter) throws DukeException { - this.hasBeenAddedBefore = true; + //this.hasBeenAddedBefore = true; String commandName = this.getClass().getSimpleName(); - commandCounter.runCommandCounter(this.hasBeenAddedBefore, commandCounter.getCommandTable(), commandName); + commandCounter.runCommandCounter(commandCounter.getCommandTable(), commandName); taskList.addTask(newStandardTask); taskStorage.save(taskList.getTaskList()); counterStorage.save(commandCounter.getCommandTable()); diff --git a/src/main/java/duke/command/AssignTaskToPatientCommand.java b/src/main/java/duke/command/AssignTaskToPatientCommand.java index 6e24c0d09b..f05aa1b4d7 100644 --- a/src/main/java/duke/command/AssignTaskToPatientCommand.java +++ b/src/main/java/duke/command/AssignTaskToPatientCommand.java @@ -52,9 +52,9 @@ public void execute(PatientTaskList patientTaskList, TaskManager tasksList, Pati CommandCounter commandCounter) throws DukeException { if (patientList.isExist(newPatientTask.getPatientId()) && tasksList.doesExist(newPatientTask.getTaskID())) { - this.hasBeenAddedBefore = true; + String commandName = this.getClass().getSimpleName(); - commandCounter.runCommandCounter(this.hasBeenAddedBefore, commandCounter.getCommandTable(), commandName); + commandCounter.runCommandCounter(commandCounter.getCommandTable(), commandName); patientTaskList.addPatientTask(newPatientTask); patientTaskStorage.save(patientTaskList.fullPatientTaskList()); counterStorage.save(commandCounter.getCommandTable()); diff --git a/src/main/java/duke/command/Command.java b/src/main/java/duke/command/Command.java index 2fd1dd5bfc..732203cae3 100644 --- a/src/main/java/duke/command/Command.java +++ b/src/main/java/duke/command/Command.java @@ -19,7 +19,7 @@ */ public abstract class Command { - protected boolean hasBeenAddedBefore = false; + //protected boolean hasBeenAddedBefore = false; /** * . diff --git a/src/main/java/duke/command/DeletePatientCommand.java b/src/main/java/duke/command/DeletePatientCommand.java index 3e62c4dc59..9bb7d7d5aa 100644 --- a/src/main/java/duke/command/DeletePatientCommand.java +++ b/src/main/java/duke/command/DeletePatientCommand.java @@ -57,9 +57,8 @@ public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManag PatientStorage patientStorage, CounterStorage counterStorage, CommandCounter commandCounter) throws DukeException { - this.hasBeenAddedBefore = true; String commandName = this.getClass().getSimpleName(); - commandCounter.runCommandCounter(this.hasBeenAddedBefore, commandCounter.getCommandTable(), commandName); + commandCounter.runCommandCounter(commandCounter.getCommandTable(), commandName); if (id != 0) { Patient patientToBeDeleted = patientManager.getPatient(id); boolean toDelete = ui.confirmPatientToBeDeleted(patientToBeDeleted); diff --git a/src/main/java/duke/command/DeleteTaskCommand.java b/src/main/java/duke/command/DeleteTaskCommand.java index c87104f95e..d22af0f331 100644 --- a/src/main/java/duke/command/DeleteTaskCommand.java +++ b/src/main/java/duke/command/DeleteTaskCommand.java @@ -55,9 +55,8 @@ public void execute(PatientTaskList patientTask, TaskManager taskManager, Patien Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage, CounterStorage counterStorage, CommandCounter commandCounter) throws DukeException { - this.hasBeenAddedBefore = true; String commandName = this.getClass().getSimpleName(); - commandCounter.runCommandCounter(this.hasBeenAddedBefore, commandCounter.getCommandTable(), commandName); + commandCounter.runCommandCounter(commandCounter.getCommandTable(), commandName); if (id != 0) { Task taskToBeDeleted = taskManager.getTask(id); boolean toDelete = ui.confirmTaskToBeDeleted(taskToBeDeleted); diff --git a/src/main/java/duke/command/FindPatientCommand.java b/src/main/java/duke/command/FindPatientCommand.java index c0cf97e198..88fe1178b4 100644 --- a/src/main/java/duke/command/FindPatientCommand.java +++ b/src/main/java/duke/command/FindPatientCommand.java @@ -40,9 +40,8 @@ public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManag Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage, CounterStorage counterStorage, CommandCounter commandCounter) throws DukeException { - this.hasBeenAddedBefore = true; String commandName = this.getClass().getSimpleName(); - commandCounter.runCommandCounter(this.hasBeenAddedBefore, commandCounter.getCommandTable(), commandName); + commandCounter.runCommandCounter(commandCounter.getCommandTable(), commandName); char firstChar = command.charAt(0); if (firstChar == '#') { int id; diff --git a/src/main/java/duke/command/FindPatientTaskCommand.java b/src/main/java/duke/command/FindPatientTaskCommand.java index 22f7baa019..2e3f5fa284 100644 --- a/src/main/java/duke/command/FindPatientTaskCommand.java +++ b/src/main/java/duke/command/FindPatientTaskCommand.java @@ -48,9 +48,8 @@ public void execute(PatientTaskList patientTaskList, TaskManager tasksManager, P Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage, CounterStorage counterStorage, CommandCounter commandCounter) throws DukeException { - this.hasBeenAddedBefore = true; String commandName = this.getClass().getSimpleName(); - commandCounter.runCommandCounter(this.hasBeenAddedBefore, commandCounter.getCommandTable(), commandName); + commandCounter.runCommandCounter(commandCounter.getCommandTable(), commandName); char firstChar = command.charAt(0); if (firstChar == '#') { int id; diff --git a/src/main/java/duke/command/ListPatientsCommand.java b/src/main/java/duke/command/ListPatientsCommand.java index f347175cf6..54d4d4a525 100644 --- a/src/main/java/duke/command/ListPatientsCommand.java +++ b/src/main/java/duke/command/ListPatientsCommand.java @@ -38,9 +38,8 @@ public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManag Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage, CounterStorage counterStorage, CommandCounter commandCounter) throws DukeException { - this.hasBeenAddedBefore = true; String commandName = this.getClass().getSimpleName(); - commandCounter.runCommandCounter(this.hasBeenAddedBefore, commandCounter.getCommandTable(), commandName); + commandCounter.runCommandCounter(commandCounter.getCommandTable(), commandName); ArrayList list = patientList.getPatientList(); counterStorage.save(commandCounter.getCommandTable()); ui.listAllPatients(list); diff --git a/src/main/java/duke/command/ListTasksCommand.java b/src/main/java/duke/command/ListTasksCommand.java index db294de68f..95fde2ead3 100644 --- a/src/main/java/duke/command/ListTasksCommand.java +++ b/src/main/java/duke/command/ListTasksCommand.java @@ -34,9 +34,8 @@ public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManag Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage, CounterStorage counterStorage, CommandCounter commandCounter) throws DukeException { - this.hasBeenAddedBefore = true; String commandName = this.getClass().getSimpleName(); - commandCounter.runCommandCounter(this.hasBeenAddedBefore, commandCounter.getCommandTable(), commandName); + commandCounter.runCommandCounter(commandCounter.getCommandTable(), commandName); ArrayList list = tasks.getTaskList(); counterStorage.save(commandCounter.getCommandTable()); ui.listAllTasks(list); diff --git a/src/main/java/duke/command/UpdatePatientCommand.java b/src/main/java/duke/command/UpdatePatientCommand.java index 66b5cf224e..32832dc46f 100644 --- a/src/main/java/duke/command/UpdatePatientCommand.java +++ b/src/main/java/duke/command/UpdatePatientCommand.java @@ -43,9 +43,8 @@ public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManag Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage, CounterStorage counterStorage, CommandCounter commandCounter) throws DukeException { - this.hasBeenAddedBefore = true; String commandName = this.getClass().getSimpleName(); - commandCounter.runCommandCounter(this.hasBeenAddedBefore, commandCounter.getCommandTable(), commandName); + commandCounter.runCommandCounter(commandCounter.getCommandTable(), commandName); String[] tempCommand = command.split(" ", 3); char firstChar = tempCommand[0].charAt(0); if (firstChar == '#') { diff --git a/src/main/java/duke/command/UpdateTaskCommand.java b/src/main/java/duke/command/UpdateTaskCommand.java index def019173f..cca5c4f680 100644 --- a/src/main/java/duke/command/UpdateTaskCommand.java +++ b/src/main/java/duke/command/UpdateTaskCommand.java @@ -42,9 +42,8 @@ public void execute(PatientTaskList patientTask, TaskManager taskManager, Patien Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage, CounterStorage counterStorage, CommandCounter commandCounter) throws DukeException { - this.hasBeenAddedBefore = true; String commandName = this.getClass().getSimpleName(); - commandCounter.runCommandCounter(this.hasBeenAddedBefore, commandCounter.getCommandTable(), commandName); + commandCounter.runCommandCounter(commandCounter.getCommandTable(), commandName); String[] tempCommand = command.split(" ", 3); char firstChar = tempCommand[0].charAt(0); if (firstChar == '#') { diff --git a/src/main/java/duke/statistic/CommandCounter.java b/src/main/java/duke/statistic/CommandCounter.java index fab773a3d9..129ca0fa15 100644 --- a/src/main/java/duke/statistic/CommandCounter.java +++ b/src/main/java/duke/statistic/CommandCounter.java @@ -15,16 +15,12 @@ public Map getCommandTable() { /** * This function is used to run the command counter. - * @param hasBeenAddedBefore check whether a command has been called before or not * @param commandTable a table with command name as key and count as value * @param commandName the command name that was used * @author QIAN JIE * @version 1.3 */ - public void runCommandCounter(boolean hasBeenAddedBefore, Map commandTable, String commandName) { - if (!hasBeenAddedBefore) { - commandTable.put(commandName, 1); - } + public void runCommandCounter(Map commandTable, String commandName) { int count = commandTable.containsKey(commandName) ? commandTable.get(commandName) : 0; commandTable.put(commandName, count + 1); From d66d4cc07d760e99e6980836dda63ac03633be6f Mon Sep 17 00:00:00 2001 From: WEIFENG-NUSCEG Date: Sat, 19 Oct 2019 18:54:21 +0800 Subject: [PATCH 170/420] Modified the code spacing to match the check style requirement --- build/reports/checkstyle/main.html | 324 ++---------------- build/reports/checkstyle/main.xml | 88 ----- build/reports/checkstyle/test.html | 61 +--- build/reports/checkstyle/test.xml | 19 - .../command/AssignTaskToPatientCommand.java | 16 +- .../command/DeletePatientTaskCommand.java | 52 ++- src/main/java/duke/core/CommandManager.java | 15 +- src/main/java/duke/core/Parser.java | 2 +- src/main/java/duke/core/Ui.java | 20 -- .../java/duke/relation/EventPatientTask.java | 8 +- src/main/java/duke/relation/PatientTask.java | 5 +- .../java/duke/relation/PatientTaskList.java | 14 +- .../duke/relation/StandardPatientTask.java | 2 +- .../java/duke/storage/PatientTaskStorage.java | 5 +- 14 files changed, 114 insertions(+), 517 deletions(-) diff --git a/build/reports/checkstyle/main.html b/build/reports/checkstyle/main.html index c66e194bc7..ce2e375045 100644 --- a/build/reports/checkstyle/main.html +++ b/build/reports/checkstyle/main.html @@ -72,7 +72,7 @@

Summary

- +
Error DescriptionLine FilesErrors
3288320

@@ -82,91 +82,91 @@

Files

NameErrors - /Users/weifeng/forkmain/src/main/java/duke/command/DeletePatientTaskCommand.java40 + /Users/weifeng/forkmain/src/main/java/duke/Duke.java0 - /Users/weifeng/forkmain/src/main/java/duke/relation/PatientTaskList.java19 + /Users/weifeng/forkmain/src/main/java/duke/command/AddPatientCommand.java0 - /Users/weifeng/forkmain/src/main/java/duke/relation/EventPatientTask.java11 + /Users/weifeng/forkmain/src/main/java/duke/command/AddStandardTaskCommand.java0 - /Users/weifeng/forkmain/src/main/java/duke/command/AssignTaskToPatientCommand.java9 + /Users/weifeng/forkmain/src/main/java/duke/command/AssignTaskToPatientCommand.java0 - /Users/weifeng/forkmain/src/main/java/duke/core/Ui.java3 + /Users/weifeng/forkmain/src/main/java/duke/command/Command.java0 - /Users/weifeng/forkmain/src/main/java/duke/relation/PatientTask.java3 + /Users/weifeng/forkmain/src/main/java/duke/command/DeletePatientCommand.java0 - /Users/weifeng/forkmain/src/main/java/duke/core/Parser.java1 + /Users/weifeng/forkmain/src/main/java/duke/command/DeletePatientTaskCommand.java0 - /Users/weifeng/forkmain/src/main/java/duke/relation/StandardPatientTask.java1 + /Users/weifeng/forkmain/src/main/java/duke/command/DeleteTaskCommand.java0 - /Users/weifeng/forkmain/src/main/java/duke/storage/PatientTaskStorage.java1 + /Users/weifeng/forkmain/src/main/java/duke/command/ExitCommand.java0 - /Users/weifeng/forkmain/src/main/java/duke/Duke.java0 + /Users/weifeng/forkmain/src/main/java/duke/command/FindPatientCommand.java0 - /Users/weifeng/forkmain/src/main/java/duke/command/AddPatientCommand.java0 + /Users/weifeng/forkmain/src/main/java/duke/command/FindPatientTaskCommand.java0 - /Users/weifeng/forkmain/src/main/java/duke/command/AddStandardTaskCommand.java0 + /Users/weifeng/forkmain/src/main/java/duke/command/HelpCommand.java0 - /Users/weifeng/forkmain/src/main/java/duke/command/Command.java0 + /Users/weifeng/forkmain/src/main/java/duke/command/ListPatientsCommand.java0 - /Users/weifeng/forkmain/src/main/java/duke/command/DeletePatientCommand.java0 + /Users/weifeng/forkmain/src/main/java/duke/command/ListTasksCommand.java0 - /Users/weifeng/forkmain/src/main/java/duke/command/DeleteTaskCommand.java0 + /Users/weifeng/forkmain/src/main/java/duke/command/UpdatePatientCommand.java0 - /Users/weifeng/forkmain/src/main/java/duke/command/ExitCommand.java0 + /Users/weifeng/forkmain/src/main/java/duke/command/UpdateTaskCommand.java0 - /Users/weifeng/forkmain/src/main/java/duke/command/FindPatientCommand.java0 + /Users/weifeng/forkmain/src/main/java/duke/core/CommandManager.java0 - /Users/weifeng/forkmain/src/main/java/duke/command/FindPatientTaskCommand.java0 + /Users/weifeng/forkmain/src/main/java/duke/core/DateTimeParser.java0 - /Users/weifeng/forkmain/src/main/java/duke/command/HelpCommand.java0 + /Users/weifeng/forkmain/src/main/java/duke/core/DukeException.java0 - /Users/weifeng/forkmain/src/main/java/duke/command/ListPatientsCommand.java0 + /Users/weifeng/forkmain/src/main/java/duke/core/Parser.java0 - /Users/weifeng/forkmain/src/main/java/duke/command/ListTasksCommand.java0 + /Users/weifeng/forkmain/src/main/java/duke/core/Ui.java0 - /Users/weifeng/forkmain/src/main/java/duke/command/UpdatePatientCommand.java0 + /Users/weifeng/forkmain/src/main/java/duke/patient/Patient.java0 - /Users/weifeng/forkmain/src/main/java/duke/command/UpdateTaskCommand.java0 + /Users/weifeng/forkmain/src/main/java/duke/patient/PatientManager.java0 - /Users/weifeng/forkmain/src/main/java/duke/core/CommandManager.java0 + /Users/weifeng/forkmain/src/main/java/duke/relation/EventPatientTask.java0 - /Users/weifeng/forkmain/src/main/java/duke/core/DateTimeParser.java0 + /Users/weifeng/forkmain/src/main/java/duke/relation/PatientTask.java0 - /Users/weifeng/forkmain/src/main/java/duke/core/DukeException.java0 + /Users/weifeng/forkmain/src/main/java/duke/relation/PatientTaskList.java0 - /Users/weifeng/forkmain/src/main/java/duke/patient/Patient.java0 + /Users/weifeng/forkmain/src/main/java/duke/relation/StandardPatientTask.java0 - /Users/weifeng/forkmain/src/main/java/duke/patient/PatientManager.java0 + /Users/weifeng/forkmain/src/main/java/duke/storage/PatientStorage.java0 - /Users/weifeng/forkmain/src/main/java/duke/storage/PatientStorage.java0 + /Users/weifeng/forkmain/src/main/java/duke/storage/PatientTaskStorage.java0 /Users/weifeng/forkmain/src/main/java/duke/storage/TaskStorage.java0 @@ -206,33 +206,6 @@

File /Users/weifeng/forkmain/src/main/java/duke/command/AssignTaskToPatientC Error DescriptionLine - - WhitespaceAround: '{' is not preceded with whitespace.49 - - - WhitespaceAround: '{' is not preceded with whitespace.50 - - - WhitespaceAround: 'else' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)56 - - - WhitespaceAround: '{' is not preceded with whitespace.56 - - - WhitespaceAround: '{' is not preceded with whitespace.64 - - - Line is longer than 120 characters (found 121).70 - - - Line is longer than 120 characters (found 121).77 - - - WhitespaceAround: 'if' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)88 - - - WhitespaceAround: '{' is not preceded with whitespace.88 - Back to top

File /Users/weifeng/forkmain/src/main/java/duke/command/Command.java

@@ -254,126 +227,6 @@

File /Users/weifeng/forkmain/src/main/java/duke/command/DeletePatientTaskCom Error DescriptionLine - - Missing a Javadoc comment.32 - - - WhitespaceAround: 'try' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)37 - - - WhitespaceAround: '{' is not preceded with whitespace.37 - - - '{' at column 13 should be on the previous line.39 - - - '}' at column 13 should be on the same line as the next part of a multi-block statement (one that directly contains multiple blocks: if/else-if/else, do/while or try/catch/finally).47 - - - WhitespaceAround: '{' is not preceded with whitespace.48 - - - '}' at column 13 should be on the same line as the next part of a multi-block statement (one that directly contains multiple blocks: if/else-if/else, do/while or try/catch/finally).54 - - - WhitespaceAround: '}' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)72 - - - WhitespaceAround: 'catch' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)72 - - - WhitespaceAround: 'catch' is not preceded with whitespace.72 - - - Line is longer than 120 characters (found 186).73 - - - Line is longer than 120 characters (found 229).80 - - - '{' at column 227 should have line break after.80 - - - WhitespaceAround: 'try' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)82 - - - WhitespaceAround: '{' is not preceded with whitespace.82 - - - Local variable name 'ToBeDeleted' must match pattern '^[a-z]([a-z0-9][a-zA-Z0-9]*)?$'.83 - - - Local variable name 'ToBeDeletedPatient' must match pattern '^[a-z]([a-z0-9][a-zA-Z0-9]*)?$'.84 - - - Local variable name 'ToBeDeletedTask' must match pattern '^[a-z]([a-z0-9][a-zA-Z0-9]*)?$'.85 - - - WhitespaceAround: '{' is not preceded with whitespace.86 - - - Line is longer than 120 characters (found 246).87 - - - '}' at column 21 should be on the same line as the next part of a multi-block statement (one that directly contains multiple blocks: if/else-if/else, do/while or try/catch/finally).90 - - - Line is longer than 120 characters (found 193).91 - - - WhitespaceAround: '{' is not preceded with whitespace.91 - - - WhitespaceAround: '}' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)96 - - - WhitespaceAround: 'catch' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)96 - - - WhitespaceAround: 'catch' is not preceded with whitespace.96 - - - WhitespaceAround: 'try' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)102 - - - WhitespaceAround: '{' is not preceded with whitespace.102 - - - Local variable name 'ToBeDeleted' must match pattern '^[a-z]([a-z0-9][a-zA-Z0-9]*)?$'.106 - - - Local variable name 'ToBeDeletedTask' must match pattern '^[a-z]([a-z0-9][a-zA-Z0-9]*)?$'.107 - - - WhitespaceAround: '{' is not preceded with whitespace.108 - - - Line is longer than 120 characters (found 270).109 - - - Line is longer than 120 characters (found 130).111 - - - '}' at column 21 should be on the same line as the next part of a multi-block statement (one that directly contains multiple blocks: if/else-if/else, do/while or try/catch/finally).112 - - - Line is longer than 120 characters (found 193).113 - - - WhitespaceAround: '{' is not preceded with whitespace.113 - - - Line is longer than 120 characters (found 131).115 - - - WhitespaceAround: '}' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)118 - - - WhitespaceAround: 'catch' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)118 - - - WhitespaceAround: 'catch' is not preceded with whitespace.118 - Back to top

File /Users/weifeng/forkmain/src/main/java/duke/command/DeleteTaskCommand.java

@@ -465,9 +318,6 @@

File /Users/weifeng/forkmain/src/main/java/duke/core/Parser.java

Error DescriptionLine - - WhitespaceAround: '{' is not preceded with whitespace.56 - Back to top

File /Users/weifeng/forkmain/src/main/java/duke/core/Ui.java

@@ -475,15 +325,6 @@

File /Users/weifeng/forkmain/src/main/java/duke/core/Ui.java

Error DescriptionLine - - WhitespaceAround: '+' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)281 - - - ')' is preceded with whitespace.281 - - - Block comment has incorrect indentation level 0, expected is 4, indentation should be the same level as line 365.341 - Back to top

File /Users/weifeng/forkmain/src/main/java/duke/patient/Patient.java

@@ -505,39 +346,6 @@

File /Users/weifeng/forkmain/src/main/java/duke/relation/EventPatientTask.ja Error DescriptionLine - - '{' at column 40 should have line break after.91 - - - WhitespaceAround: '{' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)91 - - - WhitespaceAround: '{' is not preceded with whitespace.91 - - - WhitespaceAround: 'return' is not preceded with whitespace.91 - - - WhitespaceAround: '}' is not preceded with whitespace.91 - - - '}' at column 58 should be alone on a line.91 - - - '{' at column 39 should have line break after.98 - - - WhitespaceAround: '{' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)98 - - - WhitespaceAround: 'return' is not preceded with whitespace.98 - - - WhitespaceAround: '}' is not preceded with whitespace.98 - - - '}' at column 55 should be alone on a line.98 - Back to top

File /Users/weifeng/forkmain/src/main/java/duke/relation/PatientTask.java

@@ -545,15 +353,6 @@

File /Users/weifeng/forkmain/src/main/java/duke/relation/PatientTask.java Error DescriptionLine - - 'METHOD_DEF' should be separated from previous statement.45 - - - 'METHOD_DEF' should be separated from previous statement.53 - - - '+' should be on a new line.156 - Back to top

File /Users/weifeng/forkmain/src/main/java/duke/relation/PatientTaskList.java

@@ -561,63 +360,6 @@

File /Users/weifeng/forkmain/src/main/java/duke/relation/PatientTaskList.jav Error DescriptionLine - - '&&' should be on a new line.61 - - - '&&' should be on a new line.62 - - - Line is longer than 120 characters (found 125).67 - - - Missing a Javadoc comment.75 - - - Line is longer than 120 characters (found 125).79 - - - WhitespaceAround: '&&' is not preceded with whitespace.79 - - - WhitespaceAround: '{' is not preceded with whitespace.79 - - - '}' at column 21 should be on the same line as the next part of a multi-block statement (one that directly contains multiple blocks: if/else-if/else, do/while or try/catch/finally).82 - - - WhitespaceAround: 'else' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)83 - - - WhitespaceAround: '{' is not preceded with whitespace.83 - - - Line is longer than 120 characters (found 129).84 - - - WhitespaceAround: '{' is not preceded with whitespace.101 - - - WhitespaceAround: 'for' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)102 - - - WhitespaceAround: '{' is not preceded with whitespace.102 - - - WhitespaceAround: '{' is not preceded with whitespace.103 - - - WhitespaceAround: '{' is not preceded with whitespace.115 - - - WhitespaceAround: 'for' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3)116 - - - WhitespaceAround: '{' is not preceded with whitespace.116 - - - WhitespaceAround: '{' is not preceded with whitespace.117 - Back to top

File /Users/weifeng/forkmain/src/main/java/duke/relation/StandardPatientTask.java

@@ -625,9 +367,6 @@

File /Users/weifeng/forkmain/src/main/java/duke/relation/StandardPatientTask Error DescriptionLine - - WhitespaceAround: '{' is not preceded with whitespace.55 - Back to top

File /Users/weifeng/forkmain/src/main/java/duke/storage/PatientStorage.java

@@ -642,9 +381,6 @@

File /Users/weifeng/forkmain/src/main/java/duke/storage/PatientTaskStorage.j Error DescriptionLine - - Line is longer than 120 characters (found 125).97 - Back to top

File /Users/weifeng/forkmain/src/main/java/duke/storage/TaskStorage.java

diff --git a/build/reports/checkstyle/main.xml b/build/reports/checkstyle/main.xml index d388c330ec..a771f44b91 100644 --- a/build/reports/checkstyle/main.xml +++ b/build/reports/checkstyle/main.xml @@ -7,61 +7,12 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -88,63 +39,24 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/build/reports/checkstyle/test.html b/build/reports/checkstyle/test.html index 707266a3f8..f96fb23f60 100644 --- a/build/reports/checkstyle/test.html +++ b/build/reports/checkstyle/test.html @@ -72,7 +72,7 @@

Summary

FilesErrors - 119 + 10
@@ -82,7 +82,7 @@

Files

NameErrors - /Users/weifeng/forkmain/src/test/java/duke/core/ParserTest.java19 + /Users/weifeng/forkmain/src/test/java/duke/core/ParserTest.java0
@@ -92,63 +92,6 @@

File /Users/weifeng/forkmain/src/test/java/duke/core/ParserTest.java

Error DescriptionLine - - Abbreviation in name 'assignPatientIDToTaskS' must contain no more than '2' consecutive capital letters.11 - - - Abbreviation in name 'assignPatientIDToTaskE' must contain no more than '2' consecutive capital letters.12 - - - Line is longer than 120 characters (found 132).24 - - - Line is longer than 120 characters (found 132).25 - - - Line is longer than 120 characters (found 132).26 - - - Line is longer than 120 characters (found 138).27 - - - Line is longer than 120 characters (found 152).36 - - - Distance between variable 'testOutputEvent' declaration and its first usage is 4, but allowed 3. Consider making that variable final if you still need to store its value in advance (before method calls that might have side effects on the original value).45 - - - Line is longer than 120 characters (found 134).47 - - - 'method call' child has incorrect indentation level 8, expected level should be 12.49 - - - Line is longer than 120 characters (found 137).49 - - - Line is longer than 120 characters (found 128).52 - - - Line is longer than 120 characters (found 139).54 - - - Line is longer than 120 characters (found 157).55 - - - Line is longer than 120 characters (found 155).56 - - - Line is longer than 120 characters (found 162).67 - - - Line is longer than 120 characters (found 145).68 - - - Line is longer than 120 characters (found 157).79 - - - Line is longer than 120 characters (found 150).80 - Back to top
diff --git a/build/reports/checkstyle/test.xml b/build/reports/checkstyle/test.xml index 9bb14fed9c..2150bce770 100644 --- a/build/reports/checkstyle/test.xml +++ b/build/reports/checkstyle/test.xml @@ -1,24 +1,5 @@ - - - - - - - - - - - - - - - - - - - diff --git a/src/main/java/duke/command/AssignTaskToPatientCommand.java b/src/main/java/duke/command/AssignTaskToPatientCommand.java index 0cdbd92f0c..1a2bfdabf0 100644 --- a/src/main/java/duke/command/AssignTaskToPatientCommand.java +++ b/src/main/java/duke/command/AssignTaskToPatientCommand.java @@ -46,14 +46,14 @@ public void execute(PatientTaskList patientTaskList, TaskManager tasksList, Pati char firstChar = taskAssignmentInfo[2].charAt(0); try { - if (taskAssignmentInfo[0].equals("S")){ - if (firstChar == '#'){ + if (taskAssignmentInfo[0].equals("S")) { + if (firstChar == '#') { int tempUid = Integer.parseInt(taskAssignmentInfo[1]); int tempPid = Integer.parseInt(taskAssignmentInfo[2].replace("#","").trim()); int tempTid = Integer.parseInt(taskAssignmentInfo[3]); String temptime = taskAssignmentInfo[4]; newPatientTask = new StandardPatientTask(tempPid, tempTid, temptime, taskAssignmentInfo[0],tempUid); - } else{ + } else { int tempUid = Integer.parseInt(taskAssignmentInfo[1]); int tempPid = patientList.getPatientByName(taskAssignmentInfo[2]).get(0).getID(); int tempTid = tasksList.getTaskByDescription(taskAssignmentInfo[3]).get(0).getID(); @@ -61,20 +61,22 @@ public void execute(PatientTaskList patientTaskList, TaskManager tasksList, Pati newPatientTask = new StandardPatientTask(tempPid, tempTid, temptime, taskAssignmentInfo[0],tempUid); } } else if (taskAssignmentInfo[0].equals("E")) { - if (firstChar == '#'){ + if (firstChar == '#') { int tempUid = Integer.parseInt(taskAssignmentInfo[1]); int tempPid = Integer.parseInt(taskAssignmentInfo[2].replace("#","").trim()); int tempTid = Integer.parseInt(taskAssignmentInfo[3]); String stime = taskAssignmentInfo[4].split(" to ", 2)[0]; String etime = taskAssignmentInfo[4].split(" to ", 2)[1]; - newPatientTask = new EventPatientTask(tempPid, tempTid, stime, etime, taskAssignmentInfo[0],tempUid); + newPatientTask = new EventPatientTask(tempPid, tempTid, stime, etime, + taskAssignmentInfo[0],tempUid); } else { int tempUid = Integer.parseInt(taskAssignmentInfo[1]); int tempPid = patientList.getPatientByName(taskAssignmentInfo[2]).get(0).getID(); int tempTid = tasksList.getTaskByDescription(taskAssignmentInfo[3]).get(0).getID(); String stime = taskAssignmentInfo[4].split(" to ", 2)[0]; String etime = taskAssignmentInfo[4].split(" to ", 2)[1]; - newPatientTask = new EventPatientTask(tempPid, tempTid, stime, etime, taskAssignmentInfo[0],tempUid); + newPatientTask = new EventPatientTask(tempPid, tempTid, stime, etime, + taskAssignmentInfo[0],tempUid); } } else { throw new DukeException("Wrong format is detected!"); @@ -85,7 +87,7 @@ public void execute(PatientTaskList patientTaskList, TaskManager tasksList, Pati } if (patientList.isExist(newPatientTask.getPatientId()) && tasksList.doesExist(newPatientTask.getTaskID())) { - if(patientTaskList.isIdExist(newPatientTask.getUid()) || patientTaskList.isSameTaskExist(newPatientTask)){ + if (patientTaskList.isIdExist(newPatientTask.getUid()) || patientTaskList.isSameTaskExist(newPatientTask)) { throw new DukeException("Either the unique task id is repeated or the same task exists"); } else { patientTaskList.addPatientTask(newPatientTask); diff --git a/src/main/java/duke/command/DeletePatientTaskCommand.java b/src/main/java/duke/command/DeletePatientTaskCommand.java index 1e189e7ac3..ff2c3223b1 100644 --- a/src/main/java/duke/command/DeletePatientTaskCommand.java +++ b/src/main/java/duke/command/DeletePatientTaskCommand.java @@ -25,54 +25,78 @@ public class DeletePatientTaskCommand extends Command { private String deletedPatientInfo; private String[] command; + + /** + * . + * @param deleteInfo . + * @throws DukeException . + */ public DeletePatientTaskCommand(String[] deleteInfo) throws DukeException { char firstChar = deleteInfo[0].charAt(0); - try{ - if (firstChar == '#'){ + try { + if (firstChar == '#') { this.patientId = Integer.parseInt(deleteInfo[0].replace("#","").trim()); this.taskId = Integer.parseInt(deleteInfo[1]); } else { this.deletedPatientInfo = deleteInfo[0]; this.taskId = Integer.parseInt(deleteInfo[1]); } - }catch(Exception e) { + } catch (Exception e) { throw new DukeException("Try to follow the format: delete patienttask #patientid taskuniqeid"); } } + /** + * . + * @param patientTaskList . + * @param tasks . + * @param patientManager . + * @param ui . + * @param patientTaskStorage . + * @param taskStorage . + * @param patientStorage . + * @throws DukeException . + */ @Override - public void execute(PatientTaskList patientTaskList, TaskManager tasks, PatientManager patientManager, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { ; + public void execute(PatientTaskList patientTaskList, TaskManager tasks, PatientManager patientManager, Ui ui, + PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) + throws DukeException { if (patientId != 0) { - try{ - Patient ToBeDeletedPatient = patientManager.getPatient(patientId); - for (PatientTask patientTask: patientTaskList.getPatientTask(patientId)){ - if (patientTask.getUid() == taskId){ + try { + Patient toBeDeletedPatient = patientManager.getPatient(patientId); + for (PatientTask patientTask: patientTaskList.getPatientTask(patientId)) { + if (patientTask.getUid() == taskId) { patientTaskList.deletePatientTaskByUniqueId(taskId); - ui.patientTaskDeleted(patientTask, ToBeDeletedPatient); + ui.patientTaskDeleted(patientTask, toBeDeletedPatient); } } - }catch(DukeException e) { + } catch (DukeException e) { throw new DukeException("Task or patient is not found!" + e.getMessage()); } } else { - try{ + try { String patientName = this.deletedPatientInfo; ArrayList patientsWithSameName = patientManager.getPatientByName(patientName); - ArrayList ToBeDeleted = patientTaskList.getPatientTask(patientsWithSameName.get(0).getID()); - for (PatientTask patientTask: ToBeDeleted){ + ArrayList toBeDeleted = + patientTaskList.getPatientTask(patientsWithSameName.get(0).getID()); + for (PatientTask patientTask: toBeDeleted) { if (patientTask.getUid() == taskId) { patientTaskList.deletePatientTaskByUniqueId(taskId); ui.patientTaskDeleted(patientTask, patientsWithSameName.get(0)); } } - }catch(Exception e) { + } catch (Exception e) { throw new DukeException("Task or patient is not found!"); } } } + /** + * . + * @return . + */ @Override public boolean isExit() { return false; diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index ee5a0dc5cf..bd8a0d01c3 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -1,6 +1,19 @@ package duke.core; -import duke.command.*; +import duke.command.AddStandardTaskCommand; +import duke.command.AssignTaskToPatientCommand; +import duke.command.Command; +import duke.command.AddPatientCommand; +import duke.command.ListPatientsCommand; +import duke.command.ListTasksCommand; +import duke.command.DeletePatientTaskCommand; +import duke.command.DeletePatientCommand; +import duke.command.DeleteTaskCommand; +import duke.command.FindPatientCommand; +import duke.command.FindPatientTaskCommand; +import duke.command.ExitCommand; +import duke.command.UpdatePatientCommand; +import duke.command.UpdateTaskCommand; /** * Represents a Parser that parses user input into a specific diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index eb2e3e6861..d727b839a1 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -71,7 +71,7 @@ public String[] parseAssign() throws DukeException { formattedInput[4] = parsedCommand[5]; if (parsedCommand[1].equals("eventtask")) { formattedInput[0] = "E"; - } else if (parsedCommand[1].equals("standardtask")){ + } else if (parsedCommand[1].equals("standardtask")) { formattedInput[0] = "S"; } else { throw new DukeException("Please use proper 'assign standardtask/eventtask' command format. "); diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index cce190377a..e87528b03a 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -337,27 +337,7 @@ public boolean confirmTaskToBeDeleted(Task task) { } } } -/* - public boolean confirmPatientTaskToBeDeleted(PatientTask patientTask, Patient p, Task t) { - showLine(); - System.out.println( t.getID() + ". " + t.getDescription() +"\n"); - System.out.println( patientTask.toString()); - showLine(); - while (true) { - System.out.println("The task is to be deleted from patient: " + p.getName() + " " + p.getID()); - String command = readCommand(); - if (command.toLowerCase().equals("y")) { - return true; - } else if (command.toLowerCase().equals("n")) { - System.out.println("Delete command is canceled"); - return false; - } else { - System.out.println("Please enter only Y/N to confirm/cancel deletion!"); - } - } - } -*/ /** * Shows a divider line. */ diff --git a/src/main/java/duke/relation/EventPatientTask.java b/src/main/java/duke/relation/EventPatientTask.java index ea4d239348..fca2449e0e 100644 --- a/src/main/java/duke/relation/EventPatientTask.java +++ b/src/main/java/duke/relation/EventPatientTask.java @@ -88,14 +88,18 @@ public String getEndTimeRaw() { * * @return . */ - public LocalDateTime getStartTime(){return startTime;} + public LocalDateTime getStartTime() { + return startTime; + } /** * . * * @return . */ - public LocalDateTime getEndTime() {return endTime;} + public LocalDateTime getEndTime() { + return endTime; + } /** * . diff --git a/src/main/java/duke/relation/PatientTask.java b/src/main/java/duke/relation/PatientTask.java index 9e12d6b34f..9a4a99ce97 100644 --- a/src/main/java/duke/relation/PatientTask.java +++ b/src/main/java/duke/relation/PatientTask.java @@ -39,12 +39,14 @@ public PatientTask(int pid, int tid, boolean isdone, boolean isrecurrsive, Strin this.isRecurrsive = isrecurrsive; this.uuid = uid; } + /** * . */ public int getUid() { return this.uuid; } + /** * . * @@ -153,8 +155,7 @@ public String getRecurrsiveIcon() { * @return . */ public String printStatus() { - return " Unique ID " + uuid + " " + "[" + this.getStatusIcon() + "] " + - "[" + this.getRecurrsiveIcon() + "] "; + return " Unique ID " + uuid + " " + "[" + this.getStatusIcon() + "] " + "[" + this.getRecurrsiveIcon() + "] "; } diff --git a/src/main/java/duke/relation/PatientTaskList.java b/src/main/java/duke/relation/PatientTaskList.java index 4247796f3c..d087cffcb0 100644 --- a/src/main/java/duke/relation/PatientTaskList.java +++ b/src/main/java/duke/relation/PatientTaskList.java @@ -54,7 +54,7 @@ public void addPatientTask(PatientTask t) { * @param uid . * @throws DukeException . */ - public void deletePatientTaskByUniqueId (int uid) throws DukeException { + public void deletePatientTaskByUniqueId(int uid) throws DukeException { for (PatientTask patientTask : patientTaskIdMap.values()) { if (patientTask.getUid() == uid) { patientTaskIdMap.remove(patientTask.getPatientId(), patientTask); @@ -70,9 +70,9 @@ public void deletePatientTaskByUniqueId (int uid) throws DukeException { * * @return . */ - public boolean isIdExist(int id){ - for(PatientTask patientTask: patientTaskIdMap.values()){ - if (patientTask.getUid() == id){ + public boolean isIdExist(int id) { + for (PatientTask patientTask: patientTaskIdMap.values()) { + if (patientTask.getUid() == id) { return true; } } @@ -84,9 +84,9 @@ public boolean isIdExist(int id){ * * @return . */ - public boolean isSameTaskExist(PatientTask patientTask){ - for(PatientTask newPatientTask: patientTaskIdMap.values()){ - if (newPatientTask.equals(patientTask)){ + public boolean isSameTaskExist(PatientTask patientTask) { + for (PatientTask newPatientTask: patientTaskIdMap.values()) { + if (newPatientTask.equals(patientTask)) { return true; } } diff --git a/src/main/java/duke/relation/StandardPatientTask.java b/src/main/java/duke/relation/StandardPatientTask.java index cbe46e21d3..3059a5724c 100644 --- a/src/main/java/duke/relation/StandardPatientTask.java +++ b/src/main/java/duke/relation/StandardPatientTask.java @@ -52,7 +52,7 @@ public StandardPatientTask(int pid, int tid, * . * @return . */ - public LocalDateTime getDeadline(){ + public LocalDateTime getDeadline() { return this.deadline; } diff --git a/src/main/java/duke/storage/PatientTaskStorage.java b/src/main/java/duke/storage/PatientTaskStorage.java index 89c5b0045b..f7642ed4cd 100644 --- a/src/main/java/duke/storage/PatientTaskStorage.java +++ b/src/main/java/duke/storage/PatientTaskStorage.java @@ -93,8 +93,9 @@ public ArrayList load() throws DukeException { public void save(ArrayList patientTask) throws DukeException { try { BufferedWriter writer = Files.newBufferedWriter(Paths.get(filePath)); - CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT - .withHeader("PID", "TID", "DONE", "RECURRENCE", "DEADLINE", "STARTTIME", "ENDTIME", "TASKTYPE", "uuid")); + CSVPrinter csvPrinter = new CSVPrinter(writer, + CSVFormat.DEFAULT.withHeader("PID", "TID", "DONE", "RECURRENCE", + "DEADLINE", "STARTTIME", "ENDTIME", "TASKTYPE", "uuid")); for (PatientTask patient : patientTask) { int pid = patient.getPatientId(); int tid = patient.getTaskID(); From 1643a1c16321559fa4156b2929832c530af08e2e Mon Sep 17 00:00:00 2001 From: WEIFENG-NUSCEG Date: Sat, 19 Oct 2019 19:17:11 +0800 Subject: [PATCH 171/420] updated the storage saving to delete function --- data/patientsTasks.csv | 4 ++++ src/main/java/duke/command/DeletePatientTaskCommand.java | 2 ++ 2 files changed, 6 insertions(+) diff --git a/data/patientsTasks.csv b/data/patientsTasks.csv index bea1703c32..cdb90035f4 100644 --- a/data/patientsTasks.csv +++ b/data/patientsTasks.csv @@ -5,7 +5,11 @@ PID,TID,DONE,RECURRENCE,DEADLINE,STARTTIME,ENDTIME,TASKTYPE,uuid 1,3,false,false,09/08/2020 1200,,,S,5 1,3,false,false,09/05/2013 0900,,,S,9 1,3,false,false,,16/09/2019 1400,12/08/2020 1200,E,126 +1,3,false,false,09/11/2019 1400,,,S,20 +1,2,false,false,09/05/2018 1400,,,S,18 2,7,false,false,,09/01/2019 1200,08/11/2019 1000,E,3 2,7,false,false,09/05/2013 0150,,,S,11 2,7,false,false,,09/11/2018 1400,08/08/2019 1200,E,17 +2,7,false,false,,08/08/2018 1400,09/09/2019 1200,E,25 +2,7,false,false,,09/08/2019 1200,09/12/2019 1200,E,53 3,3,false,false,10/09/2011 1200,,,S,19 diff --git a/src/main/java/duke/command/DeletePatientTaskCommand.java b/src/main/java/duke/command/DeletePatientTaskCommand.java index ff2c3223b1..1a13b1d8ba 100644 --- a/src/main/java/duke/command/DeletePatientTaskCommand.java +++ b/src/main/java/duke/command/DeletePatientTaskCommand.java @@ -69,6 +69,7 @@ public void execute(PatientTaskList patientTaskList, TaskManager tasks, PatientM for (PatientTask patientTask: patientTaskList.getPatientTask(patientId)) { if (patientTask.getUid() == taskId) { patientTaskList.deletePatientTaskByUniqueId(taskId); + patientTaskStorage.save(patientTaskList.fullPatientTaskList()); ui.patientTaskDeleted(patientTask, toBeDeletedPatient); } } @@ -84,6 +85,7 @@ public void execute(PatientTaskList patientTaskList, TaskManager tasks, PatientM for (PatientTask patientTask: toBeDeleted) { if (patientTask.getUid() == taskId) { patientTaskList.deletePatientTaskByUniqueId(taskId); + patientTaskStorage.save(patientTaskList.fullPatientTaskList()); ui.patientTaskDeleted(patientTask, patientsWithSameName.get(0)); } } From cf5dda561d1d96f80fdcec5cb9cf0a01a4865e3c Mon Sep 17 00:00:00 2001 From: Qian Jie Date: Sat, 19 Oct 2019 19:19:59 +0800 Subject: [PATCH 172/420] refactored for code quality --- build/reports/checkstyle/main.html | 6 +-- build/reports/checkstyle/main.xml | 2 +- data/counter.csv | 5 +- data/patients.csv | 2 + data/standardTasks.csv | 5 ++ src/main/java/duke/Duke.java | 10 ++-- .../java/duke/command/AddPatientCommand.java | 10 +--- .../duke/command/AddStandardTaskCommand.java | 11 ++--- .../command/AssignTaskToPatientCommand.java | 10 +--- src/main/java/duke/command/Command.java | 6 +-- .../duke/command/DeletePatientCommand.java | 10 +--- .../java/duke/command/DeleteTaskCommand.java | 10 +--- src/main/java/duke/command/ExitCommand.java | 6 +-- .../java/duke/command/FindPatientCommand.java | 10 +--- .../duke/command/FindPatientTaskCommand.java | 11 +---- .../duke/command/ListPatientsCommand.java | 10 ++-- .../java/duke/command/ListTasksCommand.java | 9 +--- .../duke/command/UpdatePatientCommand.java | 10 +--- .../java/duke/command/UpdateTaskCommand.java | 10 +--- src/main/java/duke/core/CommandManager.java | 3 -- .../java/duke/statistic/CommandCounter.java | 30 ------------ src/main/java/duke/statistic/Counter.java | 48 +++++++++++++++++++ .../java/duke/storage/CounterStorage.java | 9 ++-- 23 files changed, 100 insertions(+), 143 deletions(-) delete mode 100644 src/main/java/duke/statistic/CommandCounter.java create mode 100644 src/main/java/duke/statistic/Counter.java diff --git a/build/reports/checkstyle/main.html b/build/reports/checkstyle/main.html index 96927409b3..15b60ddde3 100644 --- a/build/reports/checkstyle/main.html +++ b/build/reports/checkstyle/main.html @@ -160,7 +160,7 @@

Files

/Users/qianjie/Desktop/main/src/main/java/duke/relation/StandardPatientTask.java0 - /Users/qianjie/Desktop/main/src/main/java/duke/statistic/CommandCounter.java0 + /Users/qianjie/Desktop/main/src/main/java/duke/statistic/Counter.java0 /Users/qianjie/Desktop/main/src/main/java/duke/storage/CounterStorage.java0 @@ -364,8 +364,8 @@

File /Users/qianjie/Desktop/main/src/main/java/duke/relation/StandardPatient Error DescriptionLine - Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/statistic/CommandCounter.java

+ Back to top +

File /Users/qianjie/Desktop/main/src/main/java/duke/statistic/Counter.java

diff --git a/build/reports/checkstyle/main.xml b/build/reports/checkstyle/main.xml index 9c549b5eb6..8c72856fa6 100644 --- a/build/reports/checkstyle/main.xml +++ b/build/reports/checkstyle/main.xml @@ -52,7 +52,7 @@ - + diff --git a/data/counter.csv b/data/counter.csv index c31dff2bcb..063eefc8c8 100644 --- a/data/counter.csv +++ b/data/counter.csv @@ -1,4 +1,5 @@ Command Name,Frequency DeletePatientCommand,1 -AddStandardTaskCommand,1 -AddPatientCommand,1 +ListTasksCommand,1 +AddStandardTaskCommand,6 +AddPatientCommand,3 diff --git a/data/patients.csv b/data/patients.csv index 6b1bd23e42..a6c53b31b8 100644 --- a/data/patients.csv +++ b/data/patients.csv @@ -1,3 +1,5 @@ Id,Name,NRIC,Room,Remark 2,qianqian,s12312,a9,asd 3,qianjie,s12323,sd,123 +4,jkjdd,s12312,da,sdasd +5,jijij,s3123,dsad,dasdas diff --git a/data/standardTasks.csv b/data/standardTasks.csv index c4427c7cc6..b21110d211 100644 --- a/data/standardTasks.csv +++ b/data/standardTasks.csv @@ -3,3 +3,8 @@ Id,Description 4,123 5,321 6,123 +7,333 +8,5555 +9,123123 +10,qian +11,money diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index 39efc74b0d..63a67ed8e7 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -4,7 +4,7 @@ import duke.core.DukeException; import duke.core.CommandManager; import duke.patient.PatientManager; -import duke.statistic.CommandCounter; +import duke.statistic.Counter; import duke.storage.CounterStorage; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; @@ -33,7 +33,7 @@ public class Duke { private PatientTaskList patientTaskList; private TaskManager taskManager; private PatientManager patientManager; - private CommandCounter commandCounter; + private Counter counter; /** * A Ui object that deals with interactions with the user. @@ -57,7 +57,7 @@ public Duke(String filePath) { patientTaskList = new PatientTaskList(patientTaskStorage.load()); taskManager = new TaskManager(taskStorage.load()); patientManager = new PatientManager(patientStorage.load()); - commandCounter = new CommandCounter(counterStorage.load()); + counter = new Counter(counterStorage.load()); } catch (DukeException e) { ui.showLoadingError(); @@ -79,13 +79,15 @@ public void run() { ui.showLine(); Command c = CommandManager.manageCommand(fullCommand); c.execute(patientTaskList, taskManager, patientManager, - ui, patientTaskStorage, taskStorage, patientStorage, counterStorage, commandCounter); + ui, patientTaskStorage, taskStorage, patientStorage); + counter.runCommandCounter(c, counterStorage, counter); isExit = c.isExit(); } catch (DukeException e) { ui.showError(e.getMessage()); } finally { ui.showLine(); } + } System.exit(0); } diff --git a/src/main/java/duke/command/AddPatientCommand.java b/src/main/java/duke/command/AddPatientCommand.java index 34b3923077..b77eb70be0 100644 --- a/src/main/java/duke/command/AddPatientCommand.java +++ b/src/main/java/duke/command/AddPatientCommand.java @@ -1,11 +1,10 @@ package duke.command; -import duke.core.CommandManager; import duke.core.DukeException; import duke.core.Ui; import duke.patient.Patient; import duke.patient.PatientManager; -import duke.statistic.CommandCounter; +import duke.statistic.Counter; import duke.storage.CounterStorage; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; @@ -36,15 +35,10 @@ public AddPatientCommand(String[] patientInfo) throws DukeException { @Override public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, - PatientStorage patientStorage, CounterStorage counterStorage, - CommandCounter commandCounter) throws DukeException { + PatientStorage patientStorage) throws DukeException { - //this.hasBeenAddedBefore = true; - String commandName = this.getClass().getSimpleName(); - commandCounter.runCommandCounter(commandCounter.getCommandTable(), commandName); patientList.addPatient(newPatient); patientStorage.save(patientList.getPatientList()); - counterStorage.save(commandCounter.getCommandTable()); ui.patientAdded(newPatient); } diff --git a/src/main/java/duke/command/AddStandardTaskCommand.java b/src/main/java/duke/command/AddStandardTaskCommand.java index 8e3f421ae6..19f7b1a5f9 100644 --- a/src/main/java/duke/command/AddStandardTaskCommand.java +++ b/src/main/java/duke/command/AddStandardTaskCommand.java @@ -1,10 +1,9 @@ package duke.command; -import duke.core.CommandManager; import duke.core.DukeException; import duke.core.Ui; import duke.patient.PatientManager; -import duke.statistic.CommandCounter; +import duke.statistic.Counter; import duke.storage.CounterStorage; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; @@ -42,14 +41,10 @@ public AddStandardTaskCommand(String taskDescription) { @Override public void execute(PatientTaskList patientTask, TaskManager taskList, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, - PatientStorage patientStorage, CounterStorage counterStorage, - CommandCounter commandCounter) throws DukeException { - //this.hasBeenAddedBefore = true; - String commandName = this.getClass().getSimpleName(); - commandCounter.runCommandCounter(commandCounter.getCommandTable(), commandName); + PatientStorage patientStorage) throws DukeException { + taskList.addTask(newStandardTask); taskStorage.save(taskList.getTaskList()); - counterStorage.save(commandCounter.getCommandTable()); ui.taskAdded(newStandardTask); } diff --git a/src/main/java/duke/command/AssignTaskToPatientCommand.java b/src/main/java/duke/command/AssignTaskToPatientCommand.java index f05aa1b4d7..605b7cb4b3 100644 --- a/src/main/java/duke/command/AssignTaskToPatientCommand.java +++ b/src/main/java/duke/command/AssignTaskToPatientCommand.java @@ -1,12 +1,11 @@ package duke.command; -import duke.core.CommandManager; import duke.core.DukeException; import duke.core.Ui; import duke.patient.PatientManager; import duke.relation.EventPatientTask; import duke.relation.StandardPatientTask; -import duke.statistic.CommandCounter; +import duke.statistic.Counter; import duke.storage.CounterStorage; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; @@ -48,16 +47,11 @@ public AssignTaskToPatientCommand(String[] taskAssignmentInfo) throws DukeExcept @Override public void execute(PatientTaskList patientTaskList, TaskManager tasksList, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, - PatientStorage patientStorage, CounterStorage counterStorage, - CommandCounter commandCounter) throws DukeException { + PatientStorage patientStorage) throws DukeException { if (patientList.isExist(newPatientTask.getPatientId()) && tasksList.doesExist(newPatientTask.getTaskID())) { - - String commandName = this.getClass().getSimpleName(); - commandCounter.runCommandCounter(commandCounter.getCommandTable(), commandName); patientTaskList.addPatientTask(newPatientTask); patientTaskStorage.save(patientTaskList.fullPatientTaskList()); - counterStorage.save(commandCounter.getCommandTable()); ui.patientTaskAssigned(newPatientTask, patientList.getPatient(newPatientTask.getPatientId()).getName(), tasksList.getTask(newPatientTask.getTaskID()).getDescription()); } else { diff --git a/src/main/java/duke/command/Command.java b/src/main/java/duke/command/Command.java index 732203cae3..5a32e83add 100644 --- a/src/main/java/duke/command/Command.java +++ b/src/main/java/duke/command/Command.java @@ -1,11 +1,10 @@ package duke.command; -import duke.core.CommandManager; import duke.core.DukeException; import duke.core.Ui; import duke.patient.PatientManager; import duke.relation.PatientTaskList; -import duke.statistic.CommandCounter; +import duke.statistic.Counter; import duke.storage.CounterStorage; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; @@ -35,8 +34,7 @@ public abstract class Command { */ public abstract void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, - PatientStorage patientStorage, CounterStorage counterStorage, - CommandCounter commandCounter) throws DukeException; + PatientStorage patientStorage) throws DukeException; diff --git a/src/main/java/duke/command/DeletePatientCommand.java b/src/main/java/duke/command/DeletePatientCommand.java index 9bb7d7d5aa..9e1e2237fb 100644 --- a/src/main/java/duke/command/DeletePatientCommand.java +++ b/src/main/java/duke/command/DeletePatientCommand.java @@ -1,11 +1,10 @@ package duke.command; -import duke.core.CommandManager; import duke.core.DukeException; import duke.core.Ui; import duke.patient.Patient; import duke.patient.PatientManager; -import duke.statistic.CommandCounter; +import duke.statistic.Counter; import duke.storage.CounterStorage; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; @@ -54,11 +53,8 @@ public DeletePatientCommand(String deletedPatientInfo) throws DukeException { @Override public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientManager, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, - PatientStorage patientStorage, CounterStorage counterStorage, - CommandCounter commandCounter) throws DukeException { + PatientStorage patientStorage) throws DukeException { - String commandName = this.getClass().getSimpleName(); - commandCounter.runCommandCounter(commandCounter.getCommandTable(), commandName); if (id != 0) { Patient patientToBeDeleted = patientManager.getPatient(id); boolean toDelete = ui.confirmPatientToBeDeleted(patientToBeDeleted); @@ -66,7 +62,6 @@ public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManag patientManager.deletePatient(id); ui.patientDeleted(); patientStorage.save(patientManager.getPatientList()); - counterStorage.save(commandCounter.getCommandTable()); } } else { ArrayList patientsWithSameName = patientManager.getPatientByName(deletedPatientInfo); @@ -79,7 +74,6 @@ public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManag patientManager.deletePatient(patientsWithSameName.get(numberChosen - 1).getID()); ui.patientDeleted(); patientStorage.save(patientManager.getPatientList()); - counterStorage.save(commandCounter.getCommandTable()); } } } diff --git a/src/main/java/duke/command/DeleteTaskCommand.java b/src/main/java/duke/command/DeleteTaskCommand.java index d22af0f331..33954bd4c8 100644 --- a/src/main/java/duke/command/DeleteTaskCommand.java +++ b/src/main/java/duke/command/DeleteTaskCommand.java @@ -1,10 +1,9 @@ package duke.command; -import duke.core.CommandManager; import duke.core.DukeException; import duke.core.Ui; import duke.patient.PatientManager; -import duke.statistic.CommandCounter; +import duke.statistic.Counter; import duke.storage.CounterStorage; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; @@ -53,10 +52,7 @@ public DeleteTaskCommand(String deletedTaskInfo) throws DukeException { @Override public void execute(PatientTaskList patientTask, TaskManager taskManager, PatientManager patientManager, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, - PatientStorage patientStorage, CounterStorage counterStorage, - CommandCounter commandCounter) throws DukeException { - String commandName = this.getClass().getSimpleName(); - commandCounter.runCommandCounter(commandCounter.getCommandTable(), commandName); + PatientStorage patientStorage) throws DukeException { if (id != 0) { Task taskToBeDeleted = taskManager.getTask(id); boolean toDelete = ui.confirmTaskToBeDeleted(taskToBeDeleted); @@ -64,7 +60,6 @@ public void execute(PatientTaskList patientTask, TaskManager taskManager, Patien taskManager.deleteTask(id); ui.taskDeleted(); taskStorage.save(taskManager.getTaskList()); - counterStorage.save(commandCounter.getCommandTable()); } } else { ArrayList tasksWithSameDescription = taskManager.getTaskByDescription(deletedTaskInfo); @@ -77,7 +72,6 @@ public void execute(PatientTaskList patientTask, TaskManager taskManager, Patien taskManager.deleteTask(tasksWithSameDescription.get(numberChosen - 1).getID()); ui.taskDeleted(); taskStorage.save(taskManager.getTaskList()); - counterStorage.save(commandCounter.getCommandTable()); } } } diff --git a/src/main/java/duke/command/ExitCommand.java b/src/main/java/duke/command/ExitCommand.java index 67510af88b..76984f45a8 100644 --- a/src/main/java/duke/command/ExitCommand.java +++ b/src/main/java/duke/command/ExitCommand.java @@ -1,9 +1,8 @@ package duke.command; -import duke.core.CommandManager; import duke.core.DukeException; import duke.patient.PatientManager; -import duke.statistic.CommandCounter; +import duke.statistic.Counter; import duke.storage.CounterStorage; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; @@ -45,8 +44,7 @@ public boolean isExit() { */ public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, - TaskStorage taskStorage, PatientStorage patientStorage, CounterStorage counterStorage, - CommandCounter commandCounter) throws DukeException { + TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { ui.exitInformation(); } } \ No newline at end of file diff --git a/src/main/java/duke/command/FindPatientCommand.java b/src/main/java/duke/command/FindPatientCommand.java index 88fe1178b4..19daa25d33 100644 --- a/src/main/java/duke/command/FindPatientCommand.java +++ b/src/main/java/duke/command/FindPatientCommand.java @@ -1,11 +1,10 @@ package duke.command; -import duke.core.CommandManager; import duke.core.DukeException; import duke.core.Ui; import duke.patient.Patient; import duke.patient.PatientManager; -import duke.statistic.CommandCounter; +import duke.statistic.Counter; import duke.storage.CounterStorage; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; @@ -38,10 +37,7 @@ public FindPatientCommand(String command) { @Override public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientManager, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, - PatientStorage patientStorage, CounterStorage counterStorage, - CommandCounter commandCounter) throws DukeException { - String commandName = this.getClass().getSimpleName(); - commandCounter.runCommandCounter(commandCounter.getCommandTable(), commandName); + PatientStorage patientStorage) throws DukeException { char firstChar = command.charAt(0); if (firstChar == '#') { int id; @@ -51,11 +47,9 @@ public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManag throw new DukeException("Please follow the format 'find patient #' or 'find patient '."); } Patient patient = patientManager.getPatient(id); - counterStorage.save(commandCounter.getCommandTable()); ui.patientsFoundById(patient); } else { ArrayList patientsWithSameName = patientManager.getPatientByName(command); - counterStorage.save(commandCounter.getCommandTable()); ui.patientsFoundByName(patientsWithSameName, command); } } diff --git a/src/main/java/duke/command/FindPatientTaskCommand.java b/src/main/java/duke/command/FindPatientTaskCommand.java index 2e3f5fa284..70ea89359e 100644 --- a/src/main/java/duke/command/FindPatientTaskCommand.java +++ b/src/main/java/duke/command/FindPatientTaskCommand.java @@ -1,13 +1,12 @@ package duke.command; -import duke.core.CommandManager; import duke.core.DukeException; import duke.core.Ui; import duke.patient.Patient; import duke.patient.PatientManager; import duke.relation.PatientTask; import duke.relation.PatientTaskList; -import duke.statistic.CommandCounter; +import duke.statistic.Counter; import duke.storage.CounterStorage; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; @@ -46,10 +45,7 @@ public FindPatientTaskCommand(String cmd) { @Override public void execute(PatientTaskList patientTaskList, TaskManager tasksManager, PatientManager patientManager, Ui ui, PatientTaskStorage patientTaskStorage, - TaskStorage taskStorage, PatientStorage patientStorage, CounterStorage counterStorage, - CommandCounter commandCounter) throws DukeException { - String commandName = this.getClass().getSimpleName(); - commandCounter.runCommandCounter(commandCounter.getCommandTable(), commandName); + TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { char firstChar = command.charAt(0); if (firstChar == '#') { int id; @@ -61,7 +57,6 @@ public void execute(PatientTaskList patientTaskList, TaskManager tasksManager, P for (PatientTask temppatientTask : patientTask) { tempTask.add(tasksManager.getTask(temppatientTask.getTaskID())); } - counterStorage.save(commandCounter.getCommandTable()); ui.patientTaskFound(patient, patientTask, tempTask); } catch (Exception e) { throw new DukeException("Please follow the format 'find patienttask #' or 'find patient '."); @@ -80,9 +75,7 @@ public void execute(PatientTaskList patientTaskList, TaskManager tasksManager, P } for (PatientTask temppatientTask : patientWithTask) { tempTask.add(tasksManager.getTask(temppatientTask.getTaskID())); - //System.out.println(temppatientTask.getTaskID() + "\n"); } - counterStorage.save(commandCounter.getCommandTable()); ui.patientTaskFound(patientsWithSameName.get(0), patientWithTask, tempTask); } catch (Exception e) { throw new DukeException(e.getMessage() diff --git a/src/main/java/duke/command/ListPatientsCommand.java b/src/main/java/duke/command/ListPatientsCommand.java index 54d4d4a525..509c4924b4 100644 --- a/src/main/java/duke/command/ListPatientsCommand.java +++ b/src/main/java/duke/command/ListPatientsCommand.java @@ -1,11 +1,10 @@ package duke.command; -import duke.core.CommandManager; import duke.core.DukeException; import duke.core.Ui; import duke.patient.Patient; import duke.patient.PatientManager; -import duke.statistic.CommandCounter; +import duke.statistic.Counter; import duke.storage.CounterStorage; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; @@ -36,12 +35,9 @@ public ListPatientsCommand() { @Override public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, - TaskStorage taskStorage, PatientStorage patientStorage, CounterStorage counterStorage, - CommandCounter commandCounter) throws DukeException { - String commandName = this.getClass().getSimpleName(); - commandCounter.runCommandCounter(commandCounter.getCommandTable(), commandName); + TaskStorage taskStorage, PatientStorage patientStorage) { + ArrayList list = patientList.getPatientList(); - counterStorage.save(commandCounter.getCommandTable()); ui.listAllPatients(list); } diff --git a/src/main/java/duke/command/ListTasksCommand.java b/src/main/java/duke/command/ListTasksCommand.java index 95fde2ead3..06c0298892 100644 --- a/src/main/java/duke/command/ListTasksCommand.java +++ b/src/main/java/duke/command/ListTasksCommand.java @@ -1,10 +1,9 @@ package duke.command; -import duke.core.CommandManager; import duke.core.DukeException; import duke.core.Ui; import duke.patient.PatientManager; -import duke.statistic.CommandCounter; +import duke.statistic.Counter; import duke.storage.CounterStorage; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; @@ -32,12 +31,8 @@ public class ListTasksCommand extends Command { @Override public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, - PatientStorage patientStorage, CounterStorage counterStorage, - CommandCounter commandCounter) throws DukeException { - String commandName = this.getClass().getSimpleName(); - commandCounter.runCommandCounter(commandCounter.getCommandTable(), commandName); + PatientStorage patientStorage) { ArrayList list = tasks.getTaskList(); - counterStorage.save(commandCounter.getCommandTable()); ui.listAllTasks(list); } diff --git a/src/main/java/duke/command/UpdatePatientCommand.java b/src/main/java/duke/command/UpdatePatientCommand.java index 32832dc46f..d2e9e33ee4 100644 --- a/src/main/java/duke/command/UpdatePatientCommand.java +++ b/src/main/java/duke/command/UpdatePatientCommand.java @@ -1,11 +1,10 @@ package duke.command; -import duke.core.CommandManager; import duke.core.DukeException; import duke.core.Ui; import duke.patient.Patient; import duke.patient.PatientManager; -import duke.statistic.CommandCounter; +import duke.statistic.Counter; import duke.storage.CounterStorage; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; @@ -41,10 +40,7 @@ public UpdatePatientCommand(String command) { @Override public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientManager, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, - PatientStorage patientStorage, CounterStorage counterStorage, - CommandCounter commandCounter) throws DukeException { - String commandName = this.getClass().getSimpleName(); - commandCounter.runCommandCounter(commandCounter.getCommandTable(), commandName); + PatientStorage patientStorage) throws DukeException { String[] tempCommand = command.split(" ", 3); char firstChar = tempCommand[0].charAt(0); if (firstChar == '#') { @@ -63,8 +59,6 @@ public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManag } patientStorage.save(patientManager.getPatientList()); - counterStorage.save(commandCounter.getCommandTable()); - ui.showUpdatedSuccessfully(); ui.showPatientInfo(patientToBeUpdated); } catch (Exception e) { diff --git a/src/main/java/duke/command/UpdateTaskCommand.java b/src/main/java/duke/command/UpdateTaskCommand.java index cca5c4f680..35e54a5d66 100644 --- a/src/main/java/duke/command/UpdateTaskCommand.java +++ b/src/main/java/duke/command/UpdateTaskCommand.java @@ -1,9 +1,8 @@ package duke.command; -import duke.core.CommandManager; import duke.core.DukeException; import duke.core.Ui; -import duke.statistic.CommandCounter; +import duke.statistic.Counter; import duke.storage.CounterStorage; import duke.task.Task; import duke.patient.PatientManager; @@ -40,10 +39,7 @@ public UpdateTaskCommand(String command) { @Override public void execute(PatientTaskList patientTask, TaskManager taskManager, PatientManager patientManager, Ui ui, PatientTaskStorage patientTaskStorage, - TaskStorage taskStorage, PatientStorage patientStorage, CounterStorage counterStorage, - CommandCounter commandCounter) throws DukeException { - String commandName = this.getClass().getSimpleName(); - commandCounter.runCommandCounter(commandCounter.getCommandTable(), commandName); + TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { String[] tempCommand = command.split(" ", 3); char firstChar = tempCommand[0].charAt(0); if (firstChar == '#') { @@ -58,8 +54,6 @@ public void execute(PatientTaskList patientTask, TaskManager taskManager, Patien } taskStorage.save(taskManager.getTaskList()); - counterStorage.save(commandCounter.getCommandTable()); - ui.showUpdatedSuccessfully(); ui.showTaskInfo(taskToBeUpdated); } catch (Exception e) { diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 5d9f9a0e3e..8ad1b98ad2 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -14,9 +14,6 @@ import duke.command.UpdatePatientCommand; import duke.command.UpdateTaskCommand; -import java.util.Map; - - /** * Represents a Parser that parses user input into a specific * type of Command. diff --git a/src/main/java/duke/statistic/CommandCounter.java b/src/main/java/duke/statistic/CommandCounter.java deleted file mode 100644 index 129ca0fa15..0000000000 --- a/src/main/java/duke/statistic/CommandCounter.java +++ /dev/null @@ -1,30 +0,0 @@ -package duke.statistic; - -import java.util.Map; - -public class CommandCounter { - private Map commandTable; - - public CommandCounter(Map commandTable) { - this.commandTable = commandTable; - } - - public Map getCommandTable() { - return commandTable; - } - - /** - * This function is used to run the command counter. - * @param commandTable a table with command name as key and count as value - * @param commandName the command name that was used - * @author QIAN JIE - * @version 1.3 - */ - public void runCommandCounter(Map commandTable, String commandName) { - int count = commandTable.containsKey(commandName) - ? commandTable.get(commandName) : 0; - commandTable.put(commandName, count + 1); - } - - -} diff --git a/src/main/java/duke/statistic/Counter.java b/src/main/java/duke/statistic/Counter.java new file mode 100644 index 0000000000..7a441d137b --- /dev/null +++ b/src/main/java/duke/statistic/Counter.java @@ -0,0 +1,48 @@ +package duke.statistic; + +import duke.command.Command; +import duke.core.DukeException; +import duke.storage.CounterStorage; + +import java.util.Map; + +/** + * This is a Counter class that mainly used for counting purpose + * which can then to be used for relevant application. + * + * @author QIAN JIE + * @version 1.3 + */ +public class Counter { + private Map commandTable; + + public Counter(Map commandTable) { + this.commandTable = commandTable; + } + + public Map getCommandTable() { + return commandTable; + } + + /** + * This function is used to run the command counter. + * + * @param command the command type that is being processed + * @param counterStorage get the counterStorage object + * @param counter get the Counter object + * @author QIAN JIE + * @version 1.3 + */ + + public void runCommandCounter(Command command, CounterStorage counterStorage, + Counter counter) throws DukeException { + String commandName = command.getClass().getSimpleName(); + + int count = commandTable.containsKey(commandName) + ? commandTable.get(commandName) : 0; + commandTable.put(commandName, count + 1); + counterStorage.save(counter.getCommandTable()); + } + + +} diff --git a/src/main/java/duke/storage/CounterStorage.java b/src/main/java/duke/storage/CounterStorage.java index 9e0f39c7b5..b19cb6eb64 100644 --- a/src/main/java/duke/storage/CounterStorage.java +++ b/src/main/java/duke/storage/CounterStorage.java @@ -41,10 +41,10 @@ public CounterStorage(String filePath) { } /** - * Load the task info with associated patient from local csv files. + * Load the command counter table from local csv files. * - * @return A arrayList of PatientTask which contain info of task with associated patient - * @throws DukeException throw a dukeException with error message for debugging + * @return A Map with key being the command name and value being the counts. + * @throws DukeException throw a dukeException with error message for debugging. */ public Map load() throws DukeException { Map cmdFreqTable = new HashMap<>(); @@ -61,7 +61,6 @@ public Map load() throws DukeException { cmdFreqTable.put(commandName, frequency); } } - System.out.println("Load completed"); return cmdFreqTable; } catch (Exception e) { throw new DukeException("Loading of " @@ -72,7 +71,7 @@ public Map load() throws DukeException { } /** - * Write the patients' info to local csv files. + * Write the key value set of command count table info to local csv files. * * @param cmdFreqTable A list of patients containing info of patients to be written * @throws DukeException throw exception with error message when i/o fails From 516a8fbed92f7d0f4a8d508fbae4b62e0976763a Mon Sep 17 00:00:00 2001 From: WEIFENG-NUSCEG Date: Sat, 19 Oct 2019 19:24:22 +0800 Subject: [PATCH 173/420] delete the parsertest as it need to be reworked --- src/test/java/duke/core/ParserTest.java | 102 ------------------------ 1 file changed, 102 deletions(-) delete mode 100644 src/test/java/duke/core/ParserTest.java diff --git a/src/test/java/duke/core/ParserTest.java b/src/test/java/duke/core/ParserTest.java deleted file mode 100644 index 1f3995349a..0000000000 --- a/src/test/java/duke/core/ParserTest.java +++ /dev/null @@ -1,102 +0,0 @@ -package duke.core; - -import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertTrue; - -public class ParserTest { - - String patientDummyInput = "add patient name NRIC room remark"; - String taskDummyInput = "add task Walk the dog"; - - String assignPatientIdToTaskS = "assign by id: S 1 2 02/02/2002 2222"; - String assignPatientIdToTaskE = "assign by id: E 2 1 02/02/2002 2222 to 03/02/2002 1234"; - - String deletePatientInputWithID = "delete patient #123"; - String deletePatientInputWithName = "delete patient billy joe"; - String deleteTaskInputWithID = "delete task 10"; - String deleteTaskInputWithName = "delete task Take medicine"; - - @Test - public void parseAddPatientTest() throws DukeException { - Parser testParser = new Parser(patientDummyInput); - String[] testOutput = testParser.parseAdd(); - - assertTrue(testOutput[0].equals("name"), - "Name field did not parse correctly. Expected: 'name', but got: " + testOutput[0]); - assertTrue(testOutput[1].equals("NRIC"), - "NRIC field did not parse correctly. Expected: 'NRIC', but got: " + testOutput[1]); - assertTrue(testOutput[2].equals("room"), - "Room field did not parse correctly. Expected: 'room', but got: " + testOutput[2]); - assertTrue(testOutput[3].equals("remark"), - "Remark field did not parse correctly. Expected: 'remark', but got: " + testOutput[3]); - - } - - @Test - public void parseAddTask() throws DukeException { - Parser testParser = new Parser(taskDummyInput); - String[] testOutput = testParser.parseAdd(); - - assertTrue(testOutput[0].equals("Walk the dog"), - "Task description did not parse correctly. Expected 'Walk the dog' but got: " + testOutput[0]); - } - - @Test - public void parseAssignPatientByID() throws DukeException { - Parser testParserStandard = new Parser(assignPatientIdToTaskS); - Parser testParserEvent = new Parser(assignPatientIdToTaskE); - - final String[] testOutputStandard = testParserStandard.parseAssign(); - final String[] testOutputEvent = testParserEvent.parseAssign(); - - assertTrue(testOutputStandard[0].equals("S"), - "Task type parsed incorrectly. Expected 'S' but got: " + testOutputStandard[0]); - assertTrue(testOutputStandard[1].equals("1") && testOutputStandard[2].equals("2"), - "IDs parsed incorrectly.\n" - + "Expected patient ID of 1, and got: " + testOutputStandard[1] - + ".\n Expected task ID of 2 and got: " + testOutputStandard[2]); - assertTrue(testOutputStandard[3].equals("02/02/2002 2222")); - - assertTrue(testOutputEvent[0].equals("E"), - "Task type parsed incorrectly. Expected 'E' but got: " + testOutputEvent[0]); - assertTrue(testOutputEvent[1].equals("2") && testOutputEvent[2].equals("1"), - "IDs parsed incorrectly.\n" - + "Expected patient ID of 2, and got: " - + testOutputEvent[1] + ".\n Expected task ID of 1 and got: " + testOutputEvent[2]); - assertTrue(testOutputEvent[3].equals("02/02/2002 2222"), - "Start date parsed incorrectly. Expected '02/02/2002 2222' but got: " + testOutputEvent[3]); - assertTrue(testOutputEvent[4].equals("03/02/2002 1234"), - "End date parsed incorrectly. Expected '03/02/2002 1234' but got: " + testOutputEvent[4]); - } - - @Test - public void parseDeletePatient() throws DukeException { - Parser testParserID = new Parser(deletePatientInputWithID); - Parser testParserName = new Parser(deletePatientInputWithName); - - String testOutputID = testParserID.parseDeletePatient(); - String testOutputName = testParserName.parseDeletePatient(); - - assertTrue(testOutputID.charAt(0) == '#' && testOutputID.equals("#123"), - "Delete patient by ID parsing failed. Expected '#123' but got: " + testOutputID); - assertTrue(testOutputName.equals("billy joe"), - "Delete patient by name parsing failed. Expected 'billy joe' but got: " + testOutputName); - } - - @Test - public void parseDeleteTask() throws DukeException { - Parser testParserID = new Parser(deleteTaskInputWithID); - Parser testParserName = new Parser(deleteTaskInputWithName); - - String testOutputID = testParserID.parseDeleteTask(); - String testOutputName = testParserName.parseDeleteTask(); - - - /*assertTrue(testOutputID.charAt(0) == '#' && testOutputID.equals("#10"), - "Delete task by ID parsing failed. Expected '#10' but got: " + testOutputID);*/ - assertTrue(testOutputName.equals("Take medicine"), - "Delete task by name parsing failed. Expected 'Take medicine' but got: " + testOutputName); - } - - -} From e780f1e00006414029cb4a9196d4132bed7b4c5b Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Sat, 19 Oct 2019 22:22:07 +0800 Subject: [PATCH 174/420] Update application of typo corrector --- src/main/java/duke/core/CommandManager.java | 10 ++++++---- src/main/java/duke/core/TypoCorrector.java | 3 ++- src/main/java/duke/core/Ui.java | 22 +++++++++++++++++++++ 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 849563d62a..8c4f635584 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -28,6 +28,12 @@ public class CommandManager { */ public static Command manageCommand(String userInput) throws DukeException { userInput = userInput.trim(); + String possibleCommand = TypoCorrector.commandCorrection(userInput); + if (!possibleCommand.equals(userInput)) { + if (Ui.getUi().confirmTypoCorrection(possibleCommand, userInput)) { + userInput = possibleCommand; + } + } String[] command = userInput.split("\\s+", 3); String firstKeyword = command[0].toLowerCase(); Parser parser = new Parser(userInput); @@ -111,10 +117,6 @@ public static Command manageCommand(String userInput) throws DukeException { case "bye": return new ExitCommand(); default: - String possibleCommand = TypoCorrector.commandCorrection(userInput); - if (!possibleCommand.equals(userInput)) { - throw new DukeException("Could not understand user input. Did you mean: \n" + possibleCommand); - } throw new DukeException("Could not understand user input"); } } diff --git a/src/main/java/duke/core/TypoCorrector.java b/src/main/java/duke/core/TypoCorrector.java index aabaa38683..c0d909758c 100644 --- a/src/main/java/duke/core/TypoCorrector.java +++ b/src/main/java/duke/core/TypoCorrector.java @@ -25,7 +25,8 @@ public class TypoCorrector { Arrays.asList("list patients", "list tasks")); private static final ArrayList otherCommands = new ArrayList( Arrays.asList("update patient", "update task", - "delete patient", "delete task", "add task", "add patient", "assign by")); + "delete patient", "delete task", "add task", "add patient", + "assign by", "find patient", "find task")); /** * This method take in an user input command with typo and return a possible matches diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index 89aa887b9e..58bb550df4 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -325,6 +325,28 @@ public boolean confirmTaskToBeDeleted(Task task) { } } + /** + * It confirms with user on the deletion of a task. + * If user confirms, key in 'Y'. Otherwise key in 'N'. + * + * @param correctedCommand the correctedCommand + * @return true if user confirmed the deletion. False otherwise. + */ + public boolean confirmTypoCorrection(String correctedCommand, String userInput) { + System.out.println("Ambiguous format! Did you mean(Y/N): \n" + correctedCommand); + while (true) { + String command = readCommand(); + if (command.toLowerCase().equals("y")) { + return true; + } else if (command.toLowerCase().equals("n")) { + System.out.println("Proceed with original command: " + userInput); + return false; + } else { + System.out.println("Please enter only Y/N to proceed with recommended command: " + correctedCommand); + } + } + } + /** * Shows a divider line. */ From a4fa8ad6f5e1b8c4de0009d2482118c887cd651a Mon Sep 17 00:00:00 2001 From: WEIFENG-NUSCEG Date: Sun, 20 Oct 2019 01:09:55 +0800 Subject: [PATCH 175/420] The unique id of assigned tasks to a patient are previously decided by the user manually, now the PatienttaskList is able to auto generate it --- data/patients.csv | 2 +- data/patientsTasks.csv | 28 ++--- data/standardTasks.csv | 6 +- .../command/AssignTaskToPatientCommand.java | 43 ++++---- .../duke/command/FindPatientTaskCommand.java | 4 +- src/main/java/duke/core/Parser.java | 7 +- .../java/duke/relation/EventPatientTask.java | 10 +- src/main/java/duke/relation/PatientTask.java | 17 ++- .../java/duke/relation/PatientTaskList.java | 13 +++ .../duke/relation/StandardPatientTask.java | 8 +- .../java/duke/storage/PatientTaskStorage.java | 5 +- src/test/java/duke/core/ParserTest.java | 103 ++++++++++++++++++ 12 files changed, 183 insertions(+), 63 deletions(-) create mode 100644 src/test/java/duke/core/ParserTest.java diff --git a/data/patients.csv b/data/patients.csv index 02e0735d33..17442480af 100644 --- a/data/patients.csv +++ b/data/patients.csv @@ -1,4 +1,4 @@ Id,Name,NRIC,Room,Remark 1,xk,G00012345,38A,no 2,weifeng,G789456,8B,no -3,Qianjie,G123456,2c,no \ No newline at end of file +3,Qianjie,G123456,2c,noQ \ No newline at end of file diff --git a/data/patientsTasks.csv b/data/patientsTasks.csv index cdb90035f4..566b9b14fc 100644 --- a/data/patientsTasks.csv +++ b/data/patientsTasks.csv @@ -1,15 +1,15 @@ PID,TID,DONE,RECURRENCE,DEADLINE,STARTTIME,ENDTIME,TASKTYPE,uuid -1,2,false,false,09/11/2019 1400,,,S,0 -1,3,false,false,09/01/2018 1200,,,S,1 -1,3,false,false,04/04/2019 1400,,,S,2 -1,3,false,false,09/08/2020 1200,,,S,5 -1,3,false,false,09/05/2013 0900,,,S,9 -1,3,false,false,,16/09/2019 1400,12/08/2020 1200,E,126 -1,3,false,false,09/11/2019 1400,,,S,20 -1,2,false,false,09/05/2018 1400,,,S,18 -2,7,false,false,,09/01/2019 1200,08/11/2019 1000,E,3 -2,7,false,false,09/05/2013 0150,,,S,11 -2,7,false,false,,09/11/2018 1400,08/08/2019 1200,E,17 -2,7,false,false,,08/08/2018 1400,09/09/2019 1200,E,25 -2,7,false,false,,09/08/2019 1200,09/12/2019 1200,E,53 -3,3,false,false,10/09/2011 1200,,,S,19 +1,2,false,false,09/11/2019 1400,,,S,1 +1,3,false,false,09/01/2018 1200,,,S,2 +1,3,false,false,04/04/2019 1400,,,S,3 +1,3,false,false,09/08/2020 1200,,,S,4 +1,3,false,false,09/05/2013 0900,,,S,5 +1,3,false,false,,16/09/2019 1400,12/08/2020 1200,E,6 +1,3,false,false,09/11/2019 1400,,,S,7 +1,2,false,false,09/05/2018 1400,,,S,8 +2,7,false,false,,09/01/2019 1200,08/11/2019 1000,E,9 +2,7,false,false,09/05/2013 0150,,,S,10 +2,7,false,false,,09/11/2018 1400,08/08/2019 1200,E,11 +2,7,false,false,,08/08/2018 1400,09/09/2019 1200,E,12 +2,7,false,false,,09/08/2019 1200,09/12/2019 1200,E,13 +3,8,false,false,09/01/2022 1400,,,S,15 diff --git a/data/standardTasks.csv b/data/standardTasks.csv index 1f2cde8fe4..954ca3b021 100644 --- a/data/standardTasks.csv +++ b/data/standardTasks.csv @@ -2,4 +2,8 @@ Id,Description 1,Take_Medicine A 2,Do_surgery 3,Take_shit -7,happy \ No newline at end of file +4,happy +5,GOOD +6,haha +7,getout +8,wake_up \ No newline at end of file diff --git a/src/main/java/duke/command/AssignTaskToPatientCommand.java b/src/main/java/duke/command/AssignTaskToPatientCommand.java index 1a2bfdabf0..efc2a37553 100644 --- a/src/main/java/duke/command/AssignTaskToPatientCommand.java +++ b/src/main/java/duke/command/AssignTaskToPatientCommand.java @@ -43,46 +43,43 @@ public AssignTaskToPatientCommand(String[] taskAssignmentInfo) throws DukeExcept public void execute(PatientTaskList patientTaskList, TaskManager tasksList, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { - char firstChar = taskAssignmentInfo[2].charAt(0); + char firstChar = taskAssignmentInfo[1].charAt(0); try { if (taskAssignmentInfo[0].equals("S")) { if (firstChar == '#') { - int tempUid = Integer.parseInt(taskAssignmentInfo[1]); - int tempPid = Integer.parseInt(taskAssignmentInfo[2].replace("#","").trim()); - int tempTid = Integer.parseInt(taskAssignmentInfo[3]); - String temptime = taskAssignmentInfo[4]; - newPatientTask = new StandardPatientTask(tempPid, tempTid, temptime, taskAssignmentInfo[0],tempUid); + int tempPid = Integer.parseInt(taskAssignmentInfo[1].replace("#","").trim()); + int tempTid = Integer.parseInt(taskAssignmentInfo[2]); + String temptime = taskAssignmentInfo[3]; + newPatientTask = new StandardPatientTask(tempPid, tempTid, temptime, taskAssignmentInfo[0]); } else { - int tempUid = Integer.parseInt(taskAssignmentInfo[1]); - int tempPid = patientList.getPatientByName(taskAssignmentInfo[2]).get(0).getID(); - int tempTid = tasksList.getTaskByDescription(taskAssignmentInfo[3]).get(0).getID(); - String temptime = taskAssignmentInfo[4]; - newPatientTask = new StandardPatientTask(tempPid, tempTid, temptime, taskAssignmentInfo[0],tempUid); + int tempPid = patientList.getPatientByName(taskAssignmentInfo[1]).get(0).getID(); + int tempTid = tasksList.getTaskByDescription(taskAssignmentInfo[2]).get(0).getID(); + String temptime = taskAssignmentInfo[3]; + newPatientTask = new StandardPatientTask(tempPid, tempTid, temptime, taskAssignmentInfo[0]); } } else if (taskAssignmentInfo[0].equals("E")) { if (firstChar == '#') { - int tempUid = Integer.parseInt(taskAssignmentInfo[1]); - int tempPid = Integer.parseInt(taskAssignmentInfo[2].replace("#","").trim()); - int tempTid = Integer.parseInt(taskAssignmentInfo[3]); - String stime = taskAssignmentInfo[4].split(" to ", 2)[0]; - String etime = taskAssignmentInfo[4].split(" to ", 2)[1]; + int tempPid = Integer.parseInt(taskAssignmentInfo[1].replace("#","").trim()); + int tempTid = Integer.parseInt(taskAssignmentInfo[2]); + String stime = taskAssignmentInfo[3].split(" to ", 2)[0]; + String etime = taskAssignmentInfo[3].split(" to ", 2)[1]; newPatientTask = new EventPatientTask(tempPid, tempTid, stime, etime, - taskAssignmentInfo[0],tempUid); + taskAssignmentInfo[0]); } else { - int tempUid = Integer.parseInt(taskAssignmentInfo[1]); - int tempPid = patientList.getPatientByName(taskAssignmentInfo[2]).get(0).getID(); - int tempTid = tasksList.getTaskByDescription(taskAssignmentInfo[3]).get(0).getID(); - String stime = taskAssignmentInfo[4].split(" to ", 2)[0]; - String etime = taskAssignmentInfo[4].split(" to ", 2)[1]; + int tempPid = patientList.getPatientByName(taskAssignmentInfo[1]).get(0).getID(); + int tempTid = tasksList.getTaskByDescription(taskAssignmentInfo[2]).get(0).getID(); + String stime = taskAssignmentInfo[3].split(" to ", 2)[0]; + String etime = taskAssignmentInfo[3].split(" to ", 2)[1]; newPatientTask = new EventPatientTask(tempPid, tempTid, stime, etime, - taskAssignmentInfo[0],tempUid); + taskAssignmentInfo[0]); } } else { throw new DukeException("Wrong format is detected!"); } } catch (Exception e) { + e.printStackTrace(); throw new DukeException("You are missing some information!"); } diff --git a/src/main/java/duke/command/FindPatientTaskCommand.java b/src/main/java/duke/command/FindPatientTaskCommand.java index f30e1a82cd..9aa24ed3e3 100644 --- a/src/main/java/duke/command/FindPatientTaskCommand.java +++ b/src/main/java/duke/command/FindPatientTaskCommand.java @@ -77,9 +77,9 @@ public void execute(PatientTaskList patientTaskList, TaskManager tasksManager, P } ui.patientTaskFound(patientsWithSameName.get(0), patientWithTask, tempTask); + } catch (Exception e) { - throw new DukeException(e.getMessage() - + "Please follow the format 'find patienttask #' or 'find patient '."); + throw new DukeException("Please follow the format 'find patienttask #' or 'find patient '."); } } } diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index d727b839a1..485394cf4b 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -62,13 +62,12 @@ public String[] parseDeletePatientTask() throws DukeException { * @throws DukeException . */ public String[] parseAssign() throws DukeException { - String[] formattedInput = new String[5]; + String[] formattedInput = new String[4]; try { - String[] parsedCommand = userInput.toLowerCase().split("\\s+", 6); - formattedInput[1] = parsedCommand[2].replace("id", "").trim(); + String[] parsedCommand = userInput.toLowerCase().split("\\s+", 5); + formattedInput[1] = parsedCommand[2]; formattedInput[2] = parsedCommand[3]; formattedInput[3] = parsedCommand[4]; - formattedInput[4] = parsedCommand[5]; if (parsedCommand[1].equals("eventtask")) { formattedInput[0] = "E"; } else if (parsedCommand[1].equals("standardtask")) { diff --git a/src/main/java/duke/relation/EventPatientTask.java b/src/main/java/duke/relation/EventPatientTask.java index fca2449e0e..f1438b6684 100644 --- a/src/main/java/duke/relation/EventPatientTask.java +++ b/src/main/java/duke/relation/EventPatientTask.java @@ -22,10 +22,9 @@ public class EventPatientTask extends PatientTask { * @param stime . * @param etime . * @param type . - * @param uid . */ - public EventPatientTask(int pid, int tid, String stime, String etime, String type, int uid) { - super(pid, tid, type, uid); + public EventPatientTask(int pid, int tid, String stime, String etime, String type) { + super(pid, tid, type); this.startTimeRaw = stime; this.endTimeRaw = etime; try { @@ -48,11 +47,10 @@ public EventPatientTask(int pid, int tid, String stime, String etime, String typ * @param stime . * @param etime . * @param type . - * @param uid . */ public EventPatientTask(int pid, int tid, boolean isDone, - boolean isRecurrsive, String stime, String etime, String type, int uid) { - super(pid, tid, isDone, isRecurrsive, type, uid); + boolean isRecurrsive, String stime, String etime, String type) { + super(pid, tid, isDone, isRecurrsive, type); this.startTimeRaw = stime; this.endTimeRaw = etime; try { diff --git a/src/main/java/duke/relation/PatientTask.java b/src/main/java/duke/relation/PatientTask.java index 9a4a99ce97..74f5245dc1 100644 --- a/src/main/java/duke/relation/PatientTask.java +++ b/src/main/java/duke/relation/PatientTask.java @@ -3,7 +3,7 @@ public abstract class PatientTask { private Integer patientId; private Integer taskID; - private Integer uuid; + private Integer uuid = 0; private boolean isDone = false; private boolean isRecurrsive = false; private String taskType; @@ -15,11 +15,19 @@ public abstract class PatientTask { * @param tid . * @param type . */ - public PatientTask(int pid, int tid, String type, int uid) { + public PatientTask(int pid, int tid, String type) { this.patientId = pid; this.taskID = tid; this.taskType = type; - this.uuid = uid; + } + + /** + * . + * + * @param id . + */ + public void setUid(int id) { + this.uuid = id; } /** @@ -31,13 +39,12 @@ public PatientTask(int pid, int tid, String type, int uid) { * @param isrecurrsive . * @param type . */ - public PatientTask(int pid, int tid, boolean isdone, boolean isrecurrsive, String type, int uid) { + public PatientTask(int pid, int tid, boolean isdone, boolean isrecurrsive, String type) { this.patientId = pid; this.taskID = tid; this.taskType = type; this.isDone = isdone; this.isRecurrsive = isrecurrsive; - this.uuid = uid; } /** diff --git a/src/main/java/duke/relation/PatientTaskList.java b/src/main/java/duke/relation/PatientTaskList.java index d087cffcb0..fcc8d0da18 100644 --- a/src/main/java/duke/relation/PatientTaskList.java +++ b/src/main/java/duke/relation/PatientTaskList.java @@ -17,6 +17,7 @@ public class PatientTaskList { * An ArrayList structure. */ private Multimap patientTaskIdMap = ArrayListMultimap.create(); + int maxId = 0; /** * . @@ -25,8 +26,16 @@ public class PatientTaskList { */ public PatientTaskList(ArrayList newPatientTaskList) { for (PatientTask patientTasK : newPatientTaskList) { + if (patientTasK.getUid() == 0) { + maxId += 1; + patientTasK.setUid(maxId); + } patientTaskIdMap.put(patientTasK.getPatientId(), patientTasK); } + + if (!newPatientTaskList.isEmpty()) { + this.maxId = newPatientTaskList.get(newPatientTaskList.size() - 1).getUid(); + } } /** @@ -44,6 +53,10 @@ public ArrayList fullPatientTaskList() { * @param t . */ public void addPatientTask(PatientTask t) { + if (t.getUid() == 0) { + maxId += 1; //Increment maxId by 1 for the new coming patient + t.setUid(maxId); //Set the unique id to patient + } patientTaskIdMap.put(t.getPatientId(), t); } diff --git a/src/main/java/duke/relation/StandardPatientTask.java b/src/main/java/duke/relation/StandardPatientTask.java index 3059a5724c..46a07d4169 100644 --- a/src/main/java/duke/relation/StandardPatientTask.java +++ b/src/main/java/duke/relation/StandardPatientTask.java @@ -18,8 +18,8 @@ public class StandardPatientTask extends PatientTask { * @param timeBeforeFormat . * @param type . */ - public StandardPatientTask(int pid, int tid, String timeBeforeFormat, String type, int uid) { - super(pid, tid, type, uid); + public StandardPatientTask(int pid, int tid, String timeBeforeFormat, String type) { + super(pid, tid, type); this.deadlineRaw = timeBeforeFormat; try { this.deadline = DateTimeParser.convertToLocalDateTime(timeBeforeFormat); @@ -38,8 +38,8 @@ public StandardPatientTask(int pid, int tid, String timeBeforeFormat, String typ * @param type . */ public StandardPatientTask(int pid, int tid, - boolean isdone, boolean isrecurrsive, String timeBeforeFormat, String type, int uid) { - super(pid, tid, isdone, isrecurrsive, type, uid); + boolean isdone, boolean isrecurrsive, String timeBeforeFormat, String type) { + super(pid, tid, isdone, isrecurrsive, type); this.deadlineRaw = timeBeforeFormat; try { this.deadline = DateTimeParser.convertToLocalDateTime(timeBeforeFormat); diff --git a/src/main/java/duke/storage/PatientTaskStorage.java b/src/main/java/duke/storage/PatientTaskStorage.java index f7642ed4cd..3214c1aca0 100644 --- a/src/main/java/duke/storage/PatientTaskStorage.java +++ b/src/main/java/duke/storage/PatientTaskStorage.java @@ -66,11 +66,10 @@ public ArrayList load() throws DukeException { String taskType = record.get("TASKTYPE"); int uniqueId = Integer.parseInt(record.get("uuid")); if (taskType.equals("S")) { - patientTaskList.add(new StandardPatientTask(pid, tid, isDone, isRecursive, deadline, taskType, - uniqueId)); + patientTaskList.add(new StandardPatientTask(pid, tid, isDone, isRecursive, deadline, taskType)); } else if (taskType.equals("E")) { patientTaskList.add(new EventPatientTask(pid, tid, isDone, isRecursive, - startTime, endTime, taskType, uniqueId)); + startTime, endTime, taskType)); } } } diff --git a/src/test/java/duke/core/ParserTest.java b/src/test/java/duke/core/ParserTest.java new file mode 100644 index 0000000000..0fcad370fe --- /dev/null +++ b/src/test/java/duke/core/ParserTest.java @@ -0,0 +1,103 @@ +package duke.core; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class ParserTest { + + /* + String patientDummyInput = "add patient name NRIC room remark"; + String taskDummyInput = "add task Walk the dog"; + + String assignPatientIdToTaskS = "assign by id: S 1 2 02/02/2002 2222"; + String assignPatientIdToTaskE = "assign by id: E 2 1 02/02/2002 2222 to 03/02/2002 1234"; + + String deletePatientInputWithID = "delete patient #123"; + String deletePatientInputWithName = "delete patient billy joe"; + String deleteTaskInputWithID = "delete task 10"; + String deleteTaskInputWithName = "delete task Take medicine"; + + @Test + public void parseAddPatientTest() throws DukeException { + Parser testParser = new Parser(patientDummyInput); + String[] testOutput = testParser.parseAdd(); + + assertTrue(testOutput[0].equals("name"), + "Name field did not parse correctly. Expected: 'name', but got: " + testOutput[0]); + assertTrue(testOutput[1].equals("NRIC"), + "NRIC field did not parse correctly. Expected: 'NRIC', but got: " + testOutput[1]); + assertTrue(testOutput[2].equals("room"), + "Room field did not parse correctly. Expected: 'room', but got: " + testOutput[2]); + assertTrue(testOutput[3].equals("remark"), + "Remark field did not parse correctly. Expected: 'remark', but got: " + testOutput[3]); + + } + + @Test + public void parseAddTask() throws DukeException { + Parser testParser = new Parser(taskDummyInput); + String[] testOutput = testParser.parseAdd(); + + assertTrue(testOutput[0].equals("Walk the dog"), + "Task description did not parse correctly. Expected 'Walk the dog' but got: " + testOutput[0]); + } + + @Test + public void parseAssignPatientByID() throws DukeException { + Parser testParserStandard = new Parser(assignPatientIdToTaskS); + Parser testParserEvent = new Parser(assignPatientIdToTaskE); + + final String[] testOutputStandard = testParserStandard.parseAssign(); + final String[] testOutputEvent = testParserEvent.parseAssign(); + + assertTrue(testOutputStandard[0].equals("S"), + "Task type parsed incorrectly. Expected 'S' but got: " + testOutputStandard[0]); + assertTrue(testOutputStandard[1].equals("1") && testOutputStandard[2].equals("2"), + "IDs parsed incorrectly.\n" + + "Expected patient ID of 1, and got: " + testOutputStandard[1] + + ".\n Expected task ID of 2 and got: " + testOutputStandard[2]); + assertTrue(testOutputStandard[3].equals("02/02/2002 2222")); + + assertTrue(testOutputEvent[0].equals("E"), + "Task type parsed incorrectly. Expected 'E' but got: " + testOutputEvent[0]); + assertTrue(testOutputEvent[1].equals("2") && testOutputEvent[2].equals("1"), + "IDs parsed incorrectly.\n" + + "Expected patient ID of 2, and got: " + + testOutputEvent[1] + ".\n Expected task ID of 1 and got: " + testOutputEvent[2]); + assertTrue(testOutputEvent[3].equals("02/02/2002 2222"), + "Start date parsed incorrectly. Expected '02/02/2002 2222' but got: " + testOutputEvent[3]); + assertTrue(testOutputEvent[4].equals("03/02/2002 1234"), + "End date parsed incorrectly. Expected '03/02/2002 1234' but got: " + testOutputEvent[4]); + } + + @Test + public void parseDeletePatient() throws DukeException { + Parser testParserID = new Parser(deletePatientInputWithID); + Parser testParserName = new Parser(deletePatientInputWithName); + + String testOutputID = testParserID.parseDeletePatient(); + String testOutputName = testParserName.parseDeletePatient(); + + assertTrue(testOutputID.charAt(0) == '#' && testOutputID.equals("#123"), + "Delete patient by ID parsing failed. Expected '#123' but got: " + testOutputID); + assertTrue(testOutputName.equals("billy joe"), + "Delete patient by name parsing failed. Expected 'billy joe' but got: " + testOutputName); + } + + @Test + public void parseDeleteTask() throws DukeException { + Parser testParserID = new Parser(deleteTaskInputWithID); + Parser testParserName = new Parser(deleteTaskInputWithName); + + String testOutputID = testParserID.parseDeleteTask(); + String testOutputName = testParserName.parseDeleteTask(); + + + assertTrue(testOutputID.charAt(0) == '#' && testOutputID.equals("#10"), + "Delete task by ID parsing failed. Expected '#10' but got: " + testOutputID); + assertTrue(testOutputName.equals("Take medicine"), + "Delete task by name parsing failed. Expected 'Take medicine' but got: " + testOutputName); + } + */ + +} \ No newline at end of file From cdde611cd62b9300a10a440633ab907fcf36cb61 Mon Sep 17 00:00:00 2001 From: lmtaek Date: Sun, 20 Oct 2019 18:41:15 +0800 Subject: [PATCH 176/420] Small changes to minimize redundancy in the CommandManager, and shift parsing duties over to the Parser class. Successfully implemented for 'list' commands. --- src/main/java/duke/core/CommandManager.java | 25 +++++++++++---------- src/main/java/duke/core/Parser.java | 5 +++++ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 33ab031aeb..20fa78eecb 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -36,15 +36,18 @@ public static Command manageCommand(String userInput) throws DukeException { } String[] command = userInput.split("\\s+", 3); String firstKeyword = command[0].toLowerCase(); + String secondKeyword = ""; + if (command.length >= 2) { + secondKeyword = command[1].toLowerCase(); + } Parser parser = new Parser(userInput); switch (firstKeyword) { //change this depending on how string is parsed case "add": - String secondKeyword = command[1].toLowerCase(); - if (secondKeyword.equals("patient")) { + if ((secondKeyword != "") && secondKeyword.equals("patient")) { String[] formattedInput = parser.parseAdd(); AddPatientCommand addPatientCommand = new AddPatientCommand(formattedInput); return addPatientCommand; - } else if (secondKeyword.equals("task")) { + } else if ((secondKeyword != "") && secondKeyword.equals("task")) { String formattedInput = parser.parseAdd()[0]; AddStandardTaskCommand addStandardTaskCommand = new AddStandardTaskCommand(formattedInput); return addStandardTaskCommand; @@ -55,10 +58,11 @@ public static Command manageCommand(String userInput) throws DukeException { return new AssignTaskToPatientCommand(parser.parseAssign()); case "list": try { - String[] tempCommand = command[1].split("\\s+"); - if (tempCommand[0].toLowerCase().equals("patients")) { + String[] tempCommand = parser.parseList(); + String followingKeyword = tempCommand[0].toLowerCase(); + if (followingKeyword.equals("patients")) { return new ListPatientsCommand(); - } else if (tempCommand[0].toLowerCase().equals("tasks")) { + } else if (followingKeyword.equals("tasks")) { return new ListTasksCommand(); } else { throw new Exception("Invalid 'list' command. "); @@ -68,8 +72,7 @@ public static Command manageCommand(String userInput) throws DukeException { } case "delete": try { - secondKeyword = command[1].toLowerCase(); - if (secondKeyword.equals("patient")) { + if ((secondKeyword != "") && secondKeyword.equals("patient")) { String formattedInput = parser.parseDeletePatient(); return new DeletePatientCommand(formattedInput); } else if (secondKeyword.equals("task")) { @@ -82,8 +85,7 @@ public static Command manageCommand(String userInput) throws DukeException { } case "find": try { - secondKeyword = command[1].toLowerCase(); - if (secondKeyword.equals("patient")) { + if ((secondKeyword != "") && secondKeyword.equals("patient")) { try { return new FindPatientCommand(command[2]); } catch (Exception e) { @@ -103,8 +105,7 @@ public static Command manageCommand(String userInput) throws DukeException { } case "update": try { - secondKeyword = command[1].toLowerCase(); - if (secondKeyword.equals("patient")) { + if ((secondKeyword != "") && secondKeyword.equals("patient")) { String formattedInput = parser.parseUpdatePatient(); return new UpdatePatientCommand(formattedInput); } else if (secondKeyword.equals("task")) { diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index 3fc98cb66e..a632e2e23d 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -74,6 +74,11 @@ public String[] parseAssign() throws DukeException { } } + public String[] parseList() { + String[] formattedInput; + formattedInput = userInput.replace("list ", "").trim().split("\\s+"); + return formattedInput; + } /** * . * @return . From dd135bc5d681540ccc2e9fa89b8ed2117f218c5e Mon Sep 17 00:00:00 2001 From: Qian Jie Date: Sun, 20 Oct 2019 20:51:18 +0800 Subject: [PATCH 177/420] Implemented DukeCommand (Not fully completeds) --- src/main/java/duke/Duke.java | 19 +- src/main/java/duke/command/DukeCommand.java | 22 ++ .../duke/command/UpdatePatientCommand.java | 2 - src/main/java/duke/core/CommandManager.java | 16 +- src/main/java/duke/core/ShortCutter.java | 266 ++++++++++++++++++ src/main/java/duke/core/Ui.java | 2 + src/main/java/duke/statistic/Counter.java | 15 +- 7 files changed, 317 insertions(+), 25 deletions(-) create mode 100644 src/main/java/duke/command/DukeCommand.java create mode 100644 src/main/java/duke/core/ShortCutter.java diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index 63a67ed8e7..799555a785 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -1,8 +1,10 @@ package duke; import duke.command.Command; +import duke.command.DukeCommand; import duke.core.DukeException; import duke.core.CommandManager; +import duke.core.ShortCutter; import duke.patient.PatientManager; import duke.statistic.Counter; import duke.storage.CounterStorage; @@ -34,6 +36,7 @@ public class Duke { private TaskManager taskManager; private PatientManager patientManager; private Counter counter; + private ShortCutter shortCutter; /** * A Ui object that deals with interactions with the user. @@ -58,6 +61,7 @@ public Duke(String filePath) { taskManager = new TaskManager(taskStorage.load()); patientManager = new PatientManager(patientStorage.load()); counter = new Counter(counterStorage.load()); + shortCutter = new ShortCutter(counter , ui); } catch (DukeException e) { ui.showLoadingError(); @@ -78,10 +82,17 @@ public void run() { String fullCommand = ui.readCommand(); ui.showLine(); Command c = CommandManager.manageCommand(fullCommand); - c.execute(patientTaskList, taskManager, patientManager, - ui, patientTaskStorage, taskStorage, patientStorage); - counter.runCommandCounter(c, counterStorage, counter); - isExit = c.isExit(); + if (c instanceof DukeCommand) { + Command cmd = shortCutter.runShortCut(); + cmd.execute(patientTaskList, taskManager, patientManager, + ui, patientTaskStorage, taskStorage, patientStorage); + } else{ + c.execute(patientTaskList, taskManager, patientManager, + ui, patientTaskStorage, taskStorage, patientStorage); + counter.runCommandCounter(c, counterStorage, counter); + isExit = c.isExit(); + } + } catch (DukeException e) { ui.showError(e.getMessage()); } finally { diff --git a/src/main/java/duke/command/DukeCommand.java b/src/main/java/duke/command/DukeCommand.java new file mode 100644 index 0000000000..6139cb1dfa --- /dev/null +++ b/src/main/java/duke/command/DukeCommand.java @@ -0,0 +1,22 @@ +package duke.command; + +import duke.core.DukeException; +import duke.core.Ui; +import duke.patient.PatientManager; +import duke.relation.PatientTaskList; +import duke.storage.PatientStorage; +import duke.storage.PatientTaskStorage; +import duke.storage.TaskStorage; +import duke.task.TaskManager; + +public class DukeCommand extends Command{ + @Override + public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + System.out.println("DUKE SHORTCUT"); + } + + @Override + public boolean isExit() { + return false; + } +} diff --git a/src/main/java/duke/command/UpdatePatientCommand.java b/src/main/java/duke/command/UpdatePatientCommand.java index d2e9e33ee4..c362e67395 100644 --- a/src/main/java/duke/command/UpdatePatientCommand.java +++ b/src/main/java/duke/command/UpdatePatientCommand.java @@ -4,8 +4,6 @@ import duke.core.Ui; import duke.patient.Patient; import duke.patient.PatientManager; -import duke.statistic.Counter; -import duke.storage.CounterStorage; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; import duke.storage.TaskStorage; diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 33ab031aeb..4ec0336fab 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -1,18 +1,6 @@ package duke.core; -import duke.command.AddPatientCommand; -import duke.command.AddStandardTaskCommand; -import duke.command.AssignTaskToPatientCommand; -import duke.command.Command; -import duke.command.DeletePatientCommand; -import duke.command.DeleteTaskCommand; -import duke.command.ExitCommand; -import duke.command.FindPatientCommand; -import duke.command.FindPatientTaskCommand; -import duke.command.ListPatientsCommand; -import duke.command.ListTasksCommand; -import duke.command.UpdatePatientCommand; -import duke.command.UpdateTaskCommand; +import duke.command.*; /** * Represents a Parser that parses user input into a specific @@ -116,6 +104,8 @@ public static Command manageCommand(String userInput) throws DukeException { } catch (Exception e) { throw new DukeException("update command fails. " + e.getMessage()); } + case "duke" : + return new DukeCommand(); case "bye": ExitCommand exitCommand = new ExitCommand(); return exitCommand; diff --git a/src/main/java/duke/core/ShortCutter.java b/src/main/java/duke/core/ShortCutter.java new file mode 100644 index 0000000000..d32f356953 --- /dev/null +++ b/src/main/java/duke/core/ShortCutter.java @@ -0,0 +1,266 @@ +package duke.core; + +import duke.command.*; +import duke.statistic.Counter; + +import java.util.*; + +public class ShortCutter { + Counter counter; + Ui ui; + + public ShortCutter(Counter counter, Ui ui) { + this.counter = counter; + this.ui = ui; + } + + private Map sortedCommandTable; + private Map topUsedCommandTable; + + public static > Map sortByValues(final Map map) { + Comparator valueComparator = (k1, k2) -> { + int compare = map.get(k2).compareTo(map.get(k1)); + if (compare == 0) + return 1; + else + return compare; + }; + Map sortedByValues = new TreeMap(valueComparator); + sortedByValues.putAll(map); + return sortedByValues; + } + + public Command runShortCut() throws DukeException { + sortedCommandTable = sortByValues(counter.getCommandTable()); + topUsedCommandTable = MapSorter(sortedCommandTable); + String commandName; + String choiceIndex = ui.readCommand(); + switch (choiceIndex) { + case "1": + commandName = topUsedCommandTable.get(1); + if (commandName.equals("AddPatientCommand")) { + String name; + String nric; + String room; + String remark; + System.out.println("Name?"); + name = ui.readCommand(); + System.out.println("NRIC?"); + nric = ui.readCommand(); + System.out.println("Room?"); + room = ui.readCommand(); + System.out.println("Remark?"); + remark = ui.readCommand(); + + String[] patientInfo = new String[]{name, nric, room, remark}; + return new AddPatientCommand(patientInfo); + } else if (commandName.equals("AddStandardTaskCommand")) { + System.out.println("Task Name?"); + String taskName = ui.readCommand(); + return new AddStandardTaskCommand(taskName); + } else if (commandName.equals("DeletePatientCommand")) { + System.out.println("Patient ID Number ?"); + String patientId = ui.readCommand(); + return new DeletePatientCommand(patientId); + + } else if (commandName.equals("DeleteTaskCommand")) { + System.out.println("Task ID?"); + String taskId = "#" + ui.readCommand(); + return new DeleteTaskCommand(taskId); + + } else if (commandName.equals("FindPatientCommand")) { + System.out.println("Patient ID?"); + String patientId = "#" + ui.readCommand(); + return new FindPatientCommand(patientId); + + } else if (commandName.equals("FindPatientTaskCommand")) { + System.out.println("Task ID?"); + String taskId = "#" + ui.readCommand(); + return new FindPatientTaskCommand(taskId); // check for command + + } else if (commandName.equals("ListPatientsCommand")) { + return new ListPatientsCommand(); + + } else if (commandName.equals("ListTasksCommand")) { + return new ListTasksCommand(); + + } else if (commandName.equals("UpdatePatientCommand")) { + String patientId; + String infoType; + String changedValue; + System.out.println("Patient ID ?"); + patientId = "#" + ui.readCommand(); + System.out.println("what do you want to change?"); + infoType = ui.readCommand(); + System.out.println("Change to ?"); + changedValue = ui.readCommand(); + + String userInput = patientId + infoType + changedValue; + return new UpdatePatientCommand(userInput); + } + +// } else if (commandName.equals("UpdateTaskCommand")) { +// +// +// +// } else if (commandName.equals("AssignTaskToPatientCommand")) { +// +// +// } + + case "2": + commandName = topUsedCommandTable.get(2); + if (commandName.equals("AddPatientCommand")) { + String name; + String nric; + String room; + String remark; + System.out.println("Name?"); + name = ui.readCommand(); + System.out.println("NRIC?"); + nric = ui.readCommand(); + System.out.println("Room?"); + room = ui.readCommand(); + System.out.println("Remark?"); + remark = ui.readCommand(); + + String[] patientInfo = new String[]{name, nric, room, remark}; + return new AddPatientCommand(patientInfo); + } else if (commandName.equals("AddStandardTaskCommand")) { + System.out.println("Task Name?"); + String taskName = ui.readCommand(); + return new AddStandardTaskCommand(taskName); + } else if (commandName.equals("DeletePatientCommand")) { + System.out.println("Patient ID Number ?"); + String patientId = ui.readCommand(); + return new DeletePatientCommand(patientId); + + } else if (commandName.equals("DeleteTaskCommand")) { + System.out.println("Task ID?"); + String taskId = "#" + ui.readCommand(); + return new DeleteTaskCommand(taskId); + + } else if (commandName.equals("FindPatientCommand")) { + System.out.println("Patient ID?"); + String patientId = "#" + ui.readCommand(); + return new FindPatientCommand(patientId); + + } else if (commandName.equals("FindPatientTaskCommand")) { + System.out.println("Task ID?"); + String taskId = "#" + ui.readCommand(); + return new FindPatientTaskCommand(taskId); // check for command + + } else if (commandName.equals("ListPatientsCommand")) { + return new ListPatientsCommand(); // check for command + + } else if (commandName.equals("ListTasksCommand")) { + return new ListTasksCommand(); // check for command + + } else if (commandName.equals("UpdatePatientCommand")) { + String patientId; + String infoType; + String changedValue; + System.out.println("Patient ID ?"); + patientId = "#" + ui.readCommand(); + System.out.println("what do you want to change?"); + infoType = ui.readCommand(); + System.out.println("Change to ?"); + changedValue = ui.readCommand(); + + String userInput = patientId + infoType + changedValue; + return new UpdatePatientCommand(userInput); + } + case "3": { + commandName = topUsedCommandTable.get(3); + if (commandName.equals("AddPatientCommand")) { + String name; + String nric; + String room; + String remark; + System.out.println("Name?"); + name = ui.readCommand(); + System.out.println("NRIC?"); + nric = ui.readCommand(); + System.out.println("Room?"); + room = ui.readCommand(); + System.out.println("Remark?"); + remark = ui.readCommand(); + + String[] patientInfo = new String[]{name, nric, room, remark}; + return new AddPatientCommand(patientInfo); + } else if (commandName.equals("AddStandardTaskCommand")) { + System.out.println("Task Name?"); + String taskName = ui.readCommand(); + return new AddStandardTaskCommand(taskName); + } else if (commandName.equals("DeletePatientCommand")) { + System.out.println("Patient ID Number ?"); + String patientId = ui.readCommand(); + return new DeletePatientCommand(patientId); + + } else if (commandName.equals("DeleteTaskCommand")) { + System.out.println("Task ID?"); + String taskId = "#" + ui.readCommand(); + return new DeleteTaskCommand(taskId); + + } else if (commandName.equals("FindPatientCommand")) { + System.out.println("Patient ID?"); + String patientId = "#" + ui.readCommand(); + return new FindPatientCommand(patientId); + + } else if (commandName.equals("FindPatientTaskCommand")) { + System.out.println("Task ID?"); + String taskId = "#" + ui.readCommand(); + return new FindPatientTaskCommand(taskId); // check for command + + } else if (commandName.equals("ListPatientsCommand")) { + return new ListPatientsCommand(); // check for command + + } else if (commandName.equals("ListTasksCommand")) { + return new ListTasksCommand(); // check for command + + } else if (commandName.equals("UpdatePatientCommand")) { + String patientId; + String infoType; + String changedValue; + System.out.println("Patient ID ?"); + patientId = "#" + ui.readCommand(); + System.out.println("what do you want to change?"); + infoType = ui.readCommand(); + System.out.println("Change to ?"); + changedValue = ui.readCommand(); + + String userInput = patientId + infoType + changedValue; + return new UpdatePatientCommand(userInput); + } + + } + + default: + throw new DukeException("ERROR"); + } + + } + + public Map MapSorter(Map sortedCommandTable) { + Map topCommandTable = new HashMap<>(); + ArrayList keys = new ArrayList<>(sortedCommandTable.keySet()); + if (sortedCommandTable.size() < 3) { + for (int i = 0; i < sortedCommandTable.size(); i++) { + int index = i + 1; + topCommandTable.put(index, keys.get(i)); + System.out.println("[" + index + "] " + keys.get(i)); + } + + } else { + for (int i = 0; i < 3; i++) { + int index = i + 1; + topCommandTable.put(index, keys.get(i)); + System.out.println("[" + index + "] " + keys.get(i)); + } + } + System.out.println("Please choose one of these commands"); + return topCommandTable; + } + + +} diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index 58bb550df4..16fdc13f36 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -5,6 +5,8 @@ import duke.task.Task; import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; import java.util.Scanner; /** diff --git a/src/main/java/duke/statistic/Counter.java b/src/main/java/duke/statistic/Counter.java index 7a441d137b..13912e695e 100644 --- a/src/main/java/duke/statistic/Counter.java +++ b/src/main/java/duke/statistic/Counter.java @@ -1,6 +1,8 @@ package duke.statistic; import duke.command.Command; +import duke.command.DukeCommand; +import duke.command.ExitCommand; import duke.core.DukeException; import duke.storage.CounterStorage; @@ -36,13 +38,14 @@ public Map getCommandTable() { public void runCommandCounter(Command command, CounterStorage counterStorage, Counter counter) throws DukeException { - String commandName = command.getClass().getSimpleName(); + if (!(command instanceof ExitCommand || command instanceof DukeCommand)) { + String commandName = command.getClass().getSimpleName(); - int count = commandTable.containsKey(commandName) + int count = commandTable.containsKey(commandName) ? commandTable.get(commandName) : 0; - commandTable.put(commandName, count + 1); - counterStorage.save(counter.getCommandTable()); - } - + commandTable.put(commandName, count + 1); + counterStorage.save(counter.getCommandTable()); + } + } } From ebb22eab8903db85e604cade8eb2674d98be920c Mon Sep 17 00:00:00 2001 From: lmtaek Date: Sun, 20 Oct 2019 20:51:34 +0800 Subject: [PATCH 178/420] Successful implementation of 'find patient' into Parser with cleaned-up logic. Still trying to successfully implement this parsing into 'find patient task'. --- .../java/duke/command/FindPatientCommand.java | 32 +++-- .../duke/command/FindPatientTaskCommand.java | 39 +++--- src/main/java/duke/core/CommandManager.java | 54 +++----- src/main/java/duke/core/Parser.java | 128 ++++++++++++------ 4 files changed, 144 insertions(+), 109 deletions(-) diff --git a/src/main/java/duke/command/FindPatientCommand.java b/src/main/java/duke/command/FindPatientCommand.java index 19daa25d33..b90d8d2e2a 100644 --- a/src/main/java/duke/command/FindPatientCommand.java +++ b/src/main/java/duke/command/FindPatientCommand.java @@ -4,8 +4,6 @@ import duke.core.Ui; import duke.patient.Patient; import duke.patient.PatientManager; -import duke.statistic.Counter; -import duke.storage.CounterStorage; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; import duke.storage.TaskStorage; @@ -16,10 +14,20 @@ public class FindPatientCommand extends Command { - private String command; + private String patientInfo; + private int id; - public FindPatientCommand(String command) { - this.command = command; + public FindPatientCommand(String patientInfo) throws DukeException { + + this.patientInfo = patientInfo; + + if (patientInfo.charAt(0) == '#') { + try { + this.id = Integer.parseInt(patientInfo.substring(1)); + } catch (Exception e) { + throw new DukeException("Failed to find ID."); + } + } } /** @@ -38,19 +46,13 @@ public FindPatientCommand(String command) { public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientManager, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { - char firstChar = command.charAt(0); - if (firstChar == '#') { - int id; - try { - id = Integer.parseInt(command.substring(1, command.length())); - } catch (Exception e) { - throw new DukeException("Please follow the format 'find patient #' or 'find patient '."); - } + char firstChar = patientInfo.charAt(0); + if (id != 0) { Patient patient = patientManager.getPatient(id); ui.patientsFoundById(patient); } else { - ArrayList patientsWithSameName = patientManager.getPatientByName(command); - ui.patientsFoundByName(patientsWithSameName, command); + ArrayList patientsWithSameName = patientManager.getPatientByName(patientInfo); + ui.patientsFoundByName(patientsWithSameName, patientInfo); } } diff --git a/src/main/java/duke/command/FindPatientTaskCommand.java b/src/main/java/duke/command/FindPatientTaskCommand.java index 70ea89359e..d2966b10ab 100644 --- a/src/main/java/duke/command/FindPatientTaskCommand.java +++ b/src/main/java/duke/command/FindPatientTaskCommand.java @@ -6,8 +6,6 @@ import duke.patient.PatientManager; import duke.relation.PatientTask; import duke.relation.PatientTaskList; -import duke.statistic.Counter; -import duke.storage.CounterStorage; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; import duke.storage.TaskStorage; @@ -18,16 +16,26 @@ public class FindPatientTaskCommand extends Command { - private String command; + private String patientTaskInfo; + private int id; /** * . * - * @param cmd . + * @param patientTaskInfo . */ - public FindPatientTaskCommand(String cmd) { + public FindPatientTaskCommand(String patientTaskInfo) throws DukeException { super(); - this.command = cmd; + this.patientTaskInfo = patientTaskInfo; + + if (patientTaskInfo.charAt(0) == '#') { + try { + this.id = Integer.parseInt(patientTaskInfo.substring(1)); + + } catch (Exception e) { + throw new DukeException("Failed to find ID."); + } + } } /** @@ -46,23 +54,20 @@ public FindPatientTaskCommand(String cmd) { public void execute(PatientTaskList patientTaskList, TaskManager tasksManager, PatientManager patientManager, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { - char firstChar = command.charAt(0); - if (firstChar == '#') { - int id; + if (id != 0) { try { - id = Integer.parseInt(command.substring(1, command.length())); Patient patient = patientManager.getPatient(id); ArrayList patientTask = patientTaskList.getPatientTask(id); ArrayList tempTask = new ArrayList<>(); - for (PatientTask temppatientTask : patientTask) { - tempTask.add(tasksManager.getTask(temppatientTask.getTaskID())); + for (PatientTask tempPatientTask : patientTask) { + tempTask.add(tasksManager.getTask(tempPatientTask.getTaskID())); } ui.patientTaskFound(patient, patientTask, tempTask); } catch (Exception e) { - throw new DukeException("Please follow the format 'find patienttask #' or 'find patient '."); + throw new DukeException("Please follow the format 'find patient task #' or 'find patient '."); } } else { - String name = command.toLowerCase(); + String name = patientTaskInfo.toLowerCase(); ArrayList patientsWithSameName = patientManager.getPatientByName(name); ArrayList patientWithTask = new ArrayList<>(); ArrayList tempTask = new ArrayList<>(); @@ -73,13 +78,13 @@ public void execute(PatientTaskList patientTaskList, TaskManager tasksManager, P patientWithTask = patientTaskList.getPatientTask(patient.getID()); } } - for (PatientTask temppatientTask : patientWithTask) { - tempTask.add(tasksManager.getTask(temppatientTask.getTaskID())); + for (PatientTask tempPatientTask : patientWithTask) { + tempTask.add(tasksManager.getTask(tempPatientTask.getTaskID())); } ui.patientTaskFound(patientsWithSameName.get(0), patientWithTask, tempTask); } catch (Exception e) { throw new DukeException(e.getMessage() - + "Please follow the format 'find patienttask #' or 'find patient '."); + + "Please follow the format 'find patient task #' or 'find patient '."); } } } diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 20fa78eecb..4501ae0346 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -37,11 +37,17 @@ public static Command manageCommand(String userInput) throws DukeException { String[] command = userInput.split("\\s+", 3); String firstKeyword = command[0].toLowerCase(); String secondKeyword = ""; + String thirdKeyword = ""; if (command.length >= 2) { secondKeyword = command[1].toLowerCase(); } + if (command.length >= 3) { + thirdKeyword = command[2].toLowerCase(); + } + Parser parser = new Parser(userInput); - switch (firstKeyword) { //change this depending on how string is parsed + + switch (firstKeyword) { case "add": if ((secondKeyword != "") && secondKeyword.equals("patient")) { String[] formattedInput = parser.parseAdd(); @@ -52,59 +58,38 @@ public static Command manageCommand(String userInput) throws DukeException { AddStandardTaskCommand addStandardTaskCommand = new AddStandardTaskCommand(formattedInput); return addStandardTaskCommand; } else { - throw new DukeException("Add command fails. "); + throw new DukeException("Add command fails."); } case "assign": return new AssignTaskToPatientCommand(parser.parseAssign()); case "list": - try { String[] tempCommand = parser.parseList(); - String followingKeyword = tempCommand[0].toLowerCase(); - if (followingKeyword.equals("patients")) { + String nextKeyword = tempCommand[0].toLowerCase(); + if (nextKeyword.equals("patients")) { return new ListPatientsCommand(); - } else if (followingKeyword.equals("tasks")) { + } else if (nextKeyword.equals("tasks")) { return new ListTasksCommand(); } else { - throw new Exception("Invalid 'list' command. "); + throw new DukeException("Invalid 'list' command."); } - } catch (Exception e) { - throw new DukeException("List command fails. " + e.getMessage()); - } case "delete": - try { if ((secondKeyword != "") && secondKeyword.equals("patient")) { String formattedInput = parser.parseDeletePatient(); return new DeletePatientCommand(formattedInput); } else if (secondKeyword.equals("task")) { return new DeleteTaskCommand(parser.parseDeleteTask()); } else { - throw new Exception("Invalid format. "); + throw new DukeException("Invalid 'delete' command."); } - } catch (Exception e) { - throw new DukeException("Delete command fails. " + e.getMessage()); - } case "find": - try { if ((secondKeyword != "") && secondKeyword.equals("patient")) { - try { - return new FindPatientCommand(command[2]); - } catch (Exception e) { - throw new Exception("Please follow the format 'find patient #' or 'find patient '."); - } - } else if (secondKeyword.equals("patienttask")) { - try { - return new FindPatientTaskCommand(command[2]); - } catch (Exception e) { - throw new Exception("Please follow the format 'find patient #' or 'find patient '."); - } + return new FindPatientCommand(parser.parseFind()); + } else if (secondKeyword.equals("patient") && ((thirdKeyword != "") && thirdKeyword.equals("task"))) { + return new FindPatientTaskCommand(parser.parseFind()); } else { - throw new Exception("Invalid format. "); + throw new DukeException("Invalid 'find' command. "); } - } catch (Exception e) { - throw new DukeException("Find command fails. " + e.getMessage()); - } case "update": - try { if ((secondKeyword != "") && secondKeyword.equals("patient")) { String formattedInput = parser.parseUpdatePatient(); return new UpdatePatientCommand(formattedInput); @@ -112,11 +97,8 @@ public static Command manageCommand(String userInput) throws DukeException { String formattedInput = parser.parseUpdateTask(); return new UpdateTaskCommand(formattedInput); } else { - throw new Exception("Invalid format. "); + throw new DukeException("Invalid 'update' command. "); } - } catch (Exception e) { - throw new DukeException("update command fails. " + e.getMessage()); - } case "bye": ExitCommand exitCommand = new ExitCommand(); return exitCommand; diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index a632e2e23d..689891058f 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -5,43 +5,45 @@ public class Parser { String userInput; /** - * . + * Constructor for the Parser class. * - * @param userInput . + * @param userInput Takes in user's raw input and stores it to use in its methods, parsing it + * into a format that is appropriate for the command it invokes. */ public Parser(String userInput) { this.userInput = userInput; } /** - * . + * Parses user input so that it is compatible with Add commands. * - * @return . - * @throws DukeException . + * @return A formatted string that will work for the available 'add' commands. + * @throws DukeException If the method is unable to parse the userInput correctly, it will throw + * a DukeException. */ public String[] parseAdd() throws DukeException { String[] parsedCommand = userInput.toLowerCase().split("\\s+", 3); try { if (parsedCommand[1].equals("patient")) { - String[] patientInfo = userInput.replace( - "add patient ", "").trim().split("\\s+", 4); + String[] patientInfo = userInput.replaceAll( + "(?i)add patient ", "").trim().split("\\s+", 4); return patientInfo; } else if (parsedCommand[1].equals("task")) { String[] taskInfo = new String[1]; - taskInfo[0] = userInput.replace("add task ", "").trim(); + taskInfo[0] = userInput.replaceAll("(?i)add task ", "").trim(); return taskInfo; } } catch (Exception e) { throw new DukeException("Please change the format for your 'add' command."); } - throw new DukeException("Failed to parse 'add' command."); + throw new DukeException("Invalid 'add' command."); } /** - * . + * Takes the user input and formats it so it is compatible with 'Assign' commands. * - * @return . - * @throws DukeException . + * @return A string of formatted output to be used by 'Assign' commands. + * @throws DukeException Thrown when the user input cannot be parsed in the desired manner. */ public String[] parseAssign() throws DukeException { String[] formattedInput = new String[5]; @@ -49,8 +51,8 @@ public String[] parseAssign() throws DukeException { String[] parsedCommand = userInput.toLowerCase().split("\\s+", 4); if (parsedCommand[1].equals("by") && parsedCommand[2].equals("id:")) { - String[] tempInput = userInput.replace( - "assign by id: ", "").split("\\s+", 4); + String[] tempInput = userInput.replaceAll( + "(?i)assign by id: ", "").split("\\s+", 4); if (tempInput[0].equals("E")) { String[] parsedTimes = tempInput[3].split(" to ", 2); @@ -65,48 +67,68 @@ public String[] parseAssign() throws DukeException { } } } else { - throw new DukeException("Please use proper 'assign by ID' command format. "); + throw new DukeException("Please use proper 'assign by id:' command format."); } - System.out.println(formattedInput[3]); return formattedInput; } catch (Exception e) { - throw new DukeException("Please use the correct format for the 'assign by id' command. "); + throw new DukeException("Invalid 'assign' command."); } } - public String[] parseList() { - String[] formattedInput; - formattedInput = userInput.replace("list ", "").trim().split("\\s+"); - return formattedInput; + /** + * Takes the user input and formats it so it is compatible with the 'list' case in CommandManager. + * + * @return A string of formatted output to be used by 'list' case in CommandManager. + * @throws DukeException Thrown when the user input cannot be parsed in the desired manner. + */ + public String[] parseList() throws DukeException { + try { + String[] formattedInput; + formattedInput = userInput.replaceAll("(?i)list ", "").trim().split("\\s+"); + return formattedInput; + } catch (Exception e) { + throw new DukeException("Invalid 'list' command."); + } } /** - * . - * @return . - * @throws DukeException . + * Takes the user input and formats it so it is compatible with 'delete patient' command. + * + * @return A string of formatted output to be used by 'delete patient' commands. + * @throws DukeException Thrown when the user input cannot be parsed in the desired manner. */ public String parseDeletePatient() throws DukeException { - String formattedInput; - String inputToParse = userInput.replaceAll("(?i)delete patient ", "").trim(); - formattedInput = inputToParse; - return formattedInput; + try { + String formattedInput; + String inputToParse = userInput.replaceAll("(?i)delete patient ", "").trim(); + formattedInput = inputToParse; + return formattedInput; + } catch (Exception e) { + throw new DukeException("Invalid 'delete' command format."); + } } /** - * . - * @return . - * @throws DukeException . + * Takes the user input and formats it so it is compatible with 'delete task' command. + * + * @return A string of formatted output to be used by 'delete task' commands. + * @throws DukeException Thrown when the user input cannot be parsed in the desired manner. */ public String parseDeleteTask() throws DukeException { - String formattedInput; - String inputToParse = userInput.replaceAll("(?i)delete task ", "").trim(); - formattedInput = inputToParse; - return formattedInput; + try { + String formattedInput; + String inputToParse = userInput.replaceAll("(?i)delete task ", "").trim(); + formattedInput = inputToParse; + return formattedInput; + } catch (Exception e) { + throw new DukeException("Invalid 'delete task' command."); + } } /** - * . - * @return . - * @throws DukeException . + * Takes the user input and formats it so it is compatible with 'update patient' command. + * + * @return A string of formatted output to be used by 'update patient' commands. + * @throws DukeException Thrown when the user input cannot be parsed in the desired manner. */ public String parseUpdatePatient() throws DukeException { String formattedInput; @@ -116,9 +138,33 @@ public String parseUpdatePatient() throws DukeException { } /** - * . - * @return . - * @throws DukeException . + * Takes the user input and formats it so it is compatible with 'find' commands. + * + * @return A string of formatted output to be used by 'find' commands. + * @throws DukeException Thrown when the user input cannot be parsed in the desired manner. + */ + public String parseFind() throws DukeException { + try { + String formattedInput; + String[] inputToParse = userInput.replaceAll("(?i)find patient ", "").trim().split("\\s+"); + + if (inputToParse[0].equalsIgnoreCase("task")) { + formattedInput = userInput.replaceAll("(?i)find patient task ", "").trim(); + } else { + formattedInput = userInput.replaceAll("(?i)find patient ", "").trim(); + } + return formattedInput; + } catch (Exception e) { + throw new DukeException("Invalid 'find patient' command."); + } + } + + + /** + * Takes the user input and formats it so it is compatible with 'update task' command. + * + * @return A string of formatted output to be used by 'update task' commands. + * @throws DukeException Thrown when the user input cannot be parsed in the desired manner. */ public String parseUpdateTask() throws DukeException { String formattedInput; From b602665fd63b532b7b7d333904f09e1e3540cbe5 Mon Sep 17 00:00:00 2001 From: lmtaek Date: Mon, 21 Oct 2019 10:49:11 +0800 Subject: [PATCH 179/420] removed 'help' command import from CommandManagerTest --- src/test/java/duke/core/CommandManagerTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/duke/core/CommandManagerTest.java b/src/test/java/duke/core/CommandManagerTest.java index 9f64d75af5..528a12ebe1 100644 --- a/src/test/java/duke/core/CommandManagerTest.java +++ b/src/test/java/duke/core/CommandManagerTest.java @@ -8,7 +8,6 @@ import duke.command.DeletePatientCommand; import duke.command.FindPatientCommand; import duke.command.FindPatientTaskCommand; -import duke.command.HelpCommand; import duke.command.ListPatientsCommand; import duke.command.ListTasksCommand; import duke.command.UpdatePatientCommand; From 3c8ad8400482eb90f3cf4111bbc24ed2b2d6e5b5 Mon Sep 17 00:00:00 2001 From: lmtaek Date: Mon, 21 Oct 2019 11:59:32 +0800 Subject: [PATCH 180/420] Altered code based on feedback from checkstyle. --- .../java/duke/command/FindPatientCommand.java | 5 ++ src/main/java/duke/core/CommandManager.java | 50 +++++++++---------- 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/src/main/java/duke/command/FindPatientCommand.java b/src/main/java/duke/command/FindPatientCommand.java index b90d8d2e2a..3e7fd64aff 100644 --- a/src/main/java/duke/command/FindPatientCommand.java +++ b/src/main/java/duke/command/FindPatientCommand.java @@ -17,6 +17,11 @@ public class FindPatientCommand extends Command { private String patientInfo; private int id; + /** + * Constructor method for FindPatientCommand. + * @param patientInfo Takes in patient information to be used to locate the desired patient. + * @throws DukeException when unable to successfully parse a patient ID number. + */ public FindPatientCommand(String patientInfo) throws DukeException { this.patientInfo = patientInfo; diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 4501ae0346..3e175106bf 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -48,21 +48,21 @@ public static Command manageCommand(String userInput) throws DukeException { Parser parser = new Parser(userInput); switch (firstKeyword) { - case "add": - if ((secondKeyword != "") && secondKeyword.equals("patient")) { - String[] formattedInput = parser.parseAdd(); - AddPatientCommand addPatientCommand = new AddPatientCommand(formattedInput); - return addPatientCommand; - } else if ((secondKeyword != "") && secondKeyword.equals("task")) { - String formattedInput = parser.parseAdd()[0]; - AddStandardTaskCommand addStandardTaskCommand = new AddStandardTaskCommand(formattedInput); - return addStandardTaskCommand; - } else { - throw new DukeException("Add command fails."); - } - case "assign": - return new AssignTaskToPatientCommand(parser.parseAssign()); - case "list": + case "add": + if ((secondKeyword != "") && secondKeyword.equals("patient")) { + String[] formattedInput = parser.parseAdd(); + AddPatientCommand addPatientCommand = new AddPatientCommand(formattedInput); + return addPatientCommand; + } else if ((secondKeyword != "") && secondKeyword.equals("task")) { + String formattedInput = parser.parseAdd()[0]; + AddStandardTaskCommand addStandardTaskCommand = new AddStandardTaskCommand(formattedInput); + return addStandardTaskCommand; + } else { + throw new DukeException("Add command fails."); + } + case "assign": + return new AssignTaskToPatientCommand(parser.parseAssign()); + case "list": String[] tempCommand = parser.parseList(); String nextKeyword = tempCommand[0].toLowerCase(); if (nextKeyword.equals("patients")) { @@ -72,7 +72,7 @@ public static Command manageCommand(String userInput) throws DukeException { } else { throw new DukeException("Invalid 'list' command."); } - case "delete": + case "delete": if ((secondKeyword != "") && secondKeyword.equals("patient")) { String formattedInput = parser.parseDeletePatient(); return new DeletePatientCommand(formattedInput); @@ -81,15 +81,15 @@ public static Command manageCommand(String userInput) throws DukeException { } else { throw new DukeException("Invalid 'delete' command."); } - case "find": + case "find": if ((secondKeyword != "") && secondKeyword.equals("patient")) { - return new FindPatientCommand(parser.parseFind()); + return new FindPatientCommand(parser.parseFind()); } else if (secondKeyword.equals("patient") && ((thirdKeyword != "") && thirdKeyword.equals("task"))) { - return new FindPatientTaskCommand(parser.parseFind()); + return new FindPatientTaskCommand(parser.parseFind()); } else { throw new DukeException("Invalid 'find' command. "); } - case "update": + case "update": if ((secondKeyword != "") && secondKeyword.equals("patient")) { String formattedInput = parser.parseUpdatePatient(); return new UpdatePatientCommand(formattedInput); @@ -99,11 +99,11 @@ public static Command manageCommand(String userInput) throws DukeException { } else { throw new DukeException("Invalid 'update' command. "); } - case "bye": - ExitCommand exitCommand = new ExitCommand(); - return exitCommand; - default: - throw new DukeException("Could not understand user input"); + case "bye": + ExitCommand exitCommand = new ExitCommand(); + return exitCommand; + default: + throw new DukeException("Could not understand user input"); } } } From e0181a717f3e3843d4fc85ef544a9fb5b5c84beb Mon Sep 17 00:00:00 2001 From: lmtaek Date: Mon, 21 Oct 2019 12:04:37 +0800 Subject: [PATCH 181/420] Removed unnecessary files (test results, test reports). --- .../test/classes/duke.core.ParserTest.html | 127 ------------------ .../tests/test/packages/duke.core.html | 103 -------------- .../test/TEST-duke.core.ParserTest.xml | 13 -- 3 files changed, 243 deletions(-) delete mode 100644 build/reports/tests/test/classes/duke.core.ParserTest.html delete mode 100644 build/reports/tests/test/packages/duke.core.html delete mode 100644 build/test-results/test/TEST-duke.core.ParserTest.xml diff --git a/build/reports/tests/test/classes/duke.core.ParserTest.html b/build/reports/tests/test/classes/duke.core.ParserTest.html deleted file mode 100644 index 3729786fdc..0000000000 --- a/build/reports/tests/test/classes/duke.core.ParserTest.html +++ /dev/null @@ -1,127 +0,0 @@ - - - - - -Test results - ParserTest - - - - - -
-

ParserTest

- -
-
Error DescriptionLine
- - - - -
-
- - - - - - - -
-
-
5
-

tests

-
-
-
-
0
-

failures

-
-
-
-
0
-

ignored

-
-
-
-
0.291s
-

duration

-
-
-
-
-
-
100%
-

successful

-
-
- -
- -
-

Tests

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TestDurationResult
parseAddPatientTest()0.090spassed
parseAddTask()0.008spassed
parseAssignPatientByID()0.107spassed
parseDeletePatient()0.005spassed
parseDeleteTask()0.081spassed
-
-
-

Standard output

- -
02/02/2002 2222
-02/02/2002 2222
-
-
-
-
- - - - diff --git a/build/reports/tests/test/packages/duke.core.html b/build/reports/tests/test/packages/duke.core.html deleted file mode 100644 index 0e3a648bd7..0000000000 --- a/build/reports/tests/test/packages/duke.core.html +++ /dev/null @@ -1,103 +0,0 @@ - - - - - -Test results - Package duke.core - - - - - -
-

Package duke.core

- -
- - - - - -
-
- - - - - - - -
-
-
5
-

tests

-
-
-
-
0
-

failures

-
-
-
-
0
-

ignored

-
-
-
-
0.291s
-

duration

-
-
-
-
-
-
100%
-

successful

-
-
-
-
- -
-

Classes

- - - - - - - - - - - - - - - - - - - -
ClassTestsFailuresIgnoredDurationSuccess rate
-ParserTest -5000.291s100%
-
-
- -
- - diff --git a/build/test-results/test/TEST-duke.core.ParserTest.xml b/build/test-results/test/TEST-duke.core.ParserTest.xml deleted file mode 100644 index dee0acf0b1..0000000000 --- a/build/test-results/test/TEST-duke.core.ParserTest.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - From 2433781c8bb2f87e3a510fe61a9a8883bba5e587 Mon Sep 17 00:00:00 2001 From: lmtaek Date: Mon, 21 Oct 2019 12:08:08 +0800 Subject: [PATCH 182/420] Added necessary imports to improve compatibility during merge. --- src/main/java/duke/command/FindPatientCommand.java | 2 ++ src/main/java/duke/command/FindPatientTaskCommand.java | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/main/java/duke/command/FindPatientCommand.java b/src/main/java/duke/command/FindPatientCommand.java index 3e7fd64aff..e29cacd54d 100644 --- a/src/main/java/duke/command/FindPatientCommand.java +++ b/src/main/java/duke/command/FindPatientCommand.java @@ -4,6 +4,8 @@ import duke.core.Ui; import duke.patient.Patient; import duke.patient.PatientManager; +import duke.statistic.Counter; +import duke.storage.CounterStorage; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; import duke.storage.TaskStorage; diff --git a/src/main/java/duke/command/FindPatientTaskCommand.java b/src/main/java/duke/command/FindPatientTaskCommand.java index d2966b10ab..6027b85440 100644 --- a/src/main/java/duke/command/FindPatientTaskCommand.java +++ b/src/main/java/duke/command/FindPatientTaskCommand.java @@ -6,6 +6,8 @@ import duke.patient.PatientManager; import duke.relation.PatientTask; import duke.relation.PatientTaskList; +import duke.statistic.Counter; +import duke.storage.CounterStorage; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; import duke.storage.TaskStorage; From c745df7d81d95eafe804b07e642cce1839404c55 Mon Sep 17 00:00:00 2001 From: Kejun Liu Date: Mon, 21 Oct 2019 19:26:53 +0800 Subject: [PATCH 183/420] Prompts user if there are tasks assigned to a patient when user is trying to delete a patient and delete all the tasks assigned to this patient if user confirms to delete the patient. --- .../duke/command/DeletePatientCommand.java | 55 ++++++++++++------- src/main/java/duke/core/Ui.java | 11 +++- 2 files changed, 44 insertions(+), 22 deletions(-) diff --git a/src/main/java/duke/command/DeletePatientCommand.java b/src/main/java/duke/command/DeletePatientCommand.java index 9e1e2237fb..322accf6e8 100644 --- a/src/main/java/duke/command/DeletePatientCommand.java +++ b/src/main/java/duke/command/DeletePatientCommand.java @@ -4,12 +4,14 @@ import duke.core.Ui; import duke.patient.Patient; import duke.patient.PatientManager; +import duke.relation.PatientTask; import duke.statistic.Counter; import duke.storage.CounterStorage; import duke.storage.PatientStorage; import duke.storage.PatientTaskStorage; import duke.storage.TaskStorage; import duke.relation.PatientTaskList; +import duke.task.Task; import duke.task.TaskManager; @@ -20,10 +22,11 @@ public class DeletePatientCommand extends Command { private String deletedPatientInfo; /** - * . + * It checks whether user is deleting a patient by id + * It extracts the id of the patient to be deleted * - * @param deletedPatientInfo . - * @throws DukeException . + * @param deletedPatientInfo it contains the information of the patient to be deleted + * @throws DukeException it shows user the correct format to delete a patient by id */ public DeletePatientCommand(String deletedPatientInfo) throws DukeException { @@ -41,8 +44,8 @@ public DeletePatientCommand(String deletedPatientInfo) throws DukeException { /** * . * - * @param patientTask . - * @param tasks . + * @param patientTaskList . + * @param taskManager . * @param patientManager . * @param ui . * @param patientTaskStorage . @@ -51,33 +54,47 @@ public DeletePatientCommand(String deletedPatientInfo) throws DukeException { * @throws DukeException . */ @Override - public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientManager, + public void execute(PatientTaskList patientTaskList, TaskManager taskManager, PatientManager patientManager, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + boolean toDelete; + ArrayList patientTask = new ArrayList<>(); + Patient patientToBeDeleted = null; + if (id != 0) { - Patient patientToBeDeleted = patientManager.getPatient(id); - boolean toDelete = ui.confirmPatientToBeDeleted(patientToBeDeleted); - if (toDelete) { - patientManager.deletePatient(id); - ui.patientDeleted(); - patientStorage.save(patientManager.getPatientList()); - } + patientToBeDeleted = patientManager.getPatient(id); + ui.showPatientInfo(patientToBeDeleted); } else { ArrayList patientsWithSameName = patientManager.getPatientByName(deletedPatientInfo); ui.patientsFoundByName(patientsWithSameName, deletedPatientInfo); if (patientsWithSameName.size() >= 1) { int numberChosen = ui.choosePatientToDelete(patientsWithSameName.size()); if (numberChosen >= 1) { - boolean toDelete = ui.confirmPatientToBeDeleted(patientsWithSameName.get(numberChosen - 1)); - if (toDelete) { - patientManager.deletePatient(patientsWithSameName.get(numberChosen - 1).getID()); - ui.patientDeleted(); - patientStorage.save(patientManager.getPatientList()); - } + patientToBeDeleted = patientsWithSameName.get(numberChosen - 1); + ui.showPatientInfo(patientToBeDeleted); } } } + try { + patientTask = patientTaskList.getPatientTask(patientToBeDeleted.getID()); + ArrayList tempTask = new ArrayList<>(); + for (PatientTask temppatientTask : patientTask) { + tempTask.add(taskManager.getTask(temppatientTask.getTaskID())); + } + ui.patientTaskFound(patientToBeDeleted, patientTask, tempTask); + toDelete = ui.confirmPatientToBeDeleted(patientToBeDeleted, true); + } catch (Exception e) { + toDelete = ui.confirmPatientToBeDeleted(patientToBeDeleted,false); + } + if (toDelete) { + patientManager.deletePatient(patientToBeDeleted.getID()); + patientTaskList.deleteEntirePatientTask(patientToBeDeleted.getID()); + ui.patientDeleted(); + patientStorage.save(patientManager.getPatientList()); + patientTaskStorage.save(patientTaskList.fullPatientTaskList()); + } + } /** diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index ea3a7be9b1..a53649c75b 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -235,15 +235,20 @@ public int chooseTaskToDelete(int numberOfTasks) { /** * It confirms with user on the deletion of a patient. + * It reminds user that the tasks assigned to this user will be delete * If user confirms, key in 'Y'. Otherwise key in 'N'. * * @param patient it contains patient's info + * @param withTasksAssigned it indicates whether the patient is assigned to any tasks * @return true if user confirmed the deletion. False otherwise. */ - public boolean confirmPatientToBeDeleted(Patient patient) { - showPatientInfo(patient); + public boolean confirmPatientToBeDeleted(Patient patient, boolean withTasksAssigned) { while (true) { - System.out.println("The patient is to be deleted. Are you sure (Y/N)? "); + if (withTasksAssigned) { + System.out.println("The patient with above tasks assigned is to be deleted. Are you sure (Y/N)?"); + } else { + System.out.println("The patient is to be deleted. Are you sure (Y/N)? "); + } String command = readCommand(); if (command.toLowerCase().equals("y")) { return true; From 142f9e2a23bde30fc5da7db9d5455204a63b2aed Mon Sep 17 00:00:00 2001 From: Kejun Liu Date: Mon, 21 Oct 2019 19:47:53 +0800 Subject: [PATCH 184/420] Fix the wrong format of JavaDocs --- src/main/java/duke/command/DeletePatientCommand.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/duke/command/DeletePatientCommand.java b/src/main/java/duke/command/DeletePatientCommand.java index 322accf6e8..744faeaa3e 100644 --- a/src/main/java/duke/command/DeletePatientCommand.java +++ b/src/main/java/duke/command/DeletePatientCommand.java @@ -22,10 +22,10 @@ public class DeletePatientCommand extends Command { private String deletedPatientInfo; /** - * It checks whether user is deleting a patient by id - * It extracts the id of the patient to be deleted + * It checks whether user is deleting a patient by id. + * It extracts the id of the patient to be deleted. * - * @param deletedPatientInfo it contains the information of the patient to be deleted + * @param deletedPatientInfo it contains the information of the patient to be deleted * @throws DukeException it shows user the correct format to delete a patient by id */ public DeletePatientCommand(String deletedPatientInfo) throws DukeException { From 526e44460639807c27f71fbfb3b16500ca2a49df Mon Sep 17 00:00:00 2001 From: lmtaek Date: Mon, 21 Oct 2019 19:51:00 +0800 Subject: [PATCH 185/420] Modifying to satisfy conditions of checkstyle. --- src/main/java/duke/core/CommandManager.java | 19 ++++++------ src/main/java/duke/core/Parser.java | 32 +++++++++++---------- 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 28c9b27847..870c1d5e03 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -1,17 +1,17 @@ package duke.core; +import duke.command.AddPatientCommand; import duke.command.AddStandardTaskCommand; import duke.command.AssignTaskToPatientCommand; import duke.command.Command; -import duke.command.AddPatientCommand; -import duke.command.ListPatientsCommand; -import duke.command.ListTasksCommand; -import duke.command.DeletePatientTaskCommand; import duke.command.DeletePatientCommand; +import duke.command.DeletePatientTaskCommand; import duke.command.DeleteTaskCommand; +import duke.command.ExitCommand; import duke.command.FindPatientCommand; import duke.command.FindPatientTaskCommand; -import duke.command.ExitCommand; +import duke.command.ListPatientsCommand; +import duke.command.ListTasksCommand; import duke.command.UpdatePatientCommand; import duke.command.UpdateTaskCommand; @@ -75,12 +75,15 @@ public static Command manageCommand(String userInput) throws DukeException { throw new DukeException("Invalid 'list' command."); } case "delete": - if ((secondKeyword != "") && (thirdKeyword != "") && secondKeyword.equals("patient") && thirdKeyword.equals("task")) { - return new DeletePatientTaskCommand(parser.parseDeletePatientTask()); + if ((secondKeyword != "") + && (thirdKeyword != "") + && secondKeyword.equals("patient") + && thirdKeyword.equals("task")) { + return new DeletePatientTaskCommand(parser.parseDeletePatientTask()); } else if ((secondKeyword != "") && secondKeyword.equals("patient")) { String formattedInput = parser.parseDeletePatient(); return new DeletePatientCommand(formattedInput); - } else if ((secondKeyword != "") && secondKeyword.equals("task")) { + } else if ((secondKeyword != "") && secondKeyword.equals("task")) { return new DeleteTaskCommand(parser.parseDeleteTask()); } else { throw new DukeException("Invalid 'delete' command."); diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index c7f9f913be..5465388e80 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -19,7 +19,7 @@ public Parser(String userInput) { * * @return A formatted string that will work for the available 'add' commands. * @throws DukeException If the method is unable to parse the userInput correctly, it will throw - * a DukeException. + * a DukeException. */ public String[] parseAdd() throws DukeException { String[] parsedCommand = userInput.toLowerCase().split("\\s+", 3); @@ -48,21 +48,21 @@ public String[] parseAdd() throws DukeException { public String[] parseAssign() throws DukeException { String[] formattedInput = new String[5]; try { - String[] tempInput = userInput.trim().replaceAll( - "(?i)assign ", "").split("\\s+", 4); - if (tempInput[0].equals("E")) { - String[] parsedTimes = tempInput[3].split(" to ", 2); - - for (int i = 0; i < 3; i++) { - formattedInput[i] = tempInput[i]; - } - formattedInput[3] = parsedTimes[0]; - formattedInput[4] = parsedTimes[1]; - } else { - for (int i = 0; i < tempInput.length; i++) { - formattedInput[i] = tempInput[i]; - } + String[] tempInput = userInput.trim().replaceAll( + "(?i)assign ", "").split("\\s+", 4); + if (tempInput[0].equals("E")) { + String[] parsedTimes = tempInput[3].split(" to ", 2); + + for (int i = 0; i < 3; i++) { + formattedInput[i] = tempInput[i]; + } + formattedInput[3] = parsedTimes[0]; + formattedInput[4] = parsedTimes[1]; + } else { + for (int i = 0; i < tempInput.length; i++) { + formattedInput[i] = tempInput[i]; } + } return formattedInput; } catch (Exception e) { throw new DukeException("Invalid 'assign' command."); @@ -84,6 +84,7 @@ public String[] parseList() throws DukeException { throw new DukeException("Invalid 'list' command."); } } + /** * Takes the user input and formats it so it is compatible with 'delete patient' command. * @@ -120,6 +121,7 @@ public String parseDeleteTask() throws DukeException { /** * Takes user input and formats it so it is compatible with 'delete patient task' command. + * * @return Array of strings to be used by 'delete patient task' command. * @throws DukeException when user input cannot be parsed properly. */ From 80294664f6087ae2b8a2d7bc633202c20366f345 Mon Sep 17 00:00:00 2001 From: lmtaek Date: Mon, 21 Oct 2019 20:08:52 +0800 Subject: [PATCH 186/420] Changed formatting of CommandManager to pass Checkstyle tests. --- src/main/java/duke/core/CommandManager.java | 122 ++++++++++---------- 1 file changed, 61 insertions(+), 61 deletions(-) diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 870c1d5e03..8a52deb14d 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -50,67 +50,67 @@ public static Command manageCommand(String userInput) throws DukeException { Parser parser = new Parser(userInput); switch (firstKeyword) { - case "add": - if ((secondKeyword != "") && secondKeyword.equals("patient")) { - String[] formattedInput = parser.parseAdd(); - AddPatientCommand addPatientCommand = new AddPatientCommand(formattedInput); - return addPatientCommand; - } else if ((secondKeyword != "") && secondKeyword.equals("task")) { - String formattedInput = parser.parseAdd()[0]; - AddStandardTaskCommand addStandardTaskCommand = new AddStandardTaskCommand(formattedInput); - return addStandardTaskCommand; - } else { - throw new DukeException("Add command fails."); - } - case "assign": - return new AssignTaskToPatientCommand(parser.parseAssign()); - case "list": - String[] tempCommand = parser.parseList(); - String nextKeyword = tempCommand[0].toLowerCase(); - if (nextKeyword.equals("patients")) { - return new ListPatientsCommand(); - } else if (nextKeyword.equals("tasks")) { - return new ListTasksCommand(); - } else { - throw new DukeException("Invalid 'list' command."); - } - case "delete": - if ((secondKeyword != "") - && (thirdKeyword != "") - && secondKeyword.equals("patient") - && thirdKeyword.equals("task")) { - return new DeletePatientTaskCommand(parser.parseDeletePatientTask()); - } else if ((secondKeyword != "") && secondKeyword.equals("patient")) { - String formattedInput = parser.parseDeletePatient(); - return new DeletePatientCommand(formattedInput); - } else if ((secondKeyword != "") && secondKeyword.equals("task")) { - return new DeleteTaskCommand(parser.parseDeleteTask()); - } else { - throw new DukeException("Invalid 'delete' command."); - } - case "find": - if ((secondKeyword != "") && secondKeyword.equals("patient")) { - return new FindPatientCommand(parser.parseFind()); - } else if (secondKeyword.equals("patient") && ((thirdKeyword != "") && thirdKeyword.equals("task"))) { - return new FindPatientTaskCommand(parser.parseFind()); - } else { - throw new DukeException("Invalid 'find' command. "); - } - case "update": - if ((secondKeyword != "") && secondKeyword.equals("patient")) { - String formattedInput = parser.parseUpdatePatient(); - return new UpdatePatientCommand(formattedInput); - } else if (secondKeyword.equals("task")) { - String formattedInput = parser.parseUpdateTask(); - return new UpdateTaskCommand(formattedInput); - } else { - throw new DukeException("Invalid 'update' command. "); - } - case "bye": - ExitCommand exitCommand = new ExitCommand(); - return exitCommand; - default: - throw new DukeException("Could not understand user input"); + case "add": + if ((secondKeyword != "") && secondKeyword.equals("patient")) { + String[] formattedInput = parser.parseAdd(); + AddPatientCommand addPatientCommand = new AddPatientCommand(formattedInput); + return addPatientCommand; + } else if ((secondKeyword != "") && secondKeyword.equals("task")) { + String formattedInput = parser.parseAdd()[0]; + AddStandardTaskCommand addStandardTaskCommand = new AddStandardTaskCommand(formattedInput); + return addStandardTaskCommand; + } else { + throw new DukeException("Add command fails."); + } + case "assign": + return new AssignTaskToPatientCommand(parser.parseAssign()); + case "list": + String[] tempCommand = parser.parseList(); + String nextKeyword = tempCommand[0].toLowerCase(); + if (nextKeyword.equals("patients")) { + return new ListPatientsCommand(); + } else if (nextKeyword.equals("tasks")) { + return new ListTasksCommand(); + } else { + throw new DukeException("Invalid 'list' command."); + } + case "delete": + if ((secondKeyword != "") + && (thirdKeyword != "") + && secondKeyword.equals("patient") + && thirdKeyword.equals("task")) { + return new DeletePatientTaskCommand(parser.parseDeletePatientTask()); + } else if ((secondKeyword != "") && secondKeyword.equals("patient")) { + String formattedInput = parser.parseDeletePatient(); + return new DeletePatientCommand(formattedInput); + } else if ((secondKeyword != "") && secondKeyword.equals("task")) { + return new DeleteTaskCommand(parser.parseDeleteTask()); + } else { + throw new DukeException("Invalid 'delete' command."); + } + case "find": + if ((secondKeyword != "") && secondKeyword.equals("patient")) { + return new FindPatientCommand(parser.parseFind()); + } else if (secondKeyword.equals("patient") && ((thirdKeyword != "") && thirdKeyword.equals("task"))) { + return new FindPatientTaskCommand(parser.parseFind()); + } else { + throw new DukeException("Invalid 'find' command. "); + } + case "update": + if ((secondKeyword != "") && secondKeyword.equals("patient")) { + String formattedInput = parser.parseUpdatePatient(); + return new UpdatePatientCommand(formattedInput); + } else if (secondKeyword.equals("task")) { + String formattedInput = parser.parseUpdateTask(); + return new UpdateTaskCommand(formattedInput); + } else { + throw new DukeException("Invalid 'update' command. "); + } + case "bye": + ExitCommand exitCommand = new ExitCommand(); + return exitCommand; + default: + throw new DukeException("Could not understand user input"); } } } From bdd99985f3f4e5c05c869c43ba76d6c9b11148d3 Mon Sep 17 00:00:00 2001 From: Kejun Liu Date: Mon, 21 Oct 2019 20:12:18 +0800 Subject: [PATCH 187/420] Correct update task command DukeException --- src/main/java/duke/command/UpdateTaskCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/duke/command/UpdateTaskCommand.java b/src/main/java/duke/command/UpdateTaskCommand.java index 35e54a5d66..6843461964 100644 --- a/src/main/java/duke/command/UpdateTaskCommand.java +++ b/src/main/java/duke/command/UpdateTaskCommand.java @@ -58,7 +58,7 @@ public void execute(PatientTaskList patientTask, TaskManager taskManager, Patien ui.showTaskInfo(taskToBeUpdated); } catch (Exception e) { throw new DukeException( - "Please follow the format 'update patient # '."); + "Please follow the format 'update task # description '."); } } From ee7bdb352600951ed44cdb6e19abeb0ce4fa123b Mon Sep 17 00:00:00 2001 From: lmtaek Date: Mon, 21 Oct 2019 20:20:57 +0800 Subject: [PATCH 188/420] Deleted unnecessary files. --- build/reports/checkstyle/main.html | 419 ----------------------------- build/reports/checkstyle/main.xml | 69 ----- 2 files changed, 488 deletions(-) delete mode 100644 build/reports/checkstyle/main.html delete mode 100644 build/reports/checkstyle/main.xml diff --git a/build/reports/checkstyle/main.html b/build/reports/checkstyle/main.html deleted file mode 100644 index 15b60ddde3..0000000000 --- a/build/reports/checkstyle/main.html +++ /dev/null @@ -1,419 +0,0 @@ - - - - - - - - - - - - - - -
-

CheckStyle Audit

-
Designed for use with CheckStyle and Ant.
-
-

Summary

- - - - - - - -
FilesErrors
330
-
-

Files

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameErrors
/Users/qianjie/Desktop/main/src/main/java/duke/Duke.java0
/Users/qianjie/Desktop/main/src/main/java/duke/command/AddPatientCommand.java0
/Users/qianjie/Desktop/main/src/main/java/duke/command/AddStandardTaskCommand.java0
/Users/qianjie/Desktop/main/src/main/java/duke/command/AssignTaskToPatientCommand.java0
/Users/qianjie/Desktop/main/src/main/java/duke/command/Command.java0
/Users/qianjie/Desktop/main/src/main/java/duke/command/DeletePatientCommand.java0
/Users/qianjie/Desktop/main/src/main/java/duke/command/DeleteTaskCommand.java0
/Users/qianjie/Desktop/main/src/main/java/duke/command/ExitCommand.java0
/Users/qianjie/Desktop/main/src/main/java/duke/command/FindPatientCommand.java0
/Users/qianjie/Desktop/main/src/main/java/duke/command/FindPatientTaskCommand.java0
/Users/qianjie/Desktop/main/src/main/java/duke/command/HelpCommand.java0
/Users/qianjie/Desktop/main/src/main/java/duke/command/ListPatientsCommand.java0
/Users/qianjie/Desktop/main/src/main/java/duke/command/ListTasksCommand.java0
/Users/qianjie/Desktop/main/src/main/java/duke/command/UpdatePatientCommand.java0
/Users/qianjie/Desktop/main/src/main/java/duke/command/UpdateTaskCommand.java0
/Users/qianjie/Desktop/main/src/main/java/duke/core/CommandManager.java0
/Users/qianjie/Desktop/main/src/main/java/duke/core/DateTimeParser.java0
/Users/qianjie/Desktop/main/src/main/java/duke/core/DukeException.java0
/Users/qianjie/Desktop/main/src/main/java/duke/core/Parser.java0
/Users/qianjie/Desktop/main/src/main/java/duke/core/Ui.java0
/Users/qianjie/Desktop/main/src/main/java/duke/patient/Patient.java0
/Users/qianjie/Desktop/main/src/main/java/duke/patient/PatientManager.java0
/Users/qianjie/Desktop/main/src/main/java/duke/relation/EventPatientTask.java0
/Users/qianjie/Desktop/main/src/main/java/duke/relation/PatientTask.java0
/Users/qianjie/Desktop/main/src/main/java/duke/relation/PatientTaskList.java0
/Users/qianjie/Desktop/main/src/main/java/duke/relation/StandardPatientTask.java0
/Users/qianjie/Desktop/main/src/main/java/duke/statistic/Counter.java0
/Users/qianjie/Desktop/main/src/main/java/duke/storage/CounterStorage.java0
/Users/qianjie/Desktop/main/src/main/java/duke/storage/PatientStorage.java0
/Users/qianjie/Desktop/main/src/main/java/duke/storage/PatientTaskStorage.java0
/Users/qianjie/Desktop/main/src/main/java/duke/storage/TaskStorage.java0
/Users/qianjie/Desktop/main/src/main/java/duke/task/Task.java0
/Users/qianjie/Desktop/main/src/main/java/duke/task/TaskManager.java0
-
- -

File /Users/qianjie/Desktop/main/src/main/java/duke/Duke.java

- - - - -
Error DescriptionLine
- Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/command/AddPatientCommand.java

- - - - -
Error DescriptionLine
- Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/command/AddStandardTaskCommand.java

- - - - -
Error DescriptionLine
- Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/command/AssignTaskToPatientCommand.java

- - - - -
Error DescriptionLine
- Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/command/Command.java

- - - - -
Error DescriptionLine
- Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/command/DeletePatientCommand.java

- - - - -
Error DescriptionLine
- Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/command/DeleteTaskCommand.java

- - - - -
Error DescriptionLine
- Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/command/ExitCommand.java

- - - - -
Error DescriptionLine
- Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/command/FindPatientCommand.java

- - - - -
Error DescriptionLine
- Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/command/FindPatientTaskCommand.java

- - - - -
Error DescriptionLine
- Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/command/HelpCommand.java

- - - - -
Error DescriptionLine
- Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/command/ListPatientsCommand.java

- - - - -
Error DescriptionLine
- Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/command/ListTasksCommand.java

- - - - -
Error DescriptionLine
- Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/command/UpdatePatientCommand.java

- - - - -
Error DescriptionLine
- Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/command/UpdateTaskCommand.java

- - - - -
Error DescriptionLine
- Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/core/CommandManager.java

- - - - -
Error DescriptionLine
- Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/core/DateTimeParser.java

- - - - -
Error DescriptionLine
- Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/core/DukeException.java

- - - - -
Error DescriptionLine
- Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/core/Parser.java

- - - - -
Error DescriptionLine
- Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/core/Ui.java

- - - - -
Error DescriptionLine
- Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/patient/Patient.java

- - - - -
Error DescriptionLine
- Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/patient/PatientManager.java

- - - - -
Error DescriptionLine
- Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/relation/EventPatientTask.java

- - - - -
Error DescriptionLine
- Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/relation/PatientTask.java

- - - - -
Error DescriptionLine
- Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/relation/PatientTaskList.java

- - - - -
Error DescriptionLine
- Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/relation/StandardPatientTask.java

- - - - -
Error DescriptionLine
- Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/statistic/Counter.java

- - - - -
Error DescriptionLine
- Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/storage/CounterStorage.java

- - - - -
Error DescriptionLine
- Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/storage/PatientStorage.java

- - - - -
Error DescriptionLine
- Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/storage/PatientTaskStorage.java

- - - - -
Error DescriptionLine
- Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/storage/TaskStorage.java

- - - - -
Error DescriptionLine
- Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/task/Task.java

- - - - -
Error DescriptionLine
- Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/task/TaskManager.java

- - - - -
Error DescriptionLine
- Back to top -
- - diff --git a/build/reports/checkstyle/main.xml b/build/reports/checkstyle/main.xml deleted file mode 100644 index 8c72856fa6..0000000000 --- a/build/reports/checkstyle/main.xml +++ /dev/null @@ -1,69 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From edd8c633586c532d673757b15ef366697198132f Mon Sep 17 00:00:00 2001 From: WEIFENG-NUSCEG Date: Mon, 21 Oct 2019 22:05:26 +0800 Subject: [PATCH 189/420] This update gives the user a new function to remove all the tasks assigned to a patient in one command --- data/patientsTasks.csv | 21 +++----- .../command/DeletePatientTaskCommand.java | 49 ++++++++++--------- .../duke/command/FindPatientTaskCommand.java | 2 +- src/main/java/duke/core/Parser.java | 9 ++-- src/main/java/duke/core/Ui.java | 19 ++++--- .../java/duke/relation/PatientTaskList.java | 13 ++++- 6 files changed, 63 insertions(+), 50 deletions(-) diff --git a/data/patientsTasks.csv b/data/patientsTasks.csv index 6a79f9c95a..be95c35174 100644 --- a/data/patientsTasks.csv +++ b/data/patientsTasks.csv @@ -1,15 +1,8 @@ PID,TID,DONE,RECURRENCE,DEADLINE,STARTTIME,ENDTIME,TASKTYPE,uuid -1,2,false,false,09/11/2019 1400,,,S,1 -1,3,false,false,09/01/2018 1200,,,S,2 -1,3,false,false,04/04/2019 1400,,,S,3 -1,3,false,false,09/08/2020 1200,,,S,4 -1,3,false,false,09/05/2013 0900,,,S,5 -1,3,false,false,,16/09/2019 1400,12/08/2020 1200,E,6 -1,3,false,false,09/11/2019 1400,,,S,7 -2,7,false,false,,09/01/2019 1200,08/11/2019 1000,E,9 -2,7,false,false,09/05/2013 0150,,,S,10 -2,7,false,false,,09/11/2018 1400,08/08/2019 1200,E,11 -2,7,false,false,,08/08/2018 1400,09/09/2019 1200,E,12 -2,7,false,false,,09/08/2019 1200,09/12/2019 1200,E,13 -3,8,false,false,09/01/2022 1400,,,S,14 -3,5,false,false,,05/11/2019 1200,05/04/2022 1200,E,15 +2,7,false,false,,09/01/2019 1200,08/11/2019 1000,E,8 +2,7,false,false,09/05/2013 0150,,,S,9 +2,7,false,false,,09/11/2018 1400,08/08/2019 1200,E,10 +2,7,false,false,,08/08/2018 1400,09/09/2019 1200,E,11 +2,7,false,false,,09/08/2019 1200,09/12/2019 1200,E,12 +3,8,false,false,09/01/2022 1400,,,S,13 +3,5,false,false,,05/11/2019 1200,05/04/2022 1200,E,14 diff --git a/src/main/java/duke/command/DeletePatientTaskCommand.java b/src/main/java/duke/command/DeletePatientTaskCommand.java index 1a13b1d8ba..5da064e6e4 100644 --- a/src/main/java/duke/command/DeletePatientTaskCommand.java +++ b/src/main/java/duke/command/DeletePatientTaskCommand.java @@ -31,19 +31,20 @@ public class DeletePatientTaskCommand extends Command { * @param deleteInfo . * @throws DukeException . */ - public DeletePatientTaskCommand(String[] deleteInfo) throws DukeException { + public DeletePatientTaskCommand(String deleteInfo) throws DukeException { - char firstChar = deleteInfo[0].charAt(0); + char firstChar = deleteInfo.charAt(0); try { if (firstChar == '#') { - this.patientId = Integer.parseInt(deleteInfo[0].replace("#","").trim()); - this.taskId = Integer.parseInt(deleteInfo[1]); + this.patientId = Integer.parseInt(deleteInfo.replace("#","").trim()); + } else if (firstChar == '%') { + this.taskId = Integer.parseInt(deleteInfo.replace("%","").trim()); } else { - this.deletedPatientInfo = deleteInfo[0]; - this.taskId = Integer.parseInt(deleteInfo[1]); + this.deletedPatientInfo = deleteInfo; } } catch (Exception e) { - throw new DukeException("Try to follow the format: delete patienttask #patientid taskuniqeid"); + throw new DukeException("Try to follow the format: delete patienttask %/#" + + "/. "); } } @@ -66,31 +67,33 @@ public void execute(PatientTaskList patientTaskList, TaskManager tasks, PatientM if (patientId != 0) { try { Patient toBeDeletedPatient = patientManager.getPatient(patientId); - for (PatientTask patientTask: patientTaskList.getPatientTask(patientId)) { - if (patientTask.getUid() == taskId) { - patientTaskList.deletePatientTaskByUniqueId(taskId); - patientTaskStorage.save(patientTaskList.fullPatientTaskList()); - ui.patientTaskDeleted(patientTask, toBeDeletedPatient); - } + if (patientTaskList.isPatientIdExist(patientId)) { + patientTaskList.deleteEntirePatientTask(patientId); + patientTaskStorage.save(patientTaskList.fullPatientTaskList()); + ui.patientTaskAllDeleted(patientManager.getPatient(patientId)); } } catch (DukeException e) { - throw new DukeException("Task or patient is not found!" + e.getMessage()); + throw new DukeException("Patient is not found!"); + } + } else if (taskId != 0) { + try { + patientTaskList.deletePatientTaskByUniqueId(taskId); + patientTaskStorage.save(patientTaskList.fullPatientTaskList()); + ui.patientTaskDeleted(taskId); + } catch (DukeException e) { + throw new DukeException("Task is not found!"); } } else { try { String patientName = this.deletedPatientInfo; ArrayList patientsWithSameName = patientManager.getPatientByName(patientName); - ArrayList toBeDeleted = - patientTaskList.getPatientTask(patientsWithSameName.get(0).getID()); - for (PatientTask patientTask: toBeDeleted) { - if (patientTask.getUid() == taskId) { - patientTaskList.deletePatientTaskByUniqueId(taskId); - patientTaskStorage.save(patientTaskList.fullPatientTaskList()); - ui.patientTaskDeleted(patientTask, patientsWithSameName.get(0)); - } + if (patientTaskList.isPatientIdExist(patientsWithSameName.get(0).getID())) { + patientTaskList.deleteEntirePatientTask(patientsWithSameName.get(0).getID()); + patientTaskStorage.save(patientTaskList.fullPatientTaskList()); + ui.patientTaskAllDeleted(patientManager.getPatient(patientsWithSameName.get(0).getID())); } } catch (Exception e) { - throw new DukeException("Task or patient is not found!"); + throw new DukeException("Patient is not found!"); } } } diff --git a/src/main/java/duke/command/FindPatientTaskCommand.java b/src/main/java/duke/command/FindPatientTaskCommand.java index dce52d2670..374bbe0b55 100644 --- a/src/main/java/duke/command/FindPatientTaskCommand.java +++ b/src/main/java/duke/command/FindPatientTaskCommand.java @@ -79,7 +79,7 @@ public void execute(PatientTaskList patientTaskList, TaskManager tasksManager, P ui.patientTaskFound(patientsWithSameName.get(0), patientWithTask, tempTask); } catch (Exception e) { - throw new DukeException("Please follow the format 'find patienttask #' or 'find patient '."); + throw new DukeException("You may entered the wrong format or the patient does not have any tasks"); } } } diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index 485394cf4b..98b4fc2951 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -43,12 +43,11 @@ public String[] parseAdd() throws DukeException { * @return . * @throws DukeException . */ - public String[] parseDeletePatientTask() throws DukeException { - String[] formattedInput = new String[2]; + public String parseDeletePatientTask() throws DukeException { + String formattedInput; try { - String[] parsedCommand = userInput.split("\\s+", 4); - formattedInput[0] = parsedCommand[2]; - formattedInput[1] = parsedCommand[3]; + String[] parsedCommand = userInput.split("\\s+", 3); + formattedInput = parsedCommand[2]; return formattedInput; } catch (Exception e) { throw new DukeException("Please use the correct format for the 'delete patienttask' command. "); diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index ea3a7be9b1..1469f0dfde 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -273,15 +273,22 @@ public void taskDeleted() { /** * It lists out all info of patients. * - * @param patient the patients to be listed out - * @param patientTask the patients to be listed out + * @param id the patients to be listed out */ - public void patientTaskDeleted(PatientTask patientTask, Patient patient) { - System.out.println("Got it. The task with "); - System.out.println(patientTask.toString()); - System.out.println("has been deleted from patient: " + patient.getID() + " " + patient.getName()); + public void patientTaskDeleted(int id) { + System.out.println("Got it. The task with unique ID: " + id + "has been deleted"); } + /** + * It lists out all info of patients. + * + * @param patient the patients to be listed out + */ + public void patientTaskAllDeleted(Patient patient) { + System.out.println("Got it. The tasks belong to: "); + System.out.println(patient.getName()); + System.out.println("has been deleted"); + } /** * It lists out all info of patients. diff --git a/src/main/java/duke/relation/PatientTaskList.java b/src/main/java/duke/relation/PatientTaskList.java index fcc8d0da18..e4d0a55bc7 100644 --- a/src/main/java/duke/relation/PatientTaskList.java +++ b/src/main/java/duke/relation/PatientTaskList.java @@ -74,7 +74,6 @@ public void deletePatientTaskByUniqueId(int uid) throws DukeException { return; } } - throw new DukeException("Such Task does not exist!"); } @@ -92,6 +91,18 @@ public boolean isIdExist(int id) { return false; } + /** + * . + * + * @return . + */ + public boolean isPatientIdExist(int id) { + if (patientTaskIdMap.containsKey(id)) { + return true; + } + return false; + } + /** * . * From 7a0563536d6a292dda1df589361169120983b25e Mon Sep 17 00:00:00 2001 From: Qian Jie Date: Mon, 21 Oct 2019 22:20:02 +0800 Subject: [PATCH 190/420] DukeCommand + Shortcut method completed , except AssignPatientTask and FindPatientTask command. --- src/main/java/duke/Duke.java | 8 +- src/main/java/duke/command/DukeCommand.java | 22 +- src/main/java/duke/core/ShortCutter.java | 417 +++++++++--------- src/main/java/duke/core/Ui.java | 81 ++++ .../java/duke/storage/CounterStorage.java | 2 +- 5 files changed, 307 insertions(+), 223 deletions(-) diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index 799555a785..24ba8e66a6 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -61,7 +61,7 @@ public Duke(String filePath) { taskManager = new TaskManager(taskStorage.load()); patientManager = new PatientManager(patientStorage.load()); counter = new Counter(counterStorage.load()); - shortCutter = new ShortCutter(counter , ui); + shortCutter = new ShortCutter(counter, ui); } catch (DukeException e) { ui.showLoadingError(); @@ -83,10 +83,10 @@ public void run() { ui.showLine(); Command c = CommandManager.manageCommand(fullCommand); if (c instanceof DukeCommand) { - Command cmd = shortCutter.runShortCut(); - cmd.execute(patientTaskList, taskManager, patientManager, + Command command = shortCutter.runShortCut(); + command.execute(patientTaskList, taskManager, patientManager, ui, patientTaskStorage, taskStorage, patientStorage); - } else{ + } else { c.execute(patientTaskList, taskManager, patientManager, ui, patientTaskStorage, taskStorage, patientStorage); counter.runCommandCounter(c, counterStorage, counter); diff --git a/src/main/java/duke/command/DukeCommand.java b/src/main/java/duke/command/DukeCommand.java index 6139cb1dfa..4767e26790 100644 --- a/src/main/java/duke/command/DukeCommand.java +++ b/src/main/java/duke/command/DukeCommand.java @@ -9,12 +9,32 @@ import duke.storage.TaskStorage; import duke.task.TaskManager; -public class DukeCommand extends Command{ + +public class DukeCommand extends Command { + + /** + * . + * + * @param patientTask . + * @param tasks . + * @param patientList . + * @param ui . + * @param patientTaskStorage . + * @param taskStorage . + * @param patientStorage . + * @throws DukeException . + */ @Override public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { System.out.println("DUKE SHORTCUT"); } + /** + * Decide whether duke should exist. + * + * @return A boolean. True if the command tells Duke to exit, false + */ + @Override public boolean isExit() { return false; diff --git a/src/main/java/duke/core/ShortCutter.java b/src/main/java/duke/core/ShortCutter.java index d32f356953..eadf5f7d95 100644 --- a/src/main/java/duke/core/ShortCutter.java +++ b/src/main/java/duke/core/ShortCutter.java @@ -3,12 +3,32 @@ import duke.command.*; import duke.statistic.Counter; -import java.util.*; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Map; +import java.util.TreeMap; + +/** + * This is a ShortCutter class to provide short cut implementation. + * DukeCommand will be used to activate the short cut mode. + * This is not a simple UI implementation but also considered user's + * daily work behavior to provide personalised short cut solution. + * + * @author QIAN JIE + * @version 1.3 + */ public class ShortCutter { - Counter counter; - Ui ui; - + private Counter counter; + private Ui ui; + + /** + * A constructor for ShortCutter class + * + * @param counter receive a counter object + * @param ui receive a ui object + */ public ShortCutter(Counter counter, Ui ui) { this.counter = counter; this.ui = ui; @@ -17,6 +37,16 @@ public ShortCutter(Counter counter, Ui ui) { private Map sortedCommandTable; private Map topUsedCommandTable; + + /** + * This function is used to allow map to be sorted by its values. + * + * @param map a command frequency table in Map structure with key + * as the command type and value as the command frequency. + * @return a Map structure that is sorted according to param's value + * which is the used command frequency. + */ + public static > Map sortByValues(final Map map) { Comparator valueComparator = (k1, k2) -> { int compare = map.get(k2).compareTo(map.get(k1)); @@ -30,237 +60,190 @@ public static > Map sortByValues(final Map MapSorter(Map sortedCommandTable) throws DukeException { + Map topCommandTable = new HashMap<>(); + ArrayList keys = new ArrayList<>(sortedCommandTable.keySet()); + System.out.println("< Most Frequently Used Commands >"); + if (sortedCommandTable.size() < 5) { + for (int i = 0; i < sortedCommandTable.size(); i++) { + int index = i + 1; + topCommandTable.put(index, keys.get(i)); + System.out.println("[" + index + "] " + commandNameConverter(keys.get(i))); + } + + } else { + for (int i = 0; i < 5; i++) { + int index = i + 1; + topCommandTable.put(index, keys.get(i)); + System.out.println("[" + index + "] " + commandNameConverter(keys.get(i))); + } + } + System.out.println("Please choose one of these commands"); + return topCommandTable; + } + + /** + * This function is used to run the short cut UI logic by getting + * necessary information from user to provide the target output + * + * @return command the command that is to be executed. + * @throws DukeException throw a dukeException with error message for debugging. + * @author QIAN JIE + */ public Command runShortCut() throws DukeException { sortedCommandTable = sortByValues(counter.getCommandTable()); topUsedCommandTable = MapSorter(sortedCommandTable); String commandName; + Command command; String choiceIndex = ui.readCommand(); switch (choiceIndex) { case "1": commandName = topUsedCommandTable.get(1); - if (commandName.equals("AddPatientCommand")) { - String name; - String nric; - String room; - String remark; - System.out.println("Name?"); - name = ui.readCommand(); - System.out.println("NRIC?"); - nric = ui.readCommand(); - System.out.println("Room?"); - room = ui.readCommand(); - System.out.println("Remark?"); - remark = ui.readCommand(); - - String[] patientInfo = new String[]{name, nric, room, remark}; - return new AddPatientCommand(patientInfo); - } else if (commandName.equals("AddStandardTaskCommand")) { - System.out.println("Task Name?"); - String taskName = ui.readCommand(); - return new AddStandardTaskCommand(taskName); - } else if (commandName.equals("DeletePatientCommand")) { - System.out.println("Patient ID Number ?"); - String patientId = ui.readCommand(); - return new DeletePatientCommand(patientId); - - } else if (commandName.equals("DeleteTaskCommand")) { - System.out.println("Task ID?"); - String taskId = "#" + ui.readCommand(); - return new DeleteTaskCommand(taskId); - - } else if (commandName.equals("FindPatientCommand")) { - System.out.println("Patient ID?"); - String patientId = "#" + ui.readCommand(); - return new FindPatientCommand(patientId); - - } else if (commandName.equals("FindPatientTaskCommand")) { - System.out.println("Task ID?"); - String taskId = "#" + ui.readCommand(); - return new FindPatientTaskCommand(taskId); // check for command - - } else if (commandName.equals("ListPatientsCommand")) { - return new ListPatientsCommand(); - - } else if (commandName.equals("ListTasksCommand")) { - return new ListTasksCommand(); - - } else if (commandName.equals("UpdatePatientCommand")) { - String patientId; - String infoType; - String changedValue; - System.out.println("Patient ID ?"); - patientId = "#" + ui.readCommand(); - System.out.println("what do you want to change?"); - infoType = ui.readCommand(); - System.out.println("Change to ?"); - changedValue = ui.readCommand(); - - String userInput = patientId + infoType + changedValue; - return new UpdatePatientCommand(userInput); - } - -// } else if (commandName.equals("UpdateTaskCommand")) { -// -// -// -// } else if (commandName.equals("AssignTaskToPatientCommand")) { -// -// -// } - + command = shortCutChecker(commandName); + return command; case "2": commandName = topUsedCommandTable.get(2); - if (commandName.equals("AddPatientCommand")) { - String name; - String nric; - String room; - String remark; - System.out.println("Name?"); - name = ui.readCommand(); - System.out.println("NRIC?"); - nric = ui.readCommand(); - System.out.println("Room?"); - room = ui.readCommand(); - System.out.println("Remark?"); - remark = ui.readCommand(); - - String[] patientInfo = new String[]{name, nric, room, remark}; - return new AddPatientCommand(patientInfo); - } else if (commandName.equals("AddStandardTaskCommand")) { - System.out.println("Task Name?"); - String taskName = ui.readCommand(); - return new AddStandardTaskCommand(taskName); - } else if (commandName.equals("DeletePatientCommand")) { - System.out.println("Patient ID Number ?"); - String patientId = ui.readCommand(); - return new DeletePatientCommand(patientId); - - } else if (commandName.equals("DeleteTaskCommand")) { - System.out.println("Task ID?"); - String taskId = "#" + ui.readCommand(); - return new DeleteTaskCommand(taskId); - - } else if (commandName.equals("FindPatientCommand")) { - System.out.println("Patient ID?"); - String patientId = "#" + ui.readCommand(); - return new FindPatientCommand(patientId); - - } else if (commandName.equals("FindPatientTaskCommand")) { - System.out.println("Task ID?"); - String taskId = "#" + ui.readCommand(); - return new FindPatientTaskCommand(taskId); // check for command - - } else if (commandName.equals("ListPatientsCommand")) { - return new ListPatientsCommand(); // check for command - - } else if (commandName.equals("ListTasksCommand")) { - return new ListTasksCommand(); // check for command - - } else if (commandName.equals("UpdatePatientCommand")) { - String patientId; - String infoType; - String changedValue; - System.out.println("Patient ID ?"); - patientId = "#" + ui.readCommand(); - System.out.println("what do you want to change?"); - infoType = ui.readCommand(); - System.out.println("Change to ?"); - changedValue = ui.readCommand(); - - String userInput = patientId + infoType + changedValue; - return new UpdatePatientCommand(userInput); - } - case "3": { + command = shortCutChecker(commandName); + return command; + case "3": commandName = topUsedCommandTable.get(3); - if (commandName.equals("AddPatientCommand")) { - String name; - String nric; - String room; - String remark; - System.out.println("Name?"); - name = ui.readCommand(); - System.out.println("NRIC?"); - nric = ui.readCommand(); - System.out.println("Room?"); - room = ui.readCommand(); - System.out.println("Remark?"); - remark = ui.readCommand(); - - String[] patientInfo = new String[]{name, nric, room, remark}; - return new AddPatientCommand(patientInfo); - } else if (commandName.equals("AddStandardTaskCommand")) { - System.out.println("Task Name?"); - String taskName = ui.readCommand(); - return new AddStandardTaskCommand(taskName); - } else if (commandName.equals("DeletePatientCommand")) { - System.out.println("Patient ID Number ?"); - String patientId = ui.readCommand(); - return new DeletePatientCommand(patientId); - - } else if (commandName.equals("DeleteTaskCommand")) { - System.out.println("Task ID?"); - String taskId = "#" + ui.readCommand(); - return new DeleteTaskCommand(taskId); - - } else if (commandName.equals("FindPatientCommand")) { - System.out.println("Patient ID?"); - String patientId = "#" + ui.readCommand(); - return new FindPatientCommand(patientId); - - } else if (commandName.equals("FindPatientTaskCommand")) { - System.out.println("Task ID?"); - String taskId = "#" + ui.readCommand(); - return new FindPatientTaskCommand(taskId); // check for command - - } else if (commandName.equals("ListPatientsCommand")) { - return new ListPatientsCommand(); // check for command - - } else if (commandName.equals("ListTasksCommand")) { - return new ListTasksCommand(); // check for command - - } else if (commandName.equals("UpdatePatientCommand")) { - String patientId; - String infoType; - String changedValue; - System.out.println("Patient ID ?"); - patientId = "#" + ui.readCommand(); - System.out.println("what do you want to change?"); - infoType = ui.readCommand(); - System.out.println("Change to ?"); - changedValue = ui.readCommand(); - - String userInput = patientId + infoType + changedValue; - return new UpdatePatientCommand(userInput); - } - - } - + command = shortCutChecker(commandName); + return command; + case "4": + commandName = topUsedCommandTable.get(4); + command = shortCutChecker(commandName); + return command; + case "5": + commandName = topUsedCommandTable.get(5); + command = shortCutChecker(commandName); + return command; default: - throw new DukeException("ERROR"); + throw new DukeException("Please enter a valid index number shown here"); } } - public Map MapSorter(Map sortedCommandTable) { - Map topCommandTable = new HashMap<>(); - ArrayList keys = new ArrayList<>(sortedCommandTable.keySet()); - if (sortedCommandTable.size() < 3) { - for (int i = 0; i < sortedCommandTable.size(); i++) { - int index = i + 1; - topCommandTable.put(index, keys.get(i)); - System.out.println("[" + index + "] " + keys.get(i)); - } - - } else { - for (int i = 0; i < 3; i++) { - int index = i + 1; - topCommandTable.put(index, keys.get(i)); - System.out.println("[" + index + "] " + keys.get(i)); - } + /** + * This function is used to provide check/filter on possible + * type of command that is chosen by the user. This check is + * necessary due the the constantly changing behavior on the + * ranking of the command usages. + * + * @return command the command that is to be executed. + * @throws DukeException throw a dukeException with error message for debugging. + */ + public Command shortCutChecker(String commandName) throws DukeException { + if (commandName.equals("AddPatientCommand")) { + String patientName = ui.getPatientInfo("name"); + String nric = ui.getPatientInfo("nric"); + String room = ui.getPatientInfo("room"); + String remark = ui.getPatientInfo("remark"); + String[] patientInfo = new String[]{patientName, nric, room, remark}; + return new AddPatientCommand(patientInfo); + } else if (commandName.equals("AddStandardTaskCommand")) { + String taskName = ui.getTaskInfo("name"); + return new AddStandardTaskCommand(taskName); + } else if (commandName.equals("DeletePatientCommand")) { + String patientId = ui.getPatientInfo("id"); + return new DeletePatientCommand(patientId); + + } else if (commandName.equals("DeleteTaskCommand")) { + String taskId = ui.getTaskInfo("id"); + return new DeleteTaskCommand(taskId); + + } else if (commandName.equals("FindPatientCommand")) { + String patientId = ui.getPatientInfo("id"); + return new FindPatientCommand(patientId); + + } else if (commandName.equals("FindPatientTaskCommand")) { + String taskId = ui.getTaskInfo("id"); + return new FindPatientTaskCommand(taskId); + + } else if (commandName.equals("ListPatientsCommand")) { + return new ListPatientsCommand(); + + } else if (commandName.equals("ListTasksCommand")) { + return new ListTasksCommand(); + + } else if (commandName.equals("UpdatePatientCommand")) { + String patientId = ui.getPatientInfo("id"); + String infoType = ui.getPatientInfo("change"); + String changeValue = ui.getPatientInfo(("changeValue")); + String userInput = patientId + infoType + changeValue; + return new UpdatePatientCommand(userInput); + } else if (commandName.equals("UpdateTaskCommand")) { + String taskId = ui.getTaskInfo("id"); + String change = ui.getTaskInfo("change"); + String changeValue = ui.getTaskInfo("changeValue"); + String userInput = taskId + change + changeValue; + return new UpdateTaskCommand(userInput); + } else {//Assign patient task will be add... + throw new DukeException("No matching command!"); } - System.out.println("Please choose one of these commands"); - return topCommandTable; + } + public String commandNameConverter (String commandClassName) throws DukeException { + String convertedName; + if (commandClassName.equals("AddPatientCommand")) { + convertedName = "Add Patient"; + return convertedName; + + } else if (commandClassName.equals("AddStandardTaskCommand")) { + convertedName = "Add a Standard Task"; + return convertedName; + } else if (commandClassName.equals("DeletePatientCommand")) { + convertedName = "Delete a Patient"; + return convertedName; + + + } else if (commandClassName.equals("DeleteTaskCommand")) { + convertedName = "Delete a Task"; + return convertedName; + + + } else if (commandClassName.equals("FindPatientCommand")) { + convertedName = "Find a Patient"; + return convertedName; + + + } else if (commandClassName.equals("FindPatientTaskCommand")) { + convertedName = "Find a patient with task "; + return convertedName; + + } else if (commandClassName.equals("ListPatientsCommand")) { + convertedName = "Show all the patient"; + return convertedName; + + } else if (commandClassName.equals("ListTasksCommand")) { + convertedName = "Show all the tasks"; + return convertedName; + + + } else if (commandClassName.equals("UpdatePatientCommand")) { + convertedName = "Update Patient information"; + return convertedName; + + } else if (commandClassName.equals("UpdateTaskCommand")) { + convertedName = "Update Task information"; + return convertedName; + } else if (commandClassName.equals("AssignTaskToPatientCommand")) { + convertedName = "Assign a task to a patient"; + return convertedName; + } + else { + throw new DukeException("No matching command!"); + } + } } diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index 16fdc13f36..b166770f60 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -419,4 +419,85 @@ public void patientTaskFound(Patient patient, ArrayList patientTask showLine(); } } + + /** + * Provide the necessary task details from the user for short cut feature. + * + * @param info The type of task information that want to be retrieved. + * @return Either the task name or task id depend on the parameter info. + * @throws DukeException throw a dukeException with error message for debugging. + * @author QIAN JIE + * @version 1.3 + */ + + public String getTaskInfo(String info) throws DukeException { + + if (info.equals("name")) { + System.out.println("Task Name ?"); + String taskName = ui.readCommand(); + return taskName; + } else if (info.equals("id")) { + System.out.println("Task ID?"); + String taskId = "#" + ui.readCommand(); + return taskId; + } else if (info.equals("change")) { + System.out.println("What would you like to change??"); + String change = ui.readCommand(); + return change; + } else if (info.equals("changeValue")) { + System.out.println("Change to ?"); + String changeValue = ui.readCommand(); + return changeValue; + } + + else { + throw new DukeException("Please provide a proper parameter into getPatient function!"); + } + } + + /** + * Provide the necessary patient details from the user for short cut feature. + * + * @param info The type of task information that want to be retrieved. + * @return Either the task name or task id depend on the parameter info. + * @throws DukeException throw a dukeException with error message for debugging. + * @author QIAN JIE + * @version 1.3 + */ + + public String getPatientInfo(String info) throws DukeException { + if (info.equals("name")) { + System.out.println("Patient Name ?"); + String patientName = ui.readCommand(); + return patientName; + } else if (info.equals("id")) { + System.out.println("Patient ID Number ?"); + String patientId = "#" + ui.readCommand(); + return patientId; + } else if (info.equals("nric")) { + System.out.println("NRIC?"); + String nric = ui.readCommand(); + return nric; + } else if (info.equals("room")) { + System.out.println("Room??"); + String room = ui.readCommand(); + return room; + } else if (info.equals("remark")) { + System.out.println("Remarks?"); + String remark = ui.readCommand(); + return remark; + } else if (info.equals("change")) { + System.out.println("what would you like to change?"); + String change = ui.readCommand(); + return change; + } else if (info.equals("changeValue")) { + System.out.println("Change to ?"); + String changeValue = ui.readCommand(); + return changeValue; + } else { + throw new DukeException("Please provide a proper parameter into getPatient function!"); + } + } + + } diff --git a/src/main/java/duke/storage/CounterStorage.java b/src/main/java/duke/storage/CounterStorage.java index b19cb6eb64..a866908963 100644 --- a/src/main/java/duke/storage/CounterStorage.java +++ b/src/main/java/duke/storage/CounterStorage.java @@ -17,7 +17,7 @@ import java.util.Map; /** - * CounterStorage.java - a class for load/save of command frequency in csv format, + * A class for load/save of command frequency in csv format, * written with Storage template written by HUANG XUAN KUN * * @author QIAN JIE From 28ea849971311de9ca44167bad2d2973c7eb0c27 Mon Sep 17 00:00:00 2001 From: WEIFENG-NUSCEG Date: Mon, 21 Oct 2019 22:20:31 +0800 Subject: [PATCH 191/420] fixed some minor bugs --- src/main/java/duke/command/AssignTaskToPatientCommand.java | 1 - src/main/java/duke/core/Ui.java | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/duke/command/AssignTaskToPatientCommand.java b/src/main/java/duke/command/AssignTaskToPatientCommand.java index 1ff1d16567..9fd0b90621 100644 --- a/src/main/java/duke/command/AssignTaskToPatientCommand.java +++ b/src/main/java/duke/command/AssignTaskToPatientCommand.java @@ -84,7 +84,6 @@ public void execute(PatientTaskList patientTaskList, TaskManager tasksList, Pati } } catch (Exception e) { - e.printStackTrace(); throw new DukeException("You are missing some information!"); } diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index 1469f0dfde..ab896a4d65 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -276,7 +276,7 @@ public void taskDeleted() { * @param id the patients to be listed out */ public void patientTaskDeleted(int id) { - System.out.println("Got it. The task with unique ID: " + id + "has been deleted"); + System.out.println("Got it. The task with unique ID: " + id + " has been deleted"); } /** From 8dd739d00f57c16f6def9c96781c095f6aeca0f2 Mon Sep 17 00:00:00 2001 From: WEIFENG-NUSCEG Date: Mon, 21 Oct 2019 22:33:30 +0800 Subject: [PATCH 192/420] adjustment for checkstyle --- src/main/java/duke/command/DeletePatientTaskCommand.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/duke/command/DeletePatientTaskCommand.java b/src/main/java/duke/command/DeletePatientTaskCommand.java index 5da064e6e4..15cde9be3e 100644 --- a/src/main/java/duke/command/DeletePatientTaskCommand.java +++ b/src/main/java/duke/command/DeletePatientTaskCommand.java @@ -43,8 +43,8 @@ public DeletePatientTaskCommand(String deleteInfo) throws DukeException { this.deletedPatientInfo = deleteInfo; } } catch (Exception e) { - throw new DukeException("Try to follow the format: delete patienttask %/#" + - "/. "); + throw new DukeException("Try to follow the format: delete patienttask %/#" + + "/. "); } } From c79a527fb82c7914c8e8907e59ab1b19d222a986 Mon Sep 17 00:00:00 2001 From: WEIFENG-NUSCEG Date: Mon, 21 Oct 2019 22:59:10 +0800 Subject: [PATCH 193/420] update a function to delete all the patienttask with the same task id --- src/main/java/duke/relation/PatientTaskList.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/main/java/duke/relation/PatientTaskList.java b/src/main/java/duke/relation/PatientTaskList.java index e4d0a55bc7..7fd8f5d37c 100644 --- a/src/main/java/duke/relation/PatientTaskList.java +++ b/src/main/java/duke/relation/PatientTaskList.java @@ -76,6 +76,21 @@ public void deletePatientTaskByUniqueId(int uid) throws DukeException { } } + /** + * . + * + * @param id . + * @throws DukeException . + */ + public void deleteAllPatientTaskByTaskName(int id) throws DukeException { + for (PatientTask patientTask : patientTaskIdMap.values()) { + if (patientTask.getTaskID() == id) { + patientTaskIdMap.remove(patientTask.getPatientId(), patientTask); + return; + } + } + } + /** * . From 13ee860768fb34d5aaa35dad1487e986a3abe380 Mon Sep 17 00:00:00 2001 From: WEIFENG-NUSCEG Date: Tue, 22 Oct 2019 00:40:23 +0800 Subject: [PATCH 194/420] renamed the function from deleteAllPatientTaskByTaskName to deleteAllPatientTaskByTaskId --- src/main/java/duke/relation/PatientTaskList.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/duke/relation/PatientTaskList.java b/src/main/java/duke/relation/PatientTaskList.java index 7fd8f5d37c..555bc5f698 100644 --- a/src/main/java/duke/relation/PatientTaskList.java +++ b/src/main/java/duke/relation/PatientTaskList.java @@ -82,7 +82,7 @@ public void deletePatientTaskByUniqueId(int uid) throws DukeException { * @param id . * @throws DukeException . */ - public void deleteAllPatientTaskByTaskName(int id) throws DukeException { + public void deleteAllPatientTaskByTaskId(int id) throws DukeException { for (PatientTask patientTask : patientTaskIdMap.values()) { if (patientTask.getTaskID() == id) { patientTaskIdMap.remove(patientTask.getPatientId(), patientTask); From 5a91c86c2d419df544fd51d4ab211c1eb0b12bc8 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Tue, 22 Oct 2019 02:32:52 +0800 Subject: [PATCH 195/420] Created CSVStorage, Storage and StorageManager classes --- src/main/java/duke/storage/CSVStorage.java | 78 ++++++ src/main/java/duke/storage/Storage.java | 26 ++ .../java/duke/storage/StorageManager.java | 225 ++++++++++++++++++ 3 files changed, 329 insertions(+) create mode 100644 src/main/java/duke/storage/CSVStorage.java create mode 100644 src/main/java/duke/storage/Storage.java create mode 100644 src/main/java/duke/storage/StorageManager.java diff --git a/src/main/java/duke/storage/CSVStorage.java b/src/main/java/duke/storage/CSVStorage.java new file mode 100644 index 0000000000..cec31fcbf3 --- /dev/null +++ b/src/main/java/duke/storage/CSVStorage.java @@ -0,0 +1,78 @@ +package duke.storage; + +import duke.core.DukeException; +import org.apache.commons.csv.CSVFormat; +import org.apache.commons.csv.CSVPrinter; +import org.apache.commons.csv.CSVRecord; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.Reader; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Map; + +public class CSVStorage extends Storage { + + private String filePath; + + /** + * Constructs a Storage object with a specific file path. + * + * @param filePath A string that represents the path of the file to read or + * write. + */ + public CSVStorage(String filePath) { + this.filePath = filePath; + } + + @Override + public void write(ArrayList> infoList, String[] headers) throws DukeException { + try { + BufferedWriter writer = Files.newBufferedWriter(Paths.get(this.filePath)); + // Set up csv printer with headers given + CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT.withHeader(headers)); + for (ArrayList row : infoList) { + csvPrinter.printRecord(row); + } + csvPrinter.flush(); + } catch (IOException e) { + throw new DukeException(e.getMessage()); + } + } + + + /** + * Read data from the file and store into a ArrayList of task. + * + * @return A ArrayList of Map from the file. + * @throws DukeException If file is not found. + */ + public ArrayList> read() throws DukeException { + // Initialize capacity for 3000 rows of records. + ArrayList> infoList = new ArrayList<>(3000); + File csvFile = new File(filePath); + try { + if (csvFile.createNewFile()) { + System.out.println("File " + filePath + " is created."); + } else { + Reader in = new FileReader(filePath); + Iterable records = CSVFormat.EXCEL.withFirstRecordAsHeader().parse(in); + for (CSVRecord record : records) { + // There are maximum 9 columns per row + Map headerValueMap = record.toMap(); + infoList.add(headerValueMap); + } + } + return infoList; + } catch (Exception e) { + throw new DukeException("Loading of " + + filePath + + " is unsuccessful.\n" + + "e.getMessage()"); + } + } +} diff --git a/src/main/java/duke/storage/Storage.java b/src/main/java/duke/storage/Storage.java new file mode 100644 index 0000000000..fdff080b9c --- /dev/null +++ b/src/main/java/duke/storage/Storage.java @@ -0,0 +1,26 @@ +package duke.storage; + +import duke.core.DukeException; + +import java.util.ArrayList; +import java.util.Map; + +public abstract class Storage { + + /** + * Write info to local csv files. + * + * @param infoList A list of records to be to be written in rows to csv file + * @throws DukeException throw exception with error message when i/o fails + */ + public abstract void write(ArrayList> infoList, String[] headers) throws DukeException; + + + /** + * Load the patients' info from local csv files. + * + * @return A arrayList of Map to be saved + * @throws DukeException throw a dukeException with error message for debugging + */ + public abstract ArrayList> read() throws DukeException; +} diff --git a/src/main/java/duke/storage/StorageManager.java b/src/main/java/duke/storage/StorageManager.java new file mode 100644 index 0000000000..1f9404a7f1 --- /dev/null +++ b/src/main/java/duke/storage/StorageManager.java @@ -0,0 +1,225 @@ +package duke.storage; + +import duke.core.DukeException; +import duke.patient.Patient; +import duke.relation.EventPatientTask; +import duke.relation.PatientTask; +import duke.relation.StandardPatientTask; +import duke.task.Task; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +/** + * It is a centralized class to manage all the storages related to data w/r. + * It provides API for saving during command execution. + */ +public class StorageManager { + + private static final String COMMAND_COUNTER_FILENAME = "counter.csv"; + private static final String PATIENT_FILENAME = "patients.csv"; + private static final String ASSIGNED_TASK_FILENAME = "patientsTasks.csv"; + private static final String STANDARD_TASK_FILENAME = "standardTasks.csv"; + + private static final String[] COMMAND_COUNTER_HEADERS = {"Command Name", "Frequency"}; + private static final String[] ASSIGNED_TASK_HEADERS = {"PID", "TID", "DONE", "RECURRENCE", + "DEADLINE", "STARTTIME", "ENDTIME", "TASKTYPE", "uuid"}; + private static final String[] PATIENT_HEADERS = {"Id", "Name", "NRIC", "Room", "Remark"}; + private static final String[] STANDARD_TASK_HEADERS = {"Id", "Description"}; + + private CSVStorage commandCounterStorage; + private CSVStorage patientStorage; + private CSVStorage assignedTaskStorage; + private CSVStorage standardTaskStorage; + + /** + * Initialize all storages to perform save/load of all data. + * + * @param filePath relative path of where all local data store + */ + public StorageManager(String filePath) { + this.commandCounterStorage = new CSVStorage(filePath + COMMAND_COUNTER_FILENAME); + this.patientStorage = new CSVStorage(filePath + PATIENT_FILENAME); + this.assignedTaskStorage = new CSVStorage(filePath + ASSIGNED_TASK_FILENAME); + this.standardTaskStorage = new CSVStorage(filePath + STANDARD_TASK_FILENAME); + } + + /** + * Save patient data in the format of("Id", "Name", "NRIC", "Room", "Remark") to local csv files. + * + * @param patients a list containing patient's info + */ + public void savePatients(ArrayList patients) throws DukeException { + // Initialize capacity of 3000 rows of patient's information + ArrayList> infoList = new ArrayList<>(3000); + try { + for (Patient patient : patients) { + ArrayList row = new ArrayList(); + row.add(String.valueOf(patient.getID())); // Append value of column ID in a row + row.add(patient.getName()); // Append value of column Name in a row + row.add(patient.getNric()); // Append value of column Nric in a row + row.add(patient.getRoom()); // Append value of column Room in a row + row.add(patient.getRemark()); // Append value of column Remark in a row + infoList.add(row); + } + patientStorage.write(infoList, PATIENT_HEADERS); + } catch (Exception e) { + throw new DukeException(e.getMessage()); + } + } + + /** + * Save task data in the format of ("Id", "Description") to local csv files. + * + * @param tasks a list containing task's info + */ + public void saveStandardTasks(ArrayList tasks) throws DukeException { + // Initialize capacity of 30 rows of standard task's info + ArrayList> infoList = new ArrayList<>(3000); + try { + for (Task task : tasks) { + ArrayList row = new ArrayList(); + row.add(String.valueOf(task.getID())); // Append value of column ID in a row + row.add(task.getDescription()); // Append value of column description in a row + infoList.add(row); + } + standardTaskStorage.write(infoList, STANDARD_TASK_HEADERS); + } catch (Exception e) { + throw new DukeException(e.getMessage()); + } + } + + public void saveAssignedTasks(ArrayList assignedTasks) throws DukeException { + // Initialize capacity of 200 rows of patient-specified task's info + ArrayList> infoList = new ArrayList<>(200); + try { + for (PatientTask assignedTask : assignedTasks) { + String pid = String.valueOf(assignedTask.getPatientId()); + String tid = String.valueOf(assignedTask.getTaskID()); + String uniqueId = String.valueOf(assignedTask.getUid()); + String isDone = String.valueOf(assignedTask.isDone()); + String isRecurr = String.valueOf(assignedTask.isRecurrsive()); + String deadline = null; + String startTime = null; + String endTime = null; + String type = assignedTask.getTaskType(); + + if (assignedTask instanceof StandardPatientTask) { + deadline = ((StandardPatientTask) assignedTask).getDeadlineRaw(); + } else if (assignedTask instanceof EventPatientTask) { + startTime = ((EventPatientTask) assignedTask).getStartTimeRaw(); + endTime = ((EventPatientTask) assignedTask).getEndTimeRaw(); + } + ArrayList row = new ArrayList(Arrays.asList(pid, tid, isDone, isRecurr, + deadline, startTime, endTime, type, uniqueId)); + infoList.add(row); + } + assignedTaskStorage.write(infoList, STANDARD_TASK_HEADERS); + } catch (Exception e) { + throw new DukeException(e.getMessage()); + } + } + + /** + * Save command frequency to local csv files. + * + * @param counts A map containing commands as keys and frequent count as values + */ + public void saveCounters(Map counts) throws DukeException { + // Initialize capacity of 20 commands type. + ArrayList> infoList = new ArrayList<>(20); + try { + for (Map.Entry entry : counts.entrySet()) { + ArrayList row = new ArrayList(); + row.add(entry.getKey()); // Append value of column "Command Name" in a row + row.add(entry.getValue().toString()); // Append value of column 'Frequency' in a row + infoList.add(row); // Append row to the list of rows + } + commandCounterStorage.write(infoList, COMMAND_COUNTER_HEADERS); + } catch (Exception e) { + throw new DukeException(e.getMessage()); + } + } + + public ArrayList loadPatients() throws DukeException { + // Load a list of Map from local data file + ArrayList> patientsMap = patientStorage.read(); + ArrayList patientList = new ArrayList(); + try { + for (Map patientInfo : patientsMap) { + int id = Integer.parseInt(patientInfo.get(PATIENT_HEADERS[0])); + String name = patientInfo.get(PATIENT_HEADERS[1]); + String nric = patientInfo.get(PATIENT_HEADERS[2]); + String room = patientInfo.get(PATIENT_HEADERS[3]); + String remark = patientInfo.get(PATIENT_HEADERS[4]); + patientList.add(new Patient(id, name, nric, room, remark)); + } + } catch (Exception e) { + throw new DukeException(e.getMessage()); + } + return patientList; + } + + public ArrayList loadTasks() throws DukeException { + // Load a list of Map from local data file + ArrayList> tasksMap = standardTaskStorage.read(); + ArrayList taskList = new ArrayList(); + try { + for (Map taskInfo : tasksMap) { + int id = Integer.parseInt(taskInfo.get(STANDARD_TASK_HEADERS[0])); + String description = taskInfo.get(STANDARD_TASK_HEADERS[1]); + taskList.add(new Task(id, description)); + } + } catch (Exception e) { + throw new DukeException(e.getMessage()); + } + return taskList; + } + + + public ArrayList loadAssignedTasks() throws DukeException { + // Load a list of Map from local data file + ArrayList> assignedTaskMap = assignedTaskStorage.read(); + ArrayList assignedTaskList = new ArrayList(); + try { + for (Map assignedTaskInfo : assignedTaskMap) { + int pid = Integer.parseInt(assignedTaskInfo.get(ASSIGNED_TASK_HEADERS[0])); + int tid = Integer.parseInt(assignedTaskInfo.get(ASSIGNED_TASK_HEADERS[1])); + boolean isDone = Boolean.parseBoolean(assignedTaskInfo.get(ASSIGNED_TASK_HEADERS[2])); + boolean isRecursive = Boolean.parseBoolean(assignedTaskInfo.get(ASSIGNED_TASK_HEADERS[3])); + String deadline = assignedTaskInfo.get(ASSIGNED_TASK_HEADERS[4]); + String startTime = assignedTaskInfo.get(ASSIGNED_TASK_HEADERS[5]); + String endTime = assignedTaskInfo.get(ASSIGNED_TASK_HEADERS[6]); + String taskType = assignedTaskInfo.get(ASSIGNED_TASK_HEADERS[7]); + int uniqueId = Integer.parseInt(assignedTaskInfo.get(ASSIGNED_TASK_HEADERS[8])); + if (taskType.equals("S")) { + assignedTaskList.add(new StandardPatientTask(pid, tid, isDone, isRecursive, deadline, taskType)); + } else if (taskType.equals("E")) { + assignedTaskList.add(new EventPatientTask(pid, tid, isDone, isRecursive, + startTime, endTime, taskType)); + } + } + } catch (Exception e) { + throw new DukeException(e.getMessage()); + } + return assignedTaskList; + } + + public Map loadCommandFrequency() throws DukeException { + // Load a list of Map from local data file + ArrayList> counterMap = commandCounterStorage.read(); + Map integratedCounterMap = new HashMap<>(); + try { + for (Map rowInfo : counterMap) { + String commandName = rowInfo.get(COMMAND_COUNTER_HEADERS[0]); + int frequency = Integer.parseInt(rowInfo.get(COMMAND_COUNTER_HEADERS[1])); + integratedCounterMap.put(commandName, frequency); + } + } catch (Exception e) { + throw new DukeException(e.getMessage()); + } + return integratedCounterMap; + } +} From 9541b5ae994838e2b03d6fe63a328873597758e0 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Tue, 22 Oct 2019 03:06:51 +0800 Subject: [PATCH 196/420] Updated CsvStorage, Storage and StorageManager class --- src/main/java/duke/storage/{CSVStorage.java => CsvStorage.java} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/main/java/duke/storage/{CSVStorage.java => CsvStorage.java} (100%) diff --git a/src/main/java/duke/storage/CSVStorage.java b/src/main/java/duke/storage/CsvStorage.java similarity index 100% rename from src/main/java/duke/storage/CSVStorage.java rename to src/main/java/duke/storage/CsvStorage.java From 749e746ea5c1d0321eb6a646c173f21ee9f1ce00 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Tue, 22 Oct 2019 04:03:28 +0800 Subject: [PATCH 197/420] Re-factored storage structure --- src/main/java/duke/Duke.java | 33 ++--- .../java/duke/command/AddPatientCommand.java | 11 +- .../duke/command/AddStandardTaskCommand.java | 15 +-- .../command/AssignTaskToPatientCommand.java | 17 +-- src/main/java/duke/command/Command.java | 22 +--- .../duke/command/DeletePatientCommand.java | 26 ++-- .../command/DeletePatientTaskCommand.java | 20 +-- .../java/duke/command/DeleteTaskCommand.java | 17 +-- src/main/java/duke/command/ExitCommand.java | 11 +- .../java/duke/command/FindPatientCommand.java | 13 +- .../duke/command/FindPatientTaskCommand.java | 13 +- .../duke/command/ListPatientsCommand.java | 13 +- .../java/duke/command/ListTasksCommand.java | 13 +- .../duke/command/UpdatePatientCommand.java | 15 +-- .../java/duke/command/UpdateTaskCommand.java | 17 +-- src/main/java/duke/statistic/Counter.java | 6 +- src/main/java/duke/storage/CsvStorage.java | 16 ++- .../java/duke/storage/PatientStorage.java | 98 -------------- .../java/duke/storage/PatientTaskStorage.java | 122 ------------------ src/main/java/duke/storage/Storage.java | 3 +- .../java/duke/storage/StorageManager.java | 57 ++++++-- src/main/java/duke/storage/TaskStorage.java | 93 ------------- 22 files changed, 132 insertions(+), 519 deletions(-) delete mode 100644 src/main/java/duke/storage/PatientStorage.java delete mode 100644 src/main/java/duke/storage/PatientTaskStorage.java delete mode 100644 src/main/java/duke/storage/TaskStorage.java diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index 6c9afaf7b1..879c7756db 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -1,17 +1,14 @@ package duke; import duke.command.Command; -import duke.core.DukeException; import duke.core.CommandManager; +import duke.core.DukeException; +import duke.core.Ui; import duke.patient.PatientManager; -import duke.statistic.Counter; -import duke.storage.CounterStorage; -import duke.storage.PatientStorage; -import duke.storage.PatientTaskStorage; -import duke.storage.TaskStorage; import duke.relation.PatientTaskList; +import duke.statistic.Counter; +import duke.storage.StorageManager; import duke.task.TaskManager; -import duke.core.Ui; /** @@ -23,10 +20,7 @@ public class Duke { * A Storage object that handles reading tasks from a local * file and saving them to the same file. */ - private TaskStorage taskStorage; - private PatientStorage patientStorage; - private PatientTaskStorage patientTaskStorage; - private CounterStorage counterStorage; + private StorageManager storageManager; /** * A TaskList object that deals with add, delete, mark as done, * find functions of a list of tasks. @@ -49,16 +43,13 @@ public class Duke { * used for storing tasks. */ public Duke(String filePath) { - taskStorage = new TaskStorage(filePath + "/standardTasks.csv"); - patientStorage = new PatientStorage(filePath + "/patients.csv"); - patientTaskStorage = new PatientTaskStorage(filePath + "/patientsTasks.csv"); - counterStorage = new CounterStorage(filePath + "/counter.csv"); + storageManager = new StorageManager(filePath); try { - patientTaskList = new PatientTaskList(patientTaskStorage.load()); - taskManager = new TaskManager(taskStorage.load()); - patientManager = new PatientManager(patientStorage.load()); - counter = new Counter(counterStorage.load()); + patientTaskList = new PatientTaskList(storageManager.loadAssignedTasks()); + taskManager = new TaskManager(storageManager.loadTasks()); + patientManager = new PatientManager(storageManager.loadPatients()); + counter = new Counter(storageManager.loadCommandFrequency()); } catch (DukeException e) { ui.showLoadingError(); @@ -80,8 +71,8 @@ public void run() { ui.showLine(); Command c = CommandManager.manageCommand(fullCommand); c.execute(patientTaskList, taskManager, patientManager, - ui, patientTaskStorage, taskStorage, patientStorage); - counter.runCommandCounter(c, counterStorage, counter); + ui, storageManager); + counter.runCommandCounter(c, storageManager, counter); isExit = c.isExit(); } catch (DukeException e) { ui.showError(e.getMessage()); diff --git a/src/main/java/duke/command/AddPatientCommand.java b/src/main/java/duke/command/AddPatientCommand.java index b77eb70be0..a2e5e5f24a 100644 --- a/src/main/java/duke/command/AddPatientCommand.java +++ b/src/main/java/duke/command/AddPatientCommand.java @@ -4,12 +4,8 @@ import duke.core.Ui; import duke.patient.Patient; import duke.patient.PatientManager; -import duke.statistic.Counter; -import duke.storage.CounterStorage; -import duke.storage.PatientStorage; -import duke.storage.PatientTaskStorage; -import duke.storage.TaskStorage; import duke.relation.PatientTaskList; +import duke.storage.StorageManager; import duke.task.TaskManager; public class AddPatientCommand extends Command { @@ -34,11 +30,10 @@ public AddPatientCommand(String[] patientInfo) throws DukeException { @Override public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, Ui ui, - PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, - PatientStorage patientStorage) throws DukeException { + StorageManager storageManager) throws DukeException { patientList.addPatient(newPatient); - patientStorage.save(patientList.getPatientList()); + storageManager.savePatients(patientList.getPatientList()); ui.patientAdded(newPatient); } diff --git a/src/main/java/duke/command/AddStandardTaskCommand.java b/src/main/java/duke/command/AddStandardTaskCommand.java index 19f7b1a5f9..7badb27d35 100644 --- a/src/main/java/duke/command/AddStandardTaskCommand.java +++ b/src/main/java/duke/command/AddStandardTaskCommand.java @@ -3,12 +3,8 @@ import duke.core.DukeException; import duke.core.Ui; import duke.patient.PatientManager; -import duke.statistic.Counter; -import duke.storage.CounterStorage; -import duke.storage.PatientStorage; -import duke.storage.PatientTaskStorage; -import duke.storage.TaskStorage; import duke.relation.PatientTaskList; +import duke.storage.StorageManager; import duke.task.Task; import duke.task.TaskManager; @@ -33,18 +29,15 @@ public AddStandardTaskCommand(String taskDescription) { * @param taskList . * @param patientList . * @param ui . - * @param patientTaskStorage . - * @param taskStorage . - * @param patientStorage . + * @param storageManager . * @throws DukeException . */ @Override public void execute(PatientTaskList patientTask, TaskManager taskList, PatientManager patientList, - Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, - PatientStorage patientStorage) throws DukeException { + Ui ui, StorageManager storageManager) throws DukeException { taskList.addTask(newStandardTask); - taskStorage.save(taskList.getTaskList()); + storageManager.saveTasks(taskList.getTaskList()); ui.taskAdded(newStandardTask); } diff --git a/src/main/java/duke/command/AssignTaskToPatientCommand.java b/src/main/java/duke/command/AssignTaskToPatientCommand.java index 1ff1d16567..4e782f8b73 100644 --- a/src/main/java/duke/command/AssignTaskToPatientCommand.java +++ b/src/main/java/duke/command/AssignTaskToPatientCommand.java @@ -4,14 +4,10 @@ import duke.core.Ui; import duke.patient.PatientManager; import duke.relation.EventPatientTask; -import duke.relation.StandardPatientTask; -import duke.statistic.Counter; -import duke.storage.CounterStorage; -import duke.storage.PatientStorage; -import duke.storage.PatientTaskStorage; -import duke.storage.TaskStorage; import duke.relation.PatientTask; import duke.relation.PatientTaskList; +import duke.relation.StandardPatientTask; +import duke.storage.StorageManager; import duke.task.TaskManager; public class AssignTaskToPatientCommand extends Command { @@ -38,15 +34,12 @@ public AssignTaskToPatientCommand(String[] taskAssignmentInfo) throws DukeExcept * @param tasksList . * @param patientList . * @param ui . - * @param patientTaskStorage . - * @param taskStorage . - * @param patientStorage . + * @param storageManager . * @throws DukeException . */ @Override public void execute(PatientTaskList patientTaskList, TaskManager tasksList, PatientManager patientList, - Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, - PatientStorage patientStorage) throws DukeException { + Ui ui, StorageManager storageManager) throws DukeException { char firstChar = taskAssignmentInfo[1].charAt(0); @@ -93,7 +86,7 @@ public void execute(PatientTaskList patientTaskList, TaskManager tasksList, Pati throw new DukeException("Either the unique task id is repeated or the same task exists"); } else { patientTaskList.addPatientTask(newPatientTask); - patientTaskStorage.save(patientTaskList.fullPatientTaskList()); + storageManager.saveAssignedTasks(patientTaskList.fullPatientTaskList()); ui.patientTaskAssigned(newPatientTask, patientList.getPatient(newPatientTask.getPatientId()).getName(), tasksList.getTask(newPatientTask.getTaskID()).getDescription()); } diff --git a/src/main/java/duke/command/Command.java b/src/main/java/duke/command/Command.java index 5a32e83add..989515cdf6 100644 --- a/src/main/java/duke/command/Command.java +++ b/src/main/java/duke/command/Command.java @@ -4,11 +4,7 @@ import duke.core.Ui; import duke.patient.PatientManager; import duke.relation.PatientTaskList; -import duke.statistic.Counter; -import duke.storage.CounterStorage; -import duke.storage.PatientStorage; -import duke.storage.PatientTaskStorage; -import duke.storage.TaskStorage; +import duke.storage.StorageManager; import duke.task.TaskManager; /** @@ -23,19 +19,15 @@ public abstract class Command { /** * . * - * @param patientTask . - * @param tasks . - * @param patientList . - * @param ui . - * @param patientTaskStorage . - * @param taskStorage . - * @param patientStorage . + * @param patientTask . + * @param tasks . + * @param patientList . + * @param ui . + * @param storageManager . * @throws DukeException . */ public abstract void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, Ui ui, - PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, - PatientStorage patientStorage) throws DukeException; - + StorageManager storageManager) throws DukeException; /** diff --git a/src/main/java/duke/command/DeletePatientCommand.java b/src/main/java/duke/command/DeletePatientCommand.java index 9e1e2237fb..f265ef90fd 100644 --- a/src/main/java/duke/command/DeletePatientCommand.java +++ b/src/main/java/duke/command/DeletePatientCommand.java @@ -4,15 +4,10 @@ import duke.core.Ui; import duke.patient.Patient; import duke.patient.PatientManager; -import duke.statistic.Counter; -import duke.storage.CounterStorage; -import duke.storage.PatientStorage; -import duke.storage.PatientTaskStorage; -import duke.storage.TaskStorage; import duke.relation.PatientTaskList; +import duke.storage.StorageManager; import duke.task.TaskManager; - import java.util.ArrayList; public class DeletePatientCommand extends Command { @@ -41,19 +36,16 @@ public DeletePatientCommand(String deletedPatientInfo) throws DukeException { /** * . * - * @param patientTask . - * @param tasks . - * @param patientManager . - * @param ui . - * @param patientTaskStorage . - * @param taskStorage . - * @param patientStorage . + * @param patientTask . + * @param tasks . + * @param patientManager . + * @param ui . + * @param storageManager . * @throws DukeException . */ @Override public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientManager, - Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, - PatientStorage patientStorage) throws DukeException { + Ui ui, StorageManager storageManager) throws DukeException { if (id != 0) { Patient patientToBeDeleted = patientManager.getPatient(id); @@ -61,7 +53,7 @@ public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManag if (toDelete) { patientManager.deletePatient(id); ui.patientDeleted(); - patientStorage.save(patientManager.getPatientList()); + storageManager.savePatients(patientManager.getPatientList()); } } else { ArrayList patientsWithSameName = patientManager.getPatientByName(deletedPatientInfo); @@ -73,7 +65,7 @@ public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManag if (toDelete) { patientManager.deletePatient(patientsWithSameName.get(numberChosen - 1).getID()); ui.patientDeleted(); - patientStorage.save(patientManager.getPatientList()); + storageManager.savePatients(patientManager.getPatientList()); } } } diff --git a/src/main/java/duke/command/DeletePatientTaskCommand.java b/src/main/java/duke/command/DeletePatientTaskCommand.java index 1a13b1d8ba..3967a167ed 100644 --- a/src/main/java/duke/command/DeletePatientTaskCommand.java +++ b/src/main/java/duke/command/DeletePatientTaskCommand.java @@ -1,22 +1,14 @@ package duke.command; -import duke.core.DateTimeParser; import duke.core.DukeException; import duke.core.Ui; import duke.patient.Patient; import duke.patient.PatientManager; -import duke.relation.EventPatientTask; import duke.relation.PatientTask; -import duke.relation.StandardPatientTask; -import duke.storage.PatientStorage; -import duke.storage.PatientTaskStorage; -import duke.storage.TaskStorage; import duke.relation.PatientTaskList; -import duke.task.Task; +import duke.storage.StorageManager; import duke.task.TaskManager; - -import java.time.LocalDateTime; import java.util.ArrayList; public class DeletePatientTaskCommand extends Command { @@ -54,14 +46,12 @@ public DeletePatientTaskCommand(String[] deleteInfo) throws DukeException { * @param tasks . * @param patientManager . * @param ui . - * @param patientTaskStorage . - * @param taskStorage . - * @param patientStorage . + * @param storageManager . * @throws DukeException . */ @Override public void execute(PatientTaskList patientTaskList, TaskManager tasks, PatientManager patientManager, Ui ui, - PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) + StorageManager storageManager) throws DukeException { if (patientId != 0) { try { @@ -69,7 +59,7 @@ public void execute(PatientTaskList patientTaskList, TaskManager tasks, PatientM for (PatientTask patientTask: patientTaskList.getPatientTask(patientId)) { if (patientTask.getUid() == taskId) { patientTaskList.deletePatientTaskByUniqueId(taskId); - patientTaskStorage.save(patientTaskList.fullPatientTaskList()); + storageManager.saveAssignedTasks(patientTaskList.fullPatientTaskList()); ui.patientTaskDeleted(patientTask, toBeDeletedPatient); } } @@ -85,7 +75,7 @@ public void execute(PatientTaskList patientTaskList, TaskManager tasks, PatientM for (PatientTask patientTask: toBeDeleted) { if (patientTask.getUid() == taskId) { patientTaskList.deletePatientTaskByUniqueId(taskId); - patientTaskStorage.save(patientTaskList.fullPatientTaskList()); + storageManager.saveAssignedTasks(patientTaskList.fullPatientTaskList()); ui.patientTaskDeleted(patientTask, patientsWithSameName.get(0)); } } diff --git a/src/main/java/duke/command/DeleteTaskCommand.java b/src/main/java/duke/command/DeleteTaskCommand.java index 33954bd4c8..8234c678bc 100644 --- a/src/main/java/duke/command/DeleteTaskCommand.java +++ b/src/main/java/duke/command/DeleteTaskCommand.java @@ -3,12 +3,8 @@ import duke.core.DukeException; import duke.core.Ui; import duke.patient.PatientManager; -import duke.statistic.Counter; -import duke.storage.CounterStorage; -import duke.storage.PatientStorage; -import duke.storage.PatientTaskStorage; -import duke.storage.TaskStorage; import duke.relation.PatientTaskList; +import duke.storage.StorageManager; import duke.task.Task; import duke.task.TaskManager; @@ -44,22 +40,19 @@ public DeleteTaskCommand(String deletedTaskInfo) throws DukeException { * @param taskManager . * @param patientManager . * @param ui . - * @param patientTaskStorage . - * @param taskStorage . - * @param patientStorage . + * @param storageManager . * @throws DukeException . */ @Override public void execute(PatientTaskList patientTask, TaskManager taskManager, PatientManager patientManager, - Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, - PatientStorage patientStorage) throws DukeException { + Ui ui, StorageManager storageManager) throws DukeException { if (id != 0) { Task taskToBeDeleted = taskManager.getTask(id); boolean toDelete = ui.confirmTaskToBeDeleted(taskToBeDeleted); if (toDelete) { taskManager.deleteTask(id); ui.taskDeleted(); - taskStorage.save(taskManager.getTaskList()); + storageManager.saveTasks(taskManager.getTaskList()); } } else { ArrayList tasksWithSameDescription = taskManager.getTaskByDescription(deletedTaskInfo); @@ -71,7 +64,7 @@ public void execute(PatientTaskList patientTask, TaskManager taskManager, Patien if (toDelete) { taskManager.deleteTask(tasksWithSameDescription.get(numberChosen - 1).getID()); ui.taskDeleted(); - taskStorage.save(taskManager.getTaskList()); + storageManager.saveTasks(taskManager.getTaskList()); } } } diff --git a/src/main/java/duke/command/ExitCommand.java b/src/main/java/duke/command/ExitCommand.java index 76984f45a8..494accc749 100644 --- a/src/main/java/duke/command/ExitCommand.java +++ b/src/main/java/duke/command/ExitCommand.java @@ -1,15 +1,11 @@ package duke.command; import duke.core.DukeException; +import duke.core.Ui; import duke.patient.PatientManager; -import duke.statistic.Counter; -import duke.storage.CounterStorage; -import duke.storage.PatientStorage; -import duke.storage.PatientTaskStorage; import duke.relation.PatientTaskList; -import duke.storage.TaskStorage; +import duke.storage.StorageManager; import duke.task.TaskManager; -import duke.core.Ui; /** * Represents a command to exit Duke. The command.ExitCommand class @@ -43,8 +39,7 @@ public boolean isExit() { * @param patientList object that handles local text file update */ public void execute(PatientTaskList patientTask, TaskManager tasks, - PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, - TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + PatientManager patientList, Ui ui, StorageManager storageManager) throws DukeException { ui.exitInformation(); } } \ No newline at end of file diff --git a/src/main/java/duke/command/FindPatientCommand.java b/src/main/java/duke/command/FindPatientCommand.java index 19daa25d33..34692b5d16 100644 --- a/src/main/java/duke/command/FindPatientCommand.java +++ b/src/main/java/duke/command/FindPatientCommand.java @@ -4,12 +4,8 @@ import duke.core.Ui; import duke.patient.Patient; import duke.patient.PatientManager; -import duke.statistic.Counter; -import duke.storage.CounterStorage; -import duke.storage.PatientStorage; -import duke.storage.PatientTaskStorage; -import duke.storage.TaskStorage; import duke.relation.PatientTaskList; +import duke.storage.StorageManager; import duke.task.TaskManager; import java.util.ArrayList; @@ -29,15 +25,12 @@ public FindPatientCommand(String command) { * @param tasks . * @param patientManager . * @param ui . - * @param patientTaskStorage . - * @param taskStorage . - * @param patientStorage . + * @param storageManager . * @throws DukeException . */ @Override public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientManager, - Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, - PatientStorage patientStorage) throws DukeException { + Ui ui, StorageManager storageManager) throws DukeException { char firstChar = command.charAt(0); if (firstChar == '#') { int id; diff --git a/src/main/java/duke/command/FindPatientTaskCommand.java b/src/main/java/duke/command/FindPatientTaskCommand.java index dce52d2670..6a635261a8 100644 --- a/src/main/java/duke/command/FindPatientTaskCommand.java +++ b/src/main/java/duke/command/FindPatientTaskCommand.java @@ -6,11 +6,7 @@ import duke.patient.PatientManager; import duke.relation.PatientTask; import duke.relation.PatientTaskList; -import duke.statistic.Counter; -import duke.storage.CounterStorage; -import duke.storage.PatientStorage; -import duke.storage.PatientTaskStorage; -import duke.storage.TaskStorage; +import duke.storage.StorageManager; import duke.task.Task; import duke.task.TaskManager; @@ -37,15 +33,12 @@ public FindPatientTaskCommand(String cmd) { * @param tasksManager . * @param patientManager . * @param ui . - * @param patientTaskStorage . - * @param taskStorage . - * @param patientStorage . + * @param storageManager . * @throws DukeException . */ @Override public void execute(PatientTaskList patientTaskList, TaskManager tasksManager, PatientManager patientManager, - Ui ui, PatientTaskStorage patientTaskStorage, - TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + Ui ui, StorageManager storageManager) throws DukeException { char firstChar = command.charAt(0); if (firstChar == '#') { int id; diff --git a/src/main/java/duke/command/ListPatientsCommand.java b/src/main/java/duke/command/ListPatientsCommand.java index 509c4924b4..34974b3002 100644 --- a/src/main/java/duke/command/ListPatientsCommand.java +++ b/src/main/java/duke/command/ListPatientsCommand.java @@ -4,12 +4,8 @@ import duke.core.Ui; import duke.patient.Patient; import duke.patient.PatientManager; -import duke.statistic.Counter; -import duke.storage.CounterStorage; -import duke.storage.PatientStorage; -import duke.storage.PatientTaskStorage; -import duke.storage.TaskStorage; import duke.relation.PatientTaskList; +import duke.storage.StorageManager; import duke.task.TaskManager; import java.util.ArrayList; @@ -27,15 +23,12 @@ public ListPatientsCommand() { * @param tasks . * @param patientList . * @param ui . - * @param patientTaskStorage . - * @param taskStorage . - * @param patientStorage . + * @param storageManager . * @throws DukeException . */ @Override public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, - Ui ui, PatientTaskStorage patientTaskStorage, - TaskStorage taskStorage, PatientStorage patientStorage) { + Ui ui, StorageManager storageManager) { ArrayList list = patientList.getPatientList(); ui.listAllPatients(list); diff --git a/src/main/java/duke/command/ListTasksCommand.java b/src/main/java/duke/command/ListTasksCommand.java index 06c0298892..6003a3e833 100644 --- a/src/main/java/duke/command/ListTasksCommand.java +++ b/src/main/java/duke/command/ListTasksCommand.java @@ -3,12 +3,8 @@ import duke.core.DukeException; import duke.core.Ui; import duke.patient.PatientManager; -import duke.statistic.Counter; -import duke.storage.CounterStorage; -import duke.storage.PatientStorage; -import duke.storage.PatientTaskStorage; -import duke.storage.TaskStorage; import duke.relation.PatientTaskList; +import duke.storage.StorageManager; import duke.task.Task; import duke.task.TaskManager; @@ -23,15 +19,12 @@ public class ListTasksCommand extends Command { * @param tasks . * @param patientList . * @param ui . - * @param patientTaskStorage . - * @param taskStorage . - * @param patientStorage . + * @param storageManager . * @throws DukeException . */ @Override public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, - Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, - PatientStorage patientStorage) { + Ui ui, StorageManager storageManager) { ArrayList list = tasks.getTaskList(); ui.listAllTasks(list); } diff --git a/src/main/java/duke/command/UpdatePatientCommand.java b/src/main/java/duke/command/UpdatePatientCommand.java index d2e9e33ee4..51a07d224c 100644 --- a/src/main/java/duke/command/UpdatePatientCommand.java +++ b/src/main/java/duke/command/UpdatePatientCommand.java @@ -4,12 +4,8 @@ import duke.core.Ui; import duke.patient.Patient; import duke.patient.PatientManager; -import duke.statistic.Counter; -import duke.storage.CounterStorage; -import duke.storage.PatientStorage; -import duke.storage.PatientTaskStorage; -import duke.storage.TaskStorage; import duke.relation.PatientTaskList; +import duke.storage.StorageManager; import duke.task.TaskManager; public class UpdatePatientCommand extends Command { @@ -32,15 +28,12 @@ public UpdatePatientCommand(String command) { * @param tasks . * @param patientManager . * @param ui . - * @param patientTaskStorage . - * @param taskStorage . - * @param patientStorage . + * @param storageManager . * @throws DukeException . */ @Override public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientManager, - Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, - PatientStorage patientStorage) throws DukeException { + Ui ui, StorageManager storageManager) throws DukeException { String[] tempCommand = command.split(" ", 3); char firstChar = tempCommand[0].charAt(0); if (firstChar == '#') { @@ -58,7 +51,7 @@ public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManag throw new DukeException("You can only update 'Name', 'NRIC', or 'Room' of the patient"); } - patientStorage.save(patientManager.getPatientList()); + storageManager.savePatients(patientManager.getPatientList()); ui.showUpdatedSuccessfully(); ui.showPatientInfo(patientToBeUpdated); } catch (Exception e) { diff --git a/src/main/java/duke/command/UpdateTaskCommand.java b/src/main/java/duke/command/UpdateTaskCommand.java index 35e54a5d66..391ab6055c 100644 --- a/src/main/java/duke/command/UpdateTaskCommand.java +++ b/src/main/java/duke/command/UpdateTaskCommand.java @@ -2,14 +2,10 @@ import duke.core.DukeException; import duke.core.Ui; -import duke.statistic.Counter; -import duke.storage.CounterStorage; -import duke.task.Task; import duke.patient.PatientManager; -import duke.storage.PatientStorage; -import duke.storage.PatientTaskStorage; -import duke.storage.TaskStorage; import duke.relation.PatientTaskList; +import duke.storage.StorageManager; +import duke.task.Task; import duke.task.TaskManager; public class UpdateTaskCommand extends Command { @@ -31,15 +27,12 @@ public UpdateTaskCommand(String command) { * @param taskManager . * @param patientManager . * @param ui . - * @param patientTaskStorage . - * @param taskStorage . - * @param patientStorage . + * @param storageManager . * @throws DukeException . */ @Override public void execute(PatientTaskList patientTask, TaskManager taskManager, PatientManager patientManager, - Ui ui, PatientTaskStorage patientTaskStorage, - TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + Ui ui, StorageManager storageManager) throws DukeException { String[] tempCommand = command.split(" ", 3); char firstChar = tempCommand[0].charAt(0); if (firstChar == '#') { @@ -53,7 +46,7 @@ public void execute(PatientTaskList patientTask, TaskManager taskManager, Patien throw new DukeException("You can only update 'Description' of the task"); } - taskStorage.save(taskManager.getTaskList()); + storageManager.saveTasks(taskManager.getTaskList()); ui.showUpdatedSuccessfully(); ui.showTaskInfo(taskToBeUpdated); } catch (Exception e) { diff --git a/src/main/java/duke/statistic/Counter.java b/src/main/java/duke/statistic/Counter.java index 7a441d137b..5364c3db8d 100644 --- a/src/main/java/duke/statistic/Counter.java +++ b/src/main/java/duke/statistic/Counter.java @@ -2,7 +2,7 @@ import duke.command.Command; import duke.core.DukeException; -import duke.storage.CounterStorage; +import duke.storage.StorageManager; import java.util.Map; @@ -34,14 +34,14 @@ public Map getCommandTable() { * @version 1.3 */ - public void runCommandCounter(Command command, CounterStorage counterStorage, + public void runCommandCounter(Command command, StorageManager storageManager, Counter counter) throws DukeException { String commandName = command.getClass().getSimpleName(); int count = commandTable.containsKey(commandName) ? commandTable.get(commandName) : 0; commandTable.put(commandName, count + 1); - counterStorage.save(counter.getCommandTable()); + storageManager.saveCounters(counter.getCommandTable()); } diff --git a/src/main/java/duke/storage/CsvStorage.java b/src/main/java/duke/storage/CsvStorage.java index cec31fcbf3..eea7dbc10c 100644 --- a/src/main/java/duke/storage/CsvStorage.java +++ b/src/main/java/duke/storage/CsvStorage.java @@ -15,7 +15,7 @@ import java.util.ArrayList; import java.util.Map; -public class CSVStorage extends Storage { +public class CsvStorage extends Storage { private String filePath; @@ -25,11 +25,17 @@ public class CSVStorage extends Storage { * @param filePath A string that represents the path of the file to read or * write. */ - public CSVStorage(String filePath) { + public CsvStorage(String filePath) { this.filePath = filePath; } @Override + /** + * . + * @param infoList A list of records to be to be written in rows to csv file + * @param headers + * @throws DukeException + */ public void write(ArrayList> infoList, String[] headers) throws DukeException { try { BufferedWriter writer = Files.newBufferedWriter(Paths.get(this.filePath)); @@ -48,12 +54,12 @@ public void write(ArrayList> infoList, String[] headers) throw /** * Read data from the file and store into a ArrayList of task. * - * @return A ArrayList of Map from the file. + * @return A list of rows in Map with header as key and column in row as value * @throws DukeException If file is not found. */ public ArrayList> read() throws DukeException { // Initialize capacity for 3000 rows of records. - ArrayList> infoList = new ArrayList<>(3000); + ArrayList> infoList = new ArrayList<>(3000); File csvFile = new File(filePath); try { if (csvFile.createNewFile()) { @@ -63,7 +69,7 @@ public ArrayList> read() throws DukeException { Iterable records = CSVFormat.EXCEL.withFirstRecordAsHeader().parse(in); for (CSVRecord record : records) { // There are maximum 9 columns per row - Map headerValueMap = record.toMap(); + Map headerValueMap = record.toMap(); infoList.add(headerValueMap); } } diff --git a/src/main/java/duke/storage/PatientStorage.java b/src/main/java/duke/storage/PatientStorage.java deleted file mode 100644 index 468a23f706..0000000000 --- a/src/main/java/duke/storage/PatientStorage.java +++ /dev/null @@ -1,98 +0,0 @@ -package duke.storage; - -import duke.core.DukeException; -import duke.patient.Patient; -import org.apache.commons.csv.CSVFormat; -import org.apache.commons.csv.CSVPrinter; -import org.apache.commons.csv.CSVRecord; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.Reader; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.ArrayList; - -/** - * TaskStorage.java - a class for writing/reading patient info to/from local in csv format. - * - * @author HUANG XUAN KUN - * @version 1.2 - */ -public class PatientStorage { - - /** - * A string that represents a relative file path from the project folder. - */ - private String filePath; - - /** - * Constructs a Storage object with a specific file path. - * - * @param filePath A string that represents the path of the file to read or - * write. - */ - public PatientStorage(String filePath) { - this.filePath = filePath; - } - - /** - * Load the patients' info from local csv files. - * - * @return A arrayList of Patient which contain info of patients - * @throws DukeException throw a dukeException with error message for debugging - */ - public ArrayList load() throws DukeException { - ArrayList patientList = new ArrayList(); - File csvFile = new File(filePath); - try { - if (csvFile.createNewFile()) { - System.out.println("File " + filePath + " is created."); - } else { - Reader in = new FileReader(filePath); - Iterable records = CSVFormat.EXCEL.withFirstRecordAsHeader().parse(in); - for (CSVRecord record : records) { - int id = Integer.parseInt(record.get("Id")); - String name = record.get("Name"); - String nric = record.get("NRIC"); - String remark = record.get("Remark"); - String room = record.get("Room"); - patientList.add(new Patient(id, name, nric, room, remark)); - } - } - return patientList; - } catch (Exception e) { - throw new DukeException("Loading of " - + filePath - + "is unsuccessful.\n" - + "e.getMessage()"); - } - } - - /** - * Write the patients' info to local csv files. - * - * @param patients A list of patients containing info of patients to be written - * @throws DukeException throw exception with error message when i/o fails - */ - public void save(ArrayList patients) throws DukeException { - try { - BufferedWriter writer = Files.newBufferedWriter(Paths.get(filePath)); - CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT - .withHeader("Id", "Name", "NRIC", "Room", "Remark")); - for (Patient patient : patients) { - int id = patient.getID(); - String room = patient.getRoom(); - String nric = patient.getNric(); - String name = patient.getName(); - String remark = patient.getRemark(); - csvPrinter.printRecord(id, name, nric, room, remark); - } - csvPrinter.flush(); - } catch (IOException e) { - throw new DukeException(e.getMessage()); - } - } -} diff --git a/src/main/java/duke/storage/PatientTaskStorage.java b/src/main/java/duke/storage/PatientTaskStorage.java deleted file mode 100644 index 3214c1aca0..0000000000 --- a/src/main/java/duke/storage/PatientTaskStorage.java +++ /dev/null @@ -1,122 +0,0 @@ -package duke.storage; - -import duke.core.DukeException; -import duke.relation.EventPatientTask; -import duke.relation.PatientTask; -import duke.relation.StandardPatientTask; -import org.apache.commons.csv.CSVFormat; -import org.apache.commons.csv.CSVPrinter; -import org.apache.commons.csv.CSVRecord; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.Reader; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.ArrayList; - -/** - * TaskStorage.java - a class for writing/reading info of task associated with patient info to/from local in csv format. - * - * @author HUANG XUAN KUN - * @version 1.2 - */ -public class PatientTaskStorage { - - /** - * A string that represents a relative file path from the project folder. - */ - private String filePath; - - /** - * Constructs a Storage object with a specific file path. - * - * @param filePath A string that represents the path of the file to read or - * write. - */ - public PatientTaskStorage(String filePath) { - this.filePath = filePath; - } - - /** - * Load the task info with associated patient from local csv files. - * - * @return A arrayList of PatientTask which contain info of task with associated patient - * @throws DukeException throw a dukeException with error message for debugging - */ - public ArrayList load() throws DukeException { - ArrayList patientTaskList = new ArrayList(); - File csvFile = new File(filePath); - try { - if (csvFile.createNewFile()) { - System.out.println("File " + filePath + " is created."); - } else { - Reader in = new FileReader(filePath); - Iterable records = CSVFormat.EXCEL.withFirstRecordAsHeader().parse(in); - for (CSVRecord record : records) { - int pid = Integer.parseInt(record.get("PID")); - int tid = Integer.parseInt(record.get("TID")); - boolean isDone = Boolean.parseBoolean(record.get("DONE")); - boolean isRecursive = Boolean.parseBoolean(record.get("RECURRENCE")); - String deadline = record.get("DEADLINE"); - String startTime = record.get("STARTTIME"); - String endTime = record.get("ENDTIME"); - String taskType = record.get("TASKTYPE"); - int uniqueId = Integer.parseInt(record.get("uuid")); - if (taskType.equals("S")) { - patientTaskList.add(new StandardPatientTask(pid, tid, isDone, isRecursive, deadline, taskType)); - } else if (taskType.equals("E")) { - patientTaskList.add(new EventPatientTask(pid, tid, isDone, isRecursive, - startTime, endTime, taskType)); - } - } - } - return patientTaskList; - } catch (Exception e) { - throw new DukeException("Loading of " - + filePath - + "is unsuccessful." - + "e.getMessage()"); - } - } - - - /** - * Write info of task with associated patient to local csv files. - * - * @param patientTask A list of patients containing info of patients to be written - * @throws DukeException throw exception with error message when i/o fails - */ - public void save(ArrayList patientTask) throws DukeException { - try { - BufferedWriter writer = Files.newBufferedWriter(Paths.get(filePath)); - CSVPrinter csvPrinter = new CSVPrinter(writer, - CSVFormat.DEFAULT.withHeader("PID", "TID", "DONE", "RECURRENCE", - "DEADLINE", "STARTTIME", "ENDTIME", "TASKTYPE", "uuid")); - for (PatientTask patient : patientTask) { - int pid = patient.getPatientId(); - int tid = patient.getTaskID(); - int uniqueId = patient.getUid(); - boolean isDone = patient.isDone(); - boolean isRecurr = patient.isRecurrsive(); - String deadline = null; - String startTime = null; - String endTime = null; - String type = patient.getTaskType(); - if (patient instanceof StandardPatientTask) { - deadline = ((StandardPatientTask) patient).getDeadlineRaw(); - } else if (patient instanceof EventPatientTask) { - startTime = ((EventPatientTask) patient).getStartTimeRaw(); - endTime = ((EventPatientTask) patient).getEndTimeRaw(); - } - csvPrinter.printRecord(pid, tid, String.valueOf(isDone), String.valueOf(isRecurr), - deadline, startTime, endTime, type, uniqueId); - } - csvPrinter.flush(); - } catch (IOException e) { - throw new DukeException(e.getMessage()); - } - } -} diff --git a/src/main/java/duke/storage/Storage.java b/src/main/java/duke/storage/Storage.java index fdff080b9c..66665f8841 100644 --- a/src/main/java/duke/storage/Storage.java +++ b/src/main/java/duke/storage/Storage.java @@ -15,11 +15,10 @@ public abstract class Storage { */ public abstract void write(ArrayList> infoList, String[] headers) throws DukeException; - /** * Load the patients' info from local csv files. * - * @return A arrayList of Map to be saved + * @return A list of rows in Map with header as key and column in row as value * @throws DukeException throw a dukeException with error message for debugging */ public abstract ArrayList> read() throws DukeException; diff --git a/src/main/java/duke/storage/StorageManager.java b/src/main/java/duke/storage/StorageManager.java index 1f9404a7f1..3fdb4483ec 100644 --- a/src/main/java/duke/storage/StorageManager.java +++ b/src/main/java/duke/storage/StorageManager.java @@ -25,14 +25,14 @@ public class StorageManager { private static final String[] COMMAND_COUNTER_HEADERS = {"Command Name", "Frequency"}; private static final String[] ASSIGNED_TASK_HEADERS = {"PID", "TID", "DONE", "RECURRENCE", - "DEADLINE", "STARTTIME", "ENDTIME", "TASKTYPE", "uuid"}; + "DEADLINE", "STARTTIME", "ENDTIME", "TASKTYPE", "uuid"}; private static final String[] PATIENT_HEADERS = {"Id", "Name", "NRIC", "Room", "Remark"}; private static final String[] STANDARD_TASK_HEADERS = {"Id", "Description"}; - private CSVStorage commandCounterStorage; - private CSVStorage patientStorage; - private CSVStorage assignedTaskStorage; - private CSVStorage standardTaskStorage; + private CsvStorage commandCounterStorage; + private CsvStorage patientStorage; + private CsvStorage assignedTaskStorage; + private CsvStorage standardTaskStorage; /** * Initialize all storages to perform save/load of all data. @@ -40,10 +40,10 @@ public class StorageManager { * @param filePath relative path of where all local data store */ public StorageManager(String filePath) { - this.commandCounterStorage = new CSVStorage(filePath + COMMAND_COUNTER_FILENAME); - this.patientStorage = new CSVStorage(filePath + PATIENT_FILENAME); - this.assignedTaskStorage = new CSVStorage(filePath + ASSIGNED_TASK_FILENAME); - this.standardTaskStorage = new CSVStorage(filePath + STANDARD_TASK_FILENAME); + this.commandCounterStorage = new CsvStorage(filePath + "/" + COMMAND_COUNTER_FILENAME); + this.patientStorage = new CsvStorage(filePath + "/" + PATIENT_FILENAME); + this.assignedTaskStorage = new CsvStorage(filePath + "/" + ASSIGNED_TASK_FILENAME); + this.standardTaskStorage = new CsvStorage(filePath + "/" + STANDARD_TASK_FILENAME); } /** @@ -75,7 +75,7 @@ public void savePatients(ArrayList patients) throws DukeException { * * @param tasks a list containing task's info */ - public void saveStandardTasks(ArrayList tasks) throws DukeException { + public void saveTasks(ArrayList tasks) throws DukeException { // Initialize capacity of 30 rows of standard task's info ArrayList> infoList = new ArrayList<>(3000); try { @@ -91,6 +91,12 @@ public void saveStandardTasks(ArrayList tasks) throws DukeException { } } + /** + * . + * + * @param assignedTasks . + * @throws DukeException . + */ public void saveAssignedTasks(ArrayList assignedTasks) throws DukeException { // Initialize capacity of 200 rows of patient-specified task's info ArrayList> infoList = new ArrayList<>(200); @@ -113,10 +119,10 @@ public void saveAssignedTasks(ArrayList assignedTasks) throws DukeE endTime = ((EventPatientTask) assignedTask).getEndTimeRaw(); } ArrayList row = new ArrayList(Arrays.asList(pid, tid, isDone, isRecurr, - deadline, startTime, endTime, type, uniqueId)); + deadline, startTime, endTime, type, uniqueId)); infoList.add(row); } - assignedTaskStorage.write(infoList, STANDARD_TASK_HEADERS); + assignedTaskStorage.write(infoList, ASSIGNED_TASK_HEADERS); } catch (Exception e) { throw new DukeException(e.getMessage()); } @@ -143,6 +149,12 @@ public void saveCounters(Map counts) throws DukeException { } } + /** + * . + * + * @return . + * @throws DukeException . + */ public ArrayList loadPatients() throws DukeException { // Load a list of Map from local data file ArrayList> patientsMap = patientStorage.read(); @@ -162,6 +174,12 @@ public ArrayList loadPatients() throws DukeException { return patientList; } + /** + * . + * + * @return . + * @throws DukeException . + */ public ArrayList loadTasks() throws DukeException { // Load a list of Map from local data file ArrayList> tasksMap = standardTaskStorage.read(); @@ -178,7 +196,12 @@ public ArrayList loadTasks() throws DukeException { return taskList; } - + /** + * . + * + * @return . + * @throws DukeException . + */ public ArrayList loadAssignedTasks() throws DukeException { // Load a list of Map from local data file ArrayList> assignedTaskMap = assignedTaskStorage.read(); @@ -198,7 +221,7 @@ public ArrayList loadAssignedTasks() throws DukeException { assignedTaskList.add(new StandardPatientTask(pid, tid, isDone, isRecursive, deadline, taskType)); } else if (taskType.equals("E")) { assignedTaskList.add(new EventPatientTask(pid, tid, isDone, isRecursive, - startTime, endTime, taskType)); + startTime, endTime, taskType)); } } } catch (Exception e) { @@ -207,6 +230,12 @@ public ArrayList loadAssignedTasks() throws DukeException { return assignedTaskList; } + /** + * . + * + * @return . + * @throws DukeException . + */ public Map loadCommandFrequency() throws DukeException { // Load a list of Map from local data file ArrayList> counterMap = commandCounterStorage.read(); diff --git a/src/main/java/duke/storage/TaskStorage.java b/src/main/java/duke/storage/TaskStorage.java deleted file mode 100644 index 87439c17dc..0000000000 --- a/src/main/java/duke/storage/TaskStorage.java +++ /dev/null @@ -1,93 +0,0 @@ -package duke.storage; - -import duke.core.DukeException; -import duke.task.Task; -import org.apache.commons.csv.CSVFormat; -import org.apache.commons.csv.CSVPrinter; -import org.apache.commons.csv.CSVRecord; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.Reader; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.ArrayList; - -/** - * TaskStorage.java - a simple class for writing/reading taskInfo to/from local in csv format. - * - * @author HUANG XUAN KUN - * @version 1.2 - */ -public class TaskStorage { - - /** - * A string that represents a relative file path from the project folder. - */ - private String filePath; - - /** - * Constructs a Storage object with a specific file path. - * - * @param filePath A string that represents the path of the file to read or - * write. - */ - public TaskStorage(String filePath) { - this.filePath = filePath; - } - - - /** - * Read tasks from the file and store into a ArrayList of task. - * - * @return A ArrayList of tasks from the file. - * @throws DukeException If file is not found. - */ - public ArrayList load() throws DukeException { - ArrayList taskList = new ArrayList(); - File csvFile = new File(filePath); - try { - if (csvFile.createNewFile()) { - System.out.println("File " + filePath + " is created."); - } else { - Reader in = new FileReader(filePath); - Iterable records = CSVFormat.EXCEL.withFirstRecordAsHeader().parse(in); - for (CSVRecord record : records) { - int id = Integer.parseInt(record.get("Id")); - String description = record.get("Description"); - taskList.add(new Task(id, description)); - } - } - return taskList; - } catch (Exception e) { - throw new DukeException("Loading of " - + filePath - + "is unsuccessful.\n" - + "e.getMessage()"); - } - } - - /** - * Saves tasks to the local file. - * - * @param tasks The TaskList storing tasks. - * @throws DukeException throw with error message if writing to the local file failed. - */ - public void save(ArrayList tasks) throws DukeException { - try { - BufferedWriter writer = Files.newBufferedWriter(Paths.get(filePath)); - CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT - .withHeader("Id", "Description")); - for (Task task : tasks) { - int id = task.getID(); - String description = task.getDescription(); - csvPrinter.printRecord(id, description); - } - csvPrinter.flush(); - } catch (IOException e) { - throw new DukeException(e.getMessage()); - } - } -} From 675ee3c4112f54012818f4b46f9ac64349bec962 Mon Sep 17 00:00:00 2001 From: lmtaek Date: Tue, 22 Oct 2019 10:14:02 +0800 Subject: [PATCH 198/420] Altered CommandManager based on Kejun's feedback. Reduced redundant checks, and reorganized orders of certain conditions to prevent bugs. --- src/main/java/duke/core/CommandManager.java | 25 +++++++++------------ 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 8a52deb14d..11ee2cfcf3 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -51,11 +51,11 @@ public static Command manageCommand(String userInput) throws DukeException { switch (firstKeyword) { case "add": - if ((secondKeyword != "") && secondKeyword.equals("patient")) { + if (secondKeyword.equals("patient")) { String[] formattedInput = parser.parseAdd(); AddPatientCommand addPatientCommand = new AddPatientCommand(formattedInput); return addPatientCommand; - } else if ((secondKeyword != "") && secondKeyword.equals("task")) { + } else if (secondKeyword.equals("task")) { String formattedInput = parser.parseAdd()[0]; AddStandardTaskCommand addStandardTaskCommand = new AddStandardTaskCommand(formattedInput); return addStandardTaskCommand; @@ -75,29 +75,26 @@ public static Command manageCommand(String userInput) throws DukeException { throw new DukeException("Invalid 'list' command."); } case "delete": - if ((secondKeyword != "") - && (thirdKeyword != "") - && secondKeyword.equals("patient") - && thirdKeyword.equals("task")) { + if (secondKeyword.equals("patient") && thirdKeyword.equals("task")) { return new DeletePatientTaskCommand(parser.parseDeletePatientTask()); - } else if ((secondKeyword != "") && secondKeyword.equals("patient")) { + } else if (secondKeyword.equals("patient")) { String formattedInput = parser.parseDeletePatient(); return new DeletePatientCommand(formattedInput); - } else if ((secondKeyword != "") && secondKeyword.equals("task")) { + } else if (secondKeyword.equals("task")) { return new DeleteTaskCommand(parser.parseDeleteTask()); } else { throw new DukeException("Invalid 'delete' command."); } case "find": - if ((secondKeyword != "") && secondKeyword.equals("patient")) { - return new FindPatientCommand(parser.parseFind()); - } else if (secondKeyword.equals("patient") && ((thirdKeyword != "") && thirdKeyword.equals("task"))) { + if (secondKeyword.equals("patient") && thirdKeyword.equals("task")) { return new FindPatientTaskCommand(parser.parseFind()); - } else { - throw new DukeException("Invalid 'find' command. "); + } else if (secondKeyword.equals("patient")) { + return new FindPatientCommand(parser.parseFind()); + } else { + throw new DukeException("Invalid 'find' command."); } case "update": - if ((secondKeyword != "") && secondKeyword.equals("patient")) { + if (secondKeyword.equals("patient")) { String formattedInput = parser.parseUpdatePatient(); return new UpdatePatientCommand(formattedInput); } else if (secondKeyword.equals("task")) { From f121356d181ddbcff199cc23f733fc90ddd1b205 Mon Sep 17 00:00:00 2001 From: Qian Jie Date: Tue, 22 Oct 2019 10:28:47 +0800 Subject: [PATCH 199/420] Fixed checkstyle issues and added javadoc. --- src/main/java/duke/command/DukeCommand.java | 5 +- src/main/java/duke/core/CommandManager.java | 15 ++++- src/main/java/duke/core/ShortCutter.java | 64 +++++++++++++------ src/main/java/duke/core/Ui.java | 8 +-- src/main/java/duke/statistic/Counter.java | 1 + .../java/duke/storage/CounterStorage.java | 4 +- 6 files changed, 68 insertions(+), 29 deletions(-) diff --git a/src/main/java/duke/command/DukeCommand.java b/src/main/java/duke/command/DukeCommand.java index 4767e26790..a097bfb3dd 100644 --- a/src/main/java/duke/command/DukeCommand.java +++ b/src/main/java/duke/command/DukeCommand.java @@ -25,8 +25,9 @@ public class DukeCommand extends Command { * @throws DukeException . */ @Override - public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { - System.out.println("DUKE SHORTCUT"); + public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, Ui ui, + PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, + PatientStorage patientStorage) throws DukeException { } /** diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 4ec0336fab..c69f3e1df0 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -1,6 +1,19 @@ package duke.core; -import duke.command.*; +import duke.command.AddPatientCommand; +import duke.command.AddStandardTaskCommand; +import duke.command.AssignTaskToPatientCommand; +import duke.command.Command; +import duke.command.DeletePatientCommand; +import duke.command.DeleteTaskCommand; +import duke.command.DukeCommand; +import duke.command.ExitCommand; +import duke.command.FindPatientCommand; +import duke.command.FindPatientTaskCommand; +import duke.command.ListPatientsCommand; +import duke.command.ListTasksCommand; +import duke.command.UpdatePatientCommand; +import duke.command.UpdateTaskCommand; /** * Represents a Parser that parses user input into a specific diff --git a/src/main/java/duke/core/ShortCutter.java b/src/main/java/duke/core/ShortCutter.java index eadf5f7d95..fb688c1543 100644 --- a/src/main/java/duke/core/ShortCutter.java +++ b/src/main/java/duke/core/ShortCutter.java @@ -1,6 +1,15 @@ package duke.core; -import duke.command.*; +import duke.command.AddPatientCommand; +import duke.command.AddStandardTaskCommand; +import duke.command.Command; +import duke.command.DeletePatientCommand; +import duke.command.DeleteTaskCommand; +import duke.command.FindPatientCommand; +import duke.command.ListPatientsCommand; +import duke.command.ListTasksCommand; +import duke.command.UpdatePatientCommand; +import duke.command.UpdateTaskCommand; import duke.statistic.Counter; import java.util.ArrayList; @@ -9,8 +18,10 @@ import java.util.Map; import java.util.TreeMap; +//@@author qjie7 + /** - * This is a ShortCutter class to provide short cut implementation. + * This is a ShortCutter class to provide short cut implementation * DukeCommand will be used to activate the short cut mode. * This is not a simple UI implementation but also considered user's * daily work behavior to provide personalised short cut solution. @@ -23,8 +34,11 @@ public class ShortCutter { private Counter counter; private Ui ui; + public ShortCutter() { + } + /** - * A constructor for ShortCutter class + * A constructor for ShortCutter class. * * @param counter receive a counter object * @param ui receive a ui object @@ -44,16 +58,20 @@ public ShortCutter(Counter counter, Ui ui) { * @param map a command frequency table in Map structure with key * as the command type and value as the command frequency. * @return a Map structure that is sorted according to param's value - * which is the used command frequency. + * which is the used command frequency. */ public static > Map sortByValues(final Map map) { Comparator valueComparator = (k1, k2) -> { int compare = map.get(k2).compareTo(map.get(k1)); - if (compare == 0) + if (compare == 0) { + return 1; - else + } else { return compare; + } + + }; Map sortedByValues = new TreeMap(valueComparator); sortedByValues.putAll(map); @@ -67,10 +85,10 @@ public static > Map sortByValues(final Map MapSorter(Map sortedCommandTable) throws DukeException { + public Map mapSorter(Map sortedCommandTable) throws DukeException { Map topCommandTable = new HashMap<>(); ArrayList keys = new ArrayList<>(sortedCommandTable.keySet()); System.out.println("< Most Frequently Used Commands >"); @@ -94,7 +112,7 @@ public Map MapSorter(Map sortedCommandTable) t /** * This function is used to run the short cut UI logic by getting - * necessary information from user to provide the target output + * necessary information from user to provide the target output. * * @return command the command that is to be executed. * @throws DukeException throw a dukeException with error message for debugging. @@ -102,7 +120,7 @@ public Map MapSorter(Map sortedCommandTable) t */ public Command runShortCut() throws DukeException { sortedCommandTable = sortByValues(counter.getCommandTable()); - topUsedCommandTable = MapSorter(sortedCommandTable); + topUsedCommandTable = mapSorter(sortedCommandTable); String commandName; Command command; String choiceIndex = ui.readCommand(); @@ -165,9 +183,9 @@ public Command shortCutChecker(String commandName) throws DukeException { String patientId = ui.getPatientInfo("id"); return new FindPatientCommand(patientId); - } else if (commandName.equals("FindPatientTaskCommand")) { - String taskId = ui.getTaskInfo("id"); - return new FindPatientTaskCommand(taskId); + //} else if (commandName.equals("FindPatientTaskCommand")) { + //String taskId = ui.getTaskInfo("id"); + //return new FindPatientTaskCommand(taskId); } else if (commandName.equals("ListPatientsCommand")) { return new ListPatientsCommand(); @@ -187,13 +205,22 @@ public Command shortCutChecker(String commandName) throws DukeException { String changeValue = ui.getTaskInfo("changeValue"); String userInput = taskId + change + changeValue; return new UpdateTaskCommand(userInput); - } else {//Assign patient task will be add... + } else { + //Assign patient task will be add... throw new DukeException("No matching command!"); } - } - public String commandNameConverter (String commandClassName) throws DukeException { + + /** + * This function is used to convert the provided command class name + * into a string that is much user friendly and easy to read by the user. + * + * @param commandClassName the command class name chosen by the user + * @return a String that is easy to read by the user. + * @throws DukeException throw a dukeException with error message for debugging. + */ + public String commandNameConverter(String commandClassName) throws DukeException { String convertedName; if (commandClassName.equals("AddPatientCommand")) { convertedName = "Add Patient"; @@ -235,14 +262,13 @@ public String commandNameConverter (String commandClassName) throws DukeExceptio convertedName = "Update Patient information"; return convertedName; - } else if (commandClassName.equals("UpdateTaskCommand")) { + } else if (commandClassName.equals("UpdateTaskCommand")) { convertedName = "Update Task information"; return convertedName; } else if (commandClassName.equals("AssignTaskToPatientCommand")) { convertedName = "Assign a task to a patient"; return convertedName; - } - else { + } else { throw new DukeException("No matching command!"); } } diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index b166770f60..118033191e 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -419,7 +419,7 @@ public void patientTaskFound(Patient patient, ArrayList patientTask showLine(); } } - + //@@author qjie7 /** * Provide the necessary task details from the user for short cut feature. * @@ -448,9 +448,7 @@ public String getTaskInfo(String info) throws DukeException { System.out.println("Change to ?"); String changeValue = ui.readCommand(); return changeValue; - } - - else { + } else { throw new DukeException("Please provide a proper parameter into getPatient function!"); } } @@ -498,6 +496,6 @@ public String getPatientInfo(String info) throws DukeException { throw new DukeException("Please provide a proper parameter into getPatient function!"); } } - + //@@author } diff --git a/src/main/java/duke/statistic/Counter.java b/src/main/java/duke/statistic/Counter.java index 13912e695e..bf839bc1c0 100644 --- a/src/main/java/duke/statistic/Counter.java +++ b/src/main/java/duke/statistic/Counter.java @@ -8,6 +8,7 @@ import java.util.Map; +//@@author qjie7 /** * This is a Counter class that mainly used for counting purpose * which can then to be used for relevant application. diff --git a/src/main/java/duke/storage/CounterStorage.java b/src/main/java/duke/storage/CounterStorage.java index a866908963..9ecf71a49d 100644 --- a/src/main/java/duke/storage/CounterStorage.java +++ b/src/main/java/duke/storage/CounterStorage.java @@ -16,14 +16,14 @@ import java.util.HashMap; import java.util.Map; + /** * A class for load/save of command frequency in csv format, - * written with Storage template written by HUANG XUAN KUN + * written with Storage template written by HUANG XUAN KUN. * * @author QIAN JIE * @version 1.3 */ - public class CounterStorage { /** * A string that represents a relative file path from the project folder. From cbf9d6afaf50925e223110fe749cfa510f68048a Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Tue, 22 Oct 2019 14:30:38 +0800 Subject: [PATCH 200/420] Reset gradle.properties that induced ZIP Header Error --- gradle/wrapper/gradle-wrapper.properties | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a2514af0f6..4b7e1f3d38 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Fri Oct 18 20:15:31 SGT 2019 -distributionUrl=https\://services.gradle.org/distributions/gradle-5.5.1-all.zip distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.5.1-bin.zip zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists From ed28b461556da5f212c33036d96b6bc3ac6ab27f Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Tue, 22 Oct 2019 14:39:16 +0800 Subject: [PATCH 201/420] Remove non-related reports/data files and update .gitignore --- .gitignore | 9 +- build/reports/checkstyle/main.html | 680 ----------------------------- build/reports/checkstyle/main.xml | 135 ------ build/reports/checkstyle/test.html | 99 ----- build/reports/checkstyle/test.xml | 5 - data/data.txt | 1 - data/duke.txt | 16 - 7 files changed, 4 insertions(+), 941 deletions(-) delete mode 100644 build/reports/checkstyle/main.html delete mode 100644 build/reports/checkstyle/main.xml delete mode 100644 build/reports/checkstyle/test.html delete mode 100644 build/reports/checkstyle/test.xml delete mode 100644 data/data.txt delete mode 100644 data/duke.txt diff --git a/.gitignore b/.gitignore index 9adda9c8d9..93417de07a 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,9 @@ /out/ /*.iml +# Gradle build properties +build.gradle + # Gradle build files /.gradle/ /build @@ -11,17 +14,13 @@ .DS_Store *.iml bin/ -build/test-results/test/binary/results.bin -build/test-results/test/binary/output.bin.idx -build/test-results/test/binary/output.bin build/scriptsShadow/duke.bat build/scriptsShadow/duke build/scripts/duke.bat -build/scripts/duke +build/scripts/duke build/distributions/duke-0.1.0.tar build/distributions/duke-shadow-0.1.0.tar build/distributions/duke-0.1.0.zip build/libs/duke-0.1.0.jar build/distributions/duke-shadow-0.1.0.zip build/libs/mid-v1.1.jar -/data/testData/ diff --git a/build/reports/checkstyle/main.html b/build/reports/checkstyle/main.html deleted file mode 100644 index 94d37ec43e..0000000000 --- a/build/reports/checkstyle/main.html +++ /dev/null @@ -1,680 +0,0 @@ - - - - - - - - - - - - - - -
-

CheckStyle Audit

-
Designed for use with CheckStyle and Ant.
-
-

Summary

- - - - - -<<<<<<< HEAD - -======= - ->>>>>>> 0a9d2eff9654b047c3e0ee2447243b4f4a345928 - -
FilesErrors
320330
-
-

Files

- - - - - -<<<<<<< HEAD - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameErrors
/Users/weifeng/forkmain/src/main/java/duke/Duke.java0
/Users/weifeng/forkmain/src/main/java/duke/command/AddPatientCommand.java0
/Users/weifeng/forkmain/src/main/java/duke/command/AddStandardTaskCommand.java0
/Users/weifeng/forkmain/src/main/java/duke/command/AssignTaskToPatientCommand.java0
/Users/weifeng/forkmain/src/main/java/duke/command/Command.java0
/Users/weifeng/forkmain/src/main/java/duke/command/DeletePatientCommand.java0
/Users/weifeng/forkmain/src/main/java/duke/command/DeletePatientTaskCommand.java0
/Users/weifeng/forkmain/src/main/java/duke/command/DeleteTaskCommand.java0
/Users/weifeng/forkmain/src/main/java/duke/command/ExitCommand.java0
/Users/weifeng/forkmain/src/main/java/duke/command/FindPatientCommand.java0
/Users/weifeng/forkmain/src/main/java/duke/command/FindPatientTaskCommand.java0
/Users/weifeng/forkmain/src/main/java/duke/command/HelpCommand.java0
/Users/weifeng/forkmain/src/main/java/duke/command/ListPatientsCommand.java0
/Users/weifeng/forkmain/src/main/java/duke/command/ListTasksCommand.java0
/Users/weifeng/forkmain/src/main/java/duke/command/UpdatePatientCommand.java0
/Users/weifeng/forkmain/src/main/java/duke/command/UpdateTaskCommand.java0
/Users/weifeng/forkmain/src/main/java/duke/core/CommandManager.java0
/Users/weifeng/forkmain/src/main/java/duke/core/DateTimeParser.java0
/Users/weifeng/forkmain/src/main/java/duke/core/DukeException.java0
/Users/weifeng/forkmain/src/main/java/duke/core/Parser.java0
/Users/weifeng/forkmain/src/main/java/duke/core/Ui.java0
/Users/weifeng/forkmain/src/main/java/duke/patient/Patient.java0
/Users/weifeng/forkmain/src/main/java/duke/patient/PatientManager.java0
/Users/weifeng/forkmain/src/main/java/duke/relation/EventPatientTask.java0
/Users/weifeng/forkmain/src/main/java/duke/relation/PatientTask.java0
/Users/weifeng/forkmain/src/main/java/duke/relation/PatientTaskList.java0
/Users/weifeng/forkmain/src/main/java/duke/relation/StandardPatientTask.java0
/Users/weifeng/forkmain/src/main/java/duke/storage/PatientStorage.java0
/Users/weifeng/forkmain/src/main/java/duke/storage/PatientTaskStorage.java0
/Users/weifeng/forkmain/src/main/java/duke/storage/TaskStorage.java0
/Users/weifeng/forkmain/src/main/java/duke/task/Task.java0
/Users/weifeng/forkmain/src/main/java/duke/task/TaskManager.java0
-
- -

File /Users/weifeng/forkmain/src/main/java/duke/Duke.java

-======= - /Users/qianjie/Desktop/main/src/main/java/duke/Duke.java0 - - - /Users/qianjie/Desktop/main/src/main/java/duke/command/AddPatientCommand.java0 - - - /Users/qianjie/Desktop/main/src/main/java/duke/command/AddStandardTaskCommand.java0 - - - /Users/qianjie/Desktop/main/src/main/java/duke/command/AssignTaskToPatientCommand.java0 - - - /Users/qianjie/Desktop/main/src/main/java/duke/command/Command.java0 - - - /Users/qianjie/Desktop/main/src/main/java/duke/command/DeletePatientCommand.java0 - - - /Users/qianjie/Desktop/main/src/main/java/duke/command/DeleteTaskCommand.java0 - - - /Users/qianjie/Desktop/main/src/main/java/duke/command/ExitCommand.java0 - - - /Users/qianjie/Desktop/main/src/main/java/duke/command/FindPatientCommand.java0 - - - /Users/qianjie/Desktop/main/src/main/java/duke/command/FindPatientTaskCommand.java0 - - - /Users/qianjie/Desktop/main/src/main/java/duke/command/HelpCommand.java0 - - - /Users/qianjie/Desktop/main/src/main/java/duke/command/ListPatientsCommand.java0 - - - /Users/qianjie/Desktop/main/src/main/java/duke/command/ListTasksCommand.java0 - - - /Users/qianjie/Desktop/main/src/main/java/duke/command/UpdatePatientCommand.java0 - - - /Users/qianjie/Desktop/main/src/main/java/duke/command/UpdateTaskCommand.java0 - - - /Users/qianjie/Desktop/main/src/main/java/duke/core/CommandManager.java0 - - - /Users/qianjie/Desktop/main/src/main/java/duke/core/DateTimeParser.java0 - - - /Users/qianjie/Desktop/main/src/main/java/duke/core/DukeException.java0 - - - /Users/qianjie/Desktop/main/src/main/java/duke/core/Parser.java0 - - - /Users/qianjie/Desktop/main/src/main/java/duke/core/Ui.java0 - - - /Users/qianjie/Desktop/main/src/main/java/duke/patient/Patient.java0 - - - /Users/qianjie/Desktop/main/src/main/java/duke/patient/PatientManager.java0 - - - /Users/qianjie/Desktop/main/src/main/java/duke/relation/EventPatientTask.java0 - - - /Users/qianjie/Desktop/main/src/main/java/duke/relation/PatientTask.java0 - - - /Users/qianjie/Desktop/main/src/main/java/duke/relation/PatientTaskList.java0 - - - /Users/qianjie/Desktop/main/src/main/java/duke/relation/StandardPatientTask.java0 - - - /Users/qianjie/Desktop/main/src/main/java/duke/statistic/Counter.java0 - - - /Users/qianjie/Desktop/main/src/main/java/duke/storage/CounterStorage.java0 - - - /Users/qianjie/Desktop/main/src/main/java/duke/storage/PatientStorage.java0 - - - /Users/qianjie/Desktop/main/src/main/java/duke/storage/PatientTaskStorage.java0 - - - /Users/qianjie/Desktop/main/src/main/java/duke/storage/TaskStorage.java0 - - - /Users/qianjie/Desktop/main/src/main/java/duke/task/Task.java0 - - - /Users/qianjie/Desktop/main/src/main/java/duke/task/TaskManager.java0 - - -
- -

File /Users/qianjie/Desktop/main/src/main/java/duke/Duke.java

- - - - -
Error DescriptionLine
- Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/command/AddPatientCommand.java

->>>>>>> 0a9d2eff9654b047c3e0ee2447243b4f4a345928 - - - - -
Error DescriptionLine
-<<<<<<< HEAD - Back to top -

File /Users/weifeng/forkmain/src/main/java/duke/command/AddPatientCommand.java

-======= - Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/command/AddStandardTaskCommand.java

->>>>>>> 0a9d2eff9654b047c3e0ee2447243b4f4a345928 - - - - -
Error DescriptionLine
-<<<<<<< HEAD - Back to top -

File /Users/weifeng/forkmain/src/main/java/duke/command/AddStandardTaskCommand.java

-======= - Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/command/AssignTaskToPatientCommand.java

->>>>>>> 0a9d2eff9654b047c3e0ee2447243b4f4a345928 - - - - -
Error DescriptionLine
-<<<<<<< HEAD - Back to top -

File /Users/weifeng/forkmain/src/main/java/duke/command/AssignTaskToPatientCommand.java

-======= - Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/command/Command.java

->>>>>>> 0a9d2eff9654b047c3e0ee2447243b4f4a345928 - - - - -
Error DescriptionLine
-<<<<<<< HEAD - Back to top -

File /Users/weifeng/forkmain/src/main/java/duke/command/Command.java

-======= - Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/command/DeletePatientCommand.java

->>>>>>> 0a9d2eff9654b047c3e0ee2447243b4f4a345928 - - - - -
Error DescriptionLine
-<<<<<<< HEAD - Back to top -

File /Users/weifeng/forkmain/src/main/java/duke/command/DeletePatientCommand.java

-======= - Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/command/DeleteTaskCommand.java

->>>>>>> 0a9d2eff9654b047c3e0ee2447243b4f4a345928 - - - - -
Error DescriptionLine
-<<<<<<< HEAD - Back to top -

File /Users/weifeng/forkmain/src/main/java/duke/command/DeletePatientTaskCommand.java

-======= - Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/command/ExitCommand.java

->>>>>>> 0a9d2eff9654b047c3e0ee2447243b4f4a345928 - - - - -
Error DescriptionLine
-<<<<<<< HEAD - Back to top -

File /Users/weifeng/forkmain/src/main/java/duke/command/DeleteTaskCommand.java

-======= - Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/command/FindPatientCommand.java

->>>>>>> 0a9d2eff9654b047c3e0ee2447243b4f4a345928 - - - - -
Error DescriptionLine
-<<<<<<< HEAD - Back to top -

File /Users/weifeng/forkmain/src/main/java/duke/command/ExitCommand.java

-======= - Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/command/FindPatientTaskCommand.java

->>>>>>> 0a9d2eff9654b047c3e0ee2447243b4f4a345928 - - - - -
Error DescriptionLine
-<<<<<<< HEAD - Back to top -

File /Users/weifeng/forkmain/src/main/java/duke/command/FindPatientCommand.java

-======= - Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/command/HelpCommand.java

->>>>>>> 0a9d2eff9654b047c3e0ee2447243b4f4a345928 - - - - -
Error DescriptionLine
-<<<<<<< HEAD - Back to top -

File /Users/weifeng/forkmain/src/main/java/duke/command/FindPatientTaskCommand.java

-======= - Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/command/ListPatientsCommand.java

->>>>>>> 0a9d2eff9654b047c3e0ee2447243b4f4a345928 - - - - -
Error DescriptionLine
-<<<<<<< HEAD - Back to top -

File /Users/weifeng/forkmain/src/main/java/duke/command/HelpCommand.java

-======= - Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/command/ListTasksCommand.java

->>>>>>> 0a9d2eff9654b047c3e0ee2447243b4f4a345928 - - - - -
Error DescriptionLine
-<<<<<<< HEAD - Back to top -

File /Users/weifeng/forkmain/src/main/java/duke/command/ListPatientsCommand.java

-======= - Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/command/UpdatePatientCommand.java

->>>>>>> 0a9d2eff9654b047c3e0ee2447243b4f4a345928 - - - - -
Error DescriptionLine
-<<<<<<< HEAD - Back to top -

File /Users/weifeng/forkmain/src/main/java/duke/command/ListTasksCommand.java

-======= - Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/command/UpdateTaskCommand.java

->>>>>>> 0a9d2eff9654b047c3e0ee2447243b4f4a345928 - - - - -
Error DescriptionLine
-<<<<<<< HEAD - Back to top -

File /Users/weifeng/forkmain/src/main/java/duke/command/UpdatePatientCommand.java

-======= - Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/core/CommandManager.java

->>>>>>> 0a9d2eff9654b047c3e0ee2447243b4f4a345928 - - - - -
Error DescriptionLine
-<<<<<<< HEAD - Back to top -

File /Users/weifeng/forkmain/src/main/java/duke/command/UpdateTaskCommand.java

-======= - Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/core/DateTimeParser.java

->>>>>>> 0a9d2eff9654b047c3e0ee2447243b4f4a345928 - - - - -
Error DescriptionLine
-<<<<<<< HEAD - Back to top -

File /Users/weifeng/forkmain/src/main/java/duke/core/CommandManager.java

-======= - Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/core/DukeException.java

->>>>>>> 0a9d2eff9654b047c3e0ee2447243b4f4a345928 - - - - -
Error DescriptionLine
-<<<<<<< HEAD - Back to top -

File /Users/weifeng/forkmain/src/main/java/duke/core/DateTimeParser.java

-======= - Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/core/Parser.java

->>>>>>> 0a9d2eff9654b047c3e0ee2447243b4f4a345928 - - - - -
Error DescriptionLine
-<<<<<<< HEAD - Back to top -

File /Users/weifeng/forkmain/src/main/java/duke/core/DukeException.java

-======= - Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/core/Ui.java

->>>>>>> 0a9d2eff9654b047c3e0ee2447243b4f4a345928 - - - - -
Error DescriptionLine
-<<<<<<< HEAD - Back to top -

File /Users/weifeng/forkmain/src/main/java/duke/core/Parser.java

-======= - Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/patient/Patient.java

->>>>>>> 0a9d2eff9654b047c3e0ee2447243b4f4a345928 - - - - -
Error DescriptionLine
-<<<<<<< HEAD - Back to top -

File /Users/weifeng/forkmain/src/main/java/duke/core/Ui.java

-======= - Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/patient/PatientManager.java

->>>>>>> 0a9d2eff9654b047c3e0ee2447243b4f4a345928 - - - - -
Error DescriptionLine
-<<<<<<< HEAD - Back to top -

File /Users/weifeng/forkmain/src/main/java/duke/patient/Patient.java

-======= - Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/relation/EventPatientTask.java

->>>>>>> 0a9d2eff9654b047c3e0ee2447243b4f4a345928 - - - - -
Error DescriptionLine
-<<<<<<< HEAD - Back to top -

File /Users/weifeng/forkmain/src/main/java/duke/patient/PatientManager.java

-======= - Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/relation/PatientTask.java

->>>>>>> 0a9d2eff9654b047c3e0ee2447243b4f4a345928 - - - - -
Error DescriptionLine
-<<<<<<< HEAD - Back to top -

File /Users/weifeng/forkmain/src/main/java/duke/relation/EventPatientTask.java

-======= - Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/relation/PatientTaskList.java

->>>>>>> 0a9d2eff9654b047c3e0ee2447243b4f4a345928 - - - - -
Error DescriptionLine
-<<<<<<< HEAD - Back to top -

File /Users/weifeng/forkmain/src/main/java/duke/relation/PatientTask.java

-======= - Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/relation/StandardPatientTask.java

->>>>>>> 0a9d2eff9654b047c3e0ee2447243b4f4a345928 - - - - -
Error DescriptionLine
-<<<<<<< HEAD - Back to top -

File /Users/weifeng/forkmain/src/main/java/duke/relation/PatientTaskList.java

-======= - Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/statistic/Counter.java

->>>>>>> 0a9d2eff9654b047c3e0ee2447243b4f4a345928 - - - - -
Error DescriptionLine
-<<<<<<< HEAD - Back to top -

File /Users/weifeng/forkmain/src/main/java/duke/relation/StandardPatientTask.java

-======= - Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/storage/CounterStorage.java

->>>>>>> 0a9d2eff9654b047c3e0ee2447243b4f4a345928 - - - - -
Error DescriptionLine
-<<<<<<< HEAD - Back to top -

File /Users/weifeng/forkmain/src/main/java/duke/storage/PatientStorage.java

-======= - Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/storage/PatientStorage.java

->>>>>>> 0a9d2eff9654b047c3e0ee2447243b4f4a345928 - - - - -
Error DescriptionLine
-<<<<<<< HEAD - Back to top -

File /Users/weifeng/forkmain/src/main/java/duke/storage/PatientTaskStorage.java

-======= - Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/storage/PatientTaskStorage.java

->>>>>>> 0a9d2eff9654b047c3e0ee2447243b4f4a345928 - - - - -
Error DescriptionLine
-<<<<<<< HEAD - Back to top -

File /Users/weifeng/forkmain/src/main/java/duke/storage/TaskStorage.java

-======= - Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/storage/TaskStorage.java

->>>>>>> 0a9d2eff9654b047c3e0ee2447243b4f4a345928 - - - - -
Error DescriptionLine
-<<<<<<< HEAD - Back to top -

File /Users/weifeng/forkmain/src/main/java/duke/task/Task.java

-======= - Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/task/Task.java

->>>>>>> 0a9d2eff9654b047c3e0ee2447243b4f4a345928 - - - - -
Error DescriptionLine
-<<<<<<< HEAD - Back to top -

File /Users/weifeng/forkmain/src/main/java/duke/task/TaskManager.java

-======= - Back to top -

File /Users/qianjie/Desktop/main/src/main/java/duke/task/TaskManager.java

->>>>>>> 0a9d2eff9654b047c3e0ee2447243b4f4a345928 - - - - -
Error DescriptionLine
- Back to top -
- - diff --git a/build/reports/checkstyle/main.xml b/build/reports/checkstyle/main.xml deleted file mode 100644 index 974c97f9e2..0000000000 --- a/build/reports/checkstyle/main.xml +++ /dev/null @@ -1,135 +0,0 @@ - - -<<<<<<< HEAD - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -======= - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->>>>>>> 0a9d2eff9654b047c3e0ee2447243b4f4a345928 - - diff --git a/build/reports/checkstyle/test.html b/build/reports/checkstyle/test.html deleted file mode 100644 index f96fb23f60..0000000000 --- a/build/reports/checkstyle/test.html +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - - - - - -
-

CheckStyle Audit

-
Designed for use with CheckStyle and Ant.
-
-

Summary

- - - - - - - -
FilesErrors
10
-
-

Files

- - - - - - - -
NameErrors
/Users/weifeng/forkmain/src/test/java/duke/core/ParserTest.java0
-
- -

File /Users/weifeng/forkmain/src/test/java/duke/core/ParserTest.java

- - - - -
Error DescriptionLine
- Back to top -
- - diff --git a/build/reports/checkstyle/test.xml b/build/reports/checkstyle/test.xml deleted file mode 100644 index 2150bce770..0000000000 --- a/build/reports/checkstyle/test.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/data/data.txt b/data/data.txt deleted file mode 100644 index d3f5a12faa..0000000000 --- a/data/data.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/data/duke.txt b/data/duke.txt deleted file mode 100644 index 9a42562322..0000000000 --- a/data/duke.txt +++ /dev/null @@ -1,16 +0,0 @@ -E | 0 | fsahufias | 30/06/2020 0316 | ONCE -D | 0 | abc | 24/09/2019 0915 | DAILY -P | 0 | abc | 27/07/1996 2130 | 27/06/2029 1630 -D | 0 | abc | 24/09/2019 1145 | DAILY -T | 1 | abc | DAILY -D | 0 | abc | 17/09/2019 2130 | ONCE -E | 0 | werq | 17/09/2019 1500 | ONCE -T | 0 | homework | ONCE -E | 0 | abc | 24/09/2019 1530 | DAILY -P | 0 | abc | 27/08/2019 1630 | 29/11/2020 1630 -P | 0 | abc | 27/08/2019 1630 | 29/11/2020 1630 -P | 0 | abc | 27/08/2019 1630 | 29/11/2020 1630 -E | 0 | dog | 24/09/2019 0001 | MONTHLY -D | 0 | cat | 11/10/2019 0001 | DAILY -E | 0 | rabbit | 23/09/2019 0909 | WEEKLY -T | 0 | 1234 | ONCE From 499ff16f736e92917e6c418471bd352edd7be862 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Tue, 22 Oct 2019 14:51:46 +0800 Subject: [PATCH 202/420] Removed CounterStorage --- .../java/duke/storage/CounterStorage.java | 94 ------------------- 1 file changed, 94 deletions(-) delete mode 100644 src/main/java/duke/storage/CounterStorage.java diff --git a/src/main/java/duke/storage/CounterStorage.java b/src/main/java/duke/storage/CounterStorage.java deleted file mode 100644 index b19cb6eb64..0000000000 --- a/src/main/java/duke/storage/CounterStorage.java +++ /dev/null @@ -1,94 +0,0 @@ -package duke.storage; - -import duke.core.DukeException; - -import org.apache.commons.csv.CSVFormat; -import org.apache.commons.csv.CSVPrinter; -import org.apache.commons.csv.CSVRecord; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.Reader; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.HashMap; -import java.util.Map; - -/** - * CounterStorage.java - a class for load/save of command frequency in csv format, - * written with Storage template written by HUANG XUAN KUN - * - * @author QIAN JIE - * @version 1.3 - */ - -public class CounterStorage { - /** - * A string that represents a relative file path from the project folder. - */ - private String filePath; - - /** - * Constructs a Storage object with a specific file path. - * - * @param filePath A string that represents the path of the file to read or - * write. - */ - public CounterStorage(String filePath) { - this.filePath = filePath; - } - - /** - * Load the command counter table from local csv files. - * - * @return A Map with key being the command name and value being the counts. - * @throws DukeException throw a dukeException with error message for debugging. - */ - public Map load() throws DukeException { - Map cmdFreqTable = new HashMap<>(); - File csvFile = new File(filePath); - try { - if (csvFile.createNewFile()) { - System.out.println("File " + filePath + " is created."); - } else { - Reader in = new FileReader(filePath); - Iterable records = CSVFormat.EXCEL.withFirstRecordAsHeader().parse(in); - for (CSVRecord record : records) { - String commandName = record.get("Command Name"); - Integer frequency = Integer.parseInt(record.get("Frequency")); - cmdFreqTable.put(commandName, frequency); - } - } - return cmdFreqTable; - } catch (Exception e) { - throw new DukeException("Loading of " - + filePath - + "is unsuccessful." - + "e.getMessage()"); - } - } - - /** - * Write the key value set of command count table info to local csv files. - * - * @param cmdFreqTable A list of patients containing info of patients to be written - * @throws DukeException throw exception with error message when i/o fails - */ - public void save(Map cmdFreqTable) throws DukeException { - try { - BufferedWriter writer = Files.newBufferedWriter(Paths.get(filePath)); - CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT - .withHeader("Command Name", "Frequency")); - for (Map.Entry entry : cmdFreqTable.entrySet()) { - String commandName = entry.getKey(); - String frequency = entry.getValue().toString(); - csvPrinter.printRecord(commandName, frequency); - } - csvPrinter.flush(); - } catch (IOException e) { - throw new DukeException(e.getMessage()); - } - } -} From 1f8ee967e5b0af5f419b607e2cf0735c68811cca Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Tue, 22 Oct 2019 15:32:22 +0800 Subject: [PATCH 203/420] Update javaDocs of StorageManager --- .../java/duke/storage/StorageManager.java | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/main/java/duke/storage/StorageManager.java b/src/main/java/duke/storage/StorageManager.java index 3fdb4483ec..2b4705a186 100644 --- a/src/main/java/duke/storage/StorageManager.java +++ b/src/main/java/duke/storage/StorageManager.java @@ -25,7 +25,7 @@ public class StorageManager { private static final String[] COMMAND_COUNTER_HEADERS = {"Command Name", "Frequency"}; private static final String[] ASSIGNED_TASK_HEADERS = {"PID", "TID", "DONE", "RECURRENCE", - "DEADLINE", "STARTTIME", "ENDTIME", "TASKTYPE", "uuid"}; + "DEADLINE", "STARTTIME", "ENDTIME", "TASKTYPE", "uuid"}; private static final String[] PATIENT_HEADERS = {"Id", "Name", "NRIC", "Room", "Remark"}; private static final String[] STANDARD_TASK_HEADERS = {"Id", "Description"}; @@ -92,10 +92,10 @@ public void saveTasks(ArrayList tasks) throws DukeException { } /** - * . + * Save patientTask data in the format of ("Id", "Description") to local csv files. * - * @param assignedTasks . - * @throws DukeException . + * @param assignedTasks a list of patientTask + * @throws DukeException show saving error message */ public void saveAssignedTasks(ArrayList assignedTasks) throws DukeException { // Initialize capacity of 200 rows of patient-specified task's info @@ -119,7 +119,7 @@ public void saveAssignedTasks(ArrayList assignedTasks) throws DukeE endTime = ((EventPatientTask) assignedTask).getEndTimeRaw(); } ArrayList row = new ArrayList(Arrays.asList(pid, tid, isDone, isRecurr, - deadline, startTime, endTime, type, uniqueId)); + deadline, startTime, endTime, type, uniqueId)); infoList.add(row); } assignedTaskStorage.write(infoList, ASSIGNED_TASK_HEADERS); @@ -150,10 +150,10 @@ public void saveCounters(Map counts) throws DukeException { } /** - * . + * Load a list of patients. * - * @return . - * @throws DukeException . + * @return a list of patients containing patient's info + * @throws DukeException show loading warning message */ public ArrayList loadPatients() throws DukeException { // Load a list of Map from local data file @@ -175,10 +175,10 @@ public ArrayList loadPatients() throws DukeException { } /** - * . + * Load task info from local csv data files. * - * @return . - * @throws DukeException . + * @return a list of tasks + * @throws DukeException return load error exception */ public ArrayList loadTasks() throws DukeException { // Load a list of Map from local data file @@ -197,10 +197,10 @@ public ArrayList loadTasks() throws DukeException { } /** - * . + * Load patient assigned task. * - * @return . - * @throws DukeException . + * @return list of patient task relation + * @throws DukeException return load error exception */ public ArrayList loadAssignedTasks() throws DukeException { // Load a list of Map from local data file @@ -221,7 +221,7 @@ public ArrayList loadAssignedTasks() throws DukeException { assignedTaskList.add(new StandardPatientTask(pid, tid, isDone, isRecursive, deadline, taskType)); } else if (taskType.equals("E")) { assignedTaskList.add(new EventPatientTask(pid, tid, isDone, isRecursive, - startTime, endTime, taskType)); + startTime, endTime, taskType)); } } } catch (Exception e) { @@ -231,10 +231,10 @@ public ArrayList loadAssignedTasks() throws DukeException { } /** - * . + * To load command counter frequency. * - * @return . - * @throws DukeException . + * @return return the command with frequency counts + * @throws DukeException return load error exception */ public Map loadCommandFrequency() throws DukeException { // Load a list of Map from local data file From e02743c4df29b63312060e9f4de34863aedcdf99 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Tue, 22 Oct 2019 15:38:21 +0800 Subject: [PATCH 204/420] Resolve checkstyle issue --- src/main/java/duke/statistic/Counter.java | 1 - src/main/java/duke/storage/StorageManager.java | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/main/java/duke/statistic/Counter.java b/src/main/java/duke/statistic/Counter.java index 5364c3db8d..d01066c685 100644 --- a/src/main/java/duke/statistic/Counter.java +++ b/src/main/java/duke/statistic/Counter.java @@ -28,7 +28,6 @@ public Map getCommandTable() { * This function is used to run the command counter. * * @param command the command type that is being processed - * @param counterStorage get the counterStorage object * @param counter get the Counter object * @author QIAN JIE * @version 1.3 diff --git a/src/main/java/duke/storage/StorageManager.java b/src/main/java/duke/storage/StorageManager.java index 2b4705a186..4b6bed46cd 100644 --- a/src/main/java/duke/storage/StorageManager.java +++ b/src/main/java/duke/storage/StorageManager.java @@ -24,8 +24,8 @@ public class StorageManager { private static final String STANDARD_TASK_FILENAME = "standardTasks.csv"; private static final String[] COMMAND_COUNTER_HEADERS = {"Command Name", "Frequency"}; - private static final String[] ASSIGNED_TASK_HEADERS = {"PID", "TID", "DONE", "RECURRENCE", - "DEADLINE", "STARTTIME", "ENDTIME", "TASKTYPE", "uuid"}; + private static final String[] ASSIGNED_TASK_HEADERS = {"PID", "TID", "DONE", + "RECURRENCE", "DEADLINE", "STARTTIME", "ENDTIME", "TASKTYPE", "uuid"}; private static final String[] PATIENT_HEADERS = {"Id", "Name", "NRIC", "Room", "Remark"}; private static final String[] STANDARD_TASK_HEADERS = {"Id", "Description"}; @@ -119,7 +119,7 @@ public void saveAssignedTasks(ArrayList assignedTasks) throws DukeE endTime = ((EventPatientTask) assignedTask).getEndTimeRaw(); } ArrayList row = new ArrayList(Arrays.asList(pid, tid, isDone, isRecurr, - deadline, startTime, endTime, type, uniqueId)); + deadline, startTime, endTime, type, uniqueId)); infoList.add(row); } assignedTaskStorage.write(infoList, ASSIGNED_TASK_HEADERS); @@ -221,7 +221,7 @@ public ArrayList loadAssignedTasks() throws DukeException { assignedTaskList.add(new StandardPatientTask(pid, tid, isDone, isRecursive, deadline, taskType)); } else if (taskType.equals("E")) { assignedTaskList.add(new EventPatientTask(pid, tid, isDone, isRecursive, - startTime, endTime, taskType)); + startTime, endTime, taskType)); } } } catch (Exception e) { From 31848cd77df2275897a20918af174943f8ff11cd Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Tue, 22 Oct 2019 21:27:12 +0800 Subject: [PATCH 205/420] Add in assignedTask command keywords with test cases --- src/main/java/duke/core/TypoCorrector.java | 10 +++---- .../java/duke/core/TypoCorrectorTest.java | 28 +++++++++++-------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/main/java/duke/core/TypoCorrector.java b/src/main/java/duke/core/TypoCorrector.java index c0d909758c..5eb90ed95c 100644 --- a/src/main/java/duke/core/TypoCorrector.java +++ b/src/main/java/duke/core/TypoCorrector.java @@ -20,13 +20,13 @@ public class TypoCorrector { //Sets of "Dictionaries" for the command keyword, categorised by number of keywords contain in a supported commands. private static final ArrayList oneKeywordCommand = new ArrayList( - Arrays.asList("bye")); + Arrays.asList("bye", "duke", "help")); private static final ArrayList twoKeywordsCommands = new ArrayList( - Arrays.asList("list patients", "list tasks")); + Arrays.asList("list patients", "list tasks")); private static final ArrayList otherCommands = new ArrayList( - Arrays.asList("update patient", "update task", - "delete patient", "delete task", "add task", "add patient", - "assign by", "find patient", "find task")); + Arrays.asList("update patient", "update task", + "delete patient", "delete task", "delete patienttask", "add task", "add patient", + "find patient", "find task", "assign standardtask", "assign eventtask")); /** * This method take in an user input command with typo and return a possible matches diff --git a/src/test/java/duke/core/TypoCorrectorTest.java b/src/test/java/duke/core/TypoCorrectorTest.java index d5a8d1eb19..933cc7c9c6 100644 --- a/src/test/java/duke/core/TypoCorrectorTest.java +++ b/src/test/java/duke/core/TypoCorrectorTest.java @@ -1,11 +1,12 @@ package duke.core; -import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; import java.util.ArrayList; import java.util.Arrays; +import static org.junit.jupiter.api.Assertions.assertEquals; + /** * Junit test for TypoCorrector class. * @@ -17,17 +18,20 @@ public class TypoCorrectorTest { @Test void stringMatchTest() { ArrayList testCases = new ArrayList( - Arrays.asList(new String[]{"beyee", "bye"}, - new String[]{"bqe", "bye"}, - new String[]{"lsit patant", "list patients"}, - new String[]{"lsfvs takss", "list tasks"}, - new String[]{"deelte Ptients #12", "delete patient #12"}, - new String[]{"deleot tasksa task description", "delete task task description"}, - new String[]{"delette tasks #1", "delete task #1"}, - new String[]{"addd patents name nric room remark", "add patient name nric room remark"}, - new String[]{"dad tsak a very long task name", "add task a very long task name"}, - new String[]{"addd task abc", "add task abc"} - )); + Arrays.asList(new String[]{"beyee", "bye"}, + new String[]{"bqe", "bye"}, + new String[]{"lsit patant", "list patients"}, + new String[]{"lsfvs takss", "list tasks"}, + new String[]{"deelte Ptients #12", "delete patient #12"}, + new String[]{"deleot tasksa task description", "delete task task description"}, + new String[]{"delette tasks #1", "delete task #1"}, + new String[]{"addd patents name nric room remark", "add patient name nric room remark"}, + new String[]{"dad tsak a very long task name", "add task a very long task name"}, + new String[]{"addd task abc", "add task abc"}, + new String[]{"asgn standrdtask #1 12 12/12/2019 1645", "assign standardtask #1 12 12/12/2019 1645"}, + new String[]{"assgn eventask #1 12 12/12/2019 1645 to 12/12/2020 1645", + "assign eventtask #1 12 12/12/2019 1645 to 12/12/2020 1645"} + )); for (String[] testPair : testCases) { String correctedOutput = TypoCorrector.commandCorrection(testPair[0]); System.out.println("Input Command: " + testPair[0]); From 026ca9d51c386aaa5981ae8156a9bc3ff2e6bb16 Mon Sep 17 00:00:00 2001 From: lmtaek Date: Tue, 22 Oct 2019 22:28:09 +0800 Subject: [PATCH 206/420] Parser class alterations done to work with ':' parsing. --- src/main/java/duke/core/Parser.java | 210 ++++++++++++++++++---------- 1 file changed, 134 insertions(+), 76 deletions(-) diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index 5465388e80..6bc1b8e9ed 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -1,8 +1,10 @@ +//@@lmtaek package duke.core; public class Parser { String userInput; + String[] parsedInput; /** * Constructor for the Parser class. @@ -10,83 +12,109 @@ public class Parser { * @param userInput Takes in user's raw input and stores it to use in its methods, parsing it * into a format that is appropriate for the command it invokes. */ - public Parser(String userInput) { - this.userInput = userInput; + public Parser(String userInput) throws DukeException { + this.userInput = userInput.trim(); + try { + parsedInput = userInput.split(":"); + } catch (Exception e) { + throw new DukeException("Could not parse user input!"); + } } /** - * Parses user input so that it is compatible with Add commands. + * Parses user input so that it is compatible with `add patient` command. + *

+ * `add patient` output: patient_name, patient_NRIC, patient_room, patient_remark * - * @return A formatted string that will work for the available 'add' commands. + * @return A formatted string that will work for the available `add patient` command. * @throws DukeException If the method is unable to parse the userInput correctly, it will throw * a DukeException. */ - public String[] parseAdd() throws DukeException { - String[] parsedCommand = userInput.toLowerCase().split("\\s+", 3); + public String[] parseAddPatient() throws DukeException { + String[] formattedOutput = new String[4]; try { - if (parsedCommand[1].equals("patient")) { - String[] patientInfo = userInput.replaceAll( - "(?i)add patient ", "").trim().split("\\s+", 4); - return patientInfo; - } else if (parsedCommand[1].equals("task")) { - String[] taskInfo = new String[1]; - taskInfo[0] = userInput.replaceAll("(?i)add task ", "").trim(); - return taskInfo; + for (int i = 1; i <= formattedOutput.length; i++) { + formattedOutput[i - 1] = parsedInput[i].trim(); } + return formattedOutput; + } catch (Exception e) { + throw new DukeException("Please follow the " + + "`add patient : : : :` " + + "format."); + } + } + + /** + * Parses user input so that it is compatible with `add task` command. + *

+ * `add task` output: task_description + * + * @return A formatted string that will work for the available `add task` command. + * @throws DukeException If the method is unable to parse the userInput correctly, it will throw + * a DukeException. + */ + public String parseAddTask() throws DukeException { + String formattedOutput; + try { + formattedOutput = parsedInput[1].trim(); } catch (Exception e) { - throw new DukeException("Please change the format for your 'add' command."); + throw new DukeException("Please follow the `add task :`."); } - throw new DukeException("Invalid 'add' command."); + return formattedOutput; } /** - * Takes the user input and formats it so it is compatible with 'Assign' commands. + * Takes the user input and formats it so it is compatible with `assign standard task` commands. + *

+ * `assign standard task` output: patient_name or #patient_id, task_name or #task_id, dateTime * - * @return A string of formatted output to be used by 'Assign' commands. + * @return A string of formatted output to be used by `assign standard task` command. * @throws DukeException Thrown when the user input cannot be parsed in the desired manner. */ - public String[] parseAssign() throws DukeException { - String[] formattedInput = new String[5]; + public String[] parseAssignStandardTask() throws DukeException { + String[] formattedInput = new String[3]; try { - String[] tempInput = userInput.trim().replaceAll( - "(?i)assign ", "").split("\\s+", 4); - if (tempInput[0].equals("E")) { - String[] parsedTimes = tempInput[3].split(" to ", 2); - - for (int i = 0; i < 3; i++) { - formattedInput[i] = tempInput[i]; - } - formattedInput[3] = parsedTimes[0]; - formattedInput[4] = parsedTimes[1]; - } else { - for (int i = 0; i < tempInput.length; i++) { - formattedInput[i] = tempInput[i]; - } + for (int i = 1; i <= formattedInput.length; i++) { + formattedInput[i - 1] = parsedInput[i].trim(); } return formattedInput; } catch (Exception e) { - throw new DukeException("Invalid 'assign' command."); + throw new DukeException("Please follow the " + + "`assign standard task : or # :# or " + + ":

+

ParserTest

+
+
+ + + + + +
+
+ + + + + + + +
+
+
5
+

tests

+
+
+
+
0
+

failures

+
+
+
+
0
+

ignored

+
+
+
+
0.291s
+

duration

+
+
+
+
+
+
100%
+

successful

+
+
+
+
+ +
+

Tests

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TestDurationResult
parseAddPatientTest()0.090spassed
parseAddTask()0.008spassed
parseAssignPatientByID()0.107spassed
parseDeletePatient()0.005spassed
parseDeleteTask()0.081spassed
+
+
+

Standard output

+ +
02/02/2002 2222
+02/02/2002 2222
+
+
+
+
+ +
` format."); } } /** - * Takes the user input and formats it so it is compatible with the 'list' case in CommandManager. + * Takes the user input and formats it so it is compatible with `assign event task` command. + *

+ * `assign event task` output: patient_name or #patient_id, task_name or #task_id, start_time, end_time * - * @return A string of formatted output to be used by 'list' case in CommandManager. + * @return A string of formatted output to be used by `assign event task` command. * @throws DukeException Thrown when the user input cannot be parsed in the desired manner. */ - public String[] parseList() throws DukeException { + public String[] parseAssignEventTask() throws DukeException { + String[] formattedInput = new String[4]; try { - String[] formattedInput; - formattedInput = userInput.replaceAll("(?i)list ", "").trim().split("\\s+"); + String[] parsedTimes = parsedInput[4].split(" to "); + for (int i = 1; i < (formattedInput.length - 1); i++) { + formattedInput[i - 1] = parsedInput[i].trim(); + } + + formattedInput[3] = parsedTimes[0]; + formattedInput[4] = parsedTimes[1]; return formattedInput; } catch (Exception e) { - throw new DukeException("Invalid 'list' command."); + throw new DukeException("Please follow the " + + "`assign event task : or # :# or " + + ":

to
` format."); } } /** * Takes the user input and formats it so it is compatible with 'delete patient' command. + *

+ * `delete patient` output: patient_name or #patient_id * * @return A string of formatted output to be used by 'delete patient' commands. * @throws DukeException Thrown when the user input cannot be parsed in the desired manner. @@ -94,16 +122,17 @@ public String[] parseList() throws DukeException { public String parseDeletePatient() throws DukeException { try { String formattedInput; - String inputToParse = userInput.replaceAll("(?i)delete patient ", "").trim(); - formattedInput = inputToParse; + formattedInput = parsedInput[1].trim(); return formattedInput; } catch (Exception e) { - throw new DukeException("Invalid 'delete' command format."); + throw new DukeException("Please follow the `delete patient : or #` format"); } } /** * Takes the user input and formats it so it is compatible with 'delete task' command. + *

+ * `delete task` output: task_id or task_name * * @return A string of formatted output to be used by 'delete task' commands. * @throws DukeException Thrown when the user input cannot be parsed in the desired manner. @@ -111,79 +140,108 @@ public String parseDeletePatient() throws DukeException { public String parseDeleteTask() throws DukeException { try { String formattedInput; - String inputToParse = userInput.replaceAll("(?i)delete task ", "").trim(); - formattedInput = inputToParse; + formattedInput = parsedInput[1].trim(); return formattedInput; } catch (Exception e) { - throw new DukeException("Invalid 'delete task' command."); + throw new DukeException("Please follow the `delete task : or #` format"); } } /** * Takes user input and formats it so it is compatible with 'delete patient task' command. + *

+ * `delete patient task` output: patient_name or #patient_id, task_name or #task_id * * @return Array of strings to be used by 'delete patient task' command. * @throws DukeException when user input cannot be parsed properly. */ public String[] parseDeletePatientTask() throws DukeException { try { - String[] formattedInput; - String inputToParse = userInput.replaceAll("(?i)delete patient task ", "").trim(); - formattedInput = inputToParse.split("\\s+", 2); - + String[] formattedInput = new String[2]; + for (int i = 1; i <= formattedInput.length; i++) { + formattedInput[i - 1] = parsedInput[i].trim(); + } return formattedInput; - } catch (Exception e) { - throw new DukeException("Invalid 'delete patient task' command."); + throw new DukeException("Please follow the `delete patient task : or #" + + " : or #` format."); } } /** * Takes the user input and formats it so it is compatible with 'update patient' command. + *

+ * `update patient` output: patient_name or #patient_id, edited_field, updated_info * * @return A string of formatted output to be used by 'update patient' commands. * @throws DukeException Thrown when the user input cannot be parsed in the desired manner. */ - public String parseUpdatePatient() throws DukeException { - String formattedInput; - String inputToParse = userInput.replaceAll("(?i)update patient ", "").trim(); - formattedInput = inputToParse; - return formattedInput; + public String[] parseUpdatePatient() throws DukeException { + try { + String[] formattedInput = new String[3]; + + for (int i = 1; i <= formattedInput.length; i++) { + formattedInput[i - 1] = parsedInput[i].trim(); + } + return formattedInput; + } catch (Exception e) { + throw new DukeException("Please use the `update patient : or #" + + "/ :` format."); + } } /** - * Takes the user input and formats it so it is compatible with 'find' commands. + * Takes the user input and formats it so it is compatible with 'update task' command. + *

+ * `update task` output: task_name or #task_id, updated_description * - * @return A string of formatted output to be used by 'find' commands. + * @return A string of formatted output to be used by 'update task' commands. * @throws DukeException Thrown when the user input cannot be parsed in the desired manner. */ - public String parseFind() throws DukeException { + public String[] parseUpdateTask() throws DukeException { try { - String formattedInput; - String[] inputToParse = userInput.replaceAll("(?i)find patient ", "").trim().split("\\s+"); - - if (inputToParse[0].equalsIgnoreCase("task")) { - formattedInput = userInput.replaceAll("(?i)find patient task ", "").trim(); - } else { - formattedInput = userInput.replaceAll("(?i)find patient ", "").trim(); + String[] formattedInput = new String[2]; + for (int i = 1; i <= formattedInput.length; i++) { + formattedInput[i - 1] = parsedInput[i].trim(); } return formattedInput; } catch (Exception e) { - throw new DukeException("Invalid 'find patient' command."); + throw new DukeException("Please use the `update patient : or #" + + " :` format."); } } + /** + * Takes the user input and formats it so it is compatible with 'find patient' command. + *

+ * `find patient` output: patient_name or #patient_id + * + * @return A string of formatted output to be used by 'find patient' command. + * @throws DukeException Thrown when the user input cannot be parsed in the desired manner. + */ + public String parseFindPatient() throws DukeException { + try { + String formattedInput = parsedInput[1].trim(); + return formattedInput; + } catch (Exception e) { + throw new DukeException("Please use the `find patient : or #` format."); + } + } /** - * Takes the user input and formats it so it is compatible with 'update task' command. + * Takes the user input and formats it so it is compatible with 'find patient task' command. + *

+ * `find patient tasks` output: patient_name or #patient_id * - * @return A string of formatted output to be used by 'update task' commands. + * @return A string of formatted output to be used by 'find patient task' command. * @throws DukeException Thrown when the user input cannot be parsed in the desired manner. */ - public String parseUpdateTask() throws DukeException { - String formattedInput; - String inputToParse = userInput.replaceAll("(?i)update task ", "").trim(); - formattedInput = inputToParse; - return formattedInput; + public String parseFindPatientTasks() throws DukeException { + try { + String formattedInput = parsedInput[1].trim(); + return formattedInput; + } catch (Exception e) { + throw new DukeException("Please use the `find patient tasks : or #` format."); + } } } \ No newline at end of file From b0091f4fdd828bb768e9b5300994a26fd255453b Mon Sep 17 00:00:00 2001 From: lmtaek Date: Tue, 22 Oct 2019 22:29:05 +0800 Subject: [PATCH 207/420] CommandManager alterations to accommodate ':' parsing. --- src/main/java/duke/core/CommandManager.java | 103 +++++++------------- 1 file changed, 34 insertions(+), 69 deletions(-) diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 11ee2cfcf3..b53ac1ef6a 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -1,3 +1,4 @@ +//@@lmtaek package duke.core; import duke.command.AddPatientCommand; @@ -22,10 +23,10 @@ public class CommandManager { /** - * Parses a Task from a string array. + * Decides which command to execute based on keywords available in the user's input. * - * @param userInput The string array to be parsed. - * @return The Command received from user. + * @param userInput The user's input. + * @return The command dictated by the user. */ public static Command manageCommand(String userInput) throws DukeException { userInput = userInput.trim(); @@ -35,79 +36,43 @@ public static Command manageCommand(String userInput) throws DukeException { userInput = possibleCommand; } } - String[] command = userInput.toLowerCase().split("\\s+", 4); - String firstKeyword = command[0]; - String secondKeyword = ""; - String thirdKeyword = ""; - if (command.length >= 2) { - secondKeyword = command[1]; - } - if (command.length >= 3) { - thirdKeyword = command[2]; - - } + String[] command = userInput.toLowerCase().split(":"); + String keyWord = command[0].trim(); Parser parser = new Parser(userInput); - switch (firstKeyword) { - case "add": - if (secondKeyword.equals("patient")) { - String[] formattedInput = parser.parseAdd(); - AddPatientCommand addPatientCommand = new AddPatientCommand(formattedInput); - return addPatientCommand; - } else if (secondKeyword.equals("task")) { - String formattedInput = parser.parseAdd()[0]; - AddStandardTaskCommand addStandardTaskCommand = new AddStandardTaskCommand(formattedInput); - return addStandardTaskCommand; - } else { - throw new DukeException("Add command fails."); - } - case "assign": - return new AssignTaskToPatientCommand(parser.parseAssign()); - case "list": - String[] tempCommand = parser.parseList(); - String nextKeyword = tempCommand[0].toLowerCase(); - if (nextKeyword.equals("patients")) { - return new ListPatientsCommand(); - } else if (nextKeyword.equals("tasks")) { - return new ListTasksCommand(); - } else { - throw new DukeException("Invalid 'list' command."); - } - case "delete": - if (secondKeyword.equals("patient") && thirdKeyword.equals("task")) { - return new DeletePatientTaskCommand(parser.parseDeletePatientTask()); - } else if (secondKeyword.equals("patient")) { - String formattedInput = parser.parseDeletePatient(); - return new DeletePatientCommand(formattedInput); - } else if (secondKeyword.equals("task")) { - return new DeleteTaskCommand(parser.parseDeleteTask()); - } else { - throw new DukeException("Invalid 'delete' command."); - } - case "find": - if (secondKeyword.equals("patient") && thirdKeyword.equals("task")) { - return new FindPatientTaskCommand(parser.parseFind()); - } else if (secondKeyword.equals("patient")) { - return new FindPatientCommand(parser.parseFind()); - } else { - throw new DukeException("Invalid 'find' command."); - } - case "update": - if (secondKeyword.equals("patient")) { - String formattedInput = parser.parseUpdatePatient(); - return new UpdatePatientCommand(formattedInput); - } else if (secondKeyword.equals("task")) { - String formattedInput = parser.parseUpdateTask(); - return new UpdateTaskCommand(formattedInput); - } else { - throw new DukeException("Invalid 'update' command. "); - } + switch (keyWord) { + case "add patient": + return new AddPatientCommand(parser.parseAddPatient()); + case "add task": + return new AddStandardTaskCommand(parser.parseAddTask()); + case "assign standard task": + return new AssignTaskToPatientCommand(parser.parseAssignStandardTask()); + case "assign event task": + return new AssignTaskToPatientCommand(parser.parseAssignEventTask()); + case "list patients": + return new ListPatientsCommand(); + case "list tasks": + return new ListTasksCommand(); + case "delete patient task": + return new DeletePatientTaskCommand(parser.parseDeletePatientTask()); + case "delete patient": + return new DeletePatientCommand(parser.parseDeletePatient()); + case "delete task": + return new DeleteTaskCommand(parser.parseDeleteTask()); + case "find patient": + return new FindPatientCommand((parser.parseFindPatient())); + case "find patient tasks": + return new FindPatientTaskCommand((parser.parseFindPatientTasks())); + case "update patient": + return new UpdatePatientCommand(parser.parseUpdatePatient()); + case "update task": + return new UpdateTaskCommand(parser.parseUpdateTask()); case "bye": ExitCommand exitCommand = new ExitCommand(); return exitCommand; default: - throw new DukeException("Could not understand user input"); + throw new DukeException("Could not understand user input."); } } } From cee02b4084d13fe582179dfdba4ab3ac289d5a38 Mon Sep 17 00:00:00 2001 From: lmtaek Date: Tue, 22 Oct 2019 22:30:20 +0800 Subject: [PATCH 208/420] Alterations done to ParserTest class to accommodate new approach with ':' parsing. --- src/test/java/duke/core/ParserTest.java | 106 ++++++++++++++---------- 1 file changed, 64 insertions(+), 42 deletions(-) diff --git a/src/test/java/duke/core/ParserTest.java b/src/test/java/duke/core/ParserTest.java index 89ed388aa0..81f36915fa 100644 --- a/src/test/java/duke/core/ParserTest.java +++ b/src/test/java/duke/core/ParserTest.java @@ -1,72 +1,69 @@ +//@@lmtaek package duke.core; import org.junit.jupiter.api.Test; + import static org.junit.jupiter.api.Assertions.assertTrue; public class ParserTest { - String patientDummyInput = "add patient name NRIC room remark"; + String patientDummyInput = "add patient :name :NRIC :room :remark"; String taskDummyInput = "add task Walk the dog"; - String assignPatientIdToTaskS = "assign S 1 2 02/02/2002 2222"; - String assignPatientIdToTaskE = "assign E 2 1 02/02/2002 2222 to 03/02/2002 1234"; + String assignPatientToStandardTask = "assign standard task :patient name :#2 :02/02/2002 2222"; + String assignPatientToEventTask = "assign event task :#2 :#1 :01/02/2003 1234 to 06/05/2004 2312"; String deletePatientInputWithID = "delete patient #123"; String deletePatientInputWithName = "delete patient billy joe"; String deleteTaskInputWithID = "delete task #10"; String deleteTaskInputWithName = "delete task Take medicine"; + String deletePatientTaskInputWithID = "delete patient task #2 #5"; + String deletePatientTaskInputWithName = "delete patient task patient name task name"; @Test public void parseAddPatientTest() throws DukeException { Parser testParser = new Parser(patientDummyInput); - String[] testOutput = testParser.parseAdd(); - - assertTrue(testOutput[0].equals("name"), - "Name field did not parse correctly. Expected: 'name', but got: " + testOutput[0]); - assertTrue(testOutput[1].equals("NRIC"), - "NRIC field did not parse correctly. Expected: 'NRIC', but got: " + testOutput[1]); - assertTrue(testOutput[2].equals("room"), - "Room field did not parse correctly. Expected: 'room', but got: " + testOutput[2]); - assertTrue(testOutput[3].equals("remark"), - "Remark field did not parse correctly. Expected: 'remark', but got: " + testOutput[3]); - + String[] desiredOutput = {"name", "NRIC", "room", "remark"}; + String[] testOutput = testParser.parseAddPatient(); + + assertTrue(desiredOutput.length == testOutput.length); + for (int i = 0; i < desiredOutput.length; i++) { + assertTrue(desiredOutput[i].equals(testOutput[i]), "Parsing failed. Expected: " + + desiredOutput[i] + " but got: " + testOutput[i]); + } } @Test public void parseAddTask() throws DukeException { Parser testParser = new Parser(taskDummyInput); - String[] testOutput = testParser.parseAdd(); + String testOutput = testParser.parseAddTask(); - assertTrue(testOutput[0].equals("Walk the dog"), - "Task description did not parse correctly. Expected 'Walk the dog' but got: " + testOutput[0]); + assertTrue(testOutput.equals("Walk the dog"), + "Task description did not parse correctly. Expected 'Walk the dog' but got: " + testOutput); } @Test - public void parseAssignPatientByID() throws DukeException { - Parser testParserStandard = new Parser(assignPatientIdToTaskS); - Parser testParserEvent = new Parser(assignPatientIdToTaskE); - - final String[] testOutputStandard = testParserStandard.parseAssign(); - final String[] testOutputEvent = testParserEvent.parseAssign(); - - assertTrue(testOutputStandard[0].equals("S"), - "Task type parsed incorrectly. Expected 'S' but got: " + testOutputStandard[0]); - assertTrue(testOutputStandard[1].equals("1") && testOutputStandard[2].equals("2"), - "IDs parsed incorrectly.\n" - + "Expected patient ID of 1, and got: " + testOutputStandard[1] - + ".\n Expected task ID of 2 and got: " + testOutputStandard[2]); - assertTrue(testOutputStandard[3].equals("02/02/2002 2222")); - - assertTrue(testOutputEvent[0].equals("E"), - "Task type parsed incorrectly. Expected 'E' but got: " + testOutputEvent[0]); - assertTrue(testOutputEvent[1].equals("2") && testOutputEvent[2].equals("1"), - "IDs parsed incorrectly.\n" - + "Expected patient ID of 2, and got: " - + testOutputEvent[1] + ".\n Expected task ID of 1 and got: " + testOutputEvent[2]); - assertTrue(testOutputEvent[3].equals("02/02/2002 2222"), - "Start date parsed incorrectly. Expected '02/02/2002 2222' but got: " + testOutputEvent[3]); - assertTrue(testOutputEvent[4].equals("03/02/2002 1234"), - "End date parsed incorrectly. Expected '03/02/2002 1234' but got: " + testOutputEvent[4]); + public void parseAssignStandardAndEventTasks() throws DukeException { + Parser testParserStandard = new Parser(assignPatientToStandardTask); + Parser testParserEvent = new Parser(assignPatientToEventTask); + + final String[] testStandardOutput = testParserStandard.parseAssignStandardTask(); + final String[] testEventOutput = testParserEvent.parseAssignEventTask(); + + String[] desiredStandardOutput = {"patient name", "#2", "02/02/2002 2222"}; + String[] desiredEventOutput = {"#2", "#1", "01/02/2003 1234", "06/05/2004 2312"}; + + assertTrue(desiredStandardOutput.length == testStandardOutput.length); + for (int i = 0; i < desiredStandardOutput.length; i++) { + assertTrue(desiredStandardOutput[i].equals(testStandardOutput[i]), "Parsing failed. Expected: " + + desiredStandardOutput[i] + " but got: " + testStandardOutput[i]); + } + + assertTrue(desiredEventOutput.length == testEventOutput.length); + for (int i = 0; i < desiredEventOutput.length; i++) { + assertTrue(desiredEventOutput[i].equals(testEventOutput[i]), "Parsing failed. Expected: " + + desiredEventOutput[i] + " but got: " + testEventOutput[i]); + } } @Test @@ -97,4 +94,29 @@ public void parseDeleteTask() throws DukeException { "Delete task by name parsing failed. Expected 'Take medicine' but got: " + testOutputName); } + @Test + public void parseDeletePatientTask() throws DukeException { + Parser testParserID = new Parser(deletePatientTaskInputWithID); + Parser testParserName = new Parser(deletePatientTaskInputWithName); + + String[] testOutputID = testParserID.parseDeletePatientTask(); + String[] testOutputName = testParserName.parseDeletePatientTask(); + + String[] desiredOutputID = {"#2", "#5"}; + String[] desiredOutputName = {"patient name", "task name"}; + + assertTrue(desiredOutputID.length == testOutputID.length); + for (int i = 0; i < desiredOutputID.length; i++) { + assertTrue(desiredOutputID[i].equals(testOutputID[i]), "Parsing failed. Expected: " + + desiredOutputID[i] + " but got: " + testOutputID[i]); + } + + assertTrue(desiredOutputName.length == testOutputName.length); + for (int i = 0; i < desiredOutputName.length; i++) { + assertTrue(desiredOutputName[i].equals(testOutputName[i]), "Parsing failed. Expected: " + + desiredOutputName[i] + " but got: " + testOutputName[i]); + } + + } + } \ No newline at end of file From 997f20b5def3e53314155c7903471fac049931fd Mon Sep 17 00:00:00 2001 From: lmtaek Date: Tue, 22 Oct 2019 22:39:09 +0800 Subject: [PATCH 209/420] Fixing unintended implementations--to be handled by respective owners. --- .../java/duke/command/AssignTaskToPatientCommand.java | 8 ++++---- src/main/java/duke/command/DeletePatientTaskCommand.java | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/duke/command/AssignTaskToPatientCommand.java b/src/main/java/duke/command/AssignTaskToPatientCommand.java index fac5feddf7..bba8deec30 100644 --- a/src/main/java/duke/command/AssignTaskToPatientCommand.java +++ b/src/main/java/duke/command/AssignTaskToPatientCommand.java @@ -60,15 +60,15 @@ public void execute(PatientTaskList patientTaskList, TaskManager tasksList, Pati if (firstChar == '#') { int tempPid = Integer.parseInt(taskAssignmentInfo[1].replace("#","").trim()); int tempTid = Integer.parseInt(taskAssignmentInfo[2]); - String stime = taskAssignmentInfo[3]; - String etime = taskAssignmentInfo[4]; + String stime = taskAssignmentInfo[3].split(" to ", 2)[0]; String stime = taskAssignmentInfo[3]; + String etime = taskAssignmentInfo[3].split(" to ", 2)[1]; newPatientTask = new EventPatientTask(tempPid, tempTid, stime, etime, taskAssignmentInfo[0]); } else { int tempPid = patientList.getPatientByName(taskAssignmentInfo[1]).get(0).getID(); int tempTid = tasksList.getTaskByDescription(taskAssignmentInfo[2]).get(0).getID(); - String stime = taskAssignmentInfo[3]; - String etime = taskAssignmentInfo[4]; + String stime = taskAssignmentInfo[3].split(" to ", 2)[0]; String stime = taskAssignmentInfo[3]; + String etime = taskAssignmentInfo[3].split(" to ", 2)[1]; newPatientTask = new EventPatientTask(tempPid, tempTid, stime, etime, taskAssignmentInfo[0]); } diff --git a/src/main/java/duke/command/DeletePatientTaskCommand.java b/src/main/java/duke/command/DeletePatientTaskCommand.java index 1fffb5f7d9..9f2657de02 100644 --- a/src/main/java/duke/command/DeletePatientTaskCommand.java +++ b/src/main/java/duke/command/DeletePatientTaskCommand.java @@ -27,14 +27,14 @@ public DeletePatientTaskCommand(String[] deleteInfo) throws DukeException { char firstChar = deleteInfo[0].charAt(0); try { if (firstChar == '#') { - this.patientId = Integer.parseInt(deleteInfo[0].substring(1).trim()); + Integer.parseInt(deleteInfo[0].replace("#","").trim()); this.taskId = Integer.parseInt(deleteInfo[1]); } else { this.deletedPatientInfo = deleteInfo[0]; this.taskId = Integer.parseInt(deleteInfo[1]); } } catch (Exception e) { - throw new DukeException("Try to follow the format: delete patient task #patientid taskuniqueid"); + throw new DukeException("Try to follow the format: delete patienttask #patientid taskuniqeid"); } } From 8f75b4d359c92e956c0a3b3e77591f0ec5e76453 Mon Sep 17 00:00:00 2001 From: lmtaek Date: Tue, 22 Oct 2019 22:44:02 +0800 Subject: [PATCH 210/420] Removing 'side effect' alterations from branch. --- src/main/java/duke/command/AssignTaskToPatientCommand.java | 4 ++-- src/main/java/duke/command/DeletePatientTaskCommand.java | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/duke/command/AssignTaskToPatientCommand.java b/src/main/java/duke/command/AssignTaskToPatientCommand.java index bba8deec30..4e782f8b73 100644 --- a/src/main/java/duke/command/AssignTaskToPatientCommand.java +++ b/src/main/java/duke/command/AssignTaskToPatientCommand.java @@ -60,14 +60,14 @@ public void execute(PatientTaskList patientTaskList, TaskManager tasksList, Pati if (firstChar == '#') { int tempPid = Integer.parseInt(taskAssignmentInfo[1].replace("#","").trim()); int tempTid = Integer.parseInt(taskAssignmentInfo[2]); - String stime = taskAssignmentInfo[3].split(" to ", 2)[0]; String stime = taskAssignmentInfo[3]; + String stime = taskAssignmentInfo[3].split(" to ", 2)[0]; String etime = taskAssignmentInfo[3].split(" to ", 2)[1]; newPatientTask = new EventPatientTask(tempPid, tempTid, stime, etime, taskAssignmentInfo[0]); } else { int tempPid = patientList.getPatientByName(taskAssignmentInfo[1]).get(0).getID(); int tempTid = tasksList.getTaskByDescription(taskAssignmentInfo[2]).get(0).getID(); - String stime = taskAssignmentInfo[3].split(" to ", 2)[0]; String stime = taskAssignmentInfo[3]; + String stime = taskAssignmentInfo[3].split(" to ", 2)[0]; String etime = taskAssignmentInfo[3].split(" to ", 2)[1]; newPatientTask = new EventPatientTask(tempPid, tempTid, stime, etime, taskAssignmentInfo[0]); diff --git a/src/main/java/duke/command/DeletePatientTaskCommand.java b/src/main/java/duke/command/DeletePatientTaskCommand.java index 9f2657de02..3967a167ed 100644 --- a/src/main/java/duke/command/DeletePatientTaskCommand.java +++ b/src/main/java/duke/command/DeletePatientTaskCommand.java @@ -15,6 +15,7 @@ public class DeletePatientTaskCommand extends Command { private int patientId; private int taskId; private String deletedPatientInfo; + private String[] command; /** @@ -27,7 +28,7 @@ public DeletePatientTaskCommand(String[] deleteInfo) throws DukeException { char firstChar = deleteInfo[0].charAt(0); try { if (firstChar == '#') { - Integer.parseInt(deleteInfo[0].replace("#","").trim()); + this.patientId = Integer.parseInt(deleteInfo[0].replace("#","").trim()); this.taskId = Integer.parseInt(deleteInfo[1]); } else { this.deletedPatientInfo = deleteInfo[0]; From d4a7c9a6fdb14bb23effb41d8e2471e2991c13f4 Mon Sep 17 00:00:00 2001 From: lmtaek Date: Tue, 22 Oct 2019 22:51:32 +0800 Subject: [PATCH 211/420] Changed naming of certain commands based on feedback; attempted to make more sensible/less similar to other commands. --- src/main/java/duke/core/CommandManager.java | 8 +++--- src/main/java/duke/core/Parser.java | 10 ++++---- src/test/java/duke/core/ParserTest.java | 28 ++++++++++----------- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index b53ac1ef6a..64e776a6cc 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -46,16 +46,16 @@ public static Command manageCommand(String userInput) throws DukeException { return new AddPatientCommand(parser.parseAddPatient()); case "add task": return new AddStandardTaskCommand(parser.parseAddTask()); - case "assign standard task": - return new AssignTaskToPatientCommand(parser.parseAssignStandardTask()); + case "assign deadline task": + return new AssignTaskToPatientCommand(parser.parseAssignDeadlineTask()); case "assign event task": return new AssignTaskToPatientCommand(parser.parseAssignEventTask()); case "list patients": return new ListPatientsCommand(); case "list tasks": return new ListTasksCommand(); - case "delete patient task": - return new DeletePatientTaskCommand(parser.parseDeletePatientTask()); + case "delete assigned task": + return new DeletePatientTaskCommand(parser.parseDeleteAssignedTask()); case "delete patient": return new DeletePatientCommand(parser.parseDeletePatient()); case "delete task": diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index 6bc1b8e9ed..c1af147755 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -64,14 +64,14 @@ public String parseAddTask() throws DukeException { } /** - * Takes the user input and formats it so it is compatible with `assign standard task` commands. + * Takes the user input and formats it so it is compatible with `assign deadline task` commands. *

- * `assign standard task` output: patient_name or #patient_id, task_name or #task_id, dateTime + * `assign standard task` output: patient_name or #patient_id, task_name or #task_id, deadline * - * @return A string of formatted output to be used by `assign standard task` command. + * @return A string of formatted output to be used by `assign deadline task` command. * @throws DukeException Thrown when the user input cannot be parsed in the desired manner. */ - public String[] parseAssignStandardTask() throws DukeException { + public String[] parseAssignDeadlineTask() throws DukeException { String[] formattedInput = new String[3]; try { for (int i = 1; i <= formattedInput.length; i++) { @@ -155,7 +155,7 @@ public String parseDeleteTask() throws DukeException { * @return Array of strings to be used by 'delete patient task' command. * @throws DukeException when user input cannot be parsed properly. */ - public String[] parseDeletePatientTask() throws DukeException { + public String[] parseDeleteAssignedTask() throws DukeException { try { String[] formattedInput = new String[2]; for (int i = 1; i <= formattedInput.length; i++) { diff --git a/src/test/java/duke/core/ParserTest.java b/src/test/java/duke/core/ParserTest.java index 81f36915fa..63f0d28234 100644 --- a/src/test/java/duke/core/ParserTest.java +++ b/src/test/java/duke/core/ParserTest.java @@ -10,15 +10,15 @@ public class ParserTest { String patientDummyInput = "add patient :name :NRIC :room :remark"; String taskDummyInput = "add task Walk the dog"; - String assignPatientToStandardTask = "assign standard task :patient name :#2 :02/02/2002 2222"; + String assignPatientToDeadlineTask = "assign standard task :patient name :#2 :02/02/2002 2222"; String assignPatientToEventTask = "assign event task :#2 :#1 :01/02/2003 1234 to 06/05/2004 2312"; String deletePatientInputWithID = "delete patient #123"; String deletePatientInputWithName = "delete patient billy joe"; String deleteTaskInputWithID = "delete task #10"; String deleteTaskInputWithName = "delete task Take medicine"; - String deletePatientTaskInputWithID = "delete patient task #2 #5"; - String deletePatientTaskInputWithName = "delete patient task patient name task name"; + String deleteAssignedTaskInputWithID = "delete patient task #2 #5"; + String deleteAssignedTaskInputWithName = "delete patient task patient name task name"; @Test public void parseAddPatientTest() throws DukeException { @@ -44,19 +44,19 @@ public void parseAddTask() throws DukeException { @Test public void parseAssignStandardAndEventTasks() throws DukeException { - Parser testParserStandard = new Parser(assignPatientToStandardTask); + Parser testParserDeadline = new Parser(assignPatientToDeadlineTask); Parser testParserEvent = new Parser(assignPatientToEventTask); - final String[] testStandardOutput = testParserStandard.parseAssignStandardTask(); + final String[] testDeadlineOutput = testParserDeadline.parseAssignDeadlineTask(); final String[] testEventOutput = testParserEvent.parseAssignEventTask(); - String[] desiredStandardOutput = {"patient name", "#2", "02/02/2002 2222"}; + String[] desiredDeadlineOutput = {"patient name", "#2", "02/02/2002 2222"}; String[] desiredEventOutput = {"#2", "#1", "01/02/2003 1234", "06/05/2004 2312"}; - assertTrue(desiredStandardOutput.length == testStandardOutput.length); - for (int i = 0; i < desiredStandardOutput.length; i++) { - assertTrue(desiredStandardOutput[i].equals(testStandardOutput[i]), "Parsing failed. Expected: " - + desiredStandardOutput[i] + " but got: " + testStandardOutput[i]); + assertTrue(desiredDeadlineOutput.length == testDeadlineOutput.length); + for (int i = 0; i < desiredDeadlineOutput.length; i++) { + assertTrue(desiredDeadlineOutput[i].equals(testDeadlineOutput[i]), "Parsing failed. Expected: " + + desiredDeadlineOutput[i] + " but got: " + testDeadlineOutput[i]); } assertTrue(desiredEventOutput.length == testEventOutput.length); @@ -96,11 +96,11 @@ public void parseDeleteTask() throws DukeException { @Test public void parseDeletePatientTask() throws DukeException { - Parser testParserID = new Parser(deletePatientTaskInputWithID); - Parser testParserName = new Parser(deletePatientTaskInputWithName); + Parser testParserID = new Parser(deleteAssignedTaskInputWithID); + Parser testParserName = new Parser(deleteAssignedTaskInputWithName); - String[] testOutputID = testParserID.parseDeletePatientTask(); - String[] testOutputName = testParserName.parseDeletePatientTask(); + String[] testOutputID = testParserID.parseDeleteAssignedTask(); + String[] testOutputName = testParserName.parseDeleteAssignedTask(); String[] desiredOutputID = {"#2", "#5"}; String[] desiredOutputName = {"patient name", "task name"}; From 49e6266cd38336754fe7458ab93fee514b205571 Mon Sep 17 00:00:00 2001 From: lmtaek Date: Wed, 23 Oct 2019 11:08:21 +0800 Subject: [PATCH 212/420] Alterations to allow Travis to pass checks; slight tweaks to Update classes that should be revisited by actual author to make sure logic works; tweaked ParserTests to be compliant to new format for user input. --- .../duke/command/UpdatePatientCommand.java | 6 +++--- .../java/duke/command/UpdateTaskCommand.java | 6 +++--- src/main/java/duke/core/CommandManager.java | 1 + src/main/java/duke/core/Parser.java | 20 +++++------------- src/test/java/duke/core/ParserTest.java | 21 ++++++++++--------- 5 files changed, 23 insertions(+), 31 deletions(-) diff --git a/src/main/java/duke/command/UpdatePatientCommand.java b/src/main/java/duke/command/UpdatePatientCommand.java index 51a07d224c..74290bce37 100644 --- a/src/main/java/duke/command/UpdatePatientCommand.java +++ b/src/main/java/duke/command/UpdatePatientCommand.java @@ -10,14 +10,14 @@ public class UpdatePatientCommand extends Command { - private String command; + private String[] command; /** * . * * @param command . */ - public UpdatePatientCommand(String command) { + public UpdatePatientCommand(String[] command) { this.command = command; } @@ -34,7 +34,7 @@ public UpdatePatientCommand(String command) { @Override public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientManager, Ui ui, StorageManager storageManager) throws DukeException { - String[] tempCommand = command.split(" ", 3); + String[] tempCommand = command[0].split(" ", 3); //changed temporarily to allow build success char firstChar = tempCommand[0].charAt(0); if (firstChar == '#') { int id; diff --git a/src/main/java/duke/command/UpdateTaskCommand.java b/src/main/java/duke/command/UpdateTaskCommand.java index 6dd83cc2d4..632f05801d 100644 --- a/src/main/java/duke/command/UpdateTaskCommand.java +++ b/src/main/java/duke/command/UpdateTaskCommand.java @@ -9,14 +9,14 @@ import duke.task.TaskManager; public class UpdateTaskCommand extends Command { - private String command; + private String[] command; /** * . * * @param command . */ - public UpdateTaskCommand(String command) { + public UpdateTaskCommand(String[] command) { this.command = command; } @@ -33,7 +33,7 @@ public UpdateTaskCommand(String command) { @Override public void execute(PatientTaskList patientTask, TaskManager taskManager, PatientManager patientManager, Ui ui, StorageManager storageManager) throws DukeException { - String[] tempCommand = command.split(" ", 3); + String[] tempCommand = command[0].split(" ", 3); //changed temporarily to allow build success char firstChar = tempCommand[0].charAt(0); if (firstChar == '#') { int id; diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 64e776a6cc..b50aafce4a 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -1,4 +1,5 @@ //@@lmtaek + package duke.core; import duke.command.AddPatientCommand; diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index c1af147755..9537cd9864 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -1,4 +1,5 @@ //@@lmtaek + package duke.core; public class Parser { @@ -23,7 +24,6 @@ public Parser(String userInput) throws DukeException { /** * Parses user input so that it is compatible with `add patient` command. - *

* `add patient` output: patient_name, patient_NRIC, patient_room, patient_remark * * @return A formatted string that will work for the available `add patient` command. @@ -46,7 +46,6 @@ public String[] parseAddPatient() throws DukeException { /** * Parses user input so that it is compatible with `add task` command. - *

* `add task` output: task_description * * @return A formatted string that will work for the available `add task` command. @@ -58,14 +57,13 @@ public String parseAddTask() throws DukeException { try { formattedOutput = parsedInput[1].trim(); } catch (Exception e) { - throw new DukeException("Please follow the `add task :`."); + throw new DukeException("Please follow the `add task :` format."); } return formattedOutput; } /** * Takes the user input and formats it so it is compatible with `assign deadline task` commands. - *

* `assign standard task` output: patient_name or #patient_id, task_name or #task_id, deadline * * @return A string of formatted output to be used by `assign deadline task` command. @@ -87,7 +85,6 @@ public String[] parseAssignDeadlineTask() throws DukeException { /** * Takes the user input and formats it so it is compatible with `assign event task` command. - *

* `assign event task` output: patient_name or #patient_id, task_name or #task_id, start_time, end_time * * @return A string of formatted output to be used by `assign event task` command. @@ -96,13 +93,13 @@ public String[] parseAssignDeadlineTask() throws DukeException { public String[] parseAssignEventTask() throws DukeException { String[] formattedInput = new String[4]; try { - String[] parsedTimes = parsedInput[4].split(" to "); + String[] parsedTimes = parsedInput[3].split(" to "); for (int i = 1; i < (formattedInput.length - 1); i++) { formattedInput[i - 1] = parsedInput[i].trim(); } - formattedInput[3] = parsedTimes[0]; - formattedInput[4] = parsedTimes[1]; + formattedInput[2] = parsedTimes[0]; + formattedInput[3] = parsedTimes[1]; return formattedInput; } catch (Exception e) { throw new DukeException("Please follow the " @@ -113,7 +110,6 @@ public String[] parseAssignEventTask() throws DukeException { /** * Takes the user input and formats it so it is compatible with 'delete patient' command. - *

* `delete patient` output: patient_name or #patient_id * * @return A string of formatted output to be used by 'delete patient' commands. @@ -131,7 +127,6 @@ public String parseDeletePatient() throws DukeException { /** * Takes the user input and formats it so it is compatible with 'delete task' command. - *

* `delete task` output: task_id or task_name * * @return A string of formatted output to be used by 'delete task' commands. @@ -149,7 +144,6 @@ public String parseDeleteTask() throws DukeException { /** * Takes user input and formats it so it is compatible with 'delete patient task' command. - *

* `delete patient task` output: patient_name or #patient_id, task_name or #task_id * * @return Array of strings to be used by 'delete patient task' command. @@ -170,7 +164,6 @@ public String[] parseDeleteAssignedTask() throws DukeException { /** * Takes the user input and formats it so it is compatible with 'update patient' command. - *

* `update patient` output: patient_name or #patient_id, edited_field, updated_info * * @return A string of formatted output to be used by 'update patient' commands. @@ -192,7 +185,6 @@ public String[] parseUpdatePatient() throws DukeException { /** * Takes the user input and formats it so it is compatible with 'update task' command. - *

* `update task` output: task_name or #task_id, updated_description * * @return A string of formatted output to be used by 'update task' commands. @@ -213,7 +205,6 @@ public String[] parseUpdateTask() throws DukeException { /** * Takes the user input and formats it so it is compatible with 'find patient' command. - *

* `find patient` output: patient_name or #patient_id * * @return A string of formatted output to be used by 'find patient' command. @@ -230,7 +221,6 @@ public String parseFindPatient() throws DukeException { /** * Takes the user input and formats it so it is compatible with 'find patient task' command. - *

* `find patient tasks` output: patient_name or #patient_id * * @return A string of formatted output to be used by 'find patient task' command. diff --git a/src/test/java/duke/core/ParserTest.java b/src/test/java/duke/core/ParserTest.java index 63f0d28234..547bcf21c5 100644 --- a/src/test/java/duke/core/ParserTest.java +++ b/src/test/java/duke/core/ParserTest.java @@ -1,4 +1,5 @@ //@@lmtaek + package duke.core; import org.junit.jupiter.api.Test; @@ -8,17 +9,17 @@ public class ParserTest { String patientDummyInput = "add patient :name :NRIC :room :remark"; - String taskDummyInput = "add task Walk the dog"; + String taskDummyInput = "add task :Walk the dog"; - String assignPatientToDeadlineTask = "assign standard task :patient name :#2 :02/02/2002 2222"; + String assignPatientToDeadlineTask = "assign deadline task :patient name :#2 :02/02/2002 2222"; String assignPatientToEventTask = "assign event task :#2 :#1 :01/02/2003 1234 to 06/05/2004 2312"; - String deletePatientInputWithID = "delete patient #123"; - String deletePatientInputWithName = "delete patient billy joe"; - String deleteTaskInputWithID = "delete task #10"; - String deleteTaskInputWithName = "delete task Take medicine"; - String deleteAssignedTaskInputWithID = "delete patient task #2 #5"; - String deleteAssignedTaskInputWithName = "delete patient task patient name task name"; + String deletePatientInputWithID = "delete patient :#123"; + String deletePatientInputWithName = "delete patient :billy joe"; + String deleteTaskInputWithID = "delete task :#10"; + String deleteTaskInputWithName = "delete task :Take medicine"; + String deleteAssignedTaskInputWithID = "delete assigned task :#2 :#5"; + String deleteAssignedTaskInputWithName = "delete assigned task :patient name :task name"; @Test public void parseAddPatientTest() throws DukeException { @@ -43,7 +44,7 @@ public void parseAddTask() throws DukeException { } @Test - public void parseAssignStandardAndEventTasks() throws DukeException { + public void parseAssignDeadlineAndEventTasks() throws DukeException { Parser testParserDeadline = new Parser(assignPatientToDeadlineTask); Parser testParserEvent = new Parser(assignPatientToEventTask); @@ -95,7 +96,7 @@ public void parseDeleteTask() throws DukeException { } @Test - public void parseDeletePatientTask() throws DukeException { + public void parseDeleteAssignedTask() throws DukeException { Parser testParserID = new Parser(deleteAssignedTaskInputWithID); Parser testParserName = new Parser(deleteAssignedTaskInputWithName); From 9c64719d4eabd71e57dc6cf8ab200c6dd37b57a5 Mon Sep 17 00:00:00 2001 From: Qian Jie Date: Wed, 23 Oct 2019 17:37:15 +0800 Subject: [PATCH 213/420] resolved travis fail due to checkstyle --- src/main/java/duke/core/CommandManager.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 6533e069ef..3c9b585ae7 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -2,7 +2,21 @@ package duke.core; -import duke.command.*; +import duke.command.AddPatientCommand; +import duke.command.AddStandardTaskCommand; +import duke.command.AssignTaskToPatientCommand; +import duke.command.Command; +import duke.command.DeletePatientCommand; +import duke.command.DeletePatientTaskCommand; +import duke.command.DeleteTaskCommand; +import duke.command.DukeCommand; +import duke.command.ExitCommand; +import duke.command.FindPatientCommand; +import duke.command.FindPatientTaskCommand; +import duke.command.ListPatientsCommand; +import duke.command.ListTasksCommand; +import duke.command.UpdatePatientCommand; +import duke.command.UpdateTaskCommand; /** * Represents a Parser that parses user input into a specific From 2d5e8a6f5f079c1dfd777b80c44cf37674f12e0a Mon Sep 17 00:00:00 2001 From: Qian Jie Date: Wed, 23 Oct 2019 18:05:49 +0800 Subject: [PATCH 214/420] removed CounterStorage --- .../java/duke/storage/CounterStorage.java | 94 ------------------- 1 file changed, 94 deletions(-) delete mode 100644 src/main/java/duke/storage/CounterStorage.java diff --git a/src/main/java/duke/storage/CounterStorage.java b/src/main/java/duke/storage/CounterStorage.java deleted file mode 100644 index 9ecf71a49d..0000000000 --- a/src/main/java/duke/storage/CounterStorage.java +++ /dev/null @@ -1,94 +0,0 @@ -package duke.storage; - -import duke.core.DukeException; - -import org.apache.commons.csv.CSVFormat; -import org.apache.commons.csv.CSVPrinter; -import org.apache.commons.csv.CSVRecord; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.Reader; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.HashMap; -import java.util.Map; - - -/** - * A class for load/save of command frequency in csv format, - * written with Storage template written by HUANG XUAN KUN. - * - * @author QIAN JIE - * @version 1.3 - */ -public class CounterStorage { - /** - * A string that represents a relative file path from the project folder. - */ - private String filePath; - - /** - * Constructs a Storage object with a specific file path. - * - * @param filePath A string that represents the path of the file to read or - * write. - */ - public CounterStorage(String filePath) { - this.filePath = filePath; - } - - /** - * Load the command counter table from local csv files. - * - * @return A Map with key being the command name and value being the counts. - * @throws DukeException throw a dukeException with error message for debugging. - */ - public Map load() throws DukeException { - Map cmdFreqTable = new HashMap<>(); - File csvFile = new File(filePath); - try { - if (csvFile.createNewFile()) { - System.out.println("File " + filePath + " is created."); - } else { - Reader in = new FileReader(filePath); - Iterable records = CSVFormat.EXCEL.withFirstRecordAsHeader().parse(in); - for (CSVRecord record : records) { - String commandName = record.get("Command Name"); - Integer frequency = Integer.parseInt(record.get("Frequency")); - cmdFreqTable.put(commandName, frequency); - } - } - return cmdFreqTable; - } catch (Exception e) { - throw new DukeException("Loading of " - + filePath - + "is unsuccessful." - + "e.getMessage()"); - } - } - - /** - * Write the key value set of command count table info to local csv files. - * - * @param cmdFreqTable A list of patients containing info of patients to be written - * @throws DukeException throw exception with error message when i/o fails - */ - public void save(Map cmdFreqTable) throws DukeException { - try { - BufferedWriter writer = Files.newBufferedWriter(Paths.get(filePath)); - CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT - .withHeader("Command Name", "Frequency")); - for (Map.Entry entry : cmdFreqTable.entrySet()) { - String commandName = entry.getKey(); - String frequency = entry.getValue().toString(); - csvPrinter.printRecord(commandName, frequency); - } - csvPrinter.flush(); - } catch (IOException e) { - throw new DukeException(e.getMessage()); - } - } -} From 0769e05923c893a65d113a8889f5314ed4bd0246 Mon Sep 17 00:00:00 2001 From: Kejun Liu Date: Wed, 23 Oct 2019 18:24:24 +0800 Subject: [PATCH 215/420] Separate the method to extract the patient id from execute function. --- .../duke/command/DeletePatientCommand.java | 106 +++++++++++------- 1 file changed, 65 insertions(+), 41 deletions(-) diff --git a/src/main/java/duke/command/DeletePatientCommand.java b/src/main/java/duke/command/DeletePatientCommand.java index 744faeaa3e..b1fc0ad39a 100644 --- a/src/main/java/duke/command/DeletePatientCommand.java +++ b/src/main/java/duke/command/DeletePatientCommand.java @@ -18,89 +18,113 @@ import java.util.ArrayList; public class DeletePatientCommand extends Command { - private int id; private String deletedPatientInfo; + private Patient patientToBeDeleted; /** - * It checks whether user is deleting a patient by id. - * It extracts the id of the patient to be deleted. + * It saves the delete patient command. * - * @param deletedPatientInfo it contains the information of the patient to be deleted - * @throws DukeException it shows user the correct format to delete a patient by id + * @param deletedPatientInfo it contains the information of the patient to be deleted. */ - public DeletePatientCommand(String deletedPatientInfo) throws DukeException { - + public DeletePatientCommand(String deletedPatientInfo) { this.deletedPatientInfo = deletedPatientInfo; + } + + /** + * It extracts patient id from the delete patient command. + * It checks whether user is deleting by id or name. + * It retrieves patient based on the id extracted. + * + * @param deletedPatientInfo contains the delete patient command. + * @param ui allows user to choose the patient to delete. + * @param patientManager retrieves patient based on patient id. + * @return patient to be deleted. + * @throws DukeException if no matched patient found. + */ + public Patient getPatientByDeletePatientCommand(String deletedPatientInfo, Ui ui, + PatientManager patientManager) throws DukeException { char firstChar = deletedPatientInfo.charAt(0); + Patient patient = null; if (firstChar == '#') { + int id; try { - this.id = Integer.parseInt(deletedPatientInfo.substring(1)); + id = Integer.parseInt(deletedPatientInfo.substring(1)); } catch (Exception e) { throw new DukeException("Please follow format 'delete patient #'. "); } + try { + patient = patientManager.getPatient(id); + } catch (Exception e) { + throw new DukeException("The patient id does not exist. "); + } + } else { + ArrayList patientsWithSameName = patientManager.getPatientByName(deletedPatientInfo); + if (patientsWithSameName.size() >= 1) { + ui.patientsFoundByName(patientsWithSameName, deletedPatientInfo); + int numberChosen = ui.choosePatientToDelete(patientsWithSameName.size()); + if (numberChosen >= 1) { + patient = patientsWithSameName.get(numberChosen - 1); + } + } else { + throw new DukeException("There is no patients matched this name."); + } } + return patient; } /** - * . + * It deletes the patient returned from getPatientByDeletePatientCommand. + * It checks whether this patient is assigned to any tasks. + * It deletes the relationship between this patient and any tasks. * - * @param patientTaskList . - * @param taskManager . - * @param patientManager . - * @param ui . - * @param patientTaskStorage . - * @param taskStorage . - * @param patientStorage . - * @throws DukeException . + * @param patientTaskList contains the information between all the tasks and patients. + * @param taskManager contains information of all the tasks. + * @param patientManager contains information of all the patients. + * @param ui interacts with user. + * @param patientTaskStorage save or load the relation between all the tasks and patients. + * @param taskStorage save or load all the tasks. + * @param patientStorage save or load all the patients. + * @throws DukeException if there is error deleting the patient. */ @Override public void execute(PatientTaskList patientTaskList, TaskManager taskManager, PatientManager patientManager, Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, PatientStorage patientStorage) throws DukeException { + try { + patientToBeDeleted = getPatientByDeletePatientCommand(deletedPatientInfo, ui, patientManager); + } catch (Exception e) { + ui.showError(e.getMessage()); + } boolean toDelete; - ArrayList patientTask = new ArrayList<>(); - Patient patientToBeDeleted = null; - - if (id != 0) { - patientToBeDeleted = patientManager.getPatient(id); - ui.showPatientInfo(patientToBeDeleted); - } else { - ArrayList patientsWithSameName = patientManager.getPatientByName(deletedPatientInfo); - ui.patientsFoundByName(patientsWithSameName, deletedPatientInfo); - if (patientsWithSameName.size() >= 1) { - int numberChosen = ui.choosePatientToDelete(patientsWithSameName.size()); - if (numberChosen >= 1) { - patientToBeDeleted = patientsWithSameName.get(numberChosen - 1); - ui.showPatientInfo(patientToBeDeleted); - } - } - } + ui.showPatientInfo(patientToBeDeleted); try { - patientTask = patientTaskList.getPatientTask(patientToBeDeleted.getID()); + ArrayList patientTask = patientTaskList.getPatientTask(patientToBeDeleted.getID()); ArrayList tempTask = new ArrayList<>(); for (PatientTask temppatientTask : patientTask) { tempTask.add(taskManager.getTask(temppatientTask.getTaskID())); } ui.patientTaskFound(patientToBeDeleted, patientTask, tempTask); toDelete = ui.confirmPatientToBeDeleted(patientToBeDeleted, true); + if (toDelete) { + patientTaskList.deleteEntirePatientTask(patientToBeDeleted.getID()); + patientTaskStorage.save(patientTaskList.fullPatientTaskList()); + } } catch (Exception e) { toDelete = ui.confirmPatientToBeDeleted(patientToBeDeleted,false); } if (toDelete) { patientManager.deletePatient(patientToBeDeleted.getID()); - patientTaskList.deleteEntirePatientTask(patientToBeDeleted.getID()); - ui.patientDeleted(); patientStorage.save(patientManager.getPatientList()); - patientTaskStorage.save(patientTaskList.fullPatientTaskList()); - } + ui.patientDeleted(); + } } /** - * . + * It terminates the Dukepital. * - * @return . + * @return false. */ @Override public boolean isExit() { From faf1621c854dd5c9a2ee928a17adb6430d87637c Mon Sep 17 00:00:00 2001 From: WEIFENG-NUSCEG Date: Wed, 23 Oct 2019 18:35:21 +0800 Subject: [PATCH 216/420] revert some csv file to avoid conflict --- data/counter.csv | 5 +---- data/patientsTasks.csv | 12 +++++++----- src/main/java/duke/core/Parser.java | 9 +++++---- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/data/counter.csv b/data/counter.csv index 46072744d1..063eefc8c8 100644 --- a/data/counter.csv +++ b/data/counter.csv @@ -1,8 +1,5 @@ Command Name,Frequency -DeletePatientTaskCommand,5 DeletePatientCommand,1 -ListPatientsCommand,1 -ListTasksCommand,2 +ListTasksCommand,1 AddStandardTaskCommand,6 AddPatientCommand,3 -FindPatientTaskCommand,2 diff --git a/data/patientsTasks.csv b/data/patientsTasks.csv index a471e61f6d..23e8033b3e 100644 --- a/data/patientsTasks.csv +++ b/data/patientsTasks.csv @@ -1,6 +1,8 @@ PID,TID,DONE,RECURRENCE,DEADLINE,STARTTIME,ENDTIME,TASKTYPE,uuid -2,7,false,false,,09/01/2019 1200,08/11/2019 1000,E,1 -2,7,false,false,09/05/2013 0150,,,S,2 -2,7,false,false,,09/11/2018 1400,08/08/2019 1200,E,3 -2,7,false,false,,08/08/2018 1400,09/09/2019 1200,E,4 -2,7,false,false,,09/08/2019 1200,09/12/2019 1200,E,5 +2,7,false,false,,09/01/2019 1200,08/11/2019 1000,E,8 +2,7,false,false,09/05/2013 0150,,,S,9 +2,7,false,false,,09/11/2018 1400,08/08/2019 1200,E,10 +2,7,false,false,,08/08/2018 1400,09/09/2019 1200,E,11 +2,7,false,false,,09/08/2019 1200,09/12/2019 1200,E,12 +3,8,false,false,09/01/2022 1400,,,S,13 +3,5,false,false,,05/11/2019 1200,05/04/2022 1200,E,14 \ No newline at end of file diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index 98b4fc2951..485394cf4b 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -43,11 +43,12 @@ public String[] parseAdd() throws DukeException { * @return . * @throws DukeException . */ - public String parseDeletePatientTask() throws DukeException { - String formattedInput; + public String[] parseDeletePatientTask() throws DukeException { + String[] formattedInput = new String[2]; try { - String[] parsedCommand = userInput.split("\\s+", 3); - formattedInput = parsedCommand[2]; + String[] parsedCommand = userInput.split("\\s+", 4); + formattedInput[0] = parsedCommand[2]; + formattedInput[1] = parsedCommand[3]; return formattedInput; } catch (Exception e) { throw new DukeException("Please use the correct format for the 'delete patienttask' command. "); From a0f0de87e0c250a03d32167b925342124a791bee Mon Sep 17 00:00:00 2001 From: WEIFENG-NUSCEG Date: Wed, 23 Oct 2019 18:44:05 +0800 Subject: [PATCH 217/420] exclude the implementation in CommandManager --- data/patientsTasks.csv | 21 ++++++++++++++------- src/main/java/duke/core/CommandManager.java | 2 -- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/data/patientsTasks.csv b/data/patientsTasks.csv index 23e8033b3e..66a0c9b77d 100644 --- a/data/patientsTasks.csv +++ b/data/patientsTasks.csv @@ -1,8 +1,15 @@ PID,TID,DONE,RECURRENCE,DEADLINE,STARTTIME,ENDTIME,TASKTYPE,uuid -2,7,false,false,,09/01/2019 1200,08/11/2019 1000,E,8 -2,7,false,false,09/05/2013 0150,,,S,9 -2,7,false,false,,09/11/2018 1400,08/08/2019 1200,E,10 -2,7,false,false,,08/08/2018 1400,09/09/2019 1200,E,11 -2,7,false,false,,09/08/2019 1200,09/12/2019 1200,E,12 -3,8,false,false,09/01/2022 1400,,,S,13 -3,5,false,false,,05/11/2019 1200,05/04/2022 1200,E,14 \ No newline at end of file +1,2,false,false,09/11/2019 1400,,,S,1 +1,3,false,false,09/01/2018 1200,,,S,2 +1,3,false,false,04/04/2019 1400,,,S,3 +1,3,false,false,09/08/2020 1200,,,S,4 +1,3,false,false,09/05/2013 0900,,,S,5 +1,3,false,false,,16/09/2019 1400,12/08/2020 1200,E,6 +1,3,false,false,09/11/2019 1400,,,S,7 +2,7,false,false,,09/01/2019 1200,08/11/2019 1000,E,9 +2,7,false,false,09/05/2013 0150,,,S,10 +2,7,false,false,,09/11/2018 1400,08/08/2019 1200,E,11 +2,7,false,false,,08/08/2018 1400,09/09/2019 1200,E,12 +2,7,false,false,,09/08/2019 1200,09/12/2019 1200,E,13 +3,8,false,false,09/01/2022 1400,,,S,14 +3,5,false,false,,05/11/2019 1200,05/04/2022 1200,E,15 \ No newline at end of file diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 5cf0cd2962..2db4fd9daf 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -75,8 +75,6 @@ public static Command manageCommand(String userInput) throws DukeException { return new DeletePatientCommand(formattedInput); } else if (secondKeyword.equals("task")) { return new DeleteTaskCommand(parser.parseDeleteTask()); - } else if (secondKeyword.equals("patienttask")) { - return new DeletePatientTaskCommand(parser.parseDeletePatientTask()); } else { throw new Exception("Invalid format. "); } From 510c0a7ac490c9257940bf53a7e972adb5e94a9a Mon Sep 17 00:00:00 2001 From: Kejun Liu Date: Wed, 23 Oct 2019 19:22:22 +0800 Subject: [PATCH 218/420] Call the new storage manager class. --- src/main/java/duke/command/DeletePatientCommand.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/java/duke/command/DeletePatientCommand.java b/src/main/java/duke/command/DeletePatientCommand.java index b3d870b4ed..58e8cf85f1 100644 --- a/src/main/java/duke/command/DeletePatientCommand.java +++ b/src/main/java/duke/command/DeletePatientCommand.java @@ -76,9 +76,7 @@ public Patient getPatientByDeletePatientCommand(String deletedPatientInfo, Ui ui * @param taskManager contains information of all the tasks. * @param patientManager contains information of all the patients. * @param ui interacts with user. - * @param patientTaskStorage save or load the relation between all the tasks and patients. - * @param taskStorage save or load all the tasks. - * @param patientStorage save or load all the patients. + * @param storageManager save the changes in csv file. * @throws DukeException if there is error deleting the patient. */ @Override @@ -102,14 +100,14 @@ public void execute(PatientTaskList patientTaskList, TaskManager taskManager, Pa toDelete = ui.confirmPatientToBeDeleted(patientToBeDeleted, true); if (toDelete) { patientTaskList.deleteEntirePatientTask(patientToBeDeleted.getID()); - patientTaskStorage.save(patientTaskList.fullPatientTaskList()); + storageManager.saveAssignedTasks(patientTaskList.fullPatientTaskList()); } } catch (Exception e) { toDelete = ui.confirmPatientToBeDeleted(patientToBeDeleted,false); } if (toDelete) { patientManager.deletePatient(patientToBeDeleted.getID()); - patientStorage.save(patientManager.getPatientList()); + storageManager.savePatients(patientManager.getPatientList()); ui.patientDeleted(); } From 2a5a04df45d3a82f492286b08a72b6e3629bae53 Mon Sep 17 00:00:00 2001 From: Qian Jie Date: Wed, 23 Oct 2019 19:31:36 +0800 Subject: [PATCH 219/420] improve code quality by performing suggestion provided by TA --- src/main/java/duke/Duke.java | 2 +- .../java/duke/command/AddPatientCommand.java | 2 +- .../duke/command/AddStandardTaskCommand.java | 2 +- .../command/AssignTaskToPatientCommand.java | 2 +- src/main/java/duke/command/Command.java | 11 ++--- .../duke/command/DeletePatientCommand.java | 2 +- .../command/DeletePatientTaskCommand.java | 2 +- .../java/duke/command/DeleteTaskCommand.java | 2 +- src/main/java/duke/command/DukeCommand.java | 2 +- src/main/java/duke/command/ExitCommand.java | 2 +- .../java/duke/command/FindPatientCommand.java | 2 +- .../duke/command/FindPatientTaskCommand.java | 2 +- src/main/java/duke/command/HelpCommand.java | 43 ------------------- .../duke/command/ListPatientsCommand.java | 2 +- .../java/duke/command/ListTasksCommand.java | 2 +- .../duke/command/UpdatePatientCommand.java | 2 +- .../java/duke/command/UpdateTaskCommand.java | 2 +- src/main/java/duke/core/DateTimeParser.java | 2 + src/main/java/duke/core/ShortCutter.java | 8 +--- src/main/java/duke/statistic/Counter.java | 4 +- src/test/java/duke/core/CounterTest.java | 5 +++ 21 files changed, 28 insertions(+), 75 deletions(-) delete mode 100644 src/main/java/duke/command/HelpCommand.java create mode 100644 src/test/java/duke/core/CounterTest.java diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index fdc545adcf..a1f8608fdc 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -34,7 +34,7 @@ public class Duke { /** * A Ui object that deals with interactions with the user. */ - private Ui ui = Ui.getUi(); + private static final Ui ui = Ui.getUi(); /** * Constructs a Duke object with a relative file path. diff --git a/src/main/java/duke/command/AddPatientCommand.java b/src/main/java/duke/command/AddPatientCommand.java index a2e5e5f24a..b40003e3da 100644 --- a/src/main/java/duke/command/AddPatientCommand.java +++ b/src/main/java/duke/command/AddPatientCommand.java @@ -8,7 +8,7 @@ import duke.storage.StorageManager; import duke.task.TaskManager; -public class AddPatientCommand extends Command { +public class AddPatientCommand implements Command { private Patient newPatient; diff --git a/src/main/java/duke/command/AddStandardTaskCommand.java b/src/main/java/duke/command/AddStandardTaskCommand.java index 7badb27d35..2967c2d793 100644 --- a/src/main/java/duke/command/AddStandardTaskCommand.java +++ b/src/main/java/duke/command/AddStandardTaskCommand.java @@ -8,7 +8,7 @@ import duke.task.Task; import duke.task.TaskManager; -public class AddStandardTaskCommand extends Command { +public class AddStandardTaskCommand implements Command { private Task newStandardTask; /** diff --git a/src/main/java/duke/command/AssignTaskToPatientCommand.java b/src/main/java/duke/command/AssignTaskToPatientCommand.java index 4e782f8b73..997a8eb320 100644 --- a/src/main/java/duke/command/AssignTaskToPatientCommand.java +++ b/src/main/java/duke/command/AssignTaskToPatientCommand.java @@ -10,7 +10,7 @@ import duke.storage.StorageManager; import duke.task.TaskManager; -public class AssignTaskToPatientCommand extends Command { +public class AssignTaskToPatientCommand implements Command { private String command; private String[] taskAssignmentInfo; diff --git a/src/main/java/duke/command/Command.java b/src/main/java/duke/command/Command.java index 989515cdf6..8b3f4d2fd8 100644 --- a/src/main/java/duke/command/Command.java +++ b/src/main/java/duke/command/Command.java @@ -12,9 +12,7 @@ * class that can not be instantiated, its child class represents different kind * of user command */ -public abstract class Command { - - //protected boolean hasBeenAddedBefore = false; +public interface Command { /** * . @@ -26,15 +24,14 @@ public abstract class Command { * @param storageManager . * @throws DukeException . */ - public abstract void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, Ui ui, - StorageManager storageManager) throws DukeException; - + void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, Ui ui, + StorageManager storageManager) throws DukeException; /** * Decide whether duke should exist. * * @return A boolean. True if the command tells Duke to exit, false */ - public abstract boolean isExit(); + boolean isExit(); } \ No newline at end of file diff --git a/src/main/java/duke/command/DeletePatientCommand.java b/src/main/java/duke/command/DeletePatientCommand.java index f265ef90fd..f3aff10c7e 100644 --- a/src/main/java/duke/command/DeletePatientCommand.java +++ b/src/main/java/duke/command/DeletePatientCommand.java @@ -10,7 +10,7 @@ import java.util.ArrayList; -public class DeletePatientCommand extends Command { +public class DeletePatientCommand implements Command { private int id; private String deletedPatientInfo; diff --git a/src/main/java/duke/command/DeletePatientTaskCommand.java b/src/main/java/duke/command/DeletePatientTaskCommand.java index 3967a167ed..5bcb24453b 100644 --- a/src/main/java/duke/command/DeletePatientTaskCommand.java +++ b/src/main/java/duke/command/DeletePatientTaskCommand.java @@ -11,7 +11,7 @@ import java.util.ArrayList; -public class DeletePatientTaskCommand extends Command { +public class DeletePatientTaskCommand implements Command { private int patientId; private int taskId; private String deletedPatientInfo; diff --git a/src/main/java/duke/command/DeleteTaskCommand.java b/src/main/java/duke/command/DeleteTaskCommand.java index 8234c678bc..f279854291 100644 --- a/src/main/java/duke/command/DeleteTaskCommand.java +++ b/src/main/java/duke/command/DeleteTaskCommand.java @@ -10,7 +10,7 @@ import java.util.ArrayList; -public class DeleteTaskCommand extends Command { +public class DeleteTaskCommand implements Command { private int id; private String deletedTaskInfo; diff --git a/src/main/java/duke/command/DukeCommand.java b/src/main/java/duke/command/DukeCommand.java index 85014d0781..3e91b6531d 100644 --- a/src/main/java/duke/command/DukeCommand.java +++ b/src/main/java/duke/command/DukeCommand.java @@ -10,7 +10,7 @@ import duke.task.TaskManager; -public class DukeCommand extends Command { +public class DukeCommand implements Command { /** * . diff --git a/src/main/java/duke/command/ExitCommand.java b/src/main/java/duke/command/ExitCommand.java index 494accc749..23e590afbf 100644 --- a/src/main/java/duke/command/ExitCommand.java +++ b/src/main/java/duke/command/ExitCommand.java @@ -12,7 +12,7 @@ * extends from the Command class for the user to quit the * program */ -public class ExitCommand extends Command { +public class ExitCommand implements Command { /** * Constructs a ExitCommand object. diff --git a/src/main/java/duke/command/FindPatientCommand.java b/src/main/java/duke/command/FindPatientCommand.java index 6f71dcfd80..0fcce5f3d8 100644 --- a/src/main/java/duke/command/FindPatientCommand.java +++ b/src/main/java/duke/command/FindPatientCommand.java @@ -10,7 +10,7 @@ import java.util.ArrayList; -public class FindPatientCommand extends Command { +public class FindPatientCommand implements Command { private String command; diff --git a/src/main/java/duke/command/FindPatientTaskCommand.java b/src/main/java/duke/command/FindPatientTaskCommand.java index 6a635261a8..49032ddd8c 100644 --- a/src/main/java/duke/command/FindPatientTaskCommand.java +++ b/src/main/java/duke/command/FindPatientTaskCommand.java @@ -12,7 +12,7 @@ import java.util.ArrayList; -public class FindPatientTaskCommand extends Command { +public class FindPatientTaskCommand implements Command { private String command; diff --git a/src/main/java/duke/command/HelpCommand.java b/src/main/java/duke/command/HelpCommand.java deleted file mode 100644 index fff248bcbb..0000000000 --- a/src/main/java/duke/command/HelpCommand.java +++ /dev/null @@ -1,43 +0,0 @@ -//package duke.command; -// -//import duke.core.DukeException; -//import duke.patient.PatientManager; -//import duke.storage.PatientStorage; -//import duke.storage.PatientTaskStorage; -//import duke.storage.TaskStorage; -//import duke.relation.PatientTaskList; -//import duke.core.Ui; -//import duke.task.TaskManager; -// -//public class HelpCommand extends Command { -// -// /** -// * . -// * -// * @param patientTask . -// * @param tasks . -// * @param patientList . -// * @param ui . -// * @param patientTaskStorage . -// * @param taskStorage . -// * @param patientStorage . -// * @throws DukeException . -// */ -// @Override -// public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientList, -// Ui ui, PatientTaskStorage patientTaskStorage, TaskStorage taskStorage, -// PatientStorage patientStorage) throws DukeException { -// //ui.showHelpCommand(); -// -// } -// -// /** -// * . -// * -// * @return . -// */ -// @Override -// public boolean isExit() { -// return false; -// } -//} diff --git a/src/main/java/duke/command/ListPatientsCommand.java b/src/main/java/duke/command/ListPatientsCommand.java index 34974b3002..945880f4af 100644 --- a/src/main/java/duke/command/ListPatientsCommand.java +++ b/src/main/java/duke/command/ListPatientsCommand.java @@ -10,7 +10,7 @@ import java.util.ArrayList; -public class ListPatientsCommand extends Command { +public class ListPatientsCommand implements Command { public ListPatientsCommand() { super(); diff --git a/src/main/java/duke/command/ListTasksCommand.java b/src/main/java/duke/command/ListTasksCommand.java index 6003a3e833..48ad7474d4 100644 --- a/src/main/java/duke/command/ListTasksCommand.java +++ b/src/main/java/duke/command/ListTasksCommand.java @@ -10,7 +10,7 @@ import java.util.ArrayList; -public class ListTasksCommand extends Command { +public class ListTasksCommand implements Command { /** * . diff --git a/src/main/java/duke/command/UpdatePatientCommand.java b/src/main/java/duke/command/UpdatePatientCommand.java index 74290bce37..9678998b36 100644 --- a/src/main/java/duke/command/UpdatePatientCommand.java +++ b/src/main/java/duke/command/UpdatePatientCommand.java @@ -8,7 +8,7 @@ import duke.storage.StorageManager; import duke.task.TaskManager; -public class UpdatePatientCommand extends Command { +public class UpdatePatientCommand implements Command { private String[] command; diff --git a/src/main/java/duke/command/UpdateTaskCommand.java b/src/main/java/duke/command/UpdateTaskCommand.java index 632f05801d..cfffc79ba4 100644 --- a/src/main/java/duke/command/UpdateTaskCommand.java +++ b/src/main/java/duke/command/UpdateTaskCommand.java @@ -8,7 +8,7 @@ import duke.task.Task; import duke.task.TaskManager; -public class UpdateTaskCommand extends Command { +public class UpdateTaskCommand implements Command { private String[] command; /** diff --git a/src/main/java/duke/core/DateTimeParser.java b/src/main/java/duke/core/DateTimeParser.java index d4003ea1a8..48ac4359b5 100644 --- a/src/main/java/duke/core/DateTimeParser.java +++ b/src/main/java/duke/core/DateTimeParser.java @@ -25,6 +25,7 @@ public static LocalDateTime convertToLocalDateTime(String timeBeforeFormat) thro } } + //@@author qjie7 /** * Returns a string that representing the data and time for the task * in a predefined English date time format. @@ -76,4 +77,5 @@ public static String convertToEnglishDateTimeBeforeParse(LocalDateTime localDate return localDateTime.format(thFormatter); } } + //@@author } diff --git a/src/main/java/duke/core/ShortCutter.java b/src/main/java/duke/core/ShortCutter.java index 3b44f35e03..fdd8b5622b 100644 --- a/src/main/java/duke/core/ShortCutter.java +++ b/src/main/java/duke/core/ShortCutter.java @@ -54,7 +54,6 @@ public ShortCutter(Counter counter, Ui ui) { /** * This function is used to allow map to be sorted by its values. - * * @param map a command frequency table in Map structure with key * as the command type and value as the command frequency. * @return a Map structure that is sorted according to param's value @@ -81,7 +80,6 @@ public static > Map sortByValues(final Map Date: Wed, 23 Oct 2019 19:42:40 +0800 Subject: [PATCH 220/420] Revisions made to aid Delete Assigned Task Command; should prevent null exception in instances where user uses unique ID --- src/main/java/duke/core/Parser.java | 16 ++++++++++++---- src/test/java/duke/core/ParserTest.java | 15 ++++++++++----- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index 9537cd9864..ad8e181a00 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -145,6 +145,7 @@ public String parseDeleteTask() throws DukeException { /** * Takes user input and formats it so it is compatible with 'delete patient task' command. * `delete patient task` output: patient_name or #patient_id, task_name or #task_id + * `delete patient task` output: assigned_task_unique_id * * @return Array of strings to be used by 'delete patient task' command. * @throws DukeException when user input cannot be parsed properly. @@ -152,13 +153,20 @@ public String parseDeleteTask() throws DukeException { public String[] parseDeleteAssignedTask() throws DukeException { try { String[] formattedInput = new String[2]; - for (int i = 1; i <= formattedInput.length; i++) { - formattedInput[i - 1] = parsedInput[i].trim(); + + if (parsedInput[1].trim().charAt(0) == '%') { + formattedInput[0] = parsedInput[1]; + return formattedInput; + } else { + for (int i = 1; i <= formattedInput.length; i++) { + formattedInput[i - 1] = parsedInput[i].trim(); + } + return formattedInput; } - return formattedInput; } catch (Exception e) { throw new DukeException("Please follow the `delete patient task : or #" - + " : or #` format."); + + " : or #` or " + + " `delete patient task :%` format."); } } diff --git a/src/test/java/duke/core/ParserTest.java b/src/test/java/duke/core/ParserTest.java index 547bcf21c5..59f1c73667 100644 --- a/src/test/java/duke/core/ParserTest.java +++ b/src/test/java/duke/core/ParserTest.java @@ -20,6 +20,7 @@ public class ParserTest { String deleteTaskInputWithName = "delete task :Take medicine"; String deleteAssignedTaskInputWithID = "delete assigned task :#2 :#5"; String deleteAssignedTaskInputWithName = "delete assigned task :patient name :task name"; + String deleteAssignedTaskInputWithUniqueID = "delete assigned task :%3"; @Test public void parseAddPatientTest() throws DukeException { @@ -98,13 +99,8 @@ public void parseDeleteTask() throws DukeException { @Test public void parseDeleteAssignedTask() throws DukeException { Parser testParserID = new Parser(deleteAssignedTaskInputWithID); - Parser testParserName = new Parser(deleteAssignedTaskInputWithName); - String[] testOutputID = testParserID.parseDeleteAssignedTask(); - String[] testOutputName = testParserName.parseDeleteAssignedTask(); - String[] desiredOutputID = {"#2", "#5"}; - String[] desiredOutputName = {"patient name", "task name"}; assertTrue(desiredOutputID.length == testOutputID.length); for (int i = 0; i < desiredOutputID.length; i++) { @@ -112,12 +108,21 @@ public void parseDeleteAssignedTask() throws DukeException { + desiredOutputID[i] + " but got: " + testOutputID[i]); } + Parser testParserName = new Parser(deleteAssignedTaskInputWithName); + String[] testOutputName = testParserName.parseDeleteAssignedTask(); + String[] desiredOutputName = {"patient name", "task name"}; assertTrue(desiredOutputName.length == testOutputName.length); for (int i = 0; i < desiredOutputName.length; i++) { assertTrue(desiredOutputName[i].equals(testOutputName[i]), "Parsing failed. Expected: " + desiredOutputName[i] + " but got: " + testOutputName[i]); } + Parser testParserUniqueID = new Parser(deleteAssignedTaskInputWithUniqueID); + String[] testOutputUniqueID = testParserUniqueID.parseDeleteAssignedTask(); + String[] desiredOutputUniqueID = {"%3"}; + assertTrue(desiredOutputUniqueID[0].equals(testOutputUniqueID[0]), "Parsing failed. Expected: " + + desiredOutputUniqueID[0] + " but got: " + testOutputUniqueID[0]); + } } \ No newline at end of file From 00826808f35227960e62ad33758172cebbffe682 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Wed, 23 Oct 2019 19:58:58 +0800 Subject: [PATCH 221/420] Update TypoCorrect and its Junit test for the new parsing format --- src/main/java/duke/core/TypoCorrector.java | 46 +++++++------------ .../java/duke/core/TypoCorrectorTest.java | 21 ++++----- 2 files changed, 26 insertions(+), 41 deletions(-) diff --git a/src/main/java/duke/core/TypoCorrector.java b/src/main/java/duke/core/TypoCorrector.java index 5eb90ed95c..0af685c533 100644 --- a/src/main/java/duke/core/TypoCorrector.java +++ b/src/main/java/duke/core/TypoCorrector.java @@ -2,9 +2,6 @@ import org.apache.commons.text.similarity.LevenshteinDistance; -import java.util.ArrayList; -import java.util.Arrays; - /** * This is a command typo corrector for Duke user command. * It provides a method TypoCorrector.CommandCorrection which takes in an invalid input command @@ -19,14 +16,10 @@ public class TypoCorrector { private static final double MAX_DISTANCE_DIFF_RATIO = 0.5; //Sets of "Dictionaries" for the command keyword, categorised by number of keywords contain in a supported commands. - private static final ArrayList oneKeywordCommand = new ArrayList( - Arrays.asList("bye", "duke", "help")); - private static final ArrayList twoKeywordsCommands = new ArrayList( - Arrays.asList("list patients", "list tasks")); - private static final ArrayList otherCommands = new ArrayList( - Arrays.asList("update patient", "update task", - "delete patient", "delete task", "delete patienttask", "add task", "add patient", - "find patient", "find task", "assign standardtask", "assign eventtask")); + private static final String[] simpleCommands = {"bye", "duke", "help", "list patients", "list tasks"}; + private static final String[] otherCommands = {"update patient", "update task", "delete patient", + "delete task", "delete assigned task", "add task", "add patient", "find patient", "find task", + "find patient tasks", "assign deadline task", "assign event task"}; /** * This method take in an user input command with typo and return a possible matches @@ -36,28 +29,21 @@ public class TypoCorrector { * @return a string of correctedCommand */ public static String commandCorrection(String command) { - String[] splitCommand = command.split("\\s+"); + String[] splitCommand = command.split(":"); int commandSize = splitCommand.length; String closestMatch; - String firstTwoKeywords; - if (commandSize == 1 || command.length() <= 6) { - closestMatch = matchStringFromDict(command, oneKeywordCommand); - if (isSimilar(command, closestMatch)) { - return closestMatch; - } - } else if (commandSize == 2) { - firstTwoKeywords = command.toLowerCase(); - closestMatch = matchStringFromDict(firstTwoKeywords, twoKeywordsCommands); - if (isSimilar(firstTwoKeywords, closestMatch)) { + if (commandSize == 1) { + String fullCommand = command.trim().toLowerCase(); + closestMatch = matchStringFromDict(fullCommand, simpleCommands); + if (isSimilar(fullCommand, closestMatch)) { return closestMatch; } } else { - firstTwoKeywords = (splitCommand[0] + " " + splitCommand[1]).toLowerCase(); - closestMatch = matchStringFromDict(firstTwoKeywords, otherCommands); - if (isSimilar(firstTwoKeywords, closestMatch)) { + String keyword = splitCommand[0].trim().toLowerCase(); + closestMatch = matchStringFromDict(keyword, otherCommands); + if (isSimilar(keyword, closestMatch)) { splitCommand[0] = ""; - splitCommand[1] = ""; - return closestMatch + " " + String.join(" ", splitCommand).trim(); + return closestMatch + " " + String.join(":", splitCommand).trim(); } } return command; @@ -67,9 +53,9 @@ public static String commandCorrection(String command) { * Get the closest match string from the array targetDict. * * @param str the arbitrary string - * @return + * @return the closest matching from the target dict */ - private static String matchStringFromDict(String str, ArrayList targetDict) { + private static String matchStringFromDict(String str, String[] targetDict) { int minDist = 256; String closestMatch = null; for (String keyword : targetDict) { @@ -89,7 +75,7 @@ private static String matchStringFromDict(String str, ArrayList targetDi * Get Levenshtein distance between target and an arbitrary string. * * @param str the arbitrary string - * @return + * @return the difference of two strings measured in distance */ private static Integer getDistance(String str, String target) { LevenshteinDistance distance = new LevenshteinDistance(); diff --git a/src/test/java/duke/core/TypoCorrectorTest.java b/src/test/java/duke/core/TypoCorrectorTest.java index 933cc7c9c6..64d09ee809 100644 --- a/src/test/java/duke/core/TypoCorrectorTest.java +++ b/src/test/java/duke/core/TypoCorrectorTest.java @@ -1,12 +1,11 @@ package duke.core; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; import java.util.ArrayList; import java.util.Arrays; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * Junit test for TypoCorrector class. * @@ -22,15 +21,15 @@ void stringMatchTest() { new String[]{"bqe", "bye"}, new String[]{"lsit patant", "list patients"}, new String[]{"lsfvs takss", "list tasks"}, - new String[]{"deelte Ptients #12", "delete patient #12"}, - new String[]{"deleot tasksa task description", "delete task task description"}, - new String[]{"delette tasks #1", "delete task #1"}, - new String[]{"addd patents name nric room remark", "add patient name nric room remark"}, - new String[]{"dad tsak a very long task name", "add task a very long task name"}, - new String[]{"addd task abc", "add task abc"}, - new String[]{"asgn standrdtask #1 12 12/12/2019 1645", "assign standardtask #1 12 12/12/2019 1645"}, - new String[]{"assgn eventask #1 12 12/12/2019 1645 to 12/12/2020 1645", - "assign eventtask #1 12 12/12/2019 1645 to 12/12/2020 1645"} + new String[]{"deelte Ptients:#12", "delete patient :#12"}, + new String[]{"deleot tasksa :task description", "delete task :task description"}, + new String[]{"delette tasks :#1", "delete task :#1"}, + new String[]{"addd patents:name :nric :room :remark", "add patient :name :nric :room :remark"}, + new String[]{"dad tsak:a very long task name", "add task :a very long task name"}, + new String[]{"addd task :abc", "add task :abc"}, + new String[]{"asgn deadli task: #1 :12 :12/12/2019 1645", "assign deadline task : #1 :12 :12/12/2019 1645"}, + new String[]{"assgn even tk :#1 :12 :12/12/2019 1645 :12/12/2020 1645", + "assign event task :#1 :12 :12/12/2019 1645 :12/12/2020 1645"} )); for (String[] testPair : testCases) { String correctedOutput = TypoCorrector.commandCorrection(testPair[0]); From c5ac1522dfa2ea5ea54436d5760f1901facd03c6 Mon Sep 17 00:00:00 2001 From: lmtaek Date: Wed, 23 Oct 2019 20:03:56 +0800 Subject: [PATCH 222/420] Updated 'find patient tasks' command to 'find assigned tasks' in order to keep commands clear and consistent. --- src/main/java/duke/core/CommandManager.java | 4 ++-- src/main/java/duke/core/Parser.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index b50aafce4a..be6623a3e8 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -63,8 +63,8 @@ public static Command manageCommand(String userInput) throws DukeException { return new DeleteTaskCommand(parser.parseDeleteTask()); case "find patient": return new FindPatientCommand((parser.parseFindPatient())); - case "find patient tasks": - return new FindPatientTaskCommand((parser.parseFindPatientTasks())); + case "find assigned tasks": + return new FindPatientTaskCommand((parser.parseFindAssignedTasks())); case "update patient": return new UpdatePatientCommand(parser.parseUpdatePatient()); case "update task": diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index ad8e181a00..a17c386c5b 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -234,12 +234,12 @@ public String parseFindPatient() throws DukeException { * @return A string of formatted output to be used by 'find patient task' command. * @throws DukeException Thrown when the user input cannot be parsed in the desired manner. */ - public String parseFindPatientTasks() throws DukeException { + public String parseFindAssignedTasks() throws DukeException { try { String formattedInput = parsedInput[1].trim(); return formattedInput; } catch (Exception e) { - throw new DukeException("Please use the `find patient tasks : or #` format."); + throw new DukeException("Please use the `find assigned tasks : or #` format."); } } } \ No newline at end of file From c0c63cec2194700a09a03ab2012f2c29e4cd63ee Mon Sep 17 00:00:00 2001 From: lmtaek Date: Wed, 23 Oct 2019 20:05:43 +0800 Subject: [PATCH 223/420] Last commit--had slight typo in phrasing of command. --- src/main/java/duke/core/CommandManager.java | 4 ++-- src/main/java/duke/core/Parser.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index be6623a3e8..b576755bae 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -63,8 +63,8 @@ public static Command manageCommand(String userInput) throws DukeException { return new DeleteTaskCommand(parser.parseDeleteTask()); case "find patient": return new FindPatientCommand((parser.parseFindPatient())); - case "find assigned tasks": - return new FindPatientTaskCommand((parser.parseFindAssignedTasks())); + case "find assigned task": + return new FindPatientTaskCommand((parser.parseFindAssignedTask())); case "update patient": return new UpdatePatientCommand(parser.parseUpdatePatient()); case "update task": diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index a17c386c5b..29de494996 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -234,7 +234,7 @@ public String parseFindPatient() throws DukeException { * @return A string of formatted output to be used by 'find patient task' command. * @throws DukeException Thrown when the user input cannot be parsed in the desired manner. */ - public String parseFindAssignedTasks() throws DukeException { + public String parseFindAssignedTask() throws DukeException { try { String formattedInput = parsedInput[1].trim(); return formattedInput; From e59c8807ec0f59be5225a8133cd49f7318b64afd Mon Sep 17 00:00:00 2001 From: lmtaek Date: Wed, 23 Oct 2019 20:12:36 +0800 Subject: [PATCH 224/420] Last typo correction. Tells user how to correctly input command. --- src/main/java/duke/core/Parser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index 29de494996..10e8aa225a 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -239,7 +239,7 @@ public String parseFindAssignedTask() throws DukeException { String formattedInput = parsedInput[1].trim(); return formattedInput; } catch (Exception e) { - throw new DukeException("Please use the `find assigned tasks : or #` format."); + throw new DukeException("Please use the `find assigned task : or #` format."); } } } \ No newline at end of file From 03e6c213ad75d52c4117b1bafd062c7cb8c6131e Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Wed, 23 Oct 2019 20:20:22 +0800 Subject: [PATCH 225/420] Update test --- .../java/duke/core/TypoCorrectorTest.java | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/test/java/duke/core/TypoCorrectorTest.java b/src/test/java/duke/core/TypoCorrectorTest.java index 64d09ee809..cf6c024475 100644 --- a/src/test/java/duke/core/TypoCorrectorTest.java +++ b/src/test/java/duke/core/TypoCorrectorTest.java @@ -17,24 +17,28 @@ public class TypoCorrectorTest { @Test void stringMatchTest() { ArrayList testCases = new ArrayList( - Arrays.asList(new String[]{"beyee", "bye"}, - new String[]{"bqe", "bye"}, - new String[]{"lsit patant", "list patients"}, - new String[]{"lsfvs takss", "list tasks"}, - new String[]{"deelte Ptients:#12", "delete patient :#12"}, + Arrays.asList( + new String[]{"b q e", "bye"}, + new String[]{"d uke ", "duke"}, + new String[]{"dbKe", "duke"}, + new String[]{"l si t patant", "list patients"}, + new String[]{"lsf vs ta kss", "list tasks"}, + new String[]{"DEe lte Pti ents:#12", "delete patient :#12"}, new String[]{"deleot tasksa :task description", "delete task :task description"}, - new String[]{"delette tasks :#1", "delete task :#1"}, + new String[]{"delette tasks:#1", "delete task :#1"}, new String[]{"addd patents:name :nric :room :remark", "add patient :name :nric :room :remark"}, new String[]{"dad tsak:a very long task name", "add task :a very long task name"}, new String[]{"addd task :abc", "add task :abc"}, new String[]{"asgn deadli task: #1 :12 :12/12/2019 1645", "assign deadline task : #1 :12 :12/12/2019 1645"}, - new String[]{"assgn even tk :#1 :12 :12/12/2019 1645 :12/12/2020 1645", - "assign event task :#1 :12 :12/12/2019 1645 :12/12/2020 1645"} + new String[]{"asSGn even tk :#1 :12 :12/12/2019 1645 :12/12/2020 1645", + "assign event task :#1 :12 :12/12/2019 1645 :12/12/2020 1645"}, + new String[]{"fi n d p atin t: #1", "find patient : #1"}, + new String[]{"u p da te pa i t en s :#12:Room:2A", "update patient :#12:Room:2A"} )); for (String[] testPair : testCases) { String correctedOutput = TypoCorrector.commandCorrection(testPair[0]); - System.out.println("Input Command: " + testPair[0]); - System.out.println("Expected Command: " + testPair[1]); + System.out.println("Input Command: " + testPair[0]); + System.out.println("Expected Command: " + testPair[1]); System.out.println("Corrected Command: " + correctedOutput); System.out.println(); assertEquals(testPair[1], correctedOutput); From a2dec32995de656c17e75eca2d81ae18bb08ca90 Mon Sep 17 00:00:00 2001 From: lmtaek Date: Wed, 23 Oct 2019 20:49:57 +0800 Subject: [PATCH 226/420] More alterations based on group feedback, changed 'patient task' commands to 'assigned task' commands for sake of clarity. Fixed typos in exception methods. --- src/main/java/duke/core/CommandManager.java | 2 +- src/main/java/duke/core/Parser.java | 24 ++++++++++----------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index b576755bae..068317a7d6 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -64,7 +64,7 @@ public static Command manageCommand(String userInput) throws DukeException { case "find patient": return new FindPatientCommand((parser.parseFindPatient())); case "find assigned task": - return new FindPatientTaskCommand((parser.parseFindAssignedTask())); + return new FindPatientTaskCommand((parser.parseFindAssignedTasks())); case "update patient": return new UpdatePatientCommand(parser.parseUpdatePatient()); case "update task": diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index 10e8aa225a..6e98d20da4 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -143,11 +143,11 @@ public String parseDeleteTask() throws DukeException { } /** - * Takes user input and formats it so it is compatible with 'delete patient task' command. - * `delete patient task` output: patient_name or #patient_id, task_name or #task_id - * `delete patient task` output: assigned_task_unique_id + * Takes user input and formats it so it is compatible with 'delete assigned task' command. + * `delete assigned task` output: patient_name or #patient_id, task_name or #task_id + * `delete assigned task` output: assigned_task_unique_id * - * @return Array of strings to be used by 'delete patient task' command. + * @return Array of strings to be used by 'delete assigned task' command. * @throws DukeException when user input cannot be parsed properly. */ public String[] parseDeleteAssignedTask() throws DukeException { @@ -164,7 +164,7 @@ public String[] parseDeleteAssignedTask() throws DukeException { return formattedInput; } } catch (Exception e) { - throw new DukeException("Please follow the `delete patient task : or #" + throw new DukeException("Please follow the `delete assigned task : or #" + " : or #` or " + " `delete patient task :%` format."); } @@ -187,7 +187,7 @@ public String[] parseUpdatePatient() throws DukeException { return formattedInput; } catch (Exception e) { throw new DukeException("Please use the `update patient : or #" - + "/ :` format."); + + ": :` format."); } } @@ -206,7 +206,7 @@ public String[] parseUpdateTask() throws DukeException { } return formattedInput; } catch (Exception e) { - throw new DukeException("Please use the `update patient : or #" + throw new DukeException("Please use the `update task : or #" + " :` format."); } } @@ -228,18 +228,18 @@ public String parseFindPatient() throws DukeException { } /** - * Takes the user input and formats it so it is compatible with 'find patient task' command. - * `find patient tasks` output: patient_name or #patient_id + * Takes the user input and formats it so it is compatible with 'find assigned tasks' command. + * `find assigned tasks` output: patient_name or #patient_id * - * @return A string of formatted output to be used by 'find patient task' command. + * @return A string of formatted output to be used by 'find assigned tasks' command. * @throws DukeException Thrown when the user input cannot be parsed in the desired manner. */ - public String parseFindAssignedTask() throws DukeException { + public String parseFindAssignedTasks() throws DukeException { try { String formattedInput = parsedInput[1].trim(); return formattedInput; } catch (Exception e) { - throw new DukeException("Please use the `find assigned task : or #` format."); + throw new DukeException("Please use the `find assigned tasks : or #` format."); } } } \ No newline at end of file From 97c2d4d2eeb05095091ddd327dcb0782a64f9ea6 Mon Sep 17 00:00:00 2001 From: lmtaek Date: Wed, 23 Oct 2019 20:52:38 +0800 Subject: [PATCH 227/420] Forgot one tiny letter in command that was necessary for functionality--sorry for all the commits. --- src/main/java/duke/core/CommandManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 068317a7d6..be6623a3e8 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -63,7 +63,7 @@ public static Command manageCommand(String userInput) throws DukeException { return new DeleteTaskCommand(parser.parseDeleteTask()); case "find patient": return new FindPatientCommand((parser.parseFindPatient())); - case "find assigned task": + case "find assigned tasks": return new FindPatientTaskCommand((parser.parseFindAssignedTasks())); case "update patient": return new UpdatePatientCommand(parser.parseUpdatePatient()); From 4584fcee20732c88fee16983515099b8e504d57b Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Wed, 23 Oct 2019 20:52:49 +0800 Subject: [PATCH 228/420] Fixed checkstyle --- src/main/java/duke/core/TypoCorrector.java | 2 +- src/test/java/duke/core/TypoCorrectorTest.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/duke/core/TypoCorrector.java b/src/main/java/duke/core/TypoCorrector.java index 0af685c533..c093dba095 100644 --- a/src/main/java/duke/core/TypoCorrector.java +++ b/src/main/java/duke/core/TypoCorrector.java @@ -19,7 +19,7 @@ public class TypoCorrector { private static final String[] simpleCommands = {"bye", "duke", "help", "list patients", "list tasks"}; private static final String[] otherCommands = {"update patient", "update task", "delete patient", "delete task", "delete assigned task", "add task", "add patient", "find patient", "find task", - "find patient tasks", "assign deadline task", "assign event task"}; + "find assigned task", "assign deadline task", "assign event task"}; /** * This method take in an user input command with typo and return a possible matches diff --git a/src/test/java/duke/core/TypoCorrectorTest.java b/src/test/java/duke/core/TypoCorrectorTest.java index cf6c024475..9f08eb7750 100644 --- a/src/test/java/duke/core/TypoCorrectorTest.java +++ b/src/test/java/duke/core/TypoCorrectorTest.java @@ -29,7 +29,8 @@ void stringMatchTest() { new String[]{"addd patents:name :nric :room :remark", "add patient :name :nric :room :remark"}, new String[]{"dad tsak:a very long task name", "add task :a very long task name"}, new String[]{"addd task :abc", "add task :abc"}, - new String[]{"asgn deadli task: #1 :12 :12/12/2019 1645", "assign deadline task : #1 :12 :12/12/2019 1645"}, + new String[]{"asgn deadli task: #1 :12 :12/12/2019 1645", + "assign deadline task : #1 :12 :12/12/2019 1645"}, new String[]{"asSGn even tk :#1 :12 :12/12/2019 1645 :12/12/2020 1645", "assign event task :#1 :12 :12/12/2019 1645 :12/12/2020 1645"}, new String[]{"fi n d p atin t: #1", "find patient : #1"}, From db40d0a1a90053fcf11803b3fd33dba007d3ae20 Mon Sep 17 00:00:00 2001 From: WEIFENG-NUSCEG Date: Wed, 23 Oct 2019 21:03:17 +0800 Subject: [PATCH 229/420] resolved the conflict with the parser class --- src/main/java/duke/command/DeletePatientCommand.java | 6 +++--- .../java/duke/command/DeletePatientTaskCommand.java | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/java/duke/command/DeletePatientCommand.java b/src/main/java/duke/command/DeletePatientCommand.java index 58e8cf85f1..44b8c471e6 100644 --- a/src/main/java/duke/command/DeletePatientCommand.java +++ b/src/main/java/duke/command/DeletePatientCommand.java @@ -93,13 +93,13 @@ public void execute(PatientTaskList patientTaskList, TaskManager taskManager, Pa try { ArrayList patientTask = patientTaskList.getPatientTask(patientToBeDeleted.getID()); ArrayList tempTask = new ArrayList<>(); - for (PatientTask temppatientTask : patientTask) { - tempTask.add(taskManager.getTask(temppatientTask.getTaskID())); + for (PatientTask tempPatientTask : patientTask) { + tempTask.add(taskManager.getTask(tempPatientTask.getTaskID())); } ui.patientTaskFound(patientToBeDeleted, patientTask, tempTask); toDelete = ui.confirmPatientToBeDeleted(patientToBeDeleted, true); if (toDelete) { - patientTaskList.deleteEntirePatientTask(patientToBeDeleted.getID()); + patientTaskList.deleteAllTasksBelongToThePatient(patientToBeDeleted.getID()); storageManager.saveAssignedTasks(patientTaskList.fullPatientTaskList()); } } catch (Exception e) { diff --git a/src/main/java/duke/command/DeletePatientTaskCommand.java b/src/main/java/duke/command/DeletePatientTaskCommand.java index 30cce26a06..151117b241 100644 --- a/src/main/java/duke/command/DeletePatientTaskCommand.java +++ b/src/main/java/duke/command/DeletePatientTaskCommand.java @@ -23,16 +23,16 @@ public class DeletePatientTaskCommand extends Command { * @param deleteInfo . * @throws DukeException . */ - public DeletePatientTaskCommand(String deleteInfo) throws DukeException { + public DeletePatientTaskCommand(String[] deleteInfo) throws DukeException { - char firstChar = deleteInfo.charAt(0); + char firstChar = deleteInfo[0].charAt(0); try { if (firstChar == '#') { - this.patientId = Integer.parseInt(deleteInfo.substring(1)); + this.patientId = Integer.parseInt(deleteInfo[0].substring(1)); } else if (firstChar == '%') { - this.taskId = Integer.parseInt(deleteInfo.substring(1)); + this.taskId = Integer.parseInt(deleteInfo[0].substring(1)); } else { - this.deletedPatientInfo = deleteInfo; + this.deletedPatientInfo = deleteInfo[0]; } } catch (Exception e) { throw new DukeException("Try to follow the format: delete patienttask %/#/" From f48c7960ce1a4a91d741b7ff382dab3a698fa90e Mon Sep 17 00:00:00 2001 From: Kejun Liu Date: Wed, 23 Oct 2019 21:07:23 +0800 Subject: [PATCH 230/420] Fix the bug cannot update patient and task after the implementation of new parser class. --- .../duke/command/UpdatePatientCommand.java | 23 ++++++++++--------- .../java/duke/command/UpdateTaskCommand.java | 13 ++++++----- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/main/java/duke/command/UpdatePatientCommand.java b/src/main/java/duke/command/UpdatePatientCommand.java index 74290bce37..041241099c 100644 --- a/src/main/java/duke/command/UpdatePatientCommand.java +++ b/src/main/java/duke/command/UpdatePatientCommand.java @@ -1,3 +1,5 @@ +//@@kkeejjuunn + package duke.command; import duke.core.DukeException; @@ -34,19 +36,18 @@ public UpdatePatientCommand(String[] command) { @Override public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientManager, Ui ui, StorageManager storageManager) throws DukeException { - String[] tempCommand = command[0].split(" ", 3); //changed temporarily to allow build success - char firstChar = tempCommand[0].charAt(0); + char firstChar = command[0].charAt(0); if (firstChar == '#') { int id; try { - id = Integer.parseInt(tempCommand[0].substring(1, tempCommand[0].length())); + id = Integer.parseInt(command[0].substring(1)); Patient patientToBeUpdated = patientManager.getPatient(id); - if (tempCommand[1].toLowerCase().equals("name")) { - patientToBeUpdated.setName(tempCommand[2]); - } else if (tempCommand[1].toLowerCase().equals("nric")) { - patientToBeUpdated.setNric(tempCommand[2]); - } else if (tempCommand[1].toLowerCase().equals("room")) { - patientToBeUpdated.setRoom(tempCommand[2]); + if (command[1].toLowerCase().equals("name")) { + patientToBeUpdated.setName(command[2]); + } else if (command[1].toLowerCase().equals("nric")) { + patientToBeUpdated.setNric(command[2]); + } else if (command[1].toLowerCase().equals("room")) { + patientToBeUpdated.setRoom(command[2]); } else { throw new DukeException("You can only update 'Name', 'NRIC', or 'Room' of the patient"); } @@ -56,11 +57,11 @@ public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManag ui.showPatientInfo(patientToBeUpdated); } catch (Exception e) { throw new DukeException( - "Please follow the format 'update patient # '."); + "Please follow the format 'update patient :# : :'."); } } else { throw new DukeException( - "Please follow the format 'update patient # '."); + "Please follow the format 'update patient :# : :'."); } } diff --git a/src/main/java/duke/command/UpdateTaskCommand.java b/src/main/java/duke/command/UpdateTaskCommand.java index 632f05801d..44ab337d21 100644 --- a/src/main/java/duke/command/UpdateTaskCommand.java +++ b/src/main/java/duke/command/UpdateTaskCommand.java @@ -1,3 +1,5 @@ +//@@kkeejjuunn + package duke.command; import duke.core.DukeException; @@ -33,15 +35,14 @@ public UpdateTaskCommand(String[] command) { @Override public void execute(PatientTaskList patientTask, TaskManager taskManager, PatientManager patientManager, Ui ui, StorageManager storageManager) throws DukeException { - String[] tempCommand = command[0].split(" ", 3); //changed temporarily to allow build success - char firstChar = tempCommand[0].charAt(0); + char firstChar = command[0].charAt(0); if (firstChar == '#') { int id; try { - id = Integer.parseInt(tempCommand[0].substring(1, tempCommand[0].length())); + id = Integer.parseInt(command[0].substring(1, command[0].length())); Task taskToBeUpdated = taskManager.getTask(id); - if (tempCommand[1].toLowerCase().equals("description")) { - taskToBeUpdated.setDescription(tempCommand[2]); + if (command[1].toLowerCase().equals("description")) { + taskToBeUpdated.setDescription(command[2]); } else { throw new DukeException("You can only update 'Description' of the task"); } @@ -51,7 +52,7 @@ public void execute(PatientTaskList patientTask, TaskManager taskManager, Patien ui.showTaskInfo(taskToBeUpdated); } catch (Exception e) { throw new DukeException( - "Please follow the format 'update task # description '."); + "Please follow the format 'update task :# :description :'."); } } From cf3670ff6e4f3baa8cf363952aabd2d55c9053c7 Mon Sep 17 00:00:00 2001 From: WEIFENG-NUSCEG Date: Wed, 23 Oct 2019 21:10:02 +0800 Subject: [PATCH 231/420] revert commit for csv --- data/patientsTasks.csv | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/data/patientsTasks.csv b/data/patientsTasks.csv index 66a0c9b77d..55f988bae9 100644 --- a/data/patientsTasks.csv +++ b/data/patientsTasks.csv @@ -11,5 +11,4 @@ PID,TID,DONE,RECURRENCE,DEADLINE,STARTTIME,ENDTIME,TASKTYPE,uuid 2,7,false,false,,09/11/2018 1400,08/08/2019 1200,E,11 2,7,false,false,,08/08/2018 1400,09/09/2019 1200,E,12 2,7,false,false,,09/08/2019 1200,09/12/2019 1200,E,13 -3,8,false,false,09/01/2022 1400,,,S,14 -3,5,false,false,,05/11/2019 1200,05/04/2022 1200,E,15 \ No newline at end of file +3,8,false,false,09/01/2022 1400,,,S,14 \ No newline at end of file From c8c10b12501cd6c49c600be2fb83eb7a2dbc1e94 Mon Sep 17 00:00:00 2001 From: WEIFENG-NUSCEG Date: Wed, 23 Oct 2019 21:12:22 +0800 Subject: [PATCH 232/420] merge csv conflict --- data/patientsTasks.csv | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/data/patientsTasks.csv b/data/patientsTasks.csv index 55f988bae9..6a79f9c95a 100644 --- a/data/patientsTasks.csv +++ b/data/patientsTasks.csv @@ -11,4 +11,5 @@ PID,TID,DONE,RECURRENCE,DEADLINE,STARTTIME,ENDTIME,TASKTYPE,uuid 2,7,false,false,,09/11/2018 1400,08/08/2019 1200,E,11 2,7,false,false,,08/08/2018 1400,09/09/2019 1200,E,12 2,7,false,false,,09/08/2019 1200,09/12/2019 1200,E,13 -3,8,false,false,09/01/2022 1400,,,S,14 \ No newline at end of file +3,8,false,false,09/01/2022 1400,,,S,14 +3,5,false,false,,05/11/2019 1200,05/04/2022 1200,E,15 From d6eddbb9f03f58ece19cbf9729a3640ccfffd597 Mon Sep 17 00:00:00 2001 From: WEIFENG-NUSCEG Date: Wed, 23 Oct 2019 21:42:34 +0800 Subject: [PATCH 233/420] travis stuck --- src/main/java/duke/command/DeletePatientTaskCommand.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/duke/command/DeletePatientTaskCommand.java b/src/main/java/duke/command/DeletePatientTaskCommand.java index 151117b241..aab8fc1a09 100644 --- a/src/main/java/duke/command/DeletePatientTaskCommand.java +++ b/src/main/java/duke/command/DeletePatientTaskCommand.java @@ -77,8 +77,8 @@ public void execute(PatientTaskList patientTaskList, TaskManager tasks, PatientM } } else { try { - String patientName = this.deletedPatientInfo; - ArrayList patientsWithSameName = patientManager.getPatientByName(patientName); + String deletePatientName = this.deletedPatientInfo; + ArrayList patientsWithSameName = patientManager.getPatientByName(deletePatientName); int tempPatientId = patientsWithSameName.get(0).getID(); if (patientTaskList.doesPatientIdExist(tempPatientId)) { patientTaskList.deleteAllTasksBelongToThePatient(tempPatientId); From fb04d35376dc5a01f245e6a06f6c155b159e0904 Mon Sep 17 00:00:00 2001 From: lmtaek Date: Wed, 23 Oct 2019 22:38:02 +0800 Subject: [PATCH 234/420] Altered parseDeleteAssignedTask() based on feedback from group members + their needs in implementing their command classes. --- src/main/java/duke/core/Parser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index 6e98d20da4..00bb39ea2e 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -154,7 +154,7 @@ public String[] parseDeleteAssignedTask() throws DukeException { try { String[] formattedInput = new String[2]; - if (parsedInput[1].trim().charAt(0) == '%') { + if (parsedInput.length <= 2) { formattedInput[0] = parsedInput[1]; return formattedInput; } else { From 1245a66cc4dfb8d1d9d48c97d1154e24b12a6043 Mon Sep 17 00:00:00 2001 From: lmtaek Date: Wed, 23 Oct 2019 22:57:34 +0800 Subject: [PATCH 235/420] Created ParserTest tests for remaining methods in Parser that were previously uncovered. --- src/test/java/duke/core/ParserTest.java | 62 +++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/src/test/java/duke/core/ParserTest.java b/src/test/java/duke/core/ParserTest.java index 59f1c73667..78d17dc82c 100644 --- a/src/test/java/duke/core/ParserTest.java +++ b/src/test/java/duke/core/ParserTest.java @@ -22,6 +22,13 @@ public class ParserTest { String deleteAssignedTaskInputWithName = "delete assigned task :patient name :task name"; String deleteAssignedTaskInputWithUniqueID = "delete assigned task :%3"; + String updatePatientInput = "update patient :name :field :new data"; + String updateTaskInput = "update task :task name :new description"; + + String findPatientInputWithName = "find patient :name"; + String findPatientInputWithID = "find patient :#200"; + String findAssignedTasksInput = "find patient tasks :jane doe"; + @Test public void parseAddPatientTest() throws DukeException { Parser testParser = new Parser(patientDummyInput); @@ -125,4 +132,59 @@ public void parseDeleteAssignedTask() throws DukeException { } + @Test + public void parseUpdatePatientTest() throws DukeException { + Parser testParser = new Parser(updatePatientInput); + String[] testOutput = testParser.parseUpdatePatient(); + String[] desiredOutput = {"name", "field", "new data"}; + + assertTrue(desiredOutput.length == testOutput.length); + for (int i = 0; i < desiredOutput.length; i++) { + assertTrue(desiredOutput[i].equals(testOutput[i]), "Parsing failed. Expected: " + + desiredOutput[i] + " but got: " + testOutput[i]); + } + + } + + @Test + public void parseUpdateTaskTest() throws DukeException { + Parser testParser = new Parser(updateTaskInput); + String[] testOutput = testParser.parseUpdateTask(); + String[] desiredOutput = {"task name", "new description"}; + + assertTrue(desiredOutput.length == testOutput.length); + for (int i = 0; i < desiredOutput.length; i++) { + assertTrue(desiredOutput[i].equals(testOutput[i]), "Parsing failed. Expected: " + + desiredOutput[i] + " but got: " + testOutput[i]); + } + } + + @Test + public void parseFindPatientTest() throws DukeException { + Parser testParserID = new Parser(findPatientInputWithID); + String testOutputID = testParserID.parseFindPatient(); + String desiredOutputID = "#200"; + + assertTrue(desiredOutputID.equals(testOutputID), "Parsing failed. Expected: " + + desiredOutputID + " but got: " + testOutputID); + + Parser testParserName = new Parser(findPatientInputWithName); + String testOutputName = testParserName.parseFindPatient(); + String desiredOutputName = "name"; + + assertTrue(desiredOutputName.equals(testOutputName), "Parsing failed. Expected: " + + desiredOutputName + " but got: " + testOutputName); + + } + + @Test + public void parseFindAssignedTasksTest() throws DukeException { + Parser testParser = new Parser(findAssignedTasksInput); + String testOutput = testParser.parseFindAssignedTasks(); + String desiredOutput = "jane doe"; + + assertTrue(desiredOutput.equals(testOutput), "Parsing failed. Expected: " + + desiredOutput + " but got: " + testOutput); + } + } \ No newline at end of file From 8e14c9418bc2b5690755d6d7cadba96dc7399fa0 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Wed, 23 Oct 2019 23:41:53 +0800 Subject: [PATCH 236/420] Update typo corrector --- src/main/java/duke/core/TypoCorrector.java | 16 +++++++++------- src/test/java/duke/core/TypoCorrectorTest.java | 4 +++- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/main/java/duke/core/TypoCorrector.java b/src/main/java/duke/core/TypoCorrector.java index c093dba095..891deda457 100644 --- a/src/main/java/duke/core/TypoCorrector.java +++ b/src/main/java/duke/core/TypoCorrector.java @@ -29,24 +29,26 @@ public class TypoCorrector { * @return a string of correctedCommand */ public static String commandCorrection(String command) { - String[] splitCommand = command.split(":"); + String[] splitCommand = command.split(":", 2); int commandSize = splitCommand.length; String closestMatch; if (commandSize == 1) { - String fullCommand = command.trim().toLowerCase(); - closestMatch = matchStringFromDict(fullCommand, simpleCommands); + // Type A command with only command keywords + String fullCommand = command.trim().toLowerCase();//Ignore spaces(back and fore)and upper/lower cases + closestMatch = matchStringFromDict(fullCommand, simpleCommands); //get closest match if (isSimilar(fullCommand, closestMatch)) { return closestMatch; } - } else { - String keyword = splitCommand[0].trim().toLowerCase(); - closestMatch = matchStringFromDict(keyword, otherCommands); + } else if (commandSize == 2){ + // Type B command with command keywords and other info/data + String keyword = splitCommand[0].trim().toLowerCase(); //Ignore spaces(back and fore)and upper/lower cases + closestMatch = matchStringFromDict(keyword, otherCommands); //get closest match if (isSimilar(keyword, closestMatch)) { splitCommand[0] = ""; return closestMatch + " " + String.join(":", splitCommand).trim(); } } - return command; + return command; // The input command will be return if there is no matched found } /** diff --git a/src/test/java/duke/core/TypoCorrectorTest.java b/src/test/java/duke/core/TypoCorrectorTest.java index 9f08eb7750..a09cbcb374 100644 --- a/src/test/java/duke/core/TypoCorrectorTest.java +++ b/src/test/java/duke/core/TypoCorrectorTest.java @@ -34,7 +34,9 @@ void stringMatchTest() { new String[]{"asSGn even tk :#1 :12 :12/12/2019 1645 :12/12/2020 1645", "assign event task :#1 :12 :12/12/2019 1645 :12/12/2020 1645"}, new String[]{"fi n d p atin t: #1", "find patient : #1"}, - new String[]{"u p da te pa i t en s :#12:Room:2A", "update patient :#12:Room:2A"} + new String[]{"u p da te pa i t en s :#12:Room:2A", "update patient :#12:Room:2A"}, + new String[]{"", ""}, + new String[]{" ", " "} )); for (String[] testPair : testCases) { String correctedOutput = TypoCorrector.commandCorrection(testPair[0]); From c1c980258dbc40535f248126898003a8afe9a440 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Wed, 23 Oct 2019 23:43:15 +0800 Subject: [PATCH 237/420] Update checkstyle --- src/main/java/duke/core/TypoCorrector.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/duke/core/TypoCorrector.java b/src/main/java/duke/core/TypoCorrector.java index 891deda457..a08b44f69f 100644 --- a/src/main/java/duke/core/TypoCorrector.java +++ b/src/main/java/duke/core/TypoCorrector.java @@ -39,7 +39,7 @@ public static String commandCorrection(String command) { if (isSimilar(fullCommand, closestMatch)) { return closestMatch; } - } else if (commandSize == 2){ + } else if (commandSize == 2) { // Type B command with command keywords and other info/data String keyword = splitCommand[0].trim().toLowerCase(); //Ignore spaces(back and fore)and upper/lower cases closestMatch = matchStringFromDict(keyword, otherCommands); //get closest match From 27e6a7bd7eaa5861f73f017388761419519ccc4a Mon Sep 17 00:00:00 2001 From: Kejun Liu Date: Thu, 24 Oct 2019 03:01:17 +0800 Subject: [PATCH 238/420] Prompts user if the task is assigned to any patients and alerts user that the deletion will cause the task no longer assigned to these patients. --- .../java/duke/command/DeleteTaskCommand.java | 120 ++++++++++++------ src/main/java/duke/core/Ui.java | 48 +++++-- 2 files changed, 124 insertions(+), 44 deletions(-) diff --git a/src/main/java/duke/command/DeleteTaskCommand.java b/src/main/java/duke/command/DeleteTaskCommand.java index 8234c678bc..edcbbc6387 100644 --- a/src/main/java/duke/command/DeleteTaskCommand.java +++ b/src/main/java/duke/command/DeleteTaskCommand.java @@ -1,8 +1,12 @@ +//@@author kkeejjuunn + package duke.command; import duke.core.DukeException; import duke.core.Ui; +import duke.patient.Patient; import duke.patient.PatientManager; +import duke.relation.PatientTask; import duke.relation.PatientTaskList; import duke.storage.StorageManager; import duke.task.Task; @@ -11,68 +15,112 @@ import java.util.ArrayList; public class DeleteTaskCommand extends Command { - private int id; private String deletedTaskInfo; + private Task taskToBeDeleted; /** - * . + * It keeps the delete task command. * - * @param deletedTaskInfo . - * @throws DukeException . + * @param deletedTaskInfo contains the information of the patient to be deleted. */ - public DeleteTaskCommand(String deletedTaskInfo) throws DukeException { - + public DeleteTaskCommand(String deletedTaskInfo) { this.deletedTaskInfo = deletedTaskInfo; + } + + /** + * It extracts the task id from the delete task command. + * It checks whether user is trying to delete a task by id or description. + * It retrieves task based on the id extracted. + * + * @param deletedTaskInfo contains the delete command received from parser class which is a string. + * @param ui allow user choose the correct task to be deleted. + * @param taskManager retrieves the task to be deleted. + * @return the task to be deleted. + * @throws DukeException if no match task found. + */ + public Task getTaskByDeleteTaskCommand(String deletedTaskInfo, Ui ui, + TaskManager taskManager) throws DukeException { char firstChar = deletedTaskInfo.charAt(0); + Task task = null; if (firstChar == '#') { + int id; + try { + id = Integer.parseInt(deletedTaskInfo.substring(1)); + } catch (Exception e) { + throw e; + } try { - this.id = Integer.parseInt(deletedTaskInfo.substring(1)); + task = taskManager.getTask(id); } catch (Exception e) { - throw new DukeException("Please follow format 'delete task #'. "); + throw new DukeException("The task id does not exist. "); + } + } else { + ArrayList tasksWithSameDescription = taskManager.getTaskByDescription(deletedTaskInfo); + if (tasksWithSameDescription.size() >= 1) { + int numberChosen = ui.chooseTaskToDelete(tasksWithSameDescription.size()); + if (numberChosen >= 1) { + task = tasksWithSameDescription.get(numberChosen - 1); + } + } else { + throw new DukeException("There is no task matched this description. "); } } + return task; } /** - * . + * It deletes the task returned from getTaskByDeleteTaskCommand. + * It checks whether this task is assigned to any patient. + * It deletes the relation between this task and any patients * - * @param patientTask . - * @param taskManager . - * @param patientManager . - * @param ui . - * @param storageManager . - * @throws DukeException . + * @param patientTaskList contains the information between all the tasks and patients. + * @param taskManager contains information of all tasks. + * @param patientManager contains information of all patients. + * @param ui interacts with user. + * @param storageManager save the changes in csv file. + * @throws DukeException if there is error deleting the task. */ @Override - public void execute(PatientTaskList patientTask, TaskManager taskManager, PatientManager patientManager, + public void execute(PatientTaskList patientTaskList, TaskManager taskManager, PatientManager patientManager, Ui ui, StorageManager storageManager) throws DukeException { - if (id != 0) { - Task taskToBeDeleted = taskManager.getTask(id); - boolean toDelete = ui.confirmTaskToBeDeleted(taskToBeDeleted); - if (toDelete) { - taskManager.deleteTask(id); - ui.taskDeleted(); - storageManager.saveTasks(taskManager.getTaskList()); + try { + taskToBeDeleted = getTaskByDeleteTaskCommand(deletedTaskInfo, ui, taskManager); + } catch (Exception e) { + throw e; + } + ui.showTaskInfo(taskToBeDeleted); + boolean toDelete; + try { + ArrayList patientTasks = patientTaskList.getTaskPatient(taskToBeDeleted.getID()); + ArrayList relatedPatients = new ArrayList<>(); + for (PatientTask patientTask : patientTasks) { + relatedPatients.add(patientManager.getPatient(patientTask.getPatientId())); } - } else { - ArrayList tasksWithSameDescription = taskManager.getTaskByDescription(deletedTaskInfo); - ui.tasksFoundByDescription(tasksWithSameDescription, deletedTaskInfo); - if (tasksWithSameDescription.size() >= 1) { - int numberChosen = ui.chooseTaskToDelete(tasksWithSameDescription.size()); - if (numberChosen >= 1) { - boolean toDelete = ui.confirmTaskToBeDeleted(tasksWithSameDescription.get(numberChosen - 1)); - if (toDelete) { - taskManager.deleteTask(tasksWithSameDescription.get(numberChosen - 1).getID()); - ui.taskDeleted(); - storageManager.saveTasks(taskManager.getTaskList()); - } - } + ui.taskPatientFound(taskToBeDeleted, patientTasks, relatedPatients); + toDelete = ui.confirmTaskToBeDeleted(taskToBeDeleted, true); + if (toDelete) { + patientTaskList.deleteAllPatientTaskByTaskId(taskToBeDeleted.getID()); + storageManager.saveAssignedTasks(patientTaskList.fullPatientTaskList()); } + } catch (Exception e) { + toDelete = ui.confirmTaskToBeDeleted(taskToBeDeleted,false); + } + if (toDelete) { + taskManager.deleteTask(taskToBeDeleted.getID()); + storageManager.saveTasks(taskManager.getTaskList()); + ui.taskDeleted(); } } + /** + * It terminates the Dukepital. + * + * @return false. + */ @Override public boolean isExit() { return false; } } + + diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index 8416920536..1272647bda 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -206,16 +206,17 @@ public int choosePatientToDelete(int numberOfPatients) { } } + //@@author kkeejjuunn /** * It asks user to choose a task to be deleted from a list of tasks. * * @param numberOfTasks the number of task contain in the list - * @return the number being choosen by user. If return -1, it means user canceled the deletion + * @return the index being chosen by user. If return -1, it means user canceled the deletion */ public int chooseTaskToDelete(int numberOfTasks) { int chosenNumber = -1; while (true) { - System.out.println("Enter the number of task to delete, or enter number 0 to cancel: "); + System.out.println("Enter the index of task to delete, or enter number 0 to cancel: "); String command = readCommand(); try { chosenNumber = Integer.parseInt(command); @@ -232,9 +233,9 @@ public int chooseTaskToDelete(int numberOfTasks) { System.out.println("The task #" + chosenNumber + " does not exist. Please enter a valid number!"); } } - } + /** * It confirms with user on the deletion of a patient. * It reminds user that the tasks assigned to this user will be delete @@ -270,13 +271,15 @@ public void patientDeleted() { System.out.println("Got it. The patient is deleted."); } + //@@author kkeejjuunn /** - * It shows message of a task being deleted. + * It shows message of a task being deleted successfully. */ public void taskDeleted() { System.out.println("Got it. The task is deleted."); } + /** * It lists out all info of patients. * @@ -329,17 +332,25 @@ public void listAllTasks(ArrayList taskList) { } } + //@@author kkeejjuunn /** * It confirms with user on the deletion of a task. + * It alerts user that the deletion will cause the current patient who assigned + * to this task will no longer assigned to this task. * If user confirms, key in 'Y'. Otherwise key in 'N'. * - * @param task it contains task's info + * @param task contains task's info + * @param assignedToAnyPatient indicates whether the task is assigned to any patient * @return true if user confirmed the deletion. False otherwise. */ - public boolean confirmTaskToBeDeleted(Task task) { - showTaskInfo(task); + public boolean confirmTaskToBeDeleted(Task task, boolean assignedToAnyPatient) { while (true) { - System.out.println("The task is to be deleted. Are you sure (Y/N)? "); + if (assignedToAnyPatient) { + System.out.println("The task is to be deleted. These patients will no " + + "longer assigned to this task. Are you sure (Y/N)?"); + } else { + System.out.println("The task is to be deleted. Are you sure (Y/N)? "); + } String command = readCommand(); if (command.toLowerCase().equals("y")) { return true; @@ -352,6 +363,7 @@ public boolean confirmTaskToBeDeleted(Task task) { } } + /** * It confirms with user on the deletion of a task. * If user confirms, key in 'Y'. Otherwise key in 'N'. @@ -444,6 +456,26 @@ public void patientTaskFound(Patient patient, ArrayList patientTask showLine(); } } + + //@@author kkeejjuunn + /** + * It shows all info of patientTasks found which are associated with the task given by user. + * + * @param task task given by user + * @param patientTask list of patienttasks being found associated with the task + * @param patients list of patients relate to task + */ + public void taskPatientFound(Task task, ArrayList patientTask, ArrayList patients) { + System.out.println("The task " + task.getID() + " " + task.getDescription() + + " assigned to following patient(s) is/are found : \n"); + for (int i = 0; i < patientTask.size(); i++) { + showLine(); + System.out.println(patients.get(i).getID() + ". " + patients.get(i).getName() + "\n"); + System.out.println(patientTask.get(i).toString()); + showLine(); + } + } + //@@author qjie7 /** * Provide the necessary task details from the user for short cut feature. From a2e0a6abf80afde29b78952ab304d20f4dbca555 Mon Sep 17 00:00:00 2001 From: lmtaek Date: Thu, 24 Oct 2019 13:07:13 +0800 Subject: [PATCH 239/420] Fixing exception messages for accuracy. --- src/main/java/duke/core/Parser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/duke/core/Parser.java b/src/main/java/duke/core/Parser.java index 00bb39ea2e..7c1dec6721 100644 --- a/src/main/java/duke/core/Parser.java +++ b/src/main/java/duke/core/Parser.java @@ -78,7 +78,7 @@ public String[] parseAssignDeadlineTask() throws DukeException { return formattedInput; } catch (Exception e) { throw new DukeException("Please follow the " - + "`assign standard task : or # :# or " + + "`assign deadline task : or # :# or " + ":

` format."); } } From 257abf24c7e0dc955d90ac70edbdb5c435d2a90f Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Fri, 25 Oct 2019 01:01:35 +0800 Subject: [PATCH 240/420] Setup javafx --- build.gradle | 11 +++++++++-- src/main/java/Launcher.java | 11 +++++++++++ src/main/java/duke/Duke.java | 18 ++++++++++++++---- 3 files changed, 34 insertions(+), 6 deletions(-) create mode 100644 src/main/java/Launcher.java diff --git a/build.gradle b/build.gradle index 6118f77b38..7bad920e0f 100644 --- a/build.gradle +++ b/build.gradle @@ -3,6 +3,7 @@ plugins { id 'application' id 'checkstyle' id 'com.github.johnrengelman.shadow' version '5.1.0' + id 'org.openjfx.javafxplugin' version '0.0.7' } group 'duke' @@ -14,7 +15,7 @@ checkstyle { shadowJar { archiveBaseName = "mid" - archiveVersion = "v1.1" + archiveVersion = "v1.2.2" archiveClassifier = null archiveAppendix = null } @@ -30,13 +31,19 @@ test { useJUnitPlatform() } +javafx { + version = "11.0.2" + modules = [ 'javafx.controls', 'javafx.fxml' ] +} + repositories { mavenCentral() } application { // Change this to your main class. - mainClassName = "duke/Duke" +// mainClassName = "duke/Duke" + mainClassName = "duke/Launcher" } run { diff --git a/src/main/java/Launcher.java b/src/main/java/Launcher.java new file mode 100644 index 0000000000..04df820bf0 --- /dev/null +++ b/src/main/java/Launcher.java @@ -0,0 +1,11 @@ +import duke.Duke; +import javafx.application.Application; + +/** + * A launcher class to workaround classpath issues. + */ +public class Launcher { + public static void main(String[] args) { + Application.launch(Duke.class, args); + } +} \ No newline at end of file diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index a1f8608fdc..6514c40611 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -1,22 +1,23 @@ package duke; - import duke.command.Command; import duke.core.CommandManager; import duke.core.DukeException; -import duke.core.ShortCutter; import duke.core.Ui; import duke.patient.PatientManager; import duke.relation.PatientTaskList; import duke.statistic.Counter; import duke.storage.StorageManager; import duke.task.TaskManager; - +import javafx.application.Application; +import javafx.scene.Scene; +import javafx.scene.control.Label; +import javafx.stage.Stage; /** * Represents Duke, a Personal Assistant to help * users tracking their progress. */ -public class Duke { +public class Duke extends Application { /** * A Storage object that handles reading tasks from a local * file and saving them to the same file. @@ -59,6 +60,15 @@ public Duke(String filePath) { } } + @Override + public void start(Stage stage) { + Label helloWorld = new Label("Hello World!"); // Creating a new Label control + Scene scene = new Scene(helloWorld); // Setting the scene to be our Label + + stage.setScene(scene); // Setting the stage to show our screen + stage.show(); // Render the stage. + } + /** * Runs the Duke program. * Reads user input until a "bye" message is received. From 71c3c8179ebe3b771bff5131fd651608422ab66d Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Fri, 25 Oct 2019 01:37:52 +0800 Subject: [PATCH 241/420] Continue working on JavaFx tutorial --- src/main/java/duke/DialogBox.java | 24 +++ src/main/java/duke/Duke.java | 283 ++++++++++++++++++------- src/main/java/{ => duke}/Launcher.java | 2 + 3 files changed, 237 insertions(+), 72 deletions(-) create mode 100644 src/main/java/duke/DialogBox.java rename src/main/java/{ => duke}/Launcher.java (94%) diff --git a/src/main/java/duke/DialogBox.java b/src/main/java/duke/DialogBox.java new file mode 100644 index 0000000000..9b44938db6 --- /dev/null +++ b/src/main/java/duke/DialogBox.java @@ -0,0 +1,24 @@ +package duke; + +import javafx.geometry.Pos; +import javafx.scene.control.Label; +import javafx.scene.image.ImageView; +import javafx.scene.layout.HBox; + +public class DialogBox extends HBox { + + private Label text; + private ImageView displayPicture; + + public DialogBox(Label l, ImageView iv) { + text = l; + displayPicture = iv; + + text.setWrapText(true); + displayPicture.setFitWidth(100.0); + displayPicture.setFitHeight(100.0); + + this.setAlignment(Pos.TOP_RIGHT); + this.getChildren().addAll(text, displayPicture); + } +} \ No newline at end of file diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index 6514c40611..1f947c5e31 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -1,4 +1,5 @@ package duke; + import duke.command.Command; import duke.core.CommandManager; import duke.core.DukeException; @@ -10,99 +11,237 @@ import duke.task.TaskManager; import javafx.application.Application; import javafx.scene.Scene; +import javafx.scene.control.Button; import javafx.scene.control.Label; +import javafx.scene.control.ScrollPane; +import javafx.scene.control.TextField; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.Region; +import javafx.scene.layout.VBox; import javafx.stage.Stage; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; + /** * Represents Duke, a Personal Assistant to help * users tracking their progress. */ public class Duke extends Application { - /** - * A Storage object that handles reading tasks from a local - * file and saving them to the same file. - */ - private StorageManager storageManager; - /** - * A TaskList object that deals with add, delete, mark as done, - * find functions of a list of tasks. - */ - private PatientTaskList patientTaskList; - private TaskManager taskManager; - private PatientManager patientManager; - private Counter counter; + private ScrollPane scrollPane; + private VBox dialogContainer; + private TextField userInput; + private Button sendButton; + private Scene scene; + // ... + private Image user = new Image(this.getClass().getResourceAsStream("/images/DaUser.png")); + private Image duke = new Image(this.getClass().getResourceAsStream("/images/DaDuke.png")); + // ... - /** - * A Ui object that deals with interactions with the user. - */ - private static final Ui ui = Ui.getUi(); - - /** - * Constructs a Duke object with a relative file path. - * Initialize the user interface and reads tasks from the specific text file. - * - * @param filePath A string that represents the path of the local file - * used for storing tasks. - */ - public Duke(String filePath) { - storageManager = new StorageManager(filePath); - - try { - patientTaskList = new PatientTaskList(storageManager.loadAssignedTasks()); - taskManager = new TaskManager(storageManager.loadTasks()); - patientManager = new PatientManager(storageManager.loadPatients()); - counter = new Counter(storageManager.loadCommandFrequency()); - - } catch (DukeException e) { - ui.showLoadingError(); - System.out.println(e.getMessage()); - taskManager = new TaskManager(); - } + public static void main(String[] args) { + // ... } @Override public void start(Stage stage) { - Label helloWorld = new Label("Hello World!"); // Creating a new Label control - Scene scene = new Scene(helloWorld); // Setting the scene to be our Label + //Step 1. Setting up required components + + //The container for the content of the chat to scroll. + scrollPane = new ScrollPane(); + dialogContainer = new VBox(); + scrollPane.setContent(dialogContainer); + + userInput = new TextField(); + sendButton = new Button("Send"); + + AnchorPane mainLayout = new AnchorPane(); + mainLayout.getChildren().addAll(scrollPane, userInput, sendButton); + + scene = new Scene(mainLayout); + + stage.setScene(scene); + stage.show(); + + //Step 2. Formatting the window to look as expected + stage.setTitle("Duke"); + stage.setResizable(false); + stage.setMinHeight(600.0); + stage.setMinWidth(400.0); + + mainLayout.setPrefSize(400.0, 600.0); + + scrollPane.setPrefSize(385, 535); + scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER); + scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS); + + scrollPane.setVvalue(1.0); + scrollPane.setFitToWidth(true); + + // You will need to import `javafx.scene.layout.Region` for this. + dialogContainer.setPrefHeight(Region.USE_COMPUTED_SIZE); + + + userInput.setPrefWidth(325.0); + + sendButton.setPrefWidth(55.0); + + AnchorPane.setTopAnchor(scrollPane, 1.0); + + AnchorPane.setBottomAnchor(sendButton, 1.0); + AnchorPane.setRightAnchor(sendButton, 1.0); + + AnchorPane.setLeftAnchor(userInput , 1.0); + AnchorPane.setBottomAnchor(userInput, 1.0); + + //Step 3. Add functionality to handle user input. +// sendButton.setOnMouseClicked((event) -> { +// dialogContainer.getChildren().add(getDialogLabel(userInput.getText())); +// userInput.clear(); +// }); + +// userInput.setOnAction((event) -> { +// dialogContainer.getChildren().add(getDialogLabel(userInput.getText())); +// userInput.clear(); +// }); + + // more code to be added here later + + //Scroll down to the end every time dialogContainer's height changes. + dialogContainer.heightProperty().addListener((observable) -> scrollPane.setVvalue(1.0)); + + //Part 3. Add functionality to handle user input. + sendButton.setOnMouseClicked((event) -> { + handleUserInput(); + }); + + userInput.setOnAction((event) -> { + handleUserInput(); + }); + - stage.setScene(scene); // Setting the stage to show our screen - stage.show(); // Render the stage. } /** - * Runs the Duke program. - * Reads user input until a "bye" message is received. + * Iteration 1: + * Creates a label with the specified text and adds it to the dialog container. + * @param text String containing text to add + * @return a label with the specified text that has word wrap enabled. */ - public void run() { - ui.showWelcome(); - boolean isExit = false; - while (!isExit) { - try { - String fullCommand = ui.readCommand(); - ui.showLine(); - Command c = CommandManager.manageCommand(fullCommand); - c.execute(patientTaskList, taskManager, patientManager, - ui, storageManager); - counter.runCommandCounter(c, storageManager, counter); - isExit = c.isExit(); - } catch (DukeException e) { - ui.showError(e.getMessage()); - } finally { - ui.showLine(); - } - - } - System.exit(0); + private Label getDialogLabel(String text) { + // You will need to import `javafx.scene.control.Label`. + Label textToAdd = new Label(text); + textToAdd.setWrapText(true); + + return textToAdd; } /** - * Starts the Duke thread and Reminder thread concurrently - * by passing a filepath to duke and a global ui object& - * task list to Reminder. - * - * @param args The command line arguments. + * Iteration 2: + * Creates two dialog boxes, one echoing user input and the other containing Duke's reply and then appends them to + * the dialog container. Clears the user input after processing. */ - public static void main(String[] args) { - new Duke("./data").run(); + private void handleUserInput() { + Label userText = new Label(userInput.getText()); + Label dukeText = new Label(getResponse(userInput.getText())); + dialogContainer.getChildren().addAll( + new DialogBox(userText, new ImageView(user)), + new DialogBox(dukeText, new ImageView(duke)) + ); + userInput.clear(); + } + + /** + * You should have your own function to generate a response to user input. + * Replace this stub with your completed method. + */ + private String getResponse(String input) { + return "Duke heard: " + input; } } + + +// +// +// /** +// * A Storage object that handles reading tasks from a local +// * file and saving them to the same file. +// */ +// private StorageManager storageManager; +// /** +// * A TaskList object that deals with add, delete, mark as done, +// * find functions of a list of tasks. +// */ +// private PatientTaskList patientTaskList; +// private TaskManager taskManager; +// private PatientManager patientManager; +// private Counter counter; +// +// +// /** +// * A Ui object that deals with interactions with the user. +// */ +// +// private static final Ui ui = Ui.getUi(); +// +// +// /** +// * Constructs a Duke object with a relative file path. +// * Initialize the user interface and reads tasks from the specific text file. +// * +// * @param filePath A string that represents the path of the local file +// * used for storing tasks. +// */ +// public Duke(String filePath) { +// storageManager = new StorageManager(filePath); +// +// try { +// patientTaskList = new PatientTaskList(storageManager.loadAssignedTasks()); +// taskManager = new TaskManager(storageManager.loadTasks()); +// patientManager = new PatientManager(storageManager.loadPatients()); +// counter = new Counter(storageManager.loadCommandFrequency()); +// +// } catch (DukeException e) { +// ui.showLoadingError(); +// System.out.println(e.getMessage()); +// taskManager = new TaskManager(); +// } +// } +// +// /** +// * Runs the Duke program. +// * Reads user input until a "bye" message is received. +// */ +// public void run() { +// ui.showWelcome(); +// boolean isExit = false; +// while (!isExit) { +// try { +// String fullCommand = ui.readCommand(); +// ui.showLine(); +// Command c = CommandManager.manageCommand(fullCommand); +// c.execute(patientTaskList, taskManager, patientManager, +// ui, storageManager); +// counter.runCommandCounter(c, storageManager, counter); +// isExit = c.isExit(); +// } catch (DukeException e) { +// ui.showError(e.getMessage()); +// } finally { +// ui.showLine(); +// } +// +// } +// System.exit(0); +// } +// +// /** +// * Starts the Duke thread and Reminder thread concurrently +// * by passing a filepath to duke and a global ui object& +// * task list to Reminder. +// * +// * @param args The command line arguments. +// */ +// public static void main(String[] args) { +// new Duke("./data").run(); +// } +// +//} diff --git a/src/main/java/Launcher.java b/src/main/java/duke/Launcher.java similarity index 94% rename from src/main/java/Launcher.java rename to src/main/java/duke/Launcher.java index 04df820bf0..be28120f3e 100644 --- a/src/main/java/Launcher.java +++ b/src/main/java/duke/Launcher.java @@ -1,3 +1,5 @@ +package duke; + import duke.Duke; import javafx.application.Application; From 73eb05a5dabedb7072a51e5baa6e31da421c711e Mon Sep 17 00:00:00 2001 From: WEIFENG-NUSCEG Date: Fri, 25 Oct 2019 17:31:02 +0800 Subject: [PATCH 242/420] A testing code for the undo command using Memento Pattern input command : "undo" to reverse any change u have made from last step, undo command has a limit when u've basically undo everything to the original state (In another word : it's the state when you just open the program) --- src/main/java/duke/Duke.java | 46 ++++++++++++++++--- .../java/duke/MementoPattern/Memento.java | 39 ++++++++++++++++ .../duke/MementoPattern/MementoManager.java | 21 +++++++++ .../duke/MementoPattern/MementoParser.java | 19 ++++++++ src/main/java/duke/command/UndoCommand.java | 43 +++++++++++++++++ src/main/java/duke/core/CommandManager.java | 21 ++------- src/main/java/duke/core/Ui.java | 7 +++ 7 files changed, 173 insertions(+), 23 deletions(-) create mode 100644 src/main/java/duke/MementoPattern/Memento.java create mode 100644 src/main/java/duke/MementoPattern/MementoManager.java create mode 100644 src/main/java/duke/MementoPattern/MementoParser.java create mode 100644 src/main/java/duke/command/UndoCommand.java diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index fdc545adcf..53121bce5c 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -1,10 +1,10 @@ package duke; +import duke.MementoPattern.Memento; +import duke.MementoPattern.MementoManager; +import duke.MementoPattern.MementoParser; import duke.command.Command; -import duke.core.CommandManager; -import duke.core.DukeException; -import duke.core.ShortCutter; -import duke.core.Ui; +import duke.core.*; import duke.patient.PatientManager; import duke.relation.PatientTaskList; import duke.statistic.Counter; @@ -22,6 +22,7 @@ public class Duke { * file and saving them to the same file. */ private StorageManager storageManager; + /** * A TaskList object that deals with add, delete, mark as done, * find functions of a list of tasks. @@ -31,6 +32,11 @@ public class Duke { private PatientManager patientManager; private Counter counter; + /** + * A Ui object that deals with interactions with the user. + */ + private MementoManager mementoManager; + private MementoParser mementoParser; /** * A Ui object that deals with interactions with the user. */ @@ -45,7 +51,7 @@ public class Duke { */ public Duke(String filePath) { storageManager = new StorageManager(filePath); - + mementoManager = new MementoManager(); try { patientTaskList = new PatientTaskList(storageManager.loadAssignedTasks()); taskManager = new TaskManager(storageManager.loadTasks()); @@ -59,6 +65,28 @@ public Duke(String filePath) { } } + /** + * . + * + * @return . + */ + public void getDukeStateFromMemento(Memento memento) { + taskManager = memento.getTaskState(); + patientTaskList = memento.getPatientTaskState(); + patientManager = memento.getPatientState(); + } + + /** + * . + * . + * @return . + */ + public Memento saveDukeStateToMemento() { + return new Memento(new TaskManager(taskManager.getTaskList()) + , new PatientTaskList(patientTaskList.fullPatientTaskList()) + , new PatientManager(patientManager.getPatientList())); + } + /** * Runs the Duke program. * Reads user input until a "bye" message is received. @@ -66,11 +94,18 @@ public Duke(String filePath) { public void run() { ui.showWelcome(); boolean isExit = false; + while (!isExit) { try { String fullCommand = ui.readCommand(); ui.showLine(); Command c = CommandManager.manageCommand(fullCommand); + if (mementoParser.getSaveFlag(c).equals("save")) { + Memento newMem = saveDukeStateToMemento(); + mementoManager.add(newMem); + } else if (mementoParser.getSaveFlag(c).equals("pop")) { + getDukeStateFromMemento(mementoManager.pop()); + } c.execute(patientTaskList, taskManager, patientManager, ui, storageManager); counter.runCommandCounter(c, storageManager, counter); @@ -80,7 +115,6 @@ public void run() { } finally { ui.showLine(); } - } System.exit(0); } diff --git a/src/main/java/duke/MementoPattern/Memento.java b/src/main/java/duke/MementoPattern/Memento.java new file mode 100644 index 0000000000..d99f7e7927 --- /dev/null +++ b/src/main/java/duke/MementoPattern/Memento.java @@ -0,0 +1,39 @@ +package duke.MementoPattern; + +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Multimap; +import duke.command.Command; +import duke.patient.Patient; +import duke.patient.PatientManager; +import duke.relation.PatientTask; +import duke.relation.PatientTaskList; +import duke.statistic.Counter; +import duke.task.Task; +import duke.task.TaskManager; + +import java.util.ArrayList; + +public class Memento +{ + private TaskManager memTaskList; + private PatientManager memPatientManager; + private PatientTaskList memPatientTaskList; + + public Memento(TaskManager taskManager, PatientTaskList patientTaskList, PatientManager patientManager) { + this.memTaskList = taskManager; + this.memPatientManager = patientManager; + this.memPatientTaskList = patientTaskList; + } + + public TaskManager getTaskState() { + return this.memTaskList; + } + + public PatientManager getPatientState() { + return this.memPatientManager; + } + + public PatientTaskList getPatientTaskState() { + return this.memPatientTaskList; + } +} \ No newline at end of file diff --git a/src/main/java/duke/MementoPattern/MementoManager.java b/src/main/java/duke/MementoPattern/MementoManager.java new file mode 100644 index 0000000000..ef231ac61d --- /dev/null +++ b/src/main/java/duke/MementoPattern/MementoManager.java @@ -0,0 +1,21 @@ +package duke.MementoPattern; + +import duke.core.DukeException; + +import java.util.Stack; + +public class MementoManager { + private Stack mementos = new Stack<>(); + + public void add(Memento state){ + mementos.add(state); + } + + public Memento pop() throws DukeException { + try { + return mementos.pop(); + } catch (Exception e) { + throw new DukeException("You have reach the undo limits!"); + } + } +} diff --git a/src/main/java/duke/MementoPattern/MementoParser.java b/src/main/java/duke/MementoPattern/MementoParser.java new file mode 100644 index 0000000000..114f0d1a93 --- /dev/null +++ b/src/main/java/duke/MementoPattern/MementoParser.java @@ -0,0 +1,19 @@ +package duke.MementoPattern; + +import duke.command.*; + +public class MementoParser { + + public static String getSaveFlag(Command command){ + if ((command instanceof AddPatientCommand) || (command instanceof AddStandardTaskCommand) + || (command instanceof AssignTaskToPatientCommand) || (command instanceof DeletePatientCommand) + || (command instanceof DeletePatientTaskCommand) || (command instanceof DeleteTaskCommand) + || (command instanceof UpdatePatientCommand) || (command instanceof UpdateTaskCommand)){ + return "save"; + } else if (command instanceof UndoCommand) { + return "pop"; + } else { + return "ignore"; + } + } +} diff --git a/src/main/java/duke/command/UndoCommand.java b/src/main/java/duke/command/UndoCommand.java new file mode 100644 index 0000000000..25c800f5ed --- /dev/null +++ b/src/main/java/duke/command/UndoCommand.java @@ -0,0 +1,43 @@ +package duke.command; + +import duke.MementoPattern.Memento; +import duke.MementoPattern.MementoManager; +import duke.core.DukeException; +import duke.core.Ui; +import duke.patient.PatientManager; +import duke.relation.PatientTaskList; +import duke.storage.StorageManager; +import duke.task.TaskManager; + +public class UndoCommand extends Command{ + + /** + * . + * + * @param patientTask . + * @param tasks . + * @param patientManager . + * @param ui . + * @param storageManager . + * @throws DukeException . + */ + @Override + public void execute(PatientTaskList patientTask, TaskManager tasks, PatientManager patientManager, + Ui ui, StorageManager storageManager) throws DukeException { + storageManager.savePatients(patientManager.getPatientList()); + storageManager.saveTasks(tasks.getTaskList()); + storageManager.saveAssignedTasks(patientTask.fullPatientTaskList()); + ui.showUndoSuccess(); + } + + /** + * Decide whether duke should exist. + * + * @return A boolean. True if the command tells Duke to exit, false + */ + + @Override + public boolean isExit() { + return false; + } +} diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index 50c85f5b2b..e89cc89b51 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -2,21 +2,7 @@ package duke.core; -import duke.command.AddPatientCommand; -import duke.command.AddStandardTaskCommand; -import duke.command.AssignTaskToPatientCommand; -import duke.command.Command; -import duke.command.DeletePatientCommand; -import duke.command.DeletePatientTaskCommand; -import duke.command.DeleteTaskCommand; -import duke.command.DukeCommand; -import duke.command.ExitCommand; -import duke.command.FindPatientCommand; -import duke.command.FindPatientTaskCommand; -import duke.command.ListPatientsCommand; -import duke.command.ListTasksCommand; -import duke.command.UpdatePatientCommand; -import duke.command.UpdateTaskCommand; +import duke.command.*; /** * Represents a Parser that parses user input into a specific @@ -72,8 +58,9 @@ public static Command manageCommand(String userInput) throws DukeException { case "duke": return new DukeCommand(); case "bye": - ExitCommand exitCommand = new ExitCommand(); - return exitCommand; + return new ExitCommand(); + case "undo" : + return new UndoCommand(); default: throw new DukeException("Could not understand user input."); } diff --git a/src/main/java/duke/core/Ui.java b/src/main/java/duke/core/Ui.java index 8416920536..d4a7fc990e 100644 --- a/src/main/java/duke/core/Ui.java +++ b/src/main/java/duke/core/Ui.java @@ -428,6 +428,13 @@ public void showLoadingError() { System.out.println("Failed to load from local data file!"); } + /** + * Show message of undo. + */ + public void showUndoSuccess() { + System.out.println("Undo command received"); + } + /** * It shows all info of patientTasks found which are associated with the patient given by user. * From 0e983b769b335a784e2338c523bbbb48e74568a7 Mon Sep 17 00:00:00 2001 From: WEIFENG-NUSCEG Date: Fri, 25 Oct 2019 17:33:36 +0800 Subject: [PATCH 243/420] resolve some conflicts --- src/main/java/duke/Duke.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index 53121bce5c..9b9eeaa082 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -10,7 +10,10 @@ import duke.statistic.Counter; import duke.storage.StorageManager; import duke.task.TaskManager; - +import duke.core.CommandManager; +import duke.core.DukeException; +import duke.core.ShortCutter; +import duke.core.Ui; /** * Represents Duke, a Personal Assistant to help From 8f40b0b24c00048632e3ab02f95c7d3ba92215ee Mon Sep 17 00:00:00 2001 From: WEIFENG-NUSCEG Date: Fri, 25 Oct 2019 17:34:39 +0800 Subject: [PATCH 244/420] correct the format of import --- src/main/java/duke/Duke.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index 9b9eeaa082..1154837de2 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -4,7 +4,6 @@ import duke.MementoPattern.MementoManager; import duke.MementoPattern.MementoParser; import duke.command.Command; -import duke.core.*; import duke.patient.PatientManager; import duke.relation.PatientTaskList; import duke.statistic.Counter; From 76f51044ab5b2510289a6e8c251f3a0043137f7b Mon Sep 17 00:00:00 2001 From: WEIFENG-NUSCEG Date: Fri, 25 Oct 2019 17:37:58 +0800 Subject: [PATCH 245/420] resolve style problem --- src/main/java/duke/Duke.java | 8 ++++---- src/main/java/duke/core/CommandManager.java | 17 ++++++++++++++++- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index 1154837de2..0a10a495b8 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -4,15 +4,15 @@ import duke.MementoPattern.MementoManager; import duke.MementoPattern.MementoParser; import duke.command.Command; +import duke.core.CommandManager; +import duke.core.DukeException; +import duke.core.Ui; import duke.patient.PatientManager; import duke.relation.PatientTaskList; import duke.statistic.Counter; import duke.storage.StorageManager; import duke.task.TaskManager; -import duke.core.CommandManager; -import duke.core.DukeException; -import duke.core.ShortCutter; -import duke.core.Ui; + /** * Represents Duke, a Personal Assistant to help diff --git a/src/main/java/duke/core/CommandManager.java b/src/main/java/duke/core/CommandManager.java index e89cc89b51..8bd336da35 100644 --- a/src/main/java/duke/core/CommandManager.java +++ b/src/main/java/duke/core/CommandManager.java @@ -2,7 +2,22 @@ package duke.core; -import duke.command.*; +import duke.command.AddPatientCommand; +import duke.command.AddStandardTaskCommand; +import duke.command.AssignTaskToPatientCommand; +import duke.command.Command; +import duke.command.DeletePatientCommand; +import duke.command.DeletePatientTaskCommand; +import duke.command.DeleteTaskCommand; +import duke.command.DukeCommand; +import duke.command.ExitCommand; +import duke.command.FindPatientCommand; +import duke.command.FindPatientTaskCommand; +import duke.command.ListPatientsCommand; +import duke.command.ListTasksCommand; +import duke.command.UpdatePatientCommand; +import duke.command.UpdateTaskCommand; +import duke.command.UndoCommand; /** * Represents a Parser that parses user input into a specific From b7d86bcde1f433fd82fafcf89b977aa3932c8203 Mon Sep 17 00:00:00 2001 From: WEI FENG <42437159+WEIFENG-NUSCEG@users.noreply.github.com> Date: Fri, 25 Oct 2019 17:54:03 +0800 Subject: [PATCH 246/420] Update UndoCommand.java --- src/main/java/duke/command/UndoCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/duke/command/UndoCommand.java b/src/main/java/duke/command/UndoCommand.java index 25c800f5ed..11504d9f97 100644 --- a/src/main/java/duke/command/UndoCommand.java +++ b/src/main/java/duke/command/UndoCommand.java @@ -9,7 +9,7 @@ import duke.storage.StorageManager; import duke.task.TaskManager; -public class UndoCommand extends Command{ +public class UndoCommand implements Command{ /** * . From 3739e1d4acb58ff80ec037ca5209568cbc5d54f1 Mon Sep 17 00:00:00 2001 From: HUANG XUAN KUN Date: Sat, 26 Oct 2019 01:24:47 +0800 Subject: [PATCH 247/420] update --- src/main/java/duke/DialogBox.java | 58 ++++- src/main/java/duke/Duke.java | 272 +++++++----------------- src/main/java/duke/Launcher.java | 2 +- src/main/java/duke/Main.java | 33 +++ src/main/java/duke/MainWindow.java | 55 +++++ src/main/resources/view/DialogBox.fxml | 16 ++ src/main/resources/view/MainWindow.fxml | 19 ++ 7 files changed, 245 insertions(+), 210 deletions(-) create mode 100644 src/main/java/duke/Main.java create mode 100644 src/main/java/duke/MainWindow.java create mode 100644 src/main/resources/view/DialogBox.fxml create mode 100644 src/main/resources/view/MainWindow.fxml diff --git a/src/main/java/duke/DialogBox.java b/src/main/java/duke/DialogBox.java index 9b44938db6..70d7fd65bc 100644 --- a/src/main/java/duke/DialogBox.java +++ b/src/main/java/duke/DialogBox.java @@ -1,24 +1,62 @@ package duke; +import java.io.IOException; +import java.util.Collections; + +import duke.MainWindow; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; import javafx.geometry.Pos; +import javafx.scene.Node; import javafx.scene.control.Label; +import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.layout.HBox; +/** + * An example of a custom control using FXML. + * This control represents a dialog box consisting of an ImageView to represent the speaker's face and a label + * containing text from the speaker. + */ public class DialogBox extends HBox { - - private Label text; + @FXML + private Label dialog; + @FXML private ImageView displayPicture; - public DialogBox(Label l, ImageView iv) { - text = l; - displayPicture = iv; + private DialogBox(String text, Image img) { + try { + FXMLLoader fxmlLoader = new FXMLLoader(MainWindow.class.getResource("/view/DialogBox.fxml")); + fxmlLoader.setController(this); + fxmlLoader.setRoot(this); + fxmlLoader.load(); + } catch (IOException e) { + e.printStackTrace(); + } + + dialog.setText(text); + displayPicture.setImage(img); + } - text.setWrapText(true); - displayPicture.setFitWidth(100.0); - displayPicture.setFitHeight(100.0); + /** + * Flips the dialog box such that the ImageView is on the left and text on the right. + */ + private void flip() { + ObservableList tmp = FXCollections.observableArrayList(this.getChildren()); + Collections.reverse(tmp); + getChildren().setAll(tmp); + setAlignment(Pos.TOP_LEFT); + } + + public static DialogBox getUserDialog(String text, Image img) { + return new DialogBox(text, img); + } - this.setAlignment(Pos.TOP_RIGHT); - this.getChildren().addAll(text, displayPicture); + public static DialogBox getDukeDialog(String text, Image img) { + var db = new DialogBox(text, img); + db.flip(); + return db; } } \ No newline at end of file diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java index 1f947c5e31..3b66ebeeab 100644 --- a/src/main/java/duke/Duke.java +++ b/src/main/java/duke/Duke.java @@ -27,221 +27,95 @@ * Represents Duke, a Personal Assistant to help * users tracking their progress. */ -public class Duke extends Application { - private ScrollPane scrollPane; - private VBox dialogContainer; - private TextField userInput; - private Button sendButton; - private Scene scene; - // ... - private Image user = new Image(this.getClass().getResourceAsStream("/images/DaUser.png")); - private Image duke = new Image(this.getClass().getResourceAsStream("/images/DaDuke.png")); - // ... - - public static void main(String[] args) { - // ... +public class Duke { + /** + * You should have your own function to generate a response to user input. + * Replace this stub with your completed method. + */ + public String getResponse(String input) { + return "Duke heard: " + input; } - @Override - public void start(Stage stage) { - //Step 1. Setting up required components - - //The container for the content of the chat to scroll. - scrollPane = new ScrollPane(); - dialogContainer = new VBox(); - scrollPane.setContent(dialogContainer); - - userInput = new TextField(); - sendButton = new Button("Send"); - - AnchorPane mainLayout = new AnchorPane(); - mainLayout.getChildren().addAll(scrollPane, userInput, sendButton); - - scene = new Scene(mainLayout); - - stage.setScene(scene); - stage.show(); - - //Step 2. Formatting the window to look as expected - stage.setTitle("Duke"); - stage.setResizable(false); - stage.setMinHeight(600.0); - stage.setMinWidth(400.0); - - mainLayout.setPrefSize(400.0, 600.0); - - scrollPane.setPrefSize(385, 535); - scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER); - scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS); - - scrollPane.setVvalue(1.0); - scrollPane.setFitToWidth(true); - - // You will need to import `javafx.scene.layout.Region` for this. - dialogContainer.setPrefHeight(Region.USE_COMPUTED_SIZE); - - - userInput.setPrefWidth(325.0); - - sendButton.setPrefWidth(55.0); - - AnchorPane.setTopAnchor(scrollPane, 1.0); - - AnchorPane.setBottomAnchor(sendButton, 1.0); - AnchorPane.setRightAnchor(sendButton, 1.0); - - AnchorPane.setLeftAnchor(userInput , 1.0); - AnchorPane.setBottomAnchor(userInput, 1.0); - - //Step 3. Add functionality to handle user input. -// sendButton.setOnMouseClicked((event) -> { -// dialogContainer.getChildren().add(getDialogLabel(userInput.getText())); -// userInput.clear(); -// }); - -// userInput.setOnAction((event) -> { -// dialogContainer.getChildren().add(getDialogLabel(userInput.getText())); -// userInput.clear(); -// }); - - // more code to be added here later - - //Scroll down to the end every time dialogContainer's height changes. - dialogContainer.heightProperty().addListener((observable) -> scrollPane.setVvalue(1.0)); + /** + * A Storage object that handles reading tasks from a local + * file and saving them to the same file. + */ + private StorageManager storageManager; + /** + * A TaskList object that deals with add, delete, mark as done, + * find functions of a list of tasks. + */ + private PatientTaskList patientTaskList; + private TaskManager taskManager; + private PatientManager patientManager; + private Counter counter; - //Part 3. Add functionality to handle user input. - sendButton.setOnMouseClicked((event) -> { - handleUserInput(); - }); - userInput.setOnAction((event) -> { - handleUserInput(); - }); + /** + * A Ui object that deals with interactions with the user. + */ + private static final Ui ui = Ui.getUi(); - } /** - * Iteration 1: - * Creates a label with the specified text and adds it to the dialog container. - * @param text String containing text to add - * @return a label with the specified text that has word wrap enabled. + * Constructs a Duke object with a relative file path. + * Initialize the user interface and reads tasks from the specific text file. + * + * @param filePath A string that represents the path of the local file + * used for storing tasks. */ - private Label getDialogLabel(String text) { - // You will need to import `javafx.scene.control.Label`. - Label textToAdd = new Label(text); - textToAdd.setWrapText(true); - - return textToAdd; + public Duke(String filePath) { + storageManager = new StorageManager(filePath); + + try { + patientTaskList = new PatientTaskList(storageManager.loadAssignedTasks()); + taskManager = new TaskManager(storageManager.loadTasks()); + patientManager = new PatientManager(storageManager.loadPatients()); + counter = new Counter(storageManager.loadCommandFrequency()); + + } catch (DukeException e) { + ui.showLoadingError(); + System.out.println(e.getMessage()); + taskManager = new TaskManager(); + } } /** - * Iteration 2: - * Creates two dialog boxes, one echoing user input and the other containing Duke's reply and then appends them to - * the dialog container. Clears the user input after processing. + * Runs the Duke program. + * Reads user input until a "bye" message is received. */ - private void handleUserInput() { - Label userText = new Label(userInput.getText()); - Label dukeText = new Label(getResponse(userInput.getText())); - dialogContainer.getChildren().addAll( - new DialogBox(userText, new ImageView(user)), - new DialogBox(dukeText, new ImageView(duke)) - ); - userInput.clear(); + public void run() { + ui.showWelcome(); + boolean isExit = false; + while (!isExit) { + try { + String fullCommand = ui.readCommand(); + ui.showLine(); + Command c = CommandManager.manageCommand(fullCommand); + c.execute(patientTaskList, taskManager, patientManager, + ui, storageManager); + counter.runCommandCounter(c, storageManager, counter); + isExit = c.isExit(); + } catch (DukeException e) { + ui.showError(e.getMessage()); + } finally { + ui.showLine(); + } + + } + System.exit(0); } /** - * You should have your own function to generate a response to user input. - * Replace this stub with your completed method. + * Starts the Duke thread and Reminder thread concurrently + * by passing a filepath to duke and a global ui object& + * task list to Reminder. + * + * @param args The command line arguments. */ - private String getResponse(String input) { - return "Duke heard: " + input; + public static void main(String[] args) { + new Duke("./data").run(); } -} - -// -// -// /** -// * A Storage object that handles reading tasks from a local -// * file and saving them to the same file. -// */ -// private StorageManager storageManager; -// /** -// * A TaskList object that deals with add, delete, mark as done, -// * find functions of a list of tasks. -// */ -// private PatientTaskList patientTaskList; -// private TaskManager taskManager; -// private PatientManager patientManager; -// private Counter counter; -// -// -// /** -// * A Ui object that deals with interactions with the user. -// */ -// -// private static final Ui ui = Ui.getUi(); -// -// -// /** -// * Constructs a Duke object with a relative file path. -// * Initialize the user interface and reads tasks from the specific text file. -// * -// * @param filePath A string that represents the path of the local file -// * used for storing tasks. -// */ -// public Duke(String filePath) { -// storageManager = new StorageManager(filePath); -// -// try { -// patientTaskList = new PatientTaskList(storageManager.loadAssignedTasks()); -// taskManager = new TaskManager(storageManager.loadTasks()); -// patientManager = new PatientManager(storageManager.loadPatients()); -// counter = new Counter(storageManager.loadCommandFrequency()); -// -// } catch (DukeException e) { -// ui.showLoadingError(); -// System.out.println(e.getMessage()); -// taskManager = new TaskManager(); -// } -// } -// -// /** -// * Runs the Duke program. -// * Reads user input until a "bye" message is received. -// */ -// public void run() { -// ui.showWelcome(); -// boolean isExit = false; -// while (!isExit) { -// try { -// String fullCommand = ui.readCommand(); -// ui.showLine(); -// Command c = CommandManager.manageCommand(fullCommand); -// c.execute(patientTaskList, taskManager, patientManager, -// ui, storageManager); -// counter.runCommandCounter(c, storageManager, counter); -// isExit = c.isExit(); -// } catch (DukeException e) { -// ui.showError(e.getMessage()); -// } finally { -// ui.showLine(); -// } -// -// } -// System.exit(0); -// } -// -// /** -// * Starts the Duke thread and Reminder thread concurrently -// * by passing a filepath to duke and a global ui object& -// * task list to Reminder. -// * -// * @param args The command line arguments. -// */ -// public static void main(String[] args) { -// new Duke("./data").run(); -// } -// -//} +} diff --git a/src/main/java/duke/Launcher.java b/src/main/java/duke/Launcher.java index be28120f3e..ccdff33964 100644 --- a/src/main/java/duke/Launcher.java +++ b/src/main/java/duke/Launcher.java @@ -8,6 +8,6 @@ */ public class Launcher { public static void main(String[] args) { - Application.launch(Duke.class, args); + Application.launch(Main.class, args); } } \ No newline at end of file diff --git a/src/main/java/duke/Main.java b/src/main/java/duke/Main.java new file mode 100644 index 0000000000..b14f0b544b --- /dev/null +++ b/src/main/java/duke/Main.java @@ -0,0 +1,33 @@ +package duke; +import javafx.application.Application; +import duke.Duke; +import duke.MainWindow; +import javafx.fxml.FXMLLoader; +import javafx.scene.Scene; +import javafx.scene.layout.AnchorPane; +import javafx.stage.Stage; + +import java.io.IOException; + + +/** + * A GUI for Duke using FXML. + */ +public class Main extends Application { + + private Duke duke = new Duke("./data"); + + @Override + public void start(Stage stage) { + try { + FXMLLoader fxmlLoader = new FXMLLoader(Main.class.getResource("/view/MainWindow.fxml")); + AnchorPane ap = fxmlLoader.load(); + Scene scene = new Scene(ap); + stage.setScene(scene); + fxmlLoader.getController().setDuke(duke); + stage.show(); + } catch (IOException e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/src/main/java/duke/MainWindow.java b/src/main/java/duke/MainWindow.java new file mode 100644 index 0000000000..05e1e0edce --- /dev/null +++ b/src/main/java/duke/MainWindow.java @@ -0,0 +1,55 @@ +package duke; + +import duke.DialogBox; +import duke.Duke; +import javafx.fxml.FXML; +import javafx.scene.control.Button; +import javafx.scene.control.ScrollPane; +import javafx.scene.control.TextField; +import javafx.scene.image.Image; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.VBox; + + +/** + * Controller for MainWindow. Provides the layout for the other controls. + */ +public class MainWindow extends AnchorPane { + @FXML + private ScrollPane scrollPane; + @FXML + private VBox dialogContainer; + @FXML + private TextField userInput; + @FXML + private Button sendButton; + + private Duke duke; + + private Image userImage = new Image(this.getClass().getResourceAsStream("/images/DaUser.png")); + private Image dukeImage = new Image(this.getClass().getResourceAsStream("/images/DaDuke.png")); + + @FXML + public void initialize() { + scrollPane.vvalueProperty().bind(dialogContainer.heightProperty()); + } + + public void setDuke(Duke d) { + duke = d; + } + + /** + * Creates two dialog boxes, one echoing user input and the other containing Duke's reply and then appends them to + * the dialog container. Clears the user input after processing. + */ + @FXML + private void handleUserInput() { + String input = userInput.getText(); + String response = duke.getResponse(input); + dialogContainer.getChildren().addAll( + DialogBox.getUserDialog(input, userImage), + DialogBox.getDukeDialog(response, dukeImage) + ); + userInput.clear(); + } +} \ No newline at end of file diff --git a/src/main/resources/view/DialogBox.fxml b/src/main/resources/view/DialogBox.fxml new file mode 100644 index 0000000000..da8fca48e1 --- /dev/null +++ b/src/main/resources/view/DialogBox.fxml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + diff --git a/src/main/resources/view/MainWindow.fxml b/src/main/resources/view/MainWindow.fxml new file mode 100644 index 0000000000..b2fd9a7725 --- /dev/null +++ b/src/main/resources/view/MainWindow.fxml @@ -0,0 +1,19 @@ + + + + + + + + + + + +