FREE Subscription to Dr. Dobb’s Digest: Same Great Content, New Digital Edition
Site Archive (Complete)
Dobbs M-Dev
Email
Print
Reprint

add to:
Del.icio.us
Digg
Google
Furl
Slashdot
Y! MyWeb
Blink
July 01, 2002
Opening Disaster

I was delighted to be accepted as Mr. C's apprentice. But despite high hopes, my first attempt at coding for the master developer quickly hacked my hubris down to size. Would I make it?

Robert Martin

It was my first day on the job as an apprentice to Mr. C. I was lucky to get this apprenticeship, as Mr. C is a recognized master of software development, and the competition for this position was fierce. Mr. C's apprentices often become journeymen in high demand. It means something to have worked with Mr. C.
July 2002: Opening Disaster

Dear Diary: Today was a disaster. I wanted so much to impress the journeymen here—but all I did was make a mess.

It was my first day on the job as an apprentice to Mr. C. I was lucky to get this apprenticeship, as Mr. C is a recognized master of software development, and the competition for this position was fierce. Mr. C's apprentices often become journeymen in high demand. It means something to have worked with Mr. C.

I thought I was going to meet him today, but instead, a journeyman named Jerry took me aside. He told me that Mr. C always puts his apprentices through an orientation during their first few days, as an introduction to the practices that Mr. C insists we use, and to the level of quality he expects from our code.

This excited me greatly—an opportunity to show them how good a programmer I am! I told Jerry I couldn't wait to start, and he responded by asking me to write a simple program using the Sieve of Eratosthenes to calculate prime numbers. He told me to have the program, including all unit tests, ready for review just after lunch.

This was fantastic! I had almost four hours to whip up a simple program like the Sieve. I was determined to do a really impressive job, well commented and neatly formatted. I wrote the following comment at the beginning of my code:

This class generates prime numbers up to a user-specified maximum. The algorithm used is the Sieve of Eratosthenes. Eratosthenes of Cyrene, b. c. 276 BC, Cyrene, Libya; d. c. 194 BC, Alexandria. He was the first man to calculate the circumference of the Earth, and was also known for working on calendars with leap years and running the library at Alexandria. The algorithm is quite simple: Given an array of integers starting at 2, cross out all multiples of 2. Find the next uncrossed integer, and cross out all of its multiples. Repeat until you have passed the square root of the maximum value. @authorAlphonse, @version 13 Feb 2002 atp.

Then, after an hour or so, I had the following code for GeneratePrimes.java written:

import java.util.*;
   
 public class GeneratePrimes {  
   /**  
   * @param maxValue is the generation limit.
   */
   public static int[] generatePrimes(int maxValue) {   
     if (maxValue >= 2) { // the only valid case 
       // declarations
       int s = maxValue + 1; // size of array 
       boolean[] f = new boolean[s];   
       int i; 
       // initialize array to true.   
       for (i = 0; i < s; i++)    
         f[i] = true; 
      
       // get rid of known non-primes.   
       f[0] = f[1] = false; 
        
       // sieve   
       int j;   
       for (i = 2; i < Math.sqrt(s) + 1; i++) {    
         if (f[i]) { // if i is uncrossed, cross its multiples. 
           for (j = 2 * i; j < s; j += i)    
             f[j] = false; // multiple is not prime  
       } 
     }
       
     // how many primes are there?   
     int count = 0;   
     for (i = 0; i < s; i++) {   
       if (f[i])   
         count++; // bump count.   
     }  
     int[] primes = new int[count];     
     // move the primes into the result.   
     for (i = 0, j = 0; i < s; i++) {    
       if (f[i]) // if prime     
         primes[j++] = i;   
     }     
     return primes; // return the primes.  
   } else // maxValue < 2  
     return new int[0];  // return null array if bad input. 
   } 
 }
Then I wrote a unit test for GeneratePrimes, using the JUnit (www.junit.org) framework, as Jerry had instructed. It takes a statistical approach, checking to see if the generator can generate primes up to 0, 2, 3 and 100. In the first case, there should be no primes. In the second, there should be one prime, and it should be 2. In the third, there should be two primes: 2 and 3. In the last case, there should be 25 primes, the last of which is 97. If all these tests pass, I could assume that the generator was working. I doubt that this is foolproof, but I couldn't think of a reasonable scenario in which these tests would pass, yet the function would fail.

import junit.framework.*;  
 import java.util.*;
    
 public class TestGeneratePrimes extends TestCase {  
   public static void main(String args[]) {   
     Junit.swingui.TestRunner.main(  
       new String[] {"TestGeneratePrimes"});  
   } 
   public TestGeneratePrimes(String name) { 
     super(name); 
   } 
    
   public void testPrimes() { 
     int[] nullArray = GeneratePrimes.generatePrimes(0);  
     assertEquals(nullArray.length, 0); 
   
     int[] minArray = GeneratePrimes.generatePrimes(2); 
     assertEquals(minArray.length, 1); 
     assertEquals(minArray[0], 2);
   
     int[] threeArray = GeneratePrimes.generatePrimes(3); 
     assertEquals(threeArray.length, 2); 
     assertEquals(threeArray[0], 2); 
     assertEquals(threeArray[1], 3);   

     int[] centArray = GeneratePrimes.generatePrimes(100); 
     assertEquals(centArray.length, 25); 
     assertEquals(centArray[24], 97); 
   } 
 }

I got all this to work in about an hour. Jerry didn't want to see me until after lunch, so I spent the rest of my time reading the Design Patterns book that he gave me.

Making the Grade?
After lunch, I stopped by Jerry's office and told him I was finished. He looked up at me with a funny grin on his face and said: "Good. Let's check it out."

He took me out into the lab next to his office, sat me down in front of a workstation and sat down next to me. Then he asked me to bring up my program on this machine. So I navigated to my laptop on the network and brought up the necessary source files.

Jerry looked at the two source files for about five minutes. Then he shook his head and said: "You can't show something like this to Mr. C! If I let him see this, he'd probably fire both of us. He's not a very patient man."

I was startled, but managed keep my cool enough to ask: "What's wrong with it?" Jerry sighed. "Let's walk through this together," he said. "I'll show you, point by point, how Mr. C wants things done."

"It seems pretty clear," he continued, "that the main function wants to be three separate functions. The first initializes all the variables and sets up the sieve. The second actually executes the sieve, and the third loads the sieved results into an integer array."

I could see what he meant—there were three concepts buried in that function. Still, I didn't see what he wanted me to do about it.

He looked at me for awhile, clearly expecting me to do something. But finally, in the face of my stricken silence, he heaved a sigh, shook his head and …

To be continued next month.

 

RELATED ARTICLES
No Related Articles
TOP 5 ARTICLES
No Top Articles.



MICROSITES
FEATURED TOPIC

ADDITIONAL TOPICS

INFO-LINK