Skip to content
Open
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
b44b350
Refractor Duke to Quinn and implement Level-0
Sep 4, 2024
1a384e7
Implement Level-1
Sep 4, 2024
80154db
Implement Level-2
Sep 4, 2024
83bc054
Implement Level-3 and adhere to coding standard
Sep 4, 2024
9cdfdcd
Implement Level-4
Sep 5, 2024
e9a5a29
Implement Level-5 and review code quality
Sep 10, 2024
6a82856
Merge branch 'branch-Level-5'
Sep 10, 2024
8e7dc1c
Organise classes into different packages
Sep 10, 2024
e16f866
Merge branch 'branch-A-Packages'
Sep 10, 2024
53936b5
Update README.md
Sep 10, 2024
b25c7de
Implement Level-6
Sep 10, 2024
b06b90c
Fix some text errors due to refactoring
Sep 10, 2024
9c924df
Merge branch 'master' into branch-Level-6
Sep 10, 2024
bdaa224
Fix text errors in Quinn java file
Sep 10, 2024
6799df1
Merge branch 'master' into branch-Level-6
Sep 10, 2024
9dde6b8
Implement Level-7
Sep 16, 2024
d8e6940
Merge branch 'branch-Level-6'
Sep 16, 2024
06ca525
Merge branch 'branch-Level-7'
Sep 16, 2024
db7785f
Implement saving after deletion of tasks
Sep 16, 2024
8a57ddf
update some responses by quinn
Sep 16, 2024
b35fedf
Implement A-MoreOOP, refactor code to extract out more classes
Sep 26, 2024
a9c924a
Implement Level-8 for chatbot to understand date time
Sep 26, 2024
b46f621
Implement Level-9
Sep 26, 2024
68cff40
Merge pull request #1 from kaboomzxc/branch-Level-8
kaboomzxc Sep 26, 2024
c29453c
Merge branch 'master' into branch-Level-9
Sep 26, 2024
5b746ce
Merge pull request #2 from kaboomzxc/branch-Level-9
kaboomzxc Sep 26, 2024
02bc63a
Added JavaDoc comments
Sep 26, 2024
a4e9125
Merge pull request #3 from kaboomzxc/branch-A-JavaDoc
kaboomzxc Sep 26, 2024
c621d5e
Implement User Guide
Oct 8, 2024
b0bf095
Update User Guide
Oct 9, 2024
bb7a02e
Update User Guide
Oct 9, 2024
0054652
Update User Guide
Oct 9, 2024
626cc6b
Update User Guide
Oct 9, 2024
e0003ff
Update User Guide
Oct 9, 2024
2d4c709
Update download link
Oct 9, 2024
0681301
Update UG
Oct 9, 2024
1444e91
remove "build.gradle" file
Oct 9, 2024
389da92
Change "Checkmark" symbol to "X" symbol
Oct 9, 2024
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
17 changes: 10 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Duke project template
# Quinn 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,12 +13,15 @@ Prerequisites: JDK 17, update Intellij to the most recent version.
1. If there are any further prompts, accept the defaults.
1. Configure the project to use **JDK 17** (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/quinn/Quinn.java` file, right-click it, and choose `Run Quinn.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
____ _
| _ \ _ _| | _____
| | | | | | | |/ / _ \
| |_| | |_| | < __/
|____/ \__,_|_|\_\___|

QQQ U U III N N N N
Q Q U U I NN N NN N
Q Q U U I N N N N N N
Q Q U U I N NN N NN
QQQ UUU III N N N N
Q
QQ
```
2 changes: 1 addition & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Duke User Guide
# quinn.Quinn User Guide

// Update the title above to match the actual product name

Expand Down
10 changes: 0 additions & 10 deletions src/main/java/Duke.java

This file was deleted.

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

import quinn.exception.QuinnException;
import quinn.task.Deadline;
import quinn.task.Event;
import quinn.task.Task;
import quinn.task.ToDo;
import quinn.ui.Ui;
import quinn.storage.Storage;

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

public class Quinn {
private final Ui ui;
private Storage storage;
private List<Task> tasks;

public Quinn(String folderName, String fileName) {
ui = new Ui();

try {
storage = new Storage(folderName, fileName);
tasks = storage.loadTasksFromFile();
} catch (QuinnException | IOException e) {
ui.displayError(e.getMessage());
tasks = new ArrayList<>();
}
}

public static void main(String[] args) {
new Quinn("data", "tasks.txt").run();
}

public void run() {
ui.displayWelcome();

String commandLine = "";

while (!commandLine.equals("bye")) {
commandLine = ui.readCommand();

try {
processCommand(commandLine);
} catch (QuinnException | IOException e) {
ui.displayError(e.getMessage());
} finally {
ui.displayLine();
}
}
}

public void processCommand(String commandLine) throws QuinnException, IOException {

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 it is better to use a more specific name for this method such as checkAndSplitCommand as process might not be a very specific term. See https://nus-cs2113-ay2425s1.github.io/website/se-book-adapted/chapters/codeQuality.html#guideline-name-well

String[] commandLineParts = commandLine.split(" ", 2);

String commandType;
String commandInfo;

if (commandLineParts.length == 2) {
commandType = commandLineParts[0].trim();
commandInfo = commandLineParts[1].trim();

if ((commandType.equals("bye") || commandType.equals("list")) && !commandInfo.isEmpty()) {
throw new QuinnException("INVALID COMMAND. Please try again!");
}
} else { // for "bye" and "list" commands which does not have any input behind
commandType = commandLineParts[0];
commandInfo = "";
}

executeCommand(commandType, commandInfo);
}

public void executeCommand(String commandType, String commandInfo) throws QuinnException, IOException {
int taskNum;
Task task;
String taskDescription;
String taskInfo;

switch (commandType.toLowerCase()) {
case "bye":
ui.displayExit();
break;
case "list":
displayTasks();
break;
case "mark":
taskNum = getTaskNumFromMarkCommand(commandInfo);
markTask(taskNum);
break;
case "unmark":
taskNum = getTaskNumFromUnmarkCommand(commandInfo);
unmarkTask(taskNum);
break;
case "delete":
taskNum = getTaskNumFromDeleteCommand(commandInfo);
deleteTask(taskNum);
break;
case "todo":
taskDescription = getTaskDescriptionFromToDoCommand(commandInfo);
task = new ToDo(taskDescription);
addTask(task);
break;
case "deadline":
taskInfo = processTaskInfoFromDeadlineCommand(commandInfo);
String[] deadlineTaskDetails = taskInfo.split("/by", 2);
task = new Deadline(deadlineTaskDetails[0].trim(), deadlineTaskDetails[1].trim());
addTask(task);
break;
case "event":
taskInfo = processTaskInfoFromEventCommand(commandInfo);
String[] eventTaskDetails = taskInfo.split("/from|/to", 3);
task = new Event(eventTaskDetails[0].trim(), eventTaskDetails[1].trim(), eventTaskDetails[2].trim());
addTask(task);
break;
default:
throw new QuinnException("INVALID COMMAND. Please try again!");
}
}

private boolean isCommandInfoPresent(String commandInfo) {
return !commandInfo.trim().isEmpty();
}

private int getTaskNumFromMarkCommand(String commandInfo) throws QuinnException {
if (isCommandInfoPresent(commandInfo)) {
try {
return Integer.parseInt(commandInfo);
} catch (NumberFormatException e) {
throw new QuinnException("Please enter a valid task number to be marked as done!");
}
} else {
throw new QuinnException("Please enter a task number to be marked as done!");
}
}

private int getTaskNumFromUnmarkCommand(String commandInfo) throws QuinnException {
if (isCommandInfoPresent(commandInfo)) {
try {
return Integer.parseInt(commandInfo);
} catch (NumberFormatException e) {
throw new QuinnException("Please enter a valid task number to be marked as not done yet!");
}
} else {
throw new QuinnException("Please enter a task number to be marked as not done yet!");
}
}

private int getTaskNumFromDeleteCommand(String commandInfo) throws QuinnException {
if (isCommandInfoPresent(commandInfo)) {
try {
return Integer.parseInt(commandInfo);
} catch (NumberFormatException e) {
throw new QuinnException("Please enter a valid task number to be deleted!");
}
} else {
throw new QuinnException("Please enter a task number to be deleted!");
}
}

private String getTaskDescriptionFromToDoCommand(String commandInfo) throws QuinnException {
if (isCommandInfoPresent(commandInfo)) {
return commandInfo;
} else {
throw new QuinnException("The description of a todo cannot be empty!");
}
}

private String processTaskInfoFromDeadlineCommand(String commandInfo) throws QuinnException {
if (!isCommandInfoPresent(commandInfo)) {
throw new QuinnException("INCOMPLETE COMMAND"
+ System.lineSeparator() + "\t"
+ "The description and date/time of a deadline cannot be empty!"
+ System.lineSeparator() + "\t"
+ "[Note: Enter /by before specifying the date/time]");
} else {
String[] deadlineInfoParts = commandInfo.split("/by", 2);

if (deadlineInfoParts.length != 2) {
throw new QuinnException("INVALID COMMAND"
+ System.lineSeparator() + "\t"
+ "Please check that the description and date/time of a deadline is present!"
+ System.lineSeparator() + "\t"
+ "[Note: Enter /by before specifying the date/time]");
}

String deadlineDescription = deadlineInfoParts[0].trim();
String deadlineByDateTime = deadlineInfoParts[1].trim();

if (deadlineDescription.isEmpty()) {
throw new QuinnException("INCOMPLETE COMMAND"
+ System.lineSeparator() + "\t"
+ "The description of a deadline cannot be empty!");
}

if (deadlineByDateTime.isEmpty()) {
throw new QuinnException("INCOMPLETE COMMAND"
+ System.lineSeparator() + "\t"
+ "The date/time of a deadline cannot be empty!"
+ System.lineSeparator() + "\t"
+ "[Note: Enter /by before specifying the date/time]");
}

return commandInfo;
}
}

private String processTaskInfoFromEventCommand(String commandInfo) throws QuinnException {
if (!isCommandInfoPresent(commandInfo)) {
throw new QuinnException("INCOMPLETE COMMAND"
+ System.lineSeparator() + "\t"
+ "The description and date/time of an event cannot be empty!"
+ System.lineSeparator() + "\t"
+ "[Note: Specify the date/time with '/from /to']");
} else {
String[] eventInfoParts = commandInfo.split("/from|/to", 3);

if (eventInfoParts.length != 3) {
throw new QuinnException("INVALID COMMAND"
+ System.lineSeparator() + "\t"
+ "Please check that the description and date/time of an event is present!"
+ System.lineSeparator() + "\t"
+ "[Note: Specify the date/time with '/from /to']");
}

String eventDescription = eventInfoParts[0].trim();
String eventFromDateTime = eventInfoParts[1].trim();
String eventToDateTime = eventInfoParts[2].trim();

if (eventDescription.isEmpty()) {
throw new QuinnException("INCOMPLETE COMMAND"
+ System.lineSeparator() + "\t"
+ "The description of an event cannot be empty!");
}

if (eventFromDateTime.isEmpty() || eventToDateTime.isEmpty()) {
throw new QuinnException("INCOMPLETE COMMAND"
+ System.lineSeparator() + "\t"
+ "The date/time of an event cannot be empty!"
+ System.lineSeparator() + "\t"
+ "[Note: Specify the date/time with '/from /to']");
}

return commandInfo;
}
}

public void addTask(Task task) throws IOException {
tasks.add(task);

String response = ui.taskAddedMessage(task)
+ System.lineSeparator()
+ ui.numOfTasksInListMessage(tasks);
ui.displayResponse(response);

storage.saveTasksToFile(tasks);
}

public void displayTasks() throws QuinnException {
if (!tasks.isEmpty()) {
String response = ui.tasksInListMessage(tasks);
ui.displayResponse(response);
} else {
throw new QuinnException("There are no tasks in your list!");
}
}

public void markTask(int taskNum) throws QuinnException, IOException {
if (taskNum > 0 && taskNum <= tasks.size()) {
Task task = tasks.get(taskNum - 1);
task.setDone();

String message = ui.taskDoneMessage(task);
ui.displayResponse(message);

storage.saveTasksToFile(tasks);
} else {
throw new QuinnException("Task not found. Please try again!");
}
}

public void unmarkTask(int taskNum) throws QuinnException, IOException {
if (taskNum > 0 && taskNum <= tasks.size()) {
Task task = tasks.get(taskNum - 1);
task.setNotDone();

String message = ui.taskNotDoneMessage(task);
ui.displayResponse(message);

storage.saveTasksToFile(tasks);
} else {
throw new QuinnException("Task not found. Please try again!");
}
}

public void deleteTask(int taskNum) throws QuinnException, IOException {
if (taskNum > 0 && taskNum <= tasks.size()) {
Task task = tasks.get(taskNum - 1);
tasks.remove(task);

String message = ui.taskDeletedMessage(task)
+ System.lineSeparator()
+ ui.numOfTasksInListMessage(tasks);
ui.displayResponse(message);

storage.saveTasksToFile(tasks);
} else {
throw new QuinnException("Task not found. Please try again!");
}
}
}
7 changes: 7 additions & 0 deletions src/main/java/quinn/exception/QuinnException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package quinn.exception;

public class QuinnException extends Exception {
public QuinnException(String errorMessage) {
super(errorMessage);
}
}
Loading