Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Section 3.2 wording and UML #177

Merged
merged 2 commits into from Oct 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
75 changes: 43 additions & 32 deletions docs/DeveloperGuide.adoc
Expand Up @@ -480,10 +480,16 @@ convenient add, delete and check operations on the user's course list.

The Course Planner feature closely follows the extendable OOP solution
implemented within Jarvis. Within `model`, the `CoursePlanner` class
manages all aspects related to this feature. The course list of the user is
stored internally using a `UniqueCourseList` object, providing an abstraction
with `add`, `delete` and `getCourseList` operations that are called by
`CoursePlanner`.
manages all aspects related to this feature.

The list of courses of the user is stored internally using a `UniqueCourseList`
object, providing an abstraction with `add`, `delete` and `getCourseList`
operations that are called by `CoursePlanner`.

The `String` that is displayed to the user within a the UI text box is
abstracted within a class called `CourseText`. This is a simple class that
abstracts some operations of operations on a `String`, such as setting,
getting, printing to a displayable form, etc.

* `Model#getCoursePlanner()` - Gets the `CoursePlanner` instance
* `Model#lookUpCourse(Course)` - Looks up a course's information
Expand All @@ -495,21 +501,30 @@ with `add`, `delete` and `getCourseList` operations that are called by
* `Model#getUnfilteredCourseList()` - Returns an `ObservableList` containing
the user's list of courses
* `Model#getCourseText()` - Returns a `CourseText` object
* `Model#setCourseText(String)` - Sets the `String` displayed by the
`CourseText` object.

.Course Model Class Diagram
image::ModelCoursePlannerClassDiagram.png[]

===== Course Datasets

Course data-sets are taken directly from the {nus-mods-api}[NUSMods API]. These
data-sets are stored using the `.json` file format on NUSMod's API. Therefore,
all course data within Jarvis is read directly from `.json` files using the
Jackson JSON API.
data-sets are stored using the `.json` file format on NUSMod's API. Since
Jarvis already heavily uses the Jackson JSON API, we have opted to store
all course data within Jarvis in their original form. Therefore, all data
is read directly from `.json` files.

[NOTE]
NUSMods is a popular website officially affiliated with NUS, where
students are able to look up information about courses and plan their
school timetable. This makes its data-set a reliable source of course
information.

Each course, and their data, are given its own file. These files are laid out
in `/modinfo` within `/resources` to be easily accessible by the program.

A sample `.json` is given below for a fictional course `AB1234`.
A sample, valid `AB1234.json` is given below for a fictional course `AB1234`.

[JSON]
----
Expand Down Expand Up @@ -551,28 +566,23 @@ datafiles downloaded from NUSMods, all at least have these attributes. The
other three: `fulfillRequirements`, `preclusion` and `prereqTree` are
optional, nullable attributes.

[NOTE]
NUSMods is a popular website officially affiliated with NUS, where
students are able to look up information about courses and plan their
school timetable. This makes its data-set a reliable source of course
information.

==== And-Or Tree

===== Overview

The `AndOrTree<R>` is a tree data structure served by the `util/andor`
package that provides an abstraction for processing the prerequisite tree.
The prerequisite tree (henceforth referred to as `prereqTree`) is an attribute
of a `Course` that is available in the NUSMod's course data-set.
of a `Course` that is available in the NUSMod's course data-set, the data
comes in the form of a `String` and will be covered shortly.

===== The `AndOrTree` Class

The following are `public` methods in `AndOrTree`.

* `buildTree(String, Function<String, ? extends R>)`
+
Builds a tree from the given jsonString. `Function` is a mapper function
Builds a tree from the given jsonString. `Function` is a mapper
that processes a `String` and returns a value of type `R`, where `R` is the
type of data stored by each node in the tree.

Expand All @@ -591,7 +601,7 @@ reflected in the class' lack of mutator methods.
===== The `AndOrNode` Class

Each node in the tree of type `R` is represented by an `AndOrNode<R>`. Every
node can either of these types:
node can exist as either of these types:

1. `AND`
+
Expand All @@ -608,13 +618,13 @@ children of this node
Any element in a `Collection<R>` must match the data stored in
this node

The following class diagram demonstrates the structure of the `AndOrNode`
`abstract class` and its sub-classes.
The following class diagram demonstrates the structure of the `abstract class`
`AndOrNode` class and its sub-classes.

.AndOrNode Inheritance Diagram
image::AndOrNodeInheritanceClassDiagram.png[800, 600]

Using this format, `AndOrNode#createNode(T,String)` is able to instantiate
Using this format, `AndOrNode#createNode(T,String)` is able to construct
all instances of its sub-class, thus the caller will not need to know the
different types of nodes there are.

Expand Down Expand Up @@ -651,9 +661,10 @@ To take AB1234, you require...
This means that to take the fictional course `AB1234`, a user would have to
complete `EF3333`, **and** either `CD1111` or `XY2222`.

The `buildTree()` method takes in the `json` string as an input. A root
`JsonNode` object is created, and the tree is built recursively from
the root. The sequence diagram of the tree building process is shown below:
The `buildTree()` method takes in the `json` string as an input. The
Jackson API uses this string to create a root `JsonNode` object, and the tree
is built recursively from the root. The sequence diagram of the tree building
process is shown below:

.buildTree() Sequence Diagram
image::AndOrSequenceDiagramSimplified.png[]
Expand All @@ -669,7 +680,7 @@ of the tree.

===== Aspect: Storing of Course data-sets

* **Alternative 1**: Storing each course in one, large JSON file
* **Alternative 1**: Storing every course in a single, large JSON file
** **Pros:**
+
Easier to manage. Every course can be found in a single file. The code need
Expand Down Expand Up @@ -735,22 +746,22 @@ non-extendable.
This makes the tree reusable in the future. The tree will also be able to
store any data-type which allows for easier unit testing, since it won't be
dependent on the correctness of the fixed data-type (`Course` in this
instance), and instead well-tested libraries such as Java's `String` API can
instance). Instead well-tested libraries such as Java's `String` API can
be used to test the class instead.

** **Cons:**
+
Due to how the tree is built (i.e from a json string), a
**mapper function** must be passed into the `buildTree()` method to process the
string in each node to the generic type of the tree. The function should be of
a type `Function<String, ? extends R>`, for a tree of type `R`.
Due to how the tree is built (i.e from a json string), a **mapper function**
must be passed into the `buildTree()` method to process the string in each
node to the generic type of the tree. The function should be of a type
`Function<String, ? extends R>`, for a tree of type `R`.

Due to its benefits far outweighing its disadvantages, we picked out
current choice. While extendability and resusability of the class is a nice
bonus, the decrease in coupling and increase in testability was the deciding
factor in choosing between these two approaches. Furthermore, behaviour of the
class can be easily extended by either inheritance, or overloading of the
`buildTree()` method.
factor in choosing between these two approaches. Furthermore, behavior of
the building of the tree can be easily extended by either inheritance, or
overloading of the `buildTree()` method.

=== Finance Tracker feature

Expand Down
6 changes: 3 additions & 3 deletions docs/diagrams/AndOrSequenceDiagramSimplified.puml
Expand Up @@ -17,23 +17,23 @@ end box
create AndNode
AndOrNode -> AndNode
return newNode
else isOrNode
else else
create OrNode
AndOrNode -> OrNode
return newNode
end
return newNode


loop for child in jsonNode
loop child in jsonNode
AndOrTree -> AndOrTree : buildTreeHelper(child, newNode)
return
|||
end

else isArray

loop for child in array
loop child in array
AndOrTree -> AndOrTree : buildTreeHelper(child, currNode)
return
|||
Expand Down
Binary file modified docs/images/AndOrSequenceDiagramSimplified.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.