Skip to content

[CS2113-T12-3] TASync - #26

Open
vihaan27 wants to merge 478 commits into
nus-cs2113-AY2425S2:masterfrom
AY2425S2-CS2113-T12-3:master
Open

[CS2113-T12-3] TASync#26
vihaan27 wants to merge 478 commits into
nus-cs2113-AY2425S2:masterfrom
AY2425S2-CS2113-T12-3:master

Conversation

@vihaan27

Copy link
Copy Markdown

Provide convenient management of tutor’s administrative tasks like attendance, remarks and planning, optimized for CLI.

@nus-se-bot nus-se-bot closed this Feb 21, 2025
@damithc damithc reopened this Feb 21, 2025
Ashertan256 pushed a commit to Ashertan256/tp that referenced this pull request Mar 18, 2025
…th-categories

Add JUnit tests and text UI test cases

@irving11119 irving11119 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, the code mostly has decent coding quality and there aren't many blatant violations of the coding standards. There are quite a number of methods which are quite long, try to those down into more methods.

Also note the comment on the data, if it is test data, I would advise not to commit this to repo and rather add it to the .gitignore

System.out.print("[C]");
break;
default:
break;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be better to catch the default case and throw an error, rather than just breaking

Comment on lines +47 to +102
public Student getStudentByName(String name) {
Scanner scanner = new Scanner(System.in);
List<Student> matched = new ArrayList<>();

for (Student s : students) {
if (s.getName().equalsIgnoreCase(name)) {
matched.add(s);
}
}

if (matched.isEmpty()) {
System.out.println("No student found with the name: " + name);
return null;
}

if (matched.size() == 1) {
return matched.get(0);
}

boolean allSame = matched.stream().allMatch(s -> s.getName().equalsIgnoreCase(name));


System.out.println("Multiple students found with the name '" + name + "':");

for (int i = 0; i < matched.size(); i++) {
Student s = matched.get(i);
System.out.println((i + 1) + ". " + s.getName() + " (Matric No: " + s.getMatricNumber() + ")");
}

if (allSame) {
System.out.print("Please enter the matric number to identify the student: ");
String matric = scanner.nextLine();
return getStudentByMatricNumber(matric);
} else {
System.out.print("Enter the number (1-" + matched.size() + ") or full name: ");
String input = scanner.nextLine();

try {
int index = Integer.parseInt(input);
if (index >= 1 && index <= matched.size()) {
return matched.get(index - 1);
} else {
System.out.println("Invalid index.");
}
} catch (NumberFormatException e) {
for (Student s : matched) {
if (s.getName().equalsIgnoreCase(input)) {
return s;
}
}
System.out.println("No match for input name.");
}
}

return null;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is quite long, you could break this down into multiple private methods. Also note ideally your public functions should all have Java Docs.

/**
* Prints the schedule for today including todos, deadlines, events, consultations, and tutorial classes.
*/
public void displayScheduleForToday() {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is quite long, try to break it down into multiple smaller methods. Also do try your best to write Java docs for your public methods

Comment on lines +98 to +102
String tutorialInfo = " - " + "Tutorial Name: " + tutorial.getTutorialName() +
", Day of Week: " + tutorial.getDayOfWeek() +
", From: " + tutorial.getStartTime() +
", To: " + tutorial.getEndTime();
System.out.println(tutorialInfo);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have a number of complicated print statements. Consider delegating these functionalities to your UI class.

Comment on lines +48 to +52
? String.valueOf(DateTimeFormatterUtil.parseDateTime(consultationStart))
: "INVALID DATE";
String formattedEnd = isEndValid
? String.valueOf(DateTimeFormatterUtil.parseDateTime(consultationEnd))
: "INVALID DATE";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try to avoid using magic strings in your code, in this case "INVALID DATE" is a hardcoded constant

Comment on lines +16 to +73
try {
// Validate input string
if (input == null || input.trim().isEmpty()) {
throw TASyncException.invalidNewTutorialCommand();
}

// Split the input to get tutorial details
String[] inputParts = input.split("\\s+");
if (inputParts.length != 4) {
throw TASyncException.invalidNewTutorialCommand();
}

String tutorialName = inputParts[0];
String dayOfWeekStr = inputParts[1];
String startTimeStr = inputParts[2];
String endTimeStr = inputParts[3];

// Parse and validate day of the week
int dayOfWeek;
try {
dayOfWeek = Integer.parseInt(dayOfWeekStr);
if (dayOfWeek < 1 || dayOfWeek > 7) {
throw TASyncException.invalidDayOfWeek();
}
} catch (NumberFormatException e) {
throw TASyncException.invalidDayOfWeek();
}

// Parse and validate start and end time

LocalTime startTime = LocalTime.parse(startTimeStr);
LocalTime endTime = LocalTime.parse(endTimeStr);

// Check if the tutorial already exists in the list
for (TutorialClass existingTutorial : tutorialClassList.getTutorialClasses()) {
if (existingTutorial.getTutorialName().equals(tutorialName) &&
existingTutorial.getDayOfWeek().getValue() == dayOfWeek &&
existingTutorial.getStartTime().equals(startTime) &&
existingTutorial.getEndTime().equals(endTime)) {
throw TASyncException.duplicateTutorial();
}
}

// Create a new TutorialClass object
StudentList emptyStudentList = new StudentList(); // Empty list for students
TutorialClass newTutorial = new TutorialClass();
newTutorial.setTutorialName(tutorialName);
newTutorial.setDayOfWeek(DayOfWeek.of(dayOfWeek)); // Convert int to DayOfWeek
newTutorial.setStartTime(startTime);
newTutorial.setEndTime(endTime);
newTutorial.setStudentList(emptyStudentList); // Set an empty student list

// Add the new tutorial to the tutorial class list
tutorialClassList.addTutorialClass(newTutorial);

// Output success message
System.out.println("New tutorial added: " + newTutorial);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is pretty long, you try to break it down more


public class ViewStudentCommentsCommand implements Command<AttendanceFile> {
//parts in format of tutname,week,studentname,matricnum
public void execute(String parts, AttendanceFile attendanceList) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try your best to document public methods with Java Docs

Comment on lines +55 to +173
public static Command createCommand(String commandString) {
String[] parts = commandString.split("\\s+", 3); // Split into command, type, and rest of input
if (parts.length < 2) {
System.out.println("Invalid command format. Please use: /add -[type] [task details]");
return null;
}

// Remove the leading '/' and convert the command to uppercase
String command = parts[0].toUpperCase();
String taskTypeShortcut = parts[1];
String listType = parts[1];

if ("HELP".equals(command)) {
CommandListPrinter.printCommands();
return null;
}

if ("ADD".equals(command)) {
TaskType taskType = TaskType.fromShortcut(taskTypeShortcut);
if (taskType == null) {
System.out.println("Invalid task type. Use -c (Consultation), -pt (Todo), -pe (Event), -pd (Deadline)");
return null;
}

switch (taskType) {
case TODO:
return new TodoCommand();
case EVENT:
return new EventCommand();
case DEADLINE:
return new DeadlineCommand();
case CONSULTATION:
return new ConsultationCommand();
default:
System.out.println("Unknown task type: " + taskType);
return null;
}
}


// Handle TaskList commands
if (listType.equalsIgnoreCase("-p")) {
switch (command) {
case "DELETE":
return new DeleteTaskCommand();
case "MARK":
return new MarkTaskCommand();
case "UNMARK":
return new UnmarkTaskCommand();
case "LIST":
return new ListTaskCommand();
case "FIND":
return new FindTaskCommand();
case "RENAME":
return new RenameTaskCommand();
default:
System.out.println("Sorry, TASync does not know what \"" + command + "\" means.");
CommandListPrinter.printCommands();
return null;
}
} else if (listType.equalsIgnoreCase("-t")) {
switch (command) {
case "NEWTUTORIAL":
return new NewTutorialCommand();
case "DELETE":
return new DeleteTutorialCommand();
case "LIST":
return new ListUpcomingTutorialsCommand();
case "NEWSTUDENT":
return new NewStudentCommand();
case "DELETESTUDENT":
return new DeleteStudentCommand();
case "LISTSTUDENTS":
return new ListTutorialStudentsCommand();
case "FIND":
return new FindStudentCommand();
case "CHANGEREMARK":
return new ChangeRemarkCommand();
case "CHECKREMARK":
return new CheckRemarkCommand();
default:
System.out.println("Sorry, TASync does not know what \"" + command + "\" means.");
CommandListPrinter.printCommands();
return null;
}
} else if (listType.equalsIgnoreCase("-a")) {
switch (command) {
case "MARK":
return new MarkStudentAttendanceCommand();
case "UNMARK":
return new UnmarkStudentAttendanceCommand();
case "COMMENT":
return new CommentOnStudentCommand();
case "VIEWCOMMENT":
return new ViewStudentCommentsCommand();
case "DELETECOMMENT":
return new DeleteStudentComment();
case "LIST":
return new ShowAttendanceListCommand();
default:
System.out.println("Sorry, TASync does not know what \"" + command + "\" means.");
CommandListPrinter.printCommands();
return null;
}
} else if (listType.equalsIgnoreCase("-at")) {
if (command.equals("CREATE")) {
return new CreateNewAttendanceList();
}
System.out.println("Sorry, TASync does not know what \"" + command + "\" means.");
CommandListPrinter.printCommands();
return null;
}

if (command.equals("BYE")) {
return new ByeCommand();
}

return null;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is pretty long, try to break it down into smaller parts

Comment thread data/AllTutorials.csv Outdated

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be advisable not to commit test data for your program. Your data should be generated fresh when running the jar file and then subsequently saved. Assuming this is all test data generated, you should add it to the .gitgnore file so its not committed.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can add this to the .gitignore as well

wongyihao02 and others added 5 commits April 1, 2025 22:48
Dev guide for AttendanceListCommands
- Abstract setUp code for each test in order to reduce code duplication
- Create ChangeRemarkCommandTest, CheckRemarkCommandTest, DeleteStudentCommandTest,FindStudentCommandTest and NewStudentCommandTest for easy testing of methods

@jessican1212 jessican1212 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, I think the written portion of your Developer Guide is very strong and I had a difficult time finding errors to critique. The professor did mention that there needs to be more diagrams. I think that is the main issue.

Comment thread docs/DeveloperGuide.md
- Removes the task from the `TaskList`.
- Displays a confirmation message upon successful removal.
- If the task is not found, an error message is shown.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the DG should include diagrams (UML diagrams, class diagrams, sequence diagrams, etc.)

Comment thread docs/DeveloperGuide.md

The class implements the following main operation:

- `NewStudentCommand#execute()`

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a typo? Should it be NewStudentcommand.execute()?

Comment thread docs/DeveloperGuide.md Outdated
- The hashMap containing the attendance status of the students will be printed.
- A different message will be printed if this hashMap is empty(signalling that the attendanceList has no students in it).
- An error message will be printed when an Exception is handled.
-

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This bullet point should probably be deleted if it's empty!

Comment thread docs/DeveloperGuide.md Outdated

#### Implementation details
This class implements the Command<AttendanceList> interface.Its function is to take in the input from the user and extract the tutorial and week the user has given
and print the names and attendance status of the students in that tutorial,if it exists.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure to fix small typos such as forgotten spaces after periods and commas for professionalism.

kmnyn and others added 13 commits April 2, 2025 11:47
Update developer guide for task commands
- Amend the formatting of the User Guide
- Add student command details for users
- Add important notes for users to take note of during command execution
- Amend the formatting of the User Guide
- Add student command details for users
- Add important notes for users to take note of during command execution
Add Junit tests for marks and marksList.
Add DG documentation for marks commands.

@jing-yen jing-yen left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good effort for your DG. Can be improved by explaning the architecture and supplementing it with UML diagrams

Comment thread docs/DeveloperGuide.md Outdated
{list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the original source as well}

## Design & implementation
## **Design & implementation**

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be a good idea to describe the architecture of TASync project, before explaining the specifics (an architecture diagram would be very welcome!)

Comment thread docs/DeveloperGuide.md

- `attendancelistcommands` - Handles commands related to attendance lists.
- `commandhandler` - Manages the processing and execution of various commands
- `student commands` - Implements commands specific to student-related operations

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure correct naming of the sub-packages. For instance, the space should be omitted from student commands sub-package.

Comment thread docs/DeveloperGuide.md Outdated
Comment on lines +253 to +262
- Parses the input to extract the tutorial class code and matriculation number.
- Validates the input to ensure it follows the expected format and does not contain any errors.
- Retrieves the specified tutorial class based on the provided class code.
- Checks if the tutorial class exists. If it does not, an error message is shown.
- Retrieves the student list from the tutorial class.
- Checks if the student with the given matriculation number exists in the class.
- If the student exists, retrieves their remark.
- If the student has a remark, displays it. Otherwise, indicates that no remarks were found.
- If the student does not exist, an error message is shown indicating that no such student was found.
- Handles any exceptions by displaying relevant error messages if validation fails or the tutorial class is not found.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For step-by-step operations, consider using numerical bullets (with possible sub-lists for conditional cases) instead of round bullets.

Comment thread docs/DeveloperGuide.md Outdated
and print the names and attendance status of the students in that tutorial,if it exists.

#### operations
- `ShowAttendanceListCommand.execute()`

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The operation code should be unindented (or the following description indented more) for clarity.

Comment thread docs/DeveloperGuide.md Outdated
- `ShowAttendanceListCommand.execute()`
- extracts tutorial name and week number from the given input.
- Exception thrown if no input or not enough input given.
- The AttendancFile is searched to find the relevant AttendanceList

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AttendancFile should be AttendanceFile

xubin0 and others added 4 commits April 3, 2025 14:13
update default value of Student Class
- Amend the formatting of the User Guide
- Add tutorial command details for users
- Add important notes for users to take note of during command execution
vihaan27 and others added 30 commits April 8, 2025 11:16
Add class diagram for marks.
- Make them less detailed but easier to comprehend to readers
- Change DG formatting
Update NewTutorialCommandSequenceDiagram.puml
update sequence diagram to remove numbering
Standardise test case format in appendix E
Update PPP to meet page limits
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants