Lab 04 - Test Cases
Thanks for my Lab Tutor Zhang Puyu
Slides:
Testing
Some conventions
It is impossible to enumerate all test cases.
It is possible to divide the test cases into a few groups.
We can choose to test for all possible classes of inputs/outputs.
Test for the boundary cases according to the constraints given.
Test Case Design
Should cover all conditional (i.e. for all conditional branch, there exists at least one test case which can enter that branch)
Should contain at least one case for 0 iteration and at least one case for k iterations where k≥1.
Should contain boundary conditions.
Example
Design the test cases for the program below:
We won't enter the loop
while n != 0, that means n=0 and now our output is 0, which is correct.We enter the loop, which means n=0.
We don't enter the conditonal first. So, that means there is no 9 in
nWe enter the conditional, which means there is at leasat a 9 in
n9 in the last digit.
9 in the middle.
Have multiple 9.
Testing Tips:
Test each function seperately (print out the value to be returned and compare it with your expectation!
Decompose your program into shorter and simpler functions: simpler code is easier to test!
Exercise 2 Review
factor.c
Optimization methods:
n−1→2n since anything bigger than 2n for sure cannot divide n!
If i divides n, then surely in divides n as well. See Proof of 2.
The above implies that we can count factors in pairs.
Note that if i divides n and i<n, then in>n
So, the supremum (the least upper bound) is n.
We should then deal with the special case where n is a perfect square (a perfet square has an odd numbero factors while any other integer has an even number of factors)
Proof of 2.
If i divides n, then we can write n=qi, where q=0. Manipulate this equation, we know q=in. So, now our problem becomes does q divide n right? This answer is obvious yes right, since we already know that n=qi. Proof!
collatz.c
When to use for or while?
`for` is used under the circumstances where we iterate through consecutive numbers. `while` loops are used under the circumstances that we don't iterate through consecutive numbers, which means that we can define a more general condition to "loop through".
pattern.c
A Little Extension on prime.c
Question
How to find all primes less than or equal to n.
Naive Solution
We iterate every integer from n to 2 (even if we exclude all even numbers, there are still 2n steps. And checking if each integer is prime takes another n steps in the worst case, so in total there are about 2nn steps -- Slow!
Optimized Solution
Using an array, we can speed up the algorithm. The algorithm we are using is called Sieve of Eratosthenes.
Consider all integers from 2 to n
Take 2 (which happens to be the smallest prime), and cross out all multiples of 2 in the list.
Take the un-crossed integer (which is 3 in this case), and cross out all muptiples of 3.
Iterate through the list while repeating the above process. We claim that: each time we come across an un-crossed integer i, it will be a prime.
Why?
Let's use proof by contracdiction. If it is not a prime, the it must have factors smaller than it. However, during our "cross-out" procedure, all the multiple of the number smaller than it must be crossed out. So, that means this number has been crossed out. Contradiction! So, that means this number we encounter is prime.
Stop when we encounter the first integer that is bigger than n. We claim that from this integer onwards, all un-crossed integers are prime!
Why?
Use proof by contracdiction also. If this number (n) is not a prime. That means n has factors that are not itself and 1. And one of its factor must be smaller than or equal to its square root. However, we have crossed out all the numbers that are multiple of that square root since it's smaller the n. So, this means this number is already crossed out. Contradiction!
Number of operations in the worst case: upper-bounded by nlog(log(n)) (fewer than nn).
Last updated