SDSU CS 535: Object-Oriented Programming & Design
Fall Semester, 1997
Doc 14, Comments on Assignment 1, part 1

To Lecture Notes Index
San Diego State University -- This page last updated 06-Oct-97

Contents of Doc 14, Comments on Assignment 1, part 1

  1. References
  2. Meyer's Criteria for Evaluating for Modularity
  3. Indentation, White space
  4. Names
  5. Comments
    1. Kinds of Comments
    2. Commenting Efficiently
    3. Commenting Techniques
    4. Commenting Data Declarations
    5. Commenting Routines
  6. Problem 1 & 2
    1. Static Version
    2. The Non-static Static Version
    3. Mixing IO and the Abstraction
    4. The One per Program Version
    5. The No Abstraction Version
    6. Flag Trouble Ahead
    7. Positional Data Problem

References


Various student papers

Code Complete, Steve McConnell, Microsoft Press, 1993, chapters 9 and 19



Doc 14, Comments on Assignment 1, part 1 Slide # 1

Meyer's Criteria for Evaluating for Modularity



Doc 14, Comments on Assignment 1, part 1 Slide # 2

Indentation, White space

public class Assgn1_Part1
{
   public static void main(String args[])
   {
            Console.println();
// Initialize strings
      DataString A=new DataString('A');      // This will prompt 
===>the user for a string.
      DataString B=new DataString('B');      // This will prompt 
===>the user for a string.
      DataString C=new DataString('C');      // This will prompt 
===>the user for a string.
      String D="";
      int i=0;
      do
      {
         {
            String a;
            String b;
            int j=0;
// Check each character of A
            do
            {
               a = A.Data.substring(i+j,i+j+1);
               b = B.Data.substring(j,j+1);
               j++;
            }
// If a letter matches, see if the whole string B is contained 
            while (a.toLowerCase().equals(b.toLowerCase())
               &&(j<B.Data.length()))
            if (a.toLowerCase().equals(b.toLowerCase())
               &&(j<B.Data.length()))
            {
// Place C into D
               D=D+C.Data;
               i+=j;
            }
            else
            {
// Place the letter from A into D
               D=D+A.Data.substring(i,i+1);
               i++;
            }
         }
      }
// Do until the end of A is too short to contain B
      while (i<=(A.Data.length()-B.Data.length()));

Doc 14, Comments on Assignment 1, part 1 Slide # 3
Indentation, White space

Use white space to make program readable

Use indentation to show the program structure

while (a.toLowerCase().equals(b.toLowerCase())
   &&(j<B.Data.length()))
if (a.toLowerCase().equals(b.toLowerCase())
   &&(j<B.Data.length()))
verses
while   (    ( a.toLowerCase().equals( b.toLowerCase() ) ) && 
         ( j<B.Data.length() ) 
      )
      if   (   ( a.toLowerCase().equals( b.toLowerCase() ) ) &&
            ( j<B.Data.length() )
         )
      {
         // Code deleted
      }

verses

while   (    ( a.toLowerCase().equals( b.toLowerCase() ) ) && 
         ( j<B.Data.length() ) 
      )
      {
         // Code deleted
      }



Doc 14, Comments on Assignment 1, part 1 Slide # 4

Names

Example 1
String s1;
String s2;
String s3;
int index1;
int index2;

verses
String  escapeChar;
String  charsToEscape;
String  unescapedString;

Example 2

Node pre;
public float compute() { stuff }
int len;
float avrg;
float avrge;
String esc_char;
String string;
Node ptr;


verses
Node previous;
public float average() { stuff }
int length;
float average;
String escapeChar;


Doc 14, Comments on Assignment 1, part 1 Slide # 5
Example 3

public  String  escape( String text)  {

   StringBuffer tmp  =  new StringBuffer();

verses
public  String  escape( String unescapedText)  {

   StringBuffer escapedText  =  new StringBuffer();



Only Possible Use of Temp
int temp;
temp = a;
a = b;
b = temp;
//temp not used after this


A Better Way?
int swapSpace;
swapSpace = a;
a = b;
b = swapSpace;

Doc 14, Comments on Assignment 1, part 1 Slide # 6
Example 4
boolean condition = true;

while ( condition )
   {
   //blah
   }
verses
while ( ! endOfFile )
   {
   //blah
   }
Example 5

How long will these be meaningful?
class p1p1 { //blah }
class p1p2 { //blah }
class project1problem2 { //blah }


Doc 14, Comments on Assignment 1, part 1 Slide # 7
Names

"Finding good names is the hardest part of OO Programming"

"Names should fully and accurately describe the entity the variable represents"

What role does the variable play in the program?
Data StructureRole, function
InputRecEmployeeData
BitFlagPrinterReady
Queuebuffer

Some Examples of Names, Good and Bad

Doc 14, Comments on Assignment 1, part 1 Slide # 8
TrainVelocityVelt, V, X, Train
CurrentDateCD, Current, C, X, Date
LinesPerPageLPP, Lines, L, X

Comments

//Declare fields
String s1;   //escape character
String s2;   //special characters
String s3;   //input string

//Prompt user for escape character
s1 = Console.readLine( "Type an escape character" );

//Prompt user for special characters
s2 = Console.readLine( "Type an escape character" );


s2 = s1 + s2                  // add s1 to s2


class FooBar
   {
   //Constructor
   public FooBar();



Doc 14, Comments on Assignment 1, part 1 Slide # 9
Comments

"Comments are easier to write poorly than well, and comments can be more damaging than helpful"
What does this do?
for i := 1 to Num do
 MeetsCriteria[ i ] := True;
for  i := 1 to Num / 2  do begin
 j := i + i;
 while ( j <= Num ) do begin
  MeetsCriteria[ j ] := False;
  j := j + i;
 end;
for i := 1 to Mun do
 if MeetsCriteria[ i ] then
  writeln( i, ' meets criteria ' );



Doc 14, Comments on Assignment 1, part 1 Slide # 10
How many comments does this need?



for PrimeCandidate:= 1 to Num do
   IsPrime[ PrimeCandidate] := True;

for  Factor:= 1 to Num / 2  do begin
   FactorableNumber := Factor + Factor ;
   while ( FactorableNumber <= Num ) do begin
      IsPrime[ FactorableNumber ] := False;
      FactorableNumber := FactorableNumber + Factor ;
   end;
end;

for PrimeCandidate:= 1 to Num do
   if IsPrime[ PrimeCandidate] then
      writeln( PrimeCandidate, ' is Prime ' );



Good Programming Style is the Foundation of Well Commented Program
Doc 14, Comments on Assignment 1, part 1 Slide # 11

Kinds of Comments

X := X + 1    /* add one to X



/* if allocation flag is zero */

if ( AllocFlag == 0 ) ...


Used to explain complicated or tricky code
*p++->*c = a

/* first we need to increase p by one, then ..
Make code simpler before commenting
(*(p++))->*c = a



ObjectPointerPointer++;
ObjectPointer = *ObjectPointerPointer;
ObjectPointer ->*DataMemberPointer = a;


Doc 14, Comments on Assignment 1, part 1 Slide # 12
/*  **** Need to add error checking here  **** */




Distills a few lines of code into one or two sentences
Explains the purpose of a section of code
/*get current employee information */   intent


/* update EmpRec structure */     what


Doc 14, Comments on Assignment 1, part 1 Slide # 13

Commenting Efficiently

/***********************************
 * module: Print                   *
 *                                 *
 * author: Roger Whitney           *
 * date:   Sept. 10, 1995          *
 *                                 *
 * blah blah blah                  *
 *                                 *
 ***********************************/



/***********************************
  module: Print          
                         
  author: Roger Whitney  
  date:   Sept. 10, 1995 
                         
  blah blah blah         
                         
 ***********************************/




Doc 14, Comments on Assignment 1, part 1 Slide # 14

Commenting Techniques

Commenting Individual Lines

Avoid self-indulgent comments
MOV AX,  723h        ;    R. I. P. L. V. B.



Endline comments have problems

MemToInit := MemoryAvailable(); { get memory available }

Not much room for comment
Must work to format the comment



Use endline comments on
Data declarations
Maintenance notes
Mark ends of blocks


Doc 14, Comments on Assignment 1, part 1 Slide # 15
Commenting Paragraphs of Code

Write comments at the level of the code's intent

Comment the why rather than the how

Make every comment count

Document surprises

Avoid abbreviations
How verses Why
How
/* if allocation flag is zero */

if ( AllocFlag == 0 ) ...

Why
/* if allocating a new member */

if ( AllocFlag == 0 ) ...

Even Better
/* if allocating a new member */

if ( AllocFlag == NEW_MEMBER ) ...

Doc 14, Comments on Assignment 1, part 1 Slide # 16
Summary comment on How
{ check each character in "InputStr" until a 
  dollar sign is found or all characters have 
  been checked }

Done   := false;
MaxPos := Length( InputStr );
i      := 1;
while ( (not Done) and (i <= MaxLen) ) begin
   if ( InputStr[ i ] = '$' ) then
      Done := True
   else
      i := i + 1
end;



Summary comment on Intent
{ find the command-word terminator }

Done   := false;
MaxPos := Length( InputStr );
i      := 1;

while ( (not Done) and (i <= MaxPos ) ) begin
   if ( InputStr[ i ] = '$' ) then
      Done := True
   else
      i := i + 1
end;


Doc 14, Comments on Assignment 1, part 1 Slide # 17
Summary comment on Intent with Better Style
{ find the command-word terminator }

FoundTheEnd      := false;
MaxCommandLength := Length( InputStr );
Index            := 1;

while ((not FoundTheEnd) and 
       (Index <= MaxCommandLength)) begin

   if ( InputStr[ Index ] = '$' ) then
      FoundTheEnd := True;
   else
      Index := Index + 1;
end;

Doc 14, Comments on Assignment 1, part 1 Slide # 18

Commenting Data Declarations


Comment the units of numeric data

Comment the range of allowable numeric values

Comment coded meanings
var
   CursorX:      1..MaxCols;   { horizontal screen position of cursor }
   CursorY:      1..MaxRows;{ vertical position of cursor on screen }

   AntennaLength:   Real; { length of antenna in meters: >= 2 }
   SignalStrength:   Integer;
                              { strength of signal in kilowatts: >= 1 }

   CharCode:      0..255;   { ASCII character code }
   CharAttib:      Integer;   { 0=Plain; 1=Italic; 2=Bold  }
   CharSize:         4..127;   { size of character in points }

Comment limitations on input data

Document flags to the bit level


Doc 14, Comments on Assignment 1, part 1 Slide # 19

Commenting Routines


Avoid Kitchen-Sink Routine Prologs

Keep comments close to the code they describe

Describe each routine in one or two sentences at the top of the routine

Document input and output variables where they are declared

Differentiate between input and output data

Document interface assumptions

Keep track of the routine's change history

Comment on the routine's limitation

Document the routine's global effects

Document the source of algorithms that are used
procedure InsertionSort 
   {
   Var   Data:      SortArray;    { sort array elements }
      FirstElement:   Integer        {index of first element to sort}
      LastElement:   Integer        {index of last element to sort}
   }

Doc 14, Comments on Assignment 1, part 1 Slide # 20

Problem 1 & 2

A Solution
class CharEscaper
   {
   private char escape;
   private String charsToEscape;
   
   public CharEscaper( char escapeChar, String specialChars )
      {
      // The escapeChar must be escaped
      charsToEscape = specialChars + escapeChar;
      
      escape = escapeChar;
      }
      
   private boolean needsEscaping( char testChar)
      {
      final int NOT_FOUND = -1;
      
      if ( charsToEscape.indexOf( testChar ) == NOT_FOUND )
         return false;
      else
         return true;
      }
   

Doc 14, Comments on Assignment 1, part 1 Slide # 21
   public String escape( String unescapedText)
      {
      StringBuffer escapedText = 
                  new StringBuffer( unescapedText.length() * 2);

      for (int index = 0; index < unescapedText.length(); index++ )
         {
         char unescapedChar = unescapedText.charAt( index );
         
         if ( needsEscaping( unescapedChar ) )
            escapedText.append( escape);
            
         escapedText.append( unescapedChar );
         }
      return escapedText.toString();
      }

   public String unescape( String escapedText)
      {
      StringBuffer unescapedText = 
               new StringBuffer( escapedText.length());
      
      for (int index = 0; index < escapedText.length(); index++ )
         {
         char nextChar = escapedText.charAt( index );
         
         if ( nextChar == escape )
            {
            index++;
            nextChar = escapedText.charAt( index );
            }
            
         unescapedText.append( nextChar );
         }
      return unescapedText.toString();
      }
   }

Doc 14, Comments on Assignment 1, part 1 Slide # 22
Using CharEscaper
class Test
   {
   public  static  void  main( String  args[] ) 
      {
      CharEscaper test  = new CharEscaper( 'a', "cd");

      System.out.println( test.escape( "cadman" ));
      System.out.println( test.escape( "this is a test" ));
      
      String escaped = test.escape( "asadcad" );
      System.out.println( test.unescape( escaped ));
      
      CharEscaper normal  = new CharEscaper( '\\', "nt");
      System.out.println( normal.escape( "this is new" ));
      }
   }

Doc 14, Comments on Assignment 1, part 1 Slide # 23

Static Version

class CharEscaper
   {   
   public static String escape(  char escapeChar, 
                                 String specialChars, 
                                 String unescapedText
                              )
      {
      final String charsToEscape =  specialChars + escapeChar;
      
      StringBuffer escapedText = 
               new StringBuffer( unescapedText.length() * 2);
      
      for (int index = 0; index < unescapedText.length(); index++ )
         {
         char unescapedChar = unescapedText.charAt( index );
         
         if ( charsToEscape.indexOf( unescapedChar ) > -1 )
            escapedText.append( escapeChar);
            
         escapedText.append( unescapedChar );
         }
      return escapedText.toString();
      }
   }
Using the Static Version
class Test
   {
   public  static  void  main( String  args[] ) 
      {
      System.out.println( 
            CharEscaper.escape( 'a', "cd", "cadman" ));
      }
   }

Doc 14, Comments on Assignment 1, part 1 Slide # 24

The Non-static Static Version

class CharEscaper
   {   
   public String escape(  char escapeChar, 
                           String specialChars, 
                           String unescapedText)
      {
      //Same as last slide
      }
   }

Using the Non-static Static Version
class Test
   {
   public  static  void  main( String  args[] ) 
      {
      CharEscaper test = new CharEscaper();
      System.out.println(  test .escape( 'a', "cd", "cadman" ));
      }
   }


Doc 14, Comments on Assignment 1, part 1 Slide # 25

Mixing IO and the Abstraction

class CharEscaper
   {
   private char escape;
   private String specialChars ;
   
   public CharEscaper( )
      {
      specialChars =
            Console.readLine( "Type the special chars");
      
      escape = Console.readChar( "Type the escape char");
      }
   // etc
   }

The One per Program Version

class CharEscaper
   {
   private static char escape;
   private static String specialChars ;
   
   etc.

Doc 14, Comments on Assignment 1, part 1 Slide # 26

The No Abstraction Version

class problem1
   {   
   public static void main(  String[] arguments )
      {
      char escapeChar = Console.getTheUserInput();
      String specialChars = Console.getMoreUserInput();
      String unescapedText = Console.getStillMoreInput();

      final String charsToEscape =  specialChars + escapeChar;
      
      StringBuffer escapedText = 
               new StringBuffer( unescapedText.length() * 2);
      
      for (int index = 0; index < unescapedText.length(); index++ )
         {
         char unescapedChar = unescapedText.charAt( index );
         
         if ( charsToEscape.indexOf( unescapedChar ) > -1 )
            escapedText.append( escapeChar);
            
         escapedText.append( unescapedChar );
         }
      System.out.println( escapedText.toString() );
      }
   }

Doc 14, Comments on Assignment 1, part 1 Slide # 27

Flag Trouble Ahead

class CharEscaper
   {
   private String escape;
   private String charsToEscape;
   private String textToEscape

   public String getString( int stringType )
      {
      switch ( stringType )
         {
         case 1:
            return escape;
         case 2:
            return charsToEscape;
         case 3:
            return textToEscape;
         }
      }

This is control coupling, which is not good

Use individual get methods for each string


Doc 14, Comments on Assignment 1, part 1 Slide # 28

Positional Data Problem

class problem1
   {   
   public static void main(  String[] arguments )
      {
      String escapeChar = arguments[0];
      String specialChars = arguments[1];
      String unescapedText = arguments[2];


Use flags!


visitors since 06-Oct-97