-
Notifications
You must be signed in to change notification settings - Fork 267
[Elumalai Oviya Dharshini] iP #275
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?
Changes from 23 commits
d839859
8d48ae0
a71e87b
3f61a7f
177c694
0438b9b
f2f611d
fa10811
21a974e
6fed456
0409484
c642af9
ce8a662
3b49e3e
3660e1d
9946873
5aad65b
769a988
b3aa7d8
924705b
5f5dd50
53505d2
69cbb4b
529f480
b295aff
e36ebcc
ffddffd
6b35610
16ca7b6
5860071
7ae1137
116bf2b
fed8f6a
d40a5c4
9156df9
4a0baa9
bd1716c
66c176c
f2811c7
e2e208b
0060559
13e7025
7798267
22cb406
5a1a342
a67fb2e
7ec9d76
9aabb5f
47ec326
063970e
197ba6b
dc40c8b
61ee763
28108d3
a4d416c
dd686dc
2af586e
6cd5b5f
fc44103
cc59e17
00ea1fb
1c79bf6
8bdaf26
307ce9e
7aae63c
cdf341e
1c9240d
af733da
6048095
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,129 @@ | ||
| package duke; | ||
|
|
||
| import duke.task.Todo; | ||
| import duke.task.Event; | ||
| import duke.task.Deadline; | ||
| import duke.task.TaskList; | ||
|
|
||
| /** | ||
| * The Duke program implements a simple task bot application with CRUD functionality. | ||
| * The program can add three different types of tasks (todo, deadline, event), mark tasks as done, and | ||
| * delete tasks. | ||
| * | ||
| * @author Elumalai Oviya Dharshini | ||
| * @version 0.1 | ||
| */ | ||
| public class Duke { | ||
| private Storage storage; | ||
| private TaskList tasks; | ||
| private final Ui ui; | ||
|
|
||
| /** | ||
| * Constructor for Duke that instantiates UI and storage, and loads Tasks from a file into tasks. | ||
| * If there is an error with loading Tasks from the specified file, it initializes tasks to be an empty | ||
| * TaskList. | ||
| * | ||
| * @param filePath path of the storage file from the current directory | ||
| */ | ||
| public Duke(String filePath) { | ||
| ui = new Ui(); | ||
| try { | ||
| storage = new Storage(filePath); | ||
| tasks = new TaskList(storage.load()); | ||
| } catch (Exception e) { | ||
| ui.showLoadingError(); | ||
| tasks = new TaskList(); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Handles the execution and main logic of the Duke program. | ||
| * It polls for user input continuously, parses user input and displays appropriate messages until user | ||
| * input is "bye", upon which it displays a goodbye message and terminates the program. | ||
| */ | ||
| public void run() { | ||
| ui.showWelcome(); | ||
| boolean isExit = false; | ||
| while (!isExit) { | ||
| try { | ||
| String input = ui.readInput(); | ||
| String command = Parser.parse(input); | ||
|
|
||
| if (command.equals("")) { | ||
| ui.showCommandMessage(command, tasks); | ||
| continue; | ||
| } | ||
| input = Parser.handleInput(input); | ||
|
|
||
| try { | ||
| switch (command) { | ||
| case "list": | ||
| ui.showCommandMessage(command, tasks); | ||
| break; | ||
| case "do": | ||
| int i = Integer.parseInt(input.replaceAll("[^0-9]", "")) - 1; | ||
| tasks.get(i).markComplete(); | ||
| ui.showCommandMessage(command, tasks); | ||
| break; | ||
| case "undo": | ||
| int j = Integer.parseInt(input.replaceAll("[^0-9]", "")) - 1; | ||
| tasks.get(j).markIncomplete(); | ||
| ui.showCommandMessage(command, tasks); | ||
| break; | ||
| case "delete": | ||
| int k = Integer.parseInt(input.replaceAll("[^0-9]", "")) - 1; | ||
| tasks.remove(k); | ||
| ui.showCommandMessage(command, tasks); | ||
| break; | ||
| case "todo": | ||
| Todo t = new Todo(input); | ||
| tasks.add(t); | ||
| ui.showCommandMessage(command, tasks); | ||
| System.out.println(t); | ||
| break; | ||
| case "find": | ||
| ui.showCommandMessage(command, tasks); | ||
| System.out.println(tasks.find(input)); | ||
| break; | ||
| case "deadline": | ||
| String datetime = input.replaceAll(".* by ", ""); | ||
| input = input.replaceAll(" by .*", ""); | ||
| Deadline d = new Deadline(input, datetime); | ||
| tasks.add(d); | ||
| ui.showCommandMessage(command, tasks); | ||
| System.out.println(d); | ||
| break; | ||
| case "event": | ||
| String time = input.replaceAll(".* at ", ""); | ||
| input = input.replaceAll(" at .*", ""); | ||
| Event e = new Event(input, time); | ||
| tasks.add(e); | ||
| ui.showCommandMessage(command, tasks); | ||
| System.out.println(e); | ||
| break; | ||
| } | ||
|
|
||
| if (!command.equals("list") && !command.equals("bye")) { | ||
| storage.save(tasks); | ||
| } | ||
| } catch (Exception e) { | ||
| throw new RuntimeException(e.getMessage()); | ||
| } | ||
|
|
||
| isExit = command.equals("bye"); | ||
| } catch (Exception e) { | ||
| ui.showError(e.getMessage()); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Main method that starts the program by calling a new instance of Duke with a specified file path. | ||
| * | ||
| * @param args command-line arguments | ||
| */ | ||
| public static void main(String[] args) { | ||
| new Duke("../../../data/tasks.txt").run(); | ||
| } | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,111 @@ | ||
| package duke; | ||
|
|
||
| /** | ||
| * Represents a class that validates and interprets user input with a pre-generated list of allowable | ||
| * input formats. | ||
| * Note: Current allowable formats are "list", "bye", "do X", "undo X", "delete X", "todo S", | ||
| * "deadline S by T", "event S at T", "find W", where X is an integer, S is a string descriptor of the task, W | ||
| * is a singular keyword and T is a string descriptor of the date(s) and/or time(s) associated with the task. | ||
| * | ||
| * @author Elumalai Oviya Dharshini | ||
| * @version 0.1 | ||
| */ | ||
| public class Parser { | ||
|
|
||
| /** | ||
| * Extracts the non-command contents of a given input string. | ||
| * Strips the string of leading whitespaces and removes the first word. | ||
| * | ||
| * @return input consisting of the non-command contents of the input string | ||
| */ | ||
| public static String handleInput(String input) { | ||
| input = input.trim(); | ||
| if (input.contains(" ")) { | ||
| input = input.substring(input.indexOf(" ")); | ||
| } | ||
| return input; | ||
| } | ||
|
|
||
| /** | ||
| * Validates format of input and extracts command from the given input, if any. | ||
| * Note: Current allowable formats are "list", "bye", "do X", "undo X", "delete X", "todo S", "find W", | ||
| * "deadline S by T", "event S at T", where X is an integer, S is a string descriptor of the task, W is a | ||
| * singular keyword and T is a string descriptor of the date(s) and/or time(s) associated with the task. | ||
| * | ||
| * @return command from input string if input is of a valid format, "" otherwise | ||
| */ | ||
| public static String parse(String input) { | ||
| input = input.trim(); | ||
| String command = input.replaceAll(" .*", ""); | ||
|
|
||
| input = input.trim(); | ||
| if (input.equals("bye") || input.equals("list")) { | ||
| return command; | ||
| } | ||
|
|
||
| // Handle do, undo, delete | ||
| String firstWord = input.replaceAll(" .*", ""); | ||
| if (firstWord.equals("do") || firstWord.equals("undo") || firstWord.equals("delete")) { | ||
| input = input.replaceAll(".* ", ""); | ||
| if (input.matches("[0-9]+")) { | ||
| return command; | ||
| } | ||
| System.out.println("You need to specify the task you want to "+ firstWord + " by its index :c"); | ||
| return ""; | ||
| } | ||
|
|
||
| // Handle todo | ||
| if (firstWord.equals("todo")) { | ||
| input = input.substring(4).trim(); | ||
| if (input.equals("")) { | ||
| System.out.println("Oops, you need to mention what the task is :c"); | ||
| return ""; | ||
| } | ||
| return command; | ||
| } | ||
|
|
||
| // Handle deadline | ||
| if (firstWord.equals("deadline")) { | ||
| input = input.substring(8).trim(); | ||
| if (!input.contains(" by ")) { | ||
| System.out.println("Oops, you need to format deadline tasks as \"deadline X by Y\" :c"); | ||
| return ""; | ||
| } | ||
| String lastWord = input.substring(input.lastIndexOf(" ") + 1); | ||
| if (lastWord.equals("by")) { | ||
| return ""; | ||
| } | ||
| return command; | ||
| } | ||
|
|
||
| // Handle event | ||
| if (firstWord.equals("event")) { | ||
| input = input.substring(5).trim(); | ||
| if (!input.contains(" at ")) { | ||
| System.out.println("Oops, you need to format event tasks as \"event X at Y\" :c"); | ||
| return ""; | ||
| } | ||
| String lastWord = input.substring(input.lastIndexOf(" ")+1); | ||
| if (lastWord.equals("at")) { | ||
| return ""; | ||
| } | ||
| return command; | ||
| } | ||
|
|
||
| // Handle find | ||
| if (firstWord.equals("find")) { | ||
| input = input.substring(4).trim(); | ||
| if (input.equals("")) { | ||
| System.out.println("Oops, you need to mention what the keyword is :c"); | ||
| return ""; | ||
| } | ||
| if (input.contains(" ")) { | ||
| System.out.println("Oops, you can only search for one keyword at a time :c"); | ||
| return ""; | ||
| } | ||
| return command; | ||
| } | ||
|
|
||
| return ""; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,124 @@ | ||
| package duke; | ||
|
|
||
| import java.io.File; | ||
| import java.io.FileWriter; | ||
| import java.io.IOException; | ||
| import java.util.ArrayList; | ||
| import java.util.Scanner; | ||
|
|
||
| import duke.task.Task; | ||
| import duke.task.Todo; | ||
| import duke.task.Event; | ||
| import duke.task.Deadline; | ||
| import duke.task.TaskList; | ||
|
|
||
| /** | ||
| * Represents a storage space for tasks on hard-drive. | ||
| * It handles the loading of tasks from a file and saving of tasks to the same file. | ||
| * | ||
| * @author Elumalai Oviya Dharshini | ||
| * @version 0.1 | ||
| */ | ||
| public class Storage { | ||
| protected String filePath; | ||
| ArrayList<Task> tasks; | ||
|
|
||
| /** | ||
| * Suppresses any unused warnings from a given boolean result. | ||
| * | ||
| * @param result variable to suppress warnings from | ||
| */ | ||
| //@@author Eric Lange-reused | ||
| //Reused from https://stackoverflow.com/questions/27904329/warning-file-mkdir-is-ignored#answer-54341862 | ||
| // with minor modifications | ||
| @SuppressWarnings("unused") | ||
| private static void IGNORE_RESULT(boolean result) { | ||
|
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 am not sure what does this means, it is not returning anything
Author
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. This utility function is defined for I am not certain if this is the recommended way to handle it so I am leaving it as is for now. |
||
|
|
||
| } | ||
| //@@author | ||
|
|
||
| /** | ||
| * Constructor for Storage that initializes the Storage object with a given file path. | ||
| * It parses input from the specified file and saves the list of Tasks from the specified file, if any. | ||
| * If file does not exist, it creates the file. | ||
| * Note: any missing parent directories in the specified file path are created prior to file creation. | ||
| * | ||
| * @param filePath path of the specified file from the current directory | ||
| * @throws IOException if an exception occurs in the creation/access of the specified file | ||
| * @throws RuntimeException if file at specified path contains data in a non-standard format | ||
| */ | ||
| Storage(String filePath) throws IOException { | ||
| this.filePath = filePath; | ||
| File data = new File(filePath); | ||
| data.getParentFile().mkdirs(); | ||
| IGNORE_RESULT(data.getParentFile().mkdirs()); //make preceding directories, if any are not found | ||
|
|
||
| tasks = new ArrayList<>(); | ||
| if (!data.createNewFile()) { //if file exists | ||
| Scanner fileReader = new Scanner(data); | ||
| while (fileReader.hasNextLine()) { | ||
| String line = fileReader.nextLine(); | ||
| String[] tmp = line.split("\\|"); | ||
| boolean isDone = tmp[1].trim().equals("D"); | ||
|
|
||
| switch (tmp[0].trim()) { | ||
|
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 followed the coding standard for switch case! Great Job! |
||
| case "T": | ||
| Todo t = new Todo(tmp[2].trim()); | ||
| if (isDone) { | ||
| t.markComplete(); | ||
| } | ||
| tasks.add(t); | ||
| break; | ||
| case "D": | ||
| Deadline d = new Deadline(tmp[2].trim(), tmp[3].trim()); | ||
| if (isDone) { | ||
| d.markComplete(); | ||
| } | ||
| tasks.add(d); | ||
| break; | ||
| case "E": | ||
| Event e = new Event(tmp[2].trim(), tmp[3].trim()); | ||
| if (isDone) { | ||
| e.markComplete(); | ||
| } | ||
| tasks.add(e); | ||
| break; | ||
| default: | ||
| throw new RuntimeException("Corrupted data in data file at " + filePath); | ||
| } | ||
| } | ||
| fileReader.close(); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Retrieves and returns Tasks saved from the storage file. | ||
| * | ||
| * @return ArrayList of saved Tasks | ||
| */ | ||
| public ArrayList<Task> load() { | ||
| return tasks; | ||
| } | ||
|
|
||
| /** | ||
| * Updates the list of Tasks saved on hard-drive at filePath by overwriting the existing file at filePath. | ||
| * Note: File creation is to be handled via load() prior this method as this assumes that filePath is | ||
| * valid and that the file exists at filePath. | ||
| * | ||
| * @param tasks TaskList of Tasks to be saved on hard-drive | ||
| * @throws IOException if an exception occurs in the saving of data to the file at filePath | ||
| */ | ||
| public void save(TaskList tasks) throws IOException { | ||
| File data = new File(filePath); | ||
| FileWriter f; | ||
|
|
||
| f = new FileWriter(data, false); | ||
| boolean isFirst = true; | ||
| for (int i = 0; i < tasks.size(); i++) { | ||
| String s = isFirst ? "" : "\n"; | ||
| f.write(s + tasks.get(i).writeToFile()); | ||
|
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 line break after the "." operators would enhance readability? I noticed the same issue in several other places too. |
||
| isFirst = false; | ||
| } | ||
| f.close(); | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.