- Acknowledgements
- Design
- Implementation
- Appendix A: Product Scope
- Appendix B: User Stories
- Appendix C: Non-Functional Requirements
- Appendix D: Glossary
- Appendix E: Instructions for Manual Testing
This project was inspired by our experiences using the Canvas learning management system. While Canvas serves large educational environments well, we envisioned a simpler, offline tool tailored for small classes that prioritizes essential features like grade tracking, student management, and assessment organization. Thus, TutorLink was born.
The design and feature set of TutorLink were developed from scratch, drawing inspiration from the need for a lightweight, offline solution for managing class assignments and reducing administrative overhead in small class environments. No code or external sources were directly referenced or reused in the development of TutorLink.
The high-level design of TutorLink is as depicted in the following Architecture Diagram:
Main Components of the Architecture
TutorLink
: Main class that serves as the main entry point of the application.
- At app launch, TutorLink initializes components (
Parser
,Ui
,Storage
,AppState
). - On app shutdown, it shuts down the components and invokes cleanup methods.
The key classes providing functionality to TutorLink are:
AppState
: Stores global variables/resources required by TutorLink at run time.Ui
: Collects data (via Strings sent via CLI) from the user and relays information to the user (via printing back to the CLI).Parser
: Interprets the raw data from the user; applies data validation and handles necessary exceptions.Storage
: Handles the loading and storage of data to be retained even after TutorLink is shut down.CommandResult
: Represents the result of user input.
All commands follow the sequence as described in the diagram below:
Where ref
frame is a placeholder for each command's specific operations:
During the setup phase of TutorLink
, the following operations are performed:
StudentStorage
,ComponentStorage
andGradeStorage
objects are instantiatedArrayList
of Student, Component and Grade are obtained from the respective Storage classesAppState
object is instantiated, passing theArrayList
s in step 3Ui
displays welcome message
The specific implementation of noteworthy operations are presented below:
The StudentStorage
, GradeStorage
and ComponentStorage
classes implement the feature to load data from the
data .txt
files into their respective List objects at the start of the program.
The load list methods for the Storage classes have largely similar logic flows. To avoid repetition,
only the implementation for GradeStorage
is shown.
The following section and sequence diagram elaborate on the implementation of the loadGradeList
method in GradeStorage
,
as referenced in Setup:
- TutorLink constructs a new
GradeStorage
. GradeStorage
creates a newArrayList
ofString
s for discarded entries.- TutorLink calls
loadGradeList
. GradeStorage
creates a newArrayList
ofGrade
s.- While there are next lines in the data file:
- FileScanner returns the current file line as a String and moves to the next file line.
GradeStorage
calls itsgetGradeFromFileLine
method with the file line.- If the file line references a valid
Component
and a validStudent
, aGrade
is returned and added to theArrayList
. - If not (e.g. file line was corrupted), the file line is added to
discardedEntries
, and the loop continues to the next iteration.
- The
ArrayList
ofGrade
s is returned to TutorLink. - TutorLink calls
getDiscardedEntries
, and the discarded entries are displayed by UI.
The AddStudentCommand
, DeleteStudentCommand
, AddComponentCommand
and DeleteComponentCommand
handles the addition and deletion of Student
and Component
within the TutorLink application, respectively.
Each command validates user input to ensure accuracy and consistency before making changes, preserving data integrity. Students are stored as Student
objects within a StudentList
. Components are stored as Component
objects within a ComponentList
.
The flow of logic for both Student
and Component
commands can be summarized as follows:
-
AddStudentCommand.execute(AppState appState, HashMap<String, String> arguments)
: Adds a student to the application by performing the following steps:- Retrieves and validates the matriculation number and name from
arguments
, throwing relevant exception in the case of failure. - Creates and adds a
Student
object toStudentList
inAppState
- Return
CommandResult
that contains the result of the Add/Delete operation.
- Retrieves and validates the matriculation number and name from
The following sequence diagrams depict the exact steps involved in the AddStudentCommand
:
DeleteStudentCommand.execute(AppState appState, HashMap<String, String> arguments)
: Removes a student via the following steps:- Retrieves and validates the matriculation number from arguments, throwing
IllegalValueException
exception if matriculation number is null. - Searches for and deletes the student from
AppState
. ThrowsStudentNotFoundException
if no student matching the matriculation number is found. - Searches for and deletes
Grade
objects inGradeList
containing a student matching the matriculation number.
- Retrieves and validates the matriculation number from arguments, throwing
Note: Step (iii) is performed because a Grade
object is only well-defined when there are both Student
and Component
objects to be refrenced by Grade
,
whenever a Student
or Component
object is deleted, the corresponding Grade
object is queried and then deleted as well.
The logic for AddComponentCommand
is very similar (replacing matriculation number
with component description
and is therefore not depicted.
The FindStudentCommand
searches for and returns matching Students
stored in the TutorLink application.
FindStudentCommand
can accept either matric number
or name
as argument. If matric number
is supplied, the query
will be executed using matric number
, else name
will be used for the search query.
The flow of logic for FindStudentCommand
can be summarized as follows:
-
FindStudentCommand.execute(AppState appState, HashMap<String, String> arguments)
: Adds a student to the application by performing the following steps:- Retrieves and validates the matriculation number/name from
arguments
, throwing relevant exception in the case of failure. - Calls
AppState.findStudentByMatricNumber
andAppState.findStudentByName
respectively to fetch list ofStudent
objects matching the suppliedmatric number
/name
. - Return
CommandResult
that contains the matchingStudents
.
- Retrieves and validates the matriculation number/name from
The following sequence diagrams depict the exact steps involved in the FindStudentCommand
:
The AddGradeCommand
and DeleteGradeCommand
classes handle the addition and deletion of grades for students within the TutorLink application. Each command validates user input to ensure accuracy and consistency before making changes, preserving data integrity. Grades are stored as Grade
objects within a GradeList
.
AddGradeCommand.execute(AppState appState, HashMap<String, String> arguments)
: Adds a grade to a student by performing the following steps:- Retrieves and validates the matric number, component description, and score from
arguments
. - Checks that the specified component and student exist.
- Ensures the score is within the allowable range for the specified component.
- Creates a new
Grade
object and adds it to theGradeList
inAppState
.
- Retrieves and validates the matric number, component description, and score from
The sequence diagram of the AddGradeCommand is shown below.
DeleteGradeCommand.execute(AppState appState, HashMap<String, String> arguments)
: Removes a grade from a student by performing these steps:- Retrieves and validates the matric number and component description from
arguments
. - Confirms the existence of the specified component and student.
- Locates and deletes the
Grade
object from theGradeList
inAppState
.
- Retrieves and validates the matric number and component description from
The sequence diagram of the DeleteGradeCommand is shown below.
The target users for TutorLink are professors at NUS who manage small, single-staffed classes. These professors typically have strong technical expertise but are often overwhelmed by time-consuming administrative tasks that detract from their ability to focus on teaching and curriculum development.
- Time-Constrained: Professors have limited time for lesson preparation due to the administrative burden of managing grades, assignments, and attendance.
- Technologically Savvy: While proficient in using educational platforms, they often find existing tools slow, overly complex, or requiring constant internet connectivity.
- Desire for Simplicity: They prefer tools that are easy to use, automate repetitive tasks, and function offline, allowing them to streamline administrative work without unnecessary complexity.
The target user values efficiency, reliability, and simplicity, seeking a solution that reduces administrative workload and enables them to focus more on the core aspects of teaching.
TutorLink solves the problem of administrative overload by automating routine tasks such as managing assignments, and monitoring student performance. Professors often struggle with time-consuming admin work that takes away from their primary focus: teaching and preparing lessons.
By offering an offline, lightweight solution that simplifies these processes, TutorLink helps professors:
- Save time by automating tedious administrative tasks.
- Access important information quickly, without needing an internet connection.
- Focus on teaching and lesson development instead of being bogged down by admin work.
In contrast to bloated systems, TutorLink is designed to be fast, simple, and effective—freeing up valuable time and enhancing teaching efficiency.
Priorities: High (must have) - * * *, Medium (nice to have) - * *, Low (unlikely to have) - *
Priority | As a ... | I want to ... | So that I can ... |
---|---|---|---|
* * * | new user | see usage instructions | refer to them when I forget how to use the application |
* * * | professor | add a student | start to record his grades after he enrolls in the class |
* * * | professor | check the list of students | see how many students are in my class |
* * * | professor | find a student | check whether the student is enrolled in the class without having to go through the entire list |
* * * | professor | delete a student | remove the student if he decides to drop out of the class |
* * * | professor | add a grade of an individual student | record his/her grade after marking |
* * * | professor | check the grade of an individual student | see how the student is doing |
* * * | professor | delete a grade of an individual student | remove incorrectly inputted grades |
- Performance: The system should respond to any command within a few seconds
- Reliability: The system should not lose any user data even if it crashes unexpectedly
- Usability: A new user should be able to use basic features without confusion, upon consulting the User Guide
- Compatibility: The system should work on any mainstream OS (Windows, macOS, Linux) that has Java 17 installed
- Offline Capability: Since the system is designed to operate offline, it should not require internet connectivity for any core features, supporting a fully local data storage solution.
- Maintainability: The system should be able to export all data in a human-readable format for backup purposes
-
AppState - A class in TutorLink responsible for storing and managing global application data, such as lists of students, grades, and components, needed at runtime.
-
CLI (Command-Line Interface) - An interface through which users interact with TutorLink by typing commands into a command-line or terminal window.
-
Component - An assessment component that is graded, such as an assignment, exam, or project, represented as an object in the application.
-
ComponentList - A object that is a collection of
Component
objects within TutorLink, storing all components for a course, such as assignments, exams, or other graded items. -
CommandResult - An object that encapsulates the outcome of a command execution, containing information about the command's success or failure and any relevant output for the user.
-
Grade - An score assigned to a student for a particular component, stored as a
Grade
object within the application. -
GradeList - A object that is a collection of
Grade
objects within TutorLink, storing all grades assigned to students for various components. -
HashMap - A data structure used in TutorLink to store key-value pairs, commonly used to handle arguments passed into command methods.
-
Matric Number - A unique identifier assigned to each student, used within TutorLink to manage and retrieve student records.
-
Parser - A class responsible for interpreting and validating user input commands, returning the requested commands, and the respective command arguments in a HashMap.
-
Student - A object in TutorLink representing an individual enrolled in a course, containing relevant data such as name, and matric number.
-
StudentList - A object that is a collection of
Student
objects managed by TutorLink, representing all students enrolled in a course. -
Storage - A component in TutorLink responsible for saving and loading data to and from files, allowing persistence of student, component, and grade information across sessions.
-
Validation - The process of verifying that user input or file data meets specific requirements and constraints to maintain application integrity and avoid errors.
This appendix provides a guide for manually testing various features of TutorLink, such as launching the application, modifying window preferences, adding/removing students and components, and managing grades.
-
Download the .jar file: Download and copy the
TutorLink.jar
file in an empty folder on your computer. -
Launch TutorLink: Open a command terminal, navigate to the folder containing the
.jar
file, and enter the commandjava -jar TutorLink.jar
.Expected: The console interface opens with a welcome message and awaits commands. No data is loaded initially if this is the first launch.
-
Add some sample data (e.g., students, components, and grades) using the respective commands (
add_student
,add_component
, etc.). -
Exit the application by typing
bye
.Expected: Data is saved automatically to files in the
[JAR file location]/data/
directory (studentlist.txt
,componentlist.txt
,gradelist.txt
). -
Re-launch TutorLink and use the
list_student
,list_component
, andlist_grade
commands to verify data persistence.Expected: Previously added data should appear, confirming successful data loading from files.
-
Test Case:
add_student i/A1234567X n/John Doe
Expected: John Doe with matric number
A1234567X
is added to the student list. Uselist_student
to confirm. -
Invalid Input Cases:
add_student n/John Doe
(missing matric number)add_student i/A1234567X
(missing name)
Expected: Error messages indicating missing fields. No student is added.
-
Prerequisites: Ensure the list of students is displayed using
list_student
and contains multiple entries. -
Test Case:
delete_student i/A1234567X
Expected: The student with matric number
A1234567X
is removed from the list. A message confirms the deletion. -
Invalid Input Cases:
delete_student i/INVALID_MATRIC_NUMBER
(nonexistent matric number)delete_student
(missing matric number)
Expected: Error messages indicating invalid or missing inputs. No student is deleted.
-
Test Case:
add_component c/Midterm w/30 m/100
Expected: The "Midterm" component with a weight of 30% and max score of 100 is added. Use
list_component
to verify. -
Invalid Input Cases:
add_component w/30 m/100
(missing component name)add_component c/Midterm w/110 m/100
(weight exceeds 100%)
Expected: Error messages indicating missing or invalid fields. No component is added.
-
Prerequisites: Use
list_component
to ensure components are available. -
Test Case:
delete_component c/Midterm
Expected: The "Midterm" component is removed from the list. A message confirms the deletion.
-
Invalid Input Cases:
delete_component c/Nonexistent
(component not found)delete_component
(missing component name)
Expected: Error messages indicating invalid or missing inputs. No component is deleted.
-
Prerequisites: Ensure both a student and a component exist in the lists.
-
Test Case:
add_grade i/A1234567X c/Midterm s/85
Expected: An 85 score for the "Midterm" component is recorded for the student with matric number
A1234567X
. Uselist_grade i/A1234567X
to confirm. -
Invalid Input Cases:
add_grade c/Midterm s/85
(missing matric number)add_grade i/A1234567X s/85
(missing component)add_grade c/Midterm s/105
(input score exceeds the maximum score of the component, set when the component was first added.)
Expected: Error messages indicating missing or invalid fields. No grade is added.
-
Prerequisites: Ensure the student has a recorded grade for a component.
-
Test Case:
delete_grade i/A1234567X c/Midterm
Expected: The "Midterm" grade for the student with matric number
A1234567X
is removed. Confirmation message is displayed. -
Invalid Input Cases:
delete_grade i/InvalidID c/Midterm
(nonexistent student)delete_grade i/A1234567X
(missing component)
Expected: Error messages indicating invalid or missing inputs. No grade is deleted.
-
Command:
bye
Expected: The program terminates smoothly, returning to the command prompt without errors.
-
Simulate Missing Data Files:
- Delete one or more files from the
data
folder (studentlist.txt
,componentlist.txt
,gradelist.txt
). - Re-launch TutorLink.
Expected: TutorLink creates new empty files if missing. The application should not crash, and it should operate normally.
- Delete one or more files from the
-
Simulate Corrupted Data:
- Open any data file and add random text or invalid data entry, then save.
- Re-launch TutorLink.
Expected: TutorLink should detect the corrupted or invalid data, display them to the user as entries to be discarded, and only load valid data entries. The application should not crash.