Wednesday, March 6, 2013

AP Computer Science - A Digression on Matrices

AP Computer Science Digression into Matrices

AP Computer Science Digression into Matrices

Unfinished business

My last article on modulo was a little long winded but let's expand on what we have done on the Matrix1d class. I want to show you how to make methods that perform operations on matrices. Matrix mathmatics are certainly important and whole languages have been created to deal with it. Two languages were discussed in the last article but Matlab is yet another language that deals with mathematics and matrices. It was the language used at MIT recently to do video processing to determine if a person is breathing or not. They created matrix processing routines that amplified the movements of video so they could enhance small motions undetectable to the human eye. So matrix mathematics is certainly a major area of study in Computer Science.

But first there was an error I found in my 'displayMatrix' method when working on the code. It turns out that since we intialized the matrix to be the values of the 1 dimension element. I used just the index in the print statements, giving the apperance of displaying the correct memory locations since the values were the same. However, I should have used the index along with mat1d hence printing mat1d[i], to print the values of the matrix. I fixed it in my code and here is the correct code. I am providing all the mistakes I make to give you the ability to see the common errors even experienced programmers make. I will do so for a few more articles. This will help you find mistakes by reading the code, rather than letting the compiler do all the work. At any rate the new code for displayMatrix follows

void displayMatrix() {
    for (int i = 0; i < this.n * this.n; i++) {
        if (i % n == 0) {
            System.out.println();
        }
        System.out.print(this.mat1d[i] + " ");  // this statement was corrected
    }
    System.out.println();
}

Matrix multiply

Matrices can be multiplied. In our case we are only creating n x n matrices, so multiplication can mean a couple of things. A trivial multiply would be to multiply common elements together and report the new matrix as the individual multiplications. The other multiply is known as Matrix Multiplication (more on that later). First an example to clarify simple matrix multiplication:

1 2      1 3         1 6
3 4  x   2 4    =    6 16

That is pretty straight forward and extending this to the n x n case is trivial. However, what would be helpful would be some methods to access and store based on 2 dimensional indexes. So first lets extend the Matrix1d class to do just that. We already defined a getElement method previously so now we just need a storage method we will call setElement. The definition is as follows:

public int setElement(int r, int c, int value)
{
  int index = (r*this.n) + c
  this.mat1d[index] = value;
}

Syntax error in the above code do you see it?

There is also a bit of a design issue. setElement returns a value of int but why? I'm just setting the value so that should be void. The IDE flagged this when I pasted it so I will change it.

Now the object oriented-ness of this may be a little confusing. I will explain after we plow through making the code. All that is missing is our multiply method so let's code that.

public int simpleMultiply(Matrix1d m)
{
  // check that the current Matrix1d (this) is the same size as the parameter m
  if (this.n != m.n) {  
    // I'm starting to access the fields directly in multiple objects
    // probably time to write getter and setter methods and refactor the code
    // if I am in this code section the matrices are not the same size 
    // return 0 for false the multiplication did not take place
    return 0;
  }

  // If we make it to here the matrices can be multiplied together
  for (int i = 0; i < this.n; i++) {
    for (int j = 0; j < this.n; j++) {
      this.setElement(i,j,this.getElement(i,j)*m.getElement(i,j));
    } 
  }
  return 1;
}

Recode the main method to test this on the 2x2 example above. But wait our Matrix1d class definition does not let us initialize the matrix except by chosing consequtive integers. We could define 2 matrices then use 'setElement' to replace the ones we want. Let's try that first (we will revisit this to allow us to define an array of values to initialize the matrix.

public static void main(String args)
{
  Matrix1d mat1 = new Matrix1d(2);
  Matrix1d ans = new Matrix1d(2);

  // Let's replace the values we need if you look at the 2x2 matrices all that's
  // changed is the 2 and 3 are swapped from their original ordinal positions
  mat1.setElement(0, 0, 1);
  mat1.setElement(0, 1, 2);
  mat1.setElement(1, 0, 3);
  mat1.setElement(1, 1, 4);

  ans.setElement(0, 0, 1);
  ans.setElement(0, 1, 3);
  ans.setElement(1, 0, 2);
  ans.setElement(1, 1, 4);


  if (ans.simpleMultiply(mat1)) {
    ans.displayMatrix();
  }
  else {
    System.out.println("Size error");
  }
}

Now there are 2 not so obvious errors above. The first one is that simpleMutiply returns an int not a boolean (this is something that the C programming language lets you do but Java does not). So we will need to change the if statement to have '== 1' in it. The other is that the String args should be String[] args. Arguments in the main method come in as an array of Strings. So fix those 2 bugs and the output of our multiply routine should be:

1 6 
6 16 

Matrix Multiplication (the real thing)

So while the above is a form of multiplying matrices it is not full blown matrix multiplication. To multiply 2 matrices in it's standard meaning means to multiply the rows of one matrix with the columns of the other and sum the terms to form new elements of the matrix that will become the answer. So if A and B are the matrices I want to Matrix Multiply and I will use C as the new matrix obtained by the operation. Matrix multiplication is defined as follows:

Ci,j = Σ Ai,k * Bk,j (k = 0,…,n-1)

To program this you will need 3 nested loops. Two (2) nested loops for the i and j of each element of C and an inner loop inside of those to sum up all the k multiplications.

public Matrix1d matrixMultiply(Matrix1d b)
{
  // Object oriented I will use the A object to do the calculation give it B
  // and return a new matrix for the return value which of course is C
  // Create C
  Matrix1d c = new Matrix1d(this.n);

  for (int i =0 ; i < this.n; i++) {
    for (int j = 0; j < this.n; j++) {
      c.setElement(i,j, 0); //zero out the element to accumulate the sum
      for (int k = 0; k < this.n; k++) {
        c.setElement(i, j, c.getElement(i,j) + this.getElement(i,k) * b.getElement(k,j);
      }
    }
  }
  return c;
}

Mistake above. Fixed in final version again see if you can sight read and find the error.

Interestingly enough in our representation of a matrix as a linear array we only need modulo in order to display rows and columns given the internal index of the array. If I didn't need to display this in matrix form I could almost write an entire matrix package without modulo. However, in the routines to convert a row and column into an index modulo is implicit. If you notice we use the formula:

array index = divisor * quotient + remainder

What is the remainder? Of course the answer we get when doing a modulo operation.

A better way of setting up a matrix

The use of setElement calls is a little cumbersome. It would be nicer if a list of numbers could be input directly and the class would take care of placing them in the storage array directly. This is easy enough to accomplish by creating a new constructor that allows an int array to be the parameter.

Matrix1d(int size, int[] vals)
{
  // vals size would have to be a square of some n that needs to be 
  // determined. For now rather than handling an error just assume only
  // an appropriately sized array is given and that the size of the 
  // matrix is provided as a parameter

  this.n = size;
  this.mat1d = vals;

}

Add the following statements to the main method to test:

// Test the array initialization
int[] matarr = {2,4,6,8,10,12,14,16,18};
Matrix1d mat2 = new Matrix1d(3,matarr);
mat2.displayMatrix();

Identity Matrix

Just as 1 x n = n (multiplicative identity). So to in Matrix Multiplication there exists an Identity Matrix we can call 'I' that creates a matrix multiplicative identity: A x I = A. Pretty interesting, let's see if our newly created matrix class is up to the task. First what does the Identity Matrix look like? It's a matrix of nxn elements with 1's in the diagonal spaces from 0,0 .. n,n.

1 0 0     1 0 0 0 
0 1 0     0 1 0 0 
0 0 1     0 0 1 0
          0 0 0 1

The preceding are 3 x 3 and 4 x 4 identity matrices We can use our new constructor to create an identity matrix. Add the following lines to main to test the constructor

int[] identity3 = {1,0,0,0,1,0,0,0,1};

Matrix1d mat3 = new Matrix1d(3,identity3);
Matrix1d mat4 = mat2.matrixMultiply(mat3);
mat4.displayMatrix();

Output

1 6 
6 16 

7 10 
15 22 

2 4 6 
8 10 12 
14 16 18 

2 4 6 
8 10 12 
14 16 18 

Let's modify main to printout the identity matrix as well. The final version of the main method is:

    public static void main(String[] args) {
        Matrix1d mat1 = new Matrix1d(2);
        Matrix1d ans = new Matrix1d(2);

        // Let's replace the values we need if you look at the 2x2 matrices all that's
        // changed is the 2 and 3 are swapped from their original ordinal positions
        // and the other corner elements are 1 and 4 respectively
        mat1.setElement(0, 0, 1);
        mat1.setElement(0, 1, 2);
        mat1.setElement(1, 0, 3);
        mat1.setElement(1, 1, 4);

        ans.setElement(0, 0, 1);
        ans.setElement(0, 1, 3);
        ans.setElement(1, 0, 2);
        ans.setElement(1, 1, 4);

        if (ans.simpleMultiply(mat1) == 1) {
            ans.displayMatrix();
        } else {
            System.out.println("Size error");
        }

        Matrix1d mmult = mat1.matrixMultiply(mat1);
        mmult.displayMatrix();

        // Test the array initialization
        int[] matarr = {2,4,6,8,10,12,14,16,18};
        Matrix1d mat2 = new Matrix1d(3,matarr);
        mat2.displayMatrix();

        int[] identity3 = {1,0,0,0,1,0,0,0,1};

Matrix1d mat3 = new Matrix1d(3,identity3);
Matrix1d mat4 = mat2.matrixMultiply(mat3);
mat3.displayMatrix();
mat4.displayMatrix();

Output

1 6 
6 16 

7 10 
15 22 

2 4 6 
8 10 12 
14 16 18 

1 0 0 
0 1 0 
0 0 1

2 4 6 
8 10 12 
14 16 18 

Conclusion

That's all for matrices for now. This should give you some exposure of how we use computers to solve math problems. We basically try to model what we do in math and make the computer go through the tedious processing. Next we will revisit modulo in a more interesting way.

References

  1. Eulerian Video Magnification MIT CSAIL web address: http://people.csail.mit.edu/mrub/vidmag/

Final Version of Code

public class Matrix1d {

    int n = 10;
    int mat1d[] = null;

    public Matrix1d(int n) {
        this.n = n;
        this.mat1d = new int[this.n * this.n];
        // intialize the elements to count up from 0
        for (int i = 0; i < this.n * this.n; i++) {
            mat1d[i] = i;
        }
    }

    public Matrix1d(int size, int[] vals)
{
  // vals size would have to be a square of some n that needs to be 
  // determined. For now rather than handling an error just assume only
  // an appropriately sized array is given and that the size of the 
  // matrix is provided as a parameter

  this.n = size;
  this.mat1d = vals;

}

// put our code to get an element here
    int getElement(int row, int col) {
        return this.mat1d[row * this.n + col];
    }

    void display() {
        int r, c;

        for (int i = 0; i < this.n * this.n; i++) {
            r = i / this.n;   // integer divide gives us the row for the element

            // for the column it's the left over after the integer divide
            // col = i - (r * n) which sin r was calculated with int division is just
            // the remainder. Well since we want to look professional we know that's 
            // modulo. So to look like we know what's going on let's use modulo
            c = i % this.n;
            System.out.println("matrix[" + r + "][" + c + "] = " + this.mat1d[i]);
        }
    }

    void displayMatrix() {
        for (int i = 0; i < this.n * this.n; i++) {
            if (i % n == 0) {
                System.out.println();
            }
            System.out.print(this.mat1d[i] + " ");
        }
        System.out.println();
    }

    public void setElement(int r, int c, int value) {
        int index = (r * this.n) + c;
        this.mat1d[index] = value;
    }

    public int simpleMultiply(Matrix1d m) {
        // check that the current Matrix1d (this) is the same size as the parameter m
        if (this.n != m.n) {
            // I'm starting to access the fields directly in multiple objects
            // probably time to write getter and setter methods and refactor the code
            // if I am in this code section the matrices are not the same size 
            // return 0 for false the multiplication did not take place
            return 0;
        }

        // If we make it to here the matrices can be multiplied together
        for (int i = 0; i < this.n; i++) {
            for (int j = 0; j < this.n; j++) {
                this.setElement(i, j, this.getElement(i, j) * m.getElement(i, j));
            }
        }
        return 1;
    }

    public Matrix1d matrixMultiply(Matrix1d b)
{
  // Object oriented I will use the A object to do the calculation give it B
  // and return a new matrix for the return value which of course is C
  // Create C
  Matrix1d c = new Matrix1d(this.n);

  for (int i =0 ; i < this.n; i++) {
    for (int j = 0; j < this.n; j++) {
      c.setElement(i,j, 0); //zero out the element to accumulate the sum
      for (int k = 0; k < this.n; k++) {
        c.setElement(i, j, c.getElement(i,j) + this.getElement(i,k) * b.getElement(k,j));
      }
    }
  }
  return c;
}

    public static void main(String[] args) {
        Matrix1d mat1 = new Matrix1d(2);
        Matrix1d ans = new Matrix1d(2);

        // Let's replace the values we need if you look at the 2x2 matrices all that's
        // changed is the 2 and 3 are swapped from their original ordinal positions
        // and the other corner elements are 1 and 4 respectively
        mat1.setElement(0, 0, 1);
        mat1.setElement(0, 1, 2);
        mat1.setElement(1, 0, 3);
        mat1.setElement(1, 1, 4);

        ans.setElement(0, 0, 1);
        ans.setElement(0, 1, 3);
        ans.setElement(1, 0, 2);
        ans.setElement(1, 1, 4);

        if (ans.simpleMultiply(mat1) == 1) {
            ans.displayMatrix();
        } else {
            System.out.println("Size error");
        }

        Matrix1d mmult = mat1.matrixMultiply(mat1);
        mmult.displayMatrix();

        // Test the array initialization
        int[] matarr = {2,4,6,8,10,12,14,16,18};
        Matrix1d mat2 = new Matrix1d(3,matarr);
        mat2.displayMatrix();

        int[] identity3 = {1,0,0,0,1,0,0,0,1};

Matrix1d mat3 = new Matrix1d(3,identity3);
Matrix1d mat4 = mat2.matrixMultiply(mat3);
mat3.displayMatrix();
mat4.displayMatrix();
    }
}

Author: Nasty Old Dog

Saturday, March 2, 2013

Modulo

AP Computer Science Modulo it's Just Remainder

AP Computer Science Modulo it's Just Remainder

Think Mathematically

Computer Science is technically a branch of Mathematics and yet pure mathematical thinking may cause problems when you try to understand the temporal relationships (temporal fancy word for timing) of computer programing. For example if you try to understand the following (based on your understanding of algebra):

j = j + 1

The above statement makes no sense, algebraically. But in Computer Science this really means take the current value of j add 1 to it, store the answer back in j. In Programming names are not algebraic variables they are memory locations whose value depends on the timing of instructions. When the above example gets compiled the instructions to the computer get ordered in a certain way and the processor acts on each statement one at a time in the order they are found. It is confusing to the beginning Computer Scientist because they have years of mathematics where the variable was only going to be one value and it was their job to find out what it is.

Another human thought process getting in our way is the fact that we read English from left to right. For the human to understand what is happening they have to read in the whole sentence then work backwards:

  • Start on the expression on the right hand side
    • interpret what is happening here (j + 1)
  • Then figure out what will happen because of the equals sign

The late Ken Iverson realized this back in the early 1960's Dr. Iverson created a whole notation that would allow a mathematician to represent algorithms. The seminal treatise was captured in his book A Programming Language. IBM hired Dr. Iverson to implement this notation on a computer. He created a new programmming language called APL.

Dr. Iverson came up with a brilliant realization (among many) that our traditional way of resolving precedence (the order we do operations in mathematics) was in reality arbitrary and ambiguous. While most computer languages (like Java) strived to duplicate tradition, Dr. Iverson1 said there is no operator precedence we just read a statement from RIGHT to LEFT (yes the opposite of what you've been taught all these years) and do the operation when we first hit it. If the programmer needs to ensure certain operations happen first rewrite your equation or use parenthesis to organize which operations go first (so parentheses are the same in any language). The beauty of this realization in our simple example above, reading Right to Left gives us a sense of the temporal considerations when running the program.

1 is added to j and the result stored back in j

Reading right to left provides a better understanding of what happens and when. You begin to think more about how the computer sees things. Java uses a traditional precedence mechanism for mathematical formulas. Reading right to left will not be that helpful for complex statements.

The budding computer scientist needs to be ready to think mathematically in non-traditional ways. Indeed, Dr. Iverson even invented new mathematic symbols and had to create his own font to even print the new operations. He was striving for a new mathematical world where the opertator relationships would be defined in a standard way so you could map your mathematical talents and apply them to a computer in a useful way. This is much the same as Dirac notation for quantum mechanics or Laplace transforms for differential equations. Create a new mathematics that abstracts away tedious details and helps the mathematician to think and get their hands around a new environment.

When you are able to map your mathematics skills into solving the programming assignments, you will be surprised at your own intuition and creativity. You will be able to simplify a problem because you saw the mathematical tricks that reduced 100 lines of code down to 10.

Tricks of the Trade: Modulo

One computer math trick you need to be aware of is modulo. There are many reasons to use Modulo. Indexing into 2 dimensional arrays (matrix after its mathematical counterpart) as an example. It is usually used when we are trying to map large a set of numbers into a smaller set. Many indexing operations will take advantage of modulo (the Java operator %). Modulo is rooted in long division. You know what it is and what it does even if you don't recognize the name.

Modulo = Remainder

Remember doing long division all those years ago in Elementary School? You used an algorithm and your knowledge of the "times" tables and would come up with 2 answers. One was the quotient the other was the remainder. The amount of stuff left over since the division did not go in evenly.

Remainder was always a throw away item in school we reported it but didn't use it very much. But it turns out it's very useful in many aspects of programming. In fact for games you use it all the time with out knowing about it. Most random number generators use modulo by a prime number. In fact the very architecture of the CPU registers has modulo built in. If you were to add 10 to (232-1) you would overflow the register but the number left in the register would wrap around 0 and what would be left is 9.

The best thing about modulo is it's a built in mathematics operation. If we had to duplicate the functionality programatically it would make our code too complex. The reality is that complex code is error prone code and we may not take into account every eventuality. By using computer mathematics we have a much better likelihood the code will operate properly. Hopefully by using a mathmatics solution there will be much smaller set of lines of code to debug. It's much easier to find a mathematical error in one line than a logic error in multiple nested if statements

First Example Simulating Multidimensional Arrays

Let's pretend Java didn't provide the ability to declare multidimensional arrays. But they do give us single dimensional arrays. For simplicity sake lets just simulate square matrices (NxN).

Specifications

  1. Call the class Matrix1d
  2. Using only one array field and any number of individual support fields
  3. The actual elements shall be 'int's just to simplify
  4. Create a class that constructs a 2 dimensional array given the size N
  5. Use Method getElement(int row, int col)
  6. Create a display method display() that prints a list of elements and their indexes and prints the matrix in standard matrix format

Lets work on 4 first. There are N columns so the first N elements of the 1d array should represent the first row of the matrix. The second row would be the next N elements … the Nth row would be the last N elements. You should be able to figure out the equation to map a row and column into a single address in our 1d array:

row * N + col

The code for this is:

int getElement(int row, int col) 
{
  return this.mat1d[row * this.n + col];
}

Let's store N in field int n and using the mat1d name for the array let's code the class so far with a possible constructor:

class Matrix1d {
int n = 10;
int mat1d[] = null;

Matrix1d(int n)
{
  this.n = n;
  this.mat1d = new int [this.n * this.n];
  // intialize the elements to count up from 0
  for (int i = 0; i < this.n*this.n; i++) 
  { 
    mat1d[i] = i;
  }
}

// put our code to get an element here
int getElement(int row, int col) 
{
  return this.mat1d[row * this.n + col];
}

void display()
{
  int r,c;

  for (int i = 0; i < this.n*this.n; i++)
  {
    r = i/this.n;   // integer divide gives us the row for the element

    // for the column it's the left over after the integer divide
    // col = i - (r * n) which sin r was calculated with int division is just
    // the remainder. Well since we want to look professional we know that's 
    // modulo. So to look like we know what's going on let's use modulo
    c = i%n
    println("matrix["+r+"]["+c+"] = " + mat1d[i];
  }
}

Now the above code has a few syntax errors in it.

  • I'm missing public in front of my class definition
  • I forgot a semicolon in the 4th line from the bottom (c = i%n)
  • I'm missing the close parenthesis int the println statement and the 'System.out.' before the println

Now these are mistakes you make all the time that the IDE (eclipse, netbeans, etc) point out to you immediately. How did I get the code with those mistakes? Because I coded it in a separate editor I use to write these blog articles and then copied the code and pasted it into Netbeans. Rather than fix my article I thought I would point out to you that you can program outside of the IDE. It's actually helpful to your design. Code out large chunks of code, think about what you want to do, then as a separate step (once you have your logic in place) fix the syntax. It helps to keep you focused on your real problem instead of being side tracked by fixing semicolons or missing keywords.

There is also another problem above in my style of coding Java I am missing 'this.' on my fields. Instead I am addressing them directly by name. I find it helpful to reference object fields by using the 'this' keyword. It is a reminder that this code takes place inside an object. That object would have been constructed somewhere else in the code by calling 'new' on the constructor in the class definition for the object.

Ultimately in object oriented programming fields should be addressed directly as little as possible (even using the 'this' directive). Indeed, I would normally refrain from using them at all and instead implement 'getter' and 'setter' methods to change and access the fields. Now you may be thinking: "It seems kind of dumb for such a simple program" and I agree. For this simple program it's not necessary and only adds clutter to the code with out expressing any central logic. This again is why I like to prepend 'this' to the field. It's a reminder that if this simple little program actually becomes part of a library that another programmer would use, it needs to be buffed up with 'getter' and 'setter' methods and replace my direct references to object fields using the get and set method calls.

Now let's add a main method to test the class so far:

static void main(String[] args)
{ 
  // Create a 5 x 5 matrix
  Martix1d mymatrix = new Matrix1d(5);

  mymatrix.display();
}

Again I just coded this directly in my article editor now I will copy and paste into the IDE and see what mistakes pop up.

There are two mistakes in the main method code see if you can find it.

In the meantime once I fixed all the mistakes in the code above here is what we get as the output:

matrix[0][0] = 0
matrix[0][1] = 1
matrix[0][2] = 2
matrix[0][3] = 3
matrix[0][4] = 4
matrix[1][0] = 5
matrix[1][1] = 6
matrix[1][2] = 7
matrix[1][3] = 8
matrix[1][4] = 9
matrix[2][0] = 10
matrix[2][1] = 11
matrix[2][2] = 12
matrix[2][3] = 13
matrix[2][4] = 14
matrix[3][0] = 15
matrix[3][1] = 16
matrix[3][2] = 17
matrix[3][3] = 18
matrix[3][4] = 19
matrix[4][0] = 20
matrix[4][1] = 21
matrix[4][2] = 22
matrix[4][3] = 23
matrix[4][4] = 24

Did I happen to mention Modulo?

Please review the code so far as it pertains to Modulo. You need to see how modulo is taking a single number and converting it into a column index. This is believe it or not a non-trivial use of a computer program. If you enter the field or do electronics as a hobby you may have to program in a language that doesn't have multidimensional arrays. But that shouldn't stop you from making them yourself out of the tools you do have available. If the project you are working on needs multi-dimensional arrays to simplify the code build your own.

Certainly Java has multidimensional arrays. But what if you wanted to fill the contents of a multidimensional array with the values in a 1 dimensional array? How would we do that? We could adapt our code without much of a problem, but how would you do it if you weren't an expert with modulo?

Better Display or at least more mathematical display

For those of you who have already been introduced to matrices you will agree that our display method does not look like a matrix in a math book. Let's create a new method call displayMatrix that will display the values in rows or columns we don't need the indexes. But we will use modulo to tell us when to start printing elements in a new row. I won't go into the design but try to do it yourself. I provide my solution with the full code listing. One problem with the output from my implementation below, the matrix printed out isn't very square. Single digit numbers get different spacing than double digit. I'll address that in the next installment.

Conclusion

I'm not finished with modulo 2 more articles are coming one to implement 2 dimensional arrays as a Java multidimentional array and fill it with consecutive numbers or from numbers in a single dimensional array. Modulo will play a role there. The second article will be a Blackjack program and how modulo helps us to determine the type of card ace through ten, jack, quesn, king. Modulo will also help determine the suit spades, diamonds, clubs, hearts.

I hope that my taking you through an actual design process didn't bore you to much. I will probably continue in that vein because these programs don't go from mind to paper with out some syntax errors. I thought it might be helpful to you to see how some one else thinks through the process and how far they take it before commiting to compile the code.

/**
 *
 * @author Nasty Old Dog
 */
public class Matrix1d {

    int n = 10;
    int mat1d[] = null;

    Matrix1d(int n) {
        this.n = n;
        this.mat1d = new int[this.n * this.n];
        // intialize the elements to count up from 0
        for (int i = 0; i < this.n * this.n; i++) {
            mat1d[i] = i;
        }
    }

// put our code to get an element here
    int getElement(int row, int col) {
        return this.mat1d[row * this.n + col];
    }

    void display() {
        int r, c;

        for (int i = 0; i < this.n * this.n; i++) {
            r = i / this.n;   // integer divide gives us the row for the element

            // for the column it's the left over after the integer divide
            // col = i - (r * n) which sin r was calculated with int division is just
            // the remainder. Well since we want to look professional we know that's 
            // modulo. So to look like we know what's going on let's use modulo
            c = i % this.n;
            System.out.println("matrix[" + r + "][" + c + "] = " + this.mat1d[i]);
        }
    }

    void displayMatrix() {
        for (int i = 0; i < this.n * this.n; i++) {
            if (i % n == 0) {
                System.out.println();
            }
            System.out.print(i + " ");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        // Create a 5 x 5 matrix
        Matrix1d mymatrix = new Matrix1d(5);

        mymatrix.display();
        mymatrix.displayMatrix();
    }
}

References

  1. Iverson, K.E., A Programming Language, Wiley, 1962-05. Available at J Software Site

Footnotes:

1 The late Dr. Iverson's work lives on at a company he created: J Software. He also updated APL (so to speak) with it's sister the programming language J. J has versions for most platforms even the iPhone and iPod. The difference between J and APL is that J reverts back to standard characters yet all of the interesting operators are there. Dr. Iverson also improves on APL in the terminology used to describe the language. Dr. Iverson maps the language contructs into English grammar equivalents. This way comments are started by NB. the english equivalent for NB note bene (note well), operators are now verbs, Variables are nouns, etc. It's a great language one I highly recommend. Read more at http://wwww.jsoftware.com

By the way in J the operator, I mean verb, for modulo is called residue and it uses the "|" symbol instead of a "%" like in Java. You also must put the numbers in reverse, why because the entire language J is read from Right to Left. So the J equivalent of Java's 121%5 would be 5|121. You may think it's confusing, I prefer to think of it as amazing that I can change the way a computer does things to suit my whims and fancies.

Author: Nasty Old Dog

Tuesday, January 1, 2013

Recursion

Recursion

Recursion

In the beginning there was the SUBROUTINE.

In the early days of programming there were no large standard libraries available. There were a small set of routines that gave the programmer access to operating system facilities like printers and screen output. In some languages these were built right into the language, much the way Java has some built in constructs for the String class.

In assembly language programming, a language to code directly in the codes the CPU (Central Processing Unit) understands, there is a 'JSR' statement. 'JSR' is a mneumonic that stands for Jump SubRoutine. In an assembler language program this means to jump to a 'label' placed in your code then, return when the 'RET' statement is hit. Return to where? To the statement right after the 'JSR'. It's much like when your playing a video game and your mom asks you to do the dishes or take out the garbage. You, as your very own CPU, pause the video game, go and accomplish the chore, then return right back at the video game picking up exactly where you left off. The problem for the assmebly language programmer is that these statements do not allow parameters. The programmer must take care of all of that themselves in the assembly language code

FORTRAN was one of the very first computer languages developed. It's short for Formula Translation. It's big claim to fame was to provide the user with variables and arithmetic operators built into the language. This became a main stay of Engineers and Scientists who wanted to solve difficult mathmatical problems. Fortran also provided a feature called SUBROUTINEs. It had a SUBROUTINE statement and better than it's assembly language counterpart it allowed you to define parameters and use them in your programs. In fact there is not much difference between the look of a FORTRAN SUBROUTINE and a Java method. Java is a little fancier there are 'public' and 'private' methods. There are 'static' methods. In the early days of FORTRAN you didn't have to worry about this every SUBROUTINE was 'static' SUBROUTINEs never return a value because FORTRAN had FUNCTION statements for that.

FORTRAN also had a CALL statement so you could execute your SUBROUTINE. This is why you may hear people talk about a 'Method Call' or an instructor may say "Don't for get to call your method". Computer Science has a very informal language when we talk about various topics, but we try to use different terminology when we can to better describe what we are doing. The example here is that I may tell you to 'Run' your method and you may understand what I mean. But more formally you 'Run' a program and the program 'Calls' your method.

A SUBROUTINE can call other SUBROUTINEs

The whole point of this stroll down memory lane is that once the syntax of the subroutine became establised, there was a natural inclination to allow a SUBROUTINE to call itself. We already had recursive definitions as part of mathematics. So now that we have computers that animate our mathematics for us, the push for recursive SUBROUTINEs was on.

It may seem that it should be self-evident that a SUBROUTINE can call itself but in the early design of computer languages it turns out you must do some special things under the covers to get this to happen. So newer languages that followed after FORTRAN made sure they had these capabilities. I won't bore you with a cronology of how recursion came into being. There were languages in existance at the time of FORTRAN that already had it. But suffice it to say that when Personal Computers came about and the C language (a predecessor to Java) dominated the programming of that platform, C had built in recursion. Lucky for you! because it's a pain to simulate recursion in a language that doesn't have it. Java as an ancestor of C also has recursion built in.

METHODS ARE JAVA SUBROUTINES

As languages change so does the nomenclature. SUBROUTINEs are now methods. Methods don't even have a METHOD statement like SUBROUTINES do. This is because after people became very familiar with FORTRAN they realized that a SUBROUTINE definition can be recognized by:

  • it's name
  • the parenthesis that follow
  • and the parameter definitions inside the parenthesis

So by the time Java comes around we expect you as a newbie just to pick up on this on your own. If you are an older programmer you know you got sick of writing SUBROUTINE for each and every SUBROUTINE definition. That's a large amount of typing saved (well kind of there are things like public and void but they are much shorter words. We even dropped a formal statement for calling the SUBROUTINE. Now you are just supposed to know that any name followed by parenthesis with comma separated parameters is a Method call. Methods have all the stuff of a subroutine but now are grouped into objects (ie. class definitions). They can be inherited and they can be overridden. These are certainly things that don't happen with SUBROUTINES. The name change is fitting since the old fashioned SUNROUTINES have more in common with "static" methods than with methods in general.

METHODS can call themselves

Recursion being well established in computer science methods can call themselves, it's built in to the language. The danger of course is that the programmer must make sure they have accounted for any and all 'base' cases, otherwise the code will run forever! Well, not forever you eventually run out of memory.

Recursive definitions

The first example is always factorial. Sorry about that. But it has a simply stated recursive definition so it is popular. Students usually focus on factorial being so trivial to implement that they feel recursion is senseless since you could do it easily with a loop. But like so many things in computer science the trivial case is foreshadowing of more complicated stuff yet to come.

Factorial

factorial (n) = 1 (for n = 1)

                   = factorial(n-1) * n (for n > 1)

Fibonacci numbers

Fib(n) = 0 (for n = 0)

           = 1 (for n = 1)

           = Fib(n-1) + Fib(n-2) (for n > 1)

This is a better example for recursion. It does not have a trivial loop alternative. That's not to say you can't create a loop that can do it. Every recursive implementation has a looping counterpart. It's just that it's not trivial like factorial is. The double calls to Fib above do us in for coming up with an easy looping code design.

This type of recursion is termed tree recursion by Abelson and Sussman in their classic work "Structure and Interpretation of Computer Programs"(known in computer science circles as just SICP). That's because if you were to draw out all the recursive calls at each step, you would form an inverted tree with the first call leading to 2 calls and those two calls lead to two calls and so on.

Greatest Common Divisors

Given 2 integers this is the greatest integer that divides both of them evenly. It is very helpful when you are trying to reduce fractions to lowest terms.

Gcd(a,b) = a (for b = 0)

             = Gcd (b, remainder(a,b)) (for b > 0)

If you think the above definition is some modern mathematic torture dreamed up to make your life a living hell. Abelson and Sussman point out that the above definition appears in Euclid's Elements Book 7 circa 300 BC. So the reality is that mathematicians have been developing torturous problems for their students from time immemorial.

Your Job

I leave it up to the student to implement these functions. If your interested there are more recursive functions defined in the SICP which is available online. There are also Scheme Programming Language examples of their implementation. That may assist you with the Java implementation or it may confuse you more.

Princeton University has an excellent collection of recursive functions at their introduction to computer science web site. Their site includes a large number of implementation examples. I would suggest you try to implement the examples above and then visit their site if you have any problems. http://introcs.cs.princeton.edu/java/23recursion/ The link to Princeton's course is here: http://introcs.cs.princeton.edu/java/home/ This includes a much broader perspective also going over some computer architecture which I believe is incredibly helpful when you are trying to make sense of computer science in general.

What No Code?

Of course there is code. It wouldn't be a comp sci article without code. Using our previously defined APString class I will implement a reverse method that uses recursion to reverse the elements of our string. Now, because we have no built in operators for the APString class (such as string concatenation), we can't do a simple recursive routine that's possible with the Java String class. Actually that's a good idea let's first look at using recursion with the Java String class.

A simple recursive methodology for Java Strings would be the following:

  1. take the first character of the String and store it as a string
  2. reverse the rest of the string after the first character is removed
  3. concatenate the new reversed remainder with the first character added to the end.

Step 2 has the recursion in it if I name the method 'revStr' the pseudo code will look like:

String firstch;
String restStr;

// ignore the base case for now
firstch = str.subString(1,2);
restStr = str.subString(2);
return revStr(restStr) + firstch;  // concatenate the first character onto the end of the string

Take some time to think of what the base case is for the code fragment above. I went ahead and implemented the whole code and placed it at the end of the article but given what I have done above you should be able to code the whole thing yourself. Go ahead and see if you can reverse a Java string recursively in your own Java IDE. I would create a separate class for this assignment and give it it's own main method. Then once you have it working compare it to the code at the end of the article.

APString reverse done recursively

This was not such an obvious recursion because there are no built in facilities for APString like the concatenation operator that the Java String has. We have not even implemented a concatenation method or a substring method. So you can see the time savings that Java provides and the difficulty we have trying to duplicate the same functionality in a class of our own. I will add those in a future article and try to implement reverse as we did for the Java String class.

Since we don't have the benefit of the methods described above I will take advantage of a Java method for arrays.

Arrays.copyOfRange(<array variable name>, start index, end index).

This is provided by the Java class library. It's kind of cheating because I don't have to make my own copy routine, which would probably loop through all the elements of the array. Since we have to loop why bother reversing the string recursively other than to show how you can think of problems recursively? Well, that's the point really. There are times when a looping construct is the best mechanism but there are times when recursion will help to simplify your code. Most of the time you will have to try both and see which one provides you with an elegant solution.

Design of the recursive algorithm

The APString class uses char arrays to implement it's String functionality. We will need a temporary char array to hold the reversed elements and to be our working storage as we change the order of the characters. We could do this in the char array we use for the object itself but then this would actually change our object rather than providing a new object with the desired results. This also means we need to return an object of APString as the final result. This creates a problem for recursion because I want to recurse on the char array and then return an APString when all is done.

  • Design Requirements
    1. return an object of APString
    2. create a recursive routine to recurse on char array
    3. use a temporary char array to be the working storage
    4. Don't let any of our methods change the underlying values of our original APString object

This means we will need 2 methods instead of one. One method to setup our working storage and return an APString value and another method to do the recursion on our working storage.

Recursive method and setup method

// reverse_array recursive helper procedure for reverser
// 
private void reverse_array(int startIdx, int endIdx, char ch[]) 
{   
    char tmpch;
    // base case 1: odd length we have reached the middle element
    if (startIdx == endIdx) 
        return;
    // base case 2: even length array the indexes are side by side
    if ((endIdx-startIdx) == 1) 
    {
        tmpch = ch[startIdx];
        ch[startIdx] = ch[endIdx];
        ch[endIdx] = tmpch;
        return;
    }
    // recursive case swap current indexes then recurse on the rest
    tmpch = ch[startIdx];
    ch[startIdx] = ch[endIdx];
    ch[endIdx] = tmpch;
    reverse_array(startIdx+1,endIdx-1,ch);        
}

 // The intial call to set up the recursive routine above with working storage array
public APString revStr() {
    char[] tmparray = Arrays.copyOfRange(chArray, 0, this.length());
    reverse_array(0,this.length()-1,tmparray);
    return new APString(tmparray);
}

The main method used to test the above code

public static void main(String[] args) {
    // Since we are trying to avoid the use of the built-in Java Strings
    // we are forced to define strings by initializing a char array
    // I think you can see why it's so nice to have Strings built into
    // Java. Imagine having to define every string like this:
    char[] a = {'T','h','i','s',' ','i','s',' ','a',' ','t','e','s','t','\0'};
    APString ap = new APString(a);
    // Using the String double quotes built in the following is an equivalent
    // statement:
    APString ap1 = new APString("This is a test".toCharArray());

    System.out.println(ap.toString()+ "   length = " + ap.length());
    System.out.println(ap1.toString()+ "   length = " + ap1.length());
    System.out.println(ap.reverse().toString());
    System.out.println(ap.revStr().toString());
    System.out.println("No change to original: " + ap.toString());
}

And the output from testing:

run:
This is a test   length = 14
This is a test   length = 14
Looping reverse: tset a si sihT
Recursive reverese: tset a si sihT
No change to original: This is a test
BUILD SUCCESSFUL (total time: 0 seconds)

The whole APString code with the recursive procedures built in

/*
 * APString class
 * The idea is to create a string class that uses arrays to hold the characters
 * This methodology is closer to how the actual hardware is organized.
 * The String class in Java has built in support. In fact any double quoted 
 * String is itself a String class object. "a string".toString(); is valid
 * Java code and all of the methods of the String class may be used above
 * in place of toString().
 * 
 * Java hides much of this organization because it is object oriented and 
 * there is a long history of String operations in computer science. So the
 * designers (rightly so) added String handling capabilities in the language 
 * itself. However for people trying to learn about computers for the first
 * time this shielding (known in computer science terms as abstracting) of the
 * lower level organization is a disservice. While Strings are well known the 
 * patterns of their processing are repeated enough for other things that a 
 * thorough understanding of the low level processing of Strings will only help
 * the new Programmer/Computer Scientist.
 * 
 * Indeed Donald Knuth in his classic treatise "The Art of Computer Programming"
 * goes so far as to invent a ficticious computer with a ficticious 
 * assembly language to bring to light the issues of computer architecture and
 * their effect on the design of computer programs.
 */
package apcompsci;

import java.util.Arrays;

/**
 *
 * @author nasty
 */
public class APString {    
    // It's not necessary to limit a char array like this. Java will 
    // dynamically create space as needed but in some computer languages
    // they must be allocated out ahead of time. So as a place holder we
    // define our initial array as 100 chars.
    char chArray[] = new char [100];
    int len;

    APString(char chArray[])
    {
        // Let's copy the char array given into the one we defined above as
        // part of the class
        int i = 0;
        for(i = 0; i < chArray.length; i++)
          this.chArray[i] = chArray[i];
        this.len = i;
        this.chArray[i]='\0';
        // The above '\0' is the ASCII null character. By setting the very
        // last character to this value it acts as a flag to let us know
        // we are at the end of our string. The length() method uses this to
        // calculate the length of the string
        // I also implemented a len field to store this in. It is left to 
        // the reader to reimplement this class with a length field and get
        // get rid of the null termination. This would save a lot of looping
        // over the string to get the string length
    }

// All classes defined in Java have a base toString but because we have
// defined some fields as part of our class we need to convert those to 
// Strings so we can print them out and we override the base toString features
//
// It's unfortunate but we must rely on the built-in String class because
// they are used by all the print procedures
@Override
    public String toString()
    {
        String s = "";

        for (int i = 0; i < this.len; i++)
            s = s + this.chArray[i];
        return s;
    }

    public int length()
    {
        int i = 0;
        for (i = 0; this.chArray[i] != '\0'; i++)
        {
            // Do nothing just let i keep count and keep looping until we hit
            // the null character which will break the test above
        }
        return i;
    }

    // reverse - create a new APString that reverses all the characters in 
    // the current class. Except for the null string we don't want that to 
    // be our first character. WHY?
    public APString reverse()
    {
        char tmp[] = new char[this.length() + 1];
        int j = 0;
        for (int i = this.length() - 1; i >= 0; i-- , j++)
        {
            tmp[j] = this.chArray[i];
        }
        tmp[j] = '\0';
        return new APString(tmp);
    }

    // reverse_array recursive helper procedure for reverser
    // 
    private void reverse_array(int startIdx, int endIdx, char ch[]) 
    {   
        char tmpch;
        // base case 1: odd length we have reached the middle element
        if (startIdx == endIdx) 
            return;
        // base case 2: even length array the indexes are side by side
        if ((endIdx-startIdx) == 1) 
        {
            tmpch = ch[startIdx];
            ch[startIdx] = ch[endIdx];
            ch[endIdx] = tmpch;
            return;
        }
        // recursive case swap current indexes then recurse on the rest
        tmpch = ch[startIdx];
        ch[startIdx] = ch[endIdx];
        ch[endIdx] = tmpch;
        reverse_array(startIdx+1,endIdx-1,ch);        
    }

     // The intial call to set up the recursive routine above with working storage array
    public APString revStr() {
        char[] tmparray = Arrays.copyOfRange(chArray, 0, this.length());
        reverse_array(0,this.length()-1,tmparray);
        return new APString(tmparray);
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // Since we are trying to avoid the use of the built-in Java Strings
        // we are forced to define strings by initializing a char array
        // I think you can see why it's so nice to have Strings built into
        // Java. Imagine having to define every string like this:
        char[] a = {'T','h','i','s',' ','i','s',' ','a',' ','t','e','s','t','\0'};
        APString ap = new APString(a);
        // Using the String double quotes built in the following is an equivalent
        // statement:
        APString ap1 = new APString("This is a test".toCharArray());

        System.out.println(ap.toString()+ "   length = " + ap.length());
        System.out.println(ap1.toString()+ "   length = " + ap1.length());
        System.out.println("Looping reverse: " + ap.reverse().toString());
        System.out.println("Recursive reverese: " + ap.revStr().toString());
        System.out.println("No change to original: " + ap.toString());
    }
}

Recursive reverse on the Java String class

package apcompsci;

/**
 *
 * @author Nasty Old Dog
 */
public class NODString {
    public String revStr(String s)
    {
        String firstch;
        String restStr;

        // base case s length is 1 just return s
        if (s.length() == 1)
            return s;
        // recursive case
        firstch = s.substring(0, 1);  // get the first character
        restStr = s.substring(1);     // get the rest of the string

        // reverse the string by moving the first char to the end and the
        // reverse of the rest of the string on the front.
        return revStr(restStr) + firstch;   
    }

    public static void main(String[]args)
    {
        String teststr = "reverse this";
        NODString nod = new NODString();
        System.out.println("The reverse of "+teststr+" is "+nod.revStr(teststr));
    }

}

The output from the above program is:

run:
The reverse of reverse this is siht esrever
BUILD SUCCESSFUL (total time: 1 second)

References

  1. Abelson, Harold, Gerald Jay. Sussman, and Julie Sussman. Structure and Interpretation of Computer Programs. Cambridge, MA: MIT, 1985. Print.
  2. "Welcome to the SICP Web Site." Welcome to the SICP Web Site. N.p., n.d. Web. 01 Jan. 2013. http://mitpress.mit.edu/sicp/.
  3. Sedgewick, Robert, and Kevin Wayne. "Introduction to Programming in Java." Introduction to Programming in Java. Addison-Wesley, n.d. Web. 01 Jan. 2013. http://introcs.cs.princeton.edu/java/home/.

Author: Nasty Old Dog

Sunday, December 9, 2012

How to Approach AP Computer Science

How to Approach AP Computer Science

How to Approach AP Computer Science

How to Approach AP Computer Science

After seeing the mess of papers my son considers organization and listening to the excuses as to why this course is so difficult. I thought I would provide a little guide on how to get on top of this course. It's not really a difficult course. But it requires that you don't sit on your hands and hope everything becomes clear just by staring at it. This is like my obsessive compulsive behavior of constantly opening the refrigerator door in the hopes that food will somehow magically appear (even though I'm home alone and no one has gone to the store). Now I realize that an AP Computer Science Student is young. They have been raised like veals by their parents and now they must come to grips with actually creating something instead of just using something. So first and foremost you must embrace the challenge and rise to the occasion. If you put a little effort up front it will make this course easy for you.

Start your assignment as early as possible

I know this may come as a surprise but your teacher actually sleeps. They are not creatures of the night looking for their next blood meal. So by starting your assigned project early you have a chance to email them with any questions that may come up as you try to do your project like:

Is it really due tomorrow? It seems awfully long!

The smart student who sent the email at 8pm found out at 9pm it's due 2 days from now. The dumb student who waited until 10pm and then stayed up until 3am trying to finish, then finds out (next day at school) as they go to hand in the project that it's actually due in 2 days.

Remember you are young. Your attention span is probably a minute longer than a 10 year old (sorry but that's probably what it is). You are probably a little arrogant so you are completely poo-pooing the previous sentence, and are convinced you don't miss a thing the teacher says. To you I have some advice:

  1. Make sure you have your teacher's email. Make sure you use it if you have any questions or complaints
  2. Make sure you have the email, home phone, and cell phone of at least 2 people taking the class (because maybe your teacher actually has a life and is unavailable when you need him or her most)
  3. If you have a class where you have no idea what the teacher is talking about make sure you talk to the teacher after class (or after school), Take notes and write down key words you don't understand so you can look them up at home. After you find or get an explanation call a friend in the class and see if that is their understanding as well
  4. If you are doing a project and it seems too complex for the amount of time alotted contact the teacher and a friend and see if you are mistaken about the deadline or misguided about how to approach it.
  5. Take notes in class they just have to be a quick outline of what was discussed so you can review
  6. Make sure you know where the teacher's web site is located. It's a computer course they probably have all the handouts online.
  7. I can't stress 1 and 2 enough so go look at them again.

Print Stuff Out

I know we are supposed to save trees but do yourself a favor and kill a few (if you have big a problem with that find recycled computer paper). Print out your assignments. Write on them, model the code on them. When you have completed the project make a printout of your code and keep it with the problem statement for you to review. The projects are set up to teach you different aspects of Computer Science they become their own review sheet.

Keep a course 3 ring binder (loose leaf notebook in my day)

Dr. Frederick Brooke in his classic work on Software Engineering talks about a large programming project at IBM back in the 1960s. Now this project hired the best of the best from within IBM and the project did one thing that kept every one on the project synchronized. They kept a set of project notebooks and in it went all the design docuemts and all the user documentation, everything.

So if it's good enough for the top people at IBM I think you should be doing it to. Keep a notebook. At a minimum: a hard copy of all your programming assignments should be in there, any notes you may have taken, and any handouts that the teacher has given you. Even though much of this is available electronically keep a hard copy around. Trust me the very fact you keep and update the notebook will mean you absorb more knowledge about the subject.

Know the language syntax

In AP Comp Sci that means: know the full Java syntax for anything you may choose to do in Java. The wikipedia website's page on Java syntax is as good as any. You should take a weekend and make sure you know how and why you use each feature of the syntax. If there is time you should get a small piece of code working showing the major control statements available in Java (if, for ,while, switch). Do not wait for the teacher to introduce this stuff to you. Do it on your own and be ready with questions when you do go over it in class.

Get the Java Library Source code

The Java development environment,known as the JDK (not JRE), on your computer usually comes with a .zip file of all the source code that implements the standard library. Be sure to unzip it and look at the various implementations for Strings, Lists, etc. It will only help you to see a good example. There is a browsable version available at http://grepcode.com/snapshot/repository.grepcode.com/java/root/jdk/openjdk/7-b147/

Get a hard copy of the textbook

I haven't found a good Java Book for a beginner. I have a number of books that I've collected over the years most are excellent references but none of them provide a decent tutorial you would want for an introductory course. My son's course uses a free online book which is available from the book's website and from Amazon as a hard cover book. I bought that. I would recommend that you get a hardcopy version of your courses text.

The hard cover book is like having a second computer dedicated to the text. Go over the teacher's reading assignments in the book don't assume you will pick it up by doing the project. Use an online version just for searching.

Get a couple of AP Comp Sci review books

These will help condense the course down and give you some more insight as to what you should be focusing on. Each book may organize the course a little differently and you may understand one better than the other. I can't really recommend one over another, but I easily found 2 review books for AP Comp Sci on Amazon.

Learn to use the cut and paste on your IDE

Programming is a repetitive process the sooner you learn to cut and paste from previous projects and similar classes the faster a programmer you will become. If you are typing everything from scratch for every project, you are wasting time. This course should get easier as you go along. Not more time consuming and difficult

Don't freak out about recursion

Just as you call methods inside other methods there is no reason a method can't call itself. It's called recursion. It exists in mathematics and it exists in programming. The trick to recursion is you must have a test built into method code that indicates when you are going to stop the recursive calls. This is just a warning of things yet to come. In the end it's not much different than a for loop. You keep looping until a test condition is reached. In recursion you keep calling yourself until a test condition is met. The Java language is set up to make this all happen. Many computer science papers exist for how to make it more efficient and less memory intensive, so it's an important topic to come to grips with.

Ok, you're freaking out anyway, I will address recursion as a topic in the future.

Finally

If you find yourself getting dinged on syntax errors on your tests, you may be better off not seeing where the errors are immediately. The IDEs (like Eclipse or Netbeans) have instant syntax checking. When you are an experienced developer this can be a time saving device. But as a new student this may be doing to much of the work for you. You aren't getting the opportunity to proofread your program before you have the computer check it. It would be nice if you could turn off the instant syntax checking. But I haven't been able to find a way to turn it off.

One way to handle would be to write your program by hand on paper first. Then type it in after you have gone over it once for syntax errors. Then as mistakes come up in the IDE you can place the corrections on your hand written program. This will give you direct feedback on where you are weak on syntax knowledge.

The other way is to drop the IDE altogether and just use an editor and then compile the program in a command line window. If you know how to do this on your computer it's a nice option that keeps you on the computer typing but forces you into proof reading your code and fixing it before you have the computer double check it. If you don't know how to do this I have it on my list of topics to address in a future blog, so more on this later.

References

Brooks, Frederick P. "The Mythical Man-month: Essays on Software Engineering." Reading, MA: Addison-Wesley Pub., 1995. Print.

Author: Nasty Old Dog