__  __           _   __  __ 
|  \/  |         | | |  \/  |
| \  / | ___   __| | | \  / | __ _ _ __
| |\/| |/ _ \ / _  | | |\/| |/ _  |  _ \
| |  | | (_) | (_| | | |  | | (_| | | | |
|_|  |_|\___/ \__'_| |_|  |_|\__'_|_| |_|
ModMan, short for Module Manager, is a desktop app designed to help Teaching Assistants (TAs) manage their module(s). It is optimized for use via a Command Line Interface (CLI). ModMan helps to track module details as well as students’ progress and data, all in one platform. It can also perform autograding for MCQ assignments.
This developer guide details how ModMan is designed, implemented and tested. Readers can find out more about the overall architecture of ModMan, and also the implementation behind various functionalities. Technically inclined readers may wish to use the developer guide and further implement features or customise ModMan for their own use!
The Developer Guide has been split into clear sections to allow readers to quickly navigate to their desired information.
You may follow this Setting Up guide and get started as a developer! This guide helps you import ModMan onto IntelliJ IDEA, but feel free to use your preferred IDE.
ModMan.java file and select Run Modman.main(). You can also test some of ModMan's commands.For readers who are not familiar with the commands of ModMan, they can access the User Guide here.
This section describes the four architecture components of ModMan, as well as the connections between them. The overall architecture of ModMan is explained first, before diving into each of the architecture components.

The Architecture Design given above explains the high-level design of ModMan. Given below is a quick overview of each component.
Modman is the main class of the application, and handles the app launch,
initializing the appropriate classes to be used. 
The rest of the app consists of four components:
How the four architecture components interact with each other and the ModMan class
The Sequence diagram below shows the interaction between components for when the user issues the command add module CS2113T

The sections below give more details of each component.

Logic uses the Parser class to parse the user command.Command object which is executed in Modman.Data and Storage components. For example, the AddModuleCommand adds a new Module object in Data.Command object can also instruct the Ui to list and display information to the user.Given below is the sequence diagram for creating the corresponding Command object from the user input via Parser. 
The sequence diagram also acts as a reference frame for getCommand which is common across most Command objects.

If a Command object does not use the reference frame, another sequence diagram would be used to describe how the Command object was created.

The UI Component consists of one class - Ui which provides all the functions
required to print different kinds of messages on the console.
Ui is class with a Scanner object that reads input from console.Modman has Ui object as an attribute which is instantiated
when we enter the program.Ui object reads input from screen and returns it which will then be passed to the Parser so that it can
parse the command.Command is an abstract class that has multiple derived command classes that implement
the abstract method execute.execute() method runs. It accepts Ui object as a parameter and calls the relevant Ui methods
that prints the specific messages.Ui method has different parameters such as Lesson, Student, Assignment, Answer, Module objects
which form dependencies between Ui and these classes.
For the Storage functionality of the application, I have added a new Storable interface that is implemented by the three main entities of the app: Assignment, Student and Lesson. The Storable interface mandates the user to write a toStorage() method in order to be stored in the database. The toStorage() method converts all information of an object into a String format to be appended onto the database.
The implementation of the Storable interface helps to decouple the Storage class from all classes that require storing of their instances into the database. This is because by implementing Storable, all Storage class needs to do to store an object information into the database would be to interact with the Storable interface via the toStorage() method.
Given below is the Class Diagram for the Storage class. The storage class interacts with the Database file, ensuring that user's data will be saved at the end of each session and loaded up upon the user's next visit. 

The Storage class is used to interact with the database.txt file. The loadData() function of the Storage object will be called at the start of the program and saveData() at the end of the program.
loadData():
The loadData() method is illustrated in the sequence diagram below.

As can be seen, multiple loops are required to load all the information of each object instance from the Database so that the user's data can be retrieved fully.
saveData():
When the saveData() method is called, the toStorage() method of each object instance implementing the Storable interface will be called. The return string of each toStorage() method will then be appended onto the database.
loadAnswer():
For Autograding purpose, the Storage class is required to retrieve the answers and students' scripts from the respective .txt files that they were stored in. The loadAnswer() method in the Storage class fulfils this. The Sequence Diagram below exhibits the behaviour of the loadAnswer() method.

loadScript():
Similarly to loadAnswer() as shown in the above Sequence Diagram, the loadScript() method follows the same logic in retrieving each student's script from their input file, scanning them as Data and allowing us to perform Autograding.
The database should not be tampered with by the user. If the user opens up Database.txt and edits its contents, the data will likely be corrupted. In such cases, the program will fail upon starting, prompting the user to delete Database.txt before running the program again.
The figure below shows the classes in ModMan that tracks module information data.

The Data,
Module objects that represents the modules.Module contains the details of Lesson and Student objects which implements the Storable interface, as well as abstract Assignment objects which implement the Storable and Comparable interfaces.This subsection provides details on the implementation of the various commands that modify the Assignment object.
There are 4 attributes of the Assignment object in which the User can interact with:
LocalDate representing the date which the assignment should be graded by.float of the percentage of the overall grade which the assignment carries in the module.HashMap<String, Float> of the students' grades for the assignment, where the key is the Student/Matric Number and the value is the Grade out of 100%.String representing comments for particular questions and/or the overall assignment.SetAssignmentDeadlineCommandThe SetAssignmentDeadlineCommand is used to set or update the deadline which the Assignment has to be graded by.
The deadline can then be used to sort the assignments based on the urgency of the grading.
Given below is the sequence diagram for the SetAssignmentDeadlineCommand:

deadline passed into the setDeadline() function is of type LocalDate
 | 
|---|
Implementation considerations for using LocalDate for deadline attribute in Assignment:
LocalDate is an immutable class that represents dates with a default format of yyyy-MM-ddLocalDate allows for standardisation of the format and representation of deadlinesLocalDate has a built-in compareTo() method that allows us to compare and order two datesLocalDate allows us to easily sort Assignment objects by their deadline attributeSetAssignmentGradeCommandThe SetAssignmentGradeCommand is used to set or update the grade of the Assignment for a Student. This can be used to track individual grades for each student.
Given below is the sequence diagram for the SetAssignmentGradeCommand:

Implementation considerations for using HashMap<String, Float> to store students' grades:
HashMap allows for easy storage of "key/value" pairs, with the studentName and grade corresponding to key and value respectivelyHashMap has worst case get/put complexity of O(logn), which offers decent time complexity performance when setting and retrieving the grade
HashMap may have even better performance with a good hashThe SortAssignmentByDeadlineCommand is used to reorder the ArrayList of Assignment objects stored in the current Module. 
The Assignment objects will be sorted based on their deadline attribute, which is of type LocalDate.
The deadline of an Assignment object can be null, in which case the Assignment will be sorted after other Assignment objects with valid LocalDate deadlines.
The sorting is also stable, and will retain the initial order of when the Assignment was added to the Module. 
The code snippet for the compareTo() function which allows Assignment to implement the Comparable interface is as follows:
    @Override
    public int compareTo(Assignment other) {
        if (this.getDeadline() == null && other.getDeadline() == null) {
            return 0;
        } else if (this.getDeadline() == null) {
            return 1;
        } else if (other.getDeadline() == null) {
            return -1;
        }
        return this.getDeadline().compareTo(other.getDeadline());
    }
Modifying the compareTo() function allows you to easily change the natural ordering of the objects of the Assignment Class.  Other attributes can also be added to Assignmentobjects in the future to be used for comparing. | 
|---|
Given below is the sequence diagram for the SortAssignmentsByDeadlineCommand:

The AutogradeAssignmentCommand is used to grade all current students' scripts found in the scripts directory. 
The grades for each student will also be automatically saved and updated in the Assignment.
Autograding also keeps track of which students in the current student list have not submitted their assignment. 
Currently, only the McqAssignment and ShortAnswerAssignment implement the Autogradableinterface | 
|---|
The sequence in which Autograding is carried out is as follows:
Module is retrieved from Data, followed by the Assignment we wish to autograde and the current students in that Module.Answer for the Assignment is read from the corresponding text file in the answers directory and is set or updated in the Assignment.Assignment is of type McqAssignment or ShortAnswerAssignment, their respective autogradeAssignment method will be invoked. Else, the NotAutogradableException() will be thrown.autogradeAssignment method, for each Student in the student list:
4.1. If the script for the Student can be found in the scripts directory, the script is loaded and compared with the Answer. The grade for the Student is calculated and saved in the HashMap<String, Float> of students' grades in Assignment.
4.2.  Else, grading for the Student is skipped and the loop continues.HashMap<String, Float> of students' grades, if a Student's grade is null for the Assignment, they are added to the ungraded list.Ui.The aforementioned sequence of events is also shown in the following sequence diagrams:

 Reference frames for the AutogradeAssignmentCommand sequence diagram:
getCommand reference frame can be found in the Logic Component section.loadAnswer and loadScript reference frames can be found in the Storage Component section.autogradeMcq and autogradeShortAnswer reference frames are similar, only autogradeMcq will be shown below. More details about the difference between autograding for Mcq and Short Answer will be discussed below as well.Reference frame for autogradeMcq:

Implementation Considerations in Autograding:
Updating of Answer Key 
Assignment every time an Answer is read from the text file in the answers directory, even if there was an existing Answer saved. Student will also be updated in the HashMap accordingly.Mcq vs Short Answer 
McqAssignments is limited to the options A through E and 1 to 5 while the answer key for ShortAnswerAssignments has no restrictions.Assignment, it was redundant to convert the answers read from the answers directory to an enum
just to convert it back to a String to be compared with the student's script.Answer before autograding. If there is an invalid option, the InvalidMcqOption exception will be thrown.Autogradable Interface 
McqAssignment and ShortAnswerAssignment implement the Autogradable Interface.The Class Diagram for Assignment given below shows all the types of assignments that inherit from Assignment and the ones which implement the Autogradable Interface:

Autograding assignments also generates statistics on how students performed for each question in the assignment.
The AddTimetableCommand is used to add a Lesson to the timetable for the Module selected.
Given below is the sequence diagram for the AddTimetableCommand:

- startTime and endTime passed into the Lesson constructor is of type LocalTime- day is of enumeration type Day
 | 
|---|
Product scope provides you an insight into the value of ModMan, and its benefits for target users.
To keep track of all information pertaining to a module, teaching assistants (at NUS) have to make use of multiple platforms:
With the help of ModMan, users will be able to add, edit, and store all information on one platform, simplifying the process. In addition, features such as autograding and saving comments for assignments will free up time, allowing TAs to focus on teaching!
| Version | As a ... | I want to ... | So that I can ... | 
|---|---|---|---|
| v1.0 | Teaching Assistant | add modules that I am teaching | keep track of the information for each of my modules | 
| v1.0 | Teaching Assistant | add the time and day of a module's lesson | keep track of my teaching timetable | 
| v1.0 | Teaching Assistant | add my student's details | contact them if they need help | 
| v1.0 | Teaching Assistant | add upcoming module assignments | manage and plan out my schedule easily | 
| v2.0 | Teaching Assistant | view my students' grades for each assignment | focus on the students who are not doing well | 
| v2.0 | Teaching Assistant | edit a module's lesson information | keep track of changes in lesson schedule | 
| v2.0 | Teaching Assistant | sort out assignments by deadline | keep track of the more urgent assignments | 
| v2.0 | Teaching Assistant | obtain an overview of information related to a module | easily view my teaching timetable, upcoming assignments and students | 
| v2.0 | Teaching Assistant | auto-grade assignments | save time while marking and focus, instead, on teaching! | 
| v2.0 | Teaching Assistant | add comments to assignments | refer back to them when other students make the same mistake | 
Java 11 installed.This section provides instructions for testing ModMan manually. You may wish to refer to ModMan's User Guide to find out about the various commands, and their input format.
ModMan.jar release from here..jar file.java -jar {filename}.jar java -jar ModMan.jar
Ensure you have added a few assignments to be sorted.
Test Case 1: Assignments with different deadlines Expected: Assignments will be sorted with the more urgent deadlines near the top of the list.
Test Case 2: Assignments with the same deadline Expected: Sorting assignments is stable. Assignments with the same deadline will retain the initial order of when they were added to the module.
Test Case 3: Assignments with no deadline Expected: Assignments with no deadline will be sorted after other assignments with valid deadlines. Two assignments both without deadlines will also retain their initial order.
Here are some steps you can take to begin testing the autograde feature:
Test Case 1: Answer key question numbers are not in sequential order. Expected: Error message regarding misalignment of question numbers shown.
Test Case 2: Answer key contains non integer question numbers. Expected: Error message regarding invalid question number shown
Test Case 3: Number of questions in answer key and script are different. Expected: Error message regarding misalignment of question numbers shown.
Test Case 4: MCQ assignment has invalid MCQ option. Expected: Error message regarding invalid MCQ option shown.
For more test cases, refer to User Guide section 2.23, 2.25 and 2.26