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.
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  
    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 
  • trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/TextInputStatisticsRule.java

    r1335 r1493  
    1515package de.ugoe.cs.autoquest.usability; 
    1616 
    17 import java.text.DecimalFormat; 
    1817import java.util.ArrayList; 
    1918import java.util.Collection; 
     
    5756        calculateStatistics(taskModel.getUserSessions(), statistics); 
    5857 
    59         UsabilityEvaluationResult results = new UsabilityEvaluationResult(); 
     58        UsabilityEvaluationResult results = new UsabilityEvaluationResult(taskModel); 
    6059        analyzeStatistics(statistics, results); 
    6160 
     
    8079                                     UsabilityEvaluationResult results) 
    8180    { 
    82         float allTextFieldInputs = 
     81        int allTextFieldInputs = 
    8382            statistics.getNoOfTextFieldInputs() + statistics.getNoOfTextAreaInputs(); 
    8483 
    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         
    10190        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)); 
    10493 
    10594            results.addDefect 
     
    122111            int noOfUsagesOfTextField1WithSameTextInTextField2 = entry.enteredTexts.size(); 
    123112             
    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(float                     ratioOfEqualEntries, 
     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, 
    143132                                                      ITextField                textField1, 
    144133                                                      ITextField                textField2, 
    145134                                                      UsabilityEvaluationResult results) 
    146135    { 
    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); 
    160139         
    161140        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); 
    167145 
    168146            results.addDefect 
     
    192170            } 
    193171 
    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                                                    ); 
    209181 
    210182            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)); 
    215186 
    216187                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); 
    218190            } 
    219191        } 
  • trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/UsabilityDefect.java

    r1335 r1493  
    1515package de.ugoe.cs.autoquest.usability; 
    1616 
     17import java.util.List; 
    1718import java.util.Map; 
    1819 
     
    3233 
    3334    /** */ 
    34     private Map<String, String> descriptionParameters; 
     35    private Map<String, Object> descriptionParameters; 
    3536 
    3637    /** 
    3738     * 
    3839     */ 
    39     UsabilityDefect(UsabilityDefectSeverity severity, UsabilityDefectDescription description) 
    40     { 
     40    UsabilityDefect(UsabilityDefectSeverity severity, UsabilityDefectDescription description) { 
    4141        this(severity, description, null); 
    4242    } 
     
    4747    UsabilityDefect(UsabilityDefectSeverity    severity, 
    4848                    UsabilityDefectDescription description, 
    49                     Map<String, String>        parameters) 
     49                    Map<String, Object>        parameters) 
    5050    { 
    5151        this.severity = severity; 
     
    8080    public String getParameterizedDescription() { 
    8181        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(); 
    8295    } 
    8396 
  • trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/UsabilityDefectDescription.java

    r1335 r1493  
    1818import java.io.InputStream; 
    1919import java.util.ArrayList; 
     20import java.util.Collection; 
    2021import java.util.List; 
    2122import java.util.Map; 
     
    3334public enum UsabilityDefectDescription { 
    3435     
    35     SCROLL_REQUIRED, 
     36    INEFFICIENT_ACTIONS, 
    3637    TEXT_FIELD_INPUT_RATIO, 
    3738    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; 
    3946 
    4047    /** */ 
     
    122129     *  
    123130     */ 
    124     public String toString(Map<String, String> parameters) throws IllegalArgumentException { 
     131    public String toString(Map<String, Object> parameters) throws IllegalArgumentException { 
    125132        StringBuffer result = new StringBuffer(); 
    126133 
     
    131138 
    132139            if (fragment instanceof ParameterFragment) { 
    133                 String value = null; 
     140                Object value = null; 
    134141                if (parameters != null) { 
    135142                    value = parameters.get(((ParameterFragment) fragment).getParameterName()); 
     
    137144 
    138145                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                    } 
    140158                } 
    141159                else { 
     
    154172    } 
    155173 
     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 
    156214    /* 
    157215     * (non-Javadoc) 
  • trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/UsabilityDefectSeverity.java

    r927 r1493  
    1515package de.ugoe.cs.autoquest.usability; 
    1616 
     17import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask; 
     18import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInfo; 
     19import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel; 
     20import de.ugoe.cs.autoquest.tasktrees.treeifc.TaskMetric; 
     21 
    1722/** 
    1823 * TODO comment 
     
    2429     
    2530    INFO, LOW, MEDIUM, HIGH; 
     31     
     32    /** */ 
     33    static int defaultCoverageQuantile = 950; 
    2634 
     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    } 
    27127} 
  • trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/UsabilityEvaluationManager.java

    r1335 r1493  
    1919import java.util.logging.Level; 
    2020 
     21import de.ugoe.cs.autoquest.tasktrees.treeifc.IMarkingTemporalRelationship; 
     22import de.ugoe.cs.autoquest.tasktrees.treeifc.IStructuringTemporalRelationship; 
     23import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask; 
    2124import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel; 
    2225import de.ugoe.cs.util.console.Console; 
     
    4548     */ 
    4649    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()); 
    4958    } 
    5059 
     
    6473                            " usability defects, of which " + result.getSevereDefects().size() + 
    6574                            " 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            } 
    66103        } 
    67104 
    68         UsabilityEvaluationResult result = new UsabilityEvaluationResult(interimResults); 
     105        UsabilityEvaluationResult result = new UsabilityEvaluationResult(taskModel, interimResults); 
    69106        Console.println("the evaluation result contains " + result.getAllDefects().size() + 
    70107                        " 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         } 
    76108 
    77109        return result; 
    78110    } 
    79111 
     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 
    80140} 
  • trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/UsabilityEvaluationResult.java

    r1335 r1493  
    1919import java.util.Map; 
    2020 
     21import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel; 
     22 
    2123/** 
    2224 * TODO comment 
     
    2830     
    2931    /** */ 
     32    private ITaskModel taskModel; 
     33     
     34    /** */ 
    3035    private List<UsabilityDefect> defects = new ArrayList<UsabilityDefect>(); 
    3136 
     
    3338     * 
    3439     */ 
    35     public UsabilityEvaluationResult() { 
    36         // default constructor 
     40    public UsabilityEvaluationResult(ITaskModel taskModel) { 
     41        this.taskModel = taskModel; 
    3742    } 
    3843 
     
    4045     * 
    4146     */ 
    42     public UsabilityEvaluationResult(List<UsabilityEvaluationResult> results) { 
     47    public UsabilityEvaluationResult(ITaskModel                      taskModel, 
     48                                     List<UsabilityEvaluationResult> results) 
     49    { 
     50        this.taskModel = taskModel; 
    4351        for (UsabilityEvaluationResult result : results) { 
    4452            for (UsabilityDefect defect : result.getAllDefects()) { 
     
    5361    public void addDefect(UsabilityDefectSeverity    severity, 
    5462                          UsabilityDefectDescription description, 
    55                           Map<String, String>        parameters) 
     63                          Map<String, Object>        parameters) 
    5664    { 
    5765        defects.add(new UsabilityDefect(severity, description, parameters)); 
     
    8088    } 
    8189 
     90    /** 
     91     * @return the taskModel 
     92     */ 
     93    public ITaskModel getTaskModel() { 
     94        return taskModel; 
     95    } 
     96 
    8297} 
Note: See TracChangeset for help on using the changeset viewer.