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