-
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
[Wang Guanlin] iP #468
base: master
Are you sure you want to change the base?
[Wang Guanlin] iP #468
Changes from 51 commits
d839859
ab74434
c8163cf
7f6a9e4
073b8bc
94a2613
29a7b43
86734d8
0704af3
840767d
bdeaad4
a792272
1327162
541a1dd
c48c98d
57a57d3
5b64f0e
213d350
ff40331
23a7854
20904d1
abba5bc
582d814
0e724a6
f854a11
153032a
287a6b4
a008ab8
f2e7526
1a95507
51f6c23
685755b
8688ae6
b12e45e
845d1b1
6da91b1
54b588f
d0a5a2e
bfb6cad
609beb1
ee37691
281a595
9e9109a
7d0c2ff
6415efd
1195f8d
9a5e6fc
c276a32
5524ba8
c72dbd8
13d56db
596cb63
d6af729
e054745
0c633a2
613f9ce
60e607a
379ba30
1ac4e8f
40f61c6
04bbebc
53dafd7
8daf0b5
f83d529
9c7e428
b5c3742
9821713
3638fd6
6af29d8
a70840f
c8a852a
1e509d0
bf8166f
0a6303e
1d7cac7
b067a25
5721b1c
e083605
75661c5
7f59eb6
49dca7b
e010b92
5430e9f
86a2f73
4a7a59b
cdb67d8
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 |
---|---|---|
|
@@ -15,3 +15,4 @@ bin/ | |
|
||
/text-ui-test/ACTUAL.txt | ||
text-ui-test/EXPECTED-UNIX.TXT | ||
*.class |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
1.[T][ ] 1 | ||
2.[E][ ] 2 (at: 2022 02 02) | ||
3.[D][ ] 3 (by: 2021 10 10) |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
Manifest-Version: 1.0 | ||
Main-Class: cs2103.duke.Duke | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package cs2103.duke; | ||
|
||
import java.time.LocalDate; | ||
import java.time.format.DateTimeFormatter; | ||
|
||
/** | ||
* This class encapsulates a Deadline Task object, which inherits from the Task class. | ||
*/ | ||
public class Deadline extends Task { | ||
protected int index; | ||
protected String by; | ||
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. Likewise for the variable "by", can change the name to be more specific. |
||
protected LocalDate date; | ||
|
||
public Deadline(int index, String description, String by) { | ||
super(index, description); | ||
this.index = index; | ||
this.by = by; | ||
this.date = LocalDate.parse(by); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "[D]" + super.toString() + " (by: " + date.format(DateTimeFormatter.ofPattern("yyyy MM dd")) + ")"; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
package cs2103.duke; | ||
|
||
import java.util.Scanner; | ||
import java.io.IOException; | ||
|
||
/** | ||
* This class encapsulates a Duke chat-bot. | ||
*/ | ||
public class Duke { | ||
private final String dukeFilePath; | ||
private final Storage storage; | ||
private TaskList tasks; | ||
private Ui ui; | ||
|
||
public Duke(String dukeFilePath) { | ||
this.dukeFilePath = dukeFilePath; | ||
storage = new Storage(dukeFilePath); | ||
try { | ||
tasks = new TaskList(storage.load()); | ||
} catch (DukeException | IOException e) { | ||
System.out.println(ui.showLoadingError()); | ||
tasks = new TaskList(); | ||
} | ||
ui = new Ui(tasks); | ||
} | ||
|
||
public void run() { | ||
System.out.println(ui.showWelcome()); | ||
boolean canExit = false; | ||
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. Awesome! Good use of descriptive name for boolean variables! |
||
// Scanner to read user inputs | ||
Scanner scanner = new Scanner(System.in); | ||
|
||
while (!canExit) { | ||
String userInput = scanner.next(); | ||
try { | ||
if (userInput.equals("bye")) { // user inputs "bye", set canExit to true and Exit | ||
canExit = true; | ||
// store task list | ||
String temp = tasks.listBeautify(); | ||
storage.overwriteFile(dukeFilePath, temp); | ||
System.out.println(ui.showGoodbye()); | ||
} else { // check first input | ||
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. Shouldn't comments be on separate lines as code? |
||
System.out.println(ui.handleInput(scanner, userInput, tasks)); | ||
} | ||
} catch (DukeException | IOException e) { | ||
e.printStackTrace(); // print stack trace for e | ||
} | ||
} | ||
} | ||
|
||
public static void main(String[] args) throws IOException { | ||
String dukeFilePath = "./data/duke.txt"; | ||
Storage s = new Storage(dukeFilePath); | ||
s.initialize(); | ||
new Duke(dukeFilePath).run(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package cs2103.duke; | ||
|
||
/** | ||
* This class encapsulates the exception thrown when the user enters an erroneous input. | ||
*/ | ||
public class DukeException extends Exception { | ||
private static String msg; | ||
|
||
public DukeException(String errorMessage) { | ||
super(errorMessage); | ||
msg = errorMessage; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return ("Oh No! I do not understand your input due to the following problem:\n" + msg); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
package cs2103.duke; | ||
|
||
import java.io.File; | ||
import java.io.IOException; | ||
import java.util.ArrayList; | ||
import java.util.Scanner; | ||
|
||
/** | ||
* This class encapsulates the parsing of duke.txt to convert the contents of the file | ||
* into an ArrayList. | ||
*/ | ||
public class DukeParser { | ||
private String filePath; | ||
|
||
public DukeParser(String dukeFilePath) { | ||
this.filePath = dukeFilePath; | ||
} | ||
|
||
/** | ||
* This method copies the contents of the file from filePath and | ||
* converts them into Task objects into the taskArrayList with the | ||
* help of the parse() method. | ||
* | ||
* @return TaskArrayList the ArrayList to copy the information to. | ||
* @throws IOException If filePath does not exist. | ||
*/ | ||
public ArrayList<Task> copyFileContents() throws IOException { | ||
File f = new File(this.filePath); // create a File for the given file path | ||
Scanner s = new Scanner(f); // create a Scanner using the File as the source | ||
StringBuilder targetBuilder = new StringBuilder(); | ||
while (s.hasNext()) { | ||
targetBuilder.append(s.nextLine()).append("\n"); | ||
} | ||
|
||
return parse(targetBuilder.toString()); | ||
} | ||
|
||
/** | ||
* This method parses the string copied from duke.txt and converts them into task objects | ||
* into the taskArrayList. | ||
* | ||
* @param toParse The string to parse. | ||
* @return A taskArrayList made up of tasks. | ||
*/ | ||
public static ArrayList<Task> parse(String toParse) { | ||
ArrayList<Task> result = new ArrayList<>(); | ||
Scanner ps = new Scanner(toParse); // passes whole file into the scanner | ||
// [[T][ ] 1, [E][ ] 2 (at: 2), [D][ ] 3 (by: 3)] | ||
while (ps.hasNextLine()) { | ||
String nLine = ps.nextLine(); // parse one line at a time | ||
int ref = 3; // reference point | ||
char taskType = nLine.charAt(ref); | ||
boolean isDone = nLine.charAt(ref + 3) == 'X'; | ||
int strLength = nLine.length(); | ||
switch (taskType) { | ||
case 'T': | ||
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. Shouldn't case body contain less code? Maybe can try to put the code here into a function then call the function. |
||
String todoName = nLine.substring(ref + 5, strLength); | ||
Task newestTodo = new ToDo(result.size(), todoName); | ||
if (isDone) { | ||
newestTodo.markAsDone(); | ||
} | ||
result.add(newestTodo); | ||
break; | ||
case 'D': | ||
String deadlineInfo = nLine.substring(ref + 5, strLength); | ||
String[] arrD = deadlineInfo.split("\\(by: ", 2); | ||
String deadlineName = arrD[0]; | ||
String deadlineReminder = arrD[1].substring(0, arrD[1].length() - 1); | ||
deadlineReminder = parseDate(deadlineReminder); | ||
Task newestDeadline = new Deadline(result.size(), deadlineName, deadlineReminder); | ||
result.add(newestDeadline); | ||
if (isDone) { | ||
newestDeadline.markAsDone(); | ||
} | ||
break; | ||
case 'E': | ||
String eventInfo = nLine.substring(ref + 5, strLength); | ||
String[] arrE = eventInfo.split("\\(at: ", 2); | ||
String eventName = arrE[0]; | ||
String eventReminder = arrE[1].substring(0, arrE[1].length() - 1); | ||
eventReminder = parseDate(eventReminder); | ||
Task newestEvent = new Event(result.size(), eventName, eventReminder); | ||
result.add(newestEvent); | ||
if (isDone) { | ||
newestEvent.markAsDone(); | ||
} | ||
break; | ||
default: | ||
System.out.println("Unknown input"); | ||
break; | ||
} | ||
} | ||
return result; | ||
} | ||
|
||
/** | ||
* Parses input string in the format "yyyy MM dd" and returns it in the format | ||
* "YYYY-MM-DD". | ||
* | ||
* @param input String in format "MMM d yyyy". | ||
* @return String in format "YYYY-MM-DD". | ||
*/ | ||
public static String parseDate(String input) { | ||
String year = input.substring(0, 4); | ||
String month = input.substring(5, 7); | ||
String day = input.substring(8, 10); | ||
|
||
return year + "-" + month + "-" + day; | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package cs2103.duke; | ||
|
||
import java.time.LocalDate; | ||
import java.time.format.DateTimeFormatter; | ||
|
||
/** | ||
* This class encapsulates an Event Task object, which inherits from the Task class. | ||
*/ | ||
public class Event extends Task { | ||
protected int index; | ||
protected String at; | ||
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 you could consider using a more descriptive variable name in place of |
||
protected LocalDate date; | ||
|
||
public Event(int index, String description, String at) { | ||
super(index, description); | ||
this.index = index; | ||
this.at = at; | ||
this.date = LocalDate.parse(at); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "[E]" + super.toString() + " (at: " + date.format(DateTimeFormatter.ofPattern("yyyy MM dd")) + ")"; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package cs2103.duke; | ||
|
||
import java.io.File; | ||
import java.io.FileWriter; | ||
import java.io.IOException; | ||
import java.util.ArrayList; | ||
|
||
/** | ||
* This class encapsulates a Storage object which saves the tasks that have been added by the user, it also | ||
* performs the initialization for the duke.txt and its parent folder, if they are not already present. | ||
*/ | ||
public class Storage { | ||
private static ArrayList<Task> taskArrayList = new ArrayList<>(); | ||
private final String filePath; | ||
|
||
public Storage(String dukeFilePath) { | ||
this.filePath = dukeFilePath; | ||
} | ||
|
||
/** | ||
* Checks the dukeFilePath for the existence of duke.txt, if the file or the folder containing it | ||
* does not exist, create them. | ||
* | ||
* @throws IOException If an invalid input is detected. | ||
*/ | ||
public void initialize() throws IOException { | ||
String dukeFileDirectoryPath = "./data"; | ||
String dukeFilePath = "./data/duke.txt"; | ||
File dukeFileDirectory = new File(dukeFileDirectoryPath); | ||
File dukeFile = new File(dukeFilePath); | ||
// creates directory if it does not exist | ||
if (dukeFileDirectory.mkdir()) { | ||
// dukeFile.mkdir(); | ||
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. Maybe this comment could be considered as redundant? The code line above it might be self-explanatory enough. |
||
System.out.println("folder: 'data/' has been created"); | ||
} | ||
// creates file if it does not exist | ||
if (dukeFile.createNewFile()) { | ||
// dukeFile.createNewFile(); | ||
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. Maybe this comment could be considered as redundant? The code line above it might be self-explanatory enough. |
||
System.out.println("'duke.txt' has been created in the 'data/' folder "); | ||
} | ||
} | ||
|
||
/** | ||
* Loads the data stored in duke.txt into a taskArrayList. | ||
* | ||
* @return The taskArrayList representation of the data stored in duke.txt, if any. | ||
* @throws IOException If an invalid input is detected. | ||
*/ | ||
public ArrayList<Task> load() throws IOException { | ||
// initialize | ||
initialize(); | ||
// load the data from the hard disk for dukeFile | ||
DukeParser p = new DukeParser(filePath); | ||
return p.copyFileContents(); | ||
} | ||
|
||
/** | ||
* This method overwrites the file. | ||
* | ||
* @param filePath The path to the file to append to. | ||
* @param textToAppend The text to append. | ||
* @throws IOException If filePath does not exist. | ||
*/ | ||
|
||
public void overwriteFile(String filePath, String textToAppend) throws IOException { | ||
FileWriter fw = new FileWriter(filePath, false); // create a FileWriter in append mode | ||
fw.write(textToAppend); | ||
fw.close(); | ||
} | ||
|
||
/** | ||
* This method appends to the file instead of overwrites. | ||
* | ||
* @param filePath The path to the file to append to. | ||
* @param textToAppend The text to append. | ||
* @throws IOException If filePath does not exist. | ||
*/ | ||
|
||
public void appendToFile(String filePath, String textToAppend) throws IOException { | ||
FileWriter fw = new FileWriter(filePath, true); // create a FileWriter in append mode | ||
fw.write(textToAppend); | ||
fw.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.
I think it is better to use less general names and more specific names for better understanding by other readers.
For example, you can change the name here to indicate the context of the index.