From b4b6cb969a5f39166ae228107546a26a45e43cc4 Mon Sep 17 00:00:00 2001 From: marioalvaro Date: Mon, 13 Nov 2023 23:46:59 +0800 Subject: [PATCH 1/4] Add additional update to UG and DG --- docs/DeveloperGuide.md | 116 ++++++++++++++++++++++++++++++----------- docs/UserGuide.md | 3 ++ 2 files changed, 89 insertions(+), 30 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index e32f67d14af..1d1a6033e9c 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -188,26 +188,48 @@ This section describes some noteworthy details on how certain features are imple ### Auto-grading -#### Proposed Implementation +#### Implementation + +The auto-grading command uses the help of `EditStudentScommand` and `SortStuCommand` to properly assign each grade to the students. +The `SortStuCommand` is used to find the grade threshold value for each grade, if the method used is by `percentile` (this will be explained later). +Additionally, it creates clearer result as it sorts the students by their total score inversely. +In a short manner, the mechanism works by finding the grade threshold for each grade and assigning the grade to each student by comparing +their total score to the previously found grade threshold. + +There are 2 possible method of grading: +* Percentile Method: `percentile` + * Calculate students' grade based on the statistical percentile. This will assign the grade for students above k-th percentile. + `SortStuCommand` will be used to sort the students and find the students at the exact position of the grade threshold. + Note that it will **round up** the index to take a more lenient approach. The total score of that student will be used as the grade threshold. +* Absolute Score Method: `absolute` + * Calculate students' grade based on the given passing grade values. + * The absolute value is compared directly with the students' total score (in percentage of the maximum score possible). + +**Important Note:** +* The `autoGrade` command works on the filtered student list. This would allow for example, to grade students only compared to their own tutorial group. To automatically grade every student in the module, `findStu` command can be used to display every student. -{Intro} -Given below is an example usage scenario and how the Autograding mechanism for percentile calculation behaves at each step. +Given below is an example usage scenario and how the auto-grading mechanism for percentile calculation behaves at each step. Step 1. The user launch the application for the first time. -Step 2. The user creates the desired graded components and adds all the students in the cohort. +Step 2. The user creates the desired graded components, adds all the students in the cohort, and assign them with scores. -Step 3. The user then executes `autograde ag/percentile pg/5 15 30 50 60 70 80 90 95` to execute the auto-grading system, the 'percentile' +Step 3. The user then executes `autoGrade ag/percentile pg/95 70 65 50 40 30 20` to execute the auto-grading system, the `percentile` keyword indicates that ModuLight grades based on the students' percentile compared to another. The value after `pg/` indicates the top percentile for each corresponding grade threshold, i.e. `pg/[A+] [A] [A-] [B+] ...`. -**Note:** The value for `ag/` can be type `score` which determines the grade based on the passing score of the student's total score. +**Note:** The value for `ag/` can be type `absolute` which determines the grade based on the passing score of the student's total score. +This step will first trigger the parse function and several things will be executed +1. +This step will first trigger the `sortStuCommand` and causes the filtered student list to be updated into the sorted form. + + Step 4. The command execution will then parse the grade threshold value based on empty space and stores them locally. Then, it will call `Model#getStudentBook()` and will calculate for every student, what tag the student will get based on the total score. ModuLight will then execute `editStudentCommand` on every student to assign them with the grade tag. All the calculations will be run in the @@ -219,9 +241,6 @@ total score. ModuLight will then execute `editStudentCommand` on every student t **Aspect: How the assignments of grade works:** -* **Alternative 1 (Current choice):** Use tags to assign the grade - * Pros: Easy to implement. - * Cons: Not ideal if we want to extend the code for more features. * **Alternative 2:** Create new Grade object for each student. * Pros: Cleaner and extendable code implementation. * Cons: require change of implementation on multiple classes. @@ -349,33 +368,33 @@ NUS professors who: Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unlikely to have) - `*` -| Priority | As a …​ | I want to …​ | So that I can…​ | -|----------|---------------|------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------| -| `* * *` | NUS professor | add a new student | track all students taking my course. | -| `* * *` | NUS professor | add a new graded component | track all graded components in my course thus far. | -| `* * *` | NUS professor | add a new student score | track individual student performance on this module's graded components. | -| `* * *` | NUS professor | delete a student | remove students dropping the course/wrongly assigned. | -| `* * *` | NUS professor | delete a graded component | remove a graded component if I feel it is no longer necessary. | -| `* * *` | NUS professor | delete a student score | | -| `* * *` | NUS professor | save changes made | so I can update student grade information throughout the semester. | -| `* * *` | NUS professor | load information | so I can update student grade information throughout the semester. | -| `* *` | NUS professor | edit a student | update outdated student information or correct mistakes. | -| `* *` | NUS professor | edit a graded component | make changes to a component (eg. modify weightage) or correct mistakes. | -| `* *` | NUS professor | edit a student score | regrade student scripts or correct mistakes. | -| `* *` | NUS professor | find student and associated scores by ID | quickly find information about a student and their scores without having to search through the list | -| `* *` | NUS professor | find graded component and associated scores by ID | quickly find information about a graded component and student scores without having to search through the list | -| `* *` | NUS professor | quickly calculate the overall statistics of student grades | have a quick insight of how my students are performing | -| `* *` | NUS professor | sort students with specific order | find the top students easily | -| `* *` | NUS professor | sort student scores with specific order | find the top students with their associated scores easily | -| | NUS professor | **autograde** | | -| `*` | NUS professor | toggle between dark and light mode | have a pleasant user experience. | +| Priority | As a …​ | I want to …​ | So that I can…​ | +|----------|---------------|---------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------| +| `* * *` | NUS professor | add a new student | track all students taking my course. | +| `* * *` | NUS professor | add a new graded component | track all graded components in my course thus far. | +| `* * *` | NUS professor | add a new student score | track individual student performance on this module's graded components. | +| `* * *` | NUS professor | delete a student | remove students dropping the course/wrongly assigned. | +| `* * *` | NUS professor | delete a graded component | remove a graded component if I feel it is no longer necessary. | +| `* * *` | NUS professor | delete a student score | | +| `* * *` | NUS professor | save changes made | so I can update student grade information throughout the semester. | +| `* * *` | NUS professor | load information | so I can update student grade information throughout the semester. | +| `* *` | NUS professor | edit a student | update outdated student information or correct mistakes. | +| `* *` | NUS professor | edit a graded component | make changes to a component (eg. modify weightage) or correct mistakes. | +| `* *` | NUS professor | edit a student score | regrade student scripts or correct mistakes. | +| `* *` | NUS professor | find student and associated scores by ID | quickly find information about a student and their scores without having to search through the list | +| `* *` | NUS professor | find graded component and associated scores by ID | quickly find information about a graded component and student scores without having to search through the list | +| `* *` | NUS professor | quickly calculate the overall statistics of student grades | have a quick insight of how my students are performing | +| `* *` | NUS professor | sort students with specific order | find the top students easily | +| `* *` | NUS professor | sort student scores with specific order | find the top students with their associated scores easily | +| `* *` | NUS professor | automatically grade students based on their total score, the grading method I want to use, and the passing value for each grade | significantly reduce the time needed to grade the students and avoid manually grading each student. | +| `*` | NUS professor | toggle between dark and light mode | have a pleasant user experience. | *{More to be added}* ### Use cases (For all use cases below, the **System** is the `ModuLight` and the **Actor** is the `user`, unless specified otherwise) -**Use case: Add a student ** +**Use case: Add a student** **MSS** @@ -503,12 +522,14 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli 1. User requests to find a student or students with the specific keywords. 2. ModuLight shows a list of students that fulfilling the searching criteria. + Use case ends. **Extensions** * 1a. There are some unsupported or incorrect keywords. * 1a1. ModuLight shows an error message. + Use case ends. **Use case: Sort student(s)** @@ -517,12 +538,14 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli 1. User requests to sort the displayed student list with the specific order. 2. ModuLight shows a list of sorted students. + Use case ends. **Extensions** * 1a. The given sorting order is unsupported. * 1a1. ModuLight shows an error message. + Use case ends. **Use case: Calculate the overall stats of student performance** @@ -531,19 +554,52 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli 1. User requests to calculate the overall statistics of student performance 2. ModuLight shows a summary of statistics + Use case ends. **Extensions** * 1a. There is currently no student scores. * 1a1. ModuLight shows an error message. + Use case ends. * 1b. User requests to calculate a non-supported statistical measure. * 1b1. ModuLight shows an error message and a list of supported statistical measures. + Use case ends. +**Use case: Automatically grade students based on their total score** + +**MSS** + +1. User requests to automatically grade student using AutoGradeCommand. +2. Modulight automatically grade every student command based on their total score, grading method, and passing value. +3. Modulight automatically sort students based on their total score for convenience. + + Use case ends. + +**Extensions** + +* 1a. User request to use unsupported grading method. + * 1a1. Modulight shows an error message and a list of supported grading method available. + + Use case ends + +* 1b. User inputted non-decreasing values for passing value. + * 1b1. Modulight shows an error message specifying that the values inputted is non-decreasing. + + Use case ends + +* 1c. User inputted passing values outside the bound of 0 and 100 inclusively. + * 1c1. Modulight shows an error message specifying that the values must be between 0 and 100 inclusively. + + Use case ends + +* 1d. User inputted too many passing values. + * 1d1. Modulight shows an error message specifying that there are too many passing values inputted. + Use case ends *{More to be added}* diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 3e903d7c038..1fde4876b1e 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -415,6 +415,9 @@ The `PASSING_VALUE` are numbers that determine the boundary for each grade * Value `30` given to `B` * Any Value below `30` will be given `F` +**Important Note:** +* The `autoGrade` command works on the filtered student list. This would allow for example, to grade students only compared to their own tutorial group. To automatically grade every student in the module, please use `findStu` command to display every student. + Example: * `autoGrade ag/absolute pg/95 80 70 55 40 20`. This would automatically grade student by using absolute grade threshold. Student with total score `95%` above will be given `A+`, total score below `95%` and `90` above will be given `A`, and so on, while below `20%` will be given `F`. From a9f88c8ab6484e623c31e6524ae912821f653dd0 Mon Sep 17 00:00:00 2001 From: marioalvaro Date: Tue, 14 Nov 2023 02:49:04 +0800 Subject: [PATCH 2/4] Add additional update to UG and DG --- docs/DeveloperGuide.md | 32 ++++- docs/UserGuide.md | 13 +- .../AutoGradeCommandSequenceDiagram.png | Bin 0 -> 63465 bytes .../AutoGradeCommandSequenceDiagram.puml | 131 ++++++++++++++++++ .../AutoGradeParserSequenceDiagram.png | Bin 0 -> 31150 bytes .../AutoGradeParserSequenceDiagram.puml | 62 +++++++++ .../logic/commands/AutoGradeCommand.java | 4 +- 7 files changed, 227 insertions(+), 15 deletions(-) create mode 100644 docs/diagrams/AutoGradeCommandSequenceDiagram.png create mode 100644 docs/diagrams/AutoGradeCommandSequenceDiagram.puml create mode 100644 docs/diagrams/AutoGradeParserSequenceDiagram.png create mode 100644 docs/diagrams/AutoGradeParserSequenceDiagram.puml diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 1d1a6033e9c..9c9edced046 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -226,22 +226,40 @@ the top percentile for each corresponding grade threshold, i.e. `pg/[A+] [A] [A- This step will first trigger the parse function and several things will be executed -1. -This step will first trigger the `sortStuCommand` and causes the filtered student list to be updated into the sorted form. +1. The string argument will be parsed into the grading method and the passing value. +2. `AutoGradeCommandParser#checkAutoGradeType()` then will parse the grading method string into AutoGradeType `PERCENTILE`. +3. `AutoGradeCommandParser#mapToFloat()` will parse the passing value string into an array of float. In this step, string that is not parsable will be checked and an exception will be thrown. + Furthermore, values less than zero or more than 100 will cause an exception to be thrown as the total mark of a student is in percentage. + Further check on values must be decreasing is also available as lower grades cannot have higher grade threshold. +4. The parser then will return a new `AutoGradeCommand` object. +Step 4. The `AutoGradeCommand` returned will then be executed and several other things will be executed +1. This step will first trigger the `sortStuCommand` and causes the filtered student list to be updated into the sorted form. +2. A check will be done to ensure that the inputted array of float does not pass the maximum number of values. An exception will be thrown otherwise. +3. As the grading method used in this example is `PERCENTILE`, it will then trigger `AutoGradeCommand#setGradeThresholdPercentile()` to be executed in order to calculate the + grade threshold. +4. It will then create an `EditStudentDescriptor` for each student in the filtered list and the assigned grade. + The grade is determined by comparing the student's total score and the grade threshold. +5. `EditStudentCommand` will be created and executed for each student and the grade will be added. -Step 4. The command execution will then parse the grade threshold value based on empty space and stores them locally. -Then, it will call `Model#getStudentBook()` and will calculate for every student, what tag the student will get based on the -total score. ModuLight will then execute `editStudentCommand` on every student to assign them with the grade tag. All the calculations will be run in the -`autoGradeCommand`. +The following sequence diagram shows how the auto-grading mechanism works: +* The parser implementation (Command execution is hidden): + + + +* The command implementation : + + + +[//]: # (The following activity diagram shows the logic behind the auto-grade mechanism:) #### Design considerations: **Aspect: How the assignments of grade works:** -* **Alternative 2:** Create new Grade object for each student. +* Create new Grade object for each student. * Pros: Cleaner and extendable code implementation. * Cons: require change of implementation on multiple classes. diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 1fde4876b1e..c432d2be685 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -105,12 +105,13 @@ The following section gives an overview of the parameters used for the commands ### Command Related Parameters -| Parameter | Description | Constraints | Valid Examples | Invalid Examples | -|-----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------|----------------------------| -| o/ | Used in the [sortStu](#sorting-students-sortstu) command, the selected parameter of students to be sorted | Only parameters in the list (The full list can be found under the description of [sortStu](#sorting-students-sortstu) command) are allowed | n, totalscore, tut | studentName, overall score | -| r/ | Used in the [sortStu](#sorting-students-sortstu) and [sortStuScore](#sorting-students-scores-sortscore) commands, the reverse order (to arrange the list either in ascending or descending order) | Only parameters in the list (The full list can be found under the description of [sortStu](#sorting-students-sortstu) and [sortScore](#sorting-students-scores-sortscore) commands) are allowed | t, f, decreasing | True, ascending | -| st/ | Used in the [stats](#calculating-overall-statistics-stats) and [compStats](#calculating-statistics-of-a-graded-component-compstats) commands, the statistical measures to be calculated | Only parameters in the list (The full list can be found under the description of [stats](#calculating-overall-statistics-stats) and [compStats](#calculating-statistics-of-a-graded-component-compstats) commands) are allowed | max, upperQuartile | quartile, correlation | -| pg/ | Used in autograde command, .... | | | | +| Parameter | Description | Constraints | Valid Examples | Invalid Examples | +|-----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------|-----------------------------| +| o/ | Used in the [sortStu](#sorting-students-sortstu) command, the selected parameter of students to be sorted | Only parameters in the list (The full list can be found under the description of [sortStu](#sorting-students-sortstu) command) are allowed | n, totalscore, tut | studentName, overall score | +| r/ | Used in the [sortStu](#sorting-students-sortstu) and [sortStuScore](#sorting-students-scores-sortscore) commands, the reverse order (to arrange the list either in ascending or descending order) | Only parameters in the list (The full list can be found under the description of [sortStu](#sorting-students-sortstu) and [sortScore](#sorting-students-scores-sortscore) commands) are allowed | t, f, decreasing | True, ascending | +| st/ | Used in the [stats](#calculating-overall-statistics-stats) and [compStats](#calculating-statistics-of-a-graded-component-compstats) commands, the statistical measures to be calculated | Only parameters in the list (The full list can be found under the description of [stats](#calculating-overall-statistics-stats) and [compStats](#calculating-statistics-of-a-graded-component-compstats) commands) are allowed | max, upperQuartile | quartile, correlation | +| pg/ | Used in [autoGrade](#auto-grading-all-the-students) to determine the passing value of the grade | At most 11 number, with each of them must be an integer. Furthermore, the value must be decreasing and cannot exceed 100 or below 0 | 90 80 50 30 20, 0, 100 | 101, -2, 90 70 75, 90 90 90 | | | +| ag/ | Used in [autoGrade](#auto-grading-all-the-students) to determine the grading method | One of the: p, percentile, Percentile, a, absolute, Absolute | p, percentile, Percentile, a, absolute, Absolute | Asolut, persentil | diff --git a/docs/diagrams/AutoGradeCommandSequenceDiagram.png b/docs/diagrams/AutoGradeCommandSequenceDiagram.png new file mode 100644 index 0000000000000000000000000000000000000000..80a6a96b2b2933175d82173bf267539724282e7d GIT binary patch literal 63465 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 AutoGradeCommand +activate AutoGradeCommand + +user <-- AutoGradeCommand +deactivate AutoGradeCommand + +user -> AutoGradeCommand : execute() +activate AutoGradeCommand + +AutoGradeCommand -> Model : sortStudent("o", true) +activate Model + +AutoGradeCommand <-- Model +deactivate Model + +alt PERCENTILE + AutoGradeCommand -> AutoGradeCommand : setGradeThresholdPercentile() + activate AutoGradeCommand + + AutoGradeCommand --> AutoGradeCommand + deactivate AutoGradeCommand + AutoGradeCommand -[hidden]-> AutoGradeCommand + +else ABSOLUTE + AutoGradeCommand -> AutoGradeCommand : setGradeThresholdAbsolute() + activate AutoGradeCommand + + AutoGradeCommand --> AutoGradeCommand + deactivate AutoGradeCommand + + AutoGradeCommand -[hidden]-> AutoGradeCommand +end + +AutoGradeCommand -> AutoGradeCommand : addGradeToAllStudent() +activate AutoGradeCommand + +AutoGradeCommand -> Model : getFilteredStudentList() +activate Model + +AutoGradeCommand <-- Model +deactivate Model + +loop studentList.size() + AutoGradeCommand -> AutoGradeCommand + activate AutoGradeCommand + + create EditStudentDescriptor + AutoGradeCommand -> EditStudentDescriptor + activate EditStudentDescriptor + + AutoGradeCommand <-- EditStudentDescriptor + deactivate EditStudentDescriptor + + AutoGradeCommand -> AutoGradeCommand : createGraded() + activate AutoGradeCommand + + AutoGradeCommand --> AutoGradeCommand : studentGrade + deactivate AutoGradeCommand + + AutoGradeCommand -> EditStudentDescriptor : setStudentGrade() + activate EditStudentDescriptor + + AutoGradeCommand <-- EditStudentDescriptor : ed + deactivate EditStudentDescriptor + + EditStudentDescriptor -[hidden]-> EditStudentDescriptor + destroy EditStudentDescriptor + + AutoGradeCommand --> AutoGradeCommand + deactivate AutoGradeCommand + + create EditStudentCommand + AutoGradeCommand -> EditStudentCommand + activate EditStudentCommand + + AutoGradeCommand <-- EditStudentCommand + deactivate EditStudentCommand + + AutoGradeCommand -> EditStudentCommand : execute() + activate EditStudentCommand + + AutoGradeCommand <-- EditStudentCommand + deactivate EditStudentCommand + + EditStudentCommand -[hidden]-> EditStudentCommand + destroy EditStudentCommand + + AutoGradeCommand -[hidden]-> AutoGradeCommand + +end + +AutoGradeCommand --> AutoGradeCommand +deactivate AutoGradeCommand + +create CommandResult +AutoGradeCommand -> CommandResult +activate CommandResult + +CommandResult --> AutoGradeCommand +deactivate CommandResult + +AutoGradeCommand -> user : result +deactivate AutoGradeCommand + + + + + + + + + +@enduml \ No newline at end of file diff --git a/docs/diagrams/AutoGradeParserSequenceDiagram.png b/docs/diagrams/AutoGradeParserSequenceDiagram.png new file mode 100644 index 0000000000000000000000000000000000000000..e61ee2434e82675014638fc8413855f9329ac462 GIT binary patch literal 31150 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 literal 0 HcmV?d00001 diff --git a/docs/diagrams/AutoGradeParserSequenceDiagram.puml b/docs/diagrams/AutoGradeParserSequenceDiagram.puml new file mode 100644 index 00000000000..efa4521cf66 --- /dev/null +++ b/docs/diagrams/AutoGradeParserSequenceDiagram.puml @@ -0,0 +1,62 @@ +@startuml +!include style.puml +skinparam ArrowFontStyle plain + +box Logic LOGIC_COLOR_T1 +participant ":LogicManager" as LogicManager LOGIC_COLOR +participant ":ModuLightParser" as ModuLightParser LOGIC_COLOR +participant ":AutoGradeCommandParser" as AutoGradeCommandParser LOGIC_COLOR +participant "a:AutoGradeCommand" as AutoGradeCommand LOGIC_COLOR +end box + +[-> LogicManager : execute("autoGrade ...") +activate LogicManager + +LogicManager -> ModuLightParser : parseCommand("autoGrade ...") +activate ModuLightParser + +create AutoGradeCommandParser +ModuLightParser -> AutoGradeCommandParser +activate AutoGradeCommandParser + +AutoGradeCommandParser --> ModuLightParser +deactivate AutoGradeCommandParser + +ModuLightParser -> AutoGradeCommandParser : parse() +activate AutoGradeCommandParser + +AutoGradeCommandParser -> AutoGradeCommandParser : mapToFloat() +activate AutoGradeCommandParser +AutoGradeCommandParser --> AutoGradeCommandParser +deactivate AutoGradeCommandParser + +AutoGradeCommandParser -> AutoGradeCommandParser : checkAutoGradeType() +activate AutoGradeCommandParser +AutoGradeCommandParser --> AutoGradeCommandParser +deactivate AutoGradeCommandParser + +create AutoGradeCommand +AutoGradeCommandParser -> AutoGradeCommand +activate AutoGradeCommand + +AutoGradeCommand --> AutoGradeCommandParser : a +deactivate AutoGradeCommand + +AutoGradeCommandParser --> ModuLightParser : a +deactivate AutoGradeCommandParser +AutoGradeCommandParser -[hidden]-> ModuLightParser +destroy AutoGradeCommandParser + +ModuLightParser --> LogicManager : a +deactivate ModuLightParser + +LogicManager -> AutoGradeCommand : execute() +activate AutoGradeCommand + +AutoGradeCommand --> LogicManager : result +deactivate AutoGradeCommand + +[<--LogicManager +deactivate LogicManager + +@enduml \ No newline at end of file diff --git a/src/main/java/seedu/modulight/logic/commands/AutoGradeCommand.java b/src/main/java/seedu/modulight/logic/commands/AutoGradeCommand.java index 9f929f55f3c..eccb818a742 100644 --- a/src/main/java/seedu/modulight/logic/commands/AutoGradeCommand.java +++ b/src/main/java/seedu/modulight/logic/commands/AutoGradeCommand.java @@ -99,10 +99,10 @@ public CommandResult execute(Model model) throws CommandException { } private void setGradeThresholdPercentile(Model model) { - int size = model.getStudentBook().getSize(); + int size = model.getFilteredStudentList().size(); for (int i = 0; i < passingGradeValue.length; i++) { int percentileIndex = (int) Math.ceil((1 - this.passingGradeValue[i] / 100) * (size - 1)); - Student student = model.getStudentBook().getStudentList().get(percentileIndex); + Student student = model.getFilteredStudentList().get(percentileIndex); float percentileScore = student.getTotalScore(); this.gradeThreshold[i] = percentileScore; From 32fc39d572c890fdfa1759734b82134950aef0b0 Mon Sep 17 00:00:00 2001 From: marioalvaro Date: Tue, 14 Nov 2023 02:52:38 +0800 Subject: [PATCH 3/4] Fix checkstyle --- docs/diagrams/AutoGradeCommandSequenceDiagram.puml | 9 +-------- docs/diagrams/AutoGradeParserSequenceDiagram.puml | 2 +- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/docs/diagrams/AutoGradeCommandSequenceDiagram.puml b/docs/diagrams/AutoGradeCommandSequenceDiagram.puml index 2c920f1153a..decf35c9849 100644 --- a/docs/diagrams/AutoGradeCommandSequenceDiagram.puml +++ b/docs/diagrams/AutoGradeCommandSequenceDiagram.puml @@ -121,11 +121,4 @@ AutoGradeCommand -> user : result deactivate AutoGradeCommand - - - - - - - -@enduml \ No newline at end of file +@enduml diff --git a/docs/diagrams/AutoGradeParserSequenceDiagram.puml b/docs/diagrams/AutoGradeParserSequenceDiagram.puml index efa4521cf66..48865f1fbc0 100644 --- a/docs/diagrams/AutoGradeParserSequenceDiagram.puml +++ b/docs/diagrams/AutoGradeParserSequenceDiagram.puml @@ -59,4 +59,4 @@ deactivate AutoGradeCommand [<--LogicManager deactivate LogicManager -@enduml \ No newline at end of file +@enduml From 5c29144f15d6f2b78ade9a81053622fa6e49c007 Mon Sep 17 00:00:00 2001 From: marioalvaro Date: Tue, 14 Nov 2023 03:28:05 +0800 Subject: [PATCH 4/4] Fix bug in UG and update PPP --- docs/UserGuide.md | 20 ++-- docs/index.md | 2 +- docs/team/marioalvaro.md | 208 +++++++++++++++++++++++++++++++++++++-- 3 files changed, 212 insertions(+), 18 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index f4f6c4f7843..ab5b106dbdf 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -97,7 +97,7 @@ The following section gives an overview of the parameters used for the commands | e/ | Email of the student | Must consist of a alphanumeric prefix, @ symbol and a domain | 12@gmail.com, e123@u.nus.edu | 12@, 1234gmail | | s/ | Student ID of the student | Must start and end with a capital letter and have 7 digits in between them | A1234567W | a1234567w, a123w, B1234567 | | g/ | Tutorial group of the student | Must consist of a capital letter followed by 2 digits | T06, L10 | T1, t10, T111, @T11 | -| t/ | Tag of the student | Must only contain alphanumeric characters | Potential TA, Makeup exam | deans_list | +| t/ | Tag of the student | Must only contain alphanumeric characters and no space | PotentialTA, MakeupExam | deans_list, Potential TA | @@ -111,12 +111,12 @@ The following section gives an overview of the parameters used for the commands ### Student Score Parameters -| Parameter | Description | Constraints | Valid Examples | Invalid Examples | -|-----------|-----------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------|----------------------------|--------------------| -| m/ | Marks of the Student Score, in absolute terms | Must be a non-negative number, though decimals are allowed. Cannot exceed the maximum marks of the graded component this score is related to | 0, 0.23, 30.00, 20 | -1, ⅔, 2^3, twelve | -| x/ | Comments of the student score | Must only contain alphanumeric characters | Nice work!, Check number 2 | 好的 | -| t/ | Tags of the student score | Must only contain alphanumeric characters | Highest score, Makeup exam | @plagiarism | -| INDEX | The index of the target student score | Positive integer | 1, 10, 21 | -2, 0, 03 | +| Parameter | Description | Constraints | Valid Examples | Invalid Examples | +|-----------|-----------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------|----------------------------|----------------------------| +| m/ | Marks of the Student Score, in absolute terms | Must be a non-negative number, though decimals are allowed. Cannot exceed the maximum marks of the graded component this score is related to | 0, 0.23, 30.00, 20 | -1, ⅔, 2^3, twelve | +| x/ | Comments of the student score | Must only contain alphanumeric characters | Nice work!, Check number 2 | 好的 | +| t/ | Tags of the student score | Must only contain alphanumeric characters and no space | HighestScore, MakeupExam | @plagiarism, Highest Score | +| INDEX | The index of the target student score | Positive integer | 1, 10, 21 | -2, 0, 03 | ### Command Related Parameters @@ -251,7 +251,7 @@ Edits an existing graded component’s details in the database, based on the 1-b Format: `editComp INDEX [c/COMP_NAME] [w/WEIGHTAGE] [mm/MAX_MARKS]` -* if no parameters except index are passed in, the graded component will remain unchanged. +* if no parameters except index are passed in, it will throw an error. Examples: `editComp 4 c/Midterm Exam mm/55` edits the fourth graded component in the Graded Components list to have a name of “Midterm Exam”, and a maximum mark of 55. @@ -267,10 +267,10 @@ Note: a StudentScore will be automatically added when a graded component is crea * The mark given cannot exceed the maximum marks for that graded component. * Please refrain from entering numbers with more than 2 decimal places of precision. -Format: `editScore INDEX [m/SCORE] [x/comment]` +Format: `editScore INDEX [m/SCORE] [x/comment] [t/tags]` * if the mark is being edited, the new mark should be more than 0 and not exceed the associated component's maximum marks. -* if no parameters except index are passed in, the score will remain unchanged. +* if no parameters except index are passed in, it will throw an error. Examples: `editScore 7 m/57` assigns a mark of 57 for the seventh student score in the Student Scores list. diff --git a/docs/index.md b/docs/index.md index 41763fc624b..e5bf9ca11d0 100644 --- a/docs/index.md +++ b/docs/index.md @@ -10,7 +10,7 @@ ![Ui](images/Ui_navigate.png) -**AModuLight is a desktop student grades system application.** While it has a GUI, most of the user interactions happen using a CLI (Command Line Interface). +**A ModuLight is a desktop student grades system application.** While it has a GUI, most of the user interactions happen using a CLI (Command Line Interface). * If you are interested in using ModuLight, head over to the [_Quick Start_ section of the **User Guide**](UserGuide.html#Quick-start). * If you are interested about developing ModuLight, the [**Developer Guide**](DeveloperGuide.html) is a good place to start. diff --git a/docs/team/marioalvaro.md b/docs/team/marioalvaro.md index 8e43975d224..c6cf8ef87a5 100644 --- a/docs/team/marioalvaro.md +++ b/docs/team/marioalvaro.md @@ -3,11 +3,13 @@ layout: default.md title: "Mario Alvaro's Project Portfolio Page" --- -### Project: tp +### Project: ModuLight ModuLight is a web application to grade students in a module. The user interface will mainly be CLI. + + * **Code contributed** * Create StudentScore model * Implement StudentScore model to store the students' score and other attributes. @@ -18,19 +20,211 @@ The user interface will mainly be CLI. * Create a command to automatically grade every student based on their total scores * Command consist of two method; percentile method, which calculate the statistical percentile and use them to rank the students; absolute score method, which grades the student based on their total score compared to the absolute passing score. * Testings - * Implement thorough testings for every personally written code - * Create a couple of utility class to help with testings. + * Implement thorough and detailed testings for every personally written code. The tests was written to accommodate most of the path possibilities. + * Create a couple of utility class to help with testings, such as StudentScoreBuilder and more. * For further details, please refer to this: [RepoSense Link](https://nus-cs2103-ay2324s1.github.io/tp-dashboard/?search=marioalvaro&breakdown=true) * **Enhancements implemented** * To be added soon... * **Contributions to the UG** * Added EditStudentScoreCommand and AutoGrade to UG. + * Contribute to the parameter table for StudentScore and AutoGradeCommand. * **Contributions to the DG** - * Add implementation detail for AutoGrade Command. + * Add implementation detail for AutoGrade Command, with the UML diagrams included. * **Contributions to team-based tasks** - * To be added soon... + * Edit Index.md to the correct format for example, by adding badges. * **Review Contributions** - * To be added soon... + * Rechecking the UG to find bugs. * **Contributions beyond the project team** - * To be added soon... + * Reviewed other team Repositories for PED. + +### Contributions to User Guide +| Parameter | Description | Constraints | Valid Examples | Invalid Examples | +|-----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------|-----------------------------| +| pg/ | Used in [autoGrade](#auto-grading-all-the-students) to determine the passing value of the grade | At most 11 number, with each of them must be an integer. Furthermore, the value must be decreasing and cannot exceed 100 or below 0 | 90 80 50 30 20, 0, 100 | 101, -2, 90 70 75, 90 90 90 | | | +| ag/ | Used in [autoGrade](#auto-grading-all-the-students) to determine the grading method | One of the: p, percentile, Percentile, a, absolute, Absolute | p, percentile, Percentile, a, absolute, Absolute | Asolut, persentil | + +### Edit student score: `editScore` + +Edits a student’s mark for a certain graded component, based on the 1-based index of the student score shown in the Student Scores list. + +Note: a StudentScore will be automatically added when a graded component is created or when a new student is added. Similarly, student scores will be automatically deleted when its associated graded component or student is deleted. + +* 1 or more fields to be edited must be provided in the command. +* The index provided must be more than 0 and not exceed the number of student scores displayed in the Student Scores list. +* The mark given cannot exceed the maximum marks for that graded component. +* Please refrain from entering numbers with more than 2 decimal places of precision. + +Format: `editScore INDEX [m/SCORE] [x/comment] [t/tags]` + +* if the mark is being edited, the new mark should be more than 0 and not exceed the associated component's maximum marks. +* if no parameters except index are passed in, it will throw an error. + +Examples: `editScore 7 m/57` assigns a mark of 57 for the seventh student score in the Student Scores list. + +### Auto grading all the students: `autoGrade` + +Automatically assign grades to all students based on their total score and +the automatic grading method. + +Format: `autoGrade ag/METHOD pg/PASSING_VALUE` + +There are 2 possible `METHOD`: +* Percentile Method: `p`, `percentile`, `Percentile` + * Calculate students' grade based on the statistical percentile. +* Absolute Score Method: `a`, `absolute`, `Absolute` + * Calculate students' grade based on the given passing grade values. + * the absolute value is compared directly with the students' total score (in percentage of the maximum score possible). + +The `PASSING_VALUE` are numbers that determine the boundary for each grade +* The structure of `PASSING_VALUE`: `[A+] [A] [A-] [B+] [B] [B-] [C+] [C] [D+] [D] [F]` +* Each bracket represents the boundary value for the grade. + * For `percentile` method, it is the statistical percentile value. + * For `absolute` method, it is the total score. +* It is **not** compulsory to fill all the `PASSING_VALUE`, but such approach would make students below the lowest given passing value to be graded `F`. +* Example: `pg/90 80 65 40 30`. This would correspond to: + * Value `90` given to `A+` + * Value `80` given to `A` + * Value `65` given to `A-` + * Value `40` given to `B+` + * Value `30` given to `B` + * Any Value below `30` will be given `F` + +**Important Note:** +* The `autoGrade` command works on the filtered student list. This would allow for example, to grade students only compared to their own tutorial group. To automatically grade every student in the module, please use `findStu` command to display every student. + +Example: +* `autoGrade ag/absolute pg/95 80 70 55 40 20`. This would automatically grade student by using absolute grade threshold. Student with total score `95%` above will be given `A+`, total score below `95%` and `90` above will be given `A`, and so on, while below `20%` will be given `F`. + +### Contributions to Developer Guide + +### Auto-grading + +#### Implementation + +The auto-grading command uses the help of `EditStudentScommand` and `SortStuCommand` to properly assign each grade to the students. +The `SortStuCommand` is used to find the grade threshold value for each grade, if the method used is by `percentile` (this will be explained later). +Additionally, it creates clearer result as it sorts the students by their total score inversely. +In a short manner, the mechanism works by finding the grade threshold for each grade and assigning the grade to each student by comparing +their total score to the previously found grade threshold. + +There are 2 possible method of grading: +* Percentile Method: `percentile` + * Calculate students' grade based on the statistical percentile. This will assign the grade for students above k-th percentile. + `SortStuCommand` will be used to sort the students and find the students at the exact position of the grade threshold. + Note that it will **round up** the index to take a more lenient approach. The total score of that student will be used as the grade threshold. +* Absolute Score Method: `absolute` + * Calculate students' grade based on the given passing grade values. + * The absolute value is compared directly with the students' total score (in percentage of the maximum score possible). + +**Important Note:** +* The `autoGrade` command works on the filtered student list. This would allow for example, to grade students only compared to their own tutorial group. To automatically grade every student in the module, `findStu` command can be used to display every student. + + +Given below is an example usage scenario and how the auto-grading mechanism for percentile calculation behaves at each step. + + +Step 1. The user launch the application for the first time. + +Step 2. The user creates the desired graded components, adds all the students in the cohort, and assign them with scores. + +Step 3. The user then executes `autoGrade ag/percentile pg/95 70 65 50 40 30 20` to execute the auto-grading system, the `percentile` +keyword indicates that ModuLight grades based on the students' percentile compared to another. The value after `pg/` indicates +the top percentile for each corresponding grade threshold, i.e. `pg/[A+] [A] [A-] [B+] ...`. + + + +**Note:** The value for `ag/` can be type `absolute` which determines the grade based on the passing score of the student's total score. + + + +This step will first trigger the parse function and several things will be executed +1. The string argument will be parsed into the grading method and the passing value. +2. `AutoGradeCommandParser#checkAutoGradeType()` then will parse the grading method string into AutoGradeType `PERCENTILE`. +3. `AutoGradeCommandParser#mapToFloat()` will parse the passing value string into an array of float. In this step, string that is not parsable will be checked and an exception will be thrown. + Furthermore, values less than zero or more than 100 will cause an exception to be thrown as the total mark of a student is in percentage. + Further check on values must be decreasing is also available as lower grades cannot have higher grade threshold. +4. The parser then will return a new `AutoGradeCommand` object. + +Step 4. The `AutoGradeCommand` returned will then be executed and several other things will be executed +1. This step will first trigger the `sortStuCommand` and causes the filtered student list to be updated into the sorted form. +2. A check will be done to ensure that the inputted array of float does not pass the maximum number of values. An exception will be thrown otherwise. +3. As the grading method used in this example is `PERCENTILE`, it will then trigger `AutoGradeCommand#setGradeThresholdPercentile()` to be executed in order to calculate the + grade threshold. +4. It will then create an `EditStudentDescriptor` for each student in the filtered list and the assigned grade. + The grade is determined by comparing the student's total score and the grade threshold. +5. `EditStudentCommand` will be created and executed for each student and the grade will be added. + + +The following sequence diagram shows how the auto-grading mechanism works: +* The parser implementation (Command execution is hidden): + + + +* The command implementation : + + + + + +**Use case: Edit a student score** + +**MSS** + +1. User requests to list student scores. +2. ModuLight shows a list of student scores. +3. User requests to edit the details of a specific student score. +4. ModuLight updates the detail of that student score with entered data. +5. ModuLight shows a list of updated student scores. + + Use case ends. + +**Extensions** + +* 2a. The list is empty. + + Use case ends. + +* 3a. The given index is invalid. + + * 3a1. ModuLight shows an error message. + + Use case resumes at step 2. + +* 3b. There is some error in the entered data. + + * 3b1. ModuLight shows an error message. + + Use case resumes at step 2. + +**Use case: Automatically grade students based on their total score** + +**MSS** + +1. User requests to automatically grade student using AutoGradeCommand. +2. Modulight automatically grade every student command based on their total score, grading method, and passing value. +3. Modulight automatically sort students based on their total score for convenience. + + Use case ends. + +**Extensions** + +* 1a. User request to use unsupported grading method. + * 1a1. Modulight shows an error message and a list of supported grading method available. + + Use case ends + +* 1b. User inputted non-decreasing values for passing value. + * 1b1. Modulight shows an error message specifying that the values inputted is non-decreasing. + + Use case ends + +* 1c. User inputted passing values outside the bound of 0 and 100 inclusively. + * 1c1. Modulight shows an error message specifying that the values must be between 0 and 100 inclusively. + + Use case ends + +* 1d. User inputted too many passing values. + * 1d1. Modulight shows an error message specifying that there are too many passing values inputted. + + Use case ends