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            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    }