Re: A critique of test-first...

From: CTips (ctips_at_bestweb.net)
Date: 11/22/04

  • Next message: CTips: "Re: A critique of test-first..."
    Date: Mon, 22 Nov 2004 08:42:57 -0500
    
    

    Jeff Grigg wrote:

    > Not long ago (relatively speaking ;-) I was given a short coding
    > assignment to complete for an interview. (I and others thought it was
    > silly to give a coding test to people of our level; but that's another
    > issue. ;-) The task was to write a small utility to display random
    > "Magic Eight Ball" answers, selected from a user-configurable set,
    > with user-defined probabilities for each. I wrote mine using Test
    > Driven Development techniques. The client said that this was the best
    > implementation they had ever seen. While they found serious design
    > limitations and bugs in all other entries, the only criticism they
    > could level against my implementation was that I had (quite
    > intentionally) used a simple interpretation in a place where the
    > requirements were vague, instead of putting in something complicated.
    > Test Driven Development gives me the confidence to know that if the
    > customer wants me to add something complicated, I can easily do so --
    > with very high confidence that I won't break anything else. And if I
    > had guessed wrong in putting in features that were not asked for, that
    > could have been bad too.
    >
    > See "JeffGrigg-Magic8Ball.zip" in
    > http://groups.yahoo.com/group/extremeprogramming/files/

    You need to be a member to get in to see those files. Any chance you
    could put the somewhere accessible?

    Anyway, let me take a whack at this problem. You're going to have to
    - read in the user file and build the table
    - select a random entry
    - print it
    The interface isn't spec'd so I'll assume that every time the program is
    run it randomly selects one message and dumps it.

    The input format isn't spec'd so I'll assume that it looks like
    <prob as a real number>
    message
    can be multi-line

    # this is a comment - note the empty line that denotes end of message
    # multiple empty lines are also legal
    # comments can occur only between messages, and have a # in col 0

    Ok, to print out the random-entry, we'll put the messages together as a
    list. Each message will have the cummulative probability. Hmmm..ok, so
    we'll store them as integers by premultiplying the probabilities by
            prob*RAND_MAX/sum_of_probs
    so the structure looks like:
            struct message {
              struct message * msg_next;
              double msg_prob;
              unsigned msg_cumm;
              char * msg_str;
            };
    To find a random message get a number from rand() and find the entry
    whose cummulative probability is >= the number, and whose previous entry
    is < number.

    [We'll have to print an error if prob*RAND_MAX/sum_of_probs returns 0]
    [For efficiency we can build an index into this table, probably by using
    an N entry array to point to the entry containing i*RAND_MAX/N]

    Since we're using random numbers, for debug, we'll have a flag to set
    the initial seed. Since this is stand-alone, no rand_r() needed.

    During parsing, we'll have to worry about unbounded user input, since
    we're allowing multi-line messages. Use a sparse/dense array of chars.
    [That's what I call a structure where its an array of pointers to arrays
    that gets filled in on demand.
            #define SCAN_L1_SIZE 256
            #define SCAN_L2_SIZE 4096
            char * scan[SCAN_L1_SIZE];
            
            void
            check_scan(
                    char * scan[],
                    unsigned n
                    )
            {
              unsigned i = n/SCAN_L2_SIZE;
              assert( n < SCAN_L1_SIZE*SCAN_L2_SIZE );
              if( scan[i] == 0 ) {
                 scan[i] = (char *)malloc(SCAN_L2_SIZE);
                assert( scan[i] ); /* substitute with error msg */
              }
            }
            
            #define scan_at(_scan, _at) \
                    (_scan[(_at)/SCAN_L2_SIZE][(_at)%SCAN_L2_SIZE])

    ]

    To verify that that something is a float, I'll use strtod(scan, &tail),
    and then check to see that the tail != scan and contains only isspace()
    characters.

    The scan routine for a record will be:
       do {
         get_line();
       } while( is_empty_line() || is_comment_line() )
       if( end_of_file() ) {
         return; /* no record */
       }
       if( get_float() == error ) {
         /* error & exit? */
       }
       do {
          get_line()
          add_to_temporary_sparse_dense_array()
        } while( !is_empty_line() ); /* end-of-file => empty line */
        if( is_empty_temp() ){
          /* error & exit */
        }
        build_record()

    I don't think there is anything more left in the design. I'd probably
    have finished coding and testing it in less time than it took to key in
    this message and debug the English :)


  • Next message: CTips: "Re: A critique of test-first..."

    Relevant Pages

    • Re: A critique of test-first...
      ... > silly to give a coding test to people of our level; ... Each message will have the cummulative probability. ... To find a random message get a number from randand find the entry ... Use a sparse/dense array of chars. ...
      (comp.programming)
    • Re: This question seems simpler than it actually is...
      ... find a lot of logic designers forget what HDL stands for... ... For the exercise I went ahead and did this with a 6 element array. ... type invect is array of entry; ... case mystate is ...
      (comp.lang.vhdl)
    • Re: Removing entry from @rray
      ... For some time I have been using two different method for removing an entry ... and places each line into the array. ... Redefining the @array element inside to loop ...
      (comp.lang.perl.misc)
    • Re: Framework 2.0 array redim unsatisfactory performance
      ... Not a surprise, most likely it is implemented as single-linked ... Implements the System.Collections.Generic.IListinterface using an array ... How are you determining "at least 5 additional bytes for each entry"? ... | The reason why I test Array is because I need a dynamic data structure ...
      (microsoft.public.dotnet.languages.vb)