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 }