Skip to content

Commit

Permalink
Merge pull request #3 from marcus2k/branch-C-Tagging
Browse files Browse the repository at this point in the history
Add tagging support
  • Loading branch information
ngmarcus committed Sep 8, 2020
2 parents fbfbd3e + e5757c6 commit 1bfd08e
Show file tree
Hide file tree
Showing 9 changed files with 191 additions and 16 deletions.
9 changes: 6 additions & 3 deletions src/main/java/duke/Deadline.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ public Deadline(String description, String datetime) {
*/
@Override
protected String getTxtFormat() {
return "deadline, " + super.getTxtFormat() + "/by" + this.dateTime.format(Deadline.INPUT_FORMAT);
String[] splitTag = super.getTxtFormat().split("#", 2);
return "deadline, " + splitTag[0] + "/by" + this.dateTime.format(Deadline.INPUT_FORMAT)
+ " #" + splitTag[1];
}

/**
Expand All @@ -34,7 +36,8 @@ protected String getTxtFormat() {
*/
@Override
public String toString() {
return "[D]" + super.toString()
+ " (by: " + super.getDateTimeString() + ")";
String[] splitTag = super.toString().split("#", 2);
return "[D]" + splitTag[0] + " (by: " + super.getDateTimeString() + ")"
+ " #" + splitTag[1];
}
}
9 changes: 6 additions & 3 deletions src/main/java/duke/Event.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ public Event(String description, String datetime) {
*/
@Override
protected String getTxtFormat() {
return "event, " + super.getTxtFormat() + "/at" + this.dateTime.format(Event.INPUT_FORMAT);
String[] splitTag = super.getTxtFormat().split("#", 2);
return "event, " + splitTag[0] + "/at" + this.dateTime.format(Deadline.INPUT_FORMAT)
+ " #" + splitTag[1];
}

/**
Expand All @@ -34,7 +36,8 @@ protected String getTxtFormat() {
*/
@Override
public String toString() {
return "[E]" + super.toString()
+ " (at: " + super.getDateTimeString() + ")";
String[] splitTag = super.toString().split("#", 2);
return "[E]" + splitTag[0] + " (at: " + super.getDateTimeString() + ")"
+ " #" + splitTag[1];
}
}
17 changes: 17 additions & 0 deletions src/main/java/duke/FindTagCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package duke;

public class FindTagCommand extends Command {
private final String tag;

public FindTagCommand(String tag) {
this.tag = tag;
}

public String execute(TaskList list, Ui ui, Storage storage) throws DukeException {
TaskList taskList = list.findTag(this.tag);
String textOutput = "Here are your tasks tagged with #" + this.tag + ":\n";
textOutput += taskList;
storage.updateTextFile(list);
return ui.getLine(textOutput);
}
}
12 changes: 12 additions & 0 deletions src/main/java/duke/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,18 @@ public static Command parse(String query) throws DukeException {
return new ExitCommand();
case "find":
return new FindCommand(queryArr[1]);
case "tag": // format: tag <itemNumber> <newTag>
String[] tagInfo = queryArr[1].split(" ", 2);
return new TagCommand(Integer.parseInt(tagInfo[0]) - 1, tagInfo[1]);
case "untag":
try {
String[] untagInfo = queryArr[1].split(" ", 2);
return new UntagCommand(Integer.parseInt(untagInfo[0]) - 1, untagInfo[1]);
} catch (NumberFormatException e) {
return new UntagCommand(queryArr[1]);
}
case "findtag":
return new FindTagCommand(queryArr[1]);
default:
return new AddCommand(queryArr[0], queryArr[1]);
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/duke/Storage.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ public TaskList loadList() throws DukeException {
TaskList list = new TaskList();
this.file = new File("./data/duke.txt");
Scanner sc = new Scanner(this.file);
while (sc.hasNext()) { // e.g. deadline, 1, description/by date
while (sc.hasNext()) { // e.g. deadline, 1, description/by date#tag1,tag2
String[] arr = sc.nextLine().split(", ");
assert arr.length > 3: "duke.txt data not in correct format";
assert arr.length == 3: "duke.txt data not in correct format";
if (arr.length == 3) {
list.addTask(arr[0], arr[2], arr[1].equals("1"));
} else {
Expand Down
19 changes: 19 additions & 0 deletions src/main/java/duke/TagCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package duke;

public class TagCommand extends Command {
private final int index;
private final String tag;

public TagCommand(int index, String tag) {
this.index = index;
this.tag = tag;
}

public String execute(TaskList list, Ui ui, Storage storage) throws DukeException {
Task task = list.tagTask(this.index, this.tag);
String textOutput = "Nice! I've tagged this task with #" + this.tag + ":\n";
textOutput += task;
storage.updateTextFile(list);
return ui.getLine(textOutput);
}
}
36 changes: 34 additions & 2 deletions src/main/java/duke/Task.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package duke;

import java.util.HashSet;

/**
* Abstract class representing a task.
*/
public abstract class Task {
protected String description;
protected boolean isDone = false;
protected HashSet<String> tagSet = new HashSet<>();

/**
* Constructor that initializes with description.
Expand Down Expand Up @@ -33,7 +36,13 @@ protected Task setDone() {
* @return String of .txt format
*/
protected String getTxtFormat() {
return (this.isDone ? "1, " : "0, ") + this.description;
StringBuilder tags = new StringBuilder();
for (String t: tagSet) {
tags.append("#");
tags.append(t);
tags.append(" ");
}
return (this.isDone ? "1, " : "0, ") + this.description + tags.toString();
}

/**
Expand All @@ -44,7 +53,30 @@ protected String getTxtFormat() {
@Override
public String toString() {
String status = (this.isDone) ? "[✓]" : "[✗]";
return status + " " + description;
StringBuilder tags = new StringBuilder();
for (String t: tagSet) {
tags.append("#");
tags.append(t);
tags.append(" ");
}
return status + " " + description + " " + tags.toString();
}

public boolean hasTag(String tag) {
return this.tagSet.contains(tag);
}

public Task addTag(String tag) throws DukeException {
if (this.tagSet.contains(tag)) {
throw new DukeException("Tag already exist for task " + this.toString());
}
this.tagSet.add(tag);
return this;
}

public Task untag(String tag) {
this.tagSet.remove(tag);
return this;
}

public String getDescription() {
Expand Down
70 changes: 64 additions & 6 deletions src/main/java/duke/TaskList.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.time.LocalDate;
import java.time.format.DateTimeParseException;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Iterator;

Expand Down Expand Up @@ -73,13 +74,17 @@ public Task addTask(String type, String input) throws DukeException {
* @throws DukeException if failed to add task.
*/
public Task addTask(String type, String input, boolean done) throws DukeException {
if (input.isEmpty()) {
throw new DukeException("OOPS!!! I'm sorry, the description cannot be empty :<");
}
Task task;
String[] splitTags = input.split("#");
switch (type) {
case "todo":
task = new Todo(input);
task = new Todo(splitTags[0]);
break;
case "deadline":
String[] arr = input.split("/by");
String[] arr = splitTags[0].split("/by");
try {
task = new Deadline(arr[0].trim(), arr[1].trim());
} catch (IndexOutOfBoundsException e) {
Expand All @@ -89,7 +94,7 @@ public Task addTask(String type, String input, boolean done) throws DukeExceptio
}
break;
case "event":
arr = input.split("/at");
arr = splitTags[0].split("/at");
try {
task = new Event(arr[0].trim(), arr[1].trim());
} catch (IndexOutOfBoundsException e) {
Expand All @@ -101,10 +106,14 @@ public Task addTask(String type, String input, boolean done) throws DukeExceptio
default:
throw new DukeException("OOPS!!! I'm sorry, I don't know what that means :<");
}
if (input.isEmpty()) {
throw new DukeException("OOPS!!! I'm sorry, the description cannot be empty :<");
}
task = done ? task.setDone() : task;
if (splitTags.length > 1) {
for (String i: splitTags) {
if (i != splitTags[0]) {
task.addTag(i.trim());
}
}
}
this.list.add(task);
return task;
}
Expand Down Expand Up @@ -168,6 +177,22 @@ public Task deleteTask(int i) throws DukeException {
}
}

/**
* Tags the i-th task with input tag.
*
* @param i index of the tasks to be deleted.
* @param tag String tag for the ith item.
* @return Task if task is in this TaskList object.
* @throws DukeException if index out of bounds.
*/
public Task tagTask(int i, String tag) throws DukeException {
try {
return this.list.get(i).addTag(tag);
} catch (IndexOutOfBoundsException e) {
throw new DukeException("OOPS!!! I'm sorry, the task number is out of range :<");
}
}

/**
* Returns a string representation of object.
*
Expand Down Expand Up @@ -201,4 +226,37 @@ public TaskList findTask(String keyword) throws DukeException {
return new TaskList(keywordTasks);
}

/**
* Returns tasks containing the specific tag.
* @param tag tag of tasks we want to retrieve
* @return list of tasks containing tag
* @throws DukeException if no such task
*/
public TaskList findTag(String tag) throws DukeException {
ArrayList<Task> taggedTasks = new ArrayList<>(this.list);
taggedTasks.removeIf(i -> !i.hasTag(tag));
if (taggedTasks.isEmpty()) {
throw new DukeException("OOPS!!! I'm sorry, no such tag :<");
}
return new TaskList(taggedTasks);
}

public Task untagTask(int i, String tag) throws DukeException {
try {
return this.list.get(i).untag(tag);
} catch (IndexOutOfBoundsException e) {
throw new DukeException("OOPS!!! I'm sorry, the task number is out of range :<");
}
}

public TaskList untagAllTasks(String tag) throws DukeException {
ArrayList<Task> taggedTasks = new ArrayList<>(this.list);
taggedTasks.removeIf(i -> !i.hasTag(tag));
if (taggedTasks.isEmpty()) {
throw new DukeException("OOPS!!! I'm sorry, no such tag :<");
}
Object[] arr = taggedTasks.stream().map((Task i) -> i.untag(tag)).toArray();
return new TaskList(new ArrayList(Arrays.asList(arr)));
}

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

public class UntagCommand extends Command {
private static final int ALL = -1;
private final int index;
private final String tag;

public UntagCommand(int index, String tag) {
this.index = index;
this.tag = tag;
}

public UntagCommand(String tag) {
this(ALL, tag);
}

public String execute(TaskList list, Ui ui, Storage storage) throws DukeException {
String textOutput = "Nice! I've removed the tag #" + this.tag;
if (this.index != ALL) {
Task task = list.untagTask(this.index, this.tag);
textOutput += " from this task:\n";
textOutput += task;
} else {
TaskList taskList = list.untagAllTasks(this.tag);
textOutput += " from these tasks:\n";
textOutput += taskList;
}
storage.updateTextFile(list);
return ui.getLine(textOutput);
}
}

0 comments on commit 1bfd08e

Please sign in to comment.