001    package net.sf.cpsolver.exam.reports;
002    
003    import java.text.DecimalFormat;
004    import java.util.Enumeration;
005    
006    import net.sf.cpsolver.exam.model.Exam;
007    import net.sf.cpsolver.exam.model.ExamModel;
008    import net.sf.cpsolver.exam.model.ExamPlacement;
009    import net.sf.cpsolver.ifs.util.CSVFile;
010    import net.sf.cpsolver.ifs.util.CSVFile.CSVField;
011    
012    /**
013     * Export student direct, back-to-back, and more than two exams a day conflicts
014     * summarized for each exam into a CSV file.
015     * <br><br>
016     * Usage:<br>
017     * <code>
018     * &nbsp;&nbsp;&nbsp;&nbsp;new ExamStudentConflictsPerExam(model).report().save(file);
019     * </code>
020     * <br><br>
021     * 
022     * @version
023     * ExamTT 1.1 (Examination Timetabling)<br>
024     * Copyright (C) 2008 Tomáš Müller<br>
025     * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
026     * Lazenska 391, 76314 Zlin, Czech Republic<br>
027     * <br>
028     * This library is free software; you can redistribute it and/or
029     * modify it under the terms of the GNU Lesser General Public
030     * License as published by the Free Software Foundation; either
031     * version 2.1 of the License, or (at your option) any later version.
032     * <br><br>
033     * This library is distributed in the hope that it will be useful,
034     * but WITHOUT ANY WARRANTY; without even the implied warranty of
035     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
036     * Lesser General Public License for more details.
037     * <br><br>
038     * You should have received a copy of the GNU Lesser General Public
039     * License along with this library; if not, write to the Free Software
040     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
041     */
042    public class ExamStudentConflictsPerExam {
043        private ExamModel iModel = null;
044        
045        /**
046         * Constructor
047         * @param model examination timetabling model
048         */
049        public ExamStudentConflictsPerExam(ExamModel model) {
050            iModel = model;
051        }
052        
053        /**
054         * generate report
055         */
056        public CSVFile report() {
057            CSVFile csv = new CSVFile();
058            csv.setHeader(new CSVField[] {
059                    new CSVField("Exam"),
060                    new CSVField("Enrl"),
061                    new CSVField("Direct"),
062                    new CSVField("Direct [%]"),
063                    new CSVField("More-2-Day"),
064                    new CSVField("More-2-Day [%]"),
065                    new CSVField("Back-To-Back"),
066                    new CSVField("Back-To-Back [%]"),
067                    new CSVField("Dist Back-To-Back"),
068                    new CSVField("Dist Back-To-Back [%]")
069            });
070            DecimalFormat df = new DecimalFormat("0.0");
071            for (Enumeration e=iModel.variables().elements();e.hasMoreElements();) {
072                Exam exam = (Exam)e.nextElement();
073                ExamPlacement placement = (ExamPlacement)exam.getAssignment();
074                if (placement==null) continue;
075                if (placement.getNrDirectConflicts()==0 &&
076                    placement.getNrMoreThanTwoADayConflicts()==0 &&
077                    placement.getNrBackToBackConflicts()==0 &&
078                    placement.getNrDistanceBackToBackConflicts()==0) continue;
079                /*
080                String section = "";
081                for (Enumeration f=exam.getCourseSections().elements();f.hasMoreElements();) {
082                    ExamCourseSection cs = (ExamCourseSection)f.nextElement();
083                    if (section.length()>0) section+="\n";
084                    section += cs.getName();
085                }
086                */
087                csv.addLine(new CSVField[] {
088                        new CSVField(exam.getName()),
089                        new CSVField(exam.getStudents().size()),
090                        new CSVField(placement.getNrDirectConflicts()),
091                        new CSVField(df.format(100.0*placement.getNrDirectConflicts()/exam.getStudents().size())),
092                        new CSVField(placement.getNrMoreThanTwoADayConflicts()),
093                        new CSVField(df.format(100.0*placement.getNrMoreThanTwoADayConflicts()/exam.getStudents().size())),
094                        new CSVField(placement.getNrBackToBackConflicts()),
095                        new CSVField(df.format(100.0*placement.getNrBackToBackConflicts()/exam.getStudents().size())),
096                        new CSVField(placement.getNrDistanceBackToBackConflicts()),
097                        new CSVField(df.format(100.0*placement.getNrDistanceBackToBackConflicts()/exam.getStudents().size()))
098                });
099            }
100            return csv;
101        }
102    }