001 package net.sf.cpsolver.exam.reports; 002 003 import java.text.DecimalFormat; 004 import java.util.Enumeration; 005 import java.util.Vector; 006 007 import net.sf.cpsolver.exam.model.Exam; 008 import net.sf.cpsolver.exam.model.ExamModel; 009 import net.sf.cpsolver.exam.model.ExamPeriod; 010 import net.sf.cpsolver.exam.model.ExamPlacement; 011 import net.sf.cpsolver.ifs.util.CSVFile; 012 import net.sf.cpsolver.ifs.util.CSVFile.CSVField; 013 014 /** 015 * Export period usage into CSV file. 016 * <br><br> 017 * Usage:<br> 018 * <code> 019 * new ExamPeriodUsage(model).report().save(file); 020 * </code> 021 * <br><br> 022 * 023 * @version 024 * ExamTT 1.1 (Examination Timetabling)<br> 025 * Copyright (C) 2008 Tomáš Müller<br> 026 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br> 027 * Lazenska 391, 76314 Zlin, Czech Republic<br> 028 * <br> 029 * This library is free software; you can redistribute it and/or 030 * modify it under the terms of the GNU Lesser General Public 031 * License as published by the Free Software Foundation; either 032 * version 2.1 of the License, or (at your option) any later version. 033 * <br><br> 034 * This library is distributed in the hope that it will be useful, 035 * but WITHOUT ANY WARRANTY; without even the implied warranty of 036 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 037 * Lesser General Public License for more details. 038 * <br><br> 039 * You should have received a copy of the GNU Lesser General Public 040 * License along with this library; if not, write to the Free Software 041 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 042 */ 043 public class ExamPeriodUsage { 044 private ExamModel iModel = null; 045 /** Exam enrollment limits */ 046 public static int[] sLimits = new int[] {10, 50, 100, 200}; 047 private static DecimalFormat sDF = new DecimalFormat("0.00"); 048 049 /** 050 * Constructor 051 * @param model examination timetabling model 052 */ 053 public ExamPeriodUsage(ExamModel model) { 054 iModel = model; 055 } 056 057 /** 058 * generate report 059 */ 060 public CSVFile report() { 061 CSVFile csv = new CSVFile(); 062 Vector header = new Vector(); 063 header.add(new CSVField("Period")); 064 header.add(new CSVField("Date")); 065 header.add(new CSVField("Time")); 066 header.add(new CSVField("Weight")); 067 header.add(new CSVField("NrExams")); 068 header.add(new CSVField("Students")); 069 for (int i=0;i<sLimits.length;i++) { 070 header.add(new CSVField("NrExams>="+sLimits[i])); 071 } 072 header.add(new CSVField("AvgPeriod")); 073 header.add(new CSVField("WgAvgPeriod")); 074 csv.setHeader(header); 075 DecimalFormat df = new DecimalFormat("0.0"); 076 for (Enumeration e=iModel.getPeriods().elements();e.hasMoreElements();) { 077 ExamPeriod period = (ExamPeriod)e.nextElement(); 078 int nrExams = 0; 079 int nrStudents = 0; 080 int[] nrExamsLim = new int[sLimits.length]; 081 int totAvgPer = 0, nrAvgPer = 0, totWgAvgPer = 0; 082 for (int i=0;i<sLimits.length;i++) nrExamsLim[i]=0; 083 for (Enumeration f=iModel.variables().elements();f.hasMoreElements();) { 084 Exam exam = (Exam)f.nextElement(); 085 ExamPlacement placement = (ExamPlacement)exam.getAssignment(); 086 if (placement==null || !(placement.getPeriod().equals(period))) continue; 087 nrExams++; 088 nrStudents+=exam.getStudents().size(); 089 if (exam.getAveragePeriod()>=0) { 090 totAvgPer += exam.getAveragePeriod(); nrAvgPer ++; 091 totWgAvgPer += exam.getAveragePeriod() * exam.getStudents().size(); 092 } 093 for (int i=0;i<sLimits.length;i++) 094 if (exam.getStudents().size()>=sLimits[i]) nrExamsLim[i]++; 095 } 096 Vector line = new Vector(); 097 line.add(new CSVField(period.getIndex()+1)); 098 line.add(new CSVField(period.getDayStr())); 099 line.add(new CSVField(period.getTimeStr())); 100 line.add(new CSVField(period.getPenalty())); 101 line.add(new CSVField(nrExams)); 102 line.add(new CSVField(nrStudents)); 103 for (int i=0;i<sLimits.length;i++) 104 line.add(new CSVField(nrExamsLim[i])); 105 if (nrAvgPer>0) { 106 line.add(new CSVField(sDF.format(((double)totAvgPer)/nrAvgPer))); 107 line.add(new CSVField(sDF.format(((double)totWgAvgPer)/nrAvgPer))); 108 } 109 csv.addLine(line); 110 } 111 return csv; 112 } 113 }