views:

815

answers:

5

Are there any tips you have for preparing useful example code ?

A: 

I would say that the two things you cite as "an aide to comprehensibility" actually detract from the comprehensibility. Non-autoboxing in particular is pretty annoying: now that Java has thankfully gotten rid of that terrible implementation detail, why foist it upon new learners anyway?

In addition, while tutoring an important part of the process would be to communicate language conventions---such as not including such extra spaces, or the placement of braces. I have actually seen the newline-for-each-brace style referred to as "Java style" before, so take that into consideration.

Domenic
+6  A: 

I think the best tip I can give you for preparing useful code examples, is this: have the person you're tutoring write some code him self. I think that will be the most instructive code you can give him. It has several advantages:

  • You don't waste time teaching him things he already does right.
  • You have good examples of things he does wrong, in a context that he understands.
  • He has already learnt things by coding the assignment you have given him.

You can give assignments that teach him various valuable topics, such as:

  • Inheritance: let him code some simple inheritance hierarchy, such as animals, or shapes. Make sure to put some gotchas in the assignment.
  • Algorithms: have him implement some well-known algorithm.
  • APIs: let him re-implement some simplified variation of a real feature that is typical for the applications in your company. Usually that will imply some real-world coding is to be done, and usually some API calls are necessary for that.

After he has completed each assignment, you have some perfect example code that you can use to teach your student how to improve his coding style!

Also, it might help to find a couple of colleagues to implement your assignments first, so that you know where the pitfalls of each assignment will be. That way, you could adjust them, if necessary, before handing them over to your student.


Keeping my old answer to the previous version of this question, for historical purposes, and also so that the comments will keep making some sense:

When I'm tutoring Java, I discourage people to use break. I forbid them to use labels. (They're gotos in disguise.)

In my opinion, labels and (to a lesser extent) breaks encourage bad coding style, and can usually be rewritten with a while or a for loop. Often your code is much clearer because of it.

I'd rewrite your inner loop as follows:

int index = 0;
int finalIndex = (int)Math.sqrt(value);
while (isPrime && index <= finalIndex) {
    Integer prime = primes.get(index);
    if (value % prime == 0) {
        isPrime = false;
    }
    index++;
}

I don't totally agree with your use of spacing: your pupils might become used to seeing code like that, and might be confused when they're let loose on 'real' code.

I do agree with your point on autoboxing, though. I would use ints in production code, but for educational purposes it might indeed be useful to spell things out explicitly. However, there's still some autoboxing voodoo going on in your example code, where you calculate value % prime :).

jqno
I agree with the point about break and especially labels. For the code cited I'd actually use a separate helper method with a return instead of the labeled break.
Laurence Gonsalves
@jqno: added a blend of your example and my formatting
_ande_turner_
Its very functional to leave break out of the business. Scala doesn't have break or continue.
kd304
How about explaining both the pros and cons of using labels and breaks?
Zach Scrivena
A: 

Use capacity on the arraylist to avoid frequent resizing.

Use Integer.valueOf() instead of newing up them.

Start the loop from 5 and step 2 at a time with value.

What is the experience level of your students?

kd304
+2  A: 

Perform Source Code Reviews

If you are looking to help instill good programming practices in your students, I would recommend finding the source code for problems that have been already solved by students. There are a number of places that would likely be happy to provide you with content, including:

  • High schools
  • Community colleges
  • Hobbyists
  • The Internet

Once you receive (an anonymous archive of) the students' work, sit down for an evening and perform a code review. Here is an actual example from a high school student:

//accepts full name and breaks it into first and last names
public Name (String name) {
    int index = 0; //index of full name

    //find the space between first name and last name
    while (true) {
        if (name.charAt(index) == ' ') {
            break;
        }//if
        index++;
    }//while

    //set first name and last name
    first = name.substring(0, index);
    last = name.substring(index + 1, name.length());

    //encrypt the full name
    encrypt();

}//constructor

//set methods
public void setFirst (String _first) {
    first = _first;

    //encrypt the full name
    encrypt();
}//setFirst

This provides much learning fodder. Here are the major points (without getting too technical or overly picky) that I would make:

  • The documentation does not conform to Javadoc standards. Javadoc is a standard way of writing source code comments that can be transformed into a useful series of web pages.
  • Do not comment the closing brace, especially when the opening brace is only a few lines away. It is a waste of development and compile time, while it offers no help to experienced developers, and serves only to clutter code readability.
  • An accessor for setFirst is provided and should be used throughout the entire class. This is the rule of Don't Repeat Yourself. When a version of Java is released that is more like Smalltalk in the way variables are treated (i.e., the accessor is hidden yet always available), this will not be an issue.
  • Eliminate the duplicate calls to encrypt() (which happens naturally by reusing the set accessor).
  • What happens when only a single name is passed (with no space) via the constructor, or even a null value? (Discuss defensive programming, possibly assertions.)
  • The while( true ) loop should use String.indexOf(...).
  • Bonus marks for those who use String.split(...) and a regular expression to extract the first and last names.
  • Comments should tell the reader why the code was written, not what it does.

Then show the rewritten code:

/**
 * Accepts full name and breaks it into first and last names.
 *
 * @param name A full name, including first and last name, with a single
 * space separator.
 */
public Name( String name ) {
    if( name != null ) {
      // Find the space that separates the first and last name.
      int index = name.indexOf( ' ' );

      // Extract and set the first and last names from the name.
      if( index > 1 ) {
        setFirst( name.substring( 0, index ) );
        setLast( name.substring( index + 1 ) );
      }
      else {
        // No space: only a single name was provided, or no text at all.
        setFirst( name );
        setLast( "" );
      }
    }
}

/**
 * Changes the first name for this instance, then reencrypts the cipher
 * text using the given first name (the current last name is reused).
 *
 * @param first The new first name for this instance.
 */
public void setFirst( String first ) {
    this.first = first;
    encrypt();
}

Some closing thoughts:

  • From just two routines, written by budding programmers, there are many tips to be learned.
  • Consider returning the reviewed code.
  • Be sure to provide logical reasons for critiques. (Saying, "Don't comment closing braces" is relatively useless -- supporting the argument adds value.)
Dave Jarvis
@Thangalin: In looking at the first code snippet I noticed alot of logic within the constructor. For the rewrite I'd also suggest "public Name( String firstname, String lastname, String...middlenames )" as the constructor, and "public static Name parse( String aName )" to perform the construction and return of a new Name Object. Reasoning: Logic within a constructor inhibits unit tests, and teaches a good habit re: dependency injection.
_ande_turner_
Good points, sudo noob. Getting a bit pickier, you could also introduce the builder pattern to avoid the problem of having to get the order of parameters correct. I seldom write methods (or constructors) with more than three parameters. Another problem that exists in the code (as it stands) is the behaviour of multiple spaces and including multiple middle names.
Dave Jarvis
+1  A: 

Show them some common algorithm implementations... BFS, DFS, Djikstras, A*, Mergesort, Quicksort, etc.

I'd say code that has a wide range of uses is best. wide as in, not code that is "this counts to 100 and prints the numbers that are modulo 3 and 5 and is totally useless." but code that solves a real problem. Once you say "A* can make a path from start to finish" then you've got their attention because they know it's useful.

The sorts and the Breadth/Depth first searches are good because they can be short and comprehended easily and have very clear implementations that can teach some good coding practices. The sorts are especially good examples of recursion.

Victor