001 package net.sf.cpsolver.exam.reports;
002
003
004 import java.util.ArrayList;
005 import java.util.List;
006
007 import net.sf.cpsolver.exam.criteria.StudentBackToBackConflicts;
008 import net.sf.cpsolver.exam.model.ExamModel;
009 import net.sf.cpsolver.exam.model.ExamPeriod;
010 import net.sf.cpsolver.exam.model.ExamStudent;
011 import net.sf.cpsolver.ifs.util.CSVFile;
012 import net.sf.cpsolver.ifs.util.CSVFile.CSVField;
013
014 /**
015 * Export distribution of number of students by number of meetings per day into
016 * a CSV file. <br>
017 * <br>
018 * Usage:<br>
019 * <code>
020 * new ExamNbrMeetingsPerDay(model).report().save(file);
021 * </code> <br>
022 * <br>
023 *
024 * @version ExamTT 1.2 (Examination Timetabling)<br>
025 * Copyright (C) 2008 - 2010 Tomas Muller<br>
026 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
027 * <a href="http://muller.unitime.org">http://muller.unitime.org</a><br>
028 * <br>
029 * This library is free software; you can redistribute it and/or modify
030 * it under the terms of the GNU Lesser General Public License as
031 * published by the Free Software Foundation; either version 3 of the
032 * License, or (at your option) any later version. <br>
033 * <br>
034 * This library is distributed in the hope that it will be useful, but
035 * WITHOUT ANY WARRANTY; without even the implied warranty of
036 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
037 * Lesser General Public License for more details. <br>
038 * <br>
039 * You should have received a copy of the GNU Lesser General Public
040 * License along with this library; if not see
041 * <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>.
042 */
043 public class ExamNbrMeetingsPerDay {
044 private ExamModel iModel = null;
045
046 /**
047 * Constructor
048 *
049 * @param model
050 * examination timetabling model
051 */
052 public ExamNbrMeetingsPerDay(ExamModel model) {
053 iModel = model;
054 }
055
056 /**
057 * generate report
058 */
059 public CSVFile report() {
060 CSVFile csv = new CSVFile();
061 List<CSVField> header = new ArrayList<CSVField>();
062 header.add(new CSVField("Date"));
063 header.add(new CSVField("None"));
064 boolean isDayBreakBackToBack = ((StudentBackToBackConflicts)iModel.getCriterion(StudentBackToBackConflicts.class)).isDayBreakBackToBack();
065 for (int i = 1; i <= 5; i++)
066 header.add(new CSVField(i == 5 ? "5+" : String.valueOf(i)));
067 header.add(new CSVField("Back-To-Back"));
068 csv.setHeader(header);
069 int[] nrExamsTotal = new int[6];
070 for (int i = 0; i <= 5; i++)
071 nrExamsTotal[i] = 0;
072 int btbTotal = 0;
073 for (int d = 0; d < iModel.getNrDays(); d++) {
074 ExamPeriod period = null;
075 for (ExamPeriod p : iModel.getPeriods()) {
076 if (p.getDay() == d) {
077 period = p;
078 break;
079 }
080 }
081 int[] nrExams = new int[6];
082 for (int i = 0; i <= 5; i++)
083 nrExams[i] = 0;
084 int btb = 0;
085 for (ExamStudent student : iModel.getStudents()) {
086 int ex = student.getExamsADay(d).size();
087 nrExams[ex <= 5 ? ex : 5]++;
088 ExamPeriod p = period;
089 while (p.next() != null && (isDayBreakBackToBack ? p : p.next()).getDay() == d) {
090 btb += student.getExams(p).size() * student.getExams(p.next()).size();
091 p = p.next();
092 }
093 }
094 List<CSVField> line = new ArrayList<CSVField>();
095 line.add(new CSVField(period.getDayStr()));
096 for (int i = 0; i <= 5; i++) {
097 line.add(new CSVField(nrExams[i]));
098 nrExamsTotal[i] += nrExams[i];
099 }
100 line.add(new CSVField(btb));
101 btbTotal += btb;
102 csv.addLine(line);
103 }
104 List<CSVField> line = new ArrayList<CSVField>();
105 line.add(new CSVField("Total"));
106 for (int i = 0; i <= 5; i++)
107 line.add(new CSVField(nrExamsTotal[i]));
108 line.add(new CSVField(btbTotal));
109 csv.addLine(line);
110 return csv;
111 }
112 }