[Cheong Yee Ming] iP#462
Conversation
| } | ||
|
|
||
| /** | ||
| * |
| * Saves tasks in TaskList to local directory. | ||
| * Folder and file will be created if not already present. | ||
| * | ||
| * @param taskList |
There was a problem hiding this comment.
Is the description of taskList missing?
| * @param task Task to be added into task list. | ||
| * @param taskLeft Total number of tasks in the task list. | ||
| */ | ||
| public void taskAddedMessage(Task task, int taskLeft) { |
There was a problem hiding this comment.
Perhaps this method name can be changed to a verb (i.e. printTaskAddedMessage)?
Similarly for some of the methods below.
| /** | ||
| * Constructor for an AddCommand. | ||
| * | ||
| * @param taskList Handles all operations regarding tasks. |
There was a problem hiding this comment.
I like how the descriptions have the same indentation which makes it easy to read. 👍
whoisjustinngo
left a comment
There was a problem hiding this comment.
LGTM, just some minor cosmetic issues to consider 🥇
| * | ||
| * @throws DukeException when an error occurs. | ||
| */ | ||
| public abstract void runCommand() throws DukeException; |
There was a problem hiding this comment.
Maybe you can consider renaming the method execute or simply run to clearly distinguish the method to run the command from the type of command (i.e. AddCommand, DeleteCommand etc.)
| * @throws DukeException If user input is invalid. | ||
| */ | ||
| public Command parseUserInput(String userInput) throws DukeException { | ||
| String[] splitUserInput = userInput.split(" "); |
There was a problem hiding this comment.
Consider using a noun like userInputTokens instead of splitUserInput
| case DEADLINE: | ||
| try { | ||
| int byIndex = commandDetails.indexOf("/by") - 1 ; | ||
| if (byIndex <= 0) { | ||
| throw new NoDateTimeException(ui); | ||
| } | ||
| String deadlineDetails = commandDetails.substring(0, byIndex); | ||
| if (deadlineDetails.isBlank()) { | ||
| throw new NoTaskDescriptionException(ui); | ||
| } | ||
| try { | ||
| LocalDateTime by = LocalDateTime.parse(commandDetails.substring(deadlineDetails.indexOf("by") + 3), | ||
| DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")); | ||
| return new Deadline(deadlineDetails, false, by); | ||
| } catch (DateTimeParseException e) { | ||
| throw new InvalidDateTimeException(ui); | ||
| } | ||
| } catch (StringIndexOutOfBoundsException e) { | ||
| throw new NoTaskDescriptionException(ui); | ||
| } | ||
|
|
||
|
|
||
| case EVENT: | ||
| try { | ||
| int atIndex = commandDetails.indexOf("/at") - 1 ; | ||
| if (atIndex <= 0) { | ||
| throw new NoDateTimeException(ui); | ||
| } | ||
| String eventDetails = commandDetails.substring(0, atIndex); | ||
| if (eventDetails.isBlank()) { | ||
| throw new NoTaskDescriptionException(ui); | ||
| } | ||
| try { | ||
| LocalDateTime at = LocalDateTime.parse(commandDetails.substring(eventDetails.indexOf("at") + 3), | ||
| DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")); | ||
| return new Event(eventDetails, false, at); | ||
| } catch (DateTimeParseException e) { | ||
| throw new InvalidDateTimeException(ui); | ||
| } | ||
| } catch (StringIndexOutOfBoundsException e) { | ||
| throw new NoTaskDescriptionException(ui); | ||
| } | ||
|
|
There was a problem hiding this comment.
The code in the Deadline and Event cases are very similar hence I think you could combine both into one case; alternatively, assuming all taskType inputs are valid, consider the ToDo case first and let the Deadline and Event be the default. To account for the 'by' and 'at' issue, maybe you can define an auxiliary delimiter string, if event then the string is 'at', else 'by'. This might help significantly reduce code duplication 👍🏼
| */ | ||
| public class TaskList { | ||
|
|
||
| private ArrayList<Task> list; |
There was a problem hiding this comment.
Perhaps tasks would be more descriptive than list
| case "list": | ||
| return new ListCommand(taskList, storage, ui); | ||
|
|
||
| case "bye": | ||
| return new ExitCommand(taskList, storage, ui); | ||
|
|
||
| case "deadline": | ||
| return new AddCommand(taskList, storage, ui, parseTaskInput(TaskType.DEADLINE, userInput)); | ||
|
|
||
| case "event": | ||
| return new AddCommand(taskList, storage, ui, parseTaskInput(TaskType.EVENT, userInput)); | ||
|
|
||
| case "todo": | ||
| return new AddCommand(taskList, storage, ui, parseTaskInput(TaskType.TODO, userInput)); | ||
|
|
||
| case "done": | ||
| return new DoneCommand(taskList, storage, ui, Integer.parseInt(splitUserInput[1])); | ||
|
|
||
| case "delete": | ||
| return new DeleteCommand(taskList, storage, ui, Integer.parseInt(splitUserInput[1])); | ||
|
|
||
| case "find": | ||
| return new FindCommand(taskList, storage, ui, userInput.substring(userInput.indexOf(" ") + 1)); | ||
|
|
||
| default: | ||
| throw new NoSuchCommandException(ui); | ||
| } |
There was a problem hiding this comment.
I like how clean and neat this is 👍🏼
chengseong
left a comment
There was a problem hiding this comment.
LGTM! Just a few nits with the JavaDocs but generally looks great!
| import duke.ui.Ui; | ||
|
|
||
| /** | ||
| * Command to add a task to the task list. |
There was a problem hiding this comment.
I think it would be good to document down what is contained in each Command
| protected final Ui ui; | ||
|
|
||
| /** | ||
| * Constructor for a DukeCommand. |
There was a problem hiding this comment.
You mention a DukeCommand in the JavaDocs, but the constructor creates a Command, so it might be good to streamline this and standardize to 1 name for the Command class
| */ | ||
| public class Deadline extends Task { | ||
|
|
||
| protected final LocalDateTime by; |
There was a problem hiding this comment.
A name like by is not really descriptive enough. Maybe consider something like deadline.
| */ | ||
| public class Event extends Task { | ||
|
|
||
| protected final LocalDateTime at; |
There was a problem hiding this comment.
Same as by, at is not very descriptive
No assertions used in code. Assertions help detect programmer mistakes. Adding assert statement to the following classes: * `AddCommand` * `DeleteCommand` * `DoneCommand` * `Parser` * `Storage` * `Deadline` * `Task` * `TaskList` Assert statements are added in cases where `null` is passed into the respective `Task` constructors, detects empty tasks.
Nested class. Outer class now had 2 responsibilities. Breaches the Single Responsibility Principle. Extracting nested class `ExitProgram` within `Main` class. Avoid nesting of classes, adhere to Single Responsibility Principle.
A-CodeQuality
Duke
DukePro frees your mind of having to remember things you need to do. It's,
FASTSUPER FAST to useAll you need to do is
And it is FREE!
Features:
If you Java programmer, you can use it to practice Java too. Here's the
mainmethod: