-
Notifications
You must be signed in to change notification settings - Fork 140
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
[CS2113-W13-4] TutorLink #13
base: master
Are you sure you want to change the base?
[CS2113-W13-4] TutorLink #13
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great job overall! The code is solid, and the functionality is well-implemented. I only had a few minor recommendations, mainly around Javadocs, using constants and naming, but nothing that detracts from the quality of the work. Thanks for the effort and attention to detail here!
private GradeList addGradeForTest(Parser parser, AppState appState, String componentName) { | ||
//Create student | ||
String line = "add_student i/A1234567X n/John Doe"; | ||
Command addStudentCommand = new AddStudentCommand(); | ||
String[] argumentPrefixes = addStudentCommand.getArgumentPrefixes(); | ||
HashMap<String, String> arguments = parser.getArguments(argumentPrefixes, line); | ||
CommandResult result = addStudentCommand.execute(appState, arguments); | ||
assertNotNull(result); | ||
assertEquals("Student John Doe (A1234567X) added successfully!", result.toString()); | ||
assertEquals(appState.students.getStudentArrayList().size(), 1); | ||
|
||
//Create component | ||
String examName = componentName; | ||
double examMaxScore = 100.0; | ||
double examWeight = 50.0; | ||
Exam exam = new Exam(examName,examMaxScore, examWeight); | ||
|
||
appState.components.addComponent(exam); | ||
|
||
//Add grade | ||
HashMap<String, String> gradeArguments = new HashMap<>(); | ||
|
||
String matricNumber = "A1234567X"; | ||
String componentDescription = componentName; | ||
String scoreNumber = "75.0"; | ||
gradeArguments.put("i/",matricNumber); | ||
gradeArguments.put("c/", componentDescription); | ||
gradeArguments.put("s/", scoreNumber); | ||
|
||
Command addGradeCommand = new AddGradeCommand(); | ||
CommandResult gradeResult = addGradeCommand.execute(appState, gradeArguments); | ||
|
||
//Test grade added | ||
assertNotNull(gradeResult); | ||
assertEquals(String.format(successMessage, scoreNumber, componentDescription, matricNumber), | ||
gradeResult.toString()); | ||
|
||
return appState.grades; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
addGradeForTest()
is too long (>30 LOC) and doing multiple things, violating the "Avoid Long Methods" and the "Single Responsibility" principle. Consider breaking it down into smaller helper methods.
double examMaxScore = 100.0; | ||
double examWeight = 50.0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider converting magic numbers and strings to constants, to increase maintainability.
|
||
private GradeList addGradeForTest(Parser parser, AppState appState, String componentName) { | ||
//Create student | ||
String line = "add_student i/A1234567X n/John Doe"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Variable names could be more descriptive
HashMap<String, String> arguments = parser.getArguments(argumentPrefixes, line); | ||
CommandResult result = addStudentCommand.execute(appState, arguments); | ||
assertNotNull(result); | ||
assertEquals("Student John Doe (A1234567X) added successfully!", result.toString()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The success string could be added to the UI class
} | ||
|
||
@Test | ||
void execute_matric_one() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Test method names don't follow the recommended format featureUnderTest_testScenario_expectedBehavior()
. Consider renaming.
comp1 = new Assignment("Homework 1", 30, 0.1); | ||
comp2 = new Assignment("Homework 2", 30, 0.1); | ||
comp3 = new Exam("Finals", 100, 0.5); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider using more descriptive variable names
} | ||
|
||
@Test | ||
void toString_test() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure to follow the format featureUnderTest_testScenario_expectedBehavior()
like you have with others
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
import static org.junit.jupiter.api.Assertions.assertThrows; | ||
|
||
class ComponentListTest { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding Javadocs
public double calculateStudentGPA(String matricNumber, ComponentList componentList) | ||
throws IncompleteGradesException { | ||
ArrayList<Grade> studentGrades = gradeArrayList | ||
.stream() | ||
.filter(grade -> grade.getStudent().getMatricNumber().equals(matricNumber.toUpperCase())) | ||
.collect(Collectors.toCollection(ArrayList::new)); | ||
|
||
ArrayList<Component> allComponents = componentList.findAllComponents(); | ||
|
||
if (studentGrades.isEmpty()) { | ||
throw new StudentNotFoundException("No grades found for student: " + matricNumber); | ||
} | ||
|
||
boolean hasAllComponents = allComponents.stream() | ||
.allMatch(component -> studentGrades.stream() | ||
.anyMatch(grade -> grade.getComponent().equals(component))); | ||
|
||
if (!hasAllComponents) { | ||
throw new IncompleteGradesException( | ||
"Cannot calculate GPA: Student " + matricNumber + " is missing grades for some components"); | ||
} | ||
|
||
return studentGrades | ||
.stream() | ||
.mapToDouble(grade -> grade.getScore() * grade.getComponent().getWeight()) | ||
.sum(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Method is doing too many things (SLAP violation) - consider breaking into smaller methods. Magic number 0.07 in tax calculation could be a constant
public boolean deleteGrade(String matricNumber, String componentDescription) { | ||
matricNumber = matricNumber.toUpperCase(); | ||
componentDescription = componentDescription.toLowerCase(); | ||
for (Grade grade : gradeArrayList) { | ||
if (grade.getStudent().getMatricNumber().equals(matricNumber) | ||
&& grade.getComponent().getName().equals(componentDescription)) { | ||
return gradeArrayList.remove(grade); | ||
} | ||
} | ||
return false; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider using early return pattern to reduce nesting
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall looks good, only minor questions
docs/DeveloperGuide.md
Outdated
@@ -2,37 +2,189 @@ | |||
|
|||
## Acknowledgements | |||
|
|||
{list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the original source as well} | |||
{list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the | |||
original source as well} | |||
|
|||
## Design & implementation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this header Design & implementation be removed, since there is a separate Implementation header below?
docs/DeveloperGuide.md
Outdated
The following sequence diagrams depict the exact steps involved in the `AddStudentCommand`: | ||
|
||
![AddStudentCommand.png](diagrams/AddStudentCommand.png) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
docs/DeveloperGuide.md
Outdated
All commands follow the sequence as described in the diagram below: | ||
|
||
![ArchitectureSequenceGrouped.png](diagrams%2FArchitectureSequenceGrouped.png) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
docs/DeveloperGuide.md
Outdated
|
||
![GradeStorage.png](diagrams/GradeStorage.png) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could all the instantiations be moved into a separate diagram?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
other than the comments, lgtm!
|
||
{Describe the value proposition: what problem does it solve?} | ||
- At app launch, TutorLink initializes components (<code>Parser</code>, <code>Ui</code>, <code>Storage</code>, <code> | ||
AppState</code>). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
formatting issue here
|
||
## Product scope | ||
### Target user profile | ||
![Architecture.png](diagrams/Architecture.png) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
confusing diagram, do not understand what the arrows and lines are trying to say, maybe add a legend of what each line
docs/DeveloperGuide.md
Outdated
|
||
All commands follow the sequence as described in the diagram below: | ||
|
||
![ArchitectureSequenceGrouped.png](diagrams%2FArchitectureSequenceGrouped.png) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should the displayException have a return to standardise?
All commands follow the sequence as described in the diagram below: | ||
|
||
![ArchitectureSequenceGrouped.png](diagrams%2FArchitectureSequenceGrouped.png) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should you use alt for exception? maybe use alt [success] and [failure]?
would opt [success] be better
docs/DeveloperGuide.md
Outdated
|
||
All commands follow the sequence as described in the diagram below: | ||
|
||
![ArchitectureSequenceGrouped.png](diagrams%2FArchitectureSequenceGrouped.png) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should you concise the alt [success] sequence? the (new StudentComponent, ComponentStorage, GradeStorage) and the rest is a bit messy/confusing
docs/DeveloperGuide.md
Outdated
|
||
Likewise, the sequence diagram for `DeleteStudentCommand` is as follows: | ||
|
||
![DeleteStudentCommand.png](diagrams%2FDeleteStudentCommand.png) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should you have a lifeline for where "main"/ or something calls DeleteStudentCommand for better readability
docs/DeveloperGuide.md
Outdated
|
||
The sequence diagram of the DeleteGradeCommand is shown below. | ||
|
||
![AddGradeCommand.png](diagrams%2FAddGradeCommand.png) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should AddStudentCommand have a X at the end of the lifeline of an object to show its deletion
docs/DeveloperGuide.md
Outdated
1. TutorLink constructs a new `GradeStorage`. | ||
2. TutorLink calls `loadGradeList`. | ||
3. `GradeStorage` creates a new `ArrayList` of `Grade`s. | ||
4. `GradeStorage` creates a new `Scanner` with the path to the file. | ||
5. While there are next lines in the data file: | ||
- `Scanner` returns the current file line as a String and moves to the next file line. | ||
- `GradeStorage` calls its `getGradeFromFileLine` method with the file line. | ||
- If the file line references a valid `Component` and a valid `Student`, a `Grade` is returned and added to the `ArrayList`. | ||
- If not (e.g. if data file was corrupted), the file line is simply ignored, and the loop continues to the next iteration. | ||
6. The `ArrayList` of `Grade`s is returned to TutorLink. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should this be more concise instead of going through your entire program/algorithm
docs/DeveloperGuide.md
Outdated
@@ -2,37 +2,189 @@ | |||
|
|||
## Acknowledgements | |||
|
|||
{list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the original source as well} | |||
{list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should you include a class diagram
@@ -2,37 +2,189 @@ | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm in general!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall, the diagrams are well-documented and rigorous! I liked how the classes were colour-coded and standard across all diagrams, and that there was efficient use of reference frames in your team's DG. Good job!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should there be some standardization for the function calls in this diagram, specifically for displayResult
to be displayResult()
?
docs/diagrams/GradeStorage.png
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the lifeline for Scanner terminate after X
, as it indicates the end of the lifeline?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor nit: In the alt
frame of this diagram, one or two words to indicate what was successful will be good!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although including activation bars are not compulsory, with reference to the sequence diagram for AddGradeCommand
and DeleteGradeCommand
, should the activation bar for :DeleteStudentCommand
be included to ensure uniformity across your team's diagrams?
docs/diagrams/FindStudentCommand.png
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to a previous comment, the activation bar for :FindStudentCommand could be included to ensure uniformity across your team's diagrams!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the alt
frame of this diagram, the second condition has not been labelled. This could be fixed by adding a [else]
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to a previous comment, should the activation bar for :AddComponentCommand
be included to ensure uniformity across your team's diagrams?
Complete Draft of Developer Guide, except for storage data in appendix E
Add calcGPA command
…an-7-Nov * 'master' of github.com:AY2425S1-CS2113-W13-4/tp: Modify DeveloperGuide.md Re-export png files Modify ArchitectureSequenceGrouped.puml Modify .puml files Fix ui test again Fix ui test Fix codestyle Fix tests Handle totalWeighting = 0 case Fix updating GPA mechanic Add command # Conflicts: # docs/diagrams/GradeStorage.puml
Branch UG update
Update UserGuide.md
Update UserGuide.md
Update AboutUs.md
Fix ppp link
Branch more javadoc
Update yeekian PPP
Updatedppp
Bugfix for incorrect error message
Add author tags for GradeStorage
Branch fix reposense
NUS professors juggle admin tasks like tracking attendance and managing assignments, which detracts from their time for lesson preparation. Our app simplifies these processes by automating routine tasks and presenting concise, essential information, freeing up valuable time and enhancing their focus on teaching.