-
Notifications
You must be signed in to change notification settings - Fork 434
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
sarjinius iP #474
base: master
Are you sure you want to change the base?
sarjinius iP #474
Changes from 25 commits
55f9f9f
f837ddb
a6f7324
4fda194
30db664
5b2458d
a4fbab2
dff389f
7f84653
bdb8f27
1f1e2b1
c3c9722
7458497
1bfce71
1d5af97
3057eee
dbd50a2
b565b98
0178d19
08d5140
c70784b
8e8f791
2d54ec1
da1e33c
f774215
8ef4a63
5ff1d0b
b012664
4e82e16
c03eaf8
e89cfd2
85c0262
a36cee0
9169b79
beebe61
36260c6
9839681
341de20
7d86535
17640c9
23bc68a
2936133
462fa52
2740425
0b48734
95de22d
819a874
bf1cf6f
86214c2
347f5f9
8036d65
3f42a80
19a8b03
7ab0a1c
f311cf5
6688e6e
2d3f605
5d9d7fd
6b00519
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 |
---|---|---|
@@ -0,0 +1,3 @@ | ||
T | 0 | Finish Assignment | ||
D | 0 | Prepare Gift | Feb 22nd | ||
E | 1 | Spend time | Feb 12 | Feb 14 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
package virtue; | ||
|
||
public class Command { | ||
// The available types of commands in Virtue. | ||
public enum CommandType { | ||
BYE ("bye", false, false), | ||
LIST ("list", false, false), | ||
MARK ("mark", true, false), | ||
UNMARK ("unmark", true, false), | ||
TODO ("todo", false, true), | ||
DEADLINE ("deadline", false, true), | ||
EVENT ("event", false, true), | ||
DELETE("delete", true, false); | ||
|
||
private final String string; | ||
private final boolean hasIndex; | ||
private final boolean hasDescription; | ||
|
||
CommandType(String string, | ||
boolean hasIndex, | ||
boolean hasDescription) { | ||
this.string = string; | ||
this.hasIndex = hasIndex; | ||
this.hasDescription = hasDescription; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return this.string; | ||
} | ||
} | ||
|
||
private String command; | ||
protected CommandType type; | ||
protected int index; | ||
protected String description; | ||
protected String by; | ||
protected String from; | ||
protected String to; | ||
|
||
public Command(String command) throws VirtueException { | ||
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. having javadoc comments here will help with understanding of the code |
||
this.command = command; | ||
this.type = getCommandType(); | ||
|
||
if (this.type.hasIndex) { | ||
this.index = getIndex(); | ||
} | ||
|
||
if (this.type.hasDescription) { | ||
this.description = getDescription(); | ||
} | ||
|
||
if (this.type == CommandType.DEADLINE) { | ||
this.by = getBy(); | ||
} | ||
|
||
if (this.type == CommandType.EVENT) { | ||
this.from = getFrom(); | ||
this.to = getTo(); | ||
} | ||
} | ||
|
||
// Gets the type of the command, which is its first word. | ||
private CommandType getCommandType() throws UnknownCommandTypeException { | ||
String firstWord = command.split(" ", 2)[0]; | ||
|
||
for (CommandType type : CommandType.values()) { | ||
if (firstWord.equals(type.toString())) { | ||
return type; | ||
} | ||
} | ||
|
||
throw new UnknownCommandTypeException(); | ||
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. using specific exceptions makes error handling more precise and helps with debugging |
||
} | ||
|
||
// Gets the index input by the user for a mark/unmark/delete command. | ||
private int getIndex() throws EmptyIndexException, IndexFormatException { | ||
try { | ||
return Integer.parseInt(command.split(" ", 2)[1]); | ||
} catch (ArrayIndexOutOfBoundsException e) { | ||
throw new EmptyIndexException(type.toString()); | ||
} catch (NumberFormatException e) { | ||
throw new IndexFormatException(type.toString()); | ||
} | ||
} | ||
|
||
// Gets the description for a todo/deadline/event command. | ||
private String getDescription() throws EmptyDescriptionException { | ||
String description; | ||
String firstWordRemoved; | ||
|
||
try { | ||
firstWordRemoved = command.split(" ", 2)[1]; | ||
} catch (ArrayIndexOutOfBoundsException e) { | ||
throw new EmptyDescriptionException(type.toString()); | ||
} | ||
|
||
switch (type) { | ||
case DEADLINE: | ||
description = firstWordRemoved.split("/by", 2)[0]; | ||
break; | ||
case EVENT: | ||
description = firstWordRemoved.split(" /from ", 2)[0]; | ||
break; | ||
default: // case TODO | ||
description = firstWordRemoved; | ||
} | ||
|
||
return description; | ||
} | ||
|
||
// Gets the deadline for a deadline command. | ||
private String getBy() { | ||
String firstWordRemoved = command.split(" ", 2)[1]; | ||
return firstWordRemoved.split(" /by ", 2)[1]; | ||
} | ||
|
||
// Gets the start for a deadline command. | ||
private String getFrom() { | ||
String firstWordRemoved = command.split(" ", 2)[1]; | ||
String fromAndTo = firstWordRemoved.split(" /from ", 2)[1]; | ||
return fromAndTo.split(" /to ", 2)[0]; | ||
} | ||
|
||
// Gets the end for a deadline command. | ||
private String getTo() { | ||
String firstWordRemoved = command.split(" ", 2)[1]; | ||
String fromAndTo = firstWordRemoved.split(" /from ", 2)[1]; | ||
return fromAndTo.split(" /to ", 2)[1]; | ||
} | ||
|
||
public boolean isBye() { | ||
return type == CommandType.BYE; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package virtue; | ||
|
||
public class Deadline extends VirtueTask { | ||
private String by; | ||
|
||
public Deadline(String description, String by) { | ||
super(description); | ||
this.by = by; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "[D]" + super.toString() + " (by: " + this.by + ")"; | ||
} | ||
|
||
@Override | ||
public String fileFormat() { | ||
return "D | " + super.fileFormat() + " | " + by; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package virtue; | ||
|
||
public class EmptyDescriptionException extends VirtueException { | ||
public EmptyDescriptionException(String type) { | ||
super("OOPS!!! The description of a " + type + " cannot be empty."); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package virtue; | ||
|
||
public class EmptyIndexException extends VirtueException{ | ||
public EmptyIndexException(String type) { | ||
super("OOPS!!! The description of a " + type + " command cannot be empty."); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package virtue; | ||
|
||
public class Event extends VirtueTask { | ||
private String from; | ||
private String to; | ||
|
||
public Event(String description, String from, String to) { | ||
super(description); | ||
this.from = from; | ||
this.to = to; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "[E]" + super.toString() + " (from: " + this.from + " to: " + this.to + ")"; | ||
} | ||
|
||
@Override | ||
public String fileFormat() { | ||
return "E | " + super.fileFormat() + " | " + from + " | " + to; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package virtue; | ||
|
||
public class IndexFormatException extends VirtueException { | ||
public IndexFormatException(String type) { | ||
super("The index of a " + type + " command must be an integer."); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package virtue; | ||
|
||
public class Todo extends VirtueTask { | ||
public Todo(String description) { | ||
super(description); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "[T]" + super.toString(); | ||
} | ||
|
||
@Override | ||
public String fileFormat() { | ||
return "T | " + super.fileFormat(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package virtue; | ||
|
||
public class UnknownCommandTypeException extends VirtueException { | ||
public UnknownCommandTypeException() { | ||
super("OOPS!!! I'm sorry, but I don't know what that means :-("); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
package virtue; | ||
|
||
import java.io.IOException; | ||
import java.util.Scanner; | ||
|
||
public class Virtue { | ||
// The scanner the chatbot uses to scan users' inputs. | ||
Scanner sc = new Scanner(System.in); | ||
|
||
// The task list to be used by the chatbot. | ||
VirtueTaskList taskList = new VirtueTaskList(); | ||
|
||
// A horizontal line. | ||
private static final String horizontalLine = "____________________________________________________________"; | ||
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. its very good that you made this final, and abstracted printing with indents and printing horizontal lines, it would have been very difficult to read otherwise |
||
|
||
// Prints with an indention. | ||
protected static void printWithIndent(String str) { | ||
System.out.println(" " + str); | ||
} | ||
|
||
// Prints a horizontal line. | ||
protected static void printHorizontalLine() { | ||
printWithIndent(horizontalLine); | ||
} | ||
|
||
// Greets the user. | ||
private void greet() { | ||
printHorizontalLine(); | ||
printWithIndent("Hello! I'm Virtue \n What can I do for you?"); | ||
printHorizontalLine(); | ||
} | ||
|
||
// Exits with a goodbye message. | ||
private void bye() { | ||
printHorizontalLine(); | ||
printWithIndent("Bye. Hope to see you again soon!"); | ||
printHorizontalLine(); | ||
} | ||
|
||
// Takes inputs from user until bye has been input. | ||
private void takeInputsUntilBye() { | ||
Command currentCommand; | ||
// While user hasn't input bye, add task to task list | ||
while (true) { | ||
// If list is input, print list, else add task to list | ||
try { | ||
String input = sc.nextLine(); | ||
currentCommand = new Command(input); | ||
} catch (VirtueException e) { | ||
printHorizontalLine(); | ||
System.out.println(" " + e.getMessage()); | ||
printHorizontalLine(); | ||
continue; | ||
} | ||
|
||
if (currentCommand.isBye()) { | ||
break; | ||
} else { | ||
try { | ||
taskList.executeCommand(currentCommand); | ||
VirtueFileWriter.writeToFile(taskList); | ||
} catch (IOException e) { | ||
System.out.println("OOPS! An error occurred while taking the inputs: " + e.toString()); | ||
} | ||
} | ||
} | ||
} | ||
|
||
// Runs the chatbot. | ||
private void run() { | ||
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. its really good you abstracted out the functions, and made the run() method concise |
||
taskList = VirtueFileReader.initializeTaskList(); | ||
greet(); | ||
takeInputsUntilBye(); | ||
bye(); | ||
} | ||
|
||
public static void main(String[] args) { | ||
Virtue virtue = new Virtue(); | ||
virtue.run(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package virtue; | ||
|
||
// Exceptions unique to Virtue. | ||
public class VirtueException extends Exception { | ||
public VirtueException(String message) { | ||
super(message); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package virtue; | ||
|
||
import java.io.File; | ||
import java.io.IOException; | ||
import java.util.Scanner; | ||
|
||
public class VirtueFileReader { | ||
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. It would be nice to explain what the file reader does for the application in a comment. Might be more important when in the future we deal with different files with more than one purpose |
||
|
||
public static VirtueTaskList initializeTaskList() { | ||
VirtueTaskList taskList = new VirtueTaskList(); | ||
|
||
File directory = new File("data"); | ||
File file = new File("data/virtue.txt"); | ||
|
||
if (!directory.exists()) { | ||
directory.mkdir(); | ||
} | ||
|
||
if (!file.exists()) { | ||
try { | ||
file.createNewFile(); | ||
} catch (IOException e) { | ||
System.out.println("OOPS! An error occurred while creating the file: " + e.getMessage()); | ||
} | ||
} | ||
|
||
try { | ||
Scanner sc = new Scanner(file); | ||
while (sc.hasNext()) { | ||
taskList.addFromFile(sc.nextLine()); | ||
} | ||
} catch (IOException e) { | ||
System.out.println("OOPS! An error occurred while reading the file: " + e.getMessage()); | ||
} | ||
|
||
return taskList; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package virtue; | ||
|
||
import java.io.FileWriter; | ||
import java.io.IOException; | ||
|
||
public class VirtueFileWriter { | ||
|
||
public static void writeToFile(VirtueTaskList taskList) throws IOException { | ||
FileWriter fileWriter = new FileWriter("data/virtue.txt"); | ||
fileWriter.write(taskList.fileFormat()); | ||
fileWriter.close(); | ||
} | ||
} |
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.
Using an enum to define CommandType was a good idea, since it groups together related constants, and makes the code more readable