Skip to content
Open
103 changes: 89 additions & 14 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,104 @@
# User Guide

## Features
## Features

### Feature-ABC
Users can add, mark, unmark, list tasks as needed.

Description of the feature.
### Add task

### Feature-XYZ
Users can add new tasks to the list. Tasks have 3 available types, Event, Todo and Deadline

Description of the feature.
Format: `type of task` `name of task` date-attribute of task
Example: deadline do tutorial /by Sunday

## Usage
Expected outcome:
New tasks of correct type and description is added to task list

### Add Todo (task subclass)

Users can add todo tasks to the list.

Format: todo `name of task`
Example: todo eat

Expected: task of type T is added to task list

### Add Event (task subclass)

Users can add Events to the list.

Format: event `name of event` /from `start time` /to `end time`
Example: event eat /from morning /to night

Expected: task of type E is added to task list

### Add Deadline (task subclass)

Users can add Deadline to the list.

Format: deadline `name of deadline` /by `due date`
Example (correct LocalDate format): deadline return books /by 2022-03-05
Example (incorrect LocalDate format): deadline return books /by next week

Expected: task of type D is added to task list, user is alerted if date was not stored as LocalDate format

### Mark task

Users can mark tasks as done.

Format: mark `task index`
Example: mark 3

Expected outcome:
[ ] state of task(s) changes to [x] when marked as done.

### Unmark task

Users can mark tasks as undone.

### `Keyword` - Describe action
Format: unmark `task index`
Example: mark 3

Expected outcome:
[x] state of task(s) changes to [ ] when marked as done.

Describe the action and its outcome.
### List task(s)

Example of usage:
Users can list and view all tasks currently in the task list

`keyword (optional arguments)`
Format: list

Expected outcome:
If task list is empty, "Tasklist is empty."
Indexed list of `index`, `done state`, `description`

Description of the outcome.
### List overdue task(s)

Users can list and view all tasks that are currently overdue in the task list

Format: list overdue

Expected outcome:
If task list is empty, "Tasklist is empty."
Indexed list of overdue tasks `index`, `done state`, `description`

```
expected output
```
### Find

Users can find and list all tasks by inputting keyword to be searched

Format: find `string to be searched`
Example: find food

Expected outcome:
If task lsit is empty, "Tasklist is empty."
Indexed list of tasks with description containing searched string

### Delete

Users can remove tasks from task list
Format: delete `index`
Example: delete 3

Expected outcome:
If index out of bounds, "Please input valid task number!"
"Noted. I've removed this task:" `index`
1 change: 1 addition & 0 deletions duke.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
D|false|eat /by tmr
Binary file added ip.jar
Binary file not shown.
61 changes: 61 additions & 0 deletions src/main/java/Deadline.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
//import java.time.temporal.ChronoUnit;

/*
* Sub-class of super-class <code>Task</code>, represents a task that has a deadline,
* Contains attributes due, info, deadline name and evaluates attribute whether Deadline task is overdue
*/
public class Deadline extends Task {
public LocalDate due;
public String dueText;
public String[] info;
public String deadlineName;
public boolean isOverdue;

public Deadline(String description) {
super(description);
this.info = this.description.split("/by", 2);
this.deadlineName = info[0];
this.due = isValid((info[1]).trim());
if (this.due == null) {
this.dueText = (info[1]).trim();
System.out.println("Due date is not in yyyy-MM-dd format, will be saved as text");
} else if (this.due.isBefore(LocalDate.now())) {
this.isOverdue = true;
}

}

private LocalDate isValid(String date) {
try {
return LocalDate.parse(date);
} catch (Exception e) {
return null;
}
}

@Override
public String fileFormat() {
DateTimeFormatter yyyyMMdd = DateTimeFormatter.ofPattern("yyyy-MM-dd");
if (this.due != null) {
return (String.format("D|%b|%s /by %s\n", super.isDone, this.deadlineName,
due.format(yyyyMMdd)));
} else {
return (String.format("D|%b|%s /by %s\n", super.isDone, this.deadlineName, this.dueText));
}
}

@Override
public String toString() {
DateTimeFormatter yyyyMMdd = DateTimeFormatter.ofPattern("yyyy-MM-dd");
if (this.due != null) {
return ("[D][" + super.getStatusIcon() + "] " + this.deadlineName) +
" (by: " + this.due.format(yyyyMMdd) + ")";
} else {
return ("[D][" + super.getStatusIcon() + "] " + this.deadlineName) +
" (by: " + this.dueText + ")";
}
}
}
34 changes: 27 additions & 7 deletions src/main/java/Duke.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,30 @@
/*
* Duke is an instance of the bot which has several subclasses,
* storage for file management, ui for communicating with user for input/output, tasklist for managing tasks and task-related commands
*/
public class Duke {
public static void main(String[] args) {
String logo = " ____ _ \n"
+ "| _ \\ _ _| | _____ \n"
+ "| | | | | | | |/ / _ \\\n"
+ "| |_| | |_| | < __/\n"
+ "|____/ \\__,_|_|\\_\\___|\n";
System.out.println("Hello from\n" + logo);

private String fileName = "duke.txt";
public Storage storage;
private UI ui;
public TaskList tasks;

public Duke() {
ui = new UI();
storage = new Storage(fileName);
this.tasks = new TaskList();
storage.load(tasks);
ui.greet(tasks);
}

// public void addTask(String taskName){
// Task t = new Task(taskName);
// taskList.add(t);
// System.out.printf(
// "Got it. I've added this task:\n" +
// String.format("added: %s\n", taskName)

// );
// }

}
27 changes: 27 additions & 0 deletions src/main/java/Event.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Sub-class of super-class <code>Task</code>, represents a task that is an event,
* Contains attributes event name, start and end time
*/
public class Event extends Task {
public String startTime, endTime, eventName;
public String[] info;

public Event(String description) {
super(description);
this.info = this.description.split("/from", 2);
this.eventName = info[0];
this.startTime = info[1].split("/to", 2)[0];
this.endTime = info[1].split("/to", 2)[1];
}

@Override
public String fileFormat() {
return (String.format("E|%b|%s /from %s /to %s\n", super.isDone, this.eventName, this.startTime, this.endTime));
}

@Override
public String toString() {
return ("[E][" + super.getStatusIcon() + "] " + this.eventName) +
" (from: " + this.startTime + " to: " + this.endTime + ")";
}
}
58 changes: 58 additions & 0 deletions src/main/java/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import java.util.Scanner;

/*
* Initialises Duke class
* If earlier written file exists, displays files
* Continuously promtps user for input until specified terminating input is received
* List of inputs include bye, list, mark, unmark, event, todo, deadline, delete, find
*/
public class Main {
public static void main(String[] args) {
Duke Duke = new Duke();
Scanner userInput = new Scanner(System.in); // create Scanner object
String inputCommand; // read user input
String[] commandPhrase;
String command, phrase;
while (true) {
inputCommand = userInput.nextLine();
commandPhrase = inputCommand.split(" ", 2);
command = commandPhrase[0];
if (commandPhrase.length < 2) {
if (command.equals("bye")) {
break;
} else if (command.equals("clear")) {
Duke.tasks.clearTaskList();
} else if (command.equals("list")) {
Duke.tasks.list();
} else if (command.equals("overdue")) {
Duke.tasks.listOverdue();
} else {
System.out.println("Invalid command");
}
} else {
phrase = commandPhrase[1];
if (command.equals("mark")) {
Duke.tasks.changeTaskState(true, Integer.parseInt(phrase));
} else if (command.equals("unmark")) {
Duke.tasks.changeTaskState(false, Integer.parseInt(phrase));
} else if (command.equals("event")) {
Duke.tasks.addEvent(phrase);
} else if (command.equals("todo")) {
Duke.tasks.addTodo(phrase);
} else if (command.equals("deadline")) {
Duke.tasks.addDeadline(phrase);
} else if (command.equals("delete")) {
Duke.tasks.delete(Integer.parseInt(phrase));
} else if (command.equals("find")) {
Duke.tasks.find(phrase);
} else {
System.out.println("Invalid command");
}
}
Duke.storage.saveToFile(Duke.tasks);
UI.horizontalLine();
}
userInput.close();
System.out.println("Bye. Hope to see you again soon!");
}
}
82 changes: 82 additions & 0 deletions src/main/java/Storage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;
import java.util.ArrayList;

/*
* Storage class handles all file methods of Duke, it only has the attribute fileName
*/
public class Storage {
private String fileName;

public Storage(String inputFileName) {
this.fileName = inputFileName;
}

/*
* Loads file from location specified by <code>fileName</code>
*
* @param none
*
* @return File object file from the location
*/
public void load(TaskList taskList) {
File file = new File(fileName);
String data;
try {
if (!file.createNewFile()) {
Scanner fileData = new Scanner(file);
while (fileData.hasNext()) {
data = fileData.nextLine();
String[] inputArgs = data.split("\\|");
addFileData(inputArgs, taskList);
for (String arg : inputArgs) {
System.out.print(arg + " ");
}
}
}
} catch (IOException e) {
System.out.print("\nError getting file data");
}
}

public void addFileData(String[] inputArgs, TaskList taskList) {
Task newTask;
String command = inputArgs[0];
boolean taskStatus = Boolean.parseBoolean(inputArgs[1]);
switch (command) {
case "T":
newTask = new Todo(inputArgs[2]);
break;
case "D":
newTask = new Deadline(inputArgs[2]);
break;
case "E":
newTask = new Event(inputArgs[2]);
break;
default:
throw new IllegalStateException("File contents are invalid");
}
if (taskStatus) {
newTask.markAsDone();
}
taskList.returnTaskList().add(newTask);
}

/*
* Saves file to destination specified by <code>fileName</code>, the same
* location where file is retrieved from
*/
public void saveToFile(TaskList taskList) {
try {
FileWriter fWriter = new FileWriter(fileName);
for (Task task : taskList.returnTaskList()) {
fWriter.write(task.fileFormat());
}
fWriter.close();
} catch (IOException e) {
System.out.print("IOException Error: data not saved to file\n");
}
}
}
Loading