-
Notifications
You must be signed in to change notification settings - Fork 223
[Sherman Ho] iP #232
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
base: master
Are you sure you want to change the base?
[Sherman Ho] iP #232
Changes from 39 commits
3b19ba1
a75fcee
d518a02
bcd1275
f4d6f0f
179b869
e707812
c7cdb78
a171f30
d8b325f
557f98c
7f652e5
558f9b7
691306e
4856b15
819aea7
dec65f3
945ec43
7fb940a
6db18be
6563d2c
6d3e2d1
eab0390
b985269
100297e
4ea7bf4
2aae990
a66f65a
494dc33
1edba8d
079455b
69d2fb3
52ab2af
893c5e7
cfefbd8
e32afc4
c1cf9f3
eb5747d
5e0abc5
d5405aa
f1e59d5
abb945f
7a7c782
568e901
4f53630
a33d08c
856473f
d269a67
42cc0d0
24aeb95
89afdd5
1e5d21c
003cfda
621e63f
9b30ce7
14bc7ac
e7457a9
10af3b6
bb690a7
5998f67
514a694
725faea
68d8318
e17d7d6
05f73fc
b1bec18
01fffc3
d78dbd7
14f02eb
18cf047
b1c6d6d
076010a
eefd33e
bb44eb1
cc14009
877e896
5790efb
a977e38
57ccda8
e8a0bc6
4e8de88
6f4d8ad
37c31dc
a7d3eb0
732447d
e90e3a8
a0313e1
cf57033
6c11a8e
c0ab2df
6bb1aa1
438d93c
dd21308
e9ae6af
a9ac758
4d4f3b0
1a4f6f5
f472d0d
41f5db3
97dcd14
c4157f2
452b578
7f615c4
003db68
df960cd
0083b41
06eeccc
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 @@ | ||
| * | ||
| */ | ||
| !.gitignore |
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| package duke; | ||
|
|
||
| import duke.command.Command; | ||
| import duke.exception.BadDateArgumentException; | ||
| import duke.exception.EmptyArgumentException; | ||
| import duke.exception.InvalidCommandException; | ||
|
|
||
| import java.io.IOException; | ||
| import java.text.ParseException; | ||
| import java.util.Scanner; | ||
|
|
||
| public class Duke { | ||
| public static void main(String[] args) { | ||
| Ui ui = new Ui(); | ||
| ui.startUpMessage(); | ||
| TaskList store; | ||
| try { | ||
| ui.loadStart(); | ||
| store = Storage.LoadTaskList(); | ||
| ui.loadSuccess(); | ||
| } catch (IOException e) { | ||
| ui.loadFail(); | ||
| return; | ||
| } | ||
| Scanner in = new Scanner(System.in); | ||
| String line; | ||
| do{ | ||
|
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 the bracket and the word 'do' have a spacing between? I noticed this same issue in several other places too. |
||
| ui.prompt(); | ||
| line = in.nextLine(); | ||
| try { | ||
| Command c = Parser.parse(line); | ||
| if (c==null){ //Bye 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. Should there be a spacing between characters in the bracket? |
||
| break; | ||
| } | ||
| String data = store.run(c); | ||
| ui.commandMessage(c,data); | ||
| } catch (ParseException e) { | ||
|
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 like how you catch each exception separately, however the handling done for each of them appears to be the same function? |
||
| ui.handleException(e); | ||
| } catch (InvalidCommandException e){ | ||
| ui.handleException(e); | ||
| } catch(EmptyArgumentException e){ | ||
| ui.handleException(e); | ||
| } catch (BadDateArgumentException e) { | ||
| ui.handleException(e); | ||
| } finally { | ||
| if(store.isEdited()){ | ||
| try { | ||
| Storage.saveTaskList(store); | ||
| store.markSaved(); | ||
| } catch (IOException e) { | ||
| ui.dumpState(store); | ||
| } | ||
| } | ||
| } | ||
| }while(true); | ||
|
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 this while loop could start on a new line? |
||
| ui.goodByeMessage(); | ||
| in.close(); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| 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. Should wildcard imports be used? |
||
| import duke.exception.InvalidCommandException; | ||
|
|
||
| import java.text.ParseException; | ||
| import java.util.Arrays; | ||
| import java.util.List; | ||
|
|
||
| public class Parser { | ||
| public static Command parse(String line) throws ParseException, InvalidCommandException { | ||
| line = line.trim(); | ||
| Command c = null; | ||
| String singleTokens[] = {"bye", "list", "exit", "ls"}; | ||
| String[] tokens = splitTokenIntoTwo(line, " ", singleTokens); | ||
| switch (tokens[0].toLowerCase()) { | ||
| case "exit": | ||
| //Fall-through | ||
| case "bye": | ||
| //Leave as null | ||
| break; | ||
| case "ls": | ||
| //Fall-through | ||
| case "list": | ||
| c = new ListCommand(); | ||
| break; | ||
| case "done": | ||
| c = new DoneCommand(Integer.parseInt(tokens[1])); | ||
| break; | ||
| case "todo": | ||
| c = new AddCommand(new String[]{"T", tokens[1]}); | ||
| break; | ||
| case "deadline": | ||
| tokens = splitTokenIntoTwo(tokens[1], " /by "); | ||
| c = new AddCommand(new String[]{"D", tokens[0], tokens[1]}); | ||
| break; | ||
| case "event": | ||
| tokens = splitTokenIntoTwo(tokens[1], " /at "); | ||
| c = new AddCommand(new String[]{"E", tokens[0], tokens[1]}); | ||
| break; | ||
| case "rm": | ||
| //Fall-through | ||
| case "remove": | ||
| //Fall-through | ||
| case "del": | ||
| //Fall-through | ||
| case "delete": | ||
| c = new DeleteCommand(Integer.parseInt(tokens[1])); | ||
| break; | ||
| default: | ||
| throw new InvalidCommandException(tokens[0]); | ||
| } | ||
| return c; | ||
| } | ||
| private static String[] splitTokenIntoTwo(String parseTarget,String delimiter) throws ParseException { | ||
|
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 a spacing could be used after the comma in "parseTarget, String delimiter"? I noticed similar issues in other arguments separated by commas in round brackets. |
||
| String[] tokens = parseTarget.split(delimiter,2); | ||
| if (tokens.length < 2){ | ||
| throw new ParseException("Expected deliminter '"+ delimiter +"'", tokens[0].length()); | ||
|
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 the +'s be separated by white spaces before an inverted comma? |
||
| } | ||
| return tokens; | ||
| } | ||
|
|
||
| private static String[] splitTokenIntoTwo(String parseTarget,String delimiter, String[] exception) throws ParseException{ | ||
| List<String> exceptionList = Arrays.asList(exception); | ||
|
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 variables that describe a collection values be named in the plural sense? |
||
| String[] tokens = parseTarget.split(delimiter,2); | ||
| if (!exceptionList.contains(tokens[0]) && tokens.length < 2){ | ||
| throw new ParseException("Expected deliminter '"+ delimiter +"'", tokens[0].length()); | ||
| } | ||
| return tokens; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,109 @@ | ||
| package duke; | ||
|
|
||
| import duke.exception.BadDateArgumentException; | ||
| import duke.exception.EmptyArgumentException; | ||
| import duke.task.Deadline; | ||
| import duke.task.Event; | ||
| import duke.task.Task; | ||
| import duke.task.ToDos; | ||
|
|
||
| import java.io.File; | ||
| import java.io.FileWriter; | ||
| import java.io.IOException; | ||
| import java.nio.file.Files; | ||
| import java.nio.file.Paths; | ||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
| import java.util.Scanner; | ||
| import java.util.regex.Matcher; | ||
| import java.util.regex.Pattern; | ||
|
|
||
| public class Storage { | ||
| public static final String FILE_DIR = "data"; | ||
|
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 like how you have followed screaming snake case for constant names 👍 |
||
| public static final String FILE_NAME = "duke.txt"; | ||
| static int badLines = 0;//Last call bad lines | ||
|
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 comments be indented in the same line as its code? |
||
|
|
||
| public static TaskList LoadTaskList() throws IOException { | ||
|
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 function names should follow camelCase? |
||
| badLines = 0; | ||
| List<Task> store = new ArrayList<>(); | ||
| File file = getOrCreateFile(); | ||
| Scanner s = new Scanner(file); | ||
| generateLines: //TODO: Whats the code style for this. | ||
| while(s.hasNextLine()){ | ||
| Task t; | ||
| String line = s.nextLine(); | ||
| String pattern = "([TED]),([01]),(\\d*),(.*)"; | ||
|
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 like how you named the regex String as pattern 👍 |
||
| Pattern r = Pattern.compile(pattern); | ||
| Matcher m = r.matcher(line); | ||
| if(!m.find()){ | ||
| badLines++; | ||
| break; | ||
| } | ||
| String type = m.group(1); | ||
| boolean isDone = m.group(2).equals("1"); | ||
| int taskLength = Integer.parseInt(m.group(3)); | ||
| String task = m.group(4).substring(0,taskLength); | ||
| String leftover = m.group(4).substring(taskLength); | ||
| try { | ||
| if (type.equals("E") || type.equals("D") ) { | ||
| line = leftover.substring(1); | ||
| pattern = "(\\d*),(.*)"; | ||
| r = Pattern.compile(pattern); | ||
| m = r.matcher(line); | ||
| if (!m.find()) { | ||
| badLines++; | ||
| break; | ||
| } | ||
| int timeLength = Integer.parseInt(m.group(1)); | ||
| String timeData = m.group(2).substring(0, timeLength); | ||
|
|
||
| switch (type) { | ||
| case "E": | ||
| t = new Event(task, timeData); | ||
| break; | ||
| case "D": | ||
| t = new Deadline(task, timeData); | ||
| break; | ||
| default: | ||
| badLines++; | ||
| break generateLines; | ||
| } | ||
| } else { | ||
| t = new ToDos(task); | ||
| } | ||
| }catch(EmptyArgumentException e){ | ||
| badLines++; | ||
| break; | ||
| }catch(BadDateArgumentException e){ | ||
| badLines++; | ||
| break; | ||
| } | ||
| if (isDone){ | ||
| t.setDone(); | ||
| } | ||
| store.add(t); | ||
| } | ||
| s.close(); | ||
| return new TaskList(store); | ||
| } | ||
|
|
||
| public static void saveTaskList(TaskList data) throws IOException { | ||
| List<Task> store = data.getRawData(); | ||
| StringBuilder saveText = new StringBuilder(); | ||
| for (Task t: store){ | ||
|
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 include some whitespaces in the for statement? |
||
| saveText.append(t.toFileString()); | ||
| saveText.append('\n'); | ||
| } | ||
| File f = getOrCreateFile(); | ||
| FileWriter writer = new FileWriter(f); | ||
| writer.write(saveText.toString()); | ||
| writer.close(); | ||
| } | ||
|
|
||
| private static File getOrCreateFile() throws IOException { | ||
| Files.createDirectories(Paths.get(FILE_DIR)); | ||
| File file = new File(FILE_DIR, FILE_NAME); // create a File for the given file path | ||
| file.createNewFile(); | ||
| return file; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,108 @@ | ||
| package duke; | ||
|
|
||
| import duke.command.Command; | ||
| import duke.exception.BadDateArgumentException; | ||
| import duke.exception.EmptyArgumentException; | ||
| import duke.task.Deadline; | ||
| import duke.task.Event; | ||
| import duke.task.Task; | ||
| import duke.task.ToDos; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| public class TaskList { | ||
| public enum Action{ | ||
| ADD, | ||
| LIST, | ||
| DONE, | ||
| DELETE, | ||
| } | ||
| private boolean edited = false; | ||
| private List<Task> store; | ||
| public TaskList(List<Task> store) { | ||
| this.store = store; | ||
| } | ||
|
|
||
| public List<Task> getRawData(){ | ||
| return this.store; | ||
| } | ||
|
|
||
| public String run(Command c) throws EmptyArgumentException, BadDateArgumentException { | ||
| String[] args = c.run(); | ||
| String results; | ||
|
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 a more suitable variable name could be used here? Perhaps singular instead of plural? |
||
| switch(c.getType()){ | ||
| case ADD: | ||
| results = addTask(args); | ||
| edited = true; | ||
| break; | ||
| case DONE: | ||
| results = setDone(Integer.parseInt(args[0])); | ||
| edited = true; | ||
| break; | ||
| case DELETE: | ||
| results = delete(Integer.parseInt(args[0])); | ||
| edited = true; | ||
| break; | ||
| case LIST: | ||
| results = getList(); | ||
| break; | ||
| default: | ||
| results = ""; | ||
| break; | ||
| } | ||
| return results; | ||
| } | ||
| public void markSaved(){ | ||
| edited = false; | ||
| } | ||
| public boolean isEdited(){ | ||
| return this.edited; | ||
| } | ||
| private String addTask(String[] tokens) throws EmptyArgumentException, BadDateArgumentException { | ||
| Task t; | ||
| switch(tokens[0]){ | ||
| case "D": | ||
| t = new Deadline(tokens[1], tokens[2]); | ||
| break; | ||
| case "E": | ||
| t = new Event(tokens[1], tokens[2]); | ||
| break; | ||
| case "T": | ||
| //Fall through | ||
| default: //More fault tolerant | ||
| t = new ToDos(tokens[1]); | ||
| break; | ||
| } | ||
| store.add(t); | ||
| return formatOrderedPrint(-1); | ||
| } | ||
| private String setDone(int doneIndex){ | ||
| Task t = store.get(doneIndex); | ||
| t.setDone(); | ||
| return formatOrderedPrint(doneIndex); | ||
| } | ||
| private String delete(int deleteIndex){ | ||
|
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 there be newlines separating these methods for better readability? |
||
| String returnValue = formatOrderedPrint(deleteIndex); | ||
| store.remove(deleteIndex); | ||
| return returnValue; | ||
| } | ||
| public String getList(){ | ||
| StringBuilder builder = new StringBuilder(); | ||
| for (int i = 0 ; i < store.size(); i++) { | ||
| builder.append(formatOrderedPrint(i)); | ||
| builder.append('\n'); | ||
| } | ||
| return builder.toString(); | ||
| } | ||
|
|
||
| private String formatOrderedPrint(int i){ | ||
| final int size = store.size(); | ||
| while (i < 0){ | ||
| i += size; | ||
| } | ||
| while (i >= size){ | ||
| i -= size; | ||
| } | ||
| return "Entry " + (i+1) + "|" + store.get(i).toString(); | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.
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.
Perhaps use a more intuitive variable name here such as taskList?