// Copyright 2012 Georg-August-Universität Göttingen, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package de.ugoe.cs.autoquest.plugin.usability2.rules.patterns;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import com.google.common.base.Optional;
import de.ugoe.cs.autoquest.eventcore.Event;
import de.ugoe.cs.autoquest.eventcore.IEventTarget;
import de.ugoe.cs.autoquest.eventcore.IEventType;
import de.ugoe.cs.autoquest.eventcore.gui.MouseClick;
import de.ugoe.cs.autoquest.eventcore.gui.Scroll;
import de.ugoe.cs.autoquest.usability.EvaluationMethodCaller;
import de.ugoe.cs.autoquest.usability.result.UsabilityProblemDescription;
import de.ugoe.cs.autoquest.usability.result.UsabilityProblemDescriptionResolver;
import de.ugoe.cs.autoquest.usability.rules.UsabilityRule;
import de.ugoe.cs.autoquest.usability.rules.UsabilityUsageProblem;
import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel;
/**
*
* Test Rule to see if new pattern method may be used for problem checking
*
*
* @author Konni Hartmann
*/
public class SessionPatternProblem extends UsabilityRule implements UsabilityUsageProblem {
private final Collection> sessions;
/**
*
* TODO: comment
*
*
* @param taskTree
*/
public SessionPatternProblem(ITaskModel taskModel, Collection> sessions) {
super(taskModel);
this.sessions = sessions;
this.name = "PatternProblem";
this.defect =
new UsabilityProblemDescriptionResolver().descriptionFor("PatternProblem");
initUsagePattern();
}
/**
*
* TODO: comment
*
*
*/
private void initUsagePattern() {
}
private class Statistics implements Comparable {
private IEventTarget target;
private int match;
private int all;
public Statistics(IEventTarget target) {
this.target = target;
}
int matchCount() {
return match;
}
int allCount() {
return all;
}
float percent() {
return ((float) matchCount()) / allCount();
}
@Override
public int compareTo(Statistics o) {
float thisPcnt = percent();
float otherPcnt = o.percent();
if (thisPcnt < otherPcnt)
return -1;
if (thisPcnt > otherPcnt)
return 1;
return 0;
}
@Override
public String toString() {
StringBuilder str = new StringBuilder();
str.append(target.getStringIdentifier());
str.append(" (").append(percent()).append(')');
return str.toString();
}
public void increaseCount() {
this.all++;
}
public void increaseMatchCount() {
this.match++;
}
}
/*
* (non-Javadoc)
*
* @see de.ugoe.cs.autoquest.usability.rules.UsabilityRule#check()
*/
@Override
public Optional check() {
Optional present = Optional.absent();
System.out.println("--");
System.out.println("PP:");
Map results = new HashMap();
int cnt = 0, click=0, scroll=0;
for (List events : this.sessions) {
IEventType last = null;
for (Event event : events) {
IEventType type = event.getType();
if (type instanceof MouseClick) {
click++;
IEventTarget target = event.getTarget();
Statistics statistics = results.get(target);
if (statistics == null) {
statistics = new Statistics(target);
results.put(target, statistics);
}
statistics.increaseCount();
if(last != null && last instanceof Scroll) {
scroll++;
statistics.increaseMatchCount();
}
}
last = type;
cnt++;
}
}
System.out.printf("Analyzed %d events with %d clicks and %d scrolls before clicks.\n", cnt, click, scroll);
analyzeResults(results);
/*
* System.out.println("PATTERN2:"); for (ITask task : tasks) { IResult result =
* this.pattern2.match(task);
*
* result = this.pattern2.match(task);
*
* if (result.isPresent()) { present = Optional.of(this.defect);
* System.out.printf("2: %s, %s, %d\n", task.getId(), task.getDescription(), task
* .getInstances().size()); } }
*/
System.out.println("Finished Pattern analysis");
return present;
}
private void analyzeResults(Map results) {
List pcnt95 = new LinkedList();
List pcnt75 = new LinkedList();
List pcnt50 = new LinkedList();
List pcnt25 = new LinkedList();
List pcnt05 = new LinkedList();
for (Statistics s : results.values()) {
float percent = s.percent();
if (percent >= 0.95)
pcnt95.add(s);
else if (percent >= 0.75)
pcnt75.add(s);
else if (percent >= 0.50)
pcnt50.add(s);
else if (percent >= 0.25)
pcnt25.add(s);
else if (percent >= 0.05)
pcnt05.add(s);
}
Comparator reverse = new Comparator() {
@Override
public int compare(Statistics o1, Statistics o2) {
return o2.matchCount() - o1.matchCount();
}
};
Collections.sort(pcnt95, reverse);
Collections.sort(pcnt75, reverse);
Collections.sort(pcnt50, reverse);
Collections.sort(pcnt25, reverse);
Collections.sort(pcnt05, reverse);
printFirstN(pcnt95, 3, 0.95);
printFirstN(pcnt75, 3, 0.75);
printFirstN(pcnt50, 3, 0.50);
printFirstN(pcnt25, 3, 0.25);
printFirstN(pcnt05, 3, 0.05);
}
private void printFirstN(List list, int i, double margin) {
if (!list.isEmpty()) {
System.out.printf(">= %f :\n", margin);
for (int j = 0; j < list.size() && j < i; j++) {
Statistics s = list.get(j);
System.out.printf("%d [%d]: %s\n", j + 1, s.matchCount(), s);
}
if (list.size() >= i) {
Statistics s = list.get(list.size() - 1);
System.out.printf("%d [%d]: %s\n", list.size() - 1, s.matchCount(), s);
}
}
}
/*
* (non-Javadoc)
*
* @see
* de.ugoe.cs.autoquest.usability.rules.UsabilityRule#callEvaluationMetho(de.ugoe.cs.autoquest
* .usability.EvaluationMethodCaller)
*/
@Override
public Optional callEvaluationMethod(EvaluationMethodCaller evaluationMethodCaller)
{
return evaluationMethodCaller.check(this);
}
}