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

[Sng Jia Ming Fadi Faris] Duke Increments #345

Open
wants to merge 45 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
65f72a8
Add support for Gradle workflow
j-lum Aug 6, 2019
0112efe
Add sample checkstyle configuration
j-lum Aug 12, 2019
cfd6da7
Change file mode on `gradle` to be executable
j-lum Aug 18, 2019
6e6ace1
Merge pull request #12 from j-lum/gradle+x
j-lum Aug 18, 2019
ba11701
Level - 1
fadisng Aug 21, 2019
c80085c
Level - 2
fadisng Aug 21, 2019
244fb4c
Level - 3
fadisng Aug 21, 2019
c0d63f6
Level - 4
fadisng Aug 21, 2019
47514be
Level - 5
fadisng Aug 22, 2019
6cc2e4d
Level - 6
fadisng Aug 22, 2019
b382bd3
Level-7
fadisng Aug 26, 2019
7fc08ec
Level-8
fadisng Aug 26, 2019
72b02cc
Level-8
fadisng Aug 26, 2019
a9033c2
A-MoreOOP
fadisng Aug 28, 2019
1c677e6
A-JUnit
fadisng Aug 28, 2019
31cc0a3
A-JUnit
fadisng Aug 28, 2019
4ea22d1
A-JUnit
fadisng Aug 28, 2019
4065b7f
A-Jar
fadisng Aug 28, 2019
743b785
A-JavaDoc
fadisng Aug 28, 2019
8c1dace
A-CodingStandard
fadisng Aug 28, 2019
126535c
branch-Level-9
fadisng Aug 28, 2019
02cf134
Merge branch 'branch-A-JavaDoc'
fadisng Aug 28, 2019
9e1c42d
Merge branch 'branch-Level-9'
fadisng Aug 28, 2019
de2854d
Merge branch 'gradle' of https://github.com/fadisng/duke
fadisng Aug 29, 2019
625f50e
A-Gradle
fadisng Aug 29, 2019
9e36be2
Level-10
fadisng Aug 29, 2019
646cc92
Revert "Level-10"
fadisng Sep 2, 2019
1ebbacc
branch-A-Gradle
fadisng Sep 2, 2019
474710e
Level-10
fadisng Sep 4, 2019
e6e293d
Level-10
fadisng Sep 6, 2019
e71990a
Level-10
fadisng Sep 6, 2019
e32e2e1
A-Assertions
fadisng Sep 9, 2019
615cda1
A-CodeQuality
fadisng Sep 9, 2019
cc3d359
Revert "A-CodeQuality"
fadisng Sep 9, 2019
c878f87
A-CodeQuality
fadisng Sep 9, 2019
77a0e35
Merge branch 'branch-A-Assertions' into branch-A-CodeQuality
fadisng Sep 9, 2019
ecd4eb2
C-Update
fadisng Sep 11, 2019
57ada88
Final changes
fadisng Sep 28, 2019
72e8820
UG update
fadisng Sep 28, 2019
1639538
Ui
fadisng Sep 28, 2019
2220297
Indentation
fadisng Sep 29, 2019
e979df1
Javadocs
fadisng Sep 29, 2019
c8aea88
Merge pull request #5 from fadisng/Javadocs
fadisng Sep 29, 2019
2a8a2ce
Merge pull request #6 from fadisng/Checkstyle
fadisng Sep 29, 2019
56de869
Update README.md
fadisng Oct 11, 2019
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
Empty file added Duke.txt
Empty file.
Binary file added src/main/java/AddCommand.class
Binary file not shown.
54 changes: 54 additions & 0 deletions src/main/java/AddCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
* Represents the command to add a task into the arraylist.
*/

import java.text.ParseException;

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's custom to have the class's javadoc comments to be directly above the declaration of the class, after any relevant import statements.

public class AddCommand extends Command {
private String[] arr;

public AddCommand(String[] arr) {
this.arr = arr;
}

@Override
public void execute(TaskList tasks, Ui ui, Storage storage){
String description = "";
Task t;
String next = arr[0];
try {
if (next.equals("todo") || next.equals("deadline") || next.equals("event")) {
if (arr.length == 1) {
throw new EmptyDescriptionException("☹ OOPS!!! The description of a " + next + " cannot be empty.");

Choose a reason for hiding this comment

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

It may be a little easier to have the message already in toString() method of EmptyDescriptionException, so you only have take in the type as a parameter. E.g throw new EmptyDescriptionException("todo"). Since you will be throwing this exception frequently, you won't need to type the message everytime. :)

} else {
for (int i = 1; i < arr.length; i++) {
description += " " + arr[i];
}
}
} else {
throw new UnknownTaskException("☹ OOPS!!! I'm sorry, but I don't know what that means :-(");

Choose a reason for hiding this comment

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

It may be a little easier to have the message already in toString() method of UnknownTaskException :)

}
System.out.println("Got it. I've added this task:");
if (next.equals("todo")) {

Choose a reason for hiding this comment

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

Not sure if this is better, but it used switch case so that .equals(...) would not be used that often :)

t = new Todos(description.trim());
} else if (next.equals("deadline")) {
int index = description.indexOf("/");
String byWhen = description.substring(index + 4);

Choose a reason for hiding this comment

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

Good idea! Another idea to split your string by "...".split("/by") instead so you would not need to care about the index:)

String desc = description.substring(1, index - 1);
t = new Deadline(desc, byWhen);
} else {
int index = description.indexOf("/");

Choose a reason for hiding this comment

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

This is a smart idea! You can also split the string by "...".split("/at") so you would not need to count the index. :)

Copy link

Choose a reason for hiding this comment

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

Just to add on, if you use the indexOf("/"), this might not have the intended effect when you have a deadline task initialised with the following command as an example:
deadline todo/or not to do that is the question /by 12/12/12 12:12
You can split as @Joanna-YJA suggested, and check if there is more than 2 items in the resulting String array. From there you may proceed to throw the appropriate DukeExceptions.

String at = description.substring(index + 4);
String desc = description.substring(1, index - 1);
t = new Event(desc, at);
}
tasks.getList().add(t);
ui.printTask(tasks.getList().size(), t);
} catch (DukeException e) {
System.out.println(e.getMessage());
} catch (ParseException e) {
System.out.println("Date in wrong format");
}
storage.writeFile(tasks.getList());
}
}
Binary file added src/main/java/Command.class
Binary file not shown.
15 changes: 15 additions & 0 deletions src/main/java/Command.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* Abstract class to represent the possible commands given to Duke.
*/

public abstract class Command {

/**
* Executes the different commands respectively.
* @param tasks Arraylist of tasks.

Choose a reason for hiding this comment

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

it may be a good idea to add attributes like isDone or methods like markAsDone() to encapsulate whether as task is done(needed when we load tasks from the file). Since all tasks need this. :)

* @param ui User interaction that comes with the command.
* @param storage To deal with saving tasks into the file after executing the command.
*/
public abstract void execute(TaskList tasks, Ui ui, Storage storage);

}
Binary file added src/main/java/Deadline.class
Binary file not shown.
41 changes: 41 additions & 0 deletions src/main/java/Deadline.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* Deadline class to represent a task with a date to be done by.
*/

import java.text.ParseException;
import java.util.Date;
import java.text.SimpleDateFormat;

public class Deadline extends Task {

protected String by;
protected Date date;

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

Choose a reason for hiding this comment

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

Just wondering, why do you need by and date attributes? As I was thinking that since they are similar representations of the same thing, and date can also be used in the toString() method, it is alright to keep date only. :)

this.date = new SimpleDateFormat("dd/MM/yyyy HHmm").parse(by);
}

public Deadline(String description, boolean isDone, String by) throws ParseException {
super(description, isDone);
this.by = by;
this.date = new SimpleDateFormat("dd/MM/yyyy HHmm").parse(by);
}

@Override
public String toString() {
SimpleDateFormat formatter = new SimpleDateFormat("d MMMM yyyy, hmma");
String formattedDate = formatter.format(this.date);
return "[D]" + super.toString() + " (by: " + formattedDate + ")";
}

@Override
public String print() {
if (this.isDone) {
return "D @ 1 @ " + this.description + " @ " + this.by;
} else {
return "D @ 0 @ " + this.description + " @ " + this.by;
}
}
}
Copy link

Choose a reason for hiding this comment

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

Consider adding newlines at the end of your files, as it is a general convention. It doesn't really cause any issues beside making GitHub and checkstyle whine, but there is a reason behind doing so, https://stackoverflow.com/questions/729692/why-should-text-files-end-with-a-newline. Hope this gives some insight!

Binary file added src/main/java/DeleteCommand.class
Binary file not shown.
19 changes: 19 additions & 0 deletions src/main/java/DeleteCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* Represents a command to remove a task from the arraylist.
*/

public class DeleteCommand extends Command {
private int taskNumber;

public DeleteCommand(int taskNumber) {
this.taskNumber = taskNumber;
}

@Override
public void execute(TaskList tasks, Ui ui, Storage storage) {
Task taskRemoved = tasks.getList().remove(taskNumber);
System.out.println("Noted. I've removed this task:");
ui.printTask(tasks.getList().size(), taskRemoved);
storage.writeFile(tasks.getList());
}
}
Binary file added src/main/java/DoneCommand.class
Binary file not shown.
35 changes: 35 additions & 0 deletions src/main/java/DoneCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* Represents a command that ticks off a task.
*/

public class DoneCommand extends Command {
private int taskNumber;

public DoneCommand(int taskNumber) {
this.taskNumber = taskNumber;
}
@Override
public void execute(TaskList tasks, Ui ui, Storage storage) {
Task taskDone = tasks.getList().get(taskNumber);
taskDone.markAsDone();
System.out.println("Nice! I've marked this task as done:\n " + taskDone);
storage.writeFile(tasks.getList());
}

public int getTaskNumber() {
return taskNumber;
}

@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
} else if (obj == null || obj.getClass() != this.getClass()) {
return false;
} else {
DoneCommand command = (DoneCommand) obj;
return taskNumber == command.getTaskNumber();
}

}
}
Binary file added src/main/java/Duke.class
Binary file not shown.
41 changes: 34 additions & 7 deletions src/main/java/Duke.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,37 @@
/**
* Main driving class for Duke.
*/

import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.ParseException;

public class Duke {

private Storage storage;
private TaskList list;
private Ui ui;

public Duke(String file) {
ui = new Ui();
storage = new Storage(file);
list = new TaskList(storage.load());
}

public void run() {
ui.showWelcome();
boolean isExit = false;
while (!isExit) {
String fullCommand = ui.readCommand();
Command c = Parser.parse(fullCommand);
c.execute(list, ui, storage);
isExit = c instanceof ExitCommand;

Choose a reason for hiding this comment

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

Good idea!

}
}


public static void main(String[] args) {
String logo = " ____ _ \n"
+ "| _ \\ _ _| | _____ \n"
+ "| | | | | | | |/ / _ \\\n"
+ "| |_| | |_| | < __/\n"
+ "|____/ \\__,_|_|\\_\\___|\n";
System.out.println("Hello from\n" + logo);
Duke duke = new Duke("Duke_List.txt");
duke.run();
}
}
}
Binary file added src/main/java/DukeException.class
Binary file not shown.
9 changes: 9 additions & 0 deletions src/main/java/DukeException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* Represents exceptions specific to Duke.
*/

public class DukeException extends Exception {
public DukeException(String message) {
super(message);
}
}
2 changes: 2 additions & 0 deletions src/main/java/Duke_List.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
D @ 1 @ art project @ 04/04/2009 1600
T @ 1 @ borrow book
Binary file added src/main/java/EmptyDescriptionException.class
Binary file not shown.
9 changes: 9 additions & 0 deletions src/main/java/EmptyDescriptionException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* An exception that occurs when a task has no description.
*/

public class EmptyDescriptionException extends DukeException {
public EmptyDescriptionException(String message) {
super(message);
}
}
Binary file added src/main/java/Event.class
Binary file not shown.
40 changes: 40 additions & 0 deletions src/main/java/Event.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* Event class to represent a task that occurs on a certain date.
*/

import java.text.ParseException;
import java.util.Date;
import java.text.SimpleDateFormat;

public class Event extends Task {
protected Date date;
protected String at;

public Event(String description, String at) throws ParseException {
super(description);
this.at = at;
this.date = new SimpleDateFormat("dd/MM/yyyy HHmm").parse(at);
}

public Event(String description, boolean isDone, String at) throws ParseException {
super(description, isDone);
this.at = at;
this.date = new SimpleDateFormat("dd/MM/yyyy HHmm").parse(at);
}

@Override
public String toString() {
SimpleDateFormat formatter = new SimpleDateFormat("d MMMM yyyy, hmma");

Choose a reason for hiding this comment

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

You could also format the date attribute to this format in the constructor, and use it for all your methods, like toString() and more.

String formattedDate = formatter.format(this.date);
return "[E]" + super.toString() + " (at: " + formattedDate + ")";
}

@Override
public String print() {
if (this.isDone) {
return "E @ 1 @ " + this.description + " @ " + this.at;
} else {
return "E @ 0 @ " + this.description + " @ " + this.at;
}
}
}
Binary file added src/main/java/ExitCommand.class
Binary file not shown.
10 changes: 10 additions & 0 deletions src/main/java/ExitCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* Represents the command for Duke to terminate.
*/

public class ExitCommand extends Command {
@Override
public void execute(TaskList tasks, Ui ui, Storage storage) {
System.out.println("Bye. Hope to see you again soon!");
}
}
Binary file added src/main/java/FindCommand.class
Binary file not shown.
24 changes: 24 additions & 0 deletions src/main/java/FindCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import java.util.ArrayList;

public class FindCommand extends Command {
private String description;

public FindCommand(String description) {
this.description = description;
}
@Override
public void execute(TaskList tasks, Ui ui, Storage storage) {
System.out.println("Here are the matching tasks in your list:");
ArrayList<Task> matchingTasks = new ArrayList<>();

Choose a reason for hiding this comment

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

I thought about this idea too! I chose to use streams in the end as the code is much simpler, this is a good idea!

int count = 1;
for (Task task : tasks.getList()) {
if (task.getDescription().contains(description)) {
matchingTasks.add(task);
}
}
for (Task task : matchingTasks) {
System.out.println(count + "." + task);
count++;
}
}
}
Binary file added src/main/java/ListCommand.class
Binary file not shown.
16 changes: 16 additions & 0 deletions src/main/java/ListCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* Represents a command to print out the tasks in the arraylist.
*/

public class ListCommand extends Command {

@Override
public void execute(TaskList tasks, Ui ui, Storage storage) {
System.out.println("Here are the tasks in your list:");
int listCount = 1;

Choose a reason for hiding this comment

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

I would recommend streams to simplify your code.

for (Task task : tasks.getList()) {
System.out.println(listCount + "." + task);
listCount++;
}
}
}
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

Binary file added src/main/java/Parser.class
Binary file not shown.
37 changes: 37 additions & 0 deletions src/main/java/Parser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* Parser class to handle user input.
*/
public class Parser {

/**
* Parses the input string and determines the type of command given.
* @param str The input string supplied to Duke.
* @return Returns the corresponding command depending on the first word of the input string.
*/
public static Command parse(String str) {
String[] arr = str.split(" ");

Choose a reason for hiding this comment

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

Splitting the string is a good idea! I used contains(...) method instead.

String next = arr[0];
Command c;
switch (next) {
case "find":
c = new FindCommand(arr[1]);
break;
case "bye":
c = new ExitCommand();
break;
case "list":
c = new ListCommand();
break;
case "done":
c = new DoneCommand(Integer.parseInt(arr[1]) - 1);
break;
case "delete":
c = new DeleteCommand(Integer.parseInt(arr[1]) - 1);
break;
default:
c = new AddCommand(arr);

Choose a reason for hiding this comment

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

It may be more easier to specify the deadline, description, whether it is done and other attributes inside the constructor of AddCommand, since the String input is already split.

break;
}
return c;
}
}
Binary file added src/main/java/Storage.class
Binary file not shown.
Loading