001 package net.sf.cpsolver.exam.reports; 002 003 import java.util.Enumeration; 004 import java.util.Iterator; 005 006 import net.sf.cpsolver.exam.model.Exam; 007 import net.sf.cpsolver.exam.model.ExamModel; 008 import net.sf.cpsolver.exam.model.ExamOwner; 009 import net.sf.cpsolver.exam.model.ExamPeriod; 010 import net.sf.cpsolver.exam.model.ExamPlacement; 011 import net.sf.cpsolver.exam.model.ExamRoomPlacement; 012 import net.sf.cpsolver.exam.model.ExamStudent; 013 import net.sf.cpsolver.ifs.util.CSVFile; 014 import net.sf.cpsolver.ifs.util.CSVFile.CSVField; 015 016 /** 017 * Export student direct, back-to-back, and more than two exams a day conflicts 018 * into a CSV file. 019 * <br><br> 020 * Usage:<br> 021 * <code> 022 * new ExamStudentConflicts(model).report().save(file); 023 * </code> 024 * <br><br> 025 * 026 * @version 027 * ExamTT 1.1 (Examination Timetabling)<br> 028 * Copyright (C) 2008 Tomáš Müller<br> 029 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br> 030 * Lazenska 391, 76314 Zlin, Czech Republic<br> 031 * <br> 032 * This library is free software; you can redistribute it and/or 033 * modify it under the terms of the GNU Lesser General Public 034 * License as published by the Free Software Foundation; either 035 * version 2.1 of the License, or (at your option) any later version. 036 * <br><br> 037 * This library is distributed in the hope that it will be useful, 038 * but WITHOUT ANY WARRANTY; without even the implied warranty of 039 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 040 * Lesser General Public License for more details. 041 * <br><br> 042 * You should have received a copy of the GNU Lesser General Public 043 * License along with this library; if not, write to the Free Software 044 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 045 */ 046 public class ExamStudentConflicts { 047 private ExamModel iModel = null; 048 049 /** 050 * Constructor 051 * @param model examination timetabling model 052 */ 053 public ExamStudentConflicts(ExamModel model) { 054 iModel = model; 055 } 056 057 /** 058 * generate report 059 */ 060 public CSVFile report() { 061 CSVFile csv = new CSVFile(); 062 csv.setHeader(new CSVField[] { 063 new CSVField("Student"), 064 new CSVField("Type"), 065 new CSVField("Section/Course"), 066 new CSVField("Period"), 067 new CSVField("Day"), 068 new CSVField("Time"), 069 new CSVField("Room"), 070 new CSVField("Distance") 071 }); 072 for (Enumeration e=iModel.getStudents().elements();e.hasMoreElements();) { 073 ExamStudent student = (ExamStudent)e.nextElement(); 074 for (Enumeration f=iModel.getPeriods().elements();f.hasMoreElements();) { 075 ExamPeriod period = (ExamPeriod)f.nextElement(); 076 int nrExams = student.getExams(period).size(); 077 if (nrExams>1) { 078 String sections = ""; 079 String rooms = ""; 080 String periods = String.valueOf(period.getIndex()+1); 081 String periodDays = period.getDayStr(); 082 String periodTimes = period.getTimeStr(); 083 for (Iterator i=student.getExams(period).iterator();i.hasNext();) { 084 Exam exam = (Exam)i.next(); 085 ExamPlacement placement = (ExamPlacement)exam.getAssignment(); 086 String roomsThisExam = ""; 087 for (Iterator j=placement.getRoomPlacements().iterator();j.hasNext();) { 088 ExamRoomPlacement room = (ExamRoomPlacement)j.next(); 089 if (roomsThisExam.length()>0) roomsThisExam+=", "; 090 roomsThisExam+=room.getName(); 091 } 092 boolean first = true; 093 for (Enumeration g=exam.getOwners(student).elements();g.hasMoreElements();){ 094 ExamOwner cs = (ExamOwner)g.nextElement(); 095 if (sections.length()>0) { 096 sections+="\n"; rooms+="\n"; 097 periods+="\n"; periodDays+="\n"; periodTimes+="\n"; 098 } 099 sections += cs.getName(); 100 if (first) rooms += roomsThisExam; 101 first = false; 102 } 103 if (exam.getOwners(student).isEmpty()) { 104 sections += exam.getName(); 105 rooms += roomsThisExam; 106 } 107 } 108 csv.addLine(new CSVField[] { 109 new CSVField(student.getName()), 110 new CSVField("direct"), 111 new CSVField(sections), 112 new CSVField(periods), 113 new CSVField(periodDays), 114 new CSVField(periodTimes), 115 new CSVField(rooms) 116 }); 117 } 118 if (nrExams>0) { 119 if (period.next()!=null && !student.getExams(period.next()).isEmpty() && (!iModel.isDayBreakBackToBack() || period.next().getDay()==period.getDay())) { 120 for (Iterator i=student.getExams(period).iterator();i.hasNext();) { 121 Exam ex1 = (Exam)i.next(); 122 for (Iterator j=student.getExams(period.next()).iterator();j.hasNext();) { 123 Exam ex2 = (Exam)j.next(); 124 ExamPlacement placement = (ExamPlacement)ex1.getAssignment(); 125 String sections = ""; 126 String rooms = ""; 127 String roomsThisExam = ""; 128 String periods = String.valueOf(period.getIndex()+1); 129 String periodDays = period.getDayStr(); 130 String periodTimes = period.getTimeStr(); 131 for (Iterator k=placement.getRoomPlacements().iterator();k.hasNext();) { 132 ExamRoomPlacement room = (ExamRoomPlacement)k.next(); 133 if (roomsThisExam.length()>0) roomsThisExam+=", "; 134 roomsThisExam+=room.getName(); 135 } 136 boolean first = true; 137 for (Enumeration g=ex1.getOwners(student).elements();g.hasMoreElements();){ 138 ExamOwner cs = (ExamOwner)g.nextElement(); 139 if (sections.length()>0) { 140 sections+="\n"; rooms+="\n"; 141 periods+="\n"; periodDays+="\n"; periodTimes+="\n"; 142 } 143 sections += cs.getName(); 144 if (first) rooms += roomsThisExam; 145 first = false; 146 } 147 if (ex1.getOwners(student).isEmpty()) { 148 sections += ex1.getName(); 149 rooms += roomsThisExam; 150 } 151 placement = (ExamPlacement)ex2.getAssignment(); 152 roomsThisExam = ""; 153 for (Iterator k=placement.getRoomPlacements().iterator();k.hasNext();) { 154 ExamRoomPlacement room = (ExamRoomPlacement)k.next(); 155 if (roomsThisExam.length()>0) roomsThisExam+=", "; 156 roomsThisExam+=room.getName(); 157 } 158 first = true; 159 for (Enumeration g=ex2.getOwners(student).elements();g.hasMoreElements();){ 160 ExamOwner cs = (ExamOwner)g.nextElement(); 161 sections+="\n"; rooms+="\n"; periods+="\n"; periodDays+="\n"; periodTimes+="\n"; 162 sections += cs.getName(); 163 if (first) { 164 rooms += roomsThisExam; 165 periods += String.valueOf(period.next().getIndex()+1); 166 periodDays += period.next().getDayStr(); 167 periodTimes += period.next().getTimeStr(); 168 } 169 first = false; 170 } 171 if (ex2.getOwners(student).isEmpty()) { 172 sections+="\n"; rooms+="\n"; periods+="\n"; periodDays+="\n"; periodTimes+="\n"; 173 sections += ex2.getName(); 174 rooms += roomsThisExam; 175 periods += String.valueOf(period.next().getIndex()+1); 176 periodDays += period.next().getDayStr(); 177 periodTimes += period.next().getTimeStr(); 178 rooms += roomsThisExam; 179 } 180 String distStr=""; 181 if (iModel.getBackToBackDistance()>=0) { 182 int dist = ((ExamPlacement)ex1.getAssignment()).getDistance((ExamPlacement)ex2.getAssignment()); 183 if (dist>0) distStr = String.valueOf(dist); 184 } 185 csv.addLine(new CSVField[] { 186 new CSVField(student.getName()), 187 new CSVField("back-to-back"), 188 new CSVField(sections), 189 new CSVField(periods), 190 new CSVField(periodDays), 191 new CSVField(periodTimes), 192 new CSVField(rooms), 193 new CSVField(distStr) 194 }); 195 } 196 } 197 } 198 } 199 if (period.next()==null || period.next().getDay()!=period.getDay()) { 200 int nrExamsADay = student.getExamsADay(period.getDay()).size(); 201 if (nrExamsADay>2) { 202 String sections = ""; 203 String periods = ""; 204 String periodDays = ""; 205 String periodTimes = ""; 206 String rooms = ""; 207 for (Iterator i=student.getExamsADay(period.getDay()).iterator();i.hasNext();) { 208 Exam exam = (Exam)i.next(); 209 ExamPlacement placement = (ExamPlacement)exam.getAssignment(); 210 String roomsThisExam = ""; 211 for (Iterator k=placement.getRoomPlacements().iterator();k.hasNext();) { 212 ExamRoomPlacement room = (ExamRoomPlacement)k.next(); 213 if (roomsThisExam.length()>0) roomsThisExam+=", "; 214 roomsThisExam+=room.getName(); 215 } 216 boolean first = true; 217 for (Enumeration g=exam.getOwners(student).elements();g.hasMoreElements();){ 218 ExamOwner cs = (ExamOwner)g.nextElement(); 219 if (sections.length()>0) { 220 sections+="\n"; rooms+="\n"; 221 periods+="\n"; periodDays+="\n"; periodTimes+="\n"; 222 } 223 sections += cs.getName(); 224 if (first) { 225 periods += (placement.getPeriod().getIndex()+1); 226 periodDays += placement.getPeriod().getDayStr(); 227 periodTimes += placement.getPeriod().getTimeStr(); 228 rooms += roomsThisExam; 229 } 230 first = false; 231 } 232 if (exam.getOwners(student).isEmpty()) { 233 if (sections.length()>0) { 234 sections+="\n"; rooms+="\n"; 235 periods+="\n"; periodDays+="\n"; periodTimes+="\n"; 236 } 237 sections += exam.getName(); 238 periods += (placement.getPeriod().getIndex()+1); 239 periodDays += placement.getPeriod().getDayStr(); 240 periodTimes += placement.getPeriod().getTimeStr(); 241 rooms += roomsThisExam; 242 } 243 } 244 csv.addLine(new CSVField[] { 245 new CSVField(student.getName()), 246 new CSVField("more-2-day"), 247 new CSVField(sections), 248 new CSVField(periods), 249 new CSVField(periodDays), 250 new CSVField(periodTimes), 251 new CSVField(rooms) 252 }); 253 } 254 } 255 } 256 } 257 return csv; 258 } 259 }