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

[Rebecca Lau] iP #476

Open
wants to merge 55 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
d839859
Add Gradle support
May 24, 2020
dce5cee
Level-1
rebeccalaujx Aug 19, 2021
247ac39
Level-2
rebeccalaujx Aug 19, 2021
78ea29d
Level-3
rebeccalaujx Aug 19, 2021
f15709b
Level-3
rebeccalaujx Aug 19, 2021
6a5d0e8
Level-4
rebeccalaujx Aug 19, 2021
0be4686
A-TextUiTesting
rebeccalaujx Aug 19, 2021
5cb8123
A-TextUiTesting
rebeccalaujx Aug 19, 2021
0c57b93
Level-5
rebeccalaujx Aug 19, 2021
310178c
Level-5
rebeccalaujx Aug 19, 2021
1cbdef7
Level-6
rebeccalaujx Aug 19, 2021
fd0bb3d
save tasks to hard disk
rebeccalaujx Aug 28, 2021
2ae58cc
changes dates into a MMM dd yyyy format
rebeccalaujx Aug 30, 2021
2fcd257
save tasks to disk
rebeccalaujx Aug 30, 2021
f2aedc3
merged branch 7
rebeccalaujx Aug 30, 2021
e6a51b1
change dates to MMM dd yyyy format
rebeccalaujx Aug 30, 2021
fe0ff94
merged branch 8
rebeccalaujx Aug 30, 2021
e4ad385
add more OOP
rebeccalaujx Sep 1, 2021
8e90406
added some OOP
rebeccalaujx Sep 1, 2021
c27673f
added more oop
rebeccalaujx Sep 1, 2021
7fb685b
add files to packages
rebeccalaujx Sep 1, 2021
cb8b508
added JUnit tests
rebeccalaujx Sep 1, 2021
e48c0b5
packaged the app as an executable JAR file
rebeccalaujx Sep 1, 2021
b4758be
added JavaDocs
rebeccalaujx Sep 2, 2021
f14f614
Tweaked the code to comply with a coding standard
rebeccalaujx Sep 2, 2021
db642c7
Gave users a way to find a task by searching for a keyword
rebeccalaujx Sep 2, 2021
80db064
Merge branch 'branch-A-JavaDoc' and 'branch-A-CodingStandard'
rebeccalaujx Sep 2, 2021
621657a
Merge branch 'branch-Level-9'
rebeccalaujx Sep 2, 2021
07cb01c
Merge branch 'add-gradle-support' of https://github.com/rebeccalaujx/…
rebeccalaujx Sep 5, 2021
87995c8
Automate project builds using Gradle and fixed some checkstyle errors
rebeccalaujx Sep 6, 2021
db907f2
fixed checkstyle issues
rebeccalaujx Sep 6, 2021
9cf988a
created basic GUI for Duke
rebeccalaujx Sep 6, 2021
c6cc3a3
used FXML for GUI
rebeccalaujx Sep 7, 2021
0972eb4
merge branch-Level-10
rebeccalaujx Sep 7, 2021
a4dd0df
Ui class: cleaned up comments
rebeccalaujx Sep 16, 2021
cc9a2e4
Add assertions feature
rebeccalaujx Sep 16, 2021
2f301dd
Improve code quality
rebeccalaujx Sep 16, 2021
20a4b9e
Merge pull request #2 from rebeccalaujx/branch-Assertions
rebeccalaujx Sep 16, 2021
b77329f
Merge pull request #1 from rebeccalaujx/branch-Assertions
rebeccalaujx Sep 16, 2021
c053484
Merge branch 'master' into branch-Assertions and branch-CodeQuality
rebeccalaujx Sep 16, 2021
2ef64a7
Merge pull request #3 from rebeccalaujx/branch-CodeQuality
rebeccalaujx Sep 16, 2021
f29ff73
Add C-MassOps
rebeccalaujx Sep 16, 2021
35b27e9
Add varargs
rebeccalaujx Sep 16, 2021
86cd0e0
Update docs/README.md
rebeccalaujx Sep 17, 2021
9931a27
Update docs/README.md
rebeccalaujx Sep 17, 2021
2e44079
Update docs/README.md
rebeccalaujx Sep 17, 2021
fcab3b7
Update docs/README.md
rebeccalaujx Sep 17, 2021
764206d
Add Ui.png
rebeccalaujx Sep 17, 2021
7f34564
Fix Storage function
rebeccalaujx Sep 17, 2021
9dcab1a
Update JavaDocs
rebeccalaujx Sep 17, 2021
308fc97
Improve GUI
rebeccalaujx Sep 17, 2021
454e98a
Fix Storage
rebeccalaujx Sep 17, 2021
1bb04c1
change class path
rebeccalaujx Sep 17, 2021
1e77943
fix Storage
rebeccalaujx Sep 17, 2021
da29a26
Update Ui.png
rebeccalaujx Sep 17, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Duke project template
# duke.Duke project template

This is a project template for a greenfield Java project. It's named after the Java mascot _Duke_. Given below are instructions on how to use it.

Expand All @@ -13,7 +13,7 @@ Prerequisites: JDK 11, update Intellij to the most recent version.
1. If there are any further prompts, accept the defaults.
1. Configure the project to use **JDK 11** (not other versions) as explained in [here](https://www.jetbrains.com/help/idea/sdk.html#set-up-jdk).<br>
In the same dialog, set the **Project language level** field to the `SDK default` option.
3. After that, locate the `src/main/java/Duke.java` file, right-click it, and choose `Run Duke.main()` (if the code editor is showing compile errors, try restarting the IDE). If the setup is correct, you should see something like the below as the output:
3. After that, locate the `src/main/java/duke.Duke.java` file, right-click it, and choose `Run duke.Duke.main()` (if the code editor is showing compile errors, try restarting the IDE). If the setup is correct, you should see something like the below as the output:
```
Hello from
____ _
Expand Down
Empty file added duke.txt
Empty file.
10 changes: 0 additions & 10 deletions src/main/java/Duke.java

This file was deleted.

49 changes: 49 additions & 0 deletions src/main/java/duke/Duke.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package duke;

import duke.command.Command;
import duke.task.TaskList;

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 {
System.out.println(storage.load());
tasks = storage.load();
} catch (DukeException e) {
ui.showError(e.getMessage());
tasks = new TaskList();
} catch (IOException e) {
ui.showError(e.getMessage());
}
}

public void run() {
ui.showWelcome();
boolean isExit = false;
while (!isExit) {
try {
String fullCommand = ui.readCommand();
ui.showLine(); // show the divider line ("_______")
Command c = Parser.parse(fullCommand);
c.execute(tasks, ui, storage);
isExit = c.isExit();
} catch (DukeException e) {
ui.showError(e.getMessage());
} finally {
ui.showLine();
}
}
}

public static void main(String[] args) {
new Duke("duke.txt").run();
}
}
7 changes: 7 additions & 0 deletions src/main/java/duke/DukeException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package duke;

public class DukeException extends Exception {
public DukeException(String message) {
super(message);
}
}
25 changes: 25 additions & 0 deletions src/main/java/duke/Parser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package duke;

import duke.command.*;
Copy link

Choose a reason for hiding this comment

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

Would be better to specifically list all duke.command imports here instead of using wildcard imports

Choose a reason for hiding this comment

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

Is it better to not use wildcard for the import? It might be better to list all the stuff you want to import.


public class Parser {
public static Command parse(String input) throws DukeException {
if (input.equals("bye")) {
return new ExitCommand();
} else if (input.equals("list")) {
return new ListCommand();
} else if (input.startsWith("done")) {
return new DoneCommand(input);
} else if (input.startsWith("delete")) {
return new DeleteCommand(input);
} else if (input.startsWith("todo")) {
return new TodoCommand(input);
} else if (input.startsWith("deadline")) {
return new DeadlineCommand(input);
} else if (input.startsWith("event")) {
return new EventCommand(input);
Copy link

Choose a reason for hiding this comment

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

Using input.startsWith("...") may cause some invalid commands to be interpreted as valid commands, e.g. when input starts with deadliner or todoy. Instead, consider using input.split(" ", 2) to get a String[], then check equality against the first element of the String[]. This way, the second element of the String[] also contains all the information you need for your Command subclasses later on.

} else {
return new ErrorCommand();
}
}
}
96 changes: 96 additions & 0 deletions src/main/java/duke/Storage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package duke;

import duke.task.*;
Copy link

Choose a reason for hiding this comment

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

Would be better to specifically list imports as before

Choose a reason for hiding this comment

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

It might be better to list all the stuff you want to import instead of using wildcard.


import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Scanner;

public class Storage {
String filePath;
PrintWriter writer;
TaskList ls;
Copy link

Choose a reason for hiding this comment

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

Would be good to add private access modifiers here


public Storage(String filePath) {
this.filePath = filePath;
}

public void rewriteFile(TaskList ls) {
this.ls = ls;
try {
FileWriter fw = new FileWriter(filePath, false);
writer = new PrintWriter(fw);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Comment on lines +46 to +50
Copy link

Choose a reason for hiding this comment

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

Possible to combine into a single catch statement here

Suggested change
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException | IOException e) {
e.printStackTrace();
}


for (int i = 0; i < ls.getSize(); i++) {
Task task = ls.getTask(i);
String type = task.getType();
String desc = task.getDesc();
String addOns = task.addOns();
if (type == "todo") {
writer.println("T" + (task.checkIfDone() ? " | 1 | " : " | 0 | ") + desc);
} else if (type == "deadline") {
writer.println("D" + (ls.getTask(i).checkIfDone() ? " | 1 | " : " | 0 | ")
+ desc + " | " + addOns);
} else if (type == "event") {
writer.println("E" + (task.checkIfDone() ? " | 1 | " : " | 0 | ")
+ desc + " | " + addOns);
}
}
writer.close();
}

public TaskList load() throws IOException, DukeException {
TaskList ls = new TaskList();
Copy link

Choose a reason for hiding this comment

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

Instead of ls, a more readable variable name for your TaskList here could be tasks.

File directory = new File("duke.txt");
if (!directory.exists()) {
directory.mkdir();
}
File data = new File(filePath);
data.createNewFile();
Scanner s = new Scanner(data);
while (s.hasNext()) {
ls.addTask(parseTask(s.nextLine()));
}
return ls;
}

public Task parseTask(String input) throws DukeException {
if (input.startsWith("T")) {
String taskDesc = input.substring(7);
Todo tTask = new Todo(taskDesc);
return tTask;
} else if (input.startsWith("D")) {
String taskDesc = input.substring(7);
String taskDate = getDate(input);
Deadline dTask = new Deadline(taskDesc, taskDate);
return dTask;
} else {
String taskDesc = input.substring(7);
String taskDate = getDate(input);
Event eTask = new Event(taskDesc, taskDate);
return eTask;
}
Copy link

Choose a reason for hiding this comment

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

Could potentially improve readability by renaming tTask, dTask and eTask into todo, deadline and event respectively.

}

public String getDate(String input) {
int endIndex = 0;
int count = 0;
for (int i = 0; i < input.length(); i++) {
if (input.charAt(i) == '|') {
if (count == 3) {
endIndex = i;
}
}
}
return input.substring(endIndex);
Copy link

Choose a reason for hiding this comment

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

Could potentially shorten code by using input.split("|") to get a String[], then return the last element of the String[].

}

}
66 changes: 66 additions & 0 deletions src/main/java/duke/Ui.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package duke;

import duke.task.Task;
import duke.task.TaskList;

import java.util.Scanner;

public class Ui {
private Scanner sc;
private String input = "";

public Ui() {
this.sc = new Scanner(System.in);
}

public void showWelcome() {
String logo = " ____ _ \n"
+ "| _ \\ _ _| | _____ \n"
+ "| | | | | | | |/ / _ \\\n"
+ "| |_| | |_| | < __/\n"
+ "|____/ \\__,_|_|\\_\\___|\n";
System.out.println("Hello from\n" + logo);
System.out.println("Hello! I'm duke.Duke\n" + "What can I do for you?");

Choose a reason for hiding this comment

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

You may import the duke package inside, and you not really have to specify package all the time.

}

public void goodbye() {
System.out.println("Bye. Hope to see you again soon!");
}

public void addTaskToList(Task task, int size) {
String taskToString = task.toString();
System.out.println("Got it. I've added this task: \n" + taskToString
+ "\nNow you have " + size + " tasks in the list.");
}

public void removeTaskFromList(Task task, int size) {
String taskToString = task.toString();
System.out.println("Noted. I've removed this task: \n" +
taskToString
+ "\nNow you have " + size + " tasks in the list.");
}
Copy link

Choose a reason for hiding this comment

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

It's possible to just use task here as the conversion to String type is done implicitly (like how you don't have to convert size to a String).

Suggested change
public void addTaskToList(Task task, int size) {
String taskToString = task.toString();
System.out.println("Got it. I've added this task: \n" + taskToString
+ "\nNow you have " + size + " tasks in the list.");
}
public void removeTaskFromList(Task task, int size) {
String taskToString = task.toString();
System.out.println("Noted. I've removed this task: \n" +
taskToString
+ "\nNow you have " + size + " tasks in the list.");
}
public void addTaskToList(Task task, int size) {
System.out.println("Got it. I've added this task: \n" + task
+ "\nNow you have " + size + " tasks in the list.");
}
public void removeTaskFromList(Task task, int size) {
System.out.println("Noted. I've removed this task: \n" +
task
+ "\nNow you have " + size + " tasks in the list.");
}


public void printTaskList(TaskList taskList) {
if (taskList.getSize() == 0) {
System.out.println("There are currently no tasks in your list.");
} else {
System.out.println("Here are the tasks in your list:");
for (int i = 0; i < taskList.getSize(); i++) {
System.out.println((i + 1) + "." + taskList.getTask(i).toString());
}
}
}

public String readCommand() {
return sc.nextLine();
}

public void showError(String e) {
System.out.println(e);
}

public void showLine() {
System.out.println("___________________");
}

}
10 changes: 10 additions & 0 deletions src/main/java/duke/command/Command.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package duke.command;
import duke.task.TaskList;
import duke.Ui;
import duke.Storage;
import duke.DukeException;

public abstract class Command {
public abstract void execute(TaskList ls, Ui ui, Storage storage) throws DukeException;
public abstract boolean isExit();
Copy link

Choose a reason for hiding this comment

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

Since all but one of the commands have isExit() as false, this can be made into a non-abstract method.

Suggested change
public abstract boolean isExit();
public boolean isExit() {
return false;
}

}
34 changes: 34 additions & 0 deletions src/main/java/duke/command/DeadlineCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package duke.command;
import duke.Ui;
import duke.Storage;
import duke.DukeException;
import duke.task.TaskList;
import duke.task.Deadline;

public class DeadlineCommand extends Command {

private String input;
private String taskDesc;
private String deadline;

public DeadlineCommand(String input) {
this.input = input;
this.taskDesc = input.replaceFirst("^deadline", "").split(" /")[0];
if (input.contains("/by")) {
this.deadline = input.substring(input.indexOf("/by") + 4);
}
}

@Override
public void execute(TaskList ls, Ui ui, Storage storage) throws DukeException {
Deadline dTask = new Deadline(taskDesc, deadline);
ls.addTask(dTask);
storage.rewriteFile(ls);
}

@Override
public boolean isExit() {
return false;
}
Comment on lines +49 to +52
Copy link

Choose a reason for hiding this comment

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

After the non-abstract isExit() is implemented in Command.java, there's no need to override here (and all commands except ExitCommand.java) anymore.


}
37 changes: 37 additions & 0 deletions src/main/java/duke/command/DeleteCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package duke.command;
import duke.Ui;
import duke.Storage;
import duke.DukeException;
import duke.task.TaskList;
import duke.task.Task;

public class DeleteCommand extends Command {
private String input;
private int taskNumber;

public DeleteCommand(String input) throws DukeException {
this.input = input;
try {
if (input.equals("delete") || input.equals("delete ")) {
Copy link

Choose a reason for hiding this comment

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

This can be avoided if the input.split(" ", 2) method is used in Parser.java, in which case you can just check if the second element of the String[] is empty.

throw new DukeException("A number must follow after the command word 'delete'.");
}
this.taskNumber = Integer.valueOf(input.substring(7)) - 1;
} catch (NumberFormatException e) {
throw new DukeException("OOPS! Please enter a valid task number.");
}
}

@Override
public void execute(TaskList ls, Ui ui, Storage storage) throws DukeException {
if (taskNumber < 0 || taskNumber >= ls.getSize()) {
throw new DukeException("Item does not exist in the list.");
}
ls.removeTask(taskNumber);
storage.rewriteFile(ls);
}

@Override
public boolean isExit() {
return false;
}
}
38 changes: 38 additions & 0 deletions src/main/java/duke/command/DoneCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package duke.command;
import duke.Ui;
import duke.Storage;
import duke.DukeException;
import duke.task.TaskList;
import duke.task.Task;

public class DoneCommand extends Command {
private String input;
private int taskNumber;

public DoneCommand(String input) throws DukeException {
this.input = input;
try {
if (input.equals("done") || input.equals("done ")) {
throw new DukeException("A number must follow after the command word 'done'.");
}
this.taskNumber = Integer.valueOf(input.substring(5)) - 1;;
} catch (NumberFormatException e) {
throw new DukeException("OOPS! Please enter a valid task number.");
}
}

@Override
public void execute(TaskList ls, Ui ui, Storage storage) throws DukeException {
if (taskNumber < 0 || taskNumber >= ls.getSize()) {
throw new DukeException("Item does not exist in the list.");
}
Task task = ls.getTask(taskNumber);
task.markAsDone();
storage.rewriteFile(ls);
}

@Override
public boolean isExit() {
return false;
}
}
Loading