Skip to content
40 changes: 40 additions & 0 deletions src/main/java/Deadline.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
public class Deadline extends Task {

private String by;

public Deadline(String description, String by) {
super(description);
this.by = by;
}


private static void checkFormat(String formattedString) throws DukeException {
int byIndex = formattedString.indexOf("/by ");
if (byIndex == -1)
byIndex = formattedString.length();

String keyword = formattedString.split(" ", 2)[0];

if (!keyword.startsWith("deadline"))
throw new DukeException("I can't seem to find the deadline keyword");
else if (formattedString.length() <= 9 || formattedString.substring(9, byIndex).isEmpty())
throw new DukeException("the description of deadline cannot be empty");
else if (byIndex == formattedString.length() || formattedString.length() < byIndex + 5)
throw new DukeException("the [/by] time of deadline cannot be empty");
}

//Format: "Deadline: [description] /by [on]
public static Deadline create(String formattedString) throws DukeException {
checkFormat(formattedString);

int onIndex = formattedString.indexOf("/by");
return new Deadline(formattedString.substring(9, onIndex),
formattedString.substring(onIndex + 4));
}

@Override
public String toString() {
char statusIcon = this.isDone ? 'X' : ' ';
return String.format("[%c] Deadline: %s(by: %s)", statusIcon, this.description, this.by);
}
}
98 changes: 97 additions & 1 deletion src/main/java/Duke.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,106 @@
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Scanner;
import java.util.function.Consumer;
import java.util.function.Function;

public class Duke {

private static final ArrayList<Task> taskList = new ArrayList<>();

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

System.out.println("\nHello buddy! I am");
System.out.println(logo);
System.out.println("What can I do for you?");
System.out.println(sectionBreak);

Scanner sc=new Scanner(System.in);

Hashtable<String, Consumer<String>> commandTable = new Hashtable<>();
commandTable.put("list", (x) -> printTaskList());
commandTable.put("event", (x) -> AddTask(x, Event::create));
commandTable.put("deadline", (x) -> AddTask(x, Deadline::create));
commandTable.put("todo", (x) -> AddTask(x, ToDo::create));
commandTable.put("done", Duke::MarkTask);
commandTable.put("delete", Duke::DeleteTask);


while (true) {
String input = sc.nextLine();

if (input.equals("bye")) break;

String keyword = input.split(" ", 2)[0];
try {
if (commandTable.containsKey(keyword))
commandTable.get(keyword).accept(input);
else
throw new DukeException("I'm not sure what you mean");
} catch (DukeException e) {
System.out.println(e);
}
System.out.println(sectionBreak);
}

System.out.println("Bye. Hope to see you soon!");
System.out.println(sectionBreak);
}

private static void AddTask(String formattedString, Function<String, ? extends Task> create) {
Task e = create.apply(formattedString);
taskList.add(e);
System.out.printf("added: %s\n", e);
}

private static void printTaskList() {
for (int i = 0; i < taskList.size(); i++) {
System.out.printf("%d. %s\n", i + 1, taskList.get(i));
}
}

private static int getId(String input, String prefix) throws DukeException {
String idString = "";
try {
if (!input.startsWith(prefix) || input.length() <= prefix.length())
throw new DukeException("you did not specify a task id");

idString = input.substring(prefix.length());
return Integer.parseInt(idString);

} catch (NumberFormatException e) {
String msg = String.format("\"%s\" is not a valid integer", idString);
throw new DukeException(msg);
}
}

private static void MarkTask(String input) {
int taskId = -1;
try {
taskId = getId(input, "done ");
Task t = taskList.get(taskId - 1);
t.markAsDone();
System.out.println("Cool, I've marked this task as done\n" + t);
} catch (IndexOutOfBoundsException e) {
System.out.printf("Oops, Task #%d doesn't exist\n", taskId);
}
}

private static void DeleteTask(String input) {
int taskId = -1;
try {
taskId = getId(input, "delete ");
Task t = taskList.get(taskId - 1);
taskList.remove(taskId);
System.out.println("Okay, I've removed this task\n" + t);
} catch (IndexOutOfBoundsException e) {
System.out.printf("Oops, Task #%d doesn't exist\n", taskId);
}
}
}
11 changes: 11 additions & 0 deletions src/main/java/DukeException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
public class DukeException extends RuntimeException {

public DukeException(String message) {
super(message);
}

@Override
public String toString() {
return String.format("Oops, %s :(", this.getMessage());
}
}
39 changes: 39 additions & 0 deletions src/main/java/Event.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
public class Event extends Task {

private String on;

public Event(String description, String on) {
super(description);
this.on = on;
}

private static void checkFormat(String formattedString) throws DukeException {
int onIndex = formattedString.indexOf("/on ");
if (onIndex == -1)
onIndex = formattedString.length();

String keyword = formattedString.split(" ", 2)[0];

if (!keyword.startsWith("event"))
throw new DukeException("I can't seem to find the event keyword");
else if (formattedString.length() <= 6 || formattedString.substring(6, onIndex).isEmpty())
throw new DukeException("the description of event cannot be empty");
else if (onIndex == formattedString.length() || formattedString.length() < onIndex + 5)
throw new DukeException("the [/on] time of event cannot be empty");
}

//Format: "Event: [description] /by [on]
public static Event create(String formattedString) throws DukeException {
checkFormat(formattedString);

int onIndex = formattedString.indexOf("/on ");
return new Event(formattedString.substring(6, onIndex),
formattedString.substring(onIndex + 4));
}

@Override
public String toString() {
char statusIcon = this.isDone ? 'X' : ' ';
return String.format("[%c] Event: %s(on: %s)", statusIcon, this.description, this.on);
}
}
19 changes: 19 additions & 0 deletions src/main/java/Task.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
public abstract class Task {
protected String description;
protected boolean isDone;

public Task(String description) {
this.description = description;
this.isDone = false;
}

public void markAsDone() {
this.isDone = true;
}

@Override
public String toString() {
char statusIcon = this.isDone ? 'X' : ' ';
return String.format("[%c] %s", statusIcon, this.description);
}
}
27 changes: 27 additions & 0 deletions src/main/java/ToDo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
public class ToDo extends Task {

public ToDo(String description) {
super(description);
}

private static void checkFormat(String formattedString) throws DukeException {
String keyword = formattedString.split(" ", 2)[0];

if (!keyword.equals("todo"))
throw new DukeException("I can't seem to find the todo keyword");
else if (formattedString.length() <= 5 || formattedString.substring(5).isEmpty())
throw new DukeException("the description of todo cannot be empty");
}

public static ToDo create(String formattedString) throws DukeException {
checkFormat(formattedString);
return new ToDo(formattedString.substring(5));
}


@Override
public String toString() {
char statusIcon = this.isDone ? 'X' : ' ';
return String.format("[%c] ToDo: %s", statusIcon, this.description);
}
}
68 changes: 67 additions & 1 deletion text-ui-test/EXPECTED.TXT
Original file line number Diff line number Diff line change
@@ -1,7 +1,73 @@
Hello from

Hello buddy! I am
____ _
| _ \ _ _| | _____
| | | | | | | |/ / _ \
| |_| | |_| | < __/
|____/ \__,_|_|\_\___|

What can I do for you?
------------------------------------------
added: [ ] Event: dinner (on: 27th March)
------------------------------------------
1. [ ] Event: dinner (on: 27th March)
------------------------------------------
added: [ ] Deadline: homework (by: 30th April)
------------------------------------------
1. [ ] Event: dinner (on: 27th March)
2. [ ] Deadline: homework (by: 30th April)
------------------------------------------
added: [ ] ToDo: visit the gym
------------------------------------------
1. [ ] Event: dinner (on: 27th March)
2. [ ] Deadline: homework (by: 30th April)
3. [ ] ToDo: visit the gym
------------------------------------------
Cool, I've marked this task as done
[X] Event: dinner (on: 27th March)
------------------------------------------
1. [X] Event: dinner (on: 27th March)
2. [ ] Deadline: homework (by: 30th April)
3. [ ] ToDo: visit the gym
------------------------------------------
Cool, I've marked this task as done
[X] Deadline: homework (by: 30th April)
------------------------------------------
1. [X] Event: dinner (on: 27th March)
2. [X] Deadline: homework (by: 30th April)
3. [ ] ToDo: visit the gym
------------------------------------------
Okay, I've removed this task
[X] Deadline: homework (by: 30th April)
------------------------------------------
1. [X] Event: dinner (on: 27th March)
2. [X] Deadline: homework (by: 30th April)
------------------------------------------
Oops, the [/on] time of event cannot be empty :(
------------------------------------------
Oops, the [/on] time of event cannot be empty :(
------------------------------------------
Oops, the description of event cannot be empty :(
------------------------------------------
Oops, the [/by] time of deadline cannot be empty :(
------------------------------------------
Oops, the [/by] time of deadline cannot be empty :(
------------------------------------------
Oops, the description of deadline cannot be empty :(
------------------------------------------
Oops, the description of todo cannot be empty :(
------------------------------------------
Oops, you did not specify a task id :(
------------------------------------------
Oops, "a" is not a valid integer :(
------------------------------------------
Oops, Task #4 doesn't exist
------------------------------------------
Oops, you did not specify a task id :(
------------------------------------------
Oops, "3.14" is not a valid integer :(
------------------------------------------
Oops, Task #8 doesn't exist
------------------------------------------
Bye. Hope to see you soon!
------------------------------------------
26 changes: 26 additions & 0 deletions text-ui-test/input.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
event dinner /on 27th March
list
deadline homework /by 30th April
list
todo visit the gym
list
done 1
list
done 2
list
delete 2
list
event lunch
event lunch /on
event
deadline project
deadline project /by
deadline
todo
done
done a
done 4
delete
delete 3.14
delete 8
bye
4 changes: 2 additions & 2 deletions text-ui-test/runtest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ then
fi

# compile the code into the bin folder, terminates if error occurred
if ! javac -cp ../src -Xlint:none -d ../bin ../src/main/java/Duke.java
if ! javac -cp ../src -Xlint:none -d ../bin ../src/main/java/*.java
then
echo "********** BUILD FAILURE **********"
exit 1
Expand All @@ -24,7 +24,7 @@ java -classpath ../bin Duke < input.txt > ACTUAL.TXT

# convert to UNIX format
cp EXPECTED.TXT EXPECTED-UNIX.TXT
dos2unix ACTUAL.TXT EXPECTED-UNIX.TXT
# dos2unix ACTUAL.TXT EXPECTED-UNIX.TXT

# compare the output to the expected output
diff ACTUAL.TXT EXPECTED-UNIX.TXT
Expand Down