source: trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/RequiredInefficientActionsRule.java @ 1493

Last change on this file since 1493 was 1493, checked in by pharms, 10 years ago
  • state of the HCSE 2014 Paper. An appropriate tag will follow.
File size: 5.5 KB
RevLine 
[1335]1//   Copyright 2012 Georg-August-Universität Göttingen, Germany
2//
3//   Licensed under the Apache License, Version 2.0 (the "License");
4//   you may not use this file except in compliance with the License.
5//   You may obtain a copy of the License at
6//
7//       http://www.apache.org/licenses/LICENSE-2.0
8//
9//   Unless required by applicable law or agreed to in writing, software
10//   distributed under the License is distributed on an "AS IS" BASIS,
11//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//   See the License for the specific language governing permissions and
13//   limitations under the License.
14
15package de.ugoe.cs.autoquest.usability;
16
17import java.util.Collection;
18import java.util.HashMap;
19import java.util.Map;
20
[1493]21import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;
22
23import de.ugoe.cs.autoquest.eventcore.Event;
[1335]24import de.ugoe.cs.autoquest.eventcore.gui.Scroll;
[1493]25import de.ugoe.cs.autoquest.tasktrees.treeifc.DefaultTaskInstanceTraversingVisitor;
26import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;
[1335]27import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance;
[1493]28import de.ugoe.cs.autoquest.tasktrees.treeifc.IMarkingTemporalRelationship;
[1335]29import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
30import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
31import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel;
32
33/**
34 * TODO comment
35 *
36 * @version $Revision: $ $Date: 16.07.2012$
37 * @author 2012, last modified by $Author: pharms$
38 */
[1493]39public class RequiredInefficientActionsRule implements UsabilityEvaluationRule {
[1335]40
41    /*
42     * (non-Javadoc)
43     *
44     * @see de.ugoe.cs.usability.UsabilityEvaluationRule#evaluate(TaskTree)
45     */
46    @Override
47    public UsabilityEvaluationResult evaluate(ITaskModel taskModel) {
[1493]48        UsabilityEvaluationResult results = new UsabilityEvaluationResult(taskModel);
[1335]49
[1493]50        Map<ITask, double[]> smellingTasks = getInefficientActionStatistics(taskModel.getTasks());
51        analyzeTasksWithInefficientActions(smellingTasks, results, taskModel);
[1335]52
53        return results;
54    }
55
56    /**
57     *
58     */
[1493]59    private void analyzeTasksWithInefficientActions(Map<ITask, double[]>      smellingTasks,
60                                                    UsabilityEvaluationResult results,
61                                                    ITaskModel                taskModel)
[1335]62    {
63
[1493]64        for (Map.Entry<ITask, double[]> entry : smellingTasks.entrySet()) {
65            DescriptiveStatistics stats = new DescriptiveStatistics(entry.getValue());
66           
67            int ratio = (int) (1000 * stats.getMean());
[1335]68
[1493]69            UsabilityDefectSeverity severity = UsabilityDefectSeverity.getSeverity
70                (ratio, 500, 300, 200, 100, entry.getKey(), taskModel);
[1335]71
72            if (severity != null) {
[1493]73                Map<String, Object> parameters = new HashMap<String, Object>();
74                parameters.put("task", entry.getKey());
75                parameters.put("ratio", (ratio / 10));
[1335]76
[1493]77                results.addDefect
78                    (severity, UsabilityDefectDescription.INEFFICIENT_ACTIONS, parameters);
[1335]79            }
80        }
81    }
82
83    /**
84     *
85     */
[1493]86    private Map<ITask, double[]> getInefficientActionStatistics(Collection<ITask> tasks) {
87        Map<ITask, double[]> inefficientActionRatios = new HashMap<ITask, double[]>();
[1335]88       
89        for (ITask task : tasks) {
[1493]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                    }
[1335]99                }
100            }
101        }
102       
[1493]103        return inefficientActionRatios;
[1335]104    }
105
106    /**
107     *
108     */
[1493]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;
115        }
116        else {
117            return true;
118        }
119    }
120
121    /**
122     *
123     */
124    private double[] getRatiosOfInefficientActionsInInstances(ITask task) {
[1335]125        Collection<ITaskInstance> instances = task.getInstances();
126       
[1493]127        double[] ratios = new double[instances.size()];
128        int index = 0;
[1335]129        for (ITaskInstance instance : instances) {
[1493]130            ratios[index++] = getRatioOfInefficientActionsInInstance(instance);
[1335]131        }
132       
[1493]133        return ratios;
[1335]134    }
135
136    /**
137     *
138     */
[1493]139    private double getRatioOfInefficientActionsInInstance(ITaskInstance instance) {
140        final int[] count = new int[2];
141        count[0] = 0;
142        count[1] = 0;
143       
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]++;
[1335]152            }
153           
[1493]154        });
[1335]155       
[1493]156        return (double) count[0] / count[1];
[1335]157    }
158
159    /**
[1493]160     *
[1335]161     */
[1493]162    private boolean isInefficientAction(Event event) {
163        return (event.getType() instanceof Scroll);
[1335]164    }
165
166}
Note: See TracBrowser for help on using the repository browser.