Changeset 1335 for trunk/autoquest-core-usability/src
- Timestamp:
- 01/24/14 13:50:29 (11 years ago)
- Location:
- trunk/autoquest-core-usability/src/main
- Files:
-
- 1 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/TextInputStatisticsRule.java
r1301 r1335 19 19 import java.util.Collection; 20 20 import java.util.HashMap; 21 import java.util.HashSet; 22 import java.util.LinkedList; 21 23 import java.util.List; 22 24 import java.util.Map; 25 import java.util.Set; 23 26 24 27 import de.ugoe.cs.autoquest.eventcore.IEventTarget; … … 27 30 import de.ugoe.cs.autoquest.eventcore.guimodel.ITextArea; 28 31 import de.ugoe.cs.autoquest.eventcore.guimodel.ITextField; 29 import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;30 32 import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance; 31 import de.ugoe.cs.autoquest.tasktrees.treeifc.IMarkingTemporalRelationship; 32 import de.ugoe.cs.autoquest.tasktrees.treeifc.IStructuringTemporalRelationship; 33 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask; 33 import de.ugoe.cs.autoquest.tasktrees.treeifc.IIterationInstance; 34 import de.ugoe.cs.autoquest.tasktrees.treeifc.IOptionalInstance; 35 import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelectionInstance; 36 import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequenceInstance; 34 37 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance; 35 38 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel; 39 import de.ugoe.cs.autoquest.tasktrees.treeifc.IUserSession; 36 40 37 41 /** … … 41 45 * @author 2012, last modified by $Author: pharms$ 42 46 */ 43 public class TextInputStatisticsRule implements de.ugoe.cs.autoquest.usability.UsabilityEvaluationRule {47 public class TextInputStatisticsRule implements UsabilityEvaluationRule { 44 48 45 49 /* … … 51 55 public UsabilityEvaluationResult evaluate(ITaskModel taskModel) { 52 56 TextInputStatistics statistics = new TextInputStatistics(); 53 calculateStatistics(taskModel.get Tasks(), statistics);57 calculateStatistics(taskModel.getUserSessions(), statistics); 54 58 55 59 UsabilityEvaluationResult results = new UsabilityEvaluationResult(); … … 97 101 if (severity != null) { 98 102 Map<String, String> parameters = new HashMap<String, String>(); 99 parameters.put("textInputRatio", DecimalFormat.getInstance().format(ratio * 100) + "%");103 parameters.put("textInputRatio", DecimalFormat.getInstance().format(ratio * 100)); 100 104 101 105 results.addDefect 102 (new UsabilityDefect(severity, UsabilityDefectDescription.TEXT_FIELD_INPUT_RATIO, 103 parameters)); 106 (severity, UsabilityDefectDescription.TEXT_FIELD_INPUT_RATIO, parameters); 104 107 } 105 108 } … … 111 114 UsabilityEvaluationResult results) 112 115 { 113 Map<String, Integer> words = new HashMap<String, Integer>(); 114 int numberOfRepeatedWords = 0; 115 int maxRepetitions = 0; 116 117 for (int i = 0; i < statistics.getNoOfTextFieldInputs(); i++) { 118 String[] fragments = statistics.getTextFieldInputFragments(i); 119 for (String fragment : fragments) { 120 if (!"".equals(fragment.trim())) { 121 Integer count = words.get(fragment); 122 if (count == null) { 123 words.put(fragment, 1); 124 } 125 else { 126 count++; 127 words.put(fragment, count); 128 maxRepetitions = Math.max(count, maxRepetitions); 129 130 if (count == 2) { 131 // do not calculate repeated words several times 132 numberOfRepeatedWords++; 133 } 134 } 135 } 136 } 137 } 138 116 List<TextFieldCorrelation> textFieldCorrelations = 117 statistics.determineTextFieldCorrelations(); 118 119 for (TextFieldCorrelation entry : textFieldCorrelations) { 120 int noOfUsagesOfTextField1 = statistics.getUsageCount(entry.textField1); 121 int noOfUsagesOfTextField2 = statistics.getUsageCount(entry.textField2); 122 int noOfUsagesOfTextField1WithSameTextInTextField2 = entry.enteredTexts.size(); 123 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, 143 ITextField textField1, 144 ITextField textField2, 145 UsabilityEvaluationResult results) 146 { 139 147 UsabilityDefectSeverity severity = null; 140 if ( (numberOfRepeatedWords > 10) || (maxRepetitions > 10)) {148 if (ratioOfEqualEntries > 0.9) { 141 149 severity = UsabilityDefectSeverity.HIGH; 142 150 } 143 else if ( (numberOfRepeatedWords > 4) || (maxRepetitions > 4)) {151 else if (ratioOfEqualEntries > 0.5) { 144 152 severity = UsabilityDefectSeverity.MEDIUM; 145 153 } 146 else if ( (numberOfRepeatedWords > 2) || (maxRepetitions > 2)) {154 else if (ratioOfEqualEntries > 0.2) { 147 155 severity = UsabilityDefectSeverity.LOW; 148 156 } 149 else if ( (numberOfRepeatedWords > 1) || (maxRepetitions > 1)) {157 else if (ratioOfEqualEntries > 0.1) { 150 158 severity = UsabilityDefectSeverity.INFO; 151 159 } 152 160 153 161 if (severity != null) { 154 162 Map<String, String> parameters = new HashMap<String, String>(); 155 parameters.put("textRepetitionRatio", numberOfRepeatedWords + 156 " repeated tokens, up to " + maxRepetitions + " repetitions per token"); 163 parameters.put("textRepetitionRatio", 164 DecimalFormat.getInstance().format(ratioOfEqualEntries * 100)); 165 parameters.put("textField1", textField1.toString()); 166 parameters.put("textField2", textField2.toString()); 157 167 158 168 results.addDefect 159 (new UsabilityDefect(severity, 160 UsabilityDefectDescription.TEXT_FIELD_INPUT_REPETITIONS, 161 parameters)); 169 (severity, UsabilityDefectDescription.TEXT_FIELD_INPUT_REPETITIONS, parameters); 162 170 } 163 171 } … … 169 177 UsabilityEvaluationResult results) 170 178 { 171 int allCharactersCount = 0; 172 int noLetterOrDigitCount = 0; 173 174 for (int i = 0; i < statistics.getNoOfTextFieldInputs(); i++) { 175 String[] fragments = statistics.getTextFieldInputFragments(i); 176 for (String fragment : fragments) { 177 String effectiveFragment = fragment.trim(); 178 for (int j = 0; j < effectiveFragment.length(); j++) { 179 if (!Character.isWhitespace(effectiveFragment.charAt(j))) { 180 if (!Character.isLetterOrDigit(effectiveFragment.charAt(j))) { 179 for (ITextField textField : statistics.getAllTextFields()) { 180 int allCharactersCount = 0; 181 int noLetterOrDigitCount = 0; 182 183 for (String textInput : statistics.getAllInputsInto(textField)) { 184 for (int j = 0; j < textInput.length(); j++) { 185 if (!Character.isWhitespace(textInput.charAt(j))) { 186 if (!Character.isLetterOrDigit(textInput.charAt(j))) { 181 187 noLetterOrDigitCount++; 182 188 } … … 185 191 } 186 192 } 187 } 188 189 float ratio = (float) noLetterOrDigitCount / (float) allCharactersCount; 190 191 UsabilityDefectSeverity severity = null; 192 if (ratio > 0.1) // every 10th sign 193 { 194 severity = UsabilityDefectSeverity.HIGH; 195 } 196 else if (ratio > 0.05) // every 20th sign 197 { 198 severity = UsabilityDefectSeverity.MEDIUM; 199 } 200 else if (ratio > 0.02) // every 50th sign 201 { 202 severity = UsabilityDefectSeverity.LOW; 203 } 204 else if (ratio > 0.01) // every 100th sign 205 { 206 severity = UsabilityDefectSeverity.INFO; 207 } 208 209 if (severity != null) { 210 Map<String, String> parameters = new HashMap<String, String>(); 211 parameters.put("noLetterOrDigitRatio", allCharactersCount + " entered characters of " + 212 "which " + noLetterOrDigitCount + " were no letter or digit"); 213 214 results.addDefect 215 (new UsabilityDefect(severity, 216 UsabilityDefectDescription.TEXT_FIELD_NO_LETTER_OR_DIGIT_RATIO, 217 parameters)); 193 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 } 209 210 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)); 215 216 results.addDefect 217 (severity, UsabilityDefectDescription.TEXT_FIELD_NO_LETTER_OR_DIGIT_RATIO, parameters); 218 } 218 219 } 219 220 } … … 222 223 * 223 224 */ 224 private void calculateStatistics(Collection<ITask> tasks, TextInputStatistics statistics) { 225 for (ITask task : tasks) { 226 calculateStatistics(task, statistics); 227 } 228 } 229 230 /** 231 * 232 */ 233 private void calculateStatistics(ITask task, TextInputStatistics statistics) { 234 235 if (isTextInput(task)) { 236 calculateStatistics((IEventTask) task, statistics); 225 private void calculateStatistics(Collection<IUserSession> sessions, 226 TextInputStatistics statistics) 227 { 228 System.out.print("calculating statistics ... "); 229 for (IUserSession session : sessions) { 230 for (ITaskInstance taskInstance : session) { 231 calculateStatistics(taskInstance, session, statistics); 232 } 233 } 234 System.out.println("done"); 235 } 236 237 /** 238 * 239 */ 240 private void calculateStatistics(ITaskInstance taskInstance, 241 IUserSession session, 242 TextInputStatistics statistics) 243 { 244 if (isTextInput(taskInstance)) { 245 calculateStatistics((IEventTaskInstance) taskInstance, session, statistics); 237 246 } 238 247 else { 239 if (task instanceof IStructuringTemporalRelationship) { 240 for (ITask child : ((IStructuringTemporalRelationship) task).getChildren()) { 241 calculateStatistics(child, statistics); 242 } 243 } 244 else if (task instanceof IMarkingTemporalRelationship) { 248 if (taskInstance instanceof ISequenceInstance) { 249 for (ITaskInstance child : (ISequenceInstance) taskInstance) { 250 calculateStatistics(child, session, statistics); 251 } 252 } 253 else if (taskInstance instanceof IIterationInstance) { 254 for (ITaskInstance child : (IIterationInstance) taskInstance) { 255 calculateStatistics(child, session, statistics); 256 } 257 } 258 else if (taskInstance instanceof ISelectionInstance) { 245 259 calculateStatistics 246 (((IMarkingTemporalRelationship) task).getMarkedTask(), statistics); 247 } 248 else { 260 (((ISelectionInstance) taskInstance).getChild(), session, statistics); 261 } 262 else if (taskInstance instanceof IOptionalInstance) { 263 calculateStatistics 264 (((IOptionalInstance) taskInstance).getChild(), session, statistics); 265 } 266 else{ 249 267 statistics.incrementNoOfOtherEventTasks(); 250 268 } … … 255 273 * 256 274 */ 257 private boolean isTextInput(ITask task) { 258 if (task.getInstances().size() > 0) { 259 ITaskInstance instance = task.getInstances().iterator().next(); 260 if (instance instanceof IEventTaskInstance) { 261 return ((IEventTaskInstance) instance).getEvent().getType() instanceof TextInput; 262 } 275 private boolean isTextInput(ITaskInstance taskInstance) { 276 if (taskInstance instanceof IEventTaskInstance) { 277 return ((IEventTaskInstance) taskInstance).getEvent().getType() instanceof TextInput; 263 278 } 264 279 … … 269 284 * 270 285 */ 271 private void calculateStatistics(IEventTask node, TextInputStatistics statistics) { 272 273 for (ITaskInstance instance : node.getInstances()) { 274 IEventType type = ((IEventTaskInstance) instance).getEvent().getType(); 275 IEventTarget target = ((IEventTaskInstance) instance).getEvent().getTarget(); 276 277 if (type instanceof TextInput) { 278 String[] fragments = 279 determineTextFragments(((TextInput) type).getEnteredText()); 280 281 if (target instanceof ITextField) { 282 statistics.addTextFieldInput(node, fragments); 283 } 284 else if (target instanceof ITextArea) { 285 statistics.addTextAreaInput(node, fragments); 286 } 287 } 288 } 289 } 290 291 /** 292 * 293 */ 294 private String[] determineTextFragments(String enteredText) { 286 private void calculateStatistics(IEventTaskInstance taskInstance, 287 IUserSession session, 288 TextInputStatistics statistics) 289 { 290 IEventType type = taskInstance.getEvent().getType(); 291 IEventTarget target = taskInstance.getEvent().getTarget(); 292 293 if (type instanceof TextInput) { 294 if (target instanceof ITextField) { 295 statistics.addTextFieldInput(taskInstance, session); 296 } 297 else if (target instanceof ITextArea) { 298 statistics.addTextAreaInput(taskInstance, session); 299 } 300 } 301 } 302 303 /** 304 * 305 */ 306 /* private static String[] determineTextFragments(String enteredText) { 295 307 List<String> fragments = new ArrayList<String>(); 296 308 … … 304 316 // the previous fragment ended. so finalize it and start a new one 305 317 if ((fragment != null) && (fragment.length() > 0)) { 306 fragments.add(fragment.toString()); 318 String fragmentStr = fragment.toString().trim(); 319 320 if (!"".equals(fragmentStr)) { 321 fragments.add(fragmentStr); 322 } 323 307 324 fragment = new StringBuffer(); 308 325 } … … 314 331 315 332 if ((fragment != null) && (fragment.length() > 0)) { 316 fragments.add(fragment.toString()); 333 String fragmentStr = fragment.toString().trim(); 334 335 if (!"".equals(fragmentStr)) { 336 fragments.add(fragmentStr); 337 } 317 338 } 318 339 … … 323 344 * 324 345 */ 325 privateboolean isEqualCharacterType(char char1, char char2) {346 /* private static boolean isEqualCharacterType(char char1, char char2) { 326 347 return 327 348 ((char1 == char2) || … … 330 351 (Character.isLetter(char1) && Character.isLetter(char2)) || 331 352 (Character.isJavaIdentifierPart(char1) && Character.isJavaIdentifierPart(char2))); 332 } 333 334 /** 335 * TODO comment 353 }*/ 354 355 /** 356 * 357 */ 358 private static class TextInputStatistics { 359 360 /** */ 361 private List<IEventTaskInstance> textFieldInputs = new ArrayList<IEventTaskInstance>(); 362 363 /** */ 364 private Map<ITextField, List<String>> textFields = new HashMap<ITextField, List<String>>(); 365 366 /** */ 367 private List<IEventTaskInstance> textAreaInputs = new ArrayList<IEventTaskInstance>(); 368 369 /** */ 370 private Map<IUserSession, Map<String, TextEntryData>> textEntries = 371 new HashMap<IUserSession, Map<String, TextEntryData>>(); 372 373 /** */ 374 private int otherEventsCount; 375 376 /** 377 * 378 */ 379 private void addTextFieldInput(IEventTaskInstance instance, IUserSession session) { 380 String enteredText = ((TextInput) instance.getEvent().getType()).getEnteredText(); 381 382 if ((enteredText != null) && (!"".equals(enteredText.trim()))) { 383 enteredText = enteredText.trim(); 384 385 textFieldInputs.add(instance); 386 387 // store text entries into text fields 388 List<String> entries = textFields.get(instance.getEvent().getTarget()); 389 390 if (entries == null) { 391 entries = new LinkedList<String>(); 392 textFields.put((ITextField) instance.getEvent().getTarget(), entries); 393 } 394 395 entries.add(enteredText); 396 397 // writing down all text entries in text fields to check later for cooccurrences in 398 // same session 399 Map<String, TextEntryData> sessionTextEntries = textEntries.get(session); 400 401 if (sessionTextEntries == null) { 402 sessionTextEntries = new HashMap<String, TextEntryData>(); 403 textEntries.put(session, sessionTextEntries); 404 } 405 406 TextEntryData data = sessionTextEntries.get(enteredText); 407 408 if (data == null) { 409 data = new TextEntryData(enteredText); 410 sessionTextEntries.put(enteredText, data); 411 } 412 413 data.addTaskInstance(instance); 414 } 415 } 416 417 /** 418 * 419 */ 420 public List<String> getAllInputsInto(ITextField textField) { 421 return textFields.get(textField); 422 } 423 424 /** 425 * 426 */ 427 private int getUsageCount(ITextField textField) { 428 List<String> entries = textFields.get(textField); 429 430 if (entries == null) { 431 return 0; 432 } 433 else { 434 return entries.size(); 435 } 436 } 437 438 /** 439 * 440 */ 441 private List<TextFieldCorrelation> determineTextFieldCorrelations() { 442 System.out.print("determining text field correlations of " + textFields.size() + 443 " text fields ... "); 444 List<TextFieldCorrelation> correlations = new ArrayList<TextFieldCorrelation>(); 445 446 // we need an ordered list of text fields to be able compare all with each other 447 // through a nested loop 448 List<ITextField> textFieldList = getAllTextFields(); 449 450 List<TextEntryData> relevantTextEntryData = new LinkedList<TextEntryData>(); 451 452 for (Map<String, TextEntryData> sessionSpecEntries : textEntries.values()) { 453 for (TextEntryData data : sessionSpecEntries.values()) { 454 if (data.textFields.size() > 1) { 455 relevantTextEntryData.add(data); 456 } 457 } 458 } 459 460 for (int i = 0; i < (textFieldList.size() - 1); i++) { 461 for (int j = i + 1; j < textFieldList.size(); j++) { 462 // count the number of times, in which the same text was entered in both 463 // text fields within the same session 464 List<String> sameEnteredTexts = new LinkedList<String>(); 465 466 for (TextEntryData data : relevantTextEntryData) { 467 if (data.textFields.contains(textFieldList.get(i)) && 468 data.textFields.contains(textFieldList.get(j))) 469 { 470 sameEnteredTexts.add(data.enteredText); 471 } 472 } 473 474 if (sameEnteredTexts.size() > 0) { 475 // for the checked combination of text fields, there is at least once 476 // the same text entered into both text fields during the same session 477 correlations.add(new TextFieldCorrelation(textFieldList.get(i), 478 textFieldList.get(j), 479 sameEnteredTexts)); 480 } 481 } 482 } 483 484 System.out.println("done"); 485 486 return correlations; 487 } 488 489 /** 490 * 491 */ 492 private void addTextAreaInput(IEventTaskInstance instance, IUserSession session) { 493 textAreaInputs.add(instance); 494 } 495 496 /** 497 * 498 */ 499 private int getNoOfAllEvents() { 500 return textFieldInputs.size() + textAreaInputs.size() + otherEventsCount; 501 } 502 503 /** 504 * 505 */ 506 private int getNoOfTextFieldInputs() { 507 return textFieldInputs.size(); 508 } 509 510 /** 511 * 512 */ 513 private int getNoOfTextAreaInputs() { 514 return textAreaInputs.size(); 515 } 516 517 /** 518 * 519 */ 520 private void incrementNoOfOtherEventTasks() { 521 otherEventsCount++; 522 } 523 524 /** 525 * 526 */ 527 private List<ITextField> getAllTextFields() { 528 List<ITextField> textFieldList = new ArrayList<ITextField>(textFields.size()); 529 530 for (ITextField textField : textFields.keySet()) { 531 textFieldList.add(textField); 532 } 533 534 return textFieldList; 535 } 536 } 537 538 /** 336 539 * 337 * @version $Revision: $ $Date: 16.07.2012$ 338 * @author 2012, last modified by $Author: pharms$ 339 */ 340 public static class TextInputStatistics { 341 342 /** */ 343 private List<Object[]> textFieldInputs = new ArrayList<Object[]>(); 344 345 /** */ 346 private List<Object[]> textAreaInputs = new ArrayList<Object[]>(); 347 348 /** */ 349 private int otherEventsCount; 350 351 /** 352 * 353 */ 354 public void addTextFieldInput(IEventTask node, String[] fragments) { 355 textFieldInputs.add(new Object[] { node, fragments }); 356 } 357 358 /** 359 * 360 */ 361 public void addTextAreaInput(IEventTask node, String[] fragments) { 362 textAreaInputs.add(new Object[] { node, fragments }); 363 } 364 365 /** 366 * 367 */ 368 public int getNoOfAllEvents() { 369 return textFieldInputs.size() + textAreaInputs.size() + otherEventsCount; 370 } 371 372 /** 373 * 374 */ 375 public int getNoOfTextFieldInputs() { 376 return textFieldInputs.size(); 377 } 378 379 /** 380 * 381 */ 382 public String[] getTextFieldInputFragments(int index) { 383 return (String[]) textFieldInputs.get(index)[1]; 384 } 385 386 /** 387 * 388 */ 389 public int getNoOfTextAreaInputs() { 390 return textAreaInputs.size(); 391 } 392 393 /** 394 * 395 */ 396 public String[] getTextAreaInputFragments(int index) { 397 return (String[]) textAreaInputs.get(index)[1]; 398 } 399 400 /** 401 * 402 */ 403 public void incrementNoOfOtherEventTasks() { 404 otherEventsCount++; 540 */ 541 private static class TextEntryData { 542 543 /** */ 544 private String enteredText; 545 546 /** */ 547 private List<IEventTaskInstance> respectiveTaskInstances = 548 new LinkedList<IEventTaskInstance>(); 549 550 /** */ 551 private Set<ITextField> textFields = new HashSet<ITextField>(); 552 553 /** 554 * 555 */ 556 private TextEntryData(String text) { 557 this.enteredText = text; 558 } 559 560 /** 561 * 562 */ 563 private void addTaskInstance(IEventTaskInstance instance) { 564 respectiveTaskInstances.add(instance); 565 textFields.add((ITextField) instance.getEvent().getTarget()); 566 } 567 568 } 569 570 /** 571 * 572 */ 573 private static class TextFieldCorrelation { 574 575 /** */ 576 private List<String> enteredTexts = new LinkedList<String>(); 577 578 /** */ 579 private ITextField textField1; 580 581 /** */ 582 private ITextField textField2; 583 584 /** 585 * 586 */ 587 private TextFieldCorrelation(ITextField textField1, 588 ITextField textField2, 589 List<String> enteredTexts) 590 { 591 this.textField1 = textField1; 592 this.textField2 = textField2; 593 this.enteredTexts = enteredTexts; 405 594 } 406 595 -
trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/UsabilityDefect.java
r1301 r1335 37 37 * 38 38 */ 39 publicUsabilityDefect(UsabilityDefectSeverity severity, UsabilityDefectDescription description)39 UsabilityDefect(UsabilityDefectSeverity severity, UsabilityDefectDescription description) 40 40 { 41 41 this(severity, description, null); … … 45 45 * 46 46 */ 47 publicUsabilityDefect(UsabilityDefectSeverity severity,48 49 47 UsabilityDefect(UsabilityDefectSeverity severity, 48 UsabilityDefectDescription description, 49 Map<String, String> parameters) 50 50 { 51 51 this.severity = severity; -
trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/UsabilityDefectDescription.java
r1301 r1335 33 33 public enum UsabilityDefectDescription { 34 34 35 SCROLL_REQUIRED, 35 36 TEXT_FIELD_INPUT_RATIO, 36 37 TEXT_FIELD_INPUT_REPETITIONS, -
trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/UsabilityEvaluationManager.java
r1301 r1335 46 46 private void init() { 47 47 rules.add(new TextInputStatisticsRule()); 48 rules.add(new RequiredScrollRule()); 48 49 } 49 50 … … 54 55 Console.traceln(Level.INFO, "evaluating usability of task model " + taskModel); 55 56 56 List<UsabilityEvaluationResult> results = new ArrayList<UsabilityEvaluationResult>();57 List<UsabilityEvaluationResult> interimResults = new ArrayList<UsabilityEvaluationResult>(); 57 58 58 59 for (UsabilityEvaluationRule rule : rules) { 59 60 Console.traceln(Level.INFO, "applying rule " + rule.getClass().getSimpleName()); 60 61 UsabilityEvaluationResult result = rule.evaluate(taskModel); 61 results.add(result);62 interimResults.add(result); 62 63 Console.traceln(Level.INFO, "the rule found " + result.getAllDefects().size() + 63 64 " usability defects, of which " + result.getSevereDefects().size() + … … 65 66 } 66 67 67 UsabilityEvaluationResult result = mergeResults(results);68 UsabilityEvaluationResult result = new UsabilityEvaluationResult(interimResults); 68 69 Console.println("the evaluation result contains " + result.getAllDefects().size() + 69 70 " defects, of which " + result.getSevereDefects().size() + " are severe."); 70 return result;71 }72 71 73 /** 74 * 75 */ 76 private UsabilityEvaluationResult mergeResults(List<UsabilityEvaluationResult> results) { 77 UsabilityEvaluationResult result = new UsabilityEvaluationResult(); 78 79 for (UsabilityEvaluationResult ruleResult : results) { 80 for (UsabilityDefect defect : ruleResult.getAllDefects()) { 81 result.addDefect(defect); 82 } 72 List<UsabilityDefect> defects = result.getAllDefects(); 73 for (int i = 0; i < defects.size(); i++) { 74 Console.println((i + 1) + ": " + defects.get(i).getParameterizedDescription()); 83 75 } 84 76 -
trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/UsabilityEvaluationResult.java
r1301 r1335 17 17 import java.util.ArrayList; 18 18 import java.util.List; 19 import java.util.Map; 19 20 20 21 /** … … 32 33 * 33 34 */ 34 public void addDefect(UsabilityDefect defect) { 35 defects.add(defect); 35 public UsabilityEvaluationResult() { 36 // default constructor 37 } 38 39 /** 40 * 41 */ 42 public UsabilityEvaluationResult(List<UsabilityEvaluationResult> results) { 43 for (UsabilityEvaluationResult result : results) { 44 for (UsabilityDefect defect : result.getAllDefects()) { 45 defects.add(defect); 46 } 47 } 48 } 49 50 /** 51 * 52 */ 53 public void addDefect(UsabilityDefectSeverity severity, 54 UsabilityDefectDescription description, 55 Map<String, String> parameters) 56 { 57 defects.add(new UsabilityDefect(severity, description, parameters)); 36 58 } 37 59 -
trunk/autoquest-core-usability/src/main/resources/defectDescriptions_en.xml
r496 r1335 12 12 <parameterFragment parameterName="textInputRatio" /> 13 13 <textFragment> 14 ). This should be reduced. As an example, entering data can also be done using check boxes14 %). This should be reduced. As an example, entering data can also be done using check boxes 15 15 or combo boxes in the case predefined values must be entered. 16 16 </textFragment> … … 19 19 <defectDescription defectId="TEXT_FIELD_INPUT_REPETITIONS"> 20 20 <textFragment> 21 Several interactions that enter text into text fields repeat tokens such as words or 22 specific signs ( 21 In 23 22 </textFragment> 24 23 <parameterFragment parameterName="textRepetitionRatio" /> 25 24 <textFragment> 26 ). This is an indicator that the same data must be entered several times. This could be 27 better supported by using e.g. automatic filling of input fields, provision of combo 28 boxes or lists prefilled with data that was already entered previously. 25 % of entering text into text field 26 </textFragment> 27 <parameterFragment parameterName="textField1" /> 28 <textFragment> 29 , the same text was also entered into text field 30 </textFragment> 31 <parameterFragment parameterName="textField2" /> 32 <textFragment> 33 during the same session. Perhaps this can be automated, so that the user does not have to 34 reenter the same text several times into different text fields. 29 35 </textFragment> 30 36 </defectDescription> 31 37 32 38 <defectDescription defectId="TEXT_FIELD_NO_LETTER_OR_DIGIT_RATIO"> 33 <textFragment>34 Much of the text entered into text fields contains signs other than letters or digits (35 </textFragment>36 39 <parameterFragment parameterName="noLetterOrDigitRatio" /> 37 40 <textFragment> 38 ). This is an indicator that the entered data has to follow a specific syntax. This should 39 be supported by syntax checking, auto completion or even providing the text fields in a way 40 that does not require the entering of special signs as they are already included at the right 41 positions. 41 % of the text entered into text field 42 </textFragment> 43 <parameterFragment parameterName="textField" /> 44 <textFragment> 45 was no letter or digit. This is an indicator that the entered data has to follow a specific 46 syntax. This should be supported by syntax checking, auto completion or even providing the 47 text fields in a way that does not require the entering of special signs as they are already 48 included at the right positions. 49 </textFragment> 50 </defectDescription> 51 52 <defectDescription defectId="SCROLL_REQUIRED"> 53 <textFragment> 54 In 55 </textFragment> 56 <parameterFragment parameterName="scrollRatio" /> 57 <textFragment> 58 % of all occurrences, the task 59 </textFragment> 60 <parameterFragment parameterName="task" /> 61 <textFragment> 62 is started with a scroll. This should be prevented as scrolling decreases the efficiency of 63 the user and indicates, that not all required information is visible at once in the 64 respective view. However, scrolling for reading of texts is no problem. 42 65 </textFragment> 43 66 </defectDescription>
Note: See TracChangeset
for help on using the changeset viewer.