package org.sakaiproject.tool.gradebook; import java.io.Serializable; import java.math.BigDecimal; import java.util.Comparator; import java.util.List; import org.sakaiproject.service.gradebook.shared.GradebookService; public class Category implements Serializable { private Long id; private int version; private Gradebook gradebook; private String name; private Double weight; private Integer drop_lowest; private Integer dropHighest; private Integer keepHighest; private Double itemValue; private boolean removed; private Double averageTotalPoints; //average total points possible for this category private Double averageScore; //average scores that students got for this category private Double mean; //mean value of percentage for this category private Double totalPointsEarned; //scores that students got for this category private Double totalPointsPossible; //total points possible for this category private List assignmentList; private int assignmentCount; private Boolean extraCredit = false; private Boolean unweighted; private Boolean equalWeightAssignments; private Integer categoryOrder; private Boolean enforcePointWeighting; public static Comparator nameComparator; public static Comparator averageScoreComparator; public static Comparator weightComparator; public static String SORT_BY_NAME = "name"; public static String SORT_BY_AVERAGE_SCORE = "averageScore"; public static String SORT_BY_WEIGHT = "weight"; static { nameComparator = new Comparator() { public int compare(Object o1, Object o2) { return ((Category)o1).getName().toLowerCase().compareTo(((Category)o2).getName().toLowerCase()); } }; averageScoreComparator = new Comparator() { public int compare(Object o1, Object o2) { Category one = (Category)o1; Category two = (Category)o2; if(one.getAverageScore() == null && two.getAverageScore() == null) { return one.getName().compareTo(two.getName()); } if(one.getAverageScore() == null) { return -1; } if(two.getAverageScore() == null) { return 1; } int comp = (one.getAverageScore().compareTo(two.getAverageScore())); if(comp == 0) { return one.getName().compareTo(two.getName()); } else { return comp; } } }; weightComparator = new Comparator() { public int compare(Object o1, Object o2) { Category one = (Category)o1; Category two = (Category)o2; if(one.getWeight() == null && two.getWeight() == null) { return one.getName().compareTo(two.getName()); } if(one.getWeight() == null) { return -1; } if(two.getWeight() == null) { return 1; } int comp = (one.getWeight().compareTo(two.getWeight())); if(comp == 0) { return one.getName().compareTo(two.getName()); } else { return comp; } } }; } public Integer getDropHighest() { return dropHighest == null ? 0 : dropHighest; } public void setDropHighest(Integer dropHighest) { this.dropHighest = dropHighest; } public Integer getKeepHighest() { return keepHighest == null ? 0 : keepHighest; } public void setKeepHighest(Integer keepHighest) { this.keepHighest = keepHighest; } /* * returns true if this category drops any scores */ public boolean isDropScores() { return getDrop_lowest() > 0 || getDropHighest() > 0 || getKeepHighest() > 0; } public Double getItemValue() { if(isAssignmentsEqual()){ Double returnVal = 0.0; List assignments = getAssignmentList(); if(assignments != null){ for(Object obj : assignments) { if(obj instanceof Assignment) { Assignment assignment = (Assignment)obj; if(!Assignment.item_type_adjustment.equals(assignment.getItemType())) {// ignore adjustment items returnVal = assignment.getPointsPossible(); return returnVal; } } } } //didn't find any, so return 0.0 return returnVal; }else{ return 0.0; } } public Integer getDrop_lowest() { return drop_lowest != null ? drop_lowest : 0; } public void setDrop_lowest(Integer drop_lowest) { this.drop_lowest = drop_lowest; } public Gradebook getGradebook() { return gradebook; } public void setGradebook(Gradebook gradebook) { this.gradebook = gradebook; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { // SAK-20071 - names over 255 chars cause DB insert failure if (name != null && name.length() > 250) { // truncate the name to only 250 chars name = name.substring(0, 249); } this.name = name; } public int getVersion() { return version; } public void setVersion(int version) { this.version = version; } public Double getWeight() { return weight; } public void setWeight(Double weight) { this.weight = weight; } public boolean isRemoved() { return removed; } public void setRemoved(boolean removed) { this.removed = removed; } public Double getAverageTotalPoints() { return averageTotalPoints; } public void setAverageTotalPoints(Double averageTotalPoints) { this.averageTotalPoints = averageTotalPoints; } public Double getAverageScore() { return averageScore; } public void setAverageScore(Double averageScore) { this.averageScore = averageScore; } public void calculateStatistics(List<Assignment> assignmentsWithStats) { int gbGradeType = getGradebook().getGrade_type(); int numScored = 0; int numOfAssignments = 0; BigDecimal total = new BigDecimal("0"); BigDecimal totalPossible = new BigDecimal("0"); BigDecimal adjustmentPoints = new BigDecimal("0"); for (Assignment assign : assignmentsWithStats) { Double score = assign.getAverageTotal(); // if(assign.isReleased()) // { boolean adjustmentItemWithNoPoints = false; if(assign.isCounted() && !assign.getUngraded() && assign.getPointsPossible() != null && assign.getPointsPossible().doubleValue() > 0.0) { if (score == null) { } else { total = total.add(new BigDecimal(score.toString())); if(assign.getPointsPossible() != null && !assign.isExtraCredit()) { totalPossible = totalPossible.add(new BigDecimal(assign.getPointsPossible().toString())); numOfAssignments ++; } if(!assign.isExtraCredit()){ numScored++; } } } // } } if (numScored == 0 || numOfAssignments == 0) { averageScore = null; averageTotalPoints = null; mean = null; totalPointsEarned = null; totalPointsPossible = null; } else { BigDecimal bdNumScored = new BigDecimal(numScored); BigDecimal bdNumAssign = new BigDecimal(numOfAssignments); averageScore = Double.valueOf(total.divide(bdNumScored, GradebookService.MATH_CONTEXT).doubleValue()); averageTotalPoints = Double.valueOf(totalPossible.divide(bdNumAssign, GradebookService.MATH_CONTEXT).doubleValue()); BigDecimal value = total.divide(bdNumScored, GradebookService.MATH_CONTEXT).divide(new BigDecimal(averageTotalPoints.doubleValue()), GradebookService.MATH_CONTEXT).multiply(new BigDecimal("100")); mean = Double.valueOf(value.doubleValue()) ; } } public void calculateStatisticsPerStudent(List<AssignmentGradeRecord> gradeRecords, String studentUid) { int gbGradeType = getGradebook().getGrade_type(); int numScored = 0; int numOfAssignments = 0; BigDecimal total = new BigDecimal("0"); BigDecimal totalPossible = new BigDecimal("0"); BigDecimal adjustmentPoints = new BigDecimal("0"); if (gradeRecords == null) { setAverageScore(null); setAverageTotalPoints(null); setMean(null); setTotalPointsEarned(null); setTotalPointsPossible(null); return; } for (AssignmentGradeRecord gradeRecord : gradeRecords) { if(gradeRecord != null && gradeRecord.getStudentId().equals(studentUid)) { Assignment assignment = gradeRecord.getAssignment(); boolean adjustmentItemWithNoPoints = false; if (assignment.isCounted() && !assignment.getUngraded() && assignment.getPointsPossible().doubleValue() > 0.0 && !gradeRecord.getDroppedFromGrade()) { Category assignCategory = assignment.getCategory(); if (assignCategory != null && assignCategory.getId().equals(id)) { Double score = gradeRecord.getPointsEarned(); if (score != null) { BigDecimal bdScore = new BigDecimal(score.toString()); total = total.add(bdScore); if(assignment.getPointsPossible() != null && !assignment.isExtraCredit() && !assignCategory.isExtraCredit()) { BigDecimal bdPointsPossible = new BigDecimal(assignment.getPointsPossible().toString()); totalPossible = totalPossible.add(bdPointsPossible); numOfAssignments ++; } if(!assignment.isExtraCredit() && !assignCategory.isExtraCredit()){ numScored++; } } } } } } // if totalPossible is 0, this prevents a division by zero scenario likely from // an adjustment item being the only thing graded. if (numScored == 0 || numOfAssignments == 0 || totalPossible.doubleValue() == 0) { averageScore = null; averageTotalPoints = null; mean = null; totalPointsEarned = null; totalPointsPossible = null; } else { BigDecimal bdNumScored = new BigDecimal(numScored); BigDecimal bdNumAssign = new BigDecimal(numOfAssignments); averageScore = Double.valueOf(total.divide(bdNumScored, GradebookService.MATH_CONTEXT).doubleValue()); averageTotalPoints = Double.valueOf(totalPossible.divide(bdNumAssign, GradebookService.MATH_CONTEXT).doubleValue()); BigDecimal value = total.divide(bdNumScored, GradebookService.MATH_CONTEXT).divide((totalPossible.divide(bdNumAssign, GradebookService.MATH_CONTEXT)), GradebookService.MATH_CONTEXT).multiply(new BigDecimal("100")); mean = Double.valueOf(value.doubleValue()) ; } } public List getAssignmentList() { return assignmentList; } public void setAssignmentList(List assignmentList) { this.assignmentList = assignmentList; } /* * The methods below are used with the GradableObjects because all three * are displayed in a dataTable together */ public boolean getIsCategory() { return true; } public boolean isCourseGrade() { return false; } public boolean isAssignment() { return false; } public Double getMean() { return mean; } public void setMean(Double mean) { this.mean = mean; } public int getAssignmentCount(){ return assignmentCount; } public void setAssignmentCount(int assignmentCount){ this.assignmentCount = assignmentCount; } //these two functions are needed to keep the old API and help JSF and RSF play nicely together. Since isExtraCredit already exists and we can't remove it //and JSF expects Boolean values to be "getExtraCredit", this had to be added for JSF. Also, since the external GB create item page is in //RSF, you can't name it getExtraCredit and keep isExtraCredit b/c of SAK-14589 public Boolean getIsExtraCredit(){ return isExtraCredit(); } public void setIsExtraCredit(Boolean isExtraCredit){ this.setExtraCredit(isExtraCredit); } public Boolean isExtraCredit() { return extraCredit; } public void setExtraCredit(Boolean isExtraCredit) { this.extraCredit = isExtraCredit; } public boolean isAssignmentsEqual() { boolean isEqual = true; Double pointsPossible = null; List assignments = getAssignmentList(); if(assignments == null) { return isEqual; } else { for(Object obj : assignments) { if(obj instanceof Assignment) { Assignment assignment = (Assignment)obj; if(pointsPossible == null) { if(!Assignment.item_type_adjustment.equals(assignment.getItemType())) {// ignore adjustment items pointsPossible = assignment.getPointsPossible(); } } else { if(assignment.getPointsPossible() != null && !Assignment.item_type_adjustment.equals(assignment.getItemType()) // ignore adjustment items that are not equal && !pointsPossible.equals(assignment.getPointsPossible())) { isEqual = false; return isEqual; } } } } } return isEqual; } public Boolean isUnweighted() { return unweighted; } public void setUnweighted(Boolean unweighted) { this.unweighted = unweighted; } public Boolean isEqualWeightAssignments() { return equalWeightAssignments; } public void setEqualWeightAssignments(Boolean equalWeightAssignments) { this.equalWeightAssignments = equalWeightAssignments; } public Integer getCategoryOrder() { return categoryOrder; } public void setCategoryOrder(Integer categoryOrder) { this.categoryOrder = categoryOrder; } public Boolean isEnforcePointWeighting() { return enforcePointWeighting; } public void setEnforcePointWeighting(Boolean enforcePointWeighting) { this.enforcePointWeighting = enforcePointWeighting; } public Double getTotalPointsEarned() { return totalPointsEarned; } public void setTotalPointsEarned(Double totalPointsEarned) { this.totalPointsEarned = totalPointsEarned; } public Double getTotalPointsPossible() { return totalPointsPossible; } public void setTotalPointsPossible(Double totalPointsPossible) { this.totalPointsPossible = totalPointsPossible; } }