Ignore:
Timestamp:
04/11/14 11:21:45 (10 years ago)
Author:
pharms
Message:
  • state of the HCSE 2014 Paper. An appropriate tag will follow.
File:
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/RequiredInefficientActionsRule.java

    r1335 r1493  
    1515package de.ugoe.cs.autoquest.usability; 
    1616 
    17 import java.text.DecimalFormat; 
    1817import java.util.Collection; 
    1918import java.util.HashMap; 
    2019import java.util.Map; 
    2120 
    22 import de.ugoe.cs.autoquest.eventcore.IEventType; 
     21import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics; 
     22 
     23import de.ugoe.cs.autoquest.eventcore.Event; 
    2324import de.ugoe.cs.autoquest.eventcore.gui.Scroll; 
     25import de.ugoe.cs.autoquest.tasktrees.treeifc.DefaultTaskInstanceTraversingVisitor; 
     26import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask; 
    2427import 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; 
     28import de.ugoe.cs.autoquest.tasktrees.treeifc.IMarkingTemporalRelationship; 
    3029import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask; 
    3130import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance; 
     
    3837 * @author 2012, last modified by $Author: pharms$ 
    3938 */ 
    40 public class RequiredScrollRule implements UsabilityEvaluationRule { 
     39public class RequiredInefficientActionsRule implements UsabilityEvaluationRule { 
    4140 
    4241    /* 
     
    4746    @Override 
    4847    public UsabilityEvaluationResult evaluate(ITaskModel taskModel) { 
    49         Map<ITask, Integer> smellingTasks = getTasksStartingWithScroll(taskModel.getTasks()); 
     48        UsabilityEvaluationResult results = new UsabilityEvaluationResult(taskModel); 
    5049 
    51         UsabilityEvaluationResult results = new UsabilityEvaluationResult(); 
    52         analyzeTasksStartingWithScroll(smellingTasks, results); 
     50        Map<ITask, double[]> smellingTasks = getInefficientActionStatistics(taskModel.getTasks()); 
     51        analyzeTasksWithInefficientActions(smellingTasks, results, taskModel); 
    5352 
    5453        return results; 
     
    5857     * 
    5958     */ 
    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) 
    6262    { 
    6363 
    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()); 
    6668 
    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); 
    8071 
    8172            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)); 
    8576 
    86                 results.addDefect(severity, UsabilityDefectDescription.SCROLL_REQUIRED, parameters); 
     77                results.addDefect 
     78                    (severity, UsabilityDefectDescription.INEFFICIENT_ACTIONS, parameters); 
    8779            } 
    8880        } 
     
    9284     *  
    9385     */ 
    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[]>(); 
    9688         
    9789        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                    } 
    10399                } 
    104100            } 
    105101        } 
    106102         
    107         return scrollCounts; 
     103        return inefficientActionRatios; 
    108104    } 
    109105 
     
    111107     * 
    112108     */ 
    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; 
    121115        } 
    122          
    123         return counter; 
     116        else { 
     117            return true; 
     118        } 
    124119    } 
    125120 
     
    127122     * 
    128123     */ 
    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); 
    175131        } 
    176132         
    177         return false; 
     133        return ratios; 
    178134    } 
    179135 
    180136    /** 
    181      * @param firstChild 
    182      * @return 
     137     * 
    183138     */ 
    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; 
    186143         
    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    } 
    190158 
    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); 
    204164    } 
    205165 
Note: See TracChangeset for help on using the changeset viewer.