diff --git a/.gitignore b/.gitignore index 5e59b862ba4..69edc14044e 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,5 @@ src/test/data/sandbox/ # MacOS custom attributes files created by Finder .DS_Store +*.iml +bin/ diff --git a/README.adoc b/README.adoc index e36efe534bb..f065a70ba05 100644 --- a/README.adoc +++ b/README.adoc @@ -1,11 +1,10 @@ -= Address Book (Level 3) += NusProductivity ifdef::env-github,env-browser[:relfileprefix: docs/] -https://travis-ci.org/se-edu/addressbook-level3[image:https://travis-ci.org/se-edu/addressbook-level3.svg?branch=master[Build Status]] -https://ci.appveyor.com/project/damithc/addressbook-level3[image:https://ci.appveyor.com/api/projects/status/3boko2x2vr5cc3w2?svg=true[Build status]] -https://coveralls.io/github/se-edu/addressbook-level3?branch=master[image:https://coveralls.io/repos/github/se-edu/addressbook-level3/badge.svg?branch=master[Coverage Status]] -https://www.codacy.com/app/damith/addressbook-level3?utm_source=github.com&utm_medium=referral&utm_content=se-edu/addressbook-level3&utm_campaign=Badge_Grade[image:https://api.codacy.com/project/badge/Grade/fc0b7775cf7f4fdeaf08776f3d8e364a[Codacy Badge]] - +https://travis-ci.org/AY1920S2-CS2103T-W16-4/main/[image:https://travis-ci.org/AY1920S2-CS2103T-W16-4/main.svg?branch=master[Build Status]] +https://ci.appveyor.com/project/zhouxinwei97/main-6u9g9/branch/master[image:https://ci.appveyor.com/api/projects/status/i7it4o886kq4u688/branch/master?svg=true[Build status] +] +https://coveralls.io/github/AY1920S2-CS2103T-W16-4/main?branch=master[image:https://coveralls.io/repos/github/AY1920S2-CS2103T-W16-4/main/badge.svg?branch=master[Coverage Status]] ifdef::env-github[] image::docs/images/Ui.png[width="600"] @@ -16,14 +15,12 @@ image::images/Ui.png[width="600"] endif::[] * This is a desktop Address Book application. It has a GUI but most of the user interactions happen using a CLI (Command Line Interface). -* It is a Java sample application intended for students learning Software Engineering while using Java as the main programming language. -* It is *written in OOP fashion*. It provides a *reasonably well-written* code example that is *significantly bigger* (around 6 KLoC)than what students usually write in beginner-level SE modules. +* This app is intended for NUS students to organise and plan for school related stuff, such as module and module deadlines. == Site Map * <> * <> -* <> * <> * <> @@ -32,5 +29,6 @@ endif::[] * Some parts of this sample application were inspired by the excellent http://code.makery.ch/library/javafx-8-tutorial/[Java FX tutorial] by _Marco Jakob_. * Libraries used: https://openjfx.io/[JavaFX], https://github.com/FasterXML/jackson[Jackson], https://github.com/junit-team/junit5[JUnit5] +* Code modified from AddressBook-Level3 project created by SE-EDU initiative at https://se-education.org == Licence : link:LICENSE[MIT] diff --git a/build.gradle b/build.gradle index 93029ef8262..e83ec473dea 100644 --- a/build.gradle +++ b/build.gradle @@ -133,7 +133,7 @@ asciidoctor { idprefix: '', // for compatibility with GitHub preview idseparator: '-', 'site-root': "${sourceDir}", // must be the same as sourceDir, do not modify - 'site-name': 'AddressBook-Level3', + 'site-name': 'NUSProductivity', 'site-githuburl': 'https://github.com/se-edu/addressbook-level3', 'site-seedu': true, // delete this line if your project is not a fork (not a SE-EDU project) ] diff --git a/docs/AboutUs.adoc b/docs/AboutUs.adoc index 458e6134f45..e657af4fce9 100644 --- a/docs/AboutUs.adoc +++ b/docs/AboutUs.adoc @@ -4,53 +4,49 @@ :imagesDir: images :stylesDir: stylesheets -AddressBook - Level 3 was developed by the https://se-edu.github.io/docs/Team.html[se-edu] team. + -_{The dummy content given below serves as a placeholder to be used by future forks of the project.}_ + -{empty} + +NusProductivity - developed by team W-16-4 + We are a team based in the http://www.comp.nus.edu.sg[School of Computing, National University of Singapore]. == Project Team -=== John Doe -image::damithc.jpg[width="150", align="left"] -{empty}[http://www.comp.nus.edu.sg/~damithch[homepage]] [https://github.com/damithc[github]] [<>] +=== Zhou Xinwei +image::zhouxinwei97.png[width="150", align="left"] +{empty} [https://github.com/zhouxinwei97[github]] [<>] -Role: Project Advisor +Role: Team lead + +Responsibilities: Integration, features development and UI ''' -=== John Roe -image::lejolly.jpg[width="150", align="left"] -{empty}[http://github.com/lejolly[github]] [<>] +=== Ng Xuan Xin +image::xuanxinng.png[width="150", align="left"] +{empty}[http://github.com/xuanxinng[github]] [https://github.com/AY1920S2-CS2103T-W16-4/main/blob/master/docs/team/NgXuanXin.adoc[portfolio]] -Role: Team Lead + -Responsibilities: UI +Role: Documentation, Developer ''' -=== Johnny Doe -image::yijinl.jpg[width="150", align="left"] -{empty}[http://github.com/yijinl[github]] [<>] +=== Max Pang +image::mpang45456.png[width="150", align="left"] +{empty}[http://github.com/mpang45456[github]] [<>] -Role: Developer + -Responsibilities: Data +Role: # To be updated ''' -=== Johnny Roe -image::m133225.jpg[width="150", align="left"] -{empty}[http://github.com/m133225[github]] [<>] +=== Kang Wangkai +image::kangwkk.png[width="150", align="left"] +{empty}[http://github.com/kangwkk[github]] [<>] -Role: Developer + -Responsibilities: Dev Ops + Threading +Role: Testing, Documentation and implementation. ''' -=== Benson Meier -image::yl_coder.jpg[width="150", align="left"] -{empty}[http://github.com/yl-coder[github]] [<>] +=== Chen Jiangwei +image::watsheldon.png[width="150", align="left"] +{empty}[http://github.com/watsheldon[github]] [<>] -Role: Developer + -Responsibilities: UI +Role: # To be updated ''' diff --git a/docs/ContactUs.adoc b/docs/ContactUs.adoc index 81be279ef6d..a76bb32233d 100644 --- a/docs/ContactUs.adoc +++ b/docs/ContactUs.adoc @@ -2,6 +2,6 @@ :site-section: ContactUs :stylesDir: stylesheets -* *Bug reports, Suggestions* : Post in our https://github.com/se-edu/addressbook-level3/issues[issue tracker] if you noticed bugs or have suggestions on how to improve. +* *Bug reports, Suggestions* : Post in our https://github.com/AY1920S2-CS2103T-W16-4/main/issues[issue tracker] if you noticed bugs or have suggestions on how to improve. * *Contributing* : We welcome pull requests. Follow the process described https://github.com/oss-generic/process[here] -* *Email us* : You can also reach us at `damith [at] comp.nus.edu.sg` +* *Email us* : You can also reach us at `zhou.xinwei [at] u.nus.edu` diff --git a/docs/DevOps.adoc b/docs/DevOps.adoc index 2aa5a6bc0c1..34b295d1548 100644 --- a/docs/DevOps.adoc +++ b/docs/DevOps.adoc @@ -1,4 +1,4 @@ -= AddressBook Level 3 - Dev Ops += NUSProductivity - Dev Ops :site-section: DeveloperGuide :toc: :toc-title: diff --git a/docs/DeveloperGuide.adoc b/docs/DeveloperGuide.adoc index 3d65905a853..00fa10bba5c 100644 --- a/docs/DeveloperGuide.adoc +++ b/docs/DeveloperGuide.adoc @@ -1,4 +1,4 @@ -= AddressBook Level 3 - Developer Guide += NUSProductivity - Developer Guide :site-section: DeveloperGuide :toc: :toc-title: @@ -12,9 +12,9 @@ ifdef::env-github[] :note-caption: :information_source: :warning-caption: :warning: endif::[] -:repoURL: https://github.com/se-edu/addressbook-level3/tree/master +:repoURL: https://github.com/AY1920S2-CS2103T-W16-4/main -By: `Team SE-EDU`      Since: `Jun 2016`      Licence: `MIT` +By: `CS2103T-W16-4` Since: `Feb 2020` Licence: `MIT` == Setting up @@ -59,27 +59,31 @@ Each of the four components For example, the `Logic` component (see the class diagram given below) defines it's API in the `Logic.java` interface and exposes its functionality using the `LogicManager.java` class. .Class Diagram of the Logic Component -image::LogicClassDiagram.png[] +image::LogicClassDiagram.png[width="790"] [discrete] ==== How the architecture components interact with each other -The _Sequence Diagram_ below shows how the components interact with each other for the scenario where the user issues the command `delete 1`. +The _Sequence Diagram_ below shows how the components interact with each other for the scenario where the user issues the command `moduleAdd m/CS2103T`. -.Component interactions for `delete 1` command -image::ArchitectureSequenceDiagram.png[] +// tag::UIDiagram[] +.Component interactions for `moduleAdd m/CS2103T` command +image::ArchitectureSequenceDiagram.png[width="790"] The sections below give more details of each component. [[Design-Ui]] === UI component + .Structure of the UI Component -image::UiClassDiagram.png[] +image::UiClassDiagram.png[width="790"] +// end::UIDiagram[] + *API* : link:{repoURL}/src/main/java/seedu/address/ui/Ui.java[`Ui.java`] -The UI consists of a `MainWindow` that is made up of parts e.g.`CommandBox`, `ResultDisplay`, `PersonListPanel`, `StatusBarFooter` etc. All these, including the `MainWindow`, inherit from the abstract `UiPart` class. +The UI consists of a `MainWindow` that is made up of parts e.g.`CommandBox`, `ResultDisplay`, `CalendarListPanel`, `StatusBarFooter` etc. All these, including the `MainWindow`, inherit from the abstract `UiPart` class. The `UI` component uses JavaFx UI framework. The layout of these UI parts are defined in matching `.fxml` files that are in the `src/main/resources/view` folder. For example, the layout of the link:{repoURL}/src/main/java/seedu/address/ui/MainWindow.java[`MainWindow`] is specified in link:{repoURL}/src/main/resources/view/MainWindow.fxml[`MainWindow.fxml`] @@ -93,7 +97,7 @@ The `UI` component, [[fig-LogicClassDiagram]] .Structure of the Logic Component -image::LogicClassDiagram.png[] +image::LogicClassDiagram.png[width="790"] *API* : link:{repoURL}/src/main/java/seedu/address/logic/Logic.java[`Logic.java`] @@ -107,15 +111,15 @@ link:{repoURL}/src/main/java/seedu/address/logic/Logic.java[`Logic.java`] Given below is the Sequence Diagram for interactions within the `Logic` component for the `execute("delete 1")` API call. .Interactions Inside the Logic Component for the `delete 1` Command -image::DeleteSequenceDiagram.png[] +image::DeleteSequenceDiagram.png[width="790"] NOTE: The lifeline for `DeleteCommandParser` should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram. [[Design-Model]] === Model component -.Structure of the Model Component -image::ModelClassDiagram.png[] +.Part of the Model Component +image::ModelClassDiagram.png[width="790"] *API* : link:{repoURL}/src/main/java/seedu/address/model/Model.java[`Model.java`] @@ -135,7 +139,7 @@ image:BetterModelClassDiagram.png[] === Storage component .Structure of the Storage Component -image::StorageClassDiagram.png[] +image::StorageClassDiagram.png[width="790"] *API* : link:{repoURL}/src/main/java/seedu/address/storage/Storage.java[`Storage.java`] @@ -153,94 +157,344 @@ Classes used by multiple components are in the `seedu.addressbook.commons` packa This section describes some noteworthy details on how certain features are implemented. -// tag::undoredo[] -=== [Proposed] Undo/Redo feature -==== Proposed Implementation +=== Module Search + +image::SearchCommandUMLDiagram.png[width="790"] -The undo/redo mechanism is facilitated by `VersionedAddressBook`. -It extends `AddressBook` with an undo/redo history, stored internally as an `addressBookStateList` and `currentStatePointer`. -Additionally, it implements the following operations: +*API* : +link:{repoURL}/src/main/java/seedu/address/searcher/Search.java[`Search.java`] + +Module Search function returns `module` object that contains useful information for each module for the rest of the application to use. +The function first checks if the information is available in local cache, and if it isnt, pulls it from NUSmods API. +The JSON object pulled from the web is then parsed into a `module` object. +This implementation means that a local cache of the added modules will be available even if the user is offline. -* `VersionedAddressBook#commit()` -- Saves the current address book state in its history. -* `VersionedAddressBook#undo()` -- Restores the previous address book state from its history. -* `VersionedAddressBook#redo()` -- Restores a previously undone address book state from its history. -These operations are exposed in the `Model` interface as `Model#commitAddressBook()`, `Model#undoAddressBook()` and `Model#redoAddressBook()` respectively. +// tag::ModuleBook[] +=== Profile (Module Book) feature (Wangkai) -Given below is an example usage scenario and how the undo/redo mechanism behaves at each step. +This profile feature allows users to manage the modules they have taken before or is taking now in NUS. +In details, users are able to store their module taken into the program with the grades for each module stated if applicable and +can also store tasks which are related to each module. -Step 1. The user launches the application for the first time. The `VersionedAddressBook` will be initialized with the initial address book state, and the `currentStatePointer` pointing to that single address book state. +==== Implementation +- This feature is implemented using a panel on the main screen of profile tab with a list of modules that is updated with every command that +may affect module list (such as add, delete or grade). -image::UndoRedoState0.png[] +- The module book (profile) currently supports following features. -Step 2. The user executes `delete 5` command to delete the 5th person in the address book. The `delete` command calls `Model#commitAddressBook()`, causing the modified state of the address book after the `delete 5` command executes to be saved in the `addressBookStateList`, and the `currentStatePointer` is shifted to the newly inserted address book state. +. Adds in or deletes modules and display the list of modules in profile tab. +. Updates user's grades for each module and get CAP calculated immediately. +. Manage the tasks related to each module (module tasks) through CLI. +. Any modification to module tasks will be updated in the Calendar tab and also show messages on the result display panel. -image::UndoRedoState1.png[] +.Class diagram of structure and relations of NusModule, ModuleBook and relevant classes. +image::NusModuleClassDiagram.png[width="790"] -Step 3. The user executes `add n/David ...` to add a new person. The `add` command also calls `Model#commitAddressBook()`, causing another modified address book state to be saved into the `addressBookStateList`. +- As shown in the class diagram above, modules are created by a class called `NusModule`. Every instance of `NusModule` contains a `ModuleCode` object, a +`Grade` object (optional) and a list of `ModuleTask` objects. -image::UndoRedoState2.png[] +- `Grade` and `Priority` are enumerations. `Grade` contains all possible grades student can get in NUS. Every `ModuleTask` instance has a `Priority` attribute which indicates how important it is. [NOTE] -If a command fails its execution, it will not call `Model#commitAddressBook()`, so the address book state will not be saved into the `addressBookStateList`. +The module book only accept modules that are provided in NUS and will check the module code the user want to add is valid or not by using the search feature mentioned above. -Step 4. The user now decides that adding the person was a mistake, and decides to undo that action by executing the `undo` command. The `undo` command will call `Model#undoAddressBook()`, which will shift the `currentStatePointer` once to the left, pointing it to the previous address book state, and restores the address book to that state. +- All possible actions mentioned above such as creating modules, deleting modules and adding tasks to modules are implemented through +the `ModuleBook` class by calling corresponding methods of it such as `addModule`, `getModule`. -image::UndoRedoState3.png[] +- The program will automatically save any modification to module book after each command is executed by calling the `saveModuleBook` method +in `Storage`. -[NOTE] -If the `currentStatePointer` is at index 0, pointing to the initial address book state, then there are no previous address book states to restore. The `undo` command uses `Model#canUndoAddressBook()` to check if this is the case. If so, it will return an error to the user rather than attempting to perform the undo. +- For example, modules are created with `moduleAdd` command, followed by the module code and grade. (if applicable) + +Our program will check if the module code is valid by using the search feature above and whether the module has already been added in our module book. +And then call method `addModule` in `ModuleBook` to create the module as required. Finally, it will automatically save the module added just now. -The following sequence diagram shows how the undo operation works: +- The _Sequence Diagram_ below shows how the components interact with each other for the scenario where the user want to add a module in our program. -image::UndoSequenceDiagram.png[] -NOTE: The lifeline for `UndoCommand` should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram. +.Sequence diagram when moduleAdd command is executed +image::ModuleAddSequenceDiagram.png[width="950"] -The `redo` command does the opposite -- it calls `Model#redoAddressBook()`, which shifts the `currentStatePointer` once to the right, pointing to the previously undone state, and restores the address book to that state. +.Relation between ModuleBook and Task +image::PartOfModelClassDiagramForProfile.png[width="400"] -[NOTE] -If the `currentStatePointer` is at index `addressBookStateList.size() - 1`, pointing to the latest address book state, then there are no undone address book states to restore. The `redo` command uses `Model#canRedoAddressBook()` to check if this is the case. If so, it will return an error to the user rather than attempting to perform the redo. +- The program will synchronize the modification to module tasks in `ModuleBook` with that shown in Calendar tab through `ModelManager` as shown above. +i.e. Any modification in module tasks will be updated in `Task` which is the main class Calendar feature depends on. (see more details in Calendar feature) + +==== Example Use Scenario + +Given below are example usages scenario and how the Module Book feature behaves at each step. + +[TIP] +User can manage their tasks in different ways. + +*Example 1*: + -Step 5. The user then decides to execute the command `list`. Commands that do not modify the address book, such as `list`, will usually not call `Model#commitAddressBook()`, `Model#undoAddressBook()` or `Model#redoAddressBook()`. Thus, the `addressBookStateList` remains unchanged. +. The user execute `listModuleTasks` command. +. The program check whether the module code provided has been recorded or not. +. Display the list of tasks. -image::UndoRedoState4.png[] +Below is an activity diagram describing the events that will happen: -Step 6. The user executes `clear`, which calls `Model#commitAddressBook()`. Since the `currentStatePointer` is not pointing at the end of the `addressBookStateList`, all address book states after the `currentStatePointer` will be purged. We designed it this way because it no longer makes sense to redo the `add n/David ...` command. This is the behavior that most modern desktop applications follow. +.Activity diagram for list module tasks command +image::ListModuleTasksActivityDiagram.png[width="790"] -image::UndoRedoState5.png[] +*Example 2*: + -The following activity diagram summarizes what happens when a user executes a new command: +. The user execute `done` command. +. The program check whether the input is valid or not. +. The task specified will be deleted accordingly. +. Synchronize between module book and calendar. -image::CommitActivityDiagram.png[] +Below is an activity diagram describing the events that will happen: + +.Activity diagram for done command +image::DoneCommandActivityDiagram.png[width="850"] ==== Design Considerations -===== Aspect: How undo & redo executes +*Aspect 1*: How the user add in a module into module book for future management ? + +- *Current solution*: Only need to provide the module code to add module and it will fetch the information about the module using Module Search feature automatically. +* *Pros*: Users don't need to provide any other information (such as modular credit of the module) for other functionality such as calculating the CAP. +* *Pros*: The module information will be cached locally after you add the module once and this can used for future development. +* *Cons*: Need Internet connection when you add in certain module for the first time. +* *Cons*: Highly depends on the Module Search feature. + +- *Alternative Solution*: Let the user enter all information required for each module when they add it in. (such as modular credit) +* *Pros*: More flexible, not depends on other features. +* *Cons*: Very tedious for users to add in lots of modules. +* *Cons*: Need to ask user to provide new information when more new functionality is added in the future. + +*Reason for chosen implementation*: + +The current implementation is much more user friendly and have more potential for future development. The implement can become +very ideal if the Module Search feature works properly. + +*Aspect 2*: How the user manage their tasks for each module? + +- *Current solution*: For each module added, it contains a list of `ModuleTask`. Also update the calendar when add task in. +* *Pros*: Users can either view their tasks for each module separately or view all the tasks shown in Calendar tab. +* *Pros*: More nice-looking that the user can view all the deadlines on calendar. +* *Cons*: Prone to bugs during the synchronization of module book and calendar. + +- *Alternative solution*: Only store the list of `ModuleTask` in module book and do not update in Calendar tab. +* *Pros*: Easier to implement and can avoid some synchronization bugs. +* *Cons*: Users can not gain a view of the whole pictures with all tasks shown on calendar. + +*Reason for chosen implementation*: + +The current implementation updates the module tasks added in onto the calender and provides the users different ways +to manage their tasks. (as a whole or separately for each module) +// end::ModuleBook[] + +// tag::Xinwei[] +=== Calendar Feature (Xinwei) +NUSProductivity consist of a calendar feature that provides an overarching view of all tasks, allowing user to view their uncompleted tasks and whether there is a task present on the date itself. + +The calendar feature allows users to add either a `deadline` or a `Module Task` to the calendar, which inherits from a super class `Task` + + +==== Implementation + + +The implementation of the main Calender tab is facilitated a `SplitPane` in the MainWindow class consisting of 2 main classes, `CalenderListPanel` and `CalenderPanel` + +The `CalenderListPanel` on the right contains a list of `Task` added to the calendar will the `CalenderPanel` shows the actual calender view for the current month. + +The diagram below describes the class structure of the calendar class structure. + +.Calender UI Class Diagram +image::CalenderUIClassDiagram.png[] + +Upon initialisation of CalenderPanel, the CalenderPanel would call its 2 methods of `setMonth()` and `setDate()` to create `CalenderDate` instances starting from the first day of the current month. + +Then, upon initialisation of CalenderListPanel, it will create instances of `CalenderDeadline` by getting the `ObservableList` from `getDeadlineTaskList`. + +This will call upon the inner class in `CalenderListPanel`, `DeadlineListViewCell updateItem` method which allows the program to check whether there is any deadline due on any on the date in `calenderDatesArrayList`. + +If a `deadline` or a `Module Task` is found, `setPriorityColour()` and `setStatusColour()` will be invoked to update the Calendar display to change the colour of the dots based on the priority levels mentioned in the User Guide. + +Every time a `Task` is modified, the `DeadlineListViewCell updateItem` method will be invoked to update any changes to the display. + +==== Implementation logic + +* Implementation: both deadline and module Task are inherits from the super class Task. A task is created when the `moduleTask` or `deadlineAdd` command is invoked. + +* The _Sequence Diagram_ below shows how the components interact with each other for the scenario where the user wants to add a task to the program. + +.Add task sequence diagram +image::AddTaskSequenceDiagram.png[] + +The `addDeadlineTask` method will modify the `ObservableList` supplied to the `CalenderListPanel`, invoking the `updateItem` method, causing a change in the user display. + +All other calendar functions works similarly to `addDeadlineTask` as shown in the Activity diagram below. + +.Calendar Activity Diagram +image::CalendarActivityDiagram.png[] + +==== Design Considerations: + +Aspect 1: Method of displaying the dot indicator + +* *Current solution*: Currently, the dot is being shown by getting the `static HashMap` from `Task` as this `HashMap` stores a key-pair value of date - Tasks. +* By making changes to the `deadlineTaskList`, we also edited the `HashMap`. This allows everytime a `updateItem` method call to check whether a task is present, and if so the priority of the task. + +* *Alternative 1*: Store all tasks of the current date in `CalendarDate`. +** Pros: Allows for tasks to be accessed locally and not through a static variable from the main class `Task`. +** Cons: Implementation may be more complex as more parameters have to be passed to `CalenderDate` and also ensuring that the list of task passed in `CalendarDate` is up to date. + + +**Reason for chosen implementation:** +The current solution is easier to implement as everything is done in the relevant functions such as `deadlineAdd` or `taskDelete`. The only thing that the program needs to check is whether a date in the `HashMap` contains a task and if so, the priority of the task. With the alternative implementation, we will need to pass in a `List` for each of the 31 dates which may be very troublesome to keep track of especially when we are editing the main task list. This ease of implementation is the deciding factor when choosing which method to implement. + + + + +=== Notes Feature (Xinwei) + +==== Implementation + +The notes feature allow users to access their desktop files and folders with commands. + +This feature is implemented using a panel on the main window, listing out a list of documents and folders that are in the specified directory. + +Notes features includes `notesOpen`, `notesCreate`, `notesDelete` and `notesList`. + +The diagram below shows the sequence diagram of a `notesOpen` command with the other methods working similarly to the stated method. + +.Notes Open Sequence Diagram +image::notesOpenSequenceDiagram.png[width="600"] + + + +.Notes List Activity Diagram +image::NotesList.png[width="600"] + +.Notes Open Activity Diagram +image::NotesCreation.png[width="600"] + +notesCreate and notesDelete activity diagram works similar to notesOpen. + + +==== Pathing +Our program allows the user to specify different pathing system, namely: + + 1. AbsolutePath + 2. RelativePath + +.Notes Pathing Diagram +image::absVSrel.png[width="600"] + +AbsolutePath will take the path given from `usr/`. + +RelativePath will take reference from the path that the current system has opened, in this case, `usr/Desktop/NUS Y2S2`. +The user is given the freedom to provide any of the 2 forms when using the `notesOpen`, `notesCreate`, `notesDelete` and `notesList` commands. + +**AbsolutePath**: + +*Benefits*: + +This allows for more flexibility as the user do not need to keep note of its current directory and will be able to access any folder/document that is on their system + +*cons*: + +Will require much more input from the user, for example, referring to the above figure, +Accessing the CS2103T file requires the user to input `loc/Desktop/NUS Y2S2/CS2103T` as opposed to `loc/CS2103T` if the user is using absolute over relative pathing + +**RelativePath**: + +*Benefits*: + +Easier for the user to navigate through the current folder and not key in the whole folder path + +*Cons*: + +Not as flexible. Referring to the above diagram, +Accessing the *Documents* folder will require the user to input `loc/../../Documents`, this may not be as intuitive to people with no programming background. +Using `loc/Documents abs/abs` will allow the user to access any folder from anywhere. + +// end::Xinwei[] + +=== Diary feature (Jiangwei) +The diary feature is just like a real life diary book. It allows you jot down any thoughts, be it for your personal life or for school work. You can also note down a concept you don't understand or your reflection for each day in case you want to revisit them in the future. +In details, users can add and delete a diary entry, display a particular diary entry and tag each entry with mood or the weather on that day. + +==== Implementation +- This feature is implemented using a panel on the main screen of diary tab. The list of diary entries will update upon executing diary commands that may affect Diary Book. (such as diaryAdd, diaryDelete or diaryMood) The GUI aspect is not fully implemented yet (coming in v2.0), so the current implementation's response is in CLI style. +- The Diary Book currently supports the following features: +. Adding a diary entry +. Deleting a diary entry +. Showing the log of recorded entries +. Display a particular diary entry with specified entry ID +. Finds the list of diary entries the match a given date +. tagging a entry with mood or weather + +.Class diagram of structure and relations of DiaryBook, DiaryEntry and relevant classes. +image::DiaryClass.png[width="790"] + +- As shown in the class diagram above, diary entries are created by `DiaryEntry` class. Every instance of `DiaryEntry` contains a `LocalDate`, a `Mood` object (optional) and a `Weather` object (optional). +- Different types of `Mood` such as `CalmMood`, `HappyMood` extends from the abstract class `Mood`. Similar subtype relation holds for different types of weather and the abstract class `Weather`. +- List of diary entries are managed by the `DiaryBook` class. All relevant actions such as adding, deleting as described above are implemented inside `DiaryBook`. This can be seen from the methods of `DiaryBook` in the class diagram above. + +==== Example Use Case +Given below are example usages scenario and how the Module Book feature behaves at each step. + +- *Example*: deleting the diary entry with entry ID 1 +The sequence diagram below shows how the `diaryDelete id/1` command is executed + +.Sequence Diagram for executing `diaryDelete id/1` +image::DiarySequence.png[width="790"] + +==== Design Considerations +How does the user edit a diary entry? +- Current solution: `Mood` and `Weather` can be updated easily with the `diaryMood` and `diaryWeather` command. However, We have not include a edit feature for the entry content. The users can first delete the entry and re-add the entry with updated diary entry. +** *Pros*: May deter users from changing past diary content as diary is meant to record what have happened and editing the past experience may not be encouraged. +** *Cons*: The users may need to retype the whole entry content which is a time consuming process. + +- Alternative solution: include a feature that replaces a certain keyword with a new keyword. +** *Pros*: Requires less typing and less time consuming. +** *Cons*: May cause some unintended changes to the entry content because of entry content containing substrings of the replaced keyword. + +*Reason for chosen implementation:* +We want to adhere to the fact that past diary entries should not be changed but still allows editing, only that it will require more effort. The alternative solution is certainly feasible, to avoid the downsides of the alternative solution we can incorporate regular expressions to ensure more accurate replacing. However, this may require the users to have some prior knowledge which is not desired. + +=== Event Feature (Proposed) (Xuan Xin) + +This feature (in the works already) is meant to be an enhancement towards the Calendar feature. + +==== Implementation -* **Alternative 1 (current choice):** Saves the entire address book. -** Pros: Easy to implement. -** Cons: May have performance issues in terms of memory usage. -* **Alternative 2:** Individual command knows how to undo/redo by itself. -** Pros: Will use less memory (e.g. for `delete`, just save the person being deleted). -** Cons: We must ensure that the implementation of each individual command are correct. +* The event feature would support the following features: +** Adds and deletes events onto the calendar +** Sort events by date (default) +** Consolidate and list all events -===== Aspect: Data structure to support the undo/redo commands +The sequence diagram below shows how components interact with each other when user inputs `eventAdd` to add an event onto the calendar. -* **Alternative 1 (current choice):** Use a list to store the history of address book states. -** Pros: Easy for new Computer Science student undergraduates to understand, who are likely to be the new incoming developers of our project. -** Cons: Logic is duplicated twice. For example, when a new command is executed, we must remember to update both `HistoryManager` and `VersionedAddressBook`. -* **Alternative 2:** Use `HistoryManager` for undo/redo -** Pros: We do not need to maintain a separate list, and just reuse what is already in the codebase. -** Cons: Requires dealing with commands that have already been undone: We must remember to skip these commands. Violates Single Responsibility Principle and Separation of Concerns as `HistoryManager` now needs to do two different things. -// end::undoredo[] +.Add Event Sequence Diagram +image::AddEventSequenceDiagram.png[] -// tag::dataencryption[] -=== [Proposed] Data Encryption +The `eventAdd` method works similar to the `addDeadlineTask` above and will modify the `ObservableList` supplied to the `CalenderListPanel`, invoking the `updateItem` method, causing a change in the user display. -_{Explain here how the data encryption feature will be implemented}_ +==== Example Use Scenario -// end::dataencryption[] +*Example 1*: + + +. The user execute `listEvent` command. +. The program checks if input is valid. +. The list of events will be displayed. + +Below then shows an example of an activity diagram for the `listEvent` command. + +.List Event Activity Diagram +image::ListEventActivityDiagram.png[] + +==== Further Developments + * The event feature will aim to link contacts from the addressbook to the calendar. + +For now, the full activity diagram for `Event`, which has a similar implementation to `Deadline`, is shown below: + +.Event Activity Diagram +image::EventActivityDiagram.png[] === Logging @@ -280,10 +534,15 @@ Refer to the guide <>. *Target user profile*: * has a need to manage a significant number of contacts +* has a need to manage deadlines and tasks +* has a need to manage module planning * prefer desktop apps over other types -* can type fast * prefers typing over mouse input +* prefers to have everything in one app +* can type fast * is reasonably comfortable using CLI apps +* is studying in NUS + *Value proposition*: manage contacts faster than a typical mouse/GUI driven app @@ -292,7 +551,7 @@ Refer to the guide <>. Priorities: High (must have) - `* * \*`, Medium (nice to have) - `* \*`, Low (unlikely to have) - `*` -[width="59%",cols="22%,<23%,<25%,<30%",options="header",] + |======================================================================= |Priority |As a ... |I want to ... |So that I can... |`* * *` |new user |see usage instructions |refer to instructions when I forget how to use the App @@ -303,9 +562,43 @@ Priorities: High (must have) - `* * \*`, Medium (nice to have) - `* \*`, Low (un |`* * *` |user |find a person by name |locate details of persons without having to go through the entire list +|`* * *` |user who wants to improve time management |add deadlines |know when to complete tasks in todo list + +|`* * *` |user |add event |know when and where is the event and who will going to participate in the event + +|`* * *` |NUS student|add module to module plan |see modules I need to take to fulfill degree requirements + +|`* * *` |NUS student|show module plan |see list of modules I need to take/have taken + +|`* * *` |NUS student|write and save notes for each module I have taken/am taking | + +|`* * *` |NUS student|write diaries for each day's summary |refer back to what I have done in the future + |`* *` |user |hide <> by default |minimize chance of someone else seeing them by accident +|`* *` |user |delete diary entry | + +|`* *` |user |show diary entry list | + +|`* *` |user |delete module from module plan |know which modules I have taken + +|`* *` |NUS student|fetch module information | + +|`* *` |NUS student|know current CAP | + +|`* *` |user who wants to improve grades |calculate target CAP |know what grades to aim for to achieve my target CAP + +|`* *` |user |sort deadlines |prioritize which tasks to finish first + +|`* *` |user who has a short memory span |receive reminders about the deadlines |don't miss out any important tasks + |`*` |user with many persons in the address book |sort persons by name |locate a person easily + +|`*` |user |create group chats |communicate with peers in the same module + +|`*` |user |tag my diary with that day's weather | + +|`*` |user |tag my diary with that day's emotion |I can filter my diaries with specific mood |======================================================================= _{More to be added}_ @@ -341,14 +634,39 @@ Use case ends. + Use case resumes at step 2. +[discrete] +=== Use case: Delete module + +*MSS* + +1. User requests to show module plan +2. AddressBook shows module plan +3. User requests to delete a module taken +4. AddressBook deletes module +5. AddressBook updates module plan ++ +Use case ends. + +*Extensions* +[none] +* 3a. The given module code is invalid. ++ +[none] +** 3a1. AddressBook shows an error message. ++ +Use case resumes at step 2. + _{More to be added}_ [appendix] == Non Functional Requirements . Should work on any <> as long as it has Java `11` or above installed. -. Should be able to hold up to 1000 persons without a noticeable sluggishness in performance for typical usage. -. A user with above average typing speed for regular English text (i.e. not code, not system admin commands) should be able to accomplish most of the tasks faster using commands than using the mouse. +. A user with above average typing speed for regular English text (i.e. not code, not system admin commands) should be able to accomplish most of the tasks faster using commands than using the mouse (e.g. fetch module information) +. Should respond within 2 seconds with exception of 5s for some commands due to network availability (`moduleSearch`, `moduleAdd`) +. Should be easy to use for users who are novice at using technology +. User should be a current student in NUS + _{More to be added}_ @@ -361,22 +679,16 @@ Windows, Linux, Unix, OS-X [[private-contact-detail]] Private contact detail:: A contact detail that is not meant to be shared with others -[appendix] -== Product Survey - -*Product Name* +[[NUS]]NUS:: +National University of Singapore -Author: ... +[[CAP]]CAP:: +The Cumulative Average Point is the weighted average grade point of the letter grades of all the modules taken by the students, according to NUS's grading system. -Pros: +[[CLI]]CLI:: +Command Line Interface -* ... -* ... -Cons: - -* ... -* ... [appendix] == Instructions for Manual Testing @@ -414,12 +726,98 @@ _{ more test cases ... }_ .. Other incorrect delete commands to try: `delete`, `delete x` (where x is larger than the list size) _{give more}_ + Expected: Similar to previous. -_{ more test cases ... }_ -=== Saving data +=== Calendar + +.. Test case: `deadlineAdd desc/Test deadline date/30-04-2020 cat/Work` + +Expected: A deadline task is added to the list, details of the task is shown on th left hand side of the calendar tab. A green dot will appear on 30-04-2020 to show that there is a task on that day + +.. Test case: `deadlineAdd desc/Test deadline2 date/28-04-2020 cat/Work` + +Expected: A deadline task is added to the list, details of the task is shown on th left hand side of the calendar tab. The task list on the left should show list sorted by dates, i.e. this deadline to be above the test case in a. + +.. Test case: `moduleTask m/CS2103T desc/CS2103T Test by/04-04-2020 pri/5` + +Expected: An error message shown that no such module is present (if you haven't add CS2103T to the program), else, a task will be added to the list, the task list on the left will be sorted by date and a red dot (priority = 5) will be shown on the calendar + +.. Test case: `taskDelete index/1` + +Expected: First task on the task list is deleted. + +.. Test case: `taskDelete index/0` + +Expected: No task will be deleted. Error details shown in the status message. Status bar remains the same. + +.. Test case: `sortTask by/priority` + +Expected: Task on the left is sorted by priority. + +.. Test case: `sortTask by/asiqowe` + +Expected: No sorting will be parsed and error message will be shown. Status bar remains the same. + +.. Test case: `findTask date/30-04-2020` + +Expected: All task that have a deadline of 30-04-2020 will be shown on the left panel, calendar dots for other dates will NOT be removed. + +.. Test case: `listTask` + +Expected: List all task after a findTask to show all available Tasks. + + +=== Notes + +.. Test case: `notesList loc/Desktop pt/abs` + +Expected: All files on your desktop will be listed in the display + +.. Test case: `notesList loc/Desktop/Desktop by/abs` + +Expected: Error message will be shown + +.. Test case: `notesOpen loc/Desktop name/Test.doc pt/abs` + +Precondition: Needs to have a file called Test.doc on the desktop, else an error will be thrown + +Expected: File is opened, notes user interface current directory changed to usr/Desktop + +.. Test case: `notesCreate loc/Desktop name/test type/folder pt/abs` + +Precondition: No folder on the desktop is named test + +Expected: folder is created, notes user interface current directory changed to usr/Desktop/test + +.. Test case: `notesDelete loc/Desktop name/Test.doc pt/abs` + +Precondition: Needs to have a file called Test.doc on the desktop, else an error will be thrown + +Expected: File is deleted, notes user interface current directory changed to usr/Desktop + + +=== Module + +.. Test case: `moduleAdd m/CS2103T g/A+` + +Expected: A module of CS2103T with its grade will be added to the profile tab list + +.. Test case: `moduleAdd m/CS2103123123T g/A+` + +Expected: Error message will be thrown with no such module. + +.. Test case: `moduleAdd m/CS2101` + +Expected: Module of CS2101 will be added to the profile tab, without a grade. + +.. Test case: `moduleDel m/CS2103T` + +Expected: CS2103T module will be deleted + +.. Test case: `grade m/CS2101 g/A+` + +Expected: CS2101 grade will be updated to A+ + +.. Test case: `cap` + +Expected: Calculates your current cap with the modules inputted. + + + + + + + + + + + + + + + + + + + + + -. Dealing with missing/corrupted data files -.. _{explain how to simulate a missing/corrupted file and the expected behavior}_ -_{ more test cases ... }_ diff --git a/docs/Documentation.adoc b/docs/Documentation.adoc index ad90ac87bda..af5dd6aa206 100644 --- a/docs/Documentation.adoc +++ b/docs/Documentation.adoc @@ -1,4 +1,4 @@ -= AddressBook Level 3 - Documentation += NUSProductivity - Documentation :site-section: DeveloperGuide :toc: :toc-title: diff --git a/docs/LearningOutcomes.adoc b/docs/LearningOutcomes.adoc deleted file mode 100644 index 436c1777617..00000000000 --- a/docs/LearningOutcomes.adoc +++ /dev/null @@ -1,216 +0,0 @@ -= Learning Outcomes -:site-section: LearningOutcomes -:toc: macro -:toc-title: -:toclevels: 1 -:imagesDir: images -:stylesDir: stylesheets -ifdef::env-github[] -:note-caption: :information_source: -endif::[] - -After studying this code and completing the corresponding exercises, you should be able to, - -toc::[] - -== Utilize User Stories `[LO-UserStories]` - -=== References - -* https://se-edu.github.io/se-book/specifyingRequirements/userStories/[se-edu/se-book: Requirements: Specifying Requirements: User Stories] - -=== Exercise: Add more user stories - -* Assume you are planing to expand the functionality of the AddressBook (but keep it as a CLI application). -What other user stories do you think AddressBook should support? Add those user stories to the `DeveloperGuide.adoc`. - -== Utilize use cases `[LO-UseCases]` - -=== References - -* https://se-edu.github.io/se-book/specifyingRequirements/useCases/[se-edu/se-book: Requirements: Specifying Requirements: Use Cases] - -=== Exercise: Add a 'Rename tag' use case - -* Add a use case to the `DeveloperGuide.adoc` to cover the case of _renaming of an existing tag_. -e.g. rename the tag `friends` to `buddies` (i.e. all persons who had the `friends` tag will now have -a `buddies` tag instead) -Assume that AddressBook confirms the change with the user before carrying out the operation. - -== Use Non Functional Requirements `[LO-NFR]` - -=== References - -* https://se-edu.github.io/se-book/requirements/nonFunctionalRequirements/[se-edu/se-book: Requirements: Non-Functional Requirements] - -=== Exercise: Add more NFRs - -* Add some more NFRs to the `DeveloperGuide.adoc` - -== Use Polymorphism `[LO-Polymorphism]` - -Note how the `Command::execute()` method shows polymorphic behavior. - -=== References - -* https://se-edu.github.io/se-book/oop/polymorphism/[se-edu/se-book: Paradigms: OOP: Polymorphism] -* https://se-edu.github.io/se-book/cppToJava/inheritance/polymorphism/[se-edu/se-book: C++ to Java: OOP: Polymorphism] - -=== Exercise: Add a polymorphic `isMutating` method - -* Add a method `boolean isMutating()` to the `Command` class. This method will return `true` for -command types that mutate the data. e.g. `AddCommand` -* Currently, AddressBook data are saved to the file after every command. -Take advantage of the the new method you added to limit file saving to only for command types that mutate data. -i.e. `add` command should always save the data while `list` command should never save data to the file. - -[NOTE] -==== -There may be better ways to limit file saving to commands that mutate data. The above approach, while not -optimal, will give you chance to implement a polymorphic behavior. -==== - -== Use abstract classes/methods `[LO-Abstract]` - -=== References - -* https://se-edu.github.io/se-book/oop/inheritance/abstractClasses/[se-edu/se-book: Paradigms: OOP: Abstract Classes] -* https://se-edu.github.io/se-book/cppToJava/inheritance/abstractClassesAndMethods/[se-edu/se-book: C++ to Java: OOP: Abstract Classes] - -=== Exercise: Make `Command#execute()` method abstract - -* Make the `Command#execute()` method abstract (hint: refer to the comment given below the method) - -== Use interfaces `[LO-Interfaces]` - -Note how the `AddressBook` class implements the `ReadOnlyAddressBook` interface so that clients who don't need write access to the `AddressBook` can access the `AddressBook` through the `ReadOnlyAddressBook` interface instead. - -image::ReadOnlyAddressBookUsage.png[width=500] - -=== References - -* https://se-edu.github.io/se-book/oop/inheritance/interfaces/[se-edu/se-book: Paradigms: OOP: Abstract Interfaces] -* https://se-edu.github.io/se-book/cppToJava/inheritance/interfaces/[se-edu/se-book: C++ to Java: OOP: Abstract Interfaces] - -=== Exercise: Add a `Printable` interface - -* Add a `Printable` interface as follows. -+ -image::PrintableInterface.png[width=400] -* `Override` the `getPrintableString` in classes `Name`, `Phone`, `Email`, and `Address` so that each produces a printable string representation of the object. e.g. `Name: John Smith`, `Phone: 12349862` -* Add the following method in a suitable place of some other class. Note how the method depends on the Interface. -+ -[source,java] ----- -/** - * Returns a concatenated version of the printable strings of each object. - */ -String getPrintableString(Printable... printables) { ----- -+ -The above method can be used to get a printable string representing a bunch of person details. -For example, you should be able to call that method like this: -+ -[source,java] ----- -// p is a Person object -return getPrintableString(p.getPhone(), p.getEmail(), p.getAddress()); ----- - -== Follow Liskov Substitution Principle `[LO-LSP]` - -=== References - -* https://se-edu.github.io/se-book/principles/liskovSubstitutionPrinciple/[se-edu/se-book: Principles: Liskov Substitution Principle] - -=== Exercise: Add an exception to an overridden method - -* Add a `throws Exception` clause to the `AddCommand::execute` method. Notice how Java compiler will not allow it, -unless you add the same `throws` clause to the parent class method. This is because if a child class throws -an exception that is not specified by the Parent's contract, the child class is no longer substitutable in place of -the parent class. -* Also note that while in the above example the compiler enforces LSP, there are other situations where it is up to -the programmer to enforce it. For example, if the method in the parent class works for `null` input, the overridden -method in the child class should not reject `null` inputs. This will not be enforced by the compiler. - -== Use Java-FX for GUI programming `[LO-JavaFx]` - -=== References - -* https://se-edu.github.io/se-book/javaTools/javaFXBasic/[se-edu/se-book: Tools: Java: JavaFX: Basic] - -=== Exercise: Enhance GUI - -* Do some enhancements to the AddressBook GUI. e.g. add an application icon, change font size/style - -== Analyze Coupling and Cohesion of designs `[LO-CouplingCohesion]` - -* Notice how having a separate `ParserUtil` class to handle user input validation, space trimming etc. of model data (an application of the Single Responsibility Principle) improves the _cohesion_ of the model component (since it does not need to be concerned with handling user input) as well as the `ParserUtil` class. - -=== References - -* https://se-edu.github.io/se-book/designFundamentals/coupling/[se-edu/se-book: Design: Design Principles: Coupling] -* https://se-edu.github.io/se-book/designFundamentals/cohesion/[se-edu/se-book: Design: Design Principles: Cohesion] - -=== Exercise: Identify places to reduce coupling and increase cohesion - -* Where else in the design coupling can be reduced further, or cohesion can be increased further? - -[[apply-dependency-inversion-principle-lo-dip]] -== Apply Dependency Inversion Principle `[LO-DIP]` - -* Note how the `LogicManager` class doesn't depend on `StorageManager` directly, but rather the interface `Storage`. -This is an application of the Dependency Inversion Principle. -+ -image::LogicStorageDIP.png[width=300] -* Where else in the code do you notice the application of DIP? - -=== References - -* https://se-edu.github.io/se-book/principles/dependencyInversionPrinciple/[se-edu/se-book: Principles: Dependency Inversion Principle] - -== Use Dependency Injection `[LO-DI]` - -Notice how the `LogicManager` class does not depend on the `StorageManager` class, but depends on the `Storage` interface. -This allows us to use _Dependency Injection_ to test the `LogicManager` class without getting the `StorageManager` class involved. - -=== References - -* https://se-edu.github.io/se-book/testing/dependencyInjection/[se-edu/se-book: Quality Assurance: Testing: Dependency Injection] - -=== Exercise: Facilitate injecting a StorageStub - -* Notice how `LogicManagerTest` tests `LogicManager` by constructing a `StorageManager` object. -* Implement `StorageStub` such that calls to its `save*` methods do nothing (i.e. empty method body). -* Update `LogicManagerTest` to work with the `StorageStub` instead of the actual `StorageManager` object. -i.e. `LogicManagerTest` injects a `StorageStub` object when constructing a `LogicManager` before testing it. -+ -image::DependencyInjection.png[width=600] -* The example above uses <> as a means to achieve DI. -Note that there is another way to inject a `StorageStub` object, as shown below. -In this case we do not apply the DIP but we still achieve DI. -+ -image::DependencyInjectionWithoutDIP.png[width=250] - -== Apply Open-Closed Principle `[LO-OCP]` - -=== References - -* https://se-edu.github.io/se-book/principles/openClosedPrinciple/[se-edu/se-book: Principles: Open-Closed Principle] - -=== Exercise: Analyze OCP-compliance of the `LogicManager` class - -* Consider adding a new command to the Address Book. e.g. an `edit` command. Notice how little you need to change in the `LogicManager` class to extend its behavior so that it can execute the new command. -That is because `LogicManager` follows the OCP i.e. `LogicManager` is _open to be extended_ with more commands but _closed for modifications_. -* Is it possible to make the `AddressBookParser` class more OCP-compliant in terms of extending it to handle more -command types? -* In terms of how it saves data, is `LogicManager` more OCP-compliant -due to the application of DIP as given in <>? -How can you improve ``LogicManager``'s OCP-compliance further so that it can not only work with different types -of storages, but different number of storages (e.g. save to both a text file and a database). - -== Work in a 3KLoC code base `[LO-3KLoC]` - -=== Exercise: Enhance AddressBook - -* Enhance AddressBook in some way. e.g. add a new command diff --git a/docs/SettingUp.adoc b/docs/SettingUp.adoc index c0659782fab..d85c4133a2f 100644 --- a/docs/SettingUp.adoc +++ b/docs/SettingUp.adoc @@ -1,4 +1,4 @@ -= AddressBook Level 3 - Setting Up += NUSProductivity - Setting Up :site-section: DeveloperGuide :toc: :toc-title: diff --git a/docs/Testing.adoc b/docs/Testing.adoc index 5767b92912c..24ae3537ee1 100644 --- a/docs/Testing.adoc +++ b/docs/Testing.adoc @@ -1,4 +1,4 @@ -= AddressBook Level 3 - Testing += NUSProductivity - Testing :site-section: DeveloperGuide :toc: :toc-title: diff --git a/docs/UserGuide.adoc b/docs/UserGuide.adoc index 4e5d297a19f..c936efa0c0f 100644 --- a/docs/UserGuide.adoc +++ b/docs/UserGuide.adoc @@ -1,6 +1,7 @@ -= AddressBook Level 3 - User Guide += NUSProductivity :site-section: UserGuide :toc: +:toclevels: 4 :toc-title: :toc-placement: preamble :sectnums: @@ -11,37 +12,76 @@ ifdef::env-github[] :tip-caption: :bulb: :note-caption: :information_source: +:caution-caption: :fire: +:important-caption: :heavy_exclamation_mark: endif::[] -:repoURL: https://github.com/se-edu/addressbook-level3 +:repoURL: https://github.com/AY1920S2-CS2103T-W16-4/main -By: `Team SE-EDU` Since: `Jun 2016` Licence: `MIT` +By: `Team W16-4` Since: `Mar 2020` Licence: `MIT` -== Introduction +== Introduction (Xinwei) -AddressBook Level 3 (AB3) is for those who *prefer to use a desktop app for managing contacts*. More importantly, AB3 is *optimized for those who prefer to work with a Command Line Interface* (CLI) while still having the benefits of a Graphical User Interface (GUI). If you can type fast, AB3 can get your contact management tasks done faster than traditional GUI apps. Interested? Jump to the <> to get started. Enjoy! -== Quick Start -. Ensure you have Java `11` or above installed in your Computer. -. Download the latest `addressbook.jar` link:{repoURL}/releases[here]. -. Copy the file to the folder you want to use as the home folder for your Address Book. -. Double-click the file to start the app. The GUI should appear in a few seconds. +=== An Introduction to NUSProductivity User guide + +- NUSProductivity is an application designed for all NUS students to better manage their school work. The app is set out to enhance your productivity in school through 5 main features, module planning, CAP (cumulative average point) tracking, note taking, deadline and task listing, and finally, diary logging. This app is designed only for NUS students for now with the possibility to customise it for students from other universities in the future. More importantly, NUSProductivity is optimized for those who prefer to work with a Command Line Interface (CLI) while still having the benefits of a Graphical User Interface (GUI). Read on to get you started on using the application! + +- The purpose of this document is for you to familiarise yourself with the functions and capabilities of what NUSProductivity can do. + +- The image below shows the different parts of the user interface of NUSProductivity + +.NUSProductivity Introduction +image::StartupDescription.png[width="790"] + + +=== Commonly Used Symbols + +[NOTE] +This symbol indicates something you should take note of. + +[TIP] +This symbol indicates a tip that you could use. + +[CAUTION] +This symbol indicates something need be used or followed with caution. + +[IMPORTANT] +This symbol indicates something you really need to pay attention to. + + +== Quick Start + +This section allows you to start up NUSProductivity with ease. Detailed steps are listed below. + +. Ensure you have Java `11` or above installed on your computer, if not you can refer to the guide below +. https://docs.oracle.com/en/java/javase/11/install/installation-jdk-microsoft-windows-platforms.html#GUID-C11500A9-252C-46FE-BB17-FC5A9528EAEB[Windows] https://docs.oracle.com/en/java/javase/11/install/installation-jdk-macos.html#GUID-2FE451B0-9572-4E38-A1A5-568B77B146DE[Mac] +. Download the latest version of `NUSProductivity.jar` link:{repoURL}/releases[here]. +. Copy the file to the folder you want to use as the home folder for NUSProductivity. +. Double-click the file to start the app. The GUI should appear in a few seconds (screenshot of GUI shown below). + +.NUSProductivity Start up image::Ui.png[width="790"] + . Type the command in the command box and press kbd:[Enter] to execute it. + e.g. typing *`help`* and pressing kbd:[Enter] will open the help window. . Some example commands you can try: -* *`list`* : lists all contacts -* **`add`**`n/John Doe p/98765432 e/johnd@example.com a/John street, block 123, #01-01` : adds a contact named `John Doe` to the Address Book. -* **`delete`**`3` : deletes the 3rd contact shown in the current list +* **`search`**`CS2103T` : searches for the module `CS2103T` +* **`calendar`** : Allows you to switch to the calendar tab +* **`deadlineAdd desc/Finish homework by/30-04-2020 cat/School`** : schedules a deadline on the calendar for you to finish your homework +* *`cap`* : calculates your CAP * *`exit`* : exits the app . Refer to <> for details of each command. + + + [[Features]] -== Features +== Features (Xinwei) + +This section shows the detailed list of usable commands. ==== *Command Format* @@ -51,127 +91,820 @@ e.g. typing *`help`* and pressing kbd:[Enter] will open the help window. * Items with `…`​ after them can be used multiple times including zero times e.g. `[t/TAG]...` can be used as `{nbsp}` (i.e. 0 times), `t/friend`, `t/friend t/family` etc. * Parameters can be in any order e.g. if the command specifies `n/NAME p/PHONE_NUMBER`, `p/PHONE_NUMBER n/NAME` is also acceptable. ==== +=== General (Xinwei) + +==== Viewing help : `help` + +- Format: `help` + +==== Exiting the program : `exit` + +- Exits the program. + +- Format: `exit` + +==== Switching Tabs : `calendar`, `diary`, `modplan`, `addressbook`, `notes`, `profile` + +- This command allows you to switch to the tab using the command line instead of clicking on the respective tab. +- Format: `calendar`, `diary`, `modplan`, `addressbook`, `notes`, `profile` + ++ +.Switching tabs +image::switching_tabs.png[width="790"] ++ + +// tag::Calendar[] + +=== Calendar (Xinwei) + +The calendar feature in the app that allows you to schedule and set deadline for important tasks such as project or assignment deadlines. + +The application allows you to add 2 type of tasks, `deadline` and `moduleTask`. + +`moduleTask` allows you to tag a module, that you have already inputted in your Profile tab, to the task itself. It allows you to set the priority level of the task. + +`deadline` allows you to input a deadline event into the calendar without any specified modules attached to it. + +==== Priority Levels + +We give you the flexibility to choose and indicate what priority each `moduleTask` should have. This priority is represented from 1 to 5, with 1 being the lowest priority and 5 being the highest. + +.NUSProductivity calendar priority levels +image::prioritylevels.png[width="790"] + + +==== Deadline + +===== Adding Deadline: `deadlineAdd` + +- Schedules a task tagged with a deadline to the calendar. A dot will be shown to indicate there is a deadline to be met on that day + +- Format: `deadlineAdd desc/DESCRIPTION by/DD-MM-YYYY cat/CATEGORY` + +.Adding Deadlines +image::deadlineAdd.png[width="790"] + +After invoking the command, the deadline will be added to the calendar as shown in figure 5. The task will be tagged as light grey to signify it is uncompleted yet. + +Deadline tasks are defaulty tagged with the lowest priority. + +==== Module Tasks (Wangkai) + +==== Adding a module task : `moduleTask` + +- Format: `moduleTask desc/DESCRIPTION m/MODULE_CODE date/DEADLINE_OR_SCHEDULED_TIMING pri/PRIORITY` + +[CAUTION] +The date inputted should be in the format: DD-MM-YYYY. + +**** +* This command allows you to create tasks to certain module you added to the program before. +* Stores the task added in the module book and automatically adds and shows on the Calender. +* You will get an updated list of tasks related to that specific module after adding. (shown in command line) +**** +- Example: +* `moduleTask desc/essay m/CS2101 date/02-04-2020 pri/3` + +Add a module task as specified in module book and also shows on calendar. + +.Adding a module task for certain module +image::ModuleTaskProfile.png[width="790"] + +.module task added will also be shown on calendar +image::ModuleTaskCalendar.png[width="790"] + +[NOTE] +This requires you to add a module under `moduleAdd` before you can use it + +.Error when adding a module task without adding a module first. +image::moduleTaskAddError.png[width="790"] + +==== Shared Functions + +The commands stated in this section can be used for both moduleTask and deadline tasks. + + +===== Marking a task as Done: `done` + +- Marks a task as completed, completed task will be shown with a black background while uncompleted task will be shown as a grey background. + +- Format: `done index/INDEX` + +.Completing a task +image::taskDone.png[width="790"] + +After a task is completed, it will be pushed to the bottom, the dot on the calendar removed and the background of the task is changed to black to signify the task is compelted. + +===== Removing Deadline: `taskDelete` + +- Deletes a task from the deadline list, marking the task as done + +- Format: `taskDelete index/INDEX` + +.Deleting a task +image::taskDelete.png[width="790"] + +[TIP] +Tip: delete a task only after the date have passed to make sure everything is completed up to your current date -=== Viewing help : `help` +===== Sorting the Calendar: `sortTask` -Format: `help` +- Allows you to sort the tasks list on the left by either date or priority. This gives you the flexibility to plan ahead, whether you want to complete a more urgent task or to complete a task with the deadline that is earlier -=== Adding a person: `add` +- Format: `sortTask by/SORT` -Adds a person to the address book + -Format: `add n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]...` +.Sorting tasks by priority +image::taskSort.png[width="790"] + +[NOTE] +SORT can only be either date or priority + +===== Finding specific tasks in the Calendar: `findTask` + +- Allows you to see task at a glance based on what you specified. + +- Format: `findTask m/MODULECODE` or `findTask cat/CATEGORY` or `findTask date/DD-MM-YYYY` + +.Finding task by module Code +image::findTask.png[width="790"] + +[NOTE] +The dots on the calendar will not disappear and will show that there is still task to be completed on that date despite filtering + +===== Listing back all tasks in the Calendar: `listTask` + +- Allows you to list back all task after you have filtered the list with findTask + +- Format: `listTask` + +.Listing all tasks +image::listTask.png[width="790"] + +==== Event (coming in v2.0) + +===== Adding Event: `eventAdd` + +- Schedules event to the calendar + +- Format: `eventAdd` desc/DESCRIPTION on/DD-MM-YYYY + +===== Deleting Event: `eventDelete` + +- Deletes event from list with the given index + +- Format: `eventDelete` index/INDEX + +===== Marking Event as done: `done` + +[NOTE] +This is meant to be an extension of the done command above, hence its implementation will follow said format. + +- Format: done index/INDEX + +===== Sorting Events: `sortEventList` + +- Sorts events by date (default) + +- Format: `sortEventList` + +===== List Events: `listEvent` + +- Lists scheduled events + +- Format: `listEvent` + +// end::Calendar[] + + +// tag::Notes[] + +=== Notes (Xinwei) + +- Allows you to create notes from the application, making it easier for you to find your files since often time students have a lot of research papers or references opened when writing a report. + +- Allows for users to create documents for notes, organise their notes in folders. +Default location is set to +`/User/` for mac +`C:\Users\` for windows + + + +==== Pathing + +- The notes feature allows you to specify the pathing used to access the file/folder you specify + +- The diagram below shows a comparision between absolute vs relative pathing + +.Pathing Absolute vs Rel +image::pathing.png[width="790"] + +[TIP] +if you want to access the Documents folder as shown in figure 13, you can use the absolute pathing and specify loc/Desktop instead of typing loc/../../../Documents + + +==== Listing Directory: `notesList` + +- List the directory that you supplied. The display will show all folders that is in that directory. + +- Format: `notesList loc/PATH pt/PATH TYPE` + +.Listing files in directory +image::notesListingUG.png[width="790"] + +==== Creating a note: `notesCreate` + +- Creates a file/directory based on what you specified. + +- Format: `notesCreate loc/PATH name/FILE_NAME type/TYPE pt/PATH_TYPE` + +[NOTE] +The type can only be file or folder + +.Creating a file in a specified directory +image::notesCreateUG.png[width="790"] + + +==== Opening a note: `notesOpen` + +- Opens a file/directory based on what you specified. + +- Format: `notesOpen loc/PATH name/FILE_NAME pt/PATH_TYPE` + +.Opening a file in a specified directory +image::notesOpenUG.png[width="790"] + +==== Deleting a note: `notesDelete` + +- Delete a file based on what you specified. + +- Format: `notesDelete loc/PATH name/FILE_NAME pt/PATH_TYPE` + +.Deleting a file in a specified directory +image::notesDeleteUG.png[width="790"] + +[NOTE] +This can only be use to delete a file and not a folder + +// end::Notes[] + +=== Address Book + +The address book allows you to add other individuals, such as professors and fellow classmates to your addressbook. Information such as phone number and email of the person will be saved into the address book for easier communication for projects or to schedule consultation relating to the module. + +==== Adding a person: `add` + +- Adds a person to the address book. +- Format: `add n/NAME p/PHONE_NUMBER e/EMAIL [t/TAG]...` [TIP] A person can have any number of tags (including 0) -Examples: +- Examples: + +* `add n/John Doe p/98765432 e/johnd@example.com` +* `add n/Betsy Crowe t/friend e/betsycrowe@example.com p/1234567 t/criminal` + -* `add n/John Doe p/98765432 e/johnd@example.com a/John street, block 123, #01-01` -* `add n/Betsy Crowe t/friend e/betsycrowe@example.com a/Newgate Prison p/1234567 t/criminal` +==== Listing all persons : `list` -=== Listing all persons : `list` +- Shows a list of all persons in the address book. -Shows a list of all persons in the address book. + -Format: `list` +- Format: `list` -=== Editing a person : `edit` +==== Editing a person : `edit` -Edits an existing person in the address book. + -Format: `edit INDEX [n/NAME] [p/PHONE] [e/EMAIL] [a/ADDRESS] [t/TAG]...` +- Edits an existing person in the address book. + +- Format: `contactEdit INDEX [n/NAME] [p/PHONE] [e/EMAIL] [t/TAG]…` **** -* Edits the person at the specified `INDEX`. The index refers to the index number shown in the displayed person list. The index *must be a positive integer* 1, 2, 3, ... -* At least one of the optional fields must be provided. -* Existing values will be updated to the input values. -* When editing tags, the existing tags of the person will be removed i.e adding of tags is not cumulative. -* You can remove all the person's tags by typing `t/` without specifying any tags after it. +• Edits the person at the specified INDEX. The index refers to the index number shown in the displayed person list. The index must be a positive integer 1, 2, 3, … +• At least one of the optional fields must be provided. +• Existing values will be updated to the input values. +• When editing tags, the existing tags of the person will be removed i.e. adding of tags is not cumulative. +• You can remove all the person’s tags by typing t/ without specifying any tags after it. **** -Examples: +- Examples: * `edit 1 p/91234567 e/johndoe@example.com` + -Edits the phone number and email address of the 1st person to be `91234567` and `johndoe@example.com` respectively. + Edits the phone number and email address of the 1st person to be `91234567` and `johndoe@example.com` respectively. * `edit 2 n/Betsy Crower t/` + -Edits the name of the 2nd person to be `Betsy Crower` and clears all existing tags. + Edits the name of the `2nd person` to be `Betsy Crower` and clears all existing tags. + +==== Locating persons by name: find -=== Locating persons by name: `find` +- Finds persons whose names contain any of the given keywords. -Finds persons whose names contain any of the given keywords. + -Format: `find KEYWORD [MORE_KEYWORDS]` +- Format: `find KEYWORD [MORE_KEYWORDS]` **** -* The search is case insensitive. e.g `hans` will match `Hans` -* The order of the keywords does not matter. e.g. `Hans Bo` will match `Bo Hans` +* The search is case insensitive. e.g. hans will match Hans +* The order of the keywords does not matter. e.g. Hans Bo will match Bo Hans * Only the name is searched. -* Only full words will be matched e.g. `Han` will not match `Hans` -* Persons matching at least one keyword will be returned (i.e. `OR` search). e.g. `Hans Bo` will return `Hans Gruber`, `Bo Yang` +* Only full words will be matched e.g. Han will not match Hans +* Persons matching at least one keyword will be returned (i.e. OR search). e.g. Hans Bo will return Hans Gruber, Bo Yang +* After a find operation, use `list` to get back the original list for address book. **** -Examples: +- Examples: * `find John` + -Returns `john` and `John Doe` + Returns `john` and `John Doe` * `find Betsy Tim John` + -Returns any person having names `Betsy`, `Tim`, or `John` + Returns any person having names `Betsy`, `Tim`, or `John` -// tag::delete[] -=== Deleting a person : `delete` +==== Deleting a person : `delete` -Deletes the specified person from the address book. + -Format: `delete INDEX` +- Deletes the specified person from the address book. + +- Format: `delete INDEX` **** -* Deletes the person at the specified `INDEX`. +* Deletes the person at the specified INDEX. * The index refers to the index number shown in the displayed person list. -* The index *must be a positive integer* 1, 2, 3, ... +* The index must be a positive integer 1, 2, 3, … **** -Examples: +- Examples: * `list` + -`delete 2` + -Deletes the 2nd person in the address book. + `delete 2` + + Deletes the 2nd person in the address book. * `find Betsy` + -`delete 1` + -Deletes the 1st person in the results of the `find` command. + `delete 1` + + Deletes the 1st person in the results of the find command. -// end::delete[] -=== Clearing all entries : `clear` +==== Clearing all entries : `clear` -Clears all entries from the address book. + -Format: `clear` +- Clears all entries from the address book. -=== Exiting the program : `exit` +- Format: `clear` -Exits the program. + -Format: `exit` +// tag::ProfilePart1[] +=== Profile / Module Book (Part 1: Manage your modules) (Wangkai) -=== Saving the data +- This feature allows individuals to see their own profile, their current cap and the all modules that the individual have taken and all the grades gotten. -Address book data are saved in the hard disk automatically after any command that changes the data. + -There is no need to save manually. +.Main Screen for profile tab +image::ProfileMainScreen.png[width="790"] -// tag::dataencryption[] -=== Encrypting data files `[coming in v2.0]` +==== Adding a module : `moduleAdd` -_{explain how the user can enable/disable data encryption}_ -// end::dataencryption[] +- Adds a module you have taken before or is taking now and store your grade for each module if you want. -== FAQ +- Format: `moduleAdd m/MODULE_CODE [g/GRADE]` -*Q*: How do I transfer my data to another Computer? + -*A*: Install the app in the other computer and overwrite the empty data file it creates with the file that contains the data of your previous Address Book folder. +[TIP] +The grade field is optional. You can state your grade when you add in modules and +also can update or add in your grade later. + +**** +* You can only add in modules which are valid modules that can be taken in NUS. +* All other module codes inputted will be considered as invalid and the program will not allow you to add in. +* This requirement is not case sensitive, which means for example, both "CS2103" and "cs2103" are considered valid module code. +**** + +[TIP] +The program checks whether a module code provided is valid or not by using the search function in module planning feature, which fetch information about +modules online. If the search function fails to fetch any information, the module code will be treated as invalid. + +- Example: +* `moduleAdd m/CS2103` +* `moduleAdd m/cs1101s g/A` + +.Adding a module +image::AddModule.png[width="790"] + +==== Deleting a module : `moduleDel` + +- Deletes a module you have added to the program before from the profile tab. + +- Format: `moduleDel MODULE_CODE` + +**** +* Deletes the module specified from the module book (profile) +* You can only delete the module which you have added into the program before. +* Module code inputted is not case sensitive ('moduleDel cs2103' is the same as 'moduleDel CS2103') +**** + +- Example: +* `moduleDel CS2103` + +Delete CS2103 from module book if you have added it before. + +.Deleting a module +image::DeleteModule.png[width="790"] + + +==== Editing the grade of a module : `grade` + +- Updates or adds the grade of certain modules you have added to the program. + +- Format: `grade m/MODULE_CODE g/GRADE` + +**** +* Updates the grade of the specified module as the grade you provided now. +* You can only update the grade of module which you have added into the program before. +* Grade inputted should be a valid grade in NUS's grading system. +* Both module code and grade inputted is not case sensitive. +**** + +[TIP] +List of all valid grade: A+, A, A-, B+, B, B-, C+, C, D+, D, F, S and U. + +- Example: +* `grade m/CS1101S g/S` +* `grade m/CS2103 g/A` + +.Updating the grade of a module +image::Grade.png[width="790"] + +==== View current CAP : `cap` + +- Shows your current cap based on the grades of modules you have stated. + +- Format: `cap` + +**** +* Calculates your current CAP. +* CAP = Sum (module grade point x modular credits for the module) / Sum (modular credits) +* The calculation strictly follow the grading system of NUS. +* Shows current CAP in in result display panel, CAP on UI will only get updated after you restart. +**** + +[TIP] +You don't need to indicate the modular credits for each module when you add it in because the program will fetch that infomation online. + +.View current CAP +image::Cap.png[width="790"] +// end::ProfilePart1[] + +// tag::ProfilePart2[] +=== Profile / Module Book (Part 2: Manage your tasks separately for each module) (Wangkai) + +Most of the functionality here has been integrate into the Calendar feature but these commands left here still can be used. +You can give it a try if you want. + +[NOTE] +These tasks related to certain module are called 'module task' from now on. + +[TIP] +All commands that make changes to the module tasks will be synchronous for both module book and the task list in calendar feature. + +[IMPORTANT] +For this part, the UI hasn't been implemented yet but you are able to see the updated list of module tasks in command line. + +[IMPORTANT] +Most functionality covered in this part can also be achieved by some commands in Calendar feature above. Just provides users +with an alternative way. (The orders of tasks shown are different. Thus, the index inputted may be different to achieve the same modification.) + + + +==== Listing all module tasks of certain module + +[TIP] +You can also view module tasks in calendar using `findModule m/MODULE_CODE` + +- Lists all module tasks related to the specific module. + +- Format: `listModuleTasks MODULE_CODE` + +**** +* Lists all module tasks related to that module in *in result display panel*. +* Module code inputted must be valid module code you have added in before. +**** + +- Example: +* `listModuleTasks CS2103` + +Lists all module tasks of CS2103. + +.Showing all module tasks related to specified module +image::ListModuleTask.png[width="790"] + +==== Deleting a module task : `taskDelete` + +- Deletes the specified module tasks for certain module from the module book and calendar. + +- Format: `taskDelete m/MODULE_CODE index/INDEX` + +[NOTE] +This command is similar to the `taskDelete` command in Calendar feature but you need to specify the module code. + +**** +* Deletes the module task at the specified INDEX. +* The index refers to the index number *shown in result display panel* (you can get that by entering 'listModuleTasks MODULE_CODE') +* The index must be a positive integer 1, 2, 3, … +**** + +[CAUTION] +Only refer to the index of tasks shown in command line when performing this command. (not the one in calendar) + +- Example: +* `taskDelete m/CS2103 index/1` + +Deletes the first module task for CS2103 in module book and Calendar. + +*(First task in module book and may not be the first in Calendar even after performing `findTask m/cs2103`)* + +.Deleting a module task +image::TaskDeleteWirhModuleCode.png[width="790"] + +==== Marking a module task as done : `done` + +- Marks the specified module tasks for certain module as done in the module book and calendar. + +- Format: `done m/MODULE_CODE index/Index` + +[NOTE] +This command is similar to the `done` command in Calendar feature but you need to specify the module code. + +**** +* Deletes the module task at the specified INDEX. +* The index refers to the index number *shown in the in result display panel* (you can get that by entering 'listModuleTasks MODULE_CODE') +* The index must be a positive integer 1, 2, 3, … +**** + +[CAUTION] +Only refer to the index of tasks shown in result display panel when performing this command. (not the one in calendar) + +- Example: +* `done m/cs2103 index/1` + +Marks the first module task for module cs2103 as done. + +.Marking a module task as done +image::DoneWithModuleCode.png[width="790"] + +[IMPORTANT] +*Clarification for `taskDelete` and `done` commands.* + +If you did not provide specific module code in the command, the index required refers to the index of list of tasks shown in calendar tab. Otherwise, +it refers to the index of list of module tasks shown in the result display panel. + +*For example:* + +`taskDelete m/cs2103 index/1` will delete the first task as shown in Figure 26 + +`taskDelete index/1` will delete the first task shown in the task list in calendar tab. + +==== View task breakdown per module : `taskBreakdown` + +- Shows the how many tasks are there in total and how many tasks haven't been completed yet for each module. + +- Format: `taskBreakdown` + +.Show task breakdown +image::TaskBreakDown.png[width="790"] + +==== States major taken : `major` (coming in v2.0) +// end::ProfilePart2[] + +=== Module planning + +==== View module requirement: `modreq` (coming in v2.0) + +- Shows the modules requirement for the major specified. This function will show the core modules that the individual have to take before graduation but have not taken yet. + +- Format: `modreq MAJOR` + +- Example: + +* `modreq computer science` + + +==== Module information: `search` + +- Shows basic information about the module, such as time of lecture, tutorial, exam venues and +professor’s contact associated with the module. + +- Format: `search MODULE_CODE` + +- Example: + +* `search CS2103T` + + +=== Diary + +- The diary feature is just like a real life diary book. It allows you jot down any thoughts, be it for your personal life or for school work. You can also note down a concept you don't understand or your reflection for each day in case you want to revisit them in the future. +The diary supports adding and deleting a diary entry, display a particular diary entry and tag each entry with your mood or the weather on that day. + +.Main Screen for diary tab +image::diaryMainScreen.png[width="790"] + + +[NOTE] +The UI for diary is not fully implemented yet. (coming in v2.0) You can just refer to the message section for response when using the diary feature and ignore the GUI for now as it may not function properly. + +==== Adding an diary entry: `diaryAdd` +- Adds a diary entry to the diary book. +- Format: `diaryAdd ec/ENTRY_CONTENT` + +[TIP] +The date of the diary will be automatically recorded according to the date you jot down the diary. + +- Example: `diaryAdd ec/I had a weird dream today.` + +.Adding a diary entry +image::DiaryAdd.png[width="790"] + +==== Viewing diary logs: `diaryLog` +- Shows all diary entries with IDs and relevant information like date, weather and mood. +- Format: `diaryLog` + +[TIP] +Anything thing that comes after the `diaryLog` command will be ignored. + +- Example: `diaryLog` + +.Showing diary logs +image::DiaryLog.png[width="790"] + +==== Deleting an diary entry: `diaryDelete` +- Deletes the specified diary ID’s entry. +- Format: `diaryDelete id/ENTRY_ID` + +[CAUTION] +The ENTRY_ID entered must be a integer and in the range of all available ENTRY_IDs as shown by the result of `diaryLog`. + +- Example: `diaryDelete id/1` + +.Deleting a diary entry with ID 1 +image::DiaryDelete.png[width="790"] + +==== Viewing diary entries with a specified entry ID: `diaryShow` +- Shows the diary entry for the specified entry ID. +- Format: `diaryShow id/ENTRY_ID` + +[CAUTION] +The ENTRY_ID entered must be a integer and in the range of all available ENTRY_IDs as shown by the result of `diaryLog`. + +- Example: `diaryShow id/1` + +.Showing a diary entry with ID 1 +image::DiaryShowID.png[width="790"] + + +==== Viewing list of diary entries with a specified date: `diaryShow` +- Shows the entry IDs of the diary entries that match the given date. +- Format: `diaryShow date/DATE` + +[NOTE] +DATE needs to be in the format of DD-MM-YYYY. + +[TIP] +With the list of IDs, you can then view a specific diary entry with the `diaryShow id/ENTRY_ID` command. + +- Example: `diaryShow date/13-04-2020` + +.Showing the list of entry IDs with date April 13, 2020 +image::DiaryShowDate.png[width="790"] + +==== Tagging a diary entry with weather: `diaryWeather` +- Tags the diary with the specific ID with a specific weather (e.g. sunny, cloudy) +- Format: `diaryWeather id/ENTRY_ID w/WEATHER` + +[NOTE] +The application supports four different kinds of weathers. They are "cloudy", "rainy", "sunny", "windy". +[CAUTION] +The `diaryWeather` command argument is case sensitive, all weathers should be in lower case. + +- Example: `diaryWeather id/1 w/sunny` + +.Recording weather for a particular diary entry +image::DiaryWeather.png[width="790"] + +==== Tagging a diary entry with mood: `diaryMood` +- Tags the diary with the specific ID with a specific mood (e.g. happy, stressed) +- Format: `diaryMood id/ENTRY_ID m/MOOD` + +[NOTE] +The application supports four different kinds of moods. They are "calm, "happy", "sad", "stressed". +[CAUTION] +The `diaryMood` command argument is case sensitive, all moods should be in lower case. + +- Example: `diaryMood id/1 m/calm` + +.Recording your mood for a particular diary entry +image::DiaryMood.png[width="790"] + +==== Filtering diary entries according to mood or weather: `diaryFilter` (coming in v2.0) +- Shows the entry IDs of the diary entries that match the given mood or weather. +- Format: `diaryFilter m/MOOD` or `diaryFilter w/WEATHER` + +- Example: +* `diaryFilter m/happy` +* `diaryFilter w/sunny` == Command Summary -* *Add* `add n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]...` + -e.g. `add n/James Ho p/22224444 e/jamesho@example.com a/123, Clementi Rd, 1234665 t/friend t/colleague` -* *Clear* : `clear` -* *Delete* : `delete INDEX` + -e.g. `delete 3` -* *Edit* : `edit INDEX [n/NAME] [p/PHONE_NUMBER] [e/EMAIL] [a/ADDRESS] [t/TAG]...` + -e.g. `edit 2 n/James Lee e/jameslee@example.com` -* *Find* : `find KEYWORD [MORE_KEYWORDS]` + -e.g. `find James Jake` -* *List* : `list` -* *Help* : `help` +This section summarizes the list of commands. + +* *General*: +** *calendar*: `calendar` +** *notes*: `notes` +** *modplan*: `modplan` +** *diary*: `diary` +** *profile*: `profile` +** *help*: `help` +** *exit*: `exit` + +* *Calendar*: +** *deadline* : `deadlineAdd desc/DESCRIPTION by/DD-MM-YYYY cat/CATEGORY` +e.g. `deadlineAdd desc/Do Chores by/30-04-2020 cat/Misc` +** *moduleTask*: `moduleTask desc/DESCRIPTION m/MODULE CODE date/DD-MM-YYYY pri/PRIORITY` +e.g. `moduleTask desc/Project Deadline date/30-04-2020 m/CS2103T pri/5` +** *done*: `done index/INDEX` +e.g. `done index/1` +** *taskDelete*: `taskDelete index/INDEX` +e.g. `taskDelete index/1` +** *sortTask*: `sortTask by/SORTING_PARAM` +e.g. `sortTask by/priority` +** *findTask*: `findTask m/MODULECODE` or `findTask cat/CATEGORY` or `findTask date/DD-MM-YYYY` +e.g. `findTask m/CS2103T` +** *listTask*: `listTask` +e.g. `listTask` + + +* *Notes* +** *notesList* loc/PATH pt/PATH TYPE +e.g. `notesList loc/Desktop pt/abs` +** *notesOpen* loc/PATH name/FILE_NAME pt/PATH_TYPE +e.g. `notesOpen loc/Desktop name/test.doc pt/abs` +** *notesCreate* loc/PATH name/FILE_NAME type/TYPE pt/PATH_TYPE +e.g. `notesCreate loc/Desktop/ name/Test.doc type/file pt/abs` +** *notesDelete* loc/PATH name/FILE_NAME pt/PATH_TYPE +e.g. `notesDelete loc/Desktop/ name/Test.doc pt/abs` + + + + +* Address Book: +** add n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]… + + e.g. `add n/James Ho p/22224444 e/jamesho@example.com t/friend t/colleague` +** clear : clear +** delete : delete INDEX + + e.g. `delete 3` +** edit : edit INDEX [n/NAME] [p/PHONE_NUMBER] [e/EMAIL] [t/TAG]… + + e.g. `edit 2 n/James Lee e/jameslee@example.com` +** find : find KEYWORD [MORE_KEYWORDS] + + e.g. `find James Jake` +** list: list + +* *Profile* (Module Book) +** moduleAdd m/MODULE_CODE [g/GRADE] + + e.g. `moduleAdd m/cs2103 g/A` +** moduleDel*MODULE_CODE + + e.g. `moduleDel CS2103` +** grade m/MODULE_CODE g/GRADE + + e.g. `grade m/cs2103 g/A` +** cap +** moduleTask desc/DESCRIPTION m/MODULE CODE date/DD-MM-YYYY pri/PRIORITY + + e.g. `moduleTask desc/Project m/CS2103T date/30-04-2020 pri/5` +** taskDelete m/MODULE_CODE index/INDEX + e.g. `taskDelete m/cs2103 index/1` +** done m/MODULE_CODE index/INDEX + e.g. `done m/cs2103 index/1` +** listModuleTasks m/MODULE_CODE + e.g. `listModuleTasks m/CS2103` +** taskBreakdown + +* *Diary* : +** diaryAdd ec/ENTRY_CONTENT + +e.g. `diaryAdd ec/I had a weird dream today.` +** diaryLog + +e.g. `diaryLog` +** diaryDelete id/ENTRY_ID + +e.g. `diaryDelete id/1` +** diaryShow id/ENTRY_ID or diaryShow date/DATE + +e.g. `diaryShow date/13-04-2020` +** diaryWeather id/ENTRY_ID w/WEATHER` + +e.g. `diaryWeather id/1 w/sunny` +** diaryMood id/ENTRY_ID m/MOOD + +e.g. `diaryMood id/1 m/calm` +** diaryFilter m/MOOD or diaryFilter w/WEATHER (coming in v2.0) + +e.g. `diaryFilter m/happy` + + + + +* Mod Plan: +** search MODULE_CODE + + e.g. `search CS2103T` +** mymodplan: mymodplan (coming in v2.0) +** mymodplan add MODULE CODE +e.g. `mymodplan add CS2103T` (coming in v2.0) +** mymodplan done MODULE CODE +e.g. `mymodplan done CS2103T` (coming in v2.0) +** modreq : modreq {\MAJOR} + (coming in v2.0) +e.g. `modreq computer science` + +== Glossary +- *NUS* : National University of Singapore + +- *CAP* : The Cumulative Average Point is the weighted average grade point of the letter grades of all the modules taken by the students, according to NUS's grading system. + +- *CLI* : Command Line Interface + + +== FAQ +*Q*: How do I transfer my data to another Computer? + +*A*: Install the app in the other computer and overwrite the empty data file it creates with the file that contains the data of your previous fitness log book folder. + +*Q*: How do I save my data in my own PC? + +*A*: NusProductivity saves your data of all your modules, grades and tasks after you make changes. + +*Q*: Do I need Internet connection when using NUSProductivity? + +*A*: Although we try to keep NUSProductivity as an offline application, some minimal network connection is required for the first time usage of certain features such as `moduleAdd` and `search`. However, only the first time searching for a module information is required as the results will be cached in our application to allow no Internet connection for future usage. diff --git a/docs/WireFrame.pdf b/docs/WireFrame.pdf new file mode 100644 index 00000000000..52619bd2ce9 Binary files /dev/null and b/docs/WireFrame.pdf differ diff --git a/docs/diagrams/DoneCommandActivityDiagram.puml b/docs/diagrams/DoneCommandActivityDiagram.puml new file mode 100644 index 00000000000..542d888c178 --- /dev/null +++ b/docs/diagrams/DoneCommandActivityDiagram.puml @@ -0,0 +1,23 @@ +@startuml + +start +:User executes done command; +:Done command parser parses input; +if () then ([module code specified by user]) + if () then ([module code and index inputted are valid]) + :Mark the specified task in module task list as done; + :Show the updated list of tasks + for this module on result display; + :Update on calendar; + else ([else]) + endif +else ([else]) + if () then ([index inputted is valid]) + :Mark the specified task on calendar as done; + :Update display of calendar; + :Update module book when needed; + else ([else]) + endif +endif +stop +@enduml diff --git a/docs/diagrams/ListModuleTasksActivityDiagram.puml b/docs/diagrams/ListModuleTasksActivityDiagram.puml new file mode 100644 index 00000000000..2f1477aa23b --- /dev/null +++ b/docs/diagrams/ListModuleTasksActivityDiagram.puml @@ -0,0 +1,10 @@ +@startuml +start +:User executes listModuleTasks command; + +if () then ([module code inputted is valid]) + :Show the list of tasks on result display; +else ([else]) +endif +stop +@enduml diff --git a/docs/diagrams/ModelClassDiagram.puml b/docs/diagrams/ModelClassDiagram.puml index e85a00d4107..a4761f9b8b7 100644 --- a/docs/diagrams/ModelClassDiagram.puml +++ b/docs/diagrams/ModelClassDiagram.puml @@ -24,6 +24,27 @@ Class Phone Class UniquePersonList } +Package NusModule { +Class Capulator +Class ModuleBook +Class ModuleCode +Class NusModule +enum Grade { + APLUS + A + AMINUS + BPLUS + B + BMINUS + CPLUS + C + DPLUS + F + S + U + } +} + Package Tag { Class Tag } @@ -37,6 +58,7 @@ AddressBook .up.|> ReadOnlyAddressBook ModelManager .up.|> Model Model .right.> ObservableList ModelManager o--> "1" AddressBook +ModelManager o--> "1" ModuleBook ModelManager o-left-> "1" UserPrefs UserPrefs .up.|> ReadOnlyUserPrefs @@ -52,5 +74,10 @@ Name -[hidden]right-> Phone Phone -[hidden]right-> Address Address -[hidden]right-> Email +ModuleBook *--> "*" NusModule +NusModule *--> "1" Grade +NusModule *--> "1" ModuleCode +ModuleCode -[hidden]right-> Grade + ModelManager -->"1" Person : filtered list @enduml diff --git a/docs/diagrams/ModuleAddSequenceDiagram.puml b/docs/diagrams/ModuleAddSequenceDiagram.puml new file mode 100644 index 00000000000..dbe673ee27f --- /dev/null +++ b/docs/diagrams/ModuleAddSequenceDiagram.puml @@ -0,0 +1,104 @@ +@startuml +!include style.puml + +box Logic LOGIC_COLOR_T1 +participant ":LogicManager" as LogicManager LOGIC_COLOR +participant ":AddressBookParser" as AddressBookParser LOGIC_COLOR +participant ":AddModuleCommandParser" as AddModuleCommandParser LOGIC_COLOR +participant "a:AddModuleCommand" as AddModuleCommand LOGIC_COLOR +end box + +box Model MODEL_COLOR_T1 +participant ":ModuleCode" as ModuleCode <> MODEL_COLOR +participant ":Search" as Search <> MODEL_COLOR +participant ":Model" as Model MODEL_COLOR +participant ":ModuleBook" as ModelBook MODEL_COLOR +end box + +box Storage STORAGE_COLOR_T1 +participant ":StorageManager" as StorageManager STORAGE_COLOR + +[-> LogicManager : execute("moduleAdd m/CS2103") +activate LogicManager + +LogicManager -> AddressBookParser : parseCommand(moduleAdd) +activate AddressBookParser + +create AddModuleCommandParser +AddressBookParser -> AddModuleCommandParser +activate AddModuleCommandParser + +AddModuleCommandParser --> AddressBookParser +deactivate AddModuleCommandParser + +AddressBookParser --> AddModuleCommandParser : parse(m/CS2103) +activate AddModuleCommandParser + +AddModuleCommandParser --> ModuleCode : isValidModuleCode(CS2103) +activate ModuleCode + +ModuleCode --> Search : findModule(CS2103) +activate Search + +Search --> ModuleCode : true +deactivate Search + +ModuleCode --> AddModuleCommandParser : true +deactivate ModuleCode + +create AddModuleCommand +AddModuleCommandParser --> AddModuleCommand +activate AddModuleCommand + +AddModuleCommand --> AddModuleCommandParser : a +deactivate AddModuleCommand + +AddModuleCommandParser --> AddressBookParser : a +deactivate AddModuleCommandParser + +AddModuleCommandParser -[hidden]-> AddressBookParser +destroy AddModuleCommandParser + +AddressBookParser --> LogicManager : a +deactivate AddressBookParser + +LogicManager -> AddModuleCommand : execute() +activate AddModuleCommand + +AddModuleCommand -> Model : hasModule() +activate Model + +Model -> ModelBook : hasModule() +activate ModelBook + +ModelBook -> Model +deactivate ModelBook + +Model --> AddModuleCommand +deactivate Model + +AddModuleCommand -> Model : addModule() +activate Model + +Model -> ModelBook : addModule() +activate ModelBook + +ModelBook -> Model +deactivate ModelBook + +Model --> AddModuleCommand +deactivate Model + +AddModuleCommand --> LogicManager : result +deactivate AddModuleCommand +AddModuleCommand -[hidden]-> LogicManager : result + +LogicManager --> StorageManager : saveModuleBook() +activate StorageManager + +StorageManager --> LogicManager +deactivate StorageManager + +[<--LogicManager +deactivate LogicManager +@enduml diff --git a/docs/diagrams/NusModuleClassDiagram.puml b/docs/diagrams/NusModuleClassDiagram.puml new file mode 100644 index 00000000000..68416314b79 --- /dev/null +++ b/docs/diagrams/NusModuleClassDiagram.puml @@ -0,0 +1,64 @@ +@startuml +skinparam classAttributeIconSize 0 +hide circle + +Class ModuleBook { + - modules: List + + addModule(:NusModule) + + getModule(:ModuleCode) : NusModule + + gradeModule(:ModuleCode, :Grade) + + addModuleTask(:ModuleTask) +} +Package NusModule { + Class NusModule { + - tasks: List + } + Class ModuleCode { + {static} isValidModuleCode() : boolean + } + enum Grade <> { + APLUS + A + AMINUS + BPLUS + B + BMINUS + CPLUS + C + DPLUS + F + S + U + } + enum Priority <> { + VERYHIGH + HIGH + MEDIAN + LOW + VERYLOW + } + Class Capulator { + - modules: List + + calculateCap() : double + } + + Class ModuleTask { + - timing: String + - priority: Priority + + getPriority() : Priority + + getDate() : String + } +} + + +ModuleBook "1" *-left-> "*" NusModule :manages > +NusModule *--> "0..1" Grade +NusModule "1" *--> "1" ModuleCode +NusModule "1" *--> "*" ModuleTask +ModuleTask *-- "1" Priority +Capulator o--> "*" NusModule +ModuleBook ..> Grade +ModuleBook ..> ModuleCode +ModuleBook ..> ModuleTask + +@enduml diff --git a/docs/diagrams/PartOfModelClassDiagramForProfile.puml b/docs/diagrams/PartOfModelClassDiagramForProfile.puml new file mode 100644 index 00000000000..b50497a9366 --- /dev/null +++ b/docs/diagrams/PartOfModelClassDiagramForProfile.puml @@ -0,0 +1,20 @@ +@startuml +!include style.puml +skinparam arrowThickness 1.1 +skinparam arrowColor MODEL_COLOR +skinparam classBackgroundColor MODEL_COLOR + +Package Model <> { +Interface Model <> +Class ModelManager +Class ModuleBook +Class Task +} + +Class HiddenOutside #FFFFFF +HiddenOutside ..> Model +ModelManager .up.|> Model +ModelManager o--> "1" ModuleBook +ModelManager ..> Task + +@enduml diff --git a/docs/images/AddEventSequenceDiagram.png b/docs/images/AddEventSequenceDiagram.png new file mode 100644 index 00000000000..6787b0dbc5f Binary files /dev/null and b/docs/images/AddEventSequenceDiagram.png differ diff --git a/docs/images/AddModule.png b/docs/images/AddModule.png new file mode 100644 index 00000000000..bf96361910f Binary files /dev/null and b/docs/images/AddModule.png differ diff --git a/docs/images/AddTaskSequenceDiagram.png b/docs/images/AddTaskSequenceDiagram.png new file mode 100644 index 00000000000..044c823aaec Binary files /dev/null and b/docs/images/AddTaskSequenceDiagram.png differ diff --git a/docs/images/ArchitectureSequenceDiagram.png b/docs/images/ArchitectureSequenceDiagram.png index aa198138f8f..0610ab635d9 100644 Binary files a/docs/images/ArchitectureSequenceDiagram.png and b/docs/images/ArchitectureSequenceDiagram.png differ diff --git a/docs/images/CalendarActivityDiagram.png b/docs/images/CalendarActivityDiagram.png new file mode 100644 index 00000000000..ab1035de03e Binary files /dev/null and b/docs/images/CalendarActivityDiagram.png differ diff --git a/docs/images/CalenderUIClassDiagram.png b/docs/images/CalenderUIClassDiagram.png new file mode 100644 index 00000000000..a2028a580cd Binary files /dev/null and b/docs/images/CalenderUIClassDiagram.png differ diff --git a/docs/images/Cap.png b/docs/images/Cap.png new file mode 100644 index 00000000000..b312fd6b58b Binary files /dev/null and b/docs/images/Cap.png differ diff --git a/docs/images/DeleteModule.png b/docs/images/DeleteModule.png new file mode 100644 index 00000000000..799c443e831 Binary files /dev/null and b/docs/images/DeleteModule.png differ diff --git a/docs/images/DiaryAdd.png b/docs/images/DiaryAdd.png new file mode 100644 index 00000000000..c8405972705 Binary files /dev/null and b/docs/images/DiaryAdd.png differ diff --git a/docs/images/DiaryClass.png b/docs/images/DiaryClass.png new file mode 100644 index 00000000000..502976e73ff Binary files /dev/null and b/docs/images/DiaryClass.png differ diff --git a/docs/images/DiaryDelete.png b/docs/images/DiaryDelete.png new file mode 100644 index 00000000000..2b21694b5e0 Binary files /dev/null and b/docs/images/DiaryDelete.png differ diff --git a/docs/images/DiaryLog.png b/docs/images/DiaryLog.png new file mode 100644 index 00000000000..80fcbfddbc9 Binary files /dev/null and b/docs/images/DiaryLog.png differ diff --git a/docs/images/DiaryMood.png b/docs/images/DiaryMood.png new file mode 100644 index 00000000000..aeec3ac9760 Binary files /dev/null and b/docs/images/DiaryMood.png differ diff --git a/docs/images/DiarySequence.png b/docs/images/DiarySequence.png new file mode 100644 index 00000000000..141ba27b319 Binary files /dev/null and b/docs/images/DiarySequence.png differ diff --git a/docs/images/DiaryShowDate.png b/docs/images/DiaryShowDate.png new file mode 100644 index 00000000000..2b7e77de828 Binary files /dev/null and b/docs/images/DiaryShowDate.png differ diff --git a/docs/images/DiaryShowID.png b/docs/images/DiaryShowID.png new file mode 100644 index 00000000000..83253d37afb Binary files /dev/null and b/docs/images/DiaryShowID.png differ diff --git a/docs/images/DiaryWeather.png b/docs/images/DiaryWeather.png new file mode 100644 index 00000000000..7078f4b0eee Binary files /dev/null and b/docs/images/DiaryWeather.png differ diff --git a/docs/images/DoneCommandActivityDiagram.png b/docs/images/DoneCommandActivityDiagram.png new file mode 100644 index 00000000000..da85edcb240 Binary files /dev/null and b/docs/images/DoneCommandActivityDiagram.png differ diff --git a/docs/images/DoneWithModuleCode.png b/docs/images/DoneWithModuleCode.png new file mode 100644 index 00000000000..664ac3c6044 Binary files /dev/null and b/docs/images/DoneWithModuleCode.png differ diff --git a/docs/images/EventActivityDiagram.png b/docs/images/EventActivityDiagram.png new file mode 100644 index 00000000000..1d5dbfff32d Binary files /dev/null and b/docs/images/EventActivityDiagram.png differ diff --git a/docs/images/Grade.png b/docs/images/Grade.png new file mode 100644 index 00000000000..53b0bedf5c1 Binary files /dev/null and b/docs/images/Grade.png differ diff --git a/docs/images/ListEventActivityDiagram.png b/docs/images/ListEventActivityDiagram.png new file mode 100644 index 00000000000..4c2ac038c60 Binary files /dev/null and b/docs/images/ListEventActivityDiagram.png differ diff --git a/docs/images/ListModuleTask.png b/docs/images/ListModuleTask.png new file mode 100644 index 00000000000..567334712b6 Binary files /dev/null and b/docs/images/ListModuleTask.png differ diff --git a/docs/images/ListModuleTasksActivityDiagram.png b/docs/images/ListModuleTasksActivityDiagram.png new file mode 100644 index 00000000000..93186f7dedb Binary files /dev/null and b/docs/images/ListModuleTasksActivityDiagram.png differ diff --git a/docs/images/ModelClassDiagram.png b/docs/images/ModelClassDiagram.png index 280064118cf..cafd4997a86 100644 Binary files a/docs/images/ModelClassDiagram.png and b/docs/images/ModelClassDiagram.png differ diff --git a/docs/images/ModuleAddSequenceDiagram.png b/docs/images/ModuleAddSequenceDiagram.png new file mode 100644 index 00000000000..a1ff85fb011 Binary files /dev/null and b/docs/images/ModuleAddSequenceDiagram.png differ diff --git a/docs/images/ModuleTaskCalendar.png b/docs/images/ModuleTaskCalendar.png new file mode 100644 index 00000000000..ff10518b796 Binary files /dev/null and b/docs/images/ModuleTaskCalendar.png differ diff --git a/docs/images/ModuleTaskProfile.png b/docs/images/ModuleTaskProfile.png new file mode 100644 index 00000000000..923239290be Binary files /dev/null and b/docs/images/ModuleTaskProfile.png differ diff --git a/docs/images/NotesCreation.png b/docs/images/NotesCreation.png new file mode 100644 index 00000000000..67e7eb57d84 Binary files /dev/null and b/docs/images/NotesCreation.png differ diff --git a/docs/images/NotesList.png b/docs/images/NotesList.png new file mode 100644 index 00000000000..6bfa38bc729 Binary files /dev/null and b/docs/images/NotesList.png differ diff --git a/docs/images/NusModuleClassDiagram.png b/docs/images/NusModuleClassDiagram.png new file mode 100644 index 00000000000..fa0a96abf41 Binary files /dev/null and b/docs/images/NusModuleClassDiagram.png differ diff --git a/docs/images/PartOfModelClassDiagramForProfile.png b/docs/images/PartOfModelClassDiagramForProfile.png new file mode 100644 index 00000000000..051c03981c0 Binary files /dev/null and b/docs/images/PartOfModelClassDiagramForProfile.png differ diff --git a/docs/images/ProfileMainScreen.png b/docs/images/ProfileMainScreen.png new file mode 100644 index 00000000000..39e333174c4 Binary files /dev/null and b/docs/images/ProfileMainScreen.png differ diff --git a/docs/images/SearchCommandUMLDiagram.png b/docs/images/SearchCommandUMLDiagram.png new file mode 100644 index 00000000000..bb7f328dfbb Binary files /dev/null and b/docs/images/SearchCommandUMLDiagram.png differ diff --git a/docs/images/SearchUMLDiagram.png b/docs/images/SearchUMLDiagram.png new file mode 100644 index 00000000000..fc3d9ee1d1a Binary files /dev/null and b/docs/images/SearchUMLDiagram.png differ diff --git a/docs/images/StartupDescription.png b/docs/images/StartupDescription.png new file mode 100644 index 00000000000..f9e3e3b0bbd Binary files /dev/null and b/docs/images/StartupDescription.png differ diff --git a/docs/images/TaskBreakDown.png b/docs/images/TaskBreakDown.png new file mode 100644 index 00000000000..24ca8fd5dc1 Binary files /dev/null and b/docs/images/TaskBreakDown.png differ diff --git a/docs/images/TaskDeleteWirhModuleCode.png b/docs/images/TaskDeleteWirhModuleCode.png new file mode 100644 index 00000000000..ab6221d77c8 Binary files /dev/null and b/docs/images/TaskDeleteWirhModuleCode.png differ diff --git a/docs/images/Ui.png b/docs/images/Ui.png index 5bd77847aa2..19f6b149b83 100644 Binary files a/docs/images/Ui.png and b/docs/images/Ui.png differ diff --git a/docs/images/UiClassDiagram.png b/docs/images/UiClassDiagram.png index 7b4b3dbea45..7ba512c419f 100644 Binary files a/docs/images/UiClassDiagram.png and b/docs/images/UiClassDiagram.png differ diff --git a/docs/images/absVSrel.png b/docs/images/absVSrel.png new file mode 100644 index 00000000000..cb9a49bfea4 Binary files /dev/null and b/docs/images/absVSrel.png differ diff --git a/docs/images/damithc.jpg b/docs/images/damithc.jpg deleted file mode 100644 index 12754388389..00000000000 Binary files a/docs/images/damithc.jpg and /dev/null differ diff --git a/docs/images/deadlineAdd.png b/docs/images/deadlineAdd.png new file mode 100644 index 00000000000..b3a89bc2542 Binary files /dev/null and b/docs/images/deadlineAdd.png differ diff --git a/docs/images/diaryMainScreen.png b/docs/images/diaryMainScreen.png new file mode 100644 index 00000000000..890ee3948f0 Binary files /dev/null and b/docs/images/diaryMainScreen.png differ diff --git a/docs/images/findTask.png b/docs/images/findTask.png new file mode 100644 index 00000000000..b6d15b5229d Binary files /dev/null and b/docs/images/findTask.png differ diff --git a/docs/images/iconfinder_photo_370076.png b/docs/images/iconfinder_photo_370076.png new file mode 100644 index 00000000000..60705810fb6 Binary files /dev/null and b/docs/images/iconfinder_photo_370076.png differ diff --git a/docs/images/kangwkk.png b/docs/images/kangwkk.png new file mode 100644 index 00000000000..7cfd16fbe82 Binary files /dev/null and b/docs/images/kangwkk.png differ diff --git a/docs/images/lejolly.jpg b/docs/images/lejolly.jpg deleted file mode 100644 index 2d1d94e0cf5..00000000000 Binary files a/docs/images/lejolly.jpg and /dev/null differ diff --git a/docs/images/listTask.png b/docs/images/listTask.png new file mode 100644 index 00000000000..a14a1f07564 Binary files /dev/null and b/docs/images/listTask.png differ diff --git a/docs/images/m133225.jpg b/docs/images/m133225.jpg deleted file mode 100644 index fd14fb94593..00000000000 Binary files a/docs/images/m133225.jpg and /dev/null differ diff --git a/docs/images/moduleTaskAdd.png b/docs/images/moduleTaskAdd.png new file mode 100644 index 00000000000..ef1e14256cc Binary files /dev/null and b/docs/images/moduleTaskAdd.png differ diff --git a/docs/images/moduleTaskAddError.png b/docs/images/moduleTaskAddError.png new file mode 100644 index 00000000000..67eb638139c Binary files /dev/null and b/docs/images/moduleTaskAddError.png differ diff --git a/docs/images/mpang45456.png b/docs/images/mpang45456.png new file mode 100644 index 00000000000..197c7a7e2ba Binary files /dev/null and b/docs/images/mpang45456.png differ diff --git a/docs/images/notesCreateUG.png b/docs/images/notesCreateUG.png new file mode 100644 index 00000000000..167f28b6fda Binary files /dev/null and b/docs/images/notesCreateUG.png differ diff --git a/docs/images/notesDeleteUG.png b/docs/images/notesDeleteUG.png new file mode 100644 index 00000000000..940239306e0 Binary files /dev/null and b/docs/images/notesDeleteUG.png differ diff --git a/docs/images/notesListingUG.png b/docs/images/notesListingUG.png new file mode 100644 index 00000000000..830a177aa93 Binary files /dev/null and b/docs/images/notesListingUG.png differ diff --git a/docs/images/notesOpenSequenceDiagram.png b/docs/images/notesOpenSequenceDiagram.png new file mode 100644 index 00000000000..ab3597f3d65 Binary files /dev/null and b/docs/images/notesOpenSequenceDiagram.png differ diff --git a/docs/images/notesOpenUG.png b/docs/images/notesOpenUG.png new file mode 100644 index 00000000000..cc91d736378 Binary files /dev/null and b/docs/images/notesOpenUG.png differ diff --git a/docs/images/pathing.png b/docs/images/pathing.png new file mode 100644 index 00000000000..dceb6cd1ce4 Binary files /dev/null and b/docs/images/pathing.png differ diff --git a/docs/images/plantuml/Screenshot 2020-04-10 at 4.24.37 PM.png b/docs/images/plantuml/Screenshot 2020-04-10 at 4.24.37 PM.png new file mode 100644 index 00000000000..fed23b37b28 Binary files /dev/null and b/docs/images/plantuml/Screenshot 2020-04-10 at 4.24.37 PM.png differ diff --git a/docs/images/prioritylevels.png b/docs/images/prioritylevels.png new file mode 100644 index 00000000000..89a58de02eb Binary files /dev/null and b/docs/images/prioritylevels.png differ diff --git a/docs/images/switching_tabs.png b/docs/images/switching_tabs.png new file mode 100644 index 00000000000..ab2e1f795df Binary files /dev/null and b/docs/images/switching_tabs.png differ diff --git a/docs/images/taskDelete.png b/docs/images/taskDelete.png new file mode 100644 index 00000000000..606fe7a2ad8 Binary files /dev/null and b/docs/images/taskDelete.png differ diff --git a/docs/images/taskDone.png b/docs/images/taskDone.png new file mode 100644 index 00000000000..0cd47179d19 Binary files /dev/null and b/docs/images/taskDone.png differ diff --git a/docs/images/taskSort.png b/docs/images/taskSort.png new file mode 100644 index 00000000000..df35097f94c Binary files /dev/null and b/docs/images/taskSort.png differ diff --git a/docs/images/tracing/Screenshot 2020-04-10 at 3.03.49 PM.png b/docs/images/tracing/Screenshot 2020-04-10 at 3.03.49 PM.png new file mode 100644 index 00000000000..ad37dc26885 Binary files /dev/null and b/docs/images/tracing/Screenshot 2020-04-10 at 3.03.49 PM.png differ diff --git a/docs/images/watsheldon.png b/docs/images/watsheldon.png new file mode 100644 index 00000000000..98a89190f43 Binary files /dev/null and b/docs/images/watsheldon.png differ diff --git a/docs/images/xuanxinng.png b/docs/images/xuanxinng.png new file mode 100644 index 00000000000..b4053a30b8f Binary files /dev/null and b/docs/images/xuanxinng.png differ diff --git a/docs/images/yijinl.jpg b/docs/images/yijinl.jpg deleted file mode 100644 index adbf62ad940..00000000000 Binary files a/docs/images/yijinl.jpg and /dev/null differ diff --git a/docs/images/yl_coder.jpg b/docs/images/yl_coder.jpg deleted file mode 100644 index 17b48a73227..00000000000 Binary files a/docs/images/yl_coder.jpg and /dev/null differ diff --git a/docs/images/zhouxinwei97.png b/docs/images/zhouxinwei97.png new file mode 100644 index 00000000000..6fedf9a9d40 Binary files /dev/null and b/docs/images/zhouxinwei97.png differ diff --git a/docs/team/MaxPang.adoc b/docs/team/MaxPang.adoc new file mode 100644 index 00000000000..2555c0df34f --- /dev/null +++ b/docs/team/MaxPang.adoc @@ -0,0 +1,37 @@ += Max Pang - Project Portjolio + +== Project: NUSProductivity + +--- + +== Overview + +NUSProductivity is a desktop application for NUS students. The user interacts with it using a CLI, and it has a GUI creasted with JavaFX. +The application is intended to help NUS students solve their productivity issues and ease student's daily task in NUS. + +== Summary of contributions + +* *Major Enchancement*: Added all classes and functions in `searcher` package. +** What it does: `searcher` package contains support for all module related tasks in the project. +** Justification: Makes it easier for team to handle all module related functions in their own code. +** Highlights: This enchancement forms the backbone of all module related tasks in each function, such as moduleTask in calender, or getting grades for cap calculator. +** Credits: NUSMods API, for all module related information. + +* *Major Enchancement 2*: Module search function. +** What it does: `search` command returns a module object parsed from the JSON object requested with NUSmods's API and caches it. +** Justification: Parsing the information from NUSmods into a format we can more easily used has saved us alot of trouble with coding. Plus caching results means we are less reliant on internet in the long run. +** Highlights: The module object returned is used in many other parts of the project, such as calender and cap calculator. +** Credits: NUSmods API, for all module related information. + +* *Minor contributions*: Wireframed the entire UI Design + +* *Code contributed*: [https://nus-cs2103-ay1920s2.github.io/tp-dashboard/#search=mpang45456&sort=groupTitle&sortWithin=title&since=2020-02-14&timeframe=commit&mergegroup=false&groupSelect=groupByRepos&breakdown=false[All my Code]] + +* *Other Contributions*: + +** Documentation: +*** Tweaks to existing Developers Guide +** Reviewing/mentoring contribution: +*** Gave feedbacks and reviewed on code pull requests +** Community: +*** Reported bugs and suggestions for other teams in the class (examples: https://github.com/mpang45456/ped/issues/1[1]) diff --git a/docs/team/NgXuanXin.adoc b/docs/team/NgXuanXin.adoc new file mode 100644 index 00000000000..6991d68bfb6 --- /dev/null +++ b/docs/team/NgXuanXin.adoc @@ -0,0 +1,43 @@ += Ng Xuan Xin - Project Portfolio +:site-section: AboutUs +:imagesDir: ../images +:stylesDir: ../stylesheets + +== PROJECT: NUSProductivity + +--- + +== Overview + +NUSProductivity is a desktop application for NUS students. The user interacts with it using a CLI, and it has a GUI creasted with JavaFX. The application is intended to help NUS students solve their productivity issues and ease student’s daily task in NUS. + +== Summary of contributions + +* *Major enhancement 1*: assisted with Deadline scheduling +** What it does: allows the user to schedule, delete, filter deadlines, and even mark them as done +** Justification: This feature forms the backbone of the calendar and allows the product to fit the target scope of increasing productivity for NUS students (users). By scheduling deadlines, users can effectively manage their schoolwork in a more organized manner. +** Highlights: As said above, the feature is a major enhancement to the calendar UI. + +* *Major enhancement 2* (Proposed): add commands and functions for Events [https://github.com/AY1920S2-CS2103T-W16-4/main/pull/204/files?file-filters%5B%5D=.java#diff-79323191b012a60de2bc047468653627[Proposed Code]] +** What it does: allows the user to add, delete, and mark events that are scheduled on the calendar as done +** Justification: Since the product is deisgned to be user-friendly for NUS students, this feature allows users to schedule school-wide events they do not want to miss, which is a huge enhancement alongside implementations for scheduling deadlines (complementary features). +** Highlights: This enhancement is complementary with the deadline scheduling feature, and further supports the calendar component. The iplementation was challenging as components had to be linked together and a slight overlook would crash the program. + +* *Minor contributions*: +** Checkstyle fixing + +* *Code contributed*: [https://nus-cs2103-ay1920s2.github.io/tp-dashboard/#search=xuanxinng&sort=groupTitle&sortWithin=title&since=2020-0214&timeframe=commit&mergegroup=false&groupSelect=groupByRepos&breakdown=false&tabOpen=true&tabType=authorship&tabAuthor=xuanxinng&tabRepo=AY1920S2-CS2103T-W16-4%2Fmain%5Bmaster%5D[Functional code]] [https://github.com/AY1920S2-CS2103T-W16-4/main/pull/204/files?file-filters%5B%5D=.java#diff-79323191b012a60de2bc047468653627[Proposed Code]] + +* *Other contributions*: + +** Documentation: +*** Did cosmetic tweaks to existing contents of the User Guide +*** Created additional user stories and use cases for the Developer Guide +*** Updated product scope and non functional requirements as well + +** Reviewing/mentoring contribution +*** Reviewed pull requests with non-trivial comments at least twice (for other teams in the class) + +** Community: +*** Reported at least twelve bugs and suggestions for other teams in the class (example: [https://github.com/xuanxinng/ped/issues/1[#1]]) + diff --git a/docs/team/kangwkk.adoc b/docs/team/kangwkk.adoc new file mode 100644 index 00000000000..171dbb6dc8b --- /dev/null +++ b/docs/team/kangwkk.adoc @@ -0,0 +1,74 @@ += Kang Wangkai - Project Portfolio +:site-section: AboutUs +:imagesDir: ../images +:stylesDir: ../stylesheets + +== PROJECT: NUSProductivity + +--- + +== Overview + +NUSProductivity is a desktop application for NUS students. The user interacts with it using a CLI, and it has a GUI creasted with JavaFX. The application is intended to help NUS students solve their productivity issues and ease student's daily task in NUS. + +== Summary of contributions + +* *Major enhancement 1*: Module Book feature +** What it does: Allows users to be able to manage the modules they have taken or are taking in NUS. (contain functionality to +add module, delete module, update grades and calculate CAP based on NUS grading system) +** Justification: This feature improves the product significantly because a user can track what modules they have taken and what grades they have gotten. Moreover, it allows users to get their CAP immediately and can change grade to +see how the CAP will change accordingly to see room for improvements. +** Highlights: This enhancement makes it very convenient for users to store their modules and getting the cap. It required an in-depth analysis of design alternatives. The implementation too was challenging as some of the functionality relies on other feature of this product (module search feature) +so I need to be familiar with that feature's implementation first. + +* *Major enhancement 2*: Add in functionality to manage module tasks +** What it does: This feature allow users to create, delete, mark as done and list all tasks related to any module users have added using the previous feature. +** Justification: This feature improves the product significantly because a user will be able to manage their tasks for each module separately and it basically avoid users be overwhelmed with lots of tasks from different modules. +** Highlights: This enhancement requires a comprehensive understanding to the original product because it needs to add in codes for logic, model and storage part of the program. + +* *Major enhancement 3*: Add in storage for modules and their tasks and synchronize the module tasks updated to the calendar feature. +** What it does: This feature allow users to store modules and module tasks they added in before and the module tasks created will be allow updated in the whole task list in Calendar feature. +** Justification: This feature improves the product significantly because users do not need to input everything every time they relaunch and makes the module task feature and calendar feature live together. +** Highlights: The implementation was very challenging because it depends on other feature which I need to get familiar with and need to change original code to fit to calendar feature after discussing with teammates which actually differs with my original idea. + +* *Minor enhancement 1*: Add some commands and its parsers to Calendar feature +** What it does: Adds in command skeletons such as sorting and finding tasks commands and their parsers, which let the user be able to sort and find tasks in Calendar. + +* *Code contributed*: https://nus-cs2103-ay1920s2.github.io/tp-dashboard/#search=kangwkk&sort=groupTitle&sortWithin=title&since=2020-02-14&timeframe=commit&mergegroup=false&groupSelect=groupByRepos&breakdown=false[tp dashboard] +* *Other contributions*: + +** Project management: +*** Setting up team organization and team repository +*** Enable Travis CI for the team repo. +*** Set up auto-publishing of docs for the team repo. +*** Open up issues for user stories and manage milestones. + +** Documentation: +*** Added contents for user guide: https://github.com/AY1920S2-CS2103T-W16-4/main/pull/12[#12], https://github.com/AY1920S2-CS2103T-W16-4/main/pull/199[#199], https://github.com/AY1920S2-CS2103T-W16-4/main/pull/203[#203] +*** Added contents for developer guide: https://github.com/AY1920S2-CS2103T-W16-4/main/pull/41[#41], https://github.com/AY1920S2-CS2103T-W16-4/main/pull/205[#205], https://github.com/AY1920S2-CS2103T-W16-4/main/pull/205[#208] + +** Reviewing/mentoring contribution: +*** Gave feedbacks and reviewed on code pull requests https://github.com/AY1920S2-CS2103T-W16-4/main/pull/45[#45], https://github.com/AY1920S2-CS2103T-W16-4/main/pull/185[#185] +** Community: +*** Reported bugs and suggestions for other teams in the class (examples: https://github.com/nus-cs2103-AY1920S2/addressbook-level3/pull/30[#30]) + +== Contributions to the User Guide + + +|=== +|_Given below are sections I contributed to the User Guide. They showcase my ability to write documentation targeting end-users._ +|=== + +include::../UserGuide.adoc[tag=ProfilePart1] + +include::../UserGuide.adoc[tag=ProfilePart2] + + +== Contributions to the Developer Guide + +|=== +|_Given below are sections I contributed to the Developer Guide. They showcase my ability to write technical documentation and the technical depth of my contributions to the project._ +|=== + +include::../DeveloperGuide.adoc[tag=ModuleBook] + diff --git a/docs/team/watsheldon.adoc b/docs/team/watsheldon.adoc new file mode 100644 index 00000000000..dda67ede76c --- /dev/null +++ b/docs/team/watsheldon.adoc @@ -0,0 +1,64 @@ += Chen Jiangwei - Project Portfolio +:site-section: AboutUs +:imagesDir: ../images +:stylesDir: ../stylesheets + +== PROJECT: NUSProductivity + +--- + +== Overview + +NUSProductivity is a desktop application for NUS students. The user interacts with it using a CLI, and it has a GUI creasted with JavaFX. The application is intended to help NUS students solve their productivity issues and ease student's daily task in NUS. + +== Summary of contributions + +* *Major enhancement 1*: Add diary package +** What it does: Models a real life diary book and abstracts all relevant traits of a diary into classes. +** Justification: The abstraction makes it easier for the team to work with diary-related functionalities such as implementing the GUI for diary tab. It also facilitates future enhancement such as incorporating calendar with diary. +** Highlights: This package lays the cornerstone for all diary features. It is the foundation for diary commands such as `diaryAdd` and `diaryWeather`. + +* *Major enhancement 2*: Implement diary features +** What it does: Allows users to manage their diary entries. Functionalities includes adding and deleting a diary entry, recording weather or mood for a entry, displaying a diary entry, finding all entries with a specified date. +** Justification: This feature facilitates users' everyday life by keeping a record of what happened in their lives. It offers something for users to reflect upon in the future. Furthermore, finding entries with a specified date provides users the opportunity to relive certain joyful moments. +** Highlights: This enhancement makes it easier for users to keep a diary in a command line interface (CLI). It requires a comprehensive understanding of the original application's logic as it makes use of the MVC model in the original implementation. Integrating all the features into the application is challenging as other aspects of the application also need to be considered. + +* *Minor enhancement 1*: Remove address attribute from the original address book. +** What it does: The person in our application does not have an address field. +** Justification: The address field in not necessary as we are targeting the NUS students and only contact number, email and related modules are relevant information. + +* *Code contributed*: https://nus-cs2103-ay1920s2.github.io/tp-dashboard/#search=&sort=groupTitle&sortWithin=title&since=2020-02-14&timeframe=commit&mergegroup=false&groupSelect=groupByRepos&breakdown=false&tabOpen=true&tabType=authorship&tabAuthor=watsheldon&tabRepo=AY1920S2-CS2103T-W16-4%2Fmain%5Bmaster%5D[Functional Code] +* *Other contributions*: + + +** Project management: +*** Created issues and assigning to relevant teammates. + +** Documentation: +*** Added contents for user guide: https://github.com/AY1920S2-CS2103T-W16-4/main/pull/210[#210] +*** Added contents for developer guide: https://github.com/AY1920S2-CS2103T-W16-4/main/pull/210[#210] +*** Fixed user guide format: https://github.com/AY1920S2-CS2103T-W16-4/main/commit/0bce7f9091d637d1f64c11448543718b831ac90a[fix format] + +** Reviewing/mentoring contribution: +*** Reivewed and gave feedback for pull requests: https://github.com/AY1920S2-CS2103T-W16-4/main/pull/172[#172] +** Community: +*** Reported bugs and reviewed developer guide for other teams in the class. + +== Contributions to the User Guide + + +|=== +|_Given below are sections I contributed to the User Guide. They showcase my ability to write documentation targeting end-users._ +|=== + +include::../UserGuide.adoc[tag=Diary] + + +== Contributions to the Developer Guide + +|=== +|_Given below are sections I contributed to the Developer Guide. They showcase my ability to write technical documentation and the technical depth of my contributions to the project._ +|=== + +include::../DeveloperGuide.adoc[tag=Diary] + diff --git a/docs/team/zhouxinwei97.adoc b/docs/team/zhouxinwei97.adoc new file mode 100644 index 00000000000..d022eaba092 --- /dev/null +++ b/docs/team/zhouxinwei97.adoc @@ -0,0 +1,72 @@ += Zhou Xinwei - Project Portfolio +:site-section: AboutUs +:imagesDir: ../images +:stylesDir: ../stylesheets + +== PROJECT: NUSProductivity + +--- + +== Overview + +NUSProductivity is a desktop application for NUS students. The user interacts with it using a CLI, and it has a GUI creasted with JavaFX. The application is intended to help NUS students solve their productivity issues and ease student's daily task in NUS. + +== Summary of contributions + +* *Major enhancement*: Added all UI functionality to the system +** What it does: Allows all commands entered to display on the User interface +** Justification: This feature improves the product significantly because a user will be able to see all changes made to the user display. +** Highlights: This enhancement affects existing commands and commands to be added in future. It required an in-depth analysis of design alternatives. The implementation too was challenging as it required changes to existing commands. + +* *Major enhancement 2*: Notes Feature +** What it does: This feature allow users to create, open, delete and list all files in a directory that the user specified +** Justification: This feature improves the product significantly because a user will be able to access their desktop through the use of the app to create documents. +** Highlights: This enhancement requires it to be compatible with any operating system, mainly Windows, Mac and Linux. The implementation with the pathing was one of the harder one to grasp especially with different pathing system used by different operating system. + +* *Major enhancement 3*: Calendar Feature +** What it does: This feature allow users to track deadlines and tasks related to modules. It allows user to see what tasks is due on a day, what task is currently ongoing/done and the ability to find task and sort task in the User Interface. +** Justification: This feature improves the product significantly because a user will be able to write down different task that needs to be completed by a certain date. +** Highlights: This enhancement affects existing commands, particularly the storage functions. It required an in-depth analysis of design alternatives. The implementation was challenging as well since I had to modify various aspect of the storage system. + + +* *Minor enhancement*: Added all functionality to the user interface. + +* *Code contributed*: [https://nus-cs2103-ay1920s2.github.io/tp-dashboard/#search=zhouxinwei97&sort=groupTitle&sortWithin=title&since=2020-02-14&timeframe=commit&mergegroup=false&groupSelect=groupByRepos&breakdown=false[Functional code]] +* *Other contributions*: + +** Project management: +*** Managed releases `v1.1` - `v1.4` (4 releases) on GitHub +** Documentation: +*** Did cosmetic tweaks to existing contents of the User Guide: https://github.com[#14] +** Reviewing/mentoring contribution: +*** Gave feedbacks and reviewed on code pull requests https://github.com/AY1920S2-CS2103T-W16-4/main/pull/86[#86], https://github.com/AY1920S2-CS2103T-W16-4/main/pull/73[#73] +** Community: +*** Reported bugs and suggestions for other teams in the class (examples: https://github.com/nus-cs2103-AY1920S2/addressbook-level3/pull/30/files/27956787443359559bd0e052afc52dd38c6dee7a[#30]) +** Tools: +*** Integrated AppVeyor to the project for CI (https://github.com/AY1920S2-CS2103T-W16-4/main/pull/10[#10]) +*** Integrated Travis to the project for CI (https://github.com/AY1920S2-CS2103T-W16-4/main/pull/3[#3]) +*** Integrated Coderalls to the project for CI (https://github.com/AY1920S2-CS2103T-W16-4/main/pull/10[#10]) + + +== Contributions to the User Guide + + +|=== +|_Given below are sections I contributed to the User Guide. They showcase my ability to write documentation targeting end-users._ +|=== + +include::../UserGuide.adoc[tag=Calendar] + +include::../UserGuide.adoc[tag=Notes] + + +== Contributions to the Developer Guide + +|=== +|_Given below are sections I contributed to the Developer Guide. They showcase my ability to write technical documentation and the technical depth of my contributions to the project._ +|=== + +include::../DeveloperGuide.adoc[tag=UIDiagram] + +include::../DeveloperGuide.adoc[tag=Xinwei] + diff --git a/docs/team/zhouxinwei97UML.adoc b/docs/team/zhouxinwei97UML.adoc new file mode 100644 index 00000000000..70a8e3b51f1 --- /dev/null +++ b/docs/team/zhouxinwei97UML.adoc @@ -0,0 +1,32 @@ += Zhou Xinwei - Project Portfolio +:site-section: AboutUs +:imagesDir: ../images +:stylesDir: ../stylesheets + + +.Component interactions for `moduleAdd m/CS2103T` command +image::../images/ArchitectureSequenceDiagram.png[width="500"] + +Shows how the components interact for each of the commands implemented in NUSProductivity + +.Structure of the UI Component +image::../images/UiClassDiagram.png[width="500"] + +Shows the UI component of NUSProductivity + +.Calender UI Class Diagram +image::../images/CalenderUIClassDiagram.png[width="500"] + +Shows the class diagram and relationship between the different UI. + +.Add task sequence diagram +image::../images/AddTaskSequenceDiagram.png[width="500"] + +Shows how a deadlineAdd interacts with the different components in the program. + +.Calendar Activity Diagram +image::../images/CalendarActivityDiagram.png[width="500"] + +Shows the activity diagram of all calendar feature commands and how it interacts with the UI. + + diff --git a/docs/tutorials/AddRemark.adoc b/docs/tutorials/AddRemark.adoc index ea388068303..46d11a10ada 100644 --- a/docs/tutorials/AddRemark.adoc +++ b/docs/tutorials/AddRemark.adoc @@ -160,6 +160,7 @@ Your code should look something like link:https://github.com/nus-cs2103-AY1920S1 Now let's move on to writing a parser that will extract the index and remark from the input provided by the user. +======= Create a `RemarkCommandParser` class in the `seedu.address.logic.parser` package. The class must implement the `Parser` interface. @@ -219,23 +220,6 @@ Now that we have the know-how to extract the data that we need from the user's i [source, java] .RemarkCommandParser.java ---- -public RemarkCommand parse(String args) throws ParseException { - requireNonNull(args); - ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args, - PREFIX_REMARK); - - Index index; - try { - index = ParserUtil.parseIndex(argMultimap.getPreamble()); - } catch (IllegalValueException ive) { - throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, - RemarkCommand.MESSAGE_USAGE), ive); - } - - String remark = argMultimap.getValue(PREFIX_REMARK).orElse(""); - - return new RemarkCommand(index, remark); -} ---- NOTE: Don't forget to update `AddressBookParser` to use our new `RemarkCommandParser`! diff --git a/src/main/java/seedu/address/Main.java b/src/main/java/seedu/address/Main.java index 052a5068631..08f7453dcad 100644 --- a/src/main/java/seedu/address/Main.java +++ b/src/main/java/seedu/address/Main.java @@ -22,4 +22,5 @@ public class Main { public static void main(String[] args) { Application.launch(MainApp.class, args); } + //testing travis, delete later } diff --git a/src/main/java/seedu/address/MainApp.java b/src/main/java/seedu/address/MainApp.java index e5cfb161b73..21db44bfae6 100644 --- a/src/main/java/seedu/address/MainApp.java +++ b/src/main/java/seedu/address/MainApp.java @@ -2,10 +2,13 @@ import java.io.IOException; import java.nio.file.Path; +import java.util.ArrayList; import java.util.Optional; import java.util.logging.Logger; import javafx.application.Application; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; import javafx.stage.Stage; import seedu.address.commons.core.Config; import seedu.address.commons.core.LogsCenter; @@ -18,13 +21,19 @@ import seedu.address.model.AddressBook; import seedu.address.model.Model; import seedu.address.model.ModelManager; +import seedu.address.model.ModuleBook; import seedu.address.model.ReadOnlyAddressBook; import seedu.address.model.ReadOnlyUserPrefs; import seedu.address.model.UserPrefs; +import seedu.address.model.calender.Task; import seedu.address.model.util.SampleDataUtil; import seedu.address.storage.AddressBookStorage; +import seedu.address.storage.CalendarBookStorage; import seedu.address.storage.JsonAddressBookStorage; +import seedu.address.storage.JsonCalendarStorage; +import seedu.address.storage.JsonModuleBookStorage; import seedu.address.storage.JsonUserPrefsStorage; +import seedu.address.storage.ModuleBookStorage; import seedu.address.storage.Storage; import seedu.address.storage.StorageManager; import seedu.address.storage.UserPrefsStorage; @@ -56,8 +65,12 @@ public void init() throws Exception { UserPrefsStorage userPrefsStorage = new JsonUserPrefsStorage(config.getUserPrefsFilePath()); UserPrefs userPrefs = initPrefs(userPrefsStorage); - AddressBookStorage addressBookStorage = new JsonAddressBookStorage(userPrefs.getAddressBookFilePath()); - storage = new StorageManager(addressBookStorage, userPrefsStorage); + AddressBookStorage addressBookStorage = new JsonAddressBookStorage(userPrefs.getAddressBookFilePath(), + userPrefs.getCalendarFilePath()); + ModuleBookStorage moduleBookStorage = new JsonModuleBookStorage(userPrefs.getModuleBookFilePath()); + CalendarBookStorage calendarBookStorage = new JsonCalendarStorage(userPrefs.getCalendarFilePath()); + + storage = new StorageManager(addressBookStorage, userPrefsStorage, moduleBookStorage, calendarBookStorage); initLogging(config); @@ -75,22 +88,37 @@ public void init() throws Exception { */ private Model initModelManager(Storage storage, ReadOnlyUserPrefs userPrefs) { Optional addressBookOptional; + Optional moduleBookOptional; + Optional> taskListOptional; ReadOnlyAddressBook initialData; + ModuleBook initialModules; + ObservableList initTask; try { addressBookOptional = storage.readAddressBook(); + moduleBookOptional = storage.readModuleBook(); + taskListOptional = storage.readCalendar(); if (!addressBookOptional.isPresent()) { logger.info("Data file not found. Will be starting with a sample AddressBook"); } + if (!moduleBookOptional.isPresent()) { + logger.info("Data file not found. Will be starting with an empty moduleBook"); + } initialData = addressBookOptional.orElseGet(SampleDataUtil::getSampleAddressBook); + initialModules = moduleBookOptional.orElseGet(ModuleBook::new); + initTask = taskListOptional.orElse(FXCollections.observableList(new ArrayList<>())); } catch (DataConversionException e) { logger.warning("Data file not in the correct format. Will be starting with an empty AddressBook"); initialData = new AddressBook(); + initialModules = new ModuleBook(); + initTask = FXCollections.observableList(new ArrayList<>()); } catch (IOException e) { logger.warning("Problem while reading from the file. Will be starting with an empty AddressBook"); initialData = new AddressBook(); + initialModules = new ModuleBook(); + initTask = FXCollections.observableList(new ArrayList<>()); } - return new ModelManager(initialData, userPrefs); + return new ModelManager(initialData, userPrefs, initialModules, initTask); } private void initLogging(Config config) { @@ -176,6 +204,9 @@ public void stop() { logger.info("============================ [ Stopping Address Book ] ============================="); try { storage.saveUserPrefs(model.getUserPrefs()); + + model.updateDeadlineTaskList(Model.PREDICATE_SHOW_ALL_TASK); + storage.saveCalendar(model.getDeadlineTaskList()); } catch (IOException e) { logger.severe("Failed to save preferences " + StringUtil.getDetails(e)); } diff --git a/src/main/java/seedu/address/commons/core/Messages.java b/src/main/java/seedu/address/commons/core/Messages.java index 1deb3a1e469..83ced0a9fe6 100644 --- a/src/main/java/seedu/address/commons/core/Messages.java +++ b/src/main/java/seedu/address/commons/core/Messages.java @@ -8,6 +8,11 @@ public class Messages { public static final String MESSAGE_UNKNOWN_COMMAND = "Unknown command"; public static final String MESSAGE_INVALID_COMMAND_FORMAT = "Invalid command format! \n%1$s"; public static final String MESSAGE_INVALID_PERSON_DISPLAYED_INDEX = "The person index provided is invalid"; + public static final String MESSAGE_NO_SUCH_MODULE = "Module specified does not exist in the module book!"; + public static final String MESSAGE_INVALID_MODULE_TASK_INDEX = "The module task index provided is invalid"; public static final String MESSAGE_PERSONS_LISTED_OVERVIEW = "%1$d persons listed!"; + public static final String MESSAGE_INVALID_DATE = "Invalid Date format! Please key in Date in DD-MM-YYYY \n%1$s"; + public static final String MESSAGE_INVALID_SORTING_PARAM = "Invalid parameter for sorting! " + + "(sorting parameter can be either 'priority' or 'date')"; } diff --git a/src/main/java/seedu/address/logic/Logic.java b/src/main/java/seedu/address/logic/Logic.java index 92cd8fa605a..802afb148f9 100644 --- a/src/main/java/seedu/address/logic/Logic.java +++ b/src/main/java/seedu/address/logic/Logic.java @@ -2,13 +2,20 @@ import java.nio.file.Path; +import javafx.beans.value.ObservableValue; import javafx.collections.ObservableList; import seedu.address.commons.core.GuiSettings; import seedu.address.logic.commands.CommandResult; import seedu.address.logic.commands.exceptions.CommandException; import seedu.address.logic.parser.exceptions.ParseException; import seedu.address.model.ReadOnlyAddressBook; +import seedu.address.model.calender.Task; +import seedu.address.model.diary.DiaryEntry; +import seedu.address.model.notes.Notes; +import seedu.address.model.nusmodule.NusModule; import seedu.address.model.person.Person; +import seedu.address.model.studentprofile.Profile; + /** * API of the Logic component @@ -38,6 +45,14 @@ public interface Logic { */ Path getAddressBookFilePath(); + /** + * Returns the user prefs' diary book file path. + */ + Path getDiaryBookFilePath(); + + /** Returns an unmodifiable view of list of diaries */ + ObservableList getDiaryList(); + /** * Returns the user prefs' GUI settings. */ @@ -47,4 +62,30 @@ public interface Logic { * Set the user prefs' GUI settings. */ void setGuiSettings(GuiSettings guiSettings); + + //=========== Notes Module ================================================================================== + /** + * Returns an list of String that contains what is currently in the folder + * */ + ObservableList getFilesInFolderList(); + + + //=========== Calender Module ================================================================================== + + /** + * + * Returns a list of deadline Tasks + */ + ObservableList getDeadlineTaskList(); + + + //=========== Profile Module ================================================================================== + ObservableList getModulesListTaken(); + + ObservableValue getMajor(); + + Profile getProfile(); + + Path getModuleBookFilePath(); + } diff --git a/src/main/java/seedu/address/logic/LogicManager.java b/src/main/java/seedu/address/logic/LogicManager.java index d47ce874b1a..8b6e01c4bba 100644 --- a/src/main/java/seedu/address/logic/LogicManager.java +++ b/src/main/java/seedu/address/logic/LogicManager.java @@ -4,6 +4,7 @@ import java.nio.file.Path; import java.util.logging.Logger; +import javafx.beans.value.ObservableValue; import javafx.collections.ObservableList; import seedu.address.commons.core.GuiSettings; import seedu.address.commons.core.LogsCenter; @@ -14,9 +15,16 @@ import seedu.address.logic.parser.exceptions.ParseException; import seedu.address.model.Model; import seedu.address.model.ReadOnlyAddressBook; +import seedu.address.model.calender.Task; +import seedu.address.model.diary.DiaryEntry; +import seedu.address.model.notes.Notes; +import seedu.address.model.nusmodule.NusModule; import seedu.address.model.person.Person; +import seedu.address.model.studentprofile.Profile; import seedu.address.storage.Storage; + + /** * The main LogicManager of the app. */ @@ -44,6 +52,8 @@ public CommandResult execute(String commandText) throws CommandException, ParseE try { storage.saveAddressBook(model.getAddressBook()); + storage.saveModuleBook(model.getModuleBook()); + storage.saveCalendar(model.getDeadlineTaskList()); } catch (IOException ioe) { throw new CommandException(FILE_OPS_ERROR_MESSAGE + ioe, ioe); } @@ -61,11 +71,21 @@ public ObservableList getFilteredPersonList() { return model.getFilteredPersonList(); } + @Override + public ObservableList getDiaryList() { + return model.getDiaryList(); + } + @Override public Path getAddressBookFilePath() { return model.getAddressBookFilePath(); } + @Override + public Path getDiaryBookFilePath() { + return model.getDiaryBookFilePath(); + } + @Override public GuiSettings getGuiSettings() { return model.getGuiSettings(); @@ -75,4 +95,34 @@ public GuiSettings getGuiSettings() { public void setGuiSettings(GuiSettings guiSettings) { model.setGuiSettings(guiSettings); } + + @Override + public ObservableList getFilesInFolderList() { + return model.getFilesInFolderList(); + } + + @Override + public ObservableList getDeadlineTaskList() { + return model.getDeadlineTaskList(); + } + + @Override + public ObservableList getModulesListTaken() { + return model.getModulesListTaken(); + } + + @Override + public ObservableValue getMajor() { + return model.getMajor(); + } + + @Override + public Profile getProfile() { + return model.getProfile(); + } + + @Override + public Path getModuleBookFilePath() { + return model.getModuleBookFilePath(); + } } diff --git a/src/main/java/seedu/address/logic/commands/AddBookCommand.java b/src/main/java/seedu/address/logic/commands/AddBookCommand.java new file mode 100644 index 00000000000..cc7b32f6f9f --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/AddBookCommand.java @@ -0,0 +1,21 @@ +package seedu.address.logic.commands; + +import seedu.address.model.Model; + +/** + * Format full help instructions for every command for display. + */ +public class AddBookCommand extends Command { + + public static final String COMMAND_WORD = "addressbook"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Shows AddBook tab.\n" + + "Example: " + COMMAND_WORD; + + public static final String SWITCHED_MESSAGE = "Switched to AddBook Tab"; + + @Override + public CommandResult execute(Model model) { + return new CommandResult(SWITCHED_MESSAGE, false, false, true); + } +} diff --git a/src/main/java/seedu/address/logic/commands/AddCommand.java b/src/main/java/seedu/address/logic/commands/AddCommand.java index 71656d7c5c8..a6cff3044b6 100644 --- a/src/main/java/seedu/address/logic/commands/AddCommand.java +++ b/src/main/java/seedu/address/logic/commands/AddCommand.java @@ -1,7 +1,6 @@ package seedu.address.logic.commands; import static java.util.Objects.requireNonNull; -import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS; import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL; import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE; @@ -23,13 +22,11 @@ public class AddCommand extends Command { + PREFIX_NAME + "NAME " + PREFIX_PHONE + "PHONE " + PREFIX_EMAIL + "EMAIL " - + PREFIX_ADDRESS + "ADDRESS " + "[" + PREFIX_TAG + "TAG]...\n" + "Example: " + COMMAND_WORD + " " + PREFIX_NAME + "John Doe " + PREFIX_PHONE + "98765432 " + PREFIX_EMAIL + "johnd@example.com " - + PREFIX_ADDRESS + "311, Clementi Ave 2, #02-25 " + PREFIX_TAG + "friends " + PREFIX_TAG + "owesMoney"; diff --git a/src/main/java/seedu/address/logic/commands/CalenderCommand.java b/src/main/java/seedu/address/logic/commands/CalenderCommand.java new file mode 100644 index 00000000000..5c2b6328f76 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/CalenderCommand.java @@ -0,0 +1,21 @@ +package seedu.address.logic.commands; + +import seedu.address.model.Model; + +/** + * Format full help instructions for every command for display. + */ +public class CalenderCommand extends Command { + + public static final String COMMAND_WORD = "calendar"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Shows Calendar tab.\n" + + "Example: " + COMMAND_WORD; + + public static final String SWITCHED_MESSAGE = "Switched to Calendar Tab"; + + @Override + public CommandResult execute(Model model) { + return new CommandResult(SWITCHED_MESSAGE, false, false, true); + } +} diff --git a/src/main/java/seedu/address/logic/commands/CommandResult.java b/src/main/java/seedu/address/logic/commands/CommandResult.java index 92f900b7916..d41ea4f11df 100644 --- a/src/main/java/seedu/address/logic/commands/CommandResult.java +++ b/src/main/java/seedu/address/logic/commands/CommandResult.java @@ -17,13 +17,17 @@ public class CommandResult { /** The application should exit. */ private final boolean exit; + /** The application should switch tab */ + private final boolean switchTab; + /** * Constructs a {@code CommandResult} with the specified fields. */ - public CommandResult(String feedbackToUser, boolean showHelp, boolean exit) { + public CommandResult(String feedbackToUser, boolean showHelp, boolean exit, boolean switchTab) { this.feedbackToUser = requireNonNull(feedbackToUser); this.showHelp = showHelp; this.exit = exit; + this.switchTab = switchTab; } /** @@ -31,7 +35,7 @@ public CommandResult(String feedbackToUser, boolean showHelp, boolean exit) { * and other fields set to their default value. */ public CommandResult(String feedbackToUser) { - this(feedbackToUser, false, false); + this(feedbackToUser, false, false, false); } public String getFeedbackToUser() { @@ -46,6 +50,10 @@ public boolean isExit() { return exit; } + public boolean isSwitchTab() { + return switchTab; + } + @Override public boolean equals(Object other) { if (other == this) { diff --git a/src/main/java/seedu/address/logic/commands/DiaryCommand.java b/src/main/java/seedu/address/logic/commands/DiaryCommand.java new file mode 100644 index 00000000000..27039013d48 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/DiaryCommand.java @@ -0,0 +1,21 @@ +package seedu.address.logic.commands; + +import seedu.address.model.Model; + +/** + * Format full help instructions for every command for display. + */ +public class DiaryCommand extends Command { + + public static final String COMMAND_WORD = "diary"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Shows diary tab.\n" + + "Example: " + COMMAND_WORD; + + public static final String SWITCHED_MESSAGE = "Switched to Diary tab"; + + @Override + public CommandResult execute(Model model) { + return new CommandResult(SWITCHED_MESSAGE, false, false, true); + } +} diff --git a/src/main/java/seedu/address/logic/commands/EditCommand.java b/src/main/java/seedu/address/logic/commands/EditCommand.java index 7e36114902f..8f540f8567a 100644 --- a/src/main/java/seedu/address/logic/commands/EditCommand.java +++ b/src/main/java/seedu/address/logic/commands/EditCommand.java @@ -1,7 +1,6 @@ package seedu.address.logic.commands; import static java.util.Objects.requireNonNull; -import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS; import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL; import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE; @@ -19,13 +18,13 @@ import seedu.address.commons.util.CollectionUtil; import seedu.address.logic.commands.exceptions.CommandException; import seedu.address.model.Model; -import seedu.address.model.person.Address; import seedu.address.model.person.Email; import seedu.address.model.person.Name; import seedu.address.model.person.Person; import seedu.address.model.person.Phone; import seedu.address.model.tag.Tag; + /** * Edits the details of an existing person in the address book. */ @@ -40,7 +39,6 @@ public class EditCommand extends Command { + "[" + PREFIX_NAME + "NAME] " + "[" + PREFIX_PHONE + "PHONE] " + "[" + PREFIX_EMAIL + "EMAIL] " - + "[" + PREFIX_ADDRESS + "ADDRESS] " + "[" + PREFIX_TAG + "TAG]...\n" + "Example: " + COMMAND_WORD + " 1 " + PREFIX_PHONE + "91234567 " @@ -96,10 +94,9 @@ private static Person createEditedPerson(Person personToEdit, EditPersonDescript Name updatedName = editPersonDescriptor.getName().orElse(personToEdit.getName()); Phone updatedPhone = editPersonDescriptor.getPhone().orElse(personToEdit.getPhone()); Email updatedEmail = editPersonDescriptor.getEmail().orElse(personToEdit.getEmail()); - Address updatedAddress = editPersonDescriptor.getAddress().orElse(personToEdit.getAddress()); Set updatedTags = editPersonDescriptor.getTags().orElse(personToEdit.getTags()); - return new Person(updatedName, updatedPhone, updatedEmail, updatedAddress, updatedTags); + return new Person(updatedName, updatedPhone, updatedEmail, updatedTags); } @Override @@ -128,7 +125,6 @@ public static class EditPersonDescriptor { private Name name; private Phone phone; private Email email; - private Address address; private Set tags; public EditPersonDescriptor() {} @@ -141,7 +137,6 @@ public EditPersonDescriptor(EditPersonDescriptor toCopy) { setName(toCopy.name); setPhone(toCopy.phone); setEmail(toCopy.email); - setAddress(toCopy.address); setTags(toCopy.tags); } @@ -149,7 +144,7 @@ public EditPersonDescriptor(EditPersonDescriptor toCopy) { * Returns true if at least one field is edited. */ public boolean isAnyFieldEdited() { - return CollectionUtil.isAnyNonNull(name, phone, email, address, tags); + return CollectionUtil.isAnyNonNull(name, phone, email, tags); } public void setName(Name name) { @@ -176,14 +171,6 @@ public Optional getEmail() { return Optional.ofNullable(email); } - public void setAddress(Address address) { - this.address = address; - } - - public Optional
getAddress() { - return Optional.ofNullable(address); - } - /** * Sets {@code tags} to this object's {@code tags}. * A defensive copy of {@code tags} is used internally. @@ -219,7 +206,6 @@ public boolean equals(Object other) { return getName().equals(e.getName()) && getPhone().equals(e.getPhone()) && getEmail().equals(e.getEmail()) - && getAddress().equals(e.getAddress()) && getTags().equals(e.getTags()); } } diff --git a/src/main/java/seedu/address/logic/commands/ExitCommand.java b/src/main/java/seedu/address/logic/commands/ExitCommand.java index 3dd85a8ba90..acac9a21374 100644 --- a/src/main/java/seedu/address/logic/commands/ExitCommand.java +++ b/src/main/java/seedu/address/logic/commands/ExitCommand.java @@ -13,7 +13,7 @@ public class ExitCommand extends Command { @Override public CommandResult execute(Model model) { - return new CommandResult(MESSAGE_EXIT_ACKNOWLEDGEMENT, false, true); + return new CommandResult(MESSAGE_EXIT_ACKNOWLEDGEMENT, false, true, false); } } diff --git a/src/main/java/seedu/address/logic/commands/HelpCommand.java b/src/main/java/seedu/address/logic/commands/HelpCommand.java index bf824f91bd0..07d26e2a23c 100644 --- a/src/main/java/seedu/address/logic/commands/HelpCommand.java +++ b/src/main/java/seedu/address/logic/commands/HelpCommand.java @@ -16,6 +16,6 @@ public class HelpCommand extends Command { @Override public CommandResult execute(Model model) { - return new CommandResult(SHOWING_HELP_MESSAGE, true, false); + return new CommandResult(SHOWING_HELP_MESSAGE, true, false, false); } } diff --git a/src/main/java/seedu/address/logic/commands/MajorCommand.java b/src/main/java/seedu/address/logic/commands/MajorCommand.java new file mode 100644 index 00000000000..0a88d1dc17e --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/MajorCommand.java @@ -0,0 +1,46 @@ +package seedu.address.logic.commands; + +import static java.util.Objects.requireNonNull; + +import seedu.address.model.Model; +import seedu.address.model.nusmodule.Major; + +/** + * Update the major the user taken in NUS. + */ +public class MajorCommand extends Command { + public static final String COMMAND_WORD = "major"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": State your major (e.g. Computer Science) " + + "for the app to help you with module planning\n" + + "Parameters: your major\n" + + "Example: " + COMMAND_WORD + "Computer Science"; + + public static final String MESSAGE_SUCCESS = "Major updated: "; + + private final Major majorTaken; + + /** + * Creates an AddModuleCommand to add the specified {@code NusModule} + */ + public MajorCommand(Major major) { + requireNonNull(major); + majorTaken = major; + } + + @Override + public CommandResult execute(Model model) { + requireNonNull(model); + + model.updateMajor(majorTaken); + + return new CommandResult(MESSAGE_SUCCESS + majorTaken); + } + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof MajorCommand // instanceof handles nulls + && majorTaken.equals(((MajorCommand) other).majorTaken)); // state check + } +} diff --git a/src/main/java/seedu/address/logic/commands/ModPlanCommand.java b/src/main/java/seedu/address/logic/commands/ModPlanCommand.java new file mode 100644 index 00000000000..751ebf6b852 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/ModPlanCommand.java @@ -0,0 +1,21 @@ +package seedu.address.logic.commands; + +import seedu.address.model.Model; + +/** + * Format full help instructions for every command for display. + */ +public class ModPlanCommand extends Command { + + public static final String COMMAND_WORD = "modplan"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Shows modplan tab.\n" + + "Example: " + COMMAND_WORD; + + public static final String SWITCHED_MESSAGE = "Switched to modplan Tab"; + + @Override + public CommandResult execute(Model model) { + return new CommandResult(SWITCHED_MESSAGE, false, false, true); + } +} diff --git a/src/main/java/seedu/address/logic/commands/NotesCommand.java b/src/main/java/seedu/address/logic/commands/NotesCommand.java new file mode 100644 index 00000000000..907332585f5 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/NotesCommand.java @@ -0,0 +1,21 @@ +package seedu.address.logic.commands; + +import seedu.address.model.Model; + +/** + * Format full help instructions for every command for display. + */ +public class NotesCommand extends Command { + + public static final String COMMAND_WORD = "notes"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Shows notes tab.\n" + + "Example: " + COMMAND_WORD; + + public static final String SWITCHED_MESSAGE = "Switched to notes Tab"; + + @Override + public CommandResult execute(Model model) { + return new CommandResult(SWITCHED_MESSAGE, false, false, true); + } +} diff --git a/src/main/java/seedu/address/logic/commands/NotesCreateCommand.java b/src/main/java/seedu/address/logic/commands/NotesCreateCommand.java new file mode 100644 index 00000000000..611442810ed --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/NotesCreateCommand.java @@ -0,0 +1,160 @@ +package seedu.address.logic.commands; + +import static seedu.address.logic.parser.CliSyntax.PREFIX_NOTES_FILE_NAME; +import static seedu.address.logic.parser.CliSyntax.PREFIX_NOTES_PATH; +import static seedu.address.logic.parser.CliSyntax.PREFIX_NOTES_PATH_TYPE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_NOTES_TYPE; +import static seedu.address.model.Model.PREDICATE_SHOW_ALL_NOTES; + +import java.io.File; +import java.io.IOException; + +import seedu.address.model.Model; +import seedu.address.model.notes.Notes; + + +/** + * NotesCommand is created when a notecommand is parsed, to return what operation to be done. + * implementation is not yet completed + */ +public class NotesCreateCommand extends Command { + + public static final String COMMAND_WORD = "notesCreate"; + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Create new file in specified directory " + + "Parameters: " + + PREFIX_NOTES_PATH + "PATH " + + PREFIX_NOTES_FILE_NAME + "FILE_NAME " + + PREFIX_NOTES_TYPE + "TYPE " + + PREFIX_NOTES_PATH_TYPE + "PATH_TYPE\n" + + "Example: " + COMMAND_WORD + " " + + PREFIX_NOTES_PATH + "Desktop/ " + + PREFIX_NOTES_FILE_NAME + "Test.doc " + + PREFIX_NOTES_TYPE + "file " + + PREFIX_NOTES_PATH_TYPE + "abs "; + + + private static final String MESSAGE_CREATE_SUCCESS = "File is successfully created at "; + private static final String MESSAGE_CREATE_FAIL = "File is unable to be created at "; + private static final String MESSAGE_CREATE_DUPLICATE = "File already exists"; + private static final String MESSAGE_NOTHING_HAPPENED = "Nothing Happened "; + private static final String MESSAGE_MAKEDIR_SUCCESSFUL = "Directory is successfully created "; + private static final String MESSAGE_MAKEDIR_UNSUCCESSFUL = "Directory is unable to be created "; + private static final String MESSAGE_MAKEDIR_DUPLICATE = " already exists"; + + private String path; + private String type; + private String filePath; + private Notes note; + + /** + * Creates a new NotesCommand to Create/Open/Delete a new note. + * + * @param note the operation and location that will be done to the note. + */ + public NotesCreateCommand(Notes note) { + this.note = note; + this.type = note.getType(); + this.path = note.getPath(); + this.filePath = note.getFilePathType(); + } + + /** + * Creates a document at the specified path. + * + * @param path the given path that the created document will reside in. + * @return a CommandResult based on whether the operation succeed or failed. + */ + public CommandResult createDoc(String path) { + String pathName = ""; + if (this.filePath.equals("abs")) { + pathName = Notes.HOME_DIRECTORY + File.separatorChar + path; + } else { + pathName = Notes.getCurrentDirectory() + File.separatorChar + path; + } + buildDirectoryName(pathName); // Build the CurrentDirectory name + File myFile = new File(pathName); + if (myFile.exists() == true) { + return new CommandResult(MESSAGE_CREATE_DUPLICATE); + } + try { + myFile.createNewFile(); + Notes.setList(NotesListCommand.listfilesArray(Notes.getCurrentDirectory())); + return new CommandResult(MESSAGE_CREATE_SUCCESS + pathName); + } catch (IOException ex) { + return new CommandResult(MESSAGE_CREATE_FAIL + pathName); + + } + + } + + /** + * Build the directory name to be shown as current directory. + * @param pathName current path name inputted + */ + public void buildDirectoryName(String pathName) { + + String[] splittedDirectoryName = pathName.split(File.separator); + String newDirectory = ""; + for (int i = 0; i < splittedDirectoryName.length - 1; i++) { + newDirectory += splittedDirectoryName[i] + File.separator; + } + Notes.setCurrentDirectory(newDirectory); + + } + + /** + * Creates a folder at the specified path. + * + * @param path the given path that the created document will reside in. + * @return a CommandResult based on whether the operation succeed or failed. + */ + public CommandResult createFolder(String path) { + String pathName = ""; + if (this.filePath.equals("abs")) { + pathName = Notes.HOME_DIRECTORY + File.separatorChar + path; + } else { + pathName = Notes.getCurrentDirectory() + File.separatorChar + path; + } + File myFile = new File(pathName); + if (myFile.exists()) { + return new CommandResult(pathName + MESSAGE_MAKEDIR_DUPLICATE); + } + Notes.setCurrentDirectory(pathName); + if (myFile.mkdir()) { // return true if directory is created + Notes.setList(NotesListCommand.listfilesArray(Notes.getCurrentDirectory())); + System.out.println("successfully created"); + System.out.println(Notes.getCurrentDirectory()); + return new CommandResult(MESSAGE_MAKEDIR_SUCCESSFUL + pathName); + } else { + return new CommandResult(MESSAGE_MAKEDIR_UNSUCCESSFUL + pathName); + } + + } + + public Notes getNote() { + return this.note; + } + + + @Override + public CommandResult execute(Model model) { + + model.updateNotesList(PREDICATE_SHOW_ALL_NOTES); + + if (this.type.equals("file")) { + return createDoc(this.path); + } else if (this.type.equals("folder")) { + return createFolder(this.path); + } + + return new CommandResult(MESSAGE_NOTHING_HAPPENED); + } + + @Override + public boolean equals(Object other) { + + NotesCreateCommand otherNotesOpen = (NotesCreateCommand) other; + return this.note.equals(otherNotesOpen.getNote()); + + } +} diff --git a/src/main/java/seedu/address/logic/commands/NotesDeleteCommand.java b/src/main/java/seedu/address/logic/commands/NotesDeleteCommand.java new file mode 100644 index 00000000000..fa50c550d36 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/NotesDeleteCommand.java @@ -0,0 +1,121 @@ +package seedu.address.logic.commands; + +import static seedu.address.logic.parser.CliSyntax.PREFIX_NOTES_FILE_NAME; +import static seedu.address.logic.parser.CliSyntax.PREFIX_NOTES_PATH; +import static seedu.address.logic.parser.CliSyntax.PREFIX_NOTES_PATH_TYPE; +import static seedu.address.model.Model.PREDICATE_SHOW_ALL_NOTES; + +import java.io.File; + +import seedu.address.model.Model; +import seedu.address.model.notes.Notes; + + +/** + * NotesCommand is created when a notecommand is parsed, to return what operation to be done. + * implementation is not yet completed + */ +public class NotesDeleteCommand extends Command { + + public static final String COMMAND_WORD = "notesDelete"; + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Delete specified file " + + "Parameters: " + + PREFIX_NOTES_PATH + "PATH " + + PREFIX_NOTES_FILE_NAME + "FILE_NAME " + + PREFIX_NOTES_PATH_TYPE + "PATH_TYPE\n" + + "Example: " + COMMAND_WORD + " " + + PREFIX_NOTES_PATH + "Desktop/ " + + PREFIX_NOTES_FILE_NAME + "Test.doc " + + PREFIX_NOTES_PATH_TYPE + "abs "; + + private static final String MESSAGE_DELETE_SUCESSFUL = " is successfully deleted "; + private static final String MESSAGE_DELETE_UNSUCCESSFUL = " is unable to be deleted "; + private static final String MESSAGE_DELETE_NOT_FOUND = " does not exists"; + private static final String MESSAGE_DELETE_FOLDER = + "You can only delete a file through this method, not a directory"; + + private String path; + private String filePath; + private Notes note; + + /** + * Creates a new NotesCommand to Create/Open/Delete a new note. + * + * @param note the operation and location that will be done to the note. + */ + public NotesDeleteCommand(Notes note) { + this.note = note; + this.path = note.getPath(); + this.filePath = note.getFilePathType(); + } + + /** + * Deletes a document at the specified path. + * + * @param path the given path that the created document will reside in. + * @return a CommandResult based on whether the operation succeed or failed. + */ + public CommandResult deleteDoc(String path) { + String pathName = ""; + if (this.filePath.equals("abs")) { + pathName = Notes.HOME_DIRECTORY + File.separatorChar + path; + } else { + pathName = Notes.getCurrentDirectory() + File.separatorChar + path; + } + buildDirectoryName(pathName); // Build the CurrentDirectory name + File myFile = new File(pathName); + if (!myFile.exists()) { + return new CommandResult(pathName + MESSAGE_DELETE_NOT_FOUND); + } + + if (myFile.isDirectory()) { + return new CommandResult(MESSAGE_DELETE_FOLDER); + } + + String[] fileNames = this.path.split(File.separator); + + if (myFile.delete()) { + Notes.setList(NotesListCommand.listfilesArray(Notes.getCurrentDirectory())); + return new CommandResult(fileNames[fileNames.length - 1] + MESSAGE_DELETE_SUCESSFUL); + } else { + return new CommandResult(fileNames[fileNames.length - 1] + MESSAGE_DELETE_UNSUCCESSFUL); + } + + } + + /** + * Build the directory name to be shown as current directory. + * @param pathName current path name inputted + */ + public void buildDirectoryName(String pathName) { + + String[] splittedDirectoryName = pathName.split(File.separator); + String newDirectory = ""; + for (int i = 0; i < splittedDirectoryName.length - 1; i++) { + newDirectory += splittedDirectoryName[i] + File.separator; + } + Notes.setCurrentDirectory(newDirectory); + + } + + public Notes getNote() { + return this.note; + } + + + @Override + public CommandResult execute(Model model) { + + model.updateNotesList(PREDICATE_SHOW_ALL_NOTES); + + return deleteDoc(this.path); + } + + @Override + public boolean equals(Object other) { + + NotesDeleteCommand otherNotesOpen = (NotesDeleteCommand) other; + return this.note.equals(otherNotesOpen.getNote()); + + } +} diff --git a/src/main/java/seedu/address/logic/commands/NotesListCommand.java b/src/main/java/seedu/address/logic/commands/NotesListCommand.java new file mode 100644 index 00000000000..8df5be5477b --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/NotesListCommand.java @@ -0,0 +1,135 @@ +package seedu.address.logic.commands; + +import static seedu.address.logic.parser.CliSyntax.PREFIX_NOTES_PATH; +import static seedu.address.logic.parser.CliSyntax.PREFIX_NOTES_PATH_TYPE; +import static seedu.address.model.Model.PREDICATE_SHOW_ALL_NOTES; + +import java.io.File; +import java.util.ArrayList; + +import seedu.address.model.Model; +import seedu.address.model.notes.Notes; + + +/** + * NotesCommand is created when a notecommand is parsed, to return what operation to be done. + * implementation is not yet completed + */ +public class NotesListCommand extends Command { + + public static final String COMMAND_WORD = "notesList"; + public static final String MESSAGE_USAGE = COMMAND_WORD + ": List files in specified directory " + + "Parameters: " + + PREFIX_NOTES_PATH + "PATH " + + PREFIX_NOTES_PATH_TYPE + "PATH TYPE \n" + + "Example: " + COMMAND_WORD + " " + + PREFIX_NOTES_PATH + "Desktop " + + PREFIX_NOTES_PATH_TYPE + "abs"; + + private static final String MESSAGE_NOTHING_HAPPENED = "Nothing Happened "; + private static final String MESSAGE_LISTED_DIR = "Listed Directory at "; + private static final String MESSAGE_NOT_DIR = " is not a directory"; + private static final String MESSAGE_NOT_EXIST = " does not exist"; + + + + private String path; + private String filePath; + private Notes note; + + /** + * Creates a new NotesListCommand to list a new note. + * + * @param note the operation and location that will be done to the note. + */ + public NotesListCommand(Notes note) { + + this.note = note; + this.path = note.getPath(); + this.filePath = note.getFilePathType(); + } + + + /** + * Tentative, may remove this function. + * @param path dummy + * @return dummy + */ + public CommandResult listFiles(String path) { + String pathName = ""; + + if (this.filePath.equals("abs")) { + pathName = Notes.HOME_DIRECTORY + File.separatorChar + path; + } else { + pathName = Notes.getCurrentDirectory() + File.separatorChar + path; + } + + File myFile = new File(pathName); + if (myFile.exists() == false) { + return new CommandResult(pathName + MESSAGE_NOT_EXIST); + } + if (myFile.isDirectory() == false) { + return new CommandResult(pathName + MESSAGE_NOT_DIR); + } + ArrayList filesArrayList = new ArrayList<>(); + + File[] allFiles = myFile.listFiles(); + for (File f : allFiles) { + String[] allFileName = f.toString().split(File.separator); + String filename = allFileName[allFileName.length - 1]; + if (filename.charAt(0) == ('.')) { + continue; + } + Notes note = new Notes(filename); + filesArrayList.add(note); + } + Notes.setList(filesArrayList); + Notes.setCurrentDirectory(pathName); + return new CommandResult(MESSAGE_LISTED_DIR + pathName); + } + + /** + * Tentative, to be updated. + * @param path dummy + * @return dummy + */ + public static ArrayList listfilesArray(String path) { + + File myFile = new File(path); + ArrayList filesArrayList = new ArrayList<>(); + + File[] allFiles = myFile.listFiles(); + for (File f : allFiles) { + String[] allFileName = f.toString().split(File.separator); + String filename = allFileName[allFileName.length - 1]; + if (filename.charAt(0) == ('.')) { + continue; + } + Notes note = new Notes(filename); + filesArrayList.add(note); + } + return filesArrayList; + + } + + public Notes getNote() { + return this.note; + } + + + @Override + public CommandResult execute(Model model) { + + model.updateNotesList(PREDICATE_SHOW_ALL_NOTES); + return listFiles(this.path); + + } + + @Override + public boolean equals(Object other) { + + NotesListCommand otherNotesOpen = (NotesListCommand) other; + return this.note.equals(otherNotesOpen.getNote()); + + } +} diff --git a/src/main/java/seedu/address/logic/commands/NotesOpenCommand.java b/src/main/java/seedu/address/logic/commands/NotesOpenCommand.java new file mode 100644 index 00000000000..d41c95819be --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/NotesOpenCommand.java @@ -0,0 +1,124 @@ +package seedu.address.logic.commands; + +import static seedu.address.logic.parser.CliSyntax.PREFIX_NOTES_FILE_NAME; +import static seedu.address.logic.parser.CliSyntax.PREFIX_NOTES_PATH; +import static seedu.address.logic.parser.CliSyntax.PREFIX_NOTES_PATH_TYPE; +import static seedu.address.model.Model.PREDICATE_SHOW_ALL_NOTES; + +import java.awt.Desktop; +import java.io.File; +import java.io.IOException; + +import seedu.address.model.Model; +import seedu.address.model.notes.Notes; + + +/** + * NotesCommand is created when a notecommand is parsed, to return what operation to be done. + * implementation is not yet completed + */ +public class NotesOpenCommand extends Command { + + public static final String COMMAND_WORD = "notesOpen"; + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Opens a file " + + "Parameters: " + + PREFIX_NOTES_PATH + "PATH " + + PREFIX_NOTES_FILE_NAME + "FILE_NAME " + + PREFIX_NOTES_PATH_TYPE + "PATH_TYPE \n" + + "Example: " + COMMAND_WORD + " " + + PREFIX_NOTES_PATH + "Desktop " + + PREFIX_NOTES_FILE_NAME + "test.doc " + + PREFIX_NOTES_PATH_TYPE + "abs "; + + public static final String MESSAGE_OPEN_SUCCESS = "Opened file "; + public static final String MESSAGE_OPEN_FAIL = "Failed to open file "; + public static final String MESSAGE_UNABLE_TO_FIND = "Unable to find file to open "; + + private String path; + private String filePath; + private Notes note; + + /** + * Creates a new NotesOpenCommand to Open a new note. + * + * @param note the operation and location that will be done to the note. + */ + public NotesOpenCommand(Notes note) { + this.note = note; + this.path = note.getPath(); + this.filePath = note.getFilePathType(); + } + + /** + * Opens a document at the specified path. + * + * @param path the given path that the document resides in. + * @return a CommandResult based on whether the operation succeed or failed. + */ + public CommandResult openDoc(String path) { + String pathName = ""; + + if (this.filePath.equals("abs")) { + pathName = Notes.HOME_DIRECTORY + File.separatorChar + path; + } else { + pathName = Notes.getCurrentDirectory() + File.separatorChar + path; + } + + File myFile = new File(pathName); + + + try { + if (Desktop.isDesktopSupported()) { + Desktop.getDesktop().open(myFile); + } + if (!myFile.isDirectory()) { + buildDirectoryName(pathName); + } else { + Notes.setCurrentDirectory(pathName); + } + Notes.setList(NotesListCommand.listfilesArray(Notes.getCurrentDirectory())); + return new CommandResult(MESSAGE_OPEN_SUCCESS); + } catch (IOException ex) { + return new CommandResult(MESSAGE_OPEN_FAIL + this.path); + } catch (IllegalArgumentException ex) { + return new CommandResult(MESSAGE_UNABLE_TO_FIND + this.path); + } + + } + + /** + * Build the directory name to be shown as current directory. + * @param pathName current path name inputted + */ + public void buildDirectoryName(String pathName) { + + String[] splittedDirectoryName = pathName.split(File.separator); + String newDirectory = ""; + for (int i = 0; i < splittedDirectoryName.length - 1; i++) { + newDirectory += splittedDirectoryName[i] + File.separator; + } + Notes.setCurrentDirectory(newDirectory); + + } + + public Notes getNote() { + return this.note; + } + + + @Override + public CommandResult execute(Model model) { + + model.updateNotesList(PREDICATE_SHOW_ALL_NOTES); + return openDoc(this.path); + + } + + @Override + public boolean equals(Object other) { + + NotesOpenCommand otherNotesOpen = (NotesOpenCommand) other; + return this.note.equals(otherNotesOpen.getNote()); + + } +} diff --git a/src/main/java/seedu/address/logic/commands/ProfileCommand.java b/src/main/java/seedu/address/logic/commands/ProfileCommand.java new file mode 100644 index 00000000000..c2a70f9bf9d --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/ProfileCommand.java @@ -0,0 +1,21 @@ +package seedu.address.logic.commands; + +import seedu.address.model.Model; + +/** + * Format full help instructions for every command for display. + */ +public class ProfileCommand extends Command { + + public static final String COMMAND_WORD = "profile"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Shows profile tab.\n" + + "Example: " + COMMAND_WORD; + + public static final String SWITCHED_MESSAGE = "Switched to profile Tab"; + + @Override + public CommandResult execute(Model model) { + return new CommandResult(SWITCHED_MESSAGE, false, false, true); + } +} diff --git a/src/main/java/seedu/address/logic/commands/SearchCommand.java b/src/main/java/seedu/address/logic/commands/SearchCommand.java new file mode 100644 index 00000000000..d5c54416d09 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/SearchCommand.java @@ -0,0 +1,43 @@ +package seedu.address.logic.commands; + +import static java.util.Objects.requireNonNull; + +import seedu.address.model.Model; +import seedu.address.searcher.Module; +import seedu.address.searcher.Search; + +/** + *

Search Command Class

+ * Handler for Search Command + */ +public class SearchCommand extends Command { + + public static final String COMMAND_WORD = "search"; + + public static final String MESSAGE_USAGE = + "Use search to perform a module search. Syntax is search \n" + + "Example: search CS1101S"; + + public static final String SEARCH_FAILURE = "There is no such Module"; + public static final String SYNTAX_FAILURE = "Your command seems to be wrong"; + + private String modToSearch; + + public SearchCommand(String modToSearch) { + this.modToSearch = modToSearch; + } + + @Override + public CommandResult execute(Model model) { + requireNonNull(model); + Module myMod; + + try { + myMod = Search.findModule(modToSearch); + + return new CommandResult(myMod.toString()); + } catch (StringIndexOutOfBoundsException e) { + return new CommandResult(SYNTAX_FAILURE); + } + } +} diff --git a/src/main/java/seedu/address/logic/commands/diarycommand/DiaryAddCommand.java b/src/main/java/seedu/address/logic/commands/diarycommand/DiaryAddCommand.java new file mode 100644 index 00000000000..5a46f6d77d3 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/diarycommand/DiaryAddCommand.java @@ -0,0 +1,48 @@ +package seedu.address.logic.commands.diarycommand; + +import static java.util.Objects.requireNonNull; +import static seedu.address.logic.parser.CliSyntax.PREFIX_ENTRY_CONTENT; + +import seedu.address.logic.commands.Command; +import seedu.address.logic.commands.CommandResult; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; +import seedu.address.model.diary.DiaryEntry; + +/** + * Represents the command that adds a diary entry. + */ +public class DiaryAddCommand extends Command { + + /** + * Dummy java docs. + */ + public static final String COMMAND_WORD = "diaryAdd"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Allows for adding diary entries " + + "Parameters: " + + PREFIX_ENTRY_CONTENT + "ENTRY CONTENT" + + "Example: " + COMMAND_WORD + " " + + PREFIX_ENTRY_CONTENT + "I failed my midterm today :( "; + + public static final String MESSAGE_SUCCESS = "Diary entry added:"; + + private final DiaryEntry diaryEntry; + + public DiaryAddCommand(DiaryEntry diaryEntry) { + requireNonNull(diaryEntry); + this.diaryEntry = diaryEntry; + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + + if (model.isEmptyDiaryEntry(diaryEntry)) { + throw new CommandException("The diary entry is empty!"); + } + + model.addDiaryEntry(diaryEntry); + return new CommandResult(String.format(MESSAGE_SUCCESS + diaryEntry.getHeading())); + } +} diff --git a/src/main/java/seedu/address/logic/commands/diarycommand/DiaryDeleteCommand.java b/src/main/java/seedu/address/logic/commands/diarycommand/DiaryDeleteCommand.java new file mode 100644 index 00000000000..93e29975a29 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/diarycommand/DiaryDeleteCommand.java @@ -0,0 +1,44 @@ +package seedu.address.logic.commands.diarycommand; + +import static java.util.Objects.requireNonNull; +import static seedu.address.logic.parser.CliSyntax.PREFIX_ENTRY_ID; + +import seedu.address.logic.commands.Command; +import seedu.address.logic.commands.CommandResult; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; + +/** + * Represents the command that deletes a diary entry. + */ +public class DiaryDeleteCommand extends Command { + + public static final String COMMAND_WORD = "diaryDelete"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Allows for deleting diary entries " + + "Parameters: " + + PREFIX_ENTRY_ID + "ENTRY ID" + + "Example: " + COMMAND_WORD + " " + + PREFIX_ENTRY_ID + "1"; + + public static final String MESSAGE_SUCCESS = "Diary entry deleted"; + + private final int entryId; + + public DiaryDeleteCommand(int entryId) { + this.entryId = entryId; + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + + if (!model.isValidEntryId(entryId)) { + throw new CommandException("The diary entry ID is not in range!"); + } + + model.deleteDiaryEntry(entryId); + String messageResult = "Diary entry " + entryId + " deleted."; + return new CommandResult(messageResult); + } +} diff --git a/src/main/java/seedu/address/logic/commands/diarycommand/DiaryLogCommand.java b/src/main/java/seedu/address/logic/commands/diarycommand/DiaryLogCommand.java new file mode 100644 index 00000000000..7e4f7140134 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/diarycommand/DiaryLogCommand.java @@ -0,0 +1,25 @@ +package seedu.address.logic.commands.diarycommand; + +import static java.util.Objects.requireNonNull; + +import seedu.address.logic.commands.Command; +import seedu.address.logic.commands.CommandResult; +import seedu.address.model.Model; + +/** + * Represents the command that shows diary log. + */ +public class DiaryLogCommand extends Command { + + public static final String COMMAND_WORD = "diaryLog"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": shows the log of added diary entries"; + + @Override + public CommandResult execute(Model model) { + requireNonNull(model); + + String diaryLogs = model.showDiaryLog(); + return new CommandResult(diaryLogs); + } +} diff --git a/src/main/java/seedu/address/logic/commands/diarycommand/DiaryMoodCommand.java b/src/main/java/seedu/address/logic/commands/diarycommand/DiaryMoodCommand.java new file mode 100644 index 00000000000..54ca37a8d9e --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/diarycommand/DiaryMoodCommand.java @@ -0,0 +1,50 @@ +package seedu.address.logic.commands.diarycommand; + +import static java.util.Objects.requireNonNull; +import static seedu.address.logic.parser.CliSyntax.PREFIX_ENTRY_ID; +import static seedu.address.logic.parser.CliSyntax.PREFIX_MOOD; + +import seedu.address.logic.commands.Command; +import seedu.address.logic.commands.CommandResult; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; +import seedu.address.model.diary.mood.Mood; + +/** + * Represents the command that tags a diary entry with mood. + */ +public class DiaryMoodCommand extends Command { + + public static final String COMMAND_WORD = "diaryMood"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Allows for tagging a diary entry with a specific mood " + + "Parameters: " + + PREFIX_ENTRY_ID + "ENTRY ID" + + PREFIX_MOOD + "WEATHER" + + "Example: " + COMMAND_WORD + " " + + PREFIX_ENTRY_ID + "1" + + PREFIX_MOOD + "stressed"; + + public static final String MESSAGE_SUCCESS = "mood recorded"; + + private final int entryId; + private final Mood mood; + + public DiaryMoodCommand(int entryId, Mood mood) { + this.entryId = entryId; + this.mood = mood; + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + + if (!model.isValidEntryId(entryId)) { + throw new CommandException("The diary entry ID is not in range!"); + } + + model.tagMood(entryId, mood); + String messageResult = "Mood recorded."; + return new CommandResult(messageResult); + } +} diff --git a/src/main/java/seedu/address/logic/commands/diarycommand/DiaryShowCommand.java b/src/main/java/seedu/address/logic/commands/diarycommand/DiaryShowCommand.java new file mode 100644 index 00000000000..6adb34ee375 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/diarycommand/DiaryShowCommand.java @@ -0,0 +1,30 @@ +package seedu.address.logic.commands.diarycommand; + +import static seedu.address.logic.parser.CliSyntax.PREFIX_DIARY_DATE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_ENTRY_ID; + +import seedu.address.logic.commands.Command; +import seedu.address.logic.commands.CommandResult; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; + +/** + * Dummy java docs. + */ +public abstract class DiaryShowCommand extends Command { + public static final String COMMAND_WORD = "diaryShow"; + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Shows a particular diary entry\n" + + COMMAND_WORD + ": Shows a diary entry by specifying the entry ID " + + "Parameters: " + + PREFIX_ENTRY_ID + "ENTRY ID " + + "Example: " + COMMAND_WORD + " " + + PREFIX_ENTRY_ID + "1 " + + "or\n" + + COMMAND_WORD + ": Shows a diary entry by specifying the date " + + "Parameters: " + + PREFIX_DIARY_DATE + " DATE" + + "Example: " + COMMAND_WORD + " " + + PREFIX_DIARY_DATE + " 01-04-2020 "; + + public abstract CommandResult execute(Model model) throws CommandException; +} diff --git a/src/main/java/seedu/address/logic/commands/diarycommand/DiaryShowDateCommand.java b/src/main/java/seedu/address/logic/commands/diarycommand/DiaryShowDateCommand.java new file mode 100644 index 00000000000..b6c4d03fa5f --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/diarycommand/DiaryShowDateCommand.java @@ -0,0 +1,37 @@ +package seedu.address.logic.commands.diarycommand; + +import static java.util.Objects.requireNonNull; + +import java.time.LocalDate; +import java.util.List; + +import seedu.address.logic.commands.CommandResult; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; + +/** + * Dummy java docs. + */ +public class DiaryShowDateCommand extends DiaryShowCommand { + public static final String MESSAGE_SUCCESS = "Entry ids with given date: "; + + private final LocalDate date; + + public DiaryShowDateCommand(LocalDate date) { + this.date = date; + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + + if (!model.isExistingDate(date)) { + throw new CommandException("Cannot find diary entry with the given date!"); + } + + List ids = model.getListOfIdsByDate(date); + + return new CommandResult(MESSAGE_SUCCESS + " " + ids + ". Use diaryShow id/ENTRY_ID " + + "to see a particular entry."); + } +} diff --git a/src/main/java/seedu/address/logic/commands/diarycommand/DiaryShowIdCommand.java b/src/main/java/seedu/address/logic/commands/diarycommand/DiaryShowIdCommand.java new file mode 100644 index 00000000000..2f0f35ea384 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/diarycommand/DiaryShowIdCommand.java @@ -0,0 +1,34 @@ +package seedu.address.logic.commands.diarycommand; + +import static java.util.Objects.requireNonNull; + +import seedu.address.logic.commands.CommandResult; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; +import seedu.address.model.diary.DiaryEntry; + +/** + * Dummy java docs. + */ +public class DiaryShowIdCommand extends DiaryShowCommand { + public static final String MESSAGE_SUCCESS = "Diary entry shown: "; + + private final int entryId; + + public DiaryShowIdCommand(int entryId) { + this.entryId = entryId; + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + + if (!model.isValidEntryId(entryId)) { + throw new CommandException("The diary entry ID is not in range!"); + } + + DiaryEntry entry = model.getDiaryEntryById(entryId); + + return new CommandResult(MESSAGE_SUCCESS + " " + entry); + } +} diff --git a/src/main/java/seedu/address/logic/commands/diarycommand/DiaryWeatherCommand.java b/src/main/java/seedu/address/logic/commands/diarycommand/DiaryWeatherCommand.java new file mode 100644 index 00000000000..e01e7c43d9f --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/diarycommand/DiaryWeatherCommand.java @@ -0,0 +1,51 @@ +package seedu.address.logic.commands.diarycommand; + +import static java.util.Objects.requireNonNull; +import static seedu.address.logic.parser.CliSyntax.PREFIX_ENTRY_ID; +import static seedu.address.logic.parser.CliSyntax.PREFIX_WEATHER; + +import seedu.address.logic.commands.Command; +import seedu.address.logic.commands.CommandResult; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; +import seedu.address.model.diary.weather.Weather; + +/** + * Represents the command that tags a diary entry with weather. + */ +public class DiaryWeatherCommand extends Command { + + public static final String COMMAND_WORD = "diaryWeather"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + + ": Allows for tagging a diary entry with a specific weather " + + "Parameters: " + + PREFIX_ENTRY_ID + "ENTRY ID" + + PREFIX_WEATHER + "WEATHER" + + "Example: " + COMMAND_WORD + " " + + PREFIX_ENTRY_ID + "1" + + PREFIX_WEATHER + "sunny"; + + public static final String MESSAGE_SUCCESS = "weather recorded"; + + private final int entryId; + private final Weather weather; + + public DiaryWeatherCommand(int entryId, Weather weather) { + this.entryId = entryId; + this.weather = weather; + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + + if (!model.isValidEntryId(entryId)) { + throw new CommandException("The diary entry ID is not in range!"); + } + + model.tagWeather(entryId, weather); + String messageResult = "Weather recorded."; + return new CommandResult(messageResult); + } +} diff --git a/src/main/java/seedu/address/logic/commands/modulecommand/AddModuleCommand.java b/src/main/java/seedu/address/logic/commands/modulecommand/AddModuleCommand.java new file mode 100644 index 00000000000..5139fa308b5 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/modulecommand/AddModuleCommand.java @@ -0,0 +1,62 @@ +package seedu.address.logic.commands.modulecommand; + +import static java.util.Objects.requireNonNull; +import static seedu.address.logic.parser.CliSyntax.PREFIX_GRADE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_MODULE_CODE; +import static seedu.address.model.Model.PREDICATE_SHOW_ALL_MODULES_TAKEN; + +import seedu.address.logic.commands.Command; +import seedu.address.logic.commands.CommandResult; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; +import seedu.address.model.nusmodule.NusModule; + +/** + * Adds a module to our application. + */ +public class AddModuleCommand extends Command { + + public static final String COMMAND_WORD = "moduleAdd"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Allows for adding modules " + + "Parameters: " + + PREFIX_MODULE_CODE + "MODULE CODE " + + PREFIX_GRADE + "GRADE [Optional] " + + "Example: " + COMMAND_WORD + " " + + PREFIX_MODULE_CODE + "CS2103T " + + PREFIX_GRADE + "A+ "; + + public static final String MESSAGE_SUCCESS = "Module added: "; + public static final String MESSAGE_DUPLICATE_NUS_MODULE = "module already exist"; + + private final NusModule toAdd; + + /** + * Creates an AddModuleCommand to add the specified {@code NusModule} + */ + public AddModuleCommand(NusModule module) { + requireNonNull(module); + toAdd = module; + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + + if (model.hasModule(toAdd.getModuleCode())) { + throw new CommandException(MESSAGE_DUPLICATE_NUS_MODULE); + } + + model.addModule(toAdd); + model.updateModulesListTaken(PREDICATE_SHOW_ALL_MODULES_TAKEN); + return new CommandResult(MESSAGE_SUCCESS + toAdd); + } + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof AddModuleCommand // instanceof handles nulls + && toAdd.equals(((AddModuleCommand) other).toAdd)); + } + +} diff --git a/src/main/java/seedu/address/logic/commands/modulecommand/CapCommand.java b/src/main/java/seedu/address/logic/commands/modulecommand/CapCommand.java new file mode 100644 index 00000000000..321e4982c06 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/modulecommand/CapCommand.java @@ -0,0 +1,27 @@ +package seedu.address.logic.commands.modulecommand; + +import static java.util.Objects.requireNonNull; + +import seedu.address.logic.commands.Command; +import seedu.address.logic.commands.CommandResult; +import seedu.address.model.Model; + +/** + * Calculates current CAP based on NUS modules the user has taken. + */ +public class CapCommand extends Command { + + public static final String COMMAND_WORD = "cap"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Calculates your current CAP based on the modules"; + + public static final String MESSAGE_SUCCESS = "CAP calculated"; + + @Override + public CommandResult execute(Model model) { + requireNonNull(model); + double result = model.getCap(); + String message = MESSAGE_SUCCESS + "\nCurrent CAP: " + result; + return new CommandResult(message); + } +} diff --git a/src/main/java/seedu/address/logic/commands/modulecommand/DeleteModuleCommand.java b/src/main/java/seedu/address/logic/commands/modulecommand/DeleteModuleCommand.java new file mode 100644 index 00000000000..c8209c1b1b9 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/modulecommand/DeleteModuleCommand.java @@ -0,0 +1,55 @@ +package seedu.address.logic.commands.modulecommand; + +import static java.util.Objects.requireNonNull; +import static seedu.address.model.Model.PREDICATE_SHOW_ALL_MODULES_TAKEN; + +import seedu.address.commons.core.Messages; +import seedu.address.logic.commands.Command; +import seedu.address.logic.commands.CommandResult; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; +import seedu.address.model.nusmodule.ModuleCode; + +/** + * Deletes a NUS module identified using given module code from the module book. + */ +public class DeleteModuleCommand extends Command { + + public static final String COMMAND_WORD = "moduleDel"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Allows for deleting modules " + + "Parameters: MODULE CODE " + + "Example: " + COMMAND_WORD + " CS2103T "; + + public static final String MESSAGE_SUCCESS = "Module deleted "; + + private final ModuleCode targetModuleCode; + + /** + * Creates an AddModuleCommand to add the specified {@code NusModule} + */ + public DeleteModuleCommand(ModuleCode moduleCode) { + requireNonNull(moduleCode); + targetModuleCode = moduleCode; + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + + if (!model.hasModule(targetModuleCode)) { + throw new CommandException(Messages.MESSAGE_NO_SUCH_MODULE); + } + + model.deleteModule(targetModuleCode); + model.updateModulesListTaken(PREDICATE_SHOW_ALL_MODULES_TAKEN); + return new CommandResult(MESSAGE_SUCCESS + targetModuleCode); + } + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof DeleteModuleCommand // instanceof handles nulls + && targetModuleCode.equals(((DeleteModuleCommand) other).targetModuleCode)); + } +} diff --git a/src/main/java/seedu/address/logic/commands/modulecommand/GradeCommand.java b/src/main/java/seedu/address/logic/commands/modulecommand/GradeCommand.java new file mode 100644 index 00000000000..e8b9401d3bd --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/modulecommand/GradeCommand.java @@ -0,0 +1,66 @@ +package seedu.address.logic.commands.modulecommand; + +import static java.util.Objects.requireNonNull; +import static seedu.address.logic.parser.CliSyntax.PREFIX_GRADE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_MODULE_CODE; +import static seedu.address.model.Model.PREDICATE_SHOW_ALL_MODULES_TAKEN; + +import seedu.address.commons.core.Messages; +import seedu.address.logic.commands.Command; +import seedu.address.logic.commands.CommandResult; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; +import seedu.address.model.nusmodule.Grade; +import seedu.address.model.nusmodule.ModuleCode; + +/** + * Updates a module's grade in our module book. + */ +public class GradeCommand extends Command { + public static final String COMMAND_WORD = "grade"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + + ": Adds or changes a grade to a module in the module book. " + + "Parameters: " + + PREFIX_MODULE_CODE + "MODULE CODE " + + PREFIX_GRADE + "GRADE " + + "Example: " + COMMAND_WORD + " " + + PREFIX_MODULE_CODE + "CS2103T " + + PREFIX_GRADE + "A+ "; + + public static final String MESSAGE_SUCCESS = "Module grade updated: "; + + private final Grade gradeToBeUpdated; + private final ModuleCode targetModuleCode; + + /** + * Creates an AddCommand to add the specified {@code Person} + */ + public GradeCommand(ModuleCode moduleCode, Grade grade) { + requireNonNull(grade); + targetModuleCode = moduleCode; + gradeToBeUpdated = grade; + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + + if (!model.hasModule(targetModuleCode)) { + throw new CommandException(Messages.MESSAGE_NO_SUCH_MODULE); + } + + model.gradeModule(targetModuleCode, gradeToBeUpdated); + model.updateModulesListTaken(PREDICATE_SHOW_ALL_MODULES_TAKEN); + return new CommandResult(MESSAGE_SUCCESS + " " + + targetModuleCode + " " + + gradeToBeUpdated.getText()); + } + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof GradeCommand // instanceof handles nulls + && targetModuleCode.equals(((GradeCommand) other).targetModuleCode)); + } +} diff --git a/src/main/java/seedu/address/logic/commands/taskcommand/TaskBreakdownCommand.java b/src/main/java/seedu/address/logic/commands/taskcommand/TaskBreakdownCommand.java new file mode 100644 index 00000000000..1dab68db284 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/taskcommand/TaskBreakdownCommand.java @@ -0,0 +1,26 @@ +package seedu.address.logic.commands.taskcommand; + +import static java.util.Objects.requireNonNull; + +import seedu.address.logic.commands.Command; +import seedu.address.logic.commands.CommandResult; +import seedu.address.model.Model; + +/** + * Shows the number of tasks for each module in the program. + */ +public class TaskBreakdownCommand extends Command { + public static final String COMMAND_WORD = "taskBreakdown"; + + public static final String MESSAGE_SUCCESS = "Listed number of tasks for each module:\n%s"; + + + @Override + public CommandResult execute(Model model) { + requireNonNull(model); + + String taskBreakdown = model.getTaskBreakdown(); + System.out.println(model.getTaskBreakdown()); + return new CommandResult(String.format(MESSAGE_SUCCESS, taskBreakdown)); + } +} diff --git a/src/main/java/seedu/address/logic/commands/taskcommand/addcommand/AddDeadlineCommand.java b/src/main/java/seedu/address/logic/commands/taskcommand/addcommand/AddDeadlineCommand.java new file mode 100644 index 00000000000..d1226d8ee8a --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/taskcommand/addcommand/AddDeadlineCommand.java @@ -0,0 +1,54 @@ +package seedu.address.logic.commands.taskcommand.addcommand; + +import static java.util.Objects.requireNonNull; +import static seedu.address.model.Model.PREDICATE_SHOW_ALL_TASK; + +import seedu.address.logic.commands.Command; +import seedu.address.logic.commands.CommandResult; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; +import seedu.address.model.calender.Task; + +/** + * Adds a deadline. + */ + +public class AddDeadlineCommand extends Command { + + public static final String COMMAND_WORD = "deadlineAdd"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds deadline. Format of input should be:" + + " deadlineAdd desc/ by/{DD-MM-YYYY} cat/\n " + + "Example: deadlineAdd desc/CS2101 presentation script by/02-04-2020 cat/School Work"; + + public static final String MESSAGE_SUCCESS = "Deadline added: "; + + private final Task deadlineToAdd; + + public AddDeadlineCommand (Task deadline) { + requireNonNull(deadline); + deadlineToAdd = deadline; + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + + if (model.isEmptyDeadline(deadlineToAdd)) { + throw new CommandException("There is no task to be added!"); + } + + model.addDeadlineTask(deadlineToAdd); + model.sortTaskList(); + model.updateDeadlineTaskList(PREDICATE_SHOW_ALL_TASK); + return new CommandResult(MESSAGE_SUCCESS + deadlineToAdd); + } + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof AddDeadlineCommand // instanceof handles nulls + && deadlineToAdd.equals(((AddDeadlineCommand) other).deadlineToAdd)); + } + +} diff --git a/src/main/java/seedu/address/logic/commands/taskcommand/addcommand/AddToDoCommand.java b/src/main/java/seedu/address/logic/commands/taskcommand/addcommand/AddToDoCommand.java new file mode 100644 index 00000000000..753a71d4b71 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/taskcommand/addcommand/AddToDoCommand.java @@ -0,0 +1,54 @@ +package seedu.address.logic.commands.taskcommand.addcommand; + +import static java.util.Objects.requireNonNull; + +import seedu.address.logic.commands.Command; +import seedu.address.logic.commands.CommandResult; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; +import seedu.address.model.calender.Task; + +/** + * Adds a todo. + */ + +public class AddToDoCommand extends Command { + + public static final String COMMAND_WORD = "todo"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds todo. Format of input should be:" + + " todo \n" + "Example: todo water plants"; + + public static final String MESSAGE_SUCCESS = "Todo added: "; + + public static final String MESSAGE_INVALID = "Your todo seems to be empty!"; + + + private final Task todoToAdd; + + + public AddToDoCommand(Task todoToAdd) { + requireNonNull(todoToAdd); + this.todoToAdd = todoToAdd; + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + + if (model.isEmptyToDo(todoToAdd)) { + throw new CommandException("There is no task to be added!"); + } + + model.addToDo(todoToAdd); + return new CommandResult(MESSAGE_SUCCESS + todoToAdd); + } + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof AddToDoCommand // instanceof handles nulls + && todoToAdd.equals(((AddToDoCommand) other).todoToAdd)); + } +} + diff --git a/src/main/java/seedu/address/logic/commands/taskcommand/addcommand/ModuleTaskCommand.java b/src/main/java/seedu/address/logic/commands/taskcommand/addcommand/ModuleTaskCommand.java new file mode 100644 index 00000000000..4aa6271ade5 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/taskcommand/addcommand/ModuleTaskCommand.java @@ -0,0 +1,74 @@ +package seedu.address.logic.commands.taskcommand.addcommand; + +import static java.util.Objects.requireNonNull; +import static seedu.address.logic.parser.CliSyntax.PREFIX_MODULETASK_TIMING; +import static seedu.address.logic.parser.CliSyntax.PREFIX_MODULE_CODE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_PRIORITY; +import static seedu.address.logic.parser.CliSyntax.PREFIX_TASK_DESC; +import static seedu.address.model.Model.PREDICATE_SHOW_ALL_TASK; + +import seedu.address.logic.commands.Command; +import seedu.address.logic.commands.CommandResult; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; +import seedu.address.model.nusmodule.ModuleTask; + +/** + * Add a new module task to a specific module which is already recorded in the program. + */ +public class ModuleTaskCommand extends Command { + + public static final String COMMAND_WORD = "moduleTask"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds a task to one of your modules " + + "Parameters: " + + PREFIX_TASK_DESC + "Description " + + PREFIX_MODULE_CODE + "Module related " + + PREFIX_MODULETASK_TIMING + "Timing of the task (in the format of {YYYY-MM-DD})" + + PREFIX_PRIORITY + "Priority " + + "Example: " + COMMAND_WORD + " " + + PREFIX_TASK_DESC + "Tutorial 08 " + + PREFIX_MODULE_CODE + "CS2030 " + + PREFIX_MODULETASK_TIMING + "30-04-2020 " + + PREFIX_PRIORITY + "5 "; + + public static final String MESSAGE_SUCCESS = "New task added successfully\nList of tasks for %s\n%s"; + public static final String MESSAGE_NO_SUCH_MODULE = "This module does not exist, " + + "maybe you can add the module first"; + + private final ModuleTask toAdd; + + /** + * Creates an AddCommand to add the specified {@code Person} + */ + public ModuleTaskCommand(ModuleTask task) { + requireNonNull(task); + toAdd = task; + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + + if (!model.hasModule(toAdd.getModuleRelated())) { + throw new CommandException(MESSAGE_NO_SUCH_MODULE); + } + + model.addModuleTask(toAdd); + model.addDeadlineTask(toAdd); + model.updateDeadlineTaskList(PREDICATE_SHOW_ALL_TASK); + model.sortTaskList(); + + String tasksInfo = model.getModuleTaskInfo(toAdd.getModuleRelated()); + + return new CommandResult(String.format(MESSAGE_SUCCESS, toAdd.getModuleRelated(), tasksInfo)); + } + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof ModuleTaskCommand // instanceof handles nulls + && toAdd.equals(((ModuleTaskCommand) other).toAdd)); + } + +} diff --git a/src/main/java/seedu/address/logic/commands/taskcommand/deletecommand/DeleteDeadlineCommand.java b/src/main/java/seedu/address/logic/commands/taskcommand/deletecommand/DeleteDeadlineCommand.java new file mode 100644 index 00000000000..90cb73542ed --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/taskcommand/deletecommand/DeleteDeadlineCommand.java @@ -0,0 +1,65 @@ +package seedu.address.logic.commands.taskcommand.deletecommand; + +import static java.util.Objects.requireNonNull; +import static seedu.address.model.Model.PREDICATE_SHOW_ALL_TASK; + +import java.util.List; + +import seedu.address.logic.commands.CommandResult; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; +import seedu.address.model.calender.Task; +import seedu.address.model.nusmodule.ModuleTask; + + +/** + * Adds a deadline. + */ + +public class DeleteDeadlineCommand extends DeleteTaskCommand { + + public static final String MESSAGE_SUCCESS = "Deadline Deleted: "; + public static final String MESSAGE_FAIL = "No such deadline exists"; + + private final Task deadlineToDelete; + + public DeleteDeadlineCommand(Task deadlineToDelete) { + requireNonNull(deadlineToDelete); + this.deadlineToDelete = deadlineToDelete; + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + + if (Task.getDeadlineTaskList().size() < deadlineToDelete.getIndex()) { + return new CommandResult(MESSAGE_FAIL); + } + + List lastShownList = model.getDeadlineTaskList(); + Task removed = lastShownList.get(deadlineToDelete.getIndex() - 1); + model.deleteTask(removed); + + if (removed instanceof ModuleTask) { + model.getModuleBook().removeModuleTask((ModuleTask) removed); + } + model.sortTaskList(); + model.updateDeadlineTaskList(PREDICATE_SHOW_ALL_TASK); + + return new CommandResult(MESSAGE_SUCCESS + removed); + } + + public Task getDeadlineToDelete() { + return this.deadlineToDelete; + } + + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof DeleteDeadlineCommand // instanceof handles nulls + && deadlineToDelete.equals(((DeleteDeadlineCommand) other).getDeadlineToDelete())); + } + + +} diff --git a/src/main/java/seedu/address/logic/commands/taskcommand/deletecommand/DeleteModuleTaskCommand.java b/src/main/java/seedu/address/logic/commands/taskcommand/deletecommand/DeleteModuleTaskCommand.java new file mode 100644 index 00000000000..65617cdf1f7 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/taskcommand/deletecommand/DeleteModuleTaskCommand.java @@ -0,0 +1,67 @@ +package seedu.address.logic.commands.taskcommand.deletecommand; + +import static java.util.Objects.requireNonNull; +import static seedu.address.model.Model.PREDICATE_SHOW_ALL_TASK; + +import java.util.List; + +import seedu.address.commons.core.Messages; +import seedu.address.commons.core.index.Index; +import seedu.address.logic.commands.CommandResult; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; +import seedu.address.model.calender.Task; +import seedu.address.model.nusmodule.ModuleCode; + + + +/** + * Deletes a task of certain module identified using it's displayed index from the module book. + */ +public class DeleteModuleTaskCommand extends DeleteTaskCommand { + + public static final String MESSAGE_SUCCESS = "Delete task as required successfully\nList of tasks for %s\n%s"; + + private final Index targetIndex; + private final ModuleCode targetModule; + + public DeleteModuleTaskCommand(ModuleCode moduleCode, Index targetIndex) { + requireNonNull(targetIndex); + requireNonNull(moduleCode); + this.targetIndex = targetIndex; + this.targetModule = moduleCode; + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + + if (!model.hasModule(targetModule)) { + throw new CommandException(Messages.MESSAGE_NO_SUCH_MODULE); + } + + if (targetIndex.getZeroBased() >= model.getSizeOfModuleTaskList(targetModule)) { + throw new CommandException(Messages.MESSAGE_INVALID_MODULE_TASK_INDEX); + } + + List lastShownList = model.getDeadlineTaskList(); + Task removed = lastShownList.get(targetIndex.getZeroBased()); + model.deleteTask(removed); + model.deleteModuleTask(targetModule, targetIndex); + model.sortTaskList(); + model.updateDeadlineTaskList(PREDICATE_SHOW_ALL_TASK); + + String tasksInfo = model.getModuleTaskInfo(targetModule); + + return new CommandResult(String.format(MESSAGE_SUCCESS, targetModule, tasksInfo)); + } + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof DeleteModuleTaskCommand // instanceof handles nulls + && targetModule.equals(((DeleteModuleTaskCommand) other).targetModule) + && targetIndex.equals(((DeleteModuleTaskCommand) other).targetIndex)); + } +} + diff --git a/src/main/java/seedu/address/logic/commands/taskcommand/deletecommand/DeleteTaskCommand.java b/src/main/java/seedu/address/logic/commands/taskcommand/deletecommand/DeleteTaskCommand.java new file mode 100644 index 00000000000..e8cedf642db --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/taskcommand/deletecommand/DeleteTaskCommand.java @@ -0,0 +1,32 @@ +package seedu.address.logic.commands.taskcommand.deletecommand; + +import static seedu.address.logic.parser.CliSyntax.PREFIX_MODULE_CODE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_TASK_INDEX; + +import seedu.address.logic.commands.Command; +import seedu.address.logic.commands.CommandResult; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; + +/** + * Deletes a task from the calendar or from certain module in profile tab. + */ +public abstract class DeleteTaskCommand extends Command { + + public static final String COMMAND_WORD = "taskDelete"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Delete deadline. Format of input should be:" + + " taskDelete index/{num} " + + "Example: taskDelete index/2\n" + + "or\n" + + COMMAND_WORD + ": Delete a module task " + + "Parameters: " + + PREFIX_MODULE_CODE + "MODULE CODE " + + PREFIX_TASK_INDEX + "index " + + "Example: " + COMMAND_WORD + " " + + PREFIX_MODULE_CODE + "CS2103T " + + PREFIX_TASK_INDEX + "1"; + + + public abstract CommandResult execute(Model model) throws CommandException; +} diff --git a/src/main/java/seedu/address/logic/commands/taskcommand/donecommand/DoneCommand.java b/src/main/java/seedu/address/logic/commands/taskcommand/donecommand/DoneCommand.java new file mode 100644 index 00000000000..cb4554edff0 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/taskcommand/donecommand/DoneCommand.java @@ -0,0 +1,28 @@ +package seedu.address.logic.commands.taskcommand.donecommand; + +import static seedu.address.logic.parser.CliSyntax.PREFIX_MODULE_CODE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_TASK_INDEX; + +import seedu.address.logic.commands.Command; +import seedu.address.logic.commands.CommandResult; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; + +/** + * Mark a task as done from the calendar or from certain module in profile tab. + */ +public abstract class DoneCommand extends Command { + public static final String COMMAND_WORD = "done"; + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Mark deadline as done. Format of input should be:" + + " done index/{num} " + + "Example: done index/2\n" + + "or\n" + + COMMAND_WORD + ": mark a module task as done " + + "Parameters: " + + PREFIX_MODULE_CODE + "MODULE CODE " + + PREFIX_TASK_INDEX + "index " + + "Example: " + COMMAND_WORD + " " + + PREFIX_MODULE_CODE + "CS2103T " + + PREFIX_TASK_INDEX + "1"; + public abstract CommandResult execute(Model model) throws CommandException; +} diff --git a/src/main/java/seedu/address/logic/commands/taskcommand/donecommand/DoneDeadlineCommand.java b/src/main/java/seedu/address/logic/commands/taskcommand/donecommand/DoneDeadlineCommand.java new file mode 100644 index 00000000000..9a3159016ad --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/taskcommand/donecommand/DoneDeadlineCommand.java @@ -0,0 +1,56 @@ +package seedu.address.logic.commands.taskcommand.donecommand; + +import static java.util.Objects.requireNonNull; + +import java.util.List; + +import seedu.address.logic.commands.CommandResult; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; +import seedu.address.model.calender.Task; + +/** + * Mark a deadline in calendar as done. + */ +public class DoneDeadlineCommand extends DoneCommand { + + public static final String MESSAGE_SUCCESS = "Deadline done: "; + public static final String MESSAGE_FAIL = "No such deadline exists"; + + private final Task deadlineDone; + + public DoneDeadlineCommand(Task deadlineDone) { + requireNonNull(deadlineDone); + this.deadlineDone = deadlineDone; + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + + if (Task.getDeadlineTaskList().size() < deadlineDone.getIndex()) { + return new CommandResult(MESSAGE_FAIL); + } + + List lastShownList = model.getDeadlineTaskList(); + Task completed = lastShownList.get(deadlineDone.getIndex() - 1); + completed.markAsDone(); + + model.sortTaskList(); + model.updateDeadlineTaskList(Model.PREDICATE_SHOW_ALL_TASK); + + return new CommandResult(MESSAGE_SUCCESS + completed); + } + + public Task getDeadlineDone() { + return deadlineDone; + } + + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof DoneDeadlineCommand // instanceof handles nulls + && deadlineDone.equals(((DoneDeadlineCommand) other).getDeadlineDone())); + } +} diff --git a/src/main/java/seedu/address/logic/commands/taskcommand/donecommand/DoneModuleTaskCommand.java b/src/main/java/seedu/address/logic/commands/taskcommand/donecommand/DoneModuleTaskCommand.java new file mode 100644 index 00000000000..58a9ba9738f --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/taskcommand/donecommand/DoneModuleTaskCommand.java @@ -0,0 +1,58 @@ +package seedu.address.logic.commands.taskcommand.donecommand; + +import static java.util.Objects.requireNonNull; + +import seedu.address.commons.core.Messages; +import seedu.address.commons.core.index.Index; +import seedu.address.logic.commands.CommandResult; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; +import seedu.address.model.nusmodule.ModuleCode; + +/** + * Mark a task of certain module identified using it's displayed index from the module book as done. + */ +public class DoneModuleTaskCommand extends DoneCommand { + + public static final String MESSAGE_SUCCESS = "Mark task as done successfully\nList of tasks for %s\n%s"; + + private final Index targetIndex; + private final ModuleCode targetModule; + + public DoneModuleTaskCommand(ModuleCode moduleCode, Index targetIndex) { + requireNonNull(targetIndex); + requireNonNull(moduleCode); + this.targetIndex = targetIndex; + this.targetModule = moduleCode; + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + + if (!model.hasModule(targetModule)) { + throw new CommandException(Messages.MESSAGE_NO_SUCH_MODULE); + } + + if (targetIndex.getZeroBased() >= model.getSizeOfModuleTaskList(targetModule)) { + throw new CommandException(Messages.MESSAGE_INVALID_MODULE_TASK_INDEX); + } + + model.doneModuleTask(targetModule, targetIndex); + + model.sortTaskList(); + model.updateDeadlineTaskList(Model.PREDICATE_SHOW_ALL_TASK); + + String tasksInfo = model.getModuleTaskInfo(targetModule); + + return new CommandResult(String.format(MESSAGE_SUCCESS, targetModule, tasksInfo)); + } + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof DoneModuleTaskCommand // instanceof handles nulls + && targetModule.equals(((DoneModuleTaskCommand) other).targetModule) + && targetIndex.equals(((DoneModuleTaskCommand) other).targetIndex)); + } +} diff --git a/src/main/java/seedu/address/logic/commands/taskcommand/findcommand/FindTasksByCatCommand.java b/src/main/java/seedu/address/logic/commands/taskcommand/findcommand/FindTasksByCatCommand.java new file mode 100644 index 00000000000..cdc4c3eff76 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/taskcommand/findcommand/FindTasksByCatCommand.java @@ -0,0 +1,36 @@ +package seedu.address.logic.commands.taskcommand.findcommand; + +import static java.util.Objects.requireNonNull; + +import seedu.address.logic.commands.CommandResult; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; +import seedu.address.model.calender.CatContainsKeywordsPredicate; + +/** + * Find tasks in calendar by specific category. + */ +public class FindTasksByCatCommand extends FindTasksCommand { + public static final String MESSAGE_SUCCESS = " Tasks found"; + + private final CatContainsKeywordsPredicate predicate; + + public FindTasksByCatCommand(CatContainsKeywordsPredicate predicate) { + this.predicate = predicate; + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + + model.updateDeadlineTaskList(predicate); + + return new CommandResult(model.getDeadlineTaskList().size() + MESSAGE_SUCCESS); + } + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof FindTasksByCatCommand); + } +} diff --git a/src/main/java/seedu/address/logic/commands/taskcommand/findcommand/FindTasksByDateCommand.java b/src/main/java/seedu/address/logic/commands/taskcommand/findcommand/FindTasksByDateCommand.java new file mode 100644 index 00000000000..f8e7c2fff31 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/taskcommand/findcommand/FindTasksByDateCommand.java @@ -0,0 +1,38 @@ +package seedu.address.logic.commands.taskcommand.findcommand; + +import static java.util.Objects.requireNonNull; + +import seedu.address.logic.commands.CommandResult; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; +import seedu.address.model.calender.DateContainKeywordsPredicate; + +/** + * Find tasks in calendar by specific date. + */ +public class FindTasksByDateCommand extends FindTasksCommand { + public static final String MESSAGE_SUCCESS = " Tasks found"; + + private final DateContainKeywordsPredicate predicate; + + public FindTasksByDateCommand(DateContainKeywordsPredicate predicate) { + requireNonNull(predicate); + this.predicate = predicate; + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + + model.updateDeadlineTaskList(predicate); + + return new CommandResult(model.getDeadlineTaskList().size() + MESSAGE_SUCCESS); + } + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof FindTasksByDateCommand); + } +} + diff --git a/src/main/java/seedu/address/logic/commands/taskcommand/findcommand/FindTasksByModuleCodeCommand.java b/src/main/java/seedu/address/logic/commands/taskcommand/findcommand/FindTasksByModuleCodeCommand.java new file mode 100644 index 00000000000..5db3d12c749 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/taskcommand/findcommand/FindTasksByModuleCodeCommand.java @@ -0,0 +1,37 @@ +package seedu.address.logic.commands.taskcommand.findcommand; + +import static java.util.Objects.requireNonNull; + +import seedu.address.logic.commands.CommandResult; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; +import seedu.address.model.calender.ModuleCodeContainKeywordsPredicate; + +/** + * Find tasks in calendar by specific module code. + */ +public class FindTasksByModuleCodeCommand extends FindTasksCommand { + public static final String MESSAGE_SUCCESS = " Tasks found"; + + private final ModuleCodeContainKeywordsPredicate predicate; + + public FindTasksByModuleCodeCommand(ModuleCodeContainKeywordsPredicate predicate) { + this.predicate = predicate; + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + + model.updateDeadlineTaskList(predicate); + System.out.println(model.getDeadlineTaskList()); + + return new CommandResult(model.getDeadlineTaskList().size() + MESSAGE_SUCCESS); + } + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof FindTasksByModuleCodeCommand); + } +} diff --git a/src/main/java/seedu/address/logic/commands/taskcommand/findcommand/FindTasksCommand.java b/src/main/java/seedu/address/logic/commands/taskcommand/findcommand/FindTasksCommand.java new file mode 100644 index 00000000000..4d2ffaed6ca --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/taskcommand/findcommand/FindTasksCommand.java @@ -0,0 +1,37 @@ +package seedu.address.logic.commands.taskcommand.findcommand; + +import static seedu.address.logic.parser.CliSyntax.PREFIX_MODULETASK_TIMING; +import static seedu.address.logic.parser.CliSyntax.PREFIX_MODULE_CODE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_TASK_CAT; + +import seedu.address.logic.commands.Command; +import seedu.address.logic.commands.CommandResult; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; + +/** + * Find tasks in calendar by specific key word (category/date/module code). + */ +public abstract class FindTasksCommand extends Command { + public static final String COMMAND_WORD = "findTask"; + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Find tasks as required\n" + + COMMAND_WORD + ": find tasks related to given module code " + + "Parameters: " + + PREFIX_MODULE_CODE + "MODULE CODE " + + "Example: " + COMMAND_WORD + " " + + PREFIX_MODULE_CODE + "CS2103T " + + "or\n" + + COMMAND_WORD + ": find tasks related to given category " + + "Parameters: " + + PREFIX_TASK_CAT + "CATEGORY" + + "Example: " + COMMAND_WORD + " " + + PREFIX_TASK_CAT + "School work " + + "or\n" + + COMMAND_WORD + ": find tasks related to given date " + + "Parameters: " + + PREFIX_MODULETASK_TIMING + "DATE " + + "Example: " + COMMAND_WORD + " " + + PREFIX_MODULETASK_TIMING + "01-01-2020"; + + public abstract CommandResult execute(Model model) throws CommandException; +} diff --git a/src/main/java/seedu/address/logic/commands/taskcommand/listcommand/ListAllTaskCommand.java b/src/main/java/seedu/address/logic/commands/taskcommand/listcommand/ListAllTaskCommand.java new file mode 100644 index 00000000000..4b161db9e9a --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/taskcommand/listcommand/ListAllTaskCommand.java @@ -0,0 +1,36 @@ +package seedu.address.logic.commands.taskcommand.listcommand; + +import static java.util.Objects.requireNonNull; + +import seedu.address.logic.commands.Command; +import seedu.address.logic.commands.CommandResult; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; + +/** + * Find tasks in calendar by specific module code. + */ +public class ListAllTaskCommand extends Command { + + public static final String MESSAGE_SUCCESS = "Listed all Tasks"; + public static final String COMMAND_WORD = "listTask"; + + + public ListAllTaskCommand() { + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + + model.updateDeadlineTaskList(Model.PREDICATE_SHOW_ALL_TASK); + + return new CommandResult(MESSAGE_SUCCESS); + } + + @Override + public boolean equals(Object other) { + + return false; + } +} diff --git a/src/main/java/seedu/address/logic/commands/taskcommand/listcommand/ListModuleTaskCommand.java b/src/main/java/seedu/address/logic/commands/taskcommand/listcommand/ListModuleTaskCommand.java new file mode 100644 index 00000000000..80e14099212 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/taskcommand/listcommand/ListModuleTaskCommand.java @@ -0,0 +1,53 @@ +package seedu.address.logic.commands.taskcommand.listcommand; + +import static java.util.Objects.requireNonNull; + +import seedu.address.commons.core.Messages; +import seedu.address.logic.commands.Command; +import seedu.address.logic.commands.CommandResult; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; +import seedu.address.model.nusmodule.ModuleCode; + +/** + * Find tasks in module book by specific module code. + */ +public class ListModuleTaskCommand extends Command { + public static final String MESSAGE_SUCCESS = "List of tasks for %s\n%s"; + public static final String COMMAND_WORD = "listModuleTasks"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Show the tasks related to certain module " + + "Parameters: " + + "MODULE CODE " + + "Example: " + COMMAND_WORD + " CS2103T "; + + private final ModuleCode targetModuleCode; + + /** + * Creates an AddModuleCommand to add the specified {@code NusModule} + */ + public ListModuleTaskCommand(ModuleCode moduleCode) { + requireNonNull(moduleCode); + targetModuleCode = moduleCode; + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + + if (!model.hasModule(targetModuleCode)) { + throw new CommandException(Messages.MESSAGE_NO_SUCH_MODULE); + } + String tasksInfo = model.getModuleTaskInfo(targetModuleCode); + + return new CommandResult(String.format(MESSAGE_SUCCESS, targetModuleCode, tasksInfo)); + } + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof ListModuleTaskCommand // instanceof handles nulls + && targetModuleCode.equals(((ListModuleTaskCommand) other).targetModuleCode)); + } + +} diff --git a/src/main/java/seedu/address/logic/commands/taskcommand/sortcommand/SortTasksCommand.java b/src/main/java/seedu/address/logic/commands/taskcommand/sortcommand/SortTasksCommand.java new file mode 100644 index 00000000000..102df5a2681 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/taskcommand/sortcommand/SortTasksCommand.java @@ -0,0 +1,52 @@ +package seedu.address.logic.commands.taskcommand.sortcommand; + +import static java.util.Objects.requireNonNull; +import static seedu.address.logic.parser.CliSyntax.PREFIX_SORTING; + +import seedu.address.logic.commands.Command; +import seedu.address.logic.commands.CommandResult; +import seedu.address.logic.commands.exceptions.CommandException; + +import seedu.address.model.Model; + +/** + * Sort tasks in calendar by date or priority. + */ +public class SortTasksCommand extends Command { + public static final String COMMAND_WORD = "sortTask"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Sort the tasks as required " + + "Parameters: " + + PREFIX_SORTING + "Sorting parameter " + + "Example: " + COMMAND_WORD + " " + + PREFIX_SORTING + "priority"; + + public static final String MESSAGE_SUCCESS = "Tasks sorted by "; + + private final String sortingParam; + + /** + * Creates an AddCommand to add the specified {@code Person} + */ + public SortTasksCommand(String sortingParam) { + requireNonNull(sortingParam); + this.sortingParam = sortingParam; + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + + model.sortTask(sortingParam); + + return new CommandResult(MESSAGE_SUCCESS + sortingParam); + } + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof SortTasksCommand // instanceof handles nulls + && sortingParam.equals(((SortTasksCommand) other).sortingParam)); + } + +} diff --git a/src/main/java/seedu/address/logic/parser/AddCommandParser.java b/src/main/java/seedu/address/logic/parser/AddCommandParser.java index 3b8bfa035e8..c39a41a3935 100644 --- a/src/main/java/seedu/address/logic/parser/AddCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/AddCommandParser.java @@ -1,7 +1,6 @@ package seedu.address.logic.parser; import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; -import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS; import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL; import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE; @@ -12,7 +11,6 @@ import seedu.address.logic.commands.AddCommand; import seedu.address.logic.parser.exceptions.ParseException; -import seedu.address.model.person.Address; import seedu.address.model.person.Email; import seedu.address.model.person.Name; import seedu.address.model.person.Person; @@ -31,9 +29,9 @@ public class AddCommandParser implements Parser { */ public AddCommand parse(String args) throws ParseException { ArgumentMultimap argMultimap = - ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS, PREFIX_TAG); + ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_TAG); - if (!arePrefixesPresent(argMultimap, PREFIX_NAME, PREFIX_ADDRESS, PREFIX_PHONE, PREFIX_EMAIL) + if (!arePrefixesPresent(argMultimap, PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL) || !argMultimap.getPreamble().isEmpty()) { throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddCommand.MESSAGE_USAGE)); } @@ -41,10 +39,9 @@ public AddCommand parse(String args) throws ParseException { Name name = ParserUtil.parseName(argMultimap.getValue(PREFIX_NAME).get()); Phone phone = ParserUtil.parsePhone(argMultimap.getValue(PREFIX_PHONE).get()); Email email = ParserUtil.parseEmail(argMultimap.getValue(PREFIX_EMAIL).get()); - Address address = ParserUtil.parseAddress(argMultimap.getValue(PREFIX_ADDRESS).get()); Set tagList = ParserUtil.parseTags(argMultimap.getAllValues(PREFIX_TAG)); - Person person = new Person(name, phone, email, address, tagList); + Person person = new Person(name, phone, email, tagList); return new AddCommand(person); } diff --git a/src/main/java/seedu/address/logic/parser/AddDeadlineCommandParser.java b/src/main/java/seedu/address/logic/parser/AddDeadlineCommandParser.java new file mode 100644 index 00000000000..ec396eedbf9 --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/AddDeadlineCommandParser.java @@ -0,0 +1,50 @@ +package seedu.address.logic.parser; + +import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.parser.CliSyntax.PREFIX_DEADLINE_DATE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_TASK_CAT; +import static seedu.address.logic.parser.CliSyntax.PREFIX_TASK_DESC; + +import java.util.stream.Stream; + +import seedu.address.logic.commands.taskcommand.addcommand.AddDeadlineCommand; +import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.calender.Task; + + + +/** + * Parses input arguments and creates a new AddCommand object + */ +public class AddDeadlineCommandParser implements Parser { + + /** + * Parses the given {@code String} of arguments in the context of the AddCommand + * and returns an AddCommand object for execution. + * @throws ParseException if the user input does not conform the expected format + */ + public AddDeadlineCommand parse(String args) throws ParseException { + ArgumentMultimap argMultimap = + ArgumentTokenizer.tokenize(args, PREFIX_TASK_DESC, PREFIX_DEADLINE_DATE, PREFIX_TASK_CAT); + + if (!arePrefixesPresent(argMultimap, PREFIX_TASK_DESC, PREFIX_DEADLINE_DATE, PREFIX_TASK_CAT) + || !argMultimap.getPreamble().isEmpty()) { + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddDeadlineCommand.MESSAGE_USAGE)); + } + + Task deadline = ParserUtil.parseDeadline(argMultimap.getValue(PREFIX_TASK_DESC).get(), + argMultimap.getValue(PREFIX_DEADLINE_DATE).get(), argMultimap.getValue(PREFIX_TASK_CAT).get()); + + + return new AddDeadlineCommand(deadline); + } + + /** + * Returns true if none of the prefixes contains empty {@code Optional} values in the given + * {@code ArgumentMultimap}. + */ + private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) { + return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent()); + } + +} diff --git a/src/main/java/seedu/address/logic/parser/AddModuleCommandParser.java b/src/main/java/seedu/address/logic/parser/AddModuleCommandParser.java new file mode 100644 index 00000000000..14514200f2e --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/AddModuleCommandParser.java @@ -0,0 +1,77 @@ +package seedu.address.logic.parser; + +import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.parser.CliSyntax.PREFIX_GRADE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_MODULE_CODE; + +import java.util.ArrayList; +import java.util.Optional; +import java.util.stream.Stream; + +import seedu.address.logic.commands.modulecommand.AddModuleCommand; +import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.nusmodule.Grade; +import seedu.address.model.nusmodule.ModuleCode; +import seedu.address.model.nusmodule.NusModule; +import seedu.address.searcher.Module; +import seedu.address.searcher.Search; + +/** + * Parses input arguments and creates a new AddModuleCommand object + */ +public class AddModuleCommandParser implements Parser { + + /** + * Parses the given {@code String} of arguments in the context of the AddModuleCommand + * and returns an AddModuleCommand object for execution. + * @throws ParseException if the user input does not conform the expected format + */ + public AddModuleCommand parse(String args) throws ParseException { + ArgumentMultimap argMultimap1 = + ArgumentTokenizer.tokenize(args, PREFIX_MODULE_CODE, PREFIX_GRADE); + + ArgumentMultimap argMultimap2 = + ArgumentTokenizer.tokenize(args, PREFIX_MODULE_CODE); + + if (arePrefixesPresent(argMultimap1, PREFIX_MODULE_CODE, PREFIX_GRADE) + && argMultimap1.getPreamble().isEmpty()) { + + ModuleCode moduleCode = ParserUtil.parseModuleCode( + argMultimap1.getValue(PREFIX_MODULE_CODE).get()); + Module moduleInfo = Search.findModule(moduleCode.toString()); + int moduleCredit = moduleInfo.getCredits(); + + Grade grade = ParserUtil.parseGrade(argMultimap1.getValue(PREFIX_GRADE).get()); + + NusModule module = new NusModule(moduleCode, moduleCredit, + Optional.of(grade), new ArrayList<>()); + + return new AddModuleCommand(module); + + } else if (arePrefixesPresent(argMultimap2, PREFIX_MODULE_CODE) + && argMultimap2.getPreamble().isEmpty()) { + + ModuleCode moduleCode = ParserUtil.parseModuleCode( + argMultimap2.getValue(PREFIX_MODULE_CODE).get()); + Module moduleInfo = Search.findModule(moduleCode.toString()); + int moduleCredit = moduleInfo.getCredits(); + + NusModule module = new NusModule(moduleCode, moduleCredit, + Optional.empty(), new ArrayList<>()); + + return new AddModuleCommand(module); + + } else { + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddModuleCommand.MESSAGE_USAGE)); + } + } + + /** + * Returns true if none of the prefixes contains empty {@code Optional} values in the given + * {@code ArgumentMultimap}. + */ + private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) { + return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent()); + } + +} diff --git a/src/main/java/seedu/address/logic/parser/AddToDoCommandParser.java b/src/main/java/seedu/address/logic/parser/AddToDoCommandParser.java new file mode 100644 index 00000000000..8c34632478c --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/AddToDoCommandParser.java @@ -0,0 +1,47 @@ +package seedu.address.logic.parser; + +import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.parser.CliSyntax.PREFIX_TASK_DESC; + +import java.util.stream.Stream; + +import seedu.address.logic.commands.taskcommand.addcommand.AddDeadlineCommand; +import seedu.address.logic.commands.taskcommand.addcommand.AddToDoCommand; +import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.calender.Task; + + +/** + * Parses input arguments and creates a new AddCommand object + */ +public class AddToDoCommandParser implements Parser { + + /** + * Parses the given {@code String} of arguments in the context of the AddCommand + * and returns an AddCommand object for execution. + * @throws ParseException if the user input does not conform the expected format + */ + public AddToDoCommand parse(String args) throws ParseException { + ArgumentMultimap argMultimap = + ArgumentTokenizer.tokenize(args, PREFIX_TASK_DESC); + + if (!arePrefixesPresent(argMultimap, PREFIX_TASK_DESC) + || !argMultimap.getPreamble().isEmpty()) { + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddDeadlineCommand.MESSAGE_USAGE)); + } + + Task todo = ParserUtil.parseTodo(argMultimap.getValue(PREFIX_TASK_DESC).get()); + + + return new AddToDoCommand(todo); + } + + /** + * Returns true if none of the prefixes contains empty {@code Optional} values in the given + * {@code ArgumentMultimap}. + */ + private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) { + return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent()); + } + +} diff --git a/src/main/java/seedu/address/logic/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java index 1e466792b46..8f2ae60f923 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -6,17 +6,50 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import seedu.address.logic.commands.AddBookCommand; import seedu.address.logic.commands.AddCommand; +import seedu.address.logic.commands.CalenderCommand; import seedu.address.logic.commands.ClearCommand; import seedu.address.logic.commands.Command; import seedu.address.logic.commands.DeleteCommand; +import seedu.address.logic.commands.DiaryCommand; import seedu.address.logic.commands.EditCommand; import seedu.address.logic.commands.ExitCommand; import seedu.address.logic.commands.FindCommand; import seedu.address.logic.commands.HelpCommand; import seedu.address.logic.commands.ListCommand; +import seedu.address.logic.commands.MajorCommand; +import seedu.address.logic.commands.ModPlanCommand; +import seedu.address.logic.commands.NotesCommand; +import seedu.address.logic.commands.NotesCreateCommand; +import seedu.address.logic.commands.NotesDeleteCommand; +import seedu.address.logic.commands.NotesListCommand; +import seedu.address.logic.commands.NotesOpenCommand; +import seedu.address.logic.commands.ProfileCommand; +import seedu.address.logic.commands.SearchCommand; +import seedu.address.logic.commands.diarycommand.DiaryAddCommand; +import seedu.address.logic.commands.diarycommand.DiaryDeleteCommand; +import seedu.address.logic.commands.diarycommand.DiaryLogCommand; +import seedu.address.logic.commands.diarycommand.DiaryMoodCommand; +import seedu.address.logic.commands.diarycommand.DiaryShowCommand; +import seedu.address.logic.commands.diarycommand.DiaryWeatherCommand; +import seedu.address.logic.commands.modulecommand.AddModuleCommand; +import seedu.address.logic.commands.modulecommand.CapCommand; +import seedu.address.logic.commands.modulecommand.DeleteModuleCommand; +import seedu.address.logic.commands.modulecommand.GradeCommand; +import seedu.address.logic.commands.taskcommand.TaskBreakdownCommand; +import seedu.address.logic.commands.taskcommand.addcommand.AddDeadlineCommand; +import seedu.address.logic.commands.taskcommand.addcommand.AddToDoCommand; +import seedu.address.logic.commands.taskcommand.addcommand.ModuleTaskCommand; +import seedu.address.logic.commands.taskcommand.deletecommand.DeleteTaskCommand; +import seedu.address.logic.commands.taskcommand.donecommand.DoneCommand; +import seedu.address.logic.commands.taskcommand.findcommand.FindTasksCommand; +import seedu.address.logic.commands.taskcommand.listcommand.ListAllTaskCommand; +import seedu.address.logic.commands.taskcommand.listcommand.ListModuleTaskCommand; +import seedu.address.logic.commands.taskcommand.sortcommand.SortTasksCommand; import seedu.address.logic.parser.exceptions.ParseException; + /** * Parses user input. */ @@ -43,7 +76,6 @@ public Command parseCommand(String userInput) throws ParseException { final String commandWord = matcher.group("commandWord"); final String arguments = matcher.group("arguments"); switch (commandWord) { - case AddCommand.COMMAND_WORD: return new AddCommandParser().parse(arguments); @@ -68,6 +100,103 @@ public Command parseCommand(String userInput) throws ParseException { case HelpCommand.COMMAND_WORD: return new HelpCommand(); + case CalenderCommand.COMMAND_WORD: + return new CalenderCommand(); + + case DiaryCommand.COMMAND_WORD: + return new DiaryCommand(); + + case AddBookCommand.COMMAND_WORD: + return new AddBookCommand(); + + case ProfileCommand.COMMAND_WORD: + return new ProfileCommand(); + + case ModPlanCommand.COMMAND_WORD: + return new ModPlanCommand(); + + case NotesCommand.COMMAND_WORD: + return new NotesCommand(); + + case DiaryAddCommand.COMMAND_WORD: + return new DiaryAddCommandParser().parse(arguments); + + case DiaryLogCommand.COMMAND_WORD: + return new DiaryLogCommand(); + + case DiaryDeleteCommand.COMMAND_WORD: + return new DiaryDeleteCommandParser().parse(arguments); + + case DiaryWeatherCommand.COMMAND_WORD: + return new DiaryWeatherCommandParser().parse(arguments); + + case DiaryMoodCommand.COMMAND_WORD: + return new DiaryMoodCommandParser().parse(arguments); + + case DiaryShowCommand.COMMAND_WORD: + return new DiaryShowCommandParser().parse(arguments); + + case SearchCommand.COMMAND_WORD: + return new SearchCommandParser().parse(arguments); + + case AddModuleCommand.COMMAND_WORD: + return new AddModuleCommandParser().parse(arguments); + + case GradeCommand.COMMAND_WORD: + return new GradeCommandParser().parse(arguments); + + case DeleteModuleCommand.COMMAND_WORD: + return new DeleteModuleCommandParser().parse(arguments); + + case CapCommand.COMMAND_WORD: + return new CapCommand(); + + case AddToDoCommand.COMMAND_WORD: + return new AddToDoCommandParser().parse(arguments); + + case AddDeadlineCommand.COMMAND_WORD: + return new AddDeadlineCommandParser().parse(arguments); + + case DeleteTaskCommand.COMMAND_WORD: + return new DeleteTaskCommandParser().parse(arguments); + + case DoneCommand.COMMAND_WORD: + return new DoneCommandParser().parse(arguments); + + case FindTasksCommand.COMMAND_WORD: + return new FindTasksCommandParser().parse(arguments); + + case ListAllTaskCommand.COMMAND_WORD: + return new ListAllTaskCommand(); + + case ListModuleTaskCommand.COMMAND_WORD: + return new ListModuleTaskCommandParser().parse(arguments); + + case TaskBreakdownCommand.COMMAND_WORD: + return new TaskBreakdownCommand(); + + case SortTasksCommand.COMMAND_WORD: + return new SortTasksCommandParser().parse(arguments); + + case ModuleTaskCommand.COMMAND_WORD: + return new ModuleTaskCommandParser().parse(arguments); + + case MajorCommand.COMMAND_WORD: + return new MajorCommandParser().parse(arguments); + + case NotesListCommand.COMMAND_WORD: + return new NotesListCommandParser().parse(arguments); + + case NotesCreateCommand.COMMAND_WORD: + return new NotesCreateCommandParser().parse(arguments); + + case NotesOpenCommand.COMMAND_WORD: + return new NotesOpenCommandParser().parse(arguments); + + case NotesDeleteCommand.COMMAND_WORD: + return new NotesDeleteCommandParser().parse(arguments); + + default: throw new ParseException(MESSAGE_UNKNOWN_COMMAND); } diff --git a/src/main/java/seedu/address/logic/parser/CliSyntax.java b/src/main/java/seedu/address/logic/parser/CliSyntax.java index 75b1a9bf119..1ebb7228682 100644 --- a/src/main/java/seedu/address/logic/parser/CliSyntax.java +++ b/src/main/java/seedu/address/logic/parser/CliSyntax.java @@ -9,7 +9,31 @@ public class CliSyntax { public static final Prefix PREFIX_NAME = new Prefix("n/"); public static final Prefix PREFIX_PHONE = new Prefix("p/"); public static final Prefix PREFIX_EMAIL = new Prefix("e/"); - public static final Prefix PREFIX_ADDRESS = new Prefix("a/"); public static final Prefix PREFIX_TAG = new Prefix("t/"); + public static final Prefix PREFIX_NOTES_PATH_TYPE = new Prefix("pt/"); + public static final Prefix PREFIX_NOTES_PATH = new Prefix("loc/"); + public static final Prefix PREFIX_NOTES_TYPE = new Prefix("type/"); + public static final Prefix PREFIX_NOTES_FILE_NAME = new Prefix("name/"); + + /* Module Prefixes*/ + public static final Prefix PREFIX_GRADE = new Prefix("g/"); + public static final Prefix PREFIX_MODULE_CODE = new Prefix("m/"); + + /* Task Prefixes*/ + public static final Prefix PREFIX_TASK_DESC = new Prefix("desc/"); + public static final Prefix PREFIX_DEADLINE_DATE = new Prefix("by/"); + public static final Prefix PREFIX_TASK_CAT = new Prefix("cat/"); + public static final Prefix PREFIX_TASK_OPERATION = new Prefix("op/"); + public static final Prefix PREFIX_TASK_INDEX = new Prefix("index/"); + public static final Prefix PREFIX_MODULETASK_TIMING = new Prefix("date/"); + public static final Prefix PREFIX_PRIORITY = new Prefix("pri/"); + public static final Prefix PREFIX_SORTING = new Prefix("by/"); + + /* Diary Prefixes*/ + public static final Prefix PREFIX_ENTRY_CONTENT = new Prefix("ec/"); + public static final Prefix PREFIX_ENTRY_ID = new Prefix("id/"); + public static final Prefix PREFIX_WEATHER = new Prefix("w/"); + public static final Prefix PREFIX_MOOD = new Prefix("m/"); + public static final Prefix PREFIX_DIARY_DATE = new Prefix("date/"); } diff --git a/src/main/java/seedu/address/logic/parser/DeleteModuleCommandParser.java b/src/main/java/seedu/address/logic/parser/DeleteModuleCommandParser.java new file mode 100644 index 00000000000..abf956e7c32 --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/DeleteModuleCommandParser.java @@ -0,0 +1,27 @@ +package seedu.address.logic.parser; + +import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; + +import seedu.address.logic.commands.modulecommand.DeleteModuleCommand; +import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.nusmodule.ModuleCode; + +/** + * Parses input arguments and creates a new DeleteModuleCommand object + */ +public class DeleteModuleCommandParser implements Parser { + /** + * Parses the given {@code String} of arguments in the context of the DeleteCommand + * and returns a DeleteCommand object for execution. + * @throws ParseException if the user input does not conform the expected format + */ + public DeleteModuleCommand parse(String args) throws ParseException { + try { + ModuleCode moduleCode = ParserUtil.parseModuleCode(args); + return new DeleteModuleCommand(moduleCode); + } catch (ParseException pe) { + throw new ParseException( + String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteModuleCommand.MESSAGE_USAGE), pe); + } + } +} diff --git a/src/main/java/seedu/address/logic/parser/DeleteTaskCommandParser.java b/src/main/java/seedu/address/logic/parser/DeleteTaskCommandParser.java new file mode 100644 index 00000000000..ef147fb965c --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/DeleteTaskCommandParser.java @@ -0,0 +1,58 @@ +package seedu.address.logic.parser; + +import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.parser.CliSyntax.PREFIX_MODULE_CODE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_TASK_INDEX; + +import java.util.stream.Stream; + +import seedu.address.commons.core.index.Index; +import seedu.address.logic.commands.taskcommand.deletecommand.DeleteDeadlineCommand; +import seedu.address.logic.commands.taskcommand.deletecommand.DeleteModuleTaskCommand; +import seedu.address.logic.commands.taskcommand.deletecommand.DeleteTaskCommand; +import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.calender.Task; +import seedu.address.model.nusmodule.ModuleCode; + +/** + * Parses input arguments and creates a new AddCommand object + */ +public class DeleteTaskCommandParser implements Parser { + + /** + * Parses the given {@code String} of arguments in the context of the AddCommand + * and returns an AddCommand object for execution. + * @throws ParseException if the user input does not conform the expected format + */ + public DeleteTaskCommand parse(String args) throws ParseException { + ArgumentMultimap argMultimap1 = + ArgumentTokenizer.tokenize(args, PREFIX_TASK_INDEX); + + ArgumentMultimap argMultimap2 = + ArgumentTokenizer.tokenize(args, PREFIX_MODULE_CODE, PREFIX_TASK_INDEX); + + if (arePrefixesPresent(argMultimap1, PREFIX_TASK_INDEX) + && argMultimap1.getPreamble().isEmpty()) { + Task deadline = ParserUtil.parseRemoveDeadline(argMultimap1.getValue(PREFIX_TASK_INDEX).get()); + return new DeleteDeadlineCommand(deadline); + } else if (arePrefixesPresent(argMultimap2, PREFIX_MODULE_CODE, PREFIX_TASK_INDEX) + && argMultimap2.getPreamble().isEmpty()) { + ModuleCode moduleCode = ParserUtil.parseModuleCode( + argMultimap2.getValue(PREFIX_MODULE_CODE).get()); + Index index = ParserUtil.parseIndex(argMultimap2.getValue(PREFIX_TASK_INDEX).get()); + return new DeleteModuleTaskCommand(moduleCode, index); + } else { + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, + DeleteTaskCommand.MESSAGE_USAGE)); + } + } + + /** + * Returns true if none of the prefixes contains empty {@code Optional} values in the given + * {@code ArgumentMultimap}. + */ + private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) { + return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent()); + } + +} diff --git a/src/main/java/seedu/address/logic/parser/DiaryAddCommandParser.java b/src/main/java/seedu/address/logic/parser/DiaryAddCommandParser.java new file mode 100644 index 00000000000..1f35b36cb96 --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/DiaryAddCommandParser.java @@ -0,0 +1,44 @@ +package seedu.address.logic.parser; + +import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.parser.CliSyntax.PREFIX_ENTRY_CONTENT; + +import java.util.stream.Stream; + +import seedu.address.logic.commands.diarycommand.DiaryAddCommand; +import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.diary.DiaryEntry; + +/** + * Dummy Java docs. + */ +public class DiaryAddCommandParser implements Parser { + + /** + * Dummy Java docs. + */ + public DiaryAddCommand parse(String args) throws ParseException { + ArgumentMultimap argMultimap = + ArgumentTokenizer.tokenize(args, PREFIX_ENTRY_CONTENT); + + if (!arePrefixesPresent(argMultimap, PREFIX_ENTRY_CONTENT) + || !argMultimap.getPreamble().isEmpty()) { + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, DiaryAddCommand.MESSAGE_USAGE)); + } + + String entryContent = argMultimap.getValue(PREFIX_ENTRY_CONTENT).get(); + + DiaryEntry diaryEntry = new DiaryEntry(entryContent); + + return new DiaryAddCommand(diaryEntry); + } + + /** + * Returns true if none of the prefixes contains empty {@code Optional} values in the given + * {@code ArgumentMultimap}. + */ + private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) { + return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent()); + } + +} diff --git a/src/main/java/seedu/address/logic/parser/DiaryDeleteCommandParser.java b/src/main/java/seedu/address/logic/parser/DiaryDeleteCommandParser.java new file mode 100644 index 00000000000..181a56670a3 --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/DiaryDeleteCommandParser.java @@ -0,0 +1,51 @@ +package seedu.address.logic.parser; + +import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.parser.CliSyntax.PREFIX_ENTRY_ID; + +import java.util.stream.Stream; + +import seedu.address.logic.commands.diarycommand.DiaryDeleteCommand; +import seedu.address.logic.parser.exceptions.ParseException; + +/** + * Dummy java docs + */ +public class DiaryDeleteCommandParser implements Parser { + + /** + * Dummy java docs. + * @param args + * @return + * @throws ParseException + */ + public DiaryDeleteCommand parse(String args) throws ParseException { + ArgumentMultimap argMultimap = + ArgumentTokenizer.tokenize(args, PREFIX_ENTRY_ID); + + if (!arePrefixesPresent(argMultimap, PREFIX_ENTRY_ID) + || !argMultimap.getPreamble().isEmpty()) { + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, DiaryDeleteCommand.MESSAGE_USAGE)); + } + + String entryIdString = argMultimap.getValue(PREFIX_ENTRY_ID).get(); + int entryId = 0; + + try { + entryId = Integer.parseInt(entryIdString); + } catch (NumberFormatException e) { + throw new ParseException("Please enter an integer!"); + } + + return new DiaryDeleteCommand(entryId); + } + + /** + * Returns true if none of the prefixes contains empty {@code Optional} values in the given + * {@code ArgumentMultimap}. + */ + private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) { + return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent()); + } + +} diff --git a/src/main/java/seedu/address/logic/parser/DiaryMoodCommandParser.java b/src/main/java/seedu/address/logic/parser/DiaryMoodCommandParser.java new file mode 100644 index 00000000000..eebe95d226b --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/DiaryMoodCommandParser.java @@ -0,0 +1,63 @@ +package seedu.address.logic.parser; + +import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.parser.CliSyntax.PREFIX_ENTRY_ID; +import static seedu.address.logic.parser.CliSyntax.PREFIX_MOOD; + +import java.util.stream.Stream; + +import seedu.address.commons.exceptions.IllegalValueException; +import seedu.address.logic.commands.diarycommand.DiaryMoodCommand; +import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.diary.mood.Mood; +import seedu.address.model.diary.mood.StressedMood; + +/** + * Dummy java docs. + */ +public class DiaryMoodCommandParser implements Parser { + + /** + * Dummy java docs. + * @param args + * @return + * @throws ParseException + */ + public DiaryMoodCommand parse(String args) throws ParseException { + ArgumentMultimap argMultimap = + ArgumentTokenizer.tokenize(args, PREFIX_ENTRY_ID, PREFIX_MOOD); + + if (!arePrefixesPresent(argMultimap, PREFIX_ENTRY_ID, PREFIX_MOOD) + || !argMultimap.getPreamble().isEmpty()) { + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, DiaryMoodCommand.MESSAGE_USAGE)); + } + + String entryIdString = argMultimap.getValue(PREFIX_ENTRY_ID).get(); + String moodString = argMultimap.getValue(PREFIX_MOOD).get(); + int entryId = 0; + Mood mood = new StressedMood(); + + try { + entryId = Integer.parseInt(entryIdString); + } catch (NumberFormatException e) { + throw new ParseException("Please enter an integer!"); + } + + try { + mood = new MoodParser().parseMood(moodString); + } catch (IllegalValueException e) { + throw new ParseException("Please enter a valid mood!"); + } + + return new DiaryMoodCommand(entryId, mood); + } + + /** + * Returns true if none of the prefixes contains empty {@code Optional} values in the given + * {@code ArgumentMultimap}. + */ + private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) { + return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent()); + } + +} diff --git a/src/main/java/seedu/address/logic/parser/DiaryShowCommandParser.java b/src/main/java/seedu/address/logic/parser/DiaryShowCommandParser.java new file mode 100644 index 00000000000..12f1178adae --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/DiaryShowCommandParser.java @@ -0,0 +1,76 @@ +package seedu.address.logic.parser; + +import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.parser.CliSyntax.PREFIX_DIARY_DATE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_ENTRY_ID; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.util.stream.Stream; + +import seedu.address.logic.commands.diarycommand.DiaryShowCommand; +import seedu.address.logic.commands.diarycommand.DiaryShowDateCommand; +import seedu.address.logic.commands.diarycommand.DiaryShowIdCommand; +import seedu.address.logic.parser.exceptions.ParseException; + + +/** + * Parses input arguments and creates a new DiaryShowCommand object + */ +public class DiaryShowCommandParser implements Parser { + + /** + * Parses the given {@code String} of arguments in the context of the DiaryShowCommand + * and returns an DiaryShowCommand object for execution. + * @throws ParseException if the user input does not conform the expected format + */ + public DiaryShowCommand parse(String args) throws ParseException { + ArgumentMultimap argMultimap1 = + ArgumentTokenizer.tokenize(args, PREFIX_ENTRY_ID); + + ArgumentMultimap argMultimap2 = + ArgumentTokenizer.tokenize(args, PREFIX_DIARY_DATE); + + if (arePrefixesPresent(argMultimap1, PREFIX_ENTRY_ID) + && argMultimap1.getPreamble().isEmpty()) { + + String entryIdString = argMultimap1.getValue(PREFIX_ENTRY_ID).get(); + int entryId = 0; + + try { + entryId = Integer.parseInt(entryIdString); + } catch (NumberFormatException e) { + throw new ParseException("Please enter an integer!"); + } + + return new DiaryShowIdCommand(entryId); + + } else if (arePrefixesPresent(argMultimap2, PREFIX_DIARY_DATE) + && argMultimap2.getPreamble().isEmpty()) { + + String dateString = argMultimap2.getValue(PREFIX_DIARY_DATE).get().trim(); + LocalDate date = LocalDate.now(); + + try { + date = LocalDate.parse(dateString, DateTimeFormatter.ofPattern("dd-MM-yyyy")); + } catch (DateTimeParseException e) { + throw new ParseException("Invalid date! format:{dd-mm-yyyy}"); + } + + return new DiaryShowDateCommand(date); + + } else { + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, + DiaryShowCommand.MESSAGE_USAGE)); + } + } + + /** + * Returns true if none of the prefixes contains empty {@code Optional} values in the given + * {@code ArgumentMultimap}. + */ + private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) { + return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent()); + } +} diff --git a/src/main/java/seedu/address/logic/parser/DiaryWeatherCommandParser.java b/src/main/java/seedu/address/logic/parser/DiaryWeatherCommandParser.java new file mode 100644 index 00000000000..fd7b50fbb9d --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/DiaryWeatherCommandParser.java @@ -0,0 +1,63 @@ +package seedu.address.logic.parser; + +import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.parser.CliSyntax.PREFIX_ENTRY_ID; +import static seedu.address.logic.parser.CliSyntax.PREFIX_WEATHER; + +import java.util.stream.Stream; + +import seedu.address.commons.exceptions.IllegalValueException; +import seedu.address.logic.commands.diarycommand.DiaryWeatherCommand; +import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.diary.weather.SunnyWeather; +import seedu.address.model.diary.weather.Weather; + +/** + * Dummy java docs. + */ +public class DiaryWeatherCommandParser implements Parser { + + /** + * Dummy java docs. + * @param args + * @return + * @throws ParseException + */ + public DiaryWeatherCommand parse(String args) throws ParseException { + ArgumentMultimap argMultimap = + ArgumentTokenizer.tokenize(args, PREFIX_ENTRY_ID, PREFIX_WEATHER); + + if (!arePrefixesPresent(argMultimap, PREFIX_ENTRY_ID, PREFIX_WEATHER) + || !argMultimap.getPreamble().isEmpty()) { + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, DiaryWeatherCommand.MESSAGE_USAGE)); + } + + String entryIdString = argMultimap.getValue(PREFIX_ENTRY_ID).get(); + String weatherString = argMultimap.getValue(PREFIX_WEATHER).get(); + int entryId = 0; + Weather weather = new SunnyWeather(); + + try { + entryId = Integer.parseInt(entryIdString); + } catch (NumberFormatException e) { + throw new ParseException("Please enter an integer!"); + } + + try { + weather = new WeatherParser().parseWeather(weatherString); + } catch (IllegalValueException e) { + throw new ParseException("Please enter a valid weather!"); + } + + return new DiaryWeatherCommand(entryId, weather); + } + + /** + * Returns true if none of the prefixes contains empty {@code Optional} values in the given + * {@code ArgumentMultimap}. + */ + private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) { + return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent()); + } + +} diff --git a/src/main/java/seedu/address/logic/parser/DoneCommandParser.java b/src/main/java/seedu/address/logic/parser/DoneCommandParser.java new file mode 100644 index 00000000000..457f3610033 --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/DoneCommandParser.java @@ -0,0 +1,58 @@ +package seedu.address.logic.parser; + +import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.parser.CliSyntax.PREFIX_MODULE_CODE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_TASK_INDEX; + +import java.util.stream.Stream; + +import seedu.address.commons.core.index.Index; +import seedu.address.logic.commands.taskcommand.donecommand.DoneCommand; +import seedu.address.logic.commands.taskcommand.donecommand.DoneDeadlineCommand; +import seedu.address.logic.commands.taskcommand.donecommand.DoneModuleTaskCommand; +import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.calender.Task; +import seedu.address.model.nusmodule.ModuleCode; + +/** + * Parses input arguments and creates a new DoneCommand object + */ +public class DoneCommandParser implements Parser { + + /** + * Parses the given {@code String} of arguments in the context of the AddCommand + * and returns an AddCommand object for execution. + * @throws ParseException if the user input does not conform the expected format + */ + public DoneCommand parse(String args) throws ParseException { + ArgumentMultimap argMultimap1 = + ArgumentTokenizer.tokenize(args, PREFIX_TASK_INDEX); + + ArgumentMultimap argMultimap2 = + ArgumentTokenizer.tokenize(args, PREFIX_MODULE_CODE, PREFIX_TASK_INDEX); + + if (arePrefixesPresent(argMultimap1, PREFIX_TASK_INDEX) + && argMultimap1.getPreamble().isEmpty()) { + Task deadline = ParserUtil.parseRemoveDeadline(argMultimap1.getValue(PREFIX_TASK_INDEX).get()); + return new DoneDeadlineCommand(deadline); + } else if (arePrefixesPresent(argMultimap2, PREFIX_MODULE_CODE, PREFIX_TASK_INDEX) + && argMultimap2.getPreamble().isEmpty()) { + ModuleCode moduleCode = ParserUtil.parseModuleCode( + argMultimap2.getValue(PREFIX_MODULE_CODE).get()); + Index index = ParserUtil.parseIndex(argMultimap2.getValue(PREFIX_TASK_INDEX).get()); + return new DoneModuleTaskCommand(moduleCode, index); + } else { + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, + DoneCommand.MESSAGE_USAGE)); + } + } + + /** + * Returns true if none of the prefixes contains empty {@code Optional} values in the given + * {@code ArgumentMultimap}. + */ + private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) { + return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent()); + } + +} diff --git a/src/main/java/seedu/address/logic/parser/EditCommandParser.java b/src/main/java/seedu/address/logic/parser/EditCommandParser.java index 845644b7dea..bdfe5ad1978 100644 --- a/src/main/java/seedu/address/logic/parser/EditCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/EditCommandParser.java @@ -2,7 +2,6 @@ import static java.util.Objects.requireNonNull; import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; -import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS; import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL; import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE; @@ -32,7 +31,7 @@ public class EditCommandParser implements Parser { public EditCommand parse(String args) throws ParseException { requireNonNull(args); ArgumentMultimap argMultimap = - ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS, PREFIX_TAG); + ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_TAG); Index index; @@ -52,9 +51,6 @@ public EditCommand parse(String args) throws ParseException { if (argMultimap.getValue(PREFIX_EMAIL).isPresent()) { editPersonDescriptor.setEmail(ParserUtil.parseEmail(argMultimap.getValue(PREFIX_EMAIL).get())); } - if (argMultimap.getValue(PREFIX_ADDRESS).isPresent()) { - editPersonDescriptor.setAddress(ParserUtil.parseAddress(argMultimap.getValue(PREFIX_ADDRESS).get())); - } parseTagsForEdit(argMultimap.getAllValues(PREFIX_TAG)).ifPresent(editPersonDescriptor::setTags); if (!editPersonDescriptor.isAnyFieldEdited()) { diff --git a/src/main/java/seedu/address/logic/parser/FindTasksCommandParser.java b/src/main/java/seedu/address/logic/parser/FindTasksCommandParser.java new file mode 100644 index 00000000000..3973c4ad080 --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/FindTasksCommandParser.java @@ -0,0 +1,79 @@ +package seedu.address.logic.parser; + +import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.parser.CliSyntax.PREFIX_MODULETASK_TIMING; +import static seedu.address.logic.parser.CliSyntax.PREFIX_MODULE_CODE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_TASK_CAT; + +import java.util.Arrays; +import java.util.stream.Stream; + +import seedu.address.logic.commands.taskcommand.findcommand.FindTasksByCatCommand; +import seedu.address.logic.commands.taskcommand.findcommand.FindTasksByDateCommand; +import seedu.address.logic.commands.taskcommand.findcommand.FindTasksByModuleCodeCommand; +import seedu.address.logic.commands.taskcommand.findcommand.FindTasksCommand; +import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.calender.CatContainsKeywordsPredicate; +import seedu.address.model.calender.DateContainKeywordsPredicate; +import seedu.address.model.calender.Deadline; +import seedu.address.model.calender.ModuleCodeContainKeywordsPredicate; +import seedu.address.model.nusmodule.ModuleCode; + +/** + * Parses input arguments and creates a new FindTasksCommand object + */ +public class FindTasksCommandParser implements Parser { + + /** + * Parses the given {@code String} of arguments in the context of the AddCommand + * and returns an AddCommand object for execution. + * + * @throws ParseException if the user input does not conform the expected format + */ + public FindTasksCommand parse(String args) throws ParseException { + ArgumentMultimap argMultimap1 = + ArgumentTokenizer.tokenize(args, PREFIX_MODULE_CODE); + + ArgumentMultimap argMultimap2 = + ArgumentTokenizer.tokenize(args, PREFIX_MODULETASK_TIMING); + + ArgumentMultimap argMultimap3 = + ArgumentTokenizer.tokenize(args, PREFIX_TASK_CAT); + + if (arePrefixesPresent(argMultimap1, PREFIX_MODULE_CODE) + && argMultimap1.getPreamble().isEmpty()) { + + ModuleCode moduleCode = ParserUtil.parseModuleCode(argMultimap1.getValue(PREFIX_MODULE_CODE).get()); + return new FindTasksByModuleCodeCommand( + new ModuleCodeContainKeywordsPredicate(Arrays.asList(moduleCode.toString()))); + + } else if (arePrefixesPresent(argMultimap2, PREFIX_MODULETASK_TIMING) + && argMultimap2.getPreamble().isEmpty()) { + + String date = argMultimap2.getValue(PREFIX_MODULETASK_TIMING).get().trim(); + if (Deadline.isValidDate(date)) { + return new FindTasksByDateCommand(new DateContainKeywordsPredicate(Arrays.asList(date))); + } else { + throw new ParseException("Invalid date! format:{dd-mm-yyyy}"); + } + + } else if (arePrefixesPresent(argMultimap3, PREFIX_TASK_CAT) + && argMultimap3.getPreamble().isEmpty()) { + + String cat = argMultimap3.getValue(PREFIX_TASK_CAT).get().trim(); + return new FindTasksByCatCommand(new CatContainsKeywordsPredicate(Arrays.asList(cat))); + + } else { + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, + FindTasksCommand.MESSAGE_USAGE)); + } + } + + /** + * Returns true if none of the prefixes contains empty {@code Optional} values in the given + * {@code ArgumentMultimap}. + */ + private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) { + return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent()); + } +} diff --git a/src/main/java/seedu/address/logic/parser/GradeCommandParser.java b/src/main/java/seedu/address/logic/parser/GradeCommandParser.java new file mode 100644 index 00000000000..848d63ec237 --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/GradeCommandParser.java @@ -0,0 +1,53 @@ +package seedu.address.logic.parser; + +import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.parser.CliSyntax.PREFIX_GRADE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_MODULE_CODE; + +import java.util.stream.Stream; + +import seedu.address.logic.commands.modulecommand.GradeCommand; +import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.nusmodule.Grade; +import seedu.address.model.nusmodule.ModuleCode; +import seedu.address.searcher.Module; +import seedu.address.searcher.Search; + +/** + * Parses input arguments and creates a new GradeCommand object + */ +public class GradeCommandParser implements Parser { + + /** + * Parses the given {@code String} of arguments in the context of the GradeCommand + * and returns an GradeCommand object for execution. + * @throws ParseException if the user input does not conform the expected format + */ + public GradeCommand parse(String args) throws ParseException { + ArgumentMultimap argMultimap = + ArgumentTokenizer.tokenize(args, PREFIX_MODULE_CODE, PREFIX_GRADE); + + if (!arePrefixesPresent(argMultimap, PREFIX_MODULE_CODE, PREFIX_GRADE) + || !argMultimap.getPreamble().isEmpty()) { + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, GradeCommand.MESSAGE_USAGE)); + } + + ModuleCode moduleCode = ParserUtil.parseModuleCode( + argMultimap.getValue(PREFIX_MODULE_CODE).get()); + Module moduleInfo = Search.findModule(moduleCode.toString()); + int moduleCredit = moduleInfo.getCredits(); + + Grade grade = ParserUtil.parseGrade(argMultimap.getValue(PREFIX_GRADE).get()); + + return new GradeCommand(moduleCode, grade); + } + + /** + * Returns true if none of the prefixes contains empty {@code Optional} values in the given + * {@code ArgumentMultimap}. + */ + private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) { + return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent()); + } + +} diff --git a/src/main/java/seedu/address/logic/parser/ListModuleTaskCommandParser.java b/src/main/java/seedu/address/logic/parser/ListModuleTaskCommandParser.java new file mode 100644 index 00000000000..0437c3afe93 --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/ListModuleTaskCommandParser.java @@ -0,0 +1,27 @@ +package seedu.address.logic.parser; + +import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; + +import seedu.address.logic.commands.taskcommand.listcommand.ListModuleTaskCommand; +import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.nusmodule.ModuleCode; + +/** + * Parses input arguments and creates a new ListModuleTaskCommand object + */ +public class ListModuleTaskCommandParser implements Parser { + /** + * Parses the given {@code String} of arguments in the context of the ListModuleTaskCommand + * and returns a ListModuleTaskCommand object for execution. + * @throws ParseException if the user input does not conform the expected format + */ + public ListModuleTaskCommand parse(String args) throws ParseException { + try { + ModuleCode moduleCode = ParserUtil.parseModuleCode(args); + return new ListModuleTaskCommand(moduleCode); + } catch (ParseException pe) { + throw new ParseException( + String.format(MESSAGE_INVALID_COMMAND_FORMAT, ListModuleTaskCommand.MESSAGE_USAGE), pe); + } + } +} diff --git a/src/main/java/seedu/address/logic/parser/MajorCommandParser.java b/src/main/java/seedu/address/logic/parser/MajorCommandParser.java new file mode 100644 index 00000000000..80d606ac60a --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/MajorCommandParser.java @@ -0,0 +1,31 @@ +package seedu.address.logic.parser; + +import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; + +import seedu.address.logic.commands.MajorCommand; +import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.nusmodule.Major; + +/** + * Parses input arguments and creates a new MajorCommand object + */ +public class MajorCommandParser implements Parser { + + /** + * Parses the given {@code String} of arguments in the context of the FindCommand + * and returns a FindCommand object for execution. + * + * @throws ParseException if the user input does not conform the expected format + */ + public MajorCommand parse(String args) throws ParseException { + String trimmedArgs = args.trim(); + if (trimmedArgs.isEmpty()) { + throw new ParseException( + String.format(MESSAGE_INVALID_COMMAND_FORMAT, MajorCommand.MESSAGE_USAGE)); + } + + Major major = ParserUtil.parseMajor(trimmedArgs); + + return new MajorCommand(major); + } +} diff --git a/src/main/java/seedu/address/logic/parser/ModuleTaskCommandParser.java b/src/main/java/seedu/address/logic/parser/ModuleTaskCommandParser.java new file mode 100644 index 00000000000..9a094556c01 --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/ModuleTaskCommandParser.java @@ -0,0 +1,59 @@ +package seedu.address.logic.parser; + +import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.commons.core.Messages.MESSAGE_INVALID_DATE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_MODULETASK_TIMING; +import static seedu.address.logic.parser.CliSyntax.PREFIX_MODULE_CODE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_PRIORITY; +import static seedu.address.logic.parser.CliSyntax.PREFIX_TASK_DESC; + +import java.util.stream.Stream; + +import seedu.address.logic.commands.taskcommand.addcommand.ModuleTaskCommand; +import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.calender.Task; +import seedu.address.model.nusmodule.ModuleCode; +import seedu.address.model.nusmodule.ModuleTask; +import seedu.address.model.nusmodule.Priority; + +/** + * Parses input arguments and creates a new ModuleTaskCommand object + */ +public class ModuleTaskCommandParser implements Parser { + /** + * Parses the given {@code String} of arguments in the context of the ModuleTaskCommand + * and returns an ModuleTaskCommand object for execution. + * @throws ParseException if the user input does not conform the expected format + */ + public ModuleTaskCommand parse(String args) throws ParseException { + ArgumentMultimap argMultimap = + ArgumentTokenizer.tokenize(args, PREFIX_TASK_DESC, PREFIX_MODULE_CODE, + PREFIX_MODULETASK_TIMING, PREFIX_PRIORITY); + + if (!arePrefixesPresent(argMultimap, PREFIX_TASK_DESC, PREFIX_MODULE_CODE, + PREFIX_MODULETASK_TIMING, PREFIX_PRIORITY) + || !argMultimap.getPreamble().isEmpty()) { + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, ModuleTaskCommand.MESSAGE_USAGE)); + } + + String trimmedDesc = argMultimap.getValue(PREFIX_TASK_DESC).get().trim(); + ModuleCode moduleCode = ParserUtil.parseModuleCode( + argMultimap.getValue(PREFIX_MODULE_CODE).get()); + String timing = argMultimap.getValue(PREFIX_MODULETASK_TIMING).get(); + if (!Task.isValidDate(timing)) { + throw new ParseException(String.format(MESSAGE_INVALID_DATE, ModuleTaskCommand.MESSAGE_USAGE)); + } + Priority p = ParserUtil.parsePriority(argMultimap.getValue(PREFIX_PRIORITY).get()); + ModuleTask moduleTask = new ModuleTask(trimmedDesc, moduleCode, timing, p); + + return new ModuleTaskCommand(moduleTask); + } + + /** + * Returns true if none of the prefixes contains empty {@code Optional} values in the given + * {@code ArgumentMultimap}. + */ + private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) { + return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent()); + } +} diff --git a/src/main/java/seedu/address/logic/parser/MoodParser.java b/src/main/java/seedu/address/logic/parser/MoodParser.java new file mode 100644 index 00000000000..62665533e7e --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/MoodParser.java @@ -0,0 +1,37 @@ +package seedu.address.logic.parser; + +import java.util.HashMap; + +import seedu.address.commons.exceptions.IllegalValueException; +import seedu.address.model.diary.mood.CalmMood; +import seedu.address.model.diary.mood.HappyMood; +import seedu.address.model.diary.mood.Mood; +import seedu.address.model.diary.mood.SadMood; +import seedu.address.model.diary.mood.StressedMood; + +/** + * Dummy java docs. + */ +public class MoodParser { + private static HashMap moodParser = new HashMap<>(); + + static { + moodParser.put("calm", new CalmMood()); + moodParser.put("happy", new HappyMood()); + moodParser.put("sad", new SadMood()); + moodParser.put("stressed", new StressedMood()); + } + + /** + * Dummy java docs. + * @param moodString + * @return + * @throws IllegalValueException + */ + public Mood parseMood(String moodString) throws IllegalValueException { + if (moodParser.get(moodString) == null) { + throw new IllegalValueException("Please enter a valid mood!"); + } + return moodParser.get(moodString); + } +} diff --git a/src/main/java/seedu/address/logic/parser/NotesCreateCommandParser.java b/src/main/java/seedu/address/logic/parser/NotesCreateCommandParser.java new file mode 100644 index 00000000000..8612d744dd2 --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/NotesCreateCommandParser.java @@ -0,0 +1,53 @@ +package seedu.address.logic.parser; + +import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.parser.CliSyntax.PREFIX_NOTES_FILE_NAME; +import static seedu.address.logic.parser.CliSyntax.PREFIX_NOTES_PATH; +import static seedu.address.logic.parser.CliSyntax.PREFIX_NOTES_PATH_TYPE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_NOTES_TYPE; + +import java.io.File; +import java.util.stream.Stream; + +import seedu.address.logic.commands.NotesCreateCommand; +import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.notes.Notes; + +/** + * Parses input arguments and creates a new NotesCommand object + */ +public class NotesCreateCommandParser implements Parser { + + /** + * Parses the given {@code String} of arguments in the context of the NotesCommand + * and returns an NotesCommand object for execution. + * @throws ParseException if the user input does not conform the expected format + */ + public NotesCreateCommand parse(String args) throws ParseException { + ArgumentMultimap argMultimap = + ArgumentTokenizer.tokenize(args, PREFIX_NOTES_PATH, PREFIX_NOTES_PATH_TYPE, + PREFIX_NOTES_TYPE, PREFIX_NOTES_FILE_NAME); + + if (!arePrefixesPresent(argMultimap, PREFIX_NOTES_PATH, PREFIX_NOTES_PATH_TYPE, + PREFIX_NOTES_TYPE, PREFIX_NOTES_FILE_NAME) + || !argMultimap.getPreamble().isEmpty()) { + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, NotesCreateCommand.MESSAGE_USAGE)); + } + String fullPathName = argMultimap.getValue(PREFIX_NOTES_PATH).get() + File.separator + + argMultimap.getValue(PREFIX_NOTES_FILE_NAME).get(); + Notes note = ParserUtil.parseNotesCreateOperation(fullPathName , + argMultimap.getValue(PREFIX_NOTES_TYPE).get(), + argMultimap.getValue(PREFIX_NOTES_PATH_TYPE).get()); + + return new NotesCreateCommand(note); + } + + /** + * Returns true if none of the prefixes contains empty {@code Optional} values in the given + * {@code ArgumentMultimap}. + */ + private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) { + return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent()); + } + +} diff --git a/src/main/java/seedu/address/logic/parser/NotesDeleteCommandParser.java b/src/main/java/seedu/address/logic/parser/NotesDeleteCommandParser.java new file mode 100644 index 00000000000..8a7600ec236 --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/NotesDeleteCommandParser.java @@ -0,0 +1,50 @@ +package seedu.address.logic.parser; + +import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.parser.CliSyntax.PREFIX_NOTES_FILE_NAME; +import static seedu.address.logic.parser.CliSyntax.PREFIX_NOTES_PATH; +import static seedu.address.logic.parser.CliSyntax.PREFIX_NOTES_PATH_TYPE; + +import java.io.File; +import java.util.stream.Stream; + +import seedu.address.logic.commands.NotesDeleteCommand; +import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.notes.Notes; + +/** + * Parses input arguments and creates a new NotesCommand object + */ +public class NotesDeleteCommandParser implements Parser { + + /** + * Parses the given {@code String} of arguments in the context of the NotesCommand + * and returns an NotesCommand object for execution. + * @throws ParseException if the user input does not conform the expected format + */ + public NotesDeleteCommand parse(String args) throws ParseException { + ArgumentMultimap argMultimap = + ArgumentTokenizer.tokenize(args, PREFIX_NOTES_PATH, PREFIX_NOTES_PATH_TYPE, PREFIX_NOTES_FILE_NAME); + + if (!arePrefixesPresent(argMultimap, PREFIX_NOTES_PATH, PREFIX_NOTES_PATH_TYPE, PREFIX_NOTES_FILE_NAME) + || !argMultimap.getPreamble().isEmpty()) { + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, NotesDeleteCommand.MESSAGE_USAGE)); + } + String fullPathName = argMultimap.getValue(PREFIX_NOTES_PATH).get() + File.separator + + argMultimap.getValue(PREFIX_NOTES_FILE_NAME).get(); + + Notes note = ParserUtil.parseNotesDeleteOperation(fullPathName, + argMultimap.getValue(PREFIX_NOTES_PATH_TYPE).get()); + + return new NotesDeleteCommand(note); + } + + /** + * Returns true if none of the prefixes contains empty {@code Optional} values in the given + * {@code ArgumentMultimap}. + */ + private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) { + return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent()); + } + +} diff --git a/src/main/java/seedu/address/logic/parser/NotesListCommandParser.java b/src/main/java/seedu/address/logic/parser/NotesListCommandParser.java new file mode 100644 index 00000000000..aa240841b86 --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/NotesListCommandParser.java @@ -0,0 +1,46 @@ +package seedu.address.logic.parser; + +import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.parser.CliSyntax.PREFIX_NOTES_PATH; +import static seedu.address.logic.parser.CliSyntax.PREFIX_NOTES_PATH_TYPE; + +import java.util.stream.Stream; + +import seedu.address.logic.commands.NotesListCommand; +import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.notes.Notes; + +/** + * Parses input arguments and creates a new NotesCommand object + */ +public class NotesListCommandParser implements Parser { + + /** + * Parses the given {@code String} of arguments in the context of the NotesCommand + * and returns an NotesCommand object for execution. + * @throws ParseException if the user input does not conform the expected format + */ + public NotesListCommand parse(String args) throws ParseException { + ArgumentMultimap argMultimap = + ArgumentTokenizer.tokenize(args, PREFIX_NOTES_PATH, PREFIX_NOTES_PATH_TYPE); + + if (!arePrefixesPresent(argMultimap, PREFIX_NOTES_PATH, PREFIX_NOTES_PATH_TYPE) + || !argMultimap.getPreamble().isEmpty()) { + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, NotesListCommand.MESSAGE_USAGE)); + } + + Notes note = ParserUtil.parseNotesListOperation(argMultimap.getValue(PREFIX_NOTES_PATH).get(), + argMultimap.getValue(PREFIX_NOTES_PATH_TYPE).get()); + + return new NotesListCommand(note); + } + + /** + * Returns true if none of the prefixes contains empty {@code Optional} values in the given + * {@code ArgumentMultimap}. + */ + private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) { + return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent()); + } + +} diff --git a/src/main/java/seedu/address/logic/parser/NotesOpenCommandParser.java b/src/main/java/seedu/address/logic/parser/NotesOpenCommandParser.java new file mode 100644 index 00000000000..a0bb7c4a653 --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/NotesOpenCommandParser.java @@ -0,0 +1,49 @@ +package seedu.address.logic.parser; + +import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.parser.CliSyntax.PREFIX_NOTES_FILE_NAME; +import static seedu.address.logic.parser.CliSyntax.PREFIX_NOTES_PATH; +import static seedu.address.logic.parser.CliSyntax.PREFIX_NOTES_PATH_TYPE; + +import java.io.File; +import java.util.stream.Stream; + +import seedu.address.logic.commands.NotesOpenCommand; +import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.notes.Notes; + +/** + * Parses input arguments and creates a new NotesCommand object + */ +public class NotesOpenCommandParser implements Parser { + + /** + * Parses the given {@code String} of arguments in the context of the NotesCommand + * and returns an NotesCommand object for execution. + * @throws ParseException if the user input does not conform the expected format + */ + public NotesOpenCommand parse(String args) throws ParseException { + ArgumentMultimap argMultimap = + ArgumentTokenizer.tokenize(args, PREFIX_NOTES_PATH, PREFIX_NOTES_FILE_NAME, PREFIX_NOTES_PATH_TYPE); + + if (!arePrefixesPresent(argMultimap, PREFIX_NOTES_PATH, PREFIX_NOTES_PATH_TYPE, PREFIX_NOTES_FILE_NAME) + || !argMultimap.getPreamble().isEmpty()) { + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, NotesOpenCommand.MESSAGE_USAGE)); + } + String fullPathName = argMultimap.getValue(PREFIX_NOTES_PATH).get() + File.separator + + argMultimap.getValue(PREFIX_NOTES_FILE_NAME).get(); + Notes note = ParserUtil.parseNotesOpenOperation(fullPathName, + argMultimap.getValue(PREFIX_NOTES_PATH_TYPE).get()); + + return new NotesOpenCommand(note); + } + + /** + * Returns true if none of the prefixes contains empty {@code Optional} values in the given + * {@code ArgumentMultimap}. + */ + private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) { + return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent()); + } + +} diff --git a/src/main/java/seedu/address/logic/parser/ParserUtil.java b/src/main/java/seedu/address/logic/parser/ParserUtil.java index b117acb9c55..c8a0a515ffa 100644 --- a/src/main/java/seedu/address/logic/parser/ParserUtil.java +++ b/src/main/java/seedu/address/logic/parser/ParserUtil.java @@ -9,7 +9,15 @@ import seedu.address.commons.core.index.Index; import seedu.address.commons.util.StringUtil; import seedu.address.logic.parser.exceptions.ParseException; -import seedu.address.model.person.Address; + +import seedu.address.model.calender.Deadline; +import seedu.address.model.calender.Task; +import seedu.address.model.calender.ToDo; +import seedu.address.model.notes.Notes; +import seedu.address.model.nusmodule.Grade; +import seedu.address.model.nusmodule.Major; +import seedu.address.model.nusmodule.ModuleCode; +import seedu.address.model.nusmodule.Priority; import seedu.address.model.person.Email; import seedu.address.model.person.Name; import seedu.address.model.person.Phone; @@ -65,21 +73,6 @@ public static Phone parsePhone(String phone) throws ParseException { return new Phone(trimmedPhone); } - /** - * Parses a {@code String address} into an {@code Address}. - * Leading and trailing whitespaces will be trimmed. - * - * @throws ParseException if the given {@code address} is invalid. - */ - public static Address parseAddress(String address) throws ParseException { - requireNonNull(address); - String trimmedAddress = address.trim(); - if (!Address.isValidAddress(trimmedAddress)) { - throw new ParseException(Address.MESSAGE_CONSTRAINTS); - } - return new Address(trimmedAddress); - } - /** * Parses a {@code String email} into an {@code Email}. * Leading and trailing whitespaces will be trimmed. @@ -121,4 +114,189 @@ public static Set parseTags(Collection tags) throws ParseException } return tagSet; } + + + /** + * Parses a {@code String path, @code String pathType} into a {@code Notes}. + * Leading and trailing whitespaces will be trimmed. + * @param path path and filename to be created + * @param pathType path type, absolute or relative. + * @return a new note object. + * @throws ParseException when the given {@code notesListoperation} is invalid. + */ + public static Notes parseNotesListOperation(String path, String pathType) throws ParseException { + requireNonNull(path, pathType); + String trimmedPath = path.trim(); + String trimmedPathType = pathType.trim(); + if (!Notes.isValidPathType(trimmedPathType)) { + throw new ParseException(Notes.MESSAGE_CONSTRAINTS_PATH_TYPE); + } + return new Notes(trimmedPath, trimmedPathType); + } + + /** + * Parses a {@code String path, @code String pathType} into a {@code Notes}. + * Leading and trailing whitespaces will be trimmed. + * @param path path and filename to be created + * @param pathType path type, absolute or relative. + * @return a new note object. + * @throws ParseException when the given {@code notesListoperation} is invalid. + */ + public static Notes parseNotesCreateOperation(String path, String type, String pathType) throws ParseException { + requireNonNull(path, pathType); + requireNonNull(type); + String trimmedPath = path.trim(); + String trimmedPathType = pathType.trim(); + String trimmedType = type.trim(); + if (!Notes.isValidPathType(trimmedPathType)) { + throw new ParseException(Notes.MESSAGE_CONSTRAINTS_PATH_TYPE); + } + if (!Notes.isValidType(trimmedType)) { + throw new ParseException(Notes.MESSAGE_CONSTRAINTS_TYPE); + } + return new Notes(trimmedPath, trimmedType, trimmedPathType); + } + + /** + * Parses a {@code String path, @code String pathType} into a {@code Notes}. + * Leading and trailing whitespaces will be trimmed. + * @param path path and filename to be created + * @param pathType path type, absolute or relative. + * @return a new note object. + * @throws ParseException when the given {@code notesOpenoperation} is invalid. + */ + public static Notes parseNotesOpenOperation(String path, String pathType) throws ParseException { + requireNonNull(path, pathType); + String trimmedPath = path.trim(); + String trimmedPathType = pathType.trim(); + if (!Notes.isValidPathType(trimmedPathType)) { + throw new ParseException(Notes.MESSAGE_CONSTRAINTS_PATH_TYPE); + } + + return new Notes(trimmedPath, trimmedPathType); + } + + /** + * Parses a {@code String path, @code String pathType} into a {@code Notes}. + * Leading and trailing whitespaces will be trimmed. + * @param path path and filename to be created + * @param pathType path type, absolute or relative. + * @return a new note object. + * @throws ParseException when the given {@code notesOpenoperation} is invalid. + */ + public static Notes parseNotesDeleteOperation(String path, String pathType) throws ParseException { + requireNonNull(path, pathType); + String trimmedPath = path.trim(); + String trimmedPathType = pathType.trim(); + if (!Notes.isValidPathType(trimmedPathType)) { + throw new ParseException(Notes.MESSAGE_CONSTRAINTS_PATH_TYPE); + } + + return new Notes(trimmedPath, trimmedPathType); + } + + /** + * Parses a {@code String moduleCode} into an {@code ModuleCode}. + * Leading and trailing whitespaces will be trimmed. + * + * @throws ParseException if the given {@code moduleCode} is invalid. + */ + public static ModuleCode parseModuleCode(String moduleCode) throws ParseException { + requireNonNull(moduleCode); + String trimmedModuleCode = moduleCode.trim().toUpperCase(); + if (!ModuleCode.isValidModuleCode(trimmedModuleCode)) { + throw new ParseException(ModuleCode.MESSAGE_CONSTRAINTS); + } + return new ModuleCode(trimmedModuleCode); + } + + /** + * Parses a {@code String grade} into an {@code Grade}. + * Leading and trailing whitespaces will be trimmed. + * + * @throws ParseException if the given {@code grade} is invalid. + */ + public static Grade parseGrade(String grade) throws ParseException { + requireNonNull(grade); + String trimmedGrade = grade.trim().toUpperCase(); + if (!Grade.isValidGrade(trimmedGrade)) { + throw new ParseException(Grade.MESSAGE_CONSTRAINTS); + } + return Grade.getGrade(trimmedGrade); + } + + /** + * Parses a {@code String priority} into an {@code Priority}. + * Leading and trailing whitespaces will be trimmed. + * + * @throws ParseException if the given {@code priority} is invalid. + */ + public static Priority parsePriority(String priority) throws ParseException { + requireNonNull(priority); + String trimmedPriority = priority.trim().toUpperCase(); + if (!Priority.isValidPriority(trimmedPriority)) { + throw new ParseException(Priority.MESSAGE_CONSTRAINTS); + } + return Priority.getPriority(trimmedPriority); + } + + /** + * Parses a {@code String major} into an {@code Major}. + * Leading and trailing whitespaces will be trimmed. + * + * @throws ParseException if the given {@code Major} is invalid. + */ + public static Major parseMajor(String major) throws ParseException { + requireNonNull(major); + String trimmedMajor = major.trim(); + if (!Major.isValidMajor(trimmedMajor)) { + throw new ParseException(Major.MESSAGE_CONSTRAINTS); + } + return new Major(trimmedMajor); + } + + /** + * Parses a {@code String description, @code String date} into an {@code Deadline}. + * Leading and trailing whitespaces will be trimmed. + * + * @throws ParseException if the given {@code date} is invalid. + */ + public static Task parseDeadline(String description, String date, String category) throws ParseException { + requireNonNull(description, date); + String trimmedDescription = description.trim(); + String trimmedDate = date.trim(); + String trimmedCategory = category.trim(); + if (!Deadline.isValidDate(trimmedDate)) { + throw new ParseException(Deadline.MESSAGE_CONSTRAINTS); + } + return new Deadline(trimmedDescription, trimmedDate, trimmedCategory, "add"); + } + + /** + * Parses a {@code String description, @code String date} into an {@code Deadline}. + * Leading and trailing whitespaces will be trimmed. + * + * @throws ParseException if the given {@code date} is invalid. + */ + public static Task parseRemoveDeadline(String index) throws ParseException { + requireNonNull(index); + int indexInt = Integer.parseInt(index.trim()); + return new Deadline(indexInt, "delete"); + } + + /** + * Parses a {@code String Description} into an {@code Todo}. + * Leading and trailing whitespaces will be trimmed. + * + * @throws ParseException + */ + public static Task parseTodo(String description) throws ParseException { + requireNonNull(description); + String trimmedDescription = description.trim(); + return new ToDo(trimmedDescription); + } + + + + } diff --git a/src/main/java/seedu/address/logic/parser/SearchCommandParser.java b/src/main/java/seedu/address/logic/parser/SearchCommandParser.java new file mode 100644 index 00000000000..6d7d1af5c4f --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/SearchCommandParser.java @@ -0,0 +1,27 @@ +package seedu.address.logic.parser; + +import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; + +import seedu.address.logic.commands.SearchCommand; +import seedu.address.logic.parser.exceptions.ParseException; + +/** + *

SearchCommandParserClass

+ * Simple Parser for Search Command + */ +public class SearchCommandParser implements Parser { + /** + * Search Command Parser + * @param args String of Module Code + * @return Search Command Object + * @throws ParseException Incase you type wrong + */ + public SearchCommand parse(String args) throws ParseException { + if (args.isEmpty()) { + throw new ParseException( + String.format(MESSAGE_INVALID_COMMAND_FORMAT, SearchCommand.SYNTAX_FAILURE)); + } + + return new SearchCommand(args.trim()); + } +} diff --git a/src/main/java/seedu/address/logic/parser/SortTasksCommandParser.java b/src/main/java/seedu/address/logic/parser/SortTasksCommandParser.java new file mode 100644 index 00000000000..bdf9626fdd4 --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/SortTasksCommandParser.java @@ -0,0 +1,46 @@ +package seedu.address.logic.parser; + +import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.commons.core.Messages.MESSAGE_INVALID_SORTING_PARAM; +import static seedu.address.logic.parser.CliSyntax.PREFIX_SORTING; + +import java.util.stream.Stream; + +import seedu.address.logic.commands.taskcommand.sortcommand.SortTasksCommand; +import seedu.address.logic.parser.exceptions.ParseException; + +/** + * Parses input arguments and creates a new SortTasksCommand object + */ +public class SortTasksCommandParser implements Parser { + /** + * Parses the given {@code String} of arguments in the context of the ModuleTaskCommand + * and returns an ModuleTaskCommand object for execution. + * @throws ParseException if the user input does not conform the expected format + */ + public SortTasksCommand parse(String args) throws ParseException { + ArgumentMultimap argMultimap = + ArgumentTokenizer.tokenize(args, PREFIX_SORTING); + + if (!arePrefixesPresent(argMultimap, PREFIX_SORTING) + || !argMultimap.getPreamble().isEmpty()) { + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, SortTasksCommand.MESSAGE_USAGE)); + } + + String sortingParam = argMultimap.getValue(PREFIX_SORTING).get().trim(); + if (!sortingParam.equals("priority") && !sortingParam.equals("date")) { + throw new ParseException(MESSAGE_INVALID_SORTING_PARAM + " " + SortTasksCommand.MESSAGE_USAGE); + } + + return new SortTasksCommand(sortingParam); + } + + /** + * Returns true if none of the prefixes contains empty {@code Optional} values in the given + * {@code ArgumentMultimap}. + */ + private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) { + return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent()); + } + +} diff --git a/src/main/java/seedu/address/logic/parser/WeatherParser.java b/src/main/java/seedu/address/logic/parser/WeatherParser.java new file mode 100644 index 00000000000..fa5052d722a --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/WeatherParser.java @@ -0,0 +1,37 @@ +package seedu.address.logic.parser; + +import java.util.HashMap; + +import seedu.address.commons.exceptions.IllegalValueException; +import seedu.address.model.diary.weather.CloudyWeather; +import seedu.address.model.diary.weather.RainyWeather; +import seedu.address.model.diary.weather.SunnyWeather; +import seedu.address.model.diary.weather.Weather; +import seedu.address.model.diary.weather.WindyWeather; + +/** + * Dummy java docs. + */ +public class WeatherParser { + private static HashMap weatherIdentifiers = new HashMap<>(); + + static { + weatherIdentifiers.put("cloudy", new CloudyWeather()); + weatherIdentifiers.put("rainy", new RainyWeather()); + weatherIdentifiers.put("sunny", new SunnyWeather()); + weatherIdentifiers.put("windy", new WindyWeather()); + } + + /** + * Dummy java docs. + * @param weatherString + * @return + * @throws IllegalValueException + */ + public Weather parseWeather(String weatherString) throws IllegalValueException { + if (weatherIdentifiers.get(weatherString) == null) { + throw new IllegalValueException("Please enter a valid weather!"); + } + return weatherIdentifiers.get(weatherString); + } +} diff --git a/src/main/java/seedu/address/model/AddressBook.java b/src/main/java/seedu/address/model/AddressBook.java index 1a943a0781a..216643a6828 100644 --- a/src/main/java/seedu/address/model/AddressBook.java +++ b/src/main/java/seedu/address/model/AddressBook.java @@ -2,9 +2,14 @@ import static java.util.Objects.requireNonNull; +import java.util.ArrayList; import java.util.List; +import javafx.collections.FXCollections; import javafx.collections.ObservableList; +import seedu.address.model.calender.Task; +import seedu.address.model.diary.DiaryBook; +import seedu.address.model.diary.DiaryEntry; import seedu.address.model.person.Person; import seedu.address.model.person.UniquePersonList; @@ -14,7 +19,10 @@ */ public class AddressBook implements ReadOnlyAddressBook { + private DiaryBook diaryBook; private final UniquePersonList persons; + private ObservableList taskList; + /* * The 'unusual' code block below is a non-static initialization block, sometimes used to avoid duplication @@ -25,9 +33,12 @@ public class AddressBook implements ReadOnlyAddressBook { */ { persons = new UniquePersonList(); + diaryBook = new DiaryBook(); + taskList = FXCollections.observableList(new ArrayList<>()); } - public AddressBook() {} + public AddressBook() { + } /** * Creates an AddressBook using the Persons in the {@code toBeCopied} @@ -54,6 +65,8 @@ public void resetData(ReadOnlyAddressBook newData) { requireNonNull(newData); setPersons(newData.getPersonList()); + + } //// person-level operations @@ -74,6 +87,10 @@ public void addPerson(Person p) { persons.add(p); } + public void addTasks(Task t) { + taskList.add(t); + } + /** * Replaces the given person {@code target} in the list with {@code editedPerson}. * {@code target} must exist in the address book. @@ -93,19 +110,39 @@ public void removePerson(Person key) { persons.remove(key); } + public void setDiaryEntry(ObservableList diaryEntry) { + diaryBook.setDiary(diaryEntry); + } + + /** + * dummy java docs. + * @param entry + * @return + */ + public boolean isEmptyDiaryEntry(DiaryEntry entry) { + // implement later + return false; + } //// util methods @Override public String toString() { + return persons.asUnmodifiableObservableList().size() + " persons"; // TODO: refine later } @Override public ObservableList getPersonList() { + return persons.asUnmodifiableObservableList(); } + @Override + public ObservableList getTaskList() { + return taskList; + } + @Override public boolean equals(Object other) { return other == this // short circuit if same object @@ -117,4 +154,8 @@ public boolean equals(Object other) { public int hashCode() { return persons.hashCode(); } + + public void addDiaryEntry(DiaryEntry diaryentry) { + this.diaryBook.getObservableList().add(diaryentry); + } } diff --git a/src/main/java/seedu/address/model/Model.java b/src/main/java/seedu/address/model/Model.java index d54df471c1f..6b81f00c4ce 100644 --- a/src/main/java/seedu/address/model/Model.java +++ b/src/main/java/seedu/address/model/Model.java @@ -1,11 +1,27 @@ package seedu.address.model; import java.nio.file.Path; + +import java.time.LocalDate; +import java.util.List; import java.util.function.Predicate; +import javafx.beans.value.ObservableValue; import javafx.collections.ObservableList; import seedu.address.commons.core.GuiSettings; +import seedu.address.commons.core.index.Index; +import seedu.address.model.calender.Task; +import seedu.address.model.diary.DiaryEntry; +import seedu.address.model.diary.mood.Mood; +import seedu.address.model.diary.weather.Weather; +import seedu.address.model.notes.Notes; +import seedu.address.model.nusmodule.Grade; +import seedu.address.model.nusmodule.Major; +import seedu.address.model.nusmodule.ModuleCode; +import seedu.address.model.nusmodule.ModuleTask; +import seedu.address.model.nusmodule.NusModule; import seedu.address.model.person.Person; +import seedu.address.model.studentprofile.Profile; /** * The API of the Model component. @@ -14,11 +30,21 @@ public interface Model { /** {@code Predicate} that always evaluate to true */ Predicate PREDICATE_SHOW_ALL_PERSONS = unused -> true; + /** {@code Predicate} that always evaluate to true */ + Predicate PREDICATE_SHOW_ALL_NOTES = unused -> true; + + /** {@code Predicate} that always evaluate to true */ + Predicate PREDICATE_SHOW_ALL_TASK = unused -> true; + + /** {@code Predicate} that always evaluate to true */ + Predicate PREDICATE_SHOW_ALL_MODULES_TAKEN = unused -> true; + /** * Replaces user prefs data with the data in {@code userPrefs}. */ void setUserPrefs(ReadOnlyUserPrefs userPrefs); + /** * Returns the user prefs. */ @@ -39,6 +65,11 @@ public interface Model { */ Path getAddressBookFilePath(); + /** + * Returns the user prefs' address book file path. + */ + Path getDiaryBookFilePath(); + /** * Sets the user prefs' address book file path. */ @@ -84,4 +115,129 @@ public interface Model { * @throws NullPointerException if {@code predicate} is null. */ void updateFilteredPersonList(Predicate predicate); + //=========== Diary Module ================================================================================== + boolean isEmptyDiaryEntry(DiaryEntry diaryEntry); + + void addDiaryEntry(DiaryEntry diaryEntry); + + String showDiaryLog(); + + ObservableList getDiaryList(); + + boolean isValidEntryId(int entryId); + + void deleteDiaryEntry(int entryId); + + void tagWeather(int entryId, Weather weather); + + void tagMood(int entryId, Mood mood); + + DiaryEntry getDiaryEntryById(int entryId); + + List getListOfIdsByDate(LocalDate date); + + boolean isExistingDate(LocalDate date); + + //=========== Notes Module ================================================================================== + /** Returns an list of String that contains what is currently in the folder */ + ObservableList getFilesInFolderList(); + + /** + * Updates the notes list by the given {@code predicate}. + * @throws NullPointerException if {@code predicate} is null. + */ + void updateNotesList(Predicate predicate); + + //=========== CAP Module ================================================================================== + /** + * Returns true if a module with the same identity as {@code module} exists in the address book. + */ + boolean hasModule(ModuleCode moduleCode); + + /** + * Adds the given module. + * {@code module} must not already exist in the address book. + */ + void addModule(NusModule module); + + void deleteModule(ModuleCode moduleCode); + + void gradeModule(ModuleCode moduleCode, Grade grade); + + double getCap(); + + void addModuleTask(ModuleTask moduleTask); + + ObservableList getModulesListTaken(); + + ModuleBook getModuleBook(); + + int getSizeOfModuleTaskList(ModuleCode moduleCode); + + void deleteModuleTask(ModuleCode moduleCode, Index index); + + void doneModuleTask(ModuleCode moduleCode, Index index); + + String getModuleTaskInfo(ModuleCode moduleCode); + + String getTaskBreakdown(); + + List getModuleTaskList(ModuleCode moduleCode); + + List findTasksByDate(String date); + + List findTasksByCat(String cat); + + void updateModulesListTaken(Predicate predicate); + + Path getModuleBookFilePath(); + + //=========== Deadline ================================================================================== + + /** + * Adds deadline. + */ + void addDeadlineTask(Task deadline); + + void sortTaskList(); + + Task deleteTask(Task task); + + Task doneDeadlineTask(Task deadline); + + void sortTask(String param); + + /** + * Checks if content of deadline is empty + */ + boolean isEmptyDeadline(Task deadline); + + /** Returns an list of Deadline that is currently in the list */ + ObservableList getDeadlineTaskList(); + + /** + * Updates the deadline list by the given {@code predicate}. + * @throws NullPointerException if {@code predicate} is null. + */ + void updateDeadlineTaskList(Predicate predicate); + + //=========== TD ================================================================================== + + /** + * Adds todo. + */ + void addToDo(Task todo); + + /** + * Checks if content of todo is empty + */ + boolean isEmptyToDo(Task todo); + + //=========== Profile ================================================================================== + + void updateMajor(Major major); + + ObservableValue getMajor(); + + Profile getProfile(); } diff --git a/src/main/java/seedu/address/model/ModelManager.java b/src/main/java/seedu/address/model/ModelManager.java index 0650c954f5c..20e1269a406 100644 --- a/src/main/java/seedu/address/model/ModelManager.java +++ b/src/main/java/seedu/address/model/ModelManager.java @@ -4,14 +4,35 @@ import static seedu.address.commons.util.CollectionUtil.requireAllNonNull; import java.nio.file.Path; + +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; import java.util.function.Predicate; import java.util.logging.Logger; +import javafx.beans.value.ObservableValue; +import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.collections.transformation.FilteredList; + import seedu.address.commons.core.GuiSettings; import seedu.address.commons.core.LogsCenter; +import seedu.address.commons.core.index.Index; +import seedu.address.model.calender.Task; +import seedu.address.model.diary.DiaryBook; +import seedu.address.model.diary.DiaryEntry; +import seedu.address.model.diary.mood.Mood; +import seedu.address.model.diary.weather.Weather; +import seedu.address.model.notes.Notes; +import seedu.address.model.nusmodule.Grade; +import seedu.address.model.nusmodule.Major; +import seedu.address.model.nusmodule.ModuleCode; +import seedu.address.model.nusmodule.ModuleTask; +import seedu.address.model.nusmodule.NusModule; import seedu.address.model.person.Person; +import seedu.address.model.studentprofile.Profile; + /** * Represents the in-memory model of the address book data. @@ -22,25 +43,44 @@ public class ModelManager implements Model { private final AddressBook addressBook; private final UserPrefs userPrefs; private final FilteredList filteredPersons; + private final ObservableList diaryEntries; + private DiaryBook diaryBook; + private final FilteredList filesInFolder; + private ModuleBook moduleBook; + private FilteredList deadlineTaskList; + private final FilteredList moduleListTaken; + private Profile studentProfile; /** * Initializes a ModelManager with the given addressBook and userPrefs. */ - public ModelManager(ReadOnlyAddressBook addressBook, ReadOnlyUserPrefs userPrefs) { + public ModelManager(ReadOnlyAddressBook addressBook, ReadOnlyUserPrefs userPrefs, + ModuleBook moduleBook, ObservableList taskList) { super(); - requireAllNonNull(addressBook, userPrefs); + requireAllNonNull(addressBook, userPrefs, moduleBook); - logger.fine("Initializing with address book: " + addressBook + " and user prefs " + userPrefs); + logger.fine("Initializing with address book: " + addressBook + " and user prefs " + userPrefs + + " and module list: " + moduleBook); this.addressBook = new AddressBook(addressBook); this.userPrefs = new UserPrefs(userPrefs); + this.moduleBook = moduleBook; filteredPersons = new FilteredList<>(this.addressBook.getPersonList()); + diaryBook = new DiaryBook(); + diaryEntries = diaryBook.getInternalList(); + filesInFolder = new FilteredList<>(Notes.getAllFilesInFolder()); + deadlineTaskList = new FilteredList<>(taskList); + Task.setDeadlineTaskList(taskList); + moduleListTaken = new FilteredList<>(moduleBook.getModulesTakenList()); + studentProfile = new Profile(moduleBook); } public ModelManager() { - this(new AddressBook(), new UserPrefs()); + this(new AddressBook(), new UserPrefs(), new ModuleBook(), + FXCollections.observableList(new ArrayList<>())); } + //=========== UserPrefs ================================================================================== @Override @@ -112,6 +152,159 @@ public void setPerson(Person target, Person editedPerson) { addressBook.setPerson(target, editedPerson); } + //=========== Diary Module ================================================================================== + @Override + public void addDiaryEntry(DiaryEntry diaryEntry) { + diaryBook.addEntry(diaryEntry); + } + + @Override + public boolean isEmptyDiaryEntry(DiaryEntry diaryEntry) { + // implement later + return false; + } + + @Override + public boolean isValidEntryId(int entryId) { + int minId = 1; + int maxId = diaryBook.getDiaryEntries().size(); + return (entryId >= minId) && (entryId <= maxId); + } + + @Override + public void deleteDiaryEntry(int entryId) { + diaryBook.deleteEntry(entryId); + } + + @Override + public void tagWeather(int entryId, Weather weather) { + diaryBook.tagWeather(entryId, weather); + } + + @Override + public void tagMood(int entryId, Mood mood) { + diaryBook.tagMood(entryId, mood); + } + + @Override + public DiaryEntry getDiaryEntryById(int entryId) { + return diaryBook.getDiaryEntryById(entryId); + } + + @Override + public List getListOfIdsByDate(LocalDate date) { + return diaryBook.getListOfIdsByDate(date); + } + + @Override + public boolean isExistingDate(LocalDate date) { + return diaryBook.isExistingDate(date); + } + + @Override + public String showDiaryLog() { + return diaryBook.showLog(); + } + + @Override + public Path getDiaryBookFilePath() { + return null; + } + + @Override + public ObservableList getDiaryList() { + return diaryEntries; + } + + + //=========== Cap Module ================================================================================== + + /** + * Dummy java docs + * + * @param + * @return + */ + @Override + public boolean hasModule(ModuleCode moduleCode) { + return moduleBook.hasModule(moduleCode); + } + + @Override + public void addModule(NusModule module) { + moduleBook.addModule(module); + } + + @Override + public void deleteModule(ModuleCode moduleCode) { + moduleBook.deleteModule(moduleCode); + } + + @Override + public void gradeModule(ModuleCode moduleCode, Grade updatedGrade) { + moduleBook.gradeModule(moduleCode, updatedGrade); + } + + @Override + public double getCap() { + return moduleBook.getCap(); + } + + public ObservableList getModulesListTaken() { + return moduleListTaken; + } + + @Override + public void updateModulesListTaken(Predicate predicate) { + requireNonNull(predicate); + moduleListTaken.setPredicate(predicate); + } + + @Override + public Path getModuleBookFilePath() { + return userPrefs.getModuleBookFilePath(); + } + + @Override + public ModuleBook getModuleBook() { + return this.moduleBook; + } + + @Override + public int getSizeOfModuleTaskList(ModuleCode moduleCode) { + return moduleBook.getSizeOfModuleTaskList(moduleCode); + } + + @Override + public List getModuleTaskList(ModuleCode moduleCode) { + return moduleBook.getModuleTaskList(moduleCode); + } + + @Override + public void deleteModuleTask(ModuleCode moduleCode, Index index) { + moduleBook.deleteModuleTask(moduleCode, index); + } + + @Override + public void doneModuleTask(ModuleCode moduleCode, Index index) { + moduleBook.doneModuleTask(moduleCode, index); + } + + @Override + public void addModuleTask(ModuleTask moduleTask) { + moduleBook.addModuleTask(moduleTask); + } + + @Override + public String getModuleTaskInfo(ModuleCode moduleCode) { + return moduleBook.getModuleTaskInfo(moduleCode); + } + + @Override + public String getTaskBreakdown() { + return moduleBook.getTaskBreakdown(); + } + //=========== Filtered Person List Accessors ============================================================= /** @@ -129,6 +322,23 @@ public void updateFilteredPersonList(Predicate predicate) { filteredPersons.setPredicate(predicate); } + //=========== Notes Module ================================================================================== + + /** + * Returns an list of String that contains what is currently in the folder + */ + @Override + public ObservableList getFilesInFolderList() { + return filesInFolder; + } + + @Override + public void updateNotesList(Predicate predicate) { + requireNonNull(predicate); + filesInFolder.setPredicate(predicate); + } + + @Override public boolean equals(Object obj) { // short circuit if same object @@ -148,4 +358,111 @@ public boolean equals(Object obj) { && filteredPersons.equals(other.filteredPersons); } + //=========== Deadline Module ================================================================================== + + @Override + public boolean isEmptyDeadline(Task deadline) { + return false; + } + + /** + * Returns a list of task in the deadline task list + */ + @Override + public ObservableList getDeadlineTaskList() { + return deadlineTaskList; + } + + @Override + public void updateDeadlineTaskList(Predicate predicate) { + requireNonNull(predicate); + deadlineTaskList.setPredicate(predicate); + } + + @Override + public List findTasksByDate(String date) { + List targetTasks = new ArrayList<>(); + for (Task task : deadlineTaskList) { + if (task.getDate().equals(date)) { + targetTasks.add(task); + } + } + return targetTasks; + } + + @Override + public List findTasksByCat(String cat) { + List targetTasks = new ArrayList<>(); + for (Task task : deadlineTaskList) { + if (task.getCategory().equals(cat)) { + targetTasks.add(task); + } + } + return targetTasks; + } + + @Override + public void addDeadlineTask(Task deadline) { + + Task.add(deadline); + } + + @Override + public Task doneDeadlineTask(Task deadline) { + Task.getDeadlineTaskList().get(deadline.getIndex() - 1).markAsDone(); + + Task done = Task.getDeadlineTaskList().get(deadline.getIndex() - 1); + Task.getDeadlineTaskList().remove(deadline.getIndex() - 1); + Task.getDeadlineTaskList().add(done); + return done; + } + + @Override + public void sortTaskList() { + Task.sortDeadlineTaskList("date"); + Task.sortDeadlineTaskList("done"); + } + + @Override + public Task deleteTask(Task task) { + Task.getDeadlineTaskList().remove(task); + Task.removeTaskPerDate(task.getDate(), task); + return task; + } + + @Override + public void sortTask(String param) { + Task.sortDeadlineTaskList(param); + } + + + //=========== TD Module ================================================================================== + + + @Override + public void addToDo(Task todo) { + + } + + @Override + public boolean isEmptyToDo(Task todo) { + return false; + } + + + //=========== Profile Module ================================================================================== + @Override + public void updateMajor(Major major) { + studentProfile.setMajor(major); + } + + public ObservableValue getMajor() { + return studentProfile.getMajor(); + } + + public Profile getProfile() { + return studentProfile; + } + + } diff --git a/src/main/java/seedu/address/model/ModuleBook.java b/src/main/java/seedu/address/model/ModuleBook.java new file mode 100644 index 00000000000..ca667b5f836 --- /dev/null +++ b/src/main/java/seedu/address/model/ModuleBook.java @@ -0,0 +1,236 @@ +package seedu.address.model; + +import static java.util.Objects.requireNonNull; + +import java.util.ArrayList; +import java.util.List; + +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import seedu.address.commons.core.index.Index; +import seedu.address.model.nusmodule.Capulator; +import seedu.address.model.nusmodule.Grade; +import seedu.address.model.nusmodule.Major; +import seedu.address.model.nusmodule.ModuleCode; +import seedu.address.model.nusmodule.ModuleTask; +import seedu.address.model.nusmodule.NusModule; + +/** + * Wraps all module-related data at the module-book level + * Duplicates are not allowed + */ +public class ModuleBook { + + private List modules; + private ObservableList modulesTakenList; + private Major majorTaken; + + public ModuleBook() { + this.modules = new ArrayList<>(); + + modulesTakenList = FXCollections.observableList(modules); + } + + /** + * Creates an ModuleBook using the Modules in the {@code toBeCopied} + */ + public ModuleBook(ModuleBook toBeCopied) { + this(); + resetData(toBeCopied); + } + + public ModuleBook(List modules) { + this.modules = modules; + getModulesTakenList(); + } + + /** + * Adds a module to the module book. + * The module must not already exist in the module book. + */ + public void addModule(NusModule module) { + + this.modulesTakenList.add(module); + + } + + /** + * Removes {@code NusModule} that has the same module code as given from this {@code ModuleBook}. + * such nus module must exist in the module book. + */ + public void deleteModule(ModuleCode moduleCode) { + int index = -1; + for (int i = 0; i < modules.size(); i++) { + if (modules.get(i).getModuleCode().equals(moduleCode)) { + index = i; + } + } + this.modulesTakenList.remove(index); + } + + public NusModule getModule(ModuleCode moduleCode) { + requireNonNull(moduleCode); + NusModule result = null; + for (NusModule module: modules) { + if (module.getModuleCode().equals(moduleCode)) { + result = module; + } + } + return result; + } + + /** + * Replaces the contents of the module list with {@code mdoules}. + */ + public void setModules(List modules) { + this.modules = modules; + } + + /** + * Resets the existing data of this {@code AddressBook} with {@code newData}. + */ + public void resetData(ModuleBook newData) { + requireNonNull(newData); + + setModules(newData.getModulesTakenList()); + + + } + + /** + * Up + * ydates the grade of the {@code NusModule} that has the same module code as given from this {@code ModuleBook}. + * such nus module must exist in the module book. + */ + public void gradeModule(ModuleCode moduleCode, Grade grade) { + requireNonNull(moduleCode); + requireNonNull(grade); + NusModule targetModule = null; + for (NusModule module: modules) { + if (module.getModuleCode().equals(moduleCode)) { + targetModule = module; + } + } + modulesTakenList.remove(targetModule); + targetModule.setGrade(grade); + modulesTakenList.add(targetModule); + } + + /** + * Add a new module task to a specific module recorded in our program. + */ + public void addModuleTask(ModuleTask moduleTask) { + requireNonNull(moduleTask); + for (NusModule module: modules) { + if (module.getModuleCode().equals(moduleTask.getModuleRelated())) { + module.addTask(moduleTask); + } + } + } + + /** + * Delete a module task in a specific module recorded in our program. + */ + public void deleteModuleTask(ModuleCode moduleCode, Index index) { + requireNonNull(moduleCode); + requireNonNull(index); + getModule(moduleCode).getTasks().remove(index.getZeroBased()); + } + + /** + * Mark a module task as done in a specific module recorded in our program. + */ + public void doneModuleTask(ModuleCode moduleCode, Index index) { + requireNonNull(moduleCode); + requireNonNull(index); + getModule(moduleCode).getTasks().get(index.getZeroBased()).markAsDone(); + } + + /** + * Remove a specific module recorded in our program. + */ + public void removeModuleTask(ModuleTask moduleTask) { + NusModule targetModule = null; + ModuleTask targetTask; + for (NusModule module: modules) { + for (ModuleTask mt : module.getTasks()) { + if (mt.equals(moduleTask)) { + targetModule = module; + targetTask = moduleTask; + } + } + } + targetModule.getTasks().remove(moduleTask); + } + + public List getModuleTaskList(ModuleCode moduleCode) { + requireNonNull(moduleCode); + return getModule(moduleCode).getTasks(); + } + + /** + * Return a String contains the information of the tasks related to the specified module. + */ + public String getModuleTaskInfo(ModuleCode moduleCode) { + requireNonNull(moduleCode); + String infoOfTasks = ""; + List tasks = getModuleTaskList(moduleCode); + for (int i = 0; i < tasks.size(); i++) { + String task = (i + 1) + ". " + tasks.get(i) + "\n"; + infoOfTasks += task; + } + return infoOfTasks; + } + + /** + * Return a String contains the information of how many tasks are there related to each module in module book. + */ + public String getTaskBreakdown() { + String infoOfTasks = ""; + for (NusModule module: modules) { + int numberOfTasksNotDone = 0; + for (ModuleTask moduleTask: module.getTasks()) { + if (moduleTask.getDoneStatus() == 0) { + numberOfTasksNotDone += 1; + } + } + String message = "- " + module.getModuleCode() + ": " + + module.getTasks().size() + " tasks in total " + + numberOfTasksNotDone + " tasks haven't been completed\n"; + infoOfTasks += message; + } + return infoOfTasks; + } + + + public void setMajor(Major major) { + requireNonNull(major); + this.majorTaken = major; + } + + /** + * Returns true if a module with the same module code as {@code NusModule} exists in the address book. + */ + public boolean hasModule(ModuleCode moduleCode) { + requireNonNull(moduleCode); + for (NusModule module: modules) { + if (module.getModuleCode().equals(moduleCode)) { + return true; + } + } + return false; + } + + public ObservableList getModulesTakenList() { + return modulesTakenList; + } + + public double getCap() { + Capulator capulator = new Capulator(modules); + return capulator.calculateCap(); + } + + public int getSizeOfModuleTaskList(ModuleCode moduleCode) { + return getModule(moduleCode).getTasks().size(); + } +} diff --git a/src/main/java/seedu/address/model/ReadOnlyAddressBook.java b/src/main/java/seedu/address/model/ReadOnlyAddressBook.java index 6ddc2cd9a29..e293a6c945d 100644 --- a/src/main/java/seedu/address/model/ReadOnlyAddressBook.java +++ b/src/main/java/seedu/address/model/ReadOnlyAddressBook.java @@ -1,6 +1,7 @@ package seedu.address.model; import javafx.collections.ObservableList; +import seedu.address.model.calender.Task; import seedu.address.model.person.Person; /** @@ -14,4 +15,10 @@ public interface ReadOnlyAddressBook { */ ObservableList getPersonList(); + /** + * Returns an unmodifiable view of the persons list. + * This list will not contain any duplicate persons. + */ + ObservableList getTaskList(); + } diff --git a/src/main/java/seedu/address/model/UserPrefs.java b/src/main/java/seedu/address/model/UserPrefs.java index 25a5fd6eab9..d69385cf3ce 100644 --- a/src/main/java/seedu/address/model/UserPrefs.java +++ b/src/main/java/seedu/address/model/UserPrefs.java @@ -15,6 +15,10 @@ public class UserPrefs implements ReadOnlyUserPrefs { private GuiSettings guiSettings = new GuiSettings(); private Path addressBookFilePath = Paths.get("data" , "addressbook.json"); + private Path calendarFilePath = Paths.get("data" , "calendar.json"); + private Path diaryBookFilePath = Paths.get("data", "stub-diaryEntries.json"); + + private Path moduleBookFilePath = Paths.get("data" , "modulebook.json"); /** * Creates a {@code UserPrefs} with default values. @@ -51,6 +55,15 @@ public Path getAddressBookFilePath() { return addressBookFilePath; } + // calendar entry at startup + public Path getCalendarFilePath() { + return calendarFilePath; + } + + public Path getModuleBookFilePath() { + return moduleBookFilePath; + } + public void setAddressBookFilePath(Path addressBookFilePath) { requireNonNull(addressBookFilePath); this.addressBookFilePath = addressBookFilePath; diff --git a/src/main/java/seedu/address/model/calender/CatContainsKeywordsPredicate.java b/src/main/java/seedu/address/model/calender/CatContainsKeywordsPredicate.java new file mode 100644 index 00000000000..9b5afab5d6c --- /dev/null +++ b/src/main/java/seedu/address/model/calender/CatContainsKeywordsPredicate.java @@ -0,0 +1,31 @@ +package seedu.address.model.calender; + +import java.util.List; +import java.util.function.Predicate; + +import seedu.address.commons.util.StringUtil; + +/** + * Tests that a {@code Person}'s {@code Name} matches any of the keywords given. + */ +public class CatContainsKeywordsPredicate implements Predicate { + private final List keywords; + + public CatContainsKeywordsPredicate(List keywords) { + this.keywords = keywords; + } + + @Override + public boolean test(Task task) { + return keywords.stream() + .anyMatch(keyword -> StringUtil.containsWordIgnoreCase(task.getCategory(), keyword)); + } + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof CatContainsKeywordsPredicate // instanceof handles nulls + && keywords.equals(((CatContainsKeywordsPredicate) other).keywords)); // state check + } + +} diff --git a/src/main/java/seedu/address/model/calender/DateContainKeywordsPredicate.java b/src/main/java/seedu/address/model/calender/DateContainKeywordsPredicate.java new file mode 100644 index 00000000000..01d4e66fd68 --- /dev/null +++ b/src/main/java/seedu/address/model/calender/DateContainKeywordsPredicate.java @@ -0,0 +1,30 @@ +package seedu.address.model.calender; + +import java.util.List; +import java.util.function.Predicate; + +import seedu.address.commons.util.StringUtil; + +/** + * Tests that a {@code Person}'s {@code Name} matches any of the keywords given. + */ +public class DateContainKeywordsPredicate implements Predicate { + private final List keywords; + + public DateContainKeywordsPredicate(List keywords) { + this.keywords = keywords; + } + + @Override + public boolean test(Task task) { + return keywords.stream() + .anyMatch(keyword -> StringUtil.containsWordIgnoreCase(task.getDate(), keyword)); + } + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof ModuleCodeContainKeywordsPredicate); // state check + } + +} diff --git a/src/main/java/seedu/address/model/calender/Deadline.java b/src/main/java/seedu/address/model/calender/Deadline.java new file mode 100644 index 00000000000..78bcbc639e0 --- /dev/null +++ b/src/main/java/seedu/address/model/calender/Deadline.java @@ -0,0 +1,108 @@ +package seedu.address.model.calender; + +import static seedu.address.commons.util.CollectionUtil.requireAllNonNull; + +/** + *

Deadline Class

+ * Returns an extended type of Task, Deadline, where tasks have to be completed by a set date + */ + +public class Deadline extends Task { + + public static final String MESSAGE_CONSTRAINTS = "Please enter valid Date in the format DD-MM-YYYY"; + protected String by; + protected String category; + protected String operation; + protected int index; + + + /** + * Constructor for deadline class + * @param description describes content of task + * @param by sets targeted completion date of task + */ + public Deadline(String description, String by, String category, String operation) { + super(description); + requireAllNonNull(operation); + this.by = by; + this.category = category; + this.operation = operation; + } + + public Deadline(int index, String operation) { + super("Delete task"); + requireAllNonNull(operation); + this.index = index; + this.operation = operation; + } + + /** + * dummy docs. + * @param date + * @return + */ + public static boolean isValidDate(String date) { + + try { + String[] splittedDate = date.split("-"); + int month = Integer.parseInt(splittedDate[1]); + int day = Integer.parseInt(splittedDate[0]); + + if (month < 1 || month > 12) { + return false; + } + + if (day < 1 || day > 31) { + return false; + } + + return true; + } catch (Exception ex) { + return false; + } + + } + + @Override + public String getDate() { + return this.by; + } + + @Override + public String getCategory() { + return this.category; + } + + @Override + public String getOperation() { + return this.operation; + } + + @Override + public int getIndex() { + return this.index; + } + + @Override + public String toString() { + return super.toString() + " (" + by + ")" + "(" + category + ")"; + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + if (!(other instanceof Deadline)) { + return false; + } + + Deadline otherTask = (Deadline) other; + System.out.println(otherTask.getDescription().equals(getDescription())); + System.out.println(otherTask.getDate().equals(this.getDate())); + return otherTask.getDescription().equals(getDescription()) + && otherTask.getDate().equals(this.getDate()); + + } +} diff --git a/src/main/java/seedu/address/model/calender/ModuleCodeContainKeywordsPredicate.java b/src/main/java/seedu/address/model/calender/ModuleCodeContainKeywordsPredicate.java new file mode 100644 index 00000000000..5baa05b5b59 --- /dev/null +++ b/src/main/java/seedu/address/model/calender/ModuleCodeContainKeywordsPredicate.java @@ -0,0 +1,36 @@ +package seedu.address.model.calender; + +import java.util.List; +import java.util.function.Predicate; + +import seedu.address.commons.util.StringUtil; +import seedu.address.model.nusmodule.ModuleTask; + +/** + * Tests that a {@code Person}'s {@code Name} matches any of the keywords given. + */ +public class ModuleCodeContainKeywordsPredicate implements Predicate { + private final List keywords; + + public ModuleCodeContainKeywordsPredicate(List keywords) { + this.keywords = keywords; + } + + @Override + public boolean test(Task task) { + if (task instanceof ModuleTask) { + return keywords.stream() + .anyMatch(keyword -> + StringUtil.containsWordIgnoreCase + (((ModuleTask) task).getModuleRelated().toString(), keyword)); + } + return false; + } + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof ModuleCodeContainKeywordsPredicate); // state check + } + +} diff --git a/src/main/java/seedu/address/model/calender/Task.java b/src/main/java/seedu/address/model/calender/Task.java new file mode 100644 index 00000000000..8fe01ef6bff --- /dev/null +++ b/src/main/java/seedu/address/model/calender/Task.java @@ -0,0 +1,292 @@ +package seedu.address.model.calender; +import static seedu.address.commons.util.CollectionUtil.requireAllNonNull; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Objects; + +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import seedu.address.model.nusmodule.ModuleTask; + +/** + *

Task Class

+ * Represents general Task class such that it can be extended into more specific classes (Deadlines, + * To Dos) + * description must specify a task + */ + +public class Task { + private static ObservableList deadlineTaskList; + private static HashMap> deadlineTaskHashMap = new HashMap<>(); + + protected boolean isDone; + private String description; + + /** + * Constructor for task class + * + * @param description describes content of task + */ + public Task(String description) { + requireAllNonNull(description); + this.description = description; + this.isDone = false; + } + + /** + * Return the status of the Task. + * + * @return icon for status (tick or cross) to display if task is completed or not + */ + public boolean getStatus() { + return isDone; + } + + /** + * Return the description of the task. + * + * @return description of task + */ + public String getDescription() { + return description; + } + + /** + * Add Task to the date in the HashMap. + * + * @param date date of the task, which is the key in the HashMap + * @param task Task that is added + */ + public static void addTaskPerDate(String date, Task task) { + if (!deadlineTaskHashMap.containsKey(date)) { + deadlineTaskHashMap.put(date, new ArrayList<>()); + deadlineTaskHashMap.get(date).add(task); + + } else { + deadlineTaskHashMap.get(date).add(task); + } + } + + /** + * Remove the task from the date in the HashMap + * + * @param date date of the task, which is the key in the HashMap + * @param task Task that is to be removed + */ + public static void removeTaskPerDate(String date, Task task) { + + deadlineTaskHashMap.get(date).remove(task); + if (deadlineTaskHashMap.get(date).size() <= 0) { + deadlineTaskHashMap.remove(date); + } + + } + + /** + * Returns whether a specific date have any task present. + * + * @param date Key of the HashMap + * @return true if a task is present in the date, false if not + */ + public static boolean isTaskPresent(String date) { + + if (!deadlineTaskHashMap.containsKey(date)) { + return false; + } else { + if (deadlineTaskHashMap.get(date).size() <= 0) { + return false; + } + } + return true; + + } + + /** + * Adds task to the calendar. + * @param task + */ + public static void add(Task task) { + deadlineTaskList.add(task); + addTaskPerDate(task.getDate(), task); + } + + /** + * Removes task to the calendar. + * @param task + */ + public static void remove(Task task) { + deadlineTaskList.remove(task); + removeTaskPerDate(task.getDate(), task); + } + + public static HashMap> getDeadlineTaskHashMap() { + + return deadlineTaskHashMap; + } + + /** + * Mark the task as done. + * + * @return true when the task is marked as done + */ + public boolean markAsDone() { + isDone = true; + return isDone; + } + + /** + * Returns a new instance of the deadline task list. + * + * @return an empty deadline task list + */ + public static ObservableList getNewDeadlineTaskList() { + ArrayList deadlineTaskListDummy = new ArrayList<>(); + + deadlineTaskList = FXCollections.observableArrayList(deadlineTaskListDummy); + return deadlineTaskList; + } + + public static void setDeadlineTaskList(ObservableList initialiedList) { + + deadlineTaskList = initialiedList; + for (Task task : initialiedList) { + addTaskPerDate(task.getDate(), task); + } + } + + + /** + * Returns the observable list required for the UI. + * + * @return observable list required for the UI + */ + public static ObservableList getDeadlineTaskList() { + return deadlineTaskList; + } + + /** + * Sort the deadline task list by value specified, value can be date or priority + * + * @param value value specified can be date or priority + */ + public static void sortDeadlineTaskList(String value) { + + SimpleDateFormat dateParser = new SimpleDateFormat("dd-MM-yyyy"); + + if (value.equals("date")) { + Comparator comparator = (Task o1, Task o2) -> { + try { + return dateParser.parse(o1.getDate()).compareTo(dateParser.parse(o2.getDate())); + } catch (ParseException e) { + e.printStackTrace(); + } + return -1; + }; + + FXCollections.sort(deadlineTaskList, comparator); + + } else if (value.equals("priority")) { + Comparator comparator = (Task o1, Task o2) -> { + if (o1 instanceof Deadline) { + return 1; + } else if (o2 instanceof Deadline) { + return -1; + } else { + return ((ModuleTask) o1).getPriority().compareTo(((ModuleTask) o2).getPriority()); + } + }; + + FXCollections.sort(deadlineTaskList, comparator); + } else if (value.equals("done")) { + Comparator comparator = (Task o1, Task o2) -> { + return Boolean.compare(o1.isDone, o2.isDone); + }; + + FXCollections.sort(deadlineTaskList, comparator); + } + + } + + public String getCategory() { + return "None"; + } + + public String getDate() { + return "None"; + } + + public String getOperation() { + return "None"; + } + + public int getIndex() { + return -1; + } + + @Override + public String toString() { + return description; + } + + + /** + * Check whether a date is valid. + * + * @param date format of the date + * @return true if it is a valid date. + */ + public static boolean isValidDate(String date) { + + try { + String[] splittedDate = date.split("-"); + int day = Integer.parseInt(splittedDate[0]); + int month = Integer.parseInt(splittedDate[1]); + + if (month < 1 || month > 12) { + return false; + } + + if (day < 1 || day > 31) { + return false; + } + + return true; + } catch (Exception ex) { + return false; + } + + } + + + /** + * Returns true if both task have the same date and data fields. + */ + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + if (!(other instanceof Task)) { + return false; + } + + Task otherTask = (Task) other; + System.out.println(otherTask.getDescription().equals(this.description)); + System.out.println(otherTask.getDate().equals(this.getDate())); + return otherTask.getDescription().equals(this.description) + && otherTask.getDate().equals(this.getDate()); + + } + + @Override + public int hashCode() { + // use this method for custom fields hashing instead of implementing your own + return Objects.hash(description); + } + +} diff --git a/src/main/java/seedu/address/model/calender/ToDo.java b/src/main/java/seedu/address/model/calender/ToDo.java new file mode 100644 index 00000000000..65069a44169 --- /dev/null +++ b/src/main/java/seedu/address/model/calender/ToDo.java @@ -0,0 +1,22 @@ +package seedu.address.model.calender; + +/** + *

To Do Class

+ * Returns an extended type of Task, To Dos, where general tasks are added + */ + +public class ToDo extends Task { + + /** + * Constructor for to do class + * @param description describes content of to do + */ + public ToDo(String description) { + super(description); + } + + @Override + public String toString() { + return "[T]" + super.toString(); + } +} diff --git a/src/main/java/seedu/address/model/diary/DiaryBook.java b/src/main/java/seedu/address/model/diary/DiaryBook.java new file mode 100644 index 00000000000..8006febb320 --- /dev/null +++ b/src/main/java/seedu/address/model/diary/DiaryBook.java @@ -0,0 +1,116 @@ +package seedu.address.model.diary; + +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; + +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import seedu.address.model.diary.mood.HappyMood; +import seedu.address.model.diary.mood.Mood; +import seedu.address.model.diary.weather.CloudyWeather; +import seedu.address.model.diary.weather.Weather; + +/** + * Represents a diary book that manages a list of diary entries. + */ +public class DiaryBook { + private static List diaryEntries; + private static ObservableList internalList; + + public DiaryBook() { + this.diaryEntries = new ArrayList<>(); + DiaryEntry dummyDiary = new DiaryEntry(LocalDate.now(), + new CloudyWeather(), + new HappyMood(), + "First dummy entry"); + diaryEntries.add(dummyDiary); + internalList = FXCollections.observableList(diaryEntries); + } + + public DiaryBook(List diaryEntries) { + this.diaryEntries = diaryEntries; + } + + public void setDiary(ObservableList diaryEntry) { + this.internalList.addAll(diaryEntry); + } + + public ObservableList getObservableList() { + return this.internalList; + } + + /** + * Shows the logs of the recorded diary entries. + * + * @return String message representing the log messages. + */ + public String showLog() { + if (diaryEntries.size() == 0) { + return "There are currently no entries in your diary book!"; + } + int entryId = 1; + StringBuilder sb = new StringBuilder(); + for (DiaryEntry entry : diaryEntries) { + sb.append(entryId++).append(". ").append(entry.getHeading()).append("\n"); + } + return sb.toString(); + } + + public String showEntry(int entryId) { + return diaryEntries.get(calibrateIndex(entryId)).toString(); + } + + /* + public void addEntry(DiaryEntry diaryEntry) { + internalList.add(diaryEntry); + } + */ + public static ObservableList getInternalList() { + return internalList; + } + + public void addEntry(DiaryEntry diaryEntry) { + diaryEntries.add(diaryEntry); + } + + public void deleteEntry(int entryId) { + diaryEntries.remove(calibrateIndex(entryId)); + } + + public void tagWeather(int entryId, Weather weather) { + diaryEntries.get(calibrateIndex(entryId)).setWeather(weather); + } + + public void tagMood(int entryId, Mood mood) { + diaryEntries.get(calibrateIndex(entryId)).setMood(mood); + } + + public DiaryEntry getDiaryEntryById(int entryId) { + return diaryEntries.get(calibrateIndex(entryId)); + } + + public List getListOfIdsByDate(LocalDate date) { + List ids = new ArrayList<>(); + for (int i = 1; i <= diaryEntries.size(); i++) { + if (getDiaryEntryById(i).getDate().equals(date)) { + ids.add(i); + } + } + return ids; + } + + public boolean isExistingDate(LocalDate date) { + return getListOfIdsByDate(date).size() != 0; + } + + + public List getDiaryEntries() { + return this.diaryEntries; + } + + + private int calibrateIndex(int index) { + return index - 1; + } +} diff --git a/src/main/java/seedu/address/model/diary/DiaryEntry.java b/src/main/java/seedu/address/model/diary/DiaryEntry.java new file mode 100644 index 00000000000..8ef9032d7b9 --- /dev/null +++ b/src/main/java/seedu/address/model/diary/DiaryEntry.java @@ -0,0 +1,71 @@ +package seedu.address.model.diary; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.Optional; + +import seedu.address.model.diary.mood.Mood; +import seedu.address.model.diary.weather.Weather; + +/** + * Represents a diary entry. + */ +public class DiaryEntry { + + private LocalDate date; + private Optional weather; + private Optional mood; + private String entryContent; + + public DiaryEntry(LocalDate date, Weather weather, Mood mood, String entryContent) { + this.date = date; + this.weather = Optional.ofNullable(weather); + this.mood = Optional.ofNullable(mood); + this.entryContent = entryContent; + } + + public DiaryEntry(String entryContent) { + this(LocalDate.now(), null, null, entryContent); + } + + public String getHeading() { + String heading = ""; + heading += " DATE: " + date.format(DateTimeFormatter.ofPattern("MMM d yyyy")) + " | "; + heading += "WEATHER: " + (weather.isPresent() ? weather.get().toString() : "N.A.") + " | "; + heading += "MOOD: " + (mood.isPresent() ? mood.get().toString() : "N.A.") + " | "; + return heading + "\n"; + } + + public String getEntryContent() { + return entryContent; + } + + public LocalDate getDate() { + return date; + } + + public Optional getWeather() { + return weather; + } + + public Optional getMood() { + return mood; + } + + public void setWeather(Weather weather) { + this.weather = Optional.ofNullable(weather); + } + + public void setMood(Mood mood) { + this.mood = Optional.ofNullable(mood); + } + + @Override + public String toString() { + String dairyDisplay = ""; + dairyDisplay += getHeading(); + dairyDisplay += "_".repeat(50) + "\n"; + dairyDisplay += entryContent + "\n"; + return dairyDisplay; + } +} diff --git a/src/main/java/seedu/address/model/diary/mood/CalmMood.java b/src/main/java/seedu/address/model/diary/mood/CalmMood.java new file mode 100644 index 00000000000..118a5c3f37e --- /dev/null +++ b/src/main/java/seedu/address/model/diary/mood/CalmMood.java @@ -0,0 +1,10 @@ +package seedu.address.model.diary.mood; + +/** + *Represents a calm mood. Extends from abstract class Mood. + */ +public class CalmMood extends Mood { + public CalmMood() { + super("calm"); + } +} diff --git a/src/main/java/seedu/address/model/diary/mood/HappyMood.java b/src/main/java/seedu/address/model/diary/mood/HappyMood.java new file mode 100644 index 00000000000..6f05b40a971 --- /dev/null +++ b/src/main/java/seedu/address/model/diary/mood/HappyMood.java @@ -0,0 +1,10 @@ +package seedu.address.model.diary.mood; + +/** + * Represents a happy mood. Extends from abstract class Mood. + */ +public class HappyMood extends Mood { + public HappyMood() { + super("happy"); + } +} diff --git a/src/main/java/seedu/address/model/diary/mood/Mood.java b/src/main/java/seedu/address/model/diary/mood/Mood.java new file mode 100644 index 00000000000..15a573c8338 --- /dev/null +++ b/src/main/java/seedu/address/model/diary/mood/Mood.java @@ -0,0 +1,17 @@ +package seedu.address.model.diary.mood; + +/** + * Represents a particular Mood. + */ +public abstract class Mood { + private final String mood; + + protected Mood(String mood) { + this.mood = mood; + } + + @Override + public String toString() { + return mood; + } +} diff --git a/src/main/java/seedu/address/model/diary/mood/SadMood.java b/src/main/java/seedu/address/model/diary/mood/SadMood.java new file mode 100644 index 00000000000..97f101d26ec --- /dev/null +++ b/src/main/java/seedu/address/model/diary/mood/SadMood.java @@ -0,0 +1,10 @@ +package seedu.address.model.diary.mood; + +/** + * Represents a sad mood. Extends from abstract class Mood. + */ +public class SadMood extends Mood { + public SadMood() { + super("sad"); + } +} diff --git a/src/main/java/seedu/address/model/diary/mood/StressedMood.java b/src/main/java/seedu/address/model/diary/mood/StressedMood.java new file mode 100644 index 00000000000..a715803b124 --- /dev/null +++ b/src/main/java/seedu/address/model/diary/mood/StressedMood.java @@ -0,0 +1,10 @@ +package seedu.address.model.diary.mood; + +/** + * Represents a stressed mood. Extends from abstract class Mood. + */ +public class StressedMood extends Mood { + public StressedMood() { + super("stressed"); + } +} diff --git a/src/main/java/seedu/address/model/diary/weather/CloudyWeather.java b/src/main/java/seedu/address/model/diary/weather/CloudyWeather.java new file mode 100644 index 00000000000..7dd89cb0c7a --- /dev/null +++ b/src/main/java/seedu/address/model/diary/weather/CloudyWeather.java @@ -0,0 +1,10 @@ +package seedu.address.model.diary.weather; + +/** + * Represents a cloudy weather. Extends from abstract class Weather. + */ +public class CloudyWeather extends Weather { + public CloudyWeather() { + super("cloudy"); + } +} diff --git a/src/main/java/seedu/address/model/diary/weather/RainyWeather.java b/src/main/java/seedu/address/model/diary/weather/RainyWeather.java new file mode 100644 index 00000000000..1101c0f60db --- /dev/null +++ b/src/main/java/seedu/address/model/diary/weather/RainyWeather.java @@ -0,0 +1,10 @@ +package seedu.address.model.diary.weather; + +/** + * Represents a rainy weather. Extends from abstract class Weather. + */ +public class RainyWeather extends Weather { + public RainyWeather() { + super("rainy"); + } +} diff --git a/src/main/java/seedu/address/model/diary/weather/SunnyWeather.java b/src/main/java/seedu/address/model/diary/weather/SunnyWeather.java new file mode 100644 index 00000000000..6d3db94d22a --- /dev/null +++ b/src/main/java/seedu/address/model/diary/weather/SunnyWeather.java @@ -0,0 +1,10 @@ +package seedu.address.model.diary.weather; + +/** + * Represents a sunny weather. Extends from abstract class Weather. + */ +public class SunnyWeather extends Weather { + public SunnyWeather() { + super("sunny"); + } +} diff --git a/src/main/java/seedu/address/model/diary/weather/Weather.java b/src/main/java/seedu/address/model/diary/weather/Weather.java new file mode 100644 index 00000000000..15b4e901453 --- /dev/null +++ b/src/main/java/seedu/address/model/diary/weather/Weather.java @@ -0,0 +1,17 @@ +package seedu.address.model.diary.weather; + +/** + * Represents a particular weather. + */ +public abstract class Weather { + private final String weather; + + protected Weather(String weather) { + this.weather = weather; + } + + @Override + public String toString() { + return weather; + } +} diff --git a/src/main/java/seedu/address/model/diary/weather/WindyWeather.java b/src/main/java/seedu/address/model/diary/weather/WindyWeather.java new file mode 100644 index 00000000000..2878d4720b5 --- /dev/null +++ b/src/main/java/seedu/address/model/diary/weather/WindyWeather.java @@ -0,0 +1,10 @@ +package seedu.address.model.diary.weather; + +/** + * Represents a windy weather. Extends from abstract class Weather. + */ +public class WindyWeather extends Weather { + public WindyWeather() { + super("windy"); + } +} diff --git a/src/main/java/seedu/address/model/notes/Notes.java b/src/main/java/seedu/address/model/notes/Notes.java new file mode 100644 index 00000000000..078b42b1595 --- /dev/null +++ b/src/main/java/seedu/address/model/notes/Notes.java @@ -0,0 +1,183 @@ +package seedu.address.model.notes; + +import static java.util.Objects.requireNonNull; + +import java.io.File; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.regex.Pattern; + +import javafx.beans.property.ReadOnlyObjectWrapper; +import javafx.beans.value.ObservableValue; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; + + +/** + * Represents a Note to be created. + * Guarantees: details are present and not null, field values are validated, immutable. + */ +public class Notes { + + public static final String MESSAGE_CONSTRAINTS = + "operation should contain open, create, createfolder and delete only and it should not be left blank."; + + public static final String MESSAGE_CONSTRAINTS_PATH_TYPE = + "Path type should only be abs(Absolute) or rel(Relative)"; + + public static final String MESSAGE_CONSTRAINTS_TYPE = + "Type must be only file or folder"; + + public static final String HOME_DIRECTORY = System.getProperty("user.home"); + + private static String currentDirectory = HOME_DIRECTORY; + + private static ObservableValue observableCurrentDirectory = + new ReadOnlyObjectWrapper<>("Current Directory " + currentDirectory); + + private static final String[] validType = {"file", "folder"}; + + private static final String[] validPathType = {"abs", "rel"}; + + private static ObservableList filesArrayListFiltered; + + private String path; + private String type; + private String pathType; + + public Notes(String path, String pathType) { + requireNonNull(path); + this.path = path; + this.pathType = pathType; + } + + public Notes(String path, String type, String pathType) { + requireNonNull(path); + this.path = path; + this.type = type; + this.pathType = pathType; + } + + public Notes(String path) { + requireNonNull(path); + this.path = path; + } + + public static ObservableList getAllFilesInFolder() { + + File myFile = new File(HOME_DIRECTORY); + ArrayList filesArrayList = new ArrayList<>(); + + File[] allFiles = myFile.listFiles(); + for (File f : allFiles) { + String[] allFileName = f.toString().split(Pattern.quote(File.separator)); + String fileName = allFileName[allFileName.length - 1]; + if (fileName.charAt(0) == ('.')) { + continue; + } + Notes note = new Notes(fileName); + filesArrayList.add(note); + } + + filesArrayListFiltered = FXCollections.observableArrayList(filesArrayList); + return filesArrayListFiltered; + } + + public static void setList(ArrayList notesList) { + + filesArrayListFiltered.setAll(notesList); + Comparator comparator = new Comparator() { + @Override + public int compare(Notes o1, Notes o2) { + return (o1.getPath().compareToIgnoreCase(o2.getPath())); + } + }; + FXCollections.sort(filesArrayListFiltered, comparator); + + + } + + /** + * Return if it is a valid type. + * + * @param checkType type that is to be checked + * @return true if valid false if not + */ + public static boolean isValidType(String checkType) { + + for (String type : validType) { + if (checkType.equals(type)) { + return true; + } + + } + return false; + + } + + /** + * Return if it is a valid path. + * + * @param checkPathType path that is to be checked + * @return true if valid false if not + */ + public static boolean isValidPathType(String checkPathType) { + + for (String pathType : validPathType) { + if (checkPathType.equals(pathType)) { + return true; + } + } + return false; + + } + + public static String getCurrentDirectory() { + return currentDirectory; + } + + + public static void setCurrentDirectory(String directory) { + + currentDirectory = directory; + } + + public String getPath() { + return this.path; + } + + public String getFilePathType() { + return this.pathType; + } + + public String getType() { + return this.type; + } + + @Override + public boolean equals(Object other) { + + boolean flag = other == this // short circuit if same object + || (other instanceof Notes // instanceof handles nulls + && this.path.equals(((Notes) other).getPath()) + && this.pathType.equals(((Notes) other).getFilePathType())); + if (flag == false) { + return false; + } else { + boolean typeFlag = false; + if (type == null) { + typeFlag = true; + } else { + typeFlag = this.type.equals(((Notes) other).getType()); + } + return flag && typeFlag; + } + } + + @Override + public int hashCode() { + return (path + pathType).hashCode(); + } + + +} diff --git a/src/main/java/seedu/address/model/nusmodule/Capulator.java b/src/main/java/seedu/address/model/nusmodule/Capulator.java new file mode 100644 index 00000000000..03c1ca24bf0 --- /dev/null +++ b/src/main/java/seedu/address/model/nusmodule/Capulator.java @@ -0,0 +1,37 @@ +package seedu.address.model.nusmodule; + +import java.util.List; + +/** + * Represents a device that can help NUS students to calculate their current CAP based on their graded modules. + */ +public class Capulator { + private List modules; + + public Capulator(List modules) { + this.modules = modules; + } + + /** + * calculates the CAP based on graded NUS modules in records. + * @return a double represents the CAP gotten. + */ + public double calculateCap() { + + double sumOfGradePoints = 0; + double sumOfModularCredits = 0; + + for (NusModule module: modules) { + if (module.getGrade().isPresent() && !module.getGrade().get().isSued()) { + sumOfModularCredits += module.modularCredit; + sumOfGradePoints += module.modularCredit * module.getGradePoint(); + } + } + + if (sumOfModularCredits == 0.0) { + return 0; + } + + return sumOfGradePoints / sumOfModularCredits; + } +} diff --git a/src/main/java/seedu/address/model/nusmodule/Grade.java b/src/main/java/seedu/address/model/nusmodule/Grade.java new file mode 100644 index 00000000000..4a6fc5e7c68 --- /dev/null +++ b/src/main/java/seedu/address/model/nusmodule/Grade.java @@ -0,0 +1,84 @@ +package seedu.address.model.nusmodule; + +/** + * Represents the grades obtained by a NUS student for any specific module. + */ +public enum Grade { + APLUS(5.0, "A+", true, true), + A(5.0, "A", true, true), + AMINUS(4.5, "A-", true, true), + BPLUS(4.0, "B+", true, true), + B(3.5, "B", true, true), + BMINUS(3.0, "B-", true, true), + CPLUS(2.5, "C+", true, true), + C(2.0, "C", true, true), + DPLUS(1.5, "D+", true, false), + D(1.0, "D", true, false), + F(0.0, "F", false, false), + S(0.0, "S", true, true), + U(0.0, "U", false, false); + + public static final String MESSAGE_CONSTRAINTS = "Please enter valid grade."; + + private final double point; + private final String text; + private final boolean isPassed; + private final boolean isSatisfactory; + + Grade(double point, String text, boolean isPassed, boolean isSatisfactory) { + this.point = point; + this.text = text; + this.isPassed = isPassed; + this.isSatisfactory = isSatisfactory; + } + + public static Grade getGrade(String text) { + Grade grade = null; + for (Grade g : values()) { + if (g.text.equals(text)) { + grade = g; + } + } + return grade; + } + + public static Grade getGradeAfterSu(String text) { + for (Grade g : values()) { + if (g.text.equals(text) && g.isSatisfactory) { + return S; + } + } + return U; + } + + /** + * checks whether the Grade object represents a grade that has been SUed or not. + * @return true if the Grade object represents a grade that has been SUed or false if otherwise. + */ + public boolean isSued() { + if (this.equals(S) || this.equals(U)) { + return true; + } + return false; + } + + public double getPoint() { + return this.point; + } + + public String getText() { + return this.text; + } + + /** + * Returns if a given string is a valid grade. + */ + public static boolean isValidGrade(String test) { + for (Grade g : values()) { + if (g.text.equals(test)) { + return true; + } + } + return false; + } +} diff --git a/src/main/java/seedu/address/model/nusmodule/Major.java b/src/main/java/seedu/address/model/nusmodule/Major.java new file mode 100644 index 00000000000..d540390269c --- /dev/null +++ b/src/main/java/seedu/address/model/nusmodule/Major.java @@ -0,0 +1,52 @@ +package seedu.address.model.nusmodule; + +import static java.util.Objects.requireNonNull; +import static seedu.address.commons.util.AppUtil.checkArgument; + +/** + * Represents a major in NUS. + */ +public class Major { + + public static final String MESSAGE_CONSTRAINTS = + "Please enter a valid major name in NUS (e.g. Computer Science)"; + + public final String nameOfMajor; + + /** + * Constructs a {@code Name}. + * + * @param name A valid name. + */ + public Major(String name) { + requireNonNull(name); + checkArgument(isValidMajor(name), MESSAGE_CONSTRAINTS); + nameOfMajor = name; + } + + /** + * Returns true if a given string is a valid major. + */ + public static boolean isValidMajor(String test) { + //implement later + return true; + } + + + @Override + public String toString() { + return nameOfMajor; + } + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof Major // instanceof handles nulls + && nameOfMajor.equals(((Major) other).nameOfMajor)); // state check + } + + @Override + public int hashCode() { + return nameOfMajor.hashCode(); + } +} diff --git a/src/main/java/seedu/address/model/nusmodule/ModuleCode.java b/src/main/java/seedu/address/model/nusmodule/ModuleCode.java new file mode 100644 index 00000000000..cbfbfd58622 --- /dev/null +++ b/src/main/java/seedu/address/model/nusmodule/ModuleCode.java @@ -0,0 +1,45 @@ +package seedu.address.model.nusmodule; + +import static java.util.Objects.requireNonNull; + +import seedu.address.searcher.Search; + +/** + * Represents a NUS module's module code. + */ +public class ModuleCode { + + public static final String MESSAGE_CONSTRAINTS = "Please enter valid module code"; + + public final String code; + + public ModuleCode(String code) { + requireNonNull(code); + this.code = code; + } + + /** + * Returns if a given string is a valid module code. + */ + public static boolean isValidModuleCode(String test) { + try { + Search.findModule(test); + } catch (Exception e) { + return false; + } + return true; + } + + @Override + public String toString() { + return this.code; + } + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof ModuleCode // instanceof handles nulls + && code.equals(((ModuleCode) other).code)); // state check + } + +} diff --git a/src/main/java/seedu/address/model/nusmodule/ModuleTask.java b/src/main/java/seedu/address/model/nusmodule/ModuleTask.java new file mode 100644 index 00000000000..61bce837e76 --- /dev/null +++ b/src/main/java/seedu/address/model/nusmodule/ModuleTask.java @@ -0,0 +1,69 @@ +package seedu.address.model.nusmodule; + +import java.util.StringJoiner; + +import seedu.address.model.calender.Task; + +/** + * Represents a task related to a specific module. (e.g. an assignment of module CS2103T) + */ +public class ModuleTask extends Task { + + private final ModuleCode moduleRelated; + private final String timing; + private final Priority priority; + + public ModuleTask(String description, ModuleCode moduleRelated, String timing, Priority priority) { + super(description); + this.moduleRelated = moduleRelated; + this.timing = timing; + this.priority = priority; + } + + public ModuleCode getModuleRelated() { + return this.moduleRelated; + } + + public String getDate() { + return timing; + } + + public Priority getPriority() { + return priority; + } + + public int getDoneStatus() { + return isDone ? 1 : 0; + } + + public String getDoneMessage() { + return isDone ? "completed" : "not completed"; + } + + @Override + public String toString() { + StringJoiner sj = new StringJoiner(" "); + String desiredString = sj.add(this.getDescription()).add(moduleRelated.toString()) + .add(timing.toString()).add(priority.toString()).add(getDoneMessage()).toString(); + return desiredString; + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + if (!(other instanceof ModuleTask)) { + return false; + } + + ModuleTask otherTask = (ModuleTask) other; + return otherTask.getDescription().equals(getDescription()) + && otherTask.getDate().equals(this.getDate()) + && otherTask.getModuleRelated().equals(getModuleRelated()) + && otherTask.getPriority().equals(getPriority()); + + } + +} diff --git a/src/main/java/seedu/address/model/nusmodule/NusModule.java b/src/main/java/seedu/address/model/nusmodule/NusModule.java new file mode 100644 index 00000000000..33cc144d3ec --- /dev/null +++ b/src/main/java/seedu/address/model/nusmodule/NusModule.java @@ -0,0 +1,63 @@ +package seedu.address.model.nusmodule; + +import java.util.List; +import java.util.Optional; + +/** + * Represents a module in NUS. + */ +public class NusModule { + public final ModuleCode moduleCode; + public final int modularCredit; + private Optional grade; + private List tasks; + + public NusModule(ModuleCode moduleCode, int modularCredit, + Optional grade, List tasks) { + this.moduleCode = moduleCode; + this.modularCredit = modularCredit; + this.grade = grade; + this.tasks = tasks; + } + + public void addTask(ModuleTask task) { + tasks.add(task); + } + + public List getTasks() { + return this.tasks; + } + + public double getGradePoint() { + return this.grade.get().getPoint(); + } + + public Optional getGrade() { + return this.grade; + } + + public void setGrade(Grade grade) { + this.grade = Optional.ofNullable(grade); + } + + public ModuleCode getModuleCode() { + return this.moduleCode; + } + + public int getModularCredit() { + return this.modularCredit; + } + + @Override + public String toString() { + return moduleCode.toString(); + } + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof NusModule // instanceof handles nulls + && moduleCode.equals(((NusModule) other).moduleCode)); // state check + } +} + diff --git a/src/main/java/seedu/address/model/nusmodule/Priority.java b/src/main/java/seedu/address/model/nusmodule/Priority.java new file mode 100644 index 00000000000..99021388256 --- /dev/null +++ b/src/main/java/seedu/address/model/nusmodule/Priority.java @@ -0,0 +1,59 @@ +package seedu.address.model.nusmodule; + +/** + * Represents the priority of certain module tasks. + */ +public enum Priority { + VERYHIGH("Very high", 5), + HIGH("High", 4), + MEDIAN("Medium", 3), + LOW("Low", 2), + VERYLOW("Very low", 1); + + public static final String MESSAGE_CONSTRAINTS = "Please enter valid priority (an integer from 1 to 5)"; + + private final String text; + private final int levelOfSignificance; + + Priority(String text, int levelOfSignificance) { + this.text = text; + this.levelOfSignificance = levelOfSignificance; + } + + /** + * Returns if a given string is a valid priority. + */ + public static boolean isValidPriority(String test) { + try { + Integer.parseInt(test); + } catch (NumberFormatException e) { + return false; + } + + for (Priority p : values()) { + if (p.levelOfSignificance == Integer.parseInt(test)) { + return true; + } + } + return false; + } + + public static Priority getPriority(String text) { + Priority priority = null; + for (Priority p : values()) { + if (p.levelOfSignificance == Integer.parseInt(text)) { + priority = p; + } + } + return priority; + } + + public int getLevelOfSignificance() { + return this.levelOfSignificance; + } + + @Override + public String toString() { + return this.text; + } +} diff --git a/src/main/java/seedu/address/model/person/Address.java b/src/main/java/seedu/address/model/person/Address.java deleted file mode 100644 index 60472ca22a0..00000000000 --- a/src/main/java/seedu/address/model/person/Address.java +++ /dev/null @@ -1,57 +0,0 @@ -package seedu.address.model.person; - -import static java.util.Objects.requireNonNull; -import static seedu.address.commons.util.AppUtil.checkArgument; - -/** - * Represents a Person's address in the address book. - * Guarantees: immutable; is valid as declared in {@link #isValidAddress(String)} - */ -public class Address { - - public static final String MESSAGE_CONSTRAINTS = "Addresses can take any values, and it should not be blank"; - - /* - * The first character of the address must not be a whitespace, - * otherwise " " (a blank string) becomes a valid input. - */ - public static final String VALIDATION_REGEX = "[^\\s].*"; - - public final String value; - - /** - * Constructs an {@code Address}. - * - * @param address A valid address. - */ - public Address(String address) { - requireNonNull(address); - checkArgument(isValidAddress(address), MESSAGE_CONSTRAINTS); - value = address; - } - - /** - * Returns true if a given string is a valid email. - */ - public static boolean isValidAddress(String test) { - return test.matches(VALIDATION_REGEX); - } - - @Override - public String toString() { - return value; - } - - @Override - public boolean equals(Object other) { - return other == this // short circuit if same object - || (other instanceof Address // instanceof handles nulls - && value.equals(((Address) other).value)); // state check - } - - @Override - public int hashCode() { - return value.hashCode(); - } - -} diff --git a/src/main/java/seedu/address/model/person/Person.java b/src/main/java/seedu/address/model/person/Person.java index 557a7a60cd5..20db18ef108 100644 --- a/src/main/java/seedu/address/model/person/Person.java +++ b/src/main/java/seedu/address/model/person/Person.java @@ -9,6 +9,7 @@ import seedu.address.model.tag.Tag; + /** * Represents a Person in the address book. * Guarantees: details are present and not null, field values are validated, immutable. @@ -21,18 +22,16 @@ public class Person { private final Email email; // Data fields - private final Address address; private final Set tags = new HashSet<>(); /** * Every field must be present and not null. */ - public Person(Name name, Phone phone, Email email, Address address, Set tags) { - requireAllNonNull(name, phone, email, address, tags); + public Person(Name name, Phone phone, Email email, Set tags) { + requireAllNonNull(name, phone, email, tags); this.name = name; this.phone = phone; this.email = email; - this.address = address; this.tags.addAll(tags); } @@ -48,10 +47,6 @@ public Email getEmail() { return email; } - public Address getAddress() { - return address; - } - /** * Returns an immutable tag set, which throws {@code UnsupportedOperationException} * if modification is attempted. @@ -92,14 +87,13 @@ public boolean equals(Object other) { return otherPerson.getName().equals(getName()) && otherPerson.getPhone().equals(getPhone()) && otherPerson.getEmail().equals(getEmail()) - && otherPerson.getAddress().equals(getAddress()) && otherPerson.getTags().equals(getTags()); } @Override public int hashCode() { // use this method for custom fields hashing instead of implementing your own - return Objects.hash(name, phone, email, address, tags); + return Objects.hash(name, phone, email, tags); } @Override @@ -111,7 +105,6 @@ public String toString() { .append(" Email: ") .append(getEmail()) .append(" Address: ") - .append(getAddress()) .append(" Tags: "); getTags().forEach(builder::append); return builder.toString(); diff --git a/src/main/java/seedu/address/model/studentprofile/Profile.java b/src/main/java/seedu/address/model/studentprofile/Profile.java new file mode 100644 index 00000000000..4b7f8ac23bb --- /dev/null +++ b/src/main/java/seedu/address/model/studentprofile/Profile.java @@ -0,0 +1,62 @@ +package seedu.address.model.studentprofile; + +import java.util.ArrayList; + +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.value.ObservableValue; +import seedu.address.model.ModuleBook; +import seedu.address.model.nusmodule.Major; +import seedu.address.model.nusmodule.NusModule; + + +/** + * Creates a profile class to hold all profile information. + */ +public class Profile { + + private static SimpleStringProperty cap; + private static ArrayList modulesTaken; + private static ArrayList modulesCurrentlyTaking; + private String name; + private Major major; + private ObservableValue majorString; + + public Profile(ModuleBook moduleBook) { + + cap = new SimpleStringProperty("" + moduleBook.getCap()); + + } + + public static ArrayList getModulesTaken() { + return modulesTaken; + } + + public static ArrayList getModulesCurrentlyTaking() { + return modulesCurrentlyTaking; + } + + public SimpleStringProperty getCap() { + return cap; + } + + public String getName() { + return name; + } + + public ObservableValue getMajor() { + return majorString; + } + + public static void setCap(String value) { + cap.set(value); + } + + + public void setMajor(Major major) { + + this.major = major; + majorString = new SimpleStringProperty(major.nameOfMajor); + } + + +} diff --git a/src/main/java/seedu/address/model/util/SampleDataUtil.java b/src/main/java/seedu/address/model/util/SampleDataUtil.java index 1806da4facf..c8ca69d0cbc 100644 --- a/src/main/java/seedu/address/model/util/SampleDataUtil.java +++ b/src/main/java/seedu/address/model/util/SampleDataUtil.java @@ -6,7 +6,6 @@ import seedu.address.model.AddressBook; import seedu.address.model.ReadOnlyAddressBook; -import seedu.address.model.person.Address; import seedu.address.model.person.Email; import seedu.address.model.person.Name; import seedu.address.model.person.Person; @@ -20,22 +19,16 @@ public class SampleDataUtil { public static Person[] getSamplePersons() { return new Person[] { new Person(new Name("Alex Yeoh"), new Phone("87438807"), new Email("alexyeoh@example.com"), - new Address("Blk 30 Geylang Street 29, #06-40"), getTagSet("friends")), new Person(new Name("Bernice Yu"), new Phone("99272758"), new Email("berniceyu@example.com"), - new Address("Blk 30 Lorong 3 Serangoon Gardens, #07-18"), getTagSet("colleagues", "friends")), new Person(new Name("Charlotte Oliveiro"), new Phone("93210283"), new Email("charlotte@example.com"), - new Address("Blk 11 Ang Mo Kio Street 74, #11-04"), getTagSet("neighbours")), new Person(new Name("David Li"), new Phone("91031282"), new Email("lidavid@example.com"), - new Address("Blk 436 Serangoon Gardens Street 26, #16-43"), getTagSet("family")), new Person(new Name("Irfan Ibrahim"), new Phone("92492021"), new Email("irfan@example.com"), - new Address("Blk 47 Tampines Street 20, #17-35"), getTagSet("classmates")), new Person(new Name("Roy Balakrishnan"), new Phone("92624417"), new Email("royb@example.com"), - new Address("Blk 45 Aljunied Street 85, #11-31"), getTagSet("colleagues")) }; } diff --git a/src/main/java/seedu/address/searcher/Classes.java b/src/main/java/seedu/address/searcher/Classes.java new file mode 100644 index 00000000000..e0ed620f218 --- /dev/null +++ b/src/main/java/seedu/address/searcher/Classes.java @@ -0,0 +1,60 @@ +package seedu.address.searcher; + +/** + *

Classes Class

+ * + * A class to hold information about each class timetable slot + */ +public class Classes { + private String classNo; + private String startTime; + private String endTime; + private int size; + private String venue; + private String day; + private String lessonType; + + public Classes(String input) { + this.classNo = input.substring(3, input.indexOf("startTime") - 3); + this.startTime = input.substring(input.indexOf("startTime") + 12, input.indexOf("endTime") - 3); + this.endTime = input.substring(input.indexOf("endTime") + 10, input.indexOf("weeks") - 3); + this.size = Integer.parseInt(input.substring(input.indexOf("size") + 6)); + this.venue = input.substring(input.indexOf("venue") + 8, input.indexOf("\"day\":") - 3); + this.day = input.substring(input.indexOf("\"day\":") + 7, input.indexOf("lessonType") - 3); + this.lessonType = input.substring(input.indexOf("lessonType") + 13, input.indexOf("size") - 3); + } + + @Override + public String toString() { + String output = ""; + output = output + "Class ID: " + this.classNo + " " + this.lessonType + "\n"; + output = output + "Start Time: " + this.startTime + " End Time: " + this.endTime + " " + this.day + "\n"; + output = output + "Size: " + this.size + "\n"; + output = output + "Venue: " + this.venue + "\n"; + return output; + } + + public String getLessonType() { + return this.lessonType; + } + + public String getStartTime() { + return this.startTime; + } + + public String getClassNo() { + return this.classNo; + } + + public String getEndTime() { + return this.classNo; + } + + public String getDay() { + return this.day; + } + + public String getVenue() { + return this.venue; + } +} diff --git a/src/main/java/seedu/address/searcher/ModPlanClass.java b/src/main/java/seedu/address/searcher/ModPlanClass.java new file mode 100644 index 00000000000..cb37dec376d --- /dev/null +++ b/src/main/java/seedu/address/searcher/ModPlanClass.java @@ -0,0 +1,125 @@ +package seedu.address.searcher; + +import java.util.ArrayList; +import java.util.Arrays; + +/** + * WIP + */ +public class ModPlanClass { + private static final ArrayList allMajors = new ArrayList<>( + Arrays.asList("Chinese Language", "Chinese Studies", "Japanese Studies", "Malay Studies", + "South Asian Studies", "Southeast Asian Studies", "English Language", "English Literature", + "History", "Philosophy", "Theater Studies", "Communications and New Media", "Economics", + "Geography", "Political Science", "Psychology", "Social Work", "Sociology", + "Environmental Studies in Geography", "Global Studies", "Business Administration(Accountancy)", + "Business Administration", "Business Analytics", "Computer Science", "Information Systems", + "Information Security", "Computer Engineering", "Dentistry", "Architecture", "Industrial Design", + "Landscape Architecture", "Project and Facilities Management", "Real Estate", + "Biomedical Engineering", "Chemical Engineering", "Civil Engineering", "Engineering Science", + "Environmental Engineering", "Electrical Engineering", "Industrial and Systems Engineering", + "Material Science Engineering", "Mechanical Engineering", "Computer Engineering", + "Undergraduate Law Programme", "Graduate LL.B. Programme", "Medicine", "Nursing", "Music", + "Applied Mathematics", "Chemistry", "Computational Biology", "Data Science and Analytics", + "Environmental Studies in Biology", "Food Science and Technology", "Life Sciences", "Mathematics", + "Pharmacy", "Pharmaceutical Science", "Physics", "Quantitative Finance", "Statistics")); + + private static ArrayList statisticsReq = new ArrayList<>(Arrays.asList("ST1131 /OR ST1232", "MA1101R", + "MA1102R", "CS1010E /OR CS1010S /OR CS1010X", "ST2131 /OR MA2216", "ST2132", "ST2137", + "MA2311 /OR MA2104 /OR MA2108S", "ST3131", "ST3236 /OR MA3238", "ST4199", "ST4231", "ST4233")); + + private static final ArrayList computerScienceReq = new ArrayList<>(Arrays.asList("CS1101S", "CS1231S", + "CS2030S", "CS2040S", "CS2100", "CS2103T", "CS2106", "CS3230", "IS1103", "CS2101", "ES2660", "MA1521", + "MA1101R", "ST2334")); + + private static final ArrayList informationSystemsReq = new ArrayList<>(Arrays.asList("CS1010J", "CS1231", + "IS1103", "CS2030", "CS2040", "CS2102", "CS2105", "IS2101", "IS2102", "IS2103", "IS3103", "IS3106", + "IS4100", "IS4103", "MA1301", "MA1312", "ST2334")); + + private static final ArrayList computerEngineeringReq = new ArrayList<>(Arrays.asList("CS1010", "CS2040C", + "CS2113T", "CG2271", "CG2027", "EE2026", "CG2028", "EE4204", "CG2023", "CG1111", "CG1112", "CG4002", + "CS1231", "MA1511", "MA1512", "MA1508E", "ST2334", "CS2101", "EG2401A")); + + private static final ArrayList businessAnalyticsReq = new ArrayList<>(Arrays.asList("BT1101", "CS1010S", + "EC1301", "IS1103", "MKT1705X", "BT2101", "BT2102", "CS2030", "CS2040", "IS2101", "ST2334", + "BT3102", "BT3103", "IS3103", "BT4103")); + + private static final ArrayList informationSecurityReq = new ArrayList<>(Arrays.asList("CS1010", "CS1231S", + "CS2040C", "CS2100", "CS2102", "CS2113T", "CS2105", "CS2106", "IS3103", "CS2107", "CS3235", "IS4231", + "IS1103", "CS2101", "MA1101R", "MA1521", "ST2334")); + + public static ArrayList getAllMajors() { + return allMajors; + } + + public static ArrayList getComputerScienceReq() { + return computerScienceReq; + } + + public static ArrayList getInformationSystemsReq() { + return informationSystemsReq; + } + + public static ArrayList getComputerEngineeringReq() { + return computerEngineeringReq; + } + + public static ArrayList getBusinessAnalyticsReq() { + return businessAnalyticsReq; + } + + public static ArrayList getInformationSecurityReq() { + return informationSystemsReq; + } + + /** + * Takes in a major and a mod code + * + * @param major (e.g Computer Science or Information Systems) + * @param mod (any mod code e.g CS1101S) + * @return true if mod (mod code) is a compulsory core mod of Major + */ + public static boolean checkIfCoreMod(String major, String mod) { + switch (major.toUpperCase()) { + case "COMPUTER SCIENCE": + for (String curr : computerScienceReq) { + if (curr.equals(mod)) { + return true; + } + } + return false; + + case "INFORMATION SYSTEMS": + for (String curr : informationSystemsReq) { + if (curr.equals(mod)) { + return true; + } + } + return false; + + case "COMPUTER ENGINEERING": + for (String curr : computerEngineeringReq) { + if (curr.equals(mod)) { + return true; + } + } + return false; + case "BUSINESS ANALYTICS": + for (String curr : businessAnalyticsReq) { + if (curr.equals(mod)) { + return true; + } + } + return false; + case "INFORMATION SECURITY": + for (String curr : informationSecurityReq) { + if (curr.equals(mod)) { + return true; + } + } + return false; + default: + return false; + } + } +} diff --git a/src/main/java/seedu/address/searcher/ModPlanLogic.java b/src/main/java/seedu/address/searcher/ModPlanLogic.java new file mode 100644 index 00000000000..8bd836f009c --- /dev/null +++ b/src/main/java/seedu/address/searcher/ModPlanLogic.java @@ -0,0 +1,80 @@ +package seedu.address.searcher; + +import java.util.ArrayList; + +/** + *

Module Planner Logic Class

+ * Just a class to handle logic behind module planning + */ +public class ModPlanLogic { + /** + * Function to check if Modules, myMod and toCheck, + * have clashing lecture slots + * @param myMod module in question + * @param toCheck module to check + * @param sem which sem you planning + * @return true if there is a clash, false otherwise + */ + public static boolean checkLectureClash (Module myMod, Module toCheck, int sem) { + ArrayList myModLectures; + ArrayList toCheckLectures; + + if (sem == 1) { + myModLectures = myMod.getSem1Lectures(); + toCheckLectures = toCheck.getSem1Lectures(); + } else { + myModLectures = myMod.getSem2Lectures(); + toCheckLectures = toCheck.getSem2Lectures(); + } + + for (Classes myModCurr : myModLectures) { + String myModCurrDay = myModCurr.getDay(); + int myModCurrStart = Integer.parseInt(myModCurr.getStartTime()); + int myModCurrEnd = Integer.parseInt(myModCurr.getEndTime()); + + for (Classes toCheckCurr : toCheckLectures) { + String toCheckCurrDay = toCheckCurr.getDay(); + int toCheckCurrStart = Integer.parseInt(toCheckCurr.getStartTime()); + int toCheckCurrEnd = Integer.parseInt(toCheckCurr.getEndTime()); + + if (myModCurrDay.equals(toCheckCurrDay)) { + if (myModCurrStart >= toCheckCurrStart) { + if (myModCurrStart >= toCheckCurrEnd) { + return false; + } + } else { + if (myModCurrEnd <= toCheckCurrStart) { + return false; + } + } + } else { + return false; + } + } + } + + return true; + } + + /** + * Function to check if two classes clash + * @param myClass first class + * @param toCheck second class + * @return true if there is clash false otherwise + */ + private static boolean checkClassClash (Classes myClass, Classes toCheck) { + int myClassStart = Integer.parseInt(myClass.getStartTime()); + int myClassEnd = Integer.parseInt(myClass.getEndTime()); + int toCheckStart = Integer.parseInt(myClass.getStartTime()); + int toCheckEnd = Integer.parseInt(toCheck.getEndTime()); + + + if (myClassStart > toCheckStart) { + return myClassStart < toCheckEnd; + } else if (myClassStart == toCheckStart) { + return true; + } else { + return myClassEnd > toCheckStart; + } + } +} diff --git a/src/main/java/seedu/address/searcher/Module.java b/src/main/java/seedu/address/searcher/Module.java new file mode 100644 index 00000000000..8a23986359e --- /dev/null +++ b/src/main/java/seedu/address/searcher/Module.java @@ -0,0 +1,212 @@ +package seedu.address.searcher; + +import java.util.ArrayList; + +/** + *

Module Class

+ * + * A simple class to hold module information + */ +public class Module { + private String title; + private String code; + private String department; + private String faculty; + private String description; + private String workload; + private String preclusion; + private int credits; + private String sem1Exam = "NA"; + private String sem2Exam = "NA"; + private ArrayList sem1Classes = new ArrayList<>(); + private ArrayList sem2Classes = new ArrayList<>(); + private ArrayList sem1Lectures = new ArrayList<>(); + private ArrayList sem1Tutorials = new ArrayList<>(); + private ArrayList sem1Others = new ArrayList<>(); + private ArrayList sem2Lectures = new ArrayList<>(); + private ArrayList sem2Tutorials = new ArrayList<>(); + private ArrayList sem2Others = new ArrayList<>(); + + /** + * Constructor for module class + * Parses info from http request into module + * access information easily by using class functions + * @param input this is raw HTTP data to be parsed + */ + public Module(String input) throws StringIndexOutOfBoundsException { + this.preclusion = input.substring(input.indexOf("preclusion") + 13, input.indexOf("description") - 3); + this.description = input.substring(input.indexOf("description") + 14, input.indexOf("title\":") - 3); + this.title = input.substring(input.indexOf("title") + 8, input.indexOf("department") - 3); + this.department = input.substring(input.indexOf("department") + 13, input.indexOf("faculty") - 3); + this.faculty = input.substring(input.indexOf("faculty") + 10, input.indexOf("workload") - 3); + this.workload = input.substring(input.indexOf("workload") + 10, input.indexOf("moduleCredit") - 2); + this.credits = Integer.parseInt(input.substring(input.indexOf("moduleCredit") + 15, + input.indexOf("moduleCode") - 3)); + + try { + this.code = input.substring(input.indexOf("moduleCode") + 13, input.indexOf("attributes") - 3); + } catch (StringIndexOutOfBoundsException e) { + this.code = input.substring(input.indexOf("moduleCode") + 13, input.indexOf("semesterData") - 3); + } + + String semesterData = input.substring(input.indexOf("semester\":")); + semesterData = semesterData.split("prereqTree")[0]; + semesterData = semesterData.split("fulfillRequirements")[0]; + parseSemData(semesterData); + splitClassByType(); + } + + /** + * Helper function for search function to parse class timetable information + * @param input string of class information + */ + private void parseSemData(String input) { + boolean hasSem1 = input.contains("semester\":1"); + boolean hasSem2 = input.contains("semester\":2"); + boolean hasExam = input.contains("examDate"); + String sem1Data = ""; + String sem2Data = ""; + + if (hasSem1 && hasExam) { + sem1Data = input.substring(input.indexOf("timetable") + 12, input.indexOf("examDate") - 4); + sem1Exam = input.substring(input.indexOf("examDate") + 11, input.indexOf("examDuration") - 3).split("T")[0]; + } else if (hasSem1) { + if (hasSem2) { + sem1Data = input.substring(input.indexOf("timetable") + 12, input.indexOf("semester\":2")); + } else { + sem1Data = input.substring(input.indexOf("timetable") + 12); + } + } + + String[] classes = sem1Data.split("classNo"); + + for (int i = 1; i < classes.length; i++) { + String temp = classes[i]; + temp = temp.split("},\\{")[0]; + Classes myClass = new Classes(temp); + sem1Classes.add(myClass); + } + + if (hasSem2) { + if (hasExam) { + sem2Data = input.substring(input.lastIndexOf("timetable") + 12, + input.lastIndexOf("examDate") - 4); + sem2Exam = input.substring(input.lastIndexOf("examDate") + 11, + input.lastIndexOf("examDuration") - 3).split("T")[0]; + } else { + sem2Data = input.substring(input.lastIndexOf("timetable") + 12); + } + } + + classes = sem2Data.split("classNo"); + + for (int i = 1; i < classes.length; i++) { + String temp = classes[i]; + temp = temp.split("},\\{")[0]; + Classes myClass = new Classes(temp); + sem2Classes.add(myClass); + } + } + + /** + * Helper Function for Constructor + */ + private void splitClassByType() { + for (Classes curr : sem1Classes) { + if (curr.getLessonType().equals("Lecture")) { + sem1Lectures.add(curr); + } else if (curr.getLessonType().equals("Tutorial")) { + sem1Tutorials.add(curr); + } else { + sem1Others.add(curr); + } + } + + for (Classes curr : sem2Classes) { + if (curr.getLessonType().equals("Lecture")) { + sem2Lectures.add(curr); + } else if (curr.getLessonType().equals("Tutorial")) { + sem2Tutorials.add(curr); + } else { + sem2Others.add(curr); + } + } + } + + public String getCode() { + return this.code; + } + + public String getTitle() { + return this.title; + } + + public String getDescription() { + return this.description; + } + + public ArrayList getSem1Classes() { + return sem1Classes; + } + + public String getSem1_exam() { + return sem1Exam; + } + + public ArrayList getSem2Classes() { + return sem2Classes; + } + + public String getSem2_exam() { + return sem2Exam; + } + + public int getCredits() { + return this.credits; + } + + public ArrayList getSem1Lectures() { + return this.sem1Lectures; + } + + public ArrayList getSem1Tutorials() { + return this.sem1Tutorials; + } + + public ArrayList getSem1Others() { + return this.sem1Others; + } + + public ArrayList getSem2Lectures() { + return this.sem2Lectures; + } + + public ArrayList getSem2Tutorials() { + return this.sem2Tutorials; + } + + public ArrayList getSem2Others() { + return this.sem2Others; + } + + @Override + public String toString() { + String output = ""; + + output = output + this.code + " " + this.title + "\n"; + output = output + "Faculty: " + this.faculty + "\n"; + output = output + "Department: " + this.department + "\n"; + output = output + "Credit Units: " + this.credits + "\n"; + output = output + "Workload: " + this.workload + "\n"; + output = output + this.description + "\n"; + + if (!sem1Exam.equals("")) { + output = output + "Semester 1 Exam: " + sem1Exam + "\n"; + } + + if (!sem2Exam.equals("")) { + output = output + "Semester 2 Exam: " + sem2Exam + "\n"; + } + return output; + } +} diff --git a/src/main/java/seedu/address/searcher/Search.java b/src/main/java/seedu/address/searcher/Search.java new file mode 100644 index 00000000000..860f102b03e --- /dev/null +++ b/src/main/java/seedu/address/searcher/Search.java @@ -0,0 +1,92 @@ +package seedu.address.searcher; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.URL; +import javax.net.ssl.HttpsURLConnection; + +/** + *

Search Class

+ * + * Class provides simple search function which takes in + * a module code and outputs simple module information + * taken from NUSMODs + */ +public class Search { + /** + * Function takes in module code and returns Module Object. + * For more info on Module Object, look at module Class. + * @param moduleCode input Module Code all caps + * @return module + */ + public static Module findModule(String moduleCode) { + String fileName = moduleCode + ".txt"; + File tempFile = new File("." + File.separator + "src" + File.separator + "main" + + File.separator + "java" + File.separator + "seedu" + File.separator + + "address" + File.separator + "searcher" + File.separator + + "cache" + File.separator + fileName); + + String output = ""; + + try { + BufferedReader myReader = new BufferedReader(new FileReader(tempFile)); + String tempString; + while ((tempString = myReader.readLine()) != null) { + output = tempString; + } + } catch (FileNotFoundException e) { + String httpsUrl = "https://api.nusmods.com/v2/2019-2020/modules/" + moduleCode + ".json"; + URL url; + try { + url = new URL(httpsUrl); + HttpsURLConnection con = (HttpsURLConnection) url.openConnection(); + output = print_content(con); + } catch (IOException d) { + d.printStackTrace(); + } + + try { + BufferedWriter myWriter = new BufferedWriter(new FileWriter(tempFile)); + myWriter.write(output); + myWriter.close(); + } catch (IOException f) { + f.printStackTrace(); + } + } catch (IOException e) { + e.printStackTrace(); + } + + return new Module(output); + } + + /** + * Function to get HTTP information + * @param con just java stuff + * @return Raw HTTP info in string + */ + private static String print_content(HttpsURLConnection con) { + String output = ""; + if (con != null) { + try { + BufferedReader br = + new BufferedReader( + new InputStreamReader(con.getInputStream())); + String input; + + while ((input = br.readLine()) != null) { + output = input; + } + br.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return output + "\n"; + } +} diff --git a/src/main/java/seedu/address/searcher/cache/.txt b/src/main/java/seedu/address/searcher/cache/.txt new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/.txt @@ -0,0 +1 @@ + diff --git a/src/main/java/seedu/address/searcher/cache/12312rd.txt b/src/main/java/seedu/address/searcher/cache/12312rd.txt new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/12312rd.txt @@ -0,0 +1 @@ + diff --git a/src/main/java/seedu/address/searcher/cache/A.txt b/src/main/java/seedu/address/searcher/cache/A.txt new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/A.txt @@ -0,0 +1 @@ + diff --git a/src/main/java/seedu/address/searcher/cache/ASDASD.txt b/src/main/java/seedu/address/searcher/cache/ASDASD.txt new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/ASDASD.txt @@ -0,0 +1 @@ + diff --git a/src/main/java/seedu/address/searcher/cache/CASDAS.txt b/src/main/java/seedu/address/searcher/cache/CASDAS.txt new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/CASDAS.txt @@ -0,0 +1 @@ + diff --git a/src/main/java/seedu/address/searcher/cache/CS1010.txt b/src/main/java/seedu/address/searcher/cache/CS1010.txt new file mode 100644 index 00000000000..4fef0ea4943 --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/CS1010.txt @@ -0,0 +1 @@ +{"acadYear":"2019/2020","preclusion":"CS1010E, CS1010J, CS1010S, CS1010X, CS1010XCP, CS1101S","description":"This module introduces the fundamental concepts of problem solving by computing and programming using an imperative programming language. It is the first and foremost introductory course to computing. Topics covered include computational thinking and computational problem solving, designing and specifying an algorithm, basic problem formulation and problem solving approaches, program development, coding, testing and debugging, fundamental programming constructs (variables, types, expressions, assignments, functions, control structures, etc.), fundamental data structures (arrays, strings, composite data types), basic sorting, and recursion.","title":"Programming Methodology","department":"Computer Science","faculty":"Computing","workload":[2,1,1,3,3],"moduleCredit":"4","moduleCode":"CS1010","attributes":{"su":true},"semesterData":[{"semester":1,"timetable":[{"classNo":"01","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B108","day":"Tuesday","lessonType":"Tutorial","size":17},{"classNo":"02","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B111","day":"Tuesday","lessonType":"Tutorial","size":17},{"classNo":"03","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B111","day":"Tuesday","lessonType":"Tutorial","size":17},{"classNo":"04","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B111","day":"Tuesday","lessonType":"Tutorial","size":17},{"classNo":"05","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B108","day":"Tuesday","lessonType":"Tutorial","size":17},{"classNo":"C02","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B108","day":"Tuesday","lessonType":"Tutorial","size":17},{"classNo":"C03","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B111","day":"Tuesday","lessonType":"Tutorial","size":17},{"classNo":"C09","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B108","day":"Monday","lessonType":"Tutorial","size":17},{"classNo":"C11","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B108","day":"Thursday","lessonType":"Tutorial","size":17},{"classNo":"C10","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B108","day":"Monday","lessonType":"Tutorial","size":17},{"classNo":"C1A","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B108","day":"Monday","lessonType":"Tutorial","size":17},{"classNo":"C04","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B111","day":"Thursday","lessonType":"Tutorial","size":17},{"classNo":"C05","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B110","day":"Thursday","lessonType":"Tutorial","size":17},{"classNo":"C06","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B108","day":"Tuesday","lessonType":"Tutorial","size":17},{"classNo":"C07","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B108","day":"Wednesday","lessonType":"Tutorial","size":17},{"classNo":"C08","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B111","day":"Wednesday","lessonType":"Tutorial","size":17},{"classNo":"1","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-AUD","day":"Wednesday","lessonType":"Sectional Teaching","size":300}],"examDate":"2019-11-27T09:00:00.000Z","examDuration":120},{"semester":2,"timetable":[{"classNo":"4","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B110","day":"Tuesday","lessonType":"Tutorial","size":15},{"classNo":"2","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B110","day":"Thursday","lessonType":"Tutorial","size":15},{"classNo":"1","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B110","day":"Monday","lessonType":"Tutorial","size":15},{"classNo":"3","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B110","day":"Thursday","lessonType":"Tutorial","size":15},{"classNo":"1","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0206","day":"Monday","lessonType":"Sectional Teaching","size":120}]}],"fulfillRequirements":["FIN4719","FIN4124","CP2106","CS1020","CS3237","CS2107","CS2040S","CS2040","CS2030","CS2040C","IT2001","IT2002","CS2100","BT2101","BT2102","IS4241","BT4222","IS3221","BT4221","BT4212","EE6934","EE4703","MA3269","DSA3102","ST3247","CG2028","CG1112","IT3011"]} diff --git a/src/main/java/seedu/address/searcher/cache/CS1010J.txt b/src/main/java/seedu/address/searcher/cache/CS1010J.txt new file mode 100644 index 00000000000..d846450cb5b --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/CS1010J.txt @@ -0,0 +1 @@ +{"acadYear":"2019/2020","preclusion":"CS1010 and its equivalents","description":"This module introduces the fundamental concepts of problem solving by computing and programming using an imperative programming language. It is the first and foremost introductory course to computing. Topics covered include computational thinking and computational problem solving, designing and specifying an algorithm, basic problem formulation and problem solving approaches, program development, coding, testing and debugging, fundamental programming constructs (variables, types, expressions, assignments, functions, control structures, etc.), fundamental data structures (arrays, strings, composite data types), basic sorting, and recursion.","title":"Programming Methodology","department":"Computer Science","faculty":"Computing","workload":[2,1,1,3,3],"moduleCredit":"4","moduleCode":"CS1010J","attributes":{"su":true},"semesterData":[{"semester":1,"timetable":[{"classNo":"03","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-0336","day":"Thursday","lessonType":"Tutorial","size":12},{"classNo":"14","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B112","day":"Friday","lessonType":"Tutorial","size":12},{"classNo":"11","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-0339","day":"Friday","lessonType":"Tutorial","size":12},{"classNo":"04","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B108","day":"Friday","lessonType":"Tutorial","size":12},{"classNo":"07","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-0336","day":"Friday","lessonType":"Tutorial","size":12},{"classNo":"05","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-0336","day":"Friday","lessonType":"Tutorial","size":12},{"classNo":"09","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B111","day":"Friday","lessonType":"Tutorial","size":12},{"classNo":"13","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B112","day":"Friday","lessonType":"Tutorial","size":12},{"classNo":"06","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-0339","day":"Wednesday","lessonType":"Tutorial","size":12},{"classNo":"12","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-0338","day":"Thursday","lessonType":"Tutorial","size":12},{"classNo":"01","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-0336","day":"Thursday","lessonType":"Tutorial","size":12},{"classNo":"10","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B108","day":"Friday","lessonType":"Tutorial","size":12},{"classNo":"08","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-0338","day":"Friday","lessonType":"Tutorial","size":12},{"classNo":"1","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"LT15","day":"Tuesday","lessonType":"Lecture","size":200},{"classNo":"02","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-0336","day":"Wednesday","lessonType":"Tutorial","size":12}],"examDate":"2019-11-27T09:00:00.000Z","examDuration":120}]} diff --git a/src/main/java/seedu/address/searcher/cache/CS1010S.txt b/src/main/java/seedu/address/searcher/cache/CS1010S.txt new file mode 100644 index 00000000000..00f35c8017d --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/CS1010S.txt @@ -0,0 +1 @@ +{"acadYear":"2019/2020","preclusion":"CS1010, CS1010E, CS1010J, CS1010X, CS1010XCP, CS1101S","description":"This module introduces the fundamental concepts of problem solving by computing and programming using an imperative programming language. It is the first and \nforemost introductory course to computing and is equivalent to CS1010 and CS1010E Programming Methodology. Topics covered include problem solving by computing, writing pseudo-codes, basic problem formulation and problem solving, program development, coding, testing and debugging, fundamental programming constructs (variables, types, expressions, assignments, functions, control structures, etc.), fundamental data structures: arrays, strings and structures, simple file processing, and basic recursion. This module is appropriate for FoS students.","title":"Programming Methodology","department":"Computer Science","faculty":"Computing","workload":[2,1,1,3,3],"moduleCredit":"4","moduleCode":"CS1010S","attributes":{"su":true},"semesterData":[{"semester":1,"timetable":[{"classNo":"2","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"LT26","day":"Wednesday","lessonType":"Lecture","size":325},{"classNo":"1","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"LT26","day":"Wednesday","lessonType":"Lecture","size":325},{"classNo":"44","startTime":"1800","endTime":"1930","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"","day":"Monday","lessonType":"Tutorial","size":16},{"classNo":"47","startTime":"2000","endTime":"2130","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"","day":"Monday","lessonType":"Tutorial","size":16},{"classNo":"49","startTime":"1800","endTime":"1930","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"","day":"Tuesday","lessonType":"Tutorial","size":16},{"classNo":"48","startTime":"2000","endTime":"2130","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"","day":"Monday","lessonType":"Tutorial","size":16},{"classNo":"50","startTime":"1800","endTime":"1930","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"","day":"Tuesday","lessonType":"Tutorial","size":16},{"classNo":"54","startTime":"2000","endTime":"2130","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"","day":"Tuesday","lessonType":"Tutorial","size":16},{"classNo":"19","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Monday","lessonType":"Tutorial","size":16},{"classNo":"37","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0120","day":"Tuesday","lessonType":"Tutorial","size":16},{"classNo":"40","startTime":"1700","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0120","day":"Tuesday","lessonType":"Tutorial","size":16},{"classNo":"06","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0620","day":"Monday","lessonType":"Tutorial","size":16},{"classNo":"07","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0620","day":"Monday","lessonType":"Tutorial","size":16},{"classNo":"11","startTime":"0800","endTime":"0900","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Monday","lessonType":"Tutorial","size":16},{"classNo":"18","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Monday","lessonType":"Tutorial","size":16},{"classNo":"08","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0620","day":"Monday","lessonType":"Tutorial","size":16},{"classNo":"04","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0620","day":"Monday","lessonType":"Tutorial","size":16},{"classNo":"07","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-0436","day":"Friday","lessonType":"Recitation","size":50},{"classNo":"04","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-0436","day":"Friday","lessonType":"Recitation","size":50},{"classNo":"15","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0212","day":"Friday","lessonType":"Recitation","size":50},{"classNo":"16","startTime":"1700","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0212","day":"Friday","lessonType":"Recitation","size":50},{"classNo":"01","startTime":"0800","endTime":"0900","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0620","day":"Monday","lessonType":"Tutorial","size":16},{"classNo":"03","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0620","day":"Monday","lessonType":"Tutorial","size":16},{"classNo":"34","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0120","day":"Tuesday","lessonType":"Tutorial","size":16},{"classNo":"35","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0120","day":"Tuesday","lessonType":"Tutorial","size":16},{"classNo":"36","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0120","day":"Tuesday","lessonType":"Tutorial","size":16},{"classNo":"52","startTime":"1900","endTime":"2030","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"","day":"Tuesday","lessonType":"Tutorial","size":16},{"classNo":"17","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Monday","lessonType":"Tutorial","size":16},{"classNo":"53","startTime":"2000","endTime":"2130","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"","day":"Tuesday","lessonType":"Tutorial","size":16},{"classNo":"29","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B110","day":"Tuesday","lessonType":"Tutorial","size":16},{"classNo":"30","startTime":"1700","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B110","day":"Tuesday","lessonType":"Tutorial","size":16},{"classNo":"31","startTime":"0800","endTime":"0900","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0120","day":"Tuesday","lessonType":"Tutorial","size":16},{"classNo":"32","startTime":"0900","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0120","day":"Tuesday","lessonType":"Tutorial","size":16},{"classNo":"21","startTime":"0800","endTime":"0900","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B110","day":"Tuesday","lessonType":"Tutorial","size":16},{"classNo":"27","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B110","day":"Tuesday","lessonType":"Tutorial","size":16},{"classNo":"28","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B110","day":"Tuesday","lessonType":"Tutorial","size":16},{"classNo":"38","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0120","day":"Tuesday","lessonType":"Tutorial","size":16},{"classNo":"39","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0120","day":"Tuesday","lessonType":"Tutorial","size":16},{"classNo":"13","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Monday","lessonType":"Tutorial","size":16},{"classNo":"15","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Monday","lessonType":"Tutorial","size":16},{"classNo":"16","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Monday","lessonType":"Tutorial","size":16},{"classNo":"20","startTime":"1700","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Monday","lessonType":"Tutorial","size":16},{"classNo":"24","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B110","day":"Tuesday","lessonType":"Tutorial","size":16},{"classNo":"25","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B110","day":"Tuesday","lessonType":"Tutorial","size":16},{"classNo":"26","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B110","day":"Tuesday","lessonType":"Tutorial","size":16},{"classNo":"12","startTime":"0900","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Monday","lessonType":"Tutorial","size":16},{"classNo":"10","startTime":"1700","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-0436","day":"Thursday","lessonType":"Recitation","size":50},{"classNo":"12","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-0436","day":"Thursday","lessonType":"Recitation","size":50},{"classNo":"13","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0204","day":"Thursday","lessonType":"Recitation","size":50},{"classNo":"14","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0204","day":"Thursday","lessonType":"Recitation","size":50},{"classNo":"19","startTime":"2000","endTime":"2130","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"","day":"Thursday","lessonType":"Recitation","size":50},{"classNo":"21","startTime":"1000","endTime":"1130","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"","day":"Friday","lessonType":"Recitation","size":50},{"classNo":"41","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0217","day":"Monday","lessonType":"Tutorial","size":16},{"classNo":"51","startTime":"1900","endTime":"2030","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"","day":"Tuesday","lessonType":"Tutorial","size":16},{"classNo":"22","startTime":"1000","endTime":"1130","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"","day":"Friday","lessonType":"Recitation","size":50},{"classNo":"09","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0620","day":"Monday","lessonType":"Tutorial","size":16},{"classNo":"05","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0620","day":"Monday","lessonType":"Tutorial","size":16},{"classNo":"33","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0120","day":"Tuesday","lessonType":"Tutorial","size":16},{"classNo":"22","startTime":"0900","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B110","day":"Tuesday","lessonType":"Tutorial","size":16},{"classNo":"42","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0217","day":"Monday","lessonType":"Tutorial","size":16},{"classNo":"45","startTime":"1900","endTime":"2030","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"","day":"Monday","lessonType":"Tutorial","size":16},{"classNo":"46","startTime":"1900","endTime":"2030","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"","day":"Monday","lessonType":"Tutorial","size":16},{"classNo":"14","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Monday","lessonType":"Tutorial","size":16},{"classNo":"23","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B110","day":"Tuesday","lessonType":"Tutorial","size":16},{"classNo":"20","startTime":"2000","endTime":"2130","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"","day":"Thursday","lessonType":"Recitation","size":50},{"classNo":"09","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-0436","day":"Thursday","lessonType":"Recitation","size":50},{"classNo":"43","startTime":"1800","endTime":"1930","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"","day":"Monday","lessonType":"Tutorial","size":16}],"examDate":"2019-11-27T09:00:00.000Z","examDuration":120},{"semester":2,"timetable":[{"classNo":"40","startTime":"1700","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM2-0108","day":"Tuesday","lessonType":"Tutorial","size":15},{"classNo":"01","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-0430","day":"Friday","lessonType":"Recitation","size":55},{"classNo":"20","startTime":"1700","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Tuesday","lessonType":"Tutorial","size":15},{"classNo":"14","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-0307","day":"Thursday","lessonType":"Recitation","size":55},{"classNo":"24","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM2-0108","day":"Monday","lessonType":"Tutorial","size":15},{"classNo":"08","startTime":"1700","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-0430","day":"Friday","lessonType":"Recitation","size":54},{"classNo":"09","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-0436","day":"Thursday","lessonType":"Recitation","size":55},{"classNo":"10","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0212","day":"Friday","lessonType":"Recitation","size":55},{"classNo":"35","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM2-0108","day":"Tuesday","lessonType":"Tutorial","size":15},{"classNo":"11","startTime":"0800","endTime":"0900","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Tuesday","lessonType":"Tutorial","size":15},{"classNo":"15","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Tuesday","lessonType":"Tutorial","size":15},{"classNo":"16","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Tuesday","lessonType":"Tutorial","size":15},{"classNo":"17","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Tuesday","lessonType":"Tutorial","size":15},{"classNo":"18","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Tuesday","lessonType":"Tutorial","size":15},{"classNo":"19","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Tuesday","lessonType":"Tutorial","size":15},{"classNo":"23","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM2-0108","day":"Monday","lessonType":"Tutorial","size":15},{"classNo":"02","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-0430","day":"Friday","lessonType":"Recitation","size":55},{"classNo":"03","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-0436","day":"Friday","lessonType":"Recitation","size":55},{"classNo":"04","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-0430","day":"Thursday","lessonType":"Recitation","size":54},{"classNo":"1","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"LT27","day":"Wednesday","lessonType":"Lecture","size":600},{"classNo":"38","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM2-0108","day":"Tuesday","lessonType":"Tutorial","size":15},{"classNo":"26","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM2-0108","day":"Monday","lessonType":"Tutorial","size":15},{"classNo":"28","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM2-0108","day":"Monday","lessonType":"Tutorial","size":15},{"classNo":"29","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM2-0108","day":"Monday","lessonType":"Tutorial","size":15},{"classNo":"33","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM2-0108","day":"Tuesday","lessonType":"Tutorial","size":15},{"classNo":"41","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0209","day":"Monday","lessonType":"Tutorial","size":15},{"classNo":"42","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0209","day":"Monday","lessonType":"Tutorial","size":15},{"classNo":"43","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0209","day":"Monday","lessonType":"Tutorial","size":15},{"classNo":"11","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0212","day":"Thursday","lessonType":"Recitation","size":55},{"classNo":"12","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0212","day":"Thursday","lessonType":"Recitation","size":55},{"classNo":"13","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0212","day":"Friday","lessonType":"Recitation","size":55},{"classNo":"02","startTime":"0900","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Monday","lessonType":"Tutorial","size":15},{"classNo":"09","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Monday","lessonType":"Tutorial","size":15},{"classNo":"04","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Monday","lessonType":"Tutorial","size":15},{"classNo":"05","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Monday","lessonType":"Tutorial","size":15},{"classNo":"06","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Monday","lessonType":"Tutorial","size":15},{"classNo":"08","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Monday","lessonType":"Tutorial","size":15},{"classNo":"01","startTime":"0800","endTime":"0900","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Monday","lessonType":"Tutorial","size":15},{"classNo":"03","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Monday","lessonType":"Tutorial","size":15},{"classNo":"05","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-0436","day":"Friday","lessonType":"Recitation","size":55},{"classNo":"36","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM2-0108","day":"Tuesday","lessonType":"Tutorial","size":15},{"classNo":"44","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0208","day":"Monday","lessonType":"Tutorial","size":15},{"classNo":"12","startTime":"0900","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Tuesday","lessonType":"Tutorial","size":15},{"classNo":"14","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Tuesday","lessonType":"Tutorial","size":15},{"classNo":"13","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Tuesday","lessonType":"Tutorial","size":15},{"classNo":"22","startTime":"0900","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM2-0108","day":"Monday","lessonType":"Tutorial","size":15},{"classNo":"32","startTime":"0900","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM2-0108","day":"Tuesday","lessonType":"Tutorial","size":15},{"classNo":"34","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM2-0108","day":"Tuesday","lessonType":"Tutorial","size":15},{"classNo":"21","startTime":"0800","endTime":"0900","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM2-0108","day":"Monday","lessonType":"Tutorial","size":15},{"classNo":"39","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM2-0108","day":"Tuesday","lessonType":"Tutorial","size":15},{"classNo":"25","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM2-0108","day":"Monday","lessonType":"Tutorial","size":15},{"classNo":"37","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM2-0108","day":"Tuesday","lessonType":"Tutorial","size":15},{"classNo":"10","startTime":"1700","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Monday","lessonType":"Tutorial","size":15},{"classNo":"27","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM2-0108","day":"Monday","lessonType":"Tutorial","size":15},{"classNo":"07","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Monday","lessonType":"Tutorial","size":15},{"classNo":"06","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-0436","day":"Friday","lessonType":"Recitation","size":55},{"classNo":"31","startTime":"0800","endTime":"0900","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM2-0108","day":"Tuesday","lessonType":"Tutorial","size":15},{"classNo":"07","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-0436","day":"Friday","lessonType":"Recitation","size":55},{"classNo":"30","startTime":"1700","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM2-0108","day":"Monday","lessonType":"Tutorial","size":15}],"examDate":"2020-05-04T01:00:00.000Z","examDuration":120}],"fulfillRequirements":["FIN4719","FIN4124","IT3010","ZB4171","LSM3241","MA3269","DSA3102","ST3247"]} diff --git a/src/main/java/seedu/address/searcher/cache/CS1101R.txt b/src/main/java/seedu/address/searcher/cache/CS1101R.txt new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/CS1101R.txt @@ -0,0 +1 @@ + diff --git a/src/main/java/seedu/address/searcher/cache/CS1101S.txt b/src/main/java/seedu/address/searcher/cache/CS1101S.txt new file mode 100644 index 00000000000..f15d9c8f85a --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/CS1101S.txt @@ -0,0 +1 @@ +{"acadYear":"2019/2020","preclusion":"CS1010 or its equivalents","description":"This module introduces the concepts of programming and computational problem solving, and is the first and foremost introductory module to computing. Starting from a small core of fundamental abstractions, the module introduces programming as a method for communicating computational processes. The module begins with purely functional programming based on a simple substitution-based execution model, and ends with a powerful modern imperative language based on a realistic environment-based execution model. Topics covered include: functional abstraction, recursion, higher-order functions, data abstraction, algorithmic strategies, state mutation, loops and arrays, evaluation strategies, sorting and searching, debugging and testing.","title":"Programming Methodology","department":"Computer Science","faculty":"Computing","workload":[2,2,1,3,2],"moduleCredit":"4","moduleCode":"CS1101S","attributes":{"su":true},"semesterData":[{"semester":1,"timetable":[{"classNo":"2","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"UT-AUD2","day":"Friday","lessonType":"Lecture","size":300},{"classNo":"2","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"UT-AUD2","day":"Wednesday","lessonType":"Lecture","size":300},{"classNo":"05F","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Monday","lessonType":"Tutorial","size":8},{"classNo":"05G","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Monday","lessonType":"Tutorial","size":8},{"classNo":"14","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0209","day":"Thursday","lessonType":"Recitation","size":27},{"classNo":"16","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0209","day":"Thursday","lessonType":"Recitation","size":27},{"classNo":"12","startTime":"0900","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0209","day":"Thursday","lessonType":"Recitation","size":27},{"classNo":"18","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0209","day":"Thursday","lessonType":"Recitation","size":27},{"classNo":"20","startTime":"1700","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0209","day":"Thursday","lessonType":"Recitation","size":27},{"classNo":"02D","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Monday","lessonType":"Tutorial","size":8},{"classNo":"02C","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Monday","lessonType":"Tutorial","size":8},{"classNo":"02A","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Monday","lessonType":"Tutorial","size":8},{"classNo":"02B","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Monday","lessonType":"Tutorial","size":8},{"classNo":"02J","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Monday","lessonType":"Tutorial","size":8},{"classNo":"03G","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Monday","lessonType":"Tutorial","size":8},{"classNo":"03E","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Monday","lessonType":"Tutorial","size":8},{"classNo":"03F","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Monday","lessonType":"Tutorial","size":8},{"classNo":"10","startTime":"1700","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Thursday","lessonType":"Recitation","size":25},{"classNo":"09","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Thursday","lessonType":"Recitation","size":25},{"classNo":"11","startTime":"0800","endTime":"0900","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0209","day":"Thursday","lessonType":"Recitation","size":27},{"classNo":"07","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Thursday","lessonType":"Recitation","size":25},{"classNo":"23","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0208","day":"Thursday","lessonType":"Recitation","size":27},{"classNo":"24","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0208","day":"Thursday","lessonType":"Recitation","size":27},{"classNo":"03","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Thursday","lessonType":"Recitation","size":25},{"classNo":"02","startTime":"0900","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Thursday","lessonType":"Recitation","size":25},{"classNo":"09C","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"09A","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"09E","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"09F","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"09G","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"06A","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"06C","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"06D","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"05A","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Monday","lessonType":"Tutorial","size":8},{"classNo":"05B","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Monday","lessonType":"Tutorial","size":8},{"classNo":"08G","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"08E","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"08F","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"08H","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0201","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"08I","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0201","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"1","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"UT-AUD2","day":"Friday","lessonType":"Lecture","size":300},{"classNo":"07D","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"07J","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"07B","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"07C","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"07A","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"07G","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"07E","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"07F","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"07H","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0201","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"07I","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0201","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"08D","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"08C","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"08B","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"06E","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"06F","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"04G","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Monday","lessonType":"Tutorial","size":8},{"classNo":"04F","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Monday","lessonType":"Tutorial","size":8},{"classNo":"04E","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Monday","lessonType":"Tutorial","size":8},{"classNo":"04D","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Monday","lessonType":"Tutorial","size":8},{"classNo":"04B","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Monday","lessonType":"Tutorial","size":8},{"classNo":"04J","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Monday","lessonType":"Tutorial","size":8},{"classNo":"04C","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Monday","lessonType":"Tutorial","size":8},{"classNo":"04A","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Monday","lessonType":"Tutorial","size":8},{"classNo":"03B","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Monday","lessonType":"Tutorial","size":8},{"classNo":"03C","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Monday","lessonType":"Tutorial","size":8},{"classNo":"03D","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Monday","lessonType":"Tutorial","size":8},{"classNo":"03A","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Monday","lessonType":"Tutorial","size":8},{"classNo":"13","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0209","day":"Thursday","lessonType":"Recitation","size":27},{"classNo":"15","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0209","day":"Thursday","lessonType":"Recitation","size":27},{"classNo":"10B","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"10A","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"10C","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"10F","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"10E","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"17","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0209","day":"Thursday","lessonType":"Recitation","size":27},{"classNo":"19","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0209","day":"Thursday","lessonType":"Recitation","size":27},{"classNo":"21","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0208","day":"Thursday","lessonType":"Recitation","size":27},{"classNo":"22","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0208","day":"Thursday","lessonType":"Recitation","size":27},{"classNo":"04","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Thursday","lessonType":"Recitation","size":25},{"classNo":"01","startTime":"0800","endTime":"0900","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Thursday","lessonType":"Recitation","size":25},{"classNo":"1","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"UT-AUD2","day":"Wednesday","lessonType":"Lecture","size":300},{"classNo":"01B","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Monday","lessonType":"Tutorial","size":8},{"classNo":"01A","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Monday","lessonType":"Tutorial","size":8},{"classNo":"01C","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Monday","lessonType":"Tutorial","size":8},{"classNo":"01G","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Monday","lessonType":"Tutorial","size":8},{"classNo":"01E","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Monday","lessonType":"Tutorial","size":8},{"classNo":"01F","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Monday","lessonType":"Tutorial","size":8},{"classNo":"02G","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Monday","lessonType":"Tutorial","size":8},{"classNo":"02E","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Monday","lessonType":"Tutorial","size":8},{"classNo":"02F","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Monday","lessonType":"Tutorial","size":8},{"classNo":"05E","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Monday","lessonType":"Tutorial","size":8},{"classNo":"05","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Thursday","lessonType":"Recitation","size":25},{"classNo":"06","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Thursday","lessonType":"Recitation","size":25},{"classNo":"09J","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"09B","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"09D","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"06B","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"05C","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Monday","lessonType":"Tutorial","size":8},{"classNo":"05D","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Monday","lessonType":"Tutorial","size":8},{"classNo":"08A","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"06G","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"10G","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"10D","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Tuesday","lessonType":"Tutorial","size":8}],"examDate":"2019-11-27T09:00:00.000Z","examDuration":120},{"semester":2,"timetable":[{"classNo":"1","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"LT19","day":"Wednesday","lessonType":"Lecture","size":80},{"classNo":"01","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Thursday","lessonType":"Recitation","size":20},{"classNo":"02","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Thursday","lessonType":"Recitation","size":20},{"classNo":"2B","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"03","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Thursday","lessonType":"Recitation","size":20},{"classNo":"1A","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"2A","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"4A","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"4B","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"1B","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"3B","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"3A","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Tuesday","lessonType":"Tutorial","size":8},{"classNo":"04","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0211","day":"Thursday","lessonType":"Recitation","size":20}],"examDate":"2020-05-04T01:00:00.000Z","examDuration":120}],"fulfillRequirements":["FIN4719","FIN4124","EE5907","MA3269"]} diff --git a/src/main/java/seedu/address/searcher/cache/CS1103.txt b/src/main/java/seedu/address/searcher/cache/CS1103.txt new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/CS1103.txt @@ -0,0 +1 @@ + diff --git a/src/main/java/seedu/address/searcher/cache/CS1521.txt b/src/main/java/seedu/address/searcher/cache/CS1521.txt new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/CS1521.txt @@ -0,0 +1 @@ + diff --git a/src/main/java/seedu/address/searcher/cache/CS20.txt b/src/main/java/seedu/address/searcher/cache/CS20.txt new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/CS20.txt @@ -0,0 +1 @@ + diff --git a/src/main/java/seedu/address/searcher/cache/CS2030.txt b/src/main/java/seedu/address/searcher/cache/CS2030.txt new file mode 100644 index 00000000000..9489c30cf70 --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/CS2030.txt @@ -0,0 +1 @@ +{"acadYear":"2019/2020","preclusion":"CS1020 or its equivalent","description":"This module is a follow up to CS1010. It explores two modern programming paradigms, object-oriented programming and functional programming. Through a series of integrated assignments, students will learn to develop medium-scale software programs in the order of thousands of lines of code and tens of classes using objectoriented design principles and advanced programming constructs available in the two paradigms. Topics include\nobjects and classes, composition, association, inheritance, interface, polymorphism, abstract classes, dynamic binding, lambda expression, effect-free programming, first class functions, closures, continuations, monad, etc.","title":"Programming Methodology II","department":"Computer Science","faculty":"Computing","workload":[2,0,2,3,3],"prerequisite":"CS1010 or its equivalent","moduleCredit":"4","moduleCode":"CS2030","semesterData":[{"semester":1,"timetable":[{"classNo":"09","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-0336","day":"Monday","lessonType":"Laboratory","size":23},{"classNo":"10","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-0338","day":"Monday","lessonType":"Laboratory","size":23},{"classNo":"06","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0206","day":"Friday","lessonType":"Recitation","size":50},{"classNo":"03","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0206","day":"Friday","lessonType":"Recitation","size":50},{"classNo":"04","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0206","day":"Friday","lessonType":"Recitation","size":50},{"classNo":"08","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-0339","day":"Monday","lessonType":"Laboratory","size":23},{"classNo":"01","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0206","day":"Friday","lessonType":"Recitation","size":50},{"classNo":"02","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0206","day":"Friday","lessonType":"Recitation","size":50},{"classNo":"05","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0206","day":"Friday","lessonType":"Recitation","size":50},{"classNo":"06","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-0336","day":"Monday","lessonType":"Laboratory","size":23},{"classNo":"07","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-0338","day":"Monday","lessonType":"Laboratory","size":23},{"classNo":"03","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-0339","day":"Monday","lessonType":"Laboratory","size":23},{"classNo":"02","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-0338","day":"Monday","lessonType":"Laboratory","size":23},{"classNo":"04","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-0336","day":"Monday","lessonType":"Laboratory","size":23},{"classNo":"05","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-0338","day":"Monday","lessonType":"Laboratory","size":23},{"classNo":"1","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"LT19","day":"Monday","lessonType":"Lecture","size":250},{"classNo":"11","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-0339","day":"Monday","lessonType":"Laboratory","size":23},{"classNo":"01","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-0336","day":"Monday","lessonType":"Laboratory","size":23}],"examDate":"2019-12-04T09:00:00.000Z","examDuration":120},{"semester":2,"timetable":[{"classNo":"33","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B111","day":"Tuesday","lessonType":"Laboratory","size":22},{"classNo":"29","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B112","day":"Tuesday","lessonType":"Laboratory","size":33},{"classNo":"31","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B110","day":"Tuesday","lessonType":"Laboratory","size":22},{"classNo":"32","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B110","day":"Tuesday","lessonType":"Laboratory","size":22},{"classNo":"1","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"UT-AUD2","day":"Wednesday","lessonType":"Lecture","size":450},{"classNo":"05","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"RMI-SR1","day":"Thursday","lessonType":"Recitation","size":100},{"classNo":"02","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"RMI-SR1","day":"Thursday","lessonType":"Recitation","size":100},{"classNo":"06","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"RMI-SR1","day":"Thursday","lessonType":"Recitation","size":100},{"classNo":"07","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"RMI-SR1","day":"Thursday","lessonType":"Recitation","size":100},{"classNo":"03","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"RMI-SR1","day":"Thursday","lessonType":"Recitation","size":100},{"classNo":"04","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"RMI-SR1","day":"Thursday","lessonType":"Recitation","size":100},{"classNo":"09","startTime":"1700","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"RMI-SR1","day":"Thursday","lessonType":"Recitation","size":100},{"classNo":"01","startTime":"0900","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"RMI-SR1","day":"Thursday","lessonType":"Recitation","size":100},{"classNo":"30","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B112","day":"Tuesday","lessonType":"Laboratory","size":33},{"classNo":"18","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B109","day":"Tuesday","lessonType":"Laboratory","size":33},{"classNo":"17","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B109","day":"Tuesday","lessonType":"Laboratory","size":33},{"classNo":"28","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B112","day":"Tuesday","lessonType":"Laboratory","size":33},{"classNo":"07","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-0339","day":"Tuesday","lessonType":"Laboratory","size":22},{"classNo":"08","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-0339","day":"Tuesday","lessonType":"Laboratory","size":22},{"classNo":"34","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B111","day":"Tuesday","lessonType":"Laboratory","size":22},{"classNo":"04","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-0338","day":"Tuesday","lessonType":"Laboratory","size":22},{"classNo":"05","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-0338","day":"Tuesday","lessonType":"Laboratory","size":22},{"classNo":"06","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-0339","day":"Tuesday","lessonType":"Laboratory","size":22},{"classNo":"01","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-0338","day":"Tuesday","lessonType":"Laboratory","size":22},{"classNo":"25","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0120","day":"Tuesday","lessonType":"Laboratory","size":22},{"classNo":"26","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B112","day":"Tuesday","lessonType":"Laboratory","size":33},{"classNo":"36","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B111","day":"Tuesday","lessonType":"Laboratory","size":22},{"classNo":"02","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-0338","day":"Tuesday","lessonType":"Laboratory","size":22},{"classNo":"03","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-0338","day":"Tuesday","lessonType":"Laboratory","size":22},{"classNo":"23","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0120","day":"Tuesday","lessonType":"Laboratory","size":22},{"classNo":"24","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0120","day":"Tuesday","lessonType":"Laboratory","size":22},{"classNo":"21","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0120","day":"Tuesday","lessonType":"Laboratory","size":22},{"classNo":"22","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0120","day":"Tuesday","lessonType":"Laboratory","size":22},{"classNo":"09","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-0339","day":"Tuesday","lessonType":"Laboratory","size":22},{"classNo":"16","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B109","day":"Tuesday","lessonType":"Laboratory","size":33},{"classNo":"14","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B108","day":"Tuesday","lessonType":"Laboratory","size":22},{"classNo":"13","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B108","day":"Tuesday","lessonType":"Laboratory","size":22},{"classNo":"15","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B108","day":"Tuesday","lessonType":"Laboratory","size":22},{"classNo":"2","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-AUD","day":"Monday","lessonType":"Lecture","size":348},{"classNo":"08","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"RMI-SR1","day":"Thursday","lessonType":"Recitation","size":100},{"classNo":"19","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B109","day":"Tuesday","lessonType":"Laboratory","size":33},{"classNo":"20","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B109","day":"Tuesday","lessonType":"Laboratory","size":33},{"classNo":"35","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B111","day":"Tuesday","lessonType":"Laboratory","size":22},{"classNo":"10","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-0339","day":"Tuesday","lessonType":"Laboratory","size":22},{"classNo":"12","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B108","day":"Tuesday","lessonType":"Laboratory","size":22},{"classNo":"3","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"LT15","day":"Wednesday","lessonType":"Lecture","size":100},{"classNo":"27","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B112","day":"Tuesday","lessonType":"Laboratory","size":33},{"classNo":"11","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B108","day":"Tuesday","lessonType":"Laboratory","size":22}],"examDate":"2020-05-05T09:00:00.000Z","examDuration":120},{"semester":3,"timetable":[{"classNo":"04","startTime":"1200","endTime":"1300","weeks":{"start":"2020-05-11","end":"2020-06-15"},"venue":"SR_LT19","day":"Monday","lessonType":"Recitation","size":20},{"classNo":"06","startTime":"1600","endTime":"1800","weeks":{"start":"2020-05-11","end":"2020-06-15"},"venue":"COM1-B112","day":"Monday","lessonType":"Laboratory","size":20},{"classNo":"02","startTime":"1400","endTime":"1600","weeks":{"start":"2020-05-13","end":"2020-06-17"},"venue":"COM1-B109","day":"Wednesday","lessonType":"Laboratory","size":20},{"classNo":"03","startTime":"1400","endTime":"1600","weeks":{"start":"2020-05-13","end":"2020-06-17"},"venue":"COM1-0120","day":"Wednesday","lessonType":"Laboratory","size":20},{"classNo":"03","startTime":"1400","endTime":"1500","weeks":{"start":"2020-05-11","end":"2020-06-15"},"venue":"COM1-0204","day":"Monday","lessonType":"Recitation","size":20},{"classNo":"04","startTime":"1600","endTime":"1800","weeks":{"start":"2020-05-11","end":"2020-06-15"},"venue":"COM1-0120","day":"Monday","lessonType":"Laboratory","size":20},{"classNo":"04","startTime":"1600","endTime":"1800","weeks":{"start":"2020-05-13","end":"2020-06-17"},"venue":"COM1-0120","day":"Wednesday","lessonType":"Laboratory","size":20},{"classNo":"05","startTime":"1600","endTime":"1800","weeks":{"start":"2020-05-11","end":"2020-06-15"},"venue":"COM1-B109","day":"Monday","lessonType":"Laboratory","size":20},{"classNo":"05","startTime":"1600","endTime":"1800","weeks":{"start":"2020-05-13","end":"2020-06-17"},"venue":"COM1-B109","day":"Wednesday","lessonType":"Laboratory","size":20},{"classNo":"06","startTime":"1600","endTime":"1700","weeks":{"start":"2020-05-11","end":"2020-06-15"},"venue":"SR_LT19","day":"Monday","lessonType":"Recitation","size":20},{"classNo":"1","startTime":"1000","endTime":"1200","weeks":{"start":"2020-05-11","end":"2020-06-15"},"venue":"LT19","day":"Monday","lessonType":"Lecture","size":120},{"classNo":"1","startTime":"1000","endTime":"1200","weeks":{"start":"2020-05-13","end":"2020-06-17"},"venue":"LT19","day":"Wednesday","lessonType":"Lecture","size":120},{"classNo":"02","startTime":"1300","endTime":"1400","weeks":{"start":"2020-05-11","end":"2020-06-15"},"venue":"COM1-0204","day":"Monday","lessonType":"Recitation","size":20},{"classNo":"01","startTime":"1400","endTime":"1600","weeks":{"start":"2020-05-11","end":"2020-06-15"},"venue":"COM1-B112","day":"Monday","lessonType":"Laboratory","size":20},{"classNo":"02","startTime":"1400","endTime":"1600","weeks":{"start":"2020-05-11","end":"2020-06-15"},"venue":"COM1-B109","day":"Monday","lessonType":"Laboratory","size":20},{"classNo":"03","startTime":"1400","endTime":"1600","weeks":{"start":"2020-05-11","end":"2020-06-15"},"venue":"COM1-0120","day":"Monday","lessonType":"Laboratory","size":20},{"classNo":"04","startTime":"1200","endTime":"1300","weeks":{"start":"2020-05-13","end":"2020-06-17"},"venue":"SR_LT19","day":"Wednesday","lessonType":"Recitation","size":20},{"classNo":"05","startTime":"1300","endTime":"1400","weeks":{"start":"2020-05-13","end":"2020-06-17"},"venue":"SR_LT19","day":"Wednesday","lessonType":"Recitation","size":20},{"classNo":"01","startTime":"1400","endTime":"1600","weeks":{"start":"2020-05-13","end":"2020-06-17"},"venue":"COM1-B112","day":"Wednesday","lessonType":"Laboratory","size":20},{"classNo":"06","startTime":"1600","endTime":"1700","weeks":{"start":"2020-05-13","end":"2020-06-17"},"venue":"SR_LT19","day":"Wednesday","lessonType":"Recitation","size":20},{"classNo":"01","startTime":"1200","endTime":"1300","weeks":{"start":"2020-05-13","end":"2020-06-17"},"venue":"COM1-0204","day":"Wednesday","lessonType":"Recitation","size":20},{"classNo":"05","startTime":"1300","endTime":"1400","weeks":{"start":"2020-05-11","end":"2020-06-15"},"venue":"SR_LT19","day":"Monday","lessonType":"Recitation","size":20},{"classNo":"03","startTime":"1400","endTime":"1500","weeks":{"start":"2020-05-13","end":"2020-06-17"},"venue":"COM1-0204","day":"Wednesday","lessonType":"Recitation","size":20},{"classNo":"01","startTime":"1200","endTime":"1300","weeks":{"start":"2020-05-11","end":"2020-06-15"},"venue":"COM1-0204","day":"Monday","lessonType":"Recitation","size":20},{"classNo":"02","startTime":"1300","endTime":"1400","weeks":{"start":"2020-05-13","end":"2020-06-17"},"venue":"COM1-0204","day":"Wednesday","lessonType":"Recitation","size":20},{"classNo":"06","startTime":"1600","endTime":"1800","weeks":{"start":"2020-05-13","end":"2020-06-17"},"venue":"COM1-B112","day":"Wednesday","lessonType":"Laboratory","size":20}],"examDate":"2020-06-19T06:30:00.000Z","examDuration":120}],"prereqTree":"CS1010","fulfillRequirements":["CS5239","CS5343","CP3107","CS3218","CS2104","CS3226","CS3240","CS4243","CS2102","CS2113","CS3245","CS2309","CS3241","CS4215","CS2113T","CS2103","CS2103T","IS4302","IS3261","BT3102","IS2102","IS2103"]} diff --git a/src/main/java/seedu/address/searcher/cache/CS2040.txt b/src/main/java/seedu/address/searcher/cache/CS2040.txt new file mode 100644 index 00000000000..1532dda08be --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/CS2040.txt @@ -0,0 +1 @@ +{"acadYear":"2019/2020","preclusion":"CS1020, CS1020E, CS2020, CS2010, CS2040C, CS2040S","description":"This module introduces students to the design and implementation of fundamental data structures and algorithms. The module covers basic data structures (linked lists, stacks, queues, hash tables, binary heaps, trees, and graphs), searching and sorting algorithms, and basic analysis of algorithms.","title":"Data Structures and Algorithms","department":"Computer Science","faculty":"Computing","workload":[3,0,1,3,3],"prerequisite":"CS1010 or its equivalent","moduleCredit":"4","moduleCode":"CS2040","semesterData":[{"semester":1,"timetable":[{"classNo":"11","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B111","day":"Monday","lessonType":"Laboratory","size":23},{"classNo":"2","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"SR_LT19","day":"Thursday","lessonType":"Lecture","size":48},{"classNo":"1","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"UT-AUD2","day":"Thursday","lessonType":"Lecture","size":250},{"classNo":"07","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Wednesday","lessonType":"Tutorial","size":21},{"classNo":"14","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0207","day":"Wednesday","lessonType":"Tutorial","size":21},{"classNo":"12","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0114","day":"Tuesday","lessonType":"Tutorial","size":21},{"classNo":"13","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0114","day":"Tuesday","lessonType":"Tutorial","size":21},{"classNo":"15","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0207","day":"Wednesday","lessonType":"Tutorial","size":21},{"classNo":"08","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B112","day":"Monday","lessonType":"Laboratory","size":23},{"classNo":"07","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B112","day":"Monday","lessonType":"Laboratory","size":23},{"classNo":"04","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B109","day":"Monday","lessonType":"Laboratory","size":23},{"classNo":"05","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B109","day":"Monday","lessonType":"Laboratory","size":23},{"classNo":"11","startTime":"0900","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0114","day":"Tuesday","lessonType":"Tutorial","size":21},{"classNo":"04","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Wednesday","lessonType":"Tutorial","size":21},{"classNo":"06","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Wednesday","lessonType":"Tutorial","size":21},{"classNo":"08","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Wednesday","lessonType":"Tutorial","size":21},{"classNo":"09","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Wednesday","lessonType":"Tutorial","size":21},{"classNo":"2","startTime":"0900","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"SR_LT19","day":"Friday","lessonType":"Lecture","size":48},{"classNo":"10","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B111","day":"Monday","lessonType":"Laboratory","size":23},{"classNo":"01","startTime":"0800","endTime":"0900","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Wednesday","lessonType":"Tutorial","size":21},{"classNo":"10","startTime":"1700","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Wednesday","lessonType":"Tutorial","size":21},{"classNo":"03","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Wednesday","lessonType":"Tutorial","size":21},{"classNo":"01","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B109","day":"Monday","lessonType":"Laboratory","size":23},{"classNo":"03","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B109","day":"Monday","lessonType":"Laboratory","size":23},{"classNo":"09","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B112","day":"Monday","lessonType":"Laboratory","size":23},{"classNo":"05","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Wednesday","lessonType":"Tutorial","size":21},{"classNo":"02","startTime":"0900","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Wednesday","lessonType":"Tutorial","size":21},{"classNo":"02","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B109","day":"Monday","lessonType":"Laboratory","size":23},{"classNo":"1","startTime":"0900","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"UT-AUD1","day":"Friday","lessonType":"Lecture","size":250},{"classNo":"06","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B112","day":"Monday","lessonType":"Laboratory","size":23}],"examDate":"2019-12-04T01:00:00.000Z","examDuration":120},{"semester":2,"timetable":[{"classNo":"1","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"LT19","day":"Monday","lessonType":"Lecture","size":220},{"classNo":"1","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"LT19","day":"Thursday","lessonType":"Lecture","size":220},{"classNo":"06","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B111","day":"Friday","lessonType":"Laboratory","size":23},{"classNo":"09","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0208","day":"Tuesday","lessonType":"Tutorial","size":20},{"classNo":"10","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0208","day":"Tuesday","lessonType":"Tutorial","size":20},{"classNo":"12","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0208","day":"Tuesday","lessonType":"Tutorial","size":20},{"classNo":"07","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B108","day":"Friday","lessonType":"Laboratory","size":23},{"classNo":"09","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B111","day":"Friday","lessonType":"Laboratory","size":23},{"classNo":"11","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B112","day":"Friday","lessonType":"Laboratory","size":23},{"classNo":"04","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0207","day":"Monday","lessonType":"Tutorial","size":20},{"classNo":"05","startTime":"0800","endTime":"0900","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0208","day":"Tuesday","lessonType":"Tutorial","size":20},{"classNo":"01","startTime":"0800","endTime":"0900","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0207","day":"Monday","lessonType":"Tutorial","size":20},{"classNo":"07","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0208","day":"Tuesday","lessonType":"Tutorial","size":20},{"classNo":"03","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0207","day":"Monday","lessonType":"Tutorial","size":20},{"classNo":"08","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0208","day":"Tuesday","lessonType":"Tutorial","size":20},{"classNo":"08","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B112","day":"Friday","lessonType":"Laboratory","size":23},{"classNo":"01","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B112","day":"Friday","lessonType":"Laboratory","size":23},{"classNo":"02","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B111","day":"Friday","lessonType":"Laboratory","size":23},{"classNo":"03","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B112","day":"Friday","lessonType":"Laboratory","size":23},{"classNo":"10","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B108","day":"Friday","lessonType":"Laboratory","size":23},{"classNo":"05","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B112","day":"Friday","lessonType":"Laboratory","size":23},{"classNo":"11","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0208","day":"Tuesday","lessonType":"Tutorial","size":20},{"classNo":"02","startTime":"0900","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0207","day":"Monday","lessonType":"Tutorial","size":20},{"classNo":"06","startTime":"0900","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0208","day":"Tuesday","lessonType":"Tutorial","size":20},{"classNo":"04","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B111","day":"Friday","lessonType":"Laboratory","size":23}]},{"semester":4,"timetable":[{"classNo":"03","startTime":"1600","endTime":"1800","weeks":{"start":"2020-06-25","end":"2020-07-30"},"venue":"COM1-B108","day":"Thursday","lessonType":"Laboratory","size":20},{"classNo":"02","startTime":"1600","endTime":"1700","weeks":{"start":"2020-06-25","end":"2020-07-30"},"venue":"COM1-0203","day":"Thursday","lessonType":"Tutorial","size":20},{"classNo":"03","startTime":"1700","endTime":"1800","weeks":{"start":"2020-06-25","end":"2020-07-30"},"venue":"COM1-0203","day":"Thursday","lessonType":"Tutorial","size":20},{"classNo":"03","startTime":"1600","endTime":"1800","weeks":{"start":"2020-06-23","end":"2020-07-28"},"venue":"COM1-B108","day":"Tuesday","lessonType":"Laboratory","size":20},{"classNo":"1","startTime":"0900","endTime":"1200","weeks":{"start":"2020-06-23","end":"2020-07-28"},"venue":"COM1-0204","day":"Tuesday","lessonType":"Lecture","size":60},{"classNo":"1","startTime":"0900","endTime":"1200","weeks":{"start":"2020-06-25","end":"2020-07-30"},"venue":"COM1-0204","day":"Thursday","lessonType":"Lecture","size":60},{"classNo":"01","startTime":"1400","endTime":"1600","weeks":{"start":"2020-06-25","end":"2020-07-30"},"venue":"COM1-B111","day":"Thursday","lessonType":"Laboratory","size":20},{"classNo":"02","startTime":"1400","endTime":"1600","weeks":{"start":"2020-06-25","end":"2020-07-30"},"venue":"COM1-B108","day":"Thursday","lessonType":"Laboratory","size":20},{"classNo":"01","startTime":"1400","endTime":"1500","weeks":{"start":"2020-06-25","end":"2020-07-30"},"venue":"COM1-0203","day":"Thursday","lessonType":"Tutorial","size":20},{"classNo":"01","startTime":"1400","endTime":"1500","weeks":{"start":"2020-06-23","end":"2020-07-28"},"venue":"COM1-0203","day":"Tuesday","lessonType":"Tutorial","size":20},{"classNo":"02","startTime":"1600","endTime":"1700","weeks":{"start":"2020-06-23","end":"2020-07-28"},"venue":"COM1-0203","day":"Tuesday","lessonType":"Tutorial","size":20},{"classNo":"02","startTime":"1400","endTime":"1600","weeks":{"start":"2020-06-23","end":"2020-07-28"},"venue":"COM1-B108","day":"Tuesday","lessonType":"Laboratory","size":20},{"classNo":"01","startTime":"1400","endTime":"1600","weeks":{"start":"2020-06-23","end":"2020-07-28"},"venue":"COM1-B111","day":"Tuesday","lessonType":"Laboratory","size":20},{"classNo":"03","startTime":"1700","endTime":"1800","weeks":{"start":"2020-06-23","end":"2020-07-28"},"venue":"COM1-0203","day":"Tuesday","lessonType":"Tutorial","size":20}],"examDate":"2020-07-30T05:00:00.000Z","examDuration":120}],"prereqTree":"CS1010","fulfillRequirements":["CS5240","CS5343","CS5332","CS5346","CS5461","CS5469","CS2102","CS2103","CS2105","CS2220","CS2309","CS3223","CS3225","CS3230","CS3241","CS3243","CS3244","CS4236","CS4243","CS3245","CS4215","CS2103T","CS3218","CS2108","CS2113","CS2113T","CP3107","CS4261","CS4269","BT4015","IS3261","CG2271","CS5477","CS4277"]} diff --git a/src/main/java/seedu/address/searcher/cache/CS2100.txt b/src/main/java/seedu/address/searcher/cache/CS2100.txt new file mode 100644 index 00000000000..c302e7ba424 --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/CS2100.txt @@ -0,0 +1 @@ +{"acadYear":"2019/2020","preclusion":"CS1104 or Students from Department of ECE","description":"The objective of this module is to familiarise students with the fundamentals of computing devices. Through this module students will understand the basics of data representation, and how the various parts of a computer work, separately and with each other. This allows students to understand the issues in computing devices, and how these issues affect the implementation of solutions. Topics covered include data representation systems, combinational and sequential circuit design techniques, assembly language, processor execution cycles, pipelining, memory hierarchy and input/output systems.","title":"Computer Organisation","department":"Computer Science","faculty":"Computing","workload":[3,1,1,3,2],"prerequisite":"CS1010 or its equivalent","moduleCredit":"4","moduleCode":"CS2100","semesterData":[{"semester":1,"timetable":[{"classNo":"02","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0207","day":"Tuesday","lessonType":"Tutorial","size":21},{"classNo":"03","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM2-0108","day":"Wednesday","lessonType":"Tutorial","size":21},{"classNo":"05","startTime":"0900","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0207","day":"Monday","lessonType":"Tutorial","size":21},{"classNo":"07","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM2-0108","day":"Wednesday","lessonType":"Tutorial","size":21},{"classNo":"09","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0207","day":"Monday","lessonType":"Tutorial","size":21},{"classNo":"04","startTime":"0800","endTime":"0900","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0207","day":"Monday","lessonType":"Tutorial","size":21},{"classNo":"06","startTime":"0900","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0208","day":"Thursday","lessonType":"Tutorial","size":21},{"classNo":"10","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0208","day":"Friday","lessonType":"Tutorial","size":21},{"classNo":"11","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0208","day":"Friday","lessonType":"Tutorial","size":21},{"classNo":"12","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0208","day":"Tuesday","lessonType":"Tutorial","size":21},{"classNo":"13","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0208","day":"Tuesday","lessonType":"Tutorial","size":21},{"classNo":"14","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM2-0108","day":"Wednesday","lessonType":"Tutorial","size":21},{"classNo":"03","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Monday","lessonType":"Laboratory","size":21},{"classNo":"05","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Monday","lessonType":"Laboratory","size":21},{"classNo":"06","startTime":"1700","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Monday","lessonType":"Laboratory","size":21},{"classNo":"07","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Thursday","lessonType":"Laboratory","size":21},{"classNo":"15","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Thursday","lessonType":"Laboratory","size":21},{"classNo":"08","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0208","day":"Friday","lessonType":"Tutorial","size":21},{"classNo":"01","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Monday","lessonType":"Laboratory","size":21},{"classNo":"02","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Monday","lessonType":"Laboratory","size":21},{"classNo":"08","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Thursday","lessonType":"Laboratory","size":21},{"classNo":"10","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Thursday","lessonType":"Laboratory","size":21},{"classNo":"13","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Monday","lessonType":"Laboratory","size":21},{"classNo":"14","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Monday","lessonType":"Laboratory","size":21},{"classNo":"1","startTime":"0900","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-AUD","day":"Wednesday","lessonType":"Lecture","size":314},{"classNo":"12","startTime":"1700","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Thursday","lessonType":"Laboratory","size":21},{"classNo":"01","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0208","day":"Friday","lessonType":"Tutorial","size":21},{"classNo":"09","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Thursday","lessonType":"Laboratory","size":21},{"classNo":"04","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Monday","lessonType":"Laboratory","size":21},{"classNo":"1","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-AUD","day":"Tuesday","lessonType":"Lecture","size":314},{"classNo":"11","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Thursday","lessonType":"Laboratory","size":21},{"classNo":"15","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM2-0108","day":"Wednesday","lessonType":"Tutorial","size":21}],"examDate":"2019-11-28T01:00:00.000Z","examDuration":120},{"semester":2,"timetable":[{"classNo":"1","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-AUD","day":"Tuesday","lessonType":"Lecture","size":200},{"classNo":"2","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-AUD","day":"Wednesday","lessonType":"Lecture","size":200},{"classNo":"05","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Friday","lessonType":"Tutorial","size":20},{"classNo":"10","startTime":"1700","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0114","day":"Monday","lessonType":"Laboratory","size":20},{"classNo":"14","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Thursday","lessonType":"Laboratory","size":20},{"classNo":"20","startTime":"1700","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Thursday","lessonType":"Laboratory","size":20},{"classNo":"15","startTime":"0800","endTime":"0900","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Friday","lessonType":"Tutorial","size":20},{"classNo":"19","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Thursday","lessonType":"Laboratory","size":20},{"classNo":"13","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Thursday","lessonType":"Laboratory","size":20},{"classNo":"07","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0114","day":"Monday","lessonType":"Laboratory","size":20},{"classNo":"08","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0114","day":"Monday","lessonType":"Laboratory","size":20},{"classNo":"09","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0114","day":"Monday","lessonType":"Laboratory","size":20},{"classNo":"05","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0114","day":"Monday","lessonType":"Laboratory","size":20},{"classNo":"06","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0114","day":"Monday","lessonType":"Laboratory","size":20},{"classNo":"03","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0114","day":"Monday","lessonType":"Laboratory","size":20},{"classNo":"04","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0114","day":"Monday","lessonType":"Laboratory","size":20},{"classNo":"13","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0114","day":"Wednesday","lessonType":"Tutorial","size":20},{"classNo":"19","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Tuesday","lessonType":"Tutorial","size":20},{"classNo":"20","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Tuesday","lessonType":"Tutorial","size":20},{"classNo":"12","startTime":"1700","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0114","day":"Thursday","lessonType":"Tutorial","size":20},{"classNo":"15","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Thursday","lessonType":"Laboratory","size":20},{"classNo":"16","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Thursday","lessonType":"Laboratory","size":20},{"classNo":"17","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Thursday","lessonType":"Laboratory","size":20},{"classNo":"01","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0114","day":"Wednesday","lessonType":"Tutorial","size":20},{"classNo":"03","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Tuesday","lessonType":"Tutorial","size":20},{"classNo":"04","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0114","day":"Wednesday","lessonType":"Tutorial","size":20},{"classNo":"08","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0201","day":"Monday","lessonType":"Tutorial","size":20},{"classNo":"10","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Tuesday","lessonType":"Tutorial","size":20},{"classNo":"11","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0201","day":"Monday","lessonType":"Tutorial","size":20},{"classNo":"14","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Tuesday","lessonType":"Tutorial","size":20},{"classNo":"16","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0201","day":"Monday","lessonType":"Tutorial","size":20},{"classNo":"18","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0114","day":"Thursday","lessonType":"Tutorial","size":20},{"classNo":"01","startTime":"0800","endTime":"0900","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0114","day":"Monday","lessonType":"Laboratory","size":20},{"classNo":"11","startTime":"0800","endTime":"0900","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Thursday","lessonType":"Laboratory","size":20},{"classNo":"2","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-AUD","day":"Monday","lessonType":"Lecture","size":200},{"classNo":"1","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-AUD","day":"Wednesday","lessonType":"Lecture","size":200},{"classNo":"06","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Friday","lessonType":"Tutorial","size":20},{"classNo":"02","startTime":"0900","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0114","day":"Monday","lessonType":"Laboratory","size":20},{"classNo":"12","startTime":"0900","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Thursday","lessonType":"Laboratory","size":20},{"classNo":"07","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Tuesday","lessonType":"Tutorial","size":20},{"classNo":"18","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Thursday","lessonType":"Laboratory","size":20},{"classNo":"09","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0201","day":"Monday","lessonType":"Tutorial","size":20},{"classNo":"17","startTime":"1700","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0114","day":"Wednesday","lessonType":"Tutorial","size":20},{"classNo":"02","startTime":"0900","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Friday","lessonType":"Tutorial","size":20}],"examDate":"2020-04-30T05:00:00.000Z","examDuration":120}],"prereqTree":"CS1010","fulfillRequirements":["CS6284","CS3237","CS2106","CS3210","EE5902"]} diff --git a/src/main/java/seedu/address/searcher/cache/CS2101.txt b/src/main/java/seedu/address/searcher/cache/CS2101.txt new file mode 100644 index 00000000000..fcf110a5e56 --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/CS2101.txt @@ -0,0 +1 @@ +{"acadYear":"2019/2020","preclusion":"CS2103 Software Engineering, IS2101 Business Technical Communication or its equivalent, ES2002, ES2007D, and ES1601.","description":"This module aims to equip students with the skills needed to communicate technical information to technical and nontechnical audiences, and to create comprehensible software documentation. A student-centric approach will\nbe adopted to encourage independent and collaborative learning while engaging students in team-based projects. Students will learn interpersonal and intercultural\ncommunication skills as well as hone their oral and written communication skills. Assessment modes include a variety of oral and written communication tasks such as reports, software guides, oral presentations, software demonstrations and project blogs.","title":"Effective Communication for Computing Professionals","department":"Center for Engl Lang Comms","faculty":"Computing","workload":[0,4,0,4,2],"prerequisite":"Students have to complete ES1000 and/or ES1103 (if required to take the module/s) before reading this module.","corequisite":"Students have to read CS2103T Software Engineering at the same time as this module.","moduleCredit":"4","moduleCode":"CS2101","attributes":{"su":true},"semesterData":[{"semester":1,"timetable":[]},{"semester":2,"timetable":[]}],"prereqTree":{"or":["ES1000","ES1103"]},"fulfillRequirements":["CP3880","CS3201","IS4010","IS3103"]} diff --git a/src/main/java/seedu/address/searcher/cache/CS2102.txt b/src/main/java/seedu/address/searcher/cache/CS2102.txt new file mode 100644 index 00000000000..37953234237 --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/CS2102.txt @@ -0,0 +1 @@ +{"acadYear":"2019/2020","preclusion":"CS2102S, IT2002","description":"The aim of this module is to introduce the fundamental concepts and techniques necessary for the understanding and practice of design and implementation of database applications and of the management of data with relational database management systems. The module covers practical and theoretical aspects of design with entity-relationship model, theory of functional dependencies and normalisation by decomposition in second, third and Boyce-Codd normal forms. The module covers practical and theoretical aspects of programming with SQL data definition and manipulation sublanguages, relational tuple calculus, relational domain calculus and relational algebra.","title":"Database Systems","department":"Computer Science","faculty":"Computing","workload":[2,1.5,0.5,3,3],"prerequisite":"((CS1020 or its equivalent) or CS2020 or CS2030 or (CS2040 or its equivalent)) and (MA1100 or (CS1231 or its equivalent))","moduleCredit":"4","moduleCode":"CS2102","semesterData":[{"semester":1,"timetable":[{"classNo":"10","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B108","day":"Wednesday","lessonType":"Tutorial","size":22},{"classNo":"09","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-0339","day":"Tuesday","lessonType":"Tutorial","size":22},{"classNo":"11","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B108","day":"Wednesday","lessonType":"Tutorial","size":22},{"classNo":"01","startTime":"0800","endTime":"0900","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-0339","day":"Tuesday","lessonType":"Tutorial","size":22},{"classNo":"02","startTime":"0900","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-0339","day":"Tuesday","lessonType":"Tutorial","size":22},{"classNo":"06","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-0339","day":"Tuesday","lessonType":"Tutorial","size":22},{"classNo":"07","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-0339","day":"Tuesday","lessonType":"Tutorial","size":22},{"classNo":"08","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-0339","day":"Tuesday","lessonType":"Tutorial","size":22},{"classNo":"1","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-AUD","day":"Monday","lessonType":"Lecture","size":233},{"classNo":"03","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-0339","day":"Tuesday","lessonType":"Tutorial","size":22},{"classNo":"04","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-0339","day":"Tuesday","lessonType":"Tutorial","size":22},{"classNo":"05","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-0339","day":"Tuesday","lessonType":"Tutorial","size":22}],"examDate":"2019-11-27T05:00:00.000Z","examDuration":120},{"semester":2,"timetable":[{"classNo":"1","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-AUD","day":"Friday","lessonType":"Lecture","size":230},{"classNo":"08","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0207","day":"Friday","lessonType":"Tutorial","size":23},{"classNo":"11","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0207","day":"Monday","lessonType":"Tutorial","size":23},{"classNo":"12","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0207","day":"Monday","lessonType":"Tutorial","size":23},{"classNo":"13","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0207","day":"Tuesday","lessonType":"Tutorial","size":23},{"classNo":"05","startTime":"1700","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0207","day":"Wednesday","lessonType":"Tutorial","size":23},{"classNo":"04","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0207","day":"Wednesday","lessonType":"Tutorial","size":23},{"classNo":"07","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0207","day":"Thursday","lessonType":"Tutorial","size":23},{"classNo":"01","startTime":"1700","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0207","day":"Monday","lessonType":"Tutorial","size":23},{"classNo":"02","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0207","day":"Tuesday","lessonType":"Tutorial","size":23},{"classNo":"03","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0207","day":"Tuesday","lessonType":"Tutorial","size":23},{"classNo":"14","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0207","day":"Tuesday","lessonType":"Tutorial","size":23},{"classNo":"09","startTime":"1700","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0207","day":"Friday","lessonType":"Tutorial","size":23},{"classNo":"10","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0207","day":"Monday","lessonType":"Tutorial","size":23},{"classNo":"06","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0207","day":"Thursday","lessonType":"Tutorial","size":23}],"examDate":"2020-04-28T01:00:00.000Z","examDuration":120}],"prereqTree":{"and":[{"or":["CS1020","CS2020","CS2030","CS2040"]},{"or":["MA1100","CS1231"]}]},"fulfillRequirements":["CP3106","CS6284","CS5346","CS5228","CS5425","CS4225","CS3223","IS4302"]} diff --git a/src/main/java/seedu/address/searcher/cache/CS2103.txt b/src/main/java/seedu/address/searcher/cache/CS2103.txt new file mode 100644 index 00000000000..563784d817c --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/CS2103.txt @@ -0,0 +1 @@ +{"acadYear":"2019/2020","preclusion":"CS2103T, CS2113, CS2113T","description":"This module introduces the necessary conceptual and analytical tools for systematic and rigorous development of software systems. It covers four main areas of software development, namely object-oriented system analysis, object-oriented system modelling and design, implementation, and testing, with emphasis on system modelling and design and implementation of software modules that work cooperatively to fulfill the requirements of the system. Tools and techniques for software development, such as Unified Modelling Language (UML), program specification, and testing methods, will be taught. Major software engineering issues such as modularisation criteria, program correctness, and software quality will also be covered.","title":"Software Engineering","department":"Computer Science","faculty":"Computing","workload":[2,1,0,3,4],"prerequisite":"(CS1020 or its equivalent) or CS2020 or (CS2030 and (CS2040 or its equivalent))","moduleCredit":"4","moduleCode":"CS2103","aliases":["CS2103T"],"semesterData":[{"semester":1,"timetable":[{"classNo":"02","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Thursday","lessonType":"Tutorial","size":20},{"classNo":"04","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Thursday","lessonType":"Tutorial","size":20},{"classNo":"06","startTime":"0900","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Friday","lessonType":"Tutorial","size":20},{"classNo":"05","startTime":"1700","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Thursday","lessonType":"Tutorial","size":20},{"classNo":"01","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Wednesday","lessonType":"Tutorial","size":20},{"classNo":"03","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Thursday","lessonType":"Tutorial","size":20},{"classNo":"07","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Friday","lessonType":"Tutorial","size":20},{"classNo":"08","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Thursday","lessonType":"Tutorial","size":20},{"classNo":"1","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"LT19","day":"Friday","lessonType":"Lecture","size":150}],"examDate":"2019-11-29T01:00:00.000Z","examDuration":120},{"semester":2,"timetable":[{"classNo":"04","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Thursday","lessonType":"Tutorial","size":20},{"classNo":"01","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Wednesday","lessonType":"Tutorial","size":20},{"classNo":"02","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Wednesday","lessonType":"Tutorial","size":20},{"classNo":"03","startTime":"0900","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Thursday","lessonType":"Tutorial","size":20},{"classNo":"1","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-AUD","day":"Friday","lessonType":"Lecture","size":100},{"classNo":"05","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Thursday","lessonType":"Tutorial","size":20}],"examDate":"2020-04-25T05:00:00.000Z","examDuration":120}],"prereqTree":{"or":["CS1020","CS2020",{"and":["CS2030","CS2040"]}]},"fulfillRequirements":["CP3101A","CP3880","CS5232","CS5246","CS5272","CS6880","CS5439","CS3201","CS3216","CS4211","UIS3951R","CS3249","CS3202","CS3281","CS3217","CS3283","CS4239","CS3219","CS3203","IS4302","BT3102","IS4234"]} diff --git a/src/main/java/seedu/address/searcher/cache/CS2103T.txt b/src/main/java/seedu/address/searcher/cache/CS2103T.txt new file mode 100644 index 00000000000..1797b3bb745 --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/CS2103T.txt @@ -0,0 +1 @@ +{"acadYear":"2019/2020","preclusion":"CS2103, CS2113, CS2113T, IS2101 or its equivalent.","description":"This module introduces the necessary conceptual and analytical tools for systematic and rigorous development of software systems. It covers four main areas of software development, namely object-oriented system analysis, object-oriented system modelling and design, implementation, and testing, with emphasis on system modelling and design and implementation of software modules that work cooperatively to fulfill the requirements of the system. Tools and techniques for software development, such as Unified Modelling Language (UML), program specification, and testing methods, will be taught. Major software engineering issues such as modularisation criteria, program correctness, and software quality will also be covered.","title":"Software Engineering","department":"Computer Science","faculty":"Computing","workload":[2,1,0,3,4],"prerequisite":"For SoC students only. (CS1020 or its equivalent) or CS2020 or (CS2030 and (CS2040 or its equivalent))","corequisite":"Students have to read CS2101 Effective Communication for Computing Professionals at the same time as this module","moduleCredit":"4","moduleCode":"CS2103T","aliases":["CS2103"],"semesterData":[{"semester":1,"timetable":[{"classNo":"G13","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-AUD","day":"Friday","lessonType":"Lecture","size":20},{"classNo":"G11","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-AUD","day":"Friday","lessonType":"Lecture","size":20},{"classNo":"G10","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-AUD","day":"Friday","lessonType":"Lecture","size":20},{"classNo":"G08","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-AUD","day":"Friday","lessonType":"Lecture","size":20},{"classNo":"G07","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-AUD","day":"Friday","lessonType":"Lecture","size":20},{"classNo":"G03","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-AUD","day":"Friday","lessonType":"Lecture","size":20},{"classNo":"G01","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-AUD","day":"Friday","lessonType":"Lecture","size":20},{"classNo":"G04","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-AUD","day":"Friday","lessonType":"Lecture","size":20},{"classNo":"G13","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0216","day":"Tuesday","lessonType":"Lecture","size":20},{"classNo":"G13","startTime":"1700","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Thursday","lessonType":"Lecture","size":20},{"classNo":"G13","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0201","day":"Friday","lessonType":"Lecture","size":20},{"classNo":"G07","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0217","day":"Monday","lessonType":"Lecture","size":20},{"classNo":"G05","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0210","day":"Friday","lessonType":"Lecture","size":20},{"classNo":"G01","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0208","day":"Thursday","lessonType":"Lecture","size":20},{"classNo":"G09","startTime":"1500","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0610","day":"Monday","lessonType":"Lecture","size":20},{"classNo":"G04","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0210","day":"Tuesday","lessonType":"Lecture","size":20},{"classNo":"G02","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0216","day":"Thursday","lessonType":"Lecture","size":20},{"classNo":"G08","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0611","day":"Monday","lessonType":"Lecture","size":20},{"classNo":"G08","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0611","day":"Thursday","lessonType":"Lecture","size":20},{"classNo":"G10","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Thursday","lessonType":"Lecture","size":20},{"classNo":"G09","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Friday","lessonType":"Lecture","size":20},{"classNo":"G03","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Wednesday","lessonType":"Lecture","size":20},{"classNo":"G06","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0216","day":"Tuesday","lessonType":"Lecture","size":20},{"classNo":"G03","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0216","day":"Monday","lessonType":"Lecture","size":20},{"classNo":"G06","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0216","day":"Friday","lessonType":"Lecture","size":20},{"classNo":"G12","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0611","day":"Thursday","lessonType":"Lecture","size":20},{"classNo":"G12","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0611","day":"Monday","lessonType":"Lecture","size":20},{"classNo":"G07","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0217","day":"Thursday","lessonType":"Lecture","size":20},{"classNo":"G10","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0610","day":"Friday","lessonType":"Lecture","size":20},{"classNo":"G01","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0208","day":"Monday","lessonType":"Lecture","size":20},{"classNo":"G09","startTime":"1500","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0610","day":"Thursday","lessonType":"Lecture","size":20},{"classNo":"G10","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0208","day":"Tuesday","lessonType":"Lecture","size":20},{"classNo":"G05","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0210","day":"Tuesday","lessonType":"Lecture","size":20},{"classNo":"G04","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Thursday","lessonType":"Lecture","size":20},{"classNo":"G05","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Thursday","lessonType":"Lecture","size":20},{"classNo":"G07","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Friday","lessonType":"Lecture","size":20},{"classNo":"G12","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Friday","lessonType":"Lecture","size":20},{"classNo":"G02","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Wednesday","lessonType":"Lecture","size":20},{"classNo":"G06","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Thursday","lessonType":"Lecture","size":20},{"classNo":"G11","startTime":"0900","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Thursday","lessonType":"Lecture","size":20},{"classNo":"G12","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-AUD","day":"Friday","lessonType":"Lecture","size":20},{"classNo":"G02","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-AUD","day":"Friday","lessonType":"Lecture","size":20},{"classNo":"G09","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-AUD","day":"Friday","lessonType":"Lecture","size":20},{"classNo":"G06","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-AUD","day":"Friday","lessonType":"Lecture","size":20},{"classNo":"G03","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0216","day":"Thursday","lessonType":"Lecture","size":20},{"classNo":"G08","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Friday","lessonType":"Lecture","size":20},{"classNo":"G11","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0610","day":"Friday","lessonType":"Lecture","size":20},{"classNo":"G11","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0610","day":"Tuesday","lessonType":"Lecture","size":20},{"classNo":"G02","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0216","day":"Monday","lessonType":"Lecture","size":20},{"classNo":"G04","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0210","day":"Friday","lessonType":"Lecture","size":20},{"classNo":"G01","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0210","day":"Wednesday","lessonType":"Lecture","size":20},{"classNo":"G05","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-AUD","day":"Friday","lessonType":"Lecture","size":20}],"examDate":"2019-11-29T01:00:00.000Z","examDuration":120},{"semester":2,"timetable":[{"classNo":"G02","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Wednesday","lessonType":"Lecture","size":20},{"classNo":"G03","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Friday","lessonType":"Lecture","size":20},{"classNo":"G09","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Thursday","lessonType":"Lecture","size":20},{"classNo":"G07","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Thursday","lessonType":"Lecture","size":20},{"classNo":"G08","startTime":"0900","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Friday","lessonType":"Lecture","size":20},{"classNo":"G05","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Wednesday","lessonType":"Lecture","size":20},{"classNo":"G04","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0208","day":"Thursday","lessonType":"Lecture","size":20},{"classNo":"G05","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0208","day":"Tuesday","lessonType":"Lecture","size":20},{"classNo":"G05","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0208","day":"Friday","lessonType":"Lecture","size":20},{"classNo":"G01","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0208","day":"Thursday","lessonType":"Lecture","size":20},{"classNo":"G02","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0208","day":"Monday","lessonType":"Lecture","size":20},{"classNo":"G02","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0208","day":"Thursday","lessonType":"Lecture","size":20},{"classNo":"G04","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0208","day":"Monday","lessonType":"Lecture","size":20},{"classNo":"G01","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0208","day":"Monday","lessonType":"Lecture","size":20},{"classNo":"G06","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0208","day":"Friday","lessonType":"Lecture","size":20},{"classNo":"G07","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0208","day":"Tuesday","lessonType":"Lecture","size":20},{"classNo":"G07","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0208","day":"Friday","lessonType":"Lecture","size":20},{"classNo":"G08","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0208","day":"Monday","lessonType":"Lecture","size":20},{"classNo":"G08","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0208","day":"Thursday","lessonType":"Lecture","size":20},{"classNo":"G08","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-AUD","day":"Friday","lessonType":"Lecture","size":20},{"classNo":"G07","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-AUD","day":"Friday","lessonType":"Lecture","size":20},{"classNo":"G05","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-AUD","day":"Friday","lessonType":"Lecture","size":20},{"classNo":"G03","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-AUD","day":"Friday","lessonType":"Lecture","size":20},{"classNo":"G09","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-AUD","day":"Friday","lessonType":"Lecture","size":20},{"classNo":"G02","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-AUD","day":"Friday","lessonType":"Lecture","size":20},{"classNo":"G01","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-AUD","day":"Friday","lessonType":"Lecture","size":20},{"classNo":"G04","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-AUD","day":"Friday","lessonType":"Lecture","size":20},{"classNo":"G09","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0208","day":"Tuesday","lessonType":"Lecture","size":20},{"classNo":"G06","startTime":"1700","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Wednesday","lessonType":"Lecture","size":20},{"classNo":"G01","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Wednesday","lessonType":"Lecture","size":20},{"classNo":"G04","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Friday","lessonType":"Lecture","size":20},{"classNo":"G03","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0208","day":"Monday","lessonType":"Lecture","size":20},{"classNo":"G03","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0208","day":"Thursday","lessonType":"Lecture","size":20},{"classNo":"G06","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-AUD","day":"Friday","lessonType":"Lecture","size":20},{"classNo":"G09","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0208","day":"Friday","lessonType":"Lecture","size":20},{"classNo":"G06","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0208","day":"Tuesday","lessonType":"Lecture","size":20}],"examDate":"2020-04-25T05:00:00.000Z","examDuration":120}],"prereqTree":{"or":["CS1020","CS2020",{"and":["CS2030","CS2040"]}]},"fulfillRequirements":["CP3880","CS3203","CS3283","IS4302","BT3102","IS4234"]} diff --git a/src/main/java/seedu/address/searcher/cache/CS2104.txt b/src/main/java/seedu/address/searcher/cache/CS2104.txt new file mode 100644 index 00000000000..f2c68aacb94 --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/CS2104.txt @@ -0,0 +1 @@ +{"acadYear":"2019/2020","description":"This module introduces the concepts that serve as a basis for hundreds of programming languages. It aims to provide the students with a basic understanding and appreciation of the various essential programming-languages constructs, programming paradigms, evaluation criteria and language implementation issues. The module covers concepts from imperative, object-oriented, functional, logic, constraints, and concurrent programming. These concepts are illustrated by examples from varieties of languages such as Pascal, C, Java, Smalltalk, Scheme, Haskell, Prolog. The module also introduces various implementation issues, such as pseudo-code interpretation, static and dynamic semantics, abstract machine, type inferencing, etc.","title":"Programming Language Concepts","department":"Computer Science","faculty":"Computing","workload":[2,1,0,3,3],"prerequisite":"CS1020 or CS1020E or CS2020 or CS2030 or CS2113/T","moduleCredit":"4","moduleCode":"CS2104","semesterData":[{"semester":1,"timetable":[{"classNo":"1","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0212","day":"Wednesday","lessonType":"Lecture","size":80},{"classNo":"1","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0421","day":"Wednesday","lessonType":"Tutorial","size":20},{"classNo":"3","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0421","day":"Thursday","lessonType":"Tutorial","size":20},{"classNo":"4","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0421","day":"Thursday","lessonType":"Tutorial","size":20},{"classNo":"2","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0421","day":"Wednesday","lessonType":"Tutorial","size":20}],"examDate":"2019-11-25T05:00:00.000Z","examDuration":120}],"prereqTree":{"or":["CS1020","CS1020E","CS2020","CS2030","CS2113","CS2113T"]},"fulfillRequirements":["CS5219","CS5215","CS4216","CS4214","CS4212"]} diff --git a/src/main/java/seedu/address/searcher/cache/CS2106.txt b/src/main/java/seedu/address/searcher/cache/CS2106.txt new file mode 100644 index 00000000000..16aba664fd1 --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/CS2106.txt @@ -0,0 +1 @@ +{"acadYear":"2019/2020","preclusion":"CG2271 or EE4214. CEG students are not allowed to take this module.","description":"This module introduces the basic concepts in operating systems and links it with contemporary operating systems (eg. Unix/Linux and Windows). It focuses on OS structuring and architecture, processes, memory management, concurrency and file systems. Topics include kernel architecture, system calls, interrupts, models of processes, process abstraction and services, scheduling, review of physical memory and memory management hardware, kernel memory management, virtual memory and paging, caches, working set, deadlock, mutual exclusion, synchronisation mechanisms, data and metadata in file systems, directories and structure, file system abstraction and operations, OS protection mechanisms, and user authentication.","title":"Introduction to Operating Systems","department":"Computer Science","faculty":"Computing","workload":[2,1,1,0,6],"prerequisite":"CS2100 or EE2007 or EE2024 or EE2028","moduleCredit":"4","moduleCode":"CS2106","semesterData":[{"semester":1,"timetable":[{"classNo":"02","startTime":"0900","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0208","day":"Tuesday","lessonType":"Tutorial","size":20},{"classNo":"07","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B113","day":"Monday","lessonType":"Laboratory","size":20},{"classNo":"05","startTime":"1700","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B113","day":"Monday","lessonType":"Laboratory","size":20},{"classNo":"09","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B113","day":"Friday","lessonType":"Laboratory","size":20},{"classNo":"08","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B113","day":"Tuesday","lessonType":"Laboratory","size":20},{"classNo":"01","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0207","day":"Friday","lessonType":"Tutorial","size":20},{"classNo":"03","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0209","day":"Wednesday","lessonType":"Tutorial","size":20},{"classNo":"05","startTime":"0900","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0209","day":"Monday","lessonType":"Tutorial","size":20},{"classNo":"06","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0209","day":"Monday","lessonType":"Tutorial","size":20},{"classNo":"04","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0209","day":"Monday","lessonType":"Tutorial","size":20},{"classNo":"10","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B113","day":"Tuesday","lessonType":"Laboratory","size":20},{"classNo":"11","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B113","day":"Thursday","lessonType":"Laboratory","size":20},{"classNo":"1","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"LT19","day":"Wednesday","lessonType":"Lecture","size":250},{"classNo":"02","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B113","day":"Monday","lessonType":"Laboratory","size":20},{"classNo":"03","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B113","day":"Monday","lessonType":"Laboratory","size":20},{"classNo":"04","startTime":"0900","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B113","day":"Thursday","lessonType":"Laboratory","size":20},{"classNo":"10","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0209","day":"Friday","lessonType":"Tutorial","size":20},{"classNo":"09","startTime":"1700","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0209","day":"Wednesday","lessonType":"Tutorial","size":20},{"classNo":"12","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0209","day":"Wednesday","lessonType":"Tutorial","size":20},{"classNo":"13","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0208","day":"Tuesday","lessonType":"Tutorial","size":20},{"classNo":"08","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0209","day":"Friday","lessonType":"Tutorial","size":20},{"classNo":"11","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0209","day":"Wednesday","lessonType":"Tutorial","size":20},{"classNo":"01","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B113","day":"Tuesday","lessonType":"Laboratory","size":20},{"classNo":"07","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0208","day":"Tuesday","lessonType":"Tutorial","size":20},{"classNo":"06","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B113","day":"Friday","lessonType":"Laboratory","size":20}],"examDate":"2019-12-03T01:00:00.000Z","examDuration":120},{"semester":2,"timetable":[{"classNo":"13","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B113","day":"Friday","lessonType":"Tutorial","size":20},{"classNo":"06","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B113","day":"Tuesday","lessonType":"Tutorial","size":20},{"classNo":"05","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B113","day":"Tuesday","lessonType":"Tutorial","size":20},{"classNo":"07","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B113","day":"Thursday","lessonType":"Tutorial","size":20},{"classNo":"09","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B113","day":"Friday","lessonType":"Tutorial","size":20},{"classNo":"11","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B113","day":"Friday","lessonType":"Tutorial","size":20},{"classNo":"03","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B113","day":"Tuesday","lessonType":"Laboratory","size":25},{"classNo":"04","startTime":"1700","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B113","day":"Tuesday","lessonType":"Laboratory","size":25},{"classNo":"07","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B113","day":"Wednesday","lessonType":"Laboratory","size":25},{"classNo":"08","startTime":"1700","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B113","day":"Wednesday","lessonType":"Laboratory","size":25},{"classNo":"09","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B113","day":"Thursday","lessonType":"Laboratory","size":25},{"classNo":"10","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B113","day":"Thursday","lessonType":"Laboratory","size":25},{"classNo":"1","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-AUD","day":"Wednesday","lessonType":"Lecture","size":280},{"classNo":"03","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B113","day":"Monday","lessonType":"Tutorial","size":20},{"classNo":"08","startTime":"1700","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B113","day":"Thursday","lessonType":"Tutorial","size":20},{"classNo":"11","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B113","day":"Thursday","lessonType":"Laboratory","size":25},{"classNo":"12","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B113","day":"Thursday","lessonType":"Laboratory","size":25},{"classNo":"10","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B113","day":"Friday","lessonType":"Tutorial","size":20},{"classNo":"02","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B113","day":"Tuesday","lessonType":"Laboratory","size":25},{"classNo":"05","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B113","day":"Wednesday","lessonType":"Laboratory","size":25},{"classNo":"06","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B113","day":"Wednesday","lessonType":"Laboratory","size":25},{"classNo":"01","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B113","day":"Monday","lessonType":"Tutorial","size":20},{"classNo":"02","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B113","day":"Monday","lessonType":"Tutorial","size":20},{"classNo":"01","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B113","day":"Tuesday","lessonType":"Laboratory","size":25},{"classNo":"04","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B113","day":"Monday","lessonType":"Tutorial","size":20},{"classNo":"12","startTime":"1700","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B113","day":"Friday","lessonType":"Tutorial","size":20},{"classNo":"14","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B113","day":"Friday","lessonType":"Tutorial","size":20}],"examDate":"2020-04-27T09:00:00.000Z","examDuration":120}],"prereqTree":{"or":["CS2100","EE2007","EE2024","EE2028"]},"fulfillRequirements":["CS6280","CS6211","CS5272","CS6219","CS5248","CS5250","CS3235","CS4344","CS4223","CS3211","CS3221","CS3220","EE5903"]} diff --git a/src/main/java/seedu/address/searcher/cache/CS2108.txt b/src/main/java/seedu/address/searcher/cache/CS2108.txt new file mode 100644 index 00000000000..983a02af424 --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/CS2108.txt @@ -0,0 +1 @@ +{"acadYear":"2019/2020","preclusion":"CS3246","description":"This module introduces students to (i) the fundamental principles, theory, algorithms, and data structures behind digital representation, compression, synchronization, and processing of image, audio, and video data types, and (ii) challenges and issues in developing media-rich applications, such as media streaming and media retrieval. Students will be exposed to the workings of common media file format and common manipulation techniques on media data. After taking the module, students should be confident enough in developing media applications and make appropriate trade-off and design decisions when dealing in media data in their software.","title":"Introduction to Media Computing","department":"Computer Science","faculty":"Computing","workload":[2,1,0,3,4],"prerequisite":"(CS1020 or its equivalent) or CS2020 or (CS2040 or its equivalent)","moduleCredit":"4","moduleCode":"CS2108","semesterData":[{"semester":2,"timetable":[{"classNo":"1","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0206","day":"Tuesday","lessonType":"Lecture","size":104},{"classNo":"5","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0208","day":"Thursday","lessonType":"Tutorial","size":21},{"classNo":"1","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0208","day":"Thursday","lessonType":"Tutorial","size":21},{"classNo":"2","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0208","day":"Thursday","lessonType":"Tutorial","size":21},{"classNo":"3","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0203","day":"Friday","lessonType":"Tutorial","size":21},{"classNo":"4","startTime":"1700","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0203","day":"Friday","lessonType":"Tutorial","size":21}]}],"prereqTree":{"or":["CS1020","CS2020","CS2040"]},"fulfillRequirements":["CS4347","CS4242"]} diff --git a/src/main/java/seedu/address/searcher/cache/CS2202.txt b/src/main/java/seedu/address/searcher/cache/CS2202.txt new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/CS2202.txt @@ -0,0 +1 @@ + diff --git a/src/main/java/seedu/address/searcher/cache/CS3131.txt b/src/main/java/seedu/address/searcher/cache/CS3131.txt new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/CS3131.txt @@ -0,0 +1 @@ + diff --git a/src/main/java/seedu/address/searcher/cache/CS3230.txt b/src/main/java/seedu/address/searcher/cache/CS3230.txt new file mode 100644 index 00000000000..f8c6d7252a4 --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/CS3230.txt @@ -0,0 +1 @@ +{"acadYear":"2019/2020","preclusion":"EEE and CPE students can only take this module as a technical elective to satisfy the program requirements or UEM but not CFM/ULR-Breadth.","description":"This module introduces different techniques of designing and analysing algorithms. Students will learn about the framework for algorithm analysis, for example, lower bound arguments, average case analysis, and the theory of NP-completeness. In addition, students are exposed to various algorithm design paradigms. The module serves two purposes: to improve the students' ability to design algorithms in different areas, and to prepare students for the study of more advanced algorithms. The module covers lower and upper bounds, recurrences, basic algorithm paradigms (such as prune-and-search, dynamic programming, branch-and-bound, graph traversal, and randomised approaches), amortized analysis, NP-completeness, and some selected advanced topics.","title":"Design and Analysis of Algorithms","department":"Computer Science","faculty":"Computing","workload":[2,1,0,3,3],"prerequisite":"((CS2010 or its equivalent) or CS2020 or (CS2040 or its equivalent)) and (MA1100 or (CS1231 or its equivalent))","moduleCredit":"4","moduleCode":"CS3230","semesterData":[{"semester":1,"timetable":[{"classNo":"05","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0114","day":"Monday","lessonType":"Tutorial","size":20},{"classNo":"03","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0114","day":"Wednesday","lessonType":"Tutorial","size":20},{"classNo":"01","startTime":"0800","endTime":"0900","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0114","day":"Monday","lessonType":"Tutorial","size":20},{"classNo":"09","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0114","day":"Wednesday","lessonType":"Tutorial","size":20},{"classNo":"10","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0114","day":"Monday","lessonType":"Tutorial","size":20},{"classNo":"07","startTime":"0900","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0114","day":"Thursday","lessonType":"Tutorial","size":20},{"classNo":"11","startTime":"0900","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Wednesday","lessonType":"Tutorial","size":20},{"classNo":"08","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0114","day":"Wednesday","lessonType":"Tutorial","size":20},{"classNo":"02","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Wednesday","lessonType":"Tutorial","size":20},{"classNo":"04","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-B103","day":"Wednesday","lessonType":"Tutorial","size":20},{"classNo":"06","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0114","day":"Monday","lessonType":"Tutorial","size":20},{"classNo":"12","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0114","day":"Wednesday","lessonType":"Tutorial","size":20},{"classNo":"1","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-AUD","day":"Tuesday","lessonType":"Lecture","size":250}],"examDate":"2019-12-02T09:00:00.000Z","examDuration":120},{"semester":2,"timetable":[{"classNo":"13","startTime":"1700","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0203","day":"Tuesday","lessonType":"Tutorial","size":15},{"classNo":"11","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0207","day":"Monday","lessonType":"Tutorial","size":15},{"classNo":"04","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0207","day":"Monday","lessonType":"Tutorial","size":15},{"classNo":"05","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0203","day":"Wednesday","lessonType":"Tutorial","size":15},{"classNo":"12","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0203","day":"Tuesday","lessonType":"Tutorial","size":15},{"classNo":"08","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0203","day":"Wednesday","lessonType":"Tutorial","size":15},{"classNo":"02","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0203","day":"Wednesday","lessonType":"Tutorial","size":15},{"classNo":"07","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0114","day":"Friday","lessonType":"Tutorial","size":15},{"classNo":"06","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0203","day":"Tuesday","lessonType":"Tutorial","size":15},{"classNo":"09","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0203","day":"Wednesday","lessonType":"Tutorial","size":15},{"classNo":"14","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0114","day":"Friday","lessonType":"Tutorial","size":15},{"classNo":"1","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"I3-AUD","day":"Thursday","lessonType":"Lecture","size":250},{"classNo":"10","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0114","day":"Friday","lessonType":"Tutorial","size":15},{"classNo":"01","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0203","day":"Tuesday","lessonType":"Tutorial","size":15},{"classNo":"03","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0114","day":"Friday","lessonType":"Tutorial","size":15}],"examDate":"2020-05-05T01:00:00.000Z","examDuration":120},{"semester":4,"timetable":[{"classNo":"02","startTime":"1400","endTime":"1500","weeks":{"start":"2020-06-22","end":"2020-07-27"},"venue":"SR_LT19","day":"Monday","lessonType":"Tutorial","size":20},{"classNo":"03","startTime":"1500","endTime":"1600","weeks":{"start":"2020-06-22","end":"2020-07-27"},"venue":"SR_LT19","day":"Monday","lessonType":"Tutorial","size":20},{"classNo":"04","startTime":"1600","endTime":"1700","weeks":{"start":"2020-06-22","end":"2020-07-27"},"venue":"SR_LT19","day":"Monday","lessonType":"Tutorial","size":20},{"classNo":"01","startTime":"1300","endTime":"1400","weeks":{"start":"2020-06-24","end":"2020-07-29"},"venue":"SR_LT19","day":"Wednesday","lessonType":"Tutorial","size":20},{"classNo":"03","startTime":"1500","endTime":"1600","weeks":{"start":"2020-06-24","end":"2020-07-29"},"venue":"SR_LT19","day":"Wednesday","lessonType":"Tutorial","size":20},{"classNo":"04","startTime":"1600","endTime":"1700","weeks":{"start":"2020-06-24","end":"2020-07-29"},"venue":"SR_LT19","day":"Wednesday","lessonType":"Tutorial","size":20},{"classNo":"1","startTime":"1000","endTime":"1200","weeks":{"start":"2020-06-24","end":"2020-07-29"},"venue":"LT19","day":"Wednesday","lessonType":"Lecture","size":100},{"classNo":"01","startTime":"1300","endTime":"1400","weeks":{"start":"2020-06-22","end":"2020-07-27"},"venue":"SR_LT19","day":"Monday","lessonType":"Tutorial","size":20},{"classNo":"05","startTime":"1700","endTime":"1800","weeks":{"start":"2020-06-22","end":"2020-07-27"},"venue":"SR_LT19","day":"Monday","lessonType":"Tutorial","size":20},{"classNo":"05","startTime":"1700","endTime":"1800","weeks":{"start":"2020-06-24","end":"2020-07-29"},"venue":"SR_LT19","day":"Wednesday","lessonType":"Tutorial","size":20},{"classNo":"1","startTime":"1000","endTime":"1200","weeks":{"start":"2020-06-22","end":"2020-07-27"},"venue":"LT19","day":"Monday","lessonType":"Lecture","size":100},{"classNo":"02","startTime":"1400","endTime":"1500","weeks":{"start":"2020-06-24","end":"2020-07-29"},"venue":"SR_LT19","day":"Wednesday","lessonType":"Tutorial","size":20}]}],"prereqTree":{"and":[{"or":["CS2010","CS2020","CS2040"]},{"or":["MA1100","CS1231"]}]},"fulfillRequirements":["CS6283","CS6244","CS6215","CS6285","CS6281","CS6235","CS5330","CS5238","CS5234","CS5237","CS5206","CS6210","CS4257","CS4234","CS4268","CS4235","CS4231"]} diff --git a/src/main/java/seedu/address/searcher/cache/CS3243.txt b/src/main/java/seedu/address/searcher/cache/CS3243.txt new file mode 100644 index 00000000000..55672fad400 --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/CS3243.txt @@ -0,0 +1 @@ +{"acadYear":"2019/2020","preclusion":"EEE and CPE students can only take this module as a technical elective to satisfy the program requirements or UEM but not CFM/ULR-Breadth.","description":"The module introduces the basic concepts in search and knowledge representation as well as to a number of sub-areas of artificial intelligence. It focuses on covering the essential concepts in AI. The module covers Turing test, blind search, iterative deepening, production systems, heuristic search, A* algorithm, minimax and alpha-beta procedures, predicate and first-order logic, resolution refutation, non-monotonic reasoning, assumption-based truth maintenance systems, inheritance hierarchies, the frame problem, certainly factors, Bayes' rule, frames and semantic nets, planning, learning, natural language, vision, and expert systems and LISP.","title":"Introduction to Artificial Intelligence","department":"Computer Science","faculty":"Computing","workload":[2,1,0,3,4],"prerequisite":"((CS2010 or its equivalent) or CS2020 or (CS2040 or its equivalent))\nand (MA1100 or (CS1231 or its equivalent))","moduleCredit":"4","moduleCode":"CS3243","semesterData":[{"semester":1,"timetable":[{"classNo":"08","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0203","day":"Wednesday","lessonType":"Tutorial","size":20},{"classNo":"09","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0203","day":"Tuesday","lessonType":"Tutorial","size":20},{"classNo":"10","startTime":"1700","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0203","day":"Tuesday","lessonType":"Tutorial","size":20},{"classNo":"02","startTime":"0900","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0201","day":"Wednesday","lessonType":"Tutorial","size":20},{"classNo":"07","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0203","day":"Wednesday","lessonType":"Tutorial","size":20},{"classNo":"04","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0201","day":"Wednesday","lessonType":"Tutorial","size":20},{"classNo":"05","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0203","day":"Wednesday","lessonType":"Tutorial","size":20},{"classNo":"06","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0203","day":"Wednesday","lessonType":"Tutorial","size":20},{"classNo":"01","startTime":"0800","endTime":"0900","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0201","day":"Wednesday","lessonType":"Tutorial","size":20},{"classNo":"1","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"LT19","day":"Monday","lessonType":"Lecture","size":200},{"classNo":"03","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0201","day":"Wednesday","lessonType":"Tutorial","size":20}],"examDate":"2019-11-26T01:00:00.000Z","examDuration":120},{"semester":2,"timetable":[{"classNo":"1","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"LT15","day":"Thursday","lessonType":"Lecture","size":200},{"classNo":"07","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0216","day":"Wednesday","lessonType":"Tutorial","size":20},{"classNo":"11","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0203","day":"Tuesday","lessonType":"Tutorial","size":20},{"classNo":"02","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0216","day":"Wednesday","lessonType":"Tutorial","size":20},{"classNo":"01","startTime":"0800","endTime":"0900","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Monday","lessonType":"Tutorial","size":20},{"classNo":"09","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Tuesday","lessonType":"Tutorial","size":20},{"classNo":"12","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0203","day":"Tuesday","lessonType":"Tutorial","size":20},{"classNo":"08","startTime":"0900","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Monday","lessonType":"Tutorial","size":20},{"classNo":"10","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0203","day":"Thursday","lessonType":"Tutorial","size":20},{"classNo":"06","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0203","day":"Thursday","lessonType":"Tutorial","size":20},{"classNo":"03","startTime":"1700","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0113","day":"Tuesday","lessonType":"Tutorial","size":20},{"classNo":"04","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0201","day":"Wednesday","lessonType":"Tutorial","size":20},{"classNo":"05","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0201","day":"Wednesday","lessonType":"Tutorial","size":20}],"examDate":"2020-05-02T05:00:00.000Z","examDuration":120},{"semester":3,"timetable":[{"classNo":"1","startTime":"1000","endTime":"1200","weeks":{"start":"2020-05-13","end":"2020-06-17"},"venue":"COM1-VCRM","day":"Wednesday","lessonType":"Lecture","size":50},{"classNo":"01","startTime":"1300","endTime":"1400","weeks":{"start":"2020-05-13","end":"2020-06-17"},"venue":"COM1-VCRM","day":"Wednesday","lessonType":"Tutorial","size":20},{"classNo":"02","startTime":"1400","endTime":"1500","weeks":{"start":"2020-05-13","end":"2020-06-17"},"venue":"COM1-VCRM","day":"Wednesday","lessonType":"Tutorial","size":20},{"classNo":"03","startTime":"1500","endTime":"1600","weeks":{"start":"2020-05-11","end":"2020-06-15"},"venue":"COM1-VCRM","day":"Monday","lessonType":"Tutorial","size":20},{"classNo":"1","startTime":"1000","endTime":"1200","weeks":{"start":"2020-05-11","end":"2020-06-15"},"venue":"COM1-VCRM","day":"Monday","lessonType":"Lecture","size":50},{"classNo":"02","startTime":"1400","endTime":"1500","weeks":{"start":"2020-05-11","end":"2020-06-15"},"venue":"COM1-VCRM","day":"Monday","lessonType":"Tutorial","size":20},{"classNo":"01","startTime":"1300","endTime":"1400","weeks":{"start":"2020-05-11","end":"2020-06-15"},"venue":"COM1-VCRM","day":"Monday","lessonType":"Tutorial","size":20},{"classNo":"03","startTime":"1500","endTime":"1600","weeks":{"start":"2020-05-13","end":"2020-06-17"},"venue":"COM1-VCRM","day":"Wednesday","lessonType":"Tutorial","size":20}],"examDate":"2020-06-19T01:00:00.000Z","examDuration":120}],"prereqTree":{"and":[{"or":["CS2010","CS2020","CS2040"]},{"or":["MA1100","CS1231"]}]},"fulfillRequirements":["CS5340","CS5228","CS5338","CS5446","CS6208","CS4246","CS4244","CS4248","CS5478","CS4278"]} diff --git a/src/main/java/seedu/address/searcher/cache/CS4433.txt b/src/main/java/seedu/address/searcher/cache/CS4433.txt new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/CS4433.txt @@ -0,0 +1 @@ + diff --git a/src/main/java/seedu/address/searcher/cache/CS4434.txt b/src/main/java/seedu/address/searcher/cache/CS4434.txt new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/CS4434.txt @@ -0,0 +1 @@ + diff --git a/src/main/java/seedu/address/searcher/cache/CSDAS.txt b/src/main/java/seedu/address/searcher/cache/CSDAS.txt new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/CSDAS.txt @@ -0,0 +1 @@ + diff --git a/src/main/java/seedu/address/searcher/cache/DASDAS.txt b/src/main/java/seedu/address/searcher/cache/DASDAS.txt new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/DASDAS.txt @@ -0,0 +1 @@ + diff --git a/src/main/java/seedu/address/searcher/cache/DASDSA.txt b/src/main/java/seedu/address/searcher/cache/DASDSA.txt new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/DASDSA.txt @@ -0,0 +1 @@ + diff --git a/src/main/java/seedu/address/searcher/cache/ES2660.txt b/src/main/java/seedu/address/searcher/cache/ES2660.txt new file mode 100644 index 00000000000..2fa93aae18b --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/ES2660.txt @@ -0,0 +1 @@ +{"acadYear":"2019/2020","preclusion":"GET1006 and GEK1901","description":"In a context of prolific production and convenient access to content and innovation in the Information Age, how should one critically process and clearly communicate ideas to various audiences? In this module, students will learn to question and articulate their analysis of assumptions and assertions on issues facing the Information Age through processes such as identifying bias and substantiating arguments. The Ennis’ (1986, 2001) taxonomy of critical thinking dispositions will be employed to develop students’ analytical thinking skills and their ability to articulate cogent responses to arguments or to defend their own positions in both written and oral form.","title":"Communicating in the Information Age","department":"Center for Engl Lang Comms","faculty":"NUS","workload":[0,4,0,2,4],"prerequisite":"1. Students who are required to take ES1000 Foundation Academic English and/or ES1103 English for Academic Purposes, must pass those modules before they are allowed to read this module.\n2. Only SoC students matriculated in AY2016/2017 and after, are allowed to take ES2660.","moduleCredit":"4","moduleCode":"ES2660","attributes":{"su":true},"semesterData":[{"semester":1,"timetable":[{"classNo":"G14","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0611","day":"Monday","lessonType":"Sectional Teaching","size":18},{"classNo":"G03","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0210","day":"Tuesday","lessonType":"Sectional Teaching","size":18},{"classNo":"G11","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0611","day":"Tuesday","lessonType":"Sectional Teaching","size":18},{"classNo":"G04","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0208","day":"Tuesday","lessonType":"Sectional Teaching","size":18},{"classNo":"G06","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0203","day":"Monday","lessonType":"Sectional Teaching","size":18},{"classNo":"G12","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0611","day":"Monday","lessonType":"Sectional Teaching","size":18},{"classNo":"G10","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0611","day":"Tuesday","lessonType":"Sectional Teaching","size":18},{"classNo":"G12","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0611","day":"Thursday","lessonType":"Sectional Teaching","size":18},{"classNo":"G13","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0610","day":"Tuesday","lessonType":"Sectional Teaching","size":18},{"classNo":"G01","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0210","day":"Thursday","lessonType":"Sectional Teaching","size":18},{"classNo":"G05","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0201","day":"Thursday","lessonType":"Sectional Teaching","size":18},{"classNo":"G11","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0611","day":"Friday","lessonType":"Sectional Teaching","size":18},{"classNo":"G04","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0208","day":"Friday","lessonType":"Sectional Teaching","size":18},{"classNo":"G09","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0611","day":"Friday","lessonType":"Sectional Teaching","size":18},{"classNo":"G05","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0201","day":"Monday","lessonType":"Sectional Teaching","size":18},{"classNo":"G01","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0210","day":"Monday","lessonType":"Sectional Teaching","size":18},{"classNo":"G02","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0210","day":"Monday","lessonType":"Sectional Teaching","size":18},{"classNo":"G08","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0203","day":"Monday","lessonType":"Sectional Teaching","size":18},{"classNo":"G08","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0203","day":"Thursday","lessonType":"Sectional Teaching","size":18},{"classNo":"G02","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0210","day":"Thursday","lessonType":"Sectional Teaching","size":18},{"classNo":"G06","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0203","day":"Thursday","lessonType":"Sectional Teaching","size":18},{"classNo":"G09","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0611","day":"Tuesday","lessonType":"Sectional Teaching","size":18},{"classNo":"G14","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0611","day":"Thursday","lessonType":"Sectional Teaching","size":18},{"classNo":"G15","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0611","day":"Friday","lessonType":"Sectional Teaching","size":18},{"classNo":"G10","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0611","day":"Friday","lessonType":"Sectional Teaching","size":18},{"classNo":"G13","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0610","day":"Friday","lessonType":"Sectional Teaching","size":18},{"classNo":"G07","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0203","day":"Monday","lessonType":"Sectional Teaching","size":18},{"classNo":"G15","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0611","day":"Tuesday","lessonType":"Sectional Teaching","size":18},{"classNo":"G07","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"COM1-0203","day":"Thursday","lessonType":"Sectional Teaching","size":18},{"classNo":"G03","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS6-0208","day":"Friday","lessonType":"Sectional Teaching","size":18}]},{"semester":2,"timetable":[{"classNo":"G11","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0611","day":"Thursday","lessonType":"Sectional Teaching","size":18},{"classNo":"G06","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0620","day":"Tuesday","lessonType":"Sectional Teaching","size":18},{"classNo":"G11","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0611","day":"Monday","lessonType":"Sectional Teaching","size":18},{"classNo":"G12","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0611","day":"Tuesday","lessonType":"Sectional Teaching","size":18},{"classNo":"G04","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0620","day":"Thursday","lessonType":"Sectional Teaching","size":18},{"classNo":"G03","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0620","day":"Thursday","lessonType":"Sectional Teaching","size":18},{"classNo":"G03","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0620","day":"Monday","lessonType":"Sectional Teaching","size":18},{"classNo":"G06","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0620","day":"Friday","lessonType":"Sectional Teaching","size":18},{"classNo":"G04","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0620","day":"Monday","lessonType":"Sectional Teaching","size":18},{"classNo":"G07","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0610","day":"Friday","lessonType":"Sectional Teaching","size":18},{"classNo":"G10","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0611","day":"Monday","lessonType":"Sectional Teaching","size":18},{"classNo":"G10","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0611","day":"Thursday","lessonType":"Sectional Teaching","size":18},{"classNo":"G05","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0620","day":"Tuesday","lessonType":"Sectional Teaching","size":18},{"classNo":"G08","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0620","day":"Friday","lessonType":"Sectional Teaching","size":18},{"classNo":"G09","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0620","day":"Thursday","lessonType":"Sectional Teaching","size":18},{"classNo":"G01","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0620","day":"Thursday","lessonType":"Sectional Teaching","size":18},{"classNo":"G01","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0620","day":"Monday","lessonType":"Sectional Teaching","size":18},{"classNo":"G05","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0620","day":"Friday","lessonType":"Sectional Teaching","size":18},{"classNo":"G09","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0620","day":"Monday","lessonType":"Sectional Teaching","size":18},{"classNo":"G08","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0620","day":"Tuesday","lessonType":"Sectional Teaching","size":18},{"classNo":"G12","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0611","day":"Friday","lessonType":"Sectional Teaching","size":18},{"classNo":"G13","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0611","day":"Tuesday","lessonType":"Sectional Teaching","size":18},{"classNo":"G13","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0611","day":"Friday","lessonType":"Sectional Teaching","size":18},{"classNo":"G02","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0620","day":"Thursday","lessonType":"Sectional Teaching","size":18},{"classNo":"G02","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0620","day":"Monday","lessonType":"Sectional Teaching","size":18},{"classNo":"G07","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"AS3-0610","day":"Tuesday","lessonType":"Sectional Teaching","size":18}]}]} diff --git a/src/main/java/seedu/address/searcher/cache/IS1103.txt b/src/main/java/seedu/address/searcher/cache/IS1103.txt new file mode 100644 index 00000000000..11194fa0ff9 --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/IS1103.txt @@ -0,0 +1 @@ +{"acadYear":"2019/2020","description":"The module gives a wide yet insightful understanding of the impact of IT on organisation and society. Issues such as Internet and “new economy” geographies; impacts of IT and creation of IT innovation for public\nhealth, urban planning, and regional equity, food systems, climate change can be discussed. Other issues for consideration could be dark web and IT security advancement, open vs. closed innovation creation. Misuse of IT that put ethics and professionalism into question will be also discussed.","title":"IS Innovations in Organisations and Society","department":"Information Systems and Analytics","faculty":"Computing","workload":[2,1,0,3,4],"moduleCredit":"4","moduleCode":"IS1103","attributes":{"su":true},"semesterData":[{"semester":1,"timetable":[{"classNo":"1","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"UT-AUD2","day":"Monday","lessonType":"Sectional Teaching","size":465},{"classNo":"18","startTime":"1200","endTime":"1400","weeks":[2,4,6,8,10,12],"venue":"COM1-0207","day":"Thursday","lessonType":"Tutorial","size":25},{"classNo":"03","startTime":"1200","endTime":"1400","weeks":[1,3,5,7,9,11,13],"venue":"COM2-0108","day":"Friday","lessonType":"Tutorial","size":25},{"classNo":"01","startTime":"1400","endTime":"1600","weeks":[1,3,5,7,9,11,13],"venue":"COM1-0209","day":"Wednesday","lessonType":"Tutorial","size":25},{"classNo":"10","startTime":"1000","endTime":"1200","weeks":[2,4,6,8,10,12],"venue":"COM1-0216","day":"Wednesday","lessonType":"Tutorial","size":21},{"classNo":"12","startTime":"0800","endTime":"1000","weeks":[2,4,6,8,10,12],"venue":"COM2-0108","day":"Thursday","lessonType":"Tutorial","size":25},{"classNo":"09","startTime":"1000","endTime":"1200","weeks":[1,3,5,7,9,11,13],"venue":"COM1-0216","day":"Wednesday","lessonType":"Tutorial","size":21},{"classNo":"05","startTime":"1200","endTime":"1400","weeks":[1,3,5,7,9,11,13],"venue":"COM1-0209","day":"Tuesday","lessonType":"Tutorial","size":25},{"classNo":"08","startTime":"1400","endTime":"1600","weeks":[2,4,6,8,10,12],"venue":"COM1-0216","day":"Tuesday","lessonType":"Tutorial","size":21},{"classNo":"07","startTime":"1400","endTime":"1600","weeks":[1,3,5,7,9,11,13],"venue":"COM1-0216","day":"Tuesday","lessonType":"Tutorial","size":21},{"classNo":"13","startTime":"1400","endTime":"1600","weeks":[1,3,5,7,9,11,13],"venue":"COM1-0207","day":"Friday","lessonType":"Tutorial","size":25},{"classNo":"15","startTime":"1600","endTime":"1800","weeks":[1,3,5,7,9,11,13],"venue":"COM1-0216","day":"Thursday","lessonType":"Tutorial","size":21},{"classNo":"19","startTime":"1600","endTime":"1800","weeks":[1,3,5,7,9,11,13],"venue":"COM1-0209","day":"Friday","lessonType":"Tutorial","size":25},{"classNo":"17","startTime":"1200","endTime":"1400","weeks":[1,3,5,7,9,11,13],"venue":"COM1-0207","day":"Thursday","lessonType":"Tutorial","size":25},{"classNo":"11","startTime":"0800","endTime":"1000","weeks":[1,3,5,7,9,11,13],"venue":"COM2-0108","day":"Thursday","lessonType":"Tutorial","size":25},{"classNo":"06","startTime":"1200","endTime":"1400","weeks":[2,4,6,8,10,12],"venue":"COM1-0209","day":"Tuesday","lessonType":"Tutorial","size":25},{"classNo":"20","startTime":"1600","endTime":"1800","weeks":[2,4,6,8,10,12],"venue":"COM1-0209","day":"Friday","lessonType":"Tutorial","size":25},{"classNo":"02","startTime":"1400","endTime":"1600","weeks":[2,4,6,8,10,12],"venue":"COM1-0209","day":"Wednesday","lessonType":"Tutorial","size":25},{"classNo":"04","startTime":"1200","endTime":"1400","weeks":[2,4,6,8,10,12],"venue":"COM2-0108","day":"Friday","lessonType":"Tutorial","size":25},{"classNo":"16","startTime":"1600","endTime":"1800","weeks":[2,4,6,8,10,12],"venue":"COM1-0216","day":"Thursday","lessonType":"Tutorial","size":21},{"classNo":"14","startTime":"1400","endTime":"1600","weeks":[2,4,6,8,10,12],"venue":"COM1-0207","day":"Friday","lessonType":"Tutorial","size":25}]},{"semester":2,"timetable":[]}],"fulfillRequirements":["IS4100","IS3251","IS3103","IS3240","IS4240","IS4250","IS4241","IS3221","IS3101"]} diff --git a/src/main/java/seedu/address/searcher/cache/IT1107.txt b/src/main/java/seedu/address/searcher/cache/IT1107.txt new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/IT1107.txt @@ -0,0 +1 @@ + diff --git a/src/main/java/seedu/address/searcher/cache/MA1101R.txt b/src/main/java/seedu/address/searcher/cache/MA1101R.txt new file mode 100644 index 00000000000..1f5bb22aba6 --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/MA1101R.txt @@ -0,0 +1 @@ +{"acadYear":"2019/2020","preclusion":"EG1401, EG1402, MA1101, MA1311, MA1506, MA1508, FOE students","description":"This module is a first course in linear algebra. Fundamental concepts of linear algebra will be introduced and investigated in the context of the Euclidean spaces R^n. Proofs of results will be presented in the concrete setting. Students are expected to acquire computational facilities and geometric intuition with regard to vectors and matrices. Some applications will be presented. Major topics: Systems of linear equations, matrices, determinants, Euclidean spaces, linear combinations and linear span, subspaces, linear independence, bases and dimension, rank of a matrix, inner products, eigenvalues and eigenvectors, diagonalization, linear transformations between Euclidean spaces, applications.","title":"Linear Algebra I","department":"Mathematics","faculty":"Science","workload":[3,1,1,0,6],"prerequisite":"GCE ‘A’ Level or H2 Mathematics or H2 Further Mathematics or MA1301 or MA1301FC or MA1301X","moduleCredit":"4","moduleCode":"MA1101R","attributes":{"su":true},"semesterData":[{"semester":1,"timetable":[{"classNo":"3","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"UT-AUD2","day":"Wednesday","lessonType":"Lecture","size":335},{"classNo":"2","startTime":"1000","endTime":"1100","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0611","day":"Monday","lessonType":"Tutorial","size":30},{"classNo":"3","startTime":"1100","endTime":"1200","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0611","day":"Monday","lessonType":"Tutorial","size":30},{"classNo":"4","startTime":"1200","endTime":"1300","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0406","day":"Tuesday","lessonType":"Tutorial","size":30},{"classNo":"10","startTime":"1400","endTime":"1500","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0611","day":"Thursday","lessonType":"Tutorial","size":30},{"classNo":"29","startTime":"1200","endTime":"1300","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0611","day":"Friday","lessonType":"Tutorial","size":30},{"classNo":"30","startTime":"1400","endTime":"1500","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0611","day":"Friday","lessonType":"Tutorial","size":30},{"classNo":"27","startTime":"0900","endTime":"1000","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0406","day":"Thursday","lessonType":"Tutorial","size":30},{"classNo":"17","startTime":"1500","endTime":"1600","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-0436","day":"Monday","lessonType":"Tutorial","size":30},{"classNo":"18","startTime":"1600","endTime":"1700","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-0436","day":"Monday","lessonType":"Tutorial","size":30},{"classNo":"12","startTime":"1600","endTime":"1700","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0611","day":"Thursday","lessonType":"Tutorial","size":30},{"classNo":"5","startTime":"1300","endTime":"1400","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0406","day":"Tuesday","lessonType":"Tutorial","size":30},{"classNo":"7","startTime":"0900","endTime":"1000","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0404","day":"Wednesday","lessonType":"Tutorial","size":30},{"classNo":"20","startTime":"1400","endTime":"1500","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0405","day":"Tuesday","lessonType":"Tutorial","size":30},{"classNo":"1","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"LT26","day":"Tuesday","lessonType":"Lecture","size":335},{"classNo":"2","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"UT-AUD1","day":"Monday","lessonType":"Lecture","size":335},{"classNo":"1","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"LT26","day":"Friday","lessonType":"Lecture","size":335},{"classNo":"C1","startTime":"1000","endTime":"1200","weeks":[4,6,8,10,12],"venue":"S17-0302","day":"Monday","lessonType":"Laboratory","size":42},{"classNo":"22","startTime":"1600","endTime":"1700","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0512","day":"Tuesday","lessonType":"Tutorial","size":30},{"classNo":"3","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"UT-AUD2","day":"Friday","lessonType":"Lecture","size":335},{"classNo":"11","startTime":"1500","endTime":"1600","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0611","day":"Thursday","lessonType":"Tutorial","size":30},{"classNo":"21","startTime":"1500","endTime":"1600","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0405","day":"Tuesday","lessonType":"Tutorial","size":30},{"classNo":"15","startTime":"1500","endTime":"1600","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0611","day":"Friday","lessonType":"Tutorial","size":30},{"classNo":"14","startTime":"1100","endTime":"1200","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0406","day":"Friday","lessonType":"Tutorial","size":30},{"classNo":"2","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"UT-AUD1","day":"Thursday","lessonType":"Lecture","size":335},{"classNo":"C2","startTime":"1100","endTime":"1300","weeks":[4,6,8,10,12],"venue":"S17-0302","day":"Wednesday","lessonType":"Laboratory","size":42},{"classNo":"24","startTime":"1000","endTime":"1100","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0405","day":"Wednesday","lessonType":"Tutorial","size":30},{"classNo":"13","startTime":"1000","endTime":"1100","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0406","day":"Friday","lessonType":"Tutorial","size":30},{"classNo":"C5","startTime":"1500","endTime":"1700","weeks":[12],"venue":"S17-0302","day":"Thursday","lessonType":"Laboratory","size":42},{"classNo":"C3","startTime":"1100","endTime":"1300","weeks":[4,6,8,10,12],"venue":"S17-0302","day":"Friday","lessonType":"Laboratory","size":42},{"classNo":"C4","startTime":"1600","endTime":"1800","weeks":[12],"venue":"S17-0302","day":"Tuesday","lessonType":"Laboratory","size":42}],"examDate":"2019-11-28T09:00:00.000Z","examDuration":120},{"semester":2,"timetable":[{"classNo":"2","startTime":"1200","endTime":"1300","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0512","day":"Monday","lessonType":"Tutorial","size":30},{"classNo":"8","startTime":"1600","endTime":"1700","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0406","day":"Tuesday","lessonType":"Tutorial","size":30},{"classNo":"9","startTime":"1700","endTime":"1800","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0406","day":"Tuesday","lessonType":"Tutorial","size":30},{"classNo":"16","startTime":"0800","endTime":"0900","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0405","day":"Thursday","lessonType":"Tutorial","size":30},{"classNo":"20","startTime":"1600","endTime":"1700","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S14-0620","day":"Friday","lessonType":"Tutorial","size":30},{"classNo":"21","startTime":"1700","endTime":"1800","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S14-0620","day":"Friday","lessonType":"Tutorial","size":30},{"classNo":"22","startTime":"1400","endTime":"1500","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S14-0620","day":"Friday","lessonType":"Tutorial","size":30},{"classNo":"23","startTime":"1500","endTime":"1600","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S14-0620","day":"Friday","lessonType":"Tutorial","size":30},{"classNo":"12","startTime":"1100","endTime":"1200","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0512","day":"Wednesday","lessonType":"Tutorial","size":30},{"classNo":"14","startTime":"1400","endTime":"1500","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0405","day":"Wednesday","lessonType":"Tutorial","size":30},{"classNo":"2","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"LT27","day":"Tuesday","lessonType":"Lecture","size":450},{"classNo":"1","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"LT27","day":"Thursday","lessonType":"Lecture","size":451},{"classNo":"18","startTime":"1000","endTime":"1100","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0611","day":"Thursday","lessonType":"Tutorial","size":30},{"classNo":"24","startTime":"1000","endTime":"1100","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0512","day":"Monday","lessonType":"Tutorial","size":30},{"classNo":"4","startTime":"1400","endTime":"1500","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0404","day":"Monday","lessonType":"Tutorial","size":30},{"classNo":"7","startTime":"1500","endTime":"1600","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0512","day":"Tuesday","lessonType":"Tutorial","size":30},{"classNo":"25","startTime":"1300","endTime":"1400","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0512","day":"Wednesday","lessonType":"Tutorial","size":30},{"classNo":"15","startTime":"1500","endTime":"1600","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0405","day":"Wednesday","lessonType":"Tutorial","size":30},{"classNo":"6","startTime":"1400","endTime":"1500","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0512","day":"Tuesday","lessonType":"Tutorial","size":30},{"classNo":"C2","startTime":"1100","endTime":"1300","weeks":[4,6,8,10,12],"venue":"S17-0302","day":"Wednesday","lessonType":"Laboratory","size":42},{"classNo":"C3","startTime":"1300","endTime":"1500","weeks":[4,6,8,10,12],"venue":"S17-0302","day":"Thursday","lessonType":"Laboratory","size":42},{"classNo":"3","startTime":"1300","endTime":"1400","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0512","day":"Monday","lessonType":"Tutorial","size":30},{"classNo":"5","startTime":"1500","endTime":"1600","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0404","day":"Monday","lessonType":"Tutorial","size":30},{"classNo":"10","startTime":"0900","endTime":"1000","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0512","day":"Wednesday","lessonType":"Tutorial","size":30},{"classNo":"11","startTime":"1000","endTime":"1100","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0512","day":"Wednesday","lessonType":"Tutorial","size":30},{"classNo":"17","startTime":"0900","endTime":"1000","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0405","day":"Thursday","lessonType":"Tutorial","size":30},{"classNo":"2","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"LT27","day":"Friday","lessonType":"Lecture","size":450},{"classNo":"19","startTime":"1100","endTime":"1200","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0611","day":"Thursday","lessonType":"Tutorial","size":30},{"classNo":"1","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"LT27","day":"Monday","lessonType":"Lecture","size":451},{"classNo":"1","startTime":"1100","endTime":"1200","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0512","day":"Monday","lessonType":"Tutorial","size":30},{"classNo":"13","startTime":"1200","endTime":"1300","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0512","day":"Wednesday","lessonType":"Tutorial","size":30},{"classNo":"C1","startTime":"1500","endTime":"1700","weeks":[4,6,8,10,12],"venue":"S17-0302","day":"Tuesday","lessonType":"Laboratory","size":42}],"examDate":"2020-04-30T09:00:00.000Z","examDuration":120}],"fulfillRequirements":["EC3314","DSC3214","CS5246","CS6244","CS5240","CS5332","CS5343","CS5249","CS5241","CS4347","CS3218","CS4234","CS3242","CS4268","CS4243","CS3244","CS4235","BT4240","MA3266","MA3252","MA3238","MA3229","MA3220","DSA3102","MA2312","MA2289","MA2288","MA2219","MA2214","MA2213","DSA2102","MA2101S","MA2101","PC2130","PC2131","PC2134","PC2132","DSA4212","ST3236","DSA2101","CS5478","CS5477","CS4278","CS4277","IT3011"]} diff --git a/src/main/java/seedu/address/searcher/cache/MA1521.txt b/src/main/java/seedu/address/searcher/cache/MA1521.txt new file mode 100644 index 00000000000..d08c73173ff --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/MA1521.txt @@ -0,0 +1 @@ +{"acadYear":"2019/2020","preclusion":"Students reading a primary major in Mathematics/Applied Mathematics/Quantitative Finance/Data Science and Analytics, MA1102R, MA1312, MA1505, MA1507, MA2501, FoE students","description":"This module provides a basic foundation for calculus and its related subjects required by computing students. The objective is to train the students to be able to handle calculus techniques arising in their courses of specialization. In addition to the standard calculus material, the course also covers simple mathematical modeling techniques and numerical methods in connection with ordinary differential equations. \n\n\n\nMajor topics: \n\nPreliminaries on sets and number systems. \n\nCalculus of functions of one variable and applications. \n\nSequences, series and power series. \n\nFunctions of several variables. Extrema.\n\nFirst and second order differential equations. \n\nBasic numerical methods for ordinary differential equations.","title":"Calculus for Computing","department":"Mathematics","faculty":"Science","workload":[3,1,0,0,6],"prerequisite":"GCE ‘A’ Level Mathematics or H2 Mathematics or H2 Further Mathematics or MA1301 or MA1301X","moduleCredit":"4","moduleCode":"MA1521","attributes":{"su":true},"semesterData":[{"semester":1,"timetable":[{"classNo":"16","startTime":"1200","endTime":"1300","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0511","day":"Wednesday","lessonType":"Tutorial","size":30},{"classNo":"20","startTime":"1600","endTime":"1700","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0404","day":"Thursday","lessonType":"Tutorial","size":30},{"classNo":"21","startTime":"1700","endTime":"1800","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0404","day":"Thursday","lessonType":"Tutorial","size":30},{"classNo":"4","startTime":"1000","endTime":"1100","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-0304","day":"Tuesday","lessonType":"Tutorial","size":30},{"classNo":"5","startTime":"1600","endTime":"1700","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0611","day":"Tuesday","lessonType":"Tutorial","size":30},{"classNo":"6","startTime":"1700","endTime":"1800","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0611","day":"Tuesday","lessonType":"Tutorial","size":30},{"classNo":"24","startTime":"1300","endTime":"1400","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0511","day":"Friday","lessonType":"Tutorial","size":30},{"classNo":"7","startTime":"1100","endTime":"1200","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0404","day":"Thursday","lessonType":"Tutorial","size":30},{"classNo":"8","startTime":"1200","endTime":"1300","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S14-0620","day":"Thursday","lessonType":"Tutorial","size":30},{"classNo":"10","startTime":"0900","endTime":"1000","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0611","day":"Friday","lessonType":"Tutorial","size":30},{"classNo":"18","startTime":"1400","endTime":"1500","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0511","day":"Wednesday","lessonType":"Tutorial","size":30},{"classNo":"11","startTime":"1000","endTime":"1100","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0611","day":"Friday","lessonType":"Tutorial","size":30},{"classNo":"22","startTime":"1100","endTime":"1200","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0512","day":"Friday","lessonType":"Tutorial","size":30},{"classNo":"14","startTime":"1000","endTime":"1100","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0511","day":"Monday","lessonType":"Tutorial","size":30},{"classNo":"15","startTime":"1100","endTime":"1200","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0511","day":"Monday","lessonType":"Tutorial","size":30},{"classNo":"13","startTime":"0900","endTime":"1000","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0404","day":"Monday","lessonType":"Tutorial","size":30},{"classNo":"3","startTime":"0900","endTime":"1000","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-0304","day":"Tuesday","lessonType":"Tutorial","size":30},{"classNo":"2","startTime":"1500","endTime":"1600","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0611","day":"Monday","lessonType":"Tutorial","size":30},{"classNo":"1","startTime":"1400","endTime":"1500","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0611","day":"Monday","lessonType":"Tutorial","size":30},{"classNo":"12","startTime":"0800","endTime":"0900","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0404","day":"Monday","lessonType":"Tutorial","size":30},{"classNo":"2","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"LT32","day":"Tuesday","lessonType":"Lecture","size":400},{"classNo":"2","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"LT32","day":"Thursday","lessonType":"Lecture","size":400},{"classNo":"17","startTime":"1300","endTime":"1400","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0511","day":"Wednesday","lessonType":"Tutorial","size":30},{"classNo":"9","startTime":"1300","endTime":"1400","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S14-0620","day":"Thursday","lessonType":"Tutorial","size":30},{"classNo":"19","startTime":"1500","endTime":"1600","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0511","day":"Wednesday","lessonType":"Tutorial","size":30},{"classNo":"1","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"LT26","day":"Monday","lessonType":"Lecture","size":350},{"classNo":"1","startTime":"1600","endTime":"1800","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"LT26","day":"Wednesday","lessonType":"Lecture","size":350}],"examDate":"2019-11-30T01:00:00.000Z","examDuration":120},{"semester":2,"timetable":[{"classNo":"8","startTime":"1000","endTime":"1100","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0406","day":"Thursday","lessonType":"Tutorial","size":30},{"classNo":"11","startTime":"1600","endTime":"1700","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0404","day":"Friday","lessonType":"Tutorial","size":30},{"classNo":"10","startTime":"1500","endTime":"1600","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0404","day":"Friday","lessonType":"Tutorial","size":30},{"classNo":"6","startTime":"1400","endTime":"1500","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0404","day":"Wednesday","lessonType":"Tutorial","size":30},{"classNo":"7","startTime":"0900","endTime":"1000","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0406","day":"Thursday","lessonType":"Tutorial","size":30},{"classNo":"4","startTime":"1000","endTime":"1100","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0406","day":"Tuesday","lessonType":"Tutorial","size":30},{"classNo":"5","startTime":"1300","endTime":"1400","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0404","day":"Wednesday","lessonType":"Tutorial","size":30},{"classNo":"1","startTime":"0900","endTime":"1000","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0611","day":"Monday","lessonType":"Tutorial","size":30},{"classNo":"2","startTime":"1000","endTime":"1100","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0611","day":"Monday","lessonType":"Tutorial","size":30},{"classNo":"1","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"UT-AUD3","day":"Monday","lessonType":"Lecture","size":260},{"classNo":"9","startTime":"1100","endTime":"1200","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0406","day":"Thursday","lessonType":"Tutorial","size":30},{"classNo":"3","startTime":"0900","endTime":"1000","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0406","day":"Tuesday","lessonType":"Tutorial","size":30},{"classNo":"2","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"UT-AUD2","day":"Friday","lessonType":"Lecture","size":360},{"classNo":"1","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"UT-AUD3","day":"Thursday","lessonType":"Lecture","size":260},{"classNo":"2","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"UT-AUD2","day":"Tuesday","lessonType":"Lecture","size":360}],"examDate":"2020-05-05T01:00:00.000Z","examDuration":120}],"fulfillRequirements":["DSC3214","CS5240","CS5332","CS5343","CS5249","CS5241","CS4347","CS3218","CS3242","CS4243","CS3244","BT2101","IS4242","BT4240","MA3220","MA2312","MA2311","MA2216","MA2213","MA2108S","MA2108","MA2104","MA1506","MA1104","ST2131","ST2334","CS5478","IT3011","CS4278"]} diff --git a/src/main/java/seedu/address/searcher/cache/MA2108.txt b/src/main/java/seedu/address/searcher/cache/MA2108.txt new file mode 100644 index 00000000000..a32de9f7d20 --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/MA2108.txt @@ -0,0 +1 @@ +{"acadYear":"2019/2020","preclusion":"MA2108S, MA2311","description":"This module is a continuation of MA1100. The main objective is to further develop the student's mastery of the mathematical language, concepts, and methods. The focus here is more on the analytic and topological notions such as convergence and continuity, which are essential for a rigorous treatment of mathematical analysis. The student's ability to read and write mathematical proofs is also further developed in this module. Main topics: real numbers, sequences and series of real numbers, metrics in Euclidean spaces, open and closed sets, continuous functions, compact sets, connected sets, sequences of functions. Major applications include: intermediate value theorem, extreme value theorem.","title":"Mathematical Analysis I","department":"Mathematics","faculty":"Science","workload":[3,1,0,0,6],"prerequisite":"MA1102R or MA1505 or MA1511 or MA1505C or MA1507 or MA1521","moduleCredit":"4","moduleCode":"MA2108","semesterData":[{"semester":1,"timetable":[{"classNo":"2","startTime":"1000","endTime":"1100","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0611","day":"Wednesday","lessonType":"Tutorial","size":30},{"classNo":"1","startTime":"1000","endTime":"1100","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0404","day":"Tuesday","lessonType":"Tutorial","size":30},{"classNo":"3","startTime":"0900","endTime":"1000","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0404","day":"Tuesday","lessonType":"Tutorial","size":30},{"classNo":"1","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"LT29","day":"Thursday","lessonType":"Lecture","size":100},{"classNo":"4","startTime":"0900","endTime":"1000","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0611","day":"Wednesday","lessonType":"Tutorial","size":30},{"classNo":"1","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"LT29","day":"Monday","lessonType":"Lecture","size":100}],"examDate":"2019-12-04T09:00:00.000Z","examDuration":120},{"semester":2,"timetable":[{"classNo":"1","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"LT26","day":"Wednesday","lessonType":"Lecture","size":150},{"classNo":"1","startTime":"1200","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"LT26","day":"Friday","lessonType":"Lecture","size":150},{"classNo":"2","startTime":"1300","endTime":"1400","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0404","day":"Monday","lessonType":"Tutorial","size":30},{"classNo":"3","startTime":"0900","endTime":"1000","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0405","day":"Monday","lessonType":"Tutorial","size":30},{"classNo":"1","startTime":"1200","endTime":"1300","weeks":[3,4,5,6,7,8,9,10,11,12,13],"venue":"S17-0404","day":"Monday","lessonType":"Tutorial","size":30}],"examDate":"2020-05-05T05:00:00.000Z","examDuration":120}],"prereqTree":{"or":["MA1102R","MA1505","MA1511","MA1505C","MA1507","MA1521"]},"fulfillRequirements":["MA4248","MA3291","MA3265","MA3264","MA3220","MA3110S","MA3110"]} diff --git a/src/main/java/seedu/address/searcher/cache/ST2132.txt b/src/main/java/seedu/address/searcher/cache/ST2132.txt new file mode 100644 index 00000000000..f6be091e5f4 --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/ST2132.txt @@ -0,0 +1 @@ +{"acadYear":"2019/2020","description":"This module introduces students to the theoretical underpinnings of statistical methodology and concentrates on inferential procedures within the framework of parametric models. Topic include: random sample and statistics, method of moments, maximum likelihood estimate, Fisher information, sufficiency and completeness, consistency and unbiasedness, sampling distributions, x2-, t- and Fdistributions, confidence intervals, exact and asymptotic pivotal method, concepts of hypothesis testing, likelihood ratio test, Neyman-Pearson lemma. This module is targeted at students who are interested in Statistic and are able to meet the prerequisite.","title":"Mathematical Statistics","department":"Statistics and Applied Probability","faculty":"Science","workload":[3,1,0,3,3],"prerequisite":"MA2216 or ST2131 or ST2334","moduleCredit":"4","moduleCode":"ST2132","semesterData":[{"semester":1,"timetable":[{"classNo":"1","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"LT31","day":"Friday","lessonType":"Lecture","size":200},{"classNo":"1","startTime":"1400","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"LT31","day":"Tuesday","lessonType":"Lecture","size":200},{"classNo":"1","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-06118","day":"Tuesday","lessonType":"Tutorial","size":28},{"classNo":"5","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-05102","day":"Wednesday","lessonType":"Tutorial","size":29},{"classNo":"6","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-0304","day":"Friday","lessonType":"Tutorial","size":29},{"classNo":"2","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-06118","day":"Tuesday","lessonType":"Tutorial","size":28},{"classNo":"3","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-06118","day":"Tuesday","lessonType":"Tutorial","size":28},{"classNo":"4","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-05102","day":"Wednesday","lessonType":"Tutorial","size":29}],"examDate":"2019-12-02T01:00:00.000Z","examDuration":120},{"semester":2,"timetable":[{"classNo":"1","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"LT29","day":"Thursday","lessonType":"Lecture","size":190},{"classNo":"1","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-0430","day":"Tuesday","lessonType":"Tutorial","size":30},{"classNo":"2","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-0440","day":"Tuesday","lessonType":"Tutorial","size":30},{"classNo":"3","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-0440","day":"Tuesday","lessonType":"Tutorial","size":30},{"classNo":"4","startTime":"1600","endTime":"1700","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-06118","day":"Tuesday","lessonType":"Tutorial","size":45},{"classNo":"1","startTime":"1000","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"LT29","day":"Tuesday","lessonType":"Lecture","size":190}],"examDate":"2020-05-06T01:00:00.000Z","examDuration":120}],"prereqTree":{"or":["MA2216","ST2131","ST2334"]},"fulfillRequirements":["CS5239","CS5340","CS5346","CS5228","CS5233","CS5332","CS5446","CS4257","CS4246","IS4242","ST5217","ST5215","ST5212","ST5211","ST4241","ST4234","ST4232","ST4231","DSA4212","ST3248","ST3246","ST3243","ST3242","ST3233","ST3232","DSA3101"]} diff --git a/src/main/java/seedu/address/searcher/cache/ST2312.txt b/src/main/java/seedu/address/searcher/cache/ST2312.txt new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/ST2312.txt @@ -0,0 +1 @@ + diff --git a/src/main/java/seedu/address/searcher/cache/ST3131.txt b/src/main/java/seedu/address/searcher/cache/ST3131.txt new file mode 100644 index 00000000000..b67c640066d --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/ST3131.txt @@ -0,0 +1 @@ +{"acadYear":"2019/2020","preclusion":"ST2335, EC3303","description":"This module focuses on data analysis using multiple regression models. Topics include simple linear regression, multiple regression, model building and regression diagnostics. One and two factor analysis of variance, analysis of covariance, linear model as special case of generalized linear model. This module is targeted at students who are interested in Statistics and are able to meet the pre-requisites.","title":"Regression Analysis","department":"Statistics and Applied Probability","faculty":"Science","workload":[3,1,0,3,3],"prerequisite":"ST2131 or MA2216 or ST2334","moduleCredit":"4","moduleCode":"ST3131","semesterData":[{"semester":1,"timetable":[{"classNo":"1","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"LT34","day":"Wednesday","lessonType":"Lecture","size":190},{"classNo":"1","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"LT34","day":"Friday","lessonType":"Lecture","size":190},{"classNo":"4","startTime":"1400","endTime":"1500","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-05102","day":"Wednesday","lessonType":"Tutorial","size":48},{"classNo":"5","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-05102","day":"Friday","lessonType":"Tutorial","size":29},{"classNo":"1","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-05101","day":"Tuesday","lessonType":"Tutorial","size":47},{"classNo":"2","startTime":"1100","endTime":"1200","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-05101","day":"Tuesday","lessonType":"Tutorial","size":47},{"classNo":"3","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-05101","day":"Friday","lessonType":"Tutorial","size":48}],"examDate":"2019-11-27T01:00:00.000Z","examDuration":120},{"semester":2,"timetable":[{"classNo":"6","startTime":"0900","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-05101","day":"Wednesday","lessonType":"Tutorial","size":29},{"classNo":"5","startTime":"1000","endTime":"1100","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-05101","day":"Tuesday","lessonType":"Tutorial","size":29},{"classNo":"3","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-05101","day":"Thursday","lessonType":"Tutorial","size":29},{"classNo":"4","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-05101","day":"Thursday","lessonType":"Tutorial","size":29},{"classNo":"1","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"LT26","day":"Thursday","lessonType":"Lecture","size":220},{"classNo":"1","startTime":"0800","endTime":"1000","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"LT26","day":"Tuesday","lessonType":"Lecture","size":220},{"classNo":"1","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-05101","day":"Tuesday","lessonType":"Tutorial","size":29},{"classNo":"2","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-05101","day":"Wednesday","lessonType":"Tutorial","size":29},{"classNo":"8","startTime":"1300","endTime":"1400","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-05101","day":"Wednesday","lessonType":"Tutorial","size":29},{"classNo":"9","startTime":"1500","endTime":"1600","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-05101","day":"Wednesday","lessonType":"Tutorial","size":29},{"classNo":"7","startTime":"1200","endTime":"1300","weeks":[1,2,3,4,5,6,7,8,9,10,11,12,13],"venue":"S16-05101","day":"Wednesday","lessonType":"Tutorial","size":29}],"examDate":"2020-04-30T01:00:00.000Z","examDuration":120}],"prereqTree":{"or":["ST2131","MA2216","ST2334"]},"fulfillRequirements":["BSS4003B","BSN4811A","ST5207","ST5213","ST5220","ST4248","ST4245","DSA4211","ST4233","ST3241","ST3240","ST4242","ST4240"]} diff --git a/src/main/java/seedu/address/searcher/cache/casfas.txt b/src/main/java/seedu/address/searcher/cache/casfas.txt new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/casfas.txt @@ -0,0 +1 @@ + diff --git a/src/main/java/seedu/address/searcher/cache/cs 1101s.txt b/src/main/java/seedu/address/searcher/cache/cs 1101s.txt new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/src/main/java/seedu/address/searcher/cache/cs 1101s.txt @@ -0,0 +1 @@ + diff --git a/src/main/java/seedu/address/storage/AddressBookStorage.java b/src/main/java/seedu/address/storage/AddressBookStorage.java index 4599182b3f9..a6f1feb0c94 100644 --- a/src/main/java/seedu/address/storage/AddressBookStorage.java +++ b/src/main/java/seedu/address/storage/AddressBookStorage.java @@ -42,4 +42,6 @@ public interface AddressBookStorage { */ void saveAddressBook(ReadOnlyAddressBook addressBook, Path filePath) throws IOException; + + } diff --git a/src/main/java/seedu/address/storage/CalendarBookStorage.java b/src/main/java/seedu/address/storage/CalendarBookStorage.java new file mode 100644 index 00000000000..7bc3c304636 --- /dev/null +++ b/src/main/java/seedu/address/storage/CalendarBookStorage.java @@ -0,0 +1,42 @@ +package seedu.address.storage; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.Optional; + +import javafx.collections.ObservableList; +import seedu.address.commons.exceptions.DataConversionException; +import seedu.address.model.calender.Task; + +/** + * API for module book storage + */ +public interface CalendarBookStorage { + /** + * Returns the file path of the data file. + */ + Path getCalendarEntriesFilePath(); + + /** + * Returns Calendar data as a List of task + * Returns {@code Optional.empty()} if storage file is not found. + * + * @throws DataConversionException if the data in storage is not in the expected format. + * @throws IOException if there was any problem when reading from the storage. + */ + Optional> readCalendar() throws DataConversionException, IOException; + + /** + * @see #readCalendar() + */ + Optional> readCalendar(Path filePath) throws DataConversionException, IOException; + + + void saveCalendar(ObservableList taskList) throws IOException; + + /** + * + */ + void saveCalendar(ObservableList taskList, Path filePath) throws IOException; + +} diff --git a/src/main/java/seedu/address/storage/JsonAdaptedCalendar.java b/src/main/java/seedu/address/storage/JsonAdaptedCalendar.java new file mode 100644 index 00000000000..6189e91d46f --- /dev/null +++ b/src/main/java/seedu/address/storage/JsonAdaptedCalendar.java @@ -0,0 +1,88 @@ +package seedu.address.storage; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; + +import seedu.address.commons.exceptions.IllegalValueException; +import seedu.address.model.calender.Deadline; +import seedu.address.model.calender.Task; +import seedu.address.model.nusmodule.ModuleCode; +import seedu.address.model.nusmodule.ModuleTask; +import seedu.address.model.nusmodule.Priority; + + +/** + * Jackson-friendly version of {@link Task}. + */ +class JsonAdaptedCalendar { + + public static final String MISSING_FIELD_MESSAGE_FORMAT = "Calendar's %s field is missing!"; + + private final String description; + private final String date; + private final String category; + private final String module; + private final String priority; + private final boolean status; + + /** + * Constructs a {@code JsonAdaptedCalendar} with the given date details. + */ + @JsonCreator + public JsonAdaptedCalendar(@JsonProperty("description") String description, @JsonProperty("date") String date, + @JsonProperty("category") String category, + @JsonProperty("module") String module, + @JsonProperty("priority") String priority, + @JsonProperty("status") boolean status) { + this.description = description; + this.date = date; + this.category = category; + this.module = module; + this.priority = priority; + this.status = status; + } + + + /** + * Converts a given {@code calendar} into this class for Jackson use. + */ + public JsonAdaptedCalendar(Task task) { + description = task.getDescription(); + date = task.getDate(); + status = task.getStatus(); + + if (task instanceof ModuleTask) { + category = "School"; + priority = Integer.toString(((ModuleTask) task).getPriority().getLevelOfSignificance()); + module = ((ModuleTask) task).getModuleRelated().toString(); + } else { + category = task.getCategory(); + priority = "1"; + module = "-1"; + } + } + + /** + * Converts this Jackson-friendly adapted Task object into the model's {@code task} object. + * + * @throws IllegalValueException if there were any data constraints violated in the adapted person. + */ + public Task toModelType() throws IllegalValueException { + + if (this.module.equals("-1")) { + Deadline deadline = new Deadline(description, date, category, "add"); + if (status) { + deadline.markAsDone(); + } + return deadline; + } else { + ModuleTask moduleTask = new ModuleTask( + description, new ModuleCode(module), date, Priority.getPriority(priority)); + if (status) { + moduleTask.markAsDone(); + } + return moduleTask; + } + } + +} diff --git a/src/main/java/seedu/address/storage/JsonAdaptedDiary.java b/src/main/java/seedu/address/storage/JsonAdaptedDiary.java new file mode 100644 index 00000000000..17d6faa3404 --- /dev/null +++ b/src/main/java/seedu/address/storage/JsonAdaptedDiary.java @@ -0,0 +1,57 @@ +package seedu.address.storage; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; + +import seedu.address.commons.exceptions.IllegalValueException; +import seedu.address.model.diary.DiaryEntry; + + +/** + * Jackson-friendly version of {@link DiaryEntry}. + */ +class JsonAdaptedDiary { + + public static final String MISSING_FIELD_MESSAGE_FORMAT = "Diary's %s field is missing!"; + + private final String entryContent; + private final String date; + private final String weather; + private final String mood; + + /** + * Constructs a {@code JsonAdaptedDiary} with the given person details. + */ + @JsonCreator + public JsonAdaptedDiary(@JsonProperty("entry_content") String entryContent, @JsonProperty("date") String date, + @JsonProperty("weather") String weather, + @JsonProperty("mood") String mood) { + this.entryContent = entryContent; + this.date = date; + this.weather = weather; + this.mood = mood; + } + + + /** + * Dummy java docs. + * @param source param + */ + public JsonAdaptedDiary(DiaryEntry source) { + entryContent = source.getEntryContent(); + date = source.getDate().toString(); + weather = source.getWeather().toString(); + mood = source.getMood().toString(); + } + + /** + * Converts this Jackson-friendly adapted DiaryEntry object into the model's {@code DiaryEntry} object. + * + * @throws IllegalValueException if there were any data constraints violated in the adapted person. + */ + public DiaryEntry toModelType() throws IllegalValueException { + + return new DiaryEntry(entryContent); + } + +} diff --git a/src/main/java/seedu/address/storage/JsonAdaptedModuleTask.java b/src/main/java/seedu/address/storage/JsonAdaptedModuleTask.java new file mode 100644 index 00000000000..dbaf6ceb83e --- /dev/null +++ b/src/main/java/seedu/address/storage/JsonAdaptedModuleTask.java @@ -0,0 +1,91 @@ +package seedu.address.storage; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; + +import seedu.address.commons.exceptions.IllegalValueException; +import seedu.address.model.calender.Task; +import seedu.address.model.nusmodule.ModuleCode; +import seedu.address.model.nusmodule.ModuleTask; +import seedu.address.model.nusmodule.Priority; + +/** + * Creates a JsonAdaptedModuleTask for usage + */ +public class JsonAdaptedModuleTask { + + public static final String MISSING_FIELD_MESSAGE_FORMAT = "Person's %s field is missing!"; + + private final String moduleRelated; + private final String timing; + private final String priority; + private final String description; + private boolean isDone; + + /** + * Constructs a {@code ModuleTask} with the given task details. + */ + @JsonCreator + public JsonAdaptedModuleTask(@JsonProperty("moduleRelated") String moduleRelated, + @JsonProperty("timing") String timing, + @JsonProperty("priority") String priority, + @JsonProperty("description") String description, + @JsonProperty("isDone") boolean isDone) { + this.moduleRelated = moduleRelated; + this.timing = timing; + this.priority = priority; + this.description = description; + this.isDone = isDone; + } + + /** + * Converts a given {@code Tag} into this class for Jackson use. + */ + public JsonAdaptedModuleTask(ModuleTask source) { + moduleRelated = source.getModuleRelated().toString(); + timing = source.getDate(); + priority = Integer.toString(source.getPriority().getLevelOfSignificance()); + description = source.getDescription(); + isDone = source.getStatus(); + } + + /** + * Converts this Jackson-friendly adapted person object into the model's {@code Person} object. + * + * @throws IllegalValueException if there were any data constraints violated in the adapted person. + */ + public ModuleTask toModelType() throws IllegalValueException { + + if (moduleRelated == null) { + throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, + ModuleCode.class.getSimpleName())); + } + if (!ModuleCode.isValidModuleCode(moduleRelated)) { + throw new IllegalValueException(ModuleCode.MESSAGE_CONSTRAINTS); + } + final ModuleCode moduleCode = new ModuleCode(moduleRelated); + + if (timing == null) { + throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, "timing")); + } + if (!Task.isValidDate(timing)) { + throw new IllegalValueException("invalid date!"); + } + + if (priority == null) { + throw new IllegalValueException( + String.format(MISSING_FIELD_MESSAGE_FORMAT, Priority.class.getSimpleName())); + } + if (!Priority.isValidPriority(priority)) { + throw new IllegalValueException(Priority.MESSAGE_CONSTRAINTS); + } + final Priority modelPriority = Priority.getPriority(priority); + ModuleTask result = new ModuleTask(description, moduleCode, timing, modelPriority); + + if (isDone) { + result.markAsDone(); + } + + return result; + } +} diff --git a/src/main/java/seedu/address/storage/JsonAdaptedNusModule.java b/src/main/java/seedu/address/storage/JsonAdaptedNusModule.java new file mode 100644 index 00000000000..09d104d75eb --- /dev/null +++ b/src/main/java/seedu/address/storage/JsonAdaptedNusModule.java @@ -0,0 +1,93 @@ +package seedu.address.storage; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; + +import seedu.address.commons.exceptions.IllegalValueException; +import seedu.address.model.nusmodule.Grade; +import seedu.address.model.nusmodule.ModuleCode; +import seedu.address.model.nusmodule.ModuleTask; +import seedu.address.model.nusmodule.NusModule; + +/** + * Jackson-friendly version of {@link NusModule}. + */ +public class JsonAdaptedNusModule { + public static final String MISSING_FIELD_MESSAGE_FORMAT = "NusModule's %s field is missing!"; + + private final String moduleCode; + private final String modularCredit; + private final String grade; + private final List tasks = new ArrayList<>(); + + /** + * Constructs a {@code JsonAdaptedNusModule} with the given module details. + */ + @JsonCreator + public JsonAdaptedNusModule(@JsonProperty("moduleCode") String moduleCode, + @JsonProperty("modularCredit") String modularCredit, + @JsonProperty("grade") String grade, + @JsonProperty("tasks") List tasks) { + this.moduleCode = moduleCode; + this.modularCredit = modularCredit; + this.grade = grade; + if (tasks != null) { + this.tasks.addAll(tasks); + } + } + + /** + * Converts a given {@code Person} into this class for Jackson use. + */ + public JsonAdaptedNusModule(NusModule source) { + moduleCode = source.getModuleCode().toString(); + modularCredit = Integer.toString(source.getModularCredit()); + if (source.getGrade().isEmpty()) { + grade = null; + } else { + grade = source.getGrade().get().getText(); + } + tasks.addAll(source.getTasks().stream() + .map(JsonAdaptedModuleTask::new) + .collect(Collectors.toList())); + } + + /** + * Converts this Jackson-friendly adapted nus module object into the model's {@code NusModule} object. + * + * @throws IllegalValueException if there were any data constraints violated in the adapted nus module. + */ + public NusModule toModelType() throws IllegalValueException { + final List moduleTasks = new ArrayList<>(); + for (JsonAdaptedModuleTask task : tasks) { + moduleTasks.add(task.toModelType()); + } + + if (moduleCode == null) { + throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, + ModuleCode.class.getSimpleName())); + } + if (!ModuleCode.isValidModuleCode(moduleCode)) { + throw new IllegalValueException(ModuleCode.MESSAGE_CONSTRAINTS); + } + final ModuleCode modelModuleCode = new ModuleCode(moduleCode); + + if (modularCredit == null) { + throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, "modular credit")); + } + + final int modelMc = Integer.parseInt(modularCredit); + + Grade modelGrade = null; + if (grade != null) { + modelGrade = Grade.getGrade(grade); + } + + return new NusModule(modelModuleCode, modelMc, Optional.ofNullable(modelGrade), moduleTasks); + } +} diff --git a/src/main/java/seedu/address/storage/JsonAdaptedPerson.java b/src/main/java/seedu/address/storage/JsonAdaptedPerson.java index a6321cec2ea..52af76e9ca7 100644 --- a/src/main/java/seedu/address/storage/JsonAdaptedPerson.java +++ b/src/main/java/seedu/address/storage/JsonAdaptedPerson.java @@ -10,7 +10,6 @@ import com.fasterxml.jackson.annotation.JsonProperty; import seedu.address.commons.exceptions.IllegalValueException; -import seedu.address.model.person.Address; import seedu.address.model.person.Email; import seedu.address.model.person.Name; import seedu.address.model.person.Person; @@ -27,7 +26,6 @@ class JsonAdaptedPerson { private final String name; private final String phone; private final String email; - private final String address; private final List tagged = new ArrayList<>(); /** @@ -35,12 +33,11 @@ class JsonAdaptedPerson { */ @JsonCreator public JsonAdaptedPerson(@JsonProperty("name") String name, @JsonProperty("phone") String phone, - @JsonProperty("email") String email, @JsonProperty("address") String address, + @JsonProperty("email") String email, @JsonProperty("tagged") List tagged) { this.name = name; this.phone = phone; this.email = email; - this.address = address; if (tagged != null) { this.tagged.addAll(tagged); } @@ -53,7 +50,6 @@ public JsonAdaptedPerson(Person source) { name = source.getName().fullName; phone = source.getPhone().value; email = source.getEmail().value; - address = source.getAddress().value; tagged.addAll(source.getTags().stream() .map(JsonAdaptedTag::new) .collect(Collectors.toList())); @@ -94,16 +90,8 @@ public Person toModelType() throws IllegalValueException { } final Email modelEmail = new Email(email); - if (address == null) { - throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, Address.class.getSimpleName())); - } - if (!Address.isValidAddress(address)) { - throw new IllegalValueException(Address.MESSAGE_CONSTRAINTS); - } - final Address modelAddress = new Address(address); - final Set modelTags = new HashSet<>(personTags); - return new Person(modelName, modelPhone, modelEmail, modelAddress, modelTags); + return new Person(modelName, modelPhone, modelEmail, modelTags); } } diff --git a/src/main/java/seedu/address/storage/JsonAddressBookStorage.java b/src/main/java/seedu/address/storage/JsonAddressBookStorage.java index dfab9daaa0d..260276ed9df 100644 --- a/src/main/java/seedu/address/storage/JsonAddressBookStorage.java +++ b/src/main/java/seedu/address/storage/JsonAddressBookStorage.java @@ -22,9 +22,16 @@ public class JsonAddressBookStorage implements AddressBookStorage { private static final Logger logger = LogsCenter.getLogger(JsonAddressBookStorage.class); private Path filePath; + private Path calendarEntriesFilePath; + + public JsonAddressBookStorage(Path filePath, Path calendarEntriesFilePath) { + this.filePath = filePath; + this.calendarEntriesFilePath = calendarEntriesFilePath; + } public JsonAddressBookStorage(Path filePath) { this.filePath = filePath; + this.calendarEntriesFilePath = null; } public Path getAddressBookFilePath() { diff --git a/src/main/java/seedu/address/storage/JsonCalendarStorage.java b/src/main/java/seedu/address/storage/JsonCalendarStorage.java new file mode 100644 index 00000000000..0cd7eda57e4 --- /dev/null +++ b/src/main/java/seedu/address/storage/JsonCalendarStorage.java @@ -0,0 +1,74 @@ +package seedu.address.storage; + +import static java.util.Objects.requireNonNull; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.Optional; +import java.util.logging.Logger; + +import javafx.collections.ObservableList; +import seedu.address.commons.core.LogsCenter; +import seedu.address.commons.exceptions.DataConversionException; +import seedu.address.commons.exceptions.IllegalValueException; +import seedu.address.commons.util.FileUtil; +import seedu.address.commons.util.JsonUtil; +import seedu.address.model.calender.Task; + +/** + * A class to access ModuleBook data stored as a json file on the hard disk. + */ +public class JsonCalendarStorage implements CalendarBookStorage { + private static final Logger logger = LogsCenter.getLogger(JsonModuleBookStorage.class); + + private Path filePath; + + public JsonCalendarStorage(Path filePath) { + this.filePath = filePath; + } + + + @Override + public Path getCalendarEntriesFilePath() { + return filePath; + } + + @Override + public Optional> readCalendar() throws DataConversionException, IOException { + return readCalendar(filePath); + } + + @Override + public Optional> readCalendar(Path filePath) throws DataConversionException, IOException { + requireNonNull(filePath); + + Optional jsonCalendarBook = JsonUtil.readJsonFile( + filePath, JsonSerializableCalenderBook.class); + if (!jsonCalendarBook.isPresent()) { + return Optional.empty(); + } + + try { + return Optional.of(jsonCalendarBook.get().toModelType()); + } catch (IllegalValueException ive) { + logger.info("Illegal values found in " + filePath + ": " + ive.getMessage()); + throw new DataConversionException(ive); + } + } + + @Override + public void saveCalendar(ObservableList taskList) throws IOException { + saveCalendar(taskList, filePath); + + } + + @Override + public void saveCalendar(ObservableList taskList, Path filePath) throws IOException { + requireNonNull(taskList); + requireNonNull(filePath); + + FileUtil.createIfMissing(filePath); + JsonUtil.saveJsonFile(new JsonSerializableCalenderBook(taskList), filePath); + + } +} diff --git a/src/main/java/seedu/address/storage/JsonModuleBookStorage.java b/src/main/java/seedu/address/storage/JsonModuleBookStorage.java new file mode 100644 index 00000000000..898867041f3 --- /dev/null +++ b/src/main/java/seedu/address/storage/JsonModuleBookStorage.java @@ -0,0 +1,78 @@ +package seedu.address.storage; + +import static java.util.Objects.requireNonNull; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.Optional; +import java.util.logging.Logger; + +import seedu.address.commons.core.LogsCenter; +import seedu.address.commons.exceptions.DataConversionException; +import seedu.address.commons.exceptions.IllegalValueException; +import seedu.address.commons.util.FileUtil; +import seedu.address.commons.util.JsonUtil; +import seedu.address.model.ModuleBook; + +/** + * A class to access ModuleBook data stored as a json file on the hard disk. + */ +public class JsonModuleBookStorage implements ModuleBookStorage { + private static final Logger logger = LogsCenter.getLogger(JsonModuleBookStorage.class); + + private Path filePath; + + public JsonModuleBookStorage(Path filePath) { + this.filePath = filePath; + } + + public Path getModuleBookFilePath() { + return filePath; + } + + @Override + public Optional readModuleBook() throws DataConversionException { + return readModuleBook(filePath); + } + + /** + * Similar to {@link #readModuleBook()}. + * + * @param filePath location of the data. Cannot be null. + * @throws DataConversionException if the file is not in the correct format. + */ + public Optional readModuleBook(Path filePath) throws DataConversionException { + requireNonNull(filePath); + + Optional jsonModuleBook = JsonUtil.readJsonFile( + filePath, JsonSerializableModuleBook.class); + if (!jsonModuleBook.isPresent()) { + return Optional.empty(); + } + + try { + return Optional.of(jsonModuleBook.get().toModelType()); + } catch (IllegalValueException ive) { + logger.info("Illegal values found in " + filePath + ": " + ive.getMessage()); + throw new DataConversionException(ive); + } + } + + @Override + public void saveModuleBook(ModuleBook moduleBook) throws IOException { + saveModuleBook(moduleBook, filePath); + } + + /** + * Similar to {@link #saveModuleBook(ModuleBook)}. + * + * @param filePath location of the data. Cannot be null. + */ + public void saveModuleBook(ModuleBook moduleBook, Path filePath) throws IOException { + requireNonNull(moduleBook); + requireNonNull(filePath); + + FileUtil.createIfMissing(filePath); + JsonUtil.saveJsonFile(new JsonSerializableModuleBook(moduleBook), filePath); + } +} diff --git a/src/main/java/seedu/address/storage/JsonSerializableAddressBook.java b/src/main/java/seedu/address/storage/JsonSerializableAddressBook.java index 5efd834091d..3a043239321 100644 --- a/src/main/java/seedu/address/storage/JsonSerializableAddressBook.java +++ b/src/main/java/seedu/address/storage/JsonSerializableAddressBook.java @@ -23,12 +23,20 @@ class JsonSerializableAddressBook { private final List persons = new ArrayList<>(); + private final List diary = new ArrayList<>(); + + private final List calendar = new ArrayList<>(); + /** * Constructs a {@code JsonSerializableAddressBook} with the given persons. */ @JsonCreator - public JsonSerializableAddressBook(@JsonProperty("persons") List persons) { + public JsonSerializableAddressBook(@JsonProperty("persons") List persons, + @JsonProperty("diary") List diary) { this.persons.addAll(persons); + if (diary != null) { + this.diary.addAll(diary); + } } /** @@ -54,6 +62,7 @@ public AddressBook toModelType() throws IllegalValueException { } addressBook.addPerson(person); } + return addressBook; } diff --git a/src/main/java/seedu/address/storage/JsonSerializableCalenderBook.java b/src/main/java/seedu/address/storage/JsonSerializableCalenderBook.java new file mode 100644 index 00000000000..4ee8e2561eb --- /dev/null +++ b/src/main/java/seedu/address/storage/JsonSerializableCalenderBook.java @@ -0,0 +1,58 @@ +package seedu.address.storage; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonRootName; + +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import seedu.address.commons.exceptions.IllegalValueException; +import seedu.address.model.calender.Task; + +/** + * An Immutable calendarbook that is serializable to JSON format. + */ +@JsonRootName(value = "calendarbook") +class JsonSerializableCalenderBook { + + private final List calendar = new ArrayList<>(); + + /** + * Constructs a {@code JsonSerializableAddressBook} with the given persons. + */ + @JsonCreator + public JsonSerializableCalenderBook (@JsonProperty("calendar") List calendar) { + this.calendar.addAll(calendar); + + } + + /** + * Converts a given {@code ReadOnlyAddressBook} into this class for Jackson use. + * + * @param source future changes to this will not affect the created {@code JsonSerializableAddressBook}. + */ + public JsonSerializableCalenderBook(ObservableList source) { + calendar.addAll(source.stream().map(JsonAdaptedCalendar::new).collect(Collectors.toList())); + } + + /** + * Converts this address book into the model's {@code AddressBook} object. + * + * @throws IllegalValueException if there were any data constraints violated. + */ + public ObservableList toModelType() throws IllegalValueException { + ObservableList taskList = FXCollections.observableList(new ArrayList<>()); + for (JsonAdaptedCalendar jsonAdaptedCalendar : calendar) { + Task calendarTask = jsonAdaptedCalendar.toModelType(); + taskList.add(calendarTask); + Task.addTaskPerDate(calendarTask.getDate(), calendarTask); + } + + return taskList; + } + +} diff --git a/src/main/java/seedu/address/storage/JsonSerializableModuleBook.java b/src/main/java/seedu/address/storage/JsonSerializableModuleBook.java new file mode 100644 index 00000000000..ff7669dae61 --- /dev/null +++ b/src/main/java/seedu/address/storage/JsonSerializableModuleBook.java @@ -0,0 +1,60 @@ +package seedu.address.storage; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonRootName; + +import seedu.address.commons.exceptions.IllegalValueException; +import seedu.address.model.ModuleBook; +import seedu.address.model.nusmodule.NusModule; + +/** + * An Immutable ModuleBook that is serializable to JSON format. + */ +@JsonRootName(value = "modulebook") +public class JsonSerializableModuleBook { + + public static final String MESSAGE_DUPLICATE_MODULE = "Modules list contains duplicate module(s)."; + + private final List modules = new ArrayList<>(); + + /** + * Constructs a {@code JsonSerializableAddressBook} with the given persons. + */ + @JsonCreator + public JsonSerializableModuleBook(@JsonProperty("modules") List modules) { + this.modules.addAll(modules); + } + + /** + * Converts a given {@code ReadOnlyAddressBook} into this class for Jackson use. + * + * @param source future changes to this will not affect the created {@code JsonSerializableAddressBook}. + */ + public JsonSerializableModuleBook(ModuleBook source) { + modules.addAll(source.getModulesTakenList().stream().map(JsonAdaptedNusModule::new) + .collect(Collectors.toList())); + } + + /** + * Converts this module book into the model's {@code ModuleBook} object. + * + * @throws IllegalValueException if there were any data constraints violated. + */ + public ModuleBook toModelType() throws IllegalValueException { + ModuleBook moduleBook = new ModuleBook(); + for (JsonAdaptedNusModule jsonAdaptedNusModule : modules) { + NusModule module = jsonAdaptedNusModule.toModelType(); + if (moduleBook.hasModule(module.getModuleCode())) { + throw new IllegalValueException(MESSAGE_DUPLICATE_MODULE); + } + moduleBook.addModule(module); + } + + return moduleBook; + } +} diff --git a/src/main/java/seedu/address/storage/ModuleBookStorage.java b/src/main/java/seedu/address/storage/ModuleBookStorage.java new file mode 100644 index 00000000000..bb17f46add6 --- /dev/null +++ b/src/main/java/seedu/address/storage/ModuleBookStorage.java @@ -0,0 +1,45 @@ +package seedu.address.storage; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.Optional; + +import seedu.address.commons.exceptions.DataConversionException; +import seedu.address.model.ModuleBook; +import seedu.address.model.ReadOnlyAddressBook; + +/** + * API for module book storage + */ +public interface ModuleBookStorage { + /** + * Returns the file path of the data file. + */ + Path getModuleBookFilePath(); + + /** + * Returns ModuleBook data as a {@link ModuleBook}. + * Returns {@code Optional.empty()} if storage file is not found. + * @throws DataConversionException if the data in storage is not in the expected format. + * @throws IOException if there was any problem when reading from the storage. + */ + Optional readModuleBook() throws DataConversionException, IOException; + + /** + * @see #getModuleBookFilePath() + */ + Optional readModuleBook(Path filePath) throws DataConversionException, IOException; + + /** + * Saves the given {@link ReadOnlyAddressBook} to the storage. + * @param moduleBook cannot be null. + * @throws IOException if there was any problem writing to the file. + */ + void saveModuleBook(ModuleBook moduleBook) throws IOException; + + /** + * @see #saveModuleBook(ModuleBook) + */ + void saveModuleBook(ModuleBook moduleBook, Path filePath) throws IOException; + +} diff --git a/src/main/java/seedu/address/storage/Storage.java b/src/main/java/seedu/address/storage/Storage.java index beda8bd9f11..c4e72a99d38 100644 --- a/src/main/java/seedu/address/storage/Storage.java +++ b/src/main/java/seedu/address/storage/Storage.java @@ -5,6 +5,7 @@ import java.util.Optional; import seedu.address.commons.exceptions.DataConversionException; +import seedu.address.model.ModuleBook; import seedu.address.model.ReadOnlyAddressBook; import seedu.address.model.ReadOnlyUserPrefs; import seedu.address.model.UserPrefs; @@ -12,7 +13,7 @@ /** * API of the Storage component */ -public interface Storage extends AddressBookStorage, UserPrefsStorage { +public interface Storage extends AddressBookStorage, UserPrefsStorage, ModuleBookStorage, CalendarBookStorage { @Override Optional readUserPrefs() throws DataConversionException, IOException; @@ -29,4 +30,17 @@ public interface Storage extends AddressBookStorage, UserPrefsStorage { @Override void saveAddressBook(ReadOnlyAddressBook addressBook) throws IOException; + @Override + Path getModuleBookFilePath(); + + @Override + Optional readModuleBook() throws DataConversionException, IOException; + + @Override + void saveModuleBook(ModuleBook moduleBook) throws IOException; + + + @Override + Path getCalendarEntriesFilePath(); + } diff --git a/src/main/java/seedu/address/storage/StorageManager.java b/src/main/java/seedu/address/storage/StorageManager.java index e4f452b6cbf..5d15fd9fc0d 100644 --- a/src/main/java/seedu/address/storage/StorageManager.java +++ b/src/main/java/seedu/address/storage/StorageManager.java @@ -5,11 +5,14 @@ import java.util.Optional; import java.util.logging.Logger; +import javafx.collections.ObservableList; import seedu.address.commons.core.LogsCenter; import seedu.address.commons.exceptions.DataConversionException; +import seedu.address.model.ModuleBook; import seedu.address.model.ReadOnlyAddressBook; import seedu.address.model.ReadOnlyUserPrefs; import seedu.address.model.UserPrefs; +import seedu.address.model.calender.Task; /** * Manages storage of AddressBook data in local storage. @@ -19,12 +22,17 @@ public class StorageManager implements Storage { private static final Logger logger = LogsCenter.getLogger(StorageManager.class); private AddressBookStorage addressBookStorage; private UserPrefsStorage userPrefsStorage; + private ModuleBookStorage moduleBookStorage; + private CalendarBookStorage calendarBookStorage; - public StorageManager(AddressBookStorage addressBookStorage, UserPrefsStorage userPrefsStorage) { + public StorageManager(AddressBookStorage addressBookStorage, UserPrefsStorage userPrefsStorage, + ModuleBookStorage moduleBookStorage, CalendarBookStorage calendarBookStorage) { super(); this.addressBookStorage = addressBookStorage; this.userPrefsStorage = userPrefsStorage; + this.moduleBookStorage = moduleBookStorage; + this.calendarBookStorage = calendarBookStorage; } // ================ UserPrefs methods ============================== @@ -73,5 +81,65 @@ public void saveAddressBook(ReadOnlyAddressBook addressBook, Path filePath) thro logger.fine("Attempting to write to data file: " + filePath); addressBookStorage.saveAddressBook(addressBook, filePath); } + // ================ ModuleBook methods ============================== + + @Override + public Path getModuleBookFilePath() { + return moduleBookStorage.getModuleBookFilePath(); + } + + @Override + public Optional readModuleBook() throws DataConversionException, IOException { + return readModuleBook(moduleBookStorage.getModuleBookFilePath()); + } + + @Override + public Optional readModuleBook(Path filePath) throws DataConversionException, IOException { + logger.fine("Attempting to read data from file: " + filePath); + return moduleBookStorage.readModuleBook(filePath); + } + + @Override + public void saveModuleBook(ModuleBook moduleBook) throws IOException { + saveModuleBook(moduleBook, moduleBookStorage.getModuleBookFilePath()); + } + + @Override + public void saveModuleBook(ModuleBook moduleBook, Path filePath) throws IOException { + logger.fine("Attempting to write to data file: " + filePath); + moduleBookStorage.saveModuleBook(moduleBook, filePath); + } + + + // ================ Calendar methods ============================== + @Override + public Path getCalendarEntriesFilePath() { + return calendarBookStorage.getCalendarEntriesFilePath(); + } + + @Override + public Optional> readCalendar() throws DataConversionException, IOException { + return readCalendar(calendarBookStorage.getCalendarEntriesFilePath()); + } + + @Override + public Optional> readCalendar(Path filePath) throws DataConversionException, IOException { + logger.fine("Attempting to read data from file: " + filePath); + return calendarBookStorage.readCalendar(filePath); + } + + @Override + public void saveCalendar(ObservableList taskList) throws IOException { + saveCalendar(taskList, calendarBookStorage.getCalendarEntriesFilePath()); + + } + + @Override + public void saveCalendar(ObservableList taskList, Path filePath) throws IOException { + logger.fine("Attempting to write to data file: " + filePath); + calendarBookStorage.saveCalendar(taskList, filePath); + + } + } diff --git a/src/main/java/seedu/address/ui/CalenderDate.java b/src/main/java/seedu/address/ui/CalenderDate.java new file mode 100644 index 00000000000..885d6c947bc --- /dev/null +++ b/src/main/java/seedu/address/ui/CalenderDate.java @@ -0,0 +1,85 @@ +package seedu.address.ui; + +import java.util.logging.Logger; + +import javafx.fxml.FXML; +import javafx.scene.control.Label; +import javafx.scene.layout.Region; +import javafx.scene.shape.Circle; +import seedu.address.commons.core.LogsCenter; +import seedu.address.model.nusmodule.Priority; + + +/** + * CalenderPanel that holds the month + */ +public class CalenderDate extends UiPart { + private static final String FXML = "CalenderDate.fxml"; + private final Logger logger = LogsCenter.getLogger(CalenderDate.class); + + + private String date; + private String day; + + @FXML + private Label calenderDate; + + @FXML + private Circle circle; + + + + public CalenderDate(String date, int day) { + + super(FXML); + this.date = date; + this.day = "" + day; + + calenderDate.setText(this.day); + setCircleNotVisible(); + setCssStyles(); + } + + public void setCssStyles() { + calenderDate.setStyle("-fx-text-fill: #fb7b6b"); + + } + + public void setCircleNotVisible() { + circle.setVisible(false); + + } + + /** + * Changes colour of the circle based on priority + * @param priority + */ + public void setPriorityColour(Priority priority) { + + String priorityLevel = priority.toString(); + + if (priorityLevel.equals("Very high")) { + circle.setStyle("-fx-fill: #dd2c00"); + } else if (priorityLevel.equals("High")) { + circle.setStyle("-fx-fill: #ff5722"); + } else if (priorityLevel.equals("Medium")) { + circle.setStyle("-fx-fill: #f2ed6f"); + } else if (priorityLevel.equals("Low")) { + circle.setStyle("-fx-fill: #639a67"); + } else { + circle.setStyle("-fx-fill: #2b580c"); + } + } + + public String getDate() { + return this.date; + } + + + public void setCircleVisible() { + circle.setVisible(true); + } + + + +} diff --git a/src/main/java/seedu/address/ui/CalenderDeadline.java b/src/main/java/seedu/address/ui/CalenderDeadline.java new file mode 100644 index 00000000000..cd4b638db2d --- /dev/null +++ b/src/main/java/seedu/address/ui/CalenderDeadline.java @@ -0,0 +1,113 @@ +package seedu.address.ui; + +import javafx.fxml.FXML; +import javafx.scene.control.Label; +import javafx.scene.layout.FlowPane; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Region; +import javafx.scene.shape.Circle; +import seedu.address.model.calender.Task; +import seedu.address.model.nusmodule.ModuleTask; +import seedu.address.model.nusmodule.Priority; + +/** + * An UI component that displays information of a {@code Person}. + */ +public class CalenderDeadline extends UiPart { + + private static final String FXML = "CalenderDeadline.fxml"; + + /** + * Note: Certain keywords such as "location" and "resources" are reserved keywords in JavaFX. + * As a consequence, UI elements' variable names cannot be set to such keywords + * or an exception will be thrown by JavaFX during runtime. + * + * @see The issue on AddressBook level 4 + */ + + public final Task deadline; + + @FXML + private HBox cardPane; + @FXML + private Label category; + @FXML + private Label id; + @FXML + private Label description; + @FXML + private Label date; + @FXML + private FlowPane modCode; + @FXML + private Circle circle; + + + public CalenderDeadline(Task deadline, int displayedIndex) { + super(FXML); + this.deadline = deadline; + id.setText(displayedIndex + ". "); + category.setText(deadline.getCategory()); + description.setText(deadline.getDescription()); + date.setText("Deadline: " + deadline.getDate()); + if (deadline instanceof ModuleTask) { + setModuleTask(deadline); + setPriorityColour(((ModuleTask) deadline).getPriority()); + } else { + setPriorityColour(Priority.VERYLOW); + } + setStatusColor(); + + } + + private void setModuleTask(Task deadline) { + category.setText("School"); + modCode.getChildren().add(new Label(((ModuleTask) deadline).getModuleRelated().toString())); + modCode.setStyle("-fx-background-color: #5b8c5a"); + + } + + private void setStatusColor() { + + if (deadline.getStatus()) { + cardPane.setStyle("-fx-background-color: #323232"); + } else { + cardPane.setStyle("-fx-background-color: #515658"); + } + } + + /** + * Changes colour of the circle based on priority + * @param priority + */ + public void setPriorityColour(Priority priority) { + + String priorityLevel = priority.toString(); + + if (priorityLevel.equals("Very high")) { + circle.setStyle("-fx-fill: #dd2c00"); + } else if (priorityLevel.equals("High")) { + circle.setStyle("-fx-fill: #ff5722"); + } else if (priorityLevel.equals("Medium")) { + circle.setStyle("-fx-fill: #f2ed6f"); + } else if (priorityLevel.equals("Low")) { + circle.setStyle("-fx-fill: #639a67"); + } else { + circle.setStyle("-fx-fill: #2b580c"); + } + } + + @Override + public boolean equals(Object other) { + // short circuit if same object + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof CalenderDeadline)) { + return false; + } + return false; + } +} diff --git a/src/main/java/seedu/address/ui/CalenderListPanel.java b/src/main/java/seedu/address/ui/CalenderListPanel.java new file mode 100644 index 00000000000..746db3c2e76 --- /dev/null +++ b/src/main/java/seedu/address/ui/CalenderListPanel.java @@ -0,0 +1,81 @@ +package seedu.address.ui; + +import java.util.ArrayList; +import java.util.logging.Logger; + +import javafx.collections.ObservableList; +import javafx.fxml.FXML; +import javafx.scene.control.ListCell; +import javafx.scene.control.ListView; +import javafx.scene.layout.Region; +import seedu.address.commons.core.LogsCenter; +import seedu.address.model.calender.Task; +import seedu.address.model.nusmodule.ModuleTask; +import seedu.address.model.nusmodule.Priority; + + +/** + * Panel containing the list of persons. + */ +public class CalenderListPanel extends UiPart { + private static final String FXML = "CalenderListPanel.fxml"; + private final Logger logger = LogsCenter.getLogger(CalenderListPanel.class); + + @FXML + private ListView calenderDeadlineListView; + + public CalenderListPanel(ObservableList deadlineList) { + super(FXML); + calenderDeadlineListView.setItems(deadlineList); + calenderDeadlineListView.setCellFactory(listView -> new DeadlineListViewCell()); + } + + /** + * Custom {@code ListCell} that displays the graphics of a {@code Person} using a {@code PersonCard}. + */ + class DeadlineListViewCell extends ListCell { + @Override + protected void updateItem(Task deadline, boolean empty) { + for (CalenderDate calenderDate : CalenderPanel.getCalenderDatesArrayList()) { + calenderDate.setCircleNotVisible(); + } + for (CalenderDate calenderDate : CalenderPanel.getCalenderDatesArrayList()) { + if (Task.isTaskPresent(calenderDate.getDate())) { + boolean flag = true; + for (Task tasks : Task.getDeadlineTaskHashMap().get(calenderDate.getDate())) { + if (!tasks.getStatus()) { + flag = false; + } + } + if (flag == false) { + calenderDate.setCircleVisible(); + ArrayList allTask = Task.getDeadlineTaskHashMap().get(calenderDate.getDate()); + Priority highestPriority = Priority.VERYLOW; + for (Task tasks : allTask) { + if (tasks instanceof ModuleTask) { + if (((ModuleTask) tasks).getPriority().compareTo(highestPriority) < 0) { + highestPriority = ((ModuleTask) tasks).getPriority(); + } + } + } + calenderDate.setPriorityColour(highestPriority); + } + + } + } + super.updateItem(deadline, empty); + + if (empty || deadline == null) { + setGraphic(null); + setText(null); + + } else { + setGraphic(new CalenderDeadline(deadline, getIndex() + 1).getRoot()); + + + } + } + + } + +} diff --git a/src/main/java/seedu/address/ui/CalenderPanel.java b/src/main/java/seedu/address/ui/CalenderPanel.java new file mode 100644 index 00000000000..e68d69ee48d --- /dev/null +++ b/src/main/java/seedu/address/ui/CalenderPanel.java @@ -0,0 +1,161 @@ +package seedu.address.ui; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.logging.Logger; + +import javafx.fxml.FXML; +import javafx.geometry.Pos; +import javafx.scene.control.Label; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.Region; +import javafx.scene.text.Text; +import seedu.address.commons.core.LogsCenter; + + +/** + * CalenderPanel that holds the month + */ +public class CalenderPanel extends UiPart { + private static int year; + private static int monthNow; + private static ArrayList calenderDatesArrayList = new ArrayList<>(); + private static final String FXML = "Calender.fxml"; + private final Logger logger = LogsCenter.getLogger(CalenderPanel.class); + private final String[] monthsArray = {"January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December"}; + private HashMap datesArray = new HashMap<>(); + private String todayMonth; + private String todayYear; + + + + @FXML + private Text month; + + @FXML + private Text todayDate; + + @FXML + private GridPane calenderGrid; + + @FXML + private Label mon1; + + + public CalenderPanel() { + + super(FXML); + + this.setMonth(); + this.setDatesArray(); + this.setDates(); + calenderGrid.setAlignment(Pos.CENTER); + } + + public void setMonth() { + DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd"); + LocalDateTime now = LocalDateTime.now(); + String[] currentDateArray = dtf.format(now).split("/"); + String currentMonth = currentDateArray[1]; + String currentYear = currentDateArray[0]; + String date = currentDateArray[2]; + todayMonth = currentMonth; + todayYear = currentYear; + + int currentMonthInt = Integer.parseInt(currentMonth); + monthNow = currentMonthInt; + year = Integer.parseInt(todayYear); + String currentMonthAndYear = monthsArray[currentMonthInt - 1] + " " + currentYear; + month.setText(currentMonthAndYear); + todayDate.setText("Today: " + date + " " + currentMonthAndYear); + } + + public void setDates() { + try { + String firstDay = getCalenderDates(); + int firstDayInt = datesArray.get(firstDay); + String dateSkeleton = makeDate(); + for (int i = 1; i < 32; i++) { + String temp = ""; + if (i < 10) { + temp = "0" + i; + } else { + temp = "" + i; + } + calenderDatesArrayList.add(new CalenderDate(temp + dateSkeleton, i)); + } + + int x = 0; + for (int col = firstDayInt; col < 7; col++) { + System.out.println(col); + calenderGrid.add(calenderDatesArrayList.get(x).getRoot(), col, 1, 1, 1); + x++; + } + + for (int row = 2; row < 7; row++) { + for (int col = 0; col < 7; col++) { + if (x >= 31) { + break; + } + calenderGrid.add(calenderDatesArrayList.get(x).getRoot(), col, row, 1, 1); + x++; + } + } + } catch (ParseException ex) { + logger.info(ex.getMessage()); + } + + } + + /** + * Create the date format. + * @return a new date format + */ + private String makeDate() { + String dateSkeleton = ""; + if (monthNow < 10) { + dateSkeleton = "-" + 0 + monthNow + "-" + year; + } else { + dateSkeleton = "-" + monthNow + "-" + year; + } + return dateSkeleton; + } + + private String getCalenderDates() throws ParseException { + String inputDate = String.format("01/%s/%s", todayMonth, todayYear); + SimpleDateFormat format1 = new SimpleDateFormat("dd/MM/yyyy"); + Date dt1 = format1.parse(inputDate); + DateFormat format2 = new SimpleDateFormat("EEEE"); + return format2.format(dt1); + } + + public static ArrayList getCalenderDatesArrayList() { + return calenderDatesArrayList; + } + + public static int getYear() { + return year; + } + + public static int getCurrentMonth() { + return monthNow; + } + + private void setDatesArray() { + datesArray.put("Monday", 0); + datesArray.put("Tuesday", 1); + datesArray.put("Wednesday", 2); + datesArray.put("Thursday", 3); + datesArray.put("Friday", 4); + datesArray.put("Saturday", 5); + datesArray.put("Sunday", 6); + } + +} diff --git a/src/main/java/seedu/address/ui/DiaryEntriesCard.java b/src/main/java/seedu/address/ui/DiaryEntriesCard.java new file mode 100644 index 00000000000..d1621f8d3d5 --- /dev/null +++ b/src/main/java/seedu/address/ui/DiaryEntriesCard.java @@ -0,0 +1,54 @@ +package seedu.address.ui; + +import javafx.fxml.FXML; +import javafx.scene.control.Label; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Region; +import seedu.address.model.diary.DiaryEntry; + +/** + * An UI component that displays information of a {@code Person}. + */ +public class DiaryEntriesCard extends UiPart { + + private static final String FXML = "DiaryListCard.fxml"; + + /** + * Note: Certain keywords such as "location" and "resources" are reserved keywords in JavaFX. + * As a consequence, UI elements' variable names cannot be set to such keywords + * or an exception will be thrown by JavaFX during runtime. + * + * @see The issue on AddressBook level 4 + */ + + public final DiaryEntry diaryEntry; + + @FXML + private HBox cardPane; + @FXML + private Label text; + @FXML + private Label id; + + public DiaryEntriesCard(DiaryEntry diaryEntry, int displayedIndex) { + super(FXML); + this.diaryEntry = diaryEntry; + id.setText(displayedIndex + ". "); + + text.setText(diaryEntry.getDate().toString()); + } + + @Override + public boolean equals(Object other) { + // short circuit if same object + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof NotesCard)) { + return false; + } + return false; + } +} diff --git a/src/main/java/seedu/address/ui/DiaryEntryMainPage.java b/src/main/java/seedu/address/ui/DiaryEntryMainPage.java new file mode 100644 index 00000000000..7074206df33 --- /dev/null +++ b/src/main/java/seedu/address/ui/DiaryEntryMainPage.java @@ -0,0 +1,65 @@ +package seedu.address.ui; + +import javafx.fxml.FXML; +import javafx.scene.control.Label; +import javafx.scene.control.TextArea; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Region; +import seedu.address.model.diary.DiaryEntry; + +/** + * An UI component that displays information of a {@code Person}. + */ +public class DiaryEntryMainPage extends UiPart { + + private static final String FXML = "DiaryEntryMainPage.fxml"; + + /** + * Note: Certain keywords such as "location" and "resources" are reserved keywords in JavaFX. + * As a consequence, UI elements' variable names cannot be set to such keywords + * or an exception will be thrown by JavaFX during runtime. + * + * @see The issue on AddressBook level 4 + */ + + public final DiaryEntry diaryEntry; + + @FXML + private HBox cardPane; + @FXML + private Label date; + @FXML + private Label weather; + @FXML + private Label mood; + @FXML + private TextArea text; + + public DiaryEntryMainPage(DiaryEntry diaryEntry) { + super(FXML); + this.diaryEntry = diaryEntry; + date.setText(diaryEntry.getDate().toString()); + weather.setText(diaryEntry.getWeather().get().toString()); + mood.setText(diaryEntry.getMood().get().toString()); + text.setText(diaryEntry.getEntryContent()); + text.setWrapText(true); + + text.setStyle("-fx-text-inner-color: white;"); + + + } + + @Override + public boolean equals(Object other) { + // short circuit if same object + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof DiaryEntryMainPage)) { + return false; + } + return false; + } +} diff --git a/src/main/java/seedu/address/ui/DiaryListPanel.java b/src/main/java/seedu/address/ui/DiaryListPanel.java new file mode 100644 index 00000000000..c2f0e7b1e78 --- /dev/null +++ b/src/main/java/seedu/address/ui/DiaryListPanel.java @@ -0,0 +1,46 @@ +package seedu.address.ui; + +import java.util.logging.Logger; + +import javafx.collections.ObservableList; +import javafx.fxml.FXML; +import javafx.scene.control.ListCell; +import javafx.scene.control.ListView; +import javafx.scene.layout.Region; +import seedu.address.commons.core.LogsCenter; +import seedu.address.model.diary.DiaryEntry; + +/** + * Panel containing the list of Notes. + */ +public class DiaryListPanel extends UiPart { + private static final String FXML = "DiaryListPanel.fxml"; + private final Logger logger = LogsCenter.getLogger(DiaryListPanel.class); + + @FXML + private ListView diaryListView; + + public DiaryListPanel(ObservableList diaryList) { + super(FXML); + diaryListView.setItems(diaryList); + diaryListView.setCellFactory(listView -> new DiaryListViewCell()); + } + + /** + * Custom {@code ListCell} that displays the graphics of a {@code Notes} using a {@code NotesCard}. + */ + class DiaryListViewCell extends ListCell { + @Override + protected void updateItem(DiaryEntry diaryEntries, boolean empty) { + super.updateItem(diaryEntries, empty); + + if (empty || diaryEntries.toString() == null) { + setGraphic(null); + setText(null); + } else { + setGraphic(new DiaryEntriesCard(diaryEntries, getIndex() + 1).getRoot()); + } + } + } + +} diff --git a/src/main/java/seedu/address/ui/HelpWindow.java b/src/main/java/seedu/address/ui/HelpWindow.java index 9a665915949..ba1914f7a45 100644 --- a/src/main/java/seedu/address/ui/HelpWindow.java +++ b/src/main/java/seedu/address/ui/HelpWindow.java @@ -15,7 +15,8 @@ */ public class HelpWindow extends UiPart { - public static final String USERGUIDE_URL = "https://se-education.org/addressbook-level3/UserGuide.html"; + public static final String USERGUIDE_URL = + "https://ay1920s2-cs2103t-w16-4.github.io/main/UserGuide.html"; public static final String HELP_MESSAGE = "Refer to the user guide: " + USERGUIDE_URL; private static final Logger logger = LogsCenter.getLogger(HelpWindow.class); diff --git a/src/main/java/seedu/address/ui/MainWindow.java b/src/main/java/seedu/address/ui/MainWindow.java index 90bbf11de97..32d16757460 100644 --- a/src/main/java/seedu/address/ui/MainWindow.java +++ b/src/main/java/seedu/address/ui/MainWindow.java @@ -4,10 +4,17 @@ import javafx.event.ActionEvent; import javafx.fxml.FXML; +import javafx.scene.Node; import javafx.scene.control.MenuItem; +import javafx.scene.control.SplitPane; +import javafx.scene.control.Tab; +import javafx.scene.control.TabPane; import javafx.scene.control.TextInputControl; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; import javafx.scene.input.KeyCombination; import javafx.scene.input.KeyEvent; +import javafx.scene.layout.AnchorPane; import javafx.scene.layout.StackPane; import javafx.stage.Stage; import seedu.address.commons.core.GuiSettings; @@ -34,6 +41,16 @@ public class MainWindow extends UiPart { private PersonListPanel personListPanel; private ResultDisplay resultDisplay; private HelpWindow helpWindow; + private NotesListPanel notesListPanel; + private DiaryListPanel diaryListPanel; + private CalenderPanel calenderPanel; + private CalenderListPanel calenderListPanel; + private ModulesTakenListPanel modulesTakenListPanel; + private ModulesTakenListPanel modulesTakenListPanel2; + private ProfileMainScreen profileMainScreen; + private DiaryEntryMainPage diaryEntryMainPage; + private ModulesYetTaken modulesYetTaken; + @FXML private StackPane commandBoxPlaceholder; @@ -47,6 +64,60 @@ public class MainWindow extends UiPart { @FXML private StackPane resultDisplayPlaceholder; + @FXML + private StackPane notesListPanelPlaceholder; + + @FXML + private AnchorPane diaryListPanelPlaceholder; + + @FXML + private AnchorPane diaryFullViewPlaceholder; + + @FXML + private AnchorPane modulesTaken; + + @FXML + private AnchorPane profile; + + @FXML + private AnchorPane profileMainScreenplaceholder; + + @FXML + private AnchorPane taskLists; + + @FXML + private AnchorPane calenderPanelPlaceholder; + + @FXML + private AnchorPane deadlinePanelPlaceholder; + + @FXML + private AnchorPane modulesTakenBefore; + + @FXML + private AnchorPane modulesYetTakenplaceholder; + + @FXML + private SplitPane profileSplitPane; + + @FXML + private SplitPane calenderSplitPane; + + @FXML + private SplitPane profilePlaceholder; + + @FXML + private SplitPane diarySplitPane; + + @FXML + private SplitPane modPlanSplitPane; + + @FXML + private TabPane tabPane; + + @FXML + private Tab addBookTab; + @FXML private StackPane statusbarPlaceholder; @@ -75,6 +146,7 @@ private void setAccelerators() { /** * Sets the accelerator of a MenuItem. + * * @param keyCombination the KeyCombination value of the accelerator */ private void setAccelerator(MenuItem menuItem, KeyCombination keyCombination) { @@ -103,16 +175,68 @@ private void setAccelerator(MenuItem menuItem, KeyCombination keyCombination) { }); } + /** + * Helper method to build image to tabs + * + * @param imgPatch image path + * @return + */ + private static ImageView buildImage(String imgPatch) { + Image i = new Image(imgPatch); + ImageView imageView = new ImageView(); + //You can set width and height + imageView.setFitHeight(16); + imageView.setFitWidth(16); + imageView.setImage(i); + return imageView; + } + /** * Fills up all the placeholders of this window. */ void fillInnerParts() { + defaultSettings(); + personListPanel = new PersonListPanel(logic.getFilteredPersonList()); personListPanelPlaceholder.getChildren().add(personListPanel.getRoot()); + diaryListPanel = new DiaryListPanel(logic.getDiaryList()); + diaryListPanelPlaceholder.getChildren().add(diaryListPanel.getRoot()); + setAnchorPaneSize(diaryListPanelPlaceholder, diaryListPanelPlaceholder.getChildren().get(0)); + + + //diaryEntryMainPage = new DiaryEntryMainPage(); + //diaryFullViewPlaceholder.getChildren().add(diaryEntryMainPage.getRoot()); + //setAnchorPaneSize(diaryFullViewPlaceholder, diaryFullViewPlaceholder.getChildren().get(0)); + + notesListPanel = new NotesListPanel(logic.getFilesInFolderList()); + notesListPanelPlaceholder.getChildren().add(notesListPanel.getRoot()); + + calenderPanel = new CalenderPanel(); + calenderPanelPlaceholder.getChildren().add(calenderPanel.getRoot()); + setAnchorPaneSize(calenderPanelPlaceholder, calenderPanelPlaceholder.getChildren().get(0)); + + calenderListPanel = new CalenderListPanel(logic.getDeadlineTaskList()); + deadlinePanelPlaceholder.getChildren().add(calenderListPanel.getRoot()); + setAnchorPaneSize(deadlinePanelPlaceholder, deadlinePanelPlaceholder.getChildren().get(0)); + + + + profileMainScreen = new ProfileMainScreen(logic.getProfile()); + profileMainScreenplaceholder.getChildren().add(profileMainScreen.getRoot()); + setAnchorPaneSize(profile, profile.getChildren().get(0)); + resultDisplay = new ResultDisplay(); resultDisplayPlaceholder.getChildren().add(resultDisplay.getRoot()); + + modulesTakenListPanel = new ModulesTakenListPanel(logic.getModulesListTaken()); + modulesTakenListPanel2 = new ModulesTakenListPanel(logic.getModulesListTaken()); + modulesTakenBefore.getChildren().add(modulesTakenListPanel.getRoot()); + modulesTaken.getChildren().add(modulesTakenListPanel2.getRoot()); + setAnchorPaneSize(modulesTaken, modulesTaken.getChildren().get(0)); + setAnchorPaneSize(modulesTakenBefore, modulesTakenBefore.getChildren().get(0)); + StatusBarFooter statusBarFooter = new StatusBarFooter(logic.getAddressBookFilePath()); statusbarPlaceholder.getChildren().add(statusBarFooter.getRoot()); @@ -120,6 +244,40 @@ void fillInnerParts() { commandBoxPlaceholder.getChildren().add(commandBox.getRoot()); } + /** + * Default Settings. + */ + void defaultSettings() { + profileSplitPane.setDividerPositions(0.25f, 0.75f); + profileSplitPane.lookupAll(".split-pane-divider").stream() + .forEach(div -> div.setMouseTransparent(true)); + calenderSplitPane.setDividerPositions(0.25f, 0.75f); + calenderSplitPane.lookupAll(".split-pane-divider").stream() + .forEach(div -> div.setMouseTransparent(true)); + + profilePlaceholder.setDividerPositions(0.75f, 0.25f); + profilePlaceholder.lookupAll(".split-pane-divider").stream() + .forEach(div -> div.setMouseTransparent(true)); + + diarySplitPane.setDividerPositions(0.25f, 0.75f); + diarySplitPane.lookupAll(".split-pane-divider").stream() + .forEach(div -> div.setMouseTransparent(true)); + + modPlanSplitPane.setDividerPositions(0.50f, 0.50f); + modPlanSplitPane.lookupAll(".split-pane-divider").stream() + .forEach(div -> div.setMouseTransparent(true)); + + + } + + + void setAnchorPaneSize(AnchorPane anchorPane, Node node) { + AnchorPane.setTopAnchor(node, 0.0); + AnchorPane.setRightAnchor(node, 0.0); + AnchorPane.setLeftAnchor(node, 0.0); + AnchorPane.setBottomAnchor(node, 0.0); + } + /** * Sets the default size based on {@code guiSettings}. */ @@ -130,6 +288,7 @@ private void setWindowDefaultSize(GuiSettings guiSettings) { primaryStage.setX(guiSettings.getWindowCoordinates().getX()); primaryStage.setY(guiSettings.getWindowCoordinates().getY()); } + } /** @@ -183,6 +342,10 @@ private CommandResult executeCommand(String commandText) throws CommandException handleExit(); } + if (commandResult.isSwitchTab()) { + showSelectedTab(commandText); + } + return commandResult; } catch (CommandException | ParseException e) { logger.info("Invalid command: " + commandText); @@ -190,4 +353,37 @@ private CommandResult executeCommand(String commandText) throws CommandException throw e; } } + + + /** + * Shows the selected tab based on the command text. + * @param commandText the selected tab to be shown + */ + private void showSelectedTab(String commandText) { + + // diary = 0, modplan = 1, addbook = 2, calender = 3, notes = 4, profile = 5 + + String tabName = commandText.split(" ")[0]; + if (tabName.equals("notes")) { + + tabPane.getSelectionModel().select(4); + + } else if (tabName.equals("calender")) { + + tabPane.getSelectionModel().select(0); + } else if (tabName.equals("addressbook")) { + + tabPane.getSelectionModel().select(3); + } else if (tabName.equals("diary")) { + + tabPane.getSelectionModel().select(1); + } else if (tabName.equals("profile")) { + + tabPane.getSelectionModel().select(5); + } else if (tabName.equals("modplan")) { + + tabPane.getSelectionModel().select(2); + } + + } } diff --git a/src/main/java/seedu/address/ui/ModuleCard.java b/src/main/java/seedu/address/ui/ModuleCard.java new file mode 100644 index 00000000000..0ca25b7356c --- /dev/null +++ b/src/main/java/seedu/address/ui/ModuleCard.java @@ -0,0 +1,62 @@ +package seedu.address.ui; + +import javafx.fxml.FXML; +import javafx.scene.control.Label; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Region; +import seedu.address.model.nusmodule.NusModule; + +/** + * An UI component that displays information of a {@code Person}. + */ +public class ModuleCard extends UiPart { + + private static final String FXML = "ModuleTaken.fxml"; + + /** + * Note: Certain keywords such as "location" and "resources" are reserved keywords in JavaFX. + * As a consequence, UI elements' variable names cannot be set to such keywords + * or an exception will be thrown by JavaFX during runtime. + * + * @see The issue on AddressBook level 4 + */ + + public final NusModule module; + + @FXML + private HBox cardPane; + @FXML + private Label moduleName; + @FXML + private Label grade; + @FXML + private GridPane grid; + + public ModuleCard(NusModule module) { + super(FXML); + this.module = module; + moduleName.setText(module.getModuleCode().toString()); + + if (!module.getGrade().isEmpty()) { + grade.setText(module.getGrade().get().getText()); + } else { + grade.setText(""); + } + + } + + @Override + public boolean equals(Object other) { + // short circuit if same object + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof ModuleCard)) { + return false; + } + return false; + } +} diff --git a/src/main/java/seedu/address/ui/ModulesTakenListPanel.java b/src/main/java/seedu/address/ui/ModulesTakenListPanel.java new file mode 100644 index 00000000000..cdc0e3109ed --- /dev/null +++ b/src/main/java/seedu/address/ui/ModulesTakenListPanel.java @@ -0,0 +1,49 @@ +package seedu.address.ui; + +import java.util.logging.Logger; + +import javafx.collections.ObservableList; +import javafx.fxml.FXML; +import javafx.scene.control.ListCell; +import javafx.scene.control.ListView; +import javafx.scene.layout.Region; +import seedu.address.commons.core.LogsCenter; +import seedu.address.model.nusmodule.NusModule; + +/** + * Panel containing the list of persons. + */ +public class ModulesTakenListPanel extends UiPart { + private static final String FXML = "ModulesTakenListPanel.fxml"; + private final Logger logger = LogsCenter.getLogger(ModulesTakenListPanel.class); + + @FXML + private ListView modulesTaken; + + public ModulesTakenListPanel(ObservableList moduleList) { + super(FXML); + modulesTaken.setItems(moduleList); + modulesTaken.setCellFactory(listView -> new ModuleListViewCell()); + + } + + /** + * Custom {@code ListCell} that displays the graphics of a {@code Person} using a {@code PersonCard}. + */ + class ModuleListViewCell extends ListCell { + @Override + protected void updateItem(NusModule module, boolean empty) { + super.updateItem(module, empty); + + if (empty || module == null) { + setGraphic(null); + setText(null); + + } else { + setGraphic((new ModuleCard(module)).getRoot()); + } + + } + } + +} diff --git a/src/main/java/seedu/address/ui/ModulesYetTaken.java b/src/main/java/seedu/address/ui/ModulesYetTaken.java new file mode 100644 index 00000000000..7d7f8fa044e --- /dev/null +++ b/src/main/java/seedu/address/ui/ModulesYetTaken.java @@ -0,0 +1,50 @@ +package seedu.address.ui; + +import javafx.fxml.FXML; +import javafx.scene.control.Label; +import javafx.scene.layout.Region; +import seedu.address.model.ModuleBook; +import seedu.address.model.studentprofile.Profile; + +/** + * An UI component that displays information of a {@code Person}. + */ +public class ModulesYetTaken extends UiPart { + + private static final String FXML = "ModulesYetTaken.fxml"; + + /** + * Note: Certain keywords such as "location" and "resources" are reserved keywords in JavaFX. + * As a consequence, UI elements' variable names cannot be set to such keywords + * or an exception will be thrown by JavaFX during runtime. + * + * @see The issue on AddressBook level 4 + */ + + public final Profile student; + + @FXML + private Label modulesEligible; + + @FXML + private Label modulesUneligible; + + public ModulesYetTaken(String asd) { + super(FXML); + this.student = new Profile(new ModuleBook()); + } + + @Override + public boolean equals(Object other) { + // short circuit if same object + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof ModulesYetTaken)) { + return false; + } + return false; + } +} diff --git a/src/main/java/seedu/address/ui/NotesCard.java b/src/main/java/seedu/address/ui/NotesCard.java new file mode 100644 index 00000000000..67211ef9dc4 --- /dev/null +++ b/src/main/java/seedu/address/ui/NotesCard.java @@ -0,0 +1,53 @@ +package seedu.address.ui; + +import javafx.fxml.FXML; +import javafx.scene.control.Label; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Region; +import seedu.address.model.notes.Notes; + +/** + * An UI component that displays information of a {@code Person}. + */ +public class NotesCard extends UiPart { + + private static final String FXML = "NotesListCard.fxml"; + + /** + * Note: Certain keywords such as "location" and "resources" are reserved keywords in JavaFX. + * As a consequence, UI elements' variable names cannot be set to such keywords + * or an exception will be thrown by JavaFX during runtime. + * + * @see The issue on AddressBook level 4 + */ + + public final Notes note; + + @FXML + private HBox cardPane; + @FXML + private Label directory; + @FXML + private Label id; + + public NotesCard(Notes note, int displayedIndex) { + super(FXML); + this.note = note; + id.setText(displayedIndex + ". "); + directory.setText(note.getPath()); + } + + @Override + public boolean equals(Object other) { + // short circuit if same object + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof NotesCard)) { + return false; + } + return false; + } +} diff --git a/src/main/java/seedu/address/ui/NotesListPanel.java b/src/main/java/seedu/address/ui/NotesListPanel.java new file mode 100644 index 00000000000..c94cdf5d89b --- /dev/null +++ b/src/main/java/seedu/address/ui/NotesListPanel.java @@ -0,0 +1,59 @@ +package seedu.address.ui; + +import java.util.logging.Logger; + +import javafx.collections.ObservableList; +import javafx.fxml.FXML; +import javafx.scene.control.Label; +import javafx.scene.control.ListCell; +import javafx.scene.control.ListView; +import javafx.scene.layout.Region; +import javafx.scene.layout.StackPane; +import seedu.address.commons.core.LogsCenter; +import seedu.address.model.notes.Notes; + +/** + * Panel containing the list of Notes. + */ +public class NotesListPanel extends UiPart { + private static final String FXML = "NotesListPanel.fxml"; + private final Logger logger = LogsCenter.getLogger(NotesListPanel.class); + + @FXML + private ListView notesListView; + + @FXML + private Label currentDirectory; + + @FXML + private StackPane placeholder; + + public NotesListPanel(ObservableList notesList) { + super(FXML); + notesListView.setItems(notesList); + notesListView.setCellFactory(listView -> new NotesListViewCell()); + currentDirectory.setText("Current Directory: " + Notes.getCurrentDirectory()); + + } + /** + * Custom {@code ListCell} that displays the graphics of a {@code Notes} using a {@code NotesCard}. + */ + class NotesListViewCell extends ListCell { + @Override + protected void updateItem(Notes note, boolean empty) { + super.updateItem(note, empty); + currentDirectory.setText("Current Directory: " + Notes.getCurrentDirectory()); + + if (empty || note.getPath() == null) { + setGraphic(null); + setText(null); + } else { + setGraphic(new NotesCard(note, getIndex() + 1).getRoot()); + + + } + } + + } + +} diff --git a/src/main/java/seedu/address/ui/PersonCard.java b/src/main/java/seedu/address/ui/PersonCard.java index 0684b088868..0c1d88bc4c1 100644 --- a/src/main/java/seedu/address/ui/PersonCard.java +++ b/src/main/java/seedu/address/ui/PersonCard.java @@ -35,8 +35,6 @@ public class PersonCard extends UiPart { @FXML private Label phone; @FXML - private Label address; - @FXML private Label email; @FXML private FlowPane tags; @@ -47,7 +45,6 @@ public PersonCard(Person person, int displayedIndex) { id.setText(displayedIndex + ". "); name.setText(person.getName().fullName); phone.setText(person.getPhone().value); - address.setText(person.getAddress().value); email.setText(person.getEmail().value); person.getTags().stream() .sorted(Comparator.comparing(tag -> tag.tagName)) diff --git a/src/main/java/seedu/address/ui/ProfileMainScreen.java b/src/main/java/seedu/address/ui/ProfileMainScreen.java new file mode 100644 index 00000000000..226796f2af8 --- /dev/null +++ b/src/main/java/seedu/address/ui/ProfileMainScreen.java @@ -0,0 +1,57 @@ +package seedu.address.ui; + +import javafx.fxml.FXML; +import javafx.scene.control.Label; +import javafx.scene.layout.Region; +import javafx.scene.layout.StackPane; +import seedu.address.model.studentprofile.Profile; + +/** + * An UI component that displays information of a {@code Person}. + */ +public class ProfileMainScreen extends UiPart { + + private static final String FXML = "ProfileMainScreen.fxml"; + + /** + * Note: Certain keywords such as "location" and "resources" are reserved keywords in JavaFX. + * As a consequence, UI elements' variable names cannot be set to such keywords + * or an exception will be thrown by JavaFX during runtime. + * + * @see The issue on AddressBook level 4 + */ + + + @FXML + private StackPane profileMainScreenPanel; + @FXML + private Label name; + @FXML + private Label major; + @FXML + private Label currentCap; + + + + public ProfileMainScreen(Profile student) { + super(FXML); + + + currentCap.setText(student.getCap().get()); + + } + + @Override + public boolean equals(Object other) { + // short circuit if same object + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof ProfileMainScreen)) { + return false; + } + return false; + } +} diff --git a/src/main/resources/images/iconfinder_photo_370076.png b/src/main/resources/images/iconfinder_photo_370076.png new file mode 100644 index 00000000000..60705810fb6 Binary files /dev/null and b/src/main/resources/images/iconfinder_photo_370076.png differ diff --git a/src/main/resources/view/Calender.fxml b/src/main/resources/view/Calender.fxml new file mode 100644 index 00000000000..8d2e18d5d44 --- /dev/null +++ b/src/main/resources/view/Calender.fxml @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/view/CalenderDate.fxml b/src/main/resources/view/CalenderDate.fxml new file mode 100644 index 00000000000..ce517b6e974 --- /dev/null +++ b/src/main/resources/view/CalenderDate.fxml @@ -0,0 +1,12 @@ + + + + + + + + + + diff --git a/src/main/resources/view/CalenderDeadline.fxml b/src/main/resources/view/CalenderDeadline.fxml new file mode 100644 index 00000000000..c920c08e5f1 --- /dev/null +++ b/src/main/resources/view/CalenderDeadline.fxml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/view/CalenderListPanel.fxml b/src/main/resources/view/CalenderListPanel.fxml new file mode 100644 index 00000000000..fc4f6a4ae6f --- /dev/null +++ b/src/main/resources/view/CalenderListPanel.fxml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/main/resources/view/DarkTheme.css b/src/main/resources/view/DarkTheme.css index 36e6b001cd8..0329f6707e1 100644 --- a/src/main/resources/view/DarkTheme.css +++ b/src/main/resources/view/DarkTheme.css @@ -33,12 +33,62 @@ -fx-padding: 0 0 0 1; } -.tab-pane .tab-header-area { +#diaryTab { + -font-size: 100; +} + +.tab-pane .tab-header-area .tab-header-background { -fx-padding: 0 0 0 0; -fx-min-height: 0; -fx-max-height: 0; } +/* ================ For tabs ================*/ +.tab-pane .tab-header-area .tab-header-background { + -fx-opacity: 0; +} + +.tab-pane +{ + -fx-tab-min-width:90px; + -fx-background-color: #3c3c3c; + /* change the colour here if you want to change the colour for the tabpane*/ + +} + +#month .content { + -fx-text-fill: white; + } + +.tab{ + -fx-background-insets: 0 1 0 1,0,0; +} +.tab-pane .tab +{ + -fx-background-color: #3c3c3c; + +} + +.tab-pane .tab:selected +{ + -fx-background-color: #3c3c3c; +} + +.tab .tab-label { + -fx-alignment: CENTER; + -fx-text-fill: #828282; + -fx-font-size: 20px; + -fx-font-weight: bold; +} + +.tab:selected .tab-label { + -fx-alignment: CENTER; + -fx-text-fill: #ffb385; +} + + + + .table-view { -fx-base: #1d1d1d; -fx-control-inner-background: #1d1d1d; @@ -81,6 +131,11 @@ -fx-border-color: transparent transparent transparent #4d4d4d; } +.split-pane:vertical .split-pane-divider { + -fx-background-color: derive(#1d1d1d, 20%); + -fx-border-color: transparent transparent transparent #4d4d4d; +} + .split-pane { -fx-border-radius: 1; -fx-border-width: 1; @@ -350,3 +405,29 @@ -fx-background-radius: 2; -fx-font-size: 11; } + +#calenderDate .label { + -fx-font-size: 11pt; + -fx-font-family: "Segoe UI Semibold"; + -fx-text-fill: #fb7b6b; + -fx-opacity: 0.9; + +} + +#moduleName .label .text { + -fx-font-sze: 100pt; +} + +.text-area { + text-area-background: #383838; + -fx-background-color: #383838; + -fx-border-color: #383838; +} + +.text-area .content { + -fx-background-color: text-area-background ; + -fx-background-radius: 0 ; + +} + + diff --git a/src/main/resources/view/DiaryListCard.fxml b/src/main/resources/view/DiaryListCard.fxml new file mode 100644 index 00000000000..412b4eba367 --- /dev/null +++ b/src/main/resources/view/DiaryListCard.fxml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/view/DiaryListPanel.fxml b/src/main/resources/view/DiaryListPanel.fxml new file mode 100644 index 00000000000..8982fcf9dbd --- /dev/null +++ b/src/main/resources/view/DiaryListPanel.fxml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/main/resources/view/MainWindow.fxml b/src/main/resources/view/MainWindow.fxml index a431648f6c0..fb513196258 100644 --- a/src/main/resources/view/MainWindow.fxml +++ b/src/main/resources/view/MainWindow.fxml @@ -7,12 +7,15 @@ + + + + - + @@ -23,7 +26,7 @@ - + @@ -32,28 +35,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - - - - - - - - + diff --git a/src/main/resources/view/ModuleTaken.fxml b/src/main/resources/view/ModuleTaken.fxml new file mode 100644 index 00000000000..eac1ec30934 --- /dev/null +++ b/src/main/resources/view/ModuleTaken.fxml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/view/ModulesTakenListPanel.fxml b/src/main/resources/view/ModulesTakenListPanel.fxml new file mode 100644 index 00000000000..30133cfab40 --- /dev/null +++ b/src/main/resources/view/ModulesTakenListPanel.fxml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/main/resources/view/ModulesYetTaken.fxml b/src/main/resources/view/ModulesYetTaken.fxml new file mode 100644 index 00000000000..e646020ac51 --- /dev/null +++ b/src/main/resources/view/ModulesYetTaken.fxml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + diff --git a/src/main/resources/view/NotesListCard.fxml b/src/main/resources/view/NotesListCard.fxml new file mode 100644 index 00000000000..b8b3c41d5d8 --- /dev/null +++ b/src/main/resources/view/NotesListCard.fxml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/view/NotesListPanel.fxml b/src/main/resources/view/NotesListPanel.fxml new file mode 100644 index 00000000000..05deec12ae1 --- /dev/null +++ b/src/main/resources/view/NotesListPanel.fxml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + diff --git a/src/main/resources/view/PersonListCard.fxml b/src/main/resources/view/PersonListCard.fxml index f08ea32ad55..2a8da41fae8 100644 --- a/src/main/resources/view/PersonListCard.fxml +++ b/src/main/resources/view/PersonListCard.fxml @@ -29,7 +29,6 @@ diff --git a/src/main/resources/view/Profile.fxml b/src/main/resources/view/Profile.fxml new file mode 100644 index 00000000000..a1e11222074 --- /dev/null +++ b/src/main/resources/view/Profile.fxml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/view/ProfileMainScreen.fxml b/src/main/resources/view/ProfileMainScreen.fxml new file mode 100644 index 00000000000..07661a517e8 --- /dev/null +++ b/src/main/resources/view/ProfileMainScreen.fxml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/view/ProfilePanel.fxml b/src/main/resources/view/ProfilePanel.fxml new file mode 100644 index 00000000000..67cd6739774 --- /dev/null +++ b/src/main/resources/view/ProfilePanel.fxml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/view/diaryEntryMainPage.fxml b/src/main/resources/view/diaryEntryMainPage.fxml new file mode 100644 index 00000000000..a3164ffc46b --- /dev/null +++ b/src/main/resources/view/diaryEntryMainPage.fxml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + +