Skip to content

Instantly share code, notes, and snippets.

@maryokhin
Created June 27, 2013 13:25
Show Gist options
  • Save maryokhin/5876368 to your computer and use it in GitHub Desktop.
Save maryokhin/5876368 to your computer and use it in GitHub Desktop.
package main;
import org.supercsv.io.CsvMapReader;
import org.supercsv.io.ICsvMapReader;
import org.supercsv.prefs.CsvPreference;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
//TODO: hardcoded 15 (outlier bounds). Priority: low
/**
* Package management: <read from file, add to List of packages>, <add to map of
* <packageName, MeasuredClass>>
*/
public class Assignment {
/**
* key - package name, value - list of classes in the package. Map of
* package names.
*/
private final Map<String, Package> packages;
/**
* number of metrics
*/
private final transient int qualifiersNumber;
/**
* list of metrics' names
*/
private transient String[] names;
/**
* number of metrics in the line. is read from titles line so titles line
* should not be omitted ;) >= 0
*/
private transient int metricsNumber;
private static boolean fileSet; // keep static or it breaks
private final List<Criterion> criteria;
public Assignment() {
packages = new HashMap<String, Package>();
qualifiersNumber = 4;
metricsNumber = 0;
fileSet = false;
criteria = new ArrayList<Criterion>();
}
/**
* first types names of metrics (column titles), then goes through map
*/
@Override
public String toString() {
final StringBuilder builder = new StringBuilder();
for (final String string : names) {
builder.append(string);
builder.append(' ');
}
builder.append('\n');
final Set<Map.Entry<String, Package>> entries = packages
.entrySet();
for (final Map.Entry<String, Package> entry : entries) {
for (final MeasuredClass measured : entry.getValue().getClasses()) {
builder.append(measured.toString());
builder.append('\n');
}
builder.append('\n');
}
return builder.toString();
}
/**
* use helper library to read data from *.csv file
*
* @param path of data file
*/
public void readDataFile(String path, boolean fullParsing) {
try {
if (!fullParsing) {
parseHeader(path);
} else {
parseData(path);
}
// metricsNumber = (names.length > 2) ? names.length - 2 : 0;
// for (int i = 1; i < data.size(); i++) {
// final MeasuredClass measured = new MeasuredClass(data.get(i), qualifiersNumber);
// final Package list = packages.get(measured.getQualifier());
// if (list == null) {
// addPackage(measured);
// } else {
// list.addClass(measured);
// }
// }
fileSet(true);
} catch (FileNotFoundException ex) {
Logger.getLogger(Assignment.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(Assignment.class.getName()).log(Level.SEVERE, null, ex);
} catch (Exception ex) {
Logger.getLogger(Assignment.class.getName()).log(Level.SEVERE, null, ex);
}
}
/**
* Creates new package with list of classes and adds it to the map
*
* @param measured
*/
private void addPackage(final MeasuredClass measured) {
final Package list = new Package(measured.getQualifier(), metricsNumber);
list.addClass(measured);
packages.put(list.getName(), list);
}
/**
* Only parses header for metric chooser
*
* @param path of CSV file
* @throws Exception
*/
private static void parseHeader(String path) throws Exception {
ICsvMapReader mapReader = null;
try {
mapReader = new CsvMapReader(new FileReader(path), CsvPreference.EXCEL_NORTH_EUROPE_PREFERENCE);
final String[] header = mapReader.getHeader(true);
header[0] = header[1] = null; // skip the first two columns
Metric.MetricName.setMetricNames(header);
System.out.println("header set: " + Arrays.toString(header));
} finally {
if (mapReader != null) {
mapReader.close();
}
}
}
/**
* Parses column of data selectively
*
* @param path of CSV file
* @throws Exception
*/
private static void parseData(String path) throws Exception {
ICsvMapReader mapReader = null;
try {
mapReader = new CsvMapReader(new FileReader(path), CsvPreference.EXCEL_NORTH_EUROPE_PREFERENCE);
final String[] data = Metric.MetricName.getUsedMetrics();
System.out.println("data array: " + Arrays.toString(data));
} finally {
if (mapReader != null) {
mapReader.close();
}
}
}
/**
* Define all 3 types of outliers <br>
* (via three different methods: defineFirstOutlier etc.)<br>
*/
private void defineOutliers() {
// assume that number of metrics in each class is equal and is > 0:
final Set<Map.Entry<String, Package>> entries = packages
.entrySet();
for (int i = 0; i < metricsNumber; i++) {
if (Metric.MetricName.getMetricNames()[i].isUsed()) {
double[] totalMinMax = getTotalMinMax(i);
for (final Map.Entry<String, Package> entry : entries) {
Package pack = entry.getValue();
double max, min;
pack.sortClasses(i);
int number = pack.getClasses().size();
List<MeasuredClass> classes = pack.getClasses();
max = classes.get(0).getMetric(i).getValue();
// first outlier min value is 15th value:
int lowBound = number;
if (lowBound > 15)
lowBound = 15;
min = classes.get(lowBound - 1).getMetric(i).getValue();
pack.setOutlier(Package.FIRST_OUTLIER, i, max, min);
// second outlier min value is 0.85 from (max-min) + min;
min = classes.get(number - 1).getMetric(i).getValue();
min += (max - min) * 0.85;
pack.setOutlier(Package.SECOND_OUTLIER, i, max, min);
// for third outlier: total values
pack.setOutlier(Package.THIRD_OUTLIER, i, totalMinMax[1], totalMinMax[0]);
}
}
}
}
public void aggregateMetric() {
defineOutliers();
for (final Map.Entry<String, Package> entry : packages
.entrySet()) {
entry.getValue().aggregate(criteria);
}
}
/**
* Goes through all packages and finds min and max of given metric. <br>
* min is 0.85*(max-absmin)+absmin, absmin is minimum of metric's values.
*
* @param index metric's index
* @return array of two doubles {min, max};
*/
private double[] getTotalMinMax(int index) {
double min = 0;
double max = 0;
final Set<Map.Entry<String, Package>> entries = packages
.entrySet();
for (final Map.Entry<String, Package> entry : entries) {
for (final MeasuredClass mc : entry.getValue().getClasses()) {
if (min > mc.getMetric(index).getValue())
min = mc.getMetric(index).getValue();
if (max < mc.getMetric(index).getValue())
max = mc.getMetric(index).getValue();
}
}
return new double[]{min + (max - min) * 0.85, max};
}
public String[] getMetricsNames() {
return names;
}
public boolean isFileSet() {
return fileSet;
}
public void fileSet(boolean value) {
fileSet = value;
}
public void addCriterion(final Criterion one) {
criteria.add(one);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment