You are on page 1of 45

Program Correctness & Efficiency

Briana Morrison
Outline
Categories of program errors
Throwing an exception:
 What it means
 How to do it
Why you should catch exceptions
A variety of testing strategies
Debugging techniques Big-O notation
 What it is
 How to use it to analyze an algorithm’s
efficiency
2
Program Defects and “Bugs”
An efficient program is worthless if it breaks
or produces a wrong answer
Defects often appear in software after it is
delivered
Testing cannot prove the absence of defects
It can be difficult to test a software product
completely in the environment in which it is
used
Debugging: removing defects

3
Major Categories of Defects

Syntax and other in-advance errors

Run-time errors and exceptions

Logic Errors
4
Syntax Errors
Syntax errors: grammatical mistakes in a
program
The compiler detects syntax errors
 You must correct them to compile successfully
Some common syntax errors include:
 Omitting or misplacing braces, parentheses, etc.
 Misplaced end-of-comment
 Typographical errors (in names, etc.)
 Misplaced keywords

5
Semantic Errors
Semantic errors: may obey grammar, but violate
other rules of the language
The compiler detects semantic errors
 You must correct them to compile successfully
Some common semantic errors include:
 Performing an incorrect operation on a primitive type
value
 Invoking a member function not defined
 Not declaring a variable before using it
 Providing multiple declarations of a variable
 Failure to include a library header
6
Run-time Errors or Exceptions
Run-time errors
 Occur during program execution (run-
time!)
 Occur when the C++ run-time library
detects an operation that it knows to be
incorrect
 Cause program to halt execution
Examples of run-time errors include
 Division by zero
 Array index out of bounds
 Null pointer reference 7
Run-time Errors or Exceptions
(continued)
Run-Time Error Cause
Division by zero Integer division by zero.
Array index out of bounds Attempt to access an array with an index value that is greater
than the array length (not detected by C+ + ).
Null pointer reference. Attempt to dereference a pointer whose value is NULL.

8
Logic Errors
A logic error is programmer mistake in
 the design of a class or method, or
 the implementation of an algorithm
Most logic errors
 Are not syntax or semantic errors: get by
the compiler
 Do not cause run-time errors
 Thus they are difficult to find
Sometimes found through testing
Sometimes found by users
9
Ways to Indicate an Error
Return a special value
Use a bool return value to indicate
success or failure.
Set a global variable.
Print an error message.
Print an error message and exit the
program.
Put an input or output stream in a fail
state.
Throw an exception 10
Example – using a special
return value
The function get_element_of_x will return
numeric_limits<int>::min() if the index is not
valid.
It’s use is illustrated as follows:
int value = get_element_of_x(i);
if (value > numeric_limits<int>::min()) {
// Do something with value
. . .
} else {
// Recover from the error
. . .
}
// Continue normal processing 11
Throwing an Exception
Using special return values to indicate
errors can lead to complicated logic.
The error detection/recovery logic is
intermixed with the normal processing.
Using exceptions allows separation of
the error detection/recovery logic from
the normal processing logic.

12
Example using a throw
/** Gets the value in the element of array x with subscript index.
@param index The subscript of the element to be retrieved
@return The value stored at x[index]
@throws A std::out_of_range exception if index is not in range.
*/
int get_element_of_x(int index) {
if (index < 0 || index >= X_SIZE) {
throw std::out_of_range(
"In get_element_of_x, "
"the value of index is out of range");
}
return x[index];
}

13
Uncaught exceptions
If there is no exception handler, the program
execution is aborted.
The message depends on the compiler and
operating system.
 The g++ compiler issues the message
Aborted
 The Microsoft .NET C++ compiler issues the
message
This application has requested the Runtime to
terminate it in an unusual way.
Please contact the application's support team
for more information.
14
Catching and Handling Exceptions
A try block encloses functions that may throw
an exception.
One or more catch blocks (exception
handlers) follow the try block.
try {
val = get_element_of_x(10);
}
catch (std::out_of_range& ex) {
std::cerr << "Out_of_range exception\n";
std::cerr << ex.what() << std::endl;
std::abort();
}
15
Standard Exceptions
Sta nda rd Exception Reas on Thrown Thrown by
bad_alloc Memory not available. The new operator.
bad_cast Attempt to cast a reference that is not of The dynamic_cast operator.
the target type.
bad_typeid Attempt to obtain the typeid of a null The typeid operator.
pointer or the default typeid object.
domain_error Function not defined for the input Not thrown by the C+ + standard
value. library.
invalid_argument Invalid function argument. The bitset constructor.
length_error Attempt to create a string or vector that The string and vector classes.
is larger than the maximum allowed size.
out_of_range Index that is larger than size() The at operator in the string,
vector, and deque class.
ios_base::failure An error flag is being set that matches Input/ output stream objects after an
one set by an earlier call to the erroneous input/ output operaton.
exceptions function.

16
Testing Programs
A program with
 No syntax/semantic errors, and

 No run-time errors,

 May still contain logic errors

“Best” case is logic error that always executes


 Otherwise, hard to find!

Worst case is logic error in code rarely run

Goal of testing: Test every part of the code, on


“good” and “bad”/”hard” cases
17
Testing Defined
Testing:
 Exercising a program under controlled

conditions
 Verifying the results

Purpose: detect program defects after


 All syntax/semantic errors removed

 Program compiles

No amount of testing can guarantee the absence


of defects in sufficiently complex programs
18
Levels of Testing
Unit testing: checking the smallest testable
piece
 A method or class

Integration testing:
 The interactions among units

System testing: testing the program in context


Acceptance testing: system testing intended
to show that the program meets its functional
requirements

19
Some Types of Testing
Black-box testing:
 Tests item based only on its interfaces

and functional requirements


 Assumes no knowledge of internals

White-box testing:
 Tests with knowledge of internal

structure

20
Preparing to Test
Develop test plan early, in the design phase
 How to test the software
 When to do the tests
 Who will do the testing
 What test data to use
Early test plan allows testing during design &
coding
Good programmer practices defensive
programming
 Includes code to detect unexpected or invalid

data
21
Testing Tips for Program Systems
Program systems contain collections of
classes, each with several methods
A method specification should document
 Input parameters

 Expected results

Carefully document:
 Each method parameter
 Each class attribute (instance and static variable)
 As you write the code!

22
Testing Tips for Program Systems
Trace execution by displaying method
name as you enter a method:
#define TRACING
...
int compute_weight (...) {
#ifdef TRACING
cerr << "Entering
compute_weight\n";
#endif
. . .
}
23
Testing Tips for Program Systems
Display values of all input parameters
on entry:
int compute_weight (float volume,
float density) {
#ifdef TRACING
cerr << "Entering computeWeight";
cerr << "volume = " << volume;
cerr << "density = " << density <<
'\n';
#endif
...
}
24
Testing Tips for Program Systems
Display values of any class data
members (instance and static) accessed
by the method
Display values of all method outputs at
point of return from a method
Plan for testing as you write each
module,
 Not after the fact!

25
Developing Test Data
Specify test data during analysis and design
 For each level of testing: unit, integration, and system
Black-box testing: unit inputs  outputs
 Check all expected inputs
 Check unanticipated data
White-box testing: exercise all code paths
 Different tests to make each if test (etc.) true and false
 Called coverage

26
Developing Test Data (2)
Helpful to do both black- and white-box
testing
Black-box tests can be developed early
since they have to do with the unit
specification
White-box tests are developed with
detailed design or implementation: need
code structure

27
Testing Boundary Conditions
Exercise all paths for
 Hand-tracing in a structured walkthrough

 Performing white-box testing

Must check special cases:


boundary conditions
Examples:
 Loop executes 0 times, 1 time, all the way to the
end
 Item not found

28
The Big Idea
How will we compare one data structure with
another?
How do I know when to use a Red-Black Tree
versus a Hash Table?

We must know something about the operations


that each support, and the efficiency of those
operations given a specific implementation.

29
Efficiency of Algorithms
By comparing the efficiency of algorithms, we have
one basis of comparison that can help us determine
the best technique to use in a particular situation.
Travel
- by foot
- by car
- by train
- by airplane

30
Efficiency of Algorithms
Question: How can we characterize the
performance of an algorithm ...
Without regard to a specific computer?
Without regard to a specific language?
Over a wide range of inputs?
Desire: Function that describes execution time
in terms of input size
Other measures might be memory needed, etc.

31
Analysis of Algorithms
The measure of the amount of work an
algorithm performs (time)
or
the space requirements of an implementation
(space)
Complexity
Order of magnitude
is a function of the number of data items.

32
Running Time
Most algorithms transform best case

input objects into output average case


worst case
objects. 120

The running time of an 100


algorithm typically grows

Running Time
80
with the input size.
60
Average case time is often
difficult to determine. 40

We focus on the worst case 20

running time. 0
1000 2000 3000 4000
 Easier to analyze Input Size
 Crucial to applications such as
games, finance and robotics
33
The “Order” of Performance:
(Big) O
Basic idea:
1. Ignore constant factor: computer and language
implementation details affect that: go for
fundamental rate of increase with problem size.
2. Consider fastest growing term: Eventually, for
large problems, it will dominate.
Value: Compares fundamental performance
difference of algorithms
Caveat: For smaller problems, big-O worse
performer may actually do better

34
Big-O notation
Big-O notation provides a machine independent

meanssort,
For the selection for determining
the number the efficiency is
of comparisons
of an =Algorithm.
T(n) n2/2 - n/2.
2
n n
T(n)  
2 2

Entire expression is called the "Big-O" measure for the


algorithm.
n = 100: T(100) = 1002/2 -100/2 = 10000/2 - 100/2 = 5,000 - 50 =
4,950

35
Big-O Notation
Algorithm A requires time proportional to a function
F(N) given a reasonable implementation and
computer.
big-o notation is then written as O(n) where n is
proportional to the number of data items
You can ignore constants
O(5n2) is O(n2)
You can ignore low-order terms
O(n3 +n2 + n) is O(n3)

36
T(n) = O(f(n))
T(n) = time for algorithm on input size n
f(n) = a simpler function that grows at
about the same rate

Example: T(n) = 3n2+5n-17 = O(n2)


 f(n) has faster growing term
 no extra leading constant in f(n)

37
Growth Rates
1E+30
Growth rates of 1E+28 Cubic
functions: 1E+26
1E+24 Quadratic
 Linear  n 1E+22
Linear
1E+20
 Quadratic  n2 1E+18
Cubic  n3
T (n )
 1E+16
1E+14
1E+12
In a log-log chart, 1E+10
1E+8
the slope of the line 1E+6
corresponds to the 1E+4
1E+2
growth rate of the 1E+0
function 1E+0 1E+2 1E+4 1E+6 1E+8 1E+10
n

38
Constant Factors
1E+26
The growth rate is 1E+24 Quadratic
Quadratic
not affected by 1E+22
1E+20 Linear
 constant factors or 1E+18 Linear
 lower-order terms 1E+16
1E+14
Examples T (n ) 1E+12
1E+10
 102n  105 is a linear 1E+8
function 1E+6
 105n2  108n is a 1E+4
quadratic function 1E+2
1E+0
1E+0 1E+2 1E+4 1E+6 1E+8 1E+10
n

39
Growth Rates
Common Growth Rates
Big-O Name
O(1) Constant
O(log n) Logarithmic
O(n) Linear
O(n log n) Log-Linear
O(n2) Quadric
O(n3) Cubic
O(2n) Exponential
O(n!) Factorial
40
Growth Rates
Constant O(1) print first item
Linear O(n) print list of items
Polynomial O(n2) print table of items
Logarithmic O(log n) binary search
Exponential O(2n) listing all the subsets of
a set
Factorial O(n!) traveling salesperson
problem
41
Efficiency of Algorithms
(continued)

42
Chessboard Puzzle
Payment scheme #1: $1 on first square, $2 on
second, $3 on third, ..., $64 on 64th.

Payment scheme #2: 1¢ on first square, 2¢ on


second, 4¢ on third, 8¢ on fourth, etc.

Which is best?

43
Chessboard Puzzle Analyzed
Payment scheme #1: Total = $1+$2+$3+...+$64
= $6465/2 = $1755

Payment scheme #2: 1¢+2¢+4¢+...+263¢ = 264-1¢


=
$184.467440737 trillion

Many cryptographic schemes require O(2n) work to


break a key of length n bits. A key of length n=40 is
perhaps breakable, but one with n=100 is not.

44
Exponential Algorithms

n log2n n log2n n2 n3 2n
2 1 2 4 8 4
4 2 8 16 64 16
8 3 24 64 512 256
16 4 64 256 4096 65536
32 5 160 1024 32768 4294967296
128 7 896 16384 2097152 3.4 x 1038
1024 10 10240 1048576 1073741824 1.8 x 10308
65536 16 1048576 4294967296 2.8 x 1014 Forget it!

45

You might also like