Skip to content

[chashaobao] iP - #640

Open
chashaobao123 wants to merge 45 commits into
nus-cs2103-AY2425S1:masterfrom
chashaobao123:master
Open

[chashaobao] iP#640
chashaobao123 wants to merge 45 commits into
nus-cs2103-AY2425S1:masterfrom
chashaobao123:master

Conversation

@chashaobao123

@chashaobao123 chashaobao123 commented Sep 3, 2024

Copy link
Copy Markdown

LittleMissHelpful

“Your mind is for having ideas, not holding them.” – David Allen

Ah Bang Mang frees your mind from remembering the things you need to do. It's:

  • Text-based
  • Easy to learn
  • SUPER FAST to use
  • Singlish Ui

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 the best part? It’s FREE!

Features:

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

If you are a Java programmer, you can use LittleMissHelpful to practice Java too! Here's the main method:

public static void main(String[] args) {
        new LittleMissHelpful("data/LittleMissHelpful.txt").run();
    }

damithc and others added 12 commits July 11, 2024 16:52
In build.gradle, the dependencies on distZip and/or distTar causes
the shadowJar task to generate a second JAR file for which the
mainClass.set("seedu.duke.Duke") does not take effect.
Hence, this additional JAR file cannot be run.
For this product, there is no need to generate a second JAR file
to begin with.

Let's remove this dependency from the build.gradle to prevent the
shadowJar task from generating the extra JAR file.
Comment thread src/main/java/LittleMissHelpful.java Outdated
loadTasks(list);

int counter = list.size();;
while (true) { // Continuous input

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Would it be better to refactor this part into the the Parse class as suggested in the project brief week 3?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

agreed! Separating all the parsing commands into a separate parse class could make the code look neater

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Yes, thank you! I have abstracted out the classes now

Comment thread src/main/java/LittleMissHelpful.java Outdated
System.out.println("Ok, I see you laze. You have marked this task as not done yet: " + curTask.toString());
System.out.println(lineBreak);
} catch (NumberFormatException e) {
System.out.println(lineBreak + "\nHai-yo, task number must be an integer lah.\n" + lineBreak);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This check looks the same as the check for the "mark" command, perhaps can refactor to reduce repetition?

Comment thread src/main/java/LittleMissHelpful.java Outdated
Task newTask = null;

try {
if (command.equalsIgnoreCase("todo")) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The switch and case statement may come in handy here. (frankly I also never use)

Comment thread src/main/java/LittleMissHelpful.java Outdated
} else {
// Invalid command --> throw exception
System.out.println(
lineBreak + "\nAlamak! Format salah already... Please provide a valid command and description.\n" + lineBreak);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Perhaps can provide some descriptions of what are valid commands

Comment thread src/main/java/Deadline.java Outdated
@@ -0,0 +1,18 @@
public class Deadline extends Task {
protected String by;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Would it make sense to save the string as Java Datetime instead?

Comment thread src/main/java/LittleMissHelpful.java Outdated
public class LittleMissHelpful {
private static final String FILE_PATH = "./data/LittleMissHelpfullist.txt";
public static void main(String[] args) {
/**

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Maybe you can add this comment in the header instead? (i.e. before the public class in Line 10) It may help others to understand your code purpose better!

Comment thread src/main/java/LittleMissHelpful.java Outdated
loadTasks(list);

int counter = list.size();;
while (true) { // Continuous input

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

agreed! Separating all the parsing commands into a separate parse class could make the code look neater

Comment thread src/main/java/LittleMissHelpful.java Outdated

if (inputList.length < 2) {
// Check if the user command is "bye" -> exit
if (command.equalsIgnoreCase("bye")) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Maybe you could separate the UI related code to a UI class?

Comment thread src/main/java/Task.java Outdated
@@ -0,0 +1,112 @@
public class Task {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Could you consider adding header comments to the classes? Saw this problem in some other classes too.

Comment thread src/main/java/Task.java Outdated
protected String description;
protected boolean isDone;

public Task (String description) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

An idea is that you could make this into an abstract class and have the different methods for the different classes in their respective class files! It's just an alternative way to do it that you can consider.

@frymash frymash left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

In general, I think your code is really well-organised and well-abstracted. This is the first time I've seen someone create a Java file for each command. I also like the vibes your bot's responses give. Good job! LGTM.

@@ -0,0 +1,59 @@
package main.LittleMissHelpful;
import java.util.ArrayList;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Small suggestion involving code consistency but I noticed some files have a line of space between the package statement and the import statement while other files don't. The course's coding standard doesn't really prescribe a set way to go about this, but perhaps you could consider either using one or the other.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Thank you for your feedback! I'll be sure to edit this

Comment thread src/main/java/LittleMissHelpful/Ui.java Outdated
import main.LittleMissHelpful.Task.Task;

public class Ui {
private static final String LINE_BREAK = "---------------------------------";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Good practice to make the divider a constant so that you don't have to repeat yourself whenever you use it.

Comment on lines +53 to +79
if (parts.length < 3) {
throw new InvalidTaskFormatException("Invalid task format: " + taskString);
}

String taskType = parts[0];
boolean isDone = parts[1].equals("1");
String description = parts[2];

// Check task type and create corresponding Task
if (taskType.equals("T")) {
return new Todo(description, isDone);

} else if (taskType.equals("D")) {
if (parts.length != 4) {
throw new InvalidTaskFormatException("Invalid Deadline format: " + taskString);
}
LocalDateTime by = LocalDateTime.parse(parts[3]);
return new Deadline(description, isDone, by);

} else if (taskType.equals("E")) {
if (parts.length != 5) {
throw new InvalidTaskFormatException("Invalid Event format: " + taskString);
}

LocalDateTime from = LocalDateTime.parse(parts[3]);
LocalDateTime to = LocalDateTime.parse(parts[4]);
return new Event(description, isDone, from, to);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Could possibly refactor the if-else statement into a switch-case statement (not 100% necessary but a suggestion).

Comment on lines +99 to +117
if (this instanceof Todo) {
taskType = "T";
description = this.description;
return taskType + spacer + isDone + spacer + description;

} else if (this instanceof Deadline d) {
taskType = "D";
description = d.description;
by = d.by;
return taskType + spacer + isDone + spacer + description + spacer + by;

} else if (this instanceof Event e) {
taskType = "E";
description = e.description;
from = e.from;
to = e.to;
return taskType + spacer + isDone + spacer + description + spacer + from + spacer + to;
} else {
throw new InvalidTaskFormatException("Cannot write task: " + this.toString());

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Was wondering if the switch-case syntax would be more idiomatic here too

@JoanneHing JoanneHing left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Overall LGTM! The naming for class , method and variables is well done and convey their purposes clear!

Would be nice if header comments could be added to class and the public method as part of JavaDoc!

Well done!

import LittleMissHelpful.Ui;
import LittleMissHelpful.Exception.InvalidCommandException;
import LittleMissHelpful.Task.Deadline;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The header comment for the class might be missed out, will be good if it could be added in

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The header comment for the class and the public methods is also missed out here, would be nice to add in!

if (dateTimeString.equalsIgnoreCase("today")) {
// Use current date and set time to 00:00 (start of the day)
return LocalDateTime.now().withHour(00).withMinute(00);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

line breaks could be added here to seperate the section and make the code more readabel : )

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

missing header comment for the class too

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

same as above

Comment on lines +34 to +72
switch (command) {
case "mark":
return new MarkTaskCommand(Integer.parseInt(item));

case "unmark":
return new UnmarkTaskCommand(Integer.parseInt(item));

case "delete":
return new DeleteTaskCommand(Integer.parseInt(item));

case "find":
return new FindCommand(item);

case "todo":
return new AddTodoCommand(item);

case "deadline":
String[] deadlineParts = item.split("/by", 2);
if (deadlineParts.length < 2) {
throw new InvalidCommandException("Invalid deadline format. Use 'deadline description /by date'.");
}
String deadlineDesc = deadlineParts[0].trim();
String deadlineBy = deadlineParts[1].trim();
return new AddDeadlineCommand(deadlineDesc, deadlineBy);

case "event":
String[] eventParts = item.split("/from | /to", 3);
if (eventParts.length < 3) {
throw new InvalidCommandException("Invalid event format. Use 'event description /from start /to end'.");
}
String eventDesc = eventParts[0].trim();
String eventFrom = eventParts[1].trim();
String eventTo = eventParts[2].trim();
return new AddEventCommand(eventDesc, eventFrom, eventTo);

default:
throw new InvalidCommandException("Invalid command. Please provide a valid command.");
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

the case should not be indented, would be nice if it is fixed!

import LittleMissHelpful.Ui;
import LittleMissHelpful.Exception.InvalidCommandException;
import LittleMissHelpful.Task.Event;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The commands naming is named well! Easy to understand what the class is handling!

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The exceptions class name is named well to let developer understand what exception it is handling too! Well done!

}
}

String item = inputList[1];

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Maybe item could be named to taskIndex for better understanding?

Comment on lines +23 to +41
// public Event(String description, LocalDate from, LocalDate to) {
// /**
// * Instatiate event without needing to input time
// * Defaults from time to start of the day and end time to end of the day
// */
// super(description);
// this.from = from.atStartOfDay(); // Set default time to start of day
// this.to = to.atStartOfDay().plusDays(1).minusSeconds(1); // Set end of day time
// }

// public Event(String description, boolean isDone, LocalDate from, LocalDate to) {
// /**
// * Instatiate event without needing to input time && isDone
// * Defaults from time to start of the day and end time to end of the day
// */
// super(description, isDone);
// this.from = from.atStartOfDay(); // Set default time to start of day
// this.to = to.atStartOfDay().plusDays(1).minusSeconds(1); // Set end of day time
// }

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

can consider removing unused code to improve code quality

chashaobao123 added 2 commits September 7, 2024 00:58
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.

7 participants