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     * &nbsp;&nbsp;&nbsp;&nbsp;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            for (Enumeration e=iModel.getPeriods().elements();e.hasMoreElements();) {
076                ExamPeriod period = (ExamPeriod)e.nextElement();
077                int nrExams = 0;
078                int nrStudents = 0;
079                int[] nrExamsLim = new int[sLimits.length];
080                int totAvgPer = 0, nrAvgPer = 0, totWgAvgPer = 0;
081                for (int i=0;i<sLimits.length;i++) nrExamsLim[i]=0;
082                for (Enumeration f=iModel.variables().elements();f.hasMoreElements();) {
083                    Exam exam = (Exam)f.nextElement();
084                    ExamPlacement placement = (ExamPlacement)exam.getAssignment();
085                    if (placement==null || !(placement.getPeriod().equals(period))) continue;
086                    nrExams++;
087                    nrStudents+=exam.getStudents().size();
088                    if (exam.getAveragePeriod()>=0) {
089                        totAvgPer += exam.getAveragePeriod(); nrAvgPer ++;
090                        totWgAvgPer += exam.getAveragePeriod() * exam.getStudents().size();
091                    }
092                    for (int i=0;i<sLimits.length;i++)
093                        if (exam.getStudents().size()>=sLimits[i]) nrExamsLim[i]++;
094                }
095                Vector line = new Vector();
096                line.add(new CSVField(period.getIndex()+1));
097                line.add(new CSVField(period.getDayStr()));
098                line.add(new CSVField(period.getTimeStr()));
099                line.add(new CSVField(period.getPenalty()));
100                line.add(new CSVField(nrExams));
101                line.add(new CSVField(nrStudents));
102                for (int i=0;i<sLimits.length;i++)
103                    line.add(new CSVField(nrExamsLim[i]));
104                if (nrAvgPer>0) {
105                    line.add(new CSVField(sDF.format(((double)totAvgPer)/nrAvgPer)));
106                    line.add(new CSVField(sDF.format(((double)totWgAvgPer)/nrAvgPer)));
107                }
108                csv.addLine(line);
109            }
110            return csv;
111        }
112    }