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}