12.5 Explaining error causes


12.5 Explaining error causes

There are many possible causes of errors, and the relationship between them is complex. The result is that predicting error timing isn’t possible. It is possible to identify circumstances that increase the probability of errors. When novices in a given competence domain make errors, these errors result from incompetence and are mostly random. When experts in a given competence domain make errors, they result mostly from misplaced competence.

Experts have a lower probability of making planning-oriented mistakes and a higher probability of making an execution-oriented skilled slip. It is easier to prevent an error that is the result of the conjunction of many causes than it is to prevent an error that has a single cause. All you have to do is break the causal chain anywhere to prevent the error from occurring.

12.5.1 Skill-based errors

Most errors that occur at the skill-based level fall into two categories. Inattention occurs when you fail to make an attention check at an important point while executing a routine sequence of actions. These types of errors often occur when the sequence is about to deviate from a standard pattern. Overattention occurs when you make an attention check at an inappropriate point while executing a routine sequence of actions.

12.5.2 Inattention failures

12.5.2.1 Interrupt sequence, start another sequence

Reason refers to these types of errors as double-capture slips, while Norman refers to them as capture errors, and Silverman [Si92] refers to them as capture slips.

These errors occur when the majority of your attention resources is claimed by internal or external distraction at a critical point in the execution of a sequence of actions. When it’s time to continue execution of the sequence, a sequence that has stronger weight and the same initial set of steps hijacks the execution.

The conditions for this error are the following:

  • You are doing an activity that you have practiced often.

  • You intend to perform some variation on this activity.

  • The standard form of the activity and the variation have a common initial sequence of steps.

  • You fail to pay attention at the place where the two sequences of steps diverge.

The following is a programming example of this type of error. Almost all counted loops use a step value of one. In C++ or Java, most counted loops begin with an initial value of zero. Experienced programmers write such loops as a single idiom without conscious thought. If you need to make the loop step in increments of two, rather than one, and you’re distracted as you begin writing the increment step, you may end up with the following code, rather than the intended version below it:

 // actual  for( counter=0; counter<limit; ++counter )  // intended  for( counter=0; counter<limit; counter += 2 ) 

12.5.2.2 Interrupt sequence, omit step

Reason refers to these types of errors as omissions following interruptions, while Silverman refers to them as omissions due to interruptions.

These errors occur when the majority of your attention resources is claimed by internal or external distraction at a critical point in the execution of a sequence of actions. When your attention returns to executing the sequence, you omit one or more steps from the sequence and continue on. These errors are more likely if you performed some action that will be treated as a substitute for the next step of the sequence.

The following is a programming example of this type of error. Coding switch compound statements in C++ and Java involves a double set of repetitions. The construct as a whole requires the switch keyword, an opening brace, a sequence of case statements, and a closing brace. Within a given case, you must provide the case keyword, an integer value followed by a semicolon, a block of one or more statements, and a break statement.

It is very easy to lose your place in a nested set of repetitions. It is easy to be distracted by some event on your computer, such as a task running in the background, which suddenly pops up a window. If this happens, you may unconsciously substitute the response to that window as the next action you should have taken in composing the switch statement. This may cause you to omit an entire case, or even more unfortunately, omit the break statement. In either case, your switch will be syntactically correct and won’t be rejected by the compiler.

12.5.2.3 Interrupt sequence, repeat step

Silverman refers to these types of errors as repetitions due to interruptions. These errors occur when the majority of your attention resources is claimed by internal or external distraction at a critical point in the execution of a sequence of actions. When your attention returns to executing the sequence, you repeat the step you last executed from the sequence and continue on.

The following is a programming example of this type of error. There are several constructs in C and Java where it’s possible to stutter at the keyboard and not have the error caught by the compiler. The simplest is entering the digits of a numeric constant or any character within a literal constant.

Under certain circumstances, it’s possible to add an additional asterisk “*” in a pointer declaration or a pair of brackets “[]” in an array declaration and create a source file that will compile. The likelihood of this error increases in C, particularly if the variable is local and not passed in function calls that would be subject to prototype checking.

12.5.2.4 Sequence interrupted, loss of control

Reason refers to these types of errors as reduced intentionality, while Norman refers to them as loss-of-activation errors, and Silverman refers to them as loss of schema activation.

These errors occur because a delay intervenes between the time you decide to do something and the time you’re in a position to start executing the sequence of actions. If you have ever gone into another room in your home and forgotten why you were there, this is the type of error you have experienced.

The following is a programming example of this type of error. Often as we write the code for one C++ function or Java method, we realize that we need to add or modify the code in another class, which is usually in a different source file. If you have ever found yourself in this situation, opened the source file for the second class, and then wondered what you wanted to change in that file, this is the type of error you experienced.

12.5.2.5 Multiple matches, incorrect choice

Reason refers to these types of errors as perceptual confusions, while Norman refers to them as description errors. These errors occur because the recognition schemata accept a match for an object that looks similar, is in a similar place, or does a similar job. Many of the anecdotal cases of this error involve putting things into, or taking things out of, the wrong container. They occur most often when the right and wrong objects aren’t only similar in appearance but also adjacent to each other.

The following is a programming example of this type of error. The metaphor of the desktop and the use of icons to represent objects to be directly manipulated makes it possible for software users to commit these types of errors.

Programmers used to be counseled to put Exit and Help function keys at the opposite ends of the keyboard. Since the action (pressing the key) is the same, the target location should be quite different to avoid errors. The same principle applies to putting similar icons next to one another on toolbars. If two icons look very similar, the action of clicking the mouse on them is the same, and buttons are right next to each other, the probability is high that users will click the wrong button some of the time.

12.5.2.6 Multiple sequences active, steps mixed

Reason refers to these types of errors as interference errors, and Norman refers to them as associative activation errors. Silverman refers to them as associative schema activation, but also distinguishes two additional categories: spoonerisms and schema binding slips. He considers the first an issue of information acquisition, while the other two are information-processing issues.

These errors occur when two currently active sequences or two elements of a sequence become entangled. This can occur because the current sequence triggers others with which it is associated or because attentional resources are being divided between two sequences that are both being executed at the same time.

This type of error is the famous Freudian slip—you think about something that you shouldn’t say and then you say it. The spoonerism, which is a ludicrous transposition of the sounds of two or more words, is also included in this category.

The following is a programming example of this type of error. The idiom for swapping two values is

 temp= left  left= right  right= temp 

The relationship between pointer dereferences and array element references in C++ is the following:

 *(a+i) == a[i] 

If a programmer is trying to swap two values and cleverly minimize typing by using the relationship between array references and pointers, two different sequences are active. This can result in erroneous code like the following:

 *a = a[1]  a[1] = a[2]  a[0] = a[1] 

12.5.2.7 Sensory input interferes with active sequence

Norman refers to these as data-driven errors, while Silverman refers to them as data-driven schema activation. Automatic actions that are skill-based are normally driven by the arrival of data from the five senses. Sometimes, however, the arrival of sensory data can intrude into an active action sequence.

The following is a programming example of this type of error. If you’re typing in literal or numeric data that will be used to initialize arrays, files, and so forth, you should be careful not to expose yourself to sources of similar input. It is very easy to get distracted while doing such menial work and for your mind to slip in the other data as an item to be entered.

People most frequently experience this error while absentmindedly dialing a phone number and including digits from some other source they’re looking at or thinking about. It is just as possible to do this while keying data, and there will be no wrong number message to warn you of your error.

12.5.3 Overattention failures

Overattention occurs when you make an attention check at an inappropriate point while executing a routine sequence of actions. If you’re a touch typist, try typing while concentrating on how your fingers are moving over the keyboard as you type. Or, if you play the piano, focus on the movement of a single finger as you play a piece that you know by heart. You will likely experience a greater error rate than normal. This is due to the intrusion of attention on skill-based behavior.

Reason notes that these types of overattention errors can manifest themselves as omissions, repetitions, and reversals. He suggests that overattention errors are particularly likely when the task at hand involves a series of steps mixed with periods of waiting between the steps. The waiting periods increase the likelihood that extra attention will be focused on the task when it should be performed automatically.

12.5.4 Memory failures

Silverman documents a number of errors that occur during skill-based reasoning.

  • Forgetting a goal: You execute an action sequence but forget why you’re doing it.

  • Order memory error: You temporarily forget the order in which actions in a sequence should be performed.

  • Spacing memory error: You temporarily forget the physical or chronological spacing between actions in a sequence.

  • Coordinating memory error: You temporarily forget the motions of physical objects required in the action sequence.

  • Remembering incorrectly: You forget how proficient you actually are in executing a specific action sequence.

  • Not remembering: You forget the actual steps of a sequence and need to relearn the skill.

These skill-based errors can all occur when a programmer is performing a sequence of actions that are part of a learned skill.

12.5.5 Rule-based errors

Most errors that occur at the rule-based level fall into two categories:

  1. Misapplication of good rules occurs when a rule that has proven to be effective in the past is applied in a situation that has the indicated conditions, but also contains additional conditions that require the execution of a different rule.

  2. Application of bad rules occurs when not all of the conditions of a situation are represented correctly or when the action corresponding to a set of conditions will result in an ineffective or inefficient action.

When a person is performing rule-based problem solving, more than one rule will be competing to represent the solution. Which rule is selected depends on several factors:

  • The conditions of the rule must be satisfied.

  • The rule with a stronger weight will be preferred, where the weight is determined by the past success of this rule in solving the problem.

  • The more specific rule will be preferred.

  • The rule with support from other rules being evaluated will be preferred.

Rules are organized into a hierarchy, with the most general rules evaluated first. Rules that handle exceptions to the general cases are found in lower levels of the hierarchy.

Consider the following set of rules, which is a representation of how a typical programmer might handle the problem of selecting a representation for a dictionary data structure.

  • If every entry to be looked up in a dictionary occurs exactly once, Then use a hash table.

  • If the same key can have multiple values in a dictionary, Then use a tree.

  • If the same key can have multiple values in a dictionary, but only the most recent is visible,

    Then use a series of hash tables chained together.

This set of rules doesn’t cover all possible uses of a dictionary data structure. It does cover several major applications of that structure (sets, natural languages, symbol tables in block-structured languages). When the current set of rules doesn’t cover a new situation, the problem solver goes into knowledge-based thinking.

12.5.6 Misapplication of good rules

12.5.6.1 General rule, exception condition

A rule that has been successful in the past acquires greater strength. The first time a person runs into an exception to a general rule, especially when that rule has been an effective solution to the problems encountered, the more likely it’s that he or she will choose the general rule, despite the exceptional condition.

The cognitive psychologists theorize that these situations cause the mind to generate rules to handle exceptions. The first time the exception is encountered, the general rule is tried, and the solution fails. This failure results in an exception rule being generated. Reason refers to these types of errors as first exceptions.

The following is a programming example of this type of error. Consider the following set of rules, which is a representation of how a typical programmer might handle the problem of selecting a sorting algorithm:

  • If the number of items to be sorted will always be relatively small, Then use Shellsort.

  • If the number of items to be sorted will always be unknown, Then use Quicksort.

This is a reasonable rule set that might serve a programmer well. The first time he or she comes upon a sorting situation that requires a stable sort of a large number of items, a bug will result. Quicksort isn’t a stable sort. Another rule covering this exception condition is needed.

12.5.6.2 Conflicting signals

In a complex problem-solving situation, a person may be exposed to a variety of information as he or she evaluates rules. There will be “signs,” or inputs that satisfy some aspect of the conditions of a potential rule. There will also be “countersigns,” or inputs that suggest using a more general rule. Finally, there will be “nonsigns,” or inputs not relating to any existing rule, which are basically just background noise.

The countersigns can influence the choice of a general rule over a specific one, and the nonsigns can cause problems just by distraction.

The following is a programming example of this type of error. Consider the following set of rules, which is a representation of how a programmer might handle the problem of selecting a sorting algorithm:

  • If the number of items to sort is unknown. Then use Quicksort.

  • If the number of items to sort is less than twenty-five, Then use Shellsort.

If the requirements indicate that maximum performance is necessary, then the general rule should be matched, since a properly implemented Quicksort will use O(2 * N * ln N) comparisons on average. If the requirements also include optimal sorting of short files, then there is a conflict.

12.5.6.3 Excess information, multiple rule match

The storage capacity of the human conscious memory is extremely limited. If a number of conditions are relevant to the problem being analyzed, it’s possible that some of them will simply fall out of consideration due to capacity problems.

One of the possible results of information loss is that several rules will match. This happens because not all of the context information is available and being used. If the choice between the matching rules is made without the missing context information, an error can result. Reason refers to these types of errors as informational overload.

12.5.6.4 Rule strength versus rule conditions

A rule that has been successful in the past has greater strength. The first time a person runs into an exception to a general rule, especially when that rule has been an effective solution to the problems encountered, it’s likely that he or she will choose the general rule, despite the exceptional condition. Reason refers to this as rule strength.

The following is a programming example of this type of error. Consider the following set of rules, which is a representation of how a typical programmer might handle the problem of selecting a sorting algorithm:

  • If characteristics of the input data are unknown,

    Then use Quicksort.

  • If a stable sort is required,

    Then use Mergesort.

  • If it is likely that the input data is mostly sorted,

    Then use Shellsort.

If the programmer has achieved many satisfactory results using Quicksort, he or she may be inclined to use it, even when input is probably mostly sorted. This decision is easy to make, despite the fact that an insertion sort like Shellsort operates in linear time on mostly sorted data and that Quicksort is much slower in such cases. While this easy decision won’t cause the application to produce incorrect results, it may make it significantly slower.

12.5.6.5 Other rule problems

There is a natural conflict between general rules and exception rules. General rules often gain greater weight because they’re exercised successfully so frequently. On the other hand, exception rules match the circumstances of the problem more precisely. Sometimes people apply the general rule when they should apply an exception rule, because the weight of the general rule is so strong. Reason refers to these types of problems as general rules errors.

As people formulate rules to solve problems, they learn to focus on the key indicators of the circumstances. This means that they also learn to treat the other indicators as redundant information and not use that information. If this information is ignored when it’s important, an error occurs. Reason refers to these types of problems as redundancy errors.

Studies show when people develop habits for solving problems, those habits can overshadow the condition-matching thought process. Humans are strongly biased to apply techniques that worked in the past, even though the current circumstances are no longer the same. Reason refers to these types of problems as rigidity errors.

12.5.7 Application of bad rules

Rules can be incorrect because they don’t match the right combination of circumstances, or because they don’t perform the right actions when the circumstances are matched.

12.5.7.1 Incorrect rule conditions

The condition part of rules can be incorrect in several ways. Aspects of the problem to be solved may be not represented at all in the condition part of a rule that is intended to address the problem.

Other aspects of the problem may be represented inaccurately. A state may be Boolean and represented as a multiple choice, or vice versa. A threshold value may be considered as a discrete integer, when it really is a function of a continuous set of real numbers. Components of the condition may be treated as mutually exclusive when they’re not, or vice versa. Components of the condition may be connected by disjunction when they should be connected by conjunction, and vice versa.

An erroneous general rule may be effectively nullified by a series of valid exception rules that prevent its activation. Reason refers to errors caused by these problems as encoding deficiencies.

The following is a programming example of this type of error. Consider the following set of rules, which is a representation of how a programmer might handle the problem of selecting a sorting algorithm:

  • If comparisons are relatively expensive, but exchanges are inexpensive, Then use an insertion sort.

  • If comparisons are relatively inexpensive, but exchanges are expensive, Then use a selection sort.

Selection sorts use about O(N ^2/2) comparisons and N exchanges. Insertion sorts use about O(N ^ 2/4) comparisons and O(N ^ 2/8) exchanges, on average [Se90]. Given these bounds, the rule set is helpful when N = 8. Thus, the rules that govern the selection of a sorting algorithm are only correct under certain circumstances.

12.5.7.2 Incorrect rule actions

Rule actions can be wrong because someone learned how to do something incorrectly or how to do something that is no longer, or is only sometimes, correct. Reason refers to these as action deficiencies.

12.5.7.3 Frequently ineffective rules

Sometimes people just learn things incorrectly. When the algorithms they use generate nondeterministic results, they may be shielded from their misunderstanding for a long time. Reason refers to these as wrong rules.

The following is a programming example of this type of error. Consider the following set of rules, which is a representation of how a programmer might handle the problem of selecting a sorting algorithm for a C program:

  • If the values to be interchanged are the values to be compared, Then call the library qsort routine.

  • If the values to be interchanged aren’t the values to be compared, Then write a Quicksort that generates a permutation vector, which is applied to the values to be interchanged after sorting.

If these are the only rules for selecting sorting algorithms, the programmer will be quite unhappy with the results the first time a stable sort is required and Quicksort’s lack of stability becomes obvious. It may take thousands or millions of executions of a program before it happens.

12.5.7.4 Formerly effective rules

There are often many ways to solve a programming problem. Sometimes the rules we learn to solve one problem later introduce other problems. Reason refers to these as inelegant or clumsy rules. He notes that these rules are often introduced to achieve economies of effort that are later counterproductive.

The following is a programming example of this type of error. In the 1970s and 1980s, it was common for programmers to manually unroll the loops that they wrote. Loop unrolling replicates the loop body in the source code and divides the number of iterations of the loop by the number of times the body was replicated.

Programmers did this because the overhead of a loop was considered high, and the compilers did not perform automatic loop unrolling. In the 1990s, automatic loop unrolling became an essential optimization for Reduced Instruction Set Computers (RISC) processors, and optimizing compilers frequently performed loop unrolling automatically.

Unfortunately, the factor to which a loop is unrolled is highly machine dependent. This means that the manually unrolled loops in older code usually had the wrong unrolling factor and actually were slower on newer machines. Loop rerolling is possible for partially unrolled loops, but very few compilers perform this optimization. As a result, the rules programmers followed for manually unrolling loops to speed up applications actually had the opposite effect over time.

12.5.7.5 Occasionally effective rules

These rule sets are sufficient to achieve the goal under normal circumstances, but occasionally cause problems. Reason refers to these as inadvisable rules.

The following is a programming example of this type of error. Consider the following set of rules, which is a representation of how a programmer might handle the problem of selecting a stable sorting algorithm:

  • If auxiliary storage is an issue,

    Then use Quicksort.

  • If auxiliary storage is an issue, and the sort must be stable,

    Then use Quicksort, and add a secondary key to preserve stability.

  • If auxiliary storage isn’t an issue, and the sort must be stable,

    Then use Mergesort.

The auxiliary memory required by Mergesort grows linearly with the size of the input. What some programmers forget is that if Quicksort is implemented using recursion, rather than using an explicit stack, and if the file is already sorted, the stack size grows linearly with the input. This is quite different from the O(lg N) size that is required without recursion. To add insult to injury, the Quicksort solution has added a secondary key to preserve stability.

If the programmer is developing software for a system with limited memory, the auxiliary storage requirements of algorithms become a major concern. This rule set will work for many situations. It will, however, use much more storage than necessary if a stable sort is required and the file is already largely sorted.

12.5.8 Knowledge-based errors

Based on the preceding sections, it should be clear that debugging itself is a knowledge-based problem-solving activity. In this section, we explain various types of knowledge-based errors and how to avoid encountering them during the debugging process.

12.5.8.1 Misdirected focus

Research has shown that people tend to focus on those aspects of a problem that are emotionally or psychologically interesting, rather than those that are logically important. A common cause of reasoning errors is giving attention to the wrong aspects of the problem, or not giving attention to the right aspects. Reason refers to these types of errors as selectivity.

A significant part of the debugging process involves knowledge-based reasoning. The programmer must deal with novel situations, since we rarely make exactly the same type of nontrivial mistake in the same context. The previous chapters have introduced methods for enabling programmers to perform knowledge-based reasoning about program defects more effectively.

How can we avoid this error during the debugging process? We have previously recommended keeping a record of the symptoms under investigation. We can enhance this approach by recording the reason why we choose to investigate a particular symptom during our debugging efforts. If we make explicit our reasons for our choices, we may be less likely to choose the symptoms that are appealing, rather than those that are important.

12.5.8.2 Storage limitations

Research has shown that the storage capacity of the conscious mind performing knowledge-based reasoning is extremely limited. Researchers have also observed that storage in the short-term memory works on the first-in, first-out principle. In addition, people tend to place greater emphasis on the first and last items in a set of information.

This means that the presentation of a problem can have a great impact on the ability of the conscious mind to store all the relevant information as it reasons through a problem. Reason refers to these types of errors as work-space limitations, while Silverman discusses order effects.

How can we avoid these errors during the debugging process? Once again, the written record of our debugging efforts is an important technique for avoiding reasoning errors. Whether we record observations, hypotheses, and experiments on paper, in a file on our workstation, or on a handheld computer, our view of the problem is much more likely to be comprehensive if it’s recorded.

12.5.8.3 Information availability

Research has shown that people give too much weight to facts that readily come to their minds. In addition, they have the tendency to ignore information that isn’t immediately accessible.

Reason refers to these types of errors as out of sight, out of mind, while Silverman distinguishes two variations of this problem: availability and ease of recall. The former refers to using only widely available information, which is external to the problem solver. The latter refers to using only easily recallable information, which is necessarily internal to the problem solver.

How can we avoid this error during the debugging process? A written record of observations can reduce the possibility of this error during debugging.

12.5.8.4 Hypothesis persistence

Research has shown that preliminary hypotheses formed on the basis of incomplete data early on in a problem-solving process are retained in the face of additional, more complete data available later.

Reason refers to these types of errors as confirmation bias, while Silverman sees three variations on this theme: confirmation, selective perception, and expectations. The first variation refers to failing to judge hypotheses that might nullify a previously held conclusion. The second refers to seeking only information that confirms the previously held conclusion. The third refers to attaching greater weight to information that supports the previously held conclusion.

How can we avoid this error during the debugging process? Unlike the first three knowledge-based errors, this problem needs more than just a written record of the investigation.

The information needs to be structured so that the supporting evidence for different hypotheses can be reviewed in parallel. The same is true for the rebutting evidence. One way to build such a structure is to use an outline editor. Put a pro and con branch under each hypothesis. To review the supporting evidence for multiple hypotheses, expand the pro section of each outline point, but leave the con section collapsed. Review both the supporting and rebutting evidence for competing hypotheses at regular intervals when you’re assessing your progress.

12.5.8.5 Selective support

Research has shown that problem solvers are often overconfident about the correctness of what they know. Not only do they tend to justify their plans by focusing on the information that supports the plan, but also they will even ignore information that doesn’t support the plan.

How can we avoid this error during the debugging process? Unlike the first three knowledge-based errors, this problem needs more than just a written record of the investigation.

The information needs to be structured so that the supporting evidence for different hypotheses can be reviewed in parallel. The same is true for the rebutting evidence. Use the same approach as described in the previous section on hypothesis persistence. A structure that can show the supporting and rebutting evidence for a hypothesis can be valuable here as well.

Cognitive psychology research also shows that the likelihood of this error increases with the expertise of the problem solver. This error is compounded if the plan is very detailed, was created with a great deal of work and emotional investment, or was created by a group of people working together.

Reason refers to these types of errors as overconfidence, and Silverman refers to them similarly. The way to avoid this error during the debugging process is the same as that for the previous error type. It is particularly important to give as much consideration to the opposing evidence as to the supporting evidence. Assigning numerical weights to each evidence item and summing the weights might be an effective way to treat both sides evenly.

12.5.8.6 Limited reviewing

Research has shown that when problem solvers review a planned course of action, they often do an incomplete job. The problem is that people don’t consider all of the factors that are relevant to their plan, and they only consider them one or two at a time, instead of in combination. Reason refers to these types of errors as biased reviewing.

How can we avoid this error during the debugging process? The methods described in Chapter 11 are very good at showing the relationship between contributing conditions to a problem. Both cause-and-event charting and fault-tree analysis could be used to avoid this mental error.

For a simpler approach, write a little program that prints all the lines of a file taken in all possible combinations. Describe all the possible contributing factors to the problem in a single sentence and put each in a separate line in a file. Run your program on your file and review all the combinations separately.

For example, for a problem with four contributing factors, first consider the six combinations of factors taken two at a time. Next, consider the four combinations of factors taken three at a time. Finally, consider the combination of all factors together.

12.5.8.7 Inadequate data

People often come to conclusions based on inadequate information. Information can be inadequate for several reasons. It can be preliminary or cover only a limited period of the total time that can be observed. It can also be an inadequate sample size for the actual population being analyzed. It has been shown that people are very likely to draw conclusions from completely inadequate samples.

We can avoid inadequate data collection in several ways. If we’re collecting data over a fraction of the time that a process or event occurs, we should be able to justify why that small time period is representative.

For example, if we’re observing the memory usage of a program, we must be able to characterize the memory allocation and deallocation behavior across the time period and across the total program execution. As a check on our tendency toward rationalization, it’s good to describe our sampling period as a percentage of the total time.

If we’re collecting data for a large population, we must be able to defend the sampling method used. For example, if we’re sampling the hardware program counter to create an execution profile, the rate of sampling must be frequent enough that short procedures have a chance to be represented. As a check on our tendency toward rationalization, it’s good to describe our sample size as a percentage of the total population.

12.5.8.8 Multiple variables

Research has shown that problem solvers do a very poor job of dealing with variables that are partially related. Statistics teaches that in the case where two variables are partially related, when one of the variables takes on an extreme variable, the other variable tends to take on less extreme values. This is called the regression effect.

Unfortunately, when people are asked to predict the future values of variables that are partially related to other variables, they tend to choose the extreme values, rather than those that tend toward the mean. This explains why so many people invest in stocks or mutual funds that did very well in the previous year (an extreme), only to be disappointed by more average performance in the following year. Reason refers to these types of errors as illusory correlation, while Silverman refers to them as illusion of correlation.

12.5.8.9 Misplaced causality

People tend to have problems correctly attributing causality. Studies have shown that people are likely to judge causality based on their perception of the similarity between a potential cause and its effect. Reason and Silverman refer to this type of error as the representativeness problem.

How can we avoid problems with incorrectly assigning causality? The cause-and-event-charting and fault-tree-analysis methods described in Chapter 11 are very good at showing the relationship between contributing conditions to a problem. An objective diagram showing cause and effect is a good counter to assigning causality based upon faulty intuitions.

12.5.8.10 Dealing with complexity

People tend to have trouble working with complex processes that occur over time and prefer to deal with a single moment. They also have problems coping with processes that have exponential growth or decay and think in terms of linear change. People have problems thinking about multiple side effects of an action or event, which spread in a manner analogous to a network. They prefer to think in linear sequences of cause and effect instead.

How can we avoid problems with dealing with complex situations? Once again, the cause-and-event-charting and fault-tree-analysis methods are very helpful in exposing change over time and showing nonlinear relationships between causes and effects.

12.5.8.11 Decisions and probability

A number of studies have shown that people don’t make good decisions in circumstances that require assessing probabilities. We don’t currently see an application of these knowledge-based errors to debugging, since the causes of software defects are deterministic. Either something is a cause of a defect, or it’s not.

For completeness, we survey these errors briefly, in the hopes that future studies on debugging might find applications for them. They demonstrate that people commit many different types of knowledge-based errors when making decisions. Readers who are interested in pursuing these topics further should read M. Piatelli-Palmarini’s Inevitable Illusions [Pi94] and T. Gilovich’s How We Know What Isn’t So [Gi91].

Ease of representation

People tend to assign a higher likelihood to events that are easier to remember or easier to imagine. They decide to take precautions against negative events based primarily not on their likelihood, but on their emotional impact.

Framing of choices

People tend to select a choice that is described in terms of the likelihood of positive outcome rather than a choice that is described in terms of negative outcome. Positive outcomes are situations like succeeding, winning, or being cured of an illness. Negative outcomes are situations like failing, losing, or succumbing to an illness. This tendency is observed even when the probability of the negative outcome is just the probability of the positive outcome subtracted from one:

  • P(negative) = 1 – P(positive)

Conjunction effect

People tend to rate as more probable those circumstances that they find easier to imagine or that seem more typical. This behavior becomes problematic when a circumstance is the simultaneous occurrence of several items, each of which isn’t a certainty. Mathematics teaches us that the probability of two or more events is the product of their individual probabilities. In the situation described above, none of individual items is a certainty, which has probability of one. Thus, the product will be smaller than the individual probabilities, and the conjunction will be less likely than any of the individual items.

Base rates

When they assess probabilities, people tend to give lesser weight to, even to ignore, general or abstract information than they do to concrete or specific case data. This phenomenon is known to psychologists as neglect of base rates. This problem occurs most often in situations in which a person must make a decision about an individual object or person that is part of a large population of individuals belonging to some particular class.

Certainty effect

People tend to be willing to incur greater costs than are justified by the economic benefit to achieve illusory certainty about taking risks. Similarly, they expect to receive a greater payback for taking risks to achieve illusory certainty. An example of this problem is the great desire on the part of the general public to seek laws and regulations that purport to reduce to zero the probability of certain accidents, diseases, and so forth.

Disjunction effect

People tend to have trouble making decisions when they’re faced with two more choices, one of which will occur with certainty some time in the future. What starts out as prudence in the face of uncertainty often becomes paralysis.

Gambler’s fallacy

The basic problem that this item covers is the notion that the occurrence of a run of some event affects the likelihood of that event occurring again. In the world of gaming, players assume that a series of outcomes increases the likelihood of that outcome recurring. In the world of sports, players assume that a series of successes (or failures) increases the likelihood of the same result again. If the events are truly independent, such as the roll of an honest pair of dice, there is no relationship between past and future outcomes.




Debugging by Thinking. A Multidisciplinary Approach
Debugging by Thinking: A Multidisciplinary Approach (HP Technologies)
ISBN: 1555583075
EAN: 2147483647
Year: 2002
Pages: 172

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net