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

[Saketh] iP #484

Open
wants to merge 38 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
d839859
Add Gradle support
May 24, 2020
4d0258b
Finished Level-1
loose-bus-change Aug 19, 2021
916e1a4
Finished Level-2
loose-bus-change Aug 19, 2021
9ee2158
Finished Level-3
loose-bus-change Aug 19, 2021
6a59fbe
Finished Level-4
loose-bus-change Aug 19, 2021
ad750b7
Finished A-TextUiTesting
loose-bus-change Aug 19, 2021
35ab331
Finished Level-5
loose-bus-change Aug 19, 2021
32dfefd
Finished Level-6
loose-bus-change Aug 19, 2021
e5200af
Finished Level-7
loose-bus-change Aug 28, 2021
2fa7e3c
Finished Level-8
loose-bus-change Aug 28, 2021
250c123
Merge branch 'branch-Level-7'
loose-bus-change Aug 28, 2021
23f2c19
Finished Level-8
loose-bus-change Aug 28, 2021
0879b67
Finished A-More-OOP
loose-bus-change Aug 29, 2021
ae519f8
Finished A-Packages
loose-bus-change Aug 29, 2021
86b9868
Finished JUnit Testing
loose-bus-change Aug 29, 2021
3281b26
Finished A-Jar
loose-bus-change Aug 29, 2021
b087b26
Finish branch-A-JavaDoc
loose-bus-change Aug 30, 2021
c907c92
Finish A-CodingStandard
loose-bus-change Aug 30, 2021
3333058
Finish branch-Level-9
loose-bus-change Aug 30, 2021
0cad0cf
Merge branch 'branch-A-JavaDoc'
loose-bus-change Aug 30, 2021
4784c9a
Finish A-CodingStandard
loose-bus-change Aug 30, 2021
43952bf
Merge branch 'branch-Level-9'
loose-bus-change Aug 30, 2021
b571757
Merge remote-tracking branch 'origin/add-gradle-support'
loose-bus-change Sep 2, 2021
e13fa9f
Finish Level-10
loose-bus-change Sep 7, 2021
ebf9a1c
Fix reading from text file
loose-bus-change Sep 8, 2021
95a3313
Finish A-Assertions
loose-bus-change Sep 10, 2021
9a716a9
Finish-A-CodeQuality
loose-bus-change Sep 11, 2021
c62e3af
Merge pull request #1 from loose-bus-change/branch-A-Assertions
loose-bus-change Sep 11, 2021
d397c7e
Changes
loose-bus-change Sep 11, 2021
ff9f39c
Fix conflicts
loose-bus-change Sep 11, 2021
dd5f648
Merge branch 'master' into branch-A-CodeQuality
loose-bus-change Sep 11, 2021
ff57ee3
Merge pull request #2 from loose-bus-change/branch-A-CodeQuality
loose-bus-change Sep 11, 2021
9a398f3
Fix conflict in text file
loose-bus-change Sep 11, 2021
10980c9
Finish BCD-Extensions
loose-bus-change Sep 11, 2021
223c05f
Add Ui.png
loose-bus-change Sep 19, 2021
1d6ed65
Add User guide
loose-bus-change Sep 20, 2021
e9fb36d
Update ReadMe
loose-bus-change Sep 20, 2021
8f6e846
Edit User guide
loose-bus-change Sep 20, 2021
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
4 changes: 4 additions & 0 deletions data/duke.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[D][ ] return book by: 2019-12-02
[E][ ] test code at: 2018-11-03
[E][ ] meeting at: 2015-10-15
[E][X] project meeting at: 2015-10-15
Empty file added data/tasks.txt
Empty file.
55 changes: 49 additions & 6 deletions src/main/java/Duke.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,53 @@
import duke.*;

Choose a reason for hiding this comment

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

Would it be better to list all the imported classes?

Choose a reason for hiding this comment

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

I concur with @gordonlzy. I think this violates one of the coding standards.

Copy link

Choose a reason for hiding this comment

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

I agree as well. Imports should be one at a time.

import java.io.File;

public class Duke {
private Storage storage;
private TaskList tasks;
private File
file;

Choose a reason for hiding this comment

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

Any reason why you put file on the next line?

private Parser p;
Copy link

Choose a reason for hiding this comment

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

Avoid one letter names; parser would be a better name

private Ui ui;

public Duke(String filePath) {
storage = new Storage(filePath);
try {
tasks = new TaskList(filePath);
} catch (DukeException e) {
ui.showLoadingError();
tasks = new TaskList(filePath);
}
ui = new Ui(tasks, storage);
p = new Parser();
this.file = new File(filePath);
tasks.readFromFile();
}

/**
* Method that runs the Duke by asking for user input
*
* @return void
*/
public void run() {
System.out.println("Hello! This is Duke, your very own chat bot.");
System.out.println("What can I help you with ?");
while (true) {
String fullCommand = ui.input();
if (!fullCommand.equals("bye")) {
try {
p.parse(fullCommand, tasks, storage, file);
} catch (DukeException e) {
System.out.println(e.getMsg());
}
} else {
System.out.println("It's sad to see you go :(");
System.out.println("Goodbye, hope to you another day!");
break;
}
}
}

public static void main(String[] args) {
String logo = " ____ _ \n"
+ "| _ \\ _ _| | _____ \n"
+ "| | | | | | | |/ / _ \\\n"
+ "| |_| | |_| | < __/\n"
+ "|____/ \\__,_|_|\\_\\___|\n";
System.out.println("Hello from\n" + logo);
new Duke("./data/duke.txt").run();
}
}
3 changes: 3 additions & 0 deletions src/main/java/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Manifest-Version: 1.0
Main-Class: Duke

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

public abstract class Command {
private String input;

public Command(String input) {
this.input = input;
}

public abstract void execute(TaskList t, Storage s);
}
25 changes: 25 additions & 0 deletions src/main/java/duke/Deadline.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package duke;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class Deadline extends Task {
protected LocalDate by;
Copy link

Choose a reason for hiding this comment

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

In my opinion, deadline seems to be a better name compared to by

private String dateForObject;

public Deadline(String description, LocalDate by) {
super(description);
this.by = by;
this.dateForObject = by.format(DateTimeFormatter.ofPattern("MMM d yyyy"));
}

/**
* toString() method for deadline object
*
* @return String The task printed in the correct format
*/
@Override
public String toString() {
return "[D]" + super.toString() + " by: " + this.by;
}
}
31 changes: 31 additions & 0 deletions src/main/java/duke/DukeException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package duke;

public abstract class DukeException extends RuntimeException {
public DukeException(String message) {
super(message);
}

public String getMsg() {
return "";
}
}

class NullTaskError extends DukeException {
public NullTaskError() {
super("OOPS!!! The description of a todo cannot be empty.");
}
Copy link

Choose a reason for hiding this comment

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

I think it would be better for type to be in the constructor instead of the getMsg method.


public String getMsg(String type) {
return "OOPS!!! The description of a " + type + " cannot be empty.";
}
}

class NonExistentKeyword extends DukeException {
public NonExistentKeyword() {
super("OOPS!!! I'm sorry, but I don't know what that means :-(");
}

public String getMsg() {
return "OOPS!!! I'm sorry, but I don't know what that means :-(";
}
}
20 changes: 20 additions & 0 deletions src/main/java/duke/Event.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package duke;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class Event extends Task{
protected LocalDate at;
private String dateForObject;

public Event(String description, LocalDate at) {
super(description);
this.at = at;
this.dateForObject = at.format(DateTimeFormatter.ofPattern("MMM d yyyy"));
}

@Override
public String toString() {
return "[E]" + super.toString() + " at: " + this.at;
}
}
125 changes: 125 additions & 0 deletions src/main/java/duke/Parser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package duke;

import java.io.File;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;

public class Parser {

/**
* Method that adds a Deadline task onto TaskList
*
* @param input The string that contains the user input
* @param t The TaskList that contains the tasks to be added

Choose a reason for hiding this comment

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

perhaps the naming of some of the parameters could be more verbose; however this is just nitpicky, since your javadocs already explain what the parameters mean. Good work! 👍🏻

* @param s The Storage that handles the reading and writing to a text file
* @param file The file that gets written to and read from
*
* @return void

Choose a reason for hiding this comment

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

Is it necessary to add @return for void?

*/
public static void parse(String input, TaskList t, Storage s, File file) {
if (input.equals("list")) {
for (int i = 0; i < t.size(); i++) {
System.out.println(i + 1 + "." + t.get(i).toString());
}
} else if (input.startsWith("done") && Character.isDigit(input.charAt(input.length() - 1))
&& input.length() <= 8 && !Character.isAlphabetic(input.charAt(input.length() - 2))
&& Character.isDigit(input.charAt(5))) {
int value = Integer.parseInt(input.replaceAll("[^0-9]", ""));
t.get(value - 1).markAsDone();
System.out.println("Nice! I've marked this task as done: ");
System.out.println("[X] " + t.get(value-1).description);
s.appendListToFile(t);
} else if (input.startsWith("todo")) {
if (input.length() < 6) {
System.out.println(new NullTaskError().getMsg("todo"));
} else {
String firstTodo = input.substring(5);
t.addTodo(firstTodo);
System.out.println("Got it. I've added this task: ");
System.out.println(new Todo(firstTodo));
System.out.println("Now you have " + t.size() + " tasks in the list");
s.appendListToFile(t);
}
} else if (input.startsWith("deadline")) {
if (input.length() < 10) {
System.out.println(new NullTaskError().getMsg("deadline"));
} else {
String[] temp = input.split("/by");
String firstDeadline = temp[0].substring(9);
String[] splitDate = temp[1].split(" ");
String date = splitDate[1];
String[] breakingDate = date.split("/");
String year = breakingDate[2];
String month = breakingDate[1];
String currentDate = breakingDate[0];
int i = Integer.parseInt(currentDate);
if (i < 10) {
currentDate = "0" + currentDate;
}
String finalDateFormat = year + "-" + month + "-" + currentDate;
LocalDate date1 = LocalDate.parse(finalDateFormat);
Copy link

Choose a reason for hiding this comment

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

Can be simplified using method LocalDate.of

String dateForObject = date1.format(DateTimeFormatter.ofPattern("MMM d yyyy"));
t.addDeadline(firstDeadline, date1);
System.out.println("Got it. I've added this task: ");
System.out.println(new Deadline(firstDeadline, date1));
System.out.println("Now you have " + t.size() + " tasks in the list");
s.appendListToFile(t);
}
} else if (input.startsWith("event")) {
if (input.length() < 7) {
System.out.println(new NullTaskError().getMsg("event"));
} else {
String[] tempEvent = input.split("/at");
String firstEvent = tempEvent[0].substring(6);
System.out.println(firstEvent);
String[] splitDate = tempEvent[1].split(" ");
String date = splitDate[1];
String[] breakingDate = date.split("/");
String year = breakingDate[2];
String month = breakingDate[1];
String currentDate = breakingDate[0];
int i = Integer.parseInt(currentDate);
if (i < 10) {
currentDate = "0" + currentDate;
}
String finalDateFormat = year + "-" + month + "-" + currentDate;
LocalDate date1 = LocalDate.parse(finalDateFormat);
System.out.println(date1);
t.addEvent(firstEvent, date1);
System.out.println("Got it. I've added this task: ");
System.out.println(new Event(firstEvent, date1));
System.out.println("Now you have " + t.size() + " tasks in the list");
s.appendListToFile(t);
}
} else if (input.startsWith("delete") && input.length() < 11) {
int value = Integer.parseInt(input.replaceAll("[^0-9]", ""));
Task removedTask = t.get(value - 1);
t.delete(value - 1);
System.out.println("Noted. I've removed this task:");
System.out.println(removedTask.toString());
System.out.println("Now you have " + t.size() + " tasks in the list.");
s.appendListToFile(t);
} else if (input.startsWith("find")) {
String keyword = input.substring(5);
ArrayList<Task> output = new ArrayList<>();

Choose a reason for hiding this comment

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

Perhaps the usage of plural form for output will work better?

Copy link

Choose a reason for hiding this comment

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

I think the variable name should be completely renamed. The queried tasks aren't an "output"; they are the result of a query, and are then reformatted into a text result that gets printed.

int count = 0;
for (Task task: t.getTaskList()) {
String desc = task.description.substring(0,task.description.length()-4);
String[] splitDesc = desc.split(" ");
for (String str: splitDesc) {
if (str.equals(keyword)) {
System.out.println(task.toString());
count = count + 1;
}
}
}
if (count == 0) {
System.out.println("OOPS! The task does not exist");
}
} else {
DukeException e = new NonExistentKeyword();
System.out.println(e.getMsg());
}
}
}
43 changes: 43 additions & 0 deletions src/main/java/duke/Storage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package duke;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class Storage {
private String filePath;
private File file;

public Storage(String filePath) {
this.filePath = filePath;
File file = new File(filePath);
this.file = file;

}



/**
* Method that adds the Tasklist arraylist into the text file
*
* @param listOfTasks The TaskList that contains all the tasks added
*
* @return void
*/
public static void appendListToFile(TaskList listOfTasks) {
try {
File fileStorage = new File("data/duke.txt");
FileWriter w = new FileWriter(fileStorage);
String str = "";
for (Task t : listOfTasks.getTaskList()) {
str += t.toString() + "\n";
}
w.write(str);
w.close();
} catch (IOException e) {
System.out.println("File does not exist");
}
}
}


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

public class Task {
protected String description;
protected boolean isDone;

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

public String toString() {
return "[" + this.getStatusIcon() + "] " + this.description;
}

/**
* Method that returns the status icon of the task based on whether it is completed.
* or not
*
* @return String Either "X" or " " based on the status
*/
public String getStatusIcon() {
return (isDone ? "X" : " "); // mark done task with X
}

/**
* Method that marks a task as done.
*
* @return void
*/
public void markAsDone() {
this.isDone = true;
}
}
Loading