Title: How to be a good programmer
Course: CPS 261: Advanced Java Concepts ~ DL & MM MASTER

How to be a Good Programmer

Programming Philosophy

I wanted to share some thoughts with you at this point in the course.
Perhaps you have found the homework more demanding than you expected.  To tell you the truth, I wish I didn't have to look at so many homework assignments because grading homework assignments is my least favorite thing to do as a teacher.
I want to express some programming philosophies by making some analogies with music

Practice Analogy:
Learning to program is a little like learning a music.  Consistent practice is what creates competent musicians.  Programming is similar. For many of you, your goal probably includes getting a good grade in this class.
I would love to see all of you get a good grade in my class.  However, my real goal for you is that if you get a good grade in this class and end up getting a job in programming, I want to know that you have the skills to succeed  in your job. This is the purpose for the programming practice that you will get by doing the homework assignments.

Style Analogy
If you were to listen to a Beethoven music piece played by a beginning piano player and compare it with an accomplished piano player, your ear would clearly hear the difference even if both players hit all of the notes.  In programming, we may not value style as much as style is valued in music;  however it is still something to pay attention to.  In programming getting the job done correctly may be the most important aspect of a program, but the style characteristics such as simplicity, readability and maintainability are something that I want you to notice.   Strive for creating programs where  the algorithms literally jump off the page if possible because they are so readable.  Avoid convoluted and overly complicated approaches  and try to come up with simple approaches when possible.  Simple readable code is usually more robust and is easier to maintain and fix when necessary.  Make it a practice to observe code and note when code is readable and when it is not. Part of the reason I provide "Published Answers" on all of the programming assignments is to give you a chance to see another approach to the problem you have just solved.
Well those are  my reasons for requiring  homework ... I believe it will pay off if you hang in there.

More Specific Suggestions

Pay attention to detail: When you write a paper in an English class, a human being reads it and will probably understand what you meant even though you said something a little off. Not so in computer programming. If your program is even a little off, it can do very different things because your program will be executed by a CPU not a human being. You must get all details correct or else you will have to deal with the consequences.

Copy and Paste - I often provide you copy and paste opportunities to get started. Although this is there to make things convenient for you, it may hinder your learning experience. Sometimes it would be better if you could try to construct programs from scratch. Peek back at the copy and paste opportunity when you get stuck. It might take you longer, but you may learn more from it.

Tracking down why your program doesn't work: - Usually there are 3 basic approaches to take when your program isn't working:

- Stare at it long enough with the output you have until you see the problem
- Add additional output(debug statements) to your program so the program tells you what is going on. Carefully construct your debug so that it facilitates your debugging.
  - Construct output that identifies whether your programming is working at the various execution stages of your program. This allows you to know the stage where you have to look for your problem
  - Put debug statements in places where unexpected things might happen. Don't expect the data your program is processing to be perfect. If it has problems you need to loudly complain with an appropriate message.
- Make the Debugger your friend and get good at using it's many features. Not all problems can be solved with the debugger. But there are many times where the debugger can quickly help you identify which program statement is defective. Become a "Debugger-Expert" and make the Debugger one of the first things you are comfortable to try.
- Get to the bottom of your problem and need before you start adding lots of code. Once you have figured out the real problem, you often will find that the fix is simple and robust. Adding a lot of code that just covers up a basic design flaw is not a good approach to take in the long haul. "Duct tape code" is often a quick and dirty fix, but in the long haul it covers up your fundamental design problem.

After adding lots of code you might find your program is harder to understand. Instead of a simple fix for what you really needed, you might find that you added some significant complexity. For example in the following picture we may have only needed a "Simple knapkin", but we got the following instead:

Robust styles: By following good programming practice you can make your programs much easier to understand, debug and maintain.

- Avoid code repetition - If you find code that gets repeated, you probably could create a utility method that contains the repeated code and you can call it as many times as the capability is needed.
- For programs that are reasonably large, I would highly recommend putting your ideas down on paper before you write any code. This might just be some informal pictures you have drawn or it could be a formal Design document for a significant project. Design Documents are what you will probably need to write if you work in the Programming Industry.
- Methods or classes that are very large can make it hard to see what is going on. Breaking the methods or the classes into smaller entities usually is a good idea.
- If your code has become overly complicated and kludgy, you might want to step back and ask yourself if there is an easier way to write this code. Keeping your logic simplified will almost always pay off in a big way. Take a look at the published answers after you receive a grade. The published answers may have a simpler way to solve a problem that you couldn't find a simple solution for.
- Always properly indent your code. Eclipse (or whatever IDE you are using) will do this for you.
- Follow naming conventions:
  - Start with a capital letter for the names of classes.
  - Start with lower case for variables.
  - Constant variable names should be upper case.
  - Use meaningful names for variables having a large scope. Usually this includes instance variables. For variable names that are 2 words, use either "camel-case" (firstName), or "underscore approach" ( first_name).
  - For variables that are unimportant and have limited scope, I like to give them short names with no meaningful name like ("i", "j", ... ).

Letting the Compiler be your friend: Properly using the compiler can improve your programming

- The compiler gives you compiler hints as you enter your code. However, you will get better feedback from the compiler if you minimize the errors you leave in your code. I often see students who have the code they are working on riddled with compiler errors. Because of this, the feedback given by the compiler is compromised. You can always leave stubs that temporarily return something just to avoid the errors generated from not returning anything.
- You have to fix the actual compile errors. You can see what the cause of it is by putting your mouse on the red error marking on the left. Actually in some cases you can use your IDE (Eclipse for example) to provide fix suggestions for the problem. Don't blindly take the advice of the IDE without understanding whether the suggested fix is the appropriate one for you.
- It is good to take a look at the yellow warnings, but not all of them need to be payed attention to. With practice I think you will figure out which warnings are worth doing something about (you can ask in MM or Group study sessions).
- Useful trick: When I am in a large program and I want to know all of the places where an instance variable is being used, I sometimes, just change the name a little where the variable is declared. In this way, the compiler will temporarily give me compile errors every place the variable was used. Once I get the idea, I fix the variable name to get rid of the temporary compile errors.

To demonstrate some of these issues, I will use a modified version of the starter code we use for the TicTacToe problem in JH7 of cps161:

package tictactoe;

class TicTacToe
{
    char ttt[][] = new char[3][3];
    static final char player1 = 'O';
    static final char player2 = 'X';
    Scanner scan  =new Scanner(System.in);


    String playerID(char player)
    {
    // Prints the identity of the player
    // For example:
    // player2: X

        if (player == player1)
            return "player1: "+player;
        else
            return "player2: "+ player;
    }

    void getPlayerInput(char player)
    {
    // ******* Details to fill in ************

       // Prompt the user for a cell input.  Make sure its a legal
       // cell designator.  Also make sure the cell doesn't already
       // have a player in it.  Prompt the user again in the case
       // of any problem.  Once a valid spot has been found,
       // you will issue a statement like:

        int row, col;
        int x;
        Scanner keyboard = new Scanner(System.in);

        ttt[row][col]=player;

    }

    boolean gameIsDraw()
    {
     // ******* Details to fill in ************

        // If all ttt entries have been taken return true
        // otherwise return false
    }

    boolean winner(char player)
    {
     // ******* Details to fill in ************

     // Check to see if the parameter player has won
     // Winning means that player shows up in a line of
     // three.  The line can be a column, row or a diagonal
     // Return true if player is a winner, otherwise return false.
    }

    void displayBoard()
    {
     // ******* Details to fill in ************

     // If you want to skip the fun of this, I have a candidate displayBoard down below

    }


    void newgame()
    {
        char currPlayer = player1;
        for(int i=0; i<3; i++)
            for(int j=0; j<3; j++)
                ttt[i][j] =' ';

        boolean continueFlag = true;
        while (continueFlag)
        {
            displayBoard();
            if (gameIsDraw())
            {
                System.out.println("Game Ends in Draw");
                continueFlag = false;
            }
            else
            {
                getPlayerInput(currPlayer);
                if (winner(currPlayer))
                {
                    System.out.println("We have a winner: " + playerID(currPlayer));
                    displayBoard();
                    continueFlag = false;
                }
                else
                {
                    if (currPlayer == player1) currPlayer = player2;
                        else currPlayer = player1;
                }
             }
        }

    }


    public static void main(String[] args)
    {
        TicTacToe game = new TicTacToe();
        String str;
        do
        {
            game.newgame();

            System.out.println("Do you want to play Tic-Tac-Toe (y/n)?");
            str= game.scan.next();
        } while ("y".equals(str));

        System.out.println("Bye");
    }
}



Last Updated: August 29, 2015 7:52 PM