## CS535 Object-Oriented Programming & Design Fall Semester, 1996 Doc 10, Comments on Assignment 1

[To Lecture Notes Index]
San Diego State University -- This page last updated Oct 1, 1996

### Contents of Doc 10, Comments on Assignment 1

`Doc 10, Comments on Assignment 1 Slide # 1`

## References

Various student papers

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

`Doc 10, Comments on Assignment 1 Slide # 2`

## Meyer's Criteria for Evaluating for Modularity

• Decomposability
• Composability
• Understandability
• Continuity
• Protection

`Doc 10, Comments on Assignment 1 Slide # 3`

## 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()));
// Place the remainder of A into D
D=D+A.Data.substring(i,A.Data.length());
Console.println(D+"\n");
}
}
```

`Doc 10, Comments on Assignment 1 Slide # 4`
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 10, Comments on Assignment 1 Slide # 5`

## Names

Example 1
```String A;
String B;
String C;
String D;

```
verses
```String  strOriginal;
String  strSearch;
String  strReplace;
String  strNew;

```
Example 2
```
private  void  growQueue()  {

temp  =  new char[ size ];

```
verses
```private  void  growQueue()  {

char[]  newQueueSpace = new char[ newQueueSize  ]

```

`Doc 10, Comments on Assignment 1 Slide # 6`
Example 3
```
class Buffer {
char[]  buff;
// I removed the rest of the class
}

in driverProgram()  {

Buffer buffr  =  new Buffer()

```
verses
```
class CharQueue  {

char[]  queueElements;
// blah blah blah
}

in driverProgram()  {

CharQueue  buffer  =  new CharQueue();

```

`Doc 10, Comments on Assignment 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 Structure Role, function InputRec EmployeeData BitFlag PrinterReady Queue buffer

Some Examples of Names, Good and Bad
 TrainVelocity Velt, V, X, Train CurrentDate CD, Current, C, X, Date LinesPerPage LPP, Lines, L, X

`Doc 10, Comments on Assignment 1 Slide # 8`

```private int INITIAL_SIZE = 32;      // initial size of buffer

TempB = B.toLowerCase();         // get lower case of string

buffer[head] = ch;               // insert the char

x = x * 2                        // multilpy x by 2

```
verses
```private int INITIAL_BUFFER_SIZE = 32;

TempB = B.toLowerCase();   // comparison is case insensitive
// compare uppercase strings

//  doubling queueSize results in O(1) cost per insertion
queueSize = queueSize * 2

```

`Doc 10, Comments on Assignment 1 Slide # 9`

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 10, Comments on Assignment 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 10, Comments on Assignment 1 Slide # 11`

• Repeat of the code
```X := X + 1    /* add one to X

/* if allocation flag is zero */

if ( AllocFlag == 0 ) ...
```

• Explanation of how code works
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;
```
• Marker in the code
```/*  **** Need to add error checking here  **** */

```

• Summary of the code
Distills a few lines of code into one or two sentences
• Description of the code's intent
Explains the purpose of a section of code
```{ get current employee information }   intent

{ update EmpRec structure }     what
```

`Doc 10, Comments on Assignment 1 Slide # 12`

### Commenting Efficiently

• Use styles that are easy to maintain
```/***********************************
* module: Print                   *
*                                 *
* author: Roger Whitney           *
* date:   Sept. 10, 1995          *
*                                 *
* blah blah blah                  *
*                                 *
***********************************/

/***********************************
module: Print

author: Roger Whitney
date:   Sept. 10, 1995

blah blah blah

***********************************/

```
• Comment as you go along

`Doc 10, Comments on Assignment 1 Slide # 13`

### Commenting Techniques

Commenting Individual Lines

```MOV AX,  723h        ;    R. I. P. L. V. B.
```

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

Not much room for comment
Must work to format the comment

Data declarations
Maintenance notes
Mark ends of blocks

`Doc 10, Comments on Assignment 1 Slide # 14`
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 10, Comments on Assignment 1 Slide # 15`
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;

```

`Doc 10, Comments on Assignment 1 Slide # 16`
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 10, Comments on Assignment 1 Slide # 17`
Summary comment on Intent with Better Style
```{ find the command-word terminator }

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

(Index <= MaxCommandLength)) begin

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

`Doc 10, Comments on Assignment 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 10, Comments on Assignment 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 10, Comments on Assignment 1 Slide # 20`

## Returning Flags

```public char removeChar()
{
if ( isQueueEmpty() == true )
return '\u0000';
else
return  queueElements[ queueFront-- ]
}

```
verses
```class CharQueue
{
//  Select a rare unicode for remove char from empty
//  queue flag
public static final char EMPTY = \u0000';

public char removeChar()
{
if ( isQueueEmpty() == true )
return EMPTY ;
else
return  queueElements[ queueFront-- ]
}
}

public void static main( String arg[] )
{
blah blah blah

char fromQueue = buffer.removeChar();
if ( fromQueue == CharQueue.EMPTY )
do something proper
else
the real code goes here
```

`Doc 10, Comments on Assignment 1 Slide # 21`
Issue Who checks for Empty Queue?

Options
Queue class only
User code only
Both user code and queue class
Queue Class only

Queue class can not know the proper response to removing a character from an empty queue!

This option does not work

Both User and Queue

See previous slide
`Doc 10, Comments on Assignment 1 Slide # 22`
User Code Only

User code
```public void static main( String arg[] )
{
blah blah blah

if ( buffer.isEmpty() == false )
fromQueue = buffer.removeChar();
else
error condition, handle it here
```

Queue code
```class CharQueue
{

public char removeChar()
{
return  queueElements[ queueFront-- ]
}
```

`Doc 10, Comments on Assignment 1 Slide # 23`
How to tell User to check
Documentation
```   /** User must insure that the queue is not empty before calling
*  removeChar
* @return first character in the queue
*/
public char removeChar()
{
return  queueElements[ queueFront-- ]
}
```
Assert
```   public char removeChar()
{
Assert.condition( isQueueEmpty() == false );

return  queueElements[ queueFront-- ]
}
```

C/C++ have an assert call
In Java we have to build our own

Exceptions will modify this
```final class Assert {
public static void condition( boolean  expression )
{
if ( expression == false )
warn user some how
}
}
```

`Doc 10, Comments on Assignment 1 Slide # 24`

## Fields as Global Variables

```class ThreeStrings {
static String A, B, C, D;

A = Console.readLine( "Enter string A: " );
B = Console.readLine( "Enter string B: " );
C = Console.readLine( "Enter string C: " );
}

static void ReplaceStrings()  {
// Code here to do the string replacement

D = stringReplaced;
}

static void OutputString() {
Console.println( "\nString D is: " + D );
}

public static void main( String args[] ) {
ReplaceStrings();
OutputString();
}
}
```

`Doc 10, Comments on Assignment 1 Slide # 25`
Remove the Globals
Now we can use the class elsewhere!
```class ThreeStrings {

static void ReadStrings( String A, String B, String C )  {
A = Console.readLine( "Enter string A: " );
B = Console.readLine( "Enter string B: " );
C = Console.readLine( "Enter string C: " );
}

public static String ReplaceStrings( String A,
String B,
String C
)  {
// Code here to do the string replacement

return stringReplaced;
}

public static void main( String args[] ) {
String A, B, C, D;

D = ReplaceStrings( A, B, C );
Console.println( "\nString D is: " + D );
}
}
```

`Doc 10, Comments on Assignment 1 Slide # 26`
More Fields as Global Variables
```class Queue {

private char[] elements;
private int queueFront;
private int queueRear;
private int queueCount;

private char[]  tempQueue;

private void growQueue()
{
tempQueue = new char[ elements.length * 2 ];

for ( int k = 0; k < elements.length; k++ )
tempQueue[ k ] = elements[ k ];

elements = tempQueue;
}
}

```
Just declare tempQueue locally, not as field in class
```   private void growQueue()
{
char[]  tempQueue;
tempQueue = new char[ elements.length * 2 ];

for ( int k = 0; k < elements.length; k++ )
tempQueue[ k ] = elements[ k ];

elements = tempQueue;
}
```

`Doc 10, Comments on Assignment 1 Slide # 27`
Even More Fields as Global Variables
```class WrongWay  {

private int argumentOne;      // used only in helper and
private int argumentTwo;   // FunctionThatNeedsHelper

public void  FunctionThatNeedsHelper()  {
// do some stuff
// need to call helper function that needs two parameters
// so save parameters in fields

argumentOne = blah;
argumentTwo = moreBlah;

// now call helper method

result = helper();
}

private int helper()  {
return argumentOne / argumentTwo + 10;
}
}

class BetterWay  {
public void  FunctionThatNeedsHelper()  {
result = helper( blah, moreBlah );
}

private int helper(int a, int b )  {
return a / b + 10;
}
}
```

`Doc 10, Comments on Assignment 1 Slide # 28`

## IO in Classes

Example 1
```public void enqueue( )
{

if ( isQueueFull() == true )
growQueue();

queueRear = ( queueRear + 1 ) % queueSize();
elementCount++;
}
```

Example 2
```public void enqueue( char  charToAdd )
{

if ( isQueueFull() == true )
growQueue();

queueRear = ( queueRear + 1 ) % queueSize();
elementCount++;
Console.println( "queueRear  is now: " + queueRear );
}
```

`Doc 10, Comments on Assignment 1 Slide # 29`
Example 3
```public void print()
{
Console.print( "Front " + queueFront );
Console.print( " Rear " + queueRear );
Console.println( " " + String.valueOf( queueElements ) );
}
```

`Doc 10, Comments on Assignment 1 Slide # 30`

## How do you implement a Queue?

```

public void enqueue( char  charToAdd )
{
char[] newQueue = new char[ queueSize() + 1];

for ( int i = 0; i < queueSize(); i++ )
newQueue[ i + 1 ] = queueElements[ i ];

queueElements = newQueue;

queueRear =  queueRear + 1;
elementCount++;
}
```

`Doc 10, Comments on Assignment 1 Slide # 31`

## Queue Class

```class CharQueue
{
/* Class invariant,
* queueRear is the location the next queue item should be placed
* If the queue is not empty, queueFront is the location of the first
* item in the queue
*/

private char[] queueElements;
private int queueFront;
private int queueRear;
private int elementCount;

public static final int DEFAULT_QUEUE_SIZE = 256;

public CharQueue( int Size )
{
queueElements = new char[ Size ];
queueFront = 0;
queueRear = 0;
elementCount = 0;
}

public CharQueue(  )
{
this( DEFAULT_QUEUE_SIZE );
}

```

`Doc 10, Comments on Assignment 1 Slide # 32`
//Queue Operations
```
public char dequeue( )
{
char itemRemoved = queueElements[ queueFront ];
queueFront = ( queueFront + 1 ) % queueCapacity();
elementCount--;
return itemRemoved;
}

public void enqueue( char itemToAdd )
{
if ( isFull() == true )
growQueue();

queueRear = ( queueRear + 1 ) % queueCapacity();
elementCount++;
}

public boolean  isFull()
{
if ( elementCount >= queueCapacity() )
return true;
else
return false;
}

public boolean  isEmpty()
{
if ( elementCount == 0 )
return true;
else
return false;
}
```

`Doc 10, Comments on Assignment 1 Slide # 33`
//Queue Operations
```   public String toString()
{
return "Front " + queueFront +
"Rear " + queueRear + " " +
String.valueOf( queueElements );
}

private void growQueue()
{
CharQueue newQueue;
newQueue = new CharQueue( queueCapacity() * 2 );

while ( isEmpty() == false )
{
newQueue.enqueue( dequeue() );
}

queueElements = newQueue.queueElements;
queueFront = newQueue.queueFront;
queueRear = newQueue.queueRear;
elementCount = newQueue.elementCount;
}

private int queueCapacity()
{
return queueElements.length;
}
}

```

`Doc 10, Comments on Assignment 1 Slide # 34`
Using the Queue Class
```class QueueTest
{
public static void main( String[] args )
{
String testData = "abcdefghijklmnopqrstuvwxyz";
int nextLetter = 0;
CharQueue buffer = new CharQueue( 4 );

buffer.enqueue( '1');
buffer.enqueue( '2');
buffer.enqueue( '3');
for ( int k = 0; k < 3; k++ )
{
buffer.enqueue( testData.charAt( nextLetter++ ) );
buffer.dequeue( );
System.out.println( buffer );
}

for ( int k = 0; k < 9; k++ )
{
buffer.enqueue( testData.charAt( nextLetter++ ) );
System.out.println( buffer );
}

for ( int k = 0; k < 8; k++ )
{
System.out.println( buffer.dequeue(  ) );
}

for ( int k = 0; k < 14; k++ )
{
buffer.enqueue( testData.charAt( nextLetter++ ) );
System.out.println( buffer );
}
}
}
```

`Doc 10, Comments on Assignment 1 Slide # 35`

### Efficient grow

```
/*  Assumes called only when queue is full. Thus
*   queueFront = queueRear
*   Use native method to copy arrays:
*      arraycopy(src, srcPosition,dest,destPosition, length)
*    Parameters:
*      src - the source data
*      srcpos - start position in the source data
*      dest - the destination
*      destpos - start position in the destination data
*      length - the number of array elements to be copied
*/

private void growQueue()
{
char[] newQueue = new char[ queueCapacity() * 2 ];

int elementsFromFrontToEnd = queueCapacity() - queueFront;

System.arraycopy( queueElements, queueFront,
newQueue, 0,
elementsFromFrontToEnd);

System.arraycopy( queueElements, 0,
newQueue, elementsFromFrontToEnd,
queueRear);

queueElements = newQueue;
queueFront = 0;
queueRear = elementCount;
}
```

`Doc 10, Comments on Assignment 1 Slide # 36`

## Problem 1 String Replacement

```class StringManipulation
{
public static final int NOT_FOUND = -1;

private String text;
private boolean ignoreCase = true;

public StringManipulation( String textToManipulate )
{
text( textToManipulate );
}

public ignoreCase( boolean yesOrNo )
{
ignoreCase = yesOrNo;
}

public String toString()
{
return text();
}

private void text( String newText )
{
text = newText;
}

private String text(  )
{
return text;
}

```

`Doc 10, Comments on Assignment 1 Slide # 37`
// More String
```   public int indexOf( String pattern, int fromIndex )
{

for (    int searchIndex = fromIndex;
searchIndex <= text().length() - pattern.length();
searchIndex ++
)
{
boolean match;
match = text().regionMatches( ignoreCase, searchIndex ,
pattern, 0, pattern.length() );
if ( match == true )
return index;
}
return NOT_FOUND;
}

public void replaceFirst(    String searchPattern,
String replacePattern
)
{
int searchIndex = indexOf( searchPattern, 0 );

if ( searchIndex != NOT_FOUND )
{
StringBuffer newText = new StringBuffer();
newText.append( text().substring( 0, searchIndex) );
newText.append( replacePattern );
newText.append( text().substring( searchIndex +
searchPattern.length() )
);

text( newText.toString() );
}
}
```

`Doc 10, Comments on Assignment 1 Slide # 38`
// Problem 1
```   public void replaceAll(    String searchPattern,
String replacePattern
)
{
StringBuffer newText = new StringBuffer();

int startIndex = 0;
int searchIndex = indexOf( searchPattern, startIndex );

while ( searchIndex != NOT_FOUND )
{
newText.append( text().substring( startIndex, searchIndex) );
newText.append( replacePattern );

startIndex = searchIndex + searchPattern.length();
searchIndex = indexOf( searchPattern, startIndex );
}

newText.append( text().substring( startIndex ) );
text( newText.toString() );
}

```

`Doc 10, Comments on Assignment 1 Slide # 39`
// Start of Problem 3
```
public String grepLikeFind(    String startPattern,
String endPattern,
int fromIndex
)
{
int startIndex = indexOf( startPattern, fromIndex );

if ( startIndex == NOT_FOUND )
return "";

int endPatternIndex;
endPatternIndex = indexOf( endPattern,
startIndex + startPattern.length()
);

if ( endPatternIndex == NOT_FOUND )
return "";

return text().substring( startIndex,
endPatternIndex + endPattern.length()
);
}
} // End class
```

`Doc 10, Comments on Assignment 1 Slide # 40`
```class StringManipulation
{
public static final int NOT_FOUND = -1;

private String text;
private boolean ignoreCase = true;
private Stack changeHistory = new Stack();

private void text( String newText )
{
changeHistory.push( text );
text = newText;
}

public void undo()
{
text = ( String ) changeHistory.pop();
}
```

// Rest of class the same