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