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

[Bingyuan] iP #230

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
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