In this lab we'll write a non-trivial sized program in Java, but it will be written following the procedural programming paradigm — not the way one normally programs in Java. However, we'll get familiar with how Java language features, run-time features and conventions enable and even encourage collaboration.
You'll work in pairs on a program to do "Mad Libs". Sometimes you'll be working together at a single computer, sometimes separately on different parts of the same project. At all times, you'll be constantly testing and debugging as you go. At the end, you should be well-positioned to start learning the core or this class: Objected-Oriented Programming.
Create a lab02 directory.
Working together with a partner (at one computer), create a file in your lab02/ with the following class definition:
public class StringNode {
String data;
StringNode next;
}
You will use this class as the basis for some functions
manipulating linked lists of strings. Again in your lab02/, create a class ListStuff
that defines the following methods/functions:
// addToFront(s,Nold) returns a StringNode reference representing the list obtained by adding s to the front of list Nold
public static StringNode addToFront(String s, StringNode Nold) {
// you will fill this in
}
// listToArray(N) returns a reference to an array containing the same strings as in the list N (in order)
public static String[] listToArray(StringNode N) {
// you will fill this in
}
You must define a main
method/function in ListStuff.java to test the code with
(of course!), and you may add any other methods/functions you find useful.
Note: A "list" is now represented by a StringNode
reference. The "empty list" is represented by
a null
reference. So, for example:
StringNode N = null; // at this point N *is* an empty list
N = addToFront("rat",N); // at this point N *is* the list ("rat")
N = addToFront("dog",N); // at this point N *is* the list ("dog","rat")
N = addToFront("pig",N); // at this point N *is* the list ("pig","dog","rat")
String[] A = listToArray(N);
for(int i = 0; i < A.length; i++) {
System.out.println(A[i]);
}
... should print out this when it's done:
pig dog rat
WordRead
that defines a
function
public static String[] get(String fname) { ... }
that takes a filename fname and reads all the strings in that file, returning them (in order) in an array. Since you don't know how many strings are in the file, you're going to have to use a linked list (good thing you have one!) to read and store, then copy into an array. Unfortunately, you really need to have things stored in order!
Of course you'll have to thoroughly test this by writing a "main" for your WordRead class. For input file nouns.txt your test program should simply call get("nouns.txt") and print the resulting array, showing the words in nouns.txt one per line.
One thing you'll need to be able to do is create a Scanner that reads from a file. Without understanding what's going on, here's how to do that:
Scanner sc = null;
try {
sc = new Scanner(new FileReader(fname));
} catch(IOException e) {
e.printStackTrace(); System.exit(1);
}
You'll need a "import java.io.*;" for that.
I also suggest you take a look at the Scanner class's
hasNext()
(see the
Scanner API documentation). The gist is that
sc.hasNext()
returns true if there's a "next"
string to be read, and false otherwise. This will tell
you when to stop reading from the input file.
Formatter
and define in it a function
public static void writeInColumns(String[] A, int cols) { .. }
that takes an array A of strings and a positive int "cols" and prints the strings from A out, in order, separated by spaces, but never using more than "cols" characters (including spaces!) in a line. So you have to periodically insert newlines as you go.
Of course you'll have to thoroughly test this by writing a "main" for
your Formatter class. Here's a sample of
how writeInColumns
works for an array containing the strings:
These, are, the, times, that, try, men's, souls.
cols = 20 These are the times that try men's souls. cols = 10 These are the times that try men's souls.Note: Test this thoroughly!
Share your functioning code from Step 2 with each other.
Then, on one computer, continue development by creating a
class MidLibs
that defines a program that takes a filename and prints the
words in that file within 35 columns. The input filename will
come as a command-line argument.
Take the following example for running a java program from the command line:
java ClassName foo bar 23
In this example, "foo", "bar", and "23" will be stored in the String[] args
that is the parameter to the main() function for the class.
In other words, your main method will now receive as its parameter: String args[] = {"foo","bar","23"}
For MidLibs, if a filename isn't provided as a paramenter in the command line (args has length 0), you should print out a usage message and exit. System.exit(1) will do this for you.
Download the file madin01.txt.
Here's some sample runs for the program:
~/$ java MidLibs usage: java MidLibs <filename> ~/$ java MidLibs madin01.txt One of my @nounp came to see me in my office. He was @adjective with his @nounp . He asked if there were any optional assignments he could do to @verb things. I told him that I don't believe in @nounp , but that I was happy to help him @verb for the final.
Create a file MidLibs.java which will be your full program.
The last step is to replace each @noun, @verb, @adjective and @nounp (plural noun) with a randomly selected word. You read the candidate words in from the files nouns.txt, verbs.txt, adjectives.txt. For a plural noun you can simply add an "s" to the end of a randomly chosen noun. Now you have a program that really does Mad Libs!
Note: The == sign cannot be used to test for equality
between String objects. It tests for equal references,
not strings. Instead, if A
and B
are
Strings, you test for equality with
A.equals(B)
... which returns true if the strings are equal, and false otherwise.
For picking random words, remember from the previous lab that you can initialize a Random object. For this lab, let's seed it with the following:
Random rand = new Random(890);
Do that just once, and then generate random numbers like so:
int myrand = rand.nextInt(k);
Each student shall submit the source code of their team solution using the following:
~/bin/submit -c=IC211 -p=lab02 *.java
Log into the submission site: submit.cs.usna.edu and review the test cases run against your submission.
Do not simply look at the Score!
Click on the timestamp for your submission and click on the MidLibs to confirm that your program runs correctly.