Changeset 1493 for trunk/autoquest-core-usability/src/main/java/de
- Timestamp:
- 04/11/14 11:21:45 (11 years ago)
- Location:
- trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability
- Files:
-
- 7 added
- 6 edited
- 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 -
trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/TextInputStatisticsRule.java
r1335 r1493 15 15 package de.ugoe.cs.autoquest.usability; 16 16 17 import java.text.DecimalFormat;18 17 import java.util.ArrayList; 19 18 import java.util.Collection; … … 57 56 calculateStatistics(taskModel.getUserSessions(), statistics); 58 57 59 UsabilityEvaluationResult results = new UsabilityEvaluationResult( );58 UsabilityEvaluationResult results = new UsabilityEvaluationResult(taskModel); 60 59 analyzeStatistics(statistics, results); 61 60 … … 80 79 UsabilityEvaluationResult results) 81 80 { 82 float allTextFieldInputs =81 int allTextFieldInputs = 83 82 statistics.getNoOfTextFieldInputs() + statistics.getNoOfTextAreaInputs(); 84 83 85 float ratio = allTextFieldInputs / (float) statistics.getNoOfAllEvents(); 86 87 UsabilityDefectSeverity severity = null; 88 if (ratio > 0.9) { 89 severity = UsabilityDefectSeverity.HIGH; 90 } 91 else if (ratio > 0.7) { 92 severity = UsabilityDefectSeverity.MEDIUM; 93 } 94 else if (ratio > 0.5) { 95 severity = UsabilityDefectSeverity.LOW; 96 } 97 else if (ratio > 0.3) { 98 severity = UsabilityDefectSeverity.INFO; 99 } 100 84 int ratio = 1000 * allTextFieldInputs / statistics.getNoOfAllEvents(); 85 86 // TODO comment magic numbers 87 UsabilityDefectSeverity severity = UsabilityDefectSeverity.getSeverity 88 (ratio, 900, 700, 500, 300); 89 101 90 if (severity != null) { 102 Map<String, String> parameters = new HashMap<String, String>();103 parameters.put("textInputRatio", DecimalFormat.getInstance().format(ratio * 100));91 Map<String, Object> parameters = new HashMap<String, Object>(); 92 parameters.put("textInputRatio", (ratio / 10)); 104 93 105 94 results.addDefect … … 122 111 int noOfUsagesOfTextField1WithSameTextInTextField2 = entry.enteredTexts.size(); 123 112 124 float ratioTextField1 =125 noOfUsagesOfTextField1WithSameTextInTextField2 / (float)noOfUsagesOfTextField1;126 127 float ratioTextField2 =128 noOfUsagesOfTextField1WithSameTextInTextField2 / (float)noOfUsagesOfTextField2;129 130 createTextFieldEntryRepetitionDefect 131 (ratioTextField1, entry.textField1,entry.textField2, results);132 133 createTextFieldEntryRepetitionDefect 134 (ratioTextField2, entry.textField2,entry.textField1, results);135 136 } 137 } 138 139 /** 140 * 141 */ 142 private void createTextFieldEntryRepetitionDefect( floatratioOfEqualEntries,113 int ratioTextField1 = 114 1000 * noOfUsagesOfTextField1WithSameTextInTextField2 / noOfUsagesOfTextField1; 115 116 int ratioTextField2 = 117 1000 * noOfUsagesOfTextField1WithSameTextInTextField2 / noOfUsagesOfTextField2; 118 119 createTextFieldEntryRepetitionDefect(ratioTextField1, entry.textField1, 120 entry.textField2, results); 121 122 createTextFieldEntryRepetitionDefect(ratioTextField2, entry.textField2, 123 entry.textField1, results); 124 125 } 126 } 127 128 /** 129 * 130 */ 131 private void createTextFieldEntryRepetitionDefect(int ratioOfEqualEntries, 143 132 ITextField textField1, 144 133 ITextField textField2, 145 134 UsabilityEvaluationResult results) 146 135 { 147 UsabilityDefectSeverity severity = null; 148 if (ratioOfEqualEntries > 0.9) { 149 severity = UsabilityDefectSeverity.HIGH; 150 } 151 else if (ratioOfEqualEntries > 0.5) { 152 severity = UsabilityDefectSeverity.MEDIUM; 153 } 154 else if (ratioOfEqualEntries > 0.2) { 155 severity = UsabilityDefectSeverity.LOW; 156 } 157 else if (ratioOfEqualEntries > 0.1) { 158 severity = UsabilityDefectSeverity.INFO; 159 } 136 // TODO comment magic numbers 137 UsabilityDefectSeverity severity = UsabilityDefectSeverity.getSeverity 138 (ratioOfEqualEntries, 900, 500, 200, 100); 160 139 161 140 if (severity != null) { 162 Map<String, String> parameters = new HashMap<String, String>(); 163 parameters.put("textRepetitionRatio", 164 DecimalFormat.getInstance().format(ratioOfEqualEntries * 100)); 165 parameters.put("textField1", textField1.toString()); 166 parameters.put("textField2", textField2.toString()); 141 Map<String, Object> parameters = new HashMap<String, Object>(); 142 parameters.put("textRepetitionRatio", (ratioOfEqualEntries / 10)); 143 parameters.put("textField1", textField1); 144 parameters.put("textField2", textField2); 167 145 168 146 results.addDefect … … 192 170 } 193 171 194 float ratio = (float) noLetterOrDigitCount / (float) allCharactersCount; 195 196 UsabilityDefectSeverity severity = null; 197 if (ratio > 0.1) { // every 10th sign 198 severity = UsabilityDefectSeverity.HIGH; 199 } 200 else if (ratio > 0.05) { // every 20th sign 201 severity = UsabilityDefectSeverity.MEDIUM; 202 } 203 else if (ratio > 0.02) { // every 50th sign 204 severity = UsabilityDefectSeverity.LOW; 205 } 206 else if (ratio > 0.01) { // every 100th sign 207 severity = UsabilityDefectSeverity.INFO; 208 } 172 int ratio = 1000 * noLetterOrDigitCount / allCharactersCount; 173 174 UsabilityDefectSeverity severity = 175 UsabilityDefectSeverity.getSeverity(ratio, 176 100, // every 10th sign 177 50, // every 20th sign 178 20, // every 50th sign 179 10 // every 100th sign 180 ); 209 181 210 182 if (severity != null) { 211 Map<String, String> parameters = new HashMap<String, String>(); 212 parameters.put("textField", textField.toString()); 213 parameters.put("noLetterOrDigitRatio", 214 DecimalFormat.getInstance().format(ratio * 100)); 183 Map<String, Object> parameters = new HashMap<String, Object>(); 184 parameters.put("textField", textField); 185 parameters.put("noLetterOrDigitRatio", (ratio / 10)); 215 186 216 187 results.addDefect 217 (severity, UsabilityDefectDescription.TEXT_FIELD_NO_LETTER_OR_DIGIT_RATIO, parameters); 188 (severity, UsabilityDefectDescription.TEXT_FIELD_NO_LETTER_OR_DIGIT_RATIO, 189 parameters); 218 190 } 219 191 } -
trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/UsabilityDefect.java
r1335 r1493 15 15 package de.ugoe.cs.autoquest.usability; 16 16 17 import java.util.List; 17 18 import java.util.Map; 18 19 … … 32 33 33 34 /** */ 34 private Map<String, String> descriptionParameters;35 private Map<String, Object> descriptionParameters; 35 36 36 37 /** 37 38 * 38 39 */ 39 UsabilityDefect(UsabilityDefectSeverity severity, UsabilityDefectDescription description) 40 { 40 UsabilityDefect(UsabilityDefectSeverity severity, UsabilityDefectDescription description) { 41 41 this(severity, description, null); 42 42 } … … 47 47 UsabilityDefect(UsabilityDefectSeverity severity, 48 48 UsabilityDefectDescription description, 49 Map<String, String> parameters)49 Map<String, Object> parameters) 50 50 { 51 51 this.severity = severity; … … 80 80 public String getParameterizedDescription() { 81 81 return description.toString(descriptionParameters); 82 } 83 84 /** 85 * 86 */ 87 public List<Object> getDescriptionFragments() { 88 return description.toFragmentList(descriptionParameters); 89 } 90 91 /* 92 */ 93 public String getBriefDescription() { 94 return description.getBriefDescription(); 82 95 } 83 96 -
trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/UsabilityDefectDescription.java
r1335 r1493 18 18 import java.io.InputStream; 19 19 import java.util.ArrayList; 20 import java.util.Collection; 20 21 import java.util.List; 21 22 import java.util.Map; … … 33 34 public enum UsabilityDefectDescription { 34 35 35 SCROLL_REQUIRED,36 INEFFICIENT_ACTIONS, 36 37 TEXT_FIELD_INPUT_RATIO, 37 38 TEXT_FIELD_INPUT_REPETITIONS, 38 TEXT_FIELD_NO_LETTER_OR_DIGIT_RATIO; 39 TEXT_FIELD_NO_LETTER_OR_DIGIT_RATIO, 40 COOCCURENCE_SUCCEED, 41 COOCCURENCE_PRECED, 42 HIGH_EVENT_COVERAGE, 43 HIGH_TARGET_DISTANCE, 44 MISSING_FEEDBACK, 45 UNUSED_GUI_ELEMENTS; 39 46 40 47 /** */ … … 122 129 * 123 130 */ 124 public String toString(Map<String, String> parameters) throws IllegalArgumentException {131 public String toString(Map<String, Object> parameters) throws IllegalArgumentException { 125 132 StringBuffer result = new StringBuffer(); 126 133 … … 131 138 132 139 if (fragment instanceof ParameterFragment) { 133 Stringvalue = null;140 Object value = null; 134 141 if (parameters != null) { 135 142 value = parameters.get(((ParameterFragment) fragment).getParameterName()); … … 137 144 138 145 if (value != null) { 139 result.append(value); 146 if (value instanceof Collection<?>) { 147 int counter = 1; 148 for (Object elem : ((Collection<?>) value)) { 149 result.append('\n'); 150 result.append(counter++); 151 result.append(".: "); 152 result.append(elem); 153 } 154 } 155 else { 156 result.append(value.toString()); 157 } 140 158 } 141 159 else { … … 154 172 } 155 173 174 /** 175 * 176 */ 177 public List<Object> toFragmentList(Map<String, Object> parameters) 178 throws IllegalArgumentException 179 { 180 List<Object> result = new ArrayList<Object>(); 181 182 for (Object fragment : defectDescription.getTextFragmentOrParameterFragment()) { 183 if (fragment instanceof ParameterFragment) { 184 Object value = null; 185 if (parameters != null) { 186 value = parameters.get(((ParameterFragment) fragment).getParameterName()); 187 } 188 189 if (value != null) { 190 result.add(value); 191 } 192 else { 193 throw new IllegalArgumentException 194 ("required parameter \"" + 195 ((ParameterFragment) fragment).getParameterName() + 196 "\" for usability defect description " + this.name() + " not provided"); 197 } 198 } 199 else { 200 result.add(getFragmentString(fragment)); 201 } 202 } 203 204 return result; 205 } 206 207 /** 208 * 209 */ 210 public String getBriefDescription() { 211 return defectDescription.briefText; 212 } 213 156 214 /* 157 215 * (non-Javadoc) -
trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/UsabilityDefectSeverity.java
r927 r1493 15 15 package de.ugoe.cs.autoquest.usability; 16 16 17 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask; 18 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInfo; 19 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel; 20 import de.ugoe.cs.autoquest.tasktrees.treeifc.TaskMetric; 21 17 22 /** 18 23 * TODO comment … … 24 29 25 30 INFO, LOW, MEDIUM, HIGH; 31 32 /** */ 33 static int defaultCoverageQuantile = 950; 26 34 35 /** 36 * 37 */ 38 static UsabilityDefectSeverity getSeverity(int ratio, 39 int highRatioLevel, 40 int mediumRatioLevel, 41 int lowRatioLevel, 42 int infoRatioLevel) 43 { 44 return getSeverity(ratio, highRatioLevel, mediumRatioLevel, lowRatioLevel, infoRatioLevel, 45 defaultCoverageQuantile); 46 } 47 48 /** 49 * 50 */ 51 static UsabilityDefectSeverity getSeverity(int ratio, 52 int highRatioLevel, 53 int mediumRatioLevel, 54 int lowRatioLevel, 55 int infoRatioLevel, 56 ITask taskWithDefect, 57 ITaskModel wholeTaskModel) 58 { 59 ITaskInfo taskInfo = wholeTaskModel.getTaskInfo(taskWithDefect); 60 int eventCoverageQuantile = taskInfo.getMeasureValue(TaskMetric.EVENT_COVERAGE_QUANTILE); 61 return getSeverity(ratio, highRatioLevel, mediumRatioLevel, lowRatioLevel, infoRatioLevel, 62 eventCoverageQuantile); 63 } 64 65 /** 66 * 67 */ 68 static UsabilityDefectSeverity getSeverity(int ratio, 69 int highRatioLevel, 70 int mediumRatioLevel, 71 int lowRatioLevel, 72 int infoRatioLevel, 73 int coverageQuantile) 74 { 75 int effectiveRatio = ratio; 76 77 // event coverage ratio is in per mille. The more executed events a task covers, the more 78 // important a related usability defect. 79 /*if (eventCoverageRatio < 1) { 80 // one per mille, so one of thousand events is covered 81 effectiveRatio *= 0.2; 82 } 83 else if (eventCoverageRatio < 5) { 84 // 5 per mille, so one of 250 events is covered 85 effectiveRatio *= 0.4; 86 } 87 else if (eventCoverageRatio < 10) { 88 // 1 percent, so one of 100 events is covered 89 effectiveRatio *= 0.5; 90 } 91 else if (eventCoverageRatio < 20) { 92 // 2 percent, so one of 50 events is covered 93 effectiveRatio *= 0.6; 94 } 95 else if (eventCoverageRatio < 30) { 96 // 3 percent, so one of 33 events is covered 97 effectiveRatio *= 0.7; 98 } 99 else if (eventCoverageRatio < 40) { 100 // 4 percent, so one of 28 events is covered 101 effectiveRatio *= 0.8; 102 } 103 else if (eventCoverageRatio < 50) { 104 // 5 percent, so one of 25 events is covered 105 effectiveRatio *= 0.9; 106 }*/ 107 //else { 108 // more than 5 percent, so 1 of 20 events, do not change ratio 109 //} 110 if (coverageQuantile >= defaultCoverageQuantile) { 111 if (effectiveRatio >= highRatioLevel) { 112 return UsabilityDefectSeverity.HIGH; 113 } 114 else if (effectiveRatio >= mediumRatioLevel) { 115 return UsabilityDefectSeverity.MEDIUM; 116 } 117 else if (effectiveRatio >= lowRatioLevel) { 118 return UsabilityDefectSeverity.LOW; 119 } 120 else if (effectiveRatio >= infoRatioLevel) { 121 return UsabilityDefectSeverity.INFO; 122 } 123 } 124 125 return null; 126 } 27 127 } -
trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/UsabilityEvaluationManager.java
r1335 r1493 19 19 import java.util.logging.Level; 20 20 21 import de.ugoe.cs.autoquest.tasktrees.treeifc.IMarkingTemporalRelationship; 22 import de.ugoe.cs.autoquest.tasktrees.treeifc.IStructuringTemporalRelationship; 23 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask; 21 24 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel; 22 25 import de.ugoe.cs.util.console.Console; … … 45 48 */ 46 49 private void init() { 47 rules.add(new TextInputStatisticsRule()); 48 rules.add(new RequiredScrollRule()); 50 //rules.add(new TextInputStatisticsRule()); 51 rules.add(new MissingFeedbackRule()); 52 rules.add(new EventCoverageRatioRule()); 53 rules.add(new RequiredInefficientActionsRule()); 54 //rules.add(new TaskCooccurrenceRule()); 55 rules.add(new TargetDistanceRule()); 56 //rules.add(new UnusedGUIElementsRule()); 57 //rules.add(new TaskTreeTestRule()); 49 58 } 50 59 … … 64 73 " usability defects, of which " + result.getSevereDefects().size() + 65 74 " are severe."); 75 76 if ((rule instanceof EventCoverageRatioRule) || 77 (rule instanceof RequiredInefficientActionsRule) || 78 (rule instanceof TargetDistanceRule)) 79 { 80 ITask[] referredTasks = new ITask[result.getAllDefects().size()]; 81 82 for (int i = 0; i < result.getAllDefects().size(); i++) { 83 referredTasks[i] = 84 (ITask) result.getAllDefects().get(i).getDescriptionFragments().get(1); 85 } 86 87 int counter = 0; 88 for (int i = 0; i < referredTasks.length; i++) { 89 for (int j = 0; j < referredTasks.length; j++) { 90 if (isChildOf(referredTasks[i], referredTasks[j])) { 91 counter++; 92 break; 93 } 94 } 95 } 96 97 if (counter > 0) { 98 Console.traceln(Level.INFO, counter + " of the findings are duplicates in " + 99 "that they refer to tasks whose parent tasks are also " + 100 "referred by the findings"); 101 } 102 } 66 103 } 67 104 68 UsabilityEvaluationResult result = new UsabilityEvaluationResult( interimResults);105 UsabilityEvaluationResult result = new UsabilityEvaluationResult(taskModel, interimResults); 69 106 Console.println("the evaluation result contains " + result.getAllDefects().size() + 70 107 " defects, of which " + result.getSevereDefects().size() + " are severe."); 71 72 List<UsabilityDefect> defects = result.getAllDefects();73 for (int i = 0; i < defects.size(); i++) {74 Console.println((i + 1) + ": " + defects.get(i).getParameterizedDescription());75 }76 108 77 109 return result; 78 110 } 79 111 112 /** 113 * <p> 114 * TODO: comment 115 * </p> 116 * 117 * @param iTask 118 * @param iTask2 119 * @return 120 */ 121 private boolean isChildOf(final ITask potChild, ITask potParent) { 122 123 if (potParent instanceof IStructuringTemporalRelationship) { 124 for (ITask child : ((IStructuringTemporalRelationship) potParent).getChildren()) { 125 if ((child == potChild) || isChildOf(potChild, child)) { 126 return true; 127 } 128 } 129 } 130 else if (potParent instanceof IMarkingTemporalRelationship) { 131 ITask child = ((IMarkingTemporalRelationship) potParent).getMarkedTask(); 132 if ((child == potChild) || isChildOf(potChild, child)) { 133 return true; 134 } 135 } 136 137 return false; 138 } 139 80 140 } -
trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/UsabilityEvaluationResult.java
r1335 r1493 19 19 import java.util.Map; 20 20 21 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel; 22 21 23 /** 22 24 * TODO comment … … 28 30 29 31 /** */ 32 private ITaskModel taskModel; 33 34 /** */ 30 35 private List<UsabilityDefect> defects = new ArrayList<UsabilityDefect>(); 31 36 … … 33 38 * 34 39 */ 35 public UsabilityEvaluationResult( ) {36 // default constructor40 public UsabilityEvaluationResult(ITaskModel taskModel) { 41 this.taskModel = taskModel; 37 42 } 38 43 … … 40 45 * 41 46 */ 42 public UsabilityEvaluationResult(List<UsabilityEvaluationResult> results) { 47 public UsabilityEvaluationResult(ITaskModel taskModel, 48 List<UsabilityEvaluationResult> results) 49 { 50 this.taskModel = taskModel; 43 51 for (UsabilityEvaluationResult result : results) { 44 52 for (UsabilityDefect defect : result.getAllDefects()) { … … 53 61 public void addDefect(UsabilityDefectSeverity severity, 54 62 UsabilityDefectDescription description, 55 Map<String, String> parameters)63 Map<String, Object> parameters) 56 64 { 57 65 defects.add(new UsabilityDefect(severity, description, parameters)); … … 80 88 } 81 89 90 /** 91 * @return the taskModel 92 */ 93 public ITaskModel getTaskModel() { 94 return taskModel; 95 } 96 82 97 }
Note: See TracChangeset
for help on using the changeset viewer.