001package org.cpsolver.instructor.test;
002
003import java.io.File;
004import java.io.IOException;
005import java.io.PrintWriter;
006import java.text.DecimalFormat;
007import java.util.Iterator;
008import java.util.TreeSet;
009
010import org.cpsolver.coursett.Constants;
011import org.cpsolver.ifs.assignment.Assignment;
012import org.cpsolver.ifs.util.DataProperties;
013import org.cpsolver.ifs.util.ToolBox;
014import org.cpsolver.instructor.Test;
015import org.cpsolver.instructor.model.Attribute;
016import org.cpsolver.instructor.model.Course;
017import org.cpsolver.instructor.model.Instructor;
018import org.cpsolver.instructor.model.Preference;
019import org.cpsolver.instructor.model.Section;
020import org.cpsolver.instructor.model.TeachingAssignment;
021import org.cpsolver.instructor.model.TeachingRequest;
022
023/**
024 * General chemistry teaching assistants test. No soft constraints at the moment.
025 * 
026 * @version IFS 1.3 (Instructor Sectioning)<br>
027 *          Copyright (C) 2016 Tomáš Müller<br>
028 *          <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
029 *          <a href="http://muller.unitime.org">http://muller.unitime.org</a><br>
030 * <br>
031 *          This library is free software; you can redistribute it and/or modify
032 *          it under the terms of the GNU Lesser General Public License as
033 *          published by the Free Software Foundation; either version 3 of the
034 *          License, or (at your option) any later version. <br>
035 * <br>
036 *          This library is distributed in the hope that it will be useful, but
037 *          WITHOUT ANY WARRANTY; without even the implied warranty of
038 *          MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
039 *          Lesser General Public License for more details. <br>
040 * <br>
041 *          You should have received a copy of the GNU Lesser General Public
042 *          License along with this library; if not see
043 *          <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>.
044 */
045public class ChmTest extends Test {
046    
047    public ChmTest(DataProperties properties) {
048        super(properties);
049    }
050    
051    public String getAttributes(TeachingRequest req, String type) {
052        TreeSet<String> attributes = new TreeSet<String>();
053        for (Preference<Attribute> attribute: req.getAttributePreferences())
054            if (attribute.getTarget().getType().getTypeName().equals(type)) {
055                attributes.add(attribute.getTarget().getAttributeName());// + (attribute.isRequired() ? "" : ":" + Constants.preferenceLevel2preference(attribute.getPreference())));
056            }
057        StringBuffer s = new StringBuffer();
058        for (String attribute: attributes) {
059            if (s.length() > 0) s.append(",");
060            s.append(attribute);
061        }
062        return s.toString();
063    }
064    
065    public String getAttributes(Instructor instructor, String type) {
066        TreeSet<String> attributes = new TreeSet<String>();
067        for (Attribute attribute: instructor.getAttributes())
068            if (attribute.getType().getTypeName().equals(type)) {
069                attributes.add(attribute.getAttributeName());
070            }
071        StringBuffer s = new StringBuffer();
072        if ("Qualification".equals(type))
073            for (Preference<Course> p: instructor.getCoursePreferences())
074                attributes.remove(p.getTarget().getCourseName().substring(4));
075        for (String attribute: attributes) {
076            // if ("00000".equals(attribute)) continue;
077            if (s.length() > 0) s.append(",");
078            s.append(attribute);
079        }
080        return s.toString();
081    }
082    
083    public String getCoursePrefs(Instructor instructor) {
084        TreeSet<String> attributes = new TreeSet<String>();
085        for (Preference<Course> p: instructor.getCoursePreferences())
086            attributes.add(p.getTarget().getCourseName().substring(4));
087        StringBuffer s = new StringBuffer();
088        for (String attribute: attributes) {
089            if (s.length() > 0) s.append(",");
090            s.append(attribute);
091        }
092        return s.toString();
093    }
094    
095    public String getCoursePreference(TeachingRequest req, Instructor instructor) {
096        Preference<Course> p = instructor.getCoursePreference(req.getCourse());
097        if (p.getPreference() == 0) return "";
098        String pref = Constants.preferenceLevel2preference(p.getPreference());
099        if ("R".equals(pref)) return "Yes (SUPER)";
100        if ("-2".equals(pref)) return "Yes";
101        if ("-1".equals(pref)) return "Organic Lab";
102        return pref;
103    }
104    
105    public String getAttributes(TeachingRequest req, Instructor instructor, String type) {
106        TreeSet<String> attributes = new TreeSet<String>();
107        for (Preference<Attribute> attribute: req.getAttributePreferences())
108            if (instructor.getAttributes().contains(attribute.getTarget()))
109                if (attribute.getTarget().getType().getTypeName().equals(type)) {
110                    attributes.add(attribute.getTarget().getAttributeName());
111                }
112        StringBuffer s = new StringBuffer();
113        for (String attribute: attributes) {
114            // if ("00000".equals(attribute)) continue;
115            if (s.length() > 0) s.append(",");
116            s.append(attribute);
117        }
118        if (attributes.isEmpty())
119            s.append("no match");
120        return s.toString();
121    }
122    
123    @Override
124    protected void generateReports(File dir, Assignment<TeachingRequest.Variable, TeachingAssignment> assignment) throws IOException {
125        PrintWriter out = new PrintWriter(new File(dir, "solution-assignments.csv"));
126        out.println("Course,Sections,Time,Room,Skill,Qualification,Performance,Load,Student,Name,Not Available,Max Load,Skill,Qualification,Performance,Requested");
127        for (TeachingRequest.Variable request : variables()) {
128            out.print(request.getCourse().getCourseName());
129            String sect = "", time = "", room = "";
130            if (request.getId() < 0) {
131                out.print(",\"SUPER\",,");
132            } else {
133                for (Iterator<Section> i = request.getSections().iterator(); i.hasNext(); ) {
134                    Section section = i.next();
135                    // if (section.isCommon() && section.isAllowOverlap()) continue;
136                    if (!sect.isEmpty()) { sect += ", "; time += ", "; room += ", "; }
137                    sect += (section.isCommon() ? "(" : "") + section.getSectionType() + " " + section.getExternalId() + (section.isCommon() ? ")" : "") ;
138                    time += (section.getTime() == null ? "-" : section.getTime().getDayHeader() + " " + section.getTime().getStartTimeHeader(true) + "-" + section.getTime().getEndTimeHeader(true));
139                    room += (section.getRoom() == null ? "-" : section.getRoom());
140                }
141                out.print(",\"" + sect + "\",\"" + time + "\",\"" + room + "\"");
142            }
143            out.print(",\"" + getAttributes(request.getRequest(), "Skill") + "\"");
144            out.print(",\"" + getAttributes(request.getRequest(), "Qualification") + "\"");
145            out.print(",\"" + getAttributes(request.getRequest(), "Performance Level") + "\"");
146            out.print("," + new DecimalFormat("0.0").format(request.getRequest().getLoad()));
147            TeachingAssignment ta = assignment.getValue(request);
148            if (ta != null) {
149                Instructor instructor = ta.getInstructor();
150                out.print("," + instructor.getExternalId());
151                out.print(",\"" + instructor.getName() + "\"");
152                out.print(",\"" + instructor.getAvailable() + "\"");
153                out.print("," + new DecimalFormat("0.0").format(instructor.getMaxLoad()));
154                out.print(",\"" + getAttributes(request.getRequest(), instructor, "Skill") + "\"");
155                out.print(",\"" + getAttributes(request.getRequest(), instructor, "Qualification") + "\"");
156                out.print(",\"" + getAttributes(request.getRequest(), instructor, "Performance Level") + "\"");
157                out.print(",\"" + getCoursePreference(request.getRequest(), instructor) + "\"");
158            }
159            out.println();
160        }
161        out.flush();
162        out.close();
163
164        out = new PrintWriter(new File(dir, "solution-students.csv"));
165        out.println("Student,Name,Not Available,Skill,Qualification,Performance,Requests,Max Load,Assigned Load,1st Assignment,2nd Assignment,Skill,Qualification,Performance,Requested");
166        for (Instructor instructor: getInstructors()) {
167            out.print(instructor.getExternalId());
168            out.print(",\"" + instructor.getName() + "\"");
169            out.print(",\"" + instructor.getAvailable() + "\"");
170            out.print(",\"" + getAttributes(instructor, "Skill") + "\"");
171            out.print(",\"" + getAttributes(instructor, "Qualification") + "\"");
172            out.print(",\"" + getAttributes(instructor, "Performance Level") + "\"");
173            out.print(",\"" + getCoursePrefs(instructor) + "\"");
174            out.print("," + new DecimalFormat("0.0").format(instructor.getMaxLoad()));
175            Instructor.Context context = instructor.getContext(assignment);
176            out.print("," + new DecimalFormat("0.0").format(context.getLoad()));
177            /*
178            out.print("," + (context.countBackToBackPercentage() == 0.0 ? "" : new DecimalFormat("0.0").format(100.0 * context.countBackToBackPercentage())));
179            out.print("," + (context.countDifferentLectures() == 0.0 ? "" : new DecimalFormat("0.0").format(100.0 * context.countDifferentLectures())));
180            int share = 0;
181            for (TeachingAssignment ta : context.getAssignments()) {
182                for (Preference<TimeLocation> p: instructor.getTimePreferences()) {
183                    if (!p.isProhibited())
184                        share += ta.variable().getRequest().share(p.getTarget());
185                }
186            }
187            out.print("," + (share == 0 ? "" : new DecimalFormat("0.#").format(share / 12.0)));
188            */
189            TeachingRequest req = null;
190            for (TeachingAssignment ta : context.getAssignments()) {
191                String sect = "";
192                if (req == null || req.getRequestId() < 0) req = ta.variable().getRequest();
193                if (ta.variable().getId() < 0) {
194                    sect = "SUPER";
195                } else {
196                    for (Iterator<Section> i = ta.variable().getSections().iterator(); i.hasNext(); ) {
197                        Section section = i.next();
198                        if (section.isCommon() && section.isAllowOverlap()) continue;
199                        sect += (sect.isEmpty() ? "" : ", ") + (section.isCommon() ? "(" : "") +
200                                section.getSectionType() + " " + section.getExternalId() +
201                                (section.getTime() == null ? "" : " " + section.getTime().getDayHeader() + " " + section.getTime().getStartTimeHeader(true) +
202                                "-" + section.getTime().getEndTimeHeader(true))+
203                                (section.isCommon() ? ")" : "");
204                    }
205                }
206                out.print(",\"" + ta.variable().getCourse() + " " + sect + "\"");
207            }
208            if (req != null) {
209                for (int i = context.getAssignments().size(); i < 2; i++) out.print(",");
210                out.print(",\"" + getAttributes(req, instructor, "Skill") + "\"");
211                out.print(",\"" + getAttributes(req, instructor, "Qualification") + "\"");
212                out.print(",\"" + getAttributes(req, instructor, "Performance Level") + "\"");
213                out.print(",\"" + getCoursePreference(req, instructor) + "\"");
214            }
215            out.println();
216        }
217        out.flush();
218        out.close();
219    }
220    
221    public static void main(String[] args) throws Exception {
222        DataProperties config = new DataProperties();
223        config.load(ChmTest.class.getClass().getResourceAsStream("/org/cpsolver/instructor/test/chm.properties"));
224        config.putAll(System.getProperties());
225        ToolBox.configureLogging();
226        
227        new ChmTest(config).execute();
228    }
229}