Skip to content

Commit

Permalink
Multiply grade rule (#129)
Browse files Browse the repository at this point in the history
New grading method that will multiply number of STATUS times a point value.
  • Loading branch information
ottenhoff authored Jan 3, 2025
1 parent b683a0f commit 49b5202
Show file tree
Hide file tree
Showing 20 changed files with 408 additions and 320 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,8 @@ $RECYCLE.BIN/
# Icon must end with two \r
Icon

# VSCode
.vscode/

# Thumbnails
._*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@
<property name="maximumGrade" column="MAXIMUM_GRADE" type="java.lang.Double" />
<property name="isGradeShown" column="IS_GRADE_SHOWN" type="java.lang.Boolean" />
<property name="sendToGradebook" column="SEND_TO_GRADEBOOK" type="java.lang.Boolean" />
<property name="useAutoGrading" column="AUTO_GRADING" type="java.lang.Boolean" />
<property name="autoGradeBySubtraction" column="GRADE_BY_SUBTRACTION" type="java.lang.Boolean" />
<property name="gradingMethod" column="GRADING_METHOD" type="java.lang.Integer" />
<property name="gradebookItemName" column="GRADEBOOK_ITEM_NAME" type="java.lang.String" />
<property name="showCommentsToStudents" column="SHOW_COMMENTS" type="java.lang.Boolean" />
<property name="isSyncing" column="SYNC" type="java.lang.Boolean" />
Expand Down
47 changes: 0 additions & 47 deletions api/src/java/org/sakaiproject/attendance/hbm/GradingRule.hbm.xml

This file was deleted.

65 changes: 28 additions & 37 deletions api/src/java/org/sakaiproject/attendance/model/AttendanceSite.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@

package org.sakaiproject.attendance.model;

import lombok.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

import org.sakaiproject.attendance.util.AttendanceConstants;

import java.io.Serializable;
Expand All @@ -29,36 +33,35 @@
* @author David Bauer [dbauer1 (at) udayton (dot) edu]
* @author Steve Swinsburg ([email protected])
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(exclude="attendanceStatuses")
public class AttendanceSite implements Serializable {
private static final long serialVersionUID = 1L;
private static final long serialVersionUID = 1L;

@Getter @Setter private Long id;
@Getter @Setter private String siteID;
@Getter @Setter private Status defaultStatus;
@Getter @Setter private Double maximumGrade;
@Getter @Setter private Boolean isGradeShown;
@Setter private Boolean sendToGradebook;
@Setter private Boolean useAutoGrading;
@Setter private Boolean autoGradeBySubtraction;
@Getter @Setter private String gradebookItemName;
@Getter @Setter private Boolean showCommentsToStudents;
@Setter private Boolean isSyncing;
@Getter @Setter private Date syncTime;
@Getter @Setter private Set<AttendanceStatus> attendanceStatuses = new HashSet<>(0);
private Long id;
private String siteID;
private Status defaultStatus;
private Double maximumGrade;
private Boolean isGradeShown;
private Boolean sendToGradebook;
private Integer gradingMethod;
private String gradebookItemName;
private Boolean showCommentsToStudents;
private Boolean isSyncing;
private Date syncTime;
private Set<AttendanceStatus> attendanceStatuses = new HashSet<>(0);

public AttendanceSite(String siteID){
this.siteID = siteID;
this.defaultStatus = Status.UNKNOWN;
this.isGradeShown = false;
this.sendToGradebook = false;
this.useAutoGrading = false;
this.autoGradeBySubtraction = true;
this.gradebookItemName = AttendanceConstants.GRADEBOOK_ITEM_NAME;
this.siteID = siteID;
this.defaultStatus = Status.UNKNOWN;
this.isGradeShown = false;
this.sendToGradebook = false;
this.gradingMethod = 0;
this.gradebookItemName = AttendanceConstants.GRADEBOOK_ITEM_NAME;
this.showCommentsToStudents = false;
this.isSyncing = false;
this.isSyncing = false;
}

public Boolean getSendToGradebook() {
Expand All @@ -78,19 +81,7 @@ public Boolean getIsSyncing() {
}

public Boolean getUseAutoGrading() {
if(this.useAutoGrading == null) {
return false;
}

return this.useAutoGrading;
}

public Boolean getAutoGradeBySubtraction() {
if(this.autoGradeBySubtraction == null) {
return true;
}

return this.autoGradeBySubtraction;
}
return this.gradingMethod != null;
}

}
42 changes: 42 additions & 0 deletions api/src/java/org/sakaiproject/attendance/model/GradingRule.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,20 @@
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.NamedQueries;
import org.hibernate.annotations.NamedQuery;
import org.hibernate.annotations.Type;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import java.io.Serializable;
import java.util.Date;

Expand All @@ -29,16 +42,45 @@
@Data
@EqualsAndHashCode(of = "id")
@NoArgsConstructor
@Entity(name = "GradingRule")
@Table(name = "ATTENDANCE_RULE_T", uniqueConstraints = {
@UniqueConstraint(name = "UK_ATTENDANCE_RULE", columnNames = {"A_SITE_ID", "STATUS", "START_RANGE", "END_RANGE"})
})
@NamedQueries({
@NamedQuery(
name = "getGradingRulesForSite",
query = "from GradingRule gradingRule JOIN FETCH gradingRule.attendanceSite WHERE gradingRule.attendanceSite = :attendanceSite"
)
})
public class GradingRule implements Serializable {
private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "GRADING_RULE_ID", updatable = false, nullable = false)
private Long id;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "A_SITE_ID", nullable = false)
private AttendanceSite attendanceSite;

@Column(name = "STATUS", nullable = false)
@Type(type = "org.sakaiproject.attendance.types.StatusUserType")
private Status status;

@Column(name = "START_RANGE", nullable = false)
private Integer startRange;

@Column(name = "END_RANGE")
private Integer endRange;

@Column(name = "POINTS", nullable = false)
private Double points;

@Column(name = "LAST_MODIFIED_BY", nullable = false, length = 99)
private String lastModifiedBy;

@Column(name = "LAST_MODIFIED_DATE", nullable = false)
private Date lastModifiedDate;

public GradingRule(AttendanceSite attendanceSite) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,9 @@ public class AttendanceConstants {
public static final String TOOL_NAME = "Attendance";
public static final String SAKAI_TOOL_NAME = "sakai.attendance";
public static final String GRADEBOOK_ITEM_NAME = "Attendance";

public static final int GRADING_METHOD_NONE = 0;
public static final int GRADING_METHOD_SUBTRACT = 1;
public static final int GRADING_METHOD_ADD = 2;
public static final int GRADING_METHOD_MULTIPLY = 3;
}
4 changes: 0 additions & 4 deletions impl/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,6 @@
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-configuration2</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ public AttendanceStatus getAttendanceStatusById(final Long id) {
* {@inheritDoc}
*/
public AttendanceGrade getAttendanceGrade(final Long id) {
log.debug("getAttendanceGrade, id: " + id.toString());
log.debug("getAttendanceGrade, id: {}", id.toString());

return (AttendanceGrade) getByIDHelper(id, QUERY_GET_ATTENDANCE_GRADE_BY_ID);
}
Expand All @@ -301,7 +301,7 @@ public AttendanceGrade getAttendanceGrade(final String userID, final AttendanceS
.setParameter(USER_ID, userID)
.uniqueResult());
} catch (DataAccessException e) {
log.error("Failed to get AttendanceGrade for " + userID + " in " + aS.getSiteID());
log.error("Failed to get AttendanceGrade for {} in {}", userID, aS.getSiteID());
return null;
}
}
Expand All @@ -319,7 +319,7 @@ public List<AttendanceGrade> getAttendanceGrades(final AttendanceSite aS) {
.setParameter(ATTENDANCE_SITE, aS)
.getResultList());
} catch (DataAccessException e) {
log.error("DataAccessException getting AttendanceGrades for " + aS.getSiteID() + ". E:", e);
log.error("DataAccessException getting AttendanceGrades for {}. E:", aS.getSiteID(), e);
return null;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.sakaiproject.attendance.api.AttendanceGradebookProvider;
import org.sakaiproject.attendance.dao.AttendanceDao;
import org.sakaiproject.attendance.model.*;
import org.sakaiproject.attendance.util.AttendanceConstants;
import org.sakaiproject.entity.api.Entity;
import org.sakaiproject.entity.api.EntityManager;
import org.sakaiproject.entity.api.EntityTransferrer;
Expand Down Expand Up @@ -837,9 +838,9 @@ private Double grade(String userId, AttendanceSite attendanceSite) {
final List<GradingRule> rules = getGradingRulesForSite(attendanceSite);
final AttendanceUserStats userStats = getStatsForUser(userId);

Double totalPoints = 0D;
double totalPoints = 0D;
Double maximumGrade = attendanceSite.getMaximumGrade();
if (attendanceSite.getAutoGradeBySubtraction() && maximumGrade != null) {
if (maximumGrade != null && attendanceSite.getGradingMethod() == AttendanceConstants.GRADING_METHOD_SUBTRACT) {
totalPoints = maximumGrade;
}

Expand All @@ -863,18 +864,25 @@ private Double grade(String userId, AttendanceSite attendanceSite) {
statusTotal = userStats.getLeftEarly();
break;
}
if (statusTotal != null && (statusTotal >= rule.getStartRange() && (rule.getEndRange() == null || statusTotal <= rule.getEndRange()))) {

if (statusTotal == null) {
log.debug("No status total for rule: {}", rule);
}
else if (attendanceSite.getGradingMethod() == AttendanceConstants.GRADING_METHOD_MULTIPLY) {
// Multiply the number of occurrences of the status by the rule's points and then add to the total points (loop of mutiple rules)
double newPoints = Math.round(statusTotal * rule.getPoints() * 100.0) / 100.0; // Avoid floating point errors
totalPoints = Double.sum(totalPoints, newPoints);
log.debug("Multiply Rule: {} Status: {} Total: {} Points: {} New Points: {} Total Points: {}", rule, rule.getStatus(), statusTotal, rule.getPoints(), newPoints, totalPoints);
}
else if (statusTotal >= rule.getStartRange() && (rule.getEndRange() == null || statusTotal <= rule.getEndRange())) {
totalPoints = Double.sum(totalPoints, rule.getPoints());
log.debug("Add Rule: {} Status: {} Total: {} Points: {} Total Points: {}", rule, rule.getStatus(), statusTotal, rule.getPoints(), totalPoints);
}
}
}

// Don't allow negative total points
if (totalPoints < 0D) {
return 0D;
} else {
return totalPoints;
}
return Math.max(totalPoints, 0D);
}

@Override
Expand Down
20 changes: 18 additions & 2 deletions impl/src/webapp/WEB-INF/components.xml
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,24 @@
<property name="gradingService" ref="org.sakaiproject.grading.api.GradingService" />
</bean>

<!-- Add our annotated classes to the Sakai global session factory -->
<bean id="org.sakaiproject.attendance.annotated.MappingList"
class="org.sakaiproject.springframework.orm.hibernate.impl.AdditionalHibernateMappingsImpl">

<property name="annotatedClasses">
<list>
<value>org.sakaiproject.attendance.model.GradingRule</value>
<value>org.sakaiproject.attendance.model.AttendanceEvent</value>
<value>org.sakaiproject.attendance.model.AttendanceGrade</value>
<value>org.sakaiproject.attendance.model.AttendanceItemStats</value>
<value>org.sakaiproject.attendance.model.AttendanceRecord</value>
<value>org.sakaiproject.attendance.model.AttendanceSite</value>
<value>org.sakaiproject.attendance.model.AttendanceStatus</value>
<value>org.sakaiproject.attendance.model.AttendanceUserStats</value>
</list>
</property>
</bean>

<!-- Add our HBM files to the Sakai global session factory -->
<bean id="org.sakaiproject.attendance.hbm.HBMMappingList"
class="org.sakaiproject.springframework.orm.hibernate.impl.AdditionalHibernateMappingsImpl">
Expand All @@ -100,10 +118,8 @@
<value>org/sakaiproject/attendance/hbm/AttendanceSite.hbm.xml</value>
<value>org/sakaiproject/attendance/hbm/AttendanceStatus.hbm.xml</value>
<value>org/sakaiproject/attendance/hbm/AttendanceUserStats.hbm.xml</value>
<value>org/sakaiproject/attendance/hbm/GradingRule.hbm.xml</value>
</list>
</property>

</bean>

<!-- Cache: ttl=1 hour -->
Expand Down
17 changes: 3 additions & 14 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -78,29 +78,18 @@
<dependency>
<groupId>org.apache.wicket</groupId>
<artifactId>wicket</artifactId>
<version>9.17.0</version>
<version>9.19.0</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.apache.wicket</groupId>
<artifactId>wicket-spring</artifactId>
<version>9.17.0</version>
<version>9.19.0</version>
</dependency>
<dependency>
<groupId>org.apache.wicket</groupId>
<artifactId>wicket-extensions</artifactId>
<version>9.17.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-configuration2</artifactId>
<version>${sakai.commons.configuration2.version}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
<version>9.19.0</version>
</dependency>
</dependencies>
</dependencyManagement>
Expand Down
Loading

0 comments on commit 49b5202

Please sign in to comment.