diff --git a/src/main/java/seedu/address/logic/commands/AddScoreCommand.java b/src/main/java/seedu/address/logic/commands/AddScoreCommand.java new file mode 100644 index 00000000000..bc46468b1fe --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/AddScoreCommand.java @@ -0,0 +1,62 @@ +package seedu.address.logic.commands; + +import static java.util.Objects.requireNonNull; +import static seedu.address.logic.parser.CliSyntax.PREFIX_ID; +import static seedu.address.logic.parser.CliSyntax.PREFIX_STUDENT; + +import javafx.collections.ObservableList; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; +import seedu.address.model.group.Lesson; +import seedu.address.model.group.Participation; +import seedu.address.model.group.Student; +import seedu.address.model.group.StudentInfo; +import seedu.address.model.group.UniqueStudentInfoList; + +public class AddScoreCommand extends Command { + + public static final String COMMAND_WORD = "addscore"; + public static final String MESSAGE_SUCCESS = "%s: \nParticipation Score - %d"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + + ": Gives a student in the class a participation score. \n" + + "Parameters: " + " " + "SCORE " + + PREFIX_STUDENT + " NAME" + " " + PREFIX_ID + " STUDENT_NUMBER\n" + + "Example: " + COMMAND_WORD + " " + "2" + " " + + PREFIX_STUDENT + " Aaron Tan" + " " + PREFIX_ID + " e0123456"; + + private Student toAddScore; + private int score; + + /** + * Creates an AddScoreCommand to award the specified {@code Student} a participation score + */ + public AddScoreCommand(Student student, int score) { + requireNonNull(student); + // Specified student to add participation score + toAddScore = student; + this.score = score; + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + + Lesson uniqueLesson = model.getFilteredLessonList().get(0); + UniqueStudentInfoList uniqueStudentInfoList = uniqueLesson.getStudentsInfo(); + ObservableList studentsInfo = uniqueStudentInfoList.asUnmodifiableObservableList(); + + // Update single student participation score + for (int i = 0; i < studentsInfo.size(); i++) { + StudentInfo studentInfo = studentsInfo.get(i); + boolean isCorrectStudent = studentInfo.containsStudent(toAddScore); + if (isCorrectStudent) { + Participation update = studentInfo.getParticipation().setScore(score); + StudentInfo updatedStudentInfo = studentInfo.updateParticipation(update); + uniqueStudentInfoList.setStudentInfo(studentInfo, updatedStudentInfo); + } + } + return new CommandResult(String.format(MESSAGE_SUCCESS, toAddScore, score)); + + } +} diff --git a/src/main/java/seedu/address/logic/parser/AddScoreCommandParser.java b/src/main/java/seedu/address/logic/parser/AddScoreCommandParser.java new file mode 100644 index 00000000000..5b26f5820fd --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/AddScoreCommandParser.java @@ -0,0 +1,48 @@ +package seedu.address.logic.parser; + +import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.parser.CliSyntax.PREFIX_ID; +import static seedu.address.logic.parser.CliSyntax.PREFIX_STUDENT; + +import java.util.Optional; + +import seedu.address.logic.commands.AddScoreCommand; +import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.group.Student; + +public class AddScoreCommandParser implements Parser { + + /** + * Parses the given {@code String} of arguments in the context of the AddScoreCommand and + * returns a AddScoreCommand object for execution. + * + * @throws ParseException if the user input does not conform the expected format + */ + @Override + public AddScoreCommand parse(String userInput) throws ParseException { + ArgumentMultimap argMultimap = + ArgumentTokenizer + .tokenize(userInput, PREFIX_STUDENT, PREFIX_ID); + + String studentName; + String studentNumber; + Optional student; + int score; + + if (argMultimap.getValue(PREFIX_STUDENT).isPresent() && argMultimap.getValue(PREFIX_ID).isPresent()) { + + score = SerenityParserUtil.parseScore(argMultimap.getPreamble()); + if (score < 0 || score > 5) { + throw new ParseException("Score should be between 0 to 5"); + } + studentName = SerenityParserUtil.parseStudent(argMultimap.getValue(PREFIX_STUDENT).get()); + studentNumber = SerenityParserUtil.parseStudentID(argMultimap.getValue(PREFIX_ID).get()); + student = Optional.ofNullable(new Student(studentName, studentNumber)); + + return new AddScoreCommand(student.get(), score); + } else { + throw new ParseException( + String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddScoreCommand.MESSAGE_USAGE)); + } + } +} diff --git a/src/main/java/seedu/address/logic/parser/SerenityParser.java b/src/main/java/seedu/address/logic/parser/SerenityParser.java index 42d2624da07..2b6c110dc9b 100644 --- a/src/main/java/seedu/address/logic/parser/SerenityParser.java +++ b/src/main/java/seedu/address/logic/parser/SerenityParser.java @@ -9,6 +9,7 @@ import seedu.address.logic.commands.AddCommand; import seedu.address.logic.commands.AddGrpCommand; import seedu.address.logic.commands.AddQnCommand; +import seedu.address.logic.commands.AddScoreCommand; import seedu.address.logic.commands.ClearCommand; import seedu.address.logic.commands.Command; import seedu.address.logic.commands.DelGrpCommand; @@ -70,6 +71,9 @@ public Command parseCommand(String userInput) throws ParseException { case MarkAttCommand.COMMAND_WORD: return new MarkAttCommandParser().parse(arguments); + case AddScoreCommand.COMMAND_WORD: + return new AddScoreCommandParser().parse(arguments); + case UnmarkAttCommand.COMMAND_WORD: return new UnmarkAttCommandParser().parse(arguments); diff --git a/src/main/java/seedu/address/logic/parser/SerenityParserUtil.java b/src/main/java/seedu/address/logic/parser/SerenityParserUtil.java index c681bfff4a0..3e706ac6f28 100644 --- a/src/main/java/seedu/address/logic/parser/SerenityParserUtil.java +++ b/src/main/java/seedu/address/logic/parser/SerenityParserUtil.java @@ -3,6 +3,7 @@ import static java.util.Objects.requireNonNull; import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.group.Participation; import seedu.address.model.group.Question; import seedu.address.model.group.Student; @@ -36,6 +37,23 @@ public static String parseStudentID(String id) throws ParseException { return trimmedId; } + /** + * Parses {@code String inputScore} into an {@code int} and returns it. Leading and trailing whitespaces will be + * trimmed. + * + * @throws ParseException if the specified score is invalid. + */ + public static int parseScore(String inputScore) throws ParseException { + String trimmedScore = inputScore.trim(); + int score; + try { + score = Integer.parseInt(trimmedScore); + return score; + } catch (Exception e) { + throw new ParseException(Participation.SCORE_ERROR); + } + } + /** * Parses a {@code String question} into a {@code String}. Leading and trailing whitespaces will be trimmed. * diff --git a/src/main/java/seedu/address/model/group/Group.java b/src/main/java/seedu/address/model/group/Group.java index 2beb047f0bc..c7cdd439111 100644 --- a/src/main/java/seedu/address/model/group/Group.java +++ b/src/main/java/seedu/address/model/group/Group.java @@ -63,7 +63,6 @@ public Group(String name, UniqueStudentList students) { * @param students A list of students. * @param lessons A list of tutorial lessons. */ - public Group(String name, UniqueStudentList students, UniqueLessonList lessons) { requireAllNonNull(name, students, lessons); this.name = name; diff --git a/src/main/java/seedu/address/model/group/Participation.java b/src/main/java/seedu/address/model/group/Participation.java index 7fa90f0e024..cad46b7398e 100644 --- a/src/main/java/seedu/address/model/group/Participation.java +++ b/src/main/java/seedu/address/model/group/Participation.java @@ -2,12 +2,21 @@ public class Participation { + public static final String SCORE_ERROR = "Score must be a number"; private final int score; public Participation() { this.score = 0; } + /** + * Creates a Participation object containing the score of a student + * @param score Score of Student + */ + public Participation(int score) { + this.score = score; + } + @Override public String toString() { return Integer.toString(score); @@ -17,6 +26,11 @@ public int getScore() { return score; } + public Participation setScore(int score) { + Participation updatedScore = new Participation(score); + return updatedScore; + } + @Override public boolean equals(Object obj) { Participation other = (Participation) obj; diff --git a/src/main/java/seedu/address/model/group/StudentInfo.java b/src/main/java/seedu/address/model/group/StudentInfo.java index 310c079ac40..245591ca404 100644 --- a/src/main/java/seedu/address/model/group/StudentInfo.java +++ b/src/main/java/seedu/address/model/group/StudentInfo.java @@ -68,6 +68,16 @@ public StudentInfo updateAttendance(Attendance updatedAttendance) { return updatedStudentInfo; } + /** + * Updates the student participation score for the class + * @param updatedScore The participation score of the student for the lesson + * @return The updated Participation object + */ + public StudentInfo updateParticipation(Participation updatedScore) { + StudentInfo updatedStudentInfo = new StudentInfo(this.student, updatedScore, this.attendance); + return updatedStudentInfo; + } + @Override public boolean equals(Object obj) { StudentInfo other = (StudentInfo) obj; diff --git a/src/test/java/seedu/address/logic/commands/AddScoreCommandTest.java b/src/test/java/seedu/address/logic/commands/AddScoreCommandTest.java new file mode 100644 index 00000000000..d2e42c7183c --- /dev/null +++ b/src/test/java/seedu/address/logic/commands/AddScoreCommandTest.java @@ -0,0 +1,24 @@ +package seedu.address.logic.commands; + +import static seedu.address.testutil.Assert.assertThrows; + +import org.junit.jupiter.api.Test; + +class AddScoreCommandTest { + + @Test + public void constructor_nullGroup_throwsNullPointerException() { + assertThrows(NullPointerException.class, () -> new AddScoreCommand(null, 2)); + } + + @Test + public void execute_addScoreOutOfRange_failure() { + + } + + @Test + public void execute_addScore_success() { + + } + +}