001package org.cpsolver.studentsct.report; 002 003import java.text.DecimalFormat; 004import java.util.Comparator; 005import java.util.TreeSet; 006 007import org.cpsolver.ifs.assignment.Assignment; 008import org.cpsolver.ifs.util.CSVFile; 009import org.cpsolver.ifs.util.DataProperties; 010import org.cpsolver.studentsct.StudentSectioningModel; 011import org.cpsolver.studentsct.model.Config; 012import org.cpsolver.studentsct.model.Course; 013import org.cpsolver.studentsct.model.Enrollment; 014import org.cpsolver.studentsct.model.Offering; 015import org.cpsolver.studentsct.model.Request; 016import org.cpsolver.studentsct.model.RequestGroup; 017import org.cpsolver.studentsct.model.Section; 018import org.cpsolver.studentsct.model.Subpart; 019 020/** 021 * This reports lists all request groups (including course name and group name) and the current spreads. 022 * For each group, the current average spread (see {@link RequestGroup#getAverageSpread(Assignment)}) 023 * is listed together with all the classes that the students of the group are enrolled into and their 024 * spreads (see {@link RequestGroup#getSectionSpread(Assignment, Section)}).<br> 025 * <br> 026 * The average spread corresponds with the probability of two students of the group to attend the same section. 027 * The section spread is a break down of the average spread by each section.<br> 028 * <br> 029 * 030 * 031 * @version StudentSct 1.3 (Student Sectioning)<br> 032 * Copyright (C) 2015 Tomáš Müller<br> 033 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br> 034 * <a href="http://muller.unitime.org">http://muller.unitime.org</a><br> 035 * <br> 036 * This library is free software; you can redistribute it and/or modify 037 * it under the terms of the GNU Lesser General Public License as 038 * published by the Free Software Foundation; either version 3 of the 039 * License, or (at your option) any later version. <br> 040 * <br> 041 * This library is distributed in the hope that it will be useful, but 042 * WITHOUT ANY WARRANTY; without even the implied warranty of 043 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 044 * Lesser General Public License for more details. <br> 045 * <br> 046 * You should have received a copy of the GNU Lesser General Public 047 * License along with this library; if not see 048 * <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>. 049 */ 050public class RequestGroupTable implements StudentSectioningReport { 051 private static DecimalFormat sDF = new DecimalFormat("0.000"); 052 private StudentSectioningModel iModel; 053 054 /** 055 * Constructor 056 * 057 * @param model student sectioning model 058 */ 059 public RequestGroupTable(StudentSectioningModel model) { 060 iModel = model; 061 } 062 063 @Override 064 public CSVFile create(Assignment<Request, Enrollment> assignment, DataProperties properties) { 065 boolean useAmPm = properties.getPropertyBoolean("useAmPm", true); 066 CSVFile csv = new CSVFile(); 067 csv.setHeader(new CSVFile.CSVField[] { 068 new CSVFile.CSVField("Group"), 069 new CSVFile.CSVField("Course"), 070 new CSVFile.CSVField("Total\nSpread"), 071 new CSVFile.CSVField("Group\nEnrollment"), 072 new CSVFile.CSVField("Class"), 073 new CSVFile.CSVField("Meeting Time"), 074 new CSVFile.CSVField("Class\nSpread"), 075 new CSVFile.CSVField("Class\nEnrollment"), 076 new CSVFile.CSVField("Class\nLimit") 077 }); 078 079 TreeSet<RequestGroup> groups = new TreeSet<RequestGroup>(new Comparator<RequestGroup>() { 080 @Override 081 public int compare(RequestGroup g1, RequestGroup g2) { 082 int cmp = g1.getName().compareTo(g2.getName()); 083 if (cmp != 0) return cmp; 084 cmp = g1.getCourse().getName().compareTo(g2.getCourse().getName()); 085 if (cmp != 0) return cmp; 086 if (g1.getId() < g2.getId()) return -1; 087 if (g1.getId() > g2.getId()) return 1; 088 return (g1.getCourse().getId() < g2.getCourse().getId() ? -1 : g1.getCourse().getId() > g2.getCourse().getId() ? 1 : 0); 089 } 090 }); 091 092 for (Offering offering: iModel.getOfferings()) 093 for (Course course: offering.getCourses()) 094 groups.addAll(course.getRequestGroups()); 095 096 for (RequestGroup group: groups) { 097 double groupEnrollment = group.getEnrollmentWeight(assignment, null); 098 double groupSpread = group.getAverageSpread(assignment); 099 for (Config config: group.getCourse().getOffering().getConfigs()) 100 for (Subpart subpart: config.getSubparts()) 101 for (Section section: subpart.getSections()) { 102 double s = group.getSectionWeight(assignment, section, null); 103 if (s > 0.00001) { 104 csv.addLine(new CSVFile.CSVField[] { 105 new CSVFile.CSVField(group.getName()), 106 new CSVFile.CSVField(group.getCourse().getName()), 107 new CSVFile.CSVField(sDF.format(100.0 * groupSpread)), 108 new CSVFile.CSVField(Math.round(groupEnrollment)), 109 new CSVFile.CSVField(section.getSubpart().getName() + " " + section.getName(group.getCourse().getId())), 110 new CSVFile.CSVField(section.getTime() == null ? "" : section.getTime().getDayHeader() + " " + section.getTime().getStartTimeHeader(useAmPm) + " - " + section.getTime().getEndTimeHeader(useAmPm)), 111 new CSVFile.CSVField(sDF.format(100.0 * group.getSectionSpread(assignment, section))), 112 new CSVFile.CSVField(Math.round(group.getSectionWeight(assignment, section, null))), 113 new CSVFile.CSVField(section.getLimit()) 114 }); 115 } 116 } 117 } 118 119 return csv; 120 } 121 122}