Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Cheong Yee Ming] iP #462

Open
wants to merge 36 commits into
base: master
Choose a base branch
from

Conversation

CheongYeeMing
Copy link

@CheongYeeMing CheongYeeMing commented Aug 25, 2021

Duke

"The way to get started is to quit talking and begin doing." -Walt Disney (source)

DukePro frees your mind of having to remember things you need to do. It's,

  • text-based
  • easy to learn
  • FAST SUPER FAST to use

All you need to do is

  1. download it from here.
  2. double-click it.
  3. add your tasks.
  4. let it manage your tasks for you 😉

And it is FREE!

Features:

  • Managing tasks
  • Managing deadlines (coming soon)
  • Reminders (coming soon)

If you Java programmer, you can use it to practice Java too. Here's the main method:

public class Main {
    public static void main(String[] args) {
        Application.launch(MainApp.class, args);
    }
}

Copy link

@pualixue pualixue left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Just some nits to fix.

}

/**
*

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the method summary missing?

* Saves tasks in TaskList to local directory.
* Folder and file will be created if not already present.
*
* @param taskList

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like how the descriptions have the same indentation which makes it easy to read. 👍

Copy link

@whoisjustinngo whoisjustinngo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, just some minor cosmetic issues to consider 🥇

*
* @throws DukeException when an error occurs.
*/
public abstract void runCommand() throws DukeException;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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(" ");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using a noun like userInputTokens instead of splitUserInput

Comment on lines 101 to 143
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);
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps tasks would be more descriptive than list

Comment on lines 57 to 83
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);
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like how clean and neat this is 👍🏼

Copy link

@chengseong chengseong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Just a few nits with the JavaDocs but generally looks great!

@@ -5,14 +5,33 @@
import duke.task.TaskList;
import duke.ui.Ui;

/**
* Command to add a task to the task list.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be good to document down what is contained in each Command

public abstract class Command {
protected final TaskList taskList;
protected final Storage storage;
protected final Ui ui;

/**
* Constructor for a DukeCommand.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

*
* @author Cheong Yee Ming
* @version Duke A-JavaDoc
*/
public class Deadline extends Task {

protected final LocalDateTime by;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A name like by is not really descriptive enough. Maybe consider something like deadline.

*
* @author Cheong Yee Ming
* @version Duke A-JavaDoc
*/
public class Event extends Task {

protected final LocalDateTime at;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as by, at is not very descriptive

CheongYeeMing and others added 10 commits September 7, 2021 04:52
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.
For loops used for iteration.

Too many lines of code, does not look good.

Replace for loops with streams.

Benefits of streams:
* Write functions at more abstract level
* Make code more expressive
* Less verbose code
* More Intuitive code
* Less error prone code
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants