Lab #5: Not-So-Random Word Generator

This is a short lab (so you have some time for the project and exam) that gives you a little experience with using inheritance to add functionality. You are going to generate sequences of random English words, and use inheritance to add alliteration and rhyming (well, sort of rhyming):

java Words3 340 10
haemodorum hypericum hypobasidium hoodlum hassium haustorium hypochondrium hilum hum hahnium 

1. RandomWord: Setup a Random Word Generator

  1. Download this file of words to your Lab5 directory: words.txt
  2. Download our custom-built RandomWords class that has already been compiled for you: RandomWord.class

    Below is the public interface for this class, and as the User of this class, you don't actually need to see the code or know how it is implemented. All you need is the interface:

    // Constructor for the class, requires a seed value.
    public RandomWord(long seed);
    
    // Returns a random word as a String.
    public String next();
    
  3. We also provide for you a simple program that uses this RandomWord class. It runs and prints out a list of random words. Copy the following Words.java program: Words.java

    public class Words {
      public static void main(String[] args) {
        // Program requires two command-line arguments.
        if( args.length != 2 ) {
          System.out.println("Usage: 'java Lab05 seedValue numWords'");
          System.exit(1);
        }
    
        // Create a RandomWord object and generate random words with it.
        RandomWord rand = new RandomWord(Long.parseLong(args[0]));
        int N = Integer.parseInt(args[1]);
        for(int i = 0; i < N; i++)
          System.out.print(rand.next() + " ");
        System.out.println();
      }
    }

  4. Compile Words.java and run it with a seed value and how many words you want to generate, for example:

    java Words 2398 10
    pokeweed dutch musophobia drypis gwynn hiking vermiculite schizachyrium kalif utmost

2. RandomWordLit: Extend the RandomWord

The above random words are nice, but suppose you need random words to create novel passwords. You'll have trouble remembering these, so let's make the sequence a little easier for humans to recall. Alliteration is a device that emphasizes meaning by using words which start with the same consonant sound. Humans are better at remembering sequences with alliteration.

Your task is to extend RandomWord so that your new class, RandomWordLit, generates random words but only when the next random word starts with the same letter as the previous word. You must extend RandomWord's interface so that your new class behaves exactly like RandomWord, except that calls to next() only produce words with the same first letter. On the very first call to next(), treat it as choosing any random word. Afterward, match the first letter.

If you do this properly, the original Words.java, modified only by replacing RandomWord with RandomWordLit, should give us what we want. i.e. the following program:

public class Words2 {
  public static void main(String[] args) {
    // Program requires two command-line arguments.
    if( args.length != 2 ) {
      System.out.println("Usage: 'java Lab05 seedValue numWords'");
      System.exit(1);
    }

    // Create a RandomWordLit object and generate random words with it.
    RandomWordLit rand = new RandomWordLit(Long.parseLong(args[0]));
    int N = Integer.parseInt(args[1]);
    for(int i = 0; i < N; i++)
      System.out.print(rand.next() + " ");
    System.out.println();
  }
}

should produce a random-looking sequence of words with alliteration. You must use inheritance to do this, and if you do it right, your solution should be short and sweet.

Your output should look as follows:

java Words2 2398 10
pokeweed px plagiarism pressure perseverance paton platyctenea padding pre-raphaelite procaine
java Words2 1000 10
slurred suitcase sandburg schoenberg searobin sorensen surcease spica saxophone soldier

3. RandomWordLitRhyme: Extend RandomWordLit

Alliteration is great, but can we do more? Rhyming is another useful memory device. Your task in this section is to extend RandomWordLit with a new class RandomWordLitRhyme. This will of course use the parent's functionality of returning alliteration words, but we'll add one more constraint: the final two letters of each word must now match. This is not really rhyming, but we're keeping it simple for you.

Create a new Words3.java that uses RandomWordLitRhyme, and a run of it should be exactly as follows:

java Words3 2398 10
pokeweed pretermitted pickerelweed pasquilled pineweed purified pubbed pandied pummelled pedalled
java Words3 340 10
haemodorum hypericum hypobasidium hoodlum hassium haustorium hypochondrium hilum hum hahnium 

4. Javadoc

That's it for coding today. Let's shift to proper Java documentation! You've already learned some Java syntax for comments that go before classes and methods:

/**
 * This area describes what the class does.
 * You can have multiple lines, prefaced by a *
 */
public class Example {
  /**
   * This is a constructor.
   */
  public Example(String arg) { }

  /**
   * Briefly say what this method does.
   */
  public String someFunction(String str, int num) { }
}

This syntax isn't just for show, it also serves a purpose. Java has a method of automatically generating user-friendly HTML documentation for all of your code! The program is called javadoc, and it will read your comments (if you follow the format) and generate documentation. There are just a few more syntax pieces you need:

Extending our little example above, this looks like the following:

/**
 * This area describes what the class does.
 * You can have multiple lines, prefaced by a *
 * @author Assoc Prof Chambers
 */
public class Example {
  /**
   * This is a constructor.
   * @param arg The default arg value you want to start with.
   */
  public Example(String arg) { }

  /**
   * Briefly say what this method does.
   * @param str The name of the person you're accessing.
   * @param num The ID of the person's exam.
   * @return A String that represents the person's grade.
   */
  public String someFunction(String str, int num) { }
}

Your Task: Comment all your Random*.java files with proper javadoc comments. This means every method is commented, every class is commented, and every parameter to a method should have a @param and @return with it.

Run javadoc: Once finished, generate your javadoc!

javadoc -d doc -Xdoclint:all *.java
or, if you would like your javadoc to contain links back to Oracle's API:
javadoc -d doc -Xdoclint:all -link https://docs.oracle.com/en/java/javase/11/docs/api *.java

This will create a doc/ directory. Open up doc/package-summary.html and look at the gloriousness!

Submission

~/bin/submit -c=IC211 -p=Lab05 Words2.java Words3.java RandomWordLit.java RandomWordLitRhyme.java