diff --git a/docs/README.md b/docs/README.md index fd44069597..2b441f6fe8 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,19 +2,29 @@ ## Features -### Feature 1 -Description of feature. - -## Usage - -### `Keyword` - Describe action - -Describe action and its outcome. - -Example of usage: - -`keyword (optional arguments)` - -Expected outcome: - -`outcome` +### Add tasks to list +#### ToDo +* Add a ToDo to your list of tasks in the following format: "todo {task to be done}" +* Example: "todo read book" +#### Deadline +* Add a task with a deadline to your list of tasks in the following format: "deadline {task to be done} /by {date and/or time}" +* Example: "deadline write essay /by today, 2pm" +#### Event +* Add an event to your list of tasks in the following format: "event {name of event} /at {date and/or time}" +* Example: "event career fair /at 2pm, 14 Feb" + +### Mark a task as completed +* Mark a task as completed in the following format: "done {index number of task in the list}" +* Example: "done 3" + +### See your list of tasks +* See your list of tasks in the following format: "list" +* Example: "list" + +### Find a certain task using keywords +* Find a certain task using keywords in the following format: "find {keywords}" +* Example: "find book" + +### Delete a task from your list +* Delete a certain task from your list in the following format: "delete {index number of the task in the list}" +* Example: "delete 4" \ No newline at end of file diff --git a/src/.idea/modules.xml b/src/.idea/modules.xml new file mode 100644 index 0000000000..f669a0e594 --- /dev/null +++ b/src/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/src/.idea/vcs.xml b/src/.idea/vcs.xml new file mode 100644 index 0000000000..6c0b863585 --- /dev/null +++ b/src/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/main/java/Command.java b/src/main/java/Command.java new file mode 100644 index 0000000000..90104589be --- /dev/null +++ b/src/main/java/Command.java @@ -0,0 +1,26 @@ +/** +<<<<<<< HEAD + * +======= + * A class that is the foundation where all the Commands extends from. +>>>>>>> JavaDocs + */ + +public class Command { + protected String command; + protected TextUi textUi; + + public Command() { + this.command = ""; + } + + /** + * Constructor for Command object. + * @param command the command inputted by the user, with trailing and leading white spaces removed. + */ + + public Command(String command) { + this.command = command; + textUi = new TextUi(); + } +} diff --git a/src/main/java/Deadline.java b/src/main/java/Deadline.java new file mode 100644 index 0000000000..4771c848e3 --- /dev/null +++ b/src/main/java/Deadline.java @@ -0,0 +1,27 @@ +/** + * Extends from Task. Stores the information needed for Deadline. + */ + +public class Deadline extends Task { + + /** + * The latest date the task must be completed. + */ + + private String latestDate; + + /** + * Constructor for Deadline. + * @param userInput the command that the user typed in. + */ + + public Deadline(String userInput) { + super(userInput.substring(0, userInput.indexOf(" /"))); + this.latestDate = userInput.substring(userInput.indexOf("/") + 4); + } + + @Override + public String toString() { + return String.format("[D][%c] %s (by: %s)", isDone() ? '✓' : '✗', taskName, latestDate); + } +} diff --git a/src/main/java/DeadlineCommand.java b/src/main/java/DeadlineCommand.java new file mode 100644 index 0000000000..af8a65b681 --- /dev/null +++ b/src/main/java/DeadlineCommand.java @@ -0,0 +1,24 @@ +/** + * Extends from Command. Gives instructions on how to proceed when a Deadline task is added. + */ + +public class DeadlineCommand extends Command { + + /** + * Create a new Deadline task as requested by the user. + */ + + private Deadline deadline; + + /** + * Constructor for DeadlineCommand. + * @param command the command that the user typed in. + * @throws IndexOutOfBoundsException throws IndexOutOfBoundsException when there are invalid arguments. + */ + public DeadlineCommand(String command) throws IndexOutOfBoundsException { + super(command); + deadline = new Deadline(command.substring(9)); + Duke.tasks.add(deadline); + textUi.printDeadlineMessage(deadline); + } +} diff --git a/src/main/java/DeleteCommand.java b/src/main/java/DeleteCommand.java new file mode 100644 index 0000000000..b6498e02a6 --- /dev/null +++ b/src/main/java/DeleteCommand.java @@ -0,0 +1,19 @@ +/** + * Extends from Command. Gives instructions on how to proceed when a task needs to be deleted. + */ + +public class DeleteCommand extends Command { + + /** + * Constructor for DeleteCommand. + * @param command the command that the user typed in. + * @throws IndexOutOfBoundsException throw IndexOutOfBoundsException when there are invalid arguments. + */ + public DeleteCommand(String command) throws IndexOutOfBoundsException { + super(command); + int selectedTaskId = Integer.parseInt(command.substring(7)); + Task task = Duke.tasks.get(selectedTaskId - 1); + Duke.tasks.remove(task); + textUi.printDeleteMessage(task, Duke.tasks.size()); + } +} diff --git a/src/main/java/DoneCommand.java b/src/main/java/DoneCommand.java new file mode 100644 index 0000000000..ec166a6fe2 --- /dev/null +++ b/src/main/java/DoneCommand.java @@ -0,0 +1,15 @@ +/** + * Extends from Command. Gives instructions on how to proceed when a task is completed. + */ + +public class DoneCommand extends Command { + + /** + * Constructor for DoneCommand. + * @param command the command that the user typed in. + */ + public DoneCommand(String command) { + super(command); + Duke.tasks.get(Integer.parseInt(command.substring(5)) - 1).setDone(); + } +} diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 5d313334cc..ab2eb334f8 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,10 +1,45 @@ +import java.io.FileNotFoundException; +import java.io.PrintWriter; +import java.util.Scanner; +import java.util.ArrayList; + +/** +<<<<<<< HEAD + * Duke is a project that keeps a list of the tasks that need to be completed. +======= + * Project Duke. + * Keeps a record of the tasks that the user has, which can be saved into and loaded from a hard disk. +>>>>>>> JavaDocs + */ + public class Duke { + static ArrayList tasks = new ArrayList<>(); + + /** + * Stores any methods that require interaction with the user. + */ + + static TextUi textUi = new TextUi(); + + /** + * Contains all the necessary objects to keep track of the tasks. + * @param args + */ + public static void main(String[] args) { - String logo = " ____ _ \n" - + "| _ \\ _ _| | _____ \n" - + "| | | | | | | |/ / _ \\\n" - + "| |_| | |_| | < __/\n" - + "|____/ \\__,_|_|\\_\\___|\n"; - System.out.println("Hello from\n" + logo); + textUi.printWelcomeMessage(); + Scanner scan = new Scanner(System.in); + String userInput = scan.nextLine(); + while (!userInput.equals("bye")) { + try { + Parser.parseInput(userInput); + } catch (IndexOutOfBoundsException exception) { + textUi.printIndexOutOfBoundsExceptionMessage(exception); + } catch (IllegalArgumentException exception) { + textUi.printIllegalArgumentExceptionMessage(exception); + } + userInput = scan.nextLine(); + } + textUi.printExitMessage(); } } diff --git a/src/main/java/Event.java b/src/main/java/Event.java new file mode 100644 index 0000000000..a5f8baed09 --- /dev/null +++ b/src/main/java/Event.java @@ -0,0 +1,26 @@ +/** + * Extends from Task. Stores the information needed for Event. + */ + +public class Event extends Task { + + /** + * The details of the event as stated by the user. + */ + + private String eventDetails; + + /** + * Constructor for Event. + * @param userInput the command that the user typed in. + */ + public Event(String userInput) { + super(userInput.substring(0, userInput.indexOf(" /"))); + this.eventDetails = userInput.substring(userInput.indexOf("/") + 4); + } + + @Override + public String toString() { + return String.format("[E][%c] %s (at: %s)", isDone() ? '✓' : '✗', taskName, eventDetails); + } +} diff --git a/src/main/java/EventCommand.java b/src/main/java/EventCommand.java new file mode 100644 index 0000000000..d76ba9c3a2 --- /dev/null +++ b/src/main/java/EventCommand.java @@ -0,0 +1,24 @@ +/** + * Extends from Command. Gives instructions on how to proceed when an Event task is added. + */ + +public class EventCommand extends Command { + + /** + * Creates a new Event task as requested by the user. + */ + private Event event; + + /** + * Constructor for EventCommand. + * @param command the command that the user typed in. + * @throws IndexOutOfBoundsException throws IndexOutOfBoundsException when there are invalid arguments. + */ + + public EventCommand(String command) throws IndexOutOfBoundsException { + super(command); + event = new Event(command.substring(6)); + Duke.tasks.add(event); + textUi.printEventMessage(event); + } +} diff --git a/src/main/java/FindCommand.java b/src/main/java/FindCommand.java new file mode 100644 index 0000000000..e25aba4cb2 --- /dev/null +++ b/src/main/java/FindCommand.java @@ -0,0 +1,22 @@ +public class FindCommand extends Command { + public FindCommand(String command) { + super(command); + execute(command); + } + + public void execute(String command) { + textUi.printFindMessage(command); + String keyword = command.substring(5); + boolean isFound = false; + for (Task task : Duke.tasks) { + if (task.getTaskName().contains(keyword)) { + System.out.println(task.getTaskId() + ". " + task.toString()); + isFound = true; + } + } + if (!isFound) { + System.out.println("Sorry there are no matches"); + } + + } +} diff --git a/src/main/java/ListCommand.java b/src/main/java/ListCommand.java new file mode 100644 index 0000000000..2cb04bfb8b --- /dev/null +++ b/src/main/java/ListCommand.java @@ -0,0 +1,27 @@ +/** + * Extends from Command. Gives instructions on how to proceed when a list of the tasks is requested. + */ + +public class ListCommand extends Command { + + /** + * Stores the list of tasks in a text file on the hard disk. + */ + + private Storage storage; + + /** + * Constructor for ListCommand. + * @param command the command that the user typed in. + */ + + public ListCommand(String command) { + super(command); + storage = new Storage(); + for (Task task : Duke.tasks) { + System.out.println(String.format("%d. %s", task.getTaskId(), task.toString())); + storage.addToList(String.format("%d. %s", task.getTaskId(), task.toString())); + } + storage.storeList(); + } +} diff --git a/src/main/java/Messages.java b/src/main/java/Messages.java new file mode 100644 index 0000000000..8032b35dc0 --- /dev/null +++ b/src/main/java/Messages.java @@ -0,0 +1,37 @@ +/** + * Contains all the frequently used messages displayed to the user. + */ + +public class Messages { + + /** + * List of commands that the user can input. + */ + public static String LIST_OF_COMMANDS = "Here is the list of commands available\n" + + "\"bye\": to exit\n" + + "\"list\": to show the list of all your tasks\n" + + "\"todo\": add a todo\n" + + "\"deadline\": add a deadline\n" + + "\"event\": add an event\n" + + "\"done\": check off a task on your list\n"; + + /** + * Exit message. + */ + + public static String EXIT_MESSAGE = "Bye la you"; + + /** + * Duke logo. + */ + public static String LOGO = " ____ _ \n" + + "| _ \\\\ _ _| | __ __ \n" + + "| | | | | | | |/ / _ \\\n" + + "| |_| | |_| | < __/\n" + + "|____/ \\\\__,_|_|\\_\\\\___\n"; + + /** + * Welcome message when the user first enters. + */ + public static String WELCOME_MESSAGE = "Hello there I am\n" + LOGO + LIST_OF_COMMANDS; +} diff --git a/src/main/java/NoSuchCommand.java b/src/main/java/NoSuchCommand.java new file mode 100644 index 0000000000..6417982aeb --- /dev/null +++ b/src/main/java/NoSuchCommand.java @@ -0,0 +1,17 @@ +/** + * Extends from Command. Gives instructions on how to proceed when the command is not recognised. + */ + +public class NoSuchCommand extends Command { + + /** + * Constructor for NoSuchCommand. + * @param command the command that the user typed in. + * @throws IllegalArgumentException throws IllegalArgumentException within the constructor for the main method + * to catch. + */ + public NoSuchCommand(String command) throws IllegalArgumentException{ + super(command); + throw new IllegalArgumentException(); + } +} diff --git a/src/main/java/Parser.java b/src/main/java/Parser.java new file mode 100644 index 0000000000..d0db3c5621 --- /dev/null +++ b/src/main/java/Parser.java @@ -0,0 +1,46 @@ +/** + * Makes sense of the user's input and allocate them to the different commands. + */ + +public class Parser { + + /** + * Breaks down the user's input to allocate to the different commands. + * @param userInput the command that the user typed in. + * @return command. + * @throws IndexOutOfBoundsException when one of the method throws IndexOutOfBoundsException. + * @throws IllegalArgumentException when one of the method throws IllegalArgumentException. + */ + + public static Command parseInput(String userInput) throws IndexOutOfBoundsException, IllegalArgumentException { + String[] separatedUserInput = userInput.trim().split(" "); + String firstWordOfUserInput = separatedUserInput[0]; + Command command; + switch (firstWordOfUserInput) { + case "todo": + command = new TodoCommand(userInput); + break; + case "event": + command = new EventCommand(userInput); + break; + case "deadline": + command = new DeadlineCommand(userInput); + break; + case "done": + command = new DoneCommand(userInput); + break; + case "delete": + command = new DeleteCommand(userInput); + break; + case "list": + command = new ListCommand(userInput); + break; + case "find": + command = new FindCommand(userInput); + default: + command = new NoSuchCommand(userInput); + break; + } + return command; + } +} diff --git a/src/main/java/Storage.java b/src/main/java/Storage.java new file mode 100644 index 0000000000..c57eaacc80 --- /dev/null +++ b/src/main/java/Storage.java @@ -0,0 +1,43 @@ +import java.io.PrintWriter; +import java.io.FileNotFoundException; + +/** + * Activated when the list is requested. Generates a text file from the list automatically. + */ + +public class Storage { + + /** + * The output seen in the text file. + */ + private String output; + + /** + * Constructor for Storage. + */ + + public Storage() { + this.output = ""; + } + + /** + * Adds new text to the output. + * @param newString the string to be added on. + */ + + public void addToList(String newString) { + output += (newString + "\n"); + } + + /** + * Generates the text file of the list of tasks. + */ + + public void storeList() { + try (PrintWriter printer = new PrintWriter("out.txt")) { + printer.println(output); + } catch (FileNotFoundException exception) { + System.out.println(exception.getMessage()); + } + } +} diff --git a/src/main/java/Task.java b/src/main/java/Task.java new file mode 100644 index 0000000000..d43d8b66ac --- /dev/null +++ b/src/main/java/Task.java @@ -0,0 +1,81 @@ +/** + * Contains all the information needed to construct a Task object. + */ + +public class Task { + + /** + * Descrption of the task. + */ + + protected String taskName; + + /** + * Status of completion of the task. + */ + + protected boolean isDone; + + /** + * The task index number. + */ + + protected int taskId; + + /** + * The total number of tasks that has been inputted by the user. + */ + + protected static int totalNumOfTasks = 0; + + /** + * Constructor for Task. + * @param taskName description of the task as stated by the user. + */ + + public Task(String taskName) { + this.taskName = taskName; + this.isDone = false; + this.taskId = ++this.totalNumOfTasks; + } + + /** + * To mark a task as completed. + */ + + public void setDone() { + this.isDone = true; + System.out.println("Nice! I've marked this task as done:\n" + + String.format("[✓] %s", this.taskName)); + } + + /** + * To get the task index number. + * @return taskId. + */ + public int getTaskId() { + return taskId; + } + + /** + * Gives the status of completion of the task. + * @return status of completion of the task. + */ + + public boolean isDone() { + return isDone; + } + + public String getTaskName() { + return taskName; + } + + /** + * Gives the total number of tasks that the user has inputted so far. + * @return total number of tasks. + */ + + public static int getTotalNumOfTasks() { + return totalNumOfTasks; + } +} diff --git a/src/main/java/TextUi.java b/src/main/java/TextUi.java new file mode 100644 index 0000000000..bef962c02d --- /dev/null +++ b/src/main/java/TextUi.java @@ -0,0 +1,56 @@ +/** + * Stores instructions to print frequently displayed messages. + */ + +public class TextUi { + + //private boolean isUserDone; + + /** + * Constructor for TextUi. + */ + public TextUi() { + //this.isUserDone = false; + } + + public void printWelcomeMessage() { + System.out.println(Messages.WELCOME_MESSAGE); + } + + public void printExitMessage() { + System.out.println(Messages.EXIT_MESSAGE); + } + + public void printIndexOutOfBoundsExceptionMessage(Exception exception) { + System.out.println("You have given the wrong number of arguments or the wrong set of arguments\n" + + "Please try again or input \"bye\" to exit"); + } + + public void printIllegalArgumentExceptionMessage(Exception exception) { + System.out.println("Sorry I don't understand that command.\n" + Messages.LIST_OF_COMMANDS); + } + + public void printTodoMessage(Task task) { + System.out.println("Got it. I've added this task:\n " + task.toString() + + String.format("\nNow you have %d tasks in the list.", Duke.tasks.size())); + } + + public void printDeadlineMessage(Task task) { + System.out.println("Got it. I've added this task:\n " + task.toString() + + String.format("\nNow you have %d tasks in the list.", Duke.tasks.size())); + } + + public void printEventMessage(Task task) { + System.out.println("Got it. I've added this task:\n " + task.toString() + + String.format("\nNow you have %d tasks in the list.", Duke.tasks.size())); + } + + public void printDeleteMessage(Task task, int numOfTasksLeft) { + System.out.println("I have removed this task:\n" + task.toString() + + String.format("\nYou only have %d tasks left to do. 加油!", numOfTasksLeft)); + } + + public void printFindMessage(String command) { + System.out.println("The following may be relevant to what you are looking for:"); + } +} diff --git a/src/main/java/ToDo.java b/src/main/java/ToDo.java new file mode 100644 index 0000000000..1a5f323902 --- /dev/null +++ b/src/main/java/ToDo.java @@ -0,0 +1,20 @@ +/** + * Extends from Task. Stores the information needed for ToDo. + */ + +public class ToDo extends Task { + + /** + * Constructor for ToDo. + * @param taskName description of the toDo. + */ + + public ToDo(String taskName) { + super(taskName); + } + + @Override + public String toString() { + return String.format("[T][%c] %s", isDone() ? '✓' : '✗', taskName); + } +} diff --git a/src/main/java/TodoCommand.java b/src/main/java/TodoCommand.java new file mode 100644 index 0000000000..18df91bb05 --- /dev/null +++ b/src/main/java/TodoCommand.java @@ -0,0 +1,26 @@ +/** + * Extends from Command. Gives instructions on how to proceed when a ToDo task is added. + */ + +public class TodoCommand extends Command { + + /** + * Creates a new ToDo task as requested by the user. + */ + + private ToDo todo; + + /** + * Constructor for TodoCommand. + * @param command the command that the user typed in. + * @throws IndexOutOfBoundsException throws IndexOutOfBoundsException when there are invalid arguments. + */ + + public TodoCommand(String command) throws IndexOutOfBoundsException { + super(command); + todo = new ToDo(command.substring(5)); + Duke.tasks.add(todo); + textUi.printTodoMessage(todo); + + } +} diff --git a/text-ui-test/runtest.bat b/text-ui-test/runtest.bat new file mode 100644 index 0000000000..cce4731c3b --- /dev/null +++ b/text-ui-test/runtest.bat @@ -0,0 +1,21 @@ +@ECHO OFF + +REM create bin directory if it doesn't exist +if not exist ..\bin mkdir ..\bin + +REM delete output from previous run +del ACTUAL.TXT + +REM compile the code into the bin folder +javac -cp ..\src -Xlint:none -d ..\bin ..\src\main\java\Duke.java +IF ERRORLEVEL 1 ( + echo ********** BUILD FAILURE ********** + exit /b 1 +) +REM no error here, errorlevel == 0 + +REM run the program, feed commands from input.txt file and redirect the output to the ACTUAL.TXT +java -classpath ..\bin Duke < input.txt > ACTUAL.TXT + +REM compare the output to the expected output +FC ACTUAL.TXT EXPECTED.TXT \ No newline at end of file