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}