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 }