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

[Huang Maodian] iP #190

Open
wants to merge 28 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
070e1ef
Add Level-0 Increment: Rename, Greet, Exit.
Geinzit Feb 1, 2024
708a584
Add feature: bot echoes all input commands, exits when received 'bye'…
Geinzit Feb 2, 2024
19f083f
Add feature to store past commands and list stored commands
Geinzit Feb 8, 2024
d23eea2
Add separate class for tasks. Improve variable naming. Check code to …
Geinzit Feb 8, 2024
ddc3476
Add 3 new types of Task class using inheritance.
Geinzit Feb 8, 2024
ce45d70
Add input file and expected result file for IO redirection testing
Geinzit Feb 14, 2024
fb1d2b4
Add input error detection and response for all current commands.
Geinzit Feb 18, 2024
fe304ab
Merge branch 'branch-Level-5'
Geinzit Feb 18, 2024
dc155ec
Organize classes into separate packages. Rename files to match the bo…
Geinzit Feb 18, 2024
7007250
Merge branch 'branch-A-Packages'
Geinzit Feb 18, 2024
5bba707
Add delete task via index feature.
Geinzit Feb 21, 2024
a8a99b1
Add task save and load to hard drive function.
Geinzit Feb 21, 2024
73d4f84
Merge branch 'branch-Level-6'
Geinzit Feb 21, 2024
5cbefdc
Merge branch 'branch-Level-7'
Geinzit Feb 21, 2024
ad834e9
Bugfix: write task to hard drive after deleting.
Geinzit Feb 22, 2024
ff9c386
Add more OOP elements: separate class for UI, Storage, Parsing, and T…
Geinzit Mar 6, 2024
eb072c6
Add date time recognition in DeadlineTasks, and a command for filteri…
Geinzit Mar 6, 2024
f8a7df6
Add 'find' feature that allows filtering tasks by matching names
Geinzit Mar 6, 2024
28951cb
Merge pull request #1 from Geinzit/branch-Level-8
Geinzit Mar 6, 2024
df262ed
Merge branch 'master' into branch-Level-9
Geinzit Mar 6, 2024
b4f967b
Merge pull request #2 from Geinzit/branch-Level-9
Geinzit Mar 6, 2024
d370e77
Add Javadoc Comments.
Geinzit Mar 6, 2024
65c9c27
Merge pull request #3 from Geinzit/branch-A-JavaDoc
Geinzit Mar 6, 2024
16fbedf
Update README.md
Geinzit Mar 6, 2024
dc722b0
Update README.md
Geinzit Mar 6, 2024
2bb5550
Update README.md
Geinzit Mar 6, 2024
38f1745
Fix typos. Ignore unparsable DeadlineTasks in 'list_deadline'
Geinzit Mar 6, 2024
669853c
Merge branch 'master' of https://github.com/Geinzit/ip
Geinzit Mar 6, 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
10 changes: 0 additions & 10 deletions src/main/java/Duke.java

This file was deleted.

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

import huan.task.*;

Choose a reason for hiding this comment

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

Avoid importing *, try to explicitly list out the import classes


import java.util.Scanner;
import java.util.ArrayList;
import java.util.List;
public class Huan {
private static List<Task> tasks = new ArrayList<>();

public static Boolean isIndexValid(int index) {
return index >= 1 && index <= tasks.size();
}
public static void addTask(Task newTask) {
tasks.add(newTask);
}

public static void listTasks() {
int cnt = 0;
System.out.println("You have a total of " + tasks.size() + " tasks.");
for (Task task : tasks) {
cnt += 1;
System.out.printf(cnt + ". ");

switch (task.getTaskType()) {
case (1):
TodoTask todoTask = (TodoTask)task;
todoTask.printTask();
break;
case (2):
EventTask eventTask = (EventTask)task;
eventTask.printTask();
break;
case (3):
DeadlineTask deadlineTask = (DeadlineTask)task;
deadlineTask.printTask();
break;
default:
task.printTask();
break;
}
}
}
public static void readProcessCommand() {

Choose a reason for hiding this comment

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

Very long method, maybe try to abstract each command?


Scanner scanner = new Scanner(System.in);
while(true) {
System.out.println("-------------------------");
String inputCommand = scanner.nextLine();
String[] words = inputCommand.split(" ");
String firstWord = words[0];
String suffixWord;
if(words.length > 1) {
suffixWord = inputCommand.substring(words[0].length() + 1);

Choose a reason for hiding this comment

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

Multiple usage of Magic numbers, try to assign the number with a meaningful variable name for easy understand of what the number is for.

}
else {
suffixWord = "";
}
switch (firstWord) {
case ("bye"):
if(!suffixWord.isEmpty()) {
System.out.println("Invalid format! Should be 'bye'");
break;
}
System.out.println("Bye! See ya!");
return;
case ("list"):
if(!suffixWord.isEmpty()) {
System.out.println("Invalid format! Should be 'list'.");
break;
}
listTasks();
break;
case ("mark"):
try {
int markIndex = Integer.parseInt(suffixWord);
if (!isIndexValid(markIndex)) {
System.out.println("Invalid task index!");
} else {
tasks.get(markIndex - 1).setIsDone(true);
System.out.println("Set task number " + markIndex + ": " + tasks.get(markIndex - 1).getName() + " as done.");
}
} catch (Exception e){
System.out.println("Incorrect format! Should be 'mark *n', where n is the index of the task you wish to mark as finished.");
}
break;
case ("unmark"):
try {
int unmarkIndex = Integer.parseInt(suffixWord);
if (!isIndexValid(unmarkIndex)) {
System.out.println("Invalid task index!");
} else {
tasks.get(unmarkIndex - 1).setIsDone(false);
System.out.println("Set task number " + unmarkIndex + ": " + tasks.get(unmarkIndex - 1).getName() + " as not done.");
}
} catch (Exception e){
System.out.println("Incorrect format! Should be 'unmark *n', where n is the index of the task you wish to mark as unfinished.");
}
break;
case ("todo"):
if(suffixWord.isEmpty()) {
System.out.println("Incorrect format! Should be 'todo *task_name'.");
break;
}
TodoTask todoTask = new TodoTask(suffixWord, false);
addTask(todoTask);
System.out.println("Added todo type task with name: " + todoTask.getName());
break;
case ("event"):
try {
EventTask eventTask = new EventTask(suffixWord, false);
addTask(eventTask);
System.out.println("Added event type task with name: " + eventTask.getName());
} catch (Exception e) {
System.out.println("Incorrect format! Should be 'event *event_name /from *start_time /to *end_time'.");
}
break;
case ("deadline"):
try {
DeadlineTask deadlineTask = new DeadlineTask(suffixWord, false);
addTask(deadlineTask);
System.out.println("Added deadline type task with name: " + deadlineTask.getName());
} catch (Exception e) {
System.out.println("Incorrect format! Should be 'deadline *task_name /by *deadline_time'");
}
break;

default:
System.out.println("Unrecognized command, please try again!");
break;
}

}
}

public static void main(String[] args) {
String botName = "Huan";
System.out.println("Hello! I'm " + botName + ", a chat bot");

readProcessCommand();
}
}
53 changes: 53 additions & 0 deletions src/main/java/huan/task/DeadlineTask.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package huan.task;

import java.util.Objects;

public class DeadlineTask extends Task{
private String ddlTime;

Choose a reason for hiding this comment

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

maybe can consider calling it deadlineTime, as ddlTime can be hard to understand what it means

public DeadlineTask(String nameWithDate, Boolean isDone) throws Exception{
StringBuilder ddlTime = new StringBuilder();
StringBuilder name = new StringBuilder();
String[] words = nameWithDate.split(" ");
/*
state:
0 means currently concatenating name

Choose a reason for hiding this comment

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

Can consider using ENUM instead of 0,1 for the state

1 means currently concatenating ddlTime
*/
int state = 0;
for(String word : words) {
if (Objects.equals(word, "/by")) {
state += 1;
}
else {
switch (state) {
case (0):
name.append((name.length() == 0) ? "" : " ").append(word);
break;
case (1):
ddlTime.append((ddlTime.length() == 0 ? "" : " ")).append(word);
break;
}
}
}
if(state != 1 || name.toString().isEmpty() || isDone.toString().isEmpty()) {
throw new Exception();
}
setName(name.toString());
setIsDone(isDone);
setTaskType(3);
this.ddlTime = ddlTime.toString();
}

public void printTask() {
System.out.println("[D][" + (getIsDone() ? "X" : " ") + "] " + getName() + " (by: " + ddlTime + ")");
}

public String getDdlTime() {
return ddlTime;
}

public void setDdlTime(String ddlTime) {
this.ddlTime = ddlTime;
}

}
68 changes: 68 additions & 0 deletions src/main/java/huan/task/EventTask.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package huan.task;

import java.util.Objects;

public class EventTask extends Task{
private String startTime, endTime;
public EventTask(String nameWithDates, Boolean isDone) throws Exception {
StringBuilder startTime = new StringBuilder();
StringBuilder endTime = new StringBuilder();
StringBuilder name = new StringBuilder();
String[] words = nameWithDates.split(" ");
/*
state:
0 means currently concatenating name
1 means currently concatenating startTime
2 means currently concatenating endTime
*/
int state = 0;
for(String word : words) {
if (Objects.equals(word, "/from")) {
state += 1;
}
else if (Objects.equals(word, "/to")) {
state += 1;
}
else {
switch (state) {
case (0):
name.append((name.length() == 0) ? "" : " ").append(word);
break;
case (1):
startTime.append((startTime.length() == 0 ? "" : " ")).append(word);
break;
case (2):
endTime.append((endTime.length() == 0 ? "" : " ")).append(word);
break;
}
}
}
if(state != 2 || name.toString().isEmpty() || startTime.toString().isEmpty() || endTime.toString().isEmpty()) {

Choose a reason for hiding this comment

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

very long and complicated statement, can consider splitting it up

throw new Exception();
}
setName(name.toString());
setIsDone(isDone);
setTaskType(2);
this.startTime = startTime.toString();
this.endTime = endTime.toString();
}
public void printTask() {
System.out.println("[E][" + (getIsDone() ? "X" : " ") + "] " + getName() + " (from: " + startTime + " to: " + endTime + ")");
}

public void setStartTime(String startTime) {
this.startTime = startTime;
}

public String getStartTime() {
return startTime;
}

public void setEndTime(String endTime) {
this.endTime = endTime;
}

public String getEndTime() {
return endTime;
}
}
51 changes: 51 additions & 0 deletions src/main/java/huan/task/Task.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package huan.task;
public class Task {
private String name;
private Boolean isDone;
/**
* used for casting back types
* 0 for no specific types
* 1 for Todo types
* 2 for Event types
* 3 for Deadline types
*/
private int taskType;

public void setName(String name) {
this.name = name;
}

public void setIsDone(Boolean isDone) {
this.isDone = isDone;
}

public void setTaskType(int taskType) {
this.taskType = taskType;
}

public String getName() {
return name;
}

public Boolean getIsDone() {
return isDone;
}

public int getTaskType() {
return taskType;
}

public void printTask() {
System.out.println("[" + (isDone ? "X" : " ") + "] " + name);
}
public Task() {
setName("task");
setIsDone(false);
taskType = 0;
}

public Task(String name, Boolean isDone) {
setName(name);
setIsDone(isDone);
}
}
11 changes: 11 additions & 0 deletions src/main/java/huan/task/TodoTask.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package huan.task;

public class TodoTask extends Task{
public TodoTask(String name, Boolean isDone) {
super(name, isDone);
setTaskType(1);
}
public void printTask() {
System.out.println("[T][" + (getIsDone() ? "X" : " ") + "] " + getName());
}
}
31 changes: 24 additions & 7 deletions text-ui-test/EXPECTED.TXT
Original file line number Diff line number Diff line change
@@ -1,7 +1,24 @@
Hello from
____ _
| _ \ _ _| | _____
| | | | | | | |/ / _ \
| |_| | |_| | < __/
|____/ \__,_|_|\_\___|

Hello! I'm Huan, a chat bot
-------------------------
Added todo type task with name: read book
-------------------------
Added deadline type task with name: return book
-------------------------
Added event type task with name: project meeting
-------------------------
Set task number 1: read book as done.
-------------------------
Added todo type task with name: join sports club
-------------------------
Added todo type task with name: borrow book
-------------------------
Set task number 4: join sports club as done.
-------------------------
You have a total of 5 tasks.
1. [T][X] read book
2. [D][ ] return book (by: June 6th)
3. [E][ ] project meeting (from: Aug 6th 2pm to: 4pm)
4. [T][X] join sports club
5. [T][ ] borrow book
-------------------------
Bye! See ya!
9 changes: 9 additions & 0 deletions text-ui-test/input.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
todo read book
deadline return book /by June 6th
event project meeting /from Aug 6th 2pm /to 4pm
mark 1
todo join sports club
todo borrow book
mark 4
list
bye