Skip to content
Open
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
ad35520
Add Greet, Echo, and Exit functionality
junweimoo Aug 18, 2022
1dc859c
Add ability to store and retrieve inputs
junweimoo Aug 18, 2022
59433e5
Add ability mark and unmark tasks
junweimoo Aug 18, 2022
081e632
Support adding different types of tasks
junweimoo Aug 22, 2022
8eb1837
Add automated text UI testing
junweimoo Aug 22, 2022
ba8b47a
Handle input errors
junweimoo Aug 22, 2022
bd7449c
Add ability to delete tasks
junweimoo Aug 22, 2022
ebafc17
Refactor code for better readability
junweimoo Aug 22, 2022
9ba4bb1
Add ability to persist data using a save file
junweimoo Aug 31, 2022
7a0cdad
Store date as a LocalDate object instead of a String
junweimoo Aug 31, 2022
f95b100
Merge branch 'branch-Level-8'
junweimoo Aug 31, 2022
7615def
Fix printing of task date
junweimoo Aug 31, 2022
272b7b3
Refactor code to be more object-oriented
junweimoo Sep 1, 2022
596be76
Put all classes into the duke package
junweimoo Sep 1, 2022
a35099a
Add gradle
junweimoo Sep 1, 2022
e2a4b22
Add JUnit tests for DataParser and Parser
junweimoo Sep 1, 2022
a06d4d2
Refactor parsing code into separate classes
junweimoo Sep 2, 2022
b934cb3
Handle more invalid commands
junweimoo Sep 2, 2022
e074e85
Add find command to search the list of tasks
junweimoo Sep 9, 2022
c13b21c
Add JavaDoc comments
junweimoo Sep 9, 2022
2d069b3
Modify code to comply with the coding standard.
junweimoo Sep 9, 2022
d081eed
Merge branch 'branch-A-JavaDoc'
junweimoo Sep 9, 2022
5f24147
Merge branch 'branch-A-CodingStandard'
junweimoo Sep 9, 2022
05ec52e
Add JavaFX GUI
junweimoo Sep 9, 2022
3cfe83c
Improve code quality in InputParser
junweimoo Sep 12, 2022
5ba0b20
Merge pull request #2 from junweimoo/branch-A-CodeQuality
junweimoo Sep 12, 2022
06a22e5
Refactor parseCommand() in InputParser
junweimoo Sep 15, 2022
688825b
Add assertions to TaskList and Storage
junweimoo Sep 15, 2022
5700e9a
Merge pull request #3 from junweimoo/branch-A-Assertions
junweimoo Sep 15, 2022
a502a2e
Add ability to undo commands
junweimoo Sep 15, 2022
3b13d75
Merge pull request #4 from junweimoo/branch-BCD-Extension
junweimoo Sep 15, 2022
1b7f7b1
Remove unneeded Ui class
junweimoo Sep 15, 2022
3ccc405
Improve the GUI
junweimoo Sep 15, 2022
56d69f1
Fix truncation of longer lists by dialog boxes
junweimoo Sep 16, 2022
646856f
Add more JUnit tests
junweimoo Sep 16, 2022
f5995ab
Add user guide and screenshot
junweimoo Sep 16, 2022
d02ea3a
Refactor methods in Storage for better readability
junweimoo Sep 16, 2022
bf98f6b
Add JUnit Tests for Storage and TaskParser
junweimoo Sep 16, 2022
f54a9f6
Update user guide
junweimoo Sep 16, 2022
feba356
Add JavaDoc comments for public methods
junweimoo Sep 16, 2022
ca041f0
Improve the appearance of the GUI
junweimoo Sep 16, 2022
54e4652
Update UI screenshot
junweimoo Sep 16, 2022
3d11a0c
Improve handling of empty and invalid commands
junweimoo Sep 16, 2022
3332db6
Add more JUnit tests for UndoCommand and InputParser
junweimoo Sep 16, 2022
40568ee
Remove unused imports
junweimoo Sep 16, 2022
7da2071
Fix undo delete task to add task back to correct position
junweimoo Sep 16, 2022
7fc7be5
Add a welcome message
junweimoo Sep 16, 2022
76c5628
Fix indentation of switch statement
junweimoo Sep 16, 2022
fb1dd66
Add JavaDoc comments for constructors
junweimoo Sep 16, 2022
13de582
Add JavaDoc for classes
junweimoo Sep 16, 2022
bdae392
Update user guide
junweimoo Sep 16, 2022
c4ccc86
Update user guide
junweimoo Sep 16, 2022
87a48ee
Update user guide
junweimoo Sep 16, 2022
d52ccea
Add JavaDoc comments
junweimoo Sep 16, 2022
d25fd66
Update user guide
junweimoo Sep 16, 2022
dfb6231
Fix code style
junweimoo Sep 17, 2022
cf5d827
Make dialog box resize to fit text width
junweimoo Sep 17, 2022
68b4c2f
Update screenshot
junweimoo Sep 17, 2022
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
210 changes: 209 additions & 1 deletion src/main/java/Duke.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,218 @@
import exception.EmptyTaskDescException;
import exception.EmptyTaskTimeException;
import exception.NoSuchTaskException;
import tasks.*;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Scanner;

public class Duke {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

It would be great if javadocs are included :))


public enum TaskTypes {
TODO,
DEADLINE,
EVENT
}

private List<Task> taskList;
private SaveData data;
private static final File savefile = new File("savedata.txt");

public static void main(String[] args) {
String logo = " ____ _ \n"
+ "| _ \\ _ _| | _____ \n"
+ "| | | | | | | |/ / _ \\\n"
+ "| |_| | |_| | < __/\n"
+ "|____/ \\__,_|_|\\_\\___|\n";
System.out.println("Hello from\n" + logo);

Duke duke = new Duke();
duke.start();
}

public Duke() {

}

public void start() {
Scanner sc = new Scanner(System.in);
System.out.println(
"Hello! I'm Duke\n" +
"What can I do for you?"
);

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 perhaps break up the line before the operator, in accordance with the coding standards?

data = new SaveData();
boolean isSaveFileCreated = savefile.exists();
if (!isSaveFileCreated) {
try {
isSaveFileCreated = savefile.createNewFile();
} catch (IOException e) {
System.out.println("Error while creating save file: " + e);
}
}

if (!isSaveFileCreated) {
System.out.println("Unable to find or create save file, exiting...");
System.exit(1);
}

data.loadFromFile(new File("savedata.txt"));
taskList = data.getTaskList();
loop(sc);
}

public void loop(Scanner sc) {

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 method looks long and complex, could think of abstracting out key components into different methods?

while (sc.hasNext()) {
String input = sc.nextLine().trim();
int spaceIndex = input.indexOf(' ');
String command, body;
if (spaceIndex == -1) {
command = input;
body = "";
} else {
command = input.substring(0, spaceIndex);
body = input.substring(spaceIndex + 1);
}

boolean isModified = false;
if ("bye".equals(command)) {
System.out.println("Bye. Hope to see you again soon!");
return;
} else if ("list".equals(command)) {
printTaskList();
} else if ("mark".equals(command)) {
markTask(body);
isModified = true;
} else if ("unmark".equals(command)) {
unmarkTask(body);
isModified = true;
} else if ("delete".equals(command)) {
deleteTask(body);
isModified = true;
} else if (isTaskType(command)) {
addTask(command, body);
isModified = true;
} else {
System.out.println("OOPS!!! I'm sorry, but I don't know what that means :-(");
}

if (isModified) {
data.setTaskList(taskList);
data.saveToFile(savefile);
}
}
}

private void markTask(String body) {
int index = Integer.parseInt(body) - 1;
Task taskToMark = taskList.get(index);
taskToMark.mark();
String response = String.format(
"Nice! I've marked this task as done:\n %s",
taskToMark);
System.out.println(response);
}

private void unmarkTask(String body) {
int index = Integer.parseInt(body) - 1;
Task taskToUnmark = taskList.get(index);
taskToUnmark.unmark();
String response = String.format(
"OK, I've marked this task as not done yet:\n %s",
taskToUnmark
);
System.out.println(response);
}

private void deleteTask(String body) {
int index = Integer.parseInt(body) - 1;
Task deletedTask = taskList.remove(index);
String response = String.format(
"Noted. I've removed this task:\n %s\nNow you have %d tasks in the list",
deletedTask, taskList.size()
);
System.out.println(response);
}

private void addTask(String command, String body) {
try {
TaskTypes type = getTaskType(command);
Task newTask = createNewTask(body, type);
String response = String.format(
"Got it. I've added this task:\n %s\nNow you have %d tasks in the list.",
newTask, taskList.size());
System.out.println(response);
} catch (NoSuchTaskException | EmptyTaskDescException | EmptyTaskTimeException e) {
System.out.println("Error: " + e.getMessage());
}
}

private void printTaskList() {
System.out.println("Here are the tasks in your list:");
StringBuilder sb = new StringBuilder();
int i = 1;
for (Task t : taskList) {
sb.append(i);
sb.append(". ");
sb.append(t);
sb.append("\n");
++i;
}
System.out.print(sb);
}

private boolean isTaskType(String s) {
return "todo".equals(s) ||
"event".equals(s) ||
"deadline".equals(s);
}

private Task createNewTask(String taskString, TaskTypes type)
throws EmptyTaskDescException, EmptyTaskTimeException {
if ("".equals(taskString)) {
throw new EmptyTaskDescException();
}

String[] taskInfo;
Task newTask;

switch (type) {
case TODO:
newTask = new Todo(taskString);
break;
case EVENT:
taskInfo = taskString.split("/at");
if (taskInfo.length < 2) {
throw new EmptyTaskTimeException();
}
newTask = new Event(taskInfo[0].trim(), taskInfo[1].trim());
break;
case DEADLINE:
taskInfo = taskString.split("/by");
if (taskInfo.length < 2) {
throw new EmptyTaskTimeException();
}
newTask = new Deadline(taskInfo[0].trim(), taskInfo[1].trim());
break;
default:
return null;
}

taskList.add(newTask);
return newTask;
}

private TaskTypes getTaskType(String type) throws NoSuchTaskException {
switch(type) {
case "todo":
return TaskTypes.TODO;
case "event":
return TaskTypes.EVENT;
case "deadline":
return TaskTypes.DEADLINE;
default:
throw new NoSuchTaskException(type);
}
}
}
}
9 changes: 9 additions & 0 deletions src/main/java/exception/EmptyTaskDescException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package exception;

public class EmptyTaskDescException extends Exception {

public EmptyTaskDescException() {
super ("OOPS!!! The description of a todo cannot be empty.");
}

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

public class EmptyTaskTimeException extends Exception {

public EmptyTaskTimeException() {
super ("OOPS!!! You need to specify a time.");
}

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

public class NoSuchTaskException extends Exception {

public NoSuchTaskException(String type) {
super("I'm sorry, there is no task of type " + type);
}

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

import utils.DateParser;

import java.time.LocalDate;

public class Deadline extends Task {

private final LocalDate localDate;

public Deadline(String name, String dateStr) {
super(name);
localDate = DateParser.stringToDate(dateStr);
}

@Override
public String toString() {
return "[D] " + super.toString() + " (by: " + localDate.toString() + ")";
}

@Override
public String toDataString() {
return String.format("[D] | %d | %s | %s",
isMarked() ? 1 : 0,

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 you could look into replacing the 1 and 0 in the conditional statement with a named constant? It could be considered a "magic number".

getName(),
localDate.toString());
}

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

import utils.DateParser;

import java.time.LocalDate;

public class Event extends Task {

private final LocalDate localDate;

public Event(String name, String dateStr) {
super(name);
localDate = DateParser.stringToDate(dateStr);
}

@Override
public String toString() {
return "[E] " + super.toString() + " (at: " + localDate.toString() + ")";
}

@Override
public String toDataString() {
return String.format("[E] | %d | %s | %s",
isMarked() ? 1 : 0,
getName(),
localDate.toString());
}
}
66 changes: 66 additions & 0 deletions src/main/java/tasks/SaveData.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package tasks;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class SaveData {

private List<Task> taskList;

public SaveData() {
this.taskList = new ArrayList<>();
}

public List<Task> getTaskList() {
return taskList;
}

public void setTaskList(List<Task> taskList1) {
taskList = taskList1;
}

public void loadFromFile(File f) {
try {
BufferedReader reader = new BufferedReader(new FileReader(f));
taskList.clear();
reader.lines().forEach((s) -> {
// System.out.println(s);
taskList.add(Task.fromDataString(s));
});
} catch (IOException e) {
System.out.println("Error while loading from file: " + e);
}
}

public void saveToFile(File f) {
try {
BufferedWriter writer = new BufferedWriter(new FileWriter(f));
for (Task task : taskList) {
writer.write(task.toDataString());
writer.write('\n');
}
writer.close();
} catch (IOException e) {
System.out.println("Error while saving file: " + e);
}

}

public static void main(String[] args) {
SaveData data = new SaveData();
List<Task> newTaskList = new ArrayList<>();
newTaskList.add(new Deadline("Deadline task", "September"));
newTaskList.add(new Todo("Todo task"));
newTaskList.add(new Event("Event task", "October"));
data.setTaskList(newTaskList);
data.saveToFile(new File("savedata.txt"));
data.loadFromFile(new File("savedata.txt"));
}

/*
File specification:
[T] | 1 | Task Name | Time
*/

}
Loading