-
Notifications
You must be signed in to change notification settings - Fork 454
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
[Pranav Ganesh] iP #477
base: master
Are you sure you want to change the base?
[Pranav Ganesh] iP #477
Changes from 26 commits
d839859
244ea63
05b4e5e
bad6e71
15cfb00
6a1c9de
667a5bd
57c60d1
e70d0aa
80299be
cfad495
10b01bb
2c44649
f7e6d0a
7ae663c
c6035cd
a5f3c25
8026b89
9605358
4537188
068f340
493460f
8479f34
02e7e75
8381e30
be2314a
ce9da73
1e3a89f
92529e0
11a840b
15859ea
528b73e
8621cd4
24169f9
1e26b45
013d465
f01545c
a84441a
c2dfd54
815d295
690a8f4
956c0a1
d8dfd36
bf16d73
c2cbb49
8afc4ce
2283f09
b93000a
5802939
3848c56
7668565
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ | |
/.idea/ | ||
/out/ | ||
/*.iml | ||
out/artifacts/ip_jar | ||
|
||
# Gradle build files | ||
/.gradle/ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,37 @@ | ||
import duke.Storage; | ||
import duke.task.TaskList; | ||
import duke.Ui; | ||
import duke.Parser; | ||
import duke.command.Command; | ||
|
||
public class Duke { | ||
private Storage storage; | ||
private TaskList taskList; | ||
private Ui ui; | ||
|
||
public Duke(String filePath) { | ||
taskList = new TaskList(); | ||
storage = new Storage(filePath); | ||
ui = new Ui(taskList, storage); | ||
} | ||
|
||
public void run() { | ||
ui.showWelcome(); | ||
ui.showLine(); | ||
boolean isExit = false; | ||
while (!isExit) { | ||
String command = ui.command(); | ||
Parser parser = new Parser(command); | ||
if (parser.isExit()) { | ||
break; | ||
} | ||
Command c = parser.parse(); | ||
c.execute(taskList, storage); | ||
isExit = parser.isExit(); | ||
} | ||
} | ||
|
||
public static void main(String[] args) { | ||
String logo = " ____ _ \n" | ||
+ "| _ \\ _ _| | _____ \n" | ||
+ "| | | | | | | |/ / _ \\\n" | ||
+ "| |_| | |_| | < __/\n" | ||
+ "|____/ \\__,_|_|\\_\\___|\n"; | ||
System.out.println("Hello from\n" + logo); | ||
new Duke("./duke.txt").run(); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
Manifest-Version: 1.0 | ||
Main-Class: Duke | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package duke; | ||
|
||
import duke.command.*; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You might want to avoid wild card imports even if you have to import everything There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For the Perhaps a switch statement here would help to improve readability or you could modify the code by splitting the string by the empty character delimiter twice so you don't have to do another Maybe your InvalidCommand can be an exception, and your doneCommand can throw the exception so you don't have to do all the checking within this method which could make the code easier to read |
||
|
||
public class Parser { | ||
private String command; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The string name Maybe change it to |
||
|
||
public Parser(String command) { | ||
this.command = command; | ||
} | ||
|
||
public Command parse() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps try not to write deeply nested loops in your function? You might consider using 'switch' for this function? |
||
if (command.equals("list")) { | ||
return new listCommand(command); | ||
} else if (command.startsWith("done") && Character.isDigit(command.charAt(command.length() - 1)) | ||
&& command.length() <= 8 && !Character.isAlphabetic(command.charAt(command.length() - 2)) | ||
&& Character.isDigit(command.charAt(5))) { | ||
return new doneCommand(command); | ||
} else { | ||
if (command.startsWith("todo")) { | ||
return new todoCommand(command); | ||
} else if (command.startsWith("deadline")) { | ||
return new deadlineCommand(command); | ||
} else if (command.startsWith("event")) { | ||
return new eventCommand(command); | ||
} else if (command.startsWith("delete")) { | ||
return new deleteCommand(command); | ||
} else { | ||
return new InvalidCommand(command); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can consider using a switch statement here 😄 |
||
} | ||
} | ||
} | ||
|
||
public boolean isExit() { | ||
if (command.equals("bye")) { | ||
Ui.bye(); | ||
Ui.showLine(); | ||
return true; | ||
} | ||
if (command.equals("")) { | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
} | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package duke; | ||
|
||
import org.junit.Test; | ||
import org.junit.Assert; | ||
|
||
public class ParserTest { | ||
@Test | ||
public void isExit_commandBye_true() { | ||
Assert.assertEquals(true, new Parser("bye").isExit()); | ||
} | ||
|
||
@Test | ||
public void isExit_commandEmptyString_true() { | ||
Assert.assertEquals(true, new Parser("").isExit()); | ||
} | ||
|
||
@Test | ||
public void isExit_commandDeadline_false() { | ||
Assert.assertEquals(false, new Parser("deadline book ticket/by 2016-09-22 1700").isExit()); | ||
} | ||
|
||
@Test | ||
public void parse_commandDeadline_success() { | ||
Assert.assertEquals("This is a deadline command", new Parser("deadline book ticket/by 2016-09-22 1700").parse().toString()); | ||
} | ||
|
||
@Test | ||
public void parse_commandEvent_success() { | ||
Assert.assertEquals("This is an event command", new Parser("event concert/at 2016-09-22 1900").parse().toString()); | ||
} | ||
|
||
@Test | ||
public void parse_commandTodo_success() { | ||
Assert.assertEquals("This is a todo command", new Parser("todo play cricket").parse().toString()); | ||
} | ||
|
||
@Test | ||
public void parse_commandDelete_success() { | ||
Assert.assertEquals("This is a delete command", new Parser("delete 1").parse().toString()); | ||
} | ||
|
||
@Test | ||
public void parse_commandDone_success() { | ||
Assert.assertEquals("This is a done command", new Parser("done 1").parse().toString()); | ||
} | ||
|
||
@Test | ||
public void parse_commandInvalidString_success() { | ||
Assert.assertEquals("This is an invalid command", new Parser("Some invalid string").parse().toString()); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
package duke; | ||
|
||
import duke.task.*; | ||
import java.io.File; | ||
import java.io.FileNotFoundException; | ||
import java.io.FileWriter; | ||
import java.io.IOException; | ||
import java.time.LocalDateTime; | ||
import java.time.format.DateTimeFormatter; | ||
import java.util.Scanner; | ||
|
||
public class Storage { | ||
private String filepath; | ||
private File file; | ||
|
||
public Storage(String filepath) { | ||
this.filepath = filepath; | ||
try { | ||
File file = new File(filepath); | ||
if (!file.exists()) { | ||
file.createNewFile(); | ||
} | ||
this.file = file; | ||
} catch (IOException e) { | ||
System.out.println("Something went wrong: " + e.getMessage()); | ||
} | ||
} | ||
|
||
public void loadTaskListData(TaskList taskList) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You may want to document public methods with javadocs The method here is also quite lengthy. It might be a good idea to abstract the other logic into various methods There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You might want to break it down into smaller functions here? This function seems to be too deeply nested. |
||
try { | ||
Scanner s = new Scanner(this.file); // create a Scanner using the File as the source | ||
if (!s.hasNext()) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The logic here is quite deeply nested, perhaps it might be good if you handled the unusual case with a guard clause if (!s.hasNext()) {
// code here...
return;
} |
||
Ui.printMessage("There are no items in your task list!"); | ||
} else { | ||
Ui.printMessage("Here is your current task list: "); | ||
while (s.hasNext()) { | ||
String str = s.nextLine(); | ||
System.out.println(str); | ||
String[] parts = str.split("\\|", 4); | ||
String subStr = parts[0].substring(3).trim(); | ||
if (subStr.equals("duke.task.Todo") || subStr.equals("duke.task.Todo")) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I might be wrong here but doesn't |
||
Task task = new Todo(parts[2].trim()); | ||
if (parts[1].trim().equals("X")) { | ||
task.markAsDone(); | ||
} | ||
taskList.addTask(task); | ||
} else if (subStr.equals("duke.task.Deadline") || subStr.equals("duke.task.Deadline")) { | ||
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MMM d yyyy, h a"); | ||
LocalDateTime dateTime = LocalDateTime.parse(parts[3].substring(5).trim(), dtf); | ||
Task task = new Deadline(parts[2].trim(), dateTime); | ||
if (parts[1].trim().equals("X")) { | ||
task.markAsDone(); | ||
} | ||
taskList.addTask(task); | ||
} else { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You may want to use a switch statement for this long if else. It may be good because you're comparing strings and it can directly be used for your cases. Additionally the else statement here captures all other cases of subStr, not necessarily when it is an The default case in a switch statement could be used to catch invalid cases. I believe the default case is optional in Java The style guide suggests that
|
||
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MMM d yyyy, h a"); | ||
LocalDateTime dateTime = LocalDateTime.parse(parts[3].substring(5).trim(), dtf); | ||
Task task = new Event(parts[2].trim(), dateTime); | ||
if (parts[1].trim().equals("X")) { | ||
task.markAsDone(); | ||
} | ||
taskList.addTask(task); | ||
} | ||
} | ||
Ui.printMessage("End of task list"); | ||
} | ||
} catch (FileNotFoundException e) { | ||
System.out.println("File not found!"); | ||
} | ||
} | ||
|
||
public void writeToFile(String filePath, TaskList tl) { | ||
try { | ||
FileWriter fw = new FileWriter(filePath); | ||
for (int i = 0; i < tl.size(); i++) { | ||
int num = i + 1; | ||
fw.write(num + ". " + tl.getTask(i).taskListOnDisk() + "\n"); | ||
} | ||
fw.close(); | ||
} catch (IOException e) { | ||
System.out.println("Something went wrong: " + e.getMessage()); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package duke; | ||
|
||
import duke.task.Task; | ||
import duke.task.TaskList; | ||
import java.util.Scanner; | ||
|
||
public class Ui { | ||
Scanner sc; | ||
private static TaskList taskList; | ||
private static Storage storage; | ||
Comment on lines
+13
to
+14
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why are taskList and storage static? |
||
|
||
public Ui(TaskList taskList, Storage storage) { | ||
sc = new Scanner(System.in); | ||
this.taskList = taskList; | ||
this.storage = storage; | ||
} | ||
|
||
public String command() { | ||
if (sc.hasNextLine()) { | ||
String str = sc.nextLine(); | ||
return str; | ||
} | ||
return ""; | ||
} | ||
|
||
public void showWelcome() { | ||
System.out.println("Hello from Duke!"); | ||
System.out.println(""); | ||
storage.loadTaskListData(taskList); | ||
System.out.println(""); | ||
System.out.println("Hope you are doing well. How can I help you?"); | ||
} | ||
|
||
public static void bye() { | ||
System.out.println("Bye. Have a great day!"); | ||
} | ||
|
||
public static void showLine() { | ||
System.out.println("-----------------------------------------------"); | ||
} | ||
|
||
public static void printMessage(String msg) { | ||
System.out.println(msg); | ||
} | ||
|
||
public static void taskResponse(Task task) { | ||
System.out.println("Got it. I've added this task:"); | ||
System.out.println(task); | ||
System.out.println("Now you have " + taskList.size() + " tasks in the list."); | ||
} | ||
|
||
public static void doneResponse(Task task) { | ||
System.out.println("Nice! I've marked this task as done:"); | ||
System.out.println(task); | ||
storage.writeToFile("./duke.txt", taskList); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good idea to write to file everytime a task is edited. This way the state of the tasks are not lost incase the app crashes. |
||
|
||
public static void deleteResponse(Task task) { | ||
System.out.println("Noted. I've removed this task:"); | ||
System.out.println(task); | ||
System.out.println("Now you have " + taskList.size() + " tasks in the list."); | ||
} | ||
} | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package duke.command; | ||
|
||
import duke.Storage; | ||
import duke.task.TaskList; | ||
|
||
public abstract class Command { | ||
private String command; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps consider making |
||
|
||
public Command(String command) { | ||
this.command = command; | ||
} | ||
|
||
public abstract void execute(TaskList taskList, Storage storage); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package duke.command; | ||
|
||
import duke.exception.DukeException; | ||
import duke.exception.InvalidCommandException; | ||
import duke.Storage; | ||
import duke.task.TaskList; | ||
|
||
public class InvalidCommand extends Command { | ||
private String command; | ||
|
||
public InvalidCommand(String command) { | ||
super(command); | ||
this.command = command; | ||
} | ||
|
||
public String toString() { | ||
return "This is an invalid command"; | ||
} | ||
|
||
public void execute(TaskList taskList, Storage storage) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should have |
||
DukeException exp = new InvalidCommandException("OOPS!!! I'm sorry, but I don't know what that means :-("); | ||
System.out.println(exp); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can consider making
parse()
a static method, that way you would not have to create a new parser object everytime a command is given.