Changeset 1493 for trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/RequiredInefficientActionsRule.java
- Timestamp:
- 04/11/14 11:21:45 (10 years ago)
- File:
-
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/RequiredInefficientActionsRule.java
r1335 r1493 15 15 package de.ugoe.cs.autoquest.usability; 16 16 17 import java.text.DecimalFormat;18 17 import java.util.Collection; 19 18 import java.util.HashMap; 20 19 import java.util.Map; 21 20 22 import de.ugoe.cs.autoquest.eventcore.IEventType; 21 import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics; 22 23 import de.ugoe.cs.autoquest.eventcore.Event; 23 24 import de.ugoe.cs.autoquest.eventcore.gui.Scroll; 25 import de.ugoe.cs.autoquest.tasktrees.treeifc.DefaultTaskInstanceTraversingVisitor; 26 import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask; 24 27 import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance; 25 import de.ugoe.cs.autoquest.tasktrees.treeifc.IIterationInstance; 26 import de.ugoe.cs.autoquest.tasktrees.treeifc.IOptionalInstance; 27 import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelectionInstance; 28 import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence; 29 import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequenceInstance; 28 import de.ugoe.cs.autoquest.tasktrees.treeifc.IMarkingTemporalRelationship; 30 29 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask; 31 30 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance; … … 38 37 * @author 2012, last modified by $Author: pharms$ 39 38 */ 40 public class Required ScrollRule implements UsabilityEvaluationRule {39 public class RequiredInefficientActionsRule implements UsabilityEvaluationRule { 41 40 42 41 /* … … 47 46 @Override 48 47 public UsabilityEvaluationResult evaluate(ITaskModel taskModel) { 49 Map<ITask, Integer> smellingTasks = getTasksStartingWithScroll(taskModel.getTasks());48 UsabilityEvaluationResult results = new UsabilityEvaluationResult(taskModel); 50 49 51 UsabilityEvaluationResult results = new UsabilityEvaluationResult();52 analyzeTasks StartingWithScroll(smellingTasks, results);50 Map<ITask, double[]> smellingTasks = getInefficientActionStatistics(taskModel.getTasks()); 51 analyzeTasksWithInefficientActions(smellingTasks, results, taskModel); 53 52 54 53 return results; … … 58 57 * 59 58 */ 60 private void analyzeTasksStartingWithScroll(Map<ITask, Integer> smellingTasks, 61 UsabilityEvaluationResult results) 59 private void analyzeTasksWithInefficientActions(Map<ITask, double[]> smellingTasks, 60 UsabilityEvaluationResult results, 61 ITaskModel taskModel) 62 62 { 63 63 64 for (Map.Entry<ITask, Integer> entry : smellingTasks.entrySet()) { 65 float ratio = entry.getValue() / (float) entry.getKey().getInstances().size(); 64 for (Map.Entry<ITask, double[]> entry : smellingTasks.entrySet()) { 65 DescriptiveStatistics stats = new DescriptiveStatistics(entry.getValue()); 66 67 int ratio = (int) (1000 * stats.getMean()); 66 68 67 UsabilityDefectSeverity severity = null; 68 if (ratio > 0.9) { 69 severity = UsabilityDefectSeverity.HIGH; 70 } 71 else if (ratio > 0.6) { 72 severity = UsabilityDefectSeverity.MEDIUM; 73 } 74 else if (ratio > 0.4) { 75 severity = UsabilityDefectSeverity.LOW; 76 } 77 else if (ratio > 0.2) { 78 severity = UsabilityDefectSeverity.INFO; 79 } 69 UsabilityDefectSeverity severity = UsabilityDefectSeverity.getSeverity 70 (ratio, 500, 300, 200, 100, entry.getKey(), taskModel); 80 71 81 72 if (severity != null) { 82 Map<String, String> parameters = new HashMap<String, String>();83 parameters.put("task", entry.getKey() .toString());84 parameters.put(" scrollRatio", DecimalFormat.getInstance().format(ratio * 100));73 Map<String, Object> parameters = new HashMap<String, Object>(); 74 parameters.put("task", entry.getKey()); 75 parameters.put("ratio", (ratio / 10)); 85 76 86 results.addDefect(severity, UsabilityDefectDescription.SCROLL_REQUIRED, parameters); 77 results.addDefect 78 (severity, UsabilityDefectDescription.INEFFICIENT_ACTIONS, parameters); 87 79 } 88 80 } … … 92 84 * 93 85 */ 94 private Map<ITask, Integer> getTasksStartingWithScroll(Collection<ITask> tasks) {95 Map<ITask, Integer> scrollCounts = new HashMap<ITask, Integer>();86 private Map<ITask, double[]> getInefficientActionStatistics(Collection<ITask> tasks) { 87 Map<ITask, double[]> inefficientActionRatios = new HashMap<ITask, double[]>(); 96 88 97 89 for (ITask task : tasks) { 98 // only sequences are important for required scrolls 99 if (task instanceof ISequence) { 100 int count = countInstancesStartingWithScroll(task); 101 if (count > 0) { 102 scrollCounts.put(task, count); 90 if (taskMustBeChecked(task)) { 91 double[] ratios = getRatiosOfInefficientActionsInInstances(task); 92 93 for (int i = 0; i < ratios.length; i++) { 94 if (ratios[i] > 0) { 95 // there is at least on inefficient action 96 inefficientActionRatios.put(task, ratios); 97 break; 98 } 103 99 } 104 100 } 105 101 } 106 102 107 return scrollCounts;103 return inefficientActionRatios; 108 104 } 109 105 … … 111 107 * 112 108 */ 113 private int countInstancesStartingWithScroll(ITask task) { 114 Collection<ITaskInstance> instances = task.getInstances(); 115 116 int counter = 0; 117 for (ITaskInstance instance : instances) { 118 if (startsWithScroll(instance)) { 119 counter++; 120 } 109 private boolean taskMustBeChecked(ITask task) { 110 if ((task instanceof IEventTask) || (task instanceof IMarkingTemporalRelationship)) { 111 // event tasks are not considered 112 // marking temporal relationships have a child, that is more important, but it will 113 // be checked independently as all tasks of a task model are checked separately 114 return false; 121 115 } 122 123 return counter; 116 else { 117 return true; 118 } 124 119 } 125 120 … … 127 122 * 128 123 */ 129 private boolean startsWithScroll(ITaskInstance instance) { 130 if (instance instanceof ISequenceInstance) { 131 ITaskInstance firstChild = ((ISequenceInstance) instance).size() > 1 ? 132 ((ISequenceInstance) instance).get(0) : null; 133 134 if (firstChild == null) { 135 throw new IllegalArgumentException 136 ("instance of a sequence must have at least two children"); 137 } 138 139 if (startsWithScroll(firstChild)) { 140 return true; 141 } 142 } 143 else if (instance instanceof ISelectionInstance) { 144 ITaskInstance child = ((ISelectionInstance) instance).getChild(); 145 146 if (child != null) { 147 return startsWithScroll(child); 148 } 149 else { 150 throw new IllegalArgumentException("instance of a selection must have a child"); 151 } 152 } 153 else if (instance instanceof IIterationInstance) { 154 ITaskInstance firstChild = ((IIterationInstance) instance).size() > 0 ? 155 ((IIterationInstance) instance).get(0) : null; 156 157 if (firstChild == null) { 158 throw new IllegalArgumentException 159 ("instance of an iteration must have at least one child"); 160 } 161 162 if (startsWithScroll(firstChild)) { 163 return true; 164 } 165 } 166 else if (instance instanceof IOptionalInstance) { 167 ITaskInstance child = ((IOptionalInstance) instance).getChild(); 168 169 if (child != null) { 170 return startsWithScroll(child); 171 } 172 } 173 else if (isScroll(instance)) { 174 return true; 124 private double[] getRatiosOfInefficientActionsInInstances(ITask task) { 125 Collection<ITaskInstance> instances = task.getInstances(); 126 127 double[] ratios = new double[instances.size()]; 128 int index = 0; 129 for (ITaskInstance instance : instances) { 130 ratios[index++] = getRatioOfInefficientActionsInInstance(instance); 175 131 } 176 132 177 return false;133 return ratios; 178 134 } 179 135 180 136 /** 181 * @param firstChild 182 * @return 137 * 183 138 */ 184 private boolean isScroll(ITaskInstance instance) { 185 ITaskInstance instanceToCheck = instance; 139 private double getRatioOfInefficientActionsInInstance(ITaskInstance instance) { 140 final int[] count = new int[2]; 141 count[0] = 0; 142 count[1] = 0; 186 143 187 if (instanceToCheck instanceof IIterationInstance) { 188 instanceToCheck = ((IIterationInstance) instanceToCheck).size() > 0 ? 189 ((IIterationInstance) instanceToCheck).get(0) : null; 144 instance.accept(new DefaultTaskInstanceTraversingVisitor() { 145 @Override 146 public void visit(IEventTaskInstance eventTaskInstance) { 147 if (isInefficientAction(eventTaskInstance.getEvent())) { 148 count[0]++; 149 } 150 151 count[1]++; 152 } 153 154 }); 155 156 return (double) count[0] / count[1]; 157 } 190 158 191 if (instanceToCheck == null) { 192 throw new IllegalArgumentException 193 ("instance of an iteration must have at least one child"); 194 } 195 } 196 197 if (instanceToCheck instanceof IEventTaskInstance) { 198 IEventType type = ((IEventTaskInstance) instanceToCheck).getEvent().getType(); 199 200 return (type instanceof Scroll); 201 } 202 203 return false; 159 /** 160 * 161 */ 162 private boolean isInefficientAction(Event event) { 163 return (event.getType() instanceof Scroll); 204 164 } 205 165
Note: See TracChangeset
for help on using the changeset viewer.